From cef006904e875b7424b7fa13ea3dc2f9762081d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Kera=CC=88nen?= Date: Fri, 12 Apr 2019 12:47:08 +0300 Subject: Flatten OpenGL source directory hierarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flatten Source,Include and PrivateInclude directories away. Replace camelcase directory names with lowercase names. Remove random Qt3DS prefixes from directory names. Task-number: QT3DS-16 Change-Id: I5b23349232c760afa9a8efcc5e8945ee19d2e31a Reviewed-by: Pasi Keränen --- .../Client/Code/Core/Doc/DocumentEditor.cpp | 2 +- src/Authoring/Common/Common.pro | 3 +- src/Authoring/CoreLib/CoreLib.pro | 15 +- src/Authoring/FBXLineExporter/FBXLineExporter.pro | 2 +- src/Authoring/MorphLines/MorphLines.pro | 4 +- src/Authoring/QT3DSDM/QT3DSDM.pro | 10 +- src/Authoring/Studio/Qt3DStudio.pro | 15 +- src/Authoring/commoninclude.pri | 13 +- src/Runtime/Qt3DSRuntime/Qt3DSRuntime.pro | 12 +- .../Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro | 1164 ++++---- .../DocumentResourceManagerCustomMaterialParser.h | 80 - .../DocumentResourceManagerRenderPluginParser.h | 80 - .../Include/DocumentResourceManagerScriptParser.h | 137 - .../Source/DataModel/Include/Qt3DSMetadata.h | 380 --- .../Source/DataModel/Source/Qt3DSMetadata.cpp | 985 ------- src/Runtime/Source/Engine/Include/EnginePrefix.h | 143 - src/Runtime/Source/Engine/Include/NVImageScaler.h | 311 -- .../Source/Engine/Include/OpenKodeInclude.h | 49 - src/Runtime/Source/Engine/Include/Qt3DSEGLInfo.h | 60 - .../Source/Engine/Include/Qt3DSEGLWindowSystem.h | 81 - src/Runtime/Source/Engine/Include/Qt3DSPluginDLL.h | 128 - .../Engine/Include/Qt3DSRenderRuntimeBinding.h | 82 - .../Engine/Include/Qt3DSRenderRuntimeBindingImpl.h | 210 -- .../Source/Engine/Include/Qt3DSTegraApplication.h | 322 --- .../Source/Engine/Include/Qt3DSTegraInputEngine.h | 81 - .../Source/Engine/Include/Qt3DSWindowSystem.h | 57 - .../Engine/Source/Qt3DSRenderRuntimeBinding.cpp | 1990 ------------- .../Qt3DSRenderRuntimeBindingImplRenderer.cpp | 224 -- .../Qt3DSRenderRuntimeBindingImplTranslation.cpp | 1811 ------------ .../Source/Engine/Source/Qt3DSTegraApplication.cpp | 746 ----- .../Source/Engine/Source/Qt3DSTegraInputEngine.cpp | 124 - src/Runtime/Source/HDR/Include/CUDABSDFMipmap.h | 77 - src/Runtime/Source/HDR/Include/GLComputeMipMap.h | 74 - src/Runtime/Source/HDR/Include/HDR.h | 239 -- src/Runtime/Source/HDR/Include/MipmapBSDF.h | 104 - src/Runtime/Source/HDR/Source/CUDABSDFMipmap.cpp | 145 - src/Runtime/Source/HDR/Source/GLComputeMipmap.cpp | 394 --- src/Runtime/Source/HDR/Source/HDR.cpp | 30 - src/Runtime/Source/HDR/Source/MipmapBSDF.cpp | 265 -- src/Runtime/Source/HDR/Source/MipmapBSDF.cu | 404 --- .../Android/jni/Qt3DSLibs/nv_math/NvVec.h | 316 --- .../Android/jni/Qt3DSLibs/nv_math/misc.h | 130 - .../Android/jni/Qt3DSLibs/nv_math/nv_math.cpp | 64 - .../Android/jni/Qt3DSLibs/nv_math/nv_math.h | 45 - .../Android/jni/Qt3DSLibs/nv_math/nv_matrix.cpp | 1030 ------- .../Android/jni/Qt3DSLibs/nv_math/nv_matrix.h | 117 - .../Android/jni/Qt3DSLibs/nv_math/nv_quat.cpp | 199 -- .../Android/jni/Qt3DSLibs/nv_math/nv_quat.h | 63 - .../PlatformSpecific/Linux/Qt3DSLibs/nv_color.h | 107 - .../PlatformSpecific/Linux/Qt3DSLibs/nv_debug.h | 86 - .../PlatformSpecific/Linux/Qt3DSLibs/nv_global.h | 36 - .../Linux/Qt3DSLibs/nv_math/NvVec.h | 316 --- .../Linux/Qt3DSLibs/nv_math/misc.h | 130 - .../Linux/Qt3DSLibs/nv_math/nv_math.cpp | 64 - .../Linux/Qt3DSLibs/nv_math/nv_math.h | 45 - .../Linux/Qt3DSLibs/nv_math/nv_matrix.cpp | 1030 ------- .../Linux/Qt3DSLibs/nv_math/nv_matrix.h | 118 - .../Linux/Qt3DSLibs/nv_math/nv_quat.cpp | 203 -- .../Linux/Qt3DSLibs/nv_math/nv_quat.h | 64 - .../PlatformSpecific/Linux/Qt3DSLibs/nv_types.h | 81 - .../Linux/assets/courier+lucida_256.abc | Bin 2048 -> 0 bytes .../Linux/assets/courier+lucida_256.dds | Bin 87509 -> 0 bytes .../Linux/assets/courier+lucida_512.abc | Bin 2048 -> 0 bytes .../Linux/assets/courier+lucida_512.dds | Bin 349653 -> 0 bytes .../Source/PlatformSpecific/Linux/assets/font.frag | 39 - .../Source/PlatformSpecific/Linux/assets/font.vert | 49 - .../PlatformSpecific/Macos/Qt3DSLibs/nv_color.h | 107 - .../PlatformSpecific/Macos/Qt3DSLibs/nv_debug.h | 86 - .../PlatformSpecific/Macos/Qt3DSLibs/nv_global.h | 36 - .../Macos/Qt3DSLibs/nv_math/NvVec.h | 316 --- .../Macos/Qt3DSLibs/nv_math/misc.h | 130 - .../Macos/Qt3DSLibs/nv_math/nv_math.cpp | 64 - .../Macos/Qt3DSLibs/nv_math/nv_math.h | 45 - .../Macos/Qt3DSLibs/nv_math/nv_matrix.cpp | 1030 ------- .../Macos/Qt3DSLibs/nv_math/nv_matrix.h | 117 - .../Macos/Qt3DSLibs/nv_math/nv_quat.cpp | 199 -- .../Macos/Qt3DSLibs/nv_math/nv_quat.h | 63 - .../PlatformSpecific/Macos/Qt3DSLibs/nv_types.h | 81 - .../Macos/assets/courier+lucida_256.abc | Bin 2048 -> 0 bytes .../Macos/assets/courier+lucida_256.dds | Bin 87509 -> 0 bytes .../Macos/assets/courier+lucida_512.abc | Bin 2048 -> 0 bytes .../Macos/assets/courier+lucida_512.dds | Bin 349653 -> 0 bytes .../Source/PlatformSpecific/Macos/assets/font.frag | 39 - .../Source/PlatformSpecific/Macos/assets/font.vert | 49 - .../PlatformSpecific/Windows/Qt3DSLibs/nv_color.h | 107 - .../Windows/Qt3DSLibs/nv_config/nv_config.h | 278 -- .../PlatformSpecific/Windows/Qt3DSLibs/nv_debug.h | 86 - .../PlatformSpecific/Windows/Qt3DSLibs/nv_global.h | 36 - .../Windows/Qt3DSLibs/nv_math/NvVec.h | 316 --- .../Windows/Qt3DSLibs/nv_math/misc.h | 130 - .../Windows/Qt3DSLibs/nv_math/nv_math.cpp | 64 - .../Windows/Qt3DSLibs/nv_math/nv_math.h | 45 - .../Windows/Qt3DSLibs/nv_math/nv_matrix.cpp | 1030 ------- .../Windows/Qt3DSLibs/nv_math/nv_matrix.h | 117 - .../Windows/Qt3DSLibs/nv_math/nv_quat.cpp | 199 -- .../Windows/Qt3DSLibs/nv_math/nv_quat.h | 63 - .../PlatformSpecific/Windows/Qt3DSLibs/nv_types.h | 81 - .../Windows/Qt3DSLibs/qt3ds_launcher_defs.h | 92 - .../Windows/Qt3DSViewer/Resource.h | 43 - .../Windows/assets/courier+lucida_256.abc | Bin 2048 -> 0 bytes .../Windows/assets/courier+lucida_256.dds | Bin 87509 -> 0 bytes .../Windows/assets/courier+lucida_512.abc | Bin 2048 -> 0 bytes .../Windows/assets/courier+lucida_512.dds | Bin 349653 -> 0 bytes .../PlatformSpecific/Windows/assets/font.frag | 39 - .../PlatformSpecific/Windows/assets/font.vert | 49 - .../Source/Qt3DSEvent/Include/EventSystem.h | 73 - .../Source/Qt3DSEvent/Include/EventSystemC.h | 139 - .../InternalInclude/EventPollingSystem.h | 87 - .../Source/Qt3DSEvent/Source/EventFactory.cpp | 143 - .../Source/Qt3DSEvent/Source/EventFactory.h | 87 - .../Source/Qt3DSEvent/Source/EventPoller.cpp | 375 --- src/Runtime/Source/Qt3DSEvent/Source/EventPoller.h | 103 - .../Source/Qt3DSEvent/Source/EventSystemC.cpp | 34 - .../Source/Qt3DSEvent/Test/CanProviderDemo.cpp | 259 -- .../Source/Qt3DSEvent/Test/CanProviderDemo.h | 56 - .../Include/foundation/AutoDeallocatorAllocator.h | 99 - .../Include/foundation/ConvertUTF.h | 179 -- .../Include/foundation/FastAllocator.h | 115 - .../Qt3DSFoundation/Include/foundation/FileTools.h | 124 - .../Qt3DSFoundation/Include/foundation/IOStreams.h | 278 -- .../Include/foundation/LICENSE_CONVERTUTF.TXT | 19 - .../Include/foundation/PoolingAllocator.h | 177 -- .../Include/foundation/PreAllocatedAllocator.h | 88 - .../Qt3DSFoundation/Include/foundation/Qt3DS.h | 59 - .../Include/foundation/Qt3DSAllocator.h | 195 -- .../Include/foundation/Qt3DSAllocatorCallback.h | 100 - .../Include/foundation/Qt3DSAssert.h | 62 - .../Include/foundation/Qt3DSAtomic.h | 63 - .../Include/foundation/Qt3DSBasicTemplates.h | 113 - .../Include/foundation/Qt3DSBounds3.h | 443 --- .../foundation/Qt3DSBroadcastingAllocator.h | 113 - .../Include/foundation/Qt3DSContainers.h | 129 - .../Include/foundation/Qt3DSDataRef.h | 162 -- .../Include/foundation/Qt3DSDiscriminatedUnion.h | 335 --- .../Qt3DSFoundation/Include/foundation/Qt3DSFPU.h | 97 - .../Include/foundation/Qt3DSFastIPC.h | 57 - .../Include/foundation/Qt3DSFlags.h | 360 --- .../Include/foundation/Qt3DSFoundation.h | 120 - .../Qt3DSFoundation/Include/foundation/Qt3DSIPC.h | 99 - .../Include/foundation/Qt3DSIndexableLinkedList.h | 309 -- .../Include/foundation/Qt3DSIntrinsics.h | 50 - .../Include/foundation/Qt3DSInvasiveLinkedList.h | 361 --- .../Include/foundation/Qt3DSInvasiveSet.h | 104 - .../Include/foundation/Qt3DSLogging.h | 51 - .../Include/foundation/Qt3DSMat33.h | 385 --- .../Include/foundation/Qt3DSMat44.h | 497 ---- .../Qt3DSFoundation/Include/foundation/Qt3DSMath.h | 323 --- .../Include/foundation/Qt3DSMathUtils.h | 571 ---- .../Include/foundation/Qt3DSMemoryBuffer.h | 160 -- .../Include/foundation/Qt3DSMutex.h | 376 --- .../Include/foundation/Qt3DSNoCopy.h | 50 - .../Include/foundation/Qt3DSOption.h | 104 - .../Include/foundation/Qt3DSPerfTimer.h | 107 - .../Include/foundation/Qt3DSPlane.h | 134 - .../Qt3DSFoundation/Include/foundation/Qt3DSPool.h | 159 -- .../Include/foundation/Qt3DSPreprocessor.h | 375 --- .../Qt3DSFoundation/Include/foundation/Qt3DSQuat.h | 381 --- .../Include/foundation/Qt3DSRefCounted.h | 199 -- .../Include/foundation/Qt3DSSemaphore.h | 67 - .../Include/foundation/Qt3DSSimpleTypes.h | 117 - .../Include/foundation/Qt3DSStringTokenizer.h | 108 - .../Qt3DSFoundation/Include/foundation/Qt3DSSync.h | 70 - .../Include/foundation/Qt3DSSystem.h | 58 - .../Include/foundation/Qt3DSThread.h | 205 -- .../Qt3DSFoundation/Include/foundation/Qt3DSTime.h | 97 - .../Include/foundation/Qt3DSTransform.h | 195 -- .../Include/foundation/Qt3DSUnionCast.h | 64 - .../Include/foundation/Qt3DSUtilities.h | 189 -- .../Qt3DSFoundation/Include/foundation/Qt3DSVec2.h | 321 --- .../Qt3DSFoundation/Include/foundation/Qt3DSVec3.h | 377 --- .../Qt3DSFoundation/Include/foundation/Qt3DSVec4.h | 373 --- .../Include/foundation/Qt3DSVersionNumber.h | 67 - .../Include/foundation/SerializationTypes.h | 132 - .../Qt3DSFoundation/Include/foundation/Socket.h | 79 - .../Include/foundation/StrConvertUTF.h | 213 -- .../Include/foundation/StringConversion.h | 226 -- .../Include/foundation/StringConversionImpl.h | 213 -- .../Include/foundation/StringTable.h | 291 -- .../Include/foundation/TaggedPointer.h | 80 - .../Include/foundation/ThreadSafeQueue.h | 111 - .../Include/foundation/TrackingAllocator.h | 252 -- .../Qt3DSFoundation/Include/foundation/Utils.h | 382 --- .../Qt3DSFoundation/Include/foundation/XML.h | 680 ----- .../Include/foundation/linux/LICENSE.TXT | 7 - .../Include/foundation/linux/Qt3DSLinuxAoS.h | 157 - .../Include/foundation/linux/Qt3DSLinuxFile.h | 48 - .../Include/foundation/linux/Qt3DSLinuxInlineAoS.h | 2666 ----------------- .../foundation/linux/Qt3DSLinuxIntrinsics.h | 209 -- .../Include/foundation/linux/Qt3DSLinuxString.h | 202 -- .../foundation/linux/Qt3DSLinuxTrigConstants.h | 96 - .../Include/foundation/linux/qt_attribution.json | 10 - .../Include/foundation/qt_attribution.json | 10 - .../Include/foundation/windows/LICENSE.TXT | 7 - .../Include/foundation/windows/Qt3DSWindowsAoS.h | 126 - .../Include/foundation/windows/Qt3DSWindowsFile.h | 48 - .../foundation/windows/Qt3DSWindowsInclude.h | 93 - .../foundation/windows/Qt3DSWindowsInlineAoS.h | 2715 ------------------ .../foundation/windows/Qt3DSWindowsIntrinsics.h | 230 -- .../foundation/windows/Qt3DSWindowsString.h | 147 - .../foundation/windows/Qt3DSWindowsTrigConstants.h | 93 - .../Include/foundation/windows/qt_attribution.json | 10 - .../Source/foundation/ConvertUTF.cpp | 661 ----- .../Source/foundation/EASTL_new.cpp | 75 - .../Source/foundation/FileTools.cpp | 545 ---- .../Source/foundation/IOStreams.cpp | 384 --- .../Source/foundation/LICENCE_SOCKET.TXT | 20 - .../Source/foundation/Qt3DSFoundation.cpp | 237 -- .../Source/foundation/Qt3DSLogging.cpp | 44 - .../Source/foundation/Qt3DSMathUtils.cpp | 181 -- .../Source/foundation/Qt3DSPerfTimer.cpp | 163 -- .../Source/foundation/Qt3DSSystem.cpp | 139 - .../Qt3DSFoundation/Source/foundation/Socket.cpp | 472 --- .../Source/foundation/StringTable.cpp | 672 ----- .../Source/foundation/TrackingAllocator.cpp | 50 - .../Qt3DSFoundation/Source/foundation/XML.cpp | 1008 ------- .../Source/foundation/linux/Qt3DSLinuxAtomic.cpp | 129 - .../Source/foundation/linux/Qt3DSLinuxFPU.cpp | 52 - .../Source/foundation/linux/Qt3DSLinuxMutex.cpp | 120 - .../foundation/linux/Qt3DSLinuxSemaphore.cpp | 146 - .../Source/foundation/linux/Qt3DSLinuxSync.cpp | 137 - .../Source/foundation/linux/Qt3DSLinuxThread.cpp | 384 --- .../Source/foundation/linux/Qt3DSLinuxTime.cpp | 111 - .../Source/foundation/linux/SocketImpl.h | 424 --- .../Source/foundation/macosx/Qt3DSUnixAtomic.cpp | 89 - .../Source/foundation/macosx/Qt3DSUnixFPU.cpp | 61 - .../Source/foundation/macosx/Qt3DSUnixMutex.cpp | 120 - .../foundation/macosx/Qt3DSUnixSemaphore.cpp | 146 - .../Source/foundation/macosx/Qt3DSUnixSync.cpp | 137 - .../Source/foundation/macosx/Qt3DSUnixTime.cpp | 108 - .../Source/foundation/qt_attribution.json | 11 - .../foundation/windows/Qt3DSWindowsAtomic.cpp | 93 - .../Source/foundation/windows/Qt3DSWindowsFPU.cpp | 61 - .../foundation/windows/Qt3DSWindowsMutex.cpp | 149 - .../foundation/windows/Qt3DSWindowsSemaphore.cpp | 72 - .../Source/foundation/windows/Qt3DSWindowsSync.cpp | 74 - .../foundation/windows/Qt3DSWindowsThread.cpp | 241 -- .../Source/foundation/windows/Qt3DSWindowsTime.cpp | 92 - .../Source/foundation/windows/SocketImpl.h | 506 ---- .../Examples/Qt3DSRenderClearColorExample.cpp | 63 - .../Qt3DSRender/Examples/Qt3DSRenderExample.cpp | 491 ---- .../Qt3DSRender/Examples/Qt3DSRenderExample.h | 123 - .../Examples/Qt3DSRenderExampleTools.cpp | 188 -- .../Qt3DSRender/Examples/Qt3DSRenderExampleTools.h | 89 - .../Examples/Qt3DSRenderRenderToTextureExample.cpp | 178 -- .../Examples/Qt3DSRenderSpinningCubeExample.cpp | 104 - .../render/Qt3DSRenderAtomicCounterBuffer.h | 182 -- .../Include/render/Qt3DSRenderAttribLayout.h | 90 - .../Include/render/Qt3DSRenderBaseTypes.h | 2100 -------------- .../Include/render/Qt3DSRenderComputeShader.h | 89 - .../Include/render/Qt3DSRenderConstantBuffer.h | 248 -- .../Include/render/Qt3DSRenderContext.h | 1063 ------- .../Include/render/Qt3DSRenderDataBuffer.h | 188 -- .../Include/render/Qt3DSRenderDepthStencilState.h | 134 - .../Include/render/Qt3DSRenderDrawIndirectBuffer.h | 152 - .../Include/render/Qt3DSRenderDrawable.h | 54 - .../Include/render/Qt3DSRenderFragmentShader.h | 89 - .../Include/render/Qt3DSRenderFrameBuffer.h | 277 -- .../Include/render/Qt3DSRenderGeometryShader.h | 89 - .../Include/render/Qt3DSRenderImageTexture.h | 143 - .../Include/render/Qt3DSRenderIndexBuffer.h | 138 - .../Include/render/Qt3DSRenderInputAssembler.h | 157 - .../Include/render/Qt3DSRenderOcclusionQuery.h | 120 - .../render/Qt3DSRenderPathFontSpecification.h | 165 -- .../Include/render/Qt3DSRenderPathFontText.h | 139 - .../Include/render/Qt3DSRenderPathRender.h | 114 - .../Include/render/Qt3DSRenderPathSpecification.h | 141 - .../Include/render/Qt3DSRenderProgramPipeline.h | 138 - .../Include/render/Qt3DSRenderQueryBase.h | 127 - .../Include/render/Qt3DSRenderRasterizerState.h | 94 - .../Include/render/Qt3DSRenderRenderBuffer.h | 158 -- .../Include/render/Qt3DSRenderSampler.h | 124 - .../Qt3DSRender/Include/render/Qt3DSRenderShader.h | 123 - .../Include/render/Qt3DSRenderShaderConstant.h | 448 --- .../Include/render/Qt3DSRenderShaderProgram.h | 540 ---- .../Include/render/Qt3DSRenderStorageBuffer.h | 158 -- .../Qt3DSRender/Include/render/Qt3DSRenderSync.h | 132 - .../Include/render/Qt3DSRenderTessellationShader.h | 132 - .../Include/render/Qt3DSRenderTexture2D.h | 165 -- .../Include/render/Qt3DSRenderTexture2DArray.h | 106 - .../Include/render/Qt3DSRenderTextureBase.h | 177 -- .../Include/render/Qt3DSRenderTextureCube.h | 106 - .../Include/render/Qt3DSRenderTimerQuery.h | 129 - .../Include/render/Qt3DSRenderVertexBuffer.h | 124 - .../Include/render/Qt3DSRenderVertexShader.h | 89 - .../Include/render/backends/Qt3DSRenderBackend.h | 2245 --------------- .../render/backends/gl/Q3DSRenderBackendGLES2.h | 193 -- .../render/backends/gl/Qt3DSOpenGLExtensions.h | 392 --- .../Include/render/backends/gl/Qt3DSOpenGLPrefix.h | 48 - .../Include/render/backends/gl/Qt3DSOpenGLTokens.h | 408 --- .../Include/render/backends/gl/Qt3DSOpenGLUtil.h | 2201 -------------- .../render/backends/gl/Qt3DSRenderBackendGL3.h | 171 -- .../render/backends/gl/Qt3DSRenderBackendGL4.h | 205 -- .../render/backends/gl/Qt3DSRenderBackendGLBase.h | 530 ---- .../gl/Qt3DSRenderBackendInputAssemblerGL.h | 146 - .../backends/gl/Qt3DSRenderBackendRenderStatesGL.h | 173 -- .../gl/Qt3DSRenderBackendShaderProgramGL.h | 105 - .../backends/software/Qt3DSRenderBackendNULL.h | 46 - .../Include/render/glg/Qt3DSGLImplObjects.h | 83 - .../Source/Qt3DSRenderAtomicCounterBuffer.cpp | 156 - .../Qt3DSRender/Source/Qt3DSRenderAttribLayout.cpp | 57 - .../Source/Qt3DSRenderComputeShader.cpp | 55 - .../Source/Qt3DSRenderConstantBuffer.cpp | 421 --- .../Qt3DSRender/Source/Qt3DSRenderContext.cpp | 1107 -------- .../Qt3DSRender/Source/Qt3DSRenderDataBuffer.cpp | 158 -- .../Source/Qt3DSRenderDepthStencilState.cpp | 91 - .../Source/Qt3DSRenderDrawIndirectBuffer.cpp | 104 - .../Source/Qt3DSRenderFragmentShader.cpp | 55 - .../Qt3DSRender/Source/Qt3DSRenderFrameBuffer.cpp | 300 -- .../Source/Qt3DSRenderGeometryShader.cpp | 55 - .../Qt3DSRender/Source/Qt3DSRenderImageTexture.cpp | 103 - .../Qt3DSRender/Source/Qt3DSRenderIndexBuffer.cpp | 100 - .../Source/Qt3DSRenderInputAssembler.cpp | 105 - .../Source/Qt3DSRenderOcclusionQuery.cpp | 82 - .../Source/Qt3DSRenderPathFontSpecification.cpp | 145 - .../Qt3DSRender/Source/Qt3DSRenderPathFontText.cpp | 191 -- .../Qt3DSRender/Source/Qt3DSRenderPathRender.cpp | 108 - .../Source/Qt3DSRenderPathSpecification.cpp | 103 - .../Source/Qt3DSRenderProgramPipeline.cpp | 134 - .../Qt3DSRender/Source/Qt3DSRenderQueryBase.cpp | 54 - .../Source/Qt3DSRenderRasterizerState.cpp | 71 - .../Qt3DSRender/Source/Qt3DSRenderRenderBuffer.cpp | 114 - .../Qt3DSRender/Source/Qt3DSRenderSampler.cpp | 84 - .../Source/Qt3DSRenderShaderProgram.cpp | 1248 -------- .../Source/Qt3DSRenderStorageBuffer.cpp | 123 - .../Source/Qt3DSRender/Source/Qt3DSRenderSync.cpp | 87 - .../Source/Qt3DSRenderTessellationShader.cpp | 74 - .../Qt3DSRender/Source/Qt3DSRenderTexture2D.cpp | 263 -- .../Source/Qt3DSRenderTexture2DArray.cpp | 123 - .../Qt3DSRender/Source/Qt3DSRenderTextureBase.cpp | 167 -- .../Qt3DSRender/Source/Qt3DSRenderTextureCube.cpp | 119 - .../Qt3DSRender/Source/Qt3DSRenderTimerQuery.cpp | 75 - .../Qt3DSRender/Source/Qt3DSRenderVertexBuffer.cpp | 74 - .../Qt3DSRender/Source/Qt3DSRenderVertexShader.cpp | 54 - .../Source/backends/gl/Q3DSRenderBackendGLES2.cpp | 887 ------ .../Source/backends/gl/Qt3DSOpenGLExtensions.cpp | 170 -- .../Source/backends/gl/Qt3DSRenderBackendGL3.cpp | 784 ----- .../Source/backends/gl/Qt3DSRenderBackendGL4.cpp | 875 ------ .../backends/gl/Qt3DSRenderBackendGLBase.cpp | 2220 --------------- .../Source/backends/gl/Qt3DSRenderContextGL.cpp | 91 - .../backends/software/Qt3DSRenderBackendNULL.cpp | 588 ---- .../GraphObjects/Qt3DSRenderCamera.cpp | 486 ---- .../GraphObjects/Qt3DSRenderCamera.h | 177 -- .../GraphObjects/Qt3DSRenderCustomMaterial.h | 147 - .../GraphObjects/Qt3DSRenderDefaultMaterial.cpp | 74 - .../GraphObjects/Qt3DSRenderDefaultMaterial.h | 148 - .../GraphObjects/Qt3DSRenderDynamicObject.cpp | 158 -- .../GraphObjects/Qt3DSRenderDynamicObject.h | 112 - .../GraphObjects/Qt3DSRenderEffect.cpp | 61 - .../GraphObjects/Qt3DSRenderEffect.h | 86 - .../GraphObjects/Qt3DSRenderGraphObject.h | 77 - .../GraphObjects/Qt3DSRenderImage.cpp | 135 - .../GraphObjects/Qt3DSRenderImage.h | 113 - .../GraphObjects/Qt3DSRenderLayer.cpp | 105 - .../GraphObjects/Qt3DSRenderLayer.h | 203 -- .../GraphObjects/Qt3DSRenderLight.cpp | 55 - .../GraphObjects/Qt3DSRenderLight.h | 90 - .../GraphObjects/Qt3DSRenderLightmaps.cpp | 41 - .../GraphObjects/Qt3DSRenderLightmaps.h | 77 - .../GraphObjects/Qt3DSRenderMaterialDirty.h | 61 - .../GraphObjects/Qt3DSRenderModel.cpp | 75 - .../GraphObjects/Qt3DSRenderModel.h | 76 - .../GraphObjects/Qt3DSRenderNode.cpp | 499 ---- .../GraphObjects/Qt3DSRenderNode.h | 307 -- .../GraphObjects/Qt3DSRenderPath.cpp | 59 - .../GraphObjects/Qt3DSRenderPath.h | 156 - .../GraphObjects/Qt3DSRenderPathSubPath.h | 65 - .../GraphObjects/Qt3DSRenderPresentation.cpp | 43 - .../GraphObjects/Qt3DSRenderPresentation.h | 94 - .../GraphObjects/Qt3DSRenderReferencedMaterial.h | 63 - .../GraphObjects/Qt3DSRenderScene.cpp | 121 - .../GraphObjects/Qt3DSRenderScene.h | 84 - .../GraphObjects/Qt3DSRenderText.cpp | 76 - .../GraphObjects/Qt3DSRenderText.h | 76 - .../Include/ANDROID/DynamicLibLoader.h | 30 - .../Include/LINUX/DynamicLibLoader.h | 92 - .../Include/OSX/DynamicLibLoader.h | 30 - .../Include/QNX/DynamicLibLoader.h | 30 - .../Include/Qt3DSOffscreenRenderKey.h | 153 - .../Include/Qt3DSOffscreenRenderManager.h | 256 -- .../Include/Qt3DSOldNBustedRenderPlugin.h | 102 - .../Qt3DSRuntimeRender/Include/Qt3DSRender.h | 254 -- .../Include/Qt3DSRenderClippingFrustum.h | 161 -- .../Include/Qt3DSRenderContextCore.h | 217 -- .../Qt3DSRenderCustomMaterialRenderContext.h | 94 - .../Qt3DSRenderCustomMaterialShaderGenerator.h | 69 - .../Include/Qt3DSRenderCustomMaterialSystem.h | 173 -- .../Qt3DSRenderDefaultMaterialShaderGenerator.h | 123 - .../Include/Qt3DSRenderDynamicObjectSystem.h | 286 -- .../Qt3DSRenderDynamicObjectSystemCommands.h | 622 ---- .../Include/Qt3DSRenderDynamicObjectSystemUtil.h | 126 - .../Include/Qt3DSRenderEffectSystem.h | 207 -- .../Include/Qt3DSRenderEulerAngles.h | 142 - .../Include/Qt3DSRenderGraphObjectPickQuery.h | 124 - .../Include/Qt3DSRenderGraphObjectSerializer.h | 69 - .../Include/Qt3DSRenderGraphObjectTypes.h | 166 -- .../Include/Qt3DSRenderImageScaler.h | 121 - .../Include/Qt3DSRenderImageTextureData.h | 102 - .../Include/Qt3DSRenderInputStreamFactory.h | 69 - .../Include/Qt3DSRenderLightConstantProperties.h | 198 -- .../Include/Qt3DSRenderMaterialHelpers.h | 94 - .../Include/Qt3DSRenderMaterialShaderGenerator.h | 152 - .../Qt3DSRuntimeRender/Include/Qt3DSRenderMesh.h | 187 -- .../Include/Qt3DSRenderPathManager.h | 121 - .../Include/Qt3DSRenderPathMath.h | 713 ----- .../Include/Qt3DSRenderPathRenderContext.h | 94 - .../Include/Qt3DSRenderPixelGraphicsRenderer.h | 54 - .../Include/Qt3DSRenderPixelGraphicsTypes.h | 103 - .../Qt3DSRuntimeRender/Include/Qt3DSRenderPlugin.h | 148 - .../Include/Qt3DSRenderPluginCInterface.h | 330 --- .../Include/Qt3DSRenderPluginGraphObject.h | 60 - .../Include/Qt3DSRenderPluginPropertyValue.h | 182 -- .../Include/Qt3DSRenderProfiler.h | 112 - .../Qt3DSRuntimeRender/Include/Qt3DSRenderRay.h | 101 - .../Include/Qt3DSRenderRenderList.h | 121 - .../Include/Qt3DSRenderRotationHelper.h | 193 -- .../Include/Qt3DSRenderShaderCache.h | 160 -- .../Include/Qt3DSRenderShaderCodeGenerator.h | 175 -- .../Include/Qt3DSRenderShaderCodeGeneratorV2.h | 132 - .../Include/Qt3DSRenderShaderKeys.h | 802 ------ .../Include/Qt3DSRenderShadowMap.h | 183 -- .../Qt3DSRuntimeRender/Include/Qt3DSRenderString.h | 70 - .../Include/Qt3DSRenderSubPresentationHelper.h | 69 - .../Include/Qt3DSRenderSubpresentation.h | 110 - .../Include/Qt3DSRenderTaggedPointer.h | 85 - .../Include/Qt3DSRenderTessModeValues.h | 74 - .../Include/Qt3DSRenderTextTextureAtlas.h | 63 - .../Include/Qt3DSRenderTextTextureCache.h | 74 - .../Include/Qt3DSRenderTextTypes.h | 196 -- .../Include/Qt3DSRenderTextureAtlas.h | 102 - .../Include/Qt3DSRenderThreadPool.h | 80 - .../Include/Qt3DSRenderUIPLoader.h | 133 - .../Include/Qt3DSRenderUIPSharedTranslation.h | 488 ---- .../Include/Qt3DSRenderWidgets.h | 181 -- .../Include/Qt3DSRenderableImage.h | 77 - .../Qt3DSRuntimeRender/Include/Qt3DSRenderer.h | 249 -- .../Qt3DSRuntimeRender/Include/Qt3DSRendererUtil.h | 62 - .../Qt3DSRuntimeRender/Include/Qt3DSTextRenderer.h | 146 - .../Include/WINDOWS/DynamicLibLoader.h | 80 - .../Qt3DSRuntimeRender/Include/q3dsqmlrender.h | 101 - .../RendererImpl/Qt3DSRenderableObjects.cpp | 530 ---- .../RendererImpl/Qt3DSRenderableObjects.h | 431 --- .../RendererImpl/Qt3DSRendererImpl.cpp | 2014 ------------- .../RendererImpl/Qt3DSRendererImpl.h | 552 ---- .../Qt3DSRendererImplLayerRenderData.cpp | 2203 -------------- .../Qt3DSRendererImplLayerRenderData.h | 182 -- .../Qt3DSRendererImplLayerRenderHelper.cpp | 259 -- .../Qt3DSRendererImplLayerRenderHelper.h | 115 - ...Qt3DSRendererImplLayerRenderPreparationData.cpp | 1446 ---------- .../Qt3DSRendererImplLayerRenderPreparationData.h | 367 --- .../RendererImpl/Qt3DSRendererImplShaders.cpp | 2999 -------------------- .../RendererImpl/Qt3DSRendererImplShaders.h | 452 --- .../RendererImpl/Qt3DSVertexPipelineImpl.h | 435 --- .../ResourceManager/Qt3DSRenderBufferLoader.cpp | 326 --- .../ResourceManager/Qt3DSRenderBufferLoader.h | 85 - .../ResourceManager/Qt3DSRenderBufferManager.cpp | 920 ------ .../ResourceManager/Qt3DSRenderBufferManager.h | 104 - .../Qt3DSRenderImageBatchLoader.cpp | 536 ---- .../ResourceManager/Qt3DSRenderImageBatchLoader.h | 96 - .../ResourceManager/Qt3DSRenderLoadedTexture.cpp | 704 ----- .../ResourceManager/Qt3DSRenderLoadedTexture.h | 184 -- .../Qt3DSRenderLoadedTextureBMP.cpp | 1262 -------- .../Qt3DSRenderLoadedTextureDDS.cpp | 695 ----- .../ResourceManager/Qt3DSRenderLoadedTextureDDS.h | 88 - .../Qt3DSRenderLoadedTextureFreeImageCompat.h | 413 --- .../Qt3DSRenderLoadedTextureGIF.cpp | 851 ------ .../Qt3DSRenderLoadedTextureHDR.cpp | 255 -- .../Qt3DSRenderLoadedTextureKTX.cpp | 277 -- .../ResourceManager/Qt3DSRenderLoadedTextureKTX.h | 39 - .../Qt3DSRenderPrefilterTexture.cpp | 599 ---- .../ResourceManager/Qt3DSRenderPrefilterTexture.h | 129 - .../Qt3DSRenderResourceBufferObjects.cpp | 101 - .../Qt3DSRenderResourceBufferObjects.h | 96 - .../ResourceManager/Qt3DSRenderResourceManager.cpp | 436 --- .../ResourceManager/Qt3DSRenderResourceManager.h | 81 - .../Qt3DSRenderResourceTexture2D.cpp | 174 -- .../ResourceManager/Qt3DSRenderResourceTexture2D.h | 126 - .../Source/Qt3DSOffscreenRenderManager.cpp | 498 ---- .../Source/Qt3DSOldNBustedRenderPlugin.cpp | 118 - .../Source/Qt3DSOnscreenTextRenderer.cpp | 421 --- .../Source/Qt3DSQtTextRenderer.cpp | 678 ----- .../Source/Qt3DSRenderClippingFrustum.cpp | 85 - .../Source/Qt3DSRenderContextCore.cpp | 819 ------ .../Qt3DSRenderCustomMaterialShaderGenerator.cpp | 1261 -------- .../Source/Qt3DSRenderCustomMaterialSystem.cpp | 2074 -------------- .../Qt3DSRenderDefaultMaterialShaderGenerator.cpp | 1930 ------------- .../Source/Qt3DSRenderDynamicObjectSystem.cpp | 1531 ---------- .../Source/Qt3DSRenderEffectSystem.cpp | 1847 ------------ .../Source/Qt3DSRenderEulerAngles.cpp | 383 --- .../Source/Qt3DSRenderGpuProfiler.cpp | 284 -- .../Source/Qt3DSRenderGraphObjectSerializer.cpp | 670 ----- .../Source/Qt3DSRenderImageScaler.cpp | 883 ------ .../Source/Qt3DSRenderInputStreamFactory.cpp | 214 -- .../Source/Qt3DSRenderPathManager.cpp | 1964 ------------- .../Source/Qt3DSRenderPixelGraphicsRenderer.cpp | 311 -- .../Source/Qt3DSRenderPixelGraphicsTypes.cpp | 66 - .../Source/Qt3DSRenderPlugin.cpp | 936 ------ .../Qt3DSRuntimeRender/Source/Qt3DSRenderRay.cpp | 164 -- .../Source/Qt3DSRenderRenderList.cpp | 110 - .../Source/Qt3DSRenderShaderCache.cpp | 768 ----- .../Source/Qt3DSRenderShaderCodeGenerator.cpp | 526 ---- .../Source/Qt3DSRenderShaderCodeGeneratorV2.cpp | 632 ----- .../Source/Qt3DSRenderShadowMap.cpp | 219 -- .../Source/Qt3DSRenderSubpresentation.cpp | 127 - .../Source/Qt3DSRenderTextTextureAtlas.cpp | 126 - .../Source/Qt3DSRenderTextTextureCache.cpp | 295 -- .../Source/Qt3DSRenderTextureAtlas.cpp | 364 --- .../Source/Qt3DSRenderThreadPool.cpp | 327 --- .../Source/Qt3DSRenderUIPLoader.cpp | 2065 -------------- .../Source/Qt3DSRenderUIPSharedTranslation.cpp | 464 --- .../Source/Qt3DSRenderWidgets.cpp | 319 --- .../Source/Qt3DSRendererUtil.cpp | 119 - .../Source/Qt3DSTextRenderer.cpp | 87 - .../Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp | 144 - .../Source/Qt3DSState/Include/Qt3DSStateConfig.h | 43 - .../Source/Qt3DSState/Include/Qt3DSStateEngine.h | 103 - .../Include/Qt3DSStateInputStreamFactory.h | 71 - .../InternalInclude/Qt3DSStateApplication.h | 48 - .../Source/Qt3DSStateInputStreamFactory.cpp | 231 -- .../Application/Qt3DSStateApplication.cpp | 63 - .../Application/Qt3DSStateApplication.h | 46 - .../Debugger/Qt3DSSceneGraphDebugger.h | 111 - .../Debugger/Qt3DSSceneGraphDebuggerProtocol.h | 375 --- .../Debugger/Qt3DSSceneGraphDebuggerValue.h | 190 -- .../Debugger/Qt3DSSceneGraphRuntimeDebugger.cpp | 345 --- .../Debugger/Qt3DSStateDataTest.cpp | 81 - .../Debugger/Qt3DSStateDebugStreams.cpp | 534 ---- .../Debugger/Qt3DSStateDebugStreams.h | 102 - .../Debugger/Qt3DSStateDebuggedInterpreter.cpp | 302 -- .../Debugger/Qt3DSStateDebugger.cpp | 312 -- .../Debugger/Qt3DSStateDebugger.h | 386 --- .../Debugger/Qt3DSStateDebuggerListener.cpp | 322 --- .../Debugger/Qt3DSStateDebuggerProtocol.h | 925 ------ .../Debugger/Qt3DSStateDebuggerValues.h | 540 ---- .../Debugger/Qt3DSStateTest.h | 88 - .../Editor/Qt3DSSceneGraphArchitectDebugger.cpp | 574 ---- .../Editor/Qt3DSStateDebuggerMaster.cpp | 222 -- .../Editor/Qt3DSStateEditor.cpp | 1880 ------------ .../Editor/Qt3DSStateEditor.h | 315 -- .../Editor/Qt3DSStateEditorEditorsImpl.h | 1772 ------------ .../Editor/Qt3DSStateEditorFoundation.h | 81 - .../Editor/Qt3DSStateEditorImpl.h | 406 --- .../Editor/Qt3DSStateEditorProperties.h | 599 ---- .../Editor/Qt3DSStateEditorTransactionImpl.cpp | 239 -- .../Editor/Qt3DSStateEditorTransactionImpl.h | 195 -- .../Editor/Qt3DSStateEditorTransitionPath.cpp | 813 ------ .../Editor/Qt3DSStateEditorTransitionPath.h | 467 --- .../Editor/Qt3DSStateEditorValue.h | 271 -- .../Editor/Qt3DSUIADatamodel.cpp | 2527 ----------------- .../Editor/Qt3DSUIADatamodel.h | 174 -- .../Editor/Qt3DSUIADatamodelValue.h | 291 -- .../Qt3DSStateApplication/Include/Qt3DSState.h | 108 - .../Include/Qt3DSStateContext.h | 95 - .../Include/Qt3DSStateExecutionContext.h | 73 - .../Include/Qt3DSStateExecutionTypes.h | 392 --- .../Include/Qt3DSStateIdValue.h | 173 -- .../Include/Qt3DSStateInterpreter.h | 121 - .../Include/Qt3DSStateScriptContext.h | 128 - .../Include/Qt3DSStateSharedImpl.h | 117 - .../Include/Qt3DSStateSignalConnection.h | 49 - .../Include/Qt3DSStateTypes.h | 720 ----- .../Include/Qt3DSStateVisualBindingContext.h | 116 - .../Qt3DSStateVisualBindingContextCommands.h | 348 --- .../Include/Qt3DSStateVisualBindingContextValues.h | 253 -- .../Include/Qt3DSStateXMLIO.h | 112 - .../Source/Qt3DSStateContext.cpp | 202 -- .../Source/Qt3DSStateExecutionContext.cpp | 332 --- .../Source/Qt3DSStateInterpreter.cpp | 2057 -------------- .../Source/Qt3DSStateVisualBindingContext.cpp | 626 ---- .../Source/Qt3DSStateXMLIO.cpp | 1948 ------------- .../Runtime/Include/Qt3DSActivationManager.h | 157 - .../Source/Runtime/Include/Qt3DSAnimationSystem.h | 68 - .../Source/Runtime/Include/Qt3DSApplication.h | 240 -- .../Runtime/Include/Qt3DSApplicationValues.h | 369 --- .../Source/Runtime/Include/Qt3DSAttributeHashes.h | 279 -- .../Runtime/Include/Qt3DSAttributeHashes.txt | 242 -- .../Runtime/Include/Qt3DSCommandEventTypes.h | 83 - .../Source/Runtime/Include/Qt3DSCommandHelper.h | 55 - .../Source/Runtime/Include/Qt3DSComponentManager.h | 143 - .../Source/Runtime/Include/Qt3DSElementHelper.h | 57 - .../Source/Runtime/Include/Qt3DSElementSystem.h | 606 ---- src/Runtime/Source/Runtime/Include/Qt3DSEvent.h | 62 - .../Source/Runtime/Include/Qt3DSEventCallbacks.h | 135 - .../Source/Runtime/Include/Qt3DSFrameworkTypes.h | 52 - .../Runtime/Include/Qt3DSIComponentManager.h | 147 - .../Source/Runtime/Include/Qt3DSIInputSystem.h | 62 - src/Runtime/Source/Runtime/Include/Qt3DSIScene.h | 177 -- .../Source/Runtime/Include/Qt3DSIScriptBridge.h | 184 -- .../Source/Runtime/Include/Qt3DSIStateful.h | 69 - src/Runtime/Source/Runtime/Include/Qt3DSIText.h | 52 - .../Source/Runtime/Include/Qt3DSInputDefs.h | 413 --- .../Source/Runtime/Include/Qt3DSInputEngine.h | 125 - .../Source/Runtime/Include/Qt3DSInputEventTypes.h | 96 - .../Source/Runtime/Include/Qt3DSInputFrame.h | 118 - .../Source/Runtime/Include/Qt3DSKernelTypes.h | 223 -- .../Source/Runtime/Include/Qt3DSLogicSystem.h | 60 - .../Runtime/Include/Qt3DSOutputMemoryStream.h | 123 - .../Source/Runtime/Include/Qt3DSParametersSystem.h | 66 - .../Source/Runtime/Include/Qt3DSPickFrame.h | 70 - .../Source/Runtime/Include/Qt3DSPresentation.h | 226 -- .../Runtime/Include/Qt3DSPresentationFrameData.h | 87 - .../Source/Runtime/Include/Qt3DSQmlElementHelper.h | 57 - .../Source/Runtime/Include/Qt3DSQmlEngine.h | 225 -- .../Source/Runtime/Include/Qt3DSRuntimeFactory.h | 116 - .../Source/Runtime/Include/Qt3DSSceneManager.h | 167 -- .../Source/Runtime/Include/Qt3DSSlideSystem.h | 151 - .../Source/Runtime/Include/Qt3DSTimePolicy.h | 124 - src/Runtime/Source/Runtime/Include/RuntimePrefix.h | 104 - .../Source/Runtime/Include/q3dsqmlbehavior.h | 83 - src/Runtime/Source/Runtime/Include/q3dsqmlscript.h | 105 - .../Source/Runtime/Include/q3dsvariantconfig_p.h | 79 - .../Runtime/Source/Qt3DSActivationManager.cpp | 1027 ------- .../Source/Runtime/Source/Qt3DSAnimationSystem.cpp | 432 --- .../Source/Runtime/Source/Qt3DSApplication.cpp | 1831 ------------ .../Source/Runtime/Source/Qt3DSAttributeHashes.cpp | 289 -- .../Source/Runtime/Source/Qt3DSCommandHelper.cpp | 129 - .../Runtime/Source/Qt3DSComponentManager.cpp | 480 ---- .../Source/Runtime/Source/Qt3DSElementHelper.cpp | 141 - .../Source/Runtime/Source/Qt3DSElementSystem.cpp | 855 ------ .../Source/Runtime/Source/Qt3DSEventCallbacks.cpp | 258 -- .../Source/Runtime/Source/Qt3DSInputEngine.cpp | 849 ------ .../Source/Runtime/Source/Qt3DSLogicSystem.cpp | 293 -- .../Runtime/Source/Qt3DSOutputMemoryStream.cpp | 150 - .../Runtime/Source/Qt3DSParametersSystem.cpp | 171 -- .../Source/Runtime/Source/Qt3DSPresentation.cpp | 784 ----- .../Runtime/Source/Qt3DSPresentationFrameData.cpp | 105 - .../Runtime/Source/Qt3DSQmlElementHelper.cpp | 319 --- .../Source/Runtime/Source/Qt3DSQmlEngine.cpp | 1346 --------- .../Source/Runtime/Source/Qt3DSSlideSystem.cpp | 541 ---- .../Source/Runtime/Source/Qt3DSTimePolicy.cpp | 407 --- .../Source/Runtime/Source/q3dsqmlbehavior.cpp | 123 - .../Source/Runtime/Source/q3dsqmlscript.cpp | 403 --- .../Source/Runtime/Source/q3dsvariantconfig.cpp | 122 - src/Runtime/Source/System/Include/Qt3DSArray.h | 135 - src/Runtime/Source/System/Include/Qt3DSArray.inl | 287 -- src/Runtime/Source/System/Include/Qt3DSAssert.h | 78 - .../Source/System/Include/Qt3DSAudioPlayer.h | 42 - .../Source/System/Include/Qt3DSBasicPluginDLL.h | 67 - .../Source/System/Include/Qt3DSBezierEval.h | 182 -- .../Source/System/Include/Qt3DSBoundingBox.h | 85 - .../Source/System/Include/Qt3DSCircularArray.h | 102 - .../Source/System/Include/Qt3DSCircularArray.inl | 225 -- src/Runtime/Source/System/Include/Qt3DSColor.h | 85 - src/Runtime/Source/System/Include/Qt3DSConfig.h | 49 - .../Source/System/Include/Qt3DSCubicRoots.h | 78 - .../Source/System/Include/Qt3DSCubicRootsImpl.h | 177 -- .../Source/System/Include/Qt3DSDLLManager.h | 96 - .../Source/System/Include/Qt3DSDataLogger.h | 226 -- .../Source/System/Include/Qt3DSDataLogger.hpp | 96 - .../Source/System/Include/Qt3DSDataLoggerEnums.h | 117 - .../Source/System/Include/Qt3DSDataLoggerViewer.h | 71 - src/Runtime/Source/System/Include/Qt3DSEGLTimer.h | 70 - src/Runtime/Source/System/Include/Qt3DSEndian.h | 38 - .../Source/System/Include/Qt3DSEulerAngles.h | 141 - src/Runtime/Source/System/Include/Qt3DSFNDTimer.h | 44 - src/Runtime/Source/System/Include/Qt3DSFile.h | 94 - .../Source/System/Include/Qt3DSFileStream.h | 93 - .../Source/System/Include/Qt3DSFixedArray.h | 87 - .../Source/System/Include/Qt3DSFixedArray.inl | 150 - .../Source/System/Include/Qt3DSFunctionWrappers.h | 416 --- src/Runtime/Source/System/Include/Qt3DSHash.h | 105 - .../Source/System/Include/Qt3DSIFileStream.h | 56 - src/Runtime/Source/System/Include/Qt3DSIStream.h | 162 -- src/Runtime/Source/System/Include/Qt3DSITimer.h | 61 - src/Runtime/Source/System/Include/Qt3DSMacros.h | 189 -- src/Runtime/Source/System/Include/Qt3DSMatrix.h | 146 - src/Runtime/Source/System/Include/Qt3DSMemory.h | 183 -- .../Source/System/Include/Qt3DSMemoryFilter.h | 69 - .../Source/System/Include/Qt3DSMemoryHeap.h | 133 - .../Source/System/Include/Qt3DSMemoryManager.h | 133 - .../Source/System/Include/Qt3DSMemoryPool.h | 104 - .../Source/System/Include/Qt3DSMemoryProbe.h | 144 - .../Source/System/Include/Qt3DSMemorySettings.h | 131 - .../Source/System/Include/Qt3DSMemoryStatistics.h | 137 - .../Source/System/Include/Qt3DSMemoryTracker.h | 104 - .../Source/System/Include/Qt3DSPlatformSpecific.h | 207 -- src/Runtime/Source/System/Include/Qt3DSTimer.h | 142 - src/Runtime/Source/System/Include/Qt3DSTypes.h | 236 -- src/Runtime/Source/System/Include/Qt3DSVector3.h | 117 - src/Runtime/Source/System/Include/SystemPrefix.h | 92 - src/Runtime/Source/System/Source/Qt3DSAssert.cpp | 93 - .../Source/System/Source/Qt3DSBoundingBox.cpp | 150 - src/Runtime/Source/System/Source/Qt3DSColor.cpp | 95 - .../Source/System/Source/Qt3DSCubicRoots.cpp | 38 - .../Source/System/Source/Qt3DSDLLManager.cpp | 220 -- .../Source/System/Source/Qt3DSDataLogger.cpp | 151 - .../Source/System/Source/Qt3DSEulerAngles.cpp | 390 --- src/Runtime/Source/System/Source/Qt3DSFile.cpp | 77 - .../Source/System/Source/Qt3DSFileStream.cpp | 237 -- .../Source/System/Source/Qt3DSFunctionWrappers.cpp | 65 - src/Runtime/Source/System/Source/Qt3DSMatrix.cpp | 897 ------ src/Runtime/Source/System/Source/Qt3DSMemory.cpp | 137 - .../Source/System/Source/Qt3DSMemoryFilter.cpp | 126 - .../Source/System/Source/Qt3DSMemoryHeap.cpp | 236 -- .../Source/System/Source/Qt3DSMemoryManager.cpp | 453 --- .../Source/System/Source/Qt3DSMemoryPool.cpp | 298 -- .../Source/System/Source/Qt3DSMemoryProbe.cpp | 149 - .../Source/System/Source/Qt3DSMemoryStatistics.cpp | 647 ----- .../Source/System/Source/Qt3DSMemoryTracker.cpp | 164 -- src/Runtime/Source/System/Source/Qt3DSTimer.cpp | 116 - src/Runtime/Source/System/Source/Qt3DSTypes.cpp | 54 - src/Runtime/Source/System/Source/Qt3DSVector3.cpp | 466 --- .../Source/UIPParser/Include/Qt3DSIPresentation.h | 176 -- .../Source/UIPParser/Include/Qt3DSUIPParser.h | 153 - .../UIPParser/Include/Qt3DSUIPParserActionHelper.h | 172 -- .../Source/UIPParser/Include/Qt3DSUIPParserImpl.h | 664 ----- .../Include/Qt3DSUIPParserObjectRefHelper.h | 159 -- .../Source/Qt3DSUIPParserActionHelper.cpp | 738 ----- .../Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp | 2587 ----------------- .../Source/Qt3DSUIPParserObjectRefHelper.cpp | 1005 ------- .../Viewer/PerfLog/SimpleTCPClientSocket.cpp | 241 -- .../Source/Viewer/PerfLog/SimpleTCPClientSocket.h | 77 - .../Viewer/PerfLog/SimpleTCPServerSocket.cpp | 255 -- .../Source/Viewer/PerfLog/SimpleTCPServerSocket.h | 84 - .../Source/Viewer/PerfLog/TCPPerfLogClient.cpp | 476 ---- .../Source/Viewer/PerfLog/TCPPerfLogClient.h | 376 --- .../Source/Viewer/PerfLog/TCPPerfLogClientStub.h | 58 - .../Source/Viewer/PerfLog/TCPPerfLogCommon.h | 98 - .../Source/Viewer/PerfLog/TCPPerfLogServer.cpp | 157 - .../Source/Viewer/PerfLog/TCPPerfLogServer.h | 58 - src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.cpp | 60 - src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.h | 48 - src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp | 766 ----- src/Runtime/Source/Viewer/Qt3DSViewerApp.h | 390 --- src/Runtime/Source/Viewer/Qt3DSViewerTimer.h | 120 - src/Runtime/Source/Viewer/qt3dsruntimeglobal.h | 45 - .../DocumentResourceManagerCustomMaterialParser.h | 80 + .../DocumentResourceManagerRenderPluginParser.h | 80 + .../DocumentResourceManagerScriptParser.h | 137 + src/Runtime/Source/datamodel/Qt3DSMetadata.cpp | 985 +++++++ src/Runtime/Source/datamodel/Qt3DSMetadata.h | 380 +++ src/Runtime/Source/engine/EnginePrefix.h | 143 + src/Runtime/Source/engine/NVImageScaler.h | 311 ++ src/Runtime/Source/engine/OpenKodeInclude.h | 49 + src/Runtime/Source/engine/Qt3DSEGLInfo.h | 60 + src/Runtime/Source/engine/Qt3DSEGLWindowSystem.h | 81 + src/Runtime/Source/engine/Qt3DSPluginDLL.h | 128 + .../Source/engine/Qt3DSRenderRuntimeBinding.cpp | 1990 +++++++++++++ .../Source/engine/Qt3DSRenderRuntimeBinding.h | 82 + .../Source/engine/Qt3DSRenderRuntimeBindingImpl.h | 210 ++ .../Qt3DSRenderRuntimeBindingImplRenderer.cpp | 224 ++ .../Qt3DSRenderRuntimeBindingImplTranslation.cpp | 1811 ++++++++++++ .../Source/engine/Qt3DSTegraApplication.cpp | 746 +++++ src/Runtime/Source/engine/Qt3DSTegraApplication.h | 322 +++ .../Source/engine/Qt3DSTegraInputEngine.cpp | 124 + src/Runtime/Source/engine/Qt3DSTegraInputEngine.h | 81 + src/Runtime/Source/engine/Qt3DSWindowSystem.h | 57 + src/Runtime/Source/event/EventFactory.cpp | 143 + src/Runtime/Source/event/EventFactory.h | 87 + src/Runtime/Source/event/EventPoller.cpp | 375 +++ src/Runtime/Source/event/EventPoller.h | 103 + src/Runtime/Source/event/EventPollingSystem.h | 87 + src/Runtime/Source/event/EventSystem.h | 73 + src/Runtime/Source/event/EventSystemC.cpp | 34 + src/Runtime/Source/event/EventSystemC.h | 139 + src/Runtime/Source/event/test/CanProviderDemo.cpp | 259 ++ src/Runtime/Source/event/test/CanProviderDemo.h | 56 + .../Source/foundation/AutoDeallocatorAllocator.h | 99 + src/Runtime/Source/foundation/ConvertUTF.cpp | 661 +++++ src/Runtime/Source/foundation/ConvertUTF.h | 179 ++ src/Runtime/Source/foundation/EASTL_new.cpp | 75 + src/Runtime/Source/foundation/FastAllocator.h | 115 + src/Runtime/Source/foundation/FileTools.cpp | 545 ++++ src/Runtime/Source/foundation/FileTools.h | 124 + src/Runtime/Source/foundation/IOStreams.cpp | 384 +++ src/Runtime/Source/foundation/IOStreams.h | 278 ++ src/Runtime/Source/foundation/LICENCE_SOCKET.TXT | 20 + .../Source/foundation/LICENSE_CONVERTUTF.TXT | 19 + src/Runtime/Source/foundation/PoolingAllocator.h | 177 ++ .../Source/foundation/PreAllocatedAllocator.h | 88 + src/Runtime/Source/foundation/Qt3DS.h | 59 + src/Runtime/Source/foundation/Qt3DSAllocator.h | 195 ++ .../Source/foundation/Qt3DSAllocatorCallback.h | 100 + src/Runtime/Source/foundation/Qt3DSAssert.h | 62 + src/Runtime/Source/foundation/Qt3DSAtomic.h | 63 + .../Source/foundation/Qt3DSBasicTemplates.h | 113 + src/Runtime/Source/foundation/Qt3DSBounds3.h | 443 +++ .../Source/foundation/Qt3DSBroadcastingAllocator.h | 113 + src/Runtime/Source/foundation/Qt3DSContainers.h | 129 + src/Runtime/Source/foundation/Qt3DSDataRef.h | 162 ++ .../Source/foundation/Qt3DSDiscriminatedUnion.h | 335 +++ src/Runtime/Source/foundation/Qt3DSFPU.h | 97 + src/Runtime/Source/foundation/Qt3DSFastIPC.h | 57 + src/Runtime/Source/foundation/Qt3DSFlags.h | 360 +++ src/Runtime/Source/foundation/Qt3DSFoundation.cpp | 237 ++ src/Runtime/Source/foundation/Qt3DSFoundation.h | 120 + src/Runtime/Source/foundation/Qt3DSIPC.h | 99 + .../Source/foundation/Qt3DSIndexableLinkedList.h | 309 ++ src/Runtime/Source/foundation/Qt3DSIntrinsics.h | 50 + .../Source/foundation/Qt3DSInvasiveLinkedList.h | 361 +++ src/Runtime/Source/foundation/Qt3DSInvasiveSet.h | 104 + src/Runtime/Source/foundation/Qt3DSLogging.cpp | 44 + src/Runtime/Source/foundation/Qt3DSLogging.h | 51 + src/Runtime/Source/foundation/Qt3DSMat33.h | 385 +++ src/Runtime/Source/foundation/Qt3DSMat44.h | 497 ++++ src/Runtime/Source/foundation/Qt3DSMath.h | 323 +++ src/Runtime/Source/foundation/Qt3DSMathUtils.cpp | 181 ++ src/Runtime/Source/foundation/Qt3DSMathUtils.h | 571 ++++ src/Runtime/Source/foundation/Qt3DSMemoryBuffer.h | 160 ++ src/Runtime/Source/foundation/Qt3DSMutex.h | 376 +++ src/Runtime/Source/foundation/Qt3DSNoCopy.h | 50 + src/Runtime/Source/foundation/Qt3DSOption.h | 104 + src/Runtime/Source/foundation/Qt3DSPerfTimer.cpp | 163 ++ src/Runtime/Source/foundation/Qt3DSPerfTimer.h | 107 + src/Runtime/Source/foundation/Qt3DSPlane.h | 134 + src/Runtime/Source/foundation/Qt3DSPool.h | 159 ++ src/Runtime/Source/foundation/Qt3DSPreprocessor.h | 375 +++ src/Runtime/Source/foundation/Qt3DSQuat.h | 381 +++ src/Runtime/Source/foundation/Qt3DSRefCounted.h | 199 ++ src/Runtime/Source/foundation/Qt3DSSemaphore.h | 67 + src/Runtime/Source/foundation/Qt3DSSimpleTypes.h | 117 + .../Source/foundation/Qt3DSStringTokenizer.h | 108 + src/Runtime/Source/foundation/Qt3DSSync.h | 70 + src/Runtime/Source/foundation/Qt3DSSystem.cpp | 139 + src/Runtime/Source/foundation/Qt3DSSystem.h | 58 + src/Runtime/Source/foundation/Qt3DSThread.h | 205 ++ src/Runtime/Source/foundation/Qt3DSTime.h | 97 + src/Runtime/Source/foundation/Qt3DSTransform.h | 195 ++ src/Runtime/Source/foundation/Qt3DSUnionCast.h | 64 + src/Runtime/Source/foundation/Qt3DSUtilities.h | 189 ++ src/Runtime/Source/foundation/Qt3DSVec2.h | 321 +++ src/Runtime/Source/foundation/Qt3DSVec3.h | 377 +++ src/Runtime/Source/foundation/Qt3DSVec4.h | 373 +++ src/Runtime/Source/foundation/Qt3DSVersionNumber.h | 67 + src/Runtime/Source/foundation/SerializationTypes.h | 132 + src/Runtime/Source/foundation/Socket.cpp | 472 +++ src/Runtime/Source/foundation/Socket.h | 79 + src/Runtime/Source/foundation/StrConvertUTF.h | 213 ++ src/Runtime/Source/foundation/StringConversion.h | 226 ++ .../Source/foundation/StringConversionImpl.h | 213 ++ src/Runtime/Source/foundation/StringTable.cpp | 672 +++++ src/Runtime/Source/foundation/StringTable.h | 291 ++ src/Runtime/Source/foundation/TaggedPointer.h | 80 + src/Runtime/Source/foundation/ThreadSafeQueue.h | 111 + .../Source/foundation/TrackingAllocator.cpp | 50 + src/Runtime/Source/foundation/TrackingAllocator.h | 252 ++ src/Runtime/Source/foundation/Utils.h | 382 +++ src/Runtime/Source/foundation/XML.cpp | 1008 +++++++ src/Runtime/Source/foundation/XML.h | 680 +++++ src/Runtime/Source/foundation/linux/LICENSE.TXT | 7 + .../Source/foundation/linux/Qt3DSLinuxAoS.h | 157 + .../Source/foundation/linux/Qt3DSLinuxAtomic.cpp | 129 + .../Source/foundation/linux/Qt3DSLinuxFPU.cpp | 52 + .../Source/foundation/linux/Qt3DSLinuxFile.h | 48 + .../Source/foundation/linux/Qt3DSLinuxInlineAoS.h | 2666 +++++++++++++++++ .../Source/foundation/linux/Qt3DSLinuxIntrinsics.h | 209 ++ .../Source/foundation/linux/Qt3DSLinuxMutex.cpp | 120 + .../foundation/linux/Qt3DSLinuxSemaphore.cpp | 146 + .../Source/foundation/linux/Qt3DSLinuxString.h | 202 ++ .../Source/foundation/linux/Qt3DSLinuxSync.cpp | 137 + .../Source/foundation/linux/Qt3DSLinuxThread.cpp | 384 +++ .../Source/foundation/linux/Qt3DSLinuxTime.cpp | 111 + .../foundation/linux/Qt3DSLinuxTrigConstants.h | 96 + src/Runtime/Source/foundation/linux/SocketImpl.h | 424 +++ .../Source/foundation/linux/qt_attribution.json | 10 + .../Source/foundation/macos/Qt3DSUnixAtomic.cpp | 89 + .../Source/foundation/macos/Qt3DSUnixFPU.cpp | 61 + .../Source/foundation/macos/Qt3DSUnixMutex.cpp | 120 + .../Source/foundation/macos/Qt3DSUnixSemaphore.cpp | 146 + .../Source/foundation/macos/Qt3DSUnixSync.cpp | 137 + .../Source/foundation/macos/Qt3DSUnixTime.cpp | 108 + src/Runtime/Source/foundation/qt_attribution.json | 22 + src/Runtime/Source/foundation/windows/LICENSE.TXT | 7 + .../Source/foundation/windows/Qt3DSWindowsAoS.h | 126 + .../foundation/windows/Qt3DSWindowsAtomic.cpp | 93 + .../Source/foundation/windows/Qt3DSWindowsFPU.cpp | 61 + .../Source/foundation/windows/Qt3DSWindowsFile.h | 48 + .../foundation/windows/Qt3DSWindowsInclude.h | 93 + .../foundation/windows/Qt3DSWindowsInlineAoS.h | 2715 ++++++++++++++++++ .../foundation/windows/Qt3DSWindowsIntrinsics.h | 230 ++ .../foundation/windows/Qt3DSWindowsMutex.cpp | 149 + .../foundation/windows/Qt3DSWindowsSemaphore.cpp | 72 + .../Source/foundation/windows/Qt3DSWindowsString.h | 147 + .../Source/foundation/windows/Qt3DSWindowsSync.cpp | 74 + .../foundation/windows/Qt3DSWindowsThread.cpp | 241 ++ .../Source/foundation/windows/Qt3DSWindowsTime.cpp | 92 + .../foundation/windows/Qt3DSWindowsTrigConstants.h | 93 + src/Runtime/Source/foundation/windows/SocketImpl.h | 506 ++++ .../Source/foundation/windows/qt_attribution.json | 10 + src/Runtime/Source/hdr/CUDABSDFMipmap.cpp | 145 + src/Runtime/Source/hdr/CUDABSDFMipmap.h | 77 + src/Runtime/Source/hdr/GLComputeMipMap.h | 74 + src/Runtime/Source/hdr/GLComputeMipmap.cpp | 394 +++ src/Runtime/Source/hdr/HDR.cpp | 30 + src/Runtime/Source/hdr/HDR.h | 239 ++ src/Runtime/Source/hdr/MipmapBSDF.cpp | 265 ++ src/Runtime/Source/hdr/MipmapBSDF.cu | 404 +++ src/Runtime/Source/hdr/MipmapBSDF.h | 104 + .../android/jni/libs/nv_math/NvVec.h | 316 +++ .../android/jni/libs/nv_math/misc.h | 130 + .../android/jni/libs/nv_math/nv_math.cpp | 64 + .../android/jni/libs/nv_math/nv_math.h | 45 + .../android/jni/libs/nv_math/nv_matrix.cpp | 1030 +++++++ .../android/jni/libs/nv_math/nv_matrix.h | 117 + .../android/jni/libs/nv_math/nv_quat.cpp | 199 ++ .../android/jni/libs/nv_math/nv_quat.h | 63 + .../linux/assets/courier+lucida_256.abc | Bin 0 -> 2048 bytes .../linux/assets/courier+lucida_256.dds | Bin 0 -> 87509 bytes .../linux/assets/courier+lucida_512.abc | Bin 0 -> 2048 bytes .../linux/assets/courier+lucida_512.dds | Bin 0 -> 349653 bytes .../Source/platformspecific/linux/assets/font.frag | 39 + .../Source/platformspecific/linux/assets/font.vert | 49 + .../Source/platformspecific/linux/libs/nv_color.h | 107 + .../Source/platformspecific/linux/libs/nv_debug.h | 86 + .../Source/platformspecific/linux/libs/nv_global.h | 36 + .../platformspecific/linux/libs/nv_math/NvVec.h | 316 +++ .../platformspecific/linux/libs/nv_math/misc.h | 130 + .../linux/libs/nv_math/nv_math.cpp | 64 + .../platformspecific/linux/libs/nv_math/nv_math.h | 45 + .../linux/libs/nv_math/nv_matrix.cpp | 1030 +++++++ .../linux/libs/nv_math/nv_matrix.h | 118 + .../linux/libs/nv_math/nv_quat.cpp | 203 ++ .../platformspecific/linux/libs/nv_math/nv_quat.h | 64 + .../Source/platformspecific/linux/libs/nv_types.h | 81 + .../macos/assets/courier+lucida_256.abc | Bin 0 -> 2048 bytes .../macos/assets/courier+lucida_256.dds | Bin 0 -> 87509 bytes .../macos/assets/courier+lucida_512.abc | Bin 0 -> 2048 bytes .../macos/assets/courier+lucida_512.dds | Bin 0 -> 349653 bytes .../Source/platformspecific/macos/assets/font.frag | 39 + .../Source/platformspecific/macos/assets/font.vert | 49 + .../Source/platformspecific/macos/libs/nv_color.h | 107 + .../Source/platformspecific/macos/libs/nv_debug.h | 86 + .../Source/platformspecific/macos/libs/nv_global.h | 36 + .../platformspecific/macos/libs/nv_math/NvVec.h | 316 +++ .../platformspecific/macos/libs/nv_math/misc.h | 130 + .../macos/libs/nv_math/nv_math.cpp | 64 + .../platformspecific/macos/libs/nv_math/nv_math.h | 45 + .../macos/libs/nv_math/nv_matrix.cpp | 1030 +++++++ .../macos/libs/nv_math/nv_matrix.h | 117 + .../macos/libs/nv_math/nv_quat.cpp | 199 ++ .../platformspecific/macos/libs/nv_math/nv_quat.h | 63 + .../Source/platformspecific/macos/libs/nv_types.h | 81 + .../windows/assets/courier+lucida_256.abc | Bin 0 -> 2048 bytes .../windows/assets/courier+lucida_256.dds | Bin 0 -> 87509 bytes .../windows/assets/courier+lucida_512.abc | Bin 0 -> 2048 bytes .../windows/assets/courier+lucida_512.dds | Bin 0 -> 349653 bytes .../platformspecific/windows/assets/font.frag | 39 + .../platformspecific/windows/assets/font.vert | 49 + .../platformspecific/windows/libs/nv_color.h | 107 + .../windows/libs/nv_config/nv_config.h | 278 ++ .../platformspecific/windows/libs/nv_debug.h | 86 + .../platformspecific/windows/libs/nv_global.h | 36 + .../platformspecific/windows/libs/nv_math/NvVec.h | 316 +++ .../platformspecific/windows/libs/nv_math/misc.h | 130 + .../windows/libs/nv_math/nv_math.cpp | 64 + .../windows/libs/nv_math/nv_math.h | 45 + .../windows/libs/nv_math/nv_matrix.cpp | 1030 +++++++ .../windows/libs/nv_math/nv_matrix.h | 117 + .../windows/libs/nv_math/nv_quat.cpp | 199 ++ .../windows/libs/nv_math/nv_quat.h | 63 + .../platformspecific/windows/libs/nv_types.h | 81 + .../windows/libs/qt3ds_launcher_defs.h | 92 + .../platformspecific/windows/viewer/Resource.h | 43 + .../Examples/Qt3DSRenderClearColorExample.cpp | 63 + .../Source/render/Examples/Qt3DSRenderExample.cpp | 491 ++++ .../Source/render/Examples/Qt3DSRenderExample.h | 123 + .../render/Examples/Qt3DSRenderExampleTools.cpp | 188 ++ .../render/Examples/Qt3DSRenderExampleTools.h | 89 + .../Examples/Qt3DSRenderRenderToTextureExample.cpp | 178 ++ .../Examples/Qt3DSRenderSpinningCubeExample.cpp | 104 + .../render/Qt3DSRenderAtomicCounterBuffer.cpp | 156 + .../Source/render/Qt3DSRenderAtomicCounterBuffer.h | 182 ++ .../Source/render/Qt3DSRenderAttribLayout.cpp | 57 + .../Source/render/Qt3DSRenderAttribLayout.h | 90 + src/Runtime/Source/render/Qt3DSRenderBaseTypes.h | 2100 ++++++++++++++ .../Source/render/Qt3DSRenderComputeShader.cpp | 55 + .../Source/render/Qt3DSRenderComputeShader.h | 89 + .../Source/render/Qt3DSRenderConstantBuffer.cpp | 421 +++ .../Source/render/Qt3DSRenderConstantBuffer.h | 248 ++ src/Runtime/Source/render/Qt3DSRenderContext.cpp | 1107 ++++++++ src/Runtime/Source/render/Qt3DSRenderContext.h | 1063 +++++++ .../Source/render/Qt3DSRenderDataBuffer.cpp | 158 ++ src/Runtime/Source/render/Qt3DSRenderDataBuffer.h | 188 ++ .../Source/render/Qt3DSRenderDepthStencilState.cpp | 91 + .../Source/render/Qt3DSRenderDepthStencilState.h | 134 + .../render/Qt3DSRenderDrawIndirectBuffer.cpp | 104 + .../Source/render/Qt3DSRenderDrawIndirectBuffer.h | 152 + src/Runtime/Source/render/Qt3DSRenderDrawable.h | 54 + .../Source/render/Qt3DSRenderFragmentShader.cpp | 55 + .../Source/render/Qt3DSRenderFragmentShader.h | 89 + .../Source/render/Qt3DSRenderFrameBuffer.cpp | 300 ++ src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h | 277 ++ .../Source/render/Qt3DSRenderGeometryShader.cpp | 55 + .../Source/render/Qt3DSRenderGeometryShader.h | 89 + .../Source/render/Qt3DSRenderImageTexture.cpp | 103 + .../Source/render/Qt3DSRenderImageTexture.h | 143 + .../Source/render/Qt3DSRenderIndexBuffer.cpp | 100 + src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h | 138 + .../Source/render/Qt3DSRenderInputAssembler.cpp | 105 + .../Source/render/Qt3DSRenderInputAssembler.h | 157 + .../Source/render/Qt3DSRenderOcclusionQuery.cpp | 82 + .../Source/render/Qt3DSRenderOcclusionQuery.h | 120 + .../render/Qt3DSRenderPathFontSpecification.cpp | 145 + .../render/Qt3DSRenderPathFontSpecification.h | 165 ++ .../Source/render/Qt3DSRenderPathFontText.cpp | 191 ++ .../Source/render/Qt3DSRenderPathFontText.h | 139 + .../Source/render/Qt3DSRenderPathRender.cpp | 108 + src/Runtime/Source/render/Qt3DSRenderPathRender.h | 114 + .../Source/render/Qt3DSRenderPathSpecification.cpp | 103 + .../Source/render/Qt3DSRenderPathSpecification.h | 141 + .../Source/render/Qt3DSRenderProgramPipeline.cpp | 134 + .../Source/render/Qt3DSRenderProgramPipeline.h | 138 + src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp | 54 + src/Runtime/Source/render/Qt3DSRenderQueryBase.h | 127 + .../Source/render/Qt3DSRenderRasterizerState.cpp | 71 + .../Source/render/Qt3DSRenderRasterizerState.h | 94 + .../Source/render/Qt3DSRenderRenderBuffer.cpp | 114 + .../Source/render/Qt3DSRenderRenderBuffer.h | 158 ++ src/Runtime/Source/render/Qt3DSRenderSampler.cpp | 84 + src/Runtime/Source/render/Qt3DSRenderSampler.h | 124 + src/Runtime/Source/render/Qt3DSRenderShader.h | 123 + .../Source/render/Qt3DSRenderShaderConstant.h | 448 +++ .../Source/render/Qt3DSRenderShaderProgram.cpp | 1248 ++++++++ .../Source/render/Qt3DSRenderShaderProgram.h | 540 ++++ .../Source/render/Qt3DSRenderStorageBuffer.cpp | 123 + .../Source/render/Qt3DSRenderStorageBuffer.h | 158 ++ src/Runtime/Source/render/Qt3DSRenderSync.cpp | 87 + src/Runtime/Source/render/Qt3DSRenderSync.h | 132 + .../render/Qt3DSRenderTessellationShader.cpp | 74 + .../Source/render/Qt3DSRenderTessellationShader.h | 132 + src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp | 263 ++ src/Runtime/Source/render/Qt3DSRenderTexture2D.h | 165 ++ .../Source/render/Qt3DSRenderTexture2DArray.cpp | 123 + .../Source/render/Qt3DSRenderTexture2DArray.h | 106 + .../Source/render/Qt3DSRenderTextureBase.cpp | 167 ++ src/Runtime/Source/render/Qt3DSRenderTextureBase.h | 177 ++ .../Source/render/Qt3DSRenderTextureCube.cpp | 119 + src/Runtime/Source/render/Qt3DSRenderTextureCube.h | 106 + .../Source/render/Qt3DSRenderTimerQuery.cpp | 75 + src/Runtime/Source/render/Qt3DSRenderTimerQuery.h | 129 + .../Source/render/Qt3DSRenderVertexBuffer.cpp | 74 + .../Source/render/Qt3DSRenderVertexBuffer.h | 124 + .../Source/render/Qt3DSRenderVertexShader.cpp | 54 + .../Source/render/Qt3DSRenderVertexShader.h | 89 + .../Source/render/backends/Qt3DSRenderBackend.h | 2245 +++++++++++++++ .../render/backends/gl/Q3DSRenderBackendGLES2.cpp | 887 ++++++ .../render/backends/gl/Q3DSRenderBackendGLES2.h | 193 ++ .../render/backends/gl/Qt3DSOpenGLExtensions.cpp | 170 ++ .../render/backends/gl/Qt3DSOpenGLExtensions.h | 392 +++ .../Source/render/backends/gl/Qt3DSOpenGLPrefix.h | 48 + .../Source/render/backends/gl/Qt3DSOpenGLTokens.h | 408 +++ .../Source/render/backends/gl/Qt3DSOpenGLUtil.h | 2201 ++++++++++++++ .../render/backends/gl/Qt3DSRenderBackendGL3.cpp | 784 +++++ .../render/backends/gl/Qt3DSRenderBackendGL3.h | 171 ++ .../render/backends/gl/Qt3DSRenderBackendGL4.cpp | 875 ++++++ .../render/backends/gl/Qt3DSRenderBackendGL4.h | 205 ++ .../backends/gl/Qt3DSRenderBackendGLBase.cpp | 2220 +++++++++++++++ .../render/backends/gl/Qt3DSRenderBackendGLBase.h | 530 ++++ .../gl/Qt3DSRenderBackendInputAssemblerGL.h | 146 + .../backends/gl/Qt3DSRenderBackendRenderStatesGL.h | 173 ++ .../gl/Qt3DSRenderBackendShaderProgramGL.h | 105 + .../render/backends/gl/Qt3DSRenderContextGL.cpp | 91 + .../backends/software/Qt3DSRenderBackendNULL.cpp | 588 ++++ .../backends/software/Qt3DSRenderBackendNULL.h | 46 + src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h | 83 + .../Source/runtime/Qt3DSActivationManager.cpp | 1027 +++++++ .../Source/runtime/Qt3DSActivationManager.h | 157 + .../Source/runtime/Qt3DSAnimationSystem.cpp | 432 +++ src/Runtime/Source/runtime/Qt3DSAnimationSystem.h | 68 + src/Runtime/Source/runtime/Qt3DSApplication.cpp | 1831 ++++++++++++ src/Runtime/Source/runtime/Qt3DSApplication.h | 240 ++ .../Source/runtime/Qt3DSApplicationValues.h | 369 +++ .../Source/runtime/Qt3DSAttributeHashes.cpp | 289 ++ src/Runtime/Source/runtime/Qt3DSAttributeHashes.h | 279 ++ .../Source/runtime/Qt3DSAttributeHashes.txt | 242 ++ .../Source/runtime/Qt3DSCommandEventTypes.h | 83 + src/Runtime/Source/runtime/Qt3DSCommandHelper.cpp | 129 + src/Runtime/Source/runtime/Qt3DSCommandHelper.h | 55 + .../Source/runtime/Qt3DSComponentManager.cpp | 480 ++++ src/Runtime/Source/runtime/Qt3DSComponentManager.h | 143 + src/Runtime/Source/runtime/Qt3DSElementHelper.cpp | 141 + src/Runtime/Source/runtime/Qt3DSElementHelper.h | 57 + src/Runtime/Source/runtime/Qt3DSElementSystem.cpp | 855 ++++++ src/Runtime/Source/runtime/Qt3DSElementSystem.h | 606 ++++ src/Runtime/Source/runtime/Qt3DSEvent.h | 62 + src/Runtime/Source/runtime/Qt3DSEventCallbacks.cpp | 258 ++ src/Runtime/Source/runtime/Qt3DSEventCallbacks.h | 135 + src/Runtime/Source/runtime/Qt3DSFrameworkTypes.h | 52 + .../Source/runtime/Qt3DSIComponentManager.h | 147 + src/Runtime/Source/runtime/Qt3DSIInputSystem.h | 62 + src/Runtime/Source/runtime/Qt3DSIScene.h | 177 ++ src/Runtime/Source/runtime/Qt3DSIScriptBridge.h | 184 ++ src/Runtime/Source/runtime/Qt3DSIStateful.h | 69 + src/Runtime/Source/runtime/Qt3DSIText.h | 52 + src/Runtime/Source/runtime/Qt3DSInputDefs.h | 413 +++ src/Runtime/Source/runtime/Qt3DSInputEngine.cpp | 849 ++++++ src/Runtime/Source/runtime/Qt3DSInputEngine.h | 125 + src/Runtime/Source/runtime/Qt3DSInputEventTypes.h | 96 + src/Runtime/Source/runtime/Qt3DSInputFrame.h | 118 + src/Runtime/Source/runtime/Qt3DSKernelTypes.h | 223 ++ src/Runtime/Source/runtime/Qt3DSLogicSystem.cpp | 293 ++ src/Runtime/Source/runtime/Qt3DSLogicSystem.h | 60 + .../Source/runtime/Qt3DSOutputMemoryStream.cpp | 150 + .../Source/runtime/Qt3DSOutputMemoryStream.h | 123 + .../Source/runtime/Qt3DSParametersSystem.cpp | 171 ++ src/Runtime/Source/runtime/Qt3DSParametersSystem.h | 66 + src/Runtime/Source/runtime/Qt3DSPickFrame.h | 70 + src/Runtime/Source/runtime/Qt3DSPresentation.cpp | 784 +++++ src/Runtime/Source/runtime/Qt3DSPresentation.h | 226 ++ .../Source/runtime/Qt3DSPresentationFrameData.cpp | 105 + .../Source/runtime/Qt3DSPresentationFrameData.h | 87 + .../Source/runtime/Qt3DSQmlElementHelper.cpp | 319 +++ src/Runtime/Source/runtime/Qt3DSQmlElementHelper.h | 57 + src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp | 1346 +++++++++ src/Runtime/Source/runtime/Qt3DSQmlEngine.h | 225 ++ src/Runtime/Source/runtime/Qt3DSRuntimeFactory.h | 116 + src/Runtime/Source/runtime/Qt3DSSceneManager.h | 167 ++ src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp | 541 ++++ src/Runtime/Source/runtime/Qt3DSSlideSystem.h | 151 + src/Runtime/Source/runtime/Qt3DSTimePolicy.cpp | 407 +++ src/Runtime/Source/runtime/Qt3DSTimePolicy.h | 124 + src/Runtime/Source/runtime/RuntimePrefix.h | 104 + src/Runtime/Source/runtime/q3dsqmlbehavior.cpp | 123 + src/Runtime/Source/runtime/q3dsqmlbehavior.h | 83 + src/Runtime/Source/runtime/q3dsqmlscript.cpp | 403 +++ src/Runtime/Source/runtime/q3dsqmlscript.h | 105 + src/Runtime/Source/runtime/q3dsvariantconfig.cpp | 122 + src/Runtime/Source/runtime/q3dsvariantconfig_p.h | 79 + .../Source/runtimerender/Qt3DSOffscreenRenderKey.h | 153 + .../runtimerender/Qt3DSOffscreenRenderManager.cpp | 498 ++++ .../runtimerender/Qt3DSOffscreenRenderManager.h | 256 ++ .../runtimerender/Qt3DSOldNBustedRenderPlugin.cpp | 118 + .../runtimerender/Qt3DSOldNBustedRenderPlugin.h | 102 + .../runtimerender/Qt3DSOnscreenTextRenderer.cpp | 421 +++ .../Source/runtimerender/Qt3DSQtTextRenderer.cpp | 678 +++++ src/Runtime/Source/runtimerender/Qt3DSRender.h | 254 ++ .../runtimerender/Qt3DSRenderClippingFrustum.cpp | 85 + .../runtimerender/Qt3DSRenderClippingFrustum.h | 161 ++ .../runtimerender/Qt3DSRenderContextCore.cpp | 819 ++++++ .../Source/runtimerender/Qt3DSRenderContextCore.h | 217 ++ .../Qt3DSRenderCustomMaterialRenderContext.h | 94 + .../Qt3DSRenderCustomMaterialShaderGenerator.cpp | 1261 ++++++++ .../Qt3DSRenderCustomMaterialShaderGenerator.h | 69 + .../Qt3DSRenderCustomMaterialSystem.cpp | 2074 ++++++++++++++ .../Qt3DSRenderCustomMaterialSystem.h | 173 ++ .../Qt3DSRenderDefaultMaterialShaderGenerator.cpp | 1930 +++++++++++++ .../Qt3DSRenderDefaultMaterialShaderGenerator.h | 123 + .../Qt3DSRenderDynamicObjectSystem.cpp | 1531 ++++++++++ .../runtimerender/Qt3DSRenderDynamicObjectSystem.h | 286 ++ .../Qt3DSRenderDynamicObjectSystemCommands.h | 622 ++++ .../Qt3DSRenderDynamicObjectSystemUtil.h | 126 + .../runtimerender/Qt3DSRenderEffectSystem.cpp | 1847 ++++++++++++ .../Source/runtimerender/Qt3DSRenderEffectSystem.h | 207 ++ .../runtimerender/Qt3DSRenderEulerAngles.cpp | 383 +++ .../Source/runtimerender/Qt3DSRenderEulerAngles.h | 142 + .../runtimerender/Qt3DSRenderGpuProfiler.cpp | 284 ++ .../Qt3DSRenderGraphObjectPickQuery.h | 124 + .../Qt3DSRenderGraphObjectSerializer.cpp | 670 +++++ .../Qt3DSRenderGraphObjectSerializer.h | 69 + .../runtimerender/Qt3DSRenderGraphObjectTypes.h | 166 ++ .../runtimerender/Qt3DSRenderImageScaler.cpp | 883 ++++++ .../Source/runtimerender/Qt3DSRenderImageScaler.h | 121 + .../runtimerender/Qt3DSRenderImageTextureData.h | 102 + .../Qt3DSRenderInputStreamFactory.cpp | 214 ++ .../runtimerender/Qt3DSRenderInputStreamFactory.h | 69 + .../Qt3DSRenderLightConstantProperties.h | 198 ++ .../runtimerender/Qt3DSRenderMaterialHelpers.h | 94 + .../Qt3DSRenderMaterialShaderGenerator.h | 152 + src/Runtime/Source/runtimerender/Qt3DSRenderMesh.h | 187 ++ .../runtimerender/Qt3DSRenderPathManager.cpp | 1964 +++++++++++++ .../Source/runtimerender/Qt3DSRenderPathManager.h | 121 + .../Source/runtimerender/Qt3DSRenderPathMath.h | 713 +++++ .../runtimerender/Qt3DSRenderPathRenderContext.h | 94 + .../Qt3DSRenderPixelGraphicsRenderer.cpp | 311 ++ .../Qt3DSRenderPixelGraphicsRenderer.h | 54 + .../Qt3DSRenderPixelGraphicsTypes.cpp | 66 + .../runtimerender/Qt3DSRenderPixelGraphicsTypes.h | 103 + .../Source/runtimerender/Qt3DSRenderPlugin.cpp | 936 ++++++ .../Source/runtimerender/Qt3DSRenderPlugin.h | 148 + .../runtimerender/Qt3DSRenderPluginCInterface.h | 330 +++ .../runtimerender/Qt3DSRenderPluginGraphObject.h | 60 + .../runtimerender/Qt3DSRenderPluginPropertyValue.h | 182 ++ .../Source/runtimerender/Qt3DSRenderProfiler.h | 112 + .../Source/runtimerender/Qt3DSRenderRay.cpp | 164 ++ src/Runtime/Source/runtimerender/Qt3DSRenderRay.h | 101 + .../Source/runtimerender/Qt3DSRenderRenderList.cpp | 110 + .../Source/runtimerender/Qt3DSRenderRenderList.h | 121 + .../runtimerender/Qt3DSRenderRotationHelper.h | 193 ++ .../runtimerender/Qt3DSRenderShaderCache.cpp | 768 +++++ .../Source/runtimerender/Qt3DSRenderShaderCache.h | 160 ++ .../Qt3DSRenderShaderCodeGenerator.cpp | 526 ++++ .../runtimerender/Qt3DSRenderShaderCodeGenerator.h | 175 ++ .../Qt3DSRenderShaderCodeGeneratorV2.cpp | 632 +++++ .../Qt3DSRenderShaderCodeGeneratorV2.h | 132 + .../Source/runtimerender/Qt3DSRenderShaderKeys.h | 802 ++++++ .../Source/runtimerender/Qt3DSRenderShadowMap.cpp | 219 ++ .../Source/runtimerender/Qt3DSRenderShadowMap.h | 183 ++ .../Source/runtimerender/Qt3DSRenderString.h | 70 + .../Qt3DSRenderSubPresentationHelper.h | 69 + .../runtimerender/Qt3DSRenderSubpresentation.cpp | 127 + .../runtimerender/Qt3DSRenderSubpresentation.h | 110 + .../runtimerender/Qt3DSRenderTaggedPointer.h | 85 + .../runtimerender/Qt3DSRenderTessModeValues.h | 74 + .../runtimerender/Qt3DSRenderTextTextureAtlas.cpp | 126 + .../runtimerender/Qt3DSRenderTextTextureAtlas.h | 63 + .../runtimerender/Qt3DSRenderTextTextureCache.cpp | 295 ++ .../runtimerender/Qt3DSRenderTextTextureCache.h | 74 + .../Source/runtimerender/Qt3DSRenderTextTypes.h | 196 ++ .../runtimerender/Qt3DSRenderTextureAtlas.cpp | 364 +++ .../Source/runtimerender/Qt3DSRenderTextureAtlas.h | 102 + .../Source/runtimerender/Qt3DSRenderThreadPool.cpp | 327 +++ .../Source/runtimerender/Qt3DSRenderThreadPool.h | 80 + .../Source/runtimerender/Qt3DSRenderUIPLoader.cpp | 2065 ++++++++++++++ .../Source/runtimerender/Qt3DSRenderUIPLoader.h | 133 + .../Qt3DSRenderUIPSharedTranslation.cpp | 464 +++ .../Qt3DSRenderUIPSharedTranslation.h | 488 ++++ .../Source/runtimerender/Qt3DSRenderWidgets.cpp | 319 +++ .../Source/runtimerender/Qt3DSRenderWidgets.h | 181 ++ .../Source/runtimerender/Qt3DSRenderableImage.h | 77 + src/Runtime/Source/runtimerender/Qt3DSRenderer.h | 249 ++ .../Source/runtimerender/Qt3DSRendererUtil.cpp | 119 + .../Source/runtimerender/Qt3DSRendererUtil.h | 62 + .../Source/runtimerender/Qt3DSTextRenderer.cpp | 87 + .../Source/runtimerender/Qt3DSTextRenderer.h | 146 + .../runtimerender/android/DynamicLibLoader.h | 30 + .../graphobjects/Qt3DSRenderCamera.cpp | 486 ++++ .../runtimerender/graphobjects/Qt3DSRenderCamera.h | 177 ++ .../graphobjects/Qt3DSRenderCustomMaterial.h | 147 + .../graphobjects/Qt3DSRenderDefaultMaterial.cpp | 74 + .../graphobjects/Qt3DSRenderDefaultMaterial.h | 148 + .../graphobjects/Qt3DSRenderDynamicObject.cpp | 158 ++ .../graphobjects/Qt3DSRenderDynamicObject.h | 112 + .../graphobjects/Qt3DSRenderEffect.cpp | 61 + .../runtimerender/graphobjects/Qt3DSRenderEffect.h | 86 + .../graphobjects/Qt3DSRenderGraphObject.h | 77 + .../graphobjects/Qt3DSRenderImage.cpp | 135 + .../runtimerender/graphobjects/Qt3DSRenderImage.h | 113 + .../graphobjects/Qt3DSRenderLayer.cpp | 105 + .../runtimerender/graphobjects/Qt3DSRenderLayer.h | 203 ++ .../graphobjects/Qt3DSRenderLight.cpp | 55 + .../runtimerender/graphobjects/Qt3DSRenderLight.h | 90 + .../graphobjects/Qt3DSRenderLightmaps.cpp | 41 + .../graphobjects/Qt3DSRenderLightmaps.h | 77 + .../graphobjects/Qt3DSRenderMaterialDirty.h | 61 + .../graphobjects/Qt3DSRenderModel.cpp | 75 + .../runtimerender/graphobjects/Qt3DSRenderModel.h | 76 + .../runtimerender/graphobjects/Qt3DSRenderNode.cpp | 499 ++++ .../runtimerender/graphobjects/Qt3DSRenderNode.h | 307 ++ .../runtimerender/graphobjects/Qt3DSRenderPath.cpp | 59 + .../runtimerender/graphobjects/Qt3DSRenderPath.h | 156 + .../graphobjects/Qt3DSRenderPathSubPath.h | 65 + .../graphobjects/Qt3DSRenderPresentation.cpp | 43 + .../graphobjects/Qt3DSRenderPresentation.h | 94 + .../graphobjects/Qt3DSRenderReferencedMaterial.h | 63 + .../graphobjects/Qt3DSRenderScene.cpp | 121 + .../runtimerender/graphobjects/Qt3DSRenderScene.h | 84 + .../runtimerender/graphobjects/Qt3DSRenderText.cpp | 76 + .../runtimerender/graphobjects/Qt3DSRenderText.h | 76 + .../Source/runtimerender/linux/DynamicLibLoader.h | 92 + .../Source/runtimerender/macos/DynamicLibLoader.h | 30 + src/Runtime/Source/runtimerender/q3dsqmlrender.cpp | 144 + src/Runtime/Source/runtimerender/q3dsqmlrender.h | 101 + .../Source/runtimerender/qnx/DynamicLibLoader.h | 30 + .../rendererimpl/Qt3DSRenderableObjects.cpp | 530 ++++ .../rendererimpl/Qt3DSRenderableObjects.h | 431 +++ .../rendererimpl/Qt3DSRendererImpl.cpp | 2014 +++++++++++++ .../runtimerender/rendererimpl/Qt3DSRendererImpl.h | 552 ++++ .../Qt3DSRendererImplLayerRenderData.cpp | 2203 ++++++++++++++ .../Qt3DSRendererImplLayerRenderData.h | 182 ++ .../Qt3DSRendererImplLayerRenderHelper.cpp | 259 ++ .../Qt3DSRendererImplLayerRenderHelper.h | 115 + ...Qt3DSRendererImplLayerRenderPreparationData.cpp | 1446 ++++++++++ .../Qt3DSRendererImplLayerRenderPreparationData.h | 367 +++ .../rendererimpl/Qt3DSRendererImplShaders.cpp | 2999 ++++++++++++++++++++ .../rendererimpl/Qt3DSRendererImplShaders.h | 452 +++ .../rendererimpl/Qt3DSVertexPipelineImpl.h | 435 +++ .../resourcemanager/Qt3DSRenderBufferLoader.cpp | 326 +++ .../resourcemanager/Qt3DSRenderBufferLoader.h | 85 + .../resourcemanager/Qt3DSRenderBufferManager.cpp | 920 ++++++ .../resourcemanager/Qt3DSRenderBufferManager.h | 104 + .../Qt3DSRenderImageBatchLoader.cpp | 536 ++++ .../resourcemanager/Qt3DSRenderImageBatchLoader.h | 96 + .../resourcemanager/Qt3DSRenderLoadedTexture.cpp | 704 +++++ .../resourcemanager/Qt3DSRenderLoadedTexture.h | 184 ++ .../Qt3DSRenderLoadedTextureBMP.cpp | 1262 ++++++++ .../Qt3DSRenderLoadedTextureDDS.cpp | 695 +++++ .../resourcemanager/Qt3DSRenderLoadedTextureDDS.h | 88 + .../Qt3DSRenderLoadedTextureFreeImageCompat.h | 413 +++ .../Qt3DSRenderLoadedTextureGIF.cpp | 851 ++++++ .../Qt3DSRenderLoadedTextureHDR.cpp | 255 ++ .../Qt3DSRenderLoadedTextureKTX.cpp | 277 ++ .../resourcemanager/Qt3DSRenderLoadedTextureKTX.h | 39 + .../Qt3DSRenderPrefilterTexture.cpp | 599 ++++ .../resourcemanager/Qt3DSRenderPrefilterTexture.h | 129 + .../Qt3DSRenderResourceBufferObjects.cpp | 101 + .../Qt3DSRenderResourceBufferObjects.h | 96 + .../resourcemanager/Qt3DSRenderResourceManager.cpp | 436 +++ .../resourcemanager/Qt3DSRenderResourceManager.h | 81 + .../Qt3DSRenderResourceTexture2D.cpp | 174 ++ .../resourcemanager/Qt3DSRenderResourceTexture2D.h | 126 + .../runtimerender/windows/DynamicLibLoader.h | 80 + src/Runtime/Source/state/Qt3DSStateApplication.h | 48 + src/Runtime/Source/state/Qt3DSStateConfig.h | 43 + src/Runtime/Source/state/Qt3DSStateEngine.h | 103 + .../Source/state/Qt3DSStateInputStreamFactory.cpp | 231 ++ .../Source/state/Qt3DSStateInputStreamFactory.h | 71 + src/Runtime/Source/stateapplication/Qt3DSState.h | 108 + .../stateapplication/Qt3DSStateApplication.cpp | 63 + .../stateapplication/Qt3DSStateApplication.h | 46 + .../Source/stateapplication/Qt3DSStateContext.cpp | 202 ++ .../Source/stateapplication/Qt3DSStateContext.h | 95 + .../Qt3DSStateExecutionContext.cpp | 332 +++ .../stateapplication/Qt3DSStateExecutionContext.h | 73 + .../stateapplication/Qt3DSStateExecutionTypes.h | 392 +++ .../Source/stateapplication/Qt3DSStateIdValue.h | 173 ++ .../stateapplication/Qt3DSStateInterpreter.cpp | 2057 ++++++++++++++ .../stateapplication/Qt3DSStateInterpreter.h | 121 + .../stateapplication/Qt3DSStateScriptContext.h | 128 + .../Source/stateapplication/Qt3DSStateSharedImpl.h | 117 + .../stateapplication/Qt3DSStateSignalConnection.h | 49 + .../Source/stateapplication/Qt3DSStateTypes.h | 720 +++++ .../Qt3DSStateVisualBindingContext.cpp | 626 ++++ .../Qt3DSStateVisualBindingContext.h | 116 + .../Qt3DSStateVisualBindingContextCommands.h | 348 +++ .../Qt3DSStateVisualBindingContextValues.h | 253 ++ .../Source/stateapplication/Qt3DSStateXMLIO.cpp | 1948 +++++++++++++ .../Source/stateapplication/Qt3DSStateXMLIO.h | 112 + .../debugger/Qt3DSSceneGraphDebugger.h | 111 + .../debugger/Qt3DSSceneGraphDebuggerProtocol.h | 375 +++ .../debugger/Qt3DSSceneGraphDebuggerValue.h | 190 ++ .../debugger/Qt3DSSceneGraphRuntimeDebugger.cpp | 345 +++ .../debugger/Qt3DSStateDataTest.cpp | 81 + .../debugger/Qt3DSStateDebugStreams.cpp | 534 ++++ .../debugger/Qt3DSStateDebugStreams.h | 102 + .../debugger/Qt3DSStateDebuggedInterpreter.cpp | 302 ++ .../debugger/Qt3DSStateDebugger.cpp | 312 ++ .../stateapplication/debugger/Qt3DSStateDebugger.h | 386 +++ .../debugger/Qt3DSStateDebuggerListener.cpp | 322 +++ .../debugger/Qt3DSStateDebuggerProtocol.h | 925 ++++++ .../debugger/Qt3DSStateDebuggerValues.h | 540 ++++ .../stateapplication/debugger/Qt3DSStateTest.h | 88 + .../editor/Qt3DSSceneGraphArchitectDebugger.cpp | 574 ++++ .../editor/Qt3DSStateDebuggerMaster.cpp | 222 ++ .../stateapplication/editor/Qt3DSStateEditor.cpp | 1880 ++++++++++++ .../stateapplication/editor/Qt3DSStateEditor.h | 315 ++ .../editor/Qt3DSStateEditorEditorsImpl.h | 1772 ++++++++++++ .../editor/Qt3DSStateEditorFoundation.h | 81 + .../stateapplication/editor/Qt3DSStateEditorImpl.h | 406 +++ .../editor/Qt3DSStateEditorProperties.h | 599 ++++ .../editor/Qt3DSStateEditorTransactionImpl.cpp | 239 ++ .../editor/Qt3DSStateEditorTransactionImpl.h | 195 ++ .../editor/Qt3DSStateEditorTransitionPath.cpp | 813 ++++++ .../editor/Qt3DSStateEditorTransitionPath.h | 467 +++ .../editor/Qt3DSStateEditorValue.h | 271 ++ .../stateapplication/editor/Qt3DSUIADatamodel.cpp | 2527 +++++++++++++++++ .../stateapplication/editor/Qt3DSUIADatamodel.h | 174 ++ .../editor/Qt3DSUIADatamodelValue.h | 291 ++ src/Runtime/Source/system/Qt3DSArray.h | 135 + src/Runtime/Source/system/Qt3DSArray.inl | 287 ++ src/Runtime/Source/system/Qt3DSAssert.cpp | 93 + src/Runtime/Source/system/Qt3DSAssert.h | 78 + src/Runtime/Source/system/Qt3DSAudioPlayer.h | 42 + src/Runtime/Source/system/Qt3DSBasicPluginDLL.h | 67 + src/Runtime/Source/system/Qt3DSBezierEval.h | 182 ++ src/Runtime/Source/system/Qt3DSBoundingBox.cpp | 150 + src/Runtime/Source/system/Qt3DSBoundingBox.h | 85 + src/Runtime/Source/system/Qt3DSCircularArray.h | 102 + src/Runtime/Source/system/Qt3DSCircularArray.inl | 225 ++ src/Runtime/Source/system/Qt3DSColor.cpp | 95 + src/Runtime/Source/system/Qt3DSColor.h | 85 + src/Runtime/Source/system/Qt3DSConfig.h | 49 + src/Runtime/Source/system/Qt3DSCubicRoots.cpp | 38 + src/Runtime/Source/system/Qt3DSCubicRoots.h | 78 + src/Runtime/Source/system/Qt3DSCubicRootsImpl.h | 177 ++ src/Runtime/Source/system/Qt3DSDLLManager.cpp | 220 ++ src/Runtime/Source/system/Qt3DSDLLManager.h | 96 + src/Runtime/Source/system/Qt3DSDataLogger.cpp | 151 + src/Runtime/Source/system/Qt3DSDataLogger.h | 226 ++ src/Runtime/Source/system/Qt3DSDataLogger.hpp | 96 + src/Runtime/Source/system/Qt3DSDataLoggerEnums.h | 117 + src/Runtime/Source/system/Qt3DSDataLoggerViewer.h | 71 + src/Runtime/Source/system/Qt3DSEGLTimer.h | 70 + src/Runtime/Source/system/Qt3DSEndian.h | 38 + src/Runtime/Source/system/Qt3DSEulerAngles.cpp | 390 +++ src/Runtime/Source/system/Qt3DSEulerAngles.h | 141 + src/Runtime/Source/system/Qt3DSFNDTimer.h | 44 + src/Runtime/Source/system/Qt3DSFile.cpp | 77 + src/Runtime/Source/system/Qt3DSFile.h | 94 + src/Runtime/Source/system/Qt3DSFileStream.cpp | 237 ++ src/Runtime/Source/system/Qt3DSFileStream.h | 93 + src/Runtime/Source/system/Qt3DSFixedArray.h | 87 + src/Runtime/Source/system/Qt3DSFixedArray.inl | 150 + .../Source/system/Qt3DSFunctionWrappers.cpp | 65 + src/Runtime/Source/system/Qt3DSFunctionWrappers.h | 416 +++ src/Runtime/Source/system/Qt3DSHash.h | 105 + src/Runtime/Source/system/Qt3DSIFileStream.h | 56 + src/Runtime/Source/system/Qt3DSIStream.h | 162 ++ src/Runtime/Source/system/Qt3DSITimer.h | 61 + src/Runtime/Source/system/Qt3DSMacros.h | 189 ++ src/Runtime/Source/system/Qt3DSMatrix.cpp | 897 ++++++ src/Runtime/Source/system/Qt3DSMatrix.h | 146 + src/Runtime/Source/system/Qt3DSMemory.cpp | 137 + src/Runtime/Source/system/Qt3DSMemory.h | 183 ++ src/Runtime/Source/system/Qt3DSMemoryFilter.cpp | 126 + src/Runtime/Source/system/Qt3DSMemoryFilter.h | 69 + src/Runtime/Source/system/Qt3DSMemoryHeap.cpp | 236 ++ src/Runtime/Source/system/Qt3DSMemoryHeap.h | 133 + src/Runtime/Source/system/Qt3DSMemoryManager.cpp | 453 +++ src/Runtime/Source/system/Qt3DSMemoryManager.h | 133 + src/Runtime/Source/system/Qt3DSMemoryPool.cpp | 298 ++ src/Runtime/Source/system/Qt3DSMemoryPool.h | 104 + src/Runtime/Source/system/Qt3DSMemoryProbe.cpp | 149 + src/Runtime/Source/system/Qt3DSMemoryProbe.h | 144 + src/Runtime/Source/system/Qt3DSMemorySettings.h | 131 + .../Source/system/Qt3DSMemoryStatistics.cpp | 647 +++++ src/Runtime/Source/system/Qt3DSMemoryStatistics.h | 137 + src/Runtime/Source/system/Qt3DSMemoryTracker.cpp | 164 ++ src/Runtime/Source/system/Qt3DSMemoryTracker.h | 104 + src/Runtime/Source/system/Qt3DSPlatformSpecific.h | 207 ++ src/Runtime/Source/system/Qt3DSTimer.cpp | 116 + src/Runtime/Source/system/Qt3DSTimer.h | 142 + src/Runtime/Source/system/Qt3DSTypes.cpp | 54 + src/Runtime/Source/system/Qt3DSTypes.h | 236 ++ src/Runtime/Source/system/Qt3DSVector3.cpp | 466 +++ src/Runtime/Source/system/Qt3DSVector3.h | 117 + src/Runtime/Source/system/SystemPrefix.h | 92 + src/Runtime/Source/uipparser/Qt3DSIPresentation.h | 176 ++ src/Runtime/Source/uipparser/Qt3DSUIPParser.h | 153 + .../uipparser/Qt3DSUIPParserActionHelper.cpp | 738 +++++ .../Source/uipparser/Qt3DSUIPParserActionHelper.h | 172 ++ .../Source/uipparser/Qt3DSUIPParserImpl.cpp | 2587 +++++++++++++++++ src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.h | 664 +++++ .../uipparser/Qt3DSUIPParserObjectRefHelper.cpp | 1005 +++++++ .../uipparser/Qt3DSUIPParserObjectRefHelper.h | 159 ++ src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.cpp | 60 + src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.h | 48 + src/Runtime/Source/viewer/Qt3DSViewerApp.cpp | 766 +++++ src/Runtime/Source/viewer/Qt3DSViewerApp.h | 390 +++ src/Runtime/Source/viewer/Qt3DSViewerTimer.h | 120 + .../viewer/perflog/SimpleTCPClientSocket.cpp | 241 ++ .../Source/viewer/perflog/SimpleTCPClientSocket.h | 77 + .../viewer/perflog/SimpleTCPServerSocket.cpp | 255 ++ .../Source/viewer/perflog/SimpleTCPServerSocket.h | 84 + .../Source/viewer/perflog/TCPPerfLogClient.cpp | 476 ++++ .../Source/viewer/perflog/TCPPerfLogClient.h | 376 +++ .../Source/viewer/perflog/TCPPerfLogClientStub.h | 58 + .../Source/viewer/perflog/TCPPerfLogCommon.h | 98 + .../Source/viewer/perflog/TCPPerfLogServer.cpp | 157 + .../Source/viewer/perflog/TCPPerfLogServer.h | 58 + src/Runtime/Source/viewer/qt3dsruntimeglobal.h | 45 + src/Runtime/commoninclude.pri | 58 +- src/commonplatform.pri | 10 +- 1441 files changed, 199218 insertions(+), 199227 deletions(-) delete mode 100644 src/Runtime/Source/DataModel/Include/DocumentResourceManagerCustomMaterialParser.h delete mode 100644 src/Runtime/Source/DataModel/Include/DocumentResourceManagerRenderPluginParser.h delete mode 100644 src/Runtime/Source/DataModel/Include/DocumentResourceManagerScriptParser.h delete mode 100644 src/Runtime/Source/DataModel/Include/Qt3DSMetadata.h delete mode 100644 src/Runtime/Source/DataModel/Source/Qt3DSMetadata.cpp delete mode 100644 src/Runtime/Source/Engine/Include/EnginePrefix.h delete mode 100644 src/Runtime/Source/Engine/Include/NVImageScaler.h delete mode 100644 src/Runtime/Source/Engine/Include/OpenKodeInclude.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSEGLInfo.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSEGLWindowSystem.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSPluginDLL.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBinding.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBindingImpl.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSTegraInputEngine.h delete mode 100644 src/Runtime/Source/Engine/Include/Qt3DSWindowSystem.h delete mode 100644 src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp delete mode 100644 src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplRenderer.cpp delete mode 100644 src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplTranslation.cpp delete mode 100644 src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp delete mode 100644 src/Runtime/Source/Engine/Source/Qt3DSTegraInputEngine.cpp delete mode 100644 src/Runtime/Source/HDR/Include/CUDABSDFMipmap.h delete mode 100644 src/Runtime/Source/HDR/Include/GLComputeMipMap.h delete mode 100644 src/Runtime/Source/HDR/Include/HDR.h delete mode 100644 src/Runtime/Source/HDR/Include/MipmapBSDF.h delete mode 100644 src/Runtime/Source/HDR/Source/CUDABSDFMipmap.cpp delete mode 100644 src/Runtime/Source/HDR/Source/GLComputeMipmap.cpp delete mode 100644 src/Runtime/Source/HDR/Source/HDR.cpp delete mode 100644 src/Runtime/Source/HDR/Source/MipmapBSDF.cpp delete mode 100644 src/Runtime/Source/HDR/Source/MipmapBSDF.cu delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/NvVec.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/misc.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_color.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_debug.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_global.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/NvVec.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/misc.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_types.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.abc delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.dds delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.abc delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.dds delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/assets/font.frag delete mode 100644 src/Runtime/Source/PlatformSpecific/Linux/assets/font.vert delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_color.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_debug.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_global.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/NvVec.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/misc.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_types.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.abc delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.dds delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.abc delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.dds delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/assets/font.frag delete mode 100644 src/Runtime/Source/PlatformSpecific/Macos/assets/font.vert delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_color.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_config/nv_config.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_debug.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_global.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/NvVec.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/misc.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.cpp delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_types.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/qt3ds_launcher_defs.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/Qt3DSViewer/Resource.h delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.abc delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.dds delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.abc delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.dds delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/assets/font.frag delete mode 100644 src/Runtime/Source/PlatformSpecific/Windows/assets/font.vert delete mode 100644 src/Runtime/Source/Qt3DSEvent/Include/EventSystem.h delete mode 100644 src/Runtime/Source/Qt3DSEvent/Include/EventSystemC.h delete mode 100644 src/Runtime/Source/Qt3DSEvent/InternalInclude/EventPollingSystem.h delete mode 100644 src/Runtime/Source/Qt3DSEvent/Source/EventFactory.cpp delete mode 100644 src/Runtime/Source/Qt3DSEvent/Source/EventFactory.h delete mode 100644 src/Runtime/Source/Qt3DSEvent/Source/EventPoller.cpp delete mode 100644 src/Runtime/Source/Qt3DSEvent/Source/EventPoller.h delete mode 100644 src/Runtime/Source/Qt3DSEvent/Source/EventSystemC.cpp delete mode 100644 src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.cpp delete mode 100644 src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/AutoDeallocatorAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/ConvertUTF.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/FastAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/FileTools.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/IOStreams.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/LICENSE_CONVERTUTF.TXT delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/PoolingAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/PreAllocatedAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DS.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocatorCallback.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAssert.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAtomic.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBasicTemplates.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBounds3.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBroadcastingAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSContainers.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDataRef.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDiscriminatedUnion.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFPU.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFastIPC.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFlags.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFoundation.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIPC.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIndexableLinkedList.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIntrinsics.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveLinkedList.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveSet.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSLogging.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat33.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat44.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMath.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMathUtils.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMemoryBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMutex.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSNoCopy.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSOption.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPerfTimer.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPlane.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPool.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPreprocessor.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSQuat.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSRefCounted.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSemaphore.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSimpleTypes.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSStringTokenizer.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSync.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSystem.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSThread.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTime.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTransform.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUnionCast.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUtilities.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec2.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec3.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec4.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVersionNumber.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/SerializationTypes.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Socket.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/StrConvertUTF.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversion.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversionImpl.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringTable.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/TaggedPointer.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/ThreadSafeQueue.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/TrackingAllocator.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/Utils.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/XML.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/LICENSE.TXT delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxAoS.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxFile.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxInlineAoS.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxIntrinsics.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxString.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxTrigConstants.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/qt_attribution.json delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/qt_attribution.json delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/LICENSE.TXT delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsAoS.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsFile.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInclude.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInlineAoS.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsIntrinsics.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsString.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsTrigConstants.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/qt_attribution.json delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/ConvertUTF.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/EASTL_new.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/FileTools.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/IOStreams.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/LICENCE_SOCKET.TXT delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSFoundation.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSLogging.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSMathUtils.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSPerfTimer.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSSystem.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/Socket.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/StringTable.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/TrackingAllocator.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/XML.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxAtomic.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxFPU.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxMutex.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSync.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxThread.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxTime.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/SocketImpl.h delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixAtomic.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixFPU.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixMutex.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSemaphore.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSync.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixTime.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/qt_attribution.json delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsAtomic.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsFPU.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsMutex.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSync.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsThread.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsTime.cpp delete mode 100644 src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/SocketImpl.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderClearColorExample.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderRenderToTextureExample.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderSpinningCubeExample.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAtomicCounterBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAttribLayout.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderComputeShader.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderConstantBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDataBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDepthStencilState.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawIndirectBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawable.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFragmentShader.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFrameBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderGeometryShader.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderImageTexture.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderIndexBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderInputAssembler.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderOcclusionQuery.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontSpecification.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontText.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathRender.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathSpecification.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderProgramPipeline.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderQueryBase.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRasterizerState.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRenderBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSampler.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShader.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderStorageBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSync.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTessellationShader.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2D.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2DArray.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureBase.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureCube.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTimerQuery.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexBuffer.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexShader.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLTokens.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL4.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Include/render/glg/Qt3DSGLImplObjects.h delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAtomicCounterBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAttribLayout.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderComputeShader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderContext.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDataBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDepthStencilState.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDrawIndirectBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFragmentShader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFrameBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderGeometryShader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderImageTexture.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderIndexBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderInputAssembler.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderOcclusionQuery.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontSpecification.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontText.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathRender.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathSpecification.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderProgramPipeline.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderQueryBase.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRasterizerState.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRenderBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSampler.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderStorageBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSync.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTessellationShader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2D.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2DArray.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureBase.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureCube.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTimerQuery.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexBuffer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexShader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp delete mode 100644 src/Runtime/Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCustomMaterial.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderGraphObject.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderMaterialDirty.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPathSubPath.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderReferencedMaterial.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/ANDROID/DynamicLibLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/LINUX/DynamicLibLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/OSX/DynamicLibLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/QNX/DynamicLibLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderKey.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRender.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderClippingFrustum.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderContextCore.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialRenderContext.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialShaderGenerator.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialSystem.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDefaultMaterialShaderGenerator.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystem.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemCommands.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemUtil.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEffectSystem.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEulerAngles.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectPickQuery.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectSerializer.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectTypes.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageScaler.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageTextureData.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderInputStreamFactory.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialHelpers.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialShaderGenerator.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMesh.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathManager.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathMath.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathRenderContext.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsRenderer.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsTypes.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPlugin.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginCInterface.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginGraphObject.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginPropertyValue.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderProfiler.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRay.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRenderList.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRotationHelper.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCache.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGenerator.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGeneratorV2.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderKeys.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShadowMap.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderString.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubPresentationHelper.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTaggedPointer.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTessModeValues.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureAtlas.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureCache.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTypes.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextureAtlas.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderThreadPool.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPSharedTranslation.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderWidgets.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderableImage.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderer.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRendererUtil.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSTextRenderer.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/WINDOWS/DynamicLibLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSVertexPipelineImpl.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureBMP.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureFreeImageCompat.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureGIF.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureHDR.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.h delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOffscreenRenderManager.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOldNBustedRenderPlugin.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOnscreenTextRenderer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSQtTextRenderer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderClippingFrustum.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialSystem.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDefaultMaterialShaderGenerator.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDynamicObjectSystem.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEffectSystem.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEulerAngles.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGpuProfiler.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGraphObjectSerializer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderImageScaler.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderInputStreamFactory.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPathManager.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsRenderer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsTypes.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRay.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRenderList.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCache.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGenerator.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGeneratorV2.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShadowMap.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderSubpresentation.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureAtlas.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureCache.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextureAtlas.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderThreadPool.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPSharedTranslation.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderWidgets.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRendererUtil.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSTextRenderer.cpp delete mode 100644 src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp delete mode 100644 src/Runtime/Source/Qt3DSState/Include/Qt3DSStateConfig.h delete mode 100644 src/Runtime/Source/Qt3DSState/Include/Qt3DSStateEngine.h delete mode 100644 src/Runtime/Source/Qt3DSState/Include/Qt3DSStateInputStreamFactory.h delete mode 100644 src/Runtime/Source/Qt3DSState/InternalInclude/Qt3DSStateApplication.h delete mode 100644 src/Runtime/Source/Qt3DSState/Source/Qt3DSStateInputStreamFactory.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebugger.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerProtocol.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerValue.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphRuntimeDebugger.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDataTest.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggedInterpreter.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerListener.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerProtocol.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerValues.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateTest.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSSceneGraphArchitectDebugger.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateDebuggerMaster.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorEditorsImpl.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorFoundation.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorImpl.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorProperties.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorValue.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodelValue.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSState.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateContext.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionContext.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionTypes.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateIdValue.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateInterpreter.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateScriptContext.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSharedImpl.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSignalConnection.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateTypes.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContext.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextCommands.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextValues.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateXMLIO.h delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateContext.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateExecutionContext.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateInterpreter.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateVisualBindingContext.cpp delete mode 100644 src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateXMLIO.cpp delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSActivationManager.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSAnimationSystem.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSApplication.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSApplicationValues.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.txt delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSCommandEventTypes.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSCommandHelper.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSComponentManager.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSElementHelper.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSElementSystem.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSEvent.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSEventCallbacks.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSFrameworkTypes.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSIComponentManager.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSIInputSystem.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSIScene.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSIScriptBridge.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSIStateful.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSIText.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSInputDefs.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSInputEngine.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSInputEventTypes.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSInputFrame.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSKernelTypes.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSLogicSystem.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSOutputMemoryStream.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSParametersSystem.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSPickFrame.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSPresentation.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSPresentationFrameData.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSQmlElementHelper.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSQmlEngine.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSRuntimeFactory.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSSlideSystem.h delete mode 100644 src/Runtime/Source/Runtime/Include/Qt3DSTimePolicy.h delete mode 100644 src/Runtime/Source/Runtime/Include/RuntimePrefix.h delete mode 100644 src/Runtime/Source/Runtime/Include/q3dsqmlbehavior.h delete mode 100644 src/Runtime/Source/Runtime/Include/q3dsqmlscript.h delete mode 100644 src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSActivationManager.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSAnimationSystem.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSAttributeHashes.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSCommandHelper.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSComponentManager.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSElementHelper.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSElementSystem.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSEventCallbacks.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSInputEngine.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSLogicSystem.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSOutputMemoryStream.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSParametersSystem.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSPresentation.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSPresentationFrameData.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSQmlElementHelper.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSQmlEngine.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSSlideSystem.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/Qt3DSTimePolicy.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/q3dsqmlbehavior.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/q3dsqmlscript.cpp delete mode 100644 src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp delete mode 100644 src/Runtime/Source/System/Include/Qt3DSArray.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSArray.inl delete mode 100644 src/Runtime/Source/System/Include/Qt3DSAssert.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSAudioPlayer.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSBasicPluginDLL.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSBezierEval.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSBoundingBox.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSCircularArray.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSCircularArray.inl delete mode 100644 src/Runtime/Source/System/Include/Qt3DSColor.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSConfig.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSCubicRoots.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSCubicRootsImpl.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSDLLManager.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSDataLogger.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSDataLogger.hpp delete mode 100644 src/Runtime/Source/System/Include/Qt3DSDataLoggerEnums.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSDataLoggerViewer.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSEGLTimer.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSEndian.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSEulerAngles.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSFNDTimer.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSFile.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSFileStream.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSFixedArray.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSFixedArray.inl delete mode 100644 src/Runtime/Source/System/Include/Qt3DSFunctionWrappers.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSHash.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSIFileStream.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSIStream.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSITimer.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMacros.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMatrix.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemory.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryFilter.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryHeap.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryManager.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryPool.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryProbe.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemorySettings.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryStatistics.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSMemoryTracker.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSPlatformSpecific.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSTimer.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSTypes.h delete mode 100644 src/Runtime/Source/System/Include/Qt3DSVector3.h delete mode 100644 src/Runtime/Source/System/Include/SystemPrefix.h delete mode 100644 src/Runtime/Source/System/Source/Qt3DSAssert.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSBoundingBox.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSColor.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSCubicRoots.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSDLLManager.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSDataLogger.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSEulerAngles.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSFile.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSFileStream.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSFunctionWrappers.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMatrix.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemory.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryFilter.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryHeap.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryManager.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryPool.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryProbe.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryStatistics.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSMemoryTracker.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSTimer.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSTypes.cpp delete mode 100644 src/Runtime/Source/System/Source/Qt3DSVector3.cpp delete mode 100644 src/Runtime/Source/UIPParser/Include/Qt3DSIPresentation.h delete mode 100644 src/Runtime/Source/UIPParser/Include/Qt3DSUIPParser.h delete mode 100644 src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserActionHelper.h delete mode 100644 src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserImpl.h delete mode 100644 src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserObjectRefHelper.h delete mode 100644 src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserActionHelper.cpp delete mode 100644 src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp delete mode 100644 src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserObjectRefHelper.cpp delete mode 100644 src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.cpp delete mode 100644 src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.h delete mode 100644 src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.cpp delete mode 100644 src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.h delete mode 100644 src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.cpp delete mode 100644 src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.h delete mode 100644 src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClientStub.h delete mode 100644 src/Runtime/Source/Viewer/PerfLog/TCPPerfLogCommon.h delete mode 100644 src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.cpp delete mode 100644 src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.h delete mode 100644 src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.cpp delete mode 100644 src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.h delete mode 100644 src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp delete mode 100644 src/Runtime/Source/Viewer/Qt3DSViewerApp.h delete mode 100644 src/Runtime/Source/Viewer/Qt3DSViewerTimer.h delete mode 100644 src/Runtime/Source/Viewer/qt3dsruntimeglobal.h create mode 100644 src/Runtime/Source/datamodel/DocumentResourceManagerCustomMaterialParser.h create mode 100644 src/Runtime/Source/datamodel/DocumentResourceManagerRenderPluginParser.h create mode 100644 src/Runtime/Source/datamodel/DocumentResourceManagerScriptParser.h create mode 100644 src/Runtime/Source/datamodel/Qt3DSMetadata.cpp create mode 100644 src/Runtime/Source/datamodel/Qt3DSMetadata.h create mode 100644 src/Runtime/Source/engine/EnginePrefix.h create mode 100644 src/Runtime/Source/engine/NVImageScaler.h create mode 100644 src/Runtime/Source/engine/OpenKodeInclude.h create mode 100644 src/Runtime/Source/engine/Qt3DSEGLInfo.h create mode 100644 src/Runtime/Source/engine/Qt3DSEGLWindowSystem.h create mode 100644 src/Runtime/Source/engine/Qt3DSPluginDLL.h create mode 100644 src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp create mode 100644 src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.h create mode 100644 src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h create mode 100644 src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp create mode 100644 src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp create mode 100644 src/Runtime/Source/engine/Qt3DSTegraApplication.cpp create mode 100644 src/Runtime/Source/engine/Qt3DSTegraApplication.h create mode 100644 src/Runtime/Source/engine/Qt3DSTegraInputEngine.cpp create mode 100644 src/Runtime/Source/engine/Qt3DSTegraInputEngine.h create mode 100644 src/Runtime/Source/engine/Qt3DSWindowSystem.h create mode 100644 src/Runtime/Source/event/EventFactory.cpp create mode 100644 src/Runtime/Source/event/EventFactory.h create mode 100644 src/Runtime/Source/event/EventPoller.cpp create mode 100644 src/Runtime/Source/event/EventPoller.h create mode 100644 src/Runtime/Source/event/EventPollingSystem.h create mode 100644 src/Runtime/Source/event/EventSystem.h create mode 100644 src/Runtime/Source/event/EventSystemC.cpp create mode 100644 src/Runtime/Source/event/EventSystemC.h create mode 100644 src/Runtime/Source/event/test/CanProviderDemo.cpp create mode 100644 src/Runtime/Source/event/test/CanProviderDemo.h create mode 100644 src/Runtime/Source/foundation/AutoDeallocatorAllocator.h create mode 100644 src/Runtime/Source/foundation/ConvertUTF.cpp create mode 100644 src/Runtime/Source/foundation/ConvertUTF.h create mode 100644 src/Runtime/Source/foundation/EASTL_new.cpp create mode 100644 src/Runtime/Source/foundation/FastAllocator.h create mode 100644 src/Runtime/Source/foundation/FileTools.cpp create mode 100644 src/Runtime/Source/foundation/FileTools.h create mode 100644 src/Runtime/Source/foundation/IOStreams.cpp create mode 100644 src/Runtime/Source/foundation/IOStreams.h create mode 100644 src/Runtime/Source/foundation/LICENCE_SOCKET.TXT create mode 100644 src/Runtime/Source/foundation/LICENSE_CONVERTUTF.TXT create mode 100644 src/Runtime/Source/foundation/PoolingAllocator.h create mode 100644 src/Runtime/Source/foundation/PreAllocatedAllocator.h create mode 100644 src/Runtime/Source/foundation/Qt3DS.h create mode 100644 src/Runtime/Source/foundation/Qt3DSAllocator.h create mode 100644 src/Runtime/Source/foundation/Qt3DSAllocatorCallback.h create mode 100644 src/Runtime/Source/foundation/Qt3DSAssert.h create mode 100644 src/Runtime/Source/foundation/Qt3DSAtomic.h create mode 100644 src/Runtime/Source/foundation/Qt3DSBasicTemplates.h create mode 100644 src/Runtime/Source/foundation/Qt3DSBounds3.h create mode 100644 src/Runtime/Source/foundation/Qt3DSBroadcastingAllocator.h create mode 100644 src/Runtime/Source/foundation/Qt3DSContainers.h create mode 100644 src/Runtime/Source/foundation/Qt3DSDataRef.h create mode 100644 src/Runtime/Source/foundation/Qt3DSDiscriminatedUnion.h create mode 100644 src/Runtime/Source/foundation/Qt3DSFPU.h create mode 100644 src/Runtime/Source/foundation/Qt3DSFastIPC.h create mode 100644 src/Runtime/Source/foundation/Qt3DSFlags.h create mode 100644 src/Runtime/Source/foundation/Qt3DSFoundation.cpp create mode 100644 src/Runtime/Source/foundation/Qt3DSFoundation.h create mode 100644 src/Runtime/Source/foundation/Qt3DSIPC.h create mode 100644 src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h create mode 100644 src/Runtime/Source/foundation/Qt3DSIntrinsics.h create mode 100644 src/Runtime/Source/foundation/Qt3DSInvasiveLinkedList.h create mode 100644 src/Runtime/Source/foundation/Qt3DSInvasiveSet.h create mode 100644 src/Runtime/Source/foundation/Qt3DSLogging.cpp create mode 100644 src/Runtime/Source/foundation/Qt3DSLogging.h create mode 100644 src/Runtime/Source/foundation/Qt3DSMat33.h create mode 100644 src/Runtime/Source/foundation/Qt3DSMat44.h create mode 100644 src/Runtime/Source/foundation/Qt3DSMath.h create mode 100644 src/Runtime/Source/foundation/Qt3DSMathUtils.cpp create mode 100644 src/Runtime/Source/foundation/Qt3DSMathUtils.h create mode 100644 src/Runtime/Source/foundation/Qt3DSMemoryBuffer.h create mode 100644 src/Runtime/Source/foundation/Qt3DSMutex.h create mode 100644 src/Runtime/Source/foundation/Qt3DSNoCopy.h create mode 100644 src/Runtime/Source/foundation/Qt3DSOption.h create mode 100644 src/Runtime/Source/foundation/Qt3DSPerfTimer.cpp create mode 100644 src/Runtime/Source/foundation/Qt3DSPerfTimer.h create mode 100644 src/Runtime/Source/foundation/Qt3DSPlane.h create mode 100644 src/Runtime/Source/foundation/Qt3DSPool.h create mode 100644 src/Runtime/Source/foundation/Qt3DSPreprocessor.h create mode 100644 src/Runtime/Source/foundation/Qt3DSQuat.h create mode 100644 src/Runtime/Source/foundation/Qt3DSRefCounted.h create mode 100644 src/Runtime/Source/foundation/Qt3DSSemaphore.h create mode 100644 src/Runtime/Source/foundation/Qt3DSSimpleTypes.h create mode 100644 src/Runtime/Source/foundation/Qt3DSStringTokenizer.h create mode 100644 src/Runtime/Source/foundation/Qt3DSSync.h create mode 100644 src/Runtime/Source/foundation/Qt3DSSystem.cpp create mode 100644 src/Runtime/Source/foundation/Qt3DSSystem.h create mode 100644 src/Runtime/Source/foundation/Qt3DSThread.h create mode 100644 src/Runtime/Source/foundation/Qt3DSTime.h create mode 100644 src/Runtime/Source/foundation/Qt3DSTransform.h create mode 100644 src/Runtime/Source/foundation/Qt3DSUnionCast.h create mode 100644 src/Runtime/Source/foundation/Qt3DSUtilities.h create mode 100644 src/Runtime/Source/foundation/Qt3DSVec2.h create mode 100644 src/Runtime/Source/foundation/Qt3DSVec3.h create mode 100644 src/Runtime/Source/foundation/Qt3DSVec4.h create mode 100644 src/Runtime/Source/foundation/Qt3DSVersionNumber.h create mode 100644 src/Runtime/Source/foundation/SerializationTypes.h create mode 100644 src/Runtime/Source/foundation/Socket.cpp create mode 100644 src/Runtime/Source/foundation/Socket.h create mode 100644 src/Runtime/Source/foundation/StrConvertUTF.h create mode 100644 src/Runtime/Source/foundation/StringConversion.h create mode 100644 src/Runtime/Source/foundation/StringConversionImpl.h create mode 100644 src/Runtime/Source/foundation/StringTable.cpp create mode 100644 src/Runtime/Source/foundation/StringTable.h create mode 100644 src/Runtime/Source/foundation/TaggedPointer.h create mode 100644 src/Runtime/Source/foundation/ThreadSafeQueue.h create mode 100644 src/Runtime/Source/foundation/TrackingAllocator.cpp create mode 100644 src/Runtime/Source/foundation/TrackingAllocator.h create mode 100644 src/Runtime/Source/foundation/Utils.h create mode 100644 src/Runtime/Source/foundation/XML.cpp create mode 100644 src/Runtime/Source/foundation/XML.h create mode 100644 src/Runtime/Source/foundation/linux/LICENSE.TXT create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxAoS.h create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxAtomic.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxFPU.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxFile.h create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxInlineAoS.h create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxIntrinsics.h create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxMutex.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxString.h create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxSync.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxThread.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxTime.cpp create mode 100644 src/Runtime/Source/foundation/linux/Qt3DSLinuxTrigConstants.h create mode 100644 src/Runtime/Source/foundation/linux/SocketImpl.h create mode 100644 src/Runtime/Source/foundation/linux/qt_attribution.json create mode 100644 src/Runtime/Source/foundation/macos/Qt3DSUnixAtomic.cpp create mode 100644 src/Runtime/Source/foundation/macos/Qt3DSUnixFPU.cpp create mode 100644 src/Runtime/Source/foundation/macos/Qt3DSUnixMutex.cpp create mode 100644 src/Runtime/Source/foundation/macos/Qt3DSUnixSemaphore.cpp create mode 100644 src/Runtime/Source/foundation/macos/Qt3DSUnixSync.cpp create mode 100644 src/Runtime/Source/foundation/macos/Qt3DSUnixTime.cpp create mode 100644 src/Runtime/Source/foundation/qt_attribution.json create mode 100644 src/Runtime/Source/foundation/windows/LICENSE.TXT create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsAoS.h create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsAtomic.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsFPU.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsFile.h create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsInclude.h create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsInlineAoS.h create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsIntrinsics.h create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsMutex.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsString.h create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsSync.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsThread.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsTime.cpp create mode 100644 src/Runtime/Source/foundation/windows/Qt3DSWindowsTrigConstants.h create mode 100644 src/Runtime/Source/foundation/windows/SocketImpl.h create mode 100644 src/Runtime/Source/foundation/windows/qt_attribution.json create mode 100644 src/Runtime/Source/hdr/CUDABSDFMipmap.cpp create mode 100644 src/Runtime/Source/hdr/CUDABSDFMipmap.h create mode 100644 src/Runtime/Source/hdr/GLComputeMipMap.h create mode 100644 src/Runtime/Source/hdr/GLComputeMipmap.cpp create mode 100644 src/Runtime/Source/hdr/HDR.cpp create mode 100644 src/Runtime/Source/hdr/HDR.h create mode 100644 src/Runtime/Source/hdr/MipmapBSDF.cpp create mode 100644 src/Runtime/Source/hdr/MipmapBSDF.cu create mode 100644 src/Runtime/Source/hdr/MipmapBSDF.h create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/NvVec.h create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/misc.h create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.cpp create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.h create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.cpp create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.h create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.cpp create mode 100644 src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.h create mode 100644 src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.abc create mode 100644 src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.dds create mode 100644 src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.abc create mode 100644 src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.dds create mode 100644 src/Runtime/Source/platformspecific/linux/assets/font.frag create mode 100644 src/Runtime/Source/platformspecific/linux/assets/font.vert create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_color.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_debug.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_global.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/NvVec.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/misc.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.cpp create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.cpp create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.cpp create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.h create mode 100644 src/Runtime/Source/platformspecific/linux/libs/nv_types.h create mode 100644 src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.abc create mode 100644 src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.dds create mode 100644 src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.abc create mode 100644 src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.dds create mode 100644 src/Runtime/Source/platformspecific/macos/assets/font.frag create mode 100644 src/Runtime/Source/platformspecific/macos/assets/font.vert create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_color.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_debug.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_global.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/NvVec.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/misc.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.cpp create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.cpp create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.cpp create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.h create mode 100644 src/Runtime/Source/platformspecific/macos/libs/nv_types.h create mode 100644 src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.abc create mode 100644 src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.dds create mode 100644 src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.abc create mode 100644 src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.dds create mode 100644 src/Runtime/Source/platformspecific/windows/assets/font.frag create mode 100644 src/Runtime/Source/platformspecific/windows/assets/font.vert create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_color.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_config/nv_config.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_debug.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_global.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/NvVec.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/misc.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.cpp create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.cpp create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.cpp create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/nv_types.h create mode 100644 src/Runtime/Source/platformspecific/windows/libs/qt3ds_launcher_defs.h create mode 100644 src/Runtime/Source/platformspecific/windows/viewer/Resource.h create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderExample.h create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp create mode 100644 src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderAttribLayout.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderBaseTypes.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderComputeShader.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderContext.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderContext.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderDataBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderDrawable.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderFragmentShader.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderGeometryShader.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderImageTexture.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderInputAssembler.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathFontText.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathRender.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathRender.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderPathSpecification.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderQueryBase.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderRasterizerState.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderSampler.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderSampler.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderShader.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderShaderConstant.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderShaderProgram.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderSync.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderSync.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderTessellationShader.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderTexture2D.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderTextureBase.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderTextureCube.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderTimerQuery.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h create mode 100644 src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp create mode 100644 src/Runtime/Source/render/Qt3DSRenderVertexShader.h create mode 100644 src/Runtime/Source/render/backends/Qt3DSRenderBackend.h create mode 100644 src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp create mode 100644 src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h create mode 100644 src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp create mode 100644 src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp create mode 100644 src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h create mode 100644 src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h create mode 100644 src/Runtime/Source/runtime/Qt3DSActivationManager.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSActivationManager.h create mode 100644 src/Runtime/Source/runtime/Qt3DSAnimationSystem.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSAnimationSystem.h create mode 100644 src/Runtime/Source/runtime/Qt3DSApplication.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSApplication.h create mode 100644 src/Runtime/Source/runtime/Qt3DSApplicationValues.h create mode 100644 src/Runtime/Source/runtime/Qt3DSAttributeHashes.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSAttributeHashes.h create mode 100644 src/Runtime/Source/runtime/Qt3DSAttributeHashes.txt create mode 100644 src/Runtime/Source/runtime/Qt3DSCommandEventTypes.h create mode 100644 src/Runtime/Source/runtime/Qt3DSCommandHelper.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSCommandHelper.h create mode 100644 src/Runtime/Source/runtime/Qt3DSComponentManager.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSComponentManager.h create mode 100644 src/Runtime/Source/runtime/Qt3DSElementHelper.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSElementHelper.h create mode 100644 src/Runtime/Source/runtime/Qt3DSElementSystem.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSElementSystem.h create mode 100644 src/Runtime/Source/runtime/Qt3DSEvent.h create mode 100644 src/Runtime/Source/runtime/Qt3DSEventCallbacks.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSEventCallbacks.h create mode 100644 src/Runtime/Source/runtime/Qt3DSFrameworkTypes.h create mode 100644 src/Runtime/Source/runtime/Qt3DSIComponentManager.h create mode 100644 src/Runtime/Source/runtime/Qt3DSIInputSystem.h create mode 100644 src/Runtime/Source/runtime/Qt3DSIScene.h create mode 100644 src/Runtime/Source/runtime/Qt3DSIScriptBridge.h create mode 100644 src/Runtime/Source/runtime/Qt3DSIStateful.h create mode 100644 src/Runtime/Source/runtime/Qt3DSIText.h create mode 100644 src/Runtime/Source/runtime/Qt3DSInputDefs.h create mode 100644 src/Runtime/Source/runtime/Qt3DSInputEngine.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSInputEngine.h create mode 100644 src/Runtime/Source/runtime/Qt3DSInputEventTypes.h create mode 100644 src/Runtime/Source/runtime/Qt3DSInputFrame.h create mode 100644 src/Runtime/Source/runtime/Qt3DSKernelTypes.h create mode 100644 src/Runtime/Source/runtime/Qt3DSLogicSystem.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSLogicSystem.h create mode 100644 src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.h create mode 100644 src/Runtime/Source/runtime/Qt3DSParametersSystem.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSParametersSystem.h create mode 100644 src/Runtime/Source/runtime/Qt3DSPickFrame.h create mode 100644 src/Runtime/Source/runtime/Qt3DSPresentation.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSPresentation.h create mode 100644 src/Runtime/Source/runtime/Qt3DSPresentationFrameData.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSPresentationFrameData.h create mode 100644 src/Runtime/Source/runtime/Qt3DSQmlElementHelper.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSQmlElementHelper.h create mode 100644 src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSQmlEngine.h create mode 100644 src/Runtime/Source/runtime/Qt3DSRuntimeFactory.h create mode 100644 src/Runtime/Source/runtime/Qt3DSSceneManager.h create mode 100644 src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSSlideSystem.h create mode 100644 src/Runtime/Source/runtime/Qt3DSTimePolicy.cpp create mode 100644 src/Runtime/Source/runtime/Qt3DSTimePolicy.h create mode 100644 src/Runtime/Source/runtime/RuntimePrefix.h create mode 100644 src/Runtime/Source/runtime/q3dsqmlbehavior.cpp create mode 100644 src/Runtime/Source/runtime/q3dsqmlbehavior.h create mode 100644 src/Runtime/Source/runtime/q3dsqmlscript.cpp create mode 100644 src/Runtime/Source/runtime/q3dsqmlscript.h create mode 100644 src/Runtime/Source/runtime/q3dsvariantconfig.cpp create mode 100644 src/Runtime/Source/runtime/q3dsvariantconfig_p.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderKey.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSOnscreenTextRenderer.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSQtTextRenderer.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRender.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialRenderContext.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemCommands.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemUtil.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderGpuProfiler.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectPickQuery.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectTypes.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderLightConstantProperties.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderMaterialHelpers.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderMaterialShaderGenerator.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderMesh.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPathMath.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPathRenderContext.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPluginCInterface.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPluginGraphObject.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderPluginPropertyValue.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderProfiler.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderRay.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderRay.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderRotationHelper.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShaderKeys.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderString.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderSubPresentationHelper.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTaggedPointer.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTessModeValues.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextTypes.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderableImage.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRenderer.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRendererUtil.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSRendererUtil.h create mode 100644 src/Runtime/Source/runtimerender/Qt3DSTextRenderer.cpp create mode 100644 src/Runtime/Source/runtimerender/Qt3DSTextRenderer.h create mode 100644 src/Runtime/Source/runtimerender/android/DynamicLibLoader.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCustomMaterial.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderGraphObject.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderMaterialDirty.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPathSubPath.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderReferencedMaterial.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.h create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.cpp create mode 100644 src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.h create mode 100644 src/Runtime/Source/runtimerender/linux/DynamicLibLoader.h create mode 100644 src/Runtime/Source/runtimerender/macos/DynamicLibLoader.h create mode 100644 src/Runtime/Source/runtimerender/q3dsqmlrender.cpp create mode 100644 src/Runtime/Source/runtimerender/q3dsqmlrender.h create mode 100644 src/Runtime/Source/runtimerender/qnx/DynamicLibLoader.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.cpp create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.cpp create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.h create mode 100644 src/Runtime/Source/runtimerender/rendererimpl/Qt3DSVertexPipelineImpl.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureBMP.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureHDR.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.h create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.cpp create mode 100644 src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.h create mode 100644 src/Runtime/Source/runtimerender/windows/DynamicLibLoader.h create mode 100644 src/Runtime/Source/state/Qt3DSStateApplication.h create mode 100644 src/Runtime/Source/state/Qt3DSStateConfig.h create mode 100644 src/Runtime/Source/state/Qt3DSStateEngine.h create mode 100644 src/Runtime/Source/state/Qt3DSStateInputStreamFactory.cpp create mode 100644 src/Runtime/Source/state/Qt3DSStateInputStreamFactory.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSState.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateApplication.cpp create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateApplication.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateContext.cpp create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateContext.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.cpp create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateExecutionTypes.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateIdValue.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.cpp create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateScriptContext.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateSharedImpl.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateSignalConnection.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateTypes.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.cpp create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextCommands.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextValues.h create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.cpp create mode 100644 src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebugger.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerProtocol.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerValue.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphRuntimeDebugger.cpp create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDataTest.cpp create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.cpp create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggedInterpreter.cpp create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.cpp create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerListener.cpp create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerProtocol.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerValues.h create mode 100644 src/Runtime/Source/stateapplication/debugger/Qt3DSStateTest.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSSceneGraphArchitectDebugger.cpp create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateDebuggerMaster.cpp create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.cpp create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorEditorsImpl.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorFoundation.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorImpl.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorProperties.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.cpp create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.cpp create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorValue.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.cpp create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.h create mode 100644 src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodelValue.h create mode 100644 src/Runtime/Source/system/Qt3DSArray.h create mode 100644 src/Runtime/Source/system/Qt3DSArray.inl create mode 100644 src/Runtime/Source/system/Qt3DSAssert.cpp create mode 100644 src/Runtime/Source/system/Qt3DSAssert.h create mode 100644 src/Runtime/Source/system/Qt3DSAudioPlayer.h create mode 100644 src/Runtime/Source/system/Qt3DSBasicPluginDLL.h create mode 100644 src/Runtime/Source/system/Qt3DSBezierEval.h create mode 100644 src/Runtime/Source/system/Qt3DSBoundingBox.cpp create mode 100644 src/Runtime/Source/system/Qt3DSBoundingBox.h create mode 100644 src/Runtime/Source/system/Qt3DSCircularArray.h create mode 100644 src/Runtime/Source/system/Qt3DSCircularArray.inl create mode 100644 src/Runtime/Source/system/Qt3DSColor.cpp create mode 100644 src/Runtime/Source/system/Qt3DSColor.h create mode 100644 src/Runtime/Source/system/Qt3DSConfig.h create mode 100644 src/Runtime/Source/system/Qt3DSCubicRoots.cpp create mode 100644 src/Runtime/Source/system/Qt3DSCubicRoots.h create mode 100644 src/Runtime/Source/system/Qt3DSCubicRootsImpl.h create mode 100644 src/Runtime/Source/system/Qt3DSDLLManager.cpp create mode 100644 src/Runtime/Source/system/Qt3DSDLLManager.h create mode 100644 src/Runtime/Source/system/Qt3DSDataLogger.cpp create mode 100644 src/Runtime/Source/system/Qt3DSDataLogger.h create mode 100644 src/Runtime/Source/system/Qt3DSDataLogger.hpp create mode 100644 src/Runtime/Source/system/Qt3DSDataLoggerEnums.h create mode 100644 src/Runtime/Source/system/Qt3DSDataLoggerViewer.h create mode 100644 src/Runtime/Source/system/Qt3DSEGLTimer.h create mode 100644 src/Runtime/Source/system/Qt3DSEndian.h create mode 100644 src/Runtime/Source/system/Qt3DSEulerAngles.cpp create mode 100644 src/Runtime/Source/system/Qt3DSEulerAngles.h create mode 100644 src/Runtime/Source/system/Qt3DSFNDTimer.h create mode 100644 src/Runtime/Source/system/Qt3DSFile.cpp create mode 100644 src/Runtime/Source/system/Qt3DSFile.h create mode 100644 src/Runtime/Source/system/Qt3DSFileStream.cpp create mode 100644 src/Runtime/Source/system/Qt3DSFileStream.h create mode 100644 src/Runtime/Source/system/Qt3DSFixedArray.h create mode 100644 src/Runtime/Source/system/Qt3DSFixedArray.inl create mode 100644 src/Runtime/Source/system/Qt3DSFunctionWrappers.cpp create mode 100644 src/Runtime/Source/system/Qt3DSFunctionWrappers.h create mode 100644 src/Runtime/Source/system/Qt3DSHash.h create mode 100644 src/Runtime/Source/system/Qt3DSIFileStream.h create mode 100644 src/Runtime/Source/system/Qt3DSIStream.h create mode 100644 src/Runtime/Source/system/Qt3DSITimer.h create mode 100644 src/Runtime/Source/system/Qt3DSMacros.h create mode 100644 src/Runtime/Source/system/Qt3DSMatrix.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMatrix.h create mode 100644 src/Runtime/Source/system/Qt3DSMemory.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemory.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryFilter.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryFilter.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryHeap.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryHeap.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryManager.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryManager.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryPool.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryPool.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryProbe.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryProbe.h create mode 100644 src/Runtime/Source/system/Qt3DSMemorySettings.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryStatistics.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryStatistics.h create mode 100644 src/Runtime/Source/system/Qt3DSMemoryTracker.cpp create mode 100644 src/Runtime/Source/system/Qt3DSMemoryTracker.h create mode 100644 src/Runtime/Source/system/Qt3DSPlatformSpecific.h create mode 100644 src/Runtime/Source/system/Qt3DSTimer.cpp create mode 100644 src/Runtime/Source/system/Qt3DSTimer.h create mode 100644 src/Runtime/Source/system/Qt3DSTypes.cpp create mode 100644 src/Runtime/Source/system/Qt3DSTypes.h create mode 100644 src/Runtime/Source/system/Qt3DSVector3.cpp create mode 100644 src/Runtime/Source/system/Qt3DSVector3.h create mode 100644 src/Runtime/Source/system/SystemPrefix.h create mode 100644 src/Runtime/Source/uipparser/Qt3DSIPresentation.h create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParser.h create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.cpp create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.h create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.cpp create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.h create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.cpp create mode 100644 src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.h create mode 100644 src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.cpp create mode 100644 src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.h create mode 100644 src/Runtime/Source/viewer/Qt3DSViewerApp.cpp create mode 100644 src/Runtime/Source/viewer/Qt3DSViewerApp.h create mode 100644 src/Runtime/Source/viewer/Qt3DSViewerTimer.h create mode 100644 src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.cpp create mode 100644 src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.h create mode 100644 src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.cpp create mode 100644 src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.h create mode 100644 src/Runtime/Source/viewer/perflog/TCPPerfLogClient.cpp create mode 100644 src/Runtime/Source/viewer/perflog/TCPPerfLogClient.h create mode 100644 src/Runtime/Source/viewer/perflog/TCPPerfLogClientStub.h create mode 100644 src/Runtime/Source/viewer/perflog/TCPPerfLogCommon.h create mode 100644 src/Runtime/Source/viewer/perflog/TCPPerfLogServer.cpp create mode 100644 src/Runtime/Source/viewer/perflog/TCPPerfLogServer.h create mode 100644 src/Runtime/Source/viewer/qt3dsruntimeglobal.h diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp index d224c975..237f0413 100644 --- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp +++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp @@ -85,7 +85,7 @@ #include #include #include -#include "Runtime/Include/q3dsqmlbehavior.h" +#include "runtime/q3dsqmlbehavior.h" #include "Qt3DSFileToolsSeekableMeshBufIOStream.h" #include "IObjectReferenceHelper.h" #include "StudioProjectSettings.h" diff --git a/src/Authoring/Common/Common.pro b/src/Authoring/Common/Common.pro index 805329ed..40afde5c 100644 --- a/src/Authoring/Common/Common.pro +++ b/src/Authoring/Common/Common.pro @@ -27,8 +27,7 @@ INCLUDEPATH += \ ../QT3DSDM \ ../QT3DSDM/Systems \ ../Studio/Utils \ - ../../Runtime/Source/Qt3DSFoundation/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include/foundation \ + ../../Runtime/Source/foundation \ ../../3rdparty/EASTL/UnknownVersion/include \ ../../3rdparty/color \ .. diff --git a/src/Authoring/CoreLib/CoreLib.pro b/src/Authoring/CoreLib/CoreLib.pro index a2ae1af0..49392d4d 100644 --- a/src/Authoring/CoreLib/CoreLib.pro +++ b/src/Authoring/CoreLib/CoreLib.pro @@ -53,14 +53,13 @@ INCLUDEPATH += \ ../Common/Code/Graph \ ../Common/Code/EulerAngles \ ../Common/Code/Serialize \ - ../../Runtime/Source/DataModel/Include \ - ../../Runtime/Source/Qt3DSRender/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include/foundation \ - ../../Runtime/Source/Qt3DSRuntimeRender/Include \ - ../../Runtime/Source/Qt3DSRuntimeRender/GraphObjects \ - ../../Runtime/Source/Qt3DSRuntimeRender/ResourceManager \ - ../../Runtime/Source/Qt3DSStateApplication/Application \ + ../../Runtime/Source/datamodel \ + ../../Runtime/Source/render \ + ../../Runtime/Source/foundation \ + ../../Runtime/Source/runtimerender \ + ../../Runtime/Source/runtimerender/graphobjects \ + ../../Runtime/Source/runtimerender/resourcemanager \ + ../../Runtime/Source/stateapplication \ ../../3rdparty/EASTL/UnknownVersion/include \ $$QMAKE_INCDIR_FBX \ ../../3rdparty/ColladaDOM/2.4.0/dom/include \ diff --git a/src/Authoring/FBXLineExporter/FBXLineExporter.pro b/src/Authoring/FBXLineExporter/FBXLineExporter.pro index 995feb41..5ae46df8 100644 --- a/src/Authoring/FBXLineExporter/FBXLineExporter.pro +++ b/src/Authoring/FBXLineExporter/FBXLineExporter.pro @@ -9,7 +9,7 @@ QT -= gui DEFINES += _UNICODE QT3DS_AUTHORING _AFXDLL PCRE_STATIC INCLUDEPATH += \ - ../../Runtime/Source/Qt3DSFoundation/Include \ + ../../Runtime/Source/foundation \ $$QMAKE_INCDIR_FBX \ ../../3rdparty/EASTL/UnknownVersion/include diff --git a/src/Authoring/MorphLines/MorphLines.pro b/src/Authoring/MorphLines/MorphLines.pro index 9cab8160..9cdace66 100644 --- a/src/Authoring/MorphLines/MorphLines.pro +++ b/src/Authoring/MorphLines/MorphLines.pro @@ -10,8 +10,8 @@ DEFINES += _UNICODE QT3DS_AUTHORING _AFXDLL PCRE_STATIC INCLUDEPATH += \ ../QT3DSIMP/Qt3DSImportLib \ - ../../Runtime/Source/Qt3DSRender/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include \ + ../../Runtime/Source/render \ + ../../Runtime/Source/foundation \ ../../3rdparty/EASTL/UnknownVersion/include LIBS += \ diff --git a/src/Authoring/QT3DSDM/QT3DSDM.pro b/src/Authoring/QT3DSDM/QT3DSDM.pro index 3e2cc68e..ca35f825 100644 --- a/src/Authoring/QT3DSDM/QT3DSDM.pro +++ b/src/Authoring/QT3DSDM/QT3DSDM.pro @@ -13,11 +13,11 @@ INCLUDEPATH += \ \ Systems \ Systems/Cores \ - ../../Runtime/Source/System/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include \ - ../../Runtime/Source/Qt3DSRuntimeRender/Include \ - ../../Runtime/Source/DataModel/Include \ - ../../Runtime/Source/Qt3DSRender/Include \ + ../../Runtime/Source/system \ + ../../Runtime/Source/foundation \ + ../../Runtime/Source/runtimerender \ + ../../Runtime/Source/datamodel \ + ../../Runtime/Source/render \ ../../3rdparty/EASTL/UnknownVersion/include \ ../../3rdparty/utf8cpp/2.3.2/source \ ../../3rdparty/color \ diff --git a/src/Authoring/Studio/Qt3DStudio.pro b/src/Authoring/Studio/Qt3DStudio.pro index 722ee49c..c1272d3e 100644 --- a/src/Authoring/Studio/Qt3DStudio.pro +++ b/src/Authoring/Studio/Qt3DStudio.pro @@ -72,14 +72,13 @@ INCLUDEPATH += \ ../Client/Code/Core/Doc/ClientDataModelBridge \ ../Client/Code/Shared \ ../Client/Code/Shared/Log \ - ../../Runtime/Source/Qt3DSRender/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include \ - ../../Runtime/Source/Qt3DSFoundation/Include/foundation \ - ../../Runtime/Source/Qt3DSRuntimeRender/Include \ - ../../Runtime/Source/Qt3DSRuntimeRender/GraphObjects \ - ../../Runtime/Source/Qt3DSRuntimeRender/ResourceManager \ - ../../Runtime/Source/Qt3DSStateApplication/Application \ - ../../Runtime/Source/Qt3DSEvent/InternalInclude \ + ../../Runtime/Source/render \ + ../../Runtime/Source/foundation \ + ../../Runtime/Source/runtimerender \ + ../../Runtime/Source/runtimerender/graphobjects \ + ../../Runtime/Source/runtimerender/resourcemanager \ + ../../Runtime/Source/stateapplication \ + ../../Runtime/Source/event \ ../../3rdparty/EASTL/UnknownVersion/include \ ../../3rdparty/color \ ../../QtExtras/qmlstreamer diff --git a/src/Authoring/commoninclude.pri b/src/Authoring/commoninclude.pri index 07f5d77b..889deb49 100644 --- a/src/Authoring/commoninclude.pri +++ b/src/Authoring/commoninclude.pri @@ -21,30 +21,27 @@ INCLUDEPATH += $$PWD/../Runtime/Source win32 { INCLUDEPATH += \ - $$PWD/../Runtime/Source/PlatformSpecific/Windows/PlatformLibs \ + $$PWD/../Runtime/Source/platformspecific/windows/libs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Windows/PlatformLibs \ - $$PWD/../Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Windows/Qt3DSLibs } linux { INCLUDEPATH += \ - $$PWD/../Runtime/Source/PlatformSpecific/Linux/PlatformLibs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Linux/PlatformLibs \ - $$PWD/../Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs \ + $$PWD/../Runtime/Source/platformspecific/Linux/libs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Linux/Qt3DSLibs } macos { INCLUDEPATH += \ - $$PWD/../Runtime/Source/PlatformSpecific/Macos/PlatformLibs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Macos/PlatformLibs \ - $$PWD/../Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs \ + $$PWD/../Runtime/Source/platformspecific/macos/libs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Macos/Qt3DSLibs } android { INCLUDEPATH += \ - $$PWD/../Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs - $$PWD/../Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_thread + $$PWD/../Runtime/Source/platformspecific/Android/jni/libs + $$PWD/../Runtime/Source/platformspecific/Android/jni/libs/nv_thread } diff --git a/src/Runtime/Qt3DSRuntime/Qt3DSRuntime.pro b/src/Runtime/Qt3DSRuntime/Qt3DSRuntime.pro index 0e675518..ac5a3936 100644 --- a/src/Runtime/Qt3DSRuntime/Qt3DSRuntime.pro +++ b/src/Runtime/Qt3DSRuntime/Qt3DSRuntime.pro @@ -18,14 +18,14 @@ integrity|ios { } SOURCES += \ - ../Source/Viewer/Qt3DSAudioPlayerImpl.cpp \ - ../Source/Viewer/Qt3DSViewerApp.cpp + ../Source/viewer/Qt3DSAudioPlayerImpl.cpp \ + ../Source/viewer/Qt3DSViewerApp.cpp HEADERS += \ - ../Source/Viewer/qt3dsruntimeglobal.h \ - ../Source/Viewer/Qt3DSAudioPlayerImpl.h \ - ../Source/Viewer/Qt3DSViewerApp.h \ - ../Source/Viewer/Qt3DSViewerTimer.h + ../Source/viewer/qt3dsruntimeglobal.h \ + ../Source/viewer/Qt3DSAudioPlayerImpl.h \ + ../Source/viewer/Qt3DSViewerApp.h \ + ../Source/viewer/Qt3DSViewerTimer.h linux|qnx|mingw { BEGIN_ARCHIVE = -Wl,--whole-archive diff --git a/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro b/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro index c1986ce0..7020f79e 100644 --- a/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro +++ b/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro @@ -18,599 +18,599 @@ QT += qml # Foundation SOURCES += \ - ../Source/Qt3DSFoundation/Source/foundation/ConvertUTF.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/EASTL_new.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/FileTools.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/IOStreams.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/Qt3DSLogging.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/Qt3DSFoundation.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/Qt3DSMathUtils.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/Qt3DSPerfTimer.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/Qt3DSSystem.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/Socket.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/StringTable.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/XML.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/TrackingAllocator.cpp \ - ../Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp \ - ../Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp \ - ../Source/Engine/Source/Qt3DSRenderRuntimeBindingImplRenderer.cpp \ - ../Source/Engine/Source/Qt3DSRenderRuntimeBindingImplTranslation.cpp \ - ../Source/Engine/Source/Qt3DSTegraApplication.cpp \ - ../Source/Engine/Source/Qt3DSTegraInputEngine.cpp \ - ../Source/Runtime/Source/Qt3DSActivationManager.cpp \ - ../Source/Runtime/Source/Qt3DSAnimationSystem.cpp \ - ../Source/Runtime/Source/Qt3DSApplication.cpp \ - ../Source/Runtime/Source/Qt3DSAttributeHashes.cpp \ - ../Source/Runtime/Source/Qt3DSComponentManager.cpp \ - ../Source/Runtime/Source/Qt3DSElementSystem.cpp \ - ../Source/Runtime/Source/Qt3DSEventCallbacks.cpp \ - ../Source/Runtime/Source/Qt3DSInputEngine.cpp \ - ../Source/Runtime/Source/Qt3DSLogicSystem.cpp \ - ../Source/Runtime/Source/Qt3DSCommandHelper.cpp \ - ../Source/Runtime/Source/Qt3DSElementHelper.cpp \ - ../Source/Runtime/Source/Qt3DSOutputMemoryStream.cpp \ - ../Source/Runtime/Source/Qt3DSParametersSystem.cpp \ - ../Source/Runtime/Source/Qt3DSPresentation.cpp \ - ../Source/Runtime/Source/Qt3DSPresentationFrameData.cpp \ - ../Source/Runtime/Source/Qt3DSQmlElementHelper.cpp \ - ../Source/Runtime/Source/Qt3DSQmlEngine.cpp \ - ../Source/Runtime/Source/Qt3DSSlideSystem.cpp \ - ../Source/Runtime/Source/Qt3DSTimePolicy.cpp \ - ../Source/Runtime/Source/q3dsvariantconfig.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.cpp \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.cpp \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.cpp \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.cpp \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.cpp \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureBMP.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureGIF.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureHDR.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSOffscreenRenderManager.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSOldNBustedRenderPlugin.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSOnscreenTextRenderer.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSQtTextRenderer.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderClippingFrustum.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialSystem.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDefaultMaterialShaderGenerator.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDynamicObjectSystem.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEffectSystem.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRendererUtil.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEulerAngles.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGpuProfiler.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGraphObjectSerializer.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderImageScaler.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderInputStreamFactory.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPathManager.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsRenderer.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsTypes.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRay.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRenderList.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCache.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGenerator.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGeneratorV2.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShadowMap.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderSubpresentation.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureAtlas.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureCache.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextureAtlas.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderThreadPool.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPSharedTranslation.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderWidgets.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSTextRenderer.cpp \ - ../Source/System/Source/Qt3DSAssert.cpp \ - ../Source/System/Source/Qt3DSBoundingBox.cpp \ - ../Source/System/Source/Qt3DSColor.cpp \ - ../Source/System/Source/Qt3DSCubicRoots.cpp \ - ../Source/System/Source/Qt3DSDataLogger.cpp \ - ../Source/System/Source/Qt3DSDLLManager.cpp \ - ../Source/System/Source/Qt3DSEulerAngles.cpp \ - ../Source/System/Source/Qt3DSFile.cpp \ - ../Source/System/Source/Qt3DSFileStream.cpp \ - ../Source/System/Source/Qt3DSFunctionWrappers.cpp \ - ../Source/System/Source/Qt3DSMatrix.cpp \ - ../Source/System/Source/Qt3DSMemory.cpp \ - ../Source/System/Source/Qt3DSMemoryFilter.cpp \ - ../Source/System/Source/Qt3DSMemoryHeap.cpp \ - ../Source/System/Source/Qt3DSMemoryManager.cpp \ - ../Source/System/Source/Qt3DSMemoryPool.cpp \ - ../Source/System/Source/Qt3DSMemoryProbe.cpp \ - ../Source/System/Source/Qt3DSMemoryStatistics.cpp \ - ../Source/System/Source/Qt3DSMemoryTracker.cpp \ - ../Source/System/Source/Qt3DSTimer.cpp \ - ../Source/System/Source/Qt3DSTypes.cpp \ - ../Source/System/Source/Qt3DSVector3.cpp \ - ../Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.cpp \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphRuntimeDebugger.cpp \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDataTest.cpp \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggedInterpreter.cpp \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.cpp \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerListener.cpp \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.cpp \ - ../Source/Qt3DSStateApplication/Source/Qt3DSStateContext.cpp \ - ../Source/Qt3DSStateApplication/Source/Qt3DSStateExecutionContext.cpp \ - ../Source/Qt3DSStateApplication/Source/Qt3DSStateInterpreter.cpp \ - ../Source/Qt3DSStateApplication/Source/Qt3DSStateVisualBindingContext.cpp \ - ../Source/Qt3DSStateApplication/Source/Qt3DSStateXMLIO.cpp \ - ../Source/UIPParser/Source/Qt3DSUIPParserActionHelper.cpp \ - ../Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp \ - ../Source/UIPParser/Source/Qt3DSUIPParserObjectRefHelper.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp + ../Source/foundation/ConvertUTF.cpp \ + ../Source/foundation/EASTL_new.cpp \ + ../Source/foundation/FileTools.cpp \ + ../Source/foundation/IOStreams.cpp \ + ../Source/foundation/Qt3DSLogging.cpp \ + ../Source/foundation/Qt3DSFoundation.cpp \ + ../Source/foundation/Qt3DSMathUtils.cpp \ + ../Source/foundation/Qt3DSPerfTimer.cpp \ + ../Source/foundation/Qt3DSSystem.cpp \ + ../Source/foundation/Socket.cpp \ + ../Source/foundation/StringTable.cpp \ + ../Source/foundation/XML.cpp \ + ../Source/foundation/TrackingAllocator.cpp \ + ../Source/runtimerender/q3dsqmlrender.cpp \ + ../Source/engine/Qt3DSRenderRuntimeBinding.cpp \ + ../Source/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp \ + ../Source/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp \ + ../Source/engine/Qt3DSTegraApplication.cpp \ + ../Source/engine/Qt3DSTegraInputEngine.cpp \ + ../Source/runtime/Qt3DSActivationManager.cpp \ + ../Source/runtime/Qt3DSAnimationSystem.cpp \ + ../Source/runtime/Qt3DSApplication.cpp \ + ../Source/runtime/Qt3DSAttributeHashes.cpp \ + ../Source/runtime/Qt3DSComponentManager.cpp \ + ../Source/runtime/Qt3DSElementSystem.cpp \ + ../Source/runtime/Qt3DSEventCallbacks.cpp \ + ../Source/runtime/Qt3DSInputEngine.cpp \ + ../Source/runtime/Qt3DSLogicSystem.cpp \ + ../Source/runtime/Qt3DSCommandHelper.cpp \ + ../Source/runtime/Qt3DSElementHelper.cpp \ + ../Source/runtime/Qt3DSOutputMemoryStream.cpp \ + ../Source/runtime/Qt3DSParametersSystem.cpp \ + ../Source/runtime/Qt3DSPresentation.cpp \ + ../Source/runtime/Qt3DSPresentationFrameData.cpp \ + ../Source/runtime/Qt3DSQmlElementHelper.cpp \ + ../Source/runtime/Qt3DSQmlEngine.cpp \ + ../Source/runtime/Qt3DSSlideSystem.cpp \ + ../Source/runtime/Qt3DSTimePolicy.cpp \ + ../Source/runtime/q3dsvariantconfig.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderCamera.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderEffect.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderLayer.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderLight.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderModel.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderNode.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderPath.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderPresentation.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderScene.cpp \ + ../Source/runtimerender/graphobjects/Qt3DSRenderText.cpp \ + ../Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.cpp \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureBMP.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureHDR.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.cpp \ + ../Source/runtimerender/Qt3DSOffscreenRenderManager.cpp \ + ../Source/runtimerender/Qt3DSOldNBustedRenderPlugin.cpp \ + ../Source/runtimerender/Qt3DSOnscreenTextRenderer.cpp \ + ../Source/runtimerender/Qt3DSQtTextRenderer.cpp \ + ../Source/runtimerender/Qt3DSRenderClippingFrustum.cpp \ + ../Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.cpp \ + ../Source/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp \ + ../Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp \ + ../Source/runtimerender/Qt3DSRenderDynamicObjectSystem.cpp \ + ../Source/runtimerender/Qt3DSRenderEffectSystem.cpp \ + ../Source/runtimerender/Qt3DSRendererUtil.cpp \ + ../Source/runtimerender/Qt3DSRenderEulerAngles.cpp \ + ../Source/runtimerender/Qt3DSRenderGpuProfiler.cpp \ + ../Source/runtimerender/Qt3DSRenderGraphObjectSerializer.cpp \ + ../Source/runtimerender/Qt3DSRenderImageScaler.cpp \ + ../Source/runtimerender/Qt3DSRenderInputStreamFactory.cpp \ + ../Source/runtimerender/Qt3DSRenderPathManager.cpp \ + ../Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.cpp \ + ../Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.cpp \ + ../Source/runtimerender/Qt3DSRenderPlugin.cpp \ + ../Source/runtimerender/Qt3DSRenderRay.cpp \ + ../Source/runtimerender/Qt3DSRenderRenderList.cpp \ + ../Source/runtimerender/Qt3DSRenderShaderCache.cpp \ + ../Source/runtimerender/Qt3DSRenderShaderCodeGenerator.cpp \ + ../Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.cpp \ + ../Source/runtimerender/Qt3DSRenderShadowMap.cpp \ + ../Source/runtimerender/Qt3DSRenderSubpresentation.cpp \ + ../Source/runtimerender/Qt3DSRenderTextTextureAtlas.cpp \ + ../Source/runtimerender/Qt3DSRenderTextTextureCache.cpp \ + ../Source/runtimerender/Qt3DSRenderTextureAtlas.cpp \ + ../Source/runtimerender/Qt3DSRenderThreadPool.cpp \ + ../Source/runtimerender/Qt3DSRenderUIPLoader.cpp \ + ../Source/runtimerender/Qt3DSRenderUIPSharedTranslation.cpp \ + ../Source/runtimerender/Qt3DSRenderWidgets.cpp \ + ../Source/runtimerender/Qt3DSTextRenderer.cpp \ + ../Source/system/Qt3DSAssert.cpp \ + ../Source/system/Qt3DSBoundingBox.cpp \ + ../Source/system/Qt3DSColor.cpp \ + ../Source/system/Qt3DSCubicRoots.cpp \ + ../Source/system/Qt3DSDataLogger.cpp \ + ../Source/system/Qt3DSDLLManager.cpp \ + ../Source/system/Qt3DSEulerAngles.cpp \ + ../Source/system/Qt3DSFile.cpp \ + ../Source/system/Qt3DSFileStream.cpp \ + ../Source/system/Qt3DSFunctionWrappers.cpp \ + ../Source/system/Qt3DSMatrix.cpp \ + ../Source/system/Qt3DSMemory.cpp \ + ../Source/system/Qt3DSMemoryFilter.cpp \ + ../Source/system/Qt3DSMemoryHeap.cpp \ + ../Source/system/Qt3DSMemoryManager.cpp \ + ../Source/system/Qt3DSMemoryPool.cpp \ + ../Source/system/Qt3DSMemoryProbe.cpp \ + ../Source/system/Qt3DSMemoryStatistics.cpp \ + ../Source/system/Qt3DSMemoryTracker.cpp \ + ../Source/system/Qt3DSTimer.cpp \ + ../Source/system/Qt3DSTypes.cpp \ + ../Source/system/Qt3DSVector3.cpp \ + ../Source/stateapplication/Qt3DSStateApplication.cpp \ + ../Source/stateapplication/debugger/Qt3DSSceneGraphRuntimeDebugger.cpp \ + ../Source/stateapplication/debugger/Qt3DSStateDataTest.cpp \ + ../Source/stateapplication/debugger/Qt3DSStateDebuggedInterpreter.cpp \ + ../Source/stateapplication/debugger/Qt3DSStateDebugger.cpp \ + ../Source/stateapplication/debugger/Qt3DSStateDebuggerListener.cpp \ + ../Source/stateapplication/debugger/Qt3DSStateDebugStreams.cpp \ + ../Source/stateapplication/Qt3DSStateContext.cpp \ + ../Source/stateapplication/Qt3DSStateExecutionContext.cpp \ + ../Source/stateapplication/Qt3DSStateInterpreter.cpp \ + ../Source/stateapplication/Qt3DSStateVisualBindingContext.cpp \ + ../Source/stateapplication/Qt3DSStateXMLIO.cpp \ + ../Source/uipparser/Qt3DSUIPParserActionHelper.cpp \ + ../Source/uipparser/Qt3DSUIPParserImpl.cpp \ + ../Source/uipparser/Qt3DSUIPParserObjectRefHelper.cpp \ + ../Source/runtimerender/Qt3DSRenderContextCore.cpp \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp HEADERS += \ - ../Source/Qt3DSFoundation/Include/foundation/ConvertUTF.h \ - ../Source/Qt3DSFoundation/Include/foundation/FileTools.h \ - ../Source/Qt3DSFoundation/Include/foundation/IOStreams.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSLogging.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSFoundation.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSMathUtils.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSPerfTimer.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSSystem.h \ - ../Source/Qt3DSFoundation/Include/foundation/Socket.h \ - ../Source/Qt3DSFoundation/Include/foundation/StringTable.h \ - ../Source/Qt3DSFoundation/Include/foundation/XML.h \ - ../Source/Qt3DSFoundation/Include/foundation/AutoDeallocatorAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/FastAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/PoolingAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/PreAllocatedAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DS.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocatorCallback.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSAssert.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSAtomic.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSBasicTemplates.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSBounds3.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSBroadcastingAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSContainers.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSDataRef.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSDiscriminatedUnion.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSFastIPC.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSFlags.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSFPU.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSIndexableLinkedList.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSIntrinsics.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveLinkedList.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveSet.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSIPC.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSMat33.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSMat44.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSMath.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSMemoryBuffer.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSMutex.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSNoCopy.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSOption.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSPlane.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSPool.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSPreprocessor.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSQuat.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSRefCounted.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSSemaphore.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSSimpleTypes.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSStringTokenizer.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSSync.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSThread.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSTime.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSTransform.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSUnionCast.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSUtilities.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSVec2.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSVec3.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSVec4.h \ - ../Source/Qt3DSFoundation/Include/foundation/Qt3DSVersionNumber.h \ - ../Source/Qt3DSFoundation/Include/foundation/SerializationTypes.h \ - ../Source/Qt3DSFoundation/Include/foundation/StrConvertUTF.h \ - ../Source/Qt3DSFoundation/Include/foundation/StringConversion.h \ - ../Source/Qt3DSFoundation/Include/foundation/StringConversionImpl.h \ - ../Source/Qt3DSFoundation/Include/foundation/TaggedPointer.h \ - ../Source/Qt3DSFoundation/Include/foundation/ThreadSafeQueue.h \ - ../Source/Qt3DSFoundation/Include/foundation/TrackingAllocator.h \ - ../Source/Qt3DSFoundation/Include/foundation/Utils.h \ - ../Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h \ - ../Source/Engine/Include/Qt3DSRenderRuntimeBinding.h \ - ../Source/Engine/Include/Qt3DSRenderRuntimeBindingImpl.h \ - ../Source/Engine/Include/Qt3DSTegraApplication.h \ - ../Source/Engine/Include/Qt3DSTegraInputEngine.h \ - ../Source/Runtime/Include/Qt3DSActivationManager.h \ - ../Source/Runtime/Include/Qt3DSAnimationSystem.h \ - ../Source/Runtime/Include/Qt3DSApplication.h \ - ../Source/Runtime/Include/Qt3DSAttributeHashes.h \ - ../Source/Runtime/Include/Qt3DSComponentManager.h \ - ../Source/Runtime/Include/Qt3DSElementSystem.h \ - ../Source/Runtime/Include/Qt3DSEventCallbacks.h \ - ../Source/Runtime/Include/Qt3DSInputEngine.h \ - ../Source/Runtime/Include/Qt3DSLogicSystem.h \ - ../Source/Runtime/Include/Qt3DSCommandHelper.h \ - ../Source/Runtime/Include/Qt3DSElementHelper.h \ - ../Source/Runtime/Include/Qt3DSOutputMemoryStream.h \ - ../Source/Runtime/Include/Qt3DSParametersSystem.h \ - ../Source/Runtime/Include/Qt3DSPresentation.h \ - ../Source/Runtime/Include/Qt3DSPresentationFrameData.h \ - ../Source/Runtime/Include/Qt3DSQmlElementHelper.h \ - ../Source/Runtime/Include/Qt3DSQmlEngine.h \ - ../Source/Runtime/Include/Qt3DSSlideSystem.h \ - ../Source/Runtime/Include/Qt3DSTimePolicy.h \ - ../Source/Runtime/Include/Qt3DSApplicationValues.h \ - ../Source/Runtime/Include/Qt3DSIComponentManager.h \ - ../Source/Runtime/Include/Qt3DSIInputSystem.h \ - ../Source/Runtime/Include/Qt3DSInputDefs.h \ - ../Source/Runtime/Include/Qt3DSInputEventTypes.h \ - ../Source/Runtime/Include/Qt3DSIStateful.h \ - ../Source/Runtime/Include/Qt3DSIText.h \ - ../Source/Runtime/Include/Qt3DSKernelTypes.h \ - ../Source/Runtime/Include/q3dsvariantconfig_p.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCustomMaterial.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderGraphObject.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderMaterialDirty.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPathSubPath.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderReferencedMaterial.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.h \ - ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderKey.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRender.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderableImage.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderClippingFrustum.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialRenderContext.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialShaderGenerator.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialSystem.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDefaultMaterialShaderGenerator.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystem.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemCommands.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemUtil.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEffectSystem.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderer.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRendererUtil.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEulerAngles.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectPickQuery.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectSerializer.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectTypes.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageScaler.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageTextureData.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderInputStreamFactory.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialHelpers.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialShaderGenerator.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMesh.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathManager.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathMath.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathRenderContext.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsRenderer.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsTypes.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPlugin.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginCInterface.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginGraphObject.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginPropertyValue.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderProfiler.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRay.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRenderList.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRotationHelper.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCache.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGenerator.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGeneratorV2.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderKeys.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShadowMap.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderString.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubPresentationHelper.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTaggedPointer.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTessModeValues.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureAtlas.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureCache.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTypes.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextureAtlas.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderThreadPool.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPSharedTranslation.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderWidgets.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSTextRenderer.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.h \ - ../Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSVertexPipelineImpl.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureFreeImageCompat.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.h \ - ../Source/System/Include/Qt3DSArray.h \ - ../Source/System/Include/Qt3DSAssert.h \ - ../Source/System/Include/Qt3DSAudioPlayer.h \ - ../Source/System/Include/Qt3DSBasicPluginDLL.h \ - ../Source/System/Include/Qt3DSBezierEval.h \ - ../Source/System/Include/Qt3DSBoundingBox.h \ - ../Source/System/Include/Qt3DSCircularArray.h \ - ../Source/System/Include/Qt3DSColor.h \ - ../Source/System/Include/Qt3DSConfig.h \ - ../Source/System/Include/Qt3DSCubicRoots.h \ - ../Source/System/Include/Qt3DSCubicRootsImpl.h \ - ../Source/System/Include/Qt3DSDataLogger.h \ - ../Source/System/Include/Qt3DSDataLogger.hpp \ - ../Source/System/Include/Qt3DSDataLoggerEnums.h \ - ../Source/System/Include/Qt3DSDataLoggerViewer.h \ - ../Source/System/Include/Qt3DSDLLManager.h \ - ../Source/System/Include/Qt3DSEGLTimer.h \ - ../Source/System/Include/Qt3DSEndian.h \ - ../Source/System/Include/Qt3DSEulerAngles.h \ - ../Source/System/Include/Qt3DSFile.h \ - ../Source/System/Include/Qt3DSFileStream.h \ - ../Source/System/Include/Qt3DSFixedArray.h \ - ../Source/System/Include/Qt3DSFNDTimer.h \ - ../Source/System/Include/Qt3DSFunctionWrappers.h \ - ../Source/System/Include/Qt3DSHash.h \ - ../Source/System/Include/Qt3DSIFileStream.h \ - ../Source/System/Include/Qt3DSIStream.h \ - ../Source/System/Include/Qt3DSITimer.h \ - ../Source/System/Include/Qt3DSMacros.h \ - ../Source/System/Include/Qt3DSMatrix.h \ - ../Source/System/Include/Qt3DSMemory.h \ - ../Source/System/Include/Qt3DSMemoryFilter.h \ - ../Source/System/Include/Qt3DSMemoryHeap.h \ - ../Source/System/Include/Qt3DSMemoryManager.h \ - ../Source/System/Include/Qt3DSMemoryPool.h \ - ../Source/System/Include/Qt3DSMemoryProbe.h \ - ../Source/System/Include/Qt3DSMemorySettings.h \ - ../Source/System/Include/Qt3DSMemoryStatistics.h \ - ../Source/System/Include/Qt3DSMemoryTracker.h \ - ../Source/System/Include/Qt3DSPlatformSpecific.h \ - ../Source/System/Include/Qt3DSTimer.h \ - ../Source/System/Include/Qt3DSTypes.h \ - ../Source/System/Include/Qt3DSVector3.h \ - ../Source/System/Include/Qt3DSArray.inl \ - ../Source/System/Include/Qt3DSCircularArray.inl \ - ../Source/System/Include/Qt3DSFixedArray.inl \ - ../Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebugger.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerProtocol.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerValue.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerProtocol.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerValues.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.h \ - ../Source/Qt3DSStateApplication/Debugger/Qt3DSStateTest.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSState.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateContext.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionContext.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionTypes.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateIdValue.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateInterpreter.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateScriptContext.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateSharedImpl.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateSignalConnection.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateTypes.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContext.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextCommands.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextValues.h \ - ../Source/Qt3DSStateApplication/Include/Qt3DSStateXMLIO.h \ - ../Source/UIPParser/Include/Qt3DSIPresentation.h \ - ../Source/UIPParser/Include/Qt3DSUIPParser.h \ - ../Source/UIPParser/Include/Qt3DSUIPParserActionHelper.h \ - ../Source/UIPParser/Include/Qt3DSUIPParserImpl.h \ - ../Source/UIPParser/Include/Qt3DSUIPParserObjectRefHelper.h \ - ../Source/Runtime/Include/Qt3DSCommandEventTypes.h \ - ../Source/Runtime/Include/Qt3DSEvent.h \ - ../Source/Runtime/Include/Qt3DSFrameworkTypes.h \ - ../Source/Runtime/Include/Qt3DSInputFrame.h \ - ../Source/Runtime/Include/Qt3DSIScene.h \ - ../Source/Runtime/Include/Qt3DSIScriptBridge.h \ - ../Source/Runtime/Include/Qt3DSPickFrame.h \ - ../Source/Runtime/Include/Qt3DSRuntimeFactory.h \ - ../Source/Runtime/Include/Qt3DSSceneManager.h \ - ../Source/Engine/Include/Qt3DSEGLInfo.h \ - ../Source/Engine/Include/Qt3DSEGLWindowSystem.h \ - ../Source/Engine/Include/Qt3DSPluginDLL.h \ - ../Source/Engine/Include/Qt3DSWindowSystem.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderContextCore.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h \ - ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h + ../Source/foundation/ConvertUTF.h \ + ../Source/foundation/FileTools.h \ + ../Source/foundation/IOStreams.h \ + ../Source/foundation/Qt3DSLogging.h \ + ../Source/foundation/Qt3DSFoundation.h \ + ../Source/foundation/Qt3DSMathUtils.h \ + ../Source/foundation/Qt3DSPerfTimer.h \ + ../Source/foundation/Qt3DSSystem.h \ + ../Source/foundation/Socket.h \ + ../Source/foundation/StringTable.h \ + ../Source/foundation/XML.h \ + ../Source/foundation/AutoDeallocatorAllocator.h \ + ../Source/foundation/FastAllocator.h \ + ../Source/foundation/PoolingAllocator.h \ + ../Source/foundation/PreAllocatedAllocator.h \ + ../Source/foundation/Qt3DS.h \ + ../Source/foundation/Qt3DSAllocator.h \ + ../Source/foundation/Qt3DSAllocatorCallback.h \ + ../Source/foundation/Qt3DSAssert.h \ + ../Source/foundation/Qt3DSAtomic.h \ + ../Source/foundation/Qt3DSBasicTemplates.h \ + ../Source/foundation/Qt3DSBounds3.h \ + ../Source/foundation/Qt3DSBroadcastingAllocator.h \ + ../Source/foundation/Qt3DSContainers.h \ + ../Source/foundation/Qt3DSDataRef.h \ + ../Source/foundation/Qt3DSDiscriminatedUnion.h \ + ../Source/foundation/Qt3DSFastIPC.h \ + ../Source/foundation/Qt3DSFlags.h \ + ../Source/foundation/Qt3DSFPU.h \ + ../Source/foundation/Qt3DSIndexableLinkedList.h \ + ../Source/foundation/Qt3DSIntrinsics.h \ + ../Source/foundation/Qt3DSInvasiveLinkedList.h \ + ../Source/foundation/Qt3DSInvasiveSet.h \ + ../Source/foundation/Qt3DSIPC.h \ + ../Source/foundation/Qt3DSMat33.h \ + ../Source/foundation/Qt3DSMat44.h \ + ../Source/foundation/Qt3DSMath.h \ + ../Source/foundation/Qt3DSMemoryBuffer.h \ + ../Source/foundation/Qt3DSMutex.h \ + ../Source/foundation/Qt3DSNoCopy.h \ + ../Source/foundation/Qt3DSOption.h \ + ../Source/foundation/Qt3DSPlane.h \ + ../Source/foundation/Qt3DSPool.h \ + ../Source/foundation/Qt3DSPreprocessor.h \ + ../Source/foundation/Qt3DSQuat.h \ + ../Source/foundation/Qt3DSRefCounted.h \ + ../Source/foundation/Qt3DSSemaphore.h \ + ../Source/foundation/Qt3DSSimpleTypes.h \ + ../Source/foundation/Qt3DSStringTokenizer.h \ + ../Source/foundation/Qt3DSSync.h \ + ../Source/foundation/Qt3DSThread.h \ + ../Source/foundation/Qt3DSTime.h \ + ../Source/foundation/Qt3DSTransform.h \ + ../Source/foundation/Qt3DSUnionCast.h \ + ../Source/foundation/Qt3DSUtilities.h \ + ../Source/foundation/Qt3DSVec2.h \ + ../Source/foundation/Qt3DSVec3.h \ + ../Source/foundation/Qt3DSVec4.h \ + ../Source/foundation/Qt3DSVersionNumber.h \ + ../Source/foundation/SerializationTypes.h \ + ../Source/foundation/StrConvertUTF.h \ + ../Source/foundation/StringConversion.h \ + ../Source/foundation/StringConversionImpl.h \ + ../Source/foundation/TaggedPointer.h \ + ../Source/foundation/ThreadSafeQueue.h \ + ../Source/foundation/TrackingAllocator.h \ + ../Source/foundation/Utils.h \ + ../Source/runtimerender/q3dsqmlrender.h \ + ../Source/engine/Qt3DSRenderRuntimeBinding.h \ + ../Source/engine/Qt3DSRenderRuntimeBindingImpl.h \ + ../Source/engine/Qt3DSTegraApplication.h \ + ../Source/engine/Qt3DSTegraInputEngine.h \ + ../Source/runtime/Qt3DSActivationManager.h \ + ../Source/runtime/Qt3DSAnimationSystem.h \ + ../Source/runtime/Qt3DSApplication.h \ + ../Source/runtime/Qt3DSAttributeHashes.h \ + ../Source/runtime/Qt3DSComponentManager.h \ + ../Source/runtime/Qt3DSElementSystem.h \ + ../Source/runtime/Qt3DSEventCallbacks.h \ + ../Source/runtime/Qt3DSInputEngine.h \ + ../Source/runtime/Qt3DSLogicSystem.h \ + ../Source/runtime/Qt3DSCommandHelper.h \ + ../Source/runtime/Qt3DSElementHelper.h \ + ../Source/runtime/Qt3DSOutputMemoryStream.h \ + ../Source/runtime/Qt3DSParametersSystem.h \ + ../Source/runtime/Qt3DSPresentation.h \ + ../Source/runtime/Qt3DSPresentationFrameData.h \ + ../Source/runtime/Qt3DSQmlElementHelper.h \ + ../Source/runtime/Qt3DSQmlEngine.h \ + ../Source/runtime/Qt3DSSlideSystem.h \ + ../Source/runtime/Qt3DSTimePolicy.h \ + ../Source/runtime/Qt3DSApplicationValues.h \ + ../Source/runtime/Qt3DSIComponentManager.h \ + ../Source/runtime/Qt3DSIInputSystem.h \ + ../Source/runtime/Qt3DSInputDefs.h \ + ../Source/runtime/Qt3DSInputEventTypes.h \ + ../Source/runtime/Qt3DSIStateful.h \ + ../Source/runtime/Qt3DSIText.h \ + ../Source/runtime/Qt3DSKernelTypes.h \ + ../Source/runtime/q3dsvariantconfig_p.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderCamera.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderCustomMaterial.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderEffect.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderGraphObject.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderImage.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderLayer.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderLight.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderMaterialDirty.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderModel.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderNode.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderPath.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderPathSubPath.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderPresentation.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderReferencedMaterial.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderScene.h \ + ../Source/runtimerender/graphobjects/Qt3DSRenderText.h \ + ../Source/runtimerender/Qt3DSOffscreenRenderKey.h \ + ../Source/runtimerender/Qt3DSOffscreenRenderManager.h \ + ../Source/runtimerender/Qt3DSOldNBustedRenderPlugin.h \ + ../Source/runtimerender/Qt3DSRender.h \ + ../Source/runtimerender/Qt3DSRenderableImage.h \ + ../Source/runtimerender/Qt3DSRenderClippingFrustum.h \ + ../Source/runtimerender/Qt3DSRenderCustomMaterialRenderContext.h \ + ../Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.h \ + ../Source/runtimerender/Qt3DSRenderCustomMaterialSystem.h \ + ../Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.h \ + ../Source/runtimerender/Qt3DSRenderDynamicObjectSystem.h \ + ../Source/runtimerender/Qt3DSRenderDynamicObjectSystemCommands.h \ + ../Source/runtimerender/Qt3DSRenderDynamicObjectSystemUtil.h \ + ../Source/runtimerender/Qt3DSRenderEffectSystem.h \ + ../Source/runtimerender/Qt3DSRenderer.h \ + ../Source/runtimerender/Qt3DSRendererUtil.h \ + ../Source/runtimerender/Qt3DSRenderEulerAngles.h \ + ../Source/runtimerender/Qt3DSRenderGraphObjectPickQuery.h \ + ../Source/runtimerender/Qt3DSRenderGraphObjectSerializer.h \ + ../Source/runtimerender/Qt3DSRenderGraphObjectTypes.h \ + ../Source/runtimerender/Qt3DSRenderImageScaler.h \ + ../Source/runtimerender/Qt3DSRenderImageTextureData.h \ + ../Source/runtimerender/Qt3DSRenderInputStreamFactory.h \ + ../Source/runtimerender/Qt3DSRenderMaterialHelpers.h \ + ../Source/runtimerender/Qt3DSRenderMaterialShaderGenerator.h \ + ../Source/runtimerender/Qt3DSRenderMesh.h \ + ../Source/runtimerender/Qt3DSRenderPathManager.h \ + ../Source/runtimerender/Qt3DSRenderPathMath.h \ + ../Source/runtimerender/Qt3DSRenderPathRenderContext.h \ + ../Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.h \ + ../Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.h \ + ../Source/runtimerender/Qt3DSRenderPlugin.h \ + ../Source/runtimerender/Qt3DSRenderPluginCInterface.h \ + ../Source/runtimerender/Qt3DSRenderPluginGraphObject.h \ + ../Source/runtimerender/Qt3DSRenderPluginPropertyValue.h \ + ../Source/runtimerender/Qt3DSRenderProfiler.h \ + ../Source/runtimerender/Qt3DSRenderRay.h \ + ../Source/runtimerender/Qt3DSRenderRenderList.h \ + ../Source/runtimerender/Qt3DSRenderRotationHelper.h \ + ../Source/runtimerender/Qt3DSRenderShaderCache.h \ + ../Source/runtimerender/Qt3DSRenderShaderCodeGenerator.h \ + ../Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.h \ + ../Source/runtimerender/Qt3DSRenderShaderKeys.h \ + ../Source/runtimerender/Qt3DSRenderShadowMap.h \ + ../Source/runtimerender/Qt3DSRenderString.h \ + ../Source/runtimerender/Qt3DSRenderSubpresentation.h \ + ../Source/runtimerender/Qt3DSRenderSubPresentationHelper.h \ + ../Source/runtimerender/Qt3DSRenderTaggedPointer.h \ + ../Source/runtimerender/Qt3DSRenderTessModeValues.h \ + ../Source/runtimerender/Qt3DSRenderTextTextureAtlas.h \ + ../Source/runtimerender/Qt3DSRenderTextTextureCache.h \ + ../Source/runtimerender/Qt3DSRenderTextTypes.h \ + ../Source/runtimerender/Qt3DSRenderTextureAtlas.h \ + ../Source/runtimerender/Qt3DSRenderThreadPool.h \ + ../Source/runtimerender/Qt3DSRenderUIPLoader.h \ + ../Source/runtimerender/Qt3DSRenderUIPSharedTranslation.h \ + ../Source/runtimerender/Qt3DSRenderWidgets.h \ + ../Source/runtimerender/Qt3DSTextRenderer.h \ + ../Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImpl.h \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h \ + ../Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.h \ + ../Source/runtimerender/rendererimpl/Qt3DSVertexPipelineImpl.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.h \ + ../Source/system/Qt3DSArray.h \ + ../Source/system/Qt3DSAssert.h \ + ../Source/system/Qt3DSAudioPlayer.h \ + ../Source/system/Qt3DSBasicPluginDLL.h \ + ../Source/system/Qt3DSBezierEval.h \ + ../Source/system/Qt3DSBoundingBox.h \ + ../Source/system/Qt3DSCircularArray.h \ + ../Source/system/Qt3DSColor.h \ + ../Source/system/Qt3DSConfig.h \ + ../Source/system/Qt3DSCubicRoots.h \ + ../Source/system/Qt3DSCubicRootsImpl.h \ + ../Source/system/Qt3DSDataLogger.h \ + ../Source/system/Qt3DSDataLogger.hpp \ + ../Source/system/Qt3DSDataLoggerEnums.h \ + ../Source/system/Qt3DSDataLoggerViewer.h \ + ../Source/system/Qt3DSDLLManager.h \ + ../Source/system/Qt3DSEGLTimer.h \ + ../Source/system/Qt3DSEndian.h \ + ../Source/system/Qt3DSEulerAngles.h \ + ../Source/system/Qt3DSFile.h \ + ../Source/system/Qt3DSFileStream.h \ + ../Source/system/Qt3DSFixedArray.h \ + ../Source/system/Qt3DSFNDTimer.h \ + ../Source/system/Qt3DSFunctionWrappers.h \ + ../Source/system/Qt3DSHash.h \ + ../Source/system/Qt3DSIFileStream.h \ + ../Source/system/Qt3DSIStream.h \ + ../Source/system/Qt3DSITimer.h \ + ../Source/system/Qt3DSMacros.h \ + ../Source/system/Qt3DSMatrix.h \ + ../Source/system/Qt3DSMemory.h \ + ../Source/system/Qt3DSMemoryFilter.h \ + ../Source/system/Qt3DSMemoryHeap.h \ + ../Source/system/Qt3DSMemoryManager.h \ + ../Source/system/Qt3DSMemoryPool.h \ + ../Source/system/Qt3DSMemoryProbe.h \ + ../Source/system/Qt3DSMemorySettings.h \ + ../Source/system/Qt3DSMemoryStatistics.h \ + ../Source/system/Qt3DSMemoryTracker.h \ + ../Source/system/Qt3DSPlatformSpecific.h \ + ../Source/system/Qt3DSTimer.h \ + ../Source/system/Qt3DSTypes.h \ + ../Source/system/Qt3DSVector3.h \ + ../Source/system/Qt3DSArray.inl \ + ../Source/system/Qt3DSCircularArray.inl \ + ../Source/system/Qt3DSFixedArray.inl \ + ../Source/stateapplication/Qt3DSStateApplication.h \ + ../Source/stateapplication/debugger/Qt3DSSceneGraphDebugger.h \ + ../Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerProtocol.h \ + ../Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerValue.h \ + ../Source/stateapplication/debugger/Qt3DSStateDebugger.h \ + ../Source/stateapplication/debugger/Qt3DSStateDebuggerProtocol.h \ + ../Source/stateapplication/debugger/Qt3DSStateDebuggerValues.h \ + ../Source/stateapplication/debugger/Qt3DSStateDebugStreams.h \ + ../Source/stateapplication/debugger/Qt3DSStateTest.h \ + ../Source/stateapplication/Qt3DSState.h \ + ../Source/stateapplication/Qt3DSStateContext.h \ + ../Source/stateapplication/Qt3DSStateExecutionContext.h \ + ../Source/stateapplication/Qt3DSStateExecutionTypes.h \ + ../Source/stateapplication/Qt3DSStateIdValue.h \ + ../Source/stateapplication/Qt3DSStateInterpreter.h \ + ../Source/stateapplication/Qt3DSStateScriptContext.h \ + ../Source/stateapplication/Qt3DSStateSharedImpl.h \ + ../Source/stateapplication/Qt3DSStateSignalConnection.h \ + ../Source/stateapplication/Qt3DSStateTypes.h \ + ../Source/stateapplication/Qt3DSStateVisualBindingContext.h \ + ../Source/stateapplication/Qt3DSStateVisualBindingContextCommands.h \ + ../Source/stateapplication/Qt3DSStateVisualBindingContextValues.h \ + ../Source/stateapplication/Qt3DSStateXMLIO.h \ + ../Source/uipparser/Qt3DSIPresentation.h \ + ../Source/uipparser/Qt3DSUIPParser.h \ + ../Source/uipparser/Qt3DSUIPParserActionHelper.h \ + ../Source/uipparser/Qt3DSUIPParserImpl.h \ + ../Source/uipparser/Qt3DSUIPParserObjectRefHelper.h \ + ../Source/runtime/Qt3DSCommandEventTypes.h \ + ../Source/runtime/Qt3DSEvent.h \ + ../Source/runtime/Qt3DSFrameworkTypes.h \ + ../Source/runtime/Qt3DSInputFrame.h \ + ../Source/runtime/Qt3DSIScene.h \ + ../Source/runtime/Qt3DSIScriptBridge.h \ + ../Source/runtime/Qt3DSPickFrame.h \ + ../Source/runtime/Qt3DSRuntimeFactory.h \ + ../Source/runtime/Qt3DSSceneManager.h \ + ../Source/engine/Qt3DSEGLInfo.h \ + ../Source/engine/Qt3DSEGLWindowSystem.h \ + ../Source/engine/Qt3DSPluginDLL.h \ + ../Source/engine/Qt3DSWindowSystem.h \ + ../Source/runtimerender/Qt3DSRenderContextCore.h \ + ../Source/runtimerender/Qt3DSRenderLightConstantProperties.h \ + ../Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.h win32 { SOURCES += \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsAtomic.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsFPU.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsMutex.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSync.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsThread.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsTime.cpp + ../Source/foundation/windows/Qt3DSWindowsAtomic.cpp \ + ../Source/foundation/windows/Qt3DSWindowsFPU.cpp \ + ../Source/foundation/windows/Qt3DSWindowsMutex.cpp \ + ../Source/foundation/windows/Qt3DSWindowsSemaphore.cpp \ + ../Source/foundation/windows/Qt3DSWindowsSync.cpp \ + ../Source/foundation/windows/Qt3DSWindowsThread.cpp \ + ../Source/foundation/windows/Qt3DSWindowsTime.cpp HEADERS += \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsAoS.h \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsFile.h \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInclude.h \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInlineAoS.h \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsIntrinsics.h \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsString.h \ - ../Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsTrigConstants.h + ../Source/foundation/windows/Qt3DSWindowsAoS.h \ + ../Source/foundation/windows/Qt3DSWindowsFile.h \ + ../Source/foundation/windows/Qt3DSWindowsInclude.h \ + ../Source/foundation/windows/Qt3DSWindowsInlineAoS.h \ + ../Source/foundation/windows/Qt3DSWindowsIntrinsics.h \ + ../Source/foundation/windows/Qt3DSWindowsString.h \ + ../Source/foundation/windows/Qt3DSWindowsTrigConstants.h } macos: SOURCES += \ - ../Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixAtomic.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixFPU.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixMutex.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSemaphore.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSync.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxThread.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixTime.cpp + ../Source/foundation/macos/Qt3DSUnixAtomic.cpp \ + ../Source/foundation/macos/Qt3DSUnixFPU.cpp \ + ../Source/foundation/macos/Qt3DSUnixMutex.cpp \ + ../Source/foundation/macos/Qt3DSUnixSemaphore.cpp \ + ../Source/foundation/macos/Qt3DSUnixSync.cpp \ + ../Source/foundation/linux/Qt3DSLinuxThread.cpp \ + ../Source/foundation/macos/Qt3DSUnixTime.cpp linux|integrity|qnx { SOURCES += \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxAtomic.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxFPU.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxMutex.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSync.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxThread.cpp \ - ../Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxTime.cpp + ../Source/foundation/linux/Qt3DSLinuxAtomic.cpp \ + ../Source/foundation/linux/Qt3DSLinuxFPU.cpp \ + ../Source/foundation/linux/Qt3DSLinuxMutex.cpp \ + ../Source/foundation/linux/Qt3DSLinuxSemaphore.cpp \ + ../Source/foundation/linux/Qt3DSLinuxSync.cpp \ + ../Source/foundation/linux/Qt3DSLinuxThread.cpp \ + ../Source/foundation/linux/Qt3DSLinuxTime.cpp HEADERS += \ - ../Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxAoS.h \ - ../Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxFile.h \ - ../Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxInlineAoS.h \ - ../Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxIntrinsics.h \ - ../Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxString.h \ - ../Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxTrigConstants.h + ../Source/foundation/linux/Qt3DSLinuxAoS.h \ + ../Source/foundation/linux/Qt3DSLinuxFile.h \ + ../Source/foundation/linux/Qt3DSLinuxInlineAoS.h \ + ../Source/foundation/linux/Qt3DSLinuxIntrinsics.h \ + ../Source/foundation/linux/Qt3DSLinuxString.h \ + ../Source/foundation/linux/Qt3DSLinuxTrigConstants.h } # Libs SOURCES += \ - ../Source/PlatformSpecific/$$PlatformSpecificDir/Qt3DSLibs/nv_math/nv_math.cpp \ - ../Source/PlatformSpecific/$$PlatformSpecificDir/Qt3DSLibs/nv_math/nv_matrix.cpp \ - ../Source/PlatformSpecific/$$PlatformSpecificDir/Qt3DSLibs/nv_math/nv_quat.cpp + ../Source/platformspecific/$$PlatformSpecificDir/libs/nv_math/nv_math.cpp \ + ../Source/platformspecific/$$PlatformSpecificDir/libs/nv_math/nv_matrix.cpp \ + ../Source/platformspecific/$$PlatformSpecificDir/libs/nv_math/nv_quat.cpp # RenderBase SOURCES += \ - ../Source/Qt3DSRender/Source/Qt3DSRenderAtomicCounterBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderAttribLayout.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderComputeShader.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderContext.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderDataBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderDepthStencilState.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderDrawIndirectBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderFragmentShader.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderFrameBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderGeometryShader.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderImageTexture.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderIndexBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderInputAssembler.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderOcclusionQuery.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderPathFontSpecification.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderPathFontText.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderPathRender.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderPathSpecification.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderProgramPipeline.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderQueryBase.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderRasterizerState.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderRenderBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderSampler.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderStorageBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderSync.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderTessellationShader.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderTexture2D.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderTexture2DArray.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderTextureBase.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderTextureCube.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderTimerQuery.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderVertexBuffer.cpp \ - ../Source/Qt3DSRender/Source/Qt3DSRenderVertexShader.cpp + ../Source/render/Qt3DSRenderAtomicCounterBuffer.cpp \ + ../Source/render/Qt3DSRenderAttribLayout.cpp \ + ../Source/render/Qt3DSRenderComputeShader.cpp \ + ../Source/render/Qt3DSRenderConstantBuffer.cpp \ + ../Source/render/Qt3DSRenderContext.cpp \ + ../Source/render/Qt3DSRenderDataBuffer.cpp \ + ../Source/render/Qt3DSRenderDepthStencilState.cpp \ + ../Source/render/Qt3DSRenderDrawIndirectBuffer.cpp \ + ../Source/render/Qt3DSRenderFragmentShader.cpp \ + ../Source/render/Qt3DSRenderFrameBuffer.cpp \ + ../Source/render/Qt3DSRenderGeometryShader.cpp \ + ../Source/render/Qt3DSRenderImageTexture.cpp \ + ../Source/render/Qt3DSRenderIndexBuffer.cpp \ + ../Source/render/Qt3DSRenderInputAssembler.cpp \ + ../Source/render/Qt3DSRenderOcclusionQuery.cpp \ + ../Source/render/Qt3DSRenderPathFontSpecification.cpp \ + ../Source/render/Qt3DSRenderPathFontText.cpp \ + ../Source/render/Qt3DSRenderPathRender.cpp \ + ../Source/render/Qt3DSRenderPathSpecification.cpp \ + ../Source/render/Qt3DSRenderProgramPipeline.cpp \ + ../Source/render/Qt3DSRenderQueryBase.cpp \ + ../Source/render/Qt3DSRenderRasterizerState.cpp \ + ../Source/render/Qt3DSRenderRenderBuffer.cpp \ + ../Source/render/Qt3DSRenderSampler.cpp \ + ../Source/render/Qt3DSRenderShaderProgram.cpp \ + ../Source/render/Qt3DSRenderStorageBuffer.cpp \ + ../Source/render/Qt3DSRenderSync.cpp \ + ../Source/render/Qt3DSRenderTessellationShader.cpp \ + ../Source/render/Qt3DSRenderTexture2D.cpp \ + ../Source/render/Qt3DSRenderTexture2DArray.cpp \ + ../Source/render/Qt3DSRenderTextureBase.cpp \ + ../Source/render/Qt3DSRenderTextureCube.cpp \ + ../Source/render/Qt3DSRenderTimerQuery.cpp \ + ../Source/render/Qt3DSRenderVertexBuffer.cpp \ + ../Source/render/Qt3DSRenderVertexShader.cpp HEADERS += \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderAtomicCounterBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderAttribLayout.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderComputeShader.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderConstantBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderDataBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderDepthStencilState.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderDrawable.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderDrawIndirectBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderFragmentShader.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderFrameBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderGeometryShader.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderImageTexture.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderIndexBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderInputAssembler.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderOcclusionQuery.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontSpecification.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontText.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderPathRender.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderPathSpecification.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderProgramPipeline.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderQueryBase.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderRasterizerState.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderRenderBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderSampler.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderShader.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderStorageBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderSync.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderTessellationShader.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2D.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2DArray.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderTextureBase.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderTextureCube.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderTimerQuery.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderVertexBuffer.h \ - ../Source/Qt3DSRender/Include/render/Qt3DSRenderVertexShader.h \ - ../Source/Qt3DSRender/Include/render/glg/Qt3DSGLImplObjects.h + ../Source/render/Qt3DSRenderAtomicCounterBuffer.h \ + ../Source/render/Qt3DSRenderAttribLayout.h \ + ../Source/render/Qt3DSRenderBaseTypes.h \ + ../Source/render/Qt3DSRenderComputeShader.h \ + ../Source/render/Qt3DSRenderConstantBuffer.h \ + ../Source/render/Qt3DSRenderContext.h \ + ../Source/render/Qt3DSRenderDataBuffer.h \ + ../Source/render/Qt3DSRenderDepthStencilState.h \ + ../Source/render/Qt3DSRenderDrawable.h \ + ../Source/render/Qt3DSRenderDrawIndirectBuffer.h \ + ../Source/render/Qt3DSRenderFragmentShader.h \ + ../Source/render/Qt3DSRenderFrameBuffer.h \ + ../Source/render/Qt3DSRenderGeometryShader.h \ + ../Source/render/Qt3DSRenderImageTexture.h \ + ../Source/render/Qt3DSRenderIndexBuffer.h \ + ../Source/render/Qt3DSRenderInputAssembler.h \ + ../Source/render/Qt3DSRenderOcclusionQuery.h \ + ../Source/render/Qt3DSRenderPathFontSpecification.h \ + ../Source/render/Qt3DSRenderPathFontText.h \ + ../Source/render/Qt3DSRenderPathRender.h \ + ../Source/render/Qt3DSRenderPathSpecification.h \ + ../Source/render/Qt3DSRenderProgramPipeline.h \ + ../Source/render/Qt3DSRenderQueryBase.h \ + ../Source/render/Qt3DSRenderRasterizerState.h \ + ../Source/render/Qt3DSRenderRenderBuffer.h \ + ../Source/render/Qt3DSRenderSampler.h \ + ../Source/render/Qt3DSRenderShader.h \ + ../Source/render/Qt3DSRenderShaderConstant.h \ + ../Source/render/Qt3DSRenderShaderProgram.h \ + ../Source/render/Qt3DSRenderStorageBuffer.h \ + ../Source/render/Qt3DSRenderSync.h \ + ../Source/render/Qt3DSRenderTessellationShader.h \ + ../Source/render/Qt3DSRenderTexture2D.h \ + ../Source/render/Qt3DSRenderTexture2DArray.h \ + ../Source/render/Qt3DSRenderTextureBase.h \ + ../Source/render/Qt3DSRenderTextureCube.h \ + ../Source/render/Qt3DSRenderTimerQuery.h \ + ../Source/render/Qt3DSRenderVertexBuffer.h \ + ../Source/render/Qt3DSRenderVertexShader.h \ + ../Source/render/glg/Qt3DSGLImplObjects.h # Render SOURCES += \ - ../Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp \ - ../Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp \ - ../Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp \ - ../Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp \ - ../Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp \ - ../Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp \ - ../Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp + ../Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp \ + ../Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp \ + ../Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp \ + ../Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp \ + ../Source/render/backends/gl/Qt3DSRenderContextGL.cpp \ + ../Source/render/backends/software/Qt3DSRenderBackendNULL.cpp \ + ../Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp HEADERS += \ - ../Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL4.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h \ - ../Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h \ - ../Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h + ../Source/render/backends/Qt3DSRenderBackend.h \ + ../Source/render/backends/gl/Qt3DSOpenGLPrefix.h \ + ../Source/render/backends/gl/Qt3DSOpenGLUtil.h \ + ../Source/render/backends/gl/Qt3DSOpenGLExtensions.h \ + ../Source/render/backends/gl/Qt3DSRenderBackendGL3.h \ + ../Source/render/backends/gl/Qt3DSRenderBackendGL4.h \ + ../Source/render/backends/gl/Qt3DSRenderBackendGLBase.h \ + ../Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h \ + ../Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h \ + ../Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h \ + ../Source/render/backends/software/Qt3DSRenderBackendNULL.h \ + ../Source/render/backends/gl/Q3DSRenderBackendGLES2.h # DataModel SOURCES += \ - ../Source/DataModel/Source/Qt3DSMetadata.cpp \ + ../Source/datamodel/Qt3DSMetadata.cpp \ ../../Authoring/QT3DSIMP/Qt3DSImportLib/Qt3DSImportMesh.cpp \ ../../Authoring/QT3DSIMP/Qt3DSImportLib/Qt3DSImportPath.cpp \ ../../Authoring/QT3DSDM/Systems/Qt3DSDMMetaData.cpp \ @@ -621,8 +621,8 @@ SOURCES += \ ../../Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.cpp HEADERS += \ - ../Source/DataModel/Include/Qt3DSMetadata.h \ - ../Source/DataModel/Include/DocumentResourceManagerScriptParser.h \ + ../Source/datamodel/Qt3DSMetadata.h \ + ../Source/datamodel/DocumentResourceManagerScriptParser.h \ ../../Authoring/QT3DSIMP/Qt3DSImportLib/Qt3DSImportMesh.h \ ../../Authoring/QT3DSIMP/Qt3DSImportLib/Qt3DSImportPath.h \ ../../Authoring/QT3DSDM/Systems/Qt3DSDMMetaData.h \ @@ -635,40 +635,40 @@ HEADERS += \ # Engine HEADERS += \ - ../Source/Engine/Include/EnginePrefix.h + ../Source/engine/EnginePrefix.h # Event SOURCES += \ - ../Source/Qt3DSEvent/Source/EventFactory.cpp \ - ../Source/Qt3DSEvent/Source/EventPoller.cpp \ - ../Source/Qt3DSEvent/Source/EventSystemC.cpp + ../Source/event/EventFactory.cpp \ + ../Source/event/EventPoller.cpp \ + ../Source/event/EventSystemC.cpp HEADERS += \ - ../Source/Qt3DSEvent/InternalInclude/EventPollingSystem.h \ - ../Source/Qt3DSEvent/Include/EventSystem.h \ - ../Source/Qt3DSEvent/Include/EventSystemC.h + ../Source/event/EventPollingSystem.h \ + ../Source/event/EventSystem.h \ + ../Source/event/EventSystemC.h # Render HEADERS += \ - ../Source/Qt3DSRuntimeRender/Include/ANDROID/DynamicLibLoader.h \ - ../Source/Qt3DSRuntimeRender/Include/LINUX/DynamicLibLoader.h \ - ../Source/Qt3DSRuntimeRender/Include/OSX/DynamicLibLoader.h \ - ../Source/Qt3DSRuntimeRender/Include/QNX/DynamicLibLoader.h \ - ../Source/Qt3DSRuntimeRender/Include/WINDOWS/DynamicLibLoader.h + ../Source/runtimerender/android/DynamicLibLoader.h \ + ../Source/runtimerender/linux/DynamicLibLoader.h \ + ../Source/runtimerender/macos/DynamicLibLoader.h \ + ../Source/runtimerender/qnx/DynamicLibLoader.h \ + ../Source/runtimerender/windows/DynamicLibLoader.h # Runtime HEADERS += \ - ../Source/Runtime/Include/RuntimePrefix.h \ - ../Source/Runtime/Include/q3dsqmlscript.h \ - ../Source/Runtime/Include/q3dsqmlbehavior.h + ../Source/runtime/RuntimePrefix.h \ + ../Source/runtime/q3dsqmlscript.h \ + ../Source/runtime/q3dsqmlbehavior.h SOURCES += \ - ../Source/Runtime/Source/q3dsqmlscript.cpp \ - ../Source/Runtime/Source/q3dsqmlbehavior.cpp + ../Source/runtime/q3dsqmlscript.cpp \ + ../Source/runtime/q3dsqmlbehavior.cpp # System HEADERS += \ - ../Source/System/Include/SystemPrefix.h + ../Source/system/SystemPrefix.h DISTFILES += \ - ../Source/Runtime/Include/Qt3DSAttributeHashes.txt + ../Source/runtime/Qt3DSAttributeHashes.txt diff --git a/src/Runtime/Source/DataModel/Include/DocumentResourceManagerCustomMaterialParser.h b/src/Runtime/Source/DataModel/Include/DocumentResourceManagerCustomMaterialParser.h deleted file mode 100644 index 47a8092d..00000000 --- a/src/Runtime/Source/DataModel/Include/DocumentResourceManagerCustomMaterialParser.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2002 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef DOCUMENTRESOURCEMANAGERCUSTOMMATERIALPARSERH -#define DOCUMENTRESOURCEMANAGERCUSTOMMATERIALPARSERH - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" -#include "Qt3DSDMXML.h" -#include "Qt3DSDMDataTypes.h" -#include "Qt3DSDMMetaData.h" -#include "Qt3DSDMWStrOpsImpl.h" -#include "foundation/StrConvertUTF.h" -#include -#include "Qt3DSRenderInputStreamFactory.h" - -namespace Q3DStudio { -struct CCustomMaterialParser -{ - - static bool NavigateToMetadata(std::shared_ptr inReader) - { - return inReader->MoveToFirstChild("MetaData"); - } - - static std::shared_ptr - ParseFile(std::shared_ptr inFactory, - std::shared_ptr inStringTable, const char8_t *inFileData, - qt3dsdm::CXmlErrorHandler &inErrorHandler, - qt3ds::render::IInputStreamFactory &inStreamFactory) - { - using namespace qt3ds; - using namespace qt3ds::foundation; - - NVScopedRefCounted theStream( - inStreamFactory.GetStreamForFile(inFileData)); - if (!theStream) { - QT3DS_ASSERT(0); - return std::shared_ptr(); - } - - qt3dsdm::SDOMElement *theElem( - qt3dsdm::CDOMSerializer::Read(*inFactory, *theStream, &inErrorHandler)); - - if (theElem == NULL) { - return std::shared_ptr(); - } else - return qt3dsdm::IDOMReader::CreateDOMReader(*theElem, inStringTable, inFactory); - } -}; -} - -#endif diff --git a/src/Runtime/Source/DataModel/Include/DocumentResourceManagerRenderPluginParser.h b/src/Runtime/Source/DataModel/Include/DocumentResourceManagerRenderPluginParser.h deleted file mode 100644 index e3eee1cf..00000000 --- a/src/Runtime/Source/DataModel/Include/DocumentResourceManagerRenderPluginParser.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2002 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef DOCUMENTRESOURCEMANAGERRENDERPLUGINPARSERH -#define DOCUMENTRESOURCEMANAGERRENDERPLUGINPARSERH - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" -#include "Qt3DSDMXML.h" -#include "Qt3DSDMDataTypes.h" -#include "Qt3DSDMMetaData.h" -#include "Qt3DSDMWStrOpsImpl.h" -#include "foundation/StrConvertUTF.h" -#include -#include "Qt3DSRenderInputStreamFactory.h" - -namespace Q3DStudio { -struct CRenderPluginParser -{ - - static bool NavigateToMetadata(std::shared_ptr inReader) - { - return inReader->MoveToFirstChild("metadata"); - } - - static std::shared_ptr - ParseFile(std::shared_ptr inFactory, - std::shared_ptr inStringTable, const char8_t *inFileData, - qt3dsdm::CXmlErrorHandler &inErrorHandler, - qt3ds::render::IInputStreamFactory &inStreamFactory) - { - using namespace qt3ds; - using namespace qt3ds::foundation; - - NVScopedRefCounted theStream( - inStreamFactory.GetStreamForFile(inFileData)); - if (!theStream) { - QT3DS_ASSERT(0); - return std::shared_ptr(); - } - - qt3dsdm::SDOMElement *theElem( - qt3dsdm::CDOMSerializer::Read(*inFactory, *theStream, &inErrorHandler)); - - if (theElem == NULL) { - return std::shared_ptr(); - } else - return qt3dsdm::IDOMReader::CreateDOMReader(*theElem, inStringTable, inFactory); - } -}; -} - -#endif diff --git a/src/Runtime/Source/DataModel/Include/DocumentResourceManagerScriptParser.h b/src/Runtime/Source/DataModel/Include/DocumentResourceManagerScriptParser.h deleted file mode 100644 index 4c2ce437..00000000 --- a/src/Runtime/Source/DataModel/Include/DocumentResourceManagerScriptParser.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DOCUMENTRESOURCEMANAGERSCRIPTPARSER_H -#define DOCUMENTRESOURCEMANAGERSCRIPTPARSER_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" -#include "Qt3DSDMXML.h" -#include "Qt3DSDMDataTypes.h" -#include "Qt3DSDMMetaData.h" -#include "Qt3DSRenderInputStreamFactory.h" - -namespace Q3DStudio { -namespace ScriptParser { - - using namespace qt3dsdm; - using namespace Q3DStudio; - - struct StringInStream : qt3ds::foundation::IInStream - { - const QString &m_String; - QT3DSU32 m_Offset; - - StringInStream(const QString &str) - : m_String(str) - , m_Offset(0) - { - } - - QT3DSU32 Read(NVDataRef data) override - { - std::string str = m_String.toUtf8().constData(); - const char *theStart((const char *)str.c_str()); - const char *theEnd(theStart + str.size()); - - QT3DSU32 amountLeft = QT3DSU32(theEnd - theStart) - m_Offset; - QT3DSU32 amountToRead = qt3ds::NVMin(data.size(), amountLeft); - qt3ds::intrinsics::memCopy(data.begin(), theStart + m_Offset, amountToRead); - m_Offset += amountToRead; - return amountToRead; - } - }; - - struct SScriptParser - { - static std::shared_ptr - ParseScriptFile(std::shared_ptr factory, - std::shared_ptr stringTable, - const QString &fullPath, CXmlErrorHandler &errorHandler, - qt3ds::render::IInputStreamFactory &streamFactory) - { - QVector readBuf; - { - using namespace qt3ds; - using namespace qt3ds::foundation; - eastl::string strConvert; - NVScopedRefCounted stream( - streamFactory.GetStreamForFile(fullPath)); - if (!stream) { - QT3DS_ASSERT(0); - return std::shared_ptr(); - } - - QT3DSU32 readLen = 0; - do { - uint32_t offset = readBuf.size(); - readBuf.resize(offset + 4096); - readLen = stream->Read(NVDataRef(&readBuf[0] + offset, 4096)); - readBuf.resize(offset + readLen); - } while (readLen == 4096); - } - - QByteArray byteArray; - for (auto &&c : qAsConst(readBuf)) - byteArray.append(c); - - QString code = QString::fromUtf8(byteArray); - - bool skipXml = false; - auto start = code.indexOf("/*[["); - if (start == -1) - skipXml = true; - - QString tagged("\n"); - if (!skipXml) { - start += 4; - auto end = code.indexOf("]]*/", start); - if (end == -1) - return std::shared_ptr(); - - QString xml = code.mid(start, end - start).trimmed(); - - tagged.append(xml); - } - tagged.append("\n"); - tagged.replace("\r\n", "\n"); - - StringInStream xmlStream(tagged); - - SDOMElement *element(CDOMSerializer::Read(*factory, xmlStream, &errorHandler)); - if (element == NULL) - return std::shared_ptr(); - - return IDOMReader::CreateDOMReader(*element, stringTable, factory); - } - }; -} -} - -#endif // DOCUMENTRESOURCEMANAGERSCRIPTPARSER_H diff --git a/src/Runtime/Source/DataModel/Include/Qt3DSMetadata.h b/src/Runtime/Source/DataModel/Include/Qt3DSMetadata.h deleted file mode 100644 index a90d4fd6..00000000 --- a/src/Runtime/Source/DataModel/Include/Qt3DSMetadata.h +++ /dev/null @@ -1,380 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSVec3.h" -#include -#include -#include "foundation/StringTable.h" -#include - -namespace qt3ds { -namespace foundation { -} -} - -namespace qt3dsdm { -class IStringTable; -struct SMetaDataEffect; -struct SMetaDataCustomMaterial; -} - -namespace qt3ds { -namespace render { - class IInputStreamFactory; -} -} - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -using namespace qt3ds::foundation; - -//============================================================================== -// Redifinition of qt3dsdm::DataModelDataType::Value -//============================================================================== -enum ERuntimeDataModelDataType { - ERuntimeDataModelDataTypeNone, - ERuntimeDataModelDataTypeFloat, - ERuntimeDataModelDataTypeFloat2, - ERuntimeDataModelDataTypeFloat3, - ERuntimeDataModelDataTypeLong, - ERuntimeDataModelDataTypeString, - ERuntimeDataModelDataTypeBool, - ERuntimeDataModelDataTypeLong4, - ERuntimeDataModelDataTypeStringRef, - ERuntimeDataModelDataTypeObjectRef, - ERuntimeDataModelDataTypeStringOrInt, -}; - -//============================================================================== -// Redifinition of qt3dsdm::AdditionalMetaDataType -//============================================================================== -enum ERuntimeAdditionalMetaDataType { - ERuntimeAdditionalMetaDataTypeNone, - ERuntimeAdditionalMetaDataTypeStringList, - ERuntimeAdditionalMetaDataTypeRange, - ERuntimeAdditionalMetaDataTypeImage, - ERuntimeAdditionalMetaDataTypeColor, - ERuntimeAdditionalMetaDataTypeRotation, - ERuntimeAdditionalMetaDataTypeFont, - ERuntimeAdditionalMetaDataTypeFontSize, - ERuntimeAdditionalMetaDataTypeMultiLine, - ERuntimeAdditionalMetaDataTypeObjectRef, - ERuntimeAdditionalMetaDataTypeMesh, - ERuntimeAdditionalMetaDataTypeImport, - ERuntimeAdditionalMetaDataTypeTexture, - ERuntimeAdditionalMetaDataTypeRenderable, - ERuntimeAdditionalMetaDataTypePathBuffer, - ERuntimeAdditionalMetaDataTypeShadowMapResolution, - ERuntimeAdditionalMetaDataTypeString, -}; - -typedef eastl::basic_string TRuntimeMetaDataStrType; -typedef qt3ds::foundation::CRegisteredString TStrTableStr; - -struct SAttOrArg -{ - TRuntimeMetaDataStrType m_Name; - TRuntimeMetaDataStrType m_FormalName; - ERuntimeDataModelDataType m_DataType; - ERuntimeAdditionalMetaDataType m_MetaType; - eastl::vector m_MetaDataList; - eastl::pair m_MetaDataRange; -}; - -typedef eastl::vector TAttOrArgList; -struct SHandler -{ - TRuntimeMetaDataStrType m_Name; - TRuntimeMetaDataStrType m_FormalName; - TAttOrArgList m_Arguments; -}; - -typedef eastl::vector THandlerList; - -struct SVisualEvent -{ - TRuntimeMetaDataStrType m_Name; - TRuntimeMetaDataStrType m_FormalName; -}; - -typedef eastl::vector TVisualEventList; - -struct SElementInfo -{ - TRuntimeMetaDataStrType m_ClassName; - bool m_IsComponent; - TAttOrArgList m_Attributes; -}; - -//============================================================================== -/** - * @class IRuntimeMetaData - * @brief Declare interfaces for querying meta data values - */ -class QT3DS_AUTOTEST_EXPORT IRuntimeMetaData : public NVReleasable -{ - -public: - static const char *GetMetaDataDirectory() - { - return ":/res/DataModelMetadata/en-us/MetaData.xml"; - } - //============================================================================== - /** - * Check if a property for the specified type or id exists - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value type - */ - virtual bool IsPropertyExist(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value type - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value type - */ - virtual ERuntimeDataModelDataType GetPropertyType(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get additional metadata type - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property meta data type - */ - virtual ERuntimeAdditionalMetaDataType - GetAdditionalType(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value as float - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option GetPropertyValueFloat(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value as QT3DSVec3 - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option GetPropertyValueVector2(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value as QT3DSVec3 - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option GetPropertyValueVector3(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value as long - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option GetPropertyValueLong(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value as string - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option - GetPropertyValueString(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get object ref property value as string - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option - GetPropertyValueObjectRef(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get property value as bool - * @param inType default object type - * @param inProperty the property to query - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param return property value - */ - virtual Option GetPropertyValueBool(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId = TStrTableStr()) = 0; - - //============================================================================== - /** - * Get references - * @param inType default object type - * @param outReferences References of the object - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - */ - virtual void GetReferences(const char *inType, - eastl::vector &outReferences, - const char *inId = NULL) = 0; - - //============================================================================== - /** - * Check if the property is custom or built in (canonical) - * @param inId object id - * @param inProperty the property to query - */ - virtual bool IsCustomProperty(const char *inId, const char *inProperty) = 0; - - //============================================================================== - /** - * Check if the handle is custom or built in (canonical) - * @param inId object id - * @param inHandlerName the handler name - */ - virtual bool IsCustomHandler(const char *inId, const char *inHandlerName) = 0; - - virtual THandlerList GetCustomHandlers(const char *inId) = 0; - - virtual TVisualEventList GetVisualEvents(const char *inId) = 0; - - virtual SElementInfo LoadElement(const char *clsName, const char *clsRef, const char *inId) = 0; - - virtual TAttOrArgList GetSlideAttributes() = 0; - - //============================================================================== - /** - * Get the data type and additional type of the custom handler - * @param inId object id - * @param inHandlerName the handler name - * @param inArgumentName the handler argument name - * @param outType the type - * @param outAdditionalType the additional type - */ - virtual void GetHandlerArgumentType(const char *inId, const char *inHandlerName, - const char *inArgumentName, - ERuntimeDataModelDataType &outType, - ERuntimeAdditionalMetaDataType &outAdditionalType) = 0; - - //============================================================================== - /** - * Get properties of the object with the given id, with the option of searching the parent or - *only specific to this object. - * @param inType default object type - * @param inId object id. if this value is not trivial, the query is based on inId - *instead of inType - * @param outProperties the list of property names - * @param inSearchParent if true, get the properties defined on the object or its derivation - *parents - * else, get only the properties defined on the object, not properties - *derived from the parent. - */ - virtual void GetInstanceProperties(const char *inType, const char *inId, - eastl::vector &outProperties, - bool inSearchParent) = 0; - - virtual bool LoadScriptFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) = 0; - - virtual bool LoadEffectXMLFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) = 0; - - virtual bool LoadMaterialXMLFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) = 0; - - virtual bool LoadPluginXMLFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) = 0; - - virtual Option GetEffectMetaDataBySourcePath(const char *inName) = 0; - - virtual Option - GetMaterialMetaDataBySourcePath(const char *inSourcePath) = 0; - - virtual std::shared_ptr GetStringTable() = 0; - - virtual TStrTableStr Register(const char *inStr) = 0; - - // Clear data that affects project loading (mainly id->instance map) - virtual void ClearPerProjectData() = 0; - -public: - //============================================================================== - /** - * Creation function creates an object implements the IRuntimeMetaData interface - * This takes an input stream factory because on android the metadata is installed - * in the APK file, so we don't have exact access to it on the filesystem. - */ - static IRuntimeMetaData &Create(qt3ds::render::IInputStreamFactory &inInputStreamFactory); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/DataModel/Source/Qt3DSMetadata.cpp b/src/Runtime/Source/DataModel/Source/Qt3DSMetadata.cpp deleted file mode 100644 index 99d7cb8e..00000000 --- a/src/Runtime/Source/DataModel/Source/Qt3DSMetadata.cpp +++ /dev/null @@ -1,985 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSDMPrefix.h" -#include "Qt3DSMetadata.h" -#include "SimpleDataCore.h" -#include "Qt3DSDMXML.h" -#include "foundation/IOStreams.h" -#include "Qt3DSEulerAngles.h" -#include "Qt3DSDMWindowsCompatibility.h" -#include "Qt3DSDMComposerTypeDefinitions.h" -#include "DocumentResourceManagerScriptParser.h" -#include "foundation/StrConvertUTF.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "foundation/FileTools.h" -#include "foundation/TrackingAllocator.h" -#include "EASTL/hash_map.h" -#include "DocumentResourceManagerRenderPluginParser.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/StringTable.h" - -using qt3ds::render::IInputStreamFactory; -using qt3ds::render::IRefCountedInputStream; - -using namespace qt3dsdm; -using namespace Q3DStudio; - -namespace { - - -struct SImportXmlErrorHandler : public CXmlErrorHandler -{ - void OnXmlError(const QString &errorName, int line, int) override - { - qCCritical(INTERNAL_ERROR) << "XML error:" - << errorName << "on line" << line; - } -}; - -struct SRuntimeMetaDataPropertyInfo -{ - ERuntimeDataModelDataType m_DataType; - ERuntimeAdditionalMetaDataType m_AdditionalType; - Option m_Value; - bool m_Exist; - SRuntimeMetaDataPropertyInfo(ERuntimeDataModelDataType inDataType, - ERuntimeAdditionalMetaDataType inAdditionalType, - const Option &inValue, bool inExist) - : m_DataType(inDataType) - , m_AdditionalType(inAdditionalType) - , m_Value(inValue) - , m_Exist(inExist) - { - } - SRuntimeMetaDataPropertyInfo() - : m_DataType(ERuntimeDataModelDataTypeNone) - , m_AdditionalType(ERuntimeAdditionalMetaDataTypeNone) - , m_Exist(false) - { - } -}; - -struct SPropertyKey -{ - const char8_t *m_TypeOrId; - const char8_t *m_PropertyName; - - // The character pointers are expected to have come from the string table - // thus we can safely use their exact pointer addresses for the hash code. - SPropertyKey(const char8_t *typeOrId, const char8_t *inPname) - : m_TypeOrId(typeOrId) - , m_PropertyName(inPname) - { - } - bool operator==(const SPropertyKey &inOther) const - { - // equality comparison safe since strings are assumed to come from string table. - return m_TypeOrId == inOther.m_TypeOrId && m_PropertyName == inOther.m_PropertyName; - } -}; -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SPropertyKey &inKey) const - { - return reinterpret_cast(inKey.m_TypeOrId) - ^ reinterpret_cast(inKey.m_PropertyName); - } -}; -} - -namespace { - -//=========================================================================== -/** - * @class SRuntimeMetaDataImpl - * @brief implements the IRumtimeMetaData interface class - */ -struct SRuntimeMetaDataImpl : public IRuntimeMetaData -{ - -private: - typedef std::map TIdToHandleMap; - typedef eastl::hash_map TPropertyLookupHash; - - //============================================================================== - // Fields - //============================================================================== - std::shared_ptr m_StrTable; - std::shared_ptr m_DataCore; - std::shared_ptr m_NewMetaData; - std::shared_ptr m_Objects; - std::vector m_TempReferences; - - TIdToHandleMap m_IdToHandleMap; - // We cache properties by id or by instance so that the same query for the same value - // will return an answer instantly instead of calling GetAggregateInstancePropertyByName which - // is really - // expensive. - TPropertyLookupHash m_PropertyLookupHash; - IInputStreamFactory &m_InputStreamFactory; - - // Helper to convert char to wchar_t - eastl::basic_string m_Buf[4]; - -public: - static void SimpleDataModelLogger(const char *inMessage) - { - qCInfo(TRACE_INFO) << SRuntimeMetaDataImpl::SimpleDataModelLogger - << inMessage; - } - //============================================================================== - /** - * Constructor - */ - SRuntimeMetaDataImpl(IInputStreamFactory &inFactory) - : m_InputStreamFactory(inFactory) - { - // Use this to enable some simple uicdm debug logging. Beware of a *lot* of log output. - // g_DataModelDebugLogger = SimpleDataModelLogger; - try { - // need to pause here to hook up the debugger - m_StrTable = qt3dsdm::IStringTable::CreateStringTable(); - m_DataCore = std::make_shared(m_StrTable); - m_NewMetaData = IMetaData::CreateNewMetaData(m_DataCore); - - m_Objects = std::make_shared(std::ref(*m_DataCore), - std::ref(*m_NewMetaData)); - } catch (qt3dsdm::Qt3DSDMError &error) { - qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl Qt3DSDMError: " - << m_StrTable->GetNarrowStr(error.m_Message); - } catch (std::runtime_error &exc) { - if (exc.what()) { - qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::runtime_error: " - << exc.what(); - } else { - qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::runtime_error"; - } - } catch (std::exception &exc) { - if (exc.what()) { - qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::exception: " - << exc.what(); - } else { - qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::exception"; - } - } - } - - void Load() - { - // Create the base types. - std::shared_ptr theFactory(IDOMFactory::CreateDOMFactory(m_StrTable)); - const char8_t *theMetaDataPath = GetMetaDataDirectory(); - NVScopedRefCounted theInStream( - m_InputStreamFactory.GetStreamForFile(theMetaDataPath)); - SDOMElement *topElement = NULL; - if (theInStream) - topElement = CDOMSerializer::Read(*theFactory, *theInStream); - if (topElement) { - shared_ptr theReader = - IDOMReader::CreateDOMReader(*topElement, m_StrTable, theFactory); - m_NewMetaData->Load(*theReader); - - } else { - qCCritical(INVALID_OPERATION) << "Metadata loading failed", "Failed to find meta data file"; - // Q3DStudio_ASSERT requires static linkage to UICSystem, which is only used - // by UICEngine and UICRuntime - // QT3DS_ASSERT requires the qt3ds foundation libraries which are used by all products. - QT3DS_ASSERT(false); - return; - } - } - - // Helper to convert wchar_t to eastl::string - static inline void ConvertWide(const wchar_t *inType, eastl::string &outStr) - { - if (inType && *inType) - qt3ds::foundation::ConvertUTF( - reinterpret_cast(inType), - 0, outStr); - else - outStr.clear(); - } - - // Helper to convert char to wchar_t - const wchar_t *ConvertChar(const char *inName, int inBufferIndex) - { - if (inName && *inName) { - qt3ds::foundation::ConvertUTF(inName, 0, m_Buf[inBufferIndex]); - return reinterpret_cast(m_Buf[inBufferIndex].c_str()); - } - return NULL; - } - inline const wchar_t *Convert0(const char *inName) { return ConvertChar(inName, 0); } - inline const wchar_t *Convert1(const char *inName) { return ConvertChar(inName, 1); } - inline const wchar_t *Convert2(const char *inName) { return ConvertChar(inName, 2); } - inline const wchar_t *Convert3(const char *inName) { return ConvertChar(inName, 3); } - - inline Qt3DSDMInstanceHandle GetInstanceForType(const wchar_t *inType) - { - return m_Objects->GetInstanceForType(ComposerObjectTypes::Convert(inType)); - } - - Qt3DSDMInstanceHandle GetInstanceById(const wchar_t *inId) - { - if (IsTrivial(inId)) - return 0; - if (inId[0] == '#') - ++inId; - - TIdToHandleMap::iterator find = m_IdToHandleMap.find(inId); - if (find != m_IdToHandleMap.end()) - return find->second; - return 0; - } - - virtual bool IsPropertyExist(const wchar_t *inType, const wchar_t *inProperty, - const wchar_t *inId) - { - Qt3DSDMInstanceHandle theInstance = - IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); - if (theInstance.Valid()) { - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); - - return theProperty.Valid(); - } - return false; - } - - ERuntimeDataModelDataType Convert(DataModelDataType::Value inType) - { - switch (inType) { - case DataModelDataType::None: - return ERuntimeDataModelDataTypeNone; - case DataModelDataType::Float: - return ERuntimeDataModelDataTypeFloat; - case DataModelDataType::Float2: - return ERuntimeDataModelDataTypeFloat2; - case DataModelDataType::Float3: - return ERuntimeDataModelDataTypeFloat3; - case DataModelDataType::Long: - return ERuntimeDataModelDataTypeLong; - case DataModelDataType::String: - return ERuntimeDataModelDataTypeString; - case DataModelDataType::Bool: - return ERuntimeDataModelDataTypeBool; - case DataModelDataType::Long4: - return ERuntimeDataModelDataTypeLong4; - case DataModelDataType::StringRef: - return ERuntimeDataModelDataTypeStringRef; - case DataModelDataType::ObjectRef: - return ERuntimeDataModelDataTypeObjectRef; - case DataModelDataType::StringOrInt: - return ERuntimeDataModelDataTypeStringOrInt; - default: - QT3DS_ASSERT(false); - return ERuntimeDataModelDataTypeNone; - } - } - - virtual ERuntimeDataModelDataType - GetPropertyType(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId) - { - Qt3DSDMInstanceHandle theInstance = - IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); - return Convert(m_DataCore->GetProperty(theProperty).m_Type); - } - - ERuntimeAdditionalMetaDataType Convert(AdditionalMetaDataType::Value inType) - { - switch (inType) { - case AdditionalMetaDataType::None: - return ERuntimeAdditionalMetaDataTypeNone; - case AdditionalMetaDataType::StringList: - return ERuntimeAdditionalMetaDataTypeStringList; - case AdditionalMetaDataType::Range: - return ERuntimeAdditionalMetaDataTypeRange; - case AdditionalMetaDataType::Image: - return ERuntimeAdditionalMetaDataTypeImage; - case AdditionalMetaDataType::Color: - return ERuntimeAdditionalMetaDataTypeColor; - case AdditionalMetaDataType::Rotation: - return ERuntimeAdditionalMetaDataTypeRotation; - case AdditionalMetaDataType::Font: - return ERuntimeAdditionalMetaDataTypeFont; - case AdditionalMetaDataType::FontSize: - return ERuntimeAdditionalMetaDataTypeFontSize; - case AdditionalMetaDataType::MultiLine: - return ERuntimeAdditionalMetaDataTypeMultiLine; - case AdditionalMetaDataType::ObjectRef: - return ERuntimeAdditionalMetaDataTypeObjectRef; - case AdditionalMetaDataType::Mesh: - return ERuntimeAdditionalMetaDataTypeMesh; - case AdditionalMetaDataType::Import: - return ERuntimeAdditionalMetaDataTypeImport; - case AdditionalMetaDataType::Texture: - return ERuntimeAdditionalMetaDataTypeTexture; - case AdditionalMetaDataType::Renderable: - return ERuntimeAdditionalMetaDataTypeRenderable; - case AdditionalMetaDataType::PathBuffer: - return ERuntimeAdditionalMetaDataTypePathBuffer; - case AdditionalMetaDataType::ShadowMapResolution: - return ERuntimeAdditionalMetaDataTypeShadowMapResolution; - case AdditionalMetaDataType::String: - return ERuntimeAdditionalMetaDataTypeString; - default: - QT3DS_ASSERT(false); - return ERuntimeAdditionalMetaDataTypeNone; - } - } - - virtual ERuntimeAdditionalMetaDataType - GetAdditionalType(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId) - { - Qt3DSDMInstanceHandle theInstance = - IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); - return Convert(m_NewMetaData->GetAdditionalMetaDataType(theInstance, theProperty)); - } - - bool GetPropertyValue(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId, - SValue &outValue) - { - Qt3DSDMInstanceHandle theInstance = - IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); - if (theInstance.Valid()) { - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); - return m_DataCore->GetInstancePropertyValue(theInstance, theProperty, outValue); - } else { - eastl::string typeStr; - eastl::string propertyStr; - eastl::string idStr; - ConvertWide(inType, typeStr); - ConvertWide(inProperty, propertyStr); - ConvertWide(inId, idStr); - qCCritical(INVALID_OPERATION) << "GetPropertyValueString: " - << typeStr.c_str() << " " - << propertyStr.c_str() << " " - << idStr.c_str(); - QT3DS_ASSERT(false); - } - return false; - } - - SRuntimeMetaDataPropertyInfo &FindProperty(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) - { - TStrTableStr theTypeOrId = inId.IsValid() ? inId : inType; - SPropertyKey theKey(theTypeOrId, inProperty); - eastl::pair theLookup = - m_PropertyLookupHash.insert(eastl::make_pair(theKey, SRuntimeMetaDataPropertyInfo())); - if (theLookup.second) { - const wchar_t *theType(Convert0(inType)); - const wchar_t *theProperty(Convert1(inProperty)); - const wchar_t *theId(Convert2(inId)); - if (IsPropertyExist(theType, theProperty, theId)) { - ERuntimeDataModelDataType theDataType(GetPropertyType(theType, theProperty, theId)); - ERuntimeAdditionalMetaDataType theAdditionalType( - GetAdditionalType(theType, theProperty, theId)); - Option theValue; - SValue theValueData; - if (GetPropertyValue(theType, theProperty, theId, theValueData)) - theValue = theValueData.toOldSkool(); - theLookup.first->second = - SRuntimeMetaDataPropertyInfo(theDataType, theAdditionalType, theValue, true); - } - } - return theLookup.first->second; - } - - bool IsPropertyExist(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override - { - return FindProperty(inType, inProperty, inId).m_Exist; - } - - ERuntimeDataModelDataType GetPropertyType(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) override - { - return FindProperty(inType, inProperty, inId).m_DataType; - } - - virtual ERuntimeAdditionalMetaDataType - GetAdditionalType(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override - { - return FindProperty(inType, inProperty, inId).m_AdditionalType; - } - - Option GetPropertyValueFloat(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) - return qt3dsdm::get(*theInfo.m_Value); - return Empty(); - } - - Option GetPropertyValueVector2(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) { - SFloat2 theFloat2 = qt3dsdm::get(*theInfo.m_Value); - return qt3ds::QT3DSVec3(theFloat2[0], theFloat2[1], 0); - } - return Empty(); - } - - Option GetPropertyValueVector3(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) { - SFloat3 theFloat3 = qt3dsdm::get(*theInfo.m_Value); - return qt3ds::QT3DSVec3(theFloat3[0], theFloat3[1], theFloat3[2]); - } - return Empty(); - } - - virtual Option GetPropertyValueLong(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) - return qt3dsdm::get(*theInfo.m_Value); - return Empty(); - } - - virtual Option - GetPropertyValueString(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) { - TDataStrPtr theStr = qt3dsdm::get(*theInfo.m_Value); - TRuntimeMetaDataStrType retval; - qt3ds::foundation::ConvertUTF( - reinterpret_cast( - theStr->GetData()), - 0, retval); - return retval; - } - return Empty(); - } - - virtual Option - GetPropertyValueObjectRef(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) { - SObjectRefType theObjectRef = ConvertToObjectRef(*theInfo.m_Value); - if (theObjectRef.GetReferenceType() == ObjectReferenceType::Relative) { - TDataStrPtr theStr = qt3dsdm::get(theObjectRef.m_Value); - TRuntimeMetaDataStrType retval; - qt3ds::foundation::ConvertUTF( - reinterpret_cast( - theStr->GetData()), - 0, retval); - return retval; - } else // we don't know how to solve absolute reference type - { - // QT3DS_ASSERT( false ); - return TRuntimeMetaDataStrType(""); - } - } - return Empty(); - } - - Option GetPropertyValueBool(TStrTableStr inType, TStrTableStr inProperty, - TStrTableStr inId) override - { - SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); - if (theInfo.m_Value.hasValue()) - return qt3dsdm::get(*theInfo.m_Value); - return Empty(); - } - - virtual void GetReferences(const wchar_t *inType, - eastl::vector &outReferences, - const wchar_t *inId) - { - Qt3DSDMInstanceHandle theInstance = - IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); - - if (theInstance.Valid()) { - m_TempReferences.clear(); - m_NewMetaData->GetReferences(theInstance, m_TempReferences); - outReferences.resize((uint32_t)m_TempReferences.size()); - for (uint32_t idx = 0, end = (uint32_t)m_TempReferences.size(); idx < end; ++idx) { - qt3ds::foundation::ConvertUTF(m_TempReferences[idx].c_str(), - m_TempReferences[idx].size(), outReferences[idx]); - } - } - } - - void GetReferences(const char *inType, - eastl::vector &outReferences, - const char *inId) override - { - GetReferences(Convert0(inType), outReferences, Convert2(inId)); - } - - virtual bool IsCustomProperty(const wchar_t *inId, const wchar_t *inProperty) - { - Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId); - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); - return m_NewMetaData->IsCustomProperty(theInstance, theProperty); - } - - bool IsCustomProperty(const char *inId, const char *inProperty) override - { - return IsCustomProperty(Convert2(inId), Convert1(inProperty)); - } - - virtual bool IsCustomHandler(const wchar_t *inId, const wchar_t *inHandlerName) - { - Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId); - Qt3DSDMHandlerHandle theHandle = - m_NewMetaData->FindHandlerByName(theInstance, inHandlerName); - return m_NewMetaData->IsCustomHandler(theHandle); - } - - inline void SetDataType(SAttOrArg &arg, const SMetaPropertyBase &argInfo) - { - arg.m_DataType = Convert(argInfo.GetDataType()); - arg.m_MetaType = Convert(argInfo.GetAdditionalType()); - qt3ds::foundation::ConvertUTF(argInfo.m_Name.c_str(), argInfo.m_Name.size(), arg.m_Name); - qt3ds::foundation::ConvertUTF(argInfo.m_FormalName.c_str(), argInfo.m_FormalName.size(), - arg.m_FormalName); - switch (argInfo.GetAdditionalType()) { - case qt3dsdm::AdditionalMetaDataType::StringList: { - const eastl::vector &theData = - argInfo.m_MetaDataData.getData>(); - arg.m_MetaDataList.resize(theData.size()); - for (uint32_t metaIdx = 0, metaEnd = theData.size(); metaIdx < metaEnd; ++metaIdx) - qt3ds::foundation::ConvertUTF(theData[metaIdx].c_str(), theData[metaIdx].size(), - arg.m_MetaDataList[metaIdx]); - } break; - case qt3dsdm::AdditionalMetaDataType::Range: { - const SMetaDataRange &range = argInfo.m_MetaDataData.getData(); - arg.m_MetaDataRange = eastl::make_pair(range.m_Min, range.m_Max); - } break; - default: - break; - } - } - - THandlerList GetCustomHandlers(const char *inId) override - { - THandlerList retval; - Qt3DSDMInstanceHandle theInstance = GetInstanceById(Convert0(inId)); - THandlerHandleList handlerList; - m_NewMetaData->GetHandlers(theInstance, handlerList); - retval.reserve((uint32_t)handlerList.size()); - for (size_t idx = 0, end = handlerList.size(); idx < end; ++idx) { - if (m_NewMetaData->IsCustomHandler(handlerList[idx])) { - SHandlerInfo theInfo(m_NewMetaData->GetHandlerInfo(handlerList[idx])); - retval.push_back(SHandler()); - SHandler &handler(retval.back()); - qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), theInfo.m_Name.size(), - handler.m_Name); - qt3ds::foundation::ConvertUTF(theInfo.m_FormalName.c_str(), - theInfo.m_FormalName.size(), handler.m_FormalName); - vector theArgInfo; - m_NewMetaData->GetHandlerArguments(handlerList[idx], theArgInfo); - handler.m_Arguments.resize((uint32_t)theArgInfo.size()); - for (uint32_t argIdx = 0, argEnd = (uint32_t)theArgInfo.size(); argIdx < argEnd; - ++argIdx) { - const SMetaDataHandlerArgumentInfo &argInfo(theArgInfo[argIdx]); - SAttOrArg &arg = handler.m_Arguments[argIdx]; - SetDataType(arg, argInfo); - } - } - } - return retval; - } - - TVisualEventList GetVisualEvents(const char *inId) override - { - TVisualEventList theRetval; - Qt3DSDMInstanceHandle theInstance = GetInstanceById(Convert0(inId)); - TEventHandleList theEventList; - m_NewMetaData->GetEvents(theInstance, theEventList); - theRetval.reserve((uint32_t)theEventList.size()); - for (uint32_t idx = 0, end = (uint32_t)theEventList.size(); idx < end; ++idx) { - SEventInfo theInfo(m_NewMetaData->GetEventInfo(theEventList[idx])); - theRetval.push_back(SVisualEvent()); - SVisualEvent &theEvent(theRetval.back()); - qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), theInfo.m_Name.size(), - theEvent.m_Name); - qt3ds::foundation::ConvertUTF(theInfo.m_FormalName.c_str(), theInfo.m_FormalName.size(), - theEvent.m_FormalName); - } - return theRetval; - } - - void MetaPropertiesToAttList(vector &theProperties, - TAttOrArgList &outAtts) - { - outAtts.reserve((uint32_t)theProperties.size()); - for (uint32_t idx = 0, end = (uint32_t)theProperties.size(); idx < end; ++idx) { - SMetaDataPropertyInfo thePropInfo = - m_NewMetaData->GetMetaDataPropertyInfo(theProperties[idx]); - outAtts.push_back(SAttOrArg()); - SAttOrArg &arg(outAtts.back()); - arg.m_DataType = Convert(thePropInfo.GetDataType()); - arg.m_MetaType = Convert(thePropInfo.GetAdditionalType()); - qt3ds::foundation::ConvertUTF(thePropInfo.m_Name.c_str(), thePropInfo.m_Name.size(), - arg.m_Name); - qt3ds::foundation::ConvertUTF(thePropInfo.m_FormalName.c_str(), - thePropInfo.m_FormalName.size(), arg.m_FormalName); - SetDataType(arg, thePropInfo); - } - } - - SElementInfo LoadElement(const char *clsName, const char *clsRef, const char *inId) override - { - SElementInfo retval; - Qt3DSDMInstanceHandle theInstance; - Qt3DSDMInstanceHandle parentInstance; - if (!qt3ds::foundation::isTrivial(clsRef)) { - if (clsRef[0] == '#') - ++clsRef; - parentInstance = GetInstanceById(Convert0(clsRef)); - } else { - parentInstance = m_NewMetaData->GetCanonicalInstanceForType(Convert0(clsName)); - } - if (parentInstance.Valid() == false) { - QT3DS_ASSERT(false); - return retval; - } - theInstance = m_DataCore->CreateInstance(); - m_DataCore->DeriveInstance(theInstance, parentInstance); - m_IdToHandleMap.insert(std::make_pair(TCharStr(Convert0(inId)), theInstance)); - // setup isComponent - Qt3DSDMInstanceHandle slideOwner = m_NewMetaData->GetCanonicalInstanceForType(L"SlideOwner"); - retval.m_IsComponent = m_DataCore->IsInstanceOrDerivedFrom(theInstance, slideOwner); - TCharStr type = m_NewMetaData->GetTypeForInstance(theInstance); - qt3ds::foundation::ConvertUTF(type.c_str(), type.size(), retval.m_ClassName); - vector theProperties; - m_NewMetaData->GetMetaDataProperties(theInstance, theProperties); - MetaPropertiesToAttList(theProperties, retval.m_Attributes); - return retval; - } - - TAttOrArgList GetSlideAttributes() override - { - TAttOrArgList retval; - Qt3DSDMInstanceHandle slideOwner = m_NewMetaData->GetCanonicalInstanceForType(L"Slide"); - vector theProperties; - m_NewMetaData->GetSpecificMetaDataProperties(slideOwner, theProperties); - MetaPropertiesToAttList(theProperties, retval); - return retval; - } - - bool IsCustomHandler(const char *inId, const char *inHandlerName) override - { - return IsCustomHandler(Convert0(inId), Convert1(inHandlerName)); - } - - virtual void GetHandlerArgumentType(const wchar_t *inId, const wchar_t *inHandlerName, - const wchar_t *inArgumentName, - ERuntimeDataModelDataType &outType, - ERuntimeAdditionalMetaDataType &outAdditionalType) - { - outType = ERuntimeDataModelDataTypeNone; - outAdditionalType = ERuntimeAdditionalMetaDataTypeNone; - - Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId); - Qt3DSDMHandlerHandle theHandle = - m_NewMetaData->FindHandlerByName(theInstance, inHandlerName); - Option theArgMetaData( - m_NewMetaData->FindHandlerArgumentByName(theHandle, inArgumentName)); - if (theArgMetaData.hasValue()) { - outType = Convert(theArgMetaData->GetDataType()); - outAdditionalType = Convert(theArgMetaData->GetAdditionalType()); - } - - // Check if the type is something that we support - QT3DS_ASSERT(outType != ERuntimeDataModelDataTypeNone); - } - - void GetHandlerArgumentType(const char *inId, const char *inHandlerName, - const char *inArgumentName, - ERuntimeDataModelDataType &outType, - ERuntimeAdditionalMetaDataType &outAdditionalType) override - { - GetHandlerArgumentType(Convert0(inId), Convert1(inHandlerName), Convert2(inArgumentName), - outType, outAdditionalType); - } - - std::shared_ptr ParseScriptFile(const wchar_t *inFullPathToDocument, - std::shared_ptr inStringTable) - { - using namespace ScriptParser; - std::shared_ptr theStringTable(inStringTable); - std::shared_ptr theFactory(IDOMFactory::CreateDOMFactory(theStringTable)); - SImportXmlErrorHandler theXmlErrorHandler; - const QString path = QString::fromWCharArray(inFullPathToDocument); - std::shared_ptr theReaderPtr( - SScriptParser::ParseScriptFile(theFactory, inStringTable, - path, - theXmlErrorHandler, m_InputStreamFactory)); - if (!theReaderPtr) - qCCritical(INVALID_OPERATION) << "Failed to open script file: " << path; - return theReaderPtr; - } - - Qt3DSDMInstanceHandle CreateAndDeriveInstance(const wchar_t *inType, const wchar_t *inId) - { - // Make sure that the same id has not been created before - TCharStr theId(inId); - QT3DS_ASSERT(m_IdToHandleMap.find(theId) == m_IdToHandleMap.end()); - - Qt3DSDMInstanceHandle theCanonicalType(m_NewMetaData->GetCanonicalInstanceForType(inType)); - if (theCanonicalType.Valid() == false) { - QT3DS_ASSERT(false); - return 0; - } - - Qt3DSDMInstanceHandle theMaster = m_DataCore->CreateInstance(); - m_DataCore->DeriveInstance(theMaster, theCanonicalType); - m_IdToHandleMap.insert(std::make_pair(theId, theMaster)); - return theMaster; - } - - virtual bool LoadScriptFile(const wchar_t *inType, const wchar_t *inId, const wchar_t *inName, - const wchar_t *inSourcePath) - { - TCharStr theId(inId); - if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) - return true; - - Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(inType, inId); - if (!theMaster.Valid()) - return false; - - std::shared_ptr theScriptPtr = - ParseScriptFile(inSourcePath, m_DataCore->GetStringTablePtr()); - if (theScriptPtr) { - std::vector warnings; - // Now the magic section - m_NewMetaData->LoadInstance(*theScriptPtr, theMaster, inName, warnings); - - // Set the name - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theMaster, L"name"); - m_DataCore->SetInstancePropertyValue(theMaster, theProperty, - std::make_shared(inName)); - return true; - } - - return false; - } - - bool LoadScriptFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) override - { - return LoadScriptFile(Convert0(inType), Convert1(inId), Convert2(inName), - Convert3(inSourcePath)); - } - - bool LoadEffectXMLFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) override - { - const wchar_t *theType(Convert0(inType)); - const wchar_t *theId(Convert1(inId)); - const wchar_t *theName(Convert2(inName)); - if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) - return true; - - Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId); - if (!theMaster.Valid()) - return false; - NVScopedRefCounted theStream( - m_InputStreamFactory.GetStreamForFile(inSourcePath)); - if (theStream) { - std::vector warnings; - bool success = m_NewMetaData->LoadEffectXMLFromSourcePath( - inSourcePath, theMaster, theName, warnings, *theStream); - (void)success; - QT3DS_ASSERT(success); - return success; - } - return false; - } - - bool LoadMaterialXMLFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) override - { - const wchar_t *theType(Convert0(inType)); - const wchar_t *theId(Convert1(inId)); - const wchar_t *theName(Convert2(inName)); - (void)theName; - if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) - return true; - - Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId); - if (!theMaster.Valid()) - return false; - - NVScopedRefCounted theStream( - m_InputStreamFactory.GetStreamForFile(inSourcePath)); - if (theStream) { - std::vector warnings; - bool success = m_NewMetaData->LoadMaterialClassFromSourcePath( - inSourcePath, theMaster, theId, warnings, *theStream); - (void)success; - QT3DS_ASSERT(success); - return success; - } - return false; - } - - struct PluginErrorHandler : public qt3dsdm::CXmlErrorHandler - { - void OnXmlError(const QString &, int, int) override {} - }; - - bool LoadPluginXMLFile(const char *inType, const char *inId, const char *inName, - const char *inSourcePath) override - { - const wchar_t *theType(Convert0(inType)); - const wchar_t *theId(Convert1(inId)); - const wchar_t *theName(Convert2(inName)); - if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) - return true; - - Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId); - if (!theMaster.Valid()) - return false; - - std::shared_ptr theFactory = - qt3dsdm::IDOMFactory::CreateDOMFactory(m_StrTable); - - PluginErrorHandler dummyHandler; - std::shared_ptr theReader = Q3DStudio::CRenderPluginParser::ParseFile( - theFactory, m_StrTable, inSourcePath, dummyHandler, m_InputStreamFactory); - if (theReader) { - Q3DStudio::CRenderPluginParser::NavigateToMetadata(theReader); - std::vector theWarnings; - m_NewMetaData->LoadInstance(*theReader, theMaster, theName, theWarnings); - Qt3DSDMPropertyHandle theProperty = - m_DataCore->GetAggregateInstancePropertyByName(theMaster, L"name"); - m_DataCore->SetInstancePropertyValue(theMaster, theProperty, - std::make_shared(theName)); - return true; - } - return false; - } - - Option GetEffectMetaDataBySourcePath(const char *inName) override - { - return m_NewMetaData->GetEffectBySourcePath(inName); - } - - virtual Option - GetMaterialMetaDataBySourcePath(const char *inName) override - { - return m_NewMetaData->GetMaterialBySourcePath(inName); - } - - virtual void GetInstanceProperties(const wchar_t *inType, const wchar_t *inId, - eastl::vector &outProperties, - bool inSearchParent) - { - // Get the instance handle given the type or id - Qt3DSDMInstanceHandle theInstance = - IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); - if (!theInstance.Valid()) { - QT3DS_ASSERT(false); - return; - } - - vector theProperties; - if (inSearchParent) - // Get the meta data properties defined on this object or its derivation parents - m_NewMetaData->GetMetaDataProperties(theInstance, theProperties); - else - // Get the meta data properties defined on *only* this object, don't search parents - m_NewMetaData->GetSpecificMetaDataProperties(theInstance, theProperties); - - outProperties.clear(); - // Iterate each property and fill outProperties - for (size_t propIdx = 0, propEnd = theProperties.size(); propIdx < propEnd; ++propIdx) { - SMetaDataPropertyInfo theInfo( - m_NewMetaData->GetMetaDataPropertyInfo(theProperties[propIdx])); - outProperties.push_back(TRuntimeMetaDataStrType()); - qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), 0, outProperties.back()); - } - } - - void GetInstanceProperties(const char *inType, const char *inId, - eastl::vector &outProperties, - bool inSearchParent) override - { - GetInstanceProperties(Convert0(inType), Convert2(inId), outProperties, inSearchParent); - } - - std::shared_ptr GetStringTable() override { return m_StrTable; } - - TStrTableStr Register(const char *inStr) override - { - return m_StrTable->GetRenderStringTable().RegisterStr(inStr); - } - - //============================================================================== - /** - * @Self release - */ - void release() override { delete this; } - - void ClearPerProjectData() override - { - - m_IdToHandleMap.clear(); - m_PropertyLookupHash.clear(); - } - -}; // end of struct SRuntimeMetaDataImpl -} - -IRuntimeMetaData &IRuntimeMetaData::Create(IInputStreamFactory &inInputStreamFactory) -{ - SRuntimeMetaDataImpl &retval = *new SRuntimeMetaDataImpl(inInputStreamFactory); - retval.Load(); - return retval; -} diff --git a/src/Runtime/Source/Engine/Include/EnginePrefix.h b/src/Runtime/Source/Engine/Include/EnginePrefix.h deleted file mode 100644 index d9017850..00000000 --- a/src/Runtime/Source/Engine/Include/EnginePrefix.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "render/backends/gl/Qt3DSOpenGLPrefix.h" - -#ifdef _WIN32 -//============================================================================== -// DEFINES -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -//============================================================================== -// DISABLED WARNINGS -// -// Note that most of these warnings are tuned off by default by the compiler -// even at warning level 4. Using option /Wall turns on all warnings and makes -// even standard Microsoft include files cry. We had to turn off these or -// turn off warnings individually for each standard include file which was -// too much work. Point is that /Wall is like Warning Level 5 and this brings -// it down to about Warning level 4.5, still way above /W4. -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union -//#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list -//#pragma warning( disable : 4511 ) // copy constructor could not be generated -#pragma warning(disable : 4512) // assignment operator could not be generated -#pragma warning(disable : 4514) // unreferenced inline function has been removed -//#pragma warning( disable : 4619 ) // #pragma warning : there is no warning number '4619' (in -//string.h) -#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy - // constructor is inaccessible -#pragma warning(disable : 4626) // assignment operator could not be generated because a base class - // assignment operator is inaccessible -//#pragma warning( disable : 4640 ) // TODO MF Remove - construction of local static object is -//not thread-safe -#pragma warning(disable : 4710) // function not inlined -#pragma warning(disable : 4711) // function selected for automatic inline expansion -#pragma warning( \ - disable : 4738) // storing 32-bit float result in memory, possible loss of performance -#pragma warning(disable : 4826) // Conversion from 'const void *' to 'void *' is sign-extended -//#pragma warning( disable : 4996 ) // _snprintf' was declared deprecated - -#endif //_WIN32 - -//============================================================================== -// Non-windows environments need to declare this -#ifndef MAX_PATH -#define MAX_PATH 260 -#endif - -//============================================================================== -// STD - Standard includes MUST come first -#ifdef _WIN32 -#pragma warning(push, 3) -#pragma warning( \ - disable : 4548) // expression before comma has no effect; expected expression with side-effect -#endif - -#include -#include - -#if defined(_PCPLATFORM) || defined(_TEGRAPLATFORM) -#include -#endif - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -//============================================================================== -// Runtime -//============================================================================== -#include "Qt3DSAssert.h" -#include "Qt3DSMacros.h" -#include "Qt3DSElementSystem.h" -#include "Qt3DSQmlEngine.h" -#include "Qt3DSAttributeHashes.h" - -//============================================================================== -// Additional Linux only dependencies -//============================================================================== -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - -#pragma pack(1) -struct BITMAPFILEHEADER -{ - Q3DStudio::UINT16 bfType; - Q3DStudio::UINT32 bfSize; - Q3DStudio::UINT16 bfReserved1; - Q3DStudio::UINT16 bfReserved2; - Q3DStudio::UINT32 bfOffBits; -}; -#pragma pack() - -#pragma pack(1) - -typedef struct tagBITMAPINFOHEADER -{ - Q3DStudio::UINT32 biSize; - Q3DStudio::INT32 biWidth; - Q3DStudio::INT32 biHeight; - Q3DStudio::UINT16 biPlanes; - Q3DStudio::UINT16 biBitCount; - Q3DStudio::UINT32 biCompression; - Q3DStudio::UINT32 biSizeImage; - Q3DStudio::INT32 biXPelsPerMeter; - Q3DStudio::INT32 biYPelsPerMeter; - Q3DStudio::UINT32 biClrUsed; - Q3DStudio::UINT32 biClrImportant; -} BITMAPINFOHEADER; - -#pragma pack() - -#define UNREFERENCED_PARAMETER(theParam) theParam; - -#endif diff --git a/src/Runtime/Source/Engine/Include/NVImageScaler.h b/src/Runtime/Source/Engine/Include/NVImageScaler.h deleted file mode 100644 index 069604a6..00000000 --- a/src/Runtime/Source/Engine/Include/NVImageScaler.h +++ /dev/null @@ -1,311 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -namespace Q3DStudio { -namespace ImageScaler { - - //============================================================================== - /** - * - */ - template - inline void BilinearReduceRows(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - CHAR *outDstBuffer, INT32 inDstHeight) - { - INT32 theDDAConst = static_cast(1024.0 * inDstHeight / inSrcHeight); - INT32 theDDAAccum = 0; - INT32 thePixelCount; - - INT32 theSrcRow; - INT32 theSrcCol; - INT32 theDstRow; - - INT32 theChannelAccum[TNumChannels] = { 0 }; - - CHAR *theDstPointer = outDstBuffer; - const CHAR *theSrcPointer = inSrcBuffer; - const CHAR *theSrcColPointer = NULL; - CHAR *theDstColPointer = NULL; - - INT32 theStepSize = TNumChannels; - INT32 theSrcStride = TNumChannels * inSrcWidth; - INT32 theDstStride = TNumChannels * inSrcWidth; - - for (theSrcCol = 0; theSrcCol < inSrcWidth; ++theSrcCol) { - theSrcColPointer = theSrcPointer + (theSrcCol * theStepSize); - theDstColPointer = theDstPointer + (theSrcCol * theStepSize); - - theSrcRow = 0L; - theDstRow = 0L; - thePixelCount = 0L; - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] = 0L; - - theDDAAccum = 0L; - - while (theSrcRow < inSrcHeight) { - while ((theDDAAccum < 1024L) && (theSrcRow < inSrcHeight)) { - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] += - 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + idx]; - - theDDAAccum += theDDAConst; - thePixelCount += 1024L; - ++theSrcRow; - } - - theDDAAccum = (theSrcRow < inSrcHeight) ? (theDDAAccum - 1024L) : (0L); - thePixelCount -= theDDAAccum; - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] -= theDDAAccum - * (INT32)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + idx]; - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theDstColPointer[(theDstRow * theDstStride) + idx] = - (CHAR)(theChannelAccum[idx] / thePixelCount); - - thePixelCount = 1024L - theDDAAccum; - ++theDstRow; - - if (theDstRow >= inDstHeight) - break; - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] = thePixelCount - * (INT32)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + idx]; - } - } - } - - inline void BilinearReduceRows(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - INT32 inChannels, CHAR *outDstBuffer, INT32 inDstHeight) - { - switch (inChannels) { - case 4: - BilinearReduceRows<4>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); - break; - case 3: - BilinearReduceRows<3>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); - break; - case 2: - BilinearReduceRows<2>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); - break; - case 1: - BilinearReduceRows<1>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); - break; - } - } - - template - inline void BilinearReduceCols(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - CHAR *outDstBuffer, INT32 inDstWidth) - { - INT32 theDDAConst = static_cast(1024.0 * inDstWidth / inSrcWidth); - INT32 theDDAAccum = 0L; - INT32 thePixelCount; - - INT32 theSrcRow; - INT32 theSrcCol; - INT32 theDstCol; - - INT32 theChannelAccum[TNumChannels]; - - CHAR *theDstPointer = outDstBuffer; - const CHAR *theSrcPointer = inSrcBuffer; - const CHAR *theSrcRowPointer; - CHAR *theDstRowPointer; - - INT32 theSrcStepSize = TNumChannels; - INT32 theDstStepSize = TNumChannels; - - for (theSrcRow = 0; theSrcRow < inSrcHeight; ++theSrcRow) { - - theSrcRowPointer = theSrcPointer + (theSrcRow * inSrcWidth * theSrcStepSize); - theDstRowPointer = theDstPointer + (theSrcRow * inDstWidth * theDstStepSize); - - theSrcCol = 0L; - theDstCol = 0L; - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] = 0L; - thePixelCount = 0L; - theDDAAccum = 0L; - - while (theSrcCol < inSrcWidth) { - while ((theDDAAccum < 1024L) && (theSrcCol < inSrcWidth)) { - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] += - 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + idx]; - - theDDAAccum += theDDAConst; - thePixelCount += 1024L; - ++theSrcCol; - } - - theDDAAccum = (theSrcCol < inSrcWidth) ? (theDDAAccum - 1024L) : (0L); - thePixelCount -= theDDAAccum; - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] -= theDDAAccum - * (INT32)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + idx]; - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theDstRowPointer[(theDstCol * theDstStepSize) + idx] = - (CHAR)(theChannelAccum[idx] / thePixelCount); - - thePixelCount = 1024L - theDDAAccum; - ++theDstCol; - - if (theDstCol >= inDstWidth) { - break; - } - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theChannelAccum[idx] = thePixelCount - * (INT32)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + idx]; - } - } - } - - inline void BilinearReduceCols(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - INT32 inChannels, CHAR *&outDstBuffer, INT32 inDstWidth) - { - switch (inChannels) { - case 4: - BilinearReduceCols<4>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); - break; - case 3: - BilinearReduceCols<3>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); - break; - case 2: - BilinearReduceCols<2>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); - break; - case 1: - BilinearReduceCols<1>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); - break; - } - } - - template - inline void BilinearReduceImage(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - CHAR *outDstBuffer, INT32 inDstWidth, INT32 inDstHeight) - { - // Number larger than 1024 - // One pixel in the source image is equivalent to this much of a pixel - // in terms of dest pixels. - INT32 theXIncrement = static_cast(1024.f * inSrcWidth / inDstWidth); - // How many rows do we skip, in fixed point arithmetic, when we bump lines - INT32 theYIncrement = static_cast(1024.f * inSrcHeight / inDstHeight); - // We are starting at position .5 in textel space - INT32 theSrcYPtr = 0; - CHAR *theDstPtr = outDstBuffer; - for (INT32 theHeightIndex = 0; theHeightIndex < inDstHeight; - ++theHeightIndex, theSrcYPtr += theYIncrement) { - INT32 theSrcXPtr = 0; - for (INT32 theWidthIndex = 0; theWidthIndex < inDstWidth; - ++theWidthIndex, theSrcXPtr += theXIncrement, theDstPtr += TNumChannels) { - INT32 theAccum[TNumChannels] = { 0 }; - INT32 theNumPixels = 0; - // Pull all reasonable pixels from the source image. - INT32 theStartRow = (theSrcYPtr / 1024); - INT32 theStopRow = (theSrcYPtr + theYIncrement) / 1024; - INT32 theStartColumn = theSrcXPtr / 1024; - INT32 theStopColumn = (theSrcXPtr + theXIncrement) / 1024; - // Average everything between the columns - for (INT32 theRow = theStartRow; theRow < theStopRow; ++theRow) { - INT32 theSrcAddr = (theRow * inSrcWidth + theStartColumn) * TNumChannels; - for (INT32 theCol = theStartColumn; theCol < theStopColumn; - ++theCol, theSrcAddr += TNumChannels) { - ++theNumPixels; - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theAccum[idx] += inSrcBuffer[theSrcAddr + idx]; - } - } - - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theDstPtr[idx] = theAccum[idx] / theNumPixels; - } - } - } - - template - inline void NearestReduceImage(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - CHAR *outDstBuffer, INT32 inDstWidth, INT32 inDstHeight) - { - // Number larger than 1024 - // One pixel in the source image is equivalent to this much of a pixel - // in terms of dest pixels. - INT32 theXIncrement = static_cast(1024.f * inSrcWidth / inDstWidth); - // How many rows do we skip, in fixed point arithmetic, when we bump lines - INT32 theYIncrement = static_cast(1024.f * inSrcHeight / inDstHeight); - // We are starting at position .5 in textel space - INT32 theSrcYPtr = theYIncrement / 2; - CHAR *theDstPtr = outDstBuffer; - for (INT32 theHeightIndex = 0; theHeightIndex < inDstHeight; - ++theHeightIndex, theSrcYPtr += theYIncrement) { - INT32 theSrcRow = (theSrcYPtr / 1024) * inSrcWidth * TNumChannels; - INT32 theSrcXPtr = theXIncrement / 2; - for (INT32 theWidthIndex = 0; theWidthIndex < inDstWidth; - ++theWidthIndex, theSrcXPtr += theXIncrement, theDstPtr += TNumChannels) { - INT32 theSrcPtr = theSrcRow + (theSrcXPtr >> 10) * TNumChannels; - for (INT32 idx = 0; idx < TNumChannels; ++idx) - theDstPtr[idx] = inSrcBuffer[theSrcPtr + idx]; - } - } - } - - inline void NearestReduceImage(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, - INT32 inChannels, CHAR *outDstBuffer, INT32 inDstWidth, - INT32 inDstHeight) - { - switch (inChannels) { - case 4: - NearestReduceImage<4>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, - inDstHeight); - break; - case 3: - NearestReduceImage<3>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, - inDstHeight); - break; - case 2: - NearestReduceImage<2>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, - inDstHeight); - break; - case 1: - NearestReduceImage<1>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, - inDstHeight); - break; - } - } -} -} \ No newline at end of file diff --git a/src/Runtime/Source/Engine/Include/OpenKodeInclude.h b/src/Runtime/Source/Engine/Include/OpenKodeInclude.h deleted file mode 100644 index 06bdf006..00000000 --- a/src/Runtime/Source/Engine/Include/OpenKodeInclude.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== - -// Wrap the include so we can ensure it gets compiled with 8 byte alignment -// also, this means we need to compile nv_main.c (via right click -> properties) with 8 byte -// alignment too! - -#pragma pack(push) -#pragma pack(8) -#include -#pragma pack(pop) - -//============================================================================== -// Namespace -//============================================================================== -namespace NVUI { - -} // namespace NVUI diff --git a/src/Runtime/Source/Engine/Include/Qt3DSEGLInfo.h b/src/Runtime/Source/Engine/Include/Qt3DSEGLInfo.h deleted file mode 100644 index 7be2c09e..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSEGLInfo.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_EGLINFO_H -#define QT3DS_EGLINFO_H - -#ifdef _PLATFORM_USE_EGL -#include - -namespace Q3DStudio { -struct SEGLInfo -{ - EGLDisplay display; - EGLSurface surface; - EGLContext context; - EGLConfig config; - EGLNativeWindowType nativewin; -}; -}; - -#else -namespace Q3DStudio { -struct SEGLInfo -{ - void *display; - void *surface; - void *context; - void *config; - void *nativewin; -}; -}; -#endif - -#endif diff --git a/src/Runtime/Source/Engine/Include/Qt3DSEGLWindowSystem.h b/src/Runtime/Source/Engine/Include/Qt3DSEGLWindowSystem.h deleted file mode 100644 index 770f5c9f..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSEGLWindowSystem.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_EGL_WINDOW_SYSTEM_H -#define QT3DS_EGL_WINDOW_SYSTEM_H -#include "Qt3DSEGLInfo.h" -#include "Qt3DSWindowSystem.h" -#include "nv_main/nv_main.h" - -namespace Q3DStudio { -struct SEGLWindowSystemImpl : public IWindowSystem -{ - SEGLInfo m_EGLInfo; - - virtual QSize GetWindowDimensions() - { - int w, h; - - eglQuerySurface(gEGLHandles[0].display, gEGLHandles[0].surface, EGL_WIDTH, &w); - eglQuerySurface(gEGLHandles[0].display, gEGLHandles[0].surface, EGL_HEIGHT, &h); - - return QSize(w, h); - } - virtual void SetWindowDimensions(const QSize &) {} - // For platforms that support it, we get the egl info for render plugins - // Feel free to return NULL. - virtual SEGLInfo *GetEGLInfo() - { - m_EGLInfo.display = gEGLHandles[0].display; - m_EGLInfo.surface = gEGLHandles[0].surface; - m_EGLInfo.context = gEGLHandles[0].context; - m_EGLInfo.config = gEGLHandles[0].config; - m_EGLInfo.nativewin = gEGLHandles[0].nativewin; - return &m_EGLInfo; - } - // on some systems we allow our default render target to be a offscreen buffer - // otherwise return 0; - virtual int GetDefaultRenderTargetID() { return 0; } - // returns the depth buffer bit count for the render window - // overwrite this one for your own needs - virtual int GetDepthBitCount() - { - EGLint depth = 16; -#ifdef _PLATFORM_USE_EGL - if (gEGLHandles[0].display && gEGLHandles[0].config) - eglGetConfigAttrib(gEGLHandles[0].display, gEGLHandles[0].config, EGL_DEPTH_SIZE, - &depth); -#endif - - return depth; - } -}; -}; - -#endif diff --git a/src/Runtime/Source/Engine/Include/Qt3DSPluginDLL.h b/src/Runtime/Source/Engine/Include/Qt3DSPluginDLL.h deleted file mode 100644 index 1ba7cf08..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSPluginDLL.h +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//============================================================================== -// Includes -//============================================================================== -#pragma once -#include "Qt3DSBasicPluginDLL.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -//============================================================================== -// Enums -//============================================================================== -// Texture format -typedef enum _ETEXTUREFORMAT { - ETEXTUREFORMAT_Unknown = 0, - ETEXTUREFORMAT_RGBA8, - ETEXTUREFORMAT_RGB8, - ETEXTUREFORMAT_RGB565, - ETEXTUREFORMAT_RGBA5551, - ETEXTUREFORMAT_Alpha8, - ETEXTUREFORMAT_Luminance8, - ETEXTUREFORMAT_LuminanceAlpha8, - ETEXTUREFORMAT_RGBA_DXT1, - ETEXTUREFORMAT_RGB_DXT1, - ETEXTUREFORMAT_RGBA_DXT3, - ETEXTUREFORMAT_RGBA_DXT5, -} ETEXTUREFORMAT; - -//============================================================================== -// Functions declarations -//============================================================================== - -//============================================================================== -/** - * Perform plugin initialization. - * @param inArgs string arguments from XIF arg parameter - * @return EDLLSTATUS_OK if initialization suceeds - */ -typedef long (*PROC_Initialize)(const char *inArgs); -Q_DECL_EXPORT long Initialize(const char *inArgs); - -//============================================================================== -/** - * Passes the current screen size and format to the plugin. - * Plugin should override with it's own desired settings. - * This affects the size and format of the allocated offscreen texture. - * When resources are allocated, SetAllocatedRenderInfo will be called to - * inform the plugin of the allocated resources - * @param ioWidth width - * @param ioHeight height - * @param ioTextureFormat See ETEXTUREFORMAT - */ -typedef void (*PROC_GetDesiredTextureSize)(long *ioWidth, long *ioHeight, - ETEXTUREFORMAT *ioTextureFormat); -Q_DECL_EXPORT void GetDesiredTextureSize(long *ioWidth, long *ioHeight, - ETEXTUREFORMAT *ioTextureFormat); - -//============================================================================== -/** - * Information about the current EGL environment. - * Useful if plugin wishes to switch EGLContext to manage it's own state. - * Optional - * @param inEGLDisplay pointer to EGLDisplay - * @param inEGLCurrentContext pointer to current EGLContext - * @param inEGLSurface pointer to EGLSurface - * @param inEGLConfig pointer to EGLConfig attributes - */ -typedef void (*PROC_SetEGLInfo)(void *inEGLDisplay, void *inEGLCurrentContext, void *inEGLSurface, - void *inEGLConfig); -Q_DECL_EXPORT void SetEGLInfo(void *inEGLDisplay, void *inEGLCurrentContext, - void *inEGLSurface, void *inEGLConfig); - -//============================================================================== -/** - * Render pulse whenever the runtime requires a frame from the plugin. - * Note that if plugin wishes to switch EGLContext, - * it should restore the previous EGLContext(obtained from SetEGLInfo) at the end of this - *function. - * @param inHostWidth width of the host rectangle - * @param inHostHeight height of the host rectangle - * @param inDrawTime current time in milliseconds - */ -typedef void (*PROC_Render)(long inHostWidth, long inHostHeight, long inDrawTime); -Q_DECL_EXPORT void Render(long inHostWidth, long inHostHeight, long inDrawTime); - -//============================================================================== -/** - * Perform plugin uninitialization. - * @return EDLLSTATUS_OK if successful - */ -typedef long (*PROC_Uninitialize)(); -Q_DECL_EXPORT long Uninitialize(); - -#ifdef __cplusplus -} -#endif diff --git a/src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBinding.h b/src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBinding.h deleted file mode 100644 index ea95b943..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBinding.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_RENDER_RUNTIME_BINDING_H -#define QT3DS_RENDER_RUNTIME_BINDING_H - -#include "Qt3DSRuntimeFactory.h" -#include "EABase/eabase.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" - -#include - -namespace Q3DStudio { -class ITegraApplicationRenderEngine; -class ITimeProvider; -class IWindowSystem; -} - -namespace qt3ds { -namespace render { - - class ITextRenderer; - class IRuntimeFactoryRenderFactory - { - protected: - virtual ~IRuntimeFactoryRenderFactory() {} - public: - virtual qt3ds::render::NVRenderContext * - CreateRenderContext(qt3ds::NVFoundationBase &foundat, qt3ds::foundation::IStringTable &strt) = 0; - }; - - class IQt3DSRenderFactory; - - class QT3DS_AUTOTEST_EXPORT IQt3DSRenderFactoryCore : public Q3DStudio::IRuntimeFactoryCore - { - public: - virtual IQt3DSRenderFactory & - CreateRenderFactory(const QSurfaceFormat &format) = 0; - - static IQt3DSRenderFactoryCore & - CreateRenderFactoryCore(const char8_t *inApplicationDirectory, - Q3DStudio::IWindowSystem &inWindowSystem, - Q3DStudio::ITimeProvider &inTimeProvider); - }; - - class IQt3DSRenderFactory : public Q3DStudio::IRuntimeFactory - { - public: - virtual Q3DStudio::ITegraApplicationRenderEngine &CreateRenderEngine() = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBindingImpl.h b/src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBindingImpl.h deleted file mode 100644 index 3ffe15ce..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSRenderRuntimeBindingImpl.h +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_RENDER_RUNTIME_BINDING_IMPL_H -#define QT3DS_RENDER_RUNTIME_BINDING_IMPL_H - -#include "Qt3DSRenderRuntimeBinding.h" -#include "foundation/TrackingAllocator.h" -#include "foundation/Utils.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSRender.h" -#include "Qt3DSRenderContextCore.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSIPresentation.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSRenderPresentation.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderModel.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSUIPParser.h" -#include "Qt3DSRenderEffect.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderEffectSystem.h" -#include "foundation/Qt3DSInvasiveSet.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderText.h" -#include "foundation/StrConvertUTF.h" -#include "Qt3DSMetadata.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSWindowSystem.h" -#include "Qt3DSRenderPluginGraphObject.h" -#include "Qt3DSRenderReferencedMaterial.h" -#include "Qt3DSRenderText.h" -#include "foundation/Qt3DSMutex.h" - -#ifdef EA_PLATFORM_WINDOWS -#pragma warning(disable : 4355) -#else -#define stricmp strcasecmp -#endif - -using namespace qt3ds::render; -using eastl::make_pair; -using eastl::pair; - -namespace qt3ds { -namespace render { - - extern qt3ds::foundation::MallocAllocator g_BaseAllocator; - // Small core object shared between the larger objects. - // creates the object stack needed by the rest of the system. - struct SBindingCore : public NVRefCounted - { - qt3ds::render::CAllocator m_Allocator; - QT3DSU8 *m_FlowData; - NVScopedRefCounted m_Foundation; - NVScopedRefCounted m_StringTable; - NVScopedRefCounted m_CoreContext; - NVScopedRefCounted m_RenderContext; - NVScopedRefCounted m_Context; - QSize m_WindowDimensions; - eastl::string m_PrimitivePath; - bool m_RenderRotationsEnabled; - bool m_WriteOutShaderCache; - volatile QT3DSI32 mRefCount; - Q3DStudio::IWindowSystem &m_WindowSystem; - Q3DStudio::ITimeProvider &m_TimeProvider; - - SBindingCore(const char8_t *inPrimitivePath, Q3DStudio::IWindowSystem &inWindowSystem, - Q3DStudio::ITimeProvider &inTimeProvider) - : m_Allocator() - , m_FlowData(NULL) - , m_Foundation(NVCreateFoundation(QT3DS_FOUNDATION_VERSION, m_Allocator)) - , m_StringTable(IStringTable::CreateStringTable(m_Foundation->getAllocator())) - , m_CoreContext(IQt3DSRenderContextCore::Create(*m_Foundation, *m_StringTable)) - , m_PrimitivePath(inPrimitivePath) - , m_RenderRotationsEnabled(false) - , m_WriteOutShaderCache(false) - , mRefCount(0) - , m_WindowSystem(inWindowSystem) - , m_TimeProvider(inTimeProvider) - { - m_CoreContext->SetTextRendererCore( - ITextRendererCore::CreateQtTextRenderer(*m_Foundation, *m_StringTable)); - - m_CoreContext->SetOnscreenTextRendererCore( - ITextRendererCore::CreateOnscreenTextRenderer(*m_Foundation)); - } - virtual ~SBindingCore() - { - m_CoreContext = NULL; - m_Context = NULL; - m_RenderContext = NULL; - if (m_FlowData) - m_Allocator.deallocate(m_FlowData); - m_FlowData = NULL; - } - - void CreateRenderContext(qt3ds::render::IRuntimeFactoryRenderFactory &inContextFactory) - { - m_RenderContext = inContextFactory.CreateRenderContext(*m_Foundation, *m_StringTable); - if (m_RenderContext) - m_Context = - m_CoreContext->CreateRenderContext(*m_RenderContext, m_PrimitivePath.c_str()); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_BaseAllocator) - - NVAllocatorCallback &GetAllocator() { return m_Allocator; } - - Q3DStudio::ITegraApplicationRenderEngine &CreateRenderer(); - }; - struct STranslatorContext - { - }; - - //////////////////////////////////////// - // Translators are the set of objects that translate - // changes in the elements to changes in the scene graph. - // TODO - get rid of the virtual functions and just do dispatch - // on the m_RenderObject.m_Type. - //////////////////////////////////////// - class Qt3DSTranslator - { - public: - QT3DSU32 m_DirtyIndex; - Q3DStudio::TElement *m_Element; - SGraphObject *m_RenderObject; - STranslatorContext *m_TranslatorContext; - - Qt3DSTranslator(Q3DStudio::TElement &inElement, SGraphObject &inRenderObject); - GraphObjectTypes::Enum GetUIPType() const { return m_RenderObject->m_Type; } - Q3DStudio::TElement &Element() { return *m_Element; } - SGraphObject &RenderObject() { return *m_RenderObject; } - - // This function is done via a dispatch mechanism on the graph object type. - void OnElementChanged(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &inStudioPresentation); - - void Save(SWriteBuffer &inWriteBuffer, QT3DSU32 inGraphObjectOffset); - // Most translators don't need an extra allocation but effects due because the mapping from - // effect property - // to runtime property is too complex to do quickly. - static Qt3DSTranslator *LoadTranslator(SDataReader &inReader, size_t inElemOffset, - NVDataRef inSGSection, - NVAllocatorCallback &inAllocator); - - static Qt3DSTranslator *GetTranslatorFromGraphNode(SGraphObject &inObject); - static Qt3DSTranslator *CreateTranslatorForElement(Q3DStudio::TElement &inElement, - SGraphObject &inGraphObject, - NVAllocatorCallback &inAlloc); - static Q3DStudio::IPresentation * - GetPresentationFromPresentation(SPresentation &inPresentation); - static void InitializePointerTags(IStringTable &inTable); - static void AssignUserData(Q3DStudio::IPresentation &inPresentation, - SPresentation &inGraphPresentation); - }; - - struct STranslatorGetOp - { - QT3DSU32 operator()(const Qt3DSTranslator &translator) { return translator.m_DirtyIndex; } - }; - struct STranslatorSetOp - { - void operator()(Qt3DSTranslator &translator, QT3DSU32 value) - { - translator.m_DirtyIndex = value; - } - }; - - typedef InvasiveSet TTranslatorDirytSet; -} -} - -#endif diff --git a/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h b/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h deleted file mode 100644 index 91233355..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h +++ /dev/null @@ -1,322 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_TEGRA_APPLICATION_H -#define QT3DS_TEGRA_APPLICATION_H - -#include "EnginePrefix.h" -#include "Qt3DSIStateful.h" -#include "foundation/Qt3DSVec4.h" -#include "foundation/Qt3DSOption.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSWindowSystem.h" -#include "Qt3DSTimer.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSRenderRuntimeBinding.h" -#include -#include - -//============================================================================== -// Namespace -//============================================================================== - -typedef void (*qml_Function)(void *inUserData); - -class QINDDViewSignalProxy : public QObject -{ - Q_OBJECT -Q_SIGNALS: - void SigSlideEntered(const QString &elementPath, unsigned int index, const QString &name); - void SigSlideExited(const QString &elementPath, unsigned int index, const QString &name); -}; - -namespace qt3ds { -class Qt3DSAssetVisitor; -} - -namespace qt3ds { -namespace render { -class NVRenderContext; -} -} - -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class CTegraInputEngine; -class CTegraRenderEngine; -class IScene; -class CInputEngine; -class IAudioPlayer; - -class ITegraRenderStateManager : public IStatefulStackBase -{ -protected: - virtual ~ITegraRenderStateManager() {} -public: - virtual void SetViewport(INT32 inX, INT32 inY, INT32 inWidth, INT32 inHeight) = 0; - virtual void SetScissorTestEnabled(bool inValue) = 0; - virtual void SaveAllState() = 0; - virtual void RestoreAllState() = 0; -}; - -struct TegraRenderScaleModes -{ - enum Enum { - ExactSize = 0, // Ensure the viewport is exactly same size as application - ScaleToFit = 1, // Resize viewport keeping aspect ratio - ScaleToFill = 2, // Resize viewport to entire window - }; -}; - -struct TegraRenderShadeModes -{ - enum Enum { - Shaded = 0, // Geometry is shaded only - ShadedWireframe = 1, // Wireframe is drawn on top shaded geometry - Wireframe = 2, // Wireframe only - }; -}; - -class ITegraApplicationRenderEngine -{ -protected: - virtual ~ITegraApplicationRenderEngine() {} - -public: - virtual void SetViewport(INT32 inX, INT32 inY, INT32 inWidth, INT32 inHeight) = 0; - virtual void SetApplicationViewport(const qt3ds::render::NVRenderRect &inViewport) = 0; - virtual void ensureRenderTarget() = 0; - virtual void CheckResize(bool inForce, IPresentation &inActivePresentation) = 0; - virtual BOOL LoadShaderCache(const CHAR *inFilePath) = 0; - virtual void AbandonLoadingImages(IScene &inScene) = 0; - virtual BOOL IsPickValid(FLOAT &outX, FLOAT &outY, - const IPresentation &inPresentation) const = 0; - virtual void SetScaleMode(TegraRenderScaleModes::Enum inScale) = 0; - virtual void SetShadeMode(TegraRenderShadeModes::Enum inShade) = 0; - virtual TegraRenderScaleModes::Enum GetScaleMode() const = 0; - - // TODO: To be removed, not used anywhere anymore - void CycleScaleMode() - { - int mode = (int)GetScaleMode(); - mode = (mode + 1) % 3; - SetScaleMode((TegraRenderScaleModes::Enum)mode); - } - - virtual ITegraRenderStateManager &GetTegraRenderStateManager() = 0; - virtual qt3ds::render::NVRenderContext &GetRenderContext() = 0; - virtual void SetMatteColor(qt3ds::foundation::Option inColor) = 0; - virtual void EnableRenderRotation(bool inEnable) = 0; - virtual void SetWriteOutShaderCache(bool inWriteOutShaderCache) = 0; - virtual void Release() = 0; - virtual void RenderText2D(FLOAT x, FLOAT y, qt3ds::foundation::Option inColor, - const char *text) = 0; - virtual void RenderGpuProfilerStats(FLOAT x, FLOAT y, - qt3ds::foundation::Option inColor) = 0; -}; - -class INDDView : public qt3ds::foundation::NVRefCounted -{ -public: - virtual ~INDDView(){} - -public: // loading - virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; - virtual bool HasOfflineLoadingCompleted() = 0; - virtual bool InitializeGraphics(const QSurfaceFormat &format) = 0; - - virtual void Cleanup() = 0; - - virtual bool CanRender() = 0; - - virtual void Render() = 0; - - virtual bool WasLastFrameDirty() = 0; - - virtual bool HandleMessage(const QEvent *inEvent) = 0; - - virtual void Pause() = 0; - virtual void UnPause() = 0; - virtual bool IsPaused() = 0; - virtual INT32 GetFrameCount() = 0; - virtual void showOnScreenStats(bool) = 0; - -public: // Input engine access - virtual CInputEngine *GetInputEngine() = 0; - // Only valid after InitializeGraphics - virtual ITegraApplicationRenderEngine *GetTegraRenderEngine() = 0; - -public: - virtual void GoToSlideByName(const char *elementPath, const char *slideName) = 0; - virtual void GoToSlideByIndex(const char *elementPath, const int slideIndex) = 0; - virtual void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) = 0; - virtual bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) = 0; - virtual void SetPresentationAttribute(const char *presId, const char *, const char *value) = 0; - virtual void GoToTime(const char *elementPath, const float time) = 0; - virtual void SetGlobalAnimationTime(qint64 inMilliSecs) = 0; - virtual void SetDataInputValue(const QString &name, const QVariant &value) = 0; - virtual void SetAttribute(const char *elementPath, const char *attributeName, - const char *value) = 0; - virtual bool GetAttribute(const char *elementPath, const char *attributeName, void *value) = 0; - virtual void FireEvent(const char *element, const char *evtName) = 0; - virtual bool PeekCustomAction(char *&outElementPath, char *&outActionName) = 0; - virtual bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) = 0; - virtual void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) = 0; - virtual qt3ds::foundation::Option GetPresentationSize() = 0; - - virtual void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) = 0; - -public: - static INDDView &Create(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, - IAudioPlayer *inAudioPlayer = NULL); - -public: - QINDDViewSignalProxy *signalProxy(); -private: - QINDDViewSignalProxy m_SignalProxy; -}; - -class CTegraApplication -{ - //============================================================================== - // Fields - //============================================================================== -private: - qt3ds::foundation::NVScopedRefCounted m_NDDView; - -public: - CTegraApplication(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, - IAudioPlayer *inAudioPlayer = 0); - virtual ~CTegraApplication(); - // loading - bool BeginLoad(const QString &sourcePath, const QStringList &variantList); - // asynchronous BeginLoad completed? That only valid for binary presentation, for text - // presentation, always true - bool HasOfflineLoadingCompleted() { return m_NDDView->HasOfflineLoadingCompleted(); } - // Invokes m_ApplicationCore->CreateApplication(), a blocking function ensures binary loading - // completed - bool InitializeGraphics(const QSurfaceFormat& format); - - void Cleanup() { m_NDDView->Cleanup(); } - bool CanRender() { return m_NDDView->CanRender(); } - void Render(); - bool WasLastFrameDirty() { return m_NDDView->WasLastFrameDirty(); } - - bool HandleMessage(const QEvent *inEvent); - void Pause() { m_NDDView->Pause(); } - void UnPause() { m_NDDView->UnPause(); } - bool IsPaused() { return m_NDDView->IsPaused(); } - INT32 GetFrameCount() { return m_NDDView->GetFrameCount(); } - -public: - CInputEngine *GetInputEngine() { return m_NDDView->GetInputEngine(); } - // Only valid after InitializeGraphics - ITegraApplicationRenderEngine *GetTegraRenderEngine() - { - return m_NDDView->GetTegraRenderEngine(); - } - -public: - void GoToSlideByName(const char *elementPath, const char *slideName) - { - m_NDDView->GoToSlideByName(elementPath, slideName); - } - void GoToSlideByIndex(const char *elementPath, const int slideIndex) - { - m_NDDView->GoToSlideByIndex(elementPath, slideIndex); - } - void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) - { - m_NDDView->GoToSlideRelative(elementPath, next, wrap); - } - bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) - { - return m_NDDView->GetSlideInfo(elementPath, currentIndex, previousIndex, - currentName, previousName); - } - void SetPresentationAttribute(const char *presId, const char *, const char *value) - { - m_NDDView->SetPresentationAttribute(presId, nullptr, value); - } - void GoToTime(const char *elementPath, const float time) - { - m_NDDView->GoToTime(elementPath, time); - } - void SetGlobalAnimationTime(qint64 inMilliSecs) - { - m_NDDView->SetGlobalAnimationTime(inMilliSecs); - } - void SetDataInputValue(const QString &name, const QVariant &value) - { - m_NDDView->SetDataInputValue(name, value); - } - void SetAttribute(const char *elementPath, const char *attributeName, const char *value) - { - m_NDDView->SetAttribute(elementPath, attributeName, value); - } - bool GetAttribute(const char *elementPath, const char *attributeName, void *value) - { - return m_NDDView->GetAttribute(elementPath, attributeName, value); - } - void FireEvent(const char *element, const char *evtName) - { - m_NDDView->FireEvent(element, evtName); - } - bool PeekCustomAction(char *&outElementPath, char *&outActionName) - { - return m_NDDView->PeekCustomAction(outElementPath, outActionName); - } - bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) - { - return m_NDDView->RegisterScriptCallback(callbackType, func, inUserData); - }; - void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) - { - m_NDDView->FireEvent(inEventType, inArgument); - } - qt3ds::foundation::Option GetPrimaryPresentationSize() - { - return m_NDDView->GetPresentationSize(); - } - qt3ds::foundation::NVScopedRefCounted getNDDView() - { - return m_NDDView; - } -}; -} // namespace Q3DStudio - -#endif // QT3DS_TEGRA_APPLICATION_H diff --git a/src/Runtime/Source/Engine/Include/Qt3DSTegraInputEngine.h b/src/Runtime/Source/Engine/Include/Qt3DSTegraInputEngine.h deleted file mode 100644 index 14047f16..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSTegraInputEngine.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_TEGRA_INPUT_ENGINE_H -#define QT3DS_TEGRA_INPUT_ENGINE_H - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSInputEngine.h" -#include "Qt3DSTegraApplication.h" -#include "Qt3DSInputEventTypes.h" -#include "Qt3DSPresentation.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class CTegraRenderEngine; -class CPresentation; -class ITegraApplicationRenderEngine; - -//============================================================================== -/** -* @class CTegraInputEngine -* @brief -*/ -class CTegraInputEngine : public CInputEngine -{ - //============================================================================== - // Fields - //============================================================================== - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CTegraInputEngine(); - virtual ~CTegraInputEngine(); - -public: // Access - SInputFrame &GetInputFrame() override; - - void HandleMessage(const QEvent *inEvent, ITegraApplicationRenderEngine &inRenderEngine, - CPresentation *inPresentation); -}; - -} // namespace Q3DStudio - -#endif // QT3DS_TEGRA_INPUT_ENGINE_H diff --git a/src/Runtime/Source/Engine/Include/Qt3DSWindowSystem.h b/src/Runtime/Source/Engine/Include/Qt3DSWindowSystem.h deleted file mode 100644 index 173dd837..00000000 --- a/src/Runtime/Source/Engine/Include/Qt3DSWindowSystem.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_WINDOW_SYSTEM_H -#define QT3DS_WINDOW_SYSTEM_H - -#include - -namespace Q3DStudio { - -struct SEGLInfo; - -class IWindowSystem -{ -protected: - virtual ~IWindowSystem() {} -public: - virtual QSize GetWindowDimensions() = 0; - virtual void SetWindowDimensions(const QSize &inSize) = 0; - // For platforms that support it, we get the egl info for render plugins - // Feel free to return NULL. - virtual SEGLInfo *GetEGLInfo() = 0; - // on some systems we allow our default render target to be a offscreen buffer - // otherwise return 0; - virtual int GetDefaultRenderTargetID() = 0; - // returns the depth buffer bit count for the render window - virtual int GetDepthBitCount() = 0; -}; -} - -#endif diff --git a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp deleted file mode 100644 index 8fa75792..00000000 --- a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp +++ /dev/null @@ -1,1990 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "EnginePrefix.h" -#include "Qt3DSRenderRuntimeBindingImpl.h" -#include "Qt3DSSceneManager.h" -#include "Qt3DSIScene.h" -#include "Qt3DSTegraApplication.h" -#include "Qt3DSQmlEngine.h" -#include "Qt3DSRenderUIPLoader.h" -#include "Qt3DSPresentationFrameData.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSRenderSubpresentation.h" -#include "Qt3DSIScriptBridge.h" -#include "Qt3DSFileStream.h" -#include "Qt3DSDMPrefix.h" -#include "foundation/IOStreams.h" -#include "Qt3DSDMStringTable.h" -#include "Qt3DSDMXML.h" -#include "Qt3DSRenderBufferManager.h" -#include "foundation/SerializationTypes.h" -#include "Qt3DSRenderGraphObjectSerializer.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderImageBatchLoader.h" -#include "Qt3DSPresentation.h" - -#include "Qt3DSDLLManager.h" -#include "Qt3DSBasicPluginDLL.h" -#include "Qt3DSPluginDLL.h" -#include "Qt3DSRenderPlugin.h" -#include "foundation/FileTools.h" -#include "Qt3DSStateVisualBindingContext.h" -#include "Qt3DSStateVisualBindingContextValues.h" -#include "Qt3DSStateScriptContext.h" -#include "EventPollingSystem.h" -#include "EventSystem.h" -#include "Qt3DSApplication.h" -#include "Qt3DSMatrix.h" -#include "Qt3DSWindowSystem.h" -#if !defined (Q_OS_MACOS) -#include "Qt3DSEGLInfo.h" -#endif -#include "Qt3DSOffscreenRenderKey.h" -#include "Qt3DSOldNBustedRenderPlugin.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "Qt3DSRenderBufferLoader.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRenderPrefilterTexture.h" -#include "foundation/PoolingAllocator.h" -#include "q3dsqmlrender.h" - -#ifdef EA_PLATFORM_WINDOWS -#pragma warning(disable : 4355) -#endif - -using namespace qt3ds::render; -using eastl::make_pair; -using eastl::pair; -using qt3ds::runtime::IApplication; - -#ifndef _WIN32 -#define stricmp strcasecmp -#endif -namespace qt3ds { -namespace render { - qt3ds::foundation::MallocAllocator g_BaseAllocator; -} -} -namespace { -struct Qt3DSRenderScene; - -struct Qt3DSRenderSceneSubPresRenderer : public CSubPresentationRenderer -{ - Qt3DSRenderScene &m_Scene; - Qt3DSRenderSceneSubPresRenderer(Qt3DSRenderScene &inScene, IQt3DSRenderContext &inRenderContext, - SPresentation &inPresentation) - : CSubPresentationRenderer(inRenderContext, inPresentation) - , m_Scene(inScene) - { - } - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) - SOffscreenRenderFlags NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, - QT3DSVec2 inPresScale, - const SRenderInstanceId instanceId) override; - void Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, - SScene::RenderClearCommand inClearBuffer, - const SRenderInstanceId instanceId) override; - void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, - SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, - const SRenderInstanceId instanceId) override; -}; - -struct SSceneLoadData -{ - NVAllocatorCallback &m_Allocator; - NVScopedRefCounted m_Data; - SPresentation *m_Presentation; - NVDataRef m_TranslatorData; - NVDataRef m_SceneGraphData; - eastl::vector m_Translators; - SPoolingAllocator m_AutoAllocator; - Q3DStudio::IPresentation *m_RuntimePresentation; - QT3DSI32 mRefCount; - - SSceneLoadData(NVAllocatorCallback &alloc) - : m_Allocator(alloc) - , m_Presentation(NULL) - , m_AutoAllocator(alloc) - , m_RuntimePresentation(NULL) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) -}; - -struct Qt3DSRenderScene : public Q3DStudio::IScene -{ - SBindingCore &m_BindingCore; - NVScopedRefCounted m_Context; - NVScopedRefCounted m_LoadData; - // The scene graph gets allocated kind of on its own - // So do the smaller translation objects that translate TElement properties - // into the graph. - SPresentation *m_Presentation; - Q3DStudio::IPresentation *m_RuntimePresentation; - void *m_UserData; - TTranslatorDirytSet m_DirtySet; - CRegisteredString m_OffscreenRendererId; - IOffscreenRenderer *m_OffscreenRenderer; - CRegisteredString m_SubPresentationType; - nvvector m_GraphObjectList; - bool m_LoggedPickLastFrame; - NVRenderRect m_LastRenderViewport; - CRegisteredString m_PathSubPathType; - - Qt3DSRenderScene(SBindingCore &inBindingCore, IQt3DSRenderContext &inContext, - SSceneLoadData &inLoadData) - : m_BindingCore(inBindingCore) - , m_Context(inContext) - , m_LoadData(inLoadData) - , m_Presentation(inLoadData.m_Presentation) - , m_RuntimePresentation(inLoadData.m_RuntimePresentation) - , m_UserData(NULL) - , m_DirtySet(inContext.GetAllocator(), "Qt3DSRenderScene::m_DirtySet") - , m_OffscreenRenderer(NULL) - , m_SubPresentationType( - inContext.GetStringTable().RegisterStr(CSubPresentationRenderer::GetRendererName())) - , m_GraphObjectList(inContext.GetAllocator(), "Qt3DSDSRenderScene::m_GraphObjectList") - , m_LoggedPickLastFrame(false) - { - for (QT3DSU32 idx = 0, end = inLoadData.m_Translators.size(); idx < end; ++idx) { - m_DirtySet.insert(*inLoadData.m_Translators[idx]); - } - m_PathSubPathType = inContext.GetStringTable().RegisterStr("PathAnchorPoint"); - } - - virtual ~Qt3DSRenderScene() - { - if (m_OffscreenRenderer) - m_Context->GetOffscreenRenderManager().ReleaseOffscreenRenderer(m_OffscreenRendererId); - m_OffscreenRenderer = NULL; - if (m_Presentation && m_Presentation->m_Scene) { - for (SLayer *theLayer = m_Presentation->m_Scene->m_FirstChild; theLayer; - theLayer = static_cast(theLayer->m_NextSibling)) { - m_Context->GetRenderer().ReleaseLayerRenderResources(*theLayer, nullptr); - } - } - } - - Q3DStudio::IPresentation &GetPresentation() override { return *m_RuntimePresentation; } - - // Update really just adds objects to the dirty set - bool Update() - { - Q3DStudio::TElementList &theDirtyList = - m_RuntimePresentation->GetFrameData().GetDirtyList(); - for (QT3DSU32 idx = 0, end = theDirtyList.GetCount(); idx < end; ++idx) { - Q3DStudio::TElement &theElement = *theDirtyList[idx]; - Qt3DSTranslator *theTranslator = - reinterpret_cast(theElement.GetAssociation()); - if (!theTranslator && theElement.GetType() == m_PathSubPathType) { - Q3DStudio::TElement *theParent = theElement.GetParent(); - if (theParent) { - theTranslator = reinterpret_cast(theParent->GetAssociation()); - // The path translator responds to anchor point changes as well as its own data - // changes. - if (theTranslator - && theTranslator->RenderObject().m_Type != GraphObjectTypes::PathSubPath) - theTranslator = NULL; - } - } - if (theTranslator) - m_DirtySet.insert(*theTranslator); - } - return m_DirtySet.size() > 0; - } - - void TransferDirtyProperties() - { - if (m_Presentation) { - for (QT3DSU32 idx = 0, end = m_DirtySet.size(); idx < end; ++idx) { - QT3DS_ASSERT(m_DirtySet.size() == end); - m_DirtySet[idx]->OnElementChanged(*m_Presentation, *m_Context, - *m_RuntimePresentation); - } - m_DirtySet.clear(); - } - } - - bool PrepareForRender() - { - TransferDirtyProperties(); - m_LastRenderViewport = m_Context->GetRenderList().GetViewport(); - if (m_Presentation && m_Presentation->m_Scene) { - NVRenderRect theViewportSize(m_LastRenderViewport); - return m_Presentation->m_Scene->PrepareForRender( - QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), - *m_Context); - } - return false; - } - - void Render() - { - if (m_Presentation && m_Presentation->m_Scene) { - NVRenderRect theViewportSize(m_LastRenderViewport); - m_Presentation->m_Scene->Render( - QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), *m_Context, - SScene::DoNotClear); - } - } - - // Note that we do not need to call WindowToPresentation on the mouse coordinates because they - // are specifically - // supposed to be the return values from getMousePosition which applies that transformation. We - // do, however need - // to reverse part of this transformation; whatever part happens after - // m_Context->GetMousePickMouseCoords - Q3DStudio::TElement *UserPick(float mouseX, float mouseY) - { - // Note that the pick code below only calls GetMousePickMouseCoords - // while windowToPresentation subtracts the window positional offset from - // the mouse position. - // Thus we have to add it back. - QT3DSVec2 mousePos(mouseX + m_LastRenderViewport.m_X, mouseY + m_LastRenderViewport.m_Y); - - Qt3DSRenderPickResult thePickResult = m_Context->GetRenderer().Pick( - *m_Presentation->m_Scene->m_FirstChild, m_Context->GetMousePickViewport() - // GetMousePickMouseCoords is called by the renderer to setup the pick frame. - // This is so that the presentation's lastMouseX and lastMouseY variables are correctly - // setup. - , - mousePos, true, true); - - if (thePickResult.m_HitObject != NULL) { - SModel *theHitModel = - static_cast(const_cast(thePickResult.m_HitObject)); - return &Qt3DSTranslator::GetTranslatorFromGraphNode(*theHitModel)->Element(); - } - return NULL; - } - - virtual Option FacePosition(Q3DStudio::TElement &inElement, float mouseX, float mouseY, - NVDataRef inMapperElements, - Q3DStudio::FacePositionPlanes::Enum inPlane) - { - if (inElement.GetBelongedPresentation() != this->m_RuntimePresentation - && inMapperElements.size() == 0) { - return Empty(); - } - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement.GetAssociation()); - if (theTranslator == NULL) - return Empty(); - bool isValidPickObject = - GraphObjectTypes::IsNodeType(theTranslator->m_RenderObject->m_Type); - if (isValidPickObject == false) - return Empty(); - SNode &theNode = static_cast(*theTranslator->m_RenderObject); - NVBounds3 theBounds = GetNodeLocalBoundingBox(&inElement, false); - // See commens in UserPick - QT3DSVec2 mousePos(mouseX + m_LastRenderViewport.m_X, mouseY + m_LastRenderViewport.m_Y); - eastl::vector theMapperObjects(inMapperElements.size()); - for (QT3DSU32 idx = 0, end = inMapperElements.size(); idx < end; ++idx) { - Qt3DSTranslator *theMapperTranslator = - reinterpret_cast(inMapperElements[idx]->GetAssociation()); - SGraphObject *theMapperObject = NULL; - if (theMapperTranslator) { - theMapperObject = theMapperTranslator->m_RenderObject; - } - if (theMapperObject == NULL) { - QT3DS_ASSERT(false); - } else { - theMapperObjects[idx] = theMapperObject; - } - } - qt3ds::render::SBasisPlanes::Enum thePlane(qt3ds::render::SBasisPlanes::XY); - switch (inPlane) { - case Q3DStudio::FacePositionPlanes::XY: - thePlane = qt3ds::render::SBasisPlanes::XY; - break; - case Q3DStudio::FacePositionPlanes::YZ: - thePlane = qt3ds::render::SBasisPlanes::YZ; - break; - case Q3DStudio::FacePositionPlanes::XZ: - thePlane = qt3ds::render::SBasisPlanes::XZ; - break; - } - if (theBounds.isEmpty() == false) - return m_Context->GetRenderer().FacePosition( - theNode, theBounds, theNode.m_GlobalTransform, m_Context->GetMousePickViewport(), - mousePos, - NVDataRef(theMapperObjects.data(), (QT3DSU32)theMapperObjects.size()), - thePlane); - return Empty(); - } - - void Pick(Q3DStudio::SPickFrame &ioPickFrame) - { - // Presentation's m_Hide can disable rendering - bool wasPickLoggedLastFrame = m_LoggedPickLastFrame; - m_LoggedPickLastFrame = false; - if (ioPickFrame.m_InputFrame.m_PickValid) { - // If we have not already found a valid pick on a previous layer - if (!ioPickFrame.m_ResultValid && m_Presentation && m_Presentation->m_Scene - && m_Presentation->m_Scene->m_FirstChild) { - Qt3DSRenderPickResult thePickResult = m_Context->GetRenderer().Pick( - *m_Presentation->m_Scene->m_FirstChild, m_Context->GetMousePickViewport() - // GetMousePickMouseCoords is called by the renderer to setup the pick frame. - // This is so that the presentation's lastMouseX and lastMouseY variables are - // correctly setup. - , - m_Context->GetMousePickMouseCoords( - QT3DSVec2(ioPickFrame.m_InputFrame.m_PickX, ioPickFrame.m_InputFrame.m_PickY)), - true); - if (thePickResult.m_HitObject != NULL) { - SModel *theHitModel = static_cast( - const_cast(thePickResult.m_HitObject)); - ioPickFrame.m_Model = - &Qt3DSTranslator::GetTranslatorFromGraphNode(*theHitModel)->Element(); - // I don't think local hit is used any more, but not sure. If they are used, - // then the code below is probably wrong. - ioPickFrame.m_LocalHit[0] = thePickResult.m_LocalUVCoords.x; - ioPickFrame.m_LocalHit[1] = thePickResult.m_LocalUVCoords.y; - ioPickFrame.m_SquaredDistance = thePickResult.m_CameraDistanceSq; - ioPickFrame.m_ResultValid = true; - if (wasPickLoggedLastFrame == false) { - m_LoggedPickLastFrame = true; - Q3DStudio::IPresentation *thePresentation = - ioPickFrame.m_Model->GetBelongedPresentation(); - IApplication &theRuntime = thePresentation->GetApplication(); - // We are picking against the previous frame of information. - qCInfo(TRACE_INFO, "Model Picked: %s on frame %d", - theHitModel->m_Id.c_str(), - theRuntime.GetFrameCount() - 1); - } - } else { - // The scene is always picked if it is pickable; nothing else really makes - // sense. - Qt3DSTranslator *theTranslator = - Qt3DSTranslator::GetTranslatorFromGraphNode(*m_Presentation->m_Scene); - - if (theTranslator) { - ioPickFrame.m_Model = &theTranslator->Element(); - // I don't think local hit is used any more, but not sure. If they are - // used, then the code below is probably wrong. - ioPickFrame.m_LocalHit[0] = ioPickFrame.m_InputFrame.m_PickX - / m_Presentation->m_PresentationDimensions.x; - ioPickFrame.m_LocalHit[1] = 1.0f - - ioPickFrame.m_InputFrame.m_PickY - / m_Presentation->m_PresentationDimensions.y; - ioPickFrame.m_SquaredDistance = 0; - ioPickFrame.m_ResultValid = true; - } - } - } - } - } - - void SetUserData(void *inUserData) override { m_UserData = inUserData; } - void *GetUserData() override { return m_UserData; } - - // Unfortunately, you should expect the node to be dirty at this point so we may need to force - // an update - void CalculateGlobalTransform(Q3DStudio::TElement *inElement, - Q3DStudio::RuntimeMatrix &outTransform) override - { - if (inElement == NULL) { - QT3DS_ASSERT(false); - return; - } - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { - Update(); - TransferDirtyProperties(); - SNode *theNode = static_cast(&theTranslator->RenderObject()); - // Ensure the node stays dirty - bool wasDirty = theNode->m_Flags.IsDirty(); - theNode->CalculateGlobalVariables(); - theNode->m_Flags.SetDirty(wasDirty); - memCopy(outTransform.m_Data, theNode->m_GlobalTransform.front(), sizeof(QT3DSMat44)); - } else { - qCCritical(INVALID_OPERATION, "Calculate global transform called on invalide object"); - QT3DS_ASSERT(false); - } - } - - void SetLocalTransformMatrix(Q3DStudio::TElement *inElement, - const Q3DStudio::RuntimeMatrix &inTransform) override - { - if (inElement == NULL) { - QT3DS_ASSERT(false); - return; - } - - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { - SNode *theNode = static_cast(&theTranslator->RenderObject()); - QT3DSMat44 transform; - memCopy(transform.front(), inTransform.m_Data, sizeof(QT3DSMat44)); - theNode->SetLocalTransformFromMatrix(transform); - theNode->MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - } - } - - void EnsureNodeIsUpToDate(SNode &inNode, bool inIncludeChildren) - { - bool wasDirty = inNode.m_Flags.IsDirty(); - if (wasDirty) { - inNode.CalculateGlobalVariables(); - inNode.m_Flags.SetDirty(wasDirty); - if (inIncludeChildren) { - for (SNode *theChild = inNode.m_FirstChild; theChild; - theChild = theChild->m_NextSibling) - EnsureNodeIsUpToDate(*theChild, inIncludeChildren); - } - } - } - - NVBounds3 GetNodeLocalBoundingBox(Q3DStudio::TElement *inElement, bool inSelfOnly) - { - NVBounds3 retval(NVBounds3::empty()); - if (inElement == NULL) { - QT3DS_ASSERT(false); - return retval; - } - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { - Update(); - TransferDirtyProperties(); - SNode *theNode = static_cast(&theTranslator->RenderObject()); - bool theIncludeChildren = !inSelfOnly; - EnsureNodeIsUpToDate(*theNode, theIncludeChildren); - IBufferManager &theBufferManager(m_Context->GetBufferManager()); - return theNode->GetBounds(theBufferManager, m_Context->GetPathManager(), - theIncludeChildren); - } else { - qCCritical(INVALID_OPERATION, "GetBoundingBox called on invalid object"); - QT3DS_ASSERT(false); - } - return retval; - } - - static void Assign(Q3DStudio::CBoundingBox &lhs, NVBounds3 &rhs) - { - lhs.m_Min.m_X = rhs.minimum.x; - lhs.m_Min.m_Y = rhs.minimum.y; - lhs.m_Min.m_Z = rhs.minimum.z; - - lhs.m_Max.m_X = rhs.maximum.x; - lhs.m_Max.m_Y = rhs.maximum.y; - lhs.m_Max.m_Z = rhs.maximum.z; - } - - Q3DStudio::CBoundingBox GetBoundingBox(Q3DStudio::TElement *inElement, bool inSelfOnly) override - { - Q3DStudio::CBoundingBox retval; - retval.SetEmpty(); - NVBounds3 theLocalBox = GetNodeLocalBoundingBox(inElement, inSelfOnly); - if (theLocalBox.isEmpty() == false) { - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { - SNode *theNode = static_cast(&theTranslator->RenderObject()); - theLocalBox.transform(theNode->m_GlobalTransform); - Assign(retval, theLocalBox); - // Left handed nodes need to return values in their space, not in the global space - // This is a hack fix due to a bug. - if (theNode->m_Flags.IsLeftHanded()) { - eastl::swap(retval.m_Min.m_Z, retval.m_Max.m_Z); - retval.m_Min.m_Z *= -1; - retval.m_Max.m_Z *= -1; - } - } - } - return retval; - } - - Q3DStudio::CBoundingBox GetLocalBoundingBox(Q3DStudio::TElement *inElement, - bool inSelfOnly) override - { - Q3DStudio::CBoundingBox retval; - retval.SetEmpty(); - if (inElement == NULL) { - QT3DS_ASSERT(false); - return retval; - } - NVBounds3 theLocalBounds = GetNodeLocalBoundingBox(inElement, inSelfOnly); - if (theLocalBounds.isEmpty() == false) - Assign(retval, theLocalBounds); - - return retval; - } - - Q3DStudio::SCameraRect GetCameraBounds(Q3DStudio::TElement &inElem) override - { - Qt3DSTranslator *theTranslator = reinterpret_cast(inElem.GetAssociation()); - if (theTranslator && theTranslator->m_RenderObject) { - Option theRectOpt = - m_Context->GetRenderer().GetCameraBounds(*theTranslator->m_RenderObject); - if (theRectOpt.hasValue()) { - qt3ds::render::SCuboidRect theRect(*theRectOpt); - return Q3DStudio::SCameraRect(theRect.m_Left, theRect.m_Top, theRect.m_Right, - theRect.m_Bottom); - } - } - return Q3DStudio::SCameraRect(); - } - - void PositionToScreen(Q3DStudio::TElement &inElement, QT3DSVec3 &inPos, QT3DSVec3 &outScreen) override - { - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement.GetAssociation()); - if (theTranslator && theTranslator->m_RenderObject) { - SNode *theNode = reinterpret_cast(theTranslator->m_RenderObject); - QT3DSVec3 thePos = theNode->m_GlobalTransform.transform(inPos); - outScreen = m_Context->GetRenderer().ProjectPosition(*theNode, thePos); - } - } - - void ScreenToPosition(Q3DStudio::TElement &inElement, QT3DSVec3 &inScreen, QT3DSVec3 &outPos) override - { - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement.GetAssociation()); - if (theTranslator && theTranslator->m_RenderObject) { - SNode *theNode = reinterpret_cast(theTranslator->m_RenderObject); - QT3DSVec3 objPos = theNode->GetGlobalPos(); - outPos = m_Context->GetRenderer().UnprojectWithDepth(*(theNode), objPos, inScreen); - } - } - - static inline int wrapMod(int a, int base) { return (a >= 0) ? a % base : (a % base) + base; } - static inline float fMin(float a, float b) { return (a < b) ? a : b; } - static inline int iMax(int a, int b) { return (a > b) ? a : b; } - - static inline void getWrappedCoords(int &sX, int &sY, int width, int height) - { - if (sY < 0) { - sX -= width >> 1; - sY = -sY; - } - if (sY >= height) { - sX += width >> 1; - sY = height - sY; - } - sX = wrapMod(sX, width); - sY = wrapMod(sY, height); - } - - static void GenerateBsdfMipmaps(SImage *theImage, const unsigned char *inBuffer, - Q3DStudio::INT32 inBufferLength, Q3DStudio::INT32 inWidth, - Q3DStudio::INT32 inHeight, - qt3ds::render::NVRenderTextureFormats::Enum inFormat, - IQt3DSRenderContext *theContext) - { - NVRenderTextureFormats::Enum destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F; - - Qt3DSRenderPrefilterTexture *theBSDFMipMap = theImage->m_TextureData.m_BSDFMipMap; - if (theBSDFMipMap == NULL) { - theBSDFMipMap = Qt3DSRenderPrefilterTexture::Create( - &theContext->GetRenderContext(), inWidth, inHeight, - *theImage->m_TextureData.m_Texture, destFormat, theContext->GetFoundation()); - theImage->m_TextureData.m_BSDFMipMap = theBSDFMipMap; - } - - if (theBSDFMipMap) - theBSDFMipMap->Build((void *)inBuffer, inBufferLength, inFormat); - } - - // This could cause some significant drama. - void SetTextureData(Q3DStudio::TElement *inElement, const unsigned char *inBuffer, - Q3DStudio::INT32 inBufferLength, Q3DStudio::INT32 inWidth, - Q3DStudio::INT32 inHeight, - qt3ds::render::NVRenderTextureFormats::Enum inFormat, - Q3DStudio::INT32 inHasTransparency) override - { - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - if (theTranslator && theTranslator->GetUIPType() == GraphObjectTypes::Image) { - SImage *theImage = static_cast(&theTranslator->RenderObject()); - // Attempt to resolve the image's path - if (!theImage->m_TextureData.m_Texture) { - if (theImage->m_ImagePath.IsValid()) - theImage->m_TextureData = m_Context->GetBufferManager().LoadRenderImage( - theImage->m_ImagePath, false, - theImage->m_MappingMode == ImageMappingModes::LightProbe); - } - // Here we go, updating the texture. - if (theImage->m_TextureData.m_Texture) { - - if (theImage->m_MappingMode == ImageMappingModes::LightProbe) { - // theImage->m_TextureData.m_Texture->GenerateMipmaps(); - GenerateBsdfMipmaps(theImage, inBuffer, inBufferLength, inWidth, inHeight, - inFormat, m_Context); - } else - theImage->m_TextureData.m_Texture->SetTextureData( - NVDataRef((QT3DSU8 *)inBuffer, (QT3DSU32)inBufferLength), 0, inWidth, - inHeight, inFormat); - - if (inHasTransparency >= 0) { - bool hasTransparency = inHasTransparency ? true : false; - theImage->m_TextureData.m_TextureFlags.SetHasTransparency(hasTransparency); - m_Context->GetBufferManager().SetImageHasTransparency(theImage->m_ImagePath, - hasTransparency); - } - theImage->m_Flags.SetDirty(true); - } - } else { - qCCritical(INVALID_OPERATION, "SetTextureData called on object that is not an image"); - QT3DS_ASSERT(false); - } - } - - bool CreateOrSetMeshData(const char *inPathStr, unsigned char *vertData, - unsigned int numVerts, unsigned int vertStride, - unsigned int *indexData, unsigned int numIndices, - qt3ds::NVBounds3 &objBounds) override - { - SRenderMesh *theMesh = NULL; - - if (inPathStr && vertData && indexData) { - theMesh = m_Context->GetBufferManager().CreateMesh( - inPathStr, vertData, numVerts, vertStride, indexData, numIndices, objBounds); - } else { - qCCritical(INVALID_OPERATION, - "CreateOrSetMeshData was not supplied necessary buffers or object path"); - } - - return (theMesh != NULL); - } - - Q3DStudio::STextSizes MeasureText(Q3DStudio::TElement *inElement, const char *inTextStr) override - { - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - Q3DStudio::STextSizes retval; - if (theTranslator && theTranslator->GetUIPType() == GraphObjectTypes::Text) { - if (inElement->IsDirty()) { - theTranslator->OnElementChanged(*m_Presentation, *m_Context, - *m_RuntimePresentation); - } - SText *theText = static_cast(&theTranslator->RenderObject()); - if (theText) { - - STextDimensions theDimensions = - m_Context->GetTextRenderer()->MeasureText(*theText, 1.0f, inTextStr); - - retval = Q3DStudio::STextSizes((Q3DStudio::INT32)theDimensions.m_TextWidth, - (Q3DStudio::INT32)theDimensions.m_TextHeight); - } - } else { - qCCritical(INVALID_OPERATION, "MeasureText called on object that is not text"); - QT3DS_ASSERT(false); - - } - return retval; - } - - Q3DStudio::STextSizes GetPresentationDesignDimensions() override - { - if (m_Presentation) { - return Q3DStudio::STextSizes( - static_cast(m_Presentation->m_PresentationDimensions.x), - static_cast(m_Presentation->m_PresentationDimensions.y)); - } - QT3DS_ASSERT(false); - return Q3DStudio::STextSizes(); - } - - // This is the best place for now... - void GetImageInfoFromRenderEngine(Q3DStudio::TElement *inElement, - Q3DStudio::INT32 &ioWidth, Q3DStudio::INT32 &ioHeight) override - { - ioWidth = 0; - ioHeight = 0; - Qt3DSTranslator *theTranslator = - reinterpret_cast(inElement->GetAssociation()); - if (theTranslator->GetUIPType() == GraphObjectTypes::Image) { - SImage *theImage = static_cast(&theTranslator->RenderObject()); - if (theImage) { - SImageTextureData theTextureData( - m_Context->GetBufferManager().LoadRenderImage(theImage->m_ImagePath)); - if (theTextureData.m_Texture) { - STextureDetails theDetails = theTextureData.m_Texture->GetTextureDetails(); - ioWidth = theDetails.m_Width; - ioHeight = theDetails.m_Height; - } - } - } - } - - virtual Q3DStudio::SMousePosition - WindowToPresentation(const Q3DStudio::SMousePosition &inWindowCoords) override - { - // If there aren't any rotations, then account for the difference in width/height of the - // presentation and the window - QT3DSVec2 theCoords = m_Context->GetMousePickMouseCoords( - QT3DSVec2((QT3DSF32)inWindowCoords.m_X, (QT3DSF32)inWindowCoords.m_Y)); - theCoords.x -= m_LastRenderViewport.m_X; - // Note that the mouse Y is reversed. Thus a positive offset of the viewport will reduce - // the mouse value. - theCoords.y -= m_LastRenderViewport.m_Y; - return Q3DStudio::SMousePosition(theCoords.x, theCoords.y); - } - - qt3ds::foundation::CRegisteredString RegisterStr(const char *inStr) override - { - return m_Context->GetStringTable().RegisterStr(inStr); - } - - Q3DStudio::INT32 LoadImageBatch(qt3ds::foundation::CRegisteredString *inFullPaths, - Q3DStudio::INT32 inNumPaths, - qt3ds::foundation::CRegisteredString inDefaultImage, - qt3ds::render::IImageLoadListener *inLoadCallback) override - { - return static_cast(m_Context->GetImageBatchLoader().LoadImageBatch( - toConstDataRef(inFullPaths, (QT3DSU32)inNumPaths), inDefaultImage, inLoadCallback, - m_Context->GetRenderContext().GetRenderContextType(), m_Presentation->m_preferKTX)); - } - - void RegisterOffscreenRenderer(const char *inKey) override - { - m_OffscreenRenderer = QT3DS_NEW(m_Context->GetAllocator(), Qt3DSRenderSceneSubPresRenderer)( - *this, *m_Context, *m_Presentation); - m_OffscreenRendererId = m_Context->GetStringTable().RegisterStr(inKey); - m_Context->GetOffscreenRenderManager().RegisterOffscreenRenderer(m_OffscreenRendererId, - *m_OffscreenRenderer); - } - - void Release() override { NVDelete(m_Context->GetAllocator(), this); } -}; - -SOffscreenRenderFlags -Qt3DSRenderSceneSubPresRenderer::NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, - QT3DSVec2 inPresScale, - const SRenderInstanceId instanceId) -{ - m_Scene.TransferDirtyProperties(); - return CSubPresentationRenderer::NeedsRender(inEnvironment, inPresScale, instanceId); -} - -void Qt3DSRenderSceneSubPresRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, - QT3DSVec2 inPresScale, - SScene::RenderClearCommand inClearBuffer, - const SRenderInstanceId instanceId) -{ - CSubPresentationRenderer::Render(inEnvironment, inRenderContext, inPresScale, inClearBuffer, - instanceId); -} - -void Qt3DSRenderSceneSubPresRenderer::RenderWithClear( - const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, - SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, - const SRenderInstanceId id) -{ - CSubPresentationRenderer::RenderWithClear(inEnvironment, inRenderContext, - inPresScale, inClearBuffer, - inClearColor, id); -} - -////////////////////////////////////////////////////////////////// -// Scene Manager -////////////////////////////////////////////////////////////////// - -struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, - public Q3DStudio::ISceneBinaryLoader -{ - typedef nvhash_map TStrBoolMap; - - NVScopedRefCounted m_Context; - nvvector> m_Scenes; - nvvector> m_RenderPlugins; - Q3DStudio::INT32 m_ViewWidth; - Q3DStudio::INT32 m_ViewHeight; - Q3DStudio::SPickFrame m_PickFrame; - NVDataRef m_StrTableData; - // The boolean is to mark transparent images - nvvector> m_SourcePaths; - eastl::hash_set m_SourcePathSet; - - Qt3DSRenderScene *m_LastRenderedScene; - Q3DStudio::IWindowSystem &m_WindowSystem; - Mutex m_LoadingScenesMutex; - eastl::vector> m_LoadingScenes; - CRegisteredString m_ProjectDir; - CRegisteredString m_BinaryDir; - bool m_ProjectInitialized; - QT3DSI32 mRefCount; - - Qt3DSRenderSceneManager(SBindingCore &ctx, Q3DStudio::IWindowSystem &inWindowSystem) - : m_Context(ctx) - , m_Scenes(ctx.GetAllocator(), "Qt3DSRenderSceneManager::m_Scenes") - , m_RenderPlugins(ctx.GetAllocator(), "Qt3DSRenderSceneManager::m_RenderPlugins") - , m_ViewWidth(0) - , m_ViewHeight(0) - , m_SourcePaths(ctx.GetAllocator(), "Qt3DSRenderSceneManager::m_SourcePaths") - , m_LastRenderedScene(NULL) - , m_WindowSystem(inWindowSystem) - , m_LoadingScenesMutex(ctx.GetAllocator()) - , m_ProjectInitialized(false) - , mRefCount(0) - { - memZero(&m_PickFrame, sizeof(m_PickFrame)); - } - virtual ~Qt3DSRenderSceneManager() - { - for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end; ++idx) - m_Scenes[idx].second->Release(); - m_Scenes.clear(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Context->GetAllocator()) - - static QT3DSU32 GetFileTag() - { - const char *fileTag = "Qt3DSS"; - const QT3DSU32 *theTagPtr = reinterpret_cast(fileTag); - return *theTagPtr; - } - - static bool IsImage(const char *ending) - { - if (!ending) - return false; - return stricmp(ending, "jpg") == 0 || stricmp(ending, "peg") == 0 - || stricmp(ending, "png") == 0 || stricmp(ending, "dds") == 0 - || stricmp(ending, "hdr") == 0; - } - static bool IsMesh(const char *ending) - { - if (!ending) - return false; - return stricmp(ending, "mesh") == 0; - } - - void FinalizeScene(Q3DStudio::IPresentation &inPresentation, Qt3DSRenderScene &inScene) - { - inPresentation.SetScene(&inScene); - if (m_ProjectInitialized == false) { - m_ProjectInitialized = true; - if (m_Context->m_Context->GetTextRenderer()) - m_Context->m_Context->GetTextRenderer()->AddProjectFontDirectory( - inScene.m_Presentation->m_PresentationDirectory); - eastl::string theBinaryPath(inPresentation.GetFilePath().toLatin1().constData()); - qt3ds::foundation::CFileTools::AppendDirectoryInPathToFile(theBinaryPath, "binary"); - eastl::string theBinaryDir(theBinaryPath); - qt3ds::foundation::CFileTools::GetDirectory(theBinaryDir); - if (m_Context->m_WriteOutShaderCache) - qt3ds::foundation::CFileTools::CreateDir(theBinaryDir.c_str()); - } - inScene.m_RuntimePresentation = &inPresentation; - m_Scenes.push_back(make_pair(&inPresentation, &inScene)); - Qt3DSTranslator::AssignUserData(inPresentation, *inScene.m_Presentation); - } - - static const char *GetBinaryExtension() { return "uibsg"; } - - struct SPluginInstanceTableProvider : public Q3DStudio::IScriptTableProvider - { - IRenderPluginInstance &m_Instance; - SPluginInstanceTableProvider(IRenderPluginInstance &ins) - : m_Instance(ins) - { - } - void CreateTable(script_State *inState) override { m_Instance.CreateScriptProxy(inState); } - }; - - void InitializeTranslator(Qt3DSTranslator &inTranslator, Q3DStudio::IScriptBridge &inBridge) - { - if (inTranslator.m_RenderObject->m_Type == GraphObjectTypes::RenderPlugin) { - SRenderPlugin &theRenderPlugin = - static_cast(*inTranslator.m_RenderObject); - IRenderPluginInstance *thePluginInstance = - m_Context->m_Context->GetRenderPluginManager().GetOrCreateRenderPluginInstance( - theRenderPlugin.m_PluginPath, &theRenderPlugin); - if (thePluginInstance) { - SPluginInstanceTableProvider theProvider(*thePluginInstance); - inBridge.SetTableForElement(*inTranslator.m_Element, theProvider); - } - } - } - - struct SResolver : public qt3ds::render::IUIPReferenceResolver - { - IStringTable &m_StringTable; - Q3DStudio::IUIPParser &m_Parser; - SResolver(IStringTable &strt, Q3DStudio::IUIPParser &p) - : m_StringTable(strt) - , m_Parser(p) - { - } - - CRegisteredString ResolveReference(CRegisteredString inStart, - const char *inReference) override - { - eastl::string theResolvedId = m_Parser.ResolveReference(inStart, inReference); - if (theResolvedId.size()) - return m_StringTable.RegisterStr(theResolvedId.c_str()); - return CRegisteredString(); - } - }; - - Q3DStudio::IScene *LoadScene(Q3DStudio::IPresentation *inPresentation, - Q3DStudio::IUIPParser *inParser, - Q3DStudio::IScriptBridge &inBridge, - const qt3ds::Q3DSVariantConfig &variantConfig) override - { - // We have to initialize the tags late so that we can load flow data before adding anything - // to the string table. - Qt3DSTranslator::InitializePointerTags(m_Context->m_RenderContext->GetStringTable()); - NVScopedRefCounted theScene = - QT3DS_NEW(m_Context->GetAllocator(), SSceneLoadData)(m_Context->GetAllocator()); - Qt3DSRenderScene *theIScene = NULL; - if (inParser) { - QString thePath(inPresentation->GetFilePath()); - QFileInfo fileInfo(thePath); - TIdObjectMap theObjMap(m_Context->GetAllocator(), "LoadScene::theObjMap"); - SResolver theResolver(m_Context->m_CoreContext->GetStringTable(), *inParser); - - theScene->m_Presentation = IUIPLoader::LoadUIPFile( - inParser->GetDOMReader(), - fileInfo.absoluteFilePath().toLatin1().constData(), - inParser->GetMetaData(), - m_Context->m_CoreContext->GetStringTable(), - m_Context->m_RenderContext->GetFoundation(), - theScene->m_AutoAllocator, theObjMap, - m_Context->m_Context->GetBufferManager(), - m_Context->m_Context->GetEffectSystem(), - fileInfo.path().toLatin1().constData(), - m_Context->m_Context->GetRenderPluginManager(), - m_Context->m_Context->GetCustomMaterialSystem(), - m_Context->m_Context->GetDynamicObjectSystem(), - m_Context->m_Context->GetPathManager(), &theResolver, - variantConfig, false); - if (!theScene->m_Presentation) { - QT3DS_ASSERT(false); - return NULL; - } - - NVConstDataRef theSourcePathData(inParser->GetSourcePaths()); - IBufferManager &theManager(m_Context->m_Context->GetBufferManager()); - // List of image paths to be loaded in parallel at the end. - eastl::vector theSourcePathList; - for (QT3DSU32 idx = 0, end = theSourcePathData.size(); idx < end; ++idx) { - const eastl::string &theValue = theSourcePathData[idx]; - CRegisteredString theSourcePath = - m_Context->m_CoreContext->GetStringTable().RegisterStr(theValue.c_str()); - size_t theValueSize = theValue.size(); - if (theValueSize > 3) { - const char *ending = theValue.c_str() + theValueSize - 3; - CRegisteredString theObjectPath = theSourcePath; - if (IsImage(ending)) { - theManager.SetImageTransparencyToFalseIfNotSet(theObjectPath); - if (m_SourcePathSet.insert(theSourcePath).second) - m_SourcePaths.push_back(eastl::make_pair( - theSourcePath, theManager.GetImageHasTransparency(theObjectPath))); - theSourcePathList.push_back(theObjectPath); - } else if (theValue.find(".mesh") != eastl::string::npos) { - theManager.LoadMesh(theObjectPath); - } - } - } - - // Fire off parallel loading of the source paths - QT3DSU64 imageBatchId = m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( - toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), - CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() - .GetRenderContextType(), - theScene->m_Presentation->m_preferKTX); - m_Context->m_Context->GetImageBatchLoader().BlockUntilLoaded( - static_cast(imageBatchId)); - - theIScene = QT3DS_NEW(m_Context->GetAllocator(), - Qt3DSRenderScene)(*m_Context, *m_Context->m_Context, *theScene); - // Now we need to associate the presentation with everything else. - NVAllocatorCallback &translatorAllocator = theScene->m_AutoAllocator; - for (TIdObjectMap::iterator iter = theObjMap.begin(), end = theObjMap.end(); - iter != end; ++iter) { - theIScene->m_GraphObjectList.push_back(iter->second); - Q3DStudio::SElementAndType theElement = - inParser->GetElementForID(iter->first.c_str()); - if (theElement.m_Element - && theElement.m_Type != Q3DStudio::UIPElementTypes::Unknown) { - Qt3DSTranslator *theTranslator = Qt3DSTranslator::CreateTranslatorForElement( - *theElement.m_Element, *iter->second, translatorAllocator); - if (theTranslator) { - theIScene->m_DirtySet.insert(*theTranslator); - InitializeTranslator(*theTranslator, inBridge); - } - } - } - } else { - // Binary load path is quite different than normal load path and - // nothing else will load here. - QT3DS_ASSERT(false); - } - if (inPresentation && theIScene) - FinalizeScene(*inPresentation, *theIScene); - return theIScene; - } - - // threadsafe - // Can be called from any thread - bool GetBinaryLoadFileName(eastl::string &inPresentationFilename, - eastl::string &outResult) override - { - eastl::string theBinaryPath(inPresentationFilename.c_str()); - qt3ds::foundation::CFileTools::AppendDirectoryInPathToFile(theBinaryPath, "binary"); - qt3ds::foundation::CFileTools::SetExtension( - theBinaryPath, GetBinaryExtension()); // uibb: short for ui binary binding - outResult = theBinaryPath; - return true; - } - - // threadsafe - // returns a handle to the loaded object. Return value of zero means error. - qt3ds::QT3DSU32 LoadSceneStage1(CRegisteredString inPresentationDirectory, - qt3ds::render::ILoadedBuffer &inData) override - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load Scene Graph Stage 1"); - NVDataRef theLoadedData(inData.Data()); - SDataReader theReader(theLoadedData.begin(), theLoadedData.end()); - - QT3DSU32 theFileSig = theReader.LoadRef(); - QT3DSU32 theBinaryVersion = theReader.LoadRef(); - QT3DSU32 theDataSectionSize = (QT3DSU32)(theReader.m_EndPtr - theReader.m_CurrentPtr); - - if (theFileSig != GetFileTag() - || theBinaryVersion != SGraphObject::GetSceneGraphBinaryVersion()) { - QT3DS_ASSERT(false); - return 0; - } - QT3DSU32 theLoadingSceneIndex = 0; - SSceneLoadData *theScene; - { - Mutex::ScopedLock __locker(m_LoadingScenesMutex); - theLoadingSceneIndex = (QT3DSU32)m_LoadingScenes.size() + 1; - m_LoadingScenes.push_back( - QT3DS_NEW(m_Context->GetAllocator(), SSceneLoadData)(m_Context->GetAllocator())); - theScene = m_LoadingScenes.back(); - } - // preserve the data buffer because we run directly from it; there isn't a memcopy. - theScene->m_Data = inData; - - QT3DSU32 theTranslatorOffset = theReader.LoadRef(); - - NVDataRef theSGData = NVDataRef(theReader.m_CurrentPtr, theTranslatorOffset); - NVDataRef theTranslatorData = NVDataRef( - theReader.m_CurrentPtr + theTranslatorOffset, theDataSectionSize - theTranslatorOffset); - - CStrTableOrDataRef theStrTableData(m_Context->m_CoreContext->GetStringTable()); - if (m_StrTableData.size()) - theStrTableData = CStrTableOrDataRef(m_StrTableData); - - theScene->m_Presentation = SGraphObjectSerializer::Load( - theSGData, m_StrTableData, m_Context->m_CoreContext->GetDynamicObjectSystemCore(), - m_Context->m_CoreContext->GetPathManagerCore(), m_Context->GetAllocator(), - inPresentationDirectory); - if (theScene->m_Presentation) - theScene->m_Presentation->m_PresentationDirectory = inPresentationDirectory; - - theScene->m_TranslatorData = theTranslatorData; - theScene->m_SceneGraphData = theSGData; - - { - Mutex::ScopedLock __locker(m_LoadingScenesMutex); - m_LoadingScenes[theLoadingSceneIndex - 1] = theScene; - } - return theLoadingSceneIndex; - } - - // threadsafe - // still does not require openGL context but has dependency on a few other things. - void LoadSceneStage2(qt3ds::QT3DSU32 inSceneHandle, Q3DStudio::IPresentation &inPresentation, - size_t inElementMemoryOffset, Q3DStudio::IScriptBridge &inBridge) override - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load Scene Graph Stage 2"); - QT3DSU32 theSceneIndex = QT3DS_MAX_U32; - SSceneLoadData *theScene; - { - Mutex::ScopedLock __locker(m_LoadingScenesMutex); - QT3DSU32 numLoadingScenes = (QT3DSU32)m_LoadingScenes.size(); - if (inSceneHandle && inSceneHandle <= numLoadingScenes) { - theSceneIndex = inSceneHandle - 1; - theScene = m_LoadingScenes[theSceneIndex]; - } else { - QT3DS_ASSERT(false); - return; - } - } - SDataReader theReader(theScene->m_TranslatorData.begin(), theScene->m_TranslatorData.end()); - QT3DSU32 theNumTranslators = theReader.LoadRef(); - theScene->m_Translators.resize(theNumTranslators); - theScene->m_RuntimePresentation = &inPresentation; - for (QT3DSU32 idx = 0, end = theNumTranslators; idx < end; ++idx) { - Qt3DSTranslator *theTranslator = Qt3DSTranslator::LoadTranslator( - theReader, inElementMemoryOffset, theScene->m_SceneGraphData, - theScene->m_AutoAllocator); - if (theTranslator) { - InitializeTranslator(*theTranslator, inBridge); - } - theScene->m_Translators[idx] = theTranslator; - } - } - - void OnGraphicsInitialized() - { - QT3DS_ASSERT(m_Context->m_Context.mPtr); - // this means graphics have been initialized - eastl::string theSourcePathStr; - IBufferManager &theManager(m_Context->m_Context->GetBufferManager()); - nvvector theSourcePathList(m_Context->GetAllocator(), - "TempSourcePathList"); - for (QT3DSU32 idx = 0, end = m_SourcePaths.size(); idx < end; ++idx) { - theSourcePathStr.assign(m_SourcePaths[idx].first); - bool hasTransparency = m_SourcePaths[idx].second; - if (theSourcePathStr.size() > 4) { - CRegisteredString theObjectPath = m_SourcePaths[idx].first; - const char *theEnding = theSourcePathStr.c_str() + theSourcePathStr.size() - 3; - if (IsImage(theEnding)) { - theManager.SetImageHasTransparency(theObjectPath, hasTransparency); - theSourcePathList.push_back(theObjectPath); - } else { - if (theSourcePathStr.find(".mesh") != eastl::string::npos) - theManager.LoadMesh(theObjectPath); - } - } - } - - bool pktx = false; - for (int i = 0; i < m_Scenes.size(); ++i) { - if (m_Scenes[i].second->m_Presentation->m_preferKTX) { - pktx = true; - break; - } - } - - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Initial Batch Image Load"); - - m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( - toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), - CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() - .GetRenderContextType(), pktx); - } - - { - - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Initialize Scenes"); - for (QT3DSU32 idx = 0, end = m_LoadingScenes.size(); idx < end; ++idx) { - SSceneLoadData &theScene = *m_LoadingScenes[idx]; - // m_Context->m_Foundation->error( QT3DS_WARN, "Finalizing scene %d", (int)idx+1 ); - if (theScene.m_RuntimePresentation) { - Qt3DSRenderScene *theIScene = QT3DS_NEW(m_Context->GetAllocator(), Qt3DSRenderScene)( - *m_Context, *m_Context->m_Context, theScene); - FinalizeScene(*theScene.m_RuntimePresentation, *theIScene); - } else { - qCWarning(WARNING, "Failed to finalize scene %d", (int)idx + 1); - } - } - } - } - - void LoadRenderPlugin(const char *inAssetIDString, const char *inPath, - const char *inArgs) override - { - Q3DStudio::CDLLManager &theDLLManager = Q3DStudio::CDLLManager::GetDLLManager(); - long theHandle = theDLLManager.LoadLibrary(inPath, EDLLTYPE_RENDERABLE_PLUGIN); - if (theHandle >= 0) { - qt3ds::render::IOffscreenRenderer *theOffscreenRenderer = - QT3DS_NEW(m_Context->GetAllocator(), - qt3ds::render::COldNBustedPluginRenderer)(*m_Context->m_Context, theHandle); - qt3ds::foundation::CRegisteredString theAssetString = - m_Context->m_CoreContext->GetStringTable().RegisterStr(inAssetIDString); - - m_Context->m_Context->GetOffscreenRenderManager().RegisterOffscreenRenderer( - theAssetString, *theOffscreenRenderer); - - PROC_Initialize theInitializeProc = - reinterpret_cast(theDLLManager.GetProc("Initialize", theHandle)); - Q3DStudio_ASSERT(theInitializeProc); -#if !defined (Q_OS_MACOS) - PROC_SetEGLInfo theSetEGLInfoProc = - reinterpret_cast(theDLLManager.GetProc("SetEGLInfo", theHandle)); - // Set EGL parameters used for optional context creation - if (theSetEGLInfoProc) { - Q3DStudio::SEGLInfo *theInfo = m_WindowSystem.GetEGLInfo(); - if (theInfo) - theSetEGLInfoProc(theInfo->display, theInfo->context, theInfo->surface, - theInfo->config); - } -#endif - if (theInitializeProc && theInitializeProc(inArgs) == EDLLSTATUS_OK) - m_RenderPlugins.push_back(make_pair(theAssetString, theHandle)); - else - qCWarning(qt3ds::INVALID_OPERATION) << "Unable to load plugin " << inAssetIDString; - } else - qCWarning(qt3ds::INVALID_OPERATION) << "Unable to load plugin " << inAssetIDString; - - return; - } - - void LoadQmlStreamerPlugin(const char *inAssetIDString) override - { - qt3ds::render::IOffscreenRenderer *theOffscreenRenderer = - QT3DS_NEW(m_Context->GetAllocator(), - Q3DSQmlRender)(*m_Context->m_Context, inAssetIDString); - if (theOffscreenRenderer) { - qt3ds::foundation::CRegisteredString theAssetString = - m_Context->m_CoreContext->GetStringTable().RegisterStr(inAssetIDString); - m_Context->m_Context->GetOffscreenRenderManager().RegisterOffscreenRenderer( - SOffscreenRendererKey(theAssetString), *theOffscreenRenderer); - - m_RenderPlugins.push_back(make_pair(theAssetString, 0)); - } - } - - void BinarySave(Q3DStudio::IScene &inScene) override - { - Qt3DSRenderScene &theScene = static_cast(inScene); - qt3ds::render::SWriteBuffer theWriteBuffer(m_Context->GetAllocator(), "BinarySaveBuffer"); - qt3ds::render::SPtrOffsetMap theSGOffsetMap(m_Context->GetAllocator(), "PointerOffsetMap"); - // Start with some versioning and sanity checks. - theWriteBuffer.write(GetFileTag()); - theWriteBuffer.write(SGraphObject::GetSceneGraphBinaryVersion()); - QT3DSU32 theTranslatorOffsetAddress = theWriteBuffer.size(); - // Now the data section starts. Offsets should be relative to here, not the first - // 8 bytes. - theWriteBuffer.writeZeros(4); // offset where the translator data starts; - QT3DSU32 theDataSectionStart = theWriteBuffer.size(); - - // These offsets are after we have read in the data section - SGraphObjectSerializer::Save( - m_Context->m_RenderContext->GetFoundation(), *theScene.m_Presentation, theWriteBuffer, - m_Context->m_Context->GetDynamicObjectSystem(), - m_Context->m_Context->GetPathManager(), theSGOffsetMap, - m_Context->m_CoreContext->GetStringTable(), theScene.m_GraphObjectList); - - theWriteBuffer.align(sizeof(void *)); - QT3DSU32 theTranslatorCountAddress = theWriteBuffer.size(); - QT3DSU32 theTranslatorOffset = theTranslatorCountAddress - theDataSectionStart; - - theWriteBuffer.writeZeros(4); - // Now write out the translators verbatim. We get an adjustment parameter on save that - // allows a translation - // from old element ptr->new element ptr. - QT3DSU32 theTranslatorCount = 0; - for (QT3DSU32 idx = 0, end = theScene.m_GraphObjectList.size(); idx < end; ++idx) { - Qt3DSTranslator *theTranslator = - Qt3DSTranslator::GetTranslatorFromGraphNode(*theScene.m_GraphObjectList[idx]); - // Presentation nodes don't have translator - if (theTranslator) { - qt3ds::render::SPtrOffsetMap::iterator theIter = - theSGOffsetMap.find(theScene.m_GraphObjectList[idx]); - if (theIter != theSGOffsetMap.end()) { - QT3DSU32 theOffset = theIter->second; - theTranslator->Save(theWriteBuffer, theOffset); - ++theTranslatorCount; - } else { - QT3DS_ASSERT(false); - } - } - } - QT3DSU32 *theTranslatorCountPtr = - reinterpret_cast(theWriteBuffer.begin() + theTranslatorCountAddress); - *theTranslatorCountPtr = theTranslatorCount; - QT3DSU32 *theTranslatorOffsetPtr = - reinterpret_cast(theWriteBuffer.begin() + theTranslatorOffsetAddress); - *theTranslatorOffsetPtr = theTranslatorOffset; - - Q3DStudio::IPresentation &thePresentation = *theScene.m_RuntimePresentation; - eastl::string theBinaryPath(thePresentation.GetFilePath().toLatin1().constData()); - qt3ds::foundation::CFileTools::AppendDirectoryInPathToFile(theBinaryPath, "binary"); - eastl::string theBinaryDir(theBinaryPath); - qt3ds::foundation::CFileTools::GetDirectory(theBinaryDir); - qt3ds::foundation::CFileTools::SetExtension( - theBinaryPath, GetBinaryExtension()); // uibb: short for ui binary binding - - Q3DStudio::CFileStream theStream(theBinaryPath.c_str(), "wb"); - if (theStream.IsOpen() == false) { - QT3DS_ASSERT(false); - } - - theStream.WriteRaw(theWriteBuffer.begin(), theWriteBuffer.size()); - theStream.Close(); - } - - // We save in the reverse order that we load because the effect system may add strings - // to the string table when it is writing its data out, this the string table needs to come - // last. - // Loading, obviously, the string table needs to be the first object loaded. - void BinarySaveManagerData(qt3ds::foundation::IOutStream &inStream, - const char *inBinaryDir) override - { - qt3ds::render::SWriteBuffer theWriteBuffer(m_Context->GetAllocator(), "BinarySaveBuffer"); - IStringTable &theStrTable = m_Context->m_CoreContext->GetStringTable(); - eastl::string theProjectDir(inBinaryDir); - qt3ds::foundation::CFileTools::GetDirectory(theProjectDir); - - // We save everything before the string table because often times saving something creates - // new strings. - theWriteBuffer.writeZeros(4); // Total data size - // Dynamic object system - theWriteBuffer.writeZeros(4); // Effect system offset - // effect system - theWriteBuffer.writeZeros(4); // Material system offset - // material system - theWriteBuffer.writeZeros(4); // Binary path offset - // binary path data - theWriteBuffer.writeZeros(4); // Plugin manager offset - // plugin manager - theWriteBuffer.writeZeros(4); // String system offset - // string system last. - QT3DSU32 theOffsetStart = theWriteBuffer.size(); - m_Context->m_Context->GetDynamicObjectSystem().Save( - theWriteBuffer, theStrTable.GetRemapMap(), theProjectDir.c_str()); - theWriteBuffer.align(sizeof(void *)); - QT3DSU32 theEffectSystemOffset = theWriteBuffer.size() - theOffsetStart; - m_Context->m_Context->GetEffectSystem().Save(theWriteBuffer, theStrTable.GetRemapMap(), - theProjectDir.c_str()); - theWriteBuffer.align(sizeof(void *)); - QT3DSU32 theMaterialSystemOffset = theWriteBuffer.size() - theOffsetStart; - m_Context->m_Context->GetCustomMaterialSystem().Save( - theWriteBuffer, theStrTable.GetRemapMap(), theProjectDir.c_str()); - QT3DSU32 theBinaryPathOffset = theWriteBuffer.size() - theOffsetStart; - - theWriteBuffer.write((QT3DSU32)m_SourcePaths.size()); - for (nvvector>::iterator iter = m_SourcePaths.begin(), - end = m_SourcePaths.end(); - iter != end; ++iter) { - CRegisteredString theStr(iter->first); - theStr.Remap(theStrTable.GetRemapMap()); - theWriteBuffer.write((size_t)theStr.c_str()); - QT3DSU32 theSourcePathFlags = iter->second ? 1 : 0; - theWriteBuffer.write(theSourcePathFlags); - } - - QT3DSU32 thePluginManagerOffset = theWriteBuffer.size() - theOffsetStart; - - m_Context->m_Context->GetRenderPluginManager().Save( - theWriteBuffer, theStrTable.GetRemapMap(), theProjectDir.c_str()); - - QT3DSU32 theStringTableOffset = theWriteBuffer.size() - theOffsetStart; - - theStrTable.Save(theWriteBuffer); - - QT3DSU32 *theSizePtr = reinterpret_cast(theWriteBuffer.begin()); - - theSizePtr[0] = theWriteBuffer.size() - 4; // overall size - theSizePtr[1] = theEffectSystemOffset; - theSizePtr[2] = theMaterialSystemOffset; - theSizePtr[3] = theBinaryPathOffset; // thePathOffset - theSizePtr[4] = thePluginManagerOffset; - theSizePtr[5] = theStringTableOffset; - - inStream.Write(theWriteBuffer.begin(), theWriteBuffer.size()); - } - - NVDataRef BinaryLoadManagerData(qt3ds::foundation::IInStream &inStream, - const char *inBinaryDir) override - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - String Table + Render Objects"); - QT3DS_ASSERT(m_Context->m_FlowData == NULL); - QT3DSU32 dataSize = 0; - inStream.Read(dataSize); - m_Context->m_FlowData = (QT3DSU8 *)m_Context->m_CoreContext->GetAllocator().allocate( - dataSize, "SceneManager::BinaryFlowData", __FILE__, __LINE__); - - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - Initial Data Load"); - inStream.Read(m_Context->m_FlowData, dataSize); - } - SDataReader theReader(m_Context->m_FlowData, m_Context->m_FlowData + dataSize); - QT3DSU32 theEffectSystemOffset = theReader.LoadRef(); - QT3DSU32 theMaterialSystemOffset = theReader.LoadRef(); - QT3DSU32 theBinaryPathOffset = theReader.LoadRef(); - QT3DSU32 thePluginManagerOffset = theReader.LoadRef(); - QT3DSU32 theStringTableOffset = theReader.LoadRef(); - QT3DSU8 *theStartOffset = theReader.m_CurrentPtr; - IStringTable &theStrTable = m_Context->m_CoreContext->GetStringTable(); - - // Load string table. - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - Load String Table"); - m_StrTableData = toDataRef(theReader.m_CurrentPtr + theStringTableOffset, - dataSize - theStringTableOffset); - theStrTable.Load(m_StrTableData); - } - - // Load source paths to preload heavy data - theReader.m_CurrentPtr = theStartOffset + theBinaryPathOffset; - QT3DSU32 theNumSourcePaths = theReader.LoadRef(); - eastl::string theSourcePathStr; - eastl::string theProjectDir(inBinaryDir); - eastl::string theShaderCacheDir(inBinaryDir); - - // Up one moves to the project directory. - qt3ds::foundation::CFileTools::GetDirectory(theProjectDir); - const char8_t *theBasePath(theProjectDir.c_str()); - - m_ProjectDir = theStrTable.RegisterStr(theProjectDir.c_str()); - m_BinaryDir = theStrTable.RegisterStr(theShaderCacheDir.c_str()); - - // Preload the heavy buffers - m_SourcePaths.resize(theNumSourcePaths); - for (QT3DSU32 idx = 0, end = theNumSourcePaths; idx < end; ++idx) { - CRegisteredString thePath = theReader.LoadRef(); - QT3DSU32 theFlags = theReader.LoadRef(); - thePath.Remap(m_StrTableData); - bool theBoolFlagValue = theFlags ? true : false; - m_SourcePaths[idx] = eastl::make_pair(thePath, theBoolFlagValue); - } - - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - Base Dynamic System"); - // Load effect system. - NVDataRef theDynamicSystemData(theStartOffset, theEffectSystemOffset); - m_Context->m_CoreContext->GetDynamicObjectSystemCore().Load( - theDynamicSystemData, m_StrTableData, theBasePath); - } - - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - Effect System"); - NVDataRef theEffectSystemData(theStartOffset + theEffectSystemOffset, - theMaterialSystemOffset - theEffectSystemOffset); - m_Context->m_CoreContext->GetEffectSystemCore().Load(theEffectSystemData, - m_StrTableData, theBasePath); - } - - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - Material System"); - NVDataRef theMaterialSystemData(theStartOffset + theMaterialSystemOffset, - thePluginManagerOffset - theMaterialSystemOffset); - m_Context->m_CoreContext->GetMaterialSystemCore().Load(theMaterialSystemData, - m_StrTableData, theBasePath); - } - - { - SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), - "Load UIAB - Plugin Manager Data"); - NVDataRef thePluginManagerData(theStartOffset + thePluginManagerOffset, - theStringTableOffset - thePluginManagerOffset); - m_Context->m_CoreContext->GetRenderPluginCore().Load(thePluginManagerData, - m_StrTableData, theBasePath); - } - - return m_StrTableData; - } - - virtual void DeleteScene(Q3DStudio::IPresentation *inPresentation) - { - QT3DSU32 idx; - QT3DSU32 end; - for (idx = 0, end = m_Scenes.size(); idx < end; ++idx) { - if (m_Scenes[idx].first == inPresentation) - break; - } - if (idx < m_Scenes.size()) { - m_Scenes[idx].second->Release(); - m_Scenes.erase(m_Scenes.begin() + idx); - } - } - - Q3DStudio::BOOL Update() override - { - bool theResult = false; - long theSceneCount = m_Scenes.size(); - for (long theSceneIndex = 0; theSceneIndex < theSceneCount; ++theSceneIndex) { - Qt3DSRenderScene *theScene = m_Scenes[theSceneIndex].second; - theResult |= theScene->Update(); - } - return theResult; - } - - Q3DStudio::BOOL RenderPresentation(Q3DStudio::IPresentation *inPresentation) override - { - Qt3DSRenderScene *theFirstScene = NULL; - for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end && theFirstScene == NULL; ++idx) - if (m_Scenes[idx].second->m_RuntimePresentation == inPresentation) - theFirstScene = m_Scenes[idx].second; - - if (theFirstScene && theFirstScene->m_Presentation) { - m_LastRenderedScene = theFirstScene; - if (theFirstScene->m_Presentation->m_Scene - && theFirstScene->m_Presentation->m_Scene->m_UseClearColor) { - m_Context->m_Context->SetSceneColor( - QT3DSVec4(theFirstScene->m_Presentation->m_Scene->m_ClearColor, 1.0f)); - } else - m_Context->m_Context->SetSceneColor(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - - // Setup the render rotation *before* rendering so that the magic can happen on begin - // render. - if (m_Context->m_RenderRotationsEnabled) - m_Context->m_Context->SetRenderRotation( - theFirstScene->m_Presentation->m_PresentationRotation); - else - m_Context->m_Context->SetRenderRotation(RenderRotationValues::NoRotation); - - m_Context->m_Context->SetPresentationDimensions(QSize( - (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.x, - (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.y)); - } - - m_Context->m_Context->BeginFrame(); - m_Context->m_RenderContext->ResetBlendState(); - - // How exactly does this work, I have no idea. - // Should we only render the first scene and not every scene, perhaps? - bool wasDirty = false; - if (theFirstScene) - wasDirty = theFirstScene->PrepareForRender(); - else { - m_Context->m_RenderContext->SetClearColor(QT3DSVec4(0, 0, 0, 0)); - m_Context->m_RenderContext->Clear(qt3ds::render::NVRenderClearFlags( - NVRenderClearValues::Color | NVRenderClearValues::Depth)); - } - m_Context->m_Context->RunRenderTasks(); - if (theFirstScene) - theFirstScene->Render(); - - m_Context->m_Context->EndFrame(); - - return wasDirty; - } - // I think render::check resize is called so this isn't necessary - void OnViewResize(Q3DStudio::INT32 inViewWidth, Q3DStudio::INT32 inViewHeight) override - { - m_ViewWidth = inViewWidth; - m_ViewHeight = inViewHeight; - } - void GetViewSize(Q3DStudio::INT32 &outWidth, Q3DStudio::INT32 &outHeight) override - { - outWidth = m_ViewWidth; - outHeight = m_ViewHeight; - } - - Q3DStudio::STextSizes GetDisplayDimensions(Q3DStudio::IPresentation *inPresentation) override - { - Qt3DSRenderScene *theFirstScene = NULL; - for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end && theFirstScene == NULL; ++idx) - if (m_Scenes[idx].second->m_RuntimePresentation == inPresentation) - theFirstScene = m_Scenes[idx].second; - if (theFirstScene) { - m_Context->m_Context->SetPresentationDimensions(QSize( - (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.x, - (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.y)); - render::NVRenderRectF theDisplayViewport = - m_Context->m_Context->GetDisplayViewport(); - return Q3DStudio::STextSizes( - static_cast(theDisplayViewport.m_Width), - static_cast(theDisplayViewport.m_Height)); - } - return Q3DStudio::STextSizes(static_cast(0), - static_cast(0)); - } - - Q3DStudio::TElement *UserPick(float mouseX, float mouseY) override - { - if (m_LastRenderedScene) { - return m_LastRenderedScene->UserPick(mouseX, mouseY); - } - return NULL; - } - - Option FacePosition(Q3DStudio::TElement &inElement, float mouseX, float mouseY, - NVDataRef inElements, - Q3DStudio::FacePositionPlanes::Enum inPlane) override - { - if (m_LastRenderedScene) { - - return m_LastRenderedScene->FacePosition(inElement, mouseX, mouseY, inElements, - inPlane); - } - return Empty(); - } - - Q3DStudio::SPickFrame AdvancePickFrame(const Q3DStudio::SInputFrame &inInputFrame) override - { - // We now have a new input frame, and our results are invalid but ready to be filled - m_PickFrame.m_InputFrame = inInputFrame; - m_PickFrame.m_Model = NULL; - m_PickFrame.m_ResultValid = false; - if (m_LastRenderedScene) { - if (m_PickFrame.m_InputFrame.m_PickValid) - m_LastRenderedScene->Pick(m_PickFrame); - } - return m_PickFrame; - } - - void Release() override - { - long theRenderPluginSize = m_RenderPlugins.size(); - Q3DStudio::CDLLManager &theDLLManager = Q3DStudio::CDLLManager::GetDLLManager(); - for (int theRenderPluginIndex = 0; theRenderPluginIndex < theRenderPluginSize; - ++theRenderPluginIndex) { - long theDLLHandle = m_RenderPlugins[theRenderPluginIndex].second; - PROC_Uninitialize theUninitializeProc = reinterpret_cast( - theDLLManager.GetProc("Uninitialize", theDLLHandle)); - Q3DStudio_ASSERT(theUninitializeProc); - theUninitializeProc &&theUninitializeProc(); - - theDLLManager.UnloadLibrary(theDLLHandle); - } - - // Ensure the binding core doesn't get released until after we get released. - NVScopedRefCounted theContext(m_Context); - NVDelete(m_Context->GetAllocator(), this); - } -}; - -struct SRenderFactory; - -struct SVisualStateHandler : public qt3ds::state::IVisualStateInterpreterFactory, - public qt3ds::state::IVisualStateCommandHandler -{ - NVAllocatorCallback &m_Allocator; - QT3DSI32 mRefCount; - SRenderFactory &m_Factory; - -public: - SVisualStateHandler(NVAllocatorCallback &alloc, SRenderFactory &inFactory) - : m_Allocator(alloc) - , mRefCount(0) - , m_Factory(inFactory) - { - } - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Allocator) - - void Handle(const qt3ds::state::SVisualStateCommand &inCommand, - qt3ds::state::IScriptContext &inScriptContext) override; -}; - -struct SRenderFactory : public IQt3DSRenderFactoryCore, public IQt3DSRenderFactory -{ - NVScopedRefCounted m_Context; - - NVScopedRefCounted m_ScriptBridgeQml; - NVScopedRefCounted m_SceneManager; - NVScopedRefCounted m_VisualStateContext; - NVScopedRefCounted m_EventSystem; - qt3ds::runtime::IApplicationCore *m_ApplicationCore; - qt3ds::runtime::IApplication *m_Application; - QT3DSI32 m_RefCount; - - SRenderFactory(SBindingCore &inCore) - : m_Context(inCore) - , m_ScriptBridgeQml(NULL) - , m_SceneManager(NULL) - , m_ApplicationCore(NULL) - , m_Application(NULL) - , m_RefCount(0) - { - } - - ~SRenderFactory() - { - using namespace Q3DStudio; - // Release the visual state context. - m_VisualStateContext = NULL; - // Release the event system, it must be released before script engine - m_EventSystem = NULL; - m_ScriptBridgeQml->Shutdown(*m_Context->m_Foundation); - } - - void addRef() override { atomicIncrement(&m_RefCount); } - - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVScopedRefCounted theContext(m_Context); - NVDelete(m_Context->GetAllocator(), this); - } - } - - qt3ds::render::IQt3DSRenderContextCore &GetRenderContextCore() override - { - return *m_Context->m_CoreContext; - } - - qt3ds::runtime::IApplicationCore *GetApplicationCore() override { return m_ApplicationCore; } - void SetApplicationCore(qt3ds::runtime::IApplicationCore *app) override - { - m_ApplicationCore = app; - } - - Q3DStudio::ISceneBinaryLoader &GetSceneLoader() override - { - if (m_SceneManager == NULL) - m_SceneManager = QT3DS_NEW(m_Context->GetAllocator(), - Qt3DSRenderSceneManager)(*m_Context, m_Context->m_WindowSystem); - return *m_SceneManager; - } - - Q3DStudio::ITegraApplicationRenderEngine &CreateRenderEngine() override - { - return m_Context->CreateRenderer(); - } - Q3DStudio::ISceneManager &GetSceneManager() override - { - if (m_SceneManager == NULL) - m_SceneManager = QT3DS_NEW(m_Context->GetAllocator(), - Qt3DSRenderSceneManager)(*m_Context, m_Context->m_WindowSystem); - return *m_SceneManager; - } - Q3DStudio::IScriptBridge &GetScriptEngineQml() override - { - if (m_ScriptBridgeQml == NULL) { - m_ScriptBridgeQml = - Q3DStudio::CQmlEngine::Create(*m_Context->m_Foundation, m_Context->m_TimeProvider); - } - - return *m_ScriptBridgeQml; - } - qt3ds::render::IInputStreamFactory &GetInputStreamFactory() override - { - return m_Context->m_CoreContext->GetInputStreamFactory(); - } - - qt3ds::render::IQt3DSRenderContext &GetQt3DSRenderContext() override - { - return *m_Context->m_Context; - } - qt3ds::state::IVisualStateContext &GetVisualStateContext() override - { - if (!m_VisualStateContext) { - m_VisualStateContext = qt3ds::state::IVisualStateContext::Create( - *m_Context->m_Foundation, m_Context->m_CoreContext->GetStringTable()); - SVisualStateHandler *newHandle = - QT3DS_NEW(m_Context->m_Foundation->getAllocator(), - SVisualStateHandler)(m_Context->m_Foundation->getAllocator(), *this); - m_VisualStateContext->SetCommandHandler(newHandle); - m_VisualStateContext->SetInterpreterFactory(newHandle); - } - return *m_VisualStateContext; - } - qt3ds::evt::IEventSystem &GetEventSystem() override - { - if (!m_EventSystem) { - m_EventSystem = qt3ds::evt::IEventSystem::Create(*m_Context->m_Foundation); - } - return *m_EventSystem; - } - Q3DStudio::ITimeProvider &GetTimeProvider() override { return m_Context->m_TimeProvider; } - qt3ds::foundation::IStringTable &GetStringTable() override - { - return m_Context->m_CoreContext->GetStringTable(); - } - qt3ds::NVFoundationBase &GetFoundation() override { return *m_Context->m_Foundation.mPtr; } - qt3ds::foundation::IPerfTimer &GetPerfTimer() override - { - return m_Context->m_CoreContext->GetPerfTimer(); - } - qt3ds::runtime::IApplication *GetApplication() override { return m_Application; } - void SetApplication(qt3ds::runtime::IApplication *app) override - { - m_Application = app; - if (app) { - // QML engine - GetScriptEngineQml(); - m_ScriptBridgeQml->SetApplication(*app); - m_ScriptBridgeQml->Initialize(); - } - } - void SetDllDir(const char *dllDir) override - { - m_Context->m_CoreContext->GetRenderPluginCore().SetDllDir(dllDir); - } - - void AddSearchPath(const char8_t *inFile) override - { - m_Context->m_CoreContext->GetInputStreamFactory().AddSearchDirectory(inFile); - } - virtual void Release() { NVDelete(m_Context->GetAllocator(), this); } - - struct SContextTypeRenderFactory : public IRuntimeFactoryRenderFactory - { - QSurfaceFormat format; - SContextTypeRenderFactory(const QSurfaceFormat &fmt) - : format(fmt) - { - } - - qt3ds::render::NVRenderContext *CreateRenderContext(qt3ds::NVFoundationBase &foundat, - IStringTable &strt) override - { -#ifndef Qt3DS_NO_RENDER_SYMBOLS - qt3ds::render::NVRenderContext &retval = NVRenderContext::CreateGL(foundat, strt, format); - return &retval; -#else - qt3ds::render::NVRenderContext &retval = NVRenderContext::CreateNULL(foundat, strt); - return &retval; -#endif - } - }; - - IQt3DSRenderFactory &CreateRenderFactory(const QSurfaceFormat& format) override - { - - SContextTypeRenderFactory theContextFactory(format); - m_Context->CreateRenderContext(theContextFactory); - - GetSceneLoader(); - { - SStackPerfTimer __loadTimer(GetPerfTimer(), "SceneManager OnGraphicsInitialized"); - m_SceneManager->OnGraphicsInitialized(); - } - return *this; - } -}; - -Q3DStudio::SScriptEngineGotoSlideArgs ToEngine(const qt3ds::state::SGotoSlideData &inData) -{ - using namespace qt3ds::state; - Q3DStudio::SScriptEngineGotoSlideArgs retval; - if (inData.m_Mode.hasValue()) { - switch (*inData.m_Mode) { - case SlidePlaybackModes::StopAtEnd: - retval.m_Mode = Q3DStudio::TimePolicyModes::StopAtEnd; - break; - case SlidePlaybackModes::Looping: - retval.m_Mode = Q3DStudio::TimePolicyModes::Looping; - break; - case SlidePlaybackModes::Ping: - retval.m_Mode = Q3DStudio::TimePolicyModes::Ping; - break; - case SlidePlaybackModes::PingPong: - retval.m_Mode = Q3DStudio::TimePolicyModes::PingPong; - break; - default: - QT3DS_ASSERT(false); - break; - } - } - if (inData.m_PlaythroughTo.hasValue()) - retval.m_PlaythroughTo = inData.m_PlaythroughTo->c_str(); - if (inData.m_Paused.hasValue()) - retval.m_Paused = inData.m_Paused; - retval.m_Rate = inData.m_Rate; - retval.m_Reverse = inData.m_Reverse; - if (inData.m_StartTime.hasValue()) - retval.m_StartTime = *inData.m_StartTime; - return retval; -} - -class CStateScriptEngineCallFunctionArgRetriever - : public Q3DStudio::CScriptEngineCallFunctionArgRetriever -{ -public: - CStateScriptEngineCallFunctionArgRetriever(const char *inArguments, - qt3ds::state::IScriptContext &inScriptContext) - : CScriptEngineCallFunctionArgRetriever(inArguments) - , m_ScriptContext(inScriptContext) - { - } - int RetrieveArgument(script_State *inState) override - { - (void *)inState; - return m_ScriptContext.ExecuteStr(m_ArgumentString, true) ? 1 : -1; - } - -private: - qt3ds::state::IScriptContext &m_ScriptContext; -}; - -void SVisualStateHandler::Handle(const qt3ds::state::SVisualStateCommand &inCommand, - qt3ds::state::IScriptContext &inScriptContext) -{ - using namespace qt3ds::state; - switch (inCommand.getType()) { - case VisualStateCommandTypes::GotoSlide: { - const SGotoSlide &theInfo(inCommand.getData()); - m_Factory.m_ScriptBridgeQml->GotoSlide(theInfo.m_Component.c_str(), - theInfo.m_Slide.c_str(), - ToEngine(theInfo.m_GotoSlideData)); - } break; - case VisualStateCommandTypes::SetAttribute: { - const SSetAttribute &theInfo(inCommand.getData()); - m_Factory.m_ScriptBridgeQml->SetAttribute( - theInfo.m_Element.c_str(), theInfo.m_Attribute.c_str(), - theInfo.m_Value.c_str()); - } break; - case VisualStateCommandTypes::GotoSlideRelative: { - const SGotoSlideRelative &theInfo(inCommand.getData()); - if (theInfo.m_Direction == SGotoSlideRelative::Error) { - qCCritical(INVALID_OPERATION, - "Goto slide relative has invalid attribute (neither 'next' nor 'previous')"); - } else { - m_Factory.m_ScriptBridgeQml->GotoSlideRelative( - theInfo.m_Component.c_str(), - theInfo.m_Direction == SGotoSlideRelative::Next, - theInfo.m_Wrap, ToEngine(theInfo.m_GotoSlideData)); - } - } break; - case VisualStateCommandTypes::FireEvent: { - const SFireEvent &theInfo(inCommand.getData()); - m_Factory.m_ScriptBridgeQml->FireEvent(theInfo.m_Element, theInfo.m_Event); - } break; - case VisualStateCommandTypes::PresentationAttribute: { - const SPresentationAttribute &theInfo(inCommand.getData()); - m_Factory.m_ScriptBridgeQml->SetPresentationAttribute(theInfo.m_Presentation, - theInfo.m_Attribute, - theInfo.m_Value); - } break; - case VisualStateCommandTypes::PlaySound: { - const SPlaySound &theInfo(inCommand.getData()); - m_Factory.m_ScriptBridgeQml->PlaySoundFile(theInfo.m_SoundFilePath); - } break; - default: - QT3DS_ASSERT(false); - break; - } -} -} - -IQt3DSRenderFactoryCore &IQt3DSRenderFactoryCore::CreateRenderFactoryCore( - const char8_t *inApplicationDirectory, - Q3DStudio::IWindowSystem &inWindowSystem, - Q3DStudio::ITimeProvider &inTimeProvider) -{ - SBindingCore *theCore = (SBindingCore *)malloc(sizeof(SBindingCore)); - new (theCore) SBindingCore(inApplicationDirectory, inWindowSystem, inTimeProvider); - return *QT3DS_NEW(theCore->GetAllocator(), SRenderFactory)(*theCore); -} diff --git a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplRenderer.cpp b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplRenderer.cpp deleted file mode 100644 index eff57579..00000000 --- a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplRenderer.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "EnginePrefix.h" -#include "Qt3DSRenderRuntimeBindingImpl.h" -#include "Qt3DSTegraApplication.h" -#include "Qt3DSWindowSystem.h" -#include "Qt3DSRenderLoadedTexture.h" - -struct SRenderer; -struct SRendererRSM : public Q3DStudio::ITegraRenderStateManager -{ - SRenderer &m_Renderer; - -public: - SRendererRSM(SRenderer &renderer) - : m_Renderer(renderer) - { - } - - void SetViewport(Q3DStudio::INT32 inX, Q3DStudio::INT32 inY, Q3DStudio::INT32 inWidth, - Q3DStudio::INT32 inHeight) override; - void PushState() override; - void PopState() override; - void SetScissorTestEnabled(bool inValue) override; - void SaveAllState() override; - void RestoreAllState() override; -}; - -struct SRenderer : public Q3DStudio::ITegraApplicationRenderEngine -{ - NVScopedRefCounted m_BindingCore; - NVScopedRefCounted m_Context; - NVRenderRect m_Viewport; - nvvector m_StateStack; - QSize m_PresentationDimensions; - SRendererRSM m_RSM; - Q3DStudio::IWindowSystem &m_WindowSystem; - - SRenderer(SBindingCore &inCore, Q3DStudio::IWindowSystem &inWindowSystem) - : m_BindingCore(inCore) - , m_Context(*inCore.m_Context) - , m_StateStack(inCore.m_Context->GetAllocator(), "SRenderer::m_StateStack") - , m_RSM(*this) - , m_WindowSystem(inWindowSystem) - { - m_Context->SetSceneColor(QT3DSVec4(0, 0, 0, 0.0f)); - if (m_BindingCore->m_RenderContext) { - m_BindingCore->m_RenderContext->SetDefaultRenderTarget( - m_WindowSystem.GetDefaultRenderTargetID()); - m_BindingCore->m_RenderContext->SetDefaultDepthBufferBitCount( - m_WindowSystem.GetDepthBitCount()); - } - } - - void ensureRenderTarget() override - { - m_BindingCore->m_RenderContext->SetDefaultRenderTarget( - m_WindowSystem.GetDefaultRenderTargetID()); - } - - void CheckResize(bool, Q3DStudio::IPresentation & /*inPresentation*/) override - { - QSize theWindowDims(m_WindowSystem.GetWindowDimensions()); - m_BindingCore->m_WindowDimensions = theWindowDims; - m_BindingCore->m_Context->SetWindowDimensions(m_BindingCore->m_WindowDimensions); - } - Q3DStudio::BOOL LoadShaderCache(const char * /*inFilePath*/) override { return true; } - - void AbandonLoadingImages(Q3DStudio::IScene & /*inScene*/) override {} - - Q3DStudio::BOOL IsPickValid(Q3DStudio::FLOAT &outX, Q3DStudio::FLOAT &outY, - const Q3DStudio::IPresentation & /*inPresentation*/) const override - { - Q3DStudio::FLOAT theX = outX; - Q3DStudio::FLOAT theY = outY; - theX = theX / static_cast(m_BindingCore->m_WindowDimensions.width()); - theY = theY / static_cast(m_BindingCore->m_WindowDimensions.height()); - Q3DStudio::BOOL theValid = false; - - if ((theX >= 0.0f) && (theY >= 0.0f) && (theX <= 1.0f) && (theY <= 1.0f)) - theValid = true; - return theValid; - } - - void SetScaleMode(Q3DStudio::TegraRenderScaleModes::Enum inScale) override - { - if (m_BindingCore && m_BindingCore->m_Context) - m_BindingCore->m_Context->SetScaleMode(static_cast(inScale)); - } - Q3DStudio::TegraRenderScaleModes::Enum GetScaleMode() const override - { - if (m_BindingCore && m_BindingCore->m_Context) - return static_cast( - const_cast(*this).m_BindingCore->m_Context->GetScaleMode()); - - QT3DS_ASSERT(false); - return Q3DStudio::TegraRenderScaleModes::ExactSize; - } - - void SetShadeMode(Q3DStudio::TegraRenderShadeModes::Enum inShade) override - { - if (m_BindingCore && m_BindingCore->m_Context) { - m_BindingCore->m_Context->SetWireframeMode( - (inShade == Q3DStudio::TegraRenderShadeModes::Shaded) ? false : true); - } - } - - void EnableRenderRotation(bool inEnable) override - { - m_BindingCore->m_RenderRotationsEnabled = inEnable; - } - - void SetWriteOutShaderCache(bool inWriteOutShaderCache) override - { - m_BindingCore->m_WriteOutShaderCache = inWriteOutShaderCache; - } - - Q3DStudio::ITegraRenderStateManager &GetTegraRenderStateManager() override { return m_RSM; } - qt3ds::render::NVRenderContext &GetRenderContext() override - { - return *m_BindingCore->m_RenderContext; - } - - void Release() override - { - // Ensure the core doesn't die until after we do. - NVScopedRefCounted theContext(m_BindingCore); - NVDelete(m_Context->GetAllocator(), this); - } - - void SetViewport(Q3DStudio::INT32 inX, Q3DStudio::INT32 inY, Q3DStudio::INT32 inWidth, - Q3DStudio::INT32 inHeight) override - { - m_Viewport = NVRenderRect(inX, inY, inWidth, inHeight); - m_BindingCore->m_RenderContext->SetViewport(m_Viewport); - } - void SetApplicationViewport(const qt3ds::render::NVRenderRect &inViewport) override - { - m_BindingCore->m_Context->SetViewport(inViewport); - } - - void SetMatteColor(Option inColor) override { m_Context->SetMatteColor(inColor); } - virtual void PushState() { m_StateStack.push_back(m_Viewport); } - virtual void PopState() - { - m_Viewport = m_StateStack.back(); - m_StateStack.pop_back(); - SetViewport(m_Viewport.m_X, m_Viewport.m_Y, m_Viewport.m_Width, m_Viewport.m_Height); - } - - void RenderText2D(Q3DStudio::FLOAT x, Q3DStudio::FLOAT y, - qt3ds::foundation::Option inColor, const char *text) override - { - m_Context->RenderText2D(x, y, inColor, text); - } - - void RenderGpuProfilerStats(Q3DStudio::FLOAT x, Q3DStudio::FLOAT y, - qt3ds::foundation::Option inColor) override - { - m_Context->RenderGpuProfilerStats(x, y, inColor); - } -}; - -void SRendererRSM::SetViewport(Q3DStudio::INT32 inX, Q3DStudio::INT32 inY, Q3DStudio::INT32 inWidth, - Q3DStudio::INT32 inHeight) -{ - m_Renderer.SetViewport(inX, inY, inWidth, inHeight); -} -void SRendererRSM::PushState() -{ - m_Renderer.PushState(); -} -void SRendererRSM::PopState() -{ - m_Renderer.PopState(); -} -void SRendererRSM::SetScissorTestEnabled(bool inValue) -{ - m_Renderer.m_BindingCore->m_RenderContext->SetScissorTestEnabled(inValue); -} -void SRendererRSM::SaveAllState() -{ - m_Renderer.m_BindingCore->m_RenderContext->PushPropertySet(); -} -void SRendererRSM::RestoreAllState() -{ - m_Renderer.m_BindingCore->m_RenderContext->PopPropertySet(true); -} - -Q3DStudio::ITegraApplicationRenderEngine &SBindingCore::CreateRenderer() -{ - SRenderer *retval = NULL; - if (m_Context) - retval = QT3DS_NEW(m_Context->GetAllocator(), SRenderer)(*this, this->m_WindowSystem); - - return *retval; -} diff --git a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplTranslation.cpp b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplTranslation.cpp deleted file mode 100644 index daf6c0f1..00000000 --- a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBindingImplTranslation.cpp +++ /dev/null @@ -1,1811 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "EnginePrefix.h" -#include "Qt3DSRenderRuntimeBindingImpl.h" -#include "Qt3DSRenderUIPSharedTranslation.h" -#include "Qt3DSRenderBufferManager.h" -#include "foundation/SerializationTypes.h" -#include "Qt3DSRenderString.h" -#include "foundation/FileTools.h" -#include "Qt3DSHash.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderPluginPropertyValue.h" -#include "Qt3DSElementHelper.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSApplication.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderPathSubPath.h" -#include "Qt3DSRenderPathManager.h" - -namespace Q3DStudio { -enum ExtendedAttributes { - ATTRIBUTE_NONE = 0, - ATTRIBUTE_NONE_R, - ATTRIBUTE_NONE_G, - ATTRIBUTE_NONE_B -}; -} - -namespace { -QT3DSU32 g_TranslatorTag; -QT3DSU32 g_PresentationTag; -} - -// Add specializations for the tagged pointer operations to make casting -// a bit safer and more transparent. -namespace qt3ds { -namespace render { - template <> - struct SPointerTag - { - static QT3DSU32 GetTag() { return g_TranslatorTag; } - }; - template <> - struct SPointerTag - { - static QT3DSU32 GetTag() { return g_PresentationTag; } - }; -} -} - -namespace { - -template -struct SDirtySetter -{ -}; - -template <> -struct SDirtySetter -{ - static void Set(bool &dirty, bool & /*transformDirty*/, bool & /*textDirty*/) { dirty = true; } -}; -template <> -struct SDirtySetter -{ - static void Set(bool &dirty, bool &transformDirty, bool & /*textDirty*/) - { - dirty = true; - transformDirty = true; - } -}; -template <> -struct SDirtySetter -{ - static void Set(bool &dirty, bool & /*transformDirty*/, bool &textDirty) - { - dirty = true; - textDirty = true; - } -}; -template <> -struct SDirtySetter -{ - static void Set(bool & /*dirty*/, bool & /*transformDirty*/, bool & /*textDirty*/) {} -}; - -// Translates individual property values from the runtime into the rendering system. -struct SRuntimePropertyParser -{ - QT3DSI32 m_PropertyName; - Q3DStudio::UVariant m_Value; - Q3DStudio::EAttributeType m_Type; - Q3DStudio::TElement &m_Element; - SPresentation &m_Presentation; - IQt3DSRenderContext &m_RenderContext; - bool m_Dirty; - bool m_TransformDirty; - bool m_TextDirty; - - SRuntimePropertyParser(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, - Q3DStudio::TElement &inElement) - : m_PropertyName(0) - , m_Type((Q3DStudio::EAttributeType)0) - , m_Element(inElement) - , m_Presentation(inPresentation) - , m_RenderContext(inRenderContext) - , m_Dirty(false) - , m_TransformDirty(false) - , m_TextDirty(false) - { - } - - void Setup(QT3DSI32 inPropName, Q3DStudio::UVariant inValue, Q3DStudio::EAttributeType inType) - { - m_PropertyName = inPropName; - m_Value = inValue; - m_Type = inType; - } - template - void SetDirty() - { - SDirtySetter::Set(m_Dirty, m_TransformDirty, m_TextDirty); - } - template - bool ParseProperty(QT3DSF32 &outValue) - { - if (m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT) { - QT3DSF32 newValue = m_Value.m_FLOAT; - if (outValue != newValue) { - outValue = newValue; - SetDirty(); - return true; - } - } else { - QT3DS_ASSERT(false); - } - return false; - }; - template - bool ParseProperty(QT3DSU32 &outValue) - { - if (m_Type == Q3DStudio::ATTRIBUTETYPE_INT32) { - QT3DSU32 newValue = (QT3DSU32)m_Value.m_INT32; - if (outValue != newValue) { - outValue = newValue; - SetDirty(); - return true; - } - } else { - QT3DS_ASSERT(false); - } - return false; - }; - template - bool ParseProperty(SGraphObject *&outValue) - { - Q3DStudio::TElement *theElem = NULL; - if (m_Type == Q3DStudio::ATTRIBUTETYPE_ELEMENTREF) { - theElem = m_Element.GetBelongedPresentation()->GetApplication().GetElementByHandle( - m_Value.m_ElementHandle); - } else if (m_Type == Q3DStudio::ATTRIBUTETYPE_STRING) { - CRegisteredString theString = - m_RenderContext.GetStringTable().HandleToStr(m_Value.m_StringHandle); - theElem = Q3DStudio::CElementHelper::GetElement( - m_Element.GetBelongedPresentation()->GetApplication(), - m_Element.GetBelongedPresentation(), theString.c_str(), &m_Element); - } - - SGraphObject *newValue = NULL; - if (theElem) { - Qt3DSTranslator *theTranslator = - reinterpret_cast(theElem->GetAssociation()); - if (theTranslator) - newValue = theTranslator->m_RenderObject; - } - if (outValue != newValue) { - outValue = newValue; - SetDirty(); - return true; - } - return false; - }; - template - bool ParseRadianProperty(QT3DSF32 &outValue) - { - if (ParseProperty(outValue)) { - TORAD(outValue); - return true; - } - return false; - } - template - bool ParseOpacityProperty(QT3DSF32 &outValue) - { - if (ParseProperty(outValue)) { - outValue *= 1.0f / 100.0f; - return true; - } - return false; - } - - template - bool ParseOrientationProperty(bool &ioCurrent) - { - if (m_Type == Q3DStudio::ATTRIBUTETYPE_STRING) { - CRegisteredString strValue = - m_RenderContext.GetStringTable().HandleToStr(m_Value.m_StringHandle); - bool newValue = AreEqual(strValue.c_str(), "Left Handed") ? true : false; - if (ioCurrent != newValue) { - ioCurrent = newValue; - SetDirty(); - return true; - } - } else { - QT3DS_ASSERT(false); - } - return false; - } - - template - bool ParseProperty(bool &ioCurrent) - { - if (m_Type == Q3DStudio::ATTRIBUTETYPE_BOOL || m_Type == Q3DStudio::ATTRIBUTETYPE_INT32) { - bool newValue = m_Value.m_INT32 ? true : false; - if (ioCurrent != newValue) { - ioCurrent = newValue; - SetDirty(); - return true; - } - } else { - QT3DS_ASSERT(false); - } - return false; - } - template - bool ParseInverseBoolean(bool &ioCurrent) - { - bool temp = !ioCurrent; - if (ParseProperty(temp)) { - ioCurrent = temp; - return true; - } - return false; - } - template - bool ParseProperty(QT3DSVec3 &outValue) - { - if (m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT3) { - QT3DSVec3 newValue(m_Value.m_FLOAT3[0], m_Value.m_FLOAT3[1], m_Value.m_FLOAT3[2]); - if (outValue != newValue) { - outValue = newValue; - SetDirty(); - return true; - } - } else { - QT3DS_ASSERT(false); - } - return false; - } - - template - bool ParseProperty(CRegisteredString &outValue) - { - if (m_Type == Q3DStudio::ATTRIBUTETYPE_STRING) { - CRegisteredString newValue = - m_RenderContext.GetStringTable().HandleToStr(m_Value.m_StringHandle); - if (newValue.c_str() != outValue.c_str()) { - outValue = newValue; - SetDirty(); - return true; - } - } else { - QT3DS_ASSERT(false); - } - return false; - } - - template - bool ParseRotationOrder(QT3DSU32 &outValue) - { - CRegisteredString theString; - ParseProperty(theString); - if (theString.IsValid()) { - QT3DSU32 newRotationOrder = MapRotationOrder(theString); - if (newRotationOrder != outValue) { - outValue = newRotationOrder; - SetDirty(); - return true; - } - } - return false; - } - - template - bool ParseOrientation(NodeFlags &outValue) - { - bool temp = false; - ParseOrientationProperty(temp); - bool wasLeftHanded = outValue.IsLeftHanded(); - if (wasLeftHanded != temp) { - outValue.SetLeftHanded(temp); - SetDirty(); - return true; - } - return false; - } - template - bool ParseNodeFlagsProperty(NodeFlags &outValue, NodeFlagValues::Enum inFlag) - { - bool temp = false; - ParseProperty(temp); - bool wasSet = outValue & inFlag; - if (temp != wasSet) { - outValue.ClearOrSet(temp, inFlag); - SetDirty(); - return true; - } - return false; - } - - template - bool ParseNodeFlagsInverseProperty(NodeFlags &outValue, NodeFlagValues::Enum inFlag) - { - bool temp = false; - ParseProperty(temp); - temp = !temp; - bool wasSet = outValue & inFlag; - if (temp != wasSet) { - outValue.ClearOrSet(temp, inFlag); - SetDirty(); - return true; - } - return false; - } - - template - bool ParseEnumProperty(TEnumType &outValue) - { - CRegisteredString theString; - ParseProperty(theString); - if (theString.IsValid()) { - SEnumNameMap *theMap = SEnumParseMap::GetMap(); - for (SEnumNameMap *theItem = theMap; theItem->m_Name && *theItem->m_Name; ++theItem) { - // hack to match advanced overlay types, whose name start with a '*' - const char8_t *p = theString.c_str(); - if (*p == '*') - ++p; - if (strcmp(p, theItem->m_Name) == 0) { - TEnumType theNewValue = static_cast(theItem->m_Enum); - if (outValue != theNewValue) { - outValue = theNewValue; - SetDirty(); - return true; - } - } - } - } - return false; - } - template - bool ParseAndResolveSourcePath(CRegisteredString &outValue) - { - CRegisteredString theTemp; - ParseProperty(theTemp); - CRegisteredString theNewStr = theTemp; - if (outValue.c_str() != theNewStr.c_str()) { - SetDirty(); - outValue = theNewStr; - return true; - } - return false; - } - - template - bool ParseProperty(SImage *&ioImagePtr) - { - Q3DStudio::TElement *theElem = - m_Element.GetBelongedPresentation()->GetApplication().GetElementByHandle( - m_Value.m_ElementHandle); - // Try to be very careful in here as casting things around like crazy is a sure - // way to crash the runtime at a bad point. - if (theElem != NULL) { - Qt3DSTranslator *theTranslator = - reinterpret_cast(theElem->GetAssociation()); - if (theTranslator != NULL && theTranslator->GetUIPType() == GraphObjectTypes::Image) { - SImage *theImage = static_cast(theTranslator->m_RenderObject); - if (ioImagePtr != theImage) { - ioImagePtr = theImage; - SetDirty(); - return true; - } - } - } - return false; - } - - template - bool ParseProperty(SNode *&ioNodePtr) - { - Q3DStudio::TElement *theElem = - m_Element.GetBelongedPresentation()->GetApplication().GetElementByHandle( - m_Value.m_ElementHandle); - // Try to be very careful in here as casting things around like crazy is a sure - // way to crash the runtime at a bad point. - SNode *theNode = NULL; - if (theElem != NULL - && theElem->GetBelongedPresentation() == m_Element.GetBelongedPresentation()) { - Qt3DSTranslator *theTranslator = - reinterpret_cast(theElem->GetAssociation()); - if (theTranslator != NULL - && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { - theNode = static_cast(theTranslator->m_RenderObject); - } - } - if (ioNodePtr != theNode) { - ioNodePtr = theNode; - SetDirty(); - return true; - } - return false; - } -}; - -// Fill out parse name table. -#define Scene_ClearColor_R ATTRIBUTE_BACKGROUNDCOLOR_R -#define Scene_ClearColor_G ATTRIBUTE_BACKGROUNDCOLOR_G -#define Scene_ClearColor_B ATTRIBUTE_BACKGROUNDCOLOR_B -#define Scene_UseClearColor ATTRIBUTE_BGCOLORENABLE -#define Node_Rotation ATTRIBUTE_ROTATION -#define Node_Rotation_X ATTRIBUTE_ROTATION_X -#define Node_Rotation_Y ATTRIBUTE_ROTATION_Y -#define Node_Rotation_Z ATTRIBUTE_ROTATION_Z -#define Node_Position ATTRIBUTE_POSITION -#define Node_Position_X ATTRIBUTE_POSITION_X -#define Node_Position_Y ATTRIBUTE_POSITION_Y -#define Node_Position_Z ATTRIBUTE_POSITION_Z -#define Node_Scale ATTRIBUTE_SCALE -#define Node_Scale_X ATTRIBUTE_SCALE_X -#define Node_Scale_Y ATTRIBUTE_SCALE_Y -#define Node_Scale_Z ATTRIBUTE_SCALE_Z -#define Node_Pivot ATTRIBUTE_PIVOT -#define Node_Pivot_X ATTRIBUTE_PIVOT_X -#define Node_Pivot_Y ATTRIBUTE_PIVOT_Y -#define Node_Pivot_Z ATTRIBUTE_PIVOT_Z -#define Node_LocalOpacity ATTRIBUTE_OPACITY -#define Node_RotationOrder ATTRIBUTE_ROTATIONORDER -#define Node_LeftHanded ATTRIBUTE_ORIENTATION -#define Layer_TemporalAAEnabled ATTRIBUTE_TEMPORALAA -#define Layer_LayerEnableDepthTest ATTRIBUTE_DISABLEDEPTHTEST -#define Layer_LayerEnableDepthPrePass ATTRIBUTE_DISABLEDEPTHPREPASS -#define Layer_ClearColor_R ATTRIBUTE_BACKGROUNDCOLOR_R -#define Layer_ClearColor_G ATTRIBUTE_BACKGROUNDCOLOR_G -#define Layer_ClearColor_B ATTRIBUTE_BACKGROUNDCOLOR_B -#define Layer_Background ATTRIBUTE_BACKGROUND -#define Layer_BlendType ATTRIBUTE_BLENDTYPE -#define Layer_ProgressiveAAMode ATTRIBUTE_PROGRESSIVEAA -#define Layer_MultisampleAAMode ATTRIBUTE_MULTISAMPLEAA -#define Layer_HorizontalFieldValues ATTRIBUTE_HORZFIELDS -#define Layer_Left ATTRIBUTE_LEFT -#define Layer_LeftUnits ATTRIBUTE_LEFTUNITS -#define Layer_Width ATTRIBUTE_WIDTH -#define Layer_WidthUnits ATTRIBUTE_WIDTHUNITS -#define Layer_Right ATTRIBUTE_RIGHT -#define Layer_RightUnits ATTRIBUTE_RIGHTUNITS -#define Layer_VerticalFieldValues ATTRIBUTE_VERTFIELDS -#define Layer_Top ATTRIBUTE_TOP -#define Layer_TopUnits ATTRIBUTE_TOPUNITS -#define Layer_Height ATTRIBUTE_HEIGHT -#define Layer_HeightUnits ATTRIBUTE_HEIGHTUNITS -#define Layer_Bottom ATTRIBUTE_BOTTOM -#define Layer_BottomUnits ATTRIBUTE_BOTTOMUNITS -#define Layer_AoStrength ATTRIBUTE_AOSTRENGTH -#define Layer_AoDistance ATTRIBUTE_AODISTANCE -#define Layer_AoSoftness ATTRIBUTE_AOSOFTNESS -#define Layer_AoBias ATTRIBUTE_AOBIAS -#define Layer_AoSamplerate ATTRIBUTE_AOSAMPLERATE -#define Layer_AoDither ATTRIBUTE_AODITHER -#define Layer_ShadowStrength ATTRIBUTE_SHADOWSTRENGTH -#define Layer_ShadowDist ATTRIBUTE_SHADOWDIST -#define Layer_ShadowSoftness ATTRIBUTE_SHADOWSOFTNESS -#define Layer_ShadowBias ATTRIBUTE_SHADOWBIAS -#define Layer_LightProbe ATTRIBUTE_LIGHTPROBE -#define Layer_ProbeBright ATTRIBUTE_PROBEBRIGHT -#define Layer_FastIbl ATTRIBUTE_FASTIBL -#define Layer_ProbeTheta ATTRIBUTE_PROBETHETA -#define Layer_ProbePhi ATTRIBUTE_PROBEPHI -#define Layer_ProbeHorizon ATTRIBUTE_PROBEHORIZON -#define Layer_LightProbe2 ATTRIBUTE_LIGHTPROBE2 -#define Layer_Probe2Fade ATTRIBUTE_PROBE2FADE -#define Layer_Probe2Window ATTRIBUTE_PROBE2WINDOW -#define Layer_Probe2Pos ATTRIBUTE_PROBE2POS -#define Layer_ProbeFov ATTRIBUTE_PROBEFOV -#define Layer_TexturePath ATTRIBUTE_SOURCEPATH -#define Camera_ClipNear ATTRIBUTE_CLIPNEAR -#define Camera_ClipFar ATTRIBUTE_CLIPFAR -#define Camera_FOV ATTRIBUTE_FOV -#define Camera_FOVHorizontal ATTRIBUTE_FOVHORIZONTAL -#define Camera_Orthographic ATTRIBUTE_ORTHOGRAPHIC -#define Camera_ScaleMode ATTRIBUTE_SCALEMODE -#define Camera_ScaleAnchor ATTRIBUTE_SCALEANCHOR -#define Light_ImageSource ATTRIBUTE_IMAGESOURCE -#define Light_Scope ATTRIBUTE_SCOPE -#define Light_ImageSetsColor ATTRIBUTE_IMAGESETSCOLOR -#define Light_ImageSetsRotation ATTRIBUTE_IMAGESETSROTATION -#define Light_ImageHFov ATTRIBUTE_IMAGEHFOV -#define Light_ImageIsFisheye ATTRIBUTE_IMAGEISFISHEYE -#define Light_LightType ATTRIBUTE_LIGHTTYPE -#define Light_DiffuseColor ATTRIBUTE_LIGHTDIFFUSE -#define Light_DiffuseColor_R ATTRIBUTE_LIGHTDIFFUSE_R -#define Light_DiffuseColor_G ATTRIBUTE_LIGHTDIFFUSE_G -#define Light_DiffuseColor_B ATTRIBUTE_LIGHTDIFFUSE_B -#define Light_SpecularColor ATTRIBUTE_LIGHTSPECULAR -#define Light_SpecularColor_R ATTRIBUTE_LIGHTSPECULAR_R -#define Light_SpecularColor_G ATTRIBUTE_LIGHTSPECULAR_G -#define Light_SpecularColor_B ATTRIBUTE_LIGHTSPECULAR_B -#define Light_AmbientColor ATTRIBUTE_LIGHTAMBIENT -#define Light_AmbientColor_R ATTRIBUTE_LIGHTAMBIENT_R -#define Light_AmbientColor_G ATTRIBUTE_LIGHTAMBIENT_G -#define Light_AmbientColor_B ATTRIBUTE_LIGHTAMBIENT_B -#define Light_Brightness ATTRIBUTE_BRIGHTNESS -#define Light_LinearFade ATTRIBUTE_LINEARFADE -#define Light_ExponentialFade ATTRIBUTE_EXPFADE -#define Light_AreaWidth ATTRIBUTE_AREAWIDTH -#define Light_AreaHeight ATTRIBUTE_AREAHEIGHT -#define Light_CastShadow ATTRIBUTE_CASTSHADOW -#define Light_ShadowBias ATTRIBUTE_SHDWBIAS -#define Light_ShadowFactor ATTRIBUTE_SHDWFACTOR -#define Light_ShadowMapRes ATTRIBUTE_SHDWMAPRES -#define Light_ShadowMapFar ATTRIBUTE_SHDWMAPFAR -#define Light_ShadowMapFov ATTRIBUTE_SHDWMAPFOV -#define Light_ShadowFilter ATTRIBUTE_SHDWFILTER -#define Model_MeshPath ATTRIBUTE_SOURCEPATH -#define Model_ShadowCaster ATTRIBUTE_SHADOWCASTER -#define Model_TessellationMode ATTRIBUTE_TESSELLATION -#define Model_EdgeTess ATTRIBUTE_EDGETESS -#define Model_InnerTess ATTRIBUTE_INNERTESS -#define Lightmaps_LightmapIndirect ATTRIBUTE_LIGHTMAPINDIRECT -#define Lightmaps_LightmapRadiosity ATTRIBUTE_LIGHTMAPRADIOSITY -#define Lightmaps_LightmapShadow ATTRIBUTE_LIGHTMAPSHADOW -#define Material_Lighting ATTRIBUTE_SHADERLIGHTING -#define Material_BlendMode ATTRIBUTE_BLENDMODE -#define MaterialBase_IblProbe ATTRIBUTE_IBLPROBE -#define Material_DiffuseColor ATTRIBUTE_DIFFUSE -#define Material_DiffuseColor_R ATTRIBUTE_DIFFUSE_R -#define Material_DiffuseColor_G ATTRIBUTE_DIFFUSE_G -#define Material_DiffuseColor_B ATTRIBUTE_DIFFUSE_B -#define Material_DiffuseMaps_0 ATTRIBUTE_DIFFUSEMAP -#define Material_DiffuseMaps_1 ATTRIBUTE_DIFFUSEMAP2 -#define Material_DiffuseMaps_2 ATTRIBUTE_DIFFUSEMAP3 -#define Material_EmissivePower ATTRIBUTE_EMISSIVEPOWER -#define Material_EmissiveColor ATTRIBUTE_EMISSIVECOLOR -#define Material_EmissiveColor_R ATTRIBUTE_EMISSIVECOLOR_R -#define Material_EmissiveColor_G ATTRIBUTE_EMISSIVECOLOR_G -#define Material_EmissiveColor_B ATTRIBUTE_EMISSIVECOLOR_B -#define Material_EmissiveMap ATTRIBUTE_EMISSIVEMAP -#define Material_EmissiveMap2 ATTRIBUTE_EMISSIVEMAP2 -#define Material_SpecularReflection ATTRIBUTE_SPECULARREFLECTION -#define Material_SpecularMap ATTRIBUTE_SPECULARMAP -#define Material_SpecularModel ATTRIBUTE_SPECULARMODEL -#define Material_SpecularTint ATTRIBUTE_SPECULARTINT -#define Material_SpecularTint_R ATTRIBUTE_SPECULARTINT_R -#define Material_SpecularTint_G ATTRIBUTE_SPECULARTINT_G -#define Material_SpecularTint_B ATTRIBUTE_SPECULARTINT_B -#define Material_IOR ATTRIBUTE_IOR -#define Material_FresnelPower ATTRIBUTE_FRESNELPOWER -#define Material_SpecularAmount ATTRIBUTE_SPECULARAMOUNT -#define Material_SpecularRoughness ATTRIBUTE_SPECULARROUGHNESS -#define Material_RoughnessMap ATTRIBUTE_ROUGHNESSMAP -#define Material_Opacity ATTRIBUTE_OPACITY -#define Material_OpacityMap ATTRIBUTE_OPACITYMAP -#define Material_BumpAmount ATTRIBUTE_BUMPAMOUNT -#define Material_BumpMap ATTRIBUTE_BUMPMAP -#define Material_NormalMap ATTRIBUTE_NORMALMAP -#define Material_DisplaceAmount ATTRIBUTE_DISPLACEAMOUNT -#define Material_DisplacementMap ATTRIBUTE_DISPLACEMENTMAP -#define Material_TranslucentFalloff ATTRIBUTE_TRANSLUCENTFALLOFF -#define Material_TranslucencyMap ATTRIBUTE_TRANSLUCENCYMAP -#define Material_DiffuseLightWrap ATTRIBUTE_DIFFUSELIGHTWRAP -#define Material_ReferencedMaterial ATTRIBUTE_REFERENCEDMATERIAL -#define Material_VertexColors ATTRIBUTE_VERTEXCOLORS -#define Image_ImagePath ATTRIBUTE_SOURCEPATH -#define Image_OffscreenRendererId ATTRIBUTE_SUBPRESENTATION -#define Image_Scale_X ATTRIBUTE_SCALEU -#define Image_Scale_Y ATTRIBUTE_SCALEV -#define Image_Pivot_X ATTRIBUTE_PIVOTU -#define Image_Pivot_Y ATTRIBUTE_PIVOTV -#define Image_Rotation ATTRIBUTE_ROTATIONUV -#define Image_Position_X ATTRIBUTE_POSITIONU -#define Image_Position_Y ATTRIBUTE_POSITIONV -#define Image_MappingMode ATTRIBUTE_MAPPINGMODE -#define Image_HorizontalTilingMode ATTRIBUTE_TILINGMODEHORZ -#define Image_VerticalTilingMode ATTRIBUTE_TILINGMODEVERT -#define Text_Text ATTRIBUTE_TEXTSTRING -#define Text_Font ATTRIBUTE_FONT -#define Text_FontSize ATTRIBUTE_SIZE -#define Text_HorizontalAlignment ATTRIBUTE_HORZALIGN -#define Text_VerticalAlignment ATTRIBUTE_VERTALIGN -#define Text_Leading ATTRIBUTE_LEADING -#define Text_Tracking ATTRIBUTE_TRACKING -#define Text_DropShadow ATTRIBUTE_DROPSHADOW -#define Text_DropShadowStrength ATTRIBUTE_DROPSHADOWSTRENGTH -#define Text_DropShadowOffset ATTRIBUTE_DROPSHADOWOFFSET -#define Text_DropShadowOffsetX ATTRIBUTE_DROPSHADOWOFFSETX -#define Text_DropShadowOffsetY ATTRIBUTE_DROPSHADOWOFFSETY -#define Text_DropShadowHorizontalAlignment ATTRIBUTE_DROPSHADOWHORZALIGN -#define Text_DropShadowVerticalAlignment ATTRIBUTE_DROPSHADOWVERTALIGN -#define Text_WordWrap ATTRIBUTE_WORDWRAP -#define Text_BoundingBox ATTRIBUTE_BOUNDINGBOX -#define Text_BoundingBox_X ATTRIBUTE_BOUNDINGBOX_X -#define Text_BoundingBox_Y ATTRIBUTE_BOUNDINGBOX_Y -#define Text_Elide ATTRIBUTE_ELIDE -#define Text_TextColor ATTRIBUTE_TEXTCOLOR -#define Text_TextColor_R ATTRIBUTE_TEXTCOLOR_R -#define Text_TextColor_G ATTRIBUTE_TEXTCOLOR_G -#define Text_TextColor_B ATTRIBUTE_TEXTCOLOR_B -#define Text_BackColor_R ATTRIBUTE_BACKCOLOR_R -#define Text_BackColor_G ATTRIBUTE_BACKCOLOR_G -#define Text_BackColor_B ATTRIBUTE_BACKCOLOR_B -#define Text_UseBackColor ATTRIBUTE_USEBACKCOLOR -#define Text_EnableAcceleratedFont ATTRIBUTE_ENABLEACCELERATEDFONT -#define Path_PathType ATTRIBUTE_PATHTYPE -#define Path_Width ATTRIBUTE_WIDTH -#define Path_LinearError ATTRIBUTE_LINEARERROR -#define Path_EdgeTessAmount ATTRIBUTE_EDGETESSAMOUNT -#define Path_InnerTessAmount ATTRIBUTE_INNERTESSAMOUNT -#define Path_BeginCapping ATTRIBUTE_BEGINCAP -#define Path_BeginCapOffset ATTRIBUTE_BEGINCAPOFFSET -#define Path_BeginCapOpacity ATTRIBUTE_BEGINCAPOPACITY -#define Path_BeginCapWidth ATTRIBUTE_BEGINCAPWIDTH -#define Path_EndCapping ATTRIBUTE_ENDCAP -#define Path_EndCapOffset ATTRIBUTE_ENDCAPOFFSET -#define Path_EndCapOpacity ATTRIBUTE_ENDCAPOPACITY -#define Path_EndCapWidth ATTRIBUTE_ENDCAPWIDTH -#define Path_PaintStyle ATTRIBUTE_PAINTSTYLE -#define Path_PathBuffer ATTRIBUTE_SOURCEPATH -#define SubPath_Closed ATTRIBUTE_CLOSED - -// Fill in implementations for the actual parse tables. -#define HANDLE_QT3DS_RENDER_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseProperty(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_RENDER_VEC3_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name##_X: \ - inParser.ParseProperty(theItem.m_##name.x); \ - break; \ - case Q3DStudio::type##_##name##_Y: \ - inParser.ParseProperty(theItem.m_##name.y); \ - break; \ - case Q3DStudio::type##_##name##_Z: \ - inParser.ParseProperty(theItem.m_##name.z); \ - break; - -#define HANDLE_QT3DS_RENDER_REAL_VEC2_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name##_X: \ - inParser.ParseProperty(theItem.m_##name.x); \ - break; \ - case Q3DStudio::type##_##name##_Y: \ - inParser.ParseProperty(theItem.m_##name.y); \ - break; - -#define HANDLE_QT3DS_RENDER_COLOR_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name##_R: \ - inParser.ParseProperty(theItem.m_##name.x); \ - break; \ - case Q3DStudio::type##_##name##_G: \ - inParser.ParseProperty(theItem.m_##name.y); \ - break; \ - case Q3DStudio::type##_##name##_B: \ - inParser.ParseProperty(theItem.m_##name.z); \ - break; - -#define HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseProperty(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseProperty(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseRadianProperty(theItem.m_##name); \ - break; - -// The runtime converts rotations for us. -#define HANDLE_QT3DS_RENDER_VEC3_RADIAN_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name##_X: \ - inParser.ParseProperty(theItem.m_##name.x); \ - break; \ - case Q3DStudio::type##_##name##_Y: \ - inParser.ParseProperty(theItem.m_##name.y); \ - break; \ - case Q3DStudio::type##_##name##_Z: \ - inParser.ParseProperty(theItem.m_##name.z); \ - break; - -#define HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseOpacityProperty(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_ROTATION_ORDER_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseRotationOrder(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseOrientation(theItem.m_Flags); \ - break; - -#define HANDLE_QT3DS_RENDER_DEPTH_TEST_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseInverseBoolean(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_NODE_FLAGS_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseNodeFlagsProperty(theItem.m_Flags, \ - NodeFlagValues::name); \ - break; - -#define HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseNodeFlagsInverseProperty(theItem.m_Flags, \ - NodeFlagValues::name); \ - break; - -#define HANDLE_QT3DS_RENDER_ENUM_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseEnumProperty(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name: \ - inParser.ParseAndResolveSourcePath(theItem.m_##name); \ - break; - -#define HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(type, name, index, dirty) \ - case Q3DStudio::type##_##name##_##index: \ - inParser.ParseProperty(theItem.m_##name[index]); \ - break; - -#define HANDLE_QT3DS_RENDER_VEC2_PROPERTY(type, name, dirty) \ - case Q3DStudio::type##_##name##_X: \ - inParser.ParseProperty(theItem.m_##name.x); \ - break; \ - case Q3DStudio::type##_##name##_Y: \ - inParser.ParseProperty(theItem.m_##name.y); \ - break; - -struct SSceneTranslator : public Qt3DSTranslator -{ - typedef SScene TNodeType; - SSceneTranslator(Q3DStudio::TElement &inElement, SScene &inRenderObject) - : Qt3DSTranslator(inElement, inRenderObject) - { - } - // Ignored, scenes are always active - void SetActive(bool /*inElementActive*/) {} - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SScene &theItem = *static_cast(m_RenderObject); - - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_SCENE_PROPERTIES - // These are ignored by the renderer - case Q3DStudio::ATTRIBUTE_NAME: - case Q3DStudio::ATTRIBUTE_STARTTIME: - case Q3DStudio::ATTRIBUTE_ENDTIME: - case Q3DStudio::ATTRIBUTE_IMPORTID: - case Q3DStudio::ATTRIBUTE_EYEBALL: - break; - default: - // Unknown attribute - // QT3DS_ASSERT( false ); - break; - } - } - void PostPropertyChanged(const SRuntimePropertyParser &, Q3DStudio::IPresentation &) {} -}; - -struct SNodeTranslator : public Qt3DSTranslator -{ - typedef SNode TNodeType; - SNodeTranslator(Q3DStudio::TElement &inElement, SNode &inRenderObject) - : Qt3DSTranslator(inElement, inRenderObject) - { - SNode &theItem = *static_cast(m_RenderObject); - theItem.m_Flags.SetLocallyPickable(false); - } - void SetActive(bool inElementActive) - { - SNode &theItem = *static_cast(m_RenderObject); - if (theItem.m_Flags.IsActive() != inElementActive) { - theItem.m_Flags.SetActive(inElementActive); - theItem.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - } - } - - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SNode &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_NODE_PROPERTIES - case Q3DStudio::ATTRIBUTE_NAME: - case Q3DStudio::ATTRIBUTE_STARTTIME: - case Q3DStudio::ATTRIBUTE_ENDTIME: - case Q3DStudio::ATTRIBUTE_IMPORTID: - case Q3DStudio::ATTRIBUTE_EYEBALL: - // Groups have a source path property on them that we like to ignore. - case Q3DStudio::ATTRIBUTE_SOURCEPATH: - break; - default: - // Unknown attribute - // QT3DS_ASSERT( false ); - break; - } - } - void PostPropertyChanged(const SRuntimePropertyParser &inParser, - Q3DStudio::IPresentation & /*inStudioPresentation*/) - { - SNode &theItem = *static_cast(m_RenderObject); - if (inParser.m_TransformDirty) - theItem.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - else if (inParser.m_Dirty) - theItem.MarkDirty(NodeTransformDirtyFlag::TransformNotDirty); - if (inParser.m_TextDirty) - theItem.m_Flags.SetTextDirty(true); - SetActive(Element().GetActive()); - bool isNodePickable = m_Element->IsPickEnabled(); - if (theItem.m_Flags.IsLocallyPickable() != isNodePickable) { - theItem.m_Flags.SetLocallyPickable(isNodePickable); - theItem.MarkDirty(NodeTransformDirtyFlag::TransformNotDirty); - } - } -}; - -struct SLayerTranslator : public SNodeTranslator -{ - typedef SLayer TNodeType; - SLayerTranslator(Q3DStudio::TElement &inElement, SLayer &inRenderObject) - : SNodeTranslator(inElement, inRenderObject) - { - } - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - const char *propName = - Q3DStudio::GetAttributeString((Q3DStudio::EAttribute)inParser.m_PropertyName); - (void)propName; - SLayer &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_LAYER_PROPERTIES - // Ignored - default: - SNodeTranslator::OnSpecificPropertyChange(inParser); - } - } -}; - -struct SLightTranslator : public SNodeTranslator -{ - typedef SLight TNodeType; - SLightTranslator(Q3DStudio::TElement &inElement, SLight &inRenderObject) - : SNodeTranslator(inElement, inRenderObject) - { - } - - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SLight &theItem = *static_cast(m_RenderObject); - // I guess there is no switching of light type in the runtime right now. - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_LIGHT_PROPERTIES - default: - SNodeTranslator::OnSpecificPropertyChange(inParser); - break; - } - } -}; -struct SCameraTranslator : public SNodeTranslator -{ - typedef SCamera TNodeType; - SCameraTranslator(Q3DStudio::TElement &inElement, SCamera &inRenderObject) - : SNodeTranslator(inElement, inRenderObject) - { - } - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SCamera &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_CAMERA_PROPERTIES - default: - SNodeTranslator::OnSpecificPropertyChange(inParser); - break; - } - } -}; - -struct SModelTranslator : public SNodeTranslator -{ - typedef SModel TNodeType; - SModelTranslator(Q3DStudio::TElement &inElement, SModel &inRenderObject) - : SNodeTranslator(inElement, inRenderObject) - { - } - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SModel &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_MODEL_PROPERTIES - default: - SNodeTranslator::OnSpecificPropertyChange(inParser); - break; - } - } -}; - -struct SPathTranslator : public SNodeTranslator -{ - typedef SPath TNodeType; - SPathTranslator(Q3DStudio::TElement &inElement, SPath &inRenderObject) - : SNodeTranslator(inElement, inRenderObject) - { - } - - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SPath &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_PATH_PROPERTIES - default: - SNodeTranslator::OnSpecificPropertyChange(inParser); - break; - } - } -}; - -struct SPathSubPathTranslator : public Qt3DSTranslator -{ - - typedef SPathSubPath TNodeType; - - SPathSubPathTranslator(Q3DStudio::TElement &inElement, SPathSubPath &inRenderObject) - : Qt3DSTranslator(inElement, inRenderObject) - { - } - - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SPathSubPath &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_PATH_SUBPATH_PROPERTIES - default: - break; - } - } - - void PostPropertyChanged(const SRuntimePropertyParser &inParser, - Q3DStudio::IPresentation & /*inStudioPresentation*/) - { - SPathSubPath &theItem = *static_cast(m_RenderObject); - qt3ds::render::IPathManager &theManager = inParser.m_RenderContext.GetPathManager(); - QT3DSU32 numAnchors = 0; - bool updatePath = false; - CRegisteredString theAnchorType = - inParser.m_RenderContext.GetStringTable().RegisterStr("PathAnchorPoint"); - for (Q3DStudio::TElement *theChild = Element().GetChild(); theChild; - theChild = theChild->GetSibling()) { - if (theChild->GetType() == theAnchorType) { - ++numAnchors; - if (theChild->IsDirty()) - updatePath = true; - } - } - if (updatePath) { - NVDataRef thePathBuffer = - theManager.ResizePathSubPathBuffer(theItem, numAnchors); - if (thePathBuffer.size()) { - QT3DSU32 anchorIndex = 0; - for (Q3DStudio::TElement *theChild = Element().GetChild(); theChild; - theChild = theChild->GetSibling()) { - if (theChild->GetType() == theAnchorType) { - if (theChild->IsDirty()) { - qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); - - for (QT3DSI32 idx = 0, end = theChild->GetAttributeCount(); idx < end; - ++idx) { - qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = - theChild->GetPropertyByIndex(idx); - switch (thePropInfo.first.GetNameHash()) { - case Q3DStudio::ATTRIBUTE_POSITION_X: - thePoint.m_Position.x = thePropInfo.second->m_FLOAT; - break; - case Q3DStudio::ATTRIBUTE_POSITION_Y: - thePoint.m_Position.y = thePropInfo.second->m_FLOAT; - break; - case Q3DStudio::ATTRIBUTE_INCOMINGANGLE: - thePoint.m_IncomingAngle = thePropInfo.second->m_FLOAT; - thePoint.m_OutgoingAngle = thePoint.m_IncomingAngle + 180.0f; - break; - case Q3DStudio::ATTRIBUTE_INCOMINGDISTANCE: - thePoint.m_IncomingDistance = thePropInfo.second->m_FLOAT; - break; - case Q3DStudio::ATTRIBUTE_OUTGOINGDISTANCE: - thePoint.m_OutgoingDistance = thePropInfo.second->m_FLOAT; - break; - default: // ignored - break; - } - } - } - ++anchorIndex; - } - } - } - } - } -}; - -struct SDefaultMaterialTranslator : public Qt3DSTranslator -{ - typedef SDefaultMaterial TNodeType; - SDefaultMaterialTranslator(Q3DStudio::TElement &inElement, SDefaultMaterial &inRenderObject) - : Qt3DSTranslator(inElement, inRenderObject) - { - } - // Right now materials do not respect the active flag - void SetActive(bool) {} - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SDefaultMaterial &theItem = *static_cast(m_RenderObject); - // There is no render-time caching on a material, so the dirty flag doesn't do much. - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_MATERIAL_PROPERTIES - - case Q3DStudio::ATTRIBUTE_NAME: - case Q3DStudio::ATTRIBUTE_STARTTIME: - case Q3DStudio::ATTRIBUTE_ENDTIME: - case Q3DStudio::ATTRIBUTE_IMPORTID: - case Q3DStudio::ATTRIBUTE_EYEBALL: - case Q3DStudio::ATTRIBUTE_SOURCEPATH: - break; - default: - // Unknown attribute - // QT3DS_ASSERT( false ); - break; - } - } - - void PostPropertyChanged(const SRuntimePropertyParser &, Q3DStudio::IPresentation &) - { - SDefaultMaterial &theItem = *static_cast(m_RenderObject); - theItem.m_Dirty.SetDirty(); - } -}; - -struct SImageTranslator : public Qt3DSTranslator -{ - typedef SImage TNodeType; - SImageTranslator(Q3DStudio::TElement &inElement, SImage &inRenderObject) - : Qt3DSTranslator(inElement, inRenderObject) - { - } - - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SImage &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_IMAGE_PROPERTIES - case Q3DStudio::ATTRIBUTE_STARTTIME: - case Q3DStudio::ATTRIBUTE_ENDTIME: - case Q3DStudio::ATTRIBUTE_NAME: - case Q3DStudio::ATTRIBUTE_EYEBALL: - break; - default: - // Unknown attribute - // QT3DS_ASSERT( false ); - break; - } - } - void PostPropertyChanged(const SRuntimePropertyParser &inParser, Q3DStudio::IPresentation &) - { - SImage &theItem = *static_cast(m_RenderObject); - if (inParser.m_Dirty) - theItem.m_Flags.SetDirty(true); - if (inParser.m_TransformDirty) - theItem.m_Flags.SetTransformDirty(true); - } -}; - -struct SReferencedMaterialTranslator : public Qt3DSTranslator -{ - typedef SReferencedMaterial TNodeType; - SReferencedMaterialTranslator(Q3DStudio::TElement &inElement, TNodeType &inRenderObject) - : Qt3DSTranslator(inElement, inRenderObject) - { - } - - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - TNodeType &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_REFERENCED_MATERIAL_PROPERTIES - case Q3DStudio::ATTRIBUTE_STARTTIME: - case Q3DStudio::ATTRIBUTE_ENDTIME: - case Q3DStudio::ATTRIBUTE_NAME: - case Q3DStudio::ATTRIBUTE_EYEBALL: - break; - default: - // Unknown attribute - // QT3DS_ASSERT( false ); - break; - } - } - void PostPropertyChanged(const SRuntimePropertyParser &inParser, Q3DStudio::IPresentation &) - { - TNodeType &theItem = *static_cast(m_RenderObject); - if (inParser.m_Dirty) - theItem.m_Dirty.SetDirty(); - } -}; - -struct STextTranslator : public SNodeTranslator -{ - typedef SText TNodeType; - STextTranslator(Q3DStudio::TElement &inElement, SText &inRenderObject) - : SNodeTranslator(inElement, inRenderObject) - { - } - void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) - { - SText &theItem = *static_cast(m_RenderObject); - switch (inParser.m_PropertyName) { - ITERATE_QT3DS_RENDER_TEXT_PROPERTIES - case Q3DStudio::ATTRIBUTE_TEXTTYPE: - case Q3DStudio::ATTRIBUTE_RENDERSTYLE: - case Q3DStudio::ATTRIBUTE_HORZSCROLL: - case Q3DStudio::ATTRIBUTE_VERTSCROLL: - case Q3DStudio::ATTRIBUTE_BOXHEIGHT: - case Q3DStudio::ATTRIBUTE_BOXWIDTH: - case Q3DStudio::ATTRIBUTE_REMOTESTRINGSOURCE: - case Q3DStudio::ATTRIBUTE_CACHEDTEXTSTRING: - // These text properties are ignored for now. - break; - default: - SNodeTranslator::OnSpecificPropertyChange(inParser); - break; - } - } -}; - -struct SEffectPropertyEntry -{ - Q3DStudio::EAttributeType m_AttributeType; - QT3DSU32 m_PropertyOffset; // offset into the property array for the property def - QT3DSU32 m_DataOffset; - SEffectPropertyEntry(Q3DStudio::EAttributeType attType, QT3DSU32 poff, QT3DSU32 doff = 0) - : m_AttributeType(attType) - , m_PropertyOffset(poff) - , m_DataOffset(doff) - { - } -}; - -struct SDynamicObjectTranslatorContext : public STranslatorContext -{ - typedef nvhash_map THashToOffsetMap; - THashToOffsetMap m_PropertyHashes; - NVAllocatorCallback &m_Allocator; - CRenderString m_Workspace; - SDynamicObjectTranslatorContext(NVAllocatorCallback &inCallback) - : m_PropertyHashes(inCallback, "SEffectTranslatorContext::PropertyHashes") - , m_Allocator(inCallback) - { - } - ~SDynamicObjectTranslatorContext() {} - void AddEffectExtendedProperty(const qt3ds::render::dynamic::SPropertyDefinition &thePropDef, - const char *inExtension, Q3DStudio::EAttributeType inType, - CRenderString &ioStringBuilder, QT3DSU32 inOffset, QT3DSU32 dataOffset) - { - ioStringBuilder.assign(thePropDef.m_Name.c_str()); - ioStringBuilder.append(inExtension); - Q3DStudio::INT32 theHash = Q3DStudio::CHash::HashAttribute(ioStringBuilder.c_str()); - m_PropertyHashes.insert( - eastl::make_pair(theHash, SEffectPropertyEntry(inType, inOffset, dataOffset))); - } - void BuildPropertyHashes(NVConstDataRef inProperties) - { - if (m_PropertyHashes.size() == 0) { - qt3ds::render::CRenderString theNameBuilder; - for (QT3DSU32 idx = 0, end = inProperties.size(); idx < end; ++idx) { - const qt3ds::render::dynamic::SPropertyDefinition &thePropDef = inProperties[idx]; - switch (thePropDef.m_DataType) { - case qt3ds::render::NVRenderShaderDataTypes::QT3DSF32: - m_PropertyHashes.insert(eastl::make_pair( - Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), - SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_FLOAT, idx))); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSRenderBool: - m_PropertyHashes.insert( - eastl::make_pair(Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), - SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_BOOL, idx))); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSI32: - if (thePropDef.m_IsEnumProperty == false) { - m_PropertyHashes.insert(eastl::make_pair( - Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), - SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_INT32, idx))); - } else { - m_PropertyHashes.insert(eastl::make_pair( - Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), - SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_STRING, idx))); - } - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec2: - AddEffectExtendedProperty(thePropDef, ".x", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 0); - AddEffectExtendedProperty(thePropDef, ".y", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, sizeof(QT3DSF32)); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec3: - AddEffectExtendedProperty(thePropDef, ".x", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 0); - AddEffectExtendedProperty(thePropDef, ".y", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, sizeof(QT3DSF32)); - AddEffectExtendedProperty(thePropDef, ".z", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 2 * sizeof(QT3DSF32)); - - AddEffectExtendedProperty(thePropDef, ".r", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 0); - AddEffectExtendedProperty(thePropDef, ".g", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, sizeof(QT3DSF32)); - AddEffectExtendedProperty(thePropDef, ".b", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 2 * sizeof(QT3DSF32)); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4: - AddEffectExtendedProperty(thePropDef, ".x", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 0); - AddEffectExtendedProperty(thePropDef, ".y", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, sizeof(QT3DSF32)); - AddEffectExtendedProperty(thePropDef, ".z", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 2 * sizeof(QT3DSF32)); - AddEffectExtendedProperty(thePropDef, ".w", Q3DStudio::ATTRIBUTETYPE_FLOAT, - theNameBuilder, idx, 3 * sizeof(QT3DSF32)); - break; - case qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr: - case qt3ds::render::NVRenderShaderDataTypes::NVRenderImage2DPtr: - m_PropertyHashes.insert(eastl::make_pair( - Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), - SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_STRING, idx))); - break; - case qt3ds::render::NVRenderShaderDataTypes::NVRenderDataBufferPtr: - break; - default: - QT3DS_ASSERT(false); - break; - } - } - } - } - void ApplyChanges(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, - SDynamicObject &inObject, Q3DStudio::TElement &element, - IDynamicObjectSystem &inSystem) - { - if (element.GetActive()) { - NVConstDataRef theProperties = - inSystem.GetProperties(inObject.m_ClassName); - BuildPropertyHashes(theProperties); - SDynamicObject &theItem(inObject); - for (long idx = 0, end = element.GetAttributeCount(); idx < end; ++idx) { - qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = - *element.GetPropertyByIndex(idx); - THashToOffsetMap::iterator theFind = - m_PropertyHashes.find(thePropInfo.first.GetNameHash()); - if (theFind != m_PropertyHashes.end()) { - const SEffectPropertyEntry &theEntry(theFind->second); - const qt3ds::render::dynamic::SPropertyDefinition &theDefinition( - theProperties[theEntry.m_PropertyOffset]); - if (theEntry.m_AttributeType - == (Q3DStudio::EAttributeType)thePropInfo.first.m_Type) { - switch (theEntry.m_AttributeType) { - case Q3DStudio::ATTRIBUTETYPE_BOOL: - theItem.SetPropertyValue(theDefinition, - thePropInfo.second->m_INT32 ? true : false); - break; - case Q3DStudio::ATTRIBUTETYPE_FLOAT: - theItem.SetPropertyValue(theDefinition, thePropInfo.second->m_FLOAT, - theEntry.m_DataOffset); - break; - case Q3DStudio::ATTRIBUTETYPE_INT32: - theItem.SetPropertyValue(theDefinition, - (QT3DSI32)thePropInfo.second->m_INT32); - break; - case Q3DStudio::ATTRIBUTETYPE_STRING: { - CRegisteredString theStr = - element.GetBelongedPresentation()->GetStringTable().HandleToStr( - thePropInfo.second->m_StringHandle); - theItem.SetPropertyValue(theDefinition, theStr.c_str(), - inPresentation.m_PresentationDirectory.c_str(), - m_Workspace, inRenderContext.GetStringTable()); - } break; - default: - // QT3DS_ASSERT( false ); - break; - } - } else { - // QT3DS_ASSERT( false ); - } - } - } - theItem.m_Flags.SetDirty(true); - } - } -}; - -struct SEffectTranslator : public Qt3DSTranslator -{ - typedef SEffect TNodeType; - SEffectTranslator(Q3DStudio::TElement &inElement, SEffect &inRenderObject, - NVAllocatorCallback &inCallback) - : Qt3DSTranslator(inElement, inRenderObject) - { - m_TranslatorContext = QT3DS_NEW(inCallback, SDynamicObjectTranslatorContext)(inCallback); - } - - void OnElementChanged(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &) - { - SRuntimePropertyParser theParser(inPresentation, inRenderContext, *m_Element); - SEffect &theItem = *static_cast(m_RenderObject); - static_cast(m_TranslatorContext) - ->ApplyChanges(inPresentation, inRenderContext, theItem, Element(), - inRenderContext.GetDynamicObjectSystem()); - theItem.SetActive(Element().GetActive(), inRenderContext.GetEffectSystem()); - } -}; - -struct SCustomMaterialTranslator : public Qt3DSTranslator -{ - typedef SCustomMaterial TNodeType; - SCustomMaterialTranslator(Q3DStudio::TElement &inElement, SCustomMaterial &inRenderObject, - NVAllocatorCallback &inCallback) - : Qt3DSTranslator(inElement, inRenderObject) - { - m_TranslatorContext = QT3DS_NEW(inCallback, SDynamicObjectTranslatorContext)(inCallback); - } - - void OnElementChanged(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &) - { - SRuntimePropertyParser theParser(inPresentation, inRenderContext, *m_Element); - SCustomMaterial &theItem = *static_cast(m_RenderObject); - static_cast(m_TranslatorContext) - ->ApplyChanges(inPresentation, inRenderContext, theItem, Element(), - inRenderContext.GetDynamicObjectSystem()); - bool active = m_Element->GetActive(); - if (active != theItem.m_Flags.IsActive()) { - theItem.m_Flags.SetActive(active); - ICustomMaterialSystem &theSystem(inRenderContext.GetCustomMaterialSystem()); - theSystem.OnMaterialActivationChange(theItem, active); - } - } -}; - -struct SRenderPluginTranslatorContext : public STranslatorContext -{ - NVAllocatorCallback &m_Allocator; - nvhash_map m_AttribHashIndexMap; - nvvector m_PropertyUpdates; - SRenderPluginTranslatorContext(NVAllocatorCallback &alloc) - : m_Allocator(alloc) - , m_AttribHashIndexMap(alloc, "SRenderPluginTranslatorContext::AttribIndexMap") - , m_PropertyUpdates(alloc, "SRenderPluginTranslatorContext::m_PropertyUpdates") - { - } - void ReverseMap(CRegisteredString str) - { - m_AttribHashIndexMap.insert( - eastl::make_pair(Q3DStudio::CHash::HashAttribute(str.c_str()), str)); - } -}; - -struct SRenderPluginTranslator : public Qt3DSTranslator -{ - typedef SRenderPlugin TNodeType; - SRenderPluginTranslator(Q3DStudio::TElement &inElement, SRenderPlugin &inRenderObject, - NVAllocatorCallback &inCallback) - : Qt3DSTranslator(inElement, inRenderObject) - { - m_TranslatorContext = QT3DS_NEW(inCallback, SRenderPluginTranslatorContext)(inCallback); - } - - void OnElementChanged(SPresentation & /*inPresentation*/, IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &) - { - SRenderPlugin &theItem = *static_cast(m_RenderObject); - theItem.m_Flags.SetActive(Element().GetActive()); - IRenderPluginInstance *theInstance = - inRenderContext.GetRenderPluginManager().GetOrCreateRenderPluginInstance( - theItem.m_PluginPath, &theItem); - if (theInstance != NULL) { - IRenderPluginClass &theClass(theInstance->GetPluginClass()); - SRenderPluginTranslatorContext &theTransContext = - static_cast(*m_TranslatorContext); - if (theTransContext.m_AttribHashIndexMap.empty()) { - NVConstDataRef theProperties( - theClass.GetRegisteredProperties()); - for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { - const SRenderPluginPropertyDeclaration &theDec(theProperties[idx]); - switch (theDec.m_Type) { - case SRenderPluginPropertyTypes::Boolean: - theTransContext.ReverseMap(theDec.m_Name); - break; - case SRenderPluginPropertyTypes::Float: - theTransContext.ReverseMap(theDec.m_Name); - break; - case SRenderPluginPropertyTypes::Long: - theTransContext.ReverseMap(theDec.m_Name); - break; - case SRenderPluginPropertyTypes::String: - theTransContext.ReverseMap(theDec.m_Name); - break; - case SRenderPluginPropertyTypes::Vector2: - theTransContext.ReverseMap( - theClass.GetPropertyValueInfo(theDec.m_StartOffset).first); - theTransContext.ReverseMap( - theClass.GetPropertyValueInfo(theDec.m_StartOffset + 1).first); - break; - case SRenderPluginPropertyTypes::Vector3: - case SRenderPluginPropertyTypes::Color: - theTransContext.ReverseMap( - theClass.GetPropertyValueInfo(theDec.m_StartOffset).first); - theTransContext.ReverseMap( - theClass.GetPropertyValueInfo(theDec.m_StartOffset + 1).first); - theTransContext.ReverseMap( - theClass.GetPropertyValueInfo(theDec.m_StartOffset + 2).first); - break; - default: - // QT3DS_ASSERT( false ); - break; - } - } - } // ok, now we have an efficient mapping from attribute to plugin value name. - theTransContext.m_PropertyUpdates.clear(); - for (long idx = 0, end = Element().GetAttributeCount(); idx < end; ++idx) { - qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = - *Element().GetPropertyByIndex(idx); - nvhash_map::iterator theFind = - theTransContext.m_AttribHashIndexMap.find(thePropInfo.first.GetNameHash()); - if (theFind != theTransContext.m_AttribHashIndexMap.end()) { - CRegisteredString thePropName(theFind->second); - Q3DStudio::EAttributeType theType = - (Q3DStudio::EAttributeType)thePropInfo.first.m_Type; - switch (theType) { - case Q3DStudio::ATTRIBUTETYPE_BOOL: - theTransContext.m_PropertyUpdates.push_back(SRenderPropertyValueUpdate( - thePropName, thePropInfo.second->m_INT32 ? true : false)); - break; - case Q3DStudio::ATTRIBUTETYPE_FLOAT: - theTransContext.m_PropertyUpdates.push_back( - SRenderPropertyValueUpdate(thePropName, thePropInfo.second->m_FLOAT)); - break; - case Q3DStudio::ATTRIBUTETYPE_INT32: - theTransContext.m_PropertyUpdates.push_back(SRenderPropertyValueUpdate( - thePropName, (QT3DSI32)thePropInfo.second->m_INT32)); - break; - case Q3DStudio::ATTRIBUTETYPE_STRING: { - CRegisteredString theStr = inRenderContext.GetStringTable().HandleToStr( - thePropInfo.second->m_StringHandle); - theTransContext.m_PropertyUpdates.push_back( - SRenderPropertyValueUpdate(thePropName, theStr)); - } break; - default: - // QT3DS_ASSERT( false ); - break; - } - } - } - if (theTransContext.m_PropertyUpdates.empty() == false) { - theInstance->Update(toConstDataRef(theTransContext.m_PropertyUpdates.data(), - theTransContext.m_PropertyUpdates.size())); - } - } - } -}; -} - -Qt3DSTranslator::Qt3DSTranslator(Q3DStudio::TElement &inElement, SGraphObject &inRenderObject) - : m_DirtyIndex(QT3DS_MAX_U32) - , m_Element(&inElement) - , m_RenderObject(&inRenderObject) - , m_TranslatorContext(NULL) -{ - Element().SetAssociation(reinterpret_cast(this)); - inRenderObject.m_UserData = STaggedPointer(this); -} - -void Qt3DSTranslator::Save(SWriteBuffer &inWriteBuffer, QT3DSU32 inGraphObjectOffset) -{ - // We have to start on pointer aligned boundaries. - QT3DS_ASSERT(inWriteBuffer.size() % 4 == 0); - QT3DSU32 theOffset = inWriteBuffer.size(); - inWriteBuffer.write(*this); - Qt3DSTranslator *theNewTranslator = - reinterpret_cast(inWriteBuffer.begin() + theOffset); - theNewTranslator->m_DirtyIndex = QT3DS_MAX_U32; - if (theNewTranslator->m_Element) - theNewTranslator->m_Element = m_Element->GetBelongedPresentation() - ->GetApplication() - .GetElementAllocator() - .GetRemappedElementAddress(m_Element); - size_t *graphObjPtr = reinterpret_cast(&theNewTranslator->m_RenderObject); - *graphObjPtr = inGraphObjectOffset; -} - -Qt3DSTranslator *Qt3DSTranslator::GetTranslatorFromGraphNode(SGraphObject &inObject) -{ - return inObject.m_UserData.DynamicCast(); -} - -namespace { -struct SPresentationTranslator; -struct SEffectTranslator; -template -struct STranslatorCreator -{ - static TTranslatorType *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, - NVAllocatorCallback &inAllocator) - { - typedef typename TTranslatorType::TNodeType TNodeType; - // This assert needs to be here because we serialize all translators generically without - // regard for type. - StaticAssert::valid_expression(); - return QT3DS_NEW(inAllocator, TTranslatorType)(inElement, static_cast(inObject)); - } - static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &) - { - typedef typename TTranslatorType::TNodeType TNodeType; - // Initialize the vtable. - new (&inTranslator) TTranslatorType(inTranslator.Element(), - static_cast(inTranslator.RenderObject())); - } - - static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, - IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &inStudioPresentation) - { - TTranslatorType &theTranslator(static_cast(inTranslator)); - SRuntimePropertyParser theParser(inPresentation, inRenderContext, *theTranslator.m_Element); - if (theTranslator.Element().GetActive()) { - // Don't push properties from inactive elements. - for (long idx = 0, end = theTranslator.Element().GetAttributeCount(); idx < end; - ++idx) { - qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = - *theTranslator.Element().GetPropertyByIndex(idx); - theParser.Setup(thePropInfo.first.GetNameHash(), *thePropInfo.second, - (Q3DStudio::EAttributeType)thePropInfo.first.m_Type); - // right now, this is the best we can do because the attribute's dirty system - // is all jacked up. - theTranslator.OnSpecificPropertyChange(theParser); - } - // same for dynamic properties - for (long idx = 0, end = theTranslator.Element().GetDynamicAttributeCount(); idx < end; - ++idx) { - qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = - *theTranslator.Element().GetDynamicPropertyByIndex(idx); - theParser.Setup(thePropInfo.first.GetNameHash(), *thePropInfo.second, - (Q3DStudio::EAttributeType)thePropInfo.first.m_Type); - // right now, this is the best we can do because the attribute's dirty system - // is all jacked up. - theTranslator.OnSpecificPropertyChange(theParser); - } - // Set appropriate dirty flags - } - theTranslator.PostPropertyChanged(theParser, inStudioPresentation); - } -}; - -template <> -struct STranslatorCreator -{ - static Qt3DSTranslator *Create(Q3DStudio::TElement &, SGraphObject &, NVAllocatorCallback &) - { - return NULL; - } - static void InitializeTranslator(Qt3DSTranslator &, NVAllocatorCallback &) {} - static void OnElementChanged(Qt3DSTranslator & /*inTranslator*/, - SPresentation & /*inPresentation*/ - , - IQt3DSRenderContext & /*inRenderContext*/, - Q3DStudio::IPresentation & /*inStudioPresentation*/) - { - QT3DS_ASSERT(false); - } -}; - -template <> -struct STranslatorCreator -{ - static SEffectTranslator *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, - NVAllocatorCallback &inAllocator) - { - typedef SEffectTranslator::TNodeType TNodeType; - // This assert needs to be here because we serialize all translators generically without - // regard for type. - StaticAssert::valid_expression(); - return QT3DS_NEW(inAllocator, SEffectTranslator)(inElement, static_cast(inObject), - inAllocator); - } - - static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &inAllocator) - { - typedef SEffectTranslator::TNodeType TNodeType; - // Initialize the vtable. - new (&inTranslator) - SEffectTranslator(inTranslator.Element(), - static_cast(inTranslator.RenderObject()), inAllocator); - } - static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, - IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &inStudioPresentation) - { - static_cast(inTranslator) - .OnElementChanged(inPresentation, inRenderContext, inStudioPresentation); - } -}; - -template <> -struct STranslatorCreator -{ - static SCustomMaterialTranslator *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, - NVAllocatorCallback &inAllocator) - { - typedef SCustomMaterialTranslator::TNodeType TNodeType; - // This assert needs to be here because we serialize all translators generically without - // regard for type. - StaticAssert::valid_expression(); - return QT3DS_NEW(inAllocator, SCustomMaterialTranslator)( - inElement, static_cast(inObject), inAllocator); - } - - static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &inAllocator) - { - typedef SCustomMaterialTranslator::TNodeType TNodeType; - // Initialize the vtable. - new (&inTranslator) SCustomMaterialTranslator( - inTranslator.Element(), static_cast(inTranslator.RenderObject()), - inAllocator); - } - - static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, - IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &inStudioPresentation) - { - static_cast(inTranslator) - .OnElementChanged(inPresentation, inRenderContext, inStudioPresentation); - } -}; - -template <> -struct STranslatorCreator -{ - static SRenderPluginTranslator *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, - NVAllocatorCallback &inAllocator) - { - typedef SRenderPluginTranslator::TNodeType TNodeType; - // This assert needs to be here because we serialize all translators generically without - // regard for type. - StaticAssert::valid_expression(); - return QT3DS_NEW(inAllocator, SRenderPluginTranslator)( - inElement, static_cast(inObject), inAllocator); - } - - static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &inAllocator) - { - typedef SRenderPluginTranslator::TNodeType TNodeType; - // Initialize the vtable. - new (&inTranslator) SRenderPluginTranslator( - inTranslator.Element(), static_cast(inTranslator.RenderObject()), - inAllocator); - } - static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, - IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &inStudioPresentation) - { - static_cast(inTranslator) - .OnElementChanged(inPresentation, inRenderContext, inStudioPresentation); - } -}; -} -Qt3DSTranslator *Qt3DSTranslator::CreateTranslatorForElement(Q3DStudio::TElement &inElement, - SGraphObject &inObject, - NVAllocatorCallback &inAlloc) -{ - Qt3DSTranslator *theTranslator = NULL; - switch (inObject.m_Type) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case GraphObjectTypes::type: \ - theTranslator = \ - STranslatorCreator::Create(inElement, inObject, inAlloc); \ - break; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - QT3DS_ASSERT(false); - break; - } - return theTranslator; -} - -void Qt3DSTranslator::OnElementChanged(SPresentation &inPresentation, - IQt3DSRenderContext &inRenderContext, - Q3DStudio::IPresentation &inStudioPresentation) -{ - switch (m_RenderObject->m_Type) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case GraphObjectTypes::type: \ - STranslatorCreator::OnElementChanged( \ - *this, inPresentation, inRenderContext, inStudioPresentation); \ - break; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - QT3DS_ASSERT(false); - break; - } -} - -Qt3DSTranslator *Qt3DSTranslator::LoadTranslator(SDataReader &inReader, size_t inElemOffset, - NVDataRef inSGSection, - NVAllocatorCallback &inAllocator) -{ - // Reader points to a new translator but we don't know what type - QT3DSU8 *theTranslatorStart = inReader.m_CurrentPtr; - // Make sure things are aligned - (void)theTranslatorStart; - QT3DS_ASSERT((size_t)theTranslatorStart % 4 == 0); - Qt3DSTranslator *theTranslator = inReader.Load(); - if (theTranslator) { - size_t *elemPtr = reinterpret_cast(&theTranslator->m_Element); - *elemPtr += inElemOffset; - size_t *graphObjPtr = reinterpret_cast(&theTranslator->m_RenderObject); - size_t sgSectionStart = reinterpret_cast(inSGSection.begin()); - *graphObjPtr += sgSectionStart; - // Call actual constructor to initialize vtable. - switch (theTranslator->RenderObject().m_Type) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case GraphObjectTypes::type: \ - STranslatorCreator::InitializeTranslator(*theTranslator, \ - inAllocator); \ - break; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - QT3DS_ASSERT(false); - break; - } - } - return theTranslator; -} -Q3DStudio::IPresentation * -Qt3DSTranslator::GetPresentationFromPresentation(SPresentation &inPresentation) -{ - return inPresentation.m_UserData.DynamicCast(); -} - -void Qt3DSTranslator::InitializePointerTags(IStringTable &) -{ - g_TranslatorTag = 0x0044FEED; - g_PresentationTag = 0x0022ABBA; -} - -void Qt3DSTranslator::AssignUserData(Q3DStudio::IPresentation &inPresentation, - SPresentation &inGraphPresentation) -{ - inGraphPresentation.m_UserData = STaggedPointer(&inPresentation); -} diff --git a/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp b/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp deleted file mode 100644 index 92c7f6cc..00000000 --- a/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp +++ /dev/null @@ -1,746 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTegraApplication.h" -#include "Qt3DSTegraInputEngine.h" -#include "Qt3DSDataLogger.h" -#include "Qt3DSFileStream.h" -#include "Qt3DSArray.h" -#include "Qt3DSApplication.h" -#include "foundation/FileTools.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSPresentation.h" -#include "EASTL/string.h" -#include "Qt3DSMemory.h" -#include "Qt3DSKernelTypes.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderer.h" - -#include "Qt3DSDLLManager.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/TrackingAllocator.h" -// For perf log timestamp -#include -#include "Qt3DSArray.h" -// For perf log timestamp -#include - -#if Q_OS_WINDOWS -#include "qt3ds_launcher_defs.h" -#endif - -#ifdef _LINUXPLATFORM -#include -#include -#endif - -#ifdef ANDROID -#include -#endif - -#include -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace qt3ds { -namespace render { -extern qt3ds::foundation::MallocAllocator g_BaseAllocator; -} -} - -namespace Q3DStudio { - -namespace { - -bool CaselessEqual(const char *lhs, const char *rhs) -{ - if (lhs == NULL) - lhs = ""; - if (rhs == NULL) - rhs = ""; - return Q3DStudio_stricmp(lhs, rhs) == 0; -} - -CInputEngine *CreateInputEngine() -{ - return Q3DStudio_virtual_new(CTegraInputEngine) CTegraInputEngine(); -} - -static eastl::string *theAppDir = nullptr; -const eastl::string &GetAppDir(const eastl::string &inAppExe) -{ - if (!theAppDir) - theAppDir = new eastl::string; -#ifndef __ANDROID__ - theAppDir->assign(inAppExe.empty() == false ? inAppExe : ""); -#ifdef Qt3DS_OS_LINUX - char theBuf[1024] = { 0 }; - int rc = readlink("/proc/self/exe", theBuf, sizeof(theBuf)); - if (rc > 0) - theAppDir->assign(theBuf); -#endif -#ifdef Qt3DS_OS_QNX - char theBuf[1024] = { 0 }; - FILE *exefile = fopen("/proc/self/exefile", "r"); - if (exefile != NULL) { - fgets(theBuf, sizeof(theBuf), exefile); - fclose(exefile); - theAppDir->assign(theBuf); - } -#endif - eastl::string::size_type pos = theAppDir->find_last_of("\\/"); - if (pos != eastl::string::npos) - *theAppDir = theAppDir->substr(0, pos); - theAppDir->append("\\"); -#endif - return *theAppDir; -} -} - -using namespace qt3ds; -using namespace qt3ds::foundation; - -//============================================================================== -/** - * CNDDView - */ -class CNDDView : public INDDView -{ - //============================================================================== - // Fields - //============================================================================== -private: - ITegraApplicationRenderEngine *m_RenderEngine; ///< Handles all rendering functions - CTegraInputEngine *m_InputEngine; ///< Handles all user input events - // Pre graphics init objects - NVScopedRefCounted m_RuntimeFactoryCore; - NVScopedRefCounted - m_ApplicationCore; ///< Base application before graphis - - // Post graphics init objects - NVScopedRefCounted m_RuntimeFactory; - NVScopedRefCounted m_Application; ///< Application after graphics - CPresentation *m_Presentation; ///< Currently loaded presentation, this should be removed in the future - - CPausingTimeProvider m_TimeProvider; - IWindowSystem &m_WindowSystem; - IAudioPlayer *m_AudioPlayer; - - volatile QT3DSI32 mRefCount; - - qt3ds::Qt3DSAssetVisitor *m_visitor; - bool m_showOnScreenStats; - -public: - CNDDView(ITimeProvider &inTimeProvider, IWindowSystem &inWindowSystem, - IAudioPlayer *inAudioPlayer); - ~CNDDView(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(qt3ds::render::g_BaseAllocator); - - bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override; - bool HasOfflineLoadingCompleted() override; - bool InitializeGraphics(const QSurfaceFormat &format) override; - - void Cleanup() override; - - bool CanRender() override; - void Render() override; - bool WasLastFrameDirty() override; - - bool HandleMessage(const QEvent *inEvent) override; - - void Pause() override; - void UnPause() override; - bool IsPaused() override; - void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) override; - - INT32 GetFrameCount() override; - void showOnScreenStats(bool) override; - - CInputEngine *GetInputEngine() override; - // Only valid after InitializeGraphics - ITegraApplicationRenderEngine *GetTegraRenderEngine() override { return m_RenderEngine; } - - void GoToSlideByName(const char *elementPath, const char *slideName) override; - void GoToSlideByIndex(const char *elementPath, const int slideIndex) override; - void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) override; - bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) override; - void SetPresentationAttribute(const char *presId, const char *, const char *value) override; - void GoToTime(const char *elementPath, const float time) override; - void SetGlobalAnimationTime(qint64 inMilliSecs) override; - void SetDataInputValue(const QString &name, const QVariant &value); - void SetAttribute(const char *elementPath, const char *attributeName, const char *value) override; - bool GetAttribute(const char *elementPath, const char *attributeName, void *value) override; - void FireEvent(const char *element, const char *evtName) override; - bool PeekCustomAction(char *&outElementPath, char *&outActionName) override; - bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) override; - void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) override; - qt3ds::foundation::Option GetPresentationSize() override; - - void BootupPreGraphicsInitObjects(); -}; - -CNDDView::CNDDView(ITimeProvider &inTimeProvider, IWindowSystem &inWindowSystem, - IAudioPlayer *inAudioPlayer) - : m_RenderEngine(NULL) - , m_InputEngine(NULL) - , m_Application(NULL) - , m_Presentation(NULL) - , m_TimeProvider(inTimeProvider) - , m_WindowSystem(inWindowSystem) - , m_AudioPlayer(inAudioPlayer) - , mRefCount(0) - , m_visitor(nullptr) - , m_showOnScreenStats(false) -{ -} - -CNDDView::~CNDDView() -{ -} - -bool CNDDView::BeginLoad(const QString &sourcePath, const QStringList &variantList) -{ - bool theResult = false; - - // boot up the application - BootupPreGraphicsInitObjects(); - - // If there was a presentation file then we have to load it or something failed. - if (m_ApplicationCore->BeginLoad(sourcePath.toUtf8(), variantList)) - theResult = true; - else - theResult = false; - - // If Initialize wasn't successful - this means the CShaderFactory failed to initialize - // or, the presentation failed to load. - // - // NOTE: if no presentation was passed, this is 'ok' - if (!theResult) - Cleanup(); - - return theResult; -} - -bool CNDDView::HasOfflineLoadingCompleted() -{ - if (m_Application.mPtr == NULL) { - if (m_ApplicationCore) - return m_ApplicationCore->HasCompletedLoading(); - else - return false; - } - return true; -} - -bool CNDDView::InitializeGraphics(const QSurfaceFormat &format) -{ - m_ApplicationCore->EndLoad(); - // Next call will initialize the render portion of the scenes. This *must* have a loaded - // application to go further as it will bind scene graph data to application data. - m_RuntimeFactory = m_RuntimeFactoryCore->CreateRenderFactory(format); - m_Application - = m_ApplicationCore->CreateApplication(*m_InputEngine, m_AudioPlayer, - *m_RuntimeFactory); - if (!m_Application->createSuccessful()) - return false; - - m_Application->ResetTime(); - m_RenderEngine = &m_RuntimeFactory->CreateRenderEngine(); - m_Presentation = m_Application->GetPrimaryPresentation(); - - QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigSlideEntered, - signalProxy(), &QINDDViewSignalProxy::SigSlideEntered); - QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigSlideExited, - signalProxy(), &QINDDViewSignalProxy::SigSlideExited); - - m_TimeProvider.Reset(); - return true; -} - -void CNDDView::Cleanup() -{ - // Q3DStudio_virtual_delete( m_Timer, CTimer ); - // Q3DStudio_virtual_delete( m_PerfFileStream, CFileStream ); - m_Application = NULL; - Q3DStudio_virtual_delete(m_InputEngine, CTegraInputEngine); - if (m_RenderEngine) { - m_RenderEngine->Release(); - m_RenderEngine = NULL; - } - - CDLLManager &theDLLManager = CDLLManager::GetDLLManager(); - theDLLManager.Cleanup(); - if (m_Presentation) - QObject::disconnect(m_Presentation->signalProxy(), 0, signalProxy(), 0); - - m_InputEngine = NULL; - m_RenderEngine = NULL; - m_Presentation = NULL; -} - -bool CNDDView::CanRender() -{ - return m_Application.mPtr != NULL; -} - -//============================================================================== -/** - * nv_main APP-SPECIFIC rendering call - * returns KD_TRUE to call egl_render and swap properly, KD_FALSE if there has been no scene update - *or redraw. - */ -void CNDDView::Render() -{ - if (m_Application.mPtr == NULL) { - // InitializeGraphics has not been called - QT3DS_ASSERT(false); - } - - PerfLogGeneralEvent1(DATALOGGER_FRAME); - - m_Application->UpdateAndRender(); - - if (m_showOnScreenStats) { - ITegraRenderStateManager &manager - = GetTegraRenderEngine()->GetTegraRenderStateManager(); - manager.PushState(); - - QSize dim = m_WindowSystem.GetWindowDimensions(); - manager.SetScissorTestEnabled(false); - manager.SetViewport(0, 0, dim.width(), dim.height()); - - QPair fps - = m_RuntimeFactory->GetQt3DSRenderContext().GetFPS(); - - QString text; - QTextStream stream(&text); - stream << QStringLiteral("Render Statistics: "); - stream << QString::number(fps.first, 'f', 2); - stream << " fps, frame count "; - stream << QString::number(fps.second); - - // bottom left coordinates - GetTegraRenderEngine()->RenderText2D( - dim.width() / 4, dim.height() - 25, qt3ds::QT3DSVec3(0.0, 1.0, 0.0), - text.toLatin1().constData()); - GetTegraRenderEngine()->RenderGpuProfilerStats( - 20.0, dim.height() - 80, qt3ds::QT3DSVec3(0.0, 1.0, 0.0)); - - manager.PopState(); - } -} - -bool CNDDView::WasLastFrameDirty() -{ - if (m_Application) - return m_Application->IsApplicationDirty(); - return false; -} - -//============================================================================== -/** - * nv_main APP-SPECIFIC message call - * HandleMessage - */ -bool CNDDView::HandleMessage(const QEvent *inEvent) -{ - if (m_Application.mPtr == NULL || m_RenderEngine == NULL) - return 0; - - bool ret = false; - switch (inEvent->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - { - const QMouseEvent *event = static_cast(inEvent); - m_InputEngine->SetPickInput(static_cast(event->x()), - static_cast(event->y()), true); - m_InputEngine->SetPickFlags(inEvent->type() == QEvent::MouseButtonPress - ? LMOUSE_DOWN : LMOUSE_UP); - ret = true; - } - break; - case QEvent::Resize: - { - if (m_Application->GetPrimaryPresentation()) - m_RenderEngine->CheckResize(true, *m_Application->GetPrimaryPresentation()); - ret = true; - } - break; - default: - break; - } - - m_InputEngine->HandleMessage(inEvent, *m_RenderEngine, m_Application->GetPrimaryPresentation()); - return ret ? 1 : 0; -} - -void CNDDView::Pause() -{ - m_TimeProvider.Pause(); -} - -void CNDDView::UnPause() -{ - m_TimeProvider.UnPause(); -} - -bool CNDDView::IsPaused() -{ - return m_TimeProvider.IsPaused(); -} - -INT32 CNDDView::GetFrameCount() -{ - return m_Application->GetFrameCount(); -} - -void CNDDView::showOnScreenStats(bool show) -{ - m_showOnScreenStats = show; -} - -CInputEngine *CNDDView::GetInputEngine() -{ - return m_InputEngine; -} - -//============================================================================== -/** - * Generates an event in the presentation. - */ -void CNDDView::GoToSlideByName(const char *elementPath, const char *slideName) -{ - if (m_Application) { - if (!elementPath || !slideName) - return; - - CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); - IScriptBridge *theBridge = thePresentation->GetScriptBridgeQml(); - - if (!theBridge) - return; - - theBridge->GotoSlide(elementPath, slideName, SScriptEngineGotoSlideArgs()); - } -} - -void CNDDView::GoToSlideByIndex(const char *elementPath, const int slideIndex) -{ - if (m_Application) { - if (!elementPath || slideIndex < 0) - return; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - theBridgeEngine.GotoSlideIndex(elementPath, slideIndex, SScriptEngineGotoSlideArgs()); - } -} - -void CNDDView::GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) -{ - if (m_Application) { - if (!elementPath) - return; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - theBridgeEngine.GotoSlideRelative(elementPath, next, wrap, SScriptEngineGotoSlideArgs()); - } -} - -bool CNDDView::GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) -{ - if (m_Application && elementPath) { - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - return theBridgeEngine.GetSlideInfo(elementPath, currentIndex, previousIndex, - currentName, previousName); - } - return false; -} - -void CNDDView::SetPresentationAttribute(const char *presId, const char *, const char *value) -{ - if (m_Application) { - if (!presId || !value) - return; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - theBridgeEngine.SetPresentationAttribute(presId, nullptr, value); - } -} - -bool CNDDView::RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) -{ - if (m_Application) { - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - return theBridgeEngine.RegisterCallback(callbackType, func, inUserData); - } - - return false; -} - -void CNDDView::GoToTime(const char *elementPath, const float time) -{ - if (m_Application) { - if (!elementPath || time < 0.0) - return; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - theBridgeEngine.GotoTime(elementPath, time); - } -} - -void CNDDView::SetGlobalAnimationTime(qint64 inMilliSecs) -{ - if (m_Application) - m_Application->SetTimeMilliSecs(inMilliSecs); -} - -void CNDDView::SetDataInputValue(const QString &name, const QVariant &value) -{ - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - theBridgeEngine.SetDataInputValue(name, value); -} - -void CNDDView::SetAttribute(const char *elementPath, const char *attributeName, const char *value) -{ - if (m_Application) { - if (!elementPath || !attributeName || !value) - return; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - theBridgeEngine.SetAttribute(elementPath, attributeName, value); - } -} - -bool CNDDView::GetAttribute(const char *elementPath, const char *attributeName, void *value) -{ - if (m_Application) { - if (!elementPath || !attributeName || !value) - return false; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - return theBridgeEngine.GetAttribute(elementPath, attributeName, (char *)value); - } - - return false; -} - -void CNDDView::FireEvent(const char *element, const char *evtName) -{ - if (m_Application) { - if (!element || !evtName) - return; - - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - theBridgeEngine.FireEvent(element, evtName); - } -} - -bool CNDDView::PeekCustomAction(char *&outElementPath, char *&outActionName) -{ - bool actionAvailable = true; - - if (m_Application) { - Q3DStudio::CQmlEngine &theBridgeEngine - = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); - - Q3DStudio::TElement *theElement = NULL; - actionAvailable = theBridgeEngine.PeekSignal(theElement, outActionName); - if (actionAvailable && theElement) - outElementPath = (char *)theElement->m_Path.c_str(); - } - - return actionAvailable; -} - -void CNDDView::FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) -{ - if (m_Application) { - CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); - TElement *theScene = thePresentation->GetRoot(); - if (inArgument.empty()) { - thePresentation->FireEvent(inEventType, theScene, NULL, NULL, ATTRIBUTETYPE_NONE, - ATTRIBUTETYPE_NONE); - } else { - UVariant inArg; - inArg.m_StringHandle = thePresentation->GetStringTable().GetHandle(inArgument.c_str()); - thePresentation->FireEvent(inEventType, theScene, &inArg, NULL, ATTRIBUTETYPE_STRING, - ATTRIBUTETYPE_NONE); - } - } -} - -qt3ds::foundation::Option CNDDView::GetPresentationSize() -{ - if (m_Application) { - CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); - if (thePresentation) - return thePresentation->GetSize(); - } - return qt3ds::foundation::Empty(); -} - -//============================================================================== -/** - * Perform the initialization steps prior to loading any presentation. - */ -void CNDDView::BootupPreGraphicsInitObjects() -{ - qCInfo(TRACE_INFO) << "CNDDView::BootupPreGraphicsInitObjects: DoInitialize"; - // Create engines and runtime - const eastl::string &theAppDir = QCoreApplication::applicationDirPath().toLatin1().constData(); - - m_RuntimeFactoryCore = qt3ds::render::IQt3DSRenderFactoryCore::CreateRenderFactoryCore( - theAppDir.c_str(), m_WindowSystem, m_TimeProvider); - m_ApplicationCore = qt3ds::runtime::IApplicationCore::CreateApplicationCore(*m_RuntimeFactoryCore, - theAppDir.c_str()); - - if (m_ApplicationCore && m_visitor) - m_ApplicationCore->setAssetVisitor(m_visitor); - - m_InputEngine = static_cast(CreateInputEngine()); - Q3DStudio_ASSERT(m_InputEngine != NULL); - - qCInfo(TRACE_INFO) << "CNDDView::DoInitialize: Successfully initialized!"; -} - -void CNDDView::setAssetVisitor(qt3ds::Qt3DSAssetVisitor *v) -{ - m_visitor = v; - if (m_ApplicationCore) - m_ApplicationCore->setAssetVisitor(v); -} - -INDDView &INDDView::Create(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, - IAudioPlayer *inAudioPlayer) -{ - return *QT3DS_NEW(qt3ds::render::g_BaseAllocator, CNDDView)(inProvider, inWindowSystem, - inAudioPlayer); -} - -QINDDViewSignalProxy *INDDView::signalProxy() -{ - return &m_SignalProxy; -} - -//============================================================================== -/** - * CTegraApplication - */ -CTegraApplication::CTegraApplication(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, - IAudioPlayer *inAudioPlayer) -{ - m_NDDView = INDDView::Create(inProvider, inWindowSystem, inAudioPlayer); -} - -CTegraApplication::~CTegraApplication() -{ -} - -bool CTegraApplication::BeginLoad(const QString &sourcePath, const QStringList &variantList) -{ -#ifndef QT3DS_NO_SEARCH_PATH - // We need these later on in case we try to load any files - // such as images - NvFSAppendSearchPath("/res"); - NvFSAppendSearchPath("/res/.."); - NvFSAppendSearchPath("/data"); -#endif - - bool theResult = false; - - qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Attempting presentation beginload"; - - if (!sourcePath.isEmpty()) { - // If there was a presentation file then we have to load it or something failed. - if (m_NDDView->BeginLoad(sourcePath, variantList)) { - qCInfo(TRACE_INFO) - << "CTegraApplication::BeginLoad: Successfully begin loading presentation: " - << sourcePath; - theResult = true; - } else { - qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Failed to load presentation: " - << sourcePath; - theResult = false; - } - } else { - // If there wasn't, then we are still in an OK state. - qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Presentation file not provided"; - theResult = true; - } - - qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: End beginload"; - return theResult; -} - -bool CTegraApplication::InitializeGraphics(const QSurfaceFormat &format) -{ - return m_NDDView->InitializeGraphics(format); -} - -void CTegraApplication::Render() -{ - m_NDDView->Render(); -} - -bool CTegraApplication::HandleMessage(const QEvent *inEvent) -{ - return m_NDDView->HandleMessage(inEvent); -} -} // namespace Q3DStudio - diff --git a/src/Runtime/Source/Engine/Source/Qt3DSTegraInputEngine.cpp b/src/Runtime/Source/Engine/Source/Qt3DSTegraInputEngine.cpp deleted file mode 100644 index bb9a7f95..00000000 --- a/src/Runtime/Source/Engine/Source/Qt3DSTegraInputEngine.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "EnginePrefix.h" -#include "Qt3DSTegraInputEngine.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * XXX - */ -CTegraInputEngine::CTegraInputEngine() -{ -} - -//============================================================================== -/** - * XXX - */ -CTegraInputEngine::~CTegraInputEngine() -{ -} - -//============================================================================== -/** - * Returns the structure that contains the input information for the current frame. - */ -SInputFrame &CTegraInputEngine::GetInputFrame() -{ - return m_InputFrame; -} - -//============================================================================== -/** - * Handles the input message. - */ -void CTegraInputEngine::HandleMessage(const QEvent *inEvent, - ITegraApplicationRenderEngine &inRenderEngine, - CPresentation *inPresentation) -{ - static bool s_PointerWasDown = false; - - if (NULL == inPresentation) - return; - - switch (inEvent->type()) { - - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - { - const QMouseEvent *event = static_cast(inEvent); - - QPointF pos = event->localPos(); - FLOAT x = pos.x(); - FLOAT y = pos.y(); - - const bool pressed = inEvent->type() == QEvent::MouseButtonPress; - - if (inRenderEngine.IsPickValid(x, y, *inPresentation)) { - // printf( "INPUT x %ld y %ld\n", (int)x, (int)y ); - SetPickInput(x, y, (pressed || s_PointerWasDown) ? true : false); - - if (pressed) { - if (s_PointerWasDown) - SetPickFlags(LMOUSE_DOWN); - else - SetPickFlags(LMOUSE_PRESSED); - - s_PointerWasDown = true; - } else { - if (s_PointerWasDown) - SetPickFlags(LMOUSE_RELEASED); - else - SetPickFlags(LMOUSE_UP); - - s_PointerWasDown = false; - } - } else { - if (s_PointerWasDown) - SetPickFlags(LMOUSE_RELEASED); - else - SetPickFlags(LMOUSE_UP); - - s_PointerWasDown = false; - } - } - break; - default: - break; - } -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/HDR/Include/CUDABSDFMipmap.h b/src/Runtime/Source/HDR/Include/CUDABSDFMipmap.h deleted file mode 100644 index 33e0b91c..00000000 --- a/src/Runtime/Source/HDR/Include/CUDABSDFMipmap.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CUDABSDfMIPMAP_H -#define CUDABSDFMIPMAP_H -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "MipmapBSDF.h" - -#include "Qt3DSRenderLoadedTexture.h" - -#include "Qt3DSTypes.h" -struct cudaGraphicsResource; -#ifdef _LINUXPLATFORM -#define __declspec(dllexport) -#define __cdecl - -#endif -using namespace qt3ds::render; - -class CUDABSDFMipMap : public BSDFMipMap -{ -public: - CUDABSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - ~CUDABSDFMipMap(); - void Build(void *inTextureData, int inTextureDataSize, - NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, - NVRenderTextureFormats::Enum inFormat); - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation); - -private: - void CreateBsdfMipMaps(qt3ds::render::SLoadedTexture &inLoadedImage, void **result, int width, - int height); //, qt3ds::foundation::IPerfTimer& inPerfTimer); - - void BindTexture(); - void TransferTexture(); - - cudaGraphicsResource *m_CudaMipMapResource; - void **md_MipMapsData; - size_t *m_Pitches; - NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; - bool m_TextureBinded; -}; - -#endif diff --git a/src/Runtime/Source/HDR/Include/GLComputeMipMap.h b/src/Runtime/Source/HDR/Include/GLComputeMipMap.h deleted file mode 100644 index a1a7ce5f..00000000 --- a/src/Runtime/Source/HDR/Include/GLComputeMipMap.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLCOMPUTE_BSDF_MIMAP_H -#define GLCOMPUTE_BSDF_MIMAP_H - -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "MipmapBSDF.h" - -#include "Qt3DSRenderLoadedTexture.h" -#include "Qt3DSTypes.h" - -using namespace qt3ds::render; - -class qt3ds::render::NVRenderContext; -class qt3ds::render::NVRenderShaderProgram; -class qt3ds::render::NVRenderTexture2D; - -class GLComputeMipMap : public BSDFMipMap -{ -public: - GLComputeMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - ~GLComputeMipMap(); - void Build(void *inTextureData, int inTextureDataSize, - NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, - NVRenderTextureFormats::Enum inFormat); - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation); - -private: - void CreateLevel0Tex(void *inTextureData, int inTextureDataSize, - NVRenderTextureFormats::Enum inFormat); - - NVScopedRefCounted m_BSDFProgram; - NVScopedRefCounted m_UploadProgram_RGBA8; - NVScopedRefCounted m_UploadProgram_RGB8; - NVScopedRefCounted m_Level0Tex; - bool m_TextureCreated; - - void createComputeProgram(NVRenderContext *context); - NVRenderShaderProgram *getOrCreateUploadComputeProgram(NVRenderContext *context, - NVRenderTextureFormats::Enum inFormat); -}; - -#endif diff --git a/src/Runtime/Source/HDR/Include/HDR.h b/src/Runtime/Source/HDR/Include/HDR.h deleted file mode 100644 index fbc4ea41..00000000 --- a/src/Runtime/Source/HDR/Include/HDR.h +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef HDR_H -#define HDR_H - -#include "foundation/Qt3DSVec3.h" -//#include "HDR.h" - -namespace qt3ds { -class QT3DSVec3; - -namespace HDR { - - template - class HDRConfiguration; - - template - class Histogram - { - public: - /** - * @brief build the histogram based on 2^10 binning. - * - * @param[in] inImage Pointer to image - * @param[in] inWidth Width of image - * @param[in] inHeight Height of image - * @param[out] outHistogram - * - * @return No return - */ - static void Build(QT3DSVec3 *inImage, int inWidth, int inHeight, QT3DSVec3 *outHistogram) - { - long noPixels = inWidth * inHeight; - - for (int i = 0; i < noPixels; ++i) { - outHistogram[(int)inImage[i].x].x++; - outHistogram[(int)inImage[i].y].y++; - outHistogram[(int)inImage[i].z].z++; - } - } - }; - - template - class HDR - { - - public: - HDR(HDRConfiguration *inConfiguration) { mHDRConfiguration = inConfiguration; } - - void Build(QT3DSVec3 **inImages, int inNoImages, int inWidth, int inHeight, float *inExposures, - QT3DSVec3 *outRadiance) - { - for (int x = 0; x < inWidth; ++x) { - for (int y = 0; y < inHeight; ++y) { - QT3DSVec3 divisor(0.0f); - QT3DSVec3 dividend(0.0f); - for (int i = 0; i < inNoImages; ++i) { - QT3DSVec3 pixel = inImages[i][x + y * inWidth]; - - dividend += (LUT(mHDRConfiguration->weights, pixel) * inExposures[i]) - .multiply(LUT(mHDRConfiguration->CRF, pixel)); - divisor += LUT(mHDRConfiguration->weights, pixel) * inExposures[i] - * inExposures[i]; - } - divisor.x = 1.0f / divisor.x; - divisor.y = 1.0f / divisor.y; - divisor.z = 1.0f / divisor.z; - - outRadiance[x + y * inWidth] = dividend.multiply(divisor); - } - } - } - - private: - /** - * @brief Return the value based off from array as a LUT - * - * @param[in] inLUT The LUT table of interest - * @param[in] inValue The value that you have - * @param[out] QT3DSVec3 The corresponding value of array based on input - * tuple - * - * @return No return - */ - QT3DSVec3 LUT(float *inLUT, QT3DSVec3 inValue) - { - return QT3DSVec3(inLUT[(int)inValue.x], inLUT[(int)inValue.y], inLUT[(int)inValue.z]); - } - - QT3DSVec3 LUT(QT3DSVec3 *inLUT, QT3DSVec3 inValue) - { - return QT3DSVec3(inLUT[(int)inValue.x].x, inLUT[(int)inValue.y].y, - inLUT[(int)inValue.z].z); - } - - HDRConfiguration *mHDRConfiguration; - }; - - template - class HDRConfiguration - { - public: - HDRConfiguration() - { - threshold = 0.1f; - maxIterations = 30; - GenerateRobertsonWeighting(); - } - - void SetCRF(QT3DSVec3 *inCRF) { memcpy(CRF, inCRF, sizeof(QT3DSVec3) * N); } - - /** - * @brief build the camera response function - * - * @param[in] inImages Pointer to images - * @param[in] inNoImages Number of images - * @param[in] inWidth Width of image - * @param[in] inHeight Height of image - * @param[out] outHistogram - * - * @return No return - */ - void BuildCRF(QT3DSVec3 **inImages, int inNoImages, int inWidth, int inHeight, - float *inExposures) - { - QT3DSVec3 histogram[N]; - QT3DSVec3 newCRF[N]; - - HDR hdr(this); - - memset(histogram, 0, sizeof(QT3DSVec3) * N); - - for (int i = 0; i < inNoImages; ++i) { - Histogram::Build(inImages[i], inWidth, inHeight, histogram); - } - - for (int i = 0; i < N; ++i) { - histogram[i].x = histogram[i].x > 0 ? 1 / histogram[i].x : 0; - histogram[i].y = histogram[i].y > 0 ? 1 / histogram[i].y : 0; - histogram[i].z = histogram[i].z > 0 ? 1 / histogram[i].z : 0; - } - - QT3DSVec3 *radiance = new QT3DSVec3[inWidth * inHeight * sizeof(QT3DSVec3)]; - - // iteration 0, linearize CRF - for (int i = 0; i < N; ++i) { - CRF[i] = QT3DSVec3((float)i) * 2.0f / N; - } - - for (int iteration = 0; iteration < maxIterations; ++iteration) { - hdr.Build(inImages, inNoImages, inWidth, inHeight, inExposures, radiance); - - memset(newCRF, 0, sizeof(QT3DSVec3) * N); - - for (int i = 0; i < inNoImages; ++i) { - for (int x = 0; x < inWidth; ++x) { - for (int y = 0; y < inHeight; ++y) { - long offset = x + y * inWidth; - QT3DSVec3 pixel = inImages[i][offset]; - newCRF[(int)pixel.x].x += (inExposures[i] * radiance[offset].x); - newCRF[(int)pixel.y].y += (inExposures[i] * radiance[offset].y); - newCRF[(int)pixel.z].z += (inExposures[i] * radiance[offset].z); - } - } - } - - float difference = 0; - for (int i = 0; i < N; ++i) { - newCRF[i] = newCRF[i].multiply(histogram[i]); - } - - QT3DSVec3 middle = newCRF[N / 2]; - for (int i = 0; i < N; ++i) { - newCRF[i].x = newCRF[i].x / middle.x; - newCRF[i].y = newCRF[i].y / middle.y; - newCRF[i].z = newCRF[i].z / middle.z; - difference += (CRF[i] - newCRF[i]).magnitude(); - } - for (int i = 0; i < N; ++i) { - CRF[i] = newCRF[i]; - } - if (difference < threshold) { - break; - } - } - delete[] radiance; - } - - float weights[N]; - QT3DSVec3 CRF[N]; - - private: - void GenerateRobertsonWeighting() - { - // Dynamic Range Improvement Through Multiple Exposures (5) - // gaussian random weighting - float divisor = (N - 1) * (N - 1) / 4.0; - for (int i = 0; i < N; ++i) { - float dividend = (i - (N - 1) / 2.0f); - dividend *= dividend; - weights[i] = exp(-4.0f * dividend / divisor); - } - } - - int maxIterations; - float threshold; - }; -} -} -#endif diff --git a/src/Runtime/Source/HDR/Include/MipmapBSDF.h b/src/Runtime/Source/HDR/Include/MipmapBSDF.h deleted file mode 100644 index be8f1366..00000000 --- a/src/Runtime/Source/HDR/Include/MipmapBSDF.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MIPMAPBSDF_H -#define MIPMAPBSDF_H -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/backends/gl/Qt3DSOpenGLUtil.h" - -#include "Qt3DSRenderLoadedTexture.h" - -#include "Qt3DSTypes.h" -#ifdef _LINUXPLATFORM -#define __declspec(dllexport) -#define __cdecl - -#endif -using namespace qt3ds::render; - -class BSDFMipMap : public NVRefCounted -{ -public: - BSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - virtual ~BSDFMipMap(); - - virtual void Build(void *inTextureData, int inTextureDataSize, - NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, - NVRenderTextureFormats::Enum inFormat) = 0; - static BSDFMipMap *Create(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - -protected: - volatile QT3DSI32 mRefCount; ///< reference count - NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things - - NVRenderTexture2D &m_Texture2D; - NVRenderTextureFormats::Enum m_InternalFormat; - NVRenderTextureFormats::Enum m_DestinationFormat; - int m_Width; - int m_Height; - int m_MaxMipMapLevel; - int m_SizeOfFormat; - int m_SizeOfInternalFormat; - int m_InternalNoOfComponent; - int m_NoOfComponent; - NVRenderContext *m_NVRenderContext; -}; - -class BasicBSDFMipMap : public BSDFMipMap -{ -public: - BasicBSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - - void Build(void *inTextureData, int inTextureDataSize, - NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, - NVRenderTextureFormats::Enum inFormat); - - STextureData CreateBsdfMipLevel(STextureData &inCurMipLevel, STextureData &inPrevMipLevel, - int width, int height); //, IPerfTimer& inPerfTimer ); - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation); - - int wrapMod(int a, int base); - void getWrappedCoords(int &sX, int &sY, int width, int height); - NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; -}; - -#endif diff --git a/src/Runtime/Source/HDR/Source/CUDABSDFMipmap.cpp b/src/Runtime/Source/HDR/Source/CUDABSDFMipmap.cpp deleted file mode 100644 index 94f6712f..00000000 --- a/src/Runtime/Source/HDR/Source/CUDABSDFMipmap.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifdef PLATFORM_HAS_CUDA - -#include "CUDABSDFMipmap.h" -#include "cuda.h" -#include "cuda_runtime.h" -#include "cuda_gl_interop.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "foundation/Qt3DSRefCounted.h" -#include "nv_log.h" - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace qt3ds::foundation; - -__host__ void jerror1(cudaError error); -#ifdef _DEBUG -#define CHECK_AND_HANDLE_CUDA_ERROR(func) \ - func; \ - { \ - cudaError error = cudaGetLastError(); \ - if (error != cudaSuccess) { \ - printf("%s\n", cudaGetErrorString(error)); \ - jerror1(error); \ - QT3DS_ASSERT(false); \ - } \ - } -#else -#define CHECK_AND_HANDLE_CUDA_ERROR(func) func; -#endif - -CUDABSDFMipMap::CUDABSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) - : BSDFMipMap(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd) - , m_TextureBinded(false) -{ - - // CHECK_AND_HANDLE_CUDA_ERROR( cudaFree( 0 ); ) - m_Pitches = (size_t *)QT3DS_ALLOC(m_Foundation.getAllocator(), - sizeof(size_t) * m_MaxMipMapLevel + 1, "BSDF MipMap pitches"); - md_MipMapsData = (void **)QT3DS_ALLOC(m_Foundation.getAllocator(), - sizeof(void *) * m_MaxMipMapLevel + 1, "BSDF MipMap data"); - // CHECK_AND_HANDLE_CUDA_ERROR(); - size_t imagePitch; - int width = m_Width; - int height = m_Height; - - for (int i = 0; i <= m_MaxMipMapLevel; ++i) { - imagePitch = m_SizeOfFormat * width; - // checkCudaErrors(cudaMalloc((void **)&cuda_dest_resource[mip], size_tex_data)); - CHECK_AND_HANDLE_CUDA_ERROR( - cudaMallocPitch((void **)&md_MipMapsData[i], &m_Pitches[i], imagePitch, height);) - CHECK_AND_HANDLE_CUDA_ERROR(cudaMemset(md_MipMapsData[i], -1, m_Pitches[i] * height);) - - width = width > 2 ? width >> 1 : 1; - height = height > 2 ? height >> 1 : 1; - } -} - -CUDABSDFMipMap::~CUDABSDFMipMap() -{ - // CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceReset(); ) - CHECK_AND_HANDLE_CUDA_ERROR(cudaDeviceSynchronize();) - for (int i = 0; i <= m_MaxMipMapLevel; ++i) { - CHECK_AND_HANDLE_CUDA_ERROR(cudaFree(md_MipMapsData[i]);) - } - QT3DS_FREE(m_Foundation.getAllocator(), md_MipMapsData); - QT3DS_FREE(m_Foundation.getAllocator(), m_Pitches); -} - -void CUDABSDFMipMap::BindTexture() -{ - if (!m_TextureBinded) { - m_TextureBinded = true; - - int width = m_Width; - int height = m_Height; - for (int i = 0; i <= m_MaxMipMapLevel; ++i) { - // if you wwant to change some texture filter settings use m_Texture2D object - m_Texture2D.SetTextureData(NVDataRef(), (QT3DSU8)i, width, height, - NVRenderTextureFormats::RGBA16F, - NVRenderTextureFormats::RGBA16F); - - width = width > 2 ? width >> 1 : 1; - height = height > 2 ? height >> 1 : 1; - } - // CHECK_AND_HANDLE_CUDA_ERROR( cudaGraphicsGLRegisterImage( &m_CudaMipMapResource, - // (GLuint)m_TextureHandle, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard | - // cudaGraphicsRegisterFlagsTextureGather) ) - CHECK_AND_HANDLE_CUDA_ERROR(cudaGraphicsGLRegisterImage( - &m_CudaMipMapResource, (GLuint)m_TextureHandle, GL_TEXTURE_2D, - cudaGraphicsRegisterFlagsWriteDiscard | cudaGraphicsRegisterFlagsTextureGather)) - } -} - -void CUDABSDFMipMap::TransferTexture() // after cuda generation -{ - cudaArray *texturePtr; - CHECK_AND_HANDLE_CUDA_ERROR(cudaGraphicsMapResources(1, &m_CudaMipMapResource, 0)) - int width = m_Width; - int height = m_Height; - for (int i = 0; i <= m_MaxMipMapLevel; ++i) { - CHECK_AND_HANDLE_CUDA_ERROR( - cudaGraphicsSubResourceGetMappedArray(&texturePtr, m_CudaMipMapResource, 0, i)) - CHECK_AND_HANDLE_CUDA_ERROR(cudaMemcpy2DToArray(texturePtr, 0, 0, md_MipMapsData[i], - m_Pitches[i], width * m_SizeOfFormat, - height, cudaMemcpyDeviceToDevice)); - - width = width > 2 ? width >> 1 : 1; - height = height > 2 ? height >> 1 : 1; - } - CHECK_AND_HANDLE_CUDA_ERROR(cudaGraphicsUnmapResources(1, &m_CudaMipMapResource, 0)) -} - -#endif diff --git a/src/Runtime/Source/HDR/Source/GLComputeMipmap.cpp b/src/Runtime/Source/HDR/Source/GLComputeMipmap.cpp deleted file mode 100644 index 36b550dd..00000000 --- a/src/Runtime/Source/HDR/Source/GLComputeMipmap.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "GLComputeMipMap.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "render/Qt3DSRenderContext.h" -#include "nv_log.h" -#include - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace qt3ds::foundation; - -static const char *computeUploadShader(std::string &prog, NVRenderTextureFormats::Enum inFormat, - bool binESContext) -{ - if (binESContext) { - prog += "#version 310 es\n" - "#extension GL_ARB_compute_shader : enable\n" - "precision highp float;\n" - "precision highp int;\n" - "precision mediump image2D;\n"; - } else { - prog += "#version 430\n" - "#extension GL_ARB_compute_shader : enable\n"; - } - - if (inFormat == NVRenderTextureFormats::RGBA8) { - prog += "// Set workgroup layout;\n" - "layout (local_size_x = 16, local_size_y = 16) in;\n\n" - "layout (rgba8, binding = 1) uniform image2D inputImage;\n\n" - "layout (rgba16f, binding = 2) uniform image2D outputImage;\n\n" - "void main()\n" - "{\n" - " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " - ">= gl_NumWorkGroups.y )\n" - " return;\n" - " vec4 value = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.xy));\n" - " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), value );\n" - "}\n"; - } else { - prog += "float convertToFloat( in uint inValue )\n" - "{\n" - " uint v = inValue & uint(0xFF);\n" - " float f = float(v)/256.0;\n" - " return f;\n" - "}\n"; - - prog += "int getMod( in int inValue, in int mod )\n" - "{\n" - " int v = mod * (inValue/mod);\n" - " return inValue - v;\n" - "}\n"; - - prog += "vec4 getRGBValue( in int byteNo, vec4 inVal, vec4 inVal1 )\n" - "{\n" - " vec4 result= vec4(0.0);\n" - " if( byteNo == 0) {\n" - " result.r = inVal.r;\n" - " result.g = inVal.g;\n" - " result.b = inVal.b;\n" - " }\n" - " else if( byteNo == 1) {\n" - " result.r = inVal.g;\n" - " result.g = inVal.b;\n" - " result.b = inVal.a;\n" - " }\n" - " else if( byteNo == 2) {\n" - " result.r = inVal.b;\n" - " result.g = inVal.a;\n" - " result.b = inVal1.r;\n" - " }\n" - " else if( byteNo == 3) {\n" - " result.r = inVal.a;\n" - " result.g = inVal1.r;\n" - " result.b = inVal1.g;\n" - " }\n" - " return result;\n" - "}\n"; - - prog += "// Set workgroup layout;\n" - "layout (local_size_x = 16, local_size_y = 16) in;\n\n" - "layout (rgba8, binding = 1) uniform image2D inputImage;\n\n" - "layout (rgba16f, binding = 2) uniform image2D outputImage;\n\n" - "void main()\n" - "{\n" - " vec4 result = vec4(0.0);\n" - " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " - ">= gl_NumWorkGroups.y )\n" - " return;\n" - " int xpos = (int(gl_GlobalInvocationID.x)*3)/4;\n" - " int xmod = getMod(int(gl_GlobalInvocationID.x)*3, 4);\n" - " ivec2 readPos = ivec2(xpos, gl_GlobalInvocationID.y);\n" - " vec4 value = imageLoad(inputImage, readPos);\n" - " vec4 value1 = imageLoad(inputImage, ivec2(readPos.x + 1, readPos.y));\n" - " result = getRGBValue( xmod, value, value1);\n" - " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), result );\n" - "}\n"; - } - return prog.c_str(); -} - -static const char *computeWorkShader(std::string &prog, bool binESContext) -{ - if (binESContext) { - prog += "#version 310 es\n" - "#extension GL_ARB_compute_shader : enable\n" - "precision highp float;\n" - "precision highp int;\n" - "precision mediump image2D;\n"; - } else { - prog += "#version 430\n" - "#extension GL_ARB_compute_shader : enable\n"; - } - - prog += "int wrapMod( in int a, in int base )\n" - "{\n" - " return ( a >= 0 ) ? a % base : -(a % base) + base;\n" - "}\n"; - - prog += "void getWrappedCoords( inout int sX, inout int sY, in int width, in int height )\n" - "{\n" - " if (sY < 0) { sX -= width >> 1; sY = -sY; }\n" - " if (sY >= height) { sX += width >> 1; sY = height - sY; }\n" - " sX = wrapMod( sX, width );\n" - "}\n"; - - prog += "// Set workgroup layout;\n" - "layout (local_size_x = 16, local_size_y = 16) in;\n\n" - "layout (rgba16f, binding = 1) uniform image2D inputImage;\n\n" - "layout (rgba16f, binding = 2) uniform image2D outputImage;\n\n" - "void main()\n" - "{\n" - " int prevWidth = int(gl_NumWorkGroups.x) << 1;\n" - " int prevHeight = int(gl_NumWorkGroups.y) << 1;\n" - " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y >= " - "gl_NumWorkGroups.y )\n" - " return;\n" - " vec4 accumVal = vec4(0.0);\n" - " for ( int sy = -2; sy <= 2; ++sy )\n" - " {\n" - " for ( int sx = -2; sx <= 2; ++sx )\n" - " {\n" - " int sampleX = sx + (int(gl_GlobalInvocationID.x) << 1);\n" - " int sampleY = sy + (int(gl_GlobalInvocationID.y) << 1);\n" - " getWrappedCoords(sampleX, sampleY, prevWidth, prevHeight);\n" - " if ((sampleY * prevWidth + sampleX) < 0 )\n" - " sampleY = prevHeight + sampleY;\n" - " ivec2 pos = ivec2(sampleX, sampleY);\n" - " vec4 value = imageLoad(inputImage, pos);\n" - " float filterPdf = 1.0 / ( 1.0 + float(sx*sx + sy*sy)*2.0 );\n" - " filterPdf /= 4.71238898;\n" - " accumVal[0] += filterPdf * value.r;\n" - " accumVal[1] += filterPdf * value.g;\n" - " accumVal[2] += filterPdf * value.b;\n" - " accumVal[3] += filterPdf * value.a;\n" - " }\n" - " }\n" - " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), accumVal );\n" - "}\n"; - - return prog.c_str(); -} - -GLComputeMipMap::GLComputeMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) - : BSDFMipMap(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd) - , m_BSDFProgram(NULL) - , m_UploadProgram_RGBA8(NULL) - , m_UploadProgram_RGB8(NULL) - , m_Level0Tex(NULL) - , m_TextureCreated(false) -{ -} - -GLComputeMipMap::~GLComputeMipMap() -{ - m_UploadProgram_RGB8 = NULL; - m_UploadProgram_RGBA8 = NULL; - m_BSDFProgram = NULL; - m_Level0Tex = NULL; -} - -inline NVConstDataRef toRef(const char *data) -{ - size_t len = strlen(data) + 1; - return NVConstDataRef((const QT3DSI8 *)data, (QT3DSU32)len); -} - -static bool isGLESContext(NVRenderContext *context) -{ - NVRenderContextType ctxType = context->GetRenderContextType(); - - // Need minimum of GL3 or GLES3 - if (ctxType == NVRenderContextValues::GLES2 || ctxType == NVRenderContextValues::GLES3 - || ctxType == NVRenderContextValues::GLES31) { - return true; - } - - return false; -} - -#define WORKGROUP_SIZE 16 - -void GLComputeMipMap::createComputeProgram(NVRenderContext *context) -{ - std::string computeProg; - - if (!m_BSDFProgram) { - m_BSDFProgram = context - ->CompileComputeSource( - "Compute BSDF mipmap shader", - toRef(computeWorkShader(computeProg, isGLESContext(context)))) - .mShader; - } -} - -NVRenderShaderProgram * -GLComputeMipMap::getOrCreateUploadComputeProgram(NVRenderContext *context, - NVRenderTextureFormats::Enum inFormat) -{ - std::string computeProg; - - if (inFormat == NVRenderTextureFormats::RGB8) { - if (!m_UploadProgram_RGB8) { - m_UploadProgram_RGB8 = - context - ->CompileComputeSource( - "Compute BSDF mipmap level 0 RGB8 shader", - toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) - .mShader; - } - - return m_UploadProgram_RGB8; - } else { - if (!m_UploadProgram_RGBA8) { - m_UploadProgram_RGBA8 = - context - ->CompileComputeSource( - "Compute BSDF mipmap level 0 RGBA8 shader", - toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) - .mShader; - } - - return m_UploadProgram_RGBA8; - } -} - -void GLComputeMipMap::CreateLevel0Tex(void *inTextureData, int inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) -{ - NVRenderTextureFormats::Enum theFormat = inFormat; - int theWidth = m_Width; - - // Since we cannot use RGB format in GL compute - // we treat it as a RGBA component format - if (inFormat == NVRenderTextureFormats::RGB8) { - // This works only with 4 byte aligned data - QT3DS_ASSERT(m_Width % 4 == 0); - theFormat = NVRenderTextureFormats::RGBA8; - theWidth = (m_Width * 3) / 4; - } - - if (m_Level0Tex == NULL) { - m_Level0Tex = m_NVRenderContext->CreateTexture2D(); - m_Level0Tex->SetTextureStorage(1, theWidth, m_Height, theFormat, theFormat, - NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); - } else { - m_Level0Tex->SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, - 0, 0, theWidth, m_Height, theFormat); - } -} - -void GLComputeMipMap::Build(void *inTextureData, int inTextureDataSize, - NVRenderBackend::NVRenderBackendTextureObject, - NVRenderTextureFormats::Enum inFormat) -{ - bool needMipUpload = (inFormat != m_DestinationFormat); - // re-upload data - if (!m_TextureCreated) { - m_Texture2D.SetTextureStorage( - m_MaxMipMapLevel + 1, m_Width, m_Height, m_DestinationFormat, inFormat, (needMipUpload) - ? NVDataRef() - : NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); - m_Texture2D.addRef(); - // create a compute shader (if not aloread done) which computes the BSDF mipmaps for this - // texture - createComputeProgram(m_NVRenderContext); - - if (!m_BSDFProgram) { - QT3DS_ASSERT(false); - return; - } - - m_TextureCreated = true; - } else if (!needMipUpload) { - m_Texture2D.SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, - 0, 0, m_Width, m_Height, inFormat); - } - - if (needMipUpload) { - CreateLevel0Tex(inTextureData, inTextureDataSize, inFormat); - } - - NVScopedRefCounted theInputImage; - NVScopedRefCounted theOutputImage; - theInputImage = - m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); - theOutputImage = - m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); - - if (needMipUpload && m_Level0Tex) { - NVRenderShaderProgram *uploadProg = - getOrCreateUploadComputeProgram(m_NVRenderContext, inFormat); - if (!uploadProg) - return; - - m_NVRenderContext->SetActiveShader(uploadProg); - - NVScopedRefCounted theInputImage0; - theInputImage0 = - m_NVRenderContext->CreateImage2D(m_Level0Tex, NVRenderImageAccessType::ReadWrite); - - theInputImage0->SetTextureLevel(0); - NVRenderCachedShaderProperty theCachedinputImage0("inputImage", - *uploadProg); - theCachedinputImage0.Set(theInputImage0); - - theOutputImage->SetTextureLevel(0); - NVRenderCachedShaderProperty theCachedOutputImage("outputImage", - *uploadProg); - theCachedOutputImage.Set(theOutputImage); - - m_NVRenderContext->DispatchCompute(uploadProg, m_Width, m_Height, 1); - - // sync - NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); - m_NVRenderContext->SetMemoryBarrier(flags); - } - - int width = m_Width >> 1; - int height = m_Height >> 1; - - m_NVRenderContext->SetActiveShader(m_BSDFProgram); - - for (int i = 1; i <= m_MaxMipMapLevel; ++i) { - theOutputImage->SetTextureLevel(i); - NVRenderCachedShaderProperty theCachedOutputImage("outputImage", - *m_BSDFProgram); - theCachedOutputImage.Set(theOutputImage); - theInputImage->SetTextureLevel(i - 1); - NVRenderCachedShaderProperty theCachedinputImage("inputImage", - *m_BSDFProgram); - theCachedinputImage.Set(theInputImage); - - m_NVRenderContext->DispatchCompute(m_BSDFProgram, width, height, 1); - - width = width > 2 ? width >> 1 : 1; - height = height > 2 ? height >> 1 : 1; - - // sync - NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); - m_NVRenderContext->SetMemoryBarrier(flags); - } -} diff --git a/src/Runtime/Source/HDR/Source/HDR.cpp b/src/Runtime/Source/HDR/Source/HDR.cpp deleted file mode 100644 index 9abe2b3b..00000000 --- a/src/Runtime/Source/HDR/Source/HDR.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "HDR.h" diff --git a/src/Runtime/Source/HDR/Source/MipmapBSDF.cpp b/src/Runtime/Source/HDR/Source/MipmapBSDF.cpp deleted file mode 100644 index fd57015e..00000000 --- a/src/Runtime/Source/HDR/Source/MipmapBSDF.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "MipmapBSDF.h" -#include "GLComputeMipMap.h" - -#ifdef PLATFORM_HAS_CUDA -#include "cuda.h" -#include "cuda_runtime.h" -#include "CUDABSDFMipmap.h" -#endif - -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "foundation/Qt3DSRefCounted.h" -#include "nv_log.h" - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace qt3ds::foundation; - -BSDFMipMap::BSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture2D, NVRenderTextureFormats::Enum inDestFormat, - NVFoundationBase &inFnd) - : m_Foundation(inFnd) - , m_Texture2D(inTexture2D) - , m_Width(inWidth) - , m_Height(inHeight) - , m_DestinationFormat(inDestFormat) - , m_NVRenderContext(inNVRenderContext) -{ - // Calculate mip level - int maxDim = inWidth >= inHeight ? inWidth : inHeight; - - m_MaxMipMapLevel = static_cast(logf((float)maxDim) / logf(2.0f)); - // no concept of sizeOfFormat just does'nt make sense - m_SizeOfFormat = NVRenderTextureFormats::getSizeofFormat(m_DestinationFormat); - m_NoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_DestinationFormat); -} - -BSDFMipMap *BSDFMipMap::Create(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd) -{ - BSDFMipMap *theBSDFMipMap = NULL; -#ifdef PLATFORM_HAS_CUDA - int deviceCount; - cudaError_t e = cudaGetDeviceCount(&deviceCount); -#endif - - if (inNVRenderContext->IsComputeSupported()) { - theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), GLComputeMipMap)( - inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); - } else -#ifdef PLATFORM_HAS_CUDA - if (e == cudaSuccess && deviceCount > 0) { - theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), CUDABSDFMipMap)( - inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); - } else -#endif - if (!theBSDFMipMap) { - theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), BasicBSDFMipMap)( - inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); - } - - return theBSDFMipMap; -} - -BasicBSDFMipMap::BasicBSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, - NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) - : BSDFMipMap(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd) -{ -} - -BSDFMipMap::~BSDFMipMap() -{ -} - -void BasicBSDFMipMap::Build(void *inTextureData, int inTextureDataSize, - NVRenderBackend::NVRenderBackendTextureObject, - NVRenderTextureFormats::Enum inFormat) -{ - - m_InternalFormat = inFormat; - m_SizeOfInternalFormat = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); - m_InternalNoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_InternalFormat); - - m_Texture2D.SetTextureData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, - m_Width, m_Height, inFormat, m_DestinationFormat); - - STextureData theMipImage; - STextureData prevImage; - prevImage.data = inTextureData; - prevImage.dataSizeInBytes = inTextureDataSize; - prevImage.format = inFormat; - int curWidth = m_Width; - int curHeight = m_Height; - int size = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); - for (int idx = 1; idx <= m_MaxMipMapLevel; ++idx) { - theMipImage = - CreateBsdfMipLevel(theMipImage, prevImage, curWidth, curHeight); //, m_PerfTimer ); - curWidth = curWidth >> 1; - curHeight = curHeight >> 1; - curWidth = curWidth >= 1 ? curWidth : 1; - curHeight = curHeight >= 1 ? curHeight : 1; - inTextureDataSize = curWidth * curHeight * size; - - m_Texture2D.SetTextureData(toU8DataRef((char *)theMipImage.data, (QT3DSU32)inTextureDataSize), - (QT3DSU8)idx, (QT3DSU32)curWidth, (QT3DSU32)curHeight, theMipImage.format, - m_DestinationFormat); - - if (prevImage.data == inTextureData) - prevImage = STextureData(); - - STextureData temp = prevImage; - prevImage = theMipImage; - theMipImage = temp; - } - QT3DS_FREE(m_Foundation.getAllocator(), theMipImage.data); - QT3DS_FREE(m_Foundation.getAllocator(), prevImage.data); -} - -inline int BasicBSDFMipMap::wrapMod(int a, int base) -{ - return (a >= 0) ? a % base : (a % base) + base; -} - -inline void BasicBSDFMipMap::getWrappedCoords(int &sX, int &sY, int width, int height) -{ - if (sY < 0) { - sX -= width >> 1; - sY = -sY; - } - if (sY >= height) { - sX += width >> 1; - sY = height - sY; - } - sX = wrapMod(sX, width); -} - -STextureData BasicBSDFMipMap::CreateBsdfMipLevel(STextureData &inCurMipLevel, - STextureData &inPrevMipLevel, int width, - int height) //, IPerfTimer& inPerfTimer ) -{ - // SStackPerfTimer __timer( inPerfTimer, "Image BSDF Mip Level" ); - STextureData retval; - int newWidth = width >> 1; - int newHeight = height >> 1; - newWidth = newWidth >= 1 ? newWidth : 1; - newHeight = newHeight >= 1 ? newHeight : 1; - - if (inCurMipLevel.data) { - retval = inCurMipLevel; - retval.dataSizeInBytes = - newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); - } else { - retval.dataSizeInBytes = - newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); - retval.format = inPrevMipLevel.format; // inLoadedImage.format; - retval.data = m_Foundation.getAllocator().allocate( - retval.dataSizeInBytes, "Bsdf Scaled Image Data", __FILE__, __LINE__); - } - - for (int y = 0; y < newHeight; ++y) { - for (int x = 0; x < newWidth; ++x) { - float accumVal[4]; - accumVal[0] = 0; - accumVal[1] = 0; - accumVal[2] = 0; - accumVal[3] = 0; - for (int sy = -2; sy <= 2; ++sy) { - for (int sx = -2; sx <= 2; ++sx) { - int sampleX = sx + (x << 1); - int sampleY = sy + (y << 1); - getWrappedCoords(sampleX, sampleY, width, height); - - // Cauchy filter (this is simply because it's the easiest to evaluate, and - // requires no complex - // functions). - float filterPdf = 1.f / (1.f + float(sx * sx + sy * sy) * 2.f); - // With FP HDR formats, we're not worried about intensity loss so much as - // unnecessary energy gain, - // whereas with LDR formats, the fear with a continuous normalization factor is - // that we'd lose - // intensity and saturation as well. - filterPdf /= (NVRenderTextureFormats::getSizeofFormat(retval.format) >= 8) - ? 4.71238898f - : 4.5403446f; - // filterPdf /= 4.5403446f; // Discrete normalization factor - // filterPdf /= 4.71238898f; // Continuous normalization factor - float curPix[4]; - QT3DSI32 byteOffset = (sampleY * width + sampleX) - * NVRenderTextureFormats::getSizeofFormat(retval.format); - if (byteOffset < 0) { - sampleY = height + sampleY; - byteOffset = (sampleY * width + sampleX) - * NVRenderTextureFormats::getSizeofFormat(retval.format); - } - - NVRenderTextureFormats::decodeToFloat(inPrevMipLevel.data, byteOffset, curPix, - retval.format); - - accumVal[0] += filterPdf * curPix[0]; - accumVal[1] += filterPdf * curPix[1]; - accumVal[2] += filterPdf * curPix[2]; - accumVal[3] += filterPdf * curPix[3]; - } - } - - /* - // Re-adjustment after the fact for the RGBD hack. - if (retval.format == NVRenderTextureFormats::RGBA8 || retval.format == - NVRenderTextureFormats::SRGB8A8) - { - float divVal = (accumVal[0] > accumVal[1]) ? accumVal[0] : accumVal[1]; - divVal = (divVal > accumVal[2]) ? divVal : accumVal[2]; - if (divVal > 1.0) - { - divVal = 1.0f / divVal; - accumVal[0] *= divVal; - accumVal[1] *= divVal; - accumVal[2] *= divVal; - accumVal[3] = divVal; - } - else - accumVal[3] = 1.0f; - } - */ - QT3DSU32 newIdx = - (y * newWidth + x) * NVRenderTextureFormats::getSizeofFormat(retval.format); - - NVRenderTextureFormats::encodeToPixel(accumVal, retval.data, newIdx, retval.format); - } - } - - return retval; -} diff --git a/src/Runtime/Source/HDR/Source/MipmapBSDF.cu b/src/Runtime/Source/HDR/Source/MipmapBSDF.cu deleted file mode 100644 index 6ddac4be..00000000 --- a/src/Runtime/Source/HDR/Source/MipmapBSDF.cu +++ /dev/null @@ -1,404 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#if defined (_PLATFORM_USE_EGL) -#include -#include -#endif - -#include "CUDABSDFMipmap.h" -#include "cuda.h" -#include "cuda_runtime.h" -#include "cuda_gl_interop.h" -#include - -using namespace nv; -using namespace nv::render; -__host__ void jerror1(cudaError error) -{ - static int i = 0; - ++i; -} -#ifdef _DEBUG -#define CHECK_AND_HANDLE_CUDA_ERROR(func) \ - func; \ - { \ - cudaError error = cudaGetLastError(); \ - if ( error != cudaSuccess ) \ - { \ - printf("%s\n", cudaGetErrorString(error)); \ - jerror1(error);\ - NV_ASSERT( false ); \ - } \ - } -#else -#define CHECK_AND_HANDLE_CUDA_ERROR(func) \ -func; -#endif - -__device__ inline int wrapMod( int a, int base ) -{ - int ret = a % base; - if (ret < 0 ) ret += base; - return ret; -} - -__device__ inline void getWrappedCoords( int &sX, int &sY, int width, int height ) -{ - if (sY < 0) { sX -= width >> 1; sY = -sY; } - if (sY >= height) { sX += width >> 1; sY = height - sY; } - sX = wrapMod( sX, width ); - sY = wrapMod( sY, height ); -} - -__device__ void decodeToFloat( void *inPtr, NVU32 byteOfs, float *outPtr, NVRenderTextureFormats::Enum inFmt, unsigned int numberOfComponent ) -{ - outPtr[0] = 0.0f; outPtr[1] = 0.0f; outPtr[2] = 0.0f; outPtr[3] = 0.0f; - NVU8 *src = reinterpret_cast(inPtr); - //float divisor; // If we want to support RGBD? - switch(inFmt) - { - case NVRenderTextureFormats::Alpha8: - outPtr[0] = ((float)src[byteOfs]) / 255.0f; - break; - - case NVRenderTextureFormats::Luminance8: - case NVRenderTextureFormats::LuminanceAlpha8: - case NVRenderTextureFormats::R8: - case NVRenderTextureFormats::RG8: - case NVRenderTextureFormats::RGB8: - case NVRenderTextureFormats::RGBA8: - case NVRenderTextureFormats::SRGB8: - case NVRenderTextureFormats::SRGB8A8: - // NOTE : RGBD Hack here for reference. Not meant for installation. - //divisor = (NVRenderTextureFormats::getSizeofFormat(inFmt) == 4) ? ((float)src[byteOfs+3]) / 255.0f : 1.0f; - for ( NVU32 i = 0; i < numberOfComponent; ++i ) - { - float val = ((float)src[byteOfs + i]) / 255.0f; - outPtr[i] = (i < 3) ? powf(val, 0.4545454545f) : val; - // Assuming RGBA8 actually means RGBD (which is stupid, I know) - //if ( NVRenderTextureFormats::getSizeofFormat(inFmt) == 4 ) { outPtr[i] /= divisor; } - } - //outPtr[3] = divisor; - break; - - case NVRenderTextureFormats::RGBA32F: - outPtr[0] = reinterpret_cast(src+byteOfs)[0]; - outPtr[1] = reinterpret_cast(src+byteOfs)[1]; - outPtr[2] = reinterpret_cast(src+byteOfs)[2]; - outPtr[3] = reinterpret_cast(src+byteOfs)[3]; - break; - case NVRenderTextureFormats::RGB32F: - outPtr[0] = reinterpret_cast(src+byteOfs)[0]; - outPtr[1] = reinterpret_cast(src+byteOfs)[1]; - outPtr[2] = reinterpret_cast(src+byteOfs)[2]; - break; - - case NVRenderTextureFormats::RGBA16F: - /* - for ( NVU32 i = 0; i < 4; ++i ) - { - // NOTE : This only works on the assumption that we don't have any denormals, Infs or NaNs. - // Every pixel in our source image should be "regular" - NVU16 h = reinterpret_cast(src + byteOfs)[i]; - NVU32 sign = (h & 0x8000) << 16; - NVU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); - NVU32 mantissa = ((h & 0x3ff) << 13); - NVU32 result = sign | exponent | mantissa; - - if (h == 0 || h == 0x8000) { result = 0; } // Special case for zero and negative zero - memcpy( reinterpret_cast(outPtr) + i, &result, 4 ); - }*/ - - for ( NVU32 i = 0; i < 2; i++ ) - { - // NOTE : This only works on the assumption that we don't have any denormals, Infs or NaNs. - // Every pixel in our source image should be "regular" - - NVU32 h1 = reinterpret_cast(src + byteOfs)[i]; - - for ( NVU8 j = 0; j < 2; j++ ) - { - NVU16 h = (h1 & (0x0000FFFF << j*16 )) >> j*16; - NVU32 sign = (h & 0x8000) << 16; - NVU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); - NVU32 mantissa = ((h & 0x3ff) << 13); - NVU32 result = sign | exponent | mantissa; - - if (h == 0 || h == 0x8000) { result = 0; } // Special case for zero and negative zero - memcpy( reinterpret_cast(outPtr) + i*2 + j, &result, 4 ); - } - } - break; - - case NVRenderTextureFormats::R11G11B10: - // place holder - NV_ASSERT( false ); - break; - - default: - outPtr[0] = 0.0f; - outPtr[1] = 0.0f; - outPtr[2] = 0.0f; - outPtr[3] = 0.0f; - break; - } -} - -void __device__ encodeToPixel( float *inPtr, void *outPtr, NVU32 byteOfs, NVRenderTextureFormats::Enum inFmt, unsigned int noOfComponent ) -{ - NVU8 *dest = reinterpret_cast(outPtr); - switch(inFmt) - { - case NVRenderTextureFormats::Alpha8: - dest[byteOfs] = NVU8( inPtr[0] * 255.0f ); - break; - - case NVRenderTextureFormats::Luminance8: - case NVRenderTextureFormats::LuminanceAlpha8: - case NVRenderTextureFormats::R8: - case NVRenderTextureFormats::RG8: - case NVRenderTextureFormats::RGB8: - case NVRenderTextureFormats::RGBA8: - case NVRenderTextureFormats::SRGB8: - case NVRenderTextureFormats::SRGB8A8: - for ( NVU32 i = 0; i < noOfComponent; ++i ) - { - inPtr[i] = (inPtr[i] > 1.0f) ? 1.0f : inPtr[i]; - if (i < 3) - dest[byteOfs+i] = NVU8( powf( inPtr[i], 2.2f ) * 255.0f); - else - dest[byteOfs+i] = NVU8( inPtr[i] * 255.0f ); - } - break; - - case NVRenderTextureFormats::RGBA32F: - reinterpret_cast(dest+byteOfs)[0] = inPtr[0]; - reinterpret_cast(dest+byteOfs)[1] = inPtr[1]; - reinterpret_cast(dest+byteOfs)[2] = inPtr[2]; - reinterpret_cast(dest+byteOfs)[3] = inPtr[3]; - break; - case NVRenderTextureFormats::RGB32F: - reinterpret_cast(dest+byteOfs)[0] = inPtr[0]; - reinterpret_cast(dest+byteOfs)[1] = inPtr[1]; - reinterpret_cast(dest+byteOfs)[2] = inPtr[2]; - break; - - case NVRenderTextureFormats::RGBA16F: - for ( NVU32 i = 0; i < 4; ++i ) - { - // NOTE : This also has the limitation of not handling infs, NaNs and denormals, but it should be - // sufficient for our purposes. - if (inPtr[i] > 65519.0f) { inPtr[i] = 65519.0f; } - if (fabs(inPtr[i]) < 6.10352E-5f) { inPtr[i] = 0.0f; } - NVU32 f = reinterpret_cast(inPtr)[i]; - NVU32 sign = (f & 0x80000000) >> 16; - NVI32 exponent = (f & 0x7f800000) >> 23; - NVU32 mantissa = (f >> 13) & 0x3ff; - exponent = exponent - 112; - if (exponent > 31) { exponent = 31; } - if (exponent < 0) { exponent = 0; } - exponent = exponent << 10; - reinterpret_cast(dest + byteOfs)[i] = NVU16(sign | exponent | mantissa); - } - break; - - case NVRenderTextureFormats::R11G11B10: - // place holder - NV_ASSERT( false ); - break; - - default: - dest[byteOfs] = 0; - dest[byteOfs+1] = 0; - dest[byteOfs+2] = 0; - dest[byteOfs+3] = 0; - break; - } -} - -void __global__ Convert3To4Component( cudaTextureObject_t tex, float *d_outBuffer, Q3DStudio::INT32 dpitch, Q3DStudio::INT32 width, Q3DStudio::INT32 height ) -{ - float *dest = d_outBuffer; - - int x = threadIdx.x + blockIdx.x * blockDim.x; - int y = threadIdx.y + blockIdx.y * blockDim.y; - if ( x >= width || y >= height ) - return; - int inX = x * 3; - int outX = x * 4; - dest[outX + y * width * 4] = tex2D(tex, inX, y); - dest[outX + y * width * 4 + 1] = tex2D(tex, inX + 1, y); - dest[outX + y * width * 4 + 2] = tex2D(tex, inX + 2, y); - dest[outX + y * width * 4 + 3] = 255 * 255; -} - -void __global__ ConvertData( void* d_InBuffer, NVRenderTextureFormats::Enum inFmt, int inSizeOfFormat, int inNoOfComponent, int inPitch, - void* d_OutBuffer, NVRenderTextureFormats::Enum outFmt, int outSizeOfFormat, int outNoOfComponent, int outPitch, int width, int height ) -{ - - int x = threadIdx.x + blockIdx.x * blockDim.x; - int y = threadIdx.y + blockIdx.y * blockDim.y; - if ( x >= width || y >= height ) - return; - float values[4]; - - decodeToFloat( d_InBuffer, (inPitch * y) + (x * inSizeOfFormat), values, inFmt, inNoOfComponent ); - encodeToPixel( values, d_OutBuffer, (outPitch * y) + (x * outSizeOfFormat), outFmt, outSizeOfFormat ); -} - -void __global__ CreateBsdfMipLevel( cudaTextureObject_t tex, void *d_curBuffer, void *d_prevBuffer, Q3DStudio::INT32 pitch, Q3DStudio::INT32 width, Q3DStudio::INT32 height, - nv::render::NVRenderTextureFormats::Enum inFormat, unsigned int sizeOfFormat ) -{ - float accumVal[4]; - //unsigned int sizeofFormat = getSizeofFormat(inFormat); - //__shared__ float dataBlock[ ]; //(32+4) * (32+4) * 12 - int x = threadIdx.x + blockIdx.x * blockDim.x; - int y = threadIdx.y + blockIdx.y * blockDim.y; - - if ( x >= (width > 2 ? width >> 1 : 1) || y >= (height > 2 ? height >> 1 : 1)) return; - - accumVal[0] = 0; accumVal[1] = 0; accumVal[2] = 0; accumVal[3] = 0; - - for ( int sy = -2; sy <= 2; ++sy ) - { - for ( int sx = -2; sx <= 2; ++sx ) - { - int sampleX = sx + (x << 1); - int sampleY = sy + (y << 1); - //getWrappedCoords(sampleX, sampleY, width, height); - // Cauchy filter (this is simply because it's the easiest to evaluate, and requires no complex - // functions). - float filterPdf = 1.f / ( 1.f + float(sx*sx + sy*sy)*2.f ); - // With FP HDR formats, we're not worried about intensity loss so much as unnecessary energy gain, - // whereas with LDR formats, the fear with a continuous normalization factor is that we'd lose - // intensity and saturation as well. - filterPdf /= sizeOfFormat >= 8 ? 4.71238898f : 4.5403446f; - //filterPdf /= 4.5403446f; // Discrete normalization factor - //filterPdf /= 4.71238898f; // Continuous normalization factor - //float curPix[4]; - sampleX = sampleX*4; - getWrappedCoords(sampleX, sampleY, width*4, height); - accumVal[0] += filterPdf * tex2D(tex, sampleX, sampleY); - accumVal[1] += filterPdf * tex2D(tex, sampleX + 1, sampleY); - accumVal[2] += filterPdf * tex2D(tex, sampleX + 2, sampleY); - accumVal[3] += filterPdf * tex2D(tex, sampleX + 3, sampleY); - } - } - - encodeToPixel(accumVal, d_curBuffer, y * pitch + x * sizeOfFormat, inFormat, sizeOfFormat); -} - -struct SMipTextureData -{ - void* data; - unsigned int dataSize; - unsigned int mipLevel; - unsigned int width; - unsigned int height; - NVRenderTextureFormats::Enum format; -}; - -__host__ void CUDABSDFMipMap::Build( void* inTextureData, int inTextureDataSize, NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, NVRenderTextureFormats::Enum inFormat ) -{ - m_TextureHandle = inTextureHandle; - m_InternalFormat = inFormat; - m_SizeOfInternalFormat = NVRenderTextureFormats::getSizeofFormat( m_InternalFormat ); - m_InternalNoOfComponent = NVRenderTextureFormats::getNumberOfComponent( m_InternalFormat ); - - m_Texture2D.SetTextureData( NVDataRef( (NVU8*)inTextureData, inTextureDataSize ) - , 0 - , m_Width - , m_Height - , inFormat - , m_DestinationFormat ); - - size_t pitch; - float* d_inTextureData; - - cudaMallocPitch(&d_inTextureData, &pitch, m_Width * m_SizeOfInternalFormat, m_Height); CHECK_AND_HANDLE_CUDA_ERROR(); - CHECK_AND_HANDLE_CUDA_ERROR( cudaMemcpy2D( d_inTextureData, pitch, inTextureData, m_Width * m_SizeOfInternalFormat, m_Width * m_SizeOfInternalFormat, m_Height, cudaMemcpyHostToDevice ) ); - { - dim3 blockDim(16, 16, 1); - dim3 gridDim(ceil(m_Width / 16.0f), ceil(m_Height / 16.0f) ,1 ); - - //std::cerr << "if= " << m_InternalFormat << " sizeOut= " << m_SizeOfInternalFormat << " numOfIntComp" << m_InternalNoOfComponent << " pitch= " << pitch << " destFormat= " << m_DestinationFormat << " sizeFormat= " << m_SizeOfFormat << " numOfComp= " << m_NoOfComponent << " Pitch0=" << m_Pitches[0] << std::endl; - //NVLogWarn("cuda", "%i %i %i %i %i %i %i %i\n",(int)m_InternalFormat ,m_SizeOfInternalFormat ,m_InternalNoOfComponent , pitch, (int)m_DestinationFormat, m_SizeOfFormat, m_NoOfComponent ,m_Pitches[0]); - ConvertData<<>>( d_inTextureData, m_InternalFormat, m_SizeOfInternalFormat, m_InternalNoOfComponent, pitch, - md_MipMapsData[0], m_DestinationFormat, m_SizeOfFormat, m_NoOfComponent, m_Pitches[0], m_Width, m_Height ); - } - cudaFree(d_inTextureData); - - int curWidth = m_Width; - int curHeight = m_Height; - - cudaTextureObject_t* tex; - tex = new cudaTextureObject_t[m_MaxMipMapLevel]; - for ( int idx = 1; idx <= m_MaxMipMapLevel; ++idx ) - { - tex[idx-1] = -1; - dim3 blockDim(16, 16, 1); - dim3 gridDim(ceil(curWidth / 32.0f), ceil(curHeight / 32.0f) ,1 ); - - cudaResourceDesc resDesc; - memset(&resDesc, 0, sizeof(resDesc)); - resDesc.res.pitch2D.desc.f = cudaChannelFormatKindFloat; - resDesc.res.pitch2D.desc.x = m_SizeOfFormat / m_NoOfComponent * 8; // bits per channel - resDesc.resType = cudaResourceTypePitch2D; - resDesc.res.pitch2D.devPtr = (char*)(md_MipMapsData[idx-1]); - resDesc.res.pitch2D.height = curHeight; - resDesc.res.pitch2D.width = curWidth * m_NoOfComponent; - resDesc.res.pitch2D.pitchInBytes = m_Pitches[idx-1];// aligned to texturePitchAlignment - - cudaTextureDesc texDesc; - memset(&texDesc, 0, sizeof(texDesc)); - texDesc.addressMode[0] = cudaAddressModeWrap; - texDesc.addressMode[1] = cudaAddressModeWrap; - texDesc.readMode = cudaReadModeElementType; - //texDesc.normalizedCoords = 1; - - - CHECK_AND_HANDLE_CUDA_ERROR( cudaCreateTextureObject( &tex[idx-1], &resDesc, &texDesc, NULL ) ); - CreateBsdfMipLevel<<>>( tex[idx-1], (reinterpret_cast(md_MipMapsData[idx])), (reinterpret_cast(md_MipMapsData[idx-1])), m_Pitches[idx], curWidth, curHeight, m_DestinationFormat, m_SizeOfFormat ); - - curWidth = curWidth > 2 ? curWidth >> 1 : 1; - curHeight = curHeight > 2 ? curHeight >> 1 : 1; - } - - CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceSynchronize(); ) - BindTexture(); - TransferTexture(); - for (int idx = 0; idx < m_MaxMipMapLevel;++idx ) - cudaDestroyTextureObject(tex[idx]); -// CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceReset(); ) - CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceSynchronize(); ) - - //NV_FREE( m_Foundation.getAllocator(), inTextureData ); - -} diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/NvVec.h b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/NvVec.h deleted file mode 100644 index 4e5b09ce..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/NvVec.h +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H -#define INCLUDED_QT3DS_MATH_CPP_VEC_H - -#include "misc.h" - -struct _NvVec3 -{ - union { - struct - { - float x, y, z; - }; - float v[3]; - }; -}; - -struct NvVec3 : public _NvVec3 -{ - NvVec3() { zero(); } - - NvVec3(float x, float y, float z) - { - v[0] = x; - v[1] = y; - v[2] = z; - } - - NvVec3(NvVec3 const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - v[2] = that.v[2]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - v[2] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - NvVec3 &operator+=(NvVec3 const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - v[2] += that.v[2]; - return *this; - } - - NvVec3 &operator-=(NvVec3 const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - v[2] -= that.v[2]; - return *this; - } - - NvVec3 &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - v[2] *= s; - return *this; - } - - NvVec3 &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - v[2] /= s; - return *this; - } -}; - -inline float dot(NvVec3 const &a, NvVec3 const &b) -{ - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} - -inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a) -{ - - return NvVec3(-a.v[0], -a.v[1], -a.v[2]); -} - -inline NvVec3 operator*(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); -} - -inline NvVec3 operator*(float s, NvVec3 const &a) -{ - - return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); -} - -inline NvVec3 operator/(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); -} - -inline float magnitude(NvVec3 const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec3 normalize(NvVec3 const &v) -{ - float l = magnitude(v); - return NvVec3(v[0] / l, v[1] / l, v[2] / l); -} - -inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], - a.v[0] * b.v[1] - a.v[1] * b.v[0]); -} - -inline bool operator==(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); -} - -inline bool operator!=(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); -} - -struct NvVec2f -{ - union { - struct - { - float x, y; - float v[2]; - }; - }; - - NvVec2f() { zero(); } - - NvVec2f(float x, float y) - { - v[0] = x; - v[1] = y; - } - - NvVec2f(NvVec2f const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - NvVec2f &operator+=(NvVec2f const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - return *this; - } - - NvVec2f &operator-=(NvVec2f const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - return *this; - } - - NvVec2f &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - return *this; - } - - NvVec2f &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - return *this; - } -}; - -inline float dot(NvVec2f const &a, NvVec2f const &b) -{ - - return a[0] * b[0] + a[1] * b[1]; -} - -inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a) -{ - - return NvVec2f(-a.v[0], -a.v[1]); -} - -inline NvVec2f operator*(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] * s, a.v[1] * s); -} - -inline NvVec2f operator*(float s, NvVec2f const &a) -{ - - return NvVec2f(s * a.v[0], s * a.v[1]); -} - -inline NvVec2f operator/(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] / s, a.v[1] / s); -} - -inline float magnitude(NvVec2f const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec2f normalize(NvVec2f const &v) -{ - float l = dot(v, v); - return NvVec2f(v[0] / l, v[1] / l); -} - -inline float cross(NvVec2f const &a, NvVec2f const &b) -{ - - return a.v[0] * b.v[1] - b.v[0] * a.v[1]; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/misc.h b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/misc.h deleted file mode 100644 index 983410f3..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/misc.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H -#define INCLUDED_QT3DS_MATH_CPP_MISC_H - -inline bool nvIsPowerOfTwo(unsigned int i) -{ - return (i & (i - 1)) == 0; -} - -inline float nvDegToRadf(float d) -{ - return d * 3.14159265358979323846f / 180.0f; -} - -inline float nvRadToDegf(float r) -{ - return r * 180.0f / 3.14159265358979323846f; -} - -/* - 'mod' differs from '%' in that it behaves correctly when either the - numerator or denominator is negative. -*/ - -inline int nvMod(int n, int d) -{ - int m = n % d; - return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; -} - -inline int nvAbs(int n) -{ - if (n < 0) - return -n; - return n; -} - -inline int nvSign(int n) -{ - if (n > 0) - return 1; - if (n < 0) - return -1; - return 0; -} - -/* - This returns the smallest amplitude value x such that - nvMod(b + x, m) == a -*/ - -inline int nvDifMod(int a, int b, int m) -{ - - int x1 = a - b; - int x2 = (x1 > 0) ? x1 - m : x1 + m; - return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; -} - -inline float nvWrapf(float a, float min, float max) -{ - - assert(max > min); - - float d = max - min; - float s = a - min; - float q = s / d; - float m = q - floorf(q); - return m * d + min; -} - -inline float nvClampf(float a, float min, float max) -{ - return (a < min) ? min : ((a > max) ? max : a); -} - -inline int nvClampi(int i, int min, int max) -{ - return (i < min) ? min : ((i > max) ? max : i); -} - -inline float nvGaussian(float x, float s) -{ - float c = s * sqrtf(2.0f * 3.14159265358979323846f); - return expf(-(x * x) / (2.0f * s * s)) / c; -} - -inline float nvLerpf(float a, float b, float t) -{ - return a * (1.0f - t) + b * t; -} - -inline float nvEasef(float t) -{ - - float t_2 = t * t; - float t_3 = t_2 * t; - return 3.0f * t_2 - 2.0f * t_3; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.cpp b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.cpp deleted file mode 100644 index b83cb39e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_math.h" - -static const double a = 16807.0; -static const double m = 2147483647.0; - -static double nextSeed(double seed) -{ - double t = a * seed; - return t - m * (double)((int)(t / m)); -} - -GLfloat NvRandf() -{ - static double seed = 1.0; - seed = nextSeed(seed); - return (GLfloat)(seed * (1 / m)); -} - -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) -{ - // kdGetTimeUST is never supposed to decrease (i.e. that - // means it can't wrap, either. IIRC, it will wrap in - // 593 years). So we ignore that option... - - // Used for frame-to-frame diffs, this will fit in 32b - // as long as the times are < ~4.3s apart - long long int diffTime = newTime - oldTime; - - // Need to find a better way to do this. - // However, I believe we will be uSec precise (not run - // out of mantissa bits for uSecs) as long as the diff - // is < ~16s (1e-6 * (2^24)) - return ((GLfloat)diffTime) / 1.0e9f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.h b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.h deleted file mode 100644 index cf2d8b30..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_math.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_MATH_H -#define _QT3DS_MATH_H - -#include - -GLfloat NvRandf(); - -/* These are the recommended "safer" ways to use GLfloat for time */ - -/* Returns the seconds between the two given times */ -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); - -#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.cpp b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.cpp deleted file mode 100644 index e208ac31..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_matrix.h" - -int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) -{ - return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); -} - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; -} - -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; -} - -GLfloat NvVecLengthf(const GLfloat v[3]) -{ - return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); -} - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) -{ - GLfloat const l = NvVecLengthf(v); - r[0] = v[0] / l; - r[1] = v[1] / l; - r[2] = v[2] / l; -} - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; -} - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - r[2] = a[2] - b[2]; -} - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - GLfloat t[3]; - - t[0] = a[1] * b[2] - a[2] * b[1]; - t[1] = a[2] * b[0] - a[0] * b[2]; - t[2] = a[0] * b[1] - a[1] * b[0]; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; -} - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); - - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; -} - -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; - r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; -} - -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; -} - -static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; - r[3][3] = 1.0f; -} - -static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; - r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; - r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; - r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; - r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; -} - -void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) - && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { - if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) - && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { - NvMultMat3x3f(r, a, b); - } else { - NvMultMat4x3f(r, a, b); - } - } else { - NvMultMat4x4f(r, a, b); - } - - NvCopyMatf(result, r); -} - -static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - /* x */ - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - /* y */ - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - /* z */ - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = 1.0f; -} - -static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] - + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] - + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] - + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] - + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] - + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] - + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] - + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] - + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] - + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] - + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] - + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] - + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] - + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) - / d; - - r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] - + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) - / d; - - r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] - + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] - + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) - / d; - - r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] - + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) - / d; - - r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] - + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) - / d; - - r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] - + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] - + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) - / d; - - r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] - + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) - / d; - - r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] - + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] - + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) - / d; - - r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] - + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] - + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) - / d; - - r[2][1] = - (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] - + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) - / d; - - r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] - + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] - + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) - / d; - - r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] - + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) - / d; - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] - + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) - / d; -} - -void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { - if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { - NvInvMat3x3f(r, m); - } else { - NvInvMat4x3f(r, m); - } - } else { - NvInvMat4x4f(r, m); - } - - NvCopyMatf(result, r); -} - -void NvBuildIdentityMatf(GLfloat r[4][4]) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = x; - r[3][1] = y; - r[3][2] = z; - r[3][3] = 1.0f; -} - -void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, - GLfloat z) -{ - GLfloat r[4][4]; /*temporary storage for result */ - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; - r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; - r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; - r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = x; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = y; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = z; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * x; - r[0][1] = m[0][1] * x; - r[0][2] = m[0][2] * x; - r[0][3] = m[0][3] * x; - - r[1][0] = m[1][0] * y; - r[1][1] = m[1][1] * y; - r[1][2] = m[1][2] * y; - r[1][3] = m[1][3] * y; - - r[2][0] = m[2][0] * z; - r[2][1] = m[2][1] * z; - r[2][2] = m[2][2] * z; - r[2][3] = m[2][3] * z; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) -{ - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = c; - r[1][2] = s; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = -s; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = 0.0f; - r[0][2] = -s; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = s; - r[2][1] = 0.0f; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = s; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = -s; - r[1][1] = c; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0] * c + m[2][0] * s; - r[1][1] = m[1][1] * c + m[2][1] * s; - r[1][2] = m[1][2] * c + m[2][2] * s; - r[1][3] = m[1][3] * c + m[2][3] * s; - - r[2][0] = m[1][0] * -s + m[2][0] * c; - r[2][1] = m[1][1] * -s + m[2][1] * c; - r[2][2] = m[1][2] * -s + m[2][2] * c; - r[2][3] = m[1][3] * -s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[2][0] * -s; - r[0][1] = m[0][1] * c + m[2][1] * -s; - r[0][2] = m[0][2] * c + m[2][2] * -s; - r[0][3] = m[0][3] * c + m[2][3] * -s; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[0][0] * s + m[2][0] * c; - r[2][1] = m[0][1] * s + m[2][1] * c; - r[2][2] = m[0][2] * s + m[2][2] * c; - r[2][3] = m[0][3] * s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[1][0] * s; - r[0][1] = m[0][1] * c + m[1][1] * s; - r[0][2] = m[0][2] * c + m[1][2] * s; - r[0][3] = m[0][3] * c + m[1][3] * s; - - r[1][0] = m[0][0] * -s + m[1][0] * c; - r[1][1] = m[0][1] * -s + m[1][1] * c; - r[1][2] = m[0][2] * -s + m[1][2] * c; - r[1][3] = m[0][3] * -s + m[1][3] * c; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) -{ - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - /* build a matrix from the quat */ - - result[0][0] = 1.0f - 2.0f * (j * j + k * k); - result[0][1] = 2.0f * (i * j + r * k); - result[0][2] = 2.0f * (i * k - r * j); - result[0][3] = 0.0f; - - result[1][0] = 2.0f * (i * j - r * k); - result[1][1] = 1.0f - 2.0f * (i * i + k * k); - result[1][2] = 2.0f * (j * k + r * i); - result[1][3] = 0.0f; - - result[2][0] = 2.0f * (i * k + r * j); - result[2][1] = 2.0f * (j * k - r * i); - result[2][2] = 1.0f - 2.0f * (i * i + j * j); - result[2][3] = 0.0f; - - result[3][0] = 0.0f; - result[3][1] = 0.0f; - result[3][2] = 0.0f; - result[3][3] = 1.0f; -} - -void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians) -{ - GLfloat r[4][4]; - - { - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat const dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - { - /* build a matrix from the quat */ - - GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); - GLfloat const a01 = 2.0f * (i * j + r * k); - GLfloat const a02 = 2.0f * (i * k - r * j); - - GLfloat const a10 = 2.0f * (i * j - r * k); - GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); - GLfloat const a12 = 2.0f * (j * k + r * i); - - GLfloat const a20 = 2.0f * (i * k + r * j); - GLfloat const a21 = 2.0f * (j * k - r * i); - GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); - - result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; - result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; - result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; - result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; - - result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; - result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; - result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; - result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; - - result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; - result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; - result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; - result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; - - result[3][0] = m[3][0]; - result[3][1] = m[3][1]; - result[3][2] = m[3][2]; - result[3][3] = m[3][3]; - } - } - - NvCopyMatf(result, r); -} - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) -{ - NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees) -{ - NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]) -{ - GLfloat ev[3]; - GLfloat z[3]; - GLfloat x_tmp[3]; - GLfloat x[3]; - GLfloat y[3]; - - NvSubVecf(ev, eye, obj); - - NvNormalizeVecf(z, ev); - - NvCrossProductf(x_tmp, up, z); - - NvNormalizeVecf(x, x_tmp); - - NvCrossProductf(y, z, x); - - r[0][0] = x[0]; - r[0][1] = y[0]; - r[0][2] = z[0]; - r[0][3] = 0.0f; - - r[1][0] = x[1]; - r[1][1] = y[1]; - r[1][2] = z[1]; - r[1][3] = 0.0f; - - r[2][0] = x[2]; - r[2][1] = y[2]; - r[2][2] = z[2]; - r[2][3] = 0.0f; - - r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; - r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; - r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; - r[3][3] = 1.0f; -} - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const m00 = znear * 2.0f / (right - left); - GLfloat const m11 = znear * 2.0f / (top - bottom); - GLfloat const m22 = -(zfar + znear) / (zfar - znear); - - GLfloat const m20 = (right + left) / (right - left); - GLfloat const m21 = (top + bottom) / (top - bottom); - - GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); - GLfloat const m23 = -1.0f; - - r[0][0] = m00; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = m11; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = m20; - r[2][1] = m21; - r[2][2] = m22; - r[2][3] = m23; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = m32; - r[3][3] = 0.0f; -} - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - GLfloat const sz = -2.0f / (zfar - znear); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - GLfloat const tz = -(zfar + znear) / (zfar - znear); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = sz; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = tz; - r[3][3] = 1.0f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.h b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.h deleted file mode 100644 index 2a8e186e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_matrix.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_MATRIX_H -#define INCLUDED_MATRIX_H - -#include -#include -#include - -#define KD_FLT_EPSILON 1.19209290E-07F -#define KD_DEG_TO_RAD_F 0.0174532924F -#define KD_RAD_TO_DEG_F 57.2957802F - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); - -/* vector utilities */ - -GLfloat NvVecLengthf(const GLfloat v[3]); - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); - -/* matrix utilities */ - -void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); - -void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); - -/* matrix building utilities */ - -void NvBuildIdentityMatf(GLfloat r[4][4]); - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); - -void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]); - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -/* matrix concatenation utilities */ - -void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); -void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees); - -void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); - -void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.cpp b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.cpp deleted file mode 100644 index 6dc6d1a7..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_quat.h" -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) -{ - memcpy(r, q, 4 * sizeof(GLfloat)); -} - -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) -{ - // Assumes that the quaternion is normalized! - GLfloat x2 = q[0] * 2.0f; - GLfloat y2 = q[1] * 2.0f; - GLfloat z2 = q[2] * 2.0f; - GLfloat xSq2 = x2 * q[0]; - GLfloat ySq2 = y2 * q[1]; - GLfloat zSq2 = z2 * q[2]; - GLfloat xy2 = x2 * q[1]; - GLfloat xz2 = x2 * q[2]; - GLfloat xw2 = x2 * q[3]; - GLfloat yz2 = y2 * q[2]; - GLfloat yw2 = y2 * q[3]; - GLfloat zw2 = z2 * q[3]; - - /* Matrix is - * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | - * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | - * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | - */ - r[0][0] = 1.0f - ySq2 - zSq2; - r[0][1] = xy2 - zw2; - r[0][2] = xz2 + yw2; - - r[1][0] = xy2 + zw2; - r[1][1] = 1.0f - xSq2 - zSq2; - r[1][2] = yz2 - xw2; - - r[2][0] = xz2 - yw2; - r[2][1] = yz2 + xw2; - r[2][2] = 1.0f - xSq2 - ySq2; -} - -void NvQuatIdentity(GLfloat r[4]) -{ - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = 1.0f; -} - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = axis[0] * sina; - r[1] = axis[1] * sina; - r[2] = axis[2] * sina; - r[3] = cosa; -} - -void NvQuatX(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = sina; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatY(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = sina; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatZ(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = sina; - r[3] = cosa; -} - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatY(h, heading); - NvQuatX(p, pitch); - NvQuatZ(ro, roll); - - NvQuatMult(r, h, p); - NvQuatMult(r, ro, r); -} - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatZ(ro, roll); - NvQuatX(p, pitch); - NvQuatY(h, heading); - - NvQuatMult(r, p, h); - NvQuatMult(r, r, ro); -} - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) -{ - return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; -} - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) -{ - const GLfloat q1x = q1[0]; - const GLfloat q1y = q1[1]; - const GLfloat q1z = q1[2]; - const GLfloat q1w = q1[3]; - const GLfloat q2x = q2[0]; - const GLfloat q2y = q2[1]; - const GLfloat q2z = q2[2]; - const GLfloat q2w = q2[3]; - - r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; - r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; - r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; - r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; -} - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) -{ - GLfloat omt = 1.0f - t; - - if (NvQuatDot(q1, q2) < 0.0f) { - r[0] = -q1[0] * omt + q2[0] * t; - r[1] = -q1[1] * omt + q2[1] * t; - r[2] = -q1[2] * omt + q2[2] * t; - r[3] = -q1[3] * omt + q2[3] * t; - } else { - r[0] = q1[0] * omt + q2[0] * t; - r[1] = q1[1] * omt + q2[1] * t; - r[2] = q1[2] * omt + q2[2] * t; - r[3] = q1[3] * omt + q2[3] * t; - } - - NvQuatNormalize(r, r); -} - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) -{ - GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); - - r[0] = invLength * q[0]; - r[1] = invLength * q[1]; - r[2] = invLength * q[2]; - r[3] = invLength * q[3]; -} diff --git a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.h b/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.h deleted file mode 100644 index 688c30a7..00000000 --- a/src/Runtime/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_math/nv_quat.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QUAT_H -#define INCLUDED_QUAT_H - -#include -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); - -void NvQuatIdentity(GLfloat r[4]); - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); - -void NvQuatX(GLfloat r[4], GLfloat radians); - -void NvQuatY(GLfloat r[4], GLfloat radians); - -void NvQuatZ(GLfloat r[4], GLfloat radians); - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_color.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_color.h deleted file mode 100644 index b9347529..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_color.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_COLOR_H -#define _QT3DS_COLOR_H - -/** @file nv_color.h - Simple abstraction for RGBA colors as parameters to various libraries/functions. -*/ - -/** Base type for a single color channel (8-bit unsigned). */ -typedef unsigned char NvPCColor8; - -//#define NV_COLOR_BREAKOLD -#ifdef NV_COLOR_BREAKOLD // uses a struct to break backwards-compat and accidental uses - -typedef struct -{ - NvPCColor8 r; - NvPCColor8 g; - NvPCColor8 b; - NvPCColor8 a; -} NvPackedColor; - -static const NvPackedColor gnvpcwhite = { 255, 255, 255, 255 }; -static const NvPackedColor gnvpcblack = { 0, 0, 0, 255 }; - -#define NV_PACKED_COLOR(r, g, b, a) \ - { \ - (NvPCColor8)(r), (NvPCColor8)(g), (NvPCColor8)(b), (NvPCColor8)(a) \ - } - -#define NV_PC_PREDEF_WHITE gnvpcwhite -#define NV_PC_PREDEF_BLACK gnvpcblack - -#define NV_PC_RED(c) (c.r) -#define NV_PC_GREEN(c) (c.g) -#define NV_PC_BLUE(c) (c.b) -#define NV_PC_ALPHA(c) (c.a) - -#define NV_PC_PACK_UINT(c) (*(unsigned int *)(&(c))) - -#define NV_PC_EQUAL(x, y) ((x).r == (y).r && (x).g == (y).g && (x).b == (y).b && (x).a == (y).a) - -#else /* code that doesn't break old pass-as-uint stuff */ - -/** Main type declaration for a packed 4-color construct. */ -typedef unsigned int NvPackedColor; - -/** A macro to build a packed color, passing in RGBA as four 8-bit integer values. */ -#define NV_PACKED_COLOR(r, g, b, a) \ - ((NvPackedColor)(((((int)(a)) & 0xFF) << 24) | ((((int)(b)) & 0xFF) << 16) \ - | ((((int)(g)) & 0xFF) << 8) | ((((int)(r)) & 0xFF)))) - -/** A predefined constant for WHITE. */ -#define NV_PC_PREDEF_WHITE NV_PACKED_COLOR(0xFF, 0xFF, 0xFF, 0xFF) -/** A predefined constant for BLACK. */ -#define NV_PC_PREDEF_BLACK NV_PACKED_COLOR(0x00, 0x00, 0x00, 0xFF) - -/** A macro for 'extracting' the red value from an NvPackedColor. */ -#define NV_PC_RED(c) ((c >> 0) & 0xff) -/** A macro for 'extracting' the green value from an NvPackedColor. */ -#define NV_PC_GREEN(c) ((c >> 8) & 0xff) -/** A macro for 'extracting' the blue value from an NvPackedColor. */ -#define NV_PC_BLUE(c) ((c >> 16) & 0xff) -/** A macro for 'extracting' the alpha value from an NvPackedColor. */ -#define NV_PC_ALPHA(c) ((c >> 24) & 0xff) - -/** A macro requesting the packed color repacked into a 32-bit unsigned int. - This is a no-op for the color-as-uint approach. -*/ -#define NV_PC_PACK_UINT(c) (c) -/** A macro for testing the equality of two NvPackedColors. */ -#define NV_PC_EQUAL(x, y) (x == y) -#endif - -/** A macro for mapping a single packed color channel into its floating point [0,1] rep. */ -#define NV_PC_TO_FLOAT(c) (c / 255.0f) - -#endif /*_QT3DS_COLOR_H*/ diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_debug.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_debug.h deleted file mode 100644 index 2559dd6f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_debug.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_DEBUG_H -#define __INCLUDED_QT3DS_DEBUG_H - -#define CT_ASSERT(tag, cond) enum { COMPILE_TIME_ASSERT__##tag = 1 / (cond) } - -#define dimof(x) (sizeof(x) / sizeof(x[0])) -#include - -#define DBG_DETAILED 0 - -#if 0 - - // the detailed prefix can be customised by setting DBG_DETAILED_PREFIX. See - // below as a reference. - // NOTE: fmt is the desired format string and must be in the prefix. - //#ifndef DBG_DETAILED_PREFIX - // #define DBG_DETAILED_PREFIX "%s, %s, line %d: " fmt, __FILE__, __FUNCTION__, __LINE__, - //#endif - //#define DEBUG_D_(fmt, args...) - //#define DEBUG_D(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, (DBG_DETAILED_PREFIX) ## args) - -#else - -#ifdef STRINGIFY -#pragma push_macro("STRINGIFY") -#undef STRINGIFY -#define STRINGIFYPUSHED_____ -#endif -#define STRINGIFY(x) #x - -// debug macro, includes file name function name and line number -#define TO(x) typeof(x) -#define DEBUG_D_(file, line, fmt, args...) \ - __android_log_print(ANDROID_LOG_DEBUG, MODULE, file ", %s, line(" STRINGIFY(line) "): " fmt, \ - __FUNCTION__, ##args) -#define DEBUG_D(fmt, args...) DEBUG_D_(__FILE__, __LINE__, fmt, ##args) - -#ifdef STRINGIFYPUSHED_____ -#undef STRINGIFYPUSHED_____ -#pragma pop_macro("STRINGIFY") -#endif - -#endif - -// basic debug macro -#define DEBUG_(fmt, args...) (__android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args)) - -// Debug macro that can be switched to spew a file name, -// function and line number using DEBUG_DETAILED -#if DBG_DETAILED == 1 -#define DEBUG(fmt, args...) DEBUG_D(fmt, ##args) -#else -#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args) -#endif - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_global.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_global.h deleted file mode 100644 index 9d23d45f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_global.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_GLOBAL_H -#define __INCLUDED_QT3DS_GLOBAL_H - -#include "nv_types.h" - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/NvVec.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/NvVec.h deleted file mode 100644 index 4e5b09ce..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/NvVec.h +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H -#define INCLUDED_QT3DS_MATH_CPP_VEC_H - -#include "misc.h" - -struct _NvVec3 -{ - union { - struct - { - float x, y, z; - }; - float v[3]; - }; -}; - -struct NvVec3 : public _NvVec3 -{ - NvVec3() { zero(); } - - NvVec3(float x, float y, float z) - { - v[0] = x; - v[1] = y; - v[2] = z; - } - - NvVec3(NvVec3 const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - v[2] = that.v[2]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - v[2] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - NvVec3 &operator+=(NvVec3 const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - v[2] += that.v[2]; - return *this; - } - - NvVec3 &operator-=(NvVec3 const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - v[2] -= that.v[2]; - return *this; - } - - NvVec3 &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - v[2] *= s; - return *this; - } - - NvVec3 &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - v[2] /= s; - return *this; - } -}; - -inline float dot(NvVec3 const &a, NvVec3 const &b) -{ - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} - -inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a) -{ - - return NvVec3(-a.v[0], -a.v[1], -a.v[2]); -} - -inline NvVec3 operator*(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); -} - -inline NvVec3 operator*(float s, NvVec3 const &a) -{ - - return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); -} - -inline NvVec3 operator/(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); -} - -inline float magnitude(NvVec3 const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec3 normalize(NvVec3 const &v) -{ - float l = magnitude(v); - return NvVec3(v[0] / l, v[1] / l, v[2] / l); -} - -inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], - a.v[0] * b.v[1] - a.v[1] * b.v[0]); -} - -inline bool operator==(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); -} - -inline bool operator!=(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); -} - -struct NvVec2f -{ - union { - struct - { - float x, y; - float v[2]; - }; - }; - - NvVec2f() { zero(); } - - NvVec2f(float x, float y) - { - v[0] = x; - v[1] = y; - } - - NvVec2f(NvVec2f const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - NvVec2f &operator+=(NvVec2f const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - return *this; - } - - NvVec2f &operator-=(NvVec2f const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - return *this; - } - - NvVec2f &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - return *this; - } - - NvVec2f &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - return *this; - } -}; - -inline float dot(NvVec2f const &a, NvVec2f const &b) -{ - - return a[0] * b[0] + a[1] * b[1]; -} - -inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a) -{ - - return NvVec2f(-a.v[0], -a.v[1]); -} - -inline NvVec2f operator*(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] * s, a.v[1] * s); -} - -inline NvVec2f operator*(float s, NvVec2f const &a) -{ - - return NvVec2f(s * a.v[0], s * a.v[1]); -} - -inline NvVec2f operator/(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] / s, a.v[1] / s); -} - -inline float magnitude(NvVec2f const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec2f normalize(NvVec2f const &v) -{ - float l = dot(v, v); - return NvVec2f(v[0] / l, v[1] / l); -} - -inline float cross(NvVec2f const &a, NvVec2f const &b) -{ - - return a.v[0] * b.v[1] - b.v[0] * a.v[1]; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/misc.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/misc.h deleted file mode 100644 index 983410f3..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/misc.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H -#define INCLUDED_QT3DS_MATH_CPP_MISC_H - -inline bool nvIsPowerOfTwo(unsigned int i) -{ - return (i & (i - 1)) == 0; -} - -inline float nvDegToRadf(float d) -{ - return d * 3.14159265358979323846f / 180.0f; -} - -inline float nvRadToDegf(float r) -{ - return r * 180.0f / 3.14159265358979323846f; -} - -/* - 'mod' differs from '%' in that it behaves correctly when either the - numerator or denominator is negative. -*/ - -inline int nvMod(int n, int d) -{ - int m = n % d; - return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; -} - -inline int nvAbs(int n) -{ - if (n < 0) - return -n; - return n; -} - -inline int nvSign(int n) -{ - if (n > 0) - return 1; - if (n < 0) - return -1; - return 0; -} - -/* - This returns the smallest amplitude value x such that - nvMod(b + x, m) == a -*/ - -inline int nvDifMod(int a, int b, int m) -{ - - int x1 = a - b; - int x2 = (x1 > 0) ? x1 - m : x1 + m; - return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; -} - -inline float nvWrapf(float a, float min, float max) -{ - - assert(max > min); - - float d = max - min; - float s = a - min; - float q = s / d; - float m = q - floorf(q); - return m * d + min; -} - -inline float nvClampf(float a, float min, float max) -{ - return (a < min) ? min : ((a > max) ? max : a); -} - -inline int nvClampi(int i, int min, int max) -{ - return (i < min) ? min : ((i > max) ? max : i); -} - -inline float nvGaussian(float x, float s) -{ - float c = s * sqrtf(2.0f * 3.14159265358979323846f); - return expf(-(x * x) / (2.0f * s * s)) / c; -} - -inline float nvLerpf(float a, float b, float t) -{ - return a * (1.0f - t) + b * t; -} - -inline float nvEasef(float t) -{ - - float t_2 = t * t; - float t_3 = t_2 * t; - return 3.0f * t_2 - 2.0f * t_3; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.cpp b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.cpp deleted file mode 100644 index b83cb39e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_math.h" - -static const double a = 16807.0; -static const double m = 2147483647.0; - -static double nextSeed(double seed) -{ - double t = a * seed; - return t - m * (double)((int)(t / m)); -} - -GLfloat NvRandf() -{ - static double seed = 1.0; - seed = nextSeed(seed); - return (GLfloat)(seed * (1 / m)); -} - -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) -{ - // kdGetTimeUST is never supposed to decrease (i.e. that - // means it can't wrap, either. IIRC, it will wrap in - // 593 years). So we ignore that option... - - // Used for frame-to-frame diffs, this will fit in 32b - // as long as the times are < ~4.3s apart - long long int diffTime = newTime - oldTime; - - // Need to find a better way to do this. - // However, I believe we will be uSec precise (not run - // out of mantissa bits for uSecs) as long as the diff - // is < ~16s (1e-6 * (2^24)) - return ((GLfloat)diffTime) / 1.0e9f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.h deleted file mode 100644 index 2ef7bba0..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_math.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_MATH_H -#define _QT3DS_MATH_H - -#include - -GLfloat NvRandf(); - -/* These are the recommended "safer" ways to use GLfloat for time */ - -/* Returns the seconds between the two given times */ -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); - -#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.cpp b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.cpp deleted file mode 100644 index e208ac31..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_matrix.h" - -int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) -{ - return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); -} - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; -} - -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; -} - -GLfloat NvVecLengthf(const GLfloat v[3]) -{ - return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); -} - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) -{ - GLfloat const l = NvVecLengthf(v); - r[0] = v[0] / l; - r[1] = v[1] / l; - r[2] = v[2] / l; -} - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; -} - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - r[2] = a[2] - b[2]; -} - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - GLfloat t[3]; - - t[0] = a[1] * b[2] - a[2] * b[1]; - t[1] = a[2] * b[0] - a[0] * b[2]; - t[2] = a[0] * b[1] - a[1] * b[0]; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; -} - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); - - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; -} - -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; - r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; -} - -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; -} - -static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; - r[3][3] = 1.0f; -} - -static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; - r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; - r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; - r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; - r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; -} - -void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) - && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { - if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) - && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { - NvMultMat3x3f(r, a, b); - } else { - NvMultMat4x3f(r, a, b); - } - } else { - NvMultMat4x4f(r, a, b); - } - - NvCopyMatf(result, r); -} - -static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - /* x */ - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - /* y */ - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - /* z */ - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = 1.0f; -} - -static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] - + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] - + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] - + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] - + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] - + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] - + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] - + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] - + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] - + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] - + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] - + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] - + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] - + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) - / d; - - r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] - + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) - / d; - - r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] - + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] - + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) - / d; - - r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] - + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) - / d; - - r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] - + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) - / d; - - r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] - + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] - + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) - / d; - - r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] - + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) - / d; - - r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] - + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] - + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) - / d; - - r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] - + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] - + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) - / d; - - r[2][1] = - (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] - + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) - / d; - - r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] - + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] - + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) - / d; - - r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] - + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) - / d; - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] - + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) - / d; -} - -void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { - if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { - NvInvMat3x3f(r, m); - } else { - NvInvMat4x3f(r, m); - } - } else { - NvInvMat4x4f(r, m); - } - - NvCopyMatf(result, r); -} - -void NvBuildIdentityMatf(GLfloat r[4][4]) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = x; - r[3][1] = y; - r[3][2] = z; - r[3][3] = 1.0f; -} - -void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, - GLfloat z) -{ - GLfloat r[4][4]; /*temporary storage for result */ - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; - r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; - r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; - r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = x; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = y; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = z; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * x; - r[0][1] = m[0][1] * x; - r[0][2] = m[0][2] * x; - r[0][3] = m[0][3] * x; - - r[1][0] = m[1][0] * y; - r[1][1] = m[1][1] * y; - r[1][2] = m[1][2] * y; - r[1][3] = m[1][3] * y; - - r[2][0] = m[2][0] * z; - r[2][1] = m[2][1] * z; - r[2][2] = m[2][2] * z; - r[2][3] = m[2][3] * z; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) -{ - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = c; - r[1][2] = s; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = -s; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = 0.0f; - r[0][2] = -s; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = s; - r[2][1] = 0.0f; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = s; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = -s; - r[1][1] = c; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0] * c + m[2][0] * s; - r[1][1] = m[1][1] * c + m[2][1] * s; - r[1][2] = m[1][2] * c + m[2][2] * s; - r[1][3] = m[1][3] * c + m[2][3] * s; - - r[2][0] = m[1][0] * -s + m[2][0] * c; - r[2][1] = m[1][1] * -s + m[2][1] * c; - r[2][2] = m[1][2] * -s + m[2][2] * c; - r[2][3] = m[1][3] * -s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[2][0] * -s; - r[0][1] = m[0][1] * c + m[2][1] * -s; - r[0][2] = m[0][2] * c + m[2][2] * -s; - r[0][3] = m[0][3] * c + m[2][3] * -s; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[0][0] * s + m[2][0] * c; - r[2][1] = m[0][1] * s + m[2][1] * c; - r[2][2] = m[0][2] * s + m[2][2] * c; - r[2][3] = m[0][3] * s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[1][0] * s; - r[0][1] = m[0][1] * c + m[1][1] * s; - r[0][2] = m[0][2] * c + m[1][2] * s; - r[0][3] = m[0][3] * c + m[1][3] * s; - - r[1][0] = m[0][0] * -s + m[1][0] * c; - r[1][1] = m[0][1] * -s + m[1][1] * c; - r[1][2] = m[0][2] * -s + m[1][2] * c; - r[1][3] = m[0][3] * -s + m[1][3] * c; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) -{ - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - /* build a matrix from the quat */ - - result[0][0] = 1.0f - 2.0f * (j * j + k * k); - result[0][1] = 2.0f * (i * j + r * k); - result[0][2] = 2.0f * (i * k - r * j); - result[0][3] = 0.0f; - - result[1][0] = 2.0f * (i * j - r * k); - result[1][1] = 1.0f - 2.0f * (i * i + k * k); - result[1][2] = 2.0f * (j * k + r * i); - result[1][3] = 0.0f; - - result[2][0] = 2.0f * (i * k + r * j); - result[2][1] = 2.0f * (j * k - r * i); - result[2][2] = 1.0f - 2.0f * (i * i + j * j); - result[2][3] = 0.0f; - - result[3][0] = 0.0f; - result[3][1] = 0.0f; - result[3][2] = 0.0f; - result[3][3] = 1.0f; -} - -void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians) -{ - GLfloat r[4][4]; - - { - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat const dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - { - /* build a matrix from the quat */ - - GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); - GLfloat const a01 = 2.0f * (i * j + r * k); - GLfloat const a02 = 2.0f * (i * k - r * j); - - GLfloat const a10 = 2.0f * (i * j - r * k); - GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); - GLfloat const a12 = 2.0f * (j * k + r * i); - - GLfloat const a20 = 2.0f * (i * k + r * j); - GLfloat const a21 = 2.0f * (j * k - r * i); - GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); - - result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; - result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; - result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; - result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; - - result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; - result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; - result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; - result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; - - result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; - result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; - result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; - result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; - - result[3][0] = m[3][0]; - result[3][1] = m[3][1]; - result[3][2] = m[3][2]; - result[3][3] = m[3][3]; - } - } - - NvCopyMatf(result, r); -} - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) -{ - NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees) -{ - NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]) -{ - GLfloat ev[3]; - GLfloat z[3]; - GLfloat x_tmp[3]; - GLfloat x[3]; - GLfloat y[3]; - - NvSubVecf(ev, eye, obj); - - NvNormalizeVecf(z, ev); - - NvCrossProductf(x_tmp, up, z); - - NvNormalizeVecf(x, x_tmp); - - NvCrossProductf(y, z, x); - - r[0][0] = x[0]; - r[0][1] = y[0]; - r[0][2] = z[0]; - r[0][3] = 0.0f; - - r[1][0] = x[1]; - r[1][1] = y[1]; - r[1][2] = z[1]; - r[1][3] = 0.0f; - - r[2][0] = x[2]; - r[2][1] = y[2]; - r[2][2] = z[2]; - r[2][3] = 0.0f; - - r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; - r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; - r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; - r[3][3] = 1.0f; -} - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const m00 = znear * 2.0f / (right - left); - GLfloat const m11 = znear * 2.0f / (top - bottom); - GLfloat const m22 = -(zfar + znear) / (zfar - znear); - - GLfloat const m20 = (right + left) / (right - left); - GLfloat const m21 = (top + bottom) / (top - bottom); - - GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); - GLfloat const m23 = -1.0f; - - r[0][0] = m00; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = m11; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = m20; - r[2][1] = m21; - r[2][2] = m22; - r[2][3] = m23; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = m32; - r[3][3] = 0.0f; -} - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - GLfloat const sz = -2.0f / (zfar - znear); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - GLfloat const tz = -(zfar + znear) / (zfar - znear); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = sz; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = tz; - r[3][3] = 1.0f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.h deleted file mode 100644 index 5f567f06..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_matrix.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_MATRIX_H -#define INCLUDED_MATRIX_H - -#include - -#include -#include - -#define KD_FLT_EPSILON 1.19209290E-07F -#define KD_DEG_TO_RAD_F 0.0174532924F -#define KD_RAD_TO_DEG_F 57.2957802F - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); - -/* vector utilities */ - -GLfloat NvVecLengthf(const GLfloat v[3]); - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); - -/* matrix utilities */ - -void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); - -void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); - -/* matrix building utilities */ - -void NvBuildIdentityMatf(GLfloat r[4][4]); - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); - -void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]); - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -/* matrix concatenation utilities */ - -void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); -void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees); - -void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); - -void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.cpp b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.cpp deleted file mode 100644 index e66420c6..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_quat.h" -#include -#ifdef _INTEGRITYPLATFORM -#include -#else -#include -#endif - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) -{ - memcpy(r, q, 4 * sizeof(GLfloat)); -} - -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) -{ - // Assumes that the quaternion is normalized! - GLfloat x2 = q[0] * 2.0f; - GLfloat y2 = q[1] * 2.0f; - GLfloat z2 = q[2] * 2.0f; - GLfloat xSq2 = x2 * q[0]; - GLfloat ySq2 = y2 * q[1]; - GLfloat zSq2 = z2 * q[2]; - GLfloat xy2 = x2 * q[1]; - GLfloat xz2 = x2 * q[2]; - GLfloat xw2 = x2 * q[3]; - GLfloat yz2 = y2 * q[2]; - GLfloat yw2 = y2 * q[3]; - GLfloat zw2 = z2 * q[3]; - - /* Matrix is - * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | - * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | - * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | - */ - r[0][0] = 1.0f - ySq2 - zSq2; - r[0][1] = xy2 - zw2; - r[0][2] = xz2 + yw2; - - r[1][0] = xy2 + zw2; - r[1][1] = 1.0f - xSq2 - zSq2; - r[1][2] = yz2 - xw2; - - r[2][0] = xz2 - yw2; - r[2][1] = yz2 + xw2; - r[2][2] = 1.0f - xSq2 - ySq2; -} - -void NvQuatIdentity(GLfloat r[4]) -{ - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = 1.0f; -} - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = axis[0] * sina; - r[1] = axis[1] * sina; - r[2] = axis[2] * sina; - r[3] = cosa; -} - -void NvQuatX(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = sina; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatY(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = sina; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatZ(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = sina; - r[3] = cosa; -} - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatY(h, heading); - NvQuatX(p, pitch); - NvQuatZ(ro, roll); - - NvQuatMult(r, h, p); - NvQuatMult(r, ro, r); -} - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatZ(ro, roll); - NvQuatX(p, pitch); - NvQuatY(h, heading); - - NvQuatMult(r, p, h); - NvQuatMult(r, r, ro); -} - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) -{ - return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; -} - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) -{ - const GLfloat q1x = q1[0]; - const GLfloat q1y = q1[1]; - const GLfloat q1z = q1[2]; - const GLfloat q1w = q1[3]; - const GLfloat q2x = q2[0]; - const GLfloat q2y = q2[1]; - const GLfloat q2z = q2[2]; - const GLfloat q2w = q2[3]; - - r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; - r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; - r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; - r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; -} - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) -{ - GLfloat omt = 1.0f - t; - - if (NvQuatDot(q1, q2) < 0.0f) { - r[0] = -q1[0] * omt + q2[0] * t; - r[1] = -q1[1] * omt + q2[1] * t; - r[2] = -q1[2] * omt + q2[2] * t; - r[3] = -q1[3] * omt + q2[3] * t; - } else { - r[0] = q1[0] * omt + q2[0] * t; - r[1] = q1[1] * omt + q2[1] * t; - r[2] = q1[2] * omt + q2[2] * t; - r[3] = q1[3] * omt + q2[3] * t; - } - - NvQuatNormalize(r, r); -} - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) -{ - GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); - - r[0] = invLength * q[0]; - r[1] = invLength * q[1]; - r[2] = invLength * q[2]; - r[3] = invLength * q[3]; -} diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.h deleted file mode 100644 index 2e97c717..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_math/nv_quat.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QUAT_H -#define INCLUDED_QUAT_H - -#include - -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); - -void NvQuatIdentity(GLfloat r[4]); - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); - -void NvQuatX(GLfloat r[4], GLfloat radians); - -void NvQuatY(GLfloat r[4], GLfloat radians); - -void NvQuatZ(GLfloat r[4], GLfloat radians); - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_types.h b/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_types.h deleted file mode 100644 index 1d1b0300..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/Qt3DSLibs/nv_types.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_TYPES_H -#define __INCLUDED_QT3DS_TYPES_H - -typedef unsigned char NvU8; // 0 to 255 -typedef unsigned short NvU16; // 0 to 65535 -typedef unsigned int NvU32; // 0 to 4294967295 -typedef unsigned long long NvU64; // 0 to 18446744073709551615 -typedef signed char NvS8; // -128 to 127 -typedef signed short NvS16; // -32768 to 32767 -typedef signed int NvS32; // -2147483648 to 2147483647 -typedef signed long long NvS64; // 2^-63 to 2^63-1 - -// Explicitly sized floats -typedef float NvF32; // IEEE Single Precision (S1E8M23) -typedef double NvF64; // IEEE Double Precision (S1E11M52) - -// Boolean type -#define QT3DS_FALSE 0 -#define QT3DS_TRUE 1 -typedef NvU8 NvBool; - -// Result of sizeof operator -typedef unsigned long NvSize; - -// Type large enough to hold a relative file offset -typedef long NvOffset; - -// Base NULL type. -#define QT3DS_NULL 0 - -// Error related -typedef enum { - NvError_Success = 0, - NvError_NotSupported, - NvError_NotInitialized, - NvError_BadParameter, - NvError_InsufficientMemory, - NvError_NoEntries, - NvError_UnknownError, -} NvError; - -#if 1 // defined(_DEBUG) // !!!!TBD TODO -#define NvAssert(c) -#else -#define NvAssert(c) ((void)((c) ? 0 : (NvHandleAssertion(#c, __FILE__, __LINE__), 0))) -#endif - -// Other standardized typedefs -typedef NvU64 NvUST; // U64 unadjusted system time value - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.abc b/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.abc deleted file mode 100644 index f7e3c2f6..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.abc and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.dds b/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.dds deleted file mode 100644 index 5bde760b..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_256.dds and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.abc b/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.abc deleted file mode 100644 index 2ff78757..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.abc and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.dds b/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.dds deleted file mode 100644 index f9e76d94..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Linux/assets/courier+lucida_512.dds and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Linux/assets/font.frag b/src/Runtime/Source/PlatformSpecific/Linux/assets/font.frag deleted file mode 100644 index e4673cf8..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/assets/font.frag +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -uniform sampler2D fontTex; - -varying lowp vec4 col_var; -varying lowp vec2 tex_var; - -void main() -{ - gl_FragColor = texture2D(fontTex, tex_var).a * col_var; -} - diff --git a/src/Runtime/Source/PlatformSpecific/Linux/assets/font.vert b/src/Runtime/Source/PlatformSpecific/Linux/assets/font.vert deleted file mode 100644 index 9f307a2f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Linux/assets/font.vert +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// this is set from higher level. think of it as the upper model matrix -uniform mat4 pixelToClipMat; - -uniform vec4 col_uni; - -attribute vec2 pos_attr; -attribute vec2 tex_attr; -attribute vec4 col_attr; - -varying vec4 col_var; -varying vec2 tex_var; - -void main() -{ - // account for translation and rotation of the primitive into [-1,1] spatial default. - gl_Position = pixelToClipMat * vec4(pos_attr.x, pos_attr.y, 0, 1); - - col_var = col_attr * col_uni; - tex_var = tex_attr; -} diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_color.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_color.h deleted file mode 100644 index b9347529..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_color.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_COLOR_H -#define _QT3DS_COLOR_H - -/** @file nv_color.h - Simple abstraction for RGBA colors as parameters to various libraries/functions. -*/ - -/** Base type for a single color channel (8-bit unsigned). */ -typedef unsigned char NvPCColor8; - -//#define NV_COLOR_BREAKOLD -#ifdef NV_COLOR_BREAKOLD // uses a struct to break backwards-compat and accidental uses - -typedef struct -{ - NvPCColor8 r; - NvPCColor8 g; - NvPCColor8 b; - NvPCColor8 a; -} NvPackedColor; - -static const NvPackedColor gnvpcwhite = { 255, 255, 255, 255 }; -static const NvPackedColor gnvpcblack = { 0, 0, 0, 255 }; - -#define NV_PACKED_COLOR(r, g, b, a) \ - { \ - (NvPCColor8)(r), (NvPCColor8)(g), (NvPCColor8)(b), (NvPCColor8)(a) \ - } - -#define NV_PC_PREDEF_WHITE gnvpcwhite -#define NV_PC_PREDEF_BLACK gnvpcblack - -#define NV_PC_RED(c) (c.r) -#define NV_PC_GREEN(c) (c.g) -#define NV_PC_BLUE(c) (c.b) -#define NV_PC_ALPHA(c) (c.a) - -#define NV_PC_PACK_UINT(c) (*(unsigned int *)(&(c))) - -#define NV_PC_EQUAL(x, y) ((x).r == (y).r && (x).g == (y).g && (x).b == (y).b && (x).a == (y).a) - -#else /* code that doesn't break old pass-as-uint stuff */ - -/** Main type declaration for a packed 4-color construct. */ -typedef unsigned int NvPackedColor; - -/** A macro to build a packed color, passing in RGBA as four 8-bit integer values. */ -#define NV_PACKED_COLOR(r, g, b, a) \ - ((NvPackedColor)(((((int)(a)) & 0xFF) << 24) | ((((int)(b)) & 0xFF) << 16) \ - | ((((int)(g)) & 0xFF) << 8) | ((((int)(r)) & 0xFF)))) - -/** A predefined constant for WHITE. */ -#define NV_PC_PREDEF_WHITE NV_PACKED_COLOR(0xFF, 0xFF, 0xFF, 0xFF) -/** A predefined constant for BLACK. */ -#define NV_PC_PREDEF_BLACK NV_PACKED_COLOR(0x00, 0x00, 0x00, 0xFF) - -/** A macro for 'extracting' the red value from an NvPackedColor. */ -#define NV_PC_RED(c) ((c >> 0) & 0xff) -/** A macro for 'extracting' the green value from an NvPackedColor. */ -#define NV_PC_GREEN(c) ((c >> 8) & 0xff) -/** A macro for 'extracting' the blue value from an NvPackedColor. */ -#define NV_PC_BLUE(c) ((c >> 16) & 0xff) -/** A macro for 'extracting' the alpha value from an NvPackedColor. */ -#define NV_PC_ALPHA(c) ((c >> 24) & 0xff) - -/** A macro requesting the packed color repacked into a 32-bit unsigned int. - This is a no-op for the color-as-uint approach. -*/ -#define NV_PC_PACK_UINT(c) (c) -/** A macro for testing the equality of two NvPackedColors. */ -#define NV_PC_EQUAL(x, y) (x == y) -#endif - -/** A macro for mapping a single packed color channel into its floating point [0,1] rep. */ -#define NV_PC_TO_FLOAT(c) (c / 255.0f) - -#endif /*_QT3DS_COLOR_H*/ diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_debug.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_debug.h deleted file mode 100644 index 2559dd6f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_debug.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_DEBUG_H -#define __INCLUDED_QT3DS_DEBUG_H - -#define CT_ASSERT(tag, cond) enum { COMPILE_TIME_ASSERT__##tag = 1 / (cond) } - -#define dimof(x) (sizeof(x) / sizeof(x[0])) -#include - -#define DBG_DETAILED 0 - -#if 0 - - // the detailed prefix can be customised by setting DBG_DETAILED_PREFIX. See - // below as a reference. - // NOTE: fmt is the desired format string and must be in the prefix. - //#ifndef DBG_DETAILED_PREFIX - // #define DBG_DETAILED_PREFIX "%s, %s, line %d: " fmt, __FILE__, __FUNCTION__, __LINE__, - //#endif - //#define DEBUG_D_(fmt, args...) - //#define DEBUG_D(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, (DBG_DETAILED_PREFIX) ## args) - -#else - -#ifdef STRINGIFY -#pragma push_macro("STRINGIFY") -#undef STRINGIFY -#define STRINGIFYPUSHED_____ -#endif -#define STRINGIFY(x) #x - -// debug macro, includes file name function name and line number -#define TO(x) typeof(x) -#define DEBUG_D_(file, line, fmt, args...) \ - __android_log_print(ANDROID_LOG_DEBUG, MODULE, file ", %s, line(" STRINGIFY(line) "): " fmt, \ - __FUNCTION__, ##args) -#define DEBUG_D(fmt, args...) DEBUG_D_(__FILE__, __LINE__, fmt, ##args) - -#ifdef STRINGIFYPUSHED_____ -#undef STRINGIFYPUSHED_____ -#pragma pop_macro("STRINGIFY") -#endif - -#endif - -// basic debug macro -#define DEBUG_(fmt, args...) (__android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args)) - -// Debug macro that can be switched to spew a file name, -// function and line number using DEBUG_DETAILED -#if DBG_DETAILED == 1 -#define DEBUG(fmt, args...) DEBUG_D(fmt, ##args) -#else -#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args) -#endif - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_global.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_global.h deleted file mode 100644 index 9d23d45f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_global.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_GLOBAL_H -#define __INCLUDED_QT3DS_GLOBAL_H - -#include "nv_types.h" - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/NvVec.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/NvVec.h deleted file mode 100644 index 4e5b09ce..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/NvVec.h +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H -#define INCLUDED_QT3DS_MATH_CPP_VEC_H - -#include "misc.h" - -struct _NvVec3 -{ - union { - struct - { - float x, y, z; - }; - float v[3]; - }; -}; - -struct NvVec3 : public _NvVec3 -{ - NvVec3() { zero(); } - - NvVec3(float x, float y, float z) - { - v[0] = x; - v[1] = y; - v[2] = z; - } - - NvVec3(NvVec3 const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - v[2] = that.v[2]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - v[2] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - NvVec3 &operator+=(NvVec3 const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - v[2] += that.v[2]; - return *this; - } - - NvVec3 &operator-=(NvVec3 const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - v[2] -= that.v[2]; - return *this; - } - - NvVec3 &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - v[2] *= s; - return *this; - } - - NvVec3 &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - v[2] /= s; - return *this; - } -}; - -inline float dot(NvVec3 const &a, NvVec3 const &b) -{ - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} - -inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a) -{ - - return NvVec3(-a.v[0], -a.v[1], -a.v[2]); -} - -inline NvVec3 operator*(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); -} - -inline NvVec3 operator*(float s, NvVec3 const &a) -{ - - return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); -} - -inline NvVec3 operator/(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); -} - -inline float magnitude(NvVec3 const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec3 normalize(NvVec3 const &v) -{ - float l = magnitude(v); - return NvVec3(v[0] / l, v[1] / l, v[2] / l); -} - -inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], - a.v[0] * b.v[1] - a.v[1] * b.v[0]); -} - -inline bool operator==(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); -} - -inline bool operator!=(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); -} - -struct NvVec2f -{ - union { - struct - { - float x, y; - float v[2]; - }; - }; - - NvVec2f() { zero(); } - - NvVec2f(float x, float y) - { - v[0] = x; - v[1] = y; - } - - NvVec2f(NvVec2f const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - NvVec2f &operator+=(NvVec2f const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - return *this; - } - - NvVec2f &operator-=(NvVec2f const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - return *this; - } - - NvVec2f &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - return *this; - } - - NvVec2f &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - return *this; - } -}; - -inline float dot(NvVec2f const &a, NvVec2f const &b) -{ - - return a[0] * b[0] + a[1] * b[1]; -} - -inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a) -{ - - return NvVec2f(-a.v[0], -a.v[1]); -} - -inline NvVec2f operator*(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] * s, a.v[1] * s); -} - -inline NvVec2f operator*(float s, NvVec2f const &a) -{ - - return NvVec2f(s * a.v[0], s * a.v[1]); -} - -inline NvVec2f operator/(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] / s, a.v[1] / s); -} - -inline float magnitude(NvVec2f const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec2f normalize(NvVec2f const &v) -{ - float l = dot(v, v); - return NvVec2f(v[0] / l, v[1] / l); -} - -inline float cross(NvVec2f const &a, NvVec2f const &b) -{ - - return a.v[0] * b.v[1] - b.v[0] * a.v[1]; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/misc.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/misc.h deleted file mode 100644 index 983410f3..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/misc.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H -#define INCLUDED_QT3DS_MATH_CPP_MISC_H - -inline bool nvIsPowerOfTwo(unsigned int i) -{ - return (i & (i - 1)) == 0; -} - -inline float nvDegToRadf(float d) -{ - return d * 3.14159265358979323846f / 180.0f; -} - -inline float nvRadToDegf(float r) -{ - return r * 180.0f / 3.14159265358979323846f; -} - -/* - 'mod' differs from '%' in that it behaves correctly when either the - numerator or denominator is negative. -*/ - -inline int nvMod(int n, int d) -{ - int m = n % d; - return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; -} - -inline int nvAbs(int n) -{ - if (n < 0) - return -n; - return n; -} - -inline int nvSign(int n) -{ - if (n > 0) - return 1; - if (n < 0) - return -1; - return 0; -} - -/* - This returns the smallest amplitude value x such that - nvMod(b + x, m) == a -*/ - -inline int nvDifMod(int a, int b, int m) -{ - - int x1 = a - b; - int x2 = (x1 > 0) ? x1 - m : x1 + m; - return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; -} - -inline float nvWrapf(float a, float min, float max) -{ - - assert(max > min); - - float d = max - min; - float s = a - min; - float q = s / d; - float m = q - floorf(q); - return m * d + min; -} - -inline float nvClampf(float a, float min, float max) -{ - return (a < min) ? min : ((a > max) ? max : a); -} - -inline int nvClampi(int i, int min, int max) -{ - return (i < min) ? min : ((i > max) ? max : i); -} - -inline float nvGaussian(float x, float s) -{ - float c = s * sqrtf(2.0f * 3.14159265358979323846f); - return expf(-(x * x) / (2.0f * s * s)) / c; -} - -inline float nvLerpf(float a, float b, float t) -{ - return a * (1.0f - t) + b * t; -} - -inline float nvEasef(float t) -{ - - float t_2 = t * t; - float t_3 = t_2 * t; - return 3.0f * t_2 - 2.0f * t_3; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.cpp b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.cpp deleted file mode 100644 index b83cb39e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_math.h" - -static const double a = 16807.0; -static const double m = 2147483647.0; - -static double nextSeed(double seed) -{ - double t = a * seed; - return t - m * (double)((int)(t / m)); -} - -GLfloat NvRandf() -{ - static double seed = 1.0; - seed = nextSeed(seed); - return (GLfloat)(seed * (1 / m)); -} - -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) -{ - // kdGetTimeUST is never supposed to decrease (i.e. that - // means it can't wrap, either. IIRC, it will wrap in - // 593 years). So we ignore that option... - - // Used for frame-to-frame diffs, this will fit in 32b - // as long as the times are < ~4.3s apart - long long int diffTime = newTime - oldTime; - - // Need to find a better way to do this. - // However, I believe we will be uSec precise (not run - // out of mantissa bits for uSecs) as long as the diff - // is < ~16s (1e-6 * (2^24)) - return ((GLfloat)diffTime) / 1.0e9f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.h deleted file mode 100644 index e777e409..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_math.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_MATH_H -#define _QT3DS_MATH_H - -#include - -GLfloat NvRandf(); - -/* These are the recommended "safer" ways to use GLfloat for time */ - -/* Returns the seconds between the two given times */ -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); - -#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.cpp b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.cpp deleted file mode 100644 index e208ac31..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_matrix.h" - -int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) -{ - return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); -} - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; -} - -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; -} - -GLfloat NvVecLengthf(const GLfloat v[3]) -{ - return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); -} - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) -{ - GLfloat const l = NvVecLengthf(v); - r[0] = v[0] / l; - r[1] = v[1] / l; - r[2] = v[2] / l; -} - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; -} - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - r[2] = a[2] - b[2]; -} - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - GLfloat t[3]; - - t[0] = a[1] * b[2] - a[2] * b[1]; - t[1] = a[2] * b[0] - a[0] * b[2]; - t[2] = a[0] * b[1] - a[1] * b[0]; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; -} - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); - - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; -} - -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; - r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; -} - -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; -} - -static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; - r[3][3] = 1.0f; -} - -static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; - r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; - r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; - r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; - r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; -} - -void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) - && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { - if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) - && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { - NvMultMat3x3f(r, a, b); - } else { - NvMultMat4x3f(r, a, b); - } - } else { - NvMultMat4x4f(r, a, b); - } - - NvCopyMatf(result, r); -} - -static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - /* x */ - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - /* y */ - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - /* z */ - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = 1.0f; -} - -static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] - + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] - + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] - + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] - + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] - + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] - + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] - + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] - + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] - + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] - + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] - + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] - + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] - + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) - / d; - - r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] - + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) - / d; - - r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] - + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] - + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) - / d; - - r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] - + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) - / d; - - r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] - + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) - / d; - - r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] - + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] - + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) - / d; - - r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] - + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) - / d; - - r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] - + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] - + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) - / d; - - r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] - + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] - + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) - / d; - - r[2][1] = - (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] - + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) - / d; - - r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] - + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] - + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) - / d; - - r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] - + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) - / d; - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] - + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) - / d; -} - -void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { - if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { - NvInvMat3x3f(r, m); - } else { - NvInvMat4x3f(r, m); - } - } else { - NvInvMat4x4f(r, m); - } - - NvCopyMatf(result, r); -} - -void NvBuildIdentityMatf(GLfloat r[4][4]) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = x; - r[3][1] = y; - r[3][2] = z; - r[3][3] = 1.0f; -} - -void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, - GLfloat z) -{ - GLfloat r[4][4]; /*temporary storage for result */ - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; - r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; - r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; - r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = x; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = y; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = z; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * x; - r[0][1] = m[0][1] * x; - r[0][2] = m[0][2] * x; - r[0][3] = m[0][3] * x; - - r[1][0] = m[1][0] * y; - r[1][1] = m[1][1] * y; - r[1][2] = m[1][2] * y; - r[1][3] = m[1][3] * y; - - r[2][0] = m[2][0] * z; - r[2][1] = m[2][1] * z; - r[2][2] = m[2][2] * z; - r[2][3] = m[2][3] * z; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) -{ - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = c; - r[1][2] = s; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = -s; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = 0.0f; - r[0][2] = -s; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = s; - r[2][1] = 0.0f; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = s; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = -s; - r[1][1] = c; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0] * c + m[2][0] * s; - r[1][1] = m[1][1] * c + m[2][1] * s; - r[1][2] = m[1][2] * c + m[2][2] * s; - r[1][3] = m[1][3] * c + m[2][3] * s; - - r[2][0] = m[1][0] * -s + m[2][0] * c; - r[2][1] = m[1][1] * -s + m[2][1] * c; - r[2][2] = m[1][2] * -s + m[2][2] * c; - r[2][3] = m[1][3] * -s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[2][0] * -s; - r[0][1] = m[0][1] * c + m[2][1] * -s; - r[0][2] = m[0][2] * c + m[2][2] * -s; - r[0][3] = m[0][3] * c + m[2][3] * -s; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[0][0] * s + m[2][0] * c; - r[2][1] = m[0][1] * s + m[2][1] * c; - r[2][2] = m[0][2] * s + m[2][2] * c; - r[2][3] = m[0][3] * s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[1][0] * s; - r[0][1] = m[0][1] * c + m[1][1] * s; - r[0][2] = m[0][2] * c + m[1][2] * s; - r[0][3] = m[0][3] * c + m[1][3] * s; - - r[1][0] = m[0][0] * -s + m[1][0] * c; - r[1][1] = m[0][1] * -s + m[1][1] * c; - r[1][2] = m[0][2] * -s + m[1][2] * c; - r[1][3] = m[0][3] * -s + m[1][3] * c; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) -{ - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - /* build a matrix from the quat */ - - result[0][0] = 1.0f - 2.0f * (j * j + k * k); - result[0][1] = 2.0f * (i * j + r * k); - result[0][2] = 2.0f * (i * k - r * j); - result[0][3] = 0.0f; - - result[1][0] = 2.0f * (i * j - r * k); - result[1][1] = 1.0f - 2.0f * (i * i + k * k); - result[1][2] = 2.0f * (j * k + r * i); - result[1][3] = 0.0f; - - result[2][0] = 2.0f * (i * k + r * j); - result[2][1] = 2.0f * (j * k - r * i); - result[2][2] = 1.0f - 2.0f * (i * i + j * j); - result[2][3] = 0.0f; - - result[3][0] = 0.0f; - result[3][1] = 0.0f; - result[3][2] = 0.0f; - result[3][3] = 1.0f; -} - -void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians) -{ - GLfloat r[4][4]; - - { - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat const dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - { - /* build a matrix from the quat */ - - GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); - GLfloat const a01 = 2.0f * (i * j + r * k); - GLfloat const a02 = 2.0f * (i * k - r * j); - - GLfloat const a10 = 2.0f * (i * j - r * k); - GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); - GLfloat const a12 = 2.0f * (j * k + r * i); - - GLfloat const a20 = 2.0f * (i * k + r * j); - GLfloat const a21 = 2.0f * (j * k - r * i); - GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); - - result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; - result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; - result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; - result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; - - result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; - result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; - result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; - result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; - - result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; - result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; - result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; - result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; - - result[3][0] = m[3][0]; - result[3][1] = m[3][1]; - result[3][2] = m[3][2]; - result[3][3] = m[3][3]; - } - } - - NvCopyMatf(result, r); -} - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) -{ - NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees) -{ - NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]) -{ - GLfloat ev[3]; - GLfloat z[3]; - GLfloat x_tmp[3]; - GLfloat x[3]; - GLfloat y[3]; - - NvSubVecf(ev, eye, obj); - - NvNormalizeVecf(z, ev); - - NvCrossProductf(x_tmp, up, z); - - NvNormalizeVecf(x, x_tmp); - - NvCrossProductf(y, z, x); - - r[0][0] = x[0]; - r[0][1] = y[0]; - r[0][2] = z[0]; - r[0][3] = 0.0f; - - r[1][0] = x[1]; - r[1][1] = y[1]; - r[1][2] = z[1]; - r[1][3] = 0.0f; - - r[2][0] = x[2]; - r[2][1] = y[2]; - r[2][2] = z[2]; - r[2][3] = 0.0f; - - r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; - r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; - r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; - r[3][3] = 1.0f; -} - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const m00 = znear * 2.0f / (right - left); - GLfloat const m11 = znear * 2.0f / (top - bottom); - GLfloat const m22 = -(zfar + znear) / (zfar - znear); - - GLfloat const m20 = (right + left) / (right - left); - GLfloat const m21 = (top + bottom) / (top - bottom); - - GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); - GLfloat const m23 = -1.0f; - - r[0][0] = m00; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = m11; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = m20; - r[2][1] = m21; - r[2][2] = m22; - r[2][3] = m23; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = m32; - r[3][3] = 0.0f; -} - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - GLfloat const sz = -2.0f / (zfar - znear); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - GLfloat const tz = -(zfar + znear) / (zfar - znear); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = sz; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = tz; - r[3][3] = 1.0f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.h deleted file mode 100644 index 0709f117..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_matrix.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_MATRIX_H -#define INCLUDED_MATRIX_H - -#include -#include -#include - -#define KD_FLT_EPSILON 1.19209290E-07F -#define KD_DEG_TO_RAD_F 0.0174532924F -#define KD_RAD_TO_DEG_F 57.2957802F - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); - -/* vector utilities */ - -GLfloat NvVecLengthf(const GLfloat v[3]); - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); - -/* matrix utilities */ - -void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); - -void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); - -/* matrix building utilities */ - -void NvBuildIdentityMatf(GLfloat r[4][4]); - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); - -void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]); - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -/* matrix concatenation utilities */ - -void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); -void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees); - -void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); - -void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.cpp b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.cpp deleted file mode 100644 index ec497941..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_quat.h" -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) -{ - memcpy(r, q, 4 * sizeof(GLfloat)); -} - -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) -{ - // Assumes that the quaternion is normalized! - GLfloat x2 = q[0] * 2.0f; - GLfloat y2 = q[1] * 2.0f; - GLfloat z2 = q[2] * 2.0f; - GLfloat xSq2 = x2 * q[0]; - GLfloat ySq2 = y2 * q[1]; - GLfloat zSq2 = z2 * q[2]; - GLfloat xy2 = x2 * q[1]; - GLfloat xz2 = x2 * q[2]; - GLfloat xw2 = x2 * q[3]; - GLfloat yz2 = y2 * q[2]; - GLfloat yw2 = y2 * q[3]; - GLfloat zw2 = z2 * q[3]; - - /* Matrix is - * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | - * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | - * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | - */ - r[0][0] = 1.0f - ySq2 - zSq2; - r[0][1] = xy2 - zw2; - r[0][2] = xz2 + yw2; - - r[1][0] = xy2 + zw2; - r[1][1] = 1.0f - xSq2 - zSq2; - r[1][2] = yz2 - xw2; - - r[2][0] = xz2 - yw2; - r[2][1] = yz2 + xw2; - r[2][2] = 1.0f - xSq2 - ySq2; -} - -void NvQuatIdentity(GLfloat r[4]) -{ - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = 1.0f; -} - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = axis[0] * sina; - r[1] = axis[1] * sina; - r[2] = axis[2] * sina; - r[3] = cosa; -} - -void NvQuatX(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = sina; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatY(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = sina; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatZ(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = sina; - r[3] = cosa; -} - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatY(h, heading); - NvQuatX(p, pitch); - NvQuatZ(ro, roll); - - NvQuatMult(r, h, p); - NvQuatMult(r, ro, r); -} - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatZ(ro, roll); - NvQuatX(p, pitch); - NvQuatY(h, heading); - - NvQuatMult(r, p, h); - NvQuatMult(r, r, ro); -} - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) -{ - return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; -} - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) -{ - const GLfloat q1x = q1[0]; - const GLfloat q1y = q1[1]; - const GLfloat q1z = q1[2]; - const GLfloat q1w = q1[3]; - const GLfloat q2x = q2[0]; - const GLfloat q2y = q2[1]; - const GLfloat q2z = q2[2]; - const GLfloat q2w = q2[3]; - - r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; - r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; - r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; - r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; -} - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) -{ - GLfloat omt = 1.0f - t; - - if (NvQuatDot(q1, q2) < 0.0f) { - r[0] = -q1[0] * omt + q2[0] * t; - r[1] = -q1[1] * omt + q2[1] * t; - r[2] = -q1[2] * omt + q2[2] * t; - r[3] = -q1[3] * omt + q2[3] * t; - } else { - r[0] = q1[0] * omt + q2[0] * t; - r[1] = q1[1] * omt + q2[1] * t; - r[2] = q1[2] * omt + q2[2] * t; - r[3] = q1[3] * omt + q2[3] * t; - } - - NvQuatNormalize(r, r); -} - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) -{ - GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); - - r[0] = invLength * q[0]; - r[1] = invLength * q[1]; - r[2] = invLength * q[2]; - r[3] = invLength * q[3]; -} diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.h deleted file mode 100644 index 2afdcb71..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_math/nv_quat.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QUAT_H -#define INCLUDED_QUAT_H - -#include -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); - -void NvQuatIdentity(GLfloat r[4]); - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); - -void NvQuatX(GLfloat r[4], GLfloat radians); - -void NvQuatY(GLfloat r[4], GLfloat radians); - -void NvQuatZ(GLfloat r[4], GLfloat radians); - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_types.h b/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_types.h deleted file mode 100644 index 1d1b0300..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/Qt3DSLibs/nv_types.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_TYPES_H -#define __INCLUDED_QT3DS_TYPES_H - -typedef unsigned char NvU8; // 0 to 255 -typedef unsigned short NvU16; // 0 to 65535 -typedef unsigned int NvU32; // 0 to 4294967295 -typedef unsigned long long NvU64; // 0 to 18446744073709551615 -typedef signed char NvS8; // -128 to 127 -typedef signed short NvS16; // -32768 to 32767 -typedef signed int NvS32; // -2147483648 to 2147483647 -typedef signed long long NvS64; // 2^-63 to 2^63-1 - -// Explicitly sized floats -typedef float NvF32; // IEEE Single Precision (S1E8M23) -typedef double NvF64; // IEEE Double Precision (S1E11M52) - -// Boolean type -#define QT3DS_FALSE 0 -#define QT3DS_TRUE 1 -typedef NvU8 NvBool; - -// Result of sizeof operator -typedef unsigned long NvSize; - -// Type large enough to hold a relative file offset -typedef long NvOffset; - -// Base NULL type. -#define QT3DS_NULL 0 - -// Error related -typedef enum { - NvError_Success = 0, - NvError_NotSupported, - NvError_NotInitialized, - NvError_BadParameter, - NvError_InsufficientMemory, - NvError_NoEntries, - NvError_UnknownError, -} NvError; - -#if 1 // defined(_DEBUG) // !!!!TBD TODO -#define NvAssert(c) -#else -#define NvAssert(c) ((void)((c) ? 0 : (NvHandleAssertion(#c, __FILE__, __LINE__), 0))) -#endif - -// Other standardized typedefs -typedef NvU64 NvUST; // U64 unadjusted system time value - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.abc b/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.abc deleted file mode 100644 index f7e3c2f6..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.abc and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.dds b/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.dds deleted file mode 100644 index 5bde760b..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_256.dds and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.abc b/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.abc deleted file mode 100644 index 2ff78757..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.abc and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.dds b/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.dds deleted file mode 100644 index f9e76d94..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Macos/assets/courier+lucida_512.dds and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Macos/assets/font.frag b/src/Runtime/Source/PlatformSpecific/Macos/assets/font.frag deleted file mode 100644 index e4673cf8..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/assets/font.frag +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -uniform sampler2D fontTex; - -varying lowp vec4 col_var; -varying lowp vec2 tex_var; - -void main() -{ - gl_FragColor = texture2D(fontTex, tex_var).a * col_var; -} - diff --git a/src/Runtime/Source/PlatformSpecific/Macos/assets/font.vert b/src/Runtime/Source/PlatformSpecific/Macos/assets/font.vert deleted file mode 100644 index 9f307a2f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Macos/assets/font.vert +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// this is set from higher level. think of it as the upper model matrix -uniform mat4 pixelToClipMat; - -uniform vec4 col_uni; - -attribute vec2 pos_attr; -attribute vec2 tex_attr; -attribute vec4 col_attr; - -varying vec4 col_var; -varying vec2 tex_var; - -void main() -{ - // account for translation and rotation of the primitive into [-1,1] spatial default. - gl_Position = pixelToClipMat * vec4(pos_attr.x, pos_attr.y, 0, 1); - - col_var = col_attr * col_uni; - tex_var = tex_attr; -} diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_color.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_color.h deleted file mode 100644 index b9347529..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_color.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_COLOR_H -#define _QT3DS_COLOR_H - -/** @file nv_color.h - Simple abstraction for RGBA colors as parameters to various libraries/functions. -*/ - -/** Base type for a single color channel (8-bit unsigned). */ -typedef unsigned char NvPCColor8; - -//#define NV_COLOR_BREAKOLD -#ifdef NV_COLOR_BREAKOLD // uses a struct to break backwards-compat and accidental uses - -typedef struct -{ - NvPCColor8 r; - NvPCColor8 g; - NvPCColor8 b; - NvPCColor8 a; -} NvPackedColor; - -static const NvPackedColor gnvpcwhite = { 255, 255, 255, 255 }; -static const NvPackedColor gnvpcblack = { 0, 0, 0, 255 }; - -#define NV_PACKED_COLOR(r, g, b, a) \ - { \ - (NvPCColor8)(r), (NvPCColor8)(g), (NvPCColor8)(b), (NvPCColor8)(a) \ - } - -#define NV_PC_PREDEF_WHITE gnvpcwhite -#define NV_PC_PREDEF_BLACK gnvpcblack - -#define NV_PC_RED(c) (c.r) -#define NV_PC_GREEN(c) (c.g) -#define NV_PC_BLUE(c) (c.b) -#define NV_PC_ALPHA(c) (c.a) - -#define NV_PC_PACK_UINT(c) (*(unsigned int *)(&(c))) - -#define NV_PC_EQUAL(x, y) ((x).r == (y).r && (x).g == (y).g && (x).b == (y).b && (x).a == (y).a) - -#else /* code that doesn't break old pass-as-uint stuff */ - -/** Main type declaration for a packed 4-color construct. */ -typedef unsigned int NvPackedColor; - -/** A macro to build a packed color, passing in RGBA as four 8-bit integer values. */ -#define NV_PACKED_COLOR(r, g, b, a) \ - ((NvPackedColor)(((((int)(a)) & 0xFF) << 24) | ((((int)(b)) & 0xFF) << 16) \ - | ((((int)(g)) & 0xFF) << 8) | ((((int)(r)) & 0xFF)))) - -/** A predefined constant for WHITE. */ -#define NV_PC_PREDEF_WHITE NV_PACKED_COLOR(0xFF, 0xFF, 0xFF, 0xFF) -/** A predefined constant for BLACK. */ -#define NV_PC_PREDEF_BLACK NV_PACKED_COLOR(0x00, 0x00, 0x00, 0xFF) - -/** A macro for 'extracting' the red value from an NvPackedColor. */ -#define NV_PC_RED(c) ((c >> 0) & 0xff) -/** A macro for 'extracting' the green value from an NvPackedColor. */ -#define NV_PC_GREEN(c) ((c >> 8) & 0xff) -/** A macro for 'extracting' the blue value from an NvPackedColor. */ -#define NV_PC_BLUE(c) ((c >> 16) & 0xff) -/** A macro for 'extracting' the alpha value from an NvPackedColor. */ -#define NV_PC_ALPHA(c) ((c >> 24) & 0xff) - -/** A macro requesting the packed color repacked into a 32-bit unsigned int. - This is a no-op for the color-as-uint approach. -*/ -#define NV_PC_PACK_UINT(c) (c) -/** A macro for testing the equality of two NvPackedColors. */ -#define NV_PC_EQUAL(x, y) (x == y) -#endif - -/** A macro for mapping a single packed color channel into its floating point [0,1] rep. */ -#define NV_PC_TO_FLOAT(c) (c / 255.0f) - -#endif /*_QT3DS_COLOR_H*/ diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_config/nv_config.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_config/nv_config.h deleted file mode 100644 index fb0b88af..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_config/nv_config.h +++ /dev/null @@ -1,278 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef _QT3DS_CONFIG_H -#define _QT3DS_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/** \file nv_config.h - Support for block-based text config files. - - Supports: -
    -
  • C-style comment blocks -
  • C++-style comment lines -
  • Line continuation via backslash -
  • Linux, Mac and Windows line endings -
  • Arrays of tokens, broken out by line -
  • Tokens are split by commas and whitespace -
  • Quoted string tokens containing any characters -
- */ - -/** The in-memory representation of a loaded config file. - - This opaque data structure is passed by pointer to all of the - configuration functions and represents the loaded configuration - file. Once loaded, there is no mutable persistent state in this - object. It is passed as const to all functions -*/ -typedef struct NvConfigData NvConfigData; - -/** The representation of a sub-range of lines in a config file. - - This structure is application-readable and mutable, and is used to - represent a subset of the lines in a config file. Generally, these - ranges represent delineated blocks in the config file. Special versions - of many of the config file functions take data ranges instead of - entire config files - - @see NvConfigFindDelimitedBlock() -*/ -typedef struct NvConfigDataRange -{ - /** A reference to the "parent" config file for this range */ - NvConfigData *data; - /** The first line of the range (inclusive) */ - KDint startLine; - /** The last line of the range (inclusive) */ - KDint endLine; -} NvConfigDataRange; - -/** Creates a config data object that represents an existing config file - - @return A pointer to the allocated config data, or NULL if the file cannot - be found or does not conform to the basic config file format - @param filename The path of the config file to be loaded - @see NvConfigFree() -*/ -NvConfigData *NvConfigCreateFromFile(const KDchar *filename); - -/** Creates a config data object from an-in memory string - - Useful when the config file is loaded from a larger, packed data file, - or generated on-the-fly in the application. Note that the code does not - automatically handle NULL-terminated strings - - @return A pointer to the allocated config data, or NULL if the string - does not conform to the basic config file format - @param fileBuffer A pointer to the start of the string of config data - @param fileSize The length of the string in characters - @see NvConfigFree() -*/ -NvConfigData *NvConfigCreateFromBuffer(const KDchar *fileBuffer, KDint fileSize); - -/** Deletes an existing config file data object - - @param data A pointer to the data object to delete -*/ -void NvConfigFree(NvConfigData *data); - -/** Returns the number of token-bearing lines in the config data object. - - This does not count merged lines, comment lines, or whitespace. This - value is one greater than the maximum valid line index in the file - - @return The line count - @param data A pointer to the data object -*/ -KDint NvConfigGetLineCount(const NvConfigData *data); - -/** Returns the number of tokens in the indexed line - - @return The token count - @param data A pointer to the data object - @param line The line whose count is to be returned. This parameter must - be at least 0 and must be less than the line count of the object - @see NvConfigGetLineCount -*/ -KDint NvConfigGetTokenCount(const NvConfigData *data, KDint line); - -/** Returns a NULL-terminated string token at the given line and token index - - The parameters are unchecked. - - @return A non-mutable token pointer for the referenced token - @param data A pointer to the data object - @param line The line whose token is to be returned. This parameter must - be at least 0 and must be less than the line count of the object - @param token The token index of the token to be returned. This parameter must - be at least 0 and must be less than the token count of the line - @see NvConfigGetLineCount - @see NvConfigGetTokenCount -*/ -const KDchar *NvConfigGetToken(const NvConfigData *data, KDint line, KDint token); - -/** Returns the string token converted to an integer - - Returns the string token at the given line and token index converted to an integer. - The parameters are unchecked, and the string token is assumed to be convertible to - an integer value. - - @return The integer value of the referenced token - @param data A pointer to the data object - @param line The line whose token is to be returned. This parameter must - be at least 0 and must be less than the line count of the object - @param token The token index of the token to be returned. This parameter must - be at least 0 and must be less than the token count of the line - @see NvConfigGetLineCount - @see NvConfigGetTokenCount -*/ -KDint NvConfigGetIntToken(const NvConfigData *data, KDint line, KDint token); - -/** Returns the string token converted to a floating-point value - - Returns the string token at the given line and token index converted to a - floating-point number. The parameters are unchecked, and the string token - is assumed to be convertible to a real value. - - @return The floating-point value of the referenced token - @param data A pointer to the data object - @param line The line whose token is to be returned. This parameter must - be at least 0 and must be less than the line count of the object - @param token The token index of the token to be returned. This parameter must - be at least 0 and must be less than the token count of the line - @see NvConfigGetLineCount - @see NvConfigGetTokenCount -*/ -KDfloat32 NvConfigGetFloatToken(const NvConfigData *data, KDint line, KDint token); - -/** Returns the count of lines in the config data whose leading token - matches a given string - - The search starts at the indicated line and continues to the end of the file - - @return The count of matching lines - @param data A pointer to the data object - @param name The string to be matched (case-sensitive) - @param startLine The line at which the search should start. This parameter must - be at least 0 and must be less than the line count of the object - @see NvConfigGetLineCount -*/ -KDint NvConfigCountMatchingLines(const NvConfigData *data, const KDchar *name, KDint startLine); - -/** Returns the count of lines in the subrange of the config data - whose leading token matches a given string - - The search is run only in the given subrange of the file - - @return The count of matching lines - @param range A pointer to the subrange of the data object - @param name The string to be matched (case-sensitive) -*/ -KDint NvConfigCountMatchingLinesInRange(const NvConfigDataRange *range, const KDchar *name); - -/** Returns the index of the first line in the config data (at or after - the given start line) whose leading token matches a given string - - The search starts at the indicated line and continues to the end of the - file - - @return The index of the first matching line, or -1 if no match - @param data A pointer to the data object - @param name The string to be matched (case-sensitive) - @param startLine The line at which the search should start. This parameter must - be at least 0 and must be less than the line count of the object - @see NvConfigGetLineCount -*/ -KDint NvConfigFindMatchingLine(const NvConfigData *data, const KDchar *name, KDint startLine); - -/** Returns the index of the first line in the subrange of the config data - whose leading token matches a given string - - The search is run only in the given subrange of the file - - @return The index of the first matching line, or -1 if no match - @param range A pointer to the subrange of the data object - @param name The string to be matched (case-sensitive) -*/ -KDint NvConfigFindMatchingLineInRange(const NvConfigDataRange *range, const KDchar *name); - -/** Finds a matching token-delimited block in the file and returns it as a subrange. - - Searches for a token-delimited open/close block in the given line range. - If the nested parameter is true, then additional nested open/close blocks - are tracked and the returned block is the one that properly closes the - given open block. If the nested flag is false, then the open/close are - treated like C-comments, and the first closing token found is returned - - @return KD_TRUE if a block with both an open and a close token is found, - KD_FALSE otherwise - @param data A pointer to the data object - @param openText The string token to be matched as the start of a block. - (case-sensitive) Only the leading token of each line is tested - @param closeText The string token to be matched as the end of a block. - (case-sensitive) Only the leading token of each line is tested - @param nested If KD_TRUE, C-bracket-style nesting is used to determine - which end token is matched. If KD_FALSE, C-comment-style flat matching - is used to match the end token. - @param startLine The index of the first line to search (inclusive) - @param endLine The index of the last line to search (inclusive) - @param range Output: A pointer to the subrange of the data object. This - should be a pointer to an allocated struct -*/ -KDboolean NvConfigFindDelimitedBlock(const NvConfigData *data, const KDchar *openText, - const KDchar *closeText, KDboolean nested, KDint startLine, - KDint endLine, NvConfigDataRange *range); - -/** Returns the index of the first matching token in the given line - - Returns the index of the first token on the given line (if any) that - matches the given string. - - @return The index of the matching string token in the line, or else -1 if - the token is not found in the line - @param data A pointer to the data object - @param token The string to be matched (case-sensitive) - @param line The line to search. This parameter must - be at least 0 and must be less than the line count of the object - @see NvConfigGetLineCount -*/ -KDint NvConfigFindMatchingTokenInLine(const NvConfigData *data, const KDchar *token, KDint line); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_debug.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_debug.h deleted file mode 100644 index 2559dd6f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_debug.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_DEBUG_H -#define __INCLUDED_QT3DS_DEBUG_H - -#define CT_ASSERT(tag, cond) enum { COMPILE_TIME_ASSERT__##tag = 1 / (cond) } - -#define dimof(x) (sizeof(x) / sizeof(x[0])) -#include - -#define DBG_DETAILED 0 - -#if 0 - - // the detailed prefix can be customised by setting DBG_DETAILED_PREFIX. See - // below as a reference. - // NOTE: fmt is the desired format string and must be in the prefix. - //#ifndef DBG_DETAILED_PREFIX - // #define DBG_DETAILED_PREFIX "%s, %s, line %d: " fmt, __FILE__, __FUNCTION__, __LINE__, - //#endif - //#define DEBUG_D_(fmt, args...) - //#define DEBUG_D(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, (DBG_DETAILED_PREFIX) ## args) - -#else - -#ifdef STRINGIFY -#pragma push_macro("STRINGIFY") -#undef STRINGIFY -#define STRINGIFYPUSHED_____ -#endif -#define STRINGIFY(x) #x - -// debug macro, includes file name function name and line number -#define TO(x) typeof(x) -#define DEBUG_D_(file, line, fmt, args...) \ - __android_log_print(ANDROID_LOG_DEBUG, MODULE, file ", %s, line(" STRINGIFY(line) "): " fmt, \ - __FUNCTION__, ##args) -#define DEBUG_D(fmt, args...) DEBUG_D_(__FILE__, __LINE__, fmt, ##args) - -#ifdef STRINGIFYPUSHED_____ -#undef STRINGIFYPUSHED_____ -#pragma pop_macro("STRINGIFY") -#endif - -#endif - -// basic debug macro -#define DEBUG_(fmt, args...) (__android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args)) - -// Debug macro that can be switched to spew a file name, -// function and line number using DEBUG_DETAILED -#if DBG_DETAILED == 1 -#define DEBUG(fmt, args...) DEBUG_D(fmt, ##args) -#else -#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args) -#endif - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_global.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_global.h deleted file mode 100644 index 9d23d45f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_global.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_GLOBAL_H -#define __INCLUDED_QT3DS_GLOBAL_H - -#include "nv_types.h" - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/NvVec.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/NvVec.h deleted file mode 100644 index 4e5b09ce..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/NvVec.h +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H -#define INCLUDED_QT3DS_MATH_CPP_VEC_H - -#include "misc.h" - -struct _NvVec3 -{ - union { - struct - { - float x, y, z; - }; - float v[3]; - }; -}; - -struct NvVec3 : public _NvVec3 -{ - NvVec3() { zero(); } - - NvVec3(float x, float y, float z) - { - v[0] = x; - v[1] = y; - v[2] = z; - } - - NvVec3(NvVec3 const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - v[2] = that.v[2]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - v[2] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 3) && (i >= 0)); - return v[i]; - } - - NvVec3 &operator+=(NvVec3 const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - v[2] += that.v[2]; - return *this; - } - - NvVec3 &operator-=(NvVec3 const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - v[2] -= that.v[2]; - return *this; - } - - NvVec3 &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - v[2] *= s; - return *this; - } - - NvVec3 &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - v[2] /= s; - return *this; - } -}; - -inline float dot(NvVec3 const &a, NvVec3 const &b) -{ - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} - -inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); -} - -inline NvVec3 operator-(NvVec3 const &a) -{ - - return NvVec3(-a.v[0], -a.v[1], -a.v[2]); -} - -inline NvVec3 operator*(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); -} - -inline NvVec3 operator*(float s, NvVec3 const &a) -{ - - return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); -} - -inline NvVec3 operator/(NvVec3 const &a, float s) -{ - - return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); -} - -inline float magnitude(NvVec3 const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec3 normalize(NvVec3 const &v) -{ - float l = magnitude(v); - return NvVec3(v[0] / l, v[1] / l, v[2] / l); -} - -inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) -{ - - return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], - a.v[0] * b.v[1] - a.v[1] * b.v[0]); -} - -inline bool operator==(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); -} - -inline bool operator!=(NvVec3 const &a, NvVec3 const &b) -{ - return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); -} - -struct NvVec2f -{ - union { - struct - { - float x, y; - float v[2]; - }; - }; - - NvVec2f() { zero(); } - - NvVec2f(float x, float y) - { - v[0] = x; - v[1] = y; - } - - NvVec2f(NvVec2f const &that) - { - v[0] = that.v[0]; - v[1] = that.v[1]; - } - - inline void zero() - { - v[0] = 0.0f; - v[1] = 0.0f; - } - - inline float &operator[](int i) - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - inline float const &operator[](int i) const - { - assert((i < 2) && (i >= 0)); - return v[i]; - } - - NvVec2f &operator+=(NvVec2f const &that) - { - v[0] += that.v[0]; - v[1] += that.v[1]; - return *this; - } - - NvVec2f &operator-=(NvVec2f const &that) - { - v[0] -= that.v[0]; - v[1] -= that.v[1]; - return *this; - } - - NvVec2f &operator*=(float s) - { - v[0] *= s; - v[1] *= s; - return *this; - } - - NvVec2f &operator/=(float s) - { - v[0] /= s; - v[1] /= s; - return *this; - } -}; - -inline float dot(NvVec2f const &a, NvVec2f const &b) -{ - - return a[0] * b[0] + a[1] * b[1]; -} - -inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) -{ - - return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); -} - -inline NvVec2f operator-(NvVec2f const &a) -{ - - return NvVec2f(-a.v[0], -a.v[1]); -} - -inline NvVec2f operator*(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] * s, a.v[1] * s); -} - -inline NvVec2f operator*(float s, NvVec2f const &a) -{ - - return NvVec2f(s * a.v[0], s * a.v[1]); -} - -inline NvVec2f operator/(NvVec2f const &a, float s) -{ - - return NvVec2f(a.v[0] / s, a.v[1] / s); -} - -inline float magnitude(NvVec2f const &v) -{ - return sqrtf(dot(v, v)); -} - -inline NvVec2f normalize(NvVec2f const &v) -{ - float l = dot(v, v); - return NvVec2f(v[0] / l, v[1] / l); -} - -inline float cross(NvVec2f const &a, NvVec2f const &b) -{ - - return a.v[0] * b.v[1] - b.v[0] * a.v[1]; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/misc.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/misc.h deleted file mode 100644 index 983410f3..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/misc.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H -#define INCLUDED_QT3DS_MATH_CPP_MISC_H - -inline bool nvIsPowerOfTwo(unsigned int i) -{ - return (i & (i - 1)) == 0; -} - -inline float nvDegToRadf(float d) -{ - return d * 3.14159265358979323846f / 180.0f; -} - -inline float nvRadToDegf(float r) -{ - return r * 180.0f / 3.14159265358979323846f; -} - -/* - 'mod' differs from '%' in that it behaves correctly when either the - numerator or denominator is negative. -*/ - -inline int nvMod(int n, int d) -{ - int m = n % d; - return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; -} - -inline int nvAbs(int n) -{ - if (n < 0) - return -n; - return n; -} - -inline int nvSign(int n) -{ - if (n > 0) - return 1; - if (n < 0) - return -1; - return 0; -} - -/* - This returns the smallest amplitude value x such that - nvMod(b + x, m) == a -*/ - -inline int nvDifMod(int a, int b, int m) -{ - - int x1 = a - b; - int x2 = (x1 > 0) ? x1 - m : x1 + m; - return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; -} - -inline float nvWrapf(float a, float min, float max) -{ - - assert(max > min); - - float d = max - min; - float s = a - min; - float q = s / d; - float m = q - floorf(q); - return m * d + min; -} - -inline float nvClampf(float a, float min, float max) -{ - return (a < min) ? min : ((a > max) ? max : a); -} - -inline int nvClampi(int i, int min, int max) -{ - return (i < min) ? min : ((i > max) ? max : i); -} - -inline float nvGaussian(float x, float s) -{ - float c = s * sqrtf(2.0f * 3.14159265358979323846f); - return expf(-(x * x) / (2.0f * s * s)) / c; -} - -inline float nvLerpf(float a, float b, float t) -{ - return a * (1.0f - t) + b * t; -} - -inline float nvEasef(float t) -{ - - float t_2 = t * t; - float t_3 = t_2 * t; - return 3.0f * t_2 - 2.0f * t_3; -} - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.cpp b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.cpp deleted file mode 100644 index b83cb39e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_math.h" - -static const double a = 16807.0; -static const double m = 2147483647.0; - -static double nextSeed(double seed) -{ - double t = a * seed; - return t - m * (double)((int)(t / m)); -} - -GLfloat NvRandf() -{ - static double seed = 1.0; - seed = nextSeed(seed); - return (GLfloat)(seed * (1 / m)); -} - -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) -{ - // kdGetTimeUST is never supposed to decrease (i.e. that - // means it can't wrap, either. IIRC, it will wrap in - // 593 years). So we ignore that option... - - // Used for frame-to-frame diffs, this will fit in 32b - // as long as the times are < ~4.3s apart - long long int diffTime = newTime - oldTime; - - // Need to find a better way to do this. - // However, I believe we will be uSec precise (not run - // out of mantissa bits for uSecs) as long as the diff - // is < ~16s (1e-6 * (2^24)) - return ((GLfloat)diffTime) / 1.0e9f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.h deleted file mode 100644 index ec729a79..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_math.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _QT3DS_MATH_H -#define _QT3DS_MATH_H - -#include - -GLfloat NvRandf(); - -/* These are the recommended "safer" ways to use GLfloat for time */ - -/* Returns the seconds between the two given times */ -GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); - -#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.cpp b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.cpp deleted file mode 100644 index e208ac31..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_matrix.h" - -int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) -{ - return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); -} - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; -} - -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) -{ - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; -} - -GLfloat NvVecLengthf(const GLfloat v[3]) -{ - return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); -} - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) -{ - GLfloat const l = NvVecLengthf(v); - r[0] = v[0] / l; - r[1] = v[1] / l; - r[2] = v[2] / l; -} - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; -} - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - r[2] = a[2] - b[2]; -} - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) -{ - GLfloat t[3]; - - t[0] = a[1] * b[2] - a[2] * b[1]; - t[1] = a[2] * b[0] - a[0] * b[2]; - t[2] = a[0] * b[1] - a[1] * b[0]; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; -} - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); - - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; -} - -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; - r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; -} - -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) -{ - r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; - r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; - r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; -} - -static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; - r[0][3] = 0.0f; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; - r[1][3] = 0.0f; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; - r[2][3] = 0.0f; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; - r[3][3] = 1.0f; -} - -static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); - - r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; - r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; - r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; - r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; - - r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; - r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; - r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; - r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; - - r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; - r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; - r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; - r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; - - r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; - r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; - r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; - r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; -} - -void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) - && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { - if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) - && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { - NvMultMat3x3f(r, a, b); - } else { - NvMultMat4x3f(r, a, b); - } - } else { - NvMultMat4x4f(r, a, b); - } - - NvCopyMatf(result, r); -} - -static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] - + -m[0][2] * m[1][1] * m[2][0]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; - r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; - r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; - r[0][3] = 0.0f; - - r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; - r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; - r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; - r[1][3] = 0.0f; - - r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; - r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; - r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; - r[2][3] = 0.0f; - - /* x */ - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - /* y */ - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - /* z */ - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = 1.0f; -} - -static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) -{ - GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] - + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] - + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] - + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] - + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] - + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] - + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] - + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] - + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] - + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] - + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] - + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; - - assert(NvDifferentMatsf(r, m)); - - r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] - + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] - + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) - / d; - - r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] - + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) - / d; - - r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] - + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] - + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) - / d; - - r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] - + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) - / d; - - r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] - + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) - / d; - - r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] - + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] - + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) - / d; - - r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] - + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) - / d; - - r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] - + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] - + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) - / d; - - r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] - + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] - + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) - / d; - - r[2][1] = - (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] - + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) - / d; - - r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] - + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] - + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) - / d; - - r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] - + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) - / d; - - r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] - + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) - / d; - - r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] - + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] - + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) - / d; - - r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] - + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) - / d; - - r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] - + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] - + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) - / d; -} - -void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) -{ - /* - Use a temporary matrix for the result and copy the temporary - into the result when finished. Doing this instead of writing - the result directly guarantees that the routine will work even - if the result overlaps one or more of the arguments in - memory. - */ - - GLfloat r[4][4]; - - if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { - if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { - NvInvMat3x3f(r, m); - } else { - NvInvMat4x3f(r, m); - } - } else { - NvInvMat4x4f(r, m); - } - - NvCopyMatf(result, r); -} - -void NvBuildIdentityMatf(GLfloat r[4][4]) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = x; - r[3][1] = y; - r[3][2] = z; - r[3][3] = 1.0f; -} - -void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, - GLfloat z) -{ - GLfloat r[4][4]; /*temporary storage for result */ - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; - r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; - r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; - r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - r[0][0] = x; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = y; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = z; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) -{ - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * x; - r[0][1] = m[0][1] * x; - r[0][2] = m[0][2] * x; - r[0][3] = m[0][3] * x; - - r[1][0] = m[1][0] * y; - r[1][1] = m[1][1] * y; - r[1][2] = m[1][2] * y; - r[1][3] = m[1][3] * y; - - r[2][0] = m[2][0] * z; - r[2][1] = m[2][1] * z; - r[2][2] = m[2][2] * z; - r[2][3] = m[2][3] * z; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) -{ - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = 1.0f; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = c; - r[1][2] = s; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = -s; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = 0.0f; - r[0][2] = -s; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = 1.0f; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = s; - r[2][1] = 0.0f; - r[2][2] = c; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - r[0][0] = c; - r[0][1] = s; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = -s; - r[1][1] = c; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0]; - r[0][1] = m[0][1]; - r[0][2] = m[0][2]; - r[0][3] = m[0][3]; - - r[1][0] = m[1][0] * c + m[2][0] * s; - r[1][1] = m[1][1] * c + m[2][1] * s; - r[1][2] = m[1][2] * c + m[2][2] * s; - r[1][3] = m[1][3] * c + m[2][3] * s; - - r[2][0] = m[1][0] * -s + m[2][0] * c; - r[2][1] = m[1][1] * -s + m[2][1] * c; - r[2][2] = m[1][2] * -s + m[2][2] * c; - r[2][3] = m[1][3] * -s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[2][0] * -s; - r[0][1] = m[0][1] * c + m[2][1] * -s; - r[0][2] = m[0][2] * c + m[2][2] * -s; - r[0][3] = m[0][3] * c + m[2][3] * -s; - - r[1][0] = m[1][0]; - r[1][1] = m[1][1]; - r[1][2] = m[1][2]; - r[1][3] = m[1][3]; - - r[2][0] = m[0][0] * s + m[2][0] * c; - r[2][1] = m[0][1] * s + m[2][1] * c; - r[2][2] = m[0][2] * s + m[2][2] * c; - r[2][3] = m[0][3] * s + m[2][3] * c; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) -{ - - GLfloat const s = sinf(radians); - GLfloat const c = cosf(radians); - - GLfloat r[4][4]; - - r[0][0] = m[0][0] * c + m[1][0] * s; - r[0][1] = m[0][1] * c + m[1][1] * s; - r[0][2] = m[0][2] * c + m[1][2] * s; - r[0][3] = m[0][3] * c + m[1][3] * s; - - r[1][0] = m[0][0] * -s + m[1][0] * c; - r[1][1] = m[0][1] * -s + m[1][1] * c; - r[1][2] = m[0][2] * -s + m[1][2] * c; - r[1][3] = m[0][3] * -s + m[1][3] * c; - - r[2][0] = m[2][0]; - r[2][1] = m[2][1]; - r[2][2] = m[2][2]; - r[2][3] = m[2][3]; - - r[3][0] = m[3][0]; - r[3][1] = m[3][1]; - r[3][2] = m[3][2]; - r[3][3] = m[3][3]; - - NvCopyMatf(result, r); -} - -void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) -{ - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - /* build a matrix from the quat */ - - result[0][0] = 1.0f - 2.0f * (j * j + k * k); - result[0][1] = 2.0f * (i * j + r * k); - result[0][2] = 2.0f * (i * k - r * j); - result[0][3] = 0.0f; - - result[1][0] = 2.0f * (i * j - r * k); - result[1][1] = 1.0f - 2.0f * (i * i + k * k); - result[1][2] = 2.0f * (j * k + r * i); - result[1][3] = 0.0f; - - result[2][0] = 2.0f * (i * k + r * j); - result[2][1] = 2.0f * (j * k - r * i); - result[2][2] = 1.0f - 2.0f * (i * i + j * j); - result[2][3] = 0.0f; - - result[3][0] = 0.0f; - result[3][1] = 0.0f; - result[3][2] = 0.0f; - result[3][3] = 1.0f; -} - -void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians) -{ - GLfloat r[4][4]; - - { - /* build a quat first */ - - GLfloat i, j, k, r; - - /* should be */ - GLfloat const dst_l = sinf(radians / 2.0f); - - /* actually is */ - GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); - - if (src_l <= KD_FLT_EPSILON) { - i = 0.0f; - j = 0.0f; - k = 0.0f; - r = 1.0f; - } else { - GLfloat const s = dst_l / src_l; - i = axis[0] * s; - j = axis[1] * s; - k = axis[2] * s; - r = cosf(radians / 2.0f); - } - - { - /* build a matrix from the quat */ - - GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); - GLfloat const a01 = 2.0f * (i * j + r * k); - GLfloat const a02 = 2.0f * (i * k - r * j); - - GLfloat const a10 = 2.0f * (i * j - r * k); - GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); - GLfloat const a12 = 2.0f * (j * k + r * i); - - GLfloat const a20 = 2.0f * (i * k + r * j); - GLfloat const a21 = 2.0f * (j * k - r * i); - GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); - - result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; - result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; - result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; - result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; - - result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; - result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; - result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; - result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; - - result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; - result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; - result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; - result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; - - result[3][0] = m[3][0]; - result[3][1] = m[3][1]; - result[3][2] = m[3][2]; - result[3][3] = m[3][3]; - } - } - - NvCopyMatf(result, r); -} - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) -{ - NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) -{ - NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) -{ - NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees) -{ - NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); -} - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]) -{ - GLfloat ev[3]; - GLfloat z[3]; - GLfloat x_tmp[3]; - GLfloat x[3]; - GLfloat y[3]; - - NvSubVecf(ev, eye, obj); - - NvNormalizeVecf(z, ev); - - NvCrossProductf(x_tmp, up, z); - - NvNormalizeVecf(x, x_tmp); - - NvCrossProductf(y, z, x); - - r[0][0] = x[0]; - r[0][1] = y[0]; - r[0][2] = z[0]; - r[0][3] = 0.0f; - - r[1][0] = x[1]; - r[1][1] = y[1]; - r[1][2] = z[1]; - r[1][3] = 0.0f; - - r[2][0] = x[2]; - r[2][1] = y[2]; - r[2][2] = z[2]; - r[2][3] = 0.0f; - - r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; - r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; - r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; - r[3][3] = 1.0f; -} - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const m00 = znear * 2.0f / (right - left); - GLfloat const m11 = znear * 2.0f / (top - bottom); - GLfloat const m22 = -(zfar + znear) / (zfar - znear); - - GLfloat const m20 = (right + left) / (right - left); - GLfloat const m21 = (top + bottom) / (top - bottom); - - GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); - GLfloat const m23 = -1.0f; - - r[0][0] = m00; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = m11; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = m20; - r[2][1] = m21; - r[2][2] = m22; - r[2][3] = m23; - - r[3][0] = 0.0f; - r[3][1] = 0.0f; - r[3][2] = m32; - r[3][3] = 0.0f; -} - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = 1.0f; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = 0.0f; - r[3][3] = 1.0f; -} - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) -{ - GLfloat const sx = 2.0f / (right - left); - GLfloat const sy = 2.0f / (top - bottom); - GLfloat const sz = -2.0f / (zfar - znear); - - GLfloat const tx = -(right + left) / (right - left); - GLfloat const ty = -(top + bottom) / (top - bottom); - GLfloat const tz = -(zfar + znear) / (zfar - znear); - - r[0][0] = sx; - r[0][1] = 0.0f; - r[0][2] = 0.0f; - r[0][3] = 0.0f; - - r[1][0] = 0.0f; - r[1][1] = sy; - r[1][2] = 0.0f; - r[1][3] = 0.0f; - - r[2][0] = 0.0f; - r[2][1] = 0.0f; - r[2][2] = sz; - r[2][3] = 0.0f; - - r[3][0] = tx; - r[3][1] = ty; - r[3][2] = tz; - r[3][3] = 1.0f; -} diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.h deleted file mode 100644 index 0e04568e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_matrix.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_MATRIX_H -#define INCLUDED_MATRIX_H - -#include -#include -#include - -#define KD_FLT_EPSILON 1.19209290E-07F -#define KD_DEG_TO_RAD_F 0.0174532924F -#define KD_RAD_TO_DEG_F 57.2957802F - -void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); -void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); - -/* vector utilities */ - -GLfloat NvVecLengthf(const GLfloat v[3]); - -void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); - -void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); - -void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); -void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); -void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); - -/* matrix utilities */ - -void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); - -void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); - -/* matrix building utilities */ - -void NvBuildIdentityMatf(GLfloat r[4][4]); - -void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); -void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); - -void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); - -void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); -void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); - -void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); - -void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], - const GLfloat up[3]); - -void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); - -void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar); - -/* matrix concatenation utilities */ - -void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); -void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); - -void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); -void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); - -void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat degrees); - -void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); -void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); - -void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], - GLfloat radians); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.cpp b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.cpp deleted file mode 100644 index 9626eb8c..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "nv_quat.h" -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) -{ - memcpy(r, q, 4 * sizeof(GLfloat)); -} - -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) -{ - // Assumes that the quaternion is normalized! - GLfloat x2 = q[0] * 2.0f; - GLfloat y2 = q[1] * 2.0f; - GLfloat z2 = q[2] * 2.0f; - GLfloat xSq2 = x2 * q[0]; - GLfloat ySq2 = y2 * q[1]; - GLfloat zSq2 = z2 * q[2]; - GLfloat xy2 = x2 * q[1]; - GLfloat xz2 = x2 * q[2]; - GLfloat xw2 = x2 * q[3]; - GLfloat yz2 = y2 * q[2]; - GLfloat yw2 = y2 * q[3]; - GLfloat zw2 = z2 * q[3]; - - /* Matrix is - * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | - * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | - * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | - */ - r[0][0] = 1.0f - ySq2 - zSq2; - r[0][1] = xy2 - zw2; - r[0][2] = xz2 + yw2; - - r[1][0] = xy2 + zw2; - r[1][1] = 1.0f - xSq2 - zSq2; - r[1][2] = yz2 - xw2; - - r[2][0] = xz2 - yw2; - r[2][1] = yz2 + xw2; - r[2][2] = 1.0f - xSq2 - ySq2; -} - -void NvQuatIdentity(GLfloat r[4]) -{ - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = 1.0f; -} - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = axis[0] * sina; - r[1] = axis[1] * sina; - r[2] = axis[2] * sina; - r[3] = cosa; -} - -void NvQuatX(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = sina; - r[1] = 0.0f; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatY(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = sina; - r[2] = 0.0f; - r[3] = cosa; -} - -void NvQuatZ(GLfloat r[4], GLfloat radians) -{ - GLfloat cosa = cosf(radians * 0.5f); - GLfloat sina = sinf(radians * 0.5f); - - r[0] = 0.0f; - r[1] = 0.0f; - r[2] = sina; - r[3] = cosa; -} - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatY(h, heading); - NvQuatX(p, pitch); - NvQuatZ(ro, roll); - - NvQuatMult(r, h, p); - NvQuatMult(r, ro, r); -} - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) -{ - GLfloat h[4], p[4], ro[4]; - - NvQuatZ(ro, roll); - NvQuatX(p, pitch); - NvQuatY(h, heading); - - NvQuatMult(r, p, h); - NvQuatMult(r, r, ro); -} - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) -{ - return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; -} - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) -{ - const GLfloat q1x = q1[0]; - const GLfloat q1y = q1[1]; - const GLfloat q1z = q1[2]; - const GLfloat q1w = q1[3]; - const GLfloat q2x = q2[0]; - const GLfloat q2y = q2[1]; - const GLfloat q2z = q2[2]; - const GLfloat q2w = q2[3]; - - r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; - r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; - r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; - r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; -} - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) -{ - GLfloat omt = 1.0f - t; - - if (NvQuatDot(q1, q2) < 0.0f) { - r[0] = -q1[0] * omt + q2[0] * t; - r[1] = -q1[1] * omt + q2[1] * t; - r[2] = -q1[2] * omt + q2[2] * t; - r[3] = -q1[3] * omt + q2[3] * t; - } else { - r[0] = q1[0] * omt + q2[0] * t; - r[1] = q1[1] * omt + q2[1] * t; - r[2] = q1[2] * omt + q2[2] * t; - r[3] = q1[3] * omt + q2[3] * t; - } - - NvQuatNormalize(r, r); -} - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) -{ - GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); - - r[0] = invLength * q[0]; - r[1] = invLength * q[1]; - r[2] = invLength * q[2]; - r[3] = invLength * q[3]; -} diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.h deleted file mode 100644 index 4c65cb9e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_math/nv_quat.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDED_QUAT_H -#define INCLUDED_QUAT_H - -#include -#include -#include - -void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); -void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); - -void NvQuatIdentity(GLfloat r[4]); - -void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); - -void NvQuatX(GLfloat r[4], GLfloat radians); - -void NvQuatY(GLfloat r[4], GLfloat radians); - -void NvQuatZ(GLfloat r[4], GLfloat radians); - -void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); - -GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); - -void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); - -void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_types.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_types.h deleted file mode 100644 index 1d1b0300..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/nv_types.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009-2011 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __INCLUDED_QT3DS_TYPES_H -#define __INCLUDED_QT3DS_TYPES_H - -typedef unsigned char NvU8; // 0 to 255 -typedef unsigned short NvU16; // 0 to 65535 -typedef unsigned int NvU32; // 0 to 4294967295 -typedef unsigned long long NvU64; // 0 to 18446744073709551615 -typedef signed char NvS8; // -128 to 127 -typedef signed short NvS16; // -32768 to 32767 -typedef signed int NvS32; // -2147483648 to 2147483647 -typedef signed long long NvS64; // 2^-63 to 2^63-1 - -// Explicitly sized floats -typedef float NvF32; // IEEE Single Precision (S1E8M23) -typedef double NvF64; // IEEE Double Precision (S1E11M52) - -// Boolean type -#define QT3DS_FALSE 0 -#define QT3DS_TRUE 1 -typedef NvU8 NvBool; - -// Result of sizeof operator -typedef unsigned long NvSize; - -// Type large enough to hold a relative file offset -typedef long NvOffset; - -// Base NULL type. -#define QT3DS_NULL 0 - -// Error related -typedef enum { - NvError_Success = 0, - NvError_NotSupported, - NvError_NotInitialized, - NvError_BadParameter, - NvError_InsufficientMemory, - NvError_NoEntries, - NvError_UnknownError, -} NvError; - -#if 1 // defined(_DEBUG) // !!!!TBD TODO -#define NvAssert(c) -#else -#define NvAssert(c) ((void)((c) ? 0 : (NvHandleAssertion(#c, __FILE__, __LINE__), 0))) -#endif - -// Other standardized typedefs -typedef NvU64 NvUST; // U64 unadjusted system time value - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/qt3ds_launcher_defs.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/qt3ds_launcher_defs.h deleted file mode 100644 index 6577fb4a..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSLibs/qt3ds_launcher_defs.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* TAGRELEASE: public */ - -#ifndef _QT3DSLAUNCHERDEFS_H -#define _QT3DSLAUNCHERDEFS_H - -/* Applications should call kdSetWindowPropertyiv with - * KD_WINDOWPROPERTY_APP_ID_QT3DS as the pname - * and one of the ID's below as the param - * Or else define their own in the range starting with - * KD_APP_ID_USER_BASE_QT3DS - * call must be made _prior_ to window realize - */ - -/* Need to define an NV internal KD property range - defining to a fixed value for now */ -/* But this window property is unused in the current KD spec */ -#define KD_WINDOWPROPERTY_APP_ID_QT3DS 0x1000 - -#define KD_APP_ID_UNKNOWN_QT3DS 0 -#define KD_APP_ID_KEYBOARD_QT3DS 1 /* QT3DS RESERVED */ -#define KD_APP_ID_CONTACTS_QT3DS 2 /* QT3DS RESERVED */ -#define KD_APP_ID_MESSAGING_QT3DS 3 /* QT3DS RESERVED */ -#define KD_APP_ID_EMAIL_QT3DS 4 /* QT3DS RESERVED */ -#define KD_APP_ID_IM_QT3DS 5 /* QT3DS RESERVED */ -#define KD_APP_ID_PHONEDIALER_QT3DS 6 /* QT3DS RESERVED */ -#define KD_APP_ID_GAME_QT3DS 7 -#define KD_APP_ID_ADDRESSBOOK_QT3DS 8 /* Assigned to NV addrbook demo */ -#define KD_APP_ID_MUSICPLAYER_QT3DS 9 /* Assigned to NV mediaplayer demo */ -#define KD_APP_ID_SMS_QT3DS 10 /* QT3DS RESERVED */ -#define KD_APP_ID_IMAGEBROWSER_QT3DS 11 /* Assigned to NV photoviewer demo */ -#define KD_APP_ID_MAP_QT3DS 12 /* QT3DS RESERVED */ -#define KD_APP_ID_HOME_QT3DS 13 /* Assigned to NV launcher_gui home screen */ -#define KD_APP_ID_CALENDAR_QT3DS 14 /* QT3DS RESERVED */ -#define KD_APP_ID_VIDEO_QT3DS 15 /* Assigned to NV videoplayer demo */ -#define KD_APP_ID_WIDGETS_QT3DS 16 /* QT3DS RESERVED */ -#define KD_APP_ID_CAMERA_QT3DS 19 /* QT3DS RESERVED */ -#define KD_APP_ID_MEDIAWALL_QT3DS 20 /* QT3DS RESERVED */ -#define KD_APP_ID_OPERA_QT3DS 21 /* QT3DS RESERVED */ -#define KD_APP_ID_YOUTUBE_QT3DS 22 /* QT3DS RESERVED */ -#define KD_APP_ID_VISION_QT3DS 23 /* QT3DS RESERVED */ -#define KD_APP_ID_USER_BASE_QT3DS 1024 /* Base of app-reserved */ - -/* starting orientation support */ -#define KD_WINDOWPROPERTY_ORIENTATION_QT3DS 0x1001 - -#define KD_WINDOWPROPERTY_STATUSBAR_QT3DS 0x1002 -#define KD_STATUSBAR_HIDEALL_QT3DS 0x0000 -#define KD_STATUSBAR_SHOWBAR_QT3DS 0x0001 -#define KD_STATUSBAR_SHOWBG_QT3DS 0x0002 /* not set as state, just for mask */ -#define KD_STATUSBAR_SHOWALL_QT3DS 0x0003 /* this is showbar+showbg in bits...*/ - -#define KD_WINDOWPROPERTY_PROCESS_ID_QT3DS 0x1003 - -/* App-level KD state - if this exists and is nonzero, then the app is */ -/* Running in the launcher */ - -#define KD_STATE_LAUNCHER_ACTIVE_QT3DS 0x11001 - -/* Part of GL_NV_log_textures extension */ -/* Not currently supported in external release */ -#define GL_LOG_TEXTURES_QT3DS 0x85FF -#define GL_LOG_TEXTURES_ZONE_QT3DS 0x85FE - -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSViewer/Resource.h b/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSViewer/Resource.h deleted file mode 100644 index 58c9336e..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/Qt3DSViewer/Resource.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#define IDI_ICON1 103 -#define IDI_ICON2 105 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.abc b/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.abc deleted file mode 100644 index f7e3c2f6..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.abc and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.dds b/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.dds deleted file mode 100644 index 5bde760b..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_256.dds and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.abc b/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.abc deleted file mode 100644 index 2ff78757..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.abc and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.dds b/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.dds deleted file mode 100644 index f9e76d94..00000000 Binary files a/src/Runtime/Source/PlatformSpecific/Windows/assets/courier+lucida_512.dds and /dev/null differ diff --git a/src/Runtime/Source/PlatformSpecific/Windows/assets/font.frag b/src/Runtime/Source/PlatformSpecific/Windows/assets/font.frag deleted file mode 100644 index e4673cf8..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/assets/font.frag +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -uniform sampler2D fontTex; - -varying lowp vec4 col_var; -varying lowp vec2 tex_var; - -void main() -{ - gl_FragColor = texture2D(fontTex, tex_var).a * col_var; -} - diff --git a/src/Runtime/Source/PlatformSpecific/Windows/assets/font.vert b/src/Runtime/Source/PlatformSpecific/Windows/assets/font.vert deleted file mode 100644 index 9f307a2f..00000000 --- a/src/Runtime/Source/PlatformSpecific/Windows/assets/font.vert +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// this is set from higher level. think of it as the upper model matrix -uniform mat4 pixelToClipMat; - -uniform vec4 col_uni; - -attribute vec2 pos_attr; -attribute vec2 tex_attr; -attribute vec4 col_attr; - -varying vec4 col_var; -varying vec2 tex_var; - -void main() -{ - // account for translation and rotation of the primitive into [-1,1] spatial default. - gl_Position = pixelToClipMat * vec4(pos_attr.x, pos_attr.y, 0, 1); - - col_var = col_attr * col_uni; - tex_var = tex_attr; -} diff --git a/src/Runtime/Source/Qt3DSEvent/Include/EventSystem.h b/src/Runtime/Source/Qt3DSEvent/Include/EventSystem.h deleted file mode 100644 index a9e3dbc5..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Include/EventSystem.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MESSAGE_SYSTEM_H -#define MESSAGE_SYSTEM_H -#include -#include "EventSystemC.h" - -namespace qt3ds { -namespace evt { - - typedef Qt3DSEventSystemStr TEventStr; - - // Factory from the provider's perspective. - class IEventFactory - { - protected: - virtual ~IEventFactory() {} - public: - virtual Qt3DSEventSystemEvent &CreateEvent(int numData) = 0; - // Guaranteed to be at least 4K - sizeof(Qt3DSEventSystemEvent) - virtual size_t GetMaxNumEventData() = 0; - // Guaranteed to be at least 4K - virtual size_t GetMaxStrLength() = 0; - - virtual Qt3DSEventSystemRegisteredStr RegisterStr(TEventStr inSrc) = 0; - // Null terminates if strlen(inSrc) > getMaxStrLength - virtual TEventStr AllocateStr(TEventStr inSrc) = 0; - // Returns null if inLength > getMaxStrLength - virtual TEventStr AllocateStr(int inLength) = 0; - }; - - class IEventProvider - { - protected: - virtual ~IEventProvider() {} - public: - // Return the next N events, placed into the event buffer. - virtual size_t GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, - size_t bufLen) = 0; - virtual void Release() = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSEvent/Include/EventSystemC.h b/src/Runtime/Source/Qt3DSEvent/Include/EventSystemC.h deleted file mode 100644 index 2517eae4..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Include/EventSystemC.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_EVENT_SYSTEM_C_H -#define QT3DS_EVENT_SYSTEM_C_H -#include //size_t - -// Interface we expect plugins to use in order to interace with the event system. -// This interface is design to avoid using c++ vtables and the C++ abi isn't stable -// across compilers. - -#ifdef _cplusplus -extern "C" { -#endif - -// Obnoxious long names to void namespace conflicts -enum QT3DSEventSystemEventTypes { - QT3DSEventSystemEventTypesNoData = 0, - QT3DSEventSystemEventTypesString = 1, - QT3DSEventSystemEventTypesNumber = 2, -}; - -typedef const char *Qt3DSEventSystemStr; - -typedef struct _Qt3DSEventSystemEventValue -{ - QT3DSEventSystemEventTypes m_Type; - double m_Number; - Qt3DSEventSystemStr m_String; -} Qt3DSEventSystemEventValue; - -typedef struct _Qt3DSEventSystemRegisteredStr -{ - Qt3DSEventSystemStr m_Data; -} Qt3DSEventSystemRegisteredStr; - -typedef struct _Qt3DSEventSystemEventData -{ - Qt3DSEventSystemRegisteredStr m_Name; - Qt3DSEventSystemEventValue m_Value; -} Qt3DSEventSystemEventData; - -typedef struct _Qt3DSEventSystemEvent -{ - Qt3DSEventSystemEventData *m_Data; // contiguous block of event data. - int m_NumData; -} Qt3DSEventSystemEvent; - -typedef Qt3DSEventSystemEvent *(*Qt3DSEventSystemEventFactoryCreateEventFn)(void *inFactory, - int numData); -typedef size_t (*Qt3DSEventSystemEventFactoryMaxNumEventDataFn)(void *inFactory); -typedef size_t (*Qt3DSEventSystemEventFactoryMaxStrLenFn)(void *inFactory); -typedef Qt3DSEventSystemRegisteredStr (*Qt3DSEventSystemEventFactoryRegisterStrFn)( - void *inFactory, Qt3DSEventSystemStr inStr); -typedef Qt3DSEventSystemStr (*Qt3DSEventSystemEventFactoryAllocateStrFn)(void *inFactory, - Qt3DSEventSystemStr inStr); -typedef Qt3DSEventSystemStr (*Qt3DSEventSystemEventFactoryAllocateStrLenFn)(void *inFactory, int len); - -// Factory from the provider's perspective. -typedef struct _Qt3DSEventSystemEventFactory -{ - void *m_Factory; - Qt3DSEventSystemEventFactoryCreateEventFn createEvent; - Qt3DSEventSystemEventFactoryMaxNumEventDataFn getMaxNumEventData; - Qt3DSEventSystemEventFactoryMaxStrLenFn getMaxStrLength; - Qt3DSEventSystemEventFactoryRegisterStrFn registerStr; - Qt3DSEventSystemEventFactoryAllocateStrFn allocateStr; - Qt3DSEventSystemEventFactoryAllocateStrLenFn allocateStrLen; - -} Qt3DSEventSystemEventFactory; - -typedef size_t (*Qt3DSEventSystemProviderGetNextEventsFn)(void *inProvider, - Qt3DSEventSystemEventFactory inFactory, - Qt3DSEventSystemEvent **outBuffer, - size_t outBufLen); -typedef void (*Qt3DSEventSystemProviderReleaseFn)(void *inProvider); - -typedef struct _Qt3DSEventSystemEventProvider -{ - void *m_Provider; - Qt3DSEventSystemProviderGetNextEventsFn getNextEvents; - Qt3DSEventSystemProviderReleaseFn release; -} Qt3DSEventSystemEventProvider; - -typedef void (*Qt3DSEventSystemPollerAddProviderFn)(void *inPoller, - Qt3DSEventSystemEventProvider inProvider); -typedef void (*Qt3DSEventSystemPollerRemoveProviderFn)(void *inPoller, - Qt3DSEventSystemEventProvider inProvider); -typedef int (*Qt3DSEventSystemPollerignoreProviderFn)(void *inPoller, - Qt3DSEventSystemEventProvider inProvider); -typedef int (*Qt3DSEventSystemPolleractivateProviderFn)(void *inPoller, - Qt3DSEventSystemEventProvider inProvider); - -typedef struct _Qt3DSEventSystemEventPoller -{ - void *m_Poller; - // Providers, once added, will be released by the event poller unless removed - Qt3DSEventSystemPollerAddProviderFn addProvider; - // Callers are responsible for releasing removed providers. - Qt3DSEventSystemPollerRemoveProviderFn removeProvider; - Qt3DSEventSystemPollerignoreProviderFn ignoreProvider; - Qt3DSEventSystemPolleractivateProviderFn activateProvider; - -} Qt3DSEventSystemEventPoller; - -extern const char *PROVIDER_TABLE_ENTRY; -extern const char *POLLER_TABLE_ENTRY; - -#ifdef _cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSEvent/InternalInclude/EventPollingSystem.h b/src/Runtime/Source/Qt3DSEvent/InternalInclude/EventPollingSystem.h deleted file mode 100644 index 4d414066..00000000 --- a/src/Runtime/Source/Qt3DSEvent/InternalInclude/EventPollingSystem.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVENT_SYSTEM_H -#define EVENT_SYSTEM_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSRefCounted.h" -#include "EventSystem.h" - -namespace qt3ds { -namespace evt { - - class CEventProviderRefCounted; - - class IEventSystem : public qt3ds::foundation::NVRefCounted - { - protected: - virtual ~IEventSystem() {} - public: - // Providers once added are released if the poller goes out of scope. - // Adding the same provider twice has no effect. - virtual void AddProvider(IEventProvider &inProvider) = 0; - - // removeProvider does not release the provider; callers are expected to release the - // provider themselves after calling remove provider. Calling remove provider - // with a provider that isn't in the system has no effect. - virtual void RemoveProvider(IEventProvider &inProvider) = 0; - - // Ignore events from this provider. Returns true if provider is added. - virtual bool IgnoreProvider(IEventProvider &inProvider) = 0; - - // Listen on this provider. Returns true if provider is added. - virtual bool ActivateProvider(IEventProvider &inProvider) = 0; - - // Get a set of events from the poller. The poller will simply run through and ask each - // provider - // for events and then begin returning the set of events. - // Note: this interface needs to set the event fetched flag. - virtual size_t GetNextEvents(Qt3DSEventSystemEvent **outBuffer, size_t bufLen) = 0; - - // Get the event factory used for this poller. - virtual IEventFactory &GetEventFactory() = 0; - - virtual Qt3DSEventSystemEventPoller *GetCInterface() = 0; - - // Get and clear the flag indicates whether GetNextEvents has been called after last call of - // this interface - // Note: the event fetched flag is set by GetNextEvents - virtual bool GetAndClearEventFetchedFlag() = 0; - - // Clear events in event system and events in all providers - virtual void PurgeEvents() = 0; - - static IEventSystem &Create(qt3ds::NVFoundationBase &inFoundation); - }; -} -} - -#endif // EVENT_SYSTEM_H diff --git a/src/Runtime/Source/Qt3DSEvent/Source/EventFactory.cpp b/src/Runtime/Source/Qt3DSEvent/Source/EventFactory.cpp deleted file mode 100644 index 4bf776c6..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Source/EventFactory.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "EventFactory.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/StringTable.h" -#include "foundation/Utils.h" - -using namespace qt3ds::evt; - -typedef char TEventChar; -using qt3ds::QT3DSU32; - -class CInitableRegisteredStr : public Qt3DSEventSystemRegisteredStr -{ -public: - CInitableRegisteredStr(const TEventStr inString) { m_Data = inString; } -}; - -CFactory &CFactory::Create(qt3ds::NVFoundationBase &inFoundation) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), CFactory)(inFoundation); -} - -CFactory::CFactory(qt3ds::NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , m_Allocator(inFoundation.getAllocator(), "event factory allocator") - , m_StringTable(qt3ds::foundation::IStringTable::CreateStringTable(inFoundation.getAllocator())) -{ -} - -CFactory::~CFactory() -{ -} - -Qt3DSEventSystemEvent &CFactory::CreateEvent(int inNumData) -{ - // Ensure num data is in range - inNumData = qt3ds::NVMax(0, inNumData); - // Ensure we can actually allocate something that big - QT3DSU32 dataSize = static_cast( - qt3ds::NVMin((size_t)inNumData * sizeof(Qt3DSEventSystemEventData), - TEventAllocator::getSlabSize() - sizeof(Qt3DSEventSystemEvent))); - // get the actual num data after safety checks. - inNumData = (int)(dataSize / sizeof(Qt3DSEventSystemEventData)); - - QT3DSU32 allocSize = sizeof(Qt3DSEventSystemEvent) + inNumData * sizeof(Qt3DSEventSystemEventData); - - Qt3DSEventSystemEvent *theEvent = (Qt3DSEventSystemEvent *)m_Allocator.allocate( - allocSize, "Event allocation", __FILE__, __LINE__); - theEvent->m_NumData = inNumData; - theEvent->m_Data = reinterpret_cast(((qt3ds::QT3DSU8 *)theEvent) - + sizeof(Qt3DSEventSystemEvent)); - - // Initialize the event data to zero so that a free event won't cause a calamity. - qt3ds::intrinsics::memZero(theEvent->m_Data, dataSize); - - return *theEvent; -} - -size_t CFactory::GetMaxNumEventData() -{ - return m_Allocator.getSlabSize() - sizeof(Qt3DSEventSystemEvent); -} - -size_t CFactory::GetMaxStrLength() -{ - return m_Allocator.getSlabSize(); -} - -void CFactory::ReleaseOutstandingEvents() -{ - m_Allocator.reset(); -} - -Qt3DSEventSystemRegisteredStr CFactory::RegisterStr(TEventStr inSrc) -{ - return CInitableRegisteredStr(m_StringTable->RegisterStr(inSrc)); -} - -TEventStr CFactory::AllocateStr(TEventStr inSrc) -{ - size_t theSizeInByte = sizeof(TEventChar) * (strlen(qt3ds::foundation::nonNull(inSrc)) + 1); - theSizeInByte = qt3ds::NVMin(theSizeInByte, TEventAllocator::getSlabSize()); - - TEventChar *theNewString = (TEventChar *)m_Allocator.allocate( - theSizeInByte, "Qt3DS::evt::CFactory::UnManagedString", __FILE__, __LINE__); - - if (theNewString) - memcpy(theNewString, inSrc, theSizeInByte); - - theNewString[theSizeInByte - 1] = 0; - - return theNewString; -} - -TEventStr CFactory::AllocateStr(int inLength) -{ - ++inLength; - int safeLen = (int)qt3ds::NVMin((size_t)inLength, TEventAllocator::getSlabSize()); - // Either give the users what they ask for or return nothing. - if (safeLen != inLength) - return NULL; - - void *retval = m_Allocator.allocate(inLength * sizeof(TEventChar), - "Qt3DS::evt::CFactory::UnManagedString", __FILE__, __LINE__); - qt3ds::intrinsics::memZero(retval, inLength); - return (TEventStr)retval; -} - -void CFactory::Release() -{ - this->~CFactory(); - QT3DS_FREE(m_Foundation.getAllocator(), this); -} diff --git a/src/Runtime/Source/Qt3DSEvent/Source/EventFactory.h b/src/Runtime/Source/Qt3DSEvent/Source/EventFactory.h deleted file mode 100644 index 10fe6b72..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Source/EventFactory.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVENT_FACTORY_H -#define EVENT_FACTORY_H - -#include "EventSystem.h" -#include "EventPollingSystem.h" - -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/FastAllocator.h" - -namespace qt3ds { -class NVFoundationBase; -namespace foundation { - class IStringTable; -} -} - -namespace qt3ds { -namespace evt { - - class CEventProviderRefCounted; - - class CFactory : public IEventFactory - { - private: - explicit CFactory(qt3ds::NVFoundationBase &inFoundation); - virtual ~CFactory(); - - CFactory &operator=(const CFactory &) { return *this; } - public: - // Interfaces from IEventFactory - Qt3DSEventSystemEvent &CreateEvent(int inNumData) override; - size_t GetMaxNumEventData() override; - size_t GetMaxStrLength() override; - - Qt3DSEventSystemRegisteredStr RegisterStr(TEventStr inSrc) override; - // Null terminates if strlen(inSrc) > getMaxStrLength - TEventStr AllocateStr(TEventStr inSrc) override; - - // Returns null if inLength > getMaxStrLength - TEventStr AllocateStr(int inLength) override; - - void ReleaseOutstandingEvents(); - void Release(); - - static CFactory &Create(qt3ds::NVFoundationBase &inFoundation); - - private: - typedef qt3ds::foundation::SFastAllocator<> TEventAllocator; - - qt3ds::NVFoundationBase &m_Foundation; - TEventAllocator m_Allocator; - qt3ds::foundation::NVScopedRefCounted m_StringTable; - }; -} -} - -#endif // EVENT_FACTORY_H diff --git a/src/Runtime/Source/Qt3DSEvent/Source/EventPoller.cpp b/src/Runtime/Source/Qt3DSEvent/Source/EventPoller.cpp deleted file mode 100644 index a8115953..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Source/EventPoller.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAllocator.h" - -#include "EventPoller.h" -#include "EventFactory.h" - -#define MAX_EVENTS 256 - -using namespace qt3ds::evt; -using qt3ds::QT3DSU32; - -IEventSystem &IEventSystem::Create(qt3ds::NVFoundationBase &inFoundation) -{ - return CPoller::Create(inFoundation); -} - -CPoller &CPoller::Create(qt3ds::NVFoundationBase &inFoundation) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), CPoller)(inFoundation); -} - -CPoller::~CPoller() -{ - for (QT3DSU32 idx = 0, end = m_Providers.size(); idx < end; ++idx) - m_Providers[idx].first->Release(); - m_Providers.clear(); - ReleaseEvents(); - m_EventFactory.Release(); -} - -void CPoller::ReleaseEvents() -{ - m_EventFactory.ReleaseOutstandingEvents(); - - m_EventList.clear(); - m_EventIndex = 0; -} - -static void AddProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) -{ - CPoller *thePoller = reinterpret_cast(inPoller); - thePoller->AddProvider(*thePoller->GetOrCreateEventProviderWrapper(inProvider)); -} - -static void RemoveProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) -{ - CPoller *thePoller = reinterpret_cast(inPoller); - CPoller::TProvider theProvider = thePoller->GetEventProviderWrapper(inProvider); - if (theProvider) - thePoller->RemoveProvider(*theProvider); - thePoller->ReleaseEventProviderWrapper(inProvider); -} - -static int IgnoreProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) -{ - CPoller *thePoller = reinterpret_cast(inPoller); - CPoller::TProvider theProvider = thePoller->GetEventProviderWrapper(inProvider); - if (theProvider) - return thePoller->IgnoreProvider(*theProvider); - return 0; -} - -static int ActivateProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) -{ - CPoller *thePoller = reinterpret_cast(inPoller); - CPoller::TProvider theProvider = thePoller->GetEventProviderWrapper(inProvider); - if (theProvider) - return thePoller->ActivateProvider(*theProvider); - return 0; -} - -CPoller::CPoller(qt3ds::NVFoundationBase &inFoundation) - : mRefCount(0) - , m_Foundation(inFoundation) - , m_EventFactory(CFactory::Create(inFoundation)) - , m_Providers(inFoundation.getAllocator(), "CPoller::m_Providers") - , m_EventList(inFoundation.getAllocator(), "CPoller::m_EventList") - , m_EventIndex(0) - , m_EventFetched(false) -{ - m_CInterface.m_Poller = this; - m_CInterface.addProvider = AddProviderFn; - m_CInterface.removeProvider = RemoveProviderFn; - m_CInterface.ignoreProvider = IgnoreProviderFn; - m_CInterface.activateProvider = ActivateProviderFn; -} - -struct SProviderSearch -{ - IEventProvider *m_Provider; - SProviderSearch(IEventProvider &inProvider) - : m_Provider(&inProvider) - { - } - bool operator()(const eastl::pair &item) - { - return item.first == m_Provider; - } -}; - -void CPoller::AddProvider(IEventProvider &inProvider) -{ - TProviderList::iterator iter = - eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); - if (iter == m_Providers.end()) - m_Providers.push_back(eastl::make_pair(&inProvider, true)); -} - -void CPoller::RemoveProvider(IEventProvider &inProvider) -{ - TProviderList::iterator thePos = - eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); - if (thePos != m_Providers.end()) - m_Providers.erase(thePos); -} - -bool CPoller::IgnoreProvider(IEventProvider &inProvider) -{ - TProviderList::iterator thePos = - eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); - if (thePos != m_Providers.end()) { - thePos->second = false; - return true; - } - return false; -} - -bool CPoller::ActivateProvider(IEventProvider &inProvider) -{ - TProviderList::iterator thePos = - eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); - if (thePos != m_Providers.end()) { - thePos->second = true; - return true; - } - return false; -} - -Qt3DSEventSystemEvent *CPoller::GetNextEvent(bool inAllowResetBuffer) -{ - if (m_EventIndex < m_EventList.size()) { - Qt3DSEventSystemEvent *retval = m_EventList[m_EventIndex]; - ++m_EventIndex; - return retval; - } - if (inAllowResetBuffer) { - ReleaseEvents(); - } - size_t theNewEventCount = 0; - for (QT3DSU32 idx = 0, end = m_Providers.size(); idx < end; ++idx) { - if (m_Providers[idx].second) { - Qt3DSEventSystemEvent *evtBuffer[MAX_EVENTS]; - for (QT3DSU32 numEvents = (QT3DSU32)(m_Providers[idx].first) - ->GetNextEvents(m_EventFactory, evtBuffer, MAX_EVENTS); - numEvents; - numEvents = (QT3DSU32)(m_Providers[idx].first) - ->GetNextEvents(m_EventFactory, evtBuffer, MAX_EVENTS)) { - m_EventList.insert(m_EventList.end(), evtBuffer, evtBuffer + numEvents); - ++theNewEventCount; - } - } - } - if (theNewEventCount) - return GetNextEvent(inAllowResetBuffer); - - return NULL; -} - -size_t CPoller::GetNextEvents(Qt3DSEventSystemEvent **outBuffer, size_t bufLen) -{ - m_EventFetched = true; - size_t bufIdx = 0; - bool theAllowResetBuffer = true; - for (; bufIdx < bufLen; ++bufIdx) { - Qt3DSEventSystemEvent *evt = GetNextEvent(theAllowResetBuffer); - if (!evt) - break; - theAllowResetBuffer = false; - outBuffer[bufIdx] = evt; - } - return bufIdx; -} - -IEventFactory &CPoller::GetEventFactory() -{ - return m_EventFactory; -} - -Qt3DSEventSystemEventPoller *CPoller::GetCInterface() -{ - return &m_CInterface; -} - -bool CPoller::GetAndClearEventFetchedFlag() -{ - bool theOld = m_EventFetched; - m_EventFetched = false; - return theOld; -} - -void CPoller::PurgeEvents() -{ - // Get events from providers and drop, - // so the providers need not to provide an additional interface for clear events - static const size_t EVENTS_NUM_ONCE_CLEAR = 512; - Qt3DSEventSystemEvent *theEvents[EVENTS_NUM_ONCE_CLEAR]; - GetNextEvents(theEvents, EVENTS_NUM_ONCE_CLEAR); - ReleaseEvents(); -} - -void CPoller::addRef() -{ - qt3ds::foundation::atomicIncrement(&mRefCount); -} - -void CPoller::release() -{ - qt3ds::QT3DSI32 value = qt3ds::foundation::atomicDecrement(&mRefCount); - if (value <= 0) { - qt3ds::NVAllocatorCallback &alloc(m_Foundation.getAllocator()); - this->~CPoller(); - QT3DS_FREE(alloc, this); - } -} - -struct SProviderFinder -{ - void *m_Key; - SProviderFinder(void *k) - : m_Key(k) - { - } - bool operator()(const CPoller::TCEventProviderPair &inPair) - { - if (inPair.first == m_Key) - return true; - return false; - } -}; - -static Qt3DSEventSystemEvent *CreateEventFn(void *inFactory, int numData) -{ - IEventFactory *theFactory = reinterpret_cast(inFactory); - return &theFactory->CreateEvent(numData); -} - -static size_t MaxNumEventDataFn(void *inFactory) -{ - IEventFactory *theFactory = reinterpret_cast(inFactory); - return theFactory->GetMaxNumEventData(); -} - -static size_t MaxStrLenFn(void *inFactory) -{ - IEventFactory *theFactory = reinterpret_cast(inFactory); - return theFactory->GetMaxStrLength(); -} - -static Qt3DSEventSystemRegisteredStr RegisterStrFn(void *inFactory, Qt3DSEventSystemStr inStr) -{ - IEventFactory *theFactory = reinterpret_cast(inFactory); - return theFactory->RegisterStr(inStr); -} - -static Qt3DSEventSystemStr AllocateStrFn(void *inFactory, Qt3DSEventSystemStr inStr) -{ - IEventFactory *theFactory = reinterpret_cast(inFactory); - return theFactory->AllocateStr(inStr); -} - -static Qt3DSEventSystemStr AllocateStrLenFn(void *inFactory, int len) -{ - IEventFactory *theFactory = reinterpret_cast(inFactory); - return theFactory->AllocateStr(len); -} - -struct SWrappedProvider : public IEventProvider -{ - Qt3DSEventSystemEventProvider m_Provider; - SWrappedProvider(Qt3DSEventSystemEventProvider prov) - : m_Provider(prov) - { - } - - size_t GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, - size_t bufLen) override - { - if (m_Provider.m_Provider) { - Qt3DSEventSystemEventFactory theFactory; - theFactory.m_Factory = &inFactory; - theFactory.createEvent = CreateEventFn; - theFactory.getMaxNumEventData = MaxNumEventDataFn; - theFactory.getMaxStrLength = MaxStrLenFn; - theFactory.registerStr = RegisterStrFn; - theFactory.allocateStr = AllocateStrFn; - theFactory.allocateStrLen = AllocateStrLenFn; - return m_Provider.getNextEvents(m_Provider.m_Provider, theFactory, outBuffer, bufLen); - } - return 0; - } - - void Release() override - { - if (m_Provider.m_Provider) - m_Provider.release(m_Provider.m_Provider); - delete this; - } -}; - -CPoller::TProvider CPoller::GetEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider) -{ - TCEventProviderList::iterator iter = eastl::find_if( - m_CEventProviders.begin(), m_CEventProviders.end(), SProviderFinder(inProvider.m_Provider)); - if (iter != m_CEventProviders.end()) - return iter->second; - return TProvider(); -} - -CPoller::TProvider CPoller::GetOrCreateEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider) -{ - TCEventProviderList::iterator iter = eastl::find_if( - m_CEventProviders.begin(), m_CEventProviders.end(), SProviderFinder(inProvider.m_Provider)); - if (iter == m_CEventProviders.end()) { - TProvider retval = new SWrappedProvider(inProvider); - m_CEventProviders.push_back(eastl::make_pair(inProvider.m_Provider, retval)); - return retval; - } - return iter->second; -} - -void CPoller::ReleaseEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider) -{ - TCEventProviderList::iterator iter = eastl::find_if( - m_CEventProviders.begin(), m_CEventProviders.end(), SProviderFinder(inProvider.m_Provider)); - if (iter != m_CEventProviders.end()) { - SWrappedProvider &wrappedProvider = static_cast(*iter->second); - wrappedProvider.m_Provider.m_Provider = NULL; - m_CEventProviders.erase( - iter); // deletes the wrapper but does not release the wrapped provider. - } -} diff --git a/src/Runtime/Source/Qt3DSEvent/Source/EventPoller.h b/src/Runtime/Source/Qt3DSEvent/Source/EventPoller.h deleted file mode 100644 index 99ac27d6..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Source/EventPoller.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVENT_POLLER_H -#define EVENT_POLLER_H - -#include - -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSContainers.h" - -#include "EventSystem.h" -#include "EventPollingSystem.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace evt { - - class CFactory; - - class CPoller : public IEventSystem - { - public: - typedef IEventProvider *TProvider; - typedef qt3ds::foundation::nvvector> TProviderList; - typedef qt3ds::foundation::nvvector TEventList; - typedef eastl::pair TCEventProviderPair; - typedef eastl::vector TCEventProviderList; - - private: - explicit CPoller(qt3ds::NVFoundationBase &inFoundation); - virtual ~CPoller(); - - public: - // Providers once added are released if the poller goes out of scope. - void AddProvider(IEventProvider &inProvider) override; - void RemoveProvider(IEventProvider &inProvider) override; - bool IgnoreProvider(IEventProvider &inProvider) override; - bool ActivateProvider(IEventProvider &inProvider) override; - size_t GetNextEvents(Qt3DSEventSystemEvent **outBuffer, size_t bufLen) override; - IEventFactory &GetEventFactory() override; - Qt3DSEventSystemEventPoller *GetCInterface() override; - bool GetAndClearEventFetchedFlag() override; - void PurgeEvents() override; - - void ReleaseEvents(); - - void addRef() override; - void release() override; - - TProvider GetEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider); - TProvider GetOrCreateEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider); - void ReleaseEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider); - - static CPoller &Create(qt3ds::NVFoundationBase &inFoundation); - - private: - Qt3DSEventSystemEvent *GetNextEvent(bool inAllowResetBuffer /* = true*/); - - qt3ds::QT3DSI32 mRefCount; - qt3ds::NVFoundationBase &m_Foundation; - CFactory &m_EventFactory; - TProviderList m_Providers; - TEventList m_EventList; - qt3ds::QT3DSU32 m_EventIndex; - Qt3DSEventSystemEventPoller m_CInterface; - TCEventProviderList m_CEventProviders; - bool m_EventFetched; - }; -} -} - -#endif // EVENT_POLLER_H diff --git a/src/Runtime/Source/Qt3DSEvent/Source/EventSystemC.cpp b/src/Runtime/Source/Qt3DSEvent/Source/EventSystemC.cpp deleted file mode 100644 index 8bfdb81c..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Source/EventSystemC.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "EventSystemC.h" - -const char *PROVIDER_TABLE_ENTRY = "__provider_impl"; -const char *POLLER_TABLE_ENTRY = "__poller_impl"; \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.cpp b/src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.cpp deleted file mode 100644 index dc51e9db..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include "CanProviderDemo.h" - -CCanProviderDemo::CCanProviderDemo() - : m_Frame(0) - , m_LastClock(0) -{ -} - -CCanProviderDemo::~CCanProviderDemo() -{ -} - -unsigned short g_VehicleSpeedData[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 6, 8, 10, 12, 14, 16, - 18, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, - 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 256, 264, - 272, 280, 288, 296, 304, 312, 320, 328, 336, 344, 352, 360, 368, 376, 384, 392, - 400, 408, 416, 424, 432, 440, 448, 456, 462, 468, 474, 480, 486, 492, 498, 504, - 510, 516, 522, 528, 534, 540, 546, 552, 558, 564, 570, 576, 582, 588, 594, 600, - 606, 612, 618, 624, 630, 636, 642, 648, 654, 660, 666, 672, 678, 684, 690, 696, - 702, 708, 714, 720, 726, 732, 738, 744, 750, 756, 762, 768, 774, 780, 786, 792, - 798, 804, 810, 816, 820, 824, 828, 832, 836, 840, 844, 848, 852, 856, 860, 864, - 868, 872, 876, 880, 884, 888, 892, 896, 900, 904, 908, 912, 916, 920, 924, 928, - 932, 936, 940, 944, 948, 952, 956, 960, 964, 968, 972, 976, 980, 984, 988, 992, - 996, 1000, 1004, 1008, 1012, 1016, 1020, 1024, 1028, 1032, 1036, 1040, 1044, 1048, 1052, 1056, - 1054, 1052, 1050, 1048, 1046, 1044, 1042, 1040, 1038, 1036, 1034, 1032, 1030, 1028, 1026, 1024, - 1022, 1020, 1018, 1016, 1014, 1012, 1010, 1008, 1006, 1004, 1002, 1000, 998, 996, 994, 992, - 990, 988, 986, 984, 982, 980, 978, 976, 974, 972, 970, 968, 966, 964, 962, 960, - 958, 956, 954, 952, 950, 948, 946, 944, 942, 940, 938, 936, 934, 932, 930, 928, - 926, 924, 922, 920, 918, 916, 914, 912, 910, 908, 906, 904, 902, 900, 898, 896, - 894, 892, 890, 888, 886, 884, 882, 880, 878, 876, 874, 872, 870, 868, 866, 864, - 862, 860, 858, 856, 854, 852, 850, 848, 846, 844, 842, 840, 838, 836, 834, 832, - 830, 828, 826, 824, 822, 820, 818, 816, 823, 830, 837, 844, 851, 858, 865, 872, - 879, 886, 893, 900, 907, 914, 921, 928, 935, 942, 949, 956, 963, 970, 977, 984, - 991, 998, 1005, 1012, 1019, 1026, 1033, 1040, 1047, 1054, 1061, 1068, 1075, 1082, 1089, 1096, - 1103, 1110, 1117, 1124, 1131, 1138, 1145, 1152, 1159, 1166, 1173, 1180, 1187, 1194, 1201, 1208, - 1215, 1222, 1229, 1236, 1246, 1256, 1266, 1276, 1286, 1296, 1306, 1316, 1326, 1336, 1346, 1356, - 1366, 1376, 1386, 1396, 1406, 1416, 1426, 1436, 1446, 1456, 1466, 1476, 1486, 1496, 1506, 1516, - 1526, 1536, 1546, 1556, 1566, 1576, 1586, 1596, 1606, 1616, 1626, 1636, 1646, 1656, 1666, 1676, - 1686, 1696, 1706, 1716, 1726, 1736, 1746, 1756, 1766, 1776, 1786, 1796, 1806, 1816, 1826, 1836, - 1836, 1836, 1836, 1834, 1832, 1830, 1828, 1826, 1824, 1822, 1820, 1818, 1816, 1814, 1812, 1810, - 1808, 1806, 1804, 1802, 1800, 1798, 1796, 1794, 1792, 1790, 1788, 1786, 1784, 1782, 1780, 1778, - 1776, 1774, 1772, 1770, 1768, 1766, 1764, 1762, 1760, 1758, 1756, 1754, 1752, 1750, 1748, 1746, - 1744, 1742, 1740, 1738, 1736, 1734, 1732, 1730, 1728, 1726, 1724, 1722, 1723, 1724, 1725, 1726, - 1728, 1730, 1732, 1734, 1736, 1738, 1740, 1742, 1744, 1746, 1748, 1750, 1753, 1756, 1759, 1762, - 1765, 1768, 1771, 1774, 1777, 1780, 1783, 1786, 1789, 1792, 1795, 1798, 1801, 1804, 1807, 1810, - 1813, 1816, 1819, 1822, 1825, 1828, 1831, 1834, 1837, 1840, 1843, 1846, 1849, 1852, 1855, 1858, - 1861, 1864, 1867, 1870, 1873, 1876, 1879, 1882, 1885, 1888, 1891, 1894, 1897, 1900, 1903, 1906, - 1909, 1912, 1915, 1918, 1921, 1924, 1927, 1930, 1933, 1936, 1939, 1942, 1945, 1948, 1951, 1954, - 1957, 1960, 1963, 1966, 1969, 1972, 1975, 1978, 1981, 1984, 1987, 1990, 1993, 1996, 1999, 2002, - 2005, 2008, 2011, 2014, 2017, 2020, 2023, 2026, 2029, 2032, 2035, 2038, 2041, 2044, 2047, 2050, - 2053, 2056, 2059, 2062, 2064, 2066, 2068, 2070, 2072, 2074, 2076, 2078, 2080, 2082, 2084, 2086, - 2088, 2090, 2092, 2094, 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, 2112, 2114, 2116, 2118, - 2120, 2122, 2124, 2126, 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, 2144, 2146, 2148, 2150, - 2152, 2154, 2156, 2158, 2160, 2162, 2164, 2166, 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2182, - 2184, 2186, 2188, 2190, 2192, 2194, 2196, 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, 2214, - 2216, 2218, 2220, 2222, 2224, 2226, 2228, 2230, 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, - 2248, 2250, 2252, 2254, 2256, 2258, 2260, 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, - 2280, 2282, 2284, 2286, 2288, 2290, 2292, 2294, 2296, 2298, 2300, 2302, 2301, 2300, 2299, 2298, - 2297, 2296, 2295, 2294, 2293, 2292, 2291, 2290, 2289, 2288, 2287, 2286, 2285, 2284, 2283, 2282, - 2281, 2280, 2279, 2278, 2277, 2276, 2275, 2274, 2273, 2272, 2271, 2270, 2269, 2268, 2267, 2266, - 2265, 2264, 2263, 2262, 2261, 2260, 2259, 2258, 2257, 2256, 2255, 2254, 2253, 2252, 2251, 2250, - 2249, 2248, 2247, 2246, 2245, 2244, 2243, 2242, 2239, 2236, 2233, 2230, 2227, 2224, 2221, 2218, - 2215, 2212, 2209, 2206, 2203, 2200, 2197, 2194, 2191, 2188, 2185, 2182, 2179, 2176, 2173, 2170, - 2167, 2164, 2161, 2158, 2155, 2152, 2149, 2146, 2143, 2140, 2137, 2134, 2131, 2128, 2125, 2122, - 2119, 2116, 2113, 2110, 2107, 2104, 2101, 2098, 2095, 2092, 2089, 2086, 2083, 2080, 2077, 2074, - 2071, 2068, 2065, 2062, 2058, 2054, 2050, 2046, 2042, 2038, 2034, 2030, 2026, 2022, 2018, 2014, - 2010, 2006, 2001, 1996, 1991, 1986, 1981, 1976, 1971, 1966, 1961, 1956, 1951, 1946, 1941, 1936, - 1931, 1926, 1921, 1916, 1911, 1906, 1901, 1896, 1891, 1886, 1881, 1876, 1871, 1866, 1861, 1856, - 1851, 1846, 1841, 1836, 1831, 1826, 1821, 1816, 1811, 1806, 1801, 1796, 1791, 1786, 1781, 1776, - 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, - 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, - 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, - 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1779, 1782, 1785, 1788, - 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, 1827, 1830, 1833, 1836, - 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, - 1887, 1890, 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, - 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1958, 1960, 1962, 1964, 1966, 1968, 1970, 1972, - 1974, 1976, 1978, 1980, 1982, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2004, - 2006, 2008, 2010, 2012, 2014, 2016, 2018, 2020, 2022, 2024, 2026, 2028, 2030, 2032, 2034, 2036, - 2038, 2040, 2042, 2044, 2046, 2048, 2050, 2052, 2054, 2056, 2058, 2060, 2062, 2064, 2066, 2068, - 2070, 2072, 2074, 2076, 2078, 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, 2096, 2098, 2100, - 2102, 2104, 2106, 2108, 2110, 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, 2128, 2130, 2132, - 2134, 2136, 2138, 2140, 2142, 2144, 2146, 2148, 2150, 2152, 2154, 2156, 2158, 2160, 2162, 2164, - 2166, 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2182, 2184, 2186, 2188, 2190, 2192, 2194, 2196, - 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, 2214, 2216, 2218, 2220, 2222, 2224, 2226, 2228, - 2230, 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, 2248, 2250, 2252, 2254, 2256, 2258, 2260, - 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, 2280, 2282, 2284, 2286, 2288, 2290, 2292, - 2294, 2296, 2298, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, - 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, - 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, - 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, - 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2366, 2364, 2362, 2360, 2358, 2356, 2354, 2352, - 2350, 2348, 2346, 2344, 2342, 2340, 2338, 2336, 2334, 2332, 2330, 2328, 2326, 2324, 2322, 2320, - 2318, 2316, 2314, 2312, 2310, 2308, 2306, 2304, 2302, 2300, 2298, 2296, 2294, 2292, 2290, 2288, - 2286, 2284, 2282, 2280, 2278, 2276, 2274, 2272, 2270, 2268, 2266, 2264, 2262, 2260, 2258, 2256, - 2254, 2252, 2250, 2248, 2240, 2230, 2220, 2210, 2200, 2190, 2180, 2170, 2160, 2150, 2140, 2130, - 2120, 2110, 2100, 2090, 2080, 2070, 2060, 2050, 2040, 2030, 2020, 2010, 2000, 1990, 1980, 1970, - 1960, 1950, 1940, 1930, 1920, 1910, 1900, 1890, 1880, 1870, 1860, 1850, 1840, 1830, 1820, 1810, - 1800, 1790, 1780, 1770, 1760, 1750, 1740, 1730, 1720, 1710, 1700, 1690, 1680, 1670, 1660, 1650, - 1645, 1640, 1635, 1630, 1625, 1620, 1615, 1610, 1605, 1600, 1595, 1590, 1585, 1580, 1575, 1570, - 1565, 1560, 1555, 1550, 1545, 1540, 1535, 1530, 1525, 1520, 1515, 1510, 1505, 1500, 1495, 1490, - 1485, 1480, 1475, 1470, 1465, 1460, 1455, 1450, 1445, 1440, 1435, 1430, 1425, 1420, 1415, 1410, - 1405, 1400, 1395, 1390, 1385, 1380, 1375, 1370, 1365, 1360, 1355, 1350, 1345, 1340, 1335, 1330, - 1325, 1320, 1315, 1310, 1305, 1300, 1295, 1290, 1285, 1280, 1275, 1270, 1265, 1260, 1255, 1250, - 1245, 1240, 1235, 1230, 1225, 1220, 1215, 1210, 1205, 1200, 1195, 1190, 1185, 1180, 1175, 1170, - 1165, 1160, 1155, 1150, 1145, 1140, 1135, 1130, 1125, 1120, 1115, 1110, 1105, 1100, 1090, 1088, - 1086, 1084, 1082, 1080, 1078, 1076, 1074, 1072, 1070, 1065, 1060, 1055, 1050, 1045, 1040, 1035, - 1030, 1025, 1020, 1015, 1010, 1005, 1000, 995, 990, 985, 980, 975, 970, 965, 960, 955, - 950, 945, 940, 935, 930, 925, 920, 915, 910, 905, 900, 895, 890, 885, 880, 875, - 870, 865, 860, 855, 850, 845, 840, 835, 830, 825, 820, 815, 810, 805, 800, 795, - 790, 785, 780, 775, 772, 769, 766, 763, 760, 757, 754, 751, 748, 745, 742, 739, - 736, 733, 730, 727, 724, 721, 718, 715, 712, 709, 706, 703, 700, 697, 694, 691, - 688, 685, 682, 679, 676, 673, 670, 667, 664, 661, 658, 655, 652, 649, 646, 643, - 640, 637, 634, 631, 628, 625, 622, 619, 616, 613, 610, 607, 604, 601, 598, 595, - 597, 599, 601, 603, 605, 607, 609, 611, 613, 615, 617, 619, 621, 623, 625, 627, - 629, 631, 633, 635, 637, 639, 641, 643, 645, 647, 649, 651, 653, 655, 657, 659, - 661, 663, 665, 667, 669, 671, 673, 675, 677, 679, 681, 683, 685, 687, 689, 691, - 693, 695, 697, 699, 701, 703, 705, 707, 709, 711, 713, 715, 715, 715, 715, 715, - 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, - 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, - 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, - 715, 715, 715, 715, 715, 715, 715, 715, 710, 705, 700, 695, 690, 685, 680, 675, - 670, 665, 660, 655, 650, 645, 640, 635, 630, 625, 620, 615, 610, 605, 600, 595, - 590, 585, 580, 575, 570, 565, 560, 555, 550, 545, 540, 535, 530, 525, 520, 515, - 510, 505, 500, 495, 490, 485, 480, 475, 470, 465, 460, 455, 450, 445, 440, 435, - 430, 425, 420, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, - 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, 471, - 473, 475, 477, 479, 481, 483, 485, 487, 489, 491, 493, 495, 497, 499, 501, 503, - 505, 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, - 536, 532, 528, 524, 520, 516, 512, 508, 504, 500, 496, 492, 488, 484, 480, 476, - 472, 468, 464, 460, 456, 452, 448, 444, 440, 436, 432, 428, 424, 420, 416, 412, - 408, 404, 400, 396, 392, 388, 384, 380, 376, 372, 368, 364, 360, 356, 352, 348, - 344, 340, 336, 332, 328, 324, 320, 316, 312, 308, 304, 300, 295, 290, 285, 280, - 275, 270, 265, 260, 255, 250, 245, 240, 235, 230, 225, 220, 215, 210, 205, 200, - 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, - 115, 110, 105, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, - 35, 30, 25, 20, 15, 10, 5, 0 -}; - -Qt3DSEventSystemEvent *CCanProviderDemo::GetNextEvent(IEventFactory &inFactory) -{ - clock_t theCurClock = clock(); - if (theCurClock > m_LastClock - && (theCurClock - m_LastClock) / (CLOCKS_PER_SEC / 1000) < 1000 / 6) - return 0; - m_LastClock = theCurClock; - unsigned char theLength = 0; - unsigned char theData[8]; - theData[0] = 81; -#define SIN_SAMPLE(s, m) ((sin((float)s) / 2 + 0.5) * m) - switch (rand() % 2) { - case 0: - theData[1] = 1; - { // Vehicle speed - int theIndex = m_Frame % (sizeof(g_VehicleSpeedData) / sizeof(g_VehicleSpeedData[0])); - theData[2] = (unsigned short)(g_VehicleSpeedData[theIndex] * 0.06) >> 8; - theData[3] = (unsigned char)(g_VehicleSpeedData[theIndex] * 0.06); - } - { - unsigned short theOdo = m_Frame; - theData[4] = theOdo >> 8; - theData[5] = (unsigned char)theOdo; - } - theLength = 6; - break; - case 1: - theData[1] = 2; - { - unsigned short theTrip = m_Frame; - theData[2] = theTrip >> 8; - theData[3] = (unsigned char)theTrip; - } - { - unsigned short theCoolant = (unsigned char)SIN_SAMPLE(m_Frame / 170, 300); - theData[4] = theCoolant >> 8; - theData[5] = (unsigned char)theCoolant; - } - theLength = 6; - break; - default: - return 0; - } - ++m_Frame; - Qt3DSEventSystemEvent &theEvent = inFactory.CreateEvent(9); - Qt3DSEventSystemEventData *theCurrentData = theEvent.m_Data; - theCurrentData->m_Name = inFactory.RegisterStr("device_type"); - theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesString; - theCurrentData->m_Value.m_String = inFactory.AllocateStr("CAN"); - ++theCurrentData; - theCurrentData->m_Name = inFactory.RegisterStr("id"); - theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesNumber; - theCurrentData->m_Value.m_Number = 101; - ++theCurrentData; - theCurrentData->m_Name = inFactory.RegisterStr("length"); - theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesNumber; - theCurrentData->m_Value.m_Number = 6; - ++theCurrentData; - for (int i = 0; i < theLength; ++i) { - theCurrentData->m_Name = inFactory.RegisterStr("data"); - theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesNumber; - theCurrentData->m_Value.m_Number = theData[i]; - ++theCurrentData; - } - - return &theEvent; -} - -size_t CCanProviderDemo::GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, - size_t bufLen) -{ - size_t bufIdx = 0; - Qt3DSEventSystemEvent *evt = NULL; - for (evt = GetNextEvent(inFactory); evt && bufIdx < bufLen; - evt = GetNextEvent(inFactory), ++bufIdx) - outBuffer[bufIdx] = evt; - return bufIdx; -} - -void CCanProviderDemo::Release() -{ - delete this; -} diff --git a/src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.h b/src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.h deleted file mode 100644 index 7d6788bc..00000000 --- a/src/Runtime/Source/Qt3DSEvent/Test/CanProviderDemo.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CAN_PROVIDER_DEMO_H -#define CAN_PROVIDER_DEMO_H - -#include - -#include - -using namespace qt3ds::evt; - -class CCanProviderDemo : public IEventProvider -{ -public: - CCanProviderDemo(); - virtual ~CCanProviderDemo(); - - Qt3DSEventSystemEvent *GetNextEvent(IEventFactory &inFactory); - virtual size_t GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, - size_t bufLen); - virtual void Release(); - -private: - unsigned int m_Frame; - clock_t m_LastClock; -}; - -#endif // CAN_PROVIDER_DEMO_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/AutoDeallocatorAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/AutoDeallocatorAllocator.h deleted file mode 100644 index 5cbbc8bb..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/AutoDeallocatorAllocator.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_FOUNDATION_AUTO_DEALLOCATOR_ALLOCATOR_H -#define QT3DS_FOUNDATION_AUTO_DEALLOCATOR_ALLOCATOR_H -#pragma once - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" - -namespace qt3ds { -namespace foundation { - - using eastl::make_pair; - using eastl::pair; - - struct SSAutoDeallocatorAllocator : public NVAllocatorCallback - { - NVAllocatorCallback &m_Allocator; - nvhash_map m_Allocations; - SSAutoDeallocatorAllocator(NVFoundationBase &inFnd) - : m_Allocator(inFnd.getAllocator()) - , m_Allocations(inFnd.getAllocator(), "SSAutoDeallocatorAllocator::m_Allocations") - { - } - - SSAutoDeallocatorAllocator(NVAllocatorCallback &inAlloc) - : m_Allocator(inAlloc) - , m_Allocations(inAlloc, "SSAutoDeallocatorAllocator::m_Allocations") - { - } - - // Automatically deallocates everything that hasn't already been deallocated. - ~SSAutoDeallocatorAllocator() { deallocateAllAllocations(); } - - void deallocateAllAllocations() - { - for (nvhash_map::iterator iter = m_Allocations.begin(), - end = m_Allocations.end(); - iter != end; ++iter) - m_Allocator.deallocate(iter->first); - m_Allocations.clear(); - } - - void *allocate(size_t size, const char *typeName, const char *filename, int line, - int flags = 0) override - { - void *value = m_Allocator.allocate(size, typeName, filename, line, flags); - m_Allocations.insert(make_pair(value, size)); - return value; - } - - void *allocate(size_t size, const char *typeName, const char *filename, int line, - size_t alignment, size_t alignmentOffset) override - { - void *value = - m_Allocator.allocate(size, typeName, filename, line, alignment, alignmentOffset); - m_Allocations.insert(make_pair(value, size)); - return value; - } - void deallocate(void *ptr) override - { - nvhash_map::iterator iter = m_Allocations.find(ptr); - QT3DS_ASSERT(iter != m_Allocations.end()); - m_Allocator.deallocate(iter->first); - m_Allocations.erase(iter); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/ConvertUTF.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/ConvertUTF.h deleted file mode 100644 index 93614a0c..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/ConvertUTF.h +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Header file. - - Several funtions are included here, forming a complete set of - conversions between the three formats. UTF-7 is not included - here, but is handled in a separate source file. - - Each of these routines takes pointers to input buffers and output - buffers. The input buffers are const. - - Each routine converts the text between *sourceStart and sourceEnd, - putting the result into the buffer between *targetStart and - targetEnd. Note: the end pointers are *after* the last item: e.g. - *(sourceEnd - 1) is the last item. - - The return result indicates whether the conversion was successful, - and if not, whether the problem was in the source or target buffers. - (Only the first encountered problem is indicated.) - - After the conversion, *sourceStart and *targetStart are both - updated to point to the end of last text successfully converted in - the respective buffers. - - Input parameters: - sourceStart - pointer to a pointer to the source buffer. - The contents of this are modified on return so that - it points at the next thing to be converted. - targetStart - similarly, pointer to pointer to the target buffer. - sourceEnd, targetEnd - respectively pointers to the ends of the - two buffers, for overflow checking only. - - These conversion functions take a ConversionFlags argument. When this - flag is set to strict, both irregular sequences and isolated surrogates - will cause an error. When the flag is set to lenient, both irregular - sequences and isolated surrogates are converted. - - Whether the flag is strict or lenient, all illegal sequences will cause - an error return. This includes sequences such as: , , - or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - must check for illegal sequences. - - When the flag is set to lenient, characters over 0x10FFFF are converted - to the replacement character; otherwise (when the flag is set to strict) - they constitute an error. - - Output parameters: - The value "sourceIllegal" is returned from some routines if the input - sequence is malformed. When "sourceIllegal" is returned, the source - value will point to the illegal value that caused the problem. E.g., - in UTF-8 when a sequence is malformed, it points to the start of the - malformed sequence. - - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------- - The following 4 definitions are compiler-specific. - The C standard does not guarantee that wchar_t has at least - 16 bits, so wchar_t is no less portable than unsigned short! - All should be unsigned values to avoid sign extension during - bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned int UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ - -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { strictConversion = 0, lenientConversion } ConversionFlags; - -/* This is for C++ and does no harm in C */ -#ifdef __cplusplus -extern "C" { -#endif - -ConversionResult Q3DSConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, - ConversionFlags flags); - -ConversionResult Q3DSConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, - ConversionFlags flags); - -ConversionResult Q3DSConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, - ConversionFlags flags); - -ConversionResult Q3DSConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, - ConversionFlags flags); - -ConversionResult Q3DSConvertUTF16toUTF32(const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, - ConversionFlags flags); - -ConversionResult Q3DSConvertUTF32toUTF16(const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, - ConversionFlags flags); - -Boolean Q3DSIsLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -#ifdef __cplusplus -} -#endif - -/* --------------------------------------------------------------------- */ diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/FastAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/FastAllocator.h deleted file mode 100644 index c296bcb6..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/FastAllocator.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSContainers.h" - -namespace qt3ds { -namespace foundation { - - /** - * Allocator that allocates slabs of a certain size and objects then - * get allocated from those slabs. This allocator is designed to reset, - * meaning every frame you can call reset and the objects get freed but - * not destructed. This allocator does not call destructors!! - */ - template - struct SFastAllocator : NVAllocatorCallback - { - ForwardingAllocator m_Allocator; - nvvector m_Slabs; - QT3DSU32 m_Offset; - - enum { - SlabSize = slabSize, - }; - - static size_t getSlabSize() { return slabSize; } - - SFastAllocator(NVAllocatorCallback &alloc, const char *memName) - : m_Allocator(alloc, memName) - , m_Slabs(alloc, "SFastAllocator::m_Slabs") - , m_Offset(0) - { - } - - ~SFastAllocator() - { - for (QT3DSU32 idx = 0, end = m_Slabs.size(); idx < end; ++idx) - m_Allocator.deallocate(m_Slabs[idx]); - m_Slabs.clear(); - m_Offset = 0; - } - void *allocate(size_t inSize, const char *inFile, int inLine, int inFlags = 0) - { - (void)inFlags; - if (inSize > slabSize) { - QT3DS_ASSERT(false); - return NULL; - } - QT3DSU32 misalign = m_Offset % alignmentInBytes; - if (misalign) - m_Offset = m_Offset + (alignmentInBytes - misalign); - - QT3DSU32 currentSlab = m_Offset / slabSize; - QT3DSU32 slabOffset = m_Offset % slabSize; - QT3DSU32 amountLeftInSlab = slabSize - slabOffset; - if (inSize > amountLeftInSlab) { - ++currentSlab; - slabOffset = 0; - m_Offset = currentSlab * slabSize; - } - while (currentSlab >= m_Slabs.size()) { - m_Slabs.push_back((QT3DSU8 *)m_Allocator.allocate(slabSize, inFile, inLine)); - } - QT3DSU8 *data = m_Slabs[currentSlab] + slabOffset; - // This would indicate the underlying allocator isn't handing back aligned memory. - QT3DS_ASSERT(reinterpret_cast(data) % alignmentInBytes == 0); - m_Offset += (QT3DSU32)inSize; - return data; - } - void *allocate(size_t size, const char * /*typeName*/, const char *filename, int line, - int flags = 0) override - { - return allocate(size, filename, line, flags); - } - void *allocate(size_t size, const char * /*typeName*/, const char *filename, int line, - size_t alignment, size_t /*alignmentOffset*/) override - { - QT3DS_ASSERT(alignment == alignmentInBytes); - if (alignment == alignmentInBytes) - return allocate(size, filename, line); - return NULL; - } - // only reset works with deallocation - void deallocate(void *) override {} - void reset() { m_Offset = 0; } - }; -} -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/FileTools.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/FileTools.h deleted file mode 100644 index 57455256..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/FileTools.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_FILE_TOOLS_H -#define QT3DS_FOUNDATION_FILE_TOOLS_H - -#include "EASTL/string.h" -#include "EASTL/vector.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/StringTable.h" -#include "foundation/IOStreams.h" -#include - -QT_FORWARD_DECLARE_CLASS(QIODevice) - -namespace qt3ds { -namespace foundation { - - typedef eastl::basic_string TStr; - - class CFileTools - { - public: - // Normalizes all slashes to be windows-like - static void NormalizePath(TStr &ioPath); - static void NormalizePath(eastl::string &ioPath); - - // This is kind of the opposite of the 'NormalizePath' methods above in - // that it forces usage of unix style directory separators rather than - // windows separators. In addition, the path here can be a file path or - // a qrc URL string. This function will eventually be refactored away - // when we've converted to using Qt's file system abstraction throughout - // the code base and use QUrl's throughout instead of raw strings to - // represent resources. - static QString NormalizePathForQtUsage(const QString &path); - - static void CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, - TStr &outString); - static void CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, - eastl::string &outString); - - // inBase and inRelative will get normalized - // This algorithm changes based on the platform. On windows it is not case sensitive, on - // not-windows it is. - static void GetRelativeFromBase(TStr &inBase, TStr &inRelative, TStr &outString); - static void GetRelativeFromBase(eastl::string &inBase, eastl::string &inRelative, - eastl::string &outString); - - // A remapped path is a file path that starts with a '.' or a '/'. GetRelativeFromBase - // *always* - // places a '.' or a '/' at the front of the path, so if you *know* the path came from - // GetRelativeFromBase then you also know this function returns true of GetRelativeFromBase - // actually generated a path that needs CombineBaseAndRelative. - static bool RequiresCombineBaseAndRelative(const char8_t *inPath); - - // Search/replace so that all slashes are unix-like but only on non-windows platforms - // Assumes the incoming path has been normalized - static void ToPlatformPath(TStr &ioPath); - static void ToPlatformPath(eastl::string &ioPath); - - static CRegisteredString RemapPathToBinaryFormat(TStr &inPath, TStr &inPresentationDir, - TStr &ioWorkspaceStr, - IStringTable &inStringTable); - static CRegisteredString RemapPathFromBinaryFormat(CRegisteredString inPath, - const char8_t *inPresDir, - TStr &ioWorkspaceStr, - const CStrTableOrDataRef &inRef, - IStringTable &inStringTable); - // I - static void GetDirectory(eastl::string &ioPath); - static bool DirectoryExists(const char8_t *inPath); - static void GetExtension(const char8_t *inPath, eastl::string &outExt); - static void Split(const char8_t *inPath, eastl::string &outDir, eastl::string &outFileStem, - eastl::string &outExtension); - - // Only implemented for windows. Does not return '.' and '..' special entries - // inPath is mangled in a platform specific way - static void GetDirectoryEntries(const eastl::string &inPath, - eastl::vector &outFiles); - - static bool CreateDir(const eastl::string &inPath, bool inRecurse = true); - - // Given a/b.txt, we will end up with a/dirName/b.txt - static void AppendDirectoryInPathToFile(eastl::string &ioPath, const char8_t *dirName); - static void RemoveLastDirectoryInPathToFile(eastl::string &ioPath); - - static void SetExtension(eastl::string &ioPath, const char8_t *inExt); - - static bool FileExists(const char8_t *inPath); - static eastl::string GetFileOrAssetPath(const char8_t *inPath); - static void SetStreamPosition(QIODevice& device, qint64 inOffset, - qt3ds::foundation::SeekPosition::Enum inEnum); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/IOStreams.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/IOStreams.h deleted file mode 100644 index 855e5209..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/IOStreams.h +++ /dev/null @@ -1,278 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_IO_STREAMS_H -#define QT3DS_FOUNDATION_IO_STREAMS_H - -#include "EABase/eabase.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/TrackingAllocator.h" -#include "foundation/Qt3DSMath.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Utils.h" -#include "foundation/Qt3DSRefCounted.h" - -#include -#include - -namespace qt3ds { -class NVFoundationBase; - -namespace foundation { - - class IOutStream - { - protected: - virtual ~IOutStream() {} - public: - virtual bool Write(NVConstDataRef data) = 0; - void WriteWithLen(NVConstDataRef data) - { - Write(data.size()); - Write(data); - } - template - void Write(const TDataType &type) - { - Write(toU8ConstDataRef(type)); - } - template - void Write(const TDataType *data, QT3DSU32 numItems) - { - Write(toU8ConstDataRef(data, numItems)); - } - void Write(const wchar_t *data) - { - if (data == NULL) - data = L""; - // Write the null character at the end of the string. - // This just makes reading and debugging a lot less error prone. - // at the expense of 2 bytes. - Write(data, (QT3DSU32)StrLen(data) + 1); - } - template - void WriteWithLen(const TDataType *data, QT3DSU32 numItems) - { - WriteWithLen(toU8ConstDataRef(data, numItems)); - } - }; - - class IInStream - { - protected: - virtual ~IInStream() {} - public: - // Semantics are precisely that you return the amount read - virtual QT3DSU32 Read(NVDataRef data) = 0; - - QT3DSU32 SafeRead(NVDataRef data) - { - QT3DSU32 amountRead = Read(data); - QT3DS_ASSERT(amountRead == data.size()); - if (amountRead < data.size()) - intrinsics::memZero(data.begin() + amountRead, data.size() - amountRead); - return amountRead; - } - QT3DSU32 ReadWithLen(NVDataRef data) - { - QT3DSU32 len = 0; - Read(len); - return SafeRead(toDataRef(data.begin(), len)); - } - template - QT3DSU32 Read(TDataType &type) - { - return SafeRead(toU8DataRef(type)); - } - template - QT3DSU32 Read(TDataType *data, QT3DSU32 numItems) - { - return SafeRead(toU8DataRef(data, numItems)); - } - }; - - struct SeekPosition - { - enum Enum { - Unknown, - Begin, - Current, - End, - }; - }; - - class ISeekable - { - protected: - virtual ~ISeekable() {} - public: - virtual void SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) = 0; - virtual QT3DSI64 GetPosition() const = 0; - virtual QT3DSI64 GetLength() const - { - ISeekable &seekable(const_cast(*this)); - QT3DSI64 currentPos(GetPosition()); - seekable.SetPosition(0, SeekPosition::End); - QT3DSI64 retval(GetPosition()); - seekable.SetPosition(currentPos, SeekPosition::Begin); - return retval; - } - }; - - class ISeekableIOStream : public IInStream, public IOutStream, public ISeekable - { - }; - - struct FileOpenFlagValues - { - enum Enum { - Open = 1, // Without this flag, function fails if file exists - Truncate = 1 << 1, // Truncate the file so an immediate close will empty it. - Create = 1 << 2, - Write = 1 << 3, - }; - }; - - typedef NVFlags FileOpenFlags; - - static inline FileOpenFlags FileReadFlags() { return FileOpenFlags(FileOpenFlagValues::Open); } - - static inline FileOpenFlags FileWriteFlags() - { - return FileOpenFlags(FileOpenFlagValues::Create | FileOpenFlagValues::Open - | FileOpenFlagValues::Write | FileOpenFlagValues::Truncate); - } - static inline FileOpenFlags FileAppendFlags() - { - return FileOpenFlags(FileOpenFlagValues::Create | FileOpenFlagValues::Open - | FileOpenFlagValues::Write); - } - - class CFileSeekableIOStream : public ISeekableIOStream - { - protected: - QFile m_File; - - public: - // Enabling append also enables reading from the file while being able to - // write to it. - CFileSeekableIOStream(const char *inFile, FileOpenFlags inFlags); -#ifdef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T - CFileSeekableIOStream(const wchar_t *inFile, FileOpenFlags inFlags); -#endif - - CFileSeekableIOStream(const char16_t *inFile, FileOpenFlags inFlags); - CFileSeekableIOStream(const QString &inFIle, FileOpenFlags inFlags); - virtual ~CFileSeekableIOStream(); - virtual bool IsOpen(); - void SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) override; - QT3DSI64 GetPosition() const override; - QT3DSU32 Read(NVDataRef data) override; - bool Write(NVConstDataRef data) override; - - private: - void openFile(const QString &path, FileOpenFlags inFlags); - }; - - class CMemorySeekableIOStream : public ISeekableIOStream - { - protected: - NVAllocatorCallback &m_Allocator; - const char *m_AllocationName; - QT3DSU8 *m_Data; - QT3DSU32 m_Size; - QT3DSU32 m_Offset; - QT3DSU32 m_Capacity; - - public: - CMemorySeekableIOStream(NVAllocatorCallback &inAlloc, const char *inAllocName); - virtual ~CMemorySeekableIOStream(); - void SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) override; - QT3DSI64 GetPosition() const override { return m_Offset; } - QT3DSI64 GetLength() const override { return m_Size; } - QT3DSU32 Read(NVDataRef data) override; - bool Write(NVConstDataRef data) override; - - // Add in the standard container functions - QT3DSU8 *begin() { return m_Data; } - QT3DSU8 *end() { return m_Data + m_Size; } - const QT3DSU8 *begin() const { return m_Data; } - const QT3DSU8 *end() const { return m_Data + m_Size; } - void clear() - { - m_Offset = 0; - m_Size = 0; - } - QT3DSU32 size() const { return m_Size; } - void reserve(QT3DSU32 inNewSize); - void resize(QT3DSU32 inNewSize) - { - reserve(inNewSize); - m_Size = inNewSize; - } - }; - - // Simple, one way input stream. - struct SMemoryInStream : public IInStream - { - const QT3DSU8 *m_Begin; - const QT3DSU8 *m_End; - SMemoryInStream(const QT3DSU8 *b, const QT3DSU8 *e) - : m_Begin(b) - , m_End(e) - { - } - - QT3DSU32 Read(NVDataRef data) override - { - size_t available = m_End - m_Begin; - size_t requested = data.size(); - size_t amount = NVMin(available, requested); - qt3ds::intrinsics::memCopy(data.mData, m_Begin, (QT3DSU32)amount); - m_Begin += amount; - return (QT3DSU32)amount; - } - }; - - class WriteBufferedOutStream : public IOutStream, public NVRefCounted - { - public: - virtual IOutStream &wrappedStream() = 0; - virtual void flush() = 0; - - static NVScopedRefCounted - Create(NVFoundationBase &fnd, IOutStream &stream, QT3DSU32 totalBufferSize = 128 * 1024); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/LICENSE_CONVERTUTF.TXT b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/LICENSE_CONVERTUTF.TXT deleted file mode 100644 index 254acdfe..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/LICENSE_CONVERTUTF.TXT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright 2001-2004 Unicode, Inc. - -Disclaimer - -This source code is provided as is by Unicode, Inc. No claims are -made as to fitness for any particular purpose. No warranties of any -kind are expressed or implied. The recipient agrees to determine -applicability of information provided. If this file has been -purchased on magnetic or optical media from Unicode, Inc., the -sole remedy for any claim will be exchange of defective media -within 90 days of receipt. - -Limitations on Rights to Redistribute This Code - -Unicode, Inc. hereby grants the right to freely use the information -supplied in this file in the creation of products supporting the -Unicode Standard, and to make copies of this file in any form -for internal or external distribution as long as this notice -remains attached. diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/PoolingAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/PoolingAllocator.h deleted file mode 100644 index 9d939fdc..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/PoolingAllocator.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_FOUNDATION_POOLING_ALLOCATOR_H -#define QT3DS_FOUNDATION_POOLING_ALLOCATOR_H -#pragma once - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "foundation/Qt3DSMutex.h" - -// Pooling allocator. Not designed for small allocations -// starting at 64 bytes and up to 4 K, allocator uses pools. -// Above that, uses default allocator. THis object is absolutely not threadsafe. -// This addes 8 bytes to each allocation in order to safely track the allocation size. -// There is no strict requirement to deallocate; this allocator automatically deallocates -// anything allocated through it. -namespace qt3ds { -namespace foundation { - struct SPoolingAllocator : public NVAllocatorCallback - { - typedef Mutex TMutexType; - typedef Mutex::ScopedLock TLockType; - - NVAllocatorCallback &m_Allocator; - TMutexType m_Mutex; - - struct SAllocationTag - { - QT3DSU32 m_Tag; - size_t m_Size; - SAllocationTag(size_t inSize = 0) - : m_Tag(0xAB5534CD) - , m_Size(inSize) - { - } - }; - - template - struct SPoolObj - { - QT3DSU32 m_Buffer[TObjSize / 4]; - SPoolObj() {} - }; -#define ITERATE_POOLING_ALLOCATOR_POOL_SIZES \ - HANDLE_POOLING_ALLOCATOR_POOL_SIZE(64) \ - HANDLE_POOLING_ALLOCATOR_POOL_SIZE(128) \ - HANDLE_POOLING_ALLOCATOR_POOL_SIZE(256) \ - HANDLE_POOLING_ALLOCATOR_POOL_SIZE(512) \ - HANDLE_POOLING_ALLOCATOR_POOL_SIZE(1024) - -#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ - Pool, ForwardingAllocator, 4> m_Pool##sz; - ITERATE_POOLING_ALLOCATOR_POOL_SIZES -#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE - - SSAutoDeallocatorAllocator m_LargeAllocator; - -#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ - , m_Pool##sz(ForwardingAllocator(inAllocator, "PoolingAllocatorPool")) - - SPoolingAllocator(NVAllocatorCallback &inAllocator) - : m_Allocator(inAllocator) - , m_Mutex(inAllocator) ITERATE_POOLING_ALLOCATOR_POOL_SIZES - , m_LargeAllocator(inAllocator) - { - } -#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE - - void *doAllocateFromPool(size_t size) - { - TLockType locker(m_Mutex); - -#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ - if (size <= sz) \ - return m_Pool##sz.allocate(__FILE__, __LINE__); - ITERATE_POOLING_ALLOCATOR_POOL_SIZES -#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE - - return m_LargeAllocator.allocate(size, "largetype", __FILE__, __LINE__, 0); - } - - void *doAllocate(size_t size) - { - size += sizeof(SAllocationTag); - SAllocationTag *tag = reinterpret_cast(doAllocateFromPool(size)); - new (tag) SAllocationTag(size); - QT3DSU8 *data = reinterpret_cast(tag); - return data + sizeof(SAllocationTag); - } - - void *allocate(size_t size, const char * /*typeName*/, const char * /*filename*/, - int /*line*/, int /*flags*/ = 0) override - { - return doAllocate(size); - } - - void *allocate(size_t size, const char * /*typeName*/, const char * /*filename*/, - int /*line*/, size_t /*alignment*/, size_t /*alignmentOffset*/) override - { - return doAllocate(size); - } - - /** - \brief Frees memory previously allocated by allocate(). - - Threading: This function should be thread safe as it can be called in the context of - the user thread - and physics processing thread(s). - - \param ptr Memory to free. - */ - void deallocate(void *ptr) override - { - TLockType locker(m_Mutex); - - // Deallocate on null is fine. - if (ptr == NULL) - return; - - SAllocationTag tempTag; - QT3DSU8 *dataPtr = reinterpret_cast(ptr); - SAllocationTag *theTag = - reinterpret_cast(dataPtr - sizeof(SAllocationTag)); - if (theTag->m_Tag != tempTag.m_Tag) { - QT3DS_ASSERT(false); - return; - } - - size_t size = theTag->m_Size; - - // We add this offset at allocation time - ptr = dataPtr - sizeof(SAllocationTag); - -#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ - if (size <= sz) { \ - m_Pool##sz.deallocate(ptr); \ - return; \ - } - ITERATE_POOLING_ALLOCATOR_POOL_SIZES -#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE - m_LargeAllocator.deallocate(ptr); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/PreAllocatedAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/PreAllocatedAllocator.h deleted file mode 100644 index aea03577..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/PreAllocatedAllocator.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_RENDER_PRE_ALLOCATED_ALLOCATOR_H -#define QT3DS_RENDER_PRE_ALLOCATED_ALLOCATOR_H -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace foundation { - - // Ignores deallocate calls if they originate withing the pre-allocation block - struct SPreAllocatedAllocator : public NVAllocatorCallback - { - NVAllocatorCallback &m_Allocator; - NVDataRef m_PreAllocatedBlock; - bool m_OwnsMemory; // then we attempt to deallocate on destruction - - SPreAllocatedAllocator(NVAllocatorCallback &inAllocator) - : m_Allocator(inAllocator) - , m_OwnsMemory(false) - { - } - - SPreAllocatedAllocator(NVAllocatorCallback &inAllocator, NVDataRef inData, - bool inOwnsMemory) - : m_Allocator(inAllocator) - , m_PreAllocatedBlock(inData) - , m_OwnsMemory(inOwnsMemory) - { - } - - virtual ~SPreAllocatedAllocator() - { - if (m_OwnsMemory) - m_Allocator.deallocate(m_PreAllocatedBlock.begin()); - } - - void *allocate(size_t size, const char *typeName, const char *filename, int line, - int flags = 0) override - { - return m_Allocator.allocate(size, typeName, filename, line, flags); - } - - void *allocate(size_t size, const char *typeName, const char *filename, int line, - size_t alignment, size_t alignmentOffset) override - { - return m_Allocator.allocate(size, typeName, filename, line, alignment, alignmentOffset); - } - - void deallocate(void *ptr) override - { - if (!ptr) - return; - if (ptr < m_PreAllocatedBlock.begin() || ptr >= m_PreAllocatedBlock.end()) - m_Allocator.deallocate(ptr); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DS.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DS.h deleted file mode 100644 index 041923c3..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DS.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_H -#define QT3DS_H -#include "EABase/eabase.h" -#include "foundation/Qt3DSPreprocessor.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSAssert.h" - -namespace eastl { -} - -namespace qt3ds { -class NVEmpty -{ -}; -class QT3DSMat33; -class QT3DSMat44; -class QT3DSVec2; -class QT3DSVec3; -class QT3DSVec4; -class NVTransform; - -#if !defined QT3DS_DONT_PRAGMA_WARNINGS && defined EA_COMPILER_MSVC -#pragma warning(disable : 4512) // assignment operator not generated -#endif - -#define QT3DS_SIGN_BITMASK 0x80000000 -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocator.h deleted file mode 100644 index cdbbe5f9..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocator.h +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSALLOCATOR_H -#define QT3DS_FOUNDATION_PSALLOCATOR_H - -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" - -#if (defined(QT3DS_WINDOWS) | defined(QT3DS_X360)) -#include -#endif -#if (defined(QT3DS_APPLE)) -#include -#endif - -#include - -// Allocation macros going through user allocator -#define QT3DS_ALLOC(alloc, n, name) alloc.allocate(n, name, __FILE__, __LINE__) -#define QT3DS_ALLOC_TEMP(alloc, n, name) QT3DS_ALLOC(n, name) -#define QT3DS_FREE(alloc, x) alloc.deallocate(x) -#define QT3DS_FREE_AND_RESET(x) \ -{ \ - QT3DS_FREE(x); \ - x = 0; \ - } - -// The following macros support plain-old-types and classes derived from UserAllocated. -#define QT3DS_NEW(alloc, T) new (QT3DS_ALLOC(alloc, sizeof(T), #T)) T -#define QT3DS_NEW_TEMP(alloc, T) QT3DS_NEW(alloc, T) -#define QT3DS_DELETE_POD(x) \ -{ \ - QT3DS_FREE(x); \ - x = 0; \ - } - -namespace qt3ds { -namespace foundation { -template -inline void NVDelete(NVAllocatorCallback &alloc, TObjType *item) -{ - if (item) { - item->~TObjType(); - alloc.deallocate(item); - } -} -} -} - -//! placement new macro to make it easy to spot bad use of 'new' -#define QT3DS_PLACEMENT_NEW(p, T) new (p) T - -// Don't use inline for alloca !!! -#ifdef QT3DS_WINDOWS -#include -#define NVAlloca(x) _alloca(x) -#elif defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_QNX) -#if defined(__INTEGRITY) -#include -#else -#include -#endif -#define NVAlloca(x) alloca(x) -#elif defined(QT3DS_PSP2) -#include -#define NVAlloca(x) alloca(x) -#elif defined(QT3DS_APPLE) -#include -#include -#define NVAlloca(x) alloca(x) -#elif defined(QT3DS_PS3) -#include -#define NVAlloca(x) alloca(x) -#elif defined(QT3DS_X360) -#include -#define NVAlloca(x) _alloca(x) -#elif defined(QT3DS_WII) -#include -#define NVAlloca(x) alloca(x) -#endif - -namespace qt3ds { -namespace foundation { -/* - * Bootstrap allocator using malloc/free. - * Don't use unless your objects get allocated before foundation is initialized. - */ -class RawAllocator -{ -public: - RawAllocator(const char * = 0) {} - void *allocate(size_t size, const char *, int) - { -#if defined(QT3DS_APPLE) - // malloc returns valid pointer for size==0, no need to check - return malloc(size); -#else - // malloc returns valid pointer for size==0, no need to check - return ::malloc(size); -#endif - } - void deallocate(void *ptr) - { -#if defined(QT3DS_APPLE) - free(ptr); -#else - // free(0) is guaranteed to have no side effect, no need to check - ::free(ptr); -#endif - } -}; - -struct ForwardingAllocator -{ - NVAllocatorCallback *mAllocator; - const char *mTypeName; - ForwardingAllocator(const char *typeName) - : mTypeName(typeName) - { - } - ForwardingAllocator(NVAllocatorCallback &alloc, const char *typeName) - : mAllocator(&alloc) - , mTypeName(typeName) - { - } - ForwardingAllocator(NVAllocatorCallback *alloc = NULL) - : mAllocator(alloc) - , mTypeName("__error__") - { - QT3DS_ASSERT(false); - } - ForwardingAllocator(const ForwardingAllocator &other) - : mAllocator(other.mAllocator) - , mTypeName(other.mTypeName) - { - } - ForwardingAllocator &operator=(const ForwardingAllocator &other) - { - mAllocator = other.mAllocator; - mTypeName = other.mTypeName; - return *this; - } - bool operator==(const ForwardingAllocator &other) const - { - return mAllocator == other.mAllocator; - } - NVAllocatorCallback &getAllocator() { return *mAllocator; } - // flags are unused - void *allocate(size_t size, const char *filename, int line, int flags = 0) - { - return getAllocator().allocate(size, mTypeName, filename, line, flags); - } - void *allocate(size_t size, const char *filename, int line, size_t alignment, - size_t alignmentOffset) - { - return getAllocator().allocate(size, mTypeName, filename, line, alignment, - alignmentOffset); - } - void deallocate(void *ptr, size_t) { getAllocator().deallocate(ptr); } - void deallocate(void *ptr) { getAllocator().deallocate(ptr); } -}; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocatorCallback.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocatorCallback.h deleted file mode 100644 index ebbf8198..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAllocatorCallback.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_ALLOCATOR_CALLBACK_H -#define QT3DS_FOUNDATION_QT3DS_ALLOCATOR_CALLBACK_H - -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DS.h" -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/** -\brief Abstract base class for an application defined memory allocator that can be used by the NV -library. - -\note The SDK state should not be modified from within any allocation/free function. - -Threading: All methods of this class should be thread safe as it can be called from the user -thread -or the physics processing thread(s). -*/ - -class NVAllocatorCallback -{ -public: - /** - \brief destructor - */ - virtual ~NVAllocatorCallback() {} - - /** - \brief Allocates size bytes of memory, which must be 16-byte aligned. - - This method should never return NULL. If you run out of memory, then - you should terminate the app or take some other appropriate action. - - Threading: This function should be thread safe as it can be called in the context of the - user thread - and physics processing thread(s). - - \param size Number of bytes to allocate. - \param typeName Name of the datatype that is being allocated - \param filename The source file which allocated the memory - \param line The source line which allocated the memory - \return The allocated block of memory. - */ - virtual void *allocate(size_t size, const char *typeName, const char *filename, int line, - int flags = 0) = 0; - virtual void *allocate(size_t size, const char *typeName, const char *filename, int line, - size_t alignment, size_t alignmentOffset) = 0; - - /** - \brief Frees memory previously allocated by allocate(). - - Threading: This function should be thread safe as it can be called in the context of the - user thread - and physics processing thread(s). - - \param ptr Memory to free. - */ - virtual void deallocate(void *ptr) = 0; -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAssert.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAssert.h deleted file mode 100644 index a628159f..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAssert.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_ASSERT_H -#define QT3DS_ASSERT_H -#include "foundation/Qt3DSPreprocessor.h" - -// Force the user to define the Qt3DSAssert function -namespace qt3ds { -void Qt3DSAssert(const char *exp, const char *file, int line, bool *ignore); -} - -#ifdef __CUDACC__ -#define QT3DS_ASSERT(exp) ((void)0) -#define QT3DS_ALWAYS_ASSERT_MESSAGE(exp) ((void)0) -#else // __CUDACC__ -#ifndef NDEBUG -#define QT3DS_ASSERT(exp) \ - { \ - static bool ignore = false; \ - (void)((!!(exp)) || (qt3ds::Qt3DSAssert(#exp, __FILE__, __LINE__, &ignore), false)); \ - } -#else // NDEBUG -#define QT3DS_ASSERT(exp) ((void)0) -#endif // NDEBUG -#define QT3DS_ALWAYS_ASSERT_MESSAGE(exp) \ - { \ - static bool ignore = false; \ - (void)((qt3ds::Qt3DSAssert(exp, __FILE__, __LINE__, &ignore), false)); \ - } -#endif // __CUDACC__ - -#define QT3DS_ALWAYS_ASSERT() QT3DS_ASSERT(0) - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAtomic.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAtomic.h deleted file mode 100644 index 69c7d3b4..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSAtomic.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSATOMIC_H -#define QT3DS_FOUNDATION_PSATOMIC_H - -#include "foundation/Qt3DS.h" - -namespace qt3ds { -namespace foundation { - /* set *dest equal to val. Return the old value of *dest */ - QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicExchange(volatile QT3DSI32 *dest, QT3DSI32 val); - - /* if *dest == comp, replace with exch. Return original value of *dest */ - QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp); - - /* if *dest == comp, replace with exch. Return original value of *dest */ - QT3DS_AUTOTEST_EXPORT void *atomicCompareExchangePointer(volatile void **dest, void *exch, - void *comp); - - /* increment the specified location. Return the incremented value */ - QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicIncrement(volatile QT3DSI32 *val); - - /* decrement the specified location. Return the decremented value */ - QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicDecrement(volatile QT3DSI32 *val); - - /* add delta to *val. Return the new value */ - QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta); - - /* compute the maximum of dest and val. Return the new value */ - QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2); - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBasicTemplates.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBasicTemplates.h deleted file mode 100644 index f14c7b32..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBasicTemplates.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSBASICTEMPLATES_H -#define QT3DS_FOUNDATION_PSBASICTEMPLATES_H - -#include "foundation/Qt3DS.h" - -namespace qt3ds { -namespace foundation { - template - struct Equal - { - bool operator()(const A &a, const A &b) const { return a == b; } - }; - - template - struct Less - { - bool operator()(const A &a, const A &b) const { return a < b; } - }; - - template - struct Greater - { - bool operator()(const A &a, const A &b) const { return a > b; } - }; - - template - class Pair - { - public: - F first; - S second; - Pair() - : first(F()) - , second(S()) - { - } - Pair(const F &f, const S &s) - : first(f) - , second(s) - { - } - Pair(const Pair &p) - : first(p.first) - , second(p.second) - { - } - // CN - fix for /.../Qt3DSBasicTemplates.h(61) : warning C4512: 'nv::foundation::Pair' : - // assignment operator could not be generated - Pair &operator=(const Pair &p) - { - first = p.first; - second = p.second; - return *this; - } - bool operator==(const Pair &p) const { return first == p.first && second == p.second; } - }; - - template - struct LogTwo - { - static const unsigned int value = LogTwo<(A >> 1)>::value + 1; - }; - template <> - struct LogTwo<1> - { - static const unsigned int value = 0; - }; - - template - struct UnConst - { - typedef T Type; - }; - template - struct UnConst - { - typedef T Type; - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBounds3.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBounds3.h deleted file mode 100644 index fda4a6d4..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBounds3.h +++ /dev/null @@ -1,443 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_BOUNDS3_H -#define QT3DS_FOUNDATION_QT3DS_BOUNDS3_H - -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSTransform.h" -#include "foundation/Qt3DSMat33.h" -#include "foundation/Qt3DSMat44.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -typedef QT3DSVec3 TNVBounds2BoxPoints[8]; - -/** -\brief Class representing 3D range or axis aligned bounding box. - -Stored as minimum and maximum extent corners. Alternate representation -would be center and dimensions. -May be empty or nonempty. If not empty, minimum <= maximum has to hold. -*/ -class NVBounds3 -{ -public: - /** - \brief Default constructor, not performing any initialization for performance reason. - \remark Use empty() function below to construct empty bounds. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3() {} - - /** - \brief Construct from two bounding points - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3(const QT3DSVec3 &minimum, const QT3DSVec3 &maximum); - - /** - \brief Return empty bounds. - */ - static QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 empty(); - - /** - \brief returns the AABB containing v0 and v1. - \param v0 first point included in the AABB. - \param v1 second point included in the AABB. - */ - static QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 boundsOfPoints(const QT3DSVec3 &v0, - const QT3DSVec3 &v1); - - /** - \brief returns the AABB from center and extents vectors. - \param center Center vector - \param extent Extents vector - */ - static QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 centerExtents(const QT3DSVec3 ¢er, - const QT3DSVec3 &extent); - - /** - \brief Construct from center, extent, and (not necessarily orthogonal) basis - */ - static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 basisExtent(const QT3DSVec3 ¢er, - const QT3DSMat33 &basis, - const QT3DSVec3 &extent); - - /** - \brief Construct from pose and extent - */ - static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 poseExtent(const NVTransform &pose, - const QT3DSVec3 &extent); - - /** - \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB). - \param[in] matrix Transform to apply, can contain scaling as well - \param[in] bounds The bounds to transform. - */ - static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 transform(const QT3DSMat33 &matrix, - const NVBounds3 &bounds); - - /** - \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB). - \param[in] transform Transform to apply, can contain scaling as well - \param[in] bounds The bounds to transform. - */ - static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 transform(const NVTransform &transform, - const NVBounds3 &bounds); - - /** - \brief Sets empty to true - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void setEmpty(); - - /** - \brief Sets infinite bounds - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void setInfinite(); - - /** - \brief expands the volume to include v - \param v Point to expand to. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void include(const QT3DSVec3 &v); - - /** - \brief expands the volume to include b. - \param b Bounds to perform union with. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void include(const NVBounds3 &b); - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isEmpty() const; - - /** - \brief indicates whether the intersection of this and b is empty or not. - \param b Bounds to test for intersection. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool intersects(const NVBounds3 &b) const; - - /** - \brief computes the 1D-intersection between two AABBs, on a given axis. - \param a the other AABB - \param axis the axis (0, 1, 2) - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool intersects1D(const NVBounds3 &a, QT3DSU32 axis) const; - - /** - \brief indicates if these bounds contain v. - \param v Point to test against bounds. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool contains(const QT3DSVec3 &v) const; - - /** - \brief checks a box is inside another box. - \param box the other AABB - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isInside(const NVBounds3 &box) const; - - /** - \brief returns the center of this axis aligned box. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getCenter() const; - - /** - \brief get component of the box's center along a given axis - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float getCenter(QT3DSU32 axis) const; - - /** - \brief get component of the box's extents along a given axis - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float getExtents(QT3DSU32 axis) const; - - /** - \brief returns the dimensions (width/height/depth) of this axis aligned box. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getDimensions() const; - - /** - \brief returns the extents, which are half of the width/height/depth. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getExtents() const; - - /** - \brief scales the AABB. - \param scale Factor to scale AABB by. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void scale(QT3DSF32 scale); - - /** - fattens the AABB in all 3 dimensions by the given distance. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void fatten(NVReal distance); - - /** - checks that the AABB values are not NaN - */ - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite() const; - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void expand(TNVBounds2BoxPoints &outPoints) const; - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void transform(const QT3DSMat44 &inMatrix); - - QT3DSVec3 minimum, maximum; -}; - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3::NVBounds3(const QT3DSVec3 &minimum, const QT3DSVec3 &maximum) - : minimum(minimum) - , maximum(maximum) -{ -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 NVBounds3::empty() -{ - return NVBounds3(QT3DSVec3(QT3DS_MAX_REAL), QT3DSVec3(-QT3DS_MAX_REAL)); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::isFinite() const -{ - return minimum.isFinite() && maximum.isFinite(); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 NVBounds3::boundsOfPoints(const QT3DSVec3 &v0, - const QT3DSVec3 &v1) -{ - return NVBounds3(v0.minimum(v1), v0.maximum(v1)); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 NVBounds3::centerExtents(const QT3DSVec3 ¢er, - const QT3DSVec3 &extent) -{ - return NVBounds3(center - extent, center + extent); -} - -QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::basisExtent(const QT3DSVec3 ¢er, - const QT3DSMat33 &basis, - const QT3DSVec3 &extent) -{ - // extended basis vectors - QT3DSVec3 c0 = basis.column0 * extent.x; - QT3DSVec3 c1 = basis.column1 * extent.y; - QT3DSVec3 c2 = basis.column2 * extent.z; - - QT3DSVec3 w; - // find combination of base vectors that produces max. distance for each component = sum of - // abs() - w.x = NVAbs(c0.x) + NVAbs(c1.x) + NVAbs(c2.x); - w.y = NVAbs(c0.y) + NVAbs(c1.y) + NVAbs(c2.y); - w.z = NVAbs(c0.z) + NVAbs(c1.z) + NVAbs(c2.z); - - return NVBounds3(center - w, center + w); -} - -QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::poseExtent(const NVTransform &pose, - const QT3DSVec3 &extent) -{ - return basisExtent(pose.p, QT3DSMat33(pose.q), extent); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::setEmpty() -{ - minimum = QT3DSVec3(QT3DS_MAX_REAL); - maximum = QT3DSVec3(-QT3DS_MAX_REAL); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::setInfinite() -{ - minimum = QT3DSVec3(-QT3DS_MAX_REAL); - maximum = QT3DSVec3(QT3DS_MAX_REAL); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::include(const QT3DSVec3 &v) -{ - QT3DS_ASSERT(isFinite()); - minimum = minimum.minimum(v); - maximum = maximum.maximum(v); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::include(const NVBounds3 &b) -{ - QT3DS_ASSERT(isFinite()); - minimum = minimum.minimum(b.minimum); - maximum = maximum.maximum(b.maximum); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::isEmpty() const -{ - QT3DS_ASSERT(isFinite()); - // Consistency condition for (Min, Max) boxes: minimum < maximum - return minimum.x > maximum.x || minimum.y > maximum.y || minimum.z > maximum.z; -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::intersects(const NVBounds3 &b) const -{ - QT3DS_ASSERT(isFinite() && b.isFinite()); - return !(b.minimum.x > maximum.x || minimum.x > b.maximum.x || b.minimum.y > maximum.y - || minimum.y > b.maximum.y || b.minimum.z > maximum.z || minimum.z > b.maximum.z); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::intersects1D(const NVBounds3 &a, QT3DSU32 axis) const -{ - QT3DS_ASSERT(isFinite() && a.isFinite()); - return maximum[axis] >= a.minimum[axis] && a.maximum[axis] >= minimum[axis]; -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::contains(const QT3DSVec3 &v) const -{ - QT3DS_ASSERT(isFinite()); - - return !(v.x < minimum.x || v.x > maximum.x || v.y < minimum.y || v.y > maximum.y - || v.z < minimum.z || v.z > maximum.z); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::isInside(const NVBounds3 &box) const -{ - QT3DS_ASSERT(isFinite() && box.isFinite()); - if (box.minimum.x > minimum.x) - return false; - if (box.minimum.y > minimum.y) - return false; - if (box.minimum.z > minimum.z) - return false; - if (box.maximum.x < maximum.x) - return false; - if (box.maximum.y < maximum.y) - return false; - if (box.maximum.z < maximum.z) - return false; - return true; -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 NVBounds3::getCenter() const -{ - QT3DS_ASSERT(isFinite()); - return (minimum + maximum) * NVReal(0.5); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVBounds3::getCenter(QT3DSU32 axis) const -{ - QT3DS_ASSERT(isFinite()); - return (minimum[axis] + maximum[axis]) * NVReal(0.5); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVBounds3::getExtents(QT3DSU32 axis) const -{ - QT3DS_ASSERT(isFinite()); - return (maximum[axis] - minimum[axis]) * NVReal(0.5); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 NVBounds3::getDimensions() const -{ - QT3DS_ASSERT(isFinite()); - return maximum - minimum; -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 NVBounds3::getExtents() const -{ - QT3DS_ASSERT(isFinite()); - return getDimensions() * NVReal(0.5); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::scale(QT3DSF32 scale) -{ - QT3DS_ASSERT(isFinite()); - *this = centerExtents(getCenter(), getExtents() * scale); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::fatten(NVReal distance) -{ - QT3DS_ASSERT(isFinite()); - minimum.x -= distance; - minimum.y -= distance; - minimum.z -= distance; - - maximum.x += distance; - maximum.y += distance; - maximum.z += distance; -} - -QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::transform(const QT3DSMat33 &matrix, - const NVBounds3 &bounds) -{ - QT3DS_ASSERT(bounds.isFinite()); - return bounds.isEmpty() ? bounds : NVBounds3::basisExtent(matrix * bounds.getCenter(), matrix, - bounds.getExtents()); -} - -QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::transform(const NVTransform &transform, - const NVBounds3 &bounds) -{ - QT3DS_ASSERT(bounds.isFinite()); - return bounds.isEmpty() ? bounds - : NVBounds3::basisExtent(transform.transform(bounds.getCenter()), - QT3DSMat33(transform.q), bounds.getExtents()); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::expand(TNVBounds2BoxPoints &outPoints) const -{ - if (isEmpty()) { - for (QT3DSU32 idx = 0; idx < 8; ++idx) - outPoints[idx] = QT3DSVec3(0, 0, 0); - } else { - // Min corner of box - outPoints[0] = QT3DSVec3(minimum[0], minimum[1], minimum[2]); - outPoints[1] = QT3DSVec3(maximum[0], minimum[1], minimum[2]); - outPoints[2] = QT3DSVec3(minimum[0], maximum[1], minimum[2]); - outPoints[3] = QT3DSVec3(minimum[0], minimum[1], maximum[2]); - - // Max corner of box - outPoints[4] = QT3DSVec3(maximum[0], maximum[1], maximum[2]); - outPoints[5] = QT3DSVec3(minimum[0], maximum[1], maximum[2]); - outPoints[6] = QT3DSVec3(maximum[0], minimum[1], maximum[2]); - outPoints[7] = QT3DSVec3(maximum[0], maximum[1], minimum[2]); - } -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::transform(const QT3DSMat44 &inMatrix) -{ - if (!isEmpty()) { - TNVBounds2BoxPoints thePoints; - expand(thePoints); - setEmpty(); - for (QT3DSU32 idx = 0; idx < 8; ++idx) - include(inMatrix.transform(thePoints[idx])); - } -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_BOUNDS3_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBroadcastingAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBroadcastingAllocator.h deleted file mode 100644 index dc6ae7b5..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSBroadcastingAllocator.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_BROADCASTING_ALLOCATOR_H -#define QT3DS_FOUNDATION_QT3DS_BROADCASTING_ALLOCATOR_H - -#include "foundation/Qt3DSAllocatorCallback.h" - -/** \addtogroup foundation - @{ -*/ -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/** -\brief Abstract listener class that listens to allocation and deallocation events from the - foundation memory system. - -Threading: All methods of this class should be thread safe as it can be called from the user -thread -or the physics processing thread(s). -*/ -class NVAllocationListener -{ -protected: - virtual ~NVAllocationListener() {} - -public: - /** - \brief callback when memory is allocated. - \param size Size of the allocation in bytes. - \param typeName Type this data is being allocated for. - \param filename File the allocation came from. - \param line the allocation came from. - \param allocatedMemory memory that will be returned from the allocation. - */ - virtual void onAllocation(size_t size, const char *typeName, const char *filename, int line, - void *allocatedMemory) = 0; - - /** - /brief callback when memory is deallocated. - /param allocatedMemory memory just before allocation. - */ - virtual void onDeallocation(void *allocatedMemory) = 0; -}; - -/** -\brief Abstract base class for an application defined memory allocator that allows an external -listener -to audit the memory allocations. - -Threading: Register/deregister are *not* threadsafe!!! -You need to be sure multiple threads are using this allocator when you are adding -new listeners. -*/ -class NVBroadcastingAllocator : public NVAllocatorCallback -{ -protected: - virtual ~NVBroadcastingAllocator() {} - -public: - /** - \brief Register an allocation listener. This object will be notified whenever an - allocation happens. - - Threading:Not threadsafe if you are allocating and deallocating in another - thread using this allocator. - */ - virtual void registerAllocationListener(NVAllocationListener &inListener) = 0; - /** - \brief Deregister an allocation listener. This object will no longer receive - notifications upon allocation. - - Threading:Not threadsafe if you are allocating and deallocating in another - thread using this allocator. - */ - virtual void deregisterAllocationListener(NVAllocationListener &inListener) = 0; -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_BROADCASTING_ALLOCATOR_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSContainers.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSContainers.h deleted file mode 100644 index de86d856..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSContainers.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_CONTAINERS_H -#define QT3DS_CONTAINERS_H -#include "foundation/Qt3DS.h" -#include "EASTL/vector.h" -#include "EASTL/hash_map.h" -#include "EASTL/hash_set.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace foundation { - - template - class nvvector : public eastl::vector - { - typedef eastl::vector base_type; - - public: - using base_type::data; - using base_type::size; - - nvvector(NVAllocatorCallback &inAllocator, const char *inTypeName) - : eastl::vector(ForwardingAllocator(inAllocator, inTypeName)) - { - } - nvvector(const nvvector &inOther) - : eastl::vector(inOther) - { - } - nvvector &operator=(const nvvector &inOther) - { - eastl::vector::operator=(inOther); - return *this; - } - operator NVConstDataRef() const { return NVConstDataRef(data(), size()); } - operator NVDataRef() { return NVDataRef(data(), size()); } - }; - - template , - typename TPredicate = eastl::equal_to> - class nvhash_map : public eastl::hash_map - { - typedef eastl::hash_map base_type; - - public: - using base_type::find; - using base_type::end; - - nvhash_map(NVAllocatorCallback &inAllocator, const char *inTypeName) - : eastl::hash_map( - ForwardingAllocator(inAllocator, inTypeName)) - { - } - nvhash_map(const nvhash_map &inOther) - : eastl::hash_map(inOther) - { - } - nvhash_map & - operator=(const nvhash_map &inOther) - { - eastl::hash_map::operator=( - inOther); - return *this; - } - bool contains(const TKey &inKey) const { return find(inKey) != end(); } - }; - - template , - typename TPredicate = eastl::equal_to> - class nvhash_set : public eastl::hash_set - { - typedef eastl::hash_set base_type; - - public: - using base_type::find; - using base_type::end; - - nvhash_set(NVAllocatorCallback &inAllocator, const char *inTypeName) - : eastl::hash_set( - ForwardingAllocator(inAllocator, inTypeName)) - { - } - nvhash_set(const nvhash_map &inOther) - : eastl::hash_set(inOther) - { - } - nvhash_set & - operator=(const nvhash_set &inOther) - { - eastl::hash_set::operator=(inOther); - return *this; - } - bool contains(const TKey &inKey) const { return find(inKey) != end(); } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDataRef.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDataRef.h deleted file mode 100644 index ad860cef..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDataRef.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_DATA_REF_H -#define QT3DS_FOUNDATION_DATA_REF_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" - -namespace qt3ds { -namespace foundation { - - template - struct NVConstDataRef - { - const TDataType *mData; - QT3DSU32 mSize; - - NVConstDataRef(const TDataType *inData, QT3DSU32 inSize) - : mData(inData) - , mSize(inSize) - { - } - NVConstDataRef() - : mData(0) - , mSize(0) - { - } - - QT3DSU32 size() const { return mSize; } - - const TDataType *begin() const { return mData; } - const TDataType *end() const { return mData + mSize; } - - const TDataType &operator[](QT3DSU32 index) const - { - QT3DS_ASSERT(index < mSize); - return mData[index]; - } - }; - - template - inline NVConstDataRef toConstDataRef(const TDataType &type) - { - return NVConstDataRef(&type, 1); - } - - template - inline NVConstDataRef toU8ConstDataRef(const TDataType &type) - { - return NVConstDataRef(reinterpret_cast(&type), sizeof(TDataType)); - } - - template - inline NVConstDataRef toConstDataRef(const TDataType *type, QT3DSU32 count) - { - return NVConstDataRef(type, count); - } - - template - inline NVConstDataRef toU8ConstDataRef(const TDataType *type, QT3DSU32 count) - { - return NVConstDataRef(reinterpret_cast(type), - sizeof(TDataType) * count); - } - - template - struct NVDataRef - { - TDataType *mData; - QT3DSU32 mSize; - - NVDataRef(TDataType *inData, QT3DSU32 inSize) - : mData(inData) - , mSize(inSize) - { - } - NVDataRef() - : mData(0) - , mSize(0) - { - } - QT3DSU32 size() const { return mSize; } - - TDataType *begin() { return mData; } - TDataType *end() { return mData + mSize; } - - TDataType *begin() const { return mData; } - TDataType *end() const { return mData + mSize; } - - TDataType &operator[](QT3DSU32 index) - { - QT3DS_ASSERT(index < mSize); - return mData[index]; - } - - const TDataType &operator[](QT3DSU32 index) const - { - QT3DS_ASSERT(index < mSize); - return mData[index]; - } - - operator NVConstDataRef() const - { - return NVConstDataRef(mData, mSize); - } - }; - - template - inline NVDataRef toDataRef(TDataType &type) - { - return NVDataRef(&type, 1); - } - - template - inline NVDataRef toU8DataRef(TDataType &type) - { - return NVDataRef(reinterpret_cast(&type), sizeof(TDataType)); - } - - template - inline NVDataRef toDataRef(TDataType *type, QT3DSU32 count) - { - return NVDataRef(type, count); - } - - template - inline NVDataRef toU8DataRef(TDataType *type, QT3DSU32 count) - { - return NVDataRef(reinterpret_cast(type), sizeof(TDataType) * count); - } -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDiscriminatedUnion.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDiscriminatedUnion.h deleted file mode 100644 index 1957eb23..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSDiscriminatedUnion.h +++ /dev/null @@ -1,335 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_DISCRIMINATED_UNION_H -#define QT3DS_FOUNDATION_DISCRIMINATED_UNION_H -#include "Qt3DSAssert.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSUnionCast.h" - -#ifdef WIN32 -#pragma warning(disable : 4100) -#endif - -namespace qt3ds { -namespace foundation { - - template - class DiscriminatedUnion - { - public: - typedef DiscriminatedUnion TThisType; - typedef TUnionTraits TTraits; - typedef typename TTraits::TIdType TIdType; - - protected: - char m_Data[TBufferSize]; - // Id type must include a no-data type. - TIdType m_DataType; - - public: - DiscriminatedUnion() { TTraits::defaultConstruct(m_Data, m_DataType); } - - DiscriminatedUnion(const TThisType &inOther) - : m_DataType(inOther.m_DataType) - { - TTraits::copyConstruct(m_Data, inOther.m_Data, m_DataType); - } - - template - DiscriminatedUnion(const TDataType &inType) - { - TTraits::copyConstruct(m_Data, m_DataType, inType); - } - - ~DiscriminatedUnion() { TTraits::destruct(m_Data, m_DataType); } - - TThisType &operator=(const TThisType &inType) - { - if (this != &inType) { - TTraits::destruct(m_Data, m_DataType); - m_DataType = inType.m_DataType; - TTraits::copyConstruct(m_Data, inType.m_Data, inType.m_DataType); - } - return *this; - } - - typename TTraits::TIdType getType() const { return m_DataType; } - - template - const TDataType *getDataPtr() const - { - return TTraits::template getDataPtr(m_Data, m_DataType); - } - - template - TDataType *getDataPtr() - { - return TTraits::template getDataPtr(m_Data, m_DataType); - } - - template - TDataType getData() const - { - const TDataType *dataPtr = getDataPtr(); - if (dataPtr) - return *dataPtr; - QT3DS_ASSERT(false); - return TDataType(); - } - - bool operator==(const TThisType &inOther) const - { - return m_DataType == inOther.m_DataType - && TTraits::areEqual(m_Data, inOther.m_Data, m_DataType); - } - - bool operator!=(const TThisType &inOther) const - { - return m_DataType != inOther.m_DataType - || TTraits::areEqual(m_Data, inOther.m_Data, m_DataType) == false; - } - - template - TRetType visit(TVisitorType inVisitor) - { - return TTraits::template visit(m_Data, m_DataType, inVisitor); - } - - template - TRetType visit(TVisitorType inVisitor) const - { - return TTraits::template visit(m_Data, m_DataType, inVisitor); - } - }; - - // Helper system to enable quicker and correct construction of union traits types - - struct CopyConstructVisitor - { - const char *m_Src; - CopyConstructVisitor(const char *inSrc) - : m_Src(inSrc) - { - } - - template - void operator()(TDataType &inDst) - { - new (&inDst) TDataType(*NVUnionCast(m_Src)); - } - void operator()() { QT3DS_ASSERT(false); } - }; - - template - struct DestructTraits - { - void destruct(TDataType &inType) { inType.~TDataType(); } - }; - - // Until compilers improve a bit, you need this for POD types else you get - // unused parameter warnings. - template <> - struct DestructTraits - { - void destruct(QT3DSU8 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSI8 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSU16 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSI16 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSU32 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSI32 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSU64 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSI64 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSF32 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSF64 &) {} - }; - template <> - struct DestructTraits - { - void destruct(bool &) {} - }; - template <> - struct DestructTraits - { - void destruct(void *&) {} - }; -#ifdef __INTEGRITY - template <> - struct DestructTraits - { - void destruct(QT3DSVec2 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSVec3 &) {} - }; -#endif - - struct DestructVisitor - { - template - void operator()(TDataType &inDst) - { - DestructTraits().destruct(inDst); - } - void operator()() { QT3DS_ASSERT(false); } - }; - - template - struct EqualVisitorTraits - { - bool operator()(const TDataType &lhs, const TDataType &rhs) { return lhs == rhs; } - }; - - struct EqualVisitor - { - const char *m_Rhs; - EqualVisitor(const char *rhs) - : m_Rhs(rhs) - { - } - template - bool operator()(const TDataType &lhs) - { - const TDataType &rhs(*NVUnionCast(m_Rhs)); - return EqualVisitorTraits()(lhs, rhs); - } - bool operator()() - { - QT3DS_ASSERT(false); - return true; - } - }; - - template - struct DiscriminatedUnionGenericBase : public TBase - { - typedef typename TBase::TIdType TIdType; - - static void zeroBuf(char *outDst) { qt3ds::intrinsics::memZero(outDst, TBufferSize); } - - static void defaultConstruct(char *outDst, TIdType &outType) - { - zeroBuf(outDst); - outType = TBase::getNoDataId(); - } - - template - static void copyConstruct(char *outDst, TIdType &outType, const TDataType &inSrc) - { - zeroBuf(outDst); - StaticAssert::valid_expression(); - outType = TBase::template getType(); - new (outDst) TDataType(inSrc); - } - - static void copyConstruct(char *inDst, const char *inSrc, TIdType inType) - { - if (inType == TBase::getNoDataId()) - zeroBuf(inDst); - else - TBase::template visit(inDst, inType, CopyConstructVisitor(inSrc)); - } - - static void destruct(char *inDst, TIdType inType) - { - if (inType != TBase::getNoDataId()) - TBase::template visit(inDst, inType, DestructVisitor()); - zeroBuf(inDst); - } - - template - static const TDataType *getDataPtr(const char *inData, const TIdType &inType) - { - if (TBase::template getType() == inType) - return NVUnionCast(inData); - QT3DS_ASSERT(false); - return NULL; - } - - template - static TDataType *getDataPtr(char *inData, const TIdType &inType) - { - if (TBase::template getType() == inType) - return NVUnionCast(inData); - QT3DS_ASSERT(false); - return NULL; - } - - static bool areEqual(const char *inLhs, const char *inRhs, TIdType inType) - { - if (inType != TBase::getNoDataId()) - return TBase::template visit(inLhs, inType, EqualVisitor(inRhs)); - else - return true; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFPU.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFPU.h deleted file mode 100644 index e4a47f0c..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFPU.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSFPU_H -#define QT3DS_FOUNDATION_PSFPU_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSUnionCast.h" - -// unsigned integer representation of a floating-point value. -#ifdef QT3DS_PS3 -QT3DS_FORCE_INLINE unsigned int QT3DS_IR(const float x) -{ - return qt3ds::NVUnionCast(x); -} -#else -#define QT3DS_IR(x) ((QT3DSU32 &)(x)) -#endif - -// signed integer representation of a floating-point value. -#ifdef QT3DS_PS3 -QT3DS_FORCE_INLINE int QT3DS_SIR(const float x) -{ - return qt3ds::NVUnionCast(x); -} -#else -#define QT3DS_SIR(x) ((QT3DSI32 &)(x)) -#endif - -// Floating-point representation of a integer value. -#ifdef QT3DS_PS3 -QT3DS_FORCE_INLINE float QT3DS_FR(const unsigned int x) -{ - return qt3ds::NVUnionCast(x); -} -#else -#define QT3DS_FR(x) ((QT3DSF32 &)(x)) -#endif - -#ifdef QT3DS_PS3 -QT3DS_FORCE_INLINE float *QT3DS_FPTR(unsigned int *x) -{ - return qt3ds::NVUnionCast(x); -} - -QT3DS_FORCE_INLINE float *QT3DS_FPTR(int *x) -{ - return qt3ds::NVUnionCast(x); -} -#else -#define QT3DS_FPTR(x) ((QT3DSF32 *)(x)) -#endif - -#define QT3DS_SIGN_BITMASK 0x80000000 - -namespace qt3ds { -namespace foundation { -class QT3DS_FOUNDATION_API FPUGuard -{ -public: - FPUGuard(); // set fpu control word for PhysX - ~FPUGuard(); // restore fpu control word -private: - QT3DSU32 mControlWords[8]; -}; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFastIPC.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFastIPC.h deleted file mode 100644 index 800c3dfd..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFastIPC.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FAST_IPC_H -#define QT3DS_FAST_IPC_H - -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSIPC.h" - -namespace qt3ds { -namespace foundation { - - NVIPC *createFastIPC( - NVIPC::ErrorCode &errorCode, // error code return if creation fails - NVIPC::ConnectionType connectionType = - NVIPC::CT_CLIENT_OR_SERVER, // how to establish the connection - const char *mappingObject = "Global\\FastIPC", // Name of communications channel - QT3DSU32 serverRingBufferSize = 1024 * 4, // buffer size for outgoing server messages. - QT3DSU32 clientRingBufferSize = 1024 * 4, // buffer size for incoming client messages. - bool allowLongMessages = true, - bool bufferSends = false, - QT3DSU32 maxBufferSendSize = 1024 * 8); // True if we want to buffer sends, if true, then - // pumpSendBuffers should be called by the send thread. - - void releaseFastIPC(NVIPC *f); - -}; // end of namespace -}; // end of namespace - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFlags.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFlags.h deleted file mode 100644 index 765f386f..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFlags.h +++ /dev/null @@ -1,360 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_FLAGS_H -#define QT3DS_FOUNDATION_QT3DS_FLAGS_H - -/** \addtogroup foundation - @{ -*/ - -#include "foundation/Qt3DS.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif -/** -\brief Container for bitfield flag variables associated with a specific enum type. - -This allows for type safe manipulation for bitfields. - -

Example

- // enum that defines each bit... - struct MyEnum - { - enum Enum - { - eMAN = 1, - eBEAR = 2, - ePIG = 4, - }; - }; - - // implements some convenient global operators. - QT3DS_FLAGS_OPERATORS(MyEnum::Enum, QT3DSU8); - - NVFlags myFlags; - myFlags |= MyEnum::eMAN; - myFlags |= MyEnum::eBEAR | MyEnum::ePIG; - if(myFlags & MyEnum::eBEAR) - { - doSomething(); - } -*/ -template -class NVFlags -{ -public: - QT3DS_INLINE explicit NVFlags(const NVEmpty &) {} - QT3DS_INLINE NVFlags(void); - QT3DS_INLINE NVFlags(enumtype e); - QT3DS_INLINE NVFlags(const NVFlags &f); - QT3DS_INLINE explicit NVFlags(storagetype b); - - QT3DS_INLINE bool operator==(enumtype e) const; - QT3DS_INLINE bool operator==(const NVFlags &f) const; - QT3DS_INLINE bool operator==(bool b) const; - QT3DS_INLINE bool operator!=(enumtype e) const; - QT3DS_INLINE bool operator!=(const NVFlags &f) const; - - QT3DS_INLINE NVFlags &operator=(enumtype e); - - QT3DS_INLINE NVFlags &operator|=(enumtype e); - QT3DS_INLINE NVFlags &operator|=(const NVFlags &f); - QT3DS_INLINE NVFlags operator|(enumtype e) const; - QT3DS_INLINE NVFlags - operator|(const NVFlags &f) const; - - QT3DS_INLINE NVFlags &operator&=(enumtype e); - QT3DS_INLINE NVFlags &operator&=(const NVFlags &f); - QT3DS_INLINE NVFlags operator&(enumtype e) const; - QT3DS_INLINE NVFlags - operator&(const NVFlags &f) const; - - QT3DS_INLINE NVFlags &operator^=(enumtype e); - QT3DS_INLINE NVFlags &operator^=(const NVFlags &f); - QT3DS_INLINE NVFlags operator^(enumtype e) const; - QT3DS_INLINE NVFlags - operator^(const NVFlags &f) const; - - QT3DS_INLINE NVFlags operator~(void)const; - - QT3DS_INLINE operator bool(void) const; - QT3DS_INLINE operator QT3DSU8(void) const; - QT3DS_INLINE operator QT3DSU16(void) const; - QT3DS_INLINE operator QT3DSU32(void) const; - - QT3DS_INLINE void clear(enumtype e); - - QT3DS_INLINE void clearOrSet(bool value, enumtype enumVal); - -public: - friend QT3DS_INLINE NVFlags operator&(enumtype a, - NVFlags &b) - { - NVFlags out; - out.mBits = a & b.mBits; - return out; - } - -private: - storagetype mBits; -}; - -#define QT3DS_FLAGS_OPERATORS(enumtype, storagetype) \ - QT3DS_INLINE NVFlags operator|(enumtype a, enumtype b) \ -{ \ - NVFlags r(a); \ - r |= b; \ - return r; \ -} \ - QT3DS_INLINE NVFlags operator&(enumtype a, enumtype b) \ -{ \ - NVFlags r(a); \ - r &= b; \ - return r; \ -} \ - QT3DS_INLINE NVFlags operator~(enumtype a) \ -{ \ - return ~NVFlags(a); \ -} - -template -QT3DS_INLINE NVFlags::NVFlags(void) -{ - mBits = 0; -} - -template -QT3DS_INLINE NVFlags::NVFlags(enumtype e) -{ - mBits = static_cast(e); -} - -template -QT3DS_INLINE NVFlags::NVFlags(const NVFlags &f) -{ - mBits = f.mBits; -} - -template -QT3DS_INLINE NVFlags::NVFlags(storagetype b) -{ - mBits = b; -} - -template -QT3DS_INLINE bool NVFlags::operator==(enumtype e) const -{ - return mBits == static_cast(e); -} - -template -QT3DS_INLINE bool NVFlags:: -operator==(const NVFlags &f) const -{ - return mBits == f.mBits; -} - -template -QT3DS_INLINE bool NVFlags::operator==(bool b) const -{ - return ((bool)*this) == b; -} - -template -QT3DS_INLINE bool NVFlags::operator!=(enumtype e) const -{ - return mBits != static_cast(e); -} - -template -QT3DS_INLINE bool NVFlags:: -operator!=(const NVFlags &f) const -{ - return mBits != f.mBits; -} - -template -QT3DS_INLINE NVFlags &NVFlags::operator=(enumtype e) -{ - mBits = static_cast(e); - return *this; -} - -template -QT3DS_INLINE NVFlags &NVFlags::operator|=(enumtype e) -{ - mBits |= static_cast(e); - return *this; -} - -template -QT3DS_INLINE NVFlags &NVFlags:: -operator|=(const NVFlags &f) -{ - mBits |= f.mBits; - return *this; -} - -template -QT3DS_INLINE NVFlags NVFlags::operator|(enumtype e) const -{ - NVFlags out(*this); - out |= e; - return out; -} - -template -QT3DS_INLINE NVFlags NVFlags:: -operator|(const NVFlags &f) const -{ - NVFlags out(*this); - out |= f; - return out; -} - -template -QT3DS_INLINE NVFlags &NVFlags::operator&=(enumtype e) -{ - mBits &= static_cast(e); - return *this; -} - -template -QT3DS_INLINE NVFlags &NVFlags:: -operator&=(const NVFlags &f) -{ - mBits &= f.mBits; - return *this; -} - -template -QT3DS_INLINE NVFlags NVFlags::operator&(enumtype e) const -{ - NVFlags out = *this; - out.mBits &= static_cast(e); - return out; -} - -template -QT3DS_INLINE NVFlags NVFlags:: -operator&(const NVFlags &f) const -{ - NVFlags out = *this; - out.mBits &= f.mBits; - return out; -} - -template -QT3DS_INLINE NVFlags &NVFlags::operator^=(enumtype e) -{ - mBits ^= static_cast(e); - return *this; -} - -template -QT3DS_INLINE NVFlags &NVFlags:: -operator^=(const NVFlags &f) -{ - mBits ^= f.mBits; - return *this; -} - -template -QT3DS_INLINE NVFlags NVFlags::operator^(enumtype e) const -{ - NVFlags out = *this; - out.mBits ^= static_cast(e); - return out; -} - -template -QT3DS_INLINE NVFlags NVFlags:: -operator^(const NVFlags &f) const -{ - NVFlags out = *this; - out.mBits ^= f.mBits; - return out; -} - -template -QT3DS_INLINE NVFlags NVFlags::operator~(void)const -{ - NVFlags out; - out.mBits = ~mBits; - return out; -} - -template -QT3DS_INLINE NVFlags::operator bool(void) const -{ - return mBits ? true : false; -} - -template -QT3DS_INLINE NVFlags::operator QT3DSU8(void) const -{ - return static_cast(mBits); -} - -template -QT3DS_INLINE NVFlags::operator QT3DSU16(void) const -{ - return static_cast(mBits); -} - -template -QT3DS_INLINE NVFlags::operator QT3DSU32(void) const -{ - return static_cast(mBits); -} - -template -QT3DS_INLINE void NVFlags::clear(enumtype e) -{ - mBits &= ~static_cast(e); -} - -template -QT3DS_INLINE void NVFlags::clearOrSet(bool value, enumtype enumVal) -{ - if (value) - this->operator|=(enumVal); - else - clear(enumVal); -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // #ifndef QT3DS_FOUNDATION_QT3DS_FLAGS_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFoundation.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFoundation.h deleted file mode 100644 index 19065d20..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSFoundation.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_FOUNDATION_H -#define QT3DS_FOUNDATION_QT3DS_FOUNDATION_H - -/** \addtogroup foundation - @{ -*/ - -#include -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSVersionNumber.h" -#include "foundation/Qt3DSLogging.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -class NVAllocatorCallback; -class NVProfilingZone; -class NVBroadcastingAllocator; - -class NVFoundationBase -{ -public: - /** - retrieves the current allocator. - */ - virtual NVBroadcastingAllocator &getAllocator() const = 0; -}; - -namespace foundation { -template -inline void NVDelete(NVFoundationBase &alloc, TObjType *item) -{ - NVDelete(alloc.getAllocator(), item); -} -} - -/** -\brief Foundation SDK singleton class. - -You need to have an instance of this class to instance the higher level SDKs. -*/ -class QT3DS_FOUNDATION_API NVFoundation : public NVFoundationBase -{ -public: - virtual void addRef() = 0; - /** - \brief Destroys the instance it is called on. - - The operation will fail, if there are still modules referencing the foundation object. Release - all dependent modules prior - to calling this method. - - @see NVCreateFoundation() - */ - virtual void release() = 0; - - /** - Retrieves the allocator this object was created with. - */ - virtual NVAllocatorCallback &getAllocatorCallback() const = 0; - -protected: - virtual ~NVFoundation() {} -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** -\brief Creates an instance of the foundation class - -\param version Version number we are expecting (should be QT3DS_FOUNDATION_VERSION) -\param allocator User supplied interface for allocating memory(see #NVAllocatorCallback) -\return Foundation instance on success, NULL if operation failed - -@see NVFoundation -*/ - -#ifdef QT3DS_FOUNDATION_NO_EXPORTS -QT3DS_AUTOTEST_EXPORT -#else -QT3DS_FOUNDATION_API -#endif -qt3ds::NVFoundation *QT3DS_CALL_CONV NVCreateFoundation( - qt3ds::QT3DSU32 version, qt3ds::NVAllocatorCallback &allocator); - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_FOUNDATION_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIPC.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIPC.h deleted file mode 100644 index 9bcea1af..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIPC.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_IPC_H -#define QT3DS_IPC_H - -#include "foundation/Qt3DS.h" - -namespace qt3ds { -namespace foundation { - - class NVIPC - { - public: - enum ConnectionType { - CT_CLIENT, // start up as a client, will succeed even if the server has not yet been - // found. - CT_CLIENT_REQUIRE_SERVER, // start up as a client, but only if the server already - // exists. - CT_SERVER, // will start up as a server, will fail if an existing server is already - // open. - CT_CLIENT_OR_SERVER, // connect as either a client or server, don't care who is created - // first. - CT_LAST - }; - - enum ErrorCode { - EC_OK, // no error. - EC_FAIL, // generic failure. - EC_SERVER_ALREADY_EXISTS, // couldn't create a server, because the server already - // exists. - EC_CLIENT_ALREADY_EXISTS, // couldn't create a client, because an existing client is - // already registered. - EC_CLIENT_SERVER_ALREADY_EXISTS, // both the client and server channels are already used - EC_SERVER_NOT_FOUND, // client opened with a required server, which was not found. - EC_BUFFER_MISSMATCH, // the reserved buffers for client/server do not match up. - EC_MAPFILE_CREATE, // failed to create the shared memory map file. - EC_MAPFILE_VIEW, // failed to map the memory view of he - // communications errors. - EC_SEND_DATA_EXCEEDS_MAX_BUFFER, // trying to send more data than can even fit in the - // sednd buffe. - EC_SEND_DATA_TOO_LARGE, // the data we tried to send exceeds the available room int the - // output ring buffer. - EC_SEND_BUFFER_FULL, // the send buffer is completely full. - EC_SEND_FROM_WRONG_THREAD, // Tried to do a send from a different thread - EC_RECEIVE_FROM_WRONG_THREAD, // Tried to do a recieve from a different thread - EC_NO_RECEIVE_PENDING, // tried to acknowledge a receive but none was pending. - }; - - virtual bool pumpPendingSends(void) = 0; // give up a time slice to pending sends; returns - // true if there are still pends sending. - virtual ErrorCode sendData(const void *data, QT3DSU32 data_len, bool bufferIfFull) = 0; - virtual const void *receiveData(QT3DSU32 &data_len) = 0; - virtual ErrorCode receiveAcknowledge(void) = 0; // acknowledge that we have processed the - // incoming message and can advance the read - // buffer. - - virtual bool isServer(void) const = 0; // returns true if we are opened as a server. - - virtual bool haveConnection(void) const = 0; - - virtual bool canSend(QT3DSU32 len) = 0; // return true if we can send a message of this size. - - virtual void release(void) = 0; - - protected: - virtual ~NVIPC(void){} - }; -}; // end of namespace -}; // end of namespace - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIndexableLinkedList.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIndexableLinkedList.h deleted file mode 100644 index ff36b42a..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIndexableLinkedList.h +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_INDEXABLE_LINKED_LIST_H -#define QT3DS_FOUNDATION_INDEXABLE_LINKED_LIST_H -#include "foundation/Qt3DSPool.h" - -namespace qt3ds { -namespace foundation { - // Set of helper functions for manipulation of lists that are - // somewhat indexable but also amenable to using a pool structure. - template - struct IndexableLinkedList - { - typedef TNodeType SNode; - - typedef Pool TPoolType; - - static TObjType &Create(SNode *&inInitialNode, QT3DSU32 &ioCurrentCount, TPoolType &ioPool) - { - QT3DSU32 idx = ioCurrentCount; - ++ioCurrentCount; - QT3DSU32 numGroups = (ioCurrentCount + TObjCount - 1) / TObjCount; - QT3DSU32 localIdx = idx % TObjCount; - - SNode *theCurrentNode = inInitialNode; - for (QT3DSU32 idx = 0, end = numGroups; idx < end; ++idx) { - if (idx == 0) { - if (theCurrentNode == NULL) - inInitialNode = ioPool.construct(__FILE__, __LINE__); - - theCurrentNode = inInitialNode; - } else { - if (theCurrentNode->m_NextNode == NULL) - theCurrentNode->m_NextNode = ioPool.construct(__FILE__, __LINE__); - theCurrentNode = theCurrentNode->m_NextNode; - } - } - return theCurrentNode->m_Data[localIdx]; - } - - static void CreateAll(SNode *&inInitialNode, QT3DSU32 inCount, TPoolType &ioPool) - { - QT3DSU32 numGroups = (inCount + TObjCount - 1) / TObjCount; - SNode *lastNode = NULL; - for (QT3DSU32 idx = 0, end = numGroups; idx < end; ++idx) { - SNode *nextNode = ioPool.construct(__FILE__, __LINE__); - if (idx == 0) - inInitialNode = nextNode; - else - lastNode->m_NextNode = nextNode; - lastNode = nextNode; - } - } - - static void DeleteList(SNode *&inInitialNode, TPoolType &ioPool) - { - SNode *theNode = inInitialNode; - inInitialNode = NULL; - while (theNode) { - SNode *theNext = theNode->m_NextNode; - theNode->m_NextNode = NULL; - ioPool.deallocate(theNode); - theNode = theNext; - } - } - - // Performs no checking, so you need to have already allocated what you need. - static const TObjType &GetObjAtIdx(const SNode *inInitialNode, QT3DSU32 inIdx) - { - QT3DSU32 groupIdx = inIdx / TObjCount; - QT3DSU32 localIdx = inIdx % TObjCount; - for (QT3DSU32 idx = 0; idx < groupIdx; ++idx) - inInitialNode = inInitialNode->m_NextNode; - return inInitialNode->m_Data[inIdx]; - } - - static TObjType &GetObjAtIdx(SNode *inInitialNode, QT3DSU32 inIdx) - { - QT3DSU32 groupIdx = inIdx / TObjCount; - QT3DSU32 localIdx = inIdx % TObjCount; - for (QT3DSU32 idx = 0; idx < groupIdx; ++idx) - inInitialNode = inInitialNode->m_NextNode; - return inInitialNode->m_Data[localIdx]; - } - - struct SIteratorType - { - QT3DSU32 m_Idx; - QT3DSU32 m_Count; - SNode *m_Node; - - SIteratorType() - : m_Idx(0) - , m_Count(0) - , m_Node(NULL) - { - } - SIteratorType(const SIteratorType &iter) - : m_Idx(iter.m_Idx) - , m_Count(iter.m_Count) - , m_Node(iter.m_Node) - { - } - SIteratorType(SNode *inNode, QT3DSU32 inCount, QT3DSU32 inIdx) - : m_Idx(inIdx) - , m_Count(inCount) - , m_Node(inNode) - { - } - - bool operator==(const SIteratorType &iter) const { return m_Idx == iter.m_Idx; } - - bool operator!=(const SIteratorType &iter) const { return m_Idx != iter.m_Idx; } - - TObjType &operator*() - { - QT3DSU32 localIdx = m_Idx % TObjCount; - return m_Node->m_Data[localIdx]; - } - - SIteratorType &operator++() - { - ++m_Idx; - if ((m_Idx % TObjCount) == 0) - m_Node = m_Node->m_NextNode; - - return *this; - } - }; - - struct SConstIteratorType - { - QT3DSU32 m_Idx; - QT3DSU32 m_Count; - const SNode *m_Node; - - SConstIteratorType() - : m_Idx(0) - , m_Count(0) - , m_Node(NULL) - { - } - SConstIteratorType(const SIteratorType &iter) - : m_Idx(iter.m_Idx) - , m_Count(iter.m_Count) - , m_Node(iter.m_Node) - { - } - SConstIteratorType(const SConstIteratorType &iter) - : m_Idx(iter.m_Idx) - , m_Count(iter.m_Count) - , m_Node(iter.m_Node) - { - } - SConstIteratorType(const SNode *inNode, QT3DSU32 inCount, QT3DSU32 inIdx) - : m_Idx(inIdx) - , m_Count(inCount) - , m_Node(inNode) - { - } - - bool operator==(const SConstIteratorType &iter) const { return m_Idx == iter.m_Idx; } - - bool operator!=(const SConstIteratorType &iter) const { return m_Idx != iter.m_Idx; } - - const TObjType &operator*() - { - QT3DSU32 localIdx = m_Idx % TObjCount; - return m_Node->m_Data[localIdx]; - } - - SConstIteratorType &operator++() - { - ++m_Idx; - if ((m_Idx % TObjCount) == 0) - m_Node = m_Node->m_NextNode; - - return *this; - } - }; - - typedef SIteratorType iterator; - typedef SConstIteratorType const_iterator; - - static iterator begin(SNode *inInitialNode, QT3DSU32 inItemCount) - { - return SIteratorType(inInitialNode, inItemCount, 0); - } - - static iterator end(SNode * /*inInitialNode*/, QT3DSU32 inItemCount) - { - return SIteratorType(NULL, inItemCount, inItemCount); - } - - static const_iterator begin(const SNode *inInitialNode, QT3DSU32 inItemCount) - { - return SConstIteratorType(inInitialNode, inItemCount, 0); - } - - static const_iterator end(const SNode * /*inInitialNode*/, QT3DSU32 inItemCount) - { - return SConstIteratorType(NULL, inItemCount, inItemCount); - } - - struct SNodeIteratorType - { - SNode *m_Node; - - SNodeIteratorType() - : m_Node(NULL) - { - } - SNodeIteratorType(const SNodeIteratorType &iter) - : m_Node(iter.m_Node) - { - } - SNodeIteratorType(SNode *inNode) - : m_Node(inNode) - { - } - - bool operator==(const SNodeIteratorType &iter) const { return m_Node == iter.m_Node; } - - bool operator!=(const SNodeIteratorType &iter) const { return m_Node != iter.m_Node; } - - TNodeType &operator*() { return *m_Node; } - - SNodeIteratorType &operator++() - { - if (m_Node) - m_Node = m_Node->m_NextNode; - - return *this; - } - }; - - typedef SNodeIteratorType node_iterator; - static node_iterator node_begin(SNode *inFirstNode) { return node_iterator(inFirstNode); } - static node_iterator node_end(SNode * /*inFirstNode*/) { return node_iterator(NULL); } - - // Iterates through the number of nodes required for a given count of objects - struct SCountIteratorType - { - QT3DSU32 m_Idx; - QT3DSU32 m_Count; - - SCountIteratorType() - : m_Idx(0) - , m_Count(0) - { - } - SCountIteratorType(const SCountIteratorType &iter) - : m_Idx(iter.m_Idx) - , m_Count(iter.m_Count) - { - } - SCountIteratorType(QT3DSU32 idx, QT3DSU32 count) - : m_Idx(idx) - , m_Count(count) - { - } - - bool operator==(const SCountIteratorType &iter) const { return m_Idx == iter.m_Idx; } - - bool operator!=(const SCountIteratorType &iter) const { return m_Idx != iter.m_Idx; } - - SCountIteratorType &operator++() - { - m_Idx = NVMin(m_Idx + TObjCount, m_Count); - return *this; - } - }; - - typedef SCountIteratorType count_iterator; - static count_iterator count_begin(QT3DSU32 count) { return SCountIteratorType(0, count); } - static count_iterator count_end(QT3DSU32 count) { return SCountIteratorType(count, count); } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIntrinsics.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIntrinsics.h deleted file mode 100644 index 1d6ac7a5..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSIntrinsics.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_INTRINSICS_H -#define QT3DS_FOUNDATION_QT3DS_INTRINSICS_H - -#include "foundation/Qt3DSPreprocessor.h" - -#if defined QT3DS_WINDOWS || defined QT3DS_WIN8ARM -#include "windows/Qt3DSWindowsIntrinsics.h" -#elif defined QT3DS_X360 -#include "xbox360/NVXbox360Intrinsics.h" -#elif (defined QT3DS_LINUX || defined QT3DS_ANDROID || defined QT3DS_APPLE || defined QT3DS_QNX) -#include "linux/Qt3DSLinuxIntrinsics.h" -#elif defined QT3DS_PS3 -#include "ps3/NVPS3Intrinsics.h" -#elif defined QT3DS_PSP2 -#include "psp2/NVPSP2Intrinsics.h" -#else -#error "Platform not supported!" -#endif - -#endif // QT3DS_FOUNDATION_QT3DS_INTRINSICS_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveLinkedList.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveLinkedList.h deleted file mode 100644 index da90e120..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveLinkedList.h +++ /dev/null @@ -1,361 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_INVASIVE_LINKED_LIST_H -#define QT3DS_FOUNDATION_INVASIVE_LINKED_LIST_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSContainers.h" - -namespace qt3ds { -namespace foundation { - - // Base linked list without an included head or tail member. - template - struct SInvasiveLinkListBase - { - TObjType *tail(TObjType *inObj) - { - if (inObj) - return TObjTailOp().get(inObj); - return NULL; - } - - TObjType *head(TObjType *inObj) - { - if (inObj) - return TObjHeadOp().get(inObj); - return NULL; - } - - const TObjType *tail(const TObjType *inObj) - { - if (inObj) - return TObjTailOp().get(inObj); - return NULL; - } - - const TObjType *head(const TObjType *inObj) - { - if (inObj) - return TObjHeadOp().get(inObj); - return NULL; - } - - void remove(TObjType &inObj) - { - TObjHeadOp theHeadOp; - TObjTailOp theTailOp; - TObjType *theHead = theHeadOp.get(inObj); - TObjType *theTail = theTailOp.get(inObj); - if (theHead) - theTailOp.set(*theHead, theTail); - if (theTail) - theHeadOp.set(*theTail, theHead); - theHeadOp.set(inObj, NULL); - theTailOp.set(inObj, NULL); - } - - void insert_after(TObjType &inPosition, TObjType &inObj) - { - TObjTailOp theTailOp; - TObjType *theHead = &inPosition; - TObjType *theTail = theTailOp.get(inPosition); - insert(theHead, theTail, inObj); - } - - void insert_before(TObjType &inPosition, TObjType &inObj) - { - TObjHeadOp theHeadOp; - TObjType *theHead = theHeadOp.get(inPosition); - TObjType *theTail = &inPosition; - insert(theHead, theTail, inObj); - } - - void insert(TObjType *inHead, TObjType *inTail, TObjType &inObj) - { - TObjHeadOp theHeadOp; - TObjTailOp theTailOp; - if (inHead) - theTailOp.set(*inHead, &inObj); - if (inTail) - theHeadOp.set(*inTail, &inObj); - theHeadOp.set(inObj, inHead); - theTailOp.set(inObj, inTail); - } - }; - - template - struct SLinkedListIterator - { - typedef SLinkedListIterator TMyType; - TObjType *m_Obj; - SLinkedListIterator(TObjType *inObj = NULL) - : m_Obj(inObj) - { - } - - bool operator!=(const TMyType &inIter) const { return m_Obj != inIter.m_Obj; } - bool operator==(const TMyType &inIter) const { return m_Obj == inIter.m_Obj; } - - TMyType &operator++() - { - if (m_Obj) - m_Obj = TObjTailOp().get(*m_Obj); - return *this; - } - - TMyType &operator++(int) - { - TMyType retval(*this); - ++(*this); - return retval; - } - - TObjType &operator*() { return *m_Obj; } - TObjType *operator->() { return m_Obj; } - }; - - // Used for singly linked list where - // items have either no head or tail ptr. - template - struct SNullOp - { - void set(TObjType &, TObjType *) {} - TObjType *get(const TObjType &) { return NULL; } - }; - - template - struct InvasiveSingleLinkedList - : public SInvasiveLinkListBase, TObjTailOp> - { - typedef InvasiveSingleLinkedList TMyType; - typedef SInvasiveLinkListBase, TObjTailOp> TBaseType; - typedef SLinkedListIterator iterator; - typedef iterator const_iterator; - TObjType *m_Head; - InvasiveSingleLinkedList() - : m_Head(NULL) - { - } - InvasiveSingleLinkedList(const TMyType &inOther) - : m_Head(inOther.m_Head) - { - } - TMyType &operator=(const TMyType &inOther) - { - m_Head = inOther.m_Head; - return *this; - } - - TObjType &front() const { return *m_Head; } - - void push_front(TObjType &inObj) - { - if (m_Head != NULL) - TBaseType::insert_before(*m_Head, inObj); - m_Head = &inObj; - } - - void push_back(TObjType &inObj) - { - if (m_Head == NULL) - m_Head = &inObj; - else { - TObjType *lastObj = NULL; - for (iterator iter = begin(), endIter = end(); iter != endIter; ++iter) - lastObj = &(*iter); - - QT3DS_ASSERT(lastObj); - if (lastObj) - TObjTailOp().set(*lastObj, &inObj); - } - } - - void remove(TObjType &inObj) - { - if (m_Head == &inObj) - m_Head = TObjTailOp().get(inObj); - TBaseType::remove(inObj); - } - - bool empty() const { return m_Head == NULL; } - - iterator begin() { return iterator(m_Head); } - iterator end() { return iterator(NULL); } - - const_iterator begin() const { return iterator(m_Head); } - const_iterator end() const { return iterator(NULL); } - }; - - template - struct InvasiveLinkedList : public SInvasiveLinkListBase - { - typedef InvasiveLinkedList TMyType; - typedef SInvasiveLinkListBase TBaseType; - typedef SLinkedListIterator iterator; - typedef iterator const_iterator; - typedef SLinkedListIterator reverse_iterator; - typedef reverse_iterator const_reverse_iterator; - - TObjType *m_Head; - TObjType *m_Tail; - - InvasiveLinkedList() - : m_Head(NULL) - , m_Tail(NULL) - { - } - InvasiveLinkedList(const TMyType &inOther) - : m_Head(inOther.m_Head) - , m_Tail(inOther.m_Tail) - { - } - TMyType &operator=(const TMyType &inOther) - { - m_Head = inOther.m_Head; - m_Tail = inOther.m_Tail; - return *this; - } - - TObjType &front() const - { - QT3DS_ASSERT(m_Head); - return *m_Head; - } - TObjType &back() const - { - QT3DS_ASSERT(m_Tail); - return *m_Tail; - } - - TObjType *front_ptr() const { return m_Head; } - TObjType *back_ptr() const { return m_Tail; } - - void push_front(TObjType &inObj) - { - if (m_Head != NULL) - TBaseType::insert_before(*m_Head, inObj); - m_Head = &inObj; - - if (m_Tail == NULL) - m_Tail = &inObj; - } - - void push_back(TObjType &inObj) - { - if (m_Tail != NULL) - TBaseType::insert_after(*m_Tail, inObj); - m_Tail = &inObj; - - if (m_Head == NULL) - m_Head = &inObj; - } - - void remove(TObjType &inObj) - { - if (m_Head == &inObj) - m_Head = TObjTailOp().get(inObj); - if (m_Tail == &inObj) - m_Tail = TObjHeadOp().get(inObj); - - TBaseType::remove(inObj); - } - - bool empty() const { return m_Head == NULL; } - - iterator begin() { return iterator(m_Head); } - iterator end() { return iterator(NULL); } - - const_iterator begin() const { return iterator(m_Head); } - const_iterator end() const { return iterator(NULL); } - - reverse_iterator rbegin() { return reverse_iterator(m_Tail); } - reverse_iterator rend() { return reverse_iterator(NULL); } - - const_reverse_iterator rbegin() const { return reverse_iterator(m_Tail); } - const_reverse_iterator rend() const { return reverse_iterator(NULL); } - }; - -// Macros to speed up the definitely of invasive linked lists. -#define DEFINE_INVASIVE_SINGLE_LIST(type) \ - struct S##type; \ - struct S##type##NextOp \ - { \ - S##type *get(S##type &s); \ - const S##type *get(const S##type &s) const; \ - void set(S##type &inItem, S##type *inNext); \ - }; \ - typedef InvasiveSingleLinkedList T##type##List; - -#define DEFINE_INVASIVE_LIST(type) \ - struct S##type; \ - struct S##type##NextOp \ - { \ - S##type *get(S##type &s); \ - const S##type *get(const S##type &s) const; \ - void set(S##type &inItem, S##type *inNext); \ - }; \ - struct S##type##PreviousOp \ - { \ - S##type *get(S##type &s); \ - const S##type *get(const S##type &s) const; \ - void set(S##type &inItem, S##type *inNext); \ - }; \ - typedef InvasiveLinkedList T##type##List; - -#define IMPLEMENT_INVASIVE_LIST(type, prevMember, nextMember) \ - inline S##type *S##type##NextOp::get(S##type &s) { return s.nextMember; } \ - inline const S##type *S##type##NextOp::get(const S##type &s) const { return s.nextMember; } \ - inline void S##type##NextOp::set(S##type &inItem, S##type *inNext) \ - { \ - inItem.nextMember = inNext; \ - } \ - inline S##type *S##type##PreviousOp::get(S##type &s) { return s.prevMember; } \ - inline const S##type *S##type##PreviousOp::get(const S##type &s) const \ - { \ - return s.prevMember; \ - } \ - inline void S##type##PreviousOp::set(S##type &inItem, S##type *inNext) \ - { \ - inItem.prevMember = inNext; \ - } - -#define IMPLEMENT_INVASIVE_SINGLE_LIST(type, nextMember) \ - inline S##type *S##type##NextOp::get(S##type &s) { return s.nextMember; } \ - inline const S##type *S##type##NextOp::get(const S##type &s) const { return s.nextMember; } \ - inline void S##type##NextOp::set(S##type &inItem, S##type *inNext) \ - { \ - inItem.nextMember = inNext; \ - } -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveSet.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveSet.h deleted file mode 100644 index 772a2308..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSInvasiveSet.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_INVASIVE_SET_H -#define QT3DS_FOUNDATION_INVASIVE_SET_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSContainers.h" - -namespace qt3ds { -namespace foundation { - - template - class InvasiveSet - { - nvvector mSet; - - InvasiveSet(const InvasiveSet &other); - InvasiveSet &operator=(const InvasiveSet &other); - - public: - InvasiveSet(NVAllocatorCallback &callback, const char *allocName) - : mSet(callback, allocName) - { - } - - bool insert(TObjectType &inObject) - { - QT3DSU32 currentIdx = TGetSetIndexOp()(inObject); - if (currentIdx == QT3DS_MAX_U32) { - TSetSetIndexOp()(inObject, mSet.size()); - mSet.push_back(&inObject); - return true; - } - return false; - } - - bool remove(TObjectType &inObject) - { - QT3DSU32 currentIdx = TGetSetIndexOp()(inObject); - if (currentIdx != QT3DS_MAX_U32) { - TObjectType *theEnd = mSet.back(); - TObjectType *theObj = &inObject; - if (theEnd != theObj) { - TSetSetIndexOp()(*theEnd, currentIdx); - mSet[currentIdx] = theEnd; - } - mSet.pop_back(); - TSetSetIndexOp()(inObject, QT3DS_MAX_U32); - return true; - } - return false; - } - - bool contains(TObjectType &inObject) { return TGetSetIndexOp()(inObject) != QT3DS_MAX_U32; } - - void clear() - { - for (QT3DSU32 idx = 0; idx < mSet.size(); ++idx) - TSetSetIndexOp()(*(mSet[idx]), QT3DS_MAX_U32); - mSet.clear(); - } - - TObjectType *operator[](QT3DSU32 idx) { return mSet[idx]; } - const TObjectType *operator[](QT3DSU32 idx) const { return mSet[idx]; } - QT3DSU32 size() const { return mSet.size(); } - TObjectType **begin() { return mSet.begin(); } - TObjectType **end() { return mSet.end(); } - const TObjectType **begin() const { return mSet.begin(); } - const TObjectType **end() const { return mSet.end(); } - const TObjectType *back() const { return mSet.back(); } - TObjectType *back() { return mSet.back(); } - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSLogging.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSLogging.h deleted file mode 100644 index 4fcb77b5..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSLogging.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_ERRORS_H -#define QT3DS_FOUNDATION_QT3DS_ERRORS_H - -#include -#include - -namespace qt3ds { - -Q_DECLARE_LOGGING_CATEGORY(GL_ERROR) -Q_DECLARE_LOGGING_CATEGORY(INVALID_PARAMETER) -Q_DECLARE_LOGGING_CATEGORY(INVALID_OPERATION) -Q_DECLARE_LOGGING_CATEGORY(OUT_OF_MEMORY) -Q_DECLARE_LOGGING_CATEGORY(INTERNAL_ERROR) -Q_DECLARE_LOGGING_CATEGORY(PERF_WARNING) -Q_DECLARE_LOGGING_CATEGORY(PERF_INFO) -Q_DECLARE_LOGGING_CATEGORY(TRACE_INFO) -Q_DECLARE_LOGGING_CATEGORY(WARNING) - -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat33.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat33.h deleted file mode 100644 index 6fa69eb5..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat33.h +++ /dev/null @@ -1,385 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_MAT33_H -#define QT3DS_FOUNDATION_QT3DS_MAT33_H -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSQuat.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif -/*! -\brief 3x3 matrix class - -Some clarifications, as there have been much confusion about matrix formats etc in the past. - -Short: -- Matrix have base vectors in columns (vectors are column matrices, 3x1 matrices). -- Matrix is physically stored in column major format -- Matrices are concaternated from left - -Long: -Given three base vectors a, b and c the matrix is stored as - -|a.x b.x c.x| -|a.y b.y c.y| -|a.z b.z c.z| - -Vectors are treated as columns, so the vector v is - -|x| -|y| -|z| - -And matrices are applied _before_ the vector (pre-multiplication) -v' = M*v - -|x'| |a.x b.x c.x| |x| |a.x*x + b.x*y + c.x*z| -|y'| = |a.y b.y c.y| * |y| = |a.y*x + b.y*y + c.y*z| -|z'| |a.z b.z c.z| |z| |a.z*x + b.z*y + c.z*z| - - -Physical storage and indexing: -To be compatible with popular 3d rendering APIs (read D3d and OpenGL) -the physical indexing is - -|0 3 6| -|1 4 7| -|2 5 8| - -index = column*3 + row - -which in C++ translates to M[column][row] - -The mathematical indexing is M_row,column and this is what is used for _-notation -so _12 is 1st row, second column and operator(row, column)! - -@see QT3DSMat44 - -*/ -class QT3DSMat33 -{ -public: - //! Default constructor - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33() {} - - //! Construct from three base vectors - QT3DS_CUDA_CALLABLE QT3DSMat33(const QT3DSVec3 &col0, const QT3DSVec3 &col1, const QT3DSVec3 &col2) - : column0(col0) - , column1(col1) - , column2(col2) - { - } - - //! Construct from float[9] - QT3DS_CUDA_CALLABLE explicit QT3DS_INLINE QT3DSMat33(NVReal values[]) - : column0(values[0], values[1], values[2]) - , column1(values[3], values[4], values[5]) - , column2(values[6], values[7], values[8]) - { - } - - //! Construct from a quaternion - QT3DS_CUDA_CALLABLE explicit QT3DS_FORCE_INLINE QT3DSMat33(const QT3DSQuat &q) - { - const NVReal x = q.x; - const NVReal y = q.y; - const NVReal z = q.z; - const NVReal w = q.w; - - const NVReal x2 = x + x; - const NVReal y2 = y + y; - const NVReal z2 = z + z; - - const NVReal xx = x2 * x; - const NVReal yy = y2 * y; - const NVReal zz = z2 * z; - - const NVReal xy = x2 * y; - const NVReal xz = x2 * z; - const NVReal xw = x2 * w; - - const NVReal yz = y2 * z; - const NVReal yw = y2 * w; - const NVReal zw = z2 * w; - - column0 = QT3DSVec3(1.0f - yy - zz, xy + zw, xz - yw); - column1 = QT3DSVec3(xy - zw, 1.0f - xx - zz, yz + xw); - column2 = QT3DSVec3(xz + yw, yz - xw, 1.0f - xx - yy); - } - - //! Copy constructor - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33(const QT3DSMat33 &other) - : column0(other.column0) - , column1(other.column1) - , column2(other.column2) - { - } - - //! Assignment operator - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 &operator=(const QT3DSMat33 &other) - { - column0 = other.column0; - column1 = other.column1; - column2 = other.column2; - return *this; - } - - //! Set to identity matrix - QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat33 createIdentity() - { - return QT3DSMat33(QT3DSVec3(1, 0, 0), QT3DSVec3(0, 1, 0), QT3DSVec3(0, 0, 1)); - } - - //! Set to zero matrix - QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat33 createZero() - { - return QT3DSMat33(QT3DSVec3(0.0f), QT3DSVec3(0.0f), QT3DSVec3(0.0f)); - } - - //! Construct from diagonal, off-diagonals are zero. - QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat33 createDiagonal(const QT3DSVec3 &d) - { - return QT3DSMat33(QT3DSVec3(d.x, 0.0f, 0.0f), QT3DSVec3(0.0f, d.y, 0.0f), QT3DSVec3(0.0f, 0.0f, d.z)); - } - - //! Get transposed matrix - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 getTranspose() const - { - const QT3DSVec3 v0(column0.x, column1.x, column2.x); - const QT3DSVec3 v1(column0.y, column1.y, column2.y); - const QT3DSVec3 v2(column0.z, column1.z, column2.z); - - return QT3DSMat33(v0, v1, v2); - } - - //! Get the real inverse - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 getInverse() const - { - const NVReal det = getDeterminant(); - QT3DSMat33 inverse; - - if (det != 0) { - const NVReal invDet = 1.0f / det; - - inverse.column0[0] = invDet * (column1[1] * column2[2] - column2[1] * column1[2]); - inverse.column0[1] = invDet * -(column0[1] * column2[2] - column2[1] * column0[2]); - inverse.column0[2] = invDet * (column0[1] * column1[2] - column0[2] * column1[1]); - - inverse.column1[0] = invDet * -(column1[0] * column2[2] - column1[2] * column2[0]); - inverse.column1[1] = invDet * (column0[0] * column2[2] - column0[2] * column2[0]); - inverse.column1[2] = invDet * -(column0[0] * column1[2] - column0[2] * column1[0]); - - inverse.column2[0] = invDet * (column1[0] * column2[1] - column1[1] * column2[0]); - inverse.column2[1] = invDet * -(column0[0] * column2[1] - column0[1] * column2[0]); - inverse.column2[2] = invDet * (column0[0] * column1[1] - column1[0] * column0[1]); - - return inverse; - } else { - return createIdentity(); - } - } - - //! Get determinant - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal getDeterminant() const - { - return column0.dot(column1.cross(column2)); - } - - //! Unary minus - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator-() const - { - return QT3DSMat33(-column0, -column1, -column2); - } - - //! Add - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator+(const QT3DSMat33 &other) const - { - return QT3DSMat33(column0 + other.column0, column1 + other.column1, column2 + other.column2); - } - - //! Subtract - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator-(const QT3DSMat33 &other) const - { - return QT3DSMat33(column0 - other.column0, column1 - other.column1, column2 - other.column2); - } - - //! Scalar multiplication - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator*(NVReal scalar) const - { - return QT3DSMat33(column0 * scalar, column1 * scalar, column2 * scalar); - } - - friend QT3DSMat33 operator*(NVReal, const QT3DSMat33 &); - - //! Matrix vector multiplication (returns 'this->transform(vec)') - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 operator*(const QT3DSVec3 &vec) const { return transform(vec); } - - //! Matrix multiplication - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 operator*(const QT3DSMat33 &other) const - { - // Rows from this columns from other - // column0 = transform(other.column0) etc - return QT3DSMat33(transform(other.column0), transform(other.column1), - transform(other.column2)); - } - - // a = b operators - - //! Equals-add - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 &operator+=(const QT3DSMat33 &other) - { - column0 += other.column0; - column1 += other.column1; - column2 += other.column2; - return *this; - } - - //! Equals-sub - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 &operator-=(const QT3DSMat33 &other) - { - column0 -= other.column0; - column1 -= other.column1; - column2 -= other.column2; - return *this; - } - - //! Equals scalar multiplication - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 &operator*=(NVReal scalar) - { - column0 *= scalar; - column1 *= scalar; - column2 *= scalar; - return *this; - } - - //! Element access, mathematical way! - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal operator()(unsigned int row, unsigned int col) const - { - return (*this)[col][row]; - } - - //! Element access, mathematical way! - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator()(unsigned int row, unsigned int col) - { - return (*this)[col][row]; - } - - // Transform etc - - //! Transform vector by matrix, equal to v' = M*v - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 transform(const QT3DSVec3 &other) const - { - return column0 * other.x + column1 * other.y + column2 * other.z; - } - - //! Transform vector by matrix transpose, v' = M^t*v - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 transformTranspose(const QT3DSVec3 &other) const - { - return QT3DSVec3(column0.dot(other), column1.dot(other), column2.dot(other)); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal *front() const { return &column0.x; } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator[](int num) { return (&column0)[num]; } - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec3 &operator[](int num) const - { - return (&column0)[num]; - } - - // Data, see above for format! - - QT3DSVec3 column0, column1, column2; // the three base vectors -}; - -// implementation from Qt3DSQuat.h -QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat::QT3DSQuat(const QT3DSMat33 &m) -{ - NVReal tr = m(0, 0) + m(1, 1) + m(2, 2), h; - if (tr >= 0) { - h = NVSqrt(tr + 1); - w = NVReal(0.5) * h; - h = NVReal(0.5) / h; - - x = (m(2, 1) - m(1, 2)) * h; - y = (m(0, 2) - m(2, 0)) * h; - z = (m(1, 0) - m(0, 1)) * h; - } else { - int i = 0; - if (m(1, 1) > m(0, 0)) - i = 1; - if (m(2, 2) > m(i, i)) - i = 2; - switch (i) { - case 0: - h = NVSqrt((m(0, 0) - (m(1, 1) + m(2, 2))) + 1); - x = NVReal(0.5) * h; - h = NVReal(0.5) / h; - - y = (m(0, 1) + m(1, 0)) * h; - z = (m(2, 0) + m(0, 2)) * h; - w = (m(2, 1) - m(1, 2)) * h; - break; - case 1: - h = NVSqrt((m(1, 1) - (m(2, 2) + m(0, 0))) + 1); - y = NVReal(0.5) * h; - h = NVReal(0.5) / h; - - z = (m(1, 2) + m(2, 1)) * h; - x = (m(0, 1) + m(1, 0)) * h; - w = (m(0, 2) - m(2, 0)) * h; - break; - case 2: - h = NVSqrt((m(2, 2) - (m(0, 0) + m(1, 1))) + 1); - z = NVReal(0.5) * h; - h = NVReal(0.5) / h; - - x = (m(2, 0) + m(0, 2)) * h; - y = (m(1, 2) + m(2, 1)) * h; - w = (m(1, 0) - m(0, 1)) * h; - break; - default: // Make compiler happy - x = y = z = w = 0; - break; - } - } -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_MAT33_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat44.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat44.h deleted file mode 100644 index 53a66e2b..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMat44.h +++ /dev/null @@ -1,497 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_MAT44_H -#define QT3DS_FOUNDATION_QT3DS_MAT44_H -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSQuat.h" -#include "foundation/Qt3DSVec4.h" -#include "foundation/Qt3DSMat33.h" -#include "foundation/Qt3DSTransform.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/*! -\brief 4x4 matrix class - -This class is layout-compatible with D3D and OpenGL matrices. More notes on layout are given in the QT3DSMat33 -Graphics matrices always (by which I mean DX and OpenGL) have the rotation basis vectors stored contiguously -in 0-2, 3-5, 6-8 and the the translation stored contiguously in 12-14. However, DX calls this row major and GL calls it column-major. -http://www.mindcontrol.org/~hplus/graphics/matrix-layout.html - -you can blat these directly into GL (or DX) - ---Dilip Sequeira - -@see QT3DSMat33 NVTransform -*/ - -class QT3DSMat44 -{ -public: - //! Default constructor - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44() {} - - //! Construct from four 4-vectors - QT3DS_CUDA_CALLABLE QT3DSMat44(const QT3DSVec4 &col0, const QT3DSVec4 &col1, const QT3DSVec4 &col2, - const QT3DSVec4 &col3) - : column0(col0) - , column1(col1) - , column2(col2) - , column3(col3) - { - } - - //! Construct from three base vectors and a translation - QT3DS_CUDA_CALLABLE QT3DSMat44(const QT3DSVec3 &column0, const QT3DSVec3 &column1, const QT3DSVec3 &column2, - const QT3DSVec3 &column3) - : column0(column0, 0) - , column1(column1, 0) - , column2(column2, 0) - , column3(column3, 1) - { - } - - //! Construct from float[16] - explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(NVReal values[]) - : column0(values[0], values[1], values[2], values[3]) - , column1(values[4], values[5], values[6], values[7]) - , column2(values[8], values[9], values[10], values[11]) - , column3(values[12], values[13], values[14], values[15]) - { - } - - //! Construct from a quaternion - explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(const QT3DSQuat &q) - { - const NVReal x = q.x; - const NVReal y = q.y; - const NVReal z = q.z; - const NVReal w = q.w; - - const NVReal x2 = x + x; - const NVReal y2 = y + y; - const NVReal z2 = z + z; - - const NVReal xx = x2 * x; - const NVReal yy = y2 * y; - const NVReal zz = z2 * z; - - const NVReal xy = x2 * y; - const NVReal xz = x2 * z; - const NVReal xw = x2 * w; - - const NVReal yz = y2 * z; - const NVReal yw = y2 * w; - const NVReal zw = z2 * w; - - column0 = QT3DSVec4(1.0f - yy - zz, xy + zw, xz - yw, 0.0f); - column1 = QT3DSVec4(xy - zw, 1.0f - xx - zz, yz + xw, 0.0f); - column2 = QT3DSVec4(xz + yw, yz - xw, 1.0f - xx - yy, 0.0f); - column3 = QT3DSVec4(0.0f, 0.0f, 0.0f, 1.0f); - } - - //! Construct from a diagonal vector - explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(const QT3DSVec4 &diagonal) - : column0(diagonal.x, 0.0f, 0.0f, 0.0f) - , column1(0.0f, diagonal.y, 0.0f, 0.0f) - , column2(0.0f, 0.0f, diagonal.z, 0.0f) - , column3(0.0f, 0.0f, 0.0f, diagonal.w) - { - } - - QT3DS_CUDA_CALLABLE QT3DSMat44(const QT3DSMat33 &orientation, const QT3DSVec3 &position) - : column0(orientation.column0, 0.0f) - , column1(orientation.column1, 0.0f) - , column2(orientation.column2, 0.0f) - , column3(position, 1) - { - } - - QT3DS_CUDA_CALLABLE QT3DSMat44(const NVTransform &t) { *this = QT3DSMat44(QT3DSMat33(t.q), t.p); } - - //! Copy constructor - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(const QT3DSMat44 &other) - : column0(other.column0) - , column1(other.column1) - , column2(other.column2) - , column3(other.column3) - { - } - - //! Assignment operator - QT3DS_CUDA_CALLABLE QT3DS_INLINE const QT3DSMat44 &operator=(const QT3DSMat44 &other) - { - column0 = other.column0; - column1 = other.column1; - column2 = other.column2; - column3 = other.column3; - return *this; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat44 createIdentity() - { - return QT3DSMat44(QT3DSVec4(1.0f, 0.0f, 0.0f, 0.0f), QT3DSVec4(0.0f, 1.0f, 0.0f, 0.0f), - QT3DSVec4(0.0f, 0.0f, 1.0f, 0.0f), QT3DSVec4(0.0f, 0.0f, 0.0f, 1.0f)); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat44 createZero() - { - return QT3DSMat44(QT3DSVec4(0.0f), QT3DSVec4(0.0f), QT3DSVec4(0.0f), QT3DSVec4(0.0f)); - } - - //! Get transposed matrix - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 getTranspose() const - { - return QT3DSMat44(QT3DSVec4(column0.x, column1.x, column2.x, column3.x), - QT3DSVec4(column0.y, column1.y, column2.y, column3.y), - QT3DSVec4(column0.z, column1.z, column2.z, column3.z), - QT3DSVec4(column0.w, column1.w, column2.w, column3.w)); - } - - //! Unary minus - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator-() const - { - return QT3DSMat44(-column0, -column1, -column2, -column3); - } - - //! Add - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator+(const QT3DSMat44 &other) const - { - return QT3DSMat44(column0 + other.column0, column1 + other.column1, column2 + other.column2, - column3 + other.column3); - } - - //! Subtract - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator-(const QT3DSMat44 &other) const - { - return QT3DSMat44(column0 - other.column0, column1 - other.column1, column2 - other.column2, - column3 - other.column3); - } - - //! Scalar multiplication - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator*(NVReal scalar) const - { - return QT3DSMat44(column0 * scalar, column1 * scalar, column2 * scalar, column3 * scalar); - } - - friend QT3DSMat44 operator*(NVReal, const QT3DSMat44 &); - - //! Matrix multiplication - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator*(const QT3DSMat44 &other) const - { - // Rows from this columns from other - // column0 = transform(other.column0) etc - return QT3DSMat44(transform(other.column0), transform(other.column1), transform(other.column2), - transform(other.column3)); - } - - // a = b operators - - //! Equals-add - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 &operator+=(const QT3DSMat44 &other) - { - column0 += other.column0; - column1 += other.column1; - column2 += other.column2; - column3 += other.column3; - return *this; - } - - //! Equals-sub - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 &operator-=(const QT3DSMat44 &other) - { - column0 -= other.column0; - column1 -= other.column1; - column2 -= other.column2; - column3 -= other.column3; - return *this; - } - - //! Equals scalar multiplication - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 &operator*=(NVReal scalar) - { - column0 *= scalar; - column1 *= scalar; - column2 *= scalar; - column3 *= scalar; - return *this; - } - - //! Element access, mathematical way! - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal operator()(unsigned int row, unsigned int col) const - { - return (*this)[col][row]; - } - - //! Element access, mathematical way! - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator()(unsigned int row, unsigned int col) - { - return (*this)[col][row]; - } - - //! Transform vector by matrix, equal to v' = M*v - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 transform(const QT3DSVec4 &other) const - { - return column0 * other.x + column1 * other.y + column2 * other.z + column3 * other.w; - } - - //! Transform vector by matrix, equal to v' = M*v - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 transform(const QT3DSVec3 &other) const - { - return transform(QT3DSVec4(other, 1)).getXYZ(); - } - - //! Rotate vector by matrix, equal to v' = M*v - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 rotate(const QT3DSVec4 &other) const - { - return column0 * other.x + column1 * other.y + column2 * other.z; // + column3*0; - } - - //! Rotate vector by matrix, equal to v' = M*v - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 rotate(const QT3DSVec3 &other) const - { - return rotate(QT3DSVec4(other, 1)).getXYZ(); - } - - /** -* Shamelessly pulled from gl-matrix.js - * Rotates a matrix by the given angle around the specified axis -* -* @param angle Angle (in radians) to rotate -* @param axis vec3 representing the axis to rotate around -*/ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool rotate(QT3DSF32 angleRadians, QT3DSVec3 axis) - { - QT3DSF32 x = axis[0], y = axis[1], z = axis[2], len = x * x + y * y + z * z, s, c, t, a00, a01, - a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, - b21, b22; - - if (!len) { - return false; - } - if (len != 1.0f) { - len = 1 / (NVSqrt(len)); - x *= len; - y *= len; - z *= len; - } - - s = NVSin(angleRadians); - c = NVCos(angleRadians); - t = 1 - c; - - QT3DSF32 *dataPtr(front()); - -// inverse algorithm was written for row-major matrixes. -#define mat(idx) dataPtr[idx] - - a00 = mat(0); - a01 = mat(1); - a02 = mat(2); - a03 = mat(3); - a10 = mat(4); - a11 = mat(5); - a12 = mat(6); - a13 = mat(7); - a20 = mat(8); - a21 = mat(9); - a22 = mat(10); - a23 = mat(11); -#undef mat - - // Construct the elements of the rotation matrix - b00 = x * x * t + c; - b01 = y * x * t + z * s; - b02 = z * x * t - y * s; - b10 = x * y * t - z * s; - b11 = y * y * t + c; - b12 = z * y * t + x * s; - b20 = x * z * t + y * s; - b21 = y * z * t - x * s; - b22 = z * z * t + c; - -// Perform rotation-specific matrix multiplication - -#define dest(idx) dataPtr[idx] - - dest(0) = a00 * b00 + a10 * b01 + a20 * b02; - dest(1) = a01 * b00 + a11 * b01 + a21 * b02; - dest(2) = a02 * b00 + a12 * b01 + a22 * b02; - dest(3) = a03 * b00 + a13 * b01 + a23 * b02; - - dest(4) = a00 * b10 + a10 * b11 + a20 * b12; - dest(5) = a01 * b10 + a11 * b11 + a21 * b12; - dest(6) = a02 * b10 + a12 * b11 + a22 * b12; - dest(7) = a03 * b10 + a13 * b11 + a23 * b12; - - dest(8) = a00 * b20 + a10 * b21 + a20 * b22; - dest(9) = a01 * b20 + a11 * b21 + a21 * b22; - dest(10) = a02 * b20 + a12 * b21 + a22 * b22; - dest(11) = a03 * b20 + a13 * b21 + a23 * b22; - -#undef dest - - return true; - }; - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getBasis(int num) const - { - QT3DS_ASSERT(num >= 0 && num < 3); - return (&column0)[num].getXYZ(); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getPosition() const { return column3.getXYZ(); } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE void setPosition(const QT3DSVec3 &position) - { - column3.x = position.x; - column3.y = position.y; - column3.z = position.z; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal *front() { return &column0.x; } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal *front() const { return &column0.x; } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec4 &operator[](int num) { return (&column0)[num]; } - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec4 &operator[](int num) const - { - return (&column0)[num]; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE void scale(const QT3DSVec4 &p) - { - column0 *= p.x; - column1 *= p.y; - column2 *= p.z; - column3 *= p.w; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 inverseRT(void) const - { - QT3DSVec3 r0(column0.x, column1.x, column2.x), r1(column0.y, column1.y, column2.y), - r2(column0.z, column1.z, column2.z); - - return QT3DSMat44(r0, r1, r2, -(r0 * column3.x + r1 * column3.y + r2 * column3.z)); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 getInverse(void) const - { - // inverse algorithm was written for row-major matrixes. - const QT3DSF32 *myPtr(front()); -#define mat(idx) myPtr[idx] - - QT3DSF32 a00 = mat(0), a01 = mat(1), a02 = mat(2), a03 = mat(3), a10 = mat(4), a11 = mat(5), - a12 = mat(6), a13 = mat(7), a20 = mat(8), a21 = mat(9), a22 = mat(10), a23 = mat(11), - a30 = mat(12), a31 = mat(13), a32 = mat(14), a33 = mat(15), -#undef mat - - b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, - b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, - b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, - b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, - - d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06), invDet; - - // Calculate the determinant - if (!d) { - QT3DS_ASSERT(false); - return QT3DSMat44::createIdentity(); - } - invDet = 1 / d; - - QT3DSMat44 retval; - QT3DSF32 *destPtr = retval.front(); - -#define dest(idx) destPtr[idx] - dest(0) = (a11 * b11 - a12 * b10 + a13 * b09) * invDet; - dest(1) = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet; - dest(2) = (a31 * b05 - a32 * b04 + a33 * b03) * invDet; - dest(3) = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet; - dest(4) = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet; - dest(5) = (a00 * b11 - a02 * b08 + a03 * b07) * invDet; - dest(6) = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet; - dest(7) = (a20 * b05 - a22 * b02 + a23 * b01) * invDet; - dest(8) = (a10 * b10 - a11 * b08 + a13 * b06) * invDet; - dest(9) = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet; - dest(10) = (a30 * b04 - a31 * b02 + a33 * b00) * invDet; - dest(11) = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet; - dest(12) = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet; - dest(13) = (a00 * b09 - a01 * b07 + a02 * b06) * invDet; - dest(14) = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet; - dest(15) = (a20 * b03 - a21 * b01 + a22 * b00) * invDet; -#undef dest - - return retval; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const - { - return column0.isFinite() && column1.isFinite() && column2.isFinite() && column3.isFinite(); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 getUpper3x3() const - { - return QT3DSMat33(column0.getXYZ(), column1.getXYZ(), column2.getXYZ()); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 getUpper3x3InverseTranspose() const - { - return getUpper3x3().getInverse().getTranspose(); - } - - // Data, see above for format! - - QT3DSVec4 column0, column1, column2, column3; // the four base vectors -}; - -// implementation from Qt3DSTransform.h -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform::NVTransform(const QT3DSMat44 &m) -{ - QT3DSVec3 column0 = QT3DSVec3(m.column0.x, m.column0.y, m.column0.z); - QT3DSVec3 column1 = QT3DSVec3(m.column1.x, m.column1.y, m.column1.z); - QT3DSVec3 column2 = QT3DSVec3(m.column2.x, m.column2.y, m.column2.z); - - q = QT3DSQuat(QT3DSMat33(column0, column1, column2)); - p = QT3DSVec3(m.column3.x, m.column3.y, m.column3.z); -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_MAT44_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMath.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMath.h deleted file mode 100644 index 931852e7..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMath.h +++ /dev/null @@ -1,323 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_MATH_H -#define QT3DS_FOUNDATION_QT3DS_MATH_H - -/** \addtogroup foundation -@{ -*/ - -#include -#include -#include - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSAssert.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -// constants -static const NVReal NVPi = NVReal(3.141592653589793); -static const NVReal NVHalfPi = NVReal(1.57079632679489661923); -static const NVReal NVTwoPi = NVReal(6.28318530717958647692); -static const NVReal NVInvPi = NVReal(0.31830988618379067154); - -/** -\brief The return value is the greater of the two specified values. -*/ -template -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE T NVMax(T a, T b) -{ - return a < b ? b : a; -} - -//! overload for float to use fsel on xbox -template <> -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVMax(float a, float b) -{ - return intrinsics::selectMax(a, b); -} - -/** -\brief The return value is the lesser of the two specified values. -*/ -template -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE T NVMin(T a, T b) -{ - return a < b ? a : b; -} - -template <> -//! overload for float to use fsel on xbox -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVMin(float a, float b) -{ - return intrinsics::selectMin(a, b); -} - -/* -Many of these are just implemented as QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE calls to the C lib right now, -but later we could replace some of them with some approximations or more -clever stuff. -*/ - -/** -\brief abs returns the absolute value of its argument. -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAbs(QT3DSF32 a) -{ - return intrinsics::abs(a); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVEquals(QT3DSF32 a, QT3DSF32 b, QT3DSF32 epsilon) -{ - return (NVAbs(a - b) < epsilon); -} - -/** -\brief abs returns the absolute value of its argument. -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAbs(QT3DSF64 a) -{ - return ::fabs(a); -} - -/** -\brief abs returns the absolute value of its argument. -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSI32 NVAbs(QT3DSI32 a) -{ - return ::abs(a); -} - -/** -\brief Clamps v to the range [hi,lo] -*/ -template -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE T NVClamp(T v, T lo, T hi) -{ - QT3DS_ASSERT(lo <= hi); - return NVMin(hi, NVMax(lo, v)); -} - -//! \brief Square root. -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVSqrt(QT3DSF32 a) -{ - return intrinsics::sqrt(a); -} - -//! \brief Square root. -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVSqrt(QT3DSF64 a) -{ - return ::sqrt(a); -} - -//! \brief reciprocal square root. -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVRecipSqrt(QT3DSF32 a) -{ - return intrinsics::recipSqrt(a); -} - -//! \brief reciprocal square root. -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVRecipSqrt(QT3DSF64 a) -{ - return 1 / ::sqrt(a); -} - -//!trigonometry -- all angles are in radians. - -//! \brief Sine of an angle ( Unit: Radians ) -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVSin(QT3DSF32 a) -{ - return intrinsics::sin(a); -} - -//! \brief Sine of an angle ( Unit: Radians ) -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVSin(QT3DSF64 a) -{ - return ::sin(a); -} - -//! \brief Cosine of an angle (Unit: Radians) -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVCos(QT3DSF32 a) -{ - return intrinsics::cos(a); -} - -//! \brief Cosine of an angle (Unit: Radians) -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVCos(QT3DSF64 a) -{ - return ::cos(a); -} - -/** -\brief Tangent of an angle. -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVTan(QT3DSF32 a) -{ - return QT3DSF32(::tan(a)); -} - -/** -\brief Tangent of an angle. -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVTan(QT3DSF64 a) -{ - return ::tan(a); -} - -/** -\brief Arcsine. -Returns angle between -PI/2 and PI/2 in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAsin(QT3DSF32 f) -{ - return QT3DSF32(::asin(NVClamp(f, -1.0f, 1.0f))); -} - -/** -\brief Arcsine. -Returns angle between -PI/2 and PI/2 in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAsin(QT3DSF64 f) -{ - return ::asin(NVClamp(f, -1.0, 1.0)); -} - -/** -\brief Arccosine. -Returns angle between 0 and PI in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAcos(QT3DSF32 f) -{ - return QT3DSF32(::acos(NVClamp(f, -1.0f, 1.0f))); -} - -/** -\brief Arccosine. -Returns angle between 0 and PI in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAcos(QT3DSF64 f) -{ - return ::acos(NVClamp(f, -1.0, 1.0)); -} - -/** -\brief ArcTangent. -Returns angle between -PI/2 and PI/2 in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAtan(QT3DSF32 a) -{ - return QT3DSF32(::atan(a)); -} - -/** -\brief ArcTangent. -Returns angle between -PI/2 and PI/2 in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAtan(QT3DSF64 a) -{ - return ::atan(a); -} - -/** -\brief Arctangent of (x/y) with correct sign. -Returns angle between -PI and PI in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAtan2(QT3DSF32 x, QT3DSF32 y) -{ - return QT3DSF32(::atan2(x, y)); -} - -/** -\brief Arctangent of (x/y) with correct sign. -Returns angle between -PI and PI in radians -Unit: Radians -*/ -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAtan2(QT3DSF64 x, QT3DSF64 y) -{ - return ::atan2(x, y); -} - -//! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVIsFinite(QT3DSF32 f) -{ - return intrinsics::isFinite(f); -} - -//! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVIsFinite(QT3DSF64 f) -{ - return intrinsics::isFinite(f); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVFloor(QT3DSF32 a) -{ - return ::floorf(a); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVExp(QT3DSF32 a) -{ - return ::expf(a); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVCeil(QT3DSF32 a) -{ - return ::ceilf(a); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVSign(QT3DSF32 a) -{ - return qt3ds::intrinsics::sign(a); -} - -QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVPow(QT3DSF32 x, QT3DSF32 y) -{ - return ::powf(x, y); -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_MATH_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMathUtils.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMathUtils.h deleted file mode 100644 index 6d3d0abc..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMathUtils.h +++ /dev/null @@ -1,571 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSMATHUTILS_H -#define QT3DS_FOUNDATION_PSMATHUTILS_H - -#include "foundation/Qt3DSTransform.h" -#include "foundation/Qt3DSMat33.h" -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSIntrinsics.h" -#include - -// General guideline is: if it's an abstract math function, it belongs here. -// If it's a math function where the inputs have specific semantics (e.g. -// separateSwingTwist) it doesn't. - -namespace qt3ds { -namespace foundation { - using namespace intrinsics; - /** - \brief sign returns the sign of its argument. The sign of zero is undefined. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 sign(const QT3DSF32 a) { - return intrinsics::sign(a); - } - - /** - \brief sign returns the sign of its argument. The sign of zero is undefined. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 sign(const QT3DSF64 a) { return (a >= 0.0) ? 1.0 : -1.0; } - - /** - \brief sign returns the sign of its argument. The sign of zero is undefined. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSI32 sign(const QT3DSI32 a) { return (a >= 0) ? 1 : -1; } - - /** - \brief Returns true if the two numbers are within eps of each other. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool equals(const QT3DSF32 a, const QT3DSF32 b, const QT3DSF32 eps) - { - return (NVAbs(a - b) < eps); - } - - /** - \brief Returns true if the two numbers are within eps of each other. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool equals(const QT3DSF64 a, const QT3DSF64 b, const QT3DSF64 eps) - { - return (NVAbs(a - b) < eps); - } - - /** - \brief The floor function returns a floating-point value representing the largest integer that - is less than or equal to x. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 floor(const QT3DSF32 a) { return floatFloor(a); } - - /** - \brief The floor function returns a floating-point value representing the largest integer that - is less than or equal to x. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 floor(const QT3DSF64 a) { return ::floor(a); } - - /** - \brief The ceil function returns a single value representing the smallest integer that is - greater than or equal to x. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 ceil(const QT3DSF32 a) { return ::ceilf(a); } - - /** - \brief The ceil function returns a double value representing the smallest integer that is - greater than or equal to x. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 ceil(const QT3DSF64 a) { return ::ceil(a); } - - /** - \brief mod returns the floating-point remainder of x / y. - - If the value of y is 0.0, mod returns a quiet NaN. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 mod(const QT3DSF32 x, const QT3DSF32 y) - { - return (QT3DSF32)::fmod(x, y); - } - - /** - \brief mod returns the floating-point remainder of x / y. - - If the value of y is 0.0, mod returns a quiet NaN. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 mod(const QT3DSF64 x, const QT3DSF64 y) - { - return ::fmod(x, y); - } - - /** - \brief Square. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 sqr(const QT3DSF32 a) { return a * a; } - - /** - \brief Square. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 sqr(const QT3DSF64 a) { return a * a; } - - /** - \brief Calculates x raised to the power of y. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 pow(const QT3DSF32 x, const QT3DSF32 y) - { - return ::powf(x, y); - } - - /** - \brief Calculates x raised to the power of y. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 pow(const QT3DSF64 x, const QT3DSF64 y) { return ::pow(x, y); } - - /** - \brief Calculates e^n - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 exp(const QT3DSF32 a) { return QT3DSF32(::exp(a)); } - /** - - \brief Calculates e^n - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 exp(const QT3DSF64 a) { return ::exp(a); } - - /** - \brief Calculates logarithms. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 logE(const QT3DSF32 a) { return QT3DSF32(::log(a)); } - - /** - \brief Calculates logarithms. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 logE(const QT3DSF64 a) { return ::log(a); } - - /** - \brief Calculates logarithms. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 log2(const QT3DSF32 a) - { - return QT3DSF32(::log(a)) / 0.693147180559945309417f; - } - - /** - \brief Calculates logarithms. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 log2(const QT3DSF64 a) - { - return ::log(a) / 0.693147180559945309417; - } - - /** - \brief Calculates logarithms. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 log10(const QT3DSF32 a) { return (QT3DSF32)::log10(a); } - - /** - \brief Calculates logarithms. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 log10(const QT3DSF64 a) { return ::log10(a); } - - /** - \brief Converts degrees to radians. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 degToRad(const QT3DSF32 a) - { - return (QT3DSF32)0.01745329251994329547 * a; - } - - /** - \brief Converts degrees to radians. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 degToRad(const QT3DSF64 a) - { - return (QT3DSF64)0.01745329251994329547 * a; - } - - /** - \brief Converts radians to degrees. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 radToDeg(const QT3DSF32 a) - { - return (QT3DSF32)57.29577951308232286465 * a; - } - - /** - \brief Converts radians to degrees. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 radToDeg(const QT3DSF64 a) - { - return (QT3DSF64)57.29577951308232286465 * a; - } - - //! \brief compute sine and cosine at the same time. There is a 'fsincos' on PC that we probably want to use here - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void sincos(const QT3DSF32 radians, QT3DSF32 &sin, QT3DSF32 &cos) - { - /* something like: - _asm fld Local - _asm fsincos - _asm fstp LocalCos - _asm fstp LocalSin - */ - sin = NVSin(radians); - cos = NVCos(radians); - } - - /** - \brief uniform random number in [a,b] - */ - QT3DS_FORCE_INLINE QT3DSI32 rand(const QT3DSI32 a, const QT3DSI32 b) - { - return a + (QT3DSI32)(::rand() % (b - a + 1)); - } - - /** - \brief uniform random number in [a,b] - */ - QT3DS_FORCE_INLINE QT3DSF32 rand(const QT3DSF32 a, const QT3DSF32 b) - { - return a + (b - a) * ::rand() / RAND_MAX; - } - - //! \brief return angle between two vectors in radians - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 angle(const QT3DSVec3 &v0, const QT3DSVec3 &v1) - { - const QT3DSF32 cos = v0.dot(v1); // |v0|*|v1|*Cos(Angle) - const QT3DSF32 sin = (v0.cross(v1)).magnitude(); // |v0|*|v1|*Sin(Angle) - return NVAtan2(sin, cos); - } - - //! If possible use instead fsel on the dot product /*fsel(d.dot(p),onething,anotherthing);*/ - //! Compares orientations (more readable, user-friendly function) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool sameDirection(const QT3DSVec3 &d, const QT3DSVec3 &p) - { - return d.dot(p) >= 0.0f; - } - - //! Checks 2 values have different signs - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE IntBool differentSign(NVReal f0, NVReal f1) - { - union { - QT3DSU32 u; - NVReal f; - } u1, u2; - u1.f = f0; - u2.f = f1; - return (u1.u ^ u2.u) & QT3DS_SIGN_BITMASK; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 star(const QT3DSVec3 &v) - { - return QT3DSMat33(QT3DSVec3(0, v.z, -v.y), QT3DSVec3(-v.z, 0, v.x), QT3DSVec3(v.y, -v.x, 0)); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 log(const QT3DSQuat &q) - { - const NVReal s = q.getImaginaryPart().magnitude(); - if (s < 1e-12) - return QT3DSVec3(0.0f); - // force the half-angle to have magnitude <= pi/2 - NVReal halfAngle = q.w < 0 ? NVAtan2(-s, -q.w) : NVAtan2(s, q.w); - QT3DS_ASSERT(halfAngle >= -NVPi / 2 && halfAngle <= NVPi / 2); - - return q.getImaginaryPart().getNormalized() * 2 * halfAngle; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat exp(const QT3DSVec3 &v) - { - const NVReal m = v.magnitudeSquared(); - return m < 1e-24 ? QT3DSQuat::createIdentity() : QT3DSQuat(NVSqrt(m), v * NVRecipSqrt(m)); - } - - // quat to rotate v0 t0 v1 - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat rotationArc(const QT3DSVec3 &v0, const QT3DSVec3 &v1) - { - const QT3DSVec3 cross = v0.cross(v1); - const NVReal d = v0.dot(v1); - if (d <= -0.99999f) - return (NVAbs(v0.x) < 0.1f ? QT3DSQuat(0.0f, v0.z, -v0.y, 0.0f) - : QT3DSQuat(v0.y, -v0.x, 0.0, 0.0)) - .getNormalized(); - - const NVReal s = NVSqrt((1 + d) * 2), r = 1 / s; - - return QT3DSQuat(cross.x * r, cross.y * r, cross.z * r, s * 0.5f).getNormalized(); - } - - //! Computes the maximum delta to another transform - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal maxComponentDelta(const NVTransform &t0, - const NVTransform &t1) - { - NVReal delta = NVAbs(t0.p.x - t1.p.x); - delta = NVMax(delta, NVAbs(t0.p.y - t1.p.y)); - delta = NVMax(delta, NVAbs(t0.p.z - t1.p.z)); - delta = NVMax(delta, NVAbs(t0.q.x - t1.q.x)); - delta = NVMax(delta, NVAbs(t0.q.y - t1.q.y)); - delta = NVMax(delta, NVAbs(t0.q.z - t1.q.z)); - delta = NVMax(delta, NVAbs(t0.q.w - t1.q.w)); - - return delta; - } - - /** - \brief returns largest axis - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU32 largestAxis(const QT3DSVec3 &v) - { - QT3DSU32 m = v.y > v.x ? 1 : 0; - return v.z > v[m] ? 2 : m; - } - - /** - \brief returns axis with smallest absolute value - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU32 closestAxis(const QT3DSVec3 &v) - { - QT3DSU32 m = NVAbs(v.y) > NVAbs(v.x) ? 1 : 0; - return NVAbs(v.z) > NVAbs(v[m]) ? 2 : m; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSU32 closestAxis(const QT3DSVec3 &v, QT3DSU32 &j, QT3DSU32 &k) - { - // find largest 2D plane projection - const QT3DSF32 absNV = NVAbs(v.x); - const QT3DSF32 absNy = NVAbs(v.y); - const QT3DSF32 absNz = NVAbs(v.z); - - QT3DSU32 m = 0; // x biggest axis - j = 1; - k = 2; - if (absNy > absNV && absNy > absNz) { - // y biggest - j = 2; - k = 0; - m = 1; - } else if (absNz > absNV) { - // z biggest - j = 0; - k = 1; - m = 2; - } - return m; - } - - /*! - Extend an edge along its length by a factor - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void makeFatEdge(QT3DSVec3 &p0, QT3DSVec3 &p1, NVReal fatCoeff) - { - QT3DSVec3 delta = p1 - p0; - - const NVReal m = delta.magnitude(); - if (m > 0.0f) { - delta *= fatCoeff / m; - p0 -= delta; - p1 += delta; - } - } - - //! Compute point as combination of barycentric coordinates - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 computeBarycentricPoint(const QT3DSVec3 &p0, - const QT3DSVec3 &p1, - const QT3DSVec3 &p2, NVReal u, - NVReal v) - { - // This seems to confuse the compiler... - // return (1.0f - u - v)*p0 + u*p1 + v*p2; - const QT3DSF32 w = 1.0f - u - v; - return QT3DSVec3(w * p0.x + u * p1.x + v * p2.x, w * p0.y + u * p1.y + v * p2.y, - w * p0.z + u * p1.z + v * p2.z); - } - - // generates a pair of quaternions (swing, twist) such that in = swing * twist, with - // swing.x = 0 - // twist.y = twist.z = 0, and twist is a unit quat - QT3DS_FORCE_INLINE void separateSwingTwist(const QT3DSQuat &q, QT3DSQuat &swing, QT3DSQuat &twist) - { - twist = q.x != 0.0f ? QT3DSQuat(q.x, 0, 0, q.w).getNormalized() : QT3DSQuat::createIdentity(); - swing = q * twist.getConjugate(); - } - - // generate two tangent vectors to a given normal - QT3DS_FORCE_INLINE void normalToTangents(const QT3DSVec3 &normal, QT3DSVec3 &tangent0, QT3DSVec3 &tangent1) - { - tangent0 = NVAbs(normal.x) < 0.70710678f ? QT3DSVec3(0, -normal.z, normal.y) - : QT3DSVec3(-normal.y, normal.x, 0); - tangent0.normalize(); - tangent1 = normal.cross(tangent0); - } - - // todo: what is this function doing? - QT3DS_FOUNDATION_API QT3DSQuat computeQuatFromNormal(const QT3DSVec3 &n); - - /** - \brief computes a oriented bounding box around the scaled basis. - \param basis Input = skewed basis, Output = (normalized) orthogonal basis. - \return Bounding box extent. - */ - QT3DS_FOUNDATION_API QT3DSVec3 optimizeBoundingBox(QT3DSMat33 &basis); - - QT3DS_FOUNDATION_API QT3DSQuat slerp(const NVReal t, const QT3DSQuat &left, const QT3DSQuat &right); - - QT3DS_INLINE QT3DSVec3 ellipseClamp(const QT3DSVec3 &point, const QT3DSVec3 &radii) - { - // This function need to be implemented in the header file because - // it is included in a spu shader program. - - // finds the closest point on the ellipse to a given point - - // (p.y, p.z) is the input point - // (e.y, e.z) are the radii of the ellipse - - // lagrange multiplier method with Newton/Halley hybrid root-finder. - // see http://www.geometrictools.com/Documentation/DistancePointToEllipse2.pdf - // for proof of Newton step robustness and initial estimate. - // Halley converges much faster but sometimes overshoots - when that happens we take - // a newton step instead - - // converges in 1-2 iterations where D&C works well, and it's good with 4 iterations - // with any ellipse that isn't completely crazy - - const QT3DSU32 MAX_ITERATIONS = 20; - const NVReal convergenceThreshold = 1e-4f; - - // iteration requires first quadrant but we recover generality later - - QT3DSVec3 q(0, NVAbs(point.y), NVAbs(point.z)); - const NVReal tinyEps = - (NVReal)(1e-6f); // very close to minor axis is numerically problematic but trivial - if (radii.y >= radii.z) { - if (q.z < tinyEps) - return QT3DSVec3(0, point.y > 0 ? radii.y : -radii.y, 0); - } else { - if (q.y < tinyEps) - return QT3DSVec3(0, 0, point.z > 0 ? radii.z : -radii.z); - } - - QT3DSVec3 denom, e2 = radii.multiply(radii), eq = radii.multiply(q); - - // we can use any initial guess which is > maximum(-e.y^2,-e.z^2) and for which f(t) is > 0. - // this guess works well near the axes, but is weak along the diagonals. - - NVReal t = NVMax(eq.y - e2.y, eq.z - e2.z); - - for (QT3DSU32 i = 0; i < MAX_ITERATIONS; i++) { - denom = QT3DSVec3(0, 1 / (t + e2.y), 1 / (t + e2.z)); - QT3DSVec3 denom2 = eq.multiply(denom); - - QT3DSVec3 fv = denom2.multiply(denom2); - NVReal f = fv.y + fv.z - 1; - - // although in exact arithmetic we are guaranteed f>0, we can get here - // on the first iteration via catastrophic cancellation if the point is - // very close to the origin. In that case we just behave as if f=0 - - if (f < convergenceThreshold) - return e2.multiply(point).multiply(denom); - - NVReal df = fv.dot(denom) * -2.0f; - t = t - f / df; - } - - // we didn't converge, so clamp what we have - QT3DSVec3 r = e2.multiply(point).multiply(denom); - return r * NVRecipSqrt(sqr(r.y / radii.y) + sqr(r.z / radii.z)); - } - - QT3DS_INLINE NVReal tanHalf(NVReal sin, NVReal cos) { return sin / (1 + cos); } - - QT3DS_INLINE QT3DSQuat quatFromTanQVector(const QT3DSVec3 &v) - { - NVReal v2 = v.dot(v); - if (v2 < 1e-12f) - return QT3DSQuat::createIdentity(); - NVReal d = 1 / (1 + v2); - return QT3DSQuat(v.x * 2, v.y * 2, v.z * 2, 1 - v2) * d; - } - - QT3DS_FORCE_INLINE QT3DSVec3 cross100(const QT3DSVec3 &b) { return QT3DSVec3(0.0f, -b.z, b.y); } - QT3DS_FORCE_INLINE QT3DSVec3 cross010(const QT3DSVec3 &b) { return QT3DSVec3(b.z, 0.0f, -b.x); } - QT3DS_FORCE_INLINE QT3DSVec3 cross001(const QT3DSVec3 &b) { return QT3DSVec3(-b.y, b.x, 0.0f); } - - QT3DS_INLINE void decomposeVector(QT3DSVec3 &normalCompo, QT3DSVec3 &tangentCompo, - const QT3DSVec3 &outwardDir, const QT3DSVec3 &outwardNormal) - { - normalCompo = outwardNormal * (outwardDir.dot(outwardNormal)); - tangentCompo = outwardDir - normalCompo; - } - - //! \brief Return (i+1)%3 - // Avoid variable shift for XBox: - // QT3DS_INLINE QT3DSU32 NV::getNextIndex3(QT3DSU32 i) { return (1<> 1)) & 3; } - - QT3DS_INLINE QT3DSMat33 rotFrom2Vectors(const QT3DSVec3 &from, const QT3DSVec3 &to) - { - // See bottom of - // http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/index.htm - - // Early exit if to = from - if ((from - to).magnitudeSquared() < 1e-4f) - return QT3DSMat33::createIdentity(); - - // Early exit if to = -from - if ((from + to).magnitudeSquared() < 1e-4f) - return QT3DSMat33::createDiagonal(QT3DSVec3(1.0f, -1.0f, -1.0f)); - - QT3DSVec3 n = from.cross(to); - - NVReal C = from.dot(to), S = NVSqrt(1 - C * C), CC = 1 - C; - - NVReal xx = n.x * n.x, yy = n.y * n.y, zz = n.z * n.z, xy = n.x * n.y, yz = n.y * n.z, - xz = n.x * n.z; - - QT3DSMat33 R; - - R(0, 0) = 1 + CC * (xx - 1); - R(0, 1) = -n.z * S + CC * xy; - R(0, 2) = n.y * S + CC * xz; - - R(1, 0) = n.z * S + CC * xy; - R(1, 1) = 1 + CC * (yy - 1); - R(1, 2) = -n.x * S + CC * yz; - - R(2, 0) = -n.y * S + CC * xz; - R(2, 1) = n.x * S + CC * yz; - R(2, 2) = 1 + CC * (zz - 1); - - return R; - } - - QT3DS_FOUNDATION_API void integrateTransform(const NVTransform &curTrans, const QT3DSVec3 &linvel, - const QT3DSVec3 &angvel, NVReal timeStep, - NVTransform &result); - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMemoryBuffer.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMemoryBuffer.h deleted file mode 100644 index bee2f0c2..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMemoryBuffer.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_MEMORYBUFFER_H -#define QT3DS_FOUNDATION_MEMORYBUFFER_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSIntrinsics.h" - -#ifdef __INTEGRITY -#define __restrict -#endif - -namespace qt3ds { -namespace foundation { - using namespace intrinsics; - - template - class MemoryBuffer : public TAllocator - { - QT3DSU8 *mBegin; - QT3DSU8 *mEnd; - QT3DSU8 *mCapacityEnd; - - public: - MemoryBuffer(const TAllocator &inAlloc = TAllocator()) - : TAllocator(inAlloc) - , mBegin(0) - , mEnd(0) - , mCapacityEnd(0) - { - } - ~MemoryBuffer() - { - if (mBegin) - TAllocator::deallocate(mBegin); - } - QT3DSU32 size() const { return static_cast(mEnd - mBegin); } - QT3DSU32 capacity() const { return static_cast(mCapacityEnd - mBegin); } - QT3DSU8 *begin() { return mBegin; } - QT3DSU8 *end() { return mEnd; } - const QT3DSU8 *begin() const { return mBegin; } - const QT3DSU8 *end() const { return mEnd; } - void clear() { mEnd = mBegin; } - void write(QT3DSU8 inValue) { *growBuf(1) = inValue; } - - template - void write(const TDataType &inValue) - { - const QT3DSU8 *__restrict readPtr = reinterpret_cast(&inValue); - QT3DSU8 *__restrict writePtr = growBuf(sizeof(TDataType)); - for (QT3DSU32 idx = 0; idx < sizeof(TDataType); ++idx) - writePtr[idx] = readPtr[idx]; - } - - template - void write(const TDataType *inValue, QT3DSU32 inLength) - { - using namespace qt3ds::intrinsics; - if (inValue && inLength) { - QT3DSU32 writeSize = inLength * sizeof(TDataType); - memCopy(growBuf(writeSize), inValue, writeSize); - } - if (inLength && !inValue) { - QT3DS_ASSERT(false); - // You can't not write something, because that will cause - // the receiving end to crash. - QT3DSU32 writeSize = inLength * sizeof(TDataType); - for (QT3DSU32 idx = 0; idx < writeSize; ++idx) - write((QT3DSU8)0); - } - } - - void writeStrided(const QT3DSU8 *__restrict inData, QT3DSU32 inItemSize, QT3DSU32 inLength, - QT3DSU32 inStride) - { - if (inStride == 0 || inStride == inItemSize) - write(inData, inLength * inItemSize); - else if (inData && inLength) { - QT3DSU32 writeSize = inLength * inItemSize; - QT3DSU8 *__restrict writePtr = growBuf(writeSize); - for (QT3DSU32 idx = 0; idx < inLength; - ++idx, writePtr += inItemSize, inData += inStride) - memCopy(writePtr, inData, inItemSize); - } - } - QT3DSU8 *growBuf(QT3DSU32 inAmount) - { - QT3DSU32 offset = size(); - QT3DSU32 newSize = offset + inAmount; - reserve(newSize); - mEnd += inAmount; - return mBegin + offset; - } - void writeZeros(QT3DSU32 inAmount) - { - QT3DSU32 offset = size(); - growBuf(inAmount); - qt3ds::foundation::memZero(begin() + offset, inAmount); - } - void align(QT3DSU32 inAmount) - { - QT3DSU32 leftover = size() % inAmount; - if (leftover) - writeZeros(inAmount - leftover); - } - void reserve(QT3DSU32 newSize) - { - using namespace qt3ds::intrinsics; - QT3DSU32 currentSize = size(); - if (newSize && newSize >= capacity()) { - QT3DSU32 newDataSize = newSize * 2; - if (newDataSize > 8192) - newDataSize = (QT3DSU32)((QT3DSU32)newSize * 1.2f); - QT3DSU8 *newData = - static_cast(TAllocator::allocate(newDataSize, __FILE__, __LINE__)); - if (mBegin) { - memCopy(newData, mBegin, currentSize); - TAllocator::deallocate(mBegin); - } - mBegin = newData; - mEnd = mBegin + currentSize; - mCapacityEnd = mBegin + newDataSize; - } - } - operator NVDataRef() { return NVDataRef(begin(), size()); } - operator NVConstDataRef() const { return NVConstDataRef(begin(), size()); } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMutex.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMutex.h deleted file mode 100644 index 5b717e5c..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSMutex.h +++ /dev/null @@ -1,376 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSMUTEX_H -#define QT3DS_FOUNDATION_PSMUTEX_H - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSNoCopy.h" - -/* - * This inclusion is a best known fix for gcc 4.4.1 error: - * Creating object file for apex/src/NVAllocator.cpp ... - * In file included from apex/include/Qt3DSFoundation.h:30, - * from apex/src/NVAllocator.cpp:26: - * apex/include/Qt3DSMutex.h: In constructor 'nv::foundation::MutexT::MutexT(const Alloc&)': - * apex/include/Qt3DSMutex.h:92: error: no matching function for call to 'operator new(unsigned int, - * qt3ds::foundation::MutexImpl*&)' - * :0: note: candidates are: void* operator new(unsigned int) - */ -#include - -namespace qt3ds { -namespace foundation { -#ifdef QT3DS_FOUNDATION_NO_EXPORTS - class QT3DS_AUTOTEST_EXPORT MutexImpl -#else - class QT3DS_FOUNDATION_API MutexImpl -#endif - { - public: - /** - The constructor for Mutex creates a mutex. It is initially unlocked. - */ - MutexImpl(); - - /** - The destructor for Mutex deletes the mutex. - */ - ~MutexImpl(); - - /** - Acquire (lock) the mutex. If the mutex is already locked - by another thread, this method blocks until the mutex is - unlocked. - */ - bool lock(); - - /** - Acquire (lock) the mutex. If the mutex is already locked - by another thread, this method returns false without blocking. - */ - bool trylock(); - - /** - Release (unlock) the mutex. - */ - bool unlock(); - - /** - Size of this class. - */ - static const QT3DSU32 size; - }; - - class Mutex - { - public: - class ScopedLock : private NoCopy - { - Mutex &mMutex; - - public: - QT3DS_INLINE ScopedLock(Mutex &mutex) - : mMutex(mutex) - { - mMutex.lock(); - } - QT3DS_INLINE ~ScopedLock() { mMutex.unlock(); } - }; - - /** - The constructor for Mutex creates a mutex. It is initially unlocked. - */ - Mutex(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - mImpl = (MutexImpl *)QT3DS_ALLOC(alloc, MutexImpl::size, "MutexImpl"); - QT3DS_PLACEMENT_NEW(mImpl, MutexImpl)(); - } - - /** - The destructor for Mutex deletes the mutex. - */ - ~Mutex() - { - mImpl->~MutexImpl(); - QT3DS_FREE(mAllocator, mImpl); - } - - /** - Acquire (lock) the mutex. If the mutex is already locked - by another thread, this method blocks until the mutex is - unlocked. - */ - bool lock() const { return mImpl->lock(); } - - /** - Acquire (lock) the mutex. If the mutex is already locked - by another thread, this method returns false without blocking. - */ - bool trylock() const { return mImpl->trylock(); } - - /** - Release (unlock) the mutex. - */ - bool unlock() const { return mImpl->unlock(); } - - private: - NVAllocatorCallback &mAllocator; - MutexImpl *mImpl; - }; - - class QT3DS_FOUNDATION_API ReadWriteLock : private NoCopy - { - public: - ReadWriteLock(NVAllocatorCallback &alloc); - ~ReadWriteLock(); - - void lockReader(); - void lockWriter(); - - void unlockReader(); - void unlockWriter(); - - private: - class ReadWriteLockImpl *mImpl; - }; - - class ScopedReadLock : private NoCopy - { - public: - QT3DS_INLINE ScopedReadLock(ReadWriteLock &lock) - : mLock(lock) - { - mLock.lockReader(); - } - QT3DS_INLINE ~ScopedReadLock() { mLock.unlockReader(); } - - private: - ReadWriteLock &mLock; - }; - - class ScopedWriteLock : private NoCopy - { - public: - QT3DS_INLINE ScopedWriteLock(ReadWriteLock &lock) - : mLock(lock) - { - mLock.lockWriter(); - } - QT3DS_INLINE ~ScopedWriteLock() { mLock.unlockWriter(); } - - private: - ReadWriteLock &mLock; - }; - -/* - * Use this type of lock for mutex behaviour that must operate on SPU and PPU - * On non-PS3 platforms, it is implemented using Mutex - */ -#ifndef QT3DS_PS3 - - class AtomicLock : private NoCopy - { - Mutex mMutex; - - public: - AtomicLock(NVAllocatorCallback &alloc) - : mMutex(alloc) - { - } - - bool lock() { return mMutex.lock(); } - - bool trylock() { return mMutex.trylock(); } - - bool unlock() { return mMutex.unlock(); } - }; - - class AtomicLockCopy - { - AtomicLock *pLock; - - public: - AtomicLockCopy() - : pLock(NULL) - { - } - - AtomicLockCopy &operator=(AtomicLock &lock) - { - pLock = &lock; - return *this; - } - - bool lock() { return pLock->lock(); } - - bool trylock() { return pLock->trylock(); } - - bool unlock() { return pLock->unlock(); } - }; -#else - struct AtomicLockImpl - { - QT3DS_ALIGN(128, QT3DSU32 m_Lock); - QT3DSI32 m_LockId; - QT3DSU32 m_LockCount; - - AtomicLockImpl(); - }; - class AtomicLock //: private NoCopy - { - friend class AtomicLockCopy; - AtomicLockImpl *m_pImpl; - - public: - AtomicLock(); - - ~AtomicLock(); - - bool lock(); - - bool trylock(); - - bool unlock(); - }; - - // if an AtomicLock is copied and then the copy goes out of scope, it'll delete the atomic - // primitive - // (just a 128-byte aligned int) and cause a crash when it tries to delete it again - // This class just uses the atomic primitive without releasing it in the end. - - class AtomicLockCopy - { - AtomicLockImpl *m_pImpl; - - public: - AtomicLockCopy() - : m_pImpl(NULL) - { - } - - AtomicLockCopy(const AtomicLock &lock) - : m_pImpl(lock.m_pImpl) - { - } - - ~AtomicLockCopy() {} - - AtomicLockCopy &operator=(const AtomicLock &lock) - { - m_pImpl = lock.m_pImpl; - return *this; - } - - bool lock(); - - bool trylock(); - - bool unlock(); - }; -#endif - -#ifndef QT3DS_PS3 - - class AtomicRwLock : private NoCopy - { - ReadWriteLock m_Lock; - - public: - AtomicRwLock(NVAllocatorCallback &alloc) - : m_Lock(alloc) - { - } - - void lockReader() { m_Lock.lockReader(); } - void lockWriter() { m_Lock.lockWriter(); } - - bool tryLockReader() - { - // Todo - implement this - m_Lock.lockReader(); - return true; - } - - void unlockReader() { m_Lock.unlockReader(); } - void unlockWriter() { m_Lock.unlockWriter(); } - }; -#else - - struct AtomicRwLockImpl - { - QT3DS_ALIGN(128, volatile QT3DSU32 m_Lock); - QT3DS_ALIGN(128, volatile QT3DSU32 m_ReadCounter); - QT3DSI32 m_LockId; - QT3DSU32 m_LockCount; - - AtomicRwLockImpl(); - }; - - class AtomicRwLock : private NoCopy - { - AtomicRwLockImpl *m_pImpl; - - public: - AtomicRwLock(); - - ~AtomicRwLock(); - - void lockReader(); - - bool tryLockReader(); - - void lockWriter(); - - void unlockReader(); - - void unlockWriter(); - }; - -#endif - - class ScopedAtomicLock : private NoCopy - { - QT3DS_INLINE ScopedAtomicLock(AtomicLock &lock) - : mLock(lock) - { - mLock.lock(); - } - QT3DS_INLINE ~ScopedAtomicLock() { mLock.unlock(); } - - private: - AtomicLock &mLock; - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSNoCopy.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSNoCopy.h deleted file mode 100644 index 817f5e19..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSNoCopy.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSNOCOPY_H -#define QT3DS_FOUNDATION_PSNOCOPY_H - -#include "foundation/Qt3DS.h" - -namespace qt3ds { -namespace foundation { - class NoCopy - { - NoCopy(const NoCopy &c); - NoCopy &operator=(const NoCopy &c); - - public: - NoCopy() {} - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSOption.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSOption.h deleted file mode 100644 index 18d6c3b2..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSOption.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_OPTION_H -#define QT3DS_FOUNDATION_OPTION_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" - -namespace qt3ds { -namespace foundation { - - struct Empty - { - }; - - template - class Option - { - TDataType mData; - bool mHasValue; - - public: - Option(const TDataType &data) - : mData(data) - , mHasValue(true) - { - } - Option(const Empty &) - : mHasValue(false) - { - } - Option() - : mHasValue(false) - { - } - Option(const Option &other) - : mData(other.mData) - , mHasValue(other.mHasValue) - { - } - Option &operator=(const Option &other) - { - mData = other.mData; - mHasValue = other.mHasValue; - return *this; - } - - bool isEmpty() const { return !mHasValue; } - void setEmpty() { mHasValue = false; } - bool hasValue() const { return mHasValue; } - - const TDataType &getValue() const - { - QT3DS_ASSERT(mHasValue); - return mData; - } - TDataType &getValue() - { - QT3DS_ASSERT(mHasValue); - return mData; - } - TDataType &unsafeGetValue() { return mData; } - - operator const TDataType &() const { return getValue(); } - operator TDataType &() { return getValue(); } - - const TDataType *operator->() const { return &getValue(); } - TDataType *operator->() { return &getValue(); } - - const TDataType &operator*() const { return getValue(); } - TDataType &operator*() { return getValue(); } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPerfTimer.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPerfTimer.h deleted file mode 100644 index c63091c0..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPerfTimer.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PERFTIMER_H -#define QT3DS_FOUNDATION_PERFTIMER_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSTime.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace foundation { - - class IPerfTimer : public NVRefCounted - { - protected: - virtual ~IPerfTimer() {} - public: - // amount is in counter frequency units - virtual void Update(const char *inTag, QT3DSU64 inAmount) = 0; - // Dump current summation of timer data. - virtual void OutputTimerData(QT3DSU32 inFrameCount = 0) = 0; - virtual void ResetTimerData() = 0; - - static IPerfTimer &CreatePerfTimer(NVFoundationBase &inFoundation); - }; - - // Specialize this struct to get the perf timer in different contexts. - template - struct STimerProvider - { - static IPerfTimer &getPerfTimer(TTimerProvider &inProvider) - { - return inProvider.getPerfTimer(); - } - }; - - template - IPerfTimer &getPerfTimer(TTimerProvider &inProvider) - { - return STimerProvider::getPerfTimer(inProvider); - } - - struct SStackPerfTimer - { - IPerfTimer *m_Timer; - QT3DSU64 m_Start; - const char *m_Id; - - SStackPerfTimer(IPerfTimer &destination, const char *inId) - : m_Timer(&destination) - , m_Start(Time::getCurrentCounterValue()) - , m_Id(inId) - { - } - - SStackPerfTimer(IPerfTimer *destination, const char *inId) - : m_Timer(destination) - , m_Start(Time::getCurrentCounterValue()) - , m_Id(inId) - { - } - - ~SStackPerfTimer() - { - if (m_Timer) { - QT3DSU64 theStop = Time::getCurrentCounterValue(); - QT3DSU64 theAmount = theStop - m_Start; - m_Timer->Update(m_Id, theAmount); - } - } - }; -} -} - -#define QT3DS_FOUNDATION_PERF_SCOPED_TIMER(context, name) \ - SStackPerfTimer __perfTimer(getPerfTimer(context), #name); - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPlane.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPlane.h deleted file mode 100644 index 378c3bc9..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPlane.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_PLANE_H -#define QT3DS_FOUNDATION_QT3DS_PLANE_H - -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSMath.h" -#include "foundation/Qt3DSVec3.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/** -\brief Representation of a plane. - - Plane equation used: n.dot(v) + d = 0 -*/ -class NVPlane -{ -public: - /** - \brief Constructor - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane() {} - - /** - \brief Constructor from a normal and a distance - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(NVReal nx, NVReal ny, NVReal nz, NVReal distance) - : n(nx, ny, nz) - , d(distance) - { - } - - /** - \brief Constructor from a normal and a distance - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(const QT3DSVec3 &normal, NVReal distance) - : n(normal) - , d(distance) - { - } - - /** - \brief Constructor from a point on the plane and a normal - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(const QT3DSVec3 &point, const QT3DSVec3 &normal) - : n(normal) - , d(-point.dot(n)) // p satisfies normal.dot(p) + d = 0 - { - } - - /** - \brief Constructor from three points - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(const QT3DSVec3 &p0, const QT3DSVec3 &p1, const QT3DSVec3 &p2) - { - n = (p1 - p0).cross(p2 - p0).getNormalized(); - d = -p0.dot(n); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal distance(const QT3DSVec3 &p) const { return p.dot(n) + d; } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool contains(const QT3DSVec3 &p) const - { - return NVAbs(distance(p)) < (1.0e-7f); - } - - /** - \brief projects p into the plane - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 project(const QT3DSVec3 &p) const - { - return p - n * distance(p); - } - - /** - \brief find an arbitrary point in the plane - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 pointInPlane() const { return -n * d; } - - /** - \brief equivalent plane with unit normal - */ - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void normalize() - { - NVReal denom = 1.0f / n.magnitude(); - n *= denom; - d *= denom; - } - - QT3DSVec3 n; //!< The normal to the plane - NVReal d; //!< The distance from the origin -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPool.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPool.h deleted file mode 100644 index 5bd07f86..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPool.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_POOL_H -#define QT3DS_POOL_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSMath.h" //NVMax -#include "EASTL/vector.h" - -namespace qt3ds { -namespace foundation { - // Pool of fixed size objects. - template - class Pool - { - protected: - TAllocator mAllocator; - struct Link - { - Link *mNext; - Link(Link *next = NULL) - : mNext(next) - { - } - }; - eastl::vector mSlabs; - Link *mFreeList; - - public: - Pool(const TAllocator &alloc = TAllocator()) - : mAllocator(alloc) - , mSlabs(alloc) - , mFreeList(NULL) - { - StaticAssert::valid_expression(); - } - ~Pool() - { - for (QT3DSU32 idx = 0, end = mSlabs.size(); idx < end; ++idx) - mAllocator.deallocate(mSlabs[idx], slabSize); - mSlabs.clear(); - mFreeList = NULL; - } - void appendToFreeList(Link *inLink) - { - inLink->mNext = mFreeList; - mFreeList = inLink; - } - void appendSlabToFreeList(void *slab) - { - QT3DSU8 *newMem = reinterpret_cast(slab); - QT3DSU32 objSize = (QT3DSU32)qt3ds::NVMax(sizeof(TObjType), sizeof(Link)); - // align the memory correctly - if (objSize % alignmentInBytes) - objSize += alignmentInBytes - (objSize % alignmentInBytes); - - QT3DSU32 numObjsInSlab = slabSize / objSize; - for (QT3DSU32 idx = 0; idx < numObjsInSlab; ++idx) { - QT3DSU8 *objPtr = newMem + idx * objSize; - appendToFreeList(reinterpret_cast(objPtr)); - } - } - void allocateSlab(const char *file, int line) - { - QT3DSU32 objSize = (QT3DSU32)NVMax(sizeof(TObjType), sizeof(Link)); - // align the memory correctly - if (objSize % alignmentInBytes) - objSize += alignmentInBytes - (objSize % alignmentInBytes); - - QT3DSU8 *newMem = (QT3DSU8 *)mAllocator.allocate(slabSize, file, line); - if (newMem == NULL) - return; // out of mem, bad error - mSlabs.push_back(newMem); - appendSlabToFreeList(newMem); - } - - void *allocate(const char *file, int line) - { - if (!mFreeList) - allocateSlab(file, line); - - if (mFreeList) { - Link *retval = mFreeList; - mFreeList = retval->mNext; - return retval; - } - - return NULL; - } - - void deallocate(void *inPtr) - { -#if _DEBUG - // Ensure inPtr came from a known slab. - bool found = false; - for (QT3DSU32 idx = 0, end = mSlabs.size(); idx < end && !found; ++idx) { - QT3DSU8 *slabMem = reinterpret_cast(mSlabs[idx]); - QT3DSU8 *slabEnd = slabMem + slabSize; - QT3DSU8 *memPtr = reinterpret_cast(inPtr); - - if (memPtr >= mSlabs[idx] && memPtr < slabEnd) - found = true; - } - QT3DS_ASSERT(found); -#endif - appendToFreeList(reinterpret_cast(inPtr)); - } - - template - TObjType *construct(const TArg1 &arg1, const TArg2 &arg2, const char *file, int line) - { - TObjType *newMem = (TObjType *)allocate(file, line); - return new (newMem) TObjType(arg1, arg2); - } - - template - TObjType *construct(const TArg1 &arg1, const char *file, int line) - { - TObjType *newMem = (TObjType *)allocate(file, line); - return new (newMem) TObjType(arg1); - } - - TObjType *construct(const char *file, int line) - { - TObjType *newMem = (TObjType *)allocate(file, line); - return new (newMem) TObjType(); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPreprocessor.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPreprocessor.h deleted file mode 100644 index 371d3e67..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSPreprocessor.h +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_PREPROCESSOR_H -#define QT3DS_FOUNDATION_QT3DS_PREPROCESSOR_H - -#include -/** \addtogroup foundation - @{ -*/ - -/** -List of preprocessor defines used to configure the SDK -- NDEBUG/_DEBUG: enable asserts (exactly one needs to be defined) -- QT3DS_CHECKED: enable run time checks, mostly unused or equiv. to _DEBUG -- QT3DS_SUPPORT_VISUAL_DEBUGGER: ... -- AG_PERFMON: ... -*/ - -/** -Compiler define -*/ -#ifdef _MSC_VER -#define QT3DS_VC -#if _MSC_VER >= 1600 -#define QT3DS_VC10 -#elif _MSC_VER >= 1500 -#define QT3DS_VC9 -#elif _MSC_VER >= 1400 -#define QT3DS_VC8 -#elif _MSC_VER >= 1300 -#define QT3DS_VC7 -#else -#define QT3DS_VC6 -#endif -#elif __GNUC__ || __SNC__ -#define QT3DS_GNUC -#elif defined(__MWERKS__) -#define QT3DS_CW -#elif defined(__ghs__) -#define QT3DS_GHS -#else -#error "Unknown compiler" -#endif - -/** -Platform define -*/ -#ifdef QT3DS_VC -#ifdef _M_IX86 -#define QT3DS_X86 -#define QT3DS_WINDOWS -#elif defined(_M_X64) -#define QT3DS_X64 -#define QT3DS_WINDOWS -#elif defined(_M_PPC) -#define QT3DS_PPC -#define QT3DS_X360 -#define QT3DS_VMX -#elif defined(_M_ARM) -#define QT3DS_ARM -#define QT3DS_WIN8ARM -#define QT3DS_ARM_NEON -#else -#error "Unknown platform" -#endif -#elif defined QT3DS_GNUC -#ifdef __CELLOS_LV2__ -#define QT3DS_PS3 -#define QT3DS_VMX -#elif defined(__arm__) -#define QT3DS_ARM -#if defined(__SNC__) -#define QT3DS_PSP2 -#endif -#if defined(__ARM_PCS_VFP) -#define QT3DS_ARM_HARDFP -#else -#define QT3DS_ARM_SOFTFP -#endif -#elif defined(__aarch64__) -#define QT3DS_ARM -#elif defined(__i386__) -#define QT3DS_X86 -#define QT3DS_VMX -#elif defined(__x86_64__) -#define QT3DS_X64 -#elif defined(__ppc__) -#define QT3DS_PPC -#elif defined(__ppc64__) -#define QT3DS_PPC -#define QT3DS_PPC64 -//# elif defined(__aarch64__) -//# define QT3DS_ARM_64 -#else -#error "Unknown platform" -#endif -#if defined(ANDROID) -#define QT3DS_ANDROID -#elif defined(__linux__) -#define QT3DS_LINUX -#elif defined(__APPLE__) -#define QT3DS_APPLE -#if defined(__arm__) -#define QT3DS_APPLE_IOS -#endif -#elif defined(__CYGWIN__) -#define QT3DS_CYGWIN -#define QT3DS_LINUX -#elif defined(__QNX__) -#define QT3DS_QNX -#elif defined(_WIN32) -#define QT3DS_WINDOWS -#else -#error "Unkown OS" -#endif -#elif defined QT3DS_CW -#if defined(__PPCGEKKO__) -#if defined(RVL) -#define QT3DS_WII -#else -#define QT3DS_GC -#endif -#else -#error "Unknown platform" -#endif -#elif defined QT3DS_GHS -#define QT3DS_LINUX // INTEGRITY deviations flagged with __INTEGRITY -#if defined(__arm__) || defined(__aarch64__) || defined(__ARM64__) -#define QT3DS_ARM -#endif -#endif - -/** -DLL export macros -*/ -#ifndef QT3DS_C_EXPORT -#define QT3DS_C_EXPORT extern "C" -#endif - -/** -Define API function declaration - -QT3DS_FOUNDATION_EXPORTS - used by the DLL library (PhysXCommon) to export the API -QT3DS_FOUNDATION_NO_EXPORTS - exists because there are windows configurations where - the QT3DS_FOUNDATION_API is linked through standard -static linking -no definition - this will allow DLLs and libraries to use the exported API from PhysXCommon - -*/ -#if defined(QT3DS_WINDOWS) && !defined(__CUDACC__) -#if defined QT3DS_FOUNDATION_EXPORTS -#define QT3DS_FOUNDATION_API __declspec(dllexport) -#elif defined QT3DS_FOUNDATION_NO_EXPORTS -#define QT3DS_FOUNDATION_API -#else -#define QT3DS_FOUNDATION_API __declspec(dllimport) -#endif -#else -#define QT3DS_FOUNDATION_API -#endif - - -#if defined(QT3DS_AUTOTESTS_ENABLED) -#include -#if defined(QT3DS_BUILDING_LIBRARY) -#define QT3DS_AUTOTEST_EXPORT Q_DECL_EXPORT -#else -#define QT3DS_AUTOTEST_EXPORT Q_DECL_IMPORT -#endif -#else -#define QT3DS_AUTOTEST_EXPORT -#endif - -/** -Calling convention -*/ -#ifndef QT3DS_CALL_CONV -#if defined QT3DS_WINDOWS -#define QT3DS_CALL_CONV __cdecl -#else -#define QT3DS_CALL_CONV -#endif -#endif - -/** -Pack macros - disabled on SPU because they are not supported -*/ -#if defined(QT3DS_VC) -#define QT3DS_PUSH_PACK_DEFAULT __pragma(pack(push, 8)) -#define QT3DS_POP_PACK __pragma(pack(pop)) -#elif defined(QT3DS_GNUC) && !defined(__SPU__) -#define QT3DS_PUSH_PACK_DEFAULT _Pragma("pack(push, 8)") -#define QT3DS_POP_PACK _Pragma("pack(pop)") -#else -#define QT3DS_PUSH_PACK_DEFAULT -#define QT3DS_POP_PACK -#endif - -/** -Inline macro -*/ -#if defined(QT3DS_WINDOWS) || defined(QT3DS_X360) -#define QT3DS_INLINE inline -#ifdef QT3DS_VC -#pragma inline_depth(255) -#endif -#else -#define QT3DS_INLINE inline -#endif - -/** -Force inline macro -*/ -#if defined(QT3DS_VC) -#define QT3DS_FORCE_INLINE __forceinline -#elif defined(QT3DS_LINUX) \ - || defined(QT3DS_QNX) // Workaround; Fedora Core 3 do not agree with force inline and NVcPool -#define QT3DS_FORCE_INLINE inline -#elif defined(QT3DS_GNUC) -#define QT3DS_FORCE_INLINE inline __attribute__((always_inline)) -#else -#define QT3DS_FORCE_INLINE inline -#endif - -/** -Noinline macro -*/ -#if defined QT3DS_WINDOWS -#define QT3DS_NOINLINE __declspec(noinline) -#elif defined(QT3DS_GNUC) -#define QT3DS_NOINLINE __attribute__((noinline)) -#else -#define QT3DS_NOINLINE -#endif - -/*! restrict macro */ -#if __CUDACC__ -#define QT3DS_RESTRICT __restrict__ -#elif defined(QT3DS_GNUC) || defined(QT3DS_VC) -#define QT3DS_RESTRICT __restrict -#elif defined(QT3DS_CW) && __STDC_VERSION__ >= 199901L -#define QT3DS_RESTRICT restrict -#else -#define QT3DS_RESTRICT -#endif - -#if defined(QT3DS_WINDOWS) || defined(QT3DS_X360) -#define QT3DS_NOALIAS __declspec(noalias) -#else -#define QT3DS_NOALIAS -#endif - -/** -Alignment macros - -QT3DS_ALIGN_PREFIX and QT3DS_ALIGN_SUFFIX can be used for type alignment instead of aligning individual -variables as follows: -QT3DS_ALIGN_PREFIX(16) -struct A { -... -} QT3DS_ALIGN_SUFFIX(16); -This declaration style is parsed correctly by Visual Assist. - -*/ -#ifndef QT3DS_ALIGN -#if defined(QT3DS_VC) -#define QT3DS_ALIGN(alignment, decl) __declspec(align(alignment)) decl -#define QT3DS_ALIGN_PREFIX(alignment) __declspec(align(alignment)) -#define QT3DS_ALIGN_SUFFIX(alignment) -#elif defined(QT3DS_GNUC) -#define QT3DS_ALIGN(alignment, decl) decl __attribute__((aligned(alignment))) -#define QT3DS_ALIGN_PREFIX(alignment) -#define QT3DS_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment))) -#elif defined(QT3DS_CW) -#define QT3DS_ALIGN(alignment, decl) decl __attribute__((aligned(alignment))) -#define QT3DS_ALIGN_PREFIX(alignment) -#define QT3DS_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment))) -#else -#define QT3DS_ALIGN(alignment, decl) -#define QT3DS_ALIGN_PREFIX(alignment) -#define QT3DS_ALIGN_SUFFIX(alignment) -#endif -#endif - -/** -Deprecated marco -*/ -#if 0 // set to 1 to create warnings for deprecated functions -#define QT3DS_DEPRECATED __declspec(deprecated) -#else -#define QT3DS_DEPRECATED -#endif - -// VC6 no '__FUNCTION__' workaround -#if defined QT3DS_VC6 && !defined __FUNCTION__ -#define __FUNCTION__ "Undefined" -#endif - -/** -General defines -*/ - -// Assertion type -template -struct StaticAssert -{ -}; -// Specialisation with member function -template <> -struct StaticAssert -{ -public: - static void valid_expression(){} -}; - -// static assert -#define QT3DS_COMPILE_TIME_ASSERT(exp) typedef char NVCompileTimeAssert_Dummy[(exp) ? 1 : -1] - -#ifdef QT3DS_GNUC -#define QT3DS_OFFSET_OF(X, Y) __builtin_offsetof(X, Y) -#else -#define QT3DS_OFFSET_OF(X, Y) offsetof(X, Y) -#endif - -// avoid unreferenced parameter warning (why not just disable it?) -// PT: or why not just omit the parameter's name from the declaration???? -#define QT3DS_FORCE_PARAMETER_REFERENCE(_P) (void)(_P); -#define QT3DS_UNUSED(_P) QT3DS_FORCE_PARAMETER_REFERENCE(_P) - -// check that exactly one of NDEBUG and _DEBUG is defined -#if !(defined NDEBUG ^ defined _DEBUG) -#error Exactly one of NDEBUG and _DEBUG needs to be defined by preprocessor -#endif - -// make sure QT3DS_CHECKED is defined in all _DEBUG configurations as well -#if !defined(QT3DS_CHECKED) && _DEBUG -#define QT3DS_CHECKED -#endif - -#ifdef __CUDACC__ -#define QT3DS_CUDA_CALLABLE __host__ __device__ -#else -#define QT3DS_CUDA_CALLABLE -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_PREPROCESSOR_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSQuat.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSQuat.h deleted file mode 100644 index 2792f977..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSQuat.h +++ /dev/null @@ -1,381 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_QUAT_H -#define QT3DS_FOUNDATION_QT3DS_QUAT_H - -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSVec3.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/** -\brief This is a quaternion class. For more information on quaternion mathematics -consult a mathematics source on complex numbers. - -*/ - -class QT3DSQuat -{ -public: - /** - \brief Default constructor, does not do any initialization. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat() {} - - /** - \brief Constructor. Take note of the order of the elements! - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat(NVReal nx, NVReal ny, NVReal nz, NVReal nw) - : x(nx) - , y(ny) - , z(nz) - , w(nw) - { - } - - /** - \brief Creates from angle-axis representation. - - Axis must be normalized! - - Angle is in radians! - - Unit: Radians - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat(NVReal angleRadians, const QT3DSVec3 &unitAxis) - { - QT3DS_ASSERT(NVAbs(1.0f - unitAxis.magnitude()) < 1e-3f); - const NVReal a = angleRadians * 0.5f; - const NVReal s = NVSin(a); - w = NVCos(a); - x = unitAxis.x * s; - y = unitAxis.y * s; - z = unitAxis.z * s; - } - - /** - \brief Copy ctor. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat(const QT3DSQuat &v) - : x(v.x) - , y(v.y) - , z(v.z) - , w(v.w) - { - } - - /** - \brief Creates from orientation matrix. - - \param[in] m Rotation matrix to extract quaternion from. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE explicit QT3DSQuat(const QT3DSMat33 &m); /* defined in Qt3DSMat33.h */ - - /** - \brief returns true if all elements are finite (not NAN or INF, etc.) - */ - QT3DS_CUDA_CALLABLE bool isFinite() const - { - return NVIsFinite(x) && NVIsFinite(y) && NVIsFinite(z) && NVIsFinite(w); - } - - /** - \brief returns true if finite and magnitude is close to unit - */ - - QT3DS_CUDA_CALLABLE bool isUnit() const - { - const NVReal unitTolerance = NVReal(1e-4); - return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; - } - - /** - \brief returns true if finite and magnitude is reasonably close to unit to allow for some - accumulation of error vs isValid - */ - - QT3DS_CUDA_CALLABLE bool isSane() const - { - const NVReal unitTolerance = NVReal(1e-2); - return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; - } - - /** - \brief converts this quaternion to angle-axis representation - */ - - QT3DS_CUDA_CALLABLE QT3DS_INLINE void toRadiansAndUnitAxis(NVReal &angle, QT3DSVec3 &axis) const - { - const NVReal quatEpsilon = (NVReal(1.0e-8f)); - const NVReal s2 = x * x + y * y + z * z; - if (s2 < quatEpsilon * quatEpsilon) // can't extract a sensible axis - { - angle = 0; - axis = QT3DSVec3(1, 0, 0); - } else { - const NVReal s = NVRecipSqrt(s2); - axis = QT3DSVec3(x, y, z) * s; - angle = w < quatEpsilon ? NVPi : NVAtan2(s2 * s, w) * 2; - } - } - - /** - \brief Gets the angle between this quat and the identity quaternion. - - Unit: Radians - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal getAngle() const { return NVAcos(w) * NVReal(2); } - - /** - \brief Gets the angle between this quat and the argument - - Unit: Radians - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal getAngle(const QT3DSQuat &q) const - { - return NVAcos(dot(q)) * NVReal(2); - } - - /** - \brief This is the squared 4D vector length, should be 1 for unit quaternions. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitudeSquared() const - { - return x * x + y * y + z * z + w * w; - } - - /** - \brief returns the scalar product of this and other. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal dot(const QT3DSQuat &v) const - { - return x * v.x + y * v.y + z * v.z + w * v.w; - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat getNormalized() const - { - const NVReal s = 1.0f / magnitude(); - return QT3DSQuat(x * s, y * s, z * s, w * s); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE float magnitude() const { return NVSqrt(magnitudeSquared()); } - - // modifiers: - /** - \brief maps to the closest unit quaternion. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal normalize() // convert this QT3DSQuat to a unit quaternion - { - const NVReal mag = magnitude(); - if (mag) { - const NVReal imag = NVReal(1) / mag; - - x *= imag; - y *= imag; - z *= imag; - w *= imag; - } - return mag; - } - - /* - \brief returns the conjugate. - - \note for unit quaternions, this is the inverse. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat getConjugate() const { return QT3DSQuat(-x, -y, -z, w); } - - /* - \brief returns imaginary part. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getImaginaryPart() const { return QT3DSVec3(x, y, z); } - - /** brief computes rotation of x-axis */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getBasisVector0() const - { - // return rotate(QT3DSVec3(1,0,0)); - const QT3DSF32 x2 = x * 2.0f; - const QT3DSF32 w2 = w * 2.0f; - return QT3DSVec3((w * w2) - 1.0f + x * x2, (z * w2) + y * x2, (-y * w2) + z * x2); - } - - /** brief computes rotation of y-axis */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getBasisVector1() const - { - // return rotate(QT3DSVec3(0,1,0)); - const QT3DSF32 y2 = y * 2.0f; - const QT3DSF32 w2 = w * 2.0f; - return QT3DSVec3((-z * w2) + x * y2, (w * w2) - 1.0f + y * y2, (x * w2) + z * y2); - } - - /** brief computes rotation of z-axis */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getBasisVector2() const - { - // return rotate(QT3DSVec3(0,0,1)); - const QT3DSF32 z2 = z * 2.0f; - const QT3DSF32 w2 = w * 2.0f; - return QT3DSVec3((y * w2) + x * z2, (-x * w2) + y * z2, (w * w2) - 1.0f + z * z2); - } - - /** - rotates passed vec by this (assumed unitary) - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec3 rotate(const QT3DSVec3 &v) const - // QT3DS_CUDA_CALLABLE QT3DS_INLINE const QT3DSVec3 rotate(const QT3DSVec3& v) const - { - const QT3DSF32 vx = 2.0f * v.x; - const QT3DSF32 vy = 2.0f * v.y; - const QT3DSF32 vz = 2.0f * v.z; - const QT3DSF32 w2 = w * w - 0.5f; - const QT3DSF32 dot2 = (x * vx + y * vy + z * vz); - return QT3DSVec3((vx * w2 + (y * vz - z * vy) * w + x * dot2), - (vy * w2 + (z * vx - x * vz) * w + y * dot2), - (vz * w2 + (x * vy - y * vx) * w + z * dot2)); - /* - const QT3DSVec3 qv(x,y,z); - return (v*(w*w-0.5f) + (qv.cross(v))*w + qv*(qv.dot(v)))*2; - */ - } - - /** - inverse rotates passed vec by this (assumed unitary) - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec3 rotateInv(const QT3DSVec3 &v) const - // QT3DS_CUDA_CALLABLE QT3DS_INLINE const QT3DSVec3 rotateInv(const QT3DSVec3& v) const - { - const QT3DSF32 vx = 2.0f * v.x; - const QT3DSF32 vy = 2.0f * v.y; - const QT3DSF32 vz = 2.0f * v.z; - const QT3DSF32 w2 = w * w - 0.5f; - const QT3DSF32 dot2 = (x * vx + y * vy + z * vz); - return QT3DSVec3((vx * w2 - (y * vz - z * vy) * w + x * dot2), - (vy * w2 - (z * vx - x * vz) * w + y * dot2), - (vz * w2 - (x * vy - y * vx) * w + z * dot2)); - // const QT3DSVec3 qv(x,y,z); - // return (v*(w*w-0.5f) - (qv.cross(v))*w + qv*(qv.dot(v)))*2; - } - - /** - \brief Assignment operator - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator=(const QT3DSQuat &p) - { - x = p.x; - y = p.y; - z = p.z; - w = p.w; - return *this; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator*=(const QT3DSQuat &q) - { - const NVReal tx = w * q.x + q.w * x + y * q.z - q.y * z; - const NVReal ty = w * q.y + q.w * y + z * q.x - q.z * x; - const NVReal tz = w * q.z + q.w * z + x * q.y - q.x * y; - - w = w * q.w - q.x * x - y * q.y - q.z * z; - x = tx; - y = ty; - z = tz; - - return *this; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator+=(const QT3DSQuat &q) - { - x += q.x; - y += q.y; - z += q.z; - w += q.w; - return *this; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator-=(const QT3DSQuat &q) - { - x -= q.x; - y -= q.y; - z -= q.z; - w -= q.w; - return *this; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator*=(const NVReal s) - { - x *= s; - y *= s; - z *= s; - w *= s; - return *this; - } - - /** quaternion multiplication */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat operator*(const QT3DSQuat &q) const - { - return QT3DSQuat(w * q.x + q.w * x + y * q.z - q.y * z, w * q.y + q.w * y + z * q.x - q.z * x, - w * q.z + q.w * z + x * q.y - q.x * y, w * q.w - x * q.x - y * q.y - z * q.z); - } - - /** quaternion addition */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator+(const QT3DSQuat &q) const - { - return QT3DSQuat(x + q.x, y + q.y, z + q.z, w + q.w); - } - - /** quaternion subtraction */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator-() const { return QT3DSQuat(-x, -y, -z, -w); } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator-(const QT3DSQuat &q) const - { - return QT3DSQuat(x - q.x, y - q.y, z - q.z, w - q.w); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator*(NVReal r) const - { - return QT3DSQuat(x * r, y * r, z * r, w * r); - } - - static QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat createIdentity() { return QT3DSQuat(0, 0, 0, 1); } - - /** the quaternion elements */ - NVReal x, y, z, w; -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_QUAT_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSRefCounted.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSRefCounted.h deleted file mode 100644 index b500b5fc..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSRefCounted.h +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_REFCOUNTED_H -#define QT3DS_FOUNDATION_QT3DS_REFCOUNTED_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSNoCopy.h" - -namespace qt3ds { -namespace foundation { - /** - Marker class for objects that have a release method that is expected - to destroy or release the object. - */ - class NVReleasable - { - protected: - virtual ~NVReleasable() {} - public: - virtual void release() = 0; - }; - - template - inline void NVSafeRelease(TObjType *&item) - { - if (item) { - item->release(); - item = NULL; - } - } - - /**Scoped pointer that releases its data - when it is being destroyed*/ - template - struct NVScopedReleasable : public NoCopy - { - TObjType *mPtr; - NVScopedReleasable() - : mPtr(NULL) - { - } - NVScopedReleasable(TObjType *item) - : mPtr(item) - { - } - NVScopedReleasable(TObjType &item) - : mPtr(&item) - { - } - ~NVScopedReleasable() { NVSafeRelease(mPtr); } - - NVScopedReleasable &operator=(TObjType *inItem) - { - if (inItem != mPtr) { - if (mPtr) - mPtr->release(); - mPtr = inItem; - } - return *this; - } - - NVScopedReleasable &operator=(const NVScopedReleasable inItem) - { - QT3DS_ASSERT(false); - // try to do the right thing. - mPtr = inItem.mPtr; - const_cast &>(inItem).mPtr = NULL; - return *this; - } - - TObjType *forget_unsafe() - { - mPtr = NULL; - return mPtr; - } - - TObjType *operator->() { return mPtr; } - const TObjType *operator->() const { return mPtr; } - TObjType &operator*() { return *mPtr; } - const TObjType &operator*() const { return *mPtr; } - operator TObjType *() { return mPtr; } - operator const TObjType *() const { return mPtr; } - }; - - // Marker class for objects that are ref counted. - class NVRefCounted : public NVReleasable - { - public: - virtual void addRef() = 0; - }; - -/**Helpers to make implementing ref counted objects as concise as possible*/ -#define QT3DS_IMPLEMENT_REF_COUNT_RELEASE(alloc) \ - QT3DSI32 value = atomicDecrement(&mRefCount); \ - if (value <= 0) \ - NVDelete(alloc, this); - -#define QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(alloc) \ - void addRef() { atomicIncrement(&mRefCount); } \ - void release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(alloc); } - - -#define QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(alloc) \ - void addRef() override { atomicIncrement(&mRefCount); } \ - void release() override { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(alloc); } - - /**Safe function that checks for null before addrefing the object*/ - template - inline TObjType *NVSafeAddRef(TObjType *item) - { - if (item) { - item->addRef(); - } - return item; - } - - /**Scoped pointer that addref's its data upon acquisition and releases its data - when it is being destroyed*/ - template - struct NVScopedRefCounted - { - TObjType *mPtr; - ~NVScopedRefCounted() { NVSafeRelease(mPtr); } - NVScopedRefCounted(TObjType *item = NULL) - : mPtr(item) - { - NVSafeAddRef(mPtr); - } - NVScopedRefCounted(TObjType &item) - : mPtr(&item) - { - NVSafeAddRef(mPtr); - } - NVScopedRefCounted(const NVScopedRefCounted &other) - : mPtr(const_cast(other.mPtr)) - { - NVSafeAddRef(mPtr); - } - NVScopedRefCounted &operator=(const NVScopedRefCounted &other) - { - if (other.mPtr != mPtr) { - NVSafeRelease(mPtr); - mPtr = const_cast(other.mPtr); - NVSafeAddRef(mPtr); - } - return *this; - } - TObjType *forget_unsafe() - { - mPtr = NULL; - return mPtr; - } - - TObjType *operator->() { return mPtr; } - const TObjType *operator->() const { return mPtr; } - TObjType &operator*() { return *mPtr; } - const TObjType &operator*() const { return *mPtr; } - operator TObjType *() { return mPtr; } - operator const TObjType *() const { return mPtr; } - bool operator==(NVScopedRefCounted &inOther) const - { - return mPtr == inOther.mPtr; - } - bool operator!=(NVScopedRefCounted &inOther) const - { - return mPtr != inOther.mPtr; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSemaphore.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSemaphore.h deleted file mode 100644 index f58bb6e0..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSemaphore.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSSEMAPHORE_H -#define QT3DS_FOUNDATION_PSSEMAPHORE_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAllocatorCallback.h" - -namespace qt3ds { -namespace foundation { - class QT3DS_FOUNDATION_API Semaphore - { - public: - static const QT3DSU32 waitForever = 0xffffffff; - - Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount); - - ~Semaphore(); - - /**Decrements (locks) the semaphore. If the semaphore's value is greater than zero, - * then the decrement proceeds, and the function returns, immediately. Otherwise - * Wait for at most the given number of ms. Returns true if the Semaphore is signaled. - * Semaphore::waitForever will block forever or until the semaphore is signaled. - */ - - bool wait(QT3DSU32 milliseconds = waitForever); - - /** increments (unlocks) the semaphore */ - - void post(); - - private: - class SemaphoreImpl *mImpl; - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSimpleTypes.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSimpleTypes.h deleted file mode 100644 index d73be064..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSimpleTypes.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_QT3DS_SIMPLE_TYPES_H -#define QT3DS_FOUNDATION_QT3DS_SIMPLE_TYPES_H - -/** \addtogroup foundation - @{ -*/ - -// Platform specific types: -// Design note: Its OK to use int for general loop variables and temps. - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSPreprocessor.h" -#include "EABase/eabase.h" -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif //#ifndef QT3DS_DOXYGEN - -typedef uint8_t QT3DSU8; -typedef int8_t QT3DSI8; -typedef uint16_t QT3DSU16; -typedef int16_t QT3DSI16; -typedef uint32_t QT3DSU32; -typedef int32_t QT3DSI32; -typedef uint64_t QT3DSU64; -typedef int64_t QT3DSI64; -typedef float QT3DSF32; -typedef double QT3DSF64; -typedef QT3DSI32 IntBool; - -struct QT3DSF16 -{ - QT3DSU16 mData; -}; - -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI8) == 1); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU8) == 1); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI16) == 2); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU16) == 2); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI32) == 4); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU32) == 4); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI64) == 8); -QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU64) == 8); - -// Type ranges -#define QT3DS_MAX_I8 127 // maximum possible sbyte value, 0x7f -#define QT3DS_MIN_I8 (-128) // minimum possible sbyte value, 0x80 -#define QT3DS_MAX_U8 255U // maximum possible ubyte value, 0xff -#define QT3DS_MIN_U8 0 // minimum possible ubyte value, 0x00 -#define QT3DS_MAX_I16 32767 // maximum possible sword value, 0x7fff -#define QT3DS_MIN_I16 (-32768) // minimum possible sword value, 0x8000 -#define QT3DS_MAX_U16 65535U // maximum possible uword value, 0xffff -#define QT3DS_MIN_U16 0 // minimum possible uword value, 0x0000 -#define QT3DS_MAX_I32 2147483647 // maximum possible sdword value, 0x7fffffff -#define QT3DS_MIN_I32 (-2147483647 - 1) // minimum possible sdword value, 0x80000000 -#define QT3DS_MAX_U32 4294967295U // maximum possible udword value, 0xffffffff -#define QT3DS_MIN_U32 0 // minimum possible udword value, 0x00000000 -#define QT3DS_MAX_F32 3.4028234663852885981170418348452e+38F -// maximum possible float value -#define QT3DS_MAX_F64 DBL_MAX // maximum possible double value - -#define QT3DS_ENV_F32 FLT_EPSILON // maximum relative error of float rounding -#define QT3DS_ENV_F64 DBL_EPSILON // maximum relative error of double rounding - -#ifndef QT3DS_FOUNDATION_USE_F64 - -typedef QT3DSF32 NVReal; - -#define QT3DS_MAX_REAL QT3DS_MAX_F32 -#define QT3DS_ENV_REAL QT3DS_ENV_F32 -#define QT3DS_NORMALIZATION_EPSILON NVReal(1e-20f) - -#else - -typedef QT3DSF64 NVReal; - -#define QT3DS_MAX_REAL QT3DS_MAX_F64 -#define QT3DS_ENV_REAL QT3DS_ENV_F64 -#define QT3DS_NORMALIZATION_EPSILON NVReal(1e-180) - -#endif - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_SIMPLE_TYPES_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSStringTokenizer.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSStringTokenizer.h deleted file mode 100644 index 5229babd..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSStringTokenizer.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_STRING_TOKENIZER_H -#define QT3DS_FOUNDATION_STRING_TOKENIZER_H - -#include "EASTL/string.h" - -namespace qt3ds { -namespace foundation { - - template - class QT3DS_FOUNDATION_API StringTokenizer - { - typedef typename eastl::basic_string::size_type size_t; - - public: - StringTokenizer(const eastl::basic_string &inString, - const eastl::basic_string &inToken) - { - eastl::basic_string mStr = inString; - eastl::basic_string theTempString = inString.substr(0, inToken.length()); - - while (inToken.length() && theTempString.compare(inToken) == 0) { - mStr = mStr.substr(inToken.length()); - theTempString = mStr.substr(0, inToken.length()); - } - - theTempString = mStr.substr(mStr.length() - 1 - inToken.length()); - while (theTempString.compare(inToken) == 0) { - mStr = mStr.substr(0, mStr.length() - inToken.length()); - theTempString = mStr.substr(mStr.length() - 1 - inToken.length()); - } - - m_OriginalString = mStr; - m_Token = inToken; - m_Index = 0; - } - - eastl::basic_string GetCurrentPartition() - { - eastl::basic_string theReturnString; - if (m_Index != eastl::basic_string::npos) { - size_t theCurrentTokenIndex = m_OriginalString.find(m_Token, m_Index); - if (theCurrentTokenIndex == eastl::basic_string::npos) { - theReturnString = m_OriginalString.substr(m_Index); - } else { - theReturnString = - m_OriginalString.substr(m_Index, theCurrentTokenIndex - m_Index); - } - } - - return theReturnString; - } - - bool HasNextPartition() { return m_Index != eastl::basic_string::npos; } - - void operator++() - { - if (m_Index != eastl::basic_string::npos) { - size_t theCurrentTokenIndex = m_OriginalString.find(m_Token, m_Index); - if (theCurrentTokenIndex == eastl::basic_string::npos) { - m_Index = eastl::basic_string::npos; - } else { - m_Index = theCurrentTokenIndex + m_Token.length(); - if (m_Index > m_OriginalString.length()) - m_Index = eastl::basic_string::npos; - } - } - } - - private: - size_t m_Index; - eastl::basic_string m_Token; - eastl::basic_string m_OriginalString; - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSync.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSync.h deleted file mode 100644 index a36afaeb..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSync.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSSYNC_H -#define QT3DS_FOUNDATION_PSSYNC_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAllocatorCallback.h" - -namespace qt3ds { -namespace foundation { - class QT3DS_FOUNDATION_API Sync - { - public: - static const QT3DSU32 waitForever = 0xffffffff; - - Sync(NVAllocatorCallback &alloc); - - ~Sync(); - - /** Wait on the object for at most the given number of ms. Returns - * true if the object is signaled. Sync::waitForever will block forever - * or until the object is signaled. - */ - - bool wait(QT3DSU32 milliseconds = waitForever); - - /** Signal the synchronization object, waking all threads waiting on it */ - - void set(); - - /** Reset the synchronization object */ - - void reset(); - - private: - class SyncImpl *mImpl; - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSystem.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSystem.h deleted file mode 100644 index 84ca87d1..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSSystem.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_FOUNDATION_SYSTEM_H -#define QT3DS_FOUNDATION_SYSTEM_H - -#include "foundation/Qt3DS.h" - -namespace qt3ds { -namespace foundation { - class QT3DS_FOUNDATION_API System - { - public: - static const char *g_OS; - static const char *g_Processor; - static const char *g_BitWidth; - static const char *g_FloatingPointModel; - static const char *g_GPUType; - static const char *g_DLLExtension; - static const char *getPlatformStr(); - static const char *getPlatformGLStr(); - - private: - System(); - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSThread.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSThread.h deleted file mode 100644 index 84e169d6..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSThread.h +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSTHREAD_H -#define QT3DS_FOUNDATION_PSTHREAD_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSFoundation.h" - -// dsequeira: according to existing comment here (David Black would be my guess) -// "This is useful to reduce bus contention on tight spin locks. And it needs -// to be a macro as the xenon compiler often ignores even __forceinline." What's not -// clear is why a pause function needs inlining...? (TODO: check with XBox team) - -// todo: these need to go somewhere else - -#if defined(QT3DS_WINDOWS) -#define NVSpinLockPause() __asm pause -#elif defined(QT3DS_X360) -#define NVSpinLockPause() __asm nop -#elif defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_APPLE) || defined(QT3DS_QNX) -#define NVSpinLockPause() asm("nop") -#elif defined(QT3DS_PS3) -#define NVSpinLockPause() asm("nop") // don't know if it's correct yet... -#define QT3DS_TLS_MAX_SLOTS 64 -#elif defined(QT3DS_WII) -#define NVSpinLockPause() asm { nop } // don't know if it's correct yet... -#endif - -namespace qt3ds { -namespace foundation { - struct ThreadPriority // todo: put in some other header file - { - enum Enum { - /** - \brief High priority - */ - eHIGH = 0, - - /** - \brief Above Normal priority - */ - eABOVE_NORMAL = 1, - - /** - \brief Normal/default priority - */ - eNORMAL = 2, - - /** - \brief Below Normal priority - */ - eBELOW_NORMAL = 3, - - /** - \brief Low priority. - */ - eLOW = 4, - - eFORCE_DWORD = 0xffFFffFF - }; - }; - - /** - Thread abstraction API - */ - - class QT3DS_FOUNDATION_API Thread - { - public: - static const QT3DSU32 DEFAULT_STACK_SIZE; - typedef size_t Id; // space for a pointer or an integer - typedef void *(*ExecuteFn)(void *); - - static Id getId(); - - /** - Construct (but do not start) the thread object. Executes in the context - of the spawning thread - */ - - Thread(NVFoundationBase &foundation); - - /** - Construct and start the the thread, passing the given arg to the given fn. (pthread style) - */ - - Thread(NVFoundationBase &foundation, ExecuteFn fn, void *arg); - - /** - Deallocate all resources associated with the thread. Should be called in the - context of the spawning thread. - */ - - virtual ~Thread(); - - /** - start the thread running. Called in the context of the spawning thread. - */ - - void start(QT3DSU32 stackSize); - - /** - Violently kill the current thread. Blunt instrument, not recommended since - it can leave all kinds of things unreleased (stack, memory, mutexes...) Should - be called in the context of the spawning thread. - */ - - void kill(); - - /** - The virtual execute() method is the user defined function that will - run in the new thread. Called in the context of the spawned thread. - */ - - virtual void execute(void); - - /** - stop the thread. Signals the spawned thread that it should stop, so the - thread should check regularly - */ - - void signalQuit(); - - /** - Wait for a thread to stop. Should be called in the context of the spawning - thread. Returns false if the thread has not been started. - */ - - bool waitForQuit(); - - /** - check whether the thread is signalled to quit. Called in the context of the - spawned thread. - */ - - bool quitIsSignalled(); - - /** - Cleanly shut down this thread. Called in the context of the spawned thread. - */ - void quit(); - - /** - Change the affinity mask for this thread. - On Xbox360, sets the hardware thread to the first non-zero bit. - - Returns previous mask if successful, or zero on failure - */ - virtual QT3DSU32 setAffinityMask(QT3DSU32 mask); - - static ThreadPriority::Enum getPriority(Id threadId); - - /** Set thread priority. */ - void setPriority(ThreadPriority::Enum prio); - - /** set the thread's name */ - void setName(const char *name); - - /** Put the current thread to sleep for the given number of milliseconds */ - static void sleep(QT3DSU32 ms); - - /** Yield the current thread's slot on the CPU */ - static void yield(); - - private: - class ThreadImpl *mImpl; - }; - - QT3DS_FOUNDATION_API QT3DSU32 TlsAlloc(); - QT3DS_FOUNDATION_API void TlsFree(QT3DSU32 index); - QT3DS_FOUNDATION_API void *TlsGet(QT3DSU32 index); - QT3DS_FOUNDATION_API QT3DSU32 TlsSet(QT3DSU32 index, void *value); - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTime.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTime.h deleted file mode 100644 index 955bd7e0..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTime.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSTIME_H -#define QT3DS_FOUNDATION_PSTIME_H - -#include "foundation/Qt3DS.h" - -#if defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_QNX) -#include -#endif - -namespace qt3ds { -namespace foundation { - - struct CounterFrequencyToTensOfNanos - { - QT3DSU64 mNumerator; - QT3DSU64 mDenominator; - CounterFrequencyToTensOfNanos(QT3DSU64 inNum, QT3DSU64 inDenom) - : mNumerator(inNum) - , mDenominator(inDenom) - { - } - - // quite slow. - QT3DSU64 toTensOfNanos(QT3DSU64 inCounter) const - { - return (inCounter * mNumerator) / mDenominator; - } - }; - - class QT3DS_FOUNDATION_API Time - { - public: - typedef double Second; - static const QT3DSU64 sNumTensOfNanoSecondsInASecond = 100000000; - // This is supposedly guaranteed to not change after system boot - // regardless of processors, speedstep, etc. - static const CounterFrequencyToTensOfNanos sCounterFreq; - - static CounterFrequencyToTensOfNanos getCounterFrequency(); - - static QT3DSU64 getCurrentCounterValue(); - - // SLOW!! - // Thar be a 64 bit divide in thar! - static QT3DSU64 getCurrentTimeInTensOfNanoSeconds() - { - QT3DSU64 ticks = getCurrentCounterValue(); - return sCounterFreq.toTensOfNanos(ticks); - } - - Time(); - Second getElapsedSeconds(); - Second peekElapsedSeconds(); - Second getLastTime() const; - - private: -#if defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_APPLE) || defined(QT3DS_PSP2) \ - || defined(QT3DS_QNX) - Second mLastTime; -#else - QT3DSI64 mTickCount; -#endif - }; -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTransform.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTransform.h deleted file mode 100644 index 0fee0a81..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSTransform.h +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_TRANSFORM_H -#define QT3DS_FOUNDATION_QT3DS_TRANSFORM_H -/** \addtogroup foundation - @{ -*/ - -#include "foundation/Qt3DSQuat.h" -#include "foundation/Qt3DSPlane.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/*! -\brief class representing a rigid euclidean transform as a quaternion and a vector -*/ - -class NVTransform -{ -public: - QT3DSQuat q; - QT3DSVec3 p; - - //#define PXTRANSFORM_DEFAULT_CONSTRUCT_NAN - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform() -#ifdef PXTRANSFORM_DEFAULT_CONSTRUCT_IDENTITY - : q(0, 0, 0, 1) - , p(0, 0, 0) -#elif defined(PXTRANSFORM_DEFAULT_CONSTRUCT_NAN) -#define invalid NVSqrt(-1.0f) - : q(invalid, invalid, invalid, invalid) - , p(invalid, invalid, invalid) -#undef invalid -#endif - { - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE explicit NVTransform(const QT3DSVec3 &position) - : q(0, 0, 0, 1) - , p(position) - { - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE explicit NVTransform(const QT3DSQuat &orientation) - : q(orientation) - , p(0, 0, 0) - { - QT3DS_ASSERT(orientation.isSane()); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform(const QT3DSVec3 &p0, const QT3DSQuat &q0) - : q(q0) - , p(p0) - { - QT3DS_ASSERT(q0.isSane()); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE explicit NVTransform(const QT3DSMat44 &m); // defined in Qt3DSMat44.h - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform operator*(const NVTransform &x) const - { - QT3DS_ASSERT(x.isSane()); - return transform(x); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform getInverse() const - { - QT3DS_ASSERT(isFinite()); - return NVTransform(q.rotateInv(-p), q.getConjugate()); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 transform(const QT3DSVec3 &input) const - { - QT3DS_ASSERT(isFinite()); - return q.rotate(input) + p; - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 transformInv(const QT3DSVec3 &input) const - { - QT3DS_ASSERT(isFinite()); - return q.rotateInv(input - p); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 rotate(const QT3DSVec3 &input) const - { - QT3DS_ASSERT(isFinite()); - return q.rotate(input); - } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 rotateInv(const QT3DSVec3 &input) const - { - QT3DS_ASSERT(isFinite()); - return q.rotateInv(input); - } - - //! Transform transform to parent (returns compound transform: first src, then *this) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform transform(const NVTransform &src) const - { - QT3DS_ASSERT(src.isSane()); - QT3DS_ASSERT(isSane()); - // src = [srct, srcr] -> [r*srct + t, r*srcr] - return NVTransform(q.rotate(src.p) + p, q * src.q); - } - - /** - \brief returns true if finite and q is a unit quaternion - */ - - QT3DS_CUDA_CALLABLE bool isValid() const { return p.isFinite() && q.isFinite() && q.isUnit(); } - - /** - \brief returns true if finite and quat magnitude is reasonably close to unit to allow for some - accumulation of error vs isValid - */ - - QT3DS_CUDA_CALLABLE bool isSane() const { return isFinite() && q.isSane(); } - - /** - \brief returns true if all elems are finite (not NAN or INF, etc.) - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite() const { return p.isFinite() && q.isFinite(); } - - //! Transform transform from parent (returns compound transform: first src, then this->inverse) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform transformInv(const NVTransform &src) const - { - QT3DS_ASSERT(src.isSane()); - QT3DS_ASSERT(isFinite()); - // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr] - QT3DSQuat qinv = q.getConjugate(); - return NVTransform(qinv.rotate(src.p - p), qinv * src.q); - } - - QT3DS_CUDA_CALLABLE static QT3DS_FORCE_INLINE NVTransform createIdentity() - { - return NVTransform(QT3DSVec3(0)); - } - - /** - \brief transform plane - */ - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane transform(const NVPlane &plane) const - { - QT3DSVec3 transformedNormal = rotate(plane.n); - return NVPlane(transformedNormal, plane.d - p.dot(transformedNormal)); - } - - /** - \brief inverse-transform plane - */ - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane inverseTransform(const NVPlane &plane) const - { - QT3DSVec3 transformedNormal = rotateInv(plane.n); - return NVPlane(transformedNormal, plane.d + p.dot(plane.n)); - } -}; - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_TRANSFORM_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUnionCast.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUnionCast.h deleted file mode 100644 index a3d03555..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUnionCast.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_UNION_CAST_H -#define QT3DS_FOUNDATION_QT3DS_UNION_CAST_H - -#include "foundation/Qt3DSPreprocessor.h" - -/** \addtogroup foundation -@{ -*/ - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -template -QT3DS_FORCE_INLINE A NVUnionCast(B b) -{ - union AB { - AB(B bb) - : _b(bb) - { - } - B _b; - A _a; - } u(b); - return u._a; -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUtilities.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUtilities.h deleted file mode 100644 index cb9ae6a2..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSUtilities.h +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_PSUTILITIES_H -#define QT3DS_FOUNDATION_PSUTILITIES_H - -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSIntrinsics.h" - -namespace qt3ds { -namespace foundation { - - // PT: checked casts - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU16 to16(QT3DSU32 value) - { - QT3DS_ASSERT(value <= 0xffff); - return QT3DSU16(value); - } - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU8 to8(QT3DSU16 value) - { - QT3DS_ASSERT(value <= 0xff); - return QT3DSU8(value); - } - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU8 to8(QT3DSU32 value) - { - QT3DS_ASSERT(value <= 0xff); - return QT3DSU8(value); - } - - template - QT3DS_CUDA_CALLABLE QT3DS_INLINE void swap(T &x, T &y) - { -// crash with optimizations enabled, ticket in Sony -#ifdef QT3DS_PSP2 -#pragma control % push O = 0 -#endif - T tmp = x; - x = y; - y = tmp; -#ifdef QT3DS_PSP2 -#pragma control % pop O -#endif - } - - /*! -Get number of elements in array -*/ - template - char (&ArraySizeHelper(T (&array)[N]))[N]; -#define QT3DS_ARRAY_SIZE(_array) (sizeof(qt3ds::foundation::ArraySizeHelper(_array))) - - /*! -Sort two elements using operator< - -On return x will be the smaller of the two -*/ - template - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void order(T &x, T &y) - { - if (y < x) - swap(x, y); - } - - // most architectures can do predication on real comparisons, and on VMX, it matters - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void order(NVReal &x, NVReal &y) - { - NVReal newX = NVMin(x, y); - NVReal newY = NVMax(x, y); - x = newX; - y = newY; - } - - /*! - Sort two elements using operator< and also keep order - of any extra data - */ - template - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void order(T &x, T &y, E1 &xe1, E1 &ye1) - { - if (y < x) { - swap(x, y); - swap(xe1, ye1); - } - } - - QT3DS_INLINE void debugBreak() - { -#if defined(QT3DS_WINDOWS) - __debugbreak(); -#elif defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_QNX) - asm("int $3"); -#elif defined(QT3DS_GNUC) - __builtin_trap(); -#else - QT3DS_ASSERT(false); -#endif - } - - bool checkValid(const float &); - bool checkValid(const QT3DSVec3 &); - bool checkValid(const QT3DSQuat &); - bool checkValid(const QT3DSMat33 &); - bool checkValid(const NVTransform &); - bool checkValid(const char *); - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSI32 getPadding2(size_t value, QT3DSU32 alignment) - { - const QT3DSI32 mask = alignment - 1; - const QT3DSI32 overhead = QT3DSI32(value) & mask; - return (alignment - overhead) & mask; - } - - // PT: "After doing a dcbz128, there is a delay of about 140 cycles before writes to that cache - // line can proceed without stalling. - // This is much faster than an L2 cache miss, but for ideal performance, it is best to avoid - // this stall by doing the cache-line - // zeroing a few cache lines ahead of where you are writing." - QT3DS_FORCE_INLINE void invalidateCache(void *QT3DS_RESTRICT voidPtr, QT3DSI32 size) - { -#ifdef QT3DS_X360 - QT3DSU8 *QT3DS_RESTRICT ptr = reinterpret_cast(voidPtr); - const QT3DSI32 padding = getPadding2(size_t(ptr), 128); - const QT3DSI32 sizeToCover = size - padding; - if (sizeToCover >= 128) { - QT3DSU8 *ptr128 = ptr + padding; - QT3DSU32 nb128 = sizeToCover / 128; - while (nb128--) { - // NV::memZero128(ptr128); - qt3ds::foundation::memZero128(ptr128); - ptr128 += 128; - } - } -#else - (void)voidPtr; - (void)size; -#endif - } - - // equivalent to std::max_element - template - inline const T *maxElement(const T *first, const T *last) - { - const T *m = first; - for (const T *it = first + 1; it < last; ++it) - if (*m < *it) - m = it; - - return m; - } - -} // namespace foundation -} // namespace qt3ds - -#define QT3DS_STRINGIZE_HELPER(X) #X -#define QT3DS_STRINGIZE(X) QT3DS_STRINGIZE_HELPER(X) - -#define QT3DS_CONCAT_HELPER(X, Y) X##Y -#define QT3DS_CONCAT(X, Y) QT3DS_CONCAT_HELPER(X, Y) - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec2.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec2.h deleted file mode 100644 index 0d86c915..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec2.h +++ /dev/null @@ -1,321 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_VEC2_H -#define QT3DS_FOUNDATION_QT3DS_VEC2_H - -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSMath.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/** -\brief 2 Element vector class. - -This is a vector class with public data members. -This is not nice but it has become such a standard that hiding the xy data members -makes it difficult to reuse external code that assumes that these are public in the library. -The vector class can be made to use float or double precision by appropriately defining NVReal. -This has been chosen as a cleaner alternative to a template class. -*/ -class QT3DSVec2 -{ -public: - /** - \brief default constructor leaves data uninitialized. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2() {} - - /** - \brief Assigns scalar parameter to all elements. - - Useful to initialize to zero or one. - - \param[in] a Value to assign to elements. - */ - explicit QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2(NVReal a) - : x(a) - , y(a) - { - } - - /** - \brief Initializes from 2 scalar parameters. - - \param[in] nx Value to initialize X component. - \param[in] ny Value to initialize Y component. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2(NVReal nx, NVReal ny) - : x(nx) - , y(ny) - { - } - - /** - \brief Copy ctor. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2(const QT3DSVec2 &v) - : x(v.x) - , y(v.y) - { - } - - // Operators - - /** - \brief Assignment operator - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator=(const QT3DSVec2 &p) - { - x = p.x; - y = p.y; - return *this; - } - - /** - \brief element access - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator[](int index) - { - QT3DS_ASSERT(index >= 0 && index <= 1); - return (&x)[index]; - } - - /** - \brief element access - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal &operator[](int index) const - { - QT3DS_ASSERT(index >= 0 && index <= 1); - return (&x)[index]; - } - - /** - \brief returns true if the two vectors are exactly equal. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator==(const QT3DSVec2 &v) const - { - return x == v.x && y == v.y; - } - - /** - \brief returns true if the two vectors are not exactly equal. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator!=(const QT3DSVec2 &v) const - { - return x != v.x || y != v.y; - } - - /** - \brief tests for exact zero vector - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isZero() const { return x == 0.0f && y == 0.0f; } - - /** - \brief returns true if all 2 elems of the vector are finite (not NAN or INF, etc.) - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const { return NVIsFinite(x) && NVIsFinite(y); } - - /** - \brief is normalized - used by API parameter validation - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isNormalized() const - { - const float unitTolerance = NVReal(1e-4); - return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; - } - - /** - \brief returns the squared magnitude - - Avoids calling NVSqrt()! - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitudeSquared() const { return x * x + y * y; } - - /** - \brief returns the magnitude - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitude() const { return NVSqrt(magnitudeSquared()); } - - /** - \brief negation - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator-() const { return QT3DSVec2(-x, -y); } - - /** - \brief vector addition - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator+(const QT3DSVec2 &v) const - { - return QT3DSVec2(x + v.x, y + v.y); - } - - /** - \brief vector difference - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator-(const QT3DSVec2 &v) const - { - return QT3DSVec2(x - v.x, y - v.y); - } - - /** - \brief scalar post-multiplication - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator*(NVReal f) const - { - return QT3DSVec2(x * f, y * f); - } - - /** - \brief scalar division - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator/(NVReal f) const - { - f = NVReal(1) / f; // PT: inconsistent notation with operator /= - return QT3DSVec2(x * f, y * f); - } - - /** - \brief vector addition - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator+=(const QT3DSVec2 &v) - { - x += v.x; - y += v.y; - return *this; - } - - /** - \brief vector difference - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator-=(const QT3DSVec2 &v) - { - x -= v.x; - y -= v.y; - return *this; - } - - /** - \brief scalar multiplication - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator*=(NVReal f) - { - x *= f; - y *= f; - return *this; - } - /** - \brief scalar division - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator/=(NVReal f) - { - f = 1.0f / f; // PT: inconsistent notation with operator / - x *= f; - y *= f; - return *this; - } - - /** - \brief returns the scalar product of this and other. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal dot(const QT3DSVec2 &v) const { return x * v.x + y * v.y; } - - /** return a unit vector */ - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 getNormalized() const - { - const NVReal m = magnitudeSquared(); - return m > 0 ? *this * NVRecipSqrt(m) : QT3DSVec2(0, 0); - } - - /** - \brief normalizes the vector in place - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalize() - { - const NVReal m = magnitude(); - if (m > 0) - *this /= m; - return m; - } - - /** - \brief a[i] * b[i], for all i. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 multiply(const QT3DSVec2 &a) const - { - return QT3DSVec2(x * a.x, y * a.y); - } - - /** - \brief element-wise minimum - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 minimum(const QT3DSVec2 &v) const - { - return QT3DSVec2(NVMin(x, v.x), NVMin(y, v.y)); - } - - /** - \brief returns MIN(x, y); - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float minElement() const { return NVMin(x, y); } - - /** - \brief element-wise maximum - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 maximum(const QT3DSVec2 &v) const - { - return QT3DSVec2(NVMax(x, v.x), NVMax(y, v.y)); - } - - /** - \brief returns MAX(x, y); - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float maxElement() const { return NVMax(x, y); } - - NVReal x, y; -}; - -QT3DS_CUDA_CALLABLE static QT3DS_FORCE_INLINE QT3DSVec2 operator*(NVReal f, const QT3DSVec2 &v) -{ - return QT3DSVec2(f * v.x, f * v.y); -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_VEC2_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec3.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec3.h deleted file mode 100644 index 24ab8231..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec3.h +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_VEC3_H -#define QT3DS_FOUNDATION_QT3DS_VEC3_H - -/** \addtogroup foundation -@{ -*/ - -#include "foundation/Qt3DSMath.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -/** -\brief 3 Element vector class. - -This is a vector class with public data members. -This is not nice but it has become such a standard that hiding the xyz data members -makes it difficult to reuse external code that assumes that these are public in the library. -The vector class can be made to use float or double precision by appropriately defining NVReal. -This has been chosen as a cleaner alternative to a template class. -*/ -class QT3DSVec3 -{ -public: - /** - \brief default constructor leaves data uninitialized. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3() {} - - /** - \brief Assigns scalar parameter to all elements. - - Useful to initialize to zero or one. - - \param[in] a Value to assign to elements. - */ - explicit QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3(NVReal a) - : x(a) - , y(a) - , z(a) - { - } - - /** - \brief Initializes from 3 scalar parameters. - - \param[in] nx Value to initialize X component. - \param[in] ny Value to initialize Y component. - \param[in] nz Value to initialize Z component. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3(NVReal nx, NVReal ny, NVReal nz) - : x(nx) - , y(ny) - , z(nz) - { - } - - /** - \brief Copy ctor. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3(const QT3DSVec3 &v) - : x(v.x) - , y(v.y) - , z(v.z) - { - } - - // Operators - - /** - \brief Assignment operator - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator=(const QT3DSVec3 &p) - { - x = p.x; - y = p.y; - z = p.z; - return *this; - } - - /** - \brief element access - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator[](int index) - { - QT3DS_ASSERT(index >= 0 && index <= 2); - return (&x)[index]; - } - - /** - \brief element access - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal &operator[](int index) const - { - QT3DS_ASSERT(index >= 0 && index <= 2); - return (&x)[index]; - } - - /** - \brief returns true if the two vectors are exactly equal. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator==(const QT3DSVec3 &v) const - { - return x == v.x && y == v.y && z == v.z; - } - - /** - \brief returns true if the two vectors are not exactly equal. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator!=(const QT3DSVec3 &v) const - { - return x != v.x || y != v.y || z != v.z; - } - - /** - \brief tests for exact zero vector - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isZero() const - { - return x == 0.0f && y == 0.0f && z == 0.0f; - } - - /** - \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.) - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const - { - return NVIsFinite(x) && NVIsFinite(y) && NVIsFinite(z); - } - - /** - \brief is normalized - used by API parameter validation - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isNormalized() const - { - const float unitTolerance = NVReal(1e-4); - return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; - } - - /** - \brief returns the squared magnitude - - Avoids calling NVSqrt()! - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitudeSquared() const - { - return x * x + y * y + z * z; - } - - /** - \brief returns the magnitude - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitude() const { return NVSqrt(magnitudeSquared()); } - - /** - \brief negation - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator-() const { return QT3DSVec3(-x, -y, -z); } - - /** - \brief vector addition - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator+(const QT3DSVec3 &v) const - { - return QT3DSVec3(x + v.x, y + v.y, z + v.z); - } - - /** - \brief vector difference - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator-(const QT3DSVec3 &v) const - { - return QT3DSVec3(x - v.x, y - v.y, z - v.z); - } - - /** - \brief scalar post-multiplication - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator*(NVReal f) const - { - return QT3DSVec3(x * f, y * f, z * f); - } - - /** - \brief scalar division - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator/(NVReal f) const - { - f = NVReal(1) / f; // PT: inconsistent notation with operator /= - return QT3DSVec3(x * f, y * f, z * f); - } - - /** - \brief vector addition - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator+=(const QT3DSVec3 &v) - { - x += v.x; - y += v.y; - z += v.z; - return *this; - } - - /** - \brief vector difference - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator-=(const QT3DSVec3 &v) - { - x -= v.x; - y -= v.y; - z -= v.z; - return *this; - } - - /** - \brief scalar multiplication - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator*=(NVReal f) - { - x *= f; - y *= f; - z *= f; - return *this; - } - /** - \brief scalar division - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator/=(NVReal f) - { - f = 1.0f / f; // PT: inconsistent notation with operator / - x *= f; - y *= f; - z *= f; - return *this; - } - - /** - \brief returns the scalar product of this and other. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal dot(const QT3DSVec3 &v) const - { - return x * v.x + y * v.y + z * v.z; - } - - /** - \brief cross product - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 cross(const QT3DSVec3 &v) const - { - return QT3DSVec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); - } - - /** return a unit vector */ - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getNormalized() const - { - const NVReal m = magnitudeSquared(); - return m > 0 ? *this * NVRecipSqrt(m) : QT3DSVec3(0, 0, 0); - } - - /** - \brief normalizes the vector in place - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalize() - { - const NVReal m = magnitude(); - if (m > 0) - *this /= m; - return m; - } - - /** - \brief normalizes the vector in place. Does nothing if vector magnitude is under - QT3DS_NORMALIZATION_EPSILON. - Returns vector magnitude if >= QT3DS_NORMALIZATION_EPSILON and 0.0f otherwise. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalizeSafe() - { - const NVReal mag = magnitude(); - if (mag < QT3DS_NORMALIZATION_EPSILON) - return 0.0f; - *this *= NVReal(1) / mag; - return mag; - } - - /** - \brief normalizes the vector in place. Asserts if vector magnitude is under - QT3DS_NORMALIZATION_EPSILON. - returns vector magnitude. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalizeFast() - { - const NVReal mag = magnitude(); - QT3DS_ASSERT(mag >= QT3DS_NORMALIZATION_EPSILON); - *this *= NVReal(1) / mag; - return mag; - } - - /** - \brief a[i] * b[i], for all i. - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 multiply(const QT3DSVec3 &a) const - { - return QT3DSVec3(x * a.x, y * a.y, z * a.z); - } - - /** - \brief element-wise minimum - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 minimum(const QT3DSVec3 &v) const - { - return QT3DSVec3(NVMin(x, v.x), NVMin(y, v.y), NVMin(z, v.z)); - } - - /** - \brief returns MIN(x, y, z); - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float minElement() const { return NVMin(x, NVMin(y, z)); } - - /** - \brief element-wise maximum - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 maximum(const QT3DSVec3 &v) const - { - return QT3DSVec3(NVMax(x, v.x), NVMax(y, v.y), NVMax(z, v.z)); - } - - /** - \brief returns MAX(x, y, z); - */ - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float maxElement() const { return NVMax(x, NVMax(y, z)); } - - NVReal x, y, z; -}; - -QT3DS_CUDA_CALLABLE static QT3DS_FORCE_INLINE QT3DSVec3 operator*(NVReal f, const QT3DSVec3 &v) -{ - return QT3DSVec3(f * v.x, f * v.y, f * v.z); -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_VEC3_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec4.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec4.h deleted file mode 100644 index acccd48c..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVec4.h +++ /dev/null @@ -1,373 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_VEC4_H -#define QT3DS_FOUNDATION_QT3DS_VEC4_H -/** \addtogroup foundation -@{ -*/ -#include "foundation/Qt3DSMath.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSAssert.h" - -/** -\brief 4 Element vector class. - -This is a vector class with public data members. -This is not nice but it has become such a standard that hiding the xyz data members -makes it difficult to reuse external code that assumes that these are public in the library. -The vector class can be made to use float or double precision by appropriately defining NVReal. -This has been chosen as a cleaner alternative to a template class. -*/ -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -class QT3DSVec4 -{ -public: - /** - \brief default constructor leaves data uninitialized. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4() {} - - /** - \brief Assigns scalar parameter to all elements. - - Useful to initialize to zero or one. - - \param[in] a Value to assign to elements. - */ - explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(NVReal a) - : x(a) - , y(a) - , z(a) - , w(a) - { - } - - /** - \brief Initializes from 3 scalar parameters. - - \param[in] nx Value to initialize X component. - \param[in] ny Value to initialize Y component. - \param[in] nz Value to initialize Z component. - \param[in] nw Value to initialize W component. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(NVReal nx, NVReal ny, NVReal nz, NVReal nw) - : x(nx) - , y(ny) - , z(nz) - , w(nw) - { - } - - /** - \brief Initializes from 3 scalar parameters. - - \param[in] v Value to initialize the X, Y, and Z components. - \param[in] nw Value to initialize W component. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(const QT3DSVec3 &v, NVReal nw) - : x(v.x) - , y(v.y) - , z(v.z) - , w(nw) - { - } - - /** - \brief Initializes from an array of scalar parameters. - - \param[in] v Value to initialize with. - */ - explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(const NVReal v[]) - : x(v[0]) - , y(v[1]) - , z(v[2]) - , w(v[3]) - { - } - - /** - \brief Copy ctor. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(const QT3DSVec4 &v) - : x(v.x) - , y(v.y) - , z(v.z) - , w(v.w) - { - } - - // Operators - - /** - \brief Assignment operator - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator=(const QT3DSVec4 &p) - { - x = p.x; - y = p.y; - z = p.z; - w = p.w; - return *this; - } - - /** - \brief element access - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal &operator[](int index) - { - QT3DS_ASSERT(index >= 0 && index <= 3); - return (&x)[index]; - } - - /** - \brief element access - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE const NVReal &operator[](int index) const - { - QT3DS_ASSERT(index >= 0 && index <= 3); - return (&x)[index]; - } - - /** - \brief returns true if the two vectors are exactly equal. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool operator==(const QT3DSVec4 &v) const - { - return x == v.x && y == v.y && z == v.z && w == v.w; - } - - /** - \brief returns true if the two vectors are not exactly equal. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool operator!=(const QT3DSVec4 &v) const - { - return x != v.x || y != v.y || z != v.z || w != v.w; - } - - /** - \brief tests for exact zero vector - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isZero() const { return x == 0 && y == 0 && z == 0 && w == 0; } - - /** - \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.) - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const - { - return NVIsFinite(x) && NVIsFinite(y) && NVIsFinite(z) && NVIsFinite(w); - } - - /** - \brief is normalized - used by API parameter validation - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isNormalized() const - { - const float unitTolerance = NVReal(1e-4); - return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; - } - - /** - \brief returns the squared magnitude - - Avoids calling NVSqrt()! - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal magnitudeSquared() const - { - return x * x + y * y + z * z + w * w; - } - - /** - \brief returns the magnitude - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal magnitude() const { return NVSqrt(magnitudeSquared()); } - - /** - \brief negation - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator-() const { return QT3DSVec4(-x, -y, -z, -w); } - - /** - \brief vector addition - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator+(const QT3DSVec4 &v) const - { - return QT3DSVec4(x + v.x, y + v.y, z + v.z, w + v.w); - } - - /** - \brief vector difference - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator-(const QT3DSVec4 &v) const - { - return QT3DSVec4(x - v.x, y - v.y, z - v.z, w - v.w); - } - - /** - \brief scalar post-multiplication - */ - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator*(NVReal f) const - { - return QT3DSVec4(x * f, y * f, z * f, w * f); - } - - /** - \brief scalar division - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator/(NVReal f) const - { - f = NVReal(1) / f; - return QT3DSVec4(x * f, y * f, z * f, w * f); - } - - /** - \brief vector addition - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator+=(const QT3DSVec4 &v) - { - x += v.x; - y += v.y; - z += v.z; - w += v.w; - return *this; - } - - /** - \brief vector difference - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator-=(const QT3DSVec4 &v) - { - x -= v.x; - y -= v.y; - z -= v.z; - w -= v.w; - return *this; - } - - /** - \brief scalar multiplication - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator*=(NVReal f) - { - x *= f; - y *= f; - z *= f; - w *= f; - return *this; - } - /** - \brief scalar division - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator/=(NVReal f) - { - f = 1.0f / f; - x *= f; - y *= f; - z *= f; - w *= f; - return *this; - } - - /** - \brief returns the scalar product of this and other. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal dot(const QT3DSVec4 &v) const - { - return x * v.x + y * v.y + z * v.z + w * v.w; - } - - /** return a unit vector */ - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 getNormalized() const - { - NVReal m = magnitudeSquared(); - return m > 0 ? *this * NVRecipSqrt(m) : QT3DSVec4(0, 0, 0, 0); - } - - /** - \brief normalizes the vector in place - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal normalize() - { - NVReal m = magnitude(); - if (m > 0) - *this /= m; - return m; - } - - /** - \brief a[i] * b[i], for all i. - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 multiply(const QT3DSVec4 &a) const - { - return QT3DSVec4(x * a.x, y * a.y, z * a.z, w * a.w); - } - - /** - \brief element-wise minimum - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 minimum(const QT3DSVec4 &v) const - { - return QT3DSVec4(NVMin(x, v.x), NVMin(y, v.y), NVMin(z, v.z), NVMin(w, v.w)); - } - - /** - \brief element-wise maximum - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 maximum(const QT3DSVec4 &v) const - { - return QT3DSVec4(NVMax(x, v.x), NVMax(y, v.y), NVMax(z, v.z), NVMax(w, v.w)); - } - - QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getXYZ() const { return QT3DSVec3(x, y, z); } - - /** - \brief set vector elements to zero - */ - QT3DS_CUDA_CALLABLE QT3DS_INLINE void setZero() { x = y = z = w = NVReal(0); } - - NVReal x, y, z, w; -}; - -QT3DS_CUDA_CALLABLE static QT3DS_INLINE QT3DSVec4 operator*(NVReal f, const QT3DSVec4 &v) -{ - return QT3DSVec4(f * v.x, f * v.y, f * v.z, f * v.w); -} - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -/** @} */ -#endif // QT3DS_FOUNDATION_QT3DS_VEC4_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVersionNumber.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVersionNumber.h deleted file mode 100644 index 5942ef72..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Qt3DSVersionNumber.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* -VersionNumbers: The combination of these -numbers uniquely identifies the API, and should -be incremented when the SDK API changes. This may -include changes to file formats. - -This header is included in the main SDK header files -so that the entire SDK and everything that builds on it -is completely rebuilt when this file changes. Thus, -this file is not to include a frequently changing -build number. See BuildNumber.h for that. - -Each of these three values should stay below 255 because -sometimes they are stored in a byte. -*/ -/** \addtogroup foundation - @{ -*/ -#ifndef QT3DS_FOUNDATION_QT3DS_VERSION_NUMBER_H -#define QT3DS_FOUNDATION_QT3DS_VERSION_NUMBER_H - -#define QT3DS_FOUNDATION_VERSION_MAJOR 3 -#define QT3DS_FOUNDATION_VERSION_MINOR 3 -#define QT3DS_FOUNDATION_VERSION_BUGFIX 0 - -/** -The constant QT3DS_FOUNDATION_VERSION is used when creating certain PhysX module objects. -This is to ensure that the application is using the same header version as the library was built -with. -*/ -#define QT3DS_FOUNDATION_VERSION \ - ((QT3DS_FOUNDATION_VERSION_MAJOR << 24) + (QT3DS_FOUNDATION_VERSION_MINOR << 16) \ - + (QT3DS_FOUNDATION_VERSION_BUGFIX << 8) + 0) - -#endif // QT3DS_FOUNDATION_QT3DS_VERSION_NUMBER_H - -/** @} */ diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/SerializationTypes.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/SerializationTypes.h deleted file mode 100644 index c7fe5ce7..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/SerializationTypes.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SERIALIZATION_TYPES_H -#define QT3DS_RENDER_SERIALIZATION_TYPES_H -#include "EASTL/hash_map.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "foundation/Qt3DSContainers.h" - -namespace qt3ds { -namespace foundation { - - struct SStrRemapMap : public nvhash_map - { - typedef nvhash_map TBaseType; - SStrRemapMap(NVAllocatorCallback &inAlloc, const char *inName) - : TBaseType(inAlloc, inName) - { - } - }; - - struct SPtrOffsetMap : public nvhash_map - { - typedef nvhash_map TBaseType; - SPtrOffsetMap(NVAllocatorCallback &inAlloc, const char *inName) - : TBaseType(inAlloc, inName) - { - } - }; - - struct SWriteBuffer : public MemoryBuffer<> - { - SWriteBuffer(NVAllocatorCallback &inAlloc, const char *inName) - : MemoryBuffer<>(ForwardingAllocator(inAlloc, inName)) - { - } - }; - - // Simple data reader that mimics a string - struct SDataReader - { - QT3DSU8 *m_CurrentPtr; - QT3DSU8 *m_EndPtr; - SDataReader(QT3DSU8 *inStartPtr, QT3DSU8 *inEndPtr) - : m_CurrentPtr(inStartPtr) - , m_EndPtr(inEndPtr) - { - } - - template - TDataType *Load() - { - if ((m_CurrentPtr + sizeof(TDataType)) > m_EndPtr) { - QT3DS_ASSERT(false); - return NULL; - } - TDataType *theType = reinterpret_cast(m_CurrentPtr); - m_CurrentPtr += sizeof(TDataType); - return theType; - } - - template - void MemCopy(TDataType *dt, QT3DSU32 count) - { - if (count) { - QT3DSU32 loadSize = count * sizeof(TDataType); - QT3DSU32 amountLeft = (QT3DSU32)(m_EndPtr - m_CurrentPtr); - QT3DSU32 amountLoaded = NVMin(loadSize, amountLeft); - memCopy(dt, m_CurrentPtr, amountLoaded); - m_CurrentPtr += amountLoaded; - if (amountLoaded < loadSize) { - QT3DS_ASSERT(false); - QT3DSU8 *rawPtr = (QT3DSU8 *)dt; - rawPtr += amountLoaded; - size_t leftover = loadSize - amountLoaded; - // zeroing things out at least is an attempt to provide ordered - // data that may prevent a crash in some cases. - memZero(rawPtr, (QT3DSU32)leftover); - } - } - } - - // Don't make a habit of using this a lot. - template - TDataType &LoadRef() - { - TDataType *retval = Load(); - if (!retval) - QT3DS_ASSERT(false); - return *retval; - } - - void Align(size_t alignment) - { - size_t offset = (size_t)(m_CurrentPtr); - if (offset % alignment) - m_CurrentPtr += (alignment - (offset % alignment)); - } - - void Align() { Align(sizeof(void *)); } - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Socket.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Socket.h deleted file mode 100644 index f561ab83..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Socket.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_SOCKET_H -#define QT3DS_FOUNDATION_SOCKET_H -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSMemoryBuffer.h" - -namespace qt3ds { - -class NVFoundationBase; -namespace foundation { - - class SocketStream : public IInStream, public IOutStream, public NVRefCounted - { - public: - // set timeout for write and blocking read operations - // Setting to zero makes all operations nonblocking. - virtual void setTimeout(QT3DSU32 milliseconds) = 0; - virtual QT3DSU32 nonBlockingRead(NVDataRef ioBuffer) = 0; - virtual bool connected() = 0; - virtual void shutdown() = 0; - - // Useful to testing systems without going into the issues that a network connection can - // cause. - static NVScopedRefCounted - CreateFileStream(NVFoundationBase &fnd, const char *fname, FileOpenFlags flags); - }; - - class SocketServer : public NVRefCounted - { - public: - virtual int port() = 0; - virtual void setTimeout(QT3DSU32 milliseconds) = 0; - virtual NVScopedRefCounted nextClient() = 0; - }; - - class SocketSystem : public NVRefCounted - { - public: - // timeout of 0 means wait forever - virtual NVScopedRefCounted - createStream(const char *host, QT3DSI32 port, QT3DSU32 timeoutMilliseconds = 10000) = 0; - virtual NVScopedRefCounted createServer(QT3DSI32 port) = 0; - - static NVScopedRefCounted createSocketSystem(NVFoundationBase &fnd); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StrConvertUTF.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StrConvertUTF.h deleted file mode 100644 index 965867c9..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StrConvertUTF.h +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_RENDER_STR_CONVERT_UTF_H -#define QT3DS_RENDER_STR_CONVERT_UTF_H -#include -#include "foundation/ConvertUTF.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSSimpleTypes.h" - -namespace qt3ds { -namespace foundation { - - using namespace qt3ds; - template - struct ConverterType - { - }; - template <> - struct ConverterType - { - typedef UTF8 TConverterType; - }; - template <> - struct ConverterType - { - typedef UTF16 TConverterType; - }; - template <> - struct ConverterType - { - typedef UTF32 TConverterType; - }; - - template - struct WCharType - { - }; - - template <> - struct WCharType<2> - { - typedef char16_t TCharType; - }; - - template <> - struct WCharType<4> - { - typedef char32_t TCharType; - }; - - typedef WCharType TWCharEASTLConverter; - - template - struct UTFConversionSelector - { - }; - - template <> - struct UTFConversionSelector - { - static ConversionResult Convert(const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, - ConversionFlags flags) - { - return Q3DSConvertUTF8toUTF16(sourceStart, sourceEnd, targetStart, targetEnd, flags); - } - }; - - template <> - struct UTFConversionSelector - { - static ConversionResult Convert(const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, - ConversionFlags flags) - { - return Q3DSConvertUTF8toUTF32(sourceStart, sourceEnd, targetStart, targetEnd, flags); - } - }; - template <> - struct UTFConversionSelector - { - static ConversionResult Convert(const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) - { - return Q3DSConvertUTF16toUTF8(sourceStart, sourceEnd, targetStart, targetEnd, flags); - } - }; - template <> - struct UTFConversionSelector - { - static ConversionResult Convert(const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, - ConversionFlags flags) - { - return Q3DSConvertUTF16toUTF32(sourceStart, sourceEnd, targetStart, targetEnd, flags); - } - }; - template <> - struct UTFConversionSelector - { - static ConversionResult Convert(const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) - { - return Q3DSConvertUTF32toUTF8(sourceStart, sourceEnd, targetStart, targetEnd, flags); - } - }; - template <> - struct UTFConversionSelector - { - static ConversionResult Convert(const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, - ConversionFlags flags) - { - return Q3DSConvertUTF32toUTF16(sourceStart, sourceEnd, targetStart, targetEnd, flags); - } - }; - - // Convert into an EASTL string type. - // inSrcLen may be zero in which case we analyze the string looking for the zero element. - template - bool ConvertUTF(const TSrcType *inSrc, size_t inSrcLen, - eastl::basic_string &outString) - { - typedef typename ConverterType::TConverterType TDestUTFType; - typedef typename ConverterType::TConverterType TSrcUTFType; - if (inSrc == 0 || *inSrc == 0) { - outString.clear(); - return true; - } - - if (inSrcLen == 0) { - // empty loop intentional. - for (const TSrcType *ptr = inSrc; ptr && *ptr; ++ptr, ++inSrcLen) { - } - } - - typename eastl::basic_string::size_type capacity = - outString.capacity(); - if (capacity == 0) - outString.resize((QT3DSU32)inSrcLen * 2); - else - outString.resize(capacity); - - ConversionResult theConversionResult(conversionOK); - TDestUTFType *writePtr = NULL; - do { - writePtr = reinterpret_cast(const_cast(outString.data())); - TDestUTFType *writeEnd(writePtr + outString.size()); - const TSrcUTFType *readPtr(reinterpret_cast(inSrc)); - const TSrcUTFType *readEnd = readPtr + inSrcLen; - theConversionResult = UTFConversionSelector::Convert( - &readPtr, readEnd, &writePtr, writeEnd, lenientConversion); - if (theConversionResult == targetExhausted) { - capacity = outString.capacity() * 2; - outString.resize(capacity); - } - } while (theConversionResult == targetExhausted); - - if (theConversionResult == conversionOK) { - TDestUTFType *writeStart = - reinterpret_cast(const_cast(outString.data())); - outString.resize((QT3DSU32)(writePtr - writeStart)); - return true; - } else { - outString.clear(); - QT3DS_ASSERT(false); - return false; - } - } - -#ifdef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T - - template - bool ConvertWideUTF(const wchar_t *inSrc, size_t inSrcLen, - eastl::basic_string &outString) - { - return ConvertUTF((const TWCharEASTLConverter::TCharType *)inSrc, inSrcLen, outString); - } - -#endif -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversion.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversion.h deleted file mode 100644 index a55ebb3e..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversion.h +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_STRING_CONVERSION_H -#define QT3DS_FOUNDATION_STRING_CONVERSION_H -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Utils.h" - -namespace qt3ds { -namespace foundation { - - // Template base class so that we can convert items to and from char* and wchar_t* - // representations - template - struct StringConversion - { - bool force_compile_error; - }; - - // Write the char8_t but exlude the null terminator - // Meant to write data model values. - // Memory buffer contains a non-null-terminated - // char8_t string - struct Char8TWriter - { - MemoryBuffer &m_Buffer; - Char8TWriter(MemoryBuffer &buf) - : m_Buffer(buf) - { - } - void Write(const char8_t *value, QT3DSU32 len = 0) - { - if (isTrivial(value)) - return; - if (len == 0) - len = (QT3DSU32)StrLen(value); - m_Buffer.write(value, len); - } - void Write(char8_t value) { m_Buffer.write(value); } - void Write(bool value) { Write(value ? "True" : "False"); } - - // Takes care of long and float - template - void Write(TDataType value) - { - char8_t buf[256]; - QT3DSU32 numWritten = - StringConversion().ToStr(value, NVDataRef(buf, 256)); - if (numWritten) - Write((const char8_t *)buf); - else { - QT3DS_ASSERT(false); - } - } - - template - void Write(NVConstDataRef values, QT3DSU32 grouping = 6, QT3DSU32 tabCount = 0) - { - for (QT3DSU32 idx = 0; idx < values.size(); ++idx) { - if (idx) { - if ((idx % grouping) == 0) { - Write((char8_t)'\n'); - for (QT3DSU32 tabIdx = 0; tabIdx < tabCount; ++tabIdx) - Write((char8_t)'\t'); - } else - Write((char8_t)' '); - } - Write(values[idx]); - } - } - - void Write(NVConstDataRef values, QT3DSU32 ignored = 6) - { - (void)ignored; - if (values.size() && values[0] != 0) { - QT3DSU32 lastItem = values.size() - 1; - if (values[lastItem] == 0) - --lastItem; - Write(values.begin(), lastItem + 1); - } - } - }; - - inline bool IsWhite(char8_t value) - { - return value == '\n' || value == '\r' || value == ' ' || value == '\t'; - } - - // skip until we find whitespace. - inline char8_t *FindNextWhitespace(char8_t *input) - { - if (input == NULL) - return input; - char8_t *marker = input; - // Empty loop intentional - for (; *marker && !IsWhite(*marker); ++marker) - ; - return marker; - } - - // skip until we find something that isn't whitespace. - inline char8_t *FindNextNonWhitespace(char8_t *input) - { - if (input == NULL) - return input; - char8_t *marker = input; - // Empty loop intentional - for (; *marker && IsWhite(*marker); ++marker) - ; - return marker; - } - - // Reading is destructive in the case of floating point lists, so we may - // destroy the incoming string. - // We are assuming the string is null-terminated at end ptr. - struct Char8TReader - { - char8_t *m_StartPtr; - // Buffer used for temp storage - MemoryBuffer &m_Buffer; - Char8TReader(char8_t *sp, MemoryBuffer &buf) - : m_StartPtr(sp) - , m_Buffer(buf) - { - } - void Read(const char8_t *&outPtr) { outPtr = m_StartPtr; } - - template - void Read(TDataType &data) - { - bool success = StringConversion().StrTo(m_StartPtr, data); - QT3DS_ASSERT(success); - (void)success; - } - // Destructive operation because we can't trust - // strtod to do the right thing. On windows, for long strings, - // it calls strlen every operation thus leading to basically N^2 - // behavior - template - void ReadRef(NVDataRef data) - { - QT3DSU32 idx = 0; - m_StartPtr = FindNextNonWhitespace(m_StartPtr); - for (; idx < data.size() && m_StartPtr && *m_StartPtr; ++idx) { - char8_t *nextPtr = FindNextWhitespace(m_StartPtr); - if (nextPtr && *nextPtr) - *nextPtr = 0; - else - nextPtr = NULL; - StringConversion().StrTo(m_StartPtr, data[idx]); - m_StartPtr = nextPtr; - if (m_StartPtr) - m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1); - } - QT3DS_ASSERT(idx == data.size()); - } - - void ReadBuffer(NVConstDataRef &outBuffer) - { - if (m_StartPtr && *m_StartPtr) { - QT3DSU32 len = (QT3DSU32)strlen(m_StartPtr); - outBuffer = NVConstDataRef(m_StartPtr, len + 1); - } - } - - // Destructive operation because we can't trust - // strtod to do the right thing. On windows, for long strings, - // it calls strlen every operation thus leading to basically N^2 - // behavior - template - void ReadBuffer(NVConstDataRef &outBuffer) - { - m_Buffer.clear(); - m_StartPtr = FindNextNonWhitespace(m_StartPtr); - while (m_StartPtr && *m_StartPtr) { - char8_t *nextPtr = FindNextWhitespace(m_StartPtr); - if (nextPtr && *nextPtr) - *nextPtr = 0; - else - nextPtr = NULL; - TDataType temp; - StringConversion().StrTo(m_StartPtr, temp); - m_Buffer.write(temp); - m_StartPtr = nextPtr; - if (m_StartPtr) - m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1); - } - QT3DSU32 numItems = m_Buffer.size() / sizeof(TDataType); - if (numItems) - outBuffer = NVConstDataRef((TDataType *)m_Buffer.begin(), numItems); - else - outBuffer = NVConstDataRef(); - } - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversionImpl.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversionImpl.h deleted file mode 100644 index c49c14b4..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringConversionImpl.h +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_STRING_CONVERSION_IMPL_H -#define QT3DS_FOUNDATION_STRING_CONVERSION_IMPL_H -#include "foundation/StringConversion.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "EABase/eabase.h" -#include "foundation/StringTable.h" -#include "foundation/Utils.h" -#include "stdlib.h" -#include "stdio.h" //snprintf - -#if !defined EA_PLATFORM_WINDOWS -#define _snprintf snprintf -#endif - -namespace qt3ds { -namespace foundation { - - template <> - struct StringConversion - { - QT3DSU32 ToStr(bool item, NVDataRef buffer) - { - return static_cast( - _snprintf(buffer.begin(), buffer.size(), "%s", item ? "True" : "False")); - } - bool StrTo(const char8_t *buffer, bool &item) - { - if (AreEqualCaseless(buffer, "True")) - item = true; - else - item = false; - return true; - } - }; - - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSU8 item, NVDataRef buffer) - { - return static_cast( - _snprintf(buffer.begin(), buffer.size(), "%hu", static_cast(item))); - } - bool StrTo(const char8_t *buffer, QT3DSU8 &item) - { - item = static_cast(strtoul(buffer, NULL, 10)); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSI8 item, NVDataRef buffer) - { - return static_cast( - _snprintf(buffer.begin(), buffer.size(), "%hd", static_cast(item))); - } - bool StrTo(const char8_t *buffer, QT3DSI8 &item) - { - item = static_cast(strtol(buffer, NULL, 10)); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSU16 item, NVDataRef buffer) - { - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%hu", item)); - } - bool StrTo(const char8_t *buffer, QT3DSU16 &item) - { - item = static_cast(strtoul(buffer, NULL, 10)); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSI16 item, NVDataRef buffer) - { - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%hd", item)); - } - bool StrTo(const char8_t *buffer, QT3DSI16 &item) - { - item = static_cast(strtol(buffer, NULL, 10)); - return true; - } - }; - - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSU32 item, NVDataRef buffer) - { - // hope the buffer is big enough... - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%u", item)); - } - bool StrTo(const char8_t *buffer, QT3DSU32 &item) - { - item = strtoul(buffer, NULL, 10); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSI32 item, NVDataRef buffer) - { - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%d", (int)item)); - } - bool StrTo(const char8_t *buffer, QT3DSI32 &item) - { - item = strtol(buffer, NULL, 10); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSU64 item, NVDataRef buffer) - { -#ifdef _WIN32 - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%I64u", item)); -#else - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%lu", item)); -#endif - } - bool StrTo(const char8_t *buffer, QT3DSU64 &item) - { - item = strtoul(buffer, NULL, 10); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSI64 item, NVDataRef buffer) - { -#ifdef _WIN32 - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%I64d", item)); -#else - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%ld", item)); -#endif - } - bool StrTo(const char8_t *buffer, QT3DSI64 &item) - { - item = strtol(buffer, NULL, 10); - return true; - } - }; - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSF32 item, NVDataRef buffer) - { - return static_cast( - _snprintf(buffer.begin(), buffer.size(), "%g", static_cast(item))); - } - bool StrTo(const char8_t *buffer, QT3DSF32 &item) - { - item = (QT3DSF32)strtod(buffer, NULL); - return true; - } - }; - - template <> - struct StringConversion - { - QT3DSU32 ToStr(QT3DSF64 item, NVDataRef buffer) - { - return static_cast(_snprintf(buffer.begin(), buffer.size(), "%g", item)); - } - bool StrTo(const char8_t *buffer, QT3DSF64 &item) - { - item = strtod(buffer, NULL); - return true; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringTable.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringTable.h deleted file mode 100644 index 79529467..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringTable.h +++ /dev/null @@ -1,291 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_STRING_TABLE_H -#define QT3DS_RENDER_STRING_TABLE_H - -#if defined(_WIN32) || defined(__QNXNTO__) -#include -#ifndef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T -#define WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T -#endif -#endif -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAllocator.h" -#include "EASTL/functional.h" -#include "EABase/eabase.h" //char16_t definition -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSOption.h" - -namespace qt3ds { -namespace foundation { - typedef char8_t Qt3DSBChar; - typedef const char8_t *Qt3DSBCharPtr; - class IStringTable; - - // Serialization types, NVRenderSerializationTypes.h - struct SStrRemapMap; - struct SWriteBuffer; - - class CRegisteredString; - - // Discriminated union of either data ref or str table - // used so clients can test serialization without actually saving - // the string table out and rebooting the entire system. - class CStrTableOrDataRef - { - Option> m_DataRef; - IStringTable *m_StrTable; - - public: - CStrTableOrDataRef() - : m_StrTable(NULL) - { - } - CStrTableOrDataRef(NVDataRef inData) - : m_DataRef(inData) - { - } - CStrTableOrDataRef(IStringTable &inStrTable) - : m_StrTable(&inStrTable) - { - } - CStrTableOrDataRef(const CStrTableOrDataRef &inOther) - : m_DataRef(inOther.m_DataRef) - , m_StrTable(inOther.m_StrTable) - { - } - CStrTableOrDataRef &operator=(const CStrTableOrDataRef &inOther) - { - m_DataRef = inOther.m_DataRef; - m_StrTable = inOther.m_StrTable; - return *this; - } - bool HasStrTable() const { return m_StrTable != NULL; } - bool HasDataRef() const { return m_DataRef.hasValue(); } - NVDataRef GetDataRef() const { return *m_DataRef; } - IStringTable *GetStringTable() const - { - QT3DS_ASSERT(m_StrTable); - return m_StrTable; - } - }; - - // String that can only be constructed from strings in the string table. - // These strings are valid utf-8 strings - class CRegisteredString - { - Qt3DSBCharPtr m_String; - - public: - CRegisteredString() - : m_String("") - { - } - CRegisteredString(const CRegisteredString &inOther) - : m_String(inOther.m_String) - { - } - CRegisteredString &operator=(const CRegisteredString &inOther) - { - m_String = inOther.m_String; - return *this; - } - - bool operator==(const CRegisteredString &inStr) const { return m_String == inStr.m_String; } - // If you use this in a real map then you will get them sorted roughly by the correct - // order. - bool operator<(const char *inStr) const - { - // Ensure non-null strings to strcmp. - const char *myStr = m_String ? m_String : ""; - inStr = inStr ? inStr : ""; - int answer; - while (*myStr && *inStr) { - answer = *inStr - *myStr; - if (answer) - return answer < 0; - ++myStr; - ++inStr; - } - answer = *inStr - *myStr; - return answer < 0; - } - size_t hash() const { return eastl::hash()(reinterpret_cast(m_String)); } - operator Qt3DSBCharPtr() const { return c_str(); } - Qt3DSBCharPtr c_str() const { return m_String ? m_String : ""; } - bool IsValid() const { return m_String && *m_String; } - - // If this string is in the map, changes it to the map value. - void Remap(const SStrRemapMap &inMap); - - void Remap(const IStringTable &inTable); - - // Using m_String as an offset, if possible remap into - // inDataPtr's block of memory - void Remap(NVDataRef inDataPtr); - - void Remap(const CStrTableOrDataRef &inRef) - { - if (inRef.HasDataRef()) - Remap(inRef.GetDataRef()); - else if (inRef.HasStrTable()) - Remap(*inRef.GetStringTable()); - else { - QT3DS_ASSERT(false); - } - } - - static CRegisteredString ISwearThisHasBeenRegistered(Qt3DSBCharPtr str) - { - CRegisteredString retval; - retval.m_String = str; - return retval; - } - }; - - class IStringTable; - - class CStringHandle - { - QT3DSU32 m_Data; - - CStringHandle(QT3DSU32 hdl) - : m_Data(hdl) - { - } - - public: - CStringHandle() - : m_Data(0) - { - } - CStringHandle(const CStringHandle &other) - : m_Data(other.m_Data) - { - } - CStringHandle &operator=(const CStringHandle &other) - { - m_Data = other.m_Data; - return *this; - } - bool IsValid() const { return m_Data != 0; } - QT3DSU32 handle() const { return m_Data; } - inline const char8_t *c_str(IStringTable &strTable) const; - operator QT3DSU32() const { return m_Data; } - static CStringHandle ISwearThisHasBeenRegistered(QT3DSU32 strHandle) - { - return CStringHandle(strHandle); - } - }; - - // String table stores strings in utf-8 format and does valid utf-16,utf-32 -> utf-8 - // also converts utf8 -> either utf-32 or utf-16, depending on sizeof( wchar_t ) if - // requested. - // UICStrConvertUTF.h - // Also generates offsets that are consistent so clients can convert their strings - // to offsets during save and convert from offset to string during load regardless - // of if they load before or after this table. - class QT3DS_AUTOTEST_EXPORT IStringTable : public NVRefCounted - { - public: - // default state is for multithreaded access to be disabled. - // remember to implement in CNullStringManager in UICTestPresentation.hxx - virtual void EnableMultithreadedAccess() = 0; - virtual void DisableMultithreadedAccess() = 0; - - virtual CRegisteredString RegisterStr(Qt3DSBCharPtr str) = 0; - // utf-16->utf-8 - virtual CRegisteredString RegisterStr(const char16_t *str) = 0; - // utf-32->utf-8 - virtual CRegisteredString RegisterStr(const char32_t *str) = 0; - - virtual CStringHandle GetHandle(Qt3DSBCharPtr str) = 0; - virtual CRegisteredString HandleToStr(QT3DSU32 strHandle) = 0; - - virtual CRegisteredString RegisterStr(const wchar_t *str) = 0; - - virtual const wchar_t *GetWideStr(Qt3DSBCharPtr src) = 0; - virtual const wchar_t *GetWideStr(const wchar_t *str) = 0; - - Qt3DSBCharPtr GetNarrowStr(const wchar_t *src) { return RegisterStr(src); } - Qt3DSBCharPtr GetNarrowStr(Qt3DSBCharPtr src) { return RegisterStr(src); } - - // The string table maintains a map that will tell clients where their strings will be - // in terms of offsets into the data that the string table writes. - // This map will change each time a new string is added to the string table. - // Conversion from string -> data offset. - virtual const SStrRemapMap &GetRemapMap() = 0; - - virtual NVAllocatorCallback &GetAllocator() = 0; - - // Save to a block of memory. It is up the callers to deallocate using allocator - // from GetAllocator(). Returns a remap map that takes existing strings and changes their - // address such that they are offsets into the block of memory where this object - // started saving. Returns a map that converts registered strings into offsets of the - // written buffer. - virtual void Save(SWriteBuffer &ioBuffer) const = 0; - - // Load all the strings from inMemory. inMemory is not freed by this object - // Finally, you will need to take inMemory and call remap on all strings - // from offsets back into their correct address into inMemory. - virtual void Load(qt3ds::foundation::NVDataRef inMemory) = 0; - - static IStringTable &CreateStringTable(NVAllocatorCallback &alloc); - }; - - inline const char8_t *CStringHandle::c_str(IStringTable &strTable) const - { - return strTable.HandleToStr(m_Data); - } -} -} - -// eastl extensions to allow easy hashtable creation using string table strings. -namespace eastl { - -template <> -struct hash -{ - size_t operator()(const qt3ds::foundation::CRegisteredString &str) const { return str.hash(); } -}; - -template <> -struct equal_to -{ - bool operator()(const qt3ds::foundation::CRegisteredString &lhs, - const qt3ds::foundation::CRegisteredString &rhs) const - { - return lhs == rhs; - } -}; -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/TaggedPointer.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/TaggedPointer.h deleted file mode 100644 index aa227250..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/TaggedPointer.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_TAGGED_POINTER_H -#define QT3DS_FOUNDATION_TAGGED_POINTER_H -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace foundation { - - template - struct SPointerTag - { - /* Expected API for runtime RTTI - static CRegisteredString GetTag() { return g_dtype_specific_string; } - */ - }; - - // A pointer tagged with an identifier so we can have generic - // user data that is still somewhat typesafe. - struct STaggedPointer - { - void *m_UserData; - CRegisteredString m_Tag; - STaggedPointer() - : m_UserData(NULL) - { - } - - STaggedPointer(void *inUserData, CRegisteredString inTag) - : m_UserData(inUserData) - , m_Tag(inTag) - { - } - - template - STaggedPointer(TDataType *inType) - : m_UserData(reinterpret_cast(inType)) - , m_Tag(SPointerTag::GetTag()) - { - } - - template - TDataType *DynamicCast() const - { - if (m_Tag == SPointerTag::GetTag()) - return reinterpret_cast(m_UserData); - return NULL; - } - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/ThreadSafeQueue.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/ThreadSafeQueue.h deleted file mode 100644 index 462b6d49..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/ThreadSafeQueue.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_FOUNDATION_THREAD_SAFE_QUEUE_H -#define QT3DS_FOUNDATION_THREAD_SAFE_QUEUE_H -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSemaphore.h" -#include "EASTL/vector.h" - -namespace qt3ds { -namespace foundation { - - template - class ThreadSafeQueue - { - public: - static const QT3DSU32 MaxQueue = 0xffffffff; - - protected: - eastl::vector mQueue; - Semaphore mGetSemaphore; - Semaphore mPutSemaphore; - Mutex mMutex; - const QT3DSU32 mMaxCount; - - public: - ThreadSafeQueue(NVAllocatorCallback &alloc, QT3DSU32 maxCount = MaxQueue) - : mMutex(alloc) - , mGetSemaphore(alloc, 0, maxCount) - , mPutSemaphore(alloc, maxCount, maxCount) - , mMaxCount(maxCount) - { - mQueue.clear(); - } - - bool push(const TObjType &obj, QT3DSU32 milliseconds = MaxQueue) - { - if (mPutSemaphore.wait(milliseconds)) { - Mutex::ScopedLock __locker(mMutex); - mQueue.push_back(obj); - mGetSemaphore.post(); - return true; - } - return false; - } - - bool pop(TObjType &obj, QT3DSU32 milliseconds = 0) - { - if (mGetSemaphore.wait(milliseconds)) { - Mutex::ScopedLock __locker(mMutex); - obj = mQueue.back(); - mQueue.pop_back(); - mPutSemaphore.post(); - return true; - } - return false; - } - - bool isFull() - { - Mutex::ScopedLock __locker(mMutex); - return mQueue.size() >= mMaxCount; - } - - bool isEmpty() - { - Mutex::ScopedLock __locker(mMutex); - return mQueue.size() == 0; - } - - void clear() - { - Mutex::ScopedLock __locker(mMutex); - while (!mQueue.empty()) { - if (mGetSemaphore.wait(MaxQueue)) { - mQueue.pop_back(); - mPutSemaphore.post(); - } - } - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/TrackingAllocator.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/TrackingAllocator.h deleted file mode 100644 index 4fd58069..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/TrackingAllocator.h +++ /dev/null @@ -1,252 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_RENDER_ALLOCATOR_H -#define QT3DS_RENDER_ALLOCATOR_H -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSMutex.h" -#include "EASTL/hash_map.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSLogging.h" - -namespace qt3ds { -namespace foundation { - - // The simplest allocator. Performs no alignment nor memory checking. - struct MallocAllocator : public NVAllocatorCallback - { - void *allocate(size_t size, const char *, const char *, int, int = 0) override - { - return malloc(size); - } - void *allocate(size_t size, const char *, const char *, int, size_t, size_t) override - { - return malloc(size); - } - void deallocate(void *ptr) override { free(ptr); } - }; - - struct MemInfo - { - size_t size; - void *originalAddress; - const char *name; - const char *file; - int line; - MemInfo(size_t _size = 0, void *addr = 0, const char *_name = "", const char *_file = "", - int _line = 0) - : size(_size) - , originalAddress(addr) - , name(_name) - , file(_file) - , line(_line) - { - } - }; - - struct FileAndLine - { - const char *mFile; - QT3DSU32 mLine; - FileAndLine(const char *f, QT3DSU32 l) - : mFile(f) - , mLine(l) - { - } - }; -} // namespace foundation -} // namespace qt3ds - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const qt3ds::foundation::FileAndLine &fl) const - { - return hash()((const void *)fl.mFile) ^ hash()(fl.mLine); - } -}; - -template <> -struct equal_to -{ - bool operator()(const qt3ds::foundation::FileAndLine &fl1, - const qt3ds::foundation::FileAndLine &fl2) const - { - size_t fl1File(reinterpret_cast(fl1.mFile)); - size_t fl2File(reinterpret_cast(fl2.mFile)); - - return fl1File == fl2File && fl1.mLine == fl2.mLine; - } -}; -} - -namespace qt3ds { -namespace foundation { - - struct MemInfoAndCount : MemInfo - { - QT3DSU32 mCount; - QT3DSU64 mTotalBytes; - MemInfoAndCount(const MemInfo &info) - : MemInfo(info) - , mCount(1) - , mTotalBytes(info.size) - { - } - void increment(const MemInfo &otherInfo) - { - ++mCount; - mTotalBytes += otherInfo.size; - } - }; - - typedef nvhash_map TFileAndLineMemHash; - - class AllocationCheckPrinter - { - protected: - virtual ~AllocationCheckPrinter() {} - public: - virtual void printMissing(const MemInfoAndCount &item) = 0; - virtual void printIncorrectCount(const MemInfoAndCount &later, - const MemInfoAndCount &earlier) = 0; - }; - - // All allocations are 16 byte aligned. - // Prints out unallocated memory at destruction. - class QT3DS_AUTOTEST_EXPORT CAllocator : public NVAllocatorCallback - { - public: - typedef Mutex TMutexType; - typedef Mutex::ScopedLock TLockType; - typedef nvhash_map PtrToInfoMap; - - private: - MallocAllocator mAlloc; - PtrToInfoMap mAllocations; - PtrToInfoMap mStoredAllocations; - TMutexType mMutex; - - public: - CAllocator() - : mAllocations(mAlloc, "MemInfo") - , mStoredAllocations(mAlloc, "MemInfo") - , mMutex(mAlloc) - { - } - virtual ~CAllocator(); - - void *allocate(size_t size, const char *tn, const char *fl, int ln, int flags) override - { - QT3DS_ASSERT(size); - if (size) { - size += 15; - TLockType locker(mMutex); - void *original = mAlloc.allocate(size, tn, fl, ln, flags); - size_t temp = (size_t)original; - temp = (temp + 15) & (~15); - void *retval = (void *)temp; - mAllocations.insert(eastl::make_pair(retval, MemInfo(size, original, tn, fl, ln))); - return retval; - } - return NULL; - } - void *allocate(size_t size, const char *tn, const char *fl, int ln, size_t, size_t) override - { - return allocate(size, tn, fl, ln, 0); - } - void deallocate(void *ptr) override - { - if (ptr) { - TLockType locker(mMutex); - PtrToInfoMap::iterator entry(mAllocations.find(ptr)); - if (entry != mAllocations.end()) { - mAlloc.deallocate(entry->second.originalAddress); - mAllocations.erase(ptr); - } else { - QT3DS_ASSERT(false); - } - } - } - const PtrToInfoMap &getOutstandingAllocations() const { return mAllocations; } - static void convert(const CAllocator::PtrToInfoMap &map, TFileAndLineMemHash &fl) - { - for (CAllocator::PtrToInfoMap::const_iterator iter = map.begin(), end = map.end(); - iter != end; ++iter) { - const MemInfo &info(iter->second); - FileAndLine flKey(info.file, info.line); - TFileAndLineMemHash::const_iterator find(fl.find(flKey)); - if (find == fl.end()) - fl.insert(eastl::make_pair(flKey, MemInfoAndCount(info))); - else - const_cast(find->second).increment(info); - } - } - static void copyMap(const CAllocator::PtrToInfoMap &map1, CAllocator::PtrToInfoMap &map2) - { - for (CAllocator::PtrToInfoMap::const_iterator iter = map1.begin(), end = map1.end(); - iter != end; ++iter) { - map2.insert(eastl::make_pair(iter->first, iter->second)); - } - } - - static void printDiffs(const TFileAndLineMemHash &fl1, const TFileAndLineMemHash &fl2, - AllocationCheckPrinter &printer) - { - using namespace std; - for (TFileAndLineMemHash::const_iterator iter = fl1.begin(), end = fl1.end(); - iter != end; ++iter) { - TFileAndLineMemHash::const_iterator entry = fl2.find(iter->first); - if (entry != fl2.end()) { - printer.printMissing(iter->second); - } else if (iter->second.mCount > entry->second.mCount) { - printer.printIncorrectCount(iter->second, entry->second); - } - } - } - - void printAllocationDiff(AllocationCheckPrinter &printer) - { - TFileAndLineMemHash map1fl(mAlloc, "printAllocationDiff"); - TFileAndLineMemHash map2fl(mAlloc, "printAllocationDiff"); - convert(mStoredAllocations, map1fl); - convert(mAllocations, map2fl); - printDiffs(map2fl, map1fl, printer); - } - void storeAllocations() - { - mStoredAllocations.clear(); - copyMap(mAllocations, mStoredAllocations); - } - bool hasStoredAllocations() { return mStoredAllocations.size() > 0; } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Utils.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Utils.h deleted file mode 100644 index 33c24004..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/Utils.h +++ /dev/null @@ -1,382 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_UTILS_H -#define QT3DS_RENDER_UTILS_H -#include "EASTL/hash_map.h" -#include "EASTL/hash_set.h" -#include "EASTL/vector.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSMath.h" -#include - -namespace qt3ds { -namespace foundation { - - // Defined in IStringTable.cpp - extern const char16_t *char16EmptyStr; - extern const char32_t *char32EmptyStr; - - inline const char *nonNull(const char *src) { return src == NULL ? "" : src; } - inline bool isTrivial(const char *str) { return str == NULL || *str == 0; } - inline const char16_t *nonNull(const char16_t *src) - { - return src == NULL ? char16EmptyStr : src; - } - inline bool isTrivial(const char16_t *str) { return str == NULL || *str == 0; } - inline const char32_t *nonNull(const char32_t *src) - { - return src == NULL ? char32EmptyStr : src; - } - inline bool isTrivial(const char32_t *str) { return str == NULL || *str == 0; } - - // Note this is safe to call on null strings. - template - inline QT3DSU32 StrLen(const TCharType *inType) - { - QT3DSU32 retval = 0; - while (inType && *inType) { - ++retval; - ++inType; - } - return retval; - } - - template - inline QT3DSI32 Compare(const TCharType *inLhs, const TCharType *inRhs) - { - inLhs = nonNull(inLhs); - inRhs = nonNull(inRhs); - while (*inLhs && *inRhs) { - QT3DSI32 diff = *inLhs - *inRhs; - if (diff) - return diff; - ++inLhs; - ++inRhs; - } - return *inLhs - *inRhs; - } - - template - inline QT3DSI32 CompareCaseless(const TCharType *inLhs, const TCharType *inRhs) - { - inLhs = nonNull(inLhs); - inRhs = nonNull(inRhs); - while (*inLhs && *inRhs) { - QT3DSI32 diff = tolower(*inLhs) - tolower(*inRhs); - if (diff) - return diff; - ++inLhs; - ++inRhs; - } - return *inLhs - *inRhs; - } - - template - inline QT3DSI32 CompareNChars(const TCharType *inLhs, const TCharType *inRhs, QT3DSU32 inNumChars) - { - inLhs = nonNull(inLhs); - inRhs = nonNull(inRhs); - while (*inLhs && *inRhs && inNumChars) { - QT3DSI32 diff = *inLhs - *inRhs; - if (diff) - return diff; - ++inLhs; - ++inRhs; - --inNumChars; - } - if (inNumChars) - return *inLhs - *inRhs; - return 0; - } - - template - bool AreEqual(const TCharType *inLhs, const TCharType *inRhs) - { - return Compare(inLhs, inRhs) == 0; - } - - template - bool AreEqualCaseless(const TCharType *inLhs, const TCharType *inRhs) - { - return CompareCaseless(inLhs, inRhs) == 0; - } - - inline QT3DSU32 IsBitSetInBitmap(NVConstDataRef bitmap, QT3DSU32 entryIndex) - { - QT3DSU32 bitMapIndex = entryIndex / 32; - QT3DSU32 bitIndex = entryIndex % 32; - QT3DSU32 shouldApply = 0; - if (bitMapIndex < bitmap.mSize) - shouldApply = (1 << bitIndex) & bitmap[bitMapIndex]; - return shouldApply; - } - - inline void SetBitInBitmap(nvvector &bitmap, QT3DSU32 entryIndex) - { - QT3DSU32 bitMapIndex = entryIndex / 32; - QT3DSU32 bitIndex = entryIndex % 32; - while (bitmap.size() <= bitMapIndex) - bitmap.push_back(0); - bitmap[bitMapIndex] |= (QT3DSU32)(1 << bitIndex); - } - inline void UnsetBitInBitmap(nvvector &bitmap, QT3DSU32 entryIndex) - { - QT3DSU32 bitMapIndex = entryIndex / 32; - QT3DSU32 bitIndex = entryIndex % 32; - if (bitMapIndex < bitmap.size()) - bitmap[bitMapIndex] &= ~((QT3DSU32)(1 << bitIndex)); - } - -#define CHECK_CONDITION_AND_RETURN_FALSE(cond, errorType, message) \ - if (cond) { \ - m_Foundation.error(errorType, message); \ - QT3DS_ASSERT(false); \ - return false; \ - } -// Returns false if the property type doesn't match the incoming type. -#define CHECK_CONDITION_AND_RETURN(cond, errorType, message) \ - if (cond) { \ - m_Foundation.error(errorType, message); \ - QT3DS_ASSERT(false); \ - } - -#define QT3DS_FOREACH(varname, stop) for (QT3DSU32 varname = 0, end = stop; varname < end; ++varname) - - template - QT3DSU32 GetMapKeysOp(const eastl::hash_map &map, - TBufType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx, TOperator op) - { - QT3DSU32 numItems = static_cast(map.size()); - if (numItems == 0 || bufSize == 0) - return 0; - - startIdx = NVMin(numItems - 1, startIdx); - QT3DSU32 retval = 0; - for (typename eastl::hash_map::const_iterator iter = map.begin(), - end = map.end(); - iter != end && bufSize; ++iter) { - if (startIdx) - --startIdx; - else { - buffer[retval] = op(iter->first); - --bufSize; - ++retval; - } - } - return retval; - } - - struct IdOp - { - template - TDataType operator()(const TDataType &item) - { - return item; - } - }; - - template - QT3DSU32 - GetMapKeys(const eastl::hash_map &map, - TKeyType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx) - { - return GetMapKeysOp(map, buffer, bufSize, startIdx, IdOp()); - } - - struct DerefOp - { - template - TDataType operator()(const TDataType *item) - { - return *item; - } - }; - - template - QT3DSU32 GetMapValues( - const eastl::hash_map &map, - TBufType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx, TOp op) - { - QT3DSU32 numItems = static_cast(map.size()); - if (numItems == 0 || bufSize == 0) - return 0; - - startIdx = NVMin(numItems - 1, startIdx); - QT3DSU32 retval = 0; - for (typename eastl::hash_map::const_iterator iter = map.begin(), - end = map.end(); - iter != end && bufSize; ++iter) { - if (startIdx) - --startIdx; - else { - buffer[retval] = op(iter->second); - --bufSize; - ++retval; - } - } - return retval; - } - - template - QT3DSU32 GetArrayEntries(const nvvector &data, TBufType *buffer, QT3DSU32 bufSize, - QT3DSU32 startIdx) - { - QT3DSU32 numItems = static_cast(data.size()); - if (numItems == 0 || bufSize == 0) - return 0; - - startIdx = NVMin(numItems - 1, startIdx); - QT3DSU32 available = NVMin(numItems - startIdx, bufSize); - QT3DS_FOREACH(idx, available) - buffer[idx] = data[idx + startIdx]; - return available; - } - - template - QT3DSU32 GetDataRefEntries(const NVDataRef &data, TBufType *buffer, QT3DSU32 bufSize, - QT3DSU32 startIdx) - { - QT3DSU32 numItems = static_cast(data.size()); - if (numItems == 0 || bufSize == 0) - return 0; - - startIdx = NVMin(numItems - 1, startIdx); - QT3DSU32 available = NVMin(numItems - startIdx, bufSize); - QT3DS_FOREACH(idx, available) - buffer[idx] = data.mData[idx + startIdx]; - return available; - } - - template - QT3DSU32 GetDataRefEntries(const NVConstDataRef &data, TBufType *buffer, QT3DSU32 bufSize, - QT3DSU32 startIdx) - { - QT3DSU32 numItems = static_cast(data.size()); - if (numItems == 0 || bufSize == 0) - return 0; - - startIdx = NVMin(numItems - 1, startIdx); - QT3DSU32 available = NVMin(numItems - startIdx, bufSize); - QT3DS_FOREACH(idx, available) - buffer[idx] = data.mData[idx + startIdx]; - return available; - } - - template - QT3DSU32 GetHashSetEntries(eastl::hash_set &data, - TKeyType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx) - { - QT3DSU32 numItems = static_cast(data.size()); - if (numItems == 0 || bufSize == 0) - return 0; - startIdx = NVMin(numItems - 1, startIdx); - QT3DSU32 available = NVMin(numItems - startIdx, bufSize); - QT3DSU32 idx = 0; - for (typename eastl::hash_set::const_iterator - iter = data.begin(), - end = data.end(); - iter != end && idx < available; ++iter, ++idx) { - if (startIdx) { - --startIdx; - continue; - } - buffer[idx] = *iter; - } - return available; - } - - template - void memCopyT(TDataType *dest, const TDataType *src, QT3DSU32 size) - { - memCopy(dest, src, size * sizeof(TDataType)); - } - - template - NVDataRef PtrAtOffset(QT3DSU8 *baseData, QT3DSU32 offset, QT3DSU32 byteSize) - { - return NVDataRef(byteSize ? (TDataType *)(baseData + offset) : NULL, - byteSize / sizeof(TDataType)); - } - - struct char_hasher - { - size_t operator()(const char *item) const { return eastl::hash()(item); } - }; - - struct char_equal_to - { - bool operator()(const char *lhs, const char *rhs) const - { - if (lhs == NULL) - lhs = ""; - if (rhs == NULL) - rhs = ""; - return strcmp(lhs, rhs) == 0; - } - }; - - struct wide_char_hasher - { - size_t operator()(const char16_t *item) const - { - return eastl::hash()(item); - } - }; - - struct wide_char_equal_to - { - bool operator()(const char16_t *lhs, const char16_t *rhs) const - { - if (lhs == NULL) - lhs = reinterpret_cast(L""); - if (rhs == NULL) - rhs = reinterpret_cast(L""); - while (*lhs && *rhs) { - int answer = *lhs - *rhs; - if (answer) - return false; - ++lhs; - ++rhs; - } - return *lhs == *rhs; - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/XML.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/XML.h deleted file mode 100644 index 360bfdd7..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/XML.h +++ /dev/null @@ -1,680 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_FOUNDATION_XML_H -#define QT3DS_FOUNDATION_XML_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "foundation/StringConversion.h" //Conversion between string and various datatypes. -#include "foundation/Qt3DSFlags.h" -#include "EASTL/algorithm.h" -#include "foundation/IOStreams.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" - -namespace qt3ds { -namespace foundation { - - class IStringTable; - - class IDOMFactory; - - class IInStream; - class IOutStream; - struct SDOMAttribute; - struct SDOMElement; - struct SNamespacePairNode; - - typedef const char8_t *TXMLCharPtr; - - typedef eastl::basic_string TXMLStr; - - // When the factor is destroyed, all elements and attributes are destroyed. - class IDOMFactory : public NVRefCounted - { - protected: - virtual ~IDOMFactory() {} - public: - // Str does not need to be null terminated. - virtual void AppendStrBuf(TXMLCharPtr str, QT3DSU32 len) = 0; - // Null terminate what is there and return the buffer. - // This pointer needs to be persistent. - virtual TXMLCharPtr FinalizeStrBuf() = 0; - virtual void IgnoreStrBuf() = 0; - - virtual SDOMAttribute *NextAttribute(CRegisteredString name, TXMLCharPtr val, - CRegisteredString ns = CRegisteredString(), - int inLine = 0) = 0; - virtual SDOMElement *NextElement(CRegisteredString name, - CRegisteredString ns = CRegisteredString(), - int inLine = 0) = 0; - virtual SNamespacePairNode *NextNSPairNode(CRegisteredString ns, - CRegisteredString abbr) = 0; - - TXMLCharPtr RegisterValue(TXMLCharPtr inValue); - - virtual NVScopedRefCounted GetStringTable() = 0; - virtual NVAllocatorCallback &GetAllocator() = 0; - - static NVScopedRefCounted - CreateDOMFactory(NVAllocatorCallback &inAllocator, - NVScopedRefCounted inStrTable); - }; - - struct SDOMAttribute - { - CRegisteredString m_Namespace; - CRegisteredString m_Name; - const char8_t *m_Value; - SDOMAttribute *m_NextAttribute; - SDOMAttribute *m_PreviousAttribute; - int m_Line; - SDOMAttribute() - : m_Value(NULL) - , m_NextAttribute(NULL) - , m_PreviousAttribute(NULL) - , m_Line(0) - { - } - - SDOMAttribute(CRegisteredString inName, CRegisteredString inNs, const char8_t *inValue, - int line) - : m_Namespace(inNs) - , m_Name(inName) - , m_Value(inValue) - , m_NextAttribute(NULL) - , m_PreviousAttribute(NULL) - , m_Line(line) - { - } - - bool Value(const char8_t *&outValue) - { - outValue = m_Value; - return true; - } - - template - bool Value(TDataType &outValue) - { - StringConversion().StrTo(m_Value, outValue); - return true; - } - }; - - struct SNextAttOp - { - SDOMAttribute *get(SDOMAttribute &inAtt) { return inAtt.m_NextAttribute; } - const SDOMAttribute *get(const SDOMAttribute &inAtt) { return inAtt.m_NextAttribute; } - void set(SDOMAttribute &inAtt, SDOMAttribute *next) { inAtt.m_NextAttribute = next; } - }; - struct SPrevAttOp - { - SDOMAttribute *get(SDOMAttribute &inAtt) { return inAtt.m_PreviousAttribute; } - const SDOMAttribute *get(const SDOMAttribute &inAtt) { return inAtt.m_PreviousAttribute; } - void set(SDOMAttribute &inAtt, SDOMAttribute *prev) { inAtt.m_PreviousAttribute = prev; } - }; - - typedef InvasiveLinkedList TAttributeList; - - struct SNamespacePair - { - CRegisteredString m_Namespace; - CRegisteredString m_Abbreviation; - SNamespacePair(CRegisteredString ns = CRegisteredString(), - CRegisteredString abbr = CRegisteredString()) - : m_Namespace(ns) - , m_Abbreviation(abbr) - { - } - }; - - struct SNamespacePairNode : public SNamespacePair - { - SNamespacePairNode *m_NextNode; - SNamespacePairNode(const SNamespacePair &inSrc = SNamespacePair()) - : SNamespacePair(inSrc) - , m_NextNode(NULL) - { - } - }; - - // Simplified dom element. All it has is one character value and list of attributes - // and children. So you can't mix elements and character data like you can in - // full xml, but this simplifies parsing. - struct SDOMElement - { - struct SNextElemOp - { - SDOMElement *get(SDOMElement &elem) { return elem.m_NextSibling; } - const SDOMElement *get(const SDOMElement &elem) { return elem.m_NextSibling; } - void set(SDOMElement &elem, SDOMElement *next) { elem.m_NextSibling = next; } - }; - struct SPrevElemOp - { - SDOMElement *get(SDOMElement &elem) { return elem.m_PreviousSibling; } - const SDOMElement *get(const SDOMElement &elem) { return elem.m_PreviousSibling; } - void set(SDOMElement &elem, SDOMElement *prev) { elem.m_PreviousSibling = prev; } - }; - typedef InvasiveLinkedList TElementChildList; - - CRegisteredString m_Namespace; - CRegisteredString m_Name; - const char8_t *m_Value; - SDOMElement *m_Parent; - SDOMElement *m_NextSibling; - SDOMElement *m_PreviousSibling; - TAttributeList m_Attributes; - TElementChildList m_Children; - int m_Line; - - SDOMElement() - : m_Value(NULL) - , m_Parent(NULL) - , m_NextSibling(NULL) - , m_PreviousSibling(NULL) - , m_Line(0) - { - } - - SDOMElement(CRegisteredString name, CRegisteredString ns, int inLine) - : m_Namespace(ns) - , m_Name(name) - , m_Value(NULL) - , m_Parent(NULL) - , m_NextSibling(NULL) - , m_PreviousSibling(NULL) - , m_Line(inLine) - { - } - - void AppendChild(SDOMElement &inElem, SDOMElement *inPos = NULL) - { - if (inElem.m_Parent) - inElem.m_Parent->RemoveChild(inElem); - inElem.m_Parent = this; - if (inPos) { - QT3DS_ASSERT(inPos->m_Parent == this); - m_Children.insert_after(*inPos, inElem); - } else - m_Children.push_back(inElem); - } - - void PrependChild(SDOMElement &inElem, SDOMElement *inPos = NULL) - { - if (inElem.m_Parent) - inElem.m_Parent->RemoveChild(inElem); - inElem.m_Parent = this; - if (inPos) { - QT3DS_ASSERT(inPos->m_Parent == this); - m_Children.insert_before(*inPos, inElem); - } else - m_Children.push_front(inElem); - } - - void RemoveChild(SDOMElement &inElem) - { - if (inElem.m_Parent == this) { - m_Children.remove(inElem); - } else { - if (inElem.m_Parent) { - QT3DS_ASSERT(false); - } - } - } - SDOMElement *FindNext(CRegisteredString inName, Option inNamespace, - TElementChildList::iterator iter) - { - for (TElementChildList::iterator end(NULL); iter != end; ++iter) { - if (inName.IsValid() == false || inName == iter->m_Name) { - if (inNamespace.hasValue() == false || *inNamespace == iter->m_Namespace) - return &(*iter); - } - } - return NULL; - } - // Search starts just *after inStartPos if provided - SDOMElement *FindChild(CRegisteredString inName, Option inNamespace, - SDOMElement *inStartPos = NULL) - { - TElementChildList::iterator iter = m_Children.begin(); - if (inStartPos) { - QT3DS_ASSERT(inStartPos->m_Parent == this); - iter = TElementChildList::iterator(inStartPos->m_NextSibling); - } - return FindNext(inName, inNamespace, iter); - } - // Search starts just *after inStartPos if provided - SDOMElement *FindSibling(CRegisteredString inName, Option inNamespace) - { - TElementChildList::iterator iter(m_NextSibling); - return FindNext(inName, inNamespace, iter); - } - - SDOMAttribute *FindAttribute(CRegisteredString inName, - Option inNamespace) - { - for (TAttributeList::iterator iter = m_Attributes.begin(), end = m_Attributes.end(); - iter != end; ++iter) { - if (iter->m_Name == inName) { - if (inNamespace.hasValue() == false || *inNamespace == iter->m_Namespace) - return &(*iter); - } - } - return NULL; - } - - template - bool AttValue(CRegisteredString inName, Option inNamespace, - TDataType &outValue) - { - SDOMAttribute *att = FindAttribute(inName, inNamespace); - if (att) - return att->Value(outValue); - return false; - } - - QT3DSU32 GetNumChildren(CRegisteredString inName, - Option inNamespace = Empty()) const - { - QT3DSU32 count = 0; - if (inName.IsValid() == false) { - // empty loop intentional - for (TElementChildList::iterator iter = m_Children.begin(), end = m_Children.end(); - iter != end; ++iter, ++count) - ; - } else { - for (TElementChildList::iterator iter = m_Children.begin(), end = m_Children.end(); - iter != end; ++iter) { - if (iter->m_Name == inName - && (inNamespace.isEmpty() || iter->m_Namespace == *inNamespace)) - ++count; - } - } - return count; - } - - void SetAttributeValue(CRegisteredString inName, Option inNamespace, - TXMLCharPtr inValue, IDOMFactory &inFactory, int inLine) - { - SDOMAttribute *att = FindAttribute(inName, inNamespace); - if (att) { - att->m_Value = inFactory.RegisterValue(inValue); - } else { - m_Attributes.push_back(*inFactory.NextAttribute( - inName, inValue, inNamespace.unsafeGetValue(), inLine)); - } - } - - void RemoveAttribute(CRegisteredString nm, Option inNamespace) - { - SDOMAttribute *theAttribute = FindAttribute(nm, inNamespace); - if (theAttribute) - m_Attributes.remove(*theAttribute); - } - }; - - struct SReaderScope - { - SDOMElement *m_Element; - SDOMAttribute *m_Attribute; - SReaderScope(SDOMElement *inElem = NULL, SDOMAttribute *inAtt = NULL) - : m_Element(inElem) - , m_Attribute(inAtt) - { - } - }; - - class IDOMReader : public NVRefCounted - { - protected: - virtual ~IDOMReader() {} - public: - // Stack object to save the reader's state. - struct Scope - { - IDOMReader &m_Reader; - Scope(IDOMReader &reader) - : m_Reader(reader) - { - m_Reader.PushScope(); - } - Scope(NVScopedRefCounted reader) - : m_Reader(*reader) - { - m_Reader.PushScope(); - } - ~Scope() { m_Reader.PopScope(); } - }; - - // Parse buffer - MemoryBuffer m_TempBuf; - NVScopedRefCounted m_StringTable; - - IDOMReader(NVAllocatorCallback &inAlloc, NVScopedRefCounted inStringTable) - : m_TempBuf(ForwardingAllocator(inAlloc, "IDOMReader::m_TempBuf")) - , m_StringTable(inStringTable) - { - } - - NVScopedRefCounted GetStringTable() { return m_StringTable; } - - // Pushing scope saves your state so no matter where you are when - // you next pop scope, you come back to the same state. - virtual void PushScope() = 0; - virtual void PopScope() = 0; - - // Sometimes pushing and popping scope isn't enough and you need - // somewhat random access to scope. - // This scope does not remember the current attribute. - virtual SReaderScope GetScope() = 0; - virtual void SetScope(SReaderScope inScope) = 0; - // Return an attribute whose value is *not* registered with the string table. - // You can't hold onto this value for any length of time, but when you need to - // immediately convert to a different value this is the most efficient way. - virtual bool UnregisteredAtt(TXMLCharPtr name, TXMLCharPtr &outValue, - TXMLCharPtr ns = NULL) = 0; - // Return an attribute whose value *is* registered with the string table. - virtual bool Att(TXMLCharPtr name, CRegisteredString &outValue, TXMLCharPtr ns = NULL) = 0; - virtual SDOMAttribute *GetFirstAttribute() = 0; - virtual SDOMAttribute *GetNextAttribute() = 0; - virtual QT3DSU32 CountChildren(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) = 0; - virtual bool MoveToFirstChild(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) = 0; - virtual bool MoveToNextSibling(TXMLCharPtr siblingName = NULL, TXMLCharPtr ns = NULL) = 0; - // Leave element means go to its parent. - virtual void Leave() = 0; - virtual SDOMElement *GetElement() const = 0; - CRegisteredString GetElementName() const - { - SDOMElement *elem = GetElement(); - if (elem) - return elem->m_Name; - return CRegisteredString(); - } - - // Value is the concatentated text node values inside the element - virtual bool Value(TXMLCharPtr &outValue) = 0; - - // Get the element this reader was created with - virtual SDOMElement *GetTopElement() = 0; - - bool Att(TXMLCharPtr name, TXMLStr &outValue) - { - TXMLCharPtr temp; - if (UnregisteredAtt(name, temp)) { - outValue.assign(temp); - return true; - } - return false; - } - - template - bool Att(TXMLCharPtr name, TDataType &outValue) - { - TXMLCharPtr temp; - if (UnregisteredAtt(name, temp)) { - StringConversion().StrTo(temp, outValue); - return true; - } else { - return false; - } - } - - bool ChildValue(TXMLCharPtr name, TXMLCharPtr &value) - { - if (MoveToFirstChild(name)) { - Value(value); - Leave(); - return true; - } - return false; - } - - bool RegisteredChildValue(TXMLCharPtr name, TXMLCharPtr &value) - { - if (MoveToFirstChild(name)) { - RegisteredValue(value); - Leave(); - return true; - } - return false; - } - bool RegisteredValue(TXMLCharPtr &outValue) - { - bool retval = Value(outValue); - if (retval) - outValue = m_StringTable->RegisterStr(outValue); - return retval; - } - - template - bool Value(TDataType &outValue) - { - TXMLCharPtr value; - if (Value(value)) { - StringConversion().StrTo(value, outValue); - return true; - } - return false; - } - - // IDOMReader implementations - template - bool ValueList(NVDataRef data) - { - const char8_t *value; - if (Value(value)) { - Char8TReader reader(const_cast(value), m_TempBuf); - reader.ReadRef(data); - } - return true; - } - - // Destructive operation because we can't trust - // strtod to do the right thing. On windows, for long strings, - // it calls strlen every operation thus leading to basically N^2 - // behavior - template - NVConstDataRef ChildValueList(TXMLCharPtr listName) - { - NVConstDataRef retval; - TXMLCharPtr childValue = NULL; - if (ChildValue(listName, childValue)) { - Char8TReader reader(const_cast(childValue), m_TempBuf); - reader.ReadBuffer(retval); - } - return retval; - } - - template - void Serialize(const char8_t *elemName, TSerializer &serializer, - const char8_t *inNamespace = NULL) - { - IDOMReader::Scope __theScope(*this); - if (MoveToFirstChild(elemName, inNamespace)) { - serializer.Serialize(*this); - } - } - // Optionally hold on to the factory to keep our elements in memory as long as we are. - static NVScopedRefCounted CreateDOMReader( - NVAllocatorCallback &inAlloc, SDOMElement &inRootElement, - NVScopedRefCounted inStringTable, - NVScopedRefCounted inFactory = NVScopedRefCounted()); - }; - - // Write out data in an xml-like fasion without specifying exactly - // where that data is being written. - class IDOMWriter : public NVRefCounted - { - protected: - virtual ~IDOMWriter() {} - public: - // Control the element scope. - struct Scope - { - IDOMWriter &m_Writer; - Scope(IDOMWriter &writer, TXMLCharPtr inElemName, TXMLCharPtr inNamespace = NULL) - : m_Writer(writer) - { - m_Writer.Begin(inElemName, inNamespace); - } - ~Scope() { m_Writer.End(); } - }; - - char8_t m_NarrowBuf[256]; - - // There tend to be two types of elements. - // Containers (\n\t\n) - // and Values onetwothree - virtual void Begin(TXMLCharPtr inElemName, TXMLCharPtr inNamespace = NULL, - int inLine = 0) = 0; - // Attributes. They may be sorted just before write - virtual void Att(TXMLCharPtr name, TXMLCharPtr value, TXMLCharPtr inNamespace = NULL, - int inLine = 0) = 0; - virtual void Value(TXMLCharPtr value) = 0; - virtual void End() = 0; - virtual void RemoveCurrent() = 0; - virtual void RemoveAttribute(TXMLCharPtr inItem, TXMLCharPtr inNamespace = NULL) = 0; - // Get the number of tabs required to line up the next line - // with the opening of the previous line - virtual QT3DSU32 GetTabs() = 0; - virtual SDOMElement *GetTopElement() = 0; - virtual NVScopedRefCounted GetFactory() = 0; - // Move this item before this sibling. Function does not rearrange the - // tree in any major way and will not work if inItem and inSibling aren't - // siblings. - virtual void MoveBefore(TXMLCharPtr inItem, TXMLCharPtr inSibling, - TXMLCharPtr inNamespace = NULL) = 0; - virtual NVAllocatorCallback &GetAllocator() = 0; - - virtual void ChildValue(TXMLCharPtr name, TXMLCharPtr value, TXMLCharPtr inNamespace = NULL) - { - Begin(name, inNamespace); - Value(value); - End(); - } - - TXMLCharPtr ToStr(char8_t val) - { - m_NarrowBuf[0] = val; - m_NarrowBuf[1] = 0; - return m_NarrowBuf; - } - - template - TXMLCharPtr ToStr(TDataType val) - { - StringConversion().ToStr(val, NVDataRef(m_NarrowBuf, 256)); - return m_NarrowBuf; - } - - void Att(TXMLCharPtr name, const TXMLStr &inValue, TXMLCharPtr inNamespace = NULL) - { - return Att(name, inValue.c_str(), inNamespace); - } - - template - void Att(TXMLCharPtr name, TData value, TXMLCharPtr inNamespace = NULL) - { - Att(name, ToStr(value), inNamespace); - } - - template - void Serialize(const char8_t *elemName, TSerializer &serializer, - TXMLCharPtr inNamespace = NULL) - { - IDOMWriter::Scope __theScope(*this, elemName, inNamespace); - serializer.Serialize(*this); - } - - NVScopedRefCounted CreateDOMReader() - { - NVScopedRefCounted theFactory(GetFactory()); - return IDOMReader::CreateDOMReader(GetAllocator(), *GetTopElement(), - theFactory->GetStringTable(), theFactory); - } - - // Note that the default method of creating a writer also creates a reader; they can - // both manipulation the DOM hierarch. - static eastl::pair, NVScopedRefCounted> - CreateDOMWriter(NVScopedRefCounted inFactory, SDOMElement &inRootElement, - NVScopedRefCounted inStringTable); - - static eastl::pair, NVScopedRefCounted> - CreateDOMWriter(NVAllocatorCallback &inAlloc, const char8_t *inTopElemName, - NVScopedRefCounted inStringTable, - const char8_t *inNamespace = NULL) - { - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(inAlloc, inStringTable)); - SDOMElement *theRoot = - theFactory->NextElement(theFactory->GetStringTable()->RegisterStr(inTopElemName), - theFactory->GetStringTable()->RegisterStr(inNamespace)); - return CreateDOMWriter(theFactory, *theRoot, inStringTable); - } - }; - - class CXmlErrorHandler - { - protected: - virtual ~CXmlErrorHandler() {} - public: - virtual void OnXmlError(TXMLCharPtr errorName, int line, int column) = 0; - }; - - class CDOMSerializer - { - public: - static void WriteXMLHeader(IOutStream &inStream); - - // Write out the elements. These pairs will be used in order to abbreviate namespaces with - // nicer abbreviations. - // Any namespaces not found in those pairs will get auto-generated abbreviations - // The document will be assumed to be in the namespace that has no abbreviation. - // For fragments or snippets, it is better to avoid writing out the namespace declarations - static void - Write(NVAllocatorCallback &inAlloc, SDOMElement &inElement, IOutStream &inStream, - IStringTable &inStrTable, - NVConstDataRef inNamespaces = NVConstDataRef(), - bool inTrimEmptyElements = true, QT3DSU32 inTabs = 0, bool inWriteNamespaces = true); - - // Returns a pair of the namespace pair nodes and the dom element. The ns pair nodes allow - // us to at least keep the same abbreviations - // used if namespace are used. - static eastl::pair - Read(IDOMFactory &inFactory, IInStream &inStream, CXmlErrorHandler *inErrorHandler = NULL); - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/LICENSE.TXT b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/LICENSE.TXT deleted file mode 100644 index f40caef8..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/LICENSE.TXT +++ /dev/null @@ -1,7 +0,0 @@ - Copyright (c) 2001 Intel Corporation. - -Permition is granted to use, copy, distribute and prepare derivative works -of this library for any purpose and without fee, provided, that the above -copyright notice and this statement appear in all copies. -Intel makes no representations about the suitability of this library for -any purpose, and specifically disclaims all warranties. diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxAoS.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxAoS.h deleted file mode 100644 index 6bcb4406..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxAoS.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_LINUX_AOS_H -#define QT3DS_LINUX_AOS_H - -// no includes here! this file should be included from NVcVecMath.h only!!! - -#if !COMPILE_VECTOR_INTRINSICS -#error Vector intrinsics should not be included when using scalar implementation. -#endif - -// only SSE compatible platforms should reach this -// likely to be split up when we add NEON support. -#include - -typedef union UnionM128 { - UnionM128() {} - UnionM128(__m128 in) { m128 = in; } - - UnionM128(__m128i in) { m128i = in; } - - operator __m128() { return m128; } - - operator const __m128() const { return m128; } - - float m128_f32[4]; - __int8_t m128_i8[16]; - __int16_t m128_i16[8]; - __int32_t m128_i32[4]; - __int64_t m128_i64[2]; - __uint16_t m128_u16[8]; - __uint32_t m128_u32[4]; - __uint64_t m128_u64[2]; - __m128 m128; - __m128i m128i; -} UnionM128; - -typedef __m128 FloatV; -typedef __m128 Vec3V; -typedef __m128 Vec4V; -typedef __m128 BoolV; -typedef __m128 QuatV; -// typedef __m128 VecU32V; -// typedef __m128 VecI32V; -// typedef __m128 VecU16V; -// typedef __m128 VecI16V; -// typedef __m128 VecU8V; -typedef UnionM128 VecU32V; -typedef UnionM128 VecI32V; -typedef UnionM128 VecU16V; -typedef UnionM128 VecI16V; -typedef UnionM128 VecU8V; - -#define FloatVArg FloatV & -#define Vec3VArg Vec3V & -#define Vec4VArg Vec4V & -#define BoolVArg BoolV & -#define VecU32VArg VecU32V & -#define VecI32VArg VecI32V & -#define VecU16VArg VecU16V & -#define VecI16VArg VecI16V & -#define VecU8VArg VecU8V & -#define QuatVArg QuatV & - -QT3DS_ALIGN_PREFIX(16) -struct Mat33V -{ - Mat33V() {} - Mat33V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2) - : col0(c0) - , col1(c1) - , col2(c2) - { - } - Vec3V QT3DS_ALIGN(16, col0); - Vec3V QT3DS_ALIGN(16, col1); - Vec3V QT3DS_ALIGN(16, col2); -} QT3DS_ALIGN_SUFFIX(16); - -QT3DS_ALIGN_PREFIX(16) -struct Mat34V -{ - Mat34V() {} - Mat34V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2, const Vec3V &c3) - : col0(c0) - , col1(c1) - , col2(c2) - , col3(c3) - { - } - Vec3V QT3DS_ALIGN(16, col0); - Vec3V QT3DS_ALIGN(16, col1); - Vec3V QT3DS_ALIGN(16, col2); - Vec3V QT3DS_ALIGN(16, col3); -} QT3DS_ALIGN_SUFFIX(16); - -QT3DS_ALIGN_PREFIX(16) -struct Mat43V -{ - Mat43V() {} - Mat43V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2) - : col0(c0) - , col1(c1) - , col2(c2) - { - } - Vec4V QT3DS_ALIGN(16, col0); - Vec4V QT3DS_ALIGN(16, col1); - Vec4V QT3DS_ALIGN(16, col2); -} QT3DS_ALIGN_SUFFIX(16); - -QT3DS_ALIGN_PREFIX(16) -struct Mat44V -{ - Mat44V() {} - Mat44V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2, const Vec4V &c3) - : col0(c0) - , col1(c1) - , col2(c2) - , col3(c3) - { - } - Vec4V QT3DS_ALIGN(16, col0); - Vec4V QT3DS_ALIGN(16, col1); - Vec4V QT3DS_ALIGN(16, col2); - Vec4V QT3DS_ALIGN(16, col3); -} QT3DS_ALIGN_SUFFIX(16); - -#endif // QT3DS_LINUX_AOS_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxFile.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxFile.h deleted file mode 100644 index 1369735f..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxFile.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_LINUX_FILE_H -#define QT3DS_FOUNDATION_QT3DS_LINUX_FILE_H - -#include "foundation/Qt3DS.h" -#include - -namespace qt3ds { -namespace foundation { - QT3DS_INLINE int fopen_s(FILE **_File, const char *_Filename, const char *_Mode) - { - FILE *fp = ::fopen(_Filename, _Mode); - return fp ? *_File = fp, 0 : -1; - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxInlineAoS.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxInlineAoS.h deleted file mode 100644 index 0443ba90..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxInlineAoS.h +++ /dev/null @@ -1,2666 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// Copyright (c) 2001 Intel Corporation. -// -// Permition is granted to use, copy, distribute and prepare derivative works -// of this library for any purpose and without fee, provided, that the above -// copyright notice and this statement appear in all copies. -// Intel makes no representations about the suitability of this library for -// any purpose, and specifically disclaims all warranties. -// See LEGAL.TXT for all the legal information. -// - -#ifndef QT3DS_LINUX_INLINE_AOS_H -#define QT3DS_LINUX_INLINE_AOS_H - -#if !COMPILE_VECTOR_INTRINSICS -#error Vector intrinsics should not be included when using scalar implementation. -#endif - -// Remove this define when all platforms use simd solver. -#define QT3DS_SUPPORT_SIMD - -#define _QT3DS_FPCLASS_SNAN 0x0001 /* signaling NaN */ -#define _QT3DS_FPCLASS_QNAN 0x0002 /* quiet NaN */ -#define _QT3DS_FPCLASS_NINF 0x0004 /* negative infinity */ -#define _QT3DS_FPCLASS_PINF 0x0200 /* positive infinity */ - -QT3DS_FORCE_INLINE __m128 m128_I2F(__m128i n) -{ - return _mm_castsi128_ps(n); -} -QT3DS_FORCE_INLINE __m128i m128_F2I(__m128 n) -{ - return _mm_castps_si128(n); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAllTrue4_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return moveMask == (0xf); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue4_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return moveMask != (0x0); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAllTrue3_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return (moveMask & 0x7) == (0x7); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue3_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return (moveMask & 0x7) != (0x0); -} - -///////////////////////////////////////////////////////////////////// -////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS -///////////////////////////////////////////////////////////////////// - -QT3DS_FORCE_INLINE QT3DSU32 FiniteTestEq(const Vec4V a, const Vec4V b) -{ - // This is a bit of a bodge. - //_mm_comieq_ss returns 1 if either value is nan so we need to re-cast a and b with true encoded - //as a non-nan number. - // There must be a better way of doing this in sse. - const BoolV one = FOne(); - const BoolV zero = FZero(); - const BoolV a1 = V4Sel(a, one, zero); - const BoolV b1 = V4Sel(b, one, zero); - return (_mm_comieq_ss(a1, b1) && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 1, 1, 1)), - _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(1, 1, 1, 1))) - && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(2, 2, 2, 2)), - _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(2, 2, 2, 2))) - && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 3, 3, 3)), - _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(3, 3, 3, 3)))); -} - -QT3DS_FORCE_INLINE bool isValidFloatV(const FloatV a) -{ - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))) - && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))) - && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)))); -} - -QT3DS_FORCE_INLINE bool isValidVec3V(const Vec3V a) -{ - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero()) ? true : false); -} - -QT3DS_FORCE_INLINE bool isFiniteFloatV(const FloatV a) -{ - const QT3DSU32 badNumber = - (_QT3DS_FPCLASS_SNAN | _QT3DS_FPCLASS_QNAN | _QT3DS_FPCLASS_NINF | _QT3DS_FPCLASS_PINF); - const FloatV vBadNum = FloatV_From_F32((QT3DSF32 &)badNumber); - const BoolV vMask = BAnd(vBadNum, a); - return FiniteTestEq(vMask, BFFFF()) == 1; -} - -QT3DS_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) -{ - const QT3DSU32 badNumber = - (_QT3DS_FPCLASS_SNAN | _QT3DS_FPCLASS_QNAN | _QT3DS_FPCLASS_NINF | _QT3DS_FPCLASS_PINF); - const Vec3V vBadNum = Vec3V_From_F32((QT3DSF32 &)badNumber); - const BoolV vMask = BAnd(BAnd(vBadNum, a), BTTTF()); - return FiniteTestEq(vMask, BFFFF()) == 1; -} - -QT3DS_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) -{ - /*Vec4V a; - QT3DS_ALIGN(16, QT3DSF32 f[4]); - F32Array_Aligned_From_Vec4V(a, f); - return NVIsFinite(f[0]) - && NVIsFinite(f[1]) - && NVIsFinite(f[2]) - && NVIsFinite(f[3]);*/ - - const QT3DSU32 badNumber = - (_QT3DS_FPCLASS_SNAN | _QT3DS_FPCLASS_QNAN | _QT3DS_FPCLASS_NINF | _QT3DS_FPCLASS_PINF); - const Vec4V vBadNum = Vec4V_From_F32((QT3DSF32 &)badNumber); - const BoolV vMask = BAnd(vBadNum, a); - - return FiniteTestEq(vMask, BFFFF()) == 1; -} - -QT3DS_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FloatV_From_F32(0.0f)) - ? true - : false); -} - -QT3DS_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FloatV_From_F32(0.0f)) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FloatV_From_F32(0.0f)) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FloatV_From_F32(0.0f))); -} - -QT3DS_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) -{ - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FloatV_From_F32(0.0f)) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FloatV_From_F32(0.0f)) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FloatV_From_F32(0.0f)) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FloatV_From_F32(0.0f))); -} - -///////////////////////////////////////////////////////////////////// -////VECTORISED FUNCTION IMPLEMENTATIONS -///////////////////////////////////////////////////////////////////// - -QT3DS_FORCE_INLINE FloatV FloatV_From_F32(const QT3DSF32 f) -{ - return (_mm_load1_ps(&f)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_F32(const QT3DSF32 f) -{ - return _mm_set_ps(0.0f, f, f, f); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32(const QT3DSF32 f) -{ - return (_mm_load1_ps(&f)); -} - -QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32(const bool f) -{ - const QT3DSU32 i = -(QT3DSI32)f; - return _mm_load1_ps((float *)&i); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_Aligned(const QT3DSVec3 &f) -{ - VECMATHAOS_ASSERT(0 == ((size_t)&f & 0x0f)); - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3(const QT3DSVec3 &f) -{ - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_WUndefined(const QT3DSVec3 &f) -{ - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) -{ - return V4SetW(v, V4Zero()); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) -{ - return f; // ok if it is implemented as the same type. -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_NVVec3_WUndefined(const QT3DSVec3 &f) -{ - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Mat33V Mat33V_From_NVMat33(const QT3DSMat33 &m) -{ - return Mat33V(Vec3V_From_NVVec3(m.column0), Vec3V_From_NVVec3(m.column1), - Vec3V_From_NVVec3(m.column2)); -} - -QT3DS_FORCE_INLINE void NVMat33_From_Mat33V(const Mat33V &m, QT3DSMat33 &out) -{ - QT3DS_ASSERT((size_t(&out) & 15) == 0); - NVVec3_From_Vec3V(m.col0, out.column0); - NVVec3_From_Vec3V(m.col1, out.column1); - NVVec3_From_Vec3V(m.col2, out.column2); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array_Aligned(const QT3DSF32 *const f) -{ - VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); - return (_mm_load_ps(f)); -} - -QT3DS_FORCE_INLINE void F32Array_Aligned_From_Vec4V(Vec4V a, QT3DSF32 *f) -{ - VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); - _mm_store_ps(f, a); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array(const QT3DSF32 *const f) -{ - return (_mm_loadu_ps(f)); -} - -QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32Array(const bool *const f) -{ - const QT3DS_ALIGN(16, QT3DSU32) b[4] = { -(QT3DSI32)f[0], -(QT3DSI32)f[1], -(QT3DSI32)f[2], -(QT3DSI32)f[3] }; - return _mm_load1_ps((float *)&b); -} - -QT3DS_FORCE_INLINE QT3DSF32 NVF32_From_FloatV(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - QT3DSF32 f; - _mm_store_ss(&f, a); - return f; -} - -QT3DS_FORCE_INLINE void NVF32_From_FloatV(const FloatV a, QT3DSF32 *QT3DS_RESTRICT f) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - _mm_store_ss(f, a); -} - -QT3DS_FORCE_INLINE void NVVec3Aligned_From_Vec3V(const Vec3V a, QT3DSVec3 &f) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); - VECMATHAOS_ASSERT(0 == ((int)&f & 0x0F)); - QT3DS_ALIGN(16, QT3DSF32) f2[4]; - _mm_store_ps(f2, a); - f = QT3DSVec3(f2[0], f2[1], f2[2]); -} - -QT3DS_FORCE_INLINE void NVVec3_From_Vec3V(const Vec3V a, QT3DSVec3 &f) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); - QT3DS_ALIGN(16, QT3DSF32) f2[4]; - _mm_store_ps(f2, a); - f = QT3DSVec3(f2[0], f2[1], f2[2]); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualFloatV(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return (_mm_comieq_ss(a, b) != 0); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec3V(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return V3AllEq(a, b) != 0; -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec4V(const Vec4V a, const Vec4V b) -{ - return V4AllEq(a, b) != 0; -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualBoolV(const BoolV a, const BoolV b) -{ - return BAllTrue4_R(VecI32V_IsEq(a, b)) != 0; -} - -#define VECMATH_AOS_EPSILON (1e-3f) - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualFloatV(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - const FloatV c = FSub(a, b); - const FloatV minError = FloatV_From_F32(-VECMATH_AOS_EPSILON); - const FloatV maxError = FloatV_From_F32(VECMATH_AOS_EPSILON); - return (_mm_comigt_ss(c, minError) && _mm_comilt_ss(c, maxError)); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - const Vec3V c = V3Sub(a, b); - const Vec3V minError = Vec3V_From_F32(-VECMATH_AOS_EPSILON); - const Vec3V maxError = Vec3V_From_F32(VECMATH_AOS_EPSILON); - return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError)); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) -{ - const Vec4V c = V4Sub(a, b); - const Vec4V minError = Vec4V_From_F32(-VECMATH_AOS_EPSILON); - const Vec4V maxError = Vec4V_From_F32(VECMATH_AOS_EPSILON); - return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), maxError)); -} - -////////////////////////////////// -// FLOATV -////////////////////////////////// - -QT3DS_FORCE_INLINE FloatV FZero() -{ - return FloatV_From_F32(0.0f); -} - -QT3DS_FORCE_INLINE FloatV FOne() -{ - return FloatV_From_F32(1.0f); -} - -QT3DS_FORCE_INLINE FloatV FHalf() -{ - return FloatV_From_F32(0.5f); -} - -QT3DS_FORCE_INLINE FloatV FEps() -{ - return FloatV_From_F32(QT3DS_ENV_REAL); -} - -QT3DS_FORCE_INLINE FloatV FEps6() -{ - return FloatV_From_F32(1e-6f); -} - -QT3DS_FORCE_INLINE FloatV FMax() -{ - return FloatV_From_F32(QT3DS_MAX_REAL); -} - -QT3DS_FORCE_INLINE FloatV FNegMax() -{ - return FloatV_From_F32(-QT3DS_MAX_REAL); -} - -QT3DS_FORCE_INLINE FloatV IZero() -{ - const QT3DSU32 zero = 0; - return _mm_load1_ps((QT3DSF32 *)&zero); -} - -QT3DS_FORCE_INLINE FloatV IOne() -{ - const QT3DSU32 one = 1; - return _mm_load1_ps((QT3DSF32 *)&one); -} - -QT3DS_FORCE_INLINE FloatV ITwo() -{ - const QT3DSU32 two = 2; - return _mm_load1_ps((QT3DSF32 *)&two); -} - -QT3DS_FORCE_INLINE FloatV IThree() -{ - const QT3DSU32 three = 3; - return _mm_load1_ps((QT3DSF32 *)&three); -} - -QT3DS_FORCE_INLINE FloatV IFour() -{ - QT3DSU32 four = 4; - return _mm_load1_ps((QT3DSF32 *)&four); -} - -QT3DS_FORCE_INLINE FloatV FNeg(const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return _mm_sub_ps(_mm_setzero_ps(), f); -} - -QT3DS_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_add_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_sub_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE FloatV FRecip(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return _mm_rcp_ps(a); -} - -QT3DS_FORCE_INLINE FloatV FRecipFast(const FloatV a) -{ - return FRecip(a); -} - -QT3DS_FORCE_INLINE FloatV FRsqrt(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return _mm_rsqrt_ps(a); -} - -QT3DS_FORCE_INLINE FloatV FSqrt(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return _mm_sqrt_ps(a); -} - -QT3DS_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) -{ - return FRsqrt(a); -} - -QT3DS_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidFloatV(c)); - return FAdd(FMul(a, b), c); -} - -QT3DS_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidFloatV(c)); - return FSub(c, FMul(a, b)); -} - -QT3DS_FORCE_INLINE FloatV FAbs(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - QT3DS_ALIGN(16, const QT3DSU32) absMask[4] = { 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF }; - return _mm_and_ps(a, _mm_load_ps((QT3DSF32 *)absMask)); -} - -QT3DS_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(_VecMathTests::allElementsEqualBoolV(c, BTTTT()) - || _VecMathTests::allElementsEqualBoolV(c, BFFFF())); - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); -} - -QT3DS_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_cmpgt_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_cmpge_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_max_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_min_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(minV)); - VECMATHAOS_ASSERT(isValidFloatV(maxV)); - return FMax(FMin(a, maxV), minV); -} - -QT3DS_FORCE_INLINE QT3DSU32 FAllGrtr(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return (_mm_comigt_ss(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 FAllGrtrOrEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - - return (_mm_comige_ss(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 FAllEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - - return (_mm_comieq_ss(a, b)); -} - -QT3DS_FORCE_INLINE FloatV FRound(const FloatV a) -{ - // return _mm_round_ps(a, 0x0); - const Vec3V half = Vec3V_From_F32(0.5f); - const Vec3V aPlusHalf = V3Add(a, half); - __m128i tmp = _mm_cvttps_epi32(aPlusHalf); - return _mm_cvtepi32_ps(tmp); -} - -QT3DS_FORCE_INLINE FloatV FSin(const FloatV a) -{ - // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; - // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; - FloatV Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const FloatV tmp = FMul(a, twoPi); - const FloatV b = FRound(tmp); - const FloatV V1 = FNegMulSub(twoPi, b, a); - - // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - - // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) - const FloatV V2 = FMul(V1, V1); - const FloatV V3 = FMul(V2, V1); - const FloatV V5 = FMul(V3, V2); - const FloatV V7 = FMul(V5, V2); - const FloatV V9 = FMul(V7, V2); - const FloatV V11 = FMul(V9, V2); - const FloatV V13 = FMul(V11, V2); - const FloatV V15 = FMul(V13, V2); - const FloatV V17 = FMul(V15, V2); - const FloatV V19 = FMul(V17, V2); - const FloatV V21 = FMul(V19, V2); - const FloatV V23 = FMul(V21, V2); - - const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); - const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); - const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); - - const FloatV S1 = V4GetY(sinCoefficients0); - const FloatV S2 = V4GetZ(sinCoefficients0); - const FloatV S3 = V4GetW(sinCoefficients0); - const FloatV S4 = V4GetX(sinCoefficients1); - const FloatV S5 = V4GetY(sinCoefficients1); - const FloatV S6 = V4GetZ(sinCoefficients1); - const FloatV S7 = V4GetW(sinCoefficients1); - const FloatV S8 = V4GetX(sinCoefficients2); - const FloatV S9 = V4GetY(sinCoefficients2); - const FloatV S10 = V4GetZ(sinCoefficients2); - const FloatV S11 = V4GetW(sinCoefficients2); - - Result = FMulAdd(S1, V3, V1); - Result = FMulAdd(S2, V5, Result); - Result = FMulAdd(S3, V7, Result); - Result = FMulAdd(S4, V9, Result); - Result = FMulAdd(S5, V11, Result); - Result = FMulAdd(S6, V13, Result); - Result = FMulAdd(S7, V15, Result); - Result = FMulAdd(S8, V17, Result); - Result = FMulAdd(S9, V19, Result); - Result = FMulAdd(S10, V21, Result); - Result = FMulAdd(S11, V23, Result); - - return Result; -} - -QT3DS_FORCE_INLINE FloatV FCos(const FloatV a) -{ - // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; - // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; - FloatV Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const FloatV tmp = FMul(a, twoPi); - const FloatV b = FRound(tmp); - const FloatV V1 = FNegMulSub(twoPi, b, a); - - // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - - // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) - const FloatV V2 = FMul(V1, V1); - const FloatV V4 = FMul(V2, V2); - const FloatV V6 = FMul(V4, V2); - const FloatV V8 = FMul(V4, V4); - const FloatV V10 = FMul(V6, V4); - const FloatV V12 = FMul(V6, V6); - const FloatV V14 = FMul(V8, V6); - const FloatV V16 = FMul(V8, V8); - const FloatV V18 = FMul(V10, V8); - const FloatV V20 = FMul(V10, V10); - const FloatV V22 = FMul(V12, V10); - - const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); - const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); - const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); - - const FloatV C1 = V4GetY(cosCoefficients0); - const FloatV C2 = V4GetZ(cosCoefficients0); - const FloatV C3 = V4GetW(cosCoefficients0); - const FloatV C4 = V4GetX(cosCoefficients1); - const FloatV C5 = V4GetY(cosCoefficients1); - const FloatV C6 = V4GetZ(cosCoefficients1); - const FloatV C7 = V4GetW(cosCoefficients1); - const FloatV C8 = V4GetX(cosCoefficients2); - const FloatV C9 = V4GetY(cosCoefficients2); - const FloatV C10 = V4GetZ(cosCoefficients2); - const FloatV C11 = V4GetW(cosCoefficients2); - - Result = FMulAdd(C1, V2, V4One()); - Result = FMulAdd(C2, V4, Result); - Result = FMulAdd(C3, V6, Result); - Result = FMulAdd(C4, V8, Result); - Result = FMulAdd(C5, V10, Result); - Result = FMulAdd(C6, V12, Result); - Result = FMulAdd(C7, V14, Result); - Result = FMulAdd(C8, V16, Result); - Result = FMulAdd(C9, V18, Result); - Result = FMulAdd(C10, V20, Result); - Result = FMulAdd(C11, V22, Result); - - return Result; -} - -QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) -{ - const BoolV ffff = BFFFF(); - const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); - return !BAllEq(c, ffff); -} - -QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) -{ - const BoolV tttt = BTTTT(); - const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); - return BAllEq(c, tttt); -} - -QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV bounds) -{ - return FOutOfBounds(a, FNeg(bounds), bounds); -} - -QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV bounds) -{ - return FInBounds(a, FNeg(bounds), bounds); -} - -////////////////////////////////// -// VEC3V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec3V V3Splat(const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - const __m128 zero = FloatV_From_F32(0.0f); - const __m128 fff0 = _mm_move_ss(f, zero); - return _mm_shuffle_ps(fff0, fff0, _MM_SHUFFLE(0, 1, 2, 3)); -} - -QT3DS_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) -{ - VECMATHAOS_ASSERT(isValidFloatV(x)); - VECMATHAOS_ASSERT(isValidFloatV(y)); - VECMATHAOS_ASSERT(isValidFloatV(z)); - // static on zero causes compiler crash on x64 debug_opt - const __m128 zero = FloatV_From_F32(0.0f); - const __m128 xy = _mm_move_ss(x, y); - const __m128 z0 = _mm_move_ss(zero, z); - - return _mm_shuffle_ps(xy, z0, _MM_SHUFFLE(1, 0, 0, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3UnitX() -{ - const QT3DS_ALIGN(16, QT3DSF32) x[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; - const __m128 x128 = _mm_load_ps(x); - return x128; -} - -QT3DS_FORCE_INLINE Vec3V V3UnitY() -{ - const QT3DS_ALIGN(16, QT3DSF32) y[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; - const __m128 y128 = _mm_load_ps(y); - return y128; -} - -QT3DS_FORCE_INLINE Vec3V V3UnitZ() -{ - const QT3DS_ALIGN(16, QT3DSF32) z[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; - const __m128 z128 = _mm_load_ps(z); - return z128; -} - -QT3DS_FORCE_INLINE FloatV V3GetX(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE FloatV V3GetY(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); -} - -QT3DS_FORCE_INLINE FloatV V3GetZ(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V3Sel(BFTTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V3Sel(BTFTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V3Sel(BTTFT(), v, f); -} - -QT3DS_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) -{ - Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 0, 3, 0)); - return V3SetY(r, V3GetX(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) -{ - Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); - return V3SetY(r, V3GetY(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) -{ - Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 2, 3, 2)); - return V3SetY(r, V3GetZ(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3Zero() -{ - return Vec3V_From_F32(0.0f); -} - -QT3DS_FORCE_INLINE Vec3V V3Eps() -{ - return Vec3V_From_F32(QT3DS_ENV_REAL); -} -QT3DS_FORCE_INLINE Vec3V V3One() -{ - return Vec3V_From_F32(1.0f); -} - -QT3DS_FORCE_INLINE Vec3V V3Neg(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_sub_ps(_mm_setzero_ps(), f); -} - -QT3DS_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_add_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_sub_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - const __m128 one = Vec3V_From_F32(1.0f); - const __m128 tttf = BTTTF(); - const __m128 b1 = V3Sel(tttf, b, one); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - const __m128 one = Vec3V_From_F32(1.0f); - const __m128 tttf = BTTTF(); - const __m128 b1 = V3Sel(tttf, b, one); - return _mm_mul_ps(a, _mm_rcp_ps(b1)); -} - -QT3DS_FORCE_INLINE Vec3V V3Recip(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = Vec3V_From_F32(0.0f); - const __m128 tttf = BTTTF(); - const __m128 recipA = _mm_rcp_ps(a); - return V3Sel(tttf, recipA, zero); -} - -QT3DS_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) -{ - return V3Recip(a); -} - -QT3DS_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = Vec3V_From_F32(0.0f); - const __m128 tttf = BTTTF(); - const __m128 recipA = _mm_rsqrt_ps(a); - return V3Sel(tttf, recipA, zero); -} - -QT3DS_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) -{ - return V3Rsqrt(a); -} - -QT3DS_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Add(V3Scale(a, b), c); -} - -QT3DS_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Sub(c, V3Scale(a, b)); -} - -QT3DS_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Add(V3Mul(a, b), c); -} - -QT3DS_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Sub(c, V3Scale(a, b)); -} - -QT3DS_FORCE_INLINE Vec3V V3Abs(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Max( - a, V3Neg(a)); // sw/physx/shared/reviewed/3/feature/sdk/include/windows/Qt3DSWindowsInlineAoS.h -} - -QT3DS_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - //__m128 dot1 = _mm_mul_ps(a, b); - ////w,z,y,x - //__m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2,1,0,3)); //z,y,x,w - //__m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1,0,3,2)); //y,x,w,z - //__m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0,3,2,1)); //x,w,z,y - // return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1,shuf1)); - - __m128 dot1 = _mm_mul_ps(a, b); - __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w - __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z - __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y - return _mm_add_ps(_mm_add_ps(shuf2, shuf3), shuf1); -} - -QT3DS_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w - __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w - __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w - __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w - return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); -} - -QT3DS_FORCE_INLINE FloatV V3Length(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_sqrt_ps(V3Dot(a, a)); -} - -QT3DS_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Dot(a, a); -} - -QT3DS_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Scale(a, _mm_rsqrt_ps(V3Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Scale(a, _mm_rsqrt_ps(V3Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = FloatV_From_F32(0.0f); - const __m128 length = V3Length(a); - const __m128 isGreaterThanZero = FIsGrtr(length, zero); - return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), zero); -} - -QT3DS_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); -} - -QT3DS_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_cmpgt_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_cmpge_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_max_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_min_ps(a, b); -} - -// Extract the maximum value from a -QT3DS_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) -{ - const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); - const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); - const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); - - return _mm_max_ps(_mm_max_ps(shuf1, shuf2), shuf3); -} - -// Extract the maximum value from a -QT3DS_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) -{ - const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); - const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); - const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); - - return _mm_min_ps(_mm_min_ps(shuf1, shuf2), shuf3); -} - -// return (a >= 0.0f) ? 1.0f : -1.0f; -QT3DS_FORCE_INLINE Vec3V V3Sign(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 one = V3One(); - const __m128 none = V3Neg(one); - return V3Sel(V3IsGrtrOrEq(a, zero), one, none); -} - -QT3DS_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(minV)); - VECMATHAOS_ASSERT(isValidVec3V(maxV)); - return V3Max(V3Min(a, maxV), minV); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtr(const Vec3V a, const Vec3V b) -{ - return BAllTrue3_R(V4IsGrtr(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) -{ - return BAllTrue3_R(V4IsGrtrOrEq(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3AllEq(const Vec3V a, const Vec3V b) -{ - return BAllTrue3_R(V4IsEq(a, b)); -} - -QT3DS_FORCE_INLINE Vec3V V3Round(const Vec3V a) -{ - // return _mm_round_ps(a, 0x0); - const Vec3V half = Vec3V_From_F32(0.5f); - const Vec3V aPlusHalf = V3Add(a, half); - __m128i tmp = _mm_cvttps_epi32(aPlusHalf); - return _mm_cvtepi32_ps(tmp); -} - -QT3DS_FORCE_INLINE Vec3V V3Sin(const Vec3V a) -{ - // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; - // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; - Vec3V Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec3V tmp = V3Mul(a, twoPi); - const Vec3V b = V3Round(tmp); - const Vec3V V1 = V3NegMulSub(twoPi, b, a); - - // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - - // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) - const Vec3V V2 = V3Mul(V1, V1); - const Vec3V V3 = V3Mul(V2, V1); - const Vec3V V5 = V3Mul(V3, V2); - const Vec3V V7 = V3Mul(V5, V2); - const Vec3V V9 = V3Mul(V7, V2); - const Vec3V V11 = V3Mul(V9, V2); - const Vec3V V13 = V3Mul(V11, V2); - const Vec3V V15 = V3Mul(V13, V2); - const Vec3V V17 = V3Mul(V15, V2); - const Vec3V V19 = V3Mul(V17, V2); - const Vec3V V21 = V3Mul(V19, V2); - const Vec3V V23 = V3Mul(V21, V2); - - const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); - const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); - const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); - - const FloatV S1 = V4GetY(sinCoefficients0); - const FloatV S2 = V4GetZ(sinCoefficients0); - const FloatV S3 = V4GetW(sinCoefficients0); - const FloatV S4 = V4GetX(sinCoefficients1); - const FloatV S5 = V4GetY(sinCoefficients1); - const FloatV S6 = V4GetZ(sinCoefficients1); - const FloatV S7 = V4GetW(sinCoefficients1); - const FloatV S8 = V4GetX(sinCoefficients2); - const FloatV S9 = V4GetY(sinCoefficients2); - const FloatV S10 = V4GetZ(sinCoefficients2); - const FloatV S11 = V4GetW(sinCoefficients2); - - Result = V3MulAdd(S1, V3, V1); - Result = V3MulAdd(S2, V5, Result); - Result = V3MulAdd(S3, V7, Result); - Result = V3MulAdd(S4, V9, Result); - Result = V3MulAdd(S5, V11, Result); - Result = V3MulAdd(S6, V13, Result); - Result = V3MulAdd(S7, V15, Result); - Result = V3MulAdd(S8, V17, Result); - Result = V3MulAdd(S9, V19, Result); - Result = V3MulAdd(S10, V21, Result); - Result = V3MulAdd(S11, V23, Result); - - return Result; -} - -QT3DS_FORCE_INLINE Vec3V V3Cos(const Vec3V a) -{ - // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; - // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; - Vec3V Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec3V tmp = V3Mul(a, twoPi); - const Vec3V b = V3Round(tmp); - const Vec3V V1 = V3NegMulSub(twoPi, b, a); - - // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - - // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) - const Vec3V V2 = V3Mul(V1, V1); - const Vec3V V4 = V3Mul(V2, V2); - const Vec3V V6 = V3Mul(V4, V2); - const Vec3V V8 = V3Mul(V4, V4); - const Vec3V V10 = V3Mul(V6, V4); - const Vec3V V12 = V3Mul(V6, V6); - const Vec3V V14 = V3Mul(V8, V6); - const Vec3V V16 = V3Mul(V8, V8); - const Vec3V V18 = V3Mul(V10, V8); - const Vec3V V20 = V3Mul(V10, V10); - const Vec3V V22 = V3Mul(V12, V10); - - const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); - const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); - const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); - - const FloatV C1 = V4GetY(cosCoefficients0); - const FloatV C2 = V4GetZ(cosCoefficients0); - const FloatV C3 = V4GetW(cosCoefficients0); - const FloatV C4 = V4GetX(cosCoefficients1); - const FloatV C5 = V4GetY(cosCoefficients1); - const FloatV C6 = V4GetZ(cosCoefficients1); - const FloatV C7 = V4GetW(cosCoefficients1); - const FloatV C8 = V4GetX(cosCoefficients2); - const FloatV C9 = V4GetY(cosCoefficients2); - const FloatV C10 = V4GetZ(cosCoefficients2); - const FloatV C11 = V4GetW(cosCoefficients2); - - Result = V3MulAdd(C1, V2, V4One()); - Result = V3MulAdd(C2, V4, Result); - Result = V3MulAdd(C3, V6, Result); - Result = V3MulAdd(C4, V8, Result); - Result = V3MulAdd(C5, V10, Result); - Result = V3MulAdd(C6, V12, Result); - Result = V3MulAdd(C7, V14, Result); - Result = V3MulAdd(C8, V16, Result); - Result = V3MulAdd(C9, V18, Result); - Result = V3MulAdd(C10, V20, Result); - Result = V3MulAdd(C11, V22, Result); - - return Result; -} - -QT3DS_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) -{ - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 2, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) -{ - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 0)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) -{ - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 2, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 0, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) -{ - return _mm_shuffle_ps(v1, v0, _MM_SHUFFLE(3, 1, 2, 3)); -} - -QT3DS_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) -{ - return _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 0, 3, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) -{ - // There must be a better way to do this. - Vec3V v2 = V3Zero(); - FloatV y1 = V3GetY(v1); - FloatV x0 = V3GetX(v0); - v2 = V3SetX(v2, y1); - return V3SetY(v2, x0); -} - -QT3DS_FORCE_INLINE FloatV V3SumElems(const Vec3V a) -{ - __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w - __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z - __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y - return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) -{ - const BoolV ffff = BFFFF(); - const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); - return !BAllEq(c, ffff); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) -{ - const BoolV tttt = BTTTT(); - const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); - return BAllEq(c, tttt); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) -{ - return V3OutOfBounds(a, V3Neg(bounds), bounds); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V bounds) -{ - return V3InBounds(a, V3Neg(bounds), bounds); -} - -////////////////////////////////// -// VEC4V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec4V V4Splat(const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatV *const floatVArray) -{ - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[0])); - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[1])); - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[2])); - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[3])); - __m128 xw = _mm_move_ss(floatVArray[1], floatVArray[0]); // y, y, y, x - __m128 yz = _mm_move_ss(floatVArray[2], floatVArray[3]); // z, z, z, w - return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); -} - -QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, - const FloatVArg w) -{ - VECMATHAOS_ASSERT(isValidFloatV(x)); - VECMATHAOS_ASSERT(isValidFloatV(y)); - VECMATHAOS_ASSERT(isValidFloatV(z)); - VECMATHAOS_ASSERT(isValidFloatV(w)); - __m128 xw = _mm_move_ss(y, x); // y, y, y, x - __m128 yz = _mm_move_ss(z, w); // z, z, z, w - return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); -} - -QT3DS_FORCE_INLINE Vec4V V4UnitW() -{ - const QT3DS_ALIGN(16, QT3DSF32) w[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - const __m128 w128 = _mm_load_ps(w); - return w128; -} - -QT3DS_FORCE_INLINE Vec4V V4UnitX() -{ - const QT3DS_ALIGN(16, QT3DSF32) x[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; - const __m128 x128 = _mm_load_ps(x); - return x128; -} - -QT3DS_FORCE_INLINE Vec4V V4UnitY() -{ - const QT3DS_ALIGN(16, QT3DSF32) y[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; - const __m128 y128 = _mm_load_ps(y); - return y128; -} - -QT3DS_FORCE_INLINE Vec4V V4UnitZ() -{ - const QT3DS_ALIGN(16, QT3DSF32) z[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; - const __m128 z128 = _mm_load_ps(z); - return z128; -} - -QT3DS_FORCE_INLINE FloatV V4GetW(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); -} - -QT3DS_FORCE_INLINE FloatV V4GetX(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE FloatV V4GetY(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); -} - -QT3DS_FORCE_INLINE FloatV V4GetZ(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); -} - -QT3DS_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BTTTF(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BFTTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BTFTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BTTFT(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4Zero() -{ - return Vec4V_From_F32(0.0f); -} - -QT3DS_FORCE_INLINE Vec4V V4One() -{ - return Vec4V_From_F32(1.0f); -} - -QT3DS_FORCE_INLINE Vec3V V4Eps() -{ - return Vec3V_From_F32(QT3DS_ENV_REAL); -} - -QT3DS_FORCE_INLINE Vec4V V4Neg(const Vec4V f) -{ - return _mm_sub_ps(_mm_setzero_ps(), f); -} - -QT3DS_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) -{ - return _mm_add_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) -{ - return _mm_sub_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) -{ - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) -{ - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) -{ - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) -{ - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE Vec4V V4Recip(const Vec4V a) -{ - return _mm_rcp_ps(a); -} - -QT3DS_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) -{ - return V4Recip(a); -} - -QT3DS_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) -{ - return _mm_rsqrt_ps(a); -} - -QT3DS_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) -{ - return V4Rsqrt(a); -} - -QT3DS_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return V4Add(V4Scale(a, b), c); -} - -QT3DS_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return V4Sub(c, V4Scale(a, b)); -} - -QT3DS_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) -{ - return V4Add(V4Scale(a, b), c); -} - -QT3DS_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) -{ - return V4Sub(c, V4Scale(a, b)); -} - -QT3DS_FORCE_INLINE Vec4V V4Abs(const Vec4V a) -{ - return V4Max(a, V3Neg(a)); -} - -QT3DS_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) -{ - __m128 dot1 = _mm_mul_ps(a, b); // x,y,z,w - __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 1, 0, 3)); // w,x,y,z - __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 0, 3, 2)); // z,w,x,y - __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 3, 2, 1)); // y,z,w,x - return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1, shuf1)); -} - -QT3DS_FORCE_INLINE FloatV V4Length(const Vec4V a) -{ - return _mm_sqrt_ps(V4Dot(a, a)); -} - -QT3DS_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) -{ - return V4Dot(a, a); -} - -QT3DS_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) -{ - return V4ScaleInv(a, _mm_sqrt_ps(V4Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) -{ - return V4ScaleInvFast(a, _mm_sqrt_ps(V4Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a) -{ - const __m128 zero = FloatV_From_F32(0.0f); - const __m128 length = V4Length(a); - const __m128 isGreaterThanZero = FIsGrtr(length, zero); - return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), zero); -} - -QT3DS_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) -{ - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) -{ - return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); -} - -QT3DS_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) -{ - return _mm_cmpgt_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) -{ - return _mm_cmpge_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) -{ - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V4Max(const Vec4V a, const Vec4V b) -{ - return _mm_max_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) -{ - return _mm_min_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) -{ - __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); - __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); - __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); - - return _mm_max_ps(_mm_max_ps(a, shuf1), _mm_max_ps(shuf2, shuf3)); -} - -QT3DS_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) -{ - return V4Max(V4Min(a, maxV), minV); -} - -QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtr(const Vec4V a, const Vec4V b) -{ - return BAllTrue4_R(V4IsGrtr(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) -{ - return BAllTrue4_R(V4IsGrtrOrEq(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V4AllEq(const Vec4V a, const Vec4V b) -{ - return BAllTrue4_R(V4IsEq(a, b)); -} - -QT3DS_FORCE_INLINE Vec4V V4Round(const Vec4V a) -{ - // return _mm_round_ps(a, 0x0); - const Vec3V half = Vec3V_From_F32(0.5f); - const Vec3V aPlusHalf = V3Add(a, half); - __m128i tmp = _mm_cvttps_epi32(aPlusHalf); - return _mm_cvtepi32_ps(tmp); -} - -QT3DS_FORCE_INLINE Vec4V V4Sin(const Vec4V a) -{ - // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; - // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; - Vec4V Result; - - const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec4V tmp = V4Mul(a, twoPi); - const Vec4V b = V4Round(tmp); - const Vec4V V1 = V4NegMulSub(twoPi, b, a); - - // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - - // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) - const Vec4V V2 = V4Mul(V1, V1); - const Vec4V V3 = V4Mul(V2, V1); - const Vec4V V5 = V4Mul(V3, V2); - const Vec4V V7 = V4Mul(V5, V2); - const Vec4V V9 = V4Mul(V7, V2); - const Vec4V V11 = V4Mul(V9, V2); - const Vec4V V13 = V4Mul(V11, V2); - const Vec4V V15 = V4Mul(V13, V2); - const Vec4V V17 = V4Mul(V15, V2); - const Vec4V V19 = V4Mul(V17, V2); - const Vec4V V21 = V4Mul(V19, V2); - const Vec4V V23 = V4Mul(V21, V2); - - const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); - const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); - const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); - - const FloatV S1 = V4GetY(sinCoefficients0); - const FloatV S2 = V4GetZ(sinCoefficients0); - const FloatV S3 = V4GetW(sinCoefficients0); - const FloatV S4 = V4GetX(sinCoefficients1); - const FloatV S5 = V4GetY(sinCoefficients1); - const FloatV S6 = V4GetZ(sinCoefficients1); - const FloatV S7 = V4GetW(sinCoefficients1); - const FloatV S8 = V4GetX(sinCoefficients2); - const FloatV S9 = V4GetY(sinCoefficients2); - const FloatV S10 = V4GetZ(sinCoefficients2); - const FloatV S11 = V4GetW(sinCoefficients2); - - Result = V4MulAdd(S1, V3, V1); - Result = V4MulAdd(S2, V5, Result); - Result = V4MulAdd(S3, V7, Result); - Result = V4MulAdd(S4, V9, Result); - Result = V4MulAdd(S5, V11, Result); - Result = V4MulAdd(S6, V13, Result); - Result = V4MulAdd(S7, V15, Result); - Result = V4MulAdd(S8, V17, Result); - Result = V4MulAdd(S9, V19, Result); - Result = V4MulAdd(S10, V21, Result); - Result = V4MulAdd(S11, V23, Result); - - return Result; -} - -QT3DS_FORCE_INLINE Vec4V V4Cos(const Vec4V a) -{ - // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; - // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; - Vec4V Result; - - const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec4V tmp = V4Mul(a, twoPi); - const Vec4V b = V4Round(tmp); - const Vec4V V1 = V4NegMulSub(twoPi, b, a); - - // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - - // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) - const Vec4V V2 = V4Mul(V1, V1); - const Vec4V V4 = V4Mul(V2, V2); - const Vec4V V6 = V4Mul(V4, V2); - const Vec4V V8 = V4Mul(V4, V4); - const Vec4V V10 = V4Mul(V6, V4); - const Vec4V V12 = V4Mul(V6, V6); - const Vec4V V14 = V4Mul(V8, V6); - const Vec4V V16 = V4Mul(V8, V8); - const Vec4V V18 = V4Mul(V10, V8); - const Vec4V V20 = V4Mul(V10, V10); - const Vec4V V22 = V4Mul(V12, V10); - - const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); - const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); - const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); - - const FloatV C1 = V4GetY(cosCoefficients0); - const FloatV C2 = V4GetZ(cosCoefficients0); - const FloatV C3 = V4GetW(cosCoefficients0); - const FloatV C4 = V4GetX(cosCoefficients1); - const FloatV C5 = V4GetY(cosCoefficients1); - const FloatV C6 = V4GetZ(cosCoefficients1); - const FloatV C7 = V4GetW(cosCoefficients1); - const FloatV C8 = V4GetX(cosCoefficients2); - const FloatV C9 = V4GetY(cosCoefficients2); - const FloatV C10 = V4GetZ(cosCoefficients2); - const FloatV C11 = V4GetW(cosCoefficients2); - - Result = V4MulAdd(C1, V2, V4One()); - Result = V4MulAdd(C2, V4, Result); - Result = V4MulAdd(C3, V6, Result); - Result = V4MulAdd(C4, V8, Result); - Result = V4MulAdd(C5, V10, Result); - Result = V4MulAdd(C6, V12, Result); - Result = V4MulAdd(C7, V14, Result); - Result = V4MulAdd(C8, V16, Result); - Result = V4MulAdd(C9, V18, Result); - Result = V4MulAdd(C10, V20, Result); - Result = V4MulAdd(C11, V22, Result); - - return Result; -} - -////////////////////////////////// -// VEC4V -////////////////////////////////// - -QT3DS_FORCE_INLINE BoolV BFFFF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0, 0 }; - const __m128 ffff = _mm_load_ps((float *)&f); - return ffff; -} - -QT3DS_FORCE_INLINE BoolV BFFFT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0, 0xFFFFFFFF }; - const __m128 ffft = _mm_load_ps((float *)&f); - return ffft; -} - -QT3DS_FORCE_INLINE BoolV BFFTF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0xFFFFFFFF, 0 }; - const __m128 fftf = _mm_load_ps((float *)&f); - return fftf; -} - -QT3DS_FORCE_INLINE BoolV BFFTT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 fftt = _mm_load_ps((float *)&f); - return fftt; -} - -QT3DS_FORCE_INLINE BoolV BFTFF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0, 0 }; - const __m128 ftff = _mm_load_ps((float *)&f); - return ftff; -} - -QT3DS_FORCE_INLINE BoolV BFTFT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0, 0xFFFFFFFF }; - const __m128 ftft = _mm_load_ps((float *)&f); - return ftft; -} - -QT3DS_FORCE_INLINE BoolV BFTTF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; - const __m128 fttf = _mm_load_ps((float *)&f); - return fttf; -} - -QT3DS_FORCE_INLINE BoolV BFTTT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 fttt = _mm_load_ps((float *)&f); - return fttt; -} - -QT3DS_FORCE_INLINE BoolV BTFFF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0, 0 }; - const __m128 tfff = _mm_load_ps((float *)&f); - return tfff; -} - -QT3DS_FORCE_INLINE BoolV BTFFT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0, 0xFFFFFFFF }; - const __m128 tfft = _mm_load_ps((float *)&f); - return tfft; -} - -QT3DS_FORCE_INLINE BoolV BTFTF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0 }; - const __m128 tftf = _mm_load_ps((float *)&f); - return tftf; -} - -QT3DS_FORCE_INLINE BoolV BTFTT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 tftt = _mm_load_ps((float *)&f); - return tftt; -} - -QT3DS_FORCE_INLINE BoolV BTTFF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0 }; - const __m128 ttff = _mm_load_ps((float *)&f); - return ttff; -} - -QT3DS_FORCE_INLINE BoolV BTTFT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF }; - const __m128 ttft = _mm_load_ps((float *)&f); - return ttft; -} - -QT3DS_FORCE_INLINE BoolV BTTTF() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; - const __m128 tttf = _mm_load_ps((float *)&f); - return tttf; -} - -QT3DS_FORCE_INLINE BoolV BTTTT() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 tttt = _mm_load_ps((float *)&f); - return tttt; -} - -QT3DS_FORCE_INLINE BoolV BXMask() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0, 0 }; - const __m128 tfff = _mm_load_ps((float *)&f); - return tfff; -} - -QT3DS_FORCE_INLINE BoolV BYMask() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0, 0 }; - const __m128 ftff = _mm_load_ps((float *)&f); - return ftff; -} - -QT3DS_FORCE_INLINE BoolV BZMask() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0xFFFFFFFF, 0 }; - const __m128 fftf = _mm_load_ps((float *)&f); - return fftf; -} - -QT3DS_FORCE_INLINE BoolV BWMask() -{ - const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0, 0xFFFFFFFF }; - const __m128 ffft = _mm_load_ps((float *)&f); - return ffft; -} - -QT3DS_FORCE_INLINE BoolV BGetX(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE BoolV BGetY(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); -} - -QT3DS_FORCE_INLINE BoolV BGetZ(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); -} - -QT3DS_FORCE_INLINE BoolV BGetW(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); -} - -QT3DS_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) -{ - return (_mm_and_ps(a, b)); -} - -QT3DS_FORCE_INLINE BoolV BNot(const BoolV a) -{ - const BoolV bAllTrue(BTTTT()); - return _mm_xor_ps(a, bAllTrue); -} - -QT3DS_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) -{ - return (_mm_andnot_ps(a, b)); -} - -QT3DS_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) -{ - return (_mm_or_ps(a, b)); -} - -QT3DS_FORCE_INLINE BoolV BAllTrue4(const BoolV a) -{ - const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); - return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) -{ - const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); - return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE BoolV BAllTrue3(const BoolV a) -{ - const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); - return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) -{ - const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); - return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAllEq(const BoolV a, const BoolV b) -{ - const BoolV bTest = m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); - return BAllTrue4_R(bTest); -} - -////////////////////////////////// -// MAT33V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec3V M33MulV3(const Mat33V &a, const Vec3V b) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - const Vec3V v0 = V3Scale(a.col0, x); - const Vec3V v1 = V3Scale(a.col1, y); - const Vec3V v2 = V3Scale(a.col2, z); - const Vec3V v0PlusV1 = V3Add(v0, v1); - return V3Add(v0PlusV1, v2); -} - -QT3DS_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V &a, const Vec3V b) -{ - const FloatV x = V3Dot(a.col0, b); - const FloatV y = V3Dot(a.col1, b); - const FloatV z = V3Dot(a.col2, b); - return V3Merge(x, y, z); -} - -QT3DS_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V &A, const Vec3V b, const Vec3V c) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - Vec3V result = V3MulAdd(A.col0, x, c); - result = V3MulAdd(A.col1, y, result); - return V3MulAdd(A.col2, z, result); -} - -QT3DS_FORCE_INLINE Mat33V M33MulM33(const Mat33V &a, const Mat33V &b) -{ - return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Add(const Mat33V &a, const Mat33V &b) -{ - return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Inverse(const Mat33V &a) -{ - const BoolV tfft = BTFFT(); - const BoolV tttf = BTTTF(); - const FloatV zero = FloatV_From_F32(0.0f); - const Vec3V cross01 = V3Cross(a.col0, a.col1); - const Vec3V cross12 = V3Cross(a.col1, a.col2); - const Vec3V cross20 = V3Cross(a.col2, a.col0); - const FloatV dot = V3Dot(cross01, a.col2); - const FloatV invDet = _mm_rcp_ps(dot); - const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); - const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); - Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); - colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); - const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); - const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); - const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); - const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); - const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); - const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); - - return Mat33V(_mm_mul_ps(colInv0, invDet), _mm_mul_ps(colInv1, invDet), - _mm_mul_ps(colInv2, invDet)); -} - -QT3DS_FORCE_INLINE Mat33V M33Trnsps(const Mat33V &a) -{ - return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), - V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), - V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); -} - -QT3DS_FORCE_INLINE Mat33V M33Identity() -{ - return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); -} - -QT3DS_FORCE_INLINE Mat33V M33Sub(const Mat33V &a, const Mat33V &b) -{ - return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Neg(const Mat33V &a) -{ - return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Abs(const Mat33V &a) -{ - return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); -} - -QT3DS_FORCE_INLINE Mat33V PromoteVec3V(const Vec3V v) -{ - const BoolV bTFFF = BTFFF(); - const BoolV bFTFF = BFTFF(); - const BoolV bFFTF = BTFTF(); - - const Vec3V zero = V3Zero(); - - return Mat33V(V3Sel(bTFFF, v, zero), V3Sel(bFTFF, v, zero), V3Sel(bFFTF, v, zero)); -} - -QT3DS_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) -{ - const FloatV x = V3Mul(V3UnitX(), d); - const FloatV y = V3Mul(V3UnitY(), d); - const FloatV z = V3Mul(V3UnitZ(), d); - return Mat33V(x, y, z); -} - -////////////////////////////////// -// MAT34V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec3V M34MulV3(const Mat34V &a, const Vec3V b) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - const Vec3V v0 = V3Scale(a.col0, x); - const Vec3V v1 = V3Scale(a.col1, y); - const Vec3V v2 = V3Scale(a.col2, z); - const Vec3V v0PlusV1 = V3Add(v0, v1); - const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); - return (V3Add(v0PlusV1Plusv2, a.col3)); -} - -QT3DS_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V &a, const Vec3V b) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - const Vec3V v0 = V3Scale(a.col0, x); - const Vec3V v1 = V3Scale(a.col1, y); - const Vec3V v2 = V3Scale(a.col2, z); - const Vec3V v0PlusV1 = V3Add(v0, v1); - return V3Add(v0PlusV1, v2); -} - -QT3DS_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V &a, const Vec3V b) -{ - const FloatV x = V3Dot(a.col0, b); - const FloatV y = V3Dot(a.col1, b); - const FloatV z = V3Dot(a.col2, b); - return V3Merge(x, y, z); -} - -QT3DS_FORCE_INLINE Mat34V M34MulM34(const Mat34V &a, const Mat34V &b) -{ - return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), - M34MulV3(a, b.col3)); -} - -QT3DS_FORCE_INLINE Mat33V M34MulM33(const Mat34V &a, const Mat33V &b) -{ - return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V &a, const Mat34V &b) -{ - return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); -} - -QT3DS_FORCE_INLINE Mat34V M34Add(const Mat34V &a, const Mat34V &b) -{ - return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), - V3Add(a.col3, b.col3)); -} - -QT3DS_FORCE_INLINE Mat34V M34InverseV(const Mat34V &a) -{ - Mat34V aInv; - const BoolV tfft = BTFFT(); - const BoolV tttf = BTTTF(); - const FloatV zero = FloatV_From_F32(0.0f); - const Vec3V cross01 = V3Cross(a.col0, a.col1); - const Vec3V cross12 = V3Cross(a.col1, a.col2); - const Vec3V cross20 = V3Cross(a.col2, a.col0); - const FloatV dot = V3Dot(cross01, a.col2); - const FloatV invDet = _mm_rcp_ps(dot); - const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); - const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); - Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); - colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); - const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); - const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); - const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); - const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); - const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); - const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); - aInv.col0 = _mm_mul_ps(colInv0, invDet); - aInv.col1 = _mm_mul_ps(colInv1, invDet); - aInv.col2 = _mm_mul_ps(colInv2, invDet); - aInv.col3 = M34Mul33V3(aInv, V3Neg(a.col3)); - return aInv; -} - -QT3DS_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V &a) -{ - return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), - V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), - V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); -} - -////////////////////////////////// -// MAT44V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec4V M44MulV4(const Mat44V &a, const Vec4V b) -{ - const FloatV x = V4GetX(b); - const FloatV y = V4GetY(b); - const FloatV z = V4GetZ(b); - const FloatV w = V4GetW(b); - - const Vec4V v0 = V4Scale(a.col0, x); - const Vec4V v1 = V4Scale(a.col1, y); - const Vec4V v2 = V4Scale(a.col2, z); - const Vec4V v3 = V4Scale(a.col3, w); - const Vec4V v0PlusV1 = V4Add(v0, v1); - const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); - return (V4Add(v0PlusV1Plusv2, v3)); -} - -QT3DS_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V &a, const Vec4V b) -{ - QT3DS_ALIGN(16, FloatV) - dotProdArray[4] = { V4Dot(a.col0, b), V4Dot(a.col1, b), V4Dot(a.col2, b), V4Dot(a.col3, b) }; - return V4Merge(dotProdArray); -} - -QT3DS_FORCE_INLINE Mat44V M44MulM44(const Mat44V &a, const Mat44V &b) -{ - return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), - M44MulV4(a, b.col3)); -} - -QT3DS_FORCE_INLINE Mat44V M44Add(const Mat44V &a, const Mat44V &b) -{ - return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), - V4Add(a.col3, b.col3)); -} - -QT3DS_FORCE_INLINE Mat44V M44Trnsps(const Mat44V &a) -{ - const Vec4V v0 = _mm_unpacklo_ps(a.col0, a.col2); - const Vec4V v1 = _mm_unpackhi_ps(a.col0, a.col2); - const Vec4V v2 = _mm_unpacklo_ps(a.col1, a.col3); - const Vec4V v3 = _mm_unpackhi_ps(a.col1, a.col3); - return Mat44V(_mm_unpacklo_ps(v0, v2), _mm_unpackhi_ps(v0, v2), _mm_unpacklo_ps(v1, v3), - _mm_unpackhi_ps(v1, v3)); -} - -QT3DS_FORCE_INLINE Mat44V M44Inverse(const Mat44V &a) -{ - __m128 minor0, minor1, minor2, minor3; - __m128 row0, row1, row2, row3; - __m128 det, tmp1; - - tmp1 = FloatV_From_F32(0.0f); - row1 = FloatV_From_F32(0.0f); - row3 = FloatV_From_F32(0.0f); - - row0 = a.col0; - row1 = _mm_shuffle_ps(a.col1, a.col1, _MM_SHUFFLE(1, 0, 3, 2)); - row2 = a.col2; - row3 = _mm_shuffle_ps(a.col3, a.col3, _MM_SHUFFLE(1, 0, 3, 2)); - - tmp1 = _mm_mul_ps(row2, row3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor0 = _mm_mul_ps(row1, tmp1); - minor1 = _mm_mul_ps(row0, tmp1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); - minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); - minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); - - tmp1 = _mm_mul_ps(row1, row2); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); - minor3 = _mm_mul_ps(row0, tmp1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); - minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); - minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); - - tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - row2 = _mm_shuffle_ps(row2, row2, 0x4E); - minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); - minor2 = _mm_mul_ps(row0, tmp1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); - minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); - minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); - - tmp1 = _mm_mul_ps(row0, row1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); - minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); - minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); - - tmp1 = _mm_mul_ps(row0, row3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); - minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); - minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); - - tmp1 = _mm_mul_ps(row0, row2); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); - minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); - minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); - - det = _mm_mul_ps(row0, minor0); - det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); - det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); - tmp1 = _mm_rcp_ss(det); -#if 0 - det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); - det = _mm_shuffle_ps(det, det, 0x00); -#else - det = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 0, 0, 0)); -#endif - - minor0 = _mm_mul_ps(det, minor0); - minor1 = _mm_mul_ps(det, minor1); - minor2 = _mm_mul_ps(det, minor2); - minor3 = _mm_mul_ps(det, minor3); - Mat44V invTrans(minor0, minor1, minor2, minor3); - return M44Trnsps(invTrans); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_XYZW(QT3DSF32 x, QT3DSF32 y, QT3DSF32 z, QT3DSF32 w) -{ - return _mm_set_ps(w, z, y, x); -} - -// AP: work in progress - use proper SSE intrinsics where possible -QT3DS_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) -{ - VecU16V result; - result.m128_u16[0] = QT3DSU16(NVClamp((a).m128_u32[0], 0, 0xFFFF)); - result.m128_u16[1] = QT3DSU16(NVClamp((a).m128_u32[1], 0, 0xFFFF)); - result.m128_u16[2] = QT3DSU16(NVClamp((a).m128_u32[2], 0, 0xFFFF)); - result.m128_u16[3] = QT3DSU16(NVClamp((a).m128_u32[3], 0, 0xFFFF)); - result.m128_u16[4] = QT3DSU16(NVClamp((b).m128_u32[0], 0, 0xFFFF)); - result.m128_u16[5] = QT3DSU16(NVClamp((b).m128_u32[1], 0, 0xFFFF)); - result.m128_u16[6] = QT3DSU16(NVClamp((b).m128_u32[2], 0, 0xFFFF)); - result.m128_u16[7] = QT3DSU16(NVClamp((b).m128_u32[3], 0, 0xFFFF)); - return result; -} - -QT3DS_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) -{ - return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) -{ - return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) -{ - return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32(const QT3DSI32 i) -{ - return (_mm_load1_ps((QT3DSF32 *)&i)); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array(const QT3DSI32 *i) -{ - return _mm_loadu_ps((QT3DSF32 *)i); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array_Aligned(const QT3DSI32 *i) -{ - return _mm_load_ps((QT3DSF32 *)i); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_add_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_sub_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_cmpgt_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Zero() -{ - return V4Zero(); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, - const VecI32VArg d) -{ - return V4Merge(a, b, c, d); -} - -template -QT3DS_FORCE_INLINE VecI32V V4ISplat() -{ - VecI32V result; - result.m128_i32[0] = a; - result.m128_i32[1] = a; - result.m128_i32[2] = a; - result.m128_i32[3] = a; - return result; -} - -QT3DS_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V *address) -{ - *address = val; -} - -QT3DS_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V *address) -{ - *address = val; -} - -QT3DS_FORCE_INLINE Vec4V V4LoadAligned(Vec4V *addr) -{ - return *addr; -} - -QT3DS_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V *addr) -{ - return Vec4V_From_F32Array((float *)addr); -} - -QT3DS_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) -{ - VecU32V result32(a); - result32 = V4U32Andc(result32, b); - return Vec4V(result32); -} - -QT3DS_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) -{ - return V4IsGrtr(a, b); -} - -QT3DS_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V *addr) -{ - return *addr; -} - -QT3DS_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V *addr) -{ - return *addr; -} - -QT3DS_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) -{ - // _mm_cmpgt_epi16 doesn't work for unsigned values unfortunately - // return m128_I2F(_mm_cmpgt_epi16(m128_F2I(a), m128_F2I(b))); - VecU16V result; - result.m128_u16[0] = (a).m128_u16[0] > (b).m128_u16[0]; - result.m128_u16[1] = (a).m128_u16[1] > (b).m128_u16[1]; - result.m128_u16[2] = (a).m128_u16[2] > (b).m128_u16[2]; - result.m128_u16[3] = (a).m128_u16[3] > (b).m128_u16[3]; - result.m128_u16[4] = (a).m128_u16[4] > (b).m128_u16[4]; - result.m128_u16[5] = (a).m128_u16[5] > (b).m128_u16[5]; - result.m128_u16[6] = (a).m128_u16[6] > (b).m128_u16[6]; - result.m128_u16[7] = (a).m128_u16[7] > (b).m128_u16[7]; - return result; -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) -{ - Vec4V result = Vec4V_From_XYZW(QT3DSF32(a.m128_u32[0]), QT3DSF32(a.m128_u32[1]), QT3DSF32(a.m128_u32[2]), - QT3DSF32(a.m128_u32[3])); - return result; -} - -template -QT3DS_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) -{ - VecU32V result; - result.m128_u32[0] = result.m128_u32[1] = result.m128_u32[2] = result.m128_u32[3] = - a.m128_u32[index]; - return result; -} - -template -QT3DS_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) -{ - float *data = (float *)&a; - return Vec4V_From_F32(data[index]); -} - -template -QT3DS_FORCE_INLINE VecU16V V4U16SplatElement(VecU16V a) -{ - VecU16V result; - for (int i = 0; i < 8; i++) - result.m128_u16[i] = a.m128_u16[index]; - return result; -} - -template -QT3DS_FORCE_INLINE VecI16V V4I16SplatImmediate() -{ - VecI16V result; - result.m128_i16[0] = imm; - result.m128_i16[1] = imm; - result.m128_i16[2] = imm; - result.m128_i16[3] = imm; - result.m128_i16[4] = imm; - result.m128_i16[5] = imm; - result.m128_i16[6] = imm; - result.m128_i16[7] = imm; - return result; -} - -QT3DS_FORCE_INLINE VecU16V V4U16SubtractModulo(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_sub_epi16(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16AddModulo(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_add_epi16(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU32V V4U16GetLo16(VecU16V a) -{ - VecU32V result; - result.m128_u32[0] = a.m128_u16[0]; - result.m128_u32[1] = a.m128_u16[2]; - result.m128_u32[2] = a.m128_u16[4]; - result.m128_u32[3] = a.m128_u16[6]; - return result; -} - -QT3DS_FORCE_INLINE VecU32V V4U16GetHi16(VecU16V a) -{ - VecU32V result; - result.m128_u32[0] = a.m128_u16[1]; - result.m128_u32[1] = a.m128_u16[3]; - result.m128_u32[2] = a.m128_u16[5]; - result.m128_u32[3] = a.m128_u16[7]; - return result; -} - -QT3DS_FORCE_INLINE VecU32V VecU32V_From_XYZW(QT3DSU32 x, QT3DSU32 y, QT3DSU32 z, QT3DSU32 w) -{ - VecU32V result; - result.m128_u32[0] = x; - result.m128_u32[1] = y; - result.m128_u32[2] = z; - result.m128_u32[3] = w; - return result; -} - -QT3DS_FORCE_INLINE Vec4V V4Ceil(const Vec4V in) -{ - UnionM128 a(in); - return Vec4V_From_XYZW(NVCeil(a.m128_f32[0]), NVCeil(a.m128_f32[1]), NVCeil(a.m128_f32[2]), - NVCeil(a.m128_f32[3])); -} - -QT3DS_FORCE_INLINE Vec4V V4Floor(const Vec4V in) -{ - UnionM128 a(in); - return Vec4V_From_XYZW(NVFloor(a.m128_f32[0]), NVFloor(a.m128_f32[1]), NVFloor(a.m128_f32[2]), - NVFloor(a.m128_f32[3])); -} - -QT3DS_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V in, QT3DSU32 power) -{ - QT3DS_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); - QT3DS_FORCE_PARAMETER_REFERENCE(power); // prevent warning in release builds - QT3DSF32 ffffFFFFasFloat = QT3DSF32(0xFFFF0000); - UnionM128 a(in); - VecU32V result; - result.m128_u32[0] = QT3DSU32(NVClamp((a).m128_f32[0], 0.0f, ffffFFFFasFloat)); - result.m128_u32[1] = QT3DSU32(NVClamp((a).m128_f32[1], 0.0f, ffffFFFFasFloat)); - result.m128_u32[2] = QT3DSU32(NVClamp((a).m128_f32[2], 0.0f, ffffFFFFasFloat)); - result.m128_u32[3] = QT3DSU32(NVClamp((a).m128_f32[3], 0.0f, ffffFFFFasFloat)); - return result; -} - -#endif // QT3DS_LINUX_INLINE_AOS_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxIntrinsics.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxIntrinsics.h deleted file mode 100644 index 70974609..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxIntrinsics.h +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_LINUX_INTRINSICS_H -#define QT3DS_FOUNDATION_QT3DS_LINUX_INTRINSICS_H - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" - -#if !(defined QT3DS_LINUX || defined QT3DS_ANDROID || defined QT3DS_APPLE || defined QT3DS_QNX) -#error "This file should only be included by Linux builds!!" -#endif - -#include -#include -#include -#include - -namespace qt3ds { -namespace intrinsics { - //! \brief platform-specific absolute value - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float abs(float a) { return ::fabs(a); } - - //! \brief platform-specific select float - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float fsel(float a, float b, float c) - { - return (a >= 0.0f) ? b : c; - } - - //! \brief platform-specific sign - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sign(float a) { return (a >= 0.0f) ? 1.0f : -1.0f; } - - //! \brief platform-specific reciprocal - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recip(float a) { return 1.0f / a; } - - //! \brief platform-specific reciprocal estimate - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipFast(float a) { return 1.0f / a; } - - //! \brief platform-specific square root - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sqrt(float a) { return ::sqrtf(a); } - - //! \brief platform-specific reciprocal square root - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrt(float a) { return 1.0f / ::sqrtf(a); } - - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrtFast(float a) { return 1.0f / ::sqrtf(a); } - - //! \brief platform-specific sine - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sin(float a) { return ::sinf(a); } - - //! \brief platform-specific cosine - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float cos(float a) { return ::cosf(a); } - - //! \brief platform-specific minimum - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMin(float a, float b) { return a < b ? a : b; } - - //! \brief platform-specific maximum - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMax(float a, float b) { return a > b ? a : b; } - - //! \brief platform-specific finiteness check (not INF or NAN) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(float a) { return std::isfinite(a); } - - //! \brief platform-specific finiteness check (not INF or NAN) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(double a) { return std::isfinite(a); } - QT3DS_FORCE_INLINE void memoryBarrier() - { -#if 0 //!defined (QT3DS_ARM) - smp_mb(); -#endif - } - - /*! - Return the index of the highest set bit. Undefined for zero arg. - */ - QT3DS_INLINE QT3DSU32 highestSetBitUnsafe(QT3DSU32 v) - { - - // http://graphics.stanford.edu/~seander/bithacks.html - static const QT3DSU32 MultiplyDeBruijnBitPosition[32] = { 0, 9, 1, 10, 13, 21, 2, 29, - 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, - 19, 27, 23, 6, 26, 5, 4, 31 }; - - v |= v >> 1; // first round up to one less than a power of 2 - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - return MultiplyDeBruijnBitPosition[(QT3DSU32)(v * 0x07C4ACDDU) >> 27]; - } - - /*! - Return the index of the highest set bit. Undefined for zero arg. - */ - QT3DS_INLINE QT3DSI32 lowestSetBitUnsafe(QT3DSU32 v) - { - // http://graphics.stanford.edu/~seander/bithacks.html - static const QT3DSU32 MultiplyDeBruijnBitPosition[32] = { 0, 1, 28, 2, 29, 14, 24, 3, - 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, - 26, 12, 18, 6, 11, 5, 10, 9 }; - QT3DSI32 w = v; - return MultiplyDeBruijnBitPosition[(QT3DSU32)((w & -w) * 0x077CB531U) >> 27]; - } - - /*! - Returns the index of the highest set bit. Undefined for zero arg. - */ - QT3DS_INLINE QT3DSU32 countLeadingZeros(QT3DSU32 v) - { - QT3DSI32 result = 0; -#ifdef _INTEGRITYPLATFORM - QT3DSU32 testBit = (1U << 31); -#else - QT3DSU32 testBit = (1 << 31); -#endif - while ((v & testBit) == 0 && testBit != 0) - result++, testBit >>= 1; - return result; - } - - /*! - Sets \c count bytes starting at \c dst to zero. - */ - QT3DS_FORCE_INLINE void *memZero(void *QT3DS_RESTRICT dest, QT3DSU32 count) - { - return memset(dest, 0, count); - } - - /*! - Sets \c count bytes starting at \c dst to \c c. - */ - QT3DS_FORCE_INLINE void *memSet(void *QT3DS_RESTRICT dest, QT3DSI32 c, QT3DSU32 count) - { - return memset(dest, c, count); - } - - /*! - Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. - */ - QT3DS_FORCE_INLINE void *memCopy(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) - { - return memcpy(dest, src, count); - } - - /*! - Copies \c count bytes from \c src to \c dst. Supports overlapping regions. - */ - QT3DS_FORCE_INLINE void *memMove(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) - { - return memmove(dest, src, count); - } - - /*! - Set 128B to zero starting at \c dst+offset. Must be aligned. - */ - QT3DS_FORCE_INLINE void memZero128(void *QT3DS_RESTRICT dest, QT3DSU32 offset = 0) - { - QT3DS_ASSERT(((size_t(dest) + offset) & 0x7f) == 0); - memSet((char *QT3DS_RESTRICT)dest + offset, 0, 128); - } - - /*! - Prefetch aligned 128B around \c ptr+offset. - */ - QT3DS_FORCE_INLINE void prefetch128(const void *, QT3DSU32 = 0) {} - - /*! - Prefetch \c count bytes starting at \c ptr. - */ - QT3DS_FORCE_INLINE void prefetch(const void *ptr, QT3DSU32 count = 0) - { - for (QT3DSU32 i = 0; i <= count; i += 128) - prefetch128(ptr, i); - } - - //! \brief platform-specific floor - QT3DS_FORCE_INLINE float floatFloor(float x) { return ::floorf(x); } -} // namespace intrinsics -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxString.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxString.h deleted file mode 100644 index a4645f2b..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxString.h +++ /dev/null @@ -1,202 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_LINUX_STRING_H -#define QT3DS_FOUNDATION_QT3DS_LINUX_STRING_H - -#include "foundation/Qt3DS.h" - -#include -#include -#include - -#pragma warning(push) -#pragma warning(disable : 4995 4996) - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -QT3DS_INLINE void NVStrcpy(char *dest, size_t size, const char *src) -{ - ::strncpy(dest, src, size); -} - -QT3DS_INLINE int NVStrcat(char *dest, size_t size, const char *src) -{ - ::strcat(dest, src); - return 0; -} -QT3DS_INLINE int NVVsprintf(char *dest, size_t size, const char *src, va_list arg) -{ - int r = ::vsprintf(dest, src, arg); - - return r; -} -QT3DS_INLINE int NVStricmp(const char *str, const char *str1) -{ - return (::strcasecmp(str, str1)); -} - -namespace string { - - QT3DS_INLINE void strcpy(char *dest, size_t size, const char *src) { ::strcpy(dest, src); } - QT3DS_INLINE void strcat(char *dest, size_t size, const char *src) { ::strcat(dest, src); } - // QT3DS_INLINE int strcasecmp(const char *str, const char *str1) {return(::strcasecmp(str, - // str1));} - QT3DS_INLINE QT3DSI32 stricmp(const char *str, const char *str1) { return (::strcasecmp(str, str1)); } - QT3DS_INLINE QT3DSI32 strnicmp(const char *str, const char *str1, size_t len) - { - return (::strncasecmp(str, str1, len)); - } - - QT3DS_INLINE QT3DSI32 strncat_s(char *dstBfr, size_t dstSize, const char *srcBfr, size_t numCpy) - { - if (!dstBfr || !srcBfr || !dstSize) - return -1; - - size_t len = strlen(dstBfr); - - if (len >= dstSize) - return -1; - - size_t remain = dstSize - len - 1; - size_t transfer = remain > numCpy ? numCpy : remain; - ::memmove(dstBfr + len, srcBfr, transfer); - dstBfr[len + transfer] = '\0'; - return numCpy <= remain ? 0 : -1; - } - - QT3DS_INLINE QT3DSI32 _vsnprintf(char *dest, size_t size, const char *src, va_list arg) - { - QT3DSI32 r = ::vsnprintf(dest, size, src, arg); - - return r; - } - QT3DS_INLINE QT3DSI32 vsprintf(char *dest, size_t size, const char *src, va_list arg) - { - QT3DSI32 r = ::vsprintf(dest, src, arg); - - return r; - } - QT3DS_INLINE int vsprintf_s(char *dest, size_t size, const char *src, va_list arg) - { - int r = ::vsprintf(dest, src, arg); - - return r; - } - - QT3DS_INLINE int sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...) - { - if (_DstBuf == NULL || _Format == NULL) { - return -1; - } - - va_list arg; - va_start(arg, _Format); - int r = ::vsprintf(_DstBuf, _Format, arg); - va_end(arg); - - return r; - } - - QT3DS_INLINE QT3DSI32 sprintf(char *_DstBuf, size_t _DstSize, const char *_Format, ...) - { - va_list arg; - va_start(arg, _Format); - QT3DSI32 r = ::vsprintf(_DstBuf, _Format, arg); - va_end(arg); - - return r; - } - - QT3DS_INLINE int strncpy_s(char *strDest, size_t sizeInBytes, const char *strSource, size_t count) - { - if (strDest == NULL || strSource == NULL || sizeInBytes == 0) { - return -1; - } - - if (sizeInBytes < count) { - strDest[0] = 0; - return -1; - } - - ::strncpy(strDest, strSource, count); - return 0; - } - - QT3DS_INLINE void strcpy_s(char *dest, size_t size, const char *src) - { - ::strncpy(dest, src, size); - } - - QT3DS_INLINE int strcat_s(char *dest, size_t size, const char *src) - { - ::strcat(dest, src); - return 0; - } - - QT3DS_INLINE QT3DSI32 sscanf(const char *buffer, const char *format, ...) - { - va_list arg; - va_start(arg, format); - QT3DSI32 r = ::sscanf(buffer, format, arg); - va_end(arg); - - return r; - }; - - QT3DS_INLINE void strlwr(char *str) - { - while (*str) { - if (*str >= 'A' && *str <= 'Z') - *str += 32; - str++; - } - } - - QT3DS_INLINE void strupr(char *str) - { - while (*str) { - if (*str >= 'a' && *str <= 'z') - *str -= 32; - str++; - } - } - -} // namespace string - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -#pragma warning(pop) - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxTrigConstants.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxTrigConstants.h deleted file mode 100644 index 120dec78..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/Qt3DSLinuxTrigConstants.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_LINUX_TRIG_CONSTANTS_H -#define QT3DS_LINUX_TRIG_CONSTANTS_H - -//#define QT3DS_GLOBALCONST extern const __declspec(selectany) - -#define QT3DS_GLOBALCONST extern const __attribute__((weak)) - -QT3DS_ALIGN_PREFIX(16) -struct QT3DS_VECTORF32 -{ - float f[4]; -}; - -#define QT3DS_PI 3.141592654f -#define QT3DS_2PI 6.283185307f -#define QT3DS_1DIVPI 0.318309886f -#define QT3DS_1DIV2PI 0.159154943f -#define QT3DS_PIDIV2 1.570796327f -#define QT3DS_PIDIV4 0.785398163f - -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients0 = { 1.0f, -0.166666667f, 8.333333333e-3f, - -1.984126984e-4f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients1 = { 2.755731922e-6f, -2.505210839e-8f, - 1.605904384e-10f, -7.647163732e-13f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients2 = { 2.811457254e-15f, -8.220635247e-18f, - 1.957294106e-20f, -3.868170171e-23f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients0 = { 1.0f, -0.5f, 4.166666667e-2f, - -1.388888889e-3f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients1 = { 2.480158730e-5f, -2.755731922e-7f, - 2.087675699e-9f, -1.147074560e-11f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients2 = { 4.779477332e-14f, -1.561920697e-16f, - 4.110317623e-19f, -8.896791392e-22f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients0 = { 1.0f, 0.333333333f, 0.133333333f, - 5.396825397e-2f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients1 = { 2.186948854e-2f, 8.863235530e-3f, - 3.592128167e-3f, 1.455834485e-3f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients2 = { 5.900274264e-4f, 2.391290764e-4f, - 9.691537707e-5f, 3.927832950e-5f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients0 = { -0.05806367563904f, -0.41861972469416f, - 0.22480114791621f, 2.17337241360606f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients1 = { 0.61657275907170f, 4.29696498283455f, - -1.18942822255452f, -6.53784832094831f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients2 = { -1.36926553863413f, -4.48179294237210f, - 1.41810672941833f, 5.48179257935713f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients0 = { 1.0f, 0.333333334f, 0.2f, 0.142857143f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients1 = { 1.111111111e-1f, 9.090909091e-2f, - 7.692307692e-2f, 6.666666667e-2f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients2 = { 5.882352941e-2f, 5.263157895e-2f, - 4.761904762e-2f, 4.347826087e-2f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinEstCoefficients = { 1.0f, -1.66521856991541e-1f, - 8.199913018755e-3f, -1.61475937228e-4f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosEstCoefficients = { 1.0f, -4.95348008918096e-1f, - 3.878259962881e-2f, -9.24587976263e-4f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanEstCoefficients = { 2.484f, -1.954923183e-1f, 2.467401101f, - QT3DS_1DIVPI }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanEstCoefficients = { 7.689891418951e-1f, 1.104742493348f, - 8.661844266006e-1f, QT3DS_PIDIV2 }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstCoefficients = { -1.36178272886711f, 2.37949493464538f, - -8.08228565650486e-1f, - 2.78440142746736e-1f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstConstants = { 1.00000011921f, QT3DS_PIDIV2, 0.0f, 0.0f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXPiConstants0 = { QT3DS_PI, QT3DS_2PI, QT3DS_1DIVPI, QT3DS_1DIV2PI }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXReciprocalTwoPi = { QT3DS_1DIV2PI, QT3DS_1DIV2PI, QT3DS_1DIV2PI, - QT3DS_1DIV2PI }; - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/qt_attribution.json b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/qt_attribution.json deleted file mode 100644 index 3c3bed6b..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/linux/qt_attribution.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Id": "qt3dslinuxinlineaos", - "Name": "Qt3DSLinuxInlineAoS", - "QDocModule": "qt3dstudio", - "QtUsage": "Used by Qt3DStudio, Runtime component.", - - "License": "Other", - "LicenseFile": "LICENSE.TXT", - "Copyright": "Copyright (c) 2001 Intel Corporation." -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/qt_attribution.json b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/qt_attribution.json deleted file mode 100644 index 067cced8..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/qt_attribution.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Id": "convertutf", - "Name": "ConvertUTF", - "QDocModule": "qt3dstudio", - "QtUsage": "Used by Qt3DStudio, Studio and Runtime components.", - - "License": "Other", - "LicenseFile": "LICENSE_CONVERTUTF.TXT", - "Copyright": "Copyright 2001-2004 Unicode, Inc." -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/LICENSE.TXT b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/LICENSE.TXT deleted file mode 100644 index f40caef8..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/LICENSE.TXT +++ /dev/null @@ -1,7 +0,0 @@ - Copyright (c) 2001 Intel Corporation. - -Permition is granted to use, copy, distribute and prepare derivative works -of this library for any purpose and without fee, provided, that the above -copyright notice and this statement appear in all copies. -Intel makes no representations about the suitability of this library for -any purpose, and specifically disclaims all warranties. diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsAoS.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsAoS.h deleted file mode 100644 index c654ec79..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsAoS.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_WINDOWS_AOS_H -#define QT3DS_WINDOWS_AOS_H - -// no includes here! this file should be included from NVcVecMath.h only!!! - -#if !COMPILE_VECTOR_INTRINSICS -#error Vector intrinsics should not be included when using scalar implementation. -#endif - -typedef __m128 FloatV; -typedef __m128 Vec3V; -typedef __m128 Vec4V; -typedef __m128 BoolV; -typedef __m128 VecU32V; -typedef __m128 VecI32V; -typedef __m128 VecU16V; -typedef __m128 VecI16V; -typedef __m128 VecU8V; -typedef __m128 QuatV; - -#define FloatVArg FloatV & -#define Vec3VArg Vec3V & -#define Vec4VArg Vec4V & -#define BoolVArg BoolV & -#define VecU32VArg VecU32V & -#define VecI32VArg VecI32V & -#define VecU16VArg VecU16V & -#define VecI16VArg VecI16V & -#define VecU8VArg VecU8V & -#define QuatVArg QuatV & - -QT3DS_ALIGN_PREFIX(16) -struct Mat33V -{ - Mat33V() {} - Mat33V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2) - : col0(c0) - , col1(c1) - , col2(c2) - { - } - Vec3V QT3DS_ALIGN(16, col0); - Vec3V QT3DS_ALIGN(16, col1); - Vec3V QT3DS_ALIGN(16, col2); -} QT3DS_ALIGN_SUFFIX(16); - -QT3DS_ALIGN_PREFIX(16) -struct Mat34V -{ - Mat34V() {} - Mat34V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2, const Vec3V &c3) - : col0(c0) - , col1(c1) - , col2(c2) - , col3(c3) - { - } - Vec3V QT3DS_ALIGN(16, col0); - Vec3V QT3DS_ALIGN(16, col1); - Vec3V QT3DS_ALIGN(16, col2); - Vec3V QT3DS_ALIGN(16, col3); -} QT3DS_ALIGN_SUFFIX(16); - -QT3DS_ALIGN_PREFIX(16) -struct Mat43V -{ - Mat43V() {} - Mat43V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2) - : col0(c0) - , col1(c1) - , col2(c2) - { - } - Vec4V QT3DS_ALIGN(16, col0); - Vec4V QT3DS_ALIGN(16, col1); - Vec4V QT3DS_ALIGN(16, col2); -} QT3DS_ALIGN_SUFFIX(16); - -QT3DS_ALIGN_PREFIX(16) -struct Mat44V -{ - Mat44V() {} - Mat44V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2, const Vec4V &c3) - : col0(c0) - , col1(c1) - , col2(c2) - , col3(c3) - { - } - Vec4V QT3DS_ALIGN(16, col0); - Vec4V QT3DS_ALIGN(16, col1); - Vec4V QT3DS_ALIGN(16, col2); - Vec4V QT3DS_ALIGN(16, col3); -} QT3DS_ALIGN_SUFFIX(16); - -#endif // QT3DS_WINDOWS_AOS_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsFile.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsFile.h deleted file mode 100644 index 6c232a54..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsFile.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_WINDOWS_FILE_H -#define QT3DS_FOUNDATION_QT3DS_WINDOWS_FILE_H - -#include "foundation/Qt3DS.h" - -#include - -namespace qt3ds { -namespace foundation { - QT3DS_INLINE errno_t fopen_s(FILE **_File, const char *_Filename, const char *_Mode) - { - return ::fopen_s(_File, _Filename, _Mode); - }; - -} // namespace foundation -} // namespace qt3ds - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInclude.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInclude.h deleted file mode 100644 index f01c9f1a..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInclude.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WINDOWSINCLUDE_H -#define WINDOWSINCLUDE_H - -#include "foundation/Qt3DS.h" - -#ifndef _WIN32 -#error "This file should only be included by Windows builds!!" -#endif - -#ifdef _WINDOWS_ // windows already included -#error "Only include windows.h through this file!!" -#endif - -// We only support >= Windows XP, and we need this for critical section and -#define _WIN32_WINNT 0x0500 - -// turn off as much as we can for windows. All we really need is the thread functions(critical -// sections/Interlocked* etc) -#define NOGDICAPMASKS -#define NOVIRTUALKEYCODES -#define NOWINMESSAGES -#define NOWINSTYLES -#define NOSYSMETRICS -#define NOMENUS -#define NOICONS -#define NOKEYSTATES -#define NOSYSCOMMANDS -#define NORASTEROPS -#define NOSHOWWINDOW -#define NOATOM -#define NOCLIPBOARD -#define NOCOLOR -#define NOCTLMGR -#define NODRAWTEXT -#define NOGDI -#define NOUSER -#define NONLS -#define NOMB -#define NOMEMMGR -#define NOMETAFILE -#define NOMSG -#define NOOPENFILE -#define NOSCROLL -#define NOSERVICE -#define NOSOUND -#define NOTEXTMETRIC -#define NOWH -#define NOWINOFFSETS -#define NOCOMM -#define NOKANJI -#define NOHELP -#define NOPROFILER -#define NODEFERWINDOWPOS -#define NOMCX -#define WIN32_LEAN_AND_MEAN - -#include - -#ifdef QT3DS_SUPPORT_SSE -#include -#endif - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInlineAoS.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInlineAoS.h deleted file mode 100644 index 60c57894..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsInlineAoS.h +++ /dev/null @@ -1,2715 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// Copyright (c) 2001 Intel Corporation. -// -// Permition is granted to use, copy, distribute and prepare derivative works -// of this library for any purpose and without fee, provided, that the above -// copyright notice and this statement appear in all copies. -// Intel makes no representations about the suitability of this library for -// any purpose, and specifically disclaims all warranties. -// See LEGAL.TXT for all the legal information. -// - -#ifndef QT3DS_WINDOWS_INLINE_AOS_H -#define QT3DS_WINDOWS_INLINE_AOS_H - -#if !COMPILE_VECTOR_INTRINSICS -#error Vector intrinsics should not be included when using scalar implementation. -#endif - -// Remove this define when all platforms use simd solver. -#define QT3DS_SUPPORT_SIMD - -QT3DS_FORCE_INLINE __m128 m128_I2F(__m128i n) -{ - return _mm_castsi128_ps(n); -} -QT3DS_FORCE_INLINE __m128i m128_F2I(__m128 n) -{ - return _mm_castps_si128(n); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAllTrue4_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return moveMask == (0xf); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue4_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return moveMask != (0x0); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAllTrue3_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return (moveMask & 0x7) == (0x7); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue3_R(const BoolV a) -{ - const QT3DSI32 moveMask = _mm_movemask_ps(a); - return (moveMask & 0x7) != (0x0); -} - -///////////////////////////////////////////////////////////////////// -////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS -///////////////////////////////////////////////////////////////////// - -QT3DS_FORCE_INLINE QT3DSU32 FiniteTestEq(const Vec4V a, const Vec4V b) -{ - // This is a bit of a bodge. - //_mm_comieq_ss returns 1 if either value is nan so we need to re-cast a and b with true encoded - //as a non-nan number. - // There must be a better way of doing this in sse. - const BoolV one = FOne(); - const BoolV zero = FZero(); - const BoolV a1 = V4Sel(a, one, zero); - const BoolV b1 = V4Sel(b, one, zero); - return (_mm_comieq_ss(a1, b1) && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 1, 1, 1)), - _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(1, 1, 1, 1))) - && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(2, 2, 2, 2)), - _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(2, 2, 2, 2))) - && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 3, 3, 3)), - _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(3, 3, 3, 3)))); -} - -QT3DS_FORCE_INLINE bool isValidFloatV(const FloatV a) -{ - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))) - && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))) - && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)))); -} - -QT3DS_FORCE_INLINE bool isValidVec3V(const Vec3V a) -{ - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero()) ? true : false); -} - -QT3DS_FORCE_INLINE bool isFiniteFloatV(const FloatV a) -{ - const QT3DSU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); - const FloatV vBadNum = FloatV_From_F32((QT3DSF32 &)badNumber); - const BoolV vMask = BAnd(vBadNum, a); - return FiniteTestEq(vMask, BFFFF()) == 1; -} - -QT3DS_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) -{ - const QT3DSU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); - const Vec3V vBadNum = Vec3V_From_F32((QT3DSF32 &)badNumber); - const BoolV vMask = BAnd(BAnd(vBadNum, a), BTTTF()); - return FiniteTestEq(vMask, BFFFF()) == 1; -} - -QT3DS_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) -{ - /*Vec4V a; - QT3DS_ALIGN(16, QT3DSF32 f[4]); - F32Array_Aligned_From_Vec4V(a, f); - return NVIsFinite(f[0]) - && NVIsFinite(f[1]) - && NVIsFinite(f[2]) - && NVIsFinite(f[3]);*/ - - const QT3DSU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); - const Vec4V vBadNum = Vec4V_From_F32((QT3DSF32 &)badNumber); - const BoolV vMask = BAnd(vBadNum, a); - - return FiniteTestEq(vMask, BFFFF()) == 1; -} - -QT3DS_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) ? true : false); -} - -QT3DS_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero())); -} - -QT3DS_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) -{ - return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero()) - || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero())); -} - -///////////////////////////////////////////////////////////////////// -////VECTORISED FUNCTION IMPLEMENTATIONS -///////////////////////////////////////////////////////////////////// - -QT3DS_FORCE_INLINE FloatV FloatV_From_F32(const QT3DSF32 f) -{ - return (_mm_load1_ps(&f)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_F32(const QT3DSF32 f) -{ - return _mm_set_ps(0.0f, f, f, f); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32(const QT3DSF32 f) -{ - return (_mm_load1_ps(&f)); -} - -QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32(const bool f) -{ - const QT3DSU32 i = -(QT3DSI32)f; - return _mm_load1_ps((float *)&i); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_Aligned(const QT3DSVec3 &f) -{ - VECMATHAOS_ASSERT(0 == ((size_t)&f & 0x0f)); - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3(const QT3DSVec3 &f) -{ - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_WUndefined(const QT3DSVec3 &f) -{ - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) -{ - return V4SetW(v, V4Zero()); -} - -QT3DS_FORCE_INLINE Vec3V Vec3V_From_F32Array_Aligned(const QT3DSF32 *const f) -{ - VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); - return (_mm_load_ps(f)); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) -{ - return f; // ok if it is implemented as the same type. -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_NVVec3_WUndefined(const QT3DSVec3 &f) -{ - return (_mm_set_ps(0.0f, f.z, f.y, f.x)); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array_Aligned(const QT3DSF32 *const f) -{ - VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); - return (_mm_load_ps(f)); -} - -QT3DS_FORCE_INLINE void F32Array_Aligned_From_Vec4V(const Vec4V a, QT3DSF32 *f) -{ - VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); - _mm_store_ps(f, a); -} - -QT3DS_FORCE_INLINE void NVU32Array_Aligned_From_BoolV(const BoolV a, QT3DSU32 *f) -{ - VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); - _mm_store_ps((QT3DSF32 *)f, a); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array(const QT3DSF32 *const f) -{ - return (_mm_loadu_ps(f)); -} - -QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32Array(const bool *const f) -{ - const QT3DS_ALIGN(16, QT3DSU32 b[4]) = { -(QT3DSI32)f[0], -(QT3DSI32)f[1], -(QT3DSI32)f[2], -(QT3DSI32)f[3] }; - return _mm_load1_ps((float *)&b); -} - -QT3DS_FORCE_INLINE QT3DSF32 NVF32_From_FloatV(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - QT3DSF32 f; - _mm_store_ss(&f, a); - return f; -} - -QT3DS_FORCE_INLINE void NVF32_From_FloatV(const FloatV a, QT3DSF32 *QT3DS_RESTRICT f) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - _mm_store_ss(f, a); -} - -QT3DS_FORCE_INLINE void NVVec3Aligned_From_Vec3V(const Vec3V a, QT3DSVec3 &f) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); - VECMATHAOS_ASSERT(0 == ((int)&f & 0x0F)); - QT3DS_ALIGN(16, QT3DSF32 f2[4]); - _mm_store_ps(f2, a); - f = QT3DSVec3(f2[0], f2[1], f2[2]); -} - -QT3DS_FORCE_INLINE void Store_From_BoolV(const BoolV b, QT3DSU32 *b2) -{ - _mm_store_ss((QT3DSF32 *)b2, b); -} - -QT3DS_FORCE_INLINE void NVVec3_From_Vec3V(const Vec3V a, QT3DSVec3 &f) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); - QT3DS_ALIGN(16, QT3DSF32 f2[4]); - _mm_store_ps(f2, a); - f = QT3DSVec3(f2[0], f2[1], f2[2]); -} - -QT3DS_FORCE_INLINE Mat33V Mat33V_From_NVMat33(const QT3DSMat33 &m) -{ - return Mat33V(Vec3V_From_NVVec3(m.column0), Vec3V_From_NVVec3(m.column1), - Vec3V_From_NVVec3(m.column2)); -} - -QT3DS_FORCE_INLINE void NVMat33_From_Mat33V(const Mat33V &m, QT3DSMat33 &out) -{ - QT3DS_ASSERT((size_t(&out) & 15) == 0); - NVVec3_From_Vec3V(m.col0, out.column0); - NVVec3_From_Vec3V(m.col1, out.column1); - NVVec3_From_Vec3V(m.col2, out.column2); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualFloatV(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return (_mm_comieq_ss(a, b) != 0); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec3V(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return V3AllEq(a, b) != 0; -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec4V(const Vec4V a, const Vec4V b) -{ - return V4AllEq(a, b) != 0; -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualBoolV(const BoolV a, const BoolV b) -{ - return BAllTrue4_R(VecI32V_IsEq(a, b)) != 0; -} - -#define VECMATH_AOS_EPSILON (1e-3f) - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualFloatV(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - const FloatV c = FSub(a, b); - static const FloatV minError = FloatV_From_F32(-VECMATH_AOS_EPSILON); - static const FloatV maxError = FloatV_From_F32(VECMATH_AOS_EPSILON); - return (_mm_comigt_ss(c, minError) && _mm_comilt_ss(c, maxError)); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - const Vec3V c = V3Sub(a, b); - static const Vec3V minError = Vec3V_From_F32(-VECMATH_AOS_EPSILON); - static const Vec3V maxError = Vec3V_From_F32(VECMATH_AOS_EPSILON); - return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError)); -} - -QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) -{ - const Vec4V c = V4Sub(a, b); - static const Vec4V minError = Vec4V_From_F32(-VECMATH_AOS_EPSILON); - static const Vec4V maxError = Vec4V_From_F32(VECMATH_AOS_EPSILON); - return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError) - && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), minError) - && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), maxError)); -} - -////////////////////////////////// -// FLOATV -////////////////////////////////// - -QT3DS_FORCE_INLINE FloatV FZero() -{ - return FloatV_From_F32(0.0f); -} - -QT3DS_FORCE_INLINE FloatV FOne() -{ - return FloatV_From_F32(1.0f); -} - -QT3DS_FORCE_INLINE FloatV FHalf() -{ - return FloatV_From_F32(0.5f); -} - -QT3DS_FORCE_INLINE FloatV FEps() -{ - return FloatV_From_F32(QT3DS_ENV_REAL); -} - -QT3DS_FORCE_INLINE FloatV FEps6() -{ - return FloatV_From_F32(1e-6f); -} - -QT3DS_FORCE_INLINE FloatV FMax() -{ - return FloatV_From_F32(QT3DS_MAX_REAL); -} - -QT3DS_FORCE_INLINE FloatV FNegMax() -{ - return FloatV_From_F32(-QT3DS_MAX_REAL); -} - -QT3DS_FORCE_INLINE FloatV IZero() -{ - const QT3DSU32 zero = 0; - return _mm_load1_ps((QT3DSF32 *)&zero); -} - -QT3DS_FORCE_INLINE FloatV IOne() -{ - const QT3DSU32 one = 1; - return _mm_load1_ps((QT3DSF32 *)&one); -} - -QT3DS_FORCE_INLINE FloatV ITwo() -{ - const QT3DSU32 two = 2; - return _mm_load1_ps((QT3DSF32 *)&two); -} - -QT3DS_FORCE_INLINE FloatV IThree() -{ - const QT3DSU32 three = 3; - return _mm_load1_ps((QT3DSF32 *)&three); -} - -QT3DS_FORCE_INLINE FloatV IFour() -{ - QT3DSU32 four = 4; - return _mm_load1_ps((QT3DSF32 *)&four); -} - -QT3DS_FORCE_INLINE FloatV FNeg(const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return _mm_sub_ps(_mm_setzero_ps(), f); -} - -QT3DS_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_add_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_sub_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE FloatV FRecip(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return _mm_div_ps(FOne(), a); -} - -QT3DS_FORCE_INLINE FloatV FRecipFast(const FloatV a) -{ - return _mm_rcp_ps(a); -} - -QT3DS_FORCE_INLINE FloatV FRsqrt(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return _mm_div_ps(FOne(), _mm_sqrt_ps(a)); -} - -QT3DS_FORCE_INLINE FloatV FSqrt(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - return _mm_sqrt_ps(a); -} - -QT3DS_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) -{ - return _mm_rsqrt_ps(a); -} - -QT3DS_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidFloatV(c)); - return FAdd(FMul(a, b), c); -} - -QT3DS_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidFloatV(c)); - return FSub(c, FMul(a, b)); -} - -QT3DS_FORCE_INLINE FloatV FAbs(const FloatV a) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - QT3DS_ALIGN(16, const static QT3DSU32 absMask[4]) = { 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF, - 0x7fFFffFF }; - return _mm_and_ps(a, _mm_load_ps((QT3DSF32 *)absMask)); -} - -QT3DS_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(_VecMathTests::allElementsEqualBoolV(c, BTTTT()) - || _VecMathTests::allElementsEqualBoolV(c, BFFFF())); - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); -} - -QT3DS_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_cmpgt_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_cmpge_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_max_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_min_ps(a, b); -} - -QT3DS_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(minV)); - VECMATHAOS_ASSERT(isValidFloatV(maxV)); - return FMax(FMin(a, maxV), minV); -} - -QT3DS_FORCE_INLINE QT3DSU32 FAllGrtr(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return (_mm_comigt_ss(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 FAllGrtrOrEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - - return (_mm_comige_ss(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 FAllEq(const FloatV a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - - return (_mm_comieq_ss(a, b)); -} - -QT3DS_FORCE_INLINE FloatV FRound(const FloatV a) -{ - // return _mm_round_ps(a, 0x0); - const Vec3V half = Vec3V_From_F32(0.5f); - const Vec3V aPlusHalf = V3Add(a, half); - __m128i tmp = _mm_cvttps_epi32(aPlusHalf); - return _mm_cvtepi32_ps(tmp); -} - -QT3DS_FORCE_INLINE FloatV FSin(const FloatV a) -{ - // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; - // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; - FloatV Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const FloatV tmp = FMul(a, twoPi); - const FloatV b = FRound(tmp); - const FloatV V1 = FNegMulSub(twoPi, b, a); - - // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - - // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) - const FloatV V2 = FMul(V1, V1); - const FloatV V3 = FMul(V2, V1); - const FloatV V5 = FMul(V3, V2); - const FloatV V7 = FMul(V5, V2); - const FloatV V9 = FMul(V7, V2); - const FloatV V11 = FMul(V9, V2); - const FloatV V13 = FMul(V11, V2); - const FloatV V15 = FMul(V13, V2); - const FloatV V17 = FMul(V15, V2); - const FloatV V19 = FMul(V17, V2); - const FloatV V21 = FMul(V19, V2); - const FloatV V23 = FMul(V21, V2); - - const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); - const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); - const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); - - const FloatV S1 = V4GetY(sinCoefficients0); - const FloatV S2 = V4GetZ(sinCoefficients0); - const FloatV S3 = V4GetW(sinCoefficients0); - const FloatV S4 = V4GetX(sinCoefficients1); - const FloatV S5 = V4GetY(sinCoefficients1); - const FloatV S6 = V4GetZ(sinCoefficients1); - const FloatV S7 = V4GetW(sinCoefficients1); - const FloatV S8 = V4GetX(sinCoefficients2); - const FloatV S9 = V4GetY(sinCoefficients2); - const FloatV S10 = V4GetZ(sinCoefficients2); - const FloatV S11 = V4GetW(sinCoefficients2); - - Result = FMulAdd(S1, V3, V1); - Result = FMulAdd(S2, V5, Result); - Result = FMulAdd(S3, V7, Result); - Result = FMulAdd(S4, V9, Result); - Result = FMulAdd(S5, V11, Result); - Result = FMulAdd(S6, V13, Result); - Result = FMulAdd(S7, V15, Result); - Result = FMulAdd(S8, V17, Result); - Result = FMulAdd(S9, V19, Result); - Result = FMulAdd(S10, V21, Result); - Result = FMulAdd(S11, V23, Result); - - return Result; -} - -QT3DS_FORCE_INLINE FloatV FCos(const FloatV a) -{ - // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; - // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; - FloatV Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const FloatV tmp = FMul(a, twoPi); - const FloatV b = FRound(tmp); - const FloatV V1 = FNegMulSub(twoPi, b, a); - - // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - - // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) - const FloatV V2 = FMul(V1, V1); - const FloatV V4 = FMul(V2, V2); - const FloatV V6 = FMul(V4, V2); - const FloatV V8 = FMul(V4, V4); - const FloatV V10 = FMul(V6, V4); - const FloatV V12 = FMul(V6, V6); - const FloatV V14 = FMul(V8, V6); - const FloatV V16 = FMul(V8, V8); - const FloatV V18 = FMul(V10, V8); - const FloatV V20 = FMul(V10, V10); - const FloatV V22 = FMul(V12, V10); - - const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); - const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); - const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); - - const FloatV C1 = V4GetY(cosCoefficients0); - const FloatV C2 = V4GetZ(cosCoefficients0); - const FloatV C3 = V4GetW(cosCoefficients0); - const FloatV C4 = V4GetX(cosCoefficients1); - const FloatV C5 = V4GetY(cosCoefficients1); - const FloatV C6 = V4GetZ(cosCoefficients1); - const FloatV C7 = V4GetW(cosCoefficients1); - const FloatV C8 = V4GetX(cosCoefficients2); - const FloatV C9 = V4GetY(cosCoefficients2); - const FloatV C10 = V4GetZ(cosCoefficients2); - const FloatV C11 = V4GetW(cosCoefficients2); - - Result = FMulAdd(C1, V2, V4One()); - Result = FMulAdd(C2, V4, Result); - Result = FMulAdd(C3, V6, Result); - Result = FMulAdd(C4, V8, Result); - Result = FMulAdd(C5, V10, Result); - Result = FMulAdd(C6, V12, Result); - Result = FMulAdd(C7, V14, Result); - Result = FMulAdd(C8, V16, Result); - Result = FMulAdd(C9, V18, Result); - Result = FMulAdd(C10, V20, Result); - Result = FMulAdd(C11, V22, Result); - - return Result; -} - -QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) -{ - const BoolV ffff = BFFFF(); - const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); - return !BAllEq(c, ffff); -} - -QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) -{ - const BoolV tttt = BTTTT(); - const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); - return BAllEq(c, tttt); -} - -QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV bounds) -{ - return FOutOfBounds(a, FNeg(bounds), bounds); -} - -QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV bounds) -{ - return FInBounds(a, FNeg(bounds), bounds); -} - -////////////////////////////////// -// VEC3V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec3V V3Splat(const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - const __m128 zero = V3Zero(); - const __m128 fff0 = _mm_move_ss(f, zero); - return _mm_shuffle_ps(fff0, fff0, _MM_SHUFFLE(0, 1, 2, 3)); -} - -QT3DS_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) -{ - VECMATHAOS_ASSERT(isValidFloatV(x)); - VECMATHAOS_ASSERT(isValidFloatV(y)); - VECMATHAOS_ASSERT(isValidFloatV(z)); - // static on zero causes compiler crash on x64 debug_opt - const __m128 zero = V3Zero(); - const __m128 xy = _mm_move_ss(x, y); - const __m128 z0 = _mm_move_ss(zero, z); - - return _mm_shuffle_ps(xy, z0, _MM_SHUFFLE(1, 0, 0, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3UnitX() -{ - const QT3DS_ALIGN(16, QT3DSF32 x[4]) = { 1.0f, 0.0f, 0.0f, 0.0f }; - const __m128 x128 = _mm_load_ps(x); - return x128; -} - -QT3DS_FORCE_INLINE Vec3V V3UnitY() -{ - const QT3DS_ALIGN(16, QT3DSF32 y[4]) = { 0.0f, 1.0f, 0.0f, 0.0f }; - const __m128 y128 = _mm_load_ps(y); - return y128; -} - -QT3DS_FORCE_INLINE Vec3V V3UnitZ() -{ - const QT3DS_ALIGN(16, QT3DSF32 z[4]) = { 0.0f, 0.0f, 1.0f, 0.0f }; - const __m128 z128 = _mm_load_ps(z); - return z128; -} - -QT3DS_FORCE_INLINE FloatV V3GetX(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE FloatV V3GetY(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); -} - -QT3DS_FORCE_INLINE FloatV V3GetZ(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V3Sel(BFTTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V3Sel(BTFTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V3Sel(BTTFT(), v, f); -} - -QT3DS_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) -{ - Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 0, 3, 0)); - return V3SetY(r, V3GetX(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) -{ - Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); - return V3SetY(r, V3GetY(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) -{ - Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 2, 3, 2)); - return V3SetY(r, V3GetZ(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3Zero() -{ - return Vec3V_From_F32(0.0f); -} - -QT3DS_FORCE_INLINE Vec3V V3One() -{ - return Vec3V_From_F32(1.0f); -} - -QT3DS_FORCE_INLINE Vec3V V3Eps() -{ - return Vec3V_From_F32(QT3DS_ENV_REAL); -} - -QT3DS_FORCE_INLINE Vec3V V3Neg(const Vec3V f) -{ - VECMATHAOS_ASSERT(isValidVec3V(f)); - return _mm_sub_ps(_mm_setzero_ps(), f); -} - -QT3DS_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_add_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_sub_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - // why are these here? - // static const __m128 one=V3One(); - // static const __m128 tttf=BTTTF(); - // const __m128 b1=V3Sel(tttf,b,one); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - const __m128 one = V3One(); - const __m128 tttf = BTTTF(); - const __m128 b1 = V3Sel(tttf, b, one); - return _mm_mul_ps(a, _mm_rcp_ps(b1)); -} - -QT3DS_FORCE_INLINE Vec3V V3Recip(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 tttf = BTTTF(); - const __m128 recipA = _mm_div_ps(V3One(), a); - return V3Sel(tttf, recipA, zero); -} - -QT3DS_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 tttf = BTTTF(); - const __m128 recipA = _mm_rcp_ps(a); - return V3Sel(tttf, recipA, zero); -} - -QT3DS_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 tttf = BTTTF(); - const __m128 recipA = _mm_div_ps(V3One(), _mm_sqrt_ps(a)); - return V3Sel(tttf, recipA, zero); -} - -QT3DS_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 tttf = BTTTF(); - const __m128 recipA = _mm_rsqrt_ps(a); - return V3Sel(tttf, recipA, zero); -} - -QT3DS_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Add(V3Scale(a, b), c); -} - -QT3DS_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidFloatV(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Sub(c, V3Scale(a, b)); -} - -QT3DS_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Add(V3Mul(a, b), c); -} - -QT3DS_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - VECMATHAOS_ASSERT(isValidVec3V(c)); - return V3Sub(c, V3Mul(a, b)); -} - -QT3DS_FORCE_INLINE Vec3V V3Abs(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Max(a, V3Neg(a)); -} - -QT3DS_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - __m128 dot1 = _mm_mul_ps(a, b); // w,z,y,x - //__m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2,1,0,3)); //z,y,x,w - //__m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1,0,3,2)); //y,x,w,z - //__m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0,3,2,1)); //x,w,z,y - // return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1,shuf1)); - - __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w - __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z - __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y - return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); -} - -QT3DS_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w - __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w - __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w - __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w - return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); -} - -QT3DS_FORCE_INLINE FloatV V3Length(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_sqrt_ps(V3Dot(a, a)); -} - -QT3DS_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Dot(a, a); -} - -QT3DS_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(V3Dot(a, a) != FZero()) - return V3ScaleInv(a, _mm_sqrt_ps(V3Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return V3Mul(a, _mm_rsqrt_ps(V3Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 eps = V3Eps(); - const __m128 length = V3Length(a); - const __m128 isGreaterThanZero = FIsGrtr(length, eps); - return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), zero); -} - -QT3DS_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); -} - -QT3DS_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_cmpgt_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_cmpge_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_max_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(b)); - return _mm_min_ps(a, b); -} - -// Extract the maximum value from a -QT3DS_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) -{ - const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); - const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); - const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); - - return _mm_max_ps(_mm_max_ps(shuf1, shuf2), shuf3); -} - -// Extract the maximum value from a -QT3DS_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) -{ - const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); - const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); - const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); - - return _mm_min_ps(_mm_min_ps(shuf1, shuf2), shuf3); -} - -//// if(a > 0.0f) return 1.0f; else if a == 0.f return 0.f, else return -1.f; -// QT3DS_FORCE_INLINE Vec3V V3MathSign(const Vec3V a) -//{ -// VECMATHAOS_ASSERT(isValidVec3V(a)); -// -// const __m128i ai = _mm_cvtps_epi32(a); -// const __m128i bi = _mm_cvtps_epi32(V3Neg(a)); -// const __m128 aa = _mm_cvtepi32_ps(_mm_srai_epi32(ai, 31)); -// const __m128 bb = _mm_cvtepi32_ps(_mm_srai_epi32(bi, 31)); -// return _mm_or_ps(aa, bb); -//} - -// return (a >= 0.0f) ? 1.0f : -1.0f; -QT3DS_FORCE_INLINE Vec3V V3Sign(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - const __m128 zero = V3Zero(); - const __m128 one = V3One(); - const __m128 none = V3Neg(one); - return V3Sel(V3IsGrtrOrEq(a, zero), one, none); -} - -QT3DS_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(minV)); - VECMATHAOS_ASSERT(isValidVec3V(maxV)); - return V3Max(V3Min(a, maxV), minV); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtr(const Vec3V a, const Vec3V b) -{ - return BAllTrue3_R(V4IsGrtr(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) -{ - return BAllTrue3_R(V4IsGrtrOrEq(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3AllEq(const Vec3V a, const Vec3V b) -{ - return BAllTrue3_R(V4IsEq(a, b)); -} - -QT3DS_FORCE_INLINE Vec3V V3Round(const Vec3V a) -{ - // return _mm_round_ps(a, 0x0); - const Vec3V half = Vec3V_From_F32(0.5f); - const Vec3V aPlusHalf = V3Add(a, half); - const __m128i tmp = _mm_cvttps_epi32(aPlusHalf); - return _mm_cvtepi32_ps(tmp); -} - -QT3DS_FORCE_INLINE Vec3V V3Sin(const Vec3V a) -{ - // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; - // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; - Vec3V Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec3V tmp = V3Mul(a, twoPi); - const Vec3V b = V3Round(tmp); - const Vec3V V1 = V3NegMulSub(twoPi, b, a); - - // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - - // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) - const Vec3V V2 = V3Mul(V1, V1); - const Vec3V V3 = V3Mul(V2, V1); - const Vec3V V5 = V3Mul(V3, V2); - const Vec3V V7 = V3Mul(V5, V2); - const Vec3V V9 = V3Mul(V7, V2); - const Vec3V V11 = V3Mul(V9, V2); - const Vec3V V13 = V3Mul(V11, V2); - const Vec3V V15 = V3Mul(V13, V2); - const Vec3V V17 = V3Mul(V15, V2); - const Vec3V V19 = V3Mul(V17, V2); - const Vec3V V21 = V3Mul(V19, V2); - const Vec3V V23 = V3Mul(V21, V2); - - const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); - const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); - const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); - - const FloatV S1 = V4GetY(sinCoefficients0); - const FloatV S2 = V4GetZ(sinCoefficients0); - const FloatV S3 = V4GetW(sinCoefficients0); - const FloatV S4 = V4GetX(sinCoefficients1); - const FloatV S5 = V4GetY(sinCoefficients1); - const FloatV S6 = V4GetZ(sinCoefficients1); - const FloatV S7 = V4GetW(sinCoefficients1); - const FloatV S8 = V4GetX(sinCoefficients2); - const FloatV S9 = V4GetY(sinCoefficients2); - const FloatV S10 = V4GetZ(sinCoefficients2); - const FloatV S11 = V4GetW(sinCoefficients2); - - Result = V3MulAdd(S1, V3, V1); - Result = V3MulAdd(S2, V5, Result); - Result = V3MulAdd(S3, V7, Result); - Result = V3MulAdd(S4, V9, Result); - Result = V3MulAdd(S5, V11, Result); - Result = V3MulAdd(S6, V13, Result); - Result = V3MulAdd(S7, V15, Result); - Result = V3MulAdd(S8, V17, Result); - Result = V3MulAdd(S9, V19, Result); - Result = V3MulAdd(S10, V21, Result); - Result = V3MulAdd(S11, V23, Result); - - return Result; -} - -QT3DS_FORCE_INLINE Vec3V V3Cos(const Vec3V a) -{ - // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; - // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; - Vec3V Result; - - // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI - const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec3V tmp = V3Mul(a, twoPi); - const Vec3V b = V3Round(tmp); - const Vec3V V1 = V3NegMulSub(twoPi, b, a); - - // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - - // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) - const Vec3V V2 = V3Mul(V1, V1); - const Vec3V V4 = V3Mul(V2, V2); - const Vec3V V6 = V3Mul(V4, V2); - const Vec3V V8 = V3Mul(V4, V4); - const Vec3V V10 = V3Mul(V6, V4); - const Vec3V V12 = V3Mul(V6, V6); - const Vec3V V14 = V3Mul(V8, V6); - const Vec3V V16 = V3Mul(V8, V8); - const Vec3V V18 = V3Mul(V10, V8); - const Vec3V V20 = V3Mul(V10, V10); - const Vec3V V22 = V3Mul(V12, V10); - - const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); - const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); - const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); - - const FloatV C1 = V4GetY(cosCoefficients0); - const FloatV C2 = V4GetZ(cosCoefficients0); - const FloatV C3 = V4GetW(cosCoefficients0); - const FloatV C4 = V4GetX(cosCoefficients1); - const FloatV C5 = V4GetY(cosCoefficients1); - const FloatV C6 = V4GetZ(cosCoefficients1); - const FloatV C7 = V4GetW(cosCoefficients1); - const FloatV C8 = V4GetX(cosCoefficients2); - const FloatV C9 = V4GetY(cosCoefficients2); - const FloatV C10 = V4GetZ(cosCoefficients2); - const FloatV C11 = V4GetW(cosCoefficients2); - - Result = V3MulAdd(C1, V2, V4One()); - Result = V3MulAdd(C2, V4, Result); - Result = V3MulAdd(C3, V6, Result); - Result = V3MulAdd(C4, V8, Result); - Result = V3MulAdd(C5, V10, Result); - Result = V3MulAdd(C6, V12, Result); - Result = V3MulAdd(C7, V14, Result); - Result = V3MulAdd(C8, V16, Result); - Result = V3MulAdd(C9, V18, Result); - Result = V3MulAdd(C10, V20, Result); - Result = V3MulAdd(C11, V22, Result); - - return Result; -} - -QT3DS_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 2, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 0)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)) - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 2, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 0, 1)); -} - -QT3DS_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) -{ - VECMATHAOS_ASSERT(isValidVec3V(v0)); - VECMATHAOS_ASSERT(isValidVec3V(v1)); - return _mm_shuffle_ps(v1, v0, _MM_SHUFFLE(3, 1, 2, 3)); -} - -QT3DS_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) -{ - VECMATHAOS_ASSERT(isValidVec3V(v0)); - VECMATHAOS_ASSERT(isValidVec3V(v1)); - return _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 0, 3, 2)); -} - -QT3DS_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) -{ - VECMATHAOS_ASSERT(isValidVec3V(v0)); - VECMATHAOS_ASSERT(isValidVec3V(v1)); - // There must be a better way to do this. - Vec3V v2 = V3Zero(); - FloatV y1 = V3GetY(v1); - FloatV x0 = V3GetX(v0); - v2 = V3SetX(v2, y1); - return V3SetY(v2, x0); -} - -QT3DS_FORCE_INLINE FloatV V3SumElems(const Vec3V a) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - - __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w - __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z - __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y - return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(min)); - VECMATHAOS_ASSERT(isValidVec3V(max)); - const BoolV ffff = BFFFF(); - const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); - return !BAllEq(c, ffff); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) -{ - VECMATHAOS_ASSERT(isValidVec3V(a)); - VECMATHAOS_ASSERT(isValidVec3V(min)); - VECMATHAOS_ASSERT(isValidVec3V(max)); - const BoolV tttt = BTTTT(); - const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); - return BAllEq(c, tttt); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) -{ - return V3OutOfBounds(a, V3Neg(bounds), bounds); -} - -QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V bounds) -{ - return V3InBounds(a, V3Neg(bounds), bounds); -} - -////////////////////////////////// -// VEC4V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec4V V4Splat(const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - // return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0,0,0,0)); - return f; -} - -QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatV *const floatVArray) -{ - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[0])); - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[1])); - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[2])); - VECMATHAOS_ASSERT(isValidFloatV(floatVArray[3])); - __m128 xw = _mm_move_ss(floatVArray[1], floatVArray[0]); // y, y, y, x - __m128 yz = _mm_move_ss(floatVArray[2], floatVArray[3]); // z, z, z, w - return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); -} - -QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, - const FloatVArg w) -{ - VECMATHAOS_ASSERT(isValidFloatV(x)); - VECMATHAOS_ASSERT(isValidFloatV(y)); - VECMATHAOS_ASSERT(isValidFloatV(z)); - VECMATHAOS_ASSERT(isValidFloatV(w)); - __m128 xw = _mm_move_ss(y, x); // y, y, y, x - __m128 yz = _mm_move_ss(z, w); // z, z, z, w - return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); -} - -QT3DS_FORCE_INLINE Vec4V V4UnitW() -{ - const QT3DS_ALIGN(16, QT3DSF32 w[4]) = { 0.0f, 0.0f, 0.0f, 1.0f }; - const __m128 w128 = _mm_load_ps(w); - return w128; -} - -QT3DS_FORCE_INLINE Vec4V V4UnitX() -{ - const QT3DS_ALIGN(16, QT3DSF32 x[4]) = { 1.0f, 0.0f, 0.0f, 0.0f }; - const __m128 x128 = _mm_load_ps(x); - return x128; -} - -QT3DS_FORCE_INLINE Vec4V V4UnitY() -{ - const QT3DS_ALIGN(16, QT3DSF32 y[4]) = { 0.0f, 1.0f, 0.0f, 0.0f }; - const __m128 y128 = _mm_load_ps(y); - return y128; -} - -QT3DS_FORCE_INLINE Vec4V V4UnitZ() -{ - const QT3DS_ALIGN(16, QT3DSF32 z[4]) = { 0.0f, 0.0f, 1.0f, 0.0f }; - const __m128 z128 = _mm_load_ps(z); - return z128; -} - -QT3DS_FORCE_INLINE FloatV V4GetW(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); -} - -QT3DS_FORCE_INLINE FloatV V4GetX(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE FloatV V4GetY(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); -} - -QT3DS_FORCE_INLINE FloatV V4GetZ(const Vec4V f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); -} - -QT3DS_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BTTTF(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BFTTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BTFTT(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) -{ - VECMATHAOS_ASSERT(isValidVec3V(v)); - VECMATHAOS_ASSERT(isValidFloatV(f)); - return V4Sel(BTTFT(), v, f); -} - -QT3DS_FORCE_INLINE Vec4V V4Zero() -{ - return Vec4V_From_F32(0.0f); -} - -QT3DS_FORCE_INLINE Vec4V V4One() -{ - return Vec4V_From_F32(1.0f); -} - -QT3DS_FORCE_INLINE Vec4V V4Eps() -{ - return Vec4V_From_F32(QT3DS_ENV_REAL); -} - -QT3DS_FORCE_INLINE Vec4V V4Neg(const Vec4V f) -{ - return _mm_sub_ps(_mm_setzero_ps(), f); -} - -QT3DS_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) -{ - return _mm_add_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) -{ - return _mm_sub_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) -{ - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) -{ - return _mm_mul_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) -{ - return _mm_div_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) -{ - return _mm_mul_ps(a, _mm_rcp_ps(b)); -} - -QT3DS_FORCE_INLINE Vec4V V4Recip(const Vec4V a) -{ - return _mm_div_ps(V4One(), a); -} - -QT3DS_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) -{ - return _mm_rcp_ps(a); -} - -QT3DS_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) -{ - return _mm_div_ps(V4One(), _mm_sqrt_ps(a)); -} - -QT3DS_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) -{ - return _mm_rsqrt_ps(a); -} - -QT3DS_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return V4Add(V4Scale(a, b), c); -} - -QT3DS_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) -{ - VECMATHAOS_ASSERT(isValidFloatV(b)); - return V4Sub(c, V4Scale(a, b)); -} - -QT3DS_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) -{ - return V4Add(V4Mul(a, b), c); -} - -QT3DS_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) -{ - return V4Sub(c, V4Mul(a, b)); -} - -QT3DS_FORCE_INLINE Vec4V V4Abs(const Vec4V a) -{ - return V4Max(a, V4Neg(a)); -} - -QT3DS_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) -{ - __m128 dot1 = _mm_mul_ps(a, b); // x,y,z,w - __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 1, 0, 3)); // w,x,y,z - __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 0, 3, 2)); // z,w,x,y - __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 3, 2, 1)); // y,z,w,x - return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1, shuf1)); -} - -QT3DS_FORCE_INLINE FloatV V4Length(const Vec4V a) -{ - return _mm_sqrt_ps(V4Dot(a, a)); -} - -QT3DS_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) -{ - return V4Dot(a, a); -} - -QT3DS_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) -{ - VECMATHAOS_ASSERT(V4Dot(a, a) != FZero()) - return V4ScaleInv(a, _mm_sqrt_ps(V4Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) -{ - return V4ScaleInvFast(a, _mm_sqrt_ps(V4Dot(a, a))); -} - -QT3DS_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a) -{ - const __m128 zero = FZero(); - const __m128 eps = V3Eps(); - const __m128 length = V4Length(a); - const __m128 isGreaterThanZero = V4IsGrtr(length, eps); - return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), zero); -} - -QT3DS_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) -{ - return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); -} - -QT3DS_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) -{ - return _mm_cmpgt_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) -{ - return _mm_cmpge_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) -{ - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) -{ - return _mm_cmpeq_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec3V V4Max(const Vec4V a, const Vec4V b) -{ - return _mm_max_ps(a, b); -} - -QT3DS_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) -{ - return _mm_min_ps(a, b); -} - -// Extract the maximum value from a -QT3DS_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) -{ - __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); - __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); - __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); - - return _mm_max_ps(_mm_max_ps(a, shuf1), _mm_max_ps(shuf2, shuf3)); -} - -// Extract the maximum value from a -QT3DS_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a) -{ - __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); - __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); - __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); - - return _mm_min_ps(_mm_min_ps(a, shuf1), _mm_min_ps(shuf2, shuf3)); -} - -QT3DS_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) -{ - return V4Max(V4Min(a, maxV), minV); -} - -QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtr(const Vec4V a, const Vec4V b) -{ - return BAllTrue4_R(V4IsGrtr(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) -{ - return BAllTrue4_R(V4IsGrtrOrEq(a, b)); -} - -QT3DS_FORCE_INLINE QT3DSU32 V4AllEq(const Vec4V a, const Vec4V b) -{ - return BAllTrue4_R(V4IsEq(a, b)); -} - -QT3DS_FORCE_INLINE Vec4V V4Round(const Vec4V a) -{ - // return _mm_round_ps(a, 0x0); - const Vec3V half = Vec3V_From_F32(0.5f); - const Vec3V aPlusHalf = V3Add(a, half); - __m128i tmp = _mm_cvttps_epi32(aPlusHalf); - return _mm_cvtepi32_ps(tmp); -} - -QT3DS_FORCE_INLINE Vec4V V4Sin(const Vec4V a) -{ - // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; - // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; - Vec4V Result; - - const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec4V tmp = V4Mul(a, twoPi); - const Vec4V b = V4Round(tmp); - const Vec4V V1 = V4NegMulSub(twoPi, b, a); - - // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - - // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) - const Vec4V V2 = V4Mul(V1, V1); - const Vec4V V3 = V4Mul(V2, V1); - const Vec4V V5 = V4Mul(V3, V2); - const Vec4V V7 = V4Mul(V5, V2); - const Vec4V V9 = V4Mul(V7, V2); - const Vec4V V11 = V4Mul(V9, V2); - const Vec4V V13 = V4Mul(V11, V2); - const Vec4V V15 = V4Mul(V13, V2); - const Vec4V V17 = V4Mul(V15, V2); - const Vec4V V19 = V4Mul(V17, V2); - const Vec4V V21 = V4Mul(V19, V2); - const Vec4V V23 = V4Mul(V21, V2); - - const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); - const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); - const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); - - const FloatV S1 = V4GetY(sinCoefficients0); - const FloatV S2 = V4GetZ(sinCoefficients0); - const FloatV S3 = V4GetW(sinCoefficients0); - const FloatV S4 = V4GetX(sinCoefficients1); - const FloatV S5 = V4GetY(sinCoefficients1); - const FloatV S6 = V4GetZ(sinCoefficients1); - const FloatV S7 = V4GetW(sinCoefficients1); - const FloatV S8 = V4GetX(sinCoefficients2); - const FloatV S9 = V4GetY(sinCoefficients2); - const FloatV S10 = V4GetZ(sinCoefficients2); - const FloatV S11 = V4GetW(sinCoefficients2); - - Result = V4MulAdd(S1, V3, V1); - Result = V4MulAdd(S2, V5, Result); - Result = V4MulAdd(S3, V7, Result); - Result = V4MulAdd(S4, V9, Result); - Result = V4MulAdd(S5, V11, Result); - Result = V4MulAdd(S6, V13, Result); - Result = V4MulAdd(S7, V15, Result); - Result = V4MulAdd(S8, V17, Result); - Result = V4MulAdd(S9, V19, Result); - Result = V4MulAdd(S10, V21, Result); - Result = V4MulAdd(S11, V23, Result); - - return Result; -} - -QT3DS_FORCE_INLINE Vec4V V4Cos(const Vec4V a) -{ - // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; - // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; - Vec4V Result; - - const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); - const Vec4V tmp = V4Mul(a, twoPi); - const Vec4V b = V4Round(tmp); - const Vec4V V1 = V4NegMulSub(twoPi, b, a); - - // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - - // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) - const Vec4V V2 = V4Mul(V1, V1); - const Vec4V V4 = V4Mul(V2, V2); - const Vec4V V6 = V4Mul(V4, V2); - const Vec4V V8 = V4Mul(V4, V4); - const Vec4V V10 = V4Mul(V6, V4); - const Vec4V V12 = V4Mul(V6, V6); - const Vec4V V14 = V4Mul(V8, V6); - const Vec4V V16 = V4Mul(V8, V8); - const Vec4V V18 = V4Mul(V10, V8); - const Vec4V V20 = V4Mul(V10, V10); - const Vec4V V22 = V4Mul(V12, V10); - - const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); - const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); - const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); - - const FloatV C1 = V4GetY(cosCoefficients0); - const FloatV C2 = V4GetZ(cosCoefficients0); - const FloatV C3 = V4GetW(cosCoefficients0); - const FloatV C4 = V4GetX(cosCoefficients1); - const FloatV C5 = V4GetY(cosCoefficients1); - const FloatV C6 = V4GetZ(cosCoefficients1); - const FloatV C7 = V4GetW(cosCoefficients1); - const FloatV C8 = V4GetX(cosCoefficients2); - const FloatV C9 = V4GetY(cosCoefficients2); - const FloatV C10 = V4GetZ(cosCoefficients2); - const FloatV C11 = V4GetW(cosCoefficients2); - - Result = V4MulAdd(C1, V2, V4One()); - Result = V4MulAdd(C2, V4, Result); - Result = V4MulAdd(C3, V6, Result); - Result = V4MulAdd(C4, V8, Result); - Result = V4MulAdd(C5, V10, Result); - Result = V4MulAdd(C6, V12, Result); - Result = V4MulAdd(C7, V14, Result); - Result = V4MulAdd(C8, V16, Result); - Result = V4MulAdd(C9, V18, Result); - Result = V4MulAdd(C10, V20, Result); - Result = V4MulAdd(C11, V22, Result); - - return Result; -} - -////////////////////////////////// -// BoolV -////////////////////////////////// - -QT3DS_FORCE_INLINE BoolV BFFFF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0, 0 }; - const __m128 ffff = _mm_load_ps((float *)&f); - return ffff; -} - -QT3DS_FORCE_INLINE BoolV BFFFT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0, 0xFFFFFFFF }; - const __m128 ffft = _mm_load_ps((float *)&f); - return ffft; -} - -QT3DS_FORCE_INLINE BoolV BFFTF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0xFFFFFFFF, 0 }; - const __m128 fftf = _mm_load_ps((float *)&f); - return fftf; -} - -QT3DS_FORCE_INLINE BoolV BFFTT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 fftt = _mm_load_ps((float *)&f); - return fftt; -} - -QT3DS_FORCE_INLINE BoolV BFTFF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0, 0 }; - const __m128 ftff = _mm_load_ps((float *)&f); - return ftff; -} - -QT3DS_FORCE_INLINE BoolV BFTFT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0, 0xFFFFFFFF }; - const __m128 ftft = _mm_load_ps((float *)&f); - return ftft; -} - -QT3DS_FORCE_INLINE BoolV BFTTF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; - const __m128 fttf = _mm_load_ps((float *)&f); - return fttf; -} - -QT3DS_FORCE_INLINE BoolV BFTTT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 fttt = _mm_load_ps((float *)&f); - return fttt; -} - -QT3DS_FORCE_INLINE BoolV BTFFF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0, 0 }; - const __m128 tfff = _mm_load_ps((float *)&f); - return tfff; -} - -QT3DS_FORCE_INLINE BoolV BTFFT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0, 0xFFFFFFFF }; - const __m128 tfft = _mm_load_ps((float *)&f); - return tfft; -} - -QT3DS_FORCE_INLINE BoolV BTFTF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0 }; - const __m128 tftf = _mm_load_ps((float *)&f); - return tftf; -} - -QT3DS_FORCE_INLINE BoolV BTFTT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 tftt = _mm_load_ps((float *)&f); - return tftt; -} - -QT3DS_FORCE_INLINE BoolV BTTFF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0 }; - const __m128 ttff = _mm_load_ps((float *)&f); - return ttff; -} - -QT3DS_FORCE_INLINE BoolV BTTFT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF }; - const __m128 ttft = _mm_load_ps((float *)&f); - return ttft; -} - -QT3DS_FORCE_INLINE BoolV BTTTF() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; - const __m128 tttf = _mm_load_ps((float *)&f); - return tttf; -} - -QT3DS_FORCE_INLINE BoolV BTTTT() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - const __m128 tttt = _mm_load_ps((float *)&f); - return tttt; -} - -QT3DS_FORCE_INLINE BoolV BXMask() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0, 0 }; - const __m128 tfff = _mm_load_ps((float *)&f); - return tfff; -} - -QT3DS_FORCE_INLINE BoolV BYMask() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0, 0 }; - const __m128 ftff = _mm_load_ps((float *)&f); - return ftff; -} - -QT3DS_FORCE_INLINE BoolV BZMask() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0xFFFFFFFF, 0 }; - const __m128 fftf = _mm_load_ps((float *)&f); - return fftf; -} - -QT3DS_FORCE_INLINE BoolV BWMask() -{ - const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0, 0xFFFFFFFF }; - const __m128 ffft = _mm_load_ps((float *)&f); - return ffft; -} - -QT3DS_FORCE_INLINE BoolV BGetX(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); -} - -QT3DS_FORCE_INLINE BoolV BGetY(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); -} - -QT3DS_FORCE_INLINE BoolV BGetZ(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); -} - -QT3DS_FORCE_INLINE BoolV BGetW(const BoolV f) -{ - return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); -} - -QT3DS_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) -{ - return (_mm_and_ps(a, b)); -} - -QT3DS_FORCE_INLINE BoolV BNot(const BoolV a) -{ - const BoolV bAllTrue(BTTTT()); - return _mm_xor_ps(a, bAllTrue); -} - -QT3DS_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) -{ - return (_mm_andnot_ps(a, b)); -} - -QT3DS_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) -{ - return (_mm_or_ps(a, b)); -} - -QT3DS_FORCE_INLINE BoolV BAllTrue4(const BoolV a) -{ - const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); - return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) -{ - const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); - return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE BoolV BAllTrue3(const BoolV a) -{ - const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); - return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) -{ - const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), - _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); - return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), - _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); -} - -QT3DS_FORCE_INLINE QT3DSU32 BAllEq(const BoolV a, const BoolV b) -{ - const BoolV bTest = m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); - return BAllTrue4_R(bTest); -} - -////////////////////////////////// -// MAT33V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec3V M33MulV3(const Mat33V &a, const Vec3V b) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - const Vec3V v0 = V3Scale(a.col0, x); - const Vec3V v1 = V3Scale(a.col1, y); - const Vec3V v2 = V3Scale(a.col2, z); - const Vec3V v0PlusV1 = V3Add(v0, v1); - return V3Add(v0PlusV1, v2); -} - -QT3DS_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V &a, const Vec3V b) -{ - const FloatV x = V3Dot(a.col0, b); - const FloatV y = V3Dot(a.col1, b); - const FloatV z = V3Dot(a.col2, b); - return V3Merge(x, y, z); -} - -QT3DS_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V &A, const Vec3V b, const Vec3V c) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - Vec3V result = V3MulAdd(A.col0, x, c); - result = V3MulAdd(A.col1, y, result); - return V3MulAdd(A.col2, z, result); -} - -QT3DS_FORCE_INLINE Mat33V M33MulM33(const Mat33V &a, const Mat33V &b) -{ - return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Add(const Mat33V &a, const Mat33V &b) -{ - return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Sub(const Mat33V &a, const Mat33V &b) -{ - return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Neg(const Mat33V &a) -{ - return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Abs(const Mat33V &a) -{ - return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M33Inverse(const Mat33V &a) -{ - const BoolV tfft = BTFFT(); - const BoolV tttf = BTTTF(); - const FloatV zero = V3Zero(); - const Vec3V cross01 = V3Cross(a.col0, a.col1); - const Vec3V cross12 = V3Cross(a.col1, a.col2); - const Vec3V cross20 = V3Cross(a.col2, a.col0); - const FloatV dot = V3Dot(cross01, a.col2); - const FloatV invDet = _mm_rcp_ps(dot); - const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); - const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); - Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); - colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); - const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); - const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); - const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); - const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); - const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); - const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); - - return Mat33V(_mm_mul_ps(colInv0, invDet), _mm_mul_ps(colInv1, invDet), - _mm_mul_ps(colInv2, invDet)); -} - -QT3DS_FORCE_INLINE Mat33V M33Trnsps(const Mat33V &a) -{ - return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), - V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), - V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); -} - -QT3DS_FORCE_INLINE Mat33V M33Identity() -{ - return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); -} - -QT3DS_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) -{ - const FloatV x = V3Mul(V3UnitX(), d); - const FloatV y = V3Mul(V3UnitY(), d); - const FloatV z = V3Mul(V3UnitZ(), d); - return Mat33V(x, y, z); -} - -////////////////////////////////// -// MAT34V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec3V M34MulV3(const Mat34V &a, const Vec3V b) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - const Vec3V v0 = V3Scale(a.col0, x); - const Vec3V v1 = V3Scale(a.col1, y); - const Vec3V v2 = V3Scale(a.col2, z); - const Vec3V v0PlusV1 = V3Add(v0, v1); - const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); - return (V3Add(v0PlusV1Plusv2, a.col3)); -} - -QT3DS_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V &a, const Vec3V b) -{ - const FloatV x = V3GetX(b); - const FloatV y = V3GetY(b); - const FloatV z = V3GetZ(b); - const Vec3V v0 = V3Scale(a.col0, x); - const Vec3V v1 = V3Scale(a.col1, y); - const Vec3V v2 = V3Scale(a.col2, z); - const Vec3V v0PlusV1 = V3Add(v0, v1); - return V3Add(v0PlusV1, v2); -} - -QT3DS_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V &a, const Vec3V b) -{ - const FloatV x = V3Dot(a.col0, b); - const FloatV y = V3Dot(a.col1, b); - const FloatV z = V3Dot(a.col2, b); - return V3Merge(x, y, z); -} - -QT3DS_FORCE_INLINE Mat34V M34MulM34(const Mat34V &a, const Mat34V &b) -{ - return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), - M34MulV3(a, b.col3)); -} - -QT3DS_FORCE_INLINE Mat33V M34MulM33(const Mat34V &a, const Mat33V &b) -{ - return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); -} - -QT3DS_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V &a, const Mat34V &b) -{ - return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); -} - -QT3DS_FORCE_INLINE Mat34V M34Add(const Mat34V &a, const Mat34V &b) -{ - return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), - V3Add(a.col3, b.col3)); -} - -QT3DS_FORCE_INLINE Mat34V M34Inverse(const Mat34V &a) -{ - Mat34V aInv; - const BoolV tfft = BTFFT(); - const BoolV tttf = BTTTF(); - const FloatV zero = V3Zero(); - const Vec3V cross01 = V3Cross(a.col0, a.col1); - const Vec3V cross12 = V3Cross(a.col1, a.col2); - const Vec3V cross20 = V3Cross(a.col2, a.col0); - const FloatV dot = V3Dot(cross01, a.col2); - const FloatV invDet = _mm_rcp_ps(dot); - const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); - const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); - Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); - colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); - const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); - const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); - const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); - const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); - const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); - const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); - aInv.col0 = _mm_mul_ps(colInv0, invDet); - aInv.col1 = _mm_mul_ps(colInv1, invDet); - aInv.col2 = _mm_mul_ps(colInv2, invDet); - aInv.col3 = M34Mul33V3(aInv, V3Neg(a.col3)); - return aInv; -} - -QT3DS_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V &a) -{ - return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), - V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), - V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); -} - -////////////////////////////////// -// MAT44V -////////////////////////////////// - -QT3DS_FORCE_INLINE Vec4V M44MulV4(const Mat44V &a, const Vec4V b) -{ - const FloatV x = V4GetX(b); - const FloatV y = V4GetY(b); - const FloatV z = V4GetZ(b); - const FloatV w = V4GetW(b); - - const Vec4V v0 = V4Scale(a.col0, x); - const Vec4V v1 = V4Scale(a.col1, y); - const Vec4V v2 = V4Scale(a.col2, z); - const Vec4V v3 = V4Scale(a.col3, w); - const Vec4V v0PlusV1 = V4Add(v0, v1); - const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); - return (V4Add(v0PlusV1Plusv2, v3)); -} - -QT3DS_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V &a, const Vec4V b) -{ - QT3DS_ALIGN(16, FloatV dotProdArray[4]) = { V4Dot(a.col0, b), V4Dot(a.col1, b), V4Dot(a.col2, b), - V4Dot(a.col3, b) }; - return V4Merge(dotProdArray); -} - -QT3DS_FORCE_INLINE Mat44V M44MulM44(const Mat44V &a, const Mat44V &b) -{ - return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), - M44MulV4(a, b.col3)); -} - -QT3DS_FORCE_INLINE Mat44V M44Add(const Mat44V &a, const Mat44V &b) -{ - return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), - V4Add(a.col3, b.col3)); -} - -QT3DS_FORCE_INLINE Mat44V M44Trnsps(const Mat44V &a) -{ - const Vec4V v0 = _mm_unpacklo_ps(a.col0, a.col2); - const Vec4V v1 = _mm_unpackhi_ps(a.col0, a.col2); - const Vec4V v2 = _mm_unpacklo_ps(a.col1, a.col3); - const Vec4V v3 = _mm_unpackhi_ps(a.col1, a.col3); - return Mat44V(_mm_unpacklo_ps(v0, v2), _mm_unpackhi_ps(v0, v2), _mm_unpacklo_ps(v1, v3), - _mm_unpackhi_ps(v1, v3)); -} - -// The original code as provided by Intel in -// "Streaming SIMD Extensions - Inverse of 4x4 Matrix" -// (ftp://download.intel.com/design/pentiumiii/sml/24504301.pdf) -QT3DS_FORCE_INLINE Mat44V M44Inverse(const Mat44V &a) -{ - __m128 minor0, minor1, minor2, minor3; - __m128 row0, row1, row2, row3; - __m128 det, tmp1; - - tmp1 = V4Zero(); - row1 = V4Zero(); - row3 = V4Zero(); - - row0 = a.col0; - row1 = _mm_shuffle_ps(a.col1, a.col1, _MM_SHUFFLE(1, 0, 3, 2)); - row2 = a.col2; - row3 = _mm_shuffle_ps(a.col3, a.col3, _MM_SHUFFLE(1, 0, 3, 2)); - - tmp1 = _mm_mul_ps(row2, row3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor0 = _mm_mul_ps(row1, tmp1); - minor1 = _mm_mul_ps(row0, tmp1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); - minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); - minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); - - tmp1 = _mm_mul_ps(row1, row2); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); - minor3 = _mm_mul_ps(row0, tmp1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); - minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); - minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); - - tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - row2 = _mm_shuffle_ps(row2, row2, 0x4E); - minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); - minor2 = _mm_mul_ps(row0, tmp1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); - minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); - minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); - - tmp1 = _mm_mul_ps(row0, row1); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); - minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); - minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); - - tmp1 = _mm_mul_ps(row0, row3); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); - minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); - minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); - - tmp1 = _mm_mul_ps(row0, row2); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); - minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); - minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); - tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); - minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); - minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); - - det = _mm_mul_ps(row0, minor0); - det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); - det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); - tmp1 = _mm_rcp_ss(det); -#if 0 - det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); - det = _mm_shuffle_ps(det, det, 0x00); -#else - det = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 0, 0, 0)); -#endif - - minor0 = _mm_mul_ps(det, minor0); - minor1 = _mm_mul_ps(det, minor1); - minor2 = _mm_mul_ps(det, minor2); - minor3 = _mm_mul_ps(det, minor3); - Mat44V invTrans(minor0, minor1, minor2, minor3); - return M44Trnsps(invTrans); -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_XYZW(QT3DSF32 x, QT3DSF32 y, QT3DSF32 z, QT3DSF32 w) -{ - return _mm_set_ps(w, z, y, x); -} - -// AP: work in progress - use proper SSE intrinsics where possible -QT3DS_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) -{ - VecU16V result; - result.m128_u16[0] = QT3DSU16(NVClamp((a).m128_u32[0], 0, 0xFFFF)); - result.m128_u16[1] = QT3DSU16(NVClamp((a).m128_u32[1], 0, 0xFFFF)); - result.m128_u16[2] = QT3DSU16(NVClamp((a).m128_u32[2], 0, 0xFFFF)); - result.m128_u16[3] = QT3DSU16(NVClamp((a).m128_u32[3], 0, 0xFFFF)); - result.m128_u16[4] = QT3DSU16(NVClamp((b).m128_u32[0], 0, 0xFFFF)); - result.m128_u16[5] = QT3DSU16(NVClamp((b).m128_u32[1], 0, 0xFFFF)); - result.m128_u16[6] = QT3DSU16(NVClamp((b).m128_u32[2], 0, 0xFFFF)); - result.m128_u16[7] = QT3DSU16(NVClamp((b).m128_u32[3], 0, 0xFFFF)); - return result; -} - -QT3DS_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) -{ - return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) -{ - return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) -{ - return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32(const QT3DSI32 i) -{ - return (_mm_load1_ps((QT3DSF32 *)&i)); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array(const QT3DSI32 *i) -{ - return _mm_loadu_ps((QT3DSF32 *)i); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array_Aligned(const QT3DSI32 *i) -{ - return _mm_load_ps((QT3DSF32 *)i); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_add_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_sub_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_cmpgt_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) -{ - return m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Zero() -{ - return V4Zero(); -} - -QT3DS_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, - const VecI32VArg d) -{ - return V4Merge(a, b, c, d); -} - -template -QT3DS_FORCE_INLINE VecI32V V4ISplat() -{ - VecI32V result; - result.m128_i32[0] = a; - result.m128_i32[1] = a; - result.m128_i32[2] = a; - result.m128_i32[3] = a; - return result; -} - -QT3DS_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V *address) -{ - *address = val; -} - -QT3DS_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V *address) -{ - *address = val; -} - -QT3DS_FORCE_INLINE Vec4V V4LoadAligned(Vec4V *addr) -{ - return *addr; -} - -QT3DS_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V *addr) -{ - return Vec4V_From_F32Array((float *)addr); -} - -QT3DS_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) -{ - VecU32V result32(a); - result32 = V4U32Andc(result32, b); - return Vec4V(result32); -} - -QT3DS_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) -{ - return V4IsGrtr(a, b); -} - -QT3DS_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V *addr) -{ - return *addr; -} - -QT3DS_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V *addr) -{ - return *addr; -} - -QT3DS_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) -{ - // _mm_cmpgt_epi16 doesn't work for unsigned values unfortunately - // return m128_I2F(_mm_cmpgt_epi16(m128_F2I(a), m128_F2I(b))); - VecU16V result; - result.m128_u16[0] = (a).m128_u16[0] > (b).m128_u16[0]; - result.m128_u16[1] = (a).m128_u16[1] > (b).m128_u16[1]; - result.m128_u16[2] = (a).m128_u16[2] > (b).m128_u16[2]; - result.m128_u16[3] = (a).m128_u16[3] > (b).m128_u16[3]; - result.m128_u16[4] = (a).m128_u16[4] > (b).m128_u16[4]; - result.m128_u16[5] = (a).m128_u16[5] > (b).m128_u16[5]; - result.m128_u16[6] = (a).m128_u16[6] > (b).m128_u16[6]; - result.m128_u16[7] = (a).m128_u16[7] > (b).m128_u16[7]; - return result; -} - -QT3DS_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) -{ - Vec4V result = Vec4V_From_XYZW(QT3DSF32(a.m128_u32[0]), QT3DSF32(a.m128_u32[1]), QT3DSF32(a.m128_u32[2]), - QT3DSF32(a.m128_u32[3])); - return result; -} - -template -QT3DS_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) -{ - VecU32V result; - result.m128_u32[0] = result.m128_u32[1] = result.m128_u32[2] = result.m128_u32[3] = - a.m128_u32[index]; - return result; -} - -template -QT3DS_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) -{ - float *data = (float *)&a; - return Vec4V_From_F32(data[index]); -} - -template -QT3DS_FORCE_INLINE VecU16V V4U16SplatElement(VecU16V a) -{ - VecU16V result = a; // AM: initializing to avoid nonsensical warning 4701 here with VC10. - for (int i = 0; i < 8; i++) - result.m128_u16[i] = a.m128_u16[index]; - return result; -} - -template -QT3DS_FORCE_INLINE VecI16V V4I16SplatImmediate() -{ - VecI16V result; - result.m128_i16[0] = imm; - result.m128_i16[1] = imm; - result.m128_i16[2] = imm; - result.m128_i16[3] = imm; - result.m128_i16[4] = imm; - result.m128_i16[5] = imm; - result.m128_i16[6] = imm; - result.m128_i16[7] = imm; - return result; -} - -QT3DS_FORCE_INLINE VecU16V V4U16SubtractModulo(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_sub_epi16(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU16V V4U16AddModulo(VecU16V a, VecU16V b) -{ - return m128_I2F(_mm_add_epi16(m128_F2I(a), m128_F2I(b))); -} - -QT3DS_FORCE_INLINE VecU32V V4U16GetLo16(VecU16V a) -{ - VecU32V result; - result.m128_u32[0] = a.m128_u16[0]; - result.m128_u32[1] = a.m128_u16[2]; - result.m128_u32[2] = a.m128_u16[4]; - result.m128_u32[3] = a.m128_u16[6]; - return result; -} - -QT3DS_FORCE_INLINE VecU32V V4U16GetHi16(VecU16V a) -{ - VecU32V result; - result.m128_u32[0] = a.m128_u16[1]; - result.m128_u32[1] = a.m128_u16[3]; - result.m128_u32[2] = a.m128_u16[5]; - result.m128_u32[3] = a.m128_u16[7]; - return result; -} - -QT3DS_FORCE_INLINE VecU32V VecU32V_From_XYZW(QT3DSU32 x, QT3DSU32 y, QT3DSU32 z, QT3DSU32 w) -{ - VecU32V result; - result.m128_u32[0] = x; - result.m128_u32[1] = y; - result.m128_u32[2] = z; - result.m128_u32[3] = w; - return result; -} - -QT3DS_FORCE_INLINE Vec4V V4Ceil(const Vec4V a) -{ - return Vec4V_From_XYZW(NVCeil(a.m128_f32[0]), NVCeil(a.m128_f32[1]), NVCeil(a.m128_f32[2]), - NVCeil(a.m128_f32[3])); -} - -QT3DS_FORCE_INLINE Vec4V V4Floor(const Vec4V a) -{ - return Vec4V_From_XYZW(NVFloor(a.m128_f32[0]), NVFloor(a.m128_f32[1]), NVFloor(a.m128_f32[2]), - NVFloor(a.m128_f32[3])); -} - -QT3DS_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V a, QT3DSU32 power) -{ - QT3DS_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); - QT3DS_FORCE_PARAMETER_REFERENCE(power); // prevent warning in release builds - QT3DSF32 ffffFFFFasFloat = QT3DSF32(0xFFFF0000); - VecU32V result; - result.m128_u32[0] = QT3DSU32(NVClamp((a).m128_f32[0], 0.0f, ffffFFFFasFloat)); - result.m128_u32[1] = QT3DSU32(NVClamp((a).m128_f32[1], 0.0f, ffffFFFFasFloat)); - result.m128_u32[2] = QT3DSU32(NVClamp((a).m128_f32[2], 0.0f, ffffFFFFasFloat)); - result.m128_u32[3] = QT3DSU32(NVClamp((a).m128_f32[3], 0.0f, ffffFFFFasFloat)); - return result; -} - -#endif // QT3DS_WINDOWS_INLINE_AOS_H diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsIntrinsics.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsIntrinsics.h deleted file mode 100644 index 3e0b3e8f..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsIntrinsics.h +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_WINDOWS_INTRINSICS_H -#define QT3DS_FOUNDATION_QT3DS_WINDOWS_INTRINSICS_H - -#include "foundation/Qt3DS.h" - -#if !defined QT3DS_WINDOWS && !defined QT3DS_WIN8ARM -#error "This file should only be included by Windows builds!!" -#endif - -#ifdef QT3DS_GNUC -#include -#else -#include -#endif -#include -#include -#include -#include "foundation/Qt3DSAssert.h" - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -namespace intrinsics { -#endif - - //! \brief platform-specific absolute value - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float abs(float a) { return float(::fabs(a)); } - - //! \brief platform-specific select float - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float fsel(float a, float b, float c) - { - return (a >= 0.0f) ? b : c; - } - - //! \brief platform-specific sign - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sign(float a) { return (a >= 0.0f) ? 1.0f : -1.0f; } - - //! \brief platform-specific reciprocal - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recip(float a) { return 1.0f / a; } - - //! \brief platform-specific square root - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sqrt(float a) { return ::sqrtf(a); } - - //! \brief platform-specific reciprocal square root - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrt(float a) { return 1.0f / ::sqrtf(a); } - - //! \brief platform-specific sine - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sin(float a) { return ::sinf(a); } - - //! \brief platform-specific cosine - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float cos(float a) { return ::cosf(a); } - - //! \brief platform-specific minimum - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMin(float a, float b) { return a < b ? a : b; } - - //! \brief platform-specific maximum - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMax(float a, float b) { return a > b ? a : b; } - - //! \brief platform-specific finiteness check (not INF or NAN) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(float a) - { -#if defined(__CUDACC__) - return isfinite(a)? true : false; -#elif defined(QT3DS_GNUC) - return (std::isfinite(a) && !std::isinf(a)) ? true : false; -#else - return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); -#endif - } - - //! \brief platform-specific finiteness check (not INF or NAN) - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(double a) - { -#if defined(__CUDACC__) - return isfinite(a)? true : false; -#elif defined(QT3DS_GNUC) - return (std::isfinite(a) && !std::isinf(a)) ? true : false; -#else - return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); -#endif - } - /* -* Implements a memory barrier -*/ - QT3DS_FORCE_INLINE void memoryBarrier() - { - _ReadWriteBarrier(); - /* long Barrier; - __asm { - xchg Barrier, eax - }*/ - } - - /*! - Returns the index of the highest set bit. Not valid for zero arg. - */ - QT3DS_FORCE_INLINE QT3DSU32 highestSetBitUnsafe(QT3DSU32 v) - { - unsigned long retval; - _BitScanReverse(&retval, v); - return retval; - } - - /*! - Returns the index of the highest set bit. Undefined for zero arg. - */ - QT3DS_FORCE_INLINE QT3DSU32 lowestSetBitUnsafe(QT3DSU32 v) - { - unsigned long retval; - _BitScanForward(&retval, v); - return retval; - } - - /*! - Returns the number of leading zeros in v. Returns 32 for v=0. - */ - QT3DS_FORCE_INLINE QT3DSU32 countLeadingZeros(QT3DSU32 v) - { - if (v) { - unsigned long bsr = (unsigned long)-1; - _BitScanReverse(&bsr, v); - return 31 - bsr; - } else - return 32; - } - - /*! - Sets \c count bytes starting at \c dst to zero. - */ - QT3DS_FORCE_INLINE void *memZero(void *QT3DS_RESTRICT dest, QT3DSU32 count) - { - return memset(dest, 0, count); - } - - /*! - Sets \c count bytes starting at \c dst to \c c. - */ - QT3DS_FORCE_INLINE void *memSet(void *QT3DS_RESTRICT dest, QT3DSI32 c, QT3DSU32 count) - { - return memset(dest, c, count); - } - - /*! - Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. - */ - QT3DS_FORCE_INLINE void *memCopy(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) - { - return memcpy(dest, src, count); - } - - /*! - Copies \c count bytes from \c src to \c dst. Supports overlapping regions. - */ - QT3DS_FORCE_INLINE void *memMove(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) - { - return memmove(dest, src, count); - } - - /*! - Set 128B to zero starting at \c dst+offset. Must be aligned. - */ - QT3DS_FORCE_INLINE void memZero128(void *QT3DS_RESTRICT dest, QT3DSU32 offset = 0) - { - QT3DS_ASSERT(((size_t(dest) + offset) & 0x7f) == 0); - memSet((char *QT3DS_RESTRICT)dest + offset, 0, 128); - } - - /*! - Prefetch aligned 128B around \c ptr+offset. - */ - QT3DS_FORCE_INLINE void prefetch128(const void *ptr, QT3DSU32 offset = 0) - { -#ifdef QT3DS_WINDOWS - _mm_prefetch(((const char *)ptr + offset), _MM_HINT_T0); -#endif - } - - /*! - Prefetch \c count bytes starting at \c ptr. - */ - QT3DS_FORCE_INLINE void prefetch(const void *ptr, QT3DSU32 count = 0) - { - for (QT3DSU32 i = 0; i <= count; i += 128) - prefetch128(ptr, i); - } - - //! \brief platform-specific reciprocal - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipFast(float a) { return 1.0f / a; } - - //! \brief platform-specific fast reciprocal square root - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrtFast(float a) { return 1.0f / ::sqrtf(a); } - - //! \brief platform-specific floor - QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float floatFloor(float x) { return ::floorf(x); } - -#ifndef QT3DS_DOXYGEN -} // namespace intrinsics -} // namespace qt3ds -#endif - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsString.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsString.h deleted file mode 100644 index 8d5fcd31..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsString.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_FOUNDATION_QT3DS_WINDOWS_STRING_H -#define QT3DS_FOUNDATION_QT3DS_WINDOWS_STRING_H - -#include "foundation/Qt3DS.h" - -#include -#include -#include - -#pragma warning(push) -#pragma warning(disable : 4995 4996) - -#ifndef QT3DS_DOXYGEN -namespace qt3ds { -#endif - -QT3DS_INLINE void NVStrcpy(char *dest, size_t size, const char *src) -{ - ::strcpy_s(dest, size, src); -} -QT3DS_INLINE void NVStrcat(char *dest, size_t size, const char *src) -{ - ::strcat_s(dest, size, src); -} -QT3DS_INLINE QT3DSI32 NVVsprintf(char *dest, size_t size, const char *src, va_list arg) -{ - QT3DSI32 r = ::vsprintf_s(dest, size, src, arg); - - return r; -} -QT3DS_INLINE QT3DSI32 NVStricmp(const char *str, const char *str1) -{ - return (::_stricmp(str, str1)); -} - -namespace string { - QT3DS_INLINE QT3DSI32 stricmp(const char *str, const char *str1) { return (::_stricmp(str, str1)); } - QT3DS_INLINE QT3DSI32 strnicmp(const char *str, const char *str1, size_t len) - { - return (::_strnicmp(str, str1, len)); - } - QT3DS_INLINE QT3DSI32 strncat_s(char *a, QT3DSI32 b, const char *c, size_t d) - { - return (::strncat_s(a, b, c, d)); - } - QT3DS_INLINE QT3DSI32 strncpy_s(char *strDest, size_t sizeInBytes, const char *strSource, - size_t count) - { - return (::strncpy_s(strDest, sizeInBytes, strSource, count)); - } - QT3DS_INLINE void strcpy_s(char *dest, size_t size, const char *src) - { - ::strcpy_s(dest, size, src); - } - QT3DS_INLINE void strcat_s(char *dest, size_t size, const char *src) - { - ::strcat_s(dest, size, src); - } - QT3DS_INLINE QT3DSI32 _vsnprintf(char *dest, size_t size, const char *src, va_list arg) - { - QT3DSI32 r = ::_vsnprintf(dest, size, src, arg); - - return r; - } - QT3DS_INLINE QT3DSI32 vsprintf_s(char *dest, size_t size, const char *src, va_list arg) - { - QT3DSI32 r = ::vsprintf_s(dest, size, src, arg); - - return r; - } - - QT3DS_INLINE QT3DSI32 sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...) - { - va_list arg; - va_start(arg, _Format); - QT3DSI32 r = ::vsprintf_s(_DstBuf, _DstSize, _Format, arg); - va_end(arg); - - return r; - } - QT3DS_INLINE QT3DSI32 sscanf_s(const char *buffer, const char *format, ...) - { - va_list arg; - va_start(arg, format); - QT3DSI32 r = ::sscanf_s(buffer, format, arg); - va_end(arg); - - return r; - }; - - QT3DS_INLINE void strlwr(char *str) - { - while (*str) { - if (*str >= 'A' && *str <= 'Z') - *str += 32; - str++; - } - } - - QT3DS_INLINE void strupr(char *str) - { - while (*str) { - if (*str >= 'a' && *str <= 'z') - *str -= 32; - str++; - } - } - -} // namespace string - -#ifndef QT3DS_DOXYGEN -} // namespace qt3ds -#endif - -#pragma warning(pop) - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsTrigConstants.h b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsTrigConstants.h deleted file mode 100644 index e3da844c..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/Qt3DSWindowsTrigConstants.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_WINDOWS_TRIG_CONSTANTS_H -#define QT3DS_WINDOWS_TRIG_CONSTANTS_H - -#define QT3DS_GLOBALCONST extern const __declspec(selectany) - -__declspec(align(16)) struct QT3DS_VECTORF32 -{ - float f[4]; -}; - -#define QT3DS_PI 3.141592654f -#define QT3DS_2PI 6.283185307f -#define QT3DS_1DIVPI 0.318309886f -#define QT3DS_1DIV2PI 0.159154943f -#define QT3DS_PIDIV2 1.570796327f -#define QT3DS_PIDIV4 0.785398163f - -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients0 = { 1.0f, -0.166666667f, 8.333333333e-3f, - -1.984126984e-4f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients1 = { 2.755731922e-6f, -2.505210839e-8f, - 1.605904384e-10f, -7.647163732e-13f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients2 = { 2.811457254e-15f, -8.220635247e-18f, - 1.957294106e-20f, -3.868170171e-23f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients0 = { 1.0f, -0.5f, 4.166666667e-2f, - -1.388888889e-3f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients1 = { 2.480158730e-5f, -2.755731922e-7f, - 2.087675699e-9f, -1.147074560e-11f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients2 = { 4.779477332e-14f, -1.561920697e-16f, - 4.110317623e-19f, -8.896791392e-22f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients0 = { 1.0f, 0.333333333f, 0.133333333f, - 5.396825397e-2f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients1 = { 2.186948854e-2f, 8.863235530e-3f, - 3.592128167e-3f, 1.455834485e-3f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients2 = { 5.900274264e-4f, 2.391290764e-4f, - 9.691537707e-5f, 3.927832950e-5f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients0 = { -0.05806367563904f, -0.41861972469416f, - 0.22480114791621f, 2.17337241360606f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients1 = { 0.61657275907170f, 4.29696498283455f, - -1.18942822255452f, -6.53784832094831f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients2 = { -1.36926553863413f, -4.48179294237210f, - 1.41810672941833f, 5.48179257935713f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients0 = { 1.0f, 0.333333334f, 0.2f, 0.142857143f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients1 = { 1.111111111e-1f, 9.090909091e-2f, - 7.692307692e-2f, 6.666666667e-2f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients2 = { 5.882352941e-2f, 5.263157895e-2f, - 4.761904762e-2f, 4.347826087e-2f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinEstCoefficients = { 1.0f, -1.66521856991541e-1f, - 8.199913018755e-3f, -1.61475937228e-4f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosEstCoefficients = { 1.0f, -4.95348008918096e-1f, - 3.878259962881e-2f, -9.24587976263e-4f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanEstCoefficients = { 2.484f, -1.954923183e-1f, 2.467401101f, - QT3DS_1DIVPI }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanEstCoefficients = { 7.689891418951e-1f, 1.104742493348f, - 8.661844266006e-1f, QT3DS_PIDIV2 }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstCoefficients = { -1.36178272886711f, 2.37949493464538f, - -8.08228565650486e-1f, - 2.78440142746736e-1f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstConstants = { 1.00000011921f, QT3DS_PIDIV2, 0.0f, 0.0f }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXPiConstants0 = { QT3DS_PI, QT3DS_2PI, QT3DS_1DIVPI, QT3DS_1DIV2PI }; -QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXReciprocalTwoPi = { QT3DS_1DIV2PI, QT3DS_1DIV2PI, QT3DS_1DIV2PI, - QT3DS_1DIV2PI }; - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/qt_attribution.json b/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/qt_attribution.json deleted file mode 100644 index e0310cfa..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Include/foundation/windows/qt_attribution.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Id": "qt3dswindowsaos", - "Name": "Qt3DSWindowsAoS", - "QDocModule": "qt3dstudio", - "QtUsage": "Used by Qt3DStudio, Runtime component.", - - "License": "Other", - "LicenseFile": "LICENSE.TXT", - "Copyright": "Copyright (c) 2001 Intel Corporation." -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/ConvertUTF.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/ConvertUTF.cpp deleted file mode 100644 index a71a3aeb..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/ConvertUTF.cpp +++ /dev/null @@ -1,661 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* -* Copyright 2001-2004 Unicode, Inc. -* -* Disclaimer -* -* This source code is provided as is by Unicode, Inc. No claims are -* made as to fitness for any particular purpose. No warranties of any -* kind are expressed or implied. The recipient agrees to determine -* applicability of information provided. If this file has been -* purchased on magnetic or optical media from Unicode, Inc., the -* sole remedy for any claim will be exchange of defective media -* within 90 days of receipt. -* -* Limitations on Rights to Redistribute This Code -* -* Unicode, Inc. hereby grants the right to freely use the information -* supplied in this file in the creation of products supporting the -* Unicode Standard, and to make copies of this file in any form -* for internal or external distribution as long as this notice -* remains attached. -*/ - -/* --------------------------------------------------------------------- - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - See the header file "ConvertUTF.h" for complete documentation. ------------------------------------------------------------------------- */ - -#include "foundation/ConvertUTF.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4365) // warnings on conversion from unsigned int to int -#endif - -#ifdef CVTUTF_DEBUG -#include -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF -#define false 0 -#define true 1 - -/* --------------------------------------------------------------------- */ - -ConversionResult Q3DSConvertUTF32toUTF16(const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, - ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF32 *source = *sourceStart; - UTF16 *target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; - break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved - * values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; - break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult Q3DSConvertUTF16toUTF32(const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, - ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF16 *source = *sourceStart; - UTF32 *target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16 *oldSource = - source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) - + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; - break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG - if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); - } -#endif - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - -/* --------------------------------------------------------------------- */ - -ConversionResult Q3DSConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF16 *source = *sourceStart; - UTF8 *target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16 *oldSource = - source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) - + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { - bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { - bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { - bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { - bytesToWrite = 4; - } else { - bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; - result = targetExhausted; - break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: - *--target = (UTF8)((ch | byteMark) & byteMask); - ch >>= 6; - case 3: - *--target = (UTF8)((ch | byteMark) & byteMask); - ch >>= 6; - case 2: - *--target = (UTF8)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) -{ - UTF8 a; - const UTF8 *srcptr = source + length; - switch (length) { - default: - return false; - /* Everything else falls through when "true"... */ - case 4: - if ((a = (*--srcptr)) < 0x80 || a > 0xBF) - return false; - case 3: - if ((a = (*--srcptr)) < 0x80 || a > 0xBF) - return false; - case 2: - if ((a = (*--srcptr)) > 0xBF) - return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: - if (a < 0xA0) - return false; - break; - case 0xED: - if (a > 0x9F) - return false; - break; - case 0xF0: - if (a < 0x90) - return false; - break; - case 0xF4: - if (a > 0x8F) - return false; - break; - default: - if (a < 0x80) - return false; - } - - case 1: - if (*source >= 0x80 && *source < 0xC2) - return false; - } - if (*source > 0xF4) - return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean Q3DSIsLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) -{ - int length = trailingBytesForUTF8[*source] + 1; - if (source + length > sourceEnd) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -ConversionResult Q3DSConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, - ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF8 *source = *sourceStart; - UTF16 *target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; - break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead + 1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: - ch += *source++; - ch <<= 6; /* remember, illegal UTF-8 */ - case 4: - ch += *source++; - ch <<= 6; /* remember, illegal UTF-8 */ - case 3: - ch += *source++; - ch <<= 6; - case 2: - ch += *source++; - ch <<= 6; - case 1: - ch += *source++; - ch <<= 6; - case 0: - ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead + 1); /* Back up source pointer! */ - result = targetExhausted; - break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead + 1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead + 1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead + 1); /* Back up source pointer! */ - result = targetExhausted; - break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult Q3DSConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF32 *source = *sourceStart; - UTF8 *target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { - bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { - bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { - bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { - bytesToWrite = 4; - } else { - bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; - result = targetExhausted; - break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: - *--target = (UTF8)((ch | byteMark) & byteMask); - ch >>= 6; - case 3: - *--target = (UTF8)((ch | byteMark) & byteMask); - ch >>= 6; - case 2: - *--target = (UTF8)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult Q3DSConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, - ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF8 *source = *sourceStart; - UTF32 *target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; - break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead + 1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: - ch += *source++; - ch <<= 6; - case 4: - ch += *source++; - ch <<= 6; - case 3: - ch += *source++; - ch <<= 6; - case 2: - ch += *source++; - ch <<= 6; - case 1: - ch += *source++; - ch <<= 6; - case 0: - ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead + 1); /* Back up the source pointer! */ - result = targetExhausted; - break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead + 1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/EASTL_new.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/EASTL_new.cpp deleted file mode 100644 index 61e8e0b4..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/EASTL_new.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// we have some build dependencies which forces us to include -// this on linux to recognize malloc -#include -#include - -#if !defined(_MSC_VER) -#include -#endif - -#include "EASTL/allocator.h" - -void *operator new[](size_t size, const char *, int, unsigned, const char *, int) -{ - return malloc(size); -} - -void *operator new[](size_t size, size_t, size_t, const char *, int, unsigned, const char *, int) -{ - return malloc(size); -} -// EASTL also wants us to define this (see string.h line 197) -int Vsnprintf8(char8_t *pDestination, size_t n, const char8_t *pFormat, va_list arguments) -{ -#ifdef _MSC_VER - return _vsnprintf(pDestination, n, pFormat, arguments); -#else - return vsnprintf(pDestination, n, pFormat, arguments); -#endif -} -int Vsnprintf16(char8_t *pDestination, size_t n, const char16_t *pFormat, va_list arguments) -{ -#ifdef _MSC_VER - return _vsnprintf(pDestination, n, (char *)pFormat, arguments); -#else - return vsnprintf(pDestination, n, (char *)pFormat, arguments); -#endif -} -int Vsnprintf32(char8_t *pDestination, size_t n, const char32_t *pFormat, va_list arguments) -{ -#ifdef _MSC_VER - return _vsnprintf(pDestination, n, (char *)pFormat, arguments); -#else - return vsnprintf(pDestination, n, (char *)pFormat, arguments); -#endif -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/FileTools.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/FileTools.cpp deleted file mode 100644 index aa1e7384..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/FileTools.cpp +++ /dev/null @@ -1,545 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/FileTools.h" -#include "foundation/Utils.h" -#include -# -#ifdef EA_PLATFORM_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#else // posix -#include -#include -#include -#include -#include -#endif -#include -#include -#include - -using namespace qt3ds::foundation; - -namespace { -// State machine where you can add a character -// and it will tell you how many characters to erase -struct SPathStateMachine -{ - struct States - { - enum Enum { - NoState = 0, // Don't care - Slash, // Last char was either a forward or backward slash - Period, // Last char was a period - TwoPeriods, // Last two characters were periods - }; - }; - struct Actions - { - enum Enum { - NoAction = 0, - DeleteBack1Slash, - DeleteBack2Slashes, - }; - }; - - States::Enum m_State; - - SPathStateMachine() - : m_State(States::NoState) - { - } - - Actions::Enum AnalyzeChar(char32_t inChar) - { - switch (inChar) { - case '\\': - case '/': - switch (m_State) { - case States::NoState: - m_State = States::Slash; - break; - case States::Period: - m_State = States::Slash; - return Actions::DeleteBack1Slash; - - case States::TwoPeriods: - m_State = States::Slash; - return Actions::DeleteBack2Slashes; - case States::Slash: - return Actions::DeleteBack1Slash; - } - break; - case '.': - switch (m_State) { - case States::Slash: - case States::NoState: - m_State = States::Period; - break; - case States::Period: - m_State = States::TwoPeriods; - break; - case States::TwoPeriods: - break; - } - break; - default: - m_State = States::NoState; - break; - } - return Actions::NoAction; - } -}; - -template -inline bool DoDeleteBack1Slash(TStr::size_type &idx, TStrType &ioPath) -{ - TStr::size_type slashLoc = ioPath.rfind('/', idx - 1); - if ((slashLoc != TStr::npos) && (slashLoc > 2) - // and the next *two* characters aren't both dots. - && ((ioPath[slashLoc - 1] != '.') || (ioPath[slashLoc - 2] != '.'))) { - - ioPath.erase(ioPath.begin() + slashLoc, ioPath.begin() + idx); - idx = slashLoc; - return true; - } - return false; -} - -template -void NormalizePathT(TStrType &ioPath) -{ - TStr::size_type pathLen = ioPath.size(); - SPathStateMachine theStateMachine; - for (TStr::size_type idx = 0; idx < pathLen; ++idx) { - char8_t ¤tChar = ioPath[idx]; - if (currentChar == '\\') - currentChar = '/'; - SPathStateMachine::Actions::Enum action = theStateMachine.AnalyzeChar(currentChar); - switch (action) { - case SPathStateMachine::Actions::DeleteBack2Slashes: - if (DoDeleteBack1Slash(idx, ioPath)) - DoDeleteBack1Slash(idx, ioPath); - pathLen = ioPath.size(); - break; - - case SPathStateMachine::Actions::DeleteBack1Slash: - DoDeleteBack1Slash(idx, ioPath); - pathLen = ioPath.size(); - break; - default: - break; - } - } -} - -bool IsAbsolute(const char8_t *inPath, size_t inLen) -{ - if (inLen > 2 && inPath[1] == ':') - return true; - else if (inLen > 1 && (inPath[0] == '\\' || inPath[0] == '/')) - return true; - return false; -} - -template -void CombineBaseAndRelativeT(const char8_t *inBase, const char8_t *inRelative, TStrType &outString) -{ - if (IsAbsolute(inRelative, StrLen(inRelative))) { - outString.assign(nonNull(inRelative)); - } else { - if (inRelative && *inRelative) { - if (inRelative[0] == '#') - outString.assign(inRelative); - else { - if (IsAbsolute(inRelative, strlen(inRelative))) { - outString.assign(inRelative); - } else { - outString = inBase ? inBase : ""; - if (outString.size()) - outString.append("/"); - outString.append(inRelative ? inRelative : (const char8_t *)L""); - } - NormalizePathT(outString); - } - } - } -} - -template -void GetRelativeFromBaseT(TStrType &inBaseStr, TStrType &inRelativeStr, TStrType &outString) -{ - outString.clear(); - NormalizePathT(inBaseStr); - NormalizePathT(inRelativeStr); - if (inBaseStr.size() == 0) { - outString.assign(inRelativeStr.c_str()); - return; - } - if (inRelativeStr.size() == 0) { - outString.clear(); - return; - } - // find longest common string - const char8_t *inBase = inBaseStr.c_str(); - const char8_t *baseEnd = inBaseStr.c_str() + inBaseStr.size(); - const char8_t *inRelative = inRelativeStr.c_str(); - size_t relativeLen = inRelativeStr.size(); - const char8_t *relativeEnd = inRelative + relativeLen; - - for (; inRelative < relativeEnd && inBase < baseEnd && *inRelative == *inBase; - ++inRelative, ++inBase) - ; - - // They had nothing in common. - if (inBase == inBaseStr.c_str()) { - outString.assign(inRelativeStr.c_str()); - return; - } - - if (inRelative && (*inRelative == '\\' || *inRelative == '/')) - ++inRelative; - - const char *common = inBase; - if (common == NULL || *common == 0) { - outString.assign("./"); - outString.append(inRelative); - NormalizePathT(outString); - return; - } - // Backtrack to the nearest slash. - while (*common && *common != '\\' && *common != '/') - --common; - - bool foundNonSlash = false; - for (; common != baseEnd; ++common) { - if (*common != '\\' && *common != '/') { - if (foundNonSlash == false) - outString.append("..\\"); - foundNonSlash = true; - } else - foundNonSlash = false; - } - if (inRelative < relativeEnd) { - if (outString.size() == 0) - outString.assign("./"); - outString.append(inRelative); - } - NormalizePathT(outString); -} -} - -void CFileTools::NormalizePath(TStr &ioPath) -{ - NormalizePathT(ioPath); -} - -void CFileTools::NormalizePath(eastl::string &ioPath) -{ - NormalizePathT(ioPath); -} - -QString CFileTools::NormalizePathForQtUsage(const QString &path) -{ - // path can be a file path or a qrc URL string. - - QString filePath = QDir::cleanPath(path); - - if (filePath.startsWith(QLatin1String("qrc:/"))) - return filePath.mid(3); - else - return filePath; -} - -void CFileTools::CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, - TStr &outString) -{ - CombineBaseAndRelativeT(inBase, inRelative, outString); -} - -void CFileTools::CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, - eastl::string &outString) -{ - CombineBaseAndRelativeT(inBase, inRelative, outString); -} - -void CFileTools::GetRelativeFromBase(TStr &inBaseStr, TStr &inRelativeStr, TStr &outString) -{ - GetRelativeFromBaseT(inBaseStr, inRelativeStr, outString); -} - -void CFileTools::GetRelativeFromBase(eastl::string &inBaseStr, eastl::string &inRelativeStr, - eastl::string &outString) -{ - GetRelativeFromBaseT(inBaseStr, inRelativeStr, outString); -} - -bool CFileTools::RequiresCombineBaseAndRelative(const char8_t *inPath) -{ - if (inPath && *inPath) - return inPath[0] == '.'; - return false; -} - -template -void ToPlatformPathT(TStrType &outString) -{ -#ifndef EA_PLATFORM_WINDOWS - for (TStr::size_type pos = outString.find('\\'); pos != TStr::npos; - pos = outString.find('\\', pos + 1)) - outString.replace(outString.begin() + pos, outString.begin() + pos + 1, "/"); -#else - (void)outString; -#endif -} - -void CFileTools::ToPlatformPath(TStr &outString) -{ - ToPlatformPathT(outString); -} - -void CFileTools::ToPlatformPath(eastl::string &outString) -{ - ToPlatformPathT(outString); -} - -CRegisteredString CFileTools::RemapPathToBinaryFormat(TStr &inPath, TStr &inPresentationDir, - TStr &ioWorkspaceStr, - IStringTable &inStringTable) -{ - GetRelativeFromBase(inPresentationDir, inPath, ioWorkspaceStr); - CRegisteredString theNewStr = inStringTable.RegisterStr(ioWorkspaceStr.c_str()); - theNewStr.Remap(inStringTable.GetRemapMap()); - return theNewStr; -} - -CRegisteredString CFileTools::RemapPathFromBinaryFormat(CRegisteredString inPath, - const char8_t *inPresDir, - TStr &ioWorkspaceStr, - const CStrTableOrDataRef &inRef, - IStringTable &inStringTable) -{ - inPath.Remap(inRef); - if (RequiresCombineBaseAndRelative(inPath.c_str())) { - CombineBaseAndRelative(inPresDir, inPath, ioWorkspaceStr); - return inStringTable.RegisterStr(ioWorkspaceStr.c_str()); - } - return inPath; -} - -void CFileTools::GetDirectory(eastl::string &ioPath) -{ - eastl::string::size_type theSlashPos = ioPath.find_last_of("\\/"); - if (theSlashPos == eastl::string::npos) { - ioPath.clear(); - return; - } - ioPath.resize(theSlashPos); -} - -bool CFileTools::DirectoryExists(const char8_t *inPath) -{ -#ifdef EA_PLATFORM_WINDOWS - DWORD theAtts = GetFileAttributesA(inPath); - return theAtts != INVALID_FILE_ATTRIBUTES && (theAtts & FILE_ATTRIBUTE_DIRECTORY); -#else // Posix style check for directory - int status; - struct stat st_buf; - status = stat(inPath, &st_buf); - if (status == 0 && S_ISDIR(st_buf.st_mode)) - return true; - return false; -#endif -} - -bool CFileTools::FileExists(const char8_t *inPath) -{ -#ifdef EA_PLATFORM_WINDOWS - DWORD theAtts = GetFileAttributesA(inPath); - return theAtts != INVALID_FILE_ATTRIBUTES; -#else // Posix style check for directory - int status; - struct stat st_buf; - status = stat(inPath, &st_buf); - if (status == 0) - return true; - return false; -#endif -} - -eastl::string CFileTools::GetFileOrAssetPath(const char8_t *inPath) -{ - QFile tmp(inPath); - if (tmp.exists()) - return inPath; - return eastl::string("assets:/") + inPath; -} - -void CFileTools::SetStreamPosition(QIODevice& device, qint64 inOffset, - qt3ds::foundation::SeekPosition::Enum inEnum) -{ - if (inEnum == qt3ds::foundation::SeekPosition::Begin) - device.seek(inOffset); - else if (inEnum == qt3ds::foundation::SeekPosition::Current) - device.seek(device.pos() + inOffset); - else if (inEnum == qt3ds::foundation::SeekPosition::End) - device.seek(device.size() + inOffset); -} - -void CFileTools::GetExtension(const char8_t *inPath, eastl::string &outExt) -{ - outExt.assign(nonNull(inPath)); - size_t dotPos = outExt.find_last_of('.'); - if (dotPos != eastl::string::npos) - outExt.erase(outExt.begin(), outExt.begin() + dotPos + 1); -} - -void CFileTools::Split(const char8_t *inPath, eastl::string &outDir, eastl::string &outFileStem, - eastl::string &outExtension) -{ - outDir.assign(nonNull(inPath)); - NormalizePath(outDir); - outFileStem = outDir; - GetDirectory(outDir); - size_t lenDiff = outFileStem.size() - outDir.size(); - if (lenDiff > 0) { - if (outDir.size()) - outFileStem = outFileStem.substr(outDir.size() + 1); - - eastl::string::size_type lastDot = outFileStem.find_last_of('.'); - if (lastDot != eastl::string::npos) { - outExtension = outFileStem.substr(lastDot + 1); - outFileStem.resize(lastDot); - } - } -} - -#ifdef EA_PLATFORM_WINDOWS -void CFileTools::GetDirectoryEntries(const eastl::string &inPath, - eastl::vector &outFiles) -{ - if (inPath.size() == 0) - return; - eastl::string tempPath(inPath); - NormalizePath(tempPath); - for (eastl::string::size_type pos = tempPath.find_first_of('/'); pos != eastl::string::npos; - pos = tempPath.find_first_of('/', pos + 1)) - tempPath[pos] = '\\'; - if (tempPath.back() != '\\') - tempPath.append("\\"); - tempPath.append(1, '*'); - WIN32_FIND_DATAA ffd; - HANDLE hFind = FindFirstFileA(tempPath.c_str(), &ffd); - outFiles.clear(); - if (INVALID_HANDLE_VALUE == hFind) - return; - - do { - if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0) - continue; - outFiles.push_back(eastl::string(ffd.cFileName)); - } while (FindNextFileA(hFind, &ffd) != 0); -} -#else -void CFileTools::GetDirectoryEntries(const eastl::string &inPath, - eastl::vector &outFiles) -{ - if (inPath.size() == 0) - return; - eastl::string tempPath(inPath); - NormalizePath(tempPath); - struct dirent *dent; - DIR *srcdir = opendir(tempPath.c_str()); - if (srcdir) { - while ((dent = readdir(srcdir)) != NULL) { - if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) - continue; - outFiles.push_back(eastl::string(dent->d_name)); - } - closedir(srcdir); - } -} -#endif - -bool CFileTools::CreateDir(const eastl::string &inPath, bool inRecurse) -{ - if (DirectoryExists(inPath.c_str())) - return true; - - eastl::string temp(inPath); - GetDirectory(temp); - if (temp.size() && !DirectoryExists(temp.c_str())) { - if (inRecurse) - CreateDir(temp, inRecurse); - else - return false; - } - -#ifdef EA_PLATFORM_WINDOWS - BOOL result = CreateDirectoryA(inPath.c_str(), NULL); - return result != 0; -#else - int result = mkdir(inPath.c_str(), 0777); - return result == 0; -#endif -} - -void CFileTools::AppendDirectoryInPathToFile(eastl::string &ioPath, const char8_t *dirName) -{ - eastl::string::size_type lastSlash = ioPath.find_last_of("\\/"); - if (lastSlash != eastl::string::npos) { - if (dirName == NULL) - dirName = ""; // avoid crashes on null strings - ioPath.insert(lastSlash + 1, "/"); - ioPath.insert(lastSlash + 1, dirName); - } else { - ioPath.insert(0, "/"); - ioPath.insert(0, dirName); - } -} - -void CFileTools::RemoveLastDirectoryInPathToFile(eastl::string &ioPath) -{ - eastl::string::size_type lastSlash = ioPath.find_last_of("\\/"); - if (lastSlash != eastl::string::npos) { - eastl::string::size_type secondToLastSlash = ioPath.find_last_of("\\/", lastSlash - 1); - if (secondToLastSlash != eastl::string::npos) - ioPath = ioPath.erase(secondToLastSlash, lastSlash - secondToLastSlash); - } -} - -void CFileTools::SetExtension(eastl::string &ioPath, const char8_t *inExt) -{ - eastl::string::size_type thePos = ioPath.find_last_of("."); - if (thePos != eastl::string::npos) { - ++thePos; - ioPath = ioPath.replace(thePos, ioPath.size() - thePos, inExt); - } -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/IOStreams.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/IOStreams.cpp deleted file mode 100644 index f1adfbc0..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/IOStreams.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/IOStreams.h" -#include "foundation/FileTools.h" -#include "foundation/StrConvertUTF.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSThread.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSMemoryBuffer.h" - -using namespace qt3ds::foundation; - -#ifndef _WIN32 - -inline int _fseeki64(FILE *inFile, int64_t pos, int seekFlags) -{ - return fseek(inFile, (int32_t)pos, seekFlags); -} - -inline int64_t _ftelli64(FILE *inFile) -{ - return ftell(inFile); -} - -#endif - -CFileSeekableIOStream::CFileSeekableIOStream(const char *inFileName, FileOpenFlags inFlags) -{ - openFile(QString(inFileName), inFlags); -} - -#ifdef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T - -CFileSeekableIOStream::CFileSeekableIOStream(const wchar_t *inFileName, FileOpenFlags inFlags) -{ - openFile(QString::fromWCharArray(inFileName), inFlags); -} - -#endif - -CFileSeekableIOStream::CFileSeekableIOStream(const char16_t *inWideName, FileOpenFlags inFlags) -{ - openFile(QString::fromUtf16(inWideName), inFlags); -} - -CFileSeekableIOStream::CFileSeekableIOStream(const QString &inFIle, FileOpenFlags inFlags) -{ - openFile(inFIle, inFlags); -} - -void CFileSeekableIOStream::openFile(const QString &path, FileOpenFlags inFlags) -{ - if (path.isEmpty()) - return; - - QIODevice::OpenMode fileFlags = QIODevice::ReadOnly; - if (inFlags & FileOpenFlagValues::Write) - fileFlags = QIODevice::ReadWrite; - if (inFlags & FileOpenFlagValues::Truncate) - fileFlags |= QIODevice::Truncate; - - m_File.setFileName(CFileTools::NormalizePathForQtUsage(path)); - if (!m_File.open(fileFlags)) { - qCCritical(INTERNAL_ERROR) << "failed to open file" - << path << "with error" << m_File.errorString(); - QT3DS_ASSERT(false); - } -} - -CFileSeekableIOStream::~CFileSeekableIOStream() -{ - m_File.close(); -} - -bool CFileSeekableIOStream::IsOpen() -{ - return m_File.isOpen(); -} - -void CFileSeekableIOStream::SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) -{ - if (inOffset > QT3DS_MAX_I32 || inOffset < QT3DS_MIN_I32) { - qCCritical(INVALID_OPERATION, "Attempt to seek further than platform allows"); - QT3DS_ASSERT(false); - return; - } else { - CFileTools::SetStreamPosition(m_File, inOffset, inEnum); - } -} - -QT3DSI64 CFileSeekableIOStream::GetPosition() const -{ - return m_File.pos(); -} - -QT3DSU32 CFileSeekableIOStream::Read(NVDataRef data) -{ - return m_File.read((char *)data.begin(), data.size()); -} - -bool CFileSeekableIOStream::Write(NVConstDataRef data) -{ - if (!m_File.isOpen()) { - QT3DS_ASSERT(false); - return 0; - } - qint64 numBytes = m_File.write((char*)data.begin(), data.size()); - return numBytes == data.size(); -} - -CMemorySeekableIOStream::CMemorySeekableIOStream(NVAllocatorCallback &inAlloc, - const char *inAllocName) - : m_Allocator(inAlloc) - , m_AllocationName(inAllocName) - , m_Data(NULL) - , m_Size(0) - , m_Offset(0) - , m_Capacity(0) -{ -} - -CMemorySeekableIOStream::~CMemorySeekableIOStream() -{ - if (m_Data) - m_Allocator.deallocate(m_Data); - m_Data = NULL; - m_Size = 0; - m_Capacity = 0; - m_Offset = 0; -} - -void CMemorySeekableIOStream::SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) -{ - QT3DSI64 startPos = 0; - - switch (inEnum) { - case SeekPosition::Begin: - startPos = 0; - break; - case SeekPosition::Current: - startPos = m_Offset; - break; - case SeekPosition::End: - startPos = m_Size; - break; - default: - QT3DS_ASSERT(false); - break; - } - - startPos += inOffset; - if (m_Size == 0 && inOffset != 0) { - QT3DS_ASSERT(false); - return; - } - if (startPos < 0) { - QT3DS_ASSERT(false); - startPos = 0; - } - if (startPos >= m_Size && startPos != 0) { - QT3DS_ASSERT(false); - startPos = m_Size - 1; - } - m_Offset = static_cast(startPos); -} - -QT3DSU32 CMemorySeekableIOStream::Read(NVDataRef data) -{ - if (m_Data == NULL) - return 0; - QT3DSU32 amountLeft = m_Size - m_Offset; - QT3DSU32 numBytes = NVMin(amountLeft, data.size()); - intrinsics::memCopy(data.begin(), m_Data + m_Offset, numBytes); - m_Offset += numBytes; - return numBytes; -} - -bool CMemorySeekableIOStream::Write(NVConstDataRef data) -{ - reserve(data.size() + m_Offset); - intrinsics::memCopy(m_Data + m_Offset, data.begin(), data.size()); - m_Offset += data.size(); - m_Size = NVMax(m_Size, m_Offset); - return true; -} - -void CMemorySeekableIOStream::reserve(QT3DSU32 inNewSize) -{ - if (inNewSize > m_Capacity) { - if (inNewSize < 100000) - inNewSize *= 2; - QT3DSU8 *newData = - (QT3DSU8 *)m_Allocator.allocate(inNewSize, m_AllocationName, __FILE__, __LINE__); - if (m_Size) { - intrinsics::memCopy(newData, m_Data, m_Size); - m_Allocator.deallocate(m_Data); - } - m_Data = newData; - m_Capacity = inNewSize; - } -} - -namespace { - -struct WriteBufferedStreamImpl; -struct WriteBufferThread : public Thread -{ - // When a buffer is available - WriteBufferedStreamImpl &m_Impl; - WriteBufferThread(NVFoundationBase &fnd, WriteBufferedStreamImpl &i) - : Thread(fnd) - , m_Impl(i) - { - setName("WriteBufferThread"); - } - void execute() override; -}; - -#ifdef _WIN32 -#pragma warning(disable : 4355) -#endif -/* Double buffered stream implementation with a sending thread constantly - * pulling data from the main thread and writing it out to socket. - */ -struct WriteBufferedStreamImpl : public WriteBufferedOutStream -{ - NVFoundationBase &m_Foundation; - IOutStream &m_Stream; - MemoryBuffer<> m_Buf1; - MemoryBuffer<> m_Buf2; - MemoryBuffer<> *m_CurrentBuffer; - MemoryBuffer<> *m_WriteBuffer; - QT3DSU32 m_BufferSize; - volatile bool m_StreamValid; - Mutex m_BufferLock; - Sync m_DataAvailable; - Sync m_WriteFinished; - WriteBufferThread m_Thread; - QT3DSI32 mRefCount; - - WriteBufferedStreamImpl(NVFoundationBase &fnd, QT3DSU32 totalBufSize, IOutStream &s) - : m_Foundation(fnd) - , m_Stream(s) - , m_Buf1(ForwardingAllocator(fnd.getAllocator(), "WriteBufferedStreamImpl::buffer")) - , m_Buf2(ForwardingAllocator(fnd.getAllocator(), "WriteBufferedStreamImpl::buffer")) - , m_CurrentBuffer(&m_Buf1) - , m_WriteBuffer(NULL) - , m_BufferSize(totalBufSize / 2) - , m_StreamValid(true) - , m_BufferLock(fnd.getAllocator()) - , m_DataAvailable(fnd.getAllocator()) - , m_WriteFinished(fnd.getAllocator()) - , m_Thread(fnd, *this) - , mRefCount(0) - { - m_Buf1.reserve(m_BufferSize); - m_Buf2.reserve(m_BufferSize); - } - ~WriteBufferedStreamImpl() - { - m_Thread.signalQuit(); - m_DataAvailable.set(); - m_Thread.waitForQuit(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - bool Write(NVConstDataRef data) override - { - while (data.size() && m_StreamValid) { - QT3DSU32 currentBufferSize; - QT3DSU32 amountCanWrite; - { - Mutex::ScopedLock locker(m_BufferLock); - currentBufferSize = m_CurrentBuffer->size(); - amountCanWrite = NVMin(data.size(), m_BufferSize - currentBufferSize); - m_CurrentBuffer->write(data.begin(), amountCanWrite); - currentBufferSize += amountCanWrite; - } - m_DataAvailable.set(); - if (currentBufferSize == m_BufferSize) { - m_WriteFinished.wait(); - m_WriteFinished.reset(); - // Blocking call if we are already sending data. - data = NVConstDataRef(data.begin() + amountCanWrite, - data.size() - amountCanWrite); - } - } - return m_StreamValid; - } - - IOutStream &wrappedStream() override { return m_Stream; } - - QT3DSU32 getTotalBufferSize() - { - Mutex::ScopedLock locker(m_BufferLock); - QT3DSU32 retval = m_CurrentBuffer->size(); - if (m_WriteBuffer) - retval += m_WriteBuffer->size(); - return retval; - } - - QT3DSU32 getWriteBufferSize() - { - Mutex::ScopedLock locker(m_BufferLock); - if (m_WriteBuffer) - return m_WriteBuffer->size(); - return 0; - } - - void flush() override - { - while (getTotalBufferSize()) { - m_WriteFinished.wait(); - m_WriteFinished.reset(); - } - } -}; - -void WriteBufferThread::execute() -{ - while (!quitIsSignalled()) { - m_Impl.m_DataAvailable.wait(); - - if (!quitIsSignalled() && m_Impl.m_StreamValid) { - m_Impl.m_DataAvailable.reset(); - { - Mutex::ScopedLock locker(m_Impl.m_BufferLock); - m_Impl.m_WriteBuffer = m_Impl.m_CurrentBuffer; - m_Impl.m_CurrentBuffer = - m_Impl.m_CurrentBuffer == &m_Impl.m_Buf1 ? &m_Impl.m_Buf2 : &m_Impl.m_Buf1; - QT3DS_ASSERT(m_Impl.m_WriteBuffer != m_Impl.m_CurrentBuffer); - } - NVConstDataRef dataBuffer(*m_Impl.m_WriteBuffer); - if (dataBuffer.size()) { - m_Impl.m_StreamValid = m_Impl.m_Stream.Write(dataBuffer); - { - Mutex::ScopedLock locker(m_Impl.m_BufferLock); - m_Impl.m_WriteBuffer->clear(); - m_Impl.m_WriteBuffer = NULL; - } - } - m_Impl.m_WriteFinished.set(); - } - } - quit(); -} -} - -NVScopedRefCounted -WriteBufferedOutStreamCreate(NVFoundationBase &fnd, IOutStream &stream, QT3DSU32 totalBufferSize) -{ - return QT3DS_NEW(fnd.getAllocator(), WriteBufferedStreamImpl)(fnd, totalBufferSize, stream); -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/LICENCE_SOCKET.TXT b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/LICENCE_SOCKET.TXT deleted file mode 100644 index 9b9ab805..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/LICENCE_SOCKET.TXT +++ /dev/null @@ -1,20 +0,0 @@ -LuaSocket 3.0 license -Copyright (C) 2004-2013 Diego Nehab - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSFoundation.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSFoundation.cpp deleted file mode 100644 index 8687cd69..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSFoundation.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSFoundation.h" - -#include "foundation/Qt3DSQuat.h" -#include "foundation/Qt3DSThread.h" -#include "foundation/Qt3DSUtilities.h" -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSLogging.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "EASTL/hash_map.h" - -#include -#ifdef _WIN32 -#pragma warning(disable : 4996) // intentionally suppressing this warning message -#endif -namespace qt3ds { -namespace foundation { - using namespace intrinsics; - union TempAllocatorChunk; - - class NVAllocatorListenerManager; - - class QT3DS_FOUNDATION_API Foundation : public NVFoundation - { - - Foundation(NVAllocatorCallback &alloc); - ~Foundation(); - - public: - void addRef() override; - void release() override; - - // factory - static Foundation *createInstance(QT3DSU32 version, NVAllocatorCallback &alloc); - - NVBroadcastingAllocator &getAllocator() const override { return mAllocator; } - NVAllocatorCallback &getAllocatorCallback() const override; - NVAllocatorCallback &getCheckedAllocator() { return mAllocator; } - - private: - class AlignCheckAllocator : public NVBroadcastingAllocator - { - static const QT3DSU32 MaxListenerCount = 5; - - public: - AlignCheckAllocator(NVAllocatorCallback &originalAllocator) - : mAllocator(originalAllocator) - , mListenerCount(0) - { - } - - void deallocate(void *ptr) override - { - // So here, for performance reasons I don't grab the mutex. - // The listener array is very rarely changing; for most situations - // only at startup. So it is unlikely that using the mutex - // will help a lot but it could have serious perf implications. - QT3DSU32 theCount = mListenerCount; - for (QT3DSU32 idx = 0; idx < theCount; ++idx) - mListeners[idx]->onDeallocation(ptr); - mAllocator.deallocate(ptr); - } - void *allocate(size_t size, const char *typeName, const char *filename, int line, - int flags) override; - void *allocate(size_t size, const char *typeName, const char *filename, int line, - size_t alignment, size_t alignmentOffset) override; - NVAllocatorCallback &getBaseAllocator() const { return mAllocator; } - void registerAllocationListener(NVAllocationListener &inListener) override - { - QT3DS_ASSERT(mListenerCount < MaxListenerCount); - if (mListenerCount < MaxListenerCount) { - mListeners[mListenerCount] = &inListener; - ++mListenerCount; - } - } - void deregisterAllocationListener(NVAllocationListener &inListener) override - { - for (QT3DSU32 idx = 0; idx < mListenerCount; ++idx) { - if (mListeners[idx] == &inListener) { - mListeners[idx] = mListeners[mListenerCount - 1]; - --mListenerCount; - break; - } - } - } - - private: - NVAllocatorCallback &mAllocator; - // I am not sure about using a NVArray here. - // For now, this is fine. - NVAllocationListener *mListeners[MaxListenerCount]; - volatile QT3DSU32 mListenerCount; - }; - - mutable AlignCheckAllocator mAllocator; - QT3DSU32 mRefCount; - Mutex mRefCountMutex; - }; - - Foundation::Foundation(NVAllocatorCallback &alloc) - : mAllocator(alloc) - , mRefCount(0) - , mRefCountMutex(alloc) - - { - } - - Foundation::~Foundation() {} - - NVAllocatorCallback &Foundation::getAllocatorCallback() const - { - return mAllocator.getBaseAllocator(); - } - - Foundation *Foundation::createInstance(QT3DSU32 version, NVAllocatorCallback &alloc) - { - if (version != QT3DS_FOUNDATION_VERSION) { - qCCritical(INVALID_PARAMETER, "Wrong version: foundation version is %d, tried to create %d", - QT3DS_FOUNDATION_VERSION, version); - return 0; - } - Foundation *mInstance = NULL; - - if (!mInstance) { - // if we don't assign this here, the Foundation object can't create member - // subobjects which require the allocator - - mInstance = reinterpret_cast( - alloc.allocate(sizeof(Foundation), "Foundation", __FILE__, __LINE__)); - - if (mInstance) { - QT3DS_PLACEMENT_NEW(mInstance, Foundation)(alloc); - - QT3DS_ASSERT(mInstance->mRefCount == 0); - - return mInstance; - } else { - qCCritical(INTERNAL_ERROR, "Memory allocation for foundation object failed."); - } - } else { - qCCritical( - INVALID_OPERATION, - "Foundation object exists already. Only one instance per process can be created."); - } - - return 0; - } - - void Foundation::addRef() - { - mRefCountMutex.lock(); - ++mRefCount; - mRefCountMutex.unlock(); - } - - void Foundation::release() - { - mRefCountMutex.lock(); - if (mRefCount) - --mRefCount; - QT3DSU32 refCount = mRefCount; - mRefCountMutex.unlock(); - if (!refCount) { - NVAllocatorCallback &alloc = mAllocator.getBaseAllocator(); - this->~Foundation(); - alloc.deallocate(this); - } - } - - void *Foundation::AlignCheckAllocator::allocate(size_t size, const char *typeName, - const char *filename, int line, int) - { - void *addr = mAllocator.allocate(size, typeName, filename, line); - - if (!addr) - qFatal("User allocator returned NULL."); - - if (!(reinterpret_cast(addr) & 15)) { - // Same comment as before in the allocation system. - // We don't lock the listener array mutex because of an assumption - // where the listener array is rarely changing. - QT3DSU32 theCount = mListenerCount; - for (QT3DSU32 idx = 0; idx < theCount; ++idx) - mListeners[idx]->onAllocation(size, typeName, filename, line, addr); - return addr; - } - - qFatal("Allocations for qt3ds::foundation must be 16-byte aligned."); - return 0; - } - - void *Foundation::AlignCheckAllocator::allocate(size_t size, const char *typeName, - const char *filename, int line, - size_t /*alignment*/, - size_t /*alignmentOffset*/) - { - return allocate(size, typeName, filename, line, 0); - } - -} // namespace foundation -} // namespace qt3ds - -qt3ds::NVFoundation *NVCreateFoundation(qt3ds::QT3DSU32 version, qt3ds::NVAllocatorCallback &allocator) -{ - return qt3ds::foundation::Foundation::createInstance(version, allocator); -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSLogging.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSLogging.cpp deleted file mode 100644 index 257b39b2..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSLogging.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSLogging.h" - -namespace qt3ds { - -Q_LOGGING_CATEGORY(GL_ERROR, "qt3ds.gl_error") -Q_LOGGING_CATEGORY(INVALID_PARAMETER, "qt3ds.invalid_parameter") -Q_LOGGING_CATEGORY(INVALID_OPERATION, "qt3ds.invalid_operation") -Q_LOGGING_CATEGORY(OUT_OF_MEMORY, "qt3ds.out_of_memory") -Q_LOGGING_CATEGORY(INTERNAL_ERROR, "qt3ds.internal_error") -Q_LOGGING_CATEGORY(PERF_WARNING, "qt3ds.perf_warning") -Q_LOGGING_CATEGORY(PERF_INFO, "qt3ds.perf_info") -Q_LOGGING_CATEGORY(TRACE_INFO, "qt3ds.trace_info") -Q_LOGGING_CATEGORY(WARNING, "qt3ds.warning") - -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSMathUtils.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSMathUtils.cpp deleted file mode 100644 index 7eee7405..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSMathUtils.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSMathUtils.h" -#include "foundation/Qt3DSUtilities.h" -#include "foundation/Qt3DSMat33.h" - -using namespace qt3ds; -using namespace qt3ds::foundation; -using namespace qt3ds::intrinsics; - -QT3DSQuat qt3ds::foundation::computeQuatFromNormal(const QT3DSVec3 &n) -{ - // parallel or anti-parallel - if (n.x > 0.9999f) { - // parallel - return QT3DSQuat::createIdentity(); - } else if (n.x < -0.9999f) { - // anti-parallel - // contactQuaternion.fromAngleAxisFast(PXD_PI, Vector3(0.0f, 1.0f, 0.0f)); - return QT3DSQuat(0.0f, 1.0f, 0.0f, 0.0f); - } else { - QT3DSVec3 rotVec(0.0f, -n.z, n.y); - - // Convert to quat - NVReal angle = rotVec.magnitude(); - rotVec *= 1.0f / angle; - // if(angle > 1.0f) angle = 1.0f; - angle = selectMin(angle, 1.0f); - - // djs: injudiciously imbecilic use of trig functions, good thing Adam is going to trample - // this path like a - // frustrated rhinoceros in mating season - - angle = NVAsin(angle); - - // if(n.x < 0) - // angle = NVPi - angle; - angle = fsel(n.x, angle, NVPi - angle); - - return QT3DSQuat(angle, rotVec); - } -} - -/** -\brief computes a oriented bounding box around the scaled basis. -\param basis Input = skewed basis, Output = (normalized) orthogonal basis. -\return Bounding box extent. -*/ -QT3DSVec3 qt3ds::foundation::optimizeBoundingBox(QT3DSMat33 &basis) -{ - QT3DSVec3 *QT3DS_RESTRICT vec = &basis[0]; // PT: don't copy vectors if not needed... - - // PT: since we store the magnitudes to memory, we can avoid the FCMNV afterwards - QT3DSVec3 magnitude(vec[0].magnitudeSquared(), vec[1].magnitudeSquared(), - vec[2].magnitudeSquared()); - -// find indices sorted by magnitude -#ifdef QT3DS_X360 - int i = (QT3DSU32 &)(magnitude[1]) > (QT3DSU32 &)(magnitude[0]) ? 1 : 0; - int j = (QT3DSU32 &)(magnitude[2]) > (QT3DSU32 &)(magnitude[1 - i]) ? 2 : 1 - i; -#else - int i = magnitude[1] > magnitude[0] ? 1 : 0; - int j = magnitude[2] > magnitude[1 - i] ? 2 : 1 - i; -#endif - const int k = 3 - i - j; -#ifdef QT3DS_X360 - if ((QT3DSU32 &)(magnitude[i]) < (QT3DSU32 &)(magnitude[j])) -#else - if (magnitude[i] < magnitude[j]) -#endif - swap(i, j); - - // ortho-normalize basis - - NVReal invSqrt = NVRecipSqrt(magnitude[i]); - magnitude[i] *= invSqrt; - vec[i] *= invSqrt; // normalize the first axis - NVReal dotij = vec[i].dot(vec[j]); - NVReal dotik = vec[i].dot(vec[k]); - magnitude[i] += NVAbs(dotij) + NVAbs(dotik); // elongate the axis by projection of the other two - vec[j] -= vec[i] * dotij; // orthogonize the two remaining axii relative to vec[i] - vec[k] -= vec[i] * dotik; - - magnitude[j] = vec[j].normalize(); - NVReal dotjk = vec[j].dot(vec[k]); - magnitude[j] += NVAbs(dotjk); // elongate the axis by projection of the other one - vec[k] -= vec[j] * dotjk; // orthogonize vec[k] relative to vec[j] - - magnitude[k] = vec[k].normalize(); - - return magnitude; -} - -QT3DSQuat qt3ds::foundation::slerp(const NVReal t, const QT3DSQuat &left, const QT3DSQuat &right) -{ - const NVReal quatEpsilon = (NVReal(1.0e-8f)); - - NVReal cosine = left.dot(right); - NVReal sign = NVReal(1); - if (cosine < 0) { - cosine = -cosine; - sign = NVReal(-1); - } - - NVReal sine = NVReal(1) - cosine * cosine; - - if (sine >= quatEpsilon * quatEpsilon) { - sine = NVSqrt(sine); - const NVReal angle = NVAtan2(sine, cosine); - const NVReal i_sin_angle = NVReal(1) / sine; - - const NVReal leftw = NVSin(angle * (NVReal(1) - t)) * i_sin_angle; - const NVReal rightw = NVSin(angle * t) * i_sin_angle * sign; - - return left * leftw + right * rightw; - } - - return left; -} - -void qt3ds::foundation::integrateTransform(const NVTransform &curTrans, const QT3DSVec3 &linvel, - const QT3DSVec3 &angvel, NVReal timeStep, NVTransform &result) -{ - result.p = curTrans.p + linvel * timeStep; - - // from void NVsDynamicsContext::integrateAtomPose(NVsRigidBody* atom, Cm::BitMap - // &shapeChangedMap) const: - // Integrate the rotation using closed form quaternion integrator - NVReal w = angvel.magnitudeSquared(); - - if (w != 0.0f) { - w = NVSqrt(w); - if (w != 0.0f) { - const NVReal v = timeStep * w * 0.5f; - const NVReal q = NVCos(v); - const NVReal s = NVSin(v) / w; - - const QT3DSVec3 pqr = angvel * s; - const QT3DSQuat quatVel(pqr.x, pqr.y, pqr.z, 0); - QT3DSQuat out; // need to have temporary, otherwise we may overwrite input if &curTrans == - // &result. - out = quatVel * curTrans.q; - out.x += curTrans.q.x * q; - out.y += curTrans.q.y * q; - out.z += curTrans.q.z * q; - out.w += curTrans.q.w * q; - result.q = out; - return; - } - } - // orientation stays the same - convert from quat to matrix: - result.q = curTrans.q; -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSPerfTimer.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSPerfTimer.cpp deleted file mode 100644 index 06fb5d38..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSPerfTimer.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "EASTL/hash_map.h" -#include "EASTL/string.h" -#include "EASTL/vector.h" -#include "EASTL/sort.h" - -using namespace qt3ds::foundation; -using namespace qt3ds; - -namespace { -struct STimerEntry -{ - QT3DSU64 m_Total; - QT3DSU64 m_Max; - QT3DSU32 m_UpdateCount; - CRegisteredString m_Tag; - size_t m_Order; - - STimerEntry(CRegisteredString tag, size_t order) - : m_Total(0) - , m_Max(0) - , m_UpdateCount(0) - , m_Tag(tag) - , m_Order(order) - { - } - void Update(QT3DSU64 increment) - { - m_Total += increment; - m_Max = increment > m_Max ? increment : m_Max; - ++m_UpdateCount; - } - - void Output(NVFoundationBase &fnd, QT3DSU32 inFramesPassed) - { - Q_UNUSED(fnd) - if (m_Total) { - QT3DSU64 tensNanos = Time::sCounterFreq.toTensOfNanos(m_Total); - QT3DSU64 maxNanos = Time::sCounterFreq.toTensOfNanos(m_Max); - - double milliseconds = tensNanos / 100000.0; - double maxMilliseconds = maxNanos / 100000.0; - if (inFramesPassed == 0) - qCWarning(WARNING, PERF_INFO, "%s - %fms", m_Tag.c_str(), milliseconds); - else { - milliseconds /= inFramesPassed; - qCWarning(WARNING, PERF_INFO, "%s - %fms/frame-total %fms-max %u hits", - m_Tag.c_str(), milliseconds, maxMilliseconds, m_UpdateCount); - } - } - } - - void Reset() - { - m_Total = 0; - m_Max = 0; - m_UpdateCount = 0; - } - - bool operator<(const STimerEntry &other) const { return m_Order < other.m_Order; } -}; -struct SPerfTimer : public IPerfTimer -{ - typedef eastl::hash_map THashMapType; - NVFoundationBase &m_Foundation; - // This object needs its own string table because it is used during the binary load process with - // the application string table gets booted up. - NVScopedRefCounted m_StringTable; - THashMapType m_Entries; - eastl::vector m_PrintEntries; - Mutex m_Mutex; - QT3DSI32 mRefCount; - - SPerfTimer(NVFoundationBase &fnd) - : m_Foundation(fnd) - , m_StringTable(IStringTable::CreateStringTable(fnd.getAllocator())) - , m_Mutex(fnd.getAllocator()) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - void Update(const char *inId, QT3DSU64 inAmount) override - { - Mutex::ScopedLock __locker(m_Mutex); - CRegisteredString theStr(m_StringTable->RegisterStr(inId)); - THashMapType::iterator theFind = - m_Entries.insert(eastl::make_pair(theStr, STimerEntry(theStr, m_Entries.size()))).first; - theFind->second.Update(inAmount); - } - - // Dump current summation of timer data. - void OutputTimerData(QT3DSU32 inFramesPassed = 0) override - { - Mutex::ScopedLock __locker(m_Mutex); - m_PrintEntries.clear(); - for (THashMapType::iterator iter = m_Entries.begin(), end = m_Entries.end(); iter != end; - ++iter) { - m_PrintEntries.push_back(iter->second); - iter->second.Reset(); - } - - eastl::sort(m_PrintEntries.begin(), m_PrintEntries.end()); - - for (QT3DSU32 idx = 0, end = (QT3DSU32)m_PrintEntries.size(); idx < end; ++idx) { - m_PrintEntries[idx].Output(m_Foundation, inFramesPassed); - } - } - - void ResetTimerData() override - { - Mutex::ScopedLock __locker(m_Mutex); - for (THashMapType::iterator iter = m_Entries.begin(), end = m_Entries.end(); iter != end; - ++iter) { - iter->second.Reset(); - } - } - - virtual void ClearPerfKeys() - { - Mutex::ScopedLock __locker(m_Mutex); - m_Entries.clear(); - } -}; -} - -IPerfTimer &IPerfTimer::CreatePerfTimer(NVFoundationBase &fnd) -{ - return *QT3DS_NEW(fnd.getAllocator(), SPerfTimer)(fnd); -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSSystem.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSSystem.cpp deleted file mode 100644 index e87a25ea..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Qt3DSSystem.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSSystem.h" -#include "foundation/Qt3DSPreprocessor.h" -#include "EASTL/string.h" - -using namespace qt3ds; -using namespace qt3ds::foundation; - -#if defined(QT3DS_ANDROID) -const char *qt3ds::foundation::System::g_OS = "android"; -const char *qt3ds::foundation::System::g_DLLExtension = ".so"; -#elif defined(QT3DS_APPLE) -const char *qt3ds::foundation::System::g_OS = "osx"; -const char *qt3ds::foundation::System::g_DLLExtension = ".dylib"; -#elif defined(QT3DS_LINUX) -const char *qt3ds::foundation::System::g_OS = "linux"; -const char *qt3ds::foundation::System::g_DLLExtension = ".so"; -#elif defined(QT3DS_QNX) -const char *qt3ds::foundation::System::g_OS = "qnx"; -const char *qt3ds::foundation::System::g_DLLExtension = ".so"; -#elif defined(QT3DS_WINDOWS) -const char *qt3ds::foundation::System::g_OS = "windows"; -const char *qt3ds::foundation::System::g_DLLExtension = ".dll"; -#else -#error "Unknown Operating System" -#endif - -#if defined(QT3DS_X86) -const char *qt3ds::foundation::System::g_Processor = "x86"; -const char *qt3ds::foundation::System::g_BitWidth = "32"; -const char *qt3ds::foundation::System::g_FloatingPointModel = ""; -#elif defined(QT3DS_X64) -const char *qt3ds::foundation::System::g_Processor = "x64"; -const char *qt3ds::foundation::System::g_BitWidth = "64"; -const char *qt3ds::foundation::System::g_FloatingPointModel = ""; -#elif defined(QT3DS_ARM) -#if defined(__aarch64__) || defined(__ARM64__) -const char *qt3ds::foundation::System::g_Processor = "arm"; -const char *qt3ds::foundation::System::g_BitWidth = "64"; -const char *qt3ds::foundation::System::g_FloatingPointModel = "softfp"; -#else -const char *qt3ds::foundation::System::g_Processor = "arm"; -const char *qt3ds::foundation::System::g_BitWidth = "32"; -#if defined(QT3DS_ARM_HARDFP) -const char *qt3ds::foundation::System::g_FloatingPointModel = "hardfp"; -#elif defined(QT3DS_ARM_SOFTFP) -const char *qt3ds::foundation::System::g_FloatingPointModel = "softfp"; -#else -#error "Unknown floating point model!" -#endif -#endif -#else -#error "Unknown Platform" -#endif - -#if defined(QT3DS_ARM) -#if defined(QT3DS_GRAPHICS_API_GLES2) -const char *qt3ds::foundation::System::g_GPUType = "gles2"; -#elif defined(QT3DS_GRAPHICS_API_GL) -const char *qt3ds::foundation::System::g_GPUType = "gl"; -#elif defined(QT3DS_GRAPHICS_API_GLES3) -const char *qt3ds::foundation::System::g_GPUType = "gles3"; -#else -#error \ - "Must define a GPU type for arm platforms (QT3DS_GRAPHICS_API_GLES2, QT3DS_GRAPHICS_API_GLES3, QT3DS_GRAPHICS_API_GL)" -#endif -#elif defined(QT3DS_X86) -const char *qt3ds::foundation::System::g_GPUType = ""; -#elif defined(QT3DS_X64) -const char *qt3ds::foundation::System::g_GPUType = ""; -#else -#error "Must define a processor type (QT3DS_ARM or QT3DS_X86)" -#endif - -namespace { -static const unsigned SYSTEM_STR_SIZE = 100; -void SystemAppendString(eastl::string &str, const char *delim, const char *string) -{ - if (string && *string) { - str.append(delim); - str.append(string); - } -} -} -const char *System::getPlatformStr() -{ - static char text[SYSTEM_STR_SIZE]; - { - eastl::string str(g_Processor); - SystemAppendString(str, "_", g_BitWidth); - SystemAppendString(str, "_", g_FloatingPointModel); - SystemAppendString(str, "_", g_OS); - strcpy(text, str.c_str()); - } - return text; -} - -const char *System::getPlatformGLStr() -{ - static char text[SYSTEM_STR_SIZE]; - { - eastl::string str(g_Processor); - SystemAppendString(str, "_", g_BitWidth); - SystemAppendString(str, "_", g_FloatingPointModel); - SystemAppendString(str, "_", g_GPUType); - SystemAppendString(str, "_", g_OS); - strcpy(text, str.c_str()); - } - return text; -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Socket.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Socket.cpp deleted file mode 100644 index df00e606..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/Socket.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* -LuaSocket 3.0 license -Copyright � 2004-2013 Diego Nehab - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - -#include "foundation/Socket.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSMemoryBuffer.h" - -#if defined QT3DS_WINDOWS || defined QT3DS_WIN8ARM -#include "windows/SocketImpl.h" -#else -#include "linux/SocketImpl.h" -#endif - -using namespace qt3ds; -using namespace qt3ds::foundation; -using namespace qt3ds::foundation::socketimpl; - -namespace { - -#if defined QT3DS_WINDOWS || defined QT3DS_WIN8ARM -/*-------------------------------------------------------------------------*\ -* Some systems do not provide this so that we provide our own. It's not -* marvelously fast, but it works just fine. -\*-------------------------------------------------------------------------*/ -int inet_aton(const char *cp, struct in_addr *inp) -{ - unsigned int a = 0, b = 0, c = 0, d = 0; - int n = 0, r; - unsigned long int addr = 0; - r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n); - if (r == 0 || n == 0) - return 0; - cp += n; - if (*cp) - return 0; - if (a > 255 || b > 255 || c > 255 || d > 255) - return 0; - if (inp) { - addr += a; - addr <<= 8; - addr += b; - addr <<= 8; - addr += c; - addr <<= 8; - addr += d; - inp->s_addr = htonl(addr); - } - return 1; -} -#endif - -/*-------------------------------------------------------------------------*\ -* Tries to connect to remote address (address, port) -\*-------------------------------------------------------------------------*/ -int inet_tryconnect(p_socket ps, const char *address, unsigned short port, QT3DSU32 tm, SA *remoteAddr) -{ - struct sockaddr_in remote; - int err; - memset(&remote, 0, sizeof(remote)); - remote.sin_family = AF_INET; - remote.sin_port = htons(port); - if (strcmp(address, "*")) { - if (!inet_aton(address, &remote.sin_addr)) { - struct hostent *hp = NULL; - struct in_addr **addr; - err = socket_gethostbyname(address, &hp); - if (err != IO_DONE) - return err; - addr = (struct in_addr **)hp->h_addr_list; - memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); - } - } else - remote.sin_family = AF_UNSPEC; - if (remoteAddr) - memcpy(remoteAddr, &remote, sizeof(remote)); - err = socket_connect(ps, (SA *)&remote, sizeof(remote), tm); - return err; -} - -/*-------------------------------------------------------------------------*\ -* Tries to bind socket to (address, port) -\*-------------------------------------------------------------------------*/ -int inet_trybind(p_socket ps, const char *address, unsigned short port) -{ - struct sockaddr_in local; - int err; - memset(&local, 0, sizeof(local)); - /* address is either wildcard or a valid ip address */ - local.sin_addr.s_addr = htonl(INADDR_ANY); - local.sin_port = htons(port); - local.sin_family = AF_INET; - if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { - struct hostent *hp = NULL; - struct in_addr **addr; - err = socket_gethostbyname(address, &hp); - if (err != IO_DONE) - return err; - addr = (struct in_addr **)hp->h_addr_list; - memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); - } - err = socket_bind(ps, (SA *)&local, sizeof(local)); - if (err != IO_DONE) - socket_destroy(ps); - return err; -} - -static bool is_socket_error(int errcode) -{ - return errcode != IO_DONE && errcode != IO_TIMEOUT; -} - -const char *generalized_strerror(int err) -{ - if (err <= 0) - return io_strerror(err); - else - return socket_strerror(err); -} - -struct SocketSystemCore : public NVRefCounted -{ - NVFoundationBase &m_Foundation; - QT3DSI32 mRefCount; - SocketSystemCore(NVFoundationBase &fnd) - : m_Foundation(fnd) - , mRefCount(0) - { - } - ~SocketSystemCore() { socket_close(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - static NVScopedRefCounted Create(NVFoundationBase &fnd) - { - int success = socket_open(); - if (!success) { - qCCritical(INVALID_OPERATION, "Failed to initialize network subsystem"); - return NVScopedRefCounted(); - } - return QT3DS_NEW(fnd.getAllocator(), SocketSystemCore)(fnd); - } -}; - -struct SocketStreamImpl : public SocketStream -{ - NVScopedRefCounted m_SocketCore; - NVFoundationBase &m_Foundation; - t_socket m_Socket; - SA m_Destination; - bool m_Connected; - QT3DSU32 m_Timeout; - QT3DSI32 mRefCount; - SocketStreamImpl(SocketSystemCore &core, NVFoundationBase &fnd, t_socket s, SA dest) - : m_SocketCore(core) - , m_Foundation(fnd) - , m_Socket(s) - , m_Destination(dest) - , m_Connected(true) - , m_Timeout(10000) - , mRefCount(0) - { - // We use wait functions in order to block. - socket_setnonblocking(&m_Socket); - } - - ~SocketStreamImpl() - { - shutdown(); - socket_destroy(&m_Socket); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - void setTimeout(QT3DSU32 milliseconds) override { m_Timeout = milliseconds; } - - bool Write(NVConstDataRef data) override - { - if (m_Connected == false) - return false; - - size_t totalSent = 0; - const char *writePtr(reinterpret_cast(data.begin())); - size_t amountLeft = data.size(); - do { - - size_t amountSent = 0; - int errcode = - socket_send(&m_Socket, writePtr + totalSent, amountLeft, &amountSent, m_Timeout); - - if (is_socket_error(errcode)) { - m_Connected = false; - qCWarning(WARNING, "Networking error during send: %s", generalized_strerror(errcode)); - return false; - } - totalSent += amountSent; - amountLeft -= amountSent; - } while (amountLeft); - return true; - } - - QT3DSU32 Read(NVDataRef data) override - { - if (m_Connected == false) - return 0; - size_t amountReceived = 0; - int errcode = socket_recv(&m_Socket, reinterpret_cast(data.begin()), data.size(), - &amountReceived, m_Timeout); - if (is_socket_error(errcode)) { - m_Connected = false; - qCWarning(WARNING, "Networking error during receive: %s", generalized_strerror(errcode)); - return false; - } - return static_cast(amountReceived); - } - - QT3DSU32 nonBlockingRead(NVDataRef data) override - { - if (m_Connected == false) - return 0; - size_t amountReceived = 0; - int errcode = socket_recv(&m_Socket, reinterpret_cast(data.begin()), data.size(), - &amountReceived, 0); - if (is_socket_error(errcode)) { - m_Connected = false; - qCWarning(WARNING, "Networking error during receive: %s", - generalized_strerror(errcode)); - return false; - } - return static_cast(amountReceived); - } - - bool connected() override { return m_Connected; } - - void shutdown() override - { - if (m_Connected) { - socket_shutdown(&m_Socket, 2); - m_Connected = false; - } - } -}; - -struct FileSocketStreamImpl : public SocketStream -{ - NVFoundationBase &m_Foundation; - CFileSeekableIOStream m_Stream; - FileOpenFlags m_FileFlags; - bool m_Connected; - QT3DSI32 mRefCount; - - FileSocketStreamImpl(NVFoundationBase &fnd, const char *fname, FileOpenFlags fileFlags) - : m_Foundation(fnd) - , m_Stream(fname, fileFlags) - , m_FileFlags(fileFlags) - , m_Connected(false) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - bool IsOpen() { return m_Connected && m_Stream.IsOpen(); } - - QT3DSU32 Read(NVDataRef data) override - { - if (IsOpen()) { - QT3DSU32 retval = m_Stream.Read(data); - if (retval < data.size()) - m_Connected = false; - return retval; - } - - return 0; - } - - bool Write(NVConstDataRef data) override - { - bool canWrite = m_FileFlags & FileOpenFlagValues::Write; - if (IsOpen() && canWrite) { - m_Stream.Write(data); - return true; - } - return false; - } - - void setTimeout(QT3DSU32) override {} - - QT3DSU32 nonBlockingRead(NVDataRef data) override { return Read(data); } - - bool connected() override { return m_Connected; } - - void shutdown() override { m_Connected = false; } -}; - -struct SocketServerImpl : public SocketServer -{ - NVScopedRefCounted m_SocketCore; - NVFoundationBase &m_Foundation; - t_socket m_Socket; - int m_Port; - QT3DSU32 m_Timeout; - QT3DSI32 mRefCount; - SocketServerImpl(SocketSystemCore &core, NVFoundationBase &fnd, t_socket s, int port) - : m_SocketCore(core) - , m_Foundation(fnd) - , m_Socket(s) - , m_Port(port) - , m_Timeout(10000) - , mRefCount(0) - { - } - - ~SocketServerImpl() { socket_destroy(&m_Socket); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - int port() override { return m_Port; } - - void setTimeout(QT3DSU32 milliseconds) override { m_Timeout = milliseconds; } - - NVScopedRefCounted nextClient() override - { - SA daddr; - memset(&daddr, 0, sizeof(daddr)); - t_socket new_socket; - int errcode = socket_accept(&m_Socket, &new_socket, NULL, NULL, m_Timeout); - - if (is_socket_error(errcode)) { - return NVScopedRefCounted(); - } else if (errcode == IO_DONE) { - return QT3DS_NEW(m_Foundation.getAllocator(), - SocketStreamImpl)(*m_SocketCore, m_Foundation, new_socket, daddr); - } - return NVScopedRefCounted(); - } -}; - -struct SocketSystemImpl : public SocketSystem -{ - NVScopedRefCounted m_SocketCore; - NVFoundationBase &m_Foundation; - QT3DSI32 mRefCount; - SocketSystemImpl(SocketSystemCore &core, NVFoundationBase &fnd) - : m_SocketCore(core) - , m_Foundation(fnd) - , mRefCount(0) - - { - } - ~SocketSystemImpl() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - NVScopedRefCounted createStream(const char *host, QT3DSI32 port, - QT3DSU32 timeoutMilliseconds) override - { - t_socket newSocket(SOCKET_INVALID); - int errcode = socket_create(&newSocket, PF_INET, SOCK_STREAM, 0); - if (is_socket_error(errcode)) { - qCWarning(WARNING, "Error during connect: %s", generalized_strerror(errcode)); - return NVScopedRefCounted(); - } - SA remoteAddr; - memset(&remoteAddr, 0, sizeof(SA)); - errcode = inet_tryconnect(&newSocket, host, (unsigned short)port, timeoutMilliseconds, - &remoteAddr); - if (is_socket_error(errcode)) { - qCWarning(WARNING, "Error during connect: %s", generalized_strerror(errcode)); - return NVScopedRefCounted(); - } else if (errcode == IO_DONE) { - return QT3DS_NEW(m_Foundation.getAllocator(), - SocketStreamImpl)(*m_SocketCore, m_Foundation, newSocket, remoteAddr); - } - return NVScopedRefCounted(); - } - - NVScopedRefCounted createServer(QT3DSI32 port) override - { - t_socket newSocket(SOCKET_INVALID); - int errcode = socket_create(&newSocket, PF_INET, SOCK_STREAM, 0); - if (is_socket_error(errcode)) { - qCWarning(WARNING, "Error during create server create socket: %s", - generalized_strerror(errcode)); - return NVScopedRefCounted(); - } - errcode = inet_trybind(&newSocket, "*", (unsigned short)port); - if (is_socket_error(errcode)) { - qCWarning(WARNING, "Error during create server bind: %s", - generalized_strerror(errcode)); - return NVScopedRefCounted(); - } else if (errcode == IO_DONE) { - errcode = socket_listen(&newSocket, 10); - if (errcode == IO_DONE) { - return QT3DS_NEW(m_Foundation.getAllocator(), - SocketServerImpl)(*m_SocketCore, m_Foundation, newSocket, port); - } else - qCWarning(WARNING, "Error during create server listen: %s", - generalized_strerror(errcode)); - } - return NVScopedRefCounted(); - } -}; -} - -NVScopedRefCounted -SocketStream::CreateFileStream(NVFoundationBase &fnd, const char *fname, FileOpenFlags flags) -{ - return QT3DS_NEW(fnd.getAllocator(), FileSocketStreamImpl)(fnd, fname, flags); -} - -NVScopedRefCounted SocketSystem::createSocketSystem(NVFoundationBase &fnd) -{ - NVScopedRefCounted theCore = SocketSystemCore::Create(fnd); - if (theCore) { - return QT3DS_NEW(fnd.getAllocator(), SocketSystemImpl)(*theCore, fnd); - } - return NVScopedRefCounted(); -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/StringTable.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/StringTable.cpp deleted file mode 100644 index 9e78cfd3..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/StringTable.cpp +++ /dev/null @@ -1,672 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/StringTable.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Utils.h" -#include "EASTL/string.h" -#include "EASTL/sort.h" -#include "foundation/StrConvertUTF.h" -#include "foundation/PreAllocatedAllocator.h" -#include "foundation/SerializationTypes.h" -#include "foundation/Qt3DSMutex.h" - -using namespace qt3ds; -using namespace qt3ds::foundation; -using namespace eastl; - -namespace eastl { -struct SCharAndHash -{ - const char8_t *m_Data; - size_t m_Hash; - // Cache the generated hash code. - SCharAndHash(const char8_t *inData) - : m_Data(inData) - , m_Hash(eastl::hash()(inData)) - { - } - SCharAndHash() - : m_Data(NULL) - , m_Hash(0) - { - } - operator const char *() const { return m_Data; } -}; -template <> -struct hash -{ - size_t operator()(const SCharAndHash &inItem) const { return inItem.m_Hash; } -}; - -template <> -struct equal_to -{ - bool operator()(const SCharAndHash &inLhs, const SCharAndHash &inRhs) const - { - return char_equal_to()(inLhs.m_Data, inRhs.m_Data); - } -}; -} - -void CRegisteredString::Remap(const IStringTable &inTable) -{ - Remap(const_cast(inTable).GetRemapMap()); -} - -void CRegisteredString::Remap(const SStrRemapMap &inMap) -{ - if (IsValid()) { - SStrRemapMap::const_iterator theIter = inMap.find((char8_t *)m_String); - if (theIter != inMap.end()) - m_String = reinterpret_cast(theIter->second); - else { - QT3DS_ASSERT(false); - // Ensure a failure here doesn't *guarantee* a crash somewhere else. - m_String = NULL; - } - } else { - // Indicates an invalid string. - m_String = reinterpret_cast(QT3DS_MAX_U32); - } -} - -void CRegisteredString::Remap(NVDataRef inDataPtr) -{ - size_t theOffset = reinterpret_cast(m_String); - if (theOffset >= QT3DS_MAX_U32) - m_String = ""; - else { - if (theOffset < inDataPtr.size()) - m_String = reinterpret_cast(inDataPtr.begin() + theOffset); - else { - QT3DS_ASSERT(false); - m_String = ""; - } - } -} - -namespace { - -const char16_t g_char16EmptyStr[] = { 0, 0, 0, 0 }; -const char32_t g_char32EmptyStr[] = { 0, 0, 0, 0 }; - -typedef eastl::basic_string TNarrowStr; -typedef eastl::basic_string TWideStr; - -inline bool isTrivialWide(const wchar_t *str) -{ - return str == NULL || *str == 0; -} - -QT3DSU8 *AlignPointer(QT3DSU8 *inStart, QT3DSU8 *inPtr) -{ - QT3DSU32 alignment = sizeof(void *); - size_t numBytes = (size_t)(inPtr - inStart); - QT3DS_ASSERT(inStart < inPtr); - if (numBytes % alignment) - inPtr += alignment - (numBytes % alignment); - return inPtr; -} - -QT3DSU32 Align(QT3DSU32 inValue) -{ - QT3DSU32 alignment = sizeof(void *); - QT3DSU32 leftover = inValue % alignment; - if (leftover) - inValue += alignment - leftover; - return inValue; -} - -// Structure that is written out to the file. -// Directly after this is the string character data. -// TWideStr& inConvertStr -struct SStringFileData -{ - QT3DSU32 m_StartOffset; - QT3DSU32 m_StrLen; - QT3DSU32 m_Handle; - char8_t *m_Str; - SStringFileData(QT3DSU32 len, QT3DSU32 off, QT3DSU32 handle, char8_t *data) - : m_StartOffset(off) - , m_StrLen(len) - , m_Handle(handle) - , m_Str(data) - { - } - SStringFileData() - : m_StartOffset(0) - , m_StrLen(0) - , m_Handle(0) - , m_Str(NULL) - { - } - void Deallocate(NVAllocatorCallback &inAlloc) - { - inAlloc.deallocate(m_Str); - m_Str = NULL; - } - const char8_t *GetNarrow() { return m_Str; } - operator CRegisteredString() const - { - return CRegisteredString::ISwearThisHasBeenRegistered(m_Str); - } - QT3DSU32 EndOffset() const { return m_StartOffset + m_StrLen; } - - // Used only for the lower bound operation to find a given object by offset. - bool operator<(const SStringFileData &inOther) const - { - return m_StartOffset < inOther.m_StartOffset; - } -}; - -struct SCharAndHandle -{ - const char8_t *m_Data; - QT3DSU32 m_Handle; - SCharAndHandle() - : m_Data(NULL) - , m_Handle(0) - { - } - SCharAndHandle(const char8_t *data, QT3DSU32 hdl) - : m_Data(data) - , m_Handle(hdl) - { - } - operator const char *() const { return m_Data; } -}; - -struct SStringFileHeader -{ - QT3DSU32 m_NumStrings; - QT3DSU32 m_NextHandleValue; - // offset to the items of fixed size. Variable sized data is stored - // up front. - QT3DSU32 m_FixedBufferOffset; - SStringFileHeader() - : m_NumStrings(0) - , m_NextHandleValue(0) - , m_FixedBufferOffset(0) - { - } - - SStringFileHeader(QT3DSU32 ns, QT3DSU32 hv, QT3DSU32 fbo) - : m_NumStrings(ns) - , m_NextHandleValue(hv) - , m_FixedBufferOffset(fbo) - { - } -}; - -// This is the core of the string table. -struct SStringFileDataList -{ - typedef nvhash_map TMapType; - typedef nvhash_map THandleMapType; - - mutable SPreAllocatedAllocator m_Allocator; - - // When we load from a file, we get a these items - NVConstDataRef m_DataBlock; - NVConstDataRef> m_HashDataBlockOffset; - NVConstDataRef> m_HandleDataBlockOffset; - - // When we are running normally, this items get mangled - nvvector m_AppendedStrings; - -protected: - // Built roughly on demand - SStrRemapMap m_StrRemapMap; - TMapType m_HashToStrMap; - THandleMapType m_HandleToStrMap; - QT3DSU32 m_NextHandleValue; - -public: - SStringFileDataList(NVAllocatorCallback &inAlloc) - : m_Allocator(inAlloc) - , m_AppendedStrings(inAlloc, "StringTable::m_AppendedStrings") - , m_StrRemapMap(inAlloc, "StringTable::m_StrRemapMap") - , m_HashToStrMap(inAlloc, "StringTable::m_HashToStrMap") - , m_HandleToStrMap(inAlloc, "StringTable::m_HashToStrMap") - , m_NextHandleValue(1) - { - } - ~SStringFileDataList() - { - for (QT3DSU32 idx = 0, end = m_AppendedStrings.size(); idx < end; ++idx) - m_AppendedStrings[idx].Deallocate(m_Allocator); - } - - SStrRemapMap &GetRemapMap() - { - if (m_StrRemapMap.empty()) { - for (QT3DSU32 idx = 0, end = m_DataBlock.size(); idx < end; ++idx) - m_StrRemapMap.insert( - eastl::make_pair(m_DataBlock[idx].m_Str, m_DataBlock[idx].m_StartOffset)); - for (QT3DSU32 idx = 0, end = m_AppendedStrings.size(); idx < end; ++idx) - m_StrRemapMap.insert(eastl::make_pair(m_AppendedStrings[idx].m_Str, - m_AppendedStrings[idx].m_StartOffset)); - } - return m_StrRemapMap; - } - - struct SHashPairComparator - { - bool operator()(const eastl::pair &lhs, - const eastl::pair &rhs) const - { - return lhs.first < rhs.first; - } - }; - - struct SHandlePairComparator - { - bool operator()(const eastl::pair &lhs, - const eastl::pair &rhs) const - { - return lhs.first < rhs.first; - } - }; - - SCharAndHandle DoFindStr(SCharAndHash hashCode) - { - if (isTrivial(hashCode.m_Data)) - return SCharAndHandle(); - TMapType::iterator theFind = m_HashToStrMap.find(hashCode); - if (theFind == m_HashToStrMap.end()) { - SCharAndHandle newStr = FindStrByHash(hashCode); - if (!newStr.m_Data) - newStr = Append(hashCode); - - // It may not be obvious why we have to reset the data member. - // we have to do this so the hashtable keys don't change if the user isn't - // passing in a persistent string. - hashCode.m_Data = newStr; - - theFind = m_HashToStrMap.insert(eastl::make_pair(hashCode, newStr)).first; - m_HandleToStrMap.insert(eastl::make_pair(theFind->second.m_Handle, newStr)); - } - return theFind->second; - } - - const CRegisteredString FindStr(SCharAndHash hashCode) - { - SCharAndHandle result = DoFindStr(hashCode); - if (result.m_Data) - return CRegisteredString::ISwearThisHasBeenRegistered(result.m_Data); - return CRegisteredString(); - } - - const CStringHandle FindStrHandle(SCharAndHash hashCode) - { - SCharAndHandle result = DoFindStr(hashCode); - return CStringHandle::ISwearThisHasBeenRegistered(result.m_Handle); - } - - const CRegisteredString FindStrByHandle(QT3DSU32 handle) - { - if (handle == 0) - return CRegisteredString(); - - THandleMapType::iterator theFind = m_HandleToStrMap.find(handle); - if (theFind == m_HandleToStrMap.end()) { - const char8_t *newStr = FindStrByHandleData(handle); - if (!newStr) - return CRegisteredString(); - theFind = m_HandleToStrMap.insert(eastl::make_pair(handle, newStr)).first; - } - return CRegisteredString::ISwearThisHasBeenRegistered(theFind->second); - } - - void Save(SWriteBuffer &ioBuffer) const - { - // Buffer should be aligned before we get to it. - QT3DS_ASSERT(ioBuffer.size() % 4 == 0); - - QT3DSU32 numStrs = Size(); - size_t bufferBegin = ioBuffer.size(); - SStringFileHeader theHeader; - ioBuffer.write(theHeader); - QT3DSU32 startOffset = ioBuffer.size(); - - eastl::vector> hashToStringIndex; - eastl::vector> handleToStringIndex; - hashToStringIndex.reserve(numStrs); - handleToStringIndex.reserve(numStrs); - WriteStringBlockData(m_DataBlock.begin(), m_DataBlock.end(), ioBuffer, hashToStringIndex, - handleToStringIndex); - WriteStringBlockData(m_AppendedStrings.data(), - m_AppendedStrings.data() + m_AppendedStrings.size(), ioBuffer, - hashToStringIndex, handleToStringIndex); - ioBuffer.align(4); - - QT3DSU32 fixedOffset = ioBuffer.size() - startOffset; - WriteStringBlock(m_DataBlock.begin(), m_DataBlock.end(), ioBuffer); - WriteStringBlock(m_AppendedStrings.data(), - m_AppendedStrings.data() + m_AppendedStrings.size(), ioBuffer); - - // sort by hash code so we can do binary lookups later. - eastl::sort(hashToStringIndex.begin(), hashToStringIndex.end(), SHashPairComparator()); - ioBuffer.write(hashToStringIndex.data(), (QT3DSU32)hashToStringIndex.size()); - - eastl::sort(handleToStringIndex.begin(), handleToStringIndex.end(), - SHandlePairComparator()); - ioBuffer.write(handleToStringIndex.data(), (QT3DSU32)handleToStringIndex.size()); - - SStringFileHeader *fixedOffsetPtr = - reinterpret_cast(ioBuffer.begin() + bufferBegin); - *fixedOffsetPtr = SStringFileHeader(numStrs, m_NextHandleValue, fixedOffset); - } - - void Load(NVDataRef inMemory) - { - QT3DS_ASSERT(m_AppendedStrings.empty()); - m_Allocator.m_PreAllocatedBlock = inMemory; - m_Allocator.m_OwnsMemory = false; - SDataReader theReader(inMemory.begin(), inMemory.end()); - SStringFileHeader theHeader = theReader.LoadRef(); - QT3DSU32 numStrs = theHeader.m_NumStrings; - m_NextHandleValue = theHeader.m_NextHandleValue; - QT3DSU32 fixedOffset = theHeader.m_FixedBufferOffset; - theReader.m_CurrentPtr += fixedOffset; - m_DataBlock = NVConstDataRef( - reinterpret_cast(theReader.m_CurrentPtr), numStrs); - theReader.m_CurrentPtr += sizeof(SStringFileData) * numStrs; - - m_HashDataBlockOffset = NVConstDataRef>( - reinterpret_cast *>(theReader.m_CurrentPtr), numStrs); - theReader.m_CurrentPtr += sizeof(eastl::pair) * numStrs; - - m_HandleDataBlockOffset = NVConstDataRef>( - reinterpret_cast *>(theReader.m_CurrentPtr), numStrs); - - for (QT3DSU32 idx = 0, end = m_DataBlock.size(); idx < end; ++idx) { - SStringFileData &theData = const_cast(m_DataBlock[idx]); - theData.m_Str = reinterpret_cast(inMemory.mData + theData.m_StartOffset); - } - } - -protected: - // When we load from a file, we do not put every string into the hash because building - // hashtables takes - // time. We only put them into the hash on demand; this avoids building a giant hashtable upon - // load. - // and since in general we do not need to lookup all hash values again it avoids building the - // hashtable - // in general. - SCharAndHandle FindStrByHash(SCharAndHash hashCode) const - { - const eastl::pair *iter = - eastl::lower_bound(m_HashDataBlockOffset.begin(), m_HashDataBlockOffset.end(), - eastl::make_pair(hashCode.m_Hash, (QT3DSU32)0), SHashPairComparator()); - - for (; iter != m_HashDataBlockOffset.end() && iter->first == hashCode.m_Hash; ++iter) { - if (AreEqual(m_DataBlock[iter->second].m_Str, hashCode.m_Data)) - return SCharAndHandle(m_DataBlock[iter->second].m_Str, - m_DataBlock[iter->second].m_Handle); - } - return SCharAndHandle(); - } - - const char8_t *FindStrByHandleData(QT3DSU32 handle) const - { - const eastl::pair *iter = - eastl::lower_bound(m_HandleDataBlockOffset.begin(), m_HandleDataBlockOffset.end(), - eastl::make_pair(handle, (QT3DSU32)0), SHandlePairComparator()); - - if (iter != m_HandleDataBlockOffset.end() && iter->first == handle - && m_DataBlock[iter->second].m_Handle == handle) - return m_DataBlock[iter->second].m_Str; - return NULL; - } - - void WriteStringBlockData(const SStringFileData *begin, const SStringFileData *end, - SWriteBuffer &ioBuffer, - eastl::vector> &ioHashToStringIndex, - eastl::vector> &ioHandleToStringIndex) const - { - for (const SStringFileData *iter = begin; iter != end; ++iter) { - size_t idx = ioHashToStringIndex.size(); - SCharAndHash theHash(iter->m_Str); - ioHashToStringIndex.push_back(eastl::make_pair(theHash.m_Hash, (QT3DSU32)idx)); - ioHandleToStringIndex.push_back(eastl::make_pair(iter->m_Handle, (QT3DSU32)idx)); - ioBuffer.write(iter->m_Str, iter->m_StrLen); - } - } - - void WriteStringBlock(const SStringFileData *begin, const SStringFileData *end, - SWriteBuffer &ioBuffer) const - { - for (const SStringFileData *iter = begin; iter != end; ++iter) - ioBuffer.write(*iter); - } - - SCharAndHandle Append(SCharAndHash inStrHash) - { - if (isTrivial(inStrHash.m_Data)) - return SCharAndHandle(); - - const char8_t *inStr(inStrHash.m_Data); - QT3DSU32 len = (QT3DSU32)strlen(inStr) + 1; - char8_t *newStr = (char8_t *)m_Allocator.allocate(len, "StringData", __FILE__, __LINE__); - memCopy(newStr, inStr, len); - - // We write the number of strings to the file just after the header. - QT3DSU32 theOffset = sizeof(SStringFileHeader); - if (Size()) - theOffset = Back().EndOffset(); - - QT3DSU32 handleValue = m_NextHandleValue; - ++m_NextHandleValue; - m_AppendedStrings.push_back(SStringFileData(len, theOffset, handleValue, newStr)); - - // Only add to the str map if necessary because building it could be expensive. - if (m_StrRemapMap.empty() == false) - m_StrRemapMap.insert(eastl::make_pair(newStr, theOffset)); - - return SCharAndHandle(newStr, handleValue); - } - // precondition is that size != 0 - const SStringFileData &Back() const - { - QT3DS_ASSERT(Size()); - - if (m_AppendedStrings.size()) { - return m_AppendedStrings.back(); - } else { - return m_DataBlock[m_DataBlock.size() - 1]; - } - } - - QT3DSU32 Size() const { return static_cast(m_AppendedStrings.size() + m_DataBlock.size()); } -}; - -struct SStringTableMutexScope -{ - Mutex *m_Mutex; - SStringTableMutexScope(Mutex *inM) - : m_Mutex(inM) - { - if (m_Mutex) - m_Mutex->lock(); - } - ~SStringTableMutexScope() - { - if (m_Mutex) - m_Mutex->unlock(); - } -}; - -#define STRING_TABLE_MULTITHREADED_METHOD SStringTableMutexScope __locker(m_MultithreadMutex) - -class StringTable : public IStringTable -{ - typedef nvhash_map TMapType; - typedef nvhash_map TNarrowToWideMapType; - SStringFileDataList m_FileData; - NVAllocatorCallback &m_Allocator; - TNarrowToWideMapType m_StrWideMap; - volatile QT3DSI32 mRefCount; // fnd's naming convention - eastl::basic_string m_ConvertBuffer; - TWideStr m_WideConvertBuffer; - Mutex m_MultithreadMutexBacker; - Mutex *m_MultithreadMutex; - // Data that will be written out to the file. - -public: - StringTable(NVAllocatorCallback &alloc) - : m_FileData(alloc) - , m_Allocator(m_FileData.m_Allocator) - , m_StrWideMap(alloc, "StringTable::m_StrWideMap") - , mRefCount(0) - , m_ConvertBuffer(ForwardingAllocator(alloc, "StringTable::m_ConvertBuffer")) - , m_WideConvertBuffer(ForwardingAllocator(alloc, "StringTable::m_WideConvertBuffer")) - , m_MultithreadMutexBacker(alloc) - , m_MultithreadMutex(NULL) - { - } - - virtual ~StringTable() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_FileData.m_Allocator.m_Allocator) - - void EnableMultithreadedAccess() override { m_MultithreadMutex = &m_MultithreadMutexBacker; } - - void DisableMultithreadedAccess() override { m_MultithreadMutex = NULL; } - - CRegisteredString RegisterStr(Qt3DSBCharPtr str) override - { - STRING_TABLE_MULTITHREADED_METHOD; - if (isTrivial(str)) - return CRegisteredString(); - return m_FileData.FindStr(str); - } - - // utf-16->utf-8 - CRegisteredString RegisterStr(const char16_t *str) override - { - STRING_TABLE_MULTITHREADED_METHOD; - qt3ds::foundation::ConvertUTF(str, 0, m_ConvertBuffer); - return RegisterStr(m_ConvertBuffer.c_str()); - } - // utf-32->utf-8 - CRegisteredString RegisterStr(const char32_t *str) override - { - STRING_TABLE_MULTITHREADED_METHOD; - qt3ds::foundation::ConvertUTF(str, 0, m_ConvertBuffer); - return RegisterStr(m_ConvertBuffer.c_str()); - } - - CRegisteredString RegisterStr(const wchar_t *str) override - { - STRING_TABLE_MULTITHREADED_METHOD; - if (isTrivialWide(str)) - return CRegisteredString(); - qt3ds::foundation::ConvertUTF( - reinterpret_cast(str), 0, - m_ConvertBuffer); - return RegisterStr(m_ConvertBuffer.c_str()); - } - - CStringHandle GetHandle(Qt3DSBCharPtr str) override - { - STRING_TABLE_MULTITHREADED_METHOD; - return m_FileData.FindStrHandle(str); - } - - CRegisteredString HandleToStr(QT3DSU32 strHandle) override - { - STRING_TABLE_MULTITHREADED_METHOD; - return m_FileData.FindStrByHandle(strHandle); - } - - const wchar_t *GetWideStr(CRegisteredString theStr) - { - STRING_TABLE_MULTITHREADED_METHOD; - eastl::pair pair_iter = m_StrWideMap.insert( - eastl::make_pair(theStr, TWideStr(ForwardingAllocator(m_Allocator, "WideString")))); - if (pair_iter.second) - qt3ds::foundation::ConvertUTF(theStr.c_str(), 0, pair_iter.first->second); - return reinterpret_cast(pair_iter.first->second.c_str()); - } - - const wchar_t *GetWideStr(Qt3DSBCharPtr src) override - { - STRING_TABLE_MULTITHREADED_METHOD; - if (isTrivial(src)) - return L""; - return GetWideStr(RegisterStr(src)); - } - - const wchar_t *GetWideStr(const wchar_t *str) override - { - STRING_TABLE_MULTITHREADED_METHOD; - if (isTrivialWide(str)) - return L""; - qt3ds::foundation::ConvertUTF( - reinterpret_cast(str), 0, - m_ConvertBuffer); - return GetWideStr(RegisterStr(m_ConvertBuffer.c_str())); - } - - const SStrRemapMap &GetRemapMap() override { return m_FileData.GetRemapMap(); } - - NVAllocatorCallback &GetAllocator() override { return m_FileData.m_Allocator.m_Allocator; } - - // Save to a block of memory. It is up the callers to deallocate using allocator - // from GetAllocator(). Returns a remap map that takes existing strings and changes their - // address such that they are offsets into the block of memory where this object - // started saving. Returns a map that converts registered strings into offsets of the - // written buffer. - void Save(SWriteBuffer &ioBuffer) const override - { - STRING_TABLE_MULTITHREADED_METHOD; - m_FileData.Save(ioBuffer); - } - - // Load all the strings from inMemory. inMemory is not freed by this object - // Finally, you will need to take inMemory and call remap on all strings - // from offsets back into their correct address into inMemory. - void Load(qt3ds::foundation::NVDataRef inMemory) override - { - STRING_TABLE_MULTITHREADED_METHOD; - m_FileData.Load(inMemory); - } -}; -} - -const char16_t *char16EmptyStr = g_char16EmptyStr; -const char32_t *char32EmptyStr = g_char32EmptyStr; - -IStringTable &IStringTable::CreateStringTable(NVAllocatorCallback &alloc) -{ - return *QT3DS_NEW(alloc, StringTable)(alloc); -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/TrackingAllocator.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/TrackingAllocator.cpp deleted file mode 100644 index 242b0ac0..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/TrackingAllocator.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/TrackingAllocator.h" - -namespace qt3ds { -namespace foundation { - -CAllocator::~CAllocator() -{ - QT3DS_ASSERT(mAllocations.size() == 0); - MemInfo info; - for (PtrToInfoMap::iterator iter = mAllocations.begin(), end = mAllocations.end(); - iter != end; ++iter) { - info = iter->second; - qCCritical(INTERNAL_ERROR, "!!Outstanding allocation of %lu bytes from %s::%d, %s", - info.size, info.file, info.line, info.name ? info.name : ""); - } - QT3DS_UNUSED(info); -} - -} -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/XML.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/XML.cpp deleted file mode 100644 index 34840103..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/XML.cpp +++ /dev/null @@ -1,1008 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/XML.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "foundation/IOStreams.h" -#include "foundation/StringConversionImpl.h" -#include "foundation/StrConvertUTF.h" -#include "foundation/StringTable.h" -#include "foundation/Utils.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/hash_map.h" -#include "utf8.h" - -#ifdef QT3DS_VC -#include //output debug string -#endif - -#include - -using namespace qt3ds; -using namespace qt3ds::foundation; -using namespace qt3ds::intrinsics; - -typedef char XML_Char; - -namespace { - -const QT3DSU16 g_BOMMarker = (QT3DSU16)0xFEFF; - -// Some DOM parsing operations are destructive. If you need -// them to not be destructive, then we need to modify -// the reader. Specifically parsing lists of floats, due -// to a bug in strtod, is destructive. -struct SDOMReader : public IDOMReader -{ - SReaderScope m_TopElement; - eastl::vector m_ScopeStack; - NVScopedRefCounted m_Factory; - volatile QT3DSI32 mRefCount; - - SDOMReader(NVAllocatorCallback &inAlloc, SDOMElement &te, NVScopedRefCounted s, - NVScopedRefCounted inFactory) - : IDOMReader(inAlloc, s) - , m_TopElement(&te) - , m_Factory(inFactory) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Factory->GetAllocator()) - - SDOMElement *Current() const { return m_TopElement.m_Element; } - - void PushScope() override { m_ScopeStack.push_back(SReaderScope(m_TopElement)); } - - void PopScope() override - { - if (m_ScopeStack.size()) { - m_TopElement = m_ScopeStack.back(); - m_ScopeStack.pop_back(); - } else - m_TopElement = SReaderScope(); - } - - SReaderScope GetScope() override { return m_TopElement; } - - void SetScope(SReaderScope inScope) override { m_TopElement = inScope; } - - SDOMElement *GetElement() const override { return m_TopElement.m_Element; } - - Option RegisterNS(TXMLCharPtr ns) - { - if (ns) { - return m_StringTable->RegisterStr(ns); - } - return Empty(); - } - - bool UnregisteredAtt(TXMLCharPtr name, TXMLCharPtr &outValue, TXMLCharPtr ns = NULL) override - { - outValue = ""; - SDOMElement *current(Current()); - if (current) { - return current->AttValue(m_StringTable->RegisterStr(name), RegisterNS(ns), outValue); - } else { - QT3DS_ASSERT(false); - } - return false; - } - - bool Att(TXMLCharPtr name, CRegisteredString &outValue, TXMLCharPtr ns = NULL) override - { - const char8_t *unregValue = NULL; - if (UnregisteredAtt(name, unregValue, ns)) { - outValue = m_StringTable->RegisterStr(unregValue); - return true; - } - return false; - } - - QT3DSU32 CountChildren(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) override - { - SDOMElement *elem = Current(); - if (elem == NULL) { - QT3DS_ASSERT(false); - return 0; - } - return elem->GetNumChildren(m_StringTable->RegisterStr(childName), RegisterNS(ns)); - } - - SDOMAttribute *CurrentAtt() - { - if (m_TopElement.m_Attribute) - return m_TopElement.m_Attribute; - return NULL; - } - - SDOMAttribute *GetFirstAttribute() override - { - if (m_TopElement.m_Element) - m_TopElement.m_Attribute = m_TopElement.m_Element->m_Attributes.m_Head; - return m_TopElement.m_Attribute; - } - - SDOMAttribute *GetNextAttribute() override - { - if (m_TopElement.m_Attribute) - m_TopElement.m_Attribute = m_TopElement.m_Attribute->m_NextAttribute; - return CurrentAtt(); - } - - bool MoveToFirstChild(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) override - { - SDOMElement *elem = Current(); - if (elem == NULL) { - QT3DS_ASSERT(false); - return false; - } - SDOMElement *child = elem->FindChild(m_StringTable->RegisterStr(childName), RegisterNS(ns)); - if (child != NULL) { - m_TopElement = child; - return true; - } - return false; - } - - bool MoveToNextSibling(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) override - { - SDOMElement *elem = Current(); - if (elem == NULL) { - QT3DS_ASSERT(false); - return false; - } - SDOMElement *nextSibling = - elem->FindSibling(m_StringTable->RegisterStr(childName), RegisterNS(ns)); - if (nextSibling) { - m_TopElement = nextSibling; - return true; - } - return false; - } - // Leave element means go to its parent. - void Leave() override - { - QT3DS_ASSERT(m_TopElement.m_Element); - if (m_TopElement.m_Element) - m_TopElement = m_TopElement.m_Element->m_Parent; - } - - bool Value(TXMLCharPtr &outValue) override - { - SDOMElement *current(Current()); - if (!current) { - QT3DS_ASSERT(false); - return false; - } - outValue = current->m_Value; - return true; - } - - SDOMElement *GetTopElement() override - { - SDOMElement *current(Current()); - while (current && current->m_Parent) - current = current->m_Parent; - return current; - } - - virtual NVScopedRefCounted GetFactory() { return m_Factory; } -}; - -struct SDOMWriter : public IDOMWriter, public SDOMReader -{ - NVScopedRefCounted m_FactoryPtr; - IDOMFactory &m_Factory; - - SDOMWriter(NVScopedRefCounted inDOMFactory, - NVScopedRefCounted inStringTable, SDOMElement &inTopElem) - : SDOMReader(inDOMFactory->GetAllocator(), inTopElem, inStringTable, *inDOMFactory) - , m_FactoryPtr(inDOMFactory) - , m_Factory(*inDOMFactory) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Factory.GetAllocator()) - - void Begin(TXMLCharPtr inElemName, TXMLCharPtr inNamespace = NULL, int inLine = 0) override - { - if (!m_TopElement.m_Element) { - QT3DS_ASSERT(false); - return; - } - SDOMElement *current(Current()); - SDOMElement *newElement(m_Factory.NextElement(m_StringTable->RegisterStr(inElemName), - m_StringTable->RegisterStr(inNamespace), - inLine)); - current->AppendChild(*newElement); - m_TopElement = newElement; - } - - void Att(TXMLCharPtr name, TXMLCharPtr value, TXMLCharPtr ns, int inLine) override - { - if (!m_TopElement.m_Element) { - QT3DS_ASSERT(false); - return; - } - m_TopElement.m_Element->SetAttributeValue(m_StringTable->RegisterStr(name), RegisterNS(ns), - value, m_Factory, inLine); - } - - void Value(TXMLCharPtr value) override - { - if (!m_TopElement.m_Element) { - QT3DS_ASSERT(false); - return; - } - if (value == NULL) - value = ""; - size_t len = strlen(value); - m_Factory.AppendStrBuf(value, (QT3DSU32)len); - m_TopElement.m_Element->m_Value = m_Factory.FinalizeStrBuf(); - } - - void End() override - { - if (!m_TopElement.m_Element) { - QT3DS_ASSERT(false); - return; - } - Leave(); - } - void RemoveCurrent() override - { - SDOMElement *current(Current()); - if (!current) { - QT3DS_ASSERT(false); - return; - } - if (current->m_Parent) { - m_TopElement = current->m_Parent; - m_TopElement.m_Element->RemoveChild(*current); - } - } - void RemoveAttribute(TXMLCharPtr inItem, TXMLCharPtr inNamespace) override - { - SDOMElement *current(Current()); - if (!current) { - QT3DS_ASSERT(false); - return; - } - current->RemoveAttribute(m_StringTable->RegisterStr(inItem), RegisterNS(inNamespace)); - } - - void MoveBefore(TXMLCharPtr inItem, TXMLCharPtr inSibling, TXMLCharPtr inNs = NULL) override - { - SDOMElement *current(Current()); - if (!current) { - QT3DS_ASSERT(false); - return; - } - - SDOMElement *theItem = - current->FindChild(m_StringTable->RegisterStr(inItem), RegisterNS(inNs)); - SDOMElement *theSibling = - current->FindChild(m_StringTable->RegisterStr(inSibling), RegisterNS(inNs)); - QT3DS_ASSERT(theItem && theSibling); - if (theItem && theSibling) - current->PrependChild(*theItem, theSibling); - } - - // If current has no parent, then we are at the top - // of the tree and we should return 0. Or if there is no - // current. - // If there is one parent, we should return 1. - QT3DSU32 GetTabs() override - { - QT3DSU32 retval = 0; - SDOMElement *current(Current()); - do { - if (current) - current = current->m_Parent; - if (current) - ++retval; - } while (current); - return retval; - } - - SDOMElement *GetTopElement() override { return SDOMReader::GetTopElement(); } - - NVScopedRefCounted GetFactory() override { return m_FactoryPtr; } - - NVAllocatorCallback &GetAllocator() override { return m_Factory.GetAllocator(); } -}; - -struct SimpleXmlWriter -{ - - struct SNameNS - { - TXMLCharPtr name; - TXMLCharPtr ns; - SNameNS(TXMLCharPtr _name = NULL, TXMLCharPtr _ns = NULL) - : name(_name) - , ns(_ns) - { - } - }; - IOutStream &m_Stream; - eastl::vector> m_OpenElements; - bool m_ElementOpen; - char8_t m_PrintBuf[256]; - QT3DSU32 m_Tabs; - eastl::basic_string m_Buffer; - - SimpleXmlWriter(NVAllocatorCallback &inAlloc, IOutStream &stream, QT3DSU32 inTabs = 0) - : m_Stream(stream) - , m_ElementOpen(false) - , m_Tabs(inTabs) - , m_Buffer(ForwardingAllocator(inAlloc, "SimpleXMLWriter::m_Buffer")) - { - } - - void Write(const SNameNS &data) - { - if (data.ns && *data.ns) { - Write(data.ns); - Write(':'); - } - Write(data.name); - } - - void Write(const char8_t *data, QT3DSU32 inLen = 0) - { - if (!isTrivial(data)) { - if (inLen == 0) - inLen = StrLen(data); - m_Stream.Write(data, inLen); - } - } - void BeginWrite() { m_Buffer.clear(); } - void WriteTemp(char8_t data) { m_Buffer.append(1, data); } - void WriteTemp(const char8_t *data) { m_Buffer.append(data); } - void EndWrite() { Write(reinterpret_cast(m_Buffer.c_str()), m_Buffer.size()); } - void Write(char8_t data) { m_Stream.Write(data); } - void Tabs() - { - QT3DS_FOREACH(idx, (m_OpenElements.size() + m_Tabs)) - Write('\t'); - } - void Close(bool newline) - { - if (m_ElementOpen) { - Write(">"); - if (newline) - Write('\n'); - } - m_ElementOpen = false; - } - void Begin(TXMLCharPtr name, TXMLCharPtr ns) - { - Close(true); - Tabs(); - Write('<'); - SNameNS theName(name, ns); - Write(theName); - m_OpenElements.push_back(eastl::pair(theName, false)); - m_ElementOpen = true; - } - TXMLCharPtr ToStr(char8_t val) - { - m_PrintBuf[0] = val; - m_PrintBuf[1] = 0; - return m_PrintBuf; - } - template - TXMLCharPtr ToStr(TDataType val) - { - StringConversion().ToStr(val, NVDataRef(m_PrintBuf, 256)); - return m_PrintBuf; - } - void Att(TXMLCharPtr name, TXMLCharPtr ns, TXMLCharPtr value) - { - QT3DS_ASSERT(m_ElementOpen); - Write(' '); - Write(SNameNS(name, ns)); - - Write("=\""); - size_t valueLen = strlen(nonNull(value)); - TXMLCharPtr start = value; - TXMLCharPtr end = value + valueLen; - TXMLCharPtr last = start; - uint32_t item = 0; - // Write out the data escaping unicode values where necessary - // I am using utf8::internal because it returns an error code and does not through - // exceptions; we don't always know the system we are running on will support or handle - // exceptions gracefully. - for (utf8::internal::utf_error err_code = utf8::internal::validate_next(start, end, item); - last != end && err_code == utf8::internal::UTF8_OK; - err_code = utf8::internal::validate_next(start, end, item)) { - switch (item) { - case '\r': - break; - case '\n': - Write(" "); - break; - case '\t': - Write(" "); - break; - case '<': - Write("<"); - break; - case '>': - Write(">"); - break; - case '"': - Write("""); - break; - case '&': - Write("&"); - break; - default: - m_Stream.Write(NVConstDataRef((const QT3DSU8 *)last, (QT3DSU32)(start - last))); - break; - } - last = start; - } - Write("\""); - } - template - void Att(TXMLCharPtr name, TXMLCharPtr ns, TData value) - { - Att(name, ns, ToStr(value)); - } - - void Value(TXMLCharPtr value) - { - if (!isTrivial(value)) { - Close(false); - size_t valueLen = strlen(nonNull(value)); - TXMLCharPtr start = value; - TXMLCharPtr end = value + valueLen; - TXMLCharPtr last = start; - uint32_t item = 0; - // Write out the data escaping unicode values where necessary - for (utf8::internal::utf_error err_code = - utf8::internal::validate_next(start, end, item); - last != end && err_code == utf8::internal::UTF8_OK; - err_code = utf8::internal::validate_next(start, end, item)) { - switch (item) { - case '<': - Write("<"); - break; - case '>': - Write(">"); - break; - case '&': - Write("&"); - break; - default: - m_Stream.Write(NVConstDataRef((const QT3DSU8 *)last, (QT3DSU32)(start - last))); - break; - } - last = start; - } - m_OpenElements.back().second = true; - } - } - void ChildValue(TXMLCharPtr name, TXMLCharPtr ns, TXMLCharPtr value) - { - Begin(name, ns); - Value(value); - End(); - } - void End(bool newlineAfterClose = true) - { - QT3DS_ASSERT(m_OpenElements.size()); - eastl::pair topElem = m_OpenElements.back(); - m_OpenElements.pop_back(); - if (m_ElementOpen) - Write("/>"); - else { - if (topElem.second == false) - Tabs(); - Write(""); - } - m_ElementOpen = false; - if (newlineAfterClose == true) - Write('\n'); - } -}; - -struct DOMParser -{ - IDOMFactory &m_Factory; - SDOMElement *m_TopElement; - SDOMElement *m_FirstElement; - char8_t m_nsSeparator; - typedef eastl::basic_string TStrType; - TStrType m_NSBuffer; - TStrType m_NameBuffer; - CRegisteredString m_RegName; - CRegisteredString m_RegNS; - SNamespacePairNode *m_FirstPair; - SNamespacePairNode *m_LastPair; - QXmlStreamReader *m_XMLParser; - - DOMParser(IDOMFactory &factory, QXmlStreamReader &parser, char8_t nsSeparator) - : m_Factory(factory) - , m_FirstElement(NULL) - , m_nsSeparator(nsSeparator) - , m_NSBuffer(ForwardingAllocator(factory.GetAllocator(), "DOMParser::m_NSBuffer")) - , m_NameBuffer(ForwardingAllocator(factory.GetAllocator(), "DOMParser::m_NameBuffer")) - , m_FirstPair(NULL) - , m_LastPair(NULL) - , m_XMLParser(&parser) - { - } - - void ParseName(const XML_Char *name) - { - m_NSBuffer.assign(name); - eastl::string::size_type pos = m_NSBuffer.find(m_nsSeparator); - if (pos != TStrType::npos) { - m_NameBuffer.assign(m_NSBuffer.c_str() + pos + 1); - m_NSBuffer.resize(pos); - } else { - m_NameBuffer = m_NSBuffer; - m_NSBuffer.clear(); - // Find the namespace with no abbreviation. - for (SNamespacePairNode *theNode = m_FirstPair; theNode; - theNode = theNode->m_NextNode) { - if (theNode->m_Abbreviation.IsValid() == false) - m_NSBuffer.assign(theNode->m_Namespace.c_str()); - } - } - m_RegName = m_Factory.GetStringTable()->RegisterStr(m_NameBuffer.c_str()); - m_RegNS = m_Factory.GetStringTable()->RegisterStr(m_NSBuffer.c_str()); - } - - struct SimpleXmlErrorHandler : public CXmlErrorHandler - { - void OnXmlError(TXMLCharPtr errorName, int line, int column) override - { - char8_t buffer[1024]; - _snprintf(buffer, 1024, "%s(%d): Xml Error %s on line %d, column %d", __FILE__, - __LINE__, errorName, line, column); -#ifdef QT3DS_VC - OutputDebugStringA(buffer); -#endif - printf("%s\n", buffer); - } - }; - - template - struct SHeaderInStream : public IInStream - { - QT3DSU8 m_Header[THeaderLen]; - IInStream &m_InStream; - QT3DSU32 m_BytesRead; - - SHeaderInStream(IInStream &inStream) - : m_InStream(inStream) - , m_BytesRead(0) - { - } - bool readHeader() - { - QT3DSU32 amountRead = m_InStream.Read(NVDataRef(m_Header, THeaderLen)); - return amountRead == THeaderLen; - } - QT3DSU32 Read(NVDataRef data) override - { - if (data.size() == 0) - return 0; - QT3DSU8 *writePtr(data.begin()); - QT3DSU32 amountToRead(data.size()); - QT3DSU32 amountRead = 0; - if (m_BytesRead < THeaderLen) { - QT3DSU32 headerLeft = NVMin(THeaderLen - m_BytesRead, amountToRead); - memCopy(writePtr, m_Header + m_BytesRead, headerLeft); - writePtr += headerLeft; - amountToRead -= headerLeft; - amountRead += headerLeft; - } - if (amountToRead) - amountRead += m_InStream.Read(NVDataRef(writePtr, amountToRead)); - m_BytesRead += amountRead; - return amountRead; - } - }; - - static eastl::pair - ParseXMLFile(IDOMFactory &factory, IInStream &inStream, CXmlErrorHandler *handler = NULL) - { - SimpleXmlErrorHandler simpleHandler; - if (handler == NULL) - handler = &simpleHandler; - - // look for BOM (Byte-Order-Marker) in the file - // if found, pass in UTF-16 as the format. else - // pass in UTF-8 as the format. - SHeaderInStream theInStream(inStream); - if (theInStream.readHeader() == false) { - QT3DS_ASSERT(false); - return NULL; - } - QT3DSU16 theHeaderData; - memCopy(&theHeaderData, theInStream.m_Header, sizeof(g_BOMMarker)); - - char8_t nsSeparator = '$'; - - if (theHeaderData == g_BOMMarker) - qFatal("UTF-16 files not supported"); - - QXmlStreamReader sreader; - DOMParser domParser(factory, sreader, nsSeparator); - QT3DSU8 dataBuf[2048]; - QT3DSU32 amountRead = 0; - do { - amountRead = theInStream.Read(toDataRef(dataBuf, 2048)); - if (amountRead) { - QByteArray tmp = QByteArray::fromRawData((char*)dataBuf,amountRead); - sreader.addData(tmp); - } - } while (amountRead > 0); - while (!sreader.atEnd()) { - QXmlStreamReader::TokenType token = sreader.readNext(); - if (token == QXmlStreamReader::StartElement) { - domParser.m_Factory.IgnoreStrBuf(); - domParser.ParseName((TXMLCharPtr)sreader.name().toUtf8().data()); - int line = sreader.lineNumber(); - SDOMElement *newElem = - domParser.m_Factory.NextElement(domParser.m_RegName, domParser.m_RegNS, line); - if (domParser.m_FirstElement == NULL) { - domParser.m_FirstElement = newElem; - domParser.m_TopElement = newElem; - } else { - domParser.m_TopElement->AppendChild(*newElem); - domParser.m_TopElement = newElem; - } - const QXmlStreamAttributes& attributes = sreader.attributes(); - for (auto attrib : attributes) { - domParser.ParseName((TXMLCharPtr)attrib.name().toUtf8().data()); - SDOMAttribute *att = - domParser.m_Factory.NextAttribute(domParser.m_RegName, - (TXMLCharPtr)attrib.value() - .toUtf8().data(), - domParser.m_RegNS, line); - newElem->m_Attributes.push_back(*att); - } - } else if (token == QXmlStreamReader::Characters) { - QByteArray text = sreader.text().toUtf8(); - domParser.m_Factory.AppendStrBuf(text.data(), text.length()); - } else if (token == QXmlStreamReader::EndElement) { - domParser.m_TopElement->m_Value = domParser.m_Factory.FinalizeStrBuf(); - domParser.m_TopElement = domParser.m_TopElement->m_Parent; - } - - if (sreader.hasError()) { - TXMLCharPtr error = (TXMLCharPtr)sreader.errorString().toUtf8().data(); - handler->OnXmlError(error, sreader.lineNumber(), sreader.columnNumber()); - return nullptr; - } - - } - return eastl::make_pair(domParser.m_FirstPair, domParser.m_FirstElement); - } -}; - -class SimpleDomFactory : public IDOMFactory -{ - typedef eastl::basic_string TNarrowStr; - NVAllocatorCallback &m_Allocator; - Pool m_ElementPool; - Pool m_AttributePool; - Pool m_NamespaceNodePool; - eastl::vector m_BigStrings; - NVScopedRefCounted m_StringTable; - TNarrowStr m_StringBuilder; - volatile QT3DSI32 mRefCount; - -public: - SimpleDomFactory(NVAllocatorCallback &alloc, NVScopedRefCounted strt) - : m_Allocator(alloc) - , m_StringTable(strt) - , m_StringBuilder(ForwardingAllocator(alloc, "SimpleDomFactory::m_StringBuilder")) - , mRefCount(0) - { - } - - ~SimpleDomFactory() - { - QT3DS_FOREACH(idx, m_BigStrings.size()) - m_Allocator.deallocate(m_BigStrings[idx]); - m_BigStrings.clear(); - } - - NVAllocatorCallback &GetAllocator() override { return m_Allocator; } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Allocator) - - TXMLCharPtr RegisterStr(TXMLCharPtr str) - { - if (str == NULL || *str == 0) - return ""; - return m_StringTable->RegisterStr(str); - } - - virtual void Release() { delete this; } - void AppendStrBuf(TXMLCharPtr str, QT3DSU32 len) override - { - if (len && *str) { - m_StringBuilder.append(str, str + len); - } - } - - // Null terminate what is there and return the buffer. - // This pointer needs to be persistent. - TXMLCharPtr FinalizeStrBuf() override - { - if (m_StringBuilder.size() == 0) - return ""; - QT3DSU32 len = m_StringBuilder.size() + 1; - QT3DSU32 numBytes = len * sizeof(char8_t); - char8_t *newMem = - (char8_t *)m_Allocator.allocate(numBytes, "DOMFactory::ValueStr", __FILE__, __LINE__); - memCopy(newMem, m_StringBuilder.c_str(), numBytes); - m_BigStrings.push_back(newMem); - m_StringBuilder.clear(); - return newMem; - } - void IgnoreStrBuf() override { m_StringBuilder.clear(); } - - SDOMAttribute *NextAttribute(CRegisteredString name, TXMLCharPtr val, - CRegisteredString ns, int inLine) override - { - TXMLCharPtr v(RegisterValue(val)); - SDOMAttribute *att = (SDOMAttribute *)m_AttributePool.allocate(__FILE__, __LINE__); - new (att) SDOMAttribute(name, ns, v, inLine); - return att; - } - - SDOMElement *NextElement(CRegisteredString name, CRegisteredString ns, int inLine) override - { - IgnoreStrBuf(); - SDOMElement *elem = (SDOMElement *)(m_ElementPool.allocate(__FILE__, __LINE__)); - new (elem) SDOMElement(name, ns, inLine); - return elem; - } - - SNamespacePairNode *NextNSPairNode(CRegisteredString ns, CRegisteredString abbr) override - { - return m_NamespaceNodePool.construct(SNamespacePair(ns, abbr), __FILE__, __LINE__); - } - - NVScopedRefCounted GetStringTable() override { return m_StringTable; } -}; -} - -NVScopedRefCounted -IDOMReader::CreateDOMReader(NVAllocatorCallback &inAlloc, SDOMElement &inRootElement, - NVScopedRefCounted inStringTable, - NVScopedRefCounted inFactory) -{ - return QT3DS_NEW(inAlloc, SDOMReader)(inAlloc, inRootElement, inStringTable, inFactory); -} - -eastl::pair, NVScopedRefCounted> -IDOMWriter::CreateDOMWriter(NVScopedRefCounted inFactory, SDOMElement &inRootElement, - NVScopedRefCounted inStringTable) -{ - NVScopedRefCounted writer( - QT3DS_NEW(inFactory->GetAllocator(), SDOMWriter)(inFactory, inStringTable, inRootElement)); - return eastl::make_pair(writer.mPtr, writer.mPtr); -} - -TXMLCharPtr IDOMFactory::RegisterValue(TXMLCharPtr inValue) -{ - if (isTrivial(inValue)) - return ""; - IgnoreStrBuf(); - AppendStrBuf(inValue, (QT3DSU32)strlen(inValue)); - return FinalizeStrBuf(); -} - -NVScopedRefCounted -IDOMFactory::CreateDOMFactory(NVAllocatorCallback &inAlloc, - NVScopedRefCounted inStrTable) -{ - return QT3DS_NEW(inAlloc, SimpleDomFactory)(inAlloc, inStrTable); -} - -void CDOMSerializer::WriteXMLHeader(IOutStream &inStream) -{ - const char8_t *header = "\n"; - QT3DSU32 len = (QT3DSU32)strlen(header); - inStream.Write(header, len); -} - -// Lexigraphically sort the attributes. -struct SAttributeComparator -{ - bool operator()(const SDOMAttribute *lhs, const SDOMAttribute *rhs) - { - int nsCmp = strcmp(lhs->m_Namespace, rhs->m_Namespace); - if (nsCmp) - return nsCmp < 0; - - return strcmp(lhs->m_Name, rhs->m_Name) < 0; - } -}; - -typedef eastl::vector TAttVector; -typedef eastl::hash_map, - eastl::equal_to, ForwardingAllocator> - TNSMap; - -CRegisteredString GetOrCreateNamespaceAbbr(NVAllocatorCallback &inAlloc, CRegisteredString theNs, - TNSMap &inNamespace, TNSMap &inReverseNamespaces, - IStringTable &inStrTable, bool &outCreated) -{ - CRegisteredString abbr; - if (theNs.IsValid()) { - TNSMap::iterator nsIter = inNamespace.find(theNs); - if (nsIter != inNamespace.end()) { - abbr = nsIter->second; - outCreated = false; - } else { - eastl::basic_string theStr( - ForwardingAllocator(inAlloc, "nsBuilderString")); - theStr.assign("a"); - eastl::basic_string theNsStr( - ForwardingAllocator(inAlloc, "nsBuilderString")); - CRegisteredString theNS = inStrTable.RegisterStr(theStr.c_str()); - while (inReverseNamespaces.find(theNS) != inReverseNamespaces.end()) { - for (int idx = 0; - idx < 26 && inReverseNamespaces.find(theNS) == inReverseNamespaces.end(); - ++idx) { - theNsStr = theStr; - theNsStr.append(1, (char8_t)('a' + idx)); - theNS = inStrTable.RegisterStr(theNsStr.c_str()); - } - theStr.append(1, 'a'); - } - inNamespace.insert(eastl::make_pair(theNs, theNS)); - abbr = theNS; - outCreated = true; - } - } - return abbr; -} - -// Write an element with attributes sorted by name so a file diff is effective. -void WriteElement(NVAllocatorCallback &inAlloc, SDOMElement &inElement, SimpleXmlWriter &inWriter, - TAttVector &inAttSorter, TNSMap &inNamespace, TNSMap &inReverseNamespaces, - IStringTable &inStrTable, bool inTrimEmptyElems, bool inWriteXMLNS) -{ - inAttSorter.clear(); - - // We decided that we don't want attribute sorting; the code that adds attributes needs - // to be consistent. - // This element doesn't add anything to the system in this case. - if (inTrimEmptyElems && inElement.m_Attributes.empty() && inElement.m_Children.empty() - && isTrivial(inElement.m_Value)) - return; - - for (TAttributeList::iterator iter = inElement.m_Attributes.begin(), - end = inElement.m_Attributes.end(); - iter != end; ++iter) - inAttSorter.push_back(&(*iter)); - - // Find the namespace for the element - bool createdAbbr = false; - CRegisteredString abbr = GetOrCreateNamespaceAbbr(inAlloc, inElement.m_Namespace, inNamespace, - inReverseNamespaces, inStrTable, createdAbbr); - - inWriter.Begin(inElement.m_Name, abbr); - eastl::basic_string theStr( - ForwardingAllocator(inAlloc, "nsBuilderString")); - if (inWriteXMLNS) { - for (TNSMap::iterator iter = inNamespace.begin(), end = inNamespace.end(); iter != end; - ++iter) { - theStr.assign("xmlns"); - if (iter->second.IsValid()) { - theStr.append(1, ':'); - theStr.append(iter->second.c_str()); - } - inWriter.Att(theStr.c_str(), NULL, iter->first.c_str()); - } - } else if (createdAbbr) { - theStr.assign("xmlns:"); - theStr.append(abbr.c_str()); - inWriter.Att(theStr.c_str(), NULL, inElement.m_Namespace.c_str()); - } - - const char8_t *theLastAttName = 0; - const char8_t *theLastAttNamespace = 0; - for (QT3DSU32 idx = 0, end = inAttSorter.size(); idx < end; ++idx) { - SDOMAttribute *theAtt(inAttSorter[idx]); - if (theAtt->m_Name != theLastAttName || theAtt->m_Namespace != theLastAttNamespace) { - abbr = GetOrCreateNamespaceAbbr(inAlloc, theAtt->m_Namespace, inNamespace, - inReverseNamespaces, inStrTable, createdAbbr); - if (createdAbbr) { - theStr.assign("xmlns:"); - theStr.append(abbr.c_str()); - inWriter.Att(theStr.c_str(), NULL, inElement.m_Namespace.c_str()); - } - - inWriter.Att(theAtt->m_Name, abbr, theAtt->m_Value); - } else { - QT3DS_ASSERT(false); - } - theLastAttName = theAtt->m_Name; - theLastAttNamespace = theAtt->m_Namespace; - } - // Elements can either have children or values but not both at this point. - if (inElement.m_Children.empty() == false) { - for (SDOMElement::TElementChildList::iterator iter = inElement.m_Children.begin(), - end = inElement.m_Children.end(); - iter != end; ++iter) - WriteElement(inAlloc, *iter, inWriter, inAttSorter, inNamespace, inReverseNamespaces, - inStrTable, inTrimEmptyElems, false); - - inWriter.End(); - } else { - if (!isTrivial(inElement.m_Value)) - inWriter.Value(inElement.m_Value); - - inWriter.End(); - } -} - -void CDOMSerializer::Write(NVAllocatorCallback &inAlloc, SDOMElement &inElement, - IOutStream &inStream, IStringTable &inStrTable, - NVConstDataRef inNamespaces, bool inTrimEmptyElements, - QT3DSU32 inTabs, bool inWriteNamespaces) -{ - TAttVector theAttSorter(ForwardingAllocator(inAlloc, "CDOMSerializer::AttributeList")); - TNSMap theNamespaces(ForwardingAllocator(inAlloc, "CDOMSerializer::NamespaceMap")); - TNSMap theReverseNamespaces(ForwardingAllocator(inAlloc, "CDOMSerializer::NamespaceMap")); - for (QT3DSU32 idx = 0, end = inNamespaces.size(); idx < end; ++idx) { - theNamespaces.insert( - eastl::make_pair(inNamespaces[idx].m_Namespace, inNamespaces[idx].m_Abbreviation)); - theReverseNamespaces.insert( - eastl::make_pair(inNamespaces[idx].m_Abbreviation, inNamespaces[idx].m_Namespace)); - } - SimpleXmlWriter writer(inAlloc, inStream, inTabs); - WriteElement(inAlloc, inElement, writer, theAttSorter, theNamespaces, theReverseNamespaces, - inStrTable, inTrimEmptyElements, inWriteNamespaces); -} - -eastl::pair -CDOMSerializer::Read(IDOMFactory &inFactory, IInStream &inStream, CXmlErrorHandler *inErrorHandler) -{ - return DOMParser::ParseXMLFile(inFactory, inStream, inErrorHandler); -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxAtomic.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxAtomic.cpp deleted file mode 100644 index f0045dd9..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxAtomic.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAtomic.h" -#ifdef __QNX__ -#include -#endif -#ifdef __INTEGRITY -#include -#endif - -#define PAUSE() asm("nop") - -namespace qt3ds { -namespace foundation { -#ifdef __QNX__ - QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) - { - atomic_add((volatile unsigned *)val, 1); - return *val; - } - - QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) - { - atomic_sub((volatile unsigned *)val, 1); - return *val; - } -#elif defined (__INTEGRITY) - // TestAndSet and AtomicModify take in volatile Address* leading to overflow error if used - - QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) - { - static QMutex mutex; - QMutexLocker lock(&mutex); - QT3DSI32 ret = *dest; - *dest = (*dest == comp) ? exch : ret; - return ret; - } - - QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) - { - static QMutex mutex; - QMutexLocker lock(&mutex); - return ++(*val); - } - - QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) - { - static QMutex mutex; - QMutexLocker lock(&mutex); - return --(*val); - } -#else - void *atomicCompareExchangePointer(volatile void **dest, void *exch, void *comp) - { - return __sync_val_compare_and_swap((void **)dest, comp, exch); - } - - QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) - { - return __sync_val_compare_and_swap(dest, comp, exch); - } - - QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) { return __sync_add_and_fetch(val, 1); } - - QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) { return __sync_sub_and_fetch(val, 1); } - - QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta) { return __sync_add_and_fetch(val, delta); } - - QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2) - { - QT3DSI32 oldVal, newVal; - - do { - PAUSE(); - oldVal = *val; - - if (val2 > oldVal) - newVal = val2; - else - newVal = oldVal; - - } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); - - return *val; - } - - QT3DSI32 atomicExchange(volatile QT3DSI32 *val, QT3DSI32 val2) - { - QT3DSI32 newVal, oldVal; - - do { - PAUSE(); - oldVal = *val; - newVal = val2; - } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); - - return newVal; - } -#endif -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxFPU.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxFPU.cpp deleted file mode 100644 index c3eae215..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxFPU.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/Qt3DSFPU.h" -#include - -QT3DS_COMPILE_TIME_ASSERT(8 * sizeof(qt3ds::QT3DSU32) >= sizeof(fenv_t)); - -qt3ds::foundation::FPUGuard::FPUGuard() -{ -#ifdef __CYGWIN__ -#pragma message "FPUGuard::FPUGuard() is not implemented" -#else - fegetenv(reinterpret_cast(mControlWords)); - fesetenv(FE_DFL_ENV); -#endif -} - -qt3ds::foundation::FPUGuard::~FPUGuard() -{ -#ifdef __CYGWIN__ -#pragma message "FPUGuard::~FPUGuard() is not implemented" -#else - fesetenv(reinterpret_cast(mControlWords)); -#endif -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxMutex.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxMutex.cpp deleted file mode 100644 index bbc55829..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxMutex.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAtomic.h" - -#include - -namespace qt3ds { -namespace foundation { - - namespace { - pthread_mutex_t *getMutex(MutexImpl *impl) - { - return reinterpret_cast(impl); - } - } - - MutexImpl::MutexImpl() - { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(getMutex(this), &attr); - pthread_mutexattr_destroy(&attr); - } - - MutexImpl::~MutexImpl() { pthread_mutex_destroy(getMutex(this)); } - - bool MutexImpl::lock() { return !pthread_mutex_lock(getMutex(this)); } - - bool MutexImpl::trylock() { return !pthread_mutex_trylock(getMutex(this)); } - - bool MutexImpl::unlock() { return !pthread_mutex_unlock(getMutex(this)); } - - const QT3DSU32 MutexImpl::size = sizeof(pthread_mutex_t); - - class ReadWriteLockImpl - { - public: - ReadWriteLockImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - pthread_mutex_t mutex; - volatile int readerCounter; - }; - - ReadWriteLock::ReadWriteLock(NVAllocatorCallback &alloc) - { - mImpl = QT3DS_NEW(alloc, ReadWriteLockImpl)(alloc); - - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mImpl->mutex, &attr); - pthread_mutexattr_destroy(&attr); - - mImpl->readerCounter = 0; - } - - ReadWriteLock::~ReadWriteLock() - { - pthread_mutex_destroy(&mImpl->mutex); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - void ReadWriteLock::lockReader() - { - pthread_mutex_lock(&mImpl->mutex); - - atomicIncrement(&mImpl->readerCounter); - - pthread_mutex_unlock(&mImpl->mutex); - } - - void ReadWriteLock::lockWriter() - { - pthread_mutex_lock(&mImpl->mutex); - - while (mImpl->readerCounter != 0) - ; - } - - void ReadWriteLock::unlockReader() { atomicDecrement(&mImpl->readerCounter); } - - void ReadWriteLock::unlockWriter() { pthread_mutex_unlock(&mImpl->mutex); } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp deleted file mode 100644 index 90aab79a..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSSemaphore.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSAllocatorCallback.h" - -#include -#include -#include -#include -#include - -namespace qt3ds { -namespace foundation { - - class SemaphoreImpl - { - public: - SemaphoreImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - pthread_mutex_t mutex; - pthread_cond_t cond; - QT3DSU32 count; - QT3DSU32 maxCount; - }; - - struct NVLinuxScopeLock - { - NVLinuxScopeLock(pthread_mutex_t &m) - : mMutex(m) - { - pthread_mutex_lock(&mMutex); - } - - ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } - private: - pthread_mutex_t &mMutex; - }; - - Semaphore::Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount) - { - mImpl = QT3DS_NEW(alloc, SemaphoreImpl)(alloc); - int status = pthread_mutex_init(&mImpl->mutex, 0); - QT3DS_ASSERT(!status); - status = pthread_cond_init(&mImpl->cond, 0); - QT3DS_ASSERT(!status); - mImpl->count = initialCount; - mImpl->maxCount = maxCount; - QT3DS_ASSERT(initialCount <= maxCount); - } - - Semaphore::~Semaphore() - { - pthread_cond_destroy(&mImpl->cond); - pthread_mutex_destroy(&mImpl->mutex); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - bool Semaphore::wait(QT3DSU32 milliseconds) - { - NVLinuxScopeLock lock(mImpl->mutex); - - if (mImpl->count > 0) { - mImpl->count--; - return true; - } - - if (milliseconds == 0) { - return false; - } - - if (milliseconds == QT3DSU32(-1)) { - int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); - QT3DS_ASSERT(!status); - (void)status; - } else { - timespec ts; - timeval tp; - gettimeofday(&tp, NULL); - QT3DSU32 sec = milliseconds / 1000; - QT3DSU32 usec = (milliseconds - 1000 * sec) * 1000; - - // sschirm: taking into account that us might accumulate to a second - // otherwise the pthread_cond_timedwait complains on osx. - usec = tp.tv_usec + usec; - QT3DSU32 div_sec = usec / 1000000; - QT3DSU32 rem_usec = usec - div_sec * 1000000; - - ts.tv_sec = tp.tv_sec + sec + div_sec; - ts.tv_nsec = rem_usec * 1000; - - int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); - QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); - (void)ierr; - return false; - } - - return true; - } - - void Semaphore::post() - { - NVLinuxScopeLock lock(mImpl->mutex); - mImpl->count++; - if (mImpl->count > mImpl->maxCount) - mImpl->count = mImpl->maxCount; - else { - pthread_cond_broadcast(&mImpl->cond); - } - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSync.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSync.cpp deleted file mode 100644 index 52f9d7ab..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxSync.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSAllocatorCallback.h" - -#include -#include -#include -#include -#include - -namespace qt3ds { -namespace foundation { - - class SyncImpl - { - public: - SyncImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - pthread_mutex_t mutex; - pthread_cond_t cond; - volatile bool is_set; - }; - - struct NVLinuxScopeLock - { - NVLinuxScopeLock(pthread_mutex_t &m) - : mMutex(m) - { - pthread_mutex_lock(&mMutex); - } - - ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } - private: - pthread_mutex_t &mMutex; - }; - - Sync::Sync(NVAllocatorCallback &alloc) - { - mImpl = QT3DS_NEW(alloc, SyncImpl)(alloc); - int status = pthread_mutex_init(&mImpl->mutex, 0); - QT3DS_ASSERT(!status); - status = pthread_cond_init(&mImpl->cond, 0); - QT3DS_ASSERT(!status); - mImpl->is_set = false; - } - - Sync::~Sync() - { - pthread_cond_destroy(&mImpl->cond); - pthread_mutex_destroy(&mImpl->mutex); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - void Sync::reset() - { - NVLinuxScopeLock lock(mImpl->mutex); - mImpl->is_set = false; - } - - void Sync::set() - { - NVLinuxScopeLock lock(mImpl->mutex); - if (!mImpl->is_set) { - mImpl->is_set = true; - pthread_cond_broadcast(&mImpl->cond); - } - } - - bool Sync::wait(QT3DSU32 ms) - { - NVLinuxScopeLock lock(mImpl->mutex); - if (!mImpl->is_set) { - if (ms == QT3DSU32(-1)) { - int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); - QT3DS_ASSERT(!status); - (void)status; - } else { - timespec ts; - timeval tp; - gettimeofday(&tp, NULL); - QT3DSU32 sec = ms / 1000; - QT3DSU32 usec = (ms - 1000 * sec) * 1000; - - // sschirm: taking into account that us might accumulate to a second - // otherwise the pthread_cond_timedwait complains on osx. - usec = tp.tv_usec + usec; - QT3DSU32 div_sec = usec / 1000000; - QT3DSU32 rem_usec = usec - div_sec * 1000000; - - ts.tv_sec = tp.tv_sec + sec + div_sec; - ts.tv_nsec = rem_usec * 1000; - - int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); - QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); - (void)ierr; - } - } - return mImpl->is_set; - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxThread.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxThread.cpp deleted file mode 100644 index fa6e069e..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxThread.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSThread.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#if !defined(QT3DS_APPLE) && !defined(ANDROID) && !defined(__CYGWIN__) && !defined(__QNX__) && !defined(__INTEGRITY) -#include // PTHREAD_STACK_MIN -#endif -#include -#include -#if !defined(__QNX__) && !defined(__INTEGRITY) -#include -#include -#if !defined(QT3DS_APPLE) -#include -#include -#endif -#endif - -#define NVSpinLockPause() asm("nop") - -namespace qt3ds { -namespace foundation { - using namespace intrinsics; - - typedef enum { _NVThreadNotStarted, _NVThreadStarted, _NVThreadStopped } NVThreadState; - - class ThreadImpl - { - public: - ThreadImpl(NVFoundationBase &foundation) - : mFoundation(foundation) - { - } - NVFoundationBase &mFoundation; - Thread::ExecuteFn fn; - void *arg; - volatile QT3DSI32 quitNow; - volatile QT3DSI32 threadStarted; - NVThreadState state; - - pthread_t thread; - pid_t tid; - }; - - void *NVThreadStart(void *arg); - - Thread::Id Thread::getId() { return Id(pthread_self()); } - - Thread::Thread(NVFoundationBase &foundation) - { - mImpl = QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); - mImpl->thread = 0; - mImpl->tid = 0; - mImpl->state = _NVThreadNotStarted; - mImpl->quitNow = 0; - mImpl->threadStarted = 0; - mImpl->fn = NULL; - mImpl->arg = NULL; - } - - Thread::Thread(NVFoundationBase &foundation, Thread::ExecuteFn fn, void *arg) - { - mImpl = (ThreadImpl *)QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); - mImpl->thread = 0; - mImpl->tid = 0; - mImpl->state = _NVThreadNotStarted; - mImpl->quitNow = 0; - mImpl->threadStarted = 0; - mImpl->fn = fn; - mImpl->arg = arg; - - start(0); - } - - Thread::~Thread() - { - if (mImpl->state == _NVThreadStarted) - kill(); - QT3DS_FREE(mImpl->mFoundation.getAllocator(), mImpl); - } - - void Thread::start(QT3DSU32 stackSize) - { - if (mImpl->state != _NVThreadNotStarted) - return; - - if (stackSize == 0) - stackSize = DEFAULT_STACK_SIZE; - -#if defined(PTHREAD_STACK_MIN) && !defined(ANDROID) - if (stackSize < PTHREAD_STACK_MIN) { - qCWarning(WARNING, "Thread::start(): stack size was set below PTHREAD_STACK_MIN"); - stackSize = PTHREAD_STACK_MIN; - } -#endif - - pthread_attr_t attr; - int status = pthread_attr_init(&attr); - QT3DS_ASSERT(!status); - - status = pthread_attr_setstacksize(&attr, stackSize); - QT3DS_ASSERT(!status); - status = pthread_create(&mImpl->thread, &attr, NVThreadStart, this); - QT3DS_ASSERT(!status); - -#ifndef __QNX__ - // wait for thread to startup and write out TID - // otherwise TID dependent calls like setAffinity will fail. - while (atomicCompareExchange(&(mImpl->threadStarted), 1, 1) == 0) - yield(); -#endif - - mImpl->state = _NVThreadStarted; - - status = pthread_attr_destroy(&attr); - QT3DS_ASSERT(!status); - } - - static void setTid(ThreadImpl &threadImpl) - { -#ifndef __QNX__ -// query TID -#ifdef QT3DS_APPLE - threadImpl.tid = syscall(SYS_gettid); -#elif defined(__INTEGRITY) - pthread_t ptid = pthread_self(); - uint64_t threadId = 0; - memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid))); - threadImpl.tid = threadId; -#else - threadImpl.tid = syscall(__NR_gettid); -#endif - - // notify/unblock parent thread - atomicCompareExchange(&(threadImpl.threadStarted), 1, 0); -#else - QT3DS_ASSERT(false); -#endif - } - - void *NVThreadStart(void *arg) - { - // run execute from base class to run gettid in the new thread's context - ((Thread *)arg)->Thread::execute(); - return 0; - } - - void Thread::execute(void) - { - // run setTid in thread's context - setTid(*mImpl); - - // then run either the passed in function or execute from the derived class. - if (mImpl->fn) - (*mImpl->fn)(mImpl->arg); - else - this->execute(); - } - - void Thread::signalQuit() { atomicIncrement(&(mImpl->quitNow)); } - - bool Thread::waitForQuit() - { - if (mImpl->state == _NVThreadNotStarted) - return false; - - pthread_join(mImpl->thread, NULL); - return true; - } - - bool Thread::quitIsSignalled() - { -#ifndef __QNX__ - return atomicCompareExchange(&(mImpl->quitNow), 0, 0) != 0; -#else - // Hope for memory locking on the arm. - return mImpl->quitNow != 0; -#endif - } - - void Thread::quit() - { - mImpl->state = _NVThreadStopped; - pthread_exit(0); - } - - void Thread::kill() - { -#ifndef ANDROID - if (mImpl->state == _NVThreadStarted) - pthread_cancel(mImpl->thread); - mImpl->state = _NVThreadStopped; -#else - qCWarning(WARNING, "Thread::kill() called, but is not implemented"); -#endif - } - - void Thread::sleep(QT3DSU32 ms) - { - timespec sleepTime; - QT3DSU32 remainder = ms % 1000; - sleepTime.tv_sec = ms - remainder; - sleepTime.tv_nsec = remainder * 1000000L; - - while (nanosleep(&sleepTime, &sleepTime) == -1) - continue; - } - - void Thread::yield() { sched_yield(); } - - QT3DSU32 Thread::setAffinityMask(QT3DSU32 mask) - { - // Same as windows impl if mask is zero - if (!mask) - return 0; - -#ifndef __QNX__ - QT3DSU64 prevMask = 0; - -// Apple doesn't support syscall with getaffinity and setaffinity -#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) - QT3DSI32 errGet = syscall(__NR_sched_getaffinity, mImpl->tid, sizeof(prevMask), &prevMask); - if (errGet < 0) - return 0; - - QT3DSI32 errSet = syscall(__NR_sched_setaffinity, mImpl->tid, sizeof(mask), &mask); - if (errSet != 0) - return 0; -#endif - - return QT3DSU32(prevMask); -#else - QT3DS_ASSERT(false); - return 0; -#endif - } - - void Thread::setName(const char *name) - { -#if (defined(ANDROID) && (__ANDROID_API__ > 8)) - pthread_setname_np(mImpl->thread, name); -#else -// not implemented because most unix APIs expect setName() -// to be called from the thread's context. Example see next comment: - -// this works only with the current thread and can rename -// the main process if used in the wrong context: -// prctl(PR_SET_NAME, reinterpret_cast(name) ,0,0,0); -#endif - } - -#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) - static ThreadPriority::Enum convertPriorityFromLinux(QT3DSU32 inPrio, int policy) - { - QT3DS_COMPILE_TIME_ASSERT(ThreadPriority::eLOW > ThreadPriority::eHIGH); - QT3DS_COMPILE_TIME_ASSERT(ThreadPriority::eHIGH == 0); - - int maxL = sched_get_priority_max(policy); - int minL = sched_get_priority_min(policy); - int rangeL = maxL - minL; - int rangeNV = ThreadPriority::eLOW - ThreadPriority::eHIGH; - - // case for default scheduler policy - if (rangeL == 0) - return ThreadPriority::eNORMAL; - - float floatPrio = (float(maxL - inPrio) * float(rangeNV)) / float(rangeL); - - return ThreadPriority::Enum(int(roundf(floatPrio))); - } - - static int convertPriorityToLinux(ThreadPriority::Enum inPrio, int policy) - { - int maxL = sched_get_priority_max(policy); - int minL = sched_get_priority_min(policy); - int rangeL = maxL - minL; - int rangeNV = ThreadPriority::eLOW - ThreadPriority::eHIGH; - - // case for default scheduler policy - if (rangeL == 0) - return 0; - - float floatPrio = (float(ThreadPriority::eLOW - inPrio) * float(rangeL)) / float(rangeNV); - - return minL + int(roundf(floatPrio)); - } -#endif - - void Thread::setPriority(ThreadPriority::Enum val) - { -#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) - int policy; - sched_param s_param; - pthread_getschedparam(mImpl->thread, &policy, &s_param); - s_param.sched_priority = convertPriorityToLinux(val, policy); - pthread_setschedparam(mImpl->thread, policy, &s_param); -#endif - } - - ThreadPriority::Enum Thread::getPriority(Id pthread) - { -#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) - int policy; - sched_param s_param; - int ret = pthread_getschedparam(pthread_t(pthread), &policy, &s_param); - if (ret == 0) - return convertPriorityFromLinux(s_param.sched_priority, policy); - else - return ThreadPriority::eNORMAL; -#else - return ThreadPriority::eNORMAL; -#endif - } - - QT3DSU32 TlsAlloc() - { -#if !defined(__INTEGRITY) - pthread_key_t key; - int status = pthread_key_create(&key, NULL); - QT3DS_ASSERT(!status); - (void)status; - return (QT3DSU32)key; -#else - QT3DS_ASSERT(false); - return 0; -#endif - } - - void TlsFree(QT3DSU32 index) - { - int status = pthread_key_delete((pthread_key_t)index); - QT3DS_ASSERT(!status); - (void)status; - } - - void *TlsGet(QT3DSU32 index) { return (void *)pthread_getspecific((pthread_key_t)index); } - - QT3DSU32 TlsSet(QT3DSU32 index, void *value) - { - int status = pthread_setspecific((pthread_key_t)index, value); - QT3DS_ASSERT(!status); - return !status; - } - - // DM: On Linux x86-32, without implementation-specific restrictions - // the default stack size for a new thread should be 2 megabytes (kernel.org). - // NOTE: take care of this value on other architecutres! - const QT3DSU32 Thread::DEFAULT_STACK_SIZE = 1 << 21; - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxTime.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxTime.cpp deleted file mode 100644 index 6b3e93e4..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/Qt3DSLinuxTime.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSTime.h" - -#include -#include - -#if defined QT3DS_APPLE -#include -#endif - -// Use real-time high-precision timer. -#ifndef QT3DS_APPLE -#define CLOCKID CLOCK_REALTIME -#endif - -namespace qt3ds { -namespace foundation { - - const CounterFrequencyToTensOfNanos Time::sCounterFreq = Time::getCounterFrequency(); - - static Time::Second getTimeSeconds() - { - static struct timeval _tv; - gettimeofday(&_tv, NULL); - return double(_tv.tv_sec) + double(_tv.tv_usec) * 0.000001; - } - - Time::Time() { mLastTime = getTimeSeconds(); } - - Time::Second Time::getElapsedSeconds() - { - Time::Second curTime = getTimeSeconds(); - Time::Second diff = curTime - mLastTime; - mLastTime = curTime; - return diff; - } - - Time::Second Time::peekElapsedSeconds() - { - Time::Second curTime = getTimeSeconds(); - Time::Second diff = curTime - mLastTime; - return diff; - } - - Time::Second Time::getLastTime() const { return mLastTime; } - -#ifdef QT3DS_APPLE - CounterFrequencyToTensOfNanos Time::getCounterFrequency() - { - mach_timebase_info_data_t info; - mach_timebase_info(&info); - // sschirm: some code in the PhysX samples assumes that - // CounterFrequencyToTensOfNanos::mDenominator is #ticks/second - // which is bad since it ignores the numenator. This is a temporary fix - // with the same setup as windows - // return CounterFrequencyToTensOfNanos( info.numer, info.denom*10 ); - return CounterFrequencyToTensOfNanos(sNumTensOfNanoSecondsInASecond, - info.denom * 1000000000 / info.numer); - } - - QT3DSU64 Time::getCurrentCounterValue() { return mach_absolute_time(); } - -#else - - CounterFrequencyToTensOfNanos Time::getCounterFrequency() - { - return CounterFrequencyToTensOfNanos(1, 10); - } - - QT3DSU64 Time::getCurrentCounterValue() - { - struct timespec mCurrTimeInt; - clock_gettime(CLOCKID, &mCurrTimeInt); - // Convert to nanos as this doesn't cause a large divide here - return (static_cast(mCurrTimeInt.tv_sec) * 1000000000) - + (static_cast(mCurrTimeInt.tv_nsec)); - } -#endif - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/SocketImpl.h b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/SocketImpl.h deleted file mode 100644 index 4c3fcb73..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/linux/SocketImpl.h +++ /dev/null @@ -1,424 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef FOUNDATION_LINUX_SOCKET_IMPL_H -#define FOUNDATION_LINUX_SOCKET_IMPL_H -#pragma once - -/*=========================================================================*\ -* BSD include files -\*=========================================================================*/ -/* error codes */ -#include -/* close function */ -#include -/* fnctnl function and associated constants */ -#include -/* struct sockaddr */ -#include -/* socket function */ -#include -/* struct timeval */ -#include -/* gethostbyname and gethostbyaddr functions */ -#include -/* sigpipe handling */ -#include -/* IP stuff*/ -#include -#include -/* TCP options (nagle algorithm disable) */ -#include - -namespace qt3ds { -namespace foundation { - namespace socketimpl { - // Functions take from lua socket implementation. Note that it has an MIT license. - - enum { - IO_DONE = 0, /* operation completed successfully */ - IO_TIMEOUT = -1, /* operation timed out */ - IO_CLOSED = -2, /* the connection has been closed */ - IO_UNKNOWN = -3 - }; - - /*-------------------------------------------------------------------------*\ - * I/O error strings - \*-------------------------------------------------------------------------*/ - const char *io_strerror(int err) - { - switch (err) { - case IO_DONE: - return NULL; - case IO_CLOSED: - return "closed"; - case IO_TIMEOUT: - return "timeout"; - default: - return "unknown error"; - } - } - - typedef int t_socket; - typedef t_socket *p_socket; - typedef struct sockaddr SA; - -#define SOCKET_INVALID (-1) - -#define WAITFD_R 1 -#define WAITFD_W 2 -#define WAITFD_C (WAITFD_R | WAITFD_W) - - int socket_waitfd(p_socket ps, int sw, QT3DSU32 tm) - { - int ret; - fd_set rfds, wfds, *rp, *wp; - struct timeval tv, *tp = NULL; - if (tm == 0) - return IO_TIMEOUT; /* optimize timeout == 0 case */ - if (tm < QT3DS_MAX_U32) { - // shoule consider max timeout specially by setting tp = NULL - // or you get invalid argument errno = 22 - tv.tv_sec = (int)(tm / 1000); - QT3DSU32 leftover = tm % 1000; - tv.tv_usec = (int)(leftover * 100000); - tp = &tv; - } - do { - /* must set bits within loop, because select may have modifed them */ - rp = wp = NULL; - if (sw & WAITFD_R) { - FD_ZERO(&rfds); - FD_SET(*ps, &rfds); - rp = &rfds; - } - if (sw & WAITFD_W) { - FD_ZERO(&wfds); - FD_SET(*ps, &wfds); - wp = &wfds; - } - ret = select(*ps + 1, rp, wp, NULL, tp); - } while (ret == -1 && errno == EINTR); - if (ret == -1) - return errno; - if (ret == 0) - return IO_TIMEOUT; - if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) - return IO_CLOSED; - return IO_DONE; - } - - /*-------------------------------------------------------------------------*\ - * Initializes module - \*-------------------------------------------------------------------------*/ - int socket_open(void) - { - /* instals a handler to ignore sigpipe or it will crash us */ - signal(SIGPIPE, SIG_IGN); - return 1; - } - - /*-------------------------------------------------------------------------*\ - * Close module - \*-------------------------------------------------------------------------*/ - int socket_close(void) { return 1; } - - /*-------------------------------------------------------------------------*\ - * Put socket into blocking mode - \*-------------------------------------------------------------------------*/ - void socket_setblocking(p_socket ps) - { - int flags = fcntl(*ps, F_GETFL, 0); - flags &= (~(O_NONBLOCK)); - fcntl(*ps, F_SETFL, flags); - } - - /*-------------------------------------------------------------------------*\ - * Put socket into non-blocking mode - \*-------------------------------------------------------------------------*/ - void socket_setnonblocking(p_socket ps) - { - int flags = fcntl(*ps, F_GETFL, 0); - flags |= O_NONBLOCK; - fcntl(*ps, F_SETFL, flags); - } - - /*-------------------------------------------------------------------------*\ - * Close and inutilize socket - \*-------------------------------------------------------------------------*/ - void socket_destroy(p_socket ps) - { - if (*ps != SOCKET_INVALID) { - socket_setblocking(ps); - close(*ps); - *ps = SOCKET_INVALID; - } - } - /*-------------------------------------------------------------------------*\ - * - \*-------------------------------------------------------------------------*/ - void socket_shutdown(p_socket ps, int how) - { - socket_setblocking(ps); - shutdown(*ps, how); - socket_setnonblocking(ps); - } - - /*-------------------------------------------------------------------------*\ - * Creates and sets up a socket - \*-------------------------------------------------------------------------*/ - int socket_create(p_socket ps, int domain, int type, int protocol) - { - *ps = socket(domain, type, protocol); - if (*ps != SOCKET_INVALID) - return IO_DONE; - else - return errno; - } - - /*-------------------------------------------------------------------------*\ - * - \*-------------------------------------------------------------------------*/ - int socket_listen(p_socket ps, int backlog) - { - int err = IO_DONE; - socket_setblocking(ps); - if (listen(*ps, backlog)) - err = errno; - socket_setnonblocking(ps); - return err; - } - - /*-------------------------------------------------------------------------*\ - * Binds or returns error message - \*-------------------------------------------------------------------------*/ - int socket_bind(p_socket ps, SA *addr, socklen_t len) - { - int err = IO_DONE; - socket_setblocking(ps); - if (bind(*ps, addr, len) < 0) - err = errno; - socket_setnonblocking(ps); - return err; - } - - /*-------------------------------------------------------------------------*\ - * Connects or returns error message - \*-------------------------------------------------------------------------*/ - int socket_connect(p_socket ps, SA *addr, socklen_t len, QT3DSU32 tm) - { - int err; - /* avoid calling on closed sockets */ - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - /* call connect until done or failed without being interrupted */ - do - if (connect(*ps, addr, len) == 0) - return IO_DONE; - while ((err = errno) == EINTR); - /* if connection failed immediately, return error code */ - if (err != EINPROGRESS && err != EAGAIN) - return err; - /* zero timeout case optimization */ - if (tm == 0) - return IO_TIMEOUT; - /* wait until we have the result of the connection attempt or timeout */ - err = socket_waitfd(ps, WAITFD_C, tm); - if (err == IO_CLOSED) { - if (recv(*ps, (char *)&err, 0, 0) == 0) - return IO_DONE; - else - return errno; - } else - return err; - } - - /*-------------------------------------------------------------------------*\ - * Accept with timeout - \*-------------------------------------------------------------------------*/ - int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, QT3DSU32 tm) - { - SA daddr; - socklen_t dlen = sizeof(daddr); - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - if (!addr) - addr = &daddr; - if (!len) - len = &dlen; - for (;;) { - int err; - if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) - return IO_DONE; - err = errno; - if (err == EINTR) - continue; - if (err != EAGAIN && err != ECONNABORTED) - return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) - return err; - } - /* can't reach here */ - return IO_UNKNOWN; - } - - /*-------------------------------------------------------------------------*\ - * Send with timeout - \*-------------------------------------------------------------------------*/ - int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, QT3DSU32 tm) - { - int err; - *sent = 0; - /* avoid making system calls on closed sockets */ - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - /* loop until we send something or we give up on error */ - for (;;) { - long put = (long)send(*ps, data, count, 0); - /* if we sent anything, we are done */ - if (put > 0) { - *sent = put; - return IO_DONE; - } - err = errno; - /* send can't really return 0, but EPIPE means the connection was closed */ - if (put == 0 || err == EPIPE) - return IO_CLOSED; - /* we call was interrupted, just try again */ - if (err == EINTR) - continue; - /* if failed fatal reason, report error */ - if (err != EAGAIN) - return err; - /* wait until we can send something or we timeout */ - if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) - return err; - } - /* can't reach here */ - return IO_UNKNOWN; - } - - /*-------------------------------------------------------------------------*\ - * Receive with timeout - \*-------------------------------------------------------------------------*/ - int socket_recv(p_socket ps, char *data, size_t count, size_t *got, QT3DSU32 tm) - { - int err; - *got = 0; - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - for (;;) { - long taken = (long)recv(*ps, data, count, 0); - if (taken > 0) { - *got = taken; - return IO_DONE; - } - err = errno; - if (taken == 0) - return IO_CLOSED; - if (err == EINTR) - continue; - if (err != EAGAIN) - return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) - return err; - } - return IO_UNKNOWN; - } - - int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) - { - *hp = gethostbyaddr(addr, len, AF_INET); - if (*hp) - return IO_DONE; - else if (h_errno) - return h_errno; - else if (errno) - return errno; - else - return IO_UNKNOWN; - } - - int socket_gethostbyname(const char *addr, struct hostent **hp) - { - *hp = gethostbyname(addr); - if (*hp) - return IO_DONE; - else if (h_errno) - return h_errno; - else if (errno) - return errno; - else - return IO_UNKNOWN; - } - - /*-------------------------------------------------------------------------*\ - * Error translation functions - * Make sure important error messages are standard - \*-------------------------------------------------------------------------*/ - const char *socket_hoststrerror(int err) - { - if (err <= 0) - return io_strerror(err); - switch (err) { - case HOST_NOT_FOUND: - return "host not found"; - default: - return hstrerror(err); - } - } - - const char *socket_strerror(int err) - { - if (err <= 0) - return io_strerror(err); - switch (err) { - case EADDRINUSE: - return "address already in use"; - case EISCONN: - return "already connected"; - case EACCES: - return "permission denied"; - case ECONNREFUSED: - return "connection refused"; - case ECONNABORTED: - return "closed"; - case ECONNRESET: - return "closed"; - case ETIMEDOUT: - return "timeout"; - default: - return strerror(errno); - } - } - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixAtomic.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixAtomic.cpp deleted file mode 100644 index c1ac3965..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixAtomic.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2001-2004 NovodeX AG. -** Copyright (C) 2004-2008 AGEIA Technologies, Inc. -** Copyright (C) 2008-2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAtomic.h" - -#define PAUSE() asm("nop") - -namespace qt3ds { -namespace foundation { - - void *atomicCompareExchangePointer(volatile void **dest, void *exch, void *comp) - { - return __sync_val_compare_and_swap((void **)dest, comp, exch); - } - - QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) - { - return __sync_val_compare_and_swap(dest, comp, exch); - } - - QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) { return __sync_add_and_fetch(val, 1); } - - QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) { return __sync_sub_and_fetch(val, 1); } - - QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta) { return __sync_add_and_fetch(val, delta); } - - QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2) - { - QT3DSI32 oldVal, newVal; - - do { - PAUSE(); - oldVal = *val; - - if (val2 > oldVal) - newVal = val2; - else - newVal = oldVal; - - } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); - - return *val; - } - - QT3DSI32 atomicExchange(volatile QT3DSI32 *val, QT3DSI32 val2) - { - QT3DSI32 newVal, oldVal; - - do { - PAUSE(); - oldVal = *val; - newVal = val2; - } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); - - return oldVal; - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixFPU.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixFPU.cpp deleted file mode 100644 index 59c9850d..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixFPU.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2001-2004 NovodeX AG. -** Copyright (C) 2004-2008 AGEIA Technologies, Inc. -** Copyright (C) 2008-2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSFPU.h" -#include - -#if !(defined(__CYGWIN__) || defined(PX_ANDROID)) -QT3DS_COMPILE_TIME_ASSERT(8 * sizeof(qt3ds::QT3DSU32) >= sizeof(fenv_t)); -#endif - -qt3ds::foundation::FPUGuard::FPUGuard() -{ -#if defined(__CYGWIN__) -#pragma message "FPUGuard::FPUGuard() is not implemented" -#elif defined(PX_ANDROID) -// not supported unless ARM_HARD_FLOAT is enabled. -#else - fegetenv(reinterpret_cast(mControlWords)); - fesetenv(FE_DFL_ENV); -#endif -} - -qt3ds::foundation::FPUGuard::~FPUGuard() -{ -#if defined(__CYGWIN__) -#pragma message "FPUGuard::~FPUGuard() is not implemented" -#elif defined(PX_ANDROID) -// not supported unless ARM_HARD_FLOAT is enabled. -#else - fesetenv(reinterpret_cast(mControlWords)); -#endif -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixMutex.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixMutex.cpp deleted file mode 100644 index bbc55829..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixMutex.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAtomic.h" - -#include - -namespace qt3ds { -namespace foundation { - - namespace { - pthread_mutex_t *getMutex(MutexImpl *impl) - { - return reinterpret_cast(impl); - } - } - - MutexImpl::MutexImpl() - { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(getMutex(this), &attr); - pthread_mutexattr_destroy(&attr); - } - - MutexImpl::~MutexImpl() { pthread_mutex_destroy(getMutex(this)); } - - bool MutexImpl::lock() { return !pthread_mutex_lock(getMutex(this)); } - - bool MutexImpl::trylock() { return !pthread_mutex_trylock(getMutex(this)); } - - bool MutexImpl::unlock() { return !pthread_mutex_unlock(getMutex(this)); } - - const QT3DSU32 MutexImpl::size = sizeof(pthread_mutex_t); - - class ReadWriteLockImpl - { - public: - ReadWriteLockImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - pthread_mutex_t mutex; - volatile int readerCounter; - }; - - ReadWriteLock::ReadWriteLock(NVAllocatorCallback &alloc) - { - mImpl = QT3DS_NEW(alloc, ReadWriteLockImpl)(alloc); - - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mImpl->mutex, &attr); - pthread_mutexattr_destroy(&attr); - - mImpl->readerCounter = 0; - } - - ReadWriteLock::~ReadWriteLock() - { - pthread_mutex_destroy(&mImpl->mutex); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - void ReadWriteLock::lockReader() - { - pthread_mutex_lock(&mImpl->mutex); - - atomicIncrement(&mImpl->readerCounter); - - pthread_mutex_unlock(&mImpl->mutex); - } - - void ReadWriteLock::lockWriter() - { - pthread_mutex_lock(&mImpl->mutex); - - while (mImpl->readerCounter != 0) - ; - } - - void ReadWriteLock::unlockReader() { atomicDecrement(&mImpl->readerCounter); } - - void ReadWriteLock::unlockWriter() { pthread_mutex_unlock(&mImpl->mutex); } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSemaphore.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSemaphore.cpp deleted file mode 100644 index 90aab79a..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSemaphore.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSSemaphore.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSAllocatorCallback.h" - -#include -#include -#include -#include -#include - -namespace qt3ds { -namespace foundation { - - class SemaphoreImpl - { - public: - SemaphoreImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - pthread_mutex_t mutex; - pthread_cond_t cond; - QT3DSU32 count; - QT3DSU32 maxCount; - }; - - struct NVLinuxScopeLock - { - NVLinuxScopeLock(pthread_mutex_t &m) - : mMutex(m) - { - pthread_mutex_lock(&mMutex); - } - - ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } - private: - pthread_mutex_t &mMutex; - }; - - Semaphore::Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount) - { - mImpl = QT3DS_NEW(alloc, SemaphoreImpl)(alloc); - int status = pthread_mutex_init(&mImpl->mutex, 0); - QT3DS_ASSERT(!status); - status = pthread_cond_init(&mImpl->cond, 0); - QT3DS_ASSERT(!status); - mImpl->count = initialCount; - mImpl->maxCount = maxCount; - QT3DS_ASSERT(initialCount <= maxCount); - } - - Semaphore::~Semaphore() - { - pthread_cond_destroy(&mImpl->cond); - pthread_mutex_destroy(&mImpl->mutex); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - bool Semaphore::wait(QT3DSU32 milliseconds) - { - NVLinuxScopeLock lock(mImpl->mutex); - - if (mImpl->count > 0) { - mImpl->count--; - return true; - } - - if (milliseconds == 0) { - return false; - } - - if (milliseconds == QT3DSU32(-1)) { - int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); - QT3DS_ASSERT(!status); - (void)status; - } else { - timespec ts; - timeval tp; - gettimeofday(&tp, NULL); - QT3DSU32 sec = milliseconds / 1000; - QT3DSU32 usec = (milliseconds - 1000 * sec) * 1000; - - // sschirm: taking into account that us might accumulate to a second - // otherwise the pthread_cond_timedwait complains on osx. - usec = tp.tv_usec + usec; - QT3DSU32 div_sec = usec / 1000000; - QT3DSU32 rem_usec = usec - div_sec * 1000000; - - ts.tv_sec = tp.tv_sec + sec + div_sec; - ts.tv_nsec = rem_usec * 1000; - - int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); - QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); - (void)ierr; - return false; - } - - return true; - } - - void Semaphore::post() - { - NVLinuxScopeLock lock(mImpl->mutex); - mImpl->count++; - if (mImpl->count > mImpl->maxCount) - mImpl->count = mImpl->maxCount; - else { - pthread_cond_broadcast(&mImpl->cond); - } - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSync.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSync.cpp deleted file mode 100644 index 52f9d7ab..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixSync.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSAllocatorCallback.h" - -#include -#include -#include -#include -#include - -namespace qt3ds { -namespace foundation { - - class SyncImpl - { - public: - SyncImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - pthread_mutex_t mutex; - pthread_cond_t cond; - volatile bool is_set; - }; - - struct NVLinuxScopeLock - { - NVLinuxScopeLock(pthread_mutex_t &m) - : mMutex(m) - { - pthread_mutex_lock(&mMutex); - } - - ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } - private: - pthread_mutex_t &mMutex; - }; - - Sync::Sync(NVAllocatorCallback &alloc) - { - mImpl = QT3DS_NEW(alloc, SyncImpl)(alloc); - int status = pthread_mutex_init(&mImpl->mutex, 0); - QT3DS_ASSERT(!status); - status = pthread_cond_init(&mImpl->cond, 0); - QT3DS_ASSERT(!status); - mImpl->is_set = false; - } - - Sync::~Sync() - { - pthread_cond_destroy(&mImpl->cond); - pthread_mutex_destroy(&mImpl->mutex); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - void Sync::reset() - { - NVLinuxScopeLock lock(mImpl->mutex); - mImpl->is_set = false; - } - - void Sync::set() - { - NVLinuxScopeLock lock(mImpl->mutex); - if (!mImpl->is_set) { - mImpl->is_set = true; - pthread_cond_broadcast(&mImpl->cond); - } - } - - bool Sync::wait(QT3DSU32 ms) - { - NVLinuxScopeLock lock(mImpl->mutex); - if (!mImpl->is_set) { - if (ms == QT3DSU32(-1)) { - int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); - QT3DS_ASSERT(!status); - (void)status; - } else { - timespec ts; - timeval tp; - gettimeofday(&tp, NULL); - QT3DSU32 sec = ms / 1000; - QT3DSU32 usec = (ms - 1000 * sec) * 1000; - - // sschirm: taking into account that us might accumulate to a second - // otherwise the pthread_cond_timedwait complains on osx. - usec = tp.tv_usec + usec; - QT3DSU32 div_sec = usec / 1000000; - QT3DSU32 rem_usec = usec - div_sec * 1000000; - - ts.tv_sec = tp.tv_sec + sec + div_sec; - ts.tv_nsec = rem_usec * 1000; - - int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); - QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); - (void)ierr; - } - } - return mImpl->is_set; - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixTime.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixTime.cpp deleted file mode 100644 index 58eadcb6..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/macosx/Qt3DSUnixTime.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2001-2004 NovodeX AG. -** Copyright (C) 2004-2008 AGEIA Technologies, Inc. -** Copyright (C) 2008-2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSTime.h" - -#include -#include - -#if defined QT3DS_APPLE -#include -#endif - -// Use real-time high-precision timer. -#ifndef QT3DS_APPLE -#define CLOCKID CLOCK_REALTIME -#endif - -namespace qt3ds { -namespace foundation { - - const CounterFrequencyToTensOfNanos Time::sCounterFreq = Time::getCounterFrequency(); - - static Time::Second getTimeSeconds() - { - static struct timeval _tv; - gettimeofday(&_tv, NULL); - return double(_tv.tv_sec) + double(_tv.tv_usec) * 0.000001; - } - - Time::Time() { mLastTime = getTimeSeconds(); } - - Time::Second Time::getElapsedSeconds() - { - Time::Second curTime = getTimeSeconds(); - Time::Second diff = curTime - mLastTime; - mLastTime = curTime; - return diff; - } - - Time::Second Time::peekElapsedSeconds() - { - Time::Second curTime = getTimeSeconds(); - Time::Second diff = curTime - mLastTime; - return diff; - } - - Time::Second Time::getLastTime() const { return mLastTime; } - -#ifdef QT3DS_APPLE - CounterFrequencyToTensOfNanos Time::getCounterFrequency() - { - mach_timebase_info_data_t info; - mach_timebase_info(&info); - // mach_absolute_time * (info.numer/info.denom) is in units of nano seconds - return CounterFrequencyToTensOfNanos(info.numer, info.denom * 10); - } - - QT3DSU64 Time::getCurrentCounterValue() { return mach_absolute_time(); } - -#else - - CounterFrequencyToTensOfNanos Time::getCounterFrequency() - { - return CounterFrequencyToTensOfNanos(1, 10); - } - - PxU64 Time::getCurrentCounterValue() - { - struct timespec mCurrTimeInt; - clock_gettime(CLOCKID, &mCurrTimeInt); - // Convert to nanos as this doesn't cause a large divide here - return (static_cast(mCurrTimeInt.tv_sec) * 1000000000) - + (static_cast(mCurrTimeInt.tv_nsec)); - } -#endif - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/qt_attribution.json b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/qt_attribution.json deleted file mode 100644 index dd58b0b6..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/qt_attribution.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "Id": "socket", - "Name": "Socket", - "QDocModule": "qt3dstudio", - "QtUsage": "Used by Qt3DStudio, Runtime component.", - - "License": "MIT license", - "LicenseId": "MIT", - "LicenseFile": "LICENCE_SOCKET.TXT", - "Copyright": "Copyright (C) 2004-2013 Diego Nehab." -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsAtomic.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsAtomic.cpp deleted file mode 100644 index 4f95d3dd..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsAtomic.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/windows/Qt3DSWindowsInclude.h" -#include "foundation/Qt3DSAtomic.h" - -namespace qt3ds { -namespace foundation { - - QT3DSI32 atomicExchange(volatile QT3DSI32 *val, QT3DSI32 val2) - { - return (QT3DSI32)InterlockedExchange((volatile LONG *)val, (LONG)val2); - } - - QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) - { - return (QT3DSI32)InterlockedCompareExchange((volatile LONG *)dest, exch, comp); - } - - void *atomicCompareExchangePointer(volatile void **dest, void *exch, void *comp) - { - return InterlockedCompareExchangePointer((volatile PVOID *)dest, exch, comp); - } - - QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) - { - return (QT3DSI32)InterlockedIncrement((volatile LONG *)val); - } - - QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) - { - return (QT3DSI32)InterlockedDecrement((volatile LONG *)val); - } - - QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta) - { - LONG newValue, oldValue; - do { - oldValue = *val; - newValue = oldValue + delta; - } while (InterlockedCompareExchange((volatile LONG *)val, newValue, oldValue) != oldValue); - - return newValue; - } - - QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2) - { - // Could do this more efficiently in asm... - - LONG newValue, oldValue; - - do { - oldValue = *val; - - if (val2 > oldValue) - newValue = val2; - else - newValue = oldValue; - - } while (InterlockedCompareExchange((volatile LONG *)val, newValue, oldValue) != oldValue); - - return newValue; - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsFPU.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsFPU.cpp deleted file mode 100644 index 47242801..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsFPU.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "foundation/Qt3DSFPU.h" -#include "float.h" - -#ifdef QT3DS_X64 -#define _MCW_ALL _MCW_DN | _MCW_EM | _MCW_RC -#else -#define _MCW_ALL _MCW_DN | _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC -#endif - -qt3ds::foundation::FPUGuard::FPUGuard() -{ -// default plus FTZ and DAZ -#if defined(QT3DS_WINDOWS) && defined(QT3DS_VC) -#ifdef QT3DS_X64 - _controlfp_s(mControlWords, _CW_DEFAULT | _DN_FLUSH, _MCW_ALL); -#else - __control87_2(_CW_DEFAULT | _DN_FLUSH, _MCW_ALL, mControlWords, mControlWords + 1); -#endif -#endif -} - -qt3ds::foundation::FPUGuard::~FPUGuard() -{ -#if defined(QT3DS_WINDOWS) && defined(QT3DS_VC) -#ifdef QT3DS_X64 - _controlfp_s(mControlWords, *mControlWords, _MCW_ALL); -#else - __control87_2(mControlWords[0], _MCW_ALL, mControlWords, 0); - __control87_2(mControlWords[1], _MCW_ALL, 0, mControlWords + 1); -#endif -#endif -} diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsMutex.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsMutex.cpp deleted file mode 100644 index c5fef09f..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsMutex.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/windows/Qt3DSWindowsInclude.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSAssert.h" - -namespace qt3ds { -namespace foundation { - - namespace { - CRITICAL_SECTION *getMutex(MutexImpl *impl) - { - return reinterpret_cast(impl); - } - } - - MutexImpl::MutexImpl() { InitializeCriticalSection(getMutex(this)); } - - MutexImpl::~MutexImpl() { DeleteCriticalSection(getMutex(this)); } - - bool MutexImpl::lock() - { - EnterCriticalSection(getMutex(this)); - return true; - } - - bool MutexImpl::trylock() { return TryEnterCriticalSection(getMutex(this)) != 0; } - - bool MutexImpl::unlock() - { - LeaveCriticalSection(getMutex(this)); - return true; - } - - const QT3DSU32 MutexImpl::size = sizeof(CRITICAL_SECTION); - - class ReadWriteLockImpl - { - public: - ReadWriteLockImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - HANDLE hReaderEvent; - HANDLE hMutex; - CRITICAL_SECTION writerMutex; - LONG counter; // count the number of readers in the lock. - LONG recursionCounter; // handle recursive writer locking - }; - - ReadWriteLock::ReadWriteLock(NVAllocatorCallback &alloc) - { - mImpl = QT3DS_NEW(alloc, ReadWriteLockImpl)(alloc); - - mImpl->hReaderEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - QT3DS_ASSERT(mImpl->hReaderEvent != NULL); - - mImpl->hMutex = CreateEvent(NULL, FALSE, TRUE, NULL); - QT3DS_ASSERT(mImpl->hMutex != NULL); - - InitializeCriticalSection(&mImpl->writerMutex); - mImpl->counter = -1; - mImpl->recursionCounter = 0; - } - - ReadWriteLock::~ReadWriteLock() - { - if (mImpl->hReaderEvent != NULL) { - CloseHandle(mImpl->hReaderEvent); - } - - if (mImpl->hMutex != NULL) { - CloseHandle(mImpl->hMutex); - } - - DeleteCriticalSection(&mImpl->writerMutex); - - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - void ReadWriteLock::lockReader() - { - if (InterlockedIncrement(&mImpl->counter) == 0) { - WaitForSingleObject(mImpl->hMutex, INFINITE); - SetEvent(mImpl->hReaderEvent); - } - - WaitForSingleObject(mImpl->hReaderEvent, INFINITE); - } - - void ReadWriteLock::lockWriter() - { - EnterCriticalSection(&mImpl->writerMutex); - - // we may already have the global mutex(really an event so we have to handle recursion - // ourselves) - if (++mImpl->recursionCounter == 1) { - WaitForSingleObject(mImpl->hMutex, INFINITE); - } - } - - void ReadWriteLock::unlockReader() - { - if (InterlockedDecrement(&mImpl->counter) < 0) { - ResetEvent(mImpl->hReaderEvent); - SetEvent(mImpl->hMutex); - } - } - - void ReadWriteLock::unlockWriter() - { - if (--mImpl->recursionCounter == 0) { - SetEvent(mImpl->hMutex); - } - - LeaveCriticalSection(&mImpl->writerMutex); - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp deleted file mode 100644 index bb14c104..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/windows/Qt3DSWindowsInclude.h" -#include "foundation/Qt3DSSemaphore.h" -#include "foundation/Qt3DSAllocator.h" - -namespace qt3ds { -namespace foundation { - - class SemaphoreImpl - { - public: - SemaphoreImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - HANDLE handle; - }; - - Semaphore::Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount) - { - mImpl = QT3DS_NEW(alloc, SemaphoreImpl)(alloc); - mImpl->handle = CreateSemaphore(0, initialCount, maxCount, (LPCTSTR)NULL); - } - - Semaphore::~Semaphore() - { - CloseHandle(mImpl->handle); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - bool Semaphore::wait(QT3DSU32 milliseconds) - { - if (milliseconds == -1) - milliseconds = INFINITE; - - return WaitForSingleObject(mImpl->handle, milliseconds) == WAIT_OBJECT_0 ? true : false; - } - - void Semaphore::post() { ReleaseSemaphore(mImpl->handle, 1, (LPLONG)NULL); } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSync.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSync.cpp deleted file mode 100644 index 49667e94..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsSync.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/windows/Qt3DSWindowsInclude.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSAllocator.h" - -namespace qt3ds { -namespace foundation { - - class SyncImpl - { - public: - SyncImpl(NVAllocatorCallback &alloc) - : mAllocator(alloc) - { - } - NVAllocatorCallback &mAllocator; - HANDLE handle; - }; - - Sync::Sync(NVAllocatorCallback &alloc) - { - mImpl = QT3DS_NEW(alloc, SyncImpl)(alloc); - mImpl->handle = CreateEvent(0, true, false, 0); - } - - Sync::~Sync() - { - CloseHandle(mImpl->handle); - QT3DS_FREE(mImpl->mAllocator, mImpl); - } - - void Sync::reset() { ResetEvent(mImpl->handle); } - - void Sync::set() { SetEvent(mImpl->handle); } - - bool Sync::wait(QT3DSU32 milliseconds) - { - if (milliseconds == -1) - milliseconds = INFINITE; - - return WaitForSingleObject(mImpl->handle, milliseconds) == WAIT_OBJECT_0 ? true : false; - } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsThread.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsThread.cpp deleted file mode 100644 index 3a30de8c..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsThread.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/windows/Qt3DSWindowsInclude.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSThread.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" - -// an exception for setting the thread name in microsoft debuggers -#define QT3DS_MS_VC_EXCEPTION 0x406D1388 - -namespace qt3ds { -namespace foundation { - -// struct for naming a thread in the debugger -#pragma pack(push, 8) - - typedef struct tagTHREADNAME_INFO - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - } THREADNAME_INFO; - -#pragma pack(pop) - - namespace { - - DWORD WINAPI NVThreadStart(LPVOID arg) - { - ((Thread *)arg)->execute(); - return 0; - } - } - - class ThreadImpl - { - public: - enum State { NotStarted, Started, Stopped }; - ThreadImpl(NVFoundationBase &foundation) - : mFoundation(foundation) - { - } - NVFoundationBase &mFoundation; - HANDLE thread; - LONG quitNow; // Should be 32bit aligned on SMP systems. - State state; - DWORD threadID; - - Thread::ExecuteFn fn; - void *arg; - }; - - Thread::Id Thread::getId() { return static_cast(GetCurrentThreadId()); } - - Thread::Thread(NVFoundationBase &foundation) - { - mImpl = (ThreadImpl *)QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); - mImpl->thread = NULL; - mImpl->state = ThreadImpl::NotStarted; - mImpl->quitNow = 0; - } - - Thread::Thread(NVFoundationBase &foundation, ExecuteFn fn, void *arg) - { - mImpl = (ThreadImpl *)QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); - mImpl->thread = NULL; - mImpl->state = ThreadImpl::NotStarted; - mImpl->quitNow = 0; - mImpl->fn = fn; - mImpl->arg = arg; - - start(0); - } - - Thread::~Thread() - { - if (mImpl->state == ThreadImpl::Started) - kill(); - CloseHandle(mImpl->thread); - QT3DS_FREE(mImpl->mFoundation.getAllocator(), mImpl); - } - - void Thread::start(QT3DSU32 stackSize) - { - if (mImpl->state != ThreadImpl::NotStarted) - return; - mImpl->state = ThreadImpl::Started; - - mImpl->thread = - CreateThread(NULL, stackSize, NVThreadStart, (LPVOID)this, 0, &mImpl->threadID); - } - - void Thread::signalQuit() { InterlockedIncrement(&(mImpl->quitNow)); } - - bool Thread::waitForQuit() - { - if (mImpl->state == ThreadImpl::NotStarted) - return false; - - WaitForSingleObject(mImpl->thread, INFINITE); - return true; - } - - bool Thread::quitIsSignalled() - { - return InterlockedCompareExchange(&(mImpl->quitNow), 0, 0) != 0; - } - - void Thread::quit() - { - mImpl->state = ThreadImpl::Stopped; - ExitThread(0); - } - - void Thread::kill() - { - if (mImpl->state == ThreadImpl::Started) - TerminateThread(mImpl->thread, 0); - mImpl->state = ThreadImpl::Stopped; - } - - void Thread::sleep(QT3DSU32 ms) { Sleep(ms); } - - void Thread::yield() { SwitchToThread(); } - - void Thread::execute(void) { (*mImpl->fn)(mImpl->arg); } - - QT3DSU32 Thread::setAffinityMask(QT3DSU32 mask) - { - return mask ? (QT3DSU32)SetThreadAffinityMask(mImpl->thread, mask) : 0; - } - - void Thread::setName(const char *name) - { - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = mImpl->threadID; - info.dwFlags = 0; - -#ifdef QT3DS_VC - // C++ Exceptions are disabled for this project, but SEH is not (and cannot be) - // http://stackoverflow.com/questions/943087/what-exactly-will-happen-if-i-disable-c-exceptions-in-a-project - __try { - RaiseException(QT3DS_MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR *)&info); - } __except (EXCEPTION_EXECUTE_HANDLER) { - // this runs if not attached to a debugger (thus not really naming the thread) - } -#else - RaiseException(QT3DS_MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR *)&info); -#endif - } - - void Thread::setPriority(ThreadPriority::Enum prio) - { - switch (prio) { - case ThreadPriority::eHIGH: - SetThreadPriority(mImpl->thread, THREAD_PRIORITY_HIGHEST); - break; - case ThreadPriority::eABOVE_NORMAL: - SetThreadPriority(mImpl->thread, THREAD_PRIORITY_ABOVE_NORMAL); - break; - case ThreadPriority::eNORMAL: - SetThreadPriority(mImpl->thread, THREAD_PRIORITY_NORMAL); - break; - case ThreadPriority::eBELOW_NORMAL: - SetThreadPriority(mImpl->thread, THREAD_PRIORITY_BELOW_NORMAL); - break; - case ThreadPriority::eLOW: - SetThreadPriority(mImpl->thread, THREAD_PRIORITY_LOWEST); - break; - default: - break; - } - } - - ThreadPriority::Enum Thread::getPriority(Id threadId) - { - ThreadPriority::Enum retval = ThreadPriority::eLOW; - int priority = GetThreadPriority((HANDLE)threadId); - StaticAssert<(THREAD_PRIORITY_HIGHEST > THREAD_PRIORITY_ABOVE_NORMAL)>::valid_expression(); - if (priority >= THREAD_PRIORITY_HIGHEST) - retval = ThreadPriority::eHIGH; - else if (priority >= THREAD_PRIORITY_ABOVE_NORMAL) - retval = ThreadPriority::eABOVE_NORMAL; - else if (priority >= THREAD_PRIORITY_NORMAL) - retval = ThreadPriority::eNORMAL; - else if (priority >= THREAD_PRIORITY_BELOW_NORMAL) - retval = ThreadPriority::eBELOW_NORMAL; - return retval; - } - - QT3DSU32 TlsAlloc() - { - DWORD rv = ::TlsAlloc(); - QT3DS_ASSERT(rv != TLS_OUT_OF_INDEXES); - return (QT3DSU32)rv; - } - - void TlsFree(QT3DSU32 index) { ::TlsFree(index); } - - void *TlsGet(QT3DSU32 index) { return ::TlsGetValue(index); } - - QT3DSU32 TlsSet(QT3DSU32 index, void *value) { return ::TlsSetValue(index, value); } - - const QT3DSU32 Thread::DEFAULT_STACK_SIZE = 1048576; - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsTime.cpp b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsTime.cpp deleted file mode 100644 index 9215d642..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/Qt3DSWindowsTime.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSTime.h" -#include "foundation/windows/Qt3DSWindowsInclude.h" - -namespace { -::qt3ds::QT3DSI64 getTimeTicks() -{ - LARGE_INTEGER a; - QueryPerformanceCounter(&a); - return a.QuadPart; -} - -double getTickDuration() -{ - LARGE_INTEGER a; - QueryPerformanceFrequency(&a); - return 1.0f / double(a.QuadPart); -} - -double sTickDuration = getTickDuration(); -} // namespace - -namespace qt3ds { -namespace foundation { - - const CounterFrequencyToTensOfNanos Time::sCounterFreq = Time::getCounterFrequency(); - - CounterFrequencyToTensOfNanos Time::getCounterFrequency() - { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - return CounterFrequencyToTensOfNanos(Time::sNumTensOfNanoSecondsInASecond, freq.QuadPart); - } - - QT3DSU64 Time::getCurrentCounterValue() - { - LARGE_INTEGER ticks; - QueryPerformanceCounter(&ticks); - return ticks.QuadPart; - } - - Time::Time() - : mTickCount(0) - { - getElapsedSeconds(); - } - - Time::Second Time::getElapsedSeconds() - { - QT3DSI64 lastTickCount = mTickCount; - mTickCount = getTimeTicks(); - return (mTickCount - lastTickCount) * sTickDuration; - } - - Time::Second Time::peekElapsedSeconds() - { - return (getTimeTicks() - mTickCount) * sTickDuration; - } - - Time::Second Time::getLastTime() const { return mTickCount * sTickDuration; } - -} // namespace foundation -} // namespace qt3ds diff --git a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/SocketImpl.h b/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/SocketImpl.h deleted file mode 100644 index f72203bd..00000000 --- a/src/Runtime/Source/Qt3DSFoundation/Source/foundation/windows/SocketImpl.h +++ /dev/null @@ -1,506 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* -LuaSocket 3.0 license -Copyright � 2004-2013 Diego Nehab - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - -#ifndef FOUNDATION_WINDOWS_SOCKET_IMPL_H -#define FOUNDATION_WINDOWS_SOCKET_IMPL_H -#pragma once -#include -#pragma warning(disable : 4127) -#pragma warning(disable : 4702) - -namespace qt3ds { -namespace foundation { - namespace socketimpl { - - // Functions take from lua socket implementation. Note that it has an MIT license. - - enum { - IO_DONE = 0, /* operation completed successfully */ - IO_TIMEOUT = -1, /* operation timed out */ - IO_CLOSED = -2, /* the connection has been closed */ - IO_UNKNOWN = -3 - }; - - /*-------------------------------------------------------------------------*\ - * I/O error strings - \*-------------------------------------------------------------------------*/ - const char *io_strerror(int err) - { - switch (err) { - case IO_DONE: - return NULL; - case IO_CLOSED: - return "closed"; - case IO_TIMEOUT: - return "timeout"; - default: - return "unknown error"; - } - } - - typedef int socklen_t; - typedef SOCKET t_socket; - typedef t_socket *p_socket; - typedef struct sockaddr SA; - -#define SOCKET_INVALID (INVALID_SOCKET) - - static const char *wstrerror(int err) - { - switch (err) { - case WSAEINTR: - return "Interrupted function call"; - case WSAEACCES: - return "Permission denied"; - case WSAEFAULT: - return "Bad address"; - case WSAEINVAL: - return "Invalid argument"; - case WSAEMFILE: - return "Too many open files"; - case WSAEWOULDBLOCK: - return "Resource temporarily unavailable"; - case WSAEINPROGRESS: - return "Operation now in progress"; - case WSAEALREADY: - return "Operation already in progress"; - case WSAENOTSOCK: - return "Socket operation on nonsocket"; - case WSAEDESTADDRREQ: - return "Destination address required"; - case WSAEMSGSIZE: - return "Message too long"; - case WSAEPROTOTYPE: - return "Protocol wrong type for socket"; - case WSAENOPROTOOPT: - return "Bad protocol option"; - case WSAEPROTONOSUPPORT: - return "Protocol not supported"; - case WSAESOCKTNOSUPPORT: - return "Socket type not supported"; - case WSAEOPNOTSUPP: - return "Operation not supported"; - case WSAEPFNOSUPPORT: - return "Protocol family not supported"; - case WSAEAFNOSUPPORT: - return "Address family not supported by protocol family"; - case WSAEADDRINUSE: - return "Address already in use"; - case WSAEADDRNOTAVAIL: - return "Cannot assign requested address"; - case WSAENETDOWN: - return "Network is down"; - case WSAENETUNREACH: - return "Network is unreachable"; - case WSAENETRESET: - return "Network dropped connection on reset"; - case WSAECONNABORTED: - return "Software caused connection abort"; - case WSAECONNRESET: - return "Connection reset by peer"; - case WSAENOBUFS: - return "No buffer space available"; - case WSAEISCONN: - return "Socket is already connected"; - case WSAENOTCONN: - return "Socket is not connected"; - case WSAESHUTDOWN: - return "Cannot send after socket shutdown"; - case WSAETIMEDOUT: - return "Connection timed out"; - case WSAECONNREFUSED: - return "Connection refused"; - case WSAEHOSTDOWN: - return "Host is down"; - case WSAEHOSTUNREACH: - return "No route to host"; - case WSAEPROCLIM: - return "Too many processes"; - case WSASYSNOTREADY: - return "Network subsystem is unavailable"; - case WSAVERNOTSUPPORTED: - return "Winsock.dll version out of range"; - case WSANOTINITIALISED: - return "Successful WSAStartup not yet performed"; - case WSAEDISCON: - return "Graceful shutdown in progress"; - case WSAHOST_NOT_FOUND: - return "Host not found"; - case WSATRY_AGAIN: - return "Nonauthoritative host not found"; - case WSANO_RECOVERY: - return "Nonrecoverable name lookup error"; - case WSANO_DATA: - return "Valid name, no data record of requested type"; - default: - return "Unknown error"; - } - } - - const char *socket_strerror(int err) - { - switch (err) { - case WSAEADDRINUSE: - return "address already in use"; - case WSAECONNREFUSED: - return "connection refused"; - case WSAEISCONN: - return "already connected"; - case WSAEACCES: - return "permission denied"; - case WSAECONNABORTED: - return "closed"; - case WSAECONNRESET: - return "closed"; - case WSAETIMEDOUT: - return "timeout"; - default: - return wstrerror(err); - } - } - - int socket_open(void) - { - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(2, 0); - int err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) - return 0; - if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) - && (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { - WSACleanup(); - return 0; - } - return 1; - } - - /*-------------------------------------------------------------------------*\ - * Close module - \*-------------------------------------------------------------------------*/ - int socket_close(void) - { - WSACleanup(); - return 1; - } - -/*-------------------------------------------------------------------------*\ -* Wait for readable/writable/connected socket with timeout -\*-------------------------------------------------------------------------*/ -#define WAITFD_R 1 -#define WAITFD_W 2 -#define WAITFD_E 4 -#define WAITFD_C (WAITFD_E | WAITFD_W) - - static int socket_waitfd(p_socket ps, int sw, QT3DSU32 timeoutMilliseconds) - { - int ret; - fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; - struct timeval tv, *tp = NULL; - if (timeoutMilliseconds == 0) - return IO_TIMEOUT; /* optimize timeout == 0 case */ - if (sw & WAITFD_R) { - FD_ZERO(&rfds); - FD_SET(*ps, &rfds); - rp = &rfds; - } - if (sw & WAITFD_W) { - FD_ZERO(&wfds); - FD_SET(*ps, &wfds); - wp = &wfds; - } - if (sw & WAITFD_C) { - FD_ZERO(&efds); - FD_SET(*ps, &efds); - ep = &efds; - } - if (timeoutMilliseconds >= 0.0) { - tv.tv_sec = (int)(timeoutMilliseconds / 1000); - QT3DSU32 leftover = timeoutMilliseconds % 1000; - tv.tv_usec = (int)(leftover * 100000); - tp = &tv; - } - ret = select(0, rp, wp, ep, tp); - if (ret == -1) - return WSAGetLastError(); - if (ret == 0) - return IO_TIMEOUT; - if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) - return IO_CLOSED; - return IO_DONE; - } - - static int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, - QT3DSU32 timeoutMilliseconds) - { - int err; - *sent = 0; - /* avoid making system calls on closed sockets */ - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - /* loop until we send something or we give up on error */ - for (;;) { - /* try to send something */ - int put = send(*ps, data, (int)count, 0); - /* if we sent something, we are done */ - if (put > 0) { - *sent = put; - return IO_DONE; - } - /* deal with failure */ - err = WSAGetLastError(); - /* we can only proceed if there was no serious error */ - if (err != WSAEWOULDBLOCK) - return err; - /* avoid busy wait */ - if ((err = socket_waitfd(ps, WAITFD_W, timeoutMilliseconds)) != IO_DONE) - return err; - } - /* can't reach here */ - return IO_UNKNOWN; - } - /*-------------------------------------------------------------------------*\ - * Receive with timeout - \*-------------------------------------------------------------------------*/ - static int socket_recv(p_socket ps, char *data, size_t count, size_t *got, - QT3DSU32 timeoutMilliseconds) - { - int err; - *got = 0; - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - for (;;) { - int taken = recv(*ps, data, (int)count, 0); - if (taken > 0) { - *got = taken; - return IO_DONE; - } - if (taken == 0) - return IO_CLOSED; - err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) - return err; - if ((err = socket_waitfd(ps, WAITFD_R, timeoutMilliseconds)) != IO_DONE) - return err; - } - return IO_UNKNOWN; - } - - void socket_setblocking(p_socket ps) - { - u_long argp = 0; - ioctlsocket(*ps, FIONBIO, &argp); - } - - /*-------------------------------------------------------------------------*\ - * Put socket into non-blocking mode - \*-------------------------------------------------------------------------*/ - void socket_setnonblocking(p_socket ps) - { - u_long argp = 1; - ioctlsocket(*ps, FIONBIO, &argp); - } - - int socket_listen(p_socket ps, int backlog) - { - int err = IO_DONE; - socket_setblocking(ps); - if (listen(*ps, backlog) < 0) - err = WSAGetLastError(); - socket_setnonblocking(ps); - return err; - } - - /*-------------------------------------------------------------------------*\ - * Accept with timeout - \*-------------------------------------------------------------------------*/ - static int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, QT3DSU32 tm) - { - SA daddr; - socklen_t dlen = sizeof(daddr); - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - if (!addr) - addr = &daddr; - if (!len) - len = &dlen; - for (;;) { - int err; - /* try to get client socket */ - if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) - return IO_DONE; - /* find out why we failed */ - err = WSAGetLastError(); - /* if we failed because there was no connectoin, keep trying */ - if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) - return err; - /* call select to avoid busy wait */ - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) - return err; - } - /* can't reach here */ - return IO_UNKNOWN; - } - - int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) - { - *hp = gethostbyaddr(addr, len, AF_INET); - if (*hp) - return IO_DONE; - else - return WSAGetLastError(); - } - - int socket_gethostbyname(const char *addr, struct hostent **hp) - { - *hp = gethostbyname(addr); - if (*hp) - return IO_DONE; - else - return WSAGetLastError(); - } - - /*-------------------------------------------------------------------------*\ - * Error translation functions - \*-------------------------------------------------------------------------*/ - const char *socket_hoststrerror(int err) - { - if (err <= 0) - return io_strerror(err); - switch (err) { - case WSAHOST_NOT_FOUND: - return "host not found"; - default: - return wstrerror(err); - } - } - /*-------------------------------------------------------------------------*\ - * Close and inutilize socket - \*-------------------------------------------------------------------------*/ - void socket_destroy(p_socket ps) - { - if (*ps != SOCKET_INVALID) { - socket_setblocking(ps); /* close can take a long time on WIN32 */ - closesocket(*ps); - *ps = SOCKET_INVALID; - } - } - - /*-------------------------------------------------------------------------*\ - * - \*-------------------------------------------------------------------------*/ - void socket_shutdown(p_socket ps, int how) - { - socket_setblocking(ps); - shutdown(*ps, how); - } - - int socket_create(p_socket ps, int domain, int type, int protocol) - { - *ps = socket(domain, type, protocol); - if (*ps != SOCKET_INVALID) - return IO_DONE; - else - return WSAGetLastError(); - } - - /*-------------------------------------------------------------------------*\ - * Connects or returns error message - \*-------------------------------------------------------------------------*/ - int socket_connect(p_socket ps, SA *addr, socklen_t len, QT3DSU32 tm) - { - int err; - /* don't call on closed socket */ - if (*ps == SOCKET_INVALID) - return IO_CLOSED; - /* ask system to connect */ - if (connect(*ps, addr, len) == 0) - return IO_DONE; - /* make sure the system is trying to connect */ - err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) - return err; - /* zero timeout case optimization */ - if (tm == 0) - return IO_TIMEOUT; - /* we wait until something happens */ - err = socket_waitfd(ps, WAITFD_C, tm); - if (err == IO_CLOSED) { - int len = sizeof(err); - /* give windows time to set the error (yes, disgusting) */ - Sleep(10); - /* find out why we failed */ - getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); - /* we KNOW there was an error. if 'why' is 0, we will return - * "unknown error", but it's not really our fault */ - return err > 0 ? err : IO_UNKNOWN; - } else - return err; - } - - /*-------------------------------------------------------------------------*\ - * Binds or returns error message - \*-------------------------------------------------------------------------*/ - int socket_bind(p_socket ps, SA *addr, socklen_t len) - { - int err = IO_DONE; - socket_setblocking(ps); - if (bind(*ps, addr, len) < 0) - err = WSAGetLastError(); - socket_setnonblocking(ps); - return err; - } - } -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderClearColorExample.cpp b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderClearColorExample.cpp deleted file mode 100644 index f67cf717..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderClearColorExample.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderExample.h" -#include "foundation/Qt3DSVec4.h" - -using namespace qt3ds; -using namespace qt3ds::render; - -namespace { -class ClearColor : public NVRenderExample -{ - NVRenderContext &m_Context; - -public: - ClearColor(NVRenderContext &ctx) - : m_Context(ctx) - { - } - virtual void drawFrame(double currentSeconds) - { - // Apply this value immediately but track it so that a later pop will in fact - // restore this value. - if (currentSeconds < 1) - m_Context.SetClearColor(QT3DSVec4(.8f, .0f, .0f, 1.f)); - else if (currentSeconds < 2) - m_Context.SetClearColor(QT3DSVec4(0.f, .0f, 1.f, 1.f)); - else - m_Context.SetClearColor(QT3DSVec4(0.f, 1.0f, 1.f, 1.f)); - m_Context.Clear(NVRenderClearFlags(NVRenderClearValues::Color)); - } - virtual QT3DSU32 getRuntimeInSeconds() { return 2; } - virtual void release() { NVDelete(m_Context.GetFoundation(), this); } -}; -} - -// QT3DS_RENDER_REGISTER_EXAMPLE( ClearColor ); \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.cpp b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.cpp deleted file mode 100644 index d866cda0..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderExample.h" -#include "render/NvRenderBaseTypes.h" -#include "render_util/NVRenderAllocator.h" -#include "render_util/NVRenderErrorStream.h" -#include "render_util/NVRenderUtils.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSTime.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSMath.h" - -#include -#include -#include - -using namespace qt3ds; -using namespace qt3ds::render; - -static TExampleCreateFunc gCreateFuncs[128]; - -TExampleCreateFunc *NVRenderExampleFactory::mExampleCreators = gCreateFuncs; -QT3DSU32 NVRenderExampleFactory::mMaxCreators = 128; -QT3DSU32 NVRenderExampleFactory::mNumCreators = 0; -namespace { -NVRenderErrorStream g_errorStream; -NVRenderAllocator g_allocator(g_errorStream); -NVFoundation *g_foundation(NULL); -NVRenderContext *g_renderContext(NULL); -NVRenderExample *g_example(NULL); -QT3DSI32 g_exampleIdx(0); -Time::Second g_runTime; -Time g_timer; -} - -bool NVRenderExampleFactory::nextExample() -{ - if (g_example) - g_example->release(); - g_example = 0; - if (g_exampleIdx < (int)mNumCreators) { - g_example = mExampleCreators[g_exampleIdx](*g_renderContext); - ++g_exampleIdx; - g_runTime = g_example->getRuntimeInSeconds(); - g_timer = Time(); - return true; - } - return false; -} - -void NVRenderExampleFactory::beginExamples() -{ - g_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, g_allocator, g_errorStream); - g_renderContext = - &NVRenderContext::CreateGL(*g_foundation, NVRenderContextType(NVRenderContextValues::GL2)); - nextExample(); -} -bool NVRenderExampleFactory::update() -{ - Time::Second currentTime = g_timer.peekElapsedSeconds(); - if (currentTime > g_runTime) - nextExample(); - if (g_example) - g_example->drawFrame(currentTime); - - return g_example != NULL; -} - -void NVRenderExampleFactory::endExamples() -{ - g_exampleIdx = mNumCreators; - nextExample(); - if (g_renderContext) - g_renderContext->release(); - if (g_foundation) - g_foundation->release(); - - g_renderContext = NULL; - g_foundation = NULL; -} - -namespace qt3ds { -namespace render { - /////////////////////////////////////////////////////////////////////////////// - - // Math stuff - - int eq(float a, float b) - { - float diff = a - b; - if (diff < 0) { - diff = -diff; - } - return diff <= eps; - } - - // - // Matrix functions, since GLES 2.x doesn't provide them - // - - void NvGl2DemoMatrixIdentity(float m[16]) - { - memset(m, 0, sizeof(float) * 16); - m[4 * 0 + 0] = m[4 * 1 + 1] = m[4 * 2 + 2] = m[4 * 3 + 3] = 1.0; - } - - int NvGl2DemoMatrixEquals(float a[16], float b[16]) - { - int i; - for (i = 0; i < 16; ++i) - if (!eq(a[i], b[i])) - return 0; - - return 1; - } - - void NvGl2DemoMatrixTranspose(float m[16]) - { - int i, j; - float t; - for (i = 1; i < 4; ++i) - for (j = 0; j < i; ++j) { - t = m[4 * i + j]; - m[4 * i + j] = m[4 * j + i]; - m[4 * j + i] = t; - } - } - - void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]) - { - int r, c, i; - for (r = 0; r < 4; r++) { - float m[4] = { 0.0, 0.0, 0.0, 0.0 }; - for (c = 0; c < 4; c++) { - for (i = 0; i < 4; i++) { - m[c] += m0[4 * i + r] * m1[4 * c + i]; - } - } - for (c = 0; c < 4; c++) { - m0[4 * c + r] = m[c]; - } - } - } - - void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]) - { - int r, c, i; - for (r = 0; r < 4; r++) { - float m[3] = { 0.0, 0.0, 0.0 }; - for (c = 0; c < 3; c++) { - for (i = 0; i < 3; i++) { - m[c] += m0[4 * i + r] * m1[3 * c + i]; - } - } - for (c = 0; c < 3; c++) { - m0[4 * c + r] = m[c]; - } - } - } - - void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]) - { - int r, c, i; - for (r = 0; r < 3; r++) { - float m[3] = { 0.0, 0.0, 0.0 }; - for (c = 0; c < 3; c++) { - for (i = 0; i < 3; i++) { - m[c] += m0[3 * i + r] * m1[3 * c + i]; - } - } - for (c = 0; c < 3; c++) { - m0[3 * c + r] = m[c]; - } - } - } - - void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f) - { - float m1[16]; - float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv, twoNear; - - rightMinusLeftInv = 1.0f / (r - l); - topMinusBottomInv = 1.0f / (t - b); - farMinusNearInv = 1.0f / (f - n); - twoNear = 2.0f * n; - - m1[0] = twoNear * rightMinusLeftInv; - m1[1] = 0.0f; - m1[2] = 0.0f; - m1[3] = 0.0f; - - m1[4] = 0.0f; - m1[5] = twoNear * topMinusBottomInv; - m1[6] = 0.0f; - m1[7] = 0.0f; - - m1[8] = (r + l) * rightMinusLeftInv; - m1[9] = (t + b) * topMinusBottomInv; - m1[10] = -(f + n) * farMinusNearInv; - m1[11] = -1.0f; - - m1[12] = 0.0f; - m1[13] = 0.0f; - m1[14] = -(twoNear * f) * farMinusNearInv; - m1[15] = 0.0f; - - NvGl2DemoMatrixMultiply(m, m1); - } - - void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f) - { - float m1[16]; - float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv; - - rightMinusLeftInv = 1.0f / (r - l); - topMinusBottomInv = 1.0f / (t - b); - farMinusNearInv = 1.0f / (f - n); - - m1[0] = 2.0f * rightMinusLeftInv; - m1[1] = 0.0f; - m1[2] = 0.0f; - m1[3] = 0.0f; - - m1[4] = 0.0f; - m1[5] = 2.0f * topMinusBottomInv; - m1[6] = 0.0f; - m1[7] = 0.0f; - - m1[8] = 0.0f; - m1[9] = 0.0f; - m1[10] = -2.0f * farMinusNearInv; - m1[11] = 0.0f; - - m1[12] = -(r + l) * rightMinusLeftInv; - m1[13] = -(t + b) * topMinusBottomInv; - m1[14] = -(f + n) * farMinusNearInv; - m1[15] = 1.0f; - - NvGl2DemoMatrixMultiply(m, m1); - } - - void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z) - { - float m1[16]; - NvGl2DemoMatrixIdentity(m1); - - m1[4 * 3 + 0] = x; - m1[4 * 3 + 1] = y; - m1[4 * 3 + 2] = z; - - NvGl2DemoMatrixMultiply(m, m1); - } - - void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z) - { - float len = (float)sqrtf(x * x + y * y + z * z); - float u0 = x / len; - float u1 = y / len; - float u2 = z / len; - float rad = (float)(theta / 180 * NVPi); - float c = (float)cosf(rad); - float s = (float)sinf(rad); - m[3 * 0 + 0] = u0 * u0 + c * (1 - u0 * u0) + s * 0; - m[3 * 0 + 1] = u0 * u1 + c * (0 - u0 * u1) + s * u2; - m[3 * 0 + 2] = u0 * u2 + c * (0 - u0 * u2) - s * u1; - - m[3 * 1 + 0] = u1 * u0 + c * (0 - u1 * u0) - s * u2; - m[3 * 1 + 1] = u1 * u1 + c * (1 - u1 * u1) + s * 0; - m[3 * 1 + 2] = u1 * u2 + c * (0 - u1 * u2) + s * u0; - - m[3 * 2 + 0] = u2 * u0 + c * (0 - u2 * u0) + s * u1; - m[3 * 2 + 1] = u2 * u1 + c * (0 - u2 * u1) - s * u0; - m[3 * 2 + 2] = u2 * u2 + c * (1 - u2 * u2) + s * 0; - } - - void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z) - { - float r[9]; - NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z); - NvGl2DemoMatrixMultiply_4x4_3x3(m, r); - } - - void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z) - { - float r[9]; - NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z); - NvGl2DemoMatrixMultiply_3x3(m, r); - } - - float NvGl2DemoMatrixDeterminant(float m[16]) - { - return m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] - - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] - - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] - + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] - + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] - - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] - - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] - + m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] - + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] - - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] - - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] - + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] - + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] - - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] - - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2] - + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] - + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] - - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] - - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] - + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] - + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3] - - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] - - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3] - + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; - } - - void NvGl2DemoMatrixInverse(float m[16]) - { - float a[16]; - float det; - int i; - float b[16], e[16]; - - a[4 * 0 + 0] = m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] - - m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] - + m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] - - m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] - - m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] - + m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; - a[4 * 0 + 1] = m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] - - m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] - - m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] - + m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] - + m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] - - m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; - a[4 * 0 + 2] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 1] - - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 1] - + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 2] - - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 2] - - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 3] - + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 3]; - a[4 * 0 + 3] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] - - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] - - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] - + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] - + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] - - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3]; - a[4 * 1 + 0] = m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] - - m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] - - m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] - + m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] - + m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] - - m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]; - a[4 * 1 + 1] = m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] - - m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] - + m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] - - m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] - - m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] - + m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]; - a[4 * 1 + 2] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 0] - - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 0] - - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 2] - + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 2] - + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 3] - - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 3]; - a[4 * 1 + 3] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] - - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] - + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] - - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] - - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] - + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3]; - a[4 * 2 + 0] = m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] - - m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] - + m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] - - m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] - - m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] - + m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]; - a[4 * 2 + 1] = m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] - - m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] - - m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] - + m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] - + m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] - - m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]; - a[4 * 2 + 2] = m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 0] - - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 0] - + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 1] - - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 1] - - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 3] - + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 3]; - a[4 * 2 + 3] = m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] - - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] - - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] - + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] - + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] - - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3]; - a[4 * 3 + 0] = m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] - - m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] - - m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] - + m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] - + m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] - - m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]; - a[4 * 3 + 1] = m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] - - m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] - + m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] - - m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] - - m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] - + m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]; - a[4 * 3 + 2] = m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 0] - - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 0] - - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 1] - + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 1] - + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 2] - - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 2]; - a[4 * 3 + 3] = m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] - - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] - + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] - - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] - - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] - + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2]; - - det = NvGl2DemoMatrixDeterminant(m); - - for (i = 0; i < 16; ++i) - a[i] /= det; - - NvGl2DemoMatrixIdentity(e); - - NvGl2DemoMatrixCopy(b, m); - NvGl2DemoMatrixMultiply(b, a); - - NvGl2DemoMatrixCopy(m, a); - } - - void NvGl2DemoMatrixCopy(float dest[16], float src[16]) - { - memcpy(dest, src, 16 * sizeof(float)); - } - - void NvGl2DemoMatrixPrint(float a[16]) - { - int i, j; - - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - printf("%f%c", a[4 * i + j], j == 3 ? '\n' : ' '); - } - - void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]) - { - float res[4]; - int i, j; - - for (i = 0; i < 4; ++i) { - res[i] = 0; - for (j = 0; j < 4; ++j) - res[i] += m[i * 4 + j] * v[j]; - } - - memcpy(v, res, sizeof(res)); - } -} -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.h b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.h deleted file mode 100644 index 79bfd911..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExample.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_EXAMPLE_H -#define QT3DS_RENDER_EXAMPLE_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/NvRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - class NVRenderContext; - - class NVRenderExample - { - protected: - virtual ~NVRenderExample() {} - public: - virtual void drawFrame(double currentSeconds) = 0; - virtual QT3DSU32 getRuntimeInSeconds() { return 5; } - virtual void handleKeypress(int /*keypress*/) {} - virtual void release() = 0; - }; - - typedef NVRenderExample *(*TExampleCreateFunc)(NVRenderContext &context); - - struct NVRenderExampleFactory - { - static TExampleCreateFunc *mExampleCreators; - static QT3DSU32 mMaxCreators; - static QT3DSU32 mNumCreators; - - static void addCreator(TExampleCreateFunc creator) - { - if (mNumCreators < mMaxCreators) { - mExampleCreators[mNumCreators] = creator; - ++mNumCreators; - } else - QT3DS_ASSERT(false); - } - - // Assuming that the render context is egl - // Relies on the global structures defined in demo common - // to figure out window state. - static bool nextExample(); - static void beginExamples(); - static bool update(); - static void endExamples(); - }; - - template - struct NVRenderExampleCreator - { - - static NVRenderExample *createExample(NVRenderContext &context) - { - return QT3DS_NEW(context.GetFoundation().getAllocator(), TExample)(context); - } - NVRenderExampleCreator() { NVRenderExampleFactory::addCreator(createExample); } - }; - -#define QT3DS_RENDER_REGISTER_EXAMPLE(dtype) static NVRenderExampleCreator dtype##Creator - -#define eps 1e-4 - - int eq(float a, float b); - - // Matrix functions - void NvGl2DemoMatrixIdentity(float m[16]); - int NvGl2DemoMatrixEquals(float a[16], float b[16]); - void NvGl2DemoMatrixTranspose(float m[16]); - void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]); - void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]); - void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]); - void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f); - void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f); - void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z); - void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z); - void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z); - void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z); - - float NvGl2DemoMatrixDeterminant(float m[16]); - void NvGl2DemoMatrixInverse(float m[16]); - void NvGl2DemoMatrixCopy(float dest[16], float src[16]); - - void NvGl2DemoMatrixPrint(float a[16]); - - void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]); -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.cpp b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.cpp deleted file mode 100644 index efae6f5e..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderExampleTools.h" -#include "render/Qt3DSRenderIndexBuffer.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render_util/NVRenderUtils.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSVec4.h" - -using namespace qt3ds; -using namespace qt3ds::render; - -struct BoxFace -{ - QT3DSVec3 positions[4]; - QT3DSVec3 normal; -}; - -static const BoxFace g_BoxFaces[] = { - { // Z+ - QT3DSVec3(-1, -1, 1), QT3DSVec3(-1, 1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(0, 0, 1) }, - { // X+ - QT3DSVec3(1, -1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, -1, -1), QT3DSVec3(1, 0, 0) }, - { // Z- - QT3DSVec3(1, -1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, -1, -1), - QT3DSVec3(0, 0, -1) }, - { // X- - QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, -1, 1), - QT3DSVec3(-1, 0, 0) }, - { // Y+ - QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, 1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, 1, 1), QT3DSVec3(0, 1, 0) }, - { // Y- - QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, -1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(1, -1, -1), QT3DSVec3(0, -1, 0) } -}; - -static const QT3DSVec3 g_BoxUVs[] = { - QT3DSVec3(0, 1, 0), QT3DSVec3(0, 0, 0), QT3DSVec3(1, 0, 0), QT3DSVec3(1, 1, 0), -}; - -void NVRenderExampleTools::createBox(NVRenderContext &context, - NVRenderVertexBuffer *&outVertexBuffer, - NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory) -{ - const QT3DSU32 numVerts = 24; - const QT3DSU32 numIndices = 36; - QT3DSVec3 extents = QT3DSVec3(1, 1, 1); - - NVRenderVertexBufferEntry entries[] = { - NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0), - NVRenderVertexBufferEntry("attr_norm", NVRenderComponentTypes::QT3DSF32, 3, 3 * sizeof(QT3DSF32)), - NVRenderVertexBufferEntry("attr_uv", NVRenderComponentTypes::QT3DSF32, 2, 6 * sizeof(QT3DSF32)), - }; - - QT3DSU32 bufStride = 8 * sizeof(QT3DSF32); - QT3DSU32 bufSize = bufStride * numVerts; - outVertexBuffer = context.CreateVertexBuffer( - NVRenderBufferUsageType::Static, NVConstDataRef(entries, 3), 0, - releaseMemory ? 0 : bufSize); - QT3DS_ASSERT(bufStride == outVertexBuffer->GetStride()); - NVDataRef vertData; - if (releaseMemory) - vertData = NVDataRef( - (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "VertexBufferData"), - bufSize); - else - vertData = outVertexBuffer->LockBuffer(bufSize); - QT3DSU8 *positions = (QT3DSU8 *)vertData.begin(); - QT3DSU8 *normals = positions + 3 * sizeof(QT3DSF32); - QT3DSU8 *uvs = normals + 3 * sizeof(QT3DSF32); - - for (QT3DSU32 i = 0; i < 6; i++) { - const BoxFace &bf = g_BoxFaces[i]; - for (QT3DSU32 j = 0; j < 4; j++) { - QT3DSVec3 &p = *(QT3DSVec3 *)positions; - positions = ((QT3DSU8 *)positions) + bufStride; - QT3DSVec3 &n = *(QT3DSVec3 *)normals; - normals = ((QT3DSU8 *)normals) + bufStride; - QT3DSF32 *uv = (QT3DSF32 *)uvs; - uvs = ((QT3DSU8 *)uvs) + bufStride; - n = bf.normal; - p = bf.positions[j].multiply(extents); - uv[0] = g_BoxUVs[j].x; - uv[1] = g_BoxUVs[j].y; - } - } - - if (releaseMemory) { - outVertexBuffer->SetBuffer(vertData, false); - context.GetFoundation().getAllocator().deallocate(vertData.begin()); - } else - outVertexBuffer->UnlockBuffer(); - - bufSize = numIndices * sizeof(QT3DSU16); - outIndexBuffer = - context.CreateIndexBuffer(NVRenderBufferUsageType::Static, NVRenderComponentTypes::QT3DSU16, - releaseMemory ? 0 : bufSize); - NVDataRef indexData; - if (releaseMemory) - indexData = NVDataRef( - (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "IndexData"), - bufSize); - else - indexData = outIndexBuffer->LockBuffer(bufSize); - QT3DSU16 *indices = reinterpret_cast(indexData.begin()); - for (QT3DSU8 i = 0; i < 6; i++) { - const QT3DSU16 base = i * 4; - *(indices++) = base + 0; - *(indices++) = base + 1; - *(indices++) = base + 2; - *(indices++) = base + 0; - *(indices++) = base + 2; - *(indices++) = base + 3; - } - if (releaseMemory) { - outIndexBuffer->SetBuffer(indexData, false); - context.GetFoundation().getAllocator().deallocate(indexData.begin()); - } else - outIndexBuffer->UnlockBuffer(); -} - -namespace { - -inline NVConstDataRef toRef(const char *data) -{ - size_t len = strlen(data) + 1; - return NVConstDataRef((const QT3DSI8 *)data, len); -} - -static void dumpShaderOutput(NVRenderContext &ctx, - const NVRenderVertFragCompilationResult &compResult) -{ - if (!isTrivial(compResult.mFragCompilationOutput)) { - ctx.GetFoundation().error(QT3DS_WARN, "Frag output:\n%s", compResult.mFragCompilationOutput); - } - if (!isTrivial(compResult.mVertCompilationOutput)) { - ctx.GetFoundation().error(QT3DS_WARN, "Vert output:\n%s", compResult.mVertCompilationOutput); - } - if (!isTrivial(compResult.mLinkOutput)) { - ctx.GetFoundation().error(QT3DS_WARN, "Link output:\n%s", compResult.mLinkOutput); - } -} - -NVRenderVertFragShader *compileAndDump(NVRenderContext &ctx, const char *name, - const char *vertShader, const char *fragShader) -{ - NVRenderVertFragCompilationResult compResult = - ctx.CompileSource(name, toRef(vertShader), toRef(fragShader)); - dumpShaderOutput(ctx, compResult); - return compResult.mShader; -} -} - -NVRenderVertFragShader *NVRenderExampleTools::createSimpleShader(NVRenderContext &ctx) -{ - return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShader()); -} - -NVRenderVertFragShader *NVRenderExampleTools::createSimpleShaderTex(NVRenderContext &ctx) -{ - return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShaderTex()); -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.h b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.h deleted file mode 100644 index 5b402868..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderExampleTools.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_EXAMPLE_TOOLS_H -#define QT3DS_RENDER_EXAMPLE_TOOLS_H -#include "Qt3DSRenderExample.h" - -namespace qt3ds { -namespace render { - - class NVRenderExampleTools - { - public: - static const char *getSimpleVertShader() - { - return "uniform mat4 mat_mvp;\n" - "attribute vec3 attr_pos; // Vertex pos\n" - "attribute vec3 attr_norm; // Vertex pos\n" - "attribute vec2 attr_uv; // UV coords\n" - "varying vec4 color_to_add;\n" - "varying vec2 uv_coords;\n" - "void main()\n" - "{\n" - "gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n" - "color_to_add.xyz = attr_norm * attr_norm;\n" - "color_to_add.a = 1.0;\n" - "uv_coords = attr_uv;\n" - "}\n"; - } - - static const char *getSimpleFragShader() - { - return "precision mediump sampler2D;\n" - "precision mediump float;\n" - "varying vec4 color_to_add;\n" - "void main()\n" - "{\n" - "gl_FragColor=color_to_add;\n" - "}\n"; - } - - static const char *getSimpleFragShaderTex() - { - return "precision mediump sampler2D;\n" - "precision mediump float;\n" - "uniform sampler2D image0;\n" - "varying vec2 uv_coords;\n" - "void main()\n" - "{\n" - "gl_FragColor=vec4(texture2D( image0, uv_coords ).xyz, 1.0 );\n" - "}\n"; - } - - static void createBox(NVRenderContext &context, NVRenderVertexBuffer *&outVertexBuffer, - NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory = true); - static NVRenderVertFragShader *createSimpleShader(NVRenderContext &context); - static NVRenderVertFragShader *createSimpleShaderTex(NVRenderContext &context); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderRenderToTextureExample.cpp b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderRenderToTextureExample.cpp deleted file mode 100644 index e2cb4149..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderRenderToTextureExample.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderExample.h" -#include "Qt3DSRenderExampleTools.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderIndexBuffer.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "foundation/Qt3DSVec4.h" - -using namespace qt3ds; -using namespace qt3ds::render; - -namespace { -struct ShaderArgs -{ - float mvp[16]; - NVRenderTexture2DPtr texture; - NVRenderVertFragShaderPtr shader; - ShaderArgs() {} -}; -class RenderToTexture : public NVRenderExample -{ - NVRenderContext &m_Context; - NVScopedRefCounted mVertexBuffer; - NVScopedRefCounted mIndexBuffer; - // Simple shader - NVScopedRefCounted mSimpleShader; - // Simple shader with texture lookup. - NVScopedRefCounted mSimpleShaderTex; - - NVScopedRefCounted mFrameBuffer; - NVScopedRefCounted mColorBuffer; - NVScopedRefCounted mDepthBuffer; - - NVRenderHandle mGroupId; - QT3DSU32 mFBWidth; - QT3DSU32 mFBHeight; - - ShaderArgs mShaderArgs; - float frus[16]; - float model[16]; - float rot[9]; - -public: - RenderToTexture(NVRenderContext &context) - : m_Context(context) - , mFBWidth(400) - , mFBHeight(400) - { - NVRenderExampleTools::createBox(m_Context, mVertexBuffer.mPtr, mIndexBuffer.mPtr); - mVertexBuffer->addRef(); - mIndexBuffer->addRef(); - mSimpleShader = NVRenderExampleTools::createSimpleShader(m_Context); - mSimpleShaderTex = NVRenderExampleTools::createSimpleShaderTex(m_Context); - // If you don't want the depth buffer information back out of the system, then you can - // do this. - // mDepthBuffer = m_Context.CreateRenderBuffer( NVRenderRenderBufferFormats::Depth16, - // mFBWidth, mFBHeight ); - - mDepthBuffer = m_Context.CreateTexture2D(); - mDepthBuffer->SetTextureData(NVDataRef(), 0, mFBWidth, mFBHeight, - NVRenderTextureFormats::Depth16); - mColorBuffer = m_Context.CreateTexture2D(); - mColorBuffer->SetTextureData(NVDataRef(), 0, mFBWidth, mFBHeight, - NVRenderTextureFormats::RGBA8); - if (mDepthBuffer.mPtr && mColorBuffer.mPtr) { - // Creating objects tends to Bind them to their active state hooks. - // So to protect the rest of the system against what they are doing (if we care), we - // need - // to push the current state - // Auto-binds the framebuffer. - mFrameBuffer = m_Context.CreateFrameBuffer(); - mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *mColorBuffer.mPtr); - mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Depth, *mDepthBuffer.mPtr); - QT3DS_ASSERT(mFrameBuffer->IsComplete()); - - m_Context.SetRenderTarget(NULL); - } - mColorBuffer->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - mColorBuffer->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - m_Context.SetVertexBuffer(mVertexBuffer); - m_Context.SetIndexBuffer(mIndexBuffer); - m_Context.SetDepthTestEnabled(true); - m_Context.SetDepthWriteEnabled(true); - m_Context.SetClearColor(QT3DSVec4(.3f)); - // Setup various matrici - NvGl2DemoMatrixIdentity(model); - NvGl2DemoMatrixIdentity(frus); - NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10); - NvGl2DemoMatrixTranslate(model, 0, 0, -4); - mShaderArgs.texture = mColorBuffer.mPtr; - } - void setupMVP(QT3DSVec3 translation) - { - float *mvp(mShaderArgs.mvp); - memCopy(mvp, frus, 16 * sizeof(float)); - NvGl2DemoMatrixMultiply(mvp, model); - NvGl2DemoMatrixTranslate(mvp, translation.x, translation.y, translation.z); - NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot); - } - void DrawIndexedArrays(QT3DSVec3 translation) - { - setupMVP(translation); - m_Context.SetActiveShader(mShaderArgs.shader); - mShaderArgs.shader->Bind(); - mShaderArgs.shader->SetPropertyValue("mat_mvp", - *reinterpret_cast(mShaderArgs.mvp)); - mShaderArgs.shader->SetPropertyValue("image0", mShaderArgs.texture); - m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0); - } - - virtual void drawFrame(double currentSeconds) - { - NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0); - NVRenderClearFlags clearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth); - // render to frame buffer - { - NVRenderContextScopedProperty __framebuffer( - m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget, - mFrameBuffer); - NVRenderContextScopedProperty __viewport( - m_Context, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, - NVRenderRect(0, 0, mFBWidth, mFBHeight)); - NVRenderContextScopedProperty __clearColor( - m_Context, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - QT3DSVec4(.6f)); - m_Context.Clear(clearFlags); - mShaderArgs.shader = mSimpleShader; - DrawIndexedArrays(QT3DSVec3(0.f)); - } - m_Context.Clear(clearFlags); - mShaderArgs.texture = mColorBuffer; - mShaderArgs.shader = mSimpleShaderTex; - - DrawIndexedArrays(QT3DSVec3(-2.f, 0.f, 0.f)); - - mShaderArgs.texture = mDepthBuffer; - DrawIndexedArrays(QT3DSVec3(2.f, 0.f, 0.f)); - } - virtual QT3DSU32 getRuntimeInSeconds() - { - return mSimpleShader.mPtr && mSimpleShaderTex.mPtr ? 5 : 0; - } - virtual void release() { NVDelete(m_Context.GetFoundation(), this); } -}; -} - -QT3DS_RENDER_REGISTER_EXAMPLE(RenderToTexture); \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderSpinningCubeExample.cpp b/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderSpinningCubeExample.cpp deleted file mode 100644 index 807f0821..00000000 --- a/src/Runtime/Source/Qt3DSRender/Examples/Qt3DSRenderSpinningCubeExample.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderExample.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderIndexBuffer.h" -#include "render/NVRenderVertFragShader.h" -#include "render_util/NVRenderUtils.h" -#include "Qt3DSRenderExampleTools.h" -#include "foundation/Qt3DSMat44.h" - -using namespace qt3ds; -using namespace qt3ds::render; - -#pragma warning(disable : 4189) -#pragma warning(disable : 4100) - -namespace { - -struct ShaderArguments -{ - QT3DSMat44 mMatrix; -}; - -class SpinningCube : public NVRenderExample -{ - NVRenderContext &m_Context; - NVScopedRefCounted mVertexBuffer; - NVScopedRefCounted mIndexBuffer; - NVScopedRefCounted mShader; - NVRenderHandle mShaderArgGroupId; - float frus[16]; - float model[16]; - float rot[9]; - -public: - SpinningCube(NVRenderContext &ctx) - : m_Context(ctx) - { - NVRenderExampleTools::createBox(ctx, mVertexBuffer.mPtr, mIndexBuffer.mPtr, false); - mVertexBuffer->addRef(); - mIndexBuffer->addRef(); - mShader = NVRenderExampleTools::createSimpleShader(ctx); - ctx.SetViewport(NVRenderRect(0, 0, 400, 400)); - // These properties will get applied just before render no matter what - // so we can just use the default settings here. - ctx.SetVertexBuffer(mVertexBuffer); - ctx.SetIndexBuffer(mIndexBuffer); - if (mShader) { - ctx.SetActiveShader(mShader); - } - ctx.SetDepthTestEnabled(true); - ctx.SetDepthWriteEnabled(true); - NvGl2DemoMatrixIdentity(model); - NvGl2DemoMatrixIdentity(frus); - NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10); - NvGl2DemoMatrixTranslate(model, 0, 0, -4); - } - virtual void drawFrame(double currentSeconds) - { - NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0); - float mvp[16]; - NvGl2DemoMatrixIdentity(mvp); - NvGl2DemoMatrixMultiply(mvp, frus); - NvGl2DemoMatrixMultiply(mvp, model); - NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot); - - NVConstDataRef instance((QT3DSU8 *)mvp, 16 * sizeof(float)); - m_Context.Clear( - NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth)); - mShader->SetPropertyValue("mat_mvp", *reinterpret_cast(mvp)); - m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0); - } - virtual QT3DSU32 getRuntimeInSeconds() { return mShader.mPtr ? 5 : 0; } - virtual void release() { NVDelete(m_Context.GetFoundation(), this); } -}; -} -QT3DS_RENDER_REGISTER_EXAMPLE(SpinningCube); \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAtomicCounterBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAtomicCounterBuffer.h deleted file mode 100644 index 5ff449ea..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAtomicCounterBuffer.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H -#include "foundation/Qt3DSOption.h" -#include "foundation/Utils.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderDataBuffer.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - // forward declaration - class NVRenderContextImpl; - class AtomicCounterBufferEntry; - - typedef nvhash_map - TRenderAtomiCounterBufferEntryMap; - - ///< Constant (uniform) buffer representation - class QT3DS_AUTOTEST_EXPORT NVRenderAtomicCounterBuffer : public NVRenderDataBuffer - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] bufferName Name of the buffer. Must match the name used in programs - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return No return. - */ - NVRenderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, - size_t size, NVRenderBufferUsageType::Enum usageType, - NVDataRef data); - - ///< destructor - virtual ~NVRenderAtomicCounterBuffer(); - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - void Bind() override; - - /** - * @brief bind the buffer to a shader program - * - * @param[in] index Index of the constant buffer within the program - * - * @return no return. - */ - virtual void BindToShaderProgram(QT3DSU32 index); - - /** - * @brief update the buffer to hardware - * - * @return no return. - */ - virtual void Update(); - - /** - * @brief update a piece of memory directly within the storage buffer - * - * Note: When you use this function you should know what you are doing. - * The memory layout within C++ must exactly match the memory layout in the - *shader. - * We use std140 (430) layout which guarantees a specific layout behavior across - *all HW vendors. - * How the memory layout is computed can be found in the GL spec. - * - * @param[in] offset offset into storage buffer - * @param[in] data pointer to data - * - * @return no return - */ - void UpdateData(QT3DSI32 offset, NVDataRef data); - - /** - * @brief add a parameter to the atomic counter buffer - * - * @param[in] name Name of the parameter (must match the name in the shader - * program) - * @param[in] offset Offset in bytes into the buffer - * - * @return no return - */ - void AddParam(CRegisteredString name, QT3DSU32 offset); - - /** - * @brief Check if the buffer contains this param - * - * @param[in] name Name of the parameter (must match the name in the shader - * program) - * - * @return no return - */ - bool ContainsParam(CRegisteredString name); - - /** - * @brief get the buffer name - * - * @return the buffer name - */ - CRegisteredString GetBufferName() const { return m_Name; } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - /** - * @brief create a NVRenderAtomicCounterBuffer object - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return the buffer object or NULL - */ - static NVRenderAtomicCounterBuffer *Create(NVRenderContextImpl &context, - const char *bufferName, - NVRenderBufferUsageType::Enum usageType, - size_t size, NVConstDataRef bufferData); - - private: - CRegisteredString m_Name; ///< buffer name - TRenderAtomiCounterBufferEntryMap - m_AtomicCounterBufferEntryMap; ///< holds the entries of a atomic counter buffer - bool m_Dirty; ///< true if buffer is dirty - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAttribLayout.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAttribLayout.h deleted file mode 100644 index da801c8e..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderAttribLayout.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_ATTRIB_LAYOUT_H -#define QT3DS_RENDER_ATTRIB_LAYOUT_H - -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Utils.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - // forward declarations - class NVRenderContextImpl; - class NVRenderBackend; - - ///< this class handles the vertex attribute layout setup - class NVRenderAttribLayout : public NVRefCounted - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] attribs Pointer to attribute list - * - * @return No return. - */ - NVRenderAttribLayout(NVRenderContextImpl &context, - NVConstDataRef attribs); - ///< destructor - ~NVRenderAttribLayout(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendAttribLayoutObject GetAttribLayoutHandle() const - { - return m_AttribLayoutHandle; - } - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - - NVRenderBackend::NVRenderBackendAttribLayoutObject - m_AttribLayoutHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h deleted file mode 100644 index c988b2f1..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h +++ /dev/null @@ -1,2100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_TYPES_H -#define QT3DS_RENDER_QT3DS_RENDER_TYPES_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSMath.h" -#include "foundation/Qt3DSVec2.h" - -namespace qt3ds { - -namespace render { -using namespace foundation; - -#define QT3DS_RENDER_ITERATE_COMPONENT_TYPES \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU8) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI8) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU16) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI16) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU32) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI32) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU64) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI64) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF16) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF32) \ - QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF64) - -struct NVRenderComponentTypes -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) x, - QT3DS_RENDER_ITERATE_COMPONENT_TYPES -#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_COMPONENT_TYPES - #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE - default: - break; - } - return "Unknown"; - } - - static qt3ds::QT3DSU32 getSizeofType(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ - case x: \ - return sizeof(qt3ds::x); - QT3DS_RENDER_ITERATE_COMPONENT_TYPES - #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } -}; - -/** - Define a set of compile-time trait classes that map the enumerations - to actual compile time types and sizeof so we can deal with the enumeration - in generic ways. - */ -template -struct NVRenderComponentTraits -{ - bool force_compile_error; -}; - -/** - Define a compile time mapping from datatype to enumeration. Not that if you - use this with a type that isn't a component type you will get a compilation - error. - */ -template -struct NVRenderComponentTypeToTypeMap -{ - bool force_compile_error; -}; - -#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ - template <> \ - struct NVRenderComponentTraits \ -{ \ - typedef x TComponentType; \ - QT3DSU8 mComponentSize; \ - NVRenderComponentTraits() \ - : mComponentSize(sizeof(x)) \ -{ \ -} \ -}; \ - template <> \ - struct NVRenderComponentTypeToTypeMap \ -{ \ - NVRenderComponentTypes::Enum m_ComponentType; \ - NVRenderComponentTypeToTypeMap() \ - : m_ComponentType(NVRenderComponentTypes::x) \ -{ \ -} \ -}; - -QT3DS_RENDER_ITERATE_COMPONENT_TYPES; - -#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE - -// Map at compile time from component type to datatype; -template -inline NVRenderComponentTypes::Enum getComponentTypeForType() -{ - return NVRenderComponentTypeToTypeMap().m_ComponentType; -} - -struct NVRenderContextValues -{ - enum Enum { - GLES2 = 1 << 0, - GL2 = 1 << 1, - GLES3 = 1 << 2, - GL3 = 1 << 3, - GLES3PLUS = 1 << 4, - GL4 = 1 << 5, - NullContext = 1 << 6, - }; -}; - -typedef NVFlags NVRenderContextType; - -struct NVRenderClearValues -{ - enum Enum { - Color = 1 << 0, - Depth = 1 << 1, - Stencil = 1 << 3, - Coverage = 1 << 4, - }; -}; - -typedef NVFlags NVRenderClearFlags; - -struct NVRenderQueryType -{ - enum Enum { - Unknown = 0, - Samples, ///< samples query object - Timer, ///< timer query object - }; -}; - -struct NVRenderQueryResultType -{ - enum Enum { - Unknown = 0, - ResultAvailable, ///< Check if query result is available - Result, ///< Get actual result - }; -}; - -struct NVRenderSyncType -{ - enum Enum { - Unknown = 0, - GpuCommandsComplete, ///< sync to Gpu commands finished - }; -}; - -struct NVRenderSyncValues -{ - enum Enum { - Unknown = 0, ///< for future usage - }; -}; - -typedef NVFlags NVRenderSyncFlags; - -struct NVRenderCommandFlushValues -{ - enum Enum { - SyncFlushCommands = 0, ///< sync for flushing command - }; -}; - -typedef NVFlags NVRenderCommandFlushFlags; - -struct NVRenderBufferBindValues -{ - enum Enum { - Unknown = 0, - Vertex = 1 << 0, ///< Bind as vertex buffer - Index = 1 << 1, ///< Bind as index buffer - Constant = 1 << 2, ///< Bind as constant buffer - Storage = 1 << 3, ///< Bind as shader storage buffer - Atomic_Counter = 1 << 4, ///< Bind as atomic counter buffer - Draw_Indirect = 1 << 5, ///< Bind as draw indirect buffer - }; -}; - -typedef NVFlags NVRenderBufferBindFlags; - -struct NVRenderBufferUsageType -{ - enum Enum { - Unknown = 0, - Static, ///< Rarely updated - Dynamic, ///< Most likely updated every frame - }; -}; - -struct NVRenderImageAccessType -{ - enum Enum { - Unknown = 0, - Read, ///< Read only access - Write, ///< Write only access - ReadWrite, ///< Read and write access - }; -}; - -struct NVRenderBufferAccessTypeValues -{ - enum Enum { - Unknown = 0, - Read = 1 << 0, ///< Read access - Write = 1 << 1, ///< Write access - Invalid = 1 << 2, ///< No sync - InvalidRange = 1 << 3, ///< No sync - - }; -}; - -typedef NVFlags NVRenderBufferAccessFlags; - -///< defines a barrier of ordering the memory transactions to a command relative to those issued -///before the barrier -struct NVRenderBufferBarrierValues -{ - enum Enum { - Unknown = 0, - VertexAttribArray = 1 << 0, ///< Barrier for vertex attributes sourced from a buffer - ElementArray = 1 << 1, ///< Barrier for indices sourced from a buffer - UniformBuffer = 1 << 2, ///< Barrier for shader uniforms sourced from a buffer - TextureFetch = 1 << 3, ///< Barrier for texture fetches within shaders - ShaderImageAccess = 1 << 4, ///< Barrier for image access using load / store - CommandBuffer = 1 << 5, ///< Barrier for indirect drawing - PixelBuffer = 1 << 6, ///< Barrier for pixel buffer access - TextureUpdate = 1 << 7, ///< Barrier for texture writes - BufferUpdate = 1 << 8, ///< Barrier for buffer writes - Framebuffer = 1 << 9, ///< Barrier for framebuffer writes - TransformFeedback = 1 << 10, ///< Barrier for transform feedback writes - AtomicCounter = 1 << 11, ///< Barrier for atomic counter writes - ShaderStorage = 1 << 12, ///< Barrier for shader storage blocks writes - All = 0xFFFF, ///< Barrier for all of the above - }; -}; - -typedef NVFlags NVRenderBufferBarrierFlags; - -#define QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA4) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGB565) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA5551) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth16) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth24) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth32) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(StencilIndex8) \ - QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(CoverageNV) - -struct NVRenderRenderBufferFormats -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) x, - QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS -#undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS - #undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_TEXTURE_FORMATS \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32I) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32UI) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8A8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB565) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA5551) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Alpha8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance16) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(LuminanceAlpha8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA16F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG16F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R11G11B10) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB9E5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT1) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_DXT1) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT3) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC1) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC2) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_ETC2) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_PunchThrough_Alpha1_ETC2) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_PunchThrough_Alpha1_ETC2) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_UNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_SNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_UNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_SNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA8_ETC2_EAC) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ETC2_EAC) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_UNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_SNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_UNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_SNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNSIGNED_FLOAT) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_SIGNED_FLOAT) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNorm) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_4x4) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x4) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x6) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x6) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x8) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x6) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x8) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x10) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x10) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x12) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_4x4) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x4) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x6) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x6) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x8) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x6) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x8) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x10) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x10) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x12) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth16) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth32) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24Stencil8) - -struct NVRenderTextureFormats -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) x, -#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) x, -#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) x, - QT3DS_RENDER_ITERATE_TEXTURE_FORMATS -#undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT -#undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT -#undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT - }; - - static bool isUncompressedTextureFormat(NVRenderTextureFormats::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \ - case NVRenderTextureFormats::x: \ - return true; -#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) -#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) - QT3DS_RENDER_ITERATE_TEXTURE_FORMATS - #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT - default: - break; - } - return false; - } - - static bool isCompressedTextureFormat(NVRenderTextureFormats::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) -#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \ - case NVRenderTextureFormats::x: \ - return true; -#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) - QT3DS_RENDER_ITERATE_TEXTURE_FORMATS - #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT - default: - break; - } - return false; - } - - static bool isDepthTextureFormat(NVRenderTextureFormats::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) -#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) -#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \ - case NVRenderTextureFormats::x: \ - return true; - QT3DS_RENDER_ITERATE_TEXTURE_FORMATS - #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT - default: - break; - } - return false; - } - - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \ - case x: \ - return #x; -#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \ - case x: \ - return #x; -#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_TEXTURE_FORMATS - #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT - #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT - default: - break; - } - return "Unknown"; - } - - static QT3DSU32 getSizeofFormat(Enum value) - { - switch (value) { - case R8: - return 1; - case R16F: - return 2; - case R16: - return 2; - case R32I: - return 4; - case R32F: - return 4; - case RGBA8: - return 4; - case RGB8: - return 3; - case RGB565: - return 2; - case RGBA5551: - return 2; - case Alpha8: - return 1; - case Luminance8: - return 1; - case LuminanceAlpha8: - return 1; - case Depth16: - return 2; - case Depth24: - return 3; - case Depth32: - return 4; - case Depth24Stencil8: - return 4; - case RGB9E5: - return 4; - case SRGB8: - return 3; - case SRGB8A8: - return 4; - case RGBA16F: - return 8; - case RG16F: - return 4; - case RG32F: - return 8; - case RGBA32F: - return 16; - case RGB32F: - return 12; - case R11G11B10: - return 4; - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static QT3DSU32 getNumberOfComponent(Enum value) - { - switch (value) { - case R8: - return 1; - case R16F: - return 1; - case R16: - return 1; - case R32I: - return 1; - case R32F: - return 1; - case RGBA8: - return 4; - case RGB8: - return 3; - case RGB565: - return 3; - case RGBA5551: - return 4; - case Alpha8: - return 1; - case Luminance8: - return 1; - case LuminanceAlpha8: - return 2; - case Depth16: - return 1; - case Depth24: - return 1; - case Depth32: - return 1; - case Depth24Stencil8: - return 2; - case RGB9E5: - return 3; - case SRGB8: - return 3; - case SRGB8A8: - return 4; - case RGBA16F: - return 4; - case RG16F: - return 2; - case RG32F: - return 2; - case RGBA32F: - return 4; - case RGB32F: - return 3; - case R11G11B10: - return 3; - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static void decodeToFloat(void *inPtr, QT3DSU32 byteOfs, float *outPtr, - NVRenderTextureFormats::Enum inFmt) - { - outPtr[0] = 0.0f; - outPtr[1] = 0.0f; - outPtr[2] = 0.0f; - outPtr[3] = 0.0f; - QT3DSU8 *src = reinterpret_cast(inPtr); - // float divisor; // If we want to support RGBD? - switch (inFmt) { - case Alpha8: - outPtr[0] = ((float)src[byteOfs]) / 255.0f; - break; - - case Luminance8: - case LuminanceAlpha8: - case R8: - case RG8: - case RGB8: - case RGBA8: - case SRGB8: - case SRGB8A8: - // NOTE : RGBD Hack here for reference. Not meant for installation. - // divisor = (NVRenderTextureFormats::getSizeofFormat(inFmt) == 4) ? - // ((float)src[byteOfs+3]) / 255.0f : 1.0f; - for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) { - float val = ((float)src[byteOfs + i]) / 255.0f; - outPtr[i] = (i < 3) ? powf(val, 0.4545454545f) : val; - // Assuming RGBA8 actually means RGBD (which is stupid, I know) - // if ( NVRenderTextureFormats::getSizeofFormat(inFmt) == 4 ) { outPtr[i] /= - // divisor; } - } - // outPtr[3] = divisor; - break; - - case R32F: - outPtr[0] = reinterpret_cast(src + byteOfs)[0]; - break; - case RG32F: - outPtr[0] = reinterpret_cast(src + byteOfs)[0]; - outPtr[1] = reinterpret_cast(src + byteOfs)[1]; - break; - case RGBA32F: - outPtr[0] = reinterpret_cast(src + byteOfs)[0]; - outPtr[1] = reinterpret_cast(src + byteOfs)[1]; - outPtr[2] = reinterpret_cast(src + byteOfs)[2]; - outPtr[3] = reinterpret_cast(src + byteOfs)[3]; - break; - case RGB32F: - outPtr[0] = reinterpret_cast(src + byteOfs)[0]; - outPtr[1] = reinterpret_cast(src + byteOfs)[1]; - outPtr[2] = reinterpret_cast(src + byteOfs)[2]; - break; - - case R16F: - case RG16F: - case RGBA16F: - for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) { - // NOTE : This only works on the assumption that we don't have any denormals, - // Infs or NaNs. - // Every pixel in our source image should be "regular" - QT3DSU16 h = reinterpret_cast(src + byteOfs)[i]; - QT3DSU32 sign = (h & 0x8000) << 16; - QT3DSU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); - QT3DSU32 mantissa = ((h & 0x3ff) << 13); - QT3DSU32 result = sign | exponent | mantissa; - - if (h == 0 || h == 0x8000) { - result = 0; - } // Special case for zero and negative zero - qt3ds::intrinsics::memCopy(reinterpret_cast(outPtr) + i, &result, 4); - } - break; - - case R11G11B10: - // place holder - QT3DS_ASSERT(false); - break; - - default: - outPtr[0] = 0.0f; - outPtr[1] = 0.0f; - outPtr[2] = 0.0f; - outPtr[3] = 0.0f; - break; - } - } - - static void encodeToPixel(float *inPtr, void *outPtr, QT3DSU32 byteOfs, - NVRenderTextureFormats::Enum inFmt) - { - QT3DSU8 *dest = reinterpret_cast(outPtr); - switch (inFmt) { - case NVRenderTextureFormats::Alpha8: - dest[byteOfs] = QT3DSU8(inPtr[0] * 255.0f); - break; - - case Luminance8: - case LuminanceAlpha8: - case R8: - case RG8: - case RGB8: - case RGBA8: - case SRGB8: - case SRGB8A8: - for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) { - inPtr[i] = (inPtr[i] > 1.0f) ? 1.0f : inPtr[i]; - if (i < 3) - dest[byteOfs + i] = QT3DSU8(powf(inPtr[i], 2.2f) * 255.0f); - else - dest[byteOfs + i] = QT3DSU8(inPtr[i] * 255.0f); - } - break; - - case R32F: - reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; - break; - case RG32F: - reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; - reinterpret_cast(dest + byteOfs)[1] = inPtr[1]; - break; - case RGBA32F: - reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; - reinterpret_cast(dest + byteOfs)[1] = inPtr[1]; - reinterpret_cast(dest + byteOfs)[2] = inPtr[2]; - reinterpret_cast(dest + byteOfs)[3] = inPtr[3]; - break; - case RGB32F: - reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; - reinterpret_cast(dest + byteOfs)[1] = inPtr[1]; - reinterpret_cast(dest + byteOfs)[2] = inPtr[2]; - break; - - case R16F: - case RG16F: - case RGBA16F: - for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) { - // NOTE : This also has the limitation of not handling infs, NaNs and - // denormals, but it should be - // sufficient for our purposes. - if (inPtr[i] > 65519.0f) { - inPtr[i] = 65519.0f; - } - if (fabs(inPtr[i]) < 6.10352E-5f) { - inPtr[i] = 0.0f; - } - QT3DSU32 f = reinterpret_cast(inPtr)[i]; - QT3DSU32 sign = (f & 0x80000000) >> 16; - QT3DSI32 exponent = (f & 0x7f800000) >> 23; - QT3DSU32 mantissa = (f >> 13) & 0x3ff; - exponent = exponent - 112; - if (exponent > 31) { - exponent = 31; - } - if (exponent < 0) { - exponent = 0; - } - exponent = exponent << 10; - reinterpret_cast(dest + byteOfs)[i] = - QT3DSU16(sign | exponent | mantissa); - } - break; - - case R11G11B10: - // place holder - QT3DS_ASSERT(false); - break; - - default: - dest[byteOfs] = 0; - dest[byteOfs + 1] = 0; - dest[byteOfs + 2] = 0; - dest[byteOfs + 3] = 0; - break; - } - } -}; - -struct NVRenderTextureTargetType -{ - enum Enum { - Unknown = 0, - Texture2D, - Texture2D_MS, - Texture2D_Array, - TextureCube, - TextureCubePosX, - TextureCubeNegX, - TextureCubePosY, - TextureCubeNegY, - TextureCubePosZ, - TextureCubeNegZ, - }; -}; - -struct NVRenderTextureUnit -{ - enum Enum { - TextureUnit_0 = 0, - TextureUnit_1, - TextureUnit_2, - TextureUnit_3, - TextureUnit_4, - TextureUnit_5, - TextureUnit_6, - TextureUnit_7, - TextureUnit_8, - TextureUnit_9, - TextureUnit_10, - TextureUnit_11, - TextureUnit_12, - TextureUnit_13, - TextureUnit_14, - TextureUnit_15, - TextureUnit_16, - TextureUnit_17, - TextureUnit_18, - TextureUnit_19, - TextureUnit_20, - TextureUnit_21, - TextureUnit_22, - TextureUnit_23, - TextureUnit_24, - TextureUnit_25, - TextureUnit_26, - TextureUnit_27, - TextureUnit_28, - TextureUnit_29, - TextureUnit_30, - TextureUnit_31 - }; -}; - -struct NVRenderTextureCompareMode -{ - enum Enum { Unknown = 0, NoCompare, CompareToRef }; -}; - -struct NVRenderTextureSwizzleMode -{ - enum Enum { NoSwizzle = 0, L8toR8, A8toR8, L8A8toRG8, L16toR16 }; -}; - -#define QT3DS_RENDER_ITERATE_BOOL_OP \ - QT3DS_RENDER_HANDLE_BOOL_OP(Never) \ - QT3DS_RENDER_HANDLE_BOOL_OP(Less) \ - QT3DS_RENDER_HANDLE_BOOL_OP(LessThanOrEqual) \ - QT3DS_RENDER_HANDLE_BOOL_OP(Equal) \ - QT3DS_RENDER_HANDLE_BOOL_OP(NotEqual) \ - QT3DS_RENDER_HANDLE_BOOL_OP(Greater) \ - QT3DS_RENDER_HANDLE_BOOL_OP(GreaterThanOrEqual) \ - QT3DS_RENDER_HANDLE_BOOL_OP(AlwaysTrue) - -struct NVRenderTextureCompareOp -{ - enum Enum { -#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x, - QT3DS_RENDER_ITERATE_BOOL_OP -#undef QT3DS_RENDER_HANDLE_BOOL_OP - }; -}; - -#define QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP \ - QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Nearest) \ - QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Linear) \ - QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapNearest) \ - QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapNearest) \ - QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapLinear) \ - QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapLinear) - -struct NVRenderTextureMinifyingOp -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x, -#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) x, - QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP -#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP -#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP - }; - const char *toString(NVRenderTextureMinifyingOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \ - case x: \ - return #x; -#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP - #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP - #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP - default: - break; - } - return "Unknown"; - } -}; - -struct NVRenderTextureMagnifyingOp -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x, -#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) - QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP -#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP -#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP - }; - const char *toString(NVRenderTextureMinifyingOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \ - case x: \ - return #x; -#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) - QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP - #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP - #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP \ - QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(ClampToEdge) \ - QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(MirroredRepeat) \ - QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(Repeat) - -struct NVRenderTextureCoordOp -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) x, - QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP -#undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP - }; - const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP - #undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_HINT \ - QT3DS_RENDER_HANDLE_HINT(Fastest) \ - QT3DS_RENDER_HANDLE_HINT(Nicest) \ - QT3DS_RENDER_HANDLE_HINT(Unspecified) - -struct NVRenderHint -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_HINT(x) x, - QT3DS_RENDER_ITERATE_HINT -#undef QT3DS_RENDER_HANDLE_HINT - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_HINT(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_HINT - #undef QT3DS_RENDER_HANDLE_HINT - default: - break; - } - return "Unknown"; - } -}; - -class NVRenderImplemented -{ -protected: - virtual ~NVRenderImplemented() {} -public: - // Get the handle that binds us to the implementation. - // For instance, return the GLuint that came back from - // glGenTextures. - virtual const void *GetImplementationHandle() const = 0; -}; - -struct NVRenderVertexBufferEntry -{ - const char *m_Name; - /** Datatype of the this entry points to in the buffer */ - NVRenderComponentTypes::Enum m_ComponentType; - /** Number of components of each data member. 1,2,3, or 4. Don't be stupid.*/ - QT3DSU32 m_NumComponents; - /** Offset from the beginning of the buffer of the first item */ - QT3DSU32 m_FirstItemOffset; - /** Attribute input slot used for this entry*/ - QT3DSU32 m_InputSlot; - - NVRenderVertexBufferEntry(const char *nm, NVRenderComponentTypes::Enum type, - QT3DSU32 numComponents, QT3DSU32 firstItemOffset = 0, - QT3DSU32 inputSlot = 0) - : m_Name(nm) - , m_ComponentType(type) - , m_NumComponents(numComponents) - , m_FirstItemOffset(firstItemOffset) - , m_InputSlot(inputSlot) - { - } - - NVRenderVertexBufferEntry() - : m_Name(NULL) - , m_ComponentType(NVRenderComponentTypes::Unknown) - , m_NumComponents(0) - , m_FirstItemOffset(0) - , m_InputSlot(0) - { - } - - NVRenderVertexBufferEntry(const NVRenderVertexBufferEntry &inOther) - : m_Name(inOther.m_Name) - , m_ComponentType(inOther.m_ComponentType) - , m_NumComponents(inOther.m_NumComponents) - , m_FirstItemOffset(inOther.m_FirstItemOffset) - , m_InputSlot(inOther.m_InputSlot) - { - } - - NVRenderVertexBufferEntry &operator=(const NVRenderVertexBufferEntry &inOther) - { - if (this != &inOther) { - m_Name = inOther.m_Name; - m_ComponentType = inOther.m_ComponentType; - m_NumComponents = inOther.m_NumComponents; - m_FirstItemOffset = inOther.m_FirstItemOffset; - m_InputSlot = inOther.m_InputSlot; - } - return *this; - } -}; - -class NVRenderShaderProgram; - -typedef NVConstDataRef TConstI8Ref; - -struct NVRenderVertFragCompilationResult -{ - const char *mShaderName; - - NVRenderShaderProgram *mShader; ///< contains the program - - NVRenderVertFragCompilationResult() - : mShaderName("") - , mShader(NULL) - { - } -}; - -#define QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color0) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color1) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color2) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color3) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color4) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color5) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color6) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color7) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Depth) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Stencil) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(DepthStencil) \ - QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(CoverageNV) - -struct NVRenderFrameBufferAttachments -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(x) x, - QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS -#undef QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT - LastAttachment, - }; -}; - -struct NVRenderDrawMode -{ - enum Enum { - Unknown = 0, - Points, - LineStrip, - LineLoop, - Lines, - TriangleStrip, - TriangleFan, - Triangles, - Patches, - }; -}; - -struct NVRenderTextureCubeFaces -{ - enum Enum { - InvalidFace = 0, - CubePosX = 1, - CubeNegX, - CubePosY, - CubeNegY, - CubePosZ, - CubeNegZ, - }; -}; - -// enums match the NV path extensions -struct NVRenderPathCommands -{ - enum Enum { - Close = 0, - MoveTo = 2, - CubicCurveTo = 12, - }; -}; - -struct NVRenderPathFontTarget -{ - enum Enum { - StandardFont = 0, - SystemFont = 1, - FileFont = 2, - }; -}; - -struct NVRenderPathMissingGlyphs -{ - enum Enum { - SkipMissing = 0, - UseMissing = 1, - }; -}; - -struct NVRenderPathFontStyleValues -{ - enum Enum { - Bold = 1 << 0, - Italic = 1 << 1, - }; -}; - -typedef NVFlags NVRenderPathFontStyleFlags; - -struct NVRenderPathReturnValues -{ - enum Enum { - FontGlypsAvailable = 0, - FontTargetUnavailable = 1, - FontUnavailable = 2, - FontUnintelligible = 3, - InvalidEnum = 4, - OutOfMemory = 5, - }; -}; - -struct NVRenderPathFormatType -{ - enum Enum { - Byte = 1, - UByte, - Short, - UShort, - Int, - Uint, - Float, - Utf8, - Utf16, - Bytes2, - Bytes3, - Bytes4, - }; -}; - -struct NVRenderPathGlyphFontMetricValues -{ - enum Enum { - GlyphWidth = 1 << 0, - GlyphHeight = 1 << 1, - GlyphHorizontalBearingX = 1 << 2, - GlyphHorizontalBearingY = 1 << 3, - GlyphHorizontalBearingAdvance = 1 << 4, - GlyphVerticalBearingX = 1 << 5, - GlyphVerticalBearingY = 1 << 6, - GlyphVerticalBearingAdvance = 1 << 7, - GlyphHasKerning = 1 << 8, - - FontXMinBounds = 1 << 9, - FontYMinBounds = 1 << 10, - FontXMaxBounds = 1 << 11, - FontYMaxBounds = 1 << 12, - FontUnitsPerEm = 1 << 13, - FontAscender = 1 << 14, - FontDescender = 1 << 15, - FontHeight = 1 << 16, - FontMaxAdvanceWidth = 1 << 17, - FontMaxAdvanceHeight = 1 << 18, - FontUnderlinePosition = 1 << 19, - FontUnderlineThickness = 1 << 20, - FontHasKerning = 1 << 21, - FontNumGlyphIndices = 1 << 22, - }; -}; - -typedef NVFlags -NVRenderPathGlyphFontMetricFlags; - -struct NVRenderPathListMode -{ - enum Enum { - AccumAdjacentPairs = 1, - AdjacentPairs, - FirstToRest, - }; -}; - -struct NVRenderPathFillMode -{ - enum Enum { - Fill = 1, - CountUp, - CountDown, - Invert, - }; -}; - -struct NVRenderPathCoverMode -{ - enum Enum { - ConvexHull = 1, - BoundingBox, - BoundingBoxOfBoundingBox, - PathFillCover, - PathStrokeCover, - }; -}; - -struct NVRenderPathTransformType -{ - enum Enum { - NoTransform = 0, - TranslateX, - TranslateY, - Translate2D, - Translate3D, - Affine2D, - Affine3D, - TransposeAffine2D, - TransposeAffine3D, - }; -}; - -#define QT3DS_RENDER_ITERATE_WINDING \ - QT3DS_RENDER_HANDLE_WINDING(Clockwise) \ - QT3DS_RENDER_HANDLE_WINDING(CounterClockwise) - -struct NVRenderWinding -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_WINDING(x) x, - QT3DS_RENDER_ITERATE_WINDING -#undef QT3DS_RENDER_HANDLE_WINDING - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_WINDING(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_WINDING - #undef QT3DS_RENDER_HANDLE_WINDING - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_RENDER_STATE \ - QT3DS_RENDER_HANDLE_RENDER_STATE(Blend) \ - QT3DS_RENDER_HANDLE_RENDER_STATE(CullFace) \ - QT3DS_RENDER_HANDLE_RENDER_STATE(DepthTest) \ - QT3DS_RENDER_HANDLE_RENDER_STATE(StencilTest) \ - QT3DS_RENDER_HANDLE_RENDER_STATE(ScissorTest) \ - QT3DS_RENDER_HANDLE_RENDER_STATE(DepthWrite) \ - QT3DS_RENDER_HANDLE_RENDER_STATE(Multisample) - -struct NVRenderState -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) x, - QT3DS_RENDER_ITERATE_RENDER_STATE -#undef QT3DS_RENDER_HANDLE_RENDER_STATE - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_RENDER_STATE - #undef QT3DS_RENDER_HANDLE_RENDER_STATE - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_BLEND_FUNC \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(Zero) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(One) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcColor) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcColor) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(DstColor) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstColor) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcAlpha) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcAlpha) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(DstAlpha) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstAlpha) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantColor) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantColor) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantAlpha) \ - QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantAlpha) \ - QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(SrcAlphaSaturate) - -struct NVRenderSrcBlendFunc -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x, -#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) x, - QT3DS_RENDER_ITERATE_BLEND_FUNC -#undef QT3DS_RENDER_HANDLE_BLEND_FUNC -#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC - }; - - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) \ - case x: \ - return #x; -#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_BLEND_FUNC - #undef QT3DS_RENDER_HANDLE_BLEND_FUNC - #undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC - default: - break; - } - return "Unknown"; - } -}; - -struct NVRenderDstBlendFunc -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x, -#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) - QT3DS_RENDER_ITERATE_BLEND_FUNC -#undef QT3DS_RENDER_HANDLE_BLEND_FUNC -#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC - }; - - static const char *toString(Enum value) - { - return NVRenderSrcBlendFunc::toString((NVRenderSrcBlendFunc::Enum)value); - } -}; - -#define QT3DS_RENDER_ITERATE_BLEND_EQUATION \ - QT3DS_RENDER_HANDLE_BLEND_EQUATION(Add) \ - QT3DS_RENDER_HANDLE_BLEND_EQUATION(Subtract) \ - QT3DS_RENDER_HANDLE_BLEND_EQUATION(ReverseSubtract) \ - QT3DS_RENDER_HANDLE_BLEND_EQUATION(Overlay) \ - QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorBurn) \ - QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorDodge) - -struct NVRenderBlendEquation -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) x, - QT3DS_RENDER_ITERATE_BLEND_EQUATION -#undef QT3DS_RENDER_HANDLE_BLEND_EQUATION - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_BLEND_EQUATION - #undef QT3DS_RENDER_HANDLE_BLEND_EQUATION - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_FACES \ - QT3DS_RENDER_HANDLE_FACES(Front) \ - QT3DS_RENDER_HANDLE_FACES(Back) \ - QT3DS_RENDER_HANDLE_FACES(FrontAndBack) - -struct NVRenderFaces -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_FACES(x) x, - QT3DS_RENDER_ITERATE_FACES -#undef QT3DS_RENDER_HANDLE_FACES - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_FACES(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_FACES - #undef QT3DS_RENDER_HANDLE_FACES - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_READ_FACES \ - QT3DS_RENDER_HANDLE_READ_FACES(Front) \ - QT3DS_RENDER_HANDLE_READ_FACES(Back) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color0) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color1) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color2) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color3) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color4) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color5) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color6) \ - QT3DS_RENDER_HANDLE_READ_FACES(Color7) - -struct NVReadFaces -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_READ_FACES(x) x, - QT3DS_RENDER_ITERATE_READ_FACES -#undef QT3DS_RENDER_HANDLE_READ_FACES - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_READ_FACES(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_READ_FACES - #undef QT3DS_RENDER_HANDLE_READ_FACES - default: - break; - } - return "Unknown"; - } -}; - -struct NVRenderBoolOp -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x, - QT3DS_RENDER_ITERATE_BOOL_OP -#undef QT3DS_RENDER_HANDLE_BOOL_OP - }; - - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_BOOL_OP(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_BOOL_OP - #undef QT3DS_RENDER_HANDLE_BOOL_OP - default: - break; - } - return "Unknown"; - } -}; - -#define QT3DS_RENDER_ITERATE_STENCIL_OP \ - QT3DS_RENDER_HANDLE_STENCIL_OP(Keep) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(Zero) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(Replace) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(Increment) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(IncrementWrap) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(Decrement) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(DecrementWrap) \ - QT3DS_RENDER_HANDLE_STENCIL_OP(Invert) - -struct NVRenderStencilOp -{ - enum Enum { - Unknown = 0, -#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) x, - QT3DS_RENDER_ITERATE_STENCIL_OP -#undef QT3DS_RENDER_HANDLE_STENCIL_OP - }; - static const char *toString(Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) \ - case x: \ - return #x; - QT3DS_RENDER_ITERATE_STENCIL_OP - #undef QT3DS_RENDER_HANDLE_STENCIL_OP - default: - break; - } - return "Unknown"; - } -}; - -struct NVRenderBlendFunctionArgument -{ - NVRenderSrcBlendFunc::Enum m_SrcRGB; - NVRenderDstBlendFunc::Enum m_DstRGB; - NVRenderSrcBlendFunc::Enum m_SrcAlpha; - NVRenderDstBlendFunc::Enum m_DstAlpha; - - NVRenderBlendFunctionArgument(NVRenderSrcBlendFunc::Enum srcRGB, - NVRenderDstBlendFunc::Enum dstRGB, - NVRenderSrcBlendFunc::Enum srcAlpha, - NVRenderDstBlendFunc::Enum dstAlpha) - : m_SrcRGB(srcRGB) - , m_DstRGB(dstRGB) - , m_SrcAlpha(srcAlpha) - , m_DstAlpha(dstAlpha) - { - } - - // Default blend system premultiplies values. - NVRenderBlendFunctionArgument() - : m_SrcRGB(NVRenderSrcBlendFunc::SrcAlpha) - , m_DstRGB(NVRenderDstBlendFunc::OneMinusSrcAlpha) - , m_SrcAlpha(NVRenderSrcBlendFunc::One) - , m_DstAlpha(NVRenderDstBlendFunc::OneMinusSrcAlpha) - { - } -}; - -struct NVRenderBlendEquationArgument -{ - NVRenderBlendEquation::Enum m_RGBEquation; - NVRenderBlendEquation::Enum m_AlphaEquation; - - NVRenderBlendEquationArgument(NVRenderBlendEquation::Enum rgb, - NVRenderBlendEquation::Enum alpha) - : m_RGBEquation(rgb) - , m_AlphaEquation(alpha) - { - } - NVRenderBlendEquationArgument() - : m_RGBEquation(NVRenderBlendEquation::Add) - , m_AlphaEquation(NVRenderBlendEquation::Add) - { - } -}; - -struct NVRenderStencilOperationArgument -{ - NVRenderStencilOp::Enum m_StencilFail; // What happens when stencil test fails. - // These values assume the stencil passed - NVRenderStencilOp::Enum - m_DepthFail; // What happens when the stencil passes but depth test fail. - NVRenderStencilOp::Enum m_DepthPass; // What happens when the stencil and depth tests pass. - - NVRenderStencilOperationArgument(NVRenderStencilOp::Enum fail, - NVRenderStencilOp::Enum depthFail, - NVRenderStencilOp::Enum depthPass) - : m_StencilFail(fail) - , m_DepthFail(depthFail) - , m_DepthPass(depthPass) - { - } - NVRenderStencilOperationArgument() - : m_StencilFail(NVRenderStencilOp::Keep) - , m_DepthFail(NVRenderStencilOp::Keep) - , m_DepthPass(NVRenderStencilOp::Keep) - { - } - NVRenderStencilOperationArgument(const NVRenderStencilOperationArgument &StencilOp) - : m_StencilFail(StencilOp.m_StencilFail) - , m_DepthFail(StencilOp.m_DepthFail) - , m_DepthPass(StencilOp.m_DepthPass) - { - } - - NVRenderStencilOperationArgument &operator=(const NVRenderStencilOperationArgument &rhs) - { - // Check for self-assignment! - if (this == &rhs) - return *this; - - m_StencilFail = rhs.m_StencilFail; - m_DepthFail = rhs.m_DepthFail; - m_DepthPass = rhs.m_DepthPass; - - return *this; - } - - bool operator==(const NVRenderStencilOperationArgument &other) const - { - return (m_StencilFail == other.m_StencilFail && m_DepthFail == other.m_DepthFail - && m_DepthPass == other.m_DepthPass); - } -}; - -// see glStencilFuncSeparate -struct NVRenderStencilFunctionArgument -{ - NVRenderBoolOp::Enum m_Function; - QT3DSU32 m_ReferenceValue; - QT3DSU32 m_Mask; - - NVRenderStencilFunctionArgument(NVRenderBoolOp::Enum function, QT3DSU32 referenceValue, - QT3DSU32 mask) - : m_Function(function) - , m_ReferenceValue(referenceValue) - , m_Mask(mask) - { - } - NVRenderStencilFunctionArgument() - : m_Function(NVRenderBoolOp::AlwaysTrue) - , m_ReferenceValue(0) - , m_Mask((QT3DSU32)-1) - { - } - NVRenderStencilFunctionArgument(const NVRenderStencilFunctionArgument &StencilFunc) - : m_Function(StencilFunc.m_Function) - , m_ReferenceValue(StencilFunc.m_ReferenceValue) - , m_Mask(StencilFunc.m_Mask) - { - } - - NVRenderStencilFunctionArgument &operator=(const NVRenderStencilFunctionArgument &rhs) - { - // Check for self-assignment! - if (this == &rhs) - return *this; - - m_Function = rhs.m_Function; - m_ReferenceValue = rhs.m_ReferenceValue; - m_Mask = rhs.m_Mask; - - return *this; - } - - bool operator==(const NVRenderStencilFunctionArgument &other) const - { - return (m_Function == other.m_Function && m_ReferenceValue == other.m_ReferenceValue - && m_Mask == other.m_Mask); - } -}; - -class NVRenderFrameBuffer; -class NVRenderVertexBuffer; -class NVRenderIndexBuffer; -class NVRenderShaderProgram; -class NVRenderProgramPipeline; -class NVRenderTextureBase; -class NVRenderTexture2D; -class NVRenderTexture2DArray; -class NVRenderTextureCube; -class NVRenderImage2D; -class NVRenderDataBuffer; -class NVRenderAttribLayout; -class NVRenderInputAssembler; - -typedef NVRenderFrameBuffer *NVRenderFrameBufferPtr; -typedef NVRenderVertexBuffer *NVRenderVertexBufferPtr; -typedef NVRenderIndexBuffer *NVRenderIndexBufferPtr; -typedef NVRenderTexture2D *NVRenderTexture2DPtr; -typedef NVRenderTexture2DPtr *NVRenderTexture2DHandle; -typedef NVRenderTexture2DArray *NVRenderTexture2DArrayPtr; -typedef NVRenderTextureCube *NVRenderTextureCubePtr; -typedef NVRenderTextureCubePtr *NVRenderTextureCubeHandle; -typedef NVRenderImage2D *NVRenderImage2DPtr; -typedef NVRenderDataBuffer *NVRenderDataBufferPtr; -typedef const char *NVRenderConstCharPtr; -typedef bool QT3DSRenderBool; -typedef NVRenderShaderProgram *NVRenderShaderProgramPtr; -typedef NVDataRef NVU32List; -typedef NVDataRef NVConstCharPtrList; - -template -struct NVRenderRectT -{ - typedef TDataType TRectType; - TDataType m_X; - TDataType m_Y; - TDataType m_Width; - TDataType m_Height; - NVRenderRectT(TDataType x, TDataType y, TDataType w, TDataType h) - : m_X(x) - , m_Y(y) - , m_Width(w) - , m_Height(h) - { - } - NVRenderRectT() - : m_X(0) - , m_Y(0) - , m_Width(0) - , m_Height(0) - { - } - bool operator==(const NVRenderRectT &inOther) const - { - return m_X == inOther.m_X && m_Y == inOther.m_Y && m_Width == inOther.m_Width - && m_Height == inOther.m_Height; - } - bool operator!=(const NVRenderRectT &inOther) const - { - return !(*this == inOther); - } - TDataType GetRightExtent() const { return m_X + m_Width; } - TDataType GetBottomExtent() const { return m_Y + m_Height; } - // Ensure this rect is inside the bounds of the other rect - void EnsureInBounds(const NVRenderRectT &inOther) - { - TDataType rightExtent = qt3ds::NVMin(GetRightExtent(), inOther.GetRightExtent()); - TDataType bottomExtent = qt3ds::NVMin(GetBottomExtent(), inOther.GetBottomExtent()); - m_X = qt3ds::NVMax(m_X, inOther.m_X); - m_Y = qt3ds::NVMax(m_Y, inOther.m_Y); - m_Width = NVMax(static_cast(0), rightExtent - m_X); - m_Height = NVMax(static_cast(0), bottomExtent - m_Y); - } -}; - -// Render rects are setup to be in the coordinate space of the gl viewport, -// so x, y are left, bottom with increasing units going to the right and -// up respectively. -struct NVRenderRect : public NVRenderRectT -{ - typedef NVRenderRectT TBase; - NVRenderRect(QT3DSI32 x, QT3DSI32 y, QT3DSI32 w, QT3DSI32 h) - : TBase(x, y, w, h) - { - } - NVRenderRect() - : TBase() - { - } -}; - -struct NVRenderRectF : public NVRenderRectT -{ - typedef NVRenderRectT TBase; - NVRenderRectF(QT3DSF32 x, QT3DSF32 y, QT3DSF32 w, QT3DSF32 h) - : TBase(x, y, w, h) - { - } - NVRenderRectF() - : TBase() - { - } - NVRenderRectF(const NVRenderRect &inRect) - : TBase((QT3DSF32)inRect.m_X, (QT3DSF32)inRect.m_Y, (QT3DSF32)inRect.m_Width, - (QT3DSF32)inRect.m_Height) - { - } - NVRenderRect ToIntegerRect() const - { - return NVRenderRect((QT3DSI32)m_X, (QT3DSI32)m_Y, (QT3DSU32)(m_Width + .5f), - (QT3DSU32)(m_Height + .5f)); - } - QT3DSVec2 BottomLeft() const { return QT3DSVec2(m_X, m_Y); } - QT3DSVec2 Center() const - { - QT3DSVec2 halfDims = HalfDims(); - return QT3DSVec2(m_X + halfDims.x, m_Y + halfDims.y); - } - QT3DSVec2 HalfDims() const { return QT3DSVec2(m_Width / 2.0f, m_Height / 2.0f); } - // Normalized coordinates are in the range of -1,1 where -1 is the left, bottom edges - // and 1 is the top,right edges. - QT3DSVec2 AbsoluteToNormalizedCoordinates(QT3DSVec2 absoluteCoordinates) const - { - QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates)); - return RelativeToNormalizedCoordinates(relativeCoords); - }; - - QT3DSVec2 RelativeToNormalizedCoordinates(QT3DSVec2 rectRelativeCoords) const - { - QT3DSVec2 halfDims(HalfDims()); - QT3DSVec2 retval((rectRelativeCoords.x / halfDims.x) - 1.0f, - (rectRelativeCoords.y / halfDims.y) - 1.0f); - return retval; - } - - // Take coordinates in global space and move local space where 0,0 is the center - // of the rect but return value in pixels, not in normalized -1,1 range - QT3DSVec2 ToNormalizedRectRelative(QT3DSVec2 absoluteCoordinates) const - { - // normalize them - QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates)); - QT3DSVec2 halfDims(HalfDims()); - QT3DSVec2 normalized((relativeCoords.x / halfDims.x) - 1.0f, - (relativeCoords.y / halfDims.y) - 1.0f); - return QT3DSVec2(normalized.x * halfDims.x, normalized.y * halfDims.y); - } - - // Return coordinates in pixels but relative to this rect. - QT3DSVec2 ToRectRelative(QT3DSVec2 absoluteCoordinates) const - { - return QT3DSVec2(absoluteCoordinates.x - m_X, absoluteCoordinates.y - m_Y); - } - - QT3DSVec2 ToAbsoluteCoords(QT3DSVec2 inRelativeCoords) const - { - return QT3DSVec2(inRelativeCoords.x + m_X, inRelativeCoords.y + m_Y); - } -}; - -template -struct NVRenderGenericVec2 -{ - TDataType x; - TDataType y; - NVRenderGenericVec2(TDataType _x, TDataType _y) - : x(_x) - , y(_y) - { - } - NVRenderGenericVec2() {} - bool operator==(const NVRenderGenericVec2 &inOther) const - { - return x == inOther.x && y == inOther.y; - } -}; - -template -struct NVRenderGenericVec3 -{ - TDataType x; - TDataType y; - TDataType z; - NVRenderGenericVec3(TDataType _x, TDataType _y, TDataType _z) - : x(_x) - , y(_y) - , z(_z) - { - } - NVRenderGenericVec3() {} - bool operator==(const NVRenderGenericVec3 &inOther) const - { - return x == inOther.x && y == inOther.y && z == inOther.z; - } -}; - -template -struct NVRenderGenericVec4 -{ - TDataType x; - TDataType y; - TDataType z; - TDataType w; - NVRenderGenericVec4(TDataType _x, TDataType _y, TDataType _z, TDataType _w) - : x(_x) - , y(_y) - , z(_z) - , w(_w) - { - } - NVRenderGenericVec4() {} - bool operator==(const NVRenderGenericVec4 &inOther) const - { - return x == inOther.x && y == inOther.y && z == inOther.z && w == inOther.w; - } -}; - -#define DECLARE_GENERIC_VECTOR_TYPE(type, numElems) \ - typedef NVRenderGenericVec##numElems type##_##numElems -DECLARE_GENERIC_VECTOR_TYPE(bool, 2); -DECLARE_GENERIC_VECTOR_TYPE(bool, 3); -DECLARE_GENERIC_VECTOR_TYPE(bool, 4); -DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 2); -DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 3); -DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 4); -DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 2); -DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 3); -DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 4); - -#define ITERATE_QT3DS_SHADER_DATA_TYPES \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_2) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_3) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_4) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSRenderBool) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(bool_2) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(bool_3) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(bool_4) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSF32) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec2) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec3) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec4) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_2) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_3) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_4) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat33) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat44) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DPtr) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DHandle) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DArrayPtr) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubePtr) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubeHandle) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderImage2DPtr) \ - HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderDataBufferPtr) - -struct NVRenderShaderDataTypes -{ - enum Enum { - Unknown = 0, -#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) type, - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - }; -}; - -template -struct NVDataTypeToShaderDataTypeMap -{ -}; - -#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ - template <> \ - struct NVDataTypeToShaderDataTypeMap \ -{ \ - static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::type; } \ -}; -ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - -template <> -struct NVDataTypeToShaderDataTypeMap> -{ - static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::QT3DSMat44; } -}; - -struct NVRenderShaderTypeValue -{ - enum Enum { - Unknown = 1 << 0, - Vertex = 1 << 1, - Fragment = 1 << 2, - TessControl = 1 << 3, - TessEvaluation = 1 << 4, - Geometry = 1 << 5 - }; -}; - -typedef NVFlags NVRenderShaderTypeFlags; - -struct NVRenderTextureTypeValue -{ - enum Enum { - Unknown = 0, - Diffuse, - Specular, - Environment, - Bump, - Normal, - Displace, - Emissive, - Emissive2, - Anisotropy, - Translucent, - LightmapIndirect, - LightmapRadiosity, - LightmapShadow - }; - - static const char *toString(NVRenderTextureTypeValue::Enum value) - { - switch (value) { - case Unknown: - return "Unknown"; - case Diffuse: - return "Diffuse"; - case Specular: - return "Specular"; - case Environment: - return "Environment"; - case Bump: - return "Bump"; - case Normal: - return "Normal"; - case Displace: - return "Displace"; - case Emissive: - return "Emissive"; - case Emissive2: - return "Emissive2"; - case Anisotropy: - return "Anisotropy"; - case Translucent: - return "Translucent"; - case LightmapIndirect: - return "LightmapIndirect"; - case LightmapRadiosity: - return "LightmapRadiosity"; - case LightmapShadow: - return "LightmapShadow"; - default: - return "Unknown"; - } - } -}; - -#define ITERATE_QT3DS_READ_PIXEL_FORMATS \ - HANDLE_QT3DS_READ_PIXEL_FORMAT(Alpha8) \ - HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB565) \ - HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB8) \ - HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA4444) \ - HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA5551) \ - HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA8) - -struct NVRenderReadPixelFormats -{ - enum Enum { - Unknown = 0, -#define HANDLE_QT3DS_READ_PIXEL_FORMAT(format) format, - ITERATE_QT3DS_READ_PIXEL_FORMATS -#undef HANDLE_QT3DS_READ_PIXEL_FORMAT - }; -}; - -// Now for scoped property access. -template -struct NVRenderGenericScopedProperty -{ - typedef void (TBaseType::*TSetter)(TDataType inType); - typedef TDataType (TBaseType::*TGetter)() const; - - TBaseType &m_Context; - TSetter m_Setter; - TDataType m_InitialValue; - NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter) - : m_Context(ctx) - , m_Setter(setter) - , m_InitialValue(((ctx).*getter)()) - { - } - NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter, - const TDataType &inNewValue) - : m_Context(ctx) - , m_Setter(setter) - , m_InitialValue(((ctx).*getter)()) - { - ((m_Context).*m_Setter)(inNewValue); - } - ~NVRenderGenericScopedProperty() { ((m_Context).*m_Setter)(m_InitialValue); } -}; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderComputeShader.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderComputeShader.h deleted file mode 100644 index 1ab36bc0..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderComputeShader.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_COMPUTE_SHADER_H -#define QT3DS_RENDER_COMPUTE_SHADER_H - -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderShader.h" - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - - ///< This class represents a compute shader - class NVRenderComputeShader : public NVRenderShader - { - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] source Pointer to shader source code - * @param[in] binaryProgram true if this is a binary program - * - * @return No return. - */ - NVRenderComputeShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram); - - /// @brief destructor - ~NVRenderComputeShader(); - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - bool IsValid() override { return (m_ShaderHandle != NULL); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendComputeShaderObject GetShaderHandle() - { - return m_ShaderHandle; - } - - private: - NVRenderBackend::NVRenderBackendComputeShaderObject - m_ShaderHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderConstantBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderConstantBuffer.h deleted file mode 100644 index 5ede23b9..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderConstantBuffer.h +++ /dev/null @@ -1,248 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H -#include "foundation/Qt3DSOption.h" -#include "foundation/Utils.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderDataBuffer.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - // forward declaration - class NVRenderContextImpl; - class ConstantBufferParamEntry; - class NVRenderShaderProgram; - - typedef nvhash_map TRenderConstantBufferEntryMap; - - ///< Constant (uniform) buffer representation - class QT3DS_AUTOTEST_EXPORT NVRenderConstantBuffer : public NVRenderDataBuffer - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] bufferName Name of the buffer. Must match the name used in programs - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return No return. - */ - NVRenderConstantBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, - size_t size, NVRenderBufferUsageType::Enum usageType, - NVDataRef data); - - ///< destructor - virtual ~NVRenderConstantBuffer(); - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - void Bind() override; - - /** - * @brief bind the buffer to a shader program - * - * @param[in] inShader Pointer to active program - * @param[in] blockIndex Index of the constant block within the program - * @param[in] binding Binding point of constant buffer - * - * @return no return. - */ - virtual void BindToShaderProgram(NVRenderShaderProgram *inShader, QT3DSU32 blockIndex, - QT3DSU32 binding); - - /** - * @brief update the buffer to hardware - * - * @return no return. - */ - virtual void Update(); - - /** - * @brief setup constant buffer - * - * @param[in] pProgram Pointer to the shader program - * @param[in] index Index of the constant buffer within the program - * @param[in] bufSize Size of the constant buffer - * @param[in] paramCount Parameter entry count of the constant buffer - * - * @return return if successful - */ - bool SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, QT3DSI32 bufSize, - QT3DSI32 paramCount); - - /** - * @brief add a parameter to the constant buffer - * - * @param[in] name Name of the parameter (must match the name in the shader - * program) - * @param[in] type Type of the parameter like Mat44 - * @param[in] count One or size of array - * - * @return no return - */ - void AddParam(CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count); - - /** - * @brief update a parameter in the constant buffer - * - * @param[in] name Name of the parameter (must match the name in the shader - * program) - * @param[in] value New value - * - * @return no return - */ - void UpdateParam(const char *name, NVDataRef value); - - /** - * @brief update a piece of memory directly within the constant buffer - * - * Note: When you use this function you should know what you are doing. - * The memory layout within C++ must exactly match the memory layout in the - *shader. - * We use std140 layout which guarantees a specific layout behavior across all - *HW vendors. - * How the memory layout is computed can be found in the GL spec. - * - * @param[in] offset offset into constant buffer - * @param[in] data pointer to new data - * - * @return no return - */ - void UpdateRaw(QT3DSI32 offset, NVDataRef data); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - /** - * @brief create a NVRenderConstantBuffer object - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return the backend object handle. - */ - static NVRenderConstantBuffer *Create(NVRenderContextImpl &context, const char *bufferName, - NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData); - - /** - * @brief get the buffer name - * - * @return the buffer name - */ - CRegisteredString GetBufferName() const { return m_Name; } - - private: - /** - * @brief Create a parameter entry - * - * @param[in] name Name of the parameter (must match the name in the shader - * program) - * @param[in] type Type of the parameter like Mat44 - * @param[in] count One or size of array - * @param[in] offset Offset of the parameter in the memory buffer - * - * @return return new Entry - */ - ConstantBufferParamEntry *createParamEntry(CRegisteredString name, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count, - QT3DSI32 offset); - - /** - * @brief get size of a uniform type - * - * @param[in] type type of uniform - * - * @return return uniform size - */ - QT3DSI32 - getUniformTypeSize(NVRenderShaderDataTypes::Enum type); - - /** - * @brief allocate the shadow buffer - * - * @param[in] size size of buffer - * - * @return return true on success - */ - bool allocateShadowBuffer(QT3DSU32 size); - - /** - * @brief update a certain range of the buffer to hardware - * - * @return no return. - */ - virtual void UpdateRange(); - - private: - CRegisteredString m_Name; ///< buffer name - TRenderConstantBufferEntryMap - m_ConstantBufferEntryMap; ///< holds the entries of a constant buffer - QT3DSU32 m_CurrentOffset; ///< holds the current offset - QT3DSU32 m_CurrentSize; ///< holds the current size - bool m_HWBufferInitialized; ///< true if the hardware version of the buffer is initialized - bool m_Dirty; ///< true if buffer is dirty - QT3DSU32 m_RangeStart; ///< start offset of the range to update - QT3DSU32 m_RangeEnd; ///< size of the range to update - QT3DSI32 m_MaxBlockSize; ///< maximum size for a single constant buffer - NVDataRef m_ShadowCopy; ///< host copy of the data in the GPU - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h deleted file mode 100644 index e5b51341..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h +++ /dev/null @@ -1,1063 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CONTEXT_H -#define QT3DS_RENDER_CONTEXT_H -#include "foundation/Qt3DS.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "render/glg/Qt3DSGLImplObjects.h" -#include "render/backends/gl/Q3DSRenderBackendGLES2.h" -#include "render/backends/gl/Qt3DSRenderBackendGL3.h" -#include "render/backends/gl/Qt3DSRenderBackendGL4.h" -#include "render/backends/software/Qt3DSRenderBackendNULL.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderIndexBuffer.h" -#include "render/Qt3DSRenderConstantBuffer.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "render/Qt3DSRenderDepthStencilState.h" -#include "render/Qt3DSRenderRasterizerState.h" -#include "render/Qt3DSRenderDrawable.h" -#include "render/Qt3DSRenderInputAssembler.h" -#include "render/Qt3DSRenderAttribLayout.h" -#include "render/Qt3DSRenderImageTexture.h" -#include "render/Qt3DSRenderOcclusionQuery.h" -#include "render/Qt3DSRenderTimerQuery.h" -#include "render/Qt3DSRenderSync.h" -#include "render/Qt3DSRenderTexture2DArray.h" -#include "render/Qt3DSRenderTextureCube.h" -#include "render/Qt3DSRenderStorageBuffer.h" -#include "render/Qt3DSRenderAtomicCounterBuffer.h" -#include "render/Qt3DSRenderDrawIndirectBuffer.h" -#include "render/Qt3DSRenderProgramPipeline.h" -#include "render/Qt3DSRenderPathRender.h" -#include "render/Qt3DSRenderPathSpecification.h" -#include "render/Qt3DSRenderPathFontSpecification.h" -#include "render/Qt3DSRenderPathFontText.h" - -#include - -// When SW fallback is defined we can support (some) object/layer advanced blend modes. If defined, -// the HW implementation is still preperred if available through extensions. SW fallback can't be -// used in custom shaders. -#define ADVANCED_BLEND_SW_FALLBACK -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - using namespace foundation; - - struct NVRenderShaderProgramBinaryType - { - enum Enum { - Unknown = 0, - NVBinary = 1, - }; - }; - - // context dirty flags - struct NVRenderContextDirtyValues - { - enum Enum { - InputAssembler = 1 << 0, - }; - }; - - typedef NVFlags NVRenderContextDirtyFlags; - typedef nvhash_map TContextConstantBufferMap; - typedef nvhash_map TContextStorageBufferMap; - typedef nvhash_map - TContextAtomicCounterBufferMap; - typedef nvhash_map - TContextDrawIndirectBufferMap; - typedef nvhash_map - TContextDepthStencilStateMap; - typedef nvhash_map - TContextRasterizerStateMap; - typedef nvhash_map - TContextTex2DArrayToImpMap; - typedef nvhash_map - TContextTexCubeToImpMap; - typedef nvhash_map - TContextImage2DToImpMap; - typedef nvhash_map - TContextPathFontSpecificationMap; - - class QT3DS_AUTOTEST_EXPORT NVRenderContext : public NVRefCounted, public NVRenderDrawable - { - public: - virtual NVRenderContextType GetRenderContextType() const = 0; - virtual bool AreMultisampleTexturesSupported() const = 0; - virtual bool GetConstantBufferSupport() const = 0; - virtual void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) = 0; - virtual const char *GetShadingLanguageVersion() = 0; - // Get the bit depth of the currently bound depth buffer. - virtual QT3DSU32 GetDepthBits() const = 0; - virtual QT3DSU32 GetStencilBits() const = 0; - virtual bool - GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const = 0; - virtual bool AreDXTImagesSupported() const = 0; - virtual bool IsDepthStencilSupported() const = 0; - virtual bool IsFpRenderTargetSupported() const = 0; - virtual bool IsTessellationSupported() const = 0; - virtual bool IsGeometryStageSupported() const = 0; - virtual bool IsComputeSupported() const = 0; - virtual bool IsSampleQuerySupported() const = 0; - virtual bool IsTimerQuerySupported() const = 0; - virtual bool IsCommandSyncSupported() const = 0; - virtual bool IsTextureArraySupported() const = 0; - virtual bool IsStorageBufferSupported() const = 0; - virtual bool IsAtomicCounterBufferSupported() const = 0; - virtual bool IsShaderImageLoadStoreSupported() const = 0; - virtual bool IsProgramPipelineSupported() const = 0; - virtual bool IsPathRenderingSupported() const = 0; - virtual bool IsBlendCoherencySupported() const = 0; - virtual bool IsAdvancedBlendHwSupported() const = 0; - virtual bool IsAdvancedBlendHwSupportedKHR() const = 0; - virtual bool IsStandardDerivativesSupported() const = 0; - virtual bool IsTextureLodSupported() const = 0; - - virtual void SetDefaultRenderTarget(QT3DSU64 targetID) = 0; - virtual void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) = 0; - - virtual NVRenderDepthStencilState * - CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, - bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) = 0; - - virtual NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, - NVRenderFaces::Enum cullFace) = 0; - - virtual NVRenderVertexBuffer * - CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, QT3DSU32 stride = 0, - NVConstDataRef bufferData = NVConstDataRef()) = 0; - virtual NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) = 0; - - virtual NVRenderIndexBuffer * - CreateIndexBuffer(NVRenderBufferUsageType::Enum usageType, - NVRenderComponentTypes::Enum componentType, size_t size, - NVConstDataRef bufferData = NVConstDataRef()) = 0; - virtual NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) = 0; - - virtual NVRenderConstantBuffer * - CreateConstantBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) = 0; - virtual NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) = 0; - - virtual NVRenderStorageBuffer * - CreateStorageBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) = 0; - virtual NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) = 0; - - virtual NVRenderAtomicCounterBuffer * - CreateAtomicCounterBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) = 0; - virtual NVRenderAtomicCounterBuffer * - GetAtomicCounterBuffer(CRegisteredString bufferName) = 0; - virtual NVRenderAtomicCounterBuffer * - GetAtomicCounterBufferByParam(CRegisteredString paramName) = 0; - - virtual NVRenderDrawIndirectBuffer * - CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) = 0; - virtual NVRenderDrawIndirectBuffer *GetDrawIndirectBuffer( - NVRenderBackend::NVRenderBackendBufferObject implementationHandle) = 0; - - virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; - - virtual NVRenderOcclusionQuery *CreateOcclusionQuery() = 0; - virtual NVRenderTimerQuery *CreateTimerQuery() = 0; - virtual NVRenderSync *CreateSync() = 0; - - virtual NVRenderTexture2D *CreateTexture2D() = 0; - virtual NVRenderTexture2D *GetTexture2D(const void *implementationHandle) = 0; - virtual NVRenderBackend *GetBackend() = 0; - - virtual NVRenderTexture2DArray *CreateTexture2DArray() = 0; - - virtual NVRenderTextureCube *CreateTextureCube() = 0; - - virtual NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) = 0; - - virtual NVRenderRenderBuffer * - CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width, - QT3DSU32 height) = 0; - virtual NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) = 0; - // Create a new frame buffer and set the current render target to that frame buffer. - virtual NVRenderFrameBuffer *CreateFrameBuffer() = 0; - virtual NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) = 0; - - virtual NVRenderAttribLayout * - CreateAttributeLayout(NVConstDataRef attribs) = 0; - - virtual NVRenderInputAssembler * - CreateInputAssembler(NVRenderAttribLayout *attribLayout, - NVConstDataRef buffers, - const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, - NVConstDataRef offsets, - NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles, - QT3DSU32 patchVertexCount = 1) = 0; - virtual void SetInputAssembler(NVRenderInputAssembler *inputAssembler) = 0; - - virtual NVRenderVertFragCompilationResult CompileSource( - const char *shaderName, NVConstDataRef vertShader, - NVConstDataRef fragShader, - NVConstDataRef tessControlShaderSource = NVConstDataRef(), - NVConstDataRef tessEvaluationShaderSource = NVConstDataRef(), - NVConstDataRef geometryShaderSource = NVConstDataRef(), - bool separateProgram = false, - NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, - bool binaryProgram = false) = 0; - - // You must figure out inVertLen and inFragLen yourself, this object doesn't do that. - NVRenderVertFragCompilationResult - CompileSource(const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, - const char *fragShader, QT3DSU32 inFragLen, const char * = NULL, - QT3DSU32 inTCLen = 0, const char *tessEvaluationShaderSource = NULL, - QT3DSU32 inTELen = 0, const char *geometryShaderSource = NULL, QT3DSU32 inGSLen = 0, - bool separableProgram = false); - - virtual NVRenderVertFragCompilationResult - CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, - NVDataRef vertShader, NVDataRef fragShader, - NVDataRef tessControlShaderSource = NVDataRef(), - NVDataRef tessEvaluationShaderSource = NVDataRef(), - NVConstDataRef geometryShaderSource = NVConstDataRef()) = 0; - - virtual NVRenderVertFragCompilationResult - CompileComputeSource(const char *shaderName, NVConstDataRef computeShaderSource) = 0; - - virtual NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) = 0; - - virtual NVRenderProgramPipeline *CreateProgramPipeline() = 0; - - virtual NVRenderPathSpecification *CreatePathSpecification() = 0; - virtual NVRenderPathRender *CreatePathRender(size_t range = 1) = 0; - virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; - virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; - virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; - virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) = 0; - - virtual NVRenderPathFontSpecification * - CreatePathFontSpecification(CRegisteredString fontName) = 0; - virtual NVRenderPathFontItem *CreatePathFontItem() = 0; - - // Specific setters for the guaranteed-to-exist context properties to set them as fast as - // possible. - // Note that this bypasses the property manage so push/pop will have no effect (unless you - // set these already - // once after a push using the property manager. - virtual void SetClearColor(QT3DSVec4 inClearColor) = 0; - virtual QT3DSVec4 GetClearColor() const = 0; - - virtual void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) = 0; - virtual NVRenderBlendFunctionArgument GetBlendFunction() const = 0; - - virtual void SetBlendEquation(NVRenderBlendEquationArgument inEquations) = 0; - virtual NVRenderBlendEquationArgument GetBlendEquation() const = 0; - - virtual void SetCullingEnabled(bool inEnabled) = 0; - virtual bool IsCullingEnabled() const = 0; - - virtual void SetDepthFunction(NVRenderBoolOp::Enum inFunction) = 0; - virtual qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const = 0; - - virtual void SetBlendingEnabled(bool inEnabled) = 0; - virtual bool IsBlendingEnabled() const = 0; - - virtual void SetDepthWriteEnabled(bool inEnabled) = 0; - virtual bool IsDepthWriteEnabled() const = 0; - - virtual void SetDepthTestEnabled(bool inEnabled) = 0; - virtual bool IsDepthTestEnabled() const = 0; - - virtual void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) = 0; - virtual void SetStencilTestEnabled(bool inEnabled) = 0; - virtual bool IsStencilTestEnabled() const = 0; - - virtual void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) = 0; - - virtual void SetScissorTestEnabled(bool inEnabled) = 0; - virtual bool IsScissorTestEnabled() const = 0; - - virtual void SetScissorRect(NVRenderRect inRect) = 0; - virtual NVRenderRect GetScissorRect() const = 0; - - virtual void SetViewport(NVRenderRect inViewport) = 0; - virtual NVRenderRect GetViewport() const = 0; - - virtual void SetColorWritesEnabled(bool inEnabled) = 0; - virtual bool IsColorWritesEnabled() const = 0; - - virtual void SetMultisampleEnabled(bool inEnabled) = 0; - virtual bool IsMultisampleEnabled() const = 0; - - // Used during layer rendering because we can't set the *actual* viewport to what it should - // be due to hardware problems. - // Set during begin render. - static QT3DSMat44 - ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, - const NVRenderRectF &inViewport, - const NVRenderRectF &inVirtualViewport); - - virtual void SetRenderTarget(NVRenderFrameBuffer *inBuffer) = 0; - virtual void SetReadTarget(NVRenderFrameBuffer *inBuffer) = 0; - virtual NVRenderFrameBuffer *GetRenderTarget() const = 0; - - virtual void SetActiveShader(NVRenderShaderProgram *inShader) = 0; - virtual NVRenderShaderProgram *GetActiveShader() const = 0; - - virtual void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) = 0; - virtual NVRenderProgramPipeline *GetActiveProgramPipeline() const = 0; - - virtual void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, - QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; - - // Push the entire set of properties. - virtual void PushPropertySet() = 0; - // Pop the entire set of properties, potentially forcing the values - // to opengl. Will set the hardware state to whatever at the time of push. - virtual void PopPropertySet(bool inForceSetProperties) = 0; - - // Ensure the hardware state matches the state we expect. - virtual void ResetBlendState() = 0; - - // Draw buffers are what the system will render to.. Applies to the current render context. - //-1 means none, else the integer is assumed to be an index past the draw buffer index. - // This applies only to the currently bound framebuffer. - virtual void SetDrawBuffers(NVConstDataRef inDrawBufferSet) = 0; - virtual void SetReadBuffer(NVReadFaces::Enum inReadFace) = 0; - - virtual void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat, - NVDataRef inWriteBuffer) = 0; - - // Return the property manager for this render context - // virtual NVRenderPropertyManager& GetPropertyManager() = 0; - // Clear the current render target - virtual void Clear(NVRenderClearFlags flags) = 0; - // Clear this framebuffer without changing the active frame buffer - virtual void Clear(NVRenderFrameBuffer &framebuffer, NVRenderClearFlags flags) = 0; - // copy framebuffer content between read target and render target - virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) = 0; - - // Render, applying these immediate property values just before render. The hardware - // properties are tracked for push/pop - // but the shader properties are just set on the active shader *after* the hardware - // properties have been set. The shader properties are not tracked for push/pop. - // This call is meant to come directly before each draw call to setup the last bit of state - // before the draw operation. Note that there isn't another way to set the immedate - // property values for a given shader because it isn't clear which shader is active - // when the properties are getting set. - void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override = 0; - - /** - * @brief Draw the current active vertex buffer using an indirect buffer - * This means the setup of the draw call is stored in a buffer bound to - * NVRenderBufferBindValues::Draw_Indirect - * - * @param[in] drawMode Draw mode (Triangles, ....) - * @param[in] indirect Offset into a indirect drawing setup buffer - * - * @return no return. - */ - virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) = 0; - - virtual NVFoundationBase &GetFoundation() = 0; - virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; - virtual NVAllocatorCallback &GetAllocator() = 0; - - virtual QSurfaceFormat format() const = 0; - - virtual void resetStates() = 0; - - static NVRenderContext &CreateGL(NVFoundationBase &foundation, IStringTable &inStringTable, - const QSurfaceFormat &format); - - static NVRenderContext &CreateNULL(NVFoundationBase &foundation, - IStringTable &inStringTable); - }; - - // Now for scoped property access. - template - struct NVRenderContextScopedProperty - : public NVRenderGenericScopedProperty - { - typedef typename NVRenderGenericScopedProperty::TGetter TGetter; - typedef typename NVRenderGenericScopedProperty::TSetter TSetter; - NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter) - : NVRenderGenericScopedProperty(ctx, getter, setter) - { - } - NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter, - const TDataType &inNewValue) - : NVRenderGenericScopedProperty(ctx, getter, setter, - inNewValue) - { - } - }; - -/** - * A Render Context implementation class - * - */ - -#define ITERATE_HARDWARE_CONTEXT_PROPERTIES \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(RenderTarget, FrameBuffer) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveShader, ActiveShader) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveProgramPipeline, ActiveProgramPipeline) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(InputAssembler, InputAssembler) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendFunction, BlendFunction) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(CullingEnabled, CullingEnabled) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthFunction, DepthFunction) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendingEnabled, BlendingEnabled) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthWriteEnabled, DepthWriteEnabled) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthTestEnabled, DepthTestEnabled) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(StencilTestEnabled, StencilTestEnabled) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorTestEnabled, ScissorTestEnabled) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorRect, ScissorRect) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(Viewport, Viewport) \ - HANDLE_CONTEXT_HARDWARE_PROPERTY(ClearColor, ClearColor) - - // forward declarations - - class NVRenderContextImpl : public NVRenderContext, public NoCopy - { - public: - // these variables represent the current hardware state of the render context. - SNVGLHardPropertyContext m_HardwarePropertyContext; - - private: - NVScopedRefCounted m_backend; ///< pointer to our render backend - NVRenderContextDirtyFlags m_DirtyFlags; ///< context dirty flags - - NVRenderBackend::NVRenderBackendRenderTargetObject - m_DefaultOffscreenRenderTarget; ///< this is a special target set from outside if we - ///never render to a window directly (GL only) - QT3DSI32 m_DephBits; ///< this is the depth bits count of the default window render target - QT3DSI32 m_StencilBits; ///< this is the stencil bits count of the default window render target - - protected: - volatile QT3DSI32 mRefCount; - NVFoundationBase &m_Foundation; - qt3ds::foundation::IStringTable &m_StringTable; - - nvhash_map m_VertToImpMap; - nvhash_map m_IndexToImpMap; - TContextConstantBufferMap m_ConstantToImpMap; - TContextStorageBufferMap m_StorageToImpMap; - TContextAtomicCounterBufferMap m_AtomicCounterToImpMap; - TContextDrawIndirectBufferMap m_DrawIndirectToImpMap; - TContextDepthStencilStateMap m_DepthStencilStateToImpMap; - TContextRasterizerStateMap m_RasterizerStateToImpMap; - TContextPathFontSpecificationMap m_PathFontSpecToImpMap; - - nvhash_map m_Tex2DToImpMap; - TContextTex2DArrayToImpMap m_Tex2DArrayToImpMap; - TContextTexCubeToImpMap m_TexCubeToImpMap; - TContextImage2DToImpMap m_Image2DtoImpMap; - nvhash_map m_ShaderToImpMap; - nvhash_map m_RenderBufferToImpMap; - nvhash_map m_FrameBufferToImpMap; - QT3DSU32 m_MaxTextureUnits; - QT3DSU32 m_NextTextureUnit; - QT3DSU32 m_MaxConstantBufferUnits; - QT3DSU32 m_NextConstantBufferUnit; - - nvvector m_PropertyStack; - - void DoSetClearColor(QT3DSVec4 inClearColor) - { - m_HardwarePropertyContext.m_ClearColor = inClearColor; - m_backend->SetClearColor(&inClearColor); - } - - void DoSetBlendFunction(NVRenderBlendFunctionArgument inFunctions) - { - QT3DSI32_4 values; - m_HardwarePropertyContext.m_BlendFunction = inFunctions; - - m_backend->SetBlendFunc(inFunctions); - } - - void DoSetBlendEquation(NVRenderBlendEquationArgument inEquations) - { - QT3DSI32_4 values; - m_HardwarePropertyContext.m_BlendEquation = inEquations; - - m_backend->SetBlendEquation(inEquations); - } - - void DoSetCullingEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_CullingEnabled = inEnabled; - m_backend->SetRenderState(inEnabled, NVRenderState::CullFace); - } - - void DoSetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) - { - m_HardwarePropertyContext.m_DepthFunction = inFunction; - m_backend->SetDepthFunc(inFunction); - } - - void DoSetBlendingEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_BlendingEnabled = inEnabled; - m_backend->SetRenderState(inEnabled, NVRenderState::Blend); - } - - void DoSetColorWritesEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_ColorWritesEnabled = inEnabled; - m_backend->SetColorWrites(inEnabled, inEnabled, inEnabled, inEnabled); - } - - void DoSetMultisampleEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_MultisampleEnabled = inEnabled; - m_backend->SetMultisample(inEnabled); - } - - void DoSetDepthWriteEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; - m_backend->SetDepthWrite(inEnabled); - } - - void DoSetDepthTestEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_DepthTestEnabled = inEnabled; - m_backend->SetRenderState(inEnabled, NVRenderState::DepthTest); - } - - void DoSetStencilTestEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_StencilTestEnabled = inEnabled; - m_backend->SetRenderState(inEnabled, NVRenderState::StencilTest); - } - - void DoSetScissorTestEnabled(bool inEnabled) - { - m_HardwarePropertyContext.m_ScissorTestEnabled = inEnabled; - m_backend->SetRenderState(inEnabled, NVRenderState::ScissorTest); - } - - void DoSetScissorRect(NVRenderRect inRect) - { - m_HardwarePropertyContext.m_ScissorRect = inRect; - m_backend->SetScissorRect(inRect); - } - - void DoSetViewport(NVRenderRect inViewport) - { - m_HardwarePropertyContext.m_Viewport = inViewport; - m_backend->SetViewportRect(inViewport); - } - - // Circular dependencies between shader constants and shader programs preclude - // implementation in header - void DoSetActiveShader(NVRenderShaderProgram *inShader); - void DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline); - - void DoSetInputAssembler(NVRenderInputAssembler *inAssembler) - { - m_HardwarePropertyContext.m_InputAssembler = inAssembler; - m_DirtyFlags |= NVRenderContextDirtyValues::InputAssembler; - } - - void DoSetRenderTarget(NVRenderFrameBuffer *inBuffer) - { - if (inBuffer) - m_backend->SetRenderTarget(inBuffer->GetFrameBuffertHandle()); - else - m_backend->SetRenderTarget(m_DefaultOffscreenRenderTarget); - - m_HardwarePropertyContext.m_FrameBuffer = inBuffer; - } - - void DoSetReadTarget(NVRenderFrameBuffer *inBuffer) - { - if (inBuffer) - m_backend->SetReadTarget(inBuffer->GetFrameBuffertHandle()); - else - m_backend->SetReadTarget(NVRenderBackend::NVRenderBackendRenderTargetObject(NULL)); - } - - bool BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, - NVRenderShaderProgram *shader); - bool ApplyPreDrawProperties(); - void OnPostDraw(); - - public: - NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, - IStringTable &inStrTable); - virtual ~NVRenderContextImpl(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation); - - NVRenderBackend *GetBackend() override { return m_backend; } - - void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) override; - - const char *GetShadingLanguageVersion() override - { - return m_backend->GetShadingLanguageVersion(); - } - - NVRenderContextType GetRenderContextType() const override - { - return m_backend->GetRenderContextType(); - } - - QT3DSU32 GetDepthBits() const override - { - // only query this if a framebuffer is bound - if (m_HardwarePropertyContext.m_FrameBuffer) - return m_backend->GetDepthBits(); - else - return m_DephBits; - } - - QT3DSU32 GetStencilBits() const override - { - // only query this if a framebuffer is bound - if (m_HardwarePropertyContext.m_FrameBuffer) - return m_backend->GetStencilBits(); - else - return m_StencilBits; - } - - bool GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const override - { - return m_backend->GetRenderBackendCap(inCap); - } - - bool AreMultisampleTexturesSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::MsTexture); - } - - bool GetConstantBufferSupport() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ConstantBuffer); - } - - bool AreDXTImagesSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DxtImages); - } - - bool IsDepthStencilSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DepthStencilTexture); - } - - bool IsFpRenderTargetSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::FpRenderTarget); - } - - bool IsTessellationSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Tessellation); - } - - bool IsGeometryStageSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Geometry); - } - - bool IsComputeSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Compute); - } - - bool IsSampleQuerySupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::SampleQuery); - } - - bool IsTimerQuerySupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TimerQuery); - } - - bool IsCommandSyncSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::CommandSync); - } - bool IsTextureArraySupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureArray); - } - bool IsStorageBufferSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StorageBuffer); - } - bool IsAtomicCounterBufferSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AtomicCounterBuffer); - } - bool IsShaderImageLoadStoreSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ShaderImageLoadStore); - } - bool IsProgramPipelineSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ProgramPipeline); - } - bool IsPathRenderingSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::PathRendering); - } - // Are blend modes really supported in HW? - bool IsAdvancedBlendHwSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlend); - } - bool IsAdvancedBlendHwSupportedKHR() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlendKHR); - } - bool IsBlendCoherencySupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::BlendCoherency); - } - bool IsStandardDerivativesSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StandardDerivatives); - } - bool IsTextureLodSupported() const override - { - return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureLod); - } - - void SetDefaultRenderTarget(QT3DSU64 targetID) override - { - m_DefaultOffscreenRenderTarget = - (NVRenderBackend::NVRenderBackendRenderTargetObject)targetID; - } - - void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) override { m_DephBits = depthBits; } - - virtual NVRenderDepthStencilState * - CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, - bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) override; - void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) override; - virtual void StateDestroyed(NVRenderDepthStencilState &state); - - NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, - NVRenderFaces::Enum cullFace) override; - void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) override; - virtual void StateDestroyed(NVRenderRasterizerState &state); - - NVRenderVertexBuffer *CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, - size_t size, QT3DSU32 stride, - NVConstDataRef bufferData) override; - NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) override; - virtual void BufferDestroyed(NVRenderVertexBuffer &buffer); - - virtual NVRenderIndexBuffer * - CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, - qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, - NVConstDataRef bufferData) override; - NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) override; - virtual void BufferDestroyed(NVRenderIndexBuffer &buffer); - - virtual NVRenderConstantBuffer * - CreateConstantBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) override; - NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) override; - virtual void BufferDestroyed(NVRenderConstantBuffer &buffer); - - virtual QT3DSU32 GetNextConstantBufferUnit(); - - virtual NVRenderStorageBuffer * - CreateStorageBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) override; - NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) override; - virtual void BufferDestroyed(NVRenderStorageBuffer &buffer); - - virtual NVRenderAtomicCounterBuffer * - CreateAtomicCounterBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) override; - NVRenderAtomicCounterBuffer *GetAtomicCounterBuffer(CRegisteredString bufferName) override; - virtual NVRenderAtomicCounterBuffer * - GetAtomicCounterBufferByParam(CRegisteredString paramName) override; - virtual void BufferDestroyed(NVRenderAtomicCounterBuffer &buffer); - - virtual NVRenderDrawIndirectBuffer * - CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) override; - virtual NVRenderDrawIndirectBuffer * - GetDrawIndirectBuffer(NVRenderBackend::NVRenderBackendBufferObject implementationHandle) override; - virtual void BufferDestroyed(NVRenderDrawIndirectBuffer &buffer); - - void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; - - NVRenderOcclusionQuery *CreateOcclusionQuery() override; - NVRenderTimerQuery *CreateTimerQuery() override; - NVRenderSync *CreateSync() override; - - NVRenderTexture2D *CreateTexture2D() override; - NVRenderTexture2D *GetTexture2D(const void *implementationHandle) override; - virtual void TextureDestroyed(NVRenderTexture2D &buffer); - - NVRenderTexture2DArray *CreateTexture2DArray() override; - virtual void TextureDestroyed(NVRenderTexture2DArray &buffer); - - NVRenderTextureCube *CreateTextureCube() override; - virtual void TextureDestroyed(NVRenderTextureCube &buffer); - - virtual QT3DSU32 GetNextTextureUnit(); - - NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) override; - virtual void ImageDestroyed(NVRenderImage2D &buffer); - - virtual NVRenderRenderBuffer * - CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width, - QT3DSU32 height) override; - NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) override; - virtual void RenderBufferDestroyed(NVRenderRenderBuffer &buffer); - - NVRenderFrameBuffer *CreateFrameBuffer() override; - NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) override; - virtual void FrameBufferDestroyed(NVRenderFrameBuffer &fb); - - virtual NVRenderAttribLayout * - CreateAttributeLayout(NVConstDataRef attribs) override; - NVRenderInputAssembler *CreateInputAssembler( - NVRenderAttribLayout *attribLayout, NVConstDataRef buffers, - const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, - NVConstDataRef offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) override; - void SetInputAssembler(NVRenderInputAssembler *inputAssembler) override; - - NVRenderVertFragCompilationResult CompileSource( - const char *shaderName, NVConstDataRef vertShader, - NVConstDataRef fragShader, - NVConstDataRef tessControlShaderSource = NVConstDataRef(), - NVConstDataRef tessEvaluationShaderSource = NVConstDataRef(), - NVConstDataRef geometryShaderSource = NVConstDataRef(), - bool separateProgram = false, - NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, - bool binaryProgram = false) override; - - virtual NVRenderVertFragCompilationResult - CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, - NVDataRef vertShader, NVDataRef fragShader, - NVDataRef tessControlShaderSource = NVDataRef(), - NVDataRef tessEvaluationShaderSource = NVDataRef(), - NVConstDataRef geometryShaderSource = NVConstDataRef()) override; - - virtual NVRenderVertFragCompilationResult - CompileComputeSource(const char *shaderName, NVConstDataRef computeShaderSource) override; - - NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) override; - virtual void ShaderDestroyed(NVRenderShaderProgram &shader); - - NVRenderProgramPipeline *CreateProgramPipeline() override; - NVRenderPathSpecification *CreatePathSpecification() override; - NVRenderPathRender *CreatePathRender(size_t range = 1) override; - void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; - void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; - void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; - void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) override; - - virtual NVRenderPathFontSpecification * - CreatePathFontSpecification(CRegisteredString fontName) override; - virtual void ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec); - NVRenderPathFontItem *CreatePathFontItem() override; - - void SetClearColor(QT3DSVec4 inClearColor) override; - QT3DSVec4 GetClearColor() const override { return m_HardwarePropertyContext.m_ClearColor; } - - void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) override; - NVRenderBlendFunctionArgument GetBlendFunction() const override - { - return m_HardwarePropertyContext.m_BlendFunction; - } - - void SetBlendEquation(NVRenderBlendEquationArgument inEquations) override; - NVRenderBlendEquationArgument GetBlendEquation() const override - { - return m_HardwarePropertyContext.m_BlendEquation; - }; - - void SetCullingEnabled(bool inEnabled) override; - bool IsCullingEnabled() const override { return m_HardwarePropertyContext.m_CullingEnabled; } - - void SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) override; - qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const override - { - return m_HardwarePropertyContext.m_DepthFunction; - } - - void SetBlendingEnabled(bool inEnabled) override; - bool IsBlendingEnabled() const override - { - return m_HardwarePropertyContext.m_BlendingEnabled; - } - - void SetDepthWriteEnabled(bool inEnabled) override; - bool IsDepthWriteEnabled() const override - { - return m_HardwarePropertyContext.m_DepthWriteEnabled; - } - void SetDepthTestEnabled(bool inEnabled) override; - bool IsDepthTestEnabled() const override - { - return m_HardwarePropertyContext.m_DepthTestEnabled; - } - - void SetStencilTestEnabled(bool inEnabled) override; - bool IsStencilTestEnabled() const override - { - return m_HardwarePropertyContext.m_StencilTestEnabled; - } - - void SetScissorTestEnabled(bool inEnabled) override; - bool IsScissorTestEnabled() const override - { - return m_HardwarePropertyContext.m_ScissorTestEnabled; - } - void SetScissorRect(NVRenderRect inRect) override; - NVRenderRect GetScissorRect() const override - { - return m_HardwarePropertyContext.m_ScissorRect; - } - - void SetViewport(NVRenderRect inViewport) override; - NVRenderRect GetViewport() const override { return m_HardwarePropertyContext.m_Viewport; } - - void SetColorWritesEnabled(bool inEnabled) override; - bool IsColorWritesEnabled() const override - { - return m_HardwarePropertyContext.m_ColorWritesEnabled; - } - - void SetMultisampleEnabled(bool inEnabled) override; - bool IsMultisampleEnabled() const override - { - return m_HardwarePropertyContext.m_MultisampleEnabled; - } - - void SetActiveShader(NVRenderShaderProgram *inShader) override; - NVRenderShaderProgram *GetActiveShader() const override - { - return m_HardwarePropertyContext.m_ActiveShader; - } - - void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) override; - NVRenderProgramPipeline *GetActiveProgramPipeline() const override - { - return m_HardwarePropertyContext.m_ActiveProgramPipeline; - } - - void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, - QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; - - void SetDrawBuffers(NVConstDataRef inDrawBufferSet) override; - void SetReadBuffer(NVReadFaces::Enum inReadFace) override; - - void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat, - NVDataRef inWriteBuffer) override; - - void SetRenderTarget(NVRenderFrameBuffer *inBuffer) override; - void SetReadTarget(NVRenderFrameBuffer *inBuffer) override; - NVRenderFrameBuffer *GetRenderTarget() const override - { - return m_HardwarePropertyContext.m_FrameBuffer; - } - - void ResetBlendState() override; - - // Push the entire set of properties. - void PushPropertySet() override { m_PropertyStack.push_back(m_HardwarePropertyContext); } - - // Pop the entire set of properties, potentially forcing the values - // to opengl. - void PopPropertySet(bool inForceSetProperties) override; - - // clear current bound render target - void Clear(NVRenderClearFlags flags) override; - // clear passed in rendertarget - void Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) override; - - // copy framebuffer content between read target and render target - void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) override; - - void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override; - void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) override; - - NVFoundationBase &GetFoundation() override { return m_Foundation; } - qt3ds::foundation::IStringTable &GetStringTable() override { return m_StringTable; } - NVAllocatorCallback &GetAllocator() override { return m_Foundation.getAllocator(); } - QSurfaceFormat format() const override - { - return m_backend->format(); - } - virtual void resetStates() - { - PushPropertySet(); - PopPropertySet(true); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDataBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDataBuffer.h deleted file mode 100644 index 579e2361..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDataBuffer.h +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DATA_BUFFER_H -#define QT3DS_RENDER_DATA_BUFFER_H -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - class NVRenderBackend; - - ///< Base class - class NVRenderDataBuffer : public NVRefCounted, public NVRenderImplemented - { - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBufferUsageType::Enum m_UsageType; ///< usage type - NVRenderBufferBindFlags m_BindFlags; ///< bind flags - NVDataRef m_BufferData; ///< buffer data pointer - QT3DSU32 m_BufferCapacity; ///< size of internal backup buffer (m_BufferData) - size_t m_BufferSize; ///< size of buffer - bool m_OwnsData; ///< true when we own m_BufferData - bool m_Mapped; ///< true when locked for reading or writing to m_BufferData - NVRenderBackend::NVRenderBackendBufferObject m_BufferHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - *application. - * - * @return No return. - */ - NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t size, - NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usageType, NVDataRef data); - - virtual ~NVRenderDataBuffer(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - /** - * @brief Get Buffer usage type - * - * @return Return usage tyoe - */ - virtual NVRenderBufferUsageType::Enum GetBufferUsageType() const - { - return m_UsageType; - } - - /** - * @brief Get Buffer usage type - * Should be overwritten - * - * @return Return usage tyoe - */ - virtual NVRenderBufferBindFlags GetBufferBindings() const { return m_BindFlags; } - - /** - * @brief Return buffer size in byte - * - * @return Return size - */ - virtual QT3DSU32 Size() { return (QT3DSU32)m_BufferSize; } - - /** - * @brief Get a pointer to the foundation - * - * @return pointer to foundation - */ - NVFoundationBase &GetFoundation() { return m_Foundation; } - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - virtual void Bind() = 0; - - /** - * @brief Map the buffer - * Mapped buffers cannot be used for rendering - * - * @return Return mapped pointer to data - */ - virtual NVDataRef MapBuffer(); - - /** - * @brief Map a range of a buffer - * Mapped buffers cannot be used for rendering - * - * @param[in] offset Offset in bytes into the buffer - * @param[in] size Range in bytes to map - * @param[in] flags Buffer access flags - * - * @return Return mapped pointer to data - */ - virtual NVDataRef MapBufferRange(size_t offset, size_t size, - NVRenderBufferAccessFlags flags); - - /** - * @brief Unmap the buffer - * This updates the data to the hardware - * - * @return no return - */ - virtual void UnmapBuffer(); - - /** - * @brief constructor - * - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * @param[in] ownsMemory If true data will be owned by this object and can therefore be - * released - * - * @return No return. - */ - virtual void UpdateBuffer(NVConstDataRef data, bool ownsMemory = false); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const = 0; - - // this will be obsolete - const void *GetImplementationHandle() const override = 0; - - private: - void releaseMemory(); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDepthStencilState.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDepthStencilState.h deleted file mode 100644 index e6b31981..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDepthStencilState.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DEPTH_STENCIL_STATE_H -#define QT3DS_RENDER_DEPTH_STENCIL_STATE_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - - // currently this handles only stencil state - class NVRenderDepthStencilState : public NVRefCounted - { - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBackend::NVRenderBackendDepthStencilStateObject - m_StateHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] enableDepth enable depth test - * @param[in] depthMask enable depth writes - * @param[in] depthFunc depth compare function - * @param[in] enableStencil enable stencil test - * @param[in] stencilFuncFront stencil setup front faces - * @param[in] stencilFuncBack stencil setup back faces - * @param[in] depthStencilOpFront depth/stencil operations front faces - * @param[in] depthStencilOpBack depth/stencil operations back faces - * - * @return No return. - */ - NVRenderDepthStencilState(NVRenderContextImpl &context, NVFoundationBase &fnd, - bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, - bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack); - - virtual ~NVRenderDepthStencilState(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - ///< various get functions - const NVRenderStencilFunctionArgument GetStencilFunc(NVRenderFaces::Enum face) const - { - return (face == NVRenderFaces::Back) ? m_StencilFuncBack : m_StencilFuncFront; - } - const NVRenderStencilOperationArgument GetStencilOp(NVRenderFaces::Enum face) const - { - return (face == NVRenderFaces::Back) ? m_DepthStencilOpBack : m_DepthStencilOpFront; - } - NVRenderBoolOp::Enum GetDepthFunc() const { return m_DepthFunc; } - bool GetDepthEnabled() const { return m_DepthEnabled; } - bool GetStencilEnabled() const { return m_StencilEnabled; } - bool GetDepthMask() const { return m_DepthMask; } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendDepthStencilStateObject - GetDepthStencilObjectHandle() - { - return m_StateHandle; - } - - static NVRenderDepthStencilState * - Create(NVRenderContextImpl &context, bool enableDepth, bool depthMask, - NVRenderBoolOp::Enum depthFunc, bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack); - - private: - bool m_DepthEnabled; ///< depth test enabled - bool m_DepthMask; ///< depth writes enabled - NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func - bool m_StencilEnabled; ///< stencil test enabled - NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup front faces - NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup back faces - NVRenderStencilOperationArgument - m_DepthStencilOpFront; ///< depth stencil operation front faces - NVRenderStencilOperationArgument - m_DepthStencilOpBack; ///< depth stencil operation back faces - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawIndirectBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawIndirectBuffer.h deleted file mode 100644 index 81cd59d1..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawIndirectBuffer.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H -#include "foundation/Qt3DSOption.h" -#include "foundation/Utils.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderDataBuffer.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - // forward declaration - class NVRenderContextImpl; - - struct DrawArraysIndirectCommand - { - QT3DSU32 count; - QT3DSU32 primCount; - QT3DSU32 first; - QT3DSU32 baseInstance; - }; - - struct DrawElementsIndirectCommand - { - QT3DSU32 count; - QT3DSU32 primCount; - QT3DSU32 firstIndex; - QT3DSU32 baseVertex; - QT3DSU32 baseInstance; - }; - - ///< Constant (uniform) buffer representation - class NVRenderDrawIndirectBuffer : public NVRenderDataBuffer - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return No return. - */ - NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, size_t size, - NVRenderBufferUsageType::Enum usageType, NVDataRef data); - - ///< destructor - virtual ~NVRenderDrawIndirectBuffer(); - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - void Bind() override; - - /** - * @brief update the buffer to hardware - * - * @return no return. - */ - virtual void Update(); - - /** - * @brief update a piece of memory directly within the storage buffer - * - * Note: When you use this function you should know what you are doing. - * The memory layout within C++ must exactly match the memory layout in the - *shader. - * We use std140 (430) layout which guarantees a specific layout behavior across - *all HW vendors. - * How the memory layout is computed can be found in the GL spec. - * - * @param[in] offset offset into storage buffer - * @param[in] data pointer to data - * - * @return no return - */ - void UpdateData(QT3DSI32 offset, NVDataRef data); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - /** - * @brief create a NVRenderDrawIndirectBuffer object - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return the buffer object or NULL - */ - static NVRenderDrawIndirectBuffer *Create(NVRenderContextImpl &context, - NVRenderBufferUsageType::Enum usageType, - size_t size, NVConstDataRef bufferData); - - private: - bool m_Dirty; ///< true if buffer is dirty - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawable.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawable.h deleted file mode 100644 index 0f78aacc..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderDrawable.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H -#define QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H -#include "Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - class NVRenderDrawable - { - protected: - virtual ~NVRenderDrawable() {} - - public: - /** - * Draw using this object. - * offset is in num elements, not in number of bytes - * because the various different draw functions differ in what datatype - * offset is (gl drawarrays vs gl drawindexedarras). - */ - virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFragmentShader.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFragmentShader.h deleted file mode 100644 index f661605c..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFragmentShader.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_FRAGMENT_SHADER_H -#define QT3DS_RENDER_FRAGMENT_SHADER_H - -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderShader.h" - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - - ///< This class represents a fragment shader - class NVRenderFragmentShader : public NVRenderShader - { - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] source Pointer to shader source code - * @param[in] binaryProgram true if this is a binary program - * - * @return No return. - */ - NVRenderFragmentShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram); - - /// @brief destructor - ~NVRenderFragmentShader(); - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - bool IsValid() override { return (m_ShaderHandle != NULL); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendFragmentShaderObject GetShaderHandle() - { - return m_ShaderHandle; - } - - private: - NVRenderBackend::NVRenderBackendFragmentShaderObject - m_ShaderHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFrameBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFrameBuffer.h deleted file mode 100644 index 1882a27d..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderFrameBuffer.h +++ /dev/null @@ -1,277 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAssert.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - class NVRenderTexture2D; - class NVRenderRenderBuffer; - class NVRenderTexture2DArray; - class NVRenderTextureCube; - - class NVRenderTextureOrRenderBuffer - { - NVRenderTexture2D *m_Texture2D; - NVRenderTexture2DArray *m_Texture2DArray; - NVRenderTextureCube *m_TextureCube; - NVRenderRenderBuffer *m_RenderBuffer; - - public: - NVRenderTextureOrRenderBuffer(NVRenderTexture2D &texture) - : m_Texture2D(&texture) - , m_Texture2DArray(NULL) - , m_TextureCube(NULL) - , m_RenderBuffer(NULL) - { - } - NVRenderTextureOrRenderBuffer(NVRenderRenderBuffer &render) - : m_Texture2D(NULL) - , m_Texture2DArray(NULL) - , m_TextureCube(NULL) - , m_RenderBuffer(&render) - { - } - NVRenderTextureOrRenderBuffer(NVRenderTexture2DArray &textureArray) - : m_Texture2D(NULL) - , m_Texture2DArray(&textureArray) - , m_TextureCube(NULL) - , m_RenderBuffer(NULL) - { - } - NVRenderTextureOrRenderBuffer(NVRenderTextureCube &textureCube) - : m_Texture2D(NULL) - , m_Texture2DArray(NULL) - , m_TextureCube(&textureCube) - , m_RenderBuffer(NULL) - { - } - NVRenderTextureOrRenderBuffer() - : m_Texture2D(NULL) - , m_Texture2DArray(NULL) - , m_TextureCube(NULL) - , m_RenderBuffer(NULL) - { - } - NVRenderTextureOrRenderBuffer(const NVRenderTextureOrRenderBuffer &other) - : m_Texture2D(other.m_Texture2D) - , m_Texture2DArray(other.m_Texture2DArray) - , m_TextureCube(other.m_TextureCube) - , m_RenderBuffer(other.m_RenderBuffer) - { - } - NVRenderTextureOrRenderBuffer &operator=(const NVRenderTextureOrRenderBuffer &other) - { - if (this != &other) { - m_Texture2D = const_cast(other.m_Texture2D); - m_Texture2DArray = const_cast(other.m_Texture2DArray); - m_RenderBuffer = const_cast(other.m_RenderBuffer); - m_TextureCube = const_cast(other.m_TextureCube); - } - return *this; - } - - bool HasTexture2D() const { return m_Texture2D != NULL; } - bool HasTexture2DArray() const { return m_Texture2DArray != NULL; } - bool HasTextureCube() const { return m_TextureCube != NULL; } - bool HasRenderBuffer() const { return m_RenderBuffer != NULL; } - - NVRenderTexture2D *GetTexture2D() const - { - QT3DS_ASSERT(HasTexture2D()); - return m_Texture2D; - } - NVRenderTexture2DArray *GetTexture2DArray() const - { - QT3DS_ASSERT(HasTexture2DArray()); - return m_Texture2DArray; - } - NVRenderTextureCube *GetTextureCube() const - { - QT3DS_ASSERT(HasTextureCube()); - return m_TextureCube; - } - NVRenderRenderBuffer *GetRenderBuffer() const - { - QT3DS_ASSERT(HasRenderBuffer()); - return m_RenderBuffer; - } - }; - - class NVRenderFrameBuffer : public NVRefCounted, public NVRenderImplemented - { - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - - NVRenderTextureOrRenderBuffer - m_Attachments[NVRenderFrameBufferAttachments::LastAttachment]; ///< attachments array - NVRenderBackend::NVRenderBackendRenderTargetObject - m_BufferHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd); - - /// destructor - virtual ~NVRenderFrameBuffer(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - /** - * @brief query attachment - * - * - * @return buffer format - */ - virtual NVRenderTextureOrRenderBuffer - GetAttachment(NVRenderFrameBufferAttachments::Enum attachment); - - /** - * @brief Attach a render or texture buffer to a render target - * For texture attachments we use always level 0 - * - * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) - * @param[in] buffer Contains a pointer to the attachment - * @param[in] target Attachment texture target - * - * @return no return - */ - virtual void - Attach(NVRenderFrameBufferAttachments::Enum attachment, - NVRenderTextureOrRenderBuffer buffer, - NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D); - - /** - * @brief Attach a particular layer of the texture 2D array to a render target - * - * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) - * @param[in] buffer Pointer to the Texture Array which contains the - * layers - * @param[in] layer The index to the layer that will be attached to the - * target - * @param[in] level Mip level of the texture that will be attached - * (default 0) - * - * @return no return - */ - virtual void AttachLayer(NVRenderFrameBufferAttachments::Enum attachment, - NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer, - QT3DSI32 level = 0); - - /** - * @brief Attach a particular face of the texture cubemap to a render target - * - * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) - * @param[in] buffer Pointer to the Texture Array which contains the - * layers - * @param[in] face The face of the cubemap that will be attached to the - * target - * @param[in] level Mip level of the texture that will be attached - * (default 0) - * - * @return no return - */ - virtual void AttachFace(NVRenderFrameBufferAttachments::Enum attachment, - NVRenderTextureOrRenderBuffer buffer, - NVRenderTextureCubeFaces::Enum face); - - /** - * @brief Check that this framebuffer is complete and can be rendered to. - * - * - * @return true if complete - */ - virtual bool IsComplete(); - - /** - * @brief query if framebuffer has any attachment - * - * @return true if any attachment - */ - virtual bool HasAnyAttachment() { return (m_AttachmentBits != 0); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendRenderTargetObject GetFrameBuffertHandle() - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - /** - * @brief static creator function - * - * @param[in] context Pointer to context - * - * @return a pointer to framebuffer object. - */ - static NVRenderFrameBuffer *Create(NVRenderContextImpl &context); - - private: - /** - * @brief releaes an attached object - * - * @return which target we released - */ - NVRenderTextureTargetType::Enum releaseAttachment(NVRenderFrameBufferAttachments::Enum idx); - - QT3DSU32 m_AttachmentBits; ///< holds flags for current attached buffers - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderGeometryShader.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderGeometryShader.h deleted file mode 100644 index 2a643cfc..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderGeometryShader.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_GEOMETRY_SHADER_H -#define QT3DS_RENDER_GEOMETRY_SHADER_H - -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderShader.h" - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - - ///< This class represents a vertex shader - class NVRenderGeometryShader : public NVRenderShader - { - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] source Pointer to shader source code - * @param[in] binaryProgram true if this is a binary program - * - * @return No return. - */ - NVRenderGeometryShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram); - - /// @brief destructor - ~NVRenderGeometryShader(); - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - bool IsValid() override { return (m_ShaderHandle != NULL); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendGeometryShaderObject GetShaderHandle() - { - return m_ShaderHandle; - } - - private: - NVRenderBackend::NVRenderBackendGeometryShaderObject - m_ShaderHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderImageTexture.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderImageTexture.h deleted file mode 100644 index 8b3469b0..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderImageTexture.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H -#define QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - class NVRenderTexture2D; - - // a wrapper class for NVRenderTexture2D - // to use with compute shaders and load / store image shaders - - class NVRenderImage2D : public NVRefCounted - { - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderTexture2D *m_Texture2D; ///< pointer to texture - QT3DSI32 m_TextureUnit; ///< texture unit this texture should use - NVRenderImageAccessType::Enum - m_AccessType; ///< texture / image access type ( read, write, read_write ) - QT3DSU32 m_TextureLevel; ///< texture level we use for this image - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] inTexture Pointer to a NVRenderTexture2D object - * @param[in] inAccess Image access type ( read, write, read_write ) - * - * @return No return. - */ - NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTexture2D *inTexture, NVRenderImageAccessType::Enum inAccess); - - virtual ~NVRenderImage2D(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief Set the access rights within the shader. - * Can be read, write or read_write. - * - * @param[in] inAccess Image access type ( read, write, read_write ) - * - * @return No return. - */ - virtual void SetAccessType(NVRenderImageAccessType::Enum inAccess) - { - m_AccessType = inAccess; - } - - /** - * @brief Set the texture level we use for this image - * - * @param[in] inLevel texture level ( must be in range of max levels ) - * - * @return No return. - */ - virtual void SetTextureLevel(QT3DSI32 inLevel); - - /** - * @brief Get texture unit used - * - * - * @return texture unit bound to. - */ - virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; } - - /** - * @brief Bind a texture for shader access - * - * @param[in] unit The binding point - * - * @return No return. - */ - virtual void Bind(QT3DSU32 unit); - - /** - * @brief get the backend object handle - * here we return the handle from the wrapped texture - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle(); - - /** - * @brief static creation function - * - * @param[in] context Pointer to context - * @param[in] inTexture Pointer to a NVRenderTexture2D object - * @param[in] inAccess Image access type ( read, write, read_write ) - * - * @return No return. - */ - static NVRenderImage2D *Create(NVRenderContextImpl &context, NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderIndexBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderIndexBuffer.h deleted file mode 100644 index 6b9c4711..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderIndexBuffer.h +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_INDEX_BUFFER_H -#define QT3DS_RENDER_INDEX_BUFFER_H -#include "render/Qt3DSRenderDataBuffer.h" -#include "render/Qt3DSRenderDrawable.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - - class NVRenderIndexBuffer : public NVRenderDataBuffer, public NVRenderDrawable - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] componentType Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return No return. - */ - NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size, - NVRenderComponentTypes::Enum componentType, - NVRenderBufferUsageType::Enum usageType, NVDataRef data); - - ///< destruvtor - ~NVRenderIndexBuffer(); - - /** - * @brief get the component type (QT3DSU8, QT3DSU16) - * - * @return the component type - */ - virtual NVRenderComponentTypes::Enum GetComponentType() const { return m_ComponentType; } - - /** - * @brief get the index count - * - * @return actual index count - */ - virtual QT3DSU32 GetNumIndices() const; - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - void Bind() override; - - /** - * @brief draw the buffer - * - * @param[in] drawMode draw mode (e.g Triangles...) - * @param[in] count vertex count - * @param[in] offset start offset in byte - * - * @return no return. - */ - void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override; - - /** - * @brief draw the buffer via indirec draw buffer setup - * - * @param[in] drawMode draw mode (e.g Triangles...) - * @param[in] offset byte offset into the bound drawIndirectBuffer see - * NVRenderDrawIndirectBuffer - * - * @return no return. - */ - virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - static NVRenderIndexBuffer *Create(NVRenderContextImpl &context, - NVRenderBufferUsageType::Enum usageType, - NVRenderComponentTypes::Enum componentType, size_t size, - NVConstDataRef bufferData); - - private: - NVRenderComponentTypes::Enum m_ComponentType; ///< component type (QT3DSU8, QT3DSU16) - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderInputAssembler.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderInputAssembler.h deleted file mode 100644 index adac4c42..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderInputAssembler.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_INPUT_ASSEMBLER_H -#define QT3DS_RENDER_INPUT_ASSEMBLER_H - -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Utils.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - // forward declarations - class NVRenderContextImpl; - class NVRenderBackend; - class NVRenderAttribLayout; - - ///< this class handles the vertex attribute layout setup - class NVRenderInputAssembler : public NVRefCounted - { - public: - /** - * @brief constructor - * - * NOTE: The limit for buffers count is currently 16 - * - * @param[in] context Pointer to context - * @param[in] attribLayout Pointer to NVRenderAttribLayout object - * @param[in] buffers list of vertex buffers - * @param[in] indexBuffer pointer to index buffer. Can be NULL - * @param[in] strides list of strides of the buffer - * @param[in] offsets list of offsets into the buffer - * @param[in] primType primitive type used for drawing - * @param[in] patchVertexCount if primitive is "Patch" this is the vertex count for a - *single patch - * - * @return No return. - */ - NVRenderInputAssembler(NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout, - NVConstDataRef buffers, - const NVRenderIndexBuffer *indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets, - NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles, - QT3DSU32 patchVertexCount = 1); - ///< destructor - ~NVRenderInputAssembler(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendInputAssemblerObject GetInputAssemblerHandle() const - { - return m_InputAssemblertHandle; - } - - /** - * @brief get the attached index buffer - * - * @return the index buffer - */ - const NVRenderIndexBuffer *GetIndexBuffer() { return m_IndexBuffer; } - - /** - * @brief get the index count of the attached index buffer (if any) - * - * @return the index buffer count - */ - QT3DSU32 GetIndexCount() const; - - /** - * @brief get the vertex count of the buffer - * Note this makes only sense if we have a single - * interleaved buffer - * - * @return the vertex buffer count - */ - QT3DSU32 GetVertexCount() const; - - /** - * @brief get the primitive type used for drawing - * - * @return primitive type - */ - NVRenderDrawMode::Enum GetPrimitiveType() const { return m_PrimitiveType; } - - /** - * @brief set the per vertex patch count - * - * @return none - */ - void SetPatchVertexCount(QT3DSU32 count) - { - if (count != m_PatchVertexCount) { - // clamp to 1; - m_PatchVertexCount = (count == 0) ? 1 : count; - ; - m_Backend->SetPatchVertexCount(m_InputAssemblertHandle, m_PatchVertexCount); - } - } - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - - NVRenderAttribLayout *m_AttribLayout; ///< pointer to attribute layout - nvvector m_VertexBuffers; ///< vertex buffers - const NVRenderIndexBuffer *m_IndexBuffer; ///< index buffer - NVConstDataRef - m_VertexbufferHandles; ///< opaque vertex buffer backend handles - - NVRenderBackend::NVRenderBackendInputAssemblerObject - m_InputAssemblertHandle; ///< opaque backend handle - NVRenderDrawMode::Enum m_PrimitiveType; ///< primitive type used for drawing - QT3DSU32 m_PatchVertexCount; ///< vertex count if primitive type is patch - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderOcclusionQuery.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderOcclusionQuery.h deleted file mode 100644 index 04f64e97..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderOcclusionQuery.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_OCCLUSION_QUERY_H -#define QT3DS_RENDER_OCCLUSION_QUERY_H - -#include "render/Qt3DSRenderQueryBase.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - - class NVRenderOcclusionQuery : public NVRenderQueryBase - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderOcclusionQuery(NVRenderContextImpl &context, NVFoundationBase &fnd); - - ///< destructor - ~NVRenderOcclusionQuery(); - - /** - * @brief Get query type - * - * @return Return query type - */ - NVRenderQueryType::Enum GetQueryType() const override - { - return NVRenderQueryType::Samples; - } - - /** - * @brief Get a pointer to the foundation - * - * @return pointer to foundation - */ - NVFoundationBase &GetFoundation() { return m_Foundation; } - - /** - * @brief begin a query - * - * @return no return. - */ - void Begin() override; - - /** - * @brief end a query - * - * @return no return. - */ - void End() override; - - /** - * @brief Get the result of a query - * - * @param[out] params Contains result of query regarding query type - * - * @return no return. - */ - void GetResult(QT3DSU32 *params) override; - - /** - * @brief query if a result is available - * - * - * @return true if available. - */ - virtual bool GetResultAvailable(); - - /* - * @brief static creation function - * - * * @return a occlusion query object on success - */ - static NVRenderOcclusionQuery *Create(NVRenderContextImpl &context); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontSpecification.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontSpecification.h deleted file mode 100644 index dad3f6bb..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontSpecification.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ #pragma once -#ifndef QT3DS_RENDER_PATH_FONT_SPECIFICATION_H -#define QT3DS_RENDER_PATH_FONT_SPECIFICATION_H -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/StringTable.h" -#include "EASTL/string.h" -#include "render/backends/Qt3DSRenderBackend.h" - - namespace qt3ds -{ - namespace render { - - using namespace foundation; - - class NVRenderContextImpl; - class NVRenderPathRender; - class NVRenderPathFontItem; - - class NVRenderPathFontSpecification : public NVRefCounted - { - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - NVRenderBackend *m_Backend; ///< pointer to backend - volatile QT3DSI32 - mRefCount; ///< Using foundations' naming convention to ease implementation - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] fontName Name of font ( may include path - * ) - * - * @return No return. - */ - NVRenderPathFontSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd, - CRegisteredString fontName); - - /// @NVRenderPathSpecification destructor - ~NVRenderPathFontSpecification(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief Load numGlyphs glyphs from specified font file - * - * @param[in] pathBase Base of path objects - * @param[in] fontName Name of font ( may include path - * ) - * @param[in] numGlyphs Glyph count - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes character string - * - * @return No return - */ - virtual void LoadPathGlyphs(const char *fontName, NVRenderPathFormatType::Enum type); - - /** - * @brief Render a stencil fill pass for fonts - * - * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification - * - * @return no return - */ - void StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem); - - /** - * @brief Render a cover fill pass for fonts - * - * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification - * - * @return no return - */ - void CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem); - - /** - * @brief get type for font path set - * - * @return path font type - */ - NVRenderPathFormatType::Enum GetPathFontType() { return m_Type; } - - /** - * @brief get font glyph count - * - * @return get glyph count - */ - QT3DSU32 GetFontGlyphsCount() { return m_NumFontGlyphs; } - - /** - * @brief get spacing for char set - * - * @return spacing array - */ - QT3DSF32 GetEmScale() const { return m_EmScale; } - - /** - * @brief Get font name - * - * @return name set - */ - CRegisteredString GetFontName() const { return m_FontName; } - - private: - QT3DSU32 m_NumFontGlyphs; ///< glyph count of the entire font set - QT3DSF32 m_EmScale; ///< true type scale - NVRenderPathFormatType::Enum m_Type; ///< type ( byte, int,... ) - NVRenderPathTransformType::Enum m_TransformType; ///< transform type default 2D - CRegisteredString m_FontName; ///< Name of Font - NVRenderBackend::NVRenderBackendPathObject - m_PathRenderHandle; ///< opaque backend handle - - private: - /** - * @brief Get size of type - * - * @param[in] type type ( byte, int,... ) - * - * @return true if successful - */ - QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type); - - public: - static NVRenderPathFontSpecification * - CreatePathFontSpecification(NVRenderContextImpl &context, CRegisteredString fontName); - }; - } -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontText.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontText.h deleted file mode 100644 index a1d103ac..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathFontText.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ #pragma once -#ifndef QT3DS_RENDER_PATH_FONT_TEXT_H -#define QT3DS_RENDER_PATH_FONT_TEXT_H -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "EASTL/string.h" -#include "render/backends/Qt3DSRenderBackend.h" - - namespace qt3ds -{ - namespace render { - - using namespace foundation; - - class NVRenderContextImpl; - class NVRenderPathFontSpecification; - - class NVRenderPathFontItem : public NVRefCounted - { - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 - mRefCount; ///< Using foundations' naming convention to ease implementation - - public: - /** - * @brief constructor - * - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderPathFontItem(NVFoundationBase &fnd); - - /// @NVRenderPathFontItem destructor - ~NVRenderPathFontItem(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief Setup text - * - * @param[in] glyphCount number of glyphs - * @param[in] glyphIDs array of glyhp ID's - * @param[in] type type ( byte, int,... ) - * @param[in] posArray array of glyhp positions - * @param[in] pixelBound pixel boundary - * @param[in] logicalBound logical boundary - * @param[in] emScale true type scale - * - * @return No return. - */ - void InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs, - NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, QT3DSVec2 pixelBound, - QT3DSVec2 logicalBound, QT3DSF32 emScale); - - /** - * @brief get glyph count - * - * @return get glyph count - */ - size_t GetGlyphsCount() { return m_NumGlyphs; } - - /** - * @brief get spacing for char set - * - * @return spacing array - */ - const QT3DSF32 *GetSpacing() { return m_TranslateXY; } - - /** - * @brief get name set - * - * @return name set - */ - const void *GetGlyphIDs() { return (void *)m_GlyphIDs; } - - /** - * @brief Get Y bound of font metric - * - * @return transform matrix - */ - const QT3DSMat44 GetTransform(); - - private: - /** - * @brief Get size of type - * - * @param[in] type type ( byte, int,... ) - * - * @return true if successful - */ - QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type); - - private: - size_t m_NumGlyphs; ///< glyph count - QT3DSU32 *m_GlyphIDs; ///< array glyph ID's - QT3DSF32 * - m_TranslateXY; ///< pointer to arrray for character advance information like kerning - QT3DSMat44 m_ModelMatrix; ///< Matrix which converts from font space to box space - - public: - static NVRenderPathFontItem *CreatePathFontItem(NVRenderContextImpl &context); - }; - } -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathRender.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathRender.h deleted file mode 100644 index c261ca31..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathRender.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PATH_RENDER_H -#define QT3DS_RENDER_PATH_RENDER_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "foundation/Qt3DSBounds3.h" -#include - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - class NVRenderPathSpecification; - class NVRenderPathFontSpecification; - - ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....) - class NVRenderPathRender : public NVRefCounted - { - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - NVRenderBackend *m_Backend; ///< pointer to backend - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] range Number of internal objects - * - * @return No return. - */ - NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t range); - - /// @brief destructor - ~NVRenderPathRender(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendPathObject GetPathHandle() { return m_PathRenderHandle; } - - // The render context can create a path specification object. - void SetPathSpecification(NVRenderPathSpecification &inCommandBuffer); - - NVBounds3 GetPathObjectBoundingBox(); - NVBounds3 GetPathObjectFillBox(); - NVBounds3 GetPathObjectStrokeBox(); - - void SetStrokeWidth(QT3DSF32 inStrokeWidth); - QT3DSF32 GetStrokeWidth() const; - - void StencilStroke(); - void StencilFill(); - - /** - * @brief static create function - * - * @param[in] context Pointer to render context - * @param[in] range Number of internal objects - * - * @return the backend object handle. - */ - static NVRenderPathRender *Create(NVRenderContextImpl &context, size_t range); - - private: - NVRenderBackend::NVRenderBackendPathObject m_PathRenderHandle; ///< opaque backend handle - size_t m_Range; ///< range of internal objects - QT3DSF32 m_StrokeWidth; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathSpecification.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathSpecification.h deleted file mode 100644 index 7c6faeda..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderPathSpecification.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PATH_SPECIFICATION_H -#define QT3DS_RENDER_PATH_SPECIFICATION_H -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - class NVRenderContextImpl; - - class NVRenderPathSpecification : public NVRefCounted - { - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - NVRenderBackend *m_Backend; ///< pointer to backend - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderPathSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd); - - /// @NVRenderPathSpecification destructor - ~NVRenderPathSpecification(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief reset commands and coordiantes - * - * @return No return. - */ - virtual void Reset(); - - /** - * @brief add new move to command - * - * @param[in] inPoint Coordinate - * - * @return No return. - */ - virtual void MoveTo(QT3DSVec2 inPoint); - - /** - * @brief add new cubic curve command - * - * @param[in] inC1 control point 1 - * @param[in] inC2 control point 2 - * @param[in] inDest final point - * - * @return No return. - */ - virtual void CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest); - - /** - * @brief add new close command - * - * - * @return No return. - */ - virtual void ClosePath(); - - /** - * @brief Get path command list - * - * - * @return path commands - */ - virtual NVConstDataRef GetPathCommands() { return m_PathCommands; } - - /** - * @brief Get path coordinates list - * - * - * @return path coordinates - */ - virtual NVConstDataRef GetPathCoords() { return m_PathCoords; } - - private: - nvvector m_PathCommands; - nvvector m_PathCoords; - - /** - * @brief add a new point to the coordinates - * - * @param[in] inPoint Coordinate - * - * @return No return. - */ - void P(QT3DSVec2 inData); - - public: - static NVRenderPathSpecification *CreatePathSpecification(NVRenderContextImpl &context); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderProgramPipeline.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderProgramPipeline.h deleted file mode 100644 index ce47146a..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderProgramPipeline.h +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PROGRAM_PIPLINE_H -#define QT3DS_RENDER_PROGRAM_PIPLINE_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderContext.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - class NVRenderShaderProgram; - - ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....) - class QT3DS_AUTOTEST_EXPORT NVRenderProgramPipeline : public NVRefCounted - { - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - NVRenderBackend *m_Backend; ///< pointer to backend - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderProgramPipeline(NVRenderContextImpl &context, NVFoundationBase &fnd); - - /// @brief destructor - ~NVRenderProgramPipeline(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief Query if pipeline is valid - * - * @return True if valid. - */ - bool IsValid(); - - /** - * @brief enable / disable a program stage in the pipeline - * - * @param[in] pProgram Pointer to program. If NULL stage will be disabled - * @param[in] flags Flags to which stage this program is bound to. Can more than - * one stage - * - * @return no return. - */ - void SetProgramStages(NVRenderShaderProgram *pProgram, NVRenderShaderTypeFlags flags); - - /** - * @brief Make the program pipeline active - * - * @return True if valid. - */ - void Bind(); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendProgramPipeline GetShaderHandle() - { - return m_ProgramPipelineHandle; - } - - /** - * @brief get the vertex stage program - * - * @return the backend object handle. - */ - NVRenderShaderProgram *GetVertexStage() { return m_VertexProgram; } - - private: - NVRenderBackend::NVRenderBackendProgramPipeline - m_ProgramPipelineHandle; ///< opaque backend handle - - NVRenderShaderProgram - *m_Program; ///< for non separable programs this contains the entire program - NVRenderShaderProgram - *m_VertexProgram; ///< for separable programs this contains the vertex program - NVRenderShaderProgram - *m_FragmentProgram; ///< for separable programs this contains the fragment program - NVRenderShaderProgram *m_TessControlProgram; ///< for separable programs this contains the - ///tessellation control program - NVRenderShaderProgram *m_TessEvalProgram; ///< for separable programs this contains the - ///tessellation evaluation program - NVRenderShaderProgram - *m_GeometryProgram; ///< for separable programs this contains the geometry program - NVRenderShaderProgram - *m_ComputProgram; ///< for separable programs this contains the compute program - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderQueryBase.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderQueryBase.h deleted file mode 100644 index 7a7ead87..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderQueryBase.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QUERY_BASE_H -#define QT3DS_RENDER_QUERY_BASE_H -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - class NVRenderBackend; - - ///< Base class - class NVRenderQueryBase : public NVRefCounted - { - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBackend::NVRenderBackendQueryObject m_QueryHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd); - - virtual ~NVRenderQueryBase(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief Get query type - * - * @return Return query type - */ - virtual NVRenderQueryType::Enum GetQueryType() const = 0; - - /** - * @brief Get a pointer to the foundation - * - * @return pointer to foundation - */ - NVFoundationBase &GetFoundation() { return m_Foundation; } - - /** - * @brief begin a query - * - * @return no return. - */ - virtual void Begin() = 0; - - /** - * @brief end a query - * - * @return no return. - */ - virtual void End() = 0; - - /** - * @brief Get the result of a query - * - * @param[out] params Contains result of query regarding query type - * - * @return no return. - */ - virtual void GetResult(QT3DSU32 *params) = 0; - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendQueryObject GetQuerytHandle() const - { - return m_QueryHandle; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRasterizerState.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRasterizerState.h deleted file mode 100644 index 9b71ae42..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRasterizerState.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_RASTERIZER_STATE_H -#define QT3DS_RENDER_RASTERIZER_STATE_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - - // currently this handles only stencil state - class NVRenderRasterizerState : public NVRefCounted - { - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBackend::NVRenderBackendRasterizerStateObject - m_StateHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] depthBias depth bias - * @param[in] depthScale depth multiplicator - * @param[in] cullFace which face to cull front or back - * - * @return No return. - */ - NVRenderRasterizerState(NVRenderContextImpl &context, NVFoundationBase &fnd, - QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace); - - virtual ~NVRenderRasterizerState(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendRasterizerStateObject GetRasterizerObjectHandle() - { - return m_StateHandle; - } - - static NVRenderRasterizerState *Create(NVRenderContextImpl &context, QT3DSF32 depthBias, - QT3DSF32 depthScale, NVRenderFaces::Enum cullFace); - - private: - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRenderBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRenderBuffer.h deleted file mode 100644 index 41f4068a..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderRenderBuffer.h +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - class NVRenderContextImpl; - - struct NVRenderRenderBufferDimensions - { - QT3DSU32 m_Width; ///< buffer width - QT3DSU32 m_Height; ///< buffer height - - NVRenderRenderBufferDimensions(QT3DSU32 w, QT3DSU32 h) - : m_Width(w) - , m_Height(h) - { - } - NVRenderRenderBufferDimensions() - : m_Width(0) - , m_Height(0) - { - } - }; - - class NVRenderRenderBuffer : public NVRefCounted, public NVRenderImplemented - { - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - QT3DSU32 m_Width; ///< buffer width - QT3DSU32 m_Height; ///< buffer height - NVRenderRenderBufferFormats::Enum m_StorageFormat; ///< buffer storage format - - NVRenderBackend::NVRenderBackendRenderbufferObject - m_BufferHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] format Renderbuffer format - * @param[in] width Renderbuffer width - * @param[in] height Renderbuffer height - * - * @return No return. - */ - NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, QT3DSU32 height); - - /// destructor - virtual ~NVRenderRenderBuffer(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - /** - * @brief query buffer format - * - * - * @return buffer format - */ - virtual NVRenderRenderBufferFormats::Enum GetStorageFormat() const - { - return m_StorageFormat; - } - - /** - * @brief query buffer dimension - * - * - * @return NVRenderRenderBufferDimensions object - */ - virtual NVRenderRenderBufferDimensions GetDimensions() const - { - return NVRenderRenderBufferDimensions(m_Width, m_Height); - } - - /** - * @brief constructor - * - * @param[in] inDimensions A dimension object - * - * @return buffer format - */ - virtual void SetDimensions(const NVRenderRenderBufferDimensions &inDimensions); - - /** - * @brief static creator function - * - * @param[in] context Pointer to context - * @param[in] format Renderbuffer format - * @param[in] width Renderbuffer width - * @param[in] height Renderbuffer height - * - * @return No return. - */ - static NVRenderRenderBuffer *Create(NVRenderContextImpl &context, - NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, - QT3DSU32 height); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendRenderbufferObject GetRenderBuffertHandle() - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSampler.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSampler.h deleted file mode 100644 index 77d3f008..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSampler.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H -#define QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - - class NVRenderTextureSampler - { - public: - NVRenderTextureMinifyingOp::Enum m_MinFilter; - NVRenderTextureMagnifyingOp::Enum m_MagFilter; - NVRenderTextureCoordOp::Enum m_WrapS; - NVRenderTextureCoordOp::Enum m_WrapT; - NVRenderTextureCoordOp::Enum m_WrapR; - NVRenderTextureSwizzleMode::Enum m_SwizzleMode; - QT3DSF32 m_MinLod; - QT3DSF32 m_MaxLod; - QT3DSF32 m_LodBias; - NVRenderTextureCompareMode::Enum m_CompareMode; - NVRenderTextureCompareOp::Enum m_CompareOp; - QT3DSF32 m_Anisotropy; - QT3DSF32 m_BorderColor[4]; - - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] minFilter Texture min filter - * @param[in] magFilter Texture mag filter - * @param[in] wrapS Texture coord generation for S - * @param[in] wrapT Texture coord generation for T - * @param[in] wrapR Texture coord generation for R - * @param[in] swizzleMode Texture swizzle mode - * @param[in] minLod Texture min level of detail - * @param[in] maxLod Texture max level of detail - * @param[in] lodBias Texture level of detail bias (unused) - * @param[in] compareMode Texture compare mode - * @param[in] compareFunc Texture compare function - * @param[in] anisoFilter Aniso filter value [1.0, 16.0] - * @param[in] borderColor Texture border color float[4] (unused) - * - * @return No return. - */ - NVRenderTextureSampler( - NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle, - QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL); - - /** - * @brief destructor - * - */ - virtual ~NVRenderTextureSampler(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendSamplerObject GetSamplerHandle() const - { - return m_SamplerHandle; - } - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBackend::NVRenderBackendSamplerObject m_SamplerHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShader.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShader.h deleted file mode 100644 index 8d0a62c4..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShader.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_H -#define QT3DS_RENDER_SHADER_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderContext.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - - ///< A shader program is an object composed of a multiple shaders (vertex, fragment, - ///geometry,....) - class NVRenderShader - { - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - NVRenderBackend *m_Backend; ///< pointer to backend - NVConstDataRef m_Source; ///< shader source code - bool m_Binary; ///< true for binary programs - eastl::string m_ErrorMessage; ///< contains the error message if linking fails - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram) - : m_Context(context) - , m_Foundation(fnd) - , m_Backend(context.GetBackend()) - , m_Source(source) - , m_Binary(binaryProgram) - { - } - - /// @brief destructor - ~NVRenderShader(){} - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - virtual bool IsValid() = 0; - - /** - * @brief Get Error Message - * - * @param[out] messageLength Pointer to error string - * @param[out] messageLength Size of error meesage - * - * @return no return - */ - virtual void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage) - { - // Since we do not have any error message just generate a generic one - if (m_Binary) - m_ErrorMessage = "Binary shader compilation failed"; - - *messageLength = m_ErrorMessage.size(); - errorMessage = m_ErrorMessage.c_str(); - } - - /** - * @brief Get Error Message - * - * - * @return error message. - */ - virtual const char *GetErrorMessage() - { - if (m_Binary) - m_ErrorMessage = "Binary shader compilation failed"; - - return m_ErrorMessage.c_str(); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h deleted file mode 100644 index 7fb57ffe..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h +++ /dev/null @@ -1,448 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_CONSTANT_H -#define QT3DS_RENDER_SHADER_CONSTANT_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSMat33.h" -#include "foundation/Qt3DSMat44.h" -#include "EASTL/string.h" -#include "EASTL/utility.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - using namespace foundation; - - ///< forward declarations - class NVRenderContextImpl; - class NVRenderConstantBuffer; - - ///< A shader constant belongs to a program - class QT3DS_AUTOTEST_EXPORT NVRenderShaderConstantBase - { - public: - NVRenderBackend *m_Backend; ///< pointer to backend - CRegisteredString m_Name; ///< register constant name - QT3DSI32 m_Location; ///< constant index - QT3DSI32 m_ElementCount; ///< constant element count for arrays - NVRenderShaderDataTypes::Enum m_Type; ///< constant type - QT3DSI32 m_Binding; ///< sampler/imnage binding point - - public: - NVRenderShaderConstantBase(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding) - : m_Backend(backend) - , m_Name(name) - , m_Location(location) - , m_ElementCount(elementCount) - , m_Type(type) - , m_Binding(binding) - { - } - - NVRenderShaderDataTypes::Enum GetShaderConstantType() const { return m_Type; } - - virtual void Release() = 0; - }; - - ///< A general class for shader types - template - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - TDataType m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - memset(&m_Value, 0, sizeof(TDataType)); - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< A specialized class for textures - template <> - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSU32 m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - m_Value = QT3DS_MAX_U32; - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< A specialized class for textures - template <> - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QVector m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - m_Value.resize(elementCount); - m_Value.fill(QT3DS_MAX_U32); - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< A specialized class for texture arrays - template <> - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSU32 m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - m_Value = QT3DS_MAX_U32; - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< A specialized class for cubemap textures - template <> - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSU32 m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - m_Value = QT3DS_MAX_U32; - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< A specialized class for cubemap textures - template <> - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QVector m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - m_Value.resize(elementCount); - m_Value.fill(QT3DS_MAX_U32); - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< A specialized class for texture image buffer - template <> - class NVRenderShaderConstant : public NVRenderShaderConstantBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSU32 m_Value; ///< constant value - - public: - NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, - QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, - QT3DSI32 binding, NVFoundationBase &allocator) - : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) - , m_Foundation(allocator) - { - m_Value = QT3DS_MAX_U32; - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override { NVDelete(GetFoundation().getAllocator(), this); } - }; - - ///< Base for any buffer ( constant, texture, ... ) which is used by this program - class NVRenderShaderBufferBase - { - public: - NVRenderContextImpl &m_Context; ///< pointer to context - CRegisteredString m_Name; ///< buffer name - QT3DSU32 m_Location; ///< program buffer block location - QT3DSU32 m_Binding; ///< program buffer binding - QT3DSI32 m_Size; ///< buffer size - - public: - NVRenderShaderBufferBase(NVRenderContextImpl &context, CRegisteredString name, - QT3DSI32 location, QT3DSI32 binding, QT3DSI32 size) - : m_Context(context) - , m_Name(name) - , m_Location(location) - , m_Binding(binding) - , m_Size(size) - { - } - - virtual void Release() = 0; - - virtual void Validate(NVRenderShaderProgram *inShader) = 0; - virtual void BindToProgram(NVRenderShaderProgram *inShader) = 0; - virtual void Update() = 0; - }; - - class NVRenderShaderConstantBuffer : public NVRenderShaderBufferBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer - NVRenderConstantBuffer *m_pCB; ///< pointer to constant buffer - - public: - NVRenderShaderConstantBuffer(NVRenderContextImpl &context, CRegisteredString name, - QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, - NVRenderConstantBuffer *pCB, NVFoundationBase &allocator) - : NVRenderShaderBufferBase(context, name, location, binding, size) - , m_Foundation(allocator) - , m_ParamCount(count) - , m_pCB(pCB) - { - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override - { - if (m_pCB) - m_pCB->release(); - - NVDelete(GetFoundation().getAllocator(), this); - } - - void Validate(NVRenderShaderProgram *inShader) override - { - // A constant buffer might not be set at first call - // due to the fact that they are compiled from a cache file - // Now it must exists. - if (m_pCB) - return; - - NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(m_Name); - if (cb) { - cb->SetupBuffer(inShader, m_Location, m_Size, m_ParamCount); - cb->addRef(); - m_pCB = cb; - } else { - QT3DS_ASSERT(false); - } - } - - void Update() override - { - if (m_pCB) - m_pCB->Update(); - } - - void BindToProgram(NVRenderShaderProgram *inShader) override - { - if (m_pCB) - m_pCB->BindToShaderProgram(inShader, m_Location, m_Binding); - } - }; - - class NVRenderShaderStorageBuffer : public NVRenderShaderBufferBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer - NVRenderStorageBuffer *m_pSB; ///< pointer to storage buffer - - public: - NVRenderShaderStorageBuffer(NVRenderContextImpl &context, CRegisteredString name, - QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, - NVRenderStorageBuffer *pSB, NVFoundationBase &allocator) - : NVRenderShaderBufferBase(context, name, location, binding, size) - , m_Foundation(allocator) - , m_ParamCount(count) - , m_pSB(pSB) - { - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override - { - if (m_pSB) - m_pSB->release(); - - NVDelete(GetFoundation().getAllocator(), this); - } - - void Validate(NVRenderShaderProgram * /*inShader*/) override - { - // A constant buffer might not be set at first call - // due to the fact that they are compile from a cache file - // Now it must exists. - if (m_pSB) - return; - - NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(m_Name); - if (sb) { - sb->addRef(); - m_pSB = sb; - } else { - QT3DS_ASSERT(false); - } - } - - void Update() override - { - if (m_pSB) - m_pSB->Update(); - } - - void BindToProgram(NVRenderShaderProgram * /*inShader*/) override - { - if (m_pSB) - m_pSB->BindToShaderProgram(m_Location); - } - }; - - class NVRenderShaderAtomicCounterBuffer : public NVRenderShaderBufferBase - { - public: - NVFoundationBase &m_Foundation; ///< allocator - QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer - NVRenderAtomicCounterBuffer *m_pAcB; ///< pointer to atomic counter buffer - - public: - NVRenderShaderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString name, - QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, - NVRenderAtomicCounterBuffer *pAcB, - NVFoundationBase &allocator) - : NVRenderShaderBufferBase(context, name, location, binding, size) - , m_Foundation(allocator) - , m_ParamCount(count) - , m_pAcB(pAcB) - { - } - - NVFoundationBase &GetFoundation() { return m_Foundation; } - - void Release() override - { - if (m_pAcB) - m_pAcB->release(); - - NVDelete(GetFoundation().getAllocator(), this); - } - - void Validate(NVRenderShaderProgram * /*inShader*/) override - { - // A constant buffer might not be set at first call - // due to the fact that they are compile from a cache file - // Now it must exists. - if (m_pAcB) - return; - - NVRenderAtomicCounterBuffer *acb = m_Context.GetAtomicCounterBuffer(m_Name); - if (acb) { - acb->addRef(); - m_pAcB = acb; - } else { - QT3DS_ASSERT(false); - } - } - - void Update() override - { - if (m_pAcB) - m_pAcB->Update(); - } - - void BindToProgram(NVRenderShaderProgram * /*inShader*/) override - { - if (m_pAcB) - m_pAcB->BindToShaderProgram(m_Location); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h deleted file mode 100644 index 054db64b..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h +++ /dev/null @@ -1,540 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_PROGRAM_H -#define QT3DS_RENDER_SHADER_PROGRAM_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderShaderConstant.h" -#include "EASTL/string.h" -#include "EASTL/utility.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - ///< forward declarations - class NVRenderContextImpl; - class NVRenderVertexShader; - class NVRenderFragmentShader; - class NVRenderTessControlShader; - class NVRenderTessEvaluationShader; - class NVRenderGeometryShader; - class NVRenderShaderConstantBase; - class NVRenderShaderBufferBase; - class NVRenderComputeShader; - - typedef nvhash_map TShaderConstantMap; - typedef nvhash_map TShaderBufferMap; - - ///< A shader program is an object composed of a multiple shaders (vertex, fragment, - ///geometry,....) - class QT3DS_AUTOTEST_EXPORT NVRenderShaderProgram : public NVRefCounted - { - public: - struct ProgramType - { - enum Enum { Graphics, Compute }; - }; - - private: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - const char *m_ProgramName; /// Name of the program - NVRenderBackend::NVRenderBackendShaderProgramObject - m_ProgramHandle; ///< opaque backend handle - TShaderConstantMap m_Constants; ///< map of shader constants - TShaderBufferMap m_ShaderBuffers; ///< map of shader buffers - ProgramType::Enum m_ProgramType; ///< shader type - eastl::string m_ErrorMessage; ///< contains the error message if linking fails - - /** - * @brief create vertex shader - * - * @param[in] context Pointer to render context - * @param[in] vertexShaderSource Fragment shader source code - * @param[in] binaryProgram True if binary program - * - * @return pointer to vertex shader object - */ - static Option - createVertexShader(NVRenderContextImpl &context, NVConstDataRef vertexShaderSource, - bool binaryProgram = false); - - /** - * @brief create fragment shader - * - * @param[in] context Pointer to render context - * @param[in] fragmentShaderSource Fragment shader source code - * @param[in] binaryProgram True if binary program - * - * @return pointer to fragment shader object - */ - static Option - createFragmentShader(NVRenderContextImpl &context, - NVConstDataRef fragmentShaderSource, bool binaryProgram = false); - - /** - * @brief create tesselation control shader - * - * @param[in] context Pointer to render context - * @param[in] tessControlShaderSource Tessellation control shader source code - * @param[in] binaryProgram True if binary program - * - * @return pointer to tessellation control shader - */ - static Option - createTessControlShader(NVRenderContextImpl &context, - NVConstDataRef tessControlShaderSource, - bool binaryProgram = false); - - /** - * @brief create tesselation evaluation shader - * - * @param[in] context Pointer to render context - * @param[in] tessEvaluationShaderSource Tessellation evaluation shader source code - * @param[in] binaryProgram True if binary program - * - * @return pointer to tessellation evaluation shader - */ - static Option - createTessEvaluationShader(NVRenderContextImpl &context, - NVConstDataRef tessEvaluationShaderSource, - bool binaryProgram = false); - - /** - * @brief create geometry shader - * - * @param[in] context Pointer to render context - * @param[in] geometryShaderSource Geometry shader source code - * @param[in] binaryProgram True if binary program - * - * @return pointer to geometry shader - */ - static Option - createGeometryShader(NVRenderContextImpl &context, - NVConstDataRef geometryShaderSource, bool binaryProgram = false); - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] programName Pointer to string of program name - * @param[in] separableProgram True if this is a separable program - * - * @return No return. - */ - NVRenderShaderProgram(NVRenderContextImpl &context, NVFoundationBase &fnd, - const char *programName, bool separableProgram); - - /// destructor - ~NVRenderShaderProgram(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief attach a shader to the program - * - * @param[in] pShader Pointer to shader object - * - * @return No return. - */ - template - void Attach(TShaderObject *pShader); - - /** - * @brief detach a shader from the program - * - * @param[in] pShader Pointer to shader object - * - * @return No return. - */ - template - void Detach(TShaderObject *pShader); - - /** - * @brief link a program - * - * - * @return true if succesfuly linked. - */ - bool Link(); - - /** - * @brief set a shader type - * - * @param[in] type shader type ( graphics or compute ) - * - * @return No return. - */ - void SetProgramType(ProgramType::Enum type) { m_ProgramType = type; } - ProgramType::Enum GetProgramType() const { return m_ProgramType; } - - /** - * @brief Get Error Message - * - * @param[out] messageLength Pointer to error string - * @param[out] messageLength Size of error meesage - * - * @return no return. - */ - void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage); - - /** - * @brief Get Error Message - * - * - * @return error message. - */ - const char *GetErrorMessage(); - - /** - * @brief Query constant class - * - * @param[in] constantName Pointer to constant name - * - * @return return a pointer to a constant class. - */ - NVRenderShaderConstantBase *GetShaderConstant(const char *constantName); - - /** - * @brief Query a shader buffer (constant, ... ) - * - * @param[in] bufferName Pointer to constant name - * - * @return return a pointer to a constant class. - */ - NVRenderShaderBufferBase *GetShaderBuffer(const char *bufferName); - - // concrete set functions - void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSI32 inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_2 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_3 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_4 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSRenderBool inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_2 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_3 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_4 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSF32 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec2 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec3 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec4 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_2 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_3 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_4 &inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat33 &inValue, - const QT3DSI32 inCount, bool inTranspose = false); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat44 &inValue, - const QT3DSI32 inCount, bool inTranspose = false); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, - const NVConstDataRef inValue, const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D *inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D **inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderTexture2DArray *inValue, const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube *inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube **inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderImage2D *inValue, - const QT3DSI32 inCount); - void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderDataBuffer *inValue, - const QT3DSI32 inCount); - - /** - * @brief Template to set constant value via name - * - * @param[in] inConstantName Pointer to constant name - * @param[in] inValue Pointer to data - * @param[in] inCount Number of elements (array count) - * - * @return return a pointer to a constant class. - */ - template - void SetPropertyValue(const char *inConstantName, const TDataType &inValue, - const QT3DSI32 inCount = 1) - { - NVRenderShaderConstantBase *theConstant = GetShaderConstant(inConstantName); - - if (theConstant) { - if (theConstant->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - SetConstantValue(theConstant, inValue, inCount); - } else { - // Types don't match or property not found - QT3DS_ASSERT(false); - } - } - } - - /** - * @brief Template to set constant value shader constant object - * - * @param[in] inConstant Pointer shader constant object - * @param[in] inValue Pointer to data - * @param[in] inCount Number of elements (array count) - * - * @return return a pointer to a constant class. - */ - template - void SetPropertyValue(NVRenderShaderConstantBase *inConstant, const TDataType &inValue, - const QT3DSI32 inCount = 1) - { - if (inConstant) { - if (inConstant->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - SetConstantValue(inConstant, inValue, inCount); - } else { - // Types don't match or property not found - QT3DS_ASSERT(false); - } - } - } - - virtual void BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendShaderProgramObject GetShaderProgramHandle() const - { - return m_ProgramHandle; - } - - /** - * @brief get the context object - * - * @return context which this shader belongs to. - */ - NVRenderContextImpl &GetRenderContext(); - - /** - * @brief Create a shader program - * - * @param[in] context Pointer to context - * @param[in] programName Name of the program - * @param[in] vertShaderSource Vertex shader source code - * @param[in] fragShaderSource Fragment shader source code - * @param[in] tessControlShaderSource tessellation control shader source code - * @param[in] tessEvaluationShaderSource tessellation evaluation shader source code - * @param[in] separateProgram True if this will we a separate - * program - * @param[in] type Binary program type - * @param[in] binaryProgram True if program is binary - * - * @return a render result - */ - static NVRenderVertFragCompilationResult Create( - NVRenderContextImpl &context, const char *programName, - NVConstDataRef vertShaderSource, NVConstDataRef fragShaderSource, - NVConstDataRef tessControlShaderSource = NVConstDataRef(), - NVConstDataRef tessEvaluationShaderSource = NVConstDataRef(), - NVConstDataRef geometryShaderSource = NVConstDataRef(), - bool separateProgram = false, - NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, - bool binaryProgram = false); - - /** - * @brief Create a compute shader program - * - * @param[in] context Pointer to context - * @param[in] programName Name of the program - * @param[in] computeShaderSource Compute shader source code - * - * @return a render result - */ - static NVRenderVertFragCompilationResult - CreateCompute(NVRenderContextImpl &context, const char *programName, - NVConstDataRef computeShaderSource); - }; - - // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe - // way. - template - struct NVRenderCachedShaderProperty - { - NVRenderShaderProgram *m_Shader; ///< pointer to shader program - NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object - - NVRenderCachedShaderProperty(const QString &inConstantName, NVRenderShaderProgram &inShader) - : NVRenderCachedShaderProperty(qPrintable(inConstantName), inShader) - { - } - - NVRenderCachedShaderProperty(const char *inConstantName, NVRenderShaderProgram &inShader) - : m_Shader(&inShader) - , m_Constant(NULL) - { - NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); - if (theConstant) { - if (theConstant->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - m_Constant = theConstant; - } else { - // Property types do not match, this probably indicates that the shader changed - // while the - // code creating this object did not change. - QT3DS_ASSERT(false); - } - } - } - - NVRenderCachedShaderProperty() - : m_Shader(NULL) - , m_Constant(NULL) - { - } - - void Set(const TDataType &inValue) - { - if (m_Constant) - m_Shader->SetPropertyValue(m_Constant, inValue); - } - - bool IsValid() const { return m_Constant != 0; } - }; - - template - struct NVRenderCachedShaderPropertyArray - { - NVRenderShaderProgram *m_Shader; ///< pointer to shader program - NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object - TDataType m_array[size]; - - NVRenderCachedShaderPropertyArray(const QString &inConstantName, - NVRenderShaderProgram &inShader) - : NVRenderCachedShaderPropertyArray(qPrintable(inConstantName), inShader) - { - - } - - NVRenderCachedShaderPropertyArray(const char *inConstantName, - NVRenderShaderProgram &inShader) - : m_Shader(&inShader) - , m_Constant(nullptr) - { - memset(m_array, 0, sizeof(m_array)); - NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); - if (theConstant) { - if (theConstant->m_ElementCount > 1 && theConstant->m_ElementCount <= size && - theConstant->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - m_Constant = theConstant; - } else { - // Property types do not match, this probably indicates that the shader changed - // while the code creating this object did not change. - QT3DS_ASSERT(false); - } - } - } - - NVRenderCachedShaderPropertyArray() - : m_Shader(nullptr) - , m_Constant(nullptr) - { - memset(m_array, 0, sizeof(m_array)); - } - - void Set(int count) - { - if (m_Constant) - m_Shader->SetPropertyValue(m_Constant, (TDataType*)m_array, qMin(size, count)); - } - - bool IsValid() const { return m_Constant != 0; } - }; - - // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe - // way. - template - struct NVRenderCachedShaderBuffer - { - NVRenderShaderProgram *m_Shader; ///< pointer to shader program - TDataType m_ShaderBuffer; ///< poiner to shader buffer object - - NVRenderCachedShaderBuffer(const char *inShaderBufferName, NVRenderShaderProgram &inShader) - : m_Shader(&inShader) - , m_ShaderBuffer(NULL) - { - TDataType theShaderBuffer = - static_cast(inShader.GetShaderBuffer(inShaderBufferName)); - if (theShaderBuffer) { - m_ShaderBuffer = theShaderBuffer; - } - } - NVRenderCachedShaderBuffer() - : m_Shader(NULL) - , m_ShaderBuffer(NULL) - { - } - - void Set() - { - if (m_ShaderBuffer) { - m_ShaderBuffer->Validate(m_Shader); - m_ShaderBuffer->Update(); - m_ShaderBuffer->BindToProgram(m_Shader); - } - } - - bool IsValid() const { return m_ShaderBuffer != 0; } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderStorageBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderStorageBuffer.h deleted file mode 100644 index fefe6b08..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderStorageBuffer.h +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H -#include "foundation/Qt3DSOption.h" -#include "foundation/Utils.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderDataBuffer.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - // forward declaration - class NVRenderContextImpl; - class NVRenderVertexBuffer; - - ///< Constant (uniform) buffer representation - class NVRenderStorageBuffer : public NVRenderDataBuffer - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] bufferName Name of the buffer. Must match the name used in programs - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * @param[in] pBuffer Pointer to the buffer - * - * @return No return. - */ - NVRenderStorageBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, - size_t size, NVRenderBufferUsageType::Enum usageType, - NVDataRef data, NVRenderDataBuffer *pBuffer = NULL); - - ///< destructor - virtual ~NVRenderStorageBuffer(); - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - void Bind() override; - - /** - * @brief bind the buffer to a shader program - * - * @param[in] index Index of the constant buffer within the program - * - * @return no return. - */ - virtual void BindToShaderProgram(QT3DSU32 index); - - /** - * @brief update the buffer to hardware - * - * @return no return. - */ - virtual void Update(); - - /** - * @brief update a piece of memory directly within the storage buffer - * - * Note: When you use this function you should know what you are doing. - * The memory layout within C++ must exactly match the memory layout in the - *shader. - * We use std140 (430) layout which guarantees a specific layout behavior across - *all HW vendors. - * How the memory layout is computed can be found in the GL spec. - * - * @param[in] offset offset into storage buffer - * @param[in] data pointer to data - * - * @return no return - */ - void UpdateData(QT3DSI32 offset, NVDataRef data); - - /** - * @brief get the buffer name - * - * @return the buffer name - */ - CRegisteredString GetBufferName() const { return m_Name; } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - /** - * @brief create a NVRenderStorageBuffer object - * - * @param[in] context Pointer to context - * @param[in] size Size of the buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - * application. - * - * @return the buffer object or NULL - */ - static NVRenderStorageBuffer *Create(NVRenderContextImpl &context, const char *bufferName, - NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData, - NVRenderDataBuffer *pBuffer); - - private: - CRegisteredString m_Name; ///< buffer name - NVRenderDataBuffer *m_WrappedBuffer; ///< pointer to wrapped buffer - bool m_Dirty; ///< true if buffer is dirty - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSync.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSync.h deleted file mode 100644 index 9dfeb28a..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderSync.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SYNC_H -#define QT3DS_RENDER_SYNC_H -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - class NVRenderBackend; - - ///< Base class - class NVRenderSync : public NVRefCounted - { - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBackend::NVRenderBackendSyncObject m_SyncHandle; ///< opaque backend handle - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd); - - virtual ~NVRenderSync(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - /** - * @brief Get sync type - * - * @return Return query type - */ - virtual NVRenderSyncType::Enum GetSyncType() const - { - return NVRenderSyncType::GpuCommandsComplete; - } - - /** - * @brief Get a pointer to the foundation - * - * @return pointer to foundation - */ - NVFoundationBase &GetFoundation() { return m_Foundation; } - - /** - * @brief Create a sync object and place it in command stream. - * Note every syncobject can only be used once. - * This function creates a new sync object on ever call - * and deletes the previous one - * - * @return no return. - */ - virtual void Sync(); - - /** - * @brief Wait for a sync to be signaled - * Note this blocks until the sync is signaled - * - * @return no return. - */ - virtual void Wait(); - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendSyncObject GetSyncHandle() const - { - return m_SyncHandle; - } - - /* - * @brief static creation function - * - * @return a sync object on success - */ - static NVRenderSync *Create(NVRenderContextImpl &context); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTessellationShader.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTessellationShader.h deleted file mode 100644 index b69e56b1..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTessellationShader.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TESSELLATION_SHADER_H -#define QT3DS_RENDER_TESSELLATION_SHADER_H - -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderShader.h" - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - - ///< This class represents a tessellation control shader - class NVRenderTessControlShader : public NVRenderShader - { - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] source Pointer to shader source code - * @param[in] binaryProgram true if this is a binary program - * - * @return No return. - */ - NVRenderTessControlShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram); - - /// @brief destructor - ~NVRenderTessControlShader(); - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - bool IsValid() override { return (m_ShaderHandle != NULL); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendTessControlShaderObject GetShaderHandle() - { - return m_ShaderHandle; - } - - private: - NVRenderBackend::NVRenderBackendTessControlShaderObject - m_ShaderHandle; ///< opaque backend handle - }; - - ///< This class represents a tessellation evaluation shader - class NVRenderTessEvaluationShader : public NVRenderShader - { - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] source Pointer to shader source code - * @param[in] binaryProgram true if this is a binary program - * - * @return No return. - */ - NVRenderTessEvaluationShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram); - - /// @brief destructor - ~NVRenderTessEvaluationShader(); - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - bool IsValid() override { return (m_ShaderHandle != NULL); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendTessEvaluationShaderObject GetShaderHandle() - { - return m_ShaderHandle; - } - - private: - NVRenderBackend::NVRenderBackendTessEvaluationShaderObject - m_ShaderHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2D.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2D.h deleted file mode 100644 index 29c7c1b4..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2D.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H -#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "render/Qt3DSRenderTextureBase.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - class NVRenderTextureSampler; - - class NVRenderTexture2D : public NVRenderTextureBase, public NVRenderImplemented - { - - private: - QT3DSU32 m_Width; ///< texture width - QT3DSU32 m_Height; ///< texture height - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] texTarget Texture target - * - * @return No return. - */ - NVRenderTexture2D( - NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D); - - virtual ~NVRenderTexture2D(); - - // Get the texture details for mipmap level 0 if it was set. - STextureDetails GetTextureDetails() const override; - - /** - * @brief Create GL texture object and upload data - * - * @param[in] newBuffer Texture data for level 0 - * @param[in] inMipLevel Texture level count - * @param[in] width Texture width - * @param[in] height Texture height - * @param[in] format Texture data format - * @param[in] formaInternal Texture internal format - * - * @return No return. - */ - virtual void SetTextureData( - NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum format, - NVRenderTextureFormats::Enum formaInternal = NVRenderTextureFormats::Unknown); - - /** - * @brief Create memory storage for a texture object - * This create a texture storage which is immutable in size and format - * Use this for textures used within compute shaders - * - * @param[in] inLevels Texture level count - * @param[in] width Texture width - * @param[in] height Texture height - * @param[in] formaInternal Texture internal format - * @param[in] format Texture data format of dataBuffer - * @param[in] dataBuffer Texture data for level 0 - * - * @return No return. - */ - virtual void - SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum formaInternal, - NVRenderTextureFormats::Enum format = NVRenderTextureFormats::Unknown, - NVDataRef dataBuffer = NVDataRef()); - - virtual void SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum format); - - bool IsMultisampleTexture() const override - { - return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS); - } - QT3DSU32 GetSampleCount() const override { return m_SampleCount; } - bool IsImmutableTexture() const override { return m_Immutable; } - - // Update a sub-rect of the image. newBuffer is expected to be a continguous subrect of the - // image. - virtual void SetTextureSubData(NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 inXOffset, - QT3DSU32 inYOffset, QT3DSU32 inSubImageWidth, - QT3DSU32 inSubImageHeight, NVRenderTextureFormats::Enum format); - // Generate a set of mipmaps from mipLevel( 0 ). Uses the graphis layer to do this if - // possible - // glGenerateMipmap - virtual void GenerateMipmaps(NVRenderHint::Enum genType = NVRenderHint::Nicest); - - /** - * @brief Bind a texture for shader access - * - * - * @return No return. - */ - void Bind() override; - - QT3DSU32 GetNumMipmaps() override { return m_MaxMipLevel; } - - /** - * @brief Query if texture needs coordinate swizzle - * - * @return texture swizzle mode - */ - NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() override - { - // if our backend supports hardware texture swizzle then there is no need for a shader - // swizzle - return (m_Backend->GetRenderBackendCap( - NVRenderBackend::NVRenderBackendCaps::TexSwizzle)) - ? NVRenderTextureSwizzleMode::NoSwizzle - : m_Backend->GetTextureSwizzleMode(m_Format); - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_TextureHandle); - } - - static NVRenderTexture2D *Create(NVRenderContextImpl &context); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2DArray.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2DArray.h deleted file mode 100644 index 30ed6dbb..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTexture2DArray.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H -#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "render/Qt3DSRenderTextureBase.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - class NVRenderTextureSampler; - - class QT3DS_AUTOTEST_EXPORT NVRenderTexture2DArray : public NVRenderTextureBase - { - private: - QT3DSU32 m_Width; ///< texture width - QT3DSU32 m_Height; ///< texture height - QT3DSU32 m_Slices; ///< texture slices - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] texTarget Texture target - * - * @return No return. - */ - NVRenderTexture2DArray( - NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D_Array); - - virtual ~NVRenderTexture2DArray(); - - /** - * @brief constructor - * - * @param[in] newBuffer Pointer to pixel buffer - * @param[in] inMipLevel Pointer to foundation - * @param[in] width Texture target - * @param[in] height Texture target - * @param[in] slices Texture target - * @param[in] format Texture target - * - * @return No return. - */ - void SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height, - QT3DSU32 slices, NVRenderTextureFormats::Enum format); - - // Get the texture details for mipmap level 0 if it was set. - STextureDetails GetTextureDetails() const override; - - /** - * @brief Bind a texture for shader access - * - * - * @return No return. - */ - void Bind() override; - - /** - * @brief create a texture array object - * - * - * @ return a texture array object - */ - static NVRenderTexture2DArray *Create(NVRenderContextImpl &context); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureBase.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureBase.h deleted file mode 100644 index 872a634e..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureBase.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - class NVRenderTextureSampler; - - struct STextureDetails - { - QT3DSU32 m_Width; - QT3DSU32 m_Height; - QT3DSU32 m_Depth; - QT3DSU32 m_SampleCount; - NVRenderTextureFormats::Enum m_Format; - - STextureDetails(QT3DSU32 w, QT3DSU32 h, QT3DSU32 d, QT3DSU32 samples, NVRenderTextureFormats::Enum f) - : m_Width(w) - , m_Height(h) - , m_Depth(d) - , m_SampleCount(samples) - , m_Format(f) - { - } - STextureDetails() - : m_Width(0) - , m_Height(0) - , m_Depth(0) - , m_SampleCount(1) - , m_Format(NVRenderTextureFormats::Unknown) - { - } - }; - - class NVRenderTextureBase : public NVRefCounted - { - - protected: - NVRenderContextImpl &m_Context; ///< pointer to context - NVFoundationBase &m_Foundation; ///< pointer to foundation - volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation - NVRenderBackend *m_Backend; ///< pointer to backend - NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; ///< opaque backend handle - QT3DSU32 m_TextureUnit; ///< texture unit this texture should use - bool m_SamplerParamsDirty; ///< true if sampler state is dirty - bool m_TexStateDirty; ///< true if texture object state is dirty - QT3DSU32 m_SampleCount; ///< texture height - NVRenderTextureFormats::Enum m_Format; ///< texture format - NVRenderTextureTargetType::Enum m_TexTarget; ///< texture target - NVRenderTextureSampler *m_Sampler; ///< current texture sampler state - QT3DSI32 m_BaseLevel; ///< minimum lod specified - QT3DSI32 m_MaxLevel; ///< maximum lod specified - QT3DSU32 m_MaxMipLevel; ///< highest mip level - bool m_Immutable; ///< true if this is a immutable texture ( size and format ) - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] texTarget Texture target - * - * @return No return. - */ - NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget); - - virtual ~NVRenderTextureBase(); - - // define refcount functions - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) - - virtual void SetMinFilter(NVRenderTextureMinifyingOp::Enum value); - virtual void SetMagFilter(NVRenderTextureMagnifyingOp::Enum value); - - virtual void SetBaseLevel(QT3DSI32 value); - virtual void SetMaxLevel(QT3DSI32 value); - - virtual void SetTextureWrapS(NVRenderTextureCoordOp::Enum value); - virtual void SetTextureWrapT(NVRenderTextureCoordOp::Enum value); - - virtual void SetTextureCompareMode(NVRenderTextureCompareMode::Enum value); - virtual void SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value); - - virtual void SetTextureUnit(QT3DSU32 unit) { m_TextureUnit = unit; } - virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; } - - // Get the texture details for mipmap level 0 if it was set. - virtual STextureDetails GetTextureDetails() const = 0; - - virtual bool IsMultisampleTexture() const - { - return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS); - } - virtual QT3DSU32 GetSampleCount() const { return m_SampleCount; } - virtual bool IsImmutableTexture() const { return m_Immutable; } - - /** - * @brief Bind a texture for shader access - * - * - * @return No return. - */ - virtual void Bind() = 0; - - virtual QT3DSU32 GetNumMipmaps() { return m_MaxMipLevel; } - - /** - * @brief Query if texture needs coordinate swizzle - * - * @return texture swizzle mode - */ - virtual NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() - { - // if our backend supports hardware texture swizzle then there is no need for a shader - // swizzle - return (m_Backend->GetRenderBackendCap( - NVRenderBackend::NVRenderBackendCaps::TexSwizzle)) - ? NVRenderTextureSwizzleMode::NoSwizzle - : m_Backend->GetTextureSwizzleMode(m_Format); - } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle() - { - return m_TextureHandle; - } - - protected: - void applyTexParams(); - void applyTexSwizzle(); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureCube.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureCube.h deleted file mode 100644 index 7310d44d..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTextureCube.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H -#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "render/Qt3DSRenderTextureBase.h" - -namespace qt3ds { -namespace render { - - class NVRenderContextImpl; - class NVRenderTextureSampler; - - class NVRenderTextureCube : public NVRenderTextureBase - { - private: - QT3DSU32 m_Width; ///< texture width (per face) - QT3DSU32 m_Height; ///< texture height (per face) - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * @param[in] texTarget Texture target - * - * @return No return. - */ - NVRenderTextureCube( - NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::TextureCube); - - virtual ~NVRenderTextureCube(); - - /** - * @brief constructor - * - * @param[in] newBuffer Pointer to pixel buffer - * @param[in] inMipLevel Pointer to foundation - * @param[in] width Texture target - * @param[in] height Texture target - * @param[in] slices Texture target - * @param[in] format Texture target - * - * @return No return. - */ - void SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, - NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum format); - - // Get the texture details for mipmap level 0 if it was set. - STextureDetails GetTextureDetails() const override; - - /** - * @brief Bind a texture for shader access - * - * - * @return No return. - */ - void Bind() override; - - /** - * @brief create a texture array object - * - * - * @ return a texture array object - */ - static NVRenderTextureCube *Create(NVRenderContextImpl &context); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTimerQuery.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTimerQuery.h deleted file mode 100644 index f909f374..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderTimerQuery.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TIMER_QUERY_H -#define QT3DS_RENDER_TIMER_QUERY_H - -#include "render/Qt3DSRenderQueryBase.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - - class NVRenderTimerQuery : public NVRenderQueryBase - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] fnd Pointer to foundation - * - * @return No return. - */ - NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd); - - ///< destructor - ~NVRenderTimerQuery(); - - /** - * @brief Get query type - * - * @return Return query type - */ - NVRenderQueryType::Enum GetQueryType() const override - { - return NVRenderQueryType::Timer; - } - - /** - * @brief Get a pointer to the foundation - * - * @return pointer to foundation - */ - NVFoundationBase &GetFoundation() { return m_Foundation; } - - /** - * @brief begin a query - * - * @return no return. - */ - void Begin() override; - - /** - * @brief end a query - * - * @return no return. - */ - void End() override; - - /** - * @brief Get the result of a query - * - * @param[out] params Contains result of query regarding query type - * - * @return no return. - */ - void GetResult(QT3DSU32 *params) override; - - /** - * @brief Get the result of a query - * - * @param[out] params Contains result of query regarding query type - * - * @return no return. - */ - virtual void GetResult(QT3DSU64 *params); - - /** - * @brief Places an absolute timer query into the render queue - * The result can be queried with GetResult - * - * @return no return. - */ - virtual void SetTimerQuery(); - - /* - * @brief static creation function - * - * * @return a timer query object on success - */ - static NVRenderTimerQuery *Create(NVRenderContextImpl &context); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexBuffer.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexBuffer.h deleted file mode 100644 index 914afe27..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexBuffer.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H -#define QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H -#include "foundation/Qt3DSOption.h" -#include "foundation/Utils.h" -#include "render/Qt3DSRenderDrawable.h" -#include "render/Qt3DSRenderDataBuffer.h" - -namespace qt3ds { -namespace render { - - // forward declaration - class NVRenderContextImpl; - - ///< Vertex buffer representation - class NVRenderVertexBuffer : public NVRenderDataBuffer - { - public: - /** - * @brief constructor - * - * @param[in] context Pointer to context - * @param[in] entries Vertex buffer attribute layout entries - * @param[in] size Size of the buffer - * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - *application. - * - * @return No return. - */ - NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, QT3DSU32 stride, - NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usageType, NVDataRef data); - - ///< destructor - virtual ~NVRenderVertexBuffer(); - - /** - * @brief return vertex data stride - * - * @return data stride. - */ - virtual QT3DSU32 GetStride() const { return m_Stride; } - - /** - * @brief get vertex count - * - * @return vertex count - */ - virtual QT3DSU32 GetNumVertexes() const - { - QT3DS_ASSERT((m_BufferCapacity % m_Stride) == 0); - return m_BufferCapacity / m_Stride; - } - - /** - * @brief bind the buffer bypasses the context state - * - * @return no return. - */ - void Bind() override; - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override - { - return m_BufferHandle; - } - - // this will be obsolete - const void *GetImplementationHandle() const override - { - return reinterpret_cast(m_BufferHandle); - } - - // No stride means that stride is calculated from the size of last entry found via entry - // offset - // Leaves this buffer temporarily bound. - static NVRenderVertexBuffer *Create(NVRenderContextImpl &context, - NVRenderBufferUsageType::Enum usageType, size_t size, - QT3DSU32 stride, NVConstDataRef bufferData); - - private: - QT3DSU32 m_Stride; ///< veretex data stride - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexShader.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexShader.h deleted file mode 100644 index 0a96045b..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderVertexShader.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_VERTEX_SHADER_H -#define QT3DS_RENDER_VERTEX_SHADER_H - -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderShader.h" - -namespace qt3ds { -namespace render { - using namespace foundation; - - class NVRenderContextImpl; - - ///< This class represents a vertex shader - class NVRenderVertexShader : public NVRenderShader - { - - public: - /** - * @brief constructor - * - * @param[in] context Pointer to render context - * @param[in] fnd Pointer to foundation - * @param[in] source Pointer to shader source code - * @param[in] binaryProgram true if this is a binary program - * - * @return No return. - */ - NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram); - - /// @brief destructor - ~NVRenderVertexShader(); - - /** - * @brief Query if shader compiled succesfuly - * - * @return True if shader is valid. - */ - bool IsValid() override { return (m_ShaderHandle != NULL); } - - /** - * @brief get the backend object handle - * - * @return the backend object handle. - */ - virtual NVRenderBackend::NVRenderBackendVertexShaderObject GetShaderHandle() - { - return m_ShaderHandle; - } - - private: - NVRenderBackend::NVRenderBackendVertexShaderObject - m_ShaderHandle; ///< opaque backend handle - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h deleted file mode 100644 index 12de5d88..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h +++ /dev/null @@ -1,2245 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_H -#define QT3DS_RENDER_BACKEND_H - -/// @file Qt3DSRenderBackend.h -/// NVRender backend definition. - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSNoCopy.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSBounds3.h" -#include - -#include - -namespace qt3ds { -namespace render { - -#define HandleToID_cast(staticType, dynamicType, handle) \ - static_cast(reinterpret_cast(handle)) - - class NVRenderBackend : public NVRefCounted, public NoCopy - { - - public: - /// opaque buffer object handle - typedef struct _NVRenderBackendBufferObject *NVRenderBackendBufferObject; - /// opaque attribute layout object handle - typedef struct _NVRenderBackendAttribLayoutObject *NVRenderBackendAttribLayoutObject; - /// opaque input assembler object handle - typedef struct _NVRenderBackendInputAssemblerObject *NVRenderBackendInputAssemblerObject; - /// opaque texture object handle - typedef struct _NVRenderBackendTextureObject *NVRenderBackendTextureObject; - /// opaque sampler object handle - typedef struct _NVRenderBackendSamplerObject *NVRenderBackendSamplerObject; - /// opaque renderbuffer object handle - typedef struct _NVRenderBackendRenderbufferObject *NVRenderBackendRenderbufferObject; - /// opaque framebuffer object handle - typedef struct _NVRenderBackendRenderTargetObject *NVRenderBackendRenderTargetObject; - /// opaque vertex shader object handle - typedef struct _NVRenderBackendVertexShaderObject *NVRenderBackendVertexShaderObject; - /// opaque fragment shader object handle - typedef struct _NVRenderBackendFragmentShaderObject *NVRenderBackendFragmentShaderObject; - /// opaque tesselation control shader object handle - typedef struct _NVRenderBackendTessControlShaderObject - *NVRenderBackendTessControlShaderObject; - /// opaque tesselation evaluation shader object handle - typedef struct _NVRenderBackendTessEvaluationShaderObject - *NVRenderBackendTessEvaluationShaderObject; - /// opaque geometry shader object handle - typedef struct _NVRenderBackendGeometryShaderObject *NVRenderBackendGeometryShaderObject; - /// opaque compute shader object handle - typedef struct _NVRenderBackendComputeShaderObject *NVRenderBackendComputeShaderObject; - /// opaque shader program object handle - typedef struct _NVRenderBackendShaderProgramObject *NVRenderBackendShaderProgramObject; - /// opaque depth stencil state object handle - typedef struct _NVRenderBackendDepthStencilStateObject - *NVRenderBackendDepthStencilStateObject; - /// opaque rasterizer state object handle - typedef struct _NVRenderBackendRasterizerStateObject *NVRenderBackendRasterizerStateObject; - /// opaque query object handle - typedef struct _NVRenderBackendQueryObject *NVRenderBackendQueryObject; - /// opaque sync object handle - typedef struct _NVRenderBackendSyncObject *NVRenderBackendSyncObject; - /// opaque sync object handle - typedef struct _NVRenderBackendProgramPipeline *NVRenderBackendProgramPipeline; - /// opaque sync object handle - typedef struct _NVRenderBackendPathObject *NVRenderBackendPathObject; - - // backend capability caps - typedef struct - { - enum Enum { - ConstantBuffer, ///< Constant buffer support query - DepthStencilTexture, ///< depth stencil texture format suport query - DxtImages, ///< DXT image support query - FpRenderTarget, ///< render to floating point target support query - MsTexture, ///< Multisample texture support query - TexSwizzle, ///< Texture swizzle support query - FastBlits, ///< Hardware supports fast blits - Tessellation, ///< Hardware supports tessellation - Compute, ///< Hardware supports compute shader - Geometry, ///< Hardware supports geometry shader - SampleQuery, ///< Hardware supports query calls of type samples - TimerQuery, ///< Hardware supports query calls of type timer - CommandSync, ///< Hardware supports command sync object - TextureArray, ///< Hardware supports texture arrays - StorageBuffer, ///< Hardware supports shader storage buffers - AtomicCounterBuffer, ///< Hardware supports atomic counter buffers - ShaderImageLoadStore, ///< Hardware supports shader image load store operations - ProgramPipeline, ///< Driver supports separate programs - PathRendering, ///< Driver support path rendering - AdvancedBlend, ///< Driver supports advanced blend modes - BlendCoherency, ///< Hardware supports blend coherency - gpuShader5, // for high precision sampling - AdvancedBlendKHR, ///< Driver supports advanced blend modes - VertexArrayObject, - StandardDerivatives, - TextureLod - }; - } NVRenderBackendCaps; - - // backend queries - typedef struct - { - enum Enum { - MaxTextureSize, ///< Return max supported texture size - MaxTextureArrayLayers, ///< Return max supported layer count for texture arrays - MaxConstantBufferSlots, ///< Return max supported constant buffe slots for a single - ///shader stage - MaxConstantBufferBlockSize ///< Return max supported size for a single constant - ///buffer block - }; - } NVRenderBackendQuery; - - /// backend interface - - /** - * @brief get the backend type - * - * @return true backend type - */ - virtual NVRenderContextType GetRenderContextType() const = 0; - - /** - * @brief get the version of the shading language - * @return version string, must be copied by clients to be retained. - */ - virtual const char *GetShadingLanguageVersion() = 0; - - /** - * @brief get maximum supported texture image units that - * can be used to access texture maps from the vertex shader and the fragment processor - *combined. - * - * @return max texture size - */ - virtual QT3DSU32 GetMaxCombinedTextureUnits() = 0; - - /** - * @brief query Backend capabilities - * - * @param[in] inCap CAPS flag to query - * @ConstantBuffer, @DepthStencilTexture, ... - * - * @return true if supported - */ - virtual bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const = 0; - - /** - * @brief query Backend values - * - * @param[in] inQuery Query flag to get value for - * @MaxTextureSize, @MaxTextureArrayLayers, - *... - * @param[in/out] params the query result is stored here - * - * @return no return - */ - virtual void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, - QT3DSI32 *params) const = 0; - - /** - * @brief query for bit depth of the depth buffer - * - * @return depth buffer bitplanes - */ - virtual QT3DSU32 GetDepthBits() const = 0; - - /** - * @brief query for bit depth of the stencil buffer - * - * @return stencil buffer bitplanes - */ - virtual QT3DSU32 GetStencilBits() const = 0; - - /* - * @brief set a backend rende state - * - * @param[in] bEnable enable/disable state - * @param[in] value type of state - * - * @return no return - */ - virtual void SetRenderState(bool bEnable, const NVRenderState::Enum value) = 0; - - /** - * @brief get a backend rende state - * - * @param[in] value type of state - * - * @return true if state enabled otherwise false - */ - virtual bool GetRenderState(const NVRenderState::Enum value) = 0; - - /** - * @brief get current depth function - * - * @return active depth function - */ - virtual NVRenderBoolOp::Enum GetDepthFunc() = 0; - - /** - * @brief create a depth stencil state object - * - * @param[in] enableDepth enable depth test - * @param[in] depthMask enable depth writes - * @param[in] depthFunc depth compare function - * @param[in] enableStencil enable stencil test - * @param[in] stencilFuncFront stencil setup front faces - * @param[in] stencilFuncBack stencil setup back faces - * @param[in] depthStencilOpFront depth/stencil operations front faces - * @param[in] depthStencilOpBack depth/stencil operations back faces - * - * @return opaque handle to state object - */ - virtual NVRenderBackendDepthStencilStateObject - CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, - bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) = 0; - - /** - * @brief release a depth stencil state object - * - * @param[in] depthStencilState pointer to state object - * - * @return none - */ - virtual void - ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; - - /** - * @brief create a rasterizer state object - * - * @param[in] depthBias any othe value than 0 enables depth bias - * @param[in] depthScale any othe value than 0 enables depth scale - * @param[in] cullFace select face to cull front or back - * - * @return opaque handle to state object - */ - virtual NVRenderBackendRasterizerStateObject - CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) = 0; - - /** - * @brief release a rasterizer state object - * - * @param[in] rasterizerState pointer to state object - * - * @return none - */ - virtual void - ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; - - /** - * @brief set depth stencil state - * - * @param[in] depthStencilState pointer to state object - * - * @return none - */ - virtual void - SetDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; - - /** - * @brief set rasterizer state - * - * @param[in] rasterizerState pointer to state object - * - * @return none - */ - virtual void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; - - /** - * @brief set current depth function - * - * @param[in] func type of function - * - * @return no return - */ - virtual void SetDepthFunc(const NVRenderBoolOp::Enum func) = 0; - - /** - * @brief query if depth write is enabled - * - * @return true if enabled - */ - virtual bool GetDepthWrite() = 0; - - /** - * @brief enable / disable depth writes - * - * @param[in] bEnable true for enable - * - * @return no return - */ - virtual void SetDepthWrite(bool bEnable) = 0; - - /** - * @brief enable / disable color channel writes - * - * @param[in] bRed true for enable red channel - * @param[in] bGreen true for enable green channel - * @param[in] bBlue true for enable blue channel - * @param[in] bAlpha true for enable alpha channel - * - * @return no return - */ - virtual void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; - - /** - * @brief enable / disable multisample rendering - * - * @param[in] bEnable true for enable - * - * @return no return - */ - virtual void SetMultisample(bool bEnable) = 0; - - /** - * @brief query blend functions - * - * @param[out] pBlendFuncArg blending functions - * - * @return no return - */ - virtual void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) = 0; - - /** - * @brief set blend functions - * - * @param[in] pBlendFuncArg blending functions - * - * @return no return - */ - virtual void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) = 0; - - /** - * @brief set blend equation - * - * @param[in] pBlendEquArg blending equation - * - * @return no return - */ - virtual void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) = 0; - - /** - * @brief guarantee blend coherency - * - * - * @return no return - */ - virtual void SetBlendBarrier(void) = 0; - - /** - * @brief query scissor rectangle - * - * @param[out] pRect contains scissor rect - * - * @return no return - */ - virtual void GetScissorRect(NVRenderRect *pRect) = 0; - - /** - * @brief set scissor rectangle - * - * @param[out] pRect contains scissor rect - * - * @return no return - */ - virtual void SetScissorRect(const NVRenderRect &rect) = 0; - - /** - * @brief query viewport rectangle - * - * @param[out] pRect contains viewport rect - * - * @return no return - */ - virtual void GetViewportRect(NVRenderRect *pRect) = 0; - - /** - * @brief set viewport rectangle - * - * @param[out] pRect contains viewport rect - * - * @return no return - */ - virtual void SetViewportRect(const NVRenderRect &rect) = 0; - - /** - * @brief query viewport rectangle - * - * @param[in] clearColor clear color - * - * @return no return - */ - virtual void SetClearColor(const QT3DSVec4 *pClearColor) = 0; - - /** - * @brief query viewport rectangle - * - * @param[in] flags clear flags - * - * @return no return - */ - virtual void Clear(NVRenderClearFlags flags) = 0; - - /** - * @brief create a buffer object - * - * @param[in] size Size of the buffer - * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - *application. - * - * @return The created buffer object or NULL if the creation failed. - */ - virtual NVRenderBackendBufferObject CreateBuffer(size_t size, - NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usage, - const void *hostPtr = NULL) = 0; - - /** - * @brief bind a buffer object - * - * @param[in] bo Pointer to buffer object - * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * - * @return no return. - */ - virtual void BindBuffer(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags) = 0; - - /** - * @brief Release a single buffer object - * - * @param[in] bo Pointer to buffer object - * - * @return no return. - */ - virtual void ReleaseBuffer(NVRenderBackendBufferObject bo) = 0; - - /** - * @brief update a whole buffer object - * - * @param[in] bo Pointer to buffer object - * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * @param[in] size Size of the data buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - *application. - * - * @return no return. - */ - virtual void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, - size_t size, NVRenderBufferUsageType::Enum usage, - const void *data) = 0; - - /** - * @brief update a range of a buffer object - * - * @param[in] bo Pointer to buffer object - * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * @param[in] size Size of the data buffer - * @param[in] usage Usage of the buffer (e.g. static, dynamic...) - * @param[in] data A pointer to the buffer data that is allocated by the - *application. - * - * @return no return. - */ - virtual void UpdateBufferRange(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags, size_t offset, - size_t size, const void *data) = 0; - - /** - * @brief Get a pointer to the buffer data ( GL(ES) >= 3 only ) - * - * @param[in] bo Pointer to buffer object - * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * @param[in] offset Byte offset into the data buffer - * @param[in] length Byte length of mapping size - * @param[in] access Access of the buffer (e.g. read, write, ...) - * - * @return pointer to mapped data or null. - */ - virtual void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, - size_t offset, size_t length, - NVRenderBufferAccessFlags accessFlags) = 0; - - /** - * @brief Unmap a previously mapped buffer ( GL(ES) >= 3 only ) - * This functions transfers the content to the hardware buffer - * - * @param[in] bo Pointer to buffer object - * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) - * For OpenGL this should be a single - *value - * - * @return true if successful - */ - virtual bool UnmapBuffer(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags) = 0; - - /** - * @brief Set a memory barrier - * - * @param[in] barriers Flags for barriers - * - * @return no return. - */ - virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; - - /** - * @brief create a query object - * - * @return The created query object or NULL if the creation failed. - */ - virtual NVRenderBackendQueryObject CreateQuery() = 0; - - /** - * @brief delete query objects - * - * @param[in] qo Handle to query object - * - * @return no return - */ - virtual void ReleaseQuery(NVRenderBackendQueryObject qo) = 0; - - /** - * @brief Start query recording - * - * @param[in] qo Handle to query object - * @param[in] type Type of query - * - * @return no return - */ - virtual void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; - - /** - * @brief End query recording - * - * @param[in] qo Handle to query object - * @param[in] type Type of query - * - * @return no return - */ - virtual void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; - - /** - * @brief Get a query result - * - * @param[in] qo Handle to query object - * @param[in] type Type of query - * @param[out] params Contains result of query regarding query type - * - * @return no return - */ - virtual void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) = 0; - - /** - * @brief Get a query result - * - * @param[in] qo Handle to query object - * @param[in] type Type of query - * @param[out] params Contains result of query regarding query type 64 bit returns - * - * @return no return - */ - virtual void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) = 0; - - /** - * @brief Record the GPU time using the query object - * - * @param[in] qo Handle to query object - * - * @return no return - */ - virtual void SetQueryTimer(NVRenderBackendQueryObject qo) = 0; - - /** - * @brief create a sync object and place it in the command queue - * - * @param[in] tpye Type to sync - * @param[in] syncFlags Currently unused - * - * @return The created sync object or NULL if the creation failed. - */ - virtual NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, - NVRenderSyncFlags syncFlags) = 0; - - /** - * @brief delete sync object - * - * @param[in] so Handle to sync object - * - * @return no return - */ - virtual void ReleaseSync(NVRenderBackendSyncObject so) = 0; - - /** - * @brief wait for sync object to be signaled - * - * @param[in] so Handle to sync object - * @param[in] syncFlags Currently unused - * @param[in] timeout Currently ignored - * - * @return no return - */ - virtual void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, - QT3DSU64 timeout) = 0; - - /** - * @brief create a render target object - * - * - * @return The created render target object or NULL if the creation failed. - */ - virtual NVRenderBackendRenderTargetObject CreateRenderTarget() = 0; - - /** - * @brief Release a single render target object - * - * @param[in] rto Pointer to render target object - * - * @return no return. - */ - virtual void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; - - /** - * @brief Attach a renderbuffer object to the framebuffer - * - * @param[in] rto Pointer to render target object - * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) - * @param[in] rbo Pointer to renderbuffer object - * - * @return no return. - */ - virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendRenderbufferObject rbo) = 0; - - /** - * @brief Attach a texture object to the render target - * - * @param[in] rto Pointer to render target object - * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) - * @param[in] to Pointer to texture object - * @param[in] target Attachment texture target - * - * @return no return. - */ - virtual void RenderTargetAttach( - NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) = 0; - - /** - * @brief Attach a texture object to the render target - * - * @param[in] rto Pointer to render target object - * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) - * @param[in] to Pointer to texture object - * @param[in] level Texture mip level - * @param[in] layer Texture layer or slice - * - * @return no return. - */ - virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, QT3DSI32 level, - QT3DSI32 layer) = 0; - - /** - * @brief Make a render target active - * - * @param[in] rto Pointer to render target object - * - * @return no return. - */ - virtual void SetRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; - - /** - * @brief Check if a render target is ready for render - * - * @param[in] rto Pointer to render target object - * - * @return true if usable. - */ - virtual bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) = 0; - - /** - * @brief Make a render target active for reading - * - * @param[in] rto Pointer to render target object - * - * @return no return. - */ - virtual void SetReadTarget(NVRenderBackendRenderTargetObject rto) = 0; - - /** - * @brief Set active buffers for drawing - * - * @param[in] rto Pointer to render target object - * @param[in] inDrawBufferSet Pointer to array of enabled render targets - * - * @return no return. - */ - virtual void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, - NVConstDataRef inDrawBufferSet) = 0; - - /** - * @brief Set active buffer for reading - * - * @param[in] rto Pointer to render target object - * @param[in] inReadFace Buffer to read from - * - * @return no return. - */ - virtual void SetReadBuffer(NVRenderBackendRenderTargetObject rto, - NVReadFaces::Enum inReadFace) = 0; - - /** - * @brief Copy framebuffer attachments. Source is set with SetReadTarget dest with - * SetRenderTarget - * - * @param[in] srcX0 Lower left X coord of source rectangle - * @param[in] srcY0 Lower left Y coord of source rectangle - * @param[in] srcX1 Upper right X coord of source rectangle - * @param[in] srcY1 Upper right Y coord of source rectangle - * @param[in] dstX0 Lower left X coord of dest rectangle - * @param[in] dstY0 Lower left Y coord of dest rectangle - * @param[in] dstX1 Upper right X coord of dest rectangle - * @param[in] dstY1 Upper right Y coord of dest rectangle - * @param[in] inDrawBufferSet pointer to array of enabled render targets - * @param[in] filter Copy filter method (NEAREST or LINEAR) - * - * @return no return. - */ - virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) = 0; - - /** - * @brief create a render buffer object - * - * @param[in] storageFormat Format of the buffer - * @param[in] width Buffer with - * @param[in] height Buffer height - * - * @return The created render buffer object or NULL if the creation failed. - */ - virtual NVRenderBackendRenderbufferObject - CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, - size_t height) = 0; - - /** - * @brief Release a single renderbuffer object - * - * @param[in] bo Pointer to renderbuffer object - * - * @return no return. - */ - virtual void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) = 0; - - /** - * @brief resize a render buffer object - * - * @param[in] storageFormat Format of the buffer - * @param[in] width Buffer with - * @param[in] height Buffer height - * - * @return True on success - */ - virtual bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, - NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) = 0; - - /** - * @brief create a texture object - * - * @return The created texture object or NULL if the creation failed.. - */ - virtual NVRenderBackendTextureObject CreateTexture() = 0; - - /** - * @brief set texture data for a 2D texture - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] level Texture mip level - * @param[in] internalFormat format of the texture - * @param[in] width texture width - * @param[in] height texture height - * @param[in] border border - * @param[in] format format of provided pixel data - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) = 0; - - /** - * @brief set texture data for the face of a Cube map - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target face - * @param[in] level Texture mip level - * @param[in] internalFormat format of the texture - * @param[in] width texture width - * @param[in] height texture height - * @param[in] border border - * @param[in] format format of provided pixel data - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetTextureDataCubeFace(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) = 0; - - /** - * @brief create a storage for a 2D texture including mip levels - * Note that this makes texture immutable in size and format - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] levels Texture mip level count - * @param[in] internalFormat format of the texture - * @param[in] width texture width - * @param[in] height texture height - * - * @return No return - */ - virtual void CreateTextureStorage2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 levels, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height) = 0; - - /** - * @brief set texture sub data for a 2D texture - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] level Texture mip level - * @param[in] xOffset Texture x offset - * @param[in] yOffset Texture y offset - * @param[in] width Texture width - * @param[in] height Texture height - * @param[in] border border - * @param[in] format format of texture - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetTextureSubData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) = 0; - - /** - * @brief set compressed texture data for a 2D texture - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] level Texture mip level - * @param[in] internalFormat format of the texture - * @param[in] width texture width - * @param[in] height texture height - * @param[in] border border - * @param[in] imageSize image size in bytes located at hostPtr - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetCompressedTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, QT3DSI32 border, - size_t imageSize, const void *hostPtr = NULL) = 0; - - /** - * @brief set compressed texture data for a Cubemap face - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] level Texture mip level - * @param[in] internalFormat format of the texture - * @param[in] width texture width - * @param[in] height texture height - * @param[in] border border - * @param[in] imageSize image size in bytes located at hostPtr - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetCompressedTextureDataCubeFace( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, - size_t imageSize, const void *hostPtr = NULL) = 0; - - /** - * @brief set compressed texture sub data for a 2D texture - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] level Texture mip level - * @param[in] xOffset Texture x offset - * @param[in] yOffset Texture y offset - * @param[in] width texture width - * @param[in] height texture height - * @param[in] format format of provided pixel data - * @param[in] imageSize image size in bytes located at hostPtr - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetCompressedTextureSubData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, - NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr = NULL) = 0; - - /** - * @brief establish a multisampled 2D texture - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D MS - * @param[in] samples Textures sample count - * @param[in] internalFormat Format of the texture - * @param[in] width Texture width - * @param[in] height Texture height - * @param[in] bool Fixed sample locations - * - * @return No return - */ - virtual void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - size_t samples, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, - bool fixedsamplelocations) = 0; - - /** - * @brief set texture data for a 3D texture or 2D texture array - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] level Texture mip level - * @param[in] internalFormat format of the texture - * @param[in] width texture width - * @param[in] height texture height - * @param[in] depth texture depth or slice count - * @param[in] border border - * @param[in] format format of provided pixel data - * @param[in] hostPtr A pointer to the buffer data that is allocated by the - * application. - * - * @return No return - */ - virtual void SetTextureData3D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, size_t depth, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) = 0; - - /** - * @brief generate mipmap levels - * - * @param[in] to Pointer to texture object - * @param[in] target Texture target 2D,... - * @param[in] hint How to generate mips (Nicest) - * - * @return No return - */ - virtual void GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum genType) = 0; - - /** - * @brief bind a texture object - * - * @param[in] to Pointer to texture object - * @param[in] target Where to bind this texture (e.g. 2D, 3D, ...) - * @param[in] unit Which unit to bind this texture - * - * @return no return. - */ - virtual void BindTexture(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 unit) = 0; - - /** - * @brief bind a image/texture object - * - * @param[in] to Pointer to texture object - * @param[in] unit Which unit to bind this texture - * @param[in] level Which level to bind - * @param[in] layered Bind layered texture (cube map, array,... ) - * @param[in] level Specify layer. Only valid of layered=false. - * @param[in] access Access mode ( read, write, read-write ) - * @param[in] format Texture format must be compatible with Image format - * - * @return no return. - */ - virtual void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, - bool layered, QT3DSI32 layer, - NVRenderImageAccessType::Enum accessFlags, - NVRenderTextureFormats::Enum format) = 0; - - /** - * @brief Release a single texture object - * - * @param[in] to Pointer to buffer object - * - * @return no return. - */ - virtual void ReleaseTexture(NVRenderBackendTextureObject to) = 0; - - /** - * @brief query texture swizzle mode - * This is mainly for luminance, alpha replacement with R8 formats - * - * @param[in] inFormat input texture format to check - * - * @return texture swizzle mode - */ - virtual NVRenderTextureSwizzleMode::Enum - GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const = 0; - - /** - * @ brief create a sampler - * - * @param[in] minFilter Texture min filter - * @param[in] magFilter Texture mag filter - * @param[in] wrapS Texture coord generation for S - * @param[in] wrapT Texture coord generation for T - * @param[in] wrapR Texture coord generation for R - * @param[in] minLod Texture min level of detail - * @param[in] maxLod Texture max level of detail - * @param[in] lodBias Texture level of detail example - * @param[in] compareMode Texture compare mode - * @param[in] compareFunc Texture compare function - * @param[in] anisoFilter Aniso filter value [1.0, 16.0] - * @param[in] borderColor Texture border color float[4] - * - * @return The created sampler object or NULL if the creation failed. - */ - virtual NVRenderBackendSamplerObject CreateSampler( - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; - - /** - * @ brief update a sampler - * - * @param[in] so Pointer to sampler object - * @param[in] target Texture target 2D, 3D - * @param[in] minFilter Texture min filter - * @param[in] magFilter Texture mag filter - * @param[in] wrapS Texture coord generation for S - * @param[in] wrapT Texture coord generation for T - * @param[in] wrapR Texture coord generation for R - * @param[in] minLod Texture min level of detail - * @param[in] maxLod Texture max level of detail - * @param[in] lodBias Texture level of detail bias (unused) - * @param[in] compareMode Texture compare mode - * @param[in] compareFunc Texture compare function - * @param[in] anisoFilter Aniso filter value [1.0, 16.0] - * @param[in] borderColor Texture border color float[4] (unused) - * - * @return No return - */ - virtual void UpdateSampler( - NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; - - /** - * @ brief Update a textures swizzle mode - * - * @param[in] so Pointer to texture object - * @param[in] target Texture target 2D, 3D - * @param[in] swizzleMode Texture swizzle mode - * - * @return No return - */ - virtual void UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) = 0; - - /** - * @ brief Update state belonging to a texture object - * - * @param[in] so Pointer to texture object - * @param[in] target Texture target 2D, 3D, Cube - * @param[in] baseLevel Texture base level - * @param[in] maxLevel Texture max level - * - * @return No return - */ - virtual void UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, - QT3DSI32 maxLevel) = 0; - - /** - * @brief Release a single sampler object - * - * @param[in] so Pointer to sampler object - * - * @return no return. - */ - virtual void ReleaseSampler(NVRenderBackendSamplerObject so) = 0; - - /** - * @brief create a attribute layout object - * - * @param[in] attribs Array off vertex attributes. - * - * @return The created attribute layout object or NULL if the creation failed. - */ - virtual NVRenderBackendAttribLayoutObject - CreateAttribLayout(NVConstDataRef attribs) = 0; - - /** - * @brief Release a attribute layoutr object - * - * @param[in] ao Pointer to attribute layout object - * - * @return no return. - */ - virtual void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) = 0; - - /** - * @brief create a input assembler object - * - * @param[in] attribLayout Pointer to NVRenderBackendAttribLayoutObject object - * @param[in] buffers list of vertex buffers - * @param[in] indexBuffer index buffer object - * @param[in] strides list of strides of the buffer - * @param[in] offsets list of offsets into the buffer - * @param[in] patchVertexCount vertext count for a patch. Only valid for patch primitives - * - * @return The created input assembler object or NULL if the creation failed. - */ - virtual NVRenderBackendInputAssemblerObject - CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, - NVConstDataRef buffers, - const NVRenderBackendBufferObject indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets, - QT3DSU32 patchVertexCount) = 0; - - /** - * @brief Release a input assembler object - * - * @param[in] iao Pointer to attribute layout object - * - * @return no return. - */ - virtual void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) = 0; - - /** - * @brief Set a input assembler object. - * This setup the render engine vertex assmebly - * - * @param[in] iao Pointer to attribute layout object - * @param[in] po Pointer program object - * - * @return false if it fails. - */ - virtual bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, - NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief Set the per patch vertex count - * - * @param[in] iao Pointer to attribute layout object - * @param[in] count Count of vertices per patch - * - * @return false if it fails. - */ - virtual void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) = 0; - - /** - * @brief create a vertex shader object - * - * @param[in] source Pointer to shader source - * @param[in/out] errorMessage Pointer to copy the error message - * @param[in] binary True if the source is actually a binary program - * - * @return The created vertex shader object or NULL if the creation failed. - */ - virtual NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef source, - eastl::string &errorMessage, - bool binary) = 0; - - /** - * @brief release a vertex shader object - * - * @param[in] vso Pointer to vertex shader object - * - * @return No Return. - */ - virtual void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) = 0; - - /** - * @brief create a fragment shader object - * - * @param[in] source Pointer to shader source - * @param[in/out] errorMessage Pointer to copy the error message - * @param[in] binary True if the source is actually a binary program - * - * @return The created vertex shader object or NULL if the creation failed. - */ - virtual NVRenderBackendFragmentShaderObject - CreateFragmentShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) = 0; - - /** - * @brief release a fragment shader object - * - * @param[in] vso Pointer to fragment shader object - * - * @return No Return. - */ - virtual void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) = 0; - - /** - * @brief create a tessellation control shader object - * - * @param[in] source Pointer to shader source - * @param[in/out] errorMessage Pointer to copy the error message - * @param[in] binary True if the source is actually a binary program - * - * @return The created tessellation control shader object or NULL if the creation failed. - */ - virtual NVRenderBackendTessControlShaderObject - CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) = 0; - - /** - * @brief release a tessellation control shader object - * - * @param[in] tcso Pointer to tessellation control shader object - * - * @return No Return. - */ - virtual void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) = 0; - - /** - * @brief create a tessellation evaluation shader object - * - * @param[in] source Pointer to shader source - * @param[in/out] errorMessage Pointer to copy the error message - * @param[in] binary True if the source is actually a binary program - * - * @return The created tessellation evaluation shader object or NULL if the creation failed. - */ - virtual NVRenderBackendTessEvaluationShaderObject - CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) = 0; - - /** - * @brief release a tessellation evaluation shader object - * - * @param[in] tcso Pointer to tessellation evaluation shader object - * - * @return No Return. - */ - virtual void - ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) = 0; - - /** - * @brief create a geometry shader object - * - * @param[in] source Pointer to shader source - * @param[in/out] errorMessage Pointer to copy the error message - * @param[in] binary True if the source is actually a binary program - * - * @return The created geometry shader object or NULL if the creation failed. - */ - virtual NVRenderBackendGeometryShaderObject - CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) = 0; - - /** - * @brief release a geometry shader object - * - * @param[in] tcso Pointer to geometry shader object - * - * @return No Return. - */ - virtual void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) = 0; - - /** - * @brief create a compute shader object - * - * @param[in] source Pointer to shader source - * @param[in/out] errorMessage Pointer to copy the error message - * @param[in] binary True if the source is actually a binary program - * - * @return The created compute shader object or NULL if the creation failed. - */ - virtual NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef source, - eastl::string &errorMessage, - bool binary) = 0; - - /** - * @brief release a compute shader object - * - * @param[in] cso Pointer to compute shader object - * - * @return No Return. - */ - virtual void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) = 0; - - /** - * @brief attach a vertex shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] vso Pointer to vertex shader object - * - * @return No Return. - */ - virtual void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendVertexShaderObject vso) = 0; - - /** - * @brief detach a vertex shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] vso Pointer to vertex shader object - * - * @return No Return. - */ - virtual void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendVertexShaderObject vso) = 0; - - /** - * @brief attach a fragment shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] fso Pointer to fragment shader object - * - * @return No Return. - */ - virtual void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendFragmentShaderObject fso) = 0; - - /** - * @brief detach a fragment shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] fso Pointer to fragment shader object - * - * @return No Return. - */ - virtual void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendFragmentShaderObject fso) = 0; - - /** - * @brief attach a tessellation control shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] tcso Pointer to tessellation control shader object - * - * @return No Return. - */ - virtual void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessControlShaderObject tcso) = 0; - - /** - * @brief detach a tessellation control shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] tcso Pointer to tessellation control shader object - * - * @return No Return. - */ - virtual void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessControlShaderObject tcso) = 0; - - /** - * @brief attach a tessellation evaluation shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] teso Pointer to tessellation evaluation shader object - * - * @return No Return. - */ - virtual void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessEvaluationShaderObject teso) = 0; - - /** - * @brief detach a tessellation evaluation shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] teso Pointer to tessellation evaluation shader object - * - * @return No Return. - */ - virtual void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessEvaluationShaderObject teso) = 0; - - /** - * @brief attach a geometry shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] teso Pointer to geometry shader object - * - * @return No Return. - */ - virtual void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendGeometryShaderObject gso) = 0; - - /** - * @brief detach a geometry shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] teso Pointer to geometry shader object - * - * @return No Return. - */ - virtual void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendGeometryShaderObject gso) = 0; - - /** - * @brief attach a compute shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] cso Pointer to compute shader object - * - * @return No Return. - */ - virtual void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendComputeShaderObject cso) = 0; - - /** - * @brief detach a compute shader object to a program object - * - * @param[in] po Pointer to program object - * @param[in] cso Pointer to compute shader object - * - * @return No Return. - */ - virtual void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendComputeShaderObject cso) = 0; - - /** - * @brief create a shader program object - * - * @param[in] isSeparable Tell the backend that this program is separable - * - * @return The created shader program object or NULL if the creation failed. - */ - virtual NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) = 0; - - /** - * @brief release a shader program object - * - * @param[in] po Pointer to shader program object - * - * @return No Return. - */ - virtual void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief link a shader program object - * - * @param[in] po Pointer to shader program object - * @param[in/out] errorMessage Pointer to copy the error message - * - * @return True if program is succesful linked. - */ - virtual bool LinkProgram(NVRenderBackendShaderProgramObject po, - eastl::string &errorMessage) = 0; - - /** - * @brief Make a program current - * - * @param[in] po Pointer to shader program object - * - * @return No return - */ - virtual void SetActiveProgram(NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief create a program pipeline object - * - * - * @return The created program pipeline object or NULL if the creation failed. - */ - virtual NVRenderBackendProgramPipeline CreateProgramPipeline() = 0; - - /** - * @brief release a program pipeline object - * - * @param[in] ppo Pointer to program pipeline object - * - * @return No Return. - */ - virtual void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; - - /** - * @brief Make a program pipeline current - * - * @param[in] ppo Pointer to program pipeline object - * - * @return No return - */ - virtual void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; - - /** - * @brief Make a program stage active for this pipeline - * - * @param[in] ppo Pointer to program pipeline object - * @param[in] flags Shader stage flags to which this po is bound to - * @param[in] po Pointer to shader program object - * - * @return No return - */ - virtual void SetProgramStages(NVRenderBackendProgramPipeline ppo, - NVRenderShaderTypeFlags flags, - NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief Runs a compute program - * - * @param[in] po Pointer to shader program object - * @param[in] numGroupsX The number of work groups to be launched in the X - * dimension - * @param[in] numGroupsY The number of work groups to be launched in the Y - * dimension - * @param[in] numGroupsZ The number of work groups to be launched in the Z - * dimension - * - * @return No return - */ - virtual void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, - QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; - - /** - * @brief Query constant count for a program object - * - * @param[in] po Pointer to shader program object - * - * @return Return active constant count - */ - virtual QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief Query constant buffer count for a program object - * - * @param[in] po Pointer to shader program object - * - * @return Return active constant buffer count - */ - virtual QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief Query constant information by ID - * - * @param[in] po Pointer to shader program object - * @param[in] id Constant ID - * @param[in] bufSize Max char for nameBuf - * @param[out] numElem Usually one unless for arrays - * @param[out] type Constant data type (QT3DSVec4, QT3DSVec3,...) - * @param[out] binding Unit binding point for samplers and images - * @param[out] nameBuf Name of the constant - * - * @return Return current constant location or -1 if not found - */ - virtual QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 bufSize, QT3DSI32 *numElem, - NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, - char *nameBuf) = 0; - - /** - * @brief Query constant buffer information by ID - * - * @param[in] po Pointer to shader program object - * @param[in] id Constant buffer ID - * @param[in] nameBufSize Size of nameBuf - * @param[out] paramCount Count ot parameter contained in the buffer - * @param[out] bufferSize Data size of the constant buffer - * @param[out] length Actual characters written - * @param[out] nameBuf Receives the name of the buffer - * - * @return Return current constant buffer location or -1 if not found - */ - virtual QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) = 0; - - /** - * @brief Query constant buffer param indices - * - * @param[in] po Pointer to shader program object - * @param[in] id Constant buffer ID - * @param[out] indices Receives the indices of the uniforms within the - * constant buffer - * - * @return no return value - */ - virtual void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSI32 *indices) = 0; - - /** - * @brief Query constant buffer param info by indices - * - * @param[in] po Pointer to shader program object - * @param[in] count Number of indices - * @param[in] indices The indices of the uniforms within the constant - * buffer - * @param[out] type Array of param types ( float ,int, ...) - * @param[out] size Array of param size - * @param[out] offset Array of param offsets within the constant buffer - * - * @return no return value - */ - virtual void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) = 0; - - /** - * @brief Bind program constant block - * - * @param[in] po Pointer to shader program object - * @param[in] blockIndex Constant block index returned by - * GetConstantBufferInfoByID - * @param[in] binding Block binding location which should be the same as index - * in ProgramSetConstantBlock - * - * @return No return - */ - virtual void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) = 0; - - /** - * @brief Bind constant buffer for usage in the current active shader program - * - * @param[in] index Constant ID - * @param[in] bo Pointer to constant buffer object - * - * @return No return - */ - virtual void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; - - /** - * @brief Query storage buffer count for a program object - * - * @param[in] po Pointer to shader program object - * - * @return Return active storage buffer count - */ - virtual QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief Query storage buffer information by ID - * - * @param[in] po Pointer to shader program object - * @param[in] id Storage buffer ID - * @param[in] nameBufSize Size of nameBuf - * @param[out] paramCount Count of parameter contained in the buffer - * @param[out] bufferSize Data size of the constant buffer - * @param[out] length Actual characters written - * @param[out] nameBuf Receives the name of the buffer - * - * @return Return current storage buffer binding or -1 if not found - */ - virtual QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) = 0; - - /** - * @brief Bind a storage buffer for usage in the current active shader program - * - * @param[in] index Constant ID - * @param[in] bo Pointer to storage buffer object - * - * @return No return - */ - virtual void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; - - /** - * @brief Query atomic counter buffer count for a program object - * - * @param[in] po Pointer to shader program object - * - * @return Return active atomic buffer count - */ - virtual QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) = 0; - - /** - * @brief Query atomic counter buffer information by ID - * - * @param[in] po Pointer to shader program object - * @param[in] id Storage buffer ID - * @param[in] nameBufSize Size of nameBuf - * @param[out] paramCount Count of parameter contained in the buffer - * @param[out] bufferSize Data size of the constant buffer - * @param[out] length Actual characters written - * @param[out] nameBuf Receives the name of the buffer - * - * @return Return current storage buffer binding or -1 if not found - */ - virtual QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) = 0; - - /** - * @brief Bind a atomic counter buffer for usage in the current active shader program - * - * @param[in] index Constant ID - * @param[in] bo Pointer to atomic counter buffer object - * - * @return No return - */ - virtual void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; - - /** - * @brief Set constant value - * - * @param[in] po Pointer program object - * @param[in] id Constant ID - * @param[in] type Constant data type (QT3DSVec4, QT3DSVec3,...) - * @param[in] count Element count - * @param[in] value Pointer to constant value - * @param[in] transpose Transpose a matrix - * - * @return No return - */ - virtual void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count, - const void *value, bool transpose = false) = 0; - - /** - * @brief Draw the current active vertex buffer - * - * @param[in] drawMode Draw mode (Triangles, ....) - * @param[in] start Start vertex - * @param[in] count Vertex count - * - * @return no return. - */ - virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) = 0; - - /** - * @brief Draw the current active vertex buffer using an indirect buffer - * This means the setup of the draw call is stored in a buffer bound to - * NVRenderBufferBindValues::Draw_Indirect - * - * @param[in] drawMode Draw mode (Triangles, ....) - * @param[in] indirect Offset into a indirect drawing setup buffer - * - * @return no return. - */ - virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) = 0; - - /** - * @brief Draw the current active index buffer - * - * @param[in] drawMode Draw mode (Triangles, ....) - * @param[in] count Index count - * @param[in] type Index type (QT3DSU16, QT3DSU8) - * @param[in] indices Pointer to index buffer. In the case of buffer objects - * this is an offset into the active index buffer - *object. - * - * @return no return. - */ - virtual void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, - NVRenderComponentTypes::Enum type, const void *indices) = 0; - - /** - * @brief Draw the current active index buffer using an indirect buffer - * This means the setup of the draw call is stored in a buffer bound to - * NVRenderBufferBindValues::Draw_Indirect - * - * @param[in] drawMode Draw mode (Triangles, ....) - * @param[in] type Index type (QT3DSU16, QT3DSU8) - * @param[in] indices Offset into a indirect drawing setup buffer - * - * @return no return. - */ - virtual void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, - NVRenderComponentTypes::Enum type, - const void *indirect) = 0; - - /** - * @brief Read a pixel rectangle from render target (from bottom left) - * - * @param[in] rto Pointer to render target object - * @param[in] x Windows X start coord - * @param[in] y Windows Y start coord - * @param[in] width Read width dim - * @param[in] height Read height dim - * @param[out] pixels Returned pixel data - * - * @return No return - */ - virtual void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, - QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, - void *pixels) = 0; - - /** - * @brief Create a NV path render object - * - * @param[in] range Number of internal objects - * - * @return return path object on success or NULL - */ - virtual NVRenderBackendPathObject CreatePathNVObject(size_t range) = 0; - - /** - * @brief Relase a NV path render object - * - * @param[in] po Created path object - * @param[in] range Number of internal objects - * - * @return return path object on success or NULL - */ - virtual void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) = 0; - - /** - * @brief Set the path commands and data. - * - * @param[in] inPathObject Pointer to NV path object - * @param[in] inPathCommands vector of path commands ( moveTo,... ) - * @param[in] inPathCoords vector of path coords - * - * @return No return - */ - virtual void SetPathSpecification(NVRenderBackendPathObject inPathObject, - NVConstDataRef inPathCommands, - NVConstDataRef inPathCoords) = 0; - - /** - * @brief Get Bounds of the path object - * - * @param[in] inPathObject Pointer to NV path object - * - * @return return bounds - */ - virtual NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) = 0; - virtual NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) = 0; - virtual NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) = 0; - - /** - * @brief Set stroke width. Defaults to 0 if unset. - * - * @param[in] inPathObject Pointer to NV path object - * - * @return No return - */ - virtual void SetStrokeWidth(NVRenderBackendPathObject inPathObject, - QT3DSF32 inStrokeWidth) = 0; - - /** - * @brief Path transform commands - * - * @param[in] inPathObject Pointer to NV path object - * - * @return No return - */ - virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; - virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; - - /** - * @brief Path stencil pass operations - * - * @param[in] inPathObject Pointer to NV path object - * - * @return No return - */ - virtual void StencilStrokePath(NVRenderBackendPathObject inPathObject) = 0; - virtual void StencilFillPath(NVRenderBackendPathObject inPathObject) = 0; - - /** - * @brief Does a instanced stencil fill pass - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] fillMode Fille mode - * @param[in] stencilMask Stencil mask - * @param[in] transformType Transforming glyphs - * @param[in] transformValues Pointer to array of transforms - * - * @return No return - */ - virtual void StencilFillPathInstanced( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, - const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, - NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) = 0; - - /** - * @brief Does a instanced stencil stroke pass - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] stencilRef Stencil reference - * @param[in] stencilMask Stencil mask - * @param[in] transformType Transforming glyphs - * @param[in] transformValues Pointer to array of transforms - * - * @return No return - */ - virtual void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathFormatType::Enum type, - const void *charCodes, QT3DSI32 stencilRef, - QT3DSU32 stencilMask, - NVRenderPathTransformType::Enum transformType, - const QT3DSF32 *transformValues) = 0; - - /** - * @brief Does a instanced cover fill pass - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] coverMode Cover mode - * @param[in] transformType Transforming glyphs - * @param[in] transformValues Pointer to array of transforms - * - * @return No return - */ - virtual void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathFormatType::Enum type, - const void *charCodes, - NVRenderPathCoverMode::Enum coverMode, - NVRenderPathTransformType::Enum transformType, - const QT3DSF32 *transformValues) = 0; - - /** - * @brief Does a instanced cover stroke pass - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] coverMode Cover mode - * @param[in] transformType Transforming glyphs - * @param[in] transformValues Pointer to array of transforms - * - * @return No return - */ - virtual void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathFormatType::Enum type, - const void *charCodes, - NVRenderPathCoverMode::Enum coverMode, - NVRenderPathTransformType::Enum transformType, - const QT3DSF32 *transformValues) = 0; - - /** - * @brief Path stencil and depth offset - * - * @param[in] inSlope slope - * @param[in] inBias bias - * - * @return No return - */ - virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; - - /** - * @brief Path cover function - * - * @param[in] inDepthFunction depth function - * - * @return No return - */ - virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) = 0; - - /** - * @brief Load glyphs - * - * @param[in] po Base of path objects - * @param[in] fontTarget System font, or application font,... - * @param[in] fontName Name of font ( may include path ) - * @param[in] fontStyle Bold or italic - * @param[in] numGlyphs Glyph count - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] handleMissingGlyphs skip or use - * @param[in] pathParameterTemplate template - * @param[in] emScale scale ( true type scale e.g. 2048 ) - * - * @return No return - */ - virtual void LoadPathGlyphs(NVRenderBackendPathObject po, - NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, - NVRenderPathFormatType::Enum type, const void *charCodes, - NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, - NVRenderBackendPathObject pathParameterTemplate, - QT3DSF32 emScale) = 0; - - /** - * @brief Load indexed font set - * - * @param[in] po Base of path objects - * @param[in] fontTarget System font, or application font,... - * @param[in] fontName Name of font ( may include path ) - * @param[in] fontStyle Bold or italic - * @param[in] firstGlyphIndex First glyph - * @param[in] numGlyphs Glyph count - * @param[in] pathParameterTemplate template - * @param[in] emScale scale ( true type scale e.g. 2048 ) - * - * @return return load status - */ - virtual NVRenderPathReturnValues::Enum - LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, - const void *fontName, NVRenderPathFontStyleFlags fontStyle, - QT3DSU32 firstGlyphIndex, size_t numGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) = 0; - - /** - * @brief Load indexed font set - * - * @param[in] fontTarget System font, or application font,... - * @param[in] fontName Name of font ( may include path ) - * @param[in] fontStyle Bold or italic - * @param[in] pathParameterTemplate template - * @param[in] emScale scale ( true type scale e.g. 2048 ) - * @param[out] po contains glyph count - * - * @return returnr base path object - */ - virtual NVRenderBackendPathObject - LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, - QT3DSU32 *count) = 0; - - /** - * @brief Load font set - * - * @param[in] po Base of path objects - * @param[in] fontTarget System font, or application font,... - * @param[in] fontName Name of font ( may include path ) - * @param[in] fontStyle Bold or italic - * @param[in] firstGlyph First glyph - * @param[in] numGlyphs Glyph count - * @param[in] handleMissingGlyphs skip or use - * @param[in] pathParameterTemplate template - * @param[in] emScale scale ( true type scale e.g. 2048 ) - * - * @return No return - */ - virtual void LoadPathGlyphRange(NVRenderBackendPathObject po, - NVRenderPathFontTarget::Enum fontTarget, - const void *fontName, NVRenderPathFontStyleFlags fontStyle, - QT3DSU32 firstGlyph, size_t numGlyphs, - NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, - NVRenderBackendPathObject pathParameterTemplate, - QT3DSF32 emScale) = 0; - - /** - * @brief Query font metrics - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] metricQueryMask Qeury bit mask - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] stride scale ( true type scale e.g. 2048 ) - * @param[out] metrics Filled with font metric values - * - * @return No return - */ - virtual void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathGlyphFontMetricFlags metricQueryMask, - NVRenderPathFormatType::Enum type, const void *charCodes, - size_t stride, QT3DSF32 *metrics) = 0; - - /** - * @brief Query font metrics - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] metricQueryMask Qeury bit mask - * @param[in] stride scale ( true type scale e.g. 2048 ) - * @param[out] metrics Filled with font metric values - * - * @return No return - */ - virtual void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathGlyphFontMetricFlags metricQueryMask, - size_t stride, QT3DSF32 *metrics) = 0; - - /** - * @brief Query path spacing - * - * @param[in] po Base of path objects - * @param[in] numPaths Number path objects - * @param[in] pathListMode How to compute spacing - * @param[in] type type ( byte, int,... ) - * @param[in] charCodes charachter string - * @param[in] advanceScale - * @param[in] kerningScale - * @param[in] transformType - * @param[out] metrics Filled with font metric values - * - * @return No return - */ - virtual void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathListMode::Enum pathListMode, - NVRenderPathFormatType::Enum type, const void *charCodes, - QT3DSF32 advanceScale, QT3DSF32 kerningScale, - NVRenderPathTransformType::Enum transformType, - QT3DSF32 *spacing) = 0; - - virtual QSurfaceFormat format() const = 0; - - protected: - /// struct for what the backend supports - typedef struct NVRenderBackendSupport - { - union { - struct - { - bool bDXTImagesSupported : 1; ///< compressed images supported - bool bAnistropySupported : 1; ///< anistropic filtering supported - bool bTextureSwizzleSupported : 1; ///< texture swizzle supported - bool bDepthStencilSupported : 1; ///< depth stencil textures are supported - bool bFPRenderTargetsSupported : 1; ///< floating point render targets are - ///supported - bool bConstantBufferSupported : 1; ///< Constant (uniform) buffers are supported - bool bMsTextureSupported : 1; ///< Multisample textures are esupported - bool bFastBlitsSupported : 1; ///< The hardware supports fast memor blits - bool bTessellationSupported : 1; ///< Hardware supports tessellation - bool bComputeSupported : 1; ///< Hardware supports compute shader - bool bGeometrySupported : 1; ///< Hardware supports geometry shader - bool bTimerQuerySupported : 1; ///< Hardware supports timer queries - bool bProgramInterfaceSupported : 1; ///< API supports program interface queries - bool bStorageBufferSupported : 1; ///< Shader storage buffers are supported - bool bAtomicCounterBufferSupported : 1; ///< Atomic counter buffers are - /// supported - bool bShaderImageLoadStoreSupported : 1; ///< Shader image load / store - ///operations are supported - bool bProgramPipelineSupported : 1; ///< Driver supports separate programs - bool bNVPathRenderingSupported : 1; ///< Driver NV path rendering - bool bNVAdvancedBlendSupported : 1; ///< Advanced blend modes supported - bool bNVBlendCoherenceSupported : 1; ///< Advanced blend done coherently - ///supported - bool bGPUShader5ExtensionSupported : 1; - bool bKHRAdvancedBlendSupported : 1; ///< Advanced blend modes supported - bool bKHRBlendCoherenceSupported : 1; ///< Advanced blend done coherently - bool bVertexArrayObjectSupported : 1; - bool bStandardDerivativesSupported : 1; - bool bTextureLodSupported : 1; - } bits; - - QT3DSU32 u32Values; - } caps; - } NVRenderBackendSupportBits; - - NVRenderBackendSupportBits m_backendSupport; ///< holds the backend support bits - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h deleted file mode 100644 index 4890de0e..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_RENDER_BACKEND_GLES2_H -#define QT3DS_RENDER_BACKEND_GLES2_H - -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" -#include "render/backends/gl/Qt3DSOpenGLExtensions.h" - -#include -#include - -namespace qt3ds { -namespace render { - - ///< forward declaration - class NVRenderBackendMiscStateGL; - - using namespace foundation; - - class NVRenderBackendGLES2Impl : public NVRenderBackendGLBase - { - public: - /// constructor - NVRenderBackendGLES2Impl(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format); - /// destructor - virtual ~NVRenderBackendGLES2Impl(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - public: - QT3DSU32 GetDepthBits() const override; - QT3DSU32 GetStencilBits() const override; - void GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum genType) override; - - void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - size_t samples, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, - bool fixedsamplelocations) override; - - void SetTextureData3D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, size_t depth, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = nullptr) override; - - void SetTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = nullptr) override; - - void UpdateSampler( - NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - QT3DSF32 minLod = -1000.0f, QT3DSF32 maxLod = 1000.0f, QT3DSF32 lodBias = 0.0f, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0f, QT3DSF32 *borderColor = nullptr) override; - - void UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, - QT3DSI32 maxLevel) override; - - void UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) override; - - bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, - NVRenderBackendShaderProgramObject po) override; - - void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, - NVConstDataRef inDrawBufferSet) override; - void SetReadBuffer(NVRenderBackendRenderTargetObject rto, - NVReadFaces::Enum inReadFace) override; - - void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) override; - - - NVRenderBackendRenderTargetObject CreateRenderTarget() override; - void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; - void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendRenderbufferObject rbo) override; - void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target - = NVRenderTextureTargetType::Texture2D) override; - void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, QT3DSI32 level, - QT3DSI32 layer) override; - void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; - bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; - - virtual NVRenderBackendRenderbufferObject - CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, - size_t height) override; - void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; - void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; - bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, - NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) override; - - void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, - size_t offset, size_t length, - NVRenderBufferAccessFlags accessFlags) override; - bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; - - QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) override; - void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSI32 *indices) override; - void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 count, QT3DSU32 *indices, - QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) override; - void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) override; - void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - NVRenderBackendQueryObject CreateQuery() override; - void ReleaseQuery(NVRenderBackendQueryObject qo) override; - void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; - void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; - void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; - void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; - void SetQueryTimer(NVRenderBackendQueryObject qo) override; - - NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, - NVRenderSyncFlags syncFlags) override; - void ReleaseSync(NVRenderBackendSyncObject so) override; - void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, - QT3DSU64 timeout) override; - - protected: - NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) - Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; -#endif - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h deleted file mode 100644 index c9ba76a6..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h +++ /dev/null @@ -1,392 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DSOPENGLEXTENSIONS_H -#define QT3DSOPENGLEXTENSIONS_H - -#include - -/* Some OpenGL extensions that are not (yet) found in Qt's OpenGL extensions. - * These should be auto-generated and added to QtOpenGLExtensions module */ -class Qt3DSOpenGLExtensionsPrivate : public QAbstractOpenGLExtensionPrivate -{ -public: - void (QOPENGLF_APIENTRYP BlendBarrierNV)(); - GLenum (QOPENGLF_APIENTRYP PathGlyphIndexArrayNV)( - GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint, - GLfloat); - GLenum (QOPENGLF_APIENTRYP PathGlyphIndexRangeNV)( - GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2]); - -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) - void (QOPENGLF_APIENTRYP PatchParameteriEXT)(GLenum, GLint); - void (QOPENGLF_APIENTRYP QueryCounterEXT)(GLuint, GLenum); - void (QOPENGLF_APIENTRYP GetQueryObjectui64vEXT)(GLuint, GLenum, - GLuint64 *); - GLuint (QOPENGLF_APIENTRYP GenPathsNV)(GLsizei); - void (QOPENGLF_APIENTRYP DeletePathsNV)(GLuint, GLsizei); - void (QOPENGLF_APIENTRYP PathCommandsNV)(GLuint, GLsizei, const GLubyte *, - GLsizei, GLenum, const void *); - void (QOPENGLF_APIENTRYP PathGlyphsNV)(GLuint, GLenum, const void *, - GLbitfield, GLsizei, GLenum, const void *, GLenum, GLuint, GLfloat); - void (QOPENGLF_APIENTRYP PathGlyphRangeNV)(GLuint, GLenum, const void *, - GLbitfield, GLuint, GLsizei, GLenum, GLuint, GLfloat); - void (QOPENGLF_APIENTRYP PathParameterfNV)(GLuint, GLenum, GLfloat); - void (QOPENGLF_APIENTRYP PathStencilDepthOffsetNV)(GLfloat, GLfloat); - void (QOPENGLF_APIENTRYP StencilFillPathNV)(GLuint, GLenum, GLuint); - void (QOPENGLF_APIENTRYP StencilStrokePathNV)(GLuint, GLint, GLuint); - void (QOPENGLF_APIENTRYP StencilFillPathInstancedNV)(GLsizei, GLenum, - const void *, GLuint, GLenum, GLuint, GLenum, const GLfloat *); - void (QOPENGLF_APIENTRYP StencilStrokePathInstancedNV)(GLsizei, GLenum, - const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *); - void (QOPENGLF_APIENTRYP PathCoverDepthFuncNV)(GLenum); - void (QOPENGLF_APIENTRYP CoverFillPathInstancedNV)(GLsizei, GLenum, - const void *, GLuint, GLenum, GLenum, const GLfloat *); - void (QOPENGLF_APIENTRYP CoverStrokePathInstancedNV)(GLsizei, GLenum, - const void *, GLuint, GLenum, GLenum, const GLfloat *); - void (QOPENGLF_APIENTRYP GetPathParameterfvNV)(GLuint, GLenum, GLfloat *); - void (QOPENGLF_APIENTRYP GetPathMetricsNV)(GLbitfield, GLsizei, GLenum, - const void *, GLuint, GLsizei, GLfloat *); - void (QOPENGLF_APIENTRYP GetPathMetricRangeNV)(GLbitfield, GLuint, GLsizei, - GLsizei, GLfloat *); - void (QOPENGLF_APIENTRYP GetPathSpacingNV)(GLenum, GLsizei, GLenum, - const void *, GLuint, GLfloat, GLfloat, GLenum, GLfloat *); - void (QOPENGLF_APIENTRYP BindVertexArrayOES) (GLuint array); - void (QOPENGLF_APIENTRYP DeleteVertexArraysOES) (GLsizei n, const GLuint *arrays); - void (QOPENGLF_APIENTRYP GenVertexArraysOES) (GLsizei n, GLuint *arrays); - GLboolean (QOPENGLF_APIENTRYP IsVertexArrayOES) (GLuint array); -#endif -}; - -class Qt3DSOpenGLExtensions : public QAbstractOpenGLExtension -{ -public: - Qt3DSOpenGLExtensions(); - - bool initializeOpenGLFunctions() override; - - void glBlendBarrierNV(); - GLenum glPathGlyphIndexArrayNV(GLuint firstPathName, GLenum fontTarget, - const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, - GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); - GLenum glPathGlyphIndexRangeNV(GLenum fontTarget, const void *fontName, - GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, - GLuint baseAndCount[2]); - -protected: - Q_DECLARE_PRIVATE(Qt3DSOpenGLExtensions) -}; - -inline void Qt3DSOpenGLExtensions::glBlendBarrierNV() -{ - Q_D(Qt3DSOpenGLExtensions); - d->BlendBarrierNV(); -} - -inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexArrayNV( - GLuint firstPathName, GLenum fontTarget, const void *fontName, - GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, - GLuint pathParameterTemplate, GLfloat emScale) -{ - Q_D(Qt3DSOpenGLExtensions); - return d->PathGlyphIndexArrayNV(firstPathName, fontTarget, fontName, - fontStyle, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale); -} - -inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexRangeNV(GLenum fontTarget, - const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, - GLfloat emScale, GLuint baseAndCount[2]) -{ - Q_D(Qt3DSOpenGLExtensions); - return d->PathGlyphIndexRangeNV(fontTarget, fontName, fontStyle, - pathParameterTemplate, emScale, baseAndCount); -} - -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) -class Qt3DSOpenGLES2Extensions : public Qt3DSOpenGLExtensions -{ -public: - Qt3DSOpenGLES2Extensions(); - - // tesselation shader - void glPatchParameteriEXT(GLenum pname, GLint value); - - // timer - void glQueryCounterEXT(GLuint id, GLenum target); - void glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params); - - // nv paths - - GLuint glGenPathsNV(GLsizei range); - void glDeletePathsNV(GLuint path, GLsizei range); - void glPathCommandsNV(GLuint path, GLsizei numCommands, - const GLubyte *commands, GLsizei numCoords, GLenum coordType, - const void *coords); - void glPathGlyphsNV(GLuint firstPathName, GLenum fontTarget, - const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, - GLenum type, const void *charcodes, GLenum handleMissingGlyphs, - GLuint pathParameterTemplate, GLfloat emScale); - void glPathGlyphRangeNV(GLuint firstPathName, GLenum fontTarget, - const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, - GLsizei numGlyphs, GLenum handleMissingGlyphs, - GLuint pathParameterTemplate, GLfloat emScale); - void glPathParameterfNV(GLuint path, GLenum pname, GLfloat value); - void glPathStencilDepthOffsetNV(GLfloat factor, GLfloat units); - void glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask); - void glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask); - void glStencilFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, - const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, - GLenum transformType, const GLfloat *transformValues); - void glStencilStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, - const void *paths, GLuint pathBase, GLint reference, GLuint mask, - GLenum transformType, const GLfloat *transformValues); - void glPathCoverDepthFuncNV(GLenum func); - void glCoverFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, - const void *paths, GLuint pathBase, GLenum coverMode, - GLenum transformType, const GLfloat *transformValues); - void glCoverStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, - const void *paths, GLuint pathBase, GLenum coverMode, - GLenum transformType, const GLfloat *transformValues); - void glGetPathParameterfvNV(GLuint path, GLenum pname, GLfloat *value); - void glGetPathMetricsNV(GLbitfield metricQueryMask, GLsizei numPaths, - GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, - GLfloat *metrics); - void glGetPathMetricRangeNV(GLbitfield metricQueryMask, - GLuint firstPathName, GLsizei numPaths, GLsizei stride, - GLfloat *metrics); - void glGetPathSpacingNV(GLenum pathListMode, GLsizei numPaths, - GLenum pathNameType, const void *paths, GLuint pathBase, - GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, - GLfloat *returnedSpacing); - void glBindVertexArrayOES(GLuint array); - void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays); - void glGenVertexArraysOES(GLsizei n, GLuint *arrays); - GLboolean glIsVertexArrayOES(GLuint array); - - bool initializeOpenGLFunctions() Q_DECL_FINAL; -}; - -inline void Qt3DSOpenGLES2Extensions::glPatchParameteriEXT(GLenum pname, - GLint value) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PatchParameteriEXT(pname, value); -} - -inline void Qt3DSOpenGLES2Extensions::glQueryCounterEXT(GLuint id, - GLenum target) -{ - Q_D(Qt3DSOpenGLExtensions); - d->QueryCounterEXT(id, target); -} - -inline void Qt3DSOpenGLES2Extensions::glGetQueryObjectui64vEXT(GLuint id, - GLenum pname, GLuint64 *params) -{ - Q_D(Qt3DSOpenGLExtensions); - d->GetQueryObjectui64vEXT(id, pname, params); -} - -inline GLuint Qt3DSOpenGLES2Extensions::glGenPathsNV(GLsizei range) -{ - Q_D(Qt3DSOpenGLExtensions); - return d->GenPathsNV(range); -} - -inline void Qt3DSOpenGLES2Extensions::glDeletePathsNV(GLuint path, - GLsizei range) -{ - Q_D(Qt3DSOpenGLExtensions); - d->DeletePathsNV(path, range); -} - -inline void Qt3DSOpenGLES2Extensions::glPathCommandsNV(GLuint path, - GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, - GLenum coordType, const void *coords) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PathCommandsNV(path, numCommands, commands, numCoords, coordType, - coords); -} - -inline void Qt3DSOpenGLES2Extensions::glPathGlyphsNV(GLuint firstPathName, - GLenum fontTarget, const void *fontName, GLbitfield fontStyle, - GLsizei numGlyphs, GLenum type, const void *charcodes, - GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, numGlyphs, - type, charcodes, handleMissingGlyphs, pathParameterTemplate, emScale); -} - -inline void Qt3DSOpenGLES2Extensions::glPathGlyphRangeNV(GLuint firstPathName, - GLenum fontTarget, const void *fontName, GLbitfield fontStyle, - GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, - GLuint pathParameterTemplate, GLfloat emScale) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PathGlyphRangeNV(firstPathName, fontTarget, fontName, fontStyle, - firstGlyph, numGlyphs, handleMissingGlyphs, pathParameterTemplate, - emScale); -} - -inline void Qt3DSOpenGLES2Extensions::glPathParameterfNV(GLuint path, - GLenum pname, GLfloat value) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PathParameterfNV(path, pname, value); -} - -inline void Qt3DSOpenGLES2Extensions::glPathStencilDepthOffsetNV(GLfloat factor, - GLfloat units) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PathStencilDepthOffsetNV(factor, units); -} - -inline void Qt3DSOpenGLES2Extensions::glStencilFillPathNV(GLuint path, - GLenum fillMode, GLuint mask) -{ - Q_D(Qt3DSOpenGLExtensions); - d->StencilFillPathNV(path, fillMode, mask); -} - -inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathNV(GLuint path, - GLint reference, GLuint mask) -{ - Q_D(Qt3DSOpenGLExtensions); - d->StencilStrokePathNV(path, reference, mask); -} - -inline void Qt3DSOpenGLES2Extensions::glStencilFillPathInstancedNV( - GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, - GLenum fillMode, GLuint mask, GLenum transformType, - const GLfloat *transformValues) -{ - Q_D(Qt3DSOpenGLExtensions); - d->StencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, - fillMode, mask, transformType, transformValues); -} - -inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathInstancedNV( - GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, - GLint reference, GLuint mask, GLenum transformType, - const GLfloat *transformValues) -{ - Q_D(Qt3DSOpenGLExtensions); - d->StencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, - reference, mask, transformType, transformValues); -} - -inline void Qt3DSOpenGLES2Extensions::glPathCoverDepthFuncNV(GLenum func) -{ - Q_D(Qt3DSOpenGLExtensions); - d->PathCoverDepthFuncNV(func); -} - -inline void Qt3DSOpenGLES2Extensions::glCoverFillPathInstancedNV( - GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, - GLenum coverMode, GLenum transformType, const GLfloat *transformValues) -{ - Q_D(Qt3DSOpenGLExtensions); - d->CoverFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, - coverMode, transformType, transformValues); -} - -inline void Qt3DSOpenGLES2Extensions::glCoverStrokePathInstancedNV( - GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, - GLenum coverMode, GLenum transformType, const GLfloat *transformValues) -{ - Q_D(Qt3DSOpenGLExtensions); - d->CoverStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, - coverMode, transformType, transformValues); -} - -inline void Qt3DSOpenGLES2Extensions::glGetPathParameterfvNV(GLuint path, - GLenum pname, GLfloat *value) -{ - Q_D(Qt3DSOpenGLExtensions); - d->GetPathParameterfvNV(path, pname, value); -} - -inline void Qt3DSOpenGLES2Extensions::glGetPathMetricsNV( - GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, - const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics) -{ - Q_D(Qt3DSOpenGLExtensions); - d->GetPathMetricsNV(metricQueryMask, numPaths, pathNameType, paths, - pathBase, stride, metrics); -} - -inline void Qt3DSOpenGLES2Extensions::glGetPathMetricRangeNV( - GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, - GLsizei stride, GLfloat *metrics) -{ - Q_D(Qt3DSOpenGLExtensions); - d->GetPathMetricRangeNV(metricQueryMask, firstPathName, numPaths, stride, - metrics); -} - -inline void Qt3DSOpenGLES2Extensions::glGetPathSpacingNV(GLenum pathListMode, - GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, - GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, - GLfloat *returnedSpacing) -{ - Q_D(Qt3DSOpenGLExtensions); - d->GetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase, - advanceScale, kerningScale, transformType, returnedSpacing); -} - -inline void Qt3DSOpenGLES2Extensions::glBindVertexArrayOES(GLuint array) -{ - Q_D(Qt3DSOpenGLExtensions); - d->BindVertexArrayOES(array); -} - -inline void Qt3DSOpenGLES2Extensions::glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) -{ - Q_D(Qt3DSOpenGLExtensions); - d->DeleteVertexArraysOES(n, arrays); -} - -inline void Qt3DSOpenGLES2Extensions::glGenVertexArraysOES(GLsizei n, GLuint *arrays) -{ - Q_D(Qt3DSOpenGLExtensions); - d->GenVertexArraysOES(n, arrays); -} - -inline GLboolean Qt3DSOpenGLES2Extensions::glIsVertexArrayOES(GLuint array) -{ - Q_D(Qt3DSOpenGLExtensions); - return d->IsVertexArrayOES(array); -} - -#endif // QT_OPENGL_ES - -#endif // QT3DSOPENGLEXTENSIONS_H diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h deleted file mode 100644 index 0e6dc6d4..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DSOPENGLPREFIX_H -#define QT3DSOPENGLPREFIX_H - -#include -#if defined(QT_OPENGL_ES) -#define GL_GLEXT_PROTOTYPES -#if defined(QT_OPENGL_ES_3_2) -#include -#else -#include -#include -#endif - -// Adding this to ensure that platform version of gl2ext.h is included -// before Qt's qopengles2ext.h which is missing symbols we need -#include -#endif - -#endif // QT3DSOPENGLPREFIX_H diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLTokens.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLTokens.h deleted file mode 100644 index 882e2761..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLTokens.h +++ /dev/null @@ -1,408 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DSOPENGLTOKENS_H -#define QT3DSOPENGLTOKENS_H - -/** - * This is our general internal to GL type conversion routines - * Add defines which are not in standard GL(ext) header but in GL2(ext) - * The define are the same with different names - * Expectation is the NVIDIA defines (need for compile) - */ -#ifndef GL_NVIDIA_PLATFORM_BINARY_NV -#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B -#endif -#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT -#endif - -#if defined(__APPLE__) || defined(ANDROID) || defined(__INTEGRITY) -#ifndef GL_DEPTH_COMPONENT24 -#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES -#endif -#ifndef GL_DEPTH_COMPONENT32 -#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES -#endif - -/** -_* tessellation_shader defines - */ -#ifndef GL_TESS_EVALUATION_SHADER -#define GL_TESS_EVALUATION_SHADER GL_TESS_EVALUATION_SHADER_EXT -#endif -#ifndef GL_TESS_CONTROL_SHADER -#define GL_TESS_CONTROL_SHADER GL_TESS_CONTROL_SHADER_EXT -#endif -#ifndef GL_PATCHES -#define GL_PATCHES GL_PATCHES_EXT -#endif -#ifndef GL_PATCH_VERTICES -#define GL_PATCH_VERTICES GL_PATCH_VERTICES_EXT -#endif -#ifndef GL_TESS_CONTROL_SHADER_BIT -#define GL_TESS_CONTROL_SHADER_BIT GL_TESS_CONTROL_SHADER_BIT_EXT -#endif -#ifndef GL_TESS_EVALUATION_SHADER_BIT -#define GL_TESS_EVALUATION_SHADER_BIT GL_TESS_EVALUATION_SHADER_BIT_EXT -#endif -#ifndef GL_VERTEX_SHADER_BIT -#define GL_VERTEX_SHADER_BIT GL_VERTEX_SHADER_BIT_EXT -#endif -#ifndef GL_FRAGMENT_SHADER_BIT -#define GL_FRAGMENT_SHADER_BIT GL_FRAGMENT_SHADER_BIT_EXT -#endif -#ifndef GL_GEOMETRY_SHADER_BIT -#define GL_GEOMETRY_SHADER_BIT GL_GEOMETRY_SHADER_BIT_EXT -#endif - - -/** - * sample shading extension - */ -#ifndef GL_SAMPLE_SHADING -#define GL_SAMPLE_SHADING GL_SAMPLE_SHADING_OES -#endif -#ifndef GL_MIN_SAMPLE_SHADING_VALUE -#define GL_MIN_SAMPLE_SHADING_VALUE GL_MIN_SAMPLE_SHADING_VALUE_OES -#endif - -/** - * Timer query extension - */ -#ifndef GL_TIME_ELAPSED -#define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT -#endif -#ifndef GL_TIMESTAMP -#define GL_TIMESTAMP GL_TIMESTAMP_EXT -#endif - -/** - * compute shader - */ -#ifndef GL_IMAGE_2D -#define GL_IMAGE_2D 0x904D -#endif - -/** - * texture formats ( make build happy ) - */ -#ifndef GL_R16 -#define GL_R16 0x822A -#endif - -#endif // __APPLE__ || ANDROID || __INTEGRITY - -#if defined(__APPLE__) || defined(ANDROID) - -#ifndef GL_NV_blend_equation_advanced -#define GL_NV_blend_equation_advanced 1 -#define GL_BLEND_OVERLAP_NV 0x9281 -#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 -#define GL_BLUE_NV 0x1905 -#define GL_COLORBURN_NV 0x929A -#define GL_COLORDODGE_NV 0x9299 -#define GL_CONJOINT_NV 0x9284 -#define GL_CONTRAST_NV 0x92A1 -#define GL_DARKEN_NV 0x9297 -#define GL_DIFFERENCE_NV 0x929E -#define GL_DISJOINT_NV 0x9283 -#define GL_DST_ATOP_NV 0x928F -#define GL_DST_IN_NV 0x928B -#define GL_DST_NV 0x9287 -#define GL_DST_OUT_NV 0x928D -#define GL_DST_OVER_NV 0x9289 -#define GL_EXCLUSION_NV 0x92A0 -#define GL_GREEN_NV 0x1904 -#define GL_HARDLIGHT_NV 0x929B -#define GL_HARDMIX_NV 0x92A9 -#define GL_HSL_COLOR_NV 0x92AF -#define GL_HSL_HUE_NV 0x92AD -#define GL_HSL_LUMINOSITY_NV 0x92B0 -#define GL_HSL_SATURATION_NV 0x92AE -#define GL_INVERT_OVG_NV 0x92B4 -#define GL_INVERT_RGB_NV 0x92A3 -#define GL_LIGHTEN_NV 0x9298 -#define GL_LINEARBURN_NV 0x92A5 -#define GL_LINEARDODGE_NV 0x92A4 -#define GL_LINEARLIGHT_NV 0x92A7 -#define GL_MINUS_CLAMPED_NV 0x92B3 -#define GL_MINUS_NV 0x929F -#define GL_MULTIPLY_NV 0x9294 -#define GL_OVERLAY_NV 0x9296 -#define GL_PINLIGHT_NV 0x92A8 -#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 -#define GL_PLUS_CLAMPED_NV 0x92B1 -#define GL_PLUS_DARKER_NV 0x9292 -#define GL_PLUS_NV 0x9291 -#define GL_RED_NV 0x1903 -#define GL_SCREEN_NV 0x9295 -#define GL_SOFTLIGHT_NV 0x929C -#define GL_SRC_ATOP_NV 0x928E -#define GL_SRC_IN_NV 0x928A -#define GL_SRC_NV 0x9286 -#define GL_SRC_OUT_NV 0x928C -#define GL_SRC_OVER_NV 0x9288 -#define GL_UNCORRELATED_NV 0x9282 -#define GL_VIVIDLIGHT_NV 0x92A6 -#define GL_XOR_NV 0x1506 -#endif /* GL_NV_blend_equation_advanced */ - -#ifndef GL_SHADER_STORAGE_BUFFER -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#endif - -#ifndef GL_ATOMIC_COUNTER_BUFFER -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#endif - -#ifndef GL_ALL_BARRIER_BITS -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF -#endif - -#ifndef GL_SHADER_STORAGE_BARRIER_BIT -#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -#endif - -#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#endif - -#ifndef GL_UNSIGNED_INT_IMAGE_2D -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#endif - - - -#ifndef GL_NV_path_rendering -#define GL_NV_path_rendering 1 -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_FILE_NAME_NV 0x9074 -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_COUNT_UP_NV 0x9088 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_CONVEX_HULL_NV 0x908B -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_UTF8_NV 0x909A -#define GL_UTF16_NV 0x909B -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_SQUARE_NV 0x90A3 -#define GL_ROUND_NV 0x90A4 -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_BEVEL_NV 0x90A6 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_CLOSE_PATH_NV 0x00 -#define GL_MOVE_TO_NV 0x02 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_LINE_TO_NV 0x04 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_RESTART_PATH_NV 0xF0 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_RECT_NV 0xF6 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_ARC_TO_NV 0xFE -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_BOLD_BIT_NV 0x01 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 -#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 -#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 -#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 -#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 -#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 -#define GL_FONT_ASCENDER_BIT_NV 0x00200000 -#define GL_FONT_DESCENDER_BIT_NV 0x00400000 -#define GL_FONT_HEIGHT_BIT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 -#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 -#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_2_BYTES_NV 0x1407 -#define GL_3_BYTES_NV 0x1408 -#define GL_4_BYTES_NV 0x1409 -#define GL_EYE_LINEAR_NV 0x2400 -#define GL_OBJECT_LINEAR_NV 0x2401 -#define GL_CONSTANT_NV 0x8576 -#define GL_PATH_PROJECTION_NV 0x1701 -#define GL_PATH_MODELVIEW_NV 0x1700 -#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 -#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 -#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 -#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 -#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 -#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 -#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 -#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 -#define GL_FRAGMENT_INPUT_NV 0x936D -#endif /* GL_NV_path_rendering */ - -#ifndef GL_SHADER_STORAGE_BLOCK -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#endif - -#ifndef GL_ACTIVE_RESOURCES -#define GL_ACTIVE_RESOURCES 0x92F5 -#endif - -#ifndef GL_BUFFER_BINDING -#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 -#define GL_BUFFER_BINDING 0x9302 -#define GL_BUFFER_DATA_SIZE 0x9303 -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#define GL_ACTIVE_VARIABLES 0x9305 -#endif - -#ifndef GL_UNIFORM -#define GL_UNIFORM 0x92E1 -#endif - -#ifndef GL_COMPUTE_SHADER -#define GL_COMPUTE_SHADER 0x91B9 -#endif - -#endif // __APPLE__ || ANDROID - -#endif // QT3DSOPENGLTOKENS_H diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h deleted file mode 100644 index 32f7dad7..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h +++ /dev/null @@ -1,2201 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DSOPENGLUTIL_H -#define QT3DSOPENGLUTIL_H - -#include "render/backends/gl/Qt3DSOpenGLPrefix.h" -#include "render/backends/gl/Qt3DSOpenGLTokens.h" -#include -#include - -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSVec4.h" -#include "foundation/Qt3DSFoundation.h" - -// The actual binding to the hardware the does some minor conversions between gles and -// the nv render enumeration types -namespace qt3ds { -namespace render { - -#ifndef GL_TEXTURE_2D_MULTISAMPLE -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#endif - -#ifndef GL_IMAGE_2D -#define GL_IMAGE_2D 0x904D -#endif - -#ifndef GL_MULTISAMPLE_EXT -#define GL_MULTISAMPLE_EXT 0x809D -#endif - -#ifndef GL_COLOR_ATTACHMENT1 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#endif - -#ifndef GL_RED -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#endif - -#ifndef GL_PATCHES -#define GL_PATCHES 0x000E -#endif - -#ifndef GL_READ_ONLY -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#endif - -#ifndef GL_SHADER_STORAGE_BUFFER -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#endif - -#ifndef GL_ATOMIC_COUNTER_BUFFER -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#endif - -#ifndef GL_DRAW_INDIRECT_BUFFER -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#endif - -#ifndef GL_VERTEX_SHADER_BIT -#define GL_VERTEX_SHADER_BIT 0x00000001 -#endif - -#ifndef GL_FRAGMENT_SHADER_BIT -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#endif - -#ifndef GL_GEOMETRY_SHADER_BIT -#define GL_GEOMETRY_SHADER_BIT 0x00000004 -#endif - -#ifndef GL_TESS_CONTROL_SHADER_BIT -#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 -#endif - -#ifndef GL_TESS_EVALUATION_SHADER_BIT -#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 -#endif - -#ifndef GL_ETC1_RGB8_OES -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - -#ifndef GL_COMPRESSED_RED_RGTC1 -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#endif - -#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#endif - -#ifndef GL_COMPRESSED_RG_RGTC2 -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#endif - -#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#endif - -#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F -#endif - -#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#endif - -#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#endif - -#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#endif - -#ifndef GL_COMPRESSED_RGB8_ETC2 -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#endif - -#ifndef GL_COMPRESSED_SRGB8_ETC2 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#endif - -#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#endif - -#ifndef GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#endif - -#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#endif - -#ifndef GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 -#endif - -#ifndef GL_COMPRESSED_R11_EAC -#define GL_COMPRESSED_R11_EAC 0x9270 -#endif - -#ifndef GL_COMPRESSED_SIGNED_R11_EAC -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#endif - -#ifndef GL_COMPRESSED_RG11_EAC -#define GL_COMPRESSED_RG11_EAC 0x9272 -#endif - -#ifndef GL_COMPRESSED_SIGNED_RG11_EAC -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#endif - -#define QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ZERO, Zero) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE, One) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_COLOR, SrcColor) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_COLOR, OneMinusSrcColor) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_COLOR, DstColor) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_COLOR, OneMinusDstColor) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_ALPHA, SrcAlpha) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_ALPHA, OneMinusSrcAlpha) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_ALPHA, DstAlpha) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_ALPHA, OneMinusDstAlpha) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_COLOR, ConstantColor) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_COLOR, OneMinusConstantColor) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_ALPHA, ConstantAlpha) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_ALPHA, OneMinusConstantAlpha) \ - QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(GL_SRC_ALPHA_SATURATE, SrcAlphaSaturate) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT, Front) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_BACK, Back) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT_AND_BACK, FrontAndBack) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CW, Clockwise) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CCW, CounterClockwise) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NEVER, Never) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LESS, Less) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_EQUAL, Equal) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LEQUAL, LessThanOrEqual) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GREATER, Greater) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NOTEQUAL, NotEqual) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GEQUAL, GreaterThanOrEqual) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_ALWAYS, AlwaysTrue) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_HINT \ - QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_FASTEST, Fastest) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_NICEST, Nicest) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_DONT_CARE, Unspecified) - -#define QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_KEEP, Keep) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_ZERO, Zero) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_REPLACE, Replace) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR, Increment) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR_WRAP, IncrementWrap) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR, Decrement) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR_WRAP, DecrementWrap) \ - QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INVERT, Invert) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_BYTE, QT3DSU8) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_BYTE, QT3DSI8) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_SHORT, QT3DSU16) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_SHORT, QT3DSI16) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_INT, QT3DSU32) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(GL_INT, QT3DSI32) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_FLOAT, QT3DSF32) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_STATIC_DRAW, Static) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_DYNAMIC_DRAW, Dynamic) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_NEAREST, Nearest) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_LINEAR, Linear) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_NEAREST, NearestMipmapNearest) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_NEAREST, LinearMipmapNearest) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_LINEAR, NearestMipmapLinear) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_LINEAR, LinearMipmapLinear) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_CLAMP_TO_EDGE, ClampToEdge) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_MIRRORED_REPEAT, MirroredRepeat) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_REPEAT, Repeat) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT, QT3DSF32) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC2, QT3DSVec2) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC3, QT3DSVec3) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC4, QT3DSVec4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT, QT3DSI32) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC2, QT3DSI32_2) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC3, QT3DSI32_3) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC4, QT3DSI32_4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL, QT3DSRenderBool) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC2, bool_2) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC3, bool_3) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC4, bool_4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT, QT3DSU32) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC2, QT3DSU32_2) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC3, QT3DSU32_3) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC4, QT3DSU32_4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT3, QT3DSMat33) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT4, QT3DSMat44) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D, NVRenderTexture2DPtr) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D_ARRAY, NVRenderTexture2DArrayPtr) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_CUBE, NVRenderTextureCubePtr) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_IMAGE_2D, NVRenderImage2DPtr) -// cube Sampler and mat22 unsupported - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT, QT3DSF32, 1) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC2, QT3DSF32, 2) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC3, QT3DSF32, 3) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC4, QT3DSF32, 4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT2, QT3DSF32, 4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT3, QT3DSF32, 9) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT4, QT3DSF32, 16) -#if defined(GL_DEPTH_COMPONENT32) -#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT32, Depth32) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) -#else -#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) -#endif - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color0, 0) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color1, 1) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color2, 2) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color3, 3) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color4, 4) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color5, 5) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color6, 6) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color7, 7) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_ATTACHMENT, Depth) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_STENCIL_ATTACHMENT, Stencil) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_STENCIL_ATTACHMENT, DepthStencil) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS \ - QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_COLOR_BUFFER_BIT, Color) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_DEPTH_BUFFER_BIT, Depth) \ - QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_STENCIL_BUFFER_BIT, Stencil) - -#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS -#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS -#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS - - static bool IsGlEsContext(NVRenderContextType inContextType) - { - NVRenderContextType esContextTypes(NVRenderContextValues::GLES2 - | NVRenderContextValues::GLES3 - | NVRenderContextValues::GLES3PLUS); - - if ((inContextType & esContextTypes)) - return true; - - return false; - } - - struct GLConversion - { - GLConversion() - { } - - static const char *processGLError(GLenum error) - { - const char *errorString = ""; - switch (error) { -#define stringiseError(error) \ - case error: \ - errorString = #error; \ - break - stringiseError(GL_NO_ERROR); - stringiseError(GL_INVALID_ENUM); - stringiseError(GL_INVALID_VALUE); - stringiseError(GL_INVALID_OPERATION); - stringiseError(GL_INVALID_FRAMEBUFFER_OPERATION); - stringiseError(GL_OUT_OF_MEMORY); -#undef stringiseError - default: - errorString = "Unknown GL error"; - break; - } - return errorString; - } - - static NVRenderSrcBlendFunc::Enum fromGLToSrcBlendFunc(QT3DSI32 value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ - case srcVal: \ - return NVRenderSrcBlendFunc::enumVal; -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ - case srcVal: \ - return NVRenderSrcBlendFunc::enumVal; - QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY - default: - QT3DS_ASSERT(false); - return NVRenderSrcBlendFunc::Unknown; - } - } - - static GLenum fromSrcBlendFuncToGL(NVRenderSrcBlendFunc::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ - case NVRenderSrcBlendFunc::enumVal: \ - return srcVal; -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ - case NVRenderSrcBlendFunc::enumVal: \ - return srcVal; - QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY - default: - QT3DS_ASSERT(false); - return 0; - } - } - - static NVRenderDstBlendFunc::Enum fromGLToDstBlendFunc(QT3DSI32 value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ - case srcVal: \ - return NVRenderDstBlendFunc::enumVal; -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) - QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY - default: - QT3DS_ASSERT(false); - return NVRenderDstBlendFunc::Unknown; - } - } - - static GLenum fromDstBlendFuncToGL(NVRenderDstBlendFunc::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ - case NVRenderDstBlendFunc::enumVal: \ - return srcVal; -#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) - QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC -#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY - default: - QT3DS_ASSERT(false); - return 0; - } - } - - static GLenum fromBlendEquationToGL(NVRenderBlendEquation::Enum value, - bool nvAdvancedBlendSupported, - bool khrAdvancedBlendSupported) - { - switch (value) { - case NVRenderBlendEquation::Add: - return GL_FUNC_ADD; - case NVRenderBlendEquation::Subtract: - return GL_FUNC_SUBTRACT; - case NVRenderBlendEquation::ReverseSubtract: - return GL_FUNC_REVERSE_SUBTRACT; - default: - QT3DS_ASSERT(nvAdvancedBlendSupported || khrAdvancedBlendSupported); - break; - } - - if (nvAdvancedBlendSupported) { - switch (value) { - case NVRenderBlendEquation::Overlay: - return GL_OVERLAY_NV; - case NVRenderBlendEquation::ColorBurn: - return GL_COLORBURN_NV; - case NVRenderBlendEquation::ColorDodge: - return GL_COLORDODGE_NV; - default: - break; - } - } - -#if defined(GL_KHR_blend_equation_advanced) - if (khrAdvancedBlendSupported) { - switch (value) { - case NVRenderBlendEquation::Overlay: - return GL_OVERLAY_KHR; - case NVRenderBlendEquation::ColorBurn: - return GL_COLORBURN_KHR; - case NVRenderBlendEquation::ColorDodge: - return GL_COLORDODGE_KHR; - default: - break; - } - } -#endif - - QT3DS_ASSERT(false); - return GL_FUNC_ADD; - } - - static NVRenderFaces::Enum fromGLToFaces(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ - case x: \ - return NVRenderFaces::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderFaces::Unknown; - } - - static GLenum fromFacesToGL(NVRenderFaces::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ - case NVRenderFaces::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVReadFaces::Enum fromGLToReadFaces(GLenum value) - { - switch (value) { - case GL_FRONT: - return NVReadFaces::Front; - case GL_BACK: - return NVReadFaces::Back; - case GL_COLOR_ATTACHMENT0: - return NVReadFaces::Color0; - case GL_COLOR_ATTACHMENT1: - return NVReadFaces::Color1; - case GL_COLOR_ATTACHMENT2: - return NVReadFaces::Color2; - case GL_COLOR_ATTACHMENT3: - return NVReadFaces::Color3; - case GL_COLOR_ATTACHMENT4: - return NVReadFaces::Color4; - case GL_COLOR_ATTACHMENT5: - return NVReadFaces::Color5; - case GL_COLOR_ATTACHMENT6: - return NVReadFaces::Color6; - case GL_COLOR_ATTACHMENT7: - return NVReadFaces::Color7; - - default: - break; - } - QT3DS_ASSERT(false); - return NVReadFaces::Unknown; - } - - static GLenum fromReadFacesToGL(NVReadFaces::Enum value) - { - switch (value) { - case NVReadFaces::Front: - return GL_FRONT; - case NVReadFaces::Back: - return GL_BACK; - case NVReadFaces::Color0: - return GL_COLOR_ATTACHMENT0; - case NVReadFaces::Color1: - return GL_COLOR_ATTACHMENT1; - case NVReadFaces::Color2: - return GL_COLOR_ATTACHMENT2; - case NVReadFaces::Color3: - return GL_COLOR_ATTACHMENT3; - case NVReadFaces::Color4: - return GL_COLOR_ATTACHMENT4; - case NVReadFaces::Color5: - return GL_COLOR_ATTACHMENT5; - case NVReadFaces::Color6: - return GL_COLOR_ATTACHMENT6; - case NVReadFaces::Color7: - return GL_COLOR_ATTACHMENT7; - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderWinding::Enum fromGLToWinding(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ - case x: \ - return NVRenderWinding::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderWinding::Unknown; - } - - static GLenum fromWindingToGL(NVRenderWinding::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ - case NVRenderWinding::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderBoolOp::Enum fromGLToBoolOp(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ - case x: \ - return NVRenderBoolOp::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderBoolOp::Unknown; - } - - static GLenum fromBoolOpToGL(NVRenderBoolOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ - case NVRenderBoolOp::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderHint::Enum fromGLToHint(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ - case x: \ - return NVRenderHint::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_HINT -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderHint::Unknown; - } - - static GLenum fromHintToGL(NVRenderHint::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ - case NVRenderHint::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_HINT -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderStencilOp::Enum fromGLToStencilOp(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ - case x: \ - return NVRenderStencilOp::y; - QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP -#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP - default: - break; - } - - QT3DS_ASSERT(false); - return NVRenderStencilOp::Unknown; - } - - static GLenum fromStencilOpToGL(NVRenderStencilOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ - case NVRenderStencilOp::y: \ - return x; - QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP -#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP - default: - break; - } - - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderComponentTypes::Enum fromGLToBufferComponentTypes(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ - case x: \ - return NVRenderComponentTypes::y; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) - QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderComponentTypes::Unknown; - } - - static GLenum fromBufferComponentTypesToGL(NVRenderComponentTypes::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ - case NVRenderComponentTypes::y: \ - return x; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) \ - case NVRenderComponentTypes::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static GLenum fromIndexBufferComponentsTypesToGL(NVRenderComponentTypes::Enum value) - { - switch (value) { - case NVRenderComponentTypes::QT3DSU8: - return GL_UNSIGNED_BYTE; - case NVRenderComponentTypes::QT3DSU16: - return GL_UNSIGNED_SHORT; - case NVRenderComponentTypes::QT3DSU32: - return GL_UNSIGNED_INT; - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static GLenum fromBindBufferFlagsToGL(NVRenderBufferBindFlags flags) - { - QT3DSU32 value = flags; - GLenum retval = GL_INVALID_ENUM; - if (value & NVRenderBufferBindValues::Vertex) - retval = GL_ARRAY_BUFFER; - else if (value & NVRenderBufferBindValues::Index) - retval = GL_ELEMENT_ARRAY_BUFFER; - else if (value & NVRenderBufferBindValues::Constant) - retval = GL_UNIFORM_BUFFER; - else if (value & NVRenderBufferBindValues::Storage) - retval = GL_SHADER_STORAGE_BUFFER; - else if (value & NVRenderBufferBindValues::Atomic_Counter) - retval = GL_ATOMIC_COUNTER_BUFFER; - else if (value & NVRenderBufferBindValues::Draw_Indirect) - retval = GL_DRAW_INDIRECT_BUFFER; - else - QT3DS_ASSERT(false); - - return retval; - } - - static NVRenderBufferBindFlags fromGLToBindBufferFlags(GLenum value) - { - QT3DSU32 retval = 0; - - if (value == GL_ARRAY_BUFFER) - retval |= NVRenderBufferBindValues::Vertex; - else if (value == GL_ELEMENT_ARRAY_BUFFER) - retval |= NVRenderBufferBindValues::Index; - else if (value == GL_UNIFORM_BUFFER) - retval |= NVRenderBufferBindValues::Constant; - else if (value == GL_SHADER_STORAGE_BUFFER) - retval |= NVRenderBufferBindValues::Storage; - else if (value == GL_ATOMIC_COUNTER_BUFFER) - retval |= NVRenderBufferBindValues::Atomic_Counter; - else if (value == GL_DRAW_INDIRECT_BUFFER) - retval |= NVRenderBufferBindValues::Draw_Indirect; - else - QT3DS_ASSERT(false); - - return NVRenderBufferBindFlags(retval); - } - - static NVRenderBufferUsageType::Enum fromGLToBufferUsageType(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ - case x: \ - return NVRenderBufferUsageType::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderBufferUsageType::Unknown; - } - - static GLenum fromBufferUsageTypeToGL(NVRenderBufferUsageType::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ - case NVRenderBufferUsageType::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static GLenum fromQueryTypeToGL(NVRenderQueryType::Enum type) - { - GLenum retval = GL_INVALID_ENUM; - if (type == NVRenderQueryType::Samples) - retval = GL_ANY_SAMPLES_PASSED; -#if defined(GL_TIME_ELAPSED) - else if (type == NVRenderQueryType::Timer) - retval = GL_TIME_ELAPSED; -#elif defined(GL_TIME_ELAPSED_EXT) - else if (type == NVRenderQueryType::Timer) - retval = GL_TIME_ELAPSED_EXT; -#endif - else - QT3DS_ASSERT(false); - - return retval; - } - - static GLenum fromQueryResultTypeToGL(NVRenderQueryResultType::Enum type) - { - GLenum retval = GL_INVALID_ENUM; - if (type == NVRenderQueryResultType::ResultAvailable) - retval = GL_QUERY_RESULT_AVAILABLE; - else if (type == NVRenderQueryResultType::Result) - retval = GL_QUERY_RESULT; - else - QT3DS_ASSERT(false); - - return retval; - } - - static GLenum fromSyncTypeToGL(NVRenderSyncType::Enum type) - { - GLenum retval = GL_INVALID_ENUM; - if (type == NVRenderSyncType::GpuCommandsComplete) - retval = GL_SYNC_GPU_COMMANDS_COMPLETE; - else - QT3DS_ASSERT(false); - - return retval; - } - - static NVRenderTextureFormats::Enum - replaceDeprecatedTextureFormat(NVRenderContextType type, NVRenderTextureFormats::Enum value, - NVRenderTextureSwizzleMode::Enum &swizzleMode) - { - NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - NVRenderTextureFormats::Enum newValue = value; - swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - - if (!(type & deprecatedContextFlags)) { - switch (value) { - case NVRenderTextureFormats::Luminance8: - newValue = NVRenderTextureFormats::R8; - swizzleMode = NVRenderTextureSwizzleMode::L8toR8; - break; - case NVRenderTextureFormats::LuminanceAlpha8: - newValue = NVRenderTextureFormats::RG8; - swizzleMode = NVRenderTextureSwizzleMode::L8A8toRG8; - break; - case NVRenderTextureFormats::Alpha8: - newValue = NVRenderTextureFormats::R8; - swizzleMode = NVRenderTextureSwizzleMode::A8toR8; - break; - case NVRenderTextureFormats::Luminance16: - newValue = NVRenderTextureFormats::R16; - swizzleMode = NVRenderTextureSwizzleMode::L16toR16; - break; - default: - break; - } - } - - return newValue; - } - - static void - NVRenderConvertSwizzleModeToGL(const NVRenderTextureSwizzleMode::Enum swizzleMode, - GLint glSwizzle[4]) - { - switch (swizzleMode) { - case NVRenderTextureSwizzleMode::L16toR16: - case NVRenderTextureSwizzleMode::L8toR8: - glSwizzle[0] = GL_RED; - glSwizzle[1] = GL_RED; - glSwizzle[2] = GL_RED; - glSwizzle[3] = GL_ONE; - break; - case NVRenderTextureSwizzleMode::L8A8toRG8: - glSwizzle[0] = GL_RED; - glSwizzle[1] = GL_RED; - glSwizzle[2] = GL_RED; - glSwizzle[3] = GL_GREEN; - break; - case NVRenderTextureSwizzleMode::A8toR8: - glSwizzle[0] = GL_ZERO; - glSwizzle[1] = GL_ZERO; - glSwizzle[2] = GL_ZERO; - glSwizzle[3] = GL_RED; - break; - case NVRenderTextureSwizzleMode::NoSwizzle: - default: - glSwizzle[0] = GL_RED; - glSwizzle[1] = GL_GREEN; - glSwizzle[2] = GL_BLUE; - glSwizzle[3] = GL_ALPHA; - break; - } - } - - static bool fromUncompressedTextureFormatToGL(NVRenderContextType type, - NVRenderTextureFormats::Enum value, - GLenum &outFormat, GLenum &outDataType, - GLenum &outInternalFormat) - { - switch (value) { - case NVRenderTextureFormats::R8: - if (type == NVRenderContextValues::GLES2) { - outFormat = GL_ALPHA; - outInternalFormat = GL_ALPHA; - } else { - outFormat = GL_RED; - outInternalFormat = GL_R8; - } - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::RG8: - outFormat = GL_RG; - outInternalFormat = GL_RG8; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::RGBA8: - outFormat = GL_RGBA; - outInternalFormat = GL_RGBA8; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::RGB8: - outFormat = GL_RGB; - outInternalFormat = GL_RGB8; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::RGB565: - outFormat = GL_RGB; - outInternalFormat = GL_RGB8; - outDataType = GL_UNSIGNED_SHORT_5_6_5; - return true; - case NVRenderTextureFormats::RGBA5551: - outFormat = GL_RGBA; - outInternalFormat = GL_RGBA8; - outDataType = GL_UNSIGNED_SHORT_5_5_5_1; - return true; - case NVRenderTextureFormats::Alpha8: - outFormat = GL_ALPHA; - outInternalFormat = GL_ALPHA; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::Luminance8: - outFormat = GL_LUMINANCE; - outInternalFormat = GL_LUMINANCE; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::LuminanceAlpha8: - outFormat = GL_LUMINANCE_ALPHA; - outInternalFormat = GL_LUMINANCE_ALPHA; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::Luminance16: -#if defined(QT_OPENGL_ES) - outFormat = GL_LUMINANCE16F_EXT; - outInternalFormat = GL_LUMINANCE16F_EXT; -#else - outFormat = GL_LUMINANCE; - outInternalFormat = GL_LUMINANCE; -#endif - outDataType = GL_UNSIGNED_INT; - return true; - default: - break; - } - - NVRenderContextType contextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - // check extented texture formats - if (!(type & contextFlags)) { - switch (value) { -#if !defined(QT_OPENGL_ES) - case NVRenderTextureFormats::R16: { - if (IsGlEsContext(type)) { - outFormat = GL_RED_INTEGER; - outInternalFormat = GL_R16UI; - } else { - outFormat = GL_RED; - outInternalFormat = GL_R16; - } - outDataType = GL_UNSIGNED_SHORT; - return true; - } -#endif - case NVRenderTextureFormats::R16F: - outFormat = GL_RED; - outInternalFormat = GL_R16F; - outDataType = GL_HALF_FLOAT; - return true; - case NVRenderTextureFormats::R32UI: - outFormat = GL_RED_INTEGER; - outInternalFormat = GL_R32UI; - outDataType = GL_UNSIGNED_INT; - return true; - case NVRenderTextureFormats::R32F: - outFormat = GL_RED; - outInternalFormat = GL_R32F; - outDataType = GL_FLOAT; - return true; - case NVRenderTextureFormats::RGBA16F: - outFormat = GL_RGBA; - outInternalFormat = GL_RGBA16F; - outDataType = GL_HALF_FLOAT; - return true; - case NVRenderTextureFormats::RG16F: - outFormat = GL_RG; - outInternalFormat = GL_RG16F; - outDataType = GL_HALF_FLOAT; - return true; - case NVRenderTextureFormats::RG32F: - outFormat = GL_RG; - outInternalFormat = GL_RG32F; - outDataType = GL_FLOAT; - return true; - case NVRenderTextureFormats::RGBA32F: - outFormat = GL_RGBA; - outInternalFormat = GL_RGBA32F; - outDataType = GL_FLOAT; - return true; - case NVRenderTextureFormats::RGB32F: - outFormat = GL_RGB; - outInternalFormat = GL_RGB32F; - outDataType = GL_FLOAT; - return true; - case NVRenderTextureFormats::R11G11B10: - outFormat = GL_RGB; - outInternalFormat = GL_R11F_G11F_B10F; - outDataType = GL_UNSIGNED_INT_10F_11F_11F_REV; - return true; - case NVRenderTextureFormats::RGB9E5: - outFormat = GL_RGB; - outInternalFormat = GL_RGB9_E5; - outDataType = GL_UNSIGNED_INT_5_9_9_9_REV; - return true; - case NVRenderTextureFormats::SRGB8: - outFormat = GL_RGB; - outInternalFormat = GL_SRGB8; - outDataType = GL_UNSIGNED_BYTE; - return true; - case NVRenderTextureFormats::SRGB8A8: - outFormat = GL_RGBA; - outInternalFormat = GL_SRGB8_ALPHA8; - outDataType = GL_UNSIGNED_BYTE; - return true; - default: - break; - } - } - - QT3DS_ASSERT(false); - return false; - } - - static GLenum fromCompressedTextureFormatToGL(NVRenderTextureFormats::Enum value) - { - switch (value) { - case NVRenderTextureFormats::RGBA_DXT1: - return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case NVRenderTextureFormats::RGB_DXT1: - return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case NVRenderTextureFormats::RGBA_DXT3: - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - case NVRenderTextureFormats::RGBA_DXT5: - return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case NVRenderTextureFormats::R_ATI1N_UNorm: - return GL_COMPRESSED_RED_RGTC1; - case NVRenderTextureFormats::R_ATI1N_SNorm: - return GL_COMPRESSED_SIGNED_RED_RGTC1; - case NVRenderTextureFormats::RG_ATI2N_UNorm: - return GL_COMPRESSED_RG_RGTC2; - case NVRenderTextureFormats::RG_ATI2N_SNorm: - return GL_COMPRESSED_SIGNED_RG_RGTC2; - case NVRenderTextureFormats::RGB_BP_UNSIGNED_FLOAT: - return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; - case NVRenderTextureFormats::RGB_BP_SIGNED_FLOAT: - return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB; - case NVRenderTextureFormats::RGB_BP_UNorm: - return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; - case NVRenderTextureFormats::R11_EAC_UNorm: - return GL_COMPRESSED_R11_EAC; - case NVRenderTextureFormats::R11_EAC_SNorm: - return GL_COMPRESSED_SIGNED_R11_EAC; - case NVRenderTextureFormats::RG11_EAC_UNorm: - return GL_COMPRESSED_RG11_EAC; - case NVRenderTextureFormats::RG11_EAC_SNorm: - return GL_COMPRESSED_SIGNED_RG11_EAC; - case NVRenderTextureFormats::RGB8_ETC2: - return GL_COMPRESSED_RGB8_ETC2; - case NVRenderTextureFormats::SRGB8_ETC2: - return GL_COMPRESSED_SRGB8_ETC2; - case NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2: - return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; - case NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2: - return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; - case NVRenderTextureFormats::RGBA8_ETC2_EAC: - return GL_COMPRESSED_RGBA8_ETC2_EAC; - case NVRenderTextureFormats::SRGB8_Alpha8_ETC2_EAC: - return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; - case NVRenderTextureFormats::RGB8_ETC1: - return GL_ETC1_RGB8_OES; -#ifdef GL_KHR_texture_compression_astc_hdr - case NVRenderTextureFormats::RGBA_ASTC_4x4: - return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; - case NVRenderTextureFormats::RGBA_ASTC_5x4: - return GL_COMPRESSED_RGBA_ASTC_5x4_KHR; - case NVRenderTextureFormats::RGBA_ASTC_5x5: - return GL_COMPRESSED_RGBA_ASTC_5x5_KHR; - case NVRenderTextureFormats::RGBA_ASTC_6x5: - return GL_COMPRESSED_RGBA_ASTC_6x5_KHR; - case NVRenderTextureFormats::RGBA_ASTC_6x6: - return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; - case NVRenderTextureFormats::RGBA_ASTC_8x5: - return GL_COMPRESSED_RGBA_ASTC_8x5_KHR; - case NVRenderTextureFormats::RGBA_ASTC_8x6: - return GL_COMPRESSED_RGBA_ASTC_8x6_KHR; - case NVRenderTextureFormats::RGBA_ASTC_8x8: - return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; - case NVRenderTextureFormats::RGBA_ASTC_10x5: - return GL_COMPRESSED_RGBA_ASTC_10x5_KHR; - case NVRenderTextureFormats::RGBA_ASTC_10x6: - return GL_COMPRESSED_RGBA_ASTC_10x6_KHR; - case NVRenderTextureFormats::RGBA_ASTC_10x8: - return GL_COMPRESSED_RGBA_ASTC_10x8_KHR; - case NVRenderTextureFormats::RGBA_ASTC_10x10: - return GL_COMPRESSED_RGBA_ASTC_10x10_KHR; - case NVRenderTextureFormats::RGBA_ASTC_12x10: - return GL_COMPRESSED_RGBA_ASTC_12x10_KHR; - case NVRenderTextureFormats::RGBA_ASTC_12x12: - return GL_COMPRESSED_RGBA_ASTC_12x12_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_4x4: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x4: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x5: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x5: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x6: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x5: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x6: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x8: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x5: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x6: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x8: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x10: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x10: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; - case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x12: - return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; -#endif // GL_KHR_texture_compression_astc_hdr - default: - break; - } - - QT3DS_ASSERT(false); - return 0; - } - - static bool fromDepthTextureFormatToGL(NVRenderContextType type, - NVRenderTextureFormats::Enum value, - GLenum &outFormat, GLenum &outDataType, - GLenum &outInternalFormat) - { - NVRenderContextType theContextFlags(NVRenderContextValues::GLES2 - | NVRenderContextValues::GL2); - - bool supportDepth24 = !(type & theContextFlags); - bool supportDepth32f = !(type & theContextFlags); - bool supportDepth24Stencil8 = !(type & theContextFlags); - - switch (value) { - case NVRenderTextureFormats::Depth16: - outFormat = GL_DEPTH_COMPONENT; - outInternalFormat = GL_DEPTH_COMPONENT16; - outDataType = GL_UNSIGNED_SHORT; - return true; - case NVRenderTextureFormats::Depth24: - outFormat = GL_DEPTH_COMPONENT; - outInternalFormat = (supportDepth24) ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16; - outDataType = (supportDepth24) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; - return true; - case NVRenderTextureFormats::Depth32: - outFormat = GL_DEPTH_COMPONENT; - outInternalFormat = - (supportDepth32f) ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT16; - outDataType = (supportDepth32f) ? GL_FLOAT : GL_UNSIGNED_SHORT; - return true; - case NVRenderTextureFormats::Depth24Stencil8: - outFormat = (supportDepth24Stencil8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; - outInternalFormat = - (supportDepth24Stencil8) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16; - outDataType = (supportDepth24Stencil8) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_SHORT; - return true; - default: - break; - } - - QT3DS_ASSERT(false); - return false; - } - - static GLenum fromTextureTargetToGL(NVRenderTextureTargetType::Enum value) - { - GLenum retval = 0; - if (value == NVRenderTextureTargetType::Texture2D) - retval = GL_TEXTURE_2D; - else if (value == NVRenderTextureTargetType::Texture2D_MS) - retval = GL_TEXTURE_2D_MULTISAMPLE; - else if (value == NVRenderTextureTargetType::Texture2D_Array) - retval = GL_TEXTURE_2D_ARRAY; - else if (value == NVRenderTextureTargetType::TextureCube) - retval = GL_TEXTURE_CUBE_MAP; - else if (value == NVRenderTextureTargetType::TextureCubeNegX) - retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; - else if (value == NVRenderTextureTargetType::TextureCubePosX) - retval = GL_TEXTURE_CUBE_MAP_POSITIVE_X; - else if (value == NVRenderTextureTargetType::TextureCubeNegY) - retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; - else if (value == NVRenderTextureTargetType::TextureCubePosY) - retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; - else if (value == NVRenderTextureTargetType::TextureCubeNegZ) - retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; - else if (value == NVRenderTextureTargetType::TextureCubePosZ) - retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; - else - QT3DS_ASSERT(false); - - return retval; - } - - static NVRenderTextureTargetType::Enum fromGLToTextureTarget(GLenum value) - { - NVRenderTextureTargetType::Enum retval = NVRenderTextureTargetType::Unknown; - - if (value == GL_TEXTURE_2D) - retval = NVRenderTextureTargetType::Texture2D; - else if (value == GL_TEXTURE_2D_MULTISAMPLE) - retval = NVRenderTextureTargetType::Texture2D_MS; - else - QT3DS_ASSERT(false); - - return retval; - } - - static GLenum fromTextureUnitToGL(NVRenderTextureUnit::Enum value) - { - QT3DSU32 v = value; - GLenum retval = GL_TEXTURE0; - retval = GL_TEXTURE0 + v; - - return retval; - } - - static GLenum fromGLToTextureUnit(GLenum value) - { - QT3DS_ASSERT(value > GL_TEXTURE0); - - QT3DSU32 v = value - GL_TEXTURE0; - NVRenderTextureUnit::Enum retval = - NVRenderTextureUnit::Enum(NVRenderTextureUnit::TextureUnit_0 + v); - - return retval; - } - - static GLenum fromTextureMinifyingOpToGL(NVRenderTextureMinifyingOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ - case NVRenderTextureMinifyingOp::y: \ - return x; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ - case NVRenderTextureMinifyingOp::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderTextureMinifyingOp::Enum fromGLToTextureMinifyingOp(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ - case x: \ - return NVRenderTextureMinifyingOp::y; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ - case x: \ - return NVRenderTextureMinifyingOp::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderTextureMinifyingOp::Unknown; - } - - static GLenum fromTextureMagnifyingOpToGL(NVRenderTextureMagnifyingOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ - case NVRenderTextureMagnifyingOp::y: \ - return x; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) - QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderTextureMagnifyingOp::Enum fromGLToTextureMagnifyingOp(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ - case x: \ - return NVRenderTextureMagnifyingOp::y; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) - QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderTextureMagnifyingOp::Unknown; - } - - static GLenum fromTextureCoordOpToGL(NVRenderTextureCoordOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ - case NVRenderTextureCoordOp::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderTextureCoordOp::Enum fromGLToTextureCoordOp(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ - case x: \ - return NVRenderTextureCoordOp::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderTextureCoordOp::Unknown; - } - - static GLenum fromTextureCompareModeToGL(NVRenderTextureCompareMode::Enum value) - { - switch (value) { - case NVRenderTextureCompareMode::NoCompare: - return GL_NONE; - case NVRenderTextureCompareMode::CompareToRef: - return GL_COMPARE_REF_TO_TEXTURE; - default: - break; - } - - QT3DS_ASSERT(false); - return NVRenderTextureCompareMode::Unknown; - } - - static GLenum fromGLToTextureCompareMode(GLenum value) - { - switch (value) { - case GL_NONE: - return NVRenderTextureCompareMode::NoCompare; - case GL_COMPARE_REF_TO_TEXTURE: - return NVRenderTextureCompareMode::CompareToRef; - default: - break; - } - - QT3DS_ASSERT(false); - return GL_INVALID_ENUM; - } - - static GLenum fromTextureCompareFuncToGL(NVRenderTextureCompareOp::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ - case NVRenderTextureCompareOp::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static GLenum fromImageFormatToGL(NVRenderTextureFormats::Enum value) - { - switch (value) { - case NVRenderTextureFormats::R8: - return GL_R8; - case NVRenderTextureFormats::R32I: - return GL_R32I; - case NVRenderTextureFormats::R32UI: - return GL_R32UI; - case NVRenderTextureFormats::R32F: - return GL_R32F; - case NVRenderTextureFormats::RGBA8: - return GL_RGBA8; - case NVRenderTextureFormats::SRGB8A8: - return GL_RGBA8_SNORM; - case NVRenderTextureFormats::RG16F: - return GL_RG16F; - case NVRenderTextureFormats::RGBA16F: - return GL_RGBA16F; - case NVRenderTextureFormats::RGBA32F: - return GL_RGBA32F; - default: - break; - } - - QT3DS_ASSERT(false); - return GL_INVALID_ENUM; - } - - - static GLenum fromImageAccessToGL(NVRenderImageAccessType::Enum value) - { - switch (value) { - case NVRenderImageAccessType::Read: - return GL_READ_ONLY; - case NVRenderImageAccessType::Write: - return GL_WRITE_ONLY; - case NVRenderImageAccessType::ReadWrite: - return GL_READ_WRITE; - default: - break; - } - QT3DS_ASSERT(false); - return GL_INVALID_ENUM; - } - - static GLbitfield fromBufferAccessBitToGL(NVRenderBufferAccessFlags flags) - { - QT3DSU32 value = flags; - GLbitfield retval = 0; - - if (value & NVRenderBufferAccessTypeValues::Read) - retval |= GL_MAP_READ_BIT; - if (value & NVRenderBufferAccessTypeValues::Write) - retval |= GL_MAP_WRITE_BIT; - if (value & NVRenderBufferAccessTypeValues::Invalid) - retval |= GL_MAP_INVALIDATE_BUFFER_BIT; - if (value & NVRenderBufferAccessTypeValues::InvalidRange) - retval |= GL_MAP_INVALIDATE_RANGE_BIT; - - QT3DS_ASSERT(retval); - return retval; - } - - static GLbitfield fromMemoryBarrierFlagsToGL(NVRenderBufferBarrierFlags flags) - { - QT3DSU32 value = flags; - GLbitfield retval = 0; -#if !defined(QT_OPENGL_ES) - if (value & NVRenderBufferBarrierValues::AtomicCounter) - retval |= GL_ATOMIC_COUNTER_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::BufferUpdate) - retval |= GL_BUFFER_UPDATE_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::CommandBuffer) - retval |= GL_COMMAND_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::ElementArray) - retval |= GL_ELEMENT_ARRAY_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::Framebuffer) - retval |= GL_FRAMEBUFFER_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::PixelBuffer) - retval |= GL_PIXEL_BUFFER_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::ShaderImageAccess) - retval |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::ShaderStorage) - retval |= GL_SHADER_STORAGE_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::TextureFetch) - retval |= GL_TEXTURE_FETCH_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::TextureUpdate) - retval |= GL_TEXTURE_UPDATE_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::TransformFeedback) - retval |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::UniformBuffer) - retval |= GL_UNIFORM_BARRIER_BIT; - if (value & NVRenderBufferBarrierValues::VertexAttribArray) - retval |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; -#endif - QT3DS_ASSERT(retval); - return retval; - } - - static GLbitfield fromShaderTypeFlagsToGL(NVRenderShaderTypeFlags flags) - { - QT3DSU32 value = flags; - GLbitfield retval = 0; - if (value & NVRenderShaderTypeValue::Vertex) - retval |= GL_VERTEX_SHADER_BIT; - if (value & NVRenderShaderTypeValue::Fragment) - retval |= GL_FRAGMENT_SHADER_BIT; - if (value & NVRenderShaderTypeValue::TessControl) - retval |= GL_TESS_CONTROL_SHADER_BIT; - if (value & NVRenderShaderTypeValue::TessEvaluation) - retval |= GL_TESS_EVALUATION_SHADER_BIT; - if (value & NVRenderShaderTypeValue::Geometry) -#if defined(QT_OPENGL_ES_3_1) - retval |= GL_GEOMETRY_SHADER_BIT_EXT; -#else - retval |= GL_GEOMETRY_SHADER_BIT; -#endif - QT3DS_ASSERT(retval || !value); - return retval; - } - - static GLenum fromPropertyDataTypesToShaderGL(NVRenderShaderDataTypes::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ - case NVRenderShaderDataTypes::nv: \ - return gl; - QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderShaderDataTypes::Enum fromShaderGLToPropertyDataTypes(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ - case gl: \ - return NVRenderShaderDataTypes::nv; - QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES - case GL_SAMPLER_2D_SHADOW: - return NVRenderShaderDataTypes::NVRenderTexture2DPtr; -#if !defined(QT_OPENGL_ES) - case GL_UNSIGNED_INT_ATOMIC_COUNTER: - return NVRenderShaderDataTypes::QT3DSU32; - case GL_UNSIGNED_INT_IMAGE_2D: - return NVRenderShaderDataTypes::NVRenderImage2DPtr; -#endif - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderShaderDataTypes::Unknown; - } - - static GLenum fromComponentTypeAndNumCompsToAttribGL(NVRenderComponentTypes::Enum compType, - QT3DSU32 numComps) - { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ - if (compType == NVRenderComponentTypes::ct && numComps == nc) \ - return gl; - QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES - QT3DS_ASSERT(false); - return 0; - } - - static void fromAttribGLToComponentTypeAndNumComps( - GLenum enumVal, NVRenderComponentTypes::Enum &outCompType, QT3DSU32 &outNumComps) - { - switch (enumVal) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ - case gl: \ - outCompType = NVRenderComponentTypes::ct; \ - outNumComps = nc; \ - return; - QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES - default: - break; - } - QT3DS_ASSERT(false); - outCompType = NVRenderComponentTypes::Unknown; - outNumComps = 0; - } - - static GLenum - fromRenderBufferFormatsToRenderBufferGL(NVRenderRenderBufferFormats::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ - case NVRenderRenderBufferFormats::nv: \ - return gl; - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderRenderBufferFormats::Enum - fromRenderBufferGLToRenderBufferFormats(GLenum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ - case gl: \ - return NVRenderRenderBufferFormats::nv; - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS - QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderRenderBufferFormats::Unknown; - } - - static GLenum fromFramebufferAttachmentsToGL(NVRenderFrameBufferAttachments::Enum value) - { - switch (value) { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ - case NVRenderFrameBufferAttachments::x: \ - return GL_COLOR_ATTACHMENT0 + idx; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ - case NVRenderFrameBufferAttachments::y: \ - return x; - QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS - QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderFrameBufferAttachments::Unknown; - } - - static NVRenderFrameBufferAttachments::Enum fromGLToFramebufferAttachments(GLenum value) - { -#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ - if (value == GL_COLOR_ATTACHMENT0 + idx) \ - return NVRenderFrameBufferAttachments::x; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ - if (value == x) \ - return NVRenderFrameBufferAttachments::y; - QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS - QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT - QT3DS_ASSERT(false); - return NVRenderFrameBufferAttachments::Unknown; - } - - static GLbitfield fromClearFlagsToGL(NVRenderClearFlags flags) - { - QT3DSU32 value = flags; - GLbitfield retval = 0; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ - if ((value & NVRenderClearValues::nv)) \ - retval |= gl; - QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS - QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS - return retval; - } - - static NVRenderClearFlags fromGLToClearFlags(GLbitfield value) - { - QT3DSU32 retval = 0; -#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ - if ((value & gl)) \ - retval |= NVRenderClearValues::nv; - QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS - QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS -#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS - return NVRenderClearFlags(retval); - } - - static GLenum fromDrawModeToGL(NVRenderDrawMode::Enum value, bool inTesselationSupported) - { - switch (value) { - case NVRenderDrawMode::Points: - return GL_POINTS; - case NVRenderDrawMode::Lines: - return GL_LINES; - case NVRenderDrawMode::LineStrip: - return GL_LINE_STRIP; - case NVRenderDrawMode::LineLoop: - return GL_LINE_LOOP; - case NVRenderDrawMode::TriangleStrip: - return GL_TRIANGLE_STRIP; - case NVRenderDrawMode::TriangleFan: - return GL_TRIANGLE_FAN; - case NVRenderDrawMode::Triangles: - return GL_TRIANGLES; - case NVRenderDrawMode::Patches: - return (inTesselationSupported) ? GL_PATCHES : GL_TRIANGLES; - default: - break; - } - - QT3DS_ASSERT(false); - return GL_INVALID_ENUM; - } - - static NVRenderDrawMode::Enum fromGLToDrawMode(GLenum value) - { - switch (value) { - case GL_POINTS: - return NVRenderDrawMode::Points; - case GL_LINES: - return NVRenderDrawMode::Lines; - case GL_LINE_STRIP: - return NVRenderDrawMode::LineStrip; - case GL_LINE_LOOP: - return NVRenderDrawMode::LineLoop; - case GL_TRIANGLE_STRIP: - return NVRenderDrawMode::TriangleStrip; - case GL_TRIANGLE_FAN: - return NVRenderDrawMode::TriangleFan; - case GL_TRIANGLES: - return NVRenderDrawMode::Triangles; - case GL_PATCHES: - return NVRenderDrawMode::Patches; - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderDrawMode::Unknown; - } - - static GLenum fromRenderStateToGL(NVRenderState::Enum value) - { - switch (value) { - case NVRenderState::Blend: - return GL_BLEND; - case NVRenderState::CullFace: - return GL_CULL_FACE; - case NVRenderState::DepthTest: - return GL_DEPTH_TEST; - case NVRenderState::Multisample: -#if defined(QT_OPENGL_ES) - return GL_MULTISAMPLE_EXT; -#else - return GL_MULTISAMPLE; -#endif - case NVRenderState::StencilTest: - return GL_STENCIL_TEST; - case NVRenderState::ScissorTest: - return GL_SCISSOR_TEST; - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - static NVRenderState::Enum fromGLToRenderState(GLenum value) - { - switch (value) { - case GL_BLEND: - return NVRenderState::Blend; - case GL_CULL_FACE: - return NVRenderState::CullFace; - case GL_DEPTH_TEST: - return NVRenderState::DepthTest; -#if defined(QT_OPENGL_ES) - case GL_MULTISAMPLE_EXT: -#else - case GL_MULTISAMPLE: -#endif - return NVRenderState::Multisample; - case GL_STENCIL_TEST: - return NVRenderState::StencilTest; - case GL_SCISSOR_TEST: - return NVRenderState::ScissorTest; - default: - break; - } - QT3DS_ASSERT(false); - return NVRenderState::Unknown; - } - - static bool fromReadPixelsToGlFormatAndType(NVRenderReadPixelFormats::Enum inReadPixels, - GLuint *outFormat, GLuint *outType) - { - switch (inReadPixels) { - case NVRenderReadPixelFormats::Alpha8: - *outFormat = GL_ALPHA; - *outType = GL_UNSIGNED_BYTE; - break; - case NVRenderReadPixelFormats::RGB565: - *outFormat = GL_RGB; - *outType = GL_UNSIGNED_SHORT_5_6_5; - case NVRenderReadPixelFormats::RGB8: - *outFormat = GL_RGB; - *outType = GL_UNSIGNED_BYTE; - break; - case NVRenderReadPixelFormats::RGBA4444: - *outFormat = GL_RGBA; - *outType = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case NVRenderReadPixelFormats::RGBA5551: - *outFormat = GL_RGBA; - *outType = GL_UNSIGNED_SHORT_5_5_5_1; - break; - case NVRenderReadPixelFormats::RGBA8: - *outFormat = GL_RGBA; - *outType = GL_UNSIGNED_BYTE; - break; - default: - *outFormat = 0; - *outType = 0; - QT3DS_ASSERT(false); - return false; - }; - - return true; - } - - static GLenum fromPathFillModeToGL(NVRenderPathFillMode::Enum inMode) - { - GLenum glFillMode; - - switch (inMode) { -#if !defined(QT_OPENGL_ES) - case NVRenderPathFillMode::Fill: - glFillMode = GL_PATH_FILL_MODE_NV; - break; - case NVRenderPathFillMode::CountUp: - glFillMode = GL_COUNT_UP_NV; - break; - case NVRenderPathFillMode::CountDown: - glFillMode = GL_COUNT_DOWN_NV; - break; - case NVRenderPathFillMode::Invert: - glFillMode = GL_INVERT; - break; -#endif - default: - QT3DS_ASSERT(false); - break; - } - - return glFillMode; - } - - static GLenum fromPathFontTargetToGL(NVRenderPathFontTarget::Enum inFontTarget) - { - GLenum glFontTarget; - - switch (inFontTarget) { -#if !defined(QT_OPENGL_ES) - case NVRenderPathFontTarget::StandardFont: - glFontTarget = GL_STANDARD_FONT_NAME_NV; - break; - case NVRenderPathFontTarget::SystemFont: - glFontTarget = GL_SYSTEM_FONT_NAME_NV; - break; - case NVRenderPathFontTarget::FileFont: - glFontTarget = GL_FILE_NAME_NV; - break; -#endif - default: - QT3DS_ASSERT(false); - break; - } - - return glFontTarget; - } - - static NVRenderPathReturnValues::Enum fromGLToPathFontReturn(GLenum inReturnValue) - { - NVRenderPathReturnValues::Enum returnValue; - - switch (inReturnValue) { -#if !defined(QT_OPENGL_ES) - case GL_FONT_GLYPHS_AVAILABLE_NV: - returnValue = NVRenderPathReturnValues::FontGlypsAvailable; - break; - case GL_FONT_TARGET_UNAVAILABLE_NV: - returnValue = NVRenderPathReturnValues::FontTargetUnavailable; - break; - case GL_FONT_UNAVAILABLE_NV: - returnValue = NVRenderPathReturnValues::FontUnavailable; - break; - case GL_FONT_UNINTELLIGIBLE_NV: - returnValue = NVRenderPathReturnValues::FontUnintelligible; - break; -#endif - case GL_INVALID_ENUM: - case GL_INVALID_VALUE: - returnValue = NVRenderPathReturnValues::InvalidEnum; - break; - case GL_OUT_OF_MEMORY: - returnValue = NVRenderPathReturnValues::OutOfMemory; - break; - default: - QT3DS_ASSERT(false); - returnValue = NVRenderPathReturnValues::FontTargetUnavailable; - break; - } - - return returnValue; - } - - static GLenum fromPathMissingGlyphsToGL(NVRenderPathMissingGlyphs::Enum inHandleGlyphs) - { - GLenum glMissingGlyphs; - - switch (inHandleGlyphs) { -#if !defined(QT_OPENGL_ES) - case NVRenderPathMissingGlyphs::SkipMissing: - glMissingGlyphs = GL_SKIP_MISSING_GLYPH_NV; - break; - case NVRenderPathMissingGlyphs::UseMissing: - glMissingGlyphs = GL_USE_MISSING_GLYPH_NV; - break; -#endif - default: - QT3DS_ASSERT(false); - break; - } - - return glMissingGlyphs; - } - - static GLenum fromPathListModeToGL(NVRenderPathListMode::Enum inListMode) - { - GLenum glListMode; - - switch (inListMode) { -#if !defined(QT_OPENGL_ES) - case NVRenderPathListMode::AccumAdjacentPairs: - glListMode = GL_ACCUM_ADJACENT_PAIRS_NV; - break; - case NVRenderPathListMode::AdjacentPairs: - glListMode = GL_ADJACENT_PAIRS_NV; - break; - case NVRenderPathListMode::FirstToRest: - glListMode = GL_FIRST_TO_REST_NV; - break; -#endif - default: - QT3DS_ASSERT(false); - break; - } - - return glListMode; - } - - static GLenum fromPathCoverModeToGL(NVRenderPathCoverMode::Enum inMode) - { - GLenum glCoverMode; - - switch (inMode) { -#if !defined(QT_OPENGL_ES) - case NVRenderPathCoverMode::ConvexHull: - glCoverMode = GL_CONVEX_HULL_NV; - break; - case NVRenderPathCoverMode::BoundingBox: - glCoverMode = GL_BOUNDING_BOX_NV; - break; - case NVRenderPathCoverMode::BoundingBoxOfBoundingBox: - glCoverMode = GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV; - break; - case NVRenderPathCoverMode::PathFillCover: - glCoverMode = GL_PATH_FILL_COVER_MODE_NV; - break; - case NVRenderPathCoverMode::PathStrokeCover: - glCoverMode = GL_PATH_STROKE_COVER_MODE_NV; - break; -#endif - default: - QT3DS_ASSERT(false); - break; - } - - return glCoverMode; - } - - static GLenum fromPathTypeToGL(NVRenderPathFormatType::Enum value) - { - switch (value) { - case NVRenderPathFormatType::Byte: - return GL_BYTE; - case NVRenderPathFormatType::UByte: - return GL_UNSIGNED_BYTE; - case NVRenderPathFormatType::Short: - return GL_SHORT; - case NVRenderPathFormatType::UShort: - return GL_UNSIGNED_SHORT; - case NVRenderPathFormatType::Int: - return GL_INT; - case NVRenderPathFormatType::Uint: - return GL_UNSIGNED_INT; -#if !defined(QT_OPENGL_ES) - case NVRenderPathFormatType::Bytes2: - return GL_2_BYTES_NV; - case NVRenderPathFormatType::Bytes3: - return GL_3_BYTES_NV; - case NVRenderPathFormatType::Bytes4: - return GL_4_BYTES_NV; - case NVRenderPathFormatType::Utf8: - return GL_UTF8_NV; - case NVRenderPathFormatType::Utf16: - return GL_UTF16_NV; -#endif - default: - break; - } - QT3DS_ASSERT(false); - return GL_UNSIGNED_BYTE; - } - - static GLbitfield fromPathFontStyleToGL(NVRenderPathFontStyleFlags flags) - { - QT3DSU32 value = flags; - GLbitfield retval = 0; -#if !defined(QT_OPENGL_ES) - if (value & NVRenderPathFontStyleValues::Bold) - retval |= GL_BOLD_BIT_NV; - if (value & NVRenderPathFontStyleValues::Italic) - retval |= GL_ITALIC_BIT_NV; -#endif - QT3DS_ASSERT(retval || !value); - return retval; - } - - static GLenum fromPathTransformToGL(NVRenderPathTransformType::Enum value) - { - switch (value) { - case NVRenderPathTransformType::NoTransform: - return GL_NONE; -#if !defined(QT_OPENGL_ES) - case NVRenderPathTransformType::TranslateX: - return GL_TRANSLATE_X_NV; - case NVRenderPathTransformType::TranslateY: - return GL_TRANSLATE_Y_NV; - case NVRenderPathTransformType::Translate2D: - return GL_TRANSLATE_2D_NV; - case NVRenderPathTransformType::Translate3D: - return GL_TRANSLATE_3D_NV; - case NVRenderPathTransformType::Affine2D: - return GL_AFFINE_2D_NV; - case NVRenderPathTransformType::Affine3D: - return GL_AFFINE_3D_NV; - case NVRenderPathTransformType::TransposeAffine2D: - return GL_TRANSPOSE_AFFINE_2D_NV; - case NVRenderPathTransformType::TransposeAffine3D: - return GL_TRANSPOSE_AFFINE_3D_NV; -#endif - default: - break; - } - QT3DS_ASSERT(false); - return GL_UNSIGNED_BYTE; - } - - static GLbitfield fromPathMetricQueryFlagsToGL(NVRenderPathGlyphFontMetricFlags flags) - { - QT3DSU32 value = flags; - GLbitfield retval = 0; -#if !defined(QT_OPENGL_ES) - if (value & NVRenderPathGlyphFontMetricValues::GlyphWidth) - retval |= GL_GLYPH_WIDTH_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphHeight) - retval |= GL_GLYPH_HEIGHT_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingX) - retval |= GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingY) - retval |= GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingAdvance) - retval |= GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingX) - retval |= GL_GLYPH_VERTICAL_BEARING_X_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingY) - retval |= GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingAdvance) - retval |= GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::GlyphHasKerning) - retval |= GL_GLYPH_HAS_KERNING_BIT_NV; - - if (value & NVRenderPathGlyphFontMetricValues::FontXMinBounds) - retval |= GL_FONT_X_MIN_BOUNDS_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontYMinBounds) - retval |= GL_FONT_Y_MIN_BOUNDS_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontXMaxBounds) - retval |= GL_FONT_X_MAX_BOUNDS_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontYMaxBounds) - retval |= GL_FONT_Y_MAX_BOUNDS_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontUnitsPerEm) - retval |= GL_FONT_UNITS_PER_EM_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontAscender) - retval |= GL_FONT_ASCENDER_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontDescender) - retval |= GL_FONT_DESCENDER_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontHeight) - retval |= GL_FONT_HEIGHT_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) - retval |= GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceHeight) - retval |= GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontUnderlinePosition) - retval |= GL_FONT_UNDERLINE_POSITION_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) - retval |= GL_FONT_UNDERLINE_THICKNESS_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontHasKerning) - retval |= GL_FONT_HAS_KERNING_BIT_NV; - if (value & NVRenderPathGlyphFontMetricValues::FontNumGlyphIndices) - retval |= GL_FONT_NUM_GLYPH_INDICES_BIT_NV; -#endif - QT3DS_ASSERT(retval || !value); - return retval; - } - }; -} -} - -#endif // QT3DSOPENGLUTIL_H diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h deleted file mode 100644 index 7147b341..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_GL3_H -#define QT3DS_RENDER_BACKEND_GL3_H - -/// @file Qt3DSRenderBackendGL3.h -/// NVRender OpenGL 3 backend definition. - -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" -#include "render/backends/gl/Qt3DSOpenGLExtensions.h" - -#include -#include - -namespace qt3ds { -namespace render { - - ///< forward declaration - class NVRenderBackendMiscStateGL; - - using namespace foundation; - - class NVRenderBackendGL3Impl : public NVRenderBackendGLBase - { - public: - /// constructor - NVRenderBackendGL3Impl(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format); - /// destructor - virtual ~NVRenderBackendGL3Impl(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - public: - QT3DSU32 GetDepthBits() const override; - QT3DSU32 GetStencilBits() const override; - void GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum genType) override; - - void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - size_t samples, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, - bool fixedsamplelocations) override; - - void SetTextureData3D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, size_t depth, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) override; - - void UpdateSampler( - NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; - - void UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, - QT3DSI32 maxLevel) override; - - void UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) override; - - bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, - NVRenderBackendShaderProgramObject po) override; - - void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, - NVConstDataRef inDrawBufferSet) override; - void SetReadBuffer(NVRenderBackendRenderTargetObject rto, - NVReadFaces::Enum inReadFace) override; - - void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; - void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; - - void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) override; - - void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, - size_t offset, size_t length, - NVRenderBufferAccessFlags accessFlags) override; - bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; - - QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; - void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSI32 *indices) override; - void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) override; - void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) override; - void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - NVRenderBackendQueryObject CreateQuery() override; - void ReleaseQuery(NVRenderBackendQueryObject qo) override; - void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; - void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; - void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; - void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; - void SetQueryTimer(NVRenderBackendQueryObject qo) override; - - NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, - NVRenderSyncFlags syncFlags) override; - void ReleaseSync(NVRenderBackendSyncObject so) override; - void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, - QT3DSU64 timeout) override; - - protected: - NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state -#if defined(QT_OPENGL_ES_2) - Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; -#else - QOpenGLExtension_ARB_timer_query *m_timerExtension; - QOpenGLExtension_ARB_tessellation_shader *m_tessellationShader; - QOpenGLExtension_ARB_texture_multisample *m_multiSample; - Qt3DSOpenGLExtensions *m_qt3dsExtensions; -#endif - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL4.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL4.h deleted file mode 100644 index bfdc03b7..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL4.h +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_GL4_H -#define QT3DS_RENDER_BACKEND_GL4_H - -/// @file Qt3DSRenderBackendGL4.h -/// NVRender OpenGL 4 backend definition. - -#include "foundation/Qt3DSAtomic.h" -#include "render/backends/gl/Qt3DSRenderBackendGL3.h" - -namespace qt3ds { -namespace render { - - using namespace foundation; - - class NVRenderBackendGL4Impl : public NVRenderBackendGL3Impl - { - public: - /// constructor - NVRenderBackendGL4Impl(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format); - /// destructor - virtual ~NVRenderBackendGL4Impl(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - public: - void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; - void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, - NVRenderComponentTypes::Enum type, const void *indirect) override; - - void CreateTextureStorage2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 levels, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height) override; - - void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - size_t samples, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, - bool fixedsamplelocations) override; - - void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count, const void *value, - bool transpose) override; - - void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) override; - virtual NVRenderBackendTessControlShaderObject - CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) override; - virtual NVRenderBackendTessEvaluationShaderObject - CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) override; - virtual NVRenderBackendGeometryShaderObject - CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; - - QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; - void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) override; - void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; - void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, - bool layered, QT3DSI32 layer, - NVRenderImageAccessType::Enum access, - NVRenderTextureFormats::Enum format) override; - - virtual NVRenderBackendComputeShaderObject - CreateComputeShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; - void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, - QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; - - NVRenderBackendProgramPipeline CreateProgramPipeline() override; - void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) override; - void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) override; - void SetProgramStages(NVRenderBackendProgramPipeline ppo, - NVRenderShaderTypeFlags flags, - NVRenderBackendShaderProgramObject po) override; - - void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; - void SetBlendBarrier(void) override; - - NVRenderBackendPathObject CreatePathNVObject(size_t range) override; - void SetPathSpecification(NVRenderBackendPathObject inPathObject, - NVConstDataRef inPathCommands, - NVConstDataRef inPathCoords) override; - NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) override; - NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) override; - NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) override; - void SetStrokeWidth(NVRenderBackendPathObject inPathObject, QT3DSF32 inStrokeWidth) override; - - void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; - void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; - void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; - void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) override; - void StencilStrokePath(NVRenderBackendPathObject inPathObject) override; - void StencilFillPath(NVRenderBackendPathObject inPathObject) override; - void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; - - void StencilFillPathInstanced( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, - const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, - NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) override; - void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathFormatType::Enum type, - const void *charCodes, QT3DSI32 stencilRef, - QT3DSU32 stencilMask, - NVRenderPathTransformType::Enum transformType, - const QT3DSF32 *transformValues) override; - void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathFormatType::Enum type, - const void *charCodes, - NVRenderPathCoverMode::Enum coverMode, - NVRenderPathTransformType::Enum transformType, - const QT3DSF32 *transformValues) override; - void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathFormatType::Enum type, - const void *charCodes, - NVRenderPathCoverMode::Enum coverMode, - NVRenderPathTransformType::Enum transformType, - const QT3DSF32 *transformValues) override; - void LoadPathGlyphs(NVRenderBackendPathObject po, - NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, - NVRenderPathFormatType::Enum type, const void *charCodes, - NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; - virtual NVRenderPathReturnValues::Enum - LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, - const void *fontName, NVRenderPathFontStyleFlags fontStyle, - QT3DSU32 firstGlyphIndex, size_t numGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; - virtual NVRenderBackendPathObject - LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, - QT3DSU32 *count) override; - void LoadPathGlyphRange(NVRenderBackendPathObject po, - NVRenderPathFontTarget::Enum fontTarget, - const void *fontName, NVRenderPathFontStyleFlags fontStyle, - QT3DSU32 firstGlyph, size_t numGlyphs, - NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, - NVRenderBackendPathObject pathParameterTemplate, - QT3DSF32 emScale) override; - void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathGlyphFontMetricFlags metricQueryMask, - NVRenderPathFormatType::Enum type, const void *charCodes, - size_t stride, QT3DSF32 *metrics) override; - void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathGlyphFontMetricFlags metricQueryMask, - size_t stride, QT3DSF32 *metrics) override; - void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathListMode::Enum pathListMode, - NVRenderPathFormatType::Enum type, const void *charCodes, - QT3DSF32 advanceScale, QT3DSF32 kerningScale, - NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) override; - private: -#if !defined(QT_OPENGL_ES) - QOpenGLExtension_NV_path_rendering *m_nvPathRendering; - QOpenGLExtension_EXT_direct_state_access *m_directStateAccess; -#endif - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h deleted file mode 100644 index 9048a9c4..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h +++ /dev/null @@ -1,530 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_GL_BASE_H -#define QT3DS_RENDER_BACKEND_GL_BASE_H - -/// @file Qt3DSRenderBackendGLBase.h -/// NVRender OpenGL Core backend definition. - -#include "foundation/Qt3DSContainers.h" -#include "foundation/StringTable.h" -#include "render/backends/Qt3DSRenderBackend.h" -#include "render/backends/gl/Qt3DSOpenGLUtil.h" -#include - -#include -#include -#include - -#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; - -// Enable this to log opengl errors instead of an assert -//#define RENDER_BACKEND_LOG_GL_ERRORS - -namespace qt3ds { -namespace render { - - ///< forward declaration - class NVRenderBackendRasterizerStateGL; - class NVRenderBackendDepthStencilStateGL; - - using namespace foundation; - - typedef eastl::basic_string TContextStr; - - class NVRenderBackendGLBase : public NVRenderBackend - { - public: - /// constructor - NVRenderBackendGLBase(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format); - /// destructor - virtual ~NVRenderBackendGLBase(); - - public: - /// API Interface - NVRenderContextType GetRenderContextType() const override; - bool isESCompatible() const; - - const char *GetShadingLanguageVersion() override; - /// get implementation depended values - QT3DSU32 GetMaxCombinedTextureUnits() override; - bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const override; - QT3DSU32 GetDepthBits() const override; - QT3DSU32 GetStencilBits() const override; - void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override; - - /// state get/set functions - void SetRenderState(bool bEnable, const NVRenderState::Enum value) override; - bool GetRenderState(const NVRenderState::Enum value) override; - virtual NVRenderBackendDepthStencilStateObject - CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, - bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) override; - virtual void - ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; - virtual NVRenderBackendRasterizerStateObject - CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) override; - void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; - virtual void - SetDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; - void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; - NVRenderBoolOp::Enum GetDepthFunc() override; - void SetDepthFunc(const NVRenderBoolOp::Enum func) override; - bool GetDepthWrite() override; - void SetDepthWrite(bool bEnable) override; - void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) override; - void SetMultisample(bool bEnable) override; - void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) override; - void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) override; - void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; - void SetBlendBarrier(void) override; - void GetScissorRect(NVRenderRect *pRect) override; - void SetScissorRect(const NVRenderRect &rect) override; - void GetViewportRect(NVRenderRect *pRect) override; - void SetViewportRect(const NVRenderRect &rect) override; - - void SetClearColor(const QT3DSVec4 *pClearColor) override; - void Clear(NVRenderClearFlags flags) override; - - /// resource handling - NVRenderBackendBufferObject CreateBuffer(size_t size, - NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usage, - const void *hostPtr = NULL) override; - void BindBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; - void ReleaseBuffer(NVRenderBackendBufferObject bo) override; - void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, - size_t size, NVRenderBufferUsageType::Enum usage, - const void *data) override; - void UpdateBufferRange(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags, size_t offset, - size_t size, const void *data) override; - void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, - size_t offset, size_t length, - NVRenderBufferAccessFlags accessFlags) override; - bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; - void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; - - NVRenderBackendQueryObject CreateQuery() override; - void ReleaseQuery(NVRenderBackendQueryObject qo) override; - void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; - void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; - void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; - void GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; - void SetQueryTimer(NVRenderBackendQueryObject qo) override; - - NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, - NVRenderSyncFlags syncFlags) override; - void ReleaseSync(NVRenderBackendSyncObject so) override; - void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, - QT3DSU64 timeout) override; - - NVRenderBackendRenderTargetObject CreateRenderTarget() override; - void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; - void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendRenderbufferObject rbo) override; - void RenderTargetAttach( - NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) override; - void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; - void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; - bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; - - virtual NVRenderBackendRenderbufferObject - CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, - size_t height) override; - void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; - bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, - NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) override; - - NVRenderBackendTextureObject CreateTexture() override; - void BindTexture(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 unit) override; - void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, - bool layered, QT3DSI32 layer, - NVRenderImageAccessType::Enum access, - NVRenderTextureFormats::Enum format) override; - void ReleaseTexture(NVRenderBackendTextureObject to) override; - void SetTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) override; - void SetTextureDataCubeFace(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) override; - void CreateTextureStorage2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 levels, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height) override; - void SetTextureSubData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) override; - void SetCompressedTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, QT3DSI32 border, - size_t imageSize, const void *hostPtr = NULL) override; - void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, QT3DSI32 border, - size_t imageSize, const void *hostPtr = NULL) override; - void SetCompressedTextureSubData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, - size_t width, size_t height, - NVRenderTextureFormats::Enum format, - size_t imageSize, const void *hostPtr = NULL) override; - void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - size_t samples, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height, - bool fixedsamplelocations) override = 0; - - void SetTextureData3D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, - size_t height, size_t depth, QT3DSI32 border, - NVRenderTextureFormats::Enum format, - const void *hostPtr = NULL) override; - - void GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum genType) override; - - virtual NVRenderTextureSwizzleMode::Enum - GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const override; - - NVRenderBackendSamplerObject CreateSampler( - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; - - void UpdateSampler( - NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, - NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, - NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, - NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, - QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, - NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, - NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, - QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; - - void UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, - QT3DSI32 maxLevel) override; - - void UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) override; - - void ReleaseSampler(NVRenderBackendSamplerObject so) override; - - virtual NVRenderBackendAttribLayoutObject - CreateAttribLayout(NVConstDataRef attribs) override; - void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) override; - - virtual NVRenderBackendInputAssemblerObject - CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, - NVConstDataRef buffers, - const NVRenderBackendBufferObject indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets, - QT3DSU32 patchVertexCount) override; - void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override; - - bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, - NVRenderBackendShaderProgramObject po) override = 0; - void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override - { - QT3DS_ASSERT(false); - } - - // shader - virtual NVRenderBackendVertexShaderObject - CreateVertexShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; - virtual NVRenderBackendFragmentShaderObject - CreateFragmentShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; - virtual NVRenderBackendTessControlShaderObject - CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) override; - virtual NVRenderBackendTessEvaluationShaderObject - CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, - bool binary) override; - virtual NVRenderBackendGeometryShaderObject - CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; - virtual NVRenderBackendComputeShaderObject - CreateComputeShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; - void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) override; - void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) override; - void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) override; - void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) override; - void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) override; - void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) override; - void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendVertexShaderObject vso) override; - void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendFragmentShaderObject fso) override; - void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessControlShaderObject tcso) override; - void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessEvaluationShaderObject teso) override; - void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendGeometryShaderObject gso) override; - void AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendComputeShaderObject cso) override; - void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendVertexShaderObject vso) override; - void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendFragmentShaderObject fso) override; - void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessControlShaderObject tcso) override; - void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessEvaluationShaderObject teso) override; - void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendGeometryShaderObject gso) override; - void DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendComputeShaderObject cso) override; - NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) override; - void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) override; - bool LinkProgram(NVRenderBackendShaderProgramObject po, - eastl::string &errorMessage) override; - void SetActiveProgram(NVRenderBackendShaderProgramObject po) override; - void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, - QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; - NVRenderBackendProgramPipeline CreateProgramPipeline() override; - void ReleaseProgramPipeline(NVRenderBackendProgramPipeline po) override; - void SetActiveProgramPipeline(NVRenderBackendProgramPipeline po) override; - void SetProgramStages(NVRenderBackendProgramPipeline ppo, - NVRenderShaderTypeFlags flags, - NVRenderBackendShaderProgramObject po) override; - - // uniforms - QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 bufSize, QT3DSI32 *numElem, - NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, - char *nameBuf) override; - void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count, - const void *value, bool transpose) override; - - // uniform buffers - QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; - void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSI32 *indices) override; - void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) override; - void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) override; - void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - // storage buffers - QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; - void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - // atomic counter buffers - QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; - QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) override; - void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; - - /// draw calls - void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) override; - void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; - void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, - NVRenderComponentTypes::Enum type, const void *indices) override; - void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, - NVRenderComponentTypes::Enum type, const void *indirect) override; - - // read calls - void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, - QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, void *pixels) override; - - // NV path rendering - NVRenderBackendPathObject CreatePathNVObject(size_t range) override; - // Pathing requires gl4 backend. - void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef, - NVConstDataRef) override - { - } - - ///< Bounds of the fill and stroke - NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override - { - return NVBounds3(); - } - NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override - { - return NVBounds3(); - } - NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override - { - return NVBounds3(); - } - - /** - * Defaults to 0 if unset. - */ - void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} - void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} - void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} - void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} - void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} - void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} - void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} - void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; - - void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, - const void *, NVRenderPathFontStyleFlags, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, - QT3DSF32) override; - virtual NVRenderPathReturnValues::Enum - LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, - const void *fontName, NVRenderPathFontStyleFlags fontStyle, - QT3DSU32 firstGlyphIndex, size_t numGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; - virtual NVRenderBackendPathObject - LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, const void *, - NVRenderPathFontStyleFlags, - NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) override; - void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, - const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, - NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, - QT3DSF32) override; - void GetPathMetrics(NVRenderBackendPathObject, size_t, - NVRenderPathGlyphFontMetricFlags, NVRenderPathFormatType::Enum, - const void *, size_t, QT3DSF32 *) override; - void GetPathMetricsRange(NVRenderBackendPathObject, size_t, - NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override; - void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, - NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, - NVRenderPathTransformType::Enum, QT3DSF32 *) override; - - void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathFillMode::Enum, QT3DSU32, - NVRenderPathTransformType::Enum, const QT3DSF32 *) override; - void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, QT3DSI32, - QT3DSU32, NVRenderPathTransformType::Enum, - const QT3DSF32 *) override; - void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathCoverMode::Enum, - NVRenderPathTransformType::Enum, const QT3DSF32 *) override; - void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathCoverMode::Enum, - NVRenderPathTransformType::Enum, const QT3DSF32 *) override; - - QSurfaceFormat format() const override - { - return m_format; - } - - protected: - virtual NVFoundationBase &GetFoundation() { return m_Foundation; } - virtual bool compileSource(GLuint shaderID, NVConstDataRef source, - eastl::string &errorMessage, bool binary); - virtual const char *getVersionString(); - virtual const char *getVendorString(); - virtual const char *getRendererString(); - virtual const char *getExtensionString(); - - virtual void setAndInspectHardwareCaps(); - - protected: - volatile QT3DSI32 mRefCount; ///< reference count - NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things - NVScopedRefCounted - m_StringTable; ///< pointer to a string table - GLConversion m_Conversion; ///< Class for conversion from base type to GL types - QStringList m_extensions; ///< contains the OpenGL extension string - QT3DSI32 m_MaxAttribCount; ///< Maximum attributes which can be used - nvvector m_DrawBuffersArray; ///< Contains the drawbuffer enums - QSurfaceFormat m_format; - - NVRenderBackendRasterizerStateGL - *m_pCurrentRasterizerState; ///< this holds the current rasterizer state - NVRenderBackendDepthStencilStateGL - *m_pCurrentDepthStencilState; ///< this holds the current depth stencil state - -#ifdef RENDER_BACKEND_LOG_GL_ERRORS - void checkGLError(const char *function, const char *file, const unsigned int line) const; -#else - void checkGLError() const; -#endif - QOpenGLFunctions *m_glFunctions; - QOpenGLExtraFunctions *m_glExtraFunctions; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h deleted file mode 100644 index e14111af..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H -#define QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/StringTable.h" -#include "foundation/Utils.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - - struct NVRenderBackendLayoutEntryGL - { - CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader - QT3DSU8 m_Normalize; ///< normalize parameter - QT3DSU32 m_AttribIndex; ///< attribute index - QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT - QT3DSU32 m_NumComponents; ///< component count. max 4 - QT3DSU32 m_InputSlot; ///< Input slot where to fetch the data from - QT3DSU32 m_Offset; ///< offset in byte - }; - - ///< this class handles the vertex attribute layout setup - class NVRenderBackendAttributeLayoutGL - { - public: - ///< constructor - NVRenderBackendAttributeLayoutGL(NVDataRef entries, - QT3DSU32 maxInputSlot) - : m_LayoutAttribEntries(entries) - , m_MaxInputSlot(maxInputSlot) - { - } - ///< destructor - ~NVRenderBackendAttributeLayoutGL(){} - - NVRenderBackendLayoutEntryGL *getEntryByName(CRegisteredString entryName) const - { - QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) - { - if (m_LayoutAttribEntries[idx].m_AttribName == entryName) - return &m_LayoutAttribEntries.mData[idx]; - } - return NULL; - } - - Option getEntryByAttribIndex(QT3DSU32 attribIndex) const - { - QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) - { - if (m_LayoutAttribEntries[idx].m_AttribIndex == attribIndex) - return m_LayoutAttribEntries[idx]; - } - return Empty(); - } - - NVDataRef - m_LayoutAttribEntries; ///< vertex attribute layout entries - QT3DSU32 m_MaxInputSlot; ///< max used input slot - }; - - ///< this class handles the input assembler setup - class NVRenderBackendInputAssemblerGL - { - public: - ///< constructor - NVRenderBackendInputAssemblerGL( - NVFoundationBase &fnd, NVRenderBackendAttributeLayoutGL *attribLayout, - NVConstDataRef buffers, - const NVRenderBackend::NVRenderBackendBufferObject indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets, QT3DSU32 patchVertexCount) - : m_Foundation(fnd) - , m_attribLayout(attribLayout) - , m_VertexbufferHandles(buffers) - , m_IndexbufferHandle(indexBuffer) - , m_VaoID(0) - , m_cachedShaderHandle(0) - , m_PatchVertexCount(patchVertexCount) - { - QT3DSU32 *strideMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), - "BackendAttributeLayoutGL:m_strides"); - QT3DSU32 *offsetMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), - "BackendAttributeLayoutGL:m_strides"); - // copy offsets and strides - QT3DS_FOREACH(idx, strides.size()) - { - strideMem[idx] = strides.mData[idx]; - offsetMem[idx] = offsets.mData[idx]; - } - - m_strides = toDataRef(strideMem, strides.size()); - m_offsets = toDataRef(offsetMem, offsets.size()); - } - ///< destructor - ~NVRenderBackendInputAssemblerGL() - { - QT3DS_FREE(m_Foundation.getAllocator(), m_strides.mData); - QT3DS_FREE(m_Foundation.getAllocator(), m_offsets.mData); - }; - - NVFoundationBase &m_Foundation; ///< pointer to foundation - NVRenderBackendAttributeLayoutGL *m_attribLayout; ///< pointer to attribute layout - NVConstDataRef - m_VertexbufferHandles; ///< opaque vertex buffer backend handles - NVRenderBackend::NVRenderBackendBufferObject - m_IndexbufferHandle; ///< opaque index buffer backend handles - QT3DSU32 m_VaoID; ///< this is only used if GL version is greater or equal 3 - QT3DSU32 m_cachedShaderHandle; ///< this is the shader id which was last used with this object - QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive - NVDataRef m_strides; ///< buffer strides - NVDataRef m_offsets; ///< buffer offsets - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h deleted file mode 100644 index 3a74a8e3..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H -#define QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Utils.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - - ///< this class handles the shader input variables - class NVRenderBackendDepthStencilStateGL - { - public: - ///< constructor - NVRenderBackendDepthStencilStateGL(bool enableDepth, bool depthMask, - NVRenderBoolOp::Enum depthFunc, bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) - : m_DepthEnable(enableDepth) - , m_DepthMask(depthMask) - , m_DepthFunc(depthFunc) - , m_StencilEnable(enableStencil) - , m_StencilFuncFront(stencilFuncFront) - , m_StencilFuncBack(stencilFuncBack) - , m_DepthStencilOpFront(depthStencilOpFront) - , m_DepthStencilOpBack(depthStencilOpBack) - { - } - - ///< constructor - NVRenderBackendDepthStencilStateGL() - : m_DepthEnable(true) - , m_DepthMask(true) - , m_DepthFunc(NVRenderBoolOp::LessThanOrEqual) - , m_StencilEnable(false) - { - } - - ///< destructor - ~NVRenderBackendDepthStencilStateGL(){} - - ///< assignement - NVRenderBackendDepthStencilStateGL &operator=(const NVRenderBackendDepthStencilStateGL &rhs) - { - // Check for self-assignment! - if (this == &rhs) - return *this; - - m_DepthEnable = rhs.m_DepthEnable; - m_DepthMask = rhs.m_DepthMask; - m_DepthFunc = rhs.m_DepthFunc; - m_StencilEnable = rhs.m_StencilEnable; - m_StencilFuncFront = rhs.m_StencilFuncFront; - m_StencilFuncBack = rhs.m_StencilFuncBack; - m_DepthStencilOpFront = rhs.m_DepthStencilOpFront; - m_DepthStencilOpBack = rhs.m_DepthStencilOpBack; - - return *this; - } - - bool operator==(const NVRenderBackendDepthStencilStateGL &other) const - { - return (m_DepthEnable == other.m_DepthEnable && m_DepthMask == other.m_DepthMask - && m_DepthFunc == other.m_DepthFunc && m_StencilEnable == other.m_StencilEnable - && m_StencilFuncFront == other.m_StencilFuncFront - && m_StencilFuncBack == other.m_StencilFuncBack - && m_DepthStencilOpFront == other.m_DepthStencilOpFront - && m_DepthStencilOpBack == other.m_DepthStencilOpBack); - } - - bool m_DepthEnable; ///< depth test enabled - bool m_DepthMask; ///< enable / disable depth writes - NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func - bool m_StencilEnable; ///< enable disable stencil test - NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup for front faces - NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup for back faces - NVRenderStencilOperationArgument - m_DepthStencilOpFront; ///< depth stencil operation for front faces - NVRenderStencilOperationArgument - m_DepthStencilOpBack; ///< depth stencil operation for back faces - }; - - class NVRenderBackendMiscStateGL - { - public: - ///< constructor - NVRenderBackendMiscStateGL() - : m_PatchVertexCount(1) - { - } - - QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive - }; - - class NVRenderBackendRasterizerStateGL - { - public: - ///< constructor - NVRenderBackendRasterizerStateGL(QT3DSF32 depthBias, QT3DSF32 depthScale, - NVRenderFaces::Enum cullFace) - : m_DepthBias(depthBias) - , m_DepthScale(depthScale) - , m_CullFace(cullFace) - { - } - ///< constructor - NVRenderBackendRasterizerStateGL() - : m_DepthBias(0.0) - , m_DepthScale(0.0) - , m_CullFace(NVRenderFaces::Back) - { - } - - NVRenderBackendRasterizerStateGL &operator=(const NVRenderBackendRasterizerStateGL &rhs) - { - // Check for self-assignment! - if (this == &rhs) - return *this; - - m_DepthBias = rhs.m_DepthBias; - m_DepthScale = rhs.m_DepthScale; - m_CullFace = rhs.m_CullFace; - - return *this; - } - - bool operator==(const NVRenderBackendRasterizerStateGL &other) const - { - return (m_DepthBias == other.m_DepthBias && m_DepthScale == other.m_DepthScale - && m_CullFace == other.m_CullFace); - } - - QT3DSF32 m_DepthBias; ///< depth bias - QT3DSF32 m_DepthScale; ///< mulitply constant - NVRenderFaces::Enum m_CullFace; ///< cull face front or back - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h deleted file mode 100644 index f7caffd8..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H -#define QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Utils.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - - struct NVRenderBackendShaderInputEntryGL - { - CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader - QT3DSU32 m_AttribLocation; ///< attribute index - QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT - QT3DSU32 m_NumComponents; ///< component count. max 4 - }; - - ///< this class handles the shader input variables - class NVRenderBackendShaderInputGL - { - public: - ///< constructor - NVRenderBackendShaderInputGL(NVDataRef entries) - : m_ShaderInputEntries(entries) - { - } - ///< destructor - ~NVRenderBackendShaderInputGL(){} - - NVRenderBackendShaderInputEntryGL *getEntryByName(CRegisteredString entryName) const - { - QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) - { - if (m_ShaderInputEntries[idx].m_AttribName == entryName) - return &m_ShaderInputEntries.mData[idx]; - } - return NULL; - } - - Option - getEntryByAttribLocation(QT3DSU32 attribLocation) const - { - QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) - { - if (m_ShaderInputEntries[idx].m_AttribLocation == attribLocation) - return m_ShaderInputEntries[idx]; - } - return Empty(); - } - - NVDataRef m_ShaderInputEntries; ///< shader input entries - }; - - ///< this class represents the internals of a GL program - class NVRenderBackendShaderProgramGL - { - public: - ///< constructor - NVRenderBackendShaderProgramGL(QT3DSU32 programID) - : m_ProgramID(programID) - , m_shaderInput(NULL) - { - } - - ///< destructor - ~NVRenderBackendShaderProgramGL(){} - - QT3DSU32 m_ProgramID; ///< this is the OpenGL object ID - NVRenderBackendShaderInputGL *m_shaderInput; ///< pointer to shader input object - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h deleted file mode 100644 index 397ecfb1..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BACKEND_NULL_H -#define QT3DS_RENDER_BACKEND_NULL_H -#include "render/backends/Qt3DSRenderBackend.h" - -namespace qt3ds { -namespace render { - - class NVRenderBackendNULL : public NVRenderBackend - { - public: - static NVRenderBackend &CreateBackend(NVFoundationBase &foundation); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/glg/Qt3DSGLImplObjects.h b/src/Runtime/Source/Qt3DSRender/Include/render/glg/Qt3DSGLImplObjects.h deleted file mode 100644 index 28f246fd..00000000 --- a/src/Runtime/Source/Qt3DSRender/Include/render/glg/Qt3DSGLImplObjects.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_GL_IMPL_OBJECTS_H -#define QT3DS_RENDER_GL_IMPL_OBJECTS_H -#include "render/backends/gl/Qt3DSOpenGLUtil.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSContainers.h" - -namespace qt3ds { -namespace render { - - // The set of all properties as they are currently set in hardware. - struct SNVGLHardPropertyContext - { - NVRenderFrameBuffer *m_FrameBuffer; - NVRenderShaderProgram *m_ActiveShader; - NVRenderProgramPipeline *m_ActiveProgramPipeline; - NVRenderInputAssembler *m_InputAssembler; - NVRenderBlendFunctionArgument m_BlendFunction; - NVRenderBlendEquationArgument m_BlendEquation; - bool m_CullingEnabled; - NVRenderBoolOp::Enum m_DepthFunction; - bool m_BlendingEnabled; - bool m_DepthWriteEnabled; - bool m_DepthTestEnabled; - bool m_StencilTestEnabled; - bool m_ScissorTestEnabled; - bool m_ColorWritesEnabled; - bool m_MultisampleEnabled; - NVRenderRect m_ScissorRect; - NVRenderRect m_Viewport; - QT3DSVec4 m_ClearColor; - - SNVGLHardPropertyContext() - : m_FrameBuffer(NULL) - , m_ActiveShader(NULL) - , m_ActiveProgramPipeline(NULL) - , m_InputAssembler(NULL) - , m_CullingEnabled(true) - , m_DepthFunction(NVRenderBoolOp::Less) - , m_BlendingEnabled(true) - , m_DepthWriteEnabled(true) - , m_DepthTestEnabled(true) - , m_StencilTestEnabled(false) - , m_ScissorTestEnabled(true) - , m_ColorWritesEnabled(true) - , m_MultisampleEnabled(false) - , m_ClearColor(0, 0, 0, 1) - { - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAtomicCounterBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAtomicCounterBuffer.cpp deleted file mode 100644 index 272c3e8c..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAtomicCounterBuffer.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderAtomicCounterBuffer.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" - -namespace qt3ds { -namespace render { - - ///< struct handling a constant buffer entry - class AtomicCounterBufferEntry - { - public: - CRegisteredString m_Name; ///< parameter Name - QT3DSI32 m_Offset; ///< offset into the memory buffer - - AtomicCounterBufferEntry(CRegisteredString name, QT3DSI32 offset) - : m_Name(name) - , m_Offset(offset) - { - } - }; - - NVRenderAtomicCounterBuffer::NVRenderAtomicCounterBuffer( - NVRenderContextImpl &context, CRegisteredString bufferName, size_t size, - NVRenderBufferUsageType::Enum usageType, NVDataRef data) - : NVRenderDataBuffer(context, context.GetFoundation(), size, - NVRenderBufferBindValues::Storage, usageType, data) - , m_Name(bufferName) - , m_AtomicCounterBufferEntryMap( - m_Foundation.getAllocator(), - "NVRenderAtomicCounterBuffer::m_AtomicCounterBufferEntryMap") - , m_Dirty(true) - { - QT3DS_ASSERT(context.IsStorageBufferSupported()); - } - - NVRenderAtomicCounterBuffer::~NVRenderAtomicCounterBuffer() - { - for (TRenderAtomiCounterBufferEntryMap::iterator - iter = m_AtomicCounterBufferEntryMap.begin(), - end = m_AtomicCounterBufferEntryMap.end(); - iter != end; ++iter) { - NVDelete(m_Foundation.getAllocator(), iter->second); - } - - m_AtomicCounterBufferEntryMap.clear(); - - m_Context.BufferDestroyed(*this); - } - - void NVRenderAtomicCounterBuffer::Bind() - { - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); - QT3DS_ASSERT(false); - } - - m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); - } - - void NVRenderAtomicCounterBuffer::BindToShaderProgram(QT3DSU32 index) - { - m_Backend->ProgramSetAtomicCounterBuffer(index, m_BufferHandle); - } - - void NVRenderAtomicCounterBuffer::Update() - { - // we only update the buffer if it is dirty and we actually have some data - if (m_Dirty && m_BufferData.size()) { - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, - m_BufferData.begin()); - m_Dirty = false; - } - } - - void NVRenderAtomicCounterBuffer::UpdateData(QT3DSI32 offset, NVDataRef data) - { - // we only update the buffer if we something - if (data.size()) - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, - data.begin() + offset); - } - - void NVRenderAtomicCounterBuffer::AddParam(CRegisteredString name, QT3DSU32 offset) - { - if (m_AtomicCounterBufferEntryMap.find(name) == m_AtomicCounterBufferEntryMap.end()) { - AtomicCounterBufferEntry *newEntry = - QT3DS_NEW(m_Foundation.getAllocator(), AtomicCounterBufferEntry)(name, offset); - - if (newEntry) - m_AtomicCounterBufferEntryMap.insert(eastl::make_pair(name, newEntry)); - } else { - // no duplicated entries - return; - } - } - - bool NVRenderAtomicCounterBuffer::ContainsParam(CRegisteredString name) - { - if (m_AtomicCounterBufferEntryMap.find(name) != m_AtomicCounterBufferEntryMap.end()) - return true; - else - return false; - } - - NVRenderAtomicCounterBuffer * - NVRenderAtomicCounterBuffer::Create(NVRenderContextImpl &context, const char *bufferName, - NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) - { - NVFoundationBase &fnd(context.GetFoundation()); - NVRenderAtomicCounterBuffer *retval = NULL; - - if (context.IsAtomicCounterBufferSupported()) { - CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); - QT3DSU32 bufSize = sizeof(NVRenderAtomicCounterBuffer); - QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "AtomicCounterBuffer"); - retval = new (newMem) NVRenderAtomicCounterBuffer( - context, theBufferName, size, usageType, - toDataRef(const_cast(bufferData.begin()), bufferData.size())); - } else { - QT3DS_ASSERT(false); - } - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAttribLayout.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAttribLayout.cpp deleted file mode 100644 index 42641a04..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderAttribLayout.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderAttribLayout.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - ///< constructor - NVRenderAttribLayout::NVRenderAttribLayout(NVRenderContextImpl &context, - NVConstDataRef attribs) - : m_Context(context) - , m_Foundation(context.GetFoundation()) - , mRefCount(0) - , m_Backend(context.GetBackend()) - { - m_AttribLayoutHandle = m_Backend->CreateAttribLayout(attribs); - QT3DS_ASSERT(m_AttribLayoutHandle); - } - - ///< destructor - NVRenderAttribLayout::~NVRenderAttribLayout() - { - if (m_AttribLayoutHandle) { - m_Backend->ReleaseAttribLayout(m_AttribLayoutHandle); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderComputeShader.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderComputeShader.cpp deleted file mode 100644 index 01aef473..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderComputeShader.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderComputeShader.h" - -namespace qt3ds { -namespace render { - - NVRenderComputeShader::NVRenderComputeShader(NVRenderContextImpl &context, - NVFoundationBase &fnd, NVConstDataRef source, - bool binaryProgram) - : NVRenderShader(context, fnd, source, binaryProgram) - , m_ShaderHandle(NULL) - { - m_ShaderHandle = m_Backend->CreateComputeShader(source, m_ErrorMessage, binaryProgram); - } - - NVRenderComputeShader::~NVRenderComputeShader() - { - if (m_ShaderHandle) { - m_Backend->ReleaseComputeShader(m_ShaderHandle); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp deleted file mode 100644 index 1b3c43a9..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderConstantBuffer.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" - -namespace qt3ds { -namespace render { - - ///< struct handling a constant buffer entry - class ConstantBufferParamEntry - { - public: - CRegisteredString m_Name; ///< parameter Name - NVRenderShaderDataTypes::Enum m_Type; ///< parameter type - QT3DSI32 m_Count; ///< one or array size - QT3DSI32 m_Offset; ///< offset into the memory buffer - - ConstantBufferParamEntry(CRegisteredString name, NVRenderShaderDataTypes::Enum type, - QT3DSI32 count, QT3DSI32 offset) - : m_Name(name) - , m_Type(type) - , m_Count(count) - , m_Offset(offset) - { - } - }; - - NVRenderConstantBuffer::NVRenderConstantBuffer(NVRenderContextImpl &context, - CRegisteredString bufferName, size_t size, - NVRenderBufferUsageType::Enum usageType, - NVDataRef data) - : NVRenderDataBuffer(context, context.GetFoundation(), size, - NVRenderBufferBindValues::Constant, usageType, NVDataRef()) - , m_Name(bufferName) - , m_ConstantBufferEntryMap(m_Foundation.getAllocator(), - "NVRenderConstantBuffer::m_ConstantBufferEntryMap") - , m_CurrentOffset(0) - , m_CurrentSize(0) - , m_HWBufferInitialized(false) - , m_Dirty(true) - , m_RangeStart(0) - , m_RangeEnd(0) - , m_MaxBlockSize(0) - { - QT3DS_ASSERT(context.GetConstantBufferSupport()); - - m_Backend->GetRenderBackendValue( - NVRenderBackend::NVRenderBackendQuery::MaxConstantBufferBlockSize, &m_MaxBlockSize); - - if (size && data.size() && size == data.size()) { - QT3DS_ASSERT(size < (QT3DSU32)m_MaxBlockSize); - if (allocateShadowBuffer(data.size())) { - memcpy(m_ShadowCopy.begin(), data.begin(), data.size()); - } - } - } - - NVRenderConstantBuffer::~NVRenderConstantBuffer() - { - // check if we should release memory - if (m_ShadowCopy.size()) { - m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin()); - } - - m_ShadowCopy = NVDataRef(); - - for (TRenderConstantBufferEntryMap::iterator iter = m_ConstantBufferEntryMap.begin(), - end = m_ConstantBufferEntryMap.end(); - iter != end; ++iter) { - NVDelete(m_Foundation.getAllocator(), iter->second); - } - - m_ConstantBufferEntryMap.clear(); - - m_Context.BufferDestroyed(*this); - } - - void NVRenderConstantBuffer::Bind() - { - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); - QT3DS_ASSERT(false); - } - - m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); - } - - void NVRenderConstantBuffer::BindToShaderProgram(NVRenderShaderProgram *inShader, - QT3DSU32 blockIndex, QT3DSU32 binding) - { - if ((QT3DSI32)binding == -1) { - binding = m_Context.GetNextConstantBufferUnit(); - m_Backend->ProgramSetConstantBlock(inShader->GetShaderProgramHandle(), blockIndex, - binding); - } - - m_Backend->ProgramSetConstantBuffer(binding, m_BufferHandle); - } - - bool NVRenderConstantBuffer::SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, - QT3DSI32 bufSize, QT3DSI32 paramCount) - { - bool bSuccess = false; - - if (!m_HWBufferInitialized) { - // allocate shadow buffer - QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate( - bufSize, "NVRenderConstantBuffer", __FILE__, __LINE__); - if (!newMem) - return false; - - // allocate temp buffers to hold constant buffer information - QT3DSI32 *theIndices = NULL, *theTypes = NULL, *theSizes = NULL, *theOffsets = NULL; - theIndices = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), - "NVRenderConstantBuffer"); - if (!theIndices) - goto fail; - theTypes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), - "NVRenderConstantBuffer"); - if (!theTypes) - goto fail; - theSizes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), - "NVRenderConstantBuffer"); - if (!theSizes) - goto fail; - theOffsets = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), - "NVRenderConstantBuffer"); - if (!theOffsets) - goto fail; - - bSuccess = true; - - // get indices for the individal constant buffer entries - m_Backend->GetConstantBufferParamIndices(pProgram->GetShaderProgramHandle(), index, - theIndices); - - // get constant buffer uniform information - m_Backend->GetConstantBufferParamInfoByIndices(pProgram->GetShaderProgramHandle(), - paramCount, (QT3DSU32 *)theIndices, - theTypes, theSizes, theOffsets); - - // get the names of the uniforms - char nameBuf[512]; - QT3DSI32 elementCount, binding; - NVRenderShaderDataTypes::Enum type; - - QT3DS_FOREACH(idx, paramCount) - { - m_Backend->GetConstantInfoByID(pProgram->GetShaderProgramHandle(), theIndices[idx], - 512, &elementCount, &type, &binding, nameBuf); - // check if we already have this entry - CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); - TRenderConstantBufferEntryMap::iterator entry = - m_ConstantBufferEntryMap.find(theName); - if (entry != m_ConstantBufferEntryMap.end()) { - ConstantBufferParamEntry *pParam = entry->second; - // copy content - if (m_ShadowCopy.size()) - memcpy(newMem + theOffsets[idx], - m_ShadowCopy.begin() + entry->second->m_Offset, - entry->second->m_Count * getUniformTypeSize(pParam->m_Type)); - - pParam->m_Offset = theOffsets[idx]; - QT3DS_ASSERT(type == pParam->m_Type); - QT3DS_ASSERT(elementCount == pParam->m_Count); - } else { - // create one - m_ConstantBufferEntryMap.insert(eastl::make_pair( - theName, - createParamEntry(theName, (NVRenderShaderDataTypes::Enum)theTypes[idx], - theSizes[idx], theOffsets[idx]))); - } - } - - // release previous one - if (m_ShadowCopy.size()) { - m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin()); - } - // set new one - m_ShadowCopy = NVDataRef(newMem, bufSize); - - m_HWBufferInitialized = true; - - fail: - if (theIndices) - QT3DS_FREE(m_Foundation.getAllocator(), theIndices); - if (theTypes) - QT3DS_FREE(m_Foundation.getAllocator(), theTypes); - if (theSizes) - QT3DS_FREE(m_Foundation.getAllocator(), theSizes); - if (theOffsets) - QT3DS_FREE(m_Foundation.getAllocator(), theOffsets); - - } else { - // some sanity checks - bSuccess = true; - bSuccess &= (m_ShadowCopy.size() <= (QT3DSU32)bufSize); - } - - return bSuccess; - } - - void NVRenderConstantBuffer::Update() - { - // we only update the buffer if the buffer is already on hardware - // and if it is dirty - if (m_Dirty && m_HWBufferInitialized) { - if (m_RangeEnd == 0) - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_ShadowCopy.size(), - m_UsageType, m_ShadowCopy.begin()); - else - UpdateRange(); - - m_Dirty = false; - m_RangeStart = m_RangeEnd = 0; - } - } - - void NVRenderConstantBuffer::UpdateRange() - { - if ((m_RangeStart + m_RangeEnd) > m_ShadowCopy.size()) { - QT3DS_ASSERT(false); - return; - } - - m_Backend->UpdateBufferRange(m_BufferHandle, m_BindFlags, m_RangeStart, - m_RangeEnd - m_RangeStart, - m_ShadowCopy.begin() + m_RangeStart); - } - - void NVRenderConstantBuffer::AddParam(CRegisteredString name, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count) - { - if (m_ConstantBufferEntryMap.find(name) == m_ConstantBufferEntryMap.end()) { - ConstantBufferParamEntry *newEntry = - QT3DS_NEW(m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, - m_CurrentOffset); - - if (newEntry) - m_ConstantBufferEntryMap.insert(eastl::make_pair(name, newEntry)); - } else { - // no duplicated entries - return; - } - - // compute new current buffer size and offset - QT3DSI32 constantSize = getUniformTypeSize(type) * count; - m_CurrentSize += constantSize; - m_CurrentOffset += constantSize; - } - - void NVRenderConstantBuffer::UpdateParam(const char *inName, NVDataRef value) - { - // allocate space if not done yet - // NOTE this gets reallocated once we get the real constant buffer size from a program - if (!m_ShadowCopy.size()) { - // allocate shadow buffer - if (!allocateShadowBuffer(m_CurrentSize)) - return; - } - - CRegisteredString theName(m_Context.GetStringTable().RegisterStr(inName)); - TRenderConstantBufferEntryMap::iterator entry = m_ConstantBufferEntryMap.find(theName); - if (entry != m_ConstantBufferEntryMap.end()) { - if (!memcmp(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(), - entry->second->m_Count * getUniformTypeSize(entry->second->m_Type))) { - return; - } - memcpy(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(), - entry->second->m_Count * getUniformTypeSize(entry->second->m_Type)); - m_Dirty = true; - } - } - - void NVRenderConstantBuffer::UpdateRaw(QT3DSI32 offset, NVDataRef data) - { - // allocate space if yet done - if (!m_ShadowCopy.size()) { - // allocate shadow buffer - if (!allocateShadowBuffer(data.size())) - return; - } - - QT3DS_ASSERT((offset + data.size()) < (QT3DSU32)m_MaxBlockSize); - - // we do not initialize anything when this is used - m_HWBufferInitialized = true; - - // we do not allow resize once allocated - if ((offset + data.size()) > m_ShadowCopy.size()) - return; - - // copy data - if (!memcmp(m_ShadowCopy.begin() + offset, data.begin(), data.size())) { - return; - } - memcpy(m_ShadowCopy.begin() + offset, data.begin(), data.size()); - - // update start - m_RangeStart = (m_Dirty) ? (m_RangeStart > (QT3DSU32)offset) ? offset : m_RangeStart : offset; - m_RangeEnd = (offset + data.size() > m_RangeEnd) ? offset + data.size() : m_RangeEnd; - - m_Dirty = true; - } - - ConstantBufferParamEntry *NVRenderConstantBuffer::createParamEntry( - CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count, QT3DSI32 offset) - { - ConstantBufferParamEntry *newEntry = QT3DS_NEW( - m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, offset); - - return newEntry; - } - - QT3DSI32 - NVRenderConstantBuffer::getUniformTypeSize(NVRenderShaderDataTypes::Enum type) - { - switch (type) { - case NVRenderShaderDataTypes::QT3DSF32: - return sizeof(QT3DSF32); - case NVRenderShaderDataTypes::QT3DSI32: - return sizeof(QT3DSI32); - case NVRenderShaderDataTypes::QT3DSI32_2: - return sizeof(QT3DSI32) * 2; - case NVRenderShaderDataTypes::QT3DSI32_3: - return sizeof(QT3DSI32) * 3; - case NVRenderShaderDataTypes::QT3DSI32_4: - return sizeof(QT3DSI32) * 4; - case NVRenderShaderDataTypes::QT3DSU32: - return sizeof(QT3DSU32); - case NVRenderShaderDataTypes::QT3DSU32_2: - return sizeof(QT3DSU32) * 2; - case NVRenderShaderDataTypes::QT3DSU32_3: - return sizeof(QT3DSU32) * 3; - case NVRenderShaderDataTypes::QT3DSU32_4: - return sizeof(QT3DSU32) * 4; - case NVRenderShaderDataTypes::QT3DSVec2: - return sizeof(QT3DSF32) * 2; - case NVRenderShaderDataTypes::QT3DSVec3: - return sizeof(QT3DSF32) * 3; - case NVRenderShaderDataTypes::QT3DSVec4: - return sizeof(QT3DSF32) * 4; - case NVRenderShaderDataTypes::QT3DSMat33: - return sizeof(QT3DSF32) * 9; - case NVRenderShaderDataTypes::QT3DSMat44: - return sizeof(QT3DSF32) * 16; - default: - QT3DS_ASSERT(!"Unhandled type in NVRenderConstantBuffer::getUniformTypeSize"); - break; - } - - return 0; - } - - bool NVRenderConstantBuffer::allocateShadowBuffer(QT3DSU32 size) - { - // allocate shadow buffer - QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate(size, "NVRenderConstantBuffer", - __FILE__, __LINE__); - if (!newMem) - return false; - - m_ShadowCopy = NVDataRef(newMem, size); - - m_BufferCapacity = size; - - return true; - } - - NVRenderConstantBuffer *NVRenderConstantBuffer::Create(NVRenderContextImpl &context, - const char *bufferName, - NVRenderBufferUsageType::Enum usageType, - size_t size, - NVConstDataRef bufferData) - { - NVFoundationBase &fnd(context.GetFoundation()); - NVRenderConstantBuffer *retval = NULL; - - if (context.GetConstantBufferSupport()) { - CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); - QT3DSU32 cbufSize = sizeof(NVRenderConstantBuffer); - QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "ConstantBuffer"); - retval = new (newMem) NVRenderConstantBuffer( - context, theBufferName, size, usageType, - toDataRef(const_cast(bufferData.begin()), bufferData.size())); - } else { - QT3DS_ASSERT(false); - } - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderContext.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderContext.cpp deleted file mode 100644 index aa2cb30f..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderContext.cpp +++ /dev/null @@ -1,1107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSMat44.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Utils.h" -#include "EASTL/set.h" -#include "EASTL/utility.h" -#include "render/Qt3DSRenderShaderProgram.h" - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace eastl; - -namespace qt3ds { -namespace render { - - NVRenderContextImpl::NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, - IStringTable &inStrTable) - : m_backend(inBackend) - , m_DirtyFlags(0) - , m_DefaultOffscreenRenderTarget((NVRenderBackend::NVRenderBackendRenderTargetObject)NULL) - , m_DephBits(16) - , m_StencilBits(8) - , mRefCount(0) - , m_Foundation(fnd) - , m_StringTable(inStrTable) - , m_VertToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_VertToImpMap") - , m_IndexToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_IndexToImpMap") - , m_ConstantToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ConstantToImpMap") - , m_StorageToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_StorageToImpMap") - , m_AtomicCounterToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_AtomicCounterToImpMap") - , m_DrawIndirectToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_DrawIndirectToImpMap") - , m_DepthStencilStateToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_DepthStencilStateToImpMap") - , m_RasterizerStateToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_RasterizerStateToImpMap") - , m_PathFontSpecToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_RasterizerStateToImpMap") - , m_Tex2DToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Tex2DToImpMap") - , m_Tex2DArrayToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_Tex2DArrayToImpMap") - , m_TexCubeToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_TexCubeToImpMap") - , m_Image2DtoImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Image2DtoImpMap") - , m_ShaderToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ShaderToImpMap") - , m_RenderBufferToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_RenderBufferToImpMap") - , m_FrameBufferToImpMap(m_Foundation.getAllocator(), - "NVRenderContextImpl::m_FrameBufferToImpMap") - , m_NextTextureUnit(1) - , m_NextConstantBufferUnit(1) - , m_PropertyStack(m_Foundation.getAllocator(), "NVRenderContextImpl::m_PropertyStack") - { - - m_StringTable.addRef(); - - m_MaxTextureUnits = m_backend->GetMaxCombinedTextureUnits(); - m_MaxConstantBufferUnits = 16; // need backend query - - // get initial state - memZero(&m_HardwarePropertyContext, sizeof(m_HardwarePropertyContext)); - - // get default blending functions - m_backend->GetBlendFunc(&m_HardwarePropertyContext.m_BlendFunction); - // set default blend euqation - m_HardwarePropertyContext.m_BlendEquation.m_RGBEquation = NVRenderBlendEquation::Add; - m_HardwarePropertyContext.m_BlendEquation.m_AlphaEquation = NVRenderBlendEquation::Add; - // default state - m_HardwarePropertyContext.m_CullingEnabled = - m_backend->GetRenderState(NVRenderState::CullFace); - m_HardwarePropertyContext.m_DepthFunction = m_backend->GetDepthFunc(); - m_HardwarePropertyContext.m_BlendingEnabled = - m_backend->GetRenderState(NVRenderState::Blend); - m_HardwarePropertyContext.m_DepthWriteEnabled = m_backend->GetDepthWrite(); - m_HardwarePropertyContext.m_DepthTestEnabled = - m_backend->GetRenderState(NVRenderState::DepthTest); - m_HardwarePropertyContext.m_ScissorTestEnabled = - m_backend->GetRenderState(NVRenderState::ScissorTest); - m_backend->GetScissorRect(&m_HardwarePropertyContext.m_ScissorRect); - m_backend->GetViewportRect(&m_HardwarePropertyContext.m_Viewport); - - DoSetClearColor(m_HardwarePropertyContext.m_ClearColor); - } - - NVRenderContextImpl::~NVRenderContextImpl() - { - m_StringTable.release(); - QT3DS_ASSERT(m_VertToImpMap.size() == 0); - m_VertToImpMap.clear(); - QT3DS_ASSERT(m_IndexToImpMap.size() == 0); - m_IndexToImpMap.clear(); - QT3DS_ASSERT(m_ConstantToImpMap.size() == 0); - m_ConstantToImpMap.clear(); - QT3DS_ASSERT(m_StorageToImpMap.size() == 0); - m_StorageToImpMap.clear(); - QT3DS_ASSERT(m_DepthStencilStateToImpMap.size() == 0); - m_DepthStencilStateToImpMap.clear(); - QT3DS_ASSERT(m_RasterizerStateToImpMap.size() == 0); - m_RasterizerStateToImpMap.clear(); - QT3DS_ASSERT(m_PathFontSpecToImpMap.size() == 0); - m_PathFontSpecToImpMap.clear(); - QT3DS_ASSERT(m_Tex2DToImpMap.size() == 0); - m_Tex2DToImpMap.clear(); - QT3DS_ASSERT(m_Tex2DArrayToImpMap.size() == 0); - m_Tex2DArrayToImpMap.clear(); - QT3DS_ASSERT(m_Image2DtoImpMap.size() == 0); - m_Image2DtoImpMap.clear(); - QT3DS_ASSERT(m_ShaderToImpMap.size() == 0); - m_ShaderToImpMap.clear(); - QT3DS_ASSERT(m_RenderBufferToImpMap.size() == 0); - m_RenderBufferToImpMap.clear(); - QT3DS_ASSERT(m_FrameBufferToImpMap.size() == 0); - m_FrameBufferToImpMap.clear(); - - m_backend = NULL; - } - - void NVRenderContextImpl::getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) - { - QT3DSI32 theMaxTextureSize = 0; - m_backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, - &theMaxTextureSize); - - oWidth = (QT3DSU32)theMaxTextureSize; - oHeight = (QT3DSU32)theMaxTextureSize; - } - - NVRenderDepthStencilState *NVRenderContextImpl::CreateDepthStencilState( - bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) - { - NVRenderDepthStencilState *state = NVRenderDepthStencilState::Create( - *this, enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, - stencilFuncBack, depthStencilOpFront, depthStencilOpBack); - if (state) - m_DepthStencilStateToImpMap.insert( - make_pair(state->GetDepthStencilObjectHandle(), state)); - - return state; - } - - void NVRenderContextImpl::SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) - { - if (inDepthStencilState) { - m_backend->SetDepthStencilState(inDepthStencilState->GetDepthStencilObjectHandle()); - // currently we have a mixture therefore we need to update the context state - SetDepthFunction(inDepthStencilState->GetDepthFunc()); - SetDepthWriteEnabled(inDepthStencilState->GetDepthMask()); - SetDepthTestEnabled(inDepthStencilState->GetDepthEnabled()); - SetStencilTestEnabled(inDepthStencilState->GetStencilEnabled()); - } - } - - void NVRenderContextImpl::StateDestroyed(NVRenderDepthStencilState &state) - { - m_DepthStencilStateToImpMap.erase(state.GetDepthStencilObjectHandle()); - } - - NVRenderRasterizerState * - NVRenderContextImpl::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, - NVRenderFaces::Enum cullFace) - { - NVRenderRasterizerState *state = - NVRenderRasterizerState::Create(*this, depthBias, depthScale, cullFace); - if (state) - m_RasterizerStateToImpMap.insert(make_pair(state->GetRasterizerObjectHandle(), state)); - - return state; - } - - void NVRenderContextImpl::SetRasterizerState(NVRenderRasterizerState *inRasterizerState) - { - if (inRasterizerState) - m_backend->SetRasterizerState(inRasterizerState->GetRasterizerObjectHandle()); - } - - void NVRenderContextImpl::StateDestroyed(NVRenderRasterizerState &state) - { - m_RasterizerStateToImpMap.erase(state.GetRasterizerObjectHandle()); - } - - NVRenderVertexBuffer * - NVRenderContextImpl::CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, - QT3DSU32 stride, NVConstDataRef bufferData) - { - NVRenderVertexBuffer *buffer = - NVRenderVertexBuffer::Create(*this, usageType, size, stride, bufferData); - if (buffer) - m_VertToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); - return buffer; - } - - NVRenderVertexBuffer *NVRenderContextImpl::GetVertexBuffer(const void *implementationHandle) - { - nvhash_map::const_iterator entry = - m_VertToImpMap.find(implementationHandle); - if (entry != m_VertToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::BufferDestroyed(NVRenderVertexBuffer &buffer) - { - m_VertToImpMap.erase(buffer.GetImplementationHandle()); - } - - NVRenderIndexBuffer * - NVRenderContextImpl::CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, - qt3ds::render::NVRenderComponentTypes::Enum componentType, - size_t size, NVConstDataRef bufferData) - { - NVRenderIndexBuffer *buffer = - NVRenderIndexBuffer::Create(*this, usageType, componentType, size, bufferData); - - if (buffer) { - m_IndexToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); - } - - return buffer; - } - - NVRenderIndexBuffer *NVRenderContextImpl::GetIndexBuffer(const void *implementationHandle) - { - const nvhash_map::iterator entry = - m_IndexToImpMap.find(implementationHandle); - if (entry != m_IndexToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::BufferDestroyed(NVRenderIndexBuffer &buffer) - { - m_IndexToImpMap.erase(buffer.GetImplementationHandle()); - } - - NVRenderConstantBuffer * - NVRenderContextImpl::CreateConstantBuffer(const char *bufferName, - qt3ds::render::NVRenderBufferUsageType::Enum usageType, - size_t size, NVConstDataRef bufferData) - { - NVRenderConstantBuffer *buffer = - NVRenderConstantBuffer::Create(*this, bufferName, usageType, size, bufferData); - - if (buffer) { - m_ConstantToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); - } - - return buffer; - } - - NVRenderConstantBuffer *NVRenderContextImpl::GetConstantBuffer(CRegisteredString bufferName) - { - TContextConstantBufferMap::iterator entry = m_ConstantToImpMap.find(bufferName); - if (entry != m_ConstantToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::BufferDestroyed(NVRenderConstantBuffer &buffer) - { - m_ConstantToImpMap.erase(buffer.GetBufferName()); - } - - QT3DSU32 NVRenderContextImpl::GetNextConstantBufferUnit() - { - QT3DSU32 retval = m_NextConstantBufferUnit; - ++m_NextConstantBufferUnit; - // Too many texture units for a single draw call. - if (retval >= m_MaxConstantBufferUnits) { - QT3DS_ASSERT(false); - retval = retval % m_MaxConstantBufferUnits; - } - return retval; - } - - NVRenderStorageBuffer *NVRenderContextImpl::CreateStorageBuffer( - const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) - { - NVRenderStorageBuffer *buffer = - NVRenderStorageBuffer::Create(*this, bufferName, usageType, size, bufferData, pBuffer); - - if (buffer) { - m_StorageToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); - } - - return buffer; - } - - NVRenderStorageBuffer *NVRenderContextImpl::GetStorageBuffer(CRegisteredString bufferName) - { - TContextStorageBufferMap::iterator entry = m_StorageToImpMap.find(bufferName); - if (entry != m_StorageToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::BufferDestroyed(NVRenderStorageBuffer &buffer) - { - m_StorageToImpMap.erase(buffer.GetBufferName()); - } - - NVRenderAtomicCounterBuffer *NVRenderContextImpl::CreateAtomicCounterBuffer( - const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) - { - NVRenderAtomicCounterBuffer *buffer = - NVRenderAtomicCounterBuffer::Create(*this, bufferName, usageType, size, bufferData); - - if (buffer) { - m_AtomicCounterToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); - } - - return buffer; - } - - NVRenderAtomicCounterBuffer * - NVRenderContextImpl::GetAtomicCounterBuffer(CRegisteredString bufferName) - { - TContextAtomicCounterBufferMap::iterator entry = m_AtomicCounterToImpMap.find(bufferName); - if (entry != m_AtomicCounterToImpMap.end()) - return entry->second; - return NULL; - } - - NVRenderAtomicCounterBuffer * - NVRenderContextImpl::GetAtomicCounterBufferByParam(CRegisteredString paramName) - { - // iterate through all atomic counter buffers - for (TContextAtomicCounterBufferMap::iterator iter = m_AtomicCounterToImpMap.begin(), - end = m_AtomicCounterToImpMap.end(); - iter != end; ++iter) { - if (iter->second && iter->second->ContainsParam(paramName)) - return iter->second; - } - - return NULL; - } - - void NVRenderContextImpl::BufferDestroyed(NVRenderAtomicCounterBuffer &buffer) - { - m_AtomicCounterToImpMap.erase(buffer.GetBufferName()); - } - - NVRenderDrawIndirectBuffer *NVRenderContextImpl::CreateDrawIndirectBuffer( - qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) - { - NVRenderDrawIndirectBuffer *buffer = - NVRenderDrawIndirectBuffer::Create(*this, usageType, size, bufferData); - - if (buffer) { - m_DrawIndirectToImpMap.insert(make_pair(buffer->GetBuffertHandle(), buffer)); - } - - return buffer; - } - - NVRenderDrawIndirectBuffer *NVRenderContextImpl::GetDrawIndirectBuffer( - NVRenderBackend::NVRenderBackendBufferObject implementationHandle) - { - TContextDrawIndirectBufferMap::iterator entry = - m_DrawIndirectToImpMap.find(implementationHandle); - if (entry != m_DrawIndirectToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::BufferDestroyed(NVRenderDrawIndirectBuffer &buffer) - { - m_DrawIndirectToImpMap.erase(buffer.GetBuffertHandle()); - } - - void NVRenderContextImpl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) - { - m_backend->SetMemoryBarrier(barriers); - } - - NVRenderOcclusionQuery *NVRenderContextImpl::CreateOcclusionQuery() - { - NVRenderOcclusionQuery *theQuery = NVRenderOcclusionQuery::Create(*this); - - return theQuery; - } - - NVRenderTimerQuery *NVRenderContextImpl::CreateTimerQuery() - { - NVRenderTimerQuery *theQuery = NVRenderTimerQuery::Create(*this); - - return theQuery; - } - - NVRenderSync *NVRenderContextImpl::CreateSync() - { - NVRenderSync *theSync = NVRenderSync::Create(*this); - - return theSync; - } - - NVRenderTexture2D *NVRenderContextImpl::CreateTexture2D() - { - NVRenderTexture2D *retval = NVRenderTexture2D::Create(*this); - if (retval) - m_Tex2DToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); - return retval; - } - - NVRenderTexture2DArray *NVRenderContextImpl::CreateTexture2DArray() - { - NVRenderTexture2DArray *retval = NVRenderTexture2DArray::Create(*this); - if (retval) - m_Tex2DArrayToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); - - return retval; - } - - NVRenderTextureCube *NVRenderContextImpl::CreateTextureCube() - { - NVRenderTextureCube *retval = NVRenderTextureCube::Create(*this); - if (retval) - m_TexCubeToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); - - return retval; - } - - NVRenderTexture2D *NVRenderContextImpl::GetTexture2D(const void *implementationHandle) - { - const nvhash_map::iterator entry = - m_Tex2DToImpMap.find(implementationHandle); - if (entry != m_Tex2DToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2D &buffer) - { - m_Tex2DToImpMap.erase(buffer.GetImplementationHandle()); - // We would like to find and catch any situations where this texture is being used - // but that would require some real work that we don't want to do right now. - } - - void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2DArray &buffer) - { - m_Tex2DArrayToImpMap.erase(buffer.GetTextureObjectHandle()); - } - - void NVRenderContextImpl::TextureDestroyed(NVRenderTextureCube &buffer) - { - m_TexCubeToImpMap.erase(buffer.GetTextureObjectHandle()); - } - - NVRenderImage2D *NVRenderContextImpl::CreateImage2D(NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) - { - NVRenderImage2D *retval = NVRenderImage2D::Create(*this, inTexture, inAccess); - if (retval) - m_Image2DtoImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); - - return retval; - } - - void NVRenderContextImpl::ImageDestroyed(NVRenderImage2D &image) - { - m_Image2DtoImpMap.erase(image.GetTextureObjectHandle()); - } - - // IF this texture isn't on a texture unit, put it on one. - // If it is on a texture unit, mark it as the most recently used texture. - QT3DSU32 NVRenderContextImpl::GetNextTextureUnit() - { - QT3DSU32 retval = m_NextTextureUnit; - ++m_NextTextureUnit; - // Too many texture units for a single draw call. - if (retval >= m_MaxTextureUnits) { - QT3DS_ASSERT(false); - retval = retval % m_MaxTextureUnits; - } - return retval; - } - - NVRenderRenderBuffer * - NVRenderContextImpl::CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, - QT3DSU32 width, QT3DSU32 height) - { - NVRenderRenderBuffer *retval = - NVRenderRenderBuffer::Create(*this, bufferFormat, width, height); - if (retval != NULL) - m_RenderBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); - return retval; - } - - NVRenderRenderBuffer *NVRenderContextImpl::GetRenderBuffer(const void *implementationHandle) - { - const nvhash_map::iterator entry = - m_RenderBufferToImpMap.find(implementationHandle); - if (entry != m_RenderBufferToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::RenderBufferDestroyed(NVRenderRenderBuffer &buffer) - { - m_RenderBufferToImpMap.erase(buffer.GetImplementationHandle()); - } - - NVRenderFrameBuffer *NVRenderContextImpl::CreateFrameBuffer() - { - NVRenderFrameBuffer *retval = NVRenderFrameBuffer::Create(*this); - if (retval != NULL) - m_FrameBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); - return retval; - } - - NVRenderFrameBuffer *NVRenderContextImpl::GetFrameBuffer(const void *implementationHandle) - { - const nvhash_map::iterator entry = - m_FrameBufferToImpMap.find(implementationHandle); - if (entry != m_FrameBufferToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::FrameBufferDestroyed(NVRenderFrameBuffer &fb) - { - m_FrameBufferToImpMap.erase(fb.GetImplementationHandle()); - if (m_HardwarePropertyContext.m_FrameBuffer == &fb) - m_HardwarePropertyContext.m_FrameBuffer = NULL; - } - - NVRenderAttribLayout * - NVRenderContextImpl::CreateAttributeLayout(NVConstDataRef attribs) - { - return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderAttribLayout)(*this, attribs); - } - - NVRenderInputAssembler *NVRenderContextImpl::CreateInputAssembler( - NVRenderAttribLayout *attribLayout, NVConstDataRef buffers, - const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, - NVConstDataRef offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) - { - return QT3DS_NEW(GetFoundation().getAllocator(), - NVRenderInputAssembler)(*this, attribLayout, buffers, indexBuffer, strides, - offsets, primType, patchVertexCount); - } - - void NVRenderContextImpl::SetInputAssembler(NVRenderInputAssembler *inputAssembler) - { - if (m_HardwarePropertyContext.m_InputAssembler != inputAssembler) { - DoSetInputAssembler(inputAssembler); - } - } - - NVRenderVertFragCompilationResult NVRenderContextImpl::CompileSource( - const char *shaderName, NVConstDataRef vertShader, NVConstDataRef fragShader, - NVConstDataRef tessControlShaderSource, - NVConstDataRef tessEvaluationShaderSource, NVConstDataRef geometryShaderSource, - bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) - { - NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( - *this, shaderName, vertShader, fragShader, tessControlShaderSource, - tessEvaluationShaderSource, geometryShaderSource, separateProgram, type, binaryProgram); - - if (result.mShader != NULL) - m_ShaderToImpMap.insert( - make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); - - return result; - } - - NVRenderVertFragCompilationResult NVRenderContextImpl::CompileBinary( - const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, - NVDataRef vertShader, NVDataRef fragShader, - NVDataRef tessControlShaderSource, NVDataRef tessEvaluationShaderSource, - NVConstDataRef geometryShaderSource) - { -#ifndef _MACOSX - NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( - *this, shaderName, vertShader, fragShader, tessControlShaderSource, - tessEvaluationShaderSource, geometryShaderSource, false, type, true); - - if (result.mShader != NULL) - m_ShaderToImpMap.insert( - make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); - - return result; -#else - QT3DS_ASSERT(false); - return NVRenderVertFragCompilationResult(); -#endif - } - - NVRenderVertFragCompilationResult - NVRenderContextImpl::CompileComputeSource(const char *shaderName, - NVConstDataRef computeShaderSource) - { - NVRenderVertFragCompilationResult result = - NVRenderShaderProgram::CreateCompute(*this, shaderName, computeShaderSource); - - if (result.mShader != NULL) - m_ShaderToImpMap.insert( - make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); - - return result; - } - - NVRenderShaderProgram *NVRenderContextImpl::GetShaderProgram(const void *implementationHandle) - { - const nvhash_map::iterator entry = - m_ShaderToImpMap.find(implementationHandle); - if (entry != m_ShaderToImpMap.end()) - return entry->second; - return NULL; - } - - void NVRenderContextImpl::ShaderDestroyed(NVRenderShaderProgram &shader) - { - m_ShaderToImpMap.erase(shader.GetShaderProgramHandle()); - if (m_HardwarePropertyContext.m_ActiveShader == &shader) - SetActiveShader(NULL); - } - - NVRenderProgramPipeline *NVRenderContextImpl::CreateProgramPipeline() - { - return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderProgramPipeline)(*this, - GetFoundation()); - } - - NVRenderPathSpecification *NVRenderContextImpl::CreatePathSpecification() - { - return NVRenderPathSpecification::CreatePathSpecification(*this); - } - - NVRenderPathRender *NVRenderContextImpl::CreatePathRender(size_t range) - { - return NVRenderPathRender::Create(*this, range); - } - - void NVRenderContextImpl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) - { - m_backend->SetPathProjectionMatrix(inPathProjection); - } - - void NVRenderContextImpl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) - { - m_backend->SetPathModelViewMatrix(inPathModelview); - } - - void NVRenderContextImpl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) - { - m_backend->SetPathStencilDepthOffset(inSlope, inBias); - } - void NVRenderContextImpl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) - { - m_backend->SetPathCoverDepthFunc(inFunc); - } - - NVRenderPathFontSpecification * - NVRenderContextImpl::CreatePathFontSpecification(CRegisteredString fontName) - { - // first check if it already exists - nvhash_map::const_iterator entry = - m_PathFontSpecToImpMap.find(fontName); - if (entry != m_PathFontSpecToImpMap.end()) - return entry->second; - - // if not create new one - NVRenderPathFontSpecification *pPathFontSpec = - NVRenderPathFontSpecification::CreatePathFontSpecification(*this, fontName); - - if (pPathFontSpec) - m_PathFontSpecToImpMap.insert(make_pair(fontName, pPathFontSpec)); - - return pPathFontSpec; - } - - void - NVRenderContextImpl::ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec) - { - m_PathFontSpecToImpMap.erase(inPathSpec.GetFontName()); - } - - NVRenderPathFontItem *NVRenderContextImpl::CreatePathFontItem() - { - // if not create new one - return NVRenderPathFontItem::CreatePathFontItem(*this); - } - - void NVRenderContextImpl::SetClearColor(QT3DSVec4 inClearColor) - { - if (m_HardwarePropertyContext.m_ClearColor != inClearColor) - DoSetClearColor(inClearColor); - } - - void NVRenderContextImpl::SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) - { - if (memcmp(&inFunctions, &m_HardwarePropertyContext.m_BlendFunction, - sizeof(NVRenderBlendFunctionArgument))) { - DoSetBlendFunction(inFunctions); - } - } - - void NVRenderContextImpl::SetBlendEquation(NVRenderBlendEquationArgument inEquations) - { - if (memcmp(&inEquations, &m_HardwarePropertyContext.m_BlendEquation, - sizeof(NVRenderBlendEquationArgument))) { - DoSetBlendEquation(inEquations); - } - } - - void NVRenderContextImpl::SetCullingEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_CullingEnabled) { - DoSetCullingEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) - { - if (inFunction != m_HardwarePropertyContext.m_DepthFunction) { - DoSetDepthFunction(inFunction); - } - } - - void NVRenderContextImpl::SetBlendingEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_BlendingEnabled) { - DoSetBlendingEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetColorWritesEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_ColorWritesEnabled) { - DoSetColorWritesEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetDepthWriteEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_DepthWriteEnabled) { - m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; - m_backend->SetRenderState(inEnabled, NVRenderState::DepthWrite); - } - } - - void NVRenderContextImpl::SetDepthTestEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_DepthTestEnabled) { - DoSetDepthTestEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetMultisampleEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_MultisampleEnabled) { - DoSetMultisampleEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetStencilTestEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_StencilTestEnabled) { - DoSetStencilTestEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetScissorTestEnabled(bool inEnabled) - { - if (inEnabled != m_HardwarePropertyContext.m_ScissorTestEnabled) { - DoSetScissorTestEnabled(inEnabled); - } - } - - void NVRenderContextImpl::SetScissorRect(NVRenderRect inRect) - { - if (memcmp(&inRect, &m_HardwarePropertyContext.m_ScissorRect, sizeof(NVRenderRect))) { - DoSetScissorRect(inRect); - } - } - - void NVRenderContextImpl::SetViewport(NVRenderRect inViewport) - { - if (memcmp(&inViewport, &m_HardwarePropertyContext.m_Viewport, sizeof(NVRenderRect))) { - DoSetViewport(inViewport); - } - } - - void NVRenderContextImpl::SetActiveShader(NVRenderShaderProgram *inShader) - { - if (inShader != m_HardwarePropertyContext.m_ActiveShader) - DoSetActiveShader(inShader); - } - - void NVRenderContextImpl::SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) - { - if (inProgramPipeline != m_HardwarePropertyContext.m_ActiveProgramPipeline) - DoSetActiveProgramPipeline(inProgramPipeline); - } - - void NVRenderContextImpl::DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, - QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) - { - QT3DS_ASSERT(inShader); - - if (inShader != m_HardwarePropertyContext.m_ActiveShader) - DoSetActiveShader(inShader); - - m_backend->DispatchCompute(inShader->GetShaderProgramHandle(), numGroupsX, numGroupsY, - numGroupsZ); - - OnPostDraw(); - } - - void NVRenderContextImpl::SetDrawBuffers(NVConstDataRef inDrawBufferSet) - { - m_backend->SetDrawBuffers( - (m_HardwarePropertyContext.m_FrameBuffer) - ? m_HardwarePropertyContext.m_FrameBuffer->GetFrameBuffertHandle() - : NULL, - inDrawBufferSet); - } - - void NVRenderContextImpl::SetReadBuffer(NVReadFaces::Enum inReadFace) - { - // currently NULL which means the read target must be set with setReadTarget - m_backend->SetReadBuffer(NULL, inReadFace); - } - - void NVRenderContextImpl::ReadPixels(NVRenderRect inRect, - NVRenderReadPixelFormats::Enum inFormat, - NVDataRef inWriteBuffer) - { - // NULL means read from current render target - m_backend->ReadPixel(NULL, inRect.m_X, inRect.m_Y, inRect.m_Width, inRect.m_Height, - inFormat, (void *)inWriteBuffer.begin()); - } - - void NVRenderContextImpl::SetRenderTarget(NVRenderFrameBuffer *inBuffer) - { - if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { - DoSetRenderTarget(inBuffer); - } - } - - void NVRenderContextImpl::SetReadTarget(NVRenderFrameBuffer *inBuffer) - { - if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { - DoSetReadTarget(inBuffer); - } - } - - void NVRenderContextImpl::ResetBlendState() - { - QT3DSI32_4 values; - - m_backend->SetRenderState(m_HardwarePropertyContext.m_BlendingEnabled, - NVRenderState::Blend); - const NVRenderBlendFunctionArgument &theBlendArg(m_HardwarePropertyContext.m_BlendFunction); - m_backend->SetBlendFunc(theBlendArg); - } - - // Pop the entire set of properties, potentially forcing the values - // to opengl. - void NVRenderContextImpl::PopPropertySet(bool inForceSetProperties) - { - if (!m_PropertyStack.empty()) { - SNVGLHardPropertyContext &theTopContext(m_PropertyStack.back()); - if (inForceSetProperties) { -#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ - DoSet##setterName(theTopContext.m_##propName); - - ITERATE_HARDWARE_CONTEXT_PROPERTIES - -#undef HANDLE_CONTEXT_HARDWARE_PROPERTY - } else { -#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ - Set##setterName(theTopContext.m_##propName); - - ITERATE_HARDWARE_CONTEXT_PROPERTIES - -#undef HANDLE_CONTEXT_HARDWARE_PROPERTY - } - m_PropertyStack.pop_back(); - } - } - - void NVRenderContextImpl::Clear(NVRenderClearFlags flags) - { - if ((flags & NVRenderClearValues::Depth) - && m_HardwarePropertyContext.m_DepthWriteEnabled == false) { - QT3DS_ASSERT(false); - SetDepthWriteEnabled(true); - } - m_backend->Clear(flags); - } - - void NVRenderContextImpl::Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) - { - NVRenderFrameBuffer *previous = m_HardwarePropertyContext.m_FrameBuffer; - if (previous != &fb) - SetRenderTarget(&fb); - - Clear(flags); - - if (previous != &fb) - SetRenderTarget(previous); - } - - void NVRenderContextImpl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) - { - m_backend->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, flags, - filter); - } - - bool - NVRenderContextImpl::BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, - NVRenderShaderProgram *shader) - { - // setup the input assembler object - return m_backend->SetInputAssembler(inputAssembler->GetInputAssemblerHandle(), - shader->GetShaderProgramHandle()); - } - - bool NVRenderContextImpl::ApplyPreDrawProperties() - { - // Get the currently bound vertex and shader - NVRenderInputAssembler *inputAssembler = this->m_HardwarePropertyContext.m_InputAssembler; - NVRenderShaderProgram *shader = this->m_HardwarePropertyContext.m_ActiveShader; - - // we could render through a program pipline - if (shader == NULL && this->m_HardwarePropertyContext.m_ActiveProgramPipeline) - shader = this->m_HardwarePropertyContext.m_ActiveProgramPipeline->GetVertexStage(); - - if (inputAssembler == NULL || shader == NULL) { - qCCritical(INVALID_OPERATION, - "Attempting to render no valid shader or input assembler setup"); - QT3DS_ASSERT(false); - return false; - } - - return BindShaderToInputAssembler(inputAssembler, shader); - } - - void NVRenderContextImpl::OnPostDraw() - { - // reset input assembler binding - m_backend->SetInputAssembler(NULL, 0); - // Texture unit 0 is used for setting up and loading textures. - // Bugs happen if we load a texture then setup the sampler. - // Then we load another texture. Because when loading we use texture unit 0, - // the render bindings for the first texture are blown away. - // Again, for this reason, texture unit 0 is reserved for loading textures. - m_NextTextureUnit = 1; - m_NextConstantBufferUnit = 0; - } - - void NVRenderContextImpl::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) - { - if (!ApplyPreDrawProperties()) - return; - - NVRenderIndexBuffer *theIndexBuffer = const_cast( - m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); - if (theIndexBuffer == NULL) - m_backend->Draw(drawMode, offset, count); - else - theIndexBuffer->Draw(drawMode, count, offset); - - OnPostDraw(); - } - - void NVRenderContextImpl::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) - { - if (!ApplyPreDrawProperties()) - return; - - NVRenderIndexBuffer *theIndexBuffer = const_cast( - m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); - if (theIndexBuffer == NULL) - m_backend->DrawIndirect(drawMode, (const void *)offset); - else - theIndexBuffer->DrawIndirect(drawMode, offset); - - OnPostDraw(); - } - - QT3DSMat44 - NVRenderContext::ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, - const NVRenderRectF &inViewport, - const NVRenderRectF &inVirtualViewport) - { - if (inVirtualViewport == inViewport) - return inProjection; - // Run conversion to floating point once. - NVRenderRectF theVirtualViewport(inVirtualViewport); - NVRenderRectF theViewport(inViewport); - if (theVirtualViewport.m_Width == 0 || theVirtualViewport.m_Height == 0 - || theViewport.m_Width == 0 || theViewport.m_Height == 0) { - QT3DS_ASSERT(false); - return inProjection; - } - QT3DSMat44 theScaleTransMat(QT3DSMat44::createIdentity()); - QT3DSF32 theHeightDiff = theViewport.m_Height - theVirtualViewport.m_Height; - QT3DSF32 theViewportOffY = theVirtualViewport.m_Y - theViewport.m_Y; - QT3DSVec2 theCameraOffsets = QT3DSVec2(theVirtualViewport.m_Width - theViewport.m_Width - + (theVirtualViewport.m_X - theViewport.m_X) * 2.0f, - theHeightDiff + (theViewportOffY - theHeightDiff) * 2.0f); - QT3DSVec2 theCameraScale = QT3DSVec2(theVirtualViewport.m_Width / theViewport.m_Width, - theVirtualViewport.m_Height / theViewport.m_Height); - - QT3DSVec3 theTranslation(theCameraOffsets.x / theViewport.m_Width, - theCameraOffsets.y / theViewport.m_Height, 0); - theScaleTransMat.column3[0] = theTranslation.x; - theScaleTransMat.column3[1] = theTranslation.y; - theScaleTransMat.column0[0] = theCameraScale.x; - theScaleTransMat.column1[1] = theCameraScale.y; - - return theScaleTransMat * inProjection; - } - - NVRenderVertFragCompilationResult NVRenderContext::CompileSource( - const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, const char *fragShader, - QT3DSU32 inFragLen, const char *tessControlShaderSource, QT3DSU32 inTCLen, - const char *tessEvaluationShaderSource, QT3DSU32 inTELen, const char *geometryShaderSource, - QT3DSU32 inGSLen, bool separableProgram) - { - return CompileSource( - shaderName, NVConstDataRef((const QT3DSI8 *)vertShader, inVertLen), - NVConstDataRef((const QT3DSI8 *)fragShader, inFragLen), - NVConstDataRef((const QT3DSI8 *)tessControlShaderSource, inTCLen), - NVConstDataRef((const QT3DSI8 *)tessEvaluationShaderSource, inTELen), - NVConstDataRef((const QT3DSI8 *)geometryShaderSource, inGSLen), separableProgram); - } - - void NVRenderContextImpl::DoSetActiveShader(NVRenderShaderProgram *inShader) - { - m_HardwarePropertyContext.m_ActiveShader = NULL; - if (inShader) - m_backend->SetActiveProgram(inShader->GetShaderProgramHandle()); - else { - m_backend->SetActiveProgram(NULL); - } - m_HardwarePropertyContext.m_ActiveShader = inShader; - } - - void NVRenderContextImpl::DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) - { - if (inProgramPipeline) { - // invalid any bound shader - DoSetActiveShader(NULL); - inProgramPipeline->Bind(); - } else - m_backend->SetActiveProgramPipeline(NULL); - - m_HardwarePropertyContext.m_ActiveProgramPipeline = inProgramPipeline; - } - - NVRenderContext &NVRenderContext::CreateNULL(NVFoundationBase &foundation, - IStringTable &inStringTable) - { - NVRenderContext *retval = NULL; - - // create backend - NVScopedRefCounted theStringTable(inStringTable); - NVScopedRefCounted theBackend = - NVRenderBackendNULL::CreateBackend(foundation); - retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, - *theStringTable); - return *retval; - } -} -} // end namespace diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDataBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDataBuffer.cpp deleted file mode 100644 index b00b0af0..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDataBuffer.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderDataBuffer.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSFoundation.h" - -namespace qt3ds { -namespace render { - - NVRenderDataBuffer::NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, - size_t size, NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usageType, - NVDataRef data) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_UsageType(usageType) - , m_BindFlags(bindFlags) - , m_BufferData(data) - , m_BufferCapacity(data.size()) - , m_BufferSize(size) - , m_OwnsData(false) - , m_Mapped(false) - { - m_BufferHandle = - m_Backend->CreateBuffer(size, bindFlags, usageType, (const void *)m_BufferData.begin()); - } - - NVRenderDataBuffer::~NVRenderDataBuffer() - { - if (m_BufferHandle) { - m_Backend->ReleaseBuffer(m_BufferHandle); - } - m_BufferHandle = 0; - - releaseMemory(); - } - - void NVRenderDataBuffer::releaseMemory() - { - // chekc if we should release memory - if (m_BufferData.size() && m_OwnsData) { - m_Foundation.getAllocator().deallocate(m_BufferData.begin()); - } - - m_BufferData = NVDataRef(); - m_OwnsData = false; - } - - NVDataRef NVRenderDataBuffer::MapBuffer() - { - // don't map twice - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer"); - QT3DS_ASSERT(false); - } - - QT3DSU8 *pData = (QT3DSU8 *)m_Backend->MapBuffer( - m_BufferHandle, m_BindFlags, 0, m_BufferSize, - NVRenderBufferAccessFlags(NVRenderBufferAccessTypeValues::Read - | NVRenderBufferAccessTypeValues::Write)); - - releaseMemory(); - m_BufferData = toDataRef(const_cast(pData), (QT3DSU32)m_BufferSize); - m_BufferCapacity = (QT3DSU32)m_BufferSize; - m_OwnsData = false; - - // currently we return a reference to the system memory - m_Mapped = true; - return m_BufferData; - } - - NVDataRef NVRenderDataBuffer::MapBufferRange(size_t offset, size_t size, - NVRenderBufferAccessFlags flags) - { - // don't map twice - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer"); - QT3DS_ASSERT(false); - } - // don't map out of range - if ((m_BufferSize < (offset + size)) || (size == 0)) { - qCCritical(INVALID_OPERATION, "Attempting to map out of buffer range"); - QT3DS_ASSERT(false); - } - - QT3DSU8 *pData = - (QT3DSU8 *)m_Backend->MapBuffer(m_BufferHandle, m_BindFlags, offset, size, flags); - - releaseMemory(); - m_BufferData = toDataRef(const_cast(pData), (QT3DSU32)size); - m_BufferCapacity = (QT3DSU32)size; - m_OwnsData = false; - - // currently we return a reference to the system memory - m_Mapped = true; - return m_BufferData; - } - - void NVRenderDataBuffer::UnmapBuffer() - { - if (m_Mapped) { - // update hardware - m_Backend->UnmapBuffer(m_BufferHandle, m_BindFlags); - m_Mapped = false; - releaseMemory(); - } - } - - void NVRenderDataBuffer::UpdateBuffer(NVConstDataRef data, bool ownsMemory) - { - // don't update a mapped buffer - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to update a mapped buffer"); - QT3DS_ASSERT(false); - } - - releaseMemory(); - - m_BufferData = toDataRef(const_cast(data.begin()), data.size()); - m_BufferCapacity = data.mSize; - m_OwnsData = ownsMemory; - // update hardware - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferCapacity, m_UsageType, - (const void *)m_BufferData.begin()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDepthStencilState.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDepthStencilState.cpp deleted file mode 100644 index 3ea47e23..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDepthStencilState.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderDepthStencilState.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderDepthStencilState::NVRenderDepthStencilState( - NVRenderContextImpl &context, NVFoundationBase &fnd, bool enableDepth, bool depthMask, - NVRenderBoolOp::Enum depthFunc, bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_DepthEnabled(enableDepth) - , m_DepthMask(depthMask) - , m_DepthFunc(depthFunc) - , m_StencilEnabled(enableStencil) - , m_StencilFuncFront(stencilFuncFront) - , m_StencilFuncBack(stencilFuncBack) - , m_DepthStencilOpFront(depthStencilOpFront) - , m_DepthStencilOpBack(depthStencilOpBack) - { - // create backend handle - m_StateHandle = m_Backend->CreateDepthStencilState( - enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, - depthStencilOpFront, depthStencilOpBack); - } - - NVRenderDepthStencilState::~NVRenderDepthStencilState() - { - if (m_StateHandle) { - m_Context.StateDestroyed(*this); - m_Backend->ReleaseDepthStencilState(m_StateHandle); - } - } - - NVRenderDepthStencilState * - NVRenderDepthStencilState::Create(NVRenderContextImpl &context, bool enableDepth, - bool depthMask, NVRenderBoolOp::Enum depthFunc, - bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) - { - return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderDepthStencilState)( - context, context.GetFoundation(), enableDepth, depthMask, depthFunc, enableStencil, - stencilFuncFront, stencilFuncBack, depthStencilOpFront, depthStencilOpBack); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDrawIndirectBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDrawIndirectBuffer.cpp deleted file mode 100644 index 9940003f..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderDrawIndirectBuffer.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderDrawIndirectBuffer.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" - -namespace qt3ds { -namespace render { - - NVRenderDrawIndirectBuffer::NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, - size_t size, - NVRenderBufferUsageType::Enum usageType, - NVDataRef data) - : NVRenderDataBuffer(context, context.GetFoundation(), size, - NVRenderBufferBindValues::Draw_Indirect, usageType, data) - , m_Dirty(true) - { - } - - NVRenderDrawIndirectBuffer::~NVRenderDrawIndirectBuffer() { m_Context.BufferDestroyed(*this); } - - void NVRenderDrawIndirectBuffer::Bind() - { - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); - QT3DS_ASSERT(false); - } - - m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); - } - - void NVRenderDrawIndirectBuffer::Update() - { - // we only update the buffer if it is dirty and we actually have some data - if (m_Dirty && m_BufferData.size()) { - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, - m_BufferData.begin()); - m_Dirty = false; - } - } - - void NVRenderDrawIndirectBuffer::UpdateData(QT3DSI32 offset, NVDataRef data) - { - // we only update the buffer if we something - if (data.size()) - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, - data.begin() + offset); - } - - NVRenderDrawIndirectBuffer * - NVRenderDrawIndirectBuffer::Create(NVRenderContextImpl &context, - NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData) - { - NVFoundationBase &fnd(context.GetFoundation()); - NVRenderDrawIndirectBuffer *retval = NULL; - - // these are the context flags which do not support this drawing mode - NVRenderContextType noDrawIndirectSupported( - NVRenderContextValues::GL2 | NVRenderContextValues::GLES2 | NVRenderContextValues::GL3 - | NVRenderContextValues::GLES3); - NVRenderContextType ctxType = context.GetRenderContextType(); - - if (!(ctxType & noDrawIndirectSupported)) { - QT3DSU32 bufSize = sizeof(NVRenderDrawIndirectBuffer); - QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "DrawIndirectBuffer"); - retval = new (newMem) NVRenderDrawIndirectBuffer( - context, size, usageType, - toDataRef(const_cast(bufferData.begin()), bufferData.size())); - } else { - QT3DS_ASSERT(false); - } - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFragmentShader.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFragmentShader.cpp deleted file mode 100644 index e2f31f1b..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFragmentShader.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderFragmentShader.h" - -namespace qt3ds { -namespace render { - - NVRenderFragmentShader::NVRenderFragmentShader(NVRenderContextImpl &context, - NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram) - : NVRenderShader(context, fnd, source, binaryProgram) - , m_ShaderHandle(NULL) - { - m_ShaderHandle = m_Backend->CreateFragmentShader(source, m_ErrorMessage, binaryProgram); - } - - NVRenderFragmentShader::~NVRenderFragmentShader() - { - if (m_ShaderHandle) { - m_Backend->ReleaseFragmentShader(m_ShaderHandle); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFrameBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFrameBuffer.cpp deleted file mode 100644 index 0ab38428..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderFrameBuffer.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - NVRenderFrameBuffer::NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_BufferHandle(NULL) - , m_AttachmentBits(0) - { - m_BufferHandle = m_Backend->CreateRenderTarget(); - QT3DS_ASSERT(m_BufferHandle); - } - - NVRenderFrameBuffer::~NVRenderFrameBuffer() - { - m_Context.FrameBufferDestroyed(*this); - m_Backend->ReleaseRenderTarget(m_BufferHandle); - m_BufferHandle = 0; - m_AttachmentBits = 0; - - // release attachments - QT3DS_FOREACH(idx, (QT3DSU32)NVRenderFrameBufferAttachments::LastAttachment) - { - if ((NVRenderFrameBufferAttachments::Enum)idx - != NVRenderFrameBufferAttachments::DepthStencil - || m_Context.IsDepthStencilSupported()) - releaseAttachment((NVRenderFrameBufferAttachments::Enum)idx); - } - } - - inline void CheckAttachment(NVRenderContext &ctx, - NVRenderFrameBufferAttachments::Enum attachment) - { -#ifdef _DEBUG - QT3DS_ASSERT(attachment != NVRenderFrameBufferAttachments::DepthStencil - || ctx.IsDepthStencilSupported()); -#endif - (void)ctx; - (void)attachment; - } - - NVRenderTextureTargetType::Enum - NVRenderFrameBuffer::releaseAttachment(NVRenderFrameBufferAttachments::Enum idx) - { - NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Unknown; - - NVRenderTextureOrRenderBuffer Attach = m_Attachments[idx]; - if (Attach.HasTexture2D()) { - target = (Attach.GetTexture2D()->IsMultisampleTexture()) - ? NVRenderTextureTargetType::Texture2D_MS - : NVRenderTextureTargetType::Texture2D; - Attach.GetTexture2D()->release(); - } else if (Attach.HasTexture2DArray()) { - target = (Attach.GetTexture2DArray()->IsMultisampleTexture()) - ? NVRenderTextureTargetType::Texture2D_MS - : NVRenderTextureTargetType::Texture2D_Array; - Attach.GetTexture2DArray()->release(); - } else if (Attach.HasTextureCube()) { - target = (Attach.GetTextureCube()->IsMultisampleTexture()) - ? NVRenderTextureTargetType::Texture2D_MS - : NVRenderTextureTargetType::TextureCube; - Attach.GetTextureCube()->release(); - } else if (Attach.HasRenderBuffer()) - Attach.GetRenderBuffer()->release(); - - CheckAttachment(m_Context, idx); - m_Attachments[idx] = NVRenderTextureOrRenderBuffer(); - - m_AttachmentBits &= ~(1 << idx); - - return target; - } - - NVRenderTextureOrRenderBuffer - NVRenderFrameBuffer::GetAttachment(NVRenderFrameBufferAttachments::Enum attachment) - { - if (attachment == NVRenderFrameBufferAttachments::Unknown - || attachment > NVRenderFrameBufferAttachments::LastAttachment) { - qCCritical(INVALID_PARAMETER, "Attachment out of range"); - return NVRenderTextureOrRenderBuffer(); - } - CheckAttachment(m_Context, attachment); - return m_Attachments[attachment]; - } - - void NVRenderFrameBuffer::Attach(NVRenderFrameBufferAttachments::Enum attachment, - NVRenderTextureOrRenderBuffer buffer, - NVRenderTextureTargetType::Enum target) - { - if (attachment == NVRenderFrameBufferAttachments::Unknown - || attachment > NVRenderFrameBufferAttachments::LastAttachment) { - qCCritical(INVALID_PARAMETER, "Attachment out of range"); - return; - } - - // early out - // if there is nothing to detach - if (!buffer.HasTexture2D() && !buffer.HasRenderBuffer() && !buffer.HasTexture2DArray() - && !(m_AttachmentBits & (1 << attachment))) - return; - - CheckAttachment(m_Context, attachment); - // Ensure we are the bound framebuffer - m_Context.SetRenderTarget(this); - - // release previous attachments - NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); - - if (buffer.HasTexture2D()) { - // On the same attachment point there could be a something attached with a different - // target MSAA <--> NoMSAA - if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target) - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - NVRenderBackend::NVRenderBackendTextureObject(NULL), - theRelTarget); - - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - buffer.GetTexture2D()->GetTextureObjectHandle(), target); - buffer.GetTexture2D()->addRef(); - m_AttachmentBits |= (1 << attachment); - } else if (buffer.HasTexture2DArray()) { - // On the same attachment point there could be a something attached with a different - // target MSAA <--> NoMSAA - if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target) - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - NVRenderBackend::NVRenderBackendTextureObject(NULL), - theRelTarget); - - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - buffer.GetTexture2D()->GetTextureObjectHandle(), target); - buffer.GetTexture2DArray()->addRef(); - m_AttachmentBits |= (1 << attachment); - } else if (buffer.HasRenderBuffer()) { - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - buffer.GetRenderBuffer()->GetRenderBuffertHandle()); - buffer.GetRenderBuffer()->addRef(); - m_AttachmentBits |= (1 << attachment); - } else if (theRelTarget == NVRenderTextureTargetType::Unknown) { - // detach renderbuffer - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - NVRenderBackend::NVRenderBackendRenderbufferObject(NULL)); - } else { - // detach texture - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - NVRenderBackend::NVRenderBackendTextureObject(NULL), - theRelTarget); - } - m_Attachments[attachment] = buffer; - } - - void NVRenderFrameBuffer::AttachLayer(NVRenderFrameBufferAttachments::Enum attachment, - NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer, - QT3DSI32 level) - { - if (attachment == NVRenderFrameBufferAttachments::Unknown - || attachment > NVRenderFrameBufferAttachments::LastAttachment) { - qCCritical(INVALID_PARAMETER, "Attachment out of range"); - return; - } - - // This function is only used for attaching a layer - // If texture exists probably something is wrong - if (!buffer.HasTexture2DArray()) { - QT3DS_ASSERT(false); - return; - } - - CheckAttachment(m_Context, attachment); - // Ensure we are the bound framebuffer - m_Context.SetRenderTarget(this); - - // release previous attachments - NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); - - // On the same attachment point there could be a something attached with a different target - // MSAA <--> NoMSAA - if (theRelTarget != NVRenderTextureTargetType::Unknown - && theRelTarget != NVRenderTextureTargetType::Texture2D_Array) - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - NVRenderBackend::NVRenderBackendTextureObject(NULL), - theRelTarget); - - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - buffer.GetTexture2DArray()->GetTextureObjectHandle(), level, - layer); - buffer.GetTexture2DArray()->addRef(); - m_AttachmentBits |= (1 << attachment); - - m_Attachments[attachment] = buffer; - } - - void NVRenderFrameBuffer::AttachFace(NVRenderFrameBufferAttachments::Enum attachment, - NVRenderTextureOrRenderBuffer buffer, - NVRenderTextureCubeFaces::Enum face) - { - if (attachment == NVRenderFrameBufferAttachments::Unknown - || attachment > NVRenderFrameBufferAttachments::LastAttachment) { - qCCritical(INVALID_PARAMETER, "Attachment out of range"); - return; - } - - if (face == NVRenderTextureCubeFaces::InvalidFace) { - QT3DS_ASSERT(false); - return; - } - - CheckAttachment(m_Context, attachment); - // Ensure we are the bound framebuffer - m_Context.SetRenderTarget(this); - - // release previous attachments - NVRenderTextureTargetType::Enum attachTarget = static_cast( - (int)NVRenderTextureTargetType::TextureCube + (int)face); - NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); - - // If buffer has no texture cube, this call is used to detach faces. - // If release target is not cube, there is something else attached to that - // attachment point, so we want to release that first. E.g (MSAA <--> NoMSAA) - if (theRelTarget == NVRenderTextureTargetType::TextureCube && !buffer.HasTextureCube()) { - theRelTarget = attachTarget; - attachTarget = NVRenderTextureTargetType::Unknown; - } else if (theRelTarget == NVRenderTextureTargetType::TextureCube) { - theRelTarget = NVRenderTextureTargetType::Unknown; - } - if (theRelTarget != NVRenderTextureTargetType::Unknown) { - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - NVRenderBackend::NVRenderBackendTextureObject(NULL), - theRelTarget); - } - - if (attachTarget != NVRenderTextureTargetType::Unknown) { - m_Backend->RenderTargetAttach(m_BufferHandle, attachment, - buffer.GetTextureCube()->GetTextureObjectHandle(), - attachTarget); - buffer.GetTextureCube()->addRef(); - m_AttachmentBits |= (1 << attachment); - } - - m_Attachments[attachment] = buffer; - } - - bool NVRenderFrameBuffer::IsComplete() - { - // Ensure we are the bound framebuffer - m_Context.SetRenderTarget(this); - - return m_Backend->RenderTargetIsValid(m_BufferHandle); - } -} -} - -qt3ds::render::NVRenderFrameBuffer * -qt3ds::render::NVRenderFrameBuffer::Create(NVRenderContextImpl &context) -{ - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderFrameBuffer)(context, context.GetFoundation()); -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderGeometryShader.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderGeometryShader.cpp deleted file mode 100644 index 50567287..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderGeometryShader.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderGeometryShader.h" - -namespace qt3ds { -namespace render { - - NVRenderGeometryShader::NVRenderGeometryShader(NVRenderContextImpl &context, - NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram) - : NVRenderShader(context, fnd, source, binaryProgram) - , m_ShaderHandle(NULL) - { - m_ShaderHandle = m_Backend->CreateGeometryShader(source, m_ErrorMessage, binaryProgram); - } - - NVRenderGeometryShader::~NVRenderGeometryShader() - { - if (m_ShaderHandle) { - m_Backend->ReleaseGeometryShader(m_ShaderHandle); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderImageTexture.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderImageTexture.cpp deleted file mode 100644 index e987cc31..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderImageTexture.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderImageTexture.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderImage2D::NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_Texture2D(inTexture) - , m_TextureUnit(QT3DS_MAX_U32) - , m_AccessType(inAccess) - , m_TextureLevel(0) - { - inTexture->addRef(); - } - - NVRenderImage2D::~NVRenderImage2D() - { - m_Context.ImageDestroyed(*this); - m_Texture2D->release(); - } - - void NVRenderImage2D::SetTextureLevel(QT3DSI32 inLevel) - { - if (m_Texture2D && m_Texture2D->GetNumMipmaps() >= (QT3DSU32)inLevel) { - m_TextureLevel = inLevel; - } - } - - void NVRenderImage2D::Bind(QT3DSU32 unit) - { - if (unit == -1) - m_TextureUnit = m_Context.GetNextTextureUnit(); - else - m_TextureUnit = unit; - - STextureDetails theDetails(m_Texture2D->GetTextureDetails()); - - // note it is the callers responsibility that the texture format is supported by the compute - // shader - m_Backend->BindImageTexture(m_Texture2D->GetTextureObjectHandle(), m_TextureUnit, - m_TextureLevel, false, 0, m_AccessType, theDetails.m_Format); - } - - NVRenderBackend::NVRenderBackendTextureObject NVRenderImage2D::GetTextureObjectHandle() - { - return m_Texture2D->GetTextureObjectHandle(); - } - - NVRenderImage2D *NVRenderImage2D::Create(NVRenderContextImpl &context, - NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) - { - if (inTexture) - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderImage2D)(context, context.GetFoundation(), inTexture, inAccess); - else - return NULL; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderIndexBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderIndexBuffer.cpp deleted file mode 100644 index 37f56bd2..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderIndexBuffer.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderIndexBuffer.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - - NVRenderIndexBuffer::NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size, - NVRenderComponentTypes::Enum componentType, - NVRenderBufferUsageType::Enum usageType, - NVDataRef data) - : NVRenderDataBuffer(context, context.GetFoundation(), size, - NVRenderBufferBindValues::Index, usageType, data) - , m_ComponentType(componentType) - { - } - - NVRenderIndexBuffer::~NVRenderIndexBuffer() { m_Context.BufferDestroyed(*this); } - - QT3DSU32 NVRenderIndexBuffer::GetNumIndices() const - { - QT3DSU32 dtypeSize = NVRenderComponentTypes::getSizeofType(m_ComponentType); - return m_BufferCapacity / dtypeSize; - } - - void NVRenderIndexBuffer::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) - { - m_Backend->DrawIndexed( - drawMode, count, m_ComponentType, - (const void *)(offset * NVRenderComponentTypes::getSizeofType(m_ComponentType))); - } - - void NVRenderIndexBuffer::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) - { - m_Backend->DrawIndexedIndirect(drawMode, m_ComponentType, (const void *)offset); - } - - void NVRenderIndexBuffer::Bind() - { - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); - QT3DS_ASSERT(false); - } - - m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); - } - - NVRenderIndexBuffer *NVRenderIndexBuffer::Create(NVRenderContextImpl &context, - NVRenderBufferUsageType::Enum usageType, - NVRenderComponentTypes::Enum componentType, - size_t size, NVConstDataRef bufferData) - { - NVFoundationBase &fnd(context.GetFoundation()); - if (componentType != NVRenderComponentTypes::QT3DSU32 - && componentType != NVRenderComponentTypes::QT3DSU16 - && componentType != NVRenderComponentTypes::QT3DSU8) { - qCCritical(INVALID_PARAMETER, "Invalid component type for index buffer"); - QT3DS_ASSERT(false); - return NULL; - } - - QT3DSU32 ibufSize = sizeof(NVRenderIndexBuffer); - QT3DSU8 *baseMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), ibufSize, "IndexBuffer"); - NVRenderIndexBuffer *retval = new (baseMem) NVRenderIndexBuffer( - context, size, componentType, usageType, - toDataRef(const_cast(bufferData.begin()), bufferData.size())); - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderInputAssembler.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderInputAssembler.cpp deleted file mode 100644 index e4d38b9d..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderInputAssembler.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderInputAssembler.h" -#include "render/Qt3DSRenderAttribLayout.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - ///< constructor - NVRenderInputAssembler::NVRenderInputAssembler( - NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout, - NVConstDataRef buffers, const NVRenderIndexBuffer *indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets, - NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) - : m_Context(context) - , m_Foundation(context.GetFoundation()) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_AttribLayout(attribLayout) - , m_VertexBuffers(context.GetAllocator(), "m_VertexBuffers") - , m_IndexBuffer(indexBuffer) - , m_PrimitiveType(primType) - , m_PatchVertexCount(patchVertexCount) - { - // we cannot currently attach more than 16 vertex buffers - QT3DS_ASSERT(buffers.size() < 16); - // if primitive is "Patch" we need a patch per vertex count > 0 - QT3DS_ASSERT(m_PrimitiveType != NVRenderDrawMode::Patches || m_PatchVertexCount > 1); - - QT3DSU32 entrySize = sizeof(NVRenderBackend::NVRenderBackendBufferObject) * buffers.size(); - NVRenderBackend::NVRenderBackendBufferObject *bufferHandle = - (NVRenderBackend::NVRenderBackendBufferObject *)QT3DS_ALLOC( - m_Foundation.getAllocator(), entrySize, "NVRenderInputAssembler"); - // setup vertex buffer backend handle array - QT3DS_FOREACH(idx, buffers.size()) - { - m_VertexBuffers.push_back(buffers.mData[idx]); - bufferHandle[idx] = buffers.mData[idx]->GetBuffertHandle(); - }; - - m_VertexbufferHandles = toConstDataRef(bufferHandle, buffers.size()); - - m_InputAssemblertHandle = m_Backend->CreateInputAssembler( - m_AttribLayout->GetAttribLayoutHandle(), m_VertexbufferHandles, - (m_IndexBuffer) ? m_IndexBuffer->GetBuffertHandle() : NULL, strides, offsets, - patchVertexCount); - - attribLayout->addRef(); - } - - ///< destructor - NVRenderInputAssembler::~NVRenderInputAssembler() - { - m_AttribLayout->release(); - - if (m_InputAssemblertHandle) { - m_Backend->ReleaseInputAssembler(m_InputAssemblertHandle); - } - - QT3DS_FREE(m_Foundation.getAllocator(), (void *)m_VertexbufferHandles.mData); - } - - QT3DSU32 NVRenderInputAssembler::GetIndexCount() const - { - return (m_IndexBuffer) ? m_IndexBuffer->GetNumIndices() : 0; - } - - QT3DSU32 NVRenderInputAssembler::GetVertexCount() const - { - // makes only sense if we have a single vertex buffer - QT3DS_ASSERT(m_VertexBuffers.size() == 1); - - return m_VertexBuffers[0]->GetNumVertexes(); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderOcclusionQuery.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderOcclusionQuery.cpp deleted file mode 100644 index d1b62d4c..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderOcclusionQuery.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderOcclusionQuery.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - - NVRenderOcclusionQuery::NVRenderOcclusionQuery(NVRenderContextImpl &context, - NVFoundationBase &fnd) - : NVRenderQueryBase(context, fnd) - { - } - - NVRenderOcclusionQuery::~NVRenderOcclusionQuery() {} - - void NVRenderOcclusionQuery::Begin() - { - m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Samples); - } - - void NVRenderOcclusionQuery::End() - { - m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Samples); - } - - void NVRenderOcclusionQuery::GetResult(QT3DSU32 *params) - { - m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); - } - - bool NVRenderOcclusionQuery::GetResultAvailable() - { - QT3DSU32 param; - - m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::ResultAvailable, ¶m); - - return (param == 1); - } - - NVRenderOcclusionQuery *NVRenderOcclusionQuery::Create(NVRenderContextImpl &context) - { - if (!context.IsSampleQuerySupported()) - return NULL; - - NVRenderOcclusionQuery *retval = - QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderOcclusionQuery)(context, context.GetFoundation()); - - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontSpecification.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontSpecification.cpp deleted file mode 100644 index 3e9276aa..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontSpecification.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderPathFontSpecification.h" -#include "render/Qt3DSRenderPathFontText.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - NVRenderPathFontSpecification::NVRenderPathFontSpecification(NVRenderContextImpl &context, - NVFoundationBase &fnd, - CRegisteredString fontName) - : m_Context(context) - , m_Foundation(fnd) - , m_Backend(context.GetBackend()) - , mRefCount(0) - , m_NumFontGlyphs(0) - , m_EmScale(2048) // 2048 is default true type scale - , m_Type(NVRenderPathFormatType::UByte) - , m_TransformType(NVRenderPathTransformType::Translate2D) - , m_FontName(fontName) - { - } - - NVRenderPathFontSpecification::~NVRenderPathFontSpecification() - { - m_Context.ReleasePathFontSpecification(*this); - } - - void NVRenderPathFontSpecification::LoadPathGlyphs(const char *fontName, - NVRenderPathFormatType::Enum type) - { - // check if we already created it - if (m_NumFontGlyphs) - return; - - m_Type = type; - - // create fonts based on the input - m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange( - NVRenderPathFontTarget::FileFont, fontName, NVRenderPathFontStyleFlags(), 0, m_EmScale, - &m_NumFontGlyphs); - - // Fallback in case the previuos call fails - // This is a no-op if the previous call succeeds - // Note that sans is an inbuild driver font - if (!m_PathRenderHandle) { - m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange( - NVRenderPathFontTarget::SystemFont, "Arial", NVRenderPathFontStyleFlags(), 0, - m_EmScale, &m_NumFontGlyphs); - } - - // we should have some glyphs - QT3DS_ASSERT(m_NumFontGlyphs); - } - - void - NVRenderPathFontSpecification::StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem) - { - const void *glyphIDs = inPathFontItem.GetGlyphIDs(); - const QT3DSF32 *spacing = inPathFontItem.GetSpacing(); - if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) { - QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount()); - return; - } - - m_Backend->StencilFillPathInstanced(m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), - m_Type, glyphIDs, NVRenderPathFillMode::Fill, 0xFF, - m_TransformType, spacing); - } - - void NVRenderPathFontSpecification::CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem) - { - const void *glyphIDs = inPathFontItem.GetGlyphIDs(); - const QT3DSF32 *spacing = inPathFontItem.GetSpacing(); - if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) { - QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount()); - return; - } - - m_Backend->CoverFillPathInstanced( - m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), m_Type, glyphIDs, - NVRenderPathCoverMode::BoundingBoxOfBoundingBox, m_TransformType, spacing); - } - - QT3DSU32 - NVRenderPathFontSpecification::getSizeofType(NVRenderPathFormatType::Enum type) - { - switch (type) { - case NVRenderPathFormatType::Byte: - return sizeof(QT3DSI8); - case NVRenderPathFormatType::UByte: - return sizeof(QT3DSU8); - case NVRenderPathFormatType::Bytes2: - return sizeof(QT3DSU16); - case NVRenderPathFormatType::Uint: - return sizeof(QT3DSU32); - case NVRenderPathFormatType::Utf8: - return sizeof(QT3DSU32); - default: - QT3DS_ASSERT(false); - return 1; - } - } - - NVRenderPathFontSpecification * - NVRenderPathFontSpecification::CreatePathFontSpecification(NVRenderContextImpl &context, - CRegisteredString fontName) - { - QT3DS_ASSERT(context.IsPathRenderingSupported()); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderPathFontSpecification)(context, context.GetFoundation(), fontName); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontText.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontText.cpp deleted file mode 100644 index aeaad13c..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathFontText.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderPathFontText.h" -#include "render/Qt3DSRenderPathFontSpecification.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderPathRender.h" - -namespace qt3ds { -namespace render { - - // see NVprSDK for explanation - // Math from page 54-56 of "Digital Image Warping" by George Wolberg, - // though credited to Paul Heckert's "Fundamentals of Texture - // Mapping and Image Warping" 1989 Master's thesis. - static QT3DSMat33 mapSquareToQuad(QT3DSVec2 inSquare[4]) - { - QT3DSMat33 ret; - - QT3DSVec2 d1(inSquare[1] - inSquare[2]); - QT3DSVec2 d2(inSquare[3] - inSquare[2]); - QT3DSVec2 d3(inSquare[0] - inSquare[1] + inSquare[2] - inSquare[3]); - - QT3DSF32 denom = d1.x * d2.y - d2.x * d1.y; - if (denom == 0.0) { - return QT3DSMat33::createIdentity(); - } - - ret[2][0] = (d3.x * d2.y - d2.x * d3.y) / denom; - ret[2][1] = (d1.x * d3.y - d3.x * d1.y) / denom; - ret[2][2] = 1.0; - ret[0][0] = inSquare[1].x - inSquare[0].x + ret[2][0] * inSquare[1].x; - ret[1][0] = inSquare[1].y - inSquare[0].y + ret[2][0] * inSquare[1].y; - ret[0][1] = inSquare[3].x - inSquare[0].x + ret[2][1] * inSquare[3].x; - ret[1][1] = inSquare[3].y - inSquare[0].y + ret[2][1] * inSquare[3].y; - ret[0][2] = inSquare[0].x; - ret[1][2] = inSquare[0].y; - - return ret; - } - - static QT3DSMat33 mapQuadToSquare(QT3DSVec2 inSquare[4]) - { - return mapSquareToQuad(inSquare).getInverse(); - } - - static QT3DSMat33 mapQuadToQuad(QT3DSVec2 fromSquare[4], QT3DSVec2 toSquare[4]) - { - return (mapSquareToQuad(toSquare) * mapQuadToSquare(fromSquare)); - } - - static QT3DSMat44 mapBoxToQuad(QT3DSVec4 inBox, QT3DSVec2 inSquare[4]) - { - QT3DSVec2 fromSquare[4] = { QT3DSVec2(inBox.x, inBox.y), QT3DSVec2(inBox.z, inBox.y), - QT3DSVec2(inBox.z, inBox.w), QT3DSVec2(inBox.x, inBox.w) }; - - QT3DSMat33 ret = mapQuadToQuad(fromSquare, inSquare); - - return QT3DSMat44(ret.column0, ret.column1, ret.column2, QT3DSVec3(0.0, 0.0, 0.0)); - } - - NVRenderPathFontItem::NVRenderPathFontItem(NVFoundationBase &fnd) - : m_Foundation(fnd) - , mRefCount(0) - , m_NumGlyphs(0) - , m_GlyphIDs(NULL) - , m_TranslateXY(NULL) - { - } - - NVRenderPathFontItem::~NVRenderPathFontItem() - { - if (m_TranslateXY) - QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY); - if (m_GlyphIDs) - QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs); - } - - void NVRenderPathFontItem::InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs, - NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, - QT3DSVec2 pixelBound, QT3DSVec2 logicalBound, QT3DSF32 emScale) - { - m_NumGlyphs = glyphCount; - - // allocate glyphs array - if (m_GlyphIDs) - QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs); - - // allocate position array - if (m_TranslateXY) - QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY); - - m_GlyphIDs = (QT3DSU32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), - glyphCount * getSizeofType(type), "NVRenderPathFontItem"); - m_TranslateXY = - (QT3DSF32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), 2 * (glyphCount + 1) * sizeof(QT3DSF32), - "NVRenderPathFontItem"); - - if (!m_GlyphIDs || !m_TranslateXY) - return; - - QT3DSU32 *pTheGlyphIDs = (QT3DSU32 *)m_GlyphIDs; - QT3DSU32 *pInGlyphs = (QT3DSU32 *)glyphIDs; - - /// copy glyphs array - for (size_t i = 0; i < glyphCount; i++) { - pTheGlyphIDs[i] = pInGlyphs[i]; - } - - // copy position array - // we copy what we got from our layout system - if (posArray != NULL) { - for (size_t i = 0, k = 0; i < glyphCount * 2; i += 2, k++) { - m_TranslateXY[i] = posArray[i] * emScale; - m_TranslateXY[i + 1] = posArray[i + 1] * emScale; - } - } - - // setup transform - QT3DSVec2 square[4] = { QT3DSVec2(0.0, 0.0), QT3DSVec2(pixelBound.x, 0.0), - QT3DSVec2(pixelBound.x, pixelBound.y), QT3DSVec2(0.0, pixelBound.y) }; - QT3DSVec4 box(0.0, 0.0, logicalBound.x * emScale, logicalBound.y * emScale); - - m_ModelMatrix = mapBoxToQuad(box, square); - } - - const QT3DSMat44 NVRenderPathFontItem::GetTransform() - { - return QT3DSMat44(QT3DSVec4(m_ModelMatrix[0][0], m_ModelMatrix[1][0], 0.0, m_ModelMatrix[2][0]), - QT3DSVec4(m_ModelMatrix[0][1], m_ModelMatrix[1][1], 0.0, m_ModelMatrix[2][1]), - QT3DSVec4(0.0, 0.0, 1.0, 0.0), - QT3DSVec4(m_ModelMatrix[0][2], m_ModelMatrix[1][2], 0.0, m_ModelMatrix[2][2])); - } - - QT3DSU32 - NVRenderPathFontItem::getSizeofType(NVRenderPathFormatType::Enum type) - { - switch (type) { - case NVRenderPathFormatType::Byte: - return sizeof(QT3DSI8); - case NVRenderPathFormatType::UByte: - return sizeof(QT3DSU8); - case NVRenderPathFormatType::Bytes2: - return sizeof(QT3DSU16); - case NVRenderPathFormatType::Uint: - return sizeof(QT3DSU32); - case NVRenderPathFormatType::Utf8: - return sizeof(QT3DSU32); - default: - QT3DS_ASSERT(false); - return 1; - } - } - - NVRenderPathFontItem *NVRenderPathFontItem::CreatePathFontItem(NVRenderContextImpl &context) - { - QT3DS_ASSERT(context.IsPathRenderingSupported()); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderPathFontItem)(context.GetFoundation()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathRender.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathRender.cpp deleted file mode 100644 index 42982498..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathRender.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderPathRender.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderPathSpecification.h" -#include "render/Qt3DSRenderPathFontSpecification.h" - -namespace qt3ds { -namespace render { - - NVRenderPathRender::NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, - size_t range) - : m_Context(context) - , m_Foundation(fnd) - , m_Backend(context.GetBackend()) - , mRefCount(0) - , m_StrokeWidth(0.0f) - { - m_Range = range; - m_PathRenderHandle = m_Backend->CreatePathNVObject(range); - } - - NVRenderPathRender::~NVRenderPathRender() - { - if (m_PathRenderHandle) { - m_Backend->ReleasePathNVObject(m_PathRenderHandle, m_Range); - } - } - - void NVRenderPathRender::SetPathSpecification(NVRenderPathSpecification &inCommandBuffer) - { - m_Backend->SetPathSpecification(m_PathRenderHandle, inCommandBuffer.GetPathCommands(), - inCommandBuffer.GetPathCoords()); - } - - NVBounds3 NVRenderPathRender::GetPathObjectBoundingBox() - { - return m_Backend->GetPathObjectBoundingBox(m_PathRenderHandle); - } - - NVBounds3 NVRenderPathRender::GetPathObjectFillBox() - { - return m_Backend->GetPathObjectFillBox(m_PathRenderHandle); - } - - NVBounds3 NVRenderPathRender::GetPathObjectStrokeBox() - { - return m_Backend->GetPathObjectStrokeBox(m_PathRenderHandle); - } - - void NVRenderPathRender::SetStrokeWidth(QT3DSF32 inStrokeWidth) - { - if (inStrokeWidth != m_StrokeWidth) { - m_StrokeWidth = inStrokeWidth; - m_Backend->SetStrokeWidth(m_PathRenderHandle, inStrokeWidth); - } - } - - QT3DSF32 NVRenderPathRender::GetStrokeWidth() const { return m_StrokeWidth; } - - void NVRenderPathRender::StencilStroke() { m_Backend->StencilStrokePath(m_PathRenderHandle); } - - void NVRenderPathRender::StencilFill() { m_Backend->StencilFillPath(m_PathRenderHandle); } - - NVRenderPathRender *NVRenderPathRender::Create(NVRenderContextImpl &context, size_t range) - { - if (!context.IsPathRenderingSupported()) - return NULL; - - NVRenderPathRender *retval = - QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderPathRender)(context, context.GetFoundation(), range); - - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathSpecification.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathSpecification.cpp deleted file mode 100644 index f4b26f11..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderPathSpecification.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderPathSpecification.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - NVRenderPathSpecification::NVRenderPathSpecification(NVRenderContextImpl &context, - NVFoundationBase &fnd) - : m_Context(context) - , m_Foundation(fnd) - , m_Backend(context.GetBackend()) - , mRefCount(0) - , m_PathCommands(fnd.getAllocator(), "m_PathCommands") - , m_PathCoords(fnd.getAllocator(), "m_PathCoords") - { - } - - NVRenderPathSpecification::~NVRenderPathSpecification() {} - - void NVRenderPathSpecification::Reset() - { - m_PathCommands.clear(); - m_PathCoords.clear(); - } - - void NVRenderPathSpecification::P(QT3DSVec2 inData) - { - m_PathCoords.push_back(inData.x); - m_PathCoords.push_back(inData.y); - } - - void NVRenderPathSpecification::MoveTo(QT3DSVec2 inPoint) - { - // we should actually query the backend for command converesion - // but will we support any other pather render system than nv path? - StaticAssert::valid_expression(); - - m_PathCommands.push_back(NVRenderPathCommands::MoveTo); - P(inPoint); - } - - void NVRenderPathSpecification::CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest) - { - // we should actually query the backend for command converesion - // but will we support any other pather render system than nv path? - StaticAssert::valid_expression(); - - m_PathCommands.push_back(NVRenderPathCommands::CubicCurveTo); - P(inC1); - P(inC2); - P(inDest); - } - - void NVRenderPathSpecification::ClosePath() - { - // we should actually query the backend for command converesion - // but will we support any other pather render system than nv path? - StaticAssert::valid_expression(); - - m_PathCommands.push_back(NVRenderPathCommands::Close); - } - - NVRenderPathSpecification * - NVRenderPathSpecification::CreatePathSpecification(NVRenderContextImpl &context) - { - QT3DS_ASSERT(context.IsPathRenderingSupported()); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderPathSpecification)(context, context.GetFoundation()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderProgramPipeline.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderProgramPipeline.cpp deleted file mode 100644 index b0a9f271..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderProgramPipeline.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderProgramPipeline.h" -#include "render/Qt3DSRenderShaderProgram.h" - -namespace qt3ds { -namespace render { - - NVRenderProgramPipeline::NVRenderProgramPipeline(NVRenderContextImpl &context, - NVFoundationBase &fnd) - : m_Context(context) - , m_Foundation(fnd) - , m_Backend(context.GetBackend()) - , mRefCount(0) - , m_Program(NULL) - , m_VertexProgram(NULL) - , m_FragmentProgram(NULL) - , m_TessControlProgram(NULL) - , m_TessEvalProgram(NULL) - , m_GeometryProgram(NULL) - , m_ComputProgram(NULL) - { - m_ProgramPipelineHandle = m_Backend->CreateProgramPipeline(); - } - - NVRenderProgramPipeline::~NVRenderProgramPipeline() - { - if (m_ProgramPipelineHandle) { - m_Backend->ReleaseProgramPipeline(m_ProgramPipelineHandle); - } - - if (m_VertexProgram) - m_VertexProgram->release(); - if (m_FragmentProgram) - m_FragmentProgram->release(); - if (m_TessControlProgram) - m_TessControlProgram->release(); - if (m_TessEvalProgram) - m_TessEvalProgram->release(); - if (m_GeometryProgram) - m_GeometryProgram->release(); - } - - bool NVRenderProgramPipeline::IsValid() { return (m_ProgramPipelineHandle != NULL); } - - void NVRenderProgramPipeline::SetProgramStages(NVRenderShaderProgram *inProgram, - NVRenderShaderTypeFlags flags) - { - bool bDirty = false; - - if (flags & NVRenderShaderTypeValue::Vertex && inProgram != m_VertexProgram) { - if (m_VertexProgram) - m_VertexProgram->release(); - if (inProgram) - inProgram->addRef(); - m_VertexProgram = inProgram; - bDirty = true; - } - if (flags & NVRenderShaderTypeValue::Fragment && inProgram != m_FragmentProgram) { - if (m_FragmentProgram) - m_FragmentProgram->release(); - if (inProgram) - inProgram->addRef(); - m_FragmentProgram = inProgram; - bDirty = true; - } - if (flags & NVRenderShaderTypeValue::TessControl && inProgram != m_TessControlProgram) { - if (m_TessControlProgram) - m_TessControlProgram->release(); - if (inProgram) - inProgram->addRef(); - m_TessControlProgram = inProgram; - bDirty = true; - } - if (flags & NVRenderShaderTypeValue::TessEvaluation && inProgram != m_TessEvalProgram) { - if (m_TessEvalProgram) - m_TessEvalProgram->release(); - if (inProgram) - inProgram->addRef(); - m_TessEvalProgram = inProgram; - bDirty = true; - } - if (flags & NVRenderShaderTypeValue::Geometry && inProgram != m_GeometryProgram) { - if (m_GeometryProgram) - m_GeometryProgram->release(); - if (inProgram) - inProgram->addRef(); - m_GeometryProgram = inProgram; - bDirty = true; - } - - if (bDirty) { - m_Backend->SetProgramStages(m_ProgramPipelineHandle, flags, - (inProgram) ? inProgram->GetShaderProgramHandle() : NULL); - } - } - - void NVRenderProgramPipeline::Bind() - { - m_Backend->SetActiveProgramPipeline(m_ProgramPipelineHandle); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderQueryBase.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderQueryBase.cpp deleted file mode 100644 index f13bc499..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderQueryBase.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderQueryBase.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSFoundation.h" - -namespace qt3ds { -namespace render { - - NVRenderQueryBase::NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - { - m_QueryHandle = m_Backend->CreateQuery(); - } - - NVRenderQueryBase::~NVRenderQueryBase() - { - if (m_QueryHandle) - m_Backend->ReleaseQuery(m_QueryHandle); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRasterizerState.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRasterizerState.cpp deleted file mode 100644 index e7daf7f4..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRasterizerState.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderRasterizerState.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderRasterizerState::NVRenderRasterizerState(NVRenderContextImpl &context, - NVFoundationBase &fnd, QT3DSF32 depthBias, - QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - { - // create backend handle - m_StateHandle = m_Backend->CreateRasterizerState(depthBias, depthScale, cullFace); - } - - NVRenderRasterizerState::~NVRenderRasterizerState() - { - if (m_StateHandle) { - m_Backend->ReleaseRasterizerState(m_StateHandle); - m_Context.StateDestroyed(*this); - } - } - - NVRenderRasterizerState *NVRenderRasterizerState::Create(NVRenderContextImpl &context, - QT3DSF32 depthBias, QT3DSF32 depthScale, - NVRenderFaces::Enum cullFace) - { - return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderRasterizerState)( - context, context.GetFoundation(), depthBias, depthScale, cullFace); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRenderBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRenderBuffer.cpp deleted file mode 100644 index b682bc1b..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderRenderBuffer.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSFoundation.h" - -namespace qt3ds { -namespace render { - - NVRenderRenderBuffer::NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderRenderBufferFormats::Enum format, - QT3DSU32 width, QT3DSU32 height) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_Width(width) - , m_Height(height) - , m_StorageFormat(format) - , m_BufferHandle(NULL) - { - SetDimensions(NVRenderRenderBufferDimensions(width, height)); - } - - NVRenderRenderBuffer::~NVRenderRenderBuffer() - { - m_Context.RenderBufferDestroyed(*this); - m_Backend->ReleaseRenderbuffer(m_BufferHandle); - m_BufferHandle = 0; - } - - void NVRenderRenderBuffer::SetDimensions(const NVRenderRenderBufferDimensions &inDimensions) - { - QT3DSU32 maxWidth, maxHeight; - m_Width = inDimensions.m_Width; - m_Height = inDimensions.m_Height; - - // get max size and clamp to max value - m_Context.getMaxTextureSize(maxWidth, maxHeight); - if (m_Width > maxWidth || m_Height > maxHeight) { - qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", - maxWidth, maxHeight); - m_Width = NVMin(m_Width, maxWidth); - m_Height = NVMin(m_Height, maxHeight); - } - - bool success = true; - - if (m_BufferHandle == NULL) - m_BufferHandle = m_Backend->CreateRenderbuffer(m_StorageFormat, m_Width, m_Height); - else - success = - m_Backend->ResizeRenderbuffer(m_BufferHandle, m_StorageFormat, m_Width, m_Height); - - if (m_BufferHandle == NULL || !success) { - // We could try smaller sizes - QT3DS_ASSERT(false); - qCCritical(INTERNAL_ERROR, "Unable to create render buffer %s, %dx%d", - NVRenderRenderBufferFormats::toString(m_StorageFormat), m_Width, - m_Height); - } - } -} -} - -qt3ds::render::NVRenderRenderBuffer * -qt3ds::render::NVRenderRenderBuffer::Create(NVRenderContextImpl &context, - NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, - QT3DSU32 height) -{ - NVRenderRenderBuffer *retval = NULL; - if (width == 0 || height == 0) { - qCCritical(INVALID_PARAMETER, "Invalid renderbuffer width or height"); - return retval; - } - - retval = QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderRenderBuffer)(context, context.GetFoundation(), format, width, height); - - return retval; -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSampler.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSampler.cpp deleted file mode 100644 index b02fc615..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSampler.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSDataRef.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderSampler.h" - -namespace qt3ds { -namespace render { - - NVRenderTextureSampler::NVRenderTextureSampler( - NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, - NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, - NVRenderTextureCoordOp::Enum wrapR, NVRenderTextureSwizzleMode::Enum swizzleMode, - QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, NVRenderTextureCompareMode::Enum compareMode, - NVRenderTextureCompareOp::Enum compareFunc, QT3DSF32 anisotropy, QT3DSF32 *borderColor) - : m_MinFilter(minFilter) - , m_MagFilter(magFilter) - , m_WrapS(wrapS) - , m_WrapT(wrapT) - , m_WrapR(wrapR) - , m_SwizzleMode(swizzleMode) - , m_MinLod(minLod) - , m_MaxLod(maxLod) - , m_LodBias(lodBias) - , m_CompareMode(compareMode) - , m_CompareOp(compareFunc) - , m_Anisotropy(anisotropy) - , m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_SamplerHandle(NULL) - { - // create backend handle - m_SamplerHandle = m_Backend->CreateSampler(); - - if (borderColor) { - m_BorderColor[0] = borderColor[0]; - m_BorderColor[1] = borderColor[1]; - m_BorderColor[2] = borderColor[2]; - m_BorderColor[3] = borderColor[3]; - } - } - - NVRenderTextureSampler::~NVRenderTextureSampler() - { - if (m_SamplerHandle) - m_Backend->ReleaseSampler(m_SamplerHandle); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp deleted file mode 100644 index 09f1094b..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp +++ /dev/null @@ -1,1248 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "render/Qt3DSRenderVertexShader.h" -#include "render/Qt3DSRenderFragmentShader.h" -#include "render/Qt3DSRenderTessellationShader.h" -#include "render/Qt3DSRenderGeometryShader.h" -#include "render/Qt3DSRenderComputeShader.h" -#include "render/Qt3DSRenderImageTexture.h" - -namespace qt3ds { -namespace render { - - template - struct ShaderConstantApplier - { - bool force_compile_error; - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32 &inValue, - QT3DSI32 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_2 &inValue, - QT3DSI32_2 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue.x); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_3 &inValue, - QT3DSI32_3 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue.x); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_4 &inValue, - QT3DSI32_4 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue.x); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - const QT3DSRenderBool inValue, QT3DSRenderBool &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_2 &inValue, - bool_2 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_3 &inValue, - bool_3 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_4 &inValue, - bool_4 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSF32 &inValue, - QT3DSF32 &oldValue) - { - if (count > 1 || !(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec2 &inValue, - QT3DSVec2 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec3 &inValue, - QT3DSVec3 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec4 &inValue, - QT3DSVec4 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32 &inValue, - QT3DSU32 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_2 &inValue, - QT3DSU32_2 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue.x); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_3 &inValue, - QT3DSU32_3 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue.x); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_4 &inValue, - QT3DSU32_4 &oldValue) - { - if (!(inValue == oldValue)) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - &inValue.x); - oldValue = inValue; - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat33 inValue, - QT3DSMat33 &, bool inTranspose) - { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - inValue.front(), inTranspose); - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat44 inValue, - QT3DSMat44 &, bool inTranspose) - { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - inValue.front(), inTranspose); - } - - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVConstDataRef inValue, QT3DSMat44 &, bool inTranspose) - { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, - reinterpret_cast(inValue.begin()), - inTranspose); - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVRenderTexture2DPtr inValue, QT3DSU32 &oldValue) - { - if (inValue) { - NVRenderTexture2D *texObj = reinterpret_cast(inValue); - texObj->Bind(); - QT3DSU32 texUnit = texObj->GetTextureUnit(); - if (texUnit != oldValue) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, - count, &texUnit); - oldValue = texUnit; - } - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, - QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVRenderTexture2DHandle inValue, QVector &oldValue) - { - Q_UNUSED(type) - if (inValue) { - bool update = false; - for (int i = 0; i < count; i++) { - NVRenderTexture2D *texObj = reinterpret_cast(inValue[i]); - QT3DSU32 texUnit = QT3DS_MAX_U32; - if (texObj) { - texObj->Bind(); - texUnit = texObj->GetTextureUnit(); - } - if (texUnit != oldValue[i]) { - update = true; - oldValue[i] = texUnit; - } - } - if (update) - backend->SetConstantValue(program->GetShaderProgramHandle(), location, - NVRenderShaderDataTypes::NVRenderTexture2DPtr, - count, oldValue.data()); - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVRenderTexture2DArrayPtr inValue, QT3DSU32 &oldValue) - { - if (inValue) { - NVRenderTexture2DArray *texObj = - reinterpret_cast(inValue); - texObj->Bind(); - QT3DSU32 texUnit = texObj->GetTextureUnit(); - if (texUnit != oldValue) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, - count, &texUnit); - oldValue = texUnit; - } - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVRenderTextureCubePtr inValue, QT3DSU32 &oldValue) - { - if (inValue) { - NVRenderTextureCube *texObj = reinterpret_cast(inValue); - texObj->Bind(); - QT3DSU32 texUnit = texObj->GetTextureUnit(); - if (texUnit != oldValue) { - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, - count, &texUnit); - oldValue = texUnit; - } - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, - QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVRenderTextureCubeHandle inValue, QVector &oldValue) - { - Q_UNUSED(type) - if (inValue) { - bool update = false; - for (int i = 0; i < count; i++) { - NVRenderTextureCube *texObj = reinterpret_cast(inValue[i]); - QT3DSU32 texUnit = QT3DS_MAX_U32; - if (texObj) { - texObj->Bind(); - texUnit = texObj->GetTextureUnit(); - } - if (texUnit != oldValue[i]) { - update = true; - oldValue[i] = texUnit; - } - } - if (update) - backend->SetConstantValue(program->GetShaderProgramHandle(), location, - NVRenderShaderDataTypes::NVRenderTextureCubePtr, - count, oldValue.data()); - } - } - }; - - template <> - struct ShaderConstantApplier - { - void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, - QT3DSI32 count, NVRenderShaderDataTypes::Enum type, - NVRenderImage2DPtr inValue, QT3DSU32 &oldValue, QT3DSI32 binding) - { - if (inValue) { - NVRenderImage2D *imgObj = reinterpret_cast(inValue); - imgObj->Bind(binding); - QT3DSU32 texUnit = imgObj->GetTextureUnit(); - if (texUnit != oldValue) { - // on ES we need a explicit binding value - QT3DS_ASSERT(backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS - || binding != -1); - // this is not allowed on ES 3+ for image types - if (backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS) - backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, - count, &texUnit); - - oldValue = texUnit; - } - } - } - }; - - NVRenderShaderProgram::NVRenderShaderProgram(NVRenderContextImpl &context, - NVFoundationBase &fnd, const char *programName, - bool separableProgram) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_ProgramName(programName) - , m_ProgramHandle(NULL) - , m_Constants(context.GetFoundation().getAllocator(), "NVRenderShaderProgram::m_Constants") - , m_ShaderBuffers(context.GetFoundation().getAllocator(), - "NVRenderShaderProgram::m_ShaderBuffers") - , m_ProgramType(ProgramType::Graphics) - { - m_ProgramHandle = m_Backend->CreateShaderProgram(separableProgram); - - QT3DS_ASSERT(m_ProgramHandle); - } - - NVRenderShaderProgram::~NVRenderShaderProgram() - { - m_Context.ShaderDestroyed(*this); - - if (m_ProgramHandle) - m_Backend->ReleaseShaderProgram(m_ProgramHandle); - - for (TShaderConstantMap::iterator iter = m_Constants.begin(), end = m_Constants.end(); - iter != end; ++iter) { - iter->second->Release(); - } - - m_Constants.clear(); - - for (TShaderBufferMap::iterator iter = m_ShaderBuffers.begin(), end = m_ShaderBuffers.end(); - iter != end; ++iter) { - iter->second->Release(); - } - - m_ShaderBuffers.clear(); - - m_ProgramHandle = NULL; - } - - template - void NVRenderShaderProgram::Attach(TShaderObject *pShader) - { - m_Backend->AttachShader(m_ProgramHandle, pShader->GetShaderHandle()); - } - - template - void NVRenderShaderProgram::Detach(TShaderObject *pShader) - { - m_Backend->DetachShader(m_ProgramHandle, pShader->GetShaderHandle()); - } - - static NVRenderShaderConstantBase * - ShaderConstantFactory(NVRenderBackend *backend, CRegisteredString inName, - NVFoundationBase &alloc, QT3DSI32 uniLoc, QT3DSI32 elementCount, - NVRenderShaderDataTypes::Enum inConstantType, QT3DSI32 binding) - { - switch (inConstantType) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(nv) \ - case NVRenderShaderDataTypes::nv: \ - return QT3DS_NEW(alloc.getAllocator(), NVRenderShaderConstant)( \ - backend, inName, uniLoc, elementCount, inConstantType, binding, alloc); - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return NULL; - } - - template - static NVRenderShaderBufferBase * - ShaderBufferFactory(NVRenderContextImpl &context, CRegisteredString inName, - NVFoundationBase &alloc, QT3DSI32 cbLoc, QT3DSI32 cbBinding, QT3DSI32 cbSize, - QT3DSI32 cbCount, TBufferDataType *pBuffer) - { - return QT3DS_NEW(alloc.getAllocator(), TShaderBufferType)(context, inName, cbLoc, cbBinding, - cbSize, cbCount, pBuffer, alloc); - } - - bool NVRenderShaderProgram::Link() - { - bool success = m_Backend->LinkProgram(m_ProgramHandle, m_ErrorMessage); - - if (success) { - char nameBuf[512]; - QT3DSI32 location, elementCount, binding; - NVRenderShaderDataTypes::Enum type; - - QT3DSI32 constantCount = m_Backend->GetConstantCount(m_ProgramHandle); - - QT3DS_FOREACH(idx, constantCount) - { - location = m_Backend->GetConstantInfoByID(m_ProgramHandle, idx, 512, &elementCount, - &type, &binding, nameBuf); - - // sampler arrays have different type - if (type == NVRenderShaderDataTypes::NVRenderTexture2DPtr && elementCount > 1) { - type = NVRenderShaderDataTypes::NVRenderTexture2DHandle; - } else if (type == NVRenderShaderDataTypes::NVRenderTextureCubePtr - && elementCount > 1) { - type = NVRenderShaderDataTypes::NVRenderTextureCubeHandle; - } - if (location != -1) { - CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); - m_Constants.insert(eastl::make_pair( - theName, - ShaderConstantFactory(m_Backend, theName, m_Context.GetFoundation(), - location, elementCount, type, binding))); - } - } - - // next query constant buffers info - QT3DSI32 length, bufferSize, paramCount; - QT3DSI32 constantBufferCount = m_Backend->GetConstantBufferCount(m_ProgramHandle); - QT3DS_FOREACH(idx, constantBufferCount) - { - location = m_Backend->GetConstantBufferInfoByID( - m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); - - if (location != -1) { - CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); - - // find constant buffer in our DB - NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(theName); - if (cb) { - cb->SetupBuffer(this, location, bufferSize, paramCount); - cb->addRef(); - } - - m_ShaderBuffers.insert(eastl::make_pair( - theName, - ShaderBufferFactory( - m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize, - paramCount, cb))); - } - } - - // next query storage buffers - QT3DSI32 storageBufferCount = m_Backend->GetStorageBufferCount(m_ProgramHandle); - QT3DS_FOREACH(idx, storageBufferCount) - { - location = m_Backend->GetStorageBufferInfoByID( - m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); - - if (location != -1) { - CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); - - // find constant buffer in our DB - NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(theName); - if (sb) { - sb->addRef(); - } - - m_ShaderBuffers.insert(eastl::make_pair( - theName, - ShaderBufferFactory( - m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize, - paramCount, sb))); - } - } - - // next query atomic counter buffers - QT3DSI32 atomicBufferCount = m_Backend->GetAtomicCounterBufferCount(m_ProgramHandle); - QT3DS_FOREACH(idx, atomicBufferCount) - { - location = m_Backend->GetAtomicCounterBufferInfoByID( - m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); - - if (location != -1) { - CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); - - // find atomic counter buffer in our DB - // The buffer itself is not used in the program itself. - // Instead uniform variables are used but the interface to set the value is like - // for buffers. - // This is a bit insane but that is how it is. - // The theName variable contains the uniform name associated with an atomic - // counter buffer. - // We get the actual buffer name by searching for this uniform name - // See NVRenderTestAtomicCounterBuffer.cpp how the setup works - NVRenderAtomicCounterBuffer *acb = - m_Context.GetAtomicCounterBufferByParam(theName); - if (acb) { - acb->addRef(); - - m_ShaderBuffers.insert(eastl::make_pair( - acb->GetBufferName(), - ShaderBufferFactory( - m_Context, acb->GetBufferName(), m_Context.GetFoundation(), - location, -1, bufferSize, paramCount, acb))); - } - } - } - } - - return success; - } - - void NVRenderShaderProgram::GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage) - { - *messageLength = m_ErrorMessage.size(); - errorMessage = m_ErrorMessage.c_str(); - } - - const char *NVRenderShaderProgram::GetErrorMessage() { return m_ErrorMessage.c_str(); } - - NVRenderShaderConstantBase *NVRenderShaderProgram::GetShaderConstant(const char *constantName) - { - TShaderConstantMap::iterator theIter = - m_Constants.find(m_Context.GetStringTable().RegisterStr(constantName)); - - if (theIter != m_Constants.end()) { - NVRenderShaderConstantBase *theConstant = - static_cast(theIter->second); - return theConstant; - } - - return NULL; - } - - NVRenderShaderBufferBase *NVRenderShaderProgram::GetShaderBuffer(const char *bufferName) - { - TShaderBufferMap::iterator theIter = - m_ShaderBuffers.find(m_Context.GetStringTable().RegisterStr(bufferName)); - - if (theIter != m_ShaderBuffers.end()) { - return theIter->second; - } - - return NULL; - } - - NVRenderContextImpl &NVRenderShaderProgram::GetRenderContext() { return m_Context; } - - template - void SetConstantValueOfType(NVRenderShaderProgram *program, - NVRenderShaderConstantBase *inConstantBase, - const TDataType &inValue, const QT3DSI32 inCount) - { - if (inConstantBase == NULL) { - QT3DS_ASSERT(false); - return; - } - - QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); - - if (inConstantBase->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - NVRenderShaderConstant *inConstant = - static_cast *>(inConstantBase); - ShaderConstantApplier().ApplyConstant( - program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, - inValue, inConstant->m_Value); - } else { - QT3DS_ASSERT(false); - } - } - - template - void SetSamplerConstantValueOfType(NVRenderShaderProgram *program, - NVRenderShaderConstantBase *inConstantBase, - const TDataType &inValue, const QT3DSI32 inCount) - { - if (inConstantBase == NULL) { - QT3DS_ASSERT(false); - return; - } - - QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); - - if (inConstantBase->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - NVRenderShaderConstant *inConstant = - static_cast *>(inConstantBase); - ShaderConstantApplier().ApplyConstant( - program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, - inValue, inConstant->m_Value, inConstant->m_Binding); - } else { - QT3DS_ASSERT(false); - } - } - - template - void SetMatrixConstantValueOfType(NVRenderShaderProgram *program, - NVRenderShaderConstantBase *inConstantBase, - const TDataType &inValue, const QT3DSI32 inCount, - bool inTranspose) - { - if (inConstantBase == NULL) { - QT3DS_ASSERT(false); - return; - } - - QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); - - if (inConstantBase->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - NVRenderShaderConstant *inConstant = - static_cast *>(inConstantBase); - ShaderConstantApplier().ApplyConstant( - program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, - inValue, inConstant->m_Value, inTranspose); - } else { - QT3DS_ASSERT(false); - } - } - - template - void SetMatrixConstantValueOfType(NVRenderShaderProgram *program, - NVRenderShaderConstantBase *inConstantBase, - const NVConstDataRef inValue, - const QT3DSI32 /*inCount*/, bool inTranspose) - { - if (inConstantBase == NULL) { - QT3DS_ASSERT(false); - return; - } - - QT3DS_ASSERT(inConstantBase->m_ElementCount >= (QT3DSI32)inValue.size()); - - if (inConstantBase->GetShaderConstantType() - == NVDataTypeToShaderDataTypeMap::GetType()) { - NVRenderShaderConstant *inConstant = - static_cast *>(inConstantBase); - ShaderConstantApplier().ApplyConstant( - program, inConstant->m_Backend, inConstant->m_Location, inValue.size(), - inConstant->m_Type, inValue, inConstant->m_Value, inTranspose); - } else { - QT3DS_ASSERT(false); - } - } - - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - QT3DSI32 inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSI32_2 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSI32_3 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSI32_4 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - QT3DSRenderBool inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const bool_2 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const bool_3 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const bool_4 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSF32 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSVec2 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSVec3 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSVec4 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSU32 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSU32_2 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSU32_3 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSU32_4 &inValue, const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSMat33 &inValue, const QT3DSI32 inCount, - bool inTranspose) - { - SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const QT3DSMat44 &inValue, const QT3DSI32 inCount, - bool inTranspose) - { - SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - const NVConstDataRef inValue, - const QT3DSI32 inCount) - { - SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, false); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderTexture2D *inValue, const QT3DSI32 inCount) - { - Q_UNUSED(inCount) - SetConstantValueOfType(this, inConstant, inValue, 1); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderTexture2D **inValue, - const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderTexture2DArray *inValue, - const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderTextureCube *inValue, const QT3DSI32 inCount) - { - Q_UNUSED(inCount) - SetConstantValueOfType(this, inConstant, inValue, 1); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderTextureCube **inValue, - const QT3DSI32 inCount) - { - SetConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, - NVRenderImage2D *inValue, const QT3DSI32 inCount) - { - SetSamplerConstantValueOfType(this, inConstant, inValue, inCount); - } - void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *, NVRenderDataBuffer *, - const QT3DSI32) - { - // this is merely a dummy right now - } - - void NVRenderShaderProgram::BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex) - { - NVRenderBackend::NVRenderBackendBufferObject obj(NULL); - if (inBuffer) - obj = inBuffer->GetBuffertHandle(); - m_Backend->ProgramSetStorageBuffer(inIndex, obj); - } - - namespace { - void WriteErrorMessage(NVFoundationBase &fnd, const char *tag, const char *message) - { - Q_UNUSED(fnd) - eastl::string messageData(nonNull(message)); - eastl::vector lines; - for (eastl::string::size_type pos = messageData.find('\n'); pos != eastl::string::npos; - pos = messageData.find('\n')) { - eastl::string line = messageData.substr(0, pos); - messageData.erase(messageData.begin(), messageData.begin() + pos + 1); - if (line.size()) - qCCritical(INVALID_OPERATION, "%s: %s", tag, line.c_str()); - } - } - } - - Option NVRenderShaderProgram::createVertexShader( - NVRenderContextImpl &context, NVConstDataRef vertexShaderSource, bool binaryProgram) - { - if (vertexShaderSource.size() == 0) - return Empty(); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderVertexShader(context, context.GetFoundation(), vertexShaderSource, - binaryProgram)); - } - - Option NVRenderShaderProgram::createFragmentShader( - NVRenderContextImpl &context, NVConstDataRef fragmentShaderSource, bool binaryProgram) - { - if (fragmentShaderSource.size() == 0) - return Empty(); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderFragmentShader(context, context.GetFoundation(), fragmentShaderSource, - binaryProgram)); - } - - Option - NVRenderShaderProgram::createTessControlShader(NVRenderContextImpl &context, - NVConstDataRef tessControlShaderSource, - bool binaryProgram) - { - if (tessControlShaderSource.size() == 0) - return Empty(); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderTessControlShader(context, context.GetFoundation(), - tessControlShaderSource, binaryProgram)); - } - - Option - NVRenderShaderProgram::createTessEvaluationShader(NVRenderContextImpl &context, - NVConstDataRef tessControlShaderSource, - bool binaryProgram) - { - if (tessControlShaderSource.size() == 0) - return Empty(); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderTessEvaluationShader(context, context.GetFoundation(), - tessControlShaderSource, binaryProgram)); - } - - Option NVRenderShaderProgram::createGeometryShader( - NVRenderContextImpl &context, NVConstDataRef geometryShaderSource, bool binaryProgram) - { - if (geometryShaderSource.size() == 0) - return Empty(); - - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderGeometryShader(context, context.GetFoundation(), geometryShaderSource, - binaryProgram)); - } - - NVRenderVertFragCompilationResult NVRenderShaderProgram::Create( - NVRenderContextImpl &context, const char *programName, - NVConstDataRef vertShaderSource, NVConstDataRef fragShaderSource, - NVConstDataRef tessControlShaderSource, - NVConstDataRef tessEvaluationShaderSource, NVConstDataRef geometryShaderSource, - bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) - { - NVRenderVertFragCompilationResult result; - NVRenderShaderProgram *pProgram = NULL; - bool bProgramIsValid = false; - - result.mShaderName = programName; - - // our minimum requirement is a vertex and a fragment shader or geometry shader - // if we should treat it as a separate program we don't care - if (!separateProgram - && (vertShaderSource.size() == 0 - || (fragShaderSource.size() == 0 && geometryShaderSource.size() == 0))) { - qCCritical(INVALID_PARAMETER, - "Vertex or fragment (geometry) source have 0 length"); - QT3DS_ASSERT(false); - return result; - } - - if (binaryProgram && type != NVRenderShaderProgramBinaryType::NVBinary) { - qCCritical(INVALID_PARAMETER, "Unrecoginzed binary format"); - QT3DS_ASSERT(false); - return result; - } - - // first create and compile shader - Option vtxShader = - createVertexShader(context, vertShaderSource, binaryProgram); - Option fragShader = - createFragmentShader(context, fragShaderSource, binaryProgram); - Option tcShader = - createTessControlShader(context, tessControlShaderSource, binaryProgram); - Option teShader = - createTessEvaluationShader(context, tessEvaluationShaderSource, binaryProgram); - Option geShader = - createGeometryShader(context, geometryShaderSource, binaryProgram); - - bool vertexValid = (vtxShader.hasValue()) ? vtxShader.getValue()->IsValid() : true; - bool fragValid = (fragShader.hasValue()) ? fragShader.getValue()->IsValid() : true; - bool tcValid = (tcShader.hasValue()) ? tcShader.getValue()->IsValid() : true; - bool teValid = (teShader.hasValue()) ? teShader.getValue()->IsValid() : true; - bool geValid = (geShader.hasValue()) ? geShader.getValue()->IsValid() : true; - - if (vertexValid && fragValid && tcValid && teValid && geValid) { - // shaders were succesfuly created - pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)( - context, context.GetFoundation(), programName, separateProgram); - - if (pProgram) { - // attach programs - if (vtxShader.hasValue() && vtxShader.getValue()->IsValid()) - pProgram->Attach(vtxShader.getValue()); - if (fragShader.hasValue() && fragShader.getValue()->IsValid()) - pProgram->Attach(fragShader.getValue()); - if (tcShader.hasValue() && tcShader.getValue()->IsValid()) - pProgram->Attach(tcShader.getValue()); - if (teShader.hasValue() && teShader.getValue()->IsValid()) - pProgram->Attach(teShader.getValue()); - if (geShader.hasValue() && geShader.getValue()->IsValid()) - pProgram->Attach(geShader.getValue()); - - // link program - bProgramIsValid = pProgram->Link(); - } - } - - // if anything went wrong print out - if (!vertexValid || !fragValid || !tcValid || !teValid || !geValid || !bProgramIsValid) { - NVFoundationBase &foundation(context.GetFoundation()); - - if (!vertexValid) { - qCCritical(INTERNAL_ERROR, "Failed to generate vertex shader!!"); - qCCritical(INTERNAL_ERROR, "Vertex source:\n%s", - nonNull((const char *)vertShaderSource.begin())); - WriteErrorMessage(foundation, "Vertex compilation output:", - vtxShader.getValue()->GetErrorMessage()); - } - - if (!fragValid) { - qCCritical(INTERNAL_ERROR, "Failed to generate fragment shader!!"); - qCCritical(INTERNAL_ERROR, "Fragment source:\n%s", - nonNull((const char *)fragShaderSource.begin())); - WriteErrorMessage(foundation, "Fragment compilation output:", - fragShader.getValue()->GetErrorMessage()); - } - - if (!tcValid) { - qCCritical(INTERNAL_ERROR, - "Failed to generate tessellation control shader!!"); - qCCritical(INTERNAL_ERROR, "Tessellation control source:\n%s", - nonNull((const char *)tessControlShaderSource.begin())); - WriteErrorMessage(foundation, "Tessellation control compilation output:", - tcShader.getValue()->GetErrorMessage()); - } - - if (!teValid) { - qCCritical(INTERNAL_ERROR, - "Failed to generate tessellation evaluation shader!!"); - qCCritical(INTERNAL_ERROR, "Tessellation evaluation source:\n%s", - nonNull((const char *)tessEvaluationShaderSource.begin())); - WriteErrorMessage(foundation, "Tessellation evaluation compilation output:", - teShader.getValue()->GetErrorMessage()); - } - - if (!geValid) { - qCCritical(INTERNAL_ERROR, "Failed to generate geometry shader!!"); - qCCritical(INTERNAL_ERROR, "Geometry source:\n%s", - nonNull((const char *)geometryShaderSource.begin())); - WriteErrorMessage(foundation, "Geometry compilation output:", - geShader.getValue()->GetErrorMessage()); - } - - if (!bProgramIsValid && pProgram) { - qCCritical(INTERNAL_ERROR, "Failed to link program!!"); - WriteErrorMessage(foundation, "Program link output:", pProgram->GetErrorMessage()); - - // delete program - QT3DS_FREE(context.GetFoundation().getAllocator(), pProgram); - pProgram = NULL; - } - } - - // clean up - if (vtxShader.hasValue()) { - if (bProgramIsValid && vtxShader.getValue()->IsValid()) - pProgram->Detach(vtxShader.getValue()); - QT3DS_FREE(context.GetFoundation().getAllocator(), vtxShader.getValue()); - } - if (fragShader.hasValue()) { - if (bProgramIsValid && fragShader.getValue()->IsValid()) - pProgram->Detach(fragShader.getValue()); - QT3DS_FREE(context.GetFoundation().getAllocator(), fragShader.getValue()); - } - if (tcShader.hasValue()) { - if (bProgramIsValid && tcShader.getValue()->IsValid()) - pProgram->Detach(tcShader.getValue()); - QT3DS_FREE(context.GetFoundation().getAllocator(), tcShader.getValue()); - } - if (teShader.hasValue()) { - if (bProgramIsValid && teShader.getValue()->IsValid()) - pProgram->Detach(teShader.getValue()); - QT3DS_FREE(context.GetFoundation().getAllocator(), teShader.getValue()); - } - if (geShader.hasValue()) { - if (bProgramIsValid && geShader.getValue()->IsValid()) - pProgram->Detach(geShader.getValue()); - QT3DS_FREE(context.GetFoundation().getAllocator(), geShader.getValue()); - } - - // set program - result.mShader = pProgram; - - return result; - } - - NVRenderVertFragCompilationResult - NVRenderShaderProgram::CreateCompute(NVRenderContextImpl &context, const char *programName, - NVConstDataRef computeShaderSource) - { - NVRenderVertFragCompilationResult result; - NVRenderShaderProgram *pProgram = NULL; - bool bProgramIsValid = true; - - result.mShaderName = programName; - - // check source - if (computeShaderSource.size() == 0) { - qCCritical(INVALID_PARAMETER, "compute source has 0 length"); - QT3DS_ASSERT(false); - return result; - } - - NVRenderComputeShader computeShader(context, context.GetFoundation(), computeShaderSource, - false); - - if (computeShader.IsValid()) { - // shaders were succesfuly created - pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)( - context, context.GetFoundation(), programName, false); - - if (pProgram) { - // attach programs - pProgram->Attach(&computeShader); - - // link program - bProgramIsValid = pProgram->Link(); - - // set program type - pProgram->SetProgramType(ProgramType::Compute); - } - } - - // if anything went wrong print out - if (!computeShader.IsValid() || !bProgramIsValid) { - NVFoundationBase &foundation(context.GetFoundation()); - - if (!computeShader.IsValid()) { - qCCritical(INTERNAL_ERROR, "Failed to generate compute shader!!"); - qCCritical(INTERNAL_ERROR, "Vertex source:\n%s", - nonNull((const char *)computeShaderSource.begin())); - WriteErrorMessage(foundation, "Compute shader compilation output:", - computeShader.GetErrorMessage()); - } - } - - // set program - result.mShader = pProgram; - - return result; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderStorageBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderStorageBuffer.cpp deleted file mode 100644 index ab632189..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderStorageBuffer.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderStorageBuffer.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" - -namespace qt3ds { -namespace render { - - NVRenderStorageBuffer::NVRenderStorageBuffer(NVRenderContextImpl &context, - CRegisteredString bufferName, size_t size, - NVRenderBufferUsageType::Enum usageType, - NVDataRef data, NVRenderDataBuffer *pBuffer) - : NVRenderDataBuffer(context, context.GetFoundation(), size, - NVRenderBufferBindValues::Storage, usageType, data) - , m_Name(bufferName) - , m_WrappedBuffer(pBuffer) - , m_Dirty(true) - { - QT3DS_ASSERT(context.IsStorageBufferSupported()); - - if (pBuffer) - pBuffer->addRef(); - } - - NVRenderStorageBuffer::~NVRenderStorageBuffer() - { - if (m_WrappedBuffer) - m_WrappedBuffer->release(); - - m_Context.BufferDestroyed(*this); - } - - void NVRenderStorageBuffer::Bind() - { - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); - QT3DS_ASSERT(false); - } - - if (m_WrappedBuffer) - m_WrappedBuffer->Bind(); - else - m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); - } - - void NVRenderStorageBuffer::BindToShaderProgram(QT3DSU32 index) - { - m_Backend->ProgramSetStorageBuffer( - index, (m_WrappedBuffer) ? m_WrappedBuffer->GetBuffertHandle() : m_BufferHandle); - } - - void NVRenderStorageBuffer::Update() - { - // we only update the buffer if it is dirty and we actually have some data - if (m_Dirty && m_BufferData.size()) { - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, - m_BufferData.begin()); - m_Dirty = false; - } - } - - void NVRenderStorageBuffer::UpdateData(QT3DSI32 offset, NVDataRef data) - { - // we only update the buffer if it is not just a wrapper - if (!m_WrappedBuffer) - m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, - data.begin() + offset); - } - - NVRenderStorageBuffer * - NVRenderStorageBuffer::Create(NVRenderContextImpl &context, const char *bufferName, - NVRenderBufferUsageType::Enum usageType, size_t size, - NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) - { - NVFoundationBase &fnd(context.GetFoundation()); - NVRenderStorageBuffer *retval = NULL; - - if (context.IsStorageBufferSupported()) { - CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); - QT3DSU32 cbufSize = sizeof(NVRenderStorageBuffer); - QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "StorageBuffer"); - retval = new (newMem) NVRenderStorageBuffer( - context, theBufferName, size, usageType, - toDataRef(const_cast(bufferData.begin()), bufferData.size()), pBuffer); - } else { - QString errorMsg = QObject::tr("Shader storage buffers are not supported: %1") - .arg(bufferName); - qCCritical(INVALID_OPERATION) << errorMsg; - QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); - } - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSync.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSync.cpp deleted file mode 100644 index 02d153a6..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderSync.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderSync.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSFoundation.h" - -namespace qt3ds { -namespace render { - - NVRenderSync::NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_SyncHandle(NULL) - { - } - - NVRenderSync::~NVRenderSync() - { - if (m_SyncHandle) - m_Backend->ReleaseSync(m_SyncHandle); - } - - void NVRenderSync::Sync() - { - // On every sync call we need to create a new sync object - // A sync object can only be used once - - // First delete the old object - // We can safely do this because it is actually not deleted until - // it is unused - if (m_SyncHandle) - m_Backend->ReleaseSync(m_SyncHandle); - - m_SyncHandle = - m_Backend->CreateSync(NVRenderSyncType::GpuCommandsComplete, NVRenderSyncFlags()); - } - - void NVRenderSync::Wait() - { - // wait until the sync object is signaled or a timeout happens - if (m_SyncHandle) - m_Backend->WaitSync(m_SyncHandle, NVRenderCommandFlushFlags(), 0); - } - - NVRenderSync *NVRenderSync::Create(NVRenderContextImpl &context) - { - if (!context.IsCommandSyncSupported()) - return NULL; - - NVRenderSync *retval = QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderSync)(context, context.GetFoundation()); - - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTessellationShader.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTessellationShader.cpp deleted file mode 100644 index 7a0fd897..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTessellationShader.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderTessellationShader.h" - -namespace qt3ds { -namespace render { - - NVRenderTessControlShader::NVRenderTessControlShader(NVRenderContextImpl &context, - NVFoundationBase &fnd, - NVConstDataRef source, - bool binaryProgram) - : NVRenderShader(context, fnd, source, binaryProgram) - , m_ShaderHandle(NULL) - { - m_ShaderHandle = m_Backend->CreateTessControlShader(source, m_ErrorMessage, binaryProgram); - } - - NVRenderTessControlShader::~NVRenderTessControlShader() - { - if (m_ShaderHandle) { - m_Backend->ReleaseTessControlShader(m_ShaderHandle); - } - } - - NVRenderTessEvaluationShader::NVRenderTessEvaluationShader(NVRenderContextImpl &context, - NVFoundationBase &fnd, - NVConstDataRef source, - bool binaryProgram) - : NVRenderShader(context, fnd, source, binaryProgram) - , m_ShaderHandle(NULL) - { - m_ShaderHandle = - m_Backend->CreateTessEvaluationShader(source, m_ErrorMessage, binaryProgram); - } - - NVRenderTessEvaluationShader::~NVRenderTessEvaluationShader() - { - if (m_ShaderHandle) { - m_Backend->ReleaseTessEvaluationShader(m_ShaderHandle); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2D.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2D.cpp deleted file mode 100644 index c5ea4750..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2D.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderSampler.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderTexture2D::NVRenderTexture2D(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget) - : NVRenderTextureBase(context, fnd, texTarget) - , m_Width(0) - , m_Height(0) - { - } - - NVRenderTexture2D::~NVRenderTexture2D() { m_Context.TextureDestroyed(*this); } - - STextureDetails NVRenderTexture2D::GetTextureDetails() const - { - return STextureDetails(m_Width, m_Height, 0, m_SampleCount, m_Format); - } - - void NVRenderTexture2D::SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, - QT3DSU32 height, NVRenderTextureFormats::Enum format, - NVRenderTextureFormats::Enum formatDest) - { - QT3DS_ASSERT(m_TextureHandle); - - // check if we should compress this texture - - if (inMipLevel == 0) { - m_Width = width; - m_Height = height; - m_Format = format; - - // We re-use textures and this might have been a MSAA texture before - // for resue we must completely destroy the texture object and create a new one - // The same is true for immutable textures - if (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS || m_Immutable) { - m_Backend->ReleaseTexture(m_TextureHandle); - m_TexTarget = NVRenderTextureTargetType::Texture2D; - m_SampleCount = 1; - m_TextureHandle = m_Backend->CreateTexture(); - } - - if (NVRenderTextureFormats::isCompressedTextureFormat(formatDest)) { - bool compress = NVRenderTextureFormats::isUncompressedTextureFormat(format); - bool appropriateSizes = ((width % 4) || (height % 4)) == false; - - // we only compress multiple of 4 textures - if (compress && !appropriateSizes) - compress = false; - - if (compress) { - // This seems like a very dubious line here. If we are compressing then the - // image - // is really 1/4 the width and height? - CN - m_Width = width / 4; - m_Height = height / 4; - m_Format = formatDest; - } - } else if (NVRenderTextureFormats::isUncompressedTextureFormat(formatDest)) { - m_Format = formatDest; - } - } - - if (m_MaxMipLevel < inMipLevel) { - m_MaxMipLevel = inMipLevel; - } - - // get max size and check value - QT3DSU32 maxWidth, maxHeight; - m_Context.getMaxTextureSize(maxWidth, maxHeight); - if (width > maxWidth || height > maxHeight) { - qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", - maxWidth, maxHeight); - } - if (NVRenderTextureFormats::isUncompressedTextureFormat(format) - || NVRenderTextureFormats::isDepthTextureFormat(format)) { - m_Backend->SetTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width, - height, 0, format, newBuffer.begin()); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) { - m_Backend->SetCompressedTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, format, - width, height, 0, newBuffer.size(), - newBuffer.begin()); - } - // Set our texture parameters to a default that will look the best - if (inMipLevel > 0) - SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - } - - void NVRenderTexture2D::SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum formaInternal, - NVRenderTextureFormats::Enum format, - NVDataRef dataBuffer) - { - QT3DS_ASSERT(m_TextureHandle); - - if (!m_Context.IsShaderImageLoadStoreSupported()) { - qCCritical(INVALID_OPERATION, "The extension Shader_Image_Load_Store is not supported"); - return; - } - - m_Width = width; - m_Height = height; - m_Format = formaInternal; - if (format == NVRenderTextureFormats::Unknown) - format = formaInternal; - - // get max size and check value - QT3DSU32 maxWidth, maxHeight; - m_Context.getMaxTextureSize(maxWidth, maxHeight); - if (width > maxWidth || height > maxHeight) { - qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", - maxWidth, maxHeight); - } - - if (inLevels < 1) { - qCCritical(INVALID_PARAMETER, "inLevels is less than 1 (%d)", inLevels); - } - - m_MaxMipLevel = inLevels - 1; // we count from 0 - - // only uncompressed formats are supported and no depth - if (NVRenderTextureFormats::isUncompressedTextureFormat(formaInternal)) { - m_Backend->CreateTextureStorage2D(m_TextureHandle, m_TexTarget, inLevels, formaInternal, - width, height); - - m_Immutable = true; - m_TexTarget = NVRenderTextureTargetType::Texture2D; - - if (dataBuffer.size() > 0) - m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, 0, 0, 0, width, height, - format, dataBuffer.begin()); - - if (inLevels > 1) - SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - } - } - - void NVRenderTexture2D::SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum format) - { - QT3DS_ASSERT(m_TextureHandle); - QT3DS_ASSERT(m_MaxMipLevel == 0); - - m_TexTarget = NVRenderTextureTargetType::Texture2D_MS; - - QT3DSU32 maxWidth, maxHeight; - m_Context.getMaxTextureSize(maxWidth, maxHeight); - if (width > maxWidth || height > maxHeight) { - qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", - maxWidth, maxHeight); - } - - QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format) - || NVRenderTextureFormats::isDepthTextureFormat(format)); - - m_Backend->SetMultisampledTextureData2D(m_TextureHandle, m_TexTarget, sampleCount, format, - width, height, true); - - m_Width = width; - m_Height = height; - m_SampleCount = sampleCount; - m_Format = format; - } - - void NVRenderTexture2D::SetTextureSubData(NVDataRef newBuffer, QT3DSU8 inMipLevel, - QT3DSU32 inXOffset, QT3DSU32 inYOffset, QT3DSU32 width, - QT3DSU32 height, NVRenderTextureFormats::Enum format) - { - QT3DS_ASSERT(m_TextureHandle); - - if (!NVRenderTextureFormats::isUncompressedTextureFormat(format)) { - qCCritical(INVALID_PARAMETER, "Cannot set sub data for depth or compressed formats"); - QT3DS_ASSERT(false); - return; - } - QT3DSU32 subRectStride = width * NVRenderTextureFormats::getSizeofFormat(format); - if (newBuffer.size() < subRectStride * height) { - qCCritical(INVALID_PARAMETER, "Invalid sub rect buffer size"); - QT3DS_ASSERT(false); - return; - } - // nop - if (width == 0 || height == 0) - return; - - if (inXOffset + width > m_Width || inYOffset + height > m_Height) { - qCCritical(INVALID_PARAMETER, "Sub rect outside existing image bounds"); - QT3DS_ASSERT(false); - return; - } - - // not handled yet - QT3DS_ASSERT(!NVRenderTextureFormats::isDepthTextureFormat(format)); - - m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, inMipLevel, inXOffset, - inYOffset, width, height, format, newBuffer.begin()); - } - - void NVRenderTexture2D::GenerateMipmaps(NVRenderHint::Enum genType) - { - applyTexParams(); - m_Backend->GenerateMipMaps(m_TextureHandle, m_TexTarget, genType); - QT3DSU32 maxDim = (m_Width >= m_Height) ? m_Width : m_Height; - m_MaxMipLevel = static_cast(logf((float)maxDim) / logf(2.0f)); - // we never create more level than m_MaxLevel - m_MaxMipLevel = qt3ds::NVMin(m_MaxMipLevel, (QT3DSU32)m_MaxLevel); - } - - void NVRenderTexture2D::Bind() - { - m_TextureUnit = m_Context.GetNextTextureUnit(); - - m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); - - applyTexParams(); - applyTexSwizzle(); - } - - NVRenderTexture2D *NVRenderTexture2D::Create(NVRenderContextImpl &context) - { - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderTexture2D)(context, context.GetFoundation()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2DArray.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2DArray.cpp deleted file mode 100644 index fc0dfa45..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTexture2DArray.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderSampler.h" -#include "render/Qt3DSRenderTexture2DArray.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderTexture2DArray::NVRenderTexture2DArray(NVRenderContextImpl &context, - NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget) - : NVRenderTextureBase(context, fnd, texTarget) - , m_Width(0) - , m_Height(0) - , m_Slices(0) - { - } - - NVRenderTexture2DArray::~NVRenderTexture2DArray() { m_Context.TextureDestroyed(*this); } - - void NVRenderTexture2DArray::SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, - QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, - NVRenderTextureFormats::Enum format) - { - QT3DS_ASSERT(m_TextureHandle); - - if (inMipLevel == 0) { - m_Width = width; - m_Height = height; - m_Slices = slices; - m_Format = format; - m_MaxMipLevel = inMipLevel; - } - - if (m_MaxMipLevel < inMipLevel) { - m_MaxMipLevel = inMipLevel; - } - - // get max size and check value - QT3DSI32 theMaxLayerSize, theMaxSize; - m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, - &theMaxSize); - m_Backend->GetRenderBackendValue( - NVRenderBackend::NVRenderBackendQuery::MaxTextureArrayLayers, &theMaxLayerSize); - if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize - || slices > (QT3DSU32)theMaxLayerSize) { - qCCritical(INVALID_OPERATION, - "Width or height or Slices is greater than max texture size (%d, %d, %d)", - theMaxSize, theMaxSize, theMaxLayerSize); - } - - // currently we do not support compressed texture arrays - QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format) - || NVRenderTextureFormats::isDepthTextureFormat(format)); - - if (NVRenderTextureFormats::isUncompressedTextureFormat(format) - || NVRenderTextureFormats::isDepthTextureFormat(format)) { - m_Backend->SetTextureData3D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width, - height, slices, 0, format, newBuffer.begin()); - } - - // Set our texture parameters to a default that will look the best - if (inMipLevel > 0) - SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - } - - STextureDetails NVRenderTexture2DArray::GetTextureDetails() const - { - return STextureDetails(m_Width, m_Height, m_Slices, m_SampleCount, m_Format); - } - - void NVRenderTexture2DArray::Bind() - { - m_TextureUnit = m_Context.GetNextTextureUnit(); - - m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); - - applyTexParams(); - applyTexSwizzle(); - } - - NVRenderTexture2DArray *NVRenderTexture2DArray::Create(NVRenderContextImpl &context) - { - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderTexture2DArray)(context, context.GetFoundation()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureBase.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureBase.cpp deleted file mode 100644 index d055d72c..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureBase.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderSampler.h" -#include "render/Qt3DSRenderTextureBase.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderTextureBase::NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget) - : m_Context(context) - , m_Foundation(fnd) - , mRefCount(0) - , m_Backend(context.GetBackend()) - , m_TextureHandle(NULL) - , m_TextureUnit(QT3DS_MAX_U32) - , m_SamplerParamsDirty(true) - , m_TexStateDirty(false) - , m_SampleCount(1) - , m_Format(NVRenderTextureFormats::Unknown) - , m_TexTarget(texTarget) - , m_BaseLevel(0) - , m_MaxLevel(1000) - , m_MaxMipLevel(0) - , m_Immutable(false) - { - m_TextureHandle = m_Backend->CreateTexture(); - m_Sampler = QT3DS_NEW(m_Context.GetFoundation().getAllocator(), - NVRenderTextureSampler)(context, context.GetFoundation()); - } - - NVRenderTextureBase::~NVRenderTextureBase() - { - if (m_Sampler) - QT3DS_FREE(m_Context.GetFoundation().getAllocator(), m_Sampler); - if (m_TextureHandle) - m_Backend->ReleaseTexture(m_TextureHandle); - } - - void NVRenderTextureBase::SetBaseLevel(QT3DSI32 value) - { - if (m_BaseLevel != value) { - m_BaseLevel = value; - m_TexStateDirty = true; - } - } - - void NVRenderTextureBase::SetMaxLevel(QT3DSI32 value) - { - if (m_MaxLevel != value) { - m_MaxLevel = value; - m_TexStateDirty = true; - } - } - - void NVRenderTextureBase::SetMinFilter(NVRenderTextureMinifyingOp::Enum value) - { - if (m_Sampler->m_MinFilter != value) { - m_Sampler->m_MinFilter = value; - m_SamplerParamsDirty = true; - } - } - - void NVRenderTextureBase::SetMagFilter(NVRenderTextureMagnifyingOp::Enum value) - { - if (m_Sampler->m_MagFilter != value) { - m_Sampler->m_MagFilter = value; - m_SamplerParamsDirty = true; - } - } - - void NVRenderTextureBase::SetTextureWrapS(NVRenderTextureCoordOp::Enum value) - { - if (m_Sampler->m_WrapS != value) { - m_Sampler->m_WrapS = value; - m_SamplerParamsDirty = true; - } - } - - void NVRenderTextureBase::SetTextureWrapT(NVRenderTextureCoordOp::Enum value) - { - if (m_Sampler->m_WrapT != value) { - m_Sampler->m_WrapT = value; - m_SamplerParamsDirty = true; - } - } - - void NVRenderTextureBase::SetTextureCompareMode(NVRenderTextureCompareMode::Enum value) - { - if (m_Sampler->m_CompareMode != value) { - m_Sampler->m_CompareMode = value; - m_SamplerParamsDirty = true; - } - } - - void NVRenderTextureBase::SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value) - { - if (m_Sampler->m_CompareOp != value) { - m_Sampler->m_CompareOp = value; - m_SamplerParamsDirty = true; - } - } - - void NVRenderTextureBase::applyTexParams() - { - if (m_SamplerParamsDirty) { - m_Backend->UpdateSampler(m_Sampler->GetSamplerHandle(), m_TexTarget, - m_Sampler->m_MinFilter, m_Sampler->m_MagFilter, - m_Sampler->m_WrapS, m_Sampler->m_WrapT, m_Sampler->m_WrapR, - m_Sampler->m_MinLod, m_Sampler->m_MaxLod, m_Sampler->m_LodBias, - m_Sampler->m_CompareMode, m_Sampler->m_CompareOp); - - m_SamplerParamsDirty = false; - } - - if (m_TexStateDirty) { - m_Backend->UpdateTextureObject(m_TextureHandle, m_TexTarget, m_BaseLevel, m_MaxLevel); - m_TexStateDirty = false; - } - } - - void NVRenderTextureBase::applyTexSwizzle() - { - NVRenderTextureSwizzleMode::Enum theSwizzleMode = - m_Backend->GetTextureSwizzleMode(m_Format); - if (theSwizzleMode != m_Sampler->m_SwizzleMode) { - m_Sampler->m_SwizzleMode = theSwizzleMode; - m_Backend->UpdateTextureSwizzle(m_TextureHandle, m_TexTarget, theSwizzleMode); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureCube.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureCube.cpp deleted file mode 100644 index 0919daf3..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTextureCube.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/vector.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderSampler.h" -#include "render/Qt3DSRenderTextureCube.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - NVRenderTextureCube::NVRenderTextureCube(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVRenderTextureTargetType::Enum texTarget) - : NVRenderTextureBase(context, fnd, texTarget) - , m_Width(0) - , m_Height(0) - { - } - - NVRenderTextureCube::~NVRenderTextureCube() { m_Context.TextureDestroyed(*this); } - - void NVRenderTextureCube::SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, - NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, - QT3DSU32 height, NVRenderTextureFormats::Enum format) - { - QT3DS_ASSERT(m_TextureHandle); - QT3DS_ASSERT(inFace != NVRenderTextureCubeFaces::InvalidFace); - - if (inMipLevel == 0) { - m_Width = width; - m_Height = height; - m_Format = format; - m_MaxMipLevel = inMipLevel; - } - - if (m_MaxMipLevel < inMipLevel) { - m_MaxMipLevel = inMipLevel; - } - - // get max size and check value - QT3DSI32 theMaxSize; - m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, - &theMaxSize); - if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize) { - qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", - theMaxSize, theMaxSize); - } - - NVRenderTextureTargetType::Enum outTarget = - static_cast((int)m_TexTarget + (int)inFace); - if (NVRenderTextureFormats::isUncompressedTextureFormat(format) - || NVRenderTextureFormats::isDepthTextureFormat(format)) { - m_Backend->SetTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, format, width, - height, 0, format, newBuffer.begin()); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) { - m_Backend->SetCompressedTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, - format, width, height, 0, newBuffer.size(), - newBuffer.begin()); - } - - // Set our texture parameters to a default that will look the best - if (inMipLevel > 0) - SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - } - - STextureDetails NVRenderTextureCube::GetTextureDetails() const - { - return STextureDetails(m_Width, m_Height, 6, m_SampleCount, m_Format); - } - - void NVRenderTextureCube::Bind() - { - m_TextureUnit = m_Context.GetNextTextureUnit(); - - m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); - - applyTexParams(); - applyTexSwizzle(); - } - - NVRenderTextureCube *NVRenderTextureCube::Create(NVRenderContextImpl &context) - { - return QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderTextureCube)(context, context.GetFoundation()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTimerQuery.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTimerQuery.cpp deleted file mode 100644 index 4184436a..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderTimerQuery.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderTimerQuery.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - - NVRenderTimerQuery::NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd) - : NVRenderQueryBase(context, fnd) - { - } - - NVRenderTimerQuery::~NVRenderTimerQuery() {} - - void NVRenderTimerQuery::Begin() - { - m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Timer); - } - - void NVRenderTimerQuery::End() { m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Timer); } - - void NVRenderTimerQuery::GetResult(QT3DSU32 *params) - { - m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); - } - - void NVRenderTimerQuery::GetResult(QT3DSU64 *params) - { - m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); - } - - void NVRenderTimerQuery::SetTimerQuery() { m_Backend->SetQueryTimer(m_QueryHandle); } - - NVRenderTimerQuery *NVRenderTimerQuery::Create(NVRenderContextImpl &context) - { - if (!context.IsTimerQuerySupported()) - return NULL; - - NVRenderTimerQuery *retval = QT3DS_NEW(context.GetFoundation().getAllocator(), - NVRenderTimerQuery)(context, context.GetFoundation()); - - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexBuffer.cpp deleted file mode 100644 index 89d6204e..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexBuffer.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - NVRenderVertexBuffer::NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, - QT3DSU32 stride, NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usageType, - NVDataRef data) - : NVRenderDataBuffer(context, context.GetFoundation(), size, bindFlags, usageType, data) - , m_Stride(stride) - { - QT3DS_ASSERT(m_Stride); - } - - NVRenderVertexBuffer::~NVRenderVertexBuffer() { m_Context.BufferDestroyed(*this); } - - void NVRenderVertexBuffer::Bind() - { - if (m_Mapped) { - qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); - QT3DS_ASSERT(false); - } - - m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); - } - - NVRenderVertexBuffer *NVRenderVertexBuffer::Create(NVRenderContextImpl &context, - NVRenderBufferUsageType::Enum usageType, - size_t size, QT3DSU32 stride, - NVConstDataRef bufferData) - { - NVFoundationBase &fnd(context.GetFoundation()); - - QT3DSU32 vbufSize = sizeof(NVRenderVertexBuffer); - QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), vbufSize, "VertexBuffer"); - NVRenderVertexBuffer *retval = new (newMem) NVRenderVertexBuffer( - context, size, stride, NVRenderBufferBindValues::Vertex, usageType, - toDataRef(const_cast(bufferData.begin()), bufferData.size())); - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexShader.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexShader.cpp deleted file mode 100644 index 3a53ad50..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderVertexShader.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderVertexShader.h" - -namespace qt3ds { -namespace render { - - NVRenderVertexShader::NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd, - NVConstDataRef source, bool binaryProgram) - : NVRenderShader(context, fnd, source, binaryProgram) - , m_ShaderHandle(NULL) - { - m_ShaderHandle = m_Backend->CreateVertexShader(source, m_ErrorMessage, binaryProgram); - } - - NVRenderVertexShader::~NVRenderVertexShader() - { - if (m_ShaderHandle) { - m_Backend->ReleaseVertexShader(m_ShaderHandle); - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp deleted file mode 100644 index d38c330c..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp +++ /dev/null @@ -1,887 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/backends/gl/Q3DSRenderBackendGLES2.h" -#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" -#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" -#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" - -#ifdef RENDER_BACKEND_LOG_GL_ERRORS -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) -#else -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() -#endif - -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) -#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_MULTISAMPLE_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_EXTENSION_FUNCTION(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#else -#define GL_CALL_TIMER_EXT(x) -#define GL_CALL_TESSELATION_EXT(x) -#define GL_CALL_MULTISAMPLE_EXT(x) -#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_EXTENSION_FUNCTION(x) -#endif - -#ifndef GL_DEPTH_STENCIL_OES -#define GL_DEPTH_STENCIL_OES 0x84F9 -#endif - -namespace qt3ds { -namespace render { - -/// constructor -NVRenderBackendGLES2Impl::NVRenderBackendGLES2Impl(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format) - : NVRenderBackendGLBase(fnd, stringTable, format) -{ - QString exts3tc = QStringLiteral("GL_EXT_texture_compression_s3tc"); - QString extsdxt = QStringLiteral("GL_EXT_texture_compression_dxt1"); - QString extsAniso = QStringLiteral("GL_EXT_texture_filter_anisotropic"); - QString extsTexSwizzle = QStringLiteral("GL_ARB_texture_swizzle"); - QString extsFPRenderTarget = QStringLiteral("GL_EXT_color_buffer_float"); - QString extsTimerQuery = QStringLiteral("GL_EXT_timer_query"); - QString extsGpuShader5 = QStringLiteral("EXT_gpu_shader5"); - QString extDepthTexture = QStringLiteral("GL_OES_packed_depth_stencil"); - QString extvao = QStringLiteral("GL_OES_vertex_array_object"); - QString extStdDd = QStringLiteral("GL_OES_standard_derivatives"); - QString extTexLod = QStringLiteral("GL_EXT_shader_texture_lod"); - - const char *languageVersion = GetShadingLanguageVersion(); - qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); - - eastl::string apiVersion(getVersionString()); - qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); - - eastl::string apiVendor(getVendorString()); - qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); - - eastl::string apiRenderer(getRendererString()); - qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); - - // clear support bits - m_backendSupport.caps.u32Values = 0; - - const char *extensions = getExtensionString(); - m_extensions = QString::fromLocal8Bit(extensions).split(" "); - - // get extension count - GLint numExtensions = m_extensions.size(); - - for (QT3DSI32 i = 0; i < numExtensions; i++) { - - const QString &extensionString = m_extensions.at(i); - - // search for extension - if (!m_backendSupport.caps.bits.bDXTImagesSupported - && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { - m_backendSupport.caps.bits.bDXTImagesSupported = true; - } else if (!m_backendSupport.caps.bits.bAnistropySupported - && extsAniso.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bAnistropySupported = true; - } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported - && extsFPRenderTarget.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; - } else if (!m_backendSupport.caps.bits.bTimerQuerySupported - && extsTimerQuery.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bTimerQuerySupported = true; - } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported - && extsGpuShader5.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; - } else if (!m_backendSupport.caps.bits.bTextureSwizzleSupported - && extsTexSwizzle.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bTextureSwizzleSupported = true; - } else if (!m_backendSupport.caps.bits.bDepthStencilSupported - && extDepthTexture.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bDepthStencilSupported = true; - } else if (!m_backendSupport.caps.bits.bVertexArrayObjectSupported - && extvao.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; - } else if (!m_backendSupport.caps.bits.bStandardDerivativesSupported - && extStdDd.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bStandardDerivativesSupported = true; - } else if (!m_backendSupport.caps.bits.bTextureLodSupported - && extTexLod.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bTextureLodSupported = true; - } - } - - qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensions); - - // constant buffers support is always not true - m_backendSupport.caps.bits.bConstantBufferSupported = false; - - // query hardware - GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); - - // internal state tracker - m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); - - // finally setup caps based on device - setAndInspectHardwareCaps(); - - // Initialize extensions -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) - m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; - m_qt3dsExtensions->initializeOpenGLFunctions(); -#endif -} -/// destructor -NVRenderBackendGLES2Impl::~NVRenderBackendGLES2Impl() -{ - if (m_pCurrentMiscState) - NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) - if (m_qt3dsExtensions) - delete m_qt3dsExtensions; -#endif -} - -void NVRenderBackendGLES2Impl::SetMultisampledTextureData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, - bool fixedsamplelocations) -{ - NVRENDER_BACKEND_UNUSED(to); - NVRENDER_BACKEND_UNUSED(target); - NVRENDER_BACKEND_UNUSED(samples); - NVRENDER_BACKEND_UNUSED(internalFormat); - NVRENDER_BACKEND_UNUSED(width); - NVRENDER_BACKEND_UNUSED(height); - NVRENDER_BACKEND_UNUSED(fixedsamplelocations); -} - -void NVRenderBackendGLES2Impl::SetTextureData3D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, - QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) -{ - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - bool conversionRequired = format != internalFormat; - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - } - - if (conversionRequired) { - GLenum dummy; - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, dummy); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - } - - GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, - (GLsizei)height, (GLsizei)depth, border, glformat, - gltype, hostPtr)); - - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); -} - -void NVRenderBackendGLES2Impl::SetTextureData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, const void *hostPtr) -{ - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - bool conversionRequired = format != internalFormat; - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - glInternalFormat = glformat; - } - - if (conversionRequired) { - GLenum dummy; - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, dummy); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - if (format == NVRenderTextureFormats::Depth24Stencil8) { - glformat = GL_DEPTH_STENCIL_OES; - gltype = GL_UNSIGNED_INT_24_8; - } - glInternalFormat = glformat; - } - - Q_ASSERT(glformat == glInternalFormat); - GL_CALL_EXTRA_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, - (GLsizei)height, border, glformat, gltype, hostPtr)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); -} - -void NVRenderBackendGLES2Impl::UpdateSampler( - NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, - NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, - NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, - NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, - QT3DSF32 anisotropy, QT3DSF32 *borderColor) -{ - - // Satisfy the compiler - // These are not available in GLES 3 and we don't use them right now - QT3DS_ASSERT(lodBias == 0.0); - QT3DS_ASSERT(!borderColor); - NVRENDER_BACKEND_UNUSED(lodBias); - NVRENDER_BACKEND_UNUSED(borderColor); - NVRENDER_BACKEND_UNUSED(wrapR); - NVRENDER_BACKEND_UNUSED(minLod); - NVRENDER_BACKEND_UNUSED(maxLod); - NVRENDER_BACKEND_UNUSED(compareMode); - NVRENDER_BACKEND_UNUSED(compareFunc); - - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, - m_Conversion.fromTextureMinifyingOpToGL(minFilter))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, - m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, - m_Conversion.fromTextureCoordOpToGL(wrapS))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, - m_Conversion.fromTextureCoordOpToGL(wrapT))); - - if (m_backendSupport.caps.bits.bAnistropySupported) { - GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, - anisotropy)); - } -} - -void NVRenderBackendGLES2Impl::UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSI32 baseLevel, QT3DSI32 maxLevel) -{ - NVRENDER_BACKEND_UNUSED(to); - - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); -} - -void NVRenderBackendGLES2Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) -{ - NVRENDER_BACKEND_UNUSED(to); - NVRENDER_BACKEND_UNUSED(target); - NVRENDER_BACKEND_UNUSED(swizzleMode); -#if defined(QT_OPENGL_ES) - if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { - GLint glSwizzle[4]; - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); - - // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); - - } -#endif -} - -QT3DSU32 -NVRenderBackendGLES2Impl::GetDepthBits() const -{ - QT3DSI32 depthBits; - GL_CALL_EXTRA_FUNCTION( - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); - - return depthBits; -} - -QT3DSU32 -NVRenderBackendGLES2Impl::GetStencilBits() const -{ - QT3DSI32 stencilBits; - GL_CALL_EXTRA_FUNCTION( - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - &stencilBits)); - - return stencilBits; -} - -void NVRenderBackendGLES2Impl::GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum /*genType*/) -{ - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); -} - -bool NVRenderBackendGLES2Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, - NVRenderBackendShaderProgramObject po) -{ - if (iao == nullptr) { - // unbind and return; - GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(0)); - return true; - } - - NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; - NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - NVDataRef shaderAttribBuffer; - if (pProgram->m_shaderInput) - shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; - - if ((attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) - || (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot)) { - return false; - } - - if (inputAssembler->m_VaoID == 0) { - // generate vao - GL_CALL_EXTENSION_FUNCTION(glGenVertexArraysOES(1, &inputAssembler->m_VaoID)); - QT3DS_ASSERT(inputAssembler->m_VaoID); - } - - if (inputAssembler->m_cachedShaderHandle != programID) { - GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); - inputAssembler->m_cachedShaderHandle = programID; - - QT3DS_FOREACH(idx, shaderAttribBuffer.size()) - { - const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); - NVRenderBackendLayoutEntryGL *entry = - attribLayout->getEntryByName(attrib.m_AttribName); - - if (entry) { - NVRenderBackendLayoutEntryGL &entryData(*entry); - if (entryData.m_Type != attrib.m_Type - || entryData.m_NumComponents != attrib.m_NumComponents) { - qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", - attrib.m_AttribName.c_str()); - QT3DS_ASSERT(false); - return false; - } else { - entryData.m_AttribIndex = attrib.m_AttribLocation; - } - } else { - qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); - } - } - - // disable max possible used first - // this is currently sufficient since we always re-arrange input attributes from 0 - for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) - GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); - - // setup all attribs - QT3DS_FOREACH(idx, shaderAttribBuffer.size()) - { - NVRenderBackendLayoutEntryGL *entry = - attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); - if (entry) { - const NVRenderBackendLayoutEntryGL &entryData(*entry); - GLuint id = HandleToID_cast( - GLuint, size_t, - inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); - GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); - GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); - GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; - GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; - GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( - entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, - stride, (const void *)(entryData.m_Offset + offset))); - - } else { - GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); - } - } - - // setup index buffer. - if (inputAssembler->m_IndexbufferHandle) { - GL_CALL_EXTRA_FUNCTION(glBindBuffer( - GL_ELEMENT_ARRAY_BUFFER, - HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); - } else { - GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - } else { - GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); - } -#ifdef _DEBUG - if (inputAssembler->m_VaoID) { - QT3DS_FOREACH(idx, shaderAttribBuffer.size()) - { - const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); - NVRenderBackendLayoutEntryGL *entry = - attribLayout->getEntryByName(attrib.m_AttribName); - - if (entry) { - NVRenderBackendLayoutEntryGL &entryData(*entry); - if (entryData.m_Type != attrib.m_Type - || entryData.m_NumComponents != attrib.m_NumComponents - || entryData.m_AttribIndex != attrib.m_AttribLocation) { - qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", - attrib.m_AttribName.c_str()); - QT3DS_ASSERT(false); - } - } else { - qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); - } - } - } -#endif // _DEBUG - - return true; -} - -void NVRenderBackendGLES2Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, - NVConstDataRef inDrawBufferSet) -{ - NVRENDER_BACKEND_UNUSED(rto); - - m_DrawBuffersArray.clear(); - - for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { - if (inDrawBufferSet[idx] < 0) - m_DrawBuffersArray.push_back(GL_NONE); - else - m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); - } - - GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), - m_DrawBuffersArray.data())); -} - -void NVRenderBackendGLES2Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, - NVReadFaces::Enum inReadFace) -{ - NVRENDER_BACKEND_UNUSED(rto); - NVRENDER_BACKEND_UNUSED(inReadFace); -} - -void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, QT3DSI32 level, - QT3DSI32 layer) -{ - NVRENDER_BACKEND_UNUSED(attachment); - NVRENDER_BACKEND_UNUSED(to); - NVRENDER_BACKEND_UNUSED(level); - NVRENDER_BACKEND_UNUSED(layer); - Q_ASSERT(false); -} - -void NVRenderBackendGLES2Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, - QT3DSI32 srcY1, QT3DSI32 dstX0, QT3DSI32 dstY0, - QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) -{ - GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, - dstY1, - m_Conversion.fromClearFlagsToGL(flags), - m_Conversion.fromTextureMagnifyingOpToGL(filter))); -} - - -NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLES2Impl::CreateRenderTarget() -{ - GLuint fboID = 0; - GL_CALL_EXTRA_FUNCTION(glGenFramebuffers(1, &fboID)); - return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; -} - -void NVRenderBackendGLES2Impl::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) -{ - GLuint fboID = HandleToID_cast(GLuint, size_t, rto); - - if (fboID) - GL_CALL_EXTRA_FUNCTION(glDeleteFramebuffers(1, &fboID)); -} - -void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendRenderbufferObject rbo) -{ - // rto must be the current render target - GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); - - GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); - - GL_CALL_EXTRA_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, - rbID)); -} - -void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target) -{ - // rto must be the current render target - GLuint texID = HandleToID_cast(GLuint, size_t, to); - - QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D - || m_backendSupport.caps.bits.bMsTextureSupported); - - GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - if (attachment == NVRenderFrameBufferAttachments::DepthStencil) { - GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - glTarget, texID, 0)); - GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - glTarget, texID, 0)); - } else { - GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, - 0)); - } -} - -void NVRenderBackendGLES2Impl::SetRenderTarget(NVRenderBackendRenderTargetObject rto) -{ - GLuint fboID = HandleToID_cast(GLuint, size_t, rto); - - GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); -} - -void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) -{ - GLuint fboID = HandleToID_cast(GLuint, size_t, rto); - - GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); -} - -bool NVRenderBackendGLES2Impl::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) -{ - GLenum completeStatus = GL_CALL_EXTRA_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); - switch (completeStatus) { -#define HANDLE_INCOMPLETE_STATUS(x) \ - case x: \ - qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ - return false; - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) - #undef HANDLE_INCOMPLETE_STATUS - } - return true; -} - -NVRenderBackend::NVRenderBackendRenderbufferObject -NVRenderBackendGLES2Impl::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) -{ - GLuint bufID = 0; - - GL_CALL_EXTRA_FUNCTION(glGenRenderbuffers(1, &bufID)); - GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); - GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, - GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), - (GLsizei)width, (GLsizei)height)); - - // check for error - GLenum error = m_glFunctions->glGetError(); - if (error != GL_NO_ERROR) { - qCCritical(GL_ERROR, GLConversion::processGLError(error)); - QT3DS_ASSERT(false); - GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); - bufID = 0; - } - - GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); - - return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; -} - -void NVRenderBackendGLES2Impl::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) -{ - GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); - - if (bufID) - GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); -} - -bool NVRenderBackendGLES2Impl::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, - NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) -{ - bool success = true; - GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); - - QT3DS_ASSERT(bufID); - - GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); - GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, - GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), - (GLsizei)width, (GLsizei)height)); - - // check for error - GLenum error = m_glFunctions->glGetError(); - if (error != GL_NO_ERROR) { - qCCritical(GL_ERROR, GLConversion::processGLError(error)); - QT3DS_ASSERT(false); - success = false; - } - - return success; -} - -void *NVRenderBackendGLES2Impl::MapBuffer(NVRenderBackendBufferObject, - NVRenderBufferBindFlags bindFlags, size_t offset, - size_t length, NVRenderBufferAccessFlags accessFlags) -{ - void *ret = nullptr; - ret = GL_CALL_EXTRA_FUNCTION( - glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, - length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); - - return ret; -} - -bool NVRenderBackendGLES2Impl::UnmapBuffer(NVRenderBackendBufferObject, - NVRenderBufferBindFlags bindFlags) -{ - GLboolean ret; - - ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); - - return (ret) ? true : false; -} - -QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) -{ - QT3DS_ASSERT(po); - GLint numUniformBuffers = 0; - if (GetRenderBackendCap(NVRenderBackendCaps::ConstantBuffer)) { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, - &numUniformBuffers)); - } - return numUniformBuffers; -} - -QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferInfoByID( - NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, - QT3DSI32 *paramCount, QT3DSI32 *bufferSize, - QT3DSI32 *length, char *nameBuf) -{ - QT3DS_ASSERT(po); - QT3DS_ASSERT(length); - QT3DS_ASSERT(nameBuf); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - GLuint blockIndex = GL_INVALID_INDEX; - - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, - nameBuf)); - - if (*length > 0) { - blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); - if (blockIndex != GL_INVALID_INDEX) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, - GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, - GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); - } - } - - return blockIndex; -} - -void NVRenderBackendGLES2Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSI32 *indices) -{ - QT3DS_ASSERT(po); - QT3DS_ASSERT(indices); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - if (indices) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, - GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, - indices)); - } -} - -void NVRenderBackendGLES2Impl::GetConstantBufferParamInfoByIndices( - NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) -{ - QT3DS_ASSERT(po); - QT3DS_ASSERT(count); - QT3DS_ASSERT(indices); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - if (count && indices) { - if (type) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, - GL_UNIFORM_TYPE, type)); - // convert to UIC types - QT3DS_FOREACH(idx, count) - { - type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); - } - } - if (size) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, - GL_UNIFORM_SIZE, size)); - } - if (offset) { - GL_CALL_EXTRA_FUNCTION( - glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); - } - } -} - -void NVRenderBackendGLES2Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) -{ - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); -} - -void NVRenderBackendGLES2Impl::ProgramSetConstantBuffer(QT3DSU32 index, - NVRenderBackendBufferObject bo) -{ - QT3DS_ASSERT(bo); - - GLuint bufID = HandleToID_cast(GLuint, size_t, bo); - GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); -} - -NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLES2Impl::CreateQuery() -{ - QT3DSU32 glQueryID = 0; - - return (NVRenderBackendQueryObject)glQueryID; -} - -void NVRenderBackendGLES2Impl::ReleaseQuery(NVRenderBackendQueryObject) -{ - -} - -void NVRenderBackendGLES2Impl::BeginQuery(NVRenderBackendQueryObject, - NVRenderQueryType::Enum) -{ - -} - -void NVRenderBackendGLES2Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) -{ - -} - -void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, - NVRenderQueryResultType::Enum, - QT3DSU32 *) -{ - -} - -void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, - NVRenderQueryResultType::Enum, - QT3DSU64 *) -{ - -} - -void NVRenderBackendGLES2Impl::SetQueryTimer(NVRenderBackendQueryObject) -{ - -} - -NVRenderBackend::NVRenderBackendSyncObject -NVRenderBackendGLES2Impl::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) -{ - GLsync syncID = 0; - return NVRenderBackendSyncObject(syncID); -} - -void NVRenderBackendGLES2Impl::ReleaseSync(NVRenderBackendSyncObject) -{ - -} - -void NVRenderBackendGLES2Impl::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, - QT3DSU64) -{ - -} -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp deleted file mode 100644 index 564ecd5a..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/backends/gl/Qt3DSOpenGLExtensions.h" - -Qt3DSOpenGLExtensions::Qt3DSOpenGLExtensions() - : QAbstractOpenGLExtension(*(new Qt3DSOpenGLExtensionsPrivate)) -{ -} - -bool Qt3DSOpenGLExtensions::initializeOpenGLFunctions() -{ - if (isInitialized()) - return true; - - QT_PREPEND_NAMESPACE(QOpenGLContext) *context = - QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); - if (!context) { - qWarning("A current OpenGL context is required to resolve functions"); - return false; - } - - Q_D(Qt3DSOpenGLExtensions); - - d->BlendBarrierNV = reinterpret_cast( - context->getProcAddress("glBlendBarrierNV")); - d->PathGlyphIndexArrayNV = reinterpret_cast( - context->getProcAddress("glPathGlyphIndexArrayNV")); - d->PathGlyphIndexRangeNV = reinterpret_cast( - context->getProcAddress("glPathGlyphIndexRangeNV")); - QAbstractOpenGLExtension::initializeOpenGLFunctions(); - return true; -} - -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) -Qt3DSOpenGLES2Extensions::Qt3DSOpenGLES2Extensions() -{ -} - -bool Qt3DSOpenGLES2Extensions::initializeOpenGLFunctions() -{ - if (isInitialized()) - return true; - - QT_PREPEND_NAMESPACE(QOpenGLContext) *context = - QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); - if (!context) { - qWarning("A current OpenGL context is required to resolve functions"); - return false; - } - - Q_D(Qt3DSOpenGLExtensions); - -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) - d->PatchParameteriEXT = reinterpret_cast( - context->getProcAddress("glPatchParameteriEXT")); - d->QueryCounterEXT = reinterpret_cast( - context->getProcAddress("glQueryCounterEXT")); - d->GetQueryObjectui64vEXT = reinterpret_cast( - context->getProcAddress("glGetQueryObjectui64vEXT")); - d->GenPathsNV = reinterpret_cast( - context->getProcAddress("glGenPathsNV")); - d->DeletePathsNV = reinterpret_cast( - context->getProcAddress("glDeletePathsNV")); - d->PathCommandsNV = reinterpret_cast( - context->getProcAddress("glPathCommandsNV")); - d->PathGlyphsNV = reinterpret_cast( - context->getProcAddress("glPathGlyphsNV")); - d->PathGlyphRangeNV = reinterpret_cast( - context->getProcAddress("glPathGlyphRangeNV")); - d->PathParameterfNV = reinterpret_cast( - context->getProcAddress("glPathParameterfNV")); - d->PathStencilDepthOffsetNV = reinterpret_cast( - context->getProcAddress("glPathStencilDepthOffsetNV")); - d->StencilFillPathNV = reinterpret_cast( - context->getProcAddress("glStencilFillPathNV")); - d->StencilStrokePathNV = reinterpret_cast( - context->getProcAddress("glStencilStrokePathNV")); - d->StencilFillPathInstancedNV = reinterpret_cast( - context->getProcAddress("glStencilFillPathInstancedNV")); - d->StencilStrokePathInstancedNV - = reinterpret_cast( - context->getProcAddress("glStencilStrokePathInstancedNV")); - d->PathCoverDepthFuncNV = reinterpret_cast( - context->getProcAddress("glPathCoverDepthFuncNV")); - d->CoverFillPathInstancedNV = reinterpret_cast( - context->getProcAddress("glCoverFillPathInstancedNV")); - d->CoverStrokePathInstancedNV = reinterpret_cast( - context->getProcAddress("glCoverStrokePathInstancedNV")); - d->GetPathParameterfvNV = reinterpret_cast( - context->getProcAddress("glGetPathParameterfvNV")); - d->GetPathMetricsNV = reinterpret_cast( - context->getProcAddress("glGetPathMetricsNV")); - d->GetPathMetricRangeNV = reinterpret_cast( - context->getProcAddress("glGetPathMetricRangeNV")); - d->GetPathSpacingNV = reinterpret_cast( - context->getProcAddress("glGetPathSpacingNV")); - d->BindVertexArrayOES = reinterpret_cast( - context->getProcAddress("glBindVertexArrayOES")); - d->DeleteVertexArraysOES = reinterpret_cast( - context->getProcAddress("glDeleteVertexArraysOES")); - d->GenVertexArraysOES = reinterpret_cast( - context->getProcAddress("glGenVertexArraysOES")); - d->IsVertexArrayOES = reinterpret_cast( - context->getProcAddress("glIsVertexArrayOES")); -#endif - Qt3DSOpenGLExtensions::initializeOpenGLFunctions(); - return true; -} -#endif // QT_OPENGL_ES diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp deleted file mode 100644 index d78c51d9..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp +++ /dev/null @@ -1,784 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/backends/gl/Qt3DSRenderBackendGL3.h" -#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" -#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" -#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" - -#ifdef RENDER_BACKEND_LOG_GL_ERRORS -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) -#else -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() -#endif - -#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); - -#if defined(QT_OPENGL_ES) -#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#else -#define GL_CALL_TIMER_EXT(x) m_timerExtension->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_TESSELATION_EXT(x) m_tessellationShader->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_MULTISAMPLE_EXT(x) m_multiSample->x; RENDER_LOG_ERROR_PARAMS(x); -#endif - -namespace qt3ds { -namespace render { - -#ifndef GL_PATCH_VERTICES -#define GL_PATCH_VERTICES 0x8E72 -#endif - - /// constructor - NVRenderBackendGL3Impl::NVRenderBackendGL3Impl(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format) - : NVRenderBackendGLBase(fnd, stringTable, format) - { - eastl::string exts3tc("GL_EXT_texture_compression_s3tc"); - eastl::string extsdxt("GL_EXT_texture_compression_dxt1"); - eastl::string extsAniso("GL_EXT_texture_filter_anisotropic"); - eastl::string extsTexSwizzle("GL_ARB_texture_swizzle"); - eastl::string extsAstcHDR("GL_KHR_texture_compression_astc_hdr"); - eastl::string extsAstcLDR("GL_KHR_texture_compression_astc_ldr"); - eastl::string extsFPRenderTarget("GL_EXT_color_buffer_float"); - eastl::string extsTimerQuery("GL_EXT_timer_query"); - eastl::string extsGpuShader5("EXT_gpu_shader5"); - - const char *languageVersion = GetShadingLanguageVersion(); - qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); - - eastl::string apiVersion(getVersionString()); - qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); - - eastl::string apiVendor(getVendorString()); - qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); - - eastl::string apiRenderer(getRendererString()); - qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); - - // clear support bits - m_backendSupport.caps.u32Values = 0; - - // get extension count - GLint numExtensions = 0; - GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); - - eastl::string extensionBuffer; - - for (QT3DSI32 i = 0; i < numExtensions; i++) { - char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); - - m_extensions.push_back(QString::fromLocal8Bit(extensionString)); - - if (extensionBuffer.size()) - extensionBuffer.append(" "); - extensionBuffer.append(extensionString); - - // search for extension - if (!m_backendSupport.caps.bits.bDXTImagesSupported - && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { - m_backendSupport.caps.bits.bDXTImagesSupported = true; - } else if (!m_backendSupport.caps.bits.bAnistropySupported - && extsAniso.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bAnistropySupported = true; - } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported - && extsFPRenderTarget.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; - } else if (!m_backendSupport.caps.bits.bTimerQuerySupported - && extsTimerQuery.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bTimerQuerySupported = true; - } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported - && extsGpuShader5.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; - } - - } - - qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensionBuffer.c_str()); - - // texture swizzle is always true - m_backendSupport.caps.bits.bTextureSwizzleSupported = true; - // depthstencil renderbuffer support is always true - m_backendSupport.caps.bits.bDepthStencilSupported = true; - // constant buffers support is always true - m_backendSupport.caps.bits.bConstantBufferSupported = true; - m_backendSupport.caps.bits.bStandardDerivativesSupported = true; - m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; - m_backendSupport.caps.bits.bTextureLodSupported = true; - - if (!isESCompatible()) { - // render to float textures is always supported on none ES systems which support >=GL3 - m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; - // multisampled texture is always supported on none ES systems which support >=GL3 - m_backendSupport.caps.bits.bMsTextureSupported = true; - // timer queries are always supported on none ES systems which support >=GL3 - m_backendSupport.caps.bits.bTimerQuerySupported = true; - } - - // query hardware - GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); - - // internal state tracker - m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); - - // finally setup caps based on device - setAndInspectHardwareCaps(); - - // Initialize extensions -#if defined(QT_OPENGL_ES_2) - m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; - m_qt3dsExtensions->initializeOpenGLFunctions(); -#else - m_timerExtension = new QOpenGLExtension_ARB_timer_query; - m_timerExtension->initializeOpenGLFunctions(); - m_tessellationShader = new QOpenGLExtension_ARB_tessellation_shader; - m_tessellationShader->initializeOpenGLFunctions(); - m_multiSample = new QOpenGLExtension_ARB_texture_multisample; - m_multiSample->initializeOpenGLFunctions(); - m_qt3dsExtensions = new Qt3DSOpenGLExtensions; - m_qt3dsExtensions->initializeOpenGLFunctions(); -#endif - } - /// destructor - NVRenderBackendGL3Impl::~NVRenderBackendGL3Impl() - { - if (m_pCurrentMiscState) - NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); -#if !defined(QT_OPENGL_ES_2) - if (m_timerExtension) - delete m_timerExtension; - if (m_tessellationShader) - delete m_tessellationShader; - if (m_multiSample) - delete m_multiSample; -#endif - if (m_qt3dsExtensions) - delete m_qt3dsExtensions; - } - - void NVRenderBackendGL3Impl::SetMultisampledTextureData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, - bool fixedsamplelocations) - { -// Not supported by ES 3 yet -#if defined(QT_OPENGL_ES) - NVRENDER_BACKEND_UNUSED(to); - NVRENDER_BACKEND_UNUSED(target); - NVRENDER_BACKEND_UNUSED(samples); - NVRENDER_BACKEND_UNUSED(internalFormat); - NVRENDER_BACKEND_UNUSED(width); - NVRENDER_BACKEND_UNUSED(height); - NVRENDER_BACKEND_UNUSED(fixedsamplelocations); -#else - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) - GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - - GL_CALL_MULTISAMPLE_EXT(glTexImage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, - (GLsizei)width, (GLsizei)height, fixedsamplelocations)); - - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); -#endif - } - - void NVRenderBackendGL3Impl::SetTextureData3D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, - QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - bool conversionRequired = format != internalFormat; - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - - if (conversionRequired) { - GLenum dummy; - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, dummy); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - - GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, - (GLsizei)depth, border, glformat, gltype, hostPtr)); - - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); - } - - void NVRenderBackendGL3Impl::UpdateSampler( - NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, - NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, - NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, - NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, - QT3DSF32 anisotropy, QT3DSF32 *borderColor) - { - - // Satisfy the compiler - // These are not available in GLES 3 and we don't use them right now - QT3DS_ASSERT(lodBias == 0.0); - QT3DS_ASSERT(!borderColor); - NVRENDER_BACKEND_UNUSED(lodBias); - NVRENDER_BACKEND_UNUSED(borderColor); - - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, - m_Conversion.fromTextureMinifyingOpToGL(minFilter))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, - m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, - m_Conversion.fromTextureCoordOpToGL(wrapS))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, - m_Conversion.fromTextureCoordOpToGL(wrapT))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_R, - m_Conversion.fromTextureCoordOpToGL(wrapR))); - GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MIN_LOD, minLod)); - GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_LOD, maxLod)); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE, - m_Conversion.fromTextureCompareModeToGL(compareMode))); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC, - m_Conversion.fromTextureCompareFuncToGL(compareFunc))); - - if (m_backendSupport.caps.bits.bAnistropySupported) { - GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy)); - } - } - - void NVRenderBackendGL3Impl::UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSI32 baseLevel, QT3DSI32 maxLevel) - { - NVRENDER_BACKEND_UNUSED(to); - - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); - } - - void NVRenderBackendGL3Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) - { - NVRENDER_BACKEND_UNUSED(to); - if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { - GLint glSwizzle[4]; - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); -#if defined(QT_OPENGL_ES) - // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); - GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); -#else - GL_CALL_EXTRA_FUNCTION(glTexParameteriv(glTarget, GL_TEXTURE_SWIZZLE_RGBA, glSwizzle)); -#endif - } - } - - QT3DSU32 - NVRenderBackendGL3Impl::GetDepthBits() const - { - QT3DSI32 depthBits; - GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv( - GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); - - return depthBits; - } - - QT3DSU32 - NVRenderBackendGL3Impl::GetStencilBits() const - { - QT3DSI32 stencilBits; - GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - &stencilBits)); - - return stencilBits; - } - - void NVRenderBackendGL3Impl::GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum /*genType*/) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); - } - - bool NVRenderBackendGL3Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, - NVRenderBackendShaderProgramObject po) - { - if (iao == NULL) { - // unbind and return; - GL_CALL_EXTRA_FUNCTION(glBindVertexArray(0)); - return true; - } - - NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; - NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - NVDataRef shaderAttribBuffer; - if (pProgram->m_shaderInput) - shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; - - if (attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) - return false; - - if (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot) { - QT3DS_ASSERT(false); - return false; - } - - if (inputAssembler->m_VaoID == 0) { - // generate vao - GL_CALL_EXTRA_FUNCTION(glGenVertexArrays(1, &inputAssembler->m_VaoID)); - QT3DS_ASSERT(inputAssembler->m_VaoID); - } - - // set patch parameter count if changed - if (m_backendSupport.caps.bits.bTessellationSupported - && m_pCurrentMiscState->m_PatchVertexCount != inputAssembler->m_PatchVertexCount) { - m_pCurrentMiscState->m_PatchVertexCount = inputAssembler->m_PatchVertexCount; -#if defined(QT_OPENGL_ES) - GL_CALL_TESSELATION_EXT(glPatchParameteriEXT(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); -#else - GL_CALL_TESSELATION_EXT(glPatchParameteri(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); -#endif - } - - if (inputAssembler->m_cachedShaderHandle != programID) { - GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); - inputAssembler->m_cachedShaderHandle = programID; - - QT3DS_FOREACH(idx, shaderAttribBuffer.size()) - { - const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); - NVRenderBackendLayoutEntryGL *entry = - attribLayout->getEntryByName(attrib.m_AttribName); - - if (entry) { - NVRenderBackendLayoutEntryGL &entryData(*entry); - if (entryData.m_Type != attrib.m_Type - || entryData.m_NumComponents != attrib.m_NumComponents) { - qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", - attrib.m_AttribName.c_str()); - QT3DS_ASSERT(false); - return false; - } else { - entryData.m_AttribIndex = attrib.m_AttribLocation; - } - } else { - qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); - } - } - - // disable max possible used first - // this is currently sufficient since we always re-arrange input attributes from 0 - for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) { - GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); - } - - // setup all attribs - QT3DS_FOREACH(idx, shaderAttribBuffer.size()) - { - NVRenderBackendLayoutEntryGL *entry = - attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); - if (entry) { - const NVRenderBackendLayoutEntryGL &entryData(*entry); - GLuint id = HandleToID_cast( - GLuint, size_t, - inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); - GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); - GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); - GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; - GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; - GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( - entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, - stride, (const void *)(entryData.m_Offset + offset))); - - } else { - GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); - } - } - - // setup index buffer. - if (inputAssembler->m_IndexbufferHandle) { - GL_CALL_EXTRA_FUNCTION(glBindBuffer( - GL_ELEMENT_ARRAY_BUFFER, - HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); - } else { - GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - } else { - GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); - } -#ifdef _DEBUG - if (inputAssembler->m_VaoID) { - QT3DS_FOREACH(idx, shaderAttribBuffer.size()) - { - const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); - NVRenderBackendLayoutEntryGL *entry = - attribLayout->getEntryByName(attrib.m_AttribName); - - if (entry) { - NVRenderBackendLayoutEntryGL &entryData(*entry); - if (entryData.m_Type != attrib.m_Type - || entryData.m_NumComponents != attrib.m_NumComponents - || entryData.m_AttribIndex != attrib.m_AttribLocation) { - qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", - attrib.m_AttribName.c_str()); - QT3DS_ASSERT(false); - } - } else { - qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); - } - } - } -#endif // _DEBUG - - return true; - } - - void NVRenderBackendGL3Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, - NVConstDataRef inDrawBufferSet) - { - NVRENDER_BACKEND_UNUSED(rto); - - m_DrawBuffersArray.clear(); - - for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { - if (inDrawBufferSet[idx] < 0) - m_DrawBuffersArray.push_back(GL_NONE); - else - m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); - } - - GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), m_DrawBuffersArray.data())); - } - - void NVRenderBackendGL3Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, - NVReadFaces::Enum inReadFace) - { - NVRENDER_BACKEND_UNUSED(rto); - - GL_CALL_EXTRA_FUNCTION(glReadBuffer(m_Conversion.fromReadFacesToGL(inReadFace))); - } - - void NVRenderBackendGL3Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, QT3DSI32 level, - QT3DSI32 layer) - { - // rto must be the current render target - GLuint texID = HandleToID_cast(GLuint, size_t, to); - - GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); - - GL_CALL_EXTRA_FUNCTION(glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttach, texID, level, layer)) - } - - void NVRenderBackendGL3Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) - { - GLuint fboID = HandleToID_cast(GLuint, size_t, rto); - - GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); - } - - void NVRenderBackendGL3Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, - QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, - NVRenderClearFlags flags, - NVRenderTextureMagnifyingOp::Enum filter) - { - GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - m_Conversion.fromClearFlagsToGL(flags), - m_Conversion.fromTextureMagnifyingOpToGL(filter))); - } - - void *NVRenderBackendGL3Impl::MapBuffer(NVRenderBackendBufferObject, - NVRenderBufferBindFlags bindFlags, size_t offset, - size_t length, NVRenderBufferAccessFlags accessFlags) - { - void *ret = NULL; - ret = GL_CALL_EXTRA_FUNCTION(glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, - length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); - - return ret; - } - - bool NVRenderBackendGL3Impl::UnmapBuffer(NVRenderBackendBufferObject, - NVRenderBufferBindFlags bindFlags) - { - GLboolean ret; - - ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); - - return (ret) ? true : false; - } - - QT3DSI32 NVRenderBackendGL3Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) - { - QT3DS_ASSERT(po); - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GLint numUniformBuffers; - GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBuffers)); - - return numUniformBuffers; - } - - QT3DSI32 - NVRenderBackendGL3Impl::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, - QT3DSI32 *paramCount, QT3DSI32 *bufferSize, - QT3DSI32 *length, char *nameBuf) - { - QT3DS_ASSERT(po); - QT3DS_ASSERT(length); - QT3DS_ASSERT(nameBuf); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - GLuint blockIndex = GL_INVALID_INDEX; - - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, nameBuf)); - - if (*length > 0) { - blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); - if (blockIndex != GL_INVALID_INDEX) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, - GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, - GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); - } - } - - return blockIndex; - } - - void - NVRenderBackendGL3Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSI32 *indices) - { - QT3DS_ASSERT(po); - QT3DS_ASSERT(indices); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - if (indices) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, - GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices)); - } - } - - void NVRenderBackendGL3Impl::GetConstantBufferParamInfoByIndices( - NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) - { - QT3DS_ASSERT(po); - QT3DS_ASSERT(count); - QT3DS_ASSERT(indices); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - if (count && indices) { - if (type) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_TYPE, type)); - // convert to UIC types - QT3DS_FOREACH(idx, count) - { - type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); - } - } - if (size) { - GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_SIZE, size)); - } - if (offset) { - GL_CALL_EXTRA_FUNCTION( - glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); - } - } - } - - void NVRenderBackendGL3Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); - } - - void NVRenderBackendGL3Impl::ProgramSetConstantBuffer(QT3DSU32 index, - NVRenderBackendBufferObject bo) - { - QT3DS_ASSERT(bo); - - GLuint bufID = HandleToID_cast(GLuint, size_t, bo); - GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); - } - - NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGL3Impl::CreateQuery() - { - QT3DSU32 glQueryID = 0; - - GL_CALL_EXTRA_FUNCTION(glGenQueries(1, &glQueryID)); - - return (NVRenderBackendQueryObject)glQueryID; - } - - void NVRenderBackendGL3Impl::ReleaseQuery(NVRenderBackendQueryObject qo) - { - GLuint queryID = HandleToID_cast(GLuint, size_t, qo); - - GL_CALL_EXTRA_FUNCTION(glDeleteQueries(1, &queryID)); - } - - void NVRenderBackendGL3Impl::BeginQuery(NVRenderBackendQueryObject qo, - NVRenderQueryType::Enum type) - { - GLuint queryID = HandleToID_cast(GLuint, size_t, qo); - - GL_CALL_EXTRA_FUNCTION(glBeginQuery(m_Conversion.fromQueryTypeToGL(type), queryID)); - } - - void NVRenderBackendGL3Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum type) - { - GL_CALL_EXTRA_FUNCTION(glEndQuery(m_Conversion.fromQueryTypeToGL(type))); - } - - void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, - QT3DSU32 *params) - { - GLuint queryID = HandleToID_cast(GLuint, size_t, qo); - - if (params) - GL_CALL_EXTRA_FUNCTION(glGetQueryObjectuiv( - queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); - } - - void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, - NVRenderQueryResultType::Enum resultType, - QT3DSU64 *params) - { - if (m_backendSupport.caps.bits.bTimerQuerySupported) { - GLuint queryID = HandleToID_cast(GLuint, size_t, qo); - - if (params) -#if defined(QT_OPENGL_ES) - GL_CALL_TIMER_EXT(glGetQueryObjectui64vEXT( - queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); -#else - GL_CALL_TIMER_EXT(glGetQueryObjectui64v( - queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); -#endif - } - } - - void NVRenderBackendGL3Impl::SetQueryTimer(NVRenderBackendQueryObject qo) - { - if (m_backendSupport.caps.bits.bTimerQuerySupported) { - GLuint queryID = HandleToID_cast(GLuint, size_t, qo); -#if defined(QT_OPENGL_ES) - GL_CALL_TIMER_EXT(glQueryCounterEXT(queryID, GL_TIMESTAMP_EXT)); -#else - GL_CALL_TIMER_EXT(glQueryCounter(queryID, GL_TIMESTAMP)); -#endif - } - } - - NVRenderBackend::NVRenderBackendSyncObject - NVRenderBackendGL3Impl::CreateSync(NVRenderSyncType::Enum syncType, NVRenderSyncFlags) - { - GLsync syncID = 0; - - syncID = GL_CALL_EXTRA_FUNCTION(glFenceSync(m_Conversion.fromSyncTypeToGL(syncType), 0)); - - return NVRenderBackendSyncObject(syncID); - } - - void NVRenderBackendGL3Impl::ReleaseSync(NVRenderBackendSyncObject so) - { - GLsync syncID = (GLsync)so; - - GL_CALL_EXTRA_FUNCTION(glDeleteSync(syncID)); - } - - void NVRenderBackendGL3Impl::WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags, - QT3DSU64) - { - GLsync syncID = (GLsync)so; - - GL_CALL_EXTRA_FUNCTION(glWaitSync(syncID, 0, GL_TIMEOUT_IGNORED)); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp deleted file mode 100644 index 083fc35e..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp +++ /dev/null @@ -1,875 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/backends/gl/Qt3DSRenderBackendGL4.h" -#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" -#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" - -#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; - -#ifdef RENDER_BACKEND_LOG_GL_ERRORS -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) -#else -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() -#endif - -#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); - -#if defined(QT_OPENGL_ES) -#define GL_CALL_NVPATH_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#else -#define GL_CALL_NVPATH_EXT(x) m_nvPathRendering->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_DIRECTSTATE_EXT(x) m_directStateAccess->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); -#endif - -#ifndef GL_GEOMETRY_SHADER_EXT -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#endif - -namespace qt3ds { -namespace render { - - /// constructor - NVRenderBackendGL4Impl::NVRenderBackendGL4Impl(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format) - : NVRenderBackendGL3Impl(fnd, stringTable, format) - { - eastl::string extTess("GL_ARB_tessellation_shader"); - eastl::string extGeometry("GL_EXT_geometry_shader4"); - eastl::string arbCompute("GL_ARB_compute_shader"); - eastl::string arbStorageBuffer("GL_ARB_shader_storage_buffer_object"); - eastl::string arbAtomicCounterBuffer("GL_ARB_shader_atomic_counters"); - eastl::string arbProgInterface("GL_ARB_program_interface_query"); - eastl::string arbShaderImageLoadStore("GL_ARB_shader_image_load_store"); - eastl::string nvPathRendering("GL_NV_path_rendering"); - eastl::string nvBlendAdvanced("GL_NV_blend_equation_advanced"); - eastl::string khrBlendAdvanced("GL_KHR_blend_equation_advanced"); - eastl::string nvBlendAdvancedCoherent("GL_NV_blend_equation_advanced_coherent"); - eastl::string khrBlendAdvancedCoherent("GL_KHR_blend_equation_advanced_coherent"); - - eastl::string apiVersion(getVersionString()); - qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); - - // get extension count - GLint numExtensions = 0; - GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); - - for (QT3DSI32 i = 0; i < numExtensions; i++) { - char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); - - // search for extension - if (!m_backendSupport.caps.bits.bTessellationSupported - && extTess.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bTessellationSupported = true; - } else if (!m_backendSupport.caps.bits.bComputeSupported - && arbCompute.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bComputeSupported = true; - } else if (!m_backendSupport.caps.bits.bGeometrySupported - && extGeometry.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bGeometrySupported = true; - } else if (!m_backendSupport.caps.bits.bStorageBufferSupported - && arbStorageBuffer.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bStorageBufferSupported = true; - } else if (!m_backendSupport.caps.bits.bAtomicCounterBufferSupported - && arbAtomicCounterBuffer.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; - } else if (!m_backendSupport.caps.bits.bProgramInterfaceSupported - && arbProgInterface.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bProgramInterfaceSupported = true; - } else if (!m_backendSupport.caps.bits.bShaderImageLoadStoreSupported - && arbShaderImageLoadStore.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; - } else if (!m_backendSupport.caps.bits.bNVPathRenderingSupported - && nvPathRendering.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bNVPathRenderingSupported = true; - } else if (!m_backendSupport.caps.bits.bNVAdvancedBlendSupported - && nvBlendAdvanced.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bNVAdvancedBlendSupported = true; - } else if (!m_backendSupport.caps.bits.bNVBlendCoherenceSupported - && nvBlendAdvancedCoherent.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bNVBlendCoherenceSupported = true; - } else if (!m_backendSupport.caps.bits.bKHRAdvancedBlendSupported - && khrBlendAdvanced.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bKHRAdvancedBlendSupported = true; - } else if (!m_backendSupport.caps.bits.bKHRBlendCoherenceSupported - && khrBlendAdvancedCoherent.compare(extensionString) == 0) { - m_backendSupport.caps.bits.bKHRBlendCoherenceSupported = true; - } - } - - // always true for GL4.1 and GLES 3.1 devices - m_backendSupport.caps.bits.bMsTextureSupported = true; - m_backendSupport.caps.bits.bProgramPipelineSupported = true; - - if (!isESCompatible()) { - // TODO: investigate GL 4.0 support - // we expect minimum GL 4.1 context anything beyond is handeled via extensions - // Tessellation is always supported on none ES systems which support >=GL4 - m_backendSupport.caps.bits.bTessellationSupported = true; - // geometry shader is always supported on none ES systems which support >=GL4 ( actually - // 3.2 already ) - m_backendSupport.caps.bits.bGeometrySupported = true; - } else { - // always true for GLES 3.1 devices - m_backendSupport.caps.bits.bComputeSupported = true; - m_backendSupport.caps.bits.bProgramInterfaceSupported = true; - m_backendSupport.caps.bits.bStorageBufferSupported = true; - m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; - m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; - } - -#if !defined(QT_OPENGL_ES) - // Initialize extensions - m_nvPathRendering = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_NV_path_rendering)(); - m_nvPathRendering->initializeOpenGLFunctions(); - m_directStateAccess = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_EXT_direct_state_access)(); - m_directStateAccess->initializeOpenGLFunctions(); -#endif - } - - /// destructor - NVRenderBackendGL4Impl::~NVRenderBackendGL4Impl() - { -#if !defined(QT_OPENGL_ES) - if (m_nvPathRendering) - NVDelete(m_Foundation.getAllocator(), m_nvPathRendering); - if (m_directStateAccess) - NVDelete(m_Foundation.getAllocator(), m_directStateAccess); -#endif - } - - void NVRenderBackendGL4Impl::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) - { - GL_CALL_EXTRA_FUNCTION( - glDrawArraysIndirect(m_Conversion.fromDrawModeToGL( - drawMode, m_backendSupport.caps.bits.bTessellationSupported), - indirect)); - } - - void NVRenderBackendGL4Impl::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, - NVRenderComponentTypes::Enum type, - const void *indirect) - { - GL_CALL_EXTRA_FUNCTION(glDrawElementsIndirect( - m_Conversion.fromDrawModeToGL(drawMode, - m_backendSupport.caps.bits.bTessellationSupported), - m_Conversion.fromIndexBufferComponentsTypesToGL(type), indirect)); - } - - void NVRenderBackendGL4Impl::CreateTextureStorage2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSU32 levels, - NVRenderTextureFormats::Enum internalFormat, - size_t width, size_t height) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - - // up to now compressed is not supported - QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - - GL_CALL_EXTRA_FUNCTION( - glTexStorage2D(glTarget, levels, glInternalFormat, (GLsizei)width, (GLsizei)height)); - - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); - } - - void NVRenderBackendGL4Impl::SetMultisampledTextureData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, - bool fixedsamplelocations) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) - GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - GL_CALL_EXTRA_FUNCTION(glTexStorage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, - (GLsizei)width, (GLsizei)height, - fixedsamplelocations)); - - GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); - } - - NVRenderBackend::NVRenderBackendTessControlShaderObject - NVRenderBackendGL4Impl::CreateTessControlShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { -#if !defined(QT_OPENGL_ES) - GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_CONTROL_SHADER)); -#else - GLuint shaderID = 0; -#endif - if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { - GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); - shaderID = 0; - } - - return (NVRenderBackend::NVRenderBackendTessControlShaderObject)shaderID; - } - - NVRenderBackend::NVRenderBackendTessEvaluationShaderObject - NVRenderBackendGL4Impl::CreateTessEvaluationShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { -#if !defined(QT_OPENGL_ES) - GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_EVALUATION_SHADER)); -#else - GLuint shaderID = 0; -#endif - - if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { - GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); - shaderID = 0; - } - - return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)shaderID; - } - - NVRenderBackend::NVRenderBackendGeometryShaderObject - NVRenderBackendGL4Impl::CreateGeometryShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { -#if defined(QT_OPENGL_ES) - GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER_EXT)); -#else - GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER)); -#endif - if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { - GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); - shaderID = 0; - } - - return (NVRenderBackend::NVRenderBackendGeometryShaderObject)shaderID; - } - - void NVRenderBackendGL4Impl::SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, - QT3DSU32 count) - { - QT3DS_ASSERT(iao); - QT3DS_ASSERT(count); - NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; - inputAssembler->m_PatchVertexCount = count; - } - - void NVRenderBackendGL4Impl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) - { - GL_CALL_EXTRA_FUNCTION(glMemoryBarrier(m_Conversion.fromMemoryBarrierFlagsToGL(barriers))); - } - - void NVRenderBackendGL4Impl::BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, - QT3DSI32 level, bool layered, QT3DSI32 layer, - NVRenderImageAccessType::Enum access, - NVRenderTextureFormats::Enum format) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - - GL_CALL_EXTRA_FUNCTION(glBindImageTexture(unit, texID, level, layered, layer, - m_Conversion.fromImageAccessToGL(access), - m_Conversion.fromImageFormatToGL(format))); - } - - QT3DSI32 NVRenderBackendGL4Impl::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) - { - GLint numStorageBuffers = 0; - QT3DS_ASSERT(po); - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - -#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) - if (m_backendSupport.caps.bits.bProgramInterfaceSupported) - GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_SHADER_STORAGE_BLOCK, - GL_ACTIVE_RESOURCES, &numStorageBuffers)); -#endif - return numStorageBuffers; - } - - QT3DSI32 - NVRenderBackendGL4Impl::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) - { - GLint bufferIndex = GL_INVALID_INDEX; - - QT3DS_ASSERT(po); - QT3DS_ASSERT(length); - QT3DS_ASSERT(nameBuf); - QT3DS_ASSERT(bufferSize); - QT3DS_ASSERT(paramCount); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); -#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) - if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { - GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_SHADER_STORAGE_BLOCK, id, nameBufSize, - length, nameBuf)); - - if (*length > 0) { -#define QUERY_COUNT 3 - GLsizei actualCount; - GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, - GL_NUM_ACTIVE_VARIABLES }; - GLint params[QUERY_COUNT]; - GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_SHADER_STORAGE_BLOCK, id, - QUERY_COUNT, props, QUERY_COUNT, &actualCount, - params)); - - QT3DS_ASSERT(actualCount == QUERY_COUNT); - - bufferIndex = params[0]; - *bufferSize = params[1]; - *paramCount = params[2]; - } - } -#endif - return bufferIndex; - } - - void NVRenderBackendGL4Impl::ProgramSetStorageBuffer(QT3DSU32 index, - NVRenderBackendBufferObject bo) - { -#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) - GL_CALL_EXTRA_FUNCTION( - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); -#endif - } - - QT3DSI32 NVRenderBackendGL4Impl::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) - { - GLint numAtomicCounterBuffers = 0; - QT3DS_ASSERT(po); - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); -#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) - if (m_backendSupport.caps.bits.bProgramInterfaceSupported) - GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_ATOMIC_COUNTER_BUFFER, - GL_ACTIVE_RESOURCES, &numAtomicCounterBuffers)); -#endif - return numAtomicCounterBuffers; - } - - QT3DSI32 - NVRenderBackendGL4Impl::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, - QT3DSI32 *paramCount, QT3DSI32 *bufferSize, - QT3DSI32 *length, char *nameBuf) - { - GLint bufferIndex = GL_INVALID_INDEX; - - QT3DS_ASSERT(po); - QT3DS_ASSERT(length); - QT3DS_ASSERT(nameBuf); - QT3DS_ASSERT(bufferSize); - QT3DS_ASSERT(paramCount); - - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); -#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) - if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { - { -#define QUERY_COUNT 3 - GLsizei actualCount; - GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, - GL_NUM_ACTIVE_VARIABLES }; - GLint params[QUERY_COUNT]; - GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_ATOMIC_COUNTER_BUFFER, id, - QUERY_COUNT, props, QUERY_COUNT, &actualCount, - params)); - - QT3DS_ASSERT(actualCount == QUERY_COUNT); - - bufferIndex = params[0]; - *bufferSize = params[1]; - *paramCount = params[2]; - - GLenum props1[1] = { GL_ATOMIC_COUNTER_BUFFER_INDEX }; - GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_UNIFORM, id, 1, props1, 1, - &actualCount, params)); - - QT3DS_ASSERT(actualCount == 1); - - *nameBuf = '\0'; - GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_UNIFORM, params[0], nameBufSize, - length, nameBuf)); - } - } -#endif - return bufferIndex; - } - - void NVRenderBackendGL4Impl::ProgramSetAtomicCounterBuffer(QT3DSU32 index, - NVRenderBackendBufferObject bo) - { -#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) - GL_CALL_EXTRA_FUNCTION( - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); -#endif - } - - void NVRenderBackendGL4Impl::SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count, - const void *value, bool transpose) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); - - switch (glType) { - case GL_FLOAT: - GL_CALL_EXTRA_FUNCTION(glProgramUniform1fv(programID, id, count, (GLfloat *)value)); - break; - case GL_FLOAT_VEC2: - GL_CALL_EXTRA_FUNCTION(glProgramUniform2fv(programID, id, count, (GLfloat *)value)); - break; - case GL_FLOAT_VEC3: - GL_CALL_EXTRA_FUNCTION(glProgramUniform3fv(programID, id, count, (GLfloat *)value)); - break; - case GL_FLOAT_VEC4: - GL_CALL_EXTRA_FUNCTION(glProgramUniform4fv(programID, id, count, (GLfloat *)value)); - break; - case GL_INT: - GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, (GLint *)value)); - break; - case GL_BOOL: - { - GLint boolValue = *(GLboolean *)value; - GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, &boolValue)); - } - break; - case GL_INT_VEC2: - case GL_BOOL_VEC2: - GL_CALL_EXTRA_FUNCTION(glProgramUniform2iv(programID, id, count, (GLint *)value)); - break; - case GL_INT_VEC3: - case GL_BOOL_VEC3: - GL_CALL_EXTRA_FUNCTION(glProgramUniform3iv(programID, id, count, (GLint *)value)); - break; - case GL_INT_VEC4: - case GL_BOOL_VEC4: - GL_CALL_EXTRA_FUNCTION(glProgramUniform4iv(programID, id, count, (GLint *)value)); - break; - case GL_FLOAT_MAT3: - GL_CALL_EXTRA_FUNCTION( - glProgramUniformMatrix3fv(programID, id, count, transpose, (GLfloat *)value)); - break; - case GL_FLOAT_MAT4: - GL_CALL_EXTRA_FUNCTION( - glProgramUniformMatrix4fv(programID, id, count, transpose, (GLfloat *)value)); - break; - case GL_IMAGE_2D: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE: { - if (count <= 1) { - GLint sampler = *(GLint *)value; - GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler)); - } else { - GLint *sampler = (GLint *)value; - GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, sampler)); - } - } break; - default: - qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); - QT3DS_ASSERT(false); - break; - } - } - - NVRenderBackend::NVRenderBackendComputeShaderObject - NVRenderBackendGL4Impl::CreateComputeShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - GLuint shaderID = 0; -#if defined(GL_COMPUTE_SHADER) - shaderID = m_glExtraFunctions->glCreateShader(GL_COMPUTE_SHADER); - - if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { - GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); - shaderID = 0; - } -#endif - return (NVRenderBackend::NVRenderBackendComputeShaderObject)shaderID; - } - - void NVRenderBackendGL4Impl::DispatchCompute(NVRenderBackendShaderProgramObject, - QT3DSU32 numGroupsX, QT3DSU32 numGroupsY, - QT3DSU32 numGroupsZ) - { - GL_CALL_EXTRA_FUNCTION(glDispatchCompute(numGroupsX, numGroupsY, numGroupsZ)); - } - - NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGL4Impl::CreateProgramPipeline() - { - GLuint pipeline; - GL_CALL_EXTRA_FUNCTION(glGenProgramPipelines(1, &pipeline)); - - return NVRenderBackend::NVRenderBackendProgramPipeline(pipeline); - } - - void NVRenderBackendGL4Impl::ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) - { - GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); - GL_CALL_EXTRA_FUNCTION(glDeleteProgramPipelines(1, &pipeline)); - } - - void NVRenderBackendGL4Impl::SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) - { - GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); - - GL_CALL_EXTRA_FUNCTION(glBindProgramPipeline(pipeline)); - } - - void NVRenderBackendGL4Impl::SetProgramStages(NVRenderBackendProgramPipeline ppo, - NVRenderShaderTypeFlags flags, - NVRenderBackendShaderProgramObject po) - { - GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); - GLuint programID = 0; - - if (po) { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - programID = static_cast(pProgram->m_ProgramID); - } - - GL_CALL_EXTRA_FUNCTION( - glUseProgramStages(pipeline, m_Conversion.fromShaderTypeFlagsToGL(flags), programID)); - } - - void NVRenderBackendGL4Impl::SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) - { - if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported || - m_backendSupport.caps.bits.bKHRAdvancedBlendSupported) - GL_CALL_EXTRA_FUNCTION(glBlendEquation(m_Conversion.fromBlendEquationToGL( - pBlendEquArg.m_RGBEquation, m_backendSupport.caps.bits.bNVAdvancedBlendSupported, - m_backendSupport.caps.bits.bKHRAdvancedBlendSupported))); - } - - void NVRenderBackendGL4Impl::SetBlendBarrier(void) - { - if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported) - GL_CALL_QT3DS_EXT(glBlendBarrierNV()); - } - - NVRenderBackend::NVRenderBackendPathObject - NVRenderBackendGL4Impl::CreatePathNVObject(size_t range) - { - GLuint pathID = GL_CALL_NVPATH_EXT(glGenPathsNV((GLsizei)range)); - - return NVRenderBackend::NVRenderBackendPathObject(pathID); - } - void NVRenderBackendGL4Impl::SetPathSpecification(NVRenderBackendPathObject inPathObject, - NVConstDataRef inPathCommands, - NVConstDataRef inPathCoords) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, inPathObject); - GL_CALL_NVPATH_EXT(glPathCommandsNV(pathID, inPathCommands.size(), inPathCommands.begin(), - inPathCoords.size(), GL_FLOAT, inPathCoords.begin())); - } - - NVBounds3 - NVRenderBackendGL4Impl::GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) - { - float data[4]; -#if defined(GL_NV_path_rendering) - GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( - HandleToID_cast(GLuint, size_t, inPathObject), - GL_PATH_OBJECT_BOUNDING_BOX_NV, data)); -#endif - return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); - } - - NVBounds3 NVRenderBackendGL4Impl::GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) - { - float data[4]; -#if defined(GL_NV_path_rendering) - GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( - HandleToID_cast(GLuint, size_t, inPathObject), - GL_PATH_FILL_BOUNDING_BOX_NV, data)); -#endif - return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); - } - - NVBounds3 NVRenderBackendGL4Impl::GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) - { - float data[4]; -#if defined(GL_NV_path_rendering) - GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( - HandleToID_cast(GLuint, size_t, inPathObject), - GL_PATH_STROKE_BOUNDING_BOX_NV, data)); -#endif - return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); - } - - void NVRenderBackendGL4Impl::SetStrokeWidth(NVRenderBackendPathObject inPathObject, - QT3DSF32 inStrokeWidth) - { -#if defined(GL_NV_path_rendering) - GL_CALL_NVPATH_EXT(glPathParameterfNV(HandleToID_cast(GLuint, size_t, inPathObject), - GL_PATH_STROKE_WIDTH_NV, inStrokeWidth)); -#endif - } - - void NVRenderBackendGL4Impl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) - { -#if defined(QT_OPENGL_ES) - NVRENDER_BACKEND_UNUSED(inPathProjection); -#else - GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_PROJECTION, inPathProjection.front())); -#endif - } - - void NVRenderBackendGL4Impl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) - { -#if defined(QT_OPENGL_ES) - NVRENDER_BACKEND_UNUSED(inPathModelview); -#else - GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_MODELVIEW, inPathModelview.front())); -#endif - } - - void NVRenderBackendGL4Impl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) - { - GL_CALL_NVPATH_EXT(glPathStencilDepthOffsetNV(inSlope, inBias)); - } - - void NVRenderBackendGL4Impl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) - { - GL_CALL_NVPATH_EXT(glPathCoverDepthFuncNV(m_Conversion.fromBoolOpToGL(inDepthFunction))); - } - - void NVRenderBackendGL4Impl::StencilStrokePath(NVRenderBackendPathObject inPathObject) - { - GL_CALL_NVPATH_EXT(glStencilStrokePathNV(HandleToID_cast(GLuint, size_t, inPathObject), 0x1, (GLuint)~0)); - } - - void NVRenderBackendGL4Impl::StencilFillPath(NVRenderBackendPathObject inPathObject) - { -#if defined(GL_NV_path_rendering) - GL_CALL_NVPATH_EXT(glStencilFillPathNV(HandleToID_cast(GLuint, size_t, inPathObject), - GL_COUNT_UP_NV, (GLuint)~0)); -#endif - } - - void NVRenderBackendGL4Impl::ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glDeletePathsNV(pathID, (GLsizei)range)); - } - - void NVRenderBackendGL4Impl::StencilFillPathInstanced( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, - const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, - NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glStencilFillPathInstancedNV( - (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, - m_Conversion.fromPathFillModeToGL(fillMode), stencilMask, - m_Conversion.fromPathTransformToGL(transformType), transformValues)); - } - - void NVRenderBackendGL4Impl::StencilStrokePathInstancedN( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, - const void *charCodes, QT3DSI32 stencilRef, QT3DSU32 stencilMask, - NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glStencilStrokePathInstancedNV( - (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, stencilRef, - stencilMask, m_Conversion.fromPathTransformToGL(transformType), transformValues)); - } - - void NVRenderBackendGL4Impl::CoverFillPathInstanced( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, - const void *charCodes, NVRenderPathCoverMode::Enum coverMode, - NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glCoverFillPathInstancedNV( - (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, - m_Conversion.fromPathCoverModeToGL(coverMode), - m_Conversion.fromPathTransformToGL(transformType), transformValues)); - } - - void NVRenderBackendGL4Impl::CoverStrokePathInstanced( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, - const void *charCodes, NVRenderPathCoverMode::Enum coverMode, - NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glCoverStrokePathInstancedNV( - (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, - m_Conversion.fromPathCoverModeToGL(coverMode), - m_Conversion.fromPathTransformToGL(transformType), transformValues)); - } - - void NVRenderBackendGL4Impl::LoadPathGlyphs( - NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, NVRenderPathFormatType::Enum type, - const void *charCodes, NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - GLuint pathTemplateID = (pathParameterTemplate == NULL) - ? ~0 - : HandleToID_cast(GLuint, size_t, pathParameterTemplate); - - GL_CALL_NVPATH_EXT(glPathGlyphsNV(pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, - m_Conversion.fromPathFontStyleToGL(fontStyle), (GLsizei)numGlyphs, - m_Conversion.fromPathTypeToGL(type), charCodes, - m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), - pathTemplateID, emScale)); - } - - NVRenderPathReturnValues::Enum NVRenderBackendGL4Impl::LoadPathGlyphsIndexed( - NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyphIndex, size_t numGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - GLuint pathTemplateID = (pathParameterTemplate == NULL) - ? ~0 - : HandleToID_cast(GLuint, size_t, pathParameterTemplate); - GLenum glRet = 0; - - glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexArrayNV( - pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, - m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyphIndex, - (GLsizei)numGlyphs, pathTemplateID, emScale)); - - return m_Conversion.fromGLToPathFontReturn(glRet); - } - - NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGL4Impl::LoadPathGlyphsIndexedRange( - NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, NVRenderBackendPathObject pathParameterTemplate, - QT3DSF32 emScale, QT3DSU32 *count) - { - GLuint pathTemplateID = (pathParameterTemplate == NULL) - ? ~0 - : HandleToID_cast(GLuint, size_t, pathParameterTemplate); - GLenum glRet = 0; - GLuint baseAndCount[2] = { 0, 0 }; - - glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexRangeNV(m_Conversion.fromPathFontTargetToGL(fontTarget), - fontName, - m_Conversion.fromPathFontStyleToGL(fontStyle), - pathTemplateID, emScale, baseAndCount)); - - if (count) - *count = baseAndCount[1]; - - return NVRenderBackend::NVRenderBackendPathObject(baseAndCount[0]); - } - - void NVRenderBackendGL4Impl::LoadPathGlyphRange( - NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, - NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyph, size_t numGlyphs, - NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, - NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - GLuint pathTemplateID = (pathParameterTemplate == NULL) - ? ~0 - : HandleToID_cast(GLuint, size_t, pathParameterTemplate); - - GL_CALL_NVPATH_EXT(glPathGlyphRangeNV( - pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, - m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyph, (GLsizei)numGlyphs, - m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), pathTemplateID, emScale)); - } - - void NVRenderBackendGL4Impl::GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathGlyphFontMetricFlags metricQueryMask, - NVRenderPathFormatType::Enum type, - const void *charCodes, size_t stride, - QT3DSF32 *metrics) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glGetPathMetricsNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), - (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), - charCodes, pathID, (GLsizei)stride, metrics)); - } - - void - NVRenderBackendGL4Impl::GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, - NVRenderPathGlyphFontMetricFlags metricQueryMask, - size_t stride, QT3DSF32 *metrics) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glGetPathMetricRangeNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), - pathID, (GLsizei)numPaths, (GLsizei)stride, metrics)); - } - - void NVRenderBackendGL4Impl::GetPathSpacing( - NVRenderBackendPathObject po, size_t numPaths, NVRenderPathListMode::Enum pathListMode, - NVRenderPathFormatType::Enum type, const void *charCodes, QT3DSF32 advanceScale, - QT3DSF32 kerningScale, NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) - { - GLuint pathID = HandleToID_cast(GLuint, size_t, po); - - GL_CALL_NVPATH_EXT(glGetPathSpacingNV(m_Conversion.fromPathListModeToGL(pathListMode), - (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), - charCodes, pathID, advanceScale, kerningScale, - m_Conversion.fromPathTransformToGL(transformType), spacing)); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp deleted file mode 100644 index 940ab094..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp +++ /dev/null @@ -1,2220 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" -#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" -#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" -#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" -#include "foundation/StringTable.h" - -#ifdef RENDER_BACKEND_LOG_GL_ERRORS -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) -#else -#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() -#endif - -#define GL_CALL_FUNCTION(x) m_glFunctions->x; RENDER_LOG_ERROR_PARAMS(x); -#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); - -namespace qt3ds { -namespace render { - -#ifndef GL_PROGRAM_SEPARABLE -#define GL_PROGRAM_SEPARABLE 0x8258 -#endif - -#ifndef GL_UNSIGNED_INT_IMAGE_2D -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#endif - -#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#endif - - /// constructor - NVRenderBackendGLBase::NVRenderBackendGLBase(NVFoundationBase &fnd, - qt3ds::foundation::IStringTable &stringTable, - const QSurfaceFormat &format) - : mRefCount(0) - , m_Foundation(fnd) - , m_StringTable(stringTable) - , m_Conversion() - , m_MaxAttribCount(0) - , m_DrawBuffersArray(m_Foundation.getAllocator(), - "NVRenderBackendGLBase::m_DrawBuffersArray") - , m_format(format) - { - m_glFunctions = new QOpenGLFunctions; - m_glFunctions->initializeOpenGLFunctions(); - m_glExtraFunctions = new QOpenGLExtraFunctions; - m_glExtraFunctions->initializeOpenGLFunctions(); - - // internal state tracker - m_pCurrentRasterizerState = - QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendRasterizerStateGL)(); - m_pCurrentDepthStencilState = - QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)(); - } - /// destructor - NVRenderBackendGLBase::~NVRenderBackendGLBase() - { - if (m_pCurrentRasterizerState) - NVDelete(m_Foundation.getAllocator(), m_pCurrentRasterizerState); - if (m_pCurrentDepthStencilState) - NVDelete(m_Foundation.getAllocator(), m_pCurrentDepthStencilState); - if (m_glFunctions) - delete m_glFunctions; - if (m_glExtraFunctions) - delete m_glExtraFunctions; - } - - NVRenderContextType NVRenderBackendGLBase::GetRenderContextType() const - { - if (m_format.renderableType() == QSurfaceFormat::OpenGLES) { - if (m_format.majorVersion() == 2) - return NVRenderContextValues::GLES2; - - if (m_format.majorVersion() == 3) { - if (m_format.minorVersion() >= 1) - return NVRenderContextValues::GLES3PLUS; - else - return NVRenderContextValues::GLES3; - } - } else if (m_format.majorVersion() == 2) { - return NVRenderContextValues::GL2; - } else if (m_format.majorVersion() == 3) { - return NVRenderContextValues::GL3; - } else if (m_format.majorVersion() == 4) { - return NVRenderContextValues::GL4; - } - - return NVRenderContextValues::NullContext; - } - - bool NVRenderBackendGLBase::isESCompatible() const - { - return m_format.renderableType() == QSurfaceFormat::OpenGLES; - } - - const char *NVRenderBackendGLBase::GetShadingLanguageVersion() - { - const char *retval = (const char *)GL_CALL_FUNCTION( - glGetString(GL_SHADING_LANGUAGE_VERSION)); - if (retval == NULL) - return ""; - - return retval; - } - - QT3DSU32 - NVRenderBackendGLBase::GetMaxCombinedTextureUnits() - { - QT3DSI32 maxUnits; - GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxUnits)); - return maxUnits; - } - - bool NVRenderBackendGLBase::GetRenderBackendCap( - NVRenderBackend::NVRenderBackendCaps::Enum inCap) const - { - bool bSupported = false; - - switch (inCap) { - case NVRenderBackendCaps::FpRenderTarget: - bSupported = m_backendSupport.caps.bits.bFPRenderTargetsSupported; - break; - case NVRenderBackendCaps::DepthStencilTexture: - bSupported = m_backendSupport.caps.bits.bDepthStencilSupported; - break; - case NVRenderBackendCaps::ConstantBuffer: - bSupported = m_backendSupport.caps.bits.bConstantBufferSupported; - break; - case NVRenderBackendCaps::DxtImages: - bSupported = m_backendSupport.caps.bits.bDXTImagesSupported; - break; - case NVRenderBackendCaps::MsTexture: - bSupported = m_backendSupport.caps.bits.bMsTextureSupported; - break; - case NVRenderBackendCaps::TexSwizzle: - bSupported = m_backendSupport.caps.bits.bTextureSwizzleSupported; - break; - case NVRenderBackendCaps::FastBlits: - bSupported = m_backendSupport.caps.bits.bFastBlitsSupported; - break; - case NVRenderBackendCaps::Tessellation: - bSupported = m_backendSupport.caps.bits.bTessellationSupported; - break; - case NVRenderBackendCaps::Compute: - bSupported = m_backendSupport.caps.bits.bComputeSupported; - break; - case NVRenderBackendCaps::Geometry: - bSupported = m_backendSupport.caps.bits.bGeometrySupported; - break; - case NVRenderBackendCaps::SampleQuery: { - // On the following context sample query is not supported - NVRenderContextType noSamplesQuerySupportedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - NVRenderContextType ctxType = GetRenderContextType(); - bSupported = !(ctxType & noSamplesQuerySupportedContextFlags); - } break; - case NVRenderBackendCaps::TimerQuery: - bSupported = m_backendSupport.caps.bits.bTimerQuerySupported; - break; - case NVRenderBackendCaps::CommandSync: { - // On the following context sync objects are not supported - NVRenderContextType noSyncObjectSupportedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - NVRenderContextType ctxType = GetRenderContextType(); - bSupported = !(ctxType & noSyncObjectSupportedContextFlags); - } break; - case NVRenderBackendCaps::TextureArray: { - // On the following context texture arrays are not supported - NVRenderContextType noTextureArraySupportedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - NVRenderContextType ctxType = GetRenderContextType(); - bSupported = !(ctxType & noTextureArraySupportedContextFlags); - } break; - case NVRenderBackendCaps::StorageBuffer: - bSupported = m_backendSupport.caps.bits.bStorageBufferSupported; - break; - case NVRenderBackendCaps::AtomicCounterBuffer: - bSupported = m_backendSupport.caps.bits.bAtomicCounterBufferSupported; - break; - case NVRenderBackendCaps::ShaderImageLoadStore: - bSupported = m_backendSupport.caps.bits.bShaderImageLoadStoreSupported; - break; - case NVRenderBackendCaps::ProgramPipeline: - bSupported = m_backendSupport.caps.bits.bProgramPipelineSupported; - break; - case NVRenderBackendCaps::PathRendering: - bSupported = m_backendSupport.caps.bits.bNVPathRenderingSupported; - break; - case NVRenderBackendCaps::AdvancedBlend: - bSupported = m_backendSupport.caps.bits.bNVAdvancedBlendSupported | - m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; - break; - case NVRenderBackendCaps::AdvancedBlendKHR: - bSupported = m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; - break; - case NVRenderBackendCaps::BlendCoherency: - bSupported = m_backendSupport.caps.bits.bNVBlendCoherenceSupported | - m_backendSupport.caps.bits.bKHRBlendCoherenceSupported; - break; - case NVRenderBackendCaps::gpuShader5: - bSupported = m_backendSupport.caps.bits.bGPUShader5ExtensionSupported; - break; - case NVRenderBackendCaps::VertexArrayObject: - bSupported = m_backendSupport.caps.bits.bVertexArrayObjectSupported; - break; - case NVRenderBackendCaps::StandardDerivatives: - bSupported = m_backendSupport.caps.bits.bStandardDerivativesSupported; - break; - case NVRenderBackendCaps::TextureLod: - bSupported = m_backendSupport.caps.bits.bTextureLodSupported; - break; - default: - QT3DS_ASSERT(false); - bSupported = false; - break; - } - - return bSupported; - } - - void NVRenderBackendGLBase::GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, - QT3DSI32 *params) const - { - if (params) { - switch (inQuery) { - case NVRenderBackendQuery::MaxTextureSize: - GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_TEXTURE_SIZE, params)); - break; - case NVRenderBackendQuery::MaxTextureArrayLayers: { - NVRenderContextType noTextureArraySupportedContextFlags( - NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); - NVRenderContextType ctxType = GetRenderContextType(); - if (!(ctxType & noTextureArraySupportedContextFlags)) { - GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, params)); - } else { - *params = 0; - } - } break; - case NVRenderBackendQuery::MaxConstantBufferSlots: { - NVRenderContextType noConstantBufferSupportedContextFlags( - NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); - NVRenderContextType ctxType = GetRenderContextType(); - if (!(ctxType & noConstantBufferSupportedContextFlags)) { - GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, params)); - } else { - *params = 0; - } - } break; - case NVRenderBackendQuery::MaxConstantBufferBlockSize: { - NVRenderContextType noConstantBufferSupportedContextFlags( - NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); - NVRenderContextType ctxType = GetRenderContextType(); - if (!(ctxType & noConstantBufferSupportedContextFlags)) { - GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, params)); - } else { - *params = 0; - } - } break; - default: - QT3DS_ASSERT(false); - *params = 0; - break; - } - } - } - - QT3DSU32 - NVRenderBackendGLBase::GetDepthBits() const - { - QT3DSI32 depthBits; - GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_BITS, &depthBits)); - return depthBits; - } - - QT3DSU32 - NVRenderBackendGLBase::GetStencilBits() const - { - QT3DSI32 stencilBits; - GL_CALL_FUNCTION(glGetIntegerv(GL_STENCIL_BITS, &stencilBits)); - return stencilBits; - } - - void NVRenderBackendGLBase::SetMultisample(bool bEnable) - { - QT3DS_ASSERT(m_backendSupport.caps.bits.bMsTextureSupported || !bEnable); - // For GL ES explicit multisample enabling is not needed - // and does not exist - NVRenderContextType noMsaaEnableContextFlags(NVRenderContextValues::GLES2 - | NVRenderContextValues::GLES3 - | NVRenderContextValues::GLES3PLUS); - NVRenderContextType ctxType = GetRenderContextType(); - if (!(ctxType & noMsaaEnableContextFlags)) { - SetRenderState(bEnable, NVRenderState::Multisample); - } - } - - void NVRenderBackendGLBase::SetRenderState(bool bEnable, const NVRenderState::Enum value) - { - if (value == NVRenderState::DepthWrite) { - GL_CALL_FUNCTION(glDepthMask(bEnable)); - } else { - if (bEnable) { - GL_CALL_FUNCTION(glEnable(m_Conversion.fromRenderStateToGL(value))); - } else { - GL_CALL_FUNCTION(glDisable(m_Conversion.fromRenderStateToGL(value))); - } - } - } - - NVRenderBackend::NVRenderBackendDepthStencilStateObject - NVRenderBackendGLBase::CreateDepthStencilState( - bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, - NVRenderStencilFunctionArgument &stencilFuncFront, - NVRenderStencilFunctionArgument &stencilFuncBack, - NVRenderStencilOperationArgument &depthStencilOpFront, - NVRenderStencilOperationArgument &depthStencilOpBack) - { - NVRenderBackendDepthStencilStateGL *retval = - QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)( - enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, - depthStencilOpFront, depthStencilOpBack); - - return (NVRenderBackend::NVRenderBackendDepthStencilStateObject)retval; - } - - void NVRenderBackendGLBase::ReleaseDepthStencilState( - NVRenderBackendDepthStencilStateObject inDepthStencilState) - { - NVRenderBackendDepthStencilStateGL *inputState = - (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; - if (inputState) - NVDelete(m_Foundation.getAllocator(), inputState); - } - - NVRenderBackend::NVRenderBackendRasterizerStateObject - NVRenderBackendGLBase::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, - NVRenderFaces::Enum cullFace) - { - NVRenderBackendRasterizerStateGL *retval = - QT3DS_NEW(m_Foundation.getAllocator(), - NVRenderBackendRasterizerStateGL)(depthBias, depthScale, cullFace); - - return (NVRenderBackend::NVRenderBackendRasterizerStateObject)retval; - } - - void NVRenderBackendGLBase::ReleaseRasterizerState( - NVRenderBackendRasterizerStateObject rasterizerState) - { - NVRenderBackendRasterizerStateGL *inputState = - (NVRenderBackendRasterizerStateGL *)rasterizerState; - if (inputState) - NVDelete(m_Foundation.getAllocator(), inputState); - } - - void NVRenderBackendGLBase::SetDepthStencilState( - NVRenderBackendDepthStencilStateObject inDepthStencilState) - { - NVRenderBackendDepthStencilStateGL *inputState = - (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; - if (inputState && !(*m_pCurrentDepthStencilState == *inputState)) { - // we check on a per single state base - if (inputState->m_DepthEnable != m_pCurrentDepthStencilState->m_DepthEnable) { - SetRenderState(inputState->m_DepthEnable, NVRenderState::DepthTest); - m_pCurrentDepthStencilState->m_DepthEnable = inputState->m_DepthEnable; - } - if (inputState->m_StencilEnable != m_pCurrentDepthStencilState->m_StencilEnable) { - SetRenderState(inputState->m_StencilEnable, NVRenderState::StencilTest); - m_pCurrentDepthStencilState->m_StencilEnable = inputState->m_StencilEnable; - } - - if (inputState->m_DepthMask != m_pCurrentDepthStencilState->m_DepthMask) { - GL_CALL_FUNCTION(glDepthMask(inputState->m_DepthMask)); - m_pCurrentDepthStencilState->m_DepthMask = inputState->m_DepthMask; - } - - if (inputState->m_DepthFunc != m_pCurrentDepthStencilState->m_DepthFunc) { - GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(inputState->m_DepthFunc))); - m_pCurrentDepthStencilState->m_DepthFunc = inputState->m_DepthFunc; - } - - if (!(inputState->m_DepthStencilOpFront - == m_pCurrentDepthStencilState->m_DepthStencilOpFront)) { - GL_CALL_FUNCTION(glStencilOpSeparate( - GL_FRONT, - m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_StencilFail), - m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthFail), - m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthPass))); - m_pCurrentDepthStencilState->m_DepthStencilOpFront = - inputState->m_DepthStencilOpFront; - } - - if (!(inputState->m_DepthStencilOpBack - == m_pCurrentDepthStencilState->m_DepthStencilOpBack)) { - GL_CALL_FUNCTION(glStencilOpSeparate( - GL_BACK, - m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_StencilFail), - m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthFail), - m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthPass))); - m_pCurrentDepthStencilState->m_DepthStencilOpBack = - inputState->m_DepthStencilOpBack; - } - - if (!(inputState->m_StencilFuncFront - == m_pCurrentDepthStencilState->m_StencilFuncFront)) { - GL_CALL_FUNCTION(glStencilFuncSeparate( - GL_FRONT, - m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncFront.m_Function), - inputState->m_StencilFuncFront.m_ReferenceValue, - inputState->m_StencilFuncFront.m_Mask)); - m_pCurrentDepthStencilState->m_StencilFuncFront = inputState->m_StencilFuncFront; - } - - if (!(inputState->m_StencilFuncBack - == m_pCurrentDepthStencilState->m_StencilFuncBack)) { - GL_CALL_FUNCTION(glStencilFuncSeparate( - GL_BACK, m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncBack.m_Function), - inputState->m_StencilFuncBack.m_ReferenceValue, - inputState->m_StencilFuncBack.m_Mask)); - m_pCurrentDepthStencilState->m_StencilFuncBack = inputState->m_StencilFuncBack; - } - } - } - - void - NVRenderBackendGLBase::SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) - { - NVRenderBackendRasterizerStateGL *inputState = - (NVRenderBackendRasterizerStateGL *)rasterizerState; - if (inputState && !(*m_pCurrentRasterizerState == *inputState)) { - // store current state - *m_pCurrentRasterizerState = *inputState; - - if (m_pCurrentRasterizerState->m_DepthBias != 0.0 - || m_pCurrentRasterizerState->m_DepthScale != 0.0) { - GL_CALL_FUNCTION(glEnable(GL_POLYGON_OFFSET_FILL)); - } else { - GL_CALL_FUNCTION(glDisable(GL_POLYGON_OFFSET_FILL)); - } - - GL_CALL_FUNCTION(glPolygonOffset(m_pCurrentRasterizerState->m_DepthBias, - m_pCurrentRasterizerState->m_DepthScale)); - - GL_CALL_FUNCTION( - glCullFace(m_Conversion.fromFacesToGL(m_pCurrentRasterizerState->m_CullFace))); - } - } - - bool NVRenderBackendGLBase::GetRenderState(const NVRenderState::Enum value) - { - bool enabled = GL_CALL_FUNCTION(glIsEnabled(m_Conversion.fromRenderStateToGL(value))); - return enabled; - } - - NVRenderBoolOp::Enum NVRenderBackendGLBase::GetDepthFunc() - { - QT3DSI32 value; - GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_FUNC, &value)); - return m_Conversion.fromGLToBoolOp(value); - } - - void NVRenderBackendGLBase::SetDepthFunc(const NVRenderBoolOp::Enum func) - { - GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(func))); - } - - bool NVRenderBackendGLBase::GetDepthWrite() - { - QT3DSI32 value; - GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_WRITEMASK, (GLint *)&value)); - return value ? true : false; - } - - void NVRenderBackendGLBase::SetDepthWrite(bool bEnable) { GL_CALL_FUNCTION(glDepthMask(bEnable)); } - - void NVRenderBackendGLBase::SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) - { - GL_CALL_FUNCTION(glColorMask(bRed, bGreen, bBlue, bAlpha)); - } - - void NVRenderBackendGLBase::GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) - { - QT3DS_ASSERT(pBlendFuncArg); - QT3DSI32_4 values; - - GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&values.x)); - GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&values.y)); - GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&values.z)); - GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&values.w)); - - pBlendFuncArg->m_SrcRGB = m_Conversion.fromGLToSrcBlendFunc(values.x); - pBlendFuncArg->m_SrcAlpha = m_Conversion.fromGLToSrcBlendFunc(values.y); - pBlendFuncArg->m_DstRGB = m_Conversion.fromGLToDstBlendFunc(values.z); - pBlendFuncArg->m_DstAlpha = m_Conversion.fromGLToDstBlendFunc(values.w); - } - - void NVRenderBackendGLBase::SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) - { - QT3DSI32_4 values; - - values.x = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcRGB); - values.y = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstRGB); - values.z = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcAlpha); - values.w = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstAlpha); - - GL_CALL_FUNCTION(glBlendFuncSeparate(values.x, values.y, values.z, values.w)); - } - - void NVRenderBackendGLBase::SetBlendEquation(const NVRenderBlendEquationArgument &) - { - // needs GL4 / GLES 3.1 - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::SetBlendBarrier() - { - // needs GL4 / GLES 3.1 - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GetScissorRect(NVRenderRect *pRect) - { - QT3DS_ASSERT(pRect); - GL_CALL_FUNCTION(glGetIntegerv(GL_SCISSOR_BOX, (GLint *)pRect)); - } - - void NVRenderBackendGLBase::SetScissorRect(const NVRenderRect &rect) - { - GL_CALL_FUNCTION(glScissor(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height)); - } - - void NVRenderBackendGLBase::GetViewportRect(NVRenderRect *pRect) - { - QT3DS_ASSERT(pRect); - GL_CALL_FUNCTION(glGetIntegerv(GL_VIEWPORT, (GLint *)pRect)); - } - - void NVRenderBackendGLBase::SetViewportRect(const NVRenderRect &rect) - { - GL_CALL_FUNCTION(glViewport(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height);); - } - - void NVRenderBackendGLBase::SetClearColor(const QT3DSVec4 *pClearColor) - { - QT3DS_ASSERT(pClearColor); - - GL_CALL_FUNCTION(glClearColor(pClearColor->x, pClearColor->y, - pClearColor->z, pClearColor->w)); - } - - void NVRenderBackendGLBase::Clear(NVRenderClearFlags flags) - { - GL_CALL_FUNCTION(glClear(m_Conversion.fromClearFlagsToGL(flags))); - } - - NVRenderBackend::NVRenderBackendBufferObject - NVRenderBackendGLBase::CreateBuffer(size_t size, NVRenderBufferBindFlags bindFlags, - NVRenderBufferUsageType::Enum usage, const void *hostPtr) - { - GLuint bufID = 0; - - GL_CALL_FUNCTION(glGenBuffers(1, &bufID)); - - if (bufID && size) { - GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); - if (target != GL_INVALID_ENUM) { - GL_CALL_FUNCTION(glBindBuffer(target, bufID)); - GL_CALL_FUNCTION(glBufferData(target, size, hostPtr, - m_Conversion.fromBufferUsageTypeToGL(usage))); - } else { - GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); - bufID = 0; - qCCritical(GL_ERROR, GLConversion::processGLError(target)); - } - } - - return (NVRenderBackend::NVRenderBackendBufferObject)bufID; - } - - void NVRenderBackendGLBase::BindBuffer(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags) - { - GLuint bufID = HandleToID_cast(GLuint, size_t, bo); - GL_CALL_FUNCTION(glBindBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags), bufID)); - } - - void NVRenderBackendGLBase::ReleaseBuffer(NVRenderBackendBufferObject bo) - { - GLuint bufID = HandleToID_cast(GLuint, size_t, bo); - GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); - } - - void NVRenderBackendGLBase::UpdateBuffer(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags, size_t size, - NVRenderBufferUsageType::Enum usage, const void *data) - { - GLuint bufID = HandleToID_cast(GLuint, size_t, bo); - GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); - GL_CALL_FUNCTION(glBindBuffer(target, bufID)); - GL_CALL_FUNCTION(glBufferData(target, size, data, m_Conversion.fromBufferUsageTypeToGL(usage))); - } - - void NVRenderBackendGLBase::UpdateBufferRange(NVRenderBackendBufferObject bo, - NVRenderBufferBindFlags bindFlags, size_t offset, - size_t size, const void *data) - { - GLuint bufID = HandleToID_cast(GLuint, size_t, bo); - GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); - GL_CALL_FUNCTION(glBindBuffer(target, bufID)); - GL_CALL_FUNCTION(glBufferSubData(target, offset, size, data)); - } - - void *NVRenderBackendGLBase::MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, - size_t, size_t, NVRenderBufferAccessFlags) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return NULL; - } - - bool NVRenderBackendGLBase::UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return true; - } - - void NVRenderBackendGLBase::SetMemoryBarrier(NVRenderBufferBarrierFlags) - { - // needs GL 4 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLBase::CreateQuery() - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return NVRenderBackendQueryObject(0); - } - - void NVRenderBackendGLBase::ReleaseQuery(NVRenderBackendQueryObject) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, - NVRenderQueryResultType::Enum, QT3DSU32 *) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, - NVRenderQueryResultType::Enum, QT3DSU64 *) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::SetQueryTimer(NVRenderBackendQueryObject) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - NVRenderBackend::NVRenderBackendSyncObject - NVRenderBackendGLBase::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return NVRenderBackendSyncObject(0); - } - - void NVRenderBackendGLBase::ReleaseSync(NVRenderBackendSyncObject) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, - QT3DSU64) - { - // needs GL 3 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLBase::CreateRenderTarget() - { - GLuint fboID = 0; - - GL_CALL_FUNCTION(glGenFramebuffers(1, &fboID)); - - return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; - } - - void NVRenderBackendGLBase::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) - { - GLuint fboID = HandleToID_cast(GLuint, size_t, rto); - - if (fboID) { - GL_CALL_FUNCTION(glDeleteFramebuffers(1, &fboID)); - } - } - - void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendRenderbufferObject rbo) - { - // rto must be the current render target - GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); - - GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); - - GL_CALL_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, rbID)); - } - - void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, - NVRenderFrameBufferAttachments::Enum attachment, - NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target) - { - // rto must be the current render target - GLuint texID = HandleToID_cast(GLuint, size_t, to); - - QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D - || m_backendSupport.caps.bits.bMsTextureSupported); - - GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - GL_CALL_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, 0)) - } - - void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject, - NVRenderFrameBufferAttachments::Enum, - NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) - { - // Needs GL3 or GLES 3 - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::SetRenderTarget(NVRenderBackendRenderTargetObject rto) - { - GLuint fboID = HandleToID_cast(GLuint, size_t, rto); - - GL_CALL_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); - } - - bool NVRenderBackendGLBase::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) - { - // rto must be the current render target - GLenum completeStatus = GL_CALL_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); - switch (completeStatus) { -#define HANDLE_INCOMPLETE_STATUS(x) \ - case x: \ - qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ - return false; - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) - HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) -#undef HANDLE_INCOMPLETE_STATUS - } - return true; - } - - NVRenderBackend::NVRenderBackendRenderbufferObject - NVRenderBackendGLBase::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) - { - GLuint bufID = 0; - - GL_CALL_FUNCTION(glGenRenderbuffers(1, &bufID)); - GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); - GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, - GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), - (GLsizei)width, (GLsizei)height)); - - // check for error - GLenum error = m_glFunctions->glGetError(); - if (error != GL_NO_ERROR) { - qCCritical(GL_ERROR, GLConversion::processGLError(error)); - QT3DS_ASSERT(false); - GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); - bufID = 0; - } - - GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); - - return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; - } - - void NVRenderBackendGLBase::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) - { - GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); - - if (bufID) { - GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); - } - } - - bool NVRenderBackendGLBase::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, - NVRenderRenderBufferFormats::Enum storageFormat, - size_t width, size_t height) - { - bool success = true; - GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); - - QT3DS_ASSERT(bufID); - - GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); - GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, - GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), - (GLsizei)width, (GLsizei)height)); - - // check for error - GLenum error = m_glFunctions->glGetError(); - if (error != GL_NO_ERROR) { - qCCritical(GL_ERROR, GLConversion::processGLError(error)); - QT3DS_ASSERT(false); - success = false; - } - - return success; - } - - NVRenderBackend::NVRenderBackendTextureObject NVRenderBackendGLBase::CreateTexture() - { - GLuint texID = 0; - - GL_CALL_FUNCTION(glGenTextures(1, &texID)); - return (NVRenderBackend::NVRenderBackendTextureObject)texID; - } - - void NVRenderBackendGLBase::BindTexture(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, QT3DSU32 unit) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0 + unit)); - GL_CALL_FUNCTION(glBindTexture(m_Conversion.fromTextureTargetToGL(target), texID)); - } - - void NVRenderBackendGLBase::BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, - QT3DSI32, NVRenderImageAccessType::Enum, - NVRenderTextureFormats::Enum) - { - // needs GL 4 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::ReleaseTexture(NVRenderBackendTextureObject to) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GL_CALL_FUNCTION(glDeleteTextures(1, &texID)); - } - - void NVRenderBackendGLBase::SetTextureData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); - bool conversionRequired = format != internalFormat; - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - - if (conversionRequired) { - GLenum dummy; - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, dummy); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - - GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, - border, glformat, gltype, hostPtr)); - - GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); - } - - // This will look very SetTextureData2D, but the target for glBindTexture will be different from - // the target for - // glTexImage2D. - void NVRenderBackendGLBase::SetTextureDataCubeFace( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, - NVRenderTextureFormats::Enum format, const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GLenum glTexTarget = - m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); - bool conversionRequired = format != internalFormat; - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), - internalFormat, swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; - - if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, - glformat, gltype, glInternalFormat); - - - if (conversionRequired) { - GLenum dummy; - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, dummy); - } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) - m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - - // for es2 internal format must be same as format - if (GetRenderContextType() == NVRenderContextValues::GLES2) - glInternalFormat = glformat; - - GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, - border, glformat, gltype, hostPtr)); - - GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); - } - - void NVRenderBackendGLBase::CreateTextureStorage2D(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, - NVRenderTextureFormats::Enum, size_t, size_t) - { - // you need GL 4.2 or GLES 3.1 - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::SetTextureSubData2D(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, - size_t width, size_t height, - NVRenderTextureFormats::Enum format, - const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); - - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - format = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), format, - swizzleMode); - - GLenum glformat = 0, glInternalFormat = 0, gltype = 0; - m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, - gltype, glInternalFormat); - GL_CALL_FUNCTION(glTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, - (GLsizei)height, glformat, gltype, hostPtr)); - - GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); - } - - void NVRenderBackendGLBase::SetCompressedTextureData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, - size_t imageSize, const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); - - GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, - (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); - - GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); - } - - void NVRenderBackendGLBase::SetCompressedTextureDataCubeFace( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, - size_t imageSize, const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GLenum glTexTarget = - m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); - - GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); - GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, - (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); - - GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); - } - - void NVRenderBackendGLBase::SetCompressedTextureSubData2D( - NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, - QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, - NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); - - GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(format); - GL_CALL_FUNCTION(glCompressedTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, - (GLsizei)height, glformat, (GLsizei)imageSize, - hostPtr)); - - GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); - } - - void NVRenderBackendGLBase::SetTextureData3D(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, - NVRenderTextureFormats::Enum, size_t, size_t, - size_t, QT3DSI32, NVRenderTextureFormats::Enum, - const void *) - { - // needs GL3 or GLES3 - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GenerateMipMaps(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderHint::Enum genType) - { - GLuint texID = HandleToID_cast(GLuint, size_t, to); - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); - GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); - - GLenum glValue = GLConversion::fromHintToGL(genType); - GL_CALL_FUNCTION(glHint(GL_GENERATE_MIPMAP_HINT, glValue)); - GL_CALL_FUNCTION(glGenerateMipmap(glTarget)); - - GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); - } - - NVRenderTextureSwizzleMode::Enum - NVRenderBackendGLBase::GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const - { - NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; - m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), inFormat, swizzleMode); - - return swizzleMode; - } - - NVRenderBackend::NVRenderBackendSamplerObject NVRenderBackendGLBase::CreateSampler( - NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, - NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, - NVRenderTextureCoordOp::Enum wrapR, QT3DSI32 minLod, QT3DSI32 maxLod, QT3DSF32 lodBias, - NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, - QT3DSF32 anisotropy, QT3DSF32 *borderColor) - { - // Satisfy the compiler - // We don"t setup the state here for GL - // but we need to pass on the variables here - // to satisfy the interface - NVRENDER_BACKEND_UNUSED(minFilter); - NVRENDER_BACKEND_UNUSED(magFilter); - NVRENDER_BACKEND_UNUSED(wrapS); - NVRENDER_BACKEND_UNUSED(wrapT); - NVRENDER_BACKEND_UNUSED(wrapR); - NVRENDER_BACKEND_UNUSED(minLod); - NVRENDER_BACKEND_UNUSED(maxLod); - NVRENDER_BACKEND_UNUSED(lodBias); - NVRENDER_BACKEND_UNUSED(compareMode); - NVRENDER_BACKEND_UNUSED(compareFunc); - NVRENDER_BACKEND_UNUSED(anisotropy); - NVRENDER_BACKEND_UNUSED(borderColor); - - // return a dummy handle - return (NVRenderBackend::NVRenderBackendSamplerObject)0x0001; - } - - void NVRenderBackendGLBase::UpdateSampler( - NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, - NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, - NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, - NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, - NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, - QT3DSF32 anisotropy, QT3DSF32 *borderColor) - { - // Satisfy the compiler - // These are not available in GLES 2 and we don't use them right now - NVRENDER_BACKEND_UNUSED(wrapR); - NVRENDER_BACKEND_UNUSED(lodBias); - NVRENDER_BACKEND_UNUSED(minLod); - NVRENDER_BACKEND_UNUSED(maxLod); - NVRENDER_BACKEND_UNUSED(compareMode); - NVRENDER_BACKEND_UNUSED(compareFunc); - NVRENDER_BACKEND_UNUSED(borderColor); - - GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); - - GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, - m_Conversion.fromTextureMinifyingOpToGL(minFilter))); - GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, - m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); - GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, - m_Conversion.fromTextureCoordOpToGL(wrapS))); - GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, - m_Conversion.fromTextureCoordOpToGL(wrapT))); - if (m_backendSupport.caps.bits.bAnistropySupported) { - GL_CALL_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy)); - } - } - - void NVRenderBackendGLBase::UpdateTextureObject(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - QT3DSI32 baseLevel, QT3DSI32 maxLevel) - { - NVRENDER_BACKEND_UNUSED(to); - NVRENDER_BACKEND_UNUSED(target); - NVRENDER_BACKEND_UNUSED(baseLevel); - NVRENDER_BACKEND_UNUSED(maxLevel); - } - - void NVRenderBackendGLBase::UpdateTextureSwizzle(NVRenderBackendTextureObject to, - NVRenderTextureTargetType::Enum target, - NVRenderTextureSwizzleMode::Enum swizzleMode) - { - NVRENDER_BACKEND_UNUSED(to); - NVRENDER_BACKEND_UNUSED(target); - - // Nothing to do here still might be called - QT3DS_ASSERT(swizzleMode == NVRenderTextureSwizzleMode::NoSwizzle); - - NVRENDER_BACKEND_UNUSED(swizzleMode); - } - - void NVRenderBackendGLBase::ReleaseSampler(NVRenderBackendSamplerObject so) - { - GLuint samplerID = HandleToID_cast(GLuint, size_t, so); - if (!samplerID) - return; - // otherwise nothing to do - } - - NVRenderBackend::NVRenderBackendAttribLayoutObject - NVRenderBackendGLBase::CreateAttribLayout(NVConstDataRef attribs) - { - QT3DSU32 attribLayoutSize = sizeof(NVRenderBackendAttributeLayoutGL); - QT3DSU32 entrySize = sizeof(NVRenderBackendLayoutEntryGL) * attribs.size(); - QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), attribLayoutSize + entrySize, - "BackendAttributeLayoutGL"); - NVDataRef entryRef = - PtrAtOffset(newMem, attribLayoutSize, entrySize); - QT3DSU32 maxInputSlot = 0; - - // copy data - QT3DS_FOREACH(idx, attribs.size()) - { - entryRef[idx].m_AttribName = m_StringTable->RegisterStr(attribs.mData[idx].m_Name); - entryRef[idx].m_Normalize = 0; - entryRef[idx].m_AttribIndex = 0; // will be set later - entryRef[idx].m_Type = m_Conversion.fromComponentTypeAndNumCompsToAttribGL( - attribs.mData[idx].m_ComponentType, attribs.mData[idx].m_NumComponents); - entryRef[idx].m_NumComponents = attribs.mData[idx].m_NumComponents; - entryRef[idx].m_InputSlot = attribs.mData[idx].m_InputSlot; - entryRef[idx].m_Offset = attribs.mData[idx].m_FirstItemOffset; - - if (maxInputSlot < entryRef[idx].m_InputSlot) - maxInputSlot = entryRef[idx].m_InputSlot; - } - - NVRenderBackendAttributeLayoutGL *retval = - new (newMem) NVRenderBackendAttributeLayoutGL(entryRef, maxInputSlot); - - return (NVRenderBackend::NVRenderBackendAttribLayoutObject)retval; - } - - void NVRenderBackendGLBase::ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) - { - NVRenderBackendAttributeLayoutGL *attribLayout = (NVRenderBackendAttributeLayoutGL *)ao; - - NVDelete(m_Foundation.getAllocator(), attribLayout); - }; - - NVRenderBackend::NVRenderBackendInputAssemblerObject - NVRenderBackendGLBase::CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, - NVConstDataRef buffers, - const NVRenderBackendBufferObject indexBuffer, - NVConstDataRef strides, - NVConstDataRef offsets, - QT3DSU32 patchVertexCount) - { - NVRenderBackendAttributeLayoutGL *attribLayoutGL = - (NVRenderBackendAttributeLayoutGL *)attribLayout; - - NVRenderBackendInputAssemblerGL *retval = QT3DS_NEW(m_Foundation.getAllocator(), - NVRenderBackendInputAssemblerGL)( - m_Foundation, attribLayoutGL, buffers, indexBuffer, strides, offsets, patchVertexCount); - - return (NVRenderBackend::NVRenderBackendInputAssemblerObject)retval; - } - - void NVRenderBackendGLBase::ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) - { - NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; - NVDelete(m_Foundation.getAllocator(), inputAssembler); - } - - bool NVRenderBackendGLBase::compileSource(GLuint shaderID, NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - GLint shaderSourceSize = static_cast(source.size()); - const char *shaderSourceData = (const char *)source.begin(); - GLint shaderStatus = GL_TRUE; - - if (!binary) { - - GL_CALL_FUNCTION(glShaderSource(shaderID, 1, &shaderSourceData, &shaderSourceSize)); - GL_CALL_FUNCTION(glCompileShader(shaderID)); - - GLint logLen; - GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_COMPILE_STATUS, &shaderStatus)); - GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLen)); - - // Check if some log exists. We also write warnings here - // Should at least contain more than the null termination - if (logLen > 2) { - errorMessage.resize(logLen + 1); - - GLint lenWithoutNull; - GL_CALL_FUNCTION(glGetShaderInfoLog(shaderID, logLen, &lenWithoutNull, - (char *)errorMessage.c_str())); - } - } else { - GL_CALL_FUNCTION(glShaderBinary(1, &shaderID, GL_NVIDIA_PLATFORM_BINARY_NV, shaderSourceData, - shaderSourceSize)); - GLenum binaryError = m_glFunctions->glGetError(); - if (binaryError != GL_NO_ERROR) { - shaderStatus = GL_FALSE; - qCCritical(GL_ERROR, GLConversion::processGLError(binaryError)); - } - } - - return (shaderStatus == GL_TRUE); - } - - NVRenderBackend::NVRenderBackendVertexShaderObject - NVRenderBackendGLBase::CreateVertexShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_VERTEX_SHADER)); - - if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - shaderID = 0; - } - - return (NVRenderBackend::NVRenderBackendVertexShaderObject)shaderID; - } - - NVRenderBackend::NVRenderBackendFragmentShaderObject - NVRenderBackendGLBase::CreateFragmentShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_FRAGMENT_SHADER)); - - if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - shaderID = 0; - } - - return (NVRenderBackend::NVRenderBackendFragmentShaderObject)shaderID; - } - - NVRenderBackend::NVRenderBackendTessControlShaderObject - NVRenderBackendGLBase::CreateTessControlShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - // needs GL 4 or GLES EXT_tessellation_shader support - NVRENDER_BACKEND_UNUSED(source); - NVRENDER_BACKEND_UNUSED(errorMessage); - NVRENDER_BACKEND_UNUSED(binary); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return (NVRenderBackend::NVRenderBackendTessControlShaderObject)0; - } - - NVRenderBackend::NVRenderBackendTessEvaluationShaderObject - NVRenderBackendGLBase::CreateTessEvaluationShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - // needs GL 4 or GLES EXT_tessellation_shader support - NVRENDER_BACKEND_UNUSED(source); - NVRENDER_BACKEND_UNUSED(errorMessage); - NVRENDER_BACKEND_UNUSED(binary); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)0; - } - - NVRenderBackend::NVRenderBackendGeometryShaderObject - NVRenderBackendGLBase::CreateGeometryShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - // needs GL 4 or GLES EXT_geometry_shader support - NVRENDER_BACKEND_UNUSED(source); - NVRENDER_BACKEND_UNUSED(errorMessage); - NVRENDER_BACKEND_UNUSED(binary); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return (NVRenderBackend::NVRenderBackendGeometryShaderObject)0; - } - - NVRenderBackend::NVRenderBackendComputeShaderObject - NVRenderBackendGLBase::CreateComputeShader(NVConstDataRef source, - eastl::string &errorMessage, bool binary) - { - // needs GL 4.3 or GLES3.1 support - NVRENDER_BACKEND_UNUSED(source); - NVRENDER_BACKEND_UNUSED(errorMessage); - NVRENDER_BACKEND_UNUSED(binary); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return (NVRenderBackend::NVRenderBackendComputeShaderObject)0; - } - - void NVRenderBackendGLBase::ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) - { - GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); - - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - } - - void NVRenderBackendGLBase::ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) - { - GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); - - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - } - - void - NVRenderBackendGLBase::ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) - { - GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); - - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - } - - void NVRenderBackendGLBase::ReleaseTessEvaluationShader( - NVRenderBackendTessEvaluationShaderObject teso) - { - GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); - - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - } - - void NVRenderBackendGLBase::ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) - { - GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); - - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - } - - void NVRenderBackendGLBase::ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) - { - GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); - - GL_CALL_FUNCTION(glDeleteShader(shaderID)); - } - - void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendVertexShaderObject vso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); - - GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendFragmentShaderObject fso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); - - GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessControlShaderObject tcso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); - - GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessEvaluationShaderObject teso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); - - GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendGeometryShaderObject gso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); - - GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendComputeShaderObject cso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); - - GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendVertexShaderObject vso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); - - GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendFragmentShaderObject fso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); - - GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessControlShaderObject tcso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); - - GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendTessEvaluationShaderObject teso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); - - GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendGeometryShaderObject gso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); - - GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, - NVRenderBackendComputeShaderObject cso) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); - - GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); - } - - NVRenderBackend::NVRenderBackendShaderProgramObject - NVRenderBackendGLBase::CreateShaderProgram(bool isSeparable) - { - NVRenderBackendShaderProgramGL *theProgram = NULL; - GLuint programID = GL_CALL_FUNCTION(glCreateProgram()); - - if (programID) { - theProgram = - QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendShaderProgramGL)(programID); - - if (!theProgram) { - GL_CALL_FUNCTION(glDeleteProgram(programID)); - } else if (isSeparable && m_backendSupport.caps.bits.bProgramPipelineSupported) { - GL_CALL_EXTRA_FUNCTION(glProgramParameteri(programID, GL_PROGRAM_SEPARABLE, GL_TRUE)); - } - } - - return (NVRenderBackend::NVRenderBackendShaderProgramObject)theProgram; - } - - void NVRenderBackendGLBase::ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GL_CALL_FUNCTION(glDeleteProgram(programID)); - - if (pProgram->m_shaderInput) { - NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); - pProgram->m_shaderInput = NULL; - } - - NVDelete(m_Foundation.getAllocator(), pProgram); - } - - bool NVRenderBackendGLBase::LinkProgram(NVRenderBackendShaderProgramObject po, - eastl::string &errorMessage) - { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GL_CALL_FUNCTION(glLinkProgram(programID)); - - GLint linkStatus, logLen; - GL_CALL_FUNCTION(glGetProgramiv(programID, GL_LINK_STATUS, &linkStatus)); - GL_CALL_FUNCTION(glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLen)); - - // if succesfuly linked get the attribute information - if (linkStatus) { - // release old stuff - if (pProgram->m_shaderInput) { - NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); - pProgram->m_shaderInput = NULL; - } - - GLint numAttribs; - GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTES, &numAttribs)); - - if (numAttribs) { - NVRenderBackendShaderInputEntryGL *tempShaderInputEntry = - (NVRenderBackendShaderInputEntryGL *)QT3DS_ALLOC( - m_Foundation.getAllocator(), - sizeof(NVRenderBackendShaderInputEntryGL) * m_MaxAttribCount, - "BackendShaderInputEntryGL"); - - GLint maxLength; - GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength)); - QT3DSI8 *nameBuf = - (QT3DSI8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), maxLength, "LinkProgram"); - - // fill in data - QT3DSU32 count = 0; - QT3DS_FOREACH(idx, numAttribs) - { - GLint size = 0; - GLenum glType; - NVRenderComponentTypes::Enum compType = NVRenderComponentTypes::Unknown; - QT3DSU32 numComps = 0; - - GL_CALL_FUNCTION(glGetActiveAttrib(programID, idx, maxLength, NULL, &size, &glType, - (char *)nameBuf)); - // Skip anything named with gl_ - if (memcmp(nameBuf, "gl_", 3) == 0) - continue; - - m_Conversion.fromAttribGLToComponentTypeAndNumComps(glType, compType, numComps); - - tempShaderInputEntry[count].m_AttribName = - m_StringTable->RegisterStr((char *)nameBuf); - tempShaderInputEntry[count].m_AttribLocation = - GL_CALL_FUNCTION(glGetAttribLocation(programID, (char *)nameBuf)); - tempShaderInputEntry[count].m_Type = glType; - tempShaderInputEntry[count].m_NumComponents = numComps; - - ++count; - } - - // Now allocate space for the actuall entries - QT3DSU32 shaderInputSize = sizeof(NVRenderBackendShaderInputGL); - QT3DSU32 entrySize = sizeof(NVRenderBackendShaderInputEntryGL) * count; - QT3DSU8 *newMem = - (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), shaderInputSize + entrySize, - "BackendShaderInputEntryGL"); - NVDataRef entryRef = - PtrAtOffset(newMem, shaderInputSize, - entrySize); - // fill data - QT3DS_FOREACH(idx, count) - { - entryRef[idx].m_AttribName = tempShaderInputEntry[idx].m_AttribName; - entryRef[idx].m_AttribLocation = tempShaderInputEntry[idx].m_AttribLocation; - entryRef[idx].m_Type = tempShaderInputEntry[idx].m_Type; - entryRef[idx].m_NumComponents = tempShaderInputEntry[idx].m_NumComponents; - } - - // placement new - NVRenderBackendShaderInputGL *shaderInput = - new (newMem) NVRenderBackendShaderInputGL(entryRef); - // set the pointer - pProgram->m_shaderInput = shaderInput; - - QT3DS_FREE(m_Foundation.getAllocator(), nameBuf); - QT3DS_FREE(m_Foundation.getAllocator(), tempShaderInputEntry); - } - } - - // Check if some log exists. We also write warnings here - // Should at least contain more than the null termination - if (logLen > 2) { - errorMessage.resize(logLen + 1); - - GLint lenWithoutNull; - GL_CALL_FUNCTION(glGetProgramInfoLog(programID, logLen, &lenWithoutNull, - (char *)errorMessage.c_str())); - } - - return (linkStatus == GL_TRUE); - } - - void NVRenderBackendGLBase::SetActiveProgram(NVRenderBackendShaderProgramObject po) - { - GLuint programID = 0; - - if (po) { - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - programID = static_cast(pProgram->m_ProgramID); - } - - GL_CALL_FUNCTION(glUseProgram(programID)); - } - - NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGLBase::CreateProgramPipeline() - { - // needs GL 4 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - return NVRenderBackend::NVRenderBackendProgramPipeline(0); - } - - void NVRenderBackendGLBase::ReleaseProgramPipeline(NVRenderBackendProgramPipeline) - { - // needs GL 4 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::SetActiveProgramPipeline(NVRenderBackendProgramPipeline) - { - // needs GL 4 context - //TODO: should be fixed? - // QT3DS_ASSERT(false); - } - - void NVRenderBackendGLBase::SetProgramStages(NVRenderBackendProgramPipeline, - NVRenderShaderTypeFlags, - NVRenderBackendShaderProgramObject) - { - // needs GL 4 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, - QT3DSU32) - { - // needs GL 4 context - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - QT3DSI32 NVRenderBackendGLBase::GetConstantCount(NVRenderBackendShaderProgramObject po) - { - QT3DS_ASSERT(po); - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GLint numUniforms; - GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORMS, &numUniforms)); - - return numUniforms; - } - - QT3DSI32 NVRenderBackendGLBase::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) - { - // needs GL3 and above - NVRENDER_BACKEND_UNUSED(po); - - return 0; - } - - QT3DSI32 - NVRenderBackendGLBase::GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 bufSize, QT3DSI32 *numElem, - NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, - char *nameBuf) - { - QT3DS_ASSERT(po); - NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; - GLuint programID = static_cast(pProgram->m_ProgramID); - - GLenum glType; - GL_CALL_FUNCTION(glGetActiveUniform(programID, id, bufSize, NULL, numElem, &glType, nameBuf)); - *type = m_Conversion.fromShaderGLToPropertyDataTypes(glType); - - QT3DSI32 uniformLoc = GL_CALL_FUNCTION(glGetUniformLocation(programID, nameBuf)); - - // get unit binding point - *binding = -1; - if (uniformLoc != -1 && (glType == GL_IMAGE_2D || glType == GL_UNSIGNED_INT_IMAGE_2D - || glType == GL_UNSIGNED_INT_ATOMIC_COUNTER)) { - GL_CALL_FUNCTION(glGetUniformiv(programID, uniformLoc, binding)); - } - - return uniformLoc; - } - - QT3DSI32 - NVRenderBackendGLBase::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, - char *nameBuf) - { - // needs GL3 and above - NVRENDER_BACKEND_UNUSED(po); - NVRENDER_BACKEND_UNUSED(id); - NVRENDER_BACKEND_UNUSED(nameBufSize); - NVRENDER_BACKEND_UNUSED(paramCount); - NVRENDER_BACKEND_UNUSED(bufferSize); - NVRENDER_BACKEND_UNUSED(length); - NVRENDER_BACKEND_UNUSED(nameBuf); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return -1; - } - - void NVRenderBackendGLBase::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSI32 *indices) - { - // needs GL3 and above - NVRENDER_BACKEND_UNUSED(po); - NVRENDER_BACKEND_UNUSED(id); - NVRENDER_BACKEND_UNUSED(indices); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GetConstantBufferParamInfoByIndices( - NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, - QT3DSI32 *size, QT3DSI32 *offset) - { - // needs GL3 and above - NVRENDER_BACKEND_UNUSED(po); - NVRENDER_BACKEND_UNUSED(count); - NVRENDER_BACKEND_UNUSED(indices); - NVRENDER_BACKEND_UNUSED(type); - NVRENDER_BACKEND_UNUSED(size); - NVRENDER_BACKEND_UNUSED(offset); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, - QT3DSU32 blockIndex, QT3DSU32 binding) - { - // needs GL3 and above - NVRENDER_BACKEND_UNUSED(po); - NVRENDER_BACKEND_UNUSED(blockIndex); - NVRENDER_BACKEND_UNUSED(binding); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::ProgramSetConstantBuffer(QT3DSU32 index, - NVRenderBackendBufferObject bo) - { - // needs GL3 and above - NVRENDER_BACKEND_UNUSED(index); - NVRENDER_BACKEND_UNUSED(bo); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - QT3DSI32 NVRenderBackendGLBase::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(po); - - return 0; - } - - QT3DSI32 - NVRenderBackendGLBase::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, - QT3DSU32 nameBufSize, QT3DSI32 *paramCount, - QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(po); - NVRENDER_BACKEND_UNUSED(id); - NVRENDER_BACKEND_UNUSED(nameBufSize); - NVRENDER_BACKEND_UNUSED(paramCount); - NVRENDER_BACKEND_UNUSED(bufferSize); - NVRENDER_BACKEND_UNUSED(length); - NVRENDER_BACKEND_UNUSED(nameBuf); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return -1; - } - - void NVRenderBackendGLBase::ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(index); - NVRENDER_BACKEND_UNUSED(bo); - } - - QT3DSI32 NVRenderBackendGLBase::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(po); - - return 0; - } - - QT3DSI32 - NVRenderBackendGLBase::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, - QT3DSU32 id, QT3DSU32 nameBufSize, - QT3DSI32 *paramCount, QT3DSI32 *bufferSize, - QT3DSI32 *length, char *nameBuf) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(po); - NVRENDER_BACKEND_UNUSED(id); - NVRENDER_BACKEND_UNUSED(nameBufSize); - NVRENDER_BACKEND_UNUSED(paramCount); - NVRENDER_BACKEND_UNUSED(bufferSize); - NVRENDER_BACKEND_UNUSED(length); - NVRENDER_BACKEND_UNUSED(nameBuf); - - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return -1; - } - - void NVRenderBackendGLBase::ProgramSetAtomicCounterBuffer(QT3DSU32 index, - NVRenderBackendBufferObject bo) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(index); - NVRENDER_BACKEND_UNUSED(bo); - } - - void NVRenderBackendGLBase::SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32 id, - NVRenderShaderDataTypes::Enum type, QT3DSI32 count, - const void *value, bool transpose) - { - GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); - - switch (glType) { - case GL_FLOAT: - GL_CALL_FUNCTION(glUniform1fv(id, count, (GLfloat *)value)); - break; - case GL_FLOAT_VEC2: - GL_CALL_FUNCTION(glUniform2fv(id, count, (GLfloat *)value)); - break; - case GL_FLOAT_VEC3: - GL_CALL_FUNCTION(glUniform3fv(id, count, (GLfloat *)value)); - break; - case GL_FLOAT_VEC4: - GL_CALL_FUNCTION(glUniform4fv(id, count, (GLfloat *)value)); - break; - case GL_INT: - GL_CALL_FUNCTION(glUniform1iv(id, count, (GLint *)value)); - break; - case GL_BOOL: - { - GLint boolValue = *(GLboolean *)value; - GL_CALL_FUNCTION(glUniform1iv(id, count, &boolValue)); - } - break; - case GL_INT_VEC2: - case GL_BOOL_VEC2: - GL_CALL_FUNCTION(glUniform2iv(id, count, (GLint *)value)); - break; - case GL_INT_VEC3: - case GL_BOOL_VEC3: - GL_CALL_FUNCTION(glUniform3iv(id, count, (GLint *)value)); - break; - case GL_INT_VEC4: - case GL_BOOL_VEC4: - GL_CALL_FUNCTION(glUniform4iv(id, count, (GLint *)value)); - break; - case GL_FLOAT_MAT3: - GL_CALL_FUNCTION(glUniformMatrix3fv(id, count, transpose, (GLfloat *)value)); - break; - case GL_FLOAT_MAT4: - GL_CALL_FUNCTION(glUniformMatrix4fv(id, count, transpose, (GLfloat *)value)); - break; - case GL_IMAGE_2D: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE: { - if (count > 1) { - GLint *sampler = (GLint *)value; - GL_CALL_FUNCTION(glUniform1iv(id, count, sampler)); - } else { - GLint sampler = *(GLint *)value; - GL_CALL_FUNCTION(glUniform1i(id, sampler)); - } - } break; - default: - qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); - QT3DS_ASSERT(false); - break; - } - } - - void NVRenderBackendGLBase::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) - { - GL_CALL_FUNCTION(glDrawArrays(m_Conversion.fromDrawModeToGL( - drawMode, m_backendSupport.caps.bits.bTessellationSupported), - start, count)); - } - - void NVRenderBackendGLBase::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(drawMode); - NVRENDER_BACKEND_UNUSED(indirect); - } - - void NVRenderBackendGLBase::DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, - NVRenderComponentTypes::Enum type, const void *indices) - { - GL_CALL_FUNCTION(glDrawElements(m_Conversion.fromDrawModeToGL( - drawMode, m_backendSupport.caps.bits.bTessellationSupported), - count, m_Conversion.fromIndexBufferComponentsTypesToGL(type), - indices)); - } - - void NVRenderBackendGLBase::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, - NVRenderComponentTypes::Enum type, - const void *indirect) - { - // needs GL4 and above - NVRENDER_BACKEND_UNUSED(drawMode); - NVRENDER_BACKEND_UNUSED(type); - NVRENDER_BACKEND_UNUSED(indirect); - } - - void NVRenderBackendGLBase::ReadPixel(NVRenderBackendRenderTargetObject /* rto */, QT3DSI32 x, - QT3DSI32 y, QT3DSI32 width, QT3DSI32 height, - NVRenderReadPixelFormats::Enum inFormat, void *pixels) - { - GLuint glFormat; - GLuint glType; - if (m_Conversion.fromReadPixelsToGlFormatAndType(inFormat, &glFormat, &glType)) { - GL_CALL_FUNCTION(glReadPixels(x, y, width, height, glFormat, glType, pixels)); - } - } - - NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::CreatePathNVObject(size_t) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return NVRenderBackend::NVRenderBackendPathObject(0); - } - - void NVRenderBackendGLBase::ReleasePathNVObject(NVRenderBackendPathObject, size_t) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::LoadPathGlyphs(NVRenderBackendPathObject, - NVRenderPathFontTarget::Enum, const void *, - NVRenderPathFontStyleFlags, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathMissingGlyphs::Enum, - NVRenderBackendPathObject, QT3DSF32) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::LoadPathGlyphRange(NVRenderBackendPathObject, - NVRenderPathFontTarget::Enum, const void *, - NVRenderPathFontStyleFlags, QT3DSU32, size_t, - NVRenderPathMissingGlyphs::Enum, - NVRenderBackendPathObject, QT3DSF32) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - NVRenderPathReturnValues::Enum NVRenderBackendGLBase::LoadPathGlyphsIndexed( - NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, - NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, QT3DSF32) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - - return NVRenderPathReturnValues::FontUnavailable; - } - - NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::LoadPathGlyphsIndexedRange( - NVRenderPathFontTarget::Enum, const void *, NVRenderPathFontStyleFlags, - NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) - { - return NVRenderBackendPathObject(0); - } - - void NVRenderBackendGLBase::GetPathMetrics(NVRenderBackendPathObject, size_t, - NVRenderPathGlyphFontMetricFlags, - NVRenderPathFormatType::Enum, const void *, size_t, - QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GetPathMetricsRange(NVRenderBackendPathObject, size_t, - NVRenderPathGlyphFontMetricFlags, size_t, - QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::GetPathSpacing(NVRenderBackendPathObject, size_t, - NVRenderPathListMode::Enum, - NVRenderPathFormatType::Enum, const void *, QT3DSF32, - QT3DSF32, NVRenderPathTransformType::Enum, QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::StencilFillPathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathFillMode::Enum, QT3DSU32, - NVRenderPathTransformType::Enum, - const QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, - const void *, QT3DSI32, QT3DSU32, - NVRenderPathTransformType::Enum, - const QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::CoverFillPathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathCoverMode::Enum, - NVRenderPathTransformType::Enum, - const QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - void NVRenderBackendGLBase::CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathCoverMode::Enum, - NVRenderPathTransformType::Enum, - const QT3DSF32 *) - { - // Needs GL 4 backend - qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; - } - - ///< private calls - const char *NVRenderBackendGLBase::getVersionString() - { - const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VERSION)); - if (retval == NULL) - return ""; - - return retval; - } - - const char *NVRenderBackendGLBase::getVendorString() - { - const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VENDOR)); - if (retval == NULL) - return ""; - - return retval; - } - - const char *NVRenderBackendGLBase::getRendererString() - { - const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER)); - if (retval == NULL) - return ""; - - return retval; - } - - const char *NVRenderBackendGLBase::getExtensionString() - { - const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS)); - if (retval == NULL) - return ""; - - return retval; - } - - /** - * @brief This function inspects the various strings to setup - * HW capabilities of the device. - * We can do a lot of smart things here based on GL version - * renderer string and vendor. - * - * @return No return - */ - void NVRenderBackendGLBase::setAndInspectHardwareCaps() - { - eastl::string apiVersion(getVersionString()); - qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); - - // we assume all GLES versions running on mobile with shared memory - // this means framebuffer blits are slow and should be optimized or avoided - if (apiVersion.find("OpenGL ES") == eastl::string::npos) { - // no ES device - m_backendSupport.caps.bits.bFastBlitsSupported = true; - } - } - -#ifdef RENDER_BACKEND_LOG_GL_ERRORS - void NVRenderBackendGLBase::checkGLError(const char *function, const char *file, - const unsigned int line) const - { - GLenum error = m_glFunctions->glGetError(); - if (error != GL_NO_ERROR) { - qCCritical(GL_ERROR) << GLConversion::processGLError(error) << " " - << function << " " << file << " " << line; - } - } -#else - void NVRenderBackendGLBase::checkGLError() const - { -#if !defined(NDEBUG) || defined(_DEBUG) - GLenum error = m_glFunctions->glGetError(); - if (error != GL_NO_ERROR) - qCCritical(GL_ERROR) << GLConversion::processGLError(error); -#endif - } -#endif - -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp deleted file mode 100644 index 88670ef7..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSMat44.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Utils.h" -#include "EASTL/set.h" -#include "EASTL/utility.h" -#include "render/Qt3DSRenderShaderProgram.h" - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace eastl; - -namespace qt3ds { -namespace render { - - NVRenderContext &NVRenderContext::CreateGL(NVFoundationBase &foundation, - IStringTable &inStringTable, - const QSurfaceFormat &format) - { - NVRenderContext *retval = NULL; - - QT3DS_ASSERT(format.majorVersion() >= 2); - - // create backend - NVScopedRefCounted theStringTable(inStringTable); - NVScopedRefCounted theBackend; - bool isES = format.renderableType() == QSurfaceFormat::OpenGLES; - if (isES && (format.majorVersion() == 2 - || (format.majorVersion() == 3 && format.minorVersion() == 0))) { - theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGLES2Impl)(foundation, - *theStringTable, - format); - } else if (format.majorVersion() == 3 && format.minorVersion() >= 1 && !isES) { - theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, - *theStringTable, - format); - } else if (format.majorVersion() == 4 - || (isES && format.majorVersion() == 3 && format.minorVersion() >= 1)) { -#ifdef Q_OS_MACOS - // TODO: macOS crashes with glTextStorage2DMultisample, so fall back to OpenGL3 - // for now (QT3DS-590) - theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, - *theStringTable, - format); -#else - theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL4Impl)(foundation, - *theStringTable, - format); -#endif - } else { - QT3DS_ASSERT(false); - qCCritical(INTERNAL_ERROR) << "Can't find a suitable OpenGL version for" << format; - } - - - retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, - *theStringTable); - - return *retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp deleted file mode 100644 index af93e928..00000000 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp +++ /dev/null @@ -1,588 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "render/backends/software/Qt3DSRenderBackendNULL.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" - -#include - -using namespace qt3ds::render; -using namespace qt3ds::foundation; -using namespace qt3ds; - -namespace { -struct SNullBackend : public NVRenderBackend -{ - NVFoundationBase &m_Foundation; - QT3DSI32 mRefCount; - - SNullBackend(NVFoundationBase &fnd) - : m_Foundation(fnd) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - /// backend interface - - NVRenderContextType GetRenderContextType() const override - { - return NVRenderContextValues::NullContext; - } - const char *GetShadingLanguageVersion() override { return ""; } - QT3DSU32 GetMaxCombinedTextureUnits() override { return 32; } - bool GetRenderBackendCap(NVRenderBackendCaps::Enum) const override { return false; } - void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override - { - if (params) { - switch (inQuery) { - case NVRenderBackendQuery::MaxTextureSize: - *params = 4096; - break; - case NVRenderBackendQuery::MaxTextureArrayLayers: - *params = 0; - break; - default: - QT3DS_ASSERT(false); - *params = 0; - break; - } - } - } - QT3DSU32 GetDepthBits() const override { return 16; } - QT3DSU32 GetStencilBits() const override { return 0; } - void SetRenderState(bool, const NVRenderState::Enum) override {} - bool GetRenderState(const NVRenderState::Enum) override { return false; } - virtual NVRenderBackendDepthStencilStateObject - CreateDepthStencilState(bool, bool, NVRenderBoolOp::Enum, bool, - NVRenderStencilFunctionArgument &, NVRenderStencilFunctionArgument &, - NVRenderStencilOperationArgument &, NVRenderStencilOperationArgument &) override - { - return NVRenderBackendDepthStencilStateObject(1); - } - void ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} - NVRenderBackendRasterizerStateObject CreateRasterizerState(QT3DSF32, QT3DSF32, - NVRenderFaces::Enum) override - { - return NVRenderBackendRasterizerStateObject(1); - } - void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject) override {} - void SetDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} - void SetRasterizerState(NVRenderBackendRasterizerStateObject) override {} - NVRenderBoolOp::Enum GetDepthFunc() override { return NVRenderBoolOp::Equal; } - void SetDepthFunc(const NVRenderBoolOp::Enum) override {} - bool GetDepthWrite() override { return false; } - - void SetDepthWrite(bool) override {} - void SetColorWrites(bool, bool, bool, bool) override {} - void SetMultisample(bool) override {} - void GetBlendFunc(NVRenderBlendFunctionArgument *) override {} - void SetBlendFunc(const NVRenderBlendFunctionArgument &) override {} - void SetBlendEquation(const NVRenderBlendEquationArgument &) override {} - void SetBlendBarrier(void) override {} - void GetScissorRect(NVRenderRect *) override {} - void SetScissorRect(const NVRenderRect &) override {} - void GetViewportRect(NVRenderRect *) override {} - void SetViewportRect(const NVRenderRect &) override {} - void SetClearColor(const QT3DSVec4 *) override {} - void Clear(NVRenderClearFlags) override {} - NVRenderBackendBufferObject CreateBuffer(size_t, NVRenderBufferBindFlags, - NVRenderBufferUsageType::Enum, const void *) override - { - return NVRenderBackendBufferObject(1); - } - void BindBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override {} - void ReleaseBuffer(NVRenderBackendBufferObject) override {} - - void UpdateBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, - NVRenderBufferUsageType::Enum, const void *) override - { - } - void UpdateBufferRange(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, - const void *) override - { - } - void *MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, - NVRenderBufferAccessFlags) override - { - return NULL; - } - bool UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override { return true; } - void SetMemoryBarrier(NVRenderBufferBarrierFlags) override {} - NVRenderBackendQueryObject CreateQuery() override { return NVRenderBackendQueryObject(1); } - void ReleaseQuery(NVRenderBackendQueryObject) override {} - void BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} - void EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} - void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, - QT3DSU32 *) override {} - void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, - QT3DSU64 *) override {} - void SetQueryTimer(NVRenderBackendQueryObject) override {} - NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) override - { - return NVRenderBackendSyncObject(1); - }; - void ReleaseSync(NVRenderBackendSyncObject) override {} - void WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, QT3DSU64) override {} - NVRenderBackendRenderTargetObject CreateRenderTarget() override - { - return NVRenderBackendRenderTargetObject(1); - } - void ReleaseRenderTarget(NVRenderBackendRenderTargetObject) override {} - void RenderTargetAttach(NVRenderBackendRenderTargetObject, - NVRenderFrameBufferAttachments::Enum, - NVRenderBackendRenderbufferObject) override - { - } - void RenderTargetAttach(NVRenderBackendRenderTargetObject, - NVRenderFrameBufferAttachments::Enum, - NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum) override - { - } - void RenderTargetAttach(NVRenderBackendRenderTargetObject, - NVRenderFrameBufferAttachments::Enum, - NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) override - { - } - void SetRenderTarget(NVRenderBackendRenderTargetObject) override {} - bool RenderTargetIsValid(NVRenderBackendRenderTargetObject) override { return false; } - void SetReadTarget(NVRenderBackendRenderTargetObject) override {} - void SetDrawBuffers(NVRenderBackendRenderTargetObject, NVConstDataRef) override {} - void SetReadBuffer(NVRenderBackendRenderTargetObject, NVReadFaces::Enum) override {} - - void BlitFramebuffer(QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, - NVRenderClearFlags, NVRenderTextureMagnifyingOp::Enum) override - { - } - NVRenderBackendRenderbufferObject CreateRenderbuffer(NVRenderRenderBufferFormats::Enum, - size_t, size_t) override - { - return NVRenderBackendRenderbufferObject(1); - } - void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject) override {} - - bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject, - NVRenderRenderBufferFormats::Enum, size_t, size_t) override - { - return false; - } - NVRenderBackendTextureObject CreateTexture() override { return NVRenderBackendTextureObject(1); } - - void SetTextureData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, - QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, - NVRenderTextureFormats::Enum, const void *) override - { - } - void SetTextureDataCubeFace(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, - NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, - NVRenderTextureFormats::Enum, const void *) override - { - } - void CreateTextureStorage2D(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, - NVRenderTextureFormats::Enum, size_t, size_t) override - { - } - void SetTextureSubData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, - QT3DSU32, QT3DSI32, QT3DSI32, size_t, size_t, - NVRenderTextureFormats::Enum, const void *) override - { - } - void SetCompressedTextureData2D(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, - NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, - size_t, const void *) override - { - } - void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, - NVRenderTextureFormats::Enum, size_t, size_t, - QT3DSI32, size_t, const void *) override - { - } - void SetCompressedTextureSubData2D(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, QT3DSU32, QT3DSI32, QT3DSI32, - size_t, size_t, NVRenderTextureFormats::Enum, size_t, - const void *) override - { - } - void SetMultisampledTextureData2D(NVRenderBackendTextureObject, - NVRenderTextureTargetType::Enum, size_t, - NVRenderTextureFormats::Enum, size_t, size_t, bool) override - { - } - void SetTextureData3D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, - QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, size_t, - QT3DSI32, NVRenderTextureFormats::Enum, const void *) override - { - } - void GenerateMipMaps(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, - NVRenderHint::Enum) override - { - } - void BindTexture(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, QT3DSU32) override - { - } - void BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, QT3DSI32, - NVRenderImageAccessType::Enum, NVRenderTextureFormats::Enum) override - { - } - void ReleaseTexture(NVRenderBackendTextureObject) override {} - - virtual NVRenderTextureSwizzleMode::Enum - GetTextureSwizzleMode(const NVRenderTextureFormats::Enum) const override - { - return NVRenderTextureSwizzleMode::NoSwizzle; - } - - virtual NVRenderBackendSamplerObject - CreateSampler(NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, - NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, - NVRenderTextureCoordOp::Enum, QT3DSI32, QT3DSI32, QT3DSF32, - NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, QT3DSF32, QT3DSF32 *) override - { - return NVRenderBackendSamplerObject(1); - } - - void UpdateSampler(NVRenderBackendSamplerObject, NVRenderTextureTargetType::Enum, - NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, - NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, - NVRenderTextureCoordOp::Enum, QT3DSF32, QT3DSF32, QT3DSF32, - NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, - QT3DSF32, QT3DSF32 *) override - { - } - - void UpdateTextureObject(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, - QT3DSI32, QT3DSI32) override - { - } - - void UpdateTextureSwizzle(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, - NVRenderTextureSwizzleMode::Enum) override - { - } - - void ReleaseSampler(NVRenderBackendSamplerObject) override {} - - virtual NVRenderBackendAttribLayoutObject - CreateAttribLayout(NVConstDataRef) override - { - return NVRenderBackendAttribLayoutObject(1); - } - - void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject) override {} - - NVRenderBackendInputAssemblerObject CreateInputAssembler( - NVRenderBackendAttribLayoutObject, NVConstDataRef, - const NVRenderBackendBufferObject, NVConstDataRef, NVConstDataRef, QT3DSU32) override - { - return NVRenderBackendInputAssemblerObject(1); - } - void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject) override {} - bool SetInputAssembler(NVRenderBackendInputAssemblerObject, - NVRenderBackendShaderProgramObject) override - { - return false; - } - void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override {} - NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef, - eastl::string &, bool) override - { - return NVRenderBackendVertexShaderObject(1); - } - void ReleaseVertexShader(NVRenderBackendVertexShaderObject) override {} - NVRenderBackendFragmentShaderObject CreateFragmentShader(NVConstDataRef, - eastl::string &, bool) override - { - return NVRenderBackendFragmentShaderObject(1); - } - void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject) override {} - NVRenderBackendTessControlShaderObject CreateTessControlShader(NVConstDataRef, - eastl::string &, bool) override - { - return NVRenderBackendTessControlShaderObject(1); - } - void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject) override {} - virtual NVRenderBackendTessEvaluationShaderObject - CreateTessEvaluationShader(NVConstDataRef, eastl::string &, bool) override - { - return NVRenderBackendTessEvaluationShaderObject(1); - } - void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject) override {} - NVRenderBackendGeometryShaderObject CreateGeometryShader(NVConstDataRef, - eastl::string &, bool) override - { - return NVRenderBackendGeometryShaderObject(1); - } - void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject) override {} - NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef, - eastl::string &, bool) override - { - return NVRenderBackendComputeShaderObject(1); - } - void ReleaseComputeShader(NVRenderBackendComputeShaderObject) override {} - void AttachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override - { - } - void AttachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendFragmentShaderObject) override - { - } - void AttachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendTessControlShaderObject) override - { - } - void AttachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendTessEvaluationShaderObject) override - { - } - void AttachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendGeometryShaderObject) override - { - } - void AttachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendComputeShaderObject) override - { - } - void DetachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override - { - } - void DetachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendFragmentShaderObject) override - { - } - void DetachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendTessControlShaderObject) override - { - } - void DetachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendTessEvaluationShaderObject) override - { - } - void DetachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendGeometryShaderObject) override - { - } - void DetachShader(NVRenderBackendShaderProgramObject, - NVRenderBackendComputeShaderObject) override - { - } - NVRenderBackendShaderProgramObject CreateShaderProgram(bool) override - { - return NVRenderBackendShaderProgramObject(1); - } - void ReleaseShaderProgram(NVRenderBackendShaderProgramObject) override {} - NVRenderBackendProgramPipeline CreateProgramPipeline() override - { - return NVRenderBackendProgramPipeline(1); - } - void ReleaseProgramPipeline(NVRenderBackendProgramPipeline) override {} - - bool LinkProgram(NVRenderBackendShaderProgramObject, eastl::string &) override { return false; } - void SetActiveProgram(NVRenderBackendShaderProgramObject) override {} - void SetActiveProgramPipeline(NVRenderBackendProgramPipeline) override {} - void SetProgramStages(NVRenderBackendProgramPipeline, NVRenderShaderTypeFlags, - NVRenderBackendShaderProgramObject) override {} - void DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSU32) override {} - QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject) override { return 0; } - QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } - QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSI32 *, - NVRenderShaderDataTypes::Enum *, QT3DSI32 *, char *) override - { - return 0; - } - - QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, - QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override - { - return 0; - } - - void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSI32 *) override - { - } - void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject, QT3DSU32, - QT3DSU32 *, QT3DSI32 *, QT3DSI32 *, QT3DSI32 *) override {} - void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32) override {} - void ProgramSetConstantBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} - - QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject) override { return 0; }; - QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, - QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override - { - return -1; - } - void ProgramSetStorageBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} - - QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } - QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, - QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override - { - return -1; - }; - void ProgramSetAtomicCounterBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} - - void SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32, - NVRenderShaderDataTypes::Enum, QT3DSI32, const void *, bool) override - { - } - - void Draw(NVRenderDrawMode::Enum, QT3DSU32, QT3DSU32) override {} - void DrawIndirect(NVRenderDrawMode::Enum, const void *) override {} - - void DrawIndexed(NVRenderDrawMode::Enum, QT3DSU32, NVRenderComponentTypes::Enum, - const void *) override - { - } - void DrawIndexedIndirect(NVRenderDrawMode::Enum, NVRenderComponentTypes::Enum, - const void *) override - { - } - - void ReadPixel(NVRenderBackendRenderTargetObject, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, - NVRenderReadPixelFormats::Enum, void *) override - { - } - - NVRenderBackendPathObject CreatePathNVObject(size_t) override - { - return NVRenderBackendPathObject(1); - }; - void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef, - NVConstDataRef) override - { - } - - ///< Bounds of the fill and stroke - NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override - { - return NVBounds3(); - } - NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override - { - return NVBounds3(); - } - NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override - { - return NVBounds3(); - } - - /** - * Defaults to 0 if unset. - */ - void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} - void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} - void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} - - void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} - void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} - void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} - void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} - void ReleasePathNVObject(NVRenderBackendPathObject, size_t) override {} - - void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, - const void *, NVRenderPathFontStyleFlags, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, QT3DSF32) override - { - } - virtual NVRenderPathReturnValues::Enum - LoadPathGlyphsIndexed(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, - NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, - QT3DSF32) override - { - return NVRenderPathReturnValues::FontUnavailable; - } - NVRenderBackendPathObject LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, - const void *, - NVRenderPathFontStyleFlags, - NVRenderBackendPathObject, QT3DSF32, - QT3DSU32 *) override - { - return NVRenderBackendPathObject(1); - } - void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, - const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, - NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, - QT3DSF32) override - { - } - void GetPathMetrics(NVRenderBackendPathObject, size_t, NVRenderPathGlyphFontMetricFlags, - NVRenderPathFormatType::Enum, const void *, size_t, QT3DSF32 *) override - { - } - void GetPathMetricsRange(NVRenderBackendPathObject, size_t, - NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override - { - } - void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, - NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, - NVRenderPathTransformType::Enum, QT3DSF32 *) override - { - } - - void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathFillMode::Enum, QT3DSU32, - NVRenderPathTransformType::Enum, const QT3DSF32 *) override - { - } - void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, QT3DSI32, - QT3DSU32, NVRenderPathTransformType::Enum, const QT3DSF32 *) override - { - } - void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathCoverMode::Enum, - NVRenderPathTransformType::Enum, const QT3DSF32 *) override - { - } - void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, - NVRenderPathFormatType::Enum, const void *, - NVRenderPathCoverMode::Enum, - NVRenderPathTransformType::Enum, const QT3DSF32 *) override - { - } - QSurfaceFormat format() const override - { - return QSurfaceFormat(); - } -}; -} - -NVRenderBackend &NVRenderBackendNULL::CreateBackend(NVFoundationBase &foundation) -{ - return *QT3DS_NEW(foundation.getAllocator(), SNullBackend)(foundation); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.cpp deleted file mode 100644 index 062a36c5..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderPresentation.h" -#include "foundation/Qt3DSVec2.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSTextRenderer.h" - -#include - -using namespace qt3ds::render; - -namespace { - -QT3DSF32 GetAspectRatio(const NVRenderRectF &inViewport) -{ - return inViewport.m_Height != 0 ? inViewport.m_Width / inViewport.m_Height : 0.0f; -} - -QT3DSF32 GetAspectRatio(const QT3DSVec2 &inDimensions) -{ - return inDimensions.y != 0 ? inDimensions.x / inDimensions.y : 0.0f; -} - -bool IsCameraVerticalAdjust(CameraScaleModes::Enum inMode, QT3DSF32 inDesignAspect, - QT3DSF32 inActualAspect) -{ - return (inMode == CameraScaleModes::Fit && inActualAspect >= inDesignAspect) - || inMode == CameraScaleModes::FitVertical; -} - -bool IsCameraHorizontalAdjust(CameraScaleModes::Enum inMode, QT3DSF32 inDesignAspect, - QT3DSF32 inActualAspect) -{ - return (inMode == CameraScaleModes::Fit && inActualAspect < inDesignAspect) - || inMode == CameraScaleModes::FitHorizontal; -} - -bool IsFitTypeScaleMode(CameraScaleModes::Enum inMode) -{ - return inMode == CameraScaleModes::Fit || inMode == CameraScaleModes::FitHorizontal - || inMode == CameraScaleModes::FitVertical; -} - -struct SPinCameraResult -{ - NVRenderRectF m_Viewport; - NVRenderRectF m_VirtualViewport; - SPinCameraResult(NVRenderRectF v, NVRenderRectF vv) - : m_Viewport(v) - , m_VirtualViewport(vv) - { - } -}; -// Scale and transform the projection matrix to respect the camera anchor attribute -// and the scale mode. -SPinCameraResult PinCamera(const NVRenderRectF &inViewport, QT3DSVec2 inDesignDims, - QT3DSMat44 &ioPerspectiveMatrix, CameraScaleModes::Enum inScaleMode, - CameraScaleAnchors::Enum inPinLocation) -{ - NVRenderRectF viewport(inViewport); - NVRenderRectF idealViewport(inViewport.m_X, inViewport.m_Y, inDesignDims.x, inDesignDims.y); - QT3DSF32 designAspect = GetAspectRatio(inDesignDims); - QT3DSF32 actualAspect = GetAspectRatio(inViewport); - if (IsFitTypeScaleMode(inScaleMode)) { - idealViewport.m_Width = viewport.m_Width; - idealViewport.m_Height = viewport.m_Height; - } - // We move the viewport such that the left, top of the presentation sits against the left top - // edge - // We only need to translate in X *if* our actual aspect > design aspect - // And then we only need to account for whatever centering would happen. - - bool pinLeft = inPinLocation == CameraScaleAnchors::SouthWest - || inPinLocation == CameraScaleAnchors::West - || inPinLocation == CameraScaleAnchors::NorthWest; - bool pinRight = inPinLocation == CameraScaleAnchors::SouthEast - || inPinLocation == CameraScaleAnchors::East - || inPinLocation == CameraScaleAnchors::NorthEast; - bool pinTop = inPinLocation == CameraScaleAnchors::NorthWest - || inPinLocation == CameraScaleAnchors::North - || inPinLocation == CameraScaleAnchors::NorthEast; - bool pinBottom = inPinLocation == CameraScaleAnchors::SouthWest - || inPinLocation == CameraScaleAnchors::South - || inPinLocation == CameraScaleAnchors::SouthEast; - - if (inScaleMode == CameraScaleModes::SameSize) { - // In this case the perspective transform does not center the view, - // it places it in the lower-left of the viewport. - QT3DSF32 idealWidth = inDesignDims.x; - QT3DSF32 idealHeight = inDesignDims.y; - if (pinRight) - idealViewport.m_X -= ((idealWidth - inViewport.m_Width)); - else if (!pinLeft) - idealViewport.m_X -= ((idealWidth - inViewport.m_Width) / 2.0f); - - if (pinTop) - idealViewport.m_Y -= ((idealHeight - inViewport.m_Height)); - else if (!pinBottom) - idealViewport.m_Y -= ((idealHeight - inViewport.m_Height) / 2.0f); - } else { - // In this case our perspective matrix will center the view and we need to decenter - // it as necessary - // if we are wider than we are high - if (IsCameraVerticalAdjust(inScaleMode, designAspect, actualAspect)) { - if (pinLeft || pinRight) { - QT3DSF32 idealWidth = inViewport.m_Height * designAspect; - QT3DSI32 halfOffset = (QT3DSI32)((idealWidth - inViewport.m_Width) / 2.0f); - halfOffset = pinLeft ? halfOffset : -1 * halfOffset; - idealViewport.m_X += halfOffset; - } - } else { - if (pinTop || pinBottom) { - QT3DSF32 idealHeight = inViewport.m_Width / designAspect; - QT3DSI32 halfOffset = (QT3DSI32)((idealHeight - inViewport.m_Height) / 2.0f); - halfOffset = pinBottom ? halfOffset : -1 * halfOffset; - idealViewport.m_Y += halfOffset; - } - } - } - - ioPerspectiveMatrix = NVRenderContext::ApplyVirtualViewportToProjectionMatrix( - ioPerspectiveMatrix, viewport, idealViewport); - return SPinCameraResult(viewport, idealViewport); -} -} - -SCamera::SCamera() - : SNode(GraphObjectTypes::Camera) - , m_ClipNear(10) - , m_ClipFar(10000) - , m_FOV(60) - , m_FOVHorizontal(false) - , m_ScaleMode(CameraScaleModes::Fit) - , m_ScaleAnchor(CameraScaleAnchors::Center) -{ - TORAD(m_FOV); - m_Projection = QT3DSMat44::createIdentity(); - m_Position = QT3DSVec3(0, 0, -600); -} - -// Code for testing -SCameraGlobalCalculationResult SCamera::CalculateGlobalVariables(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) -{ - bool wasDirty = SNode::CalculateGlobalVariables(); - return SCameraGlobalCalculationResult(wasDirty, - CalculateProjection(inViewport, inDesignDimensions)); -} - -bool SCamera::CalculateProjection(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions) -{ - bool retval = false; - if (m_Flags.IsOrthographic()) - retval = ComputeFrustumOrtho(inViewport, inDesignDimensions); - else - retval = ComputeFrustumPerspective(inViewport, inDesignDimensions); - if (retval) { - QT3DSF32 *writePtr(m_Projection.front()); - m_FrustumScale.x = writePtr[0]; - m_FrustumScale.y = writePtr[5]; - PinCamera(inViewport, inDesignDimensions, m_Projection, m_ScaleMode, m_ScaleAnchor); - } - return retval; -} - -//============================================================================== -/** - * Compute the projection matrix for a perspective camera - * @return true if the computed projection matrix is valid - */ -bool SCamera::ComputeFrustumPerspective(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) -{ - m_Projection = QT3DSMat44::createIdentity(); - QT3DSF32 theAngleInRadians = verticalFov(inViewport) / 2.0f; - QT3DSF32 theDeltaZ = m_ClipFar - m_ClipNear; - QT3DSF32 theSine = sinf(theAngleInRadians); - QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); - QT3DSF32 theAspectRatio = designAspect; - if (IsFitTypeScaleMode(m_ScaleMode)) - theAspectRatio = GetAspectRatio(inViewport); - - if ((theDeltaZ != 0) && (theSine != 0) && (theAspectRatio != 0)) { - QT3DSF32 *writePtr(m_Projection.front()); - writePtr[10] = -(m_ClipFar + m_ClipNear) / theDeltaZ; - writePtr[11] = -1; - writePtr[14] = -2 * m_ClipNear * m_ClipFar / theDeltaZ; - writePtr[15] = 0; - - if (IsCameraVerticalAdjust(m_ScaleMode, designAspect, theAspectRatio)) { - QT3DSF32 theCotangent = cosf(theAngleInRadians) / theSine; - writePtr[0] = theCotangent / theAspectRatio; - writePtr[5] = theCotangent; - } else { - QT3DSF32 theCotangent = cosf(theAngleInRadians) / theSine; - writePtr[0] = theCotangent / designAspect; - writePtr[5] = theCotangent * (theAspectRatio / designAspect); - } - return true; - } else { - QT3DS_ASSERT(false); - return false; - } -} - -//============================================================================== -/** - * Compute the projection matrix for a orthographic camera - * @return true if the computed projection matrix is valid - */ -bool SCamera::ComputeFrustumOrtho(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions) -{ - m_Projection = QT3DSMat44::createIdentity(); - - QT3DSF32 theDeltaZ = m_ClipFar - m_ClipNear; - QT3DSF32 halfWidth = inDesignDimensions.x / 2.0f; - QT3DSF32 halfHeight = inDesignDimensions.y / 2.0f; - QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); - QT3DSF32 theAspectRatio = designAspect; - if (IsFitTypeScaleMode(m_ScaleMode)) - theAspectRatio = GetAspectRatio(inViewport); - if (theDeltaZ != 0) { - QT3DSF32 *writePtr(m_Projection.front()); - writePtr[10] = -2.0f / theDeltaZ; - writePtr[11] = 0.0f; - writePtr[14] = -(m_ClipNear + m_ClipFar) / theDeltaZ; - writePtr[15] = 1.0f; - if (IsCameraVerticalAdjust(m_ScaleMode, designAspect, theAspectRatio)) { - writePtr[0] = 1.0f / (halfHeight * theAspectRatio); - writePtr[5] = 1.0f / halfHeight; - } else { - writePtr[0] = 1.0f / halfWidth; - writePtr[5] = 1.0f / (halfWidth / theAspectRatio); - } - return true; - } else { - QT3DS_ASSERT(false); - return false; - } -} - -QT3DSF32 SCamera::GetOrthographicScaleFactor(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const -{ - if (m_ScaleMode == CameraScaleModes::SameSize) - return 1.0f; - QT3DSMat44 temp(QT3DSMat44::createIdentity()); - QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); - QT3DSF32 theAspectRatio = GetAspectRatio(inViewport); - if (m_ScaleMode == CameraScaleModes::Fit) { - if (theAspectRatio >= designAspect) { - return inViewport.m_Width < inDesignDimensions.x ? theAspectRatio / designAspect : 1.0f; - - } else { - return inViewport.m_Height < inDesignDimensions.y ? designAspect / theAspectRatio - : 1.0f; - } - } else if (m_ScaleMode == CameraScaleModes::FitVertical) { - return (QT3DSF32)inDesignDimensions.y / (QT3DSF32)inViewport.m_Height; - } else { - return (QT3DSF32)inDesignDimensions.x / (QT3DSF32)inViewport.m_Width; - } -} - -QT3DSF32 SCamera::GetTextScaleFactor(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const -{ - return NVMax(1.0f, 1.0f / GetOrthographicScaleFactor(inViewport, inDesignDimensions)); -} - -QT3DSMat33 SCamera::GetLookAtMatrix(const QT3DSVec3 &inUpDir, const QT3DSVec3 &inDirection) const -{ - QT3DSVec3 theDirection(inDirection); - - theDirection.normalize(); - - const QT3DSVec3 &theUpDir(inUpDir); - - // gram-shmidt orthogonalization - QT3DSVec3 theCrossDir(theDirection.cross(theUpDir)); - theCrossDir.normalize(); - QT3DSVec3 theFinalDir(theCrossDir.cross(theDirection)); - theFinalDir.normalize(); - QT3DSF32 multiplier = 1.0f; - if (m_Flags.IsLeftHanded()) - multiplier = -1.0f; - - QT3DSMat33 theResultMatrix(theCrossDir, theFinalDir, multiplier * theDirection); - return theResultMatrix; -} - -void SCamera::LookAt(const QT3DSVec3 &inCameraPos, const QT3DSVec3 &inUpDir, const QT3DSVec3 &inTargetPos) -{ - QT3DSVec3 theDirection = inTargetPos - inCameraPos; - if (m_Flags.IsLeftHanded()) - theDirection.z *= -1.0f; - m_Rotation = GetRotationVectorFromRotationMatrix(GetLookAtMatrix(inUpDir, theDirection)); - m_Position = inCameraPos; - MarkDirty(qt3ds::render::NodeTransformDirtyFlag::TransformIsDirty); -} - -void SCamera::CalculateViewProjectionMatrix(QT3DSMat44 &outMatrix) const -{ - QT3DSMat44 globalInverse = m_GlobalTransform.getInverse(); - outMatrix = m_Projection * globalInverse; -} - -SCuboidRect SCamera::GetCameraBounds(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const -{ - QT3DSMat44 unused(QT3DSMat44::createIdentity()); - SPinCameraResult theResult = - PinCamera(inViewport, inDesignDimensions, unused, m_ScaleMode, m_ScaleAnchor); - // find the normalized edges of the view frustum given the renormalization that happens when - // pinning the camera. - SCuboidRect normalizedCuboid(-1, 1, 1, -1); - QT3DSVec2 translation(theResult.m_Viewport.m_X - theResult.m_VirtualViewport.m_X, - theResult.m_Viewport.m_Y - theResult.m_VirtualViewport.m_Y); - if (m_ScaleMode == CameraScaleModes::SameSize) { - // the cuboid ranges are the actual divided by the ideal in this case - QT3DSF32 xRange = 2.0f * (theResult.m_Viewport.m_Width / theResult.m_VirtualViewport.m_Width); - QT3DSF32 yRange = - 2.0f * (theResult.m_Viewport.m_Height / theResult.m_VirtualViewport.m_Height); - normalizedCuboid = SCuboidRect(-1, -1 + yRange, -1 + xRange, -1); - translation.x /= (theResult.m_VirtualViewport.m_Width / 2.0f); - translation.y /= (theResult.m_VirtualViewport.m_Height / 2.0f); - normalizedCuboid.Translate(translation); - } - // fit. This means that two parameters of the normalized cuboid will be -1, 1. - else { - // In this case our perspective matrix will center the view and we need to decenter - // it as necessary - QT3DSF32 actualAspect = GetAspectRatio(inViewport); - QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); - // if we are wider than we are high - QT3DSF32 idealWidth = inViewport.m_Width; - QT3DSF32 idealHeight = inViewport.m_Height; - - if (IsCameraVerticalAdjust(m_ScaleMode, designAspect, actualAspect)) { - // then we just need to setup the left, right parameters of the cuboid because we know - // the top - // bottom are -1,1 due to how fit works. - idealWidth = (QT3DSF32)ITextRenderer::NextMultipleOf4( - (QT3DSU32)(inViewport.m_Height * designAspect + .5f)); - // halfRange should always be greater than 1.0f. - QT3DSF32 halfRange = inViewport.m_Width / idealWidth; - normalizedCuboid.m_Left = -halfRange; - normalizedCuboid.m_Right = halfRange; - translation.x = translation.x / (idealWidth / 2.0f); - } else { - idealHeight = (QT3DSF32)ITextRenderer::NextMultipleOf4( - (QT3DSU32)(inViewport.m_Width / designAspect + .5f)); - QT3DSF32 halfRange = inViewport.m_Height / idealHeight; - normalizedCuboid.m_Bottom = -halfRange; - normalizedCuboid.m_Top = halfRange; - translation.y = translation.y / (idealHeight / 2.0f); - } - normalizedCuboid.Translate(translation); - } - // Given no adjustment in the virtual rect, then this is what we would have. - - return normalizedCuboid; -} - -void SCamera::SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, - QT3DSMat44 &outVP) -{ - STextureDetails theDetails(inTexture.GetTextureDetails()); - SCamera theTempCamera; - SetupOrthographicCameraForOffscreenRender(inTexture, outVP, theTempCamera); -} - -void SCamera::SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, - QT3DSMat44 &outVP, SCamera &outCamera) -{ - STextureDetails theDetails(inTexture.GetTextureDetails()); - SCamera theTempCamera; - theTempCamera.m_Flags.SetOrthographic(true); - theTempCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - QT3DSVec2 theDimensions((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); - theTempCamera.CalculateGlobalVariables( - NVRenderRect(0, 0, theDetails.m_Width, theDetails.m_Height), theDimensions); - theTempCamera.CalculateViewProjectionMatrix(outVP); - outCamera = theTempCamera; -} - -SRay SCamera::Unproject(const QT3DSVec2 &inViewportRelativeCoords, const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const -{ - SRay theRay; - QT3DSMat44 tempVal(QT3DSMat44::createIdentity()); - SPinCameraResult result = - PinCamera(inViewport, inDesignDimensions, tempVal, m_ScaleMode, m_ScaleAnchor); - QT3DSVec2 globalCoords = inViewport.ToAbsoluteCoords(inViewportRelativeCoords); - QT3DSVec2 normalizedCoords = - result.m_VirtualViewport.AbsoluteToNormalizedCoordinates(globalCoords); - QT3DSVec3 &outOrigin(theRay.m_Origin); - QT3DSVec3 &outDir(theRay.m_Direction); - QT3DSVec2 inverseFrustumScale(1.0f / m_FrustumScale.x, 1.0f / m_FrustumScale.y); - QT3DSVec2 scaledCoords(inverseFrustumScale.x * normalizedCoords.x, - inverseFrustumScale.y * normalizedCoords.y); - - if (m_Flags.IsOrthographic()) { - outOrigin.x = scaledCoords.x; - outOrigin.y = scaledCoords.y; - outOrigin.z = 0.0f; - - outDir.x = 0.0f; - outDir.y = 0.0f; - outDir.z = -1.0f; - } else { - outOrigin.x = 0.0f; - outOrigin.y = 0.0f; - outOrigin.z = 0.0f; - - outDir.x = scaledCoords.x; - outDir.y = scaledCoords.y; - outDir.z = -1.0f; - } - - outOrigin = m_GlobalTransform.transform(outOrigin); - QT3DSMat33 theNormalMatrix; - CalculateNormalMatrix(theNormalMatrix); - - outDir = theNormalMatrix.transform(outDir); - outDir.normalize(); - /* - char printBuf[2000]; - sprintf_s( printBuf, "normCoords %f %f outDir %f %f %f\n" - , normalizedCoords.x, normalizedCoords.y, outDir.x, outDir.y, outDir.z ); - OutputDebugStringA( printBuf ); - */ - - return theRay; -} - -QT3DSVec3 SCamera::UnprojectToPosition(const QT3DSVec3 &inGlobalPos, const SRay &inRay) const -{ - QT3DSVec3 theCameraDir = GetDirection(); - QT3DSVec3 theObjGlobalPos = inGlobalPos; - QT3DSF32 theDistance = -1.0f * theObjGlobalPos.dot(theCameraDir); - NVPlane theCameraPlane(theCameraDir, theDistance); - return inRay.Intersect(theCameraPlane); -} - -QT3DSF32 SCamera::verticalFov(QT3DSF32 aspectRatio) const -{ - if (m_FOVHorizontal) - return 2.0f * qAtan(qTan(qreal(m_FOV) / 2.0) / qreal(aspectRatio)); - else - return m_FOV; -} - -QT3DSF32 SCamera::verticalFov(const NVRenderRectF &inViewport) const -{ - return verticalFov(GetAspectRatio(inViewport)); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.h deleted file mode 100644 index d6d8ce82..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CAMERA_H -#define QT3DS_RENDER_CAMERA_H -#include "Qt3DSRenderNode.h" -#include "Qt3DSRenderRay.h" - -namespace qt3ds { -namespace render { - - struct SCameraGlobalCalculationResult - { - bool m_WasDirty; - bool m_ComputeFrustumSucceeded; - SCameraGlobalCalculationResult(bool inWasDirty, bool inComputeSucceeded = true) - : m_WasDirty(inWasDirty) - , m_ComputeFrustumSucceeded(inComputeSucceeded) - { - } - }; - - struct CameraScaleModes - { - enum Enum { - Fit = 0, - SameSize, - FitHorizontal, - FitVertical, - }; - }; - - struct CameraScaleAnchors - { - enum Enum { - Center = 0, - North, - NorthEast, - East, - SouthEast, - South, - SouthWest, - West, - NorthWest, - }; - }; - - struct SCuboidRect - { - QT3DSF32 m_Left; - QT3DSF32 m_Top; - QT3DSF32 m_Right; - QT3DSF32 m_Bottom; - SCuboidRect(QT3DSF32 l = 0.0f, QT3DSF32 t = 0.0f, QT3DSF32 r = 0.0f, QT3DSF32 b = 0.0f) - : m_Left(l) - , m_Top(t) - , m_Right(r) - , m_Bottom(b) - { - } - void Translate(QT3DSVec2 inTranslation) - { - m_Left += inTranslation.x; - m_Right += inTranslation.x; - m_Top += inTranslation.y; - m_Bottom += inTranslation.y; - } - }; - - struct SCamera : public SNode - { - - // Setting these variables should set dirty on the camera. - QT3DSF32 m_ClipNear; - QT3DSF32 m_ClipFar; - - QT3DSF32 m_FOV; // Radians - bool m_FOVHorizontal; - - QT3DSMat44 m_Projection; - CameraScaleModes::Enum m_ScaleMode; - CameraScaleAnchors::Enum m_ScaleAnchor; - // Record some values from creating the projection matrix - // to use during mouse picking. - QT3DSVec2 m_FrustumScale; - - SCamera(); - - QT3DSMat33 GetLookAtMatrix(const QT3DSVec3 &inUpDir, const QT3DSVec3 &inDirection) const; - // Set our position, rotation member variables based on the lookat target - // Marks this object as dirty. - // Need to test this when the camera's local transform is null. - // Assumes parent's local transform is the identity, meaning our local transform is - // our global transform. - void LookAt(const QT3DSVec3 &inCameraPos, const QT3DSVec3 &inUpDir, const QT3DSVec3 &inTargetPos); - - SCameraGlobalCalculationResult CalculateGlobalVariables(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions); - bool CalculateProjection(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions); - bool ComputeFrustumOrtho(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions); - // Used when rendering the widgets in studio. This scales the widget when in orthographic - // mode in order to have - // constant size on screen regardless. - // Number is always greater than one - QT3DSF32 GetOrthographicScaleFactor(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const; - bool ComputeFrustumPerspective(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions); - // Text may be scaled so that it doesn't appear pixellated when the camera itself is doing - // the scaling. - QT3DSF32 GetTextScaleFactor(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const; - - void CalculateViewProjectionMatrix(QT3DSMat44 &outMatrix) const; - - // If this is an orthographic camera, the cuboid properties are the distance from the center - // point - // to the left, top, right, and bottom edges of the view frustum in world units. - // If this is a perspective camera, the cuboid properties are the FOV angles - // (left,top,right,bottom) - // of the view frustum. - - // Return a normalized rect that describes the area the camera is rendering to. - // This takes into account the various camera properties (scale mode, scale anchor). - SCuboidRect GetCameraBounds(const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const; - - // Setup a camera VP projection for rendering offscreen. - static void SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, - QT3DSMat44 &outVP); - static void SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, - QT3DSMat44 &outVP, SCamera &outCamera); - - // Unproject a point (x,y) in viewport relative coordinates meaning - // left, bottom is 0,0 and values are increasing right,up respectively. - SRay Unproject(const QT3DSVec2 &inLayerRelativeMouseCoords, const NVRenderRectF &inViewport, - const QT3DSVec2 &inDesignDimensions) const; - - // Unproject a given coordinate to a 3d position that lies on the same camera - // plane as inGlobalPos. - // Expects CalculateGlobalVariables has been called or doesn't need to be. - QT3DSVec3 UnprojectToPosition(const QT3DSVec3 &inGlobalPos, const SRay &inRay) const; - - QT3DSF32 verticalFov(QT3DSF32 aspectRatio) const; - QT3DSF32 verticalFov(const NVRenderRectF &inViewport) const; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCustomMaterial.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCustomMaterial.h deleted file mode 100644 index 593c7573..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCustomMaterial.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_H -#define QT3DS_RENDER_CUSTOM_MATERIAL_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderDynamicObject.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSRenderLightmaps.h" -#include "foundation/Qt3DSFlags.h" - -namespace qt3ds { -namespace render { - - // IMPORTANT: These flags matches the key produced by a MDL export file - struct SCustomMaterialShaderKeyValues - { - enum Enum { - diffuse = 1 << 0, - specular = 1 << 1, - glossy = 1 << 2, - cutout = 1 << 3, - refraction = 1 << 4, - transparent = 1 << 5, - displace = 1 << 6, - volumetric = 1 << 7, - transmissive = 1 << 8, - }; - }; - - typedef NVFlags SCustomMaterialShaderKeyFlags; - - struct SCustomMaterial : public SDynamicObject - { - private: - // These objects are only created via the dynamic object system. - SCustomMaterial(const SCustomMaterial &); - SCustomMaterial &operator=(const SCustomMaterial &); - SCustomMaterial(); - - public: - // lightmap section - SLightmaps m_Lightmaps; - // material section - bool m_hasTransparency; - bool m_hasRefraction; - bool m_hasVolumetricDF; - SImage *m_IblProbe; - SImage *m_EmissiveMap2; - SImage *m_DisplacementMap; - QT3DSF32 m_DisplaceAmount; ///< depends on the object size - - SGraphObject *m_NextSibling; - - SCustomMaterialShaderKeyFlags m_ShaderKeyValues; ///< input from MDL files - QT3DSU32 m_LayerCount; ///< input from MDL files - - void Initialize(QT3DSU32 inKey, QT3DSU32 inLayerCount) - { - m_Lightmaps.m_LightmapIndirect = NULL; - m_Lightmaps.m_LightmapRadiosity = NULL; - m_Lightmaps.m_LightmapShadow = NULL; - m_hasTransparency = false; - m_hasRefraction = false; - m_hasVolumetricDF = false; - m_NextSibling = NULL; - m_DirtyFlagWithInFrame = m_Flags.IsDirty(); - m_IblProbe = NULL; - m_EmissiveMap2 = NULL; - m_DisplacementMap = NULL; - m_DisplaceAmount = 0.0; - m_ShaderKeyValues = (SCustomMaterialShaderKeyFlags)inKey; - m_LayerCount = inLayerCount; - } - - bool IsDielectric() const - { - return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::diffuse; - } - bool IsSpecularEnabled() const - { - return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::specular; - } - bool IsCutOutEnabled() const - { - return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::cutout; - } - bool IsVolumetric() const - { - return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::volumetric; - } - bool IsTransmissive() const - { - return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::transmissive; - } - bool HasLighting() const { return true; } - - template - void Remap(TRemapperType &inRemapper) - { - SDynamicObject::Remap(inRemapper); - m_Lightmaps.Remap(inRemapper); - inRemapper.Remap(m_IblProbe); - inRemapper.RemapMaterial(m_NextSibling); - inRemapper.Remap(m_EmissiveMap2); - inRemapper.Remap(m_DisplacementMap); - } - - // Dirty - bool m_DirtyFlagWithInFrame; - bool IsDirty() const { return m_Flags.IsDirty() || m_DirtyFlagWithInFrame; } - void UpdateDirtyForFrame() - { - m_DirtyFlagWithInFrame = m_Flags.IsDirty(); - m_Flags.SetDirty(false); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.cpp deleted file mode 100644 index 06f3649a..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderDefaultMaterial.h" - -using namespace qt3ds::render; - -SDefaultMaterial::SDefaultMaterial() - : SGraphObject(GraphObjectTypes::DefaultMaterial) - , m_IblProbe(NULL) - , m_Lighting(DefaultMaterialLighting::VertexLighting) - , m_BlendMode(DefaultMaterialBlendMode::Normal) - , m_DiffuseColor(1, 1, 1) - , m_EmissivePower(0) - , m_EmissiveMap(NULL) - , m_EmissiveMap2(NULL) - , m_EmissiveColor(1, 1, 1) - , m_SpecularReflection(NULL) - , m_SpecularMap(NULL) - , m_SpecularModel(DefaultMaterialSpecularModel::Default) - , m_SpecularTint(1, 1, 1) - , m_IOR(.2f) - , m_FresnelPower(0.0f) - , m_SpecularAmount(0) - , m_SpecularRoughness(50) - , m_RoughnessMap(NULL) - , m_Opacity(1) - , m_OpacityMap(NULL) - , m_BumpMap(NULL) - , m_BumpAmount(0.f) - , m_NormalMap(NULL) - , m_DisplacementMap(NULL) - , m_DisplaceAmount(0.f) - , m_TranslucencyMap(NULL) - , m_TranslucentFalloff(0.f) - , m_DiffuseLightWrap(0.f) - , m_VertexColors(false) - , m_NextSibling(NULL) - , m_Parent(NULL) -{ - m_Lightmaps.m_LightmapIndirect = NULL; - m_Lightmaps.m_LightmapRadiosity = NULL; - m_Lightmaps.m_LightmapShadow = NULL; - - m_DiffuseMaps[0] = NULL; - m_DiffuseMaps[2] = NULL; - m_DiffuseMaps[1] = NULL; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.h deleted file mode 100644 index 09595236..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DEFAULT_MATERIAL_H -#define QT3DS_RENDER_DEFAULT_MATERIAL_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSVec3.h" -#include "Qt3DSRenderMaterialDirty.h" -#include "Qt3DSRenderLightmaps.h" - -namespace qt3ds { -namespace render { - struct DefaultMaterialLighting - { - enum Enum { - NoLighting = 0, - VertexLighting, - FragmentLighting - }; - }; - struct DefaultMaterialBlendMode - { - enum Enum { - Normal = 0, - Screen, - Multiply, - Overlay, - ColorBurn, - ColorDodge - }; - }; - - struct DefaultMaterialSpecularModel - { - enum Enum { - Default = 0, - KGGX, - KWard - }; - }; - - struct SImage; - - struct QT3DS_AUTOTEST_EXPORT SDefaultMaterial : SGraphObject - { - CMaterialDirty m_Dirty; - // lightmap section - SLightmaps m_Lightmaps; - // material section - SImage *m_IblProbe; - DefaultMaterialLighting::Enum m_Lighting; // defaults to vertex - DefaultMaterialBlendMode::Enum m_BlendMode; // defaults to normal - QT3DSVec3 m_DiffuseColor; // colors are 0-1 normalized - SImage *m_DiffuseMaps[3]; - QT3DSF32 m_EmissivePower; // 0-100, defaults to 0 - QT3DSVec3 m_EmissiveColor; - SImage *m_EmissiveMap; - SImage *m_EmissiveMap2; - SImage *m_SpecularReflection; - SImage *m_SpecularMap; - DefaultMaterialSpecularModel::Enum m_SpecularModel; - QT3DSVec3 m_SpecularTint; - QT3DSF32 m_IOR; - QT3DSF32 m_FresnelPower; - QT3DSF32 m_SpecularAmount; // 0-??, defaults to 0 - QT3DSF32 m_SpecularRoughness; // 0-??, defaults to 50 - SImage *m_RoughnessMap; - QT3DSF32 m_Opacity; // 0-1 - SImage *m_OpacityMap; - SImage *m_BumpMap; - QT3DSF32 m_BumpAmount; // 0-?? - SImage *m_NormalMap; - SImage *m_DisplacementMap; - QT3DSF32 m_DisplaceAmount; // 0-?? - SImage *m_TranslucencyMap; - QT3DSF32 m_TranslucentFalloff; // 0 - ?? - QT3DSF32 m_DiffuseLightWrap; // 0 - 1 - bool m_VertexColors; - // Materials are stored as a linked list on models. - SGraphObject *m_NextSibling; - SModel *m_Parent; - - SDefaultMaterial(); - - bool IsSpecularEnabled() const { return m_SpecularAmount > .01f; } - bool IsFresnelEnabled() const { return m_FresnelPower > 0.0f; } - bool IsVertexColorsEnabled() const { return m_VertexColors; } - bool HasLighting() const { return m_Lighting != DefaultMaterialLighting::NoLighting; } - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - m_Lightmaps.Remap(inRemapper); - inRemapper.Remap(m_IblProbe); - inRemapper.Remap(m_DiffuseMaps[0]); - inRemapper.Remap(m_DiffuseMaps[1]); - inRemapper.Remap(m_DiffuseMaps[2]); - inRemapper.Remap(m_EmissiveMap); - inRemapper.Remap(m_EmissiveMap2); - inRemapper.Remap(m_SpecularReflection); - inRemapper.Remap(m_SpecularMap); - inRemapper.Remap(m_RoughnessMap); - inRemapper.Remap(m_OpacityMap); - inRemapper.Remap(m_BumpMap); - inRemapper.Remap(m_NormalMap); - inRemapper.Remap(m_DisplacementMap); - inRemapper.Remap(m_TranslucencyMap); - inRemapper.RemapMaterial(m_NextSibling); - inRemapper.Remap(m_Parent); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.cpp deleted file mode 100644 index 3d7c6ff5..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRender.h" -#include "Qt3DSRenderDynamicObject.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "foundation/FileTools.h" -#include "Qt3DSRenderString.h" - -#include - -using namespace qt3ds; -using namespace qt3ds::render; - -SDynamicObject::SDynamicObject(GraphObjectTypes::Enum inType, CRegisteredString inObjName, - QT3DSU32 inDSByteSize, QT3DSU32 thisObjSize) - : SGraphObject(inType) - , m_ClassName(inObjName) - , m_DataSectionByteSize(inDSByteSize) - , m_ThisObjectSize(thisObjSize) -{ -} - -template -void SDynamicObject::SetPropertyValueT(const dynamic::SPropertyDefinition &inDefinition, - const TDataType &inValue) -{ - if (sizeof(inValue) != inDefinition.m_ByteSize) { - QT3DS_ASSERT(false); - return; - } - memCopy(GetDataSectionBegin() + inDefinition.m_Offset, &inValue, sizeof(inValue)); -} - -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - bool inValue) -{ - SetPropertyValueT(inDefinition, inValue); -} - -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - QT3DSF32 inValue) -{ - SetPropertyValueT(inDefinition, inValue); -} -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - QT3DSF32 inValue, QT3DSU32 inOffset) -{ - if (sizeof(QT3DSF32) > (inDefinition.m_ByteSize - inOffset)) { - QT3DS_ASSERT(false); - return; - } - memCopy(GetDataSectionBegin() + inDefinition.m_Offset + inOffset, &inValue, sizeof(inValue)); -} -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const QT3DSVec2 &inValue) -{ - SetPropertyValueT(inDefinition, inValue); -} -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const QT3DSVec3 &inValue) -{ - SetPropertyValueT(inDefinition, inValue); -} -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const QT3DSVec4 &inValue) -{ - SetPropertyValueT(inDefinition, inValue); -} -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - QT3DSI32 inValue) -{ - SetPropertyValueT(inDefinition, inValue); -} -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - CRegisteredString inValue) -{ - QT3DS_ASSERT(inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr); - SetPropertyValueT(inDefinition, inValue); -} -template -void SDynamicObject::SetStrPropertyValueT(dynamic::SPropertyDefinition &inDefinition, - const char8_t *inValue, const char8_t *inProjectDir, - TStrType &ioWorkspace, IStringTable &inStrTable) -{ - if (inValue == NULL) - inValue = ""; - if (inDefinition.m_DataType == NVRenderShaderDataTypes::QT3DSI32) { - NVConstDataRef theEnumValues = inDefinition.m_EnumValueNames; - for (QT3DSI32 idx = 0, end = (QT3DSI32)theEnumValues.size(); idx < end; ++idx) { - if (strcmp(theEnumValues[idx].c_str(), inValue) == 0) { - SetPropertyValueT(inDefinition, idx); - break; - } - } - } else if (inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - if (inProjectDir == NULL) - inProjectDir = ""; - if (CFileTools::RequiresCombineBaseAndRelative(inValue)) { - QString absolute = QDir(inProjectDir).filePath(inValue); - ioWorkspace.assign(absolute.toLatin1().constData()); - SetPropertyValueT(inDefinition, inStrTable.RegisterStr(ioWorkspace.c_str())); - // We also adjust the image path in the definition - // I could not find a better place - inDefinition.m_ImagePath = inStrTable.RegisterStr(ioWorkspace.c_str()); - } else { - SetPropertyValueT(inDefinition, inStrTable.RegisterStr(inValue)); - } - } else if (inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderImage2DPtr) { - SetPropertyValueT(inDefinition, inStrTable.RegisterStr(inValue)); - } else if (inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderDataBufferPtr) { - SetPropertyValueT(inDefinition, inStrTable.RegisterStr(inValue)); - } else { - QT3DS_ASSERT(false); - } -} - -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const char8_t *inValue, const char8_t *inProjectDir, - CRenderString &ioWorkspace, IStringTable &inStrTable) -{ - SetStrPropertyValueT(const_cast(inDefinition), inValue, - inProjectDir, ioWorkspace, inStrTable); -} - -void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const char8_t *inValue, const char8_t *inProjectDir, - eastl::string &ioWorkspace, IStringTable &inStrTable) -{ - SetStrPropertyValueT(const_cast(inDefinition), inValue, - inProjectDir, ioWorkspace, inStrTable); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.h deleted file mode 100644 index a275e572..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DYNAMIC_OBJECT_H -#define QT3DS_RENDER_DYNAMIC_OBJECT_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "Qt3DSRenderNode.h" -#include "EASTL/string.h" - -namespace qt3ds { -namespace render { - - namespace dynamic { - struct SPropertyDefinition; - } - - // Dynamic objects are objects that have variable number of properties during runtime. - struct SDynamicObject : public SGraphObject - { - CRegisteredString m_ClassName; - NodeFlags m_Flags; - QT3DSU32 m_DataSectionByteSize; - QT3DSU32 m_ThisObjectSize; - - SDynamicObject(GraphObjectTypes::Enum inType, CRegisteredString inClassName, - QT3DSU32 inDSByteSize, QT3DSU32 thisObjSize); - - QT3DSU8 *GetDataSectionBegin() - { - QT3DSU8 *thisObjectStart = reinterpret_cast(this); - QT3DSU8 *retval = thisObjectStart + m_ThisObjectSize; - QT3DS_ASSERT((reinterpret_cast(retval) % 4 == 0)); - return retval; - } - - const QT3DSU8 *GetDataSectionBegin() const - { - return const_cast(this)->GetDataSectionBegin(); - } - - QT3DSU8 *GetDataSectionEnd() { return GetDataSectionBegin() + m_DataSectionByteSize; } - - template - void SetPropertyValueT(const dynamic::SPropertyDefinition &inDefinition, - const TDataType &inType); - template - void SetStrPropertyValueT(dynamic::SPropertyDefinition &inDefinition, - const char8_t *inValue, const char8_t *inProjectDir, - TStrType &ioWorkspace, IStringTable &inStrTable); - - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, bool inValue); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, QT3DSF32 inValue); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, QT3DSF32 inValue, - QT3DSU32 inOffset); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const QT3DSVec2 &inValue); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const QT3DSVec3 &inValue); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const QT3DSVec4 &inValue); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, QT3DSI32 inValue); - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - CRegisteredString inValue); - - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const char8_t *inValue, const char8_t *inProjectDir, - CRenderString &ioWorkspace, IStringTable &inStrTable); - - void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, - const char8_t *inValue, const char8_t *inProjectDir, - eastl::string &ioWorkspace, IStringTable &inStrTable); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_ClassName); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.cpp deleted file mode 100644 index 97cddd9d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderEffect.h" -#include "Qt3DSRenderEffectSystem.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec3.h" -#include "Qt3DSRenderString.h" -#include "foundation/FileTools.h" - -using namespace qt3ds::render; - -void SEffect::Initialize() -{ - m_Layer = NULL; - m_NextEffect = NULL; - m_Context = NULL; -} - -void SEffect::SetActive(bool inActive, IEffectSystem &inManager) -{ - if (m_Flags.IsActive() != inActive) { - m_Flags.SetActive(inActive); - if (m_Context) - inManager.ResetEffectFrameData(*m_Context); - m_Flags.SetDirty(true); - } -} - -void SEffect::Reset(IEffectSystem &inSystem) -{ - if (m_Context) - inSystem.ResetEffectFrameData(*m_Context); - m_Flags.SetDirty(true); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.h deleted file mode 100644 index c11c214c..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderEffect.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_EFFECT_H -#define QT3DS_RENDER_EFFECT_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "Qt3DSRenderNode.h" -#include "EASTL/string.h" -#include "Qt3DSRenderDynamicObject.h" - -namespace qt3ds { -namespace render { - struct SLayer; - struct SEffectContext; - - // Effects are post-render effect applied to the layer. There can be more than one of - // them and they have completely variable properties. - // see IEffectManager in order to create these effects. - // The data for the effect immediately follows the effect - struct SEffect : public SDynamicObject - { - private: - // These objects are only created via the dynamic object system. - SEffect(const SEffect &); - SEffect &operator=(const SEffect &); - SEffect(); - - public: - SLayer *m_Layer; - SEffect *m_NextEffect; - // Opaque pointer to context type implemented by the effect system. - // May be null in which case the effect system will generate a new context - // the first time it needs to render this effect. - SEffectContext *m_Context; - - void Initialize(); - - // If our active flag value changes, then we ask the effect manager - // to reset our context. - void SetActive(bool inActive, IEffectSystem &inSystem); - - void Reset(IEffectSystem &inSystem); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SDynamicObject::Remap(inRemapper); - inRemapper.Remap(m_Layer); - inRemapper.Remap(m_NextEffect); - inRemapper.NullPtr(m_Context); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderGraphObject.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderGraphObject.h deleted file mode 100644 index 58c48ed1..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderGraphObject.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_GRAPH_OBJECT_H -#define QT3DS_RENDER_GRAPH_OBJECT_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderTaggedPointer.h" -#include "Qt3DSRenderGraphObjectTypes.h" - -namespace qt3ds { -namespace render { - - // Types should be setup on construction. Change the type - // at your own risk as the type is used for RTTI purposes. - struct QT3DS_AUTOTEST_EXPORT SGraphObject - { - // Id's help debugging the object and are optionally set - CRegisteredString m_Id; - // Type is used for RTTI purposes down the road. - GraphObjectTypes::Enum m_Type; - STaggedPointer m_UserData; - - SGraphObject(GraphObjectTypes::Enum inType) - : m_Type(inType) - { - } - SGraphObject(const SGraphObject &inCloningObject, NVAllocatorCallback & /*inAllocator*/) - : m_Id(inCloningObject.m_Id) - , m_Type(inCloningObject.m_Type) - { - } - - // If you change any detail of the scene graph, or even *breath* on a - // scene graph object, you need to bump this binary version so at least - // we know if we can load a file or not. - static QT3DSU32 GetSceneGraphBinaryVersion() { return 1; } - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - inRemapper.Remap(m_Id); - inRemapper.NullPtr(m_UserData.m_UserData); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.cpp deleted file mode 100644 index eaa98c77..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderImage.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSOffscreenRenderKey.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderPluginGraphObject.h" - -using namespace qt3ds::render; - -SImage::SImage() - : SGraphObject(GraphObjectTypes::Image) - , m_RenderPlugin(NULL) - , m_LastFrameOffscreenRenderer(NULL) - , m_Parent(NULL) - , m_Scale(1, 1) - , m_Pivot(0, 0) - , m_Rotation(0) - , m_Position(0, 0) - , m_MappingMode(ImageMappingModes::Normal) - , m_HorizontalTilingMode(NVRenderTextureCoordOp::ClampToEdge) - , m_VerticalTilingMode(NVRenderTextureCoordOp::ClampToEdge) -{ - m_Flags.SetActive(true); - m_Flags.SetDirty(true); - m_Flags.SetTransformDirty(true); -} - -static void HandleOffscreenResult(SImage &theImage, SImageTextureData &newImage, - SOffscreenRenderResult &theResult, bool &replaceTexture, - bool &wasDirty) -{ - newImage.m_Texture = theResult.m_Texture; - newImage.m_TextureFlags.SetHasTransparency(theResult.m_HasTransparency); - newImage.m_TextureFlags.SetPreMultiplied(true); - wasDirty = wasDirty || theResult.m_HasChangedSinceLastFrame; - theImage.m_LastFrameOffscreenRenderer = theResult.m_Renderer; - replaceTexture = true; -} - -bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager &inRenderManager, - IRenderPluginManager &inPluginManager, bool forIbl) -{ - - bool wasDirty = m_Flags.IsDirty(); - m_Flags.SetDirty(false); - SImageTextureData newImage; - bool replaceTexture(false); - if (m_RenderPlugin && m_RenderPlugin->m_Flags.IsActive()) { - IRenderPluginInstance *theInstance = inPluginManager.GetOrCreateRenderPluginInstance( - m_RenderPlugin->m_PluginPath, m_RenderPlugin); - if (theInstance) { - inRenderManager.MaybeRegisterOffscreenRenderer(theInstance, *theInstance); - SOffscreenRenderResult theResult = inRenderManager.GetRenderedItem(theInstance); - HandleOffscreenResult(*this, newImage, theResult, replaceTexture, wasDirty); - } - } - - if (newImage.m_Texture == NULL) { - if (m_OffscreenRendererId.IsValid()) { - SOffscreenRenderResult theResult = - inRenderManager.GetRenderedItem(m_OffscreenRendererId); - HandleOffscreenResult(*this, newImage, theResult, replaceTexture, wasDirty); - } - } - - if (newImage.m_Texture == NULL) { - m_LastFrameOffscreenRenderer = NULL; - newImage = inBufferManager.LoadRenderImage(m_ImagePath, false, forIbl); - replaceTexture = newImage.m_Texture != m_TextureData.m_Texture; - } - - if (replaceTexture) { - wasDirty = true; - m_TextureData = newImage; - } - - if (m_Flags.IsTransformDirty()) { - wasDirty = true; - CalculateTextureTransform(); - } - return wasDirty; -} - -void SImage::CalculateTextureTransform() -{ - m_Flags.SetTransformDirty(false); - - m_TextureTransform = QT3DSMat44::createIdentity(); - - QT3DSMat44 translation(QT3DSMat44::createIdentity()); - QT3DSMat44 rotation(QT3DSMat44::createIdentity()); - QT3DSMat44 scale(QT3DSMat44::createIdentity()); - - translation.column3[0] = m_Position.x; - translation.column3[1] = m_Position.y; - scale.column0[0] = m_Scale.x; - scale.column1[1] = m_Scale.y; - rotation.rotate(m_Rotation, QT3DSVec3(0, 0, 1)); - - // Setup the pivot. - m_TextureTransform.column3[0] = m_Pivot.x; - m_TextureTransform.column3[1] = m_Pivot.y; - m_TextureTransform = m_TextureTransform * rotation; - m_TextureTransform = m_TextureTransform * scale; - m_TextureTransform = m_TextureTransform * translation; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.h deleted file mode 100644 index 47993e73..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderImage.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_IMAGE_H -#define QT3DS_RENDER_IMAGE_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "Qt3DSRenderNode.h" -#include "foundation/Qt3DSVec2.h" -#include "Qt3DSRenderImageTextureData.h" -#include "EASTL/utility.h" - -namespace qt3ds { -namespace render { - class IQt3DSRenderContext; - class IOffscreenRenderManager; - class IOffscreenRenderer; - struct ImageMappingModes - { - enum Enum { - Normal = 0, // UV mapping - Environment = 1, - LightProbe = 2, - }; - }; - - struct QT3DS_AUTOTEST_EXPORT SImage : public SGraphObject - { - // Complete path to the file; - //*not* relative to the presentation directory - CRegisteredString m_ImagePath; - CRegisteredString m_ImageShaderName; ///< for custom materials we don't generate the name - - // Presentation id. - CRegisteredString m_OffscreenRendererId; // overrides source path if available - SRenderPlugin *m_RenderPlugin; // Overrides everything if available. - IOffscreenRenderer *m_LastFrameOffscreenRenderer; - SGraphObject *m_Parent; - - SImageTextureData m_TextureData; - - NodeFlags m_Flags; // only dirty, transform dirty, and active apply - - QT3DSVec2 m_Scale; - QT3DSVec2 m_Pivot; - QT3DSF32 m_Rotation; // Radians. - QT3DSVec2 m_Position; - ImageMappingModes::Enum m_MappingMode; - NVRenderTextureCoordOp::Enum m_HorizontalTilingMode; - NVRenderTextureCoordOp::Enum m_VerticalTilingMode; - - // Setting any of the above variables means this object is dirty. - // Setting any of the vec2 properties means this object's transform is dirty - - QT3DSMat44 m_TextureTransform; - - SImage(); - // Renders the sub presentation - // Or finds the image. - // and sets up the texture transform - bool ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager &inRenderManager, - IRenderPluginManager &pluginManager, bool forIbl = false); - - void CalculateTextureTransform(); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_ImagePath); - inRemapper.Remap(m_OffscreenRendererId); - // Null out objects that should be null when loading from file. - inRemapper.NullPtr(m_LastFrameOffscreenRenderer); - inRemapper.NullPtr(m_TextureData.m_Texture); - inRemapper.Remap(m_RenderPlugin); - inRemapper.Remap(m_Parent); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.cpp deleted file mode 100644 index ee146624..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderEffect.h" - -using namespace qt3ds::render; - -SLayer::SLayer() - : SNode(GraphObjectTypes::Layer) - , m_Scene(NULL) - , m_FirstEffect(NULL) - , m_RenderPlugin(NULL) - , m_ProgressiveAAMode(AAModeValues::NoAA) - , m_MultisampleAAMode(AAModeValues::NoAA) - , m_Background(LayerBackground::Transparent) - , m_ClearColor(0) - , m_BlendType(LayerBlendTypes::Normal) - , m_HorizontalFieldValues(HorizontalFieldValues::LeftWidth) - , m_Left(0) - , m_LeftUnits(LayerUnitTypes::Percent) - , m_Width(100.0f) - , m_WidthUnits(LayerUnitTypes::Percent) - , m_Right(0) - , m_RightUnits(LayerUnitTypes::Percent) - , m_VerticalFieldValues(VerticalFieldValues::TopHeight) - , m_Top(0) - , m_TopUnits(LayerUnitTypes::Percent) - , m_Height(100.0f) - , m_HeightUnits(LayerUnitTypes::Percent) - , m_Bottom(0) - , m_BottomUnits(LayerUnitTypes::Percent) - , m_AoStrength(0) - , m_AoDistance(5.0f) - , m_AoSoftness(50.0f) - , m_AoBias(0) - , m_AoSamplerate(2) - , m_AoDither(false) - , m_ShadowStrength(0) - , m_ShadowDist(10) - , m_ShadowSoftness(100.0f) - , m_ShadowBias(0) - , m_LightProbe(NULL) - , m_ProbeBright(100.0f) - , m_FastIbl(false) - , m_ProbeHorizon(-1.0f) - , m_ProbeFov(180.0f) - , m_LightProbe2(NULL) - , m_Probe2Fade(1.0f) - , m_Probe2Window(1.0f) - , m_Probe2Pos(0.5f) - , m_TemporalAAEnabled(false) -{ - m_Flags.SetLayerRenderToTarget(true); - m_Flags.SetLayerEnableDepthTest(true); - m_Flags.SetLayerEnableDepthPrepass(true); -} - -void SLayer::AddEffect(SEffect &inEffect) -{ - // Effects need to be rendered in reverse order as described in the file. - inEffect.m_NextEffect = m_FirstEffect; - m_FirstEffect = &inEffect; - inEffect.m_Layer = this; -} - -SEffect *SLayer::GetLastEffect() -{ - if (m_FirstEffect) { - SEffect *theEffect = m_FirstEffect; - // Empty loop intentional - for (; theEffect->m_NextEffect; theEffect = theEffect->m_NextEffect) { - } - QT3DS_ASSERT(theEffect->m_NextEffect == NULL); - return theEffect; - } - return NULL; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.h deleted file mode 100644 index 3759fe12..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLayer.h +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_LAYER_H -#define QT3DS_RENDER_LAYER_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderNode.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderer.h" - -namespace qt3ds { -namespace render { - class IQt3DSRenderContext; - struct SPresentation; - struct SScene; - struct SEffect; - - struct AAModeValues - { - enum Enum { - NoAA = 0, - SSAA = 1, - X2 = 2, - X4 = 4, - X8 = 8 - }; - }; - - struct HorizontalFieldValues - { - enum Enum { - LeftWidth = 0, - LeftRight, - WidthRight - }; - }; - - struct VerticalFieldValues - { - enum Enum { - TopHeight = 0, - TopBottom, - HeightBottom - }; - }; - - struct LayerUnitTypes - { - enum Enum { - Percent = 0, - Pixels - }; - }; - - struct LayerBackground - { - enum Enum { - Transparent = 0, - Unspecified, - Color - }; - }; - - struct LayerBlendTypes - { - enum Enum { - Normal = 0, - Screen, - Multiply, - Add, - Subtract, - Overlay, - ColorBurn, - ColorDodge - }; - }; - - // A layer is a special node. It *always* presents its global transform - // to children as the identity. It also can optionally have a width or height - // different than the overlying context. You can think of layers as the transformation - // between a 3d scene graph and a 2D texture. - struct QT3DS_AUTOTEST_EXPORT SLayer : public SNode - { - SScene *m_Scene; - - // First effect in a list of effects. - SEffect *m_FirstEffect; - - // If a layer has a valid texture path (one that resolves to either a - // an on-disk image or a offscreen renderer), then it does not render its - // own source path. Instead, it renders the offscreen renderer. Used in this manner, - // offscreen renderer's also have the option (if they support it) to render directly to the - // render target given a specific viewport (that is also scissored if necessary). - qt3ds::foundation::CRegisteredString m_TexturePath; - - SRenderPlugin *m_RenderPlugin; // Overrides texture path if available. - - AAModeValues::Enum m_ProgressiveAAMode; - AAModeValues::Enum m_MultisampleAAMode; - LayerBackground::Enum m_Background; - QT3DSVec3 m_ClearColor; - - LayerBlendTypes::Enum m_BlendType; - - HorizontalFieldValues::Enum m_HorizontalFieldValues; - QT3DSF32 m_Left; - LayerUnitTypes::Enum m_LeftUnits; - QT3DSF32 m_Width; - LayerUnitTypes::Enum m_WidthUnits; - QT3DSF32 m_Right; - LayerUnitTypes::Enum m_RightUnits; - - VerticalFieldValues::Enum m_VerticalFieldValues; - QT3DSF32 m_Top; - LayerUnitTypes::Enum m_TopUnits; - QT3DSF32 m_Height; - LayerUnitTypes::Enum m_HeightUnits; - QT3DSF32 m_Bottom; - LayerUnitTypes::Enum m_BottomUnits; - - // Ambient occlusion - QT3DSF32 m_AoStrength; - QT3DSF32 m_AoDistance; - QT3DSF32 m_AoSoftness; - QT3DSF32 m_AoBias; - QT3DSI32 m_AoSamplerate; - bool m_AoDither; - - // Direct occlusion - QT3DSF32 m_ShadowStrength; - QT3DSF32 m_ShadowDist; - QT3DSF32 m_ShadowSoftness; - QT3DSF32 m_ShadowBias; - - // IBL - SImage *m_LightProbe; - QT3DSF32 m_ProbeBright; - bool m_FastIbl; - QT3DSF32 m_ProbeHorizon; - QT3DSF32 m_ProbeFov; - SImage *m_LightProbe2; - QT3DSF32 m_Probe2Fade; - QT3DSF32 m_Probe2Window; - QT3DSF32 m_Probe2Pos; - - bool m_TemporalAAEnabled; - - SLayer(); - - void AddEffect(SEffect &inEffect); - - SEffect *GetLastEffect(); - - LayerBlendTypes::Enum GetLayerBlend() - { - return m_BlendType; - } - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SNode::Remap(inRemapper); - inRemapper.Remap(m_Scene); - inRemapper.Remap(m_FirstEffect); - inRemapper.Remap(m_TexturePath); - inRemapper.Remap(m_RenderPlugin); - inRemapper.Remap(m_LightProbe); - inRemapper.Remap(m_LightProbe2); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.cpp deleted file mode 100644 index 3b45e8c9..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderLight.h" - -using namespace qt3ds::render; - -SLight::SLight() - : SNode(GraphObjectTypes::Light) - , m_LightType(RenderLightTypes::Directional) - , m_Scope(NULL) - , m_DiffuseColor(1, 1, 1) - , m_SpecularColor(1, 1, 1) - , m_AmbientColor(0, 0, 0) - , m_Brightness(100) - , m_LinearFade(0) - , m_ExponentialFade(0) - , m_AreaWidth(0) - , m_AreaHeight(0) - , m_CastShadow(false) - , m_ShadowBias(0.0f) - , m_ShadowFactor(5.0f) - , m_ShadowMapRes(9) - , m_ShadowMapFar(5000.0f) - , m_ShadowMapFov(90.0f) - , m_ShadowFilter(35.0f) -{ - m_Flags.SetPointLight(0); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.h deleted file mode 100644 index 549e3e26..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLight.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_LIGHT_H -#define QT3DS_RENDER_LIGHT_H -#include "Qt3DSRenderNode.h" - -namespace qt3ds { -namespace render { - - struct RenderLightTypes - { - enum Enum { - Unknown = 0, - Directional, - Point, - Area, - }; - }; - - struct SImage; - - struct QT3DS_AUTOTEST_EXPORT SLight : public SNode - { - RenderLightTypes::Enum m_LightType; // Directional - SNode *m_Scope; - QT3DSVec3 m_DiffuseColor; // colors are 0-1 normalized - QT3DSVec3 m_SpecularColor; // colors are 0-1 normalized - QT3DSVec3 m_AmbientColor; // colors are 0-1 normalized - - // The variables below are in the same range as Studio - // Only valid if node is a point light - QT3DSF32 m_Brightness; // 0-200 - QT3DSF32 m_LinearFade; // 0-200 - QT3DSF32 m_ExponentialFade; // 0-200 - - QT3DSF32 m_AreaWidth; // 0.01-inf - QT3DSF32 m_AreaHeight; // 0.01-inf - - bool m_CastShadow; // true if this light produce shadows - QT3DSF32 m_ShadowBias; // depth shift to avoid self-shadowing artifacts - QT3DSF32 m_ShadowFactor; // Darkening factor for ESMs - QT3DSU32 m_ShadowMapRes; // Resolution of shadow map - QT3DSF32 m_ShadowMapFar; // Far clip plane for the shadow map - QT3DSF32 m_ShadowMapFov; // Field of View for the shadow map - QT3DSF32 m_ShadowFilter; // Shadow map filter step size - - // Defaults to directional light - SLight(); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SNode::Remap(inRemapper); - inRemapper.Remap(m_Scope); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.cpp deleted file mode 100644 index 0e5e6c60..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderLightmaps.h" - -using namespace qt3ds::render; - -SLightmaps::SLightmaps() - : SGraphObject(GraphObjectTypes::Lightmaps) - , m_LightmapIndirect(NULL) - , m_LightmapRadiosity(NULL) - , m_LightmapShadow(NULL) -{ -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.h deleted file mode 100644 index 4480aea4..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderLightmaps.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_RENDER_LIGHTMAPS_H -#define QT3DS_RENDER_LIGHTMAPS_H - -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRenderMaterialDirty.h" - -namespace qt3ds { -namespace render { - - struct MaterialLightmapsUsage - { - enum Enum { - Dynamic = 0, - Baked, - DynamicAndBaked, - }; - }; - - struct QT3DS_AUTOTEST_EXPORT SLightmaps : public SGraphObject - { - CMaterialDirty m_Dirty; - - SImage *m_LightmapIndirect; - SImage *m_LightmapRadiosity; - SImage *m_LightmapShadow; - - SLightmaps(); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_LightmapIndirect); - inRemapper.Remap(m_LightmapRadiosity); - inRemapper.Remap(m_LightmapShadow); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderMaterialDirty.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderMaterialDirty.h deleted file mode 100644 index c04c1b6b..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderMaterialDirty.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_MATERIAL_DIRTY_H -#define QT3DS_RENDER_MATERIAL_DIRTY_H - -namespace qt3ds { -namespace render { - class CMaterialDirty - { - private: - bool m_Dirty; - bool m_DirtyFlagWithInFrame; - - public: - CMaterialDirty() - : m_Dirty(true) - , m_DirtyFlagWithInFrame(m_Dirty) - { - } - - void SetDirty() { m_Dirty = m_DirtyFlagWithInFrame = true; } - bool IsDirty() const { return m_Dirty || m_DirtyFlagWithInFrame; } - void ClearDirty() { m_DirtyFlagWithInFrame = m_Dirty = false; } - void UpdateDirtyForFrame() - { - m_DirtyFlagWithInFrame = m_Dirty; - m_Dirty = false; - } - }; -} -} - -#endif // QT3DS_RENDER_MATERIAL_DIRTY_H diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.cpp deleted file mode 100644 index a78396c5..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderModel.h" -#include "Qt3DSRenderMaterialHelpers.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderMesh.h" - -using namespace qt3ds::render; - -SModel::SModel() - : SNode(GraphObjectTypes::Model) - , m_FirstMaterial(NULL) - , m_SkeletonRoot(-1) - , m_TessellationMode(TessModeValues::NoTess) - , m_EdgeTess(1.0) - , m_InnerTess(1.0) - , m_WireframeMode(false) - , m_ShadowCaster(true) -{ -} - -void SModel::AddMaterial(SGraphObject &inMaterial) -{ - if (m_FirstMaterial == NULL) - m_FirstMaterial = &inMaterial; - else { - SGraphObject *lastMaterial; - // empty loop intentional - for (lastMaterial = m_FirstMaterial; lastMaterial && GetNextMaterialSibling(lastMaterial); - lastMaterial = GetNextMaterialSibling(lastMaterial)) { - } - SetNextMaterialSibling(*lastMaterial, &inMaterial); - } - if (inMaterial.m_Type == GraphObjectTypes::DefaultMaterial) - static_cast(inMaterial).m_Parent = this; -} - -NVBounds3 SModel::GetModelBounds(IBufferManager &inManager) const -{ - NVBounds3 retval; - retval.setEmpty(); - SRenderMesh *theMesh = inManager.LoadMesh(m_MeshPath); - if (theMesh) { - for (QT3DSU32 idx = 0, end = theMesh->m_Subsets.size(); idx < end; ++idx) - retval.include(theMesh->m_Subsets[idx].m_Bounds); - } - return retval; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.h deleted file mode 100644 index cc5c4e27..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderModel.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_MODEL_H -#define QT3DS_RENDER_MODEL_H - -#include "Qt3DSRenderNode.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderTessModeValues.h" - -namespace qt3ds { -namespace render { - - struct SDefaultMaterial; - class IBufferManager; - - struct QT3DS_AUTOTEST_EXPORT SModel : public SNode - { - // Complete path to the file; - //*not* relative to the presentation directory - CRegisteredString m_MeshPath; - SGraphObject *m_FirstMaterial; - QT3DSI32 m_SkeletonRoot; - TessModeValues::Enum m_TessellationMode; - QT3DSF32 m_EdgeTess; - QT3DSF32 m_InnerTess; - bool m_WireframeMode; - bool m_ShadowCaster; - - SModel(); - - void AddMaterial(SGraphObject &inMaterial); - - NVBounds3 GetModelBounds(IBufferManager &inManager) const; - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SNode::Remap(inRemapper); - inRemapper.RemapMaterial(m_FirstMaterial); - inRemapper.Remap(m_MeshPath); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.cpp deleted file mode 100644 index bf47bb8d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.cpp +++ /dev/null @@ -1,499 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderModel.h" -#include "Qt3DSRenderNode.h" -#include "Qt3DSRenderText.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRenderPathManager.h" -#include "Qt3DSRenderPath.h" - -using namespace qt3ds::render; - -SNode::SNode(GraphObjectTypes::Enum inGraphObjectType) - : SGraphObject(inGraphObjectType) - , m_Rotation(0, 0, 0) // Radians - , m_Position(0, 0, 0) - , m_Scale(1, 1, 1) - , m_Pivot(0, 0, 0) - , m_RotationOrder(EulOrdYXZs) - , m_LocalOpacity(1.0f) - , m_GlobalOpacity(1.0f) - , m_SkeletonId(-1) - , m_Parent(NULL) - , m_NextSibling(NULL) - , m_PreviousSibling(NULL) - , m_FirstChild(NULL) - , m_DFSIndex(0) -{ - m_Flags.SetDirty(true); - m_Flags.SetTransformDirty(true); - m_Flags.SetLeftHanded(true); - m_Flags.SetActive(true); - m_Flags.SetLocallyPickable(true); -} - -SNode::SNode(const SNode &inCloningObject, NVAllocatorCallback &inAllocator) - : SGraphObject(inCloningObject, inAllocator) - , m_Rotation(inCloningObject.m_Rotation) // Radians - , m_Position(inCloningObject.m_Position) - , m_Scale(inCloningObject.m_Scale) - , m_Pivot(inCloningObject.m_Pivot) - , m_RotationOrder(inCloningObject.m_RotationOrder) - , m_LocalOpacity(inCloningObject.m_LocalOpacity) - , m_LocalTransform(inCloningObject.m_LocalTransform) - , m_GlobalTransform(inCloningObject.m_GlobalTransform) - , m_GlobalOpacity(inCloningObject.m_GlobalOpacity) - , m_SkeletonId(inCloningObject.m_SkeletonId) - , m_Parent(NULL) - , m_NextSibling(NULL) - , m_PreviousSibling(NULL) - , m_FirstChild(NULL) - , m_DFSIndex(0) -{ - m_Flags.SetDirty(true); - m_Flags.SetTransformDirty(true); - m_Flags.SetLeftHanded(true); - m_Flags.SetActive(true); - m_Flags.SetLocallyPickable(true); - - // for ( SNode* theChild = m_FirstChild; theChild != NULL; theChild = theChild->m_NextSibling ) - //{ - // SNode* theClonedChild = static_cast( CGraphObjectFactory::CloneGraphObject( - //*theChild, inAllocator ) ); - // AddChild( *theClonedChild ); - //} -} - -// Sets this object dirty and walks down the graph setting all -// children who are not dirty to be dirty. -void SNode::MarkDirty(NodeTransformDirtyFlag::Enum inTransformDirty) -{ - if (m_Flags.IsTransformDirty() == false) - m_Flags.SetTransformDirty(inTransformDirty != NodeTransformDirtyFlag::TransformNotDirty); - if (m_Flags.IsDirty() == false) { - m_Flags.SetDirty(true); - for (SNode *child = m_FirstChild; child; child = child->m_NextSibling) - child->MarkDirty(inTransformDirty); - } -} - -// Calculate global transform and opacity -// Walks up the graph ensure all parents are not dirty so they have -// valid global transforms. - -bool SNode::CalculateGlobalVariables() -{ - bool retval = m_Flags.IsDirty(); - if (retval) { - m_Flags.SetDirty(false); - if (m_Flags.IsTransformDirty()) - CalculateLocalTransform(); - m_GlobalOpacity = m_LocalOpacity; - if (m_Parent) { - // Layer transforms do not flow down but affect the final layer's rendered - // representation. - retval = m_Parent->CalculateGlobalVariables() || retval; - if (m_Parent->m_Type != GraphObjectTypes::Layer) { - m_GlobalOpacity *= m_Parent->m_GlobalOpacity; - if (m_Flags.IsIgnoreParentTransform() == false) - m_GlobalTransform = m_Parent->m_GlobalTransform * m_LocalTransform; - else - m_GlobalTransform = m_LocalTransform; - } else - m_GlobalTransform = m_LocalTransform; - - m_Flags.SetGlobalActive(m_Flags.IsActive() && m_Parent->m_Flags.IsGloballyActive()); - m_Flags.SetGloballyPickable(m_Flags.IsLocallyPickable() - || m_Parent->m_Flags.IsGloballyPickable()); - } else { - m_GlobalTransform = m_LocalTransform; - m_Flags.SetGlobalActive(m_Flags.IsActive()); - m_Flags.SetGloballyPickable(m_Flags.IsLocallyPickable()); - } - } - // We always clear dirty in a reasonable manner but if we aren't active - // there is no reason to tell the universe if we are dirty or not. - return retval && m_Flags.IsActive(); -} - -// Create some mapping of euler angles to their axis mapping. -#define ITERATE_POSSIBLE_EULER_ANGLES \ - HANDLE_EULER_ANGLE(EulOrdXYZs, X, Y, Z) \ - HANDLE_EULER_ANGLE(EulOrdXYXs, X, Y, X) \ - HANDLE_EULER_ANGLE(EulOrdXZYs, X, Z, Y) \ - HANDLE_EULER_ANGLE(EulOrdXZXs, X, Z, X) \ - HANDLE_EULER_ANGLE(EulOrdYZXs, Y, Z, X) \ - HANDLE_EULER_ANGLE(EulOrdYZYs, Y, Z, Y) \ - HANDLE_EULER_ANGLE(EulOrdYXZs, Y, X, Z) \ - HANDLE_EULER_ANGLE(EulOrdYXYs, Y, X, Y) \ - HANDLE_EULER_ANGLE(EulOrdZXYs, Z, X, Y) \ - HANDLE_EULER_ANGLE(EulOrdZXZs, Z, X, Z) \ - HANDLE_EULER_ANGLE(EulOrdZYXs, Z, Y, X) \ - HANDLE_EULER_ANGLE(EulOrdZYZs, Z, Y, Z) \ - HANDLE_EULER_ANGLE(EulOrdZYXr, Z, Y, X) \ - HANDLE_EULER_ANGLE(EulOrdXYXr, X, Y, X) \ - HANDLE_EULER_ANGLE(EulOrdYZXr, Y, Z, X) \ - HANDLE_EULER_ANGLE(EulOrdXZXr, X, Z, X) \ - HANDLE_EULER_ANGLE(EulOrdXZYr, X, Z, Y) \ - HANDLE_EULER_ANGLE(EulOrdYZYr, Y, Z, Y) \ - HANDLE_EULER_ANGLE(EulOrdZXYr, Z, X, Y) \ - HANDLE_EULER_ANGLE(EulOrdYXYr, Y, X, Y) \ - HANDLE_EULER_ANGLE(EulOrdYXZr, Y, X, Z) \ - HANDLE_EULER_ANGLE(EulOrdZXZr, Z, X, Z) \ - HANDLE_EULER_ANGLE(EulOrdXYZr, X, Y, Z) \ - HANDLE_EULER_ANGLE(EulOrdZYZr, Z, Y, Z) - -inline EulerAngles RotationAndOrderToShoemake(QT3DSVec3 inRotation, QT3DSU32 inOrder) -{ - EulerAngles retval; - retval.w = (QT3DSF32)inOrder; - int X = 0; - int Y = 1; - int Z = 2; - - switch (inOrder) { -#define HANDLE_EULER_ANGLE(order, xIdx, yIdx, zIdx) \ - case order: \ - retval.x = -inRotation[xIdx]; \ - retval.y = -inRotation[yIdx]; \ - retval.z = -inRotation[zIdx]; \ - break; - ITERATE_POSSIBLE_EULER_ANGLES -#undef HANDLE_EULER_ANGLE - default: - QT3DS_ASSERT(false); - retval.x = inRotation[X]; - retval.y = inRotation[Y]; - retval.z = inRotation[Z]; - break; - } - return retval; -} - -QT3DSVec3 SNode::GetRotationVectorFromRotationMatrix(const QT3DSMat33 &inMatrix) const -{ - QT3DSMat44 theConvertMatrix(inMatrix, QT3DSVec3(0, 0, 0)); - if (m_Flags.IsLeftHanded()) - SNode::FlipCoordinateSystem(theConvertMatrix); - qt3ds::render::CEulerAngleConverter theConverter; - qt3ds::render::HMatrix *theHMatrix = - reinterpret_cast(theConvertMatrix.front()); - qt3ds::render::EulerAngles theAngles = theConverter.Eul_FromHMatrix(*theHMatrix, m_RotationOrder); - return GetRotationVectorFromEulerAngles(theAngles); -} - -QT3DSVec3 SNode::GetRotationVectorFromEulerAngles(const EulerAngles &inAngles) -{ - QT3DSVec3 retval(0, 0, 0); - int X = 0; - int Y = 1; - int Z = 2; - switch ((int)inAngles.w) { -#define HANDLE_EULER_ANGLE(order, xIdx, yIdx, zIdx) \ - case order: \ - retval[xIdx] = -inAngles.x; \ - retval[yIdx] = -inAngles.y; \ - retval[zIdx] = -inAngles.z; \ - break; - ITERATE_POSSIBLE_EULER_ANGLES -#undef HANDLE_EULER_ANGLE - default: - QT3DS_ASSERT(false); - retval.x = inAngles.x; - retval.y = inAngles.y; - retval.z = inAngles.z; - break; - } - - return retval; -} - -void SNode::CalculateRotationMatrix(QT3DSMat44 &outMatrix) const -{ - StaticAssert::valid_expression(); - CEulerAngleConverter theConverter; - EulerAngles theAngles(RotationAndOrderToShoemake(m_Rotation, (int)m_RotationOrder)); - HMatrix *theMatrix = reinterpret_cast(&outMatrix); - theConverter.Eul_ToHMatrix(theAngles, *theMatrix); -} - -void SNode::FlipCoordinateSystem(QT3DSMat44 &inMatrix) -{ - QT3DSF32 *writePtr(inMatrix.front()); - // rotation conversion - writePtr[0 * 4 + 2] *= -1; - writePtr[1 * 4 + 2] *= -1; - writePtr[2 * 4 + 0] *= -1; - writePtr[2 * 4 + 1] *= -1; - - // translation conversion - writePtr[3 * 4 + 2] *= -1; -} - -void SNode::CalculateLocalTransform() -{ - m_Flags.SetTransformDirty(false); - bool leftHanded = m_Flags.IsLeftHanded(); - m_LocalTransform = QT3DSMat44::createIdentity(); - m_GlobalTransform = m_LocalTransform; - QT3DSF32 *writePtr = m_LocalTransform.front(); - QT3DSVec3 theScaledPivot(-m_Pivot[0] * m_Scale[0], -m_Pivot[1] * m_Scale[1], - -m_Pivot[2] * m_Scale[2]); - m_LocalTransform.column0[0] = m_Scale[0]; - m_LocalTransform.column1[1] = m_Scale[1]; - m_LocalTransform.column2[2] = m_Scale[2]; - - writePtr[12] = theScaledPivot[0]; - writePtr[13] = theScaledPivot[1]; - if (leftHanded) - writePtr[14] = theScaledPivot[2]; - else - writePtr[14] = -theScaledPivot[2]; - - QT3DSMat44 theRotationTransform; - CalculateRotationMatrix(theRotationTransform); - // may need column conversion in here somewhere. - m_LocalTransform = theRotationTransform * m_LocalTransform; - - writePtr[12] += m_Position[0]; - writePtr[13] += m_Position[1]; - if (leftHanded) - writePtr[14] = writePtr[14] + m_Position[2]; - else - writePtr[14] = writePtr[14] - m_Position[2]; - - if (leftHanded) { - FlipCoordinateSystem(m_LocalTransform); - } -} - -void SNode::SetLocalTransformFromMatrix(QT3DSMat44 &inTransform) -{ - m_Flags.SetTransformDirty(true); - - // clear pivot - m_Pivot[0] = m_Pivot[1] = m_Pivot[2] = 0.0f; - - // set translation - m_Position[0] = inTransform[3][0]; - m_Position[1] = inTransform[3][1]; - m_Position[2] = inTransform[3][2]; - // set scale - m_Scale[0] = inTransform.column0.magnitude(); - m_Scale[1] = inTransform.column1.magnitude(); - m_Scale[2] = inTransform.column2.magnitude(); - - // make sure there is no zero value - m_Scale[0] = (m_Scale[0] == 0.0) ? 1.0f : m_Scale[0]; - m_Scale[1] = (m_Scale[1] == 0.0) ? 1.0f : m_Scale[1]; - m_Scale[2] = (m_Scale[2] == 0.0) ? 1.0f : m_Scale[2]; - - // extract rotation by first dividing through scale value - float invScaleX = 1.0f / m_Scale[0]; - float invScaleY = 1.0f / m_Scale[1]; - float invScaleZ = 1.0f / m_Scale[2]; - - inTransform[0][0] *= invScaleX; - inTransform[0][1] *= invScaleX; - inTransform[0][2] *= invScaleX; - inTransform[1][0] *= invScaleY; - inTransform[1][1] *= invScaleY; - inTransform[1][2] *= invScaleY; - inTransform[2][0] *= invScaleZ; - inTransform[2][1] *= invScaleZ; - inTransform[2][2] *= invScaleZ; - - QT3DSMat33 theRotationMatrix(inTransform.column0.getXYZ(), inTransform.column1.getXYZ(), - inTransform.column2.getXYZ()); - m_Rotation = GetRotationVectorFromRotationMatrix(theRotationMatrix); -} - -void SNode::AddChild(SNode &inChild) -{ - if (inChild.m_Parent) - inChild.m_Parent->RemoveChild(inChild); - inChild.m_Parent = this; - if (m_FirstChild == nullptr) { - m_FirstChild = &inChild; - inChild.m_NextSibling = nullptr; - inChild.m_PreviousSibling = nullptr; - } else { - SNode *lastChild = GetLastChild(); - if (lastChild) { - lastChild->m_NextSibling = &inChild; - inChild.m_PreviousSibling = lastChild; - inChild.m_NextSibling = nullptr; - } else { - QT3DS_ASSERT(false); // no last child but first child isn't null? - } - } -} - -void SNode::RemoveChild(SNode &inChild) -{ - if (inChild.m_Parent != this) { - QT3DS_ASSERT(false); - return; - } - for (SNode *child = m_FirstChild; child; child = child->m_NextSibling) { - if (child == &inChild) { - if (child->m_PreviousSibling) - child->m_PreviousSibling->m_NextSibling = child->m_NextSibling; - if (child->m_NextSibling) - child->m_NextSibling->m_PreviousSibling = child->m_PreviousSibling; - child->m_Parent = NULL; - if (m_FirstChild == child) - m_FirstChild = child->m_NextSibling; - child->m_NextSibling = NULL; - child->m_PreviousSibling = NULL; - return; - } - } - QT3DS_ASSERT(false); -} - -SNode *SNode::GetLastChild() -{ - SNode *lastChild = NULL; - // empty loop intentional - for (lastChild = m_FirstChild; lastChild && lastChild->m_NextSibling; - lastChild = lastChild->m_NextSibling) { - } - return lastChild; -} - -void SNode::RemoveFromGraph() -{ - if (m_Parent) - m_Parent->RemoveChild(*this); - - m_NextSibling = NULL; - - // Orphan all of my children. - SNode *nextSibling = NULL; - for (SNode *child = m_FirstChild; child != NULL; child = nextSibling) { - child->m_PreviousSibling = NULL; - child->m_Parent = NULL; - nextSibling = child->m_NextSibling; - child->m_NextSibling = NULL; - } -} - -NVBounds3 SNode::GetBounds(IBufferManager &inManager, IPathManager &inPathManager, - bool inIncludeChildren, IQt3DSRenderNodeFilter *inChildFilter) const -{ - NVBounds3 retval; - retval.setEmpty(); - if (inIncludeChildren) - retval = GetChildBounds(inManager, inPathManager, inChildFilter); - - if (m_Type == GraphObjectTypes::Model) - retval.include(static_cast(this)->GetModelBounds(inManager)); - else if (m_Type == GraphObjectTypes::Text) - retval.include(static_cast(this)->GetTextBounds()); - else if (m_Type == GraphObjectTypes::Path) - retval.include(inPathManager.GetBounds(*static_cast(this))); - return retval; -} - -NVBounds3 SNode::GetChildBounds(IBufferManager &inManager, IPathManager &inPathManager, - IQt3DSRenderNodeFilter *inChildFilter) const -{ - NVBounds3 retval; - retval.setEmpty(); - for (SNode *child = m_FirstChild; child != NULL; child = child->m_NextSibling) { - if (inChildFilter == NULL || inChildFilter->IncludeNode(*child)) { - NVBounds3 childBounds; - if (child->m_Flags.IsTransformDirty()) - child->CalculateLocalTransform(); - childBounds = child->GetBounds(inManager, inPathManager); - if (childBounds.isEmpty() == false) { - // Transform the bounds into our local space. - childBounds.transform(child->m_LocalTransform); - retval.include(childBounds); - } - } - } - return retval; -} - -QT3DSVec3 SNode::GetGlobalPos() const -{ - return m_GlobalTransform.getPosition(); -} - -QT3DSVec3 SNode::GetDirection() const -{ - const QT3DSF32 *dataPtr(m_GlobalTransform.front()); - QT3DSVec3 retval(dataPtr[8], dataPtr[9], dataPtr[10]); - retval.normalize(); - return retval; -} - -QT3DSVec3 SNode::GetScalingCorrectDirection() const -{ - QT3DSMat33 theDirMatrix(m_GlobalTransform.getUpper3x3().getInverse().getTranspose()); - QT3DSVec3 theOriginalDir(0, 0, -1); - QT3DSVec3 retval = theDirMatrix.transform(theOriginalDir); - retval.normalize(); - return retval; -} - -QT3DSVec3 SNode::GetGlobalPivot() const -{ - QT3DSVec3 retval(m_Position); - retval.z *= -1; - - if (m_Parent && m_Parent->m_Type != GraphObjectTypes::Layer) - return m_Parent->m_GlobalTransform.transform(retval); - - return retval; -} - -void SNode::CalculateMVPAndNormalMatrix(const QT3DSMat44 &inViewProjection, QT3DSMat44 &outMVP, - QT3DSMat33 &outNormalMatrix) const -{ - outMVP = inViewProjection * m_GlobalTransform; - CalculateNormalMatrix(outNormalMatrix); -} - -void SNode::GetMatrixUpper3x3(QT3DSMat33 &outDest, const QT3DSMat44 &inSrc) -{ - outDest.column0 = QT3DSVec3(inSrc.column0[0], inSrc.column0[1], inSrc.column0[2]); - outDest.column1 = QT3DSVec3(inSrc.column1[0], inSrc.column1[1], inSrc.column1[2]); - outDest.column2 = QT3DSVec3(inSrc.column2[0], inSrc.column2[1], inSrc.column2[2]); -} - -void SNode::CalculateNormalMatrix(QT3DSMat33 &outNormalMatrix) const -{ - GetMatrixUpper3x3(outNormalMatrix, m_GlobalTransform); - outNormalMatrix = outNormalMatrix.getInverse().getTranspose(); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.h deleted file mode 100644 index 87a1500c..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderNode.h +++ /dev/null @@ -1,307 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_NODE_H -#define QT3DS_RENDER_NODE_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "foundation/Qt3DSMat44.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSBounds3.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSNoCopy.h" -#include "Qt3DSRenderEulerAngles.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - - struct SModel; - struct SLight; - struct SCamera; - struct SText; - struct SNode; - class IBufferManager; - - class INodeQueue - { - protected: - virtual ~INodeQueue() {} - public: - virtual void Enqueue(SModel &inModel) = 0; - virtual void Enqueue(SLight &inLight) = 0; - virtual void Enqueue(SCamera &inCamera) = 0; - // virtual void Enqueue( SText& inText ) = 0; - }; - - struct NodeFlagValues - { - enum Enum { - Dirty = 1, - TransformDirty = 1 << 1, - Active = 1 << 2, ///< Is this exact object active - LeftHanded = 1 << 3, - Orthographic = 1 << 4, - PointLight = 1 << 5, - GlobalActive = 1 << 6, ///< set based in Active and if a parent is active. - TextDirty = 1 << 7, - LocallyPickable = 1 << 8, - GloballyPickable = 1 << 9, - LayerEnableDepthTest = 1 << 10, - LayerRenderToTarget = 1 << 11, ///< Does this layer render to the normal render target, - ///or is it offscreen-only - ForceLayerOffscreen = 1 << 12, ///< Forces a layer to always use the offscreen rendering - ///mechanism. This can be usefulf or caching purposes. - IgnoreParentTransform = 1 << 13, - LayerEnableDepthPrePass = 1 << 14, ///< True when we render a depth pass before - }; - }; - - struct NodeTransformDirtyFlag - { - enum Enum { - TransformNotDirty, - TransformIsDirty, - }; - }; - struct NodeFlags : public NVFlags - { - NodeFlags() - : NVFlags((QT3DSU32)0) - { - } - void ClearOrSet(bool value, NodeFlagValues::Enum enumVal) { clearOrSet(value, enumVal); } - void SetActive(bool value) { ClearOrSet(value, NodeFlagValues::Active); } - bool IsActive() const { return this->operator&(NodeFlagValues::Active); } - - void SetGlobalActive(bool value) { ClearOrSet(value, NodeFlagValues::GlobalActive); } - bool IsGloballyActive() const { return this->operator&(NodeFlagValues::GlobalActive); } - - void SetTransformDirty(bool value) { ClearOrSet(value, NodeFlagValues::TransformDirty); } - bool IsTransformDirty() const { return this->operator&(NodeFlagValues::TransformDirty); } - - void SetDirty(bool value) { ClearOrSet(value, NodeFlagValues::Dirty); } - bool IsDirty() const { return this->operator&(NodeFlagValues::Dirty); } - - bool IsLeftHanded() const { return this->operator&(NodeFlagValues::LeftHanded); } - void SetLeftHanded(bool value) { ClearOrSet(value, NodeFlagValues::LeftHanded); } - - bool IsOrthographic() const { return this->operator&(NodeFlagValues::Orthographic); } - void SetOrthographic(bool value) { ClearOrSet(value, NodeFlagValues::Orthographic); } - - bool IsPointLight() const { return this->operator&(NodeFlagValues::PointLight); } - void SetPointLight(bool value) { ClearOrSet(value, NodeFlagValues::PointLight); } - - bool IsTextDirty() const { return this->operator&(NodeFlagValues::TextDirty); } - void SetTextDirty(bool value) { ClearOrSet(value, NodeFlagValues::TextDirty); } - - bool IsLocallyPickable() const { return this->operator&(NodeFlagValues::LocallyPickable); } - void SetLocallyPickable(bool value) { ClearOrSet(value, NodeFlagValues::LocallyPickable); } - - bool IsGloballyPickable() const - { - return this->operator&(NodeFlagValues::GloballyPickable); - } - void SetGloballyPickable(bool value) - { - ClearOrSet(value, NodeFlagValues::GloballyPickable); - } - - bool IsLayerRenderToTarget() const - { - return this->operator&(NodeFlagValues::LayerRenderToTarget); - } - void SetLayerRenderToTarget(bool value) - { - ClearOrSet(value, NodeFlagValues::LayerRenderToTarget); - } - - bool IsLayerEnableDepthTest() const - { - return this->operator&(NodeFlagValues::LayerEnableDepthTest); - } - void SetLayerEnableDepthTest(bool value) - { - ClearOrSet(value, NodeFlagValues::LayerEnableDepthTest); - } - - bool IsForceLayerOffscreen() const - { - return this->operator&(NodeFlagValues::ForceLayerOffscreen); - } - void SetForceLayerOffscreen(bool value) - { - ClearOrSet(value, NodeFlagValues::ForceLayerOffscreen); - } - - bool IsIgnoreParentTransform() const - { - return this->operator&(NodeFlagValues::IgnoreParentTransform); - } - void SetIgnoreParentTransform(bool value) - { - ClearOrSet(value, NodeFlagValues::IgnoreParentTransform); - } - - bool IsLayerEnableDepthPrepass() const - { - return this->operator&(NodeFlagValues::LayerEnableDepthPrePass); - } - void SetLayerEnableDepthPrepass(bool value) - { - ClearOrSet(value, NodeFlagValues::LayerEnableDepthPrePass); - } - }; - - struct QT3DS_AUTOTEST_EXPORT SNode : public SGraphObject - { - // changing any one of these means you have to - // set this object dirty - QT3DSVec3 m_Rotation; // Radians - QT3DSVec3 m_Position; - QT3DSVec3 m_Scale; - QT3DSVec3 m_Pivot; - QT3DSU32 m_RotationOrder; // UICEulerOrder::EulOrd, defaults YXZs - - // This only sets dirty, not transform dirty - // Opacity of 1 means opaque, opacity of zero means transparent. - QT3DSF32 m_LocalOpacity; - - // results of clearing dirty. - NodeFlags m_Flags; - // These end up right handed - QT3DSMat44 m_LocalTransform; - QT3DSMat44 m_GlobalTransform; - QT3DSF32 m_GlobalOpacity; - QT3DSI32 m_SkeletonId; - - // node graph members. - SNode *m_Parent; - SNode *m_NextSibling; - SNode *m_PreviousSibling; - SNode *m_FirstChild; - // Property maintained solely by the render system. - // Depth-first-search index assigned and maintained by render system. - QT3DSU32 m_DFSIndex; - - SNode(GraphObjectTypes::Enum inType = GraphObjectTypes::Node); - SNode(const SNode &inCloningObject, NVAllocatorCallback &inAllocator); - ~SNode() {} - - // Sets this object dirty and walks down the graph setting all - // children who are not dirty to be dirty. - void MarkDirty(NodeTransformDirtyFlag::Enum inTransformDirty = - NodeTransformDirtyFlag::TransformNotDirty); - - void AddChild(SNode &inChild); - void RemoveChild(SNode &inChild); - SNode *GetLastChild(); - - // Remove this node from the graph. - // It is no longer the the parent's child lists - // and all of its children no longer have a parent - // finally they are no longer siblings of each other. - void RemoveFromGraph(); - - // Calculate global transform and opacity - // Walks up the graph ensure all parents are not dirty so they have - // valid global transforms. - bool CalculateGlobalVariables(); - - // Given our rotation order and handedness, calculate the final rotation matrix - // Only the upper 3x3 of this matrix is filled in. - // If this object is left handed, then you need to call FlipCoordinateSystem - // to get a result identical to the result produced in CalculateLocalTransform - void CalculateRotationMatrix(QT3DSMat44 &outMatrix) const; - - // Get a rotation vector that would produce the given 3x.3 matrix. - // Takes m_RotationOrder and m_Flags.IsLeftHandled into account. - // Returns a rotation vector in radians. - QT3DSVec3 GetRotationVectorFromRotationMatrix(const QT3DSMat33 &inMatrix) const; - - static QT3DSVec3 GetRotationVectorFromEulerAngles(const EulerAngles &inAngles); - - // Flip a matrix from left-handed to right-handed and vice versa - static void FlipCoordinateSystem(QT3DSMat44 &ioMatrix); - - // Force the calculation of the local transform - void CalculateLocalTransform(); - - /** - * @brief setup local tranform from a matrix. - * This function decomposes a SRT matrix. - * This will fail if this matrix contains non-affine transformations - * - * @param inTransform[in] input transformation - * - * @return true backend type - */ - void SetLocalTransformFromMatrix(QT3DSMat44 &inTransform); - - // Get the bounds of us and our children in our local space. - NVBounds3 GetBounds(IBufferManager &inManager, IPathManager &inPathManager, - bool inIncludeChildren = true, - IQt3DSRenderNodeFilter *inChildFilter = NULL) const; - NVBounds3 GetChildBounds(IBufferManager &inManager, IPathManager &inPathManager, - IQt3DSRenderNodeFilter *inChildFilter = NULL) const; - // Assumes CalculateGlobalVariables has already been called. - QT3DSVec3 GetGlobalPos() const; - QT3DSVec3 GetGlobalPivot() const; - // Pulls the 3rd column out of the global transform. - QT3DSVec3 GetDirection() const; - // Multiplies (0,0,-1) by the inverse transpose of the upper 3x3 of the global transform. - // This is correct w/r/t to scaling and which the above getDirection is not. - QT3DSVec3 GetScalingCorrectDirection() const; - - // outMVP and outNormalMatrix are returned ready to upload to openGL, meaning they are - // row-major. - void CalculateMVPAndNormalMatrix(const QT3DSMat44 &inViewProjection, QT3DSMat44 &outMVP, - QT3DSMat33 &outNormalMatrix) const; - - // This should be in a utility file somewhere - static void GetMatrixUpper3x3(QT3DSMat33 &inDest, const QT3DSMat44 &inSrc); - void CalculateNormalMatrix(QT3DSMat33 &outNormalMatrix) const; - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_Parent); - inRemapper.Remap(m_FirstChild); - inRemapper.Remap(m_NextSibling); - inRemapper.Remap(m_PreviousSibling); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.cpp deleted file mode 100644 index bc637680..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderPathSubPath.h" - -using namespace qt3ds::render; - -void SPath::AddSubPath(SPathSubPath &inSegment) -{ - SPathSubPath *lastSegment = NULL; - inSegment.m_Path = this; - inSegment.m_NextSubPath = NULL; - if (m_FirstSubPath) { - // find last segment - for (lastSegment = m_FirstSubPath; lastSegment && lastSegment->m_NextSubPath; - lastSegment = lastSegment->m_NextSubPath) - ; - lastSegment->m_NextSubPath = &inSegment; - } else - m_FirstSubPath = &inSegment; -} - -void SPath::ClearSubPaths() -{ - SPathSubPath *nextSegment = NULL; - for (SPathSubPath *theSegment = m_FirstSubPath; theSegment; theSegment = nextSegment) { - nextSegment = theSegment->m_NextSubPath; - theSegment->m_Path = NULL; - theSegment->m_NextSubPath = NULL; - } - m_FirstSubPath = NULL; -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.h deleted file mode 100644 index 7db3ef50..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPath.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PATH_H -#define QT3DS_RENDER_PATH_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderNode.h" - -namespace qt3ds { -namespace render { - struct PathCapping - { - enum Enum { - Noner = 0, - Taper = 1, - }; - }; - - struct PathTypes - { - enum Enum { - Noner = 0, - Painted, - Geometry, - }; - }; - - struct PathPaintStyles - { - enum Enum { - Noner = 0, - FilledAndStroked, - Filled, - Stroked, - }; - }; - - struct SPath : public SNode - { - PathTypes::Enum m_PathType; - QT3DSF32 m_Width; - QT3DSF32 m_LinearError; - QT3DSF32 m_EdgeTessAmount; - QT3DSF32 m_InnerTessAmount; - PathCapping::Enum m_BeginCapping; - QT3DSF32 m_BeginCapOffset; - QT3DSF32 m_BeginCapOpacity; - QT3DSF32 m_BeginCapWidth; - PathCapping::Enum m_EndCapping; - QT3DSF32 m_EndCapOffset; - QT3DSF32 m_EndCapOpacity; - QT3DSF32 m_EndCapWidth; - SGraphObject *m_Material; - SGraphObject *m_SecondMaterial; - // Paths can either be immediate - children attached define path - // or they can link to a path buffer that defines the path. - SPathSubPath *m_FirstSubPath; - CRegisteredString m_PathBuffer; - PathPaintStyles::Enum m_PaintStyle; - - bool m_WireframeMode; - // Loaded onto the card just as data. - SPath() - : SNode(GraphObjectTypes::Path) - , m_PathType(PathTypes::Geometry) - , m_Width(5.0f) - , m_LinearError(100.0f) - , m_EdgeTessAmount(8.0f) - , m_InnerTessAmount(1.0f) - , m_BeginCapping(PathCapping::Noner) - , m_BeginCapOffset(10.0f) - , m_BeginCapOpacity(.2f) - , m_BeginCapWidth(0.0f) - , m_EndCapping(PathCapping::Noner) - , m_EndCapOffset(10.0f) - , m_EndCapOpacity(.2f) - , m_EndCapWidth(0.0f) - , m_Material(NULL) - , m_SecondMaterial(NULL) - , m_FirstSubPath(NULL) - , m_PaintStyle(PathPaintStyles::Stroked) - , m_WireframeMode(false) - { - } - - bool IsStroked() const - { - return m_PaintStyle == PathPaintStyles::Stroked - || m_PaintStyle == PathPaintStyles::FilledAndStroked; - } - - bool IsFilled() const - { - return m_PaintStyle == PathPaintStyles::Filled - || m_PaintStyle == PathPaintStyles::FilledAndStroked; - } - - void AddMaterial(SGraphObject *inMaterial) - { - if (m_Material == NULL) - m_Material = inMaterial; - else - m_SecondMaterial = inMaterial; - } - - void ClearMaterials() - { - m_Material = NULL; - m_SecondMaterial = NULL; - } - - void AddSubPath(SPathSubPath &inSubPath); - void ClearSubPaths(); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SNode::Remap(inRemapper); - inRemapper.Remap(m_PathBuffer); - inRemapper.RemapMaterial(m_Material); - inRemapper.RemapMaterial(m_SecondMaterial); - inRemapper.Remap(m_FirstSubPath); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPathSubPath.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPathSubPath.h deleted file mode 100644 index ed1f9beb..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPathSubPath.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PATH_SEGMENT_H -#define QT3DS_RENDER_PATH_SEGMENT_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" - -namespace qt3ds { -namespace render { - struct SPathSubPath : public SGraphObject - { - SPath *m_Path; - SPathSubPath *m_NextSubPath; - bool m_Closed; - - SPathSubPath() - : SGraphObject(GraphObjectTypes::PathSubPath) - , m_Path(NULL) - , m_NextSubPath(NULL) - , m_Closed(false) - { - } - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_Path); - inRemapper.Remap(m_NextSubPath); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.cpp deleted file mode 100644 index 6403959e..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderPresentation.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderContextCore.h" - -using namespace qt3ds::render; - -void SPresentation::Render(IQt3DSRenderContext &inContext) -{ - if (m_Scene) { - NVRenderRect theViewportSize(inContext.GetRenderContext().GetViewport()); - m_Scene->Render(QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), - inContext); - } -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h deleted file mode 100644 index 2403e3b8..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PRESENTATION_H -#define QT3DS_RENDER_PRESENTATION_H - -#include "foundation/StringTable.h" -#include "Qt3DSRenderGraphObject.h" -#include "Qt3DSRenderScene.h" -#include "foundation/Qt3DSVec2.h" - -namespace qt3ds { -namespace render { - - struct RenderRotationValues - { - enum Enum { - NoRotation = 0, - Clockwise90, - Clockwise180, - Clockwise270, - }; - }; - - struct SPresentation : public SGraphObject - { - QT3DSVec2 m_PresentationDimensions; - RenderRotationValues::Enum m_PresentationRotation; - bool m_preferKTX; - SScene *m_Scene; - - CRegisteredString m_PresentationDirectory; - - SPresentation() - : SGraphObject(GraphObjectTypes::Presentation) - , m_PresentationDimensions(800, 400) - , m_PresentationRotation(RenderRotationValues::NoRotation) - , m_preferKTX(false) - , m_Scene(NULL) - { - } - - SPresentation(QT3DSF32 w, QT3DSF32 h, bool preferKTX, CRegisteredString presDir) - : SGraphObject(GraphObjectTypes::Presentation) - , m_PresentationDimensions(w, h) - , m_PresentationRotation(RenderRotationValues::NoRotation) - , m_preferKTX(preferKTX) - , m_Scene(NULL) - , m_PresentationDirectory(presDir) - { - } - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_Scene); - inRemapper.Remap(m_PresentationDirectory); - } - - void Render(IQt3DSRenderContext &inContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderReferencedMaterial.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderReferencedMaterial.h deleted file mode 100644 index d2043f0d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderReferencedMaterial.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_REFERENCED_MATERIAL_H -#define QT3DS_RENDER_REFERENCED_MATERIAL_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -#include "Qt3DSRenderMaterialDirty.h" - -namespace qt3ds { -namespace render { - - struct SReferencedMaterial : SGraphObject - { - CMaterialDirty m_Dirty; - SGraphObject *m_ReferencedMaterial; - SGraphObject *m_NextSibling; - SReferencedMaterial() - : SGraphObject(GraphObjectTypes::ReferencedMaterial) - , m_ReferencedMaterial(NULL) - , m_NextSibling(NULL) - { - } - - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.RemapMaterial(m_ReferencedMaterial); - inRemapper.RemapMaterial(m_NextSibling); - } - }; -} -} - -#endif // QT3DS_RENDER_REFERENCED_MATERIAL_H diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.cpp deleted file mode 100644 index 8d206e69..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRender.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderContextCore.h" -#include "render/Qt3DSRenderContext.h" - -using namespace qt3ds::render; - -SScene::SScene() - : SGraphObject(GraphObjectTypes::Scene) - , m_Presentation(NULL) - , m_FirstChild(NULL) - , m_ClearColor(0, 0, 0) - , m_UseClearColor(true) - , m_Dirty(true) -{ -} - -void SScene::AddChild(SLayer &inLayer) -{ - if (m_FirstChild == NULL) - m_FirstChild = &inLayer; - else - GetLastChild()->m_NextSibling = &inLayer; - inLayer.m_Scene = this; -} - -SLayer *SScene::GetLastChild() -{ - // empty loop intentional - SLayer *child; - for (child = m_FirstChild; child && child->m_NextSibling; - child = (SLayer *)child->m_NextSibling) { - } - - return child; -} - -bool SScene::PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, - const SRenderInstanceId id) -{ - // We need to iterate through the layers in reverse order and ask them to render. - bool wasDirty = m_Dirty; - m_Dirty = false; - if (m_FirstChild) { - wasDirty |= - inContext.GetRenderer().PrepareLayerForRender(*m_FirstChild, inViewportDimensions, - true, id); - } - return wasDirty; -} - -void SScene::Render(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, - RenderClearCommand inClearColorBuffer, const SRenderInstanceId id) -{ - if ((inClearColorBuffer == SScene::ClearIsOptional && m_UseClearColor) - || inClearColorBuffer == SScene::AlwaysClear) { - QT3DSF32 clearColorAlpha - = inContext.IsInSubPresentation() && !m_UseClearColor ? 0.0f : 1.0f; - QT3DSVec4 clearColor(0.0f, 0.0f, 0.0f, clearColorAlpha); - if (m_UseClearColor) { - clearColor.x = m_ClearColor.x; - clearColor.y = m_ClearColor.y; - clearColor.z = m_ClearColor.z; - } - // Maybe clear and reset to previous clear color after we leave. - qt3ds::render::NVRenderContextScopedProperty __clearColor( - inContext.GetRenderContext(), &NVRenderContext::GetClearColor, - &NVRenderContext::SetClearColor, clearColor); - inContext.GetRenderContext().Clear(qt3ds::render::NVRenderClearValues::Color); - } - if (m_FirstChild) { - inContext.GetRenderer().RenderLayer(*m_FirstChild, inViewportDimensions, m_UseClearColor, - m_ClearColor, true, id); - } -} -void SScene::RenderWithClear(const QT3DSVec2 &inViewportDimensions, - IQt3DSRenderContext &inContext, - RenderClearCommand inClearColorBuffer, - QT3DSVec3 inClearColor, - const SRenderInstanceId id) -{ - // If this scene is not using clear color, we set the color - // to background color from parent layer. This allows - // fully transparent subpresentations (both scene and layer(s) transparent) - // to inherit color from the layer that contains them. - if (!m_UseClearColor) { - m_ClearColor = inClearColor; - m_UseClearColor = true; - } - Render(inViewportDimensions, inContext, inClearColorBuffer, id); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.h deleted file mode 100644 index 57887199..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderScene.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SCENE_H -#define QT3DS_RENDER_SCENE_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSVec3.h" -#include "Qt3DSRenderGraphObject.h" - -namespace qt3ds { -namespace render { - struct SLayer; - struct SPresentation; - typedef void *SRenderInstanceId; - - struct SScene : public SGraphObject - { - SPresentation *m_Presentation; - SLayer *m_FirstChild; - QT3DSVec3 m_ClearColor; - bool m_UseClearColor; - bool m_Dirty; - - enum RenderClearCommand { - ClearIsOptional = 0, - DoNotClear = 1, - AlwaysClear = 2, - }; - - SScene(); - - void AddChild(SLayer &inLayer); - SLayer *GetLastChild(); - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_Presentation); - inRemapper.Remap(m_FirstChild); - } - // returns true if any of the layers were dirty or if this object was dirty - bool PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, - const SRenderInstanceId id = nullptr); - void Render(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, - RenderClearCommand command = ClearIsOptional, - const SRenderInstanceId id = nullptr); - void RenderWithClear(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, - RenderClearCommand inClearColorBuffer, - QT3DSVec3 inclearColor, const SRenderInstanceId id = nullptr); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.cpp deleted file mode 100644 index 8b44e00f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderText.h" - -using namespace qt3ds::render; - -STextRenderInfo::STextRenderInfo() - : m_FontSize(24) - , m_HorizontalAlignment(TextHorizontalAlignment::Center) - , m_VerticalAlignment(TextVerticalAlignment::Middle) - , m_Leading(0) - , m_Tracking(0) - , m_DropShadow(false) - , m_DropShadowStrength(80) - , m_DropShadowOffset(10) - , m_DropShadowOffsetX(0) - , m_DropShadowOffsetY(0) - , m_DropShadowHorizontalAlignment(TextHorizontalAlignment::Right) - , m_DropShadowVerticalAlignment(TextVerticalAlignment::Bottom) - , m_WordWrap(TextWordWrap::WrapWord) - , m_BoundingBox(QT3DSVec2(0 ,0)) - , m_Elide(TextElide::ElideNone) - , m_ScaleX(0) - , m_ScaleY(0) - , m_EnableAcceleratedFont(false) -{ -} - -STextRenderInfo::~STextRenderInfo() -{ -} - -SText::SText() - : SNode(GraphObjectTypes::Text) - , m_TextColor(1, 1, 1) - , m_TextTexture(NULL) -{ - m_Bounds.setEmpty(); -} - -NVBounds3 SText::GetTextBounds() const -{ - NVBounds3 retval; - retval.setEmpty(); - if (m_TextTexture != NULL) { - retval.include(m_Bounds); - } - return retval; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.h deleted file mode 100644 index 56a2a9bf..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderText.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TEXT_H -#define QT3DS_RENDER_TEXT_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderNode.h" -#include "Qt3DSRenderTextTypes.h" - -namespace qt3ds { -namespace render { - - struct SText : public SNode, public STextRenderInfo - { - // Change any of these properties and you can expect - // that the text will force an expensive re-layer and render. - // For these you need to set TextDirty. - - // These properties can change every frame with no additional cost. - QT3DSVec3 m_TextColor; - // Setup and utilized by the rendering system - NVRenderTexture2D *m_TextTexture; - STextTextureDetails m_TextTextureDetails; - // used for nv path rendering - NVRenderPathFontItem *m_PathFontItem; - NVRenderPathFontSpecification *m_PathFontDetails; - - NVBounds3 m_Bounds; - - SText(); - - NVBounds3 GetTextBounds() const; - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SNode::Remap(inRemapper); - inRemapper.Remap(m_Text); - inRemapper.Remap(m_Font); - inRemapper.NullPtr(m_TextTexture); - inRemapper.NullPtr(m_PathFontItem); - inRemapper.NullPtr(m_PathFontDetails); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/ANDROID/DynamicLibLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/ANDROID/DynamicLibLoader.h deleted file mode 100644 index ad47c506..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/ANDROID/DynamicLibLoader.h +++ /dev/null @@ -1,30 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "LINUX/DynamicLibLoader.h" \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/LINUX/DynamicLibLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/LINUX/DynamicLibLoader.h deleted file mode 100644 index cc5d077c..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/LINUX/DynamicLibLoader.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_LINUX_DYNAMIC_LIB_LOADER_H -#define QT3DS_LINUX_DYNAMIC_LIB_LOADER_H -#include -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" - -namespace qt3ds { -namespace render { - using namespace qt3ds; - using namespace qt3ds::render; - - class CLoadedDynamicLibrary - { - void *m_DLLHandle; - CLoadedDynamicLibrary(void *hdl) - : m_DLLHandle(hdl) - { - } - CLoadedDynamicLibrary(const CLoadedDynamicLibrary &); - CLoadedDynamicLibrary &operator=(const CLoadedDynamicLibrary &); - - public: - ~CLoadedDynamicLibrary() - { - if (m_DLLHandle) - { -#ifndef _INTEGRITYPLATFORM - ::dlclose(m_DLLHandle); -#endif - } - m_DLLHandle = 0; - } - void *FindFunction(const char *name) - { -#ifndef _INTEGRITYPLATFORM - return ::dlsym(m_DLLHandle, name); -#else - qWarning() << "CLoadedDynamicLibrary::FindFunction returns NULL!"; - return NULL; -#endif - } - static CLoadedDynamicLibrary *Create(const char *inFullDllPath, NVFoundationBase &fnd) - { -#ifndef _INTEGRITYPLATFORM - void *hdl = ::dlopen(inFullDllPath, RTLD_NOW); - if (hdl == 0) { - const char *error = ::dlerror(); - qCCritical(INVALID_OPERATION, "Failed to load dynamic library %s: %s", - inFullDllPath, error); - return NULL; - } - return QT3DS_NEW(fnd.getAllocator(), CLoadedDynamicLibrary)(hdl); -#else - qWarning() << "CLoadedDynamicLibrary::Create returns NULL!"; - return NULL; -#endif - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/OSX/DynamicLibLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/OSX/DynamicLibLoader.h deleted file mode 100644 index df486c14..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/OSX/DynamicLibLoader.h +++ /dev/null @@ -1,30 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "LINUX/DynamicLibLoader.h" diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/QNX/DynamicLibLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/QNX/DynamicLibLoader.h deleted file mode 100644 index df486c14..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/QNX/DynamicLibLoader.h +++ /dev/null @@ -1,30 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "LINUX/DynamicLibLoader.h" diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderKey.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderKey.h deleted file mode 100644 index 555c2689..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderKey.h +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_OFFSCREEN_RENDER_KEY_H -#define QT3DS_OFFSCREEN_RENDER_KEY_H -#include "Qt3DSRender.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" - -namespace qt3ds { -namespace foundation { - - template <> - struct DestructTraits - { - void destruct(CRegisteredString &) {} - }; -} -} - -namespace qt3ds { -namespace render { - struct OffscreenRendererKeyTypes - { - enum Enum { - NoOffscreenRendererKey = 0, - RegisteredString, - VoidPtr, - }; - }; - - template - struct SOffscreenRendererKeyTypeMap - { - }; - template <> - struct SOffscreenRendererKeyTypeMap - { - enum { KeyType = OffscreenRendererKeyTypes::RegisteredString }; - }; - template <> - struct SOffscreenRendererKeyTypeMap - { - enum { KeyType = OffscreenRendererKeyTypes::VoidPtr }; - }; - - struct SOffscreenRendererKeyUnionTraits - { - typedef OffscreenRendererKeyTypes::Enum TIdType; - enum { - TBufferSize = sizeof(CRegisteredString), - }; - - static TIdType getNoDataId() { return OffscreenRendererKeyTypes::NoOffscreenRendererKey; } - - template - static TIdType getType() - { - return (TIdType)SOffscreenRendererKeyTypeMap::KeyType; - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case OffscreenRendererKeyTypes::RegisteredString: - return inVisitor(*NVUnionCast(inData)); - case OffscreenRendererKeyTypes::VoidPtr: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case OffscreenRendererKeyTypes::NoOffscreenRendererKey: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case OffscreenRendererKeyTypes::RegisteredString: - return inVisitor(*NVUnionCast(inData)); - case OffscreenRendererKeyTypes::VoidPtr: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case OffscreenRendererKeyTypes::NoOffscreenRendererKey: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SOffscreenRendererKeyUnionTraits::TBufferSize> - TOffscreenRendererKeyUnionType; - - struct SOffscreenRendererKey : public TOffscreenRendererKeyUnionType - { - typedef TOffscreenRendererKeyUnionType TBase; - SOffscreenRendererKey() {} - SOffscreenRendererKey(const CRegisteredString &str) - : TBase(str) - { - } - SOffscreenRendererKey(void *key) - : TBase(key) - { - } - SOffscreenRendererKey(const SOffscreenRendererKey &other) - : TBase(static_cast(other)) - { - } - SOffscreenRendererKey &operator=(const SOffscreenRendererKey &other) - { - TBase::operator=(other); - return *this; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h deleted file mode 100644 index 57dcf430..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_OFFSCREEN_RENDER_MANAGER_H -#define QT3DS_OFFSCREEN_RENDER_MANAGER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSOption.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderLayer.h" - -namespace qt3ds { -namespace render { - class IResourceManager; - struct Qt3DSRenderPickResult; - class IGraphObjectPickQuery; - struct OffscreenRendererDepthValues - { - enum Enum { - NoDepthBuffer = 0, - Depth16, // 16 bit depth buffer - Depth24, // 24 bit depth buffer - Depth32, // 32 bit depth buffer - Depth24Stencil8 // 24 bit depth buffer 8 bit stencil buffer - }; - }; - - struct SOffscreenRendererEnvironment - { - QT3DSU32 m_Width; - QT3DSU32 m_Height; - NVRenderTextureFormats::Enum m_Format; - OffscreenRendererDepthValues::Enum m_Depth; - bool m_Stencil; - AAModeValues::Enum m_MSAAMode; - - SOffscreenRendererEnvironment() - : m_Width(0) - , m_Height(0) - , m_Format(NVRenderTextureFormats::Unknown) - , m_Depth(OffscreenRendererDepthValues::NoDepthBuffer) - , m_Stencil(false) - , m_MSAAMode(AAModeValues::NoAA) - { - } - - SOffscreenRendererEnvironment(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inFormat) - : m_Width(inWidth) - , m_Height(inHeight) - , m_Format(inFormat) - , m_Depth(OffscreenRendererDepthValues::Depth16) - , m_Stencil(false) - , m_MSAAMode(AAModeValues::NoAA) - { - } - - SOffscreenRendererEnvironment(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inFormat, - OffscreenRendererDepthValues::Enum inDepth, bool inStencil, - AAModeValues::Enum inAAMode) - : m_Width(inWidth) - , m_Height(inHeight) - , m_Format(inFormat) - , m_Depth(inDepth) - , m_Stencil(inStencil) - , m_MSAAMode(inAAMode) - { - } - - SOffscreenRendererEnvironment(const SOffscreenRendererEnvironment &inOther) - : m_Width(inOther.m_Width) - , m_Height(inOther.m_Height) - , m_Format(inOther.m_Format) - , m_Depth(inOther.m_Depth) - , m_Stencil(inOther.m_Stencil) - , m_MSAAMode(inOther.m_MSAAMode) - { - } - }; - - struct SOffscreenRenderFlags - { - bool m_HasTransparency; - bool m_HasChangedSinceLastFrame; - SOffscreenRenderFlags() - : m_HasTransparency(false) - , m_HasChangedSinceLastFrame(false) - { - } - - SOffscreenRenderFlags(bool transparency, bool hasChanged) - : m_HasTransparency(transparency) - , m_HasChangedSinceLastFrame(hasChanged) - { - } - }; - - typedef void *SRenderInstanceId; - - class IOffscreenRenderer : public NVRefCounted - { - public: - class IOffscreenRendererCallback - { - public: - virtual void onOffscreenRendererInitialized(const QString &id) = 0; - virtual void onOffscreenRendererFrame(const QString &id) = 0; - protected: - virtual ~IOffscreenRendererCallback() {} - }; - - protected: - virtual ~IOffscreenRenderer() {} - public: - virtual void addCallback(IOffscreenRendererCallback *cb) = 0; - // Arbitrary const char* returned to indicate the type of this renderer - // Can be overloaded to form the basis of an RTTI type system. - // Not currently used by the rendering system. - virtual CRegisteredString GetOffscreenRendererType() = 0; - virtual SOffscreenRendererEnvironment - GetDesiredEnvironment(QT3DSVec2 inPresentationScaleFactor) = 0; - // Returns true of this object needs to be rendered, false if this object is not dirty - virtual SOffscreenRenderFlags - NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, - QT3DSVec2 inPresentationScaleFactor, - const SRenderInstanceId instanceId) = 0; - // Returns true if the rendered result image has transparency, or false - // if it should be treated as a completely opaque image. - // It is the IOffscreenRenderer's job to clear any buffers (color, depth, stencil) that it - // needs to. It should not assume that it's buffers are clear; - // Sometimes we scale the width and height of the main presentation in order to fit a - // window. - // If we do so, the scale factor tells the subpresentation renderer how much the system has - // scaled. - virtual void Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, - SScene::RenderClearCommand inColorBufferNeedsClear, - const SRenderInstanceId instanceId) = 0; - virtual void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, - SScene::RenderClearCommand inColorBufferNeedsClear, - QT3DSVec3 inclearColor, - const SRenderInstanceId instanceId) = 0; - - // Implementors should implement one of the two interfaces below. - - // If this renderer supports picking that can return graph objects - // then return an interface here. - virtual IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId instanceId) = 0; - - // If you *don't* support the GraphObjectPickIterator interface, then you should implement - // this interface - // The system will just ask you to pick. - // If you return true, then we will assume that you swallowed the pick and will continue no - // further. - // else we will assume you did not and will continue the picking algorithm. - virtual bool Pick(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, - const SRenderInstanceId instanceId) = 0; - }; - - struct SOffscreenRenderResult - { - NVScopedRefCounted m_Renderer; - NVRenderTexture2D *m_Texture; - bool m_HasTransparency; - bool m_HasChangedSinceLastFrame; - - SOffscreenRenderResult(IOffscreenRenderer &inRenderer, NVRenderTexture2D &inTexture, - bool inTrans, bool inDirty) - : m_Renderer(&inRenderer) - , m_Texture(&inTexture) - , m_HasTransparency(inTrans) - , m_HasChangedSinceLastFrame(inDirty) - { - } - SOffscreenRenderResult() - : m_Renderer(NULL) - , m_Texture(NULL) - , m_HasTransparency(false) - , m_HasChangedSinceLastFrame(false) - { - } - }; - - struct SOffscreenRendererKey; - - /** - * The offscreen render manager attempts to satisfy requests for a given image under a given - *key. - * Renderers are throttled such that they render at most once per frame and potentially less - *than - * that if they don't require a new render. - */ - class IOffscreenRenderManager : public NVRefCounted - { - protected: - virtual ~IOffscreenRenderManager() {} - public: - // returns true if the renderer has not been registered. - // No return value means there was an error registering this id. - virtual Option MaybeRegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, - IOffscreenRenderer &inRenderer) = 0; - virtual void RegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, - IOffscreenRenderer &inRenderer) = 0; - virtual bool HasOffscreenRenderer(const SOffscreenRendererKey &inKey) = 0; - virtual IOffscreenRenderer *GetOffscreenRenderer(const SOffscreenRendererKey &inKey) = 0; - virtual void ReleaseOffscreenRenderer(const SOffscreenRendererKey &inKey) = 0; - - // This doesn't trigger rendering right away. A node is added to the render graph that - // points to this item. - // Thus rendering is deffered until the graph is run but we promise to render to this - // resource. - virtual SOffscreenRenderResult GetRenderedItem(const SOffscreenRendererKey &inKey) = 0; - // Called by the UICRenderContext, clients don't need to call this. - virtual void BeginFrame() = 0; - virtual void EndFrame() = 0; - - static IOffscreenRenderManager & - CreateOffscreenRenderManager(NVAllocatorCallback &inCallback, IStringTable &inStringTable, - IResourceManager &inManager, IQt3DSRenderContext &inContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h deleted file mode 100644 index 86f20a78..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_OLD_N_BUSTED_RENDER_PLUGIN_H -#define QT3DS_OLD_N_BUSTED_RENDER_PLUGIN_H - -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSRenderContextCore.h" -#include "foundation/Qt3DSVec4.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "Qt3DSPluginDLL.h" - -namespace qt3ds { -namespace render { - - class COldNBustedPluginRenderer; - - class COldNBustedPluginRenderer : public IOffscreenRenderer - { - public: - IQt3DSRenderContext &m_RenderContext; - long m_DLLHandle; - volatile QT3DSI32 mRefCount; - SOffscreenRendererEnvironment m_LastRenderedEnvironment; - CRegisteredString m_OffscreenRendererType; - - PROC_GetDesiredTextureSize m_GetTextureSizeProc; - PROC_Render m_RenderProc; - - COldNBustedPluginRenderer(IQt3DSRenderContext &inRenderContext, long inDLLHandle); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) - - SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresScale) override; - virtual SOffscreenRenderFlags - NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, QT3DSVec2 inPresScale, - const SRenderInstanceId instanceId) override; - void Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext & /*inRenderContext*/, - QT3DSVec2 inPresScale, SScene::RenderClearCommand inClearBuffer, - const SRenderInstanceId instanceId) override; - void RenderWithClear(const SOffscreenRendererEnvironment &/*inEnvironment*/, - NVRenderContext &/*inRenderContext*/, - QT3DSVec2 /*inPresentationScaleFactor*/, - SScene::RenderClearCommand /*inColorBufferNeedsClear*/, - QT3DSVec3 /*inclearColor*/, - const SRenderInstanceId /*instanceId*/) override {} - IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId instanceId) override - { - Q_UNUSED(instanceId); - return NULL; - } - bool Pick(const QT3DSVec2 & /*inMouseCoords*/, const QT3DSVec2 & /*inViewportDimensions*/, - const SRenderInstanceId instanceId) override - { - Q_UNUSED(instanceId); - return false; - } - void addCallback(IOffscreenRendererCallback *cb) override - { - - } - // Used for RTTI purposes so we can safely static-cast an offscreen renderer to a - // CPluginRenderer - static const char *GetRendererName() { return "Plugin"; } - CRegisteredString GetOffscreenRendererType() override { return m_OffscreenRendererType; } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRender.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRender.h deleted file mode 100644 index 44729682..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRender.h +++ /dev/null @@ -1,254 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_H -#define QT3DS_RENDER_H - -namespace qt3ds { -class NVAllocatorCallback; -class NVFoundationBase; -namespace foundation { - class CRegisteredString; - class IStringTable; - class CStrTableOrDataRef; - struct SStrRemapMap; - struct SWriteBuffer; - struct SDataReader; - struct SPtrOffsetMap; - class IPerfTimer; -} -namespace intrinsics { -} -namespace render { - class NVRenderTexture2D; - class NVRenderTexture2DArray; - class NVRenderTextureCube; - class NVRenderImage2D; - class NVRenderFrameBuffer; - class NVRenderRenderBuffer; - class NVRenderVertexBuffer; - class NVRenderIndexBuffer; - class NVRenderDrawIndirectBuffer; - class NVRenderInputAssembler; - class NVRenderAttribLayout; - class NVRenderDepthStencilState; - class NVRenderContext; - class NVRenderConstantBuffer; - class NVRenderShaderProgram; - class NVRenderShaderConstantBase; - struct NVRenderDrawMode; - struct NVRenderWinding; - struct NVRenderSrcBlendFunc; - struct NVRenderBlendEquation; - struct NVRenderState; - struct NVRenderTextureCoordOp; - struct NVRenderTextureMagnifyingOp; - struct NVRenderDstBlendFunc; - struct NVRenderContextValues; - struct NVRenderClearValues; - struct NVRenderRect; - struct NVRenderRectF; - struct NVRenderRenderBufferFormats; - struct NVRenderTextureFormats; - struct NVRenderTextureSwizzleMode; - struct NVRenderFrameBufferAttachments; - struct NVRenderRect; - struct NVRenderTextureCubeFaces; - struct STextureDetails; - struct NVRenderShaderDataTypes; - class NVRenderTextureOrRenderBuffer; - struct NVRenderTextureMinifyingOp; - struct NVReadFaces; - struct NVRenderVertexBufferEntry; - struct NVRenderPtrPtrMap; - class NVRenderComputeShader; - class NVRenderAttribLayout; - struct NVRenderBufferAccessTypeValues; - struct NVRenderImageAccessType; - struct NVRenderBufferBindValues; - struct DrawArraysIndirectCommand; - struct NVRenderShaderTypeValue; - class NVRenderPathRender; - class NVRenderPathSpecification; - class NVRenderPathFontSpecification; - class NVRenderPathFontItem; - struct NVRenderTextureTypeValue; - class NVRenderProgramPipeline; -} -class NVPlane; -} - -namespace eastl { -} - -namespace qt3ds { - -namespace render { - using namespace qt3ds; - using namespace qt3ds::foundation; - using namespace qt3ds::intrinsics; - using qt3ds::render::NVRenderTexture2D; - using qt3ds::render::NVRenderTexture2DArray; - using qt3ds::render::NVRenderTextureCube; - using qt3ds::render::NVRenderImage2D; - using qt3ds::render::NVRenderFrameBuffer; - using qt3ds::render::NVRenderRenderBuffer; - using qt3ds::render::NVRenderVertexBuffer; - using qt3ds::render::NVRenderIndexBuffer; - using qt3ds::render::NVRenderDrawIndirectBuffer; - using qt3ds::render::NVRenderInputAssembler; - using qt3ds::render::NVRenderAttribLayout; - using qt3ds::render::NVRenderDepthStencilState; - using qt3ds::render::NVRenderContext; - using qt3ds::render::NVRenderConstantBuffer; - using qt3ds::render::NVRenderShaderProgram; - using qt3ds::render::NVRenderShaderConstantBase; - using qt3ds::render::NVRenderDrawMode; - using qt3ds::render::NVRenderWinding; - using qt3ds::foundation::CRegisteredString; - using qt3ds::foundation::IStringTable; - using qt3ds::render::NVRenderSrcBlendFunc; - using qt3ds::render::NVRenderBlendEquation; - using qt3ds::render::NVRenderState; - using qt3ds::foundation::IStringTable; - using qt3ds::foundation::CRegisteredString; - using qt3ds::render::NVRenderTextureCoordOp; - using qt3ds::render::NVRenderDstBlendFunc; - using qt3ds::render::NVRenderRect; - using qt3ds::render::NVRenderRectF; - using qt3ds::render::NVRenderRenderBufferFormats; - using qt3ds::render::NVRenderTextureFormats; - using qt3ds::render::NVRenderTextureSwizzleMode; - using qt3ds::render::NVRenderFrameBufferAttachments; - using qt3ds::render::NVRenderRect; - using qt3ds::render::NVRenderContextValues; - using qt3ds::render::NVRenderClearValues; - using qt3ds::render::STextureDetails; - using qt3ds::render::NVRenderShaderDataTypes; - using qt3ds::render::NVRenderTextureMagnifyingOp; - using qt3ds::render::NVRenderTextureOrRenderBuffer; - using qt3ds::render::NVRenderTextureMinifyingOp; - using qt3ds::render::NVReadFaces; - using qt3ds::render::NVRenderTextureCubeFaces; - using qt3ds::foundation::SStrRemapMap; - using qt3ds::foundation::SWriteBuffer; - using qt3ds::foundation::SDataReader; - using qt3ds::render::NVRenderPtrPtrMap; - using qt3ds::foundation::CStrTableOrDataRef; - using qt3ds::foundation::SPtrOffsetMap; - using qt3ds::foundation::IPerfTimer; - using qt3ds::render::NVRenderVertexBufferEntry; - using qt3ds::render::NVRenderComputeShader; - using qt3ds::render::NVRenderAttribLayout; - using qt3ds::render::NVRenderBufferAccessTypeValues; - using qt3ds::render::NVRenderImageAccessType; - using qt3ds::render::NVRenderBufferBindValues; - using qt3ds::render::DrawArraysIndirectCommand; - using qt3ds::render::NVRenderShaderTypeValue; - using qt3ds::render::NVRenderPathRender; - using qt3ds::render::NVRenderPathSpecification; - using qt3ds::render::NVRenderPathFontSpecification; - using qt3ds::render::NVRenderPathFontItem; - using qt3ds::render::NVRenderTextureTypeValue; - using qt3ds::render::NVRenderProgramPipeline; - - class IQt3DSRenderContextCore; - class IQt3DSRenderContext; - class IQt3DSRenderer; - class IBufferManager; - struct SRenderMesh; - class IRenderableObject; - class IQt3DSRenderer; - class IBufferManager; - class IResourceManager; - class IOffscreenRenderManager; - struct SNode; - struct SGraphObject; - class ITextRenderer; - class ITextRendererCore; - class IInputStreamFactory; - class IRefCountedInputStream; - class IEffectSystem; - class IEffectSystemCore; - class CRenderString; - class IShaderCache; - class IQt3DSRenderNodeFilter; - class IRenderWidget; - class IRenderWidgetContext; - struct SShaderVertexCodeGenerator; - struct SShaderFragmentCodeGenerator; - class IThreadPool; - struct SRenderMesh; - struct SLoadedTexture; - class IImageBatchLoader; - class ITextTextureCache; - class ITextTextureAtlas; - class IRenderPluginInstance; - class IRenderPluginClass; - class IRenderPluginManager; - class IRenderPluginManagerCore; - struct SRenderPlugin; - class IDynamicObjectSystemCore; - class IDynamicObjectSystem; - class IDynamicObjectClass; - struct SRenderSubset; - struct SModel; - namespace dynamic { - struct SPropertyDefinition; - } - struct SLight; - struct SCamera; - struct SCustomMaterial; - class ICustomMaterialSystem; - class ICustomMaterialSystemCore; - struct SLayer; - struct SReferencedMaterial; - struct SPGGraphObject; - class IPixelGraphicsRenderer; - class IBufferLoader; - struct SEffect; - class IRenderList; - class IRenderTask; - class CResourceTexture2D; - class IPathManagerCore; - class IPathManager; - struct SPath; - struct SPathSubPath; - class IShaderProgramGenerator; - class IShaderStageGenerator; - class IDefaultMaterialShaderGenerator; - class ICustomMaterialShaderGenerator; - struct SRenderableImage; - class Qt3DSShadowMap; - struct SLightmaps; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderClippingFrustum.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderClippingFrustum.h deleted file mode 100644 index b788ad24..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderClippingFrustum.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CLIPPING_PLANE_H -#define QT3DS_RENDER_CLIPPING_PLANE_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSPlane.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSBounds3.h" - -namespace qt3ds { -namespace render { - - struct BoxEdgeFlagValues - { - enum Enum { - xMax = 1, - yMax = 1 << 1, - zMax = 1 << 2, - }; - }; - - typedef NVFlags TRenderBoxEdge; - - // For an intesection test, we only need two points of the bounding box. - // There will be a point nearest to the plane, and a point furthest from the plane. - // We can derive these points from the plane normal equation. - struct SPlaneBoxEdge - { - TRenderBoxEdge lowerEdge; - TRenderBoxEdge upperEdge; - }; - - struct SClipPlane - { - QT3DSVec3 normal; - QT3DSF32 d; - SPlaneBoxEdge mEdges; - - // For intersection tests, we only need to know if the numerator is greater than, equal to, - // or less than zero. - inline QT3DSF32 distance(const QT3DSVec3 &pt) const { return normal.dot(pt) + d; } - - // Only works if p0 is above the line and p1 is below the plane. - inline QT3DSVec3 intersectWithLine(const QT3DSVec3 &p0, const QT3DSVec3 &p1) const - { - QT3DSVec3 dir = p1 - p0; - QT3DSVec3 pointOnPlane = normal * (-d); -#ifdef _DEBUG - QT3DSF32 distanceOfPoint = distance(pointOnPlane); - QT3DS_ASSERT(NVAbs(distanceOfPoint) < 0.0001f); -#endif - QT3DSF32 numerator = (pointOnPlane - p0).dot(normal); - QT3DSF32 denominator = dir.dot(normal); - - QT3DS_ASSERT(NVAbs(denominator) > .0001f); - QT3DSF32 t = (numerator / denominator); - QT3DSVec3 retval = p0 + dir * t; -#ifdef _DEBUG - QT3DSF32 retvalDistance = distance(retval); - QT3DS_ASSERT(NVAbs(retvalDistance) < .0001f); -#endif - return retval; - } - - static inline QT3DSVec3 corner(const NVBounds3 &bounds, TRenderBoxEdge edge) - { - return QT3DSVec3((edge & BoxEdgeFlagValues::xMax) ? bounds.maximum[0] : bounds.minimum[0], - (edge & BoxEdgeFlagValues::yMax) ? bounds.maximum[1] : bounds.minimum[1], - (edge & BoxEdgeFlagValues::zMax) ? bounds.maximum[2] : bounds.minimum[2]); - } - - // dividing the distance numerator - - // I got this code from osg, but it is in graphics gems - // as well. - /** intersection test between plane and bounding sphere. - return 1 if the bs is completely above plane, - return 0 if the bs intersects the plane, - return -1 if the bs is completely below the plane.*/ - inline int intersect(const NVBounds3 &bounds) const - { - // if lowest point above plane than all above. - if (distance(corner(bounds, mEdges.lowerEdge)) > 0.0f) - return 1; - - // if highest point is below plane then all below. - if (distance(corner(bounds, mEdges.upperEdge)) < 0.0f) - return -1; - - // d_lower<=0.0f && d_upper>=0.0f - // therefore must be crossing plane. - return 0; - } - - inline void calculateBBoxEdges() - { - mEdges.upperEdge = TRenderBoxEdge( - static_cast((normal[0] >= 0.0f ? BoxEdgeFlagValues::xMax : 0) - | (normal[1] >= 0.0f ? BoxEdgeFlagValues::yMax : 0) - | (normal[2] >= 0.0f ? BoxEdgeFlagValues::zMax : 0))); - - mEdges.lowerEdge = TRenderBoxEdge((~((QT3DSU8)mEdges.upperEdge)) & 7); - } - }; - - struct SClippingFrustum - { - SClipPlane mPlanes[6]; - - SClippingFrustum() {} - - SClippingFrustum(const QT3DSMat44 &modelviewprojection, SClipPlane nearPlane); - - bool intersectsWith(const NVBounds3 &bounds) const - { - for (QT3DSU32 idx = 0; idx < 6; ++idx) - if (mPlanes[idx].intersect(bounds) < 0) - return false; - return true; - } - - bool intersectsWith(const QT3DSVec3 &point, QT3DSF32 radius = 0.0f) const - { - for (QT3DSU32 idx = 0; idx < 6; ++idx) - if (mPlanes[idx].distance(point) < radius) - return false; - return true; - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderContextCore.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderContextCore.h deleted file mode 100644 index be1498b8..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderContextCore.h +++ /dev/null @@ -1,217 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CONTEXT_CORE_H -#define QT3DS_RENDER_CONTEXT_CORE_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderPresentation.h" - -#include -#include - -namespace qt3ds { -namespace render { - struct ScaleModes - { - enum Enum { - ExactSize = 0, // Ensure the viewport is exactly same size as application - ScaleToFit = 1, // Resize viewport keeping aspect ratio - ScaleToFill = 2, // Resize viewport to entire window - FitSelected = 3, // Resize presentation to fit into viewport - }; - }; - - // Part of render context that does not require the render system. - class IQt3DSRenderContextCore : public NVRefCounted - { - public: - virtual IStringTable &GetStringTable() = 0; - virtual NVFoundationBase &GetFoundation() = 0; - virtual NVAllocatorCallback &GetAllocator() = 0; - virtual IInputStreamFactory &GetInputStreamFactory() = 0; - virtual IThreadPool &GetThreadPool() = 0; - virtual IDynamicObjectSystemCore &GetDynamicObjectSystemCore() = 0; - virtual ICustomMaterialSystemCore &GetMaterialSystemCore() = 0; - virtual IEffectSystemCore &GetEffectSystemCore() = 0; - virtual IPerfTimer &GetPerfTimer() = 0; - virtual IBufferLoader &GetBufferLoader() = 0; - virtual IRenderPluginManagerCore &GetRenderPluginCore() = 0; - virtual IPathManagerCore &GetPathManagerCore() = 0; - // Text renderers may be provided by clients at runtime. - virtual void SetTextRendererCore(ITextRendererCore &inRenderer) = 0; - virtual ITextRendererCore *GetTextRendererCore() = 0; - // this is our default 2D text onscreen renderer - virtual void SetOnscreenTextRendererCore(ITextRendererCore &inRenderer) = 0; - virtual ITextRendererCore *GetOnscreenTextRendererCore() = 0; - // The render context maintains a reference to this object. - virtual IQt3DSRenderContext &CreateRenderContext(NVRenderContext &inContext, - const char8_t *inPrimitivesDirectory) = 0; - - static IQt3DSRenderContextCore &Create(NVFoundationBase &fnd, IStringTable &strt); - }; - - class IQt3DSRenderContext : public NVRefCounted - { - protected: - virtual ~IQt3DSRenderContext() {} - public: - virtual IStringTable &GetStringTable() = 0; - virtual NVFoundationBase &GetFoundation() = 0; - virtual NVAllocatorCallback &GetAllocator() = 0; - virtual IQt3DSRenderer &GetRenderer() = 0; - virtual IRenderWidgetContext &GetRenderWidgetContext() = 0; - virtual IBufferManager &GetBufferManager() = 0; - virtual IResourceManager &GetResourceManager() = 0; - virtual NVRenderContext &GetRenderContext() = 0; - virtual IOffscreenRenderManager &GetOffscreenRenderManager() = 0; - virtual IInputStreamFactory &GetInputStreamFactory() = 0; - virtual IEffectSystem &GetEffectSystem() = 0; - virtual IShaderCache &GetShaderCache() = 0; - virtual IThreadPool &GetThreadPool() = 0; - virtual IImageBatchLoader &GetImageBatchLoader() = 0; - virtual IRenderPluginManager &GetRenderPluginManager() = 0; - virtual IDynamicObjectSystem &GetDynamicObjectSystem() = 0; - virtual ICustomMaterialSystem &GetCustomMaterialSystem() = 0; - virtual IPixelGraphicsRenderer &GetPixelGraphicsRenderer() = 0; - virtual IPerfTimer &GetPerfTimer() = 0; - virtual ITextTextureCache *GetTextureCache() = 0; - virtual ITextRenderer *GetTextRenderer() = 0; - virtual IRenderList &GetRenderList() = 0; - virtual IPathManager &GetPathManager() = 0; - virtual IShaderProgramGenerator &GetShaderProgramGenerator() = 0; - virtual IDefaultMaterialShaderGenerator &GetDefaultMaterialShaderGenerator() = 0; - virtual ICustomMaterialShaderGenerator &GetCustomMaterialShaderGenerator() = 0; - // The memory used for the per frame allocator is released as the first step in BeginFrame. - // This is useful for short lived objects and datastructures. - virtual NVAllocatorCallback &GetPerFrameAllocator() = 0; - // Get the number of times EndFrame has been called - virtual QT3DSU32 GetFrameCount() = 0; - - // Get fps - virtual QPair GetFPS() = 0; - // Set fps by higher level, etc application - virtual void SetFPS(QPair inFPS) = 0; - - // Currently there are a few things that need to work differently - // in authoring mode vs. runtime. The particle effects, for instance - // need to be framerate-independent at runtime but framerate-dependent during - // authoring time assuming virtual 16 ms frames. - // Defaults to falst. - virtual bool IsAuthoringMode() = 0; - virtual void SetAuthoringMode(bool inMode) = 0; - - // This one is setup by the runtime binding - virtual ITextRenderer *GetOnscreenTextRenderer() = 0; - virtual ITextTextureAtlas *GetTextureAtlas() = 0; - - // Sub presentations change the rendering somewhat. - virtual bool IsInSubPresentation() = 0; - virtual void SetInSubPresentation(bool inValue) = 0; - virtual void SetSceneColor(Option inSceneColor) = 0; - virtual void SetMatteColor(Option inMatteColor) = 0; - - // Render screen aligned 2D text at x,y - virtual void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, - const char *text) = 0; - // render Gpu profiler values - virtual void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, - qt3ds::foundation::Option inColor) = 0; - - // The reason you can set both window dimensions and an overall viewport is that the mouse - // needs to be inverted - // which requires the window height, and then the rest of the system really requires the - // viewport. - virtual void SetWindowDimensions(const QSize &inWindowDimensions) = 0; - virtual QSize GetWindowDimensions() = 0; - - // In addition to the window dimensions which really have to be set, you can optionally - // set the viewport which will force the entire viewer to render specifically to this - // viewport. - virtual void SetViewport(Option inViewport) = 0; - virtual Option GetViewport() const = 0; - virtual NVRenderRect GetContextViewport() const = 0; - // Only valid between calls to Begin,End. - virtual NVRenderRect GetPresentationViewport() const = 0; - - virtual void SetScaleMode(ScaleModes::Enum inMode) = 0; - virtual ScaleModes::Enum GetScaleMode() = 0; - - virtual void SetWireframeMode(bool inEnable) = 0; - virtual bool GetWireframeMode() = 0; - - // Return the viewport the system is using to render data to. This gives the the dimensions - // of the rendered system. It is dependent on but not equal to the viewport. - virtual NVRenderRectF GetDisplayViewport() const = 0; - - // Layers require the current presentation dimensions in order to render. - virtual void - SetPresentationDimensions(const QSize &inPresentationDimensions) = 0; - virtual QSize GetCurrentPresentationDimensions() const = 0; - - virtual void SetRenderRotation(RenderRotationValues::Enum inRotation) = 0; - virtual RenderRotationValues::Enum GetRenderRotation() const = 0; - - virtual QT3DSVec2 GetMousePickViewport() const = 0; - virtual QT3DSVec2 GetMousePickMouseCoords(const QT3DSVec2 &inMouseCoords) const = 0; - - // Valid during and just after prepare for render. - virtual QT3DSVec2 GetPresentationScaleFactor() const = 0; - - // Steps needed to render: - // 1. BeginFrame - sets up new target in render graph - // 2. Add everything you need to the render graph - // 3. RunRenderGraph - runs the graph, rendering things to main render target - // 4. Render any additional stuff to main render target on top of previously rendered - // information - // 5. EndFrame - - // Clients need to call this every frame in order for various subsystems to release - // temporary per-frame allocated objects. - // Also sets up the viewport according to SetViewportInfo - // and the topmost presentation dimensions. Expects there to be exactly one presentation - // dimension pushed at this point. - // This also starts a render target in the render graph. - virtual void BeginFrame() = 0; - - // This runs through the added tasks in reverse order. This is used to render dependencies - // before rendering to the main render target. - virtual void RunRenderTasks() = 0; - // Now you can render to the main render target if you want to render over the top - // of everything. - // Next call end frame. - virtual void EndFrame() = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialRenderContext.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialRenderContext.h deleted file mode 100644 index 5283660c..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialRenderContext.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_RENDER_CONTEXT_H -#define QT3DS_RENDER_CUSTOM_MATERIAL_RENDER_CONTEXT_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSMat44.h" -#include "foundation/Qt3DSMat33.h" -#include "Qt3DSRenderShaderKeys.h" - -namespace qt3ds { -namespace render { - - struct SLayerRenderData; - - struct SCustomMaterialRenderContext - { - // The lights and camera will not change per layer, - // so that information can be set once for all the shaders. - const SLayer &m_Layer; - const SLayerRenderData &m_LayerData; - NVDataRef m_Lights; - const SCamera &m_Camera; - - // Per-object information. - const SModel &m_Model; - const SRenderSubset &m_Subset; - const QT3DSMat44 &m_ModelViewProjection; - const QT3DSMat44 &m_ModelMatrix; ///< model to world transformation - const QT3DSMat33 &m_NormalMatrix; - const SCustomMaterial &m_Material; - const NVRenderTexture2D *m_DepthTexture; - const NVRenderTexture2D *m_AOTexture; - SShaderDefaultMaterialKey m_MaterialKey; - SRenderableImage *m_FirstImage; - QT3DSF32 m_Opacity; - - SCustomMaterialRenderContext( - const SLayer &layer, const SLayerRenderData &data, NVDataRef lights, - const SCamera &cam, const SModel &m, const SRenderSubset &subset, const QT3DSMat44 &mvp, - const QT3DSMat44 &world, const QT3DSMat33 &nm, const SCustomMaterial &material, - const NVRenderTexture2D *depthTex, const NVRenderTexture2D *aoTex, - SShaderDefaultMaterialKey inMaterialKey, SRenderableImage *inFirstImage = NULL, - QT3DSF32 opacity = 1.0) - : m_Layer(layer) - , m_LayerData(data) - , m_Lights(lights) - , m_Camera(cam) - , m_Model(m) - , m_Subset(subset) - , m_ModelViewProjection(mvp) - , m_ModelMatrix(world) - , m_NormalMatrix(nm) - , m_Material(material) - , m_DepthTexture(depthTex) - , m_AOTexture(aoTex) - , m_MaterialKey(inMaterialKey) - , m_FirstImage(inFirstImage) - , m_Opacity(opacity) - { - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialShaderGenerator.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialShaderGenerator.h deleted file mode 100644 index 44e2c064..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialShaderGenerator.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_SHADER_GENERATOR_H -#define QT3DS_RENDER_CUSTOM_MATERIAL_SHADER_GENERATOR_H -#include "Qt3DSRenderMaterialShaderGenerator.h" - -namespace qt3ds { -namespace render { - - class Qt3DSShadowMap; - - class ICustomMaterialShaderGenerator : public IMaterialShaderGenerator - { - public: - SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override = 0; - void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, - QT3DSU32 uvSet, SRenderableImage &image) override = 0; - - // inPipelineName needs to be unique else the shader cache will just return shaders from - // different pipelines. - NVRenderShaderProgram *GenerateShader( - const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, - IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, - NVDataRef inLights, SRenderableImage *inFirstImage, bool inHasTransparency, - const char8_t *inVertexPipelineName, const char8_t *inCustomMaterialName = "") override = 0; - - // Also sets the blend function on the render context. - virtual void - SetMaterialProperties(NVRenderShaderProgram &inProgram, const SGraphObject &inMaterial, - const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - SLayerGlobalRenderProperties inRenderProperties) override = 0; - - static ICustomMaterialShaderGenerator & - CreateCustomMaterialShaderGenerator(IQt3DSRenderContext &inRenderContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialSystem.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialSystem.h deleted file mode 100644 index 345e7675..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderCustomMaterialSystem.h +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_SYSTEM_H -#define QT3DS_RENDER_CUSTOM_MATERIAL_SYSTEM_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "../RendererImpl/Qt3DSVertexPipelineImpl.h" - -namespace qt3ds { -namespace render { - - namespace dynamic { - struct SCommand; // UICRenderEffectCommands.h - } - - struct SCustomMaterialRenderContext; - - class ICustomMaterialSystemCore : public NVRefCounted - { - public: - virtual bool IsMaterialRegistered(CRegisteredString inStr) = 0; - - virtual bool - RegisterMaterialClass(CRegisteredString inName, - NVConstDataRef inProperties) = 0; - - virtual NVConstDataRef - GetCustomMaterialProperties(CRegisteredString inCustomMaterialName) const = 0; - - virtual void SetCustomMaterialRefraction(CRegisteredString inName, - bool inHasRefraction) = 0; - virtual void SetCustomMaterialTransparency(CRegisteredString inName, - bool inHasTransparency) = 0; - virtual void SetCustomMaterialAlwaysDirty(CRegisteredString inName, - bool inIsAlwaysDirty) = 0; - virtual void SetCustomMaterialShaderKey(CRegisteredString inName, QT3DSU32 inShaderKey) = 0; - virtual void SetCustomMaterialLayerCount(CRegisteredString inName, QT3DSU32 inLayerCount) = 0; - // The custom material commands are the actual commands that run for a given material - // effect. The tell the system exactly - // explicitly things like bind this shader, bind this render target, apply this property, - // run this shader - // See UICRenderEffectCommands.h for the list of commands. - // These commands are copied into the effect. - virtual void SetCustomMaterialCommands(CRegisteredString inName, - NVConstDataRef inCommands) = 0; - - virtual void SetMaterialClassShader(CRegisteredString inName, const char8_t *inShaderType, - const char8_t *inShaderVersion, - const char8_t *inShaderData, bool inHasGeomShader, - bool inIsComputeShader) = 0; - - virtual SCustomMaterial * - CreateCustomMaterial(CRegisteredString inName, - NVAllocatorCallback &inSceneGraphAllocator) = 0; - - virtual void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inNames) = 0; - - virtual void SetPropertyTextureSettings(CRegisteredString inEffectName, - CRegisteredString inPropName, - CRegisteredString inPropPath, - NVRenderTextureTypeValue::Enum inTexType, - NVRenderTextureCoordOp::Enum inCoordOp, - NVRenderTextureMagnifyingOp::Enum inMagFilterOp, - NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0; - - virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, - const char8_t *inProjectDir) const = 0; - virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t *inProjectDir) = 0; - - virtual ICustomMaterialSystem &GetCustomMaterialSystem(IQt3DSRenderContext &inContext) = 0; - - static ICustomMaterialSystemCore & - CreateCustomMaterialSystemCore(IQt3DSRenderContextCore &inContext); - }; - // How to handle blend modes? - class ICustomMaterialSystem : public ICustomMaterialSystemCore - { - public: - // Returns true if the material is dirty and thus will produce a different render result - // than previously. This effects things like progressive AA. - virtual bool PrepareForRender(const SModel &inModel, const SRenderSubset &inSubset, - SCustomMaterial &inMaterial, bool inClearDirty) = 0; - - virtual bool RenderDepthPrepass(const QT3DSMat44 &inMVP, const SCustomMaterial &inMaterial, - const SRenderSubset &inSubset) = 0; - virtual void RenderSubset(SCustomMaterialRenderContext &inRenderContext, - TShaderFeatureSet inFeatureSet) = 0; - virtual void OnMaterialActivationChange(const SCustomMaterial &inMaterial, - bool inActive) = 0; - - // get shader name - virtual const char *GetShaderName(const SCustomMaterial &inMaterial) = 0; - // apply property values - virtual void ApplyShaderPropertyValues(const SCustomMaterial &inMaterial, - NVRenderShaderProgram &inProgram) = 0; - // Called by the uiccontext so this system can clear any per-frame render information. - virtual void EndFrame() = 0; - }; - - struct QT3DS_AUTOTEST_EXPORT SCustomMaterialVertexPipeline : public SVertexPipelineImpl - { - IQt3DSRenderContext *m_Context; - TessModeValues::Enum m_TessMode; - - SCustomMaterialVertexPipeline(IQt3DSRenderContext *inContext, TessModeValues::Enum inTessMode); - void InitializeTessControlShader(); - void InitializeTessEvaluationShader(); - void FinalizeTessControlShader(); - void FinalizeTessEvaluationShader(); - - // Responsible for beginning all vertex and fragment generation (void main() { etc). - virtual void BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override; - // The fragment shader expects a floating point constant, object_opacity to be defined - // post this method. - virtual void BeginFragmentGeneration() override; - // Output variables may be mangled in some circumstances so the shader generation - // system needs an abstraction mechanism around this. - virtual void AssignOutput(const char8_t *inVarName, const char8_t *inVarValue) override; - virtual void GenerateEnvMapReflection() override {} - virtual void GenerateViewVector() override {} - virtual void GenerateUVCoords(QT3DSU32 inUVSet) override; - virtual void GenerateWorldNormal() override; - virtual void GenerateObjectNormal() override; - virtual void GenerateVarTangentAndBinormal() override; - virtual void GenerateWorldPosition() override; - // responsible for closing all vertex and fragment generation - virtual void EndVertexGeneration() override; - virtual void EndFragmentGeneration() override; - virtual IShaderStageGenerator &ActiveStage() override; - virtual void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override; - virtual void DoGenerateUVCoords(QT3DSU32 inUVSet) override; - virtual void DoGenerateWorldNormal() override; - virtual void DoGenerateObjectNormal() override; - virtual void DoGenerateWorldPosition() override; - virtual void DoGenerateVarTangentAndBinormal() override; - virtual void DoGenerateVertexColor() override; - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDefaultMaterialShaderGenerator.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDefaultMaterialShaderGenerator.h deleted file mode 100644 index fc845b51..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDefaultMaterialShaderGenerator.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DEFAULT_MATERIAL_SHADER_GENERATOR_H -#define QT3DS_RENDER_DEFAULT_MATERIAL_SHADER_GENERATOR_H -#include "Qt3DSRenderMaterialShaderGenerator.h" -#include "Qt3DSRenderLightConstantProperties.h" - -namespace qt3ds { -namespace render { - - class Qt3DSShadowMap; - struct SShaderGeneratorGeneratedShader; - - class IDefaultMaterialVertexPipeline : public IShaderStageGenerator - { - protected: - virtual ~IDefaultMaterialVertexPipeline() {} - public: - // Responsible for beginning all vertex and fragment generation (void main() { etc). - virtual void BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) = 0; - // The fragment shader expects a floating point constant, object_opacity to be defined - // post this method. - virtual void BeginFragmentGeneration() = 0; - // Output variables may be mangled in some circumstances so the shader generation system - // needs an abstraction - // mechanism around this. - virtual void AssignOutput(const char8_t *inVarName, const char8_t *inVarValueExpr) = 0; - - /** - * @brief Generates UV coordinates in shader code - * - * @param[in] inUVSet index of UV data set - * - * @return no return - */ - virtual void GenerateUVCoords(QT3DSU32 inUVSet = 0) = 0; - - virtual void GenerateEnvMapReflection() = 0; - virtual void GenerateViewVector() = 0; - - // fragment shader expects varying vertex normal - // lighting in vertex pipeline expects world_normal - virtual void GenerateWorldNormal() = 0; // world_normal in both vert and frag shader - virtual void GenerateObjectNormal() = 0; // object_normal in both vert and frag shader - virtual void - GenerateWorldPosition() = 0; // model_world_position in both vert and frag shader - virtual void GenerateVarTangentAndBinormal() = 0; - virtual void GenerateVertexColor() = 0; - - virtual bool HasActiveWireframe() = 0; // varEdgeDistance is a valid entity - - // responsible for closing all vertex and fragment generation - virtual void EndVertexGeneration() = 0; - virtual void EndFragmentGeneration() = 0; - }; - - class IDefaultMaterialShaderGenerator : public IMaterialShaderGenerator - { - public: - virtual void AddDisplacementImageUniforms(IShaderStageGenerator &inGenerator, - QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) = 0; - SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override = 0; - void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, - QT3DSU32 uvSet, SRenderableImage &image) override = 0; - // Transforms attr_pos, attr_norm, and attr_uv0. - virtual void AddDisplacementMappingForDepthPass(IShaderStageGenerator &inShader) = 0; - - // inPipelineName needs to be unique else the shader cache will just return shaders from - // different pipelines. - NVRenderShaderProgram *GenerateShader( - const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, - IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, - NVDataRef inLights, SRenderableImage *inFirstImage, bool inHasTransparency, - const char8_t *inVertexPipelineName, const char8_t *inCustomMaterialName = "") override = 0; - - // Also sets the blend function on the render context. - virtual void - SetMaterialProperties(NVRenderShaderProgram &inProgram, const SGraphObject &inMaterial, - const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - SLayerGlobalRenderProperties inRenderProperties) override = 0; - - static IDefaultMaterialShaderGenerator & - CreateDefaultMaterialShaderGenerator(IQt3DSRenderContext &inRenderContext); - - SLightConstantProperties - *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystem.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystem.h deleted file mode 100644 index b149efc8..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystem.h +++ /dev/null @@ -1,286 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_H -#define QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSVec2.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderTessModeValues.h" -#include "Qt3DSRenderGraphObjectTypes.h" -#include "EASTL/utility.h" - -#include - -namespace qt3ds { -namespace render { - struct SDynamicObject; - - namespace dynamic { - - struct SCommand; - - struct SPropertyDeclaration - { - const char8_t *m_Name; - // The datatypes map directly to the obvious types *except* - // for NVRenderTexture2DPtr. This type will be interpreted as a - // CRegisteredString (they are the same binary size) - // and will be used to lookup the texture from the buffer manager. - NVRenderShaderDataTypes::Enum m_DataType; - - SPropertyDeclaration(const char8_t *inName, NVRenderShaderDataTypes::Enum inDtype) - : m_Name(inName) - , m_DataType(inDtype) - { - } - SPropertyDeclaration() - : m_Name("") - , m_DataType(NVRenderShaderDataTypes::Unknown) - { - } - }; - - struct SPropertyDefinition - { - CRegisteredString m_Name; - - //*not* relative to the presentation directory - CRegisteredString m_ImagePath; - // The datatypes map directly to the obvious types *except* - // for NVRenderTexture2DPtr. This type will be interpreted as a - // CRegisteredString and will be used to lookup the texture - // from the buffer manager. - NVRenderShaderDataTypes::Enum m_DataType; - // All offsets are relative to the beginning of the SEffect - // and are aligned to 4 byte boundaries. - QT3DSU32 m_Offset; - // Sizeof this datatype. - QT3DSU32 m_ByteSize; - NVConstDataRef m_EnumValueNames; - - NVRenderTextureTypeValue::Enum - m_TexUsageType; ///< texture usage type like diffuse, specular, ... - // Applies to both s,t - NVRenderTextureCoordOp::Enum m_CoordOp; - // Set mag Filter - NVRenderTextureMagnifyingOp::Enum m_MagFilterOp; - // Set min Filter - NVRenderTextureMinifyingOp::Enum m_MinFilterOp; - bool m_IsEnumProperty; - SPropertyDefinition() - : m_DataType(NVRenderShaderDataTypes::Unknown) - , m_Offset(0) - , m_ByteSize(0) - , m_TexUsageType(NVRenderTextureTypeValue::Unknown) - , m_CoordOp(NVRenderTextureCoordOp::ClampToEdge) - , m_MagFilterOp(NVRenderTextureMagnifyingOp::Linear) - , m_MinFilterOp(NVRenderTextureMinifyingOp::Linear) - , m_IsEnumProperty(false) - { - } - SPropertyDefinition(CRegisteredString inName, NVRenderShaderDataTypes::Enum inType, - QT3DSU32 inOffset, QT3DSU32 inByteSize) - : m_Name(inName) - , m_DataType(inType) - , m_Offset(inOffset) - , m_ByteSize(inByteSize) - , m_TexUsageType(NVRenderTextureTypeValue::Unknown) - , m_CoordOp(NVRenderTextureCoordOp::ClampToEdge) - , m_MagFilterOp(NVRenderTextureMagnifyingOp::Linear) - , m_MinFilterOp(NVRenderTextureMinifyingOp::Linear) - , m_IsEnumProperty(false) - { - } - }; - - struct SDynamicShaderProgramFlags : public SShaderCacheProgramFlags - { - TessModeValues::Enum m_TessMode; - bool m_WireframeMode; - - SDynamicShaderProgramFlags() - : m_TessMode(TessModeValues::NoTess) - , m_WireframeMode(false) - { - } - - SDynamicShaderProgramFlags(TessModeValues::Enum inTessMode, bool inWireframeMode) - : m_TessMode(inTessMode) - , m_WireframeMode(inWireframeMode) - { - } - - static const char *wireframeToString(bool inEnable) - { - if (inEnable) - return "wireframeMode:true"; - else - return "wireframeMode:false"; - } - }; - } - - class IDynamicObjectClass - { - protected: - virtual ~IDynamicObjectClass() {} - public: - virtual CRegisteredString GetId() const = 0; - virtual NVConstDataRef GetProperties() const = 0; - virtual QT3DSU32 GetPropertySectionByteSize() const = 0; - virtual const QT3DSU8 *GetDefaultValueBuffer() const = 0; - virtual QT3DSU32 GetBaseObjectSize() const = 0; - virtual GraphObjectTypes::Enum GraphObjectType() const = 0; - virtual const dynamic::SPropertyDefinition * - FindPropertyByName(CRegisteredString inName) const = 0; - virtual NVConstDataRef GetRenderCommands() const = 0; - virtual bool RequiresDepthTexture() const = 0; - virtual void SetRequiresDepthTexture(bool inRequires) = 0; - virtual bool RequiresCompilation() const = 0; - virtual void SetRequiresCompilation(bool inRequires) = 0; - virtual NVRenderTextureFormats::Enum GetOutputTextureFormat() const = 0; - }; - - class IDynamicObjectSystemCore : public NVRefCounted - { - protected: - virtual ~IDynamicObjectSystemCore() {} - public: - virtual bool IsRegistered(CRegisteredString inStr) = 0; - - virtual bool Register(CRegisteredString inName, - NVConstDataRef inProperties, - QT3DSU32 inBaseObjectSize, GraphObjectTypes::Enum inGraphObjectType) = 0; - - virtual bool Unregister(CRegisteredString inName) = 0; - - // Set the default value. THis is unnecessary if the default is zero as that is what it is - // assumed to be. - virtual void SetPropertyDefaultValue(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inDefaultData) = 0; - - virtual void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inNames) = 0; - - virtual NVConstDataRef - GetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName) const = 0; - - virtual NVConstDataRef - GetProperties(CRegisteredString inName) const = 0; - - virtual void SetPropertyTextureSettings(CRegisteredString inName, - CRegisteredString inPropName, - CRegisteredString inPropPath, - NVRenderTextureTypeValue::Enum inTexType, - NVRenderTextureCoordOp::Enum inCoordOp, - NVRenderTextureMagnifyingOp::Enum inMagFilterOp, - NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0; - - virtual IDynamicObjectClass *GetDynamicObjectClass(CRegisteredString inName) = 0; - - // The effect commands are the actual commands that run for a given effect. The tell the - // system exactly - // explicitly things like bind this shader, bind this render target, apply this property, - // run this shader - // See UICRenderEffectCommands.h for the list of commands. - // These commands are copied into the effect. - virtual void SetRenderCommands(CRegisteredString inClassName, - NVConstDataRef inCommands) = 0; - virtual NVConstDataRef - GetRenderCommands(CRegisteredString inClassName) const = 0; - - virtual SDynamicObject *CreateInstance(CRegisteredString inClassName, - NVAllocatorCallback &inSceneGraphAllocator) = 0; - - // scan shader for #includes and insert any found" - virtual void InsertShaderHeaderInformation(CRenderString &inShader, - const char *inLogPath) = 0; - - // Set the shader data for a given path. Used when a path doesn't correspond to a file but - // the data has been - // auto-generated. The system will look for data under this path key during the BindShader - // effect command. - virtual void SetShaderData(CRegisteredString inPath, const char8_t *inData, - const char8_t *inShaderType = NULL, - const char8_t *inShaderVersion = NULL, - bool inHasGeomShader = false, - bool inIsComputeShader = false) = 0; - - // Overall save functions for saving the class information out to the binary file. - virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, - const char8_t *inProjectDir) const = 0; - virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t *inProjectDir) = 0; - - virtual IDynamicObjectSystem &CreateDynamicSystem(IQt3DSRenderContext &rc) = 0; - - static IDynamicObjectSystemCore &CreateDynamicSystemCore(IQt3DSRenderContextCore &rc); - }; - - typedef eastl::pair, - dynamic::SDynamicShaderProgramFlags> - TShaderAndFlags; - - class IDynamicObjectSystem : public IDynamicObjectSystemCore - { - protected: - virtual ~IDynamicObjectSystem() {} - - public: - virtual TShaderAndFlags - GetShaderProgram(CRegisteredString inPath, CRegisteredString inProgramMacro, - TShaderFeatureSet inFeatureSet, - const dynamic::SDynamicShaderProgramFlags &inFlags, - bool inForceCompilation = false) = 0; - - virtual const char8_t *GetShaderSource(CRegisteredString inPath, CRenderString &source) = 0; - - // Will return null in the case where a custom prepass shader isn't needed for this object - // If no geom shader, then no depth prepass shader. - virtual TShaderAndFlags GetDepthPrepassShader(CRegisteredString inPath, - CRegisteredString inProgramMacro, - TShaderFeatureSet inFeatureSet) = 0; - - virtual void setShaderCodeLibraryPlatformDirectory(const QString &directory) = 0; - virtual QString shaderCodeLibraryPlatformDirectory() = 0; - - static QString GetShaderCodeLibraryDirectory() { return QStringLiteral("res/effectlib"); } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemCommands.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemCommands.h deleted file mode 100644 index 857dfa97..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemCommands.h +++ /dev/null @@ -1,622 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_EFFECT_SYSTEM_COMMANDS_H -#define QT3DS_RENDER_EFFECT_SYSTEM_COMMANDS_H -#include "Qt3DSRender.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSFlags.h" - -namespace qt3ds { -namespace render { - namespace dynamic { - using qt3ds::render::NVRenderBufferBarrierFlags; - - struct CommandTypes - { - enum Enum { - Unknown = 0, - AllocateBuffer, - BindTarget, - BindBuffer, - BindShader, - ApplyInstanceValue, - ApplyBufferValue, - // Apply the depth buffer as an input texture. - ApplyDepthValue, - Render, // Render to current FBO - ApplyBlending, - ApplyRenderState, // apply a render state - ApplyBlitFramebuffer, - ApplyValue, - DepthStencil, - AllocateImage, - ApplyImageValue, - AllocateDataBuffer, - ApplyDataBufferValue, - }; - }; - -#define QT3DS_RENDER_EFFECTS_ITERATE_COMMAND_TYPES \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(AllocateBuffer) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(BindTarget) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(BindBuffer) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(BindShader) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyInstanceValue) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyBufferValue) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyDepthValue) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(Render) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyBlending) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyRenderState) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyBlitFramebuffer) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyValue) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(DepthStencil) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(AllocateImage) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyImageValue) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(AllocateDataBuffer) \ - QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyDataBufferValue) - - // All commands need at least two constructors. One for when they are created that should - // setup all their member variables and one for when we are copying commands from an outside - // entity into the effect system. We have to re-register strings in that case because we - // can't assume the outside entity was using the same string table we are... - struct SCommand - { - CommandTypes::Enum m_Type; - SCommand(CommandTypes::Enum inType) - : m_Type(inType) - { - } - SCommand() - : m_Type(CommandTypes::Unknown) - { - } - // Implemented in UICRenderEffectSystem.cpp - static QT3DSU32 GetSizeofCommand(const SCommand &inCommand); - static void CopyConstructCommand(QT3DSU8 *inDataBuffer, const SCommand &inCommand, - IStringTable &inStrTable); - }; - - struct AllocateBufferFlagValues - { - enum Enum { - SceneLifetime = 1, - }; - }; - - struct SAllocateBufferFlags : public NVFlags - { - SAllocateBufferFlags(QT3DSU32 inValues) - : NVFlags(inValues) - { - } - SAllocateBufferFlags() {} - void SetSceneLifetime(bool inValue) - { - clearOrSet(inValue, AllocateBufferFlagValues::SceneLifetime); - } - // If isSceneLifetime is unset the buffer is assumed to be frame lifetime and will be - // released after this render operation. - bool IsSceneLifetime() const - { - return this->operator&(AllocateBufferFlagValues::SceneLifetime); - } - }; - - struct SAllocateBuffer : public SCommand - { - CRegisteredString m_Name; - NVRenderTextureFormats::Enum m_Format; - NVRenderTextureMagnifyingOp::Enum m_FilterOp; - NVRenderTextureCoordOp::Enum m_TexCoordOp; - QT3DSF32 m_SizeMultiplier; - SAllocateBufferFlags m_BufferFlags; - SAllocateBuffer() - : SCommand(CommandTypes::AllocateBuffer) - , m_Format(NVRenderTextureFormats::RGBA8) - , m_FilterOp(NVRenderTextureMagnifyingOp::Linear) - , m_TexCoordOp(NVRenderTextureCoordOp::ClampToEdge) - , m_SizeMultiplier(1.0f) - { - } - SAllocateBuffer(CRegisteredString inName, NVRenderTextureFormats::Enum inFormat, - NVRenderTextureMagnifyingOp::Enum inFilterOp, - NVRenderTextureCoordOp::Enum inCoordOp, QT3DSF32 inMultiplier, - SAllocateBufferFlags inFlags) - : SCommand(CommandTypes::AllocateBuffer) - , m_Name(inName) - , m_Format(inFormat) - , m_FilterOp(inFilterOp) - , m_TexCoordOp(inCoordOp) - , m_SizeMultiplier(inMultiplier) - , m_BufferFlags(inFlags) - { - } - SAllocateBuffer(const SAllocateBuffer &inOther, IStringTable &inStrTable) - : SCommand(CommandTypes::AllocateBuffer) - , m_Name(inStrTable.RegisterStr(inOther.m_Name)) - , m_Format(inOther.m_Format) - , m_FilterOp(inOther.m_FilterOp) - , m_TexCoordOp(inOther.m_TexCoordOp) - , m_SizeMultiplier(inOther.m_SizeMultiplier) - , m_BufferFlags(inOther.m_BufferFlags) - { - } - }; - - struct SAllocateImage : public SAllocateBuffer - { - NVRenderImageAccessType::Enum m_Access; - - SAllocateImage() - : SAllocateBuffer() - , m_Access(NVRenderImageAccessType::ReadWrite) - { - m_Type = CommandTypes::AllocateImage; - } - SAllocateImage(CRegisteredString inName, NVRenderTextureFormats::Enum inFormat, - NVRenderTextureMagnifyingOp::Enum inFilterOp, - NVRenderTextureCoordOp::Enum inCoordOp, QT3DSF32 inMultiplier, - SAllocateBufferFlags inFlags, NVRenderImageAccessType::Enum inAccess) - : SAllocateBuffer(inName, inFormat, inFilterOp, inCoordOp, inMultiplier, inFlags) - , m_Access(inAccess) - { - m_Type = CommandTypes::AllocateImage; - } - - SAllocateImage(const SAllocateImage &inOther, IStringTable &inStrTable) - : SAllocateBuffer(inStrTable.RegisterStr(inOther.m_Name), inOther.m_Format, - inOther.m_FilterOp, inOther.m_TexCoordOp, - inOther.m_SizeMultiplier, inOther.m_BufferFlags) - , m_Access(inOther.m_Access) - { - m_Type = CommandTypes::AllocateImage; - } - }; - - struct SAllocateDataBuffer : public SCommand - { - CRegisteredString m_Name; - NVRenderBufferBindValues::Enum m_DataBufferType; - CRegisteredString m_WrapName; - NVRenderBufferBindValues::Enum m_DataBufferWrapType; - QT3DSF32 m_Size; - SAllocateBufferFlags m_BufferFlags; - - SAllocateDataBuffer() - : SCommand(CommandTypes::AllocateDataBuffer) - { - } - - SAllocateDataBuffer(CRegisteredString inName, - NVRenderBufferBindValues::Enum inBufferType, - CRegisteredString inWrapName, - NVRenderBufferBindValues::Enum inBufferWrapType, QT3DSF32 inSize, - SAllocateBufferFlags inFlags) - : SCommand(CommandTypes::AllocateDataBuffer) - , m_Name(inName) - , m_DataBufferType(inBufferType) - , m_WrapName(inWrapName) - , m_DataBufferWrapType(inBufferWrapType) - , m_Size(inSize) - , m_BufferFlags(inFlags) - { - } - - SAllocateDataBuffer(const SAllocateDataBuffer &inOther, IStringTable &inStrTable) - : SCommand(CommandTypes::AllocateDataBuffer) - , m_Name(inStrTable.RegisterStr(inOther.m_Name)) - , m_DataBufferType(inOther.m_DataBufferType) - , m_WrapName(inStrTable.RegisterStr(inOther.m_WrapName)) - , m_DataBufferWrapType(inOther.m_DataBufferWrapType) - , m_Size(inOther.m_Size) - , m_BufferFlags(inOther.m_BufferFlags) - { - } - }; - - struct SBindTarget : public SCommand - { - NVRenderTextureFormats::Enum m_OutputFormat; - - SBindTarget(NVRenderTextureFormats::Enum inFormat = NVRenderTextureFormats::RGBA8) - : SCommand(CommandTypes::BindTarget) - , m_OutputFormat(inFormat) - { - } - SBindTarget(const SBindTarget &inOther, IStringTable &) - : SCommand(CommandTypes::BindTarget) - , m_OutputFormat(inOther.m_OutputFormat) - { - } - }; - - struct SBindBuffer : public SCommand - { - CRegisteredString m_BufferName; - bool m_NeedsClear; - SBindBuffer(CRegisteredString inBufName, bool inNeedsClear) - : SCommand(CommandTypes::BindBuffer) - , m_BufferName(inBufName) - , m_NeedsClear(inNeedsClear) - { - } - SBindBuffer(const SBindBuffer &inOther, IStringTable &inTable) - : SCommand(CommandTypes::BindBuffer) - , m_BufferName(inTable.RegisterStr(inOther.m_BufferName)) - , m_NeedsClear(inOther.m_NeedsClear) - { - } - }; - - struct SBindShader : public SCommand - { - CRegisteredString m_ShaderPath; - // One GLSL file can hold multiple shaders in the case of multipass effects. - // This makes it significantly easier for authors to reason about the shader - // but it means we need to #define a preprocessor token to indicate which - // effect we intend to compile at this point. - CRegisteredString m_ShaderDefine; - SBindShader(CRegisteredString inShaderPath, - CRegisteredString inShaderDefine = CRegisteredString()) - : SCommand(CommandTypes::BindShader) - , m_ShaderPath(inShaderPath) - , m_ShaderDefine(inShaderDefine) - { - } - SBindShader() - : SCommand(CommandTypes::BindShader) - { - } - SBindShader(const SBindShader &inOther, IStringTable &inTable) - : SCommand(CommandTypes::BindShader) - , m_ShaderPath(inTable.RegisterStr(inOther.m_ShaderPath)) - , m_ShaderDefine(inTable.RegisterStr(inOther.m_ShaderDefine)) - { - } - }; - - // The value sits immediately after the 'this' object - // in memory. - // If propertyName is not valid then we attempt to apply all of the effect property values - // to the shader, ignoring ones that don't match up. - struct SApplyInstanceValue : public SCommand - { - // Name of value to apply in shader - CRegisteredString m_PropertyName; - // type of value - NVRenderShaderDataTypes::Enum m_ValueType; - // offset in the effect data section of value. - QT3DSU32 m_ValueOffset; - SApplyInstanceValue(CRegisteredString inName, NVRenderShaderDataTypes::Enum inValueType, - QT3DSU32 inValueOffset) - : SCommand(CommandTypes::ApplyInstanceValue) - , m_PropertyName(inName) - , m_ValueType(inValueType) - , m_ValueOffset(inValueOffset) - { - } - // Default will attempt to apply all effect values to the currently bound shader - SApplyInstanceValue() - : SCommand(CommandTypes::ApplyInstanceValue) - , m_ValueType(NVRenderShaderDataTypes::Unknown) - , m_ValueOffset(0) - { - } - SApplyInstanceValue(const SApplyInstanceValue &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyInstanceValue) - , m_PropertyName(inTable.RegisterStr(inOther.m_PropertyName)) - , m_ValueType(inOther.m_ValueType) - , m_ValueOffset(inOther.m_ValueOffset) - { - } - }; - - struct SApplyValue : public SCommand - { - CRegisteredString m_PropertyName; - NVRenderShaderDataTypes::Enum m_ValueType; - NVDataRef m_Value; - SApplyValue(CRegisteredString inName, NVRenderShaderDataTypes::Enum inValueType) - : SCommand(CommandTypes::ApplyValue) - , m_PropertyName(inName) - , m_ValueType(inValueType) - { - } - // Default will attempt to apply all effect values to the currently bound shader - SApplyValue() - : SCommand(CommandTypes::ApplyValue) - , m_ValueType(NVRenderShaderDataTypes::Unknown) - { - } - - SApplyValue(const SApplyValue &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyValue) - , m_PropertyName(inTable.RegisterStr(inOther.m_PropertyName)) - , m_ValueType(inOther.m_ValueType) - , m_Value(inOther.m_Value) - { - } - }; - - // bind a buffer to a given shader parameter. - struct SApplyBufferValue : public SCommand - { - // If no buffer name is given then the special buffer [source] - // is assumed. - CRegisteredString m_BufferName; - // If no param name is given, the buffer is bound to the - // input texture parameter (texture0). - CRegisteredString m_ParamName; - - SApplyBufferValue(CRegisteredString bufferName, CRegisteredString shaderParam) - : SCommand(CommandTypes::ApplyBufferValue) - , m_BufferName(bufferName) - , m_ParamName(shaderParam) - { - } - SApplyBufferValue(const SApplyBufferValue &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyBufferValue) - , m_BufferName(inTable.RegisterStr(inOther.m_BufferName)) - , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) - { - } - }; - - // bind a buffer to a given shader parameter. - struct SApplyImageValue : public SCommand - { - CRegisteredString m_ImageName; ///< name which the image was allocated - CRegisteredString m_ParamName; ///< must match the name in the shader - bool m_BindAsTexture; ///< bind image as texture - bool m_NeedSync; ///< if true we add a memory barrier before usage - - SApplyImageValue(CRegisteredString bufferName, CRegisteredString shaderParam, - bool inBindAsTexture, bool inNeedSync) - : SCommand(CommandTypes::ApplyImageValue) - , m_ImageName(bufferName) - , m_ParamName(shaderParam) - , m_BindAsTexture(inBindAsTexture) - , m_NeedSync(inNeedSync) - { - } - SApplyImageValue(const SApplyImageValue &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyImageValue) - , m_ImageName(inTable.RegisterStr(inOther.m_ImageName)) - , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) - , m_BindAsTexture(inOther.m_BindAsTexture) - , m_NeedSync(inOther.m_NeedSync) - { - } - }; - - // bind a buffer to a given shader parameter. - struct SApplyDataBufferValue : public SCommand - { - CRegisteredString m_ParamName; ///< must match the name in the shader - NVRenderBufferBindValues::Enum m_BindAs; ///< to which target we bind this buffer - - SApplyDataBufferValue(CRegisteredString inShaderParam, - NVRenderBufferBindValues::Enum inBufferType) - : SCommand(CommandTypes::ApplyDataBufferValue) - , m_ParamName(inShaderParam) - , m_BindAs(inBufferType) - { - } - SApplyDataBufferValue(const SApplyDataBufferValue &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyDataBufferValue) - , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) - , m_BindAs(inOther.m_BindAs) - { - } - }; - - struct SApplyDepthValue : public SCommand - { - // If no param name is given, the buffer is bound to the - // input texture parameter (texture0). - CRegisteredString m_ParamName; - SApplyDepthValue(CRegisteredString param) - : SCommand(CommandTypes::ApplyDepthValue) - , m_ParamName(param) - { - } - SApplyDepthValue(const SApplyDepthValue &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyDepthValue) - , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) - { - } - }; - - struct SRender : public SCommand - { - bool m_DrawIndirect; - SRender(bool inDrawIndirect) - : SCommand(CommandTypes::Render) - , m_DrawIndirect(inDrawIndirect) - { - } - - SRender(const SRender &inOther, IStringTable &) - : SCommand(CommandTypes::Render) - , m_DrawIndirect(inOther.m_DrawIndirect) - { - } - }; - - struct SApplyBlending : public SCommand - { - NVRenderSrcBlendFunc::Enum m_SrcBlendFunc; - NVRenderDstBlendFunc::Enum m_DstBlendFunc; - - SApplyBlending(NVRenderSrcBlendFunc::Enum inSrcBlendFunc, - NVRenderDstBlendFunc::Enum inDstBlendFunc) - : SCommand(CommandTypes::ApplyBlending) - , m_SrcBlendFunc(inSrcBlendFunc) - , m_DstBlendFunc(inDstBlendFunc) - { - } - - SApplyBlending(const SApplyBlending &inOther, IStringTable &) - : SCommand(CommandTypes::ApplyBlending) - , m_SrcBlendFunc(inOther.m_SrcBlendFunc) - , m_DstBlendFunc(inOther.m_DstBlendFunc) - { - } - }; - - struct SApplyRenderState : public SCommand - { - NVRenderState::Enum m_RenderState; - bool m_Enabled; - - SApplyRenderState(qt3ds::render::NVRenderState::Enum inRenderStateValue, bool inEnabled) - : SCommand(CommandTypes::ApplyRenderState) - , m_RenderState(inRenderStateValue) - , m_Enabled(inEnabled) - { - } - - SApplyRenderState(const SApplyRenderState &inOther, IStringTable &) - : SCommand(CommandTypes::ApplyRenderState) - , m_RenderState(inOther.m_RenderState) - , m_Enabled(inOther.m_Enabled) - { - } - }; - - struct SApplyBlitFramebuffer : public SCommand - { - // If no buffer name is given then the special buffer [source] - // is assumed. Which is the default render target - CRegisteredString m_SourceBufferName; - // If no buffer name is given then the special buffer [dest] - // is assumed. Which is the default render target - CRegisteredString m_DestBufferName; - - SApplyBlitFramebuffer(CRegisteredString inSourceBufferName, - CRegisteredString inDestBufferName) - : SCommand(CommandTypes::ApplyBlitFramebuffer) - , m_SourceBufferName(inSourceBufferName) - , m_DestBufferName(inDestBufferName) - { - } - - SApplyBlitFramebuffer(const SApplyBlitFramebuffer &inOther, IStringTable &inTable) - : SCommand(CommandTypes::ApplyBlitFramebuffer) - , m_SourceBufferName(inTable.RegisterStr(inOther.m_SourceBufferName)) - , m_DestBufferName(inTable.RegisterStr(inOther.m_DestBufferName)) - { - } - }; - - struct DepthStencilFlagValues - { - enum Enum { - NoFlagValue = 0, - ClearStencil = 1 << 0, - ClearDepth = 1 << 1, - }; - }; - - struct SDepthStencilFlags : public NVFlags - { - bool HasClearStencil() const { return operator&(DepthStencilFlagValues::ClearStencil); } - void SetClearStencil(bool value) - { - clearOrSet(value, DepthStencilFlagValues::ClearStencil); - } - - bool HasClearDepth() const { return operator&(DepthStencilFlagValues::ClearDepth); } - void SetClearDepth(bool value) - { - clearOrSet(value, DepthStencilFlagValues::ClearDepth); - } - }; - - struct SDepthStencil : public SCommand - { - CRegisteredString m_BufferName; - SDepthStencilFlags m_Flags; - qt3ds::render::NVRenderStencilOp::Enum m_StencilFailOperation; - qt3ds::render::NVRenderStencilOp::Enum m_DepthPassOperation; - qt3ds::render::NVRenderStencilOp::Enum m_DepthFailOperation; - qt3ds::render::NVRenderBoolOp::Enum m_StencilFunction; - QT3DSU32 m_Reference; - QT3DSU32 m_Mask; - - SDepthStencil() - : SCommand(CommandTypes::DepthStencil) - , m_StencilFailOperation(qt3ds::render::NVRenderStencilOp::Keep) - , m_DepthPassOperation(qt3ds::render::NVRenderStencilOp::Keep) - , m_DepthFailOperation(qt3ds::render::NVRenderStencilOp::Keep) - , m_StencilFunction(qt3ds::render::NVRenderBoolOp::Equal) - , m_Reference(0) - , m_Mask(QT3DS_MAX_U32) - { - } - - SDepthStencil(CRegisteredString bufName, SDepthStencilFlags flags, - qt3ds::render::NVRenderStencilOp::Enum inStencilOp, - qt3ds::render::NVRenderStencilOp::Enum inDepthPassOp, - qt3ds::render::NVRenderStencilOp::Enum inDepthFailOp, - qt3ds::render::NVRenderBoolOp::Enum inStencilFunc, QT3DSU32 value, QT3DSU32 mask) - : SCommand(CommandTypes::DepthStencil) - , m_BufferName(bufName) - , m_Flags(flags) - , m_StencilFailOperation(inStencilOp) - , m_DepthPassOperation(inDepthPassOp) - , m_DepthFailOperation(inDepthFailOp) - , m_StencilFunction(inStencilFunc) - , m_Reference(value) - , m_Mask(mask) - { - } - - SDepthStencil(const SDepthStencil &inOther, IStringTable &inTable) - : SCommand(CommandTypes::DepthStencil) - , m_BufferName(inTable.RegisterStr(inOther.m_BufferName)) - , m_Flags(inOther.m_Flags) - , m_StencilFailOperation(inOther.m_StencilFailOperation) - , m_DepthPassOperation(inOther.m_DepthPassOperation) - , m_DepthFailOperation(inOther.m_DepthFailOperation) - , m_StencilFunction(inOther.m_StencilFunction) - , m_Reference(inOther.m_Reference) - , m_Mask(inOther.m_Mask) - { - } - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemUtil.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemUtil.h deleted file mode 100644 index 5d78a4c9..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderDynamicObjectSystemUtil.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_UTIL_H -#define QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_UTIL_H -#include "Qt3DSRender.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "Qt3DSRenderString.h" - -namespace qt3ds { -namespace render { - namespace dynamic { - - struct SStringLoadRemapper - { - CStrTableOrDataRef m_StrData; - IStringTable &m_StringTable; - CRenderString m_PathMapper; - const char8_t *m_ProjectDir; - SStringLoadRemapper(NVAllocatorCallback &alloc, CStrTableOrDataRef inData, - const char8_t *inProjectDir, IStringTable &inStrTable) - : m_StrData(inData) - , m_StringTable(inStrTable) - , m_ProjectDir(inProjectDir) - { - Q_UNUSED(alloc) - } - void Remap(CRegisteredString &inStr) { inStr.Remap(m_StrData); } - }; - - struct SStringSaveRemapper - { - const qt3ds::render::SStrRemapMap &m_Map; - CRenderString m_RelativeBuffer; - CRenderString m_ProjectDir; - CRenderString m_FinalBuffer; - IStringTable &m_StringTable; - SStringSaveRemapper(NVAllocatorCallback &alloc, const qt3ds::render::SStrRemapMap &map, - const char8_t *inProjectDir, IStringTable &inStrTable) - : m_Map(map) - , m_StringTable(inStrTable) - { - Q_UNUSED(alloc) - m_ProjectDir.assign(inProjectDir); - } - void Remap(CRegisteredString &inStr) { inStr.Remap(m_Map); } - }; - - inline QT3DSU32 Align(QT3DSU32 inValue) - { - if (inValue % 4) - return inValue + (4 - (inValue % 4)); - return inValue; - } - - inline QT3DSU32 Align8(QT3DSU32 inValue) - { - if (inValue % 8) - return inValue + (8 - (inValue % 8)); - return inValue; - } - - inline qt3ds::QT3DSU32 getSizeofShaderDataType(NVRenderShaderDataTypes::Enum value) - { - using namespace qt3ds; - using namespace qt3ds::render; - switch (value) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(x) \ - case NVRenderShaderDataTypes::x: \ - return sizeof(x); - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - inline const char *GetShaderDatatypeName(NVRenderShaderDataTypes::Enum inValue) - { - switch (inValue) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ - case NVRenderShaderDataTypes::type: \ - return #type; - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return ""; - } - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEffectSystem.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEffectSystem.h deleted file mode 100644 index 119564da..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEffectSystem.h +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_EFFECT_SYSTEM_H -#define QT3DS_RENDER_EFFECT_SYSTEM_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSVec2.h" -#include "Qt3DSRenderDynamicObjectSystem.h" - -namespace qt3ds { -namespace render { - struct SEffect; - struct SEffectContext; - namespace dynamic { - struct SCommand; // UICRenderEffectCommands.h - } - - struct SEffectRenderArgument - { - SEffect &m_Effect; - NVRenderTexture2D &m_ColorBuffer; - // Some effects need the camera near and far ranges. - QT3DSVec2 m_CameraClipRange; - // Some effects require the depth buffer from the rendering of thelayer - // most do not. - NVRenderTexture2D *m_DepthTexture; - // this is a depth preapass texture we need for some effects like bloom - // actually we need the stencil values - NVRenderTexture2D *m_DepthStencilBuffer; - - SEffectRenderArgument(SEffect &inEffect, NVRenderTexture2D &inColorBuffer, - const QT3DSVec2 &inCameraClipRange, - NVRenderTexture2D *inDepthTexture = NULL, - NVRenderTexture2D *inDepthBuffer = NULL) - : m_Effect(inEffect) - , m_ColorBuffer(inColorBuffer) - , m_CameraClipRange(inCameraClipRange) - , m_DepthTexture(inDepthTexture) - , m_DepthStencilBuffer(inDepthBuffer) - { - } - }; - - class IEffectSystemCore : public NVRefCounted - { - public: - virtual bool IsEffectRegistered(CRegisteredString inStr) = 0; - virtual NVConstDataRef GetRegisteredEffects() = 0; - // Register an effect class that uses exactly these commands to render. - // Effect properties cannot change after the effect is created because that would invalidate - // existing effect instances. - // Effect commands, which are stored on the effect class, can change. - virtual bool RegisterEffect(CRegisteredString inName, - NVConstDataRef inProperties) = 0; - - virtual bool UnregisterEffect(CRegisteredString inName) = 0; - - // Shorthand method that creates an effect and auto-generates the effect commands like such: - // BindShader(inPathToEffect) - // foreach( propdec in inProperties ) ApplyValue( propDecType ) - // ApplyShader() - virtual bool - RegisterGLSLEffect(CRegisteredString inName, const char8_t *inPathToEffect, - NVConstDataRef inProperties) = 0; - // Set the default value. THis is unnecessary if the default is zero as that is what it is - // assumed to be. - virtual void SetEffectPropertyDefaultValue(CRegisteredString inName, - CRegisteredString inPropName, - NVConstDataRef inDefaultData) = 0; - virtual void SetEffectPropertyEnumNames(CRegisteredString inName, - CRegisteredString inPropName, - NVConstDataRef inNames) = 0; - virtual NVConstDataRef - GetEffectPropertyEnumNames(CRegisteredString inName, - CRegisteredString inPropName) const = 0; - - virtual NVConstDataRef - GetEffectProperties(CRegisteredString inEffectName) const = 0; - - virtual void SetEffectPropertyTextureSettings( - CRegisteredString inEffectName, CRegisteredString inPropName, - CRegisteredString inPropPath, NVRenderTextureTypeValue::Enum inTexType, - NVRenderTextureCoordOp::Enum inCoordOp, NVRenderTextureMagnifyingOp::Enum inMagFilterOp, - NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0; - - // Setting the effect commands also sets this as if there isn't a specific "apply depth - // value" - // command then this effect does not require the depth texture. - // So the setter here is completely optional. - virtual void SetEffectRequiresDepthTexture(CRegisteredString inEffectName, - bool inValue) = 0; - virtual bool DoesEffectRequireDepthTexture(CRegisteredString inEffectName) const = 0; - - virtual void SetEffectRequiresCompilation(CRegisteredString inEffectName, - bool inValue) = 0; - virtual bool DoesEffectRequireCompilation(CRegisteredString inEffectName) const = 0; - - // The effect commands are the actual commands that run for a given effect. The tell the - // system exactly - // explicitly things like bind this shader, bind this render target, apply this property, - // run this shader - // See UICRenderEffectCommands.h for the list of commands. - // These commands are copied into the effect. - virtual void SetEffectCommands(CRegisteredString inEffectName, - NVConstDataRef inCommands) = 0; - virtual NVConstDataRef - GetEffectCommands(CRegisteredString inEffectName) const = 0; - - // Set the shader data for a given path. Used when a path doesn't correspond to a file but - // the data has been - // auto-generated. The system will look for data under this path key during the BindShader - // effect command. - virtual void SetShaderData(CRegisteredString inPath, const char8_t *inData, - const char8_t *inShaderType = NULL, - const char8_t *inShaderVersion = NULL, - bool inHasGeomShader = false, - bool inIsComputeShader = false) = 0; - - // An effect instance is just a property bag along with the name of the effect to run. - // This instance is what is placed into the object graph. - virtual SEffect *CreateEffectInstance(CRegisteredString inEffectName, - NVAllocatorCallback &inSceneGraphAllocator) = 0; - - virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, - const char8_t *inProjectDir) const = 0; - virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t *inProjectDir) = 0; - - virtual IEffectSystem &GetEffectSystem(IQt3DSRenderContext &context) = 0; - - virtual IResourceManager &GetResourceManager() = 0; - - static IEffectSystemCore &CreateEffectSystemCore(IQt3DSRenderContextCore &context); - }; - - /** - * An effect is essentially a function that takes a image and produces a new image. The source - *and dest images - * aren't guaranteed to be the same size, the effect may enlarge or shrink the result. - * A specialization is when you want the effect to render to the final render target instead of - *to a separate image. - * In this case the effect cannot enlarge or shrink the final target and it will render to the - *destination buffer - * using the given MVP. - */ - class IEffectSystem : public IEffectSystemCore - { - protected: - virtual ~IEffectSystem() {} - - public: - // Calling release effect context with no context results in no problems. - virtual void ReleaseEffectContext(SEffectContext *inEffect) = 0; - - // If the effect has a context you can call this to clear persistent buffers back to their - // original value. - virtual void ResetEffectFrameData(SEffectContext &inContext) = 0; - - // Render this effect. Returns false in the case the effect wasn't rendered and the render - // state - // is guaranteed to be the same as before. - // The texture returned is allocated using the resource manager, and it is up to the caller - // to deallocate it or return it to the temporary pool if items when necessary - // Pass in true if you want the result image premultiplied. Most of the functions in the - // system - // assume non-premultiplied color for images so probably this is false. - virtual NVRenderTexture2D *RenderEffect(SEffectRenderArgument inRenderArgument) = 0; - - // Render the effect to the currently bound render target using this MVP and optionally - // enabling blending when rendering to the target - virtual bool RenderEffect(SEffectRenderArgument inRenderArgument, QT3DSMat44 &inMVP, - bool inEnableBlendWhenRenderToTarget) = 0; - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEulerAngles.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEulerAngles.h deleted file mode 100644 index bf271e29..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEulerAngles.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -namespace qt3ds { -namespace render { - //============================================================================== - // Description - //============================================================================== - // QuatTypes.h - Basic type declarations - // by Ken Shoemake, shoemake@graphics.cis.upenn.edu - // in "Graphics Gems IV", Academic Press, 1994 - typedef struct - { - float x, y, z, w; - } Quat; /* Quaternion */ - typedef float HMatrix[4][4]; /* Right-handed, for column vectors */ - enum QuatPart { X, Y, Z, W }; - typedef Quat EulerAngles; /* (x,y,z)=ang 1,2,3, w=order code */ - -#define EulFrmS 0 -#define EulFrmR 1 -#define EulFrm(ord) ((unsigned)(ord)&1) -#define EulRepNo 0 -#define EulRepYes 1 -#define EulRep(ord) (((unsigned)(ord) >> 1) & 1) -#define EulParEven 0 -#define EulParOdd 1 -#define EulPar(ord) (((unsigned)(ord) >> 2) & 1) -#define EulSafe "\000\001\002\000" -#define EulNext "\001\002\000\001" -#define EulAxI(ord) ((int)(EulSafe[(((unsigned)(ord) >> 3) & 3)])) -#define EulAxJ(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) == EulParOdd)])) -#define EulAxK(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) != EulParOdd)])) -#define EulAxH(ord) ((EulRep(ord) == EulRepNo) ? EulAxK(ord) : EulAxI(ord)) - -// EulGetOrd unpacks all useful information about order simultaneously. -#define EulGetOrd(ord, i, j, k, h, n, s, f) \ - { \ - unsigned o = ord; \ - f = o & 1; \ - o = o >> 1; \ - s = o & 1; \ - o = o >> 1; \ - n = o & 1; \ - o = o >> 1; \ - i = EulSafe[o & 3]; \ - j = EulNext[i + n]; \ - k = EulNext[i + 1 - n]; \ - h = s ? k : i; \ - } - -// EulOrd creates an order value between 0 and 23 from 4-tuple choices. -#define EulOrd(i, p, r, f) (((((((i) << 1) + (p)) << 1) + (r)) << 1) + (f)) - -// Static axes -// X = 0, Y = 1, Z = 2 ref QuatPart -#define EulOrdXYZs EulOrd(0, EulParEven, EulRepNo, EulFrmS) -#define EulOrdXYXs EulOrd(0, EulParEven, EulRepYes, EulFrmS) -#define EulOrdXZYs EulOrd(0, EulParOdd, EulRepNo, EulFrmS) -#define EulOrdXZXs EulOrd(0, EulParOdd, EulRepYes, EulFrmS) -#define EulOrdYZXs EulOrd(1, EulParEven, EulRepNo, EulFrmS) -#define EulOrdYZYs EulOrd(1, EulParEven, EulRepYes, EulFrmS) -#define EulOrdYXZs EulOrd(1, EulParOdd, EulRepNo, EulFrmS) -#define EulOrdYXYs EulOrd(1, EulParOdd, EulRepYes, EulFrmS) -#define EulOrdZXYs EulOrd(2, EulParEven, EulRepNo, EulFrmS) -#define EulOrdZXZs EulOrd(2, EulParEven, EulRepYes, EulFrmS) -#define EulOrdZYXs EulOrd(2, EulParOdd, EulRepNo, EulFrmS) -#define EulOrdZYZs EulOrd(2, EulParOdd, EulRepYes, EulFrmS) - -// Rotating axes -#define EulOrdZYXr EulOrd(0, EulParEven, EulRepNo, EulFrmR) -#define EulOrdXYXr EulOrd(0, EulParEven, EulRepYes, EulFrmR) -#define EulOrdYZXr EulOrd(0, EulParOdd, EulRepNo, EulFrmR) -#define EulOrdXZXr EulOrd(0, EulParOdd, EulRepYes, EulFrmR) -#define EulOrdXZYr EulOrd(1, EulParEven, EulRepNo, EulFrmR) -#define EulOrdYZYr EulOrd(1, EulParEven, EulRepYes, EulFrmR) -#define EulOrdZXYr EulOrd(1, EulParOdd, EulRepNo, EulFrmR) -#define EulOrdYXYr EulOrd(1, EulParOdd, EulRepYes, EulFrmR) -#define EulOrdYXZr EulOrd(2, EulParEven, EulRepNo, EulFrmR) -#define EulOrdZXZr EulOrd(2, EulParEven, EulRepYes, EulFrmR) -#define EulOrdXYZr EulOrd(2, EulParOdd, EulRepNo, EulFrmR) -#define EulOrdZYZr EulOrd(2, EulParOdd, EulRepYes, EulFrmR) - -#ifndef M_PI -#define M_PI 3.1415926535898 -#endif - -#define TODEG(x) x = (float)(x * 180 / M_PI); -#define TORAD(x) x = (float)(x / 180 * M_PI); - - class CEulerAngleConverter - { - private: - char m_OrderInfoBuffer[1024]; - - public: - CEulerAngleConverter(); - virtual ~CEulerAngleConverter(); - - public: - EulerAngles Eul_(float ai, float aj, float ah, int order); - Quat Eul_ToQuat(EulerAngles ea); - void Eul_ToHMatrix(EulerAngles ea, HMatrix M); - EulerAngles Eul_FromHMatrix(HMatrix M, int order); - EulerAngles Eul_FromQuat(Quat q, int order); - - // Debug Stuff - const char *DumpOrderInfo(); - }; -} -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectPickQuery.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectPickQuery.h deleted file mode 100644 index e63cad3f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectPickQuery.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_GRAPH_OBJECT_PICK_QUERY_H -#define QT3DS_RENDER_GRAPH_OBJECT_PICK_QUERY_H - -#include "Qt3DSRender.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSMat44.h" -#include "Qt3DSRenderImage.h" - -namespace qt3ds { -namespace render { - - class IOffscreenRenderer; - - struct Qt3DSRenderPickSubResult - { - IOffscreenRenderer *m_SubRenderer; - QT3DSMat44 m_TextureMatrix; - NVRenderTextureCoordOp::Enum m_HorizontalTilingMode; - NVRenderTextureCoordOp::Enum m_VerticalTilingMode; - QT3DSU32 m_ViewportWidth; - QT3DSU32 m_ViewportHeight; - Qt3DSRenderPickSubResult *m_NextSibling; - - Qt3DSRenderPickSubResult() - : m_SubRenderer(NULL) - , m_NextSibling(NULL) - { - } - Qt3DSRenderPickSubResult(IOffscreenRenderer &inSubRenderer, QT3DSMat44 inTextureMatrix, - NVRenderTextureCoordOp::Enum inHorizontalTilingMode, - NVRenderTextureCoordOp::Enum inVerticalTilingMode, QT3DSU32 width, - QT3DSU32 height) - : m_SubRenderer(&inSubRenderer) - , m_TextureMatrix(inTextureMatrix) - , m_HorizontalTilingMode(inHorizontalTilingMode) - , m_VerticalTilingMode(inVerticalTilingMode) - , m_ViewportWidth(width) - , m_ViewportHeight(height) - , m_NextSibling(NULL) - { - } - }; - - struct Qt3DSRenderPickResult - { - const SGraphObject *m_HitObject; - QT3DSF32 m_CameraDistanceSq; - // The local coordinates in X,Y UV space where the hit occured - QT3DSVec2 m_LocalUVCoords; - // The local mouse coordinates will be the same on all of the sub objects. - Qt3DSRenderPickSubResult *m_FirstSubObject; - // The offscreen renderer that was used to render the scene graph this result was produced - // from. - IOffscreenRenderer *m_OffscreenRenderer; - - Qt3DSRenderPickResult(const SGraphObject &inHitObject, QT3DSF32 inCameraDistance, - const QT3DSVec2 &inLocalUVCoords) - : m_HitObject(&inHitObject) - , m_CameraDistanceSq(inCameraDistance) - , m_LocalUVCoords(inLocalUVCoords) - , m_FirstSubObject(NULL) - , m_OffscreenRenderer(NULL) - { - } - Qt3DSRenderPickResult() - : m_HitObject(NULL) - , m_CameraDistanceSq(QT3DS_MAX_F32) - , m_LocalUVCoords(0, 0) - , m_FirstSubObject(NULL) - , m_OffscreenRenderer(NULL) - { - } - }; - - class IGraphObjectPickQuery - { - protected: - virtual ~IGraphObjectPickQuery() {} - - public: - // Implementors have the option of batching the results to allow fewer virtual calls - // or returning one item each pick. - // Results are guaranteed to be returned nearest to furthest - // If the return value has size of zero then we assume nothing more can be picked and the - // pick - // is finished. - virtual Qt3DSRenderPickResult Pick(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool inPickEverything) = 0; - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectSerializer.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectSerializer.h deleted file mode 100644 index 8f8420c1..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectSerializer.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_GRAPH_OBJECT_SERIALZER_H -#define QT3DS_RENDER_GRAPH_OBJECT_SERIALZER_H - -#include "Qt3DSRender.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -class NVFoundationBase; -} - -namespace qt3ds { -namespace render { - struct SPresentation; - class IEffectSystem; - - struct SGraphObjectSerializer - { - // This will save the tree as it exists but clients may wish to save out extra objects in - // addtion - static void - Save(NVFoundationBase &inFoundation, const SPresentation &inPresentation, - SWriteBuffer &outSavedData, IDynamicObjectSystem &inDynamicObjectSystem, - IPathManager &inPathManager, SPtrOffsetMap &outSceneGraphOffsets, - IStringTable &inStringTable, - NVDataRef inExtraGraphObjects = NVDataRef()); - - // Loading requires a correctly setup effect system because the effects have arbitrary data - // and the strings embedded in that data will - // require string remapping. - static SPresentation *Load(NVDataRef inData, NVDataRef inStrDataBlock, - IDynamicObjectSystemCore &inDynamicObjectSystem, - IPathManagerCore &inPathManager, - NVAllocatorCallback &inAllocator, - const char8_t *inProjectDirectory); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectTypes.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectTypes.h deleted file mode 100644 index 620f6c5d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderGraphObjectTypes.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_GRAPH_OBJECT_TYPES_H -#define QT3DS_RENDER_GRAPH_OBJECT_TYPES_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSAssert.h" - -namespace qt3ds { -namespace render { - -// If you need a generic switch statement, then these macros will ensure -// you get all the types the first time. -#define QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Presentation) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Scene) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Node) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Layer) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Light) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Camera) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Model) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(DefaultMaterial) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Image) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Text) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Effect) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(RenderPlugin) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(CustomMaterial) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(ReferencedMaterial) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Path) \ - QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(PathSubPath) - - struct GraphObjectTypes - { - enum Enum { - Unknown = 0, - Presentation, - Scene, - Node, - Layer, - Light, - Camera, - Model, - DefaultMaterial, - Image, - Text, - Effect, - CustomMaterial, - RenderPlugin, - ReferencedMaterial, - Path, - PathSubPath, - Lightmaps, - LastKnownGraphObjectType, - }; - - static bool IsMaterialType(Enum type) - { - switch (type) { - case ReferencedMaterial: - case CustomMaterial: - case DefaultMaterial: - return true; - default: - return false; - } - } - - static bool IsLightmapType(Enum type) - { - switch (type) { - case Lightmaps: - case DefaultMaterial: - return true; - default: - return false; - } - } - - static bool IsNodeType(Enum type) - { - switch (type) { - case Node: - case Layer: - case Light: - case Camera: - case Model: - case Text: - case Path: - return true; - - default: - break; - } - return false; - } - - static bool IsRenderableType(Enum type) - { - switch (type) { - case Model: - case Text: - case Path: - return true; - default: - break; - } - return false; - } - - static bool IsLightCameraType(Enum type) - { - switch (type) { - case Camera: - case Light: - return true; - default: - break; - } - return false; - } - static const char *GetObjectTypeName(Enum inType) - { - switch (inType) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case type: \ - return #type; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return ""; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageScaler.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageScaler.h deleted file mode 100644 index 27b51770..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageScaler.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2001 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Prefix -//============================================================================== -#ifndef __IMAGESCALER_H_ -#define __IMAGESCALER_H_ -#include "Qt3DSRender.h" - -namespace qt3ds { -namespace render { - //============================================================================== - // Class - //============================================================================== - //============================================================================== - /** - * @class CImageScaler - */ - //============================================================================== - class CImageScaler - { - NVAllocatorCallback &m_Allocator; - - public: - //============================================================================== - // Methods - //============================================================================== - enum EScaleMethod { - SCALEMETHOD_CROP = -1, // Debug only, not a scaler - SCALEMETHOD_POINTSAMPLE = 0, - SCALEMETHOD_BILINEAR = 1, - }; - - //============================================================================== - // Methods - //============================================================================== - - // Access - - public: - CImageScaler(NVAllocatorCallback &inAlloc); - - void Scale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, unsigned long inChannels); - - void FastScale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, - unsigned long inOldWidth, unsigned long inOldHeight, - unsigned char *&outNewBuffer, unsigned long inNewWidth, - unsigned long inNewHeight, unsigned long inChannels); - - void Crop(unsigned char *inOldBuffer, unsigned long inOldWidth, unsigned long inOldHeight, - unsigned char *&outNewBuffer, unsigned long inNewWidth, unsigned long inNewHeight, - unsigned long inPlanes); - - void Bilinear(unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, unsigned long inPlanes); - - void FastPointSample(unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, - unsigned long inPlanes); - - unsigned char *AllocateBuffer(long inWidth, long inHeight); - void ReleaseBuffer(unsigned char *&ioBuffer); - void Resize(unsigned char *inOldBuffer, unsigned long inOldWidth, unsigned long inOldHeight, - unsigned char *&outNewBuffer, unsigned long inNewWidth, - unsigned long inNewHeight, unsigned long inPlanes); - - // variable numbers of planes, i.e. greyscale, rb, rbg, and rgba or argb - // Bilinear algorithms, good for quality - void ExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, - unsigned long inHeight, unsigned char *outBuffer, - unsigned long inDstWidth, unsigned long inDstHeight, - unsigned long inPlanes); - - // The method implemented above, but with some optimizations - // specifically, fixed the number of planes at 4 - // eliminated the new/delete allocations - void FastExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, - unsigned long inHeight, unsigned char *outBuffer, - unsigned long inDstWidth, unsigned long inDstHeight); - - void ReduceCols(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, - unsigned char *&outDstBuffer, long inDstWidth); - void ReduceRows(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, - unsigned char *&outDstBuffer, long inDstHeight); - }; -} -} - -#endif // !defined(__IMAGESCALER_H_) diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageTextureData.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageTextureData.h deleted file mode 100644 index d3698032..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderImageTextureData.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_IMAGE_TEXTURE_DATA_H -#define QT3DS_RENDER_IMAGE_TEXTURE_DATA_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSFlags.h" - -namespace qt3ds { -namespace render { - - // forward declararion - class Qt3DSRenderPrefilterTexture; - - struct ImageTextureFlagValues - { - enum Enum { - HasTransparency = 1, - InvertUVCoords = 1 << 1, - PreMultiplied = 1 << 2, - }; - }; - - struct SImageTextureFlags : public NVFlags - { - bool HasTransparency() const - { - return this->operator&(ImageTextureFlagValues::HasTransparency); - } - void SetHasTransparency(bool inValue) - { - clearOrSet(inValue, ImageTextureFlagValues::HasTransparency); - } - - bool IsInvertUVCoords() const - { - return this->operator&(ImageTextureFlagValues::InvertUVCoords); - } - void SetInvertUVCoords(bool inValue) - { - clearOrSet(inValue, ImageTextureFlagValues::InvertUVCoords); - } - - bool IsPreMultiplied() const - { - return this->operator&(ImageTextureFlagValues::PreMultiplied); - } - void SetPreMultiplied(bool inValue) - { - clearOrSet(inValue, ImageTextureFlagValues::PreMultiplied); - } - }; - - struct SImageTextureData - { - NVRenderTexture2D *m_Texture; - SImageTextureFlags m_TextureFlags; - Qt3DSRenderPrefilterTexture *m_BSDFMipMap; - - SImageTextureData() - : m_Texture(NULL) - , m_BSDFMipMap(NULL) - { - } - - bool operator!=(const SImageTextureData &inOther) - { - return m_Texture != inOther.m_Texture || m_TextureFlags != inOther.m_TextureFlags - || m_BSDFMipMap != inOther.m_BSDFMipMap; - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderInputStreamFactory.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderInputStreamFactory.h deleted file mode 100644 index e82134b8..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderInputStreamFactory.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_INPUT_STREAM_FACTORY_H -#define QT3DS_RENDER_INPUT_STREAM_FACTORY_H -#include "Qt3DSRender.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/string.h" - -namespace qt3ds { -namespace render { - class IRefCountedInputStream : public qt3ds::foundation::ISeekableIOStream, public NVRefCounted - { - protected: - virtual ~IRefCountedInputStream() {} - }; - // This class is threadsafe. - class IInputStreamFactory : public NVRefCounted - { - protected: - virtual ~IInputStreamFactory() {} - public: - // These directories must have a '/' on them - virtual void AddSearchDirectory(const char8_t *inDirectory) = 0; - virtual IRefCountedInputStream *GetStreamForFile(const QString &inFilename, - bool inQuiet = false) = 0; - // Return a path for this file. Returns true if GetStreamForFile would return a valid - // stream. - // else returns false - virtual bool GetPathForFile(const QString &inFilename, QString &outFile, - bool inQuiet = false) = 0; - - // Create an input stream factory using this foundation and an platform-optional app - // directory - // on android the app directory has no effect; use use the assets bundled with the APK file. - static IInputStreamFactory &Create(NVFoundationBase &inFoundation); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h deleted file mode 100644 index 4dcd62c5..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_RENDER_LIGHT_CONSTANT_PROPERTIES -#define QT3DS_RENDER_LIGHT_CONSTANT_PROPERTIES - -#include "render/Qt3DSRenderShaderProgram.h" - -namespace qt3ds { -namespace render { - -static const QStringList lconstantnames = { - QStringLiteral("position"), - QStringLiteral("direction"), - QStringLiteral("up"), - QStringLiteral("right"), - QStringLiteral("diffuse"), - QStringLiteral("ambient"), - QStringLiteral("specular"), - QStringLiteral("spotExponent"), - QStringLiteral("spotCutoff"), - QStringLiteral("constantAttenuation"), - QStringLiteral("linearAttenuation"), - QStringLiteral("quadraticAttenuation"), - QStringLiteral("range"), - QStringLiteral("width"), - QStringLiteral("height"), - QStringLiteral("shadowControls"), - QStringLiteral("shadowView"), - QStringLiteral("shadowIdx"), - QStringLiteral("attenuation") -}; - -#define LCSEED QStringLiteral("%1%2") - -template -struct SLightConstantProperties -{ - struct LightConstants - { - NVRenderCachedShaderProperty m_position; - NVRenderCachedShaderProperty m_direction; - NVRenderCachedShaderProperty m_up; - NVRenderCachedShaderProperty m_right; - NVRenderCachedShaderProperty m_diffuse; - NVRenderCachedShaderProperty m_ambient; - NVRenderCachedShaderProperty m_specular; - NVRenderCachedShaderProperty m_spotExponent; - NVRenderCachedShaderProperty m_spotCutoff; - NVRenderCachedShaderProperty m_constantAttenuation; - NVRenderCachedShaderProperty m_linearAttenuation; - NVRenderCachedShaderProperty m_quadraticAttenuation; - NVRenderCachedShaderProperty m_range; - NVRenderCachedShaderProperty m_width; - NVRenderCachedShaderProperty m_height; - NVRenderCachedShaderProperty m_shadowControls; - NVRenderCachedShaderProperty m_shadowView; - NVRenderCachedShaderProperty m_shadowIdx; - NVRenderCachedShaderProperty m_attenuation; - - LightConstants(const QString &lightRef, render::NVRenderShaderProgram &shader) - : m_position(LCSEED.arg(lightRef, lconstantnames[0]), shader) - , m_direction(LCSEED.arg(lightRef).arg(lconstantnames[1]), shader) - , m_up(LCSEED.arg(lightRef, lconstantnames[2]), shader) - , m_right(LCSEED.arg(lightRef, lconstantnames[3]), shader) - , m_diffuse(LCSEED.arg(lightRef, lconstantnames[4]), shader) - , m_ambient(LCSEED.arg(lightRef, lconstantnames[5]), shader) - , m_specular(LCSEED.arg(lightRef, lconstantnames[6]), shader) - , m_spotExponent(LCSEED.arg(lightRef, lconstantnames[7]), shader) - , m_spotCutoff(LCSEED.arg(lightRef, lconstantnames[8]), shader) - , m_constantAttenuation(LCSEED.arg(lightRef, lconstantnames[9]), shader) - , m_linearAttenuation(LCSEED.arg(lightRef, lconstantnames[10]), shader) - , m_quadraticAttenuation(LCSEED.arg(lightRef, lconstantnames[11]), shader) - , m_range(LCSEED.arg(lightRef, lconstantnames[12]), shader) - , m_width(LCSEED.arg(lightRef, lconstantnames[13]), shader) - , m_height(LCSEED.arg(lightRef, lconstantnames[14]), shader) - , m_shadowControls(LCSEED.arg(lightRef, lconstantnames[15]), shader) - , m_shadowView(LCSEED.arg(lightRef, lconstantnames[16]), shader) - , m_shadowIdx(LCSEED.arg(lightRef, lconstantnames[17]), shader) - , m_attenuation(LCSEED.arg(lightRef, lconstantnames[18]), shader) - { - - } - - template - void updateLights(LightProps &props) - { - m_position.Set(props.m_position); - m_direction.Set(props.m_direction); - m_up.Set(props.m_up); - m_right.Set(props.m_right); - m_diffuse.Set(props.m_diffuse); - m_ambient.Set(props.m_ambient); - m_specular.Set(props.m_specular); - m_spotExponent.Set(props.m_spotExponent); - m_spotCutoff.Set(props.m_spotCutoff); - m_constantAttenuation.Set(props.m_constantAttenuation); - m_linearAttenuation.Set(props.m_linearAttenuation); - m_quadraticAttenuation.Set(props.m_quadraticAttenuation); - m_range.Set(props.m_range); - m_width.Set(props.m_width); - m_height.Set(props.m_height); - m_shadowControls.Set(props.m_shadowControls); - m_shadowView.Set(props.m_shadowView); - m_shadowIdx.Set(props.m_shadowIdx); - m_attenuation.Set(QT3DSVec3(props.m_constantAttenuation, - props.m_linearAttenuation, - props.m_quadraticAttenuation)); - } - }; - - SLightConstantProperties(GeneratedShader &shader, bool packed) - : m_lightCount("uNumLights", shader.m_Shader) - { - m_constants.resize(shader.m_Lights.size()); - for (unsigned int i = 0; i < shader.m_Lights.size(); ++i) { - QString lref; - if (packed) - lref = QStringLiteral("light_%1_"); - else - lref = QStringLiteral("lights[%1]."); - lref = lref.arg(i); - m_constants[i] = new LightConstants(lref, shader.m_Shader); - } - m_lightCount.Set(shader.m_Lights.size()); - m_lightCountInt = shader.m_Lights.size(); - } - - SLightConstantProperties(const QString &lseed, const QString &lcount, - GeneratedShader &shader, bool packed, int count) - : m_lightCount(lcount, shader.m_Shader) - { - m_constants.resize(count); - for (int i = 0; i < count; ++i) { - QString lref; - if (packed) - lref = lseed + QStringLiteral("_%1_"); - else - lref = lseed + QStringLiteral("[%1]."); - lref = lref.arg(i); - m_constants[i] = new LightConstants(lref, shader.m_Shader); - } - m_lightCount.Set(count); - m_lightCountInt = count; - } - - ~SLightConstantProperties() - { - qDeleteAll(m_constants); - } - - void updateLights(GeneratedShader &shader) - { - for (int i = 0; i < m_constants.size(); ++i) - m_constants[i]->updateLights(shader.m_Lights[i].m_LightData); - } - template - void updateLights(const QVector &props) - { - for (int i = 0; i < m_constants.size(); ++i) - m_constants[i]->updateLights(props[i]->m_LightData); - } - - QVector m_constants; - NVRenderCachedShaderProperty m_lightCount; - int m_lightCountInt; -}; - -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialHelpers.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialHelpers.h deleted file mode 100644 index afb799e7..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialHelpers.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_MATERIAL_HELPERS_H -#define QT3DS_RENDER_MATERIAL_HELPERS_H -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderReferencedMaterial.h" - -namespace qt3ds { -namespace render { - - inline bool IsMaterial(SGraphObject &obj) - { - return obj.m_Type == GraphObjectTypes::CustomMaterial - || obj.m_Type == GraphObjectTypes::DefaultMaterial - || obj.m_Type == GraphObjectTypes::ReferencedMaterial; - } - - inline bool IsMaterial(SGraphObject *obj) - { - if (obj) - return IsMaterial(*obj); - return false; - } - - inline bool IsImage(SGraphObject &obj) { return obj.m_Type == GraphObjectTypes::Image; } - - inline bool IsImage(SGraphObject *obj) - { - if (obj) - return IsImage(*obj); - return false; - } - - inline SGraphObject *GetNextMaterialSibling(SGraphObject *obj) - { - if (obj == NULL) - return NULL; - if (IsMaterial(obj) == false) { - QT3DS_ASSERT(false); - return NULL; - } - if (obj->m_Type == GraphObjectTypes::CustomMaterial) - return static_cast(obj)->m_NextSibling; - else if (obj->m_Type == GraphObjectTypes::DefaultMaterial) - return static_cast(obj)->m_NextSibling; - else - return static_cast(obj)->m_NextSibling; - } - - inline void SetNextMaterialSibling(SGraphObject &obj, SGraphObject *sibling) - { - if (IsMaterial(obj) == false) { - QT3DS_ASSERT(false); - return; - } - if (obj.m_Type == GraphObjectTypes::CustomMaterial) - static_cast(&obj)->m_NextSibling = sibling; - else if (obj.m_Type == GraphObjectTypes::DefaultMaterial) - static_cast(&obj)->m_NextSibling = sibling; - else - static_cast(&obj)->m_NextSibling = sibling; - } -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialShaderGenerator.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialShaderGenerator.h deleted file mode 100644 index e8b9880d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMaterialShaderGenerator.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_MATERIAL_SHADER_GENERATOR_H -#define QT3DS_RENDER_MATERIAL_SHADER_GENERATOR_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSRenderShaderKeys.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" - -namespace qt3ds { -namespace render { - -// these are our current shader limits -#define QT3DS_MAX_NUM_LIGHTS 16 -#define QT3DS_MAX_NUM_SHADOWS 8 - - // note this struct must exactly match the memory layout of the - // struct sampleLight.glsllib and sampleArea.glsllib. If you make changes here you need - // to adjust the code in sampleLight.glsllib and sampleArea.glsllib as well - struct SLightSourceShader - { - QT3DSVec4 m_position; - QT3DSVec4 m_direction; // Specifies the light direction in world coordinates. - QT3DSVec4 m_up; - QT3DSVec4 m_right; - QT3DSVec4 m_diffuse; - QT3DSVec4 m_ambient; - QT3DSVec4 m_specular; - QT3DSF32 m_spotExponent; // Specifies the intensity distribution of the light. - QT3DSF32 m_spotCutoff; // Specifies the maximum spread angle of the light. - QT3DSF32 m_constantAttenuation; // Specifies the constant light attenuation factor. - QT3DSF32 m_linearAttenuation; // Specifies the linear light attenuation factor. - QT3DSF32 m_quadraticAttenuation; // Specifies the quadratic light attenuation factor. - QT3DSF32 m_range; // Specifies the maximum distance of the light influence - QT3DSF32 m_width; // Specifies the width of the area light surface. - QT3DSF32 m_height; // Specifies the height of the area light surface; - QT3DSVec4 m_shadowControls; - QT3DSMat44 m_shadowView; - QT3DSI32 m_shadowIdx; - QT3DSF32 m_padding1[3]; - }; - - struct SLayerGlobalRenderProperties - { - const SLayer &m_Layer; - SCamera &m_Camera; - QT3DSVec3 m_CameraDirection; - NVDataRef m_Lights; - NVDataRef m_LightDirections; - Qt3DSShadowMap *m_ShadowMapManager; - NVRenderTexture2D *m_DepthTexture; - NVRenderTexture2D *m_SSaoTexture; - SImage *m_LightProbe; - SImage *m_LightProbe2; - QT3DSF32 m_ProbeHorizon; - QT3DSF32 m_ProbeBright; - QT3DSF32 m_Probe2Window; - QT3DSF32 m_Probe2Pos; - QT3DSF32 m_Probe2Fade; - QT3DSF32 m_ProbeFOV; - - SLayerGlobalRenderProperties(const SLayer &inLayer, SCamera &inCamera, - QT3DSVec3 inCameraDirection, NVDataRef inLights, - NVDataRef inLightDirections, - Qt3DSShadowMap *inShadowMapManager, - NVRenderTexture2D *inDepthTexture, - NVRenderTexture2D *inSSaoTexture, SImage *inLightProbe, - SImage *inLightProbe2, QT3DSF32 inProbeHorizon, - QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, - QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) - : m_Layer(inLayer) - , m_Camera(inCamera) - , m_CameraDirection(inCameraDirection) - , m_Lights(inLights) - , m_LightDirections(inLightDirections) - , m_ShadowMapManager(inShadowMapManager) - , m_DepthTexture(inDepthTexture) - , m_SSaoTexture(inSSaoTexture) - , m_LightProbe(inLightProbe) - , m_LightProbe2(inLightProbe2) - , m_ProbeHorizon(inProbeHorizon) - , m_ProbeBright(inProbeBright) - , m_Probe2Window(inProbe2Window) - , m_Probe2Pos(inProbe2Pos) - , m_Probe2Fade(inProbe2Fade) - , m_ProbeFOV(inProbeFOV) - { - } - }; - - class IMaterialShaderGenerator : public NVRefCounted - { - public: - struct SImageVariableNames - { - const char8_t *m_ImageSampler; - const char8_t *m_ImageFragCoords; - }; - - virtual SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) = 0; - virtual void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, - QT3DSU32 uvSet, SRenderableImage &image) = 0; - - // inPipelineName needs to be unique else the shader cache will just return shaders from - // different pipelines. - virtual NVRenderShaderProgram *GenerateShader( - const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, - IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, - NVDataRef inLights, SRenderableImage *inFirstImage, bool inHasTransparency, - const char8_t *inVertexPipelineName, const char8_t *inCustomMaterialName = "") = 0; - - // Also sets the blend function on the render context. - virtual void - SetMaterialProperties(NVRenderShaderProgram &inProgram, const SGraphObject &inMaterial, - const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - SLayerGlobalRenderProperties inRenderProperties) = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMesh.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMesh.h deleted file mode 100644 index d6959ec8..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderMesh.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_MESH_H -#define QT3DS_RENDER_MESH_H -#include "Qt3DSRender.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderIndexBuffer.h" -#include "render/Qt3DSRenderInputAssembler.h" -#include "foundation/Qt3DSBounds3.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSNoCopy.h" - -namespace qt3ds { -namespace render { - - struct SRenderSubsetBase - { - QT3DSU32 m_Count; - QT3DSU32 m_Offset; - NVBounds3 m_Bounds; // Vertex buffer bounds - SRenderSubsetBase() {} - SRenderSubsetBase(const SRenderSubsetBase &inOther) - : m_Count(inOther.m_Count) - , m_Offset(inOther.m_Offset) - , m_Bounds(inOther.m_Bounds) - { - } - - SRenderSubsetBase &operator=(const SRenderSubsetBase &inOther) - { - m_Count = inOther.m_Count; - m_Offset = inOther.m_Offset; - m_Bounds = inOther.m_Bounds; - return *this; - } - }; - - struct SRenderJoint - { - QT3DSI32 m_JointID; - QT3DSI32 m_ParentID; - QT3DSF32 m_invBindPose[16]; - QT3DSF32 m_localToGlobalBoneSpace[16]; - }; - - struct SRenderSubset : public SRenderSubsetBase - { - NVRenderInputAssembler *m_InputAssembler; - NVRenderInputAssembler *m_InputAssemblerDepth; - NVRenderInputAssembler - *m_InputAssemblerPoints; ///< similar to depth but ignores index buffer. - NVRenderVertexBuffer *m_VertexBuffer; - NVRenderVertexBuffer - *m_PosVertexBuffer; ///< separate position buffer for fast depth path rendering - NVRenderIndexBuffer *m_IndexBuffer; - NVRenderDrawMode::Enum m_PrimitiveType; ///< primitive type used for drawing - QT3DSF32 m_EdgeTessFactor; ///< edge tessellation amount used for tessellation shaders - QT3DSF32 m_InnerTessFactor; ///< inner tessellation amount used for tessellation shaders - bool m_WireframeMode; ///< true if we should draw the object as wireframe ( currently ony if - ///tessellation is enabled ) - NVConstDataRef m_Joints; - CRegisteredString m_Name; - nvvector m_SubSubsets; - - SRenderSubset(NVAllocatorCallback &alloc) - : m_InputAssembler(NULL) - , m_InputAssemblerDepth(NULL) - , m_InputAssemblerPoints(NULL) - , m_VertexBuffer(NULL) - , m_PosVertexBuffer(NULL) - , m_IndexBuffer(NULL) - , m_PrimitiveType(NVRenderDrawMode::Triangles) - , m_EdgeTessFactor(1.0) - , m_InnerTessFactor(1.0) - , m_WireframeMode(false) - , m_SubSubsets(alloc, "SRenderSubset::m_SubSubsets") - { - } - SRenderSubset(const SRenderSubset &inOther) - : SRenderSubsetBase(inOther) - , m_InputAssembler(inOther.m_InputAssembler) - , m_InputAssemblerDepth(inOther.m_InputAssemblerDepth) - , m_InputAssemblerPoints(inOther.m_InputAssemblerPoints) - , m_VertexBuffer(inOther.m_VertexBuffer) - , m_PosVertexBuffer(inOther.m_PosVertexBuffer) - , m_IndexBuffer(inOther.m_IndexBuffer) - , m_PrimitiveType(inOther.m_PrimitiveType) - , m_EdgeTessFactor(inOther.m_EdgeTessFactor) - , m_InnerTessFactor(inOther.m_InnerTessFactor) - , m_WireframeMode(inOther.m_WireframeMode) - , m_Joints(inOther.m_Joints) - , m_Name(inOther.m_Name) - , m_SubSubsets(inOther.m_SubSubsets) - { - } - // Note that subSubsets is *not* copied. - SRenderSubset(NVAllocatorCallback &alloc, const SRenderSubset &inOther, - const SRenderSubsetBase &inBase) - : SRenderSubsetBase(inBase) - , m_InputAssembler(inOther.m_InputAssembler) - , m_InputAssemblerDepth(inOther.m_InputAssemblerDepth) - , m_InputAssemblerPoints(inOther.m_InputAssemblerPoints) - , m_VertexBuffer(inOther.m_VertexBuffer) - , m_PosVertexBuffer(inOther.m_PosVertexBuffer) - , m_IndexBuffer(inOther.m_IndexBuffer) - , m_PrimitiveType(inOther.m_PrimitiveType) - , m_EdgeTessFactor(inOther.m_EdgeTessFactor) - , m_InnerTessFactor(inOther.m_InnerTessFactor) - , m_WireframeMode(inOther.m_WireframeMode) - , m_Name(inOther.m_Name) - , m_SubSubsets(alloc, "SRenderSubset::m_SubSubsets") - { - } - - SRenderSubset &operator=(const SRenderSubset &inOther) - { - if (this != &inOther) { - SRenderSubsetBase::operator=(inOther); - m_InputAssembler = inOther.m_InputAssembler; - m_InputAssemblerDepth = inOther.m_InputAssemblerDepth; - m_VertexBuffer = inOther.m_VertexBuffer; - m_PosVertexBuffer = inOther.m_PosVertexBuffer; - m_IndexBuffer = inOther.m_IndexBuffer; - m_PrimitiveType = inOther.m_PrimitiveType; - m_EdgeTessFactor = inOther.m_EdgeTessFactor; - m_InnerTessFactor = inOther.m_InnerTessFactor; - m_WireframeMode = inOther.m_WireframeMode; - m_Joints = inOther.m_Joints; - m_Name = inOther.m_Name; - m_SubSubsets = inOther.m_SubSubsets; - } - return *this; - } - }; - - struct SRenderMesh : public NoCopy - { - nvvector m_Subsets; - nvvector m_Joints; - NVRenderDrawMode::Enum m_DrawMode; - NVRenderWinding::Enum m_Winding; // counterclockwise - QT3DSU32 m_MeshId; // Id from the file of this mesh. - - SRenderMesh(NVRenderDrawMode::Enum inDrawMode, NVRenderWinding::Enum inWinding, - QT3DSU32 inMeshId, NVAllocatorCallback &alloc) - : m_Subsets(alloc, "SRenderMesh::m_Subsets") - , m_Joints(alloc, "SRenderMesh::Joints") - , m_DrawMode(inDrawMode) - , m_Winding(inWinding) - , m_MeshId(inMeshId) - { - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathManager.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathManager.h deleted file mode 100644 index fc7e05f1..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathManager.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PATH_MANAGER_H -#define QT3DS_RENDER_PATH_MANAGER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderShaderCache.h" //TShaderFeatureSet -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSBounds3.h" -//#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" //SLayerGlobalRenderProperties - -namespace qt3ds { -namespace render { - - struct SLayerGlobalRenderProperties; - - struct SPathAnchorPoint - { - QT3DSVec2 m_Position; - QT3DSF32 m_IncomingAngle; - QT3DSF32 m_OutgoingAngle; - QT3DSF32 m_IncomingDistance; - QT3DSF32 m_OutgoingDistance; - SPathAnchorPoint() {} - SPathAnchorPoint(QT3DSVec2 inPos, QT3DSF32 inAngle, QT3DSF32 outAngle, QT3DSF32 inDis, QT3DSF32 outDis) - : m_Position(inPos) - , m_IncomingAngle(inAngle) - , m_OutgoingAngle(outAngle) - , m_IncomingDistance(inDis) - , m_OutgoingDistance(outDis) - { - } - }; - - class IPathManagerCore : public NVRefCounted - { - public: - // returns the path buffer id - //!! Note this call is made from multiple threads simultaneously during binary load. - //!! - see UICRenderGraphObjectSerializer.cpp - virtual void - SetPathSubPathData(const SPathSubPath &inPathSubPath, - NVConstDataRef inPathSubPathAnchorPoints) = 0; - - virtual NVDataRef - GetPathSubPathBuffer(const SPathSubPath &inPathSubPath) = 0; - // Marks the PathSubPath anchor points as dirty. This will mean rebuilding any PathSubPath - // context required to render the PathSubPath. - virtual NVDataRef - ResizePathSubPathBuffer(const SPathSubPath &inPathSubPath, QT3DSU32 inNumAnchors) = 0; - virtual NVBounds3 GetBounds(const SPath &inPath) = 0; - - // Helper functions used in various locations - // Angles here are in degrees because that is how they are represented in the data. - static QT3DSVec2 GetControlPointFromAngleDistance(QT3DSVec2 inPosition, float inAngle, - float inDistance); - - // Returns angle in x, distance in y. - static QT3DSVec2 GetAngleDistanceFromControlPoint(QT3DSVec2 inPosition, QT3DSVec2 inControlPoint); - - virtual IPathManager &OnRenderSystemInitialize(IQt3DSRenderContext &context) = 0; - - static IPathManagerCore &CreatePathManagerCore(IQt3DSRenderContextCore &inContext); - }; - - struct SPathRenderContext; // UICRenderPathRenderContext.h - - class IPathManager : public IPathManagerCore - { - public: - // The path segments are next expected to change after this call; changes will be ignored. - virtual bool PrepareForRender(const SPath &inPath) = 0; - - virtual void RenderDepthPrepass(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) = 0; - - virtual void RenderShadowMapPass(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) = 0; - - virtual void RenderCubeFaceShadowPass(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) = 0; - - virtual void RenderPath(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) = 0; - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathMath.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathMath.h deleted file mode 100644 index e9eb2220..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathMath.h +++ /dev/null @@ -1,713 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_RENDER_PATH_MATH_H -#define QT3DS_RENDER_PATH_MATH_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec3.h" -namespace qt3ds { -namespace render { -namespace path { -// Solve quadratic equation in with a templated real number system. -template - -int quadratic(REAL b, REAL c, REAL rts[2]) -{ - int nquad; - REAL dis; - REAL rtdis; - - dis = b * b - 4 * c; - rts[0] = 0; - rts[1] = 0; - if (b == 0) { - if (c == 0) { - nquad = 2; - } else { - if (c < 0) { - nquad = 2; - rts[0] = sqrt(-c); - rts[1] = -rts[0]; - } else { - nquad = 0; - } - } - } else if (c == 0) { - nquad = 2; - rts[0] = -b; - } else if (dis >= 0) { - nquad = 2; - rtdis = sqrt(dis); - if (b > 0) - rts[0] = (-b - rtdis) * (1 / REAL(2)); - else - rts[0] = (-b + rtdis) * (1 / REAL(2)); - if (rts[0] == 0) - rts[1] = -b; - else - rts[1] = c / rts[0]; - } else { - nquad = 0; - } - - return (nquad); -} /* quadratic */ - -float interest_range[2] = {0, 1}; - -void cubicInflectionPoint(const QT3DSVec2 cp[4], nvvector &key_point) -{ - // Convert control points to cubic monomial polynomial coefficients - const QT3DSVec2 A = cp[3] - cp[0] + (cp[1] - cp[2]) * 3.0; - const QT3DSVec2 B = (cp[0] - cp[1] * 2.0 + cp[2]) * 3.0, C = (cp[1] - cp[0]) * 3.0; - const QT3DSVec2 D = cp[0]; - - double a = 3 * (B.x * A.y - A.x * B.y); - double b = 3 * (C.x * A.y - C.y * A.x); - double c = C.x * B.y - C.y * B.x; - - double roots[2]; - int solutions; - // Is the quadratic really a degenerate line? - if (a == 0) { - // Is the line really a degenerate point? - if (b == 0) { - solutions = 0; - } else { - solutions = 1; - roots[0] = c / b; - } - } else { - solutions = quadratic(b / a, c / a, roots); - } - for (int i = 0; i < solutions; i++) { - QT3DSF32 t = static_cast(roots[i]); - - QT3DSVec2 p = ((A * t + B) * t + C) * t + D; - if (t >= interest_range[0] && t <= interest_range[1]) - key_point.push_back(t); - // else; Outside range of interest, ignore. - } -} - -typedef enum { - CT_POINT, - CT_LINE, - CT_QUADRATIC, - CT_CUSP, - CT_LOOP, - CT_SERPENTINE -} CurveType; - -static inline bool isZero(double v) -{ -#if 0 - const double eps = 6e-008; - - if (fabs(v) < eps) - return true; - else - return false; -#else - return v == 0.0; -#endif -} - -inline QT3DSVec3 crossv1(const QT3DSVec2 &a, const QT3DSVec2 &b) -{ - return QT3DSVec3(a[1] - b[1], b[0] - a[0], a[0] * b[1] - a[1] * b[0]); -} - -inline bool sameVertex(const QT3DSVec2 &a, const QT3DSVec2 &b) -{ - return (a.x == b.x && a.y == b.y); -} - -inline bool sameVertex(const QT3DSVec3 &a, const QT3DSVec3 &b) -{ - return (a.x == b.x && a.y == b.y && a.z == b.z); -} - -// This function "normalizes" the input vector so the larger of its components -// is in the range [512,1024]. Exploit integer math on the exponent bits to -// do this without expensive DP exponentiation. -inline void scaleTo512To1024(QT3DSVec2 &d, int e) -{ - union { - QT3DSU64 u64; - double f64; - } x; - int ie = 10 - (int)e + 1023; - QT3DS_ASSERT(ie > 0); - x.u64 = ((QT3DSU64)ie) << 52; - d *= static_cast(x.f64); -} - -inline double fastfrexp(double d, int *exponent) -{ - union { - QT3DSU64 u64; - double f64; - } x; - x.f64 = d; - *exponent = (((int)(x.u64 >> 52)) & 0x7ff) - 0x3ff; - x.u64 &= (1ULL << 63) - (1ULL << 52); - x.u64 |= (0x3ffULL << 52); - return x.f64; -} - -QT3DSVec3 CreateVec3(QT3DSVec2 xy, float z) -{ - return QT3DSVec3(xy.x, xy.y, z); -} - -QT3DSVec2 GetXY(const QT3DSVec3 &data) -{ - return QT3DSVec2(data.x, data.y); -} - -CurveType cubicDoublePoint(const QT3DSVec2 points[4], nvvector &key_point) -{ -#if 0 - const QT3DSVec2 AA = points[3] - points[0] + (points[1] - points[2]) * 3.0; - const QT3DSVec3 BB = (points[0] - points[1] * 2.0 + points[2]) * 3.0; - const QT3DSVec3 CC = (points[1] - points[0]) * 3.0, DD = points[0]; -#endif - - // Assume control points of the cubic curve are A, B, C, and D. - const QT3DSVec3 A = CreateVec3(points[0], 1); - const QT3DSVec3 B = CreateVec3(points[1], 1); - const QT3DSVec3 C = CreateVec3(points[2], 1); - const QT3DSVec3 D = CreateVec3(points[3], 1); - - // Compute the discriminant of the roots of - // H(s,t) = -36*(d1^2*s^2 - d1*d2*s*t + (d2^2 - d1*d3)*t^2) - // where H is the Hessian (the square matrix of second-order - // partial derivatives of a function) of I(s,t) - // where I(s,t) determine the inflection points of the cubic - // Bezier curve C(s,t). - // - // d1, d2, and d3 functions of the determinants constructed - // from the cubic control points. - // - // Recall dot(a,cross(b,c)) is determinant of a 3x3 matrix - // with a, b, c the rows of the matrix. - const QT3DSVec3 DC = crossv1(GetXY(D), GetXY(C)); - const QT3DSVec3 AD = crossv1(GetXY(A), GetXY(D)); - const QT3DSVec3 BA = crossv1(GetXY(B), GetXY(A)); - - const double a1 = A.dot(DC); - const double a2 = B.dot(AD); - const double a3 = C.dot(BA); - const double d1 = a1 - 2 * a2 + 3 * a3; - const double d2 = -a2 + 3 * a3; - const double d3 = 3 * a3; - const double discriminant = (3 * d2 * d2 - 4 * d1 * d3); - - // The sign of the discriminant of I classifies the curbic curve - // C into one of 6 classifications: - // 1) discriminant>0 ==> serpentine - // 2) discriminant=0 ==> cusp - // 3) discriminant<0 ==> loop - - // If the discriminant or d1 are almost but not exactly zero, the - // result is really noisy unacceptable (k,l,m) interpolation. - // If it looks almost like a quadratic or linear case, treat it that way. - if (isZero(discriminant) && isZero(d1)) { - // Cusp case - - if (isZero(d2)) { - // degenerate cases (points, lines, quadratics)... - if (isZero(d3)) { - if (sameVertex(A, B) && sameVertex(A, C) && sameVertex(A, D)) - return CT_POINT; - else - return CT_LINE; - } else { - return CT_QUADRATIC; - } - } else { - return CT_CUSP; - } - } else if (discriminant < 0) { - // Loop case - - const QT3DSF32 t = static_cast(d2 + sqrt(-discriminant)); - QT3DSVec2 d = QT3DSVec2(t, static_cast(2 * d1)); - QT3DSVec2 e = QT3DSVec2(static_cast(2 * (d2 * d2 - d1 * d3)), - static_cast(d1 * t)); - - // There is the situation where r2=c/t results in division by zero, but - // in this case, the two roots represent a double root at zero so - // subsitute l for (the otherwise NaN) m in this case. - // - // This situation can occur when the 1st and 2nd (or 3rd and 4th?) - // control point of a cubic Bezier path SubPath are identical. - if (e.x == 0 && e.y == 0) - e = d; - - // d, e, or both could be very large values. To mitigate the risk of - // floating-point overflow in subsequent calculations - // scale both vectors to be in the range [768,1024] since their relative - // scale of their x & y components is irrelevant. - - // Be careful to divide by a power-of-two to disturb mantissa bits. - - double d_max_mag = NVMax(fabs(d.x), fabs(d.y)); - int exponent; - fastfrexp(d_max_mag, &exponent); - scaleTo512To1024(d, exponent); - - double e_max_mag = NVMax(fabs(e.x), fabs(e.y)); - fastfrexp(e_max_mag, &exponent); - scaleTo512To1024(e, exponent); - - const QT3DSVec2 roots = QT3DSVec2(d.x / d.y, e.x / e.y); - - double tt; -#if 0 - tt = roots[0]; - if (tt >= interest_range[0] && tt <= interest_range[1]) - // key_point.push_back(tt); - tt = roots[1]; - if (tt >= interest_range[0] && tt <= interest_range[1]) - // key_point.push_back(tt); -#endif - tt = (roots[0] + roots[1]) / 2; - if (tt >= interest_range[0] && tt <= interest_range[1]) - key_point.push_back(static_cast(tt)); - - return CT_LOOP; - } else { - QT3DS_ASSERT(discriminant >= 0); - cubicInflectionPoint(points, key_point); - if (discriminant > 0) { - // Serpentine case - return CT_SERPENTINE; - } else { - // Cusp with inflection at infinity (treat like serpentine) - return CT_CUSP; - } - } -} - -QT3DSVec4 CreateVec4(QT3DSVec2 p1, QT3DSVec2 p2) -{ - return QT3DSVec4(p1.x, p1.y, p2.x, p2.y); -} - -QT3DSVec2 lerp(QT3DSVec2 p1, QT3DSVec2 p2, QT3DSF32 distance) -{ - return p1 + (p2 - p1) * distance; -} - -QT3DSF32 lerp(QT3DSF32 p1, QT3DSF32 p2, QT3DSF32 distance) -{ - return p1 + (p2 - p1) * distance; -} - -// Using first derivative to get tangent. -// If this equation does not make immediate sense consider that it is the first derivative -// of the de Casteljau bezier expansion, not the polynomial expansion. -float TangentAt(float inT, float p1, float c1, float c2, float p2) -{ - float a = c1 - p1; - float b = c2 - c1 - a; - float c = p2 - c2 - a - (2.0f * b); - float retval = 3.0f * (a + (2.0f * b * inT) + (c * inT * inT)); - return retval; -} - -QT3DSVec2 midpoint(QT3DSVec2 p1, QT3DSVec2 p2) -{ - return lerp(p1, p2, .5f); -} - -QT3DSF32 LineLength(QT3DSVec2 inStart, QT3DSVec2 inStop) -{ - return (inStop - inStart).magnitude(); -} - -struct SCubicBezierCurve -{ - QT3DSVec2 m_Points[4]; - SCubicBezierCurve(QT3DSVec2 a1, QT3DSVec2 c1, QT3DSVec2 c2, QT3DSVec2 a2) - { - m_Points[0] = a1; - m_Points[1] = c1; - m_Points[2] = c2; - m_Points[3] = a2; - } - - // Normal is of course orthogonal to the tangent. - QT3DSVec2 NormalAt(float inT) const - { - QT3DSVec2 tangent = QT3DSVec2( - TangentAt(inT, m_Points[0].x, m_Points[1].x, m_Points[2].x, m_Points[3].x), - TangentAt(inT, m_Points[0].y, m_Points[1].y, m_Points[2].y, m_Points[3].y)); - - QT3DSVec2 result(tangent.y, -tangent.x); - result.normalize(); - return result; - } - - eastl::pair SplitCubicBezierCurve(float inT) - { - // compute point on curve based on inT - // using de Casteljau algorithm - QT3DSVec2 p12 = lerp(m_Points[0], m_Points[1], inT); - QT3DSVec2 p23 = lerp(m_Points[1], m_Points[2], inT); - QT3DSVec2 p34 = lerp(m_Points[2], m_Points[3], inT); - QT3DSVec2 p123 = lerp(p12, p23, inT); - QT3DSVec2 p234 = lerp(p23, p34, inT); - QT3DSVec2 p1234 = lerp(p123, p234, inT); - - return eastl::make_pair(SCubicBezierCurve(m_Points[0], p12, p123, p1234), - SCubicBezierCurve(p1234, p234, p34, m_Points[3])); - } -}; - -#if 0 - static QT3DSVec2 NormalToLine( QT3DSVec2 startPoint, QT3DSVec2 endPoint ) - { - QT3DSVec2 lineDxDy = endPoint - startPoint; - QT3DSVec2 result( lineDxDy.y, -lineDxDy.x ); - result.normalize(); - return result; - } -#endif - -struct SResultCubic -{ - enum Mode { - Normal = 0, - BeginTaper = 1, - EndTaper = 2, - }; - QT3DSVec2 m_P1; - QT3DSVec2 m_C1; - QT3DSVec2 m_C2; - QT3DSVec2 m_P2; - // Location in the original data where this cubic is taken from - QT3DSU32 m_EquationIndex; - QT3DSF32 m_TStart; - QT3DSF32 m_TStop; - QT3DSF32 m_Length; - QT3DSVec2 m_TaperMultiplier; // normally 1, goes to zero at very end of taper if any taper. - Mode m_Mode; - - SResultCubic(QT3DSVec2 inP1, QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inP2, - QT3DSU32 equationIndex, QT3DSF32 tStart, QT3DSF32 tStop, QT3DSF32 length) - : m_P1(inP1) - , m_C1(inC1) - , m_C2(inC2) - , m_P2(inP2) - , m_EquationIndex(equationIndex) - , m_TStart(tStart) - , m_TStop(tStop) - , m_Length(length) - , m_TaperMultiplier(1.0f, 1.0f) - , m_Mode(Normal) - { - } - // Note the vec2 items are *not* initialized in any way here. - SResultCubic() {} - QT3DSF32 GetP1Width(QT3DSF32 inPathWidth, QT3DSF32 beginTaperWidth, QT3DSF32 endTaperWidth) - { - return GetPathWidth(inPathWidth, beginTaperWidth, endTaperWidth, 0); - } - - QT3DSF32 GetP2Width(QT3DSF32 inPathWidth, QT3DSF32 beginTaperWidth, QT3DSF32 endTaperWidth) - { - return GetPathWidth(inPathWidth, beginTaperWidth, endTaperWidth, 1); - } - - QT3DSF32 GetPathWidth(QT3DSF32 inPathWidth, QT3DSF32 beginTaperWidth, QT3DSF32 endTaperWidth, - QT3DSU32 inTaperIndex) - { - QT3DSF32 retval = inPathWidth; - switch (m_Mode) { - case BeginTaper: - retval = beginTaperWidth * m_TaperMultiplier[inTaperIndex]; - break; - case EndTaper: - retval = endTaperWidth * m_TaperMultiplier[inTaperIndex]; - break; - default: - break; - } - return retval; - } -}; - -void PushLine(nvvector &ioResultVec, QT3DSVec2 inStart, QT3DSVec2 inStop, - QT3DSU32 inEquationIndex) -{ - QT3DSVec2 range = inStop - inStart; - ioResultVec.push_back(SResultCubic(inStart, inStart + range * .333f, - inStart + range * .666f, inStop, inEquationIndex, - 0.0f, 1.0f, LineLength(inStart, inStop))); -} - -struct PathDirtyFlagValues -{ - enum Enum { - SourceData = 1, - PathType = 1 << 1, - Width = 1 << 2, - BeginTaper = 1 << 3, - EndTaper = 1 << 4, - CPUError = 1 << 5, - }; -}; - -struct SPathDirtyFlags : public NVFlags -{ - typedef NVFlags TBase; - SPathDirtyFlags() {} - SPathDirtyFlags(int inFlags) - : TBase(static_cast(inFlags)) - { - } - void Clear() - { - *this = SPathDirtyFlags(); - } -}; - -struct STaperInformation -{ - QT3DSF32 m_CapOffset; - QT3DSF32 m_CapOpacity; - QT3DSF32 m_CapWidth; - - STaperInformation() - : m_CapOffset(0) - , m_CapOpacity(0) - , m_CapWidth(0) - { - } - STaperInformation(QT3DSF32 capOffset, QT3DSF32 capOpacity, QT3DSF32 capWidth) - : m_CapOffset(capOffset) - , m_CapOpacity(capOpacity) - , m_CapWidth(capWidth) - { - } - - bool operator==(const STaperInformation &inOther) const - { - return m_CapOffset == inOther.m_CapOffset && m_CapOpacity == inOther.m_CapOpacity - && m_CapWidth == inOther.m_CapWidth; - } -}; - -template -bool OptionEquals(const Option &lhs, const Option &rhs) -{ - if (lhs.hasValue() != rhs.hasValue()) - return false; - if (lhs.hasValue()) - return lhs.getValue() == rhs.getValue(); - return true; -} -void OuterAdaptiveSubdivideBezierCurve(nvvector &ioResultVec, - nvvector &keyPointVec, - SCubicBezierCurve inCurve, QT3DSF32 inLinearError, - QT3DSU32 inEquationIndex); - -void AdaptiveSubdivideBezierCurve(nvvector &ioResultVec, - SCubicBezierCurve &inCurve, QT3DSF32 inLinearError, - QT3DSU32 inEquationIndex, QT3DSF32 inTStart, QT3DSF32 inTStop); - -// Adaptively subdivide source data to produce m_PatchData. -void AdaptiveSubdivideSourceData(NVConstDataRef inSourceData, - nvvector &ioResultVec, - nvvector &keyPointVec, QT3DSF32 inLinearError) -{ - ioResultVec.clear(); - if (inSourceData.size() < 2) - return; - // Assuming no attributes in the source data. - QT3DSU32 numEquations = (inSourceData.size() - 1); - for (QT3DSU32 idx = 0, end = numEquations; idx < end; ++idx) { - const SPathAnchorPoint &beginAnchor = inSourceData[idx]; - const SPathAnchorPoint &endAnchor = inSourceData[idx + 1]; - - QT3DSVec2 anchor1(beginAnchor.m_Position); - QT3DSVec2 control1(IPathManagerCore::GetControlPointFromAngleDistance( - beginAnchor.m_Position, beginAnchor.m_OutgoingAngle, - beginAnchor.m_OutgoingDistance)); - - QT3DSVec2 control2(IPathManagerCore::GetControlPointFromAngleDistance( - endAnchor.m_Position, endAnchor.m_IncomingAngle, - endAnchor.m_IncomingDistance)); - QT3DSVec2 anchor2(endAnchor.m_Position); - - OuterAdaptiveSubdivideBezierCurve( - ioResultVec, keyPointVec, - SCubicBezierCurve(anchor1, control1, control2, anchor2), inLinearError, idx); - } -} - -// The outer subdivide function topologically analyzes the curve to ensure that -// the sign of the second derivative does not change, no inflection points. -// Once that condition is held, then we proceed with a simple adaptive subdivision algorithm -// until the curve is accurately approximated by a straight line. -void OuterAdaptiveSubdivideBezierCurve(nvvector &ioResultVec, - nvvector &keyPointVec, - SCubicBezierCurve inCurve, QT3DSF32 inLinearError, - QT3DSU32 inEquationIndex) -{ - // Step 1, find what type of curve we are dealing with and the inflection points. - keyPointVec.clear(); - CurveType theCurveType = cubicDoublePoint(inCurve.m_Points, keyPointVec); - - QT3DSF32 tStart = 0; - switch (theCurveType) { - case CT_POINT: - ioResultVec.push_back(SResultCubic(inCurve.m_Points[0], inCurve.m_Points[0], - inCurve.m_Points[0], inCurve.m_Points[0], - inEquationIndex, 0.0f, 1.0f, 0.0f)); - return; // don't allow further recursion - case CT_LINE: - PushLine(ioResultVec, inCurve.m_Points[0], inCurve.m_Points[3], inEquationIndex); - return; // don't allow further recursion - case CT_CUSP: - case CT_LOOP: - case CT_SERPENTINE: { - // Break the curve at the inflection points if there is one. If there aren't - // inflection points - // the treat as linear (degenerate case that should not happen except in limiting - // ranges of floating point accuracy) - if (!keyPointVec.empty()) { - // It is not clear that the code results in a sorted vector, - // or a vector where all values are within the range of 0-1 - if (keyPointVec.size() > 1) - eastl::sort(keyPointVec.begin(), keyPointVec.end()); - for (QT3DSU32 idx = 0, end = (QT3DSU32)keyPointVec.size(); - idx < end && keyPointVec[idx] < 1.0f; ++idx) { - // We have a list of T values I believe sorted from beginning to end, we - // will create a set of bezier curves - // Since we split the curves, tValue is relative to tSTart, not 0. - QT3DSF32 range = 1.0f - tStart; - QT3DSF32 splitPoint = keyPointVec[idx] - tStart; - QT3DSF32 tValue = splitPoint / range; - if (tValue > 0.0f) { - eastl::pair newCurves - = inCurve.SplitCubicBezierCurve(tValue); - AdaptiveSubdivideBezierCurve(ioResultVec, newCurves.first, - inLinearError, inEquationIndex, tStart, - splitPoint); - inCurve = newCurves.second; - tStart = splitPoint; - } - } - } - } - // fallthrough intentional - break; - // fallthrough intentional - case CT_QUADRATIC: - break; - } - AdaptiveSubdivideBezierCurve(ioResultVec, inCurve, inLinearError, inEquationIndex, - tStart, 1.0f); -} - -static QT3DSF32 DistanceFromPointToLine(QT3DSVec2 inLineDxDy, QT3DSVec2 lineStart, QT3DSVec2 point) -{ - QT3DSVec2 pointToLineStart = lineStart - point; - return fabs((inLineDxDy.x * pointToLineStart.y) - (inLineDxDy.y * pointToLineStart.x)); -} - -// There are two options here. The first is to just subdivide below a given error -// tolerance. -// The second is to fit a quadratic to the curve and then precisely find the length of the -// quadratic. -// Obviously we are choosing the subdivide method at this moment but I think the fitting -// method is probably more robust. -QT3DSF32 LengthOfBezierCurve(SCubicBezierCurve &inCurve) -{ - // Find distance of control points from line. Note that both control points should be - // on same side of line else we have a serpentine which should have been removed by topological - // analysis. - QT3DSVec2 lineDxDy = inCurve.m_Points[3] - inCurve.m_Points[0]; - QT3DSF32 c1Distance = DistanceFromPointToLine( - lineDxDy, inCurve.m_Points[0], inCurve.m_Points[1]); - QT3DSF32 c2Distance = DistanceFromPointToLine( - lineDxDy, inCurve.m_Points[0], inCurve.m_Points[2]); - const float lineTolerance = 100.0f; // error in world coordinates, squared. - if (c1Distance > lineTolerance || c2Distance > lineTolerance) { - eastl::pair subdivCurve - = inCurve.SplitCubicBezierCurve(.5f); - return LengthOfBezierCurve(subdivCurve.first) - + LengthOfBezierCurve(subdivCurve.second); - } else { - return LineLength(inCurve.m_Points[0], inCurve.m_Points[3]); - } -} - -// The assumption here is the the curve type is not cusp, loop, or serpentine. -// It is either linear or it is a constant curve meaning we can use very simple means to -// figure out the curvature. There is a possibility to use some math to figure out the point of -// maximum curvature, where the second derivative will have a max value. This is probably not -// necessary. -void AdaptiveSubdivideBezierCurve(nvvector &ioResultVec, - SCubicBezierCurve &inCurve, QT3DSF32 inLinearError, - QT3DSU32 inEquationIndex, QT3DSF32 inTStart, QT3DSF32 inTStop) -{ - // Find distance of control points from line. Note that both control points should be - // on same side of line else we have a serpentine which should have been removed by topological - // analysis. - QT3DSVec2 lineDxDy = inCurve.m_Points[3] - inCurve.m_Points[0]; - QT3DSF32 c1Distance = DistanceFromPointToLine(lineDxDy, inCurve.m_Points[0], - inCurve.m_Points[1]); - QT3DSF32 c2Distance = DistanceFromPointToLine(lineDxDy, inCurve.m_Points[0], - inCurve.m_Points[2]); - const float lineTolerance = inLinearError * inLinearError; // error in world coordinates - if (c1Distance > lineTolerance || c2Distance > lineTolerance) { - eastl::pair subdivCurve - = inCurve.SplitCubicBezierCurve(.5f); - QT3DSF32 halfway = lerp(inTStart, inTStop, .5f); - AdaptiveSubdivideBezierCurve(ioResultVec, subdivCurve.first, inLinearError, - inEquationIndex, inTStart, halfway); - AdaptiveSubdivideBezierCurve(ioResultVec, subdivCurve.second, inLinearError, - inEquationIndex, halfway, inTStop); - } else { - ioResultVec.push_back(SResultCubic(inCurve.m_Points[0], inCurve.m_Points[1], - inCurve.m_Points[2], inCurve.m_Points[3], - inEquationIndex, inTStart, inTStop, - LengthOfBezierCurve(inCurve))); - } -} -} -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathRenderContext.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathRenderContext.h deleted file mode 100644 index deeea281..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPathRenderContext.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PATH_RENDER_CONTEXT_H -#define QT3DS_RENDER_PATH_RENDER_CONTEXT_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderShaderCache.h" //TShaderFeatureSet -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSBounds3.h" -#include "Qt3DSRenderShaderKeys.h" -#include "Qt3DSRenderableImage.h" - -namespace qt3ds { -namespace render { - - struct SPathRenderContext - { - // The lights and camera will not change per layer, - // so that information can be set once for all the shaders. - NVConstDataRef m_Lights; - const SCamera &m_Camera; - - // Per-object information. - const SPath &m_Path; - const QT3DSMat44 &m_ModelViewProjection; - const QT3DSMat44 &m_ModelMatrix; ///< model to world transformation - const QT3DSMat33 &m_NormalMatrix; - - QT3DSF32 m_Opacity; - const SGraphObject &m_Material; - SShaderDefaultMaterialKey m_MaterialKey; - SRenderableImage *m_FirstImage; - QT3DSVec2 m_CameraVec; - - bool m_EnableWireframe; - bool m_HasTransparency; - bool m_IsStroke; - - SPathRenderContext(NVConstDataRef lights, const SCamera &cam, const SPath &p, - const QT3DSMat44 &mvp, const QT3DSMat44 &world, const QT3DSMat33 &nm, - QT3DSF32 inOpacity, const SGraphObject &inMaterial, - SShaderDefaultMaterialKey inMaterialKey, SRenderableImage *inFirstImage, - bool inWireframe, QT3DSVec2 inCameraVec, bool inHasTransparency, - bool inIsStroke) - - : m_Lights(lights) - , m_Camera(cam) - , m_Path(p) - , m_ModelViewProjection(mvp) - , m_ModelMatrix(world) - , m_NormalMatrix(nm) - , m_Opacity(inOpacity) - , m_Material(inMaterial) - , m_MaterialKey(inMaterialKey) - , m_FirstImage(inFirstImage) - , m_CameraVec(inCameraVec) - , m_EnableWireframe(inWireframe) - , m_HasTransparency(inHasTransparency) - , m_IsStroke(inIsStroke) - { - } - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsRenderer.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsRenderer.h deleted file mode 100644 index b37cb26b..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsRenderer.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PIXEL_GRAPHICS_RENDERER_H -#define QT3DS_RENDER_PIXEL_GRAPHICS_RENDERER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace render { - - // Pixel graphics are graphics described in pixels. - // Colors are expected to be non-premultiplied, we use ROP - // hardware to do the alpha multiply into the color. - class IPixelGraphicsRenderer : public NVRefCounted - { - public: - // Renders the node to the current viewport. - virtual void Render(NVConstDataRef inObjects) = 0; - - static IPixelGraphicsRenderer &CreateRenderer(IQt3DSRenderContext &ctx, IStringTable &strt); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsTypes.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsTypes.h deleted file mode 100644 index 2c154c18..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPixelGraphicsTypes.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PIXEL_GRAPHICS_TYPES_H -#define QT3DS_RENDER_PIXEL_GRAPHICS_TYPES_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec4.h" -#include "foundation/Qt3DSMat33.h" -#include "foundation/Qt3DSOption.h" - -namespace qt3ds { -namespace render { - - // Vector graphics with no scaling are pixel aligned with 0,0 being the bottom,left of the - // screen - // with coordinates increasing to the right and up. This is opposite most window systems but it - // preserves the normal openGL assumptions about viewports and positive Y going up in general. - struct SGTypes - { - enum Enum { - UnknownVGType = 0, - Layer, - Rect, - VertLine, - HorzLine, - }; - }; - - struct SPGGraphObject - { - SGTypes::Enum m_Type; - SPGGraphObject(SGTypes::Enum inType); - }; - - struct SPGRect : public SPGGraphObject - { - QT3DSF32 m_Left; - QT3DSF32 m_Top; - QT3DSF32 m_Right; - QT3DSF32 m_Bottom; - - QT3DSVec4 m_FillColor; - - SPGRect(); - }; - - struct SPGVertLine : public SPGGraphObject - { - QT3DSF32 m_X; - QT3DSF32 m_Top; - QT3DSF32 m_Bottom; - QT3DSVec4 m_LineColor; - void SetPosition(QT3DSF32 val) { m_X = val; } - void SetStart(QT3DSF32 val) { m_Bottom = val; } - void SetStop(QT3DSF32 val) { m_Top = val; } - - SPGVertLine(); - }; - - struct SPGHorzLine : public SPGGraphObject - { - QT3DSF32 m_Y; - QT3DSF32 m_Left; - QT3DSF32 m_Right; - QT3DSVec4 m_LineColor; - void SetPosition(QT3DSF32 val) { m_Y = val; } - void SetStart(QT3DSF32 val) { m_Left = val; } - void SetStop(QT3DSF32 val) { m_Right = val; } - - SPGHorzLine(); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPlugin.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPlugin.h deleted file mode 100644 index eb71f846..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPlugin.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PLUGIN_H -#define QT3DS_RENDER_PLUGIN_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderPluginCInterface.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "EASTL/utility.h" - -namespace qt3ds { -namespace render { - - // UICRenderPluginPropertyValue.h - struct SRenderPropertyValueUpdate; - - class IRenderPluginInstance : public IOffscreenRenderer - { - protected: - virtual ~IRenderPluginInstance() {} - public: - static const char *IRenderPluginOffscreenRendererType() { return "IRenderPluginInstance"; } - // If this render plugin has an instance ptr, get it. - virtual TRenderPluginInstancePtr GetRenderPluginInstance() = 0; - virtual void Update(NVConstDataRef updateBuffer) = 0; - virtual IRenderPluginClass &GetPluginClass() = 0; - virtual void CreateScriptProxy(script_State *state) = 0; - }; - struct RenderPluginPropertyValueTypes - { - enum Enum { - NoRenderPluginPropertyValue = 0, - Boolean, - Long, - Float, - String, - }; - }; - - struct SRenderPluginPropertyTypes - { - enum Enum { - UnknownRenderPluginPropertyType = 0, - Float, - Vector3, - Vector2, - Color, - Boolean, - Long, - String, - }; - }; - - struct SRenderPluginPropertyDeclaration - { - CRegisteredString m_Name; - SRenderPluginPropertyTypes::Enum m_Type; - // Filled in by the class, ignored if set on registered property - QT3DSU32 m_StartOffset; - SRenderPluginPropertyDeclaration() - : m_Type(SRenderPluginPropertyTypes::UnknownRenderPluginPropertyType) - { - } - SRenderPluginPropertyDeclaration(CRegisteredString n, SRenderPluginPropertyTypes::Enum t) - : m_Name(n) - , m_Type(t) - , m_StartOffset(0) - { - } - }; - - class IRenderPluginClass : public NVRefCounted - { - protected: - virtual ~IRenderPluginClass() {} - public: - virtual NVScopedRefCounted CreateInstance() = 0; - virtual void RegisterProperty(const SRenderPluginPropertyDeclaration &dec) = 0; - virtual NVConstDataRef GetRegisteredProperties() = 0; - // The declaration contains an offset - virtual SRenderPluginPropertyDeclaration - GetPropertyDeclaration(CRegisteredString inPropName) = 0; - // From which you can get the property name breakdown - virtual eastl::pair - GetPropertyValueInfo(QT3DSU32 inIndex) = 0; - }; - - class IRenderPluginManager; - - class IRenderPluginManagerCore : public NVRefCounted - { - public: - virtual void SetDllDir(const char *inDllDir) = 0; - virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t *inProjectDir) = 0; - virtual IRenderPluginManager &GetRenderPluginManager(NVRenderContext &rc) = 0; - - static IRenderPluginManagerCore &Create(NVFoundationBase &inFoundation, - IStringTable &strTable, - IInputStreamFactory &inFactory); - }; - - class IRenderPluginManager : public NVRefCounted - { - public: - virtual IRenderPluginClass *GetRenderPlugin(CRegisteredString inRelativePath) = 0; - virtual IRenderPluginClass *GetOrCreateRenderPlugin(CRegisteredString inRelativePath) = 0; - // Map a render plugin instance to this key. The instance's lifetime is managed by the - // manager so a client does not - // need to manage it. - virtual IRenderPluginInstance * - GetOrCreateRenderPluginInstance(CRegisteredString inRelativePath, void *inKey) = 0; - - virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, - const char8_t *inProjectDir) const = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginCInterface.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginCInterface.h deleted file mode 100644 index ec7481a0..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginCInterface.h +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_OBJECT_RENDER_PLUGIN_H -#define QT3DS_OBJECT_RENDER_PLUGIN_H - -/* - * Below are the definitions required in order to write a render plugin for UIComposer. - * Please note that calling anything related to opengl is explicitly not allowed except - * during either the class gl resource initialization function or during render. Calling into - * openGL and especially changing GL state during any other function may produce corrupt - *rendering. - */ - -#ifdef _cplusplus -#extern "C" { -#endif - -enum QT3DSRenderPluginPropertyTypes { - QT3DSRenderPluginPropertyTypeNone = 0, - QT3DSRenderPluginPropertyTypeLong = 1, - QT3DSRenderPluginPropertyTypeFloat = 2, - QT3DSRenderPluginPropertyTypeCharPtr = 3, -}; - -enum QT3DSRenderPluginDepthTypes { - QT3DSRenderPluginDepthTypeNoDepthBuffer = 0, - QT3DSRenderPluginDepthTypeDepth16, // 16 bit depth buffer - QT3DSRenderPluginDepthTypeDepth24, // 24 bit depth buffer - QT3DSRenderPluginDepthTypeDepth32, // 32 bit depth buffer -}; - -enum QT3DSRenderPluginTextureTypes { - QT3DSRenderPluginTextureTypeNoTexture = 0, - QT3DSRenderPluginTextureTypeRGBA8, // 32 bit format - QT3DSRenderPluginTextureTypeRGB8, // 24 bit format - QT3DSRenderPluginTextureTypeRGB565, // 16 bit format - QT3DSRenderPluginTextureTypeRGBA5551, // 16 bit format -}; - -enum QT3DSRenderPluginColorClearState { - QT3DSRenderPluginColorClearStateClearIsOptional = 0, - QT3DSRenderPluginColorClearStateDoNotClear, - QT3DSRenderPluginColorClearStateAlwaysClear, -}; - -enum QT3DSRenderPluginMSAALevel { - QT3DSRenderPluginMSAALevelNoMSAA = 0, // no MSAA, one also works. - QT3DSRenderPluginMSAALevelTwo = 2, // 2 samples - QT3DSRenderPluginMSAALevelFour = 4, // 4 samples - QT3DSRenderPluginMSAALevelEight = 8, // 8 samples -}; - -typedef long TBool; -#define TTRUE 1 -#define TFALSE 0 - -#define QT3DS_CURRENT_RENDER_PLUGIN_API_VERSION 2 - -typedef void *TRenderPluginInstancePtr; -typedef void *TRenderPluginClassPtr; - -// We will pass the componentized properties to the instance ptr. -typedef struct _RenderPluginPropertyUpdate -{ - const char *m_PropName; - enum QT3DSRenderPluginPropertyTypes m_PropertyType; - - // Is either a float or a long or a const char* depending on the property type. - // for specify types of properties, example code would be: - // float value = *((float*)&update.m_PropertyValue) - // long value = *((long*)&update.m_PropertyValue) - // char* value = (char*)update.m_PropertyValue - void *m_PropertyValue; -} TRenderPluginPropertyUpdate; - -typedef struct _RenderPluginSurfaceDescription -{ - long m_Width; - long m_Height; - enum QT3DSRenderPluginDepthTypes m_DepthBuffer; - enum QT3DSRenderPluginTextureTypes m_ColorBuffer; - TBool m_HasStencilBuffer; - QT3DSRenderPluginMSAALevel m_MSAALevel; -} TRenderPluginSurfaceDescription; - -typedef struct _TVec2 -{ - float x; - float y; -} TVec2; - -typedef struct _NeedsRenderResult -{ - TBool HasChangedSinceLastFrame; - TBool HasTransparency; -} TNeedsRenderResult; - -struct script_State; - -/* - * Create a new instance object. Typename is the name of the plugin file, so for example - * gears.plugin generates 'gears' as a type name. - * - * Required API function. - * - */ -typedef TRenderPluginInstancePtr (*TCreateInstanceFunction)(TRenderPluginClassPtr cls, - const char *inTypeName); - -typedef void (*TCreateInstanceScriptProxy)(TRenderPluginClassPtr cls, - TRenderPluginInstancePtr insPtr, - struct script_State *state); - -/* - * Update the plugin instance with a list of property updates. Properties are broken down by - *component so for example - * a color property named leftColor will be broken down into 'leftColor.r', 'leftColor.g', - *'leftColor.b'. Vector - * properties are broken down into x,y,z components. The property string has a void* member - *that is the actual value - * or in a charPtr property's case it is the char*. - * Please see the comments for m_PropertyValue member of TRenderPluginPropertyUpdate struct. - * - * Optional API function. - */ -typedef void (*TUpdateInstanceFunction)(TRenderPluginClassPtr cls, - TRenderPluginInstancePtr instance, - TRenderPluginPropertyUpdate *updates, long numUpdates); - -/* - * Query used when the plugin is rendering to an image. Should return the desired - *specifications of the plugins - * render target. - * presScaleFactor - the presentation scale factor when the user has requested scale to fit to - *be used for the - * presentation. - * - * Required API function. - */ -typedef TRenderPluginSurfaceDescription (*TSurfaceQueryFunction)(TRenderPluginClassPtr cls, - TRenderPluginInstancePtr instance, - TVec2 presScaleFactor); - -/* - * Query used by the rendering system. Should return true if the plugin will render something - *different than it did - * the last time it rendered. This is used so that we can cache render results and also so that we - *can trigger the - * progressive AA algorithm in the case where nothing has changed. - * - * presScaleFactor - the presentation scale factor when the user has requested scale to fit to be - *used for the - * presentation. - * - * OpenGL state may be changed in this function. - * - * Optional API function, returns true by default. - */ -typedef TNeedsRenderResult (*TNeedsRenderFunction)(TRenderPluginClassPtr cls, - TRenderPluginInstancePtr instance, - TRenderPluginSurfaceDescription surface, - TVec2 presScaleFactor); - -/* - * Render plugin data. - * Do not assume the surface requested is the surface given; for some cases it will be but if - *the system has deemed it - * appropriate to render the plugin directly to the back buffer then the surface description - *presented could differ by - * quite a bit. - * - * presScaleFactor - is the presentation scale factor when the user has requested scale to fit - *to be used for the - * presentation. - * inClearColorBuffer - True if the plugin needs to clear the color buffer (when rendering to - *texture) else false - * (when rendering to back buffer). - * - * Function should return 'UICTRUE' the image produced by rendering contains transparency; - *either every pixel wasn't - * written to or it is desired for the plugin to blend with background objects. Else should - *return UICFALSE. - * - * Required API function. - */ -typedef void (*TRenderFunction)(TRenderPluginClassPtr cls, TRenderPluginInstancePtr instance, - TRenderPluginSurfaceDescription surface, TVec2 presScaleFactor, - QT3DSRenderPluginColorClearState inClearColorBuffer); - -/* - * Pick - handle a mouse pick into the plugin. - * Returns true if the pick was consumed, false otherwise. - * - * Option API function. - */ -typedef TBool (*TPickFunction)(TRenderPluginClassPtr cls, TRenderPluginInstancePtr instance, - TVec2 inMouse, TVec2 inViewport); - -/* - * Release a given instance of the plugin. - * - * Required API function. - */ -typedef void (*TReleaseInstanceFunction)(TRenderPluginClassPtr cls, - TRenderPluginInstancePtr instance); - -/* - * Get the plugin API version. This allows the runtime to account for API changes over time or - * refuse to load the plugin. Plugins should return QT3DS_CURRENT_RENDER_PLUGIN_API_VERSION - * - * Required API function. - */ -typedef long (*TGetAPIVersionFunction)(TRenderPluginClassPtr cls); - -/* - * Initialize the resources for the class. Implementing this allows UIComposer to move - * expensive initialization outside of the actual presentation run, thus allowing for - * a smoother experience during the presentation at the cost of longer startup times. - * - * - plugin path is the path to the .plugin xml file so that clients can find resources - * specific to their plugin relative to their .plugin file. - * - * OpenGL state may be changed in this function. - * - * Optional API function. - */ -typedef void (*TInitializeClassGLResourcesFunction)(TRenderPluginClassPtr cls, - const char *pluginPath); - -/* - * Release the class allocated with the create proc provided in the shared library. - * - * Required API function. - */ -typedef void (*TReleaseClassFunction)(TRenderPluginClassPtr cls); - -/* - * Structure returned form the create class function. Unimplemented functions should be left - *NULL. - */ -typedef struct _RenderPluginClass -{ - TRenderPluginClassPtr m_Class; - - TGetAPIVersionFunction GetRenderPluginAPIVersion; - TInitializeClassGLResourcesFunction InitializeClassGLResources; - TReleaseClassFunction ReleaseClass; - - TCreateInstanceFunction CreateInstance; - TCreateInstanceScriptProxy CreateInstanceScriptProxy; - TUpdateInstanceFunction UpdateInstance; - TSurfaceQueryFunction QueryInstanceRenderSurface; - TNeedsRenderFunction NeedsRenderFunction; - TRenderFunction RenderInstance; - TPickFunction Pick; - TReleaseInstanceFunction ReleaseInstance; - -} TRenderPluginClass; - -// We look for this function name in the shared library -#define QT3DS_RENDER_PLUGIN_CREATE_CLASS_FUNCION_NAME "CreateRenderPlugin" - -/* - * Function signature we expect mapped to "CreateRenderPlugin". Example code: - * - extern "C" { - -#ifdef _WIN32 -#define PLUGIN_EXPORT_API __declspec(dllexport) -#else -#define PLUGIN_EXPORT_API -#endif - - - -PLUGIN_EXPORT_API TRenderPluginClass CreateRenderPlugin( const char*) -{ - GearClass* classItem = (GearClass*)malloc( sizeof(GearClass) ); - TRenderPluginClass retval; - memset( &retval, 0, sizeof( TRenderPluginClass ) ); - retval.m_Class = classItem; - retval.GetRenderPluginAPIVersion = GetAPIVersion; - retval.CreateInstance = CreateInstance; - retval.CreateInstanceScriptProxy = CreateInstanceScriptProxy; - retval.UpdateInstance = UpdateInstance; - retval.QueryInstanceRenderSurface = QuerySurface; - retval.RenderInstance = Render; - retval.ReleaseInstance = ReleaseInstance; - retval.ReleaseClass = ReleaseClass; - return retval; -} - - * Required API function. - */ - -typedef TRenderPluginClass (*TCreateRenderPluginClassFunction)(const char *inTypeName); - -#ifdef _cplusplus -} -#endif - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginGraphObject.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginGraphObject.h deleted file mode 100644 index c0ea66b4..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginGraphObject.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PLUGIN_GRAPH_OBJECT_H -#define QT3DS_RENDER_PLUGIN_GRAPH_OBJECT_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderGraphObject.h" -namespace qt3ds { -namespace render { - - struct SRenderPlugin : public SGraphObject - { - CRegisteredString m_PluginPath; - NodeFlags m_Flags; - - SRenderPlugin() - : SGraphObject(GraphObjectTypes::RenderPlugin) - { - } - - // Generic method used during serialization - // to remap string and object pointers - template - void Remap(TRemapperType &inRemapper) - { - SGraphObject::Remap(inRemapper); - inRemapper.Remap(m_PluginPath); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginPropertyValue.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginPropertyValue.h deleted file mode 100644 index a266e8d3..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderPluginPropertyValue.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PLUGIN_PROPERTY_VALUE_H -#define QT3DS_RENDER_PLUGIN_PROPERTY_VALUE_H -#include "Qt3DSRender.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" -#include "Qt3DSRenderPlugin.h" - -namespace qt3ds { -namespace foundation { - - template <> - struct DestructTraits - { - void destruct(CRegisteredString &) {} - }; -} -} - -namespace qt3ds { -namespace render { - - template - struct SRenderPluginPropertyValueTypeMap - { - }; - - template <> - struct SRenderPluginPropertyValueTypeMap - { - enum { TypeMap = RenderPluginPropertyValueTypes::Long }; - }; - template <> - struct SRenderPluginPropertyValueTypeMap - { - enum { TypeMap = RenderPluginPropertyValueTypes::Float }; - }; - template <> - struct SRenderPluginPropertyValueTypeMap - { - enum { TypeMap = RenderPluginPropertyValueTypes::String }; - }; - template <> - struct SRenderPluginPropertyValueTypeMap - { - enum { TypeMap = RenderPluginPropertyValueTypes::Boolean }; - }; - - struct SRenderPluginPropertyValueUnionTraits - { - typedef RenderPluginPropertyValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(CRegisteredString), - }; - - static TIdType getNoDataId() - { - return RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue; - } - - template - static TIdType getType() - { - return (TIdType)SRenderPluginPropertyValueTypeMap::TypeMap; - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case RenderPluginPropertyValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case RenderPluginPropertyValueTypes::Float: - return inVisitor(*NVUnionCast(inData)); - case RenderPluginPropertyValueTypes::Long: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case RenderPluginPropertyValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case RenderPluginPropertyValueTypes::Float: - return inVisitor(*NVUnionCast(inData)); - case RenderPluginPropertyValueTypes::Long: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SRenderPluginPropertyValueUnionTraits::TBufferSize> - TRenderPluginPropertyValueUnionType; - - struct SRenderPluginPropertyValue : public TRenderPluginPropertyValueUnionType - { - typedef TRenderPluginPropertyValueUnionType TBase; - SRenderPluginPropertyValue() {} - SRenderPluginPropertyValue(const CRegisteredString &str) - : TBase(str) - { - } - SRenderPluginPropertyValue(QT3DSI32 value) - : TBase(value) - { - } - SRenderPluginPropertyValue(QT3DSF32 value) - : TBase(value) - { - } - SRenderPluginPropertyValue(const SRenderPluginPropertyValue &other) - : TBase(static_cast(other)) - { - } - SRenderPluginPropertyValue &operator=(const SRenderPluginPropertyValue &other) - { - TBase::operator=(other); - return *this; - } - }; - - struct SRenderPropertyValueUpdate - { - // Should be the componentized name, so colors get .r .g .b appended - // and vectors get .x .y etc. This interface only updates a component at a time. - CRegisteredString m_PropertyName; - SRenderPluginPropertyValue m_Value; - SRenderPropertyValueUpdate() {} - SRenderPropertyValueUpdate(CRegisteredString str, const SRenderPluginPropertyValue &v) - : m_PropertyName(str) - , m_Value(v) - { - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderProfiler.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderProfiler.h deleted file mode 100644 index a5941c03..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderProfiler.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PROFILER_H -#define QT3DS_RENDER_PROFILER_H -#include "Qt3DSRender.h" -#include "EASTL/string.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/Qt3DSContainers.h" - -namespace qt3ds { -namespace render { - - /** - * Opaque profiling system for rendering. - */ - class IRenderProfiler : public NVRefCounted - { - public: - typedef nvvector TStrIDVec; - - protected: - virtual ~IRenderProfiler() {} - - public: - /** - * @brief start a timer query - * - * @param[in] nameID Timer ID for tracking - * @param[in] absoluteTime If true the absolute GPU is queried - * @param[in] sync Do a sync before starting the timer - * - * @return no return - */ - virtual void StartTimer(CRegisteredString &nameID, bool absoluteTime, bool sync) = 0; - - /** - * @brief stop a timer query - * - * @param[in] nameID Timer ID for tracking - * - * @return no return - */ - virtual void EndTimer(CRegisteredString &nameID) = 0; - - /** - * @brief Get elapsed timer value. Not this is an averaged time over several frames - * - * @param[in] nameID Timer ID for tracking - * - * @return no return - */ - virtual QT3DSF64 GetElapsedTime(const CRegisteredString &nameID) const = 0; - - /** - * @brief Get ID list of tracked timers - * - * @return ID list - */ - virtual const TStrIDVec &GetTimerIDs() const = 0; - - /** - * @brief add vertex count to current counter - * - * @return - */ - virtual void AddVertexCount(QT3DSU32 count) = 0; - - /** - * @brief get current vertex count and reset - * - * @return - */ - virtual QT3DSU32 GetAndResetTriangleCount() const = 0; - - static IRenderProfiler &CreateGpuProfiler(NVFoundationBase &inFoundation, - IQt3DSRenderContext &inContext, - NVRenderContext &inRenderContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRay.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRay.h deleted file mode 100644 index 705f7089..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRay.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_RAY_H -#define QT3DS_RENDER_RAY_H - -#include "Qt3DSRender.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSMat44.h" -#include "foundation/Qt3DSBounds3.h" - -namespace qt3ds { -namespace render { - - struct SBasisPlanes - { - enum Enum { - XY = 0, - YZ, - XZ, - }; - }; - - struct SRayIntersectionResult - { - QT3DSF32 m_RayLengthSquared; // Length of the ray in world coordinates for the hit. - QT3DSVec2 m_RelXY; // UV coords for further mouse picking against a offscreen-rendered object. - SRayIntersectionResult() - : m_RayLengthSquared(0) - , m_RelXY(0, 0) - { - } - SRayIntersectionResult(QT3DSF32 rl, QT3DSVec2 relxy) - : m_RayLengthSquared(rl) - , m_RelXY(relxy) - { - } - }; - - struct SRay - { - QT3DSVec3 m_Origin; - QT3DSVec3 m_Direction; - SRay() - : m_Origin(0, 0, 0) - , m_Direction(0, 0, 0) - { - } - SRay(const QT3DSVec3 &inOrigin, const QT3DSVec3 &inDirection) - : m_Origin(inOrigin) - , m_Direction(inDirection) - { - } - // If we are parallel, then no intersection of course. - Option Intersect(const NVPlane &inPlane) const; - - Option IntersectWithAABB(const QT3DSMat44 &inGlobalTransform, - const NVBounds3 &inBounds, - bool inForceIntersect = false) const; - - Option GetRelative(const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, - SBasisPlanes::Enum inPlane) const; - - Option GetRelativeXY(const QT3DSMat44 &inGlobalTransform, - const NVBounds3 &inBounds) const - { - return GetRelative(inGlobalTransform, inBounds, SBasisPlanes::XY); - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRenderList.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRenderList.h deleted file mode 100644 index dce9a95a..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRenderList.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_RENDER_LIST_H -#define QT3DS_RENDER_RENDER_LIST_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - - class IRenderTask - { - public: - virtual ~IRenderTask() {} - virtual void Run() = 0; - }; - - /** - * The render list exists so that dependencies of the main render target can render themselves - * completely before the main render target renders. From Maxwell GPU's on, we have a tiled - * architecture. This tiling mechanism is sensitive to switching the render target, so we would - * really like to render completely to a single render target and then switch. With our layered - * render architecture, this is not very feasible unless dependencies render themselves before - * the - * main set of layers render themselves. Furthermore it benefits the overall software - * architecture - * to have a distinct split between the prepare for render step and the render step and using - * this - * render list allows us to avoid some level of repeated tree traversal at the cost of some - * minimal - * per frame allocation. The rules for using the render list are that you need to add yourself - * before - * your dependencies do; the list is iterated in reverse during RunRenderTasks. So a layer adds - * itself - * (if it is going to render offscreen) before it runs through its renderable list to prepare - * each object - * because it is during the renderable prepare traversale that subpresentations will get added - * by - * the offscreen render manager. - */ - class IRenderList : public NVRefCounted - { - public: - // Called by the render context, do not call this. - virtual void BeginFrame() = 0; - - // Next tell all sub render target rendering systems to add themselves to the render list. - // At this point - // we agree to *not* have rendered anything, no clears or anything so if you are caching - // render state and you detect nothing has changed it may not be necessary to swap egl - // buffers. - virtual QT3DSU32 AddRenderTask(IRenderTask &inTask) = 0; - virtual void DiscardRenderTask(QT3DSU32 inTaskId) = 0; - // This runs through the added tasks in reverse order. This is used to render dependencies - // before rendering to the main render target. - virtual void RunRenderTasks() = 0; - - // We used to use GL state to pass information down the callstack. - // I have replaced those calls with this state here because that information - // controls how layers size themselves (which is quite a complicated process). - virtual void SetScissorTestEnabled(bool enabled) = 0; - virtual void SetScissorRect(NVRenderRect rect) = 0; - virtual void SetViewport(NVRenderRect rect) = 0; - virtual bool IsScissorTestEnabled() const = 0; - virtual NVRenderRect GetScissor() const = 0; - virtual NVRenderRect GetViewport() const = 0; - - static IRenderList &CreateRenderList(NVFoundationBase &inFnd); - }; - - // Now for scoped property access. - template - struct SRenderListScopedProperty - : public qt3ds::render::NVRenderGenericScopedProperty - { - typedef qt3ds::render::NVRenderGenericScopedProperty TBaseType; - typedef typename TBaseType::TGetter TGetter; - typedef typename TBaseType::TSetter TSetter; - SRenderListScopedProperty(IRenderList &ctx, TGetter getter, TSetter setter) - : TBaseType(ctx, getter, setter) - { - } - SRenderListScopedProperty(IRenderList &ctx, TGetter getter, TSetter setter, - const TDataType &inNewValue) - : TBaseType(ctx, getter, setter, inNewValue) - { - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRotationHelper.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRotationHelper.h deleted file mode 100644 index 19ba8eb7..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderRotationHelper.h +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_ROTATION_HELPER_H -#define QT3DS_RENDER_ROTATION_HELPER_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderNode.h" -#include "EASTL/utility.h" - -namespace qt3ds { -namespace render { - /** - * Unfortunately we still use an XYZ-Euler rotation system. This means that identical - *rotations - * can be represented in various ways. We need to ensure that the value that we write in the - * inspector palette are reasonable, however, and to do this we need a least-distance function - * from two different xyz tuples. - */ - - struct SRotationHelper - { - - // Attempt to go for negative values intead of large positive ones - // Goal is to keep the fabs of the angle low. - static QT3DSF32 ToMinimalAngle(QT3DSF32 value) - { - QT3DSF32 epsilon = (QT3DSF32)M_PI + .001f; - while (fabs(value) > epsilon) { - QT3DSF32 tpi = (QT3DSF32)(2.0f * M_PI); - if (value > 0.0f) - value -= tpi; - else - value += tpi; - } - return value; - } - - /** - * Convert an angle to a canonical form. Return this canonical form. - * - * The canonical form is defined as: - * 1. XYZ all positive. - * 2. XYZ all less than 360. - * - * To do this we rely on two identities, the first is that given an angle, adding - * (or subtracting) pi from all three components does not change the angle. - * - * The second is the obvious one that adding or subtracting 2*pi from any single - * component does not change the angle. - * - * Note that this function works in radian space. - */ - static QT3DSVec3 ToCanonicalFormStaticAxis(const QT3DSVec3 &inSrcAngle, QT3DSU32 inRotOrder) - { - // step 1 - reduce all components to less than 2*pi but greater than 0 - QT3DSVec3 retval(inSrcAngle); - retval.x = ToMinimalAngle(retval.x); - retval.y = ToMinimalAngle(retval.y); - retval.z = ToMinimalAngle(retval.z); - - // step 2 - if any two components are equal to or greater than pi - // then subtract pi from all three, then run two pi reduce again. - - QT3DSU32 greaterThanPiSum = 0; - QT3DSF32 pi = (QT3DSF32)M_PI; - for (QT3DSU32 idx = 0; idx < 3; ++idx) - if (fabs(retval[idx]) >= pi) - greaterThanPiSum++; - - if (greaterThanPiSum > 1) { - // For this identity to work, the middle axis angle needs to be subtracted from - // 180 instead of added to 180 because the previous axis *reversed* it. - QT3DSU32 theMiddleAxis = 0; - - switch (inRotOrder) { - case EulOrdXYZs: - theMiddleAxis = 1; - break; - case EulOrdXZYs: - theMiddleAxis = 2; - break; - case EulOrdYXZs: - theMiddleAxis = 0; - break; - case EulOrdYZXs: - theMiddleAxis = 2; - break; - case EulOrdZYXs: - theMiddleAxis = 1; - break; - case EulOrdZXYs: - theMiddleAxis = 0; - break; - case EulOrdXYZr: - theMiddleAxis = 1; - break; - case EulOrdXZYr: - theMiddleAxis = 2; - break; - case EulOrdYXZr: - theMiddleAxis = 0; - break; - case EulOrdYZXr: - theMiddleAxis = 2; - break; - case EulOrdZYXr: - theMiddleAxis = 1; - break; - case EulOrdZXYr: - theMiddleAxis = 0; - break; - default: - QT3DS_ASSERT(false); - return inSrcAngle; - } - for (QT3DSU32 idx = 0; idx < 3; ++idx) { - if (idx == theMiddleAxis) - retval[idx] = pi - retval[idx]; - else - retval[idx] = retval[idx] > 0.0f ? retval[idx] - pi : retval[idx] + pi; - } - } - return retval; - } - - static QT3DSVec3 ToMinimalAngleDiff(const QT3DSVec3 inDiff) - { - return QT3DSVec3(ToMinimalAngle(inDiff.x), ToMinimalAngle(inDiff.y), - ToMinimalAngle(inDiff.z)); - } - - /** - * Given an old angle and a new angle, return an angle has the same rotational value - * as the new angle *but* is as close to the old angle as possible. - * Works in radian space. This function doesn't currently work for euler angles or - * with Euler angles with repeating axis. - */ - static QT3DSVec3 ToNearestAngle(const QT3DSVec3 &inOldAngle, const QT3DSVec3 &inNewAngle, - QT3DSU32 inRotOrder) - { - switch (inRotOrder) { - case EulOrdXYZs: - case EulOrdXZYs: - case EulOrdYXZs: - case EulOrdYZXs: - case EulOrdZYXs: - case EulOrdZXYs: - case EulOrdXYZr: - case EulOrdXZYr: - case EulOrdYXZr: - case EulOrdYZXr: - case EulOrdZYXr: - case EulOrdZXYr: { - QT3DSVec3 oldA = ToCanonicalFormStaticAxis(inOldAngle, inRotOrder); - QT3DSVec3 newA = ToCanonicalFormStaticAxis(inNewAngle, inRotOrder); - QT3DSVec3 diff = newA - oldA; - return inOldAngle + ToMinimalAngleDiff(diff); - } break; - default: - return inNewAngle; - } - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCache.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCache.h deleted file mode 100644 index 47e76f36..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCache.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_CACHE_H -#define QT3DS_RENDER_SHADER_CACHE_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - struct ShaderCacheProgramFlagValues - { - enum Enum { - TessellationEnabled = 1 << 0, // tessellation enabled - GeometryShaderEnabled = 1 << 1, // geometry shader enabled - }; - }; - struct SShaderCacheProgramFlags : public NVFlags - { - // tessellation enabled - void SetTessellationEnabled(bool inValue) - { - clearOrSet(inValue, ShaderCacheProgramFlagValues::TessellationEnabled); - } - bool IsTessellationEnabled() const - { - return this->operator&(ShaderCacheProgramFlagValues::TessellationEnabled); - } - // geometry shader enabled - void SetGeometryShaderEnabled(bool inValue) - { - clearOrSet(inValue, ShaderCacheProgramFlagValues::GeometryShaderEnabled); - } - bool IsGeometryShaderEnabled() const - { - return this->operator&(ShaderCacheProgramFlagValues::GeometryShaderEnabled); - } - }; - // There are a number of macros used to turn on or off various features. This allows those - // features - // to be propagated into the shader cache's caching mechanism. They will be translated into - //#define name value where value is 1 or zero depending on if the feature is enabled or not. - struct SShaderPreprocessorFeature - { - CRegisteredString m_Name; - bool m_Enabled; - SShaderPreprocessorFeature() - : m_Enabled(false) - { - } - SShaderPreprocessorFeature(CRegisteredString name, bool val) - : m_Name(name) - , m_Enabled(val) - { - } - bool operator<(const SShaderPreprocessorFeature &inOther) const; - bool operator==(const SShaderPreprocessorFeature &inOther) const; - }; - - typedef NVConstDataRef TShaderFeatureSet; - - inline TShaderFeatureSet ShaderCacheNoFeatures() { return TShaderFeatureSet(); } - - // Hash is dependent on the order of the keys; so make sure their order is consistent!! - size_t HashShaderFeatureSet(NVConstDataRef inFeatureSet); - - class IShaderCache : public NVRefCounted - { - protected: - virtual ~IShaderCache() {} - public: - // If directory is nonnull, then we attempt to load any shaders from shadercache.xml in - // inDirectory - // and save any new ones out to the same file. The shaders are marked by the gl version - // used when saving. - // If we can't open shadercache.xml from inDirectory for writing (at least), then we still - // consider the - // shadercache to be disabled. - // This call immediately blocks and attempts to load all applicable shaders from the - // shadercache.xml file in - // the given directory. - virtual void SetShaderCachePersistenceEnabled(const char8_t *inDirectory) = 0; - virtual bool IsShaderCachePersistenceEnabled() const = 0; - // It is up to the caller to ensure that inFeatures contains unique keys. - // It is also up the the caller to ensure the keys are ordered in some way. - virtual NVRenderShaderProgram * - GetProgram(CRegisteredString inKey, - NVConstDataRef inFeatures) = 0; - - // Replace an existing program in the cache for the same key with this program. - // The shaders returned by *CompileProgram functions can be released by this object - // due to ForceCompileProgram or SetProjectDirectory, so clients need to either not - // hold on to them or they need to addref/release them to ensure they still have - // access to them. - // The flags just tell us under what gl state to compile the program in order to hopefully - // reduce program compilations. - // It is up to the caller to ensure that inFeatures contains unique keys. - // It is also up the the caller to ensure the keys are ordered in some way. - virtual NVRenderShaderProgram * - ForceCompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, - const char8_t *inTessCtrl, const char8_t *inTessEval, - const char8_t *inGeom, const SShaderCacheProgramFlags &inFlags, - TShaderFeatureSet inFeatures, bool separableProgram, - bool fromDisk = false) = 0; - - // It is up to the caller to ensure that inFeatures contains unique keys. - // It is also up the the caller to ensure the keys are ordered in some way. - virtual NVRenderShaderProgram * - CompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, - const char8_t *inTessCtrl, const char8_t *inTessEval, const char8_t *inGeom, - const SShaderCacheProgramFlags &inFlags, TShaderFeatureSet inFeatures, - bool separableProgram = false) = 0; - - // Used to disable any shader compilation during loading. This is used when we are just - // interested in going from uia->binary - // and we expect to run on a headless server of sorts. See the UICCompiler project for its - // only current use case. - virtual void SetShaderCompilationEnabled(bool inEnableShaderCompilation) = 0; - - // Upping the shader version invalidates all previous cache files. - static QT3DSU32 GetShaderVersion() { return 4; } - static const char8_t *GetShaderCacheFileName() { return "shadercache.xml"; } - - static IShaderCache &CreateShaderCache(NVRenderContext &inContext, - IInputStreamFactory &inInputStreamFactory, - IPerfTimer &inPerfTimer); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGenerator.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGenerator.h deleted file mode 100644 index 80cbaaae..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGenerator.h +++ /dev/null @@ -1,175 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_CODE_GENERATOR_H -#define QT3DS_RENDER_SHADER_CODE_GENERATOR_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSContainers.h" -#include "EASTL/string.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "Qt3DSRenderString.h" - -namespace qt3ds { -namespace render { - - struct SEndlType - { - }; - extern SEndlType Endl; - - typedef std::basic_string TStrType; - typedef eastl::pair TParamPair; - typedef eastl::pair TConstantBufferParamPair; - typedef nvvector TConstantBufferParamArray; - typedef nvhash_map TStrTableStrMap; - - struct SShaderCodeGeneratorBase - { - enum Enum { - Unknown = 0, - Lighting, - ViewVector, - WorldNormal, - WorldPosition, - EnvMapReflection, - UVCoords, - }; - IStringTable &m_StringTable; - nvhash_set m_Codes; // set of enums we have included. - nvhash_set m_Includes; - TStrTableStrMap m_Uniforms; - TStrTableStrMap m_ConstantBuffers; - TConstantBufferParamArray m_ConstantBufferParams; - TStrTableStrMap m_Attributes; - CRenderString m_FinalShaderBuilder; - TStrType m_CodeBuilder; - qt3ds::render::NVRenderContextType m_RenderContextType; - - SShaderCodeGeneratorBase(IStringTable &inStringTable, NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType); - virtual TStrTableStrMap &GetVaryings() = 0; - void Begin(); - void Append(const char *data); - // don't add the newline - void AppendPartial(const char *data); - void AddConstantBuffer(const char *name, const char *layout); - void AddConstantBufferParam(const char *cbName, const char *paramName, const char *type); - void AddUniform(const char *name, const char *type); - void AddUniform(TStrType &name, const char *type); - void AddAttribute(const char *name, const char *type); - void AddAttribute(TStrType &name, const char *type); - void AddVarying(const char *name, const char *type); - void AddVarying(TStrType &name, const char *type); - void AddLocalVariable(const char *name, const char *type, int tabCount = 1); - void AddLocalVariable(TStrType &name, const char *type, int tabCount = 1); - void AddInclude(const char *name); - void AddInclude(TStrType &name); - bool HasCode(Enum value); - void SetCode(Enum value); - void SetupWorldPosition(); - void GenerateViewVector(); - void GenerateWorldNormal(); - void GenerateEnvMapReflection(SShaderCodeGeneratorBase &inFragmentShader); - void GenerateUVCoords(); - void GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, - eastl::basic_string &texSwizzle, - eastl::basic_string &lookupSwizzle); - void GenerateShadedWireframeBase(); - void AddLighting(); - const char *BuildShaderSource(); - SShaderCodeGeneratorBase &operator<<(const char *data); - SShaderCodeGeneratorBase &operator<<(const TStrType &data); - SShaderCodeGeneratorBase &operator<<(const SEndlType & /*data*/); - - protected: - virtual void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap); - void AddShaderConstantBufferItemMap(const char *itemType, const TStrTableStrMap &cbMap, - TConstantBufferParamArray cbParamsArray); - }; - - struct SShaderVertexCodeGenerator : public SShaderCodeGeneratorBase - { - TStrTableStrMap m_Varyings; - SShaderVertexCodeGenerator(IStringTable &inStringTable, NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType); - TStrTableStrMap &GetVaryings() override; - }; - - struct SShaderTessControlCodeGenerator : public SShaderCodeGeneratorBase - { - SShaderVertexCodeGenerator &m_VertGenerator; - TStrTableStrMap m_Varyings; - SShaderTessControlCodeGenerator(SShaderVertexCodeGenerator &vert, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType); - - void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap) override; - TStrTableStrMap &GetVaryings() override; - }; - - struct SShaderTessEvalCodeGenerator : public SShaderCodeGeneratorBase - { - SShaderTessControlCodeGenerator &m_TessControlGenerator; - bool m_hasGeometryStage; - - SShaderTessEvalCodeGenerator(SShaderTessControlCodeGenerator &tc, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType); - - void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap) override; - TStrTableStrMap &GetVaryings() override; - virtual void SetGeometryStage(bool hasGeometryStage); - }; - - struct SShaderGeometryCodeGenerator : public SShaderCodeGeneratorBase - { - SShaderVertexCodeGenerator &m_VertGenerator; - bool m_hasTessellationStage; - - SShaderGeometryCodeGenerator(SShaderVertexCodeGenerator &vert, NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType); - - void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap) override; - TStrTableStrMap &GetVaryings() override; - virtual void SetTessellationStage(bool hasTessellationStage); - }; - - struct SShaderFragmentCodeGenerator : public SShaderCodeGeneratorBase - { - SShaderVertexCodeGenerator &m_VertGenerator; - SShaderFragmentCodeGenerator(SShaderVertexCodeGenerator &vert, NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType); - TStrTableStrMap &GetVaryings() override; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGeneratorV2.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGeneratorV2.h deleted file mode 100644 index 23892c5c..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderCodeGeneratorV2.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_CODE_GENERATOR_V2_H -#define QT3DS_RENDER_SHADER_CODE_GENERATOR_V2_H -#include "Qt3DSRenderShaderCodeGenerator.h" -#include "Qt3DSRenderShaderCache.h" -#include "foundation/Qt3DSFlags.h" - -#include - -namespace qt3ds { -namespace render { - // So far the generator is only useful for graphics stages, - // it doesn't seem useful for compute stages. - struct ShaderGeneratorStages - { - enum Enum { - Vertex = 1, - TessControl = 1 << 1, - TessEval = 1 << 2, - Geometry = 1 << 3, - Fragment = 1 << 4, - StageCount = 5, - }; - }; - - typedef NVFlags TShaderGeneratorStageFlags; - - class IShaderStageGenerator - { - protected: - virtual ~IShaderStageGenerator() {} - public: - virtual void AddIncoming(const char8_t *name, const char8_t *type) = 0; - virtual void AddIncoming(const TStrType &name, const char8_t *type) = 0; - - virtual void AddOutgoing(const char8_t *name, const char8_t *type) = 0; - virtual void AddOutgoing(const TStrType &name, const char8_t *type) = 0; - - virtual void AddUniform(const char8_t *name, const char8_t *type) = 0; - virtual void AddUniform(const TStrType &name, const char8_t *type) = 0; - - virtual void AddInclude(const char8_t *name) = 0; - virtual void AddInclude(const TStrType &name) = 0; - virtual void AddInclude(const QString &name) = 0; - - virtual void AddFunction(const QString &functionName) = 0; - - virtual void AddConstantBuffer(const char *name, const char *layout) = 0; - virtual void AddConstantBufferParam(const char *cbName, const char *paramName, - const char *type) = 0; - - virtual IShaderStageGenerator &operator<<(const char *data) = 0; - virtual IShaderStageGenerator &operator<<(const TStrType &data) = 0; - virtual IShaderStageGenerator &operator<<(const SEndlType & /*data*/) = 0; - virtual void Append(const char *data) = 0; - virtual void AppendPartial(const char *data) = 0; - - virtual ShaderGeneratorStages::Enum Stage() const = 0; - }; - - class IShaderProgramGenerator : public NVRefCounted - { - public: - static TShaderGeneratorStageFlags DefaultFlags() - { - return TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex - | ShaderGeneratorStages::Fragment); - } - virtual void BeginProgram(TShaderGeneratorStageFlags inEnabledStages = DefaultFlags()) = 0; - - virtual TShaderGeneratorStageFlags GetEnabledStages() const = 0; - - // get the stage or NULL if it has not been created. - virtual IShaderStageGenerator *GetStage(ShaderGeneratorStages::Enum inStage) = 0; - - // Implicit call to end program. - virtual qt3ds::render::NVRenderShaderProgram * - CompileGeneratedShader(const char *inShaderName, const SShaderCacheProgramFlags &inFlags, - TShaderFeatureSet inFeatureSet, bool separableProgram = false) = 0; - - qt3ds::render::NVRenderShaderProgram *CompileGeneratedShader(const char *inShaderName, - bool separableProgram = false) - { - return CompileGeneratedShader(inShaderName, SShaderCacheProgramFlags(), - TShaderFeatureSet(), separableProgram); - } - - static IShaderProgramGenerator &CreateProgramGenerator(IQt3DSRenderContext &inContext); - - static void OutputParaboloidDepthVertex(IShaderStageGenerator &inGenerator); - // By convention, the local space result of the TE is stored in vec4 pos local variable. - // This function expects such state. - static void OutputParaboloidDepthTessEval(IShaderStageGenerator &inGenerator); - // Utilities shared among the various different systems. - static void OutputParaboloidDepthFragment(IShaderStageGenerator &inGenerator); - - static void OutputCubeFaceDepthVertex(IShaderStageGenerator &inGenerator); - static void OutputCubeFaceDepthGeometry(IShaderStageGenerator &inGenerator); - static void OutputCubeFaceDepthFragment(IShaderStageGenerator &inGenerator); - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderKeys.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderKeys.h deleted file mode 100644 index 5d02e414..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShaderKeys.h +++ /dev/null @@ -1,802 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_KEY_H -#define QT3DS_RENDER_SHADER_KEY_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSDataRef.h" -#include "EASTL/string.h" -#include "foundation/StringConversionImpl.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderTessModeValues.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - // We have an ever expanding set of properties we like to hash into one or more 32 bit - // quantities. - // Furthermore we would like this set of properties to be convertable to string - // So the shader cache file itself is somewhat human readable/diagnosable. - // To do this we create a set of objects that act as properties to the master shader key. - // These objects are tallied in order to figure out their actual offset into the shader key's - // data store. They are also run through in order to create the string shader cache key. - - struct SShaderKeyPropertyBase - { - const char *m_Name; - QT3DSU32 m_Offset; - SShaderKeyPropertyBase(const char *name = "") - : m_Name(name) - , m_Offset(0) - { - } - QT3DSU32 GetOffset() const { return m_Offset; } - void SetOffset(QT3DSU32 of) { m_Offset = of; } - - template - QT3DSU32 GetMaskTemplate() const - { - QT3DSU32 bit = m_Offset % 32; - QT3DSU32 startValue = (1 << TBitWidth) - 1; - QT3DSU32 mask = startValue << bit; - return mask; - } - - QT3DSU32 GetIdx() const { return m_Offset / 32; } - protected: - void InternalToString(eastl::string &ioStr, const char *inBuffer) const - { - ioStr.append(m_Name); - ioStr.append("="); - ioStr.append(inBuffer); - } - - static void InternalToString(eastl::string &ioStr, const char *name, bool inValue) - { - if (inValue) { - ioStr.append(name); - ioStr.append("="); - ioStr.append(inValue ? "true" : "false"); - } - } - }; - - struct SShaderKeyBoolean : public SShaderKeyPropertyBase - { - enum { - BitWidth = 1, - }; - - SShaderKeyBoolean(const char *name = "") - : SShaderKeyPropertyBase(name) - { - } - - QT3DSU32 GetMask() const { return GetMaskTemplate(); } - void SetValue(NVDataRef inDataStore, bool inValue) const - { - QT3DSU32 idx = GetIdx(); - QT3DS_ASSERT(inDataStore.size() > idx); - QT3DSU32 mask = GetMask(); - QT3DSU32 &target = inDataStore[idx]; - if (inValue == true) { - target = target | mask; - } else { - mask = ~mask; - target = target & mask; - } - } - - bool GetValue(NVConstDataRef inDataStore) const - { - QT3DSU32 idx = GetIdx(); - QT3DSU32 mask = GetMask(); - const QT3DSU32 &target = inDataStore[idx]; - return (target & mask) ? true : false; - } - - void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const - { - bool isHigh = GetValue(inKeySet); - InternalToString(ioStr, m_Name, isHigh); - } - }; - - template - struct SShaderKeyUnsigned : public SShaderKeyPropertyBase - { - enum { - BitWidth = TBitWidth, - }; - SShaderKeyUnsigned(const char *name = "") - : SShaderKeyPropertyBase(name) - { - } - QT3DSU32 GetMask() const { return GetMaskTemplate(); } - void SetValue(NVDataRef inDataStore, QT3DSU32 inValue) const - { - QT3DSU32 startValue = (1 << TBitWidth) - 1; - // Ensure inValue is within range of bit width. - inValue = inValue & startValue; - QT3DSU32 bit = m_Offset % 32; - QT3DSU32 mask = GetMask(); - QT3DSU32 idx = GetIdx(); - inValue = inValue << bit; - QT3DSU32 &target = inDataStore[idx]; - // Get rid of existing value - QT3DSU32 inverseMask = ~mask; - target = target & inverseMask; - target = target | inValue; - } - - QT3DSU32 GetValue(NVConstDataRef inDataStore) const - { - QT3DSU32 idx = GetIdx(); - QT3DSU32 bit = m_Offset % 32; - QT3DSU32 mask = GetMask(); - const QT3DSU32 &target = inDataStore[idx]; - - QT3DSU32 retval = target & mask; - retval = retval >> bit; - return retval; - } - - void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const - { - QT3DSU32 value = GetValue(inKeySet); - char buf[64]; - StringConversion().ToStr(value, toDataRef(buf, 64)); - InternalToString(ioStr, buf); - } - }; - - struct SShaderKeyTessellation : public SShaderKeyUnsigned<4> - { - enum TessellationBits { - noTessellation = 1 << 0, - linearTessellation = 1 << 1, - phongTessellation = 1 << 2, - npatchTessellation = 1 << 3 - }; - - SShaderKeyTessellation(const char *name = "") - : SShaderKeyUnsigned<4>(name) - { - } - - bool GetBitValue(TessellationBits swizzleBit, NVConstDataRef inKeySet) const - { - return (GetValue(inKeySet) & swizzleBit) ? true : false; - } - - void SetBitValue(TessellationBits swizzleBit, bool inValue, NVDataRef inKeySet) - { - QT3DSU32 theValue = GetValue(inKeySet); - QT3DSU32 mask = swizzleBit; - if (inValue) { - theValue = theValue | mask; - } else { - mask = ~mask; - theValue = theValue & mask; - } - SetValue(inKeySet, theValue); - } - - void SetTessellationMode(NVDataRef inKeySet, TessModeValues::Enum tessellationMode, - bool val) - { - switch (tessellationMode) { - case TessModeValues::NoTess: - SetBitValue(noTessellation, val, inKeySet); - break; - case TessModeValues::TessLinear: - SetBitValue(linearTessellation, val, inKeySet); - break; - case TessModeValues::TessNPatch: - SetBitValue(npatchTessellation, val, inKeySet); - break; - case TessModeValues::TessPhong: - SetBitValue(phongTessellation, val, inKeySet); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - bool IsNoTessellation(NVConstDataRef inKeySet) const - { - return GetBitValue(noTessellation, inKeySet); - } - void SetNoTessellation(NVDataRef inKeySet, bool val) - { - SetBitValue(noTessellation, val, inKeySet); - } - - bool IsLinearTessellation(NVConstDataRef inKeySet) const - { - return GetBitValue(linearTessellation, inKeySet); - } - void SetLinearTessellation(NVDataRef inKeySet, bool val) - { - SetBitValue(linearTessellation, val, inKeySet); - } - - bool IsNPatchTessellation(NVConstDataRef inKeySet) const - { - return GetBitValue(npatchTessellation, inKeySet); - } - void SetNPatchTessellation(NVDataRef inKeySet, bool val) - { - SetBitValue(npatchTessellation, val, inKeySet); - } - - bool IsPhongTessellation(NVConstDataRef inKeySet) const - { - return GetBitValue(phongTessellation, inKeySet); - } - void SetPhongTessellation(NVDataRef inKeySet, bool val) - { - SetBitValue(phongTessellation, val, inKeySet); - } - - void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const - { - ioStr.append(m_Name); - ioStr.append("={"); - InternalToString(ioStr, "noTessellation", IsNoTessellation(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "linearTessellation", IsLinearTessellation(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "npatchTessellation", IsNPatchTessellation(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "phongTessellation", IsPhongTessellation(inKeySet)); - ioStr.append("}"); - } - }; - - struct SShaderKeyTextureSwizzle : public SShaderKeyUnsigned<5> - { - enum TextureSwizzleBits { - noSwizzle = 1 << 0, - L8toR8 = 1 << 1, - A8toR8 = 1 << 2, - L8A8toRG8 = 1 << 3, - L16toR16 = 1 << 4 - }; - - SShaderKeyTextureSwizzle(const char *name = "") - : SShaderKeyUnsigned<5>(name) - { - } - - bool GetBitValue(TextureSwizzleBits swizzleBit, NVConstDataRef inKeySet) const - { - return (GetValue(inKeySet) & swizzleBit) ? true : false; - } - - void SetBitValue(TextureSwizzleBits swizzleBit, bool inValue, NVDataRef inKeySet) - { - QT3DSU32 theValue = GetValue(inKeySet); - QT3DSU32 mask = swizzleBit; - if (inValue) { - theValue = theValue | mask; - } else { - mask = ~mask; - theValue = theValue & mask; - } - SetValue(inKeySet, theValue); - } - - void SetSwizzleMode(NVDataRef inKeySet, NVRenderTextureSwizzleMode::Enum swizzleMode, - bool val) - { - switch (swizzleMode) { - case NVRenderTextureSwizzleMode::NoSwizzle: - SetBitValue(noSwizzle, val, inKeySet); - break; - case NVRenderTextureSwizzleMode::L8toR8: - SetBitValue(L8toR8, val, inKeySet); - break; - case NVRenderTextureSwizzleMode::A8toR8: - SetBitValue(A8toR8, val, inKeySet); - break; - case NVRenderTextureSwizzleMode::L8A8toRG8: - SetBitValue(L8A8toRG8, val, inKeySet); - break; - case NVRenderTextureSwizzleMode::L16toR16: - SetBitValue(L16toR16, val, inKeySet); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - bool IsNoSwizzled(NVConstDataRef inKeySet) const - { - return GetBitValue(noSwizzle, inKeySet); - } - void SetNoSwizzled(NVDataRef inKeySet, bool val) - { - SetBitValue(noSwizzle, val, inKeySet); - } - - bool IsL8Swizzled(NVConstDataRef inKeySet) const - { - return GetBitValue(L8toR8, inKeySet); - } - void SetL8Swizzled(NVDataRef inKeySet, bool val) - { - SetBitValue(L8toR8, val, inKeySet); - } - - bool IsA8Swizzled(NVConstDataRef inKeySet) const - { - return GetBitValue(A8toR8, inKeySet); - } - void SetA8Swizzled(NVDataRef inKeySet, bool val) - { - SetBitValue(A8toR8, val, inKeySet); - } - - bool IsL8A8Swizzled(NVConstDataRef inKeySet) const - { - return GetBitValue(L8A8toRG8, inKeySet); - } - void SetL8A8Swizzled(NVDataRef inKeySet, bool val) - { - SetBitValue(L8A8toRG8, val, inKeySet); - } - - bool IsL16Swizzled(NVConstDataRef inKeySet) const - { - return GetBitValue(L16toR16, inKeySet); - } - void SetL16Swizzled(NVDataRef inKeySet, bool val) - { - SetBitValue(L16toR16, val, inKeySet); - } - - void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const - { - ioStr.append(m_Name); - ioStr.append("={"); - InternalToString(ioStr, "noswizzle", IsNoSwizzled(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "l8swizzle", IsL8Swizzled(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "a8swizzle", IsA8Swizzled(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "l8a8swizzle", IsL8A8Swizzled(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "l16swizzle", IsL16Swizzled(inKeySet)); - ioStr.append("}"); - } - }; - - struct SShaderKeyImageMap : public SShaderKeyUnsigned<5> - { - enum ImageMapBits { - Enabled = 1 << 0, - EnvMap = 1 << 1, - LightProbe = 1 << 2, - InvertUV = 1 << 3, - Premultiplied = 1 << 4, - }; - - SShaderKeyImageMap(const char *name = "") - : SShaderKeyUnsigned<5>(name) - { - } - - bool GetBitValue(ImageMapBits imageBit, NVConstDataRef inKeySet) const - { - return (GetValue(inKeySet) & imageBit) ? true : false; - } - - void SetBitValue(ImageMapBits imageBit, bool inValue, NVDataRef inKeySet) - { - QT3DSU32 theValue = GetValue(inKeySet); - QT3DSU32 mask = imageBit; - if (inValue) { - theValue = theValue | mask; - } else { - mask = ~mask; - theValue = theValue & mask; - } - SetValue(inKeySet, theValue); - } - - bool IsEnabled(NVConstDataRef inKeySet) const - { - return GetBitValue(Enabled, inKeySet); - } - void SetEnabled(NVDataRef inKeySet, bool val) - { - SetBitValue(Enabled, val, inKeySet); - } - - bool IsEnvMap(NVConstDataRef inKeySet) const - { - return GetBitValue(EnvMap, inKeySet); - } - void SetEnvMap(NVDataRef inKeySet, bool val) { SetBitValue(EnvMap, val, inKeySet); } - - bool IsLightProbe(NVConstDataRef inKeySet) const - { - return GetBitValue(LightProbe, inKeySet); - } - void SetLightProbe(NVDataRef inKeySet, bool val) - { - SetBitValue(LightProbe, val, inKeySet); - } - - bool IsInvertUVMap(NVConstDataRef inKeySet) const - { - return GetBitValue(InvertUV, inKeySet); - } - void SetInvertUVMap(NVDataRef inKeySet, bool val) - { - SetBitValue(InvertUV, val, inKeySet); - } - - bool IsPremultiplied(NVConstDataRef inKeySet) const - { - return GetBitValue(Premultiplied, inKeySet); - } - void SetPremultiplied(NVDataRef inKeySet, bool val) - { - SetBitValue(Premultiplied, val, inKeySet); - } - - void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const - { - ioStr.append(m_Name); - ioStr.append("={"); - InternalToString(ioStr, "enabled", IsEnabled(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "envMap", IsEnvMap(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "lightProbe", IsLightProbe(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "invertUV", IsInvertUVMap(inKeySet)); - ioStr.append(";"); - InternalToString(ioStr, "premultiplied", IsPremultiplied(inKeySet)); - ioStr.append("}"); - } - }; - - struct SShaderKeySpecularModel : SShaderKeyUnsigned<2> - { - SShaderKeySpecularModel(const char *name = "") - : SShaderKeyUnsigned<2>(name) - { - } - - void SetSpecularModel(NVDataRef inKeySet, - qt3ds::render::DefaultMaterialSpecularModel::Enum inModel) - { - SetValue(inKeySet, (QT3DSU32)inModel); - } - - qt3ds::render::DefaultMaterialSpecularModel::Enum - GetSpecularModel(NVConstDataRef inKeySet) const - { - return static_cast(GetValue(inKeySet)); - } - - void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const - { - ioStr.append(m_Name); - ioStr.append("="); - switch (GetSpecularModel(inKeySet)) { - case DefaultMaterialSpecularModel::KGGX: - ioStr.append("KGGX"); - break; - case DefaultMaterialSpecularModel::KWard: - ioStr.append("KWard"); - break; - case DefaultMaterialSpecularModel::Default: - ioStr.append("Default"); - break; - } - ioStr.append(";"); - } - }; - - struct SShaderDefaultMaterialKeyProperties - { - enum { - LightCount = 7, - }; - enum ImageMapNames { - DiffuseMap0 = 0, - DiffuseMap1, - DiffuseMap2, - EmissiveMap, - EmissiveMap2, - SpecularMap, - OpacityMap, - BumpMap, - SpecularAmountMap, - NormalMap, - DisplacementMap, - TranslucencyMap, - LightmapIndirect, - LightmapRadiosity, - LightmapShadow, - RoughnessMap, - ImageMapCount - }; - - SShaderKeyBoolean m_HasLighting; - SShaderKeyBoolean m_HasIbl; - SShaderKeyUnsigned<3> m_LightCount; - SShaderKeyBoolean m_LightFlags[LightCount]; - SShaderKeyBoolean m_LightAreaFlags[LightCount]; - SShaderKeyBoolean m_LightShadowFlags[LightCount]; - SShaderKeyBoolean m_SpecularEnabled; - SShaderKeyBoolean m_FresnelEnabled; - SShaderKeyBoolean m_VertexColorsEnabled; - SShaderKeySpecularModel m_SpecularModel; - SShaderKeyImageMap m_ImageMaps[ImageMapCount]; - SShaderKeyTextureSwizzle m_TextureSwizzle[ImageMapCount]; - SShaderKeyTessellation m_TessellationMode; - SShaderKeyBoolean m_HasSkinning; - SShaderKeyBoolean m_WireframeMode; - - SShaderDefaultMaterialKeyProperties() - : m_HasLighting("hasLighting") - , m_HasIbl("hasIbl") - , m_LightCount("lightCount") - , m_SpecularEnabled("specularEnabled") - , m_FresnelEnabled("fresnelEnabled") - , m_VertexColorsEnabled("vertexColorsEnabled") - , m_SpecularModel("specularModel") - , m_TessellationMode("tessellationMode") - , m_HasSkinning("hasSkinning") - , m_WireframeMode("wireframeMode") - { - m_LightFlags[0].m_Name = "light0HasPosition"; - m_LightFlags[1].m_Name = "light1HasPosition"; - m_LightFlags[2].m_Name = "light2HasPosition"; - m_LightFlags[3].m_Name = "light3HasPosition"; - m_LightFlags[4].m_Name = "light4HasPosition"; - m_LightFlags[5].m_Name = "light5HasPosition"; - m_LightFlags[6].m_Name = "light6HasPosition"; - m_LightAreaFlags[0].m_Name = "light0HasArea"; - m_LightAreaFlags[1].m_Name = "light1HasArea"; - m_LightAreaFlags[2].m_Name = "light2HasArea"; - m_LightAreaFlags[3].m_Name = "light3HasArea"; - m_LightAreaFlags[4].m_Name = "light4HasArea"; - m_LightAreaFlags[5].m_Name = "light5HasArea"; - m_LightAreaFlags[6].m_Name = "light6HasArea"; - m_LightShadowFlags[0].m_Name = "light0HasShadow"; - m_LightShadowFlags[1].m_Name = "light1HasShadow"; - m_LightShadowFlags[2].m_Name = "light2HasShadow"; - m_LightShadowFlags[3].m_Name = "light3HasShadow"; - m_LightShadowFlags[4].m_Name = "light4HasShadow"; - m_LightShadowFlags[5].m_Name = "light5HasShadow"; - m_LightShadowFlags[6].m_Name = "light6HasShadow"; - m_ImageMaps[0].m_Name = "diffuseMap0"; - m_ImageMaps[1].m_Name = "diffuseMap1"; - m_ImageMaps[2].m_Name = "diffuseMap2"; - m_ImageMaps[3].m_Name = "emissiveMap"; - m_ImageMaps[4].m_Name = "emissiveMap2"; - m_ImageMaps[5].m_Name = "specularMap"; - m_ImageMaps[6].m_Name = "opacityMap"; - m_ImageMaps[7].m_Name = "bumpMap"; - m_ImageMaps[8].m_Name = "specularAmountMap"; - m_ImageMaps[9].m_Name = "normalMap"; - m_ImageMaps[10].m_Name = "displacementMap"; - m_ImageMaps[11].m_Name = "translucencyMap"; - m_ImageMaps[12].m_Name = "lightmapIndirect"; - m_ImageMaps[13].m_Name = "lightmapRadiosity"; - m_ImageMaps[14].m_Name = "lightmapShadow"; - m_ImageMaps[15].m_Name = "roughnessMap"; - m_TextureSwizzle[0].m_Name = "diffuseMap0_swizzle"; - m_TextureSwizzle[1].m_Name = "diffuseMap1_swizzle"; - m_TextureSwizzle[2].m_Name = "diffuseMap2_swizzle"; - m_TextureSwizzle[3].m_Name = "emissiveMap_swizzle"; - m_TextureSwizzle[4].m_Name = "emissiveMap2_swizzle"; - m_TextureSwizzle[5].m_Name = "specularMap_swizzle"; - m_TextureSwizzle[6].m_Name = "opacityMap_swizzle"; - m_TextureSwizzle[7].m_Name = "bumpMap_swizzle"; - m_TextureSwizzle[8].m_Name = "specularAmountMap_swizzle"; - m_TextureSwizzle[9].m_Name = "normalMap_swizzle"; - m_TextureSwizzle[10].m_Name = "displacementMap_swizzle"; - m_TextureSwizzle[11].m_Name = "translucencyMap_swizzle"; - m_TextureSwizzle[12].m_Name = "lightmapIndirect_swizzle"; - m_TextureSwizzle[13].m_Name = "lightmapRadiosity_swizzle"; - m_TextureSwizzle[14].m_Name = "lightmapShadow_swizzle"; - m_TextureSwizzle[15].m_Name = "roughnessMap_swizzle"; - SetPropertyOffsets(); - } - - template - void VisitProperties(TVisitor &inVisitor) - { - inVisitor.Visit(m_HasLighting); - inVisitor.Visit(m_HasIbl); - inVisitor.Visit(m_LightCount); - - for (QT3DSU32 idx = 0, end = LightCount; idx < end; ++idx) { - inVisitor.Visit(m_LightFlags[idx]); - } - - for (QT3DSU32 idx = 0, end = LightCount; idx < end; ++idx) { - inVisitor.Visit(m_LightAreaFlags[idx]); - } - - for (QT3DSU32 idx = 0, end = LightCount; idx < end; ++idx) { - inVisitor.Visit(m_LightShadowFlags[idx]); - } - - inVisitor.Visit(m_SpecularEnabled); - inVisitor.Visit(m_FresnelEnabled); - inVisitor.Visit(m_VertexColorsEnabled); - inVisitor.Visit(m_SpecularModel); - - for (QT3DSU32 idx = 0, end = ImageMapCount; idx < end; ++idx) { - inVisitor.Visit(m_ImageMaps[idx]); - inVisitor.Visit(m_TextureSwizzle[idx]); - } - - inVisitor.Visit(m_TessellationMode); - inVisitor.Visit(m_HasSkinning); - inVisitor.Visit(m_WireframeMode); - } - - struct SOffsetVisitor - { - QT3DSU32 m_Offset; - SOffsetVisitor() - : m_Offset(0) - { - } - template - void Visit(TPropType &inProp) - { - // if we cross the 32 bit border we just move - // to the next dword. - // This cost a few extra bits but prevents tedious errors like - // loosing shader key bits because they got moved beyond the 32 border - QT3DSU32 bit = m_Offset % 32; - if (bit + TPropType::BitWidth > 31) { - m_Offset += 32 - bit; - } - - inProp.SetOffset(m_Offset); - m_Offset += TPropType::BitWidth; - } - }; - - void SetPropertyOffsets() - { - SOffsetVisitor visitor; - VisitProperties(visitor); - // If this assert fires, then the default material key needs more bits. - QT3DS_ASSERT(visitor.m_Offset < 224); - } - }; - - struct SShaderDefaultMaterialKey - { - enum { - DataBufferSize = 7, - }; - QT3DSU32 m_DataBuffer[DataBufferSize]; - size_t m_FeatureSetHash; - - SShaderDefaultMaterialKey(size_t inFeatureSetHash) - : m_FeatureSetHash(inFeatureSetHash) - { - for (size_t idx = 0; idx < DataBufferSize; ++idx) - m_DataBuffer[idx] = 0; - } - - SShaderDefaultMaterialKey() - : m_FeatureSetHash(0) - { - for (size_t idx = 0; idx < DataBufferSize; ++idx) - m_DataBuffer[idx] = 0; - } - - size_t hash() const - { - size_t retval = 0; - for (size_t idx = 0; idx < DataBufferSize; ++idx) - retval = retval ^ eastl::hash()(m_DataBuffer[idx]); - return retval ^ m_FeatureSetHash; - } - - bool operator==(const SShaderDefaultMaterialKey &other) const - { - bool retval = true; - for (size_t idx = 0; idx < DataBufferSize && retval; ++idx) - retval = m_DataBuffer[idx] == other.m_DataBuffer[idx]; - return retval && m_FeatureSetHash == other.m_FeatureSetHash; - } - - // Cast operators to make getting properties easier. - operator NVDataRef() { return toDataRef(m_DataBuffer, DataBufferSize); } - - operator NVConstDataRef() const - { - return toConstDataRef(m_DataBuffer, DataBufferSize); - } - - struct SStringVisitor - { - eastl::string &m_Str; - NVConstDataRef m_KeyStore; - SStringVisitor(eastl::string &s, NVConstDataRef ks) - : m_Str(s) - , m_KeyStore(ks) - { - } - template - void Visit(const TPropType &prop) - { - QT3DSU32 originalSize = m_Str.size(); - if (m_Str.size()) - m_Str.append(";"); - prop.ToString(m_Str, m_KeyStore); - // if the only thing we added was the semicolon - // then nuke the semicolon - if (originalSize && m_Str.size() == originalSize + 1) - m_Str.resize(originalSize); - } - }; - - void ToString(eastl::string &ioString, - SShaderDefaultMaterialKeyProperties &inProperties) const - { - SStringVisitor theVisitor(ioString, *this); - inProperties.VisitProperties(theVisitor); - } - }; -} -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const qt3ds::render::SShaderDefaultMaterialKey &key) const - { - return key.hash(); - } -}; -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShadowMap.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShadowMap.h deleted file mode 100644 index c5ba2eaa..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderShadowMap.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADOW_MAP_H -#define QT3DS_RENDER_SHADOW_MAP_H -#include "Qt3DSRenderContextCore.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSMat44.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "render/Qt3DSRenderTexture2D.h" -#ifdef _INTEGRITYPLATFORM -#include "render/Qt3DSRenderTextureCube.h" -#endif - -namespace qt3ds { -namespace render { - - struct SLayerRenderData; - - struct ShadowMapModes - { - enum Enum { - SSM, ///< standard shadow mapping - VSM, ///< variance shadow mapping - CUBE, ///< cubemap omnidirectional shadows - }; - }; - - struct ShadowFilterValues - { - enum Enum { - NONE = 1 << 0, ///< hard shadows - PCF = 1 << 1, ///< Percentage close filtering - BLUR = 1 << 2, ///< Gausian Blur - }; - }; - - struct SShadowMapEntry - { - SShadowMapEntry() - : m_LightIndex(QT3DS_MAX_U32) - , m_ShadowMapMode(ShadowMapModes::SSM) - , m_ShadowFilterFlags(ShadowFilterValues::NONE) - { - } - - SShadowMapEntry(QT3DSU32 index, ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter, - NVRenderTexture2D &depthMap, NVRenderTexture2D &depthCopy, - NVRenderTexture2D &depthTemp) - : m_LightIndex(index) - , m_ShadowMapMode(mode) - , m_ShadowFilterFlags(filter) - , m_DepthMap(depthMap) - , m_DepthCopy(depthCopy) - , m_DepthCube(NULL) - , m_CubeCopy(NULL) - , m_DepthRender(depthTemp) - { - } - - SShadowMapEntry(QT3DSU32 index, ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter, - NVRenderTextureCube &depthCube, NVRenderTextureCube &cubeTmp, - NVRenderTexture2D &depthTemp) - : m_LightIndex(index) - , m_ShadowMapMode(mode) - , m_ShadowFilterFlags(filter) - , m_DepthMap(NULL) - , m_DepthCopy(NULL) - , m_DepthCube(depthCube) - , m_CubeCopy(cubeTmp) - , m_DepthRender(depthTemp) - { - } - - QT3DSU32 m_LightIndex; ///< the light index it belongs to - ShadowMapModes::Enum m_ShadowMapMode; ///< shadow map method - ShadowFilterValues::Enum m_ShadowFilterFlags; ///< shadow filter mode - - // PKC : Adding the DepthRender buffer allows us to have a depth+stencil format when filling - // the shadow maps (depth+stencil is necessary), but use a more compact format for the - // actual - // shadow map used at shade time. See if it's worth adding. - NVScopedRefCounted m_DepthMap; ///< shadow map texture - NVScopedRefCounted - m_DepthCopy; ///< shadow map buffer used during blur passes - NVScopedRefCounted m_DepthCube; ///< shadow cube map - NVScopedRefCounted - m_CubeCopy; ///< cube map buffer used during the blur passes - NVScopedRefCounted - m_DepthRender; ///< shadow depth+stencil map used during rendering - - QT3DSMat44 m_LightVP; ///< light view projection matrix - QT3DSMat44 m_LightCubeView[6]; ///< light cubemap view matrices - QT3DSMat44 m_LightView; ///< light view transform - }; - - class Qt3DSShadowMap : public NVRefCounted - { - typedef nvvector TShadowMapEntryList; - - public: - IQt3DSRenderContext &m_Context; - volatile QT3DSI32 mRefCount; - - public: - Qt3DSShadowMap(IQt3DSRenderContext &inContext); - ~Qt3DSShadowMap(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Context.GetAllocator()) - - /* - * @brief Add a shadow map entry - * This creates a new shadow map if it does not exist or changed - * - * @param[in] index shadow map entry index - * @param[in] width shadow map width - * @param[in] height shadow map height - * @param[in] format shadow map format - * @param[in] samples shadow map sample count - * @param[in] mode shadow map mode like SSM, VCM - * @param[in] filter soft shadow map mode filter like PCF - * - * @ return no return - */ - void AddShadowMapEntry(QT3DSU32 index, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum format, QT3DSU32 samples, - ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter); - - /* - * @brief Get a shadow map entry - * - * @param[in] index shadow map entry index - * - * @ return shadow map entry or NULL - */ - SShadowMapEntry *GetShadowMapEntry(QT3DSU32 index); - - /* - * @brief Get shadow map entry count - * - * @ return count of shadow map entries - */ - QT3DSU32 GetShadowMapEntryCount() { return m_ShadowMapList.size(); } - - static Qt3DSShadowMap *Create(IQt3DSRenderContext &inContext); - - private: - TShadowMapEntryList m_ShadowMapList; ///< List of shadow map entries - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderString.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderString.h deleted file mode 100644 index 8d831c20..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderString.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_STRING_H -#define QT3DS_RENDER_STRING_H -#include "Qt3DSRender.h" -#include - -namespace qt3ds { -namespace render { - // can't name this CString else we will conflict a - class CRenderString : public std::basic_string - { - public: - typedef std::basic_string TStrType; - - CRenderString() - : TStrType() - { - } - CRenderString(const CRenderString &inOther) - : TStrType(inOther) - { - } - CRenderString(const TStrType &inOther) - : TStrType(inOther) - { - } - CRenderString &operator=(const CRenderString &inOther) - { - TStrType::operator=(inOther); - return *this; - } - CRenderString &operator=(const char8_t *inOther) - { - TStrType::operator=(inOther); - return *this; - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubPresentationHelper.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubPresentationHelper.h deleted file mode 100644 index d77c7a7f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubPresentationHelper.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SUB_PRESENTATION_HELPER_H -#define QT3DS_RENDER_SUB_PRESENTATION_HELPER_H -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderer.h" -#include "render/Qt3DSRenderContext.h" - -namespace qt3ds { -namespace render { - - // Small helper object to setup the state needed to render a sub presentation - // correctly. Sub presentations may have transparency, and if they do then - // then need to be rendered with pre multiple alpha disabled. If they don't, - // then they need to be rendered with pre-multiply alpha enabled (and have the alpha channel - // set to 1 - struct SSubPresentationHelper - { - IQt3DSRenderContext &m_RenderContext; - QSize m_PreviousPresentationDimensions; - - bool m_WasInSubPresentation; - - SSubPresentationHelper(IQt3DSRenderContext &inContext, - const QSize &inPresDimensions) - : m_RenderContext(inContext) - , m_PreviousPresentationDimensions(inContext.GetCurrentPresentationDimensions()) - , m_WasInSubPresentation(inContext.IsInSubPresentation()) - { - m_RenderContext.SetInSubPresentation(true); - m_RenderContext.SetPresentationDimensions(inPresDimensions); - } - ~SSubPresentationHelper() - { - m_RenderContext.SetInSubPresentation(m_WasInSubPresentation); - m_RenderContext.SetPresentationDimensions(m_PreviousPresentationDimensions); - } - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h deleted file mode 100644 index 9eb51450..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SUBPRESENTATION_H -#define QT3DS_RENDER_SUBPRESENTATION_H - -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSRenderSubPresentationHelper.h" -#include "Qt3DSRenderPresentation.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - - class CSubPresentationRenderer; - - struct CSubPresentationPickQuery : public IGraphObjectPickQuery - { - CSubPresentationRenderer &m_Renderer; - - CSubPresentationPickQuery(CSubPresentationRenderer &renderer) - : m_Renderer(renderer) - { - } - Qt3DSRenderPickResult Pick(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool inPickEverything) override; - }; - - class CSubPresentationRenderer : public IOffscreenRenderer - { - public: - IQt3DSRenderContext &m_RenderContext; - SPresentation &m_Presentation; - volatile QT3DSI32 mRefCount; - SOffscreenRendererEnvironment m_LastRenderedEnvironment; - CSubPresentationPickQuery m_PickQuery; - CRegisteredString m_OffscreenRendererType; - - CSubPresentationRenderer(IQt3DSRenderContext &inRenderContext, SPresentation &inPresentation); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) - - SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresScale) override; - virtual SOffscreenRenderFlags - NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, QT3DSVec2 inPresScale, - const SRenderInstanceId instanceId) override; - void Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext & /*inRenderContext*/, - QT3DSVec2 inPresScale, SScene::RenderClearCommand inClearBuffer, - const SRenderInstanceId instanceId) override; - void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, - QT3DSVec2 inPresScale, SScene::RenderClearCommand inClearBuffer, - QT3DSVec3 inClearColor, - const SRenderInstanceId instanceId) override; - IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId) override { return &m_PickQuery; } - bool Pick(const QT3DSVec2 & /*inMouseCoords*/, const QT3DSVec2 & /*inViewportDimensions*/, - const SRenderInstanceId) override - { - return false; - } - void addCallback(IOffscreenRendererCallback *cb) override - { - - } - // Used for RTTI purposes so we can safely static-cast an offscreen renderer to a - // CSubPresentationRenderer - static const char *GetRendererName() { return "SubPresentation"; } - CRegisteredString GetOffscreenRendererType() override { return m_OffscreenRendererType; } - - Qt3DSRenderPickResult DoGraphQueryPick(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool inPickEverything); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTaggedPointer.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTaggedPointer.h deleted file mode 100644 index 8dd8bdd0..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTaggedPointer.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TAGGED_POINTER_H -#define QT3DS_RENDER_TAGGED_POINTER_H -#include "Qt3DSRender.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - - // User's will need to define specialize this struct in order - // to de-tag a pointer. - template - struct SPointerTag - { - /* Expected API for runtime RTTI - static CRegisteredString GetTag() { return g_dtype_specific_string; } - */ - }; - - // A pointer tagged with an identifier so we can have generic - // user data that is still somewhat typesafe. - struct STaggedPointer - { - void *m_UserData; - QT3DSU32 m_Tag; - STaggedPointer() - : m_UserData(NULL) - , m_Tag(0) - { - } - - STaggedPointer(void *inUserData, QT3DSU32 inTag) - : m_UserData(inUserData) - , m_Tag(inTag) - { - } - - template - STaggedPointer(TDataType *inType) - : m_UserData(reinterpret_cast(inType)) - , m_Tag(SPointerTag::GetTag()) - { - } - - template - TDataType *DynamicCast() const - { - if (m_Tag == SPointerTag::GetTag()) - return reinterpret_cast(m_UserData); - return NULL; - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTessModeValues.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTessModeValues.h deleted file mode 100644 index 15ea03c9..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTessModeValues.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TESS_MODE_VALUES_H -#define QT3DS_RENDER_TESS_MODE_VALUES_H -#include "Qt3DSRender.h" - -namespace qt3ds { -namespace render { - - struct SDefaultMaterial; - class IBufferManager; - - struct TessModeValues - { - enum Enum { - NoTess = 0, - TessLinear = 1, - TessPhong = 2, - TessNPatch = 3, - }; - - static const char *toString(Enum value) - { - switch (value) { - case NoTess: - return "NoTess"; - break; - case TessLinear: - return "TessLinear"; - break; - case TessPhong: - return "TessPhong"; - break; - case TessNPatch: - return "TessNPatch"; - break; - default: - return "NoTess"; - break; - } - } - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureAtlas.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureAtlas.h deleted file mode 100644 index 7a3f1215..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureAtlas.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TEXT_TEXTURE_ATLAS_H -#define QT3DS_RENDER_TEXT_TEXTURE_ATLAS_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSRenderText.h" -#include "EASTL/algorithm.h" - -namespace qt3ds { -namespace render { - - class ITextRenderer; - - typedef eastl::pair> - TTextTextureAtlasDetailsAndTexture; - typedef eastl::pair> - TTextRenderAtlasDetailsAndTexture; - - class ITextTextureAtlas : public NVRefCounted - { - protected: - virtual ~ITextTextureAtlas() {} - public: - virtual TTextRenderAtlasDetailsAndTexture RenderText(const STextRenderInfo &inText) = 0; - virtual bool IsInitialized() = 0; - virtual TTextTextureAtlasDetailsAndTexture PrepareTextureAtlas() = 0; - - static ITextTextureAtlas &CreateTextureAtlas(NVFoundationBase &inFnd, - ITextRenderer &inTextRenderer, - NVRenderContext &inRenderContext); - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureCache.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureCache.h deleted file mode 100644 index 45d40217..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTextureCache.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TEXT_TEXTURE_CACHE_H -#define QT3DS_RENDER_TEXT_TEXTURE_CACHE_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSRenderText.h" -#include "EASTL/algorithm.h" - -namespace qt3ds { -namespace render { - - class ITextRenderer; - - typedef eastl::pair, - NVScopedRefCounted> - TPathFontSpecAndPathObject; - typedef eastl::pair> - TTextTextureDetailsAndTexture; - typedef eastl::pair - TTPathObjectAndTexture; - - class ITextTextureCache : public NVRefCounted - { - protected: - virtual ~ITextTextureCache() {} - public: - virtual TTPathObjectAndTexture RenderText(const STextRenderInfo &inText, - QT3DSF32 inScaleFactor) = 0; - // We may have one more texture in cache than this byte count, but this will be the limiting - // factor. - virtual QT3DSU32 GetCacheHighWaterBytes() const = 0; - virtual void SetCacheHighWaterBytes(QT3DSU32 inNumBytes) = 0; - - virtual void BeginFrame() = 0; - // We need to know the frame rhythm because we can't release anything that was touched this - // frame. - virtual void EndFrame() = 0; - - static ITextTextureCache &CreateTextureCache(NVFoundationBase &inFnd, - ITextRenderer &inTextRenderer, - NVRenderContext &inRenderContext); - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTypes.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTypes.h deleted file mode 100644 index 72ea9c15..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextTypes.h +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2015 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TEXT_TYPES_H -#define QT3DS_RENDER_TEXT_TYPES_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSVec2.h" - -namespace qt3ds { -namespace render { - - struct TextHorizontalAlignment - { - enum Enum { - Unknown = 0, - Left, - Center, - Right, - }; - }; - - struct TextVerticalAlignment - { - enum Enum { - Unknown = 0, - Top, - Middle, - Bottom, - }; - }; - - struct TextWordWrap - { - enum Enum { - Unknown = 0, - Clip, - WrapWord, - WrapAnywhere, - }; - }; - - struct TextElide - { - enum Enum { - ElideNone = 0, - ElideLeft, - ElideMiddle, - ElideRight, - }; - }; - - struct STextDimensions - { - QT3DSU32 m_TextWidth; - QT3DSU32 m_TextHeight; - STextDimensions(QT3DSU32 w, QT3DSU32 h) - : m_TextWidth(w) - , m_TextHeight(h) - { - } - STextDimensions() - : m_TextWidth(0) - , m_TextHeight(0) - { - } - }; - - struct STextTextureDetails : public STextDimensions - { - QT3DSVec2 m_ScaleFactor; - bool m_FlipY; - STextTextureDetails(QT3DSU32 w, QT3DSU32 h, bool inFlipY, QT3DSVec2 scaleF) - : STextDimensions(w, h) - , m_ScaleFactor(scaleF) - , m_FlipY(inFlipY) - { - } - STextTextureDetails() - : m_ScaleFactor(1.0f) - , m_FlipY(false) - { - } - }; - - struct STextTextureAtlasEntryDetails : public STextDimensions - { - QT3DSI32 m_X, m_Y; - STextTextureAtlasEntryDetails(QT3DSU32 w, QT3DSU32 h, QT3DSI32 x, QT3DSI32 y) - : STextDimensions(w, h) - , m_X(x) - , m_Y(y) - { - } - STextTextureAtlasEntryDetails() - : m_X(0) - , m_Y(0) - { - } - }; - - struct SRenderTextureAtlasDetails - { - QT3DSU32 m_VertexCount; - NVDataRef m_Vertices; - - SRenderTextureAtlasDetails(QT3DSU32 count, NVDataRef inVertices) - : m_VertexCount(count) - , m_Vertices(inVertices) - { - } - SRenderTextureAtlasDetails() - : m_VertexCount(0) - , m_Vertices(NVDataRef()) - { - } - }; - - struct STextTextureAtlasDetails : public STextTextureDetails - { - QT3DSU32 m_EntryCount; - STextTextureAtlasDetails(QT3DSU32 w, QT3DSU32 h, bool inFlipY, QT3DSU32 count) - : STextTextureDetails(w, h, inFlipY, QT3DSVec2(1.0f)) - , m_EntryCount(count) - { - } - STextTextureAtlasDetails() - : m_EntryCount(0) - { - } - }; - - // Adding/removing a member to this object means you need to update the texture cache code - // - UICRenderTextTextureCache.cpp - - struct STextRenderInfo - { - CRegisteredString m_Text; - CRegisteredString m_Font; - QT3DSF32 m_FontSize; - TextHorizontalAlignment::Enum m_HorizontalAlignment; - TextVerticalAlignment::Enum m_VerticalAlignment; - QT3DSF32 m_Leading; // space between lines - QT3DSF32 m_Tracking; // space between letters - bool m_DropShadow; - QT3DSF32 m_DropShadowStrength; - QT3DSF32 m_DropShadowOffset; // To be removed in 2.x (when UIP version is next updated) - QT3DSF32 m_DropShadowOffsetX; - QT3DSF32 m_DropShadowOffsetY; - TextHorizontalAlignment::Enum m_DropShadowHorizontalAlignment; // To be removed in 2.x (when UIP version is next updated) - TextVerticalAlignment::Enum m_DropShadowVerticalAlignment; // To be removed in 2.x (when UIP version is next updated) - TextWordWrap::Enum m_WordWrap; - QT3DSVec2 m_BoundingBox; - TextElide::Enum m_Elide; - - QT3DSF32 m_ScaleX; // Pixel scale in X - QT3DSF32 m_ScaleY; // Pixel scale in Y - - bool m_EnableAcceleratedFont; ///< use NV path rendering - - STextRenderInfo(); - ~STextRenderInfo(); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextureAtlas.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextureAtlas.h deleted file mode 100644 index 46f7bdb5..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderTextureAtlas.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_TEXTURE_ATLAS_H -#define QT3DS_RENDER_TEXTURE_ATLAS_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "EASTL/algorithm.h" - -namespace qt3ds { -namespace render { - - class ITextRenderer; - - struct STextureAtlasRect - { - - STextureAtlasRect() - : m_X(0) - , m_Y(0) - , m_Width(0) - , m_Height(0) - { - } - - STextureAtlasRect(QT3DSI32 x, QT3DSI32 y, QT3DSI32 w, QT3DSI32 h) - : m_X(x) - , m_Y(y) - , m_Width(w) - , m_Height(h) - { - } - - QT3DSI32 m_X; - QT3DSI32 m_Y; - QT3DSI32 m_Width; - QT3DSI32 m_Height; - - // normalized coordinates - QT3DSF32 m_NormX; - QT3DSF32 m_NormY; - QT3DSF32 m_NormWidth; - QT3DSF32 m_NormHeight; - }; - - typedef eastl::pair> TTextureAtlasEntryAndBuffer; - - /** - * Abstract class of a texture atlas representation - */ - class ITextureAtlas : public NVRefCounted - { - protected: - virtual ~ITextureAtlas() {} - - public: - virtual QT3DSI32 GetWidth() const = 0; - virtual QT3DSI32 GetHeight() const = 0; - virtual QT3DSI32 GetAtlasEntryCount() const = 0; - virtual TTextureAtlasEntryAndBuffer GetAtlasEntryByIndex(QT3DSU32 index) = 0; - - virtual STextureAtlasRect AddAtlasEntry(QT3DSI32 width, QT3DSI32 height, QT3DSI32 pitch, - QT3DSI32 dataWidth, - NVConstDataRef bufferData) = 0; - virtual void RelaseEntries() = 0; - - static ITextureAtlas &CreateTextureAtlas(NVFoundationBase &inFnd, - NVRenderContext &inRenderContext, QT3DSI32 width, - QT3DSI32 height); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderThreadPool.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderThreadPool.h deleted file mode 100644 index d39f226f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderThreadPool.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_THREAD_POOL_H -#define QT3DS_RENDER_THREAD_POOL_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" - -namespace qt3ds { -namespace render { - - typedef void (*TTaskFunction)(void *inUserData); - - struct TaskStates - { - enum Enum { - UnknownTask = 0, - Queued, - Running, - }; - }; - - struct CancelReturnValues - { - enum Enum { - TaskCanceled = 0, - TaskRunning, - TaskNotFound, - }; - }; - - class IThreadPool : public NVRefCounted - { - protected: - virtual ~IThreadPool() {} - public: - // Add a task to be run at some point in the future. - // Tasks will be run roughly in order they are given. - // The returned value is a handle that can be used to query - // details about the task - // Cancel function will be called if the thread pool is destroyed or - // of the task gets canceled. - virtual QT3DSU64 AddTask(void *inUserData, TTaskFunction inFunction, - TTaskFunction inCancelFunction) = 0; - virtual TaskStates::Enum GetTaskState(QT3DSU64 inTaskId) = 0; - virtual CancelReturnValues::Enum CancelTask(QT3DSU64 inTaskId) = 0; - - static IThreadPool &CreateThreadPool(NVFoundationBase &inFoundation, - QT3DSU32 inNumThreads = 4); - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h deleted file mode 100644 index 2b70c687..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_UIP_LOADER_H -#define QT3DS_RENDER_UIP_LOADER_H - -#ifdef QT3DS_RENDER_ENABLE_LOAD_UIP - -#include "Qt3DSRender.h" -#include "foundation/StringTable.h" -#include -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderGraphObject.h" -#include - -namespace Q3DStudio { -class IRuntimeMetaData; -} - -namespace qt3dsdm { -class IDOMReader; -struct SMetaDataEffect; -struct SMetaDataCustomMaterial; -} - -namespace qt3ds { -class Q3DSVariantConfig; - -namespace render { - - class IBufferManager; - - typedef nvhash_map TIdObjectMap; - - struct IUIPReferenceResolver - { - protected: - virtual ~IUIPReferenceResolver() {} - public: - virtual CRegisteredString ResolveReference(CRegisteredString inStart, - const char *inReference) = 0; - }; - - struct SPresentation; - - class QT3DS_AUTOTEST_EXPORT IUIPLoader - { - public: - // The reader needs to point to the top of the file, we will search - // several objects that exist at the top level of the uip file. - // Returns NULL if we were incapable of loading the presentation. - static SPresentation * - LoadUIPFile(qt3dsdm::IDOMReader &inReader - // the full path, including the filename - // to the presentation file - , - const char8_t *inFullPathToPresentationFile, - Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable, - NVFoundationBase &inFoundation - // Allocator used for the presentation objects themselves - // this allows clients to pre-allocate a block of memory just for - // the scene graph - , - NVAllocatorCallback &inPresentationAllocator - // Map of string ids to objects - , - TIdObjectMap &ioObjectMap - // Buffer manager to load details about the images - , - IBufferManager &inBufferManager - // To load effects we need the effect system - // and the presentation directory - , - IEffectSystem &inEffectSystem, const char8_t *inPresentationDir, - IRenderPluginManager &inPluginManager, ICustomMaterialSystem &inMaterialSystem, - IDynamicObjectSystem &inDynamicSystem, qt3ds::render::IPathManager &inPathManager - // Resolve references to objects; this is done by the main uip loader during - // its normal mode of operation so we try to reuse that code. - , - IUIPReferenceResolver *inResolver - // Variant config defines variant groups and tags to be used to filter out - // unneeded parts of the presentation - , - const Q3DSVariantConfig &variantConfig - // Set some initial values by going to the master slide then slide 1 - // Useful for quick testing, sort of equivalent to showing the first frame - // of a given presentation - , - bool setValuesFromSlides = false); - - static void CreateEffectClassFromMetaEffect(CRegisteredString inEffectName, - NVFoundationBase &inFoundation, - IEffectSystem &inEffectSystem, - const qt3dsdm::SMetaDataEffect &inMetaDataEffect, - IStringTable &inStrTable); - - static void CreateMaterialClassFromMetaMaterial( - CRegisteredString inEffectName, NVFoundationBase &inFoundation, - ICustomMaterialSystem &inEffectSystem, - const qt3dsdm::SMetaDataCustomMaterial &inMetaDataMaterial, IStringTable &inStrTable); - }; -} -} - -#endif -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPSharedTranslation.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPSharedTranslation.h deleted file mode 100644 index 8ba74eae..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPSharedTranslation.h +++ /dev/null @@ -1,488 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_UIP_SHARED_TRANSLATION_H -#define QT3DS_RENDER_UIP_SHARED_TRANSLATION_H -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSRenderText.h" -#include "Qt3DSDMWindowsCompatibility.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderModel.h" -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderPresentation.h" - -// map from qt3dsdm to qt3ds::render -namespace qt3ds { -namespace render { - - template - struct SEnumParseMap - { - }; - - struct SEnumNameMap - { - QT3DSU32 m_Enum; - const wchar_t *m_WideName; - const char8_t *m_Name; - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - - template <> - struct SEnumParseMap - { - static SEnumNameMap *GetMap(); - }; - -#define QT3DS_RENDER_WCHAR_T_XYZs L"XYZ" -#define QT3DS_RENDER_WCHAR_T_YZXs L"YZX" -#define QT3DS_RENDER_WCHAR_T_ZXYs L"ZXY" -#define QT3DS_RENDER_WCHAR_T_XZYs L"XZY" -#define QT3DS_RENDER_WCHAR_T_YXZs L"YXZ" -#define QT3DS_RENDER_WCHAR_T_ZYXs L"ZYX" - -#define QT3DS_RENDER_WCHAR_T_XYZr L"XYZr" -#define QT3DS_RENDER_WCHAR_T_YZXr L"YZXr" -#define QT3DS_RENDER_WCHAR_T_ZXYr L"ZXYr" -#define QT3DS_RENDER_WCHAR_T_XZYr L"XZYr" -#define QT3DS_RENDER_WCHAR_T_YXZr L"YXZr" -#define QT3DS_RENDER_WCHAR_T_ZYXr L"ZYXr" - -#define QT3DS_RENDER_CHAR_T_XYZs "XYZ" -#define QT3DS_RENDER_CHAR_T_YZXs "YZX" -#define QT3DS_RENDER_CHAR_T_ZXYs "ZXY" -#define QT3DS_RENDER_CHAR_T_XZYs "XZY" -#define QT3DS_RENDER_CHAR_T_YXZs "YXZ" -#define QT3DS_RENDER_CHAR_T_ZYXs "ZYX" - -#define QT3DS_RENDER_CHAR_T_XYZr "XYZr" -#define QT3DS_RENDER_CHAR_T_YZXr "YZXr" -#define QT3DS_RENDER_CHAR_T_ZXYr "ZXYr" -#define QT3DS_RENDER_CHAR_T_XZYr "XZYr" -#define QT3DS_RENDER_CHAR_T_YXZr "YXZr" -#define QT3DS_RENDER_CHAR_T_ZYXr "ZYXr" - - inline QT3DSU32 MapRotationOrder(const wchar_t *inOrderStr) - { -#define MAP_ROTATION_ORDER(name, postfix) \ - if (wcscmp(inOrderStr, QT3DS_RENDER_WCHAR_T_##name##postfix) == 0) { \ - return EulOrd##name##postfix; \ - } - MAP_ROTATION_ORDER(XYZ, s); - MAP_ROTATION_ORDER(YZX, s); - MAP_ROTATION_ORDER(ZXY, s); - MAP_ROTATION_ORDER(XZY, s); - MAP_ROTATION_ORDER(YXZ, s); - MAP_ROTATION_ORDER(ZYX, s); - MAP_ROTATION_ORDER(XYZ, r); - MAP_ROTATION_ORDER(YZX, r); - MAP_ROTATION_ORDER(ZXY, r); - MAP_ROTATION_ORDER(XZY, r); - MAP_ROTATION_ORDER(YXZ, r); - MAP_ROTATION_ORDER(ZYX, r); -#undef MAP_ROTATION_ORDER - return EulOrdYXZs; - } - - inline QT3DSU32 MapRotationOrder(const char8_t *inOrderStr) - { -#define MAP_ROTATION_ORDER(name, postfix) \ - if (strcmp(inOrderStr, QT3DS_RENDER_CHAR_T_##name##postfix) == 0) { \ - return EulOrd##name##postfix; \ - } - MAP_ROTATION_ORDER(XYZ, s); - MAP_ROTATION_ORDER(YZX, s); - MAP_ROTATION_ORDER(ZXY, s); - MAP_ROTATION_ORDER(XZY, s); - MAP_ROTATION_ORDER(YXZ, s); - MAP_ROTATION_ORDER(ZYX, s); - MAP_ROTATION_ORDER(XYZ, r); - MAP_ROTATION_ORDER(YZX, r); - MAP_ROTATION_ORDER(ZXY, r); - MAP_ROTATION_ORDER(XZY, r); - MAP_ROTATION_ORDER(YXZ, r); - MAP_ROTATION_ORDER(ZYX, r); -#undef MAP_ROTATION_ORDER - return EulOrdYXZs; - } - - // the goal is to unify the systems that transfer information into the UICRender library. - // There are currently three such systems; the runtime, studio, and the uip loader that loads - // uip files - // directly into the render library. - // To do this, we need to have a mapping between a generic key and a given property on every - // object - // along with some information about what portion of the object model this property affects. - - struct Qt3DSRenderDirtyFlags - { - enum Enum { - Unknown = 0, - Dirty = 1 << 0, - TransformDirty = 1 << 1, - TextDirty = 1 << 2, - }; - }; - -// Now we build out generic macros with no implementation that list all of the properties -// on each struct that we care about. We will fill in these macros with implementation later. -// Each macro will list the property name along with what dirty operation should get marked -// Global parse tables that list every property used by the system. - -#define ITERATE_QT3DS_RENDER_SCENE_PROPERTIES \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Scene, ClearColor, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Scene, UseClearColor, Dirty) - -#define ITERATE_QT3DS_RENDER_NODE_PROPERTIES \ - HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Rotation, TransformDirty) \ - HANDLE_QT3DS_RENDER_VEC3_RADIAN_PROPERTY(Node, Rotation, TransformDirty) \ - HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Position, TransformDirty) \ - HANDLE_QT3DS_RENDER_VEC3_PROPERTY(Node, Position, TransformDirty) \ - HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Scale, TransformDirty) \ - HANDLE_QT3DS_RENDER_VEC3_PROPERTY(Node, Scale, TransformDirty) \ - HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Pivot, TransformDirty) \ - HANDLE_QT3DS_RENDER_VEC3_PROPERTY(Node, Pivot, TransformDirty) \ - HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(Node, LocalOpacity, TransformDirty) \ - HANDLE_QT3DS_ROTATION_ORDER_PROPERTY(Node, RotationOrder, TransformDirty) \ - HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY(Node, LeftHanded, TransformDirty) - -#define ITERATE_QT3DS_RENDER_LAYER_PROPERTIES \ - HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(Layer, LayerEnableDepthTest, Dirty) \ - HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(Layer, LayerEnableDepthPrePass, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, ProgressiveAAMode, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, MultisampleAAMode, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, TemporalAAEnabled, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Layer, ClearColor, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, BlendType, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, Background, Dirty) \ - HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Layer, TexturePath, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, HorizontalFieldValues, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Left, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, LeftUnits, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Width, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, WidthUnits, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Right, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, RightUnits, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, VerticalFieldValues, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Top, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, TopUnits, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Height, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, HeightUnits, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Bottom, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, BottomUnits, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoStrength, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoDistance, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoSoftness, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoBias, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoDither, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowStrength, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowDist, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowSoftness, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowBias, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, LightProbe, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ProbeBright, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, FastIbl, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ProbeHorizon, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, ProbeFov, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, LightProbe2, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Probe2Fade, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Probe2Window, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Layer, Probe2Pos, Dirty) - -#define ITERATE_QT3DS_RENDER_CAMERA_PROPERTIES \ - HANDLE_QT3DS_RENDER_PROPERTY(Camera, ClipNear, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Camera, ClipFar, Dirty) \ - HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(Camera, FOV, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Camera, FOVHorizontal, Dirty) \ - HANDLE_QT3DS_NODE_FLAGS_PROPERTY(Camera, Orthographic, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Camera, ScaleMode, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Camera, ScaleAnchor, Dirty) - -#define ITERATE_QT3DS_RENDER_LIGHT_PROPERTIES \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Light, LightType, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, Scope, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Light, DiffuseColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Light, DiffuseColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Light, SpecularColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Light, SpecularColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Light, AmbientColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Light, AmbientColor, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, Brightness, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, LinearFade, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, ExponentialFade, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, AreaWidth, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, AreaHeight, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, CastShadow, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowBias, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowFactor, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowMapFar, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowMapFov, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowFilter, Dirty) - -#define ITERATE_QT3DS_RENDER_MODEL_PROPERTIES \ - HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Model, MeshPath, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Model, ShadowCaster, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Model, TessellationMode, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Model, EdgeTess, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Model, InnerTess, Dirty) - -#define ITERATE_QT3DS_RENDER_CUSTOM_MATERIAL_PROPERTIES \ - HANDLE_QT3DS_RENDER_PROPERTY(MaterialBase, IblProbe, Dirty) - -#define ITERATE_QT3DS_RENDER_LIGHTMAP_PROPERTIES \ - HANDLE_QT3DS_RENDER_PROPERTY(Lightmaps, LightmapIndirect, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Lightmaps, LightmapRadiosity, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Lightmaps, LightmapShadow, Dirty) - -#define ITERATE_QT3DS_RENDER_MATERIAL_PROPERTIES \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Material, Lighting, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Material, BlendMode, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, VertexColors, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(MaterialBase, IblProbe, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Material, DiffuseColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Material, DiffuseColor, Dirty) \ - HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(Material, DiffuseMaps, 0, Dirty) \ - HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(Material, DiffuseMaps, 1, Dirty) \ - HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(Material, DiffuseMaps, 2, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, EmissivePower, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Material, EmissiveColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Material, EmissiveColor, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, EmissiveMap, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, EmissiveMap2, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularReflection, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularMap, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Material, SpecularModel, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Material, SpecularTint, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Material, SpecularTint, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, FresnelPower, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, IOR, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularAmount, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularRoughness, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, RoughnessMap, Dirty) \ - HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(Material, Opacity, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, OpacityMap, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, BumpMap, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, BumpAmount, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, NormalMap, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, DisplacementMap, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, DisplaceAmount, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, TranslucencyMap, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, TranslucentFalloff, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, DiffuseLightWrap, Dirty) - -#define ITERATE_QT3DS_RENDER_REFERENCED_MATERIAL_PROPERTIES \ - HANDLE_QT3DS_RENDER_PROPERTY(Material, ReferencedMaterial, Dirty) - -#define ITERATE_QT3DS_RENDER_IMAGE_PROPERTIES \ - HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Image, ImagePath, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Image, OffscreenRendererId, Dirty) \ - HANDLE_QT3DS_RENDER_VEC2_PROPERTY(Image, Scale, TransformDirty) \ - HANDLE_QT3DS_RENDER_VEC2_PROPERTY(Image, Pivot, TransformDirty) \ - HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(Image, Rotation, TransformDirty) \ - HANDLE_QT3DS_RENDER_VEC2_PROPERTY(Image, Position, TransformDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Image, MappingMode, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Image, HorizontalTilingMode, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Image, VerticalTilingMode, Dirty) - -#define ITERATE_QT3DS_RENDER_TEXT_PROPERTIES \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, Text, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, Font, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, FontSize, TextDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, HorizontalAlignment, TextDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, VerticalAlignment, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, Leading, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, Tracking, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadow, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowStrength, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowOffset, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowOffsetX, TextDirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowOffsetY, TextDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, DropShadowHorizontalAlignment, TextDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, DropShadowVerticalAlignment, TextDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, WordWrap, TextDirty) \ - HANDLE_QT3DS_RENDER_REAL_VEC2_PROPERTY(Text, BoundingBox, TextDirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, Elide, TextDirty) \ - HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Text, TextColor, Dirty) \ - HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Text, TextColor, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Text, EnableAcceleratedFont, Dirty) - -#define ITERATE_QT3DS_RENDER_PATH_PROPERTIES \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, PathType, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, Width, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, LinearError, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, EdgeTessAmount, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, InnerTessAmount, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, BeginCapping, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, BeginCapOffset, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, BeginCapOpacity, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, BeginCapWidth, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, EndCapping, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, EndCapOffset, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, EndCapOpacity, Dirty) \ - HANDLE_QT3DS_RENDER_PROPERTY(Path, EndCapWidth, Dirty) \ - HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, PaintStyle, Dirty) \ - HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Path, PathBuffer, Dirty) - -#define ITERATE_QT3DS_RENDER_PATH_SUBPATH_PROPERTIES \ - HANDLE_QT3DS_RENDER_PROPERTY(SubPath, Closed, Dirty) -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderWidgets.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderWidgets.h deleted file mode 100644 index 28cb3322..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderWidgets.h +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_WIDGETS_H -#define QT3DS_RENDER_WIDGETS_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSMat44.h" -#include "foundation/Qt3DSMat33.h" -#include "foundation/Qt3DSBounds3.h" -#include "foundation/Qt3DSVec3.h" -#include "EASTL/utility.h" -#include "foundation/Qt3DSDataRef.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderIndexBuffer.h" -#include "Qt3DSRenderText.h" - -namespace qt3ds { -namespace render { - - struct SWidgetRenderInformation - { - // Just the rotation component of the nodeparenttocamera. - QT3DSMat33 m_NormalMatrix; - // The node parent's global transform multiplied by the inverse camera global transfrom; - // basically the MV from model-view-projection - QT3DSMat44 m_NodeParentToCamera; - // Projection that accounts for layer scaling - QT3DSMat44 m_LayerProjection; - // Pure camera projection without layer scaling - QT3DSMat44 m_PureProjection; - // A look at matrix that will rotate objects facing directly up - // the Z axis such that the point to the camera. - QT3DSMat33 m_LookAtMatrix; - // Conversion from world to camera position so world points not in object - // local space can be converted to camera space without going through the node's - // inverse global transform - QT3DSMat44 m_CameraGlobalInverse; - // Offset to add to the node's world position in camera space to move to the ideal camera - // location so that scale will work. This offset should be added *after* translation into - // camera space - QT3DSVec3 m_WorldPosOffset; - // Position in camera space to center the widget around - QT3DSVec3 m_Position; - // Scale factor to scale the widget by. - QT3DSF32 m_Scale; - - // The camera used to render this object. - SCamera *m_Camera; - SWidgetRenderInformation(const QT3DSMat33 &inNormal, const QT3DSMat44 &inNodeParentToCamera, - const QT3DSMat44 &inLayerProjection, const QT3DSMat44 &inProjection, - const QT3DSMat33 &inLookAt, const QT3DSMat44 &inCameraGlobalInverse, - const QT3DSVec3 &inWorldPosOffset, const QT3DSVec3 &inPos, QT3DSF32 inScale, - SCamera &inCamera) - : m_NormalMatrix(inNormal) - , m_NodeParentToCamera(inNodeParentToCamera) - , m_LayerProjection(inLayerProjection) - , m_PureProjection(inProjection) - , m_LookAtMatrix(inLookAt) - , m_CameraGlobalInverse(inCameraGlobalInverse) - , m_WorldPosOffset(inWorldPosOffset) - , m_Position(inPos) - , m_Scale(inScale) - , m_Camera(&inCamera) - { - } - SWidgetRenderInformation() - : m_Camera(NULL) - { - } - }; - typedef eastl::pair - TShaderGeneratorPair; - - struct RenderWidgetModes - { - enum Enum { - Local, - Global, - }; - }; - // Context used to get render data for the widget. - class IRenderWidgetContext - { - protected: - virtual ~IRenderWidgetContext() {} - public: - virtual NVRenderVertexBuffer & - GetOrCreateVertexBuffer(CRegisteredString &inStr, QT3DSU32 stride, - NVConstDataRef bufferData = NVConstDataRef()) = 0; - virtual NVRenderIndexBuffer & - GetOrCreateIndexBuffer(CRegisteredString &inStr, - qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, - NVConstDataRef bufferData = NVConstDataRef()) = 0; - virtual NVRenderAttribLayout & - CreateAttributeLayout(NVConstDataRef attribs) = 0; - virtual NVRenderInputAssembler & - GetOrCreateInputAssembler(CRegisteredString &inStr, NVRenderAttribLayout *attribLayout, - NVConstDataRef buffers, - const NVRenderIndexBuffer *indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets) = 0; - - virtual NVRenderVertexBuffer *GetVertexBuffer(CRegisteredString &inStr) = 0; - virtual NVRenderIndexBuffer *GetIndexBuffer(CRegisteredString &inStr) = 0; - virtual NVRenderInputAssembler *GetInputAssembler(CRegisteredString &inStr) = 0; - - virtual NVRenderShaderProgram *GetShader(CRegisteredString inStr) = 0; - virtual IShaderProgramGenerator &GetProgramGenerator() = 0; - // calls compile on the program generator and stores result under this name. - virtual NVRenderShaderProgram *CompileAndStoreShader(CRegisteredString inStr) = 0; - virtual STextDimensions MeasureText(const STextRenderInfo &inText) = 0; - // Render text using a specific MVP - virtual void RenderText(const STextRenderInfo &inText, const QT3DSVec3 &inTextColor, - const QT3DSVec3 &inBackgroundColor, const QT3DSMat44 &inMVP) = 0; - // Given a node and a point in the node's local space (most likely its pivot point), we - // return - // a normal matrix so you can get the axis out, a transformation from node to camera - // a new position and a floating point scale factor so you can render in 1/2 perspective - // mode - // or orthographic mode if you would like to. - virtual SWidgetRenderInformation - GetWidgetRenderInformation(SNode &inNode, const QT3DSVec3 &inPos, - RenderWidgetModes::Enum inWidgetMode) = 0; - }; - - class IRenderWidget - { - protected: - virtual ~IRenderWidget() {} - SNode *m_Node; - - public: - IRenderWidget(SNode &inNode) - : m_Node(&inNode) - { - } - IRenderWidget() - : m_Node(NULL) - { - } - virtual void Render(IRenderWidgetContext &inWidgetContext, - NVRenderContext &inRenderContext) = 0; - SNode &GetNode() { return *m_Node; } - - // Pure widgets. - static IRenderWidget &CreateBoundingBoxWidget(SNode &inNode, const NVBounds3 &inBounds, - const QT3DSVec3 &inColor, - NVAllocatorCallback &inAlloc); - static IRenderWidget &CreateAxisWidget(SNode &inNode, NVAllocatorCallback &inAlloc); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderableImage.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderableImage.h deleted file mode 100644 index 5d4aa1c4..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderableImage.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDERABLE_IMAGE_H -#define QT3DS_RENDERABLE_IMAGE_H -#include "Qt3DSRender.h" - -namespace qt3ds { -namespace render { - - struct ImageMapTypes - { - enum Enum { - Unknown = 0, - Diffuse = 1, - Opacity = 2, - Specular = 3, - Emissive = 4, - Bump = 5, - SpecularAmountMap = 6, - Normal = 7, - Displacement = 8, - Translucency = 9, - LightmapIndirect = 10, - LightmapRadiosity = 11, - LightmapShadow = 12, - Roughness = 13, - }; - }; - - /** - * Some precomputed information on a given image. When generating a renderable, the shader - * generator goes through all the possible images on a material and for each valid image - * computes this renderable image and attaches it to the renderable. - */ - struct SRenderableImage - { - ImageMapTypes::Enum m_MapType; - SImage &m_Image; - SRenderableImage *m_NextImage; - SRenderableImage(ImageMapTypes::Enum inMapType, SImage &inImage) - : m_MapType(inMapType) - , m_Image(inImage) - , m_NextImage(NULL) - { - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderer.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderer.h deleted file mode 100644 index 360ebf48..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderer.h +++ /dev/null @@ -1,249 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDERER_H -#define QT3DS_RENDERER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSFlags.h" -#include "EASTL/algorithm.h" //pair -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSVec2.h" -#include "Qt3DSRenderGraphObjectPickQuery.h" -#include "Qt3DSRenderCamera.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "Qt3DSRenderRay.h" - -namespace qt3ds { -namespace render { - - class IRenderableObject; - struct SModel; - struct SText; - struct SCamera; - struct SLight; - struct SLayer; - class IBufferManager; - typedef void *SRenderInstanceId; - - using qt3ds::foundation::NVConstDataRef; - - class IQt3DSRenderNodeFilter - { - protected: - virtual ~IQt3DSRenderNodeFilter() {} - public: - virtual bool IncludeNode(const SNode &inNode) = 0; - }; - struct SLayerPickSetup - { - QT3DSMat44 m_ProjectionPreMultiply; - QT3DSMat44 m_ViewProjection; - NVRenderRect m_ScissorRect; - SLayerPickSetup(const QT3DSMat44 &inProjPreMult, const QT3DSMat44 &inVP, - const NVRenderRect &inScissor) - : m_ProjectionPreMultiply(inProjPreMult) - , m_ViewProjection(inVP) - , m_ScissorRect(inScissor) - { - } - SLayerPickSetup() {} - }; - - struct SScaleAndPosition - { - QT3DSVec3 m_Position; - QT3DSF32 m_Scale; - SScaleAndPosition(const QT3DSVec3 &inPos, QT3DSF32 inScale) - : m_Position(inPos) - , m_Scale(inScale) - { - } - SScaleAndPosition() {} - }; - - class IQt3DSRenderer : public NVRefCounted - { - protected: - virtual ~IQt3DSRenderer() {} - - public: - virtual void EnableLayerCaching(bool inEnabled) = 0; - virtual bool IsLayerCachingEnabled() const = 0; - virtual void EnableLayerGpuProfiling(bool inEnabled) = 0; - virtual bool IsLayerGpuProfilingEnabled() const = 0; - - // Get the camera that rendered this node last render - virtual SCamera *GetCameraForNode(const SNode &inNode) const = 0; - virtual Option GetCameraBounds(const SGraphObject &inObject) = 0; - // Called when you have changed the number or order of children of a given node. - virtual void ChildrenUpdated(SNode &inParent) = 0; - virtual QT3DSF32 GetTextScale(const SText &inText) = 0; - - // The IQt3DSRenderContext calls these, clients should not. - virtual void BeginFrame() = 0; - virtual void EndFrame() = 0; - - // Setup the vertex and index buffers (but not shader state) - // and render the quad. The quad is setup so that its edges - // go from -1,1 in x,y and its UV coordinates will map naturally - // to an image. - virtual void RenderQuad() = 0; - - // Render a given texture to the scene using a given transform. - virtual void RenderQuad(const QT3DSVec2 inDimensions, const QT3DSMat44 &inMVP, - NVRenderTexture2D &inQuadTexture) = 0; - - // This point rendering works uisng indirect array drawing - // This means you need to setup a GPU buffer - // which contains the drawing information - virtual void RenderPointsIndirect() = 0; - - // Returns true if this layer or a sibling was dirty. - virtual bool PrepareLayerForRender(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - bool inRenderSiblings = true, - const SRenderInstanceId id = nullptr) = 0; - virtual void RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, bool clear, - QT3DSVec3 clearColor, bool inRenderSiblings = true, - const SRenderInstanceId id = nullptr) = 0; - - // Studio option to disable picking against sub renderers. This allows better interaction - // in studio. - // In pick siblings measn pick the layer siblings; this is the normal behavior. - // InPickEverything means ignore the node's pick flags; this allows us to only pick things - // that have handlers - // in some cases and just pick everything in other things. - virtual void PickRenderPlugins(bool inPick) = 0; - virtual Qt3DSRenderPickResult Pick(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, bool inPickSiblings = true, - bool inPickEverything = false, - const SRenderInstanceId id = nullptr) = 0; - - // Return the relative hit position, in UV space, of a mouse pick against this object. - // We need the node in order to figure out which layer rendered this object. - // We need mapper objects if this is a in a subpresentation because we have to know how - // to map the mouse coordinates into the subpresentation. So for instance if inNode is in - // a subpres then we need to know which image is displaying the subpres in order to map - // the mouse coordinates into the subpres's render space. - virtual Option FacePosition(SNode &inNode, NVBounds3 inBounds, - const QT3DSMat44 &inGlobalTransform, - const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, - NVDataRef inMapperObjects, - SBasisPlanes::Enum inIsectPlane) = 0; - - virtual QT3DSVec3 UnprojectToPosition(SNode &inNode, QT3DSVec3 &inPosition, - const QT3DSVec2 &inMouseVec) const = 0; - virtual QT3DSVec3 UnprojectWithDepth(SNode &inNode, QT3DSVec3 &inPosition, - const QT3DSVec3 &inMouseVec) const = 0; - virtual QT3DSVec3 ProjectPosition(SNode &inNode, const QT3DSVec3 &inPosition) const = 0; - - // Roughly equivalent of gluPickMatrix, allows users to setup a perspective transform that - // will draw some sub component - // of the layer. Used in combination with an expected viewport of 0,0,width,height the - // viewproj matrix returned will center - // around the center of the viewport and render just the part of the layer around this area. - // The return value is optional because if the mouse point is completely outside the layer - // obviously this method is irrelevant. - virtual Option GetLayerPickSetup(SLayer &inLayer, - const QT3DSVec2 &inMouseCoords, - const QSize &inPickDims) = 0; - - // Return the layer's viewport rect after the layer's member variables have been applied. - // Uses the last rendered viewport rect. - virtual Option GetLayerRect(SLayer &inLayer) = 0; - // Testing function to allow clients to render a layer using a custom view project instead - // of the one that would be setup - // using the layer's camera in conjunction with the layer's position,scale. - virtual void RunLayerRender(SLayer &inLayer, const QT3DSMat44 &inViewProjection) = 0; - - // This allocator is cleared every frame on BeginFrame. Objects constructed using this - // allocator - // Must not need their destructors called. Objects are allocate on 4 byte boundaries using - // this allocator - // regardless - virtual NVAllocatorCallback &GetPerFrameAllocator() = 0; - - // Render the layer's rect onscreen. Will only render one frame, you need to call this - // every frame - // for this to work and be persistent. - virtual void RenderLayerRect(SLayer &inLayer, const QT3DSVec3 &inColor) = 0; - // Render widgets are things that are draw on the layer's widget texture which is then - // rendered to the - // scene's widget texture. You must add them every frame you wish them to be rendered; the - // list of - // widgets is cleared every frame. - virtual void AddRenderWidget(IRenderWidget &inWidget) = 0; - - // Get a scale factor so you can have objects precisely 50 pixels. Note that this scale - // factor - // only applies to things drawn parallel to the camera plane; If you aren't parallel then - // there isn't - // a single scale factor that will work. - // For perspective-rendered objects, we shift the object forward or backwards along the - // vector from the camera - // to the object so that we are working in a consistent mathematical space. So if the - // camera is orthographic, - // you are done. - // If the camera is perspective, then this method will tell you want you need to scale - // things by to account for - // the FOV and also where the origin of the object needs to be to ensure the scale factor is - // relevant. - virtual SScaleAndPosition GetWorldToPixelScaleFactor(SLayer &inLayer, - const QT3DSVec3 &inWorldPoint) = 0; - // Called before a layer goes completely out of scope to release any rendering resources - // related to the layer. - virtual void ReleaseLayerRenderResources(SLayer &inLayer, const SRenderInstanceId id) = 0; - - // render a screen aligned 2D text - virtual void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, - const char *text) = 0; - // render Gpu profiler values - virtual void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, - qt3ds::foundation::Option inColor) = 0; - - // Get the mouse coordinates as they relate to a given layer - virtual Option GetLayerMouseCoords(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool forceImageIntersect = false) const = 0; - - virtual IRenderWidgetContext &GetRenderWidgetContext() = 0; - - static bool IsGlEsContext(qt3ds::render::NVRenderContextType inContextType); - static bool IsGlEs3Context(qt3ds::render::NVRenderContextType inContextType); - static bool IsGl2Context(qt3ds::render::NVRenderContextType inContextType); - static const char *GetGlslVesionString(qt3ds::render::NVRenderContextType inContextType); - - static IQt3DSRenderer &CreateRenderer(IQt3DSRenderContext &inContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRendererUtil.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRendererUtil.h deleted file mode 100644 index 96f36426..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRendererUtil.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDERER_UTIL_H -#define QT3DS_RENDERER_UTIL_H -#include "Qt3DSRender.h" -#include "render/Qt3DSRenderBaseTypes.h" -namespace qt3ds { -namespace render { - class CRendererUtil - { - static const QT3DSU32 MAX_SSAA_DIM = 8192; // max render traget size for SSAA mode - - public: - static void ResolveMutisampleFBOColorOnly(IResourceManager &inManager, - CResourceTexture2D &ioResult, - NVRenderContext &inRenderContext, QT3DSU32 inWidth, - QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inColorFormat, - NVRenderFrameBuffer &inSourceFBO); - - static void ResolveSSAAFBOColorOnly(IResourceManager &inManager, - CResourceTexture2D &ioResult, QT3DSU32 outWidth, - QT3DSU32 outHeight, NVRenderContext &inRenderContext, - QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inColorFormat, - NVRenderFrameBuffer &inSourceFBO); - - static void GetSSAARenderSize(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 &outWidth, - QT3DSU32 &outHeight); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSTextRenderer.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSTextRenderer.h deleted file mode 100644 index 756c3a90..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSTextRenderer.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_TEXT_RENDERER_H -#define QT3DS_TEXT_RENDERER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderTextTypes.h" - -namespace qt3ds { -namespace render { - - struct SRendererFontEntry - { - CRegisteredString m_FontName; - CRegisteredString m_FontFile; - SRendererFontEntry() {} - SRendererFontEntry(CRegisteredString nm, CRegisteredString file) - : m_FontName(nm) - , m_FontFile(file) - { - } - }; - - class ITextRendererCore : public NVRefCounted - { - public: - // You can have several standard font directories and these will be persistent - virtual void AddSystemFontDirectory(const char8_t *inDirectory) = 0; - // Should be called to clear the current context. - virtual void AddProjectFontDirectory(const char8_t *inProjectDirectory) = 0; - virtual void ClearProjectFontDirectories() = 0; - // Force font loading *right now* - virtual void PreloadFonts() = 0; - // Do not access object in between begin/end preload pairs. - virtual void BeginPreloadFonts(IThreadPool &inThreadPool, IPerfTimer &inTimer) = 0; - virtual void EndPreloadFonts() = 0; - // Force a clear and reload of all of the fonts. - virtual void ReloadFonts() = 0; - // Get the list of project fonts. These are the only fonts that can be displayed. - virtual NVConstDataRef GetProjectFontList() = 0; - // The name stored in the ttf file isn't the actual name we use; we use the file stems. - // But we used to use the name. So this provides a sort of first-come-first-serve remapping - // from ttf-name to file-stem. - virtual Option GetFontNameForFont(CRegisteredString inFontname) = 0; - virtual Option GetFontNameForFont(const char8_t *inFontname) = 0; - - virtual ITextRenderer &GetTextRenderer(NVRenderContext &inContext) = 0; - - static ITextRendererCore &CreateQtTextRenderer(NVFoundationBase &inFoundation, - IStringTable &inStrTable); - - // call this to create onscreen text renderer - // it needs true type fonts - static ITextRendererCore &CreateOnscreenTextRenderer(NVFoundationBase &inFoundation); - }; - /** - * Opaque text rendering system. Must be able to render text to an opengl texture object. - */ - class ITextRenderer : public ITextRendererCore - { - protected: - virtual ~ITextRenderer() {} - - public: - // Measure text will inText if it isn't null or the text on the info if inText is null - virtual STextDimensions MeasureText(const STextRenderInfo &inText, QT3DSF32 inTextScaleFactor, - const char8_t *inTextOverride = NULL) = 0; - // The system will use the 'r' channel as an alpha mask in order to render the - // text. You can assume GetTextDimensions was called *just* prior to this. - // It is a good idea to ensure the texture is a power of two as not all rendering systems - // support nonpot textures. Our text rendering algorithms will render a sub-rect of the - // image - // assuming it is located toward the upper-left of the image and we are also capable of - // flipping - // the image. - virtual STextTextureDetails RenderText(const STextRenderInfo &inText, - NVRenderTexture2D &inTexture) = 0; - // this is for rendering text with NV path rendering - virtual STextTextureDetails - RenderText(const STextRenderInfo &inText, NVRenderPathFontItem &inPathFontItem, - NVRenderPathFontSpecification &inPathFontSpecicification) = 0; - // this is for rednering text using a texture atlas - virtual SRenderTextureAtlasDetails RenderText(const STextRenderInfo &inText) = 0; - - virtual void BeginFrame() = 0; - virtual void EndFrame() = 0; - - // these two function are for texture atlas usage only - // returns the atlas entries count - virtual QT3DSI32 CreateTextureAtlas() = 0; - virtual STextTextureAtlasEntryDetails RenderAtlasEntry(QT3DSU32 index, - NVRenderTexture2D &inTexture) = 0; - - // Helper function to upload the texture data to the texture - // Will resize texture as necessary and upload using texSubImage for - // quickest upload times - // This function expects that the dataWidth to be divisible by four and - // that the total data height is larger then inTextHeight *and* divisible by four. - // and that textWidth and textHeight are less than or equal to dataWidth,dataHeight - //,can be zero, and don't need to be divisible by four (or 2). - static STextTextureDetails - UploadData(NVDataRef inTextureData, NVRenderTexture2D &inTexture, QT3DSU32 inDataWidth, - QT3DSU32 inDataHeight, QT3DSU32 inTextWidth, QT3DSU32 inTextHeight, - NVRenderTextureFormats::Enum inFormat, bool inFlipYAxis); - - // Helper function to return the next power of two. - // Fails for values of 0 or QT3DS_MAX_U32 - static QT3DSU32 NextPowerOf2(QT3DSU32 inValue); - // If inValue is divisible by four, then return inValue - // else next largest number that is divisible by four. - static QT3DSU32 NextMultipleOf4(QT3DSU32 inValue); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/WINDOWS/DynamicLibLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/WINDOWS/DynamicLibLoader.h deleted file mode 100644 index 09b028bc..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/WINDOWS/DynamicLibLoader.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_WINDOWS_DYNAMIC_LIB_LOADER_H -#define QT3DS_WINDOWS_DYNAMIC_LIB_LOADER_H - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" - -#include - -namespace qt3ds { -namespace render { - using namespace qt3ds; - // using namespace qt3ds::render; - - class CLoadedDynamicLibrary - { - QLibrary* m_DLLHandle; - CLoadedDynamicLibrary(QLibrary* hdl) - : m_DLLHandle(hdl) - { - } - CLoadedDynamicLibrary(const CLoadedDynamicLibrary &); - CLoadedDynamicLibrary &operator=(const CLoadedDynamicLibrary &); - - public: - ~CLoadedDynamicLibrary() - { - if (m_DLLHandle) { - m_DLLHandle->unload(); - delete m_DLLHandle; - } - m_DLLHandle = 0; - } - void *FindFunction(const char *name) { return (void*)m_DLLHandle->resolve(name); } - static CLoadedDynamicLibrary *Create(const char *inFullDllPath, NVFoundationBase &fnd) - { - QLibrary* hdl = new QLibrary(inFullDllPath); - if (!hdl->load()) { - qCCritical(INVALID_OPERATION, "Failed to load dynamic library %s: %s", - inFullDllPath, qPrintable(hdl->errorString())); - - delete hdl; - return nullptr; - } - return QT3DS_NEW(fnd.getAllocator(), CLoadedDynamicLibrary)(hdl); - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h deleted file mode 100644 index 12d459cf..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_QML_RENDER_H -#define QT3DS_QML_RENDER_H - -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSRenderContextCore.h" - -class IQt3DS; - -using namespace qt3ds::render; - -class IQ3DSQmlStreamService; -class IQ3DSQmlStreamRenderer; - -class Q3DSQmlRender : public IOffscreenRenderer -{ -public: - Q3DSQmlRender(IQt3DSRenderContext &inRenderContext, const char *asset); - ~Q3DSQmlRender(); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) - - CRegisteredString GetOffscreenRendererType() override; - - SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresentationScaleFactor) override; - - // Returns true of this object needs to be rendered, false if this object is not dirty - SOffscreenRenderFlags NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, - QT3DSVec2 inPresentationScaleFactor, - const SRenderInstanceId instanceId) override; - - void Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, - SScene::RenderClearCommand inColorBufferNeedsClear, - const SRenderInstanceId instanceId) override; - void RenderWithClear(const SOffscreenRendererEnvironment &/*inEnvironment*/, - NVRenderContext &/*inRenderContext*/, - QT3DSVec2 /*inPresentationScaleFactor*/, - SScene::RenderClearCommand /*inColorBufferNeedsClear*/, - QT3DSVec3 /*inclearColor*/, - const SRenderInstanceId /*instanceId*/) override {} - - IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId instanceId) override - { - Q_UNUSED(instanceId) - return nullptr; - } - bool Pick(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, - const SRenderInstanceId instanceId) override - { - Q_UNUSED(inMouseCoords) - Q_UNUSED(inViewportDimensions) - Q_UNUSED(instanceId) - return false; - } - void addCallback(IOffscreenRendererCallback *cb) override - { - m_callback = cb; - } - static const char *GetRendererName() { return "qml-render"; } -private: - - void initializeRenderer(); - - IQt3DSRenderContext &m_RenderContext; - IQ3DSQmlStreamRenderer *m_qmlStreamRenderer; - CRegisteredString m_offscreenRenderType; - CRegisteredString m_assetString; - IOffscreenRendererCallback *m_callback; - volatile QT3DSI32 mRefCount; -}; - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.cpp deleted file mode 100644 index 7d8054f7..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderableObjects.h" -#include "Qt3DSRendererImpl.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderCustomMaterialRenderContext.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderPathManager.h" -#include "Qt3DSRenderPathRenderContext.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" - -using qt3ds::foundation::CRegisteredString; - -namespace qt3ds { -namespace render { - struct SRenderableImage; - struct SShaderGeneratorGeneratedShader; - struct SSubsetRenderable; - using eastl::make_pair; - using eastl::reverse; - - STextScaleAndOffset::STextScaleAndOffset(NVRenderTexture2D &inTexture, - const STextTextureDetails &inTextDetails, - const STextRenderInfo &inInfo) - : m_TextOffset(0, 0) - , m_TextScale(1, 1) - - { - NVRenderTexture2D &theTexture = inTexture; - STextureDetails theDetails(theTexture.GetTextureDetails()); - QT3DSVec2 textDimensions(inTextDetails.m_TextWidth / 2.0f, inTextDetails.m_TextHeight / 2.0f); - textDimensions.x /= inTextDetails.m_ScaleFactor.x; - textDimensions.y /= inTextDetails.m_ScaleFactor.y; - QT3DSVec2 theTextScale(textDimensions.x, textDimensions.y); - QT3DSVec2 theTextOffset(0, 0); - - // Set the offsets to use after scaling the rect coordinates. - switch (inInfo.m_HorizontalAlignment) { - case TextHorizontalAlignment::Left: - theTextOffset[0] = theTextScale[0]; - break; - case TextHorizontalAlignment::Center: - break; - case TextHorizontalAlignment::Right: - theTextOffset[0] = -theTextScale[0]; - break; - default: - break; - } - - switch (inInfo.m_VerticalAlignment) { - case TextVerticalAlignment::Top: - theTextOffset[1] = -theTextScale[1]; - break; - case TextVerticalAlignment::Middle: - break; - case TextVerticalAlignment::Bottom: - theTextOffset[1] = theTextScale[1]; - break; - default: - break; - } - m_TextScale = theTextScale; - m_TextOffset = theTextOffset; - } - - void SSubsetRenderableBase::RenderShadowMapPass(const QT3DSVec2 &inCameraVec, - const SLight *inLight, const SCamera &inCamera, - SShadowMapEntry *inShadowMapEntry) - { - NVRenderContext &context(m_Generator.GetContext()); - SRenderableDepthPrepassShader *shader = NULL; - NVRenderInputAssembler *pIA = NULL; - - /* - if ( inLight->m_LightType == RenderLightTypes::Area ) - shader = m_Generator.GetParaboloidDepthShader( m_TessellationMode ); - else if ( inLight->m_LightType == RenderLightTypes::Directional ) - shader = m_Generator.GetOrthographicDepthShader( m_TessellationMode ); - else if ( inLight->m_LightType == RenderLightTypes::Point ) - shader = m_Generator.GetCubeShadowDepthShader( m_TessellationMode ); // This - will change to include a geometry shader pass. - */ - - if (inLight->m_LightType == RenderLightTypes::Directional) - shader = m_Generator.GetOrthographicDepthShader(m_TessellationMode); - else - shader = m_Generator.GetCubeShadowDepthShader(m_TessellationMode); - - if (shader == NULL || inShadowMapEntry == NULL) - return; - - // for phong and npatch tesselleation we need the normals too - if (m_TessellationMode == TessModeValues::NoTess - || m_TessellationMode == TessModeValues::TessLinear) - pIA = m_Subset.m_InputAssemblerDepth; - else - pIA = m_Subset.m_InputAssembler; - - QT3DSMat44 theModelViewProjection = inShadowMapEntry->m_LightVP * m_GlobalTransform; - // QT3DSMat44 theModelView = inLight->m_GlobalTransform.getInverse() * m_GlobalTransform; - - context.SetActiveShader(&shader->m_Shader); - shader->m_MVP.Set(theModelViewProjection); - shader->m_CameraPosition.Set(inCamera.m_Position); - shader->m_GlobalTransform.Set(m_GlobalTransform); - shader->m_CameraProperties.Set(inCameraVec); - /* - shader->m_CameraDirection.Set( inCamera.GetDirection() ); - - shader->m_ShadowMV[0].Set( inShadowMapEntry->m_LightCubeView[0] * m_GlobalTransform ); - shader->m_ShadowMV[1].Set( inShadowMapEntry->m_LightCubeView[1] * m_GlobalTransform ); - shader->m_ShadowMV[2].Set( inShadowMapEntry->m_LightCubeView[2] * m_GlobalTransform ); - shader->m_ShadowMV[3].Set( inShadowMapEntry->m_LightCubeView[3] * m_GlobalTransform ); - shader->m_ShadowMV[4].Set( inShadowMapEntry->m_LightCubeView[4] * m_GlobalTransform ); - shader->m_ShadowMV[5].Set( inShadowMapEntry->m_LightCubeView[5] * m_GlobalTransform ); - shader->m_Projection.Set( inCamera.m_Projection ); - */ - - // tesselation - if (m_TessellationMode != TessModeValues::NoTess) { - // set uniforms we need - shader->m_Tessellation.m_EdgeTessLevel.Set(m_Subset.m_EdgeTessFactor); - shader->m_Tessellation.m_InsideTessLevel.Set(m_Subset.m_InnerTessFactor); - // the blend value is hardcoded - shader->m_Tessellation.m_PhongBlend.Set(0.75); - // set distance range value - shader->m_Tessellation.m_DistanceRange.Set(inCameraVec); - // disable culling - shader->m_Tessellation.m_DisableCulling.Set(1.0); - } - - context.SetInputAssembler(pIA); - context.Draw(m_Subset.m_PrimitiveType, m_Subset.m_Count, m_Subset.m_Offset); - } - - void SSubsetRenderableBase::RenderDepthPass(const QT3DSVec2 &inCameraVec, - SRenderableImage *inDisplacementImage, - float inDisplacementAmount) - { - NVRenderContext &context(m_Generator.GetContext()); - SRenderableDepthPrepassShader *shader = NULL; - NVRenderInputAssembler *pIA = NULL; - SRenderableImage *displacementImage = inDisplacementImage; - - if (m_Subset.m_PrimitiveType != NVRenderDrawMode::Patches) - shader = m_Generator.GetDepthPrepassShader(displacementImage != NULL); - else - shader = m_Generator.GetDepthTessPrepassShader(m_TessellationMode, - displacementImage != NULL); - - if (shader == NULL) - return; - - // for phong and npatch tesselleation or displacement mapping we need the normals (and uv's) - // too - if ((m_TessellationMode == TessModeValues::NoTess - || m_TessellationMode == TessModeValues::TessLinear) - && !displacementImage) - pIA = m_Subset.m_InputAssemblerDepth; - else - pIA = m_Subset.m_InputAssembler; - - context.SetActiveShader(&shader->m_Shader); - context.SetCullingEnabled(true); - - shader->m_MVP.Set(m_ModelContext.m_ModelViewProjection); - - if (displacementImage) { - // setup image transform - const QT3DSMat44 &textureTransform = displacementImage->m_Image.m_TextureTransform; - const QT3DSF32 *dataPtr(textureTransform.front()); - QT3DSVec3 offsets(dataPtr[12], dataPtr[13], - displacementImage->m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() - ? 1.0f - : 0.0f); - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - displacementImage->m_Image.m_TextureData.m_Texture->SetTextureWrapS( - displacementImage->m_Image.m_HorizontalTilingMode); - displacementImage->m_Image.m_TextureData.m_Texture->SetTextureWrapT( - displacementImage->m_Image.m_VerticalTilingMode); - - shader->m_DisplaceAmount.Set(inDisplacementAmount); - shader->m_DisplacementProps.m_Offsets.Set(offsets); - shader->m_DisplacementProps.m_Rotations.Set(rotations); - shader->m_DisplacementProps.m_Sampler.Set( - displacementImage->m_Image.m_TextureData.m_Texture); - } - - // tesselation - if (m_TessellationMode != TessModeValues::NoTess) { - // set uniforms we need - shader->m_GlobalTransform.Set(m_GlobalTransform); - - if (m_Generator.GetLayerRenderData() && m_Generator.GetLayerRenderData()->m_Camera) - shader->m_CameraPosition.Set( - m_Generator.GetLayerRenderData()->m_Camera->GetGlobalPos()); - else if (m_Generator.GetLayerRenderData()->m_Camera) - shader->m_CameraPosition.Set(QT3DSVec3(0.0, 0.0, 1.0)); - - shader->m_Tessellation.m_EdgeTessLevel.Set(m_Subset.m_EdgeTessFactor); - shader->m_Tessellation.m_InsideTessLevel.Set(m_Subset.m_InnerTessFactor); - // the blend value is hardcoded - shader->m_Tessellation.m_PhongBlend.Set(0.75); - // set distance range value - shader->m_Tessellation.m_DistanceRange.Set(inCameraVec); - // enable culling - shader->m_Tessellation.m_DisableCulling.Set(0.0); - } - - context.SetInputAssembler(pIA); - context.Draw(m_Subset.m_PrimitiveType, m_Subset.m_Count, m_Subset.m_Offset); - } - - // An interface to the shader generator that is available to the renderables - - void SSubsetRenderable::Render(const QT3DSVec2 &inCameraVec, TShaderFeatureSet inFeatureSet) - { - NVRenderContext &context(m_Generator.GetContext()); - - SShaderGeneratorGeneratedShader *shader = m_Generator.GetShader(*this, inFeatureSet); - if (shader == NULL) - return; - - context.SetActiveShader(&shader->m_Shader); - - m_Generator.GetQt3DSContext().GetDefaultMaterialShaderGenerator().SetMaterialProperties( - shader->m_Shader, m_Material, inCameraVec, m_ModelContext.m_ModelViewProjection, - m_ModelContext.m_NormalMatrix, m_ModelContext.m_Model.m_GlobalTransform, m_FirstImage, - m_Opacity, m_Generator.GetLayerGlobalRenderProperties()); - - // tesselation - if (m_Subset.m_PrimitiveType == NVRenderDrawMode::Patches) { - shader->m_Tessellation.m_EdgeTessLevel.Set(m_Subset.m_EdgeTessFactor); - shader->m_Tessellation.m_InsideTessLevel.Set(m_Subset.m_InnerTessFactor); - // the blend value is hardcoded - shader->m_Tessellation.m_PhongBlend.Set(0.75); - // this should finally be based on some user input - shader->m_Tessellation.m_DistanceRange.Set(inCameraVec); - // enable culling - shader->m_Tessellation.m_DisableCulling.Set(0.0); - - if (m_Subset.m_WireframeMode) { - // we need the viewport matrix - NVRenderRect theViewport(context.GetViewport()); - QT3DSMat44 vpMatrix; - vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0); - vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0); - vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0); - vpMatrix.column3 = - QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X, - (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0); - - shader->m_ViewportMatrix.Set(vpMatrix); - } - } - - context.SetCullingEnabled(true); - context.SetInputAssembler(m_Subset.m_InputAssembler); - context.Draw(m_Subset.m_PrimitiveType, m_Subset.m_Count, m_Subset.m_Offset); - } - - void SSubsetRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec) - { - SRenderableImage *displacementImage = NULL; - for (SRenderableImage *theImage = m_FirstImage; - theImage != NULL && displacementImage == NULL; theImage = theImage->m_NextImage) { - if (theImage->m_MapType == ImageMapTypes::Displacement) - displacementImage = theImage; - } - SSubsetRenderableBase::RenderDepthPass(inCameraVec, displacementImage, - m_Material.m_DisplaceAmount); - } - - void STextRenderable::Render(const QT3DSVec2 &inCameraVec) - { - NVRenderContext &context(m_Generator.GetContext()); - - if (!m_Text.m_PathFontDetails) { - - STextRenderHelper theInfo = m_Generator.GetShader(*this, false); - if (theInfo.m_Shader == NULL) - return; - // All of our shaders produce premultiplied values. - qt3ds::render::NVRenderBlendFunctionArgument blendFunc( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); - - qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - - context.SetBlendFunction(blendFunc); - context.SetBlendEquation(blendEqu); - QT3DSVec4 theColor(m_Text.m_TextColor, m_Text.m_GlobalOpacity); - - STextShader &shader(*theInfo.m_Shader); - shader.Render(*m_Text.m_TextTexture, *this, theColor, m_ModelViewProjection, - inCameraVec, context, theInfo.m_QuadInputAssembler, - theInfo.m_QuadInputAssembler.GetIndexCount(), m_Text.m_TextTextureDetails, - QT3DSVec3(0, 0, 0)); - } else { - QT3DS_ASSERT(context.IsPathRenderingSupported() && context.IsProgramPipelineSupported()); - - STextRenderHelper theInfo = m_Generator.GetShader(*this, true); - if (theInfo.m_Shader == NULL) - return; - - // All of our shaders produce premultiplied values. - qt3ds::render::NVRenderBlendFunctionArgument blendFunc( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); - - qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - - context.SetBlendFunction(blendFunc); - context.SetBlendEquation(blendEqu); - QT3DSVec4 theColor(m_Text.m_TextColor, m_Text.m_GlobalOpacity); - - STextShader &shader(*theInfo.m_Shader); - - shader.RenderPath(*m_Text.m_PathFontItem, *m_Text.m_PathFontDetails, *this, theColor, - m_ViewProjection, m_GlobalTransform, inCameraVec, context, - m_Text.m_TextTextureDetails, QT3DSVec3(0, 0, 0)); - } - } - - void STextRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec) - { - NVRenderContext &context(m_Generator.GetContext()); - STextDepthShader *theDepthShader = m_Generator.GetTextDepthShader(); - if (theDepthShader == NULL) - return; - - if (!m_Text.m_PathFontDetails) { - // we may change stencil test state - qt3ds::render::NVRenderContextScopedProperty __stencilTest( - context, &NVRenderContext::IsStencilTestEnabled, - &NVRenderContext::SetStencilTestEnabled, true); - - NVRenderShaderProgram &theShader(theDepthShader->m_Shader); - context.SetCullingEnabled(false); - context.SetActiveShader(&theShader); - theDepthShader->m_MVP.Set(m_ModelViewProjection); - theDepthShader->m_Sampler.Set(m_Text.m_TextTexture); - const STextScaleAndOffset &theScaleAndOffset(*this); - theDepthShader->m_Dimensions.Set( - QT3DSVec4(theScaleAndOffset.m_TextScale.x, theScaleAndOffset.m_TextScale.y, - theScaleAndOffset.m_TextOffset.x, theScaleAndOffset.m_TextOffset.y)); - theDepthShader->m_CameraProperties.Set(inCameraVec); - - STextureDetails theTextureDetails = m_Text.m_TextTexture->GetTextureDetails(); - const STextTextureDetails &theTextTextureDetails(m_Text.m_TextTextureDetails); - QT3DSF32 theWidthScale = - (QT3DSF32)theTextTextureDetails.m_TextWidth / (QT3DSF32)theTextureDetails.m_Width; - QT3DSF32 theHeightScale = - (QT3DSF32)theTextTextureDetails.m_TextHeight / (QT3DSF32)theTextureDetails.m_Height; - theDepthShader->m_TextDimensions.Set( - QT3DSVec3(theWidthScale, theHeightScale, theTextTextureDetails.m_FlipY ? 1.0f : 0.0f)); - context.SetInputAssembler(&theDepthShader->m_QuadInputAssembler); - context.Draw(NVRenderDrawMode::Triangles, - theDepthShader->m_QuadInputAssembler.GetIndexCount(), 0); - } else { - qt3ds::render::NVRenderBoolOp::Enum theDepthFunction = context.GetDepthFunction(); - bool isDepthEnabled = context.IsDepthTestEnabled(); - bool isStencilEnabled = context.IsStencilTestEnabled(); - bool isDepthWriteEnabled = context.IsDepthWriteEnabled(); - qt3ds::render::NVRenderStencilFunctionArgument theArg(qt3ds::render::NVRenderBoolOp::NotEqual, - 0, 0xFF); - qt3ds::render::NVRenderStencilOperationArgument theOpArg( - qt3ds::render::NVRenderStencilOp::Keep, qt3ds::render::NVRenderStencilOp::Keep, - qt3ds::render::NVRenderStencilOp::Zero); - NVScopedRefCounted depthStencilState = - context.CreateDepthStencilState(isDepthEnabled, isDepthWriteEnabled, - theDepthFunction, false, theArg, theArg, theOpArg, - theOpArg); - - context.SetActiveShader(NULL); - context.SetCullingEnabled(false); - - context.SetDepthStencilState(depthStencilState); - - // setup transform - QT3DSMat44 offsetMatrix = QT3DSMat44::createIdentity(); - offsetMatrix.setPosition(QT3DSVec3( - m_TextOffset.x - (QT3DSF32)m_Text.m_TextTextureDetails.m_TextWidth / 2.0f, - m_TextOffset.y - (QT3DSF32)m_Text.m_TextTextureDetails.m_TextHeight / 2.0f, 0.0)); - - QT3DSMat44 pathMatrix = m_Text.m_PathFontItem->GetTransform(); - - context.SetPathProjectionMatrix(m_ViewProjection); - context.SetPathModelViewMatrix(m_GlobalTransform * offsetMatrix * pathMatrix); - - // first pass - m_Text.m_PathFontDetails->StencilFillPathInstanced(*m_Text.m_PathFontItem); - - // second pass - context.SetStencilTestEnabled(true); - m_Text.m_PathFontDetails->CoverFillPathInstanced(*m_Text.m_PathFontItem); - - context.SetStencilTestEnabled(isStencilEnabled); - context.SetDepthFunction(theDepthFunction); - } - } - - void SCustomMaterialRenderable::Render(const QT3DSVec2 & /*inCameraVec*/, - const SLayerRenderData &inLayerData, - const SLayer &inLayer, NVDataRef inLights, - const SCamera &inCamera, - const NVRenderTexture2D *inDepthTexture, - const NVRenderTexture2D *inSsaoTexture, - TShaderFeatureSet inFeatureSet) - { - IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); - SCustomMaterialRenderContext theRenderContext( - inLayer, inLayerData, inLights, inCamera, m_ModelContext.m_Model, m_Subset, - m_ModelContext.m_ModelViewProjection, m_GlobalTransform, m_ModelContext.m_NormalMatrix, - m_Material, inDepthTexture, inSsaoTexture, m_ShaderDescription, m_FirstImage, - m_Opacity); - - qt3dsContext.GetCustomMaterialSystem().RenderSubset(theRenderContext, inFeatureSet); - } - - void SCustomMaterialRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec, - const SLayer & /*inLayer*/, - NVConstDataRef /*inLights*/ - , - const SCamera & /*inCamera*/, - const NVRenderTexture2D * /*inDepthTexture*/) - { - - IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); - if (!qt3dsContext.GetCustomMaterialSystem().RenderDepthPrepass( - m_ModelContext.m_ModelViewProjection, m_Material, m_Subset)) { - SRenderableImage *displacementImage = NULL; - for (SRenderableImage *theImage = m_FirstImage; - theImage != NULL && displacementImage == NULL; theImage = theImage->m_NextImage) { - if (theImage->m_MapType == ImageMapTypes::Displacement) - displacementImage = theImage; - } - - SSubsetRenderableBase::RenderDepthPass(inCameraVec, displacementImage, - m_Material.m_DisplaceAmount); - } - } - - void SPathRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer & /*inLayer*/, - NVConstDataRef inLights, - const SCamera &inCamera, - const NVRenderTexture2D * /*inDepthTexture*/) - { - IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); - SPathRenderContext theRenderContext( - inLights, inCamera, m_Path, m_ModelViewProjection, m_GlobalTransform, m_NormalMatrix, - m_Opacity, m_Material, m_ShaderDescription, m_FirstImage, qt3dsContext.GetWireframeMode(), - inCameraVec, false, m_IsStroke); - - qt3dsContext.GetPathManager().RenderDepthPrepass( - theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), TShaderFeatureSet()); - } - - void SPathRenderable::Render(const QT3DSVec2 &inCameraVec, const SLayer & /*inLayer*/, - NVConstDataRef inLights, const SCamera &inCamera, - const NVRenderTexture2D * /*inDepthTexture*/ - , - const NVRenderTexture2D * /*inSsaoTexture*/ - , - TShaderFeatureSet inFeatureSet) - { - IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); - SPathRenderContext theRenderContext( - inLights, inCamera, m_Path, m_ModelViewProjection, m_GlobalTransform, m_NormalMatrix, - m_Opacity, m_Material, m_ShaderDescription, m_FirstImage, qt3dsContext.GetWireframeMode(), - inCameraVec, m_RenderableFlags.HasTransparency(), m_IsStroke); - - qt3dsContext.GetPathManager().RenderPath( - theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), inFeatureSet); - } - - void SPathRenderable::RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, - const SCamera &inCamera, - SShadowMapEntry *inShadowMapEntry) - { - NVConstDataRef theLights; - IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); - - QT3DSMat44 theModelViewProjection = inShadowMapEntry->m_LightVP * m_GlobalTransform; - SPathRenderContext theRenderContext( - theLights, inCamera, m_Path, theModelViewProjection, m_GlobalTransform, m_NormalMatrix, - m_Opacity, m_Material, m_ShaderDescription, m_FirstImage, qt3dsContext.GetWireframeMode(), - inCameraVec, false, m_IsStroke); - - if (inLight->m_LightType != RenderLightTypes::Directional) { - qt3dsContext.GetPathManager().RenderCubeFaceShadowPass( - theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), - TShaderFeatureSet()); - } else - qt3dsContext.GetPathManager().RenderShadowMapPass( - theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), - TShaderFeatureSet()); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.h deleted file mode 100644 index d380b850..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRenderableObjects.h +++ /dev/null @@ -1,431 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_IMPL_RENDERABLE_OBJECTS_H -#define QT3DS_RENDER_IMPL_RENDERABLE_OBJECTS_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSFlags.h" -#include "Qt3DSRenderModel.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderText.h" -#include "Qt3DSRenderMesh.h" -#include "Qt3DSRenderShaderKeys.h" -#include "Qt3DSRenderShaderCache.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "Qt3DSRenderableImage.h" - -namespace qt3ds { -namespace render { - - struct RenderPreparationResultFlagValues - { - enum Enum { - HasTransparency = 1 << 0, - CompletelyTransparent = 1 << 1, - Dirty = 1 << 2, - Pickable = 1 << 3, - DefaultMaterialMeshSubset = 1 << 4, - Text = 1 << 5, - Custom = 1 << 6, - CustomMaterialMeshSubset = 1 << 7, - HasRefraction = 1 << 8, - Path = 1 << 9, - ShadowCaster = 1 << 10 - }; - }; - - struct SRenderableObjectFlags : public NVFlags - { - void ClearOrSet(bool value, RenderPreparationResultFlagValues::Enum enumVal) - { - if (value) - this->operator|=(enumVal); - else - clear(enumVal); - } - - void SetHasTransparency(bool inHasTransparency) - { - ClearOrSet(inHasTransparency, RenderPreparationResultFlagValues::HasTransparency); - } - bool HasTransparency() const - { - return this->operator&(RenderPreparationResultFlagValues::HasTransparency); - } - bool HasRefraction() const - { - return this->operator&(RenderPreparationResultFlagValues::HasRefraction); - } - void SetCompletelyTransparent(bool inTransparent) - { - ClearOrSet(inTransparent, RenderPreparationResultFlagValues::CompletelyTransparent); - } - bool IsCompletelyTransparent() const - { - return this->operator&(RenderPreparationResultFlagValues::CompletelyTransparent); - } - void SetDirty(bool inDirty) - { - ClearOrSet(inDirty, RenderPreparationResultFlagValues::Dirty); - } - bool IsDirty() const { return this->operator&(RenderPreparationResultFlagValues::Dirty); } - void SetPickable(bool inPickable) - { - ClearOrSet(inPickable, RenderPreparationResultFlagValues::Pickable); - } - bool GetPickable() const - { - return this->operator&(RenderPreparationResultFlagValues::Pickable); - } - - // Mutually exclusive values - void SetDefaultMaterialMeshSubset(bool inMeshSubset) - { - ClearOrSet(inMeshSubset, RenderPreparationResultFlagValues::DefaultMaterialMeshSubset); - } - bool IsDefaultMaterialMeshSubset() const - { - return this->operator&(RenderPreparationResultFlagValues::DefaultMaterialMeshSubset); - } - - void SetCustomMaterialMeshSubset(bool inMeshSubset) - { - ClearOrSet(inMeshSubset, RenderPreparationResultFlagValues::CustomMaterialMeshSubset); - } - bool IsCustomMaterialMeshSubset() const - { - return this->operator&(RenderPreparationResultFlagValues::CustomMaterialMeshSubset); - } - - void SetText(bool inText) { ClearOrSet(inText, RenderPreparationResultFlagValues::Text); } - bool IsText() const { return this->operator&(RenderPreparationResultFlagValues::Text); } - - void SetCustom(bool inCustom) - { - ClearOrSet(inCustom, RenderPreparationResultFlagValues::Custom); - } - bool IsCustom() const { return this->operator&(RenderPreparationResultFlagValues::Custom); } - - void SetPath(bool inPath) { ClearOrSet(inPath, RenderPreparationResultFlagValues::Path); } - bool IsPath() const { return this->operator&(RenderPreparationResultFlagValues::Path); } - - void SetShadowCaster(bool inCaster) - { - ClearOrSet(inCaster, RenderPreparationResultFlagValues::ShadowCaster); - } - bool IsShadowCaster() const - { - return this->operator&(RenderPreparationResultFlagValues::ShadowCaster); - } - }; - - struct SNodeLightEntry - { - SLight *m_Light; - QT3DSU32 m_LightIndex; - SNodeLightEntry *m_NextNode; - SNodeLightEntry() - : m_Light(NULL) - , m_NextNode(NULL) - { - } - SNodeLightEntry(SLight *inLight, QT3DSU32 inLightIndex) - : m_Light(inLight) - , m_LightIndex(inLightIndex) - , m_NextNode(NULL) - { - } - }; - - DEFINE_INVASIVE_SINGLE_LIST(NodeLightEntry); - - IMPLEMENT_INVASIVE_SINGLE_LIST(NodeLightEntry, m_NextNode); - - struct SRenderableObject; - - typedef void (*TRenderFunction)(SRenderableObject &inObject, const QT3DSVec2 &inCameraProperties); - - struct SRenderableObject - { - // Variables used for picking - const QT3DSMat44 &m_GlobalTransform; - const NVBounds3 &m_Bounds; - SRenderableObjectFlags m_RenderableFlags; - // For rough sorting for transparency and for depth - QT3DSVec3 m_WorldCenterPoint; - QT3DSF32 m_CameraDistanceSq; - TessModeValues::Enum m_TessellationMode; - bool m_ShadowCaster; - // For custom renderable objects the render function must be defined - TRenderFunction m_RenderFunction; - TNodeLightEntryList m_ScopedLights; - SRenderableObject(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, - const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, - TessModeValues::Enum inTessMode = TessModeValues::NoTess, - bool inShadowCaster = true, TRenderFunction inFunction = nullptr) - - : m_GlobalTransform(inGlobalTransform) - , m_Bounds(inBounds) - , m_RenderableFlags(inFlags) - , m_WorldCenterPoint(inWorldCenterPt) - , m_CameraDistanceSq(0) - , m_TessellationMode(inTessMode) - , m_ShadowCaster(inShadowCaster) - , m_RenderFunction(inFunction) - { - } - bool operator<(SRenderableObject *inOther) const - { - return m_CameraDistanceSq < inOther->m_CameraDistanceSq; - } - }; - - typedef nvvector TRenderableObjectList; - - // Different subsets from the same model will get the same - // model context so we can generate the MVP and normal matrix once - // and only once per subset. - struct SModelContext - { - const SModel &m_Model; - QT3DSMat44 m_ModelViewProjection; - QT3DSMat33 m_NormalMatrix; - - SModelContext(const SModel &inModel, const QT3DSMat44 &inViewProjection) - : m_Model(inModel) - { - m_Model.CalculateMVPAndNormalMatrix(inViewProjection, m_ModelViewProjection, - m_NormalMatrix); - } - SModelContext(const SModelContext &inOther) - : m_Model(inOther.m_Model) - { - // The default copy constructor for these objects is pretty darn slow. - memCopy(&m_ModelViewProjection, &inOther.m_ModelViewProjection, - sizeof(m_ModelViewProjection)); - memCopy(&m_NormalMatrix, &inOther.m_NormalMatrix, sizeof(m_NormalMatrix)); - } - }; - - typedef nvvector TModelContextPtrList; - - class Qt3DSRendererImpl; - struct SLayerRenderData; - struct SShadowMapEntry; - - struct SSubsetRenderableBase : public SRenderableObject - { - Qt3DSRendererImpl &m_Generator; - const SModelContext &m_ModelContext; - SRenderSubset m_Subset; - QT3DSF32 m_Opacity; - - SSubsetRenderableBase(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, - Qt3DSRendererImpl &gen, const SRenderSubset &subset, - const SModelContext &modelContext, QT3DSF32 inOpacity) - - : SRenderableObject(inFlags, inWorldCenterPt, modelContext.m_Model.m_GlobalTransform, - m_Subset.m_Bounds) - , m_Generator(gen) - , m_ModelContext(modelContext) - , m_Subset(subset) - , m_Opacity(inOpacity) - { - } - void RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, - const SCamera &inCamera, SShadowMapEntry *inShadowMapEntry); - - void RenderDepthPass(const QT3DSVec2 &inCameraVec, SRenderableImage *inDisplacementImage, - float inDisplacementAmount); - }; - - /** - * A renderable that corresponds to a subset (a part of a model). - * These are created per subset per layer and are responsible for actually - * rendering this type of object. - */ - struct SSubsetRenderable : public SSubsetRenderableBase - { - const SDefaultMaterial &m_Material; - SRenderableImage *m_FirstImage; - SShaderDefaultMaterialKey m_ShaderDescription; - NVConstDataRef m_Bones; - - SSubsetRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, - Qt3DSRendererImpl &gen, const SRenderSubset &subset, - const SDefaultMaterial &mat, const SModelContext &modelContext, - QT3DSF32 inOpacity, SRenderableImage *inFirstImage, - SShaderDefaultMaterialKey inShaderKey, - NVConstDataRef inBoneGlobals) - - : SSubsetRenderableBase(inFlags, inWorldCenterPt, gen, subset, modelContext, inOpacity) - , m_Material(mat) - , m_FirstImage(inFirstImage) - , m_ShaderDescription(inShaderKey) - , m_Bones(inBoneGlobals) - { - m_RenderableFlags.SetDefaultMaterialMeshSubset(true); - m_RenderableFlags.SetCustom(false); - m_RenderableFlags.SetText(false); - } - - void Render(const QT3DSVec2 &inCameraVec, TShaderFeatureSet inFeatureSet); - - void RenderDepthPass(const QT3DSVec2 &inCameraVec); - - DefaultMaterialBlendMode::Enum getBlendingMode() - { - return m_Material.m_BlendMode; - } - }; - - struct SCustomMaterialRenderable : public SSubsetRenderableBase - { - const SCustomMaterial &m_Material; - SRenderableImage *m_FirstImage; - SShaderDefaultMaterialKey m_ShaderDescription; - - SCustomMaterialRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, - Qt3DSRendererImpl &gen, const SRenderSubset &subset, - const SCustomMaterial &mat, const SModelContext &modelContext, - QT3DSF32 inOpacity, SRenderableImage *inFirstImage, - SShaderDefaultMaterialKey inShaderKey) - : SSubsetRenderableBase(inFlags, inWorldCenterPt, gen, subset, modelContext, inOpacity) - , m_Material(mat) - , m_FirstImage(inFirstImage) - , m_ShaderDescription(inShaderKey) - { - m_RenderableFlags.SetCustomMaterialMeshSubset(true); - } - - void Render(const QT3DSVec2 &inCameraVec, const SLayerRenderData &inLayerData, - const SLayer &inLayer, NVDataRef inLights, const SCamera &inCamera, - const NVRenderTexture2D *inDepthTexture, const NVRenderTexture2D *inSsaoTexture, - TShaderFeatureSet inFeatureSet); - - void RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, - NVConstDataRef inLights, const SCamera &inCamera, - const NVRenderTexture2D *inDepthTexture); - }; - - struct STextScaleAndOffset - { - QT3DSVec2 m_TextOffset; - QT3DSVec2 m_TextScale; - STextScaleAndOffset(const QT3DSVec2 &inTextOffset, const QT3DSVec2 &inTextScale) - : m_TextOffset(inTextOffset) - , m_TextScale(inTextScale) - { - } - STextScaleAndOffset(NVRenderTexture2D &inTexture, const STextTextureDetails &inTextDetails, - const STextRenderInfo &inInfo); - }; - - struct STextRenderable : public SRenderableObject, public STextScaleAndOffset - { - Qt3DSRendererImpl &m_Generator; - const SText &m_Text; - NVRenderTexture2D &m_Texture; - QT3DSMat44 m_ModelViewProjection; - QT3DSMat44 m_ViewProjection; - - STextRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, - Qt3DSRendererImpl &gen, const SText &inText, const NVBounds3 &inBounds, - const QT3DSMat44 &inModelViewProjection, const QT3DSMat44 &inViewProjection, - NVRenderTexture2D &inTextTexture, const QT3DSVec2 &inTextOffset, - const QT3DSVec2 &inTextScale) - : SRenderableObject(inFlags, inWorldCenterPt, inText.m_GlobalTransform, inBounds) - , STextScaleAndOffset(inTextOffset, inTextScale) - , m_Generator(gen) - , m_Text(inText) - , m_Texture(inTextTexture) - , m_ModelViewProjection(inModelViewProjection) - , m_ViewProjection(inViewProjection) - { - m_RenderableFlags.SetDefaultMaterialMeshSubset(false); - m_RenderableFlags.SetCustom(false); - m_RenderableFlags.SetText(true); - } - - void Render(const QT3DSVec2 &inCameraVec); - void RenderDepthPass(const QT3DSVec2 &inCameraVec); - }; - - struct SPathRenderable : public SRenderableObject - { - Qt3DSRendererImpl &m_Generator; - SPath &m_Path; - NVBounds3 m_Bounds; - QT3DSMat44 m_ModelViewProjection; - QT3DSMat33 m_NormalMatrix; - const SGraphObject &m_Material; - QT3DSF32 m_Opacity; - SRenderableImage *m_FirstImage; - SShaderDefaultMaterialKey m_ShaderDescription; - bool m_IsStroke; - - SPathRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, - Qt3DSRendererImpl &gen, const QT3DSMat44 &inGlobalTransform, - NVBounds3 &inBounds, SPath &inPath, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 inNormalMat, const SGraphObject &inMaterial, QT3DSF32 inOpacity, - SShaderDefaultMaterialKey inShaderKey, bool inIsStroke) - - : SRenderableObject(inFlags, inWorldCenterPt, inGlobalTransform, m_Bounds) - , m_Generator(gen) - , m_Path(inPath) - , m_Bounds(inBounds) - , m_ModelViewProjection(inModelViewProjection) - , m_NormalMatrix(inNormalMat) - , m_Material(inMaterial) - , m_Opacity(inOpacity) - , m_FirstImage(NULL) - , m_ShaderDescription(inShaderKey) - , m_IsStroke(inIsStroke) - { - m_RenderableFlags.SetPath(true); - } - void Render(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, - NVConstDataRef inLights, const SCamera &inCamera, - const NVRenderTexture2D *inDepthTexture, const NVRenderTexture2D *inSsaoTexture, - TShaderFeatureSet inFeatureSet); - - void RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, - NVConstDataRef inLights, const SCamera &inCamera, - const NVRenderTexture2D *inDepthTexture); - - void RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, - const SCamera &inCamera, SShadowMapEntry *inShadowMapEntry); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.cpp deleted file mode 100644 index d6fb3b1b..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.cpp +++ /dev/null @@ -1,2014 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRender.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRendererImpl.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSRenderBufferManager.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "EASTL/sort.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderPresentation.h" -#include "Qt3DSRenderEffect.h" -#include "Qt3DSRenderEffectSystem.h" -#include "Qt3DSRenderResourceManager.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "Qt3DSRenderTextTextureCache.h" -#include "Qt3DSRenderTextTextureAtlas.h" -#include "Qt3DSRenderMaterialHelpers.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include - -#ifdef _WIN32 -#pragma warning(disable : 4355) -#endif - -// Quick tests you can run to find performance problems - -//#define QT3DS_RENDER_DISABLE_HARDWARE_BLENDING 1 -//#define QT3DS_RENDER_DISABLE_LIGHTING 1 -//#define QT3DS_RENDER_DISABLE_TEXTURING 1 -//#define QT3DS_RENDER_DISABLE_TRANSPARENCY 1 -//#define QT3DS_RENDER_DISABLE_FRUSTUM_CULLING 1 - -// If you are fillrate bound then sorting opaque objects can help in some circumstances -//#define QT3DS_RENDER_DISABLE_OPAQUE_SORT 1 - -using qt3ds::foundation::CRegisteredString; - -namespace qt3ds { -namespace render { - - struct SRenderableImage; - struct SShaderGeneratorGeneratedShader; - struct SSubsetRenderable; - using eastl::make_pair; - using eastl::reverse; - using eastl::stable_sort; - - SEndlType Endl; - - static SRenderInstanceId combineLayerAndId(const SLayer *layer, const SRenderInstanceId id) - { - uint64_t x = (uint64_t)layer; - x += 31u * (uint64_t)id; - return (SRenderInstanceId)x; - } - - Qt3DSRendererImpl::Qt3DSRendererImpl(IQt3DSRenderContext &ctx) - : m_qt3dsContext(ctx) - , m_Context(ctx.GetRenderContext()) - , m_BufferManager(ctx.GetBufferManager()) - , m_OffscreenRenderManager(ctx.GetOffscreenRenderManager()) - , m_StringTable(IStringTable::CreateStringTable(ctx.GetAllocator())) - , m_LayerShaders(ctx.GetAllocator(), "Qt3DSRendererImpl::m_LayerShaders") - , m_Shaders(ctx.GetAllocator(), "Qt3DSRendererImpl::m_Shaders") - , m_ConstantBuffers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_ConstantBuffers") - , m_TextShader(ctx.GetAllocator()) - , m_TextPathShader(ctx.GetAllocator()) - , m_TextWidgetShader(ctx.GetAllocator()) - , m_TextOnscreenShader(ctx.GetAllocator()) -#ifdef ADVANCED_BLEND_SW_FALLBACK - , m_LayerBlendTexture(ctx.GetResourceManager()) - , m_BlendFB(NULL) -#endif - , m_InstanceRenderMap(ctx.GetAllocator(), "Qt3DSRendererImpl::m_InstanceRenderMap") - , m_LastFrameLayers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_LastFrameLayers") - , mRefCount(0) - , m_LastPickResults(ctx.GetAllocator(), "Qt3DSRendererImpl::m_LastPickResults") - , m_CurrentLayer(NULL) - , m_WidgetVertexBuffers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetVertexBuffers") - , m_WidgetIndexBuffers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetIndexBuffers") - , m_WidgetShaders(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetShaders") - , m_WidgetInputAssembler(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetInputAssembler") - , m_BoneIdNodeMap(ctx.GetAllocator(), "Qt3DSRendererImpl::m_BoneIdNodeMap") - , m_PickRenderPlugins(true) - , m_LayerCachingEnabled(true) - , m_LayerGPuProfilingEnabled(false) - { - } - Qt3DSRendererImpl::~Qt3DSRendererImpl() - { - m_LayerShaders.clear(); - for (TShaderMap::iterator iter = m_Shaders.begin(), end = m_Shaders.end(); iter != end; - ++iter) - NVDelete(m_Context->GetAllocator(), iter->second); - - m_Shaders.clear(); - m_InstanceRenderMap.clear(); - m_ConstantBuffers.clear(); - } - - void Qt3DSRendererImpl::addRef() { atomicIncrement(&mRefCount); } - - void Qt3DSRendererImpl::release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Context->GetAllocator()); } - - void Qt3DSRendererImpl::ChildrenUpdated(SNode &inParent) - { - if (inParent.m_Type == GraphObjectTypes::Layer) { - TInstanceRenderMap::iterator theIter = - m_InstanceRenderMap.find(static_cast(&inParent)); - if (theIter != m_InstanceRenderMap.end()) { - theIter->second->m_CamerasAndLights.clear(); - theIter->second->m_RenderableNodes.clear(); - } - } else if (inParent.m_Parent) - ChildrenUpdated(*inParent.m_Parent); - } - - QT3DSF32 Qt3DSRendererImpl::GetTextScale(const SText &inText) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inText); - if (theData) - return theData->m_TextScale; - return 1.0f; - } - - static inline SLayer *GetNextLayer(SLayer &inLayer) - { - if (inLayer.m_NextSibling && inLayer.m_NextSibling->m_Type == GraphObjectTypes::Layer) - return static_cast(inLayer.m_NextSibling); - return NULL; - } - - static inline void MaybePushLayer(SLayer &inLayer, nvvector &outLayerList) - { - inLayer.CalculateGlobalVariables(); - if (inLayer.m_Flags.IsGloballyActive() && inLayer.m_Flags.IsLayerRenderToTarget()) - outLayerList.push_back(&inLayer); - } - static void BuildRenderableLayers(SLayer &inLayer, nvvector &renderableLayers, - bool inRenderSiblings) - { - MaybePushLayer(inLayer, renderableLayers); - if (inRenderSiblings) { - for (SLayer *theNextLayer = GetNextLayer(inLayer); theNextLayer; - theNextLayer = GetNextLayer(*theNextLayer)) - MaybePushLayer(*theNextLayer, renderableLayers); - } - } - - bool Qt3DSRendererImpl::PrepareLayerForRender(SLayer &inLayer, - const QT3DSVec2 &inViewportDimensions, - bool inRenderSiblings, - const SRenderInstanceId id) - { - (void)inViewportDimensions; - nvvector renderableLayers(m_qt3dsContext.GetPerFrameAllocator(), "LayerVector"); - // Found by fair roll of the dice. - renderableLayers.reserve(4); - - BuildRenderableLayers(inLayer, renderableLayers, inRenderSiblings); - - bool retval = false; - - for (nvvector::reverse_iterator iter = renderableLayers.rbegin(), - end = renderableLayers.rend(); - iter != end; ++iter) { - // Store the previous state of if we were rendering a layer. - SLayer *theLayer = *iter; - SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id); - - if (theRenderData) { - theRenderData->PrepareForRender(); - retval = retval || theRenderData->m_LayerPrepResult->m_Flags.WasDirty(); - } else { - QT3DS_ASSERT(false); - } - } - - return retval; - } - - void Qt3DSRendererImpl::RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - bool clear, QT3DSVec3 clearColor, bool inRenderSiblings, - const SRenderInstanceId id) - { - (void)inViewportDimensions; - nvvector renderableLayers(m_qt3dsContext.GetPerFrameAllocator(), "LayerVector"); - // Found by fair roll of the dice. - renderableLayers.reserve(4); - - BuildRenderableLayers(inLayer, renderableLayers, inRenderSiblings); - - NVRenderContext &theRenderContext(m_qt3dsContext.GetRenderContext()); - qt3ds::render::NVRenderFrameBuffer *theFB = theRenderContext.GetRenderTarget(); - for (nvvector::reverse_iterator iter = renderableLayers.rbegin(), - end = renderableLayers.rend(); - iter != end; ++iter) { - SLayer *theLayer = *iter; - SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id); - SLayerRenderPreparationResult &prepRes(*theRenderData->m_LayerPrepResult); - LayerBlendTypes::Enum layerBlend = prepRes.GetLayer()->GetLayerBlend(); -#ifdef ADVANCED_BLEND_SW_FALLBACK - if ((layerBlend == LayerBlendTypes::Overlay || - layerBlend == LayerBlendTypes::ColorBurn || - layerBlend == LayerBlendTypes::ColorDodge) && - !theRenderContext.IsAdvancedBlendHwSupported() && - !theRenderContext.IsAdvancedBlendHwSupportedKHR()) { - // Create and set up FBO and texture for advanced blending SW fallback - NVRenderRect viewport = theRenderContext.GetViewport(); - m_LayerBlendTexture.EnsureTexture(viewport.m_Width + viewport.m_X, - viewport.m_Height + viewport.m_Y, - NVRenderTextureFormats::RGBA8); - if (m_BlendFB == NULL) - m_BlendFB = theRenderContext.CreateFrameBuffer(); - m_BlendFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerBlendTexture); - theRenderContext.SetRenderTarget(m_BlendFB); - theRenderContext.SetScissorTestEnabled(false); - QT3DSVec4 color(0.0f, 0.0f, 0.0f, 0.0f); - if (clear) { - color.x = clearColor.x; - color.y = clearColor.y; - color.z = clearColor.z; - color.w = 1.0f; - } - QT3DSVec4 origColor = theRenderContext.GetClearColor(); - theRenderContext.SetClearColor(color); - theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); - theRenderContext.SetClearColor(origColor); - theRenderContext.SetRenderTarget(theFB); - break; - } else { - m_LayerBlendTexture.ReleaseTexture(); - } -#endif - } - for (nvvector::reverse_iterator iter = renderableLayers.rbegin(), - end = renderableLayers.rend(); - iter != end; ++iter) { - // Store the previous state of if we were rendering a layer. - SLayer *theLayer = *iter; - SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id); - - if (theRenderData) { - if (theRenderData->m_LayerPrepResult->IsLayerVisible()) - theRenderData->RunnableRenderToViewport(theFB); - } else { - QT3DS_ASSERT(false); - } - } - } - - SLayer *Qt3DSRendererImpl::GetLayerForNode(const SNode &inNode) const - { - if (inNode.m_Type == GraphObjectTypes::Layer) { - return &const_cast(static_cast(inNode)); - } - if (inNode.m_Parent) - return GetLayerForNode(*inNode.m_Parent); - return NULL; - } - - SLayerRenderData *Qt3DSRendererImpl::GetOrCreateLayerRenderDataForNode(const SNode &inNode, - const SRenderInstanceId id) - { - const SLayer *theLayer = GetLayerForNode(inNode); - if (theLayer) { - TInstanceRenderMap::const_iterator theIter - = m_InstanceRenderMap.find(combineLayerAndId(theLayer, id)); - if (theIter != m_InstanceRenderMap.end()) - return const_cast(theIter->second.mPtr); - - SLayerRenderData *theRenderData = QT3DS_NEW(m_Context->GetAllocator(), SLayerRenderData)( - const_cast(*theLayer), *this); - m_InstanceRenderMap.insert(make_pair(combineLayerAndId(theLayer, id), theRenderData)); - - // create a profiler if enabled - if (IsLayerGpuProfilingEnabled() && theRenderData) - theRenderData->CreateGpuProfiler(); - - return theRenderData; - } - return NULL; - } - - SCamera *Qt3DSRendererImpl::GetCameraForNode(const SNode &inNode) const - { - SLayerRenderData *theLayer = - const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); - if (theLayer) - return theLayer->m_Camera; - return NULL; - } - - Option Qt3DSRendererImpl::GetCameraBounds(const SGraphObject &inObject) - { - if (GraphObjectTypes::IsNodeType(inObject.m_Type)) { - const SNode &theNode = static_cast(inObject); - SLayerRenderData *theLayer = GetOrCreateLayerRenderDataForNode(theNode); - if (theLayer->GetOffscreenRenderer() == false) { - SCamera *theCamera = theLayer->m_Camera; - if (theCamera) - return theCamera->GetCameraBounds( - theLayer->m_LayerPrepResult->GetLayerToPresentationViewport(), - theLayer->m_LayerPrepResult->GetPresentationDesignDimensions()); - } - } - return Option(); - } - - void Qt3DSRendererImpl::DrawScreenRect(NVRenderRectF inRect, const QT3DSVec3 &inColor) - { - SCamera theScreenCamera; - theScreenCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - NVRenderRectF theViewport(m_Context->GetViewport()); - theScreenCamera.m_Flags.SetOrthographic(true); - theScreenCamera.CalculateGlobalVariables(theViewport, - QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); - GenerateXYQuad(); - if (!m_ScreenRectShader) { - IShaderProgramGenerator &theGenerator(GetProgramGenerator()); - theGenerator.BeginProgram(); - IShaderStageGenerator &vertexGenerator( - *theGenerator.GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *theGenerator.GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddUniform("rectangle_dims", "vec3"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append( - "\tgl_Position = model_view_projection * vec4(attr_pos * rectangle_dims, 1.0);"); - vertexGenerator.Append("}"); - fragmentGenerator.AddUniform("output_color", "vec3"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tgl_FragColor.rgb = output_color;"); - fragmentGenerator.Append("\tgl_FragColor.a = 1.0;"); - fragmentGenerator.Append("}"); - // No flags enabled - m_ScreenRectShader = theGenerator.CompileGeneratedShader( - "DrawScreenRect", SShaderCacheProgramFlags(), TShaderFeatureSet()); - } - if (m_ScreenRectShader) { - // Fudge the rect by one pixel to ensure we see all the corners. - if (inRect.m_Width > 1) - inRect.m_Width -= 1; - if (inRect.m_Height > 1) - inRect.m_Height -= 1; - inRect.m_X += 1; - inRect.m_Y += 1; - // Figure out the rect center. - SNode theNode; - - QT3DSVec2 rectGlobalCenter = inRect.Center(); - QT3DSVec2 rectCenter(theViewport.ToNormalizedRectRelative(rectGlobalCenter)); - theNode.m_Position.x = rectCenter.x; - theNode.m_Position.y = rectCenter.y; - theNode.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - theNode.CalculateGlobalVariables(); - QT3DSMat44 theViewProjection; - theScreenCamera.CalculateViewProjectionMatrix(theViewProjection); - QT3DSMat44 theMVP; - QT3DSMat33 theNormal; - theNode.CalculateMVPAndNormalMatrix(theViewProjection, theMVP, theNormal); - m_Context->SetBlendingEnabled(false); - m_Context->SetDepthWriteEnabled(false); - m_Context->SetDepthTestEnabled(false); - m_Context->SetCullingEnabled(false); - m_Context->SetActiveShader(m_ScreenRectShader); - m_ScreenRectShader->SetPropertyValue("model_view_projection", theMVP); - m_ScreenRectShader->SetPropertyValue("output_color", inColor); - m_ScreenRectShader->SetPropertyValue( - "rectangle_dims", QT3DSVec3(inRect.m_Width / 2.0f, inRect.m_Height / 2.0f, 0.0f)); - } - if (!m_RectInputAssembler) { - QT3DS_ASSERT(m_QuadVertexBuffer); - QT3DSU8 indexData[] = { 0, 1, 1, 2, 2, 3, 3, 0 }; - - m_RectIndexBuffer = m_Context->CreateIndexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, - qt3ds::render::NVRenderComponentTypes::QT3DSU8, sizeof(indexData), - toConstDataRef(indexData, sizeof(indexData))); - - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - }; - - // create our attribute layout - m_RectAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 1)); - - QT3DSU32 strides = m_QuadVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_RectInputAssembler = m_Context->CreateInputAssembler( - m_RectAttribLayout, toConstDataRef(&m_QuadVertexBuffer.mPtr, 1), m_RectIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - - m_Context->SetInputAssembler(m_RectInputAssembler); - m_Context->Draw(NVRenderDrawMode::Lines, m_RectIndexBuffer->GetNumIndices(), 0); - } - - void Qt3DSRendererImpl::SetupWidgetLayer() - { - NVRenderContext &theContext = m_qt3dsContext.GetRenderContext(); - - if (!m_WidgetTexture) { - IResourceManager &theManager = m_qt3dsContext.GetResourceManager(); - m_WidgetTexture = theManager.AllocateTexture2D(m_BeginFrameViewport.m_Width, - m_BeginFrameViewport.m_Height, - NVRenderTextureFormats::RGBA8); - m_WidgetFBO = theManager.AllocateFrameBuffer(); - m_WidgetFBO->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*m_WidgetTexture)); - theContext.SetRenderTarget(m_WidgetFBO); - - // NVRenderRect theScissorRect( 0, 0, m_BeginFrameViewport.m_Width, - // m_BeginFrameViewport.m_Height ); - // NVRenderContextScopedProperty __scissorRect( theContext, - // &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect, theScissorRect ); - qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, false); - m_Context->SetClearColor(QT3DSVec4(0, 0, 0, 0)); - m_Context->Clear(NVRenderClearValues::Color); - - } else - theContext.SetRenderTarget(m_WidgetFBO); - } - - void Qt3DSRendererImpl::BeginFrame() - { - for (QT3DSU32 idx = 0, end = m_LastFrameLayers.size(); idx < end; ++idx) - m_LastFrameLayers[idx]->ResetForFrame(); - m_LastFrameLayers.clear(); - m_BeginFrameViewport = m_qt3dsContext.GetRenderList().GetViewport(); - } - void Qt3DSRendererImpl::EndFrame() - { - if (m_WidgetTexture) { - using qt3ds::render::NVRenderContextScopedProperty; - // Releasing the widget FBO can set it as the active frame buffer. - NVRenderContextScopedProperty __fbo( - *m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - STextureDetails theDetails = m_WidgetTexture->GetTextureDetails(); - m_Context->SetBlendingEnabled(true); - // Colors are expected to be non-premultiplied, so we premultiply alpha into them at - // this point. - m_Context->SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); - m_Context->SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); - - m_Context->SetDepthTestEnabled(false); - m_Context->SetScissorTestEnabled(false); - m_Context->SetViewport(m_BeginFrameViewport); - SCamera theCamera; - theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - theCamera.m_Flags.SetOrthographic(true); - QT3DSVec2 theTextureDims((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); - theCamera.CalculateGlobalVariables( - NVRenderRect(0, 0, theDetails.m_Width, theDetails.m_Height), theTextureDims); - QT3DSMat44 theViewProj; - theCamera.CalculateViewProjectionMatrix(theViewProj); - RenderQuad(theTextureDims, theViewProj, *m_WidgetTexture); - - IResourceManager &theManager(m_qt3dsContext.GetResourceManager()); - theManager.Release(*m_WidgetFBO); - theManager.Release(*m_WidgetTexture); - m_WidgetTexture = NULL; - m_WidgetFBO = NULL; - } - } - - inline bool PickResultLessThan(const Qt3DSRenderPickResult &lhs, const Qt3DSRenderPickResult &rhs) - { - return FloatLessThan(lhs.m_CameraDistanceSq, rhs.m_CameraDistanceSq); - } - - inline QT3DSF32 ClampUVCoord(QT3DSF32 inUVCoord, NVRenderTextureCoordOp::Enum inCoordOp) - { - if (inUVCoord > 1.0f || inUVCoord < 0.0f) { - switch (inCoordOp) { - default: - QT3DS_ASSERT(false); - break; - case NVRenderTextureCoordOp::ClampToEdge: - inUVCoord = NVMin(inUVCoord, 1.0f); - inUVCoord = NVMax(inUVCoord, 0.0f); - break; - case NVRenderTextureCoordOp::Repeat: { - QT3DSF32 multiplier = inUVCoord > 0.0f ? 1.0f : -1.0f; - QT3DSF32 clamp = fabs(inUVCoord); - clamp = clamp - floor(clamp); - if (multiplier < 0) - inUVCoord = 1.0f - clamp; - else - inUVCoord = clamp; - } break; - case NVRenderTextureCoordOp::MirroredRepeat: { - QT3DSF32 multiplier = inUVCoord > 0.0f ? 1.0f : -1.0f; - QT3DSF32 clamp = fabs(inUVCoord); - if (multiplier > 0.0f) - clamp -= 1.0f; - QT3DSU32 isMirrored = ((QT3DSU32)clamp) % 2 == 0; - QT3DSF32 remainder = clamp - floor(clamp); - inUVCoord = remainder; - if (isMirrored) { - if (multiplier > 0.0f) - inUVCoord = 1.0f - inUVCoord; - } else { - if (multiplier < 0.0f) - inUVCoord = 1.0f - remainder; - } - } break; - } - } - return inUVCoord; - } - - static eastl::pair - GetMouseCoordsAndViewportFromSubObject(QT3DSVec2 inLocalHitUVSpace, - Qt3DSRenderPickSubResult &inSubResult) - { - QT3DSMat44 theTextureMatrix(inSubResult.m_TextureMatrix); - QT3DSVec3 theNewUVCoords( - theTextureMatrix.transform(QT3DSVec3(inLocalHitUVSpace.x, inLocalHitUVSpace.y, 0))); - theNewUVCoords.x = ClampUVCoord(theNewUVCoords.x, inSubResult.m_HorizontalTilingMode); - theNewUVCoords.y = ClampUVCoord(theNewUVCoords.y, inSubResult.m_VerticalTilingMode); - QT3DSVec2 theViewportDimensions = - QT3DSVec2((QT3DSF32)inSubResult.m_ViewportWidth, (QT3DSF32)inSubResult.m_ViewportHeight); - QT3DSVec2 theMouseCoords(theNewUVCoords.x * theViewportDimensions.x, - (1.0f - theNewUVCoords.y) * theViewportDimensions.y); - - return eastl::make_pair(theMouseCoords, theViewportDimensions); - } - - SPickResultProcessResult Qt3DSRendererImpl::ProcessPickResultList(bool inPickEverything) - { - if (m_LastPickResults.empty()) - return SPickResultProcessResult(); - // Things are rendered in a particular order and we need to respect that ordering. - eastl::stable_sort(m_LastPickResults.begin(), m_LastPickResults.end(), PickResultLessThan); - - // We need to pick against sub objects basically somewhat recursively - // but if we don't hit any sub objects and the parent isn't pickable then - // we need to move onto the next item in the list. - // We need to keep in mind that theQuery->Pick will enter this method in a later - // stack frame so *if* we get to sub objects we need to pick against them but if the pick - // completely misses *and* the parent object locally pickable is false then we need to move - // onto the next object. - - QT3DSU32 maxPerFrameAllocationPickResultCount = - SFastAllocator<>::SlabSize / sizeof(Qt3DSRenderPickResult); - QT3DSU32 numToCopy = - NVMin(maxPerFrameAllocationPickResultCount, (QT3DSU32)m_LastPickResults.size()); - QT3DSU32 numCopyBytes = numToCopy * sizeof(Qt3DSRenderPickResult); - Qt3DSRenderPickResult *thePickResults = reinterpret_cast( - GetPerFrameAllocator().allocate(numCopyBytes, "tempPickData", __FILE__, __LINE__)); - memCopy(thePickResults, m_LastPickResults.data(), numCopyBytes); - m_LastPickResults.clear(); - bool foundValidResult = false; - SPickResultProcessResult thePickResult(thePickResults[0]); - for (size_t idx = 0; idx < numToCopy && foundValidResult == false; ++idx) { - thePickResult = thePickResults[idx]; - // Here we do a hierarchy. Picking against sub objects takes precedence. - // If picking against the sub object doesn't return a valid result *and* - // the current object isn't globally pickable then we move onto the next object returned - // by the pick query. - if (thePickResult.m_HitObject != NULL && thePickResult.m_FirstSubObject != NULL - && m_PickRenderPlugins) { - QT3DSVec2 theUVCoords(thePickResult.m_LocalUVCoords.x, - thePickResult.m_LocalUVCoords.y); - IOffscreenRenderer *theSubRenderer(thePickResult.m_FirstSubObject->m_SubRenderer); - eastl::pair mouseAndViewport = - GetMouseCoordsAndViewportFromSubObject(theUVCoords, - *thePickResult.m_FirstSubObject); - QT3DSVec2 theMouseCoords = mouseAndViewport.first; - QT3DSVec2 theViewportDimensions = mouseAndViewport.second; - IGraphObjectPickQuery *theQuery = theSubRenderer->GetGraphObjectPickQuery(this); - if (theQuery) { - Qt3DSRenderPickResult theInnerPickResult = - theQuery->Pick(theMouseCoords, theViewportDimensions, inPickEverything); - if (theInnerPickResult.m_HitObject) { - thePickResult = theInnerPickResult; - thePickResult.m_OffscreenRenderer = theSubRenderer; - foundValidResult = true; - thePickResult.m_WasPickConsumed = true; - } else if (GraphObjectTypes::IsNodeType(thePickResult.m_HitObject->m_Type)) { - const SNode *theNode = - static_cast(thePickResult.m_HitObject); - if (theNode->m_Flags.IsGloballyPickable() == true) { - foundValidResult = true; - thePickResult.m_WasPickConsumed = true; - } - } - } else { - // If the sub renderer doesn't consume the pick then we return the picked object - // itself. So no matter what, if we get to here the pick was consumed. - thePickResult.m_WasPickConsumed = true; - bool wasPickConsumed = - theSubRenderer->Pick(theMouseCoords, theViewportDimensions, this); - if (wasPickConsumed) { - thePickResult.m_HitObject = NULL; - foundValidResult = true; - } - } - } else { - foundValidResult = true; - thePickResult.m_WasPickConsumed = true; - } - } - return thePickResult; - } - - Qt3DSRenderPickResult Qt3DSRendererImpl::Pick(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, bool inPickSiblings, - bool inPickEverything, const SRenderInstanceId id) - { - m_LastPickResults.clear(); - - SLayer *theLayer = &inLayer; - // Stepping through how the original runtime did picking it picked layers in order - // stopping at the first hit. So objects on the top layer had first crack at the pick - // vector itself. - do { - if (theLayer->m_Flags.IsActive()) { - TInstanceRenderMap::iterator theIter - = m_InstanceRenderMap.find(combineLayerAndId(theLayer, id)); - if (theIter != m_InstanceRenderMap.end()) { - m_LastPickResults.clear(); - GetLayerHitObjectList(*theIter->second, inViewportDimensions, inMouseCoords, - inPickEverything, m_LastPickResults, - GetPerFrameAllocator()); - SPickResultProcessResult retval(ProcessPickResultList(inPickEverything)); - if (retval.m_WasPickConsumed) - return retval; - } else { - // QT3DS_ASSERT( false ); - } - } - - if (inPickSiblings) - theLayer = GetNextLayer(*theLayer); - else - theLayer = NULL; - } while (theLayer != NULL); - - return Qt3DSRenderPickResult(); - } - - static inline Option IntersectRayWithNode(const SNode &inNode, - SRenderableObject &inRenderableObject, - const SRay &inPickRay) - { - if (inRenderableObject.m_RenderableFlags.IsText()) { - STextRenderable &theRenderable = static_cast(inRenderableObject); - if (&theRenderable.m_Text == &inNode) - return inPickRay.GetRelativeXY(inRenderableObject.m_GlobalTransform, - inRenderableObject.m_Bounds); - } else if (inRenderableObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) { - SSubsetRenderable &theRenderable = static_cast(inRenderableObject); - if (&theRenderable.m_ModelContext.m_Model == &inNode) - return inPickRay.GetRelativeXY(inRenderableObject.m_GlobalTransform, - inRenderableObject.m_Bounds); - } else if (inRenderableObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - SCustomMaterialRenderable &theRenderable = - static_cast(inRenderableObject); - if (&theRenderable.m_ModelContext.m_Model == &inNode) - return inPickRay.GetRelativeXY(inRenderableObject.m_GlobalTransform, - inRenderableObject.m_Bounds); - } else { - QT3DS_ASSERT(false); - } - return Empty(); - } - - static inline Qt3DSRenderPickSubResult ConstructSubResult(SImage &inImage) - { - STextureDetails theDetails = inImage.m_TextureData.m_Texture->GetTextureDetails(); - return Qt3DSRenderPickSubResult(*inImage.m_LastFrameOffscreenRenderer, - inImage.m_TextureTransform, inImage.m_HorizontalTilingMode, - inImage.m_VerticalTilingMode, theDetails.m_Width, - theDetails.m_Height); - } - - Option Qt3DSRendererImpl::FacePosition(SNode &inNode, NVBounds3 inBounds, - const QT3DSMat44 &inGlobalTransform, - const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, - NVDataRef inMapperObjects, - SBasisPlanes::Enum inPlane) - { - SLayerRenderData *theLayerData = GetOrCreateLayerRenderDataForNode(inNode); - if (theLayerData == NULL) - return Empty(); - // This function assumes the layer was rendered to the scene itself. There is another - // function - // for completely offscreen layers that don't get rendered to the scene. - bool wasRenderToTarget(theLayerData->m_Layer.m_Flags.IsLayerRenderToTarget()); - if (wasRenderToTarget == false || theLayerData->m_Camera == NULL - || theLayerData->m_LayerPrepResult.hasValue() == false - || theLayerData->m_LastFrameOffscreenRenderer.mPtr != NULL) - return Empty(); - - QT3DSVec2 theMouseCoords(inMouseCoords); - QT3DSVec2 theViewportDimensions(inViewportDimensions); - - for (QT3DSU32 idx = 0, end = inMapperObjects.size(); idx < end; ++idx) { - SGraphObject ¤tObject = *inMapperObjects[idx]; - if (currentObject.m_Type == GraphObjectTypes::Layer) { - // The layer knows its viewport so it can take the information directly. - // This is extremely counter intuitive but a good sign. - } else if (currentObject.m_Type == GraphObjectTypes::Image) { - SImage &theImage = static_cast(currentObject); - SModel *theParentModel = NULL; - if (theImage.m_Parent - && theImage.m_Parent->m_Type == GraphObjectTypes::DefaultMaterial) { - SDefaultMaterial *theMaterial = - static_cast(theImage.m_Parent); - if (theMaterial) { - theParentModel = theMaterial->m_Parent; - } - } - if (theParentModel == NULL) { - QT3DS_ASSERT(false); - return Empty(); - } - NVBounds3 theModelBounds = theParentModel->GetBounds( - GetQt3DSContext().GetBufferManager(), GetQt3DSContext().GetPathManager(), false); - - if (theModelBounds.isEmpty()) { - QT3DS_ASSERT(false); - return Empty(); - } - Option relativeHit = - FacePosition(*theParentModel, theModelBounds, theParentModel->m_GlobalTransform, - theViewportDimensions, theMouseCoords, NVDataRef(), - SBasisPlanes::XY); - if (relativeHit.isEmpty()) { - return Empty(); - } - Qt3DSRenderPickSubResult theResult = ConstructSubResult(theImage); - QT3DSVec2 hitInUVSpace = (*relativeHit) + QT3DSVec2(.5f, .5f); - eastl::pair mouseAndViewport = - GetMouseCoordsAndViewportFromSubObject(hitInUVSpace, theResult); - theMouseCoords = mouseAndViewport.first; - theViewportDimensions = mouseAndViewport.second; - } - } - - Option theHitRay = theLayerData->m_LayerPrepResult->GetPickRay( - theMouseCoords, theViewportDimensions, false); - if (theHitRay.hasValue() == false) - return Empty(); - - // Scale the mouse coords to change them into the camera's numerical space. - SRay thePickRay = *theHitRay; - Option newValue = thePickRay.GetRelative(inGlobalTransform, inBounds, inPlane); - return newValue; - } - - Qt3DSRenderPickResult - Qt3DSRendererImpl::PickOffscreenLayer(SLayer &/*inLayer*/, const QT3DSVec2 & /*inViewportDimensions*/ - , - const QT3DSVec2 & /*inMouseCoords*/ - , - bool /*inPickEverything*/) - { - return Qt3DSRenderPickResult(); - } - - QT3DSVec3 Qt3DSRendererImpl::UnprojectToPosition(SNode &inNode, QT3DSVec3 &inPosition, - const QT3DSVec2 &inMouseVec) const - { - // Translate mouse into layer's coordinates - SLayerRenderData *theData = - const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); - if (theData == NULL || theData->m_Camera == NULL) { - return QT3DSVec3(0, 0, 0); - } // QT3DS_ASSERT( false ); return QT3DSVec3(0,0,0); } - - QSize theWindow = m_qt3dsContext.GetWindowDimensions(); - QT3DSVec2 theDims((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()); - - SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); - SRay theRay = thePrepResult.GetPickRay(inMouseVec, theDims, true); - - return theData->m_Camera->UnprojectToPosition(inPosition, theRay); - } - - QT3DSVec3 Qt3DSRendererImpl::UnprojectWithDepth(SNode &inNode, QT3DSVec3 &, - const QT3DSVec3 &inMouseVec) const - { - // Translate mouse into layer's coordinates - SLayerRenderData *theData = - const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); - if (theData == NULL || theData->m_Camera == NULL) { - return QT3DSVec3(0, 0, 0); - } // QT3DS_ASSERT( false ); return QT3DSVec3(0,0,0); } - - // Flip the y into gl coordinates from window coordinates. - QT3DSVec2 theMouse(inMouseVec.x, inMouseVec.y); - NVReal theDepth = inMouseVec.z; - - SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); - QSize theWindow = m_qt3dsContext.GetWindowDimensions(); - SRay theRay = thePrepResult.GetPickRay( - theMouse, QT3DSVec2((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()), true); - QT3DSVec3 theTargetPosition = theRay.m_Origin + theRay.m_Direction * theDepth; - if (inNode.m_Parent != NULL && inNode.m_Parent->m_Type != GraphObjectTypes::Layer) - theTargetPosition = - inNode.m_Parent->m_GlobalTransform.getInverse().transform(theTargetPosition); - // Our default global space is right handed, so if you are left handed z means something - // opposite. - if (inNode.m_Flags.IsLeftHanded()) - theTargetPosition.z *= -1; - return theTargetPosition; - } - - QT3DSVec3 Qt3DSRendererImpl::ProjectPosition(SNode &inNode, const QT3DSVec3 &inPosition) const - { - // Translate mouse into layer's coordinates - SLayerRenderData *theData = - const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); - if (theData == NULL || theData->m_Camera == NULL) { - return QT3DSVec3(0, 0, 0); - } - - QT3DSMat44 viewProj; - theData->m_Camera->CalculateViewProjectionMatrix(viewProj); - QT3DSVec4 projPos = viewProj.transform(QT3DSVec4(inPosition, 1.0f)); - projPos.x /= projPos.w; - projPos.y /= projPos.w; - - NVRenderRectF theViewport = theData->m_LayerPrepResult->GetLayerToPresentationViewport(); - QT3DSVec2 theDims((QT3DSF32)theViewport.m_Width, (QT3DSF32)theViewport.m_Height); - projPos.x += 1.0; - projPos.y += 1.0; - projPos.x *= 0.5; - projPos.y *= 0.5; - QT3DSVec3 cameraToObject = theData->m_Camera->GetGlobalPos() - inPosition; - projPos.z = sqrtf(cameraToObject.dot(cameraToObject)); - QT3DSVec3 mouseVec = QT3DSVec3(projPos.x, projPos.y, projPos.z); - mouseVec.x *= theDims.x; - mouseVec.y *= theDims.y; - - mouseVec.x += theViewport.m_X; - mouseVec.y += theViewport.m_Y; - - // Flip the y into window coordinates so it matches the mouse. - QSize theWindow = m_qt3dsContext.GetWindowDimensions(); - mouseVec.y = theWindow.height() - mouseVec.y; - - return mouseVec; - } - - Option Qt3DSRendererImpl::GetLayerPickSetup(SLayer &inLayer, - const QT3DSVec2 &inMouseCoords, - const QSize &inPickDims) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); - if (theData == NULL || theData->m_Camera == NULL) { - QT3DS_ASSERT(false); - return Empty(); - } - QSize theWindow = m_qt3dsContext.GetWindowDimensions(); - QT3DSVec2 theDims((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()); - // The mouse is relative to the layer - Option theLocalMouse = GetLayerMouseCoords(*theData, inMouseCoords, theDims, false); - if (theLocalMouse.hasValue() == false) { - return Empty(); - } - - SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); - if (thePrepResult.GetCamera() == NULL) { - return Empty(); - } - // Perform gluPickMatrix and pre-multiply it into the view projection - QT3DSMat44 theTransScale(QT3DSMat44::createIdentity()); - SCamera &theCamera(*thePrepResult.GetCamera()); - - NVRenderRectF layerToPresentation = thePrepResult.GetLayerToPresentationViewport(); - // Offsetting is already taken care of in the camera's projection. - // All we need to do is to scale and translate the image. - layerToPresentation.m_X = 0; - layerToPresentation.m_Y = 0; - QT3DSVec2 theMouse(*theLocalMouse); - // The viewport will need to center at this location - QT3DSVec2 viewportDims((QT3DSF32)inPickDims.width(), (QT3DSF32)inPickDims.height()); - QT3DSVec2 bottomLeft = - QT3DSVec2(theMouse.x - viewportDims.x / 2.0f, theMouse.y - viewportDims.y / 2.0f); - // For some reason, and I haven't figured out why yet, the offsets need to be backwards for - // this to work. - // bottomLeft.x = layerToPresentation.m_Width - bottomLeft.x; - // bottomLeft.y = layerToPresentation.m_Height - bottomLeft.y; - // Virtual rect is relative to the layer. - NVRenderRectF thePickRect(bottomLeft.x, bottomLeft.y, viewportDims.x, viewportDims.y); - QT3DSMat44 projectionPremult(QT3DSMat44::createIdentity()); - projectionPremult = render::NVRenderContext::ApplyVirtualViewportToProjectionMatrix( - projectionPremult, layerToPresentation, thePickRect); - projectionPremult = projectionPremult.getInverse(); - - QT3DSMat44 globalInverse = theCamera.m_GlobalTransform.getInverse(); - QT3DSMat44 theVP = theCamera.m_Projection * globalInverse; - // For now we won't setup the scissor, so we may be off by inPickDims at most because - // GetLayerMouseCoords will return - // false if the mouse is too far off the layer. - return SLayerPickSetup(projectionPremult, theVP, - NVRenderRect(0, 0, (QT3DSU32)layerToPresentation.m_Width, - (QT3DSU32)layerToPresentation.m_Height)); - } - - Option Qt3DSRendererImpl::GetLayerRect(SLayer &inLayer) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); - if (theData == NULL || theData->m_Camera == NULL) { - QT3DS_ASSERT(false); - return Empty(); - } - SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); - return thePrepResult.GetLayerToPresentationViewport(); - } - - // This doesn't have to be cheap. - void Qt3DSRendererImpl::RunLayerRender(SLayer &inLayer, const QT3DSMat44 &inViewProjection) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); - if (theData == NULL || theData->m_Camera == NULL) { - QT3DS_ASSERT(false); - return; - } - theData->PrepareAndRender(inViewProjection); - } - - void Qt3DSRendererImpl::AddRenderWidget(IRenderWidget &inWidget) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inWidget.GetNode()); - if (theData) - theData->AddRenderWidget(inWidget); - } - - void Qt3DSRendererImpl::RenderLayerRect(SLayer &inLayer, const QT3DSVec3 &inColor) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); - if (theData) - theData->m_BoundingRectColor = inColor; - } - - SScaleAndPosition Qt3DSRendererImpl::GetWorldToPixelScaleFactor(const SCamera &inCamera, - const QT3DSVec3 &inWorldPoint, - SLayerRenderData &inRenderData) - { - if (inCamera.m_Flags.IsOrthographic() == true) { - // There are situations where the camera can scale. - return SScaleAndPosition( - inWorldPoint, - inCamera.GetOrthographicScaleFactor( - inRenderData.m_LayerPrepResult->GetLayerToPresentationViewport(), - inRenderData.m_LayerPrepResult->GetPresentationDesignDimensions())); - } else { - QT3DSVec3 theCameraPos(0, 0, 0); - QT3DSVec3 theCameraDir(0, 0, -1); - SRay theRay(theCameraPos, inWorldPoint - theCameraPos); - NVPlane thePlane(theCameraDir, -600); - QT3DSVec3 theItemPosition(inWorldPoint); - Option theIntersection = theRay.Intersect(thePlane); - if (theIntersection.hasValue()) - theItemPosition = *theIntersection; - // The special number comes in from physically measuring how off we are on the screen. - QT3DSF32 theScaleFactor = (1.0f / inCamera.m_Projection.column1[1]); - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inCamera); - QT3DSU32 theHeight = theData->m_LayerPrepResult->GetTextureDimensions().height(); - QT3DSF32 theScaleMultiplier = 600.0f / ((QT3DSF32)theHeight / 2.0f); - theScaleFactor *= theScaleMultiplier; - - return SScaleAndPosition(theItemPosition, theScaleFactor); - } - } - - SScaleAndPosition Qt3DSRendererImpl::GetWorldToPixelScaleFactor(SLayer &inLayer, - const QT3DSVec3 &inWorldPoint) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); - if (theData == NULL || theData->m_Camera == NULL) { - QT3DS_ASSERT(false); - return SScaleAndPosition(); - } - return GetWorldToPixelScaleFactor(*theData->m_Camera, inWorldPoint, *theData); - } - - void Qt3DSRendererImpl::ReleaseLayerRenderResources(SLayer &inLayer, const SRenderInstanceId id) - { - TInstanceRenderMap::iterator theIter - = m_InstanceRenderMap.find(combineLayerAndId(&inLayer, id)); - if (theIter != m_InstanceRenderMap.end()) { - TLayerRenderList::iterator theLastFrm = eastl::find( - m_LastFrameLayers.begin(), m_LastFrameLayers.end(), theIter->second.mPtr); - if (theLastFrm != m_LastFrameLayers.end()) { - theIter->second->ResetForFrame(); - m_LastFrameLayers.erase(theLastFrm); - } - m_InstanceRenderMap.erase(theIter); - } - } - - void Qt3DSRendererImpl::RenderQuad(const QT3DSVec2 inDimensions, const QT3DSMat44 &inMVP, - NVRenderTexture2D &inQuadTexture) - { - m_Context->SetCullingEnabled(false); - SLayerSceneShader *theShader = GetSceneLayerShader(); - NVRenderContext &theContext(*m_Context); - theContext.SetActiveShader(&theShader->m_Shader); - theShader->m_MVP.Set(inMVP); - theShader->m_Dimensions.Set(inDimensions); - theShader->m_Sampler.Set(&inQuadTexture); - - GenerateXYQuad(); - theContext.SetInputAssembler(m_QuadInputAssembler); - theContext.Draw(NVRenderDrawMode::Triangles, m_QuadIndexBuffer->GetNumIndices(), 0); - } - - void Qt3DSRendererImpl::RenderQuad() - { - m_Context->SetCullingEnabled(false); - GenerateXYQuad(); - m_Context->SetInputAssembler(m_QuadInputAssembler); - m_Context->Draw(NVRenderDrawMode::Triangles, m_QuadIndexBuffer->GetNumIndices(), 0); - } - - void Qt3DSRendererImpl::RenderPointsIndirect() - { - m_Context->SetCullingEnabled(false); - GenerateXYZPoint(); - m_Context->SetInputAssembler(m_PointInputAssembler); - m_Context->DrawIndirect(NVRenderDrawMode::Points, 0); - } - - void Qt3DSRendererImpl::LayerNeedsFrameClear(SLayerRenderData &inLayer) - { - m_LastFrameLayers.push_back(&inLayer); - } - - void Qt3DSRendererImpl::BeginLayerDepthPassRender(SLayerRenderData &inLayer) - { - m_CurrentLayer = &inLayer; - } - - void Qt3DSRendererImpl::EndLayerDepthPassRender() { m_CurrentLayer = NULL; } - - void Qt3DSRendererImpl::BeginLayerRender(SLayerRenderData &inLayer) - { - m_CurrentLayer = &inLayer; - // Remove all of the shaders from the layer shader set - // so that we can only apply the camera and lighting properties to - // shaders that are in the layer. - m_LayerShaders.clear(); - } - void Qt3DSRendererImpl::EndLayerRender() { m_CurrentLayer = NULL; } - -// Allocate an object that lasts only this frame. -#define RENDER_FRAME_NEW(type) \ - new (m_PerFrameAllocator.m_FastAllocator.allocate(sizeof(type), __FILE__, __LINE__)) type - - void Qt3DSRendererImpl::PrepareImageForIbl(SImage &inImage) - { - if (inImage.m_TextureData.m_Texture && inImage.m_TextureData.m_Texture->GetNumMipmaps() < 1) - inImage.m_TextureData.m_Texture->GenerateMipmaps(); - } - - bool NodeContainsBoneRoot(SNode &childNode, QT3DSI32 rootID) - { - for (SNode *childChild = childNode.m_FirstChild; childChild != NULL; - childChild = childChild->m_NextSibling) { - if (childChild->m_SkeletonId == rootID) - return true; - } - - return false; - } - - void FillBoneIdNodeMap(SNode &childNode, nvhash_map &ioMap) - { - if (childNode.m_SkeletonId >= 0) - ioMap[childNode.m_SkeletonId] = &childNode; - for (SNode *childChild = childNode.m_FirstChild; childChild != NULL; - childChild = childChild->m_NextSibling) - FillBoneIdNodeMap(*childChild, ioMap); - } - - bool Qt3DSRendererImpl::PrepareTextureAtlasForRender() - { - ITextTextureAtlas *theTextureAtlas = m_qt3dsContext.GetTextureAtlas(); - if (theTextureAtlas == NULL) - return false; - - // this is a one time creation - if (!theTextureAtlas->IsInitialized()) { - NVRenderContext &theContext(*m_Context); - NVScopedRefCounted mVertexBuffer; - NVScopedRefCounted mInputAssembler; - NVScopedRefCounted mAttribLayout; - // temporay FB - using qt3ds::render::NVRenderContextScopedProperty; - NVRenderContextScopedProperty __fbo( - *m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - - ITextRenderer &theTextRenderer(*m_qt3dsContext.GetOnscreenTextRenderer()); - TTextTextureAtlasDetailsAndTexture theResult = theTextureAtlas->PrepareTextureAtlas(); - if (!theResult.first.m_EntryCount) { - QT3DS_ASSERT(theResult.first.m_EntryCount); - return false; - } - - // generate the index buffer we need - GenerateXYQuad(); - - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry( - "attr_uv", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), - }; - - // create our attribute layout - mAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); - - NVRenderFrameBuffer *theAtlasFB( - m_qt3dsContext.GetResourceManager().AllocateFrameBuffer()); - theAtlasFB->Attach(NVRenderFrameBufferAttachments::Color0, *theResult.second); - m_qt3dsContext.GetRenderContext().SetRenderTarget(theAtlasFB); - - // this texture contains our single entries - NVRenderTexture2D *theTexture = nullptr; - if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) { - theTexture = m_qt3dsContext.GetResourceManager() - .AllocateTexture2D(32, 32, NVRenderTextureFormats::RGBA8); - } else { - theTexture = m_qt3dsContext.GetResourceManager() - .AllocateTexture2D(32, 32, NVRenderTextureFormats::Alpha8); - } - m_Context->SetClearColor(QT3DSVec4(0, 0, 0, 0)); - m_Context->Clear(NVRenderClearValues::Color); - m_Context->SetDepthTestEnabled(false); - m_Context->SetScissorTestEnabled(false); - m_Context->SetCullingEnabled(false); - m_Context->SetBlendingEnabled(false); - m_Context->SetViewport( - NVRenderRect(0, 0, theResult.first.m_TextWidth, theResult.first.m_TextHeight)); - - SCamera theCamera; - theCamera.m_ClipNear = -1.0; - theCamera.m_ClipFar = 1.0; - theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - theCamera.m_Flags.SetOrthographic(true); - QT3DSVec2 theTextureDims((QT3DSF32)theResult.first.m_TextWidth, - (QT3DSF32)theResult.first.m_TextHeight); - theCamera.CalculateGlobalVariables( - NVRenderRect(0, 0, theResult.first.m_TextWidth, theResult.first.m_TextHeight), - theTextureDims); - // We want a 2D lower left projection - QT3DSF32 *writePtr(theCamera.m_Projection.front()); - writePtr[12] = -1; - writePtr[13] = -1; - - // generate render stuff - // We dynamicall update the vertex buffer - QT3DSF32 tempBuf[20]; - QT3DSF32 *bufPtr = tempBuf; - QT3DSU32 bufSize = 20 * sizeof(QT3DSF32); // 4 vertices 3 pos 2 tex - NVDataRef vertData((QT3DSU8 *)bufPtr, bufSize); - mVertexBuffer = theContext.CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Dynamic, 20 * sizeof(QT3DSF32), - 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32), vertData); - QT3DSU32 strides = mVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - mInputAssembler = theContext.CreateInputAssembler( - mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), m_QuadIndexBuffer.mPtr, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - - NVRenderShaderProgram *theShader = GetTextAtlasEntryShader(); - STextShader theTextShader(*theShader); - - if (theShader) { - theContext.SetActiveShader(theShader); - theTextShader.m_MVP.Set(theCamera.m_Projection); - - // we are going through all entries and render to the FBO - for (QT3DSU32 i = 0; i < theResult.first.m_EntryCount; i++) { - STextTextureAtlasEntryDetails theDetails = - theTextRenderer.RenderAtlasEntry(i, *theTexture); - // update vbo - // we need to mirror coordinates - QT3DSF32 x1 = (QT3DSF32)theDetails.m_X; - QT3DSF32 x2 = (QT3DSF32)theDetails.m_X + theDetails.m_TextWidth; - QT3DSF32 y1 = (QT3DSF32)theDetails.m_Y; - QT3DSF32 y2 = (QT3DSF32)theDetails.m_Y + theDetails.m_TextHeight; - - QT3DSF32 box[4][5] = { - { x1, y1, 0, 0, 1 }, - { x1, y2, 0, 0, 0 }, - { x2, y2, 0, 1, 0 }, - { x2, y1, 0, 1, 1 }, - }; - - NVDataRef vertData((QT3DSU8 *)box, bufSize); - mVertexBuffer->UpdateBuffer(vertData, false); - - theTextShader.m_Sampler.Set(theTexture); - - theContext.SetInputAssembler(mInputAssembler); - theContext.Draw(NVRenderDrawMode::Triangles, m_QuadIndexBuffer->GetNumIndices(), - 0); - } - } - - m_qt3dsContext.GetResourceManager().Release(*theTexture); - m_qt3dsContext.GetResourceManager().Release(*theAtlasFB); - - return true; - } - - return theTextureAtlas->IsInitialized(); - } - - Option Qt3DSRendererImpl::GetLayerMouseCoords(SLayerRenderData &inLayerRenderData, - const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool forceImageIntersect) const - { - if (inLayerRenderData.m_LayerPrepResult.hasValue()) - return inLayerRenderData.m_LayerPrepResult->GetLayerMouseCoords( - inMouseCoords, inViewportDimensions, forceImageIntersect); - return Empty(); - } - - void Qt3DSRendererImpl::GetLayerHitObjectList(SLayerRenderData &inLayerRenderData, - const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inPresCoords, bool inPickEverything, - TPickResultArray &outIntersectionResult, - NVAllocatorCallback &inTempAllocator) - { - // This function assumes the layer was rendered to the scene itself. There is another - // function - // for completely offscreen layers that don't get rendered to the scene. - bool wasRenderToTarget(inLayerRenderData.m_Layer.m_Flags.IsLayerRenderToTarget()); - if (wasRenderToTarget && inLayerRenderData.m_Camera != NULL) { - Option theHitRay; - if (inLayerRenderData.m_LayerPrepResult.hasValue()) - theHitRay = inLayerRenderData.m_LayerPrepResult->GetPickRay( - inPresCoords, inViewportDimensions, false); - if (inLayerRenderData.m_LastFrameOffscreenRenderer.mPtr == NULL) { - if (theHitRay.hasValue()) { - // Scale the mouse coords to change them into the camera's numerical space. - SRay thePickRay = *theHitRay; - for (QT3DSU32 idx = inLayerRenderData.m_OpaqueObjects.size(), end = 0; idx > end; - --idx) { - SRenderableObject *theRenderableObject = - inLayerRenderData.m_OpaqueObjects[idx - 1]; - if (inPickEverything - || theRenderableObject->m_RenderableFlags.GetPickable()) - IntersectRayWithSubsetRenderable(thePickRay, *theRenderableObject, - outIntersectionResult, - inTempAllocator); - } - for (QT3DSU32 idx = inLayerRenderData.m_TransparentObjects.size(), end = 0; - idx > end; --idx) { - SRenderableObject *theRenderableObject = - inLayerRenderData.m_TransparentObjects[idx - 1]; - if (inPickEverything - || theRenderableObject->m_RenderableFlags.GetPickable()) - IntersectRayWithSubsetRenderable(thePickRay, *theRenderableObject, - outIntersectionResult, - inTempAllocator); - } - } - } else { - IGraphObjectPickQuery *theQuery = - inLayerRenderData.m_LastFrameOffscreenRenderer->GetGraphObjectPickQuery(this); - if (theQuery) { - Qt3DSRenderPickResult theResult = - theQuery->Pick(inPresCoords, inViewportDimensions, inPickEverything); - if (theResult.m_HitObject) { - theResult.m_OffscreenRenderer = - inLayerRenderData.m_LastFrameOffscreenRenderer; - outIntersectionResult.push_back(theResult); - } - } else - inLayerRenderData.m_LastFrameOffscreenRenderer->Pick(inPresCoords, - inViewportDimensions, - this); - } - } - } - - static inline Qt3DSRenderPickSubResult ConstructSubResult(SRenderableImage &inImage) - { - return ConstructSubResult(inImage.m_Image); - } - - void Qt3DSRendererImpl::IntersectRayWithSubsetRenderable( - const SRay &inRay, SRenderableObject &inRenderableObject, - TPickResultArray &outIntersectionResultList, NVAllocatorCallback &inTempAllocator) - { - Option theIntersectionResultOpt(inRay.IntersectWithAABB( - inRenderableObject.m_GlobalTransform, inRenderableObject.m_Bounds)); - if (theIntersectionResultOpt.hasValue() == false) - return; - SRayIntersectionResult &theResult(*theIntersectionResultOpt); - - // Leave the coordinates relative for right now. - const SGraphObject *thePickObject = NULL; - if (inRenderableObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - thePickObject = - &static_cast(&inRenderableObject)->m_ModelContext.m_Model; - else if (inRenderableObject.m_RenderableFlags.IsText()) - thePickObject = &static_cast(&inRenderableObject)->m_Text; - else if (inRenderableObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) - thePickObject = &static_cast(&inRenderableObject) - ->m_ModelContext.m_Model; - else if (inRenderableObject.m_RenderableFlags.IsPath()) - thePickObject = &static_cast(&inRenderableObject)->m_Path; - - if (thePickObject != NULL) { - outIntersectionResultList.push_back(Qt3DSRenderPickResult( - *thePickObject, theResult.m_RayLengthSquared, theResult.m_RelXY)); - - // For subsets, we know we can find images on them which may have been the result - // of rendering a sub-presentation. - if (inRenderableObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) { - Qt3DSRenderPickSubResult *theLastResult = NULL; - for (SRenderableImage *theImage = - static_cast(&inRenderableObject)->m_FirstImage; - theImage != NULL; theImage = theImage->m_NextImage) { - if (theImage->m_Image.m_LastFrameOffscreenRenderer != NULL - && theImage->m_Image.m_TextureData.m_Texture != NULL) { - Qt3DSRenderPickSubResult *theSubResult = - (Qt3DSRenderPickSubResult *)inTempAllocator.allocate( - sizeof(Qt3DSRenderPickSubResult), "Qt3DSRenderPickSubResult", - __FILE__, __LINE__); - - new (theSubResult) Qt3DSRenderPickSubResult(ConstructSubResult(*theImage)); - if (theLastResult == NULL) - outIntersectionResultList.back().m_FirstSubObject = theSubResult; - else - theLastResult->m_NextSibling = theSubResult; - theLastResult = theSubResult; - } - } - } - } - } - -#ifndef EA_PLATFORM_WINDOWS -#define _snprintf snprintf -#endif - - NVRenderShaderProgram *Qt3DSRendererImpl::CompileShader(CRegisteredString inName, - const char8_t *inVert, - const char8_t *inFrag) - { - GetProgramGenerator().BeginProgram(); - GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)->Append(inVert); - GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)->Append(inFrag); - return GetProgramGenerator().CompileGeneratedShader(inName); - } - - const QT3DSF32 MINATTENUATION = 0; - const QT3DSF32 MAXATTENUATION = 1000; - - QT3DSF32 ClampFloat(QT3DSF32 value, QT3DSF32 min, QT3DSF32 max) - { - return value < min ? min : ((value > max) ? max : value); - } - - QT3DSF32 TranslateConstantAttenuation(QT3DSF32 attenuation) { return attenuation * .01f; } - - QT3DSF32 TranslateLinearAttenuation(QT3DSF32 attenuation) - { - attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); - return attenuation * 0.0001f; - } - - QT3DSF32 TranslateQuadraticAttenuation(QT3DSF32 attenuation) - { - attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); - return attenuation * 0.0000001f; - } - - SShaderGeneratorGeneratedShader *Qt3DSRendererImpl::GetShader(SSubsetRenderable &inRenderable, - TShaderFeatureSet inFeatureSet) - { - if (m_CurrentLayer == NULL) { - QT3DS_ASSERT(false); - return NULL; - } - TShaderMap::iterator theFind = m_Shaders.find(inRenderable.m_ShaderDescription); - SShaderGeneratorGeneratedShader *retval = NULL; - if (theFind == m_Shaders.end()) { - // Generate the shader. - NVRenderShaderProgram *theShader(GenerateShader(inRenderable, inFeatureSet)); - if (theShader) { - SShaderGeneratorGeneratedShader *theGeneratedShader = - (SShaderGeneratorGeneratedShader *)m_Context->GetAllocator().allocate( - sizeof(SShaderGeneratorGeneratedShader), "SShaderGeneratorGeneratedShader", - __FILE__, __LINE__); - new (theGeneratedShader) SShaderGeneratorGeneratedShader( - m_StringTable->RegisterStr(m_GeneratedShaderString.c_str()), *theShader); - m_Shaders.insert(make_pair(inRenderable.m_ShaderDescription, theGeneratedShader)); - retval = theGeneratedShader; - } - // We still insert something because we don't to attempt to generate the same bad shader - // twice. - else - m_Shaders.insert(make_pair(inRenderable.m_ShaderDescription, - (SShaderGeneratorGeneratedShader *)NULL)); - } else - retval = theFind->second; - - if (retval != NULL) { - if (!m_LayerShaders.contains(*retval)) { - m_LayerShaders.insert(*retval); - } - if (m_CurrentLayer && m_CurrentLayer->m_Camera) { - SCamera &theCamera(*m_CurrentLayer->m_Camera); - if (m_CurrentLayer->m_CameraDirection.hasValue() == false) - m_CurrentLayer->m_CameraDirection = theCamera.GetScalingCorrectDirection(); - } - } - return retval; - } - static QT3DSVec3 g_fullScreenRectFace[] = { - QT3DSVec3(-1, -1, 0), QT3DSVec3(-1, 1, 0), QT3DSVec3(1, 1, 0), QT3DSVec3(1, -1, 0), - }; - - static QT3DSVec2 g_fullScreenRectUVs[] = { QT3DSVec2(0, 0), QT3DSVec2(0, 1), QT3DSVec2(1, 1), - QT3DSVec2(1, 0) }; - - void Qt3DSRendererImpl::GenerateXYQuad() - { - if (m_QuadInputAssembler) - return; - - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry("attr_uv", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), - }; - - QT3DSF32 tempBuf[20]; - QT3DSF32 *bufPtr = tempBuf; - QT3DSVec3 *facePtr(g_fullScreenRectFace); - QT3DSVec2 *uvPtr(g_fullScreenRectUVs); - for (int j = 0; j < 4; j++, ++facePtr, ++uvPtr, bufPtr += 5) { - bufPtr[0] = facePtr->x; - bufPtr[1] = facePtr->y; - bufPtr[2] = facePtr->z; - bufPtr[3] = uvPtr->x; - bufPtr[4] = uvPtr->y; - } - m_QuadVertexBuffer = m_Context->CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, 20 * sizeof(QT3DSF32), - 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32), toU8DataRef(tempBuf, 20)); - - QT3DSU8 indexData[] = { - 0, 1, 2, 0, 2, 3, - }; - m_QuadIndexBuffer = m_Context->CreateIndexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, qt3ds::render::NVRenderComponentTypes::QT3DSU8, - sizeof(indexData), toU8DataRef(indexData, sizeof(indexData))); - - // create our attribute layout - m_QuadAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); - - // create input assembler object - QT3DSU32 strides = m_QuadVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_QuadInputAssembler = m_Context->CreateInputAssembler( - m_QuadAttribLayout, toConstDataRef(&m_QuadVertexBuffer.mPtr, 1), m_QuadIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - - void Qt3DSRendererImpl::GenerateXYZPoint() - { - if (m_PointInputAssembler) - return; - - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry("attr_uv", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), - }; - - QT3DSF32 tempBuf[5]; - tempBuf[0] = tempBuf[1] = tempBuf[2] = 0.0; - tempBuf[3] = tempBuf[4] = 0.0; - - m_PointVertexBuffer = m_Context->CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, 5 * sizeof(QT3DSF32), - 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32), toU8DataRef(tempBuf, 5)); - - // create our attribute layout - m_PointAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); - - // create input assembler object - QT3DSU32 strides = m_PointVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_PointInputAssembler = m_Context->CreateInputAssembler( - m_PointAttribLayout, toConstDataRef(&m_PointVertexBuffer.mPtr, 1), NULL, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - - eastl::pair Qt3DSRendererImpl::GetXYQuad() - { - if (!m_QuadInputAssembler) - GenerateXYQuad(); - - return eastl::make_pair(m_QuadVertexBuffer.mPtr, m_QuadIndexBuffer.mPtr); - } - - SLayerGlobalRenderProperties Qt3DSRendererImpl::GetLayerGlobalRenderProperties() - { - SLayerRenderData &theData = *m_CurrentLayer; - SLayer &theLayer = theData.m_Layer; - if (theData.m_CameraDirection.hasValue() == false) - theData.m_CameraDirection = theData.m_Camera->GetScalingCorrectDirection(); - - return SLayerGlobalRenderProperties( - theLayer, *theData.m_Camera, *theData.m_CameraDirection, theData.m_Lights, - theData.m_LightDirections, theData.m_ShadowMapManager.mPtr, theData.m_LayerDepthTexture, - theData.m_LayerSsaoTexture, theLayer.m_LightProbe, theLayer.m_LightProbe2, - theLayer.m_ProbeHorizon, theLayer.m_ProbeBright, theLayer.m_Probe2Window, - theLayer.m_Probe2Pos, theLayer.m_Probe2Fade, theLayer.m_ProbeFov); - } - - void Qt3DSRendererImpl::GenerateXYQuadStrip() - { - if (m_QuadStripInputAssembler) - return; - - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry("attr_uv", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), - }; - - // this buffer is filled dynmically - m_QuadStripVertexBuffer = - m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Dynamic, 0, - 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32) // stride - , - NVDataRef()); - - // create our attribute layout - m_QuadStripAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); - - // create input assembler object - QT3DSU32 strides = m_QuadStripVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_QuadStripInputAssembler = m_Context->CreateInputAssembler( - m_QuadStripAttribLayout, toConstDataRef(&m_QuadStripVertexBuffer.mPtr, 1), NULL, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - - void Qt3DSRendererImpl::UpdateCbAoShadow(const SLayer *pLayer, const SCamera *pCamera, - CResourceTexture2D &inDepthTexture) - { - if (m_Context->GetConstantBufferSupport()) { - CRegisteredString theName = m_Context->GetStringTable().RegisterStr("cbAoShadow"); - NVRenderConstantBuffer *pCB = m_Context->GetConstantBuffer(theName); - - if (!pCB) { - // the size is determined automatically later on - pCB = m_Context->CreateConstantBuffer( - theName, qt3ds::render::NVRenderBufferUsageType::Static, 0, NVDataRef()); - if (!pCB) { - QT3DS_ASSERT(false); - return; - } - m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); - - // Add paramters. Note should match the appearance in the shader program - pCB->AddParam(m_Context->GetStringTable().RegisterStr("ao_properties"), - qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); - pCB->AddParam(m_Context->GetStringTable().RegisterStr("ao_properties2"), - qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); - pCB->AddParam(m_Context->GetStringTable().RegisterStr("shadow_properties"), - qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); - pCB->AddParam(m_Context->GetStringTable().RegisterStr("aoScreenConst"), - qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); - pCB->AddParam(m_Context->GetStringTable().RegisterStr("UvToEyeConst"), - qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); - } - - // update values - QT3DSVec4 aoProps(pLayer->m_AoStrength * 0.01f, pLayer->m_AoDistance * 0.4f, - pLayer->m_AoSoftness * 0.02f, pLayer->m_AoBias); - pCB->UpdateParam("ao_properties", NVDataRef((QT3DSU8 *)&aoProps, 1)); - QT3DSVec4 aoProps2((QT3DSF32)pLayer->m_AoSamplerate, (pLayer->m_AoDither) ? 1.0f : 0.0f, 0.0f, - 0.0f); - pCB->UpdateParam("ao_properties2", NVDataRef((QT3DSU8 *)&aoProps2, 1)); - QT3DSVec4 shadowProps(pLayer->m_ShadowStrength * 0.01f, pLayer->m_ShadowDist, - pLayer->m_ShadowSoftness * 0.01f, pLayer->m_ShadowBias); - pCB->UpdateParam("shadow_properties", NVDataRef((QT3DSU8 *)&shadowProps, 1)); - - QT3DSF32 R2 = pLayer->m_AoDistance * pLayer->m_AoDistance * 0.16f; - QT3DSF32 rw = 100, rh = 100; - - if (inDepthTexture && inDepthTexture.GetTexture()) { - rw = (QT3DSF32)inDepthTexture.GetTexture()->GetTextureDetails().m_Width; - rh = (QT3DSF32)inDepthTexture.GetTexture()->GetTextureDetails().m_Height; - } - QT3DSF32 fov = (pCamera) ? pCamera->verticalFov(rw / rh) : 1.0f; - QT3DSF32 tanHalfFovY = tanf(0.5f * fov * (rh / rw)); - QT3DSF32 invFocalLenX = tanHalfFovY * (rw / rh); - - QT3DSVec4 aoScreenConst(1.0f / R2, rh / (2.0f * tanHalfFovY), 1.0f / rw, 1.0f / rh); - pCB->UpdateParam("aoScreenConst", NVDataRef((QT3DSU8 *)&aoScreenConst, 1)); - QT3DSVec4 UvToEyeConst(2.0f * invFocalLenX, -2.0f * tanHalfFovY, -invFocalLenX, - tanHalfFovY); - pCB->UpdateParam("UvToEyeConst", NVDataRef((QT3DSU8 *)&UvToEyeConst, 1)); - - // update buffer to hardware - pCB->Update(); - } - } - - // widget context implementation - - NVRenderVertexBuffer &Qt3DSRendererImpl::GetOrCreateVertexBuffer(CRegisteredString &inStr, - QT3DSU32 stride, - NVConstDataRef bufferData) - { - NVRenderVertexBuffer *retval = GetVertexBuffer(inStr); - if (retval) { - // we update the buffer - retval->UpdateBuffer(bufferData, false); - return *retval; - } - retval = m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Dynamic, - bufferData.size(), stride, bufferData); - m_WidgetVertexBuffers.insert(eastl::make_pair(inStr, retval)); - return *retval; - } - NVRenderIndexBuffer & - Qt3DSRendererImpl::GetOrCreateIndexBuffer(CRegisteredString &inStr, - qt3ds::render::NVRenderComponentTypes::Enum componentType, - size_t size, NVConstDataRef bufferData) - { - NVRenderIndexBuffer *retval = GetIndexBuffer(inStr); - if (retval) { - // we update the buffer - retval->UpdateBuffer(bufferData, false); - return *retval; - } - - retval = m_Context->CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Dynamic, - componentType, size, bufferData); - m_WidgetIndexBuffers.insert(eastl::make_pair(inStr, retval)); - return *retval; - } - - NVRenderAttribLayout &Qt3DSRendererImpl::CreateAttributeLayout( - NVConstDataRef attribs) - { - // create our attribute layout - NVRenderAttribLayout *theAttribLAyout = m_Context->CreateAttributeLayout(attribs); - return *theAttribLAyout; - } - - NVRenderInputAssembler &Qt3DSRendererImpl::GetOrCreateInputAssembler( - CRegisteredString &inStr, NVRenderAttribLayout *attribLayout, - NVConstDataRef buffers, const NVRenderIndexBuffer *indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets) - { - NVRenderInputAssembler *retval = GetInputAssembler(inStr); - if (retval) - return *retval; - - retval = - m_Context->CreateInputAssembler(attribLayout, buffers, indexBuffer, strides, offsets); - m_WidgetInputAssembler.insert(eastl::make_pair(inStr, retval)); - return *retval; - } - - NVRenderVertexBuffer *Qt3DSRendererImpl::GetVertexBuffer(CRegisteredString &inStr) - { - TStrVertBufMap::iterator theIter = m_WidgetVertexBuffers.find(inStr); - if (theIter != m_WidgetVertexBuffers.end()) - return theIter->second; - return NULL; - } - - NVRenderIndexBuffer *Qt3DSRendererImpl::GetIndexBuffer(CRegisteredString &inStr) - { - TStrIndexBufMap::iterator theIter = m_WidgetIndexBuffers.find(inStr); - if (theIter != m_WidgetIndexBuffers.end()) - return theIter->second; - return NULL; - } - - NVRenderInputAssembler *Qt3DSRendererImpl::GetInputAssembler(CRegisteredString &inStr) - { - TStrIAMap::iterator theIter = m_WidgetInputAssembler.find(inStr); - if (theIter != m_WidgetInputAssembler.end()) - return theIter->second; - return NULL; - } - - NVRenderShaderProgram *Qt3DSRendererImpl::GetShader(CRegisteredString inStr) - { - TStrShaderMap::iterator theIter = m_WidgetShaders.find(inStr); - if (theIter != m_WidgetShaders.end()) - return theIter->second; - return NULL; - } - - NVRenderShaderProgram *Qt3DSRendererImpl::CompileAndStoreShader(CRegisteredString inStr) - { - NVRenderShaderProgram *newProgram = GetProgramGenerator().CompileGeneratedShader(inStr); - if (newProgram) - m_WidgetShaders.insert(eastl::make_pair(inStr, newProgram)); - return newProgram; - } - - IShaderProgramGenerator &Qt3DSRendererImpl::GetProgramGenerator() - { - return m_qt3dsContext.GetShaderProgramGenerator(); - } - - STextDimensions Qt3DSRendererImpl::MeasureText(const STextRenderInfo &inText) - { - if (m_qt3dsContext.GetTextRenderer() != NULL) - return m_qt3dsContext.GetTextRenderer()->MeasureText(inText, 0); - return STextDimensions(); - } - - void Qt3DSRendererImpl::RenderText(const STextRenderInfo &inText, const QT3DSVec3 &inTextColor, - const QT3DSVec3 &inBackgroundColor, const QT3DSMat44 &inMVP) - { - if (m_qt3dsContext.GetTextRenderer() != NULL) { - ITextRenderer &theTextRenderer(*m_qt3dsContext.GetTextRenderer()); - NVRenderTexture2D *theTexture = m_qt3dsContext.GetResourceManager().AllocateTexture2D( - 32, 32, NVRenderTextureFormats::RGBA8); - STextTextureDetails theTextTextureDetails = - theTextRenderer.RenderText(inText, *theTexture); - STextRenderHelper theTextHelper(GetTextWidgetShader()); - if (theTextHelper.m_Shader != NULL) { - m_qt3dsContext.GetRenderContext().SetBlendingEnabled(false); - STextScaleAndOffset theScaleAndOffset(*theTexture, theTextTextureDetails, inText); - theTextHelper.m_Shader->Render(*theTexture, theScaleAndOffset, - QT3DSVec4(inTextColor, 1.0f), inMVP, QT3DSVec2(0, 0), - GetContext(), theTextHelper.m_QuadInputAssembler, - theTextHelper.m_QuadInputAssembler.GetIndexCount(), - theTextTextureDetails, inBackgroundColor); - } - m_qt3dsContext.GetResourceManager().Release(*theTexture); - } - } - - void Qt3DSRendererImpl::RenderText2D(QT3DSF32 x, QT3DSF32 y, - qt3ds::foundation::Option inColor, - const char *text) - { - if (m_qt3dsContext.GetOnscreenTextRenderer() != NULL) { - GenerateXYQuadStrip(); - - if (PrepareTextureAtlasForRender()) { - TTextRenderAtlasDetailsAndTexture theRenderTextDetails; - ITextTextureAtlas *theTextureAtlas = m_qt3dsContext.GetTextureAtlas(); - QSize theWindow = m_qt3dsContext.GetWindowDimensions(); - - const wchar_t *wText = m_StringTable->GetWideStr(text); - STextRenderInfo theInfo; - theInfo.m_Text = m_StringTable->RegisterStr(wText); - theInfo.m_FontSize = 20; - // text scale 2% of screen we don't scale Y though because it becomes unreadable - theInfo.m_ScaleX = (theWindow.width() / 100.0f) * 1.5f / (theInfo.m_FontSize); - theInfo.m_ScaleY = 1.0f; - - theRenderTextDetails = theTextureAtlas->RenderText(theInfo); - - if (theRenderTextDetails.first.m_Vertices.size()) { - STextRenderHelper theTextHelper(GetOnscreenTextShader()); - if (theTextHelper.m_Shader != NULL) { - // setup 2D projection - SCamera theCamera; - theCamera.m_ClipNear = -1.0; - theCamera.m_ClipFar = 1.0; - - theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - theCamera.m_Flags.SetOrthographic(true); - QT3DSVec2 theWindowDim((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()); - theCamera.CalculateGlobalVariables( - NVRenderRect(0, 0, theWindow.width(), theWindow.height()), - theWindowDim); - // We want a 2D lower left projection - QT3DSF32 *writePtr(theCamera.m_Projection.front()); - writePtr[12] = -1; - writePtr[13] = -1; - - // upload vertices - m_QuadStripVertexBuffer->UpdateBuffer(theRenderTextDetails.first.m_Vertices, - false); - - theTextHelper.m_Shader->Render2D( - *theRenderTextDetails.second, QT3DSVec4(inColor, 1.0f), - theCamera.m_Projection, GetContext(), - theTextHelper.m_QuadInputAssembler, - theRenderTextDetails.first.m_VertexCount, QT3DSVec2(x, y)); - } - // we release the memory here - QT3DS_FREE(m_Context->GetAllocator(), - theRenderTextDetails.first.m_Vertices.begin()); - } - } - } - } - - void Qt3DSRendererImpl::RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, - qt3ds::foundation::Option inColor) - { - if (!IsLayerGpuProfilingEnabled()) - return; - - char messageLine[1024]; - TInstanceRenderMap::const_iterator theIter; - - QT3DSF32 startY = y; - - for (theIter = m_InstanceRenderMap.begin(); theIter != m_InstanceRenderMap.end(); theIter++) { - QT3DSF32 startX = x; - const SLayerRenderData *theLayerRenderData = theIter->second; - const SLayer *theLayer = &theLayerRenderData->m_Layer; - - if (theLayer->m_Flags.IsActive() && theLayerRenderData->m_LayerProfilerGpu.mPtr) { - const IRenderProfiler::TStrIDVec &idList = - theLayerRenderData->m_LayerProfilerGpu->GetTimerIDs(); - if (!idList.empty()) { - startY -= 22; - startX += 20; - RenderText2D(startX, startY, inColor, theLayer->m_Id); - IRenderProfiler::TStrIDVec::const_iterator theIdIter = idList.begin(); - for (theIdIter = idList.begin(); theIdIter != idList.end(); theIdIter++) { - startY -= 22; - sprintf(messageLine, "%s: %.3f ms", theIdIter->c_str(), - theLayerRenderData->m_LayerProfilerGpu->GetElapsedTime(*theIdIter)); - RenderText2D(startX + 20, startY, inColor, messageLine); - } - } - } - } - } - - // Given a node and a point in the node's local space (most likely its pivot point), we return - // a normal matrix so you can get the axis out, a transformation from node to camera - // a new position and a floating point scale factor so you can render in 1/2 perspective mode - // or orthographic mode if you would like to. - SWidgetRenderInformation - Qt3DSRendererImpl::GetWidgetRenderInformation(SNode &inNode, const QT3DSVec3 &inPos, - RenderWidgetModes::Enum inWidgetMode) - { - SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inNode); - SCamera *theCamera = theData->m_Camera; - if (theCamera == NULL || theData->m_LayerPrepResult.hasValue() == false) { - QT3DS_ASSERT(false); - return SWidgetRenderInformation(); - } - QT3DSMat44 theGlobalTransform(QT3DSMat44::createIdentity()); - if (inNode.m_Parent != NULL && inNode.m_Parent->m_Type != GraphObjectTypes::Layer - && !inNode.m_Flags.IsIgnoreParentTransform()) - theGlobalTransform = inNode.m_Parent->m_GlobalTransform; - QT3DSMat44 theCameraInverse(theCamera->m_GlobalTransform.getInverse()); - QT3DSMat44 theNodeParentToCamera; - if (inWidgetMode == RenderWidgetModes::Local) - theNodeParentToCamera = theCameraInverse * theGlobalTransform; - else - theNodeParentToCamera = theCameraInverse; - - QT3DSMat33 theNormalMat(theNodeParentToCamera.column0.getXYZ(), - theNodeParentToCamera.column1.getXYZ(), - theNodeParentToCamera.column2.getXYZ()); - theNormalMat = theNormalMat.getInverse().getTranspose(); - theNormalMat.column0.normalize(); - theNormalMat.column1.normalize(); - theNormalMat.column2.normalize(); - - QT3DSMat44 theTranslation(QT3DSMat44::createIdentity()); - theTranslation.column3.x = inNode.m_Position.x; - theTranslation.column3.y = inNode.m_Position.y; - theTranslation.column3.z = inNode.m_Position.z; - theTranslation.column3.z *= -1.0f; - - theGlobalTransform = theGlobalTransform * theTranslation; - - QT3DSMat44 theNodeToParentPlusTranslation = theCameraInverse * theGlobalTransform; - QT3DSVec3 thePos = theNodeToParentPlusTranslation.transform(inPos); - SScaleAndPosition theScaleAndPos = GetWorldToPixelScaleFactor(*theCamera, thePos, *theData); - QT3DSMat33 theLookAtMatrix(QT3DSMat33::createIdentity()); - if (theCamera->m_Flags.IsOrthographic() == false) { - QT3DSVec3 theNodeToCamera = theScaleAndPos.m_Position; - theNodeToCamera.normalize(); - QT3DSVec3 theOriginalAxis = QT3DSVec3(0, 0, -1); - QT3DSVec3 theRotAxis = theOriginalAxis.cross(theNodeToCamera); - QT3DSF32 theAxisLen = theRotAxis.normalize(); - if (theAxisLen > .05f) { - QT3DSF32 theRotAmount = acos(theOriginalAxis.dot(theNodeToCamera)); - QT3DSQuat theQuat(theRotAmount, theRotAxis); - theLookAtMatrix = QT3DSMat33(theQuat); - } - } - QT3DSVec3 thePosInWorldSpace = theGlobalTransform.transform(inPos); - QT3DSVec3 theCameraPosInWorldSpace = theCamera->GetGlobalPos(); - QT3DSVec3 theCameraOffset = thePosInWorldSpace - theCameraPosInWorldSpace; - QT3DSVec3 theDir = theCameraOffset; - theDir.normalize(); - // Things should be 600 units from the camera, as that is how all of our math is setup. - theCameraOffset = 600.0f * theDir; - return SWidgetRenderInformation( - theNormalMat, theNodeParentToCamera, theCamera->m_Projection, theCamera->m_Projection, - theLookAtMatrix, theCameraInverse, theCameraOffset, theScaleAndPos.m_Position, - theScaleAndPos.m_Scale, *theCamera); - } - - Option Qt3DSRendererImpl::GetLayerMouseCoords(SLayer &inLayer, - const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool forceImageIntersect) const - { - SLayerRenderData *theData = - const_cast(*this).GetOrCreateLayerRenderDataForNode(inLayer); - return GetLayerMouseCoords(*theData, inMouseCoords, inViewportDimensions, - forceImageIntersect); - } - - bool IQt3DSRenderer::IsGlEsContext(qt3ds::render::NVRenderContextType inContextType) - { - qt3ds::render::NVRenderContextType esContextTypes(NVRenderContextValues::GLES2 - | NVRenderContextValues::GLES3 - | NVRenderContextValues::GLES3PLUS); - - if ((inContextType & esContextTypes)) - return true; - - return false; - } - - bool IQt3DSRenderer::IsGlEs3Context(qt3ds::render::NVRenderContextType inContextType) - { - if (inContextType == NVRenderContextValues::GLES3 - || inContextType == NVRenderContextValues::GLES3PLUS) - return true; - - return false; - } - - bool IQt3DSRenderer::IsGl2Context(qt3ds::render::NVRenderContextType inContextType) - { - if (inContextType == NVRenderContextValues::GL2) - return true; - - return false; - } - - IQt3DSRenderer &IQt3DSRenderer::CreateRenderer(IQt3DSRenderContext &inContext) - { - return *QT3DS_NEW(inContext.GetAllocator(), Qt3DSRendererImpl)(inContext); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.h deleted file mode 100644 index 686e7d3b..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImpl.h +++ /dev/null @@ -1,552 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_SHADER_GENERATOR_IMPL_H -#define QT3DS_RENDER_SHADER_GENERATOR_IMPL_H -#include "Qt3DSRender.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRenderableObjects.h" -#include "Qt3DSRendererImplShaders.h" -#include "Qt3DSRendererImplLayerRenderData.h" -#include "foundation/Qt3DSFlags.h" -#include "Qt3DSRenderMesh.h" -#include "Qt3DSRenderModel.h" -#include "foundation/Qt3DSBounds3.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSInvasiveSet.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSDataRef.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderRay.h" -#include "Qt3DSRenderText.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSRendererImplLayerRenderHelper.h" -#include "Qt3DSRenderWidgets.h" -#include "Qt3DSRenderShaderCodeGenerator.h" -#include "Qt3DSRenderClippingFrustum.h" -#include "foundation/Qt3DSUnionCast.h" -#include "foundation/FastAllocator.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSRenderShaderKeys.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderProfiler.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" - -namespace qt3ds { -namespace render { - - inline bool FloatLessThan(QT3DSF32 lhs, QT3DSF32 rhs) - { - QT3DSF32 diff = lhs - rhs; - if (fabs(diff) < .001) - return false; - return diff < 0.0f ? true : false; - } - inline bool ISRenderObjectPtrLessThan(const SRenderableObject *lhs, - const SRenderableObject *rhs) - { - return FloatLessThan(lhs->m_CameraDistanceSq, rhs->m_CameraDistanceSq); - } - inline bool ISRenderObjectPtrGreatThan(const SRenderableObject *lhs, - const SRenderableObject *rhs) - { - return FloatLessThan(rhs->m_CameraDistanceSq, lhs->m_CameraDistanceSq); - } - inline bool NonZero(float inValue) { return fabs(inValue) > .001f; } - inline bool NonZero(QT3DSU32 inValue) { return inValue != 0; } - inline bool IsZero(float inValue) { return fabs(inValue) < .001f; } - inline bool IsNotOne(float inValue) { return fabs(1.0f - inValue) > .001f; } - - inline bool IsRectEdgeInBounds(QT3DSI32 inNewRectOffset, QT3DSI32 inNewRectWidth, - QT3DSI32 inCurrentRectOffset, QT3DSI32 inCurrentRectWidth) - { - QT3DSI32 newEnd = inNewRectOffset + inNewRectWidth; - QT3DSI32 currentEnd = inCurrentRectOffset + inCurrentRectWidth; - return inNewRectOffset >= inCurrentRectOffset && newEnd <= currentEnd; - } - - struct STextRenderHelper - { - STextShader *m_Shader; - NVRenderInputAssembler &m_QuadInputAssembler; - STextRenderHelper(STextShader *inShader, NVRenderInputAssembler &inQuadInputAssembler) - : m_Shader(inShader) - , m_QuadInputAssembler(inQuadInputAssembler) - { - } - }; - - struct SPickResultProcessResult : public Qt3DSRenderPickResult - { - SPickResultProcessResult(const Qt3DSRenderPickResult &inSrc) - : Qt3DSRenderPickResult(inSrc) - , m_WasPickConsumed(false) - { - } - SPickResultProcessResult() - : m_WasPickConsumed(false) - { - } - bool m_WasPickConsumed; - }; - - struct STextShaderPtr - { - NVAllocatorCallback &m_Allocator; - bool m_HasGeneratedShader; - STextShader *m_Shader; - STextShaderPtr(NVAllocatorCallback &alloc) - : m_Allocator(alloc) - , m_HasGeneratedShader(false) - , m_Shader(NULL) - { - } - bool HasGeneratedShader() { return m_HasGeneratedShader; } - void Set(STextShader *inShader) - { - m_Shader = inShader; - m_HasGeneratedShader = true; - } - ~STextShaderPtr() - { - if (m_Shader) - NVDelete(m_Allocator, m_Shader); - } - operator STextShader *() { return m_Shader; } - }; - - class QT3DS_AUTOTEST_EXPORT Qt3DSRendererImpl : public IQt3DSRenderer, public IRenderWidgetContext - { - typedef nvhash_map TShaderMap; - typedef nvhash_map> - TStrConstanBufMap; - typedef nvhash_map, - eastl::hash> TInstanceRenderMap; - typedef nvvector TLayerRenderList; - typedef nvvector TPickResultArray; - - // Items to implement the widget context. - typedef nvhash_map> - TStrVertBufMap; - typedef nvhash_map> - TStrIndexBufMap; - typedef nvhash_map> - TStrShaderMap; - typedef nvhash_map> TStrIAMap; - - typedef nvhash_map TBoneIdNodeMap; - - IQt3DSRenderContext &m_qt3dsContext; - NVScopedRefCounted m_Context; - NVScopedRefCounted m_BufferManager; - NVScopedRefCounted m_OffscreenRenderManager; - NVScopedRefCounted m_StringTable; - InvasiveSet m_LayerShaders; - // For rendering bounding boxes. - NVScopedRefCounted m_BoxVertexBuffer; - NVScopedRefCounted m_BoxIndexBuffer; - NVScopedRefCounted m_BoxShader; - NVScopedRefCounted m_ScreenRectShader; - - NVScopedRefCounted m_AxisVertexBuffer; - NVScopedRefCounted m_AxisShader; - - // X,Y quad, broken down into 2 triangles and normalized over - //-1,1. - NVScopedRefCounted m_QuadVertexBuffer; - NVScopedRefCounted m_QuadIndexBuffer; - NVScopedRefCounted m_RectIndexBuffer; - NVScopedRefCounted m_QuadInputAssembler; - NVScopedRefCounted m_RectInputAssembler; - NVScopedRefCounted m_QuadAttribLayout; - NVScopedRefCounted m_RectAttribLayout; - - // X,Y triangle strip quads in screen coord dynamiclly setup - NVScopedRefCounted m_QuadStripVertexBuffer; - NVScopedRefCounted m_QuadStripInputAssembler; - NVScopedRefCounted m_QuadStripAttribLayout; - - // X,Y,Z point which is used for instanced based rendering of points - NVScopedRefCounted m_PointVertexBuffer; - NVScopedRefCounted m_PointInputAssembler; - NVScopedRefCounted m_PointAttribLayout; - - Option> m_SceneLayerShader; - Option> m_LayerProgAAShader; - - TShaderMap m_Shaders; - TStrConstanBufMap m_ConstantBuffers; ///< store the the shader constant buffers - // Option is true if we have attempted to generate the shader. - // This does not mean we were successul, however. - Option> - m_DefaultMaterialDepthPrepassShader; - Option> m_DepthPrepassShader; - Option> m_DepthPrepassShaderDisplaced; - Option> m_DepthTessLinearPrepassShader; - Option> - m_DepthTessLinearPrepassShaderDisplaced; - Option> m_DepthTessPhongPrepassShader; - Option> m_DepthTessNPatchPrepassShader; - Option> m_TextDepthPrepassShader; - Option> m_DefaultAoPassShader; - Option> m_FakeDepthShader; - Option> m_FakeCubemapDepthShader; - Option> m_ParaboloidDepthShader; - Option> m_ParaboloidDepthTessLinearShader; - Option> m_ParaboloidDepthTessPhongShader; - Option> m_ParaboloidDepthTessNPatchShader; - Option> m_CubemapDepthShader; - Option> m_CubemapDepthTessLinearShader; - Option> m_CubemapDepthTessPhongShader; - Option> m_CubemapDepthTessNPatchShader; - Option> m_OrthographicDepthShader; - Option> - m_OrthographicDepthTessLinearShader; - Option> - m_OrthographicDepthTessPhongShader; - Option> - m_OrthographicDepthTessNPatchShader; - Option> m_CubeShadowBlurXShader; - Option> m_CubeShadowBlurYShader; - Option> m_OrthoShadowBlurXShader; - Option> m_OrthoShadowBlurYShader; - -#ifdef ADVANCED_BLEND_SW_FALLBACK - Option> m_AdvancedModeOverlayBlendShader; - Option> m_AdvancedModeColorBurnBlendShader; - Option> m_AdvancedModeColorDodgeBlendShader; -#endif - // Text shaders may be generated on demand. - STextShaderPtr m_TextShader; - STextShaderPtr m_TextPathShader; - STextShaderPtr m_TextWidgetShader; - STextShaderPtr m_TextOnscreenShader; - - // Overlay used to render all widgets. - NVRenderRect m_BeginFrameViewport; - NVScopedRefCounted m_WidgetTexture; - NVScopedRefCounted m_WidgetFBO; - -#ifdef ADVANCED_BLEND_SW_FALLBACK - // Advanced blend mode SW fallback - CResourceTexture2D m_LayerBlendTexture; - NVScopedRefCounted m_BlendFB; -#endif - // Allocator for temporary data that is cleared after every layer. - TInstanceRenderMap m_InstanceRenderMap; - TLayerRenderList m_LastFrameLayers; - volatile QT3DSI32 mRefCount; - - // Set from the first layer. - TPickResultArray m_LastPickResults; - - // Temporary information stored only when rendering a particular layer. - SLayerRenderData *m_CurrentLayer; - QT3DSMat44 m_ViewProjection; - eastl::string m_GeneratedShaderString; - - TStrVertBufMap m_WidgetVertexBuffers; - TStrIndexBufMap m_WidgetIndexBuffers; - TStrShaderMap m_WidgetShaders; - TStrIAMap m_WidgetInputAssembler; - - TBoneIdNodeMap m_BoneIdNodeMap; - - bool m_PickRenderPlugins; - bool m_LayerCachingEnabled; - bool m_LayerGPuProfilingEnabled; - SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; - - public: - Qt3DSRendererImpl(IQt3DSRenderContext &ctx); - virtual ~Qt3DSRendererImpl(); - SShaderDefaultMaterialKeyProperties &DefaultMaterialShaderKeyProperties() - { - return m_DefaultMaterialShaderKeyProperties; - } - - // NVRefCounted - void addRef() override; - void release() override; - - void EnableLayerCaching(bool inEnabled) override { m_LayerCachingEnabled = inEnabled; } - bool IsLayerCachingEnabled() const override { return m_LayerCachingEnabled; } - - void EnableLayerGpuProfiling(bool inEnabled) override - { - m_LayerGPuProfilingEnabled = inEnabled; - } - bool IsLayerGpuProfilingEnabled() const override { return m_LayerGPuProfilingEnabled; } - - // Calls prepare layer for render - // and then do render layer. - bool PrepareLayerForRender(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - bool inRenderSiblings, const SRenderInstanceId id) override; - void RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - bool clear, QT3DSVec3 clearColor, bool inRenderSiblings, - const SRenderInstanceId id) override; - void ChildrenUpdated(SNode &inParent) override; - QT3DSF32 GetTextScale(const SText &inText) override; - - SCamera *GetCameraForNode(const SNode &inNode) const override; - Option GetCameraBounds(const SGraphObject &inObject) override; - virtual SLayer *GetLayerForNode(const SNode &inNode) const; - SLayerRenderData *GetOrCreateLayerRenderDataForNode(const SNode &inNode, - const SRenderInstanceId id = nullptr); - - IRenderWidgetContext &GetRenderWidgetContext() - { - return *this; - } - - void BeginFrame() override; - void EndFrame() override; - - void PickRenderPlugins(bool inPick) override { m_PickRenderPlugins = inPick; } - Qt3DSRenderPickResult Pick(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, bool inPickSiblings, - bool inPickEverything, - const SRenderInstanceId id) override; - - virtual Option - FacePosition(SNode &inNode, NVBounds3 inBounds, const QT3DSMat44 &inGlobalTransform, - const QT3DSVec2 &inViewportDimensions, const QT3DSVec2 &inMouseCoords, - NVDataRef inMapperObjects, SBasisPlanes::Enum inPlane) override; - - virtual Qt3DSRenderPickResult PickOffscreenLayer(SLayer &inLayer, - const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, - bool inPickEverything); - - QT3DSVec3 UnprojectToPosition(SNode &inNode, QT3DSVec3 &inPosition, - const QT3DSVec2 &inMouseVec) const override; - QT3DSVec3 UnprojectWithDepth(SNode &inNode, QT3DSVec3 &inPosition, - const QT3DSVec3 &inMouseVec) const override; - QT3DSVec3 ProjectPosition(SNode &inNode, const QT3DSVec3 &inPosition) const override; - - Option GetLayerPickSetup(SLayer &inLayer, - const QT3DSVec2 &inMouseCoords, - const QSize &inPickDims) override; - - Option GetLayerRect(SLayer &inLayer) override; - - void RunLayerRender(SLayer &inLayer, const QT3DSMat44 &inViewProjection) override; - - // Note that this allocator is completely reset on BeginFrame. - NVAllocatorCallback &GetPerFrameAllocator() override - { - return m_qt3dsContext.GetPerFrameAllocator(); - } - void RenderLayerRect(SLayer &inLayer, const QT3DSVec3 &inColor) override; - void AddRenderWidget(IRenderWidget &inWidget) override; - - SScaleAndPosition GetWorldToPixelScaleFactor(SLayer &inLayer, - const QT3DSVec3 &inWorldPoint) override; - SScaleAndPosition GetWorldToPixelScaleFactor(const SCamera &inCamera, - const QT3DSVec3 &inWorldPoint, - SLayerRenderData &inRenderData); - - void ReleaseLayerRenderResources(SLayer &inLayer, const SRenderInstanceId id) override; - - void RenderQuad(const QT3DSVec2 inDimensions, const QT3DSMat44 &inMVP, - NVRenderTexture2D &inQuadTexture) override; - void RenderQuad() override; - - void RenderPointsIndirect() override; - - // render a screen aligned 2D text - void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, - const char *text) override; - bool PrepareTextureAtlasForRender(); - - // render Gpu profiler values - void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, - qt3ds::foundation::Option inColor) override; - - // Callback during the layer render process. - void LayerNeedsFrameClear(SLayerRenderData &inLayer); - void BeginLayerDepthPassRender(SLayerRenderData &inLayer); - void EndLayerDepthPassRender(); - void BeginLayerRender(SLayerRenderData &inLayer); - void EndLayerRender(); - void PrepareImageForIbl(SImage &inImage); - - NVRenderShaderProgram *CompileShader(CRegisteredString inName, const char8_t *inVert, - const char8_t *inFrame); - - NVRenderShaderProgram *GenerateShader(SSubsetRenderable &inRenderable, - TShaderFeatureSet inFeatureSet); - SShaderGeneratorGeneratedShader *GetShader(SSubsetRenderable &inRenderable, - TShaderFeatureSet inFeatureSet); - - SDefaultAoPassShader *GetDefaultAoPassShader(TShaderFeatureSet inFeatureSet); - SDefaultAoPassShader *GetFakeDepthShader(TShaderFeatureSet inFeatureSet); - SDefaultAoPassShader *GetFakeCubeDepthShader(TShaderFeatureSet inFeatureSet); - SDefaultMaterialRenderableDepthShader *GetRenderableDepthShader(); - - SRenderableDepthPrepassShader *GetParaboloidDepthShader(TessModeValues::Enum inTessMode); - SRenderableDepthPrepassShader *GetParaboloidDepthNoTessShader(); - SRenderableDepthPrepassShader *GetParaboloidDepthTessLinearShader(); - SRenderableDepthPrepassShader *GetParaboloidDepthTessPhongShader(); - SRenderableDepthPrepassShader *GetParaboloidDepthTessNPatchShader(); - SRenderableDepthPrepassShader *GetCubeShadowDepthShader(TessModeValues::Enum inTessMode); - SRenderableDepthPrepassShader *GetCubeDepthNoTessShader(); - SRenderableDepthPrepassShader *GetCubeDepthTessLinearShader(); - SRenderableDepthPrepassShader *GetCubeDepthTessPhongShader(); - SRenderableDepthPrepassShader *GetCubeDepthTessNPatchShader(); - SRenderableDepthPrepassShader *GetOrthographicDepthShader(TessModeValues::Enum inTessMode); - SRenderableDepthPrepassShader *GetOrthographicDepthNoTessShader(); - SRenderableDepthPrepassShader *GetOrthographicDepthTessLinearShader(); - SRenderableDepthPrepassShader *GetOrthographicDepthTessPhongShader(); - SRenderableDepthPrepassShader *GetOrthographicDepthTessNPatchShader(); - - SRenderableDepthPrepassShader *GetDepthPrepassShader(bool inDisplaced); - SRenderableDepthPrepassShader *GetDepthTessPrepassShader(TessModeValues::Enum inTessMode, - bool inDisplaced); - SRenderableDepthPrepassShader *GetDepthTessLinearPrepassShader(bool inDisplaced); - SRenderableDepthPrepassShader *GetDepthTessPhongPrepassShader(); - SRenderableDepthPrepassShader *GetDepthTessNPatchPrepassShader(); - STextDepthShader *GetTextDepthShader(); - STextRenderHelper GetShader(STextRenderable &inRenderable, bool inUsePathRendering); - STextRenderHelper GetTextShader(bool inUsePathRendering); - STextRenderHelper GetTextWidgetShader(); - STextRenderHelper GetOnscreenTextShader(); - SLayerSceneShader *GetSceneLayerShader(); - NVRenderShaderProgram *GetTextAtlasEntryShader(); - void GenerateXYQuad(); - void GenerateXYQuadStrip(); - void GenerateXYZPoint(); - eastl::pair GetXYQuad(); - SLayerProgAABlendShader *GetLayerProgAABlendShader(); - SShadowmapPreblurShader *GetCubeShadowBlurXShader(); - SShadowmapPreblurShader *GetCubeShadowBlurYShader(); - SShadowmapPreblurShader *GetOrthoShadowBlurXShader(); - SShadowmapPreblurShader *GetOrthoShadowBlurYShader(); - -#ifdef ADVANCED_BLEND_SW_FALLBACK - SAdvancedModeBlendShader *GetAdvancedBlendModeShader(AdvancedBlendModes::Enum blendMode); - SAdvancedModeBlendShader *GetOverlayBlendModeShader(); - SAdvancedModeBlendShader *GetColorBurnBlendModeShader(); - SAdvancedModeBlendShader *GetColorDodgeBlendModeShader(); -#endif - SLayerRenderData *GetLayerRenderData() { return m_CurrentLayer; } - SLayerGlobalRenderProperties GetLayerGlobalRenderProperties(); - void UpdateCbAoShadow(const SLayer *pLayer, const SCamera *pCamera, - CResourceTexture2D &inDepthTexture); - - NVRenderContext &GetContext() { return *m_Context; } - - IQt3DSRenderContext &GetQt3DSContext() { return m_qt3dsContext; } - - void DrawScreenRect(NVRenderRectF inRect, const QT3DSVec3 &inColor); - // Binds an offscreen texture. Widgets are rendered last. - void SetupWidgetLayer(); - -#ifdef ADVANCED_BLEND_SW_FALLBACK - NVScopedRefCounted GetLayerBlendTexture() - { - return m_LayerBlendTexture.GetTexture(); - } - - NVScopedRefCounted GetBlendFB() - { - return m_BlendFB; - } -#endif - // widget context implementation - virtual NVRenderVertexBuffer & - GetOrCreateVertexBuffer(CRegisteredString &inStr, QT3DSU32 stride, - NVConstDataRef bufferData = NVConstDataRef()) override; - virtual NVRenderIndexBuffer & - GetOrCreateIndexBuffer(CRegisteredString &inStr, - qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, - NVConstDataRef bufferData = NVConstDataRef()) override; - virtual NVRenderAttribLayout & - CreateAttributeLayout(NVConstDataRef attribs) override; - virtual NVRenderInputAssembler & - GetOrCreateInputAssembler(CRegisteredString &inStr, NVRenderAttribLayout *attribLayout, - NVConstDataRef buffers, - const NVRenderIndexBuffer *indexBuffer, - NVConstDataRef strides, NVConstDataRef offsets) override; - - NVRenderVertexBuffer *GetVertexBuffer(CRegisteredString &inStr) override; - NVRenderIndexBuffer *GetIndexBuffer(CRegisteredString &inStr) override; - NVRenderInputAssembler *GetInputAssembler(CRegisteredString &inStr) override; - - NVRenderShaderProgram *GetShader(CRegisteredString inStr) override; - NVRenderShaderProgram *CompileAndStoreShader(CRegisteredString inStr) override; - IShaderProgramGenerator &GetProgramGenerator() override; - - STextDimensions MeasureText(const STextRenderInfo &inText) override; - void RenderText(const STextRenderInfo &inText, const QT3DSVec3 &inTextColor, - const QT3DSVec3 &inBackgroundColor, const QT3DSMat44 &inMVP) override; - - // Given a node and a point in the node's local space (most likely its pivot point), we - // return - // a normal matrix so you can get the axis out, a transformation from node to camera - // a new position and a floating point scale factor so you can render in 1/2 perspective - // mode - // or orthographic mode if you would like to. - virtual SWidgetRenderInformation - GetWidgetRenderInformation(SNode &inNode, const QT3DSVec3 &inPos, - RenderWidgetModes::Enum inWidgetMode) override; - - Option GetLayerMouseCoords(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool forceImageIntersect = false) const override; - - protected: - Option GetLayerMouseCoords(SLayerRenderData &inLayer, const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool forceImageIntersect = false) const; - SPickResultProcessResult ProcessPickResultList(bool inPickEverything); - // If the mouse y coordinates need to be flipped we expect that to happen before entry into - // this function - void GetLayerHitObjectList(SLayerRenderData &inLayer, const QT3DSVec2 &inViewportDimensions, - const QT3DSVec2 &inMouseCoords, bool inPickEverything, - TPickResultArray &outIntersectionResult, - NVAllocatorCallback &inTempAllocator); - void IntersectRayWithSubsetRenderable(const SRay &inRay, - SRenderableObject &inRenderableObject, - TPickResultArray &outIntersectionResultList, - NVAllocatorCallback &inTempAllocator); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp deleted file mode 100644 index af3cb613..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp +++ /dev/null @@ -1,2203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRender.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRendererImpl.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderEffect.h" -#include "EASTL/sort.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderPresentation.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderResourceManager.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderEffectSystem.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "Qt3DSOffscreenRenderKey.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderPluginGraphObject.h" -#include "Qt3DSRenderResourceBufferObjects.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSRenderMaterialHelpers.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderTextTextureCache.h" -#include "Qt3DSRenderTextTextureAtlas.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRendererUtil.h" - -#ifdef WIN32 -#pragma warning(disable : 4355) -#endif - -#define QT3DS_CACHED_POST_EFFECT -const float QT3DS_DEGREES_TO_RADIANS = 0.0174532925199f; - -namespace qt3ds { -namespace render { - using eastl::reverse; - using eastl::stable_sort; - using qt3ds::render::NVRenderContextScopedProperty; - using qt3ds::QT3DSVec2; - - SLayerRenderData::SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer) - : SLayerRenderPreparationData(inLayer, inRenderer) - , m_LayerTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_TemporalAATexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerPrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerSsaoTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerMultisampleTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerMultisamplePrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerMultisampleWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerCachedTexture(NULL) - , m_AdvancedBlendDrawTexture(NULL) - , m_AdvancedBlendBlendTexture(NULL) - , m_AdvancedModeDrawFB(NULL) - , m_AdvancedModeBlendFB(NULL) - , m_ProgressiveAAPassIndex(0) - , m_TemporalAAPassIndex(0) - , m_NonDirtyTemporalAAPassIndex(0) - , m_TextScale(1.0f) - , mRefCount(0) - , m_DepthBufferFormat(NVRenderTextureFormats::Unknown) - { - } - - SLayerRenderData::~SLayerRenderData() - { - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) - theResourceManager.Release(*m_LayerCachedTexture); - if (m_AdvancedModeDrawFB) { - m_AdvancedModeDrawFB->release(); - m_AdvancedModeDrawFB = NULL; - } - if (m_AdvancedModeBlendFB) { - m_AdvancedModeBlendFB->release(); - m_AdvancedModeBlendFB = NULL; - } - if (m_AdvancedBlendBlendTexture) - m_AdvancedBlendBlendTexture = NULL; - if (m_AdvancedBlendDrawTexture) - m_AdvancedBlendDrawTexture = NULL; - } - void SLayerRenderData::PrepareForRender(const QSize &inViewportDimensions) - { - SLayerRenderPreparationData::PrepareForRender(inViewportDimensions); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - // at that time all values shoud be updated - m_Renderer.UpdateCbAoShadow(&m_Layer, m_Camera, m_LayerDepthTexture); - - // Generate all necessary lighting keys - - if (thePrepResult.m_Flags.WasLayerDataDirty()) { - m_ProgressiveAAPassIndex = 0; - } - - // Get rid of the layer texture if we aren't rendering to texture this frame. - if (m_LayerTexture && !thePrepResult.m_Flags.ShouldRenderToTexture()) { - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; - } - - m_LayerTexture.ReleaseTexture(); - m_LayerDepthTexture.ReleaseTexture(); - m_LayerWidgetTexture.ReleaseTexture(); - m_LayerSsaoTexture.ReleaseTexture(); - m_LayerMultisampleTexture.ReleaseTexture(); - m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); - m_LayerMultisampleWidgetTexture.ReleaseTexture(); - } - - if (NeedsWidgetTexture() == false) - m_LayerWidgetTexture.ReleaseTexture(); - - if (m_LayerDepthTexture && !thePrepResult.m_Flags.RequiresDepthTexture()) - m_LayerDepthTexture.ReleaseTexture(); - - if (m_LayerSsaoTexture && !thePrepResult.m_Flags.RequiresSsaoPass()) - m_LayerSsaoTexture.ReleaseTexture(); - - m_Renderer.LayerNeedsFrameClear(*this); - - // Clean up the texture cache if layer dimensions changed - if (inViewportDimensions.width() != m_previousDimensions.width() - || inViewportDimensions.height() != m_previousDimensions.height()) { - m_LayerTexture.ReleaseTexture(); - m_LayerDepthTexture.ReleaseTexture(); - m_LayerSsaoTexture.ReleaseTexture(); - m_LayerWidgetTexture.ReleaseTexture(); - m_LayerPrepassDepthTexture.ReleaseTexture(); - m_TemporalAATexture.ReleaseTexture(); - m_LayerMultisampleTexture.ReleaseTexture(); - m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); - m_LayerMultisampleWidgetTexture.ReleaseTexture(); - - m_previousDimensions.setWidth(inViewportDimensions.width()); - m_previousDimensions.setHeight(inViewportDimensions.height()); - - theResourceManager.DestroyFreeSizedResources(); - - // Effect system uses different resource manager, so clean that up too - m_Renderer.GetQt3DSContext().GetEffectSystem().GetResourceManager() - .DestroyFreeSizedResources(); - } - } - - NVRenderTextureFormats::Enum SLayerRenderData::GetDepthBufferFormat() - { - if (m_DepthBufferFormat == NVRenderTextureFormats::Unknown) { - QT3DSU32 theExistingDepthBits = m_Renderer.GetContext().GetDepthBits(); - QT3DSU32 theExistingStencilBits = m_Renderer.GetContext().GetStencilBits(); - switch (theExistingDepthBits) { - case 32: - m_DepthBufferFormat = NVRenderTextureFormats::Depth32; - break; - case 24: - // check if we have stencil bits - if (theExistingStencilBits > 0) - m_DepthBufferFormat = - NVRenderTextureFormats::Depth24Stencil8; // currently no stencil usage - // should be Depth24Stencil8 in - // this case - else - m_DepthBufferFormat = NVRenderTextureFormats::Depth24; - break; - case 16: - m_DepthBufferFormat = NVRenderTextureFormats::Depth16; - break; - default: - QT3DS_ASSERT(false); - m_DepthBufferFormat = NVRenderTextureFormats::Depth16; - break; - } - } - return m_DepthBufferFormat; - } - - NVRenderFrameBufferAttachments::Enum - SLayerRenderData::GetFramebufferDepthAttachmentFormat(NVRenderTextureFormats::Enum depthFormat) - { - NVRenderFrameBufferAttachments::Enum fmt = NVRenderFrameBufferAttachments::Depth; - - switch (depthFormat) { - case NVRenderTextureFormats::Depth16: - case NVRenderTextureFormats::Depth24: - case NVRenderTextureFormats::Depth32: - fmt = NVRenderFrameBufferAttachments::Depth; - break; - case NVRenderTextureFormats::Depth24Stencil8: - fmt = NVRenderFrameBufferAttachments::DepthStencil; - break; - default: - QT3DS_ASSERT(false); - break; - } - - return fmt; - } - - void SLayerRenderData::RenderAoPass() - { - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theContext(m_Renderer.GetContext()); - SDefaultAoPassShader *shader = m_Renderer.GetDefaultAoPassShader(GetShaderFeatureSet()); - if (shader == NULL) - return; - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetActiveShader(&(shader->m_Shader)); - - // Setup constants - shader->m_CameraDirection.Set(m_CameraDirection); - shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform); - - shader->m_DepthTexture.Set(m_LayerDepthTexture); - shader->m_DepthSamplerSize.Set(QT3DSVec2(m_LayerDepthTexture->GetTextureDetails().m_Width, - m_LayerDepthTexture->GetTextureDetails().m_Height)); - - // Important uniforms for AO calculations - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - shader->m_CameraProperties.Set(theCameraProps); - shader->m_AoShadowParams.Set(); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - m_Renderer.EndLayerDepthPassRender(); - } - - void SLayerRenderData::RenderFakeDepthMapPass(NVRenderTexture2D *theDepthTex, - NVRenderTextureCube *theDepthCube) - { - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theContext(m_Renderer.GetContext()); - SDefaultAoPassShader *shader = theDepthTex - ? m_Renderer.GetFakeDepthShader(GetShaderFeatureSet()) - : m_Renderer.GetFakeCubeDepthShader(GetShaderFeatureSet()); - if (shader == NULL) - return; - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetActiveShader(&(shader->m_Shader)); - - // Setup constants - shader->m_CameraDirection.Set(m_CameraDirection); - shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform); - - shader->m_DepthTexture.Set(theDepthTex); - shader->m_CubeTexture.Set(theDepthCube); - shader->m_DepthSamplerSize.Set(QT3DSVec2(theDepthTex->GetTextureDetails().m_Width, - theDepthTex->GetTextureDetails().m_Height)); - - // Important uniforms for AO calculations - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - shader->m_CameraProperties.Set(theCameraProps); - shader->m_AoShadowParams.Set(); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - } - - namespace { - - void computeFrustumBounds(const SCamera &inCamera, const NVRenderRectF &inViewPort, - QT3DSVec3 &ctrBound, QT3DSVec3 camVerts[8]) - { - QT3DSVec3 camEdges[4]; - - const QT3DSF32 *dataPtr(inCamera.m_GlobalTransform.front()); - QT3DSVec3 camX(dataPtr[0], dataPtr[1], dataPtr[2]); - QT3DSVec3 camY(dataPtr[4], dataPtr[5], dataPtr[6]); - QT3DSVec3 camZ(dataPtr[8], dataPtr[9], dataPtr[10]); - - float tanFOV = tanf(inCamera.verticalFov(inViewPort) * 0.5f); - float asTanFOV = tanFOV * inViewPort.m_Width / inViewPort.m_Height; - camEdges[0] = -asTanFOV * camX + tanFOV * camY + camZ; - camEdges[1] = asTanFOV * camX + tanFOV * camY + camZ; - camEdges[2] = asTanFOV * camX - tanFOV * camY + camZ; - camEdges[3] = -asTanFOV * camX - tanFOV * camY + camZ; - - for (int i = 0; i < 4; ++i) { - camEdges[i].x = -camEdges[i].x; - camEdges[i].y = -camEdges[i].y; - } - - camVerts[0] = inCamera.m_Position + camEdges[0] * inCamera.m_ClipNear; - camVerts[1] = inCamera.m_Position + camEdges[0] * inCamera.m_ClipFar; - camVerts[2] = inCamera.m_Position + camEdges[1] * inCamera.m_ClipNear; - camVerts[3] = inCamera.m_Position + camEdges[1] * inCamera.m_ClipFar; - camVerts[4] = inCamera.m_Position + camEdges[2] * inCamera.m_ClipNear; - camVerts[5] = inCamera.m_Position + camEdges[2] * inCamera.m_ClipFar; - camVerts[6] = inCamera.m_Position + camEdges[3] * inCamera.m_ClipNear; - camVerts[7] = inCamera.m_Position + camEdges[3] * inCamera.m_ClipFar; - - ctrBound = camVerts[0]; - for (int i = 1; i < 8; ++i) { - ctrBound += camVerts[i]; - } - ctrBound *= 0.125f; - } - - void SetupCameraForShadowMap(const QT3DSVec2 &inCameraVec, NVRenderContext & /*inContext*/, - const NVRenderRectF &inViewport, const SCamera &inCamera, - const SLight *inLight, SCamera &theCamera) - { - // setup light matrix - QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes; - NVRenderRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes); - theCamera.m_ClipNear = 1.0f; - theCamera.m_ClipFar = inLight->m_ShadowMapFar; - // Setup camera projection - QT3DSVec3 inLightPos = inLight->GetGlobalPos(); - QT3DSVec3 inLightDir = inLight->GetDirection(); - - if (inLight->m_Flags.IsLeftHanded()) - inLightPos.z = -inLightPos.z; - - inLightPos -= inLightDir * inCamera.m_ClipNear; - theCamera.m_FOV = inLight->m_ShadowMapFov * QT3DS_DEGREES_TO_RADIANS; - - if (inLight->m_LightType == RenderLightTypes::Directional) { - QT3DSVec3 frustBounds[8], boundCtr; - computeFrustumBounds(inCamera, inViewport, boundCtr, frustBounds); - - QT3DSVec3 forward = inLightDir; - forward.normalize(); - QT3DSVec3 right = forward.cross(QT3DSVec3(0, 1, 0)); - right.normalize(); - QT3DSVec3 up = right.cross(forward); - up.normalize(); - - // Calculate bounding box of the scene camera frustum - float minDistanceZ = std::numeric_limits::max(); - float maxDistanceZ = -std::numeric_limits::max(); - float minDistanceY = std::numeric_limits::max(); - float maxDistanceY = -std::numeric_limits::max(); - float minDistanceX = std::numeric_limits::max(); - float maxDistanceX = -std::numeric_limits::max(); - for (int i = 0; i < 8; ++i) { - float distanceZ = frustBounds[i].dot(forward); - if (distanceZ < minDistanceZ) - minDistanceZ = distanceZ; - if (distanceZ > maxDistanceZ) - maxDistanceZ = distanceZ; - float distanceY = frustBounds[i].dot(up); - if (distanceY < minDistanceY) - minDistanceY = distanceY; - if (distanceY > maxDistanceY) - maxDistanceY = distanceY; - float distanceX = frustBounds[i].dot(right); - if (distanceX < minDistanceX) - minDistanceX = distanceX; - if (distanceX > maxDistanceX) - maxDistanceX = distanceX; - } - - // Apply bounding box parameters to shadow map camera projection matrix - // so that the whole scene is fit inside the shadow map - inLightPos = boundCtr; - theViewport.m_Height = abs(maxDistanceY - minDistanceY); - theViewport.m_Width = abs(maxDistanceX - minDistanceX); - theCamera.m_ClipNear = -abs(maxDistanceZ - minDistanceZ); - theCamera.m_ClipFar = abs(maxDistanceZ - minDistanceZ); - } - - theCamera.m_Flags.SetLeftHanded(false); - - theCamera.m_Flags.ClearOrSet(inLight->m_LightType == RenderLightTypes::Directional, - NodeFlagValues::Orthographic); - theCamera.m_Parent = NULL; - theCamera.m_Pivot = inLight->m_Pivot; - - if (inLight->m_LightType != RenderLightTypes::Point) { - theCamera.LookAt(inLightPos, QT3DSVec3(0, 1.0, 0), inLightPos + inLightDir); - } else { - theCamera.LookAt(inLightPos, QT3DSVec3(0, 1.0, 0), QT3DSVec3(0, 0, 0)); - } - - theCamera.CalculateGlobalVariables(theViewport, - QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); - } - } - - void SetupCubeShadowCameras(const SLight *inLight, SCamera inCameras[6]) - { - // setup light matrix - QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes; - NVRenderRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes); - QT3DSVec3 rotOfs[6]; - - QT3DS_ASSERT(inLight != NULL); - QT3DS_ASSERT(inLight->m_LightType != RenderLightTypes::Directional); - - QT3DSVec3 inLightPos = inLight->GetGlobalPos(); - if (inLight->m_Flags.IsLeftHanded()) - inLightPos.z = -inLightPos.z; - - rotOfs[0] = QT3DSVec3(0.f, -NVHalfPi, NVPi); - rotOfs[1] = QT3DSVec3(0.f, NVHalfPi, NVPi); - rotOfs[2] = QT3DSVec3(NVHalfPi, 0.f, 0.f); - rotOfs[3] = QT3DSVec3(-NVHalfPi, 0.f, 0.f); - rotOfs[4] = QT3DSVec3(0.f, NVPi, -NVPi); - rotOfs[5] = QT3DSVec3(0.f, 0.f, NVPi); - - for (int i = 0; i < 6; ++i) { - inCameras[i].m_Flags.SetLeftHanded(false); - - inCameras[i].m_Flags.ClearOrSet(false, NodeFlagValues::Orthographic); - inCameras[i].m_Parent = NULL; - inCameras[i].m_Pivot = inLight->m_Pivot; - inCameras[i].m_ClipNear = 1.0f; - inCameras[i].m_ClipFar = NVMax(2.0f, inLight->m_ShadowMapFar); - inCameras[i].m_FOV = inLight->m_ShadowMapFov * QT3DS_DEGREES_TO_RADIANS; - - inCameras[i].m_Position = inLightPos; - inCameras[i].m_Rotation = rotOfs[i]; - inCameras[i].CalculateGlobalVariables( - theViewport, QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); - } - - /* - if ( inLight->m_LightType == RenderLightTypes::Point ) return; - - QT3DSVec3 viewDirs[6]; - QT3DSVec3 viewUp[6]; - QT3DSMat33 theDirMatrix( inLight->m_GlobalTransform.getUpper3x3() ); - - viewDirs[0] = theDirMatrix.transform( QT3DSVec3( 1.f, 0.f, 0.f ) ); - viewDirs[2] = theDirMatrix.transform( QT3DSVec3( 0.f, -1.f, 0.f ) ); - viewDirs[4] = theDirMatrix.transform( QT3DSVec3( 0.f, 0.f, 1.f ) ); - viewDirs[0].normalize(); viewDirs[2].normalize(); viewDirs[4].normalize(); - viewDirs[1] = -viewDirs[0]; - viewDirs[3] = -viewDirs[2]; - viewDirs[5] = -viewDirs[4]; - - viewUp[0] = viewDirs[2]; - viewUp[1] = viewDirs[2]; - viewUp[2] = viewDirs[5]; - viewUp[3] = viewDirs[4]; - viewUp[4] = viewDirs[2]; - viewUp[5] = viewDirs[2]; - - for (int i = 0; i < 6; ++i) - { - inCameras[i].LookAt( inLightPos, viewUp[i], inLightPos + viewDirs[i] ); - inCameras[i].CalculateGlobalVariables( theViewport, QT3DSVec2( theViewport.m_Width, - theViewport.m_Height ) ); - } - */ - } - - inline void RenderRenderableShadowMapPass(SLayerRenderData &inData, SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, TShaderFeatureSet, - QT3DSU32 lightIndex, const SCamera &inCamera) - { - if (!inObject.m_RenderableFlags.IsShadowCaster()) - return; - - SShadowMapEntry *pEntry = inData.m_ShadowMapManager->GetShadowMapEntry(lightIndex); - - if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - static_cast(inObject).RenderShadowMapPass( - inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); - else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - static_cast(inObject).RenderShadowMapPass( - inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); - } else if (inObject.m_RenderableFlags.IsPath()) { - static_cast(inObject).RenderShadowMapPass( - inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); - } - } - - void SLayerRenderData::RenderShadowCubeBlurPass(CResourceFrameBuffer *theFB, - NVRenderTextureCube *target0, - NVRenderTextureCube *target1, QT3DSF32 filterSz, - QT3DSF32 clipFar) - { - NVRenderContext &theContext(m_Renderer.GetContext()); - - SShadowmapPreblurShader *shaderX = m_Renderer.GetCubeShadowBlurXShader(); - SShadowmapPreblurShader *shaderY = m_Renderer.GetCubeShadowBlurYShader(); - - if (shaderX == NULL) - return; - if (shaderY == NULL) - return; - // if ( theShader == NULL ) return; - - // Enable drawing to 6 color attachment buffers for cubemap passes - qt3ds::QT3DSI32 buffers[6] = { 0, 1, 2, 3, 4, 5 }; - qt3ds::foundation::NVConstDataRef bufferList(buffers, 6); - theContext.SetDrawBuffers(bufferList); - - // Attach framebuffer targets - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, *target1, - NVRenderTextureCubeFaces::CubePosX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, *target1, - NVRenderTextureCubeFaces::CubeNegX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, *target1, - NVRenderTextureCubeFaces::CubePosY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, *target1, - NVRenderTextureCubeFaces::CubeNegY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, *target1, - NVRenderTextureCubeFaces::CubePosZ); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, *target1, - NVRenderTextureCubeFaces::CubeNegZ); - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - // theContext.SetColorWritesEnabled(true); - theContext.SetActiveShader(&(shaderX->m_Shader)); - - shaderX->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderX->m_DepthCube.Set(target0); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - theContext.SetActiveShader(&(shaderY->m_Shader)); - - // Lather, Rinse, and Repeat for the Y-blur pass - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, *target0, - NVRenderTextureCubeFaces::CubePosX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, *target0, - NVRenderTextureCubeFaces::CubeNegX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, *target0, - NVRenderTextureCubeFaces::CubePosY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, *target0, - NVRenderTextureCubeFaces::CubeNegY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, *target0, - NVRenderTextureCubeFaces::CubePosZ); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, *target0, - NVRenderTextureCubeFaces::CubeNegZ); - - shaderY->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderY->m_DepthCube.Set(target1); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - theContext.SetDepthWriteEnabled(true); - theContext.SetDepthTestEnabled(true); - // theContext.SetColorWritesEnabled(false); - - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubePosX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubeNegX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubePosY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubeNegY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubePosZ); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubeNegZ); - - theContext.SetDrawBuffers(qt3ds::foundation::toConstDataRef((qt3ds::QT3DSI32)0)); - } - - void SLayerRenderData::RenderShadowMapBlurPass(CResourceFrameBuffer *theFB, - NVRenderTexture2D *target0, - NVRenderTexture2D *target1, QT3DSF32 filterSz, - QT3DSF32 clipFar) - { - NVRenderContext &theContext(m_Renderer.GetContext()); - - SShadowmapPreblurShader *shaderX = m_Renderer.GetOrthoShadowBlurXShader(); - SShadowmapPreblurShader *shaderY = m_Renderer.GetOrthoShadowBlurYShader(); - - if (shaderX == NULL) - return; - if (shaderY == NULL) - return; - - // Attach framebuffer target - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *target1); - //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, *target1 ); - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetColorWritesEnabled(true); - theContext.SetActiveShader(&(shaderX->m_Shader)); - - shaderX->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderX->m_DepthMap.Set(target0); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *target0); - //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, *target0 ); - theContext.SetActiveShader(&(shaderY->m_Shader)); - - shaderY->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderY->m_DepthMap.Set(target1); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - theContext.SetDepthWriteEnabled(true); - theContext.SetDepthTestEnabled(true); - theContext.SetColorWritesEnabled(false); - - //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, - //NVRenderTextureOrRenderBuffer() ); - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); - } - - void SLayerRenderData::RenderShadowMapPass(CResourceFrameBuffer *theFB) - { - SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::RenderShadowMapPass"); - - if (m_Camera == NULL || !GetShadowMapManager()) - return; - - // Check if we have anything to render - if (m_OpaqueObjects.size() == 0 || m_Lights.size() == 0) - return; - - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - - // we may change the viewport - NVRenderContextScopedProperty __viewport( - theRenderContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - - // disable color writes - // theRenderContext.SetColorWritesEnabled( false ); - theRenderContext.SetColorWritesEnabled(true); - theRenderContext.SetDepthWriteEnabled(true); - theRenderContext.SetCullingEnabled(false); - theRenderContext.SetClearColor(QT3DSVec4(1.0f)); - - // we render the shadow map with a slight offset to prevent shadow acne and cull the front - // faces - NVScopedRefCounted rsdefaultstate = - theRenderContext.CreateRasterizerState(0.0, 0.0, qt3ds::render::NVRenderFaces::Back); - NVScopedRefCounted rsstate = - theRenderContext.CreateRasterizerState(1.5, 2.0, qt3ds::render::NVRenderFaces::Front); - theRenderContext.SetRasterizerState(rsstate); - - qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Depth - | qt3ds::render::NVRenderClearValues::Stencil - | qt3ds::render::NVRenderClearValues::Color); - - for (QT3DSU32 i = 0; i < m_Lights.size(); i++) { - // don't render shadows when not casting - if (m_Lights[i]->m_CastShadow == false) - continue; - SShadowMapEntry *pEntry = m_ShadowMapManager->GetShadowMapEntry(i); - if (pEntry && pEntry->m_DepthMap && pEntry->m_DepthCopy && pEntry->m_DepthRender) { - SCamera theCamera; - - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - SetupCameraForShadowMap(theCameraProps, m_Renderer.GetContext(), - __viewport.m_InitialValue, *m_Camera, - m_Lights[i], theCamera); - // we need this matrix for the final rendering - theCamera.CalculateViewProjectionMatrix(pEntry->m_LightVP); - pEntry->m_LightView = theCamera.m_GlobalTransform.getInverse(); - - STextureDetails theDetails(pEntry->m_DepthMap->GetTextureDetails()); - theRenderContext.SetViewport( - NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); - - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *pEntry->m_DepthMap); - (*theFB)->Attach(NVRenderFrameBufferAttachments::DepthStencil, - *pEntry->m_DepthRender); - theRenderContext.Clear(clearFlags); - - RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i, theCamera); - RenderShadowMapBlurPass(theFB, pEntry->m_DepthMap, pEntry->m_DepthCopy, - m_Lights[i]->m_ShadowFilter, m_Lights[i]->m_ShadowMapFar); - } else if (pEntry && pEntry->m_DepthCube && pEntry->m_CubeCopy - && pEntry->m_DepthRender) { - SCamera theCameras[6]; - - SetupCubeShadowCameras(m_Lights[i], theCameras); - - // pEntry->m_LightView = m_Lights[i]->m_LightType == RenderLightTypes::Point ? - // QT3DSMat44::createIdentity() - // : m_Lights[i]->m_GlobalTransform; - pEntry->m_LightView = QT3DSMat44::createIdentity(); - - STextureDetails theDetails(pEntry->m_DepthCube->GetTextureDetails()); - theRenderContext.SetViewport( - NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); - - // int passes = m_Lights[i]->m_LightType == RenderLightTypes::Point ? 6 : 5; - int passes = 6; - for (int k = 0; k < passes; ++k) { - // theCameras[k].CalculateViewProjectionMatrix( pEntry->m_LightCubeVP[k] ); - pEntry->m_LightCubeView[k] = theCameras[k].m_GlobalTransform.getInverse(); - theCameras[k].CalculateViewProjectionMatrix(pEntry->m_LightVP); - - // Geometry shader multiplication really doesn't work unless you have a - // 6-layered 3D depth texture... - // Otherwise, you have no way to depth test while rendering... - // which more or less completely defeats the purpose of having a cubemap render - // target. - NVRenderTextureCubeFaces::Enum curFace = - (NVRenderTextureCubeFaces::Enum)(k + 1); - //(*theFB)->AttachFace( NVRenderFrameBufferAttachments::DepthStencil, - //*pEntry->m_DepthCube, curFace ); - (*theFB)->Attach(NVRenderFrameBufferAttachments::DepthStencil, - *pEntry->m_DepthRender); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, - *pEntry->m_DepthCube, curFace); - (*theFB)->IsComplete(); - theRenderContext.Clear(clearFlags); - - RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i, - theCameras[k]); - } - - RenderShadowCubeBlurPass(theFB, pEntry->m_DepthCube, pEntry->m_CubeCopy, - m_Lights[i]->m_ShadowFilter, m_Lights[i]->m_ShadowMapFar); - } - } - - (*theFB)->Attach(NVRenderFrameBufferAttachments::Depth, NVRenderTextureOrRenderBuffer()); - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); - - // enable color writes - theRenderContext.SetColorWritesEnabled(true); - theRenderContext.SetCullingEnabled(true); - theRenderContext.SetClearColor(QT3DSVec4(0.0f)); - // reset rasterizer state - theRenderContext.SetRasterizerState(rsdefaultstate); - - m_Renderer.EndLayerDepthPassRender(); - } - - inline void RenderRenderableDepthPass(SLayerRenderData &inData, SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, TShaderFeatureSet, QT3DSU32, - const SCamera &inCamera) - { - if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - static_cast(inObject).RenderDepthPass(inCameraProps); - else if (inObject.m_RenderableFlags.IsText()) - static_cast(inObject).RenderDepthPass(inCameraProps); - else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - static_cast(inObject).RenderDepthPass( - inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, NULL); - } else if (inObject.m_RenderableFlags.IsPath()) { - static_cast(inObject).RenderDepthPass( - inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, NULL); - } else { - QT3DS_ASSERT(false); - } - } - - void SLayerRenderData::RenderDepthPass(bool inEnableTransparentDepthWrite) - { - SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::RenderDepthPass"); - if (m_Camera == NULL) - return; - - // Avoid running this method if possible. - if ((inEnableTransparentDepthWrite == false - && (m_OpaqueObjects.size() == 0 - || m_Layer.m_Flags.IsLayerEnableDepthPrepass() == false)) - || m_Layer.m_Flags.IsLayerEnableDepthTest() == false) - return; - - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - - // disable color writes - theRenderContext.SetColorWritesEnabled(false); - theRenderContext.SetDepthWriteEnabled(true); - - qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Stencil - | qt3ds::render::NVRenderClearValues::Depth); - theRenderContext.Clear(clearFlags); - - RunRenderPass(RenderRenderableDepthPass, false, true, inEnableTransparentDepthWrite, 0, - *m_Camera); - - // enable color writes - theRenderContext.SetColorWritesEnabled(true); - - m_Renderer.EndLayerDepthPassRender(); - } - - inline void RenderRenderable(SLayerRenderData &inData, SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, TShaderFeatureSet inFeatureSet, QT3DSU32, - const SCamera &inCamera) - { - if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - static_cast(inObject).Render(inCameraProps, inFeatureSet); - else if (inObject.m_RenderableFlags.IsText()) - static_cast(inObject).Render(inCameraProps); - else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - // PKC : Need a better place to do this. - SCustomMaterialRenderable &theObject = - static_cast(inObject); - if (!inData.m_Layer.m_LightProbe && theObject.m_Material.m_IblProbe) - inData.SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", - theObject.m_Material.m_IblProbe->m_TextureData.m_Texture - != NULL); - else if (inData.m_Layer.m_LightProbe) - inData.SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", - inData.m_Layer.m_LightProbe->m_TextureData.m_Texture - != NULL); - - static_cast(inObject).Render( - inCameraProps, inData, inData.m_Layer, inData.m_Lights, inCamera, - inData.m_LayerDepthTexture, inData.m_LayerSsaoTexture, inFeatureSet); - } else if (inObject.m_RenderableFlags.IsPath()) { - static_cast(inObject).Render( - inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, - inData.m_LayerDepthTexture, inData.m_LayerSsaoTexture, inFeatureSet); - } else { - QT3DS_ASSERT(false); - } - } - - void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, - bool inEnableBlending, bool inEnableDepthWrite, - bool inEnableTransparentDepthWrite, QT3DSU32 indexLight, - const SCamera &inCamera, CResourceFrameBuffer *theFB) - { - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - theRenderContext.SetDepthFunction(qt3ds::render::NVRenderBoolOp::LessThanOrEqual); - theRenderContext.SetBlendingEnabled(false); - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - NVDataRef theOpaqueObjects = GetOpaqueRenderableObjects(); - bool usingDepthBuffer = - m_Layer.m_Flags.IsLayerEnableDepthTest() && theOpaqueObjects.size() > 0; - - if (usingDepthBuffer) { - theRenderContext.SetDepthTestEnabled(true); - theRenderContext.SetDepthWriteEnabled(inEnableDepthWrite); - } else { - theRenderContext.SetDepthWriteEnabled(false); - theRenderContext.SetDepthTestEnabled(false); - } - - for (QT3DSU32 idx = 0, end = theOpaqueObjects.size(); idx < end; ++idx) { - SRenderableObject &theObject(*theOpaqueObjects[idx]); - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, m_SourceLightDirections, - theObject.m_ScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), indexLight, - inCamera); - } - - // transparent objects - if (inEnableBlending || m_Layer.m_Flags.IsLayerEnableDepthTest() == false) { - theRenderContext.SetBlendingEnabled(true && inEnableBlending); - theRenderContext.SetDepthWriteEnabled(inEnableTransparentDepthWrite); - - NVDataRef theTransparentObjects = GetTransparentRenderableObjects(); - // Assume all objects have transparency if the layer's depth test enabled flag is true. - if (m_Layer.m_Flags.IsLayerEnableDepthTest() == true) { - for (QT3DSU32 idx = 0, end = theTransparentObjects.size(); idx < end; ++idx) { - SRenderableObject &theObject(*theTransparentObjects[idx]); - if (!(theObject.m_RenderableFlags.IsCompletelyTransparent())) { -#ifdef ADVANCED_BLEND_SW_FALLBACK - // SW fallback for advanced blend modes. - // Renders transparent objects to a separate FBO and blends them in shader - // with the opaque items and background. - DefaultMaterialBlendMode::Enum blendMode - = DefaultMaterialBlendMode::Enum::Normal; - if (theObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - blendMode = static_cast(theObject).getBlendingMode(); - bool useBlendFallback = (blendMode == DefaultMaterialBlendMode::Overlay || - blendMode == DefaultMaterialBlendMode::ColorBurn || - blendMode == DefaultMaterialBlendMode::ColorDodge) && - !theRenderContext.IsAdvancedBlendHwSupported() && - !theRenderContext.IsAdvancedBlendHwSupportedKHR() && - m_LayerPrepassDepthTexture; - if (useBlendFallback) - SetupDrawFB(true); -#endif - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, - m_SourceLightDirections, - theObject.m_ScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - - inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), - indexLight, inCamera); -#ifdef ADVANCED_BLEND_SW_FALLBACK - // SW fallback for advanced blend modes. - // Continue blending after transparent objects have been rendered to a FBO - if (useBlendFallback) { - BlendAdvancedToFB(blendMode, true, theFB); - // restore blending status - theRenderContext.SetBlendingEnabled(inEnableBlending); - // restore depth test status - theRenderContext.SetDepthTestEnabled(usingDepthBuffer); - theRenderContext.SetDepthWriteEnabled(inEnableTransparentDepthWrite); - } -#endif - } - } - } - // If the layer doesn't have depth enabled then we have to render via an alternate route - // where the transparent objects vector could have both opaque and transparent objects. - else { - for (QT3DSU32 idx = 0, end = theTransparentObjects.size(); idx < end; ++idx) { - SRenderableObject &theObject(*theTransparentObjects[idx]); - if (!(theObject.m_RenderableFlags.IsCompletelyTransparent())) { -#ifdef ADVANCED_BLEND_SW_FALLBACK - DefaultMaterialBlendMode::Enum blendMode - = DefaultMaterialBlendMode::Enum::Normal; - if (theObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - blendMode = static_cast(theObject).getBlendingMode(); - bool useBlendFallback = (blendMode == DefaultMaterialBlendMode::Overlay || - blendMode == DefaultMaterialBlendMode::ColorBurn || - blendMode == DefaultMaterialBlendMode::ColorDodge) && - !theRenderContext.IsAdvancedBlendHwSupported() && - !theRenderContext.IsAdvancedBlendHwSupportedKHR(); - - if (theObject.m_RenderableFlags.HasTransparency()) { - theRenderContext.SetBlendingEnabled(true && inEnableBlending); - // If we have SW fallback for blend mode, render to a FBO and blend back. - // Slow as this must be done per-object (transparent and opaque items - // are mixed, not batched) - if (useBlendFallback) - SetupDrawFB(false); - } -#endif - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, - m_SourceLightDirections, - theObject.m_ScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), - indexLight, inCamera); -#ifdef ADVANCED_BLEND_SW_FALLBACK - if (useBlendFallback) { - BlendAdvancedToFB(blendMode, false, theFB); - // restore blending status - theRenderContext.SetBlendingEnabled(inEnableBlending); - - } -#endif - } - } - } - } - } - - void SLayerRenderData::Render(CResourceFrameBuffer *theFB) - { - SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::Render"); - if (m_Camera == NULL) - return; - - m_Renderer.BeginLayerRender(*this); - RunRenderPass(RenderRenderable, true, !m_Layer.m_Flags.IsLayerEnableDepthPrepass(), false, - 0, *m_Camera, theFB); - m_Renderer.EndLayerRender(); - } - - void SLayerRenderData::CreateGpuProfiler() - { - if (m_Renderer.GetContext().IsTimerQuerySupported()) { - m_LayerProfilerGpu = IRenderProfiler::CreateGpuProfiler( - m_Renderer.GetContext().GetFoundation(), m_Renderer.GetQt3DSContext(), - m_Renderer.GetContext()); - } - } - - void SLayerRenderData::StartProfiling(CRegisteredString &nameID, bool sync) - { - if (m_LayerProfilerGpu.mPtr) { - m_LayerProfilerGpu->StartTimer(nameID, false, sync); - } - } - - void SLayerRenderData::EndProfiling(CRegisteredString &nameID) - { - if (m_LayerProfilerGpu.mPtr) { - m_LayerProfilerGpu->EndTimer(nameID); - } - } - - void SLayerRenderData::StartProfiling(const char *nameID, bool sync) - { - if (m_LayerProfilerGpu.mPtr) { - CRegisteredString theStr( - m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(nameID)); - m_LayerProfilerGpu->StartTimer(theStr, false, sync); - } - } - - void SLayerRenderData::EndProfiling(const char *nameID) - { - if (m_LayerProfilerGpu.mPtr) { - CRegisteredString theStr( - m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(nameID)); - m_LayerProfilerGpu->EndTimer(theStr); - } - } - - void SLayerRenderData::AddVertexCount(QT3DSU32 count) - { - if (m_LayerProfilerGpu.mPtr) { - m_LayerProfilerGpu->AddVertexCount(count); - } - } - - // Assumes the viewport is setup appropriately to render the widget. - void SLayerRenderData::RenderRenderWidgets() - { - if (m_Camera) { - NVRenderContext &theContext(m_Renderer.GetContext()); - for (QT3DSU32 idx = 0, end = m_IRenderWidgets.size(); idx < end; ++idx) { - IRenderWidget &theWidget = *m_IRenderWidgets[idx]; - theWidget.Render(m_Renderer, theContext); - } - } - } - -#ifdef ADVANCED_BLEND_SW_FALLBACK - void SLayerRenderData::BlendAdvancedEquationSwFallback(NVRenderTexture2D *drawTexture, - NVRenderTexture2D *layerTexture, - AdvancedBlendModes::Enum blendMode) - { - NVRenderContext &theContext(m_Renderer.GetContext()); - SAdvancedModeBlendShader *shader = m_Renderer.GetAdvancedBlendModeShader(blendMode); - if (shader == NULL) - return; - - theContext.SetActiveShader(&(shader->m_Shader)); - - shader->m_baseLayer.Set(layerTexture); - shader->m_blendLayer.Set(drawTexture); - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - } - - void SLayerRenderData::SetupDrawFB(bool depthEnabled) - { - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - // create drawing FBO and texture, if not existing - if (!m_AdvancedModeDrawFB) - m_AdvancedModeDrawFB = theRenderContext.CreateFrameBuffer(); - if (!m_AdvancedBlendDrawTexture) { - m_AdvancedBlendDrawTexture = theRenderContext.CreateTexture2D(); - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - m_AdvancedBlendDrawTexture->SetTextureData(NVDataRef(), 0, - theViewport.m_Width, - theViewport.m_Height, - NVRenderTextureFormats::RGBA8); - m_AdvancedModeDrawFB->Attach(NVRenderFrameBufferAttachments::Color0, - *m_AdvancedBlendDrawTexture); - // Use existing depth prepass information when rendering transparent objects to a FBO - if (depthEnabled) - m_AdvancedModeDrawFB->Attach(NVRenderFrameBufferAttachments::Depth, - *m_LayerPrepassDepthTexture); - } - theRenderContext.SetRenderTarget(m_AdvancedModeDrawFB); - // make sure that depth testing is on in order to render just the - // depth-passed objects (=transparent objects) and leave background intact - if (depthEnabled) - theRenderContext.SetDepthTestEnabled(true); - theRenderContext.SetBlendingEnabled(false); - // clear color commonly is the layer background, make sure that it is all-zero here - QT3DSVec4 originalClrColor = theRenderContext.GetClearColor(); - theRenderContext.SetClearColor(QT3DSVec4(0.0)); - theRenderContext.Clear(NVRenderClearValues::Color); - theRenderContext.SetClearColor(originalClrColor); - - } - void SLayerRenderData::BlendAdvancedToFB(DefaultMaterialBlendMode::Enum blendMode, - bool depthEnabled, CResourceFrameBuffer *theFB) - { - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - AdvancedBlendModes::Enum advancedMode; - - switch (blendMode) { - case DefaultMaterialBlendMode::Overlay: - advancedMode = AdvancedBlendModes::Overlay; - break; - case DefaultMaterialBlendMode::ColorBurn: - advancedMode = AdvancedBlendModes::ColorBurn; - break; - case DefaultMaterialBlendMode::ColorDodge: - advancedMode = AdvancedBlendModes::ColorDodge; - break; - default: - Q_UNREACHABLE(); - } - // create blending FBO and texture if not existing - if (!m_AdvancedModeBlendFB) - m_AdvancedModeBlendFB = theRenderContext.CreateFrameBuffer(); - if (!m_AdvancedBlendBlendTexture) { - m_AdvancedBlendBlendTexture = theRenderContext.CreateTexture2D(); - m_AdvancedBlendBlendTexture->SetTextureData(NVDataRef(), 0, - theViewport.m_Width, - theViewport.m_Height, - NVRenderTextureFormats::RGBA8); - m_AdvancedModeBlendFB->Attach(NVRenderFrameBufferAttachments::Color0, - *m_AdvancedBlendBlendTexture); - } - theRenderContext.SetRenderTarget(m_AdvancedModeBlendFB); - - // Blend transparent objects with SW fallback shaders. - // Disable depth testing as transparent objects have already been - // depth-checked; here we want to run shader for all layer pixels - if (depthEnabled) - { - theRenderContext.SetDepthTestEnabled(false); - theRenderContext.SetDepthWriteEnabled(false); - } - BlendAdvancedEquationSwFallback(m_AdvancedBlendDrawTexture, m_LayerTexture, advancedMode); - theRenderContext.SetRenderTarget(*theFB); - // setup read target - theRenderContext.SetReadTarget(m_AdvancedModeBlendFB); - theRenderContext.SetReadBuffer(NVReadFaces::Color0); - theRenderContext.BlitFramebuffer(0, 0, theViewport.m_Width, theViewport.m_Height, - 0, 0, theViewport.m_Width, theViewport.m_Height, - NVRenderClearValues::Color, - NVRenderTextureMagnifyingOp::Nearest); - } -#endif - - void SLayerRenderData::RenderToViewport() - { - if (m_LayerPrepResult->IsLayerVisible()) { - if (GetOffscreenRenderer()) { - if (m_Layer.m_Background == LayerBackground::Color) { - m_LastFrameOffscreenRenderer->RenderWithClear( - CreateOffscreenRenderEnvironment(), m_Renderer.GetContext(), - m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), - SScene::AlwaysClear, m_Layer.m_ClearColor, &m_Layer); - } else { - m_LastFrameOffscreenRenderer->Render( - CreateOffscreenRenderEnvironment(), m_Renderer.GetContext(), - m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), - SScene::ClearIsOptional, &m_Layer); - } - } else { - RenderDepthPass(false); - Render(); - RenderRenderWidgets(); - } - } - } - // These are meant to be pixel offsets, so you need to divide them by the width/height - // of the layer respectively. - const QT3DSVec2 s_VertexOffsets[SLayerRenderPreparationData::MAX_AA_LEVELS] = { - QT3DSVec2(-0.170840f, -0.553840f), // 1x - QT3DSVec2(0.162960f, -0.319340f), // 2x - QT3DSVec2(0.360260f, -0.245840f), // 3x - QT3DSVec2(-0.561340f, -0.149540f), // 4x - QT3DSVec2(0.249460f, 0.453460f), // 5x - QT3DSVec2(-0.336340f, 0.378260f), // 6x - QT3DSVec2(0.340000f, 0.166260f), // 7x - QT3DSVec2(0.235760f, 0.527760f), // 8x - }; - - // Blend factors are in the form of (frame blend factor, accumulator blend factor) - const QT3DSVec2 s_BlendFactors[SLayerRenderPreparationData::MAX_AA_LEVELS] = { - QT3DSVec2(0.500000f, 0.500000f), // 1x - QT3DSVec2(0.333333f, 0.666667f), // 2x - QT3DSVec2(0.250000f, 0.750000f), // 3x - QT3DSVec2(0.200000f, 0.800000f), // 4x - QT3DSVec2(0.166667f, 0.833333f), // 5x - QT3DSVec2(0.142857f, 0.857143f), // 6x - QT3DSVec2(0.125000f, 0.875000f), // 7x - QT3DSVec2(0.111111f, 0.888889f), // 8x - }; - - const QT3DSVec2 s_TemporalVertexOffsets[SLayerRenderPreparationData::MAX_TEMPORAL_AA_LEVELS] = { - QT3DSVec2(.3f, .3f), QT3DSVec2(-.3f, -.3f) - }; - - static inline void OffsetProjectionMatrix(QT3DSMat44 &inProjectionMatrix, QT3DSVec2 inVertexOffsets) - { - inProjectionMatrix.column3.x = - inProjectionMatrix.column3.x + inProjectionMatrix.column3.w * inVertexOffsets.x; - inProjectionMatrix.column3.y = - inProjectionMatrix.column3.y + inProjectionMatrix.column3.w * inVertexOffsets.y; - } - - CRegisteredString depthPassStr; - - // Render this layer's data to a texture. Required if we have any effects, - // prog AA, or if forced. - void SLayerRenderData::RenderToTexture() - { - QT3DS_ASSERT(m_LayerPrepResult->m_Flags.ShouldRenderToTexture()); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - QSize theLayerTextureDimensions = thePrepResult.GetTextureDimensions(); - QSize theLayerOriginalTextureDimensions = theLayerTextureDimensions; - NVRenderTextureFormats::Enum DepthTextureFormat = NVRenderTextureFormats::Depth24Stencil8; - NVRenderTextureFormats::Enum ColorTextureFormat = NVRenderTextureFormats::RGBA8; - if (thePrepResult.m_LastEffect - && theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) { - if (m_Layer.m_Background != LayerBackground::Transparent) - ColorTextureFormat = NVRenderTextureFormats::R11G11B10; - else - ColorTextureFormat = NVRenderTextureFormats::RGBA16F; - } - NVRenderTextureFormats::Enum ColorSSAOTextureFormat = NVRenderTextureFormats::RGBA8; - - bool needsRender = false; - QT3DSU32 sampleCount = 1; - // check multsample mode and MSAA texture support - if (m_Layer.m_MultisampleAAMode != AAModeValues::NoAA - && theRenderContext.AreMultisampleTexturesSupported()) - sampleCount = (QT3DSU32)m_Layer.m_MultisampleAAMode; - - bool isMultisamplePass = false; - if (theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) - isMultisamplePass = - (sampleCount > 1) || (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA); - - qt3ds::render::NVRenderTextureTargetType::Enum thFboAttachTarget = - qt3ds::render::NVRenderTextureTargetType::Texture2D; - - // If the user has disabled all layer caching this has the side effect of disabling the - // progressive AA algorithm. - if (thePrepResult.m_Flags.WasLayerDataDirty() - || thePrepResult.m_Flags.WasDirty() - || m_Renderer.IsLayerCachingEnabled() == false - || thePrepResult.m_Flags.ShouldRenderToTexture()) { - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - needsRender = true; - } - - CResourceTexture2D *renderColorTexture = &m_LayerTexture; - CResourceTexture2D *renderPrepassDepthTexture = &m_LayerPrepassDepthTexture; - CResourceTexture2D *renderWidgetTexture = &m_LayerWidgetTexture; - NVRenderContextScopedProperty __multisampleEnabled( - theRenderContext, &NVRenderContext::IsMultisampleEnabled, - &NVRenderContext::SetMultisampleEnabled); - theRenderContext.SetMultisampleEnabled(false); - if (isMultisamplePass) { - renderColorTexture = &m_LayerMultisampleTexture; - renderPrepassDepthTexture = &m_LayerMultisamplePrepassDepthTexture; - renderWidgetTexture = &m_LayerMultisampleWidgetTexture; - // for SSAA we don't use MS textures - if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) - thFboAttachTarget = qt3ds::render::NVRenderTextureTargetType::Texture2D_MS; - } - QT3DSU32 maxTemporalPassIndex = m_Layer.m_TemporalAAEnabled ? 2 : 0; - - // If all the dimensions match then we do not have to re-render the layer. - if (m_LayerTexture.TextureMatches(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), ColorTextureFormat) - && (!thePrepResult.m_Flags.RequiresDepthTexture() - || m_LayerDepthTexture.TextureMatches(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - DepthTextureFormat)) - && m_ProgressiveAAPassIndex >= thePrepResult.m_MaxAAPassIndex - && m_NonDirtyTemporalAAPassIndex >= maxTemporalPassIndex && needsRender == false) { - return; - } - - // adjust render size for SSAA - if (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA) { - QT3DSU32 ow, oh; - CRendererUtil::GetSSAARenderSize(theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), - ow, oh); - theLayerTextureDimensions = QSize(ow, oh); - } - - // If our pass index == thePreResult.m_MaxAAPassIndex then - // we shouldn't get into here. - - IResourceManager &theResourceManager = m_Renderer.GetQt3DSContext().GetResourceManager(); - bool hadLayerTexture = true; - - if (renderColorTexture->EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - ColorTextureFormat, sampleCount)) { - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - hadLayerTexture = false; - } - - if (thePrepResult.m_Flags.RequiresDepthTexture()) { - // The depth texture doesn't need to be multisample, the prepass depth does. - if (m_LayerDepthTexture.EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - DepthTextureFormat)) { - // Depth textures are generally not bilinear filtered. - m_LayerDepthTexture->SetMinFilter(NVRenderTextureMinifyingOp::Nearest); - m_LayerDepthTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Nearest); - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - } - } - - if (thePrepResult.m_Flags.RequiresSsaoPass()) { - if (m_LayerSsaoTexture.EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - ColorSSAOTextureFormat)) { - m_LayerSsaoTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - m_LayerSsaoTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - } - } - - QT3DS_ASSERT(!thePrepResult.m_Flags.RequiresDepthTexture() || m_LayerDepthTexture); - QT3DS_ASSERT(!thePrepResult.m_Flags.RequiresSsaoPass() || m_LayerSsaoTexture); - - CResourceTexture2D theLastLayerTexture(theResourceManager); - SLayerProgAABlendShader *theBlendShader = NULL; - QT3DSU32 aaFactorIndex = 0; - bool isProgressiveAABlendPass = - m_ProgressiveAAPassIndex && m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex; - bool isTemporalAABlendPass = m_Layer.m_TemporalAAEnabled && m_ProgressiveAAPassIndex == 0; - - if (isProgressiveAABlendPass || isTemporalAABlendPass) { - theBlendShader = m_Renderer.GetLayerProgAABlendShader(); - if (theBlendShader) { - m_LayerTexture.EnsureTexture(theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), - ColorTextureFormat); - QT3DSVec2 theVertexOffsets; - if (isProgressiveAABlendPass) { - theLastLayerTexture.StealTexture(m_LayerTexture); - aaFactorIndex = (m_ProgressiveAAPassIndex - 1); - theVertexOffsets = s_VertexOffsets[aaFactorIndex]; - } else { - if (m_TemporalAATexture.GetTexture()) - theLastLayerTexture.StealTexture(m_TemporalAATexture); - else { - if (hadLayerTexture) { - theLastLayerTexture.StealTexture(m_LayerTexture); - } - } - theVertexOffsets = s_TemporalVertexOffsets[m_TemporalAAPassIndex]; - ++m_TemporalAAPassIndex; - ++m_NonDirtyTemporalAAPassIndex; - m_TemporalAAPassIndex = m_TemporalAAPassIndex % MAX_TEMPORAL_AA_LEVELS; - } - if (theLastLayerTexture.GetTexture()) { - theVertexOffsets.x = - theVertexOffsets.x / (theLayerOriginalTextureDimensions.width() / 2.0f); - theVertexOffsets.y = - theVertexOffsets.y / (theLayerOriginalTextureDimensions.height() / 2.0f); - // Run through all models and update MVP. - // run through all texts and update MVP. - // run through all path and update MVP. - - // TODO - optimize this exact matrix operation. - for (QT3DSU32 idx = 0, end = m_ModelContexts.size(); idx < end; ++idx) { - QT3DSMat44 &originalProjection(m_ModelContexts[idx]->m_ModelViewProjection); - OffsetProjectionMatrix(originalProjection, theVertexOffsets); - } - for (QT3DSU32 idx = 0, end = m_OpaqueObjects.size(); idx < end; ++idx) { - if (m_OpaqueObjects[idx]->m_RenderableFlags.IsPath()) { - SPathRenderable &theRenderable = - static_cast(*m_OpaqueObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, - theVertexOffsets); - } - } - for (QT3DSU32 idx = 0, end = m_TransparentObjects.size(); idx < end; ++idx) { - if (m_TransparentObjects[idx]->m_RenderableFlags.IsText()) { - STextRenderable &theRenderable = - static_cast(*m_TransparentObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, - theVertexOffsets); - } else if (m_TransparentObjects[idx]->m_RenderableFlags.IsPath()) { - SPathRenderable &theRenderable = - static_cast(*m_TransparentObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, - theVertexOffsets); - } - } - } - } - } - if (theLastLayerTexture.GetTexture() == NULL) { - isProgressiveAABlendPass = false; - isTemporalAABlendPass = false; - } - // Sometimes we will have stolen the render texture. - renderColorTexture->EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), ColorTextureFormat, - sampleCount); - - if (!isTemporalAABlendPass) - m_TemporalAATexture.ReleaseTexture(); - - // Allocating a frame buffer can cause it to be bound, so we need to save state before this - // happens. - NVRenderContextScopedProperty __framebuf( - theRenderContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - // Match the bit depth of the current render target to avoid popping when we switch from aa - // to non aa layers - // We have to all this here in because once we change the FB by allocating an FB we are - // screwed. - NVRenderTextureFormats::Enum theDepthFormat(GetDepthBufferFormat()); - NVRenderFrameBufferAttachments::Enum theDepthAttachmentFormat( - GetFramebufferDepthAttachmentFormat(theDepthFormat)); - - // Definitely disable the scissor rect if it is running right now. - NVRenderContextScopedProperty __scissorEnabled( - theRenderContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, false); - CResourceFrameBuffer theFB(theResourceManager); - // Allocates the frame buffer which has the side effect of setting the current render target - // to that frame buffer. - theFB.EnsureFrameBuffer(); - - bool hasDepthObjects = m_OpaqueObjects.size() > 0; - bool requiresDepthStencilBuffer = - hasDepthObjects || thePrepResult.m_Flags.RequiresStencilBuffer(); - NVRenderRect theNewViewport(0, 0, theLayerTextureDimensions.width(), - theLayerTextureDimensions.height()); - { - theRenderContext.SetRenderTarget(theFB); - NVRenderContextScopedProperty __viewport( - theRenderContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, - theNewViewport); - QT3DSVec4 clearColor(0.0); - if (m_Layer.m_Background == LayerBackground::Color) - clearColor = QT3DSVec4(m_Layer.m_ClearColor, 1.0); - - NVRenderContextScopedProperty __clearColor( - theRenderContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - clearColor); - if (requiresDepthStencilBuffer) { - if (renderPrepassDepthTexture->EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - theDepthFormat, sampleCount)) { - (*renderPrepassDepthTexture)->SetMinFilter(NVRenderTextureMinifyingOp::Nearest); - (*renderPrepassDepthTexture) - ->SetMagFilter(NVRenderTextureMagnifyingOp::Nearest); - } - } - - if (thePrepResult.m_Flags.RequiresDepthTexture() && m_ProgressiveAAPassIndex == 0) { - // Setup FBO with single depth buffer target. - // Note this does not use multisample. - NVRenderFrameBufferAttachments::Enum theAttachment = - GetFramebufferDepthAttachmentFormat(DepthTextureFormat); - theFB->Attach(theAttachment, *m_LayerDepthTexture); - - // In this case transparent objects also may write their depth. - RenderDepthPass(true); - theFB->Attach(theAttachment, NVRenderTextureOrRenderBuffer()); - } - - if (thePrepResult.m_Flags.RequiresSsaoPass() && m_ProgressiveAAPassIndex == 0 - && m_Camera != nullptr) { - StartProfiling("AO pass", false); - // Setup FBO with single color buffer target - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerSsaoTexture); - theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); - RenderAoPass(); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer()); - EndProfiling("AO pass"); - } - - if (thePrepResult.m_Flags.RequiresShadowMapPass() && m_ProgressiveAAPassIndex == 0) { - // shadow map path - RenderShadowMapPass(&theFB); - } - - if (sampleCount > 1) { - theRenderContext.SetMultisampleEnabled(true); - } - - qt3ds::render::NVRenderClearFlags clearFlags = qt3ds::render::NVRenderClearValues::Color; - - // render depth prepass - if ((*renderPrepassDepthTexture)) { - theFB->Attach(theDepthAttachmentFormat, **renderPrepassDepthTexture, - thFboAttachTarget); - - if (m_Layer.m_Flags.IsLayerEnableDepthPrepass()) { - StartProfiling("Depth pass", false); - RenderDepthPass(false); - EndProfiling("Depth pass"); - } else { - clearFlags |= (qt3ds::render::NVRenderClearValues::Depth); - clearFlags |= (qt3ds::render::NVRenderClearValues::Stencil); - // enable depth write for the clear below - theRenderContext.SetDepthWriteEnabled(true); - } - } - - theFB->Attach(NVRenderFrameBufferAttachments::Color0, **renderColorTexture, - thFboAttachTarget); - if (m_Layer.m_Background != LayerBackground::Unspecified) - theRenderContext.Clear(clearFlags); - - // We don't clear the depth buffer because the layer render code we are about to call - // will do this. - StartProfiling("Render pass", false); - Render(&theFB); - // Debug measure to view the depth map to ensure we're rendering it correctly. - //if (m_Layer.m_TemporalAAEnabled) { - // RenderFakeDepthMapPass(m_ShadowMapManager->GetShadowMapEntry(0)->m_DepthMap, - // m_ShadowMapManager->GetShadowMapEntry(0)->m_DepthCube); - //} - EndProfiling("Render pass"); - - // Now before going further, we downsample and resolve the multisample information. - // This allows all algorithms running after - // this point to run unchanged. - if (isMultisamplePass) { - if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) { - // Resolve the FBO to the layer texture - CRendererUtil::ResolveMutisampleFBOColorOnly( - theResourceManager, m_LayerTexture, theRenderContext, - theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), - ColorTextureFormat, *theFB); - - theRenderContext.SetMultisampleEnabled(false); - } else { - // Resolve the FBO to the layer texture - CRendererUtil::ResolveSSAAFBOColorOnly( - theResourceManager, m_LayerTexture, - theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), theRenderContext, - theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), - ColorTextureFormat, *theFB); - } - } - - // CN - when I tried to get anti-aliased widgets I lost all transparency on the widget - // layer which made it overwrite the object you were - // manipulating. When I tried to use parallel nsight on it the entire studio - // application crashed on startup. - if (NeedsWidgetTexture()) { - m_LayerWidgetTexture.EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - NVRenderTextureFormats::RGBA8); - theRenderContext.SetRenderTarget(theFB); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerWidgetTexture); - theFB->Attach(GetFramebufferDepthAttachmentFormat(DepthTextureFormat), - *m_LayerDepthTexture); - theRenderContext.SetClearColor(QT3DSVec4(0.0f)); - theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); - // We should already have the viewport and everything setup for this. - RenderRenderWidgets(); - } - - if (theLastLayerTexture.GetTexture() != NULL - && (isProgressiveAABlendPass || isTemporalAABlendPass)) { - theRenderContext.SetViewport( - NVRenderRect(0, 0, theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height())); - CResourceTexture2D targetTexture( - theResourceManager, theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), ColorTextureFormat); - theFB->Attach(theDepthAttachmentFormat, - NVRenderTextureOrRenderBuffer()); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *targetTexture); - QT3DSVec2 theBlendFactors; - if (isProgressiveAABlendPass) - theBlendFactors = s_BlendFactors[aaFactorIndex]; - else - theBlendFactors = QT3DSVec2(.5f, .5f); - - theRenderContext.SetDepthTestEnabled(false); - theRenderContext.SetBlendingEnabled(false); - theRenderContext.SetCullingEnabled(false); - theRenderContext.SetActiveShader(theBlendShader->m_Shader); - theBlendShader->m_AccumSampler.Set(theLastLayerTexture); - theBlendShader->m_LastFrame.Set(m_LayerTexture); - theBlendShader->m_BlendFactors.Set(theBlendFactors); - m_Renderer.RenderQuad(); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - if (isTemporalAABlendPass) - m_TemporalAATexture.StealTexture(m_LayerTexture); - m_LayerTexture.StealTexture(targetTexture); - } - - m_LayerTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - m_LayerTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - - // Don't remember why needs widget texture is false here. - // Should have commented why progAA plus widgets is a fail. - if (m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex - && NeedsWidgetTexture() == false) - ++m_ProgressiveAAPassIndex; - -// now we render all post effects -#ifdef QT3DS_CACHED_POST_EFFECT - ApplyLayerPostEffects(); -#endif - - if (m_LayerPrepassDepthTexture) { - // Detach any depth buffers. - theFB->Attach(theDepthAttachmentFormat, qt3ds::render::NVRenderTextureOrRenderBuffer(), - thFboAttachTarget); - } - - theFB->Attach(NVRenderFrameBufferAttachments::Color0, - qt3ds::render::NVRenderTextureOrRenderBuffer(), thFboAttachTarget); - // Let natural scoping rules destroy the other stuff. - } - } - - void SLayerRenderData::ApplyLayerPostEffects() - { - if (m_Layer.m_FirstEffect == NULL) { - if (m_LayerCachedTexture) { - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; - } - return; - } - - IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - // we use the non MSAA buffer for the effect - NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; - NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; - - NVRenderTexture2D *theCurrentTexture = theLayerColorTexture; - for (SEffect *theEffect = m_Layer.m_FirstEffect; theEffect; - theEffect = theEffect->m_NextEffect) { - if (theEffect->m_Flags.IsActive() && m_Camera) { - StartProfiling(theEffect->m_ClassName, false); - - NVRenderTexture2D *theRenderedEffect = theEffectSystem.RenderEffect( - SEffectRenderArgument(*theEffect, *theCurrentTexture, - QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), - theLayerDepthTexture, m_LayerPrepassDepthTexture)); - - EndProfiling(theEffect->m_ClassName); - - // If the texture came from rendering a chain of effects, then we don't need it - // after this. - if (theCurrentTexture != theLayerColorTexture) - theResourceManager.Release(*theCurrentTexture); - - theCurrentTexture = theRenderedEffect; - - if (!theRenderedEffect) { - QString errorMsg = QObject::tr("Failed to compile \"%1\" effect.\nConsider" - " removing it from the presentation.") - .arg(theEffect->m_ClassName.c_str()); - QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); - break; - } - } - } - - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; - } - - if (theCurrentTexture != m_LayerTexture) - m_LayerCachedTexture = theCurrentTexture; - } - - inline bool AnyCompletelyNonTransparentObjects(TRenderableObjectList &inObjects) - { - for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { - if (inObjects[idx]->m_RenderableFlags.IsCompletelyTransparent() == false) - return true; - } - return false; - } - - void SLayerRenderData::RunnableRenderToViewport(qt3ds::render::NVRenderFrameBuffer *theFB) - { - // If we have an effect, an opaque object, or any transparent objects that aren't completely - // transparent - // or an offscreen renderer or a layer widget texture - // Then we can't possible affect the resulting render target. - bool needsToRender = m_Layer.m_FirstEffect != NULL || m_OpaqueObjects.empty() == false - || AnyCompletelyNonTransparentObjects(m_TransparentObjects) || GetOffscreenRenderer() - || m_LayerWidgetTexture || m_BoundingRectColor.hasValue() - || m_Layer.m_Background == LayerBackground::Color; - - if (needsToRender == false) - return; - - NVRenderContext &theContext(m_Renderer.GetContext()); - theContext.resetStates(); - - NVRenderContextScopedProperty __fbo( - theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - qt3ds::render::NVRenderRect theCurrentViewport = theContext.GetViewport(); - NVRenderContextScopedProperty __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - NVRenderContextScopedProperty theScissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled); - NVRenderContextScopedProperty theScissorRect( - theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - NVRenderRectF theScreenRect(thePrepResult.GetLayerToPresentationViewport()); - - bool blendingEnabled = m_Layer.m_Background == LayerBackground::Transparent; - if (!thePrepResult.m_Flags.ShouldRenderToTexture()) { - theContext.SetViewport( - m_LayerPrepResult->GetLayerToPresentationViewport().ToIntegerRect()); - theContext.SetScissorTestEnabled(true); - theContext.SetScissorRect( - m_LayerPrepResult->GetLayerToPresentationScissorRect().ToIntegerRect()); - if (m_Layer.m_Background == LayerBackground::Color) { - NVRenderContextScopedProperty __clearColor( - theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - QT3DSVec4(m_Layer.m_ClearColor, 0.0f)); - theContext.Clear(NVRenderClearValues::Color); - } - RenderToViewport(); - } else { -// First, render the layer along with whatever progressive AA is appropriate. -// The render graph should have taken care of the render to texture step. -#ifdef QT3DS_CACHED_POST_EFFECT - NVRenderTexture2D *theLayerColorTexture = - (m_LayerCachedTexture) ? m_LayerCachedTexture : m_LayerTexture; -#else - // Then render all but the last effect - IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - // we use the non MSAA buffer for the effect - NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; - NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; - - NVRenderTexture2D *theCurrentTexture = theLayerColorTexture; - for (SEffect *theEffect = m_Layer.m_FirstEffect; - theEffect && theEffect != thePrepResult.m_LastEffect; - theEffect = theEffect->m_NextEffect) { - if (theEffect->m_Flags.IsActive() && m_Camera) { - StartProfiling(theEffect->m_ClassName, false); - - NVRenderTexture2D *theRenderedEffect = theEffectSystem.RenderEffect( - SEffectRenderArgument(*theEffect, *theCurrentTexture, - QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), - theLayerDepthTexture, m_LayerPrepassDepthTexture)); - - EndProfiling(theEffect->m_ClassName); - - // If the texture came from rendering a chain of effects, then we don't need it - // after this. - if (theCurrentTexture != theLayerColorTexture) - theResourceManager.Release(*theCurrentTexture); - - theCurrentTexture = theRenderedEffect; - } - } -#endif - // Now the last effect or straight to the scene if we have no last effect - // There are two cases we need to consider here. The first is when we shouldn't - // transform - // the result and thus we need to setup an MVP that just maps to the viewport width and - // height. - // The second is when we are expected to render to the scene using some global - // transform. - QT3DSMat44 theFinalMVP(QT3DSMat44::createIdentity()); - SCamera theTempCamera; - NVRenderRect theLayerViewport( - thePrepResult.GetLayerToPresentationViewport().ToIntegerRect()); - NVRenderRect theLayerClip( - thePrepResult.GetLayerToPresentationScissorRect().ToIntegerRect()); - - { - QT3DSMat33 ignored; - QT3DSMat44 theViewProjection; - // We could cache these variables - theTempCamera.m_Flags.SetOrthographic(true); - theTempCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - // Move the camera back far enough that we can see everything - QT3DSF32 theCameraSetback(10); - // Attempt to ensure the layer can never be clipped. - theTempCamera.m_Position.z = -theCameraSetback; - theTempCamera.m_ClipFar = 2.0f * theCameraSetback; - // Render the layer texture to the entire viewport. - SCameraGlobalCalculationResult theResult = theTempCamera.CalculateGlobalVariables( - theLayerViewport, - QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, (QT3DSF32)theLayerViewport.m_Height)); - theTempCamera.CalculateViewProjectionMatrix(theViewProjection); - SNode theTempNode; - theFinalMVP = theViewProjection; - qt3ds::render::NVRenderBlendFunctionArgument blendFunc; - qt3ds::render::NVRenderBlendEquationArgument blendEqu; - - switch (m_Layer.m_BlendType) { - case LayerBlendTypes::Screen: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - case LayerBlendTypes::Multiply: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::DstColor, NVRenderDstBlendFunc::Zero, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - case LayerBlendTypes::Add: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - case LayerBlendTypes::Subtract: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ReverseSubtract, - NVRenderBlendEquation::ReverseSubtract); - break; - case LayerBlendTypes::Overlay: - // SW fallback doesn't use blend equation - // note blend func is not used here anymore - if (theContext.IsAdvancedBlendHwSupported() || - theContext.IsAdvancedBlendHwSupportedKHR()) - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Overlay, NVRenderBlendEquation::Overlay); - break; - case LayerBlendTypes::ColorBurn: - // SW fallback doesn't use blend equation - // note blend func is not used here anymore - if (theContext.IsAdvancedBlendHwSupported() || - theContext.IsAdvancedBlendHwSupportedKHR()) - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorBurn, NVRenderBlendEquation::ColorBurn); - break; - case LayerBlendTypes::ColorDodge: - // SW fallback doesn't use blend equation - // note blend func is not used here anymore - if (theContext.IsAdvancedBlendHwSupported() || - theContext.IsAdvancedBlendHwSupportedKHR()) - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorDodge, NVRenderBlendEquation::ColorDodge); - break; - default: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - } - theContext.SetBlendFunction(blendFunc); - theContext.SetBlendEquation(blendEqu); - theContext.SetBlendingEnabled(blendingEnabled); - theContext.SetDepthTestEnabled(false); - } - - { - theContext.SetScissorTestEnabled(true); - theContext.SetViewport(theLayerViewport); - theContext.SetScissorRect(theLayerClip); - - // Remember the camera we used so we can get a valid pick ray - m_SceneCamera = theTempCamera; - theContext.SetDepthTestEnabled(false); -#ifndef QT3DS_CACHED_POST_EFFECT - if (thePrepResult.m_LastEffect && m_Camera) { - StartProfiling(thePrepResult.m_LastEffect->m_ClassName, false); - // inUseLayerMPV is true then we are rendering directly to the scene and thus we - // should enable blending - // for the final render pass. Else we should leave it. - theEffectSystem.RenderEffect( - SEffectRenderArgument(*thePrepResult.m_LastEffect, *theCurrentTexture, - QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), - theLayerDepthTexture, m_LayerPrepassDepthTexture), - theFinalMVP, blendingEnabled); - EndProfiling(thePrepResult.m_LastEffect->m_ClassName); - // If the texture came from rendering a chain of effects, then we don't need it - // after this. - if (theCurrentTexture != theLayerColorTexture) - theResourceManager.Release(*theCurrentTexture); - } else -#endif - { - theContext.SetCullingEnabled(false); - theContext.SetBlendingEnabled(blendingEnabled); - theContext.SetDepthTestEnabled(false); -#ifdef ADVANCED_BLEND_SW_FALLBACK - NVScopedRefCounted screenTexture = - m_Renderer.GetLayerBlendTexture(); - NVScopedRefCounted blendFB = m_Renderer.GetBlendFB(); - - // Layer blending for advanced blending modes if SW fallback is needed - // rendering to FBO and blending with separate shader - if (screenTexture) { - // Blending is enabled only if layer background has been chosen transparent - // Layers with advanced blending modes - if (blendingEnabled && (m_Layer.m_BlendType == LayerBlendTypes::Overlay || - m_Layer.m_BlendType == LayerBlendTypes::ColorBurn || - m_Layer.m_BlendType == LayerBlendTypes::ColorDodge)) { - theContext.SetScissorTestEnabled(false); - theContext.SetBlendingEnabled(false); - - // Get part matching to layer from screen texture and - // use that for blending - qt3ds::render::NVRenderTexture2D *blendBlitTexture; - blendBlitTexture = theContext.CreateTexture2D(); - blendBlitTexture->SetTextureData(NVDataRef(), 0, - theLayerViewport.m_Width, - theLayerViewport.m_Height, - NVRenderTextureFormats::RGBA8); - qt3ds::render::NVRenderFrameBuffer *blitFB; - blitFB = theContext.CreateFrameBuffer(); - blitFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*blendBlitTexture)); - blendFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*screenTexture)); - theContext.SetRenderTarget(blitFB); - theContext.SetReadTarget(blendFB); - theContext.SetReadBuffer(NVReadFaces::Color0); - theContext.BlitFramebuffer(theLayerViewport.m_X, theLayerViewport.m_Y, - theLayerViewport.m_Width + - theLayerViewport.m_X, - theLayerViewport.m_Height + - theLayerViewport.m_Y, - 0, 0, - theLayerViewport.m_Width, - theLayerViewport.m_Height, - NVRenderClearValues::Color, - NVRenderTextureMagnifyingOp::Nearest); - - qt3ds::render::NVRenderTexture2D *blendResultTexture; - blendResultTexture = theContext.CreateTexture2D(); - blendResultTexture->SetTextureData(NVDataRef(), 0, - theLayerViewport.m_Width, - theLayerViewport.m_Height, - NVRenderTextureFormats::RGBA8); - qt3ds::render::NVRenderFrameBuffer *resultFB; - resultFB = theContext.CreateFrameBuffer(); - resultFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*blendResultTexture)); - theContext.SetRenderTarget(resultFB); - - AdvancedBlendModes::Enum advancedMode; - switch (m_Layer.m_BlendType) { - case LayerBlendTypes::Overlay: - advancedMode = AdvancedBlendModes::Overlay; - break; - case LayerBlendTypes::ColorBurn: - advancedMode = AdvancedBlendModes::ColorBurn; - break; - case LayerBlendTypes::ColorDodge: - advancedMode = AdvancedBlendModes::ColorDodge; - break; - default: - advancedMode = AdvancedBlendModes::None; - break; - } - - theContext.SetViewport(NVRenderRect(0, 0, theLayerViewport.m_Width, - theLayerViewport.m_Height)); - BlendAdvancedEquationSwFallback(theLayerColorTexture, blendBlitTexture, - advancedMode); - blitFB->release(); - // save blending result to screen texture for use with other layers - theContext.SetViewport(theLayerViewport); - theContext.SetRenderTarget(blendFB); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *blendResultTexture); - // render the blended result - theContext.SetRenderTarget(theFB); - theContext.SetScissorTestEnabled(true); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *blendResultTexture); - resultFB->release(); - } else { - // Layers with normal blending modes - // save result for future use - theContext.SetViewport(theLayerViewport); - theContext.SetScissorTestEnabled(false); - theContext.SetBlendingEnabled(true); - theContext.SetRenderTarget(blendFB); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); - theContext.SetRenderTarget(theFB); - theContext.SetScissorTestEnabled(true); - theContext.SetViewport(theCurrentViewport); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); - } - } else { - // No advanced blending SW fallback needed - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); - } -#else - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); -#endif - } - if (m_LayerWidgetTexture) { - theContext.SetBlendingEnabled(false); - m_Renderer.SetupWidgetLayer(); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - NVRenderRectF thePresRect(thePrepResult.GetPresentationViewport()); - NVRenderRectF theLayerRect(thePrepResult.GetLayerToPresentationViewport()); - - // Ensure we remove any offsetting in the layer rect that was caused simply by - // the - // presentation rect offsetting but then use a new rect. - NVRenderRectF theWidgetLayerRect(theLayerRect.m_X - thePresRect.m_X, - theLayerRect.m_Y - thePresRect.m_Y, - theLayerRect.m_Width, theLayerRect.m_Height); - theContext.SetScissorTestEnabled(false); - theContext.SetViewport(theWidgetLayerRect.ToIntegerRect()); - m_Renderer.RenderQuad( - QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *m_LayerWidgetTexture); - } - } - } // End offscreen render code. - - if (m_BoundingRectColor.hasValue()) { - NVRenderContextScopedProperty __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - NVRenderContextScopedProperty theScissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled); - NVRenderContextScopedProperty theScissorRect( - theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); - m_Renderer.SetupWidgetLayer(); - // Setup a simple viewport to render to the entire presentation viewport. - theContext.SetViewport( - NVRenderRect(0, 0, (QT3DSU32)thePrepResult.GetPresentationViewport().m_Width, - (QT3DSU32)thePrepResult.GetPresentationViewport().m_Height)); - - NVRenderRectF thePresRect(thePrepResult.GetPresentationViewport()); - - // Remove any offsetting from the presentation rect since the widget layer is a - // stand-alone fbo. - NVRenderRectF theWidgetScreenRect(theScreenRect.m_X - thePresRect.m_X, - theScreenRect.m_Y - thePresRect.m_Y, - theScreenRect.m_Width, theScreenRect.m_Height); - theContext.SetScissorTestEnabled(false); - m_Renderer.DrawScreenRect(theWidgetScreenRect, *m_BoundingRectColor); - } - theContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); - theContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); - } - -#define RENDER_FRAME_NEW(type) QT3DS_NEW(m_Renderer.GetPerFrameAllocator(), type) - - void SLayerRenderData::AddLayerRenderStep() - { - SStackPerfTimer __perfTimer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::AddLayerRenderStep"); - QT3DS_ASSERT(m_Camera); - if (!m_Camera) - return; - - IRenderList &theGraph(m_Renderer.GetQt3DSContext().GetRenderList()); - - qt3ds::render::NVRenderRect theCurrentViewport = theGraph.GetViewport(); - if (!m_LayerPrepResult.hasValue()) - PrepareForRender( - QSize(theCurrentViewport.m_Width, theCurrentViewport.m_Height)); - } - - void SLayerRenderData::PrepareForRender() - { - // When we render to the scene itself (as opposed to an offscreen buffer somewhere) - // then we use the MVP of the layer somewhat. - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - PrepareForRender( - QSize((QT3DSU32)theViewport.m_Width, (QT3DSU32)theViewport.m_Height)); - } - - void SLayerRenderData::ResetForFrame() - { - SLayerRenderPreparationData::ResetForFrame(); - m_BoundingRectColor.setEmpty(); - } - - void SLayerRenderData::PrepareAndRender(const QT3DSMat44 &inViewProjection) - { - TRenderableObjectList theTransparentObjects(m_TransparentObjects); - TRenderableObjectList theOpaqueObjects(m_OpaqueObjects); - theTransparentObjects.clear(); - theOpaqueObjects.clear(); - m_ModelContexts.clear(); - SLayerRenderPreparationResultFlags theFlags; - PrepareRenderablesForRender(inViewProjection, Empty(), 1.0, theFlags); - RenderDepthPass(false); - Render(); - } - - struct SLayerRenderToTextureRunnable : public IRenderTask - { - SLayerRenderData &m_Data; - SLayerRenderToTextureRunnable(SLayerRenderData &d) - : m_Data(d) - { - } - - void Run() override { m_Data.RenderToTexture(); } - }; - - static inline OffscreenRendererDepthValues::Enum - GetOffscreenRendererDepthValue(NVRenderTextureFormats::Enum inBufferFormat) - { - switch (inBufferFormat) { - case NVRenderTextureFormats::Depth32: - return OffscreenRendererDepthValues::Depth32; - case NVRenderTextureFormats::Depth24: - return OffscreenRendererDepthValues::Depth24; - case NVRenderTextureFormats::Depth24Stencil8: - return OffscreenRendererDepthValues::Depth24; - default: - QT3DS_ASSERT(false); // fallthrough intentional - case NVRenderTextureFormats::Depth16: - return OffscreenRendererDepthValues::Depth16; - } - } - - SOffscreenRendererEnvironment SLayerRenderData::CreateOffscreenRenderEnvironment() - { - OffscreenRendererDepthValues::Enum theOffscreenDepth( - GetOffscreenRendererDepthValue(GetDepthBufferFormat())); - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - return SOffscreenRendererEnvironment(theViewport.m_Width, theViewport.m_Height, - NVRenderTextureFormats::RGBA8, theOffscreenDepth, - false, AAModeValues::NoAA); - } - - IRenderTask &SLayerRenderData::CreateRenderToTextureRunnable() - { - return *RENDER_FRAME_NEW(SLayerRenderToTextureRunnable)(*this); - } - - void SLayerRenderData::addRef() { atomicIncrement(&mRefCount); } - - void SLayerRenderData::release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Allocator); } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.h deleted file mode 100644 index 4e237b0b..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDERER_IMPL_LAYER_RENDER_DATA_H -#define QT3DS_RENDERER_IMPL_LAYER_RENDER_DATA_H -#include "Qt3DSRender.h" -#include "Qt3DSRendererImplLayerRenderPreparationData.h" -#include "Qt3DSRenderResourceBufferObjects.h" - -namespace qt3ds { -namespace render { - -struct AdvancedBlendModes -{ - enum Enum { - None = 0, - Overlay, - ColorBurn, - ColorDodge - }; -}; - struct QT3DS_AUTOTEST_EXPORT SLayerRenderData : public SLayerRenderPreparationData - { - - // Layers can be rendered offscreen for many reasons; effects, progressive aa, - // or just because a flag forces it. If they are rendered offscreen we can then - // cache the result so we don't render the layer again if it isn't dirty. - CResourceTexture2D m_LayerTexture; - CResourceTexture2D m_TemporalAATexture; - // Sometimes we need to render our depth buffer to a depth texture. - CResourceTexture2D m_LayerDepthTexture; - CResourceTexture2D m_LayerPrepassDepthTexture; - CResourceTexture2D m_LayerWidgetTexture; - CResourceTexture2D m_LayerSsaoTexture; - // if we render multisampled we need resolve buffers - CResourceTexture2D m_LayerMultisampleTexture; - CResourceTexture2D m_LayerMultisamplePrepassDepthTexture; - CResourceTexture2D m_LayerMultisampleWidgetTexture; - // the texture contains the render result inclusive post effects - NVRenderTexture2D *m_LayerCachedTexture; - - NVRenderTexture2D *m_AdvancedBlendDrawTexture; - NVRenderTexture2D *m_AdvancedBlendBlendTexture; - qt3ds::render::NVRenderFrameBuffer *m_AdvancedModeDrawFB; - qt3ds::render::NVRenderFrameBuffer *m_AdvancedModeBlendFB; - - // True if this layer was rendered offscreen. - // If this object has no value then this layer wasn't rendered at all. - SOffscreenRendererEnvironment m_LastOffscreenRenderEnvironment; - - // GPU profiler per layer - NVScopedRefCounted m_LayerProfilerGpu; - - SCamera m_SceneCamera; - QT3DSVec2 m_SceneDimensions; - - // ProgressiveAA algorithm details. - QT3DSU32 m_ProgressiveAAPassIndex; - // Increments every frame regardless to provide appropriate jittering - QT3DSU32 m_TemporalAAPassIndex; - // Ensures we don't stop on an in-between frame; we will run two frames after the dirty flag - // is clear. - QT3DSU32 m_NonDirtyTemporalAAPassIndex; - QT3DSF32 m_TextScale; - - volatile QT3DSI32 mRefCount; - Option m_BoundingRectColor; - NVRenderTextureFormats::Enum m_DepthBufferFormat; - - QSize m_previousDimensions; - - SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer); - - virtual ~SLayerRenderData(); - - void PrepareForRender(); - - // Internal Call - void PrepareForRender(const QSize &inViewportDimensions) override; - - NVRenderTextureFormats::Enum GetDepthBufferFormat(); - NVRenderFrameBufferAttachments::Enum - GetFramebufferDepthAttachmentFormat(NVRenderTextureFormats::Enum depthFormat); - - // Render this layer assuming viewport and RT are setup. Just renders exactly this item - // no effects. - void RenderDepthPass(bool inEnableTransparentDepthWrite = false); - void RenderAoPass(); - void RenderFakeDepthMapPass(NVRenderTexture2D *theDepthTex, - NVRenderTextureCube *theDepthCube); - void RenderShadowMapPass(CResourceFrameBuffer *theFB); - void RenderShadowCubeBlurPass(CResourceFrameBuffer *theFB, NVRenderTextureCube *target0, - NVRenderTextureCube *target1, QT3DSF32 filterSz, QT3DSF32 clipFar); - void RenderShadowMapBlurPass(CResourceFrameBuffer *theFB, NVRenderTexture2D *target0, - NVRenderTexture2D *target1, QT3DSF32 filterSz, QT3DSF32 clipFar); - - void Render(CResourceFrameBuffer *theFB = NULL); - void ResetForFrame() override; - - void CreateGpuProfiler(); - void StartProfiling(CRegisteredString &nameID, bool sync); - void EndProfiling(CRegisteredString &nameID); - void StartProfiling(const char *nameID, bool sync); - void EndProfiling(const char *nameID); - void AddVertexCount(QT3DSU32 count); - - void RenderToViewport(); - // Render this layer's data to a texture. Required if we have any effects, - // prog AA, or if forced. - void RenderToTexture(); - - void ApplyLayerPostEffects(); - - void RunnableRenderToViewport(qt3ds::render::NVRenderFrameBuffer *theFB); - - void AddLayerRenderStep(); - - void RenderRenderWidgets(); - -#ifdef ADVANCED_BLEND_SW_FALLBACK - void BlendAdvancedEquationSwFallback(NVRenderTexture2D *drawTexture, - NVRenderTexture2D *m_LayerTexture, - AdvancedBlendModes::Enum blendMode); -#endif - // test method to render this layer to a given view projection without running the entire - // layer setup system. This assumes the client has setup the viewport, scissor, and render - // target - // the way they want them. - void PrepareAndRender(const QT3DSMat44 &inViewProjection); - - SOffscreenRendererEnvironment CreateOffscreenRenderEnvironment() override; - IRenderTask &CreateRenderToTextureRunnable() override; - - void addRef(); - void release(); - - protected: - // Used for both the normal passes and the depth pass. - // When doing the depth pass, we disable blending completely because it does not really make - // sense - // to write blend equations into - void RunRenderPass(TRenderRenderableFunction renderFn, bool inEnableBlending, - bool inEnableDepthWrite, bool inEnableTransparentDepthWrite, - QT3DSU32 indexLight, const SCamera &inCamera, - CResourceFrameBuffer *theFB = NULL); -#ifdef ADVANCED_BLEND_SW_FALLBACK - //Functions for advanced blending mode fallback - void SetupDrawFB(bool depthEnabled); - void BlendAdvancedToFB(DefaultMaterialBlendMode::Enum blendMode, bool depthEnabled, - CResourceFrameBuffer *theFB); -#endif - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.cpp deleted file mode 100644 index 8a050db0..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRendererImplLayerRenderHelper.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSTextRenderer.h" - -using namespace qt3ds::render; - -namespace { -// left/top -QT3DSF32 GetMinValue(QT3DSF32 start, QT3DSF32 width, QT3DSF32 value, LayerUnitTypes::Enum units) -{ - if (units == LayerUnitTypes::Pixels) - return start + value; - - return start + (value * width / 100.0f); -} - -// width/height -QT3DSF32 GetValueLen(QT3DSF32 width, QT3DSF32 value, LayerUnitTypes::Enum units) -{ - if (units == LayerUnitTypes::Pixels) - return value; - - return width * value / 100.0f; -} - -// right/bottom -QT3DSF32 GetMaxValue(QT3DSF32 start, QT3DSF32 width, QT3DSF32 value, LayerUnitTypes::Enum units) -{ - if (units == LayerUnitTypes::Pixels) - return start + width - value; - - return start + width - (value * width / 100.0f); -} - -QT3DSVec2 ToRectRelativeCoords(const QT3DSVec2 &inCoords, const NVRenderRectF &inRect) -{ - return QT3DSVec2(inCoords.x - inRect.m_X, inCoords.y - inRect.m_Y); -} -} - -SLayerRenderHelper::SLayerRenderHelper() - : m_Layer(NULL) - , m_Camera(NULL) - , m_Offscreen(false) -{ -} - -SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewport, - const NVRenderRectF &inPresentationScissor, - const QT3DSVec2 &inPresentationDesignDimensions, - SLayer &inLayer, bool inOffscreen, - qt3ds::render::ScaleModes::Enum inScaleMode, - qt3ds::QT3DSVec2 inScaleFactor) - : m_PresentationViewport(inPresentationViewport) - , m_PresentationScissor(inPresentationScissor) - , m_PresentationDesignDimensions(inPresentationDesignDimensions) - , m_Layer(&inLayer) - , m_Offscreen(inOffscreen) - , m_ScaleMode(inScaleMode) - , m_ScaleFactor(inScaleFactor) -{ - { - QT3DSF32 left = m_Layer->m_Left; - QT3DSF32 right = m_Layer->m_Right; - QT3DSF32 width = m_Layer->m_Width; - - if (m_ScaleMode == qt3ds::render::ScaleModes::FitSelected) { - if (m_Layer->m_LeftUnits == LayerUnitTypes::Pixels) - left *= m_ScaleFactor.x; - - if (m_Layer->m_RightUnits == LayerUnitTypes::Pixels) - right *= m_ScaleFactor.x; - - if (m_Layer->m_WidthUnits == LayerUnitTypes::Pixels) - width *= m_ScaleFactor.x; - } - - QT3DSF32 horzMin = GetMinValue(inPresentationViewport.m_X, inPresentationViewport.m_Width, - left, m_Layer->m_LeftUnits); - QT3DSF32 horzWidth = GetValueLen(inPresentationViewport.m_Width, width, m_Layer->m_WidthUnits); - QT3DSF32 horzMax = GetMaxValue(inPresentationViewport.m_X, inPresentationViewport.m_Width, - right, m_Layer->m_RightUnits); - - switch (inLayer.m_HorizontalFieldValues) { - case HorizontalFieldValues::LeftWidth: - m_Viewport.m_X = horzMin; - m_Viewport.m_Width = horzWidth; - break; - case HorizontalFieldValues::LeftRight: - m_Viewport.m_X = horzMin; - m_Viewport.m_Width = horzMax - horzMin; - break; - case HorizontalFieldValues::WidthRight: - m_Viewport.m_Width = horzWidth; - m_Viewport.m_X = horzMax - horzWidth; - break; - } - } - { - QT3DSF32 top = m_Layer->m_Top; - QT3DSF32 bottom = m_Layer->m_Bottom; - QT3DSF32 height = m_Layer->m_Height; - - if (m_ScaleMode == qt3ds::render::ScaleModes::FitSelected) { - - if (m_Layer->m_TopUnits == LayerUnitTypes::Pixels) - top *= m_ScaleFactor.y; - - if (m_Layer->m_BottomUnits == LayerUnitTypes::Pixels) - bottom *= m_ScaleFactor.y; - - if (m_Layer->m_HeightUnits == LayerUnitTypes::Pixels) - height *= m_ScaleFactor.y; - } - - QT3DSF32 vertMin = GetMinValue(inPresentationViewport.m_Y, inPresentationViewport.m_Height, - bottom, m_Layer->m_BottomUnits); - QT3DSF32 vertWidth = - GetValueLen(inPresentationViewport.m_Height, height, m_Layer->m_HeightUnits); - QT3DSF32 vertMax = GetMaxValue(inPresentationViewport.m_Y, inPresentationViewport.m_Height, - top, m_Layer->m_TopUnits); - - switch (inLayer.m_VerticalFieldValues) { - case VerticalFieldValues::HeightBottom: - m_Viewport.m_Y = vertMin; - m_Viewport.m_Height = vertWidth; - break; - case VerticalFieldValues::TopBottom: - m_Viewport.m_Y = vertMin; - m_Viewport.m_Height = vertMax - vertMin; - break; - case VerticalFieldValues::TopHeight: - m_Viewport.m_Height = vertWidth; - m_Viewport.m_Y = vertMax - vertWidth; - break; - } - } - - m_Viewport.m_Width = NVMax(1.0f, m_Viewport.m_Width); - m_Viewport.m_Height = NVMax(1.0f, m_Viewport.m_Height); - // Now force the viewport to be a multiple of four in width and height. This is because - // when rendering to a texture we have to respect this and not forcing it causes scaling issues - // that are noticeable especially in situations where customers are using text and such. - QT3DSF32 originalWidth = m_Viewport.m_Width; - QT3DSF32 originalHeight = m_Viewport.m_Height; - - m_Viewport.m_Width = (QT3DSF32)ITextRenderer::NextMultipleOf4((QT3DSU32)m_Viewport.m_Width); - m_Viewport.m_Height = (QT3DSF32)ITextRenderer::NextMultipleOf4((QT3DSU32)m_Viewport.m_Height); - - // Now fudge the offsets to account for this slight difference - m_Viewport.m_X += (originalWidth - m_Viewport.m_Width) / 2.0f; - m_Viewport.m_Y += (originalHeight - m_Viewport.m_Height) / 2.0f; - - m_Scissor = m_Viewport; - m_Scissor.EnsureInBounds(inPresentationScissor); - QT3DS_ASSERT(m_Scissor.m_Width >= 0.0f); - QT3DS_ASSERT(m_Scissor.m_Height >= 0.0f); -} - -// This is the viewport the camera will use to setup the projection. -NVRenderRectF SLayerRenderHelper::GetLayerRenderViewport() const -{ - if (m_Offscreen) - return NVRenderRectF(0, 0, m_Viewport.m_Width, (QT3DSF32)m_Viewport.m_Height); - else - return m_Viewport; -} - -QSize SLayerRenderHelper::GetTextureDimensions() const -{ - QT3DSU32 width = (QT3DSU32)m_Viewport.m_Width; - QT3DSU32 height = (QT3DSU32)m_Viewport.m_Height; - return QSize(ITextRenderer::NextMultipleOf4(width), - ITextRenderer::NextMultipleOf4(height)); -} - -SCameraGlobalCalculationResult SLayerRenderHelper::SetupCameraForRender(SCamera &inCamera) -{ - m_Camera = &inCamera; - NVRenderRectF rect = GetLayerRenderViewport(); - if (m_ScaleMode == ScaleModes::FitSelected) { - rect.m_Width = - (QT3DSF32)(ITextRenderer::NextMultipleOf4((QT3DSU32)(rect.m_Width / m_ScaleFactor.x))); - rect.m_Height = - (QT3DSF32)(ITextRenderer::NextMultipleOf4((QT3DSU32)(rect.m_Height / m_ScaleFactor.y))); - } - return m_Camera->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); -} - -Option SLayerRenderHelper::GetLayerMouseCoords(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inWindowDimensions, - bool inForceIntersect) const -{ - // First invert the y so we are dealing with numbers in a normal coordinate space. - // Second, move into our layer's coordinate space - QT3DSVec2 correctCoords(inMouseCoords.x, inWindowDimensions.y - inMouseCoords.y); - QT3DSVec2 theLocalMouse = m_Viewport.ToRectRelative(correctCoords); - - QT3DSF32 theRenderRectWidth = m_Viewport.m_Width; - QT3DSF32 theRenderRectHeight = m_Viewport.m_Height; - // Crop the mouse to the rect. Apply no further translations. - if (inForceIntersect == false - && (theLocalMouse.x < 0.0f || theLocalMouse.x >= theRenderRectWidth - || theLocalMouse.y < 0.0f || theLocalMouse.y >= theRenderRectHeight)) { - return Empty(); - } - return theLocalMouse; -} - -Option SLayerRenderHelper::GetPickRay(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inWindowDimensions, - bool inForceIntersect) const -{ - if (m_Camera == NULL) - return Empty(); - Option theCoords( - GetLayerMouseCoords(inMouseCoords, inWindowDimensions, inForceIntersect)); - if (theCoords.hasValue()) { - // The cameras projection is different if we are onscreen vs. offscreen. - // When offscreen, we need to move the mouse coordinates into a local space - // to the layer. - return m_Camera->Unproject(*theCoords, m_Viewport, m_PresentationDesignDimensions); - } - return Empty(); -} - -bool SLayerRenderHelper::IsLayerVisible() const -{ - return m_Scissor.m_Height >= 2.0f && m_Scissor.m_Width >= 2.0f; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.h deleted file mode 100644 index 8ee4ff73..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderHelper.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#include "Qt3DSRender.h" -#include "foundation/Qt3DSVec2.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderContextCore.h" - -namespace qt3ds { -namespace render { - - /** An independent, testable entity to encapsulate taking at least: - * layer, current viewport rect, current scissor rect, presentation design dimensions - * and producing a set of rectangles: - * layer viewport rect (inside viewport rect and calculated using outer viewport rect info) - * layer scissor rect (inside current scissor rect) - * layer camera rect (may be the viewport rect) - * - * In the case where we have to render offscreen for this layer then we need to handle produce - * a set of texture dimensions and the layer camera rect ends up being same size but with no - *offsets. - * - * This object should handle part of any translation from screenspace to global space. - * I am using language level access control on this object because it needs specific - * interface design that will enable future modifications. - */ - struct SLayerRenderHelper - { - private: - NVRenderRectF m_PresentationViewport; - NVRenderRectF m_PresentationScissor; - QT3DSVec2 m_PresentationDesignDimensions; - SLayer *m_Layer; - SCamera *m_Camera; - bool m_Offscreen; - - NVRenderRectF m_Viewport; - NVRenderRectF m_Scissor; - - ScaleModes::Enum m_ScaleMode; - QT3DSVec2 m_ScaleFactor; - - public: - SLayerRenderHelper(); - - SLayerRenderHelper(const NVRenderRectF &inPresentationViewport, - const NVRenderRectF &inPresentationScissor, - const QT3DSVec2 &inPresentationDesignDimensions, SLayer &inLayer, - bool inOffscreen, qt3ds::render::ScaleModes::Enum inScaleMode, - qt3ds::QT3DSVec2 inScaleFactor); - - NVRenderRectF GetPresentationViewport() const { return m_PresentationViewport; } - NVRenderRectF GetPresentationScissor() const { return m_PresentationScissor; } - QT3DSVec2 GetPresentationDesignDimensions() const { return m_PresentationDesignDimensions; } - SLayer *GetLayer() const { return m_Layer; } - SCamera *GetCamera() const { return m_Camera; } - bool IsOffscreen() const { return m_Offscreen; } - - // Does not differ whether offscreen or not, simply states how this layer maps to the - // presentation - NVRenderRectF GetLayerToPresentationViewport() const { return m_Viewport; } - // Does not differ whether offscreen or not, scissor rect of how this layer maps to - // presentation. - NVRenderRectF GetLayerToPresentationScissorRect() const { return m_Scissor; } - - QSize GetTextureDimensions() const; - - SCameraGlobalCalculationResult SetupCameraForRender(SCamera &inCamera); - - Option GetLayerMouseCoords(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inWindowDimensions, - bool inForceIntersect) const; - - Option GetPickRay(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inWindowDimensions, - bool inForceIntersect) const; - - // Checks the various viewports and determines if the layer is visible or not. - bool IsLayerVisible() const; - - private: - // Viewport used when actually rendering. In the case where this is an offscreen item then - // it may be - // different than the layer to presentation viewport. - NVRenderRectF GetLayerRenderViewport() const; - }; -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp deleted file mode 100644 index 68ed9907..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp +++ /dev/null @@ -1,1446 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRender.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRendererImpl.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderEffect.h" -#include "EASTL/sort.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderPresentation.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderResourceManager.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderEffectSystem.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "Qt3DSOffscreenRenderKey.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderPluginGraphObject.h" -#include "Qt3DSRenderResourceBufferObjects.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSRenderMaterialHelpers.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderTextTextureCache.h" -#include "Qt3DSRenderTextTextureAtlas.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderPathManager.h" - -#ifdef _WIN32 -#pragma warning(disable : 4355) -#endif -namespace qt3ds { -namespace render { - using eastl::reverse; - using eastl::stable_sort; - using qt3ds::render::NVRenderContextScopedProperty; - using qt3ds::QT3DSVec2; - - namespace { - void MaybeQueueNodeForRender(SNode &inNode, nvvector &outRenderables, - nvvector &outCamerasAndLights, QT3DSU32 &ioDFSIndex) - { - ++ioDFSIndex; - inNode.m_DFSIndex = ioDFSIndex; - if (GraphObjectTypes::IsRenderableType(inNode.m_Type)) - outRenderables.push_back(inNode); - else if (GraphObjectTypes::IsLightCameraType(inNode.m_Type)) - outCamerasAndLights.push_back(&inNode); - - for (SNode *theChild = inNode.m_FirstChild; theChild != NULL; - theChild = theChild->m_NextSibling) - MaybeQueueNodeForRender(*theChild, outRenderables, outCamerasAndLights, ioDFSIndex); - } - - bool HasValidLightProbe(SImage *inLightProbeImage) - { - return inLightProbeImage && inLightProbeImage->m_TextureData.m_Texture; - } - } - - SDefaultMaterialPreparationResult::SDefaultMaterialPreparationResult( - SShaderDefaultMaterialKey inKey) - : m_FirstImage(NULL) - , m_Opacity(1.0f) - , m_MaterialKey(inKey) - , m_Dirty(false) - { - } - -#define MAX_AA_LEVELS 8 - - SLayerRenderPreparationData::SLayerRenderPreparationData(SLayer &inLayer, - Qt3DSRendererImpl &inRenderer) - : m_Layer(inLayer) - , m_Renderer(inRenderer) - , m_Allocator(inRenderer.GetContext().GetAllocator()) - , m_RenderableNodeLightEntryPool( - ForwardingAllocator(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_RenderableNodes")) - , m_RenderableNodes(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_RenderableNodes") - , m_LightToNodeMap(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_LightToNodeMap") - , m_CamerasAndLights(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_CamerasAndLights") - , m_Camera(NULL) - , m_Lights(inRenderer.GetContext().GetAllocator(), "SLayerRenderPreparationData::m_Lights") - , m_OpaqueObjects(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_OpaqueObjects") - , m_TransparentObjects(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_TransparentObjects") - , m_RenderedOpaqueObjects(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_RenderedOpaqueObjects") - , m_RenderedTransparentObjects(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_RenderedTransparentObjects") - , m_IRenderWidgets(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_IRenderWidgets") - , m_SourceLightDirections(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_SourceLightDirections") - , m_LightDirections(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_LightDirections") - , m_ModelContexts(inRenderer.GetContext().GetAllocator(), - "SLayerRenderPreparationData::m_ModelContexts") - , m_CGLightingFeatureName( - inRenderer.GetContext().GetStringTable().RegisterStr("QT3DS_ENABLE_CG_LIGHTING")) - , m_FeaturesDirty(true) - , m_FeatureSetHash(0) - , m_TooManyLightsError(false) - { - } - - SLayerRenderPreparationData::~SLayerRenderPreparationData() {} - - bool SLayerRenderPreparationData::NeedsWidgetTexture() const - { - return m_IRenderWidgets.size() > 0; - } - - void SLayerRenderPreparationData::SetShaderFeature(CRegisteredString theStr, bool inValue) - { - SShaderPreprocessorFeature item(theStr, inValue); - eastl::vector::iterator iter = m_Features.begin(), - end = m_Features.end(); - - // empty loop intentional. - for (; iter != end && ((iter->m_Name == theStr) == false); ++iter) - ; - - if (iter != end) { - if (iter->m_Enabled != inValue) { - iter->m_Enabled = inValue; - m_FeaturesDirty = true; - m_FeatureSetHash = 0; - } - } else { - m_Features.push_back(item); - m_FeaturesDirty = true; - m_FeatureSetHash = 0; - } - } - - void SLayerRenderPreparationData::SetShaderFeature(const char *inName, bool inValue) - { - CRegisteredString theStr(m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(inName)); - SetShaderFeature(theStr, inValue); - } - - NVConstDataRef SLayerRenderPreparationData::GetShaderFeatureSet() - { - if (m_FeaturesDirty) { - eastl::sort(m_Features.begin(), m_Features.end()); - m_FeaturesDirty = false; - } - return toConstDataRef(m_Features.data(), (QT3DSU32)m_Features.size()); - } - - size_t SLayerRenderPreparationData::GetShaderFeatureSetHash() - { - if (!m_FeatureSetHash) - m_FeatureSetHash = HashShaderFeatureSet(GetShaderFeatureSet()); - return m_FeatureSetHash; - } - - bool SLayerRenderPreparationData::GetShadowMapManager() - { - if (m_ShadowMapManager.mPtr) - return true; - - m_ShadowMapManager.mPtr = Qt3DSShadowMap::Create(m_Renderer.GetQt3DSContext()); - - return m_ShadowMapManager.mPtr != NULL; - } - - bool SLayerRenderPreparationData::GetOffscreenRenderer() - { - if (m_LastFrameOffscreenRenderer.mPtr) - return true; - - if (m_Layer.m_RenderPlugin && m_Layer.m_RenderPlugin->m_Flags.IsActive()) { - IRenderPluginInstance *theInstance = - m_Renderer.GetQt3DSContext().GetRenderPluginManager().GetOrCreateRenderPluginInstance( - m_Layer.m_RenderPlugin->m_PluginPath, m_Layer.m_RenderPlugin); - if (theInstance) { - m_Renderer.GetQt3DSContext() - .GetOffscreenRenderManager() - .MaybeRegisterOffscreenRenderer(&theInstance, *theInstance); - m_LastFrameOffscreenRenderer = theInstance; - } - } - if (m_LastFrameOffscreenRenderer.mPtr == NULL) - m_LastFrameOffscreenRenderer = - m_Renderer.GetQt3DSContext().GetOffscreenRenderManager().GetOffscreenRenderer( - m_Layer.m_TexturePath); - return m_LastFrameOffscreenRenderer.mPtr != NULL; - } - - QT3DSVec3 SLayerRenderPreparationData::GetCameraDirection() - { - if (m_CameraDirection.hasValue() == false) { - if (m_Camera) - m_CameraDirection = m_Camera->GetScalingCorrectDirection(); - else - m_CameraDirection = QT3DSVec3(0, 0, -1); - } - return *m_CameraDirection; - } - - // Per-frame cache of renderable objects post-sort. - NVDataRef SLayerRenderPreparationData::GetOpaqueRenderableObjects() - { - if (m_RenderedOpaqueObjects.empty() == false || m_Camera == NULL) - return m_RenderedOpaqueObjects; - if (m_Layer.m_Flags.IsLayerEnableDepthTest() && m_OpaqueObjects.empty() == false) { - QT3DSVec3 theCameraDirection(GetCameraDirection()); - QT3DSVec3 theCameraPosition = m_Camera->GetGlobalPos(); - m_RenderedOpaqueObjects.assign(m_OpaqueObjects.begin(), m_OpaqueObjects.end()); - // Setup the object's sorting information - for (QT3DSU32 idx = 0, end = m_RenderedOpaqueObjects.size(); idx < end; ++idx) { - SRenderableObject &theInfo = *m_RenderedOpaqueObjects[idx]; - QT3DSVec3 difference = theInfo.m_WorldCenterPoint - theCameraPosition; - theInfo.m_CameraDistanceSq = difference.dot(theCameraDirection); - } - - ForwardingAllocator alloc(m_Renderer.GetPerFrameAllocator(), "SortAllocations"); - // Render nearest to furthest objects - eastl::merge_sort(m_RenderedOpaqueObjects.begin(), m_RenderedOpaqueObjects.end(), alloc, - ISRenderObjectPtrLessThan); - } - return m_RenderedOpaqueObjects; - } - - // If layer depth test is false, this may also contain opaque objects. - NVDataRef SLayerRenderPreparationData::GetTransparentRenderableObjects() - { - if (m_RenderedTransparentObjects.empty() == false || m_Camera == NULL) - return m_RenderedTransparentObjects; - - m_RenderedTransparentObjects.assign(m_TransparentObjects.begin(), - m_TransparentObjects.end()); - - if (m_Layer.m_Flags.IsLayerEnableDepthTest() == false) - m_RenderedTransparentObjects.insert(m_RenderedTransparentObjects.end(), - m_OpaqueObjects.begin(), m_OpaqueObjects.end()); - - if (m_RenderedTransparentObjects.empty() == false) { - QT3DSVec3 theCameraDirection(GetCameraDirection()); - QT3DSVec3 theCameraPosition = m_Camera->GetGlobalPos(); - - // Setup the object's sorting information - for (QT3DSU32 idx = 0, end = m_RenderedTransparentObjects.size(); idx < end; ++idx) { - SRenderableObject &theInfo = *m_RenderedTransparentObjects[idx]; - QT3DSVec3 difference = theInfo.m_WorldCenterPoint - theCameraPosition; - theInfo.m_CameraDistanceSq = difference.dot(theCameraDirection); - } - ForwardingAllocator alloc(m_Renderer.GetPerFrameAllocator(), "SortAllocations"); - // render furthest to nearest. - eastl::merge_sort(m_RenderedTransparentObjects.begin(), - m_RenderedTransparentObjects.end(), alloc, - ISRenderObjectPtrGreatThan); - } - - return m_RenderedTransparentObjects; - } - -#define MAX_LAYER_WIDGETS 200 - - void SLayerRenderPreparationData::AddRenderWidget(IRenderWidget &inWidget) - { - // The if the layer is not active then the widget can't be displayed. - // Furthermore ResetForFrame won't be called below which leads to stale - // widgets in the m_IRenderWidgets array. These stale widgets would get rendered - // the next time the layer was active potentially causing a crash. - if (!m_Layer.m_Flags.IsActive()) - return; - - // Ensure we clear the widget layer always - m_Renderer.LayerNeedsFrameClear(*static_cast(this)); - - if (m_IRenderWidgets.size() < MAX_LAYER_WIDGETS) - m_IRenderWidgets.push_back(&inWidget); - } - -#define RENDER_FRAME_NEW(type) QT3DS_NEW(m_Renderer.GetPerFrameAllocator(), type) - -#define QT3DS_RENDER_MINIMUM_RENDER_OPACITY .01f - - SShaderDefaultMaterialKey - SLayerRenderPreparationData::GenerateLightingKey(DefaultMaterialLighting::Enum inLightingType) - { - SShaderDefaultMaterialKey theGeneratedKey(GetShaderFeatureSetHash()); - const bool lighting = inLightingType != DefaultMaterialLighting::NoLighting; - m_Renderer.DefaultMaterialShaderKeyProperties().m_HasLighting.SetValue(theGeneratedKey, - lighting); - if (lighting) { - const bool lightProbe = m_Layer.m_LightProbe - && m_Layer.m_LightProbe->m_TextureData.m_Texture; - m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(theGeneratedKey, - lightProbe); - - QT3DSU32 numLights = (QT3DSU32)m_Lights.size(); - if (numLights > SShaderDefaultMaterialKeyProperties::LightCount - && m_TooManyLightsError == false) { - m_TooManyLightsError = true; - numLights = SShaderDefaultMaterialKeyProperties::LightCount; - qCCritical(INVALID_OPERATION, "Too many lights on layer, max is 7"); - QT3DS_ASSERT(false); - } - m_Renderer.DefaultMaterialShaderKeyProperties().m_LightCount.SetValue(theGeneratedKey, - numLights); - - for (QT3DSU32 lightIdx = 0, lightEnd = m_Lights.size(); - lightIdx < lightEnd; ++lightIdx) { - SLight *theLight(m_Lights[lightIdx]); - const bool isDirectional = theLight->m_LightType == RenderLightTypes::Directional; - const bool isArea = theLight->m_LightType == RenderLightTypes::Area; - const bool castShadowsArea = (theLight->m_LightType != RenderLightTypes::Area) - && (theLight->m_CastShadow); - - m_Renderer.DefaultMaterialShaderKeyProperties().m_LightFlags[lightIdx] - .SetValue(theGeneratedKey, !isDirectional); - m_Renderer.DefaultMaterialShaderKeyProperties().m_LightAreaFlags[lightIdx] - .SetValue(theGeneratedKey, isArea); - m_Renderer.DefaultMaterialShaderKeyProperties().m_LightShadowFlags[lightIdx] - .SetValue(theGeneratedKey, castShadowsArea); - } - } - return theGeneratedKey; - } - - bool SLayerRenderPreparationData::PrepareTextForRender( - SText &inText, const QT3DSMat44 &inViewProjection, QT3DSF32 inTextScaleFactor, - SLayerRenderPreparationResultFlags &ioFlags) - { - ITextTextureCache *theTextRenderer = m_Renderer.GetQt3DSContext().GetTextureCache(); - if (theTextRenderer == NULL) - return false; - - SRenderableObjectFlags theFlags; - theFlags.SetHasTransparency(true); - theFlags.SetCompletelyTransparent(inText.m_GlobalOpacity < .01f); - theFlags.SetPickable(true); - bool retval = false; - - if (theFlags.IsCompletelyTransparent() == false) { - retval = inText.m_Flags.IsDirty() || inText.m_Flags.IsTextDirty(); - inText.m_Flags.SetTextDirty(false); - TTPathObjectAndTexture theResult = - theTextRenderer->RenderText(inText, inTextScaleFactor); - inText.m_TextTexture = theResult.second.second.mPtr; - inText.m_TextTextureDetails = theResult.second.first; - inText.m_PathFontItem = theResult.first.second; - inText.m_PathFontDetails = theResult.first.first; - STextScaleAndOffset theScaleAndOffset(*inText.m_TextTexture, - inText.m_TextTextureDetails, inText); - QT3DSVec2 theTextScale(theScaleAndOffset.m_TextScale); - QT3DSVec2 theTextOffset(theScaleAndOffset.m_TextOffset); - QT3DSVec3 minimum(theTextOffset[0] - theTextScale[0], theTextOffset[1] - theTextScale[1], - 0); - QT3DSVec3 maximum(theTextOffset[0] + theTextScale[0], theTextOffset[1] + theTextScale[1], - 0); - inText.m_Bounds = NVBounds3(minimum, maximum); - QT3DSMat44 theMVP; - QT3DSMat33 theNormalMatrix; - inText.CalculateMVPAndNormalMatrix(inViewProjection, theMVP, theNormalMatrix); - - if (inText.m_PathFontDetails) - ioFlags.SetRequiresStencilBuffer(true); - - STextRenderable *theRenderable = RENDER_FRAME_NEW(STextRenderable)( - theFlags, inText.GetGlobalPos(), m_Renderer, inText, inText.m_Bounds, theMVP, - inViewProjection, *inText.m_TextTexture, theTextOffset, theTextScale); - m_TransparentObjects.push_back(theRenderable); - } - return retval; - } - - eastl::pair - SLayerRenderPreparationData::ResolveReferenceMaterial(SGraphObject *inMaterial) - { - bool subsetDirty = false; - bool badIdea = false; - SGraphObject *theSourceMaterialObject(inMaterial); - SGraphObject *theMaterialObject(inMaterial); - while (theMaterialObject - && theMaterialObject->m_Type == GraphObjectTypes::ReferencedMaterial && !badIdea) { - SReferencedMaterial *theRefMaterial = - static_cast(theMaterialObject); - theMaterialObject = theRefMaterial->m_ReferencedMaterial; - if (theMaterialObject == theSourceMaterialObject) { - badIdea = true; - } - - if (theRefMaterial == theSourceMaterialObject) { - theRefMaterial->m_Dirty.UpdateDirtyForFrame(); - } - subsetDirty = subsetDirty | theRefMaterial->m_Dirty.IsDirty(); - } - if (badIdea) { - theMaterialObject = NULL; - } - return eastl::make_pair(subsetDirty, theMaterialObject); - } - - bool SLayerRenderPreparationData::PreparePathForRender( - SPath &inPath, const QT3DSMat44 &inViewProjection, - const Option &inClipFrustum, SLayerRenderPreparationResultFlags &ioFlags) - { - SRenderableObjectFlags theSharedFlags; - theSharedFlags.SetPickable(true); - QT3DSF32 subsetOpacity = inPath.m_GlobalOpacity; - bool retval = inPath.m_Flags.IsDirty(); - inPath.m_Flags.SetDirty(false); - QT3DSMat44 theMVP; - QT3DSMat33 theNormalMatrix; - - inPath.CalculateMVPAndNormalMatrix(inViewProjection, theMVP, theNormalMatrix); - NVBounds3 theBounds(this->m_Renderer.GetQt3DSContext().GetPathManager().GetBounds(inPath)); - - if (inPath.m_GlobalOpacity >= QT3DS_RENDER_MINIMUM_RENDER_OPACITY - && inClipFrustum.hasValue()) { - // Check bounding box against the clipping planes - NVBounds3 theGlobalBounds = theBounds; - theGlobalBounds.transform(inPath.m_GlobalTransform); - if (inClipFrustum->intersectsWith(theGlobalBounds) == false) - subsetOpacity = 0.0f; - } - - SGraphObject *theMaterials[2] = { inPath.m_Material, inPath.m_SecondMaterial }; - - if (inPath.m_PathType == PathTypes::Geometry - || inPath.m_PaintStyle != PathPaintStyles::FilledAndStroked) - theMaterials[1] = NULL; - - // We need to fill material to be the first one rendered so the stroke goes on top. - // In the timeline, however, this is reversed. - - if (theMaterials[1]) - eastl::swap(theMaterials[1], theMaterials[0]); - - for (QT3DSU32 idx = 0, end = 2; idx < end; ++idx) { - if (theMaterials[idx] == NULL) - continue; - - SRenderableObjectFlags theFlags = theSharedFlags; - - eastl::pair theMaterialAndDirty( - ResolveReferenceMaterial(theMaterials[idx])); - SGraphObject *theMaterial(theMaterialAndDirty.second); - retval = retval || theMaterialAndDirty.first; - - if (theMaterial != NULL && theMaterial->m_Type == GraphObjectTypes::DefaultMaterial) { - SDefaultMaterial *theDefaultMaterial = static_cast(theMaterial); - // Don't clear dirty flags if the material was referenced. - bool clearMaterialFlags = theMaterial == inPath.m_Material; - SDefaultMaterialPreparationResult prepResult(PrepareDefaultMaterialForRender( - *theDefaultMaterial, theFlags, subsetOpacity, clearMaterialFlags)); - - theFlags = prepResult.m_RenderableFlags; - if (inPath.m_PathType == PathTypes::Geometry) { - if ((inPath.m_BeginCapping != PathCapping::Noner - && inPath.m_BeginCapOpacity < 1.0f) - || (inPath.m_EndCapping != PathCapping::Noner - && inPath.m_EndCapOpacity < 1.0f)) - theFlags.SetHasTransparency(true); - } else { - ioFlags.SetRequiresStencilBuffer(true); - } - retval = retval || prepResult.m_Dirty; - bool isStroke = true; - if (idx == 0 && inPath.m_PathType == PathTypes::Painted) { - if (inPath.m_PaintStyle == PathPaintStyles::Filled - || inPath.m_PaintStyle == PathPaintStyles::FilledAndStroked) - isStroke = false; - } - - SPathRenderable *theRenderable = RENDER_FRAME_NEW(SPathRenderable)( - theFlags, inPath.GetGlobalPos(), m_Renderer, inPath.m_GlobalTransform, - theBounds, inPath, theMVP, theNormalMatrix, *theMaterial, prepResult.m_Opacity, - prepResult.m_MaterialKey, isStroke); - theRenderable->m_FirstImage = prepResult.m_FirstImage; - - IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); - IPathManager &thePathManager = qt3dsContext.GetPathManager(); - retval = thePathManager.PrepareForRender(inPath) || retval; - retval |= (inPath.m_WireframeMode != qt3dsContext.GetWireframeMode()); - inPath.m_WireframeMode = qt3dsContext.GetWireframeMode(); - - if (theFlags.HasTransparency()) - m_TransparentObjects.push_back(theRenderable); - else - m_OpaqueObjects.push_back(theRenderable); - } else if (theMaterial != NULL - && theMaterial->m_Type == GraphObjectTypes::CustomMaterial) { - SCustomMaterial *theCustomMaterial = static_cast(theMaterial); - // Don't clear dirty flags if the material was referenced. - // bool clearMaterialFlags = theMaterial == inPath.m_Material; - SDefaultMaterialPreparationResult prepResult( - PrepareCustomMaterialForRender(*theCustomMaterial, theFlags, subsetOpacity)); - - theFlags = prepResult.m_RenderableFlags; - if (inPath.m_PathType == PathTypes::Geometry) { - if ((inPath.m_BeginCapping != PathCapping::Noner - && inPath.m_BeginCapOpacity < 1.0f) - || (inPath.m_EndCapping != PathCapping::Noner - && inPath.m_EndCapOpacity < 1.0f)) - theFlags.SetHasTransparency(true); - } else { - ioFlags.SetRequiresStencilBuffer(true); - } - - retval = retval || prepResult.m_Dirty; - bool isStroke = true; - if (idx == 0 && inPath.m_PathType == PathTypes::Painted) { - if (inPath.m_PaintStyle == PathPaintStyles::Filled - || inPath.m_PaintStyle == PathPaintStyles::FilledAndStroked) - isStroke = false; - } - - SPathRenderable *theRenderable = RENDER_FRAME_NEW(SPathRenderable)( - theFlags, inPath.GetGlobalPos(), m_Renderer, inPath.m_GlobalTransform, - theBounds, inPath, theMVP, theNormalMatrix, *theMaterial, prepResult.m_Opacity, - prepResult.m_MaterialKey, isStroke); - theRenderable->m_FirstImage = prepResult.m_FirstImage; - - IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); - IPathManager &thePathManager = qt3dsContext.GetPathManager(); - retval = thePathManager.PrepareForRender(inPath) || retval; - retval |= (inPath.m_WireframeMode != qt3dsContext.GetWireframeMode()); - inPath.m_WireframeMode = qt3dsContext.GetWireframeMode(); - - if (theFlags.HasTransparency()) - m_TransparentObjects.push_back(theRenderable); - else - m_OpaqueObjects.push_back(theRenderable); - } - } - return retval; - } - - void SLayerRenderPreparationData::PrepareImageForRender( - SImage &inImage, ImageMapTypes::Enum inMapType, SRenderableImage *&ioFirstImage, - SRenderableImage *&ioNextImage, SRenderableObjectFlags &ioFlags, - SShaderDefaultMaterialKey &inShaderKey, QT3DSU32 inImageIndex) - { - IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); - IBufferManager &bufferManager = qt3dsContext.GetBufferManager(); - IOffscreenRenderManager &theOffscreenRenderManager( - qt3dsContext.GetOffscreenRenderManager()); - IRenderPluginManager &theRenderPluginManager(qt3dsContext.GetRenderPluginManager()); - if (inImage.ClearDirty(bufferManager, theOffscreenRenderManager, theRenderPluginManager)) - ioFlags |= RenderPreparationResultFlagValues::Dirty; - - // All objects with offscreen renderers are pickable so we can pass the pick through to the - // offscreen renderer and let it deal with the pick. - if (inImage.m_LastFrameOffscreenRenderer != NULL) { - ioFlags.SetPickable(true); - ioFlags |= RenderPreparationResultFlagValues::HasTransparency; - } - - if (inImage.m_TextureData.m_Texture) { - if (inImage.m_TextureData.m_TextureFlags.HasTransparency() - && (inMapType == ImageMapTypes::Diffuse - || inMapType == ImageMapTypes::Opacity - || inMapType == ImageMapTypes::Translucency)) { - ioFlags |= RenderPreparationResultFlagValues::HasTransparency; - } - // Textures used in general have linear characteristics. - // PKC -- The filters are properly set already. Setting them here only overrides what - // would - // otherwise be a correct setting. - // inImage.m_TextureData.m_Texture->SetMinFilter( NVRenderTextureMinifyingOp::Linear ); - // inImage.m_TextureData.m_Texture->SetMagFilter( NVRenderTextureMagnifyingOp::Linear ); - - SRenderableImage *theImage = RENDER_FRAME_NEW(SRenderableImage)(inMapType, inImage); - SShaderKeyImageMap &theKeyProp = - m_Renderer.DefaultMaterialShaderKeyProperties().m_ImageMaps[inImageIndex]; - - theKeyProp.SetEnabled(inShaderKey, true); - switch (inImage.m_MappingMode) { - default: - QT3DS_ASSERT(false); - // fallthrough intentional - case ImageMappingModes::Normal: - break; - case ImageMappingModes::Environment: - theKeyProp.SetEnvMap(inShaderKey, true); - break; - case ImageMappingModes::LightProbe: - theKeyProp.SetLightProbe(inShaderKey, true); - break; - } - - if (inImage.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - theKeyProp.SetInvertUVMap(inShaderKey, true); - if (ioFirstImage == NULL) - ioFirstImage = theImage; - else - ioNextImage->m_NextImage = theImage; - - // assume offscreen renderer produces non-premultiplied image - if (inImage.m_LastFrameOffscreenRenderer == nullptr - && inImage.m_TextureData.m_TextureFlags.IsPreMultiplied()) - theKeyProp.SetPremultiplied(inShaderKey, true); - - SShaderKeyTextureSwizzle &theSwizzleKeyProp = - m_Renderer.DefaultMaterialShaderKeyProperties().m_TextureSwizzle[inImageIndex]; - theSwizzleKeyProp.SetSwizzleMode( - inShaderKey, inImage.m_TextureData.m_Texture->GetTextureSwizzleMode(), true); - - ioNextImage = theImage; - } - } - - SDefaultMaterialPreparationResult SLayerRenderPreparationData::PrepareDefaultMaterialForRender( - SDefaultMaterial &inMaterial, SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity, - bool inClearDirtyFlags) - { - SDefaultMaterial *theMaterial = &inMaterial; - SDefaultMaterialPreparationResult retval(GenerateLightingKey(theMaterial->m_Lighting)); - retval.m_RenderableFlags = inExistingFlags; - SRenderableObjectFlags &renderableFlags(retval.m_RenderableFlags); - SShaderDefaultMaterialKey &theGeneratedKey(retval.m_MaterialKey); - retval.m_Opacity = inOpacity; - QT3DSF32 &subsetOpacity(retval.m_Opacity); - - if (theMaterial->m_Dirty.IsDirty()) { - renderableFlags |= RenderPreparationResultFlagValues::Dirty; - } - subsetOpacity *= theMaterial->m_Opacity; - if (inClearDirtyFlags) - theMaterial->m_Dirty.UpdateDirtyForFrame(); - - SRenderableImage *firstImage = NULL; - - // set wireframe mode - m_Renderer.DefaultMaterialShaderKeyProperties().m_WireframeMode.SetValue( - theGeneratedKey, m_Renderer.GetQt3DSContext().GetWireframeMode()); - - if (theMaterial->m_IblProbe && CheckLightProbeDirty(*theMaterial->m_IblProbe)) { - m_Renderer.PrepareImageForIbl(*theMaterial->m_IblProbe); - } - - if (!m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.GetValue(theGeneratedKey)) { - bool lightProbeValid = HasValidLightProbe(theMaterial->m_IblProbe); - SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", lightProbeValid); - m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(theGeneratedKey, - lightProbeValid); - // SetShaderFeature( "QT3DS_ENABLE_IBL_FOV", - // m_Renderer.GetLayerRenderData()->m_Layer.m_ProbeFov < 180.0f ); - } - - if (subsetOpacity >= QT3DS_RENDER_MINIMUM_RENDER_OPACITY) { - - if (theMaterial->m_BlendMode != DefaultMaterialBlendMode::Normal - || theMaterial->m_OpacityMap) { - renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; - } - - bool specularEnabled = theMaterial->IsSpecularEnabled(); - m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularEnabled.SetValue( - theGeneratedKey, specularEnabled); - if (specularEnabled) { - m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularModel.SetSpecularModel( - theGeneratedKey, theMaterial->m_SpecularModel); - } - - m_Renderer.DefaultMaterialShaderKeyProperties().m_FresnelEnabled.SetValue( - theGeneratedKey, theMaterial->IsFresnelEnabled()); - - m_Renderer.DefaultMaterialShaderKeyProperties().m_VertexColorsEnabled.SetValue( - theGeneratedKey, theMaterial->IsVertexColorsEnabled()); - - // Run through the material's images and prepare them for render. - // this may in fact set pickable on the renderable flags if one of the images - // links to a sub presentation or any offscreen rendered object. - SRenderableImage *nextImage = NULL; -#define CHECK_IMAGE_AND_PREPARE(img, imgtype, shadercomponent) \ - if ((img)) \ - PrepareImageForRender(*(img), imgtype, firstImage, nextImage, renderableFlags, \ - theGeneratedKey, shadercomponent); - - CHECK_IMAGE_AND_PREPARE(theMaterial->m_DiffuseMaps[0], ImageMapTypes::Diffuse, - SShaderDefaultMaterialKeyProperties::DiffuseMap0); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_DiffuseMaps[1], ImageMapTypes::Diffuse, - SShaderDefaultMaterialKeyProperties::DiffuseMap1); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_DiffuseMaps[2], ImageMapTypes::Diffuse, - SShaderDefaultMaterialKeyProperties::DiffuseMap2); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_EmissiveMap, ImageMapTypes::Emissive, - SShaderDefaultMaterialKeyProperties::EmissiveMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_EmissiveMap2, ImageMapTypes::Emissive, - SShaderDefaultMaterialKeyProperties::EmissiveMap2); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_SpecularReflection, ImageMapTypes::Specular, - SShaderDefaultMaterialKeyProperties::SpecularMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_RoughnessMap, ImageMapTypes::Roughness, - SShaderDefaultMaterialKeyProperties::RoughnessMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_OpacityMap, ImageMapTypes::Opacity, - SShaderDefaultMaterialKeyProperties::OpacityMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_BumpMap, ImageMapTypes::Bump, - SShaderDefaultMaterialKeyProperties::BumpMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_SpecularMap, ImageMapTypes::SpecularAmountMap, - SShaderDefaultMaterialKeyProperties::SpecularAmountMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_NormalMap, ImageMapTypes::Normal, - SShaderDefaultMaterialKeyProperties::NormalMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_DisplacementMap, ImageMapTypes::Displacement, - SShaderDefaultMaterialKeyProperties::DisplacementMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_TranslucencyMap, ImageMapTypes::Translucency, - SShaderDefaultMaterialKeyProperties::TranslucencyMap); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_Lightmaps.m_LightmapIndirect, - ImageMapTypes::LightmapIndirect, - SShaderDefaultMaterialKeyProperties::LightmapIndirect); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_Lightmaps.m_LightmapRadiosity, - ImageMapTypes::LightmapRadiosity, - SShaderDefaultMaterialKeyProperties::LightmapRadiosity); - CHECK_IMAGE_AND_PREPARE(theMaterial->m_Lightmaps.m_LightmapShadow, - ImageMapTypes::LightmapShadow, - SShaderDefaultMaterialKeyProperties::LightmapShadow); - } -#undef CHECK_IMAGE_AND_PREPARE - - if (subsetOpacity < QT3DS_RENDER_MINIMUM_RENDER_OPACITY) { - subsetOpacity = 0.0f; - // You can still pick against completely transparent objects(or rather their bounding - // box) - // you just don't render them. - renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; - renderableFlags |= RenderPreparationResultFlagValues::CompletelyTransparent; - } - - if (IsNotOne(subsetOpacity)) - renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; - - retval.m_FirstImage = firstImage; - if (retval.m_RenderableFlags.IsDirty()) - retval.m_Dirty = true; - return retval; - } - - SDefaultMaterialPreparationResult SLayerRenderPreparationData::PrepareCustomMaterialForRender( - SCustomMaterial &inMaterial, SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity) - { - SDefaultMaterialPreparationResult retval(GenerateLightingKey( - DefaultMaterialLighting::FragmentLighting)); // always fragment lighting - retval.m_RenderableFlags = inExistingFlags; - SRenderableObjectFlags &renderableFlags(retval.m_RenderableFlags); - SShaderDefaultMaterialKey &theGeneratedKey(retval.m_MaterialKey); - retval.m_Opacity = inOpacity; - QT3DSF32 &subsetOpacity(retval.m_Opacity); - - // set wireframe mode - m_Renderer.DefaultMaterialShaderKeyProperties().m_WireframeMode.SetValue( - theGeneratedKey, m_Renderer.GetQt3DSContext().GetWireframeMode()); - - if (subsetOpacity < QT3DS_RENDER_MINIMUM_RENDER_OPACITY) { - subsetOpacity = 0.0f; - // You can still pick against completely transparent objects(or rather their bounding - // box) - // you just don't render them. - renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; - renderableFlags |= RenderPreparationResultFlagValues::CompletelyTransparent; - } - - if (IsNotOne(subsetOpacity)) - renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; - - SRenderableImage *firstImage = NULL; - SRenderableImage *nextImage = NULL; - -#define CHECK_IMAGE_AND_PREPARE(img, imgtype, shadercomponent) \ - if ((img)) \ - PrepareImageForRender(*(img), imgtype, firstImage, nextImage, renderableFlags, \ - theGeneratedKey, shadercomponent); - - CHECK_IMAGE_AND_PREPARE(inMaterial.m_DisplacementMap, ImageMapTypes::Displacement, - SShaderDefaultMaterialKeyProperties::DisplacementMap); - CHECK_IMAGE_AND_PREPARE(inMaterial.m_Lightmaps.m_LightmapIndirect, - ImageMapTypes::LightmapIndirect, - SShaderDefaultMaterialKeyProperties::LightmapIndirect); - CHECK_IMAGE_AND_PREPARE(inMaterial.m_Lightmaps.m_LightmapRadiosity, - ImageMapTypes::LightmapRadiosity, - SShaderDefaultMaterialKeyProperties::LightmapRadiosity); - CHECK_IMAGE_AND_PREPARE(inMaterial.m_Lightmaps.m_LightmapShadow, - ImageMapTypes::LightmapShadow, - SShaderDefaultMaterialKeyProperties::LightmapShadow); -#undef CHECK_IMAGE_AND_PREPARE - - retval.m_FirstImage = firstImage; - return retval; - } - - bool SLayerRenderPreparationData::PrepareModelForRender( - SModel &inModel, const QT3DSMat44 &inViewProjection, - const Option &inClipFrustum, TNodeLightEntryList &inScopedLights) - { - IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); - IBufferManager &bufferManager = qt3dsContext.GetBufferManager(); - SRenderMesh *theMesh = bufferManager.LoadMesh(inModel.m_MeshPath); - if (theMesh == NULL) - return false; - - SGraphObject *theSourceMaterialObject = inModel.m_FirstMaterial; - SModelContext &theModelContext = - *RENDER_FRAME_NEW(SModelContext)(inModel, inViewProjection); - m_ModelContexts.push_back(&theModelContext); - - bool subsetDirty = false; - - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, m_SourceLightDirections, - inScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - for (QT3DSU32 idx = 0, end = theMesh->m_Subsets.size(); idx < end && theSourceMaterialObject; - ++idx, theSourceMaterialObject = GetNextMaterialSibling(theSourceMaterialObject)) { - SRenderSubset &theOuterSubset(theMesh->m_Subsets[idx]); - { - SRenderSubset &theSubset(theOuterSubset); - SRenderableObjectFlags renderableFlags; - renderableFlags.SetPickable(false); - renderableFlags.SetShadowCaster(inModel.m_ShadowCaster); - QT3DSF32 subsetOpacity = inModel.m_GlobalOpacity; - QT3DSVec3 theModelCenter(theSubset.m_Bounds.getCenter()); - theModelCenter = inModel.m_GlobalTransform.transform(theModelCenter); - - if (subsetOpacity >= QT3DS_RENDER_MINIMUM_RENDER_OPACITY - && inClipFrustum.hasValue()) { - // Check bounding box against the clipping planes - NVBounds3 theGlobalBounds = theSubset.m_Bounds; - theGlobalBounds.transform(theModelContext.m_Model.m_GlobalTransform); - if (inClipFrustum->intersectsWith(theGlobalBounds) == false) - subsetOpacity = 0.0f; - } - - // For now everything is pickable. Eventually we want to have localPickable and - // globalPickable set on the node during - // updates and have the runtime tell us what is pickable and what is not pickable. - // Completely transparent models cannot be pickable. But models with completely - // transparent materials - // still are. This allows the artist to control pickability in a somewhat - // fine-grained style. - bool canModelBePickable = inModel.m_GlobalOpacity > .01f; - renderableFlags.SetPickable(canModelBePickable - && (theModelContext.m_Model.m_Flags.IsGloballyPickable() - || renderableFlags.GetPickable())); - SRenderableObject *theRenderableObject(NULL); - eastl::pair theMaterialObjectAndDirty = - ResolveReferenceMaterial(theSourceMaterialObject); - SGraphObject *theMaterialObject = theMaterialObjectAndDirty.second; - subsetDirty = subsetDirty || theMaterialObjectAndDirty.first; - if (theMaterialObject == NULL) - continue; - - // set tessellation - if (inModel.m_TessellationMode != TessModeValues::NoTess) { - theSubset.m_PrimitiveType = NVRenderDrawMode::Patches; - // set tessellation factor - theSubset.m_EdgeTessFactor = inModel.m_EdgeTess; - theSubset.m_InnerTessFactor = inModel.m_InnerTess; - // update the vertex ver patch count in the input assembler - // currently we only support triangle patches so count is always 3 - theSubset.m_InputAssembler->SetPatchVertexCount(3); - theSubset.m_InputAssemblerDepth->SetPatchVertexCount(3); - // check wireframe mode - theSubset.m_WireframeMode = qt3dsContext.GetWireframeMode(); - - subsetDirty = - subsetDirty | (theSubset.m_WireframeMode != inModel.m_WireframeMode); - inModel.m_WireframeMode = qt3dsContext.GetWireframeMode(); - } else { - theSubset.m_PrimitiveType = theSubset.m_InputAssembler->GetPrimitiveType(); - theSubset.m_InputAssembler->SetPatchVertexCount(1); - theSubset.m_InputAssemblerDepth->SetPatchVertexCount(1); - // currently we allow wirframe mode only if tessellation is on - theSubset.m_WireframeMode = false; - - subsetDirty = - subsetDirty | (theSubset.m_WireframeMode != inModel.m_WireframeMode); - inModel.m_WireframeMode = false; - } - // Only clear flags on the materials in this direct hierarchy. Do not clear them of - // this - // references materials in another hierarchy. - bool clearMaterialDirtyFlags = theMaterialObject == theSourceMaterialObject; - - if (theMaterialObject == NULL) - continue; - - if (theMaterialObject->m_Type == GraphObjectTypes::DefaultMaterial) { - SDefaultMaterial &theMaterial( - static_cast(*theMaterialObject)); - SDefaultMaterialPreparationResult theMaterialPrepResult( - PrepareDefaultMaterialForRender(theMaterial, renderableFlags, subsetOpacity, - clearMaterialDirtyFlags)); - SShaderDefaultMaterialKey theGeneratedKey = theMaterialPrepResult.m_MaterialKey; - subsetOpacity = theMaterialPrepResult.m_Opacity; - SRenderableImage *firstImage(theMaterialPrepResult.m_FirstImage); - subsetDirty |= theMaterialPrepResult.m_Dirty; - renderableFlags = theMaterialPrepResult.m_RenderableFlags; - - m_Renderer.DefaultMaterialShaderKeyProperties() - .m_TessellationMode.SetTessellationMode(theGeneratedKey, - inModel.m_TessellationMode, true); - - NVConstDataRef boneGlobals; - if (theSubset.m_Joints.size()) { - QT3DS_ASSERT(false); - } - - theRenderableObject = RENDER_FRAME_NEW(SSubsetRenderable)( - renderableFlags, theModelCenter, m_Renderer, theSubset, theMaterial, - theModelContext, subsetOpacity, firstImage, theGeneratedKey, boneGlobals); - subsetDirty = subsetDirty || renderableFlags.IsDirty(); - - } // if type == DefaultMaterial - else if (theMaterialObject->m_Type == GraphObjectTypes::CustomMaterial) { - SCustomMaterial &theMaterial( - static_cast(*theMaterialObject)); - - ICustomMaterialSystem &theMaterialSystem( - qt3dsContext.GetCustomMaterialSystem()); - subsetDirty |= theMaterialSystem.PrepareForRender( - theModelContext.m_Model, theSubset, theMaterial, clearMaterialDirtyFlags); - - SDefaultMaterialPreparationResult theMaterialPrepResult( - PrepareCustomMaterialForRender(theMaterial, renderableFlags, - subsetOpacity)); - SShaderDefaultMaterialKey theGeneratedKey = theMaterialPrepResult.m_MaterialKey; - subsetOpacity = theMaterialPrepResult.m_Opacity; - SRenderableImage *firstImage(theMaterialPrepResult.m_FirstImage); - renderableFlags = theMaterialPrepResult.m_RenderableFlags; - - // prepare for render tells us if the object is transparent - if (theMaterial.m_hasTransparency) - renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; - // prepare for render tells us if the object is transparent - if (theMaterial.m_hasRefraction) - renderableFlags |= RenderPreparationResultFlagValues::HasRefraction; - - m_Renderer.DefaultMaterialShaderKeyProperties() - .m_TessellationMode.SetTessellationMode(theGeneratedKey, - inModel.m_TessellationMode, true); - - if (theMaterial.m_IblProbe && CheckLightProbeDirty(*theMaterial.m_IblProbe)) { - m_Renderer.PrepareImageForIbl(*theMaterial.m_IblProbe); - } - - theRenderableObject = RENDER_FRAME_NEW(SCustomMaterialRenderable)( - renderableFlags, theModelCenter, m_Renderer, theSubset, theMaterial, - theModelContext, subsetOpacity, firstImage, theGeneratedKey); - } - if (theRenderableObject) { - theRenderableObject->m_ScopedLights = inScopedLights; - // set tessellation - theRenderableObject->m_TessellationMode = inModel.m_TessellationMode; - - if (theRenderableObject->m_RenderableFlags.HasTransparency() - || theRenderableObject->m_RenderableFlags.HasRefraction()) { - m_TransparentObjects.push_back(theRenderableObject); - } else { - m_OpaqueObjects.push_back(theRenderableObject); - } - } - } - } - return subsetDirty; - } - - bool SLayerRenderPreparationData::PrepareRenderablesForRender( - const QT3DSMat44 &inViewProjection, const Option &inClipFrustum, - QT3DSF32 inTextScaleFactor, SLayerRenderPreparationResultFlags &ioFlags) - { - SStackPerfTimer __timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::PrepareRenderablesForRender"); - m_ViewProjection = inViewProjection; - QT3DSF32 theTextScaleFactor = inTextScaleFactor; - bool wasDataDirty = false; - bool hasTextRenderer = m_Renderer.GetQt3DSContext().GetTextRenderer() != NULL; - for (QT3DSU32 idx = 0, end = m_RenderableNodes.size(); idx < end; ++idx) { - SRenderableNodeEntry &theNodeEntry(m_RenderableNodes[idx]); - SNode *theNode = theNodeEntry.m_Node; - wasDataDirty = wasDataDirty || theNode->m_Flags.IsDirty(); - switch (theNode->m_Type) { - case GraphObjectTypes::Model: { - SModel *theModel = static_cast(theNode); - theModel->CalculateGlobalVariables(); - if (theModel->m_Flags.IsGloballyActive()) { - bool wasModelDirty = PrepareModelForRender( - *theModel, inViewProjection, inClipFrustum, theNodeEntry.m_Lights); - wasDataDirty = wasDataDirty || wasModelDirty; - } - } break; - case GraphObjectTypes::Text: { - if (hasTextRenderer) { - SText *theText = static_cast(theNode); - theText->CalculateGlobalVariables(); - if (theText->m_Flags.IsGloballyActive()) { - bool wasTextDirty = PrepareTextForRender(*theText, inViewProjection, - theTextScaleFactor, ioFlags); - wasDataDirty = wasDataDirty || wasTextDirty; - } - } - } break; - case GraphObjectTypes::Path: { - SPath *thePath = static_cast(theNode); - thePath->CalculateGlobalVariables(); - if (thePath->m_Flags.IsGloballyActive()) { - bool wasPathDirty = - PreparePathForRender(*thePath, inViewProjection, inClipFrustum, ioFlags); - wasDataDirty = wasDataDirty || wasPathDirty; - } - } break; - default: - QT3DS_ASSERT(false); - break; - } - } - return wasDataDirty; - } - - bool SLayerRenderPreparationData::CheckLightProbeDirty(SImage &inLightProbe) - { - IQt3DSRenderContext &theContext(m_Renderer.GetQt3DSContext()); - return inLightProbe.ClearDirty(theContext.GetBufferManager(), - theContext.GetOffscreenRenderManager(), - theContext.GetRenderPluginManager(), true); - } - - struct SLightNodeMarker - { - SLight *m_Light; - QT3DSU32 m_LightIndex; - QT3DSU32 m_FirstValidIndex; - QT3DSU32 m_JustPastLastValidIndex; - bool m_AddOrRemove; - SLightNodeMarker() - : m_Light(NULL) - , m_FirstValidIndex(0) - , m_JustPastLastValidIndex(0) - , m_AddOrRemove(false) - { - } - SLightNodeMarker(SLight &inLight, QT3DSU32 inLightIndex, SNode &inNode, bool aorm) - : m_Light(&inLight) - , m_LightIndex(inLightIndex) - , m_AddOrRemove(aorm) - { - if (inNode.m_Type == GraphObjectTypes::Layer) { - m_FirstValidIndex = 0; - m_JustPastLastValidIndex = QT3DS_MAX_U32; - } else { - m_FirstValidIndex = inNode.m_DFSIndex; - SNode *lastChild = NULL; - SNode *firstChild = inNode.m_FirstChild; - // find deepest last child - while (firstChild) { - for (SNode *childNode = firstChild; childNode; - childNode = childNode->m_NextSibling) - lastChild = childNode; - - if (lastChild) - firstChild = lastChild->m_FirstChild; - else - firstChild = NULL; - } - if (lastChild) - // last valid index would be the last child index + 1 - m_JustPastLastValidIndex = lastChild->m_DFSIndex + 1; - else // no children. - m_JustPastLastValidIndex = m_FirstValidIndex + 1; - } - } - }; - - // m_Layer.m_Camera->CalculateViewProjectionMatrix(m_ViewProjection); - void - SLayerRenderPreparationData::PrepareForRender(const QSize &inViewportDimensions) - { - SStackPerfTimer __timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::PrepareForRender"); - if (m_LayerPrepResult.hasValue()) - return; - - m_Features.clear(); - m_FeatureSetHash = 0; - QT3DSVec2 thePresentationDimensions((QT3DSF32)inViewportDimensions.width(), - (QT3DSF32)inViewportDimensions.height()); - IRenderList &theGraph(m_Renderer.GetQt3DSContext().GetRenderList()); - NVRenderRect theViewport(theGraph.GetViewport()); - NVRenderRect theScissor(theGraph.GetViewport()); - if (theGraph.IsScissorTestEnabled()) - theScissor = m_Renderer.GetContext().GetScissorRect(); - bool wasDirty = false; - bool wasDataDirty = false; - wasDirty = m_Layer.m_Flags.IsDirty(); - // The first pass is just to render the data. - QT3DSU32 maxNumAAPasses = m_Layer.m_ProgressiveAAMode == AAModeValues::NoAA - ? (QT3DSU32)0 - : (QT3DSU32)(m_Layer.m_ProgressiveAAMode) + 1; - maxNumAAPasses = NVMin((QT3DSU32)(MAX_AA_LEVELS + 1), maxNumAAPasses); - SEffect *theLastEffect = NULL; - // Uncomment the line below to disable all progressive AA. - // maxNumAAPasses = 0; - - SLayerRenderPreparationResult thePrepResult; - bool hasOffscreenRenderer = GetOffscreenRenderer(); - - bool SSAOEnabled = (m_Layer.m_AoStrength > 0.0f && m_Layer.m_AoDistance > 0.0f); - bool SSDOEnabled = (m_Layer.m_ShadowStrength > 0.0f && m_Layer.m_ShadowDist > 0.0f); - SetShaderFeature("QT3DS_ENABLE_SSAO", SSAOEnabled); - SetShaderFeature("QT3DS_ENABLE_SSDO", SSDOEnabled); - bool requiresDepthPrepass = (hasOffscreenRenderer == false) && (SSAOEnabled || SSDOEnabled); - SetShaderFeature("QT3DS_ENABLE_SSM", false); // by default no shadow map generation - - if (m_Layer.m_Flags.IsActive()) { - // Get the layer's width and height. - IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); - for (SEffect *theEffect = m_Layer.m_FirstEffect; theEffect; - theEffect = theEffect->m_NextEffect) { - if (theEffect->m_Flags.IsDirty()) { - wasDirty = true; - theEffect->m_Flags.SetDirty(false); - } - if (theEffect->m_Flags.IsActive()) { - theLastEffect = theEffect; - if (hasOffscreenRenderer == false - && theEffectSystem.DoesEffectRequireDepthTexture(theEffect->m_ClassName)) - requiresDepthPrepass = true; - } - } - if (m_Layer.m_Flags.IsDirty()) { - wasDirty = true; - m_Layer.CalculateGlobalVariables(); - } - - bool shouldRenderToTexture = true; - - if (hasOffscreenRenderer) { - // We don't render to texture with offscreen renderers, we just render them to the - // viewport. - shouldRenderToTexture = false; - // Progaa disabled when using offscreen rendering. - maxNumAAPasses = 0; - } - - thePrepResult = SLayerRenderPreparationResult(SLayerRenderHelper( - theViewport, theScissor, m_Layer.m_Scene->m_Presentation->m_PresentationDimensions, - m_Layer, shouldRenderToTexture, m_Renderer.GetQt3DSContext().GetScaleMode(), - m_Renderer.GetQt3DSContext().GetPresentationScaleFactor())); - thePrepResult.m_LastEffect = theLastEffect; - thePrepResult.m_MaxAAPassIndex = maxNumAAPasses; - thePrepResult.m_Flags.SetRequiresDepthTexture(requiresDepthPrepass - || NeedsWidgetTexture()); - thePrepResult.m_Flags.SetShouldRenderToTexture(shouldRenderToTexture); - if (m_Renderer.GetContext().GetRenderContextType() != NVRenderContextValues::GLES2) - thePrepResult.m_Flags.SetRequiresSsaoPass(SSAOEnabled); - - if (thePrepResult.IsLayerVisible()) { - if (shouldRenderToTexture) { - m_Renderer.GetQt3DSContext().GetRenderList().AddRenderTask( - CreateRenderToTextureRunnable()); - } - if (m_Layer.m_LightProbe && CheckLightProbeDirty(*m_Layer.m_LightProbe)) { - m_Renderer.PrepareImageForIbl(*m_Layer.m_LightProbe); - wasDataDirty = true; - } - - bool lightProbeValid = HasValidLightProbe(m_Layer.m_LightProbe); - - SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", lightProbeValid); - SetShaderFeature("QT3DS_ENABLE_IBL_FOV", m_Layer.m_ProbeFov < 180.0f); - - if (lightProbeValid && m_Layer.m_LightProbe2 - && CheckLightProbeDirty(*m_Layer.m_LightProbe2)) { - m_Renderer.PrepareImageForIbl(*m_Layer.m_LightProbe2); - wasDataDirty = true; - } - - SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE_2", - lightProbeValid && HasValidLightProbe(m_Layer.m_LightProbe2)); - - // Push nodes in reverse depth first order - if (m_RenderableNodes.empty()) { - m_CamerasAndLights.clear(); - QT3DSU32 dfsIndex = 0; - for (SNode *theChild = m_Layer.m_FirstChild; theChild; - theChild = theChild->m_NextSibling) - MaybeQueueNodeForRender(*theChild, m_RenderableNodes, m_CamerasAndLights, - dfsIndex); - reverse(m_CamerasAndLights.begin(), m_CamerasAndLights.end()); - reverse(m_RenderableNodes.begin(), m_RenderableNodes.end()); - m_LightToNodeMap.clear(); - } - m_Camera = NULL; - m_Lights.clear(); - m_OpaqueObjects.clear(); - m_TransparentObjects.clear(); - nvvector theLightNodeMarkers(m_Renderer.GetPerFrameAllocator(), - "LightNodeMarkers"); - m_SourceLightDirections.clear(); - - for (QT3DSU32 idx = 0, end = m_CamerasAndLights.size(); idx < end; ++idx) { - SNode *theNode(m_CamerasAndLights[idx]); - wasDataDirty = wasDataDirty || theNode->m_Flags.IsDirty(); - switch (theNode->m_Type) { - case GraphObjectTypes::Camera: { - SCamera *theCamera = static_cast(theNode); - SCameraGlobalCalculationResult theResult = - thePrepResult.SetupCameraForRender(*theCamera); - wasDataDirty = wasDataDirty || theResult.m_WasDirty; - if (theCamera->m_Flags.IsGloballyActive()) - m_Camera = theCamera; - if (theResult.m_ComputeFrustumSucceeded == false) { - qCCritical(INTERNAL_ERROR, "Failed to calculate camera frustum"); - } - } break; - case GraphObjectTypes::Light: { - SLight *theLight = static_cast(theNode); - bool lightResult = theLight->CalculateGlobalVariables(); - wasDataDirty = lightResult || wasDataDirty; - // Note we setup the light index such that it is completely invariant of if - // the - // light is active or scoped. - QT3DSU32 lightIndex = (QT3DSU32)m_SourceLightDirections.size(); - m_SourceLightDirections.push_back(QT3DSVec3(0.0f)); - // Note we still need a light check when building the renderable light list. - // We also cannot cache shader-light bindings based on layers any more - // because - // the number of lights for a given renderable does not depend on the layer - // as it used to but - // additional perhaps on the light's scoping rules. - if (theLight->m_Flags.IsGloballyActive()) { - if (theLight->m_Scope == NULL) { - m_Lights.push_back(theLight); - if (m_Renderer.GetContext().GetRenderContextType() - != NVRenderContextValues::GLES2 - && theLight->m_CastShadow && GetShadowMapManager()) { - // PKC -- use of "res" as an exponent of two is an annoying - // artifact of the XML interface - // I'll change this with an enum interface later on, but that's - // less important right now. - QT3DSU32 mapSize = 1 << theLight->m_ShadowMapRes; - ShadowMapModes::Enum mapMode = - (theLight->m_LightType != RenderLightTypes::Directional) - ? ShadowMapModes::CUBE - : ShadowMapModes::VSM; - m_ShadowMapManager->AddShadowMapEntry( - m_Lights.size() - 1, mapSize, mapSize, - NVRenderTextureFormats::R16F, 1, mapMode, - ShadowFilterValues::NONE); - thePrepResult.m_Flags.SetRequiresShadowMapPass(true); - SetShaderFeature("QT3DS_ENABLE_SSM", true); - } - } - TLightToNodeMap::iterator iter = - m_LightToNodeMap.insert(eastl::make_pair(theLight, (SNode *)NULL)) - .first; - SNode *oldLightScope = iter->second; - SNode *newLightScope = theLight->m_Scope; - - if (oldLightScope != newLightScope) { - iter->second = newLightScope; - if (oldLightScope) - theLightNodeMarkers.push_back(SLightNodeMarker( - *theLight, lightIndex, *oldLightScope, false)); - if (newLightScope) - theLightNodeMarkers.push_back(SLightNodeMarker( - *theLight, lightIndex, *newLightScope, true)); - } - if (newLightScope) { - m_SourceLightDirections.back() = - theLight->GetScalingCorrectDirection(); - } - } - } break; - default: - QT3DS_ASSERT(false); - break; - } - } - - if (theLightNodeMarkers.empty() == false) { - for (QT3DSU32 idx = 0, end = m_RenderableNodes.size(); idx < end; ++idx) { - SRenderableNodeEntry &theNodeEntry(m_RenderableNodes[idx]); - QT3DSU32 nodeDFSIndex = theNodeEntry.m_Node->m_DFSIndex; - for (QT3DSU32 markerIdx = 0, markerEnd = theLightNodeMarkers.size(); - markerIdx < markerEnd; ++markerIdx) { - SLightNodeMarker &theMarker = theLightNodeMarkers[markerIdx]; - if (nodeDFSIndex >= theMarker.m_FirstValidIndex - && nodeDFSIndex < theMarker.m_JustPastLastValidIndex) { - if (theMarker.m_AddOrRemove) { - SNodeLightEntry *theNewEntry = - m_RenderableNodeLightEntryPool.construct( - theMarker.m_Light, theMarker.m_LightIndex, __FILE__, - __LINE__); - theNodeEntry.m_Lights.push_back(*theNewEntry); - } else { - for (TNodeLightEntryList::iterator - lightIter = theNodeEntry.m_Lights.begin(), - lightEnd = theNodeEntry.m_Lights.end(); - lightIter != lightEnd; ++lightIter) { - if (lightIter->m_Light == theMarker.m_Light) { - SNodeLightEntry &theEntry = *lightIter; - theNodeEntry.m_Lights.remove(theEntry); - m_RenderableNodeLightEntryPool.deallocate(&theEntry); - break; - } - } - } - } - } - } - } - - QT3DSF32 theTextScaleFactor = 1.0f; - if (m_Camera) { - m_Camera->CalculateViewProjectionMatrix(m_ViewProjection); - theTextScaleFactor = m_Camera->GetTextScaleFactor( - thePrepResult.GetLayerToPresentationViewport(), - thePrepResult.GetPresentationDesignDimensions()); - SClipPlane nearPlane; - QT3DSMat33 theUpper33(m_Camera->m_GlobalTransform.getUpper3x3InverseTranspose()); - - QT3DSVec3 dir(theUpper33.transform(QT3DSVec3(0, 0, -1))); - dir.normalize(); - nearPlane.normal = dir; - QT3DSVec3 theGlobalPos = m_Camera->GetGlobalPos() + m_Camera->m_ClipNear * dir; - nearPlane.d = -(dir.dot(theGlobalPos)); - // the near plane's bbox edges are calculated in the clipping frustum's - // constructor. - m_ClippingFrustum = SClippingFrustum(m_ViewProjection, nearPlane); - } else - m_ViewProjection = QT3DSMat44::createIdentity(); - - // Setup the light directions here. - - for (QT3DSU32 lightIdx = 0, lightEnd = m_Lights.size(); lightIdx < lightEnd; - ++lightIdx) { - m_LightDirections.push_back(m_Lights[lightIdx]->GetScalingCorrectDirection()); - } - - m_ModelContexts.clear(); - if (GetOffscreenRenderer() == false) { - bool renderablesDirty = - PrepareRenderablesForRender(m_ViewProjection, m_ClippingFrustum, - theTextScaleFactor, thePrepResult.m_Flags); - wasDataDirty = wasDataDirty || renderablesDirty; - if (thePrepResult.m_Flags.RequiresStencilBuffer()) - thePrepResult.m_Flags.SetShouldRenderToTexture(true); - } else { - NVRenderRect theViewport = - thePrepResult.GetLayerToPresentationViewport().ToIntegerRect(); - bool theScissor = true; - NVRenderRect theScissorRect = - thePrepResult.GetLayerToPresentationScissorRect().ToIntegerRect(); - // This happens here because if there are any fancy render steps - IRenderList &theRenderList(m_Renderer.GetQt3DSContext().GetRenderList()); - NVRenderContext &theContext(m_Renderer.GetContext()); - SRenderListScopedProperty _listScissorEnabled( - theRenderList, &IRenderList::IsScissorTestEnabled, - &IRenderList::SetScissorTestEnabled, theScissor); - SRenderListScopedProperty _listViewport( - theRenderList, &IRenderList::GetViewport, &IRenderList::SetViewport, - theViewport); - SRenderListScopedProperty _listScissor( - theRenderList, &IRenderList::GetScissor, &IRenderList::SetScissorRect, - theScissorRect); - // Some plugins don't use the render list so they need the actual gl context - // setup. - qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, true); - qt3ds::render::NVRenderContextScopedProperty __scissorRect( - theContext, &NVRenderContext::GetScissorRect, - &NVRenderContext::SetScissorRect, theScissorRect); - qt3ds::render::NVRenderContextScopedProperty __viewportRect( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, - theViewport); - SOffscreenRenderFlags theResult = m_LastFrameOffscreenRenderer->NeedsRender( - CreateOffscreenRenderEnvironment(), - m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), &m_Layer); - wasDataDirty = wasDataDirty || theResult.m_HasChangedSinceLastFrame; - } - } - } - wasDirty = wasDirty || wasDataDirty; - thePrepResult.m_Flags.SetWasDirty(wasDirty); - thePrepResult.m_Flags.SetLayerDataDirty(wasDataDirty); - - m_LayerPrepResult = thePrepResult; - - // Per-frame cache of renderable objects post-sort. - GetOpaqueRenderableObjects(); - // If layer depth test is false, this may also contain opaque objects. - GetTransparentRenderableObjects(); - - GetCameraDirection(); - } - - void SLayerRenderPreparationData::ResetForFrame() - { - m_TransparentObjects.clear_unsafe(); - m_OpaqueObjects.clear_unsafe(); - m_LayerPrepResult.setEmpty(); - // The check for if the camera is or is not null is used - // to figure out if this layer was rendered at all. - m_Camera = NULL; - m_LastFrameOffscreenRenderer = NULL; - m_IRenderWidgets.clear_unsafe(); - m_CameraDirection.setEmpty(); - m_LightDirections.clear_unsafe(); - m_RenderedOpaqueObjects.clear_unsafe(); - m_RenderedTransparentObjects.clear_unsafe(); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.h deleted file mode 100644 index 5b8d6e10..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.h +++ /dev/null @@ -1,367 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDERER_IMPL_LAYER_RENDER_PREPARATION_DATA_H -#define QT3DS_RENDERER_IMPL_LAYER_RENDER_PREPARATION_DATA_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSFlags.h" -#include "Qt3DSRendererImplLayerRenderHelper.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderableObjects.h" -#include "Qt3DSRenderClippingFrustum.h" -#include "Qt3DSRenderResourceTexture2D.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSRenderProfiler.h" -#include "Qt3DSRenderShadowMap.h" -#include "foundation/Qt3DSPool.h" -#include "Qt3DSRenderableObjects.h" - -namespace qt3ds { -namespace render { - struct SLayerRenderData; - class Qt3DSRendererImpl; - struct SRenderableObject; - - struct LayerRenderPreparationResultFlagValues - { - enum Enum { - // Was the data in this layer dirty (meaning re-render to texture, possibly) - WasLayerDataDirty = 1, - // Was the data in this layer dirty *or* this layer *or* any effect dirty. - WasDirty = 1 << 1, - // An effect or flag or rotation on the layer dictates this object should - // render to the texture. - ShouldRenderToTexture = 1 << 2, - // Some effects require depth texturing, this should be set on the effect - // instance. - RequiresDepthTexture = 1 << 3, - - // Should create independent viewport - // If we aren't rendering to texture we still may have width/height manipulations - // that require our own viewport. - ShouldCreateIndependentViewport = 1 << 4, - - // SSAO should be done in a separate pass - // Note that having an AO pass necessitates a DepthTexture so this flag should - // never be set without the RequiresDepthTexture flag as well. - RequiresSsaoPass = 1 << 5, - - // if some light cause shadow - // we need a separate per light shadow map pass - RequiresShadowMapPass = 1 << 6, - - // Currently we use a stencil-cover algorithm to render bezier curves. - RequiresStencilBuffer = 1 << 7 - }; - }; - - struct SLayerRenderPreparationResultFlags - : public NVFlags - { - bool WasLayerDataDirty() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::WasLayerDataDirty); - } - void SetLayerDataDirty(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::WasLayerDataDirty); - } - - bool WasDirty() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::WasDirty); - } - void SetWasDirty(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::WasDirty); - } - - bool ShouldRenderToTexture() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::ShouldRenderToTexture); - } - void SetShouldRenderToTexture(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::ShouldRenderToTexture); - } - - bool RequiresDepthTexture() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::RequiresDepthTexture); - } - void SetRequiresDepthTexture(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresDepthTexture); - } - - bool ShouldCreateIndependentViewport() const - { - return this->operator&( - LayerRenderPreparationResultFlagValues::ShouldCreateIndependentViewport); - } - void SetShouldCreateIndependentViewport(bool inValue) - { - clearOrSet(inValue, - LayerRenderPreparationResultFlagValues::ShouldCreateIndependentViewport); - } - - bool RequiresSsaoPass() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::RequiresSsaoPass); - } - void SetRequiresSsaoPass(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresSsaoPass); - } - - bool RequiresShadowMapPass() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::RequiresShadowMapPass); - } - void SetRequiresShadowMapPass(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresShadowMapPass); - } - - bool RequiresStencilBuffer() const - { - return this->operator&(LayerRenderPreparationResultFlagValues::RequiresStencilBuffer); - } - void SetRequiresStencilBuffer(bool inValue) - { - clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresStencilBuffer); - } - }; - - struct SLayerRenderPreparationResult : public SLayerRenderHelper - { - SEffect *m_LastEffect; - SLayerRenderPreparationResultFlags m_Flags; - QT3DSU32 m_MaxAAPassIndex; - SLayerRenderPreparationResult() - : m_LastEffect(NULL) - , m_MaxAAPassIndex(0) - { - } - SLayerRenderPreparationResult(const SLayerRenderHelper &inHelper) - : SLayerRenderHelper(inHelper) - , m_LastEffect(NULL) - , m_MaxAAPassIndex(0) - { - } - }; - - struct SRenderableNodeEntry - { - SNode *m_Node; - TNodeLightEntryList m_Lights; - SRenderableNodeEntry() - : m_Node(NULL) - { - } - SRenderableNodeEntry(SNode &inNode) - : m_Node(&inNode) - { - } - }; - - struct SScopedLightsListScope - { - nvvector &m_LightsList; - nvvector &m_LightDirList; - QT3DSU32 m_ListOriginalSize; - SScopedLightsListScope(nvvector &inLights, nvvector &inDestLightDirList, - nvvector &inSrcLightDirList, - TNodeLightEntryList &inScopedLights) - : m_LightsList(inLights) - , m_LightDirList(inDestLightDirList) - , m_ListOriginalSize(m_LightsList.size()) - { - for (TNodeLightEntryList::iterator iter = inScopedLights.begin(), - end = inScopedLights.end(); - iter != end; ++iter) { - m_LightsList.push_back(iter->m_Light); - m_LightDirList.push_back(inSrcLightDirList[iter->m_LightIndex]); - } - } - ~SScopedLightsListScope() - { - m_LightsList.resize(m_ListOriginalSize); - m_LightDirList.resize(m_ListOriginalSize); - } - }; - - struct SDefaultMaterialPreparationResult - { - SRenderableImage *m_FirstImage; - QT3DSF32 m_Opacity; - SRenderableObjectFlags m_RenderableFlags; - SShaderDefaultMaterialKey m_MaterialKey; - bool m_Dirty; - - SDefaultMaterialPreparationResult(SShaderDefaultMaterialKey inMaterialKey); - }; - - // Data used strictly in the render preparation step. - struct SLayerRenderPreparationData - { - typedef void (*TRenderRenderableFunction)(SLayerRenderData &inData, - SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, - TShaderFeatureSet inShaderFeatures, - QT3DSU32 lightIndex, const SCamera &inCamera); - typedef nvhash_map TLightToNodeMap; - typedef Pool TNodeLightEntryPoolType; - - enum Enum { - MAX_AA_LEVELS = 8, - MAX_TEMPORAL_AA_LEVELS = 2, - }; - - SLayer &m_Layer; - Qt3DSRendererImpl &m_Renderer; - NVAllocatorCallback &m_Allocator; - // List of nodes we can render, not all may be active. Found by doing a depth-first - // search through m_FirstChild if length is zero. - - TNodeLightEntryPoolType m_RenderableNodeLightEntryPool; - nvvector m_RenderableNodes; - TLightToNodeMap m_LightToNodeMap; // map of lights to nodes to cache if we have looked up a - // given scoped light yet. - // Built at the same time as the renderable nodes map. - // these are processed so they are available when the shaders for the models - // are being generated. - nvvector m_CamerasAndLights; - - // Results of prepare for render. - SCamera *m_Camera; - nvvector m_Lights; // Only contains lights that are global. - TRenderableObjectList m_OpaqueObjects; - TRenderableObjectList m_TransparentObjects; - // Sorted lists of the rendered objects. There may be other transforms applied so - // it is simplest to duplicate the lists. - TRenderableObjectList m_RenderedOpaqueObjects; - TRenderableObjectList m_RenderedTransparentObjects; - QT3DSMat44 m_ViewProjection; - SClippingFrustum m_ClippingFrustum; - Option m_LayerPrepResult; - // Widgets drawn at particular times during the rendering process - nvvector m_IRenderWidgets; - Option m_CameraDirection; - // Scoped lights need a level of indirection into a light direction list. The source light - // directions list is as long as there are lights on the layer. It holds invalid - // information for - // any lights that are not both active and scoped; but the relative position for a given - // light - // in this list is completely constant and immutable; this relative position is saved on a - // structure - // and used when looking up the light direction for a given light. - nvvector m_SourceLightDirections; - nvvector m_LightDirections; - TModelContextPtrList m_ModelContexts; - NVScopedRefCounted m_LastFrameOffscreenRenderer; - - eastl::vector m_Features; - CRegisteredString m_CGLightingFeatureName; - bool m_FeaturesDirty; - size_t m_FeatureSetHash; - bool m_TooManyLightsError; - - // shadow mapps - NVScopedRefCounted m_ShadowMapManager; - - SLayerRenderPreparationData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer); - virtual ~SLayerRenderPreparationData(); - bool GetOffscreenRenderer(); - bool GetShadowMapManager(); - bool NeedsWidgetTexture() const; - - SShaderDefaultMaterialKey GenerateLightingKey(DefaultMaterialLighting::Enum inLightingType); - - void PrepareImageForRender(SImage &inImage, ImageMapTypes::Enum inMapType, - SRenderableImage *&ioFirstImage, SRenderableImage *&ioNextImage, - SRenderableObjectFlags &ioFlags, - SShaderDefaultMaterialKey &ioGeneratedShaderKey, - QT3DSU32 inImageIndex); - - SDefaultMaterialPreparationResult - PrepareDefaultMaterialForRender(SDefaultMaterial &inMaterial, - SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity, - bool inClearMaterialFlags); - - SDefaultMaterialPreparationResult - PrepareCustomMaterialForRender(SCustomMaterial &inMaterial, - SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity); - - bool PrepareModelForRender(SModel &inModel, const QT3DSMat44 &inViewProjection, - const Option &inClipFrustum, - TNodeLightEntryList &inScopedLights); - - bool PrepareTextForRender(SText &inText, const QT3DSMat44 &inViewProjection, - QT3DSF32 inTextScaleFactor, - SLayerRenderPreparationResultFlags &ioFlags); - bool PreparePathForRender(SPath &inPath, const QT3DSMat44 &inViewProjection, - const Option &inClipFrustum, - SLayerRenderPreparationResultFlags &ioFlags); - // Helper function used during PRepareForRender and PrepareAndRender - bool PrepareRenderablesForRender(const QT3DSMat44 &inViewProjection, - const Option &inClipFrustum, - QT3DSF32 inTextScaleFactor, - SLayerRenderPreparationResultFlags &ioFlags); - - // returns true if this object will render something different than it rendered the last - // time. - virtual void PrepareForRender(const QSize &inViewportDimensions); - bool CheckLightProbeDirty(SImage &inLightProbe); - void AddRenderWidget(IRenderWidget &inWidget); - void SetShaderFeature(const char *inName, bool inValue); - void SetShaderFeature(CRegisteredString inName, bool inValue); - NVConstDataRef GetShaderFeatureSet(); - size_t GetShaderFeatureSetHash(); - // The graph object is not const because this traversal updates dirty state on the objects. - eastl::pair ResolveReferenceMaterial(SGraphObject *inMaterial); - - QT3DSVec3 GetCameraDirection(); - // Per-frame cache of renderable objects post-sort. - NVDataRef GetOpaqueRenderableObjects(); - // If layer depth test is false, this may also contain opaque objects. - NVDataRef GetTransparentRenderableObjects(); - - virtual void ResetForFrame(); - - // The render list and gl context are setup for what the embedded item will - // need. - virtual SOffscreenRendererEnvironment CreateOffscreenRenderEnvironment() = 0; - - virtual IRenderTask &CreateRenderToTextureRunnable() = 0; - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.cpp deleted file mode 100644 index c3fc2d4d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.cpp +++ /dev/null @@ -1,2999 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRendererImpl.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include "../RendererImpl/Qt3DSVertexPipelineImpl.h" - -// This adds support for the depth buffers in the shader so we can do depth -// texture-based effects. -#define QT3DS_RENDER_SUPPORT_DEPTH_TEXTURE 1 - -namespace qt3ds { -namespace render { - - void STextShader::Render(NVRenderTexture2D &inTexture, - const STextScaleAndOffset &inScaleAndOffset, const QT3DSVec4 &inTextColor, - const QT3DSMat44 &inMVP, const QT3DSVec2 &inCameraVec, - NVRenderContext &inRenderContext, - NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, - const STextTextureDetails &inTextTextureDetails, - const QT3DSVec3 &inBackgroundColor) - { - inRenderContext.SetCullingEnabled(false); - inRenderContext.SetActiveShader(&m_Shader); - m_MVP.Set(inMVP); - m_Sampler.Set(&inTexture); - m_TextColor.Set(inTextColor); - m_Dimensions.Set(QT3DSVec4(inScaleAndOffset.m_TextScale.x, inScaleAndOffset.m_TextScale.y, - inScaleAndOffset.m_TextOffset.x, inScaleAndOffset.m_TextOffset.y)); - m_CameraProperties.Set(inCameraVec); - STextureDetails theTextureDetails = inTexture.GetTextureDetails(); - QT3DSF32 theWidthScale = - (QT3DSF32)inTextTextureDetails.m_TextWidth / (QT3DSF32)theTextureDetails.m_Width; - QT3DSF32 theHeightScale = - (QT3DSF32)inTextTextureDetails.m_TextHeight / (QT3DSF32)theTextureDetails.m_Height; - m_BackgroundColor.Set(inBackgroundColor); - - m_TextDimensions.Set( - QT3DSVec3(theWidthScale, theHeightScale, inTextTextureDetails.m_FlipY ? 1.0f : 0.0f)); - inRenderContext.SetInputAssembler(&inInputAssemblerBuffer); - inRenderContext.Draw(NVRenderDrawMode::Triangles, count, 0); - } - - void STextShader::RenderPath(NVRenderPathFontItem &inPathFontItem, - NVRenderPathFontSpecification &inPathFontSpec, - const STextScaleAndOffset &inScaleAndOffset, - const QT3DSVec4 &inTextColor, const QT3DSMat44 &inViewProjection, - const QT3DSMat44 &inModel, const QT3DSVec2 &, - NVRenderContext &inRenderContext, - const STextTextureDetails &inTextTextureDetails, - const QT3DSVec3 &inBackgroundColor) - { - qt3ds::render::NVRenderBoolOp::Enum theDepthFunction = inRenderContext.GetDepthFunction(); - bool isDepthEnabled = inRenderContext.IsDepthTestEnabled(); - bool isStencilEnabled = inRenderContext.IsStencilTestEnabled(); - bool isDepthWriteEnabled = inRenderContext.IsDepthWriteEnabled(); - qt3ds::render::NVRenderStencilFunctionArgument theArg(qt3ds::render::NVRenderBoolOp::NotEqual, 0, - 0xFF); - qt3ds::render::NVRenderStencilOperationArgument theOpArg(qt3ds::render::NVRenderStencilOp::Keep, - qt3ds::render::NVRenderStencilOp::Keep, - qt3ds::render::NVRenderStencilOp::Zero); - NVScopedRefCounted depthStencilState = - inRenderContext.CreateDepthStencilState(isDepthEnabled, isDepthWriteEnabled, - theDepthFunction, false, theArg, theArg, - theOpArg, theOpArg); - - inRenderContext.SetActiveShader(NULL); - inRenderContext.SetCullingEnabled(false); - - inRenderContext.SetDepthStencilState(depthStencilState); - - // setup transform - QT3DSMat44 offsetMatrix = QT3DSMat44::createIdentity(); - offsetMatrix.setPosition(QT3DSVec3( - inScaleAndOffset.m_TextOffset.x - (QT3DSF32)inTextTextureDetails.m_TextWidth / 2.0f, - inScaleAndOffset.m_TextOffset.y - (QT3DSF32)inTextTextureDetails.m_TextHeight / 2.0f, - 0.0)); - - QT3DSMat44 pathMatrix = inPathFontItem.GetTransform(); - - inRenderContext.SetPathProjectionMatrix(inViewProjection); - inRenderContext.SetPathModelViewMatrix(inModel * offsetMatrix * pathMatrix); - - // first pass - inPathFontSpec.StencilFillPathInstanced(inPathFontItem); - - // second pass - inRenderContext.SetActiveProgramPipeline(m_ProgramPipeline); - m_TextColor.Set(inTextColor); - m_BackgroundColor.Set(inBackgroundColor); - - inRenderContext.SetStencilTestEnabled(true); - inPathFontSpec.CoverFillPathInstanced(inPathFontItem); - - inRenderContext.SetStencilTestEnabled(isStencilEnabled); - inRenderContext.SetDepthFunction(theDepthFunction); - - inRenderContext.SetActiveProgramPipeline(NULL); - } - - void STextShader::Render2D(NVRenderTexture2D &inTexture, const QT3DSVec4 &inTextColor, - const QT3DSMat44 &inMVP, NVRenderContext &inRenderContext, - NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, - QT3DSVec2 inVertexOffsets) - { - // inRenderContext.SetCullingEnabled( false ); - inRenderContext.SetBlendingEnabled(true); - inRenderContext.SetDepthWriteEnabled(false); - inRenderContext.SetDepthTestEnabled(false); - - inRenderContext.SetActiveShader(&m_Shader); - - qt3ds::render::NVRenderBlendFunctionArgument blendFunc( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - - inRenderContext.SetBlendFunction(blendFunc); - inRenderContext.SetBlendEquation(blendEqu); - - m_MVP.Set(inMVP); - m_Sampler.Set(&inTexture); - m_TextColor.Set(inTextColor); - m_VertexOffsets.Set(inVertexOffsets); - - inRenderContext.SetInputAssembler(&inInputAssemblerBuffer); - inRenderContext.Draw(NVRenderDrawMode::Triangles, count, 0); - } - - using eastl::make_pair; - - static inline void AddVertexDepth(SShaderVertexCodeGenerator &vertexShader) - { - // near plane, far plane - vertexShader.AddInclude("viewProperties.glsllib"); - vertexShader.AddVarying("vertex_depth", "float"); - // the w coordinate is the unormalized distance to the object from the camera - // We want the normalized distance, with 0 representing the far plane and 1 representing - // the near plane, of the object in the vertex depth variable. - - vertexShader << "\tvertex_depth = calculateVertexDepth( camera_properties, gl_Position );" - << Endl; - } - - // Helper implements the vertex pipeline for mesh subsets when bound to the default material. - // Should be completely possible to use for custom materials with a bit of refactoring. - struct SSubsetMaterialVertexPipeline : public SVertexPipelineImpl - { - Qt3DSRendererImpl &m_Renderer; - SSubsetRenderable &m_Renderable; - TessModeValues::Enum m_TessMode; - - SSubsetMaterialVertexPipeline(Qt3DSRendererImpl &renderer, SSubsetRenderable &renderable, - bool inWireframeRequested) - : SVertexPipelineImpl(renderer.GetQt3DSContext().GetAllocator(), - renderer.GetQt3DSContext().GetDefaultMaterialShaderGenerator(), - renderer.GetQt3DSContext().GetShaderProgramGenerator(), - renderer.GetQt3DSContext().GetStringTable(), false) - , m_Renderer(renderer) - , m_Renderable(renderable) - , m_TessMode(TessModeValues::NoTess) - { - if (m_Renderer.GetContext().IsTessellationSupported()) { - m_TessMode = renderable.m_TessellationMode; - } - - if (m_Renderer.GetContext().IsGeometryStageSupported() - && m_TessMode != TessModeValues::NoTess) - m_Wireframe = inWireframeRequested; - } - - void InitializeTessControlShader() - { - if (m_TessMode == TessModeValues::NoTess - || ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl) == NULL) - return; - - IShaderStageGenerator &tessCtrlShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - - SetupTessIncludes(ShaderGeneratorStages::TessControl, m_TessMode); - - tessCtrlShader.Append("void main() {\n"); - - tessCtrlShader.Append("\tctWorldPos[0] = varWorldPos[0];"); - tessCtrlShader.Append("\tctWorldPos[1] = varWorldPos[1];"); - tessCtrlShader.Append("\tctWorldPos[2] = varWorldPos[2];"); - - if (m_TessMode == TessModeValues::TessPhong - || m_TessMode == TessModeValues::TessNPatch) { - tessCtrlShader.Append("\tctNorm[0] = varObjectNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = varObjectNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = varObjectNormal[2];"); - } - if (m_TessMode == TessModeValues::TessNPatch) { - tessCtrlShader.Append("\tctTangent[0] = varTangent[0];"); - tessCtrlShader.Append("\tctTangent[1] = varTangent[1];"); - tessCtrlShader.Append("\tctTangent[2] = varTangent[2];"); - } - - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - } - void InitializeTessEvaluationShader() - { - if (m_TessMode == TessModeValues::NoTess - || ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval) == NULL) - return; - - IShaderStageGenerator &tessEvalShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - SetupTessIncludes(ShaderGeneratorStages::TessEval, m_TessMode); - - if (m_TessMode == TessModeValues::TessLinear) - m_Renderer.GetQt3DSContext() - .GetDefaultMaterialShaderGenerator() - .AddDisplacementImageUniforms(tessEvalShader, m_DisplacementIdx, - m_DisplacementImage); - - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddUniform("normal_matrix", "mat3"); - - tessEvalShader.Append("void main() {"); - - if (m_TessMode == TessModeValues::TessNPatch) { - tessEvalShader.Append("\tctNorm[0] = varObjectNormalTC[0];"); - tessEvalShader.Append("\tctNorm[1] = varObjectNormalTC[1];"); - tessEvalShader.Append("\tctNorm[2] = varObjectNormalTC[2];"); - - tessEvalShader.Append("\tctTangent[0] = varTangentTC[0];"); - tessEvalShader.Append("\tctTangent[1] = varTangentTC[1];"); - tessEvalShader.Append("\tctTangent[2] = varTangentTC[2];"); - } - - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - } - - void FinalizeTessControlShader() - { - IShaderStageGenerator &tessCtrlShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - // add varyings we must pass through - typedef TStrTableStrMap::const_iterator TParamIter; - for (TParamIter iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - tessCtrlShader << "\t" << iter->first.c_str() - << "TC[gl_InvocationID] = " << iter->first.c_str() - << "[gl_InvocationID];\n"; - } - } - - void FinalizeTessEvaluationShader() - { - IShaderStageGenerator &tessEvalShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - eastl::string outExt(""); - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) - outExt = "TE"; - - // add varyings we must pass through - typedef TStrTableStrMap::const_iterator TParamIter; - if (m_TessMode == TessModeValues::TessNPatch) { - for (TParamIter iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() - << " = gl_TessCoord.z * " << iter->first.c_str() << "TC[0] + "; - tessEvalShader << "gl_TessCoord.x * " << iter->first.c_str() << "TC[1] + "; - tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[2];\n"; - } - - // transform the normal - if (m_GenerationFlags & GenerationFlagValues::WorldNormal) - tessEvalShader << "\n\tvarNormal" << outExt.c_str() - << " = normalize(normal_matrix * teNorm);\n"; - // transform the tangent - if (m_GenerationFlags & GenerationFlagValues::TangentBinormal) { - tessEvalShader << "\n\tvarTangent" << outExt.c_str() - << " = normalize(normal_matrix * teTangent);\n"; - // transform the binormal - tessEvalShader << "\n\tvarBinormal" << outExt.c_str() - << " = normalize(normal_matrix * teBinormal);\n"; - } - } else { - for (TParamIter iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() - << " = gl_TessCoord.x * " << iter->first.c_str() << "TC[0] + "; - tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[1] + "; - tessEvalShader << "gl_TessCoord.z * " << iter->first.c_str() << "TC[2];\n"; - } - - // displacement mapping makes only sense with linear tessellation - if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) { - IDefaultMaterialShaderGenerator::SImageVariableNames theNames = - m_Renderer.GetQt3DSContext() - .GetDefaultMaterialShaderGenerator() - .GetImageVariableNames(m_DisplacementIdx); - tessEvalShader << "\tpos.xyz = defaultMaterialFileDisplacementTexture( " - << theNames.m_ImageSampler << ", displaceAmount, " - << theNames.m_ImageFragCoords << outExt.c_str(); - tessEvalShader << ", varObjectNormal" << outExt.c_str() << ", pos.xyz );" - << Endl; - tessEvalShader << "\tvarWorldPos" << outExt.c_str() - << "= (model_matrix * pos).xyz;" << Endl; - tessEvalShader << "\tvarViewVector" << outExt.c_str() - << "= normalize(camera_position - " - << "varWorldPos" << outExt.c_str() << ");" << Endl; - } - - // transform the normal - tessEvalShader << "\n\tvarNormal" << outExt.c_str() - << " = normalize(normal_matrix * varObjectNormal" << outExt.c_str() - << ");\n"; - } - - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); - } - - void BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override - { - m_DisplacementIdx = displacementImageIdx; - m_DisplacementImage = displacementImage; - - TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); - if (m_TessMode != TessModeValues::NoTess) { - theStages |= ShaderGeneratorStages::TessControl; - theStages |= ShaderGeneratorStages::TessEval; - } - if (m_Wireframe) { - theStages |= ShaderGeneratorStages::Geometry; - } - ProgramGenerator().BeginProgram(theStages); - if (m_TessMode != TessModeValues::NoTess) { - InitializeTessControlShader(); - InitializeTessEvaluationShader(); - } - if (m_Wireframe) { - InitializeWireframeGeometryShader(); - } - // Open up each stage. - IShaderStageGenerator &vertexShader(Vertex()); - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader << "void main()" << Endl << "{" << Endl; - vertexShader << "\tvec3 uTransform;" << Endl; - vertexShader << "\tvec3 vTransform;" << Endl; - - if (displacementImage) { - GenerateUVCoords(); - MaterialGenerator().GenerateImageUVCoordinates(*this, displacementImageIdx, 0, - *displacementImage); - if (!HasTessellation()) { - vertexShader.AddUniform("displaceAmount", "float"); - // we create the world position setup here - // because it will be replaced with the displaced position - SetCode(GenerationFlagValues::WorldPosition); - vertexShader.AddUniform("model_matrix", "mat4"); - - vertexShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - IDefaultMaterialShaderGenerator::SImageVariableNames theVarNames = - MaterialGenerator().GetImageVariableNames(displacementImageIdx); - - vertexShader.AddUniform(theVarNames.m_ImageSampler, "sampler2D"); - - vertexShader - << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - << theVarNames.m_ImageSampler << ", displaceAmount, " - << theVarNames.m_ImageFragCoords << ", attr_norm, attr_pos );" << Endl; - AddInterpolationParameter("varWorldPos", "vec3"); - vertexShader.Append("\tvec3 local_model_world_position = (model_matrix * " - "vec4(displacedPos, 1.0)).xyz;"); - AssignOutput("varWorldPos", "local_model_world_position"); - } - } - // for tessellation we pass on the position in object coordinates - // Also note that gl_Position is written in the tess eval shader - if (HasTessellation()) - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - else { - vertexShader.AddUniform("model_view_projection", "mat4"); - if (displacementImage) - vertexShader.Append( - "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - else - vertexShader.Append( - "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - } - - if (HasTessellation()) { - GenerateWorldPosition(); - GenerateWorldNormal(); - GenerateObjectNormal(); - GenerateVarTangentAndBinormal(); - } - } - - void BeginFragmentGeneration() override - { - Fragment().AddUniform("material_diffuse", "vec4"); - Fragment() << "void main()" << Endl << "{" << Endl; - // We do not pass object opacity through the pipeline. - Fragment() << "\tfloat object_opacity = material_diffuse.a;" << Endl; - } - - void AssignOutput(const char8_t *inVarName, const char8_t *inVarValue) override - { - Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n"; - } - void DoGenerateUVCoords(QT3DSU32 inUVSet = 0) override - { - QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); - - if (inUVSet == 0) { - Vertex().AddIncoming("attr_uv0", "vec2"); - Vertex() << "\tvarTexCoord0 = attr_uv0;" << Endl; - } else if (inUVSet == 1) { - Vertex().AddIncoming("attr_uv1", "vec2"); - Vertex() << "\tvarTexCoord1 = attr_uv1;" << Endl; - } - } - - // fragment shader expects varying vertex normal - // lighting in vertex pipeline expects world_normal - void DoGenerateWorldNormal() override - { - IShaderStageGenerator &vertexGenerator(Vertex()); - vertexGenerator.AddIncoming("attr_norm", "vec3"); - vertexGenerator.AddUniform("normal_matrix", "mat3"); - if (HasTessellation() == false) { - vertexGenerator.Append( - "\tvec3 world_normal = normalize(normal_matrix * attr_norm).xyz;"); - vertexGenerator.Append("\tvarNormal = world_normal;"); - } - } - void DoGenerateObjectNormal() override - { - AddInterpolationParameter("varObjectNormal", "vec3"); - Vertex().Append("\tvarObjectNormal = attr_norm;"); - } - void DoGenerateWorldPosition() override - { - Vertex().Append( - "\tvec3 local_model_world_position = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); - AssignOutput("varWorldPos", "local_model_world_position"); - } - - void DoGenerateVarTangentAndBinormal() override - { - Vertex().AddIncoming("attr_textan", "vec3"); - Vertex().AddIncoming("attr_binormal", "vec3"); - - bool hasNPatchTessellation = m_TessMode == TessModeValues::TessNPatch; - - if (!hasNPatchTessellation) { - Vertex() << "\tvarTangent = normal_matrix * attr_textan;" << Endl - << "\tvarBinormal = normal_matrix * attr_binormal;" << Endl; - } else { - Vertex() << "\tvarTangent = attr_textan;" << Endl - << "\tvarBinormal = attr_binormal;" << Endl; - } - } - - void DoGenerateVertexColor() override - { - Vertex().AddIncoming("attr_color", "vec3"); - Vertex().Append("\tvarColor = attr_color;"); - } - - void EndVertexGeneration() override - { - - if (HasTessellation()) { - // finalize tess control shader - FinalizeTessControlShader(); - // finalize tess evaluation shader - FinalizeTessEvaluationShader(); - - TessControl().Append("}"); - TessEval().Append("}"); - } - if (m_Wireframe) { - // finalize geometry shader - FinalizeWireframeGeometryShader(); - Geometry().Append("}"); - } - Vertex().Append("}"); - } - - void EndFragmentGeneration() override { Fragment().Append("}"); } - - void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override - { - m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); - Vertex().AddOutgoing(inName, inType); - Fragment().AddIncoming(inName, inType); - if (HasTessellation()) { - eastl::string nameBuilder(inName); - nameBuilder.append("TC"); - TessControl().AddOutgoing(nameBuilder.c_str(), inType); - - nameBuilder.assign(inName); - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) { - nameBuilder.append("TE"); - Geometry().AddOutgoing(inName, inType); - } - TessEval().AddOutgoing(nameBuilder.c_str(), inType); - } - } - - IShaderStageGenerator &ActiveStage() override { return Vertex(); } - }; - - NVRenderShaderProgram *Qt3DSRendererImpl::GenerateShader(SSubsetRenderable &inRenderable, - TShaderFeatureSet inFeatureSet) - { - // build a string that allows us to print out the shader we are generating to the log. - // This is time consuming but I feel like it doesn't happen all that often and is very - // useful to users - // looking at the log file. - QLatin1String logPrefix("mesh subset pipeline-- "); - - m_GeneratedShaderString.clear(); - m_GeneratedShaderString.assign(logPrefix.data()); - - SShaderDefaultMaterialKey theKey(inRenderable.m_ShaderDescription); - theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = - m_qt3dsContext.GetStringTable().RegisterStr(m_GeneratedShaderString.c_str()); - NVRenderShaderProgram *cachedProgram = theCache.GetProgram(theCacheKey, inFeatureSet); - if (cachedProgram) - return cachedProgram; - - SSubsetMaterialVertexPipeline pipeline( - *this, inRenderable, - m_DefaultMaterialShaderKeyProperties.m_WireframeMode.GetValue(theKey)); - return m_qt3dsContext.GetDefaultMaterialShaderGenerator().GenerateShader( - inRenderable.m_Material, inRenderable.m_ShaderDescription, pipeline, inFeatureSet, - m_CurrentLayer->m_Lights, inRenderable.m_FirstImage, - inRenderable.m_RenderableFlags.HasTransparency(), - logPrefix.data()); - } - - // -------------- Special cases for shadows ------------------- - - SRenderableDepthPrepassShader * - Qt3DSRendererImpl::GetParaboloidDepthShader(TessModeValues::Enum inTessMode) - { - if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() - || inTessMode == TessModeValues::NoTess) { - return GetParaboloidDepthNoTessShader(); - } else if (inTessMode == TessModeValues::TessLinear) { - return GetParaboloidDepthTessLinearShader(); - } else if (inTessMode == TessModeValues::TessPhong) { - return GetParaboloidDepthTessPhongShader(); - } else if (inTessMode == TessModeValues::TessNPatch) { - return GetParaboloidDepthTessNPatchShader(); - } - - return GetParaboloidDepthNoTessShader(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthNoTessShader() - { - Option> &theDepthShader = - m_ParaboloidDepthShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("paraboloid depth shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - IShaderProgramGenerator::OutputParaboloidDepthVertex(vertexShader); - IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthTessLinearShader() - { - Option> &theDepthShader = - m_ParaboloidDepthTessLinearShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("paraboloid depth tess linear shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - // vertexShader.AddOutgoing("world_pos", "vec4"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - // vertexShader.Append("\tworld_pos = attr_pos;"); - vertexShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationLinear.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - // tessCtrlShader.AddOutgoing( "outUVTC", "vec2" ); - // tessCtrlShader.AddOutgoing( "outNormalTC", "vec3" ); - tessCtrlShader.Append("void main() {\n"); - // tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); - // tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); - // tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationLinear.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - IShaderProgramGenerator::OutputParaboloidDepthTessEval(tessEvalShader); - tessEvalShader.Append("}"); - - IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); - } - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthTessPhongShader() - { - Option> &theDepthShader = - m_ParaboloidDepthTessPhongShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("paraboloid depth tess phong shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - // vertexShader.AddOutgoing("world_pos", "vec4"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - // vertexShader.Append("\tworld_pos = attr_pos;"); - vertexShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationPhong.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - // tessCtrlShader.AddOutgoing( "outUVTC", "vec2" ); - // tessCtrlShader.AddOutgoing( "outNormalTC", "vec3" ); - tessCtrlShader.Append("void main() {\n"); - // tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); - // tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); - // tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationPhong.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - IShaderProgramGenerator::OutputParaboloidDepthTessEval(tessEvalShader); - tessEvalShader.Append("}"); - - IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); - } - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthTessNPatchShader() - { - Option> &theDepthShader = - m_ParaboloidDepthTessNPatchShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("paraboloid depth tess NPatch shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - // vertexShader.AddOutgoing("world_pos", "vec4"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - // vertexShader.Append("\tworld_pos = attr_pos;"); - vertexShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - // tessCtrlShader.AddOutgoing( "outUVTC", "vec2" ); - // tessCtrlShader.AddOutgoing( "outNormalTC", "vec3" ); - tessCtrlShader.Append("void main() {\n"); - // tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); - // tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); - // tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationNPatch.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - IShaderProgramGenerator::OutputParaboloidDepthTessEval(tessEvalShader); - tessEvalShader.Append("}"); - - IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); - } - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader * - Qt3DSRendererImpl::GetCubeShadowDepthShader(TessModeValues::Enum inTessMode) - { - if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() - || inTessMode == TessModeValues::NoTess) { - return GetCubeDepthNoTessShader(); - } else if (inTessMode == TessModeValues::TessLinear) { - return GetCubeDepthTessLinearShader(); - } else if (inTessMode == TessModeValues::TessPhong) { - return GetCubeDepthTessPhongShader(); - } else if (inTessMode == TessModeValues::TessNPatch) { - return GetCubeDepthTessNPatchShader(); - } - - return GetCubeDepthNoTessShader(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthNoTessShader() - { - Option> &theDepthShader = - m_CubemapDepthShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("cubemap face depth shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - - if (!depthShaderProgram) { - // GetProgramGenerator().BeginProgram( - // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | - // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( - // ShaderGeneratorStages::Geometry ) ); - - IShaderProgramGenerator::OutputCubeFaceDepthVertex(vertexShader); - // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); - IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); - } else if (theCache.IsShaderCachePersistenceEnabled()) { - // we load from shader cache set default shader stages - GetProgramGenerator().BeginProgram(); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthTessLinearShader() - { - Option> &theDepthShader = - m_CubemapDepthTessLinearShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("cubemap face depth linear tess shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - - if (!depthShaderProgram) { - // GetProgramGenerator().BeginProgram( - // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | - // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( - // ShaderGeneratorStages::Geometry ) ); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("}"); - - // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); - IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); - - tessCtrlShader.AddInclude("tessellationLinear.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationLinear.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddUniform("model_matrix", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tworld_pos = model_matrix * pos;"); - tessEvalShader.Append("\tworld_pos /= world_pos.w;"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - tessEvalShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthTessPhongShader() - { - Option> &theDepthShader = - m_CubemapDepthTessPhongShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("cubemap face depth phong tess shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - - if (!depthShaderProgram) { - // GetProgramGenerator().BeginProgram( - // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | - // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( - // ShaderGeneratorStages::Geometry ) ); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddIncoming("attr_norm", "vec3"); - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("}"); - - // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); - IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); - - tessCtrlShader.AddInclude("tessellationPhong.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationPhong.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddUniform("model_matrix", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tworld_pos = model_matrix * pos;"); - tessEvalShader.Append("\tworld_pos /= world_pos.w;"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - tessEvalShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthTessNPatchShader() - { - Option> &theDepthShader = - m_CubemapDepthTessNPatchShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("cubemap face depth npatch tess shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - - if (!depthShaderProgram) { - // GetProgramGenerator().BeginProgram( - // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | - // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( - // ShaderGeneratorStages::Geometry ) ); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddIncoming("attr_norm", "vec3"); - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("}"); - - // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); - IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); - - tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); - tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append( - "\toutNormalTC[gl_InvocationID] = outNormal[gl_InvocationID];\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationNPatch.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddUniform("model_matrix", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tctNorm[0] = outNormalTC[0];"); - tessEvalShader.Append("\tctNorm[1] = outNormalTC[1];"); - tessEvalShader.Append("\tctNorm[2] = outNormalTC[2];"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tworld_pos = model_matrix * pos;"); - tessEvalShader.Append("\tworld_pos /= world_pos.w;"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - tessEvalShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader * - Qt3DSRendererImpl::GetOrthographicDepthShader(TessModeValues::Enum inTessMode) - { - if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() - || inTessMode == TessModeValues::NoTess) { - return GetOrthographicDepthNoTessShader(); - } else if (inTessMode == TessModeValues::TessLinear) { - return GetOrthographicDepthTessLinearShader(); - } else if (inTessMode == TessModeValues::TessPhong) { - return GetOrthographicDepthTessPhongShader(); - } else if (inTessMode == TessModeValues::TessNPatch) { - return GetOrthographicDepthTessNPatchShader(); - } - - return GetOrthographicDepthNoTessShader(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthNoTessShader() - { - Option> &theDepthShader = - m_OrthographicDepthShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("orthographic depth shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader.AddOutgoing("outDepth", "vec3"); - vertexShader.Append("void main() {"); - vertexShader.Append( - " gl_Position = model_view_projection * vec4( attr_pos, 1.0 );"); - vertexShader.Append(" outDepth.x = gl_Position.z / gl_Position.w;"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfloat depth = (outDepth.x + 1.0) * 0.5;"); - fragmentShader.Append("\tfragOutput = vec4(depth);"); - fragmentShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthTessLinearShader() - { - Option> &theDepthShader = - m_OrthographicDepthTessLinearShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("orthographic depth tess linear shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfloat depth = (outDepth.x + 1.0) * 0.5;"); - fragmentShader.Append("\tfragOutput = vec4(depth);"); - fragmentShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationLinear.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationLinear.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddOutgoing("outDepth", "vec3"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - tessEvalShader.Append("\toutDepth.x = gl_Position.z / gl_Position.w;"); - tessEvalShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthTessPhongShader() - { - Option> &theDepthShader = - m_OrthographicDepthTessPhongShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("orthographic depth tess phong shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddIncoming("attr_norm", "vec3"); - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfloat depth = (outDepth.x + 1.0) * 0.5;"); - fragmentShader.Append("\tfragOutput = vec4(depth);"); - fragmentShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationPhong.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationPhong.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddOutgoing("outDepth", "vec3"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - tessEvalShader.Append("\toutDepth.x = gl_Position.z / gl_Position.w;"); - tessEvalShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthTessNPatchShader() - { - Option> &theDepthShader = - m_OrthographicDepthTessNPatchShader; - - if (theDepthShader.hasValue() == false) { - TStrType name; - name.assign("orthographic depth tess npatch shader"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddIncoming("attr_norm", "vec3"); - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - fragmentShader.AddUniform("model_view_projection", "mat4"); - fragmentShader.AddUniform("camera_properties", "vec2"); - fragmentShader.AddUniform("camera_position", "vec3"); - fragmentShader.AddUniform("camera_direction", "vec3"); - fragmentShader.AddInclude("depthpass.glsllib"); - - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - // fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); - fragmentShader.Append("\tfloat depth = (outDepth.x - camera_properties.x) / " - "(camera_properties.y - camera_properties.x);"); - fragmentShader.Append("\tfragOutput = vec4(depth);"); - fragmentShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationNPatch.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddUniform("model_matrix", "mat4"); - tessEvalShader.AddOutgoing("outDepth", "vec3"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - tessEvalShader.Append("\toutDepth.x = gl_Position.z / gl_Position.w;"); - tessEvalShader.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthShader = NVScopedRefCounted(); - } - } - - return theDepthShader.getValue(); - } - - // --------------------------------- - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetDepthPrepassShader(bool inDisplaced) - { - Option> &theDepthPrePassShader = - (!inDisplaced) ? m_DepthPrepassShader : m_DepthPrepassShaderDisplaced; - - if (theDepthPrePassShader.hasValue() == false) { - // check if we do displacement mapping - TStrType name; - name.assign("depth prepass shader"); - if (inDisplaced) - name.append(" displacement"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.Append("void main() {"); - - if (inDisplaced) { - GetQt3DSContext() - .GetDefaultMaterialShaderGenerator() - .AddDisplacementMappingForDepthPass(vertexShader); - } else { - vertexShader.Append( - "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - } - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); - fragmentShader.Append("}"); - } else if (theCache.IsShaderCachePersistenceEnabled()) { - // we load from shader cache set default shader stages - GetProgramGenerator().BeginProgram(); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthPrePassShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthPrePassShader = NVScopedRefCounted(); - } - } - return theDepthPrePassShader.getValue(); - } - - SRenderableDepthPrepassShader * - Qt3DSRendererImpl::GetDepthTessPrepassShader(TessModeValues::Enum inTessMode, bool inDisplaced) - { - if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() - || inTessMode == TessModeValues::NoTess) { - return GetDepthPrepassShader(inDisplaced); - } else if (inTessMode == TessModeValues::TessLinear) { - return GetDepthTessLinearPrepassShader(inDisplaced); - } else if (inTessMode == TessModeValues::TessPhong) { - return GetDepthTessPhongPrepassShader(); - } else if (inTessMode == TessModeValues::TessNPatch) { - return GetDepthTessNPatchPrepassShader(); - } - - return GetDepthPrepassShader(inDisplaced); - } - - SRenderableDepthPrepassShader * - Qt3DSRendererImpl::GetDepthTessLinearPrepassShader(bool inDisplaced) - { - Option> &theDepthPrePassShader = - (!inDisplaced) ? m_DepthTessLinearPrepassShader - : m_DepthTessLinearPrepassShaderDisplaced; - - if (theDepthPrePassShader.hasValue() == false) { - // check if we do displacement mapping - TStrType name; - name.assign("depth tess linear prepass shader"); - if (inDisplaced) - name.append(" displacement"); - - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexShader.AddIncoming("attr_pos", "vec3"); - if (inDisplaced) { - vertexShader.AddIncoming("attr_uv0", "vec2"); - vertexShader.AddIncoming("attr_norm", "vec3"); - - vertexShader.AddUniform("displacementMap_rot", "vec4"); - vertexShader.AddUniform("displacementMap_offset", "vec3"); - - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.AddOutgoing("outUV", "vec2"); - } - vertexShader.AddOutgoing("outWorldPos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader.AddUniform("model_matrix", "mat4"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - if (inDisplaced) { - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, " - "displacementMap_rot.y, displacementMap_offset.x );"); - vertexShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, " - "displacementMap_rot.w, displacementMap_offset.y );"); - vertexShader.AddInclude( - "defaultMaterialLighting.glsllib"); // getTransformedUVCoords is in the - // lighting code addition. - vertexShader << "\tvec2 uv_coords = attr_uv0;" << Endl; - vertexShader << "\toutUV = getTransformedUVCoords( vec3( uv_coords, 1.0), " - "uTransform, vTransform );\n"; - } - vertexShader.Append("\toutWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); - fragmentShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationLinear.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.AddOutgoing("outUVTC", "vec2"); - tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); - tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); - tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - - if (inDisplaced) { - tessCtrlShader.Append("\toutUVTC[gl_InvocationID] = outUV[gl_InvocationID];"); - tessCtrlShader.Append( - "\toutNormalTC[gl_InvocationID] = outNormal[gl_InvocationID];"); - } - - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationLinear.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - if (inDisplaced) { - tessEvalShader.AddUniform("displacementSampler", "sampler2D"); - tessEvalShader.AddUniform("displaceAmount", "float"); - tessEvalShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - } - tessEvalShader.AddOutgoing("outUV", "vec2"); - tessEvalShader.AddOutgoing("outNormal", "vec3"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - - if (inDisplaced) { - tessEvalShader << "\toutUV = gl_TessCoord.x * outUVTC[0] + gl_TessCoord.y * " - "outUVTC[1] + gl_TessCoord.z * outUVTC[2];" - << Endl; - tessEvalShader - << "\toutNormal = gl_TessCoord.x * outNormalTC[0] + gl_TessCoord.y * " - "outNormalTC[1] + gl_TessCoord.z * outNormalTC[2];" - << Endl; - tessEvalShader - << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - "displacementSampler , displaceAmount, outUV , outNormal, pos.xyz );" - << Endl; - tessEvalShader.Append( - "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - } else - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); - - tessEvalShader.Append("}"); - } else if (theCache.IsShaderCachePersistenceEnabled()) { - // we load from shader cache set default shader stages - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - } - - SShaderCacheProgramFlags theFlags; - theFlags.SetTessellationEnabled(true); - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - name.c_str(), theFlags, TShaderFeatureSet()); - - if (depthShaderProgram) { - theDepthPrePassShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - theDepthPrePassShader = NVScopedRefCounted(); - } - } - return theDepthPrePassShader->mPtr; - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetDepthTessPhongPrepassShader() - { - if (m_DepthTessPhongPrepassShader.hasValue() == false) { - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = - m_qt3dsContext.GetStringTable().RegisterStr("depth tess phong prepass shader"); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddIncoming("attr_norm", "vec3"); - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.AddOutgoing("outWorldPos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader.AddUniform("model_matrix", "mat4"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("\toutWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); - fragmentShader.Append("}"); - - tessCtrlShader.AddInclude("tessellationPhong.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); - tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); - tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); - tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationPhong.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); - tessEvalShader.Append("}"); - } else if (theCache.IsShaderCachePersistenceEnabled()) { - // we load from shader cache set default shader stages - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - } - - SShaderCacheProgramFlags theFlags; - theFlags.SetTessellationEnabled(true); - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - "depth tess phong prepass shader", theFlags, TShaderFeatureSet()); - - if (depthShaderProgram) { - m_DepthTessPhongPrepassShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - m_DepthTessPhongPrepassShader = NVScopedRefCounted(); - } - } - return m_DepthTessPhongPrepassShader->mPtr; - } - - SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetDepthTessNPatchPrepassShader() - { - if (m_DepthTessNPatchPrepassShader.hasValue() == false) { - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = - m_qt3dsContext.GetStringTable().RegisterStr("depth tess npatch prepass shader"); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &vertexShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &tessCtrlShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - IShaderStageGenerator &tessEvalShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - IShaderStageGenerator &fragmentShader( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddIncoming("attr_norm", "vec3"); - vertexShader.AddOutgoing("outNormal", "vec3"); - vertexShader.AddOutgoing("outWorldPos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader.AddUniform("model_matrix", "mat4"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - vertexShader.Append("\toutWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); - vertexShader.Append("\toutNormal = attr_norm;"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); - fragmentShader.Append("}"); - - tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); - tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - tessCtrlShader.Append("void main() {\n"); - tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); - tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); - tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); - tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tctTangent[0] = outNormal[0];"); // we don't care for the tangent - tessCtrlShader.Append("\tctTangent[1] = outNormal[1];"); - tessCtrlShader.Append("\tctTangent[2] = outNormal[2];"); - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); - tessCtrlShader.Append( - "\toutNormalTC[gl_InvocationID] = outNormal[gl_InvocationID];\n"); - tessCtrlShader.Append("}"); - - tessEvalShader.AddInclude("tessellationNPatch.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.Append("void main() {"); - tessEvalShader.Append("\tctNorm[0] = outNormalTC[0];"); - tessEvalShader.Append("\tctNorm[1] = outNormalTC[1];"); - tessEvalShader.Append("\tctNorm[2] = outNormalTC[2];"); - tessEvalShader.Append( - "\tctTangent[0] = outNormalTC[0];"); // we don't care for the tangent - tessEvalShader.Append("\tctTangent[1] = outNormalTC[1];"); - tessEvalShader.Append("\tctTangent[2] = outNormalTC[2];"); - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); - tessEvalShader.Append("}"); - } else if (theCache.IsShaderCachePersistenceEnabled()) { - // we load from shader cache set default shader stages - GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( - ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl - | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); - } - - SShaderCacheProgramFlags theFlags; - theFlags.SetTessellationEnabled(true); - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - "depth tess npatch prepass shader", theFlags, TShaderFeatureSet()); - - if (depthShaderProgram) { - m_DepthTessNPatchPrepassShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), - SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); - } else { - m_DepthTessNPatchPrepassShader = - NVScopedRefCounted(); - } - } - return m_DepthTessNPatchPrepassShader->mPtr; - } - - SDefaultAoPassShader *Qt3DSRendererImpl::GetDefaultAoPassShader(TShaderFeatureSet inFeatureSet) - { - if (m_DefaultAoPassShader.hasValue() == false) { - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = - m_qt3dsContext.GetStringTable().RegisterStr("fullscreen AO pass shader"); - NVRenderShaderProgram *aoPassShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!aoPassShaderProgram) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &theVertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &theFragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - theVertexGenerator.AddIncoming("attr_pos", "vec3"); - theVertexGenerator.AddIncoming("attr_uv", "vec2"); - theVertexGenerator.AddOutgoing("uv_coords", "vec2"); - theVertexGenerator.Append("void main() {"); - theVertexGenerator.Append("\tgl_Position = vec4(attr_pos.xy, 0.5, 1.0 );"); - theVertexGenerator.Append("\tuv_coords = attr_uv;"); - theVertexGenerator.Append("}"); - - // fragmentGenerator.AddInclude( "SSAOCustomMaterial.glsllib" ); - theFragmentGenerator.AddInclude("viewProperties.glsllib"); - theFragmentGenerator.AddInclude("screenSpaceAO.glsllib"); - if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) { - theFragmentGenerator - << "\tuniform vec4 ao_properties;" << Endl - << "\tuniform vec4 ao_properties2;" << Endl - << "\tuniform vec4 shadow_properties;" << Endl - << "\tuniform vec4 aoScreenConst;" << Endl - << "\tuniform vec4 UvToEyeConst;" << Endl; - } else { - theFragmentGenerator - << "layout (std140) uniform cbAoShadow { " << Endl << "\tvec4 ao_properties;" - << Endl << "\tvec4 ao_properties2;" << Endl << "\tvec4 shadow_properties;" - << Endl << "\tvec4 aoScreenConst;" << Endl << "\tvec4 UvToEyeConst;" << Endl - << "};" << Endl; - } - theFragmentGenerator.AddUniform("camera_direction", "vec3"); - theFragmentGenerator.AddUniform("depth_sampler", "sampler2D"); - theFragmentGenerator.Append("void main() {"); - theFragmentGenerator << "\tfloat aoFactor;" << Endl; - theFragmentGenerator << "\tvec3 screenNorm;" << Endl; - - // We're taking multiple depth samples and getting the derivatives at each of them - // to get a more - // accurate view space normal vector. When we do only one, we tend to get bizarre - // values at the edges - // surrounding objects, and this also ends up giving us weird AO values. - // If we had a proper screen-space normal map, that would also do the trick. - if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) { - theFragmentGenerator.AddUniform("depth_sampler_size", "vec2"); - theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );"); - theFragmentGenerator.Append("\tfloat depth = getDepthValue( " - "texture2D(depth_sampler, vec2(iCoords)" - " / depth_sampler_size), camera_properties );"); - theFragmentGenerator.Append( - "\tdepth = depthValueToLinearDistance( depth, camera_properties );"); - theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / " - "(camera_properties.y - camera_properties.x);"); - theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( " - "texture2D(depth_sampler, vec2(iCoords+ivec2(1))" - " / depth_sampler_size), camera_properties );"); - theFragmentGenerator.Append( - "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );"); - theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( " - "texture2D(depth_sampler, vec2(iCoords-ivec2(1))" - " / depth_sampler_size), camera_properties );"); - } else { - theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );"); - theFragmentGenerator.Append("\tfloat depth = getDepthValue( " - "texelFetch(depth_sampler, iCoords, 0), " - "camera_properties );"); - theFragmentGenerator.Append( - "\tdepth = depthValueToLinearDistance( depth, camera_properties );"); - theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / " - "(camera_properties.y - camera_properties.x);"); - theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( " - "texelFetch(depth_sampler, iCoords+ivec2(1), 0), " - "camera_properties );"); - theFragmentGenerator.Append( - "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );"); - theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( " - "texelFetch(depth_sampler, iCoords-ivec2(1), 0), " - "camera_properties );"); - } - theFragmentGenerator.Append( - "\tdepth3 = depthValueToLinearDistance( depth, camera_properties );"); - theFragmentGenerator.Append("\tvec3 tanU = vec3(10, 0, dFdx(depth));"); - theFragmentGenerator.Append("\tvec3 tanV = vec3(0, 10, dFdy(depth));"); - theFragmentGenerator.Append("\tscreenNorm = normalize(cross(tanU, tanV));"); - theFragmentGenerator.Append("\ttanU = vec3(10, 0, dFdx(depth2));"); - theFragmentGenerator.Append("\ttanV = vec3(0, 10, dFdy(depth2));"); - theFragmentGenerator.Append("\tscreenNorm += normalize(cross(tanU, tanV));"); - theFragmentGenerator.Append("\ttanU = vec3(10, 0, dFdx(depth3));"); - theFragmentGenerator.Append("\ttanV = vec3(0, 10, dFdy(depth3));"); - theFragmentGenerator.Append("\tscreenNorm += normalize(cross(tanU, tanV));"); - theFragmentGenerator.Append("\tscreenNorm = -normalize(screenNorm);"); - - theFragmentGenerator.Append("\taoFactor = \ - SSambientOcclusion( depth_sampler, screenNorm, ao_properties, ao_properties2, \ - camera_properties, aoScreenConst, UvToEyeConst );"); - - theFragmentGenerator.Append( - "\tgl_FragColor = vec4(aoFactor, aoFactor, aoFactor, 1.0);"); - - theFragmentGenerator.Append("}"); - } - - aoPassShaderProgram = GetProgramGenerator().CompileGeneratedShader( - "fullscreen AO pass shader", SShaderCacheProgramFlags(), inFeatureSet); - - if (aoPassShaderProgram) { - m_DefaultAoPassShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), SDefaultAoPassShader)(*aoPassShaderProgram, - GetContext())); - } else { - m_DefaultAoPassShader = NVScopedRefCounted(); - } - } - return m_DefaultAoPassShader->mPtr; - } - - SDefaultAoPassShader *Qt3DSRendererImpl::GetFakeDepthShader(TShaderFeatureSet inFeatureSet) - { - if (m_FakeDepthShader.hasValue() == false) { - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = - m_qt3dsContext.GetStringTable().RegisterStr("depth display shader"); - NVRenderShaderProgram *depthShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!depthShaderProgram) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &theVertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &theFragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - theVertexGenerator.AddIncoming("attr_pos", "vec3"); - theVertexGenerator.AddIncoming("attr_uv", "vec2"); - theVertexGenerator.AddOutgoing("uv_coords", "vec2"); - theVertexGenerator.Append("void main() {"); - theVertexGenerator.Append("\tgl_Position = vec4(attr_pos.xy, 0.5, 1.0 );"); - theVertexGenerator.Append("\tuv_coords = attr_uv;"); - theVertexGenerator.Append("}"); - - theFragmentGenerator.AddUniform("depth_sampler", "sampler2D"); - theFragmentGenerator.Append("void main() {"); - theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );"); - theFragmentGenerator.Append( - "\tfloat depSample = texelFetch(depth_sampler, iCoords, 0).x;"); - theFragmentGenerator.Append( - "\tgl_FragColor = vec4( depSample, depSample, depSample, 1.0 );"); - theFragmentGenerator.Append("\treturn;"); - theFragmentGenerator.Append("}"); - } - - depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( - "depth display shader", SShaderCacheProgramFlags(), inFeatureSet); - - if (depthShaderProgram) { - m_FakeDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), SDefaultAoPassShader)( - *depthShaderProgram, GetContext())); - } else { - m_FakeDepthShader = NVScopedRefCounted(); - } - } - return m_FakeDepthShader->mPtr; - } - - SDefaultAoPassShader *Qt3DSRendererImpl::GetFakeCubeDepthShader(TShaderFeatureSet inFeatureSet) - { - if (!m_FakeCubemapDepthShader.hasValue()) { - IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); - CRegisteredString theCacheKey = - m_qt3dsContext.GetStringTable().RegisterStr("cube depth display shader"); - NVRenderShaderProgram *cubeShaderProgram = - theCache.GetProgram(theCacheKey, TShaderFeatureSet()); - if (!cubeShaderProgram) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &theVertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &theFragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - theVertexGenerator.AddIncoming("attr_pos", "vec3"); - theVertexGenerator.AddIncoming("attr_uv", "vec2"); - theVertexGenerator.AddOutgoing("sample_dir", "vec3"); - theVertexGenerator.Append("void main() {"); - theVertexGenerator.Append("\tgl_Position = vec4(attr_pos.xy, 0.5, 1.0 );"); - theVertexGenerator.Append( - "\tsample_dir = vec3(4.0 * (attr_uv.x - 0.5), -1.0, 4.0 * (attr_uv.y - 0.5));"); - theVertexGenerator.Append("}"); - theFragmentGenerator.AddUniform("depth_cube", "samplerCube"); - theFragmentGenerator.Append("void main() {"); - theFragmentGenerator.Append( - "\tfloat smpDepth = texture( depth_cube, sample_dir ).x;"); - theFragmentGenerator.Append( - "\tgl_FragColor = vec4(smpDepth, smpDepth, smpDepth, 1.0);"); - theFragmentGenerator.Append("}"); - } - - cubeShaderProgram = GetProgramGenerator().CompileGeneratedShader( - "cube depth display shader", SShaderCacheProgramFlags(), inFeatureSet); - - if (cubeShaderProgram) { - m_FakeCubemapDepthShader = NVScopedRefCounted( - QT3DS_NEW(GetContext().GetAllocator(), SDefaultAoPassShader)(*cubeShaderProgram, - GetContext())); - } else { - m_FakeCubemapDepthShader = NVScopedRefCounted(); - } - } - return m_FakeCubemapDepthShader.getValue(); - } - - STextRenderHelper Qt3DSRendererImpl::GetTextShader(bool inUsePathRendering) - { - STextShaderPtr &thePtr = (!inUsePathRendering) ? m_TextShader : m_TextPathShader; - if (thePtr.HasGeneratedShader()) - return STextRenderHelper(thePtr, *m_QuadInputAssembler); - - NVRenderShaderProgram *theShader = NULL; - NVRenderProgramPipeline *thePipeline = NULL; - - if (!inUsePathRendering) { - GetProgramGenerator().BeginProgram(); - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - // xy of text dimensions are scaling factors, zw are offset factors. - vertexGenerator.AddUniform("text_dimensions", "vec4"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator - << "\tvec3 textPos = vec3(attr_pos.x * text_dimensions.x + text_dimensions.z" - << ", attr_pos.y * text_dimensions.y + text_dimensions.w" - << ", attr_pos.z);" << Endl; - - vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(textPos, 1.0);"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - - fragmentGenerator.AddUniform("text_textcolor", "vec4"); - fragmentGenerator.AddUniform("text_textdimensions", "vec3"); - fragmentGenerator.AddUniform("text_image", "sampler2D"); - fragmentGenerator.AddUniform("text_backgroundcolor", "vec3"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec2 theCoords = uv_coords;"); - // Enable rendering from a sub-rect - - fragmentGenerator - << "\ttheCoords.x = theCoords.x * text_textdimensions.x;" << Endl - << "\ttheCoords.y = theCoords.y * text_textdimensions.y;" << Endl - // flip the y uv coord if the dimension's z variable is set - << "\tif ( text_textdimensions.z > 0.0 ) theCoords.y = 1.0 - theCoords.y;" << Endl; - fragmentGenerator.Append( - "\tvec4 c = texture2D(text_image, theCoords);"); - fragmentGenerator.Append( - "\tfragOutput = vec4(mix(text_backgroundcolor.rgb, " - "text_textcolor.rgb, c.rgb), c.a) * text_textcolor.a;"); - - vertexGenerator.Append("}"); - fragmentGenerator.Append("}"); - const char *shaderName = "text shader"; - theShader = GetProgramGenerator().CompileGeneratedShader( - shaderName, SShaderCacheProgramFlags(), TShaderFeatureSet(), false); - } else { - GetProgramGenerator().BeginProgram( - TShaderGeneratorStageFlags(ShaderGeneratorStages::Fragment)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - fragmentGenerator.AddUniform("text_textcolor", "vec4"); - fragmentGenerator.AddUniform("text_backgroundcolor", "vec3"); - - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tfragOutput = vec4(mix(text_backgroundcolor.rgb, " - "text_textcolor.rgb, text_textcolor.a), text_textcolor.a );"); - fragmentGenerator.Append("}"); - - const char *shaderName = "text path shader"; - theShader = GetProgramGenerator().CompileGeneratedShader( - shaderName, SShaderCacheProgramFlags(), TShaderFeatureSet(), true); - - // setup program pipeline - if (theShader) { - thePipeline = GetContext().CreateProgramPipeline(); - if (thePipeline) { - thePipeline->SetProgramStages( - theShader, - qt3ds::render::NVRenderShaderTypeFlags(NVRenderShaderTypeValue::Fragment)); - } - } - } - - if (theShader == NULL) { - thePtr.Set(NULL); - } else { - GenerateXYQuad(); - thePtr.Set(QT3DS_NEW(m_Context->GetAllocator(), STextShader)(*theShader, thePipeline)); - } - return STextRenderHelper(thePtr, *m_QuadInputAssembler); - } - - STextDepthShader *Qt3DSRendererImpl::GetTextDepthShader() - { - if (m_TextDepthPrepassShader.hasValue() == false) { - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - // xy of text dimensions are scaling factors, zw are offset factors. - vertexGenerator.AddUniform("text_dimensions", "vec4"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator - << "\tvec3 textPos = vec3(attr_pos.x * text_dimensions.x + text_dimensions.z" - << ", attr_pos.y * text_dimensions.y + text_dimensions.w" - << ", attr_pos.z);" << Endl; - - vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(textPos, 1.0);"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - - fragmentGenerator.AddUniform("text_textdimensions", "vec3"); - fragmentGenerator.AddUniform("text_image", "sampler2D"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec2 theCoords = uv_coords;"); - // Enable rendering from a sub-rect - - fragmentGenerator - << "\ttheCoords.x = theCoords.x * text_textdimensions.x;" << Endl - << "\ttheCoords.y = theCoords.y * text_textdimensions.y;" << Endl - // flip the y uv coord if the dimension's z variable is set - << "\tif ( text_textdimensions.z > 0.0 ) theCoords.y = 1.0 - theCoords.y;" << Endl; - fragmentGenerator.Append("\tfloat alpha_mask = texture2D( text_image, theCoords ).r;"); - fragmentGenerator.Append("\tif ( alpha_mask < .05 ) discard;"); - vertexGenerator.Append("}"); - fragmentGenerator.Append("}"); - const char *shaderName = "text depth shader"; - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - shaderName, SShaderCacheProgramFlags(), TShaderFeatureSet()); - if (theShader == NULL) { - m_TextDepthPrepassShader = NVScopedRefCounted(); - } else { - GenerateXYQuad(); - m_TextDepthPrepassShader = NVScopedRefCounted( - QT3DS_NEW(m_Context->GetAllocator(), STextDepthShader)( - m_Context->GetAllocator(), *theShader, *m_QuadInputAssembler)); - } - } - return m_TextDepthPrepassShader->mPtr; - } - - STextRenderHelper Qt3DSRendererImpl::GetTextWidgetShader() - { - if (m_TextWidgetShader.HasGeneratedShader()) - return STextRenderHelper(m_TextWidgetShader, *m_QuadInputAssembler); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - // xy of text dimensions are scaling factors, zw are offset factors. - vertexGenerator.AddUniform("text_dimensions", "vec4"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator - << "\tvec3 textPos = vec3(attr_pos.x * text_dimensions.x + text_dimensions.z" - << ", attr_pos.y * text_dimensions.y + text_dimensions.w" - << ", attr_pos.z);" << Endl; - - vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(textPos, 1.0);"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("text_textcolor", "vec4"); - fragmentGenerator.AddUniform("text_textdimensions", "vec3"); - fragmentGenerator.AddUniform("text_image", "sampler2D"); - fragmentGenerator.AddUniform("text_backgroundcolor", "vec3"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec2 theCoords = uv_coords;"); - // Enable rendering from a sub-rect - - fragmentGenerator << "\ttheCoords.x = theCoords.x * text_textdimensions.x;" << Endl - << "\ttheCoords.y = theCoords.y * text_textdimensions.y;" << Endl - // flip the y uv coord if the dimension's z variable is set - << "\tif ( text_textdimensions.z > 0.0 ) theCoords.y = 1.0 - theCoords.y;" - << Endl; - fragmentGenerator.Append( - "\tfloat alpha_mask = texture2D( text_image, theCoords ).r * text_textcolor.a;"); - fragmentGenerator.Append("\tfragOutput = vec4(mix(text_backgroundcolor.rgb, " - "text_textcolor.rgb, alpha_mask), 1.0 );"); - fragmentGenerator.Append("}"); - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "text widget shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (theShader == NULL) - m_TextWidgetShader.Set(NULL); - else { - GenerateXYQuad(); - m_TextWidgetShader.Set(QT3DS_NEW(m_Context->GetAllocator(), STextShader)(*theShader)); - } - return STextRenderHelper(m_TextWidgetShader, *m_QuadInputAssembler); - } - - STextRenderHelper Qt3DSRendererImpl::GetOnscreenTextShader() - { - if (m_TextOnscreenShader.HasGeneratedShader()) - return STextRenderHelper(m_TextOnscreenShader, *m_QuadStripInputAssembler); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddUniform("vertex_offsets", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - - vertexGenerator.Append("\tvec3 pos = attr_pos + vec3(vertex_offsets, 0.0);"); - vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(pos, 1.0);"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("text_textcolor", "vec4"); - fragmentGenerator.AddUniform("text_image", "sampler2D"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tfloat alpha = texture2D( text_image, uv_coords ).a;"); - fragmentGenerator.Append( - "\tfragOutput = vec4(text_textcolor.r, text_textcolor.g, text_textcolor.b, alpha);"); - fragmentGenerator.Append("}"); - - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "onscreen texture shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - - if (theShader == NULL) - m_TextOnscreenShader.Set(NULL); - else { - GenerateXYQuadStrip(); - m_TextOnscreenShader.Set(QT3DS_NEW(m_Context->GetAllocator(), STextShader)(*theShader)); - } - return STextRenderHelper(m_TextOnscreenShader, *m_QuadStripInputAssembler); - } - - NVRenderShaderProgram *Qt3DSRendererImpl::GetTextAtlasEntryShader() - { - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - - vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("text_image", "sampler2D"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tfloat alpha = texture2D( text_image, uv_coords ).a;"); - fragmentGenerator.Append("\tfragOutput = vec4(alpha, alpha, alpha, alpha);"); - fragmentGenerator.Append("}"); - - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "texture atlas entry shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - - return theShader; - } - - STextRenderHelper Qt3DSRendererImpl::GetShader(STextRenderable & /*inRenderable*/, - bool inUsePathRendering) - { - return GetTextShader(inUsePathRendering); - } - - SLayerSceneShader *Qt3DSRendererImpl::GetSceneLayerShader() - { - if (m_SceneLayerShader.hasValue()) - return m_SceneLayerShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - // xy of text dimensions are scaling factors, zw are offset factors. - vertexGenerator.AddUniform("layer_dimensions", "vec2"); - vertexGenerator.AddUniform("model_view_projection", "mat4"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator << "\tvec3 layerPos = vec3(attr_pos.x * layer_dimensions.x / 2.0" - << ", attr_pos.y * layer_dimensions.y / 2.0" - << ", attr_pos.z);" << Endl; - - vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(layerPos, 1.0);"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("layer_image", "sampler2D"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec2 theCoords = uv_coords;\n"); - fragmentGenerator.Append("\tvec4 theLayerTexture = texture2D( layer_image, theCoords );\n"); - fragmentGenerator.Append("\tif( theLayerTexture.a == 0.0 ) discard;\n"); - fragmentGenerator.Append("\tfragOutput = theLayerTexture;\n"); - fragmentGenerator.Append("}"); - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "layer shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SLayerSceneShader)(*theShader); - m_SceneLayerShader = retval; - return m_SceneLayerShader.getValue(); - } - - SLayerProgAABlendShader *Qt3DSRendererImpl::GetLayerProgAABlendShader() - { - if (m_LayerProgAAShader.hasValue()) - return m_LayerProgAAShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - fragmentGenerator.AddUniform("accumulator", "sampler2D"); - fragmentGenerator.AddUniform("last_frame", "sampler2D"); - fragmentGenerator.AddUniform("blend_factors", "vec2"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec4 accum = texture2D( accumulator, uv_coords );"); - fragmentGenerator.Append("\tvec4 lastFrame = texture2D( last_frame, uv_coords );"); - fragmentGenerator.Append( - "\tgl_FragColor = accum*blend_factors.y + lastFrame*blend_factors.x;"); - fragmentGenerator.Append("}"); - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "layer progressiveAA blend shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SLayerProgAABlendShader)(*theShader); - m_LayerProgAAShader = retval; - return m_LayerProgAAShader.getValue(); - } - - SShadowmapPreblurShader *Qt3DSRendererImpl::GetCubeShadowBlurXShader() - { - if (m_CubeShadowBlurXShader.hasValue()) - return m_CubeShadowBlurXShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - // vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords.xy = attr_pos.xy;"); - vertexGenerator.Append("}"); - - // This with the ShadowBlurYShader design for a 2-pass 5x5 (sigma=1.0) - // Weights computed using -- http://dev.theomader.com/gaussian-kernel-calculator/ - fragmentGenerator.AddUniform("camera_properties", "vec2"); - fragmentGenerator.AddUniform("depthCube", "samplerCube"); - // fragmentGenerator.AddUniform("depthSrc", "sampler2D"); - fragmentGenerator.Append("layout(location = 0) out vec4 frag0;"); - fragmentGenerator.Append("layout(location = 1) out vec4 frag1;"); - fragmentGenerator.Append("layout(location = 2) out vec4 frag2;"); - fragmentGenerator.Append("layout(location = 3) out vec4 frag3;"); - fragmentGenerator.Append("layout(location = 4) out vec4 frag4;"); - fragmentGenerator.Append("layout(location = 5) out vec4 frag5;"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tfloat ofsScale = camera_properties.x / 2500.0;"); - fragmentGenerator.Append("\tvec3 dir0 = vec3(1.0, -uv_coords.y, -uv_coords.x);"); - fragmentGenerator.Append("\tvec3 dir1 = vec3(-1.0, -uv_coords.y, uv_coords.x);"); - fragmentGenerator.Append("\tvec3 dir2 = vec3(uv_coords.x, 1.0, uv_coords.y);"); - fragmentGenerator.Append("\tvec3 dir3 = vec3(uv_coords.x, -1.0, -uv_coords.y);"); - fragmentGenerator.Append("\tvec3 dir4 = vec3(uv_coords.x, -uv_coords.y, 1.0);"); - fragmentGenerator.Append("\tvec3 dir5 = vec3(-uv_coords.x, -uv_coords.y, -1.0);"); - fragmentGenerator.Append("\tfloat depth0;"); - fragmentGenerator.Append("\tfloat depth1;"); - fragmentGenerator.Append("\tfloat depth2;"); - fragmentGenerator.Append("\tfloat outDepth;"); - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir0).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir0 + vec3(0.0, 0.0, -ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir0 + vec3(0.0, 0.0, ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir0 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir0 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag0 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir1).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir1 + vec3(0.0, 0.0, -ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir1 + vec3(0.0, 0.0, ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir1 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir1 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag1 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir2).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir2 + vec3(-ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir2 + vec3(ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir2 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir2 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag2 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir3).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir3 + vec3(-ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir3 + vec3(ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir3 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir3 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag3 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir4).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir4 + vec3(-ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir4 + vec3(ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir4 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir4 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag4 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir5).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir5 + vec3(-ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir5 + vec3(ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir5 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir5 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag5 = vec4(outDepth);"); - - fragmentGenerator.Append("}"); - - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "cubemap shadow blur X shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); - m_CubeShadowBlurXShader = retval; - return m_CubeShadowBlurXShader.getValue(); - } - - SShadowmapPreblurShader *Qt3DSRendererImpl::GetCubeShadowBlurYShader() - { - if (m_CubeShadowBlurYShader.hasValue()) - return m_CubeShadowBlurYShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - // vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords.xy = attr_pos.xy;"); - vertexGenerator.Append("}"); - - // This with the ShadowBlurXShader design for a 2-pass 5x5 (sigma=1.0) - // Weights computed using -- http://dev.theomader.com/gaussian-kernel-calculator/ - fragmentGenerator.AddUniform("camera_properties", "vec2"); - fragmentGenerator.AddUniform("depthCube", "samplerCube"); - // fragmentGenerator.AddUniform("depthSrc", "sampler2D"); - fragmentGenerator.Append("layout(location = 0) out vec4 frag0;"); - fragmentGenerator.Append("layout(location = 1) out vec4 frag1;"); - fragmentGenerator.Append("layout(location = 2) out vec4 frag2;"); - fragmentGenerator.Append("layout(location = 3) out vec4 frag3;"); - fragmentGenerator.Append("layout(location = 4) out vec4 frag4;"); - fragmentGenerator.Append("layout(location = 5) out vec4 frag5;"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tfloat ofsScale = camera_properties.x / 2500.0;"); - fragmentGenerator.Append("\tvec3 dir0 = vec3(1.0, -uv_coords.y, -uv_coords.x);"); - fragmentGenerator.Append("\tvec3 dir1 = vec3(-1.0, -uv_coords.y, uv_coords.x);"); - fragmentGenerator.Append("\tvec3 dir2 = vec3(uv_coords.x, 1.0, uv_coords.y);"); - fragmentGenerator.Append("\tvec3 dir3 = vec3(uv_coords.x, -1.0, -uv_coords.y);"); - fragmentGenerator.Append("\tvec3 dir4 = vec3(uv_coords.x, -uv_coords.y, 1.0);"); - fragmentGenerator.Append("\tvec3 dir5 = vec3(-uv_coords.x, -uv_coords.y, -1.0);"); - fragmentGenerator.Append("\tfloat depth0;"); - fragmentGenerator.Append("\tfloat depth1;"); - fragmentGenerator.Append("\tfloat depth2;"); - fragmentGenerator.Append("\tfloat outDepth;"); - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir0).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir0 + vec3(0.0, -ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir0 + vec3(0.0, ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir0 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir0 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag0 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir1).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir1 + vec3(0.0, -ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir1 + vec3(0.0, ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir1 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir1 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag1 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir2).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir2 + vec3(0.0, 0.0, -ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir2 + vec3(0.0, 0.0, ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir2 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir2 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag2 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir3).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir3 + vec3(0.0, 0.0, -ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir3 + vec3(0.0, 0.0, ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir3 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir3 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag3 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir4).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir4 + vec3(0.0, -ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir4 + vec3(0.0, ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir4 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir4 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag4 = vec4(outDepth);"); - - fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir5).x;"); - fragmentGenerator.Append( - "\tdepth1 = texture(depthCube, dir5 + vec3(0.0, -ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth1 += texture(depthCube, dir5 + vec3(0.0, ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 = texture(depthCube, dir5 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\tdepth2 += texture(depthCube, dir5 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); - fragmentGenerator.Append( - "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfrag5 = vec4(outDepth);"); - - fragmentGenerator.Append("}"); - - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "cubemap shadow blur Y shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); - m_CubeShadowBlurYShader = retval; - return m_CubeShadowBlurYShader.getValue(); - } - - SShadowmapPreblurShader *Qt3DSRendererImpl::GetOrthoShadowBlurXShader() - { - if (m_OrthoShadowBlurXShader.hasValue()) - return m_OrthoShadowBlurXShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords.xy = attr_uv.xy;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("camera_properties", "vec2"); - fragmentGenerator.AddUniform("depthSrc", "sampler2D"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec2 ofsScale = vec2( camera_properties.x / 7680.0, 0.0 );"); - fragmentGenerator.Append("\tfloat depth0 = texture(depthSrc, uv_coords).x;"); - fragmentGenerator.Append("\tfloat depth1 = texture(depthSrc, uv_coords + ofsScale).x;"); - fragmentGenerator.Append("\tdepth1 += texture(depthSrc, uv_coords - ofsScale).x;"); - fragmentGenerator.Append( - "\tfloat depth2 = texture(depthSrc, uv_coords + 2.0 * ofsScale).x;"); - fragmentGenerator.Append("\tdepth2 += texture(depthSrc, uv_coords - 2.0 * ofsScale).x;"); - fragmentGenerator.Append( - "\tfloat outDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfragOutput = vec4(outDepth);"); - fragmentGenerator.Append("}"); - - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "shadow map blur X shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); - m_OrthoShadowBlurXShader = retval; - return m_OrthoShadowBlurXShader.getValue(); - } - - SShadowmapPreblurShader *Qt3DSRendererImpl::GetOrthoShadowBlurYShader() - { - if (m_OrthoShadowBlurYShader.hasValue()) - return m_OrthoShadowBlurYShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords.xy = attr_uv.xy;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("camera_properties", "vec2"); - fragmentGenerator.AddUniform("depthSrc", "sampler2D"); - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec2 ofsScale = vec2( 0.0, camera_properties.x / 7680.0 );"); - fragmentGenerator.Append("\tfloat depth0 = texture(depthSrc, uv_coords).x;"); - fragmentGenerator.Append("\tfloat depth1 = texture(depthSrc, uv_coords + ofsScale).x;"); - fragmentGenerator.Append("\tdepth1 += texture(depthSrc, uv_coords - ofsScale).x;"); - fragmentGenerator.Append( - "\tfloat depth2 = texture(depthSrc, uv_coords + 2.0 * ofsScale).x;"); - fragmentGenerator.Append("\tdepth2 += texture(depthSrc, uv_coords - 2.0 * ofsScale).x;"); - fragmentGenerator.Append( - "\tfloat outDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); - fragmentGenerator.Append("\tfragOutput = vec4(outDepth);"); - fragmentGenerator.Append("}"); - - NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( - "shadow map blur Y shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); - m_OrthoShadowBlurYShader = retval; - return m_OrthoShadowBlurYShader.getValue(); - } - -#ifdef ADVANCED_BLEND_SW_FALLBACK - SAdvancedModeBlendShader * - Qt3DSRendererImpl::GetAdvancedBlendModeShader(AdvancedBlendModes::Enum blendMode) - { - // Select between blend equations. - if (blendMode == AdvancedBlendModes::Overlay) { - return GetOverlayBlendModeShader(); - } else if (blendMode == AdvancedBlendModes::ColorBurn) { - return GetColorBurnBlendModeShader(); - } else if (blendMode == AdvancedBlendModes::ColorDodge) { - return GetColorDodgeBlendModeShader(); - } - return {}; - } - - SAdvancedModeBlendShader *Qt3DSRendererImpl::GetOverlayBlendModeShader() - { - if (m_AdvancedModeOverlayBlendShader.hasValue()) - return m_AdvancedModeOverlayBlendShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("base_layer", "sampler2D"); - fragmentGenerator.AddUniform("blend_layer", "sampler2D"); - - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec4 base = texture2D(base_layer, uv_coords);"); - fragmentGenerator.Append("\tif (base.a != 0.0) base.rgb /= base.a;"); - fragmentGenerator.Append("\telse base = vec4(0.0);"); - fragmentGenerator.Append("\tvec4 blend = texture2D(blend_layer, uv_coords);"); - fragmentGenerator.Append("\tif (blend.a != 0.0) blend.rgb /= blend.a;"); - fragmentGenerator.Append("\telse blend = vec4(0.0);"); - - fragmentGenerator.Append("\tvec4 res = vec4(0.0);"); - fragmentGenerator.Append("\tfloat p0 = base.a * blend.a;"); - fragmentGenerator.Append("\tfloat p1 = base.a * (1.0 - blend.a);"); - fragmentGenerator.Append("\tfloat p2 = blend.a * (1.0 - base.a);"); - fragmentGenerator.Append("\tres.a = p0 + p1 + p2;"); - - NVRenderShaderProgram *theShader; - fragmentGenerator.Append( - "\tfloat f_rs_rd = (base.r < 0.5? (2.0 * base.r * blend.r) : " - "(1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r)));"); - fragmentGenerator.Append( - "\tfloat f_gs_gd = (base.g < 0.5? (2.0 * base.g * blend.g) : " - "(1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g)));"); - fragmentGenerator.Append( - "\tfloat f_bs_bd = (base.b < 0.5? (2.0 * base.b * blend.b) : " - "(1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b)));"); - fragmentGenerator.Append("\tres.r = f_rs_rd * p0 + base.r * p1 + blend.r * p2;"); - fragmentGenerator.Append("\tres.g = f_gs_gd * p0 + base.g * p1 + blend.g * p2;"); - fragmentGenerator.Append("\tres.b = f_bs_bd * p0 + base.b * p1 + blend.b * p2;"); - fragmentGenerator.Append("\tgl_FragColor = vec4(res.rgb * res.a, res.a);"); - fragmentGenerator.Append("}"); - theShader = GetProgramGenerator().CompileGeneratedShader( - "advanced overlay shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SAdvancedModeBlendShader)(*theShader); - m_AdvancedModeOverlayBlendShader = retval; - return m_AdvancedModeOverlayBlendShader.getValue(); - } - - SAdvancedModeBlendShader *Qt3DSRendererImpl::GetColorBurnBlendModeShader() - { - if (m_AdvancedModeColorBurnBlendShader.hasValue()) - return m_AdvancedModeColorBurnBlendShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("base_layer", "sampler2D"); - fragmentGenerator.AddUniform("blend_layer", "sampler2D"); - - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec4 base = texture2D(base_layer, uv_coords);"); - fragmentGenerator.Append("\tif (base.a != 0.0) base.rgb /= base.a;"); - fragmentGenerator.Append("\telse base = vec4(0.0);"); - fragmentGenerator.Append("\tvec4 blend = texture2D(blend_layer, uv_coords);"); - fragmentGenerator.Append("\tif (blend.a != 0.0) blend.rgb /= blend.a;"); - fragmentGenerator.Append("\telse blend = vec4(0.0);"); - - fragmentGenerator.Append("\tvec4 res = vec4(0.0);"); - fragmentGenerator.Append("\tfloat p0 = base.a * blend.a;"); - fragmentGenerator.Append("\tfloat p1 = base.a * (1.0 - blend.a);"); - fragmentGenerator.Append("\tfloat p2 = blend.a * (1.0 - base.a);"); - fragmentGenerator.Append("\tres.a = p0 + p1 + p2;"); - - NVRenderShaderProgram *theShader; - fragmentGenerator.Append( - "\tfloat f_rs_rd = ((base.r == 1.0) ? 1.0 : " - "(blend.r == 0.0) ? 0.0 : 1.0 - min(1.0, ((1.0 - base.r) / blend.r)));"); - fragmentGenerator.Append( - "\tfloat f_gs_gd = ((base.g == 1.0) ? 1.0 : " - "(blend.g == 0.0) ? 0.0 : 1.0 - min(1.0, ((1.0 - base.g) / blend.g)));"); - fragmentGenerator.Append( - "\tfloat f_bs_bd = ((base.b == 1.0) ? 1.0 : " - "(blend.b == 0.0) ? 0.0 : 1.0 - min(1.0, ((1.0 - base.b) / blend.b)));"); - fragmentGenerator.Append("\tres.r = f_rs_rd * p0 + base.r * p1 + blend.r * p2;"); - fragmentGenerator.Append("\tres.g = f_gs_gd * p0 + base.g * p1 + blend.g * p2;"); - fragmentGenerator.Append("\tres.b = f_bs_bd * p0 + base.b * p1 + blend.b * p2;"); - fragmentGenerator.Append("\tgl_FragColor = vec4(res.rgb * res.a, res.a);"); - fragmentGenerator.Append("}"); - - theShader = GetProgramGenerator().CompileGeneratedShader( - "advanced colorBurn shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SAdvancedModeBlendShader)(*theShader); - m_AdvancedModeColorBurnBlendShader = retval; - return m_AdvancedModeColorBurnBlendShader.getValue(); - - } - - SAdvancedModeBlendShader *Qt3DSRendererImpl::GetColorDodgeBlendModeShader() - { - if (m_AdvancedModeColorDodgeBlendShader.hasValue()) - return m_AdvancedModeColorDodgeBlendShader.getValue(); - - GetProgramGenerator().BeginProgram(); - - IShaderStageGenerator &vertexGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); - IShaderStageGenerator &fragmentGenerator( - *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); - vertexGenerator.AddIncoming("attr_pos", "vec3"); - vertexGenerator.AddIncoming("attr_uv", "vec2"); - vertexGenerator.AddOutgoing("uv_coords", "vec2"); - vertexGenerator.Append("void main() {"); - vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); - vertexGenerator.Append("\tuv_coords = attr_uv;"); - vertexGenerator.Append("}"); - - fragmentGenerator.AddUniform("base_layer", "sampler2D"); - fragmentGenerator.AddUniform("blend_layer", "sampler2D"); - - fragmentGenerator.Append("void main() {"); - fragmentGenerator.Append("\tvec4 base = texture2D(base_layer, uv_coords);"); - fragmentGenerator.Append("\tif (base.a != 0.0) base.rgb /= base.a;"); - fragmentGenerator.Append("\telse base = vec4(0.0);"); - fragmentGenerator.Append("\tvec4 blend = texture2D(blend_layer, uv_coords);"); - fragmentGenerator.Append("\tif (blend.a != 0.0) blend.rgb /= blend.a;"); - fragmentGenerator.Append("\telse blend = vec4(0.0);"); - - fragmentGenerator.Append("\tvec4 res = vec4(0.0);"); - fragmentGenerator.Append("\tfloat p0 = base.a * blend.a;"); - fragmentGenerator.Append("\tfloat p1 = base.a * (1.0 - blend.a);"); - fragmentGenerator.Append("\tfloat p2 = blend.a * (1.0 - base.a);"); - fragmentGenerator.Append("\tres.a = p0 + p1 + p2;"); - - NVRenderShaderProgram *theShader; - fragmentGenerator.Append( - "\tfloat f_rs_rd = ((base.r == 0.0) ? 0.0 : " - "(blend.r == 1.0) ? 1.0 : min(base.r / (1.0 - blend.r), 1.0));"); - fragmentGenerator.Append( - "\tfloat f_gs_gd = ((base.g == 0.0) ? 0.0 : " - "(blend.g == 1.0) ? 1.0 : min(base.g / (1.0 - blend.g), 1.0));"); - fragmentGenerator.Append( - "\tfloat f_bs_bd = ((base.b == 0.0) ? 0.0 : " - "(blend.b == 1.0) ? 1.0 : min(base.b / (1.0 - blend.b), 1.0));"); - fragmentGenerator.Append("\tres.r = f_rs_rd * p0 + base.r * p1 + blend.r * p2;"); - fragmentGenerator.Append("\tres.g = f_gs_gd * p0 + base.g * p1 + blend.g * p2;"); - fragmentGenerator.Append("\tres.b = f_bs_bd * p0 + base.b * p1 + blend.b * p2;"); - - fragmentGenerator.Append("\tgl_FragColor = vec4(res.rgb * res.a, res.a);"); - fragmentGenerator.Append("}"); - theShader = GetProgramGenerator().CompileGeneratedShader( - "advanced colorDodge shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); - NVScopedRefCounted retval; - if (theShader) - retval = QT3DS_NEW(m_Context->GetAllocator(), SAdvancedModeBlendShader)(*theShader); - m_AdvancedModeColorDodgeBlendShader = retval; - return m_AdvancedModeColorDodgeBlendShader.getValue(); - - } -#endif -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.h deleted file mode 100644 index 1ac85dbf..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplShaders.h +++ /dev/null @@ -1,452 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDERER_IMPL_SHADERS_H -#define QT3DS_RENDERER_IMPL_SHADERS_H -#include "Qt3DSRender.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "render/Qt3DSRenderProgramPipeline.h" - -namespace qt3ds { -namespace render { - using qt3ds::render::NVRenderCachedShaderProperty; - using qt3ds::render::NVRenderCachedShaderBuffer; - - /** - * Cached tessellation property lookups this is on a per mesh base - */ - struct SShaderTessellationProperties - { - NVRenderCachedShaderProperty m_EdgeTessLevel; ///< tesselation value for the edges - NVRenderCachedShaderProperty m_InsideTessLevel; ///< tesselation value for the inside - NVRenderCachedShaderProperty - m_PhongBlend; ///< blending between linear and phong component - NVRenderCachedShaderProperty - m_DistanceRange; ///< distance range for min and max tess level - NVRenderCachedShaderProperty m_DisableCulling; ///< if set to 1.0 this disables - ///backface culling optimization in - ///the tess shader - - SShaderTessellationProperties() {} - SShaderTessellationProperties(NVRenderShaderProgram &inShader) - : m_EdgeTessLevel("tessLevelOuter", inShader) - , m_InsideTessLevel("tessLevelInner", inShader) - , m_PhongBlend("phongBlend", inShader) - , m_DistanceRange("distanceRange", inShader) - , m_DisableCulling("disableCulling", inShader) - { - } - }; - - /** - * The results of generating a shader. Caches all possible variable names into - * typesafe objects. - */ - struct SShaderGeneratorGeneratedShader - { - QT3DSU32 m_LayerSetIndex; - CRegisteredString m_QueryString; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_ViewportMatrix; - SShaderTessellationProperties m_Tessellation; - - SShaderGeneratorGeneratedShader(CRegisteredString inQueryString, - NVRenderShaderProgram &inShader) - : m_LayerSetIndex(QT3DS_MAX_U32) - , m_QueryString(inQueryString) - , m_Shader(inShader) - , m_ViewportMatrix("viewport_matrix", inShader) - , m_Tessellation(inShader) - { - m_Shader.addRef(); - } - ~SShaderGeneratorGeneratedShader() { m_Shader.release(); } - static QT3DSU32 GetLayerIndex(const SShaderGeneratorGeneratedShader &inShader) - { - return inShader.m_LayerSetIndex; - } - static void SetLayerIndex(SShaderGeneratorGeneratedShader &inShader, QT3DSU32 idx) - { - inShader.m_LayerSetIndex = idx; - } - }; - - struct SDefaultMaterialRenderableDepthShader - { - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_MVP; - - QT3DSI32 m_RefCount; - SDefaultMaterialRenderableDepthShader(NVRenderShaderProgram &inShader, - NVRenderContext &inContext) - : m_Allocator(inContext.GetAllocator()) - , m_Shader(inShader) - , m_MVP("model_view_projection", inShader) - , m_RefCount(0) - { - m_Shader.addRef(); - } - - ~SDefaultMaterialRenderableDepthShader() { m_Shader.release(); } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - NVDelete(m_Allocator, this); - } - }; - - /** - * Cached texture property lookups, used one per texture so a shader generator for N - * textures will have an array of N of these lookup objects. - */ - struct SShaderTextureProperties - { - NVRenderCachedShaderProperty m_Sampler; - NVRenderCachedShaderProperty m_Offsets; - NVRenderCachedShaderProperty m_Rotations; - SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, - NVRenderShaderProgram &inShader) - : m_Sampler(sampName, inShader) - , m_Offsets(offName, inShader) - , m_Rotations(rotName, inShader) - { - } - SShaderTextureProperties() {} - }; - - struct SRenderableDepthPrepassShader - { - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_MVP; - NVRenderCachedShaderProperty m_GlobalTransform; - NVRenderCachedShaderProperty m_Projection; - NVRenderCachedShaderProperty m_CameraPosition; - NVRenderCachedShaderProperty m_DisplaceAmount; - SShaderTextureProperties m_DisplacementProps; - NVRenderCachedShaderProperty m_CameraProperties; - NVRenderCachedShaderProperty m_CameraDirection; - // NVRenderCachedShaderProperty m_ShadowMV[6]; - - QT3DSI32 m_RefCount; - // Cache the tessellation property name lookups - SShaderTessellationProperties m_Tessellation; - - SRenderableDepthPrepassShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) - : m_Allocator(inContext.GetAllocator()) - , m_Shader(inShader) - , m_MVP("model_view_projection", inShader) - , m_GlobalTransform("model_matrix", inShader) - , m_Projection("projection", inShader) - , m_CameraPosition("camera_position", inShader) - , m_DisplaceAmount("displaceAmount", inShader) - , m_DisplacementProps("displacementSampler", "displacementMap_offset", - "displacementMap_rot", inShader) - , m_CameraProperties("camera_properties", inShader) - , m_CameraDirection("camera_direction", inShader) - , m_RefCount(0) - , m_Tessellation(inShader) - { - /* - m_ShadowMV[0].m_Shader = &inShader; - m_ShadowMV[0].m_Constant = inShader.GetShaderConstant( "shadow_mv0" ); - m_ShadowMV[1].m_Shader = &inShader; - m_ShadowMV[1].m_Constant = inShader.GetShaderConstant( "shadow_mv1" ); - m_ShadowMV[2].m_Shader = &inShader; - m_ShadowMV[2].m_Constant = inShader.GetShaderConstant( "shadow_mv2" ); - m_ShadowMV[3].m_Shader = &inShader; - m_ShadowMV[3].m_Constant = inShader.GetShaderConstant( "shadow_mv3" ); - m_ShadowMV[4].m_Shader = &inShader; - m_ShadowMV[4].m_Constant = inShader.GetShaderConstant( "shadow_mv4" ); - m_ShadowMV[5].m_Shader = &inShader; - m_ShadowMV[5].m_Constant = inShader.GetShaderConstant( "shadow_mv5" ); - */ - m_Shader.addRef(); - } - - ~SRenderableDepthPrepassShader() { m_Shader.release(); } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - NVDelete(m_Allocator, this); - } - }; - - struct SDefaultAoPassShader - { - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_ViewMatrix; - NVRenderCachedShaderProperty m_CameraProperties; - NVRenderCachedShaderProperty m_CameraDirection; - NVRenderCachedShaderProperty m_DepthTexture; - NVRenderCachedShaderProperty m_CubeTexture; - NVRenderCachedShaderProperty m_DepthSamplerSize; - - NVRenderCachedShaderBuffer m_AoShadowParams; - QT3DSI32 m_RefCount; - - SDefaultAoPassShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) - : m_Allocator(inContext.GetAllocator()) - , m_Shader(inShader) - , m_ViewMatrix("view_matrix", inShader) - , m_CameraProperties("camera_properties", inShader) - , m_CameraDirection("camera_direction", inShader) - , m_DepthTexture("depth_sampler", inShader) - , m_CubeTexture("depth_cube", inShader) - , m_DepthSamplerSize("depth_sampler_size", inShader) - , m_AoShadowParams("cbAoShadow", inShader) - , m_RefCount(0) - { - m_Shader.addRef(); - } - ~SDefaultAoPassShader() { m_Shader.release(); } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - NVDelete(m_Allocator, this); - } - }; - - struct STextShader - { - NVRenderShaderProgram &m_Shader; - - NVScopedRefCounted m_ProgramPipeline; - - NVRenderCachedShaderProperty m_MVP; - // Dimensions and offsetting of the image. - NVRenderCachedShaderProperty m_Dimensions; - // The fourth member of text color is the opacity - NVRenderCachedShaderProperty m_TextColor; - NVRenderCachedShaderProperty m_BackgroundColor; - NVRenderCachedShaderProperty m_Sampler; - // Dimensions and offsetting of the texture - NVRenderCachedShaderProperty m_TextDimensions; - NVRenderCachedShaderProperty m_CameraProperties; - // Used only for onscreen text - NVRenderCachedShaderProperty m_VertexOffsets; - - STextShader(NVRenderShaderProgram &shader, NVRenderProgramPipeline *pipeline = NULL) - : m_Shader(shader) - , m_ProgramPipeline(pipeline) - , m_MVP("model_view_projection", shader) - , m_Dimensions("text_dimensions", shader) - , m_TextColor("text_textcolor", shader) - , m_BackgroundColor("text_backgroundcolor", shader) - , m_Sampler("text_image", shader) - , m_TextDimensions("text_textdimensions", shader) - , m_CameraProperties("camera_properties", shader) - , m_VertexOffsets("vertex_offsets", shader) - { - if (!pipeline) - m_Shader.addRef(); - } - ~STextShader() - { - if (!m_ProgramPipeline.mPtr) - m_Shader.release(); - } - void Render(NVRenderTexture2D &inTexture, const STextScaleAndOffset &inScaleAndOffset, - const QT3DSVec4 &inTextColor, const QT3DSMat44 &inMVP, const QT3DSVec2 &inCameraVec, - NVRenderContext &inRenderContext, - NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, - const STextTextureDetails &inTextTextureDetails, - const QT3DSVec3 &inBackgroundColor); - - void RenderPath(NVRenderPathFontItem &inPathFontItem, - NVRenderPathFontSpecification &inPathFontSpec, - const STextScaleAndOffset &inScaleAndOffset, const QT3DSVec4 &inTextColor, - const QT3DSMat44 &inViewProjection, const QT3DSMat44 &inModel, - const QT3DSVec2 &inCameraVec, NVRenderContext &inRenderContext, - const STextTextureDetails &inTextTextureDetails, - const QT3DSVec3 &inBackgroundColor); - - void Render2D(NVRenderTexture2D &inTexture, const QT3DSVec4 &inTextColor, const QT3DSMat44 &inMVP, - NVRenderContext &inRenderContext, - NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, - QT3DSVec2 inVertexOffsets); - }; - - struct STextDepthShader - { - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_MVP; - // Dimensions and offsetting of the image. - NVRenderCachedShaderProperty m_Dimensions; - NVRenderCachedShaderProperty m_TextDimensions; - NVRenderCachedShaderProperty m_CameraProperties; - NVRenderCachedShaderProperty m_Sampler; - NVRenderInputAssembler &m_QuadInputAssembler; - QT3DSI32 m_RefCount; - - STextDepthShader(NVAllocatorCallback &alloc, NVRenderShaderProgram &prog, - NVRenderInputAssembler &assembler) - : m_Allocator(alloc) - , m_Shader(prog) - , m_MVP("model_view_projection", prog) - , m_Dimensions("text_dimensions", prog) - , m_TextDimensions("text_textdimensions", prog) - , m_CameraProperties("camera_properties", prog) - , m_Sampler("text_image", prog) - , m_QuadInputAssembler(assembler) - , m_RefCount(0) - { - m_Shader.addRef(); - } - ~STextDepthShader() { m_Shader.release(); } - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - NVDelete(m_Allocator, this); - } - }; - - struct SLayerProgAABlendShader - { - NVScopedRefCounted m_Shader; - NVRenderCachedShaderProperty m_AccumSampler; - NVRenderCachedShaderProperty m_LastFrame; - NVRenderCachedShaderProperty m_BlendFactors; - volatile QT3DSI32 mRefCount; - SLayerProgAABlendShader(NVRenderShaderProgram &inShader) - : m_Shader(inShader) - , m_AccumSampler("accumulator", inShader) - , m_LastFrame("last_frame", inShader) - , m_BlendFactors("blend_factors", inShader) - , mRefCount(0) - { - } - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) - }; - - struct SLayerSceneShader - { - NVRenderShaderProgram &m_Shader; - - NVRenderCachedShaderProperty m_MVP; - // Dimensions and offsetting of the image. - NVRenderCachedShaderProperty m_Dimensions; - // The fourth member of text color is the opacity - NVRenderCachedShaderProperty m_Sampler; - - volatile QT3DSI32 mRefCount; - - SLayerSceneShader(NVRenderShaderProgram &inShader) - : m_Shader(inShader) - , m_MVP("model_view_projection", inShader) - , m_Dimensions("layer_dimensions", inShader) - , m_Sampler("layer_image", inShader) - , mRefCount(0) - { - m_Shader.addRef(); - } - ~SLayerSceneShader() { m_Shader.release(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader.GetRenderContext().GetAllocator()) - }; - - struct SShadowmapPreblurShader - { - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_CameraProperties; - NVRenderCachedShaderProperty m_DepthCube; - NVRenderCachedShaderProperty m_DepthMap; - - volatile QT3DSI32 mRefCount; - - SShadowmapPreblurShader(NVRenderShaderProgram &inShader) - : m_Shader(inShader) - , m_CameraProperties("camera_properties", inShader) - , m_DepthCube("depthCube", inShader) - , m_DepthMap("depthSrc", inShader) - , mRefCount(0) - { - m_Shader.addRef(); - } - ~SShadowmapPreblurShader() { m_Shader.release(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader.GetRenderContext().GetAllocator()) - }; - -#ifdef ADVANCED_BLEND_SW_FALLBACK - struct SAdvancedModeBlendShader - { - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_baseLayer; - NVRenderCachedShaderProperty m_blendLayer; - - volatile QT3DSI32 mRefCount; - - SAdvancedModeBlendShader(NVRenderShaderProgram &inShader) - : m_Shader(inShader) - , m_baseLayer("base_layer", inShader) - , m_blendLayer("blend_layer", inShader) - , mRefCount(0) - { - m_Shader.addRef(); - } - ~SAdvancedModeBlendShader() { m_Shader.release(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader.GetRenderContext().GetAllocator()) - - }; -#endif - - struct SGGSGet - { - QT3DSU32 operator()(const SShaderGeneratorGeneratedShader &inShader) - { - return inShader.m_LayerSetIndex; - } - }; - struct SGGSSet - { - void operator()(SShaderGeneratorGeneratedShader &inShader, QT3DSU32 idx) - { - inShader.m_LayerSetIndex = idx; - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSVertexPipelineImpl.h b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSVertexPipelineImpl.h deleted file mode 100644 index e2de7e0f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSVertexPipelineImpl.h +++ /dev/null @@ -1,435 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_VERTEX_PIPELINE_IMPL_H -#define QT3DS_VERTEX_PIPELINE_IMPL_H -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" - -namespace qt3ds { -namespace render { - // Baseclass for the vertex pipelines to be sure we have consistent implementations. - struct SVertexPipelineImpl : public IDefaultMaterialVertexPipeline - { - struct GenerationFlagValues - { - enum Enum { - UVCoords = 1, - EnvMapReflection = 1 << 1, - ViewVector = 1 << 2, - WorldNormal = 1 << 3, - ObjectNormal = 1 << 4, - WorldPosition = 1 << 5, - TangentBinormal = 1 << 6, - UVCoords1 = 1 << 7, - VertexColor = 1 << 8, - }; - }; - - typedef TStrTableStrMap::const_iterator TParamIter; - typedef NVFlags TGenerationFlags; - - IMaterialShaderGenerator &m_MaterialGenerator; - IShaderProgramGenerator &m_ProgramGenerator; - IStringTable &m_StringTable; - CRenderString m_TempString; - - TGenerationFlags m_GenerationFlags; - bool m_Wireframe; - TStrTableStrMap m_InterpolationParameters; - QT3DSU32 m_DisplacementIdx; - SRenderableImage *m_DisplacementImage; - QStringList m_addedFunctions; - - SVertexPipelineImpl(NVAllocatorCallback &inAllocator, IMaterialShaderGenerator &inMaterial, - IShaderProgramGenerator &inProgram, IStringTable &inStringTable, - bool inWireframe // only works if tessellation is true - ) - - : m_MaterialGenerator(inMaterial) - , m_ProgramGenerator(inProgram) - , m_StringTable(inStringTable) - , m_Wireframe(inWireframe) - , m_InterpolationParameters(inAllocator, "m_InterpolationParameters") - , m_DisplacementIdx(0) - , m_DisplacementImage(NULL) - { - } - - // Trues true if the code was *not* set. - bool SetCode(GenerationFlagValues::Enum inCode) - { - if (((QT3DSU32)m_GenerationFlags & inCode) != 0) - return true; - m_GenerationFlags |= inCode; - return false; - } - bool HasCode(GenerationFlagValues::Enum inCode) - { - return ((QT3DSU32)(m_GenerationFlags & inCode)) != 0; - } - IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } - IShaderStageGenerator &Vertex() - { - return *ProgramGenerator().GetStage(ShaderGeneratorStages::Vertex); - } - IShaderStageGenerator &TessControl() - { - return *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl); - } - IShaderStageGenerator &TessEval() - { - return *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval); - } - IShaderStageGenerator &Geometry() - { - return *ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry); - } - IShaderStageGenerator &Fragment() - { - return *ProgramGenerator().GetStage(ShaderGeneratorStages::Fragment); - } - IMaterialShaderGenerator &MaterialGenerator() { return m_MaterialGenerator; } - - void SetupDisplacement(QT3DSU32 displacementImageIdx, SRenderableImage *displacementImage) - { - m_DisplacementIdx = displacementImageIdx; - m_DisplacementImage = displacementImage; - } - - CRegisteredString Str(const char8_t *inItem) { return m_StringTable.RegisterStr(inItem); } - - bool HasTessellation() const - { - return m_ProgramGenerator.GetEnabledStages() & ShaderGeneratorStages::TessEval; - } - bool HasGeometryStage() const - { - return m_ProgramGenerator.GetEnabledStages() & ShaderGeneratorStages::Geometry; - } - bool HasDisplacment() const { return m_DisplacementImage != NULL; } - - void InitializeWireframeGeometryShader() - { - if (m_Wireframe && ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry) - && ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)) { - IShaderStageGenerator &geometryShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry)); - // currently geometry shader is only used for drawing wireframe - if (m_Wireframe) { - geometryShader.AddUniform("viewport_matrix", "mat4"); - geometryShader.AddOutgoing("varEdgeDistance", "vec3"); - geometryShader.Append("layout (triangles) in;"); - geometryShader.Append("layout (triangle_strip, max_vertices = 3) out;"); - geometryShader.Append("void main() {"); - - // how this all work see - // http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf - - geometryShader.Append( - "// project points to screen space\n" - "\tvec3 p0 = vec3(viewport_matrix * (gl_in[0].gl_Position / " - "gl_in[0].gl_Position.w));\n" - "\tvec3 p1 = vec3(viewport_matrix * (gl_in[1].gl_Position / " - "gl_in[1].gl_Position.w));\n" - "\tvec3 p2 = vec3(viewport_matrix * (gl_in[2].gl_Position / " - "gl_in[2].gl_Position.w));\n" - "// compute triangle heights\n" - "\tfloat e1 = length(p1 - p2);\n" - "\tfloat e2 = length(p2 - p0);\n" - "\tfloat e3 = length(p1 - p0);\n" - "\tfloat alpha = acos( (e2*e2 + e3*e3 - e1*e1) / (2.0*e2*e3) );\n" - "\tfloat beta = acos( (e1*e1 + e3*e3 - e2*e2) / (2.0*e1*e3) );\n" - "\tfloat ha = abs( e3 * sin( beta ) );\n" - "\tfloat hb = abs( e3 * sin( alpha ) );\n" - "\tfloat hc = abs( e2 * sin( alpha ) );\n"); - } - } - } - - void FinalizeWireframeGeometryShader() - { - IShaderStageGenerator &geometryShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry)); - - if (m_Wireframe == true && ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry) - && ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)) { - const char8_t *theExtension("TE["); - // we always assume triangles - for (int i = 0; i < 3; i++) { - char buf[10]; - sprintf(buf, "%d", i); - for (TStrTableStrMap::const_iterator iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - geometryShader << "\t" << iter->first.c_str() << " = " - << iter->first.c_str() << theExtension << buf << "];\n"; - } - - geometryShader << "\tgl_Position = gl_in[" << buf << "].gl_Position;\n"; - // the triangle distance is interpolated through the shader stage - if (i == 0) - geometryShader << "\n\tvarEdgeDistance = vec3(ha*" - << "gl_in[" << buf << "].gl_Position.w, 0.0, 0.0);\n"; - else if (i == 1) - geometryShader << "\n\tvarEdgeDistance = vec3(0.0, hb*" - << "gl_in[" << buf << "].gl_Position.w, 0.0);\n"; - else if (i == 2) - geometryShader << "\n\tvarEdgeDistance = vec3(0.0, 0.0, hc*" - << "gl_in[" << buf << "].gl_Position.w);\n"; - - // submit vertex - geometryShader << "\tEmitVertex();\n"; - } - // end primitive - geometryShader << "\tEndPrimitive();\n"; - } - } - - virtual void SetupTessIncludes(ShaderGeneratorStages::Enum inStage, - TessModeValues::Enum inTessMode) - { - IShaderStageGenerator &tessShader(*ProgramGenerator().GetStage(inStage)); - - // depending on the selected tessellation mode chose program - switch (inTessMode) { - case TessModeValues::TessPhong: - tessShader.AddInclude("tessellationPhong.glsllib"); - break; - case TessModeValues::TessNPatch: - tessShader.AddInclude("tessellationNPatch.glsllib"); - break; - default: - QT3DS_ASSERT(false); // fallthrough intentional - case TessModeValues::TessLinear: - tessShader.AddInclude("tessellationLinear.glsllib"); - break; - } - } - - void GenerateUVCoords(QT3DSU32 inUVSet = 0) override - { - if (inUVSet == 0 && SetCode(GenerationFlagValues::UVCoords)) - return; - if (inUVSet == 1 && SetCode(GenerationFlagValues::UVCoords1)) - return; - - QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); - - if (inUVSet == 0) - AddInterpolationParameter("varTexCoord0", "vec2"); - else if (inUVSet == 1) - AddInterpolationParameter("varTexCoord1", "vec2"); - - DoGenerateUVCoords(inUVSet); - } - void GenerateEnvMapReflection() override - { - if (SetCode(GenerationFlagValues::EnvMapReflection)) - return; - - GenerateWorldPosition(); - GenerateWorldNormal(); - IShaderStageGenerator &activeGenerator(ActiveStage()); - activeGenerator.AddInclude("viewProperties.glsllib"); - AddInterpolationParameter("var_object_to_camera", "vec3"); - activeGenerator.Append("\tvar_object_to_camera = normalize( local_model_world_position " - "- camera_position );"); - // World normal cannot be relied upon in the vertex shader because of bump maps. - Fragment().Append("\tvec3 environment_map_reflection = reflect( " - "normalize(var_object_to_camera), world_normal.xyz );"); - Fragment().Append("\tenvironment_map_reflection *= vec3( 0.5, 0.5, 0 );"); - Fragment().Append("\tenvironment_map_reflection += vec3( 0.5, 0.5, 1.0 );"); - } - void GenerateViewVector() override - { - if (SetCode(GenerationFlagValues::ViewVector)) - return; - GenerateWorldPosition(); - IShaderStageGenerator &activeGenerator(ActiveStage()); - activeGenerator.AddInclude("viewProperties.glsllib"); - AddInterpolationParameter("varViewVector", "vec3"); - activeGenerator.Append("\tvec3 local_view_vector = normalize(camera_position - " - "local_model_world_position);"); - AssignOutput("varViewVector", "local_view_vector"); - Fragment() << "\tvec3 view_vector = normalize(varViewVector);" << Endl; - } - - // fragment shader expects varying vertex normal - // lighting in vertex pipeline expects world_normal - void GenerateWorldNormal() override - { - if (SetCode(GenerationFlagValues::WorldNormal)) - return; - AddInterpolationParameter("varNormal", "vec3"); - DoGenerateWorldNormal(); - Fragment().Append("\tvec3 world_normal = normalize( varNormal );"); - } - void GenerateObjectNormal() override - { - if (SetCode(GenerationFlagValues::ObjectNormal)) - return; - DoGenerateObjectNormal(); - Fragment().Append("\tvec3 object_normal = normalize(varObjectNormal);"); - } - void GenerateWorldPosition() override - { - if (SetCode(GenerationFlagValues::WorldPosition)) - return; - - ActiveStage().AddUniform("model_matrix", "mat4"); - AddInterpolationParameter("varWorldPos", "vec3"); - DoGenerateWorldPosition(); - - AssignOutput("varWorldPos", "local_model_world_position"); - } - void GenerateVarTangentAndBinormal() override - { - if (SetCode(GenerationFlagValues::TangentBinormal)) - return; - AddInterpolationParameter("varTangent", "vec3"); - AddInterpolationParameter("varBinormal", "vec3"); - DoGenerateVarTangentAndBinormal(); - Fragment() << "\tvec3 tangent = normalize(varTangent);" << Endl - << "\tvec3 binormal = normalize(varBinormal);" << Endl; - } - void GenerateVertexColor() override - { - if (SetCode(GenerationFlagValues::VertexColor)) - return; - AddInterpolationParameter("varColor", "vec3"); - DoGenerateVertexColor(); - Fragment().Append("\tvec3 vertColor = varColor;"); - } - - bool HasActiveWireframe() override { return m_Wireframe; } - - // IShaderStageGenerator interface - void AddIncoming(const char8_t *name, const char8_t *type) override - { - ActiveStage().AddIncoming(name, type); - } - void AddIncoming(const TStrType &name, const char8_t *type) override - { - AddIncoming(name.c_str(), type); - } - - void AddOutgoing(const char8_t *name, const char8_t *type) override - { - AddInterpolationParameter(name, type); - } - void AddOutgoing(const TStrType &name, const char8_t *type) override - { - AddOutgoing(name.c_str(), type); - } - - void AddUniform(const char8_t *name, const char8_t *type) override - { - ActiveStage().AddUniform(name, type); - } - void AddUniform(const TStrType &name, const char8_t *type) override - { - AddUniform(name.c_str(), type); - } - - void AddInclude(const char8_t *name) override { ActiveStage().AddInclude(name); } - void AddInclude(const TStrType &name) override { AddInclude(name.c_str()); } - void AddInclude(const QString &name) override - { - QByteArray arr = name.toLatin1(); - AddInclude(arr.data()); - } - - void AddFunction(const QString &functionName) override - { - if (!m_addedFunctions.contains(functionName)) { - m_addedFunctions.push_back(functionName); - QString includeName; - QTextStream stream(&includeName); - stream << "func" << functionName << ".glsllib"; - AddInclude(includeName); - } - } - - void AddConstantBuffer(const char *name, const char *layout) override - { - ActiveStage().AddConstantBuffer(name, layout); - } - void AddConstantBufferParam(const char *cbName, const char *paramName, - const char *type) override - { - ActiveStage().AddConstantBufferParam(cbName, paramName, type); - } - - IShaderStageGenerator &operator<<(const char *data) override - { - ActiveStage() << data; - return *this; - } - IShaderStageGenerator &operator<<(const TStrType &data) override - { - ActiveStage() << data; - return *this; - } - IShaderStageGenerator &operator<<(const SEndlType &data) override - { - ActiveStage() << data; - return *this; - } - void Append(const char *data) override { ActiveStage().Append(data); } - void AppendPartial(const char *data) override { ActiveStage().Append(data); } - - ShaderGeneratorStages::Enum Stage() const override - { - return const_cast(this)->ActiveStage().Stage(); - } - - void BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override = 0; - void AssignOutput(const char8_t *inVarName, const char8_t *inVarValueExpr) override = 0; - void EndVertexGeneration() override = 0; - - void BeginFragmentGeneration() override = 0; - void EndFragmentGeneration() override = 0; - - virtual IShaderStageGenerator &ActiveStage() = 0; - virtual void AddInterpolationParameter(const char8_t *inParamName, - const char8_t *inParamType) = 0; - - virtual void DoGenerateUVCoords(QT3DSU32 inUVSet) = 0; - virtual void DoGenerateWorldNormal() = 0; - virtual void DoGenerateObjectNormal() = 0; - virtual void DoGenerateWorldPosition() = 0; - virtual void DoGenerateVarTangentAndBinormal() = 0; - virtual void DoGenerateVertexColor() = 0; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.cpp deleted file mode 100644 index 963186ff..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderBufferLoader.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSSync.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderThreadPool.h" - -using namespace qt3ds::render; - -namespace { -struct SBufferLoader; -struct SBufferLoadResult : public ILoadedBuffer -{ - NVFoundationBase &m_Foundation; - CRegisteredString m_Path; - IBufferLoaderCallback *m_UserData; - NVDataRef m_Data; - QT3DSI32 mRefCount; - - SBufferLoadResult(NVFoundationBase &fnd, CRegisteredString p, IBufferLoaderCallback *ud, - NVDataRef data) - : m_Foundation(fnd) - , m_Path(p) - , m_UserData(ud) - , m_Data(data) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - CRegisteredString Path() override { return m_Path; } - // Data is released when the buffer itself is released. - NVDataRef Data() override { return m_Data; } - IBufferLoaderCallback *UserData() override { return m_UserData; } - - static SBufferLoadResult *Allocate(QT3DSU32 inBufferSize, NVFoundationBase &fnd, - CRegisteredString p, - NVScopedRefCounted ud) - { - size_t allocSize = sizeof(SBufferLoadResult) + inBufferSize; - QT3DSU8 *allocMem = - (QT3DSU8 *)fnd.getAllocator().allocate(allocSize, "ILoadedBuffer", __FILE__, __LINE__); - if (allocMem == NULL) - return NULL; - QT3DSU8 *bufferStart = allocMem + sizeof(SBufferLoadResult); - NVDataRef dataBuffer = toDataRef(bufferStart, inBufferSize); - return new (allocMem) SBufferLoadResult(fnd, p, ud, dataBuffer); - } -}; -struct SLoadedBufferImpl -{ - SBufferLoader &m_Loader; - QT3DSU64 m_JobId; - QT3DSU64 m_LoadId; - CRegisteredString m_Path; - NVScopedRefCounted m_UserData; - bool m_Quiet; - volatile bool m_Cancel; - NVScopedRefCounted m_Result; - SLoadedBufferImpl *m_NextBuffer; - SLoadedBufferImpl *m_PreviousBuffer; - - SLoadedBufferImpl(SBufferLoader &l, CRegisteredString inPath, - NVScopedRefCounted ud, bool inQuiet, QT3DSU64 loadId) - : m_Loader(l) - , m_JobId(0) - , m_LoadId(loadId) - , m_Path(inPath) - , m_UserData(ud) - , m_Quiet(inQuiet) - , m_Cancel(false) - , m_NextBuffer(NULL) - , m_PreviousBuffer(NULL) - { - } -}; - -DEFINE_INVASIVE_LIST(LoadedBufferImpl); -IMPLEMENT_INVASIVE_LIST(LoadedBufferImpl, m_PreviousBuffer, m_NextBuffer); - -struct SBufferLoader : public IBufferLoader -{ - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_Factory; - NVScopedRefCounted m_ThreadPool; - - Mutex m_BuffersToLoadMutex; - TLoadedBufferImplList m_BuffersToLoad; - - Mutex m_BuffersLoadingMutex; - TLoadedBufferImplList m_BuffersLoading; - - Mutex m_LoadedBuffersMutex; - TLoadedBufferImplList m_LoadedBuffers; - - Sync m_BufferLoadedEvent; - - QT3DSU64 m_NextBufferId; - - QT3DSI32 mRefCount; - - SBufferLoader(NVFoundationBase &fnd, IInputStreamFactory &fac, IThreadPool &tp) - : m_Foundation(fnd) - , m_Factory(fac) - , m_ThreadPool(tp) - , m_BuffersToLoadMutex(fnd.getAllocator()) - , m_BuffersLoadingMutex(fnd.getAllocator()) - , m_LoadedBuffersMutex(fnd.getAllocator()) - , m_BufferLoadedEvent(fnd.getAllocator()) - , m_NextBufferId(1) - , mRefCount(0) - { - m_BufferLoadedEvent.reset(); - } - - virtual ~SBufferLoader() - { - { - Mutex::ScopedLock __locker(m_BuffersToLoadMutex); - for (TLoadedBufferImplList::iterator iter = m_BuffersToLoad.begin(), - end = m_BuffersToLoad.end(); - iter != end; ++iter) { - m_ThreadPool->CancelTask(iter->m_JobId); - } - } - - // Pull any remaining buffers out of the thread system. - while (WillLoadedBuffersBeAvailable()) { - NextLoadedBuffer(); - } - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - static void InitializeActiveLoadingBuffer(SLoadedBufferImpl &theBuffer) - { - Mutex::ScopedLock theLocker(theBuffer.m_Loader.m_BuffersToLoadMutex); - Mutex::ScopedLock theSecondLocker(theBuffer.m_Loader.m_BuffersLoadingMutex); - theBuffer.m_Loader.m_BuffersToLoad.remove(theBuffer); - theBuffer.m_Loader.m_BuffersLoading.push_back(theBuffer); - } - - static void SetBufferAsLoaded(SLoadedBufferImpl &theBuffer) - { - Mutex::ScopedLock theSecondLocker(theBuffer.m_Loader.m_BuffersLoadingMutex); - Mutex::ScopedLock theLocker(theBuffer.m_Loader.m_LoadedBuffersMutex); - theBuffer.m_Loader.m_BuffersLoading.remove(theBuffer); - theBuffer.m_Loader.m_LoadedBuffers.push_back(theBuffer); - theBuffer.m_Loader.m_BufferLoadedEvent.set(); - theBuffer.m_Loader.m_BufferLoadedEvent.reset(); - } - - static void LoadNextBuffer(void *loader) - { - SLoadedBufferImpl &theBuffer = *reinterpret_cast(loader); - - InitializeActiveLoadingBuffer(theBuffer); - NVScopedRefCounted theStream = - theBuffer.m_Loader.m_Factory->GetStreamForFile(theBuffer.m_Path.c_str(), - theBuffer.m_Quiet); - if (theStream && theBuffer.m_Cancel == false) { - theStream->SetPosition(0, SeekPosition::End); - QT3DSI64 theFileLen = theStream->GetPosition(); - if (theFileLen > 0 && theFileLen < (QT3DSU32)QT3DS_MAX_U32) { - QT3DSU32 required = (QT3DSU32)theFileLen; - theBuffer.m_Result = - SBufferLoadResult::Allocate(required, theBuffer.m_Loader.m_Foundation, - theBuffer.m_Path, theBuffer.m_UserData); - QT3DSU32 amountRead = 0; - QT3DSU32 total = amountRead; - if (theBuffer.m_Result && theBuffer.m_Cancel == false) { - NVDataRef theDataBuffer(theBuffer.m_Result->m_Data); - theStream->SetPosition(0, SeekPosition::Begin); - amountRead = theStream->Read(theDataBuffer); - total += amountRead; - // Ensure we keep trying, not all file systems allow huge reads. - while (total < required && amountRead > 0 && theBuffer.m_Cancel == false) { - NVDataRef newBuffer(theDataBuffer.mData + total, required - total); - amountRead = theStream->Read(newBuffer); - total += amountRead; - } - } - if (theBuffer.m_Cancel || total != required) { - theBuffer.m_Result->m_Data = NVDataRef(); - } - } - } - - // only callback if the file was successfully loaded. - if (theBuffer.m_UserData) { - if (theBuffer.m_Cancel == false && theBuffer.m_Result.mPtr - && theBuffer.m_Result->m_Data.size()) { - theBuffer.m_UserData->OnBufferLoaded(*theBuffer.m_Result.mPtr); - } else { - if (theBuffer.m_Cancel) - theBuffer.m_UserData->OnBufferLoadCancelled(theBuffer.m_Path); - else - theBuffer.m_UserData->OnBufferLoadFailed(theBuffer.m_Path); - } - } - - SetBufferAsLoaded(theBuffer); - } - static void CancelNextBuffer(void *loader) - { - SLoadedBufferImpl &theBuffer = *reinterpret_cast(loader); - theBuffer.m_Cancel = true; - InitializeActiveLoadingBuffer(theBuffer); - - if (theBuffer.m_UserData) - theBuffer.m_UserData->OnBufferLoadCancelled(theBuffer.m_Path); - - SetBufferAsLoaded(theBuffer); - } - - // nonblocking. Quiet failure is passed to the input stream factory. - QT3DSU64 QueueForLoading(CRegisteredString inPath, - IBufferLoaderCallback *inUserData = NULL, - bool inQuietFailure = false) override - { - SLoadedBufferImpl &theBuffer = *QT3DS_NEW(m_Foundation.getAllocator(), SLoadedBufferImpl)( - *this, inPath, inUserData, inQuietFailure, m_NextBufferId); - ++m_NextBufferId; - { - Mutex::ScopedLock theLocker(m_BuffersToLoadMutex); - m_BuffersToLoad.push_back(theBuffer); - } - theBuffer.m_JobId = m_ThreadPool->AddTask(&theBuffer, LoadNextBuffer, CancelNextBuffer); - return theBuffer.m_LoadId; - } - - void CancelBufferLoad(QT3DSU64 inBufferId) override - { - { - Mutex::ScopedLock theLocker(m_BuffersToLoadMutex); - SLoadedBufferImpl *theLoadedBuffer = NULL; - for (TLoadedBufferImplList::iterator iter = m_BuffersToLoad.begin(), - end = m_BuffersToLoad.end(); - iter != end && theLoadedBuffer == NULL; ++iter) { - if (iter->m_LoadId == inBufferId) { - theLoadedBuffer = &(*iter); - // both cancellation attempts are necessary. The user will still get - // a load result, it will just have no data. - theLoadedBuffer->m_Cancel = true; - m_ThreadPool->CancelTask(theLoadedBuffer->m_JobId); - } - } - } - } - - // If we were will to wait, will we ever get another buffer - bool WillLoadedBuffersBeAvailable() override - { - Mutex::ScopedLock theLocker(m_BuffersToLoadMutex); - Mutex::ScopedLock theSecondLocker(m_BuffersLoadingMutex); - return AreLoadedBuffersAvailable() || m_BuffersToLoad.empty() == false - || m_BuffersLoading.empty() == false; - } - // Will nextLoadedBuffer block or not? - bool AreLoadedBuffersAvailable() override - { - Mutex::ScopedLock theLocker(m_LoadedBuffersMutex); - return m_LoadedBuffers.empty() == false; - } - - // blocking, be careful with this. No order guarantees here. - NVScopedRefCounted NextLoadedBuffer() override - { - while (!AreLoadedBuffersAvailable()) { - m_BufferLoadedEvent.wait(); - } - SLoadedBufferImpl *theBuffer; - { - Mutex::ScopedLock theLocker(m_LoadedBuffersMutex); - theBuffer = m_LoadedBuffers.back_ptr(); - m_LoadedBuffers.remove(*theBuffer); - } - NVScopedRefCounted retval(theBuffer->m_Result); - if (retval.mPtr == NULL) { - retval = SBufferLoadResult::Allocate(0, m_Foundation, theBuffer->m_Path, - theBuffer->m_UserData); - } - NVDelete(m_Foundation.getAllocator(), theBuffer); - return retval; - } -}; -} - -IBufferLoader &IBufferLoader::Create(NVFoundationBase &fnd, IInputStreamFactory &inFactory, - IThreadPool &inThreadPool) -{ - return *QT3DS_NEW(fnd.getAllocator(), SBufferLoader)(fnd, inFactory, inThreadPool); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.h deleted file mode 100644 index 8d75e259..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferLoader.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BUFFER_LOADED_H -#define QT3DS_RENDER_BUFFER_LOADED_H - -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace render { - - class IBufferLoaderCallback; - - class ILoadedBuffer : public NVRefCounted - { - public: - virtual CRegisteredString Path() = 0; - // Data is released when the buffer itself is released. - virtual NVDataRef Data() = 0; - virtual IBufferLoaderCallback *UserData() = 0; - }; - - class IBufferLoaderCallback : public NVRefCounted - { - public: - virtual void OnBufferLoaded(ILoadedBuffer &inBuffer) = 0; - virtual void OnBufferLoadFailed(CRegisteredString inPath) = 0; - virtual void OnBufferLoadCancelled(CRegisteredString inPath) = 0; - }; - - // Job of this object is to load buffers all the way to memory as fast as possible. - class IBufferLoader : public NVRefCounted - { - public: - // nonblocking. Quiet failure is passed to the input stream factory. - // Returns handle to loading buffer - virtual QT3DSU64 QueueForLoading(CRegisteredString inPath, - IBufferLoaderCallback *inUserData = NULL, - bool inQuietFailure = false) = 0; - // Cancel a buffer that has not made it to the loaded buffers list. - virtual void CancelBufferLoad(QT3DSU64 inBufferId) = 0; - // If we were will to wait, will we ever get another buffer - virtual bool WillLoadedBuffersBeAvailable() = 0; - // Will nextLoadedBuffer block or not? - virtual bool AreLoadedBuffersAvailable() = 0; - - // blocking, be careful with this. No guarantees about timely return here. - virtual NVScopedRefCounted NextLoadedBuffer() = 0; - - static IBufferLoader &Create(NVFoundationBase &fnd, IInputStreamFactory &inFactory, - IThreadPool &inThreadPool); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp deleted file mode 100644 index 37ca281f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp +++ /dev/null @@ -1,920 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifdef _WIN32 -#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union -#endif -#include "Qt3DSRender.h" -#include "Qt3DSRenderBufferManager.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSAllocator.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/hash_map.h" -#include "foundation/FileTools.h" -#include "Qt3DSImportMesh.h" -#include "Qt3DSRenderMesh.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "Qt3DSRenderLoadedTexture.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderImageScaler.h" -#include "Qt3DSTextRenderer.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/Qt3DSMutex.h" -#include "Qt3DSRenderPrefilterTexture.h" -#include - -using namespace qt3ds::render; - -namespace { - -using eastl::hash; -using eastl::pair; -using eastl::make_pair; -typedef eastl::basic_string TStr; -struct StrHasher -{ - size_t operator()(const TStr &str) const - { - return hash()((const char8_t *)str.c_str()); - } -}; - -struct StrEq -{ - bool operator()(const TStr &lhs, const TStr &rhs) const { return lhs == rhs; } -}; - -struct SImageEntry : public SImageTextureData -{ - bool m_Loaded; - SImageEntry() - : m_Loaded(false) - { - } - ~SImageEntry() - { - if (m_BSDFMipMap) - m_BSDFMipMap->release(); - } -}; - -struct SPrimitiveEntry -{ - // Name of the primitive as it will be in the UIP file - CRegisteredString m_PrimitiveName; - // Name of the primitive file on the filesystem - CRegisteredString m_FileName; -}; - -struct SBufferManager : public IBufferManager -{ - typedef eastl::hash_set, - eastl::equal_to, ForwardingAllocator> - TStringSet; - typedef nvhash_map TImageMap; - typedef nvhash_map TMeshMap; - typedef nvhash_map TAliasImageMap; - - NVScopedRefCounted m_Context; - NVScopedRefCounted m_StrTable; - NVScopedRefCounted m_InputStreamFactory; - IPerfTimer &m_PerfTimer; - volatile QT3DSI32 mRefCount; - TStr m_PathBuilder; - TImageMap m_ImageMap; - Mutex m_LoadedImageSetMutex; - TStringSet m_LoadedImageSet; - TAliasImageMap m_AliasImageMap; - TMeshMap m_MeshMap; - SPrimitiveEntry m_PrimitiveNames[5]; - nvvector m_EntryBuffer; - bool m_GPUSupportsDXT; - static const char8_t *GetPrimitivesDirectory() { return "res//primitives"; } - - SBufferManager(NVRenderContext &ctx, IStringTable &strTable, - IInputStreamFactory &inInputStreamFactory, IPerfTimer &inTimer) - : m_Context(ctx) - , m_StrTable(strTable) - , m_InputStreamFactory(inInputStreamFactory) - , m_PerfTimer(inTimer) - , mRefCount(0) - , m_PathBuilder(ForwardingAllocator(ctx.GetAllocator(), "SBufferManager::m_PathBuilder")) - , m_ImageMap(ctx.GetAllocator(), "SBufferManager::m_ImageMap") - , m_LoadedImageSetMutex(ctx.GetAllocator()) - , m_LoadedImageSet( - ForwardingAllocator(ctx.GetAllocator(), "SBufferManager::m_LoadedImageSet")) - , m_AliasImageMap(ctx.GetAllocator(), "SBufferManager::m_AliasImageMap") - , m_MeshMap(ctx.GetAllocator(), "SBufferManager::m_MeshMap") - , m_EntryBuffer(ctx.GetAllocator(), "SBufferManager::m_EntryBuffer") - , m_GPUSupportsDXT(ctx.AreDXTImagesSupported()) - { - } - virtual ~SBufferManager() { Clear(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Context->GetAllocator()) - - CRegisteredString CombineBaseAndRelative(const char8_t *inBase, - const char8_t *inRelative) override - { - CFileTools::CombineBaseAndRelative(inBase, inRelative, m_PathBuilder); - return m_StrTable->RegisterStr(m_PathBuilder.c_str()); - } - - void SetImageHasTransparency(CRegisteredString inImagePath, bool inHasTransparency) override - { - pair theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - theImage.first->second.m_TextureFlags.SetHasTransparency(inHasTransparency); - } - - bool GetImageHasTransparency(CRegisteredString inSourcePath) const override - { - TImageMap::const_iterator theIter = m_ImageMap.find(inSourcePath); - if (theIter != m_ImageMap.end()) - return theIter->second.m_TextureFlags.HasTransparency(); - return false; - } - - void SetImageTransparencyToFalseIfNotSet(CRegisteredString inSourcePath) override - { - pair theImage = - m_ImageMap.insert(make_pair(inSourcePath, SImageEntry())); - // If we did actually insert something - if (theImage.second) - theImage.first->second.m_TextureFlags.SetHasTransparency(false); - } - - void SetInvertImageUVCoords(CRegisteredString inImagePath, bool inShouldInvertCoords) override - { - pair theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - theImage.first->second.m_TextureFlags.SetInvertUVCoords(inShouldInvertCoords); - } - - bool IsImageLoaded(CRegisteredString inSourcePath) override - { - Mutex::ScopedLock __locker(m_LoadedImageSetMutex); - return m_LoadedImageSet.find(inSourcePath) != m_LoadedImageSet.end(); - } - - bool AliasImagePath(CRegisteredString inSourcePath, CRegisteredString inAliasPath, - bool inIgnoreIfLoaded) override - { - if (inSourcePath.IsValid() == false || inAliasPath.IsValid() == false) - return false; - // If the image is loaded then we ignore this call in some cases. - if (inIgnoreIfLoaded && IsImageLoaded(inSourcePath)) - return false; - m_AliasImageMap.insert(eastl::make_pair(inSourcePath, inAliasPath)); - return true; - } - - void UnaliasImagePath(CRegisteredString inSourcePath) override - { - m_AliasImageMap.erase(inSourcePath); - } - - CRegisteredString GetImagePath(CRegisteredString inSourcePath) override - { - TAliasImageMap::iterator theAliasIter = m_AliasImageMap.find(inSourcePath); - if (theAliasIter != m_AliasImageMap.end()) - return theAliasIter->second; - return inSourcePath; - } - - static inline int wrapMod(int a, int base) - { - int ret = a % base; - if (ret < 0) - ret += base; - return ret; - } - - static inline void getWrappedCoords(int &sX, int &sY, int width, int height) - { - if (sY < 0) { - sX -= width >> 1; - sY = -sY; - } - if (sY >= height) { - sX += width >> 1; - sY = height - sY; - } - sX = wrapMod(sX, width); - sY = wrapMod(sY, height); - } - - SImageTextureData LoadRenderImage(CRegisteredString inImagePath, - SLoadedTexture &inLoadedImage, - bool inForceScanForTransparency, bool inBsdfMipmaps) override - { - SStackPerfTimer __perfTimer(m_PerfTimer, "Image Upload"); - { - Mutex::ScopedLock __mapLocker(m_LoadedImageSetMutex); - m_LoadedImageSet.insert(inImagePath); - } - pair theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - bool wasInserted = theImage.second; - theImage.first->second.m_Loaded = true; - // inLoadedImage.EnsureMultiplerOfFour( m_Context->GetFoundation(), inImagePath.c_str() ); - - NVRenderTexture2D *theTexture = m_Context->CreateTexture2D(); - if (inLoadedImage.data) { - qt3ds::render::NVRenderTextureFormats::Enum destFormat = inLoadedImage.format; - if (inBsdfMipmaps) { - if (m_Context->GetRenderContextType() == render::NVRenderContextValues::GLES2) - destFormat = qt3ds::render::NVRenderTextureFormats::RGBA8; - else - destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F; - } - else { - theTexture->SetTextureData( - NVDataRef((QT3DSU8 *)inLoadedImage.data, inLoadedImage.dataSizeInBytes), 0, - inLoadedImage.width, inLoadedImage.height, inLoadedImage.format, destFormat); - } - - if (inBsdfMipmaps - && NVRenderTextureFormats::isUncompressedTextureFormat(inLoadedImage.format)) { - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - Qt3DSRenderPrefilterTexture *theBSDFMipMap = theImage.first->second.m_BSDFMipMap; - if (theBSDFMipMap == NULL) { - theBSDFMipMap = Qt3DSRenderPrefilterTexture::Create( - m_Context, inLoadedImage.width, inLoadedImage.height, *theTexture, - destFormat, m_Context->GetFoundation()); - theImage.first->second.m_BSDFMipMap = theBSDFMipMap; - } - - if (theBSDFMipMap) { - theBSDFMipMap->Build(inLoadedImage.data, inLoadedImage.dataSizeInBytes, - inLoadedImage.format); - } - } - } else if (inLoadedImage.dds) { - theImage.first->second.m_Texture = theTexture; - bool supportsDXT = m_GPUSupportsDXT; - bool isDXT = NVRenderTextureFormats::isCompressedTextureFormat(inLoadedImage.format); - bool requiresDecompression = (supportsDXT == false && isDXT) || false; - // test code for DXT decompression - // if ( isDXT ) requiresDecompression = true; - if (requiresDecompression) { - qCWarning(WARNING, PERF_INFO, - "Image %s is DXT format which is unsupported by " - "the graphics subsystem, decompressing in CPU", - inImagePath.c_str()); - } - STextureData theDecompressedImage; - for (int idx = 0; idx < inLoadedImage.dds->numMipmaps; ++idx) { - if (inLoadedImage.dds->mipwidth[idx] && inLoadedImage.dds->mipheight[idx]) { - if (requiresDecompression == false) { - theTexture->SetTextureData( - toU8DataRef((char *)inLoadedImage.dds->data[idx], - (QT3DSU32)inLoadedImage.dds->size[idx]), - (QT3DSU8)idx, (QT3DSU32)inLoadedImage.dds->mipwidth[idx], - (QT3DSU32)inLoadedImage.dds->mipheight[idx], inLoadedImage.format); - } else { - theDecompressedImage = - inLoadedImage.DecompressDXTImage(idx, &theDecompressedImage); - - if (theDecompressedImage.data) { - theTexture->SetTextureData( - toU8DataRef((char *)theDecompressedImage.data, - (QT3DSU32)theDecompressedImage.dataSizeInBytes), - (QT3DSU8)idx, (QT3DSU32)inLoadedImage.dds->mipwidth[idx], - (QT3DSU32)inLoadedImage.dds->mipheight[idx], - theDecompressedImage.format); - } - } - } - } - if (theDecompressedImage.data) - inLoadedImage.ReleaseDecompressedTexture(theDecompressedImage); - } - if (wasInserted == true || inForceScanForTransparency) - theImage.first->second.m_TextureFlags.SetHasTransparency( - inLoadedImage.ScanForTransparency()); - theImage.first->second.m_Texture = theTexture; - return theImage.first->second; - } - - SImageTextureData LoadRenderImage(CRegisteredString inImagePath, - bool inForceScanForTransparency, bool inBsdfMipmaps) override - { - inImagePath = GetImagePath(inImagePath); - - if (!inImagePath.IsValid()) - return SImageEntry(); - - TImageMap::iterator theIter = m_ImageMap.find(inImagePath); - if (theIter == m_ImageMap.end() && inImagePath.IsValid()) { - NVScopedReleasable theLoadedImage; - { - SStackPerfTimer __perfTimer(m_PerfTimer, "Image Decompression"); - theLoadedImage = SLoadedTexture::Load( - inImagePath.c_str(), m_Context->GetFoundation(), *m_InputStreamFactory, - true, m_Context->GetRenderContextType()); - // Hackish solution to custom materials not finding their textures if they are used - // in sub-presentations. Note: Runtime 1 is going to be removed in Qt 3D Studio 2.x, - // so this should be ok. - if (!theLoadedImage) { - if (QDir(inImagePath.c_str()).isRelative()) { - QString searchPath = inImagePath.c_str(); - if (searchPath.startsWith(QLatin1String("./"))) - searchPath.prepend(QLatin1String(".")); - int loops = 0; - while (!theLoadedImage && ++loops <= 3) { - theLoadedImage = SLoadedTexture::Load( - searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, - m_Context->GetRenderContextType()); - searchPath.prepend(QLatin1String("../")); - } - } else { - // Some textures, for example environment maps for custom materials, - // have absolute path at this point. It points to the wrong place with - // the new project structure, so we need to split it up and construct - // the new absolute path here. - QString wholePath = inImagePath.c_str(); - QStringList splitPath = wholePath.split(QLatin1String("../")); - if (splitPath.size() > 1) { - QString searchPath = splitPath.at(0) + splitPath.at(1); - int loops = 0; - while (!theLoadedImage && ++loops <= 3) { - theLoadedImage = SLoadedTexture::Load( - searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, - m_Context->GetRenderContextType()); - searchPath = splitPath.at(0); - for (int i = 0; i < loops; i++) - searchPath.append(QLatin1String("../")); - searchPath.append(splitPath.at(1)); - } - } - } - } - } - - if (theLoadedImage) { - return LoadRenderImage(inImagePath, *theLoadedImage, inForceScanForTransparency, - inBsdfMipmaps); - } else { - // We want to make sure that bad path fails once and doesn't fail over and over - // again - // which could slow down the system quite a bit. - pair theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - theImage.first->second.m_Loaded = true; - qCWarning(WARNING, "Failed to load image: %s", inImagePath.c_str()); - theIter = theImage.first; - } - } - return theIter->second; - } - - qt3dsimp::SMultiLoadResult LoadPrimitive(const char8_t *inRelativePath) - { - CRegisteredString theName(m_StrTable->RegisterStr(inRelativePath)); - if (m_PrimitiveNames[0].m_PrimitiveName.IsValid() == false) { - IStringTable &strTable(m_Context->GetStringTable()); - m_PrimitiveNames[0].m_PrimitiveName = strTable.RegisterStr("#Rectangle"); - m_PrimitiveNames[0].m_FileName = strTable.RegisterStr("Rectangle.mesh"); - m_PrimitiveNames[1].m_PrimitiveName = strTable.RegisterStr("#Sphere"); - m_PrimitiveNames[1].m_FileName = strTable.RegisterStr("Sphere.mesh"); - m_PrimitiveNames[2].m_PrimitiveName = strTable.RegisterStr("#Cube"); - m_PrimitiveNames[2].m_FileName = strTable.RegisterStr("Cube.mesh"); - m_PrimitiveNames[3].m_PrimitiveName = strTable.RegisterStr("#Cone"); - m_PrimitiveNames[3].m_FileName = strTable.RegisterStr("Cone.mesh"); - m_PrimitiveNames[4].m_PrimitiveName = strTable.RegisterStr("#Cylinder"); - m_PrimitiveNames[4].m_FileName = strTable.RegisterStr("Cylinder.mesh"); - } - for (size_t idx = 0; idx < 5; ++idx) { - if (m_PrimitiveNames[idx].m_PrimitiveName == theName) { - CFileTools::CombineBaseAndRelative(GetPrimitivesDirectory(), - m_PrimitiveNames[idx].m_FileName, m_PathBuilder); - QT3DSU32 id = 1; - NVScopedRefCounted theInStream( - m_InputStreamFactory->GetStreamForFile(m_PathBuilder.c_str())); - if (theInStream) - return qt3dsimp::Mesh::LoadMulti(m_Context->GetAllocator(), *theInStream, id); - else { - qCCritical(INTERNAL_ERROR, "Unable to find mesh primitive %s", - m_PathBuilder.c_str()); - return qt3dsimp::SMultiLoadResult(); - } - } - } - return qt3dsimp::SMultiLoadResult(); - } - - virtual NVConstDataRef CreatePackedPositionDataArray(qt3dsimp::SMultiLoadResult *inResult) - { - // we assume a position consists of 3 floats - QT3DSU32 vertexCount = inResult->m_Mesh->m_VertexBuffer.m_Data.size() - / inResult->m_Mesh->m_VertexBuffer.m_Stride; - QT3DSU32 dataSize = vertexCount * 3 * sizeof(QT3DSF32); - QT3DSF32 *posData = (QT3DSF32 *)QT3DS_ALLOC(m_Context->GetAllocator(), dataSize, - "SRenderMesh::CreatePackedPositionDataArray"); - QT3DSU8 *baseOffset = reinterpret_cast(inResult->m_Mesh); - // copy position data - if (posData) { - QT3DSF32 *srcData = (QT3DSF32 *)inResult->m_Mesh->m_VertexBuffer.m_Data.begin(baseOffset); - QT3DSU32 srcStride = inResult->m_Mesh->m_VertexBuffer.m_Stride / sizeof(QT3DSF32); - QT3DSF32 *dstData = posData; - QT3DSU32 dstStride = 3; - - for (QT3DSU32 i = 0; i < vertexCount; ++i) { - dstData[0] = srcData[0]; - dstData[1] = srcData[1]; - dstData[2] = srcData[2]; - - dstData += dstStride; - srcData += srcStride; - } - - return toConstDataRef((const qt3ds::QT3DSU8 *)posData, dataSize); - } - - return NVConstDataRef(); - } - - SRenderMesh *LoadMesh(CRegisteredString inMeshPath) override - { - if (inMeshPath.IsValid() == false) - return NULL; - pair theMesh = - m_MeshMap.insert(make_pair(inMeshPath, (SRenderMesh *)NULL)); - if (theMesh.second == true) { - // check to see if this is primitive - - qt3dsimp::SMultiLoadResult theResult = LoadPrimitive(inMeshPath); - - // Attempt a load from the filesystem if this mesh isn't a primitive. - if (theResult.m_Mesh == NULL) { - m_PathBuilder = inMeshPath; - TStr::size_type pound = m_PathBuilder.rfind('#'); - QT3DSU32 id = 0; - if (pound != TStr::npos) { - id = atoi(m_PathBuilder.c_str() + pound + 1); - m_PathBuilder.erase(m_PathBuilder.begin() + pound, m_PathBuilder.end()); - } - NVScopedRefCounted theStream( - m_InputStreamFactory->GetStreamForFile(m_PathBuilder.c_str())); - if (theStream) { - theResult = qt3dsimp::Mesh::LoadMulti(m_Context->GetAllocator(), *theStream, id); - } - if (theResult.m_Mesh == NULL) - qCWarning(WARNING, "Failed to load mesh: %s", m_PathBuilder.c_str()); - } - - if (theResult.m_Mesh) { - SRenderMesh *theNewMesh = QT3DS_NEW(m_Context->GetAllocator(), SRenderMesh)( - qt3ds::render::NVRenderDrawMode::Triangles, - qt3ds::render::NVRenderWinding::CounterClockwise, theResult.m_Id, - m_Context->GetAllocator()); - QT3DSU8 *baseAddress = reinterpret_cast(theResult.m_Mesh); - theMesh.first->second = theNewMesh; - NVConstDataRef theVBufData( - theResult.m_Mesh->m_VertexBuffer.m_Data.begin(baseAddress), - theResult.m_Mesh->m_VertexBuffer.m_Data.size()); - - NVRenderVertexBuffer *theVertexBuffer = m_Context->CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, - theResult.m_Mesh->m_VertexBuffer.m_Data.m_Size, - theResult.m_Mesh->m_VertexBuffer.m_Stride, theVBufData); - - // create a tight packed position data VBO - // this should improve our depth pre pass rendering - NVRenderVertexBuffer *thePosVertexBuffer = NULL; - NVConstDataRef posData = CreatePackedPositionDataArray(&theResult); - if (posData.size()) { - thePosVertexBuffer = - m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, - posData.size(), 3 * sizeof(QT3DSF32), posData); - } - - NVRenderIndexBuffer *theIndexBuffer = NULL; - if (theResult.m_Mesh->m_IndexBuffer.m_Data.size()) { - using qt3ds::render::NVRenderComponentTypes; - QT3DSU32 theIndexBufferSize = theResult.m_Mesh->m_IndexBuffer.m_Data.size(); - NVRenderComponentTypes::Enum bufComponentType = - theResult.m_Mesh->m_IndexBuffer.m_ComponentType; - QT3DSU32 sizeofType = - qt3ds::render::NVRenderComponentTypes::getSizeofType(bufComponentType); - - if (sizeofType == 2 || sizeofType == 4) { - // Ensure type is unsigned; else things will fail in rendering pipeline. - if (bufComponentType == NVRenderComponentTypes::QT3DSI16) - bufComponentType = NVRenderComponentTypes::QT3DSU16; - if (bufComponentType == NVRenderComponentTypes::QT3DSI32) - bufComponentType = NVRenderComponentTypes::QT3DSU32; - - NVConstDataRef theIBufData( - theResult.m_Mesh->m_IndexBuffer.m_Data.begin(baseAddress), - theResult.m_Mesh->m_IndexBuffer.m_Data.size()); - theIndexBuffer = m_Context->CreateIndexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, bufComponentType, - theIndexBufferSize, theIBufData); - } else { - QT3DS_ASSERT(false); - } - } - nvvector &theEntryBuffer(m_EntryBuffer); - theEntryBuffer.resize(theResult.m_Mesh->m_VertexBuffer.m_Entries.size()); - for (QT3DSU32 entryIdx = 0, - entryEnd = theResult.m_Mesh->m_VertexBuffer.m_Entries.size(); - entryIdx < entryEnd; ++entryIdx) { - theEntryBuffer[entryIdx] = - theResult.m_Mesh->m_VertexBuffer.m_Entries.index(baseAddress, entryIdx) - .ToVertexBufferEntry(baseAddress); - } - // create our attribute layout - NVRenderAttribLayout *theAttribLayout = - m_Context->CreateAttributeLayout(theEntryBuffer); - // create our attribute layout for depth pass - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry( - "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - }; - NVRenderAttribLayout *theAttribLayoutDepth = - m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 1)); - - // create input assembler object - QT3DSU32 strides = theResult.m_Mesh->m_VertexBuffer.m_Stride; - QT3DSU32 offsets = 0; - NVRenderInputAssembler *theInputAssembler = m_Context->CreateInputAssembler( - theAttribLayout, toConstDataRef(&theVertexBuffer, 1), theIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), - theResult.m_Mesh->m_DrawMode); - - // create depth input assembler object - QT3DSU32 posStrides = (thePosVertexBuffer) ? 3 * sizeof(QT3DSF32) : strides; - NVRenderInputAssembler *theInputAssemblerDepth = m_Context->CreateInputAssembler( - theAttribLayoutDepth, - toConstDataRef((thePosVertexBuffer) ? &thePosVertexBuffer : &theVertexBuffer, - 1), - theIndexBuffer, toConstDataRef(&posStrides, 1), toConstDataRef(&offsets, 1), - theResult.m_Mesh->m_DrawMode); - - NVRenderInputAssembler *theInputAssemblerPoints = m_Context->CreateInputAssembler( - theAttribLayoutDepth, - toConstDataRef((thePosVertexBuffer) ? &thePosVertexBuffer : &theVertexBuffer, - 1), - NULL, toConstDataRef(&posStrides, 1), toConstDataRef(&offsets, 1), - NVRenderDrawMode::Points); - - if (!theInputAssembler || !theInputAssemblerDepth || !theInputAssemblerPoints) { - QT3DS_ASSERT(false); - return NULL; - } - theNewMesh->m_Joints.resize(theResult.m_Mesh->m_Joints.size()); - for (QT3DSU32 jointIdx = 0, jointEnd = theResult.m_Mesh->m_Joints.size(); - jointIdx < jointEnd; ++jointIdx) { - const qt3dsimp::Joint &theImportJoint( - theResult.m_Mesh->m_Joints.index(baseAddress, jointIdx)); - SRenderJoint &theNewJoint(theNewMesh->m_Joints[jointIdx]); - theNewJoint.m_JointID = theImportJoint.m_JointID; - theNewJoint.m_ParentID = theImportJoint.m_ParentID; - memCopy(theNewJoint.m_invBindPose, theImportJoint.m_invBindPose, - 16 * sizeof(QT3DSF32)); - memCopy(theNewJoint.m_localToGlobalBoneSpace, - theImportJoint.m_localToGlobalBoneSpace, 16 * sizeof(QT3DSF32)); - } - - for (QT3DSU32 subsetIdx = 0, subsetEnd = theResult.m_Mesh->m_Subsets.size(); - subsetIdx < subsetEnd; ++subsetIdx) { - SRenderSubset theSubset(m_Context->GetAllocator()); - const qt3dsimp::MeshSubset &source( - theResult.m_Mesh->m_Subsets.index(baseAddress, subsetIdx)); - theSubset.m_Bounds = source.m_Bounds; - theSubset.m_Count = source.m_Count; - theSubset.m_Offset = source.m_Offset; - theSubset.m_Joints = theNewMesh->m_Joints; - theSubset.m_Name = m_StrTable->RegisterStr(source.m_Name.begin(baseAddress)); - theVertexBuffer->addRef(); - theSubset.m_VertexBuffer = theVertexBuffer; - if (thePosVertexBuffer) { - thePosVertexBuffer->addRef(); - theSubset.m_PosVertexBuffer = thePosVertexBuffer; - } - if (theIndexBuffer) { - theIndexBuffer->addRef(); - theSubset.m_IndexBuffer = theIndexBuffer; - } - theSubset.m_InputAssembler = theInputAssembler; - theSubset.m_InputAssemblerDepth = theInputAssemblerDepth; - theSubset.m_InputAssemblerPoints = theInputAssemblerPoints; - theSubset.m_PrimitiveType = theResult.m_Mesh->m_DrawMode; - theInputAssembler->addRef(); - theInputAssemblerDepth->addRef(); - theSubset.m_InputAssemblerPoints->addRef(); - theNewMesh->m_Subsets.push_back(theSubset); - } -// If we want to, we can an in a quite stupid way break up modes into sub-subsets. -// These are assumed to use the same material as the outer subset but have fewer tris -// and should have a more exact bounding box. This sort of thing helps with using the frustum -// culling -// system but it is really done incorrectly. It should be done via some sort of oct-tree mechanism -// and it -// so that the sub-subsets spatially sorted and it should only be done upon save-to-binary with the -// results -// saved out to disk. As you can see, doing it properly requires some real engineering effort so it -// is somewhat -// unlikely it will ever happen. Or it could be done on import if someone really wants to change -// the mesh buffer -// format. Either way it isn't going to happen here and it isn't going to happen this way but this -// is a working -// example of using the technique. -#ifdef QT3DS_RENDER_GENERATE_SUB_SUBSETS - Option thePosAttrOpt = - theVertexBuffer->GetEntryByName("attr_pos"); - bool hasPosAttr = thePosAttrOpt.hasValue() - && thePosAttrOpt->m_ComponentType == qt3ds::render::NVRenderComponentTypes::QT3DSF32 - && thePosAttrOpt->m_NumComponents == 3; - - for (size_t subsetIdx = 0, subsetEnd = theNewMesh->m_Subsets.size(); - subsetIdx < subsetEnd; ++subsetIdx) { - SRenderSubset &theOuterSubset = theNewMesh->m_Subsets[subsetIdx]; - if (theOuterSubset.m_Count && theIndexBuffer - && theIndexBuffer->GetComponentType() - == qt3ds::render::NVRenderComponentTypes::QT3DSU16 - && theNewMesh->m_DrawMode == NVRenderDrawMode::Triangles && hasPosAttr) { - // Num tris in a sub subset. - QT3DSU32 theSubsetSize = 3334 * 3; // divisible by three. - size_t theNumSubSubsets = - ((theOuterSubset.m_Count - 1) / theSubsetSize) + 1; - QT3DSU32 thePosAttrOffset = thePosAttrOpt->m_FirstItemOffset; - const QT3DSU8 *theVertData = theResult.m_Mesh->m_VertexBuffer.m_Data.begin(); - const QT3DSU8 *theIdxData = theResult.m_Mesh->m_IndexBuffer.m_Data.begin(); - QT3DSU32 theVertStride = theResult.m_Mesh->m_VertexBuffer.m_Stride; - QT3DSU32 theOffset = theOuterSubset.m_Offset; - QT3DSU32 theCount = theOuterSubset.m_Count; - for (size_t subSubsetIdx = 0, subSubsetEnd = theNumSubSubsets; - subSubsetIdx < subSubsetEnd; ++subSubsetIdx) { - SRenderSubsetBase theBase; - theBase.m_Offset = theOffset; - theBase.m_Count = NVMin(theSubsetSize, theCount); - theBase.m_Bounds.setEmpty(); - theCount -= theBase.m_Count; - theOffset += theBase.m_Count; - // Create new bounds. - // Offset is in item size, not bytes. - const QT3DSU16 *theSubsetIdxData = - reinterpret_cast(theIdxData + theBase.m_Offset * 2); - for (size_t theIdxIdx = 0, theIdxEnd = theBase.m_Count; - theIdxIdx < theIdxEnd; ++theIdxIdx) { - QT3DSU32 theVertOffset = theSubsetIdxData[theIdxIdx] * theVertStride; - theVertOffset += thePosAttrOffset; - QT3DSVec3 thePos = *( - reinterpret_cast(theVertData + theVertOffset)); - theBase.m_Bounds.include(thePos); - } - theOuterSubset.m_SubSubsets.push_back(theBase); - } - } else { - SRenderSubsetBase theBase; - theBase.m_Bounds = theOuterSubset.m_Bounds; - theBase.m_Count = theOuterSubset.m_Count; - theBase.m_Offset = theOuterSubset.m_Offset; - theOuterSubset.m_SubSubsets.push_back(theBase); - } - } -#endif - if (posData.size()) - m_Context->GetAllocator().deallocate((void *)posData.begin()); - - m_Context->GetAllocator().deallocate(theResult.m_Mesh); - } - } - return theMesh.first->second; - } - - SRenderMesh *CreateMesh(Qt3DSBCharPtr inSourcePath, QT3DSU8 *inVertData, QT3DSU32 inNumVerts, - QT3DSU32 inVertStride, QT3DSU32 *inIndexData, QT3DSU32 inIndexCount, - qt3ds::NVBounds3 inBounds) override - { - CRegisteredString sourcePath = m_StrTable->RegisterStr(inSourcePath); - - // eastl::pair thePair(sourcePath, (SRenderMesh*)NULL); - pair theMesh; - // Make sure there isn't already a buffer entry for this mesh. - if (m_MeshMap.contains(sourcePath)) { - theMesh = make_pair(m_MeshMap.find(sourcePath), true); - } else { - theMesh = m_MeshMap.insert(make_pair(sourcePath, (SRenderMesh *)NULL)); - } - - if (theMesh.second == true) { - SRenderMesh *theNewMesh = QT3DS_NEW(m_Context->GetAllocator(), SRenderMesh)( - qt3ds::render::NVRenderDrawMode::Triangles, - qt3ds::render::NVRenderWinding::CounterClockwise, 0, m_Context->GetAllocator()); - - // If we failed to create the RenderMesh, return a failure. - if (!theNewMesh) { - QT3DS_ASSERT(false); - return NULL; - } - - // Get rid of any old mesh that was sitting here and fill it with a new one. - // NOTE : This is assuming that the source of our mesh data doesn't do its own memory - // management and always returns new buffer pointers every time. - // Don't know for sure if that's what we'll get from our intended sources, but that's - // easily - // adjustable by looking for matching pointers in the Subsets. - if (theNewMesh && theMesh.first->second != NULL) { - delete theMesh.first->second; - theMesh.first->second = NULL; - } - - theMesh.first->second = theNewMesh; - QT3DSU32 vertDataSize = inNumVerts * inVertStride; - NVConstDataRef theVBufData(inVertData, vertDataSize); - // NVConstDataRef theVBufData( theResult.m_Mesh->m_VertexBuffer.m_Data.begin( - // baseAddress ) - // , theResult.m_Mesh->m_VertexBuffer.m_Data.size() ); - - NVRenderVertexBuffer *theVertexBuffer = - m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, - vertDataSize, inVertStride, theVBufData); - NVRenderIndexBuffer *theIndexBuffer = NULL; - if (inIndexData != NULL && inIndexCount > 3) { - NVConstDataRef theIBufData((QT3DSU8 *)inIndexData, inIndexCount * sizeof(QT3DSU32)); - theIndexBuffer = - m_Context->CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, - qt3ds::render::NVRenderComponentTypes::QT3DSU32, - inIndexCount * sizeof(QT3DSU32), theIBufData); - } - - // WARNING - // Making an assumption here about the contents of the stream - // PKC TODO : We may have to consider some other format. - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry( - "attr_uv", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), - qt3ds::render::NVRenderVertexBufferEntry( - "attr_norm", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3, 18), - }; - - // create our attribute layout - NVRenderAttribLayout *theAttribLayout = - m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 3)); - /* - // create our attribute layout for depth pass - qt3ds::render::NVRenderVertexBufferEntry theEntriesDepth[] = { - qt3ds::render::NVRenderVertexBufferEntry( "attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3 ), - }; - NVRenderAttribLayout* theAttribLayoutDepth = m_Context->CreateAttributeLayout( - toConstDataRef( theEntriesDepth, 1 ) ); - */ - // create input assembler object - QT3DSU32 strides = inVertStride; - QT3DSU32 offsets = 0; - NVRenderInputAssembler *theInputAssembler = m_Context->CreateInputAssembler( - theAttribLayout, toConstDataRef(&theVertexBuffer, 1), theIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), - qt3ds::render::NVRenderDrawMode::Triangles); - - if (!theInputAssembler) { - QT3DS_ASSERT(false); - return NULL; - } - - // Pull out just the mesh object name from the total path - eastl::string fullName(inSourcePath); - eastl::string subName(inSourcePath); - if (fullName.rfind("#") != eastl::string::npos) { - subName = fullName.substr(fullName.rfind("#"), eastl::string::npos); - } - - theNewMesh->m_Joints.clear(); - SRenderSubset theSubset(m_Context->GetAllocator()); - theSubset.m_Bounds = inBounds; - theSubset.m_Count = inIndexCount; - theSubset.m_Offset = 0; - theSubset.m_Joints = theNewMesh->m_Joints; - theSubset.m_Name = m_StrTable->RegisterStr(subName.c_str()); - theVertexBuffer->addRef(); - theSubset.m_VertexBuffer = theVertexBuffer; - theSubset.m_PosVertexBuffer = NULL; - if (theIndexBuffer) - theIndexBuffer->addRef(); - theSubset.m_IndexBuffer = theIndexBuffer; - theSubset.m_InputAssembler = theInputAssembler; - theSubset.m_InputAssemblerDepth = theInputAssembler; - theSubset.m_InputAssemblerPoints = theInputAssembler; - theSubset.m_PrimitiveType = qt3ds::render::NVRenderDrawMode::Triangles; - theSubset.m_InputAssembler->addRef(); - theSubset.m_InputAssemblerDepth->addRef(); - theSubset.m_InputAssemblerPoints->addRef(); - theNewMesh->m_Subsets.push_back(theSubset); - } - - return theMesh.first->second; - } - - void ReleaseMesh(SRenderMesh &inMesh) - { - for (QT3DSU32 subsetIdx = 0, subsetEnd = inMesh.m_Subsets.size(); subsetIdx < subsetEnd; - ++subsetIdx) { - inMesh.m_Subsets[subsetIdx].m_VertexBuffer->release(); - if (inMesh.m_Subsets[subsetIdx].m_PosVertexBuffer) // can be NULL - inMesh.m_Subsets[subsetIdx].m_PosVertexBuffer->release(); - if (inMesh.m_Subsets[subsetIdx].m_IndexBuffer) // can be NULL - inMesh.m_Subsets[subsetIdx].m_IndexBuffer->release(); - inMesh.m_Subsets[subsetIdx].m_InputAssembler->release(); - inMesh.m_Subsets[subsetIdx].m_InputAssemblerDepth->release(); - if (inMesh.m_Subsets[subsetIdx].m_InputAssemblerPoints) - inMesh.m_Subsets[subsetIdx].m_InputAssemblerPoints->release(); - } - NVDelete(m_Context->GetAllocator(), &inMesh); - } - void ReleaseTexture(SImageEntry &inEntry) - { - if (inEntry.m_Texture) - inEntry.m_Texture->release(); - } - void Clear() override - { - for (TMeshMap::iterator iter = m_MeshMap.begin(), end = m_MeshMap.end(); iter != end; - ++iter) { - SRenderMesh *theMesh = iter->second; - if (theMesh) - ReleaseMesh(*theMesh); - } - m_MeshMap.clear(); - for (TImageMap::iterator iter = m_ImageMap.begin(), end = m_ImageMap.end(); iter != end; - ++iter) { - SImageEntry &theEntry = iter->second; - ReleaseTexture(theEntry); - } - m_ImageMap.clear(); - m_AliasImageMap.clear(); - { - Mutex::ScopedLock __locker(m_LoadedImageSetMutex); - m_LoadedImageSet.clear(); - } - } - void InvalidateBuffer(CRegisteredString inSourcePath) override - { - { - TMeshMap::iterator iter = m_MeshMap.find(inSourcePath); - if (iter != m_MeshMap.end()) { - if (iter->second) - ReleaseMesh(*iter->second); - m_MeshMap.erase(iter); - return; - } - } - { - TImageMap::iterator iter = m_ImageMap.find(inSourcePath); - if (iter != m_ImageMap.end()) { - SImageEntry &theEntry = iter->second; - ReleaseTexture(theEntry); - m_ImageMap.erase(inSourcePath); - { - Mutex::ScopedLock __locker(m_LoadedImageSetMutex); - m_LoadedImageSet.erase(inSourcePath); - } - } - } - } - IStringTable &GetStringTable() override { return *m_StrTable; } -}; -} - -IBufferManager &IBufferManager::Create(NVRenderContext &inRenderContext, IStringTable &inStrTable, - IInputStreamFactory &inFactory, IPerfTimer &inPerfTimer) -{ - return *QT3DS_NEW(inRenderContext.GetAllocator(), SBufferManager)(inRenderContext, inStrTable, - inFactory, inPerfTimer); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.h deleted file mode 100644 index cd9e3d33..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_BUFFER_MANAGER_H -#define QT3DS_RENDER_BUFFER_MANAGER_H -#include "Qt3DSRender.h" -#include "EASTL/utility.h" //pair -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderImageTextureData.h" -#include "foundation/Qt3DSBounds3.h" - -namespace qt3ds { -namespace render { - - class IBufferManager : public NVRefCounted - { - protected: - virtual ~IBufferManager() {} - - public: - // Path manipulation used to get the final path form a base path plus relative extension - virtual CRegisteredString CombineBaseAndRelative(const char8_t *inBase, - const char8_t *inRelative) = 0; - virtual void SetImageHasTransparency(CRegisteredString inSourcePath, - bool inHasTransparency) = 0; - virtual bool GetImageHasTransparency(CRegisteredString inSourcePath) const = 0; - virtual void SetImageTransparencyToFalseIfNotSet(CRegisteredString inSourcePath) = 0; - virtual void SetInvertImageUVCoords(CRegisteredString inSourcePath, - bool inShouldInvertCoords) = 0; - - // Returns true if this image has been loaded into memory - // This call is threadsafe. Nothing else on this object is guaranteed to be. - virtual bool IsImageLoaded(CRegisteredString inSourcePath) = 0; - - // Alias one image path with another image path. Optionally this object will ignore the - // call if - // the source path is already loaded. Aliasing is currently used to allow a default image - // to be shown - // in place of an image that is loading offline. - // Returns true if the image was aliased, false otherwise. - virtual bool AliasImagePath(CRegisteredString inSourcePath, CRegisteredString inAliasPath, - bool inIgnoreIfLoaded) = 0; - virtual void UnaliasImagePath(CRegisteredString inSourcePath) = 0; - - // Returns the given source path unless the source path is aliased; in which case returns - // the aliased path. - virtual CRegisteredString GetImagePath(CRegisteredString inSourcePath) = 0; - // Returns a texture and a boolean indicating if this texture has transparency in it or not. - // Can't name this LoadImage because that gets mangled by windows to LoadImageA (uggh) - // In some cases we need to only scan particular images for transparency. - virtual SImageTextureData LoadRenderImage(CRegisteredString inImagePath, - SLoadedTexture &inTexture, - bool inForceScanForTransparency = false, - bool inBsdfMipmaps = false) = 0; - virtual SImageTextureData LoadRenderImage(CRegisteredString inSourcePath, - bool inForceScanForTransparency = false, - bool inBsdfMipmaps = false) = 0; - virtual SRenderMesh *LoadMesh(CRegisteredString inSourcePath) = 0; - - virtual SRenderMesh *CreateMesh(const char *inSourcePath, QT3DSU8 *inVertData, - QT3DSU32 inNumVerts, QT3DSU32 inVertStride, QT3DSU32 *inIndexData, - QT3DSU32 inIndexCount, qt3ds::NVBounds3 inBounds) = 0; - - // Remove *all* buffers from the buffer manager; - virtual void Clear() = 0; - virtual void InvalidateBuffer(CRegisteredString inSourcePath) = 0; - virtual IStringTable &GetStringTable() = 0; - - static IBufferManager &Create(NVRenderContext &inRenderContext, IStringTable &inStrTable, - IInputStreamFactory &inInputStreamFactory, - IPerfTimer &inTimer); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp deleted file mode 100644 index 8f1cb14f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderImageBatchLoader.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderThreadPool.h" -#include "Qt3DSRenderImageScaler.h" -#include "Qt3DSRenderLoadedTexture.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSPerfTimer.h" - -using namespace qt3ds::render; - -namespace { - -struct SImageLoaderBatch; -typedef Mutex::ScopedLock TScopedLock; - -struct SLoadingImage -{ - SImageLoaderBatch *m_Batch; - CRegisteredString m_SourcePath; - QT3DSU64 m_TaskId; - SLoadingImage *m_Tail; - - // Called from main thread - SLoadingImage(CRegisteredString inSourcePath) - : m_Batch(NULL) - , m_SourcePath(inSourcePath) - , m_TaskId(0) - , m_Tail(NULL) - { - } - SLoadingImage() - : m_Batch(NULL) - , m_TaskId(0) - , m_Tail(NULL) - { - } - // Called from main thread - void Setup(SImageLoaderBatch &inBatch); - - // Called from loader thread - static void LoadImage(void *inImg); - - // Potentially called from loader thread - static void TaskCancelled(void *inImg); -}; - -struct SLoadingImageTailOp -{ - SLoadingImage *get(SLoadingImage &inImg) { return inImg.m_Tail; } - void set(SLoadingImage &inImg, SLoadingImage *inItem) { inImg.m_Tail = inItem; } -}; - -typedef InvasiveSingleLinkedList TLoadingImageList; - -struct SBatchLoader; - -struct SImageLoaderBatch -{ - // All variables setup in main thread and constant from then on except - // loaded image count. - SBatchLoader &m_Loader; - NVScopedRefCounted m_LoadListener; - Sync m_LoadEvent; - Mutex m_LoadMutex; - TLoadingImageList m_Images; - - TImageBatchId m_BatchId; - // Incremented in main thread - QT3DSU32 m_LoadedOrCanceledImageCount; - QT3DSU32 m_FinalizedImageCount; - QT3DSU32 m_NumImages; - NVRenderContextType m_contextType; - bool m_preferKTX; - - // Called from main thread - static SImageLoaderBatch *CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBatchId, - NVConstDataRef inSourcePaths, - CRegisteredString inImageTillLoaded, - IImageLoadListener *inListener, - NVRenderContextType contextType, - bool preferKTX); - - // Called from main thread - SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, - const TLoadingImageList &inImageList, TImageBatchId inBatchId, - QT3DSU32 inImageCount, NVRenderContextType contextType, - bool preferKTX); - - // Called from main thread - ~SImageLoaderBatch(); - - // Called from main thread - bool IsLoadingFinished() - { - Mutex::ScopedLock __locker(m_LoadMutex); - return m_LoadedOrCanceledImageCount >= m_NumImages; - } - - bool IsFinalizedFinished() - { - Mutex::ScopedLock __locker(m_LoadMutex); - return m_FinalizedImageCount >= m_NumImages; - } - - void IncrementLoadedImageCount() - { - Mutex::ScopedLock __locker(m_LoadMutex); - ++m_LoadedOrCanceledImageCount; - } - void IncrementFinalizedImageCount() - { - Mutex::ScopedLock __locker(m_LoadMutex); - ++m_FinalizedImageCount; - } - // Called from main thread - void Cancel(); - void Cancel(CRegisteredString inSourcePath); -}; - -struct SBatchLoadedImage -{ - CRegisteredString m_SourcePath; - SLoadedTexture *m_Texture; - SImageLoaderBatch *m_Batch; - SBatchLoadedImage() - : m_Texture(NULL) - , m_Batch(NULL) - { - } - - // Called from loading thread - SBatchLoadedImage(CRegisteredString inSourcePath, SLoadedTexture *inTexture, - SImageLoaderBatch &inBatch) - : m_SourcePath(inSourcePath) - , m_Texture(inTexture) - , m_Batch(&inBatch) - { - } - - // Called from main thread - bool Finalize(IBufferManager &inMgr); -}; - -struct SBatchLoader : public IImageBatchLoader -{ - typedef nvhash_map TImageLoaderBatchMap; - typedef nvhash_map TSourcePathToBatchMap; - typedef Pool TLoadingImagePool; - typedef Pool TBatchPool; - - // Accessed from loader thread - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - // Accessed from loader thread - IInputStreamFactory &m_InputStreamFactory; - //!!Not threadsafe! accessed only from main thread - IBufferManager &m_BufferManager; - // Accessed from main thread - IThreadPool &m_ThreadPool; - // Accessed from both threads - IPerfTimer &m_PerfTimer; - // main thread - TImageBatchId m_NextBatchId; - // main thread - TImageLoaderBatchMap m_Batches; - // main thread - Mutex m_LoaderMutex; - - // Both loader and main threads - nvvector m_LoadedImages; - // main thread - nvvector m_FinishedBatches; - // main thread - TSourcePathToBatchMap m_SourcePathToBatches; - // main thread - nvvector m_LoaderBuilderWorkspace; - TLoadingImagePool m_LoadingImagePool; - TBatchPool m_BatchPool; - - SBatchLoader(NVFoundationBase &inFoundation, IInputStreamFactory &inFactory, - IBufferManager &inBufferManager, IThreadPool &inThreadPool, IPerfTimer &inTimer) - : m_Foundation(inFoundation) - , mRefCount(0) - , m_InputStreamFactory(inFactory) - , m_BufferManager(inBufferManager) - , m_ThreadPool(inThreadPool) - , m_PerfTimer(inTimer) - , m_NextBatchId(1) - , m_Batches(inFoundation.getAllocator(), "SBatchLoader::m_Batches") - , m_LoaderMutex(inFoundation.getAllocator()) - , m_LoadedImages(inFoundation.getAllocator(), "SBatchLoader::m_LoadedImages") - , m_FinishedBatches(inFoundation.getAllocator(), "SBatchLoader::m_FinishedBatches") - , m_SourcePathToBatches(inFoundation.getAllocator(), "SBatchLoader::m_SourcePathToBatches") - , m_LoaderBuilderWorkspace(inFoundation.getAllocator(), - "SBatchLoader::m_LoaderBuilderWorkspace") - , m_LoadingImagePool( - ForwardingAllocator(inFoundation.getAllocator(), "SBatchLoader::m_LoadingImagePool")) - , m_BatchPool(ForwardingAllocator(inFoundation.getAllocator(), "SBatchLoader::m_BatchPool")) - { - } - - virtual ~SBatchLoader() - { - nvvector theCancelledBatches(m_Foundation.getAllocator(), "~SBatchLoader"); - for (TImageLoaderBatchMap::iterator theIter = m_Batches.begin(), theEnd = m_Batches.end(); - theIter != theEnd; ++theIter) { - theIter->second->Cancel(); - theCancelledBatches.push_back(theIter->second->m_BatchId); - } - for (QT3DSU32 idx = 0, end = theCancelledBatches.size(); idx < end; ++idx) - BlockUntilLoaded(theCancelledBatches[idx]); - - QT3DS_ASSERT(m_Batches.size() == 0); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - // Returns an ID to the load request. Request a block of images to be loaded. - // Also takes an image that the buffer system will return when requested for the given source - // paths - // until said path is loaded. - // An optional listener can be passed in to get callbacks about the batch. - TImageBatchId LoadImageBatch(NVConstDataRef inSourcePaths, - CRegisteredString inImageTillLoaded, - IImageLoadListener *inListener, - NVRenderContextType contextType, - bool preferKTX) override - { - if (inSourcePaths.size() == 0) - return 0; - - TScopedLock __loaderLock(m_LoaderMutex); - - TImageBatchId theBatchId = 0; - - // Empty loop intentional to find an unused batch id. - for (theBatchId = m_NextBatchId; m_Batches.find(theBatchId) != m_Batches.end(); - ++m_NextBatchId, theBatchId = m_NextBatchId) { - } - - SImageLoaderBatch *theBatch(SImageLoaderBatch::CreateLoaderBatch( - *this, theBatchId, inSourcePaths, inImageTillLoaded, inListener, contextType, preferKTX)); - if (theBatch) { - m_Batches.insert(eastl::make_pair(theBatchId, theBatch)); - return theBatchId; - } - return 0; - } - - void CancelImageBatchLoading(TImageBatchId inBatchId) override - { - SImageLoaderBatch *theBatch(GetBatch(inBatchId)); - if (theBatch) - theBatch->Cancel(); - } - - // Blocks if the image is currently in-flight - void CancelImageLoading(CRegisteredString inSourcePath) override - { - TScopedLock __loaderLock(m_LoaderMutex); - TSourcePathToBatchMap::iterator theIter = m_SourcePathToBatches.find(inSourcePath); - if (theIter != m_SourcePathToBatches.end()) { - TImageBatchId theBatchId = theIter->second; - TImageLoaderBatchMap::iterator theBatchIter = m_Batches.find(theBatchId); - if (theBatchIter != m_Batches.end()) - theBatchIter->second->Cancel(inSourcePath); - } - } - - SImageLoaderBatch *GetBatch(TImageBatchId inId) - { - TScopedLock __loaderLock(m_LoaderMutex); - TImageLoaderBatchMap::iterator theIter = m_Batches.find(inId); - if (theIter != m_Batches.end()) - return theIter->second; - return NULL; - } - - void BlockUntilLoaded(TImageBatchId inId) override - { - for (SImageLoaderBatch *theBatch = GetBatch(inId); theBatch; theBatch = GetBatch(inId)) { - // Only need to block if images aren't loaded. Don't need to block if they aren't - // finalized. - if (!theBatch->IsLoadingFinished()) { - theBatch->m_LoadEvent.wait(200); - theBatch->m_LoadEvent.reset(); - } - BeginFrame(); - } - } - void ImageLoaded(SLoadingImage &inImage, SLoadedTexture *inTexture) - { - TScopedLock __loaderLock(m_LoaderMutex); - m_LoadedImages.push_back( - SBatchLoadedImage(inImage.m_SourcePath, inTexture, *inImage.m_Batch)); - inImage.m_Batch->IncrementLoadedImageCount(); - inImage.m_Batch->m_LoadEvent.set(); - } - // These are called by the render context, users don't need to call this. - void BeginFrame() override - { - TScopedLock __loaderLock(m_LoaderMutex); - // Pass 1 - send out all image loaded signals - for (QT3DSU32 idx = 0, end = m_LoadedImages.size(); idx < end; ++idx) { - - m_SourcePathToBatches.erase(m_LoadedImages[idx].m_SourcePath); - m_LoadedImages[idx].Finalize(m_BufferManager); - m_LoadedImages[idx].m_Batch->IncrementFinalizedImageCount(); - if (m_LoadedImages[idx].m_Batch->IsFinalizedFinished()) - m_FinishedBatches.push_back(m_LoadedImages[idx].m_Batch->m_BatchId); - } - m_LoadedImages.clear(); - // pass 2 - clean up any existing batches. - for (QT3DSU32 idx = 0, end = m_FinishedBatches.size(); idx < end; ++idx) { - TImageLoaderBatchMap::iterator theIter = m_Batches.find(m_FinishedBatches[idx]); - if (theIter != m_Batches.end()) { - SImageLoaderBatch *theBatch = theIter->second; - if (theBatch->m_LoadListener) - theBatch->m_LoadListener->OnImageBatchComplete(theBatch->m_BatchId); - m_Batches.erase(m_FinishedBatches[idx]); - theBatch->~SImageLoaderBatch(); - m_BatchPool.deallocate(theBatch); - } - } - m_FinishedBatches.clear(); - } - - void EndFrame() override {} -}; - -void SLoadingImage::Setup(SImageLoaderBatch &inBatch) -{ - m_Batch = &inBatch; - m_TaskId = inBatch.m_Loader.m_ThreadPool.AddTask(this, LoadImage, TaskCancelled); -} - -void SLoadingImage::LoadImage(void *inImg) -{ - SLoadingImage *theThis = reinterpret_cast(inImg); - SStackPerfTimer theTimer(theThis->m_Batch->m_Loader.m_PerfTimer, "Image Decompression"); - if (theThis->m_Batch->m_Loader.m_BufferManager.IsImageLoaded(theThis->m_SourcePath) == false) { - SLoadedTexture *theTexture = SLoadedTexture::Load( - theThis->m_SourcePath.c_str(), theThis->m_Batch->m_Loader.m_Foundation, - theThis->m_Batch->m_Loader.m_InputStreamFactory, true, - theThis->m_Batch->m_contextType, - theThis->m_Batch->m_preferKTX); - // if ( theTexture ) - // theTexture->EnsureMultiplerOfFour( theThis->m_Batch->m_Loader.m_Foundation, - //theThis->m_SourcePath.c_str() ); - - theThis->m_Batch->m_Loader.ImageLoaded(*theThis, theTexture); - } else { - theThis->m_Batch->m_Loader.ImageLoaded(*theThis, NULL); - } -} - -void SLoadingImage::TaskCancelled(void *inImg) -{ - SLoadingImage *theThis = reinterpret_cast(inImg); - theThis->m_Batch->m_Loader.ImageLoaded(*theThis, NULL); -} - -bool SBatchLoadedImage::Finalize(IBufferManager &inMgr) -{ - if (m_Texture) { - // PKC : We'll look at the path location to see if the image is in the standard - // location for IBL light probes or a standard hdr format and decide to generate BSDF - // miplevels (if the image doesn't have - // mipmaps of its own that is). - eastl::string thepath(m_SourcePath); - bool isIBL = (thepath.find(".hdr") != eastl::string::npos) - || (thepath.find("\\IBL\\") != eastl::string::npos) - || (thepath.find("/IBL/") != eastl::string::npos); - inMgr.LoadRenderImage(m_SourcePath, *m_Texture, false, isIBL); - inMgr.UnaliasImagePath(m_SourcePath); - } - if (m_Batch->m_LoadListener) - m_Batch->m_LoadListener->OnImageLoadComplete( - m_SourcePath, m_Texture ? ImageLoadResult::Succeeded : ImageLoadResult::Failed); - - if (m_Texture) { - m_Texture->release(); - return true; - } - - return false; -} - -SImageLoaderBatch * -SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBatchId, - NVConstDataRef inSourcePaths, - CRegisteredString inImageTillLoaded, - IImageLoadListener *inListener, - NVRenderContextType contextType, - bool preferKTX) -{ - TLoadingImageList theImages; - QT3DSU32 theLoadingImageCount = 0; - for (QT3DSU32 idx = 0, end = inSourcePaths.size(); idx < end; ++idx) { - CRegisteredString theSourcePath(inSourcePaths[idx]); - - if (theSourcePath.IsValid() == false) - continue; - - if (inLoader.m_BufferManager.IsImageLoaded(theSourcePath)) - continue; - - eastl::pair theInserter = - inLoader.m_SourcePathToBatches.insert(eastl::make_pair(inSourcePaths[idx], inBatchId)); - - // If the loader has already seen this image. - if (theInserter.second == false) - continue; - - if (inImageTillLoaded.IsValid()) { - // Alias the image so any further requests for this source path will result in - // the default images (image till loaded). - bool aliasSuccess = - inLoader.m_BufferManager.AliasImagePath(theSourcePath, inImageTillLoaded, true); - (void)aliasSuccess; - QT3DS_ASSERT(aliasSuccess); - } - - theImages.push_front( - *inLoader.m_LoadingImagePool.construct(theSourcePath, __FILE__, __LINE__)); - ++theLoadingImageCount; - } - if (theImages.empty() == false) { - SImageLoaderBatch *theBatch = - (SImageLoaderBatch *)inLoader.m_BatchPool.allocate(__FILE__, __LINE__); - new (theBatch) - SImageLoaderBatch(inLoader, inListener, theImages, inBatchId, theLoadingImageCount, - contextType, preferKTX); - return theBatch; - } - return NULL; -} - -SImageLoaderBatch::SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, - const TLoadingImageList &inImageList, TImageBatchId inBatchId, - QT3DSU32 inImageCount, NVRenderContextType contextType, - bool preferKTX) - : m_Loader(inLoader) - , m_LoadListener(inLoadListener) - , m_LoadEvent(inLoader.m_Foundation.getAllocator()) - , m_LoadMutex(inLoader.m_Foundation.getAllocator()) - , m_Images(inImageList) - , m_BatchId(inBatchId) - , m_LoadedOrCanceledImageCount(0) - , m_FinalizedImageCount(0) - , m_NumImages(inImageCount) - , m_contextType(contextType) - , m_preferKTX(preferKTX) -{ - for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; - ++iter) { - iter->Setup(*this); - } -} - -SImageLoaderBatch::~SImageLoaderBatch() -{ - for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; - ++iter) { - TLoadingImageList::iterator temp(iter); - ++iter; - m_Loader.m_LoadingImagePool.deallocate(temp.m_Obj); - } -} - -void SImageLoaderBatch::Cancel() -{ - for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; - ++iter) - m_Loader.m_ThreadPool.CancelTask(iter->m_TaskId); -} - -void SImageLoaderBatch::Cancel(CRegisteredString inSourcePath) -{ - for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; - ++iter) { - if (iter->m_SourcePath == inSourcePath) { - m_Loader.m_ThreadPool.CancelTask(iter->m_TaskId); - break; - } - } -} -} - -IImageBatchLoader &IImageBatchLoader::CreateBatchLoader(NVFoundationBase &inFoundation, - IInputStreamFactory &inFactory, - IBufferManager &inBufferManager, - IThreadPool &inThreadPool, - IPerfTimer &inTimer) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), - SBatchLoader)(inFoundation, inFactory, inBufferManager, inThreadPool, inTimer); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h deleted file mode 100644 index d45123f1..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_THREADED_IMAGE_LOADER_H -#define QT3DS_RENDER_THREADED_IMAGE_LOADER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSDataRef.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - struct ImageLoadResult - { - enum Enum { - Succeeded, - Failed, - }; - }; - - class IImageLoadListener : public NVRefCounted - { - protected: - virtual ~IImageLoadListener() {} - - public: - virtual void OnImageLoadComplete(CRegisteredString inPath, - ImageLoadResult::Enum inResult) = 0; - virtual void OnImageBatchComplete(QT3DSU64 inBatch) = 0; - }; - - typedef QT3DSU32 TImageBatchId; - - class IImageBatchLoader : public NVRefCounted - { - protected: - virtual ~IImageBatchLoader() {} - - public: - // Returns an ID to the load request. Request a block of images to be loaded. - // Also takes an image that the buffer system will return when requested for the given - // source paths - // until said path is loaded. - // An optional listener can be passed in to get callbacks about the batch. - virtual TImageBatchId LoadImageBatch(NVConstDataRef inSourcePaths, - CRegisteredString inImageTillLoaded, - IImageLoadListener *inListener, - NVRenderContextType type, - bool preferKTX) = 0; - // Blocks if any of the images in the batch are in flight - virtual void CancelImageBatchLoading(TImageBatchId inBatchId) = 0; - // Blocks if the image is currently in-flight - virtual void CancelImageLoading(CRegisteredString inSourcePath) = 0; - // Block until every image in the batch is loaded. - virtual void BlockUntilLoaded(TImageBatchId inId) = 0; - - // These are called by the render context, users don't need to call this. - virtual void BeginFrame() = 0; - virtual void EndFrame() = 0; - - static IImageBatchLoader &CreateBatchLoader(NVFoundationBase &inFoundation, - IInputStreamFactory &inFactory, - IBufferManager &inBufferManager, - IThreadPool &inThreadPool, IPerfTimer &inTimer); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp deleted file mode 100644 index 3365a2ce..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp +++ /dev/null @@ -1,704 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderLoadedTexture.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSDMWindowsCompatibility.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSRenderImageScaler.h" -#include "Qt3DSTextRenderer.h" -#include - -using namespace qt3ds::render; - -SLoadedTexture *SLoadedTexture::LoadQImage(const QString &inPath, QT3DSI32 flipVertical, - NVFoundationBase &fnd, - NVRenderContextType renderContextType) -{ - Q_UNUSED(flipVertical) - Q_UNUSED(renderContextType) - SLoadedTexture *retval(NULL); - NVAllocatorCallback &alloc(fnd.getAllocator()); - QImage image(inPath); - image = image.mirrored(); - image = image.rgbSwapped(); - retval = QT3DS_NEW(alloc, SLoadedTexture)(alloc); - retval->width = image.width(); - retval->height = image.height(); - retval->components = image.pixelFormat().channelCount(); - retval->image = image; - retval->data = (void*)retval->image.bits(); - retval->dataSizeInBytes = image.byteCount(); - retval->setFormatFromComponents(); - return retval; -} - - -namespace { - -/** - !!Large section of code ripped from FreeImage!! - -*/ -// ---------------------------------------------------------- -// Structures used by DXT textures -// ---------------------------------------------------------- -typedef QT3DSU8 BYTE; -typedef QT3DSU16 WORD; - -typedef struct tagColor8888 -{ - BYTE b; - BYTE g; - BYTE r; - BYTE a; -} Color8888; - -typedef struct tagColor565 -{ - WORD b : 5; - WORD g : 6; - WORD r : 5; -} Color565; - -typedef struct tagDXTColBlock -{ - Color565 colors[2]; - BYTE row[4]; -} DXTColBlock; - -typedef struct tagDXTAlphaBlockExplicit -{ - WORD row[4]; -} DXTAlphaBlockExplicit; - -typedef struct tagDXTAlphaBlock3BitLinear -{ - BYTE alpha[2]; - BYTE data[6]; -} DXTAlphaBlock3BitLinear; - -typedef struct tagDXT1Block -{ - DXTColBlock color; -} DXT1Block; - -typedef struct tagDXT3Block -{ // also used by dxt2 - DXTAlphaBlockExplicit alpha; - DXTColBlock color; -} DXT3Block; - -typedef struct tagDXT5Block -{ // also used by dxt4 - DXTAlphaBlock3BitLinear alpha; - DXTColBlock color; -} DXT5Block; - -static void GetBlockColors(const DXTColBlock &block, Color8888 colors[4], bool isDXT1) -{ - int i; - for (i = 0; i < 2; i++) { - colors[i].a = 0xff; - colors[i].r = (BYTE)(block.colors[i].r * 0xff / 0x1f); - colors[i].g = (BYTE)(block.colors[i].g * 0xff / 0x3f); - colors[i].b = (BYTE)(block.colors[i].b * 0xff / 0x1f); - } - - WORD *wCol = (WORD *)block.colors; - if (wCol[0] > wCol[1] || !isDXT1) { - // 4 color block - for (i = 0; i < 2; i++) { - colors[i + 2].a = 0xff; - colors[i + 2].r = - (BYTE)((WORD(colors[0].r) * (2 - i) + WORD(colors[1].r) * (1 + i)) / 3); - colors[i + 2].g = - (BYTE)((WORD(colors[0].g) * (2 - i) + WORD(colors[1].g) * (1 + i)) / 3); - colors[i + 2].b = - (BYTE)((WORD(colors[0].b) * (2 - i) + WORD(colors[1].b) * (1 + i)) / 3); - } - } else { - // 3 color block, number 4 is transparent - colors[2].a = 0xff; - colors[2].r = (BYTE)((WORD(colors[0].r) + WORD(colors[1].r)) / 2); - colors[2].g = (BYTE)((WORD(colors[0].g) + WORD(colors[1].g)) / 2); - colors[2].b = (BYTE)((WORD(colors[0].b) + WORD(colors[1].b)) / 2); - - colors[3].a = 0x00; - colors[3].g = 0x00; - colors[3].b = 0x00; - colors[3].r = 0x00; - } -} - -struct DXT_INFO_1 -{ - typedef DXT1Block Block; - enum { isDXT1 = 1, bytesPerBlock = 8 }; -}; - -struct DXT_INFO_3 -{ - typedef DXT3Block Block; - enum { isDXT1 = 1, bytesPerBlock = 16 }; -}; - -struct DXT_INFO_5 -{ - typedef DXT5Block Block; - enum { isDXT1 = 1, bytesPerBlock = 16 }; -}; - -template -class DXT_BLOCKDECODER_BASE -{ -protected: - Color8888 m_colors[4]; - const typename INFO::Block *m_pBlock; - unsigned m_colorRow; - -public: - void Setup(const BYTE *pBlock) - { - m_pBlock = (const typename INFO::Block *)pBlock; - GetBlockColors(m_pBlock->color, m_colors, INFO::isDXT1); - } - - void SetY(int y) { m_colorRow = m_pBlock->color.row[y]; } - - void GetColor(int x, int y, Color8888 &color) - { - Q_UNUSED(y) - unsigned bits = (m_colorRow >> (x * 2)) & 3; - color = m_colors[bits]; - std::swap(color.r, color.b); - } -}; - -class DXT_BLOCKDECODER_1 : public DXT_BLOCKDECODER_BASE -{ -public: - typedef DXT_INFO_1 INFO; -}; - -class DXT_BLOCKDECODER_3 : public DXT_BLOCKDECODER_BASE -{ -public: - typedef DXT_BLOCKDECODER_BASE base; - typedef DXT_INFO_3 INFO; - -protected: - unsigned m_alphaRow; - -public: - void SetY(int y) - { - base::SetY(y); - m_alphaRow = m_pBlock->alpha.row[y]; - } - - void GetColor(int x, int y, Color8888 &color) - { - base::GetColor(x, y, color); - const unsigned bits = (m_alphaRow >> (x * 4)) & 0xF; - color.a = (BYTE)((bits * 0xFF) / 0xF); - } -}; - -class DXT_BLOCKDECODER_5 : public DXT_BLOCKDECODER_BASE -{ -public: - typedef DXT_BLOCKDECODER_BASE base; - typedef DXT_INFO_5 INFO; - -protected: - unsigned m_alphas[8]; - unsigned m_alphaBits; - int m_offset; - -public: - void Setup(const BYTE *pBlock) - { - base::Setup(pBlock); - - const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha; - m_alphas[0] = block.alpha[0]; - m_alphas[1] = block.alpha[1]; - if (m_alphas[0] > m_alphas[1]) { - // 8 alpha block - for (int i = 0; i < 6; i++) { - m_alphas[i + 2] = ((6 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 3) / 7; - } - } else { - // 6 alpha block - for (int i = 0; i < 4; i++) { - m_alphas[i + 2] = ((4 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 2) / 5; - } - m_alphas[6] = 0; - m_alphas[7] = 0xFF; - } - } - - void SetY(int y) - { - base::SetY(y); - int i = y / 2; - const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha; - m_alphaBits = unsigned(block.data[0 + i * 3]) | (unsigned(block.data[1 + i * 3]) << 8) - | (unsigned(block.data[2 + i * 3]) << 16); - m_offset = (y & 1) * 12; - } - - void GetColor(int x, int y, Color8888 &color) - { - base::GetColor(x, y, color); - unsigned bits = (m_alphaBits >> (x * 3 + m_offset)) & 7; - color.a = (BYTE)m_alphas[bits]; - std::swap(color.r, color.b); - } -}; - -template -void DecodeDXTBlock(BYTE *dstData, const BYTE *srcBlock, long dstPitch, int bw, int bh) -{ - DECODER decoder; - decoder.Setup(srcBlock); - for (int y = 0; y < bh; y++) { - // Note that this assumes the pointer is pointing to the *last* valid start - // row. - BYTE *dst = dstData - y * dstPitch; - decoder.SetY(y); - for (int x = 0; x < bw; x++) { - decoder.GetColor(x, y, (Color8888 &)*dst); - dst += 4; - } - } -} - -struct STextureDataWriter -{ - QT3DSU32 m_Width; - QT3DSU32 m_Height; - QT3DSU32 m_Stride; - QT3DSU32 m_NumComponents; - STextureData &m_TextureData; - STextureDataWriter(QT3DSU32 w, QT3DSU32 h, bool hasA, STextureData &inTd, NVAllocatorCallback &alloc) - : m_Width(w) - , m_Height(h) - , m_Stride(hasA ? m_Width * 4 : m_Width * 3) - , m_NumComponents(hasA ? 4 : 3) - , m_TextureData(inTd) - { - QT3DSU32 dataSize = m_Stride * m_Height; - if (dataSize > m_TextureData.dataSizeInBytes) { - alloc.deallocate(m_TextureData.data); - m_TextureData.data = - alloc.allocate(dataSize, "SLoadedTexture::DecompressDXTImage", __FILE__, __LINE__); - m_TextureData.dataSizeInBytes = dataSize; - } - memZero(m_TextureData.data, m_TextureData.dataSizeInBytes); - m_TextureData.format = hasA ? NVRenderTextureFormats::RGBA8 : NVRenderTextureFormats::RGB8; - } - - void WritePixel(QT3DSU32 X, QT3DSU32 Y, QT3DSU8 *pixelData) - { - if (X < m_Width && Y < m_Height) { - char *textureData = reinterpret_cast(m_TextureData.data); - QT3DSU32 offset = Y * m_Stride + X * m_NumComponents; - - for (QT3DSU32 idx = 0; idx < m_NumComponents; ++idx) - QT3DS_ASSERT(textureData[offset + idx] == 0); - - memCopy(textureData + offset, pixelData, m_NumComponents); - } - } - - // Incoming pixels are assumed to be RGBA or RGBX, 32 bit in any case - void WriteBlock(QT3DSU32 X, QT3DSU32 Y, QT3DSU32 width, QT3DSU32 height, QT3DSU8 *pixelData) - { - QT3DSU32 offset = 0; - for (QT3DSU32 yidx = 0; yidx < height; ++yidx) { - for (QT3DSU32 xidx = 0; xidx < width; ++xidx, offset += 4) { - WritePixel(X + xidx, Y + (height - yidx - 1), pixelData + offset); - } - } - } - bool Finished() { return false; } -}; - -struct STextureAlphaScanner -{ - bool &m_Alpha; - - STextureAlphaScanner(bool &inAlpha) - : m_Alpha(inAlpha) - { - } - - void WriteBlock(QT3DSU32 X, QT3DSU32 Y, QT3DSU32 width, QT3DSU32 height, QT3DSU8 *pixelData) - { - Q_UNUSED(X) - Q_UNUSED(Y) - QT3DSU32 offset = 0; - for (QT3DSU32 yidx = 0; yidx < height; ++yidx) { - for (QT3DSU32 xidx = 0; xidx < width; ++xidx, offset += 4) { - if (pixelData[offset + 3] < 255) - m_Alpha = true; - } - } - } - - // If we detect alpha we can stop right there. - bool Finished() { return m_Alpha; } -}; -// Scan the dds image's mipmap 0 level for alpha. -template -static void DecompressDDS(void *inSrc, QT3DSU32 inDataSize, QT3DSU32 inWidth, QT3DSU32 inHeight, - TWriterType ioWriter) -{ - typedef typename DECODER::INFO INFO; - typedef typename INFO::Block Block; - (void)inDataSize; - - const QT3DSU8 *pbSrc = (const QT3DSU8 *)inSrc; - // Each DX block is composed of 16 pixels. Free image decodes those - // pixels into a 4x4 block of data. - QT3DSU8 pbDstData[4 * 4 * 4]; - // The decoder decodes backwards - // So we need to point to the last line. - QT3DSU8 *pbDst = pbDstData + 48; - - int width = (int)inWidth; - int height = (int)inHeight; - int lineStride = 16; - for (int y = 0; y < height && ioWriter.Finished() == false; y += 4) { - int yPixels = NVMin(height - y, 4); - for (int x = 0; x < width && ioWriter.Finished() == false; x += 4) { - int xPixels = NVMin(width - x, 4); - DecodeDXTBlock(pbDst, pbSrc, lineStride, xPixels, yPixels); - pbSrc += INFO::bytesPerBlock; - ioWriter.WriteBlock(x, y, xPixels, yPixels, pbDstData); - } - } -} - -bool ScanDDSForAlpha(Qt3DSDDSImage *dds) -{ - bool hasAlpha = false; - switch (dds->format) { - case qt3ds::render::NVRenderTextureFormats::RGBA_DXT1: - DecompressDDS(dds->data[0], dds->size[0], dds->mipwidth[0], - dds->mipheight[0], STextureAlphaScanner(hasAlpha)); - break; - case qt3ds::render::NVRenderTextureFormats::RGBA_DXT3: - DecompressDDS(dds->data[0], dds->size[0], dds->mipwidth[0], - dds->mipheight[0], STextureAlphaScanner(hasAlpha)); - break; - case qt3ds::render::NVRenderTextureFormats::RGBA_DXT5: - DecompressDDS(dds->data[0], dds->size[0], dds->mipwidth[0], - dds->mipheight[0], STextureAlphaScanner(hasAlpha)); - break; - default: - QT3DS_ASSERT(false); - break; - } - return hasAlpha; -} - -bool ScanImageForAlpha(const void *inData, QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 inPixelSizeInBytes, - QT3DSU8 inAlphaSizeInBits) -{ - const QT3DSU8 *rowPtr = reinterpret_cast(inData); - bool hasAlpha = false; - if (inAlphaSizeInBits == 0) - return hasAlpha; - if (inPixelSizeInBytes != 2 && inPixelSizeInBytes != 4) { - QT3DS_ASSERT(false); - return false; - } - if (inAlphaSizeInBits > 8) { - QT3DS_ASSERT(false); - return false; - } - - QT3DSU32 alphaRightShift = inPixelSizeInBytes * 8 - inAlphaSizeInBits; - QT3DSU32 maxAlphaValue = (1 << inAlphaSizeInBits) - 1; - - for (QT3DSU32 rowIdx = 0; rowIdx < inHeight && hasAlpha == false; ++rowIdx) { - for (QT3DSU32 idx = 0; idx < inWidth && hasAlpha == false; - ++idx, rowPtr += inPixelSizeInBytes) { - QT3DSU32 pixelValue = 0; - if (inPixelSizeInBytes == 2) - pixelValue = *(reinterpret_cast(rowPtr)); - else - pixelValue = *(reinterpret_cast(rowPtr)); - pixelValue = pixelValue >> alphaRightShift; - if (pixelValue < maxAlphaValue) - hasAlpha = true; - } - } - return hasAlpha; -} -} - -SLoadedTexture::~SLoadedTexture() -{ - if (dds) { - if (dds->dataBlock) - QT3DS_FREE(m_Allocator, dds->dataBlock); - - QT3DS_FREE(m_Allocator, dds); - } else if (data && image.byteCount() <= 0) { - m_Allocator.deallocate(data); - } - if (m_Palette) - m_Allocator.deallocate(m_Palette); - if (m_TransparencyTable) - m_Allocator.deallocate(m_TransparencyTable); -} - -void SLoadedTexture::release() -{ - NVAllocatorCallback *theAllocator(&m_Allocator); - this->~SLoadedTexture(); - theAllocator->deallocate(this); -} - -bool SLoadedTexture::ScanForTransparency() -{ - switch (format) { - case NVRenderTextureFormats::SRGB8A8: - case NVRenderTextureFormats::RGBA8: - if (!data) { // dds - return true; - } else { - return ScanImageForAlpha(data, width, height, 4, 8); - } - break; - // Scan the image. - case NVRenderTextureFormats::SRGB8: - case NVRenderTextureFormats::RGB8: - return false; - break; - case NVRenderTextureFormats::RGB565: - return false; - break; - case NVRenderTextureFormats::RGBA5551: - if (!data) { // dds - return true; - } else { - return ScanImageForAlpha(data, width, height, 2, 1); - } - break; - case NVRenderTextureFormats::Alpha8: - return true; - break; - case NVRenderTextureFormats::Luminance8: - return false; - break; - case NVRenderTextureFormats::LuminanceAlpha8: - if (!data) { // dds - return true; - } else { - return ScanImageForAlpha(data, width, height, 2, 8); - } - break; - case NVRenderTextureFormats::RGB_DXT1: - return false; - break; - case NVRenderTextureFormats::RGBA_DXT3: - case NVRenderTextureFormats::RGBA_DXT1: - case NVRenderTextureFormats::RGBA_DXT5: - if (dds) { - return ScanDDSForAlpha(dds); - } else { - QT3DS_ASSERT(false); - return false; - } - break; - case NVRenderTextureFormats::RGB9E5: - return false; - break; - case NVRenderTextureFormats::RG32F: - case NVRenderTextureFormats::RGB32F: - case NVRenderTextureFormats::RGBA16F: - case NVRenderTextureFormats::RGBA32F: - // PKC TODO : For now, since IBL will be the main consumer, we'll just pretend there's no - // alpha. - // Need to do a proper scan down the line, but doing it for floats is a little different - // from - // integer scans. - return false; - break; - default: - break; - } - QT3DS_ASSERT(false); - return false; -} - -void SLoadedTexture::EnsureMultiplerOfFour(NVFoundationBase &inFoundation, const char *inPath) -{ - if (width % 4 || height % 4) { - qCWarning(PERF_WARNING, - "Image %s has non multiple of four width or height; perf hit for scaling", inPath); - if (data) { - QT3DSU32 newWidth = ITextRenderer::NextMultipleOf4(width); - QT3DSU32 newHeight = ITextRenderer::NextMultipleOf4(height); - QT3DSU32 newDataSize = newWidth * newHeight * components; - NVAllocatorCallback &theAllocator(inFoundation.getAllocator()); - QT3DSU8 *newData = (QT3DSU8 *)(theAllocator.allocate(newDataSize, "Scaled Image Data", - __FILE__, __LINE__)); - CImageScaler theScaler(theAllocator); - if (components == 4) { - theScaler.FastExpandRowsAndColumns((unsigned char *)data, width, height, newData, - newWidth, newHeight); - } else - theScaler.ExpandRowsAndColumns((unsigned char *)data, width, height, newData, - newWidth, newHeight, components); - - theAllocator.deallocate(data); - data = newData; - width = newWidth; - height = newHeight; - dataSizeInBytes = newDataSize; - } - } -} - -STextureData SLoadedTexture::DecompressDXTImage(int inMipMapIdx, STextureData *inOptLastImage) -{ - STextureData retval; - if (inOptLastImage) - retval = *inOptLastImage; - - if (dds == NULL || inMipMapIdx >= dds->numMipmaps) { - QT3DS_ASSERT(false); - ReleaseDecompressedTexture(retval); - return STextureData(); - } - char *srcData = (char *)dds->data[inMipMapIdx]; - int srcDataSize = dds->size[inMipMapIdx]; - QT3DSU32 imgWidth = (QT3DSU32)dds->mipwidth[inMipMapIdx]; - QT3DSU32 imgHeight = (QT3DSU32)dds->mipheight[inMipMapIdx]; - - switch (format) { - case NVRenderTextureFormats::RGB_DXT1: - DecompressDDS( - srcData, srcDataSize, imgWidth, imgHeight, - STextureDataWriter(imgWidth, imgHeight, false, retval, m_Allocator)); - break; - case NVRenderTextureFormats::RGBA_DXT1: - DecompressDDS( - srcData, srcDataSize, imgWidth, imgHeight, - STextureDataWriter(imgWidth, imgHeight, true, retval, m_Allocator)); - break; - case NVRenderTextureFormats::RGBA_DXT3: - DecompressDDS( - srcData, srcDataSize, imgWidth, imgHeight, - STextureDataWriter(imgWidth, imgHeight, true, retval, m_Allocator)); - break; - case NVRenderTextureFormats::RGBA_DXT5: - DecompressDDS( - srcData, srcDataSize, imgWidth, imgHeight, - STextureDataWriter(imgWidth, imgHeight, true, retval, m_Allocator)); - break; - default: - QT3DS_ASSERT(false); - break; - } - return retval; -} - -void SLoadedTexture::ReleaseDecompressedTexture(STextureData inImage) -{ - if (inImage.data) - m_Allocator.deallocate(inImage.data); -} - -#ifndef EA_PLATFORM_WINDOWS -#define stricmp strcasecmp -#endif - -SLoadedTexture *SLoadedTexture::Load(const QString &inPath, NVFoundationBase &inFoundation, - IInputStreamFactory &inFactory, bool inFlipY, - NVRenderContextType renderContextType, bool preferKTX) -{ - if (inPath.isEmpty()) - return nullptr; - - // Check KTX path first - QString path = inPath; - QString ktxSource = inPath; - if (preferKTX) { - ktxSource = ktxSource.left(ktxSource.lastIndexOf(QLatin1Char('.'))); - ktxSource.append(QLatin1String(".ktx")); - } - - SLoadedTexture *theLoadedImage = nullptr; - // We will get invalid error logs of files not found if we don't force quiet mode - // If the file is actually missing, it will be logged later (loaded image is null) - NVScopedRefCounted theStream( - inFactory.GetStreamForFile(preferKTX ? ktxSource : inPath, true)); - if (!theStream.mPtr) { - if (!preferKTX) - theStream = inFactory.GetStreamForFile(inPath, true); - else - return nullptr; - } else { - path = ktxSource; - } - QString fileName; - inFactory.GetPathForFile(path, fileName, true); - if (theStream.mPtr && path.size() > 3) { - if (path.endsWith(QLatin1String("png"), Qt::CaseInsensitive) - || path.endsWith(QLatin1String("jpg"), Qt::CaseInsensitive) - || path.endsWith(QLatin1String("peg"), Qt::CaseInsensitive)) { - theLoadedImage = LoadQImage(fileName, inFlipY, inFoundation, renderContextType); - } else if (path.endsWith(QLatin1String("dds"), Qt::CaseInsensitive)) { - theLoadedImage = LoadDDS(*theStream, inFlipY, inFoundation, renderContextType); - } else if (path.endsWith(QLatin1String("gif"), Qt::CaseInsensitive)) { - theLoadedImage = LoadGIF(*theStream, !inFlipY, inFoundation, renderContextType); - } else if (path.endsWith(QLatin1String("bmp"), Qt::CaseInsensitive)) { - theLoadedImage = LoadBMP(*theStream, !inFlipY, inFoundation, renderContextType); - } else if (path.endsWith(QLatin1String("hdr"), Qt::CaseInsensitive)) { - theLoadedImage = LoadHDR(*theStream, inFoundation, renderContextType); - } else if (path.endsWith(QLatin1String("ktx"), Qt::CaseInsensitive)) { - theLoadedImage = LoadKTX(*theStream, inFlipY, inFoundation, renderContextType); - } else { - qCWarning(INTERNAL_ERROR, "Unrecognized image extension: %s", qPrintable(inPath)); - } - } - - return theLoadedImage; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h deleted file mode 100644 index f0194000..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_LOADED_TEXTURE_H -#define QT3DS_RENDER_LOADED_TEXTURE_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSSimpleTypes.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "Qt3DSRenderLoadedTextureDDS.h" -#include "foundation/Qt3DSRefCounted.h" -#include - -namespace qt3ds { -namespace foundation { - class ISeekableIOStream; - class IInStream; -} -} - -namespace qt3ds { -namespace render { - - class IInputStreamFactory; - - struct STextureData - { - void *data; - QT3DSU32 dataSizeInBytes; - qt3ds::render::NVRenderTextureFormats::Enum format; - STextureData() - : data(NULL) - , dataSizeInBytes(0) - , format(qt3ds::render::NVRenderTextureFormats::Unknown) - { - } - }; - struct ExtendedTextureFormats - { - enum Enum { - NoExtendedFormat = 0, - Palettized, - CustomRGB, - }; - }; - // Utility class used for loading image data from disk. - // Supports jpg, png, and dds. - struct SLoadedTexture : public NVReleasable - { - private: - ~SLoadedTexture(); - - public: - NVAllocatorCallback &m_Allocator; - QT3DSI32 width; - QT3DSI32 height; - QT3DSI32 components; - void *data; - QImage image; - QT3DSU32 dataSizeInBytes; - qt3ds::render::NVRenderTextureFormats::Enum format; - Qt3DSDDSImage *dds; - ExtendedTextureFormats::Enum m_ExtendedFormat; - // Used for palettized images. - void *m_Palette; - QT3DSI32 m_CustomMasks[3]; - int m_BitCount; - char8_t m_BackgroundColor[3]; - uint8_t *m_TransparencyTable; - int32_t m_TransparentPaletteIndex; - - SLoadedTexture(NVAllocatorCallback &inAllocator) - : m_Allocator(inAllocator) - , width(0) - , height(0) - , components(0) - , data(NULL) - , image(0) - , dataSizeInBytes(0) - , format(qt3ds::render::NVRenderTextureFormats::RGBA8) - , dds(NULL) - , m_ExtendedFormat(ExtendedTextureFormats::NoExtendedFormat) - , m_Palette(NULL) - , m_BitCount(0) - , m_TransparencyTable(NULL) - , m_TransparentPaletteIndex(-1) - { - m_CustomMasks[0] = 0; - m_CustomMasks[1] = 0; - m_CustomMasks[2] = 0; - m_BackgroundColor[0] = 0; - m_BackgroundColor[1] = 0; - m_BackgroundColor[2] = 0; - } - void setFormatFromComponents() - { - switch (components) { - case 1: // undefined, but in this context probably luminance - format = qt3ds::render::NVRenderTextureFormats::Luminance8; - break; - case 2: - format = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; - break; - case 3: - format = qt3ds::render::NVRenderTextureFormats::RGB8; - break; - - default: - // fallthrough intentional - case 4: - format = qt3ds::render::NVRenderTextureFormats::RGBA8; - break; - } - } - - void EnsureMultiplerOfFour(NVFoundationBase &inFoundation, const char *inPath); - // Returns true if this image has a pixel less than 255. - bool ScanForTransparency(); - - // Be sure to call this or risk leaking an enormous amount of memory - void release() override; - - // Not all video cards support dxt compression. Giving the last image allows - // this object to potentially reuse the memory - STextureData DecompressDXTImage(int inMipMapIdx, STextureData *inOptLastImage = NULL); - void ReleaseDecompressedTexture(STextureData inImage); - - static SLoadedTexture *Load(const QString &inPath, NVFoundationBase &inAllocator, - IInputStreamFactory &inFactory, bool inFlipY = true, - NVRenderContextType renderContextType - = NVRenderContextValues::NullContext, bool preferKTX = false); - static SLoadedTexture *LoadDDS(IInStream &inStream, QT3DSI32 flipVertical, - NVFoundationBase &fnd, - NVRenderContextType renderContextType); - static SLoadedTexture *LoadKTX(IInStream &inStream, QT3DSI32 flipVertical, - NVFoundationBase &fnd, - NVRenderContextType renderContextType); - static SLoadedTexture *LoadBMP(ISeekableIOStream &inStream, bool inFlipY, - NVFoundationBase &inFnd, - NVRenderContextType renderContextType); - static SLoadedTexture *LoadGIF(ISeekableIOStream &inStream, bool inFlipY, - NVFoundationBase &inFnd, - NVRenderContextType renderContextType); - static SLoadedTexture *LoadHDR(ISeekableIOStream &inStream, NVFoundationBase &inFnd, - NVRenderContextType renderContextType); - - static SLoadedTexture *LoadQImage(const QString &inPath, QT3DSI32 flipVertical, - NVFoundationBase &fnd, - NVRenderContextType renderContextType); - - private: - // Implemented in the bmp loader. - void FreeImagePostProcess(bool inFlipY); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureBMP.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureBMP.cpp deleted file mode 100644 index 29e75a89..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureBMP.cpp +++ /dev/null @@ -1,1262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// ========================================================== -// BMP Loader and Writer -// -// Design and implementation by -// - Floris van den Berg (flvdberg@wxs.nl) -// - Markus Loibl (markus.loibl@epost.de) -// - Martin Weber (martweb@gmx.net) -// - Herve Drolon (drolon@infonie.fr) -// - Michal Novotny (michal@etc.cz) -// -// This file is part of FreeImage 3 -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== - -#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" - -// ---------------------------------------------------------- -// Constants + headers -// ---------------------------------------------------------- - -static const BYTE RLE_COMMAND = 0; -static const BYTE RLE_ENDOFLINE = 0; -static const BYTE RLE_ENDOFBITMAP = 1; -static const BYTE RLE_DELTA = 2; - -static const BYTE BI_RGB = 0; -static const BYTE BI_RLE8 = 1; -static const BYTE BI_RLE4 = 2; -static const BYTE BI_BITFIELDS = 3; - -// ---------------------------------------------------------- - -#ifdef _WIN32 -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif - -typedef struct tagBITMAPCOREHEADER -{ - DWORD bcSize; - WORD bcWidth; - WORD bcHeight; - WORD bcPlanes; - WORD bcBitCnt; -} BITMAPCOREHEADER, *PBITMAPCOREHEADER; - -typedef struct tagBITMAPINFOOS2_1X_HEADER -{ - DWORD biSize; - WORD biWidth; - WORD biHeight; - WORD biPlanes; - WORD biBitCount; -} BITMAPINFOOS2_1X_HEADER, *PBITMAPINFOOS2_1X_HEADER; - -typedef struct tagBITMAPFILEHEADER -{ - WORD bfType; - DWORD bfSize; - WORD bfReserved1; - WORD bfReserved2; - DWORD bfOffBits; -} BITMAPFILEHEADER, *PBITMAPFILEHEADER; - - -#ifdef _WIN32 -#pragma pack(pop) -#else -#pragma pack() -#endif - -// ========================================================== -// Plugin Interface -// ========================================================== - -static int s_format_id; - -// ========================================================== -// Internal functions -// ========================================================== - -#ifdef FREEIMAGE_BIGENDIAN -static void SwapInfoHeader(BITMAPINFOHEADER *header) -{ - SwapLong(&header->biSize); - SwapLong((DWORD *)&header->biWidth); - SwapLong((DWORD *)&header->biHeight); - SwapShort(&header->biPlanes); - SwapShort(&header->biBitCount); - SwapLong(&header->biCompression); - SwapLong(&header->biSizeImage); - SwapLong((DWORD *)&header->biXPelsPerMeter); - SwapLong((DWORD *)&header->biYPelsPerMeter); - SwapLong(&header->biClrUsed); - SwapLong(&header->biClrImportant); -} - -static void SwapCoreHeader(BITMAPCOREHEADER *header) -{ - SwapLong(&header->bcSize); - SwapShort(&header->bcWidth); - SwapShort(&header->bcHeight); - SwapShort(&header->bcPlanes); - SwapShort(&header->bcBitCnt); -} - -static void SwapOS21XHeader(BITMAPINFOOS2_1X_HEADER *header) -{ - SwapLong(&header->biSize); - SwapShort(&header->biWidth); - SwapShort(&header->biHeight); - SwapShort(&header->biPlanes); - SwapShort(&header->biBitCount); -} - -static void SwapFileHeader(BITMAPFILEHEADER *header) -{ - SwapShort(&header->bfType); - SwapLong(&header->bfSize); - SwapShort(&header->bfReserved1); - SwapShort(&header->bfReserved2); - SwapLong(&header->bfOffBits); -} -#endif - -// -------------------------------------------------------------------------- - -/** -Load uncompressed image pixels for 1-, 4-, 8-, 16-, 24- and 32-bit dib -@param io FreeImage IO -@param handle FreeImage IO handle -@param dib Image to be loaded -@param height Image height -@param pitch Image pitch -@param bit_count Image bit-depth (1-, 4-, 8-, 16-, 24- or 32-bit) -*/ -static void LoadPixelData(FreeImageIO *io, fi_handle handle, FIBITMAP *dib, int height, int pitch, - int bit_count) -{ - (void)bit_count; - // Load pixel data - // NB: height can be < 0 for BMP data - if (height > 0) { - io->read_proc((void *)FreeImage_GetBits(dib), height * pitch, 1, handle); - } else { - int positiveHeight = abs(height); - for (int c = 0; c < positiveHeight; ++c) { - io->read_proc((void *)FreeImage_GetScanLine(dib, positiveHeight - c - 1), pitch, 1, - handle); - } - } - -// swap as needed -#ifdef FREEIMAGE_BIGENDIAN - if (bit_count == 16) { - for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) { - WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++) { - SwapShort(pixel); - pixel++; - } - } - } -#endif - -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - if (bit_count == 24 || bit_count == 32) { - for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) { - BYTE *pixel = FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++) { - INPLACESWAP(pixel[0], pixel[2]); - pixel += (bit_count >> 3); - } - } - } -#endif -} - -/** -Load image pixels for 4-bit RLE compressed dib -@param io FreeImage IO -@param handle FreeImage IO handle -@param width Image width -@param height Image height -@param dib Image to be loaded -@return Returns TRUE if successful, returns FALSE otherwise -*/ -static BOOL LoadPixelDataRLE4(FreeImageIO *io, fi_handle handle, int width, int height, - FIBITMAP *dib) -{ - int status_byte = 0; - BYTE second_byte = 0; - int bits = 0; - - BYTE *pixels = NULL; // temporary 8-bit buffer - - try { - height = abs(height); - - pixels = (BYTE *)malloc(width * height * sizeof(BYTE)); - if (!pixels) - throw(1); - memset(pixels, 0, width * height * sizeof(BYTE)); - - BYTE *q = pixels; - BYTE *end = pixels + height * width; - - for (int scanline = 0; scanline < height;) { - if (q < pixels || q >= end) { - break; - } - if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - if (status_byte != 0) { - status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q)); - // Encoded mode - if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - for (int i = 0; i < status_byte; i++) { - *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); - } - bits += status_byte; - } else { - // Escape mode - if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - switch (status_byte) { - case RLE_ENDOFLINE: { - // End of line - bits = 0; - scanline++; - q = pixels + scanline * width; - } break; - - case RLE_ENDOFBITMAP: - // End of bitmap - q = end; - break; - - case RLE_DELTA: { - // read the delta values - - BYTE delta_x = 0; - BYTE delta_y = 0; - - if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - - // apply them - - bits += delta_x; - scanline += delta_y; - q = pixels + scanline * width + bits; - } break; - - default: { - // Absolute mode - status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q)); - for (int i = 0; i < status_byte; i++) { - if ((i & 0x01) == 0) { - if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - } - *q++ = - (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); - } - bits += status_byte; - // Read pad byte - if (((status_byte & 0x03) == 1) || ((status_byte & 0x03) == 2)) { - BYTE padding = 0; - if (io->read_proc(&padding, sizeof(BYTE), 1, handle) != 1) { - throw(1); - } - } - } break; - } - } - } - - { - // Convert to 4-bit - for (int y = 0; y < height; y++) { - const BYTE *src = (BYTE *)pixels + y * width; - BYTE *dst = FreeImage_GetScanLine(dib, y); - - BOOL hinibble = TRUE; - - for (int cols = 0; cols < width; cols++) { - if (hinibble) { - dst[cols >> 1] = (src[cols] << 4); - } else { - dst[cols >> 1] |= src[cols]; - } - - hinibble = !hinibble; - } - } - } - - free(pixels); - - return TRUE; - - } catch (int) { - if (pixels) - free(pixels); - return FALSE; - } -} - -/** -Load image pixels for 8-bit RLE compressed dib -@param io FreeImage IO -@param handle FreeImage IO handle -@param width Image width -@param height Image height -@param dib Image to be loaded -@return Returns TRUE if successful, returns FALSE otherwise -*/ -static BOOL LoadPixelDataRLE8(FreeImageIO *io, fi_handle handle, int width, int height, - FIBITMAP *dib) -{ - BYTE status_byte = 0; - BYTE second_byte = 0; - int scanline = 0; - int bits = 0; - - for (;;) { - if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - - switch (status_byte) { - case RLE_COMMAND: - if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - - switch (status_byte) { - case RLE_ENDOFLINE: - bits = 0; - scanline++; - break; - - case RLE_ENDOFBITMAP: - return TRUE; - - case RLE_DELTA: { - // read the delta values - - BYTE delta_x = 0; - BYTE delta_y = 0; - - if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - - // apply them - - bits += delta_x; - scanline += delta_y; - - break; - } - - default: { - if (scanline >= abs(height)) { - return TRUE; - } - - int count = MIN((int)status_byte, width - bits); - - BYTE *sline = FreeImage_GetScanLine(dib, scanline); - - if (io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) { - return FALSE; - } - - // align run length to even number of bytes - - if ((status_byte & 1) == 1) { - if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - } - - bits += status_byte; - - break; - } - } - - break; - - default: { - if (scanline >= abs(height)) { - return TRUE; - } - - int count = MIN((int)status_byte, width - bits); - - BYTE *sline = FreeImage_GetScanLine(dib, scanline); - - if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - - for (int i = 0; i < count; i++) { - *(sline + bits) = second_byte; - - bits++; - } - - break; - } - } - } -} - -// -------------------------------------------------------------------------- - -static FIBITMAP *LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, - unsigned bitmap_bits_offset) -{ - FIBITMAP *dib = NULL; - (void)flags; - try { - // load the info header - - BITMAPINFOHEADER bih; - - io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapInfoHeader(&bih); -#endif - - // keep some general information about the bitmap - - int used_colors = bih.biClrUsed; - int width = bih.biWidth; - int height = bih.biHeight; // WARNING: height can be < 0 => check each call using 'height' - // as a parameter - int alloc_height = abs(height); - int bit_count = bih.biBitCount; - int compression = bih.biCompression; - int pitch = CalculatePitch(CalculateLine(width, bit_count)); - - switch (bit_count) { - case 1: - case 4: - case 8: { - if ((used_colors <= 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) - used_colors = CalculateUsedPaletteEntries(bit_count); - - // allocate enough memory to hold the bitmap (header, palette, pixels) and read the - // palette - - dib = FreeImage_Allocate(width, alloc_height, bit_count, io); - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information - FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); - FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); - - // load the palette - - io->read_proc(FreeImage_GetPalette(dib), used_colors * sizeof(RGBQUAD), 1, handle); -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - RGBQUAD *pal = FreeImage_GetPalette(dib); - for (int i = 0; i < used_colors; i++) { - INPLACESWAP(pal[i].rgbRed, pal[i].rgbBlue); - } -#endif - - // seek to the actual pixel data. - // this is needed because sometimes the palette is larger than the entries it contains - // predicts - - if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) - + (used_colors * sizeof(RGBQUAD)))) - io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); - - // read the pixel data - - switch (compression) { - case BI_RGB: - LoadPixelData(io, handle, dib, height, pitch, bit_count); - return dib; - - case BI_RLE4: - if (LoadPixelDataRLE4(io, handle, width, height, dib)) { - return dib; - } else { - throw "Error encountered while decoding RLE4 BMP data"; - } - break; - - case BI_RLE8: - if (LoadPixelDataRLE8(io, handle, width, height, dib)) { - return dib; - } else { - throw "Error encountered while decoding RLE8 BMP data"; - } - break; - - default: - throw "compression type not supported"; - } - } break; // 1-, 4-, 8-bit - - case 16: { - if (bih.biCompression == BI_BITFIELDS) { - DWORD bitfields[3]; - - io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle); - - dib = FreeImage_Allocate(width, alloc_height, bit_count, bitfields[0], bitfields[1], - bitfields[2], io); - } else { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI16_555_RED_MASK, - FI16_555_GREEN_MASK, FI16_555_BLUE_MASK, io); - } - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information - FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); - FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); - - // load pixel data and swap as needed if OS is Big Endian - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - return dib; - } break; // 16-bit - - case 24: - case 32: { - if (bih.biCompression == BI_BITFIELDS) { - DWORD bitfields[3]; - - io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle); - - dib = FreeImage_Allocate(width, alloc_height, bit_count, bitfields[0], bitfields[1], - bitfields[2], io); - } else { - if (bit_count == 32) { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, - FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); - } else { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, - FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); - } - } - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information - FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); - FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); - - // Skip over the optional palette - // A 24 or 32 bit DIB may contain a palette for faster color reduction - - if (used_colors > 0) { - io->seek_proc(handle, used_colors * sizeof(RGBQUAD), SEEK_CUR); - } else if ((bih.biCompression != BI_BITFIELDS) - && (bitmap_bits_offset - > sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))) { - io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); - } - - // read in the bitmap bits - // load pixel data and swap as needed if OS is Big Endian - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - // check if the bitmap contains transparency, if so enable it in the header - - return dib; - } break; // 24-, 32-bit - } - } catch (const char *message) { - if (dib) { - FreeImage_Unload(dib); - } - if (message) { - FreeImage_OutputMessageProc(s_format_id, message, io); - } - } - - return NULL; -} - -// -------------------------------------------------------------------------- - -static FIBITMAP *LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, - unsigned bitmap_bits_offset) -{ - FIBITMAP *dib = NULL; - (void)flags; - try { - // load the info header - - BITMAPINFOHEADER bih; - - io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapInfoHeader(&bih); -#endif - - // keep some general information about the bitmap - - int used_colors = bih.biClrUsed; - int width = bih.biWidth; - int height = bih.biHeight; // WARNING: height can be < 0 => check each read_proc using - // 'height' as a parameter - int alloc_height = abs(height); - int bit_count = bih.biBitCount; - int compression = bih.biCompression; - int pitch = CalculatePitch(CalculateLine(width, bit_count)); - - switch (bit_count) { - case 1: - case 4: - case 8: { - if ((used_colors <= 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) - used_colors = CalculateUsedPaletteEntries(bit_count); - - // allocate enough memory to hold the bitmap (header, palette, pixels) and read the - // palette - - dib = FreeImage_Allocate(width, alloc_height, bit_count, io); - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information - FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); - FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); - - // load the palette - - io->seek_proc(handle, sizeof(BITMAPFILEHEADER) + bih.biSize, SEEK_SET); - - RGBQUAD *pal = FreeImage_GetPalette(dib); - - for (int count = 0; count < used_colors; count++) { - FILE_BGR bgr; - - io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle); - - pal[count].rgbRed = bgr.r; - pal[count].rgbGreen = bgr.g; - pal[count].rgbBlue = bgr.b; - } - - // seek to the actual pixel data. - // this is needed because sometimes the palette is larger than the entries it contains - // predicts - - if (bitmap_bits_offset - > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) - io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); - - // read the pixel data - - switch (compression) { - case BI_RGB: - // load pixel data - LoadPixelData(io, handle, dib, height, pitch, bit_count); - return dib; - - case BI_RLE4: - if (LoadPixelDataRLE4(io, handle, width, height, dib)) { - return dib; - } else { - throw "Error encountered while decoding RLE4 BMP data"; - } - break; - - case BI_RLE8: - if (LoadPixelDataRLE8(io, handle, width, height, dib)) { - return dib; - } else { - throw "Error encountered while decoding RLE8 BMP data"; - } - break; - - default: - throw "compression type not supported"; - } - } - - case 16: { - if (bih.biCompression == 3) { - DWORD bitfields[3]; - - io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle); - - dib = FreeImage_Allocate(width, alloc_height, bit_count, bitfields[0], bitfields[1], - bitfields[2], io); - } else { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI16_555_RED_MASK, - FI16_555_GREEN_MASK, FI16_555_BLUE_MASK, io); - } - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information - FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); - FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); - - if (bitmap_bits_offset - > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) { - io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); - } - - // load pixel data and swap as needed if OS is Big Endian - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - return dib; - } - - case 24: - case 32: { - if (bit_count == 32) { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, - FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); - } else { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, - FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); - } - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information - FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); - FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); - - // Skip over the optional palette - // A 24 or 32 bit DIB may contain a palette for faster color reduction - - if (bitmap_bits_offset - > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) - io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); - - // read in the bitmap bits - // load pixel data and swap as needed if OS is Big Endian - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - return dib; - } - } - } catch (const char *message) { - if (dib) - FreeImage_Unload(dib); - - FreeImage_OutputMessageProc(s_format_id, message, io); - } - - return NULL; -} - -// -------------------------------------------------------------------------- - -static FIBITMAP *LoadOS21XBMP(FreeImageIO *io, fi_handle handle, int flags, - unsigned bitmap_bits_offset) -{ - FIBITMAP *dib = NULL; - (void)flags; - try { - BITMAPINFOOS2_1X_HEADER bios2_1x; - - io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapOS21XHeader(&bios2_1x); -#endif - // keep some general information about the bitmap - - int used_colors = 0; - int width = bios2_1x.biWidth; - int height = bios2_1x.biHeight; // WARNING: height can be < 0 => check each read_proc using - // 'height' as a parameter - int alloc_height = abs(height); - int bit_count = bios2_1x.biBitCount; - int pitch = CalculatePitch(CalculateLine(width, bit_count)); - - switch (bit_count) { - case 1: - case 4: - case 8: { - used_colors = CalculateUsedPaletteEntries(bit_count); - - // allocate enough memory to hold the bitmap (header, palette, pixels) and read the - // palette - - dib = FreeImage_Allocate(width, alloc_height, bit_count, io); - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information to default values (72 dpi in english units) - FreeImage_SetDotsPerMeterX(dib, 2835); - FreeImage_SetDotsPerMeterY(dib, 2835); - - // load the palette - - RGBQUAD *pal = FreeImage_GetPalette(dib); - - for (int count = 0; count < used_colors; count++) { - FILE_BGR bgr; - - io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle); - - pal[count].rgbRed = bgr.r; - pal[count].rgbGreen = bgr.g; - pal[count].rgbBlue = bgr.b; - } - - // Skip over the optional palette - // A 24 or 32 bit DIB may contain a palette for faster color reduction - - io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); - - // read the pixel data - - // load pixel data - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - return dib; - } - - case 16: { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI16_555_RED_MASK, - FI16_555_GREEN_MASK, FI16_555_BLUE_MASK, io); - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information to default values (72 dpi in english units) - FreeImage_SetDotsPerMeterX(dib, 2835); - FreeImage_SetDotsPerMeterY(dib, 2835); - - // load pixel data and swap as needed if OS is Big Endian - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - return dib; - } - - case 24: - case 32: { - if (bit_count == 32) { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, - FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); - } else { - dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, - FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); - } - - if (dib == NULL) - throw "DIB allocation failed"; - - // set resolution information to default values (72 dpi in english units) - FreeImage_SetDotsPerMeterX(dib, 2835); - FreeImage_SetDotsPerMeterY(dib, 2835); - - // Skip over the optional palette - // A 24 or 32 bit DIB may contain a palette for faster color reduction - - // load pixel data and swap as needed if OS is Big Endian - LoadPixelData(io, handle, dib, height, pitch, bit_count); - - // check if the bitmap contains transparency, if so enable it in the header - - return dib; - } - } - } catch (const char *message) { - if (dib) - FreeImage_Unload(dib); - - FreeImage_OutputMessageProc(s_format_id, message, io); - } - - return NULL; -} - -// ========================================================== -// Plugin Implementation -// ========================================================== - -// ---------------------------------------------------------- - -static FIBITMAP *DoLoadBMP(FreeImageIO *io, fi_handle handle, int flags) -{ - if (handle != NULL) { - BITMAPFILEHEADER bitmapfileheader; - DWORD type = 0; - BYTE magic[2]; - - // we use this offset value to make seemingly absolute seeks relative in the file - - long offset_in_file = io->tell_proc(handle); - - // read the magic - - io->read_proc(&magic, sizeof(magic), 1, handle); - - // compare the magic with the number we know - - // somebody put a comment here explaining the purpose of this loop - while (memcmp(&magic, "BA", 2) == 0) { - io->read_proc(&bitmapfileheader.bfSize, sizeof(DWORD), 1, handle); - io->read_proc(&bitmapfileheader.bfReserved1, sizeof(WORD), 1, handle); - io->read_proc(&bitmapfileheader.bfReserved2, sizeof(WORD), 1, handle); - io->read_proc(&bitmapfileheader.bfOffBits, sizeof(DWORD), 1, handle); - io->read_proc(&magic, sizeof(magic), 1, handle); - } - - // read the fileheader - - io->seek_proc(handle, (0 - (int)sizeof(magic)), SEEK_CUR); - io->read_proc(&bitmapfileheader, (int)sizeof(BITMAPFILEHEADER), 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapFileHeader(&bitmapfileheader); -#endif - - // read the first byte of the infoheader - - io->read_proc(&type, sizeof(DWORD), 1, handle); - io->seek_proc(handle, 0 - (int)sizeof(DWORD), SEEK_CUR); -#ifdef FREEIMAGE_BIGENDIAN - SwapLong(&type); -#endif - - // call the appropriate load function for the found bitmap type - - if (type == 40) - return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits); - - if (type == 12) - return LoadOS21XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits); - - if (type <= 64) - return LoadOS22XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits); - - char buf[256]; - sprintf(buf, "unknown bmp subtype with id %d", type); - FreeImage_OutputMessageProc(s_format_id, buf, io); - } - - return NULL; -} - -template -struct SPaletteIndexer -{ - static inline uint32_t IndexOf(const uint8_t *inData, uint32_t inPos) - { - uint32_t divisor = 8 / TBitWidth; - uint32_t byte = inPos / divisor; - uint32_t modulus = inPos % divisor; - uint32_t shift = TBitWidth * modulus; - uint32_t mask = (1 << TBitWidth) - 1; - mask = mask << shift; - uint32_t byteData = inData[byte]; - return (byteData & mask) >> shift; - } -}; - -template <> -struct SPaletteIndexer<1> -{ - static inline uint32_t IndexOf(const uint8_t *inData, uint32_t inPos) - { - uint32_t byte = (inPos / 8); - uint32_t bit = 1 << (7 - (inPos % 8)); - uint32_t byteData = inData[byte]; - return (byteData & bit) ? 1 : 0; - } -}; - -template <> -struct SPaletteIndexer<8> -{ - static inline uint32_t IndexOf(const uint8_t *inData, uint32_t inPos) - { - uint32_t byte = inPos; - uint32_t bit = 0xFF; - uint32_t byteData = inData[byte]; - return byteData & bit; - } -}; - -static inline void assignQuad(uint8_t *dest, const RGBQUAD &quad) -{ - dest[0] = quad.rgbRed; - dest[1] = quad.rgbGreen; - dest[2] = quad.rgbBlue; -} - -template -inline void LoadPalettized(bool inFlipY, const RGBQUAD *palette, void *data, uint8_t *newData, - int width, int height, int components, int transparentIndex) -{ - const uint8_t *oldData = (const uint8_t *)data; - int pitch = CalculatePitch(CalculateLine(width, bitCount)); - for (uint32_t h = 0; h < (uint32_t)height; ++h) { - uint32_t relHeight = h; - if (inFlipY) - relHeight = ((uint32_t)height) - h - 1; - for (uint32_t w = 0; w < (uint32_t)width; ++w) { - const uint8_t *dataLine = oldData + pitch * h; - uint32_t pos = width * relHeight + w; - uint32_t paletteIndex = SPaletteIndexer::IndexOf(dataLine, w); - const RGBQUAD &theQuad = palette[paletteIndex]; - uint8_t *writePtr = newData + (pos * components); - assignQuad(writePtr, theQuad); - if (paletteIndex == (uint32_t)transparentIndex && components == 4) { - writePtr[3] = 0; - } - } - } -} - -inline int firstHighBit(int data) -{ - if (data == 0) - return 0; - int idx = 0; - while ((data % 2) == 0) { - data = data >> 1; - ++idx; - } - return idx; -} - -struct SMaskData -{ - uint32_t mask; - uint32_t shift; - uint32_t max; - - SMaskData(int inMask) - { - mask = inMask; - shift = firstHighBit(mask); - max = mask >> shift; - } - - inline uint8_t MapColor(uint32_t color) const - { - uint32_t intermediateValue = (color & mask) >> shift; - return (uint8_t)((intermediateValue * 255) / max); - } -}; - -template -struct ColorAccess -{ -}; - -template <> -struct ColorAccess<16> -{ - static uint32_t GetPixelWidth() { return 2; } - static uint32_t GetColor(const char8_t *src) - { - return (uint32_t) * reinterpret_cast(src); - } -}; - -template <> -struct ColorAccess<24> -{ - static uint32_t GetPixelWidth() { return 3; } - static uint32_t GetColor(const char8_t *src) - { - return (uint32_t)(*reinterpret_cast(src) & 0xFFFFFF); - } -}; - -template <> -struct ColorAccess<32> -{ - static uint32_t GetPixelWidth() { return 4; } - static uint32_t GetColor(const char8_t *src) - { - return *reinterpret_cast(src); - } -}; - -template -inline void LoadMasked(bool inFlipY, QT3DSI32 *inMasks, void *data, uint8_t *newData, int width, - int height) -{ - const char8_t *oldData = (const char8_t *)data; - SMaskData rMask(inMasks[0]); - SMaskData gMask(inMasks[1]); - SMaskData bMask(inMasks[2]); - for (int h = 0; h < height; ++h) { - int relHeight = h; - if (inFlipY) - relHeight = height - h - 1; - for (int w = 0; w < width; ++w) { - int pos = width * relHeight + w; - const char8_t *readPtr = oldData + (pos * ColorAccess::GetPixelWidth()); - uint8_t *writePtr = newData + (pos * 3); - uint32_t colorVal = ColorAccess::GetColor(readPtr); - writePtr[0] = rMask.MapColor(colorVal); - writePtr[1] = gMask.MapColor(colorVal); - writePtr[2] = bMask.MapColor(colorVal); - } - } -} - -void SLoadedTexture::FreeImagePostProcess(bool inFlipY) -{ - // We always convert 32 bit RGBA - if (m_ExtendedFormat != ExtendedTextureFormats::NoExtendedFormat) { - - QT3DSU32 stride = 3 * width; - format = NVRenderTextureFormats::RGB8; - components = 3; - if (m_ExtendedFormat == ExtendedTextureFormats::Palettized && m_TransparentPaletteIndex > -1 - && m_TransparentPaletteIndex < 256) { - stride = 4 * width; - components = 4; - format = NVRenderTextureFormats::RGBA8; - } - QT3DSU32 byteSize = height * stride; - uint8_t *newData = - (uint8_t *)m_Allocator.allocate(byteSize, "texture data", __FILE__, __LINE__); - if (format == NVRenderTextureFormats::RGBA8) - memSet(newData, 255, byteSize); - switch (m_ExtendedFormat) { - case ExtendedTextureFormats::Palettized: { - RGBQUAD *palette = (RGBQUAD *)m_Palette; - switch (m_BitCount) { - case 1: - LoadPalettized<1>(inFlipY, palette, data, newData, width, height, components, - m_TransparentPaletteIndex); - break; - case 2: - LoadPalettized<2>(inFlipY, palette, data, newData, width, height, components, - m_TransparentPaletteIndex); - break; - case 4: - LoadPalettized<4>(inFlipY, palette, data, newData, width, height, components, - m_TransparentPaletteIndex); - break; - case 8: - LoadPalettized<8>(inFlipY, palette, data, newData, width, height, components, - m_TransparentPaletteIndex); - break; - default: - QT3DS_ASSERT(false); - memSet(newData, 0, byteSize); - break; - } - } break; - case ExtendedTextureFormats::CustomRGB: { - switch (m_BitCount) { - case 16: - LoadMasked<16>(inFlipY, m_CustomMasks, data, newData, width, height); - break; - case 24: - LoadMasked<24>(inFlipY, m_CustomMasks, data, newData, width, height); - break; - case 32: - LoadMasked<32>(inFlipY, m_CustomMasks, data, newData, width, height); - break; - default: - QT3DS_ASSERT(false); - memSet(newData, 0, byteSize); - break; - } - } break; - default: - QT3DS_ASSERT(false); - memSet(newData, 0, byteSize); - break; - } - m_Allocator.deallocate(data); - if (m_Palette) - m_Allocator.deallocate(m_Palette); - data = newData; - m_Palette = NULL; - m_BitCount = 0; - this->dataSizeInBytes = byteSize; - m_ExtendedFormat = ExtendedTextureFormats::NoExtendedFormat; - } -} - -SLoadedTexture *SLoadedTexture::LoadBMP(ISeekableIOStream &inStream, bool inFlipY, - NVFoundationBase &inFnd, - qt3ds::render::NVRenderContextType renderContextType) -{ - Q_UNUSED(renderContextType) - FreeImageIO theIO(inFnd.getAllocator(), inFnd); - SLoadedTexture *retval = DoLoadBMP(&theIO, &inStream, 0); - if (retval) - retval->FreeImagePostProcess(inFlipY); - return retval; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.cpp deleted file mode 100644 index 19d41d11..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderLoadedTextureDDS.h" -#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" - -using namespace qt3ds::render; - -namespace qt3ds { -namespace render { - - static int s_exception_string; - - //================================================================================ - // DXT data-layout structure definitions. - typedef struct - { - QT3DSU16 col0; // 16-bit 565 interpolant endpoints - QT3DSU16 col1; - QT3DSU8 row[4]; // 4x4 * 2bpp color-index == 4 bytes. - } DXTColBlock; - - typedef struct - { - QT3DSU16 row[4]; // 4x4 * 4bpp alpha == 8 bytes. (pure 4-bit alpha values) - } DXT3AlphaBlock; - - typedef struct - { - QT3DSU8 alpha0; // 8-bit alpha interpolant endpoints - QT3DSU8 alpha1; - QT3DSU8 row[6]; // 4x4 * 3bpp alpha-index == 48bits == 6 bytes. - } DXT5AlphaBlock; - - typedef struct - { - QT3DSU8 red; - QT3DSU8 green; - QT3DSU8 blue; - QT3DSU8 alpha; - } Color8888; - -//================================================================================ -// Various DDS file defines - -#define DDSD_CAPS 0x00000001l -#define DDSD_HEIGHT 0x00000002l -#define DDSD_WIDTH 0x00000004l -#define DDSD_PIXELFORMAT 0x00001000l -#define DDS_ALPHAPIXELS 0x00000001l -#define DDS_FOURCC 0x00000004l -#define DDS_PITCH 0x00000008l -#define DDS_COMPLEX 0x00000008l -#define DDS_RGB 0x00000040l -#define DDS_TEXTURE 0x00001000l -#define DDS_MIPMAPCOUNT 0x00020000l -#define DDS_LINEARSIZE 0x00080000l -#define DDS_VOLUME 0x00200000l -#define DDS_MIPMAP 0x00400000l -#define DDS_DEPTH 0x00800000l - -#define DDS_CUBEMAP 0x00000200L -#define DDS_CUBEMAP_POSITIVEX 0x00000400L -#define DDS_CUBEMAP_NEGATIVEX 0x00000800L -#define DDS_CUBEMAP_POSITIVEY 0x00001000L -#define DDS_CUBEMAP_NEGATIVEY 0x00002000L -#define DDS_CUBEMAP_POSITIVEZ 0x00004000L -#define DDS_CUBEMAP_NEGATIVEZ 0x00008000L - -#define FOURCC_DXT1 0x31545844 //(MAKEFOURCC('D','X','T','1')) -#define FOURCC_DXT3 0x33545844 //(MAKEFOURCC('D','X','T','3')) -#define FOURCC_DXT5 0x35545844 //(MAKEFOURCC('D','X','T','5')) - -#define DDS_MAGIC_FLIPPED 0x0F7166ED - - //================================================================================ - // DDS file format structures. - typedef struct _DDS_PIXELFORMAT - { - QT3DSU32 dwSize; - QT3DSU32 dwFlags; - QT3DSU32 dwFourCC; - QT3DSU32 dwRGBBitCount; - QT3DSU32 dwRBitMask; - QT3DSU32 dwGBitMask; - QT3DSU32 dwBBitMask; - QT3DSU32 dwABitMask; - } DDS_PIXELFORMAT; - - typedef struct _DDS_HEADER - { - QT3DSU32 dwSize; - QT3DSU32 dwFlags; - QT3DSU32 dwHeight; - QT3DSU32 dwWidth; - QT3DSU32 dwPitchOrLinearSize; - QT3DSU32 dwDepth; - QT3DSU32 dwMipMapCount; - QT3DSU32 dwReserved1[11]; - DDS_PIXELFORMAT ddspf; - QT3DSU32 dwCaps1; - QT3DSU32 dwCaps2; - QT3DSU32 dwReserved2[3]; - } DDS_HEADER; - - //================================================================================ - // helper functions - //================================================================================ - - // helper macros. - static inline void NvSwapChar(QT3DSU8 &a, QT3DSU8 &b) - { - QT3DSU8 tmp; - tmp = a; - a = b; - b = tmp; - } - - static inline void NvSwapShort(QT3DSU16 &a, QT3DSU16 &b) - { - QT3DSU16 tmp; - tmp = a; - a = b; - b = tmp; - } - - //================================================================================ - //================================================================================ - static void flip_blocks_dxtc1(DXTColBlock *line, QT3DSI32 numBlocks) - { - DXTColBlock *curblock = line; - QT3DSI32 i; - - for (i = 0; i < numBlocks; i++) { - NvSwapChar(curblock->row[0], curblock->row[3]); - NvSwapChar(curblock->row[1], curblock->row[2]); - curblock++; - } - } - - //================================================================================ - //================================================================================ - static void flip_blocks_dxtc3(DXTColBlock *line, QT3DSI32 numBlocks) - { - DXTColBlock *curblock = line; - DXT3AlphaBlock *alphablock; - QT3DSI32 i; - - for (i = 0; i < numBlocks; i++) { - alphablock = (DXT3AlphaBlock *)curblock; - - NvSwapShort(alphablock->row[0], alphablock->row[3]); - NvSwapShort(alphablock->row[1], alphablock->row[2]); - curblock++; - - NvSwapChar(curblock->row[0], curblock->row[3]); - NvSwapChar(curblock->row[1], curblock->row[2]); - curblock++; - } - } - - static void flip_dxt5_alpha(DXT5AlphaBlock *block) - { - QT3DSI8 gBits[4][4]; - - const QT3DSU32 mask = 0x00000007; // bits = 00 00 01 11 - QT3DSU32 bits = 0; - memcpy(&bits, &block->row[0], sizeof(QT3DSI8) * 3); - - gBits[0][0] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[0][1] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[0][2] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[0][3] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[1][0] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[1][1] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[1][2] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[1][3] = (QT3DSI8)(bits & mask); - - bits = 0; - memcpy(&bits, &block->row[3], sizeof(QT3DSI8) * 3); - - gBits[2][0] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[2][1] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[2][2] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[2][3] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[3][0] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[3][1] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[3][2] = (QT3DSI8)(bits & mask); - bits >>= 3; - gBits[3][3] = (QT3DSI8)(bits & mask); - - bits = (gBits[3][0] << 0) | (gBits[3][1] << 3) | (gBits[3][2] << 6) | (gBits[3][3] << 9) - | (gBits[2][0] << 12) | (gBits[2][1] << 15) | (gBits[2][2] << 18) | (gBits[2][3] << 21); - memcpy(&block->row[0], &bits, 3); - - bits = (gBits[1][0] << 0) | (gBits[1][1] << 3) | (gBits[1][2] << 6) | (gBits[1][3] << 9) - | (gBits[0][0] << 12) | (gBits[0][1] << 15) | (gBits[0][2] << 18) | (gBits[0][3] << 21); - memcpy(&block->row[3], &bits, 3); - } - - static void flip_blocks_dxtc5(DXTColBlock *line, QT3DSI32 numBlocks) - { - DXTColBlock *curblock = line; - DXT5AlphaBlock *alphablock; - QT3DSI32 i; - - for (i = 0; i < numBlocks; i++) { - alphablock = (DXT5AlphaBlock *)curblock; - - flip_dxt5_alpha(alphablock); - curblock++; - - NvSwapChar(curblock->row[0], curblock->row[3]); - NvSwapChar(curblock->row[1], curblock->row[2]); - curblock++; - } - } - - static void flip_data_vertical(FreeImageIO *io, QT3DSI8 *image, QT3DSI32 width, QT3DSI32 height, - Qt3DSDDSImage *info) - { - if (info->compressed) { - QT3DSI32 linesize, j; - DXTColBlock *top; - DXTColBlock *bottom; - QT3DSI8 *tmp; - void (*flipblocks)(DXTColBlock *, QT3DSI32) = NULL; - QT3DSI32 xblocks = width / 4; - QT3DSI32 yblocks = height / 4; - QT3DSI32 blocksize; - - switch (info->format) { - case qt3ds::render::NVRenderTextureFormats::RGBA_DXT1: - blocksize = 8; - flipblocks = &flip_blocks_dxtc1; - break; - case qt3ds::render::NVRenderTextureFormats::RGBA_DXT3: - blocksize = 16; - flipblocks = &flip_blocks_dxtc3; - break; - case qt3ds::render::NVRenderTextureFormats::RGBA_DXT5: - blocksize = 16; - flipblocks = &flip_blocks_dxtc5; - break; - default: - return; - } - - linesize = xblocks * blocksize; - tmp = (QT3DSI8 *)QT3DS_ALLOC(io->m_Allocator, linesize, "flip_data_vertical compressed"); - - for (j = 0; j < (yblocks >> 1); j++) { - top = (DXTColBlock *)(void *)(image + j * linesize); - bottom = (DXTColBlock *)(void *)(image + (((yblocks - j) - 1) * linesize)); - - (*flipblocks)(top, xblocks); - (*flipblocks)(bottom, xblocks); - - memcpy(tmp, bottom, linesize); - memcpy(bottom, top, linesize); - memcpy(top, tmp, linesize); - } - - // Catch the middle row of blocks if there is one - // The loop above will skip the middle row - if (yblocks & 0x01) { - DXTColBlock *middle = (DXTColBlock *)(void *)(image + (yblocks >> 1) * linesize); - (*flipblocks)(middle, xblocks); - } - - QT3DS_FREE(io->m_Allocator, tmp); - } else { - QT3DSI32 linesize = width * info->bytesPerPixel; - QT3DSI32 j; - QT3DSI8 *top; - QT3DSI8 *bottom; - QT3DSI8 *tmp; - - // much simpler - just compute the line length and swap each row - tmp = (QT3DSI8 *)QT3DS_ALLOC(io->m_Allocator, linesize, "flip_data_vertical"); - ; - - for (j = 0; j < (height >> 1); j++) { - top = (QT3DSI8 *)(image + j * linesize); - bottom = (QT3DSI8 *)(image + (((height - j) - 1) * linesize)); - - memcpy(tmp, bottom, linesize); - memcpy(bottom, top, linesize); - memcpy(top, tmp, linesize); - } - - QT3DS_FREE(io->m_Allocator, tmp); - } - } - - static QT3DSI32 size_image(QT3DSI32 width, QT3DSI32 height, const Qt3DSDDSImage *image) - { - if (image->compressed) { - return ((width + 3) / 4) * ((height + 3) / 4) - * (image->format == qt3ds::render::NVRenderTextureFormats::RGBA_DXT1 ? 8 : 16); - } else { - return width * height * image->bytesPerPixel; - } - } - - static QT3DSI32 total_image_data_size(Qt3DSDDSImage *image) - { - QT3DSI32 i, j, index = 0, size = 0, w, h; - QT3DSI32 cubeCount = image->cubemap ? 6 : 1; - - for (j = 0; j < cubeCount; j++) { - w = image->width; - h = image->height; - - for (i = 0; i < image->numMipmaps; i++) // account for base plus each mip - { - image->size[index] = size_image(w, h, image); - image->mipwidth[index] = w; - image->mipheight[index] = h; - size += image->size[index]; - if (w != 1) { - w >>= 1; - } - if (h != 1) { - h >>= 1; - } - - index++; - } - } - - return (size); - } - - void *Qt3DSDDSAllocDataBlock(FreeImageIO *io, Qt3DSDDSImage *image) - { - if (image) { - QT3DSI32 i; - QT3DSI32 size = total_image_data_size(image); - image->dataBlock = - QT3DS_ALLOC(io->m_Allocator, size, - "Qt3DSDDSAllocDataBlock"); // no need to calloc, as we fill every bit... - if (image->dataBlock == NULL) { - return NULL; - } - - image->data[0] = image->dataBlock; - - QT3DSI32 planes = image->numMipmaps * (image->cubemap ? 6 : 1); - - for (i = 1; i < planes; i++) // account for base plus each mip - { - image->data[i] = - (void *)(((size_t)(image->data[i - 1])) + (size_t)image->size[i - 1]); - } - - return (image->dataBlock); // in case caller wants to sanity check... - } - return (NULL); - } - - static FIBITMAP *DoLoadDDS(FreeImageIO *io, IInStream &inStream, QT3DSI32 flipVertical) - { - FIBITMAP *dib = NULL; - DDS_HEADER ddsh; - QT3DSI8 filecode[4]; - Qt3DSDDSImage *image = NULL; - bool needsBGRASwap = false; - ; - bool isAllreadyFlipped = false; - - try { - // check file code - inStream.Read(filecode, 4); - if (memcmp(filecode, "DDS ", 4)) { - throw "Invalid DDS file"; - } - - image = (Qt3DSDDSImage *)QT3DS_ALLOC(io->m_Allocator, sizeof(Qt3DSDDSImage), "DoLoadDDS"); - if (image == NULL) { - throw "Qt3DSDDSImage allocation failed"; - } - memset(image, 0, sizeof(Qt3DSDDSImage)); - - // read in DDS header - inStream.Read(&ddsh, 1); - - // check if image is a cubempap - if (ddsh.dwCaps2 & DDS_CUBEMAP) { - const QT3DSI32 allFaces = DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_POSITIVEY - | DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEX | DDS_CUBEMAP_NEGATIVEY - | DDS_CUBEMAP_NEGATIVEZ; - - if ((ddsh.dwCaps2 & allFaces) != allFaces) { - throw "Not all cubemap faces defined - not supported"; - } - - image->cubemap = 1; - } else { - image->cubemap = 0; - } - - // check if image is a volume texture - if ((ddsh.dwCaps2 & DDS_VOLUME) && (ddsh.dwDepth > 0)) { - throw "Volume textures not supported"; - } - - // allocated the memory for the structure we return - dib = QT3DS_NEW(io->m_Allocator, SLoadedTexture)(io->m_Allocator); - if (dib == NULL) { - throw "DIB allocation failed"; - } - - // figure out what the image format is - if (ddsh.ddspf.dwFlags & DDS_FOURCC) { - switch (ddsh.ddspf.dwFourCC) { - case FOURCC_DXT1: - image->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT1; - image->components = 3; - image->compressed = 1; - image->alpha = 0; // Ugh - for backwards compatibility - dib->format = qt3ds::render::NVRenderTextureFormats::RGB_DXT1; - break; - case FOURCC_DXT3: - image->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT3; - image->components = 4; - image->compressed = 1; - image->alpha = 1; - dib->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT3; - break; - case FOURCC_DXT5: - image->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT5; - image->components = 4; - image->compressed = 1; - image->alpha = 1; - dib->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT5; - break; - default: - throw "Unsupported FOURCC code"; - } - } else { - // Check for a supported pixel format - if ((ddsh.ddspf.dwRGBBitCount == 32) && (ddsh.ddspf.dwRBitMask == 0x000000FF) - && (ddsh.ddspf.dwGBitMask == 0x0000FF00) - && (ddsh.ddspf.dwBBitMask == 0x00FF0000) - && (ddsh.ddspf.dwABitMask == 0xFF000000)) { - // We support D3D's A8B8G8R8, which is actually RGBA in linear - // memory, equivalent to GL's RGBA - image->format = qt3ds::render::NVRenderTextureFormats::RGBA8; - image->components = 4; - image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; - image->bytesPerPixel = 4; - image->alpha = 1; - image->compressed = 0; - dib->format = qt3ds::render::NVRenderTextureFormats::RGBA8; - } else if ((ddsh.ddspf.dwRGBBitCount == 32) && (ddsh.ddspf.dwRBitMask == 0x00FF0000) - && (ddsh.ddspf.dwGBitMask == 0x0000FF00) - && (ddsh.ddspf.dwBBitMask == 0x000000FF) - && (ddsh.ddspf.dwABitMask == 0xFF000000)) { - // We support D3D's A8R8G8B8, which is actually BGRA in linear - // memory, need to be - image->format = qt3ds::render::NVRenderTextureFormats::RGBA8; - image->components = 4; - image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; - image->bytesPerPixel = 4; - image->alpha = 1; - image->compressed = 0; - needsBGRASwap = true; - dib->format = qt3ds::render::NVRenderTextureFormats::RGBA8; - } else if ((ddsh.ddspf.dwRGBBitCount == 16) && (ddsh.ddspf.dwRBitMask == 0x0000F800) - && (ddsh.ddspf.dwGBitMask == 0x000007E0) - && (ddsh.ddspf.dwBBitMask == 0x0000001F) - && (ddsh.ddspf.dwABitMask == 0x00000000)) { - // We support D3D's R5G6B5, which is actually RGB in linear - // memory. It is equivalent to GL's GL_UNSIGNED_SHORT_5_6_5 - image->format = qt3ds::render::NVRenderTextureFormats::RGB8; - image->components = 3; - image->alpha = 0; - image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU16; - image->bytesPerPixel = 2; - image->compressed = 0; - dib->format = qt3ds::render::NVRenderTextureFormats::RGB8; - } else if ((ddsh.ddspf.dwRGBBitCount == 8) && (ddsh.ddspf.dwRBitMask == 0x00000000) - && (ddsh.ddspf.dwGBitMask == 0x00000000) - && (ddsh.ddspf.dwBBitMask == 0x00000000) - && (ddsh.ddspf.dwABitMask == 0x000000FF)) { - // We support D3D's A8 - image->format = qt3ds::render::NVRenderTextureFormats::Alpha8; - image->components = 1; - image->alpha = 1; - image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; - image->bytesPerPixel = 1; - image->compressed = 0; - dib->format = qt3ds::render::NVRenderTextureFormats::Alpha8; - } else if ((ddsh.ddspf.dwRGBBitCount == 8) && (ddsh.ddspf.dwRBitMask == 0x000000FF) - && (ddsh.ddspf.dwGBitMask == 0x00000000) - && (ddsh.ddspf.dwBBitMask == 0x00000000) - && (ddsh.ddspf.dwABitMask == 0x00000000)) { - // We support D3D's L8 (flagged as 8 bits of red only) - image->format = qt3ds::render::NVRenderTextureFormats::Luminance8; - image->components = 1; - image->alpha = 0; - image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; - image->bytesPerPixel = 1; - image->compressed = 0; - dib->format = qt3ds::render::NVRenderTextureFormats::Luminance8; - } else if ((ddsh.ddspf.dwRGBBitCount == 16) && (ddsh.ddspf.dwRBitMask == 0x000000FF) - && (ddsh.ddspf.dwGBitMask == 0x00000000) - && (ddsh.ddspf.dwBBitMask == 0x00000000) - && (ddsh.ddspf.dwABitMask == 0x0000FF00)) { - // We support D3D's A8L8 (flagged as 8 bits of red and 8 bits of alpha) - image->format = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; - image->components = 2; - image->alpha = 1; - image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; - image->bytesPerPixel = 2; - image->compressed = 0; - dib->format = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; - } else { - throw "not a DXTC or supported RGB(A) format image"; - } - } - - // detect flagging to indicate this texture was stored in a y-inverted fashion - if (!(ddsh.dwFlags & DDS_LINEARSIZE)) { - if (ddsh.dwPitchOrLinearSize == DDS_MAGIC_FLIPPED) { - isAllreadyFlipped = true; - } - } - - flipVertical = (isAllreadyFlipped != (flipVertical ? true : false)) ? 1 : 0; - - // store primary surface width/height/numMipmaps - image->width = ddsh.dwWidth; - image->height = ddsh.dwHeight; - image->numMipmaps = ddsh.dwFlags & DDS_MIPMAPCOUNT ? ddsh.dwMipMapCount : 1; - - if (image->numMipmaps > QT3DS_DDS_MAX_MIPMAPS) { - throw "Too many mipmaps: max 16"; - } - - // allocate the meta datablock for all mip storage. - Qt3DSDDSAllocDataBlock(io, image); - if (image->dataBlock == NULL) { - throw "Failed to allocate memory for image data storage"; - } - - dib->width = image->width; - dib->height = image->height; - dib->dds = image; - - QT3DSI32 faces = image->cubemap ? 6 : 1; - - QT3DSI32 index = 0; - for (QT3DSI32 j = 0; j < faces; j++) { - // load all surfaces for the image - QT3DSI32 width = image->width; - QT3DSI32 height = image->height; - - for (QT3DSI32 i = 0; i < image->numMipmaps; i++) { - // Get the size, read in the data. - inStream.Read( - NVDataRef((QT3DSU8 *)image->data[index], (QT3DSU32)image->size[index])); - - // Flip in Y for OpenGL if needed - if (flipVertical) - flip_data_vertical(io, (QT3DSI8 *)image->data[index], width, height, image); - - // shrink to next power of 2 - width >>= 1; - height >>= 1; - - if (!width) - width = 1; - - if (!height) - height = 1; - - // make sure DXT isn't <4 on a side... - if (image->compressed) { - if (width < 4) - width = 4; - if (height < 4) - height = 4; - } - - index++; - } - } - - if (needsBGRASwap) { - QT3DSI32 index = 0; - QT3DSI32 k; - - for (k = 0; k < faces; k++) { - QT3DSI32 width = image->width; - QT3DSI32 height = image->height; - - for (QT3DSI32 i = 0; i < image->numMipmaps; i++) { - QT3DSI8 *data = (QT3DSI8 *)(image->data[index]); - QT3DSI32 pixels = width * height; - QT3DSI32 j; - - for (j = 0; j < pixels; j++) { - QT3DSI8 temp = data[0]; - data[0] = data[2]; - data[2] = temp; - - data += 4; - } - - // shrink to next power of 2 - width >>= 1; - height >>= 1; - - if (!width) - width = 1; - - if (!height) - height = 1; - - index++; - } - } - } - } catch (const char *message) { - if (image) { - if (image->dataBlock) - QT3DS_FREE(io->m_Allocator, image->dataBlock); - - QT3DS_FREE(io->m_Allocator, image); - } - if (dib) { - FreeImage_Unload(dib); - } - if (message) { - FreeImage_OutputMessageProc(s_exception_string, message, io); - } - } - - return dib; - } - - SLoadedTexture *SLoadedTexture::LoadDDS(IInStream &inStream, QT3DSI32 flipVertical, - NVFoundationBase &inFnd, - qt3ds::render::NVRenderContextType renderContextType) - { - Q_UNUSED(renderContextType) - FreeImageIO theIO(inFnd.getAllocator(), inFnd); - SLoadedTexture *retval = DoLoadDDS(&theIO, inStream, flipVertical); - - return retval; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h deleted file mode 100644 index 8490b474..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_RENDER_LOAD_DDS_H -#define QT3DS_RENDER_LOAD_DDS_H - -namespace qt3ds { -namespace render { - -/** The maximum number of mipmap levels (per texture or per cubemap face) */ -#define QT3DS_DDS_MAX_MIPMAPS (16) - -/** The number of cubemap faces that must exist in a cubemap-bearing DDS file */ -#define QT3DS_DDS_NUM_CUBEMAP_FACES (6) - - /** The master DDS structure for loading and saving - - This is the master DDS structure. It shouldn't be allocated by hand, - always use NVHHDDSAlloc/NVHHDDSAllocData/NVHHDDSFree to manage them properly. - */ - - struct Qt3DSDDSImage - { - /** Width of the overall texture in texels */ - int width; - /** Height of the overall texture in texels */ - int height; - /** Number of color/alpha components per texel 1-4 */ - int components; - /** The GL type of each color component (noncompressed textures only) */ - int componentFormat; - /** The number of bytes per pixel (noncompressed textures only) */ - int bytesPerPixel; - /** Nonzero if the format is DXT-compressed */ - int compressed; - /** The number of levels in the mipmap pyramid (including the base level) */ - int numMipmaps; - /** If nonzero, then the file contains 6 cubemap faces */ - int cubemap; - /** The format of the loaded texture data */ - int format; - /** The GL internal format of the loaded texture data(compressed textures only) */ - int internalFormat; - /** Nonzero if the texture data includes alpha */ - int alpha; - /** Base of the allocated block of all texel data */ - void *dataBlock; - /** Pointers to the mipmap levels for the texture or each cubemap face */ - void *data[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; - /** Array of sizes of the mipmap levels for the texture or each cubemap face */ - int size[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; - /** Array of widths of the mipmap levels for the texture or each cubemap face */ - int mipwidth[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; - /** Array of heights of the mipmap levels for the texture or each cubemap face */ - int mipheight[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureFreeImageCompat.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureFreeImageCompat.h deleted file mode 100644 index 13f317bd..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureFreeImageCompat.h +++ /dev/null @@ -1,413 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_LOADED_TEXTURE_FREEIMAGE_COMPAT_H -#define QT3DS_RENDER_LOADED_TEXTURE_FREEIMAGE_COMPAT_H -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSRenderLoadedTexture.h" -#include "EASTL/algorithm.h" -#include -#ifndef _MACOSX -#ifndef _INTEGRITYPLATFORM -#include -#endif -#endif - -// We use a compatibility layer so we can easily convert freeimage code to load our texture formats -// where necessary. - -namespace qt3ds { -namespace render { - using namespace qt3ds::foundation; - - typedef int32_t BOOL; - typedef uint8_t BYTE; - typedef uint16_t WORD; - typedef uint32_t DWORD; - typedef int32_t LONG; - -#define FREEIMAGE_COLORORDER_BGR 0 -#define FREEIMAGE_COLORORDER_RGB 1 - -#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR - - typedef ISeekableIOStream *fi_handle; - - struct FreeImageIO - { - NVAllocatorCallback &m_Allocator; - NVFoundationBase &m_Foundation; - int (*read_proc)(void *data, int size, int itemSize, fi_handle handle); - void (*seek_proc)(fi_handle handle, int offset, int pos); - int (*tell_proc)(fi_handle handle); - static inline int reader(void *data, int size, int itemSize, fi_handle handle) - { - NVDataRef theData(toDataRef((QT3DSU8 *)data, (QT3DSU32)size * itemSize)); - QT3DSU32 amount = handle->Read(theData); - return (int)amount; - } - static inline void seeker(fi_handle handle, int offset, int pos) - { - SeekPosition::Enum seekPos(SeekPosition::Begin); - /* -#define SEEK_CUR 1 -#define SEEK_END 2 -#define SEEK_SET 0*/ - switch (pos) { - case 0: - seekPos = SeekPosition::Begin; - break; - case 1: - seekPos = SeekPosition::Current; - break; - case 2: - seekPos = SeekPosition::End; - break; - default: - QT3DS_ASSERT(false); - break; - } - handle->SetPosition(offset, seekPos); - } - static inline int teller(fi_handle handle) { return (int)handle->GetPosition(); } - FreeImageIO(NVAllocatorCallback &alloc, NVFoundationBase &fnd) - : m_Allocator(alloc) - , m_Foundation(fnd) - , read_proc(reader) - , seek_proc(seeker) - , tell_proc(teller) - { - } - }; - - typedef SLoadedTexture FIBITMAP; - inline BYTE *FreeImage_GetBits(FIBITMAP *bmp) { return (BYTE *)bmp->data; } - - inline int FreeImage_GetHeight(FIBITMAP *bmp) { return bmp->height; } - inline int FreeImage_GetWidth(FIBITMAP *bmp) { return bmp->width; } - -#define INPLACESWAP(x, y) eastl::swap(x, y) -#define MIN(x, y) NVMin(x, y) -#define MAX(x, y) NVMax(x, y) - -#define TRUE 1 -#define FALSE 0 - - typedef struct tagBITMAPINFOHEADER - { - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; - } BITMAPINFOHEADER, *PBITMAPINFOHEADER; - - typedef struct tagRGBQUAD - { -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR - BYTE rgbBlue; - BYTE rgbGreen; - BYTE rgbRed; -#else - BYTE rgbRed; - BYTE rgbGreen; - BYTE rgbBlue; -#endif // FREEIMAGE_COLORORDER - BYTE rgbReserved; - } RGBQUAD; - - typedef struct tagRGBTRIPLE - { -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR - BYTE rgbtBlue; - BYTE rgbtGreen; - BYTE rgbtRed; -#else - BYTE rgbtRed; - BYTE rgbtGreen; - BYTE rgbtBlue; -#endif // FREEIMAGE_COLORORDER - } RGBTRIPLE; - - typedef struct tagBITMAPINFO - { - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[1]; - } BITMAPINFO, *PBITMAPINFO; - - typedef struct tagFILE_RGBA - { - unsigned char r, g, b, a; - } FILE_RGBA; - - typedef struct tagFILE_BGRA - { - unsigned char b, g, r, a; - } FILE_BGRA; - - typedef struct tagFILE_RGB - { - unsigned char r, g, b; - } FILE_RGB; - - typedef struct tagFILE_BGR - { - unsigned char b, g, r; - } FILE_BGR; - -// Indexes for byte arrays, masks and shifts for treating pixels as words --- -// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- - -#ifndef FREEIMAGE_BIGENDIAN -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR -// Little Endian (x86 / MS Windows, Linux) : BGR(A) order -#define FI_RGBA_RED 2 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 0 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x00FF0000 -#define FI_RGBA_GREEN_MASK 0x0000FF00 -#define FI_RGBA_BLUE_MASK 0x000000FF -#define FI_RGBA_ALPHA_MASK 0xFF000000 -#define FI_RGBA_RED_SHIFT 16 -#define FI_RGBA_GREEN_SHIFT 8 -#define FI_RGBA_BLUE_SHIFT 0 -#define FI_RGBA_ALPHA_SHIFT 24 -#else -// Little Endian (x86 / MaxOSX) : RGB(A) order -#define FI_RGBA_RED 0 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 2 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x000000FF -#define FI_RGBA_GREEN_MASK 0x0000FF00 -#define FI_RGBA_BLUE_MASK 0x00FF0000 -#define FI_RGBA_ALPHA_MASK 0xFF000000 -#define FI_RGBA_RED_SHIFT 0 -#define FI_RGBA_GREEN_SHIFT 8 -#define FI_RGBA_BLUE_SHIFT 16 -#define FI_RGBA_ALPHA_SHIFT 24 -#endif // FREEIMAGE_COLORORDER -#else -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR -// Big Endian (PPC / none) : BGR(A) order -#define FI_RGBA_RED 2 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 0 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x0000FF00 -#define FI_RGBA_GREEN_MASK 0x00FF0000 -#define FI_RGBA_BLUE_MASK 0xFF000000 -#define FI_RGBA_ALPHA_MASK 0x000000FF -#define FI_RGBA_RED_SHIFT 8 -#define FI_RGBA_GREEN_SHIFT 16 -#define FI_RGBA_BLUE_SHIFT 24 -#define FI_RGBA_ALPHA_SHIFT 0 -#else -// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order -#define FI_RGBA_RED 0 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 2 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0xFF000000 -#define FI_RGBA_GREEN_MASK 0x00FF0000 -#define FI_RGBA_BLUE_MASK 0x0000FF00 -#define FI_RGBA_ALPHA_MASK 0x000000FF -#define FI_RGBA_RED_SHIFT 24 -#define FI_RGBA_GREEN_SHIFT 16 -#define FI_RGBA_BLUE_SHIFT 8 -#define FI_RGBA_ALPHA_SHIFT 0 -#endif // FREEIMAGE_COLORORDER -#endif // FREEIMAGE_BIGENDIAN - -#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK | FI_RGBA_GREEN_MASK | FI_RGBA_BLUE_MASK) - -// The 16bit macros only include masks and shifts, since each color element is not byte aligned - -#define FI16_555_RED_MASK 0x7C00 -#define FI16_555_GREEN_MASK 0x03E0 -#define FI16_555_BLUE_MASK 0x001F -#define FI16_555_RED_SHIFT 10 -#define FI16_555_GREEN_SHIFT 5 -#define FI16_555_BLUE_SHIFT 0 -#define FI16_565_RED_MASK 0xF800 -#define FI16_565_GREEN_MASK 0x07E0 -#define FI16_565_BLUE_MASK 0x001F -#define FI16_565_RED_SHIFT 11 -#define FI16_565_GREEN_SHIFT 5 -#define FI16_565_BLUE_SHIFT 0 - - inline unsigned char HINIBBLE(unsigned char byte) { return byte & 0xF0; } - - inline unsigned char LOWNIBBLE(unsigned char byte) { return byte & 0x0F; } - - inline int CalculateUsedBits(int bits) - { - int bit_count = 0; - unsigned bit = 1; - - for (unsigned i = 0; i < 32; i++) { - if ((bits & bit) == bit) { - bit_count++; - } - - bit <<= 1; - } - - return bit_count; - } - - inline int CalculateLine(int width, int bitdepth) { return ((width * bitdepth) + 7) / 8; } - - inline int CalculatePitch(int line) { return (line + 3) & ~3; } - - inline int CalculateUsedPaletteEntries(int bit_count) - { - if ((bit_count >= 1) && (bit_count <= 8)) - return 1 << bit_count; - - return 0; - } - - inline unsigned char *CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) - { - return (bits + (pitch * scanline)); - } - - inline void ReplaceExtension(char *result, const char *filename, const char *extension) - { - for (size_t i = strlen(filename) - 1; i > 0; --i) { - if (filename[i] == '.') { - memcpy(result, filename, i); - result[i] = '.'; - memcpy(result + i + 1, extension, strlen(extension) + 1); - return; - } - } - - memcpy(result, filename, strlen(filename)); - result[strlen(filename)] = '.'; - memcpy(result + strlen(filename) + 1, extension, strlen(extension) + 1); - } - - inline BYTE *FreeImage_GetScanLine(FIBITMAP *bmp, int height) - { - return CalculateScanLine( - (BYTE *)bmp->data, CalculatePitch(CalculateLine(bmp->width, bmp->m_BitCount)), height); - } - -#define DLL_CALLCONV - -// ignored for now. -#define FreeImage_SetDotsPerMeterX(img, dots) -#define FreeImage_SetDotsPerMeterY(img, dots) - - inline SLoadedTexture *FreeImage_Allocate(int width, int height, int bit_count, FreeImageIO *io) - { - SLoadedTexture *theTexture = QT3DS_NEW(io->m_Allocator, SLoadedTexture)(io->m_Allocator); - int pitch = CalculatePitch(CalculateLine(width, bit_count)); - QT3DSU32 dataSize = (QT3DSU32)(height * pitch); - theTexture->dataSizeInBytes = dataSize; - theTexture->data = io->m_Allocator.allocate(dataSize, "image data", __FILE__, __LINE__); - memZero(theTexture->data, dataSize); - theTexture->width = width; - theTexture->height = height; - theTexture->m_BitCount = bit_count; - // If free image asks us for a palette, we change our format at that time. - theTexture->m_ExtendedFormat = ExtendedTextureFormats::CustomRGB; - return theTexture; - } - - inline SLoadedTexture *FreeImage_Allocate(int width, int height, int bit_count, int rmask, - int gmask, int bmask, FreeImageIO *io) - { - SLoadedTexture *retval = FreeImage_Allocate(width, height, bit_count, io); - retval->m_CustomMasks[0] = rmask; - retval->m_CustomMasks[1] = gmask; - retval->m_CustomMasks[2] = bmask; - return retval; - } - - inline RGBQUAD *FreeImage_GetPalette(SLoadedTexture *texture) - { - if (texture->m_Palette == NULL) { - texture->m_ExtendedFormat = ExtendedTextureFormats::Palettized; - QT3DSU32 memory = 256 * sizeof(RGBQUAD); - if (memory) { - texture->m_Palette = - texture->m_Allocator.allocate(memory, "texture palette", __FILE__, __LINE__); - memZero(texture->m_Palette, memory); - } - } - return (RGBQUAD *)texture->m_Palette; - } - - inline void FreeImage_Unload(SLoadedTexture *texture) { texture->release(); } - inline void FreeImage_OutputMessageProc(int, const char *message, FreeImageIO *io) - { - Q_UNUSED(io); - qCCritical(INVALID_OPERATION, "Error loading image: %s", message); - } - - inline void FreeImage_SetBackgroundColor(SLoadedTexture *texture, RGBQUAD *inColor) - { - if (inColor) { - texture->m_BackgroundColor[0] = inColor->rgbRed; - texture->m_BackgroundColor[1] = inColor->rgbGreen; - texture->m_BackgroundColor[2] = inColor->rgbBlue; - } else - memSet(texture->m_BackgroundColor, 0, 3); - } - - inline void FreeImage_SetTransparencyTable(SLoadedTexture *texture, BYTE *table, int size) - { - if (texture->m_TransparencyTable) - texture->m_Allocator.deallocate(texture->m_TransparencyTable); - texture->m_TransparencyTable = NULL; - if (table && size) { - texture->m_TransparencyTable = (uint8_t *)texture->m_Allocator.allocate( - size, "texture transparency table", __FILE__, __LINE__); - memCopy(texture->m_TransparencyTable, table, size); - } - } -} -} - -using namespace qt3ds::render; - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureGIF.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureGIF.cpp deleted file mode 100644 index ece4d3a3..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureGIF.cpp +++ /dev/null @@ -1,851 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// ========================================================== -// GIF Loader and Writer -// -// Design and implementation by -// - Ryan Rubley -// - Raphael Gaquer -// -// This file is part of FreeImage 3 -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== -#ifdef _MSC_VER -#pragma warning(disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" -#include "EASTL/vector.h" -#include "EASTL/string.h" -// ========================================================== -// Metadata declarations -// ========================================================== - -#define GIF_DISPOSAL_UNSPECIFIED 0 -#define GIF_DISPOSAL_LEAVE 1 -#define GIF_DISPOSAL_BACKGROUND 2 -#define GIF_DISPOSAL_PREVIOUS 3 - -// ========================================================== -// Constant/Typedef declarations -// ========================================================== - -struct GIFinfo -{ - BOOL read; - // only really used when reading - size_t global_color_table_offset; - int global_color_table_size; - BYTE background_color; - eastl::vector application_extension_offsets; - eastl::vector comment_extension_offsets; - eastl::vector graphic_control_extension_offsets; - eastl::vector image_descriptor_offsets; - - GIFinfo() - : read(0) - , global_color_table_offset(0) - , global_color_table_size(0) - , background_color(0) - { - } -}; - -struct PageInfo -{ - PageInfo(int d, int l, int t, int w, int h) - { - disposal_method = d; - left = (WORD)l; - top = (WORD)t; - width = (WORD)w; - height = (WORD)h; - } - int disposal_method; - WORD left, top, width, height; -}; - -// GIF defines a max of 12 bits per code -#define MAX_LZW_CODE 4096 - -class StringTable -{ -public: - StringTable(); - ~StringTable(); - void Initialize(int minCodeSize); - BYTE *FillInputBuffer(int len); - void CompressStart(int bpp, int width); - int CompressEnd(BYTE *buf); // 0-4 bytes - bool Compress(BYTE *buf, int *len); - bool Decompress(BYTE *buf, int *len); - void Done(void); - -protected: - bool m_done; - - int m_minCodeSize, m_clearCode, m_endCode, m_nextCode; - - int m_bpp, m_slack; // Compressor information - - int m_prefix; // Compressor state variable - int m_codeSize, m_codeMask; // Compressor/Decompressor state variables - int m_oldCode; // Decompressor state variable - int m_partial, m_partialSize; // Compressor/Decompressor bit buffer - - int firstPixelPassed; // A specific flag that indicates if the first pixel - // of the whole image had already been read - - eastl::string m_strings[MAX_LZW_CODE]; // This is what is really the "string table" data for the - // Decompressor - int *m_strmap; - - // input buffer - BYTE *m_buffer; - int m_bufferSize, m_bufferRealSize, m_bufferPos, m_bufferShift; - - void ClearCompressorTable(void); - void ClearDecompressorTable(void); -}; - -#define GIF_PACKED_LSD_HAVEGCT 0x80 -#define GIF_PACKED_LSD_COLORRES 0x70 -#define GIF_PACKED_LSD_GCTSORTED 0x08 -#define GIF_PACKED_LSD_GCTSIZE 0x07 -#define GIF_PACKED_ID_HAVELCT 0x80 -#define GIF_PACKED_ID_INTERLACED 0x40 -#define GIF_PACKED_ID_LCTSORTED 0x20 -#define GIF_PACKED_ID_RESERVED 0x18 -#define GIF_PACKED_ID_LCTSIZE 0x07 -#define GIF_PACKED_GCE_RESERVED 0xE0 -#define GIF_PACKED_GCE_DISPOSAL 0x1C -#define GIF_PACKED_GCE_WAITINPUT 0x02 -#define GIF_PACKED_GCE_HAVETRANS 0x01 - -#define GIF_BLOCK_IMAGE_DESCRIPTOR 0x2C -#define GIF_BLOCK_EXTENSION 0x21 -#define GIF_BLOCK_TRAILER 0x3B - -#define GIF_EXT_PLAINTEXT 0x01 -#define GIF_EXT_GRAPHIC_CONTROL 0xF9 -#define GIF_EXT_COMMENT 0xFE -#define GIF_EXT_APPLICATION 0xFF - -#define GIF_INTERLACE_PASSES 4 -static int g_GifInterlaceOffset[GIF_INTERLACE_PASSES] = { 0, 4, 2, 1 }; -static int g_GifInterlaceIncrement[GIF_INTERLACE_PASSES] = { 8, 8, 4, 2 }; - -StringTable::StringTable() -{ - m_buffer = NULL; - firstPixelPassed = 0; // Still no pixel read - // Maximum number of entries in the map is MAX_LZW_CODE * 256 - // (aka 2**12 * 2**8 => a 20 bits key) - // This Map could be optmized to only handle MAX_LZW_CODE * 2**(m_bpp) - m_strmap = (int *)new int[1 << 20]; -} - -StringTable::~StringTable() -{ - if (m_buffer != NULL) { - delete[] m_buffer; - } - if (m_strmap != NULL) { - delete[] m_strmap; - m_strmap = NULL; - } -} - -void StringTable::Initialize(int minCodeSize) -{ - m_done = false; - - m_bpp = 8; - m_minCodeSize = minCodeSize; - m_clearCode = 1 << m_minCodeSize; - if (m_clearCode > MAX_LZW_CODE) { - m_clearCode = MAX_LZW_CODE; - } - m_endCode = m_clearCode + 1; - - m_partial = 0; - m_partialSize = 0; - - m_bufferSize = 0; - ClearCompressorTable(); - ClearDecompressorTable(); -} - -BYTE *StringTable::FillInputBuffer(int len) -{ - if (m_buffer == NULL) { - m_buffer = new BYTE[len]; - m_bufferRealSize = len; - } else if (len > m_bufferRealSize) { - delete[] m_buffer; - m_buffer = new BYTE[len]; - m_bufferRealSize = len; - } - m_bufferSize = len; - m_bufferPos = 0; - m_bufferShift = 8 - m_bpp; - return m_buffer; -} - -void StringTable::CompressStart(int bpp, int width) -{ - m_bpp = bpp; - m_slack = (8 - ((width * bpp) % 8)) % 8; - - m_partial |= m_clearCode << m_partialSize; - m_partialSize += m_codeSize; - ClearCompressorTable(); -} - -int StringTable::CompressEnd(BYTE *buf) -{ - int len = 0; - - // output code for remaining prefix - m_partial |= m_prefix << m_partialSize; - m_partialSize += m_codeSize; - while (m_partialSize >= 8) { - *buf++ = (BYTE)m_partial; - m_partial >>= 8; - m_partialSize -= 8; - len++; - } - - // add the end of information code and flush the entire buffer out - m_partial |= m_endCode << m_partialSize; - m_partialSize += m_codeSize; - while (m_partialSize > 0) { - *buf++ = (BYTE)m_partial; - m_partial >>= 8; - m_partialSize -= 8; - len++; - } - - // most this can be is 4 bytes. 7 bits in m_partial to start + 12 for the - // last code + 12 for the end code = 31 bits total. - return len; -} - -bool StringTable::Compress(BYTE *buf, int *len) -{ - if (m_bufferSize == 0 || m_done) { - return false; - } - - int mask = (1 << m_bpp) - 1; - BYTE *bufpos = buf; - while (m_bufferPos < m_bufferSize) { - // get the current pixel value - char ch = (char)((m_buffer[m_bufferPos] >> m_bufferShift) & mask); - - // The next prefix is : - // | - int nextprefix = (((m_prefix) << 8) & 0xFFF00) + (ch & 0x000FF); - if (firstPixelPassed) { - - if (m_strmap[nextprefix] > 0) { - m_prefix = m_strmap[nextprefix]; - } else { - m_partial |= m_prefix << m_partialSize; - m_partialSize += m_codeSize; - // grab full bytes for the output buffer - while (m_partialSize >= 8 && bufpos - buf < *len) { - *bufpos++ = (BYTE)m_partial; - m_partial >>= 8; - m_partialSize -= 8; - } - - // add the code to the "table map" - m_strmap[nextprefix] = m_nextCode; - - // increment the next highest valid code, increase the code size - if (m_nextCode == (1 << m_codeSize)) { - m_codeSize++; - } - m_nextCode++; - - // if we're out of codes, restart the string table - if (m_nextCode == MAX_LZW_CODE) { - m_partial |= m_clearCode << m_partialSize; - m_partialSize += m_codeSize; - ClearCompressorTable(); - } - - // Only keep the 8 lowest bits (prevent problems with "negative chars") - m_prefix = ch & 0x000FF; - } - - // increment to the next pixel - if (m_bufferShift > 0 - && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack)) { - m_bufferShift -= m_bpp; - } else { - m_bufferPos++; - m_bufferShift = 8 - m_bpp; - } - - // jump out here if the output buffer is full - if (bufpos - buf == *len) { - return true; - } - - } else { - // Specific behavior for the first pixel of the whole image - - firstPixelPassed = 1; - // Only keep the 8 lowest bits (prevent problems with "negative chars") - m_prefix = ch & 0x000FF; - - // increment to the next pixel - if (m_bufferShift > 0 - && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack)) { - m_bufferShift -= m_bpp; - } else { - m_bufferPos++; - m_bufferShift = 8 - m_bpp; - } - - // jump out here if the output buffer is full - if (bufpos - buf == *len) { - return true; - } - } - } - - m_bufferSize = 0; - *len = (int)(bufpos - buf); - - return true; -} - -bool StringTable::Decompress(BYTE *buf, int *len) -{ - if (m_bufferSize == 0 || m_done) { - return false; - } - - BYTE *bufpos = buf; - for (; m_bufferPos < m_bufferSize; m_bufferPos++) { - m_partial |= (int)m_buffer[m_bufferPos] << m_partialSize; - m_partialSize += 8; - while (m_partialSize >= m_codeSize) { - int code = m_partial & m_codeMask; - m_partial >>= m_codeSize; - m_partialSize -= m_codeSize; - - if (code > m_nextCode || (m_nextCode == MAX_LZW_CODE && code != m_clearCode) - || code == m_endCode) { - m_done = true; - *len = (int)(bufpos - buf); - return true; - } - if (code == m_clearCode) { - ClearDecompressorTable(); - continue; - } - - // add new string to string table, if not the first pass since a clear code - if (m_oldCode != MAX_LZW_CODE) { - m_strings[m_nextCode] = - m_strings[m_oldCode] + m_strings[code == m_nextCode ? m_oldCode : code][0]; - } - - if ((int)m_strings[code].size() > *len - (bufpos - buf)) { - // out of space, stuff the code back in for next time - m_partial <<= m_codeSize; - m_partialSize += m_codeSize; - m_partial |= code; - m_bufferPos++; - *len = (int)(bufpos - buf); - return true; - } - - // output the string into the buffer - memcpy(bufpos, m_strings[code].data(), m_strings[code].size()); - bufpos += m_strings[code].size(); - - // increment the next highest valid code, add a bit to the mask if we need to increase - // the code size - if (m_oldCode != MAX_LZW_CODE && m_nextCode < MAX_LZW_CODE) { - if (++m_nextCode < MAX_LZW_CODE) { - if ((m_nextCode & m_codeMask) == 0) { - m_codeSize++; - m_codeMask |= m_nextCode; - } - } - } - - m_oldCode = code; - } - } - - m_bufferSize = 0; - *len = (int)(bufpos - buf); - - return true; -} - -void StringTable::Done(void) -{ - m_done = true; -} - -void StringTable::ClearCompressorTable(void) -{ - if (m_strmap) { - memset(m_strmap, 0xFF, sizeof(unsigned int) * (1 << 20)); - } - m_nextCode = m_endCode + 1; - - m_prefix = 0; - m_codeSize = m_minCodeSize + 1; -} - -void StringTable::ClearDecompressorTable(void) -{ - for (int i = 0; i < m_clearCode; i++) { - m_strings[i].resize(1); - m_strings[i][0] = (char)i; - } - m_nextCode = m_endCode + 1; - - m_codeSize = m_minCodeSize + 1; - m_codeMask = (1 << m_codeSize) - 1; - m_oldCode = MAX_LZW_CODE; -} - -// ========================================================== -// Plugin Interface -// ========================================================== - -static int s_format_id; - -// ========================================================== -// Plugin Implementation -// ========================================================== - -static BOOL DLL_CALLCONV Validate(FreeImageIO *io, fi_handle handle) -{ - char buf[6]; - if (io->read_proc(buf, 6, 1, handle) < 1) { - return FALSE; - } - - BOOL bResult = FALSE; - if (!strncmp(buf, "GIF", 3)) { - if (buf[3] >= '0' && buf[3] <= '9' && buf[4] >= '0' && buf[4] <= '9' && buf[5] >= 'a' - && buf[5] <= 'z') { - bResult = TRUE; - } - } - - io->seek_proc(handle, -6, SEEK_CUR); - - return bResult; -} - -// ---------------------------------------------------------- - -static void *DLL_CALLCONV Open(FreeImageIO *io, fi_handle handle) -{ - GIFinfo *info = new GIFinfo; - if (info == NULL) { - return NULL; - } - BOOL read = TRUE; - - // 25/02/2008 MDA: Not safe to memset GIFinfo structure with VS 2008 (safe iterators), - // perform initialization in constructor instead. - // memset(info, 0, sizeof(GIFinfo)); - - info->read = read; - try { - // Header - if (!Validate(io, handle)) { - throw "Not a GIF file"; - } - io->seek_proc(handle, 6, SEEK_CUR); - - // Logical Screen Descriptor - io->seek_proc(handle, 4, SEEK_CUR); - BYTE packed; - if (io->read_proc(&packed, 1, 1, handle) < 1) { - throw "EOF reading Logical Screen Descriptor"; - } - if (io->read_proc(&info->background_color, 1, 1, handle) < 1) { - throw "EOF reading Logical Screen Descriptor"; - } - io->seek_proc(handle, 1, SEEK_CUR); - - // Global Color Table - if (packed & GIF_PACKED_LSD_HAVEGCT) { - info->global_color_table_offset = io->tell_proc(handle); - info->global_color_table_size = 2 << (packed & GIF_PACKED_LSD_GCTSIZE); - io->seek_proc(handle, 3 * info->global_color_table_size, SEEK_CUR); - } - - // Scan through all the rest of the blocks, saving offsets - size_t gce_offset = 0; - BYTE block = 0; - while (block != GIF_BLOCK_TRAILER) { - if (io->read_proc(&block, 1, 1, handle) < 1) { - throw "EOF reading blocks"; - } - if (block == GIF_BLOCK_IMAGE_DESCRIPTOR) { - info->image_descriptor_offsets.push_back(io->tell_proc(handle)); - // GCE may be 0, meaning no GCE preceded this ID - info->graphic_control_extension_offsets.push_back(gce_offset); - gce_offset = 0; - - io->seek_proc(handle, 8, SEEK_CUR); - if (io->read_proc(&packed, 1, 1, handle) < 1) { - throw "EOF reading Image Descriptor"; - } - - // Local Color Table - if (packed & GIF_PACKED_ID_HAVELCT) { - io->seek_proc(handle, 3 * (2 << (packed & GIF_PACKED_ID_LCTSIZE)), SEEK_CUR); - } - - // LZW Minimum Code Size - io->seek_proc(handle, 1, SEEK_CUR); - } else if (block == GIF_BLOCK_EXTENSION) { - BYTE ext; - if (io->read_proc(&ext, 1, 1, handle) < 1) { - throw "EOF reading extension"; - } - - if (ext == GIF_EXT_GRAPHIC_CONTROL) { - // overwrite previous offset if more than one GCE found before an ID - gce_offset = io->tell_proc(handle); - } else if (ext == GIF_EXT_COMMENT) { - info->comment_extension_offsets.push_back(io->tell_proc(handle)); - } else if (ext == GIF_EXT_APPLICATION) { - info->application_extension_offsets.push_back(io->tell_proc(handle)); - } - } else if (block == GIF_BLOCK_TRAILER) { - continue; - } else { - throw "Invalid GIF block found"; - } - - // Data Sub-blocks - BYTE len; - if (io->read_proc(&len, 1, 1, handle) < 1) { - throw "EOF reading sub-block"; - } - while (len != 0) { - io->seek_proc(handle, len, SEEK_CUR); - if (io->read_proc(&len, 1, 1, handle) < 1) { - throw "EOF reading sub-block"; - } - } - } - } catch (const char *msg) { - FreeImage_OutputMessageProc(s_format_id, msg, io); - delete info; - return NULL; - } - - return info; -} - -static FIBITMAP *DLL_CALLCONV DoLoadGIF(FreeImageIO *io, fi_handle handle, int flags, void *data) -{ - if (data == NULL) { - return NULL; - } - (void)flags; - GIFinfo *info = (GIFinfo *)data; - - int page = 0; - FIBITMAP *dib = NULL; - try { - bool have_transparent = false, no_local_palette = false, interlaced = false; - int disposal_method = GIF_DISPOSAL_LEAVE, transparent_color = 0; - WORD left, top, width, height; - BYTE packed, b; - WORD w; - - // Image Descriptor - io->seek_proc(handle, (long)info->image_descriptor_offsets[page], SEEK_SET); - io->read_proc(&left, 2, 1, handle); - io->read_proc(&top, 2, 1, handle); - io->read_proc(&width, 2, 1, handle); - io->read_proc(&height, 2, 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapShort(&left); - SwapShort(&top); - SwapShort(&width); - SwapShort(&height); -#endif - io->read_proc(&packed, 1, 1, handle); - interlaced = (packed & GIF_PACKED_ID_INTERLACED) ? true : false; - no_local_palette = (packed & GIF_PACKED_ID_HAVELCT) ? false : true; - - int bpp = 8; - if (!no_local_palette) { - int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE); - if (size <= 2) - bpp = 1; - else if (size <= 16) - bpp = 4; - } else if (info->global_color_table_offset != 0) { - if (info->global_color_table_size <= 2) - bpp = 1; - else if (info->global_color_table_size <= 16) - bpp = 4; - } - dib = FreeImage_Allocate(width, height, bpp, io); - if (dib == NULL) { - throw "DIB allocated failed"; - } - - // Palette - RGBQUAD *pal = FreeImage_GetPalette(dib); - if (!no_local_palette) { - int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE); - - int i = 0; - while (i < size) { - io->read_proc(&pal[i].rgbRed, 1, 1, handle); - io->read_proc(&pal[i].rgbGreen, 1, 1, handle); - io->read_proc(&pal[i].rgbBlue, 1, 1, handle); - i++; - } - } else if (info->global_color_table_offset != 0) { - long pos = io->tell_proc(handle); - io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET); - - int i = 0; - while (i < info->global_color_table_size) { - io->read_proc(&pal[i].rgbRed, 1, 1, handle); - io->read_proc(&pal[i].rgbGreen, 1, 1, handle); - io->read_proc(&pal[i].rgbBlue, 1, 1, handle); - i++; - } - - io->seek_proc(handle, pos, SEEK_SET); - } else { - // its legal to have no palette, but we're going to generate *something* - for (int i = 0; i < 256; i++) { - pal[i].rgbRed = (BYTE)i; - pal[i].rgbGreen = (BYTE)i; - pal[i].rgbBlue = (BYTE)i; - } - } - - // LZW Minimum Code Size - io->read_proc(&b, 1, 1, handle); - StringTable *stringtable = new StringTable; - stringtable->Initialize(b); - - // Image Data Sub-blocks - int x = 0, xpos = 0, y = 0, shift = 8 - bpp, mask = (1 << bpp) - 1, interlacepass = 0; - BYTE *scanline = FreeImage_GetScanLine(dib, height - 1); - BYTE buf[4096]; - io->read_proc(&b, 1, 1, handle); - while (b) { - io->read_proc(stringtable->FillInputBuffer(b), b, 1, handle); - int size = sizeof(buf); - while (stringtable->Decompress(buf, &size)) { - for (int i = 0; i < size; i++) { - scanline[xpos] |= (buf[i] & mask) << shift; - if (shift > 0) { - shift -= bpp; - } else { - xpos++; - shift = 8 - bpp; - } - if (++x >= width) { - if (interlaced) { - y += g_GifInterlaceIncrement[interlacepass]; - if (y >= height && ++interlacepass < GIF_INTERLACE_PASSES) { - y = g_GifInterlaceOffset[interlacepass]; - } - } else { - y++; - } - if (y >= height) { - stringtable->Done(); - break; - } - x = xpos = 0; - shift = 8 - bpp; - scanline = FreeImage_GetScanLine(dib, height - y - 1); - } - } - size = sizeof(buf); - } - io->read_proc(&b, 1, 1, handle); - } - - if (page == 0) { - QT3DSU32 idx; - - // Logical Screen Descriptor - io->seek_proc(handle, 6, SEEK_SET); - WORD logicalwidth, logicalheight; - io->read_proc(&logicalwidth, 2, 1, handle); - io->read_proc(&logicalheight, 2, 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapShort(&logicalwidth); - SwapShort(&logicalheight); -#endif - - // Global Color Table - if (info->global_color_table_offset != 0) { - RGBQUAD globalpalette[256]; - io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET); - int i = 0; - while (i < info->global_color_table_size) { - io->read_proc(&globalpalette[i].rgbRed, 1, 1, handle); - io->read_proc(&globalpalette[i].rgbGreen, 1, 1, handle); - io->read_proc(&globalpalette[i].rgbBlue, 1, 1, handle); - globalpalette[i].rgbReserved = 0; - i++; - } - // background color - if (info->background_color < info->global_color_table_size) { - FreeImage_SetBackgroundColor(dib, &globalpalette[info->background_color]); - } - } - - // Application Extension - LONG loop = 1; // If no AE with a loop count is found, the default must be 1 - for (idx = 0; idx < info->application_extension_offsets.size(); idx++) { - io->seek_proc(handle, (long)info->application_extension_offsets[idx], SEEK_SET); - io->read_proc(&b, 1, 1, handle); - if (b == 11) { // All AEs start with an 11 byte sub-block to determine what type of - // AE it is - char buf[11]; - io->read_proc(buf, 11, 1, handle); - if (!memcmp(buf, "NETSCAPE2.0", 11) - || !memcmp(buf, "ANIMEXTS1.0", - 11)) { // Not everybody recognizes ANIMEXTS1.0 but it is valid - io->read_proc(&b, 1, 1, handle); - if (b == 3) { // we're supposed to have a 3 byte sub-block now - io->read_proc(&b, 1, 1, - handle); // this should be 0x01 but isn't really important - io->read_proc(&w, 2, 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapShort(&w); -#endif - loop = w; - if (loop > 0) - loop++; - break; - } - } - } - } - } - - // Graphic Control Extension - if (info->graphic_control_extension_offsets[page] != 0) { - io->seek_proc(handle, (long)(info->graphic_control_extension_offsets[page] + 1), - SEEK_SET); - io->read_proc(&packed, 1, 1, handle); - io->read_proc(&w, 2, 1, handle); -#ifdef FREEIMAGE_BIGENDIAN - SwapShort(&w); -#endif - io->read_proc(&b, 1, 1, handle); - have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false; - disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2; - - transparent_color = b; - if (have_transparent) { - int size = 1 << bpp; - if (transparent_color <= size) { - BYTE table[256]; - memset(table, 0xFF, size); - table[transparent_color] = 0; - FreeImage_SetTransparencyTable(dib, table, size); - dib->m_TransparentPaletteIndex = b; - } - } - } - b = (BYTE)disposal_method; - - delete stringtable; - - } catch (const char *msg) { - if (dib != NULL) { - FreeImage_Unload(dib); - } - FreeImage_OutputMessageProc(s_format_id, msg, io); - return NULL; - } - - return dib; -} - -static void DLL_CALLCONV Close(void *data) -{ - if (data == NULL) { - return; - } - GIFinfo *info = (GIFinfo *)data; - delete info; -} - -SLoadedTexture *SLoadedTexture::LoadGIF(ISeekableIOStream &inStream, bool inFlipY, - NVFoundationBase &inFnd, - qt3ds::render::NVRenderContextType renderContextType) -{ - Q_UNUSED(renderContextType) - FreeImageIO theIO(inFnd.getAllocator(), inFnd); - void *gifData = Open(&theIO, &inStream); - if (gifData) { - SLoadedTexture *retval = DoLoadGIF(&theIO, &inStream, 0, gifData); - Close(gifData); - if (retval) - retval->FreeImagePostProcess(inFlipY); - return retval; - } - return NULL; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureHDR.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureHDR.cpp deleted file mode 100644 index defff295..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureHDR.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// ========================================================== -// Radiance RGBE .HDR Loader -// Decodes Radiance RGBE HDR image into FP16 texture buffer. -// -// Implementation by -// Parashar Krishnamachari (parashark@nvidia.com) -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== - -#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" -#include "render/Qt3DSRenderBaseTypes.h" - -typedef unsigned char RGBE[4]; -#define R 0 -#define G 1 -#define B 2 -#define E 3 - -#define MINELEN 8 // minimum scanline length for encoding -#define MAXELEN 0x7fff // maximum scanline length for encoding - -static int s_format_id; - -static float convertComponent(int exponent, int val) -{ - float v = val / (256.0f); - float d = powf(2.0f, (float)exponent - 128.0f); - return v * d; -} - -static void decrunchScanlineOld(FreeImageIO *io, fi_handle handle, RGBE *scanline, int width) -{ - int i; - int rshift = 0; - - while (width > 0) { - io->read_proc(scanline, 4, 1, handle); - - // The older version of RLE encodes the length in the exponent. - // and marks a run with 1, 1, 1 in RGB. This is differentiated from - // a raw value of 1, 1, 1, by having a exponent of 0; - if (scanline[0][R] == 1 && scanline[0][G] == 1 && scanline[0][B] == 1) { - for (i = (scanline[0][E] << rshift); i > 0; --i) { - memcpy(&scanline[0][0], &scanline[-1][0], 4); - ++scanline; - --width; - } - rshift += 8; - } else { - ++scanline; - --width; - rshift = 0; - } - } -} - -static void decrunchScanline(FreeImageIO *io, fi_handle handle, RGBE *scanline, int width) -{ - if ((width < MINELEN) || (width > MAXELEN)) { - decrunchScanlineOld(io, handle, scanline, width); - return; - } - - char c; - io->read_proc(&c, 1, 1, handle); - if (c != 2) { - io->seek_proc(handle, -1, SEEK_CUR); - decrunchScanlineOld(io, handle, scanline, width); - return; - } - - io->read_proc(&(scanline[0][G]), 1, 1, handle); - io->read_proc(&(scanline[0][B]), 1, 1, handle); - io->read_proc(&c, 1, 1, handle); - - if (scanline[0][G] != 2 || scanline[0][B] & 128) { - scanline[0][R] = 2; - scanline[0][E] = c; - decrunchScanlineOld(io, handle, scanline + 1, width - 1); - } - - // RLE-encoded version does a separate buffer for each channel per scanline - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < width;) { - unsigned char code, val; - io->read_proc(&code, 1, 1, handle); - if (code - > 128) // RLE-encoded run... read 1 value and copy it forward for some n count. - { - code &= 127; - io->read_proc(&val, 1, 1, handle); - while (code--) - scanline[j++][i] = val; - } else // Not a run, so we read it as raw data - { - // Note -- we store each pixel in memory 4 bytes apart, so we can't just - // do one long read. - while (code--) - io->read_proc(&(scanline[j++][i]), 1, 1, handle); - } - } - } -} - -static void decodeScanlineToTexture(RGBE *scanline, int width, void *outBuf, QT3DSU32 offset, - NVRenderTextureFormats::Enum inFormat) -{ - float rgbaF32[4]; - - for (int i = 0; i < width; ++i) { - rgbaF32[R] = convertComponent(scanline[i][E], scanline[i][R]); - rgbaF32[G] = convertComponent(scanline[i][E], scanline[i][G]); - rgbaF32[B] = convertComponent(scanline[i][E], scanline[i][B]); - rgbaF32[3] = 1.0f; - - QT3DSU8 *target = reinterpret_cast(outBuf); - target += offset; - NVRenderTextureFormats::encodeToPixel( - rgbaF32, target, i * NVRenderTextureFormats::getSizeofFormat(inFormat), inFormat); - } -} - -static FIBITMAP *DoLoadHDR(FreeImageIO *io, fi_handle handle, - NVRenderTextureFormats::Enum inFormat = NVRenderTextureFormats::RGB32F) -{ - FIBITMAP *dib = NULL; - try { - if (handle != NULL) { - char str[200]; - int i; - - // Make sure it's a Radiance RGBE file - io->read_proc(str, 10, 1, handle); - if (memcmp(str, "#?RADIANCE", 10)) { - throw "Invalid HDR file"; - } - - io->seek_proc(handle, 1, SEEK_CUR); - - // Get the command string (it's not really important for us; We're always assuming - // 32bit_rle_rgbe is the format - // we're just reading it to skip ahead the correct number of bytes). - i = 0; - char c = 0, prevC; - do { - prevC = c; - io->read_proc(&c, 1, 1, handle); - str[i++] = c; - } while (!(c == 0xa && prevC == 0xa)); - - // Get the resolution string (it will be NULL-terminated for us) - char res[200]; - i = 0; - do { - io->read_proc(&c, 1, 1, handle); - res[i++] = c; - } while (c != 0xa); - res[i] = 0; - - int width, height; - if (!sscanf(res, "-Y %d +X %d", &height, &width)) { - throw "Error encountered while loading HDR stream : could not determine image " - "resolution!"; - } - int bytesPerPixel = NVRenderTextureFormats::getSizeofFormat(inFormat); - dib = FreeImage_Allocate(width, height, bytesPerPixel * 8, io); - if (dib == NULL) { - throw "DIB allocation failed"; - } - - dib->format = inFormat; - dib->components = NVRenderTextureFormats::getNumberOfComponent(inFormat); - - // Allocate a scanline worth of RGBE data - RGBE *scanline = new RGBE[width]; - if (!scanline) { - throw "Error encountered while loading HDR stream : could not buffer scanlines!"; - } - - // Go through all the scanlines - for (int y = 0; y < height; ++y) { - QT3DSU32 byteOfs = (height - 1 - y) * width * bytesPerPixel; - decrunchScanline(io, handle, scanline, width); - decodeScanlineToTexture(scanline, width, dib->data, byteOfs, inFormat); - } - } - return dib; - } catch (const char *message) { - if (dib) { - FreeImage_Unload(dib); - } - if (message) { - FreeImage_OutputMessageProc(s_format_id, message, io); - } - } - - return NULL; -} - -SLoadedTexture *SLoadedTexture::LoadHDR(ISeekableIOStream &inStream, NVFoundationBase &inFnd, - qt3ds::render::NVRenderContextType renderContextType) -{ - FreeImageIO theIO(inFnd.getAllocator(), inFnd); - SLoadedTexture *retval = nullptr; - if (renderContextType == qt3ds::render::NVRenderContextValues::GLES2) - retval = DoLoadHDR(&theIO, &inStream, NVRenderTextureFormats::RGBA8); - else - retval = DoLoadHDR(&theIO, &inStream, NVRenderTextureFormats::RGBA16F); - - - // Let's just assume we don't support this just yet. - // if ( retval ) - // retval->FreeImagePostProcess( inFlipY ); - return retval; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp deleted file mode 100644 index b1d4b050..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSRenderLoadedTexture.h" -#include "Qt3DSRenderLoadedTextureKTX.h" -#include "Qt3DSRenderLoadedTextureDDS.h" - -#include -#include - -using namespace qt3ds::render; -using namespace qt3ds::foundation; - -namespace qt3ds { -namespace render { - -static inline int blockSizeForTextureFormat(int format) -{ - switch (format) { - case QOpenGLTexture::RGB8_ETC1: - case QOpenGLTexture::RGB8_ETC2: - case QOpenGLTexture::SRGB8_ETC2: - case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: - case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: - case QOpenGLTexture::R11_EAC_UNorm: - case QOpenGLTexture::R11_EAC_SNorm: - case QOpenGLTexture::RGB_DXT1: - return 8; - - default: - return 16; - } -} - -static inline int runtimeFormat(quint32 internalFormat) -{ - switch (internalFormat) { - case QOpenGLTexture::RGB8_ETC1: - return NVRenderTextureFormats::RGB8_ETC1; - case QOpenGLTexture::RGB8_ETC2: - return NVRenderTextureFormats::RGB8_ETC2; - case QOpenGLTexture::SRGB8_ETC2: - return NVRenderTextureFormats::SRGB8_ETC2; - case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: - return NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2; - case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: - return NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2; - case QOpenGLTexture::R11_EAC_UNorm: - return NVRenderTextureFormats::R11_EAC_UNorm; - case QOpenGLTexture::R11_EAC_SNorm: - return NVRenderTextureFormats::R11_EAC_SNorm; - case QOpenGLTexture::RGB_DXT1: - return NVRenderTextureFormats::RGB_DXT1; - case QOpenGLTexture::RGBA_DXT1: - return NVRenderTextureFormats::RGBA_DXT3; - case QOpenGLTexture::RGBA_DXT3: - return NVRenderTextureFormats::RGBA_DXT3; - case QOpenGLTexture::RGBA_DXT5: - return NVRenderTextureFormats::RGBA_DXT5; - default: - break; - } - return NVRenderTextureFormats::Unknown; -} - -static inline int imageSize(QT3DSI32 width, QT3DSI32 height, const Qt3DSDDSImage *image) -{ - return ((width + 3) / 4) * ((height + 3) / 4) - * blockSizeForTextureFormat(image->internalFormat); -} - -static inline quint32 totalImageDataSize(Qt3DSDDSImage *image) -{ - int i, j; - int index = 0; - quint32 size = 0; - int w, h; - int cubeCount = image->cubemap ? 6 : 1; - - for (j = 0; j < cubeCount; j++) { - w = image->width; - h = image->height; - - for (i = 0; i < image->numMipmaps; i++) // account for base plus each mip - { - size += 4; // image size is saved in the file - image->size[index] = imageSize(w, h, image); - image->mipwidth[index] = w; - image->mipheight[index] = h; - size += quint32(image->size[index]); - if (w != 1) - w >>= 1; - if (h != 1) - h >>= 1; - - index++; - } - } - - return (size); -} - -static inline quint32 alignedOffset(quint32 offset, quint32 byteAlign) -{ - return (offset + byteAlign - 1) & ~(byteAlign - 1); -} - -inline SLoadedTexture *loadKtx(NVAllocatorCallback &allocator, IInStream &inStream, - QT3DSI32 flipVertical) -{ - static const int KTX_IDENTIFIER_LENGTH = 12; - static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { - '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' - }; - static const quint32 platformEndianIdentifier = 0x04030201; - static const quint32 inversePlatformEndianIdentifier = 0x01020304; - - struct KTXHeader { - quint8 identifier[KTX_IDENTIFIER_LENGTH]; - quint32 endianness; - quint32 glType; - quint32 glTypeSize; - quint32 glFormat; - quint32 glInternalFormat; - quint32 glBaseInternalFormat; - quint32 pixelWidth; - quint32 pixelHeight; - quint32 pixelDepth; - quint32 numberOfArrayElements; - quint32 numberOfFaces; - quint32 numberOfMipmapLevels; - quint32 bytesOfKeyValueData; - }; - - KTXHeader header; - if (inStream.Read(header) != sizeof(header) - || qstrncmp(reinterpret_cast(header.identifier), - ktxIdentifier, KTX_IDENTIFIER_LENGTH) != 0 - || (header.endianness != platformEndianIdentifier - && header.endianness != inversePlatformEndianIdentifier)) { - return nullptr; - } - - const bool isInverseEndian = (header.endianness == inversePlatformEndianIdentifier); - auto decode = [isInverseEndian](quint32 val) { - return isInverseEndian ? qbswap(val) : val; - }; - - const bool isCompressed = decode(header.glType) == 0 && decode(header.glFormat) == 0 - && decode(header.glTypeSize) == 1; - if (!isCompressed) { - qWarning("Uncompressed ktx texture data is not supported"); - return nullptr; - } - - if (decode(header.numberOfArrayElements) != 0) { - qWarning("Array ktx textures not supported"); - return nullptr; - } - - if (decode(header.pixelDepth) != 0) { - qWarning("Only 2D and cube ktx textures are supported"); - return nullptr; - } - - const int bytesToSkip = int(decode(header.bytesOfKeyValueData)); - QVector skipData; - skipData.resize(bytesToSkip); - if (inStream.Read(NVDataRef(skipData.data(), bytesToSkip)) != bytesToSkip) { - qWarning("Unexpected end of ktx data"); - return nullptr; - } - - // now for each mipmap level we have (arrays and 3d textures not supported here) - // uint32 imageSize - // for each array element - // for each face - // for each z slice - // compressed data - // padding so that each face data starts at an offset that is a multiple of 4 - // padding so that each imageSize starts at an offset that is a multiple of 4 - - Qt3DSDDSImage *image = (Qt3DSDDSImage *)QT3DS_ALLOC(allocator, sizeof(Qt3DSDDSImage), "DoLoadDDS"); - - const quint32 level0Width = decode(header.pixelWidth); - const quint32 level0Height = decode(header.pixelHeight); - quint32 faceCount = decode(header.numberOfFaces); - const quint32 mipMapLevels = decode(header.numberOfMipmapLevels); - const quint32 format = decode(header.glInternalFormat); - image->numMipmaps = int(mipMapLevels); - image->cubemap = faceCount == 6 ? 6 : 0; - image->internalFormat = int(format); - image->format = runtimeFormat(format); - image->width = int(level0Width); - image->height = int(level0Height); - image->compressed = 1; - quint32 totalSize = totalImageDataSize(image); - image->dataBlock = QT3DS_ALLOC(allocator, totalSize, "Qt3DSDDSAllocDataBlock"); - if (inStream.Read(NVDataRef(reinterpret_cast(image->dataBlock), totalSize)) - != totalSize) { - QT3DS_FREE(allocator, image); - return nullptr; - } - - SLoadedTexture *result = QT3DS_NEW(allocator, SLoadedTexture)(allocator); - result->dds = image; - result->width = int(level0Width); - result->height = int(level0Height); - result->format = static_cast(image->format); - - // TODO: Proper support for cubemaps should be implemented at some point. - if (faceCount > 1) { - qWarning("Multiple faces (cubemaps) not currently supported in ktx"); - faceCount = 1; - } - - uint8_t *p = reinterpret_cast(image->dataBlock); - uint8_t *basep = p; - - for (quint32 mip = 0; mip < mipMapLevels; ++mip) { - if (p + 4 - basep > totalSize) - break; - const quint32 imageSize = *reinterpret_cast(p); - p += 4; - for (quint32 face = 0; face < faceCount; ++face) { - const quint32 nextOffset = quint32(p + imageSize - basep); - if (nextOffset > totalSize) - break; - image->data[mip] = reinterpret_cast(p); - p = basep + alignedOffset(nextOffset, 4); - } - } - - return result; -} - -SLoadedTexture *SLoadedTexture::LoadKTX(IInStream &inStream, QT3DSI32 flipVertical, - NVFoundationBase &inFnd, - qt3ds::render::NVRenderContextType renderContextType) -{ - Q_UNUSED(renderContextType) - SLoadedTexture *retval = loadKtx(inFnd.getAllocator(), inStream, flipVertical); - - return retval; -} - -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h deleted file mode 100644 index 3a2d7628..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_RENDER_LOAD_KTX_H -#define QT3DS_RENDER_LOAD_KTX_H - -namespace qt3ds { -namespace render { - -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.cpp deleted file mode 100644 index 023964f5..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.cpp +++ /dev/null @@ -1,599 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderPrefilterTexture.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" - -#include - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace qt3ds::foundation; - -Qt3DSRenderPrefilterTexture::Qt3DSRenderPrefilterTexture(NVRenderContext *inNVRenderContext, - QT3DSI32 inWidth, QT3DSI32 inHeight, - NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, - NVFoundationBase &inFnd) - : m_Foundation(inFnd) - , mRefCount(0) - , m_Texture2D(inTexture2D) - , m_DestinationFormat(inDestFormat) - , m_Width(inWidth) - , m_Height(inHeight) - , m_NVRenderContext(inNVRenderContext) -{ - // Calculate mip level - int maxDim = inWidth >= inHeight ? inWidth : inHeight; - - m_MaxMipMapLevel = static_cast(logf((float)maxDim) / logf(2.0f)); - // no concept of sizeOfFormat just does'nt make sense - m_SizeOfFormat = NVRenderTextureFormats::getSizeofFormat(m_DestinationFormat); - m_NoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_DestinationFormat); -} - -Qt3DSRenderPrefilterTexture * -Qt3DSRenderPrefilterTexture::Create(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, QT3DSI32 inHeight, - NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd) -{ - Qt3DSRenderPrefilterTexture *theBSDFMipMap = NULL; - - if (inNVRenderContext->IsComputeSupported()) { - theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), Qt3DSRenderPrefilterTextureCompute)( - inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); - } - - if (!theBSDFMipMap) { - theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), Qt3DSRenderPrefilterTextureCPU)( - inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); - } - - if (theBSDFMipMap) - theBSDFMipMap->addRef(); - - return theBSDFMipMap; -} - -Qt3DSRenderPrefilterTexture::~Qt3DSRenderPrefilterTexture() -{ -} - -//------------------------------------------------------------------------------------ -// CPU based filtering -//------------------------------------------------------------------------------------ - -Qt3DSRenderPrefilterTextureCPU::Qt3DSRenderPrefilterTextureCPU( - NVRenderContext *inNVRenderContext, int inWidth, int inHeight, NVRenderTexture2D &inTexture2D, - NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) - : Qt3DSRenderPrefilterTexture(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, - inFnd) -{ -} - -inline int Qt3DSRenderPrefilterTextureCPU::wrapMod(int a, int base) -{ - return (a >= 0) ? a % base : (a % base) + base; -} - -inline void Qt3DSRenderPrefilterTextureCPU::getWrappedCoords(int &sX, int &sY, int width, int height) -{ - if (sY < 0) { - sX -= width >> 1; - sY = -sY; - } - if (sY >= height) { - sX += width >> 1; - sY = height - sY; - } - sX = wrapMod(sX, width); -} - -STextureData -Qt3DSRenderPrefilterTextureCPU::CreateBsdfMipLevel(STextureData &inCurMipLevel, - STextureData &inPrevMipLevel, int width, - int height) //, IPerfTimer& inPerfTimer ) -{ - STextureData retval; - int newWidth = width >> 1; - int newHeight = height >> 1; - newWidth = newWidth >= 1 ? newWidth : 1; - newHeight = newHeight >= 1 ? newHeight : 1; - - if (inCurMipLevel.data) { - retval = inCurMipLevel; - retval.dataSizeInBytes = - newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); - } else { - retval.dataSizeInBytes = - newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); - retval.format = inPrevMipLevel.format; // inLoadedImage.format; - retval.data = m_Foundation.getAllocator().allocate( - retval.dataSizeInBytes, "Bsdf Scaled Image Data", __FILE__, __LINE__); - } - - for (int y = 0; y < newHeight; ++y) { - for (int x = 0; x < newWidth; ++x) { - float accumVal[4]; - accumVal[0] = 0; - accumVal[1] = 0; - accumVal[2] = 0; - accumVal[3] = 0; - for (int sy = -2; sy <= 2; ++sy) { - for (int sx = -2; sx <= 2; ++sx) { - int sampleX = sx + (x << 1); - int sampleY = sy + (y << 1); - getWrappedCoords(sampleX, sampleY, width, height); - - // Cauchy filter (this is simply because it's the easiest to evaluate, and - // requires no complex - // functions). - float filterPdf = 1.f / (1.f + float(sx * sx + sy * sy) * 2.f); - // With FP HDR formats, we're not worried about intensity loss so much as - // unnecessary energy gain, - // whereas with LDR formats, the fear with a continuous normalization factor is - // that we'd lose - // intensity and saturation as well. - filterPdf /= (NVRenderTextureFormats::getSizeofFormat(retval.format) >= 8) - ? 4.71238898f - : 4.5403446f; - // filterPdf /= 4.5403446f; // Discrete normalization factor - // filterPdf /= 4.71238898f; // Continuous normalization factor - float curPix[4]; - QT3DSI32 byteOffset = (sampleY * width + sampleX) - * NVRenderTextureFormats::getSizeofFormat(retval.format); - if (byteOffset < 0) { - sampleY = height + sampleY; - byteOffset = (sampleY * width + sampleX) - * NVRenderTextureFormats::getSizeofFormat(retval.format); - } - - NVRenderTextureFormats::decodeToFloat(inPrevMipLevel.data, byteOffset, curPix, - retval.format); - - accumVal[0] += filterPdf * curPix[0]; - accumVal[1] += filterPdf * curPix[1]; - accumVal[2] += filterPdf * curPix[2]; - accumVal[3] += filterPdf * curPix[3]; - } - } - - QT3DSU32 newIdx = - (y * newWidth + x) * NVRenderTextureFormats::getSizeofFormat(retval.format); - - NVRenderTextureFormats::encodeToPixel(accumVal, retval.data, newIdx, retval.format); - } - } - - return retval; -} - -void Qt3DSRenderPrefilterTextureCPU::Build(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) -{ - - m_InternalFormat = inFormat; - m_SizeOfInternalFormat = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); - m_InternalNoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_InternalFormat); - - m_Texture2D.SetTextureData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, - m_Width, m_Height, inFormat, m_DestinationFormat); - - STextureData theMipImage; - STextureData prevImage; - prevImage.data = inTextureData; - prevImage.dataSizeInBytes = inTextureDataSize; - prevImage.format = inFormat; - int curWidth = m_Width; - int curHeight = m_Height; - int size = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); - for (int idx = 1; idx <= m_MaxMipMapLevel; ++idx) { - theMipImage = - CreateBsdfMipLevel(theMipImage, prevImage, curWidth, curHeight); //, m_PerfTimer ); - curWidth = curWidth >> 1; - curHeight = curHeight >> 1; - curWidth = curWidth >= 1 ? curWidth : 1; - curHeight = curHeight >= 1 ? curHeight : 1; - inTextureDataSize = curWidth * curHeight * size; - - m_Texture2D.SetTextureData(toU8DataRef((char *)theMipImage.data, (QT3DSU32)inTextureDataSize), - (QT3DSU8)idx, (QT3DSU32)curWidth, (QT3DSU32)curHeight, theMipImage.format, - m_DestinationFormat); - - if (prevImage.data == inTextureData) - prevImage = STextureData(); - - STextureData temp = prevImage; - prevImage = theMipImage; - theMipImage = temp; - } - QT3DS_FREE(m_Foundation.getAllocator(), theMipImage.data); - QT3DS_FREE(m_Foundation.getAllocator(), prevImage.data); -} - -//------------------------------------------------------------------------------------ -// GL compute based filtering -//------------------------------------------------------------------------------------ - -static const char *computeUploadShader(std::string &prog, NVRenderTextureFormats::Enum inFormat, - bool binESContext) -{ - if (binESContext) { - prog += "#version 310 es\n" - "#extension GL_ARB_compute_shader : enable\n" - "precision highp float;\n" - "precision highp int;\n" - "precision mediump image2D;\n"; - } else { - prog += "#version 430\n" - "#extension GL_ARB_compute_shader : enable\n"; - } - - if (inFormat == NVRenderTextureFormats::RGBA8) { - prog += "// Set workgroup layout;\n" - "layout (local_size_x = 16, local_size_y = 16) in;\n\n" - "layout (rgba8, binding = 1) readonly uniform image2D inputImage;\n\n" - "layout (rgba16f, binding = 2) writeonly uniform image2D outputImage;\n\n" - "void main()\n" - "{\n" - " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " - ">= gl_NumWorkGroups.y )\n" - " return;\n" - " vec4 value = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.xy));\n" - " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), value );\n" - "}\n"; - } else { - prog += "float convertToFloat( in uint inValue )\n" - "{\n" - " uint v = inValue & uint(0xFF);\n" - " float f = float(v)/256.0;\n" - " return f;\n" - "}\n"; - - prog += "int getMod( in int inValue, in int mod )\n" - "{\n" - " int v = mod * (inValue/mod);\n" - " return inValue - v;\n" - "}\n"; - - prog += "vec4 getRGBValue( in int byteNo, vec4 inVal, vec4 inVal1 )\n" - "{\n" - " vec4 result= vec4(0.0);\n" - " if( byteNo == 0) {\n" - " result.r = inVal.r;\n" - " result.g = inVal.g;\n" - " result.b = inVal.b;\n" - " }\n" - " else if( byteNo == 1) {\n" - " result.r = inVal.g;\n" - " result.g = inVal.b;\n" - " result.b = inVal.a;\n" - " }\n" - " else if( byteNo == 2) {\n" - " result.r = inVal.b;\n" - " result.g = inVal.a;\n" - " result.b = inVal1.r;\n" - " }\n" - " else if( byteNo == 3) {\n" - " result.r = inVal.a;\n" - " result.g = inVal1.r;\n" - " result.b = inVal1.g;\n" - " }\n" - " return result;\n" - "}\n"; - - prog += "// Set workgroup layout;\n" - "layout (local_size_x = 16, local_size_y = 16) in;\n\n" - "layout (rgba8, binding = 1) readonly uniform image2D inputImage;\n\n" - "layout (rgba16f, binding = 2) writeonly uniform image2D outputImage;\n\n" - "void main()\n" - "{\n" - " vec4 result = vec4(0.0);\n" - " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " - ">= gl_NumWorkGroups.y )\n" - " return;\n" - " int xpos = (int(gl_GlobalInvocationID.x)*3)/4;\n" - " int xmod = getMod(int(gl_GlobalInvocationID.x)*3, 4);\n" - " ivec2 readPos = ivec2(xpos, gl_GlobalInvocationID.y);\n" - " vec4 value = imageLoad(inputImage, readPos);\n" - " vec4 value1 = imageLoad(inputImage, ivec2(readPos.x + 1, readPos.y));\n" - " result = getRGBValue( xmod, value, value1);\n" - " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), result );\n" - "}\n"; - } - return prog.c_str(); -} - -static const char *computeWorkShader(std::string &prog, bool binESContext) -{ - if (binESContext) { - prog += "#version 310 es\n" - "#extension GL_ARB_compute_shader : enable\n" - "precision highp float;\n" - "precision highp int;\n" - "precision mediump image2D;\n"; - } else { - prog += "#version 430\n" - "#extension GL_ARB_compute_shader : enable\n"; - } - - prog += "int wrapMod( in int a, in int base )\n" - "{\n" - " return ( a >= 0 ) ? a % base : -(a % base) + base;\n" - "}\n"; - - prog += "void getWrappedCoords( inout int sX, inout int sY, in int width, in int height )\n" - "{\n" - " if (sY < 0) { sX -= width >> 1; sY = -sY; }\n" - " if (sY >= height) { sX += width >> 1; sY = height - sY; }\n" - " sX = wrapMod( sX, width );\n" - "}\n"; - - prog += "// Set workgroup layout;\n" - "layout (local_size_x = 16, local_size_y = 16) in;\n\n" - "layout (rgba16f, binding = 1) readonly uniform image2D inputImage;\n\n" - "layout (rgba16f, binding = 2) writeonly uniform image2D outputImage;\n\n" - "void main()\n" - "{\n" - " int prevWidth = int(gl_NumWorkGroups.x) << 1;\n" - " int prevHeight = int(gl_NumWorkGroups.y) << 1;\n" - " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y >= " - "gl_NumWorkGroups.y )\n" - " return;\n" - " vec4 accumVal = vec4(0.0);\n" - " for ( int sy = -2; sy <= 2; ++sy )\n" - " {\n" - " for ( int sx = -2; sx <= 2; ++sx )\n" - " {\n" - " int sampleX = sx + (int(gl_GlobalInvocationID.x) << 1);\n" - " int sampleY = sy + (int(gl_GlobalInvocationID.y) << 1);\n" - " getWrappedCoords(sampleX, sampleY, prevWidth, prevHeight);\n" - " if ((sampleY * prevWidth + sampleX) < 0 )\n" - " sampleY = prevHeight + sampleY;\n" - " ivec2 pos = ivec2(sampleX, sampleY);\n" - " vec4 value = imageLoad(inputImage, pos);\n" - " float filterPdf = 1.0 / ( 1.0 + float(sx*sx + sy*sy)*2.0 );\n" - " filterPdf /= 4.71238898;\n" - " accumVal[0] += filterPdf * value.r;\n" - " accumVal[1] += filterPdf * value.g;\n" - " accumVal[2] += filterPdf * value.b;\n" - " accumVal[3] += filterPdf * value.a;\n" - " }\n" - " }\n" - " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), accumVal );\n" - "}\n"; - - return prog.c_str(); -} - -inline NVConstDataRef toRef(const char *data) -{ - size_t len = strlen(data) + 1; - return NVConstDataRef((const QT3DSI8 *)data, (QT3DSU32)len); -} - -static bool isGLESContext(NVRenderContext *context) -{ - NVRenderContextType ctxType = context->GetRenderContextType(); - - // Need minimum of GL3 or GLES3 - if (ctxType == NVRenderContextValues::GLES2 || ctxType == NVRenderContextValues::GLES3 - || ctxType == NVRenderContextValues::GLES3PLUS) { - return true; - } - - return false; -} - -#define WORKGROUP_SIZE 16 - -Qt3DSRenderPrefilterTextureCompute::Qt3DSRenderPrefilterTextureCompute( - NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, QT3DSI32 inHeight, - NVRenderTexture2D &inTexture2D, NVRenderTextureFormats::Enum inDestFormat, - NVFoundationBase &inFnd) - : Qt3DSRenderPrefilterTexture(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, - inFnd) - , m_BSDFProgram(NULL) - , m_UploadProgram_RGBA8(NULL) - , m_UploadProgram_RGB8(NULL) - , m_Level0Tex(NULL) - , m_TextureCreated(false) -{ -} - -Qt3DSRenderPrefilterTextureCompute::~Qt3DSRenderPrefilterTextureCompute() -{ - m_UploadProgram_RGB8 = NULL; - m_UploadProgram_RGBA8 = NULL; - m_BSDFProgram = NULL; - m_Level0Tex = NULL; -} - -void Qt3DSRenderPrefilterTextureCompute::createComputeProgram(NVRenderContext *context) -{ - std::string computeProg; - - if (!m_BSDFProgram) { - m_BSDFProgram = context - ->CompileComputeSource( - "Compute BSDF mipmap shader", - toRef(computeWorkShader(computeProg, isGLESContext(context)))) - .mShader; - } -} - -NVRenderShaderProgram *Qt3DSRenderPrefilterTextureCompute::getOrCreateUploadComputeProgram( - NVRenderContext *context, NVRenderTextureFormats::Enum inFormat) -{ - std::string computeProg; - - if (inFormat == NVRenderTextureFormats::RGB8) { - if (!m_UploadProgram_RGB8) { - m_UploadProgram_RGB8 = - context - ->CompileComputeSource( - "Compute BSDF mipmap level 0 RGB8 shader", - toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) - .mShader; - } - - return m_UploadProgram_RGB8; - } else { - if (!m_UploadProgram_RGBA8) { - m_UploadProgram_RGBA8 = - context - ->CompileComputeSource( - "Compute BSDF mipmap level 0 RGBA8 shader", - toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) - .mShader; - } - - return m_UploadProgram_RGBA8; - } -} - -void Qt3DSRenderPrefilterTextureCompute::CreateLevel0Tex(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) -{ - NVRenderTextureFormats::Enum theFormat = inFormat; - QT3DSI32 theWidth = m_Width; - - // Since we cannot use RGB format in GL compute - // we treat it as a RGBA component format - if (inFormat == NVRenderTextureFormats::RGB8) { - // This works only with 4 byte aligned data - QT3DS_ASSERT(m_Width % 4 == 0); - theFormat = NVRenderTextureFormats::RGBA8; - theWidth = (m_Width * 3) / 4; - } - - if (m_Level0Tex == NULL) { - m_Level0Tex = m_NVRenderContext->CreateTexture2D(); - m_Level0Tex->SetTextureStorage(1, theWidth, m_Height, theFormat, theFormat, - NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); - } else { - m_Level0Tex->SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, - 0, 0, theWidth, m_Height, theFormat); - } -} - -void Qt3DSRenderPrefilterTextureCompute::Build(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) -{ - bool needMipUpload = (inFormat != m_DestinationFormat); - // re-upload data - if (!m_TextureCreated) { - m_Texture2D.SetTextureStorage( - m_MaxMipMapLevel + 1, m_Width, m_Height, m_DestinationFormat, inFormat, (needMipUpload) - ? NVDataRef() - : NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); - m_Texture2D.addRef(); - // create a compute shader (if not aloread done) which computes the BSDF mipmaps for this - // texture - createComputeProgram(m_NVRenderContext); - - if (!m_BSDFProgram) { - QT3DS_ASSERT(false); - return; - } - - m_TextureCreated = true; - } else if (!needMipUpload) { - m_Texture2D.SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, - 0, 0, m_Width, m_Height, inFormat); - } - - if (needMipUpload) { - CreateLevel0Tex(inTextureData, inTextureDataSize, inFormat); - } - - NVScopedRefCounted theInputImage; - NVScopedRefCounted theOutputImage; - theInputImage = - m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); - theOutputImage = - m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); - - if (needMipUpload && m_Level0Tex) { - NVRenderShaderProgram *uploadProg = - getOrCreateUploadComputeProgram(m_NVRenderContext, inFormat); - if (!uploadProg) - return; - - m_NVRenderContext->SetActiveShader(uploadProg); - - NVScopedRefCounted theInputImage0; - theInputImage0 = - m_NVRenderContext->CreateImage2D(m_Level0Tex, NVRenderImageAccessType::ReadWrite); - - theInputImage0->SetTextureLevel(0); - NVRenderCachedShaderProperty theCachedinputImage0("inputImage", - *uploadProg); - theCachedinputImage0.Set(theInputImage0); - - theOutputImage->SetTextureLevel(0); - NVRenderCachedShaderProperty theCachedOutputImage("outputImage", - *uploadProg); - theCachedOutputImage.Set(theOutputImage); - - m_NVRenderContext->DispatchCompute(uploadProg, m_Width, m_Height, 1); - - // sync - NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); - m_NVRenderContext->SetMemoryBarrier(flags); - } - - int width = m_Width >> 1; - int height = m_Height >> 1; - - m_NVRenderContext->SetActiveShader(m_BSDFProgram); - - for (int i = 1; i <= m_MaxMipMapLevel; ++i) { - theOutputImage->SetTextureLevel(i); - NVRenderCachedShaderProperty theCachedOutputImage("outputImage", - *m_BSDFProgram); - theCachedOutputImage.Set(theOutputImage); - theInputImage->SetTextureLevel(i - 1); - NVRenderCachedShaderProperty theCachedinputImage("inputImage", - *m_BSDFProgram); - theCachedinputImage.Set(theInputImage); - - m_NVRenderContext->DispatchCompute(m_BSDFProgram, width, height, 1); - - width = width > 2 ? width >> 1 : 1; - height = height > 2 ? height >> 1 : 1; - - // sync - NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); - m_NVRenderContext->SetMemoryBarrier(flags); - } -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.h deleted file mode 100644 index e633eb14..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderPrefilterTexture.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_PREFILTER_TEXTURE_H -#define QT3DS_RENDER_PREFILTER_TEXTURE_H -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "Qt3DSRender.h" - -#include "Qt3DSTypes.h" -#include "Qt3DSRenderLoadedTexture.h" - -namespace qt3ds { -namespace render { - - class Qt3DSRenderPrefilterTexture : public NVRefCounted - { - public: - Qt3DSRenderPrefilterTexture(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, QT3DSI32 inHeight, - NVRenderTexture2D &inTexture, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - virtual ~Qt3DSRenderPrefilterTexture(); - - virtual void Build(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) = 0; - - static Qt3DSRenderPrefilterTexture *Create(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, - QT3DSI32 inHeight, NVRenderTexture2D &inTexture, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - - protected: - NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things - volatile QT3DSI32 mRefCount; ///< reference count - - NVRenderTexture2D &m_Texture2D; - NVRenderTextureFormats::Enum m_InternalFormat; - NVRenderTextureFormats::Enum m_DestinationFormat; - - QT3DSI32 m_Width; - QT3DSI32 m_Height; - QT3DSI32 m_MaxMipMapLevel; - QT3DSI32 m_SizeOfFormat; - QT3DSI32 m_SizeOfInternalFormat; - QT3DSI32 m_InternalNoOfComponent; - QT3DSI32 m_NoOfComponent; - NVRenderContext *m_NVRenderContext; - }; - - class Qt3DSRenderPrefilterTextureCPU : public Qt3DSRenderPrefilterTexture - { - public: - Qt3DSRenderPrefilterTextureCPU(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, - QT3DSI32 inHeight, NVRenderTexture2D &inTexture, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - - void Build(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) override; - - STextureData CreateBsdfMipLevel(STextureData &inCurMipLevel, STextureData &inPrevMipLevel, - QT3DSI32 width, QT3DSI32 height); - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - int wrapMod(int a, int base); - void getWrappedCoords(int &sX, int &sY, int width, int height); - }; - - class Qt3DSRenderPrefilterTextureCompute : public Qt3DSRenderPrefilterTexture - { - public: - Qt3DSRenderPrefilterTextureCompute(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, - QT3DSI32 inHeight, NVRenderTexture2D &inTexture, - NVRenderTextureFormats::Enum inDestFormat, - qt3ds::NVFoundationBase &inFnd); - ~Qt3DSRenderPrefilterTextureCompute(); - - void Build(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat) override; - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) - - private: - void CreateLevel0Tex(void *inTextureData, QT3DSI32 inTextureDataSize, - NVRenderTextureFormats::Enum inFormat); - - NVScopedRefCounted m_BSDFProgram; - NVScopedRefCounted m_UploadProgram_RGBA8; - NVScopedRefCounted m_UploadProgram_RGB8; - NVScopedRefCounted m_Level0Tex; - bool m_TextureCreated; - - void createComputeProgram(NVRenderContext *context); - NVRenderShaderProgram * - getOrCreateUploadComputeProgram(NVRenderContext *context, - NVRenderTextureFormats::Enum inFormat); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.cpp deleted file mode 100644 index 25fbb414..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderResourceBufferObjects.h" - -using namespace qt3ds::render; - -/* - IResourceManager& m_ResourceManager; - NVRenderFrameBuffer* m_FrameBuffer; - */ - -CResourceFrameBuffer::CResourceFrameBuffer(IResourceManager &mgr) - : m_ResourceManager(mgr) - , m_FrameBuffer(NULL) -{ -} - -CResourceFrameBuffer::~CResourceFrameBuffer() -{ - ReleaseFrameBuffer(); -} - -bool CResourceFrameBuffer::EnsureFrameBuffer() -{ - if (!m_FrameBuffer) { - m_FrameBuffer = m_ResourceManager.AllocateFrameBuffer(); - return true; - } - return false; -} - -void CResourceFrameBuffer::ReleaseFrameBuffer() -{ - if (m_FrameBuffer) { - m_ResourceManager.Release(*m_FrameBuffer); - } -} - -CResourceRenderBuffer::CResourceRenderBuffer(IResourceManager &mgr) - : m_ResourceManager(mgr) - , m_RenderBuffer(NULL) -{ -} - -CResourceRenderBuffer::~CResourceRenderBuffer() -{ - ReleaseRenderBuffer(); -} - -bool CResourceRenderBuffer::EnsureRenderBuffer(QT3DSU32 width, QT3DSU32 height, - NVRenderRenderBufferFormats::Enum storageFormat) -{ - if (m_RenderBuffer == NULL || m_Dimensions.m_Width != width || m_Dimensions.m_Height != height - || m_StorageFormat != storageFormat) { - if (m_RenderBuffer == NULL || m_StorageFormat != storageFormat) { - ReleaseRenderBuffer(); - m_RenderBuffer = m_ResourceManager.AllocateRenderBuffer(width, height, storageFormat); - } else - m_RenderBuffer->SetDimensions( - qt3ds::render::NVRenderRenderBufferDimensions(width, height)); - m_Dimensions = m_RenderBuffer->GetDimensions(); - m_StorageFormat = m_RenderBuffer->GetStorageFormat(); - return true; - } - return false; -} - -void CResourceRenderBuffer::ReleaseRenderBuffer() -{ - if (m_RenderBuffer) { - m_ResourceManager.Release(*m_RenderBuffer); - m_RenderBuffer = NULL; - } -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.h deleted file mode 100644 index fb54c4dc..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceBufferObjects.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_RESOURCE_BUFFER_OBJECTS_H -#define QT3DS_RENDER_RESOURCE_BUFFER_OBJECTS_H -#include "Qt3DSRender.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderResourceManager.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" - -namespace qt3ds { -namespace render { - class CResourceFrameBuffer - { - protected: - IResourceManager &m_ResourceManager; - NVRenderFrameBuffer *m_FrameBuffer; - - public: - CResourceFrameBuffer(IResourceManager &mgr); - ~CResourceFrameBuffer(); - bool EnsureFrameBuffer(); - void ReleaseFrameBuffer(); - - IResourceManager &GetResourceManager() { return m_ResourceManager; } - operator NVRenderFrameBuffer *() { return m_FrameBuffer; } - NVRenderFrameBuffer *operator->() - { - QT3DS_ASSERT(m_FrameBuffer); - return m_FrameBuffer; - } - NVRenderFrameBuffer &operator*() - { - QT3DS_ASSERT(m_FrameBuffer); - return *m_FrameBuffer; - } - }; - - class CResourceRenderBuffer - { - protected: - IResourceManager &m_ResourceManager; - NVRenderRenderBuffer *m_RenderBuffer; - qt3ds::render::NVRenderRenderBufferFormats::Enum m_StorageFormat; - qt3ds::render::NVRenderRenderBufferDimensions m_Dimensions; - - public: - CResourceRenderBuffer(IResourceManager &mgr); - ~CResourceRenderBuffer(); - bool EnsureRenderBuffer(QT3DSU32 width, QT3DSU32 height, - NVRenderRenderBufferFormats::Enum storageFormat); - void ReleaseRenderBuffer(); - - operator NVRenderRenderBuffer *() { return m_RenderBuffer; } - NVRenderRenderBuffer *operator->() - { - QT3DS_ASSERT(m_RenderBuffer); - return m_RenderBuffer; - } - NVRenderRenderBuffer &operator*() - { - QT3DS_ASSERT(m_RenderBuffer); - return *m_RenderBuffer; - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.cpp deleted file mode 100644 index 35936885..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderResourceManager.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderTexture2DArray.h" -#include "render/Qt3DSRenderTextureCube.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" - -using namespace qt3ds::render; - -namespace { - -struct SResourceManager : public IResourceManager -{ - NVScopedRefCounted m_RenderContext; - // Complete list of all allocated objects - nvvector> m_AllocatedObjects; - - nvvector m_FreeFrameBuffers; - nvvector m_FreeRenderBuffers; - nvvector m_FreeTextures; - nvvector m_FreeTexArrays; - nvvector m_FreeTexCubes; - nvvector m_FreeImages; - - volatile QT3DSI32 mRefCount; - - SResourceManager(NVRenderContext &ctx) - : m_RenderContext(ctx) - , m_AllocatedObjects(ctx.GetAllocator(), "SResourceManager::m_FrameBuffers") - , m_FreeFrameBuffers(ctx.GetAllocator(), "SResourceManager::m_FreeFrameBuffers") - , m_FreeRenderBuffers(ctx.GetAllocator(), "SResourceManager::m_FreeRenderBuffers") - , m_FreeTextures(ctx.GetAllocator(), "SResourceManager::m_FreeTextures") - , m_FreeTexArrays(ctx.GetAllocator(), "SResourceManager::m_FreeTexArrays") - , m_FreeTexCubes(ctx.GetAllocator(), "SResourceManager::m_FreeTexCubes") - , m_FreeImages(ctx.GetAllocator(), "SResourceManager::m_FreeImages") - , mRefCount(0) - { - } - virtual ~SResourceManager() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext->GetAllocator()) - - NVRenderFrameBuffer *AllocateFrameBuffer() override - { - if (m_FreeFrameBuffers.empty() == true) { - NVRenderFrameBuffer *newBuffer = m_RenderContext->CreateFrameBuffer(); - m_AllocatedObjects.push_back(newBuffer); - m_FreeFrameBuffers.push_back(newBuffer); - } - NVRenderFrameBuffer *retval = m_FreeFrameBuffers.back(); - m_FreeFrameBuffers.pop_back(); - return retval; - } - void Release(NVRenderFrameBuffer &inBuffer) override - { - if (inBuffer.HasAnyAttachment()) { - // Ensure the framebuffer has no attachments. - inBuffer.Attach(NVRenderFrameBufferAttachments::Color0, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color1, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color2, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color3, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color4, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color5, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color6, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Color7, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Depth, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - inBuffer.Attach(NVRenderFrameBufferAttachments::Stencil, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - if (m_RenderContext->IsDepthStencilSupported()) - inBuffer.Attach(NVRenderFrameBufferAttachments::DepthStencil, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - } -#ifdef _DEBUG - nvvector::iterator theFind = - eastl::find(m_FreeFrameBuffers.begin(), m_FreeFrameBuffers.end(), &inBuffer); - QT3DS_ASSERT(theFind == m_FreeFrameBuffers.end()); -#endif - m_FreeFrameBuffers.push_back(&inBuffer); - } - - virtual NVRenderRenderBuffer * - AllocateRenderBuffer(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderRenderBufferFormats::Enum inBufferFormat) override - { - // Look for one of this specific size and format. - QT3DSU32 existingMatchIdx = m_FreeRenderBuffers.size(); - for (QT3DSU32 idx = 0, end = existingMatchIdx; idx < end; ++idx) { - NVRenderRenderBuffer *theBuffer = m_FreeRenderBuffers[idx]; - qt3ds::render::NVRenderRenderBufferDimensions theDims = theBuffer->GetDimensions(); - NVRenderRenderBufferFormats::Enum theFormat = theBuffer->GetStorageFormat(); - if (theDims.m_Width == inWidth && theDims.m_Height == inHeight - && theFormat == inBufferFormat) { - // Replace idx with last for efficient erasure (that reorders the vector). - m_FreeRenderBuffers.replace_with_last(idx); - return theBuffer; - } else if (theFormat == inBufferFormat) - existingMatchIdx = idx; - } - // If a specific exact match couldn't be found, just use the buffer with - // the same format and resize it. - if (existingMatchIdx < m_FreeRenderBuffers.size()) { - NVRenderRenderBuffer *theBuffer = m_FreeRenderBuffers[existingMatchIdx]; - m_FreeRenderBuffers.replace_with_last(existingMatchIdx); - theBuffer->SetDimensions(qt3ds::render::NVRenderRenderBufferDimensions(inWidth, inHeight)); - return theBuffer; - } - - NVRenderRenderBuffer *theBuffer = - m_RenderContext->CreateRenderBuffer(inBufferFormat, inWidth, inHeight); - m_AllocatedObjects.push_back(theBuffer); - return theBuffer; - } - void Release(NVRenderRenderBuffer &inBuffer) override - { -#ifdef _DEBUG - nvvector::iterator theFind = - eastl::find(m_FreeRenderBuffers.begin(), m_FreeRenderBuffers.end(), &inBuffer); - QT3DS_ASSERT(theFind == m_FreeRenderBuffers.end()); -#endif - m_FreeRenderBuffers.push_back(&inBuffer); - } - NVRenderTexture2D *SetupAllocatedTexture(NVRenderTexture2D &inTexture) - { - inTexture.SetMinFilter(NVRenderTextureMinifyingOp::Linear); - inTexture.SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return &inTexture; - } - NVRenderTexture2D *AllocateTexture2D(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inTextureFormat, - QT3DSU32 inSampleCount, bool immutable) override - { - bool inMultisample = - inSampleCount > 1 && m_RenderContext->AreMultisampleTexturesSupported(); - for (QT3DSU32 idx = 0, end = m_FreeTextures.size(); idx < end; ++idx) { - NVRenderTexture2D *theTexture = m_FreeTextures[idx]; - STextureDetails theDetails = theTexture->GetTextureDetails(); - if (theDetails.m_Width == inWidth && theDetails.m_Height == inHeight - && inTextureFormat == theDetails.m_Format - && theTexture->GetSampleCount() == inSampleCount) { - m_FreeTextures.replace_with_last(idx); - return SetupAllocatedTexture(*theTexture); - } - } - // else resize an existing texture. This is very expensive - // note that MSAA textures are not resizable ( in GLES ) - /* - if ( !m_FreeTextures.empty() && !inMultisample ) - { - NVRenderTexture2D* theTexture = m_FreeTextures.back(); - m_FreeTextures.pop_back(); - - // note we could re-use a former MSAA texture - // this causes a entiere destroy of the previous texture object - theTexture->SetTextureData( NVDataRef(), 0, inWidth, inHeight, inTextureFormat - ); - - return SetupAllocatedTexture( *theTexture ); - }*/ - // else create a new texture. - NVRenderTexture2D *theTexture = m_RenderContext->CreateTexture2D(); - - if (inMultisample) - theTexture->SetTextureDataMultisample(inSampleCount, inWidth, inHeight, - inTextureFormat); - else if (immutable) - theTexture->SetTextureStorage(1, inWidth, inHeight, inTextureFormat); - else - theTexture->SetTextureData(NVDataRef(), 0, inWidth, inHeight, inTextureFormat); - - m_AllocatedObjects.push_back(theTexture); - return SetupAllocatedTexture(*theTexture); - } - void Release(NVRenderTexture2D &inBuffer) override - { -#ifdef _DEBUG - nvvector::iterator theFind = - eastl::find(m_FreeTextures.begin(), m_FreeTextures.end(), &inBuffer); - QT3DS_ASSERT(theFind == m_FreeTextures.end()); -#endif - m_FreeTextures.push_back(&inBuffer); - } - - NVRenderTexture2DArray *AllocateTexture2DArray(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 inSlices, - NVRenderTextureFormats::Enum inTextureFormat, - QT3DSU32 inSampleCount) override - { - bool inMultisample = - inSampleCount > 1 && m_RenderContext->AreMultisampleTexturesSupported(); - for (QT3DSU32 idx = 0, end = m_FreeTexArrays.size(); idx < end; ++idx) { - NVRenderTexture2DArray *theTexture = m_FreeTexArrays[idx]; - STextureDetails theDetails = theTexture->GetTextureDetails(); - if (theDetails.m_Width == inWidth && theDetails.m_Height == inHeight - && theDetails.m_Depth == inSlices && inTextureFormat == theDetails.m_Format - && theTexture->GetSampleCount() == inSampleCount) { - m_FreeTexArrays.replace_with_last(idx); - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return theTexture; - } - } - - // else resize an existing texture. This should be fairly quick at the driver level. - // note that MSAA textures are not resizable ( in GLES ) - if (!m_FreeTexArrays.empty() && !inMultisample) { - NVRenderTexture2DArray *theTexture = m_FreeTexArrays.back(); - m_FreeTexArrays.pop_back(); - - // note we could re-use a former MSAA texture - // this causes a entiere destroy of the previous texture object - theTexture->SetTextureData(NVDataRef(), 0, inWidth, inHeight, inSlices, - inTextureFormat); - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return theTexture; - } - - // else create a new texture. - NVRenderTexture2DArray *theTexture = NULL; - - if (!inMultisample) { - theTexture = m_RenderContext->CreateTexture2DArray(); - theTexture->SetTextureData(NVDataRef(), 0, inWidth, inHeight, inSlices, - inTextureFormat); - } else { - // Not supported yet - return NULL; - } - - m_AllocatedObjects.push_back(theTexture); - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return theTexture; - } - - void Release(NVRenderTexture2DArray &inBuffer) override - { -#ifdef _DEBUG - nvvector::iterator theFind = - eastl::find(m_FreeTexArrays.begin(), m_FreeTexArrays.end(), &inBuffer); - QT3DS_ASSERT(theFind == m_FreeTexArrays.end()); -#endif - m_FreeTexArrays.push_back(&inBuffer); - } - - NVRenderTextureCube *AllocateTextureCube(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inTextureFormat, - QT3DSU32 inSampleCount) override - { - bool inMultisample = - inSampleCount > 1 && m_RenderContext->AreMultisampleTexturesSupported(); - for (QT3DSU32 idx = 0, end = m_FreeTexCubes.size(); idx < end; ++idx) { - NVRenderTextureCube *theTexture = m_FreeTexCubes[idx]; - STextureDetails theDetails = theTexture->GetTextureDetails(); - if (theDetails.m_Width == inWidth && theDetails.m_Height == inHeight - && inTextureFormat == theDetails.m_Format - && theTexture->GetSampleCount() == inSampleCount) { - m_FreeTexCubes.replace_with_last(idx); - - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return theTexture; - } - } - - // else resize an existing texture. This should be fairly quick at the driver level. - // note that MSAA textures are not resizable ( in GLES ) - if (!m_FreeTexCubes.empty() && !inMultisample) { - NVRenderTextureCube *theTexture = m_FreeTexCubes.back(); - m_FreeTexCubes.pop_back(); - - // note we could re-use a former MSAA texture - // this causes a entire destroy of the previous texture object - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosX, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegX, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosY, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegY, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosZ, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegZ, - inWidth, inHeight, inTextureFormat); - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return theTexture; - } - - // else create a new texture. - NVRenderTextureCube *theTexture = NULL; - - if (!inMultisample) { - theTexture = m_RenderContext->CreateTextureCube(); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosX, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegX, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosY, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegY, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosZ, - inWidth, inHeight, inTextureFormat); - theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegZ, - inWidth, inHeight, inTextureFormat); - } else { - // Not supported yet - return NULL; - } - - m_AllocatedObjects.push_back(theTexture); - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - return theTexture; - } - - void Release(NVRenderTextureCube &inBuffer) override - { -#ifdef _DEBUG - nvvector::iterator theFind = - eastl::find(m_FreeTexCubes.begin(), m_FreeTexCubes.end(), &inBuffer); - QT3DS_ASSERT(theFind == m_FreeTexCubes.end()); -#endif - m_FreeTexCubes.push_back(&inBuffer); - } - - NVRenderImage2D *AllocateImage2D(NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) override - { - if (m_FreeImages.empty() == true) { - NVRenderImage2D *newImage = m_RenderContext->CreateImage2D(inTexture, inAccess); - if (newImage) { - m_AllocatedObjects.push_back(newImage); - m_FreeImages.push_back(newImage); - } - } - - NVRenderImage2D *retval = m_FreeImages.back(); - m_FreeImages.pop_back(); - - return retval; - } - - void Release(NVRenderImage2D &inBuffer) override - { -#ifdef _DEBUG - nvvector::iterator theFind = - eastl::find(m_FreeImages.begin(), m_FreeImages.end(), &inBuffer); - QT3DS_ASSERT(theFind == m_FreeImages.end()); -#endif - m_FreeImages.push_back(&inBuffer); - } - - NVRenderContext &GetRenderContext() override { return *m_RenderContext; } - - void RemoveObjectAllocation(NVRefCounted *obj) { - for (QT3DSU32 idx = 0, end = m_AllocatedObjects.size(); idx < end; ++idx) { - if (obj == m_AllocatedObjects[idx]) { - m_AllocatedObjects.replace_with_last(idx); - break; - } - } - } - - void DestroyFreeSizedResources() - { - for (int idx = m_FreeRenderBuffers.size() - 1; idx >= 0; --idx) { - NVRenderRenderBuffer *obj = m_FreeRenderBuffers[idx]; - m_FreeRenderBuffers.replace_with_last(idx); - RemoveObjectAllocation(obj); - } - for (int idx = m_FreeTextures.size() - 1; idx >= 0; --idx) { - NVRenderTexture2D *obj = m_FreeTextures[idx]; - m_FreeTextures.replace_with_last(idx); - RemoveObjectAllocation(obj); - } - for (int idx = m_FreeTexArrays.size() - 1; idx >= 0; --idx) { - NVRenderTexture2DArray *obj = m_FreeTexArrays[idx]; - m_FreeTexArrays.replace_with_last(idx); - RemoveObjectAllocation(obj); - } - for (int idx = m_FreeTexCubes.size() - 1; idx >= 0; --idx) { - NVRenderTextureCube *obj = m_FreeTexCubes[idx]; - m_FreeTexCubes.replace_with_last(idx); - RemoveObjectAllocation(obj); - } - } -}; -} - -IResourceManager &IResourceManager::CreateResourceManager(NVRenderContext &inContext) -{ - return *QT3DS_NEW(inContext.GetAllocator(), SResourceManager)(inContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.h deleted file mode 100644 index 675d644c..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceManager.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_RESOURCE_MANAGER_H -#define QT3DS_RENDER_RESOURCE_MANAGER_H -#include "Qt3DSRender.h" -#include "foundation/Qt3DSRefCounted.h" -#include "render/Qt3DSRenderBaseTypes.h" - -namespace qt3ds { -namespace render { - /** - * Implements simple pooling of render resources - */ - class IResourceManager : public NVRefCounted - { - protected: - virtual ~IResourceManager() {} - - public: - virtual NVRenderFrameBuffer *AllocateFrameBuffer() = 0; - virtual void Release(NVRenderFrameBuffer &inBuffer) = 0; - virtual NVRenderRenderBuffer * - AllocateRenderBuffer(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderRenderBufferFormats::Enum inBufferFormat) = 0; - virtual void Release(NVRenderRenderBuffer &inBuffer) = 0; - virtual NVRenderTexture2D *AllocateTexture2D(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inTextureFormat, - QT3DSU32 inSampleCount = 1, - bool immutable = false) = 0; - virtual void Release(NVRenderTexture2D &inBuffer) = 0; - virtual NVRenderTexture2DArray * - AllocateTexture2DArray(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 inSlices, - NVRenderTextureFormats::Enum inTextureFormat, - QT3DSU32 inSampleCount = 1) = 0; - virtual void Release(NVRenderTexture2DArray &inBuffer) = 0; - virtual NVRenderTextureCube * - AllocateTextureCube(QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inTextureFormat, - QT3DSU32 inSampleCount = 1) = 0; - virtual void Release(NVRenderTextureCube &inBuffer) = 0; - virtual NVRenderImage2D *AllocateImage2D(NVRenderTexture2D *inTexture, - NVRenderImageAccessType::Enum inAccess) = 0; - virtual void Release(NVRenderImage2D &inBuffer) = 0; - - virtual NVRenderContext &GetRenderContext() = 0; - virtual void DestroyFreeSizedResources() = 0; - - static IResourceManager &CreateResourceManager(NVRenderContext &inContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.cpp deleted file mode 100644 index e877cbc9..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderResourceTexture2D.h" - -using namespace qt3ds::render; - -CResourceTexture2D::CResourceTexture2D(IResourceManager &mgr, NVRenderTexture2D *inTexture) - : m_ResourceManager(mgr) - , m_Texture(inTexture) -{ - if (inTexture) - m_TextureDetails = inTexture->GetTextureDetails(); -} - -CResourceTexture2D::CResourceTexture2D(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) - : m_ResourceManager(mgr) - , m_Texture(NULL) -{ - EnsureTexture(width, height, inFormat, inSamples); -} - -CResourceTexture2D::~CResourceTexture2D() -{ - ReleaseTexture(); -} - -// Returns true if the texture was allocated, false if nothing changed (no allocation). -bool CResourceTexture2D::TextureMatches(QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) -{ - return m_Texture && m_TextureDetails.m_Width == width && m_TextureDetails.m_Height == height - && m_TextureDetails.m_Format == inFormat && m_TextureDetails.m_SampleCount == inSamples; -} - -bool CResourceTexture2D::EnsureTexture(QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) -{ - if (TextureMatches(width, height, inFormat, inSamples)) - return false; - - if (m_Texture && inSamples > 1) { - // we cannot resize MSAA textures though release first - ReleaseTexture(); - } - - if (!m_Texture) - m_Texture = m_ResourceManager.AllocateTexture2D(width, height, inFormat, inSamples); - else { - // multisampled textures are immuteable - QT3DS_ASSERT(inSamples == 1); - m_Texture->SetTextureData(NVDataRef(), 0, width, height, inFormat); - } - - m_TextureDetails = m_Texture->GetTextureDetails(); - return true; -} - -void CResourceTexture2D::ReleaseTexture() -{ - if (m_Texture) { - m_ResourceManager.Release(*m_Texture); - ForgetTexture(); - } -} - -void CResourceTexture2D::ForgetTexture() -{ - m_Texture = NULL; -} - -void CResourceTexture2D::StealTexture(CResourceTexture2D &inOther) -{ - ReleaseTexture(); - m_Texture = inOther.m_Texture; - m_TextureDetails = inOther.m_TextureDetails; - inOther.m_Texture = NULL; -} - -CResourceTexture2DArray::CResourceTexture2DArray(IResourceManager &mgr) - : m_ResourceManager(mgr) - , m_Texture(NULL) -{ -} - -CResourceTexture2DArray::CResourceTexture2DArray(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, - QT3DSU32 slices, - NVRenderTextureFormats::Enum inFormat, - QT3DSU32 inSamples) - : m_ResourceManager(mgr) - , m_Texture(NULL) -{ - EnsureTexture(width, height, slices, inFormat, inSamples); -} - -CResourceTexture2DArray::~CResourceTexture2DArray() -{ - ReleaseTexture(); -} - -bool CResourceTexture2DArray::TextureMatches(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) -{ - return m_Texture && m_TextureDetails.m_Depth == slices && m_TextureDetails.m_Width == width - && m_TextureDetails.m_Height == height && m_TextureDetails.m_Format == inFormat - && m_TextureDetails.m_SampleCount == inSamples; -} - -bool CResourceTexture2DArray::EnsureTexture(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) -{ - if (TextureMatches(width, height, slices, inFormat, inSamples)) - return false; - - if (m_Texture && inSamples > 1) { - // we cannot resize MSAA textures though release first - ReleaseTexture(); - } - - if (!m_Texture) - m_Texture = - m_ResourceManager.AllocateTexture2DArray(width, height, slices, inFormat, inSamples); - else { - // multisampled textures are immuteable - QT3DS_ASSERT(inSamples == 1); - m_Texture->SetTextureData(NVDataRef(), 0, width, height, slices, inFormat); - } - - m_TextureDetails = m_Texture->GetTextureDetails(); - return true; -} - -void CResourceTexture2DArray::ReleaseTexture() -{ - if (m_Texture) { - m_ResourceManager.Release(*m_Texture); - m_Texture = NULL; - } -} - -void CResourceTexture2DArray::StealTexture(CResourceTexture2DArray &inOther) -{ - ReleaseTexture(); - m_Texture = inOther.m_Texture; - m_TextureDetails = inOther.m_TextureDetails; - inOther.m_Texture = NULL; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.h deleted file mode 100644 index eb54713a..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderResourceTexture2D.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_RENDER_RESOURCE_TEXTURE_2D_H -#define QT3DS_RENDER_RESOURCE_TEXTURE_2D_H -#include "Qt3DSRender.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderTexture2DArray.h" -#include "Qt3DSRenderResourceManager.h" - -namespace qt3ds { -namespace render { - class CResourceTexture2D - { - protected: - IResourceManager &m_ResourceManager; - NVRenderTexture2D *m_Texture; - STextureDetails m_TextureDetails; - - public: - CResourceTexture2D(IResourceManager &mgr, NVRenderTexture2D *inTexture = NULL); - // create and allocate the texture right away. - CResourceTexture2D(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); - ~CResourceTexture2D(); - // Returns true if the texture matches the specs, false if the texture needs to be - // reallocated - bool TextureMatches(QT3DSU32 width, QT3DSU32 height, NVRenderTextureFormats::Enum inFormat, - QT3DSU32 inSamples = 1); - - // Returns true if the texture was allocated, false if nothing changed (no allocation). - // Note this is the exact opposite of TextureMatches. - bool EnsureTexture(QT3DSU32 width, QT3DSU32 height, NVRenderTextureFormats::Enum inFormat, - QT3DSU32 inSamples = 1); - - // Force release the texture. - void ReleaseTexture(); - NVRenderTexture2D &operator*() - { - QT3DS_ASSERT(m_Texture); - return *m_Texture; - } - NVRenderTexture2D *operator->() - { - QT3DS_ASSERT(m_Texture); - return m_Texture; - } - operator NVRenderTexture2D *() { return m_Texture; } - NVRenderTexture2D *GetTexture() { return m_Texture; } - void ForgetTexture(); - // Enforces single ownership rules. - void StealTexture(CResourceTexture2D &inOther); - }; - - class CResourceTexture2DArray - { - protected: - IResourceManager &m_ResourceManager; - qt3ds::render::NVRenderTexture2DArray *m_Texture; - STextureDetails m_TextureDetails; - - public: - CResourceTexture2DArray(IResourceManager &mgr); - // create and allocate the texture right away. - CResourceTexture2DArray(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); - ~CResourceTexture2DArray(); - // Returns true if the texture matches the specs, false if the texture needs to be - // reallocated - bool TextureMatches(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); - - // Returns true if the texture was allocated, false if nothing changed (no allocation). - // Note this is the exact opposite of TextureMatches. - bool EnsureTexture(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, - NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); - - // Force release the texture. - void ReleaseTexture(); - qt3ds::render::NVRenderTexture2DArray &operator*() - { - QT3DS_ASSERT(m_Texture); - return *m_Texture; - } - qt3ds::render::NVRenderTexture2DArray *operator->() - { - QT3DS_ASSERT(m_Texture); - return m_Texture; - } - operator qt3ds::render::NVRenderTexture2DArray *() { return m_Texture; } - qt3ds::render::NVRenderTexture2DArray *GetTexture() { return m_Texture; } - // Enforces single ownership rules. - void StealTexture(CResourceTexture2DArray &inOther); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOffscreenRenderManager.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOffscreenRenderManager.cpp deleted file mode 100644 index 7d66c7a3..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOffscreenRenderManager.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSOffscreenRenderManager.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/StringTable.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "Qt3DSRenderResourceManager.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSOffscreenRenderKey.h" -#include "foundation/FastAllocator.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRenderResourceTexture2D.h" -#include "Qt3DSRenderResourceBufferObjects.h" -#include "Qt3DSRendererUtil.h" - -using namespace qt3ds::render; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SOffscreenRendererKey &key) const - { - switch (key.getType()) { - case OffscreenRendererKeyTypes::RegisteredString: - return hash()(key.getData()); - case OffscreenRendererKeyTypes::VoidPtr: - return hash()(reinterpret_cast(key.getData())); - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - bool operator()(const SOffscreenRendererKey &lhs, const SOffscreenRendererKey &rhs) const - { - return lhs == rhs; - } -}; -} - -namespace { - -using eastl::pair; -using eastl::make_pair; - -struct SRendererData : SOffscreenRenderResult -{ - NVAllocatorCallback &m_Allocator; - IResourceManager &m_ResourceManager; - QT3DSU32 m_FrameCount; - bool m_Rendering; - - SRendererData(NVAllocatorCallback &inAllocator, IResourceManager &inResourceManager) - : m_Allocator(inAllocator) - , m_ResourceManager(inResourceManager) - , m_FrameCount(QT3DS_MAX_U32) - , m_Rendering(false) - { - } - ~SRendererData() - { - if (m_Texture) - m_ResourceManager.Release(*m_Texture); - m_Texture = NULL; - } - void Release() { NVDelete(m_Allocator, this); } -}; - -struct SScopedRenderDataRenderMarker -{ - SRendererData &m_Data; - SScopedRenderDataRenderMarker(SRendererData &d) - : m_Data(d) - { - QT3DS_ASSERT(m_Data.m_Rendering == false); - m_Data.m_Rendering = true; - } - ~SScopedRenderDataRenderMarker() { m_Data.m_Rendering = false; } -}; - -struct SRenderDataReleaser -{ - SRendererData *mPtr; - SRenderDataReleaser(SRendererData *inItem) - : mPtr(inItem) - { - } - // Transfer ownership - SRenderDataReleaser(const SRenderDataReleaser &inOther) - : mPtr(inOther.mPtr) - { - const_cast(inOther).mPtr = NULL; - } - - ~SRenderDataReleaser() - { - if (mPtr) - mPtr->Release(); - } -}; -struct SOffscreenRenderManager; - -struct SOffscreenRunnable : public IRenderTask -{ - SOffscreenRenderManager &m_RenderManager; - SRendererData &m_Data; - SOffscreenRendererEnvironment m_DesiredEnvironment; - SOffscreenRunnable(SOffscreenRenderManager &rm, SRendererData &data, - SOffscreenRendererEnvironment env) - : m_RenderManager(rm) - , m_Data(data) - , m_DesiredEnvironment(env) - { - } - void Run() override; -}; - -struct SOffscreenRenderManager : public IOffscreenRenderManager -{ - typedef nvhash_map TRendererMap; - IQt3DSRenderContext &m_Context; - NVAllocatorCallback &m_Allocator; - NVScopedRefCounted m_StringTable; - NVScopedRefCounted m_ResourceManager; - TRendererMap m_Renderers; - SFastAllocator<> m_PerFrameAllocator; - QT3DSU32 m_FrameCount; // cheap per- - - volatile QT3DSI32 mRefCount; - - SOffscreenRenderManager(NVAllocatorCallback &inCallback, IStringTable &inStringTable, - IResourceManager &inManager, IQt3DSRenderContext &inContext) - : m_Context(inContext) - , m_Allocator(inCallback) - , m_StringTable(inStringTable) - , m_ResourceManager(inManager) - , m_Renderers(inCallback, "SOffscreenRenderManager::m_Renderers") - , m_PerFrameAllocator(inCallback, "m_PerFrameAllocator") - , m_FrameCount(0) - , mRefCount(0) - { - } - - virtual ~SOffscreenRenderManager() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Allocator) - - Option MaybeRegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, - IOffscreenRenderer &inRenderer) override - { - TRendererMap::iterator theIter = m_Renderers.find(inKey); - if (theIter != m_Renderers.end()) { - SRendererData &theData = *(theIter->second.mPtr); - if (theData.m_Renderer != &inRenderer) { - if (inKey.getType() == OffscreenRendererKeyTypes::RegisteredString) { - qCCritical(INVALID_OPERATION, "Different renderers registered under same key: %s", - inKey.getData().c_str()); - } - QT3DS_ASSERT(false); - return Empty(); - } - return false; - } - RegisterOffscreenRenderer(inKey, inRenderer); - return true; - } - - void RegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, - IOffscreenRenderer &inRenderer) override - { - pair theInsert = m_Renderers.insert( - make_pair(inKey, QT3DS_NEW(m_Allocator, SRendererData)(m_Allocator, *m_ResourceManager))); - QT3DS_ASSERT(theInsert.second); - SRendererData &theData = *(theInsert.first->second.mPtr); - theData.m_Renderer = &inRenderer; - } - - bool HasOffscreenRenderer(const SOffscreenRendererKey &inKey) override - { - return m_Renderers.find(inKey) != m_Renderers.end(); - } - - IOffscreenRenderer *GetOffscreenRenderer(const SOffscreenRendererKey &inKey) override - { - TRendererMap::iterator theRenderer = m_Renderers.find(inKey); - if (theRenderer != m_Renderers.end()) { - SRendererData &theData = *theRenderer->second.mPtr; - return theData.m_Renderer; - } - return NULL; - } - void ReleaseOffscreenRenderer(const SOffscreenRendererKey &inKey) override - { - m_Renderers.erase(inKey); - } - - void RenderItem(SRendererData &theData, SOffscreenRendererEnvironment theDesiredEnvironment) - { - NVRenderContext &theContext = m_ResourceManager->GetRenderContext(); - QT3DSVec2 thePresScaleFactor = m_Context.GetPresentationScaleFactor(); - SOffscreenRendererEnvironment theOriginalDesiredEnvironment(theDesiredEnvironment); - // Ensure that our overall render context comes back no matter what the client does. - qt3ds::render::NVRenderContextScopedProperty __clearColor( - theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - QT3DSVec4(0, 0, 0, 0)); - qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, false); - qt3ds::render::NVRenderContextScopedProperty __scissorRect( - theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); - qt3ds::render::NVRenderContextScopedProperty __viewportRect( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - qt3ds::render::NVRenderContextScopedProperty __depthWrite( - theContext, &NVRenderContext::IsDepthWriteEnabled, - &NVRenderContext::SetDepthWriteEnabled, false); - qt3ds::render::NVRenderContextScopedProperty __depthFunction( - theContext, &NVRenderContext::GetDepthFunction, &NVRenderContext::SetDepthFunction, - qt3ds::render::NVRenderBoolOp::Less); - qt3ds::render::NVRenderContextScopedProperty __blendEnabled( - theContext, &NVRenderContext::IsBlendingEnabled, &NVRenderContext::SetBlendingEnabled, - false); - qt3ds::render::NVRenderContextScopedProperty - __blendFunction(theContext, &NVRenderContext::GetBlendFunction, - &NVRenderContext::SetBlendFunction, - qt3ds::render::NVRenderBlendFunctionArgument()); - qt3ds::render::NVRenderContextScopedProperty - __blendEquation(theContext, &NVRenderContext::GetBlendEquation, - &NVRenderContext::SetBlendEquation, - qt3ds::render::NVRenderBlendEquationArgument()); - qt3ds::render::NVRenderContextScopedProperty - __rendertarget(theContext, &NVRenderContext::GetRenderTarget, - &NVRenderContext::SetRenderTarget); - - QT3DSU32 theSampleCount = 1; - bool isMultisamplePass = false; - if (theDesiredEnvironment.m_MSAAMode != AAModeValues::NoAA) { - switch (theDesiredEnvironment.m_MSAAMode) { - case AAModeValues::SSAA: - theSampleCount = 1; - isMultisamplePass = true; - break; - case AAModeValues::X2: - theSampleCount = 2; - isMultisamplePass = true; - break; - case AAModeValues::X4: - theSampleCount = 4; - isMultisamplePass = true; - break; - case AAModeValues::X8: - theSampleCount = 8; - isMultisamplePass = true; - break; - default: - QT3DS_ASSERT(false); - break; - }; - - // adjust render size for SSAA - if (theDesiredEnvironment.m_MSAAMode == AAModeValues::SSAA) { - CRendererUtil::GetSSAARenderSize( - theOriginalDesiredEnvironment.m_Width, theOriginalDesiredEnvironment.m_Height, - theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height); - } - } - CResourceFrameBuffer theFrameBuffer(*m_ResourceManager); - theFrameBuffer.EnsureFrameBuffer(); - NVRenderTexture2D *renderTargetTexture(theData.m_Texture); - qt3ds::render::NVRenderTextureTargetType::Enum fboAttachmentType = - qt3ds::render::NVRenderTextureTargetType::Texture2D; - if (isMultisamplePass) { - renderTargetTexture = NULL; - if (theSampleCount > 1) - fboAttachmentType = qt3ds::render::NVRenderTextureTargetType::Texture2D_MS; - } - - CResourceTexture2D renderColorTexture(*m_ResourceManager, renderTargetTexture); - - CResourceTexture2D renderDepthStencilTexture(*m_ResourceManager); - - if (theSampleCount > 1) - m_Context.GetRenderContext().SetMultisampleEnabled(true); - - qt3ds::render::NVRenderClearFlags theClearFlags; - NVRenderTextureFormats::Enum theDepthStencilTextureFormat(NVRenderTextureFormats::Unknown); - NVRenderFrameBufferAttachments::Enum theAttachmentLocation( - NVRenderFrameBufferAttachments::Unknown); - if (theDesiredEnvironment.m_Stencil) { - theDepthStencilTextureFormat = NVRenderTextureFormats::Depth24Stencil8; - theAttachmentLocation = NVRenderFrameBufferAttachments::DepthStencil; - } else if (theDesiredEnvironment.m_Depth != OffscreenRendererDepthValues::NoDepthBuffer) { - theAttachmentLocation = NVRenderFrameBufferAttachments::Depth; - switch (theDesiredEnvironment.m_Depth) { - case OffscreenRendererDepthValues::Depth16: - theDepthStencilTextureFormat = NVRenderTextureFormats::Depth16; - break; - case OffscreenRendererDepthValues::Depth24: - theDepthStencilTextureFormat = NVRenderTextureFormats::Depth24; - break; - case OffscreenRendererDepthValues::Depth32: - theDepthStencilTextureFormat = NVRenderTextureFormats::Depth32; - break; - default: - theAttachmentLocation = NVRenderFrameBufferAttachments::Unknown; - theDepthStencilTextureFormat = NVRenderTextureFormats::Unknown; - break; - } - } - renderColorTexture.EnsureTexture(theDesiredEnvironment.m_Width, - theDesiredEnvironment.m_Height, - theDesiredEnvironment.m_Format, theSampleCount); - theFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *renderColorTexture, - fboAttachmentType); - - if (theDepthStencilTextureFormat != NVRenderTextureFormats::Unknown) { - renderDepthStencilTexture.EnsureTexture(theDesiredEnvironment.m_Width, - theDesiredEnvironment.m_Height, - theDepthStencilTextureFormat, theSampleCount); - theFrameBuffer->Attach(theAttachmentLocation, *renderDepthStencilTexture, - fboAttachmentType); - } - // IsComplete check takes a really long time so I am not going to worry about it for now. - - theContext.SetRenderTarget(theFrameBuffer); - theContext.SetViewport( - NVRenderRect(0, 0, theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height)); - theContext.SetScissorTestEnabled(false); - - theContext.SetBlendingEnabled(false); - theData.m_Renderer->Render(theDesiredEnvironment, theContext, thePresScaleFactor, - SScene::AlwaysClear, this); - - if (theSampleCount > 1) { - CResourceTexture2D theResult(*m_ResourceManager, theData.m_Texture); - - if (theDesiredEnvironment.m_MSAAMode != AAModeValues::SSAA) { - // Have to downsample the FBO. - CRendererUtil::ResolveMutisampleFBOColorOnly( - *m_ResourceManager, theResult, m_Context.GetRenderContext(), - theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height, - theDesiredEnvironment.m_Format, *theFrameBuffer); - - m_Context.GetRenderContext().SetMultisampleEnabled(false); - } else { - // Resolve the FBO to the layer texture - CRendererUtil::ResolveSSAAFBOColorOnly( - *m_ResourceManager, theResult, theOriginalDesiredEnvironment.m_Width, - theOriginalDesiredEnvironment.m_Height, m_Context.GetRenderContext(), - theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height, - theDesiredEnvironment.m_Format, *theFrameBuffer); - } - - QT3DS_ASSERT(theData.m_Texture == theResult.GetTexture()); - theResult.ForgetTexture(); - } else { - renderColorTexture.ForgetTexture(); - } - theFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(), fboAttachmentType); - if (theAttachmentLocation != NVRenderFrameBufferAttachments::Unknown) - theFrameBuffer->Attach(theAttachmentLocation, NVRenderTextureOrRenderBuffer(), - fboAttachmentType); - } - - SOffscreenRenderResult GetRenderedItem(const SOffscreenRendererKey &inKey) override - { - TRendererMap::iterator theRenderer = m_Renderers.find(inKey); - QT3DSVec2 thePresScaleFactor = m_Context.GetPresentationScaleFactor(); - if (theRenderer != m_Renderers.end() && theRenderer->second.mPtr->m_Rendering == false) { - SRendererData &theData = *theRenderer->second.mPtr; - SScopedRenderDataRenderMarker __renderMarker(theData); - - bool renderedThisFrame = theData.m_Texture && theData.m_FrameCount == m_FrameCount; - theData.m_FrameCount = m_FrameCount; - // Two different quick-out pathways. - if (renderedThisFrame) - return theData; - - SOffscreenRendererEnvironment theDesiredEnvironment = - theData.m_Renderer->GetDesiredEnvironment(thePresScaleFactor); - // Ensure we get a valid width and height - theDesiredEnvironment.m_Width = - ITextRenderer::NextMultipleOf4(theDesiredEnvironment.m_Width); - theDesiredEnvironment.m_Height = - ITextRenderer::NextMultipleOf4(theDesiredEnvironment.m_Height); - if (theDesiredEnvironment.m_Width == 0 || theDesiredEnvironment.m_Height == 0) { - return SOffscreenRenderResult(); - } - - NVRenderRect theViewport(0, 0, theDesiredEnvironment.m_Width, - theDesiredEnvironment.m_Height); - IRenderList &theRenderList(m_Context.GetRenderList()); - NVRenderContext &theContext(m_Context.GetRenderContext()); - // This happens here because if there are any fancy render steps - SRenderListScopedProperty _scissor(theRenderList, - &IRenderList::IsScissorTestEnabled, - &IRenderList::SetScissorTestEnabled, false); - SRenderListScopedProperty _viewport( - theRenderList, &IRenderList::GetViewport, &IRenderList::SetViewport, theViewport); - // Some plugins don't use the render list so they need the actual gl context setup. - qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, false); - qt3ds::render::NVRenderContextScopedProperty __viewportRect( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, - theViewport); - - QT3DSU32 taskId = m_Context.GetRenderList().AddRenderTask( - *QT3DS_NEW(m_Context.GetPerFrameAllocator(), - SOffscreenRunnable)(*this, theData, theDesiredEnvironment)); - - SOffscreenRenderFlags theFlags = - theData.m_Renderer->NeedsRender(theDesiredEnvironment, thePresScaleFactor, this); - theData.m_HasTransparency = theFlags.m_HasTransparency; - theData.m_HasChangedSinceLastFrame = theFlags.m_HasChangedSinceLastFrame; - if (theData.m_Texture) { - // Quick-out if the renderer doesn't need to render itself. - if (theData.m_HasChangedSinceLastFrame == false) { - m_Context.GetRenderList().DiscardRenderTask(taskId); - return theData; - } - } else - theData.m_HasChangedSinceLastFrame = true; - - // Release existing texture if it doesn't match latest environment request. - if (theData.m_Texture) { - STextureDetails theDetails = theData.m_Texture->GetTextureDetails(); - if (theDesiredEnvironment.m_Width != theDetails.m_Width - || theDesiredEnvironment.m_Height != theDetails.m_Height - || theDesiredEnvironment.m_Format != theDetails.m_Format) { - m_ResourceManager->Release(*theData.m_Texture); - theData.m_Texture = NULL; - } - } - - if (theData.m_Texture == NULL) - theData.m_Texture = m_ResourceManager->AllocateTexture2D( - theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height, - theDesiredEnvironment.m_Format); - - // Add the node to the graph and get on with it. - - return theData; - } - return SOffscreenRenderResult(); - } - - void BeginFrame() override { m_PerFrameAllocator.reset(); } - void EndFrame() override { ++m_FrameCount; } -}; - -void SOffscreenRunnable::Run() -{ - m_RenderManager.RenderItem(m_Data, m_DesiredEnvironment); -} -} - -IOffscreenRenderManager &IOffscreenRenderManager::CreateOffscreenRenderManager( - NVAllocatorCallback &inCallback, IStringTable &inStringTable, IResourceManager &inManager, - IQt3DSRenderContext &inContext) -{ - return *QT3DS_NEW(inCallback, SOffscreenRenderManager)(inCallback, inStringTable, inManager, - inContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOldNBustedRenderPlugin.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOldNBustedRenderPlugin.cpp deleted file mode 100644 index 4028373b..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOldNBustedRenderPlugin.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSOldNBustedRenderPlugin.h" -#include "SystemPrefix.h" -#include "Qt3DSDLLManager.h" -#include "render/Qt3DSRenderContext.h" - -#ifdef WIN32 -#pragma warning(disable : 4355) // this used in initializer list. I have never seen this result in - // a physical error -#endif - -namespace qt3ds { -namespace render { - - COldNBustedPluginRenderer::COldNBustedPluginRenderer(IQt3DSRenderContext &inRenderContext, - long inDLLHandle) - : m_RenderContext(inRenderContext) - , m_DLLHandle(inDLLHandle) - , mRefCount(0) - , m_OffscreenRendererType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) - { - if (m_DLLHandle != -1) { - Q3DStudio::CDLLManager &theManager = Q3DStudio::CDLLManager::GetDLLManager(); - - // Grab function procs - m_GetTextureSizeProc = reinterpret_cast( - theManager.GetProc("GetDesiredTextureSize", m_DLLHandle)); - Q3DStudio_ASSERT(m_GetTextureSizeProc); - - m_RenderProc = reinterpret_cast(theManager.GetProc("Render", m_DLLHandle)); - Q3DStudio_ASSERT(m_RenderProc); - } - } - - NVRenderTextureFormats::Enum convertTextureFormat(ETEXTUREFORMAT fmt) - { - NVRenderTextureFormats::Enum ret = NVRenderTextureFormats::RGBA8; - switch (fmt) { - - case ETEXTUREFORMAT_RGBA8: - break; - - case ETEXTUREFORMAT_RGB8: - ret = NVRenderTextureFormats::RGB8; - break; - - default: - break; - - } - return ret; - } - - SOffscreenRendererEnvironment - COldNBustedPluginRenderer::GetDesiredEnvironment(QT3DSVec2 inPresScale) - { - long width, height; - ETEXTUREFORMAT format; - - m_GetTextureSizeProc(&width, &height, &format); - - return SOffscreenRendererEnvironment( - (QT3DSU32)(width * inPresScale.x), (QT3DSU32)(height * inPresScale.y), - convertTextureFormat(format), OffscreenRendererDepthValues::Depth24, false, - AAModeValues::NoAA); - } - - SOffscreenRenderFlags - COldNBustedPluginRenderer::NeedsRender(const SOffscreenRendererEnvironment & /*inEnvironment*/, - QT3DSVec2 /*inPresScale*/, - const SRenderInstanceId) - { - return SOffscreenRenderFlags(true, true); - } - - // Returns true if the rendered result image has transparency, or false - // if it should be treated as a completely opaque image. - void COldNBustedPluginRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 /*inPresScale*/, - SScene::RenderClearCommand /*inClearColorBuffer*/, - const SRenderInstanceId) - { - inRenderContext.PushPropertySet(); - - m_RenderProc(inEnvironment.m_Width, inEnvironment.m_Height, 1); - - inRenderContext.PopPropertySet(true); - } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOnscreenTextRenderer.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOnscreenTextRenderer.cpp deleted file mode 100644 index 4b74c511..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSOnscreenTextRenderer.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#define QT3DS_RENDER_ONSCREEN_TEXT -#ifdef QT3DS_RENDER_ONSCREEN_TEXT - -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderTextureAtlas.h" - -#include "EASTL/string.h" -#include "EASTL/hash_set.h" - -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/StrConvertUTF.h" - -#include "render/Qt3DSRenderContext.h" - -#include -#include -#include -#include - -using namespace qt3ds::render; - -namespace { - -struct STextureAtlasFontEntry -{ - STextureAtlasFontEntry() - : m_x(0) - , m_y(0) - , m_width(0) - , m_height(0) - , m_xOffset(0) - , m_yOffset(0) - , m_advance(0) - , m_s(0) - , m_t(0) - , m_s1(0) - , m_t1(0) - { - } - - STextureAtlasFontEntry(float x, float y, float width, float height, float xoffset, - float yoffset, float advance, float s, float t, float s1, float t1) - : m_x(x) - , m_y(y) - , m_width(width) - , m_height(height) - , m_xOffset(xoffset) - , m_yOffset(yoffset) - , m_advance(advance) - , m_s(s) - , m_t(t) - , m_s1(s1) - , m_t1(t1) - { - } - - QT3DSF32 m_x; - QT3DSF32 m_y; - QT3DSF32 m_width; - QT3DSF32 m_height; - QT3DSF32 m_xOffset; - QT3DSF32 m_yOffset; - QT3DSF32 m_advance; - - QT3DSF32 m_s; - QT3DSF32 m_t; - QT3DSF32 m_s1; - QT3DSF32 m_t1; -}; - -typedef eastl::basic_string TStrType; -typedef nvhash_map TTextureAtlasMap; - -struct STextAtlasFont -{ - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - QT3DSU32 m_FontSize; - TTextureAtlasMap m_AtlasEntries; ///< our entries in the atlas - - STextAtlasFont(NVFoundationBase &inFoundation, QT3DSU32 fontSize) - : m_Foundation(inFoundation) - , mRefCount(0) - , m_FontSize(fontSize) - , m_AtlasEntries(inFoundation.getAllocator(), - "Qt3DSOnscreenRenderer::STextAtlasFont::m_AtlasEntrys") - { - } - - ~STextAtlasFont() { m_AtlasEntries.clear(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - static STextAtlasFont &CreateTextureAtlasFont(NVFoundationBase &inFnd, QT3DSU32 fontSize) - { - return *QT3DS_NEW(inFnd.getAllocator(), STextAtlasFont)(inFnd, fontSize); - } -}; - -// This class is only for rendering 2D screen aligned text -// it uses a predefined true type font and character set with various sizes -struct Qt3DSOnscreenTextRenderer : public ITextRenderer -{ - - static const QT3DSI32 TEXTURE_ATLAS_DIM = - 256; // if you change this you need to adjust STextTextureAtlas size as well - -private: - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_RenderContext; - volatile QT3DSI32 mRefCount; - bool m_TextureAtlasInitialized; ///< true if atlas is setup - NVScopedRefCounted m_TextTextureAtlas; - NVScopedRefCounted m_TextFont; - QRawFont *m_font; -public: - Qt3DSOnscreenTextRenderer(NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , mRefCount(0) - , m_TextureAtlasInitialized(false) - , m_font(nullptr) - { - } - - virtual ~Qt3DSOnscreenTextRenderer() - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - void AddSystemFontDirectory(const char8_t *) override {} - - virtual void AddProjectFontDirectory(CRegisteredString) - { - // We always render using the default font with on-screen renderer, - // so no need to care about font directories - } - - void AddProjectFontDirectory(const char8_t *inProjectDirectory) override - { - if (m_RenderContext) - AddProjectFontDirectory( - m_RenderContext->GetStringTable().RegisterStr(inProjectDirectory)); - } - - void loadFont() - { - // Ensure font. We can only render text of single size at the moment. - // Add a size map of fonts if it ever becomes necessary to render multiple font sizes. - if (!m_font) - m_font = new QRawFont(QStringLiteral(":res/Font/TitilliumWeb-Regular.ttf"), 20.0); - - // setup texture atlas - m_TextTextureAtlas = - ITextureAtlas::CreateTextureAtlas(m_RenderContext->GetFoundation(), *m_RenderContext, - TEXTURE_ATLAS_DIM, TEXTURE_ATLAS_DIM); - - // our list of predefined cached characters - QString cache = QStringLiteral(" !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"); - - m_TextFont = STextAtlasFont::CreateTextureAtlasFont(m_Foundation, 20); - CreateTextureAtlasEntries(m_font, *m_TextFont, cache); - m_TextureAtlasInitialized = true; - } - - void CreateTextureAtlasEntries(QRawFont *rawFont, STextAtlasFont &font, const QString &cache) - { - if (m_TextureAtlasInitialized || !m_TextTextureAtlas || !rawFont) - return; - - STextureAtlasRect theAtlasRect; - - QVector glyphIndices = rawFont->glyphIndexesForString(cache); - QVector glyphAdvances = rawFont->advancesForGlyphIndexes(glyphIndices); - - for (int i = 0; i < glyphIndices.size(); i++) { - quint32 index = glyphIndices[i]; - QImage glyphImage; - - // blank char is not contained in a true type font - if (cache.at(i) != QChar(' ')) - glyphImage = rawFont->alphaMapForGlyph(index, QRawFont::PixelAntialiasing); - - QRectF rect = rawFont->boundingRect(index); - NVConstDataRef bufferData(static_cast(glyphImage.bits()), - glyphImage.byteCount()); - - theAtlasRect = m_TextTextureAtlas->AddAtlasEntry( - glyphImage.width(), glyphImage.height(), - glyphImage.bytesPerLine(), glyphImage.width(), bufferData); - - if (theAtlasRect.m_Width != 0) { - font.m_AtlasEntries.insert( - eastl::make_pair( - cache.at(i).unicode(), STextureAtlasFontEntry( - (QT3DSF32)theAtlasRect.m_X, (QT3DSF32)theAtlasRect.m_Y, - (QT3DSF32)theAtlasRect.m_Width, (QT3DSF32)theAtlasRect.m_Height, - (QT3DSF32)rect.x(), (QT3DSF32)(0.0 - rect.height() - rect.y()), - glyphAdvances[i].x(), - theAtlasRect.m_NormX, theAtlasRect.m_NormY, - theAtlasRect.m_NormX + theAtlasRect.m_NormWidth, - theAtlasRect.m_NormY + theAtlasRect.m_NormHeight))); - } - } - } - - void ClearProjectFontDirectories() override {} - - ITextRenderer &GetTextRenderer(NVRenderContext &inRenderContext) override - { - m_RenderContext = inRenderContext; - return *this; - } - - void PreloadFonts() override {} - void ReloadFonts() override {} - - // unused - NVConstDataRef GetProjectFontList() override - { - Q_ASSERT(false); - return NVConstDataRef(); - } - - // unused - Option GetFontNameForFont(CRegisteredString) override - { - Q_ASSERT(false); - return Empty(); - } - - // unused - Option GetFontNameForFont(const char8_t *) override - { - Q_ASSERT(false); - return Empty(); - } - - // unused - STextDimensions MeasureText(const STextRenderInfo &, QT3DSF32, const char8_t *) override - { - Q_ASSERT(false); - return STextDimensions(0, 0); - } - - // unused - STextTextureDetails RenderText(const STextRenderInfo &, NVRenderTexture2D &) override - { - QT3DS_ASSERT(false); - return STextTextureDetails(); - } - - // unused - STextTextureDetails RenderText(const STextRenderInfo &, NVRenderPathFontItem &, - NVRenderPathFontSpecification &) override - { - QT3DS_ASSERT(false); - return STextTextureDetails(); - } - - SRenderTextureAtlasDetails RenderText(const STextRenderInfo &inText) override - { - qt3ds::foundation::IStringTable &theStringTable(m_RenderContext->GetStringTable()); - - const wchar_t *wText = theStringTable.GetWideStr(inText.m_Text); - QT3DSU32 length = (QT3DSU32)wcslen(wText); - - if (length) { - STextAtlasFont *pFont = m_TextFont; - const STextureAtlasFontEntry *pEntry; - QT3DSF32 x1, y1, x2, y2; - QT3DSF32 s, t, s1, t1; - QT3DSF32 advance = 0.0; - // allocate buffer for all the vertex data we need - // we construct triangles here - // which means character count x 6 vertices x 5 floats - QT3DSF32 *vertexData = - (QT3DSF32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), - length * 6 * 5 * sizeof(QT3DSF32), - "Qt3DSOnscreenTextRenderer"); - QT3DSF32 *bufPtr = vertexData; - if (vertexData) { - for (size_t i = 0; i < length; ++i) { - pEntry = &pFont->m_AtlasEntries.find(wText[i])->second; - - if (pEntry) { - x1 = advance + pEntry->m_xOffset; - x2 = x1 + pEntry->m_width * inText.m_ScaleX; - y1 = pEntry->m_yOffset; - y2 = y1 + pEntry->m_height * inText.m_ScaleY; - - s = pEntry->m_s; - s1 = pEntry->m_s1; - t = pEntry->m_t; - t1 = pEntry->m_t1; - // store vertex data - bufPtr[0] = x1; - bufPtr[1] = y1; - bufPtr[2] = 0.0; - bufPtr[3] = s; - bufPtr[4] = t; - bufPtr[5] = x2; - bufPtr[6] = y1; - bufPtr[7] = 0.0; - bufPtr[8] = s1; - bufPtr[9] = t; - bufPtr[10] = x2; - bufPtr[11] = y2; - bufPtr[12] = 0.0; - bufPtr[13] = s1; - bufPtr[14] = t1; - - bufPtr[15] = x1; - bufPtr[16] = y1; - bufPtr[17] = 0.0; - bufPtr[18] = s; - bufPtr[19] = t; - bufPtr[20] = x2; - bufPtr[21] = y2; - bufPtr[22] = 0.0; - bufPtr[23] = s1; - bufPtr[24] = t1; - bufPtr[25] = x1; - bufPtr[26] = y2; - bufPtr[27] = 0.0; - bufPtr[28] = s; - bufPtr[29] = t1; - - advance += pEntry->m_advance * inText.m_ScaleX; - - bufPtr += 30; - } - } - - m_TextTextureAtlas->RelaseEntries(); - - return SRenderTextureAtlasDetails(length * 6, - toU8DataRef(vertexData, length * 6 * 5)); - } - } - - return SRenderTextureAtlasDetails(); - } - - STextTextureAtlasEntryDetails RenderAtlasEntry(QT3DSU32 index, - NVRenderTexture2D &inTexture) override - { - if (m_TextTextureAtlas) { - TTextureAtlasEntryAndBuffer theEntry = m_TextTextureAtlas->GetAtlasEntryByIndex(index); - if (theEntry.first.m_Width) { - inTexture.SetTextureData(theEntry.second, 0, theEntry.first.m_Width, - theEntry.first.m_Height, NVRenderTextureFormats::Alpha8); - inTexture.SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - inTexture.SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - inTexture.SetTextureWrapS(qt3ds::render::NVRenderTextureCoordOp::ClampToEdge); - inTexture.SetTextureWrapT(qt3ds::render::NVRenderTextureCoordOp::ClampToEdge); - STextureDetails theTextureDetails = inTexture.GetTextureDetails(); - return STextTextureAtlasEntryDetails(theTextureDetails.m_Width, - theTextureDetails.m_Height, theEntry.first.m_X, - theEntry.first.m_Y); - } - } - - return STextTextureAtlasEntryDetails(); - } - QT3DSI32 CreateTextureAtlas() override - { - loadFont(); - - QT3DSI32 count = 0; - if (m_TextTextureAtlas) - count = m_TextTextureAtlas->GetAtlasEntryCount(); - - return count; - } - - void BeginFrame() override {} - void EndFrame() override {} - void BeginPreloadFonts(IThreadPool &, IPerfTimer &) override {} - void EndPreloadFonts() override {} -}; -} - -ITextRendererCore &ITextRendererCore::CreateOnscreenTextRenderer(NVFoundationBase &inFnd) -{ - return *QT3DS_NEW(inFnd.getAllocator(), Qt3DSOnscreenTextRenderer)(inFnd); -} - -#endif // QT3DS_RENDER_ONSCREEN_TEXT diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSQtTextRenderer.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSQtTextRenderer.cpp deleted file mode 100644 index 17539e4a..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSQtTextRenderer.cpp +++ /dev/null @@ -1,678 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderText.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" - -#include "foundation/Qt3DSVec2.h" -#include "foundation/FileTools.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderThreadPool.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "EASTL/set.h" -#include "EASTL/list.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace qt3ds::render; - -namespace { - -struct Qt3DSQtTextRenderer : public ITextRenderer -{ - struct FontInfo - { - QString fontFileName; - QString fontName; - QString fontFamily; - int fontId; - QFont font; - - FontInfo() : - fontId(-1) - {} - - FontInfo(const QString &fileName, const QString &name, const QString &family, int id) : - fontFileName(fileName) - , fontName(name) - , fontFamily(family) - , fontId(id) - { - font.setFamily(fontFamily); - } - - FontInfo(const FontInfo &other) : - fontFileName(other.fontFileName) - , fontName(other.fontName) - , fontFamily(other.fontFamily) - , fontId(other.fontId) - , font(other.font) - {} - - FontInfo &operator=(const FontInfo &other) - { - fontFileName = other.fontFileName; - fontName = other.fontName; - fontFamily = other.fontFamily; - fontId = other.fontId; - font = other.font; - - return *this; - } - }; - - typedef eastl::string TStrType; - typedef eastl::set TStringSet; - typedef QHash TFontInfoHash; - - NVFoundationBase &m_foundation; - NVScopedRefCounted m_stringTable; - NVScopedRefCounted m_renderContext; - NVScopedRefCounted m_perfTimer; - volatile QT3DSI32 mRefCount; - nvvector m_installedFonts; - - Sync m_PreloadSync; - - TStringSet m_systemFontDirs; - TStringSet m_projectFontDirs; - TFontInfoHash m_projectFontInfos; - TFontInfoHash m_systemFontInfos; - TStrType m_workspace; - - bool m_systemFontsInitialized; - bool m_projectFontsInitialized; - bool m_PreloadingFonts; - - QStringList m_nameFilters; - qreal m_pixelRatio; - - Qt3DSQtTextRenderer(NVFoundationBase &inFoundation, IStringTable &inStrTable) - : m_foundation(inFoundation) - , m_stringTable(inStrTable) - , mRefCount(0) - , m_installedFonts(inFoundation.getAllocator(), "Qt3DSQtTextRenderer::m_installedFonts") - , m_PreloadSync(inFoundation.getAllocator()) - , m_systemFontsInitialized(false) - , m_projectFontsInitialized(false) - , m_PreloadingFonts(false) - , m_pixelRatio(1.0) - { - const QWindowList list = QGuiApplication::topLevelWindows(); - if (list.size() > 0) - m_pixelRatio = list[0]->devicePixelRatio(); - - m_nameFilters << QStringLiteral("*.ttf"); - m_nameFilters << QStringLiteral("*.otf"); - } - virtual ~Qt3DSQtTextRenderer() - { - QFontDatabase::removeAllApplicationFonts(); - } - - QString stringToQString(const CRegisteredString &str) - { - return QString::fromUtf8(str.c_str()); - } - - QString stringToQString(const eastl::string &str) - { - return QString::fromUtf8(str.c_str()); - } - - QString stringToQString(const char8_t *str) - { - return QString::fromUtf8(str); - } - - CRegisteredString QStringToRegisteredString(const QString &str) - { - return m_stringTable->RegisterStr(str.toUtf8().constData()); - } - - void unregisterProjectFonts() - { - for (FontInfo &fi : m_projectFontInfos.values()) - QFontDatabase::removeApplicationFont(fi.fontId); - m_projectFontsInitialized = false; - m_installedFonts.clear(); - m_projectFontInfos.clear(); - } - - QString getFileStem(const QString &fileName) - { - QString retVal; - int dotPos = fileName.lastIndexOf(QChar('.')); - if (dotPos < 0) - return retVal; - int slashPos = fileName.lastIndexOf(QChar('/')); - retVal = fileName.mid(slashPos + 1); - retVal.chop(fileName.length() - dotPos); - return retVal; - } - - void registerFonts(TStringSet dirSet, TFontInfoHash *fontInfos = nullptr) - { - for (TStringSet::const_iterator theIter = dirSet.begin(), - theEnd = dirSet.end(); - theIter != theEnd; ++theIter) { - QString localDir = CFileTools::NormalizePathForQtUsage(stringToQString(*theIter)); - QDir dir(localDir); - if (!dir.exists()) { - qCCritical(INTERNAL_ERROR) << "Adding font directory:" << localDir; - continue; - } - if (fontInfos) - dir.cd(QStringLiteral("fonts")); - QStringList entryList = dir.entryList(m_nameFilters); - for (QString entry : entryList) { - entry = dir.absoluteFilePath(entry); - QFile file(entry); - if (file.open(QIODevice::ReadOnly)) { - QByteArray rawData = file.readAll(); - int fontId = QFontDatabase::addApplicationFontFromData(rawData); - if (fontId < 0) { - qCWarning(WARNING, "Failed to register font: %s", - entry.toStdString().c_str()); - } else if (fontInfos) { - QString fontName = getFileStem(entry); - QString fontFamily; - QStringList families = QFontDatabase::applicationFontFamilies(fontId); - if (families.size() > 0) - fontFamily = families.at(0); - FontInfo fi(entry, fontName, fontFamily, fontId); - // Detect font style and weight using a dummy QRawFont - QRawFont rawFont(rawData, 1.0); - if (rawFont.isValid()) { - if (rawFont.style() != QFont::StyleOblique) { - fi.font.setStyle(rawFont.style()); - fi.font.setWeight(rawFont.weight()); - } - } else { - qCWarning(WARNING, "Failed to determine font style: %s", - entry.toStdString().c_str()); - } - fontInfos->insert(fontName, fi); - } - } else { - qCWarning(WARNING, "Failed to load font: %s", - entry.toStdString().c_str()); - } - } - } - } - - void projectCleanup() - { - m_projectFontsInitialized = false; - unregisterProjectFonts(); - m_projectFontDirs.clear(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_foundation.getAllocator()) - - eastl::pair AddFontDirectory(const TStrType &inDirectory, TStringSet &inDirSet) - { - if (inDirectory.empty()) { - m_workspace.assign("./"); - } else { - m_workspace.clear(); - for (const char8_t *item = inDirectory.c_str(); item && *item; ++item) { - if (*item == '\\') - m_workspace.append(1, '/'); - else - m_workspace.append(1, static_cast(*item)); - } - if (m_workspace.back() != '/') - m_workspace.append(1, '/'); - } - - return eastl::make_pair(m_workspace, inDirSet.insert(m_workspace).second); - } - - // You can have several standard font directories and these will be persistent - void AddSystemFontDirectory(const char8_t *inDirectory) override - { - AddFontDirectory(inDirectory, m_systemFontDirs); - } - - void AddProjectFontDirectory(const char8_t *inProjectDirectory) override - { - eastl::pair theAddResult = - AddFontDirectory(inProjectDirectory, m_projectFontDirs); - if (theAddResult.second && m_projectFontsInitialized) - ReloadFonts(); - } - - void ReloadFonts() override - { - unregisterProjectFonts(); - PreloadFonts(); - } - - void PreloadFonts() override - { - if (!m_systemFontsInitialized) { - m_systemFontsInitialized = true; - registerFonts(m_systemFontDirs, &m_systemFontInfos); - } - - if (!m_projectFontsInitialized) { - m_projectFontsInitialized = true; - registerFonts(m_projectFontDirs, &m_projectFontInfos); - } - } - - void ClearProjectFontDirectories() override - { - projectCleanup(); - } - - static void PreloadThreadCallback(void *inData) - { - Qt3DSQtTextRenderer *theRenderer(reinterpret_cast(inData)); - theRenderer->PreloadFonts(); - theRenderer->m_PreloadSync.set(); - } - - void BeginPreloadFonts(IThreadPool &inThreadPool, IPerfTimer &inTimer) override - { - m_PreloadingFonts = true; - - m_PreloadSync.reset(); - m_perfTimer = inTimer; - - inThreadPool.AddTask(this, PreloadThreadCallback, NULL); - } - - void EndPreloadFonts() override - { - if (m_PreloadingFonts) { - { - SStackPerfTimer __perfTimer(*m_perfTimer, "QtText: Wait till font preloading completed"); - m_PreloadSync.wait(); - } - } - m_PreloadingFonts = false; - } - - // Get the list of project fonts. These are the only fonts that can be displayed. - NVConstDataRef GetProjectFontList() override - { - PreloadFonts(); - if (m_installedFonts.empty()) { - m_installedFonts.reserve(m_projectFontInfos.size()); - for (FontInfo &fi : m_projectFontInfos.values()) { - m_installedFonts.push_back(SRendererFontEntry( - QStringToRegisteredString(fi.fontName), - QStringToRegisteredString(fi.fontFileName))); - } - } - return m_installedFonts; - } - - Option GetFontNameForFont(CRegisteredString inFontname) override - { - // This function is there to support legacy font names. - - QString inStr = stringToQString(inFontname); - if (m_projectFontInfos.keys().contains(inStr)) - return inFontname; - - // Fall back for family name detection if not found by font name - for (FontInfo &fi : m_projectFontInfos.values()) { - if (inStr == fi.fontFamily) - return QStringToRegisteredString(fi.fontName); - } - - return Empty(); - } - - Option GetFontNameForFont(const char8_t *inFontname) override - { - return GetFontNameForFont(m_stringTable->RegisterStr(inFontname)); - } - - ITextRenderer &GetTextRenderer(NVRenderContext &inRenderContext) override - { - m_renderContext = inRenderContext; - return *this; - } - - FontInfo &fontInfoForName(const CRegisteredString &fontName) - { - PreloadFonts(); - QString qtFontName = stringToQString(fontName); - if (m_projectFontInfos.contains(qtFontName)) - return m_projectFontInfos[qtFontName]; - - if (m_systemFontInfos.contains(qtFontName)) - return m_systemFontInfos[qtFontName]; - - // Unknown font, create a system font for it - FontInfo fi("", qtFontName, qtFontName, -1); - m_systemFontInfos.insert(qtFontName, fi); - - return m_systemFontInfos[qtFontName]; - } - - void updateFontInfo(FontInfo &fi, const STextRenderInfo &inText, - QT3DSF32 inTextScaleFactor = 1.0f) - { - qreal pixelSize = inText.m_FontSize; - fi.font.setPixelSize(pixelSize * inTextScaleFactor); - fi.font.setLetterSpacing(QFont::AbsoluteSpacing, qreal(inText.m_Tracking)); - } - - QStringList splitText(const char8_t *theText) - { - // Split the text into lines - int lines = 1; - int lineLen = 0; - QStringList lineList; - const char8_t *lineStartItem = nullptr; - for (const char8_t *item = theText; item && *item; ++item) { - if (!lineLen) - lineStartItem = item; - ++lineLen; - if (*item == '\n') { - int chopAmount = 1; - if (lineLen > 1 && *(item - 1) == '\r') - ++chopAmount; - - ++lines; - lineList.append(QString::fromUtf8(lineStartItem, lineLen - chopAmount)); - lineLen = 0; - } - } - if (lineStartItem) - lineList.append(QString::fromUtf8(lineStartItem, lineLen)); - - return lineList; - } - - QRectF textBoundingBox(const STextRenderInfo &inText, - const QFontMetricsF &fm, QStringList &lineList, - QVector &lineWidths, const char8_t *inTextOverride = nullptr) - { - const char8_t *theText = inTextOverride ? inTextOverride : inText.m_Text.c_str(); - lineList = splitText(theText); - - QRectF boundingBox; - boundingBox.setHeight(lineList.size() * fm.height() + qCeil(qreal(lineList.size() - 1) * qreal(inText.m_Leading))); - - lineWidths.resize(lineList.size()); - - for (int i = 0; i < lineList.size(); ++i) { - // For italicized fonts the bounding box right is the correct method - // to measure since the left offset may extend, but for - // non-italicized fonts we need the width method to meausure - // otherwise the resultant text will be clipped. - QString line = lineList.at(i); - qreal width = fm.width(line); - qreal right = fm.boundingRect(line).right(); - // For hdpi displays, fontmetrics doesn't always calculate enough space for fonts, so - // we add the pixel ratio to all widths to avoid clipping - qreal lineWidth = qMax(width, right) + m_pixelRatio; - lineWidths[i] = lineWidth; - if (boundingBox.width() < lineWidth) - boundingBox.setWidth(lineWidth); - } - - // We don't want extra letter spacing on the last glyph, so let's remove it - boundingBox.setRight(qMax(boundingBox.left(), boundingBox.right() - qFloor(inText.m_Tracking))); - - return boundingBox; - } - - STextDimensions MeasureText(const STextRenderInfo &inText, QT3DSF32 inTextScaleFactor, - const char8_t *inTextOverride) override - { - FontInfo &fi = fontInfoForName(inText.m_Font); - updateFontInfo(fi, inText, inTextScaleFactor); - QFontMetricsF fm(fi.font); - QStringList dummyList; - QVector dummyWidth; - QRectF boundingBox = textBoundingBox(inText, fm, dummyList, dummyWidth, inTextOverride); - return STextDimensions(boundingBox.width(), boundingBox.height()); - } - - int alignToQtAlign(TextVerticalAlignment::Enum va) - { - int qtAlign(0); - switch (va) { - case TextVerticalAlignment::Top: - qtAlign = Qt::AlignTop; - break; - case TextVerticalAlignment::Bottom: - qtAlign = Qt::AlignBottom; - break; - default: - qtAlign = Qt::AlignVCenter; - } - - return qtAlign; - } - - STextTextureDetails RenderText(const STextRenderInfo &inSrcText, - NVRenderTexture2D &inTexture) override - { - FontInfo &fi = fontInfoForName(inSrcText.m_Font); - updateFontInfo(fi, inSrcText); - QFontMetricsF fm(fi.font); - int horizontalAlignmentFlag = Qt::AlignLeft; - - int shadowRgb = int(2.55f * (100 - int(inSrcText.m_DropShadowStrength))); - QStringList lineList; - QVector lineWidths; - QRectF boundingBox; - const bool dynamicTextArea = inSrcText.m_BoundingBox.isZero(); - - if (dynamicTextArea) { - boundingBox = textBoundingBox(inSrcText, fm, lineList, lineWidths); - } else { - lineList << inSrcText.m_Text.c_str(); - lineWidths << inSrcText.m_BoundingBox.x; - boundingBox = QRectF(0, 0, inSrcText.m_BoundingBox.x, inSrcText.m_BoundingBox.y); - } - - if (boundingBox.width() <= 0 || boundingBox.height() <= 0) { - return ITextRenderer::UploadData(toU8DataRef((char *)nullptr, 0), inTexture, 4, 4, - 0, 0, - NVRenderTextureFormats::RGBA8, true); - } - - int finalWidth = NextMultipleOf4(boundingBox.width()); - int finalHeight = NextMultipleOf4(boundingBox.height()); - - QImage image(finalWidth, finalHeight, QImage::Format_ARGB32); - image.fill(0); - QPainter painter(&image); - painter.setPen(Qt::white); - painter.setFont(fi.font); - - // Translate painter to remove the extra spacing of the last letter - qreal tracking = 0.0; - switch (inSrcText.m_HorizontalAlignment) { - case TextHorizontalAlignment::Center: - horizontalAlignmentFlag = Qt::AlignHCenter; - tracking += qreal(inSrcText.m_Tracking / 2.0f); - break; - case TextHorizontalAlignment::Right: - horizontalAlignmentFlag = Qt::AlignRight; - tracking += qreal(inSrcText.m_Tracking); - break; - default: - break; // Do nothing - } - - qreal shadowOffsetX = qreal(inSrcText.m_FontSize * inSrcText.m_DropShadowOffsetX) / 1000.; - qreal shadowOffsetY = qreal(inSrcText.m_FontSize * inSrcText.m_DropShadowOffsetY) / 1000.; - // To be removed in 2.x (when UIP version is next updated) - if (inSrcText.m_DropShadow && shadowOffsetX == 0. && shadowOffsetY == 0.) { - const qreal offset = qreal(inSrcText.m_DropShadowOffset) / 10.; - switch (inSrcText.m_DropShadowHorizontalAlignment) { - case TextHorizontalAlignment::Left: - shadowOffsetX = -offset; - break; - case TextHorizontalAlignment::Right: - shadowOffsetX = offset; - break; - default: - break; - } - switch (inSrcText.m_DropShadowVerticalAlignment) { - case TextVerticalAlignment::Top: - shadowOffsetY = -offset; - break; - case TextVerticalAlignment::Bottom: - shadowOffsetY = offset; - break; - default: - break; - } - } - - int wordWrapFlags = 0; - if (dynamicTextArea) { - wordWrapFlags = Qt::TextDontClip; - } else { - switch (inSrcText.m_WordWrap) { - case TextWordWrap::WrapWord: - wordWrapFlags = Qt::TextWordWrap | Qt::TextDontClip; - break; - case TextWordWrap::WrapAnywhere: - wordWrapFlags = Qt::TextWrapAnywhere | Qt::TextDontClip; - break; - case TextWordWrap::Clip: - default: - break; - } - } - - int lineHeight = dynamicTextArea ? fm.height() : finalHeight; - QT3DSF32 nextHeight = 0; - for (int i = 0; i < lineList.size(); ++i) { - const QString &line = lineList.at(i); - qreal xTranslation = tracking; - switch (inSrcText.m_HorizontalAlignment) { - case TextHorizontalAlignment::Center: - xTranslation += qreal(boundingBox.width() - lineWidths.at(i)) / 2.0; - break; - case TextHorizontalAlignment::Right: - xTranslation += qreal(boundingBox.width() - lineWidths.at(i)); - break; - default: - break; // Do nothing - } - QRectF bound(xTranslation, qreal(nextHeight), lineWidths.at(i), lineHeight); - QRectF actualBound; - if (inSrcText.m_DropShadow) { - QRectF boundShadow(xTranslation + shadowOffsetX, nextHeight + shadowOffsetY, - qreal(lineWidths.at(i)), lineHeight); - // shadow is a darker shade of the given font color - painter.setPen(QColor(shadowRgb, shadowRgb, shadowRgb)); - painter.drawText(boundShadow, - alignToQtAlign(inSrcText.m_VerticalAlignment) | wordWrapFlags - | horizontalAlignmentFlag, line, &actualBound); - painter.setPen(Qt::white); // coloring is done in the shader - } - painter.drawText(bound, - alignToQtAlign(inSrcText.m_VerticalAlignment) | wordWrapFlags - | horizontalAlignmentFlag, line, &actualBound); - - nextHeight += QT3DSF32(lineHeight) + inSrcText.m_Leading; - } - - return ITextRenderer::UploadData(toU8DataRef(image.bits(), image.byteCount()), inTexture, - image.width(), image.height(), - image.width(), image.height(), - NVRenderTextureFormats::RGBA8, true); - } - - STextTextureDetails RenderText(const STextRenderInfo &inText, - NVRenderPathFontItem &inPathFontItem, - NVRenderPathFontSpecification &inFontPathSpec) override - { - Q_UNUSED(inText); - Q_UNUSED(inPathFontItem); - Q_UNUSED(inFontPathSpec); - QT3DS_ASSERT(m_renderContext->IsPathRenderingSupported()); - - // We do not support HW accelerated fonts (yet?) - QT3DS_ASSERT(false); - - return STextTextureDetails(); - } - - void BeginFrame() override - { - // Nothing to do - } - - void EndFrame() override - { - // Nothing to do - } - - // unused for text rendering via texture atlas - STextTextureAtlasEntryDetails RenderAtlasEntry(QT3DSU32, NVRenderTexture2D &) override - { - return STextTextureAtlasEntryDetails(); - } - QT3DSI32 CreateTextureAtlas() override - { - return 0; - } - SRenderTextureAtlasDetails RenderText(const STextRenderInfo &) override - { - return SRenderTextureAtlasDetails(); - } -}; -} - -ITextRendererCore &ITextRendererCore::CreateQtTextRenderer(NVFoundationBase &inFnd, - IStringTable &inStrTable) -{ - return *QT3DS_NEW(inFnd.getAllocator(), Qt3DSQtTextRenderer)(inFnd, inStrTable); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderClippingFrustum.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderClippingFrustum.cpp deleted file mode 100644 index 86375566..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderClippingFrustum.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderClippingFrustum.h" - -using namespace qt3ds::render; - -SClippingFrustum::SClippingFrustum(const QT3DSMat44 &modelviewprojection, SClipPlane nearPlane) -{ - SClipPlane *_cullingPlanes = mPlanes; - const QT3DSMat44 &modelViewProjectionMat(modelviewprojection); - const QT3DSF32 *modelviewProjection = modelViewProjectionMat.front(); - -// update planes (http://read.pudn.com/downloads128/doc/542641/Frustum.pdf) -// Google for Gribb plane extraction if that link doesn't work. -// http://www.google.com/search?q=ravensoft+plane+extraction -#define M(_x, _y) modelviewProjection[(4 * (_y)) + (_x)] - // left plane - _cullingPlanes[0].normal.x = M(3, 0) + M(0, 0); - _cullingPlanes[0].normal.y = M(3, 1) + M(0, 1); - _cullingPlanes[0].normal.z = M(3, 2) + M(0, 2); - _cullingPlanes[0].d = M(3, 3) + M(0, 3); - _cullingPlanes[0].d /= _cullingPlanes[0].normal.normalize(); - - // right plane - _cullingPlanes[1].normal.x = M(3, 0) - M(0, 0); - _cullingPlanes[1].normal.y = M(3, 1) - M(0, 1); - _cullingPlanes[1].normal.z = M(3, 2) - M(0, 2); - _cullingPlanes[1].d = M(3, 3) - M(0, 3); - _cullingPlanes[1].d /= _cullingPlanes[1].normal.normalize(); - - // far plane - _cullingPlanes[2].normal.x = M(3, 0) - M(2, 0); - _cullingPlanes[2].normal.y = M(3, 1) - M(2, 1); - _cullingPlanes[2].normal.z = M(3, 2) - M(2, 2); - _cullingPlanes[2].d = M(3, 3) - M(2, 3); - _cullingPlanes[2].d /= _cullingPlanes[2].normal.normalize(); - - // bottom plane - _cullingPlanes[3].normal.x = M(3, 0) + M(1, 0); - _cullingPlanes[3].normal.y = M(3, 1) + M(1, 1); - _cullingPlanes[3].normal.z = M(3, 2) + M(1, 2); - _cullingPlanes[3].d = M(3, 3) + M(1, 3); - _cullingPlanes[3].d /= _cullingPlanes[3].normal.normalize(); - - // top plane - _cullingPlanes[4].normal.x = M(3, 0) - M(1, 0); - _cullingPlanes[4].normal.y = M(3, 1) - M(1, 1); - _cullingPlanes[4].normal.z = M(3, 2) - M(1, 2); - _cullingPlanes[4].d = M(3, 3) - M(1, 3); - _cullingPlanes[4].d /= _cullingPlanes[4].normal.normalize(); -#undef M - _cullingPlanes[5] = nearPlane; - // http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/include/osg/Plane?rev=5328 - // setup the edges of the plane that we will clip against an axis-aligned bounding box. - for (QT3DSU32 idx = 0; idx < 6; ++idx) { - _cullingPlanes[idx].calculateBBoxEdges(); - } -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp deleted file mode 100644 index e0eedfd3..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp +++ /dev/null @@ -1,819 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRender.h" -#include "EABase/eabase.h" //char16_t definition -#include "Qt3DSRenderContextCore.h" -#include "foundation/StringTable.h" -#include "Qt3DSRenderNode.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRenderResourceManager.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderEffectSystem.h" -#include "Qt3DSRenderShaderCache.h" -#include "foundation/Qt3DSFoundation.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "Qt3DSRenderCamera.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderThreadPool.h" -#include "Qt3DSRenderImageBatchLoader.h" -#include "Qt3DSRenderTextTextureCache.h" -#include "Qt3DSRenderTextTextureAtlas.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderPixelGraphicsRenderer.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "Qt3DSRenderBufferLoader.h" -#include "foundation/FastAllocator.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRenderPathManager.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include "Qt3DSRenderCustomMaterialShaderGenerator.h" - -using namespace qt3ds::render; - -namespace { - -struct SRenderContextCore : public IQt3DSRenderContextCore -{ - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_StringTable; - NVScopedRefCounted m_PerfTimer; - NVScopedRefCounted m_InputStreamFactory; - NVScopedRefCounted m_ThreadPool; - NVScopedRefCounted m_DynamicObjectSystem; - NVScopedRefCounted m_MaterialSystem; - NVScopedRefCounted m_EffectSystem; - NVScopedRefCounted m_BufferLoader; - NVScopedRefCounted m_RenderPluginManagerCore; - NVScopedRefCounted m_TextRenderer; - NVScopedRefCounted m_OnscreenTexRenderer; - NVScopedRefCounted m_PathManagerCore; - - QT3DSI32 mRefCount; - SRenderContextCore(NVFoundationBase &fnd, IStringTable &strTable) - : m_Foundation(fnd) - , m_StringTable(strTable) - , m_PerfTimer(IPerfTimer::CreatePerfTimer(fnd)) - , m_InputStreamFactory(IInputStreamFactory::Create(fnd)) - , m_ThreadPool(IThreadPool::CreateThreadPool(fnd, 4)) - , mRefCount(0) - { - m_DynamicObjectSystem = IDynamicObjectSystemCore::CreateDynamicSystemCore(*this); - m_MaterialSystem = ICustomMaterialSystemCore::CreateCustomMaterialSystemCore(*this); - m_EffectSystem = IEffectSystemCore::CreateEffectSystemCore(*this); - m_RenderPluginManagerCore = - IRenderPluginManagerCore::Create(fnd, strTable, *m_InputStreamFactory); - m_BufferLoader = IBufferLoader::Create(m_Foundation, *m_InputStreamFactory, *m_ThreadPool); - m_PathManagerCore = IPathManagerCore::CreatePathManagerCore(*this); - } - - virtual ~SRenderContextCore() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - IStringTable &GetStringTable() override { return *m_StringTable; } - NVFoundationBase &GetFoundation() override { return m_Foundation; } - NVAllocatorCallback &GetAllocator() override { return m_Foundation.getAllocator(); } - IInputStreamFactory &GetInputStreamFactory() override { return *m_InputStreamFactory; } - IThreadPool &GetThreadPool() override { return *m_ThreadPool; } - IDynamicObjectSystemCore &GetDynamicObjectSystemCore() override - { - return *m_DynamicObjectSystem; - } - ICustomMaterialSystemCore &GetMaterialSystemCore() override { return *m_MaterialSystem; } - IEffectSystemCore &GetEffectSystemCore() override { return *m_EffectSystem; } - IPerfTimer &GetPerfTimer() override { return *m_PerfTimer; } - IBufferLoader &GetBufferLoader() override { return *m_BufferLoader; } - IRenderPluginManagerCore &GetRenderPluginCore() override { return *m_RenderPluginManagerCore; } - IPathManagerCore &GetPathManagerCore() override { return *m_PathManagerCore; } - IQt3DSRenderContext &CreateRenderContext(NVRenderContext &inContext, - const char8_t *inPrimitivesDirectory) override; - void SetTextRendererCore(ITextRendererCore &inRenderer) override { m_TextRenderer = inRenderer; } - ITextRendererCore *GetTextRendererCore() override { return m_TextRenderer.mPtr; } - void SetOnscreenTextRendererCore(ITextRendererCore &inRenderer) override - { - m_OnscreenTexRenderer = inRenderer; - } - ITextRendererCore *GetOnscreenTextRendererCore() override { return m_OnscreenTexRenderer.mPtr; } -}; - -inline float Clamp(float val, float inMin = 0.0f, float inMax = 1.0f) -{ - if (val < inMin) - return inMin; - if (val > inMax) - return inMax; - return val; -} - -struct SPerFrameAllocator : public NVAllocatorCallback -{ - SFastAllocator<> m_FastAllocator; - SSAutoDeallocatorAllocator m_LargeAllocator; - - SPerFrameAllocator(NVAllocatorCallback &baseAllocator) - : m_FastAllocator(baseAllocator, "PerFrameAllocation") - , m_LargeAllocator(baseAllocator) - { - } - - inline void *allocate(size_t inSize, const char *inFile, int inLine) - { - if (inSize < 8192) - return m_FastAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); - else - return m_LargeAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); - } - - inline void *allocate(size_t inSize, const char *inFile, int inLine, int, int) - { - if (inSize < 8192) - return m_FastAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); - else - return m_LargeAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); - } - - inline void deallocate(void *, size_t) {} - - void reset() - { - m_FastAllocator.reset(); - m_LargeAllocator.deallocateAllAllocations(); - } - - void *allocate(size_t inSize, const char *typeName, const char *inFile, int inLine, - int flags = 0) override - { - if (inSize < SFastAllocator<>::SlabSize) - return m_FastAllocator.allocate(inSize, typeName, inFile, inLine, flags); - else - return m_LargeAllocator.allocate(inSize, typeName, inFile, inLine, flags); - } - - void *allocate(size_t inSize, const char *typeName, const char *inFile, int inLine, - size_t alignment, size_t alignmentOffset) override - { - if (inSize < SFastAllocator<>::SlabSize) - return m_FastAllocator.allocate(inSize, typeName, inFile, inLine, alignment, - alignmentOffset); - else - return m_LargeAllocator.allocate(inSize, typeName, inFile, inLine, alignment, - alignmentOffset); - } - - void deallocate(void *) override {} -}; - -struct SRenderContext : public IQt3DSRenderContext -{ - NVScopedRefCounted m_RenderContext; - NVScopedRefCounted m_CoreContext; - NVScopedRefCounted m_StringTable; - NVScopedRefCounted m_PerfTimer; - NVScopedRefCounted m_InputStreamFactory; - NVScopedRefCounted m_BufferManager; - NVScopedRefCounted m_ResourceManager; - NVScopedRefCounted m_OffscreenRenderManager; - NVScopedRefCounted m_Renderer; - NVScopedRefCounted m_TextRenderer; - NVScopedRefCounted m_OnscreenTextRenderer; - NVScopedRefCounted m_TextTextureCache; - NVScopedRefCounted m_TextTextureAtlas; - NVScopedRefCounted m_DynamicObjectSystem; - NVScopedRefCounted m_EffectSystem; - NVScopedRefCounted m_ShaderCache; - NVScopedRefCounted m_ThreadPool; - NVScopedRefCounted m_ImageBatchLoader; - NVScopedRefCounted m_RenderPluginManager; - NVScopedRefCounted m_CustomMaterialSystem; - NVScopedRefCounted m_PixelGraphicsRenderer; - NVScopedRefCounted m_PathManager; - NVScopedRefCounted m_ShaderProgramGenerator; - NVScopedRefCounted m_DefaultMaterialShaderGenerator; - NVScopedRefCounted m_CustomMaterialShaderGenerator; - SPerFrameAllocator m_PerFrameAllocator; - NVScopedRefCounted m_RenderList; - QT3DSU32 m_FrameCount; - volatile QT3DSI32 mRefCount; - // Viewport that this render context should use - Option m_Viewport; - QSize m_WindowDimensions; - ScaleModes::Enum m_ScaleMode; - bool m_WireframeMode; - bool m_IsInSubPresentation; - Option m_SceneColor; - Option m_MatteColor; - RenderRotationValues::Enum m_Rotation; - NVScopedRefCounted m_RotationFBO; - NVScopedRefCounted m_RotationTexture; - NVScopedRefCounted m_RotationDepthBuffer; - NVRenderFrameBuffer *m_ContextRenderTarget; - NVRenderRect m_PresentationViewport; - QSize m_PresentationDimensions; - QSize m_RenderPresentationDimensions; - QSize m_PreRenderPresentationDimensions; - QT3DSVec2 m_PresentationScale; - NVRenderRect m_VirtualViewport; - QPair m_FPS; - bool m_AuthoringMode; - - SRenderContext(NVRenderContext &ctx, IQt3DSRenderContextCore &inCore, - const char8_t *inApplicationDirectory) - : m_RenderContext(ctx) - , m_CoreContext(inCore) - , m_StringTable(ctx.GetStringTable()) - , m_PerfTimer(inCore.GetPerfTimer()) - , m_InputStreamFactory(inCore.GetInputStreamFactory()) - , m_BufferManager( - IBufferManager::Create(ctx, *m_StringTable, *m_InputStreamFactory, *m_PerfTimer)) - , m_ResourceManager(IResourceManager::CreateResourceManager(ctx)) - , m_ShaderCache(IShaderCache::CreateShaderCache(ctx, *m_InputStreamFactory, *m_PerfTimer)) - , m_ThreadPool(inCore.GetThreadPool()) - , m_RenderList(IRenderList::CreateRenderList(ctx.GetFoundation())) - , m_PerFrameAllocator(ctx.GetAllocator()) - , m_FrameCount(0) - , mRefCount(0) - , m_WindowDimensions(800, 480) - , m_ScaleMode(ScaleModes::ExactSize) - , m_WireframeMode(false) - , m_IsInSubPresentation(false) - , m_Rotation(RenderRotationValues::NoRotation) - , m_ContextRenderTarget(NULL) - , m_PresentationScale(0, 0) - , m_FPS(qMakePair(0.0, 0)) - , m_AuthoringMode(false) - { - m_OffscreenRenderManager = IOffscreenRenderManager::CreateOffscreenRenderManager( - ctx.GetAllocator(), *m_StringTable, *m_ResourceManager, *this); - m_Renderer = IQt3DSRenderer::CreateRenderer(*this); - if (inApplicationDirectory && *inApplicationDirectory) - m_InputStreamFactory->AddSearchDirectory(inApplicationDirectory); - - m_ImageBatchLoader = - IImageBatchLoader::CreateBatchLoader(ctx.GetFoundation(), *m_InputStreamFactory, - *m_BufferManager, *m_ThreadPool, *m_PerfTimer); - m_RenderPluginManager = inCore.GetRenderPluginCore().GetRenderPluginManager(ctx); - m_DynamicObjectSystem = inCore.GetDynamicObjectSystemCore().CreateDynamicSystem(*this); - m_EffectSystem = inCore.GetEffectSystemCore().GetEffectSystem(*this); - m_CustomMaterialSystem = inCore.GetMaterialSystemCore().GetCustomMaterialSystem(*this); - // as does the custom material system - m_PixelGraphicsRenderer = IPixelGraphicsRenderer::CreateRenderer(*this, *m_StringTable); - ITextRendererCore *theTextCore = inCore.GetTextRendererCore(); - m_ShaderProgramGenerator = IShaderProgramGenerator::CreateProgramGenerator(*this); - m_DefaultMaterialShaderGenerator = - IDefaultMaterialShaderGenerator::CreateDefaultMaterialShaderGenerator(*this); - m_CustomMaterialShaderGenerator = - ICustomMaterialShaderGenerator::CreateCustomMaterialShaderGenerator(*this); - if (theTextCore) { - m_TextRenderer = theTextCore->GetTextRenderer(ctx); - m_TextTextureCache = ITextTextureCache::CreateTextureCache( - m_RenderContext->GetFoundation(), *m_TextRenderer, *m_RenderContext); - } - - ITextRendererCore *theOnscreenTextCore = inCore.GetOnscreenTextRendererCore(); - if (theOnscreenTextCore) { - m_OnscreenTextRenderer = theOnscreenTextCore->GetTextRenderer(ctx); - m_TextTextureAtlas = ITextTextureAtlas::CreateTextureAtlas( - m_RenderContext->GetFoundation(), *m_OnscreenTextRenderer, *m_RenderContext); - } - m_PathManager = inCore.GetPathManagerCore().OnRenderSystemInitialize(*this); - -#if defined (QT3DS_SHADER_PLATFORM_LIBRARY_DIR) - const QString platformDirectory; -#if defined(_WIN32) - platformDirectory = QStringLiteral("res/platform/win"); -#elif defined(_LINUX) - platformDirectory = QStringLiteral("res/platform/linux"); -#elif defined(_MACOSX) - platformDirectory = QStringLiteral("res/platform/macos"); -#endif - GetDynamicObjectSystem().setShaderCodeLibraryPlatformDirectory(platformDirectory); -#endif - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext->GetAllocator()); - - IStringTable &GetStringTable() override { return *m_StringTable; } - NVFoundationBase &GetFoundation() override { return m_RenderContext->GetFoundation(); } - NVAllocatorCallback &GetAllocator() override { return m_RenderContext->GetAllocator(); } - IQt3DSRenderer &GetRenderer() override { return *m_Renderer; } - IBufferManager &GetBufferManager() override { return *m_BufferManager; } - IResourceManager &GetResourceManager() override { return *m_ResourceManager; } - NVRenderContext &GetRenderContext() override { return *m_RenderContext; } - IOffscreenRenderManager &GetOffscreenRenderManager() override - { - return *m_OffscreenRenderManager; - } - IInputStreamFactory &GetInputStreamFactory() override { return *m_InputStreamFactory; } - IEffectSystem &GetEffectSystem() override { return *m_EffectSystem; } - IShaderCache &GetShaderCache() override { return *m_ShaderCache; } - IThreadPool &GetThreadPool() override { return *m_ThreadPool; } - IImageBatchLoader &GetImageBatchLoader() override { return *m_ImageBatchLoader; } - ITextTextureCache *GetTextureCache() override { return m_TextTextureCache.mPtr; } - ITextTextureAtlas *GetTextureAtlas() override { return m_TextTextureAtlas.mPtr; } - IRenderPluginManager &GetRenderPluginManager() override { return *m_RenderPluginManager; } - IDynamicObjectSystem &GetDynamicObjectSystem() override { return *m_DynamicObjectSystem; } - ICustomMaterialSystem &GetCustomMaterialSystem() override { return *m_CustomMaterialSystem; } - IPixelGraphicsRenderer &GetPixelGraphicsRenderer() override { return *m_PixelGraphicsRenderer; } - IPerfTimer &GetPerfTimer() override { return *m_PerfTimer; } - IRenderList &GetRenderList() override { return *m_RenderList; } - IPathManager &GetPathManager() override { return *m_PathManager; } - IShaderProgramGenerator &GetShaderProgramGenerator() override - { - return *m_ShaderProgramGenerator; - } - IDefaultMaterialShaderGenerator &GetDefaultMaterialShaderGenerator() override - { - return *m_DefaultMaterialShaderGenerator; - } - ICustomMaterialShaderGenerator &GetCustomMaterialShaderGenerator() override - { - return *m_CustomMaterialShaderGenerator; - } - NVAllocatorCallback &GetPerFrameAllocator() override { return m_PerFrameAllocator; } - - QT3DSU32 GetFrameCount() override { return m_FrameCount; } - void SetFPS(QPair inFPS) override { m_FPS = inFPS; } - QPair GetFPS(void) override { return m_FPS; } - - bool IsAuthoringMode() override { return m_AuthoringMode; } - void SetAuthoringMode(bool inMode) override { m_AuthoringMode = inMode; } - - bool IsInSubPresentation() override { return m_IsInSubPresentation; } - void SetInSubPresentation(bool inValue) override { m_IsInSubPresentation = inValue; } - - ITextRenderer *GetTextRenderer() override { return m_TextRenderer; } - - ITextRenderer *GetOnscreenTextRenderer() override { return m_OnscreenTextRenderer; } - - void SetSceneColor(Option inSceneColor) override { m_SceneColor = inSceneColor; } - void SetMatteColor(Option inMatteColor) override { m_MatteColor = inMatteColor; } - - void SetWindowDimensions(const QSize &inWindowDimensions) override - { - m_WindowDimensions = inWindowDimensions; - } - - QSize GetWindowDimensions() override { return m_WindowDimensions; } - - void SetScaleMode(ScaleModes::Enum inMode) override { m_ScaleMode = inMode; } - - ScaleModes::Enum GetScaleMode() override { return m_ScaleMode; } - - void SetWireframeMode(bool inEnable) override { m_WireframeMode = inEnable; } - - bool GetWireframeMode() override { return m_WireframeMode; } - - void SetViewport(Option inViewport) override { m_Viewport = inViewport; } - Option GetViewport() const override { return m_Viewport; } - - IRenderWidgetContext &GetRenderWidgetContext() override - { - return m_Renderer->GetRenderWidgetContext(); - } - - eastl::pair GetPresentationViewportAndOuterViewport() const - { - QSize thePresentationDimensions(m_PresentationDimensions); - NVRenderRect theOuterViewport(GetContextViewport()); - if (m_Rotation == RenderRotationValues::Clockwise90 - || m_Rotation == RenderRotationValues::Clockwise270) { - eastl::swap(theOuterViewport.m_Width, theOuterViewport.m_Height); - eastl::swap(theOuterViewport.m_X, theOuterViewport.m_Y); - } - // Calculate the presentation viewport perhaps with the window width and height swapped. - return eastl::make_pair( - GetPresentationViewport(theOuterViewport, m_ScaleMode, thePresentationDimensions), - theOuterViewport); - } - - NVRenderRectF GetDisplayViewport() const override - { - return GetPresentationViewportAndOuterViewport().first; - } - - void SetPresentationDimensions(const QSize &inPresentationDimensions) override - { - m_PresentationDimensions = inPresentationDimensions; - } - QSize GetCurrentPresentationDimensions() const override - { - return m_PresentationDimensions; - } - - void SetRenderRotation(RenderRotationValues::Enum inRotation) override - { - m_Rotation = inRotation; - } - - RenderRotationValues::Enum GetRenderRotation() const override { return m_Rotation; } - QT3DSVec2 GetMousePickViewport() const override - { - bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation; - if (renderOffscreen) - return QT3DSVec2((QT3DSF32)m_PresentationViewport.m_Width, - (QT3DSF32)m_PresentationViewport.m_Height); - else - return QT3DSVec2((QT3DSF32)m_WindowDimensions.width(), (QT3DSF32)m_WindowDimensions.height()); - } - NVRenderRect GetContextViewport() const override - { - NVRenderRect retval; - if (m_Viewport.hasValue()) - retval = *m_Viewport; - else - retval = NVRenderRect(0, 0, m_WindowDimensions.width(), m_WindowDimensions.height()); - - return retval; - } - - QT3DSVec2 GetMousePickMouseCoords(const QT3DSVec2 &inMouseCoords) const override - { - bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation; - if (renderOffscreen) { - QSize thePresentationDimensions(m_RenderPresentationDimensions); - NVRenderRect theViewport(GetContextViewport()); - // Calculate the presentation viewport perhaps with the presentation width and height - // swapped. - NVRenderRect thePresentationViewport = - GetPresentationViewport(theViewport, m_ScaleMode, thePresentationDimensions); - // Translate pick into presentation space without rotations or anything else. - QT3DSF32 YHeightDiff = (QT3DSF32)((QT3DSF32)m_WindowDimensions.height() - - (QT3DSF32)thePresentationViewport.m_Height); - QT3DSVec2 theLocalMouse((inMouseCoords.x - thePresentationViewport.m_X), - (inMouseCoords.y - YHeightDiff + thePresentationViewport.m_Y)); - switch (m_Rotation) { - default: - case RenderRotationValues::NoRotation: - QT3DS_ASSERT(false); - break; - case RenderRotationValues::Clockwise90: - eastl::swap(theLocalMouse.x, theLocalMouse.y); - theLocalMouse.y = thePresentationViewport.m_Width - theLocalMouse.y; - break; - case RenderRotationValues::Clockwise180: - theLocalMouse.y = thePresentationViewport.m_Height - theLocalMouse.y; - theLocalMouse.x = thePresentationViewport.m_Width - theLocalMouse.x; - break; - case RenderRotationValues::Clockwise270: - eastl::swap(theLocalMouse.x, theLocalMouse.y); - theLocalMouse.x = thePresentationViewport.m_Height - theLocalMouse.x; - break; - } - return theLocalMouse; - } - return inMouseCoords; - } - - NVRenderRect GetPresentationViewport(const NVRenderRect &inViewerViewport, - ScaleModes::Enum inScaleToFit, - const QSize &inPresDimensions) const - { - NVRenderRect retval; - QT3DSI32 theWidth = inViewerViewport.m_Width; - QT3DSI32 theHeight = inViewerViewport.m_Height; - if (inPresDimensions.width() == 0 || inPresDimensions.height() == 0) - return NVRenderRect(0, 0, 0, 0); - // Setup presentation viewport. This may or may not match the physical viewport that we - // want to setup. - // Avoiding scaling keeps things as sharp as possible. - if (inScaleToFit == ScaleModes::ExactSize) { - retval.m_Width = inPresDimensions.width(); - retval.m_Height = inPresDimensions.height(); - retval.m_X = (theWidth - (QT3DSI32)inPresDimensions.width()) / 2; - retval.m_Y = (theHeight - (QT3DSI32)inPresDimensions.height()) / 2; - } else if (inScaleToFit == ScaleModes::ScaleToFit - || inScaleToFit == ScaleModes::FitSelected) { - // Scale down in such a way to preserve aspect ratio. - float screenAspect = (float)theWidth / (float)theHeight; - float thePresentationAspect = - (float)inPresDimensions.width() / (float)inPresDimensions.height(); - if (screenAspect >= thePresentationAspect) { - // if the screen height is the limiting factor - retval.m_Y = 0; - retval.m_Height = theHeight; - retval.m_Width = (QT3DSI32)(thePresentationAspect * retval.m_Height); - retval.m_X = (theWidth - retval.m_Width) / 2; - } else { - retval.m_X = 0; - retval.m_Width = theWidth; - retval.m_Height = (QT3DSI32)(retval.m_Width / thePresentationAspect); - retval.m_Y = (theHeight - retval.m_Height) / 2; - } - } else { - // Setup the viewport for everything and let the presentations figure it out. - retval.m_X = 0; - retval.m_Y = 0; - retval.m_Width = theWidth; - retval.m_Height = theHeight; - } - retval.m_X += inViewerViewport.m_X; - retval.m_Y += inViewerViewport.m_Y; - return retval; - } - - void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, - const char *text) override - { - m_Renderer->RenderText2D(x, y, inColor, text); - } - - void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, - qt3ds::foundation::Option inColor) override - { - m_Renderer->RenderGpuProfilerStats(x, y, inColor); - } - - NVRenderRect GetPresentationViewport() const override { return m_PresentationViewport; } - struct SBeginFrameResult - { - bool m_RenderOffscreen; - QSize m_PresentationDimensions; - bool m_ScissorTestEnabled; - NVRenderRect m_ScissorRect; - NVRenderRect m_Viewport; - QSize m_FBODimensions; - SBeginFrameResult(bool ro, QSize presDims, bool scissorEnabled, - NVRenderRect scissorRect, NVRenderRect viewport, - QSize fboDims) - : m_RenderOffscreen(ro) - , m_PresentationDimensions(presDims) - , m_ScissorTestEnabled(scissorEnabled) - , m_ScissorRect(scissorRect) - , m_Viewport(viewport) - , m_FBODimensions(fboDims) - { - } - SBeginFrameResult() {} - }; - - // Calculated values passed from beginframe to setupRenderTarget. - // Trying to avoid duplicate code as much as possible. - SBeginFrameResult m_BeginFrameResult; - - void BeginFrame() override - { - m_PreRenderPresentationDimensions = m_PresentationDimensions; - QSize thePresentationDimensions(m_PreRenderPresentationDimensions); - NVRenderRect theContextViewport(GetContextViewport()); - m_PerFrameAllocator.reset(); - IRenderList &theRenderList(*m_RenderList); - theRenderList.BeginFrame(); - if (m_Viewport.hasValue()) { - theRenderList.SetScissorTestEnabled(true); - theRenderList.SetScissorRect(theContextViewport); - } else { - theRenderList.SetScissorTestEnabled(false); - } - bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation; - eastl::pair thePresViewportAndOuterViewport = - GetPresentationViewportAndOuterViewport(); - NVRenderRect theOuterViewport = thePresViewportAndOuterViewport.second; - // Calculate the presentation viewport perhaps with the window width and height swapped. - NVRenderRect thePresentationViewport = thePresViewportAndOuterViewport.first; - m_PresentationViewport = thePresentationViewport; - m_PresentationScale = QT3DSVec2( - (QT3DSF32)thePresentationViewport.m_Width / (QT3DSF32)thePresentationDimensions.width(), - (QT3DSF32)thePresentationViewport.m_Height / (QT3DSF32)thePresentationDimensions.height()); - QSize fboDimensions; - if (thePresentationViewport.m_Width > 0 && thePresentationViewport.m_Height > 0) { - if (renderOffscreen == false) { - m_PresentationDimensions = QSize(thePresentationViewport.m_Width, - thePresentationViewport.m_Height); - m_RenderList->SetViewport(thePresentationViewport); - if (thePresentationViewport.m_X || thePresentationViewport.m_Y - || thePresentationViewport.m_Width != (QT3DSI32)theOuterViewport.m_Width - || thePresentationViewport.m_Height != (QT3DSI32)theOuterViewport.m_Height) { - m_RenderList->SetScissorRect(thePresentationViewport); - m_RenderList->SetScissorTestEnabled(true); - } - } else { - QT3DSU32 imageWidth = ITextRenderer::NextMultipleOf4(thePresentationViewport.m_Width); - QT3DSU32 imageHeight = - ITextRenderer::NextMultipleOf4(thePresentationViewport.m_Height); - fboDimensions = QSize(imageWidth, imageHeight); - m_PresentationDimensions = QSize(thePresentationViewport.m_Width, - thePresentationViewport.m_Height); - NVRenderRect theSceneViewport = NVRenderRect(0, 0, imageWidth, imageHeight); - m_RenderList->SetScissorTestEnabled(false); - m_RenderList->SetViewport(theSceneViewport); - } - } - - m_BeginFrameResult = SBeginFrameResult( - renderOffscreen, m_PresentationDimensions, m_RenderList->IsScissorTestEnabled(), - m_RenderList->GetScissor(), m_RenderList->GetViewport(), fboDimensions); - - m_Renderer->BeginFrame(); - m_OffscreenRenderManager->BeginFrame(); - if (m_TextRenderer) - m_TextRenderer->BeginFrame(); - if (m_TextTextureCache) - m_TextTextureCache->BeginFrame(); - m_ImageBatchLoader->BeginFrame(); - } - - QT3DSVec2 GetPresentationScaleFactor() const override { return m_PresentationScale; } - - virtual void SetupRenderTarget() - { - NVRenderRect theContextViewport(GetContextViewport()); - if (m_Viewport.hasValue()) { - m_RenderContext->SetScissorTestEnabled(true); - m_RenderContext->SetScissorRect(theContextViewport); - } else { - m_RenderContext->SetScissorTestEnabled(false); - } - { - QT3DSVec4 theClearColor; - if (m_MatteColor.hasValue()) - theClearColor = m_MatteColor; - else - theClearColor = m_SceneColor; - m_RenderContext->SetClearColor(theClearColor); - m_RenderContext->Clear(qt3ds::render::NVRenderClearValues::Color); - } - bool renderOffscreen = m_BeginFrameResult.m_RenderOffscreen; - m_RenderContext->SetViewport(m_BeginFrameResult.m_Viewport); - m_RenderContext->SetScissorRect(m_BeginFrameResult.m_ScissorRect); - m_RenderContext->SetScissorTestEnabled(m_BeginFrameResult.m_ScissorTestEnabled); - - if (m_PresentationViewport.m_Width > 0 && m_PresentationViewport.m_Height > 0) { - if (renderOffscreen == false) { - if (m_RotationFBO != NULL) { - m_ResourceManager->Release(*m_RotationFBO); - m_ResourceManager->Release(*m_RotationTexture); - m_ResourceManager->Release(*m_RotationDepthBuffer); - m_RotationFBO = NULL; - m_RotationTexture = NULL; - m_RotationDepthBuffer = NULL; - } - if (m_SceneColor.hasValue() && m_SceneColor.getValue().w != 0.0f) { - m_RenderContext->SetClearColor(m_SceneColor); - m_RenderContext->Clear(qt3ds::render::NVRenderClearValues::Color); - } - } else { - QT3DSU32 imageWidth = m_BeginFrameResult.m_FBODimensions.width(); - QT3DSU32 imageHeight = m_BeginFrameResult.m_FBODimensions.height(); - NVRenderTextureFormats::Enum theColorBufferFormat = NVRenderTextureFormats::RGBA8; - NVRenderRenderBufferFormats::Enum theDepthBufferFormat = - NVRenderRenderBufferFormats::Depth16; - m_ContextRenderTarget = m_RenderContext->GetRenderTarget(); - if (m_RotationFBO == NULL) { - m_RotationFBO = m_ResourceManager->AllocateFrameBuffer(); - m_RotationTexture = m_ResourceManager->AllocateTexture2D( - imageWidth, imageHeight, theColorBufferFormat); - m_RotationDepthBuffer = m_ResourceManager->AllocateRenderBuffer( - imageWidth, imageHeight, theDepthBufferFormat); - m_RotationFBO->Attach(NVRenderFrameBufferAttachments::Color0, - *m_RotationTexture); - m_RotationFBO->Attach(NVRenderFrameBufferAttachments::Depth, - *m_RotationDepthBuffer); - } else { - STextureDetails theDetails = m_RotationTexture->GetTextureDetails(); - if (theDetails.m_Width != imageWidth || theDetails.m_Height != imageHeight) { - m_RotationTexture->SetTextureData(NVDataRef(), 0, imageWidth, - imageHeight, theColorBufferFormat); - m_RotationDepthBuffer->SetDimensions( - qt3ds::render::NVRenderRenderBufferDimensions(imageWidth, imageHeight)); - } - } - m_RenderContext->SetRenderTarget(m_RotationFBO); - if (m_SceneColor.hasValue()) { - m_RenderContext->SetClearColor(m_SceneColor); - m_RenderContext->Clear(qt3ds::render::NVRenderClearValues::Color); - } - } - } - } - - void RunRenderTasks() override - { - m_RenderList->RunRenderTasks(); - SetupRenderTarget(); - } - - // Note this runs before EndFrame - virtual void TeardownRenderTarget() - { - if (m_RotationFBO) { - ScaleModes::Enum theScaleToFit = m_ScaleMode; - NVRenderRect theOuterViewport(GetContextViewport()); - m_RenderContext->SetRenderTarget(m_ContextRenderTarget); - QSize thePresentationDimensions = GetCurrentPresentationDimensions(); - if (m_Rotation == RenderRotationValues::Clockwise90 - || m_Rotation == RenderRotationValues::Clockwise270) { - thePresentationDimensions = QSize(thePresentationDimensions.height(), - thePresentationDimensions.width()); - } - m_RenderPresentationDimensions = thePresentationDimensions; - // Calculate the presentation viewport perhaps with the presentation width and height - // swapped. - NVRenderRect thePresentationViewport = - GetPresentationViewport(theOuterViewport, theScaleToFit, thePresentationDimensions); - SCamera theCamera; - switch (m_Rotation) { - default: - QT3DS_ASSERT(false); - break; - case RenderRotationValues::Clockwise90: - theCamera.m_Rotation.z = 90; - break; - case RenderRotationValues::Clockwise180: - theCamera.m_Rotation.z = 180; - break; - case RenderRotationValues::Clockwise270: - theCamera.m_Rotation.z = 270; - break; - } - TORAD(theCamera.m_Rotation.z); - theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - theCamera.m_Flags.SetOrthographic(true); - m_RenderContext->SetViewport(thePresentationViewport); - QT3DSVec2 theCameraDimensions((QT3DSF32)thePresentationViewport.m_Width, - (QT3DSF32)thePresentationViewport.m_Height); - theCamera.CalculateGlobalVariables( - NVRenderRect(0, 0, (QT3DSU32)thePresentationViewport.m_Width, - (QT3DSU32)thePresentationViewport.m_Height), - theCameraDimensions); - QT3DSMat44 theVP; - theCamera.CalculateViewProjectionMatrix(theVP); - SNode theTempNode; - theTempNode.CalculateGlobalVariables(); - QT3DSMat44 theMVP; - QT3DSMat33 theNormalMat; - theTempNode.CalculateMVPAndNormalMatrix(theVP, theMVP, theNormalMat); - m_RenderContext->SetCullingEnabled(false); - m_RenderContext->SetBlendingEnabled(false); - m_RenderContext->SetDepthTestEnabled(false); - m_Renderer->RenderQuad(QT3DSVec2((QT3DSF32)m_PresentationViewport.m_Width, - (QT3DSF32)m_PresentationViewport.m_Height), - theMVP, *m_RotationTexture); - } - } - - void EndFrame() override - { - TeardownRenderTarget(); - m_ImageBatchLoader->EndFrame(); - if (m_TextTextureCache) - m_TextTextureCache->EndFrame(); - if (m_TextRenderer) - m_TextRenderer->EndFrame(); - m_OffscreenRenderManager->EndFrame(); - m_Renderer->EndFrame(); - m_CustomMaterialSystem->EndFrame(); - m_PresentationDimensions = m_PreRenderPresentationDimensions; - ++m_FrameCount; - } -}; - -IQt3DSRenderContext &SRenderContextCore::CreateRenderContext(NVRenderContext &inContext, - const char8_t *inPrimitivesDirectory) -{ - return *QT3DS_NEW(m_Foundation.getAllocator(), SRenderContext)(inContext, *this, - inPrimitivesDirectory); -} -} - -IQt3DSRenderContextCore &IQt3DSRenderContextCore::Create(NVFoundationBase &fnd, IStringTable &strt) -{ - return *QT3DS_NEW(fnd.getAllocator(), SRenderContextCore)(fnd, strt); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp deleted file mode 100644 index fe6a6dc3..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp +++ /dev/null @@ -1,1261 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderCustomMaterialShaderGenerator.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderableImage.h" -#include "Qt3DSRenderImage.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderLight.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderShadowMap.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderLightConstantProperties.h" - -using namespace qt3ds::render; -using qt3ds::render::NVRenderCachedShaderProperty; -using qt3ds::render::NVRenderCachedShaderBuffer; - -namespace { -struct SShaderLightProperties -{ - NVScopedRefCounted m_Shader; - RenderLightTypes::Enum m_LightType; - SLightSourceShader m_LightData; - volatile QT3DSI32 mRefCount; - - SShaderLightProperties(NVRenderShaderProgram &inShader) - : m_Shader(inShader) - , m_LightType(RenderLightTypes::Directional) - , mRefCount(0) - { - } - - void Set(const SLight *inLight) - { - QT3DSVec3 dir(0, 0, 1); - if (inLight->m_LightType == RenderLightTypes::Directional) { - dir = inLight->GetScalingCorrectDirection(); - // we lit in world sapce - dir *= -1; - m_LightData.m_position = QT3DSVec4(dir, 0.0); - } else if (inLight->m_LightType == RenderLightTypes::Area) { - dir = inLight->GetScalingCorrectDirection(); - m_LightData.m_position = QT3DSVec4(inLight->GetGlobalPos(), 1.0); - } else { - dir = inLight->GetGlobalPos(); - m_LightData.m_position = QT3DSVec4(dir, 1.0); - } - - m_LightType = inLight->m_LightType; - - m_LightData.m_direction = QT3DSVec4(dir, 0.0); - - float normalizedBrightness = inLight->m_Brightness / 100.0f; - m_LightData.m_diffuse = QT3DSVec4(inLight->m_DiffuseColor * normalizedBrightness, 1.0); - m_LightData.m_specular = QT3DSVec4(inLight->m_SpecularColor * normalizedBrightness, 1.0); - - if (inLight->m_LightType == RenderLightTypes::Area) { - m_LightData.m_width = inLight->m_AreaWidth; - m_LightData.m_height = inLight->m_AreaWidth; - - QT3DSMat33 theDirMatrix(inLight->m_GlobalTransform.getUpper3x3()); - m_LightData.m_right = - QT3DSVec4(theDirMatrix.transform(QT3DSVec3(1, 0, 0)), inLight->m_AreaWidth); - m_LightData.m_up = - QT3DSVec4(theDirMatrix.transform(QT3DSVec3(0, 1, 0)), inLight->m_AreaHeight); - } else { - m_LightData.m_width = 0.0; - m_LightData.m_height = 0.0; - m_LightData.m_right = QT3DSVec4(0.0f); - m_LightData.m_up = QT3DSVec4(0.0f); - - // These components only apply to CG lights - m_LightData.m_ambient = QT3DSVec4(inLight->m_AmbientColor, 1.0); - - m_LightData.m_constantAttenuation = 1.0; - m_LightData.m_linearAttenuation = inLight->m_LinearFade; - m_LightData.m_quadraticAttenuation = inLight->m_ExponentialFade; - m_LightData.m_spotCutoff = 180.0; - } - - if (m_LightType == RenderLightTypes::Point) { - m_LightData.m_shadowView = QT3DSMat44::createIdentity(); - } else { - m_LightData.m_shadowView = inLight->m_GlobalTransform; - } - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) - - static SShaderLightProperties CreateLightEntry(NVRenderShaderProgram &inShader) - { - return SShaderLightProperties(inShader); - } -}; - -/** - * Cached texture property lookups, used one per texture so a shader generator for N - * textures will have an array of N of these lookup objects. - */ -struct SShaderTextureProperties -{ - NVRenderCachedShaderProperty m_Sampler; - NVRenderCachedShaderProperty m_Offsets; - NVRenderCachedShaderProperty m_Rotations; - SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, - NVRenderShaderProgram &inShader) - : m_Sampler(sampName, inShader) - , m_Offsets(offName, inShader) - , m_Rotations(rotName, inShader) - { - } - SShaderTextureProperties() {} -}; - -/* We setup some shared state on the custom material shaders */ -struct SShaderGeneratorGeneratedShader -{ - typedef nvhash_map TCustomMaterialImagMap; - - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - // Specific properties we know the shader has to have. - NVRenderCachedShaderProperty m_ModelMatrix; - NVRenderCachedShaderProperty m_ViewProjMatrix; - NVRenderCachedShaderProperty m_ViewMatrix; - NVRenderCachedShaderProperty m_NormalMatrix; - NVRenderCachedShaderProperty m_CameraPos; - NVRenderCachedShaderProperty m_ProjMatrix; - NVRenderCachedShaderProperty m_ViewportMatrix; - NVRenderCachedShaderProperty m_CamProperties; - NVRenderCachedShaderProperty m_DepthTexture; - NVRenderCachedShaderProperty m_AOTexture; - NVRenderCachedShaderProperty m_LightProbe; - NVRenderCachedShaderProperty m_LightProbeProps; - NVRenderCachedShaderProperty m_LightProbeOpts; - NVRenderCachedShaderProperty m_LightProbeRot; - NVRenderCachedShaderProperty m_LightProbeOfs; - NVRenderCachedShaderProperty m_LightProbe2; - NVRenderCachedShaderProperty m_LightProbe2Props; - NVRenderCachedShaderProperty m_LightCount; - NVRenderCachedShaderProperty m_AreaLightCount; - NVRenderCachedShaderProperty m_ShadowMapCount; - NVRenderCachedShaderProperty m_ShadowCubeCount; - NVRenderCachedShaderProperty m_Opacity; - NVRenderCachedShaderBuffer m_AoShadowParams; - NVRenderCachedShaderBuffer m_LightsBuffer; - NVRenderCachedShaderBuffer m_AreaLightsBuffer; - - SLightConstantProperties *m_lightsProperties; - SLightConstantProperties *m_areaLightsProperties; - - typedef NVRenderCachedShaderPropertyArray ShadowMapPropertyArray; - typedef NVRenderCachedShaderPropertyArray ShadowCubePropertyArray; - - ShadowMapPropertyArray m_shadowMaps; - ShadowCubePropertyArray m_shadowCubes; - - // Cache the image property name lookups - TCustomMaterialImagMap m_Images; // Images external to custom material usage - volatile QT3DSI32 m_RefCount; - - SShaderGeneratorGeneratedShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) - : m_Allocator(inContext.GetAllocator()) - , m_Shader(inShader) - , m_ModelMatrix("model_matrix", inShader) - , m_ViewProjMatrix("model_view_projection", inShader) - , m_ViewMatrix("view_matrix", inShader) - , m_NormalMatrix("normal_matrix", inShader) - , m_CameraPos("camera_position", inShader) - , m_ProjMatrix("view_projection_matrix", inShader) - , m_ViewportMatrix("viewport_matrix", inShader) - , m_CamProperties("camera_properties", inShader) - , m_DepthTexture("depth_sampler", inShader) - , m_AOTexture("ao_sampler", inShader) - , m_LightProbe("light_probe", inShader) - , m_LightProbeProps("light_probe_props", inShader) - , m_LightProbeOpts("light_probe_opts", inShader) - , m_LightProbeRot("light_probe_rotation", inShader) - , m_LightProbeOfs("light_probe_offset", inShader) - , m_LightProbe2("light_probe2", inShader) - , m_LightProbe2Props("light_probe2_props", inShader) - , m_LightCount("uNumLights", inShader) - , m_AreaLightCount("uNumAreaLights", inShader) - , m_ShadowMapCount("uNumShadowMaps", inShader) - , m_ShadowCubeCount("uNumShadowCubes", inShader) - , m_Opacity("object_opacity", inShader) - , m_AoShadowParams("cbAoShadow", inShader) - , m_LightsBuffer("cbBufferLights", inShader) - , m_AreaLightsBuffer("cbBufferAreaLights", inShader) - , m_lightsProperties(nullptr) - , m_areaLightsProperties(nullptr) - , m_shadowMaps("shadowMaps[0]", inShader) - , m_shadowCubes("shadowCubes[0]", inShader) - , m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images") - , m_RefCount(0) - { - m_Shader.addRef(); - } - - ~SShaderGeneratorGeneratedShader() - { - m_Shader.release(); - delete m_lightsProperties; - delete m_areaLightsProperties; - } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Allocator); - NVDelete(alloc, this); - } - } - - SLightConstantProperties *GetLightProperties(int count) - { - if (!m_lightsProperties || m_areaLightsProperties->m_lightCountInt < count) { - if (m_lightsProperties) - delete m_lightsProperties; - m_lightsProperties = new SLightConstantProperties - ("lights", "uNumLights", *this, false, count); - } - return m_lightsProperties; - } - SLightConstantProperties *GetAreaLightProperties(int count) - { - if (!m_areaLightsProperties || m_areaLightsProperties->m_lightCountInt < count) { - if (m_areaLightsProperties) - delete m_areaLightsProperties; - m_areaLightsProperties = new SLightConstantProperties - ("areaLights", "uNumAreaLights", *this, false, count); - } - return m_areaLightsProperties; - } -}; - -struct SShaderGenerator : public ICustomMaterialShaderGenerator -{ - typedef CRenderString TStrType; - typedef nvhash_map> - TProgramToShaderMap; - typedef eastl::pair> - TCustomMaterialLightEntry; - typedef eastl::pair> TShadowMapEntry; - typedef eastl::pair> - TShadowCubeEntry; - typedef qt3ds::foundation::nvhash_map> - TStrConstanBufMap; - - IQt3DSRenderContext &m_RenderContext; - IShaderProgramGenerator &m_ProgramGenerator; - - const SCustomMaterial *m_CurrentMaterial; - SShaderDefaultMaterialKey *m_CurrentKey; - IDefaultMaterialVertexPipeline *m_CurrentPipeline; - TShaderFeatureSet m_CurrentFeatureSet; - NVDataRef m_Lights; - SRenderableImage *m_FirstImage; - bool m_HasTransparency; - - TStrType m_ImageStem; - TStrType m_ImageSampler; - TStrType m_ImageFragCoords; - TStrType m_ImageRotScale; - TStrType m_ImageOffset; - - eastl::string m_GeneratedShaderString; - - SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; - TProgramToShaderMap m_ProgramToShaderMap; - - nvvector m_LightEntries; - - TStrConstanBufMap m_ConstantBuffers; ///< store all constants buffers - - QT3DSI32 m_RefCount; - - SShaderGenerator(IQt3DSRenderContext &inRc) - : m_RenderContext(inRc) - , m_ProgramGenerator(m_RenderContext.GetShaderProgramGenerator()) - , m_CurrentMaterial(NULL) - , m_CurrentKey(NULL) - , m_CurrentPipeline(NULL) - , m_FirstImage(NULL) - , m_HasTransparency(false) - , m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap") - , m_LightEntries(inRc.GetAllocator(), "m_LightEntries") - , m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers") - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - m_ConstantBuffers.clear(); - NVDelete(m_RenderContext.GetAllocator(), this); - } - } - - IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } - IDefaultMaterialVertexPipeline &VertexGenerator() { return *m_CurrentPipeline; } - IShaderStageGenerator &FragmentGenerator() - { - return *m_ProgramGenerator.GetStage(ShaderGeneratorStages::Fragment); - } - SShaderDefaultMaterialKey &Key() { return *m_CurrentKey; } - const SCustomMaterial &Material() { return *m_CurrentMaterial; } - TShaderFeatureSet FeatureSet() { return m_CurrentFeatureSet; } - bool HasTransparency() { return m_HasTransparency; } - - QT3DSU32 - ConvertTextureTypeValue(ImageMapTypes::Enum inType) - { - NVRenderTextureTypeValue::Enum retVal = NVRenderTextureTypeValue::Unknown; - - switch (inType) { - case ImageMapTypes::LightmapIndirect: - retVal = NVRenderTextureTypeValue::LightmapIndirect; - break; - case ImageMapTypes::LightmapRadiosity: - retVal = NVRenderTextureTypeValue::LightmapRadiosity; - break; - case ImageMapTypes::LightmapShadow: - retVal = NVRenderTextureTypeValue::LightmapShadow; - break; - case ImageMapTypes::Bump: - retVal = NVRenderTextureTypeValue::Bump; - break; - case ImageMapTypes::Diffuse: - retVal = NVRenderTextureTypeValue::Diffuse; - break; - case ImageMapTypes::Displacement: - retVal = NVRenderTextureTypeValue::Displace; - break; - default: - retVal = NVRenderTextureTypeValue::Unknown; - break; - } - - QT3DS_ASSERT(retVal != NVRenderTextureTypeValue::Unknown); - - return (QT3DSU32)retVal; - } - - SImageVariableNames GetImageVariableNames(QT3DSU32 imageIdx) override - { - // convert to NVRenderTextureTypeValue - NVRenderTextureTypeValue::Enum texType = (NVRenderTextureTypeValue::Enum)imageIdx; - m_ImageStem = NVRenderTextureTypeValue::toString(texType); - m_ImageStem.append("_"); - m_ImageSampler = m_ImageStem; - m_ImageSampler.append("sampler"); - m_ImageFragCoords = m_ImageStem; - m_ImageFragCoords.append("uv_coords"); - m_ImageRotScale = m_ImageStem; - m_ImageRotScale.append("rot_scale"); - m_ImageOffset = m_ImageStem; - m_ImageOffset.append("offset"); - - SImageVariableNames retVal; - retVal.m_ImageSampler = m_ImageSampler.c_str(); - retVal.m_ImageFragCoords = m_ImageFragCoords.c_str(); - return retVal; - } - - void SetImageShaderVariables(SShaderGeneratorGeneratedShader &inShader, - SRenderableImage &inImage) - { - // skip displacement and emissive mask maps which are handled differently - if (inImage.m_MapType == ImageMapTypes::Displacement - || inImage.m_MapType == ImageMapTypes::Emissive) - return; - - SShaderGeneratorGeneratedShader::TCustomMaterialImagMap::iterator iter = - inShader.m_Images.find(inImage.m_MapType); - if (iter == inShader.m_Images.end()) { - SImageVariableNames names = - GetImageVariableNames(ConvertTextureTypeValue(inImage.m_MapType)); - inShader.m_Images.insert(eastl::make_pair( - (QT3DSU32)inImage.m_MapType, - SShaderTextureProperties(names.m_ImageSampler, m_ImageOffset.c_str(), - m_ImageRotScale.c_str(), inShader.m_Shader))); - iter = inShader.m_Images.find(inImage.m_MapType); - } - - SShaderTextureProperties &theShaderProps = iter->second; - const QT3DSMat44 &textureTransform = inImage.m_Image.m_TextureTransform; - const QT3DSF32 *dataPtr(textureTransform.front()); - QT3DSVec3 offsets(dataPtr[12], dataPtr[13], 0.0f); - // Grab just the upper 2x2 rotation matrix from the larger matrix. - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - - // The image horizontal and vertical tiling modes need to be set here, before we set texture - // on the shader. - // because setting the image on the texture forces the textue to bind and immediately apply - // any tex params. - inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapS( - inImage.m_Image.m_HorizontalTilingMode); - inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapT( - inImage.m_Image.m_VerticalTilingMode); - - theShaderProps.m_Sampler.Set(inImage.m_Image.m_TextureData.m_Texture); - theShaderProps.m_Offsets.Set(offsets); - theShaderProps.m_Rotations.Set(rotations); - } - - void GenerateImageUVCoordinates(IShaderStageGenerator &, QT3DSU32, QT3DSU32, SRenderableImage &) override {} - - ///< get the light constant buffer and generate if necessary - NVRenderConstantBuffer *GetLightConstantBuffer(const char *name, QT3DSU32 inLightCount) - { - NVRenderContext &theContext(m_RenderContext.GetRenderContext()); - - // we assume constant buffer support - QT3DS_ASSERT(theContext.GetConstantBufferSupport()); - // we only create if if we have lights - if (!inLightCount || !theContext.GetConstantBufferSupport()) - return NULL; - - CRegisteredString theName = theContext.GetStringTable().RegisterStr(name); - NVRenderConstantBuffer *pCB = theContext.GetConstantBuffer(theName); - - if (!pCB) { - // create with size of all structures + int for light count - SLightSourceShader s[QT3DS_MAX_NUM_LIGHTS]; - NVDataRef cBuffer((QT3DSU8 *)&s, (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) - + (4 * sizeof(QT3DSI32))); - pCB = theContext.CreateConstantBuffer( - name, qt3ds::render::NVRenderBufferUsageType::Static, - (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + (4 * sizeof(QT3DSI32)), cBuffer); - if (!pCB) { - QT3DS_ASSERT(false); - return NULL; - } - // init first set - memset(&s[0], 0x0, sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS); - QT3DSI32 cgLights[4] = {0, 0, 0, 0}; - pCB->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32) * 4)); - pCB->UpdateRaw(4 * sizeof(QT3DSI32), - NVDataRef((QT3DSU8 *)&s[0], - sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS)); - pCB->Update(); // update to hardware - - m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); - } - - return pCB; - } - - bool GenerateVertexShader(SShaderDefaultMaterialKey &, const char8_t *inShaderPathName) - { - qt3ds::render::IDynamicObjectSystem &theDynamicSystem( - m_RenderContext.GetDynamicObjectSystem()); - CRenderString theShaderBuffer; - const char8_t *vertSource = theDynamicSystem.GetShaderSource( - m_RenderContext.GetStringTable().RegisterStr(inShaderPathName), theShaderBuffer); - - QT3DS_ASSERT(vertSource); - eastl::string srcString(vertSource); - - // Check if the vertex shader portion already contains a main function - // The same string contains both the vertex and the fragment shader - // The last "#ifdef FRAGMENT_SHADER" should mark the start of the fragment shader - eastl_size_t fragmentDefStart = srcString.find("#ifdef FRAGMENT_SHADER"); - eastl_size_t nextIndex = fragmentDefStart; - while (nextIndex != eastl::string::npos) { - nextIndex = srcString.find("#ifdef FRAGMENT_SHADER", nextIndex + 1); - if (nextIndex != eastl::string::npos) - fragmentDefStart = nextIndex; - } - eastl_size_t mainStart = srcString.find("void main()"); - - if (mainStart != eastl::string::npos && (fragmentDefStart == eastl::string::npos - || mainStart < fragmentDefStart)) { - TShaderGeneratorStageFlags stages(IShaderProgramGenerator::DefaultFlags()); - ProgramGenerator().BeginProgram(stages); - IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); - vertexShader << "#define VERTEX_SHADER\n\n"; - vertexShader << srcString.data() << Endl; - return true; - } - - // vertex displacement - QT3DSU32 imageIdx = 0; - SRenderableImage *displacementImage = NULL; - QT3DSU32 displacementImageIdx = 0; - - for (SRenderableImage *img = m_FirstImage; img != NULL; - img = img->m_NextImage, ++imageIdx) { - if (img->m_MapType == ImageMapTypes::Displacement) { - displacementImage = img; - displacementImageIdx = imageIdx; - break; - } - } - - // the pipeline opens/closes up the shaders stages - VertexGenerator().BeginVertexGeneration(displacementImageIdx, displacementImage); - return false; - } - - SShaderGeneratorGeneratedShader &GetShaderForProgram(NVRenderShaderProgram &inProgram) - { - eastl::pair inserter = - m_ProgramToShaderMap.insert(eastl::make_pair( - &inProgram, NVScopedRefCounted(NULL))); - if (inserter.second) { - NVAllocatorCallback &alloc(m_RenderContext.GetRenderContext().GetAllocator()); - inserter.first->second = QT3DS_NEW(alloc, SShaderGeneratorGeneratedShader)( - inProgram, m_RenderContext.GetRenderContext()); - } - return *inserter.first->second; - } - - virtual SShaderLightProperties *SetLight(NVRenderShaderProgram &inShader, size_t lightIdx, - size_t shadeIdx, const SLight *inLight, - SShadowMapEntry *inShadow, QT3DSI32 shadowIdx, - QT3DSF32 shadowDist) - { - SShaderLightProperties *theLightEntry(NULL); - for (QT3DSU32 idx = 0, end = m_LightEntries.size(); idx < end && theLightEntry == NULL; - ++idx) { - if (m_LightEntries[idx].first == lightIdx - && m_LightEntries[idx].second->m_Shader.mPtr == &inShader - && m_LightEntries[idx].second->m_LightType == inLight->m_LightType) { - theLightEntry = m_LightEntries[idx].second; - } - } - if (theLightEntry == NULL) { - // create a new name - eastl::string lightName; - if (inLight->m_LightType == RenderLightTypes::Area) - lightName = "arealights"; - else - lightName = "lights"; - char buf[16]; - _snprintf(buf, 16, "[%d]", int(shadeIdx)); - lightName.append(buf); - - NVScopedRefCounted theNewEntry = - QT3DS_NEW(m_RenderContext.GetAllocator(), - SShaderLightProperties)(SShaderLightProperties::CreateLightEntry(inShader)); - m_LightEntries.push_back(eastl::make_pair(lightIdx, theNewEntry)); - theLightEntry = theNewEntry.mPtr; - } - theLightEntry->Set(inLight); - theLightEntry->m_LightData.m_shadowControls = - QT3DSVec4(inLight->m_ShadowBias, inLight->m_ShadowFactor, shadowDist, 0.0); - theLightEntry->m_LightData.m_shadowIdx = (inShadow) ? shadowIdx : -1; - - return theLightEntry; - } - - void SetShadowMaps(NVRenderShaderProgram &inProgram, SShadowMapEntry *inShadow, - QT3DSI32 &numShadowMaps, QT3DSI32 &numShadowCubes, bool shadowMap, - SShaderGeneratorGeneratedShader::ShadowMapPropertyArray &shadowMaps, - SShaderGeneratorGeneratedShader::ShadowCubePropertyArray &shadowCubes) - { - Q_UNUSED(inProgram) - if (inShadow) { - if (shadowMap == false && inShadow->m_DepthCube - && (numShadowCubes < QT3DS_MAX_NUM_SHADOWS)) { - shadowCubes.m_array[numShadowCubes] = inShadow->m_DepthCube.mPtr; - ++numShadowCubes; - } else if (shadowMap && inShadow->m_DepthMap - && (numShadowMaps < QT3DS_MAX_NUM_SHADOWS)) { - shadowMaps.m_array[numShadowMaps] = inShadow->m_DepthMap.mPtr; - ++numShadowMaps; - } - } - } - - void SetGlobalProperties(NVRenderShaderProgram &inProgram, const SLayer & /*inLayer*/ - , - SCamera &inCamera, QT3DSVec3, NVDataRef inLights, - NVDataRef, Qt3DSShadowMap *inShadowMaps) - { - SShaderGeneratorGeneratedShader &theShader(GetShaderForProgram(inProgram)); - m_RenderContext.GetRenderContext().SetActiveShader(&inProgram); - - SCamera &theCamera(inCamera); - - QT3DSVec2 camProps(theCamera.m_ClipNear, theCamera.m_ClipFar); - theShader.m_CamProperties.Set(camProps); - theShader.m_CameraPos.Set(theCamera.GetGlobalPos()); - - if (theShader.m_ViewMatrix.IsValid()) - theShader.m_ViewMatrix.Set(theCamera.m_GlobalTransform.getInverse()); - - if (theShader.m_ProjMatrix.IsValid()) { - QT3DSMat44 vProjMat; - inCamera.CalculateViewProjectionMatrix(vProjMat); - theShader.m_ProjMatrix.Set(vProjMat); - } - - // set lights separate for area lights - QT3DSI32 cgLights = 0, areaLights = 0; - QT3DSI32 numShadowMaps = 0, numShadowCubes = 0; - - // this call setup the constant buffer for ambient occlusion and shadow - theShader.m_AoShadowParams.Set(); - - if (m_RenderContext.GetRenderContext().GetConstantBufferSupport()) { - NVRenderConstantBuffer *pLightCb = - GetLightConstantBuffer("cbBufferLights", inLights.size()); - NVRenderConstantBuffer *pAreaLightCb = - GetLightConstantBuffer("cbBufferAreaLights", inLights.size()); - - // Split the count between CG lights and area lights - for (QT3DSU32 lightIdx = 0; lightIdx < inLights.size() && pLightCb; ++lightIdx) { - SShadowMapEntry *theShadow = NULL; - if (inShadowMaps && inLights[lightIdx]->m_CastShadow) - theShadow = inShadowMaps->GetShadowMapEntry(lightIdx); - - QT3DSI32 shdwIdx = (inLights[lightIdx]->m_LightType - != RenderLightTypes::Directional) - ? numShadowCubes - : numShadowMaps; - SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes, - inLights[lightIdx]->m_LightType == RenderLightTypes::Directional, - theShader.m_shadowMaps, theShader.m_shadowCubes); - - if (inLights[lightIdx]->m_LightType == RenderLightTypes::Area) { - SShaderLightProperties *theAreaLightEntry = - SetLight(inProgram, lightIdx, areaLights, inLights[lightIdx], theShadow, - shdwIdx, inCamera.m_ClipFar); - - if (theAreaLightEntry && pAreaLightCb) { - pAreaLightCb->UpdateRaw( - areaLights * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), - NVDataRef((QT3DSU8 *)&theAreaLightEntry->m_LightData, - sizeof(SLightSourceShader))); - } - - areaLights++; - } else { - SShaderLightProperties *theLightEntry = - SetLight(inProgram, lightIdx, cgLights, inLights[lightIdx], theShadow, - shdwIdx, inCamera.m_ClipFar); - - if (theLightEntry && pLightCb) { - pLightCb->UpdateRaw( - cgLights * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), - NVDataRef((QT3DSU8 *)&theLightEntry->m_LightData, - sizeof(SLightSourceShader))); - } - - cgLights++; - } - } - - if (pLightCb) { - pLightCb->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); - theShader.m_LightsBuffer.Set(); - } - if (pAreaLightCb) { - pAreaLightCb->UpdateRaw(0, NVDataRef((QT3DSU8 *)&areaLights, - sizeof(QT3DSI32))); - theShader.m_AreaLightsBuffer.Set(); - } - - theShader.m_LightCount.Set(cgLights); - theShader.m_AreaLightCount.Set(areaLights); - } else { - QVector lprop; - QVector alprop; - for (QT3DSU32 lightIdx = 0; lightIdx < inLights.size(); ++lightIdx) { - - SShadowMapEntry *theShadow = NULL; - if (inShadowMaps && inLights[lightIdx]->m_CastShadow) - theShadow = inShadowMaps->GetShadowMapEntry(lightIdx); - - QT3DSI32 shdwIdx = (inLights[lightIdx]->m_LightType - != RenderLightTypes::Directional) - ? numShadowCubes - : numShadowMaps; - SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes, - inLights[lightIdx]->m_LightType == RenderLightTypes::Directional, - theShader.m_shadowMaps, theShader.m_shadowCubes); - - SShaderLightProperties *p = SetLight(inProgram, lightIdx, areaLights, - inLights[lightIdx], theShadow, - shdwIdx, inCamera.m_ClipFar); - if (inLights[lightIdx]->m_LightType == RenderLightTypes::Area) - alprop.push_back(p); - else - lprop.push_back(p); - } - SLightConstantProperties *lightProperties - = theShader.GetLightProperties(lprop.size()); - SLightConstantProperties *areaLightProperties - = theShader.GetAreaLightProperties(alprop.size()); - - lightProperties->updateLights(lprop); - areaLightProperties->updateLights(alprop); - - theShader.m_LightCount.Set(lprop.size()); - theShader.m_AreaLightCount.Set(alprop.size()); - } - for (int i = numShadowMaps; i < QT3DS_MAX_NUM_SHADOWS; ++i) - theShader.m_shadowMaps.m_array[i] = NULL; - for (int i = numShadowCubes; i < QT3DS_MAX_NUM_SHADOWS; ++i) - theShader.m_shadowCubes.m_array[i] = NULL; - theShader.m_shadowMaps.Set(numShadowMaps); - theShader.m_shadowCubes.Set(numShadowCubes); - theShader.m_ShadowMapCount.Set(numShadowMaps); - theShader.m_ShadowCubeCount.Set(numShadowCubes); - } - - void SetMaterialProperties(NVRenderShaderProgram &inProgram, const SCustomMaterial &inMaterial, - const QT3DSVec2 &, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inSSaoTexture, - SImage *inLightProbe, SImage *inLightProbe2, QT3DSF32 inProbeHorizon, - QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, - QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) - { - ICustomMaterialSystem &theMaterialSystem(m_RenderContext.GetCustomMaterialSystem()); - SShaderGeneratorGeneratedShader &theShader(GetShaderForProgram(inProgram)); - - theShader.m_ViewProjMatrix.Set(inModelViewProjection); - theShader.m_NormalMatrix.Set(inNormalMatrix); - theShader.m_ModelMatrix.Set(inGlobalTransform); - - theShader.m_DepthTexture.Set(inDepthTexture); - theShader.m_AOTexture.Set(inSSaoTexture); - - theShader.m_Opacity.Set(inOpacity); - - qt3ds::render::SImage *theLightProbe = inLightProbe; - qt3ds::render::SImage *theLightProbe2 = inLightProbe2; - - if (inMaterial.m_IblProbe && inMaterial.m_IblProbe->m_TextureData.m_Texture) { - theLightProbe = inMaterial.m_IblProbe; - } - - if (theLightProbe) { - if (theLightProbe->m_TextureData.m_Texture) { - NVRenderTextureCoordOp::Enum theHorzLightProbeTilingMode = - theLightProbe->m_HorizontalTilingMode; - NVRenderTextureCoordOp::Enum theVertLightProbeTilingMode = - theLightProbe->m_VerticalTilingMode; - theLightProbe->m_TextureData.m_Texture->SetTextureWrapS( - theHorzLightProbeTilingMode); - theLightProbe->m_TextureData.m_Texture->SetTextureWrapT( - theVertLightProbeTilingMode); - - const QT3DSMat44 &textureTransform = theLightProbe->m_TextureTransform; - // We separate rotational information from offset information so that just maybe the - // shader - // will attempt to push less information to the card. - const QT3DSF32 *dataPtr(textureTransform.front()); - // The third member of the offsets contains a flag indicating if the texture was - // premultiplied or not. - // We use this to mix the texture alpha. - // light_probe_offsets.w is now no longer being used to enable/disable fast IBL, - // (it's now the only option) - // So now, it's storing the number of mip levels in the IBL image. - QT3DSVec4 offsets(dataPtr[12], dataPtr[13], - theLightProbe->m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f - : 0.0f, - (float)theLightProbe->m_TextureData.m_Texture->GetNumMipmaps()); - // Fast IBL is always on; - // inRenderContext.m_Layer.m_FastIbl ? 1.0f : 0.0f ); - // Grab just the upper 2x2 rotation matrix from the larger matrix. - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - - theShader.m_LightProbeRot.Set(rotations); - theShader.m_LightProbeOfs.Set(offsets); - - if ((!inMaterial.m_IblProbe) && (inProbeFOV < 180.f)) { - theShader.m_LightProbeOpts.Set( - QT3DSVec4(0.01745329251994329547f * inProbeFOV, 0.0f, 0.0f, 0.0f)); - } - - // Also make sure to add the secondary texture, but it should only be added if the - // primary - // (i.e. background) texture is also there. - if (theLightProbe2 && theLightProbe2->m_TextureData.m_Texture) { - theLightProbe2->m_TextureData.m_Texture->SetTextureWrapS( - theHorzLightProbeTilingMode); - theLightProbe2->m_TextureData.m_Texture->SetTextureWrapT( - theVertLightProbeTilingMode); - theShader.m_LightProbe2.Set(theLightProbe2->m_TextureData.m_Texture); - theShader.m_LightProbe2Props.Set( - QT3DSVec4(inProbe2Window, inProbe2Pos, inProbe2Fade, 1.0f)); - - const QT3DSMat44 &xform2 = theLightProbe2->m_TextureTransform; - const QT3DSF32 *dataPtr(xform2.front()); - - theShader.m_LightProbeProps.Set( - QT3DSVec4(dataPtr[12], dataPtr[13], inProbeHorizon, inProbeBright * 0.01f)); - } else { - theShader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - theShader.m_LightProbeProps.Set( - QT3DSVec4(0.0f, 0.0f, inProbeHorizon, inProbeBright * 0.01f)); - } - } else { - theShader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); - theShader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } - - theShader.m_LightProbe.Set(theLightProbe->m_TextureData.m_Texture); - - } else { - theShader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); - theShader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } - - // finally apply custom material shader properties - theMaterialSystem.ApplyShaderPropertyValues(inMaterial, inProgram); - - // additional textures - for (SRenderableImage *theImage = inFirstImage; theImage; theImage = theImage->m_NextImage) - SetImageShaderVariables(theShader, *theImage); - } - - void SetMaterialProperties(NVRenderShaderProgram &inProgram, - const SGraphObject &inMaterial, const QT3DSVec2 &inCameraVec, - const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, - const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - SLayerGlobalRenderProperties inRenderProperties) override - { - const SCustomMaterial &theCustomMaterial( - reinterpret_cast(inMaterial)); - QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::CustomMaterial); - - SetGlobalProperties(inProgram, inRenderProperties.m_Layer, inRenderProperties.m_Camera, - inRenderProperties.m_CameraDirection, inRenderProperties.m_Lights, - inRenderProperties.m_LightDirections, - inRenderProperties.m_ShadowMapManager); - - SetMaterialProperties(inProgram, theCustomMaterial, inCameraVec, inModelViewProjection, - inNormalMatrix, inGlobalTransform, inFirstImage, inOpacity, - inRenderProperties.m_DepthTexture, inRenderProperties.m_SSaoTexture, - inRenderProperties.m_LightProbe, inRenderProperties.m_LightProbe2, - inRenderProperties.m_ProbeHorizon, inRenderProperties.m_ProbeBright, - inRenderProperties.m_Probe2Window, inRenderProperties.m_Probe2Pos, - inRenderProperties.m_Probe2Fade, inRenderProperties.m_ProbeFOV); - } - - void GenerateLightmapIndirectFunc(IShaderStageGenerator &inFragmentShader, - SImage *pEmissiveLightmap) - { - inFragmentShader << "\n"; - inFragmentShader << "vec3 computeMaterialLightmapIndirect()\n{\n"; - inFragmentShader << " vec4 indirect = vec4( 0.0, 0.0, 0.0, 0.0 );\n"; - if (pEmissiveLightmap) { - SImageVariableNames names = - GetImageVariableNames(ConvertTextureTypeValue(ImageMapTypes::LightmapIndirect)); - inFragmentShader.AddUniform(names.m_ImageSampler, "sampler2D"); - inFragmentShader.AddUniform(m_ImageOffset, "vec3"); - inFragmentShader.AddUniform(m_ImageRotScale, "vec4"); - - inFragmentShader << "\n indirect = evalIndirectLightmap( " << m_ImageSampler - << ", varTexCoord1, "; - inFragmentShader << m_ImageRotScale << ", "; - inFragmentShader << m_ImageOffset << " );\n\n"; - } - - inFragmentShader << " return indirect.rgb;\n"; - inFragmentShader << "}\n\n"; - } - - void GenerateLightmapRadiosityFunc(IShaderStageGenerator &inFragmentShader, - SImage *pRadiosityLightmap) - { - inFragmentShader << "\n"; - inFragmentShader << "vec3 computeMaterialLightmapRadiosity()\n{\n"; - inFragmentShader << " vec4 radiosity = vec4( 1.0, 1.0, 1.0, 1.0 );\n"; - if (pRadiosityLightmap) { - SImageVariableNames names = - GetImageVariableNames(ConvertTextureTypeValue(ImageMapTypes::LightmapRadiosity)); - inFragmentShader.AddUniform(names.m_ImageSampler, "sampler2D"); - inFragmentShader.AddUniform(m_ImageOffset, "vec3"); - inFragmentShader.AddUniform(m_ImageRotScale, "vec4"); - - inFragmentShader << "\n radiosity = evalRadiosityLightmap( " << m_ImageSampler - << ", varTexCoord1, "; - inFragmentShader << m_ImageRotScale << ", "; - inFragmentShader << m_ImageOffset << " );\n\n"; - } - - inFragmentShader << " return radiosity.rgb;\n"; - inFragmentShader << "}\n\n"; - } - - void GenerateLightmapShadowFunc(IShaderStageGenerator &inFragmentShader, - SImage *pBakedShadowMap) - { - inFragmentShader << "\n"; - inFragmentShader << "vec4 computeMaterialLightmapShadow()\n{\n"; - inFragmentShader << " vec4 shadowMask = vec4( 1.0, 1.0, 1.0, 1.0 );\n"; - if (pBakedShadowMap) { - SImageVariableNames names = - GetImageVariableNames((QT3DSU32)NVRenderTextureTypeValue::LightmapShadow); - // Add uniforms - inFragmentShader.AddUniform(names.m_ImageSampler, "sampler2D"); - inFragmentShader.AddUniform(m_ImageOffset, "vec3"); - inFragmentShader.AddUniform(m_ImageRotScale, "vec4"); - - inFragmentShader << "\n shadowMask = evalShadowLightmap( " << m_ImageSampler - << ", texCoord0, "; - inFragmentShader << m_ImageRotScale << ", "; - inFragmentShader << m_ImageOffset << " );\n\n"; - } - - inFragmentShader << " return shadowMask;\n"; - inFragmentShader << "}\n\n"; - } - - void GenerateLightmapIndirectSetupCode(IShaderStageGenerator &inFragmentShader, - SRenderableImage *pIndirectLightmap, - SRenderableImage *pRadiosityLightmap) - { - if (!pIndirectLightmap && !pRadiosityLightmap) - return; - - eastl::string finalValue; - - inFragmentShader << "\n"; - inFragmentShader << "void initializeLayerVariablesWithLightmap(void)\n{\n"; - if (pIndirectLightmap) { - inFragmentShader - << " vec3 lightmapIndirectValue = computeMaterialLightmapIndirect( );\n"; - finalValue.append("vec4(lightmapIndirectValue, 1.0)"); - } - if (pRadiosityLightmap) { - inFragmentShader - << " vec3 lightmapRadisoityValue = computeMaterialLightmapRadiosity( );\n"; - if (finalValue.empty()) - finalValue.append("vec4(lightmapRadisoityValue, 1.0)"); - else - finalValue.append(" + vec4(lightmapRadisoityValue, 1.0)"); - } - - finalValue.append(";\n"); - - char buf[16]; - for (QT3DSU32 idx = 0; idx < Material().m_LayerCount; idx++) { - _snprintf(buf, 16, "[%d]", idx); - inFragmentShader << " layers" << buf << ".base += " << finalValue.c_str(); - inFragmentShader << " layers" << buf << ".layer += " << finalValue.c_str(); - } - - inFragmentShader << "}\n\n"; - } - - void GenerateLightmapShadowCode(IShaderStageGenerator &inFragmentShader, - SRenderableImage *pBakedShadowMap) - { - if (pBakedShadowMap) { - inFragmentShader << " tmpShadowTerm *= computeMaterialLightmapShadow( );\n\n"; - } - } - - void ApplyEmissiveMask(IShaderStageGenerator &inFragmentShader, SImage *pEmissiveMaskMap) - { - inFragmentShader << "\n"; - inFragmentShader << "vec3 computeMaterialEmissiveMask()\n{\n"; - inFragmentShader << " vec3 emissiveMask = vec3( 1.0, 1.0, 1.0 );\n"; - if (pEmissiveMaskMap) { - inFragmentShader << " texture_coordinate_info tci;\n"; - inFragmentShader << " texture_coordinate_info transformed_tci;\n"; - inFragmentShader << " tci = textureCoordinateInfo( texCoord0, tangent, binormal );\n"; - inFragmentShader << " transformed_tci = transformCoordinate( " - "rotationTranslationScale( vec3( 0.000000, 0.000000, 0.000000 ), "; - inFragmentShader << "vec3( 0.000000, 0.000000, 0.000000 ), vec3( 1.000000, 1.000000, " - "1.000000 ) ), tci );\n"; - inFragmentShader << " emissiveMask = fileTexture( " - << pEmissiveMaskMap->m_ImageShaderName.c_str() - << ", vec3( 0, 0, 0 ), vec3( 1, 1, 1 ), mono_alpha, transformed_tci, "; - inFragmentShader << "vec2( 0.000000, 1.000000 ), vec2( 0.000000, 1.000000 ), " - "wrap_repeat, wrap_repeat, gamma_default ).tint;\n"; - } - - inFragmentShader << " return emissiveMask;\n"; - inFragmentShader << "}\n\n"; - } - - void GenerateFragmentShader(SShaderDefaultMaterialKey &, const char8_t *inShaderPathName, - bool hasCustomVertexShader) - { - qt3ds::render::IDynamicObjectSystem &theDynamicSystem( - m_RenderContext.GetDynamicObjectSystem()); - CRenderString theShaderBuffer; - const char8_t *fragSource = theDynamicSystem.GetShaderSource( - m_RenderContext.GetStringTable().RegisterStr(inShaderPathName), theShaderBuffer); - - QT3DS_ASSERT(fragSource); - - // light maps - bool hasLightmaps = false; - SRenderableImage *lightmapShadowImage = NULL; - SRenderableImage *lightmapIndirectImage = NULL; - SRenderableImage *lightmapRadisoityImage = NULL; - - for (SRenderableImage *img = m_FirstImage; img != NULL; img = img->m_NextImage) { - if (img->m_MapType == ImageMapTypes::LightmapIndirect) { - lightmapIndirectImage = img; - hasLightmaps = true; - } else if (img->m_MapType == ImageMapTypes::LightmapRadiosity) { - lightmapRadisoityImage = img; - hasLightmaps = true; - } else if (img->m_MapType == ImageMapTypes::LightmapShadow) { - lightmapShadowImage = img; - } - } - - if (!hasCustomVertexShader) { - VertexGenerator().GenerateUVCoords(0); - // for lightmaps we expect a second set of uv coordinates - if (hasLightmaps) - VertexGenerator().GenerateUVCoords(1); - } - - IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); - IShaderStageGenerator &fragmentShader(FragmentGenerator()); - - eastl::string srcString(fragSource); - - if (m_RenderContext.GetRenderContext().GetRenderContextType() - == NVRenderContextValues::GLES2) { - eastl::string::size_type pos = 0; - while ((pos = srcString.find("out vec4 fragColor", pos)) != eastl::string::npos) { - srcString.insert(pos, "//"); - pos += int(strlen("//out vec4 fragColor")); - } - } - - fragmentShader << "#define FRAGMENT_SHADER\n\n"; - - // Check if the fragment shader portion already contains a main function - // The same string contains both the vertex and the fragment shader - // The last "#ifdef FRAGMENT_SHADER" should mark the start of the fragment shader - eastl_size_t fragmentDefStart = srcString.find("#ifdef FRAGMENT_SHADER"); - eastl_size_t nextIndex = fragmentDefStart; - while (nextIndex != eastl::string::npos) { - nextIndex = srcString.find("#ifdef FRAGMENT_SHADER", nextIndex + 1); - if (nextIndex != eastl::string::npos) - fragmentDefStart = nextIndex; - } - eastl_size_t mainStart = srcString.find("void main()"); - if (fragmentDefStart == eastl::string::npos) - return; - - if (mainStart != eastl::string::npos && mainStart < fragmentDefStart) - mainStart = srcString.find("void main()", mainStart + 1); - - bool hasCustomFragmentShader = mainStart != eastl::string::npos; - - if (!hasCustomFragmentShader) - fragmentShader.AddInclude("evalLightmaps.glsllib"); - - // check dielectric materials - if (!Material().IsDielectric()) - fragmentShader << "#define MATERIAL_IS_NON_DIELECTRIC 1\n\n"; - else - fragmentShader << "#define MATERIAL_IS_NON_DIELECTRIC 0\n\n"; - - fragmentShader << "#define QT3DS_ENABLE_RNM 0\n\n"; - - fragmentShader << srcString.data() << Endl; - - if (hasCustomFragmentShader) { - fragmentShader << "#define FRAGMENT_SHADER\n\n"; - if (!hasCustomVertexShader) { - vertexShader.GenerateWorldNormal(); - vertexShader.GenerateVarTangentAndBinormal(); - vertexShader.GenerateWorldPosition(); - - vertexShader.GenerateViewVector(); - } - return; - } - - if (Material().HasLighting() && lightmapIndirectImage) { - GenerateLightmapIndirectFunc(fragmentShader, &lightmapIndirectImage->m_Image); - } - if (Material().HasLighting() && lightmapRadisoityImage) { - GenerateLightmapRadiosityFunc(fragmentShader, &lightmapRadisoityImage->m_Image); - } - if (Material().HasLighting() && lightmapShadowImage) { - GenerateLightmapShadowFunc(fragmentShader, &lightmapShadowImage->m_Image); - } - - if (Material().HasLighting() && (lightmapIndirectImage || lightmapRadisoityImage)) - GenerateLightmapIndirectSetupCode(fragmentShader, lightmapIndirectImage, - lightmapRadisoityImage); - - if (Material().HasLighting()) { - ApplyEmissiveMask(fragmentShader, Material().m_EmissiveMap2); - } - - // setup main - VertexGenerator().BeginFragmentGeneration(); - - // since we do pixel lighting we always need this if lighting is enabled - // We write this here because the functions below may also write to - // the fragment shader - if (Material().HasLighting()) { - vertexShader.GenerateWorldNormal(); - vertexShader.GenerateVarTangentAndBinormal(); - vertexShader.GenerateWorldPosition(); - - if (Material().IsSpecularEnabled()) - vertexShader.GenerateViewVector(); - } - - fragmentShader << " initializeBaseFragmentVariables();" << Endl; - fragmentShader << " computeTemporaries();" << Endl; - fragmentShader << " normal = normalize( computeNormal() );" << Endl; - fragmentShader << " initializeLayerVariables();" << Endl; - fragmentShader << " float alpha = clamp( evalCutout(), 0.0, 1.0 );" << Endl; - - if (Material().IsCutOutEnabled()) { - fragmentShader << " if ( alpha <= 0.0f )" << Endl; - fragmentShader << " discard;" << Endl; - } - - // indirect / direct lightmap init - if (Material().HasLighting() && (lightmapIndirectImage || lightmapRadisoityImage)) - fragmentShader << " initializeLayerVariablesWithLightmap();" << Endl; - - // shadow map - GenerateLightmapShadowCode(fragmentShader, lightmapShadowImage); - - // main Body - fragmentShader << "#include \"customMaterialFragBodyAO.glsllib\"" << Endl; - - // for us right now transparency means we render a glass style material - if (m_HasTransparency && !Material().IsTransmissive()) - fragmentShader << " rgba = computeGlass( normal, materialIOR, alpha, rgba );" << Endl; - if (Material().IsTransmissive()) - fragmentShader << " rgba = computeOpacity( rgba );" << Endl; - - if (VertexGenerator().HasActiveWireframe()) { - fragmentShader.Append("vec3 edgeDistance = varEdgeDistance * gl_FragCoord.w;"); - fragmentShader.Append( - "\tfloat d = min(min(edgeDistance.x, edgeDistance.y), edgeDistance.z);"); - fragmentShader.Append("\tfloat mixVal = smoothstep(0.0, 1.0, d);"); // line width 1.0 - - fragmentShader.Append("\trgba = mix( vec4(0.0, 1.0, 0.0, 1.0), rgba, mixVal);"); - } - fragmentShader << " rgba.a *= object_opacity;" << Endl; - if (m_RenderContext.GetRenderContext().GetRenderContextType() - == NVRenderContextValues::GLES2) - fragmentShader << " gl_FragColor = rgba;" << Endl; - else - fragmentShader << " fragColor = rgba;" << Endl; - } - - NVRenderShaderProgram *GenerateCustomMaterialShader(const char8_t *inShaderPrefix, - const char8_t *inCustomMaterialName) - { - // build a string that allows us to print out the shader we are generating to the log. - // This is time consuming but I feel like it doesn't happen all that often and is very - // useful to users - // looking at the log file. - m_GeneratedShaderString.clear(); - m_GeneratedShaderString.assign(nonNull(inShaderPrefix)); - m_GeneratedShaderString.append(inCustomMaterialName); - SShaderDefaultMaterialKey theKey(Key()); - theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); - - bool hasCustomVertexShader = GenerateVertexShader(theKey, inCustomMaterialName); - GenerateFragmentShader(theKey, inCustomMaterialName, hasCustomVertexShader); - - VertexGenerator().EndVertexGeneration(); - VertexGenerator().EndFragmentGeneration(); - - NVRenderShaderProgram *program = ProgramGenerator().CompileGeneratedShader( - m_GeneratedShaderString.c_str(), SShaderCacheProgramFlags(), FeatureSet()); - if (program && hasCustomVertexShader) { - // Change uniforms names to match runtime 2.x uniforms - SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(*program)); - shader.m_ModelMatrix = NVRenderCachedShaderProperty("modelMatrix", - *program); - shader.m_ViewProjMatrix = NVRenderCachedShaderProperty( - "modelViewProjection", *program); - shader.m_ViewMatrix = NVRenderCachedShaderProperty("viewMatrix", *program); - shader.m_NormalMatrix = NVRenderCachedShaderProperty("modelNormalMatrix", - *program); - shader.m_ProjMatrix = NVRenderCachedShaderProperty("viewProjectionMatrix", - *program); - shader.m_ViewportMatrix = NVRenderCachedShaderProperty("viewportMatrix", - *program); - shader.m_CameraPos = NVRenderCachedShaderProperty("eyePosition", *program); - } - return program; - } - - virtual NVRenderShaderProgram * - GenerateShader(const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, - IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, - NVDataRef inLights, SRenderableImage *inFirstImage, - bool inHasTransparency, const char8_t *inShaderPrefix, - const char8_t *inCustomMaterialName) override - { - QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::CustomMaterial); - m_CurrentMaterial = reinterpret_cast(&inMaterial); - m_CurrentKey = &inShaderDescription; - m_CurrentPipeline = static_cast(&inVertexPipeline); - m_CurrentFeatureSet = inFeatureSet; - m_Lights = inLights; - m_FirstImage = inFirstImage; - m_HasTransparency = inHasTransparency; - - return GenerateCustomMaterialShader(inShaderPrefix, inCustomMaterialName); - } -}; -} - -ICustomMaterialShaderGenerator & -ICustomMaterialShaderGenerator::CreateCustomMaterialShaderGenerator(IQt3DSRenderContext &inRc) -{ - return *QT3DS_NEW(inRc.GetAllocator(), SShaderGenerator)(inRc); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialSystem.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialSystem.cpp deleted file mode 100644 index 1ae32bf4..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialSystem.cpp +++ /dev/null @@ -1,2074 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderCustomMaterialRenderContext.h" -#include "Qt3DSRenderContextCore.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderDynamicObjectSystemCommands.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderResourceManager.h" -#include "Qt3DSRenderMesh.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderLayer.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "render/Qt3DSRenderComputeShader.h" -#include "foundation/PreAllocatedAllocator.h" -#include "foundation/SerializationTypes.h" -#include "foundation/Qt3DSTime.h" -#include "Qt3DSRenderDynamicObjectSystemUtil.h" -#include "Qt3DSRenderableImage.h" -#include "../RendererImpl/Qt3DSVertexPipelineImpl.h" -#include "../RendererImpl/Qt3DSRendererImplLayerRenderData.h" -#include "Qt3DSRenderCustomMaterialShaderGenerator.h" -#include "Qt3DSRenderModel.h" - -using namespace qt3ds::render; -using namespace qt3ds::render::dynamic; -using qt3ds::render::NVRenderContextScopedProperty; -using qt3ds::render::NVRenderCachedShaderProperty; -using qt3ds::render::NVRenderCachedShaderBuffer; - -SCustomMaterialVertexPipeline::SCustomMaterialVertexPipeline(IQt3DSRenderContext *inContext, - TessModeValues::Enum inTessMode) - : SVertexPipelineImpl( - inContext->GetAllocator(), inContext->GetCustomMaterialShaderGenerator(), - inContext->GetShaderProgramGenerator(), inContext->GetStringTable(), false) - , m_Context(inContext) - , m_TessMode(TessModeValues::NoTess) -{ - if (m_Context->GetRenderContext().IsTessellationSupported()) { - m_TessMode = inTessMode; - } - - if (m_Context->GetRenderContext().IsGeometryStageSupported() - && m_TessMode != TessModeValues::NoTess) { - m_Wireframe = inContext->GetWireframeMode(); - } -} - -void SCustomMaterialVertexPipeline::InitializeTessControlShader() -{ - if (m_TessMode == TessModeValues::NoTess - || ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl) == NULL) { - return; - } - - IShaderStageGenerator &tessCtrlShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - - tessCtrlShader.AddUniform("tessLevelInner", "float"); - tessCtrlShader.AddUniform("tessLevelOuter", "float"); - - SetupTessIncludes(ShaderGeneratorStages::TessControl, m_TessMode); - - tessCtrlShader.Append("void main() {\n"); - - tessCtrlShader.Append("\tctWorldPos[0] = varWorldPos[0];"); - tessCtrlShader.Append("\tctWorldPos[1] = varWorldPos[1];"); - tessCtrlShader.Append("\tctWorldPos[2] = varWorldPos[2];"); - - if (m_TessMode == TessModeValues::TessPhong || m_TessMode == TessModeValues::TessNPatch) { - tessCtrlShader.Append("\tctNorm[0] = varObjectNormal[0];"); - tessCtrlShader.Append("\tctNorm[1] = varObjectNormal[1];"); - tessCtrlShader.Append("\tctNorm[2] = varObjectNormal[2];"); - } - if (m_TessMode == TessModeValues::TessNPatch) { - tessCtrlShader.Append("\tctTangent[0] = varObjTangent[0];"); - tessCtrlShader.Append("\tctTangent[1] = varObjTangent[1];"); - tessCtrlShader.Append("\tctTangent[2] = varObjTangent[2];"); - } - - tessCtrlShader.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); -} - -void SCustomMaterialVertexPipeline::InitializeTessEvaluationShader() -{ - if (m_TessMode == TessModeValues::NoTess - || ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval) == NULL) { - return; - } - - IShaderStageGenerator &tessEvalShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddUniform("normal_matrix", "mat3"); - - SetupTessIncludes(ShaderGeneratorStages::TessEval, m_TessMode); - - if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) { - tessEvalShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - tessEvalShader.AddUniform("model_matrix", "mat4"); - tessEvalShader.AddUniform("displace_tiling", "vec3"); - tessEvalShader.AddUniform("displaceAmount", "float"); - tessEvalShader.AddUniform(m_DisplacementImage->m_Image.m_ImageShaderName.c_str(), - "sampler2D"); - } - - tessEvalShader.Append("void main() {"); - - if (m_TessMode == TessModeValues::TessNPatch) { - tessEvalShader.Append("\tctNorm[0] = varObjectNormalTC[0];"); - tessEvalShader.Append("\tctNorm[1] = varObjectNormalTC[1];"); - tessEvalShader.Append("\tctNorm[2] = varObjectNormalTC[2];"); - - tessEvalShader.Append("\tctTangent[0] = varTangentTC[0];"); - tessEvalShader.Append("\tctTangent[1] = varTangentTC[1];"); - tessEvalShader.Append("\tctTangent[2] = varTangentTC[2];"); - } - - tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); -} - -void SCustomMaterialVertexPipeline::FinalizeTessControlShader() -{ - IShaderStageGenerator &tessCtrlShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); - // add varyings we must pass through - typedef TStrTableStrMap::const_iterator TParamIter; - for (TParamIter iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - tessCtrlShader << "\t" << iter->first.c_str() - << "TC[gl_InvocationID] = " << iter->first.c_str() - << "[gl_InvocationID];\n"; - } -} - -void SCustomMaterialVertexPipeline::FinalizeTessEvaluationShader() -{ - IShaderStageGenerator &tessEvalShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - - eastl::string outExt(""); - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) - outExt = "TE"; - - // add varyings we must pass through - typedef TStrTableStrMap::const_iterator TParamIter; - if (m_TessMode == TessModeValues::TessNPatch) { - for (TParamIter iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() - << " = gl_TessCoord.z * " << iter->first.c_str() << "TC[0] + "; - tessEvalShader << "gl_TessCoord.x * " << iter->first.c_str() << "TC[1] + "; - tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[2];\n"; - } - - // transform the normal - if (m_GenerationFlags & GenerationFlagValues::WorldNormal) - tessEvalShader << "\n\tvarNormal" << outExt.c_str() - << " = normalize(normal_matrix * teNorm);\n"; - // transform the tangent - if (m_GenerationFlags & GenerationFlagValues::TangentBinormal) { - tessEvalShader << "\n\tvarTangent" << outExt.c_str() - << " = normalize(normal_matrix * teTangent);\n"; - // transform the binormal - tessEvalShader << "\n\tvarBinormal" << outExt.c_str() - << " = normalize(normal_matrix * teBinormal);\n"; - } - } else { - for (TParamIter iter = m_InterpolationParameters.begin(), - end = m_InterpolationParameters.end(); - iter != end; ++iter) { - tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() - << " = gl_TessCoord.x * " << iter->first.c_str() << "TC[0] + "; - tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[1] + "; - tessEvalShader << "gl_TessCoord.z * " << iter->first.c_str() << "TC[2];\n"; - } - - // displacement mapping makes only sense with linear tessellation - if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) { - tessEvalShader - << "\ttexture_coordinate_info tmp = textureCoordinateInfo( varTexCoord0" - << outExt.c_str() << ", varTangent" << outExt.c_str() << ", varBinormal" - << outExt.c_str() << " );" << Endl; - tessEvalShader << "\ttmp = transformCoordinate( rotationTranslationScale( vec3( " - "0.000000, 0.000000, 0.000000 ), vec3( 0.000000, 0.000000, " - "0.000000 ), displace_tiling ), tmp);" - << Endl; - - tessEvalShader << "\tpos.xyz = defaultMaterialFileDisplacementTexture( " - << m_DisplacementImage->m_Image.m_ImageShaderName.c_str() - << ", displaceAmount, " - << "tmp.position.xy"; - tessEvalShader << ", varObjectNormal" << outExt.c_str() << ", pos.xyz );" << Endl; - tessEvalShader << "\tvarWorldPos" << outExt.c_str() << "= (model_matrix * pos).xyz;" - << Endl; - } - - // transform the normal - tessEvalShader << "\n\tvarNormal" << outExt.c_str() - << " = normalize(normal_matrix * varObjectNormal" << outExt.c_str() - << ");\n"; - } - - tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); -} - -// Responsible for beginning all vertex and fragment generation (void main() { etc). -void SCustomMaterialVertexPipeline::BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) -{ - m_DisplacementIdx = displacementImageIdx; - m_DisplacementImage = displacementImage; - - TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); - - if (m_TessMode != TessModeValues::NoTess) { - theStages |= ShaderGeneratorStages::TessControl; - theStages |= ShaderGeneratorStages::TessEval; - } - if (m_Wireframe) { - theStages |= ShaderGeneratorStages::Geometry; - } - - ProgramGenerator().BeginProgram(theStages); - - if (m_TessMode != TessModeValues::NoTess) { - InitializeTessControlShader(); - InitializeTessEvaluationShader(); - } - if (m_Wireframe) { - InitializeWireframeGeometryShader(); - } - - IShaderStageGenerator &vertexShader(Vertex()); - - // thinks we need - vertexShader.AddInclude("viewProperties.glsllib"); - vertexShader.AddInclude("customMaterial.glsllib"); - - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader << "void main()" << Endl << "{" << Endl; - - if (displacementImage) { - GenerateUVCoords(0); - if (!HasTessellation()) { - vertexShader.AddUniform("displaceAmount", "float"); - vertexShader.AddUniform("displace_tiling", "vec3"); - // we create the world position setup here - // because it will be replaced with the displaced position - SetCode(GenerationFlagValues::WorldPosition); - vertexShader.AddUniform("model_matrix", "mat4"); - - vertexShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - vertexShader.AddUniform(displacementImage->m_Image.m_ImageShaderName.c_str(), - "sampler2D"); - - vertexShader << "\ttexture_coordinate_info tmp = textureCoordinateInfo( texCoord0, " - "varTangent, varBinormal );" - << Endl; - vertexShader << "\ttmp = transformCoordinate( rotationTranslationScale( vec3( " - "0.000000, 0.000000, 0.000000 ), vec3( 0.000000, 0.000000, " - "0.000000 ), displace_tiling ), tmp);" - << Endl; - - vertexShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - << displacementImage->m_Image.m_ImageShaderName.c_str() - << ", displaceAmount, " - << "tmp.position.xy" - << ", attr_norm, attr_pos );" << Endl; - - AddInterpolationParameter("varWorldPos", "vec3"); - vertexShader.Append("\tvec3 local_model_world_position = (model_matrix * " - "vec4(displacedPos, 1.0)).xyz;"); - AssignOutput("varWorldPos", "local_model_world_position"); - } - } - - if (HasTessellation()) { - vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); - } else { - vertexShader.AddUniform("model_view_projection", "mat4"); - if (displacementImage) - vertexShader.Append( - "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - else - vertexShader.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - } - - if (HasTessellation()) { - GenerateWorldPosition(); - GenerateWorldNormal(); - GenerateObjectNormal(); - GenerateVarTangentAndBinormal(); - } -} - -void SCustomMaterialVertexPipeline::BeginFragmentGeneration() -{ - Fragment().AddUniform("object_opacity", "float"); - Fragment() << "void main()" << Endl << "{" << Endl; -} - -void SCustomMaterialVertexPipeline::AssignOutput(const char8_t *inVarName, - const char8_t *inVarValue) -{ - Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n"; -} - -void SCustomMaterialVertexPipeline::GenerateUVCoords(QT3DSU32 inUVSet) -{ - if (inUVSet == 0 && SetCode(GenerationFlagValues::UVCoords)) - return; - if (inUVSet == 1 && SetCode(GenerationFlagValues::UVCoords1)) - return; - - QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); - - if (inUVSet == 0) - AddInterpolationParameter("varTexCoord0", "vec3"); - else if (inUVSet == 1) - AddInterpolationParameter("varTexCoord1", "vec3"); - - DoGenerateUVCoords(inUVSet); -} - -void SCustomMaterialVertexPipeline::GenerateWorldNormal() -{ - if (SetCode(GenerationFlagValues::WorldNormal)) - return; - AddInterpolationParameter("varNormal", "vec3"); - DoGenerateWorldNormal(); -} - -void SCustomMaterialVertexPipeline::GenerateObjectNormal() -{ - if (SetCode(GenerationFlagValues::ObjectNormal)) - return; - DoGenerateObjectNormal(); -} - -void SCustomMaterialVertexPipeline::GenerateVarTangentAndBinormal() -{ - if (SetCode(GenerationFlagValues::TangentBinormal)) - return; - AddInterpolationParameter("varTangent", "vec3"); - AddInterpolationParameter("varBinormal", "vec3"); - AddInterpolationParameter("varObjTangent", "vec3"); - AddInterpolationParameter("varObjBinormal", "vec3"); - DoGenerateVarTangentAndBinormal(); -} - -void SCustomMaterialVertexPipeline::GenerateWorldPosition() -{ - if (SetCode(GenerationFlagValues::WorldPosition)) - return; - - ActiveStage().AddUniform("model_matrix", "mat4"); - AddInterpolationParameter("varWorldPos", "vec3"); - AddInterpolationParameter("varObjPos", "vec3"); - DoGenerateWorldPosition(); -} - -// responsible for closing all vertex and fragment generation -void SCustomMaterialVertexPipeline::EndVertexGeneration() -{ - if (HasTessellation()) { - // finalize tess control shader - FinalizeTessControlShader(); - // finalize tess evaluation shader - FinalizeTessEvaluationShader(); - - TessControl().Append("}"); - TessEval().Append("}"); - - if (m_Wireframe) { - // finalize geometry shader - FinalizeWireframeGeometryShader(); - Geometry().Append("}"); - } - } - - Vertex().Append("}"); -} - -void SCustomMaterialVertexPipeline::EndFragmentGeneration() -{ - Fragment().Append("}"); -} - -IShaderStageGenerator &SCustomMaterialVertexPipeline::ActiveStage() -{ - return Vertex(); -} - -void SCustomMaterialVertexPipeline::AddInterpolationParameter(const char8_t *inName, - const char8_t *inType) -{ - m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); - Vertex().AddOutgoing(inName, inType); - Fragment().AddIncoming(inName, inType); - - if (HasTessellation()) { - eastl::string nameBuilder(inName); - nameBuilder.append("TC"); - TessControl().AddOutgoing(nameBuilder.c_str(), inType); - - nameBuilder.assign(inName); - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) { - nameBuilder.append("TE"); - Geometry().AddOutgoing(inName, inType); - } - TessEval().AddOutgoing(nameBuilder.c_str(), inType); - } -} - -void SCustomMaterialVertexPipeline::DoGenerateUVCoords(QT3DSU32 inUVSet) -{ - QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); - - if (inUVSet == 0) { - Vertex().AddIncoming("attr_uv0", "vec2"); - Vertex() << "\tvec3 texCoord0 = vec3( attr_uv0, 0.0 );" << Endl; - AssignOutput("varTexCoord0", "texCoord0"); - } else if (inUVSet == 1) { - Vertex().AddIncoming("attr_uv1", "vec2"); - Vertex() << "\tvec3 texCoord1 = vec3( attr_uv1, 1.0 );" << Endl; - AssignOutput("varTexCoord1", "texCoord1"); - } -} - -void SCustomMaterialVertexPipeline::DoGenerateWorldNormal() -{ - IShaderStageGenerator &vertexGenerator(Vertex()); - vertexGenerator.AddIncoming("attr_norm", "vec3"); - vertexGenerator.AddUniform("normal_matrix", "mat3"); - - if (HasTessellation() == false) { - Vertex().Append("\tvarNormal = normalize( normal_matrix * attr_norm );"); - } -} - -void SCustomMaterialVertexPipeline::DoGenerateObjectNormal() -{ - AddInterpolationParameter("varObjectNormal", "vec3"); - Vertex().Append("\tvarObjectNormal = attr_norm;"); -} - -void SCustomMaterialVertexPipeline::DoGenerateWorldPosition() -{ - Vertex().Append("\tvarObjPos = attr_pos;"); - Vertex().Append("\tvec4 worldPos = (model_matrix * vec4(attr_pos, 1.0));"); - AssignOutput("varWorldPos", "worldPos.xyz"); -} - -void SCustomMaterialVertexPipeline::DoGenerateVarTangentAndBinormal() -{ - Vertex().AddIncoming("attr_textan", "vec3"); - Vertex().AddIncoming("attr_binormal", "vec3"); - - Vertex() << "\tvarTangent = normal_matrix * attr_textan;" << Endl - << "\tvarBinormal = normal_matrix * attr_binormal;" << Endl; - - Vertex() << "\tvarObjTangent = attr_textan;" << Endl << "\tvarObjBinormal = attr_binormal;" - << Endl; -} - -void SCustomMaterialVertexPipeline::DoGenerateVertexColor() -{ - Vertex().AddIncoming("attr_color", "vec3"); - Vertex().Append("\tvarColor = attr_color;"); -} - - -struct SMaterialClass -{ - NVAllocatorCallback *m_Allocator; - IDynamicObjectClass *m_Class; - bool m_HasTransparency; - bool m_HasRefraction; - bool m_HasDisplacement; - bool m_AlwaysDirty; - QT3DSU32 m_ShaderKey; - QT3DSU32 m_LayerCount; - QT3DSI32 mRefCount; - SMaterialClass(NVAllocatorCallback &alloc, IDynamicObjectClass &inCls) - : m_Allocator(&alloc) - , m_Class(&inCls) - , m_HasTransparency(false) - , m_HasRefraction(false) - , m_HasDisplacement(false) - , m_AlwaysDirty(false) - , m_ShaderKey(0) - , m_LayerCount(0) - , mRefCount(0) - { - } - - ~SMaterialClass() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator) - - void AfterWrite() - { - m_Allocator = NULL; - m_Class = NULL; - mRefCount = 0; - } - - void AfterRead(NVAllocatorCallback &alloc, IDynamicObjectClass &inCls) - { - m_Allocator = &alloc; - m_Class = &inCls; - mRefCount = 0; - } -}; - -typedef nvhash_map> TStringMaterialMap; -typedef eastl::pair TStrStrPair; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const TStrStrPair &item) const - { - return hash()(item.first) ^ hash()(item.second); - } -}; -} - -struct SShaderMapKey -{ - TStrStrPair m_Name; - eastl::vector m_Features; - TessModeValues::Enum m_TessMode; - bool m_WireframeMode; - SShaderDefaultMaterialKey m_MaterialKey; - size_t m_HashCode; - SShaderMapKey(TStrStrPair inName, TShaderFeatureSet inFeatures, TessModeValues::Enum inTessMode, - bool inWireframeMode, SShaderDefaultMaterialKey inMaterialKey) - : m_Name(inName) - , m_Features(inFeatures.begin(), inFeatures.end()) - , m_TessMode(inTessMode) - , m_WireframeMode(inWireframeMode) - , m_MaterialKey(inMaterialKey) - { - m_HashCode = eastl::hash()(m_Name) - ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size())) - ^ eastl::hash()(m_TessMode) ^ eastl::hash()(m_WireframeMode) - ^ eastl::hash()(inMaterialKey.hash()); - } - bool operator==(const SShaderMapKey &inKey) const - { - return m_Name == inKey.m_Name && m_Features == inKey.m_Features - && m_TessMode == inKey.m_TessMode && m_WireframeMode == inKey.m_WireframeMode - && m_MaterialKey == inKey.m_MaterialKey; - } -}; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SShaderMapKey &inKey) const { return inKey.m_HashCode; } -}; -} - -namespace { - -struct SCustomMaterialTextureData -{ - NVScopedRefCounted m_Shader; - qt3ds::render::NVRenderCachedShaderProperty m_Sampler; - qt3ds::render::NVRenderTexture2D *m_Texture; - bool m_needsMips; - volatile QT3DSI32 mRefCount; - - SCustomMaterialTextureData(NVRenderShaderProgram &inShader, NVRenderTexture2D *inTexture, - const char *inTexName, bool needMips) - : m_Shader(inShader) - , m_Sampler(inTexName, inShader) - , m_Texture(inTexture) - , m_needsMips(needMips) - , mRefCount(0) - { - } - - void Set(const SPropertyDefinition *inDefinition) - { - if (m_Texture && inDefinition) { - m_Texture->SetMagFilter(inDefinition->m_MagFilterOp); - m_Texture->SetMinFilter(inDefinition->m_MinFilterOp); - m_Texture->SetTextureWrapS(inDefinition->m_CoordOp); - m_Texture->SetTextureWrapT(inDefinition->m_CoordOp); - } else if (m_Texture) { - // set some defaults - m_Texture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - m_Texture->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - m_Texture->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - } - - if ((m_Texture->GetNumMipmaps() == 0) && m_needsMips) - m_Texture->GenerateMipmaps(); - - m_Sampler.Set(m_Texture); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) - - static SCustomMaterialTextureData CreateTextureEntry(NVRenderShaderProgram &inShader, - NVRenderTexture2D *inTexture, - const char *inTexName, bool needMips) - { - return SCustomMaterialTextureData(inShader, inTexture, inTexName, needMips); - } -}; - -typedef eastl::pair> - TCustomMaterialTextureEntry; - -/** - * Cached tessellation property lookups this is on a per mesh base - */ -struct SCustomMaterialsTessellationProperties -{ - NVRenderCachedShaderProperty m_EdgeTessLevel; ///< tesselation value for the edges - NVRenderCachedShaderProperty m_InsideTessLevel; ///< tesselation value for the inside - NVRenderCachedShaderProperty - m_PhongBlend; ///< blending between linear and phong component - NVRenderCachedShaderProperty - m_DistanceRange; ///< distance range for min and max tess level - NVRenderCachedShaderProperty m_DisableCulling; ///< if set to 1.0 this disables backface - ///culling optimization in the tess shader - - SCustomMaterialsTessellationProperties() {} - SCustomMaterialsTessellationProperties(NVRenderShaderProgram &inShader) - : m_EdgeTessLevel("tessLevelOuter", inShader) - , m_InsideTessLevel("tessLevelInner", inShader) - , m_PhongBlend("phongBlend", inShader) - , m_DistanceRange("distanceRange", inShader) - , m_DisableCulling("disableCulling", inShader) - { - } -}; - -/* We setup some shared state on the custom material shaders */ -struct SCustomMaterialShader -{ - NVScopedRefCounted m_Shader; - NVRenderCachedShaderProperty m_ModelMatrix; - NVRenderCachedShaderProperty m_ViewProjMatrix; - NVRenderCachedShaderProperty m_ViewMatrix; - NVRenderCachedShaderProperty m_NormalMatrix; - NVRenderCachedShaderProperty m_CameraPos; - NVRenderCachedShaderProperty m_ProjMatrix; - NVRenderCachedShaderProperty m_ViewportMatrix; - NVRenderCachedShaderProperty m_CamProperties; - NVRenderCachedShaderProperty m_DepthTexture; - NVRenderCachedShaderProperty m_AOTexture; - NVRenderCachedShaderProperty m_LightProbe; - NVRenderCachedShaderProperty m_LightProbeProps; - NVRenderCachedShaderProperty m_LightProbeOpts; - NVRenderCachedShaderProperty m_LightProbeRot; - NVRenderCachedShaderProperty m_LightProbeOfs; - NVRenderCachedShaderProperty m_LightProbe2; - NVRenderCachedShaderProperty m_LightProbe2Props; - NVRenderCachedShaderProperty m_LightCount; - NVRenderCachedShaderProperty m_AreaLightCount; - NVRenderCachedShaderBuffer m_AoShadowParams; - SCustomMaterialsTessellationProperties m_Tessellation; - SDynamicShaderProgramFlags m_ProgramFlags; - volatile QT3DSI32 mRefCount; - SCustomMaterialShader(NVRenderShaderProgram &inShader, SDynamicShaderProgramFlags inFlags) - : m_Shader(inShader) - , m_ModelMatrix("model_matrix", inShader) - , m_ViewProjMatrix("model_view_projection", inShader) - , m_ViewMatrix("view_matrix", inShader) - , m_NormalMatrix("normal_matrix", inShader) - , m_CameraPos("camera_position", inShader) - , m_ProjMatrix("view_projection_matrix", inShader) - , m_ViewportMatrix("viewport_matrix", inShader) - , m_CamProperties("camera_properties", inShader) - , m_DepthTexture("depth_sampler", inShader) - , m_AOTexture("ao_sampler", inShader) - , m_LightProbe("light_probe", inShader) - , m_LightProbeProps("light_probe_props", inShader) - , m_LightProbeOpts("light_probe_opts", inShader) - , m_LightProbeRot("light_probe_rotation", inShader) - , m_LightProbeOfs("light_probe_offset", inShader) - , m_LightProbe2("light_probe2", inShader) - , m_LightProbe2Props("light_probe2_props", inShader) - , m_LightCount("uNumLights", inShader) - , m_AreaLightCount("uNumAreaLights", inShader) - , m_AoShadowParams("cbAoShadow", inShader) - , m_Tessellation(inShader) - , m_ProgramFlags(inFlags) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) -}; - -struct SMaterialOrComputeShader -{ - SCustomMaterialShader *m_MaterialShader; - NVRenderShaderProgram *m_ComputeShader; - SMaterialOrComputeShader() - : m_MaterialShader(NULL) - , m_ComputeShader(NULL) - { - } - SMaterialOrComputeShader(SCustomMaterialShader &inMaterialShader) - : m_MaterialShader(&inMaterialShader) - , m_ComputeShader(NULL) - { - } - SMaterialOrComputeShader(NVRenderShaderProgram &inComputeShader) - : m_MaterialShader(NULL) - , m_ComputeShader(&inComputeShader) - { - QT3DS_ASSERT(inComputeShader.GetProgramType() == NVRenderShaderProgram::ProgramType::Compute); - } - bool IsValid() const { return m_MaterialShader || m_ComputeShader; } - bool IsComputeShader() const { return m_ComputeShader != NULL; } - bool IsMaterialShader() const { return m_MaterialShader != NULL; } - SCustomMaterialShader &MaterialShader() - { - QT3DS_ASSERT(IsMaterialShader()); - return *m_MaterialShader; - } - NVRenderShaderProgram &ComputeShader() - { - QT3DS_ASSERT(IsComputeShader()); - return *m_ComputeShader; - } -}; - -struct SCustomMaterialBuffer -{ - CRegisteredString m_Name; - NVScopedRefCounted m_FrameBuffer; - NVScopedRefCounted m_Texture; - SAllocateBufferFlags m_Flags; - - SCustomMaterialBuffer(CRegisteredString inName, NVRenderFrameBuffer &inFb, - NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags) - : m_Name(inName) - , m_FrameBuffer(&inFb) - , m_Texture(&inTexture) - , m_Flags(inFlags) - { - } - SCustomMaterialBuffer() {} -}; - -struct SMaterialSystem; -typedef nvhash_map> - TStringVertexBufferMap; -typedef nvhash_map> - TStringAssemblerMap; - -struct SStringMemoryBarrierFlagMap -{ - const char8_t *m_Name; - qt3ds::render::NVRenderBufferBarrierValues::Enum m_Value; - SStringMemoryBarrierFlagMap(const char8_t *nm, - qt3ds::render::NVRenderBufferBarrierValues::Enum val) - : m_Name(nm) - , m_Value(val) - { - } -}; - -SStringMemoryBarrierFlagMap g_StringMemoryFlagMap[] = { - SStringMemoryBarrierFlagMap("vertex_attribute", - qt3ds::render::NVRenderBufferBarrierValues::VertexAttribArray), - SStringMemoryBarrierFlagMap("element_array", - qt3ds::render::NVRenderBufferBarrierValues::ElementArray), - SStringMemoryBarrierFlagMap("uniform_buffer", - qt3ds::render::NVRenderBufferBarrierValues::UniformBuffer), - SStringMemoryBarrierFlagMap("texture_fetch", - qt3ds::render::NVRenderBufferBarrierValues::TextureFetch), - SStringMemoryBarrierFlagMap("shader_image_access", - qt3ds::render::NVRenderBufferBarrierValues::ShaderImageAccess), - SStringMemoryBarrierFlagMap("command_buffer", - qt3ds::render::NVRenderBufferBarrierValues::CommandBuffer), - SStringMemoryBarrierFlagMap("pixel_buffer", - qt3ds::render::NVRenderBufferBarrierValues::PixelBuffer), - SStringMemoryBarrierFlagMap("texture_update", - qt3ds::render::NVRenderBufferBarrierValues::TextureUpdate), - SStringMemoryBarrierFlagMap("buffer_update", - qt3ds::render::NVRenderBufferBarrierValues::BufferUpdate), - SStringMemoryBarrierFlagMap("frame_buffer", - qt3ds::render::NVRenderBufferBarrierValues::Framebuffer), - SStringMemoryBarrierFlagMap("transform_feedback", - qt3ds::render::NVRenderBufferBarrierValues::TransformFeedback), - SStringMemoryBarrierFlagMap("atomic_counter", - qt3ds::render::NVRenderBufferBarrierValues::AtomicCounter), - SStringMemoryBarrierFlagMap("shader_storage", - qt3ds::render::NVRenderBufferBarrierValues::ShaderStorage), -}; - -struct SStringBlendFuncMap -{ - const char8_t *m_Name; - qt3ds::render::NVRenderSrcBlendFunc::Enum m_Value; - SStringBlendFuncMap(const char8_t *nm, qt3ds::render::NVRenderSrcBlendFunc::Enum val) - : m_Name(nm) - , m_Value(val) - { - } -}; - -SStringBlendFuncMap g_BlendFuncMap[] = { -#define QT3DS_RENDER_HANDLE_BLEND_FUNC(nm) \ - SStringBlendFuncMap(#nm, qt3ds::render::NVRenderSrcBlendFunc::nm), -#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(nm) \ - SStringBlendFuncMap(#nm, qt3ds::render::NVRenderSrcBlendFunc::nm), - QT3DS_RENDER_ITERATE_BLEND_FUNC -#undef QT3DS_RENDER_HANDLE_BLEND_FUNC -#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC -}; - -struct SMaterialSystem : public ICustomMaterialSystem -{ - typedef nvhash_map> TShaderMap; - typedef eastl::pair TAllocatedImageEntry; - - IQt3DSRenderContextCore &m_CoreContext; - IQt3DSRenderContext *m_Context; - mutable qt3ds::render::SPreAllocatedAllocator m_Allocator; - TStringMaterialMap m_StringMaterialMap; - TShaderMap m_ShaderMap; - nvvector m_TextureEntries; - nvvector m_AllocatedBuffers; - nvvector m_AllocatedImages; - bool m_UseFastBlits; - eastl::string m_ShaderNameBuilder; - QT3DSU64 m_LastFrameTime; - QT3DSF32 m_MillisecondsSinceLastFrame; - QT3DSI32 mRefCount; - - SMaterialSystem(IQt3DSRenderContextCore &ct) - : m_CoreContext(ct) - , m_Context(NULL) - , m_Allocator(ct.GetAllocator()) - , m_StringMaterialMap(ct.GetAllocator(), "SMaterialSystem::m_StringMaterialMap") - , m_ShaderMap(ct.GetAllocator(), "SMaterialSystem::m_ShaderMap") - , m_TextureEntries(ct.GetAllocator(), "SMaterialSystem::m_TextureEntries") - , m_AllocatedBuffers(ct.GetAllocator(), "SMaterialSystem::m_AllocatedBuffers") - , m_AllocatedImages(ct.GetAllocator(), "SMaterialSystem::m_AllocatedImages") - , m_UseFastBlits(true) - , m_LastFrameTime(0) - , m_MillisecondsSinceLastFrame(0) - , mRefCount(0) - { - } - - ~SMaterialSystem() - { - while (m_AllocatedBuffers.size()) - m_AllocatedBuffers.replace_with_last(0); - - for (QT3DSU32 idx = 0; idx < m_AllocatedImages.size(); ++idx) { - SImage *pImage = m_AllocatedImages[idx].second; - QT3DS_FREE(m_CoreContext.GetAllocator(), pImage); - } - m_AllocatedImages.clear(); - } - - void ReleaseBuffer(QT3DSU32 inIdx) - { - // Don't call this on MaterialSystem destroy. - // This causes issues for scene liftime buffers - // because the resource manager is destroyed before - IResourceManager &theManager(m_Context->GetResourceManager()); - SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[inIdx]); - theEntry.m_FrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer()); - - theManager.Release(*theEntry.m_FrameBuffer); - theManager.Release(*theEntry.m_Texture); - m_AllocatedBuffers.replace_with_last(inIdx); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_CoreContext.GetAllocator()) - - bool IsMaterialRegistered(CRegisteredString inStr) override - { - return m_StringMaterialMap.find(inStr) != m_StringMaterialMap.end(); - } - - bool RegisterMaterialClass(CRegisteredString inName, - NVConstDataRef inProperties) override - { - if (IsMaterialRegistered(inName)) - return false; - m_CoreContext.GetDynamicObjectSystemCore().Register( - inName, inProperties, sizeof(SCustomMaterial), GraphObjectTypes::CustomMaterial); - IDynamicObjectClass *theClass = - m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - return false; - } - SMaterialClass *theNewClass = QT3DS_NEW(m_Allocator, SMaterialClass)(m_Allocator, *theClass); - m_StringMaterialMap.insert(eastl::make_pair(inName, theNewClass)); - return true; - } - - SMaterialClass *GetMaterialClass(CRegisteredString inStr) - { - TStringMaterialMap::iterator theIter = m_StringMaterialMap.find(inStr); - if (theIter != m_StringMaterialMap.end()) - return theIter->second; - return NULL; - } - - const SMaterialClass *GetMaterialClass(CRegisteredString inStr) const - { - return const_cast(this)->GetMaterialClass(inStr); - } - - virtual NVConstDataRef - GetCustomMaterialProperties(CRegisteredString inCustomMaterialName) const override - { - IDynamicObjectClass *theMaterialClass = - m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inCustomMaterialName); - - if (theMaterialClass) - return theMaterialClass->GetProperties(); - - return NVConstDataRef(); - } - - virtual QT3DSU32 FindBuffer(CRegisteredString inName) - { - for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx) - if (m_AllocatedBuffers[idx].m_Name == inName) - return idx; - return m_AllocatedBuffers.size(); - } - - virtual QT3DSU32 FindAllocatedImage(CRegisteredString inName) - { - for (QT3DSU32 idx = 0, end = m_AllocatedImages.size(); idx < end; ++idx) - if (m_AllocatedImages[idx].first == inName) - return idx; - return QT3DSU32(-1); - } - - virtual bool TextureNeedsMips(const SPropertyDefinition *inPropDec, - qt3ds::render::NVRenderTexture2D *inTexture) - { - if (inPropDec && inTexture) { - return bool((inPropDec->m_MinFilterOp == NVRenderTextureMinifyingOp::LinearMipmapLinear) - && (inTexture->GetNumMipmaps() == 0)); - } - - return false; - } - - virtual void SetTexture(NVRenderShaderProgram &inShader, CRegisteredString inPropName, - NVRenderTexture2D *inTexture, - const SPropertyDefinition *inPropDec = NULL, bool needMips = false) - { - SCustomMaterialTextureData *theTextureEntry(NULL); - for (QT3DSU32 idx = 0, end = m_TextureEntries.size(); idx < end && theTextureEntry == NULL; - ++idx) { - if (m_TextureEntries[idx].first == inPropName - && m_TextureEntries[idx].second->m_Shader.mPtr == &inShader - && m_TextureEntries[idx].second->m_Texture == inTexture) { - theTextureEntry = m_TextureEntries[idx].second; - break; - } - } - if (theTextureEntry == NULL) { - NVScopedRefCounted theNewEntry = - QT3DS_NEW(m_CoreContext.GetAllocator(), SCustomMaterialTextureData)( - SCustomMaterialTextureData::CreateTextureEntry(inShader, inTexture, inPropName, - needMips)); - m_TextureEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); - theTextureEntry = theNewEntry.mPtr; - } - theTextureEntry->Set(inPropDec); - } - - void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inNames) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetPropertyEnumNames(inName, inPropName, - inNames); - } - - void SetPropertyTextureSettings(CRegisteredString inName, CRegisteredString inPropName, - CRegisteredString inPropPath, - NVRenderTextureTypeValue::Enum inTexType, - NVRenderTextureCoordOp::Enum inCoordOp, - NVRenderTextureMagnifyingOp::Enum inMagFilterOp, - NVRenderTextureMinifyingOp::Enum inMinFilterOp) override - { - SMaterialClass *theClass = GetMaterialClass(inName); - if (theClass && inTexType == NVRenderTextureTypeValue::Displace) { - theClass->m_HasDisplacement = true; - } - m_CoreContext.GetDynamicObjectSystemCore().SetPropertyTextureSettings( - inName, inPropName, inPropPath, inTexType, inCoordOp, inMagFilterOp, inMinFilterOp); - } - - void SetMaterialClassShader(CRegisteredString inName, const char8_t *inShaderType, - const char8_t *inShaderVersion, const char8_t *inShaderData, - bool inHasGeomShader, bool inIsComputeShader) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetShaderData(inName, inShaderData, inShaderType, - inShaderVersion, inHasGeomShader, - inIsComputeShader); - } - - SCustomMaterial *CreateCustomMaterial(CRegisteredString inName, - NVAllocatorCallback &inSceneGraphAllocator) override - { - SCustomMaterial *theMaterial = static_cast( - m_CoreContext.GetDynamicObjectSystemCore().CreateInstance(inName, - inSceneGraphAllocator)); - SMaterialClass *theClass = GetMaterialClass(inName); - - if (theMaterial) { - QT3DSU32 key = 0, count = 0; - if (theClass) { - key = theClass->m_ShaderKey; - count = theClass->m_LayerCount; - } - theMaterial->Initialize(key, count); - } - - return theMaterial; - } - - void SetCustomMaterialTransparency(CRegisteredString inName, bool inHasTransparency) override - { - SMaterialClass *theClass = GetMaterialClass(inName); - - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - - theClass->m_HasTransparency = inHasTransparency; - } - - void SetCustomMaterialRefraction(CRegisteredString inName, bool inHasRefraction) override - { - SMaterialClass *theClass = GetMaterialClass(inName); - - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - - theClass->m_HasRefraction = inHasRefraction; - } - - void SetCustomMaterialAlwaysDirty(CRegisteredString inName, bool inIsAlwaysDirty) override - { - SMaterialClass *theClass = GetMaterialClass(inName); - - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - - theClass->m_AlwaysDirty = inIsAlwaysDirty; - } - - void SetCustomMaterialShaderKey(CRegisteredString inName, QT3DSU32 inShaderKey) override - { - SMaterialClass *theClass = GetMaterialClass(inName); - - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - - theClass->m_ShaderKey = inShaderKey; - } - - void SetCustomMaterialLayerCount(CRegisteredString inName, QT3DSU32 inLayerCount) override - { - SMaterialClass *theClass = GetMaterialClass(inName); - - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - - theClass->m_LayerCount = inLayerCount; - } - - void SetCustomMaterialCommands(CRegisteredString inName, - NVConstDataRef inCommands) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands(inName, inCommands); - } - - CRegisteredString GetShaderCacheKey(CRenderString &inShaderKeyBuffer, const char8_t *inId, - const char8_t *inProgramMacro, - const dynamic::SDynamicShaderProgramFlags &inFlags) - { - inShaderKeyBuffer.assign(inId); - if (inProgramMacro && *inProgramMacro) { - inShaderKeyBuffer.append("#"); - inShaderKeyBuffer.append(inProgramMacro); - } - if (inFlags.IsTessellationEnabled()) { - inShaderKeyBuffer.append("#"); - inShaderKeyBuffer.append(TessModeValues::toString(inFlags.m_TessMode)); - } - if (inFlags.IsGeometryShaderEnabled() && inFlags.m_WireframeMode) { - inShaderKeyBuffer.append("#"); - inShaderKeyBuffer.append(inFlags.wireframeToString(inFlags.m_WireframeMode)); - } - - return m_CoreContext.GetStringTable().RegisterStr(inShaderKeyBuffer.c_str()); - } - - NVRenderShaderProgram *GetShader(SCustomMaterialRenderContext &inRenderContext, - const SCustomMaterial &inMaterial, - const SBindShader &inCommand, TShaderFeatureSet inFeatureSet, - const dynamic::SDynamicShaderProgramFlags &inFlags) - { - ICustomMaterialShaderGenerator &theMaterialGenerator( - m_Context->GetCustomMaterialShaderGenerator()); - - // generate key - CRenderString theShaderKeyBuffer; - CRegisteredString theKey = GetShaderCacheKey(theShaderKeyBuffer, inCommand.m_ShaderPath, - inCommand.m_ShaderDefine, inFlags); - - SCustomMaterialVertexPipeline thePipeline(m_Context, - inRenderContext.m_Model.m_TessellationMode); - - NVRenderShaderProgram *theProgram = theMaterialGenerator.GenerateShader( - inMaterial, inRenderContext.m_MaterialKey, thePipeline, inFeatureSet, - inRenderContext.m_Lights, inRenderContext.m_FirstImage, - (inMaterial.m_hasTransparency || inMaterial.m_hasRefraction), - "custom material pipeline-- ", inCommand.m_ShaderPath.c_str()); - - return theProgram; - } - - SMaterialOrComputeShader BindShader(SCustomMaterialRenderContext &inRenderContext, - const SCustomMaterial &inMaterial, - const SBindShader &inCommand, - TShaderFeatureSet inFeatureSet) - { - NVRenderShaderProgram *theProgram = NULL; - - SDynamicShaderProgramFlags theFlags(inRenderContext.m_Model.m_TessellationMode, - inRenderContext.m_Subset.m_WireframeMode); - theFlags.SetTessellationEnabled(inRenderContext.m_Model.m_TessellationMode - != TessModeValues::NoTess); - theFlags.SetGeometryShaderEnabled(inRenderContext.m_Subset.m_WireframeMode); - - SShaderMapKey skey = SShaderMapKey( - TStrStrPair(inCommand.m_ShaderPath, inCommand.m_ShaderDefine), inFeatureSet, - theFlags.m_TessMode, theFlags.m_WireframeMode, inRenderContext.m_MaterialKey); - eastl::pair theInsertResult(m_ShaderMap.insert( - eastl::make_pair(skey, NVScopedRefCounted(NULL)))); - - if (theInsertResult.second) { - theProgram = GetShader(inRenderContext, inMaterial, inCommand, inFeatureSet, theFlags); - - if (theProgram) { - theInsertResult.first->second = - QT3DS_NEW(m_Allocator, SCustomMaterialShader)(*theProgram, theFlags); - } - } else if (theInsertResult.first->second) - theProgram = theInsertResult.first->second->m_Shader; - - if (theProgram) { - if (theProgram->GetProgramType() == NVRenderShaderProgram::ProgramType::Graphics) { - if (theInsertResult.first->second) { - NVRenderContext &theContext(m_Context->GetRenderContext()); - theContext.SetActiveShader(theInsertResult.first->second->m_Shader); - } - - return *theInsertResult.first->second; - } else { - NVRenderContext &theContext(m_Context->GetRenderContext()); - theContext.SetActiveShader(theProgram); - return *(static_cast(theProgram)); - } - } - return SMaterialOrComputeShader(); - } - - void DoApplyInstanceValue(SCustomMaterial & /* inMaterial */, QT3DSU8 *inDataPtr, - CRegisteredString inPropertyName, - NVRenderShaderDataTypes::Enum inPropertyType, - NVRenderShaderProgram &inShader, - const SPropertyDefinition &inDefinition) - { - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(inPropertyName); - using namespace qt3ds::render; - if (theConstant) { - if (theConstant->GetShaderConstantType() == inPropertyType) { - if (inPropertyType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - StaticAssert::valid_expression(); - CRegisteredString *theStrPtr = reinterpret_cast(inDataPtr); - IBufferManager &theBufferManager(m_Context->GetBufferManager()); - NVRenderTexture2D *theTexture = NULL; - - if (theStrPtr->IsValid()) { - SImageTextureData theTextureData = - theBufferManager.LoadRenderImage(*theStrPtr); - if (theTextureData.m_Texture) { - theTexture = theTextureData.m_Texture; - SetTexture(inShader, inPropertyName, theTexture, &inDefinition, - TextureNeedsMips(&inDefinition, theTexture)); - } - } - } else { - switch (inPropertyType) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ - case NVRenderShaderDataTypes::type: \ - inShader.SetPropertyValue(theConstant, *(reinterpret_cast(inDataPtr))); \ - break; - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - QT3DS_ASSERT(false); - break; - } - } - } else { - qCCritical(INVALID_OPERATION, - "CustomMaterial ApplyInstanceValue command datatype and " - "shader datatypes differ for property %s", - inPropertyName.c_str()); - QT3DS_ASSERT(false); - } - } - } - - void ApplyInstanceValue(SCustomMaterial &inMaterial, SMaterialClass &inClass, - NVRenderShaderProgram &inShader, const SApplyInstanceValue &inCommand) - { - // sanity check - if (inCommand.m_PropertyName.IsValid()) { - bool canGetData = - inCommand.m_ValueOffset + getSizeofShaderDataType(inCommand.m_ValueType) - <= inMaterial.m_DataSectionByteSize; - if (canGetData == false) { - QT3DS_ASSERT(false); - return; - } - QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + inCommand.m_ValueOffset; - const SPropertyDefinition *theDefinition = - inClass.m_Class->FindPropertyByName(inCommand.m_PropertyName); - if (theDefinition) - DoApplyInstanceValue(inMaterial, dataPtr, inCommand.m_PropertyName, - inCommand.m_ValueType, inShader, *theDefinition); - } else { - NVConstDataRef theDefs = inClass.m_Class->GetProperties(); - for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) { - const SPropertyDefinition &theDefinition(theDefs[idx]); - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(theDefinition.m_Name); - - // This is fine, the property wasn't found and we continue, no problem. - if (!theConstant) - continue; - QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + theDefinition.m_Offset; - DoApplyInstanceValue(inMaterial, dataPtr, theDefinition.m_Name, - theDefinition.m_DataType, inShader, theDefinition); - } - } - } - - void ApplyBlending(const SApplyBlending &inCommand) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - - theContext.SetBlendingEnabled(true); - - qt3ds::render::NVRenderBlendFunctionArgument blendFunc = - qt3ds::render::NVRenderBlendFunctionArgument( - inCommand.m_SrcBlendFunc, inCommand.m_DstBlendFunc, inCommand.m_SrcBlendFunc, - inCommand.m_DstBlendFunc); - - qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - - theContext.SetBlendFunction(blendFunc); - theContext.SetBlendEquation(blendEqu); - } - - // we currently only bind a source texture - const NVRenderTexture2D *ApplyBufferValue(const SCustomMaterial &inMaterial, - NVRenderShaderProgram &inShader, - const SApplyBufferValue &inCommand, - const NVRenderTexture2D *inSourceTexture) - { - const NVRenderTexture2D *theTexture = NULL; - - if (inCommand.m_BufferName.IsValid()) { - QT3DSU32 bufferIdx = FindBuffer(inCommand.m_BufferName); - if (bufferIdx < m_AllocatedBuffers.size()) { - SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); - theTexture = theEntry.m_Texture; - } else { - // we must have allocated the read target before - qCCritical(INTERNAL_ERROR, - "CustomMaterial: ApplyBufferValue: Failed to setup read target"); - QT3DS_ASSERT(false); - } - } else - theTexture = inSourceTexture; - - if (inCommand.m_ParamName.IsValid()) { - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(inCommand.m_ParamName); - - if (theConstant) { - if (theConstant->GetShaderConstantType() - != NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - qCCritical(INVALID_OPERATION, - "CustomMaterial %s: Binding buffer to parameter %s that is not a texture", - inMaterial.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); - QT3DS_ASSERT(false); - } else { - SetTexture(inShader, inCommand.m_ParamName, - const_cast(theTexture)); - } - } - } - - return theTexture; - } - - void AllocateBuffer(const SAllocateBuffer &inCommand, NVRenderFrameBuffer *inTarget) - { - STextureDetails theSourceTextureDetails; - NVRenderTexture2D *theTexture = NULL; - // get color attachment we always assume at location 0 - if (inTarget) { - NVRenderTextureOrRenderBuffer theSourceTexture = - inTarget->GetAttachment(NVRenderFrameBufferAttachments::Color0); - // we need a texture - if (theSourceTexture.HasTexture2D()) { - theSourceTextureDetails = theSourceTexture.GetTexture2D()->GetTextureDetails(); - } else { - qCCritical(INVALID_OPERATION, "CustomMaterial %s: Invalid source texture", - inCommand.m_Name.c_str()); - QT3DS_ASSERT(false); - return; - } - } else { - NVRenderContext &theContext = m_Context->GetRenderContext(); - // if we allocate a buffer based on the default target use viewport to get the dimension - NVRenderRect theViewport(theContext.GetViewport()); - theSourceTextureDetails.m_Height = theViewport.m_Height; - theSourceTextureDetails.m_Width = theViewport.m_Width; - } - - QT3DSU32 theWidth = (QT3DSU32)(theSourceTextureDetails.m_Width * inCommand.m_SizeMultiplier); - QT3DSU32 theHeight = (QT3DSU32)(theSourceTextureDetails.m_Height * inCommand.m_SizeMultiplier); - NVRenderTextureFormats::Enum theFormat = inCommand.m_Format; - if (theFormat == NVRenderTextureFormats::Unknown) - theFormat = theSourceTextureDetails.m_Format; - IResourceManager &theResourceManager(m_Context->GetResourceManager()); - // size intentionally requiried every loop; - QT3DSU32 bufferIdx = FindBuffer(inCommand.m_Name); - if (bufferIdx < m_AllocatedBuffers.size()) { - SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); - STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails(); - if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight - && theDetails.m_Format == theFormat) { - theTexture = theEntry.m_Texture; - } else { - ReleaseBuffer(bufferIdx); - } - } - - if (theTexture == NULL) { - NVRenderFrameBuffer *theFB(theResourceManager.AllocateFrameBuffer()); - NVRenderTexture2D *theTexture( - theResourceManager.AllocateTexture2D(theWidth, theHeight, theFormat)); - theTexture->SetMagFilter(inCommand.m_FilterOp); - theTexture->SetMinFilter( - static_cast(inCommand.m_FilterOp)); - theTexture->SetTextureWrapS(inCommand.m_TexCoordOp); - theTexture->SetTextureWrapT(inCommand.m_TexCoordOp); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *theTexture); - m_AllocatedBuffers.push_back(SCustomMaterialBuffer( - inCommand.m_Name, *theFB, *theTexture, inCommand.m_BufferFlags)); - } - } - - NVRenderFrameBuffer *BindBuffer(const SCustomMaterial &inMaterial, const SBindBuffer &inCommand, - bool &outClearTarget, QT3DSVec2 &outDestSize) - { - NVRenderFrameBuffer *theBuffer = NULL; - NVRenderTexture2D *theTexture = NULL; - - // search for the buffer - QT3DSU32 bufferIdx = FindBuffer(inCommand.m_BufferName); - if (bufferIdx < m_AllocatedBuffers.size()) { - theBuffer = m_AllocatedBuffers[bufferIdx].m_FrameBuffer; - theTexture = m_AllocatedBuffers[bufferIdx].m_Texture; - } - - if (theBuffer == NULL) { - qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", - inMaterial.m_ClassName.c_str(), inCommand.m_BufferName.c_str()); - QT3DS_ASSERT(false); - return NULL; - } - - if (theTexture) { - STextureDetails theDetails(theTexture->GetTextureDetails()); - m_Context->GetRenderContext().SetViewport( - NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); - outDestSize = QT3DSVec2((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); - outClearTarget = inCommand.m_NeedsClear; - } - - return theBuffer; - } - - void computeScreenCoverage(SCustomMaterialRenderContext &inRenderContext, QT3DSI32 *xMin, - QT3DSI32 *yMin, QT3DSI32 *xMax, QT3DSI32 *yMax) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - TNVBounds2BoxPoints outPoints; - QT3DSVec4 projMin(QT3DS_MAX_REAL); - QT3DSVec4 projMax(-QT3DS_MAX_REAL); - - // get points - inRenderContext.m_Subset.m_Bounds.expand(outPoints); - for (QT3DSU32 idx = 0; idx < 8; ++idx) { - QT3DSVec4 homPoint(outPoints[idx], 1.0); - QT3DSVec4 projPoint = inRenderContext.m_ModelViewProjection.transform(homPoint); - projPoint /= projPoint.w; - - if (projMin.x > projPoint.x) - projMin.x = projPoint.x; - if (projMin.y > projPoint.y) - projMin.y = projPoint.y; - if (projMin.z > projPoint.z) - projMin.z = projPoint.z; - - if (projMax.x < projPoint.x) - projMax.x = projPoint.x; - if (projMax.y < projPoint.y) - projMax.y = projPoint.y; - if (projMax.z < projPoint.z) - projMax.z = projPoint.z; - } - - NVRenderRect theViewport(theContext.GetViewport()); - QT3DSI32 x1 = QT3DSI32(projMax.x * (theViewport.m_Width / 2) - + (theViewport.m_X + (theViewport.m_Width / 2))); - QT3DSI32 y1 = QT3DSI32(projMax.y * (theViewport.m_Height / 2) - + (theViewport.m_Y + (theViewport.m_Height / 2))); - - QT3DSI32 x2 = QT3DSI32(projMin.x * (theViewport.m_Width / 2) - + (theViewport.m_X + (theViewport.m_Width / 2))); - QT3DSI32 y2 = QT3DSI32(projMin.y * (theViewport.m_Height / 2) - + (theViewport.m_Y + (theViewport.m_Height / 2))); - - if (x1 > x2) { - *xMin = x2; - *xMax = x1; - } else { - *xMin = x1; - *xMax = x2; - } - if (y1 > y2) { - *yMin = y2; - *yMax = y1; - } else { - *yMin = y1; - *yMax = y2; - } - } - - void BlitFramebuffer(SCustomMaterialRenderContext &inRenderContext, - const SApplyBlitFramebuffer &inCommand, NVRenderFrameBuffer *inTarget) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - // we change the read/render targets here - NVRenderContextScopedProperty __framebuffer( - theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - // we may alter scissor - NVRenderContextScopedProperty theScissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled); - - if (inCommand.m_DestBufferName.IsValid()) { - QT3DSU32 bufferIdx = FindBuffer(inCommand.m_DestBufferName); - if (bufferIdx < m_AllocatedBuffers.size()) { - SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); - theContext.SetRenderTarget(theEntry.m_FrameBuffer); - } else { - // we must have allocated the read target before - qCCritical(INTERNAL_ERROR, - "CustomMaterial: BlitFramebuffer: Failed to setup render target"); - QT3DS_ASSERT(false); - } - } else { - // our dest is the default render target - theContext.SetRenderTarget(inTarget); - } - - if (inCommand.m_SourceBufferName.IsValid()) { - QT3DSU32 bufferIdx = FindBuffer(inCommand.m_SourceBufferName); - if (bufferIdx < m_AllocatedBuffers.size()) { - SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); - theContext.SetReadTarget(theEntry.m_FrameBuffer); - theContext.SetReadBuffer(NVReadFaces::Color0); - } else { - // we must have allocated the read target before - qCCritical(INTERNAL_ERROR, - "CustomMaterial: BlitFramebuffer: Failed to setup read target"); - QT3DS_ASSERT(false); - } - } else { - // our source is the default read target - // depending on what we render we assume color0 or back - theContext.SetReadTarget(inTarget); - NVReadFaces::Enum value = (inTarget) ? NVReadFaces::Color0 : NVReadFaces::Back; - theContext.SetReadBuffer(value); - } - - NVRenderRect theViewport(theContext.GetViewport()); - theContext.SetScissorTestEnabled(false); - - if (!m_UseFastBlits) { - // only copy sreen amount of pixels - QT3DSI32 xMin, yMin, xMax, yMax; - computeScreenCoverage(inRenderContext, &xMin, &yMin, &xMax, &yMax); - - // same dimension - theContext.BlitFramebuffer(xMin, yMin, xMax, yMax, xMin, yMin, xMax, yMax, - NVRenderClearValues::Color, - NVRenderTextureMagnifyingOp::Nearest); - } else { - // same dimension - theContext.BlitFramebuffer( - theViewport.m_X, theViewport.m_Y, theViewport.m_X + theViewport.m_Width, - theViewport.m_Y + theViewport.m_Height, theViewport.m_X, theViewport.m_Y, - theViewport.m_X + theViewport.m_Width, theViewport.m_Y + theViewport.m_Height, - NVRenderClearValues::Color, NVRenderTextureMagnifyingOp::Nearest); - } - } - - SLayerGlobalRenderProperties - GetLayerGlobalRenderProperties(SCustomMaterialRenderContext &inRenderContext) - { - const SLayer &theLayer = inRenderContext.m_Layer; - const SLayerRenderData &theData = inRenderContext.m_LayerData; - - return SLayerGlobalRenderProperties( - theLayer, const_cast(inRenderContext.m_Camera), theData.m_CameraDirection, - inRenderContext.m_Lights, NVDataRef(), theData.m_ShadowMapManager.mPtr, - const_cast(inRenderContext.m_DepthTexture), - const_cast(inRenderContext.m_AOTexture), theLayer.m_LightProbe, - theLayer.m_LightProbe2, theLayer.m_ProbeHorizon, theLayer.m_ProbeBright, - theLayer.m_Probe2Window, theLayer.m_Probe2Pos, theLayer.m_Probe2Fade, - theLayer.m_ProbeFov); - } - - void RenderPass(SCustomMaterialRenderContext &inRenderContext, SCustomMaterialShader &inShader, - NVRenderTexture2D * /* inSourceTexture */ - , - NVRenderFrameBuffer *inFrameBuffer, bool inRenderTargetNeedsClear, - NVRenderInputAssembler &inAssembler, QT3DSU32 inCount, QT3DSU32 inOffset) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - theContext.SetRenderTarget(inFrameBuffer); - - QT3DSVec4 clearColor(0.0); - NVRenderContextScopedProperty __clearColor( - theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - clearColor); - if (inRenderTargetNeedsClear) { - theContext.Clear(qt3ds::render::NVRenderClearValues::Color); - } - - ICustomMaterialShaderGenerator &theMaterialGenerator( - m_Context->GetCustomMaterialShaderGenerator()); - - theMaterialGenerator.SetMaterialProperties( - *inShader.m_Shader, inRenderContext.m_Material, QT3DSVec2(1.0, 1.0), - inRenderContext.m_ModelViewProjection, inRenderContext.m_NormalMatrix, - inRenderContext.m_ModelMatrix, inRenderContext.m_FirstImage, inRenderContext.m_Opacity, - GetLayerGlobalRenderProperties(inRenderContext)); - - // I think the prim type should always be fetched from the - // current mesh subset setup because there you get the actual draw mode - // for this frame - NVRenderDrawMode::Enum theDrawMode = inAssembler.GetPrimitiveType(); - - // tesselation - if (inRenderContext.m_Subset.m_PrimitiveType == NVRenderDrawMode::Patches) { - QT3DSVec2 camProps(inRenderContext.m_Camera.m_ClipNear, - inRenderContext.m_Camera.m_ClipFar); - theDrawMode = inRenderContext.m_Subset.m_PrimitiveType; - inShader.m_Tessellation.m_EdgeTessLevel.Set(inRenderContext.m_Subset.m_EdgeTessFactor); - inShader.m_Tessellation.m_InsideTessLevel.Set( - inRenderContext.m_Subset.m_InnerTessFactor); - // the blend value is hardcoded - inShader.m_Tessellation.m_PhongBlend.Set(0.75); - // this should finally be based on some user input - inShader.m_Tessellation.m_DistanceRange.Set(camProps); - // enable culling - inShader.m_Tessellation.m_DisableCulling.Set(0.0); - } - - if (inRenderContext.m_Subset.m_WireframeMode) { - NVRenderRect theViewport(theContext.GetViewport()); - QT3DSMat44 vpMatrix; - vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0); - vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0); - vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0); - vpMatrix.column3 = - QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X, - (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0); - - inShader.m_ViewportMatrix.Set(vpMatrix); - } - - theContext.SetInputAssembler(&inAssembler); - - theContext.SetCullingEnabled(true); - QT3DSU32 count = inCount; - QT3DSU32 offset = inOffset; - - theContext.Draw(theDrawMode, count, offset); - } - - void DoRenderCustomMaterial(SCustomMaterialRenderContext &inRenderContext, - const SCustomMaterial &inMaterial, SMaterialClass &inClass, - NVRenderFrameBuffer *inTarget, TShaderFeatureSet inFeatureSet) - { - NVRenderContext &theContext = m_Context->GetRenderContext(); - SCustomMaterialShader *theCurrentShader(NULL); - - NVRenderFrameBuffer *theCurrentRenderTarget(inTarget); - NVRenderRect theOriginalViewport(theContext.GetViewport()); - NVRenderTexture2D *theCurrentSourceTexture = 0; - - // for refrative materials we come from the transparent render path - // but we do not want to do blending - bool wasBlendingEnabled = theContext.IsBlendingEnabled(); - if (inMaterial.m_hasRefraction) - theContext.SetBlendingEnabled(false); - - NVRenderContextScopedProperty __framebuffer( - theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - NVRenderContextScopedProperty __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - - QT3DSVec2 theDestSize; - bool theRenderTargetNeedsClear = false; - - NVConstDataRef theCommands(inClass.m_Class->GetRenderCommands()); - for (QT3DSU32 commandIdx = 0, commandEnd = theCommands.size(); commandIdx < commandEnd; - ++commandIdx) { - const SCommand &theCommand(*theCommands[commandIdx]); - - switch (theCommand.m_Type) { - case CommandTypes::AllocateBuffer: - AllocateBuffer(static_cast(theCommand), inTarget); - break; - case CommandTypes::BindBuffer: - theCurrentRenderTarget = - BindBuffer(inMaterial, static_cast(theCommand), - theRenderTargetNeedsClear, theDestSize); - break; - case CommandTypes::BindTarget: - // Restore the previous render target and info. - theCurrentRenderTarget = inTarget; - theContext.SetViewport(theOriginalViewport); - break; - case CommandTypes::BindShader: { - theCurrentShader = NULL; - SMaterialOrComputeShader theBindResult = - BindShader(inRenderContext, inMaterial, - static_cast(theCommand), inFeatureSet); - if (theBindResult.IsMaterialShader()) - theCurrentShader = &theBindResult.MaterialShader(); - } break; - case CommandTypes::ApplyInstanceValue: - // we apply the property update explicitly at the render pass - break; - case CommandTypes::Render: - if (theCurrentShader) { - RenderPass(inRenderContext, *theCurrentShader, theCurrentSourceTexture, - theCurrentRenderTarget, theRenderTargetNeedsClear, - *inRenderContext.m_Subset.m_InputAssembler, - inRenderContext.m_Subset.m_Count, inRenderContext.m_Subset.m_Offset); - } - // reset - theRenderTargetNeedsClear = false; - break; - case CommandTypes::ApplyBlending: - ApplyBlending(static_cast(theCommand)); - break; - case CommandTypes::ApplyBufferValue: - if (theCurrentShader) - ApplyBufferValue(inMaterial, *theCurrentShader->m_Shader, - static_cast(theCommand), - theCurrentSourceTexture); - break; - case CommandTypes::ApplyBlitFramebuffer: - BlitFramebuffer(inRenderContext, - static_cast(theCommand), inTarget); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - if (inMaterial.m_hasRefraction) - theContext.SetBlendingEnabled(wasBlendingEnabled); - - // Release any per-frame buffers - for (QT3DSU32 idx = 0; idx < m_AllocatedBuffers.size(); ++idx) { - if (m_AllocatedBuffers[idx].m_Flags.IsSceneLifetime() == false) { - ReleaseBuffer(idx); - --idx; - } - } - } - - const char *GetShaderName(const SCustomMaterial &inMaterial) override - { - SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); - if (!theClass) - return NULL; - - NVConstDataRef theCommands = theClass->m_Class->GetRenderCommands(); - TShaderAndFlags thePrepassShader; - for (QT3DSU32 idx = 0, end = theCommands.size(); - idx < end && thePrepassShader.first.mPtr == NULL; ++idx) { - const SCommand &theCommand = *theCommands[idx]; - if (theCommand.m_Type == CommandTypes::BindShader) { - const SBindShader &theBindCommand = static_cast(theCommand); - return theBindCommand.m_ShaderPath.c_str(); - } - } - - QT3DS_ASSERT(false); - return NULL; - } - - void ApplyShaderPropertyValues(const SCustomMaterial &inMaterial, - NVRenderShaderProgram &inProgram) override - { - SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); - if (!theClass) - return; - - SApplyInstanceValue applier; - ApplyInstanceValue(const_cast(inMaterial), *theClass, inProgram, - applier); - } - - virtual void PrepareTextureForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) - { - NVConstDataRef thePropDefs = inClass.m_Class->GetProperties(); - for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) { - if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - if (thePropDefs[idx].m_TexUsageType == NVRenderTextureTypeValue::Displace) { - SImage *pImage = NULL; - - // we only do this to not miss if "None" is selected - CRegisteredString theStrPtr = *reinterpret_cast( - inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset); - - if (theStrPtr.IsValid()) { - - QT3DSU32 index = FindAllocatedImage(thePropDefs[idx].m_ImagePath); - if (index == QT3DSU32(-1)) { - pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)(); - m_AllocatedImages.push_back( - eastl::make_pair(thePropDefs[idx].m_ImagePath, pImage)); - } else - pImage = m_AllocatedImages[index].second; - - if (inMaterial.m_DisplacementMap != pImage) { - inMaterial.m_DisplacementMap = pImage; - inMaterial.m_DisplacementMap->m_ImagePath = - thePropDefs[idx].m_ImagePath; - inMaterial.m_DisplacementMap->m_ImageShaderName = - thePropDefs[idx].m_Name; // this is our name in the shader - inMaterial.m_DisplacementMap->m_VerticalTilingMode = - thePropDefs[idx].m_CoordOp; - inMaterial.m_DisplacementMap->m_HorizontalTilingMode = - thePropDefs[idx].m_CoordOp; - } - } else { - inMaterial.m_DisplacementMap = NULL; - } - } else if (thePropDefs[idx].m_TexUsageType == NVRenderTextureTypeValue::Emissive2) { - SImage *pImage = NULL; - - // we only do this to not miss if "None" is selected - CRegisteredString theStrPtr = *reinterpret_cast( - inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset); - - if (theStrPtr.IsValid()) { - QT3DSU32 index = FindAllocatedImage(thePropDefs[idx].m_ImagePath); - if (index == QT3DSU32(-1)) { - pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)(); - m_AllocatedImages.push_back( - eastl::make_pair(thePropDefs[idx].m_ImagePath, pImage)); - } else - pImage = m_AllocatedImages[index].second; - - if (inMaterial.m_EmissiveMap2 != pImage) { - inMaterial.m_EmissiveMap2 = pImage; - inMaterial.m_EmissiveMap2->m_ImagePath = thePropDefs[idx].m_ImagePath; - inMaterial.m_EmissiveMap2->m_ImageShaderName = - thePropDefs[idx].m_Name; // this is our name in the shader - inMaterial.m_EmissiveMap2->m_VerticalTilingMode = - thePropDefs[idx].m_CoordOp; - inMaterial.m_EmissiveMap2->m_HorizontalTilingMode = - thePropDefs[idx].m_CoordOp; - } - } else { - inMaterial.m_EmissiveMap2 = NULL; - } - } - } - } - } - - virtual void PrepareDisplacementForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) - { - if (inMaterial.m_DisplacementMap == NULL) - return; - - // our displacement mappin in MDL has fixed naming - NVConstDataRef thePropDefs = inClass.m_Class->GetProperties(); - for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) { - if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSF32 - && AreEqual(thePropDefs[idx].m_Name.c_str(), "displaceAmount")) { - QT3DSF32 theValue = *reinterpret_cast(inMaterial.GetDataSectionBegin() - + thePropDefs[idx].m_Offset); - inMaterial.m_DisplaceAmount = theValue; - } else if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSVec3 - && AreEqual(thePropDefs[idx].m_Name.c_str(), "displace_tiling")) { - QT3DSVec3 theValue = *reinterpret_cast(inMaterial.GetDataSectionBegin() - + thePropDefs[idx].m_Offset); - if (theValue.x != inMaterial.m_DisplacementMap->m_Scale.x - || theValue.y != inMaterial.m_DisplacementMap->m_Scale.y) { - inMaterial.m_DisplacementMap->m_Scale = QT3DSVec2(theValue.x, theValue.y); - inMaterial.m_DisplacementMap->m_Flags.SetTransformDirty(true); - } - } - } - } - - void PrepareMaterialForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) - { - PrepareTextureForRender(inClass, inMaterial); - - if (inClass.m_HasDisplacement) - PrepareDisplacementForRender(inClass, inMaterial); - } - - // Returns true if the material is dirty and thus will produce a different render result - // than previously. This effects things like progressive AA. - // TODO - return more information, specifically about transparency (object is transparent, - // object is completely transparent - bool PrepareForRender(const SModel & /*inModel*/, const SRenderSubset & /*inSubset*/, - SCustomMaterial &inMaterial, bool clearMaterialDirtyFlags) override - { - SMaterialClass *theMaterialClass = GetMaterialClass(inMaterial.m_ClassName); - if (theMaterialClass == NULL) { - QT3DS_ASSERT(false); - return false; - } - - PrepareMaterialForRender(*theMaterialClass, inMaterial); - - inMaterial.m_hasTransparency = theMaterialClass->m_HasTransparency; - inMaterial.m_hasRefraction = theMaterialClass->m_HasRefraction; - inMaterial.m_hasVolumetricDF = false; - - bool wasDirty = inMaterial.IsDirty() || theMaterialClass->m_AlwaysDirty; - if (clearMaterialDirtyFlags) - inMaterial.UpdateDirtyForFrame(); - - return wasDirty; - } - - // TODO - handle UIC specific features such as vertex offsets for prog-aa and opacity. - void RenderSubset(SCustomMaterialRenderContext &inRenderContext, - TShaderFeatureSet inFeatureSet) override - { - SMaterialClass *theClass = GetMaterialClass(inRenderContext.m_Material.m_ClassName); - - // Ensure that our overall render context comes back no matter what the client does. - qt3ds::render::NVRenderContextScopedProperty - __blendFunction(m_Context->GetRenderContext(), &NVRenderContext::GetBlendFunction, - &NVRenderContext::SetBlendFunction, - qt3ds::render::NVRenderBlendFunctionArgument()); - qt3ds::render::NVRenderContextScopedProperty - __blendEquation(m_Context->GetRenderContext(), &NVRenderContext::GetBlendEquation, - &NVRenderContext::SetBlendEquation, - qt3ds::render::NVRenderBlendEquationArgument()); - - NVRenderContextScopedProperty theBlendEnabled(m_Context->GetRenderContext(), - &NVRenderContext::IsBlendingEnabled, - &NVRenderContext::SetBlendingEnabled); - - DoRenderCustomMaterial(inRenderContext, inRenderContext.m_Material, *theClass, - m_Context->GetRenderContext().GetRenderTarget(), inFeatureSet); - } - - bool RenderDepthPrepass(const QT3DSMat44 &inMVP, const SCustomMaterial &inMaterial, - const SRenderSubset &inSubset) override - { - SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); - NVConstDataRef theCommands = theClass->m_Class->GetRenderCommands(); - TShaderAndFlags thePrepassShader; - for (QT3DSU32 idx = 0, end = theCommands.size(); - idx < end && thePrepassShader.first.mPtr == NULL; ++idx) { - const SCommand &theCommand = *theCommands[idx]; - if (theCommand.m_Type == CommandTypes::BindShader) { - const SBindShader &theBindCommand = static_cast(theCommand); - thePrepassShader = m_Context->GetDynamicObjectSystem().GetDepthPrepassShader( - theBindCommand.m_ShaderPath, CRegisteredString(), TShaderFeatureSet()); - } - } - - if (thePrepassShader.first.mPtr == NULL) - return false; - - NVRenderContext &theContext = m_Context->GetRenderContext(); - NVRenderShaderProgram &theProgram = *thePrepassShader.first; - theContext.SetActiveShader(&theProgram); - theProgram.SetPropertyValue("model_view_projection", inMVP); - theContext.SetInputAssembler(inSubset.m_InputAssemblerPoints); - theContext.Draw(NVRenderDrawMode::Lines, inSubset.m_PosVertexBuffer->GetNumVertexes(), 0); - return true; - } - - void OnMaterialActivationChange(const SCustomMaterial &inMaterial, bool inActive) override - { - Q_UNUSED(inMaterial) - Q_UNUSED(inActive) - } - - void EndFrame() override - { - QT3DSU64 currentFrameTime = qt3ds::foundation::Time::getCurrentTimeInTensOfNanoSeconds(); - if (m_LastFrameTime) { - QT3DSU64 timePassed = currentFrameTime - m_LastFrameTime; - m_MillisecondsSinceLastFrame = static_cast(timePassed / 100000.0); - } - m_LastFrameTime = currentFrameTime; - } - - void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, - const char8_t * /*inProjectDir*/) const override - { - QT3DSU32 offset = ioBuffer.size(); - ioBuffer.write((QT3DSU32)m_StringMaterialMap.size()); - for (TStringMaterialMap::const_iterator iter = m_StringMaterialMap.begin(), - end = m_StringMaterialMap.end(); - iter != end; ++iter) { - size_t nameOffset = ioBuffer.size() - offset; - (void)nameOffset; - CRegisteredString materialName(iter->first); - materialName.Remap(inRemapMap); - ioBuffer.write(materialName); - const SMaterialClass *materialClass = iter->second.mPtr; - QT3DSU32 offset = ioBuffer.size(); - ioBuffer.write(*materialClass); - QT3DSU8 *materialOffset = ioBuffer.begin() + offset; - SMaterialClass *writtenClass = (SMaterialClass *)materialOffset; - writtenClass->AfterWrite(); - ioBuffer.align(4); - } - } - - void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t * /*inProjectDir*/) override - { - m_Allocator.m_PreAllocatedBlock = inData; - m_Allocator.m_OwnsMemory = false; - qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); - QT3DSU32 numMaterialClasses = theReader.LoadRef(); - for (QT3DSU32 idx = 0; idx < numMaterialClasses; ++idx) { - CRegisteredString clsName = theReader.LoadRef(); - clsName.Remap(inStrDataBlock); - IDynamicObjectClass *theDynamicCls = - m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(clsName); - SMaterialClass *theReadClass = theReader.Load(); - theReader.Align(4); - if (theDynamicCls) { - theReadClass->AfterRead(m_Allocator, *theDynamicCls); - m_StringMaterialMap.insert(eastl::make_pair(clsName, theReadClass)); - } - } - } - - ICustomMaterialSystem &GetCustomMaterialSystem(IQt3DSRenderContext &inContext) override - { - m_Context = &inContext; - - // check for fast blits - NVRenderContext &theContext = m_Context->GetRenderContext(); - m_UseFastBlits = theContext.GetRenderBackendCap( - qt3ds::render::NVRenderBackend::NVRenderBackendCaps::FastBlits); - - return *this; - } -}; -} - -ICustomMaterialSystemCore & -ICustomMaterialSystemCore::CreateCustomMaterialSystemCore(IQt3DSRenderContextCore &ctx) -{ - return *QT3DS_NEW(ctx.GetAllocator(), SMaterialSystem)(ctx); -} - diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDefaultMaterialShaderGenerator.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDefaultMaterialShaderGenerator.cpp deleted file mode 100644 index 4dceaca8..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDefaultMaterialShaderGenerator.cpp +++ /dev/null @@ -1,1930 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderableImage.h" -#include "Qt3DSRenderImage.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderLight.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderShadowMap.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderLightConstantProperties.h" - -using namespace qt3ds::render; -using qt3ds::render::NVRenderCachedShaderProperty; -using qt3ds::render::NVRenderCachedShaderBuffer; - -namespace { - -const QT3DSF32 MINATTENUATION = 0; -const QT3DSF32 MAXATTENUATION = 1000; - -QT3DSF32 ClampFloat(QT3DSF32 value, QT3DSF32 min, QT3DSF32 max) -{ - return value < min ? min : ((value > max) ? max : value); -} - -QT3DSF32 TranslateConstantAttenuation(QT3DSF32 attenuation) -{ - return attenuation * .01f; -} - -QT3DSF32 TranslateLinearAttenuation(QT3DSF32 attenuation) -{ - attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); - return attenuation * 0.0001f; -} - -QT3DSF32 TranslateQuadraticAttenuation(QT3DSF32 attenuation) -{ - attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); - return attenuation * 0.0000001f; -} - -/** - * Cached texture property lookups, used one per texture so a shader generator for N - * textures will have an array of N of these lookup objects. - */ -struct SShaderTextureProperties -{ - NVRenderCachedShaderProperty m_Sampler; - NVRenderCachedShaderProperty m_Offsets; - NVRenderCachedShaderProperty m_Rotations; - NVRenderCachedShaderProperty m_Size; - SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, - const char *sizeName, - NVRenderShaderProgram &inShader) - : m_Sampler(sampName, inShader) - , m_Offsets(offName, inShader) - , m_Rotations(rotName, inShader) - , m_Size(sizeName, inShader) - { - } - SShaderTextureProperties() {} -}; - -/** - * Cached light property lookups, used one per light so a shader generator for N - * lights will have an array of N of these lookup objects. - */ -struct SShaderLightProperties -{ - // Color of the light - QT3DSVec3 m_LightColor; - SLightSourceShader m_LightData; - - SShaderLightProperties() {} -}; - -struct SShadowMapProperties -{ - NVRenderCachedShaderProperty m_ShadowmapTexture; ///< shadow texture - NVRenderCachedShaderProperty m_ShadowCubeTexture; ///< shadow cubemap - NVRenderCachedShaderProperty - m_ShadowmapMatrix; ///< world to ligh space transform matrix - NVRenderCachedShaderProperty m_ShadowmapSettings; ///< shadow rendering settings - - SShadowMapProperties() {} - SShadowMapProperties(const char *shadowmapTextureName, const char *shadowcubeTextureName, - const char *shadowmapMatrixName, const char *shadowmapSettingsName, - NVRenderShaderProgram &inShader) - : m_ShadowmapTexture(shadowmapTextureName, inShader) - , m_ShadowCubeTexture(shadowcubeTextureName, inShader) - , m_ShadowmapMatrix(shadowmapMatrixName, inShader) - , m_ShadowmapSettings(shadowmapSettingsName, inShader) - { - } -}; - -/** - * The results of generating a shader. Caches all possible variable names into - * typesafe objects. - */ -struct SShaderGeneratorGeneratedShader -{ - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - // Specific properties we know the shader has to have. - NVRenderCachedShaderProperty m_MVP; - NVRenderCachedShaderProperty m_NormalMatrix; - NVRenderCachedShaderProperty m_GlobalTransform; - NVRenderCachedShaderProperty m_ViewProj; - NVRenderCachedShaderProperty m_ViewMatrix; - NVRenderCachedShaderProperty m_MaterialDiffuse; - NVRenderCachedShaderProperty m_MaterialProperties; - // tint, ior - NVRenderCachedShaderProperty m_MaterialSpecular; - NVRenderCachedShaderProperty m_BumpAmount; - NVRenderCachedShaderProperty m_DisplaceAmount; - NVRenderCachedShaderProperty m_TranslucentFalloff; - NVRenderCachedShaderProperty m_DiffuseLightWrap; - NVRenderCachedShaderProperty m_FresnelPower; - NVRenderCachedShaderProperty m_DiffuseColor; - NVRenderCachedShaderProperty m_CameraPosition; - NVRenderCachedShaderProperty m_CameraDirection; - QT3DSVec3 m_LightAmbientTotal; - NVRenderCachedShaderProperty m_MaterialDiffuseLightAmbientTotal; - NVRenderCachedShaderProperty m_CameraProperties; - - NVRenderCachedShaderProperty m_DepthTexture; - NVRenderCachedShaderProperty m_AOTexture; - NVRenderCachedShaderProperty m_LightProbe; - NVRenderCachedShaderProperty m_LightProbeProps; - NVRenderCachedShaderProperty m_LightProbeOpts; - NVRenderCachedShaderProperty m_LightProbeRot; - NVRenderCachedShaderProperty m_LightProbeOfs; - NVRenderCachedShaderProperty m_LightProbeSize; - NVRenderCachedShaderProperty m_LightProbe2; - NVRenderCachedShaderProperty m_LightProbe2Props; - NVRenderCachedShaderProperty m_LightProbe2Size; - - NVRenderCachedShaderBuffer m_AoShadowParams; - NVRenderCachedShaderBuffer m_LightsBuffer; - - SLightConstantProperties *m_lightConstantProperties; - - // Cache the image property name lookups - nvvector m_Images; - nvvector m_Lights; - // Cache shadow map properties - nvvector m_ShadowMaps; - - QT3DSI32 m_RefCount; - - SShaderGeneratorGeneratedShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) - : m_Allocator(inContext.GetAllocator()) - , m_Shader(inShader) - , m_MVP("model_view_projection", inShader) - , m_NormalMatrix("normal_matrix", inShader) - , m_GlobalTransform("model_matrix", inShader) - , m_ViewProj("view_projection_matrix", inShader) - , m_ViewMatrix("view_matrix", inShader) - , m_MaterialDiffuse("material_diffuse", inShader) - , m_MaterialProperties("material_properties", inShader) - , m_MaterialSpecular("material_specular", inShader) - , m_BumpAmount("bumpAmount", inShader) - , m_DisplaceAmount("displaceAmount", inShader) - , m_TranslucentFalloff("translucentFalloff", inShader) - , m_DiffuseLightWrap("diffuseLightWrap", inShader) - , m_FresnelPower("fresnelPower", inShader) - , m_DiffuseColor("diffuse_color", inShader) - , m_CameraPosition("camera_position", inShader) - , m_CameraDirection("camera_direction", inShader) - , m_MaterialDiffuseLightAmbientTotal("light_ambient_total", inShader) - , m_CameraProperties("camera_properties", inShader) - , m_DepthTexture("depth_sampler", inShader) - , m_AOTexture("ao_sampler", inShader) - , m_LightProbe("light_probe", inShader) - , m_LightProbeProps("light_probe_props", inShader) - , m_LightProbeOpts("light_probe_opts", inShader) - , m_LightProbeRot("light_probe_rotation", inShader) - , m_LightProbeOfs("light_probe_offset", inShader) - , m_LightProbeSize("light_probe_size", inShader) - , m_LightProbe2("light_probe2", inShader) - , m_LightProbe2Props("light_probe2_props", inShader) - , m_LightProbe2Size("light_probe2_size", inShader) - , m_AoShadowParams("cbAoShadow", inShader) - , m_LightsBuffer("cbBufferLights", inShader) - , m_lightConstantProperties(NULL) - , m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images") - , m_Lights(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Lights") - , m_ShadowMaps(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_ShadowMaps") - , m_RefCount(0) - { - m_Shader.addRef(); - } - ~SShaderGeneratorGeneratedShader() - { - if (m_lightConstantProperties) - delete m_lightConstantProperties; - m_Shader.release(); - } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Allocator); - NVDelete(alloc, this); - } - } -}; - - -#ifndef EA_PLATFORM_WINDOWS -#define _snprintf snprintf -#endif - -struct SShaderGenerator : public IDefaultMaterialShaderGenerator -{ - typedef CRenderString TStrType; - typedef nvhash_map> - TProgramToShaderMap; - typedef qt3ds::foundation::nvhash_map> - TStrConstanBufMap; - - IQt3DSRenderContext &m_RenderContext; - IShaderProgramGenerator &m_ProgramGenerator; - - const SDefaultMaterial *m_CurrentMaterial; - SShaderDefaultMaterialKey *m_CurrentKey; - Qt3DSShadowMap *m_ShadowMapManager; - IDefaultMaterialVertexPipeline *m_CurrentPipeline; - TShaderFeatureSet m_CurrentFeatureSet; - NVDataRef m_Lights; - SRenderableImage *m_FirstImage; - bool m_HasTransparency; - bool m_LightsAsSeparateUniforms; - - TStrType m_ImageStem; - TStrType m_ImageSampler; - TStrType m_ImageOffsets; - TStrType m_ImageRotations; - TStrType m_ImageFragCoords; - TStrType m_ImageTemp; - TStrType m_ImageSamplerSize; - - TStrType m_TexCoordTemp; - - TStrType m_LightStem; - TStrType m_LightColor; - TStrType m_LightSpecularColor; - TStrType m_LightAttenuation; - TStrType m_LightConstantAttenuation; - TStrType m_LightLinearAttenuation; - TStrType m_LightQuadraticAttenuation; - TStrType m_NormalizedDirection; - TStrType m_LightDirection; - TStrType m_LightPos; - TStrType m_LightUp; - TStrType m_LightRt; - TStrType m_RelativeDistance; - TStrType m_RelativeDirection; - - TStrType m_ShadowMapStem; - TStrType m_ShadowCubeStem; - TStrType m_ShadowMatrixStem; - TStrType m_ShadowCoordStem; - TStrType m_ShadowControlStem; - - TStrType m_TempStr; - - eastl::string m_GeneratedShaderString; - - SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; - TProgramToShaderMap m_ProgramToShaderMap; - - TStrConstanBufMap m_ConstantBuffers; ///< store all constants buffers - - QT3DSI32 m_RefCount; - - SShaderGenerator(IQt3DSRenderContext &inRc) - : m_RenderContext(inRc) - , m_ProgramGenerator(m_RenderContext.GetShaderProgramGenerator()) - , m_CurrentMaterial(NULL) - , m_CurrentKey(NULL) - , m_ShadowMapManager(NULL) - , m_CurrentPipeline(NULL) - , m_FirstImage(NULL) - , m_LightsAsSeparateUniforms(false) - , m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap") - , m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers") - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - m_ConstantBuffers.clear(); - NVDelete(m_RenderContext.GetAllocator(), this); - } - } - IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } - IDefaultMaterialVertexPipeline &VertexGenerator() { return *m_CurrentPipeline; } - IShaderStageGenerator &FragmentGenerator() - { - return *m_ProgramGenerator.GetStage(ShaderGeneratorStages::Fragment); - } - SShaderDefaultMaterialKey &Key() { return *m_CurrentKey; } - const SDefaultMaterial &Material() { return *m_CurrentMaterial; } - TShaderFeatureSet FeatureSet() { return m_CurrentFeatureSet; } - bool HasTransparency() { return m_HasTransparency; } - - void addFunction(IShaderStageGenerator &generator, QString functionName) - { - generator.AddFunction(functionName); - } - - void SetupImageVariableNames(size_t imageIdx) - { - m_ImageStem = "image"; - char buf[16]; - _snprintf(buf, 16, "%d", int(imageIdx)); - m_ImageStem.append(buf); - m_ImageStem.append("_"); - - m_ImageSampler = m_ImageStem; - m_ImageSampler.append("sampler"); - m_ImageOffsets = m_ImageStem; - m_ImageOffsets.append("offsets"); - m_ImageRotations = m_ImageStem; - m_ImageRotations.append("rotations"); - m_ImageFragCoords = m_ImageStem; - m_ImageFragCoords.append("uv_coords"); - m_ImageSamplerSize = m_ImageStem; - m_ImageSamplerSize.append("size"); - } - - void SetupTexCoordVariableName(size_t uvSet) - { - m_TexCoordTemp = "varTexCoord"; - char buf[16]; - _snprintf(buf, 16, "%d", int(uvSet)); - m_TexCoordTemp.append(buf); - } - - SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override - { - SetupImageVariableNames(inIdx); - SImageVariableNames retval; - retval.m_ImageSampler = m_ImageSampler.c_str(); - retval.m_ImageFragCoords = m_ImageFragCoords.c_str(); - return retval; - } - - void AddLocalVariable(IShaderStageGenerator &inGenerator, const char8_t *inName, - const char8_t *inType) - { - inGenerator << "\t" << inType << " " << inName << ";" << Endl; - } - - void AddLocalVariable(IShaderStageGenerator &inGenerator, const TStrType &inName, - const char8_t *inType) - { - AddLocalVariable(inGenerator, inName.c_str(), inType); - } - - void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, QT3DSU32 uvSet, - SRenderableImage &image) override - { - IDefaultMaterialVertexPipeline &vertexShader( - static_cast(inVertexPipeline)); - IShaderStageGenerator &fragmentShader(FragmentGenerator()); - SetupImageVariableNames(idx); - SetupTexCoordVariableName(uvSet); - fragmentShader.AddUniform(m_ImageSampler, "sampler2D"); - vertexShader.AddUniform(m_ImageOffsets, "vec3"); - fragmentShader.AddUniform(m_ImageOffsets, "vec3"); - vertexShader.AddUniform(m_ImageRotations, "vec4"); - fragmentShader.AddUniform(m_ImageRotations, "vec4"); - - if (image.m_Image.m_MappingMode == ImageMappingModes::Normal) { - vertexShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " - << m_ImageRotations << ".y, " << m_ImageOffsets << ".x );" << Endl; - vertexShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " - << m_ImageRotations << ".w, " << m_ImageOffsets << ".y );" << Endl; - vertexShader.AddOutgoing(m_ImageFragCoords, "vec2"); - addFunction(vertexShader, "getTransformedUVCoords"); - vertexShader.GenerateUVCoords(uvSet); - m_ImageTemp = m_ImageFragCoords; - m_ImageTemp.append("temp"); - vertexShader << "\tvec2 " << m_ImageTemp << " = getTransformedUVCoords( vec3( " - << m_TexCoordTemp << ", 1.0), uTransform, vTransform );" << Endl; - if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - vertexShader << "\t" << m_ImageTemp << ".y = 1.0 - " << m_ImageFragCoords << ".y;" - << Endl; - - vertexShader.AssignOutput(m_ImageFragCoords.c_str(), m_ImageTemp.c_str()); - } else { - fragmentShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " - << m_ImageRotations << ".y, " << m_ImageOffsets << ".x );" << Endl; - fragmentShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " - << m_ImageRotations << ".w, " << m_ImageOffsets << ".y );" << Endl; - vertexShader.GenerateEnvMapReflection(); - addFunction(fragmentShader, "getTransformedUVCoords"); - fragmentShader << "\tvec2 " << m_ImageFragCoords - << " = getTransformedUVCoords( environment_map_reflection, uTransform, " - "vTransform );" - << Endl; - if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - fragmentShader << "\t" << m_ImageFragCoords << ".y = 1.0 - " << m_ImageFragCoords - << ".y;" << Endl; - } - } - - void GenerateImageUVCoordinates(QT3DSU32 idx, SRenderableImage &image, QT3DSU32 uvSet = 0) - { - GenerateImageUVCoordinates(VertexGenerator(), idx, uvSet, image); - } - - void GenerateImageUVCoordinates(QT3DSU32 idx, SRenderableImage &image, - IDefaultMaterialVertexPipeline &inShader) - { - if (image.m_Image.m_MappingMode == ImageMappingModes::Normal) { - SetupImageVariableNames(idx); - inShader.AddUniform(m_ImageSampler, "sampler2D"); - inShader.AddUniform(m_ImageOffsets, "vec3"); - inShader.AddUniform(m_ImageRotations, "vec4"); - - inShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " << m_ImageRotations - << ".y, " << m_ImageOffsets << ".x );" << Endl; - inShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " << m_ImageRotations - << ".w, " << m_ImageOffsets << ".y );" << Endl; - inShader << "\tvec2 " << m_ImageFragCoords << ";" << Endl; - addFunction(inShader, "getTransformedUVCoords"); - inShader.GenerateUVCoords(); - inShader - << "\t" << m_ImageFragCoords - << " = getTransformedUVCoords( vec3( varTexCoord0, 1.0), uTransform, vTransform );" - << Endl; - if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - inShader << "\t" << m_ImageFragCoords << ".y = 1.0 - " << m_ImageFragCoords << ".y;" - << Endl; - } - } - - void OutputSpecularEquation(DefaultMaterialSpecularModel::Enum inSpecularModel, - IShaderStageGenerator &fragmentShader, const char *inLightDir, - const char *inLightSpecColor) - { - switch (inSpecularModel) { - case DefaultMaterialSpecularModel::KGGX: { - fragmentShader.AddInclude("defaultMaterialPhysGlossyBSDF.glsllib"); - fragmentShader.AddUniform("material_specular", "vec4"); - fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " - "specularColor * kggxGlossyDefaultMtl( " - << "world_normal, tangent, -" << inLightDir << ".xyz, view_vector, " - << inLightSpecColor - << ".rgb, vec3(material_specular.xyz), roughnessAmount, " - "roughnessAmount ).rgb;" - << Endl; - } break; - case DefaultMaterialSpecularModel::KWard: { - fragmentShader.AddInclude("defaultMaterialPhysGlossyBSDF.glsllib"); - fragmentShader.AddUniform("material_specular", "vec4"); - fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " - "specularColor * wardGlossyDefaultMtl( " - << "world_normal, tangent, -" << inLightDir << ".xyz, view_vector, " - << inLightSpecColor - << ".rgb, vec3(material_specular.xyz), roughnessAmount, " - "roughnessAmount ).rgb;" - << Endl; - } break; - default: - addFunction(fragmentShader, "specularBSDF"); - fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " - "specularColor * specularBSDF( " - << "world_normal, -" << inLightDir << ".xyz, view_vector, " - << inLightSpecColor << ".rgb, 1.0, 2.56 / (roughnessAmount + " - "0.01), vec3(1.0), scatter_reflect ).rgb;" - << Endl; - break; - } - } - - void OutputDiffuseAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos, - TStrType inLightPrefix) - { - m_NormalizedDirection = inLightPrefix + "_areaDir"; - AddLocalVariable(infragmentShader, m_NormalizedDirection, "vec3"); - infragmentShader << "\tlightAttenuation = calculateDiffuseAreaOld( " << m_LightDirection - << ".xyz, " << m_LightPos << ".xyz, " << m_LightUp << ", " << m_LightRt - << ", " << inPos << ", " << m_NormalizedDirection << " );" << Endl; - } - - void OutputSpecularAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos, - const char *inView, const char *inLightSpecColor) - { - addFunction(infragmentShader, "sampleAreaGlossyDefault"); - infragmentShader.AddUniform("material_specular", "vec4"); - infragmentShader << "global_specular_light.rgb += " << inLightSpecColor - << ".rgb * lightAttenuation * shadowFac * material_specular.rgb * " - "specularAmount * sampleAreaGlossyDefault( tanFrame, " - << inPos << ", " << m_NormalizedDirection << ", " << m_LightPos << ".xyz, " - << m_LightRt << ".w, " << m_LightUp << ".w, " << inView - << ", roughnessAmount, roughnessAmount ).rgb;" << Endl; - } - - void AddTranslucencyIrradiance(IShaderStageGenerator &infragmentShader, SRenderableImage *image, - TStrType inLightPrefix, bool areaLight) - { - if (image == NULL) - return; - - addFunction(infragmentShader, "diffuseReflectionWrapBSDF"); - if (areaLight) { - infragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "translucent_thickness_exp * diffuseReflectionWrapBSDF( " - "-world_normal, " - << m_NormalizedDirection << ", " << m_LightColor - << ".rgb, diffuseLightWrap ).rgb;" << Endl; - } else { - infragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "translucent_thickness_exp * diffuseReflectionWrapBSDF( " - "-world_normal, " - << "-" << m_NormalizedDirection << ", " << m_LightColor - << ".rgb, diffuseLightWrap ).rgb;" << Endl; - } - } - - void SetupShadowMapVariableNames(size_t lightIdx) - { - m_ShadowMapStem = "shadowmap"; - m_ShadowCubeStem = "shadowcube"; - char buf[16]; - _snprintf(buf, 16, "%d", int(lightIdx)); - m_ShadowMapStem.append(buf); - m_ShadowCubeStem.append(buf); - m_ShadowMatrixStem = m_ShadowMapStem; - m_ShadowMatrixStem.append("_matrix"); - m_ShadowCoordStem = m_ShadowMapStem; - m_ShadowCoordStem.append("_coord"); - m_ShadowControlStem = m_ShadowMapStem; - m_ShadowControlStem.append("_control"); - } - - void AddShadowMapContribution(IShaderStageGenerator &inLightShader, QT3DSU32 lightIndex, - RenderLightTypes::Enum inType) - { - SetupShadowMapVariableNames(lightIndex); - - inLightShader.AddInclude("shadowMapping.glsllib"); - if (inType == RenderLightTypes::Directional) { - inLightShader.AddUniform(m_ShadowMapStem, "sampler2D"); - } else { - inLightShader.AddUniform(m_ShadowCubeStem, "samplerCube"); - } - inLightShader.AddUniform(m_ShadowControlStem, "vec4"); - inLightShader.AddUniform(m_ShadowMatrixStem, "mat4"); - - /* - if ( inType == RenderLightTypes::Area ) - { - inLightShader << "vec2 " << m_ShadowCoordStem << ";" << Endl; - inLightShader << "\tshadow_map_occl = sampleParaboloid( " << m_ShadowMapStem << ", " - << m_ShadowControlStem << ", " - << - m_ShadowMatrixStem << ", varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z), " - << m_ShadowCoordStem - << " );" << Endl; - } - else */ - if (inType != RenderLightTypes::Directional) { - inLightShader << "\tshadow_map_occl = sampleCubemap( " << m_ShadowCubeStem << ", " - << m_ShadowControlStem << ", " << m_ShadowMatrixStem << ", " << m_LightPos - << ".xyz, varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z) );" - << Endl; - } else - inLightShader << "\tshadow_map_occl = sampleOrthographic( " << m_ShadowMapStem << ", " - << m_ShadowControlStem << ", " << m_ShadowMatrixStem - << ", varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z) );" << Endl; - } - - void AddDisplacementMappingForDepthPass(IShaderStageGenerator &inShader) override - { - inShader.AddIncoming("attr_uv0", "vec2"); - inShader.AddIncoming("attr_norm", "vec3"); - inShader.AddUniform("displacementSampler", "sampler2D"); - inShader.AddUniform("displaceAmount", "float"); - inShader.AddUniform("displacementMap_rot", "vec4"); - inShader.AddUniform("displacementMap_offset", "vec3"); - inShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - - inShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, displacementMap_rot.y, " - "displacementMap_offset.x );"); - inShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, displacementMap_rot.w, " - "displacementMap_offset.y );"); - addFunction(inShader, "getTransformedUVCoords"); - inShader.Append("\tvec2 uv_coords = attr_uv0;"); - inShader << "\tuv_coords = getTransformedUVCoords( vec3( uv_coords, 1.0), uTransform, " - "vTransform );\n"; - inShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - "displacementSampler , displaceAmount, uv_coords , attr_norm, attr_pos );" - << Endl; - inShader.Append("\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - } - - void AddDisplacementImageUniforms(IShaderStageGenerator &inGenerator, - QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override - { - if (displacementImage) { - SetupImageVariableNames(displacementImageIdx); - inGenerator.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - inGenerator.AddUniform("model_matrix", "mat4"); - inGenerator.AddUniform("camera_position", "vec3"); - inGenerator.AddUniform("displaceAmount", "float"); - inGenerator.AddUniform(m_ImageSampler, "sampler2D"); - } - } - - bool MaybeAddMaterialFresnel(IShaderStageGenerator &fragmentShader, NVConstDataRef inKey, - bool inFragmentHasSpecularAmount) - { - if (m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey)) { - if (inFragmentHasSpecularAmount == false) - fragmentShader << "\tfloat specularAmount = 1.0;" << Endl; - inFragmentHasSpecularAmount = true; - fragmentShader.AddInclude("defaultMaterialFresnel.glsllib"); - fragmentShader.AddUniform("fresnelPower", "float"); - fragmentShader.AddUniform("material_specular", "vec4"); - fragmentShader << "\tfloat fresnelRatio = defaultMaterialSimpleFresnel( world_normal, " - "view_vector, material_specular.w, fresnelPower );" - << Endl; - fragmentShader << "\tspecularAmount *= fresnelRatio;" << Endl; - } - return inFragmentHasSpecularAmount; - } - void SetupLightVariableNames(size_t lightIdx, SLight &inLight) - { - if (m_LightsAsSeparateUniforms) { - char buf[16]; - _snprintf(buf, 16, "light_%d", int(lightIdx)); - m_LightStem = buf; - m_LightColor = m_LightStem; - m_LightColor.append("_diffuse"); - m_LightDirection = m_LightStem; - m_LightDirection.append("_direction"); - m_LightSpecularColor = m_LightStem; - m_LightSpecularColor.append("_specular"); - if (inLight.m_LightType == RenderLightTypes::Point) { - m_LightPos = m_LightStem; - m_LightPos.append("_position"); - m_LightAttenuation = m_LightStem; - m_LightAttenuation.append("_attenuation"); - } else if (inLight.m_LightType == RenderLightTypes::Area) { - m_LightPos = m_LightStem; - m_LightPos.append("_position"); - m_LightUp = m_LightStem; - m_LightUp.append("_up"); - m_LightRt = m_LightStem; - m_LightRt.append("_right"); - } - } else { - m_LightStem = "lights"; - char buf[16]; - _snprintf(buf, 16, "[%d].", int(lightIdx)); - m_LightStem.append(buf); - - m_LightColor = m_LightStem; - m_LightColor.append("diffuse"); - m_LightDirection = m_LightStem; - m_LightDirection.append("direction"); - m_LightSpecularColor = m_LightStem; - m_LightSpecularColor.append("specular"); - if (inLight.m_LightType == RenderLightTypes::Point) { - m_LightPos = m_LightStem; - m_LightPos.append("position"); - m_LightConstantAttenuation = m_LightStem; - m_LightConstantAttenuation.append("constantAttenuation"); - m_LightLinearAttenuation = m_LightStem; - m_LightLinearAttenuation.append("linearAttenuation"); - m_LightQuadraticAttenuation = m_LightStem; - m_LightQuadraticAttenuation.append("quadraticAttenuation"); - } else if (inLight.m_LightType == RenderLightTypes::Area) { - m_LightPos = m_LightStem; - m_LightPos.append("position"); - m_LightUp = m_LightStem; - m_LightUp.append("up"); - m_LightRt = m_LightStem; - m_LightRt.append("right"); - } - } - } - - void addDisplacementMapping(IDefaultMaterialVertexPipeline &inShader) - { - inShader.AddIncoming("attr_uv0", "vec2"); - inShader.AddIncoming("attr_norm", "vec3"); - inShader.AddUniform("displacementSampler", "sampler2D"); - inShader.AddUniform("displaceAmount", "float"); - inShader.AddUniform("displacementMap_rot", "vec4"); - inShader.AddUniform("displacementMap_offset", "vec3"); - inShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - - inShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, displacementMap_rot.y, " - "displacementMap_offset.x );"); - inShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, displacementMap_rot.w, " - "displacementMap_offset.y );"); - addFunction(inShader, "getTransformedUVCoords"); - inShader.GenerateUVCoords(); - inShader << "\tvarTexCoord0 = getTransformedUVCoords( vec3( varTexCoord0, 1.0), " - "uTransform, vTransform );\n"; - inShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - "displacementSampler , displaceAmount, varTexCoord0 , attr_norm, attr_pos );" - << Endl; - inShader.Append("\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - } - - void GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, - eastl::basic_string &texSwizzle, - eastl::basic_string &lookupSwizzle) - { - qt3ds::render::NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - - if (!(m_RenderContext.GetRenderContext().GetRenderContextType() & deprecatedContextFlags)) { - switch (swizzleMode) { - case NVRenderTextureSwizzleMode::L8toR8: - case NVRenderTextureSwizzleMode::L16toR16: - texSwizzle.append(".rgb"); - lookupSwizzle.append(".rrr"); - break; - case NVRenderTextureSwizzleMode::L8A8toRG8: - texSwizzle.append(".rgba"); - lookupSwizzle.append(".rrrg"); - break; - case NVRenderTextureSwizzleMode::A8toR8: - texSwizzle.append(".a"); - lookupSwizzle.append(".r"); - break; - default: - break; - } - } - } - - ///< get the light constant buffer and generate if necessary - NVRenderConstantBuffer *GetLightConstantBuffer(QT3DSU32 inLightCount) - { - NVRenderContext &theContext(m_RenderContext.GetRenderContext()); - - // we assume constant buffer support - QT3DS_ASSERT(theContext.GetConstantBufferSupport()); - - // we only create if if we have lights - if (!inLightCount || !theContext.GetConstantBufferSupport()) - return NULL; - - CRegisteredString theName = theContext.GetStringTable().RegisterStr("cbBufferLights"); - NVRenderConstantBuffer *pCB = theContext.GetConstantBuffer(theName); - - if (!pCB) { - // create - SLightSourceShader s[QT3DS_MAX_NUM_LIGHTS]; - NVDataRef cBuffer((QT3DSU8 *)&s, (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) - + (4 * sizeof(QT3DSI32))); - pCB = theContext.CreateConstantBuffer( - theName, qt3ds::render::NVRenderBufferUsageType::Static, - (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + (4 * sizeof(QT3DSI32)), cBuffer); - if (!pCB) { - QT3DS_ASSERT(false); - return NULL; - } - // init first set - memset(&s[0], 0x0, sizeof(SLightSourceShader)); - QT3DSI32 cgLights = 0; - pCB->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); - pCB->UpdateRaw(4 * sizeof(QT3DSI32), - NVDataRef((QT3DSU8 *)&s[0], sizeof(SLightSourceShader))); - pCB->Update(); // update to hardware - - m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); - } - - return pCB; - } - - void SetImageShaderVariables(SShaderGeneratorGeneratedShader &inShader, - SRenderableImage &inImage, QT3DSU32 idx) - { - size_t numImageVariables = inShader.m_Images.size(); - for (size_t namesIdx = numImageVariables; namesIdx <= idx; ++namesIdx) { - SetupImageVariableNames(idx); - inShader.m_Images.push_back( - SShaderTextureProperties(m_ImageSampler.c_str(), m_ImageOffsets.c_str(), - m_ImageRotations.c_str(), m_ImageSamplerSize.c_str(), - inShader.m_Shader)); - } - SShaderTextureProperties &theShaderProps = inShader.m_Images[idx]; - const QT3DSMat44 &textureTransform = inImage.m_Image.m_TextureTransform; - // We separate rotational information from offset information so that just maybe the shader - // will attempt to push less information to the card. - const QT3DSF32 *dataPtr(textureTransform.front()); - // The third member of the offsets contains a flag indicating if the texture was - // premultiplied or not. - // We use this to mix the texture alpha. - QT3DSVec3 offsets(dataPtr[12], dataPtr[13], - inImage.m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f - : 0.0f); - // Grab just the upper 2x2 rotation matrix from the larger matrix. - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - - // The image horizontal and vertical tiling modes need to be set here, before we set texture - // on the shader. - // because setting the image on the texture forces the textue to bind and immediately apply - // any tex params. - NVRenderTexture2D *imageTexture = inImage.m_Image.m_TextureData.m_Texture; - inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapS( - inImage.m_Image.m_HorizontalTilingMode); - inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapT( - inImage.m_Image.m_VerticalTilingMode); - theShaderProps.m_Sampler.Set(imageTexture); - theShaderProps.m_Offsets.Set(offsets); - theShaderProps.m_Rotations.Set(rotations); - theShaderProps.m_Size.Set(QT3DSVec2(imageTexture->GetTextureDetails().m_Width, - imageTexture->GetTextureDetails().m_Height)); - } - - void GenerateShadowMapOcclusion(QT3DSU32 lightIdx, bool inShadowEnabled, - RenderLightTypes::Enum inType) - { - if (inShadowEnabled) { - VertexGenerator().GenerateWorldPosition(); - AddShadowMapContribution(FragmentGenerator(), lightIdx, inType); - /* - VertexGenerator().AddUniform( m_ShadowMatrixStem, "mat4" ); - VertexGenerator().AddOutgoing( m_ShadowCoordStem, "vec4" ); - VertexGenerator() << "\tvec4 local_" << m_ShadowCoordStem << " = " << m_ShadowMatrixStem - << " * vec4(local_model_world_position, 1.0);" << Endl; - m_TempStr.assign( "local_" ); - m_TempStr.append( m_ShadowCoordStem ); - VertexGenerator().AssignOutput( m_ShadowCoordStem.c_str(), m_TempStr.c_str() ); - */ - } else { - FragmentGenerator() << "\tshadow_map_occl = 1.0;" << Endl; - } - } - - void GenerateVertexShader() - { - // vertex displacement - QT3DSU32 imageIdx = 0; - SRenderableImage *displacementImage = NULL; - QT3DSU32 displacementImageIdx = 0; - - for (SRenderableImage *img = m_FirstImage; img != NULL; - img = img->m_NextImage, ++imageIdx) { - if (img->m_MapType == ImageMapTypes::Displacement) { - displacementImage = img; - displacementImageIdx = imageIdx; - break; - } - } - - // the pipeline opens/closes up the shaders stages - VertexGenerator().BeginVertexGeneration(displacementImageIdx, displacementImage); - } - - void GenerateFragmentShader(SShaderDefaultMaterialKey &inKey) - { - bool specularEnabled = Material().IsSpecularEnabled(); - bool vertexColorsEnabled = Material().IsVertexColorsEnabled(); - - bool hasLighting = Material().HasLighting(); - bool hasImage = m_FirstImage != NULL; - - bool hasIblProbe = m_DefaultMaterialShaderKeyProperties.m_HasIbl.GetValue(inKey); - bool hasSpecMap = false; - bool hasEnvMap = false; - bool hasEmissiveMap = false; - bool hasLightmaps = false; - // Pull the bump out as - SRenderableImage *bumpImage = NULL; - QT3DSU32 imageIdx = 0; - QT3DSU32 bumpImageIdx = 0; - SRenderableImage *specularAmountImage = NULL; - QT3DSU32 specularAmountImageIdx = 0; - SRenderableImage *roughnessImage = NULL; - QT3DSU32 roughnessImageIdx = 0; - // normal mapping - SRenderableImage *normalImage = NULL; - QT3DSU32 normalImageIdx = 0; - // translucency map - SRenderableImage *translucencyImage = NULL; - QT3DSU32 translucencyImageIdx = 0; - // lightmaps - SRenderableImage *lightmapIndirectImage = NULL; - QT3DSU32 lightmapIndirectImageIdx = 0; - SRenderableImage *lightmapRadiosityImage = NULL; - QT3DSU32 lightmapRadiosityImageIdx = 0; - SRenderableImage *lightmapShadowImage = NULL; - QT3DSU32 lightmapShadowImageIdx = 0; - const bool supportStandardDerivatives - = m_RenderContext.GetRenderContext().IsStandardDerivativesSupported(); - - for (SRenderableImage *img = m_FirstImage; img != NULL; - img = img->m_NextImage, ++imageIdx) { - hasSpecMap = img->m_MapType == ImageMapTypes::Specular; - if (img->m_MapType == ImageMapTypes::Bump) { - bumpImage = img; - bumpImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::SpecularAmountMap) { - specularAmountImage = img; - specularAmountImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::Roughness) { - roughnessImage = img; - roughnessImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::Normal) { - normalImage = img; - normalImageIdx = imageIdx; - } else if (img->m_Image.m_MappingMode == ImageMappingModes::Environment) { - hasEnvMap = true; - } else if (img->m_MapType == ImageMapTypes::Translucency) { - translucencyImage = img; - translucencyImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::Emissive) { - hasEmissiveMap = true; - } else if (img->m_MapType == ImageMapTypes::LightmapIndirect) { - lightmapIndirectImage = img; - lightmapIndirectImageIdx = imageIdx; - hasLightmaps = true; - } else if (img->m_MapType == ImageMapTypes::LightmapRadiosity) { - lightmapRadiosityImage = img; - lightmapRadiosityImageIdx = imageIdx; - hasLightmaps = true; - } else if (img->m_MapType == ImageMapTypes::LightmapShadow) { - lightmapShadowImage = img; - lightmapShadowImageIdx = imageIdx; - hasLightmaps = true; - } - } - - bool enableFresnel = m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey); - bool enableSSAO = false; - bool enableSSDO = false; - bool enableShadowMaps = false; - bool enableBumpNormal = normalImage || bumpImage; - - for (QT3DSU32 idx = 0; idx < FeatureSet().size(); ++idx) { - eastl::string name(FeatureSet()[idx].m_Name.c_str()); - if (name == "QT3DS_ENABLE_SSAO") - enableSSAO = FeatureSet()[idx].m_Enabled; - else if (name == "QT3DS_ENABLE_SSDO") - enableSSDO = FeatureSet()[idx].m_Enabled; - else if (name == "QT3DS_ENABLE_SSM") - enableShadowMaps = FeatureSet()[idx].m_Enabled; - } - - bool includeSSAOSSDOVars = enableSSAO || enableSSDO || enableShadowMaps; - - VertexGenerator().BeginFragmentGeneration(); - IShaderStageGenerator &fragmentShader(FragmentGenerator()); - IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); - - // The fragment or vertex shaders may not use the material_properties or diffuse - // uniforms in all cases but it is simpler to just add them and let the linker strip them. - fragmentShader.AddUniform("material_diffuse", "vec4"); - fragmentShader.AddUniform("diffuse_color", "vec3"); - fragmentShader.AddUniform("material_properties", "vec4"); - - // All these are needed for SSAO - if (includeSSAOSSDOVars) { - fragmentShader.AddInclude("SSAOCustomMaterial.glsllib"); - // fragmentShader.AddUniform( "ao_sampler", "sampler2D" ); - } - - if (hasIblProbe && hasLighting) { - fragmentShader.AddInclude("sampleProbe.glsllib"); - } - - if (hasLighting) { - if (!m_LightsAsSeparateUniforms) - addFunction(fragmentShader, "sampleLightVars"); - addFunction(fragmentShader, "diffuseReflectionBSDF"); - } - - if (hasLighting && hasLightmaps) { - fragmentShader.AddInclude("evalLightmaps.glsllib"); - } - - // view_vector, varWorldPos, world_normal are all used if there is a specular map - // in addition to if there is specular lighting. So they are lifted up here, always - // generated. - // we rely on the linker to strip out what isn't necessary instead of explicitly stripping - // it for code simplicity. - if (hasImage) { - fragmentShader.Append("\tvec3 uTransform;"); - fragmentShader.Append("\tvec3 vTransform;"); - } - - if (includeSSAOSSDOVars || hasSpecMap || hasLighting || hasEnvMap || enableFresnel - || hasIblProbe || enableBumpNormal) { - vertexShader.GenerateViewVector(); - vertexShader.GenerateWorldNormal(); - vertexShader.GenerateWorldPosition(); - } - if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal) - vertexShader.GenerateVarTangentAndBinormal(); - - if (vertexColorsEnabled) - vertexShader.GenerateVertexColor(); - else - fragmentShader.Append("\tvec3 vertColor = vec3(1.0);"); - - // You do bump or normal mapping but not both - if (bumpImage != NULL) { - GenerateImageUVCoordinates(bumpImageIdx, *bumpImage); - fragmentShader.AddUniform("bumpAmount", "float"); - - fragmentShader.AddUniform(m_ImageSamplerSize, "vec2"); - fragmentShader.AddInclude("defaultMaterialBumpNoLod.glsllib"); - fragmentShader << "\tworld_normal = defaultMaterialBumpNoLod( " << m_ImageSampler - << ", bumpAmount, " << m_ImageFragCoords - << ", tangent, binormal, world_normal, " - << m_ImageSamplerSize << ");" << Endl; - // Do gram schmidt - fragmentShader << "\tbinormal = normalize(cross(world_normal, tangent) );\n"; - fragmentShader << "\ttangent = normalize(cross(binormal, world_normal) );\n"; - - } else if (normalImage != NULL) { - GenerateImageUVCoordinates(normalImageIdx, *normalImage); - - fragmentShader.AddInclude("defaultMaterialFileNormalTexture.glsllib"); - fragmentShader.AddUniform("bumpAmount", "float"); - - fragmentShader << "\tworld_normal = defaultMaterialFileNormalTexture( " - << m_ImageSampler << ", bumpAmount, " << m_ImageFragCoords - << ", tangent, binormal );" << Endl; - } - - if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal) - fragmentShader << "\tmat3 tanFrame = mat3(tangent, binormal, world_normal);" << Endl; - - bool fragmentHasSpecularAmount = false; - - if (hasEmissiveMap) { - fragmentShader.Append("\tvec3 global_emission = material_diffuse.rgb;"); - } - - if (hasLighting) { - fragmentShader.AddUniform("light_ambient_total", "vec3"); - - fragmentShader.Append( - "\tvec4 global_diffuse_light = vec4(light_ambient_total.xyz, 1.0);"); - fragmentShader.Append("\tvec3 global_specular_light = vec3(0.0, 0.0, 0.0);"); - fragmentShader.Append("\tfloat shadow_map_occl = 1.0;"); - - if (specularEnabled) { - vertexShader.GenerateViewVector(); - fragmentShader.AddUniform("material_properties", "vec4"); - } - - if (lightmapIndirectImage != NULL) { - GenerateImageUVCoordinates(lightmapIndirectImageIdx, *lightmapIndirectImage, 1); - fragmentShader << "\tvec4 indirect_light = texture2D( " << m_ImageSampler << ", " - << m_ImageFragCoords << ");" << Endl; - fragmentShader << "\tglobal_diffuse_light += indirect_light;" << Endl; - if (specularEnabled) { - fragmentShader - << "\tglobal_specular_light += indirect_light.rgb * material_properties.x;" - << Endl; - } - } - - if (lightmapRadiosityImage != NULL) { - GenerateImageUVCoordinates(lightmapRadiosityImageIdx, *lightmapRadiosityImage, 1); - fragmentShader << "\tvec4 direct_light = texture2D( " << m_ImageSampler << ", " - << m_ImageFragCoords << ");" << Endl; - fragmentShader << "\tglobal_diffuse_light += direct_light;" << Endl; - if (specularEnabled) { - fragmentShader - << "\tglobal_specular_light += direct_light.rgb * material_properties.x;" - << Endl; - } - } - - if (translucencyImage != NULL) { - fragmentShader.AddUniform("translucentFalloff", "float"); - fragmentShader.AddUniform("diffuseLightWrap", "float"); - - GenerateImageUVCoordinates(translucencyImageIdx, *translucencyImage); - - fragmentShader << "\tvec4 translucent_depth_range = texture2D( " << m_ImageSampler - << ", " << m_ImageFragCoords << ");" << Endl; - fragmentShader << "\tfloat translucent_thickness = translucent_depth_range.r * " - "translucent_depth_range.r;" - << Endl; - fragmentShader << "\tfloat translucent_thickness_exp = exp( translucent_thickness " - "* translucentFalloff);" - << Endl; - } - - fragmentShader.Append("\tfloat lightAttenuation = 1.0;"); - - AddLocalVariable(fragmentShader, "aoFactor", "float"); - - if (hasLighting && enableSSAO) - fragmentShader.Append("\taoFactor = customMaterialAO();"); - else - fragmentShader.Append("\taoFactor = 1.0;"); - - AddLocalVariable(fragmentShader, "shadowFac", "float"); - - if (specularEnabled) { - fragmentShader << "\tfloat specularAmount = material_properties.x;" << Endl; - fragmentHasSpecularAmount = true; - } - // Fragment lighting means we can perhaps attenuate the specular amount by a texture - // lookup. - - fragmentShader << "\tvec3 specularColor = vec3(1.0);" << Endl; - if (specularAmountImage) { - if (!specularEnabled) - fragmentShader << "\tfloat specularAmount = 1.0;" << Endl; - GenerateImageUVCoordinates(specularAmountImageIdx, *specularAmountImage); - fragmentShader << "\tspecularColor = texture2D( " - << m_ImageSampler << ", " << m_ImageFragCoords << " ).xyz;" << Endl; - fragmentHasSpecularAmount = true; - } - - fragmentShader << "\tfloat roughnessAmount = material_properties.y;" << Endl; - if (roughnessImage) { - GenerateImageUVCoordinates(roughnessImageIdx, *roughnessImage); - fragmentShader << "\tfloat sampledRoughness = texture2D( " - << m_ImageSampler << ", " << m_ImageFragCoords << " ).x;" << Endl; - //The roughness sampled from roughness textures is Disney roughness - //which has to be squared to get the proper value - fragmentShader << "\troughnessAmount = roughnessAmount * " - << "sampledRoughness * sampledRoughness;" << Endl; - } - - fragmentHasSpecularAmount = - MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount); - - // Iterate through all lights - for (QT3DSU32 lightIdx = 0; lightIdx < m_Lights.size(); ++lightIdx) { - SLight *lightNode = m_Lights[lightIdx]; - SetupLightVariableNames(lightIdx, *lightNode); - bool isDirectional = lightNode->m_LightType == RenderLightTypes::Directional; - bool isArea = lightNode->m_LightType == RenderLightTypes::Area; - bool isShadow = enableShadowMaps && lightNode->m_CastShadow; - - fragmentShader.Append(""); - char buf[10]; - sprintf(buf, "%d", lightIdx); - - m_TempStr.assign("light"); - m_TempStr.append(buf); - - fragmentShader << "\t//Light " << buf << Endl; - fragmentShader << "\tlightAttenuation = 1.0;" << Endl; - if (isDirectional) { - - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightDirection, "vec4"); - fragmentShader.AddUniform(m_LightColor, "vec4"); - } - - if (enableSSDO) { - fragmentShader << "\tshadowFac = customMaterialShadow( " << m_LightDirection - << ".xyz, varWorldPos );" << Endl; - } else { - fragmentShader << "\tshadowFac = 1.0;" << Endl; - } - - GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, - lightNode->m_LightType); - - if (specularEnabled && enableShadowMaps && isShadow) - fragmentShader << "\tlightAttenuation *= shadow_map_occl;" << Endl; - - fragmentShader << "\tglobal_diffuse_light.rgb += shadowFac * shadow_map_occl * " - "diffuseReflectionBSDF( world_normal, " - << "-" << m_LightDirection << ".xyz, view_vector, " - << m_LightColor << ".rgb, 0.0 ).rgb;" << Endl; - - if (specularEnabled) { - if (m_LightsAsSeparateUniforms) - fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); - OutputSpecularEquation(Material().m_SpecularModel, fragmentShader, - m_LightDirection.c_str(), - m_LightSpecularColor.c_str()); - } - } else if (isArea) { - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightColor, "vec4"); - fragmentShader.AddUniform(m_LightPos, "vec4"); - fragmentShader.AddUniform(m_LightDirection, "vec4"); - fragmentShader.AddUniform(m_LightUp, "vec4"); - fragmentShader.AddUniform(m_LightRt, "vec4"); - } else { - addFunction(fragmentShader, "areaLightVars"); - } - addFunction(fragmentShader, "calculateDiffuseAreaOld"); - vertexShader.GenerateWorldPosition(); - GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, - lightNode->m_LightType); - - // Debug measure to make sure paraboloid sampling was projecting to the right - // location - // fragmentShader << "\tglobal_diffuse_light.rg += " << m_ShadowCoordStem << ";" - // << Endl; - m_NormalizedDirection = m_TempStr; - m_NormalizedDirection.append("_Frame"); - - AddLocalVariable(fragmentShader, m_NormalizedDirection, "mat3"); - fragmentShader << m_NormalizedDirection << " = mat3( " << m_LightRt << ".xyz, " - << m_LightUp << ".xyz, -" << m_LightDirection << ".xyz );" - << Endl; - - if (enableSSDO) { - fragmentShader << "\tshadowFac = shadow_map_occl * customMaterialShadow( " - << m_LightDirection << ".xyz, varWorldPos );" << Endl; - } else { - fragmentShader << "\tshadowFac = shadow_map_occl;" << Endl; - } - - if (specularEnabled) { - vertexShader.GenerateViewVector(); - if (m_LightsAsSeparateUniforms) - fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); - OutputSpecularAreaLighting(fragmentShader, "varWorldPos", "view_vector", - m_LightSpecularColor.c_str()); - } - - OutputDiffuseAreaLighting(fragmentShader, "varWorldPos", m_TempStr); - fragmentShader << "\tlightAttenuation *= shadowFac;" << Endl; - - AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, true); - - fragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "diffuseReflectionBSDF( world_normal, " - << m_NormalizedDirection << ", view_vector, " << m_LightColor - << ".rgb, 0.0 ).rgb;" << Endl; - } else { - - vertexShader.GenerateWorldPosition(); - GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, - lightNode->m_LightType); - - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightColor, "vec4"); - fragmentShader.AddUniform(m_LightPos, "vec4"); - } - - m_RelativeDirection = m_TempStr; - m_RelativeDirection.append("_relativeDirection"); - - m_NormalizedDirection = m_RelativeDirection; - m_NormalizedDirection.append("_normalized"); - - m_RelativeDistance = m_TempStr; - m_RelativeDistance.append("_distance"); - - fragmentShader << "\tvec3 " << m_RelativeDirection << " = varWorldPos - " - << m_LightPos << ".xyz;" << Endl; - fragmentShader << "\tfloat " << m_RelativeDistance << " = length( " - << m_RelativeDirection << " );" << Endl; - fragmentShader << "\tvec3 " << m_NormalizedDirection << " = " - << m_RelativeDirection << " / " << m_RelativeDistance << ";" - << Endl; - - if (enableSSDO) { - fragmentShader << "\tshadowFac = shadow_map_occl * customMaterialShadow( " - << m_NormalizedDirection << ", varWorldPos );" << Endl; - } else { - fragmentShader << "\tshadowFac = shadow_map_occl;" << Endl; - } - - addFunction(fragmentShader, "calculatePointLightAttenuation"); - - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightAttenuation, "vec3"); - fragmentShader - << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation(" - << "vec3( " << m_LightAttenuation << ".x, " << m_LightAttenuation - << ".y, " << m_LightAttenuation << ".z), " << m_RelativeDistance - << ");" << Endl; - } else { - fragmentShader - << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation(" - << "vec3( " << m_LightConstantAttenuation << ", " - << m_LightLinearAttenuation << ", " << m_LightQuadraticAttenuation - << "), " << m_RelativeDistance << ");" - << Endl; - } - - - - AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, false); - - fragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "diffuseReflectionBSDF( world_normal, " - << "-" << m_NormalizedDirection << ", view_vector, " - << m_LightColor << ".rgb, 0.0 ).rgb;" << Endl; - - if (specularEnabled) { - if (m_LightsAsSeparateUniforms) - fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); - OutputSpecularEquation(Material().m_SpecularModel, fragmentShader, - m_NormalizedDirection.c_str(), - m_LightSpecularColor.c_str()); - } - } - } - - // This may be confusing but the light colors are already modulated by the base - // material color. - // Thus material color is the base material color * material emissive. - // Except material_color.a *is* the actual opacity factor. - // Furthermore object_opacity is something that may come from the vertex pipeline or - // somewhere else. - // We leave it up to the vertex pipeline to figure it out. - fragmentShader << "\tglobal_diffuse_light = vec4(global_diffuse_light.xyz * aoFactor, " - "object_opacity);" - << Endl << "\tglobal_specular_light = vec3(global_specular_light.xyz);" - << Endl; - } else // no lighting. - { - fragmentShader << "\tvec4 global_diffuse_light = vec4(0.0, 0.0, 0.0, object_opacity);" - << Endl << "\tvec3 global_specular_light = vec3(0.0, 0.0, 0.0);" << Endl; - - // We still have specular maps and such that could potentially use the fresnel variable. - fragmentHasSpecularAmount = - MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount); - } - - if (!hasEmissiveMap) - fragmentShader - << "\tglobal_diffuse_light.rgb += diffuse_color.rgb * material_diffuse.rgb;" - << Endl; - - // since we already modulate our material diffuse color - // into the light color we will miss it entirely if no IBL - // or light is used - if (hasLightmaps && !(m_Lights.size() || hasIblProbe)) - fragmentShader << "\tglobal_diffuse_light.rgb *= diffuse_color.rgb;" << Endl; - - if (hasLighting && hasIblProbe) { - vertexShader.GenerateWorldNormal(); - - fragmentShader << "\tglobal_diffuse_light.rgb += diffuse_color.rgb * aoFactor * " - "sampleDiffuse( tanFrame ).xyz;" - << Endl; - - if (specularEnabled) { - - fragmentShader.AddUniform("material_specular", "vec4"); - - fragmentShader << "\tglobal_specular_light.xyz += specularAmount * specularColor * " - "vec3(material_specular.xyz) * sampleGlossy( tanFrame, " - "view_vector, roughnessAmount ).xyz;" - << Endl; - } - } - - if (hasImage) { - fragmentShader.Append("\tvec4 texture_color;"); - QT3DSU32 idx = 0; - for (SRenderableImage *image = m_FirstImage; image; image = image->m_NextImage, ++idx) { - // Various maps are handled on a different locations - if (image->m_MapType == ImageMapTypes::Bump - || image->m_MapType == ImageMapTypes::Normal - || image->m_MapType == ImageMapTypes::Displacement - || image->m_MapType == ImageMapTypes::SpecularAmountMap - || image->m_MapType == ImageMapTypes::Roughness - || image->m_MapType == ImageMapTypes::Translucency - || image->m_MapType == ImageMapTypes::LightmapIndirect - || image->m_MapType == ImageMapTypes::LightmapRadiosity) { - continue; - } - - eastl::basic_string texSwizzle, lookupSwizzle, texLodStr; - - GenerateImageUVCoordinates(idx, *image, 0); - - GenerateTextureSwizzle( - image->m_Image.m_TextureData.m_Texture->GetTextureSwizzleMode(), texSwizzle, - lookupSwizzle); - - if (texLodStr.empty()) { - fragmentShader << "\ttexture_color" << texSwizzle.c_str() << " = texture2D( " - << m_ImageSampler << ", " << m_ImageFragCoords << ")" - << lookupSwizzle.c_str() << ";" << Endl; - } else { - fragmentShader << "\ttexture_color" << texSwizzle.c_str() << "= textureLod( " - << m_ImageSampler << ", " << m_ImageFragCoords << ", " - << texLodStr.c_str() << " )" << lookupSwizzle.c_str() << ";" - << Endl; - } - - if (image->m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() == true) - fragmentShader << "\ttexture_color.rgb = texture_color.a > 0.0 ? " - "texture_color.rgb / texture_color.a : vec3( 0, 0, 0 );" - << Endl; - - // These mapping types honestly don't make a whole ton of sense to me. - switch (image->m_MapType) { - case ImageMapTypes::Diffuse: // assume images are premultiplied. - case ImageMapTypes::LightmapShadow: - // We use image offsets.z to switch between incoming premultiplied textures or - // not premultiplied textures. - // If Z is 1, then we assume the incoming texture is already premultiplied, else - // we just read the rgb value. - fragmentShader.Append("\tglobal_diffuse_light *= texture_color;"); - break; - case ImageMapTypes::Specular: - - fragmentShader.AddUniform("material_specular", "vec4"); - if (fragmentHasSpecularAmount) { - fragmentShader.Append("\tglobal_specular_light.xyz += specularAmount * " - "specularColor * texture_color.xyz * " - "material_specular.xyz;"); - } else { - fragmentShader.Append("\tglobal_specular_light.xyz += texture_color.xyz * " - "material_specular.xyz;"); - } - fragmentShader.Append("\tglobal_diffuse_light.a *= texture_color.a;"); - break; - case ImageMapTypes::Opacity: - fragmentShader.Append("\tglobal_diffuse_light.a *= texture_color.a;"); - break; - case ImageMapTypes::Emissive: - fragmentShader.Append( - "\tglobal_emission *= texture_color.xyz * texture_color.a;"); - break; - default: - QT3DS_ASSERT(false); // fallthrough intentional - } - } - } - - if (hasEmissiveMap) { - fragmentShader.Append("\tglobal_diffuse_light.rgb += global_emission.rgb;"); - } - - // Ensure the rgb colors are in range. - fragmentShader.Append("\tfragOutput = vec4( clamp( vertColor * global_diffuse_light.xyz + " - "global_specular_light.xyz, 0.0, 65519.0 ), global_diffuse_light.a " - ");"); - - if (VertexGenerator().HasActiveWireframe()) { - fragmentShader.Append("vec3 edgeDistance = varEdgeDistance * gl_FragCoord.w;"); - fragmentShader.Append( - "\tfloat d = min(min(edgeDistance.x, edgeDistance.y), edgeDistance.z);"); - fragmentShader.Append("\tfloat mixVal = smoothstep(0.0, 1.0, d);"); // line width 1.0 - - fragmentShader.Append( - "\tfragOutput = mix( vec4(0.0, 1.0, 0.0, 1.0), fragOutput, mixVal);"); - } - } - - NVRenderShaderProgram *GenerateMaterialShader(const char8_t *inShaderPrefix) - { - // build a string that allows us to print out the shader we are generating to the log. - // This is time consuming but I feel like it doesn't happen all that often and is very - // useful to users - // looking at the log file. - - m_GeneratedShaderString.clear(); - m_GeneratedShaderString.assign(nonNull(inShaderPrefix)); - - SShaderDefaultMaterialKey theKey(Key()); - theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); - - m_LightsAsSeparateUniforms = !m_RenderContext.GetRenderContext().GetConstantBufferSupport(); - - GenerateVertexShader(); - GenerateFragmentShader(theKey); - - VertexGenerator().EndVertexGeneration(); - VertexGenerator().EndFragmentGeneration(); - - return ProgramGenerator().CompileGeneratedShader(m_GeneratedShaderString.c_str(), - SShaderCacheProgramFlags(), FeatureSet()); - } - - virtual NVRenderShaderProgram * - GenerateShader(const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, - IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, - NVDataRef inLights, SRenderableImage *inFirstImage, - bool inHasTransparency, const char8_t *inVertexPipelineName, const char8_t *) override - { - QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::DefaultMaterial); - m_CurrentMaterial = static_cast(&inMaterial); - m_CurrentKey = &inShaderDescription; - m_CurrentPipeline = static_cast(&inVertexPipeline); - m_CurrentFeatureSet = inFeatureSet; - m_Lights = inLights; - m_FirstImage = inFirstImage; - m_HasTransparency = inHasTransparency; - - return GenerateMaterialShader(inVertexPipelineName); - } - - SShaderGeneratorGeneratedShader &GetShaderForProgram(NVRenderShaderProgram &inProgram) - { - eastl::pair inserter = - m_ProgramToShaderMap.insert(eastl::make_pair( - &inProgram, NVScopedRefCounted(NULL))); - if (inserter.second) { - NVAllocatorCallback &alloc(m_RenderContext.GetRenderContext().GetAllocator()); - inserter.first->second = QT3DS_NEW(alloc, SShaderGeneratorGeneratedShader)( - inProgram, m_RenderContext.GetRenderContext()); - } - return *inserter.first->second; - } - - void SetGlobalProperties(NVRenderShaderProgram &inProgram, const SLayer & /*inLayer*/ - , - SCamera &inCamera, QT3DSVec3 inCameraDirection, - NVDataRef inLights, NVDataRef inLightDirections, - Qt3DSShadowMap *inShadowMapManager) - { - SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(inProgram)); - m_RenderContext.GetRenderContext().SetActiveShader(&inProgram); - - m_ShadowMapManager = inShadowMapManager; - - SCamera &theCamera(inCamera); - shader.m_CameraPosition.Set(theCamera.GetGlobalPos()); - shader.m_CameraDirection.Set(inCameraDirection); - - QT3DSMat44 viewProj; - if (shader.m_ViewProj.IsValid()) { - theCamera.CalculateViewProjectionMatrix(viewProj); - shader.m_ViewProj.Set(viewProj); - } - - if (shader.m_ViewMatrix.IsValid()) { - viewProj = theCamera.m_GlobalTransform.getInverse(); - shader.m_ViewMatrix.Set(viewProj); - } - - // update the constant buffer - shader.m_AoShadowParams.Set(); - // We can't cache light properties because they can change per object. - QT3DSVec3 theLightAmbientTotal = QT3DSVec3(0, 0, 0); - size_t numShaderLights = shader.m_Lights.size(); - size_t numShadowLights = shader.m_ShadowMaps.size(); - for (QT3DSU32 lightIdx = 0, shadowMapIdx = 0, lightEnd = inLights.size(); - lightIdx < lightEnd && lightIdx < QT3DS_MAX_NUM_LIGHTS; ++lightIdx) { - SLight *theLight(inLights[lightIdx]); - if (lightIdx >= numShaderLights) { - shader.m_Lights.push_back(SShaderLightProperties()); - ++numShaderLights; - } - if (shadowMapIdx >= numShadowLights && numShadowLights < QT3DS_MAX_NUM_SHADOWS) { - if (theLight->m_Scope == NULL && theLight->m_CastShadow) { - // PKC TODO : Fix multiple shadow issues. - // Need to know when the list of lights changes order, and clear shadow maps - // when that happens. - SetupShadowMapVariableNames(lightIdx); - shader.m_ShadowMaps.push_back(SShadowMapProperties( - m_ShadowMapStem.c_str(), m_ShadowCubeStem.c_str(), - m_ShadowMatrixStem.c_str(), m_ShadowControlStem.c_str(), inProgram)); - } - } - QT3DS_ASSERT(lightIdx < numShaderLights); - SShaderLightProperties &theLightProperties(shader.m_Lights[lightIdx]); - float brightness = TranslateConstantAttenuation(theLight->m_Brightness); - - // setup light data - theLightProperties.m_LightColor = theLight->m_DiffuseColor * brightness; - theLightProperties.m_LightData.m_specular = - QT3DSVec4(theLight->m_SpecularColor * brightness, 1.0); - theLightProperties.m_LightData.m_direction = QT3DSVec4(inLightDirections[lightIdx], 1.0); - - // TODO : This does potentially mean that we can create more shadow map entries than - // we can actually use at once. - if ((theLight->m_Scope == NULL) && (theLight->m_CastShadow && inShadowMapManager)) { - SShadowMapProperties &theShadowMapProperties(shader.m_ShadowMaps[shadowMapIdx++]); - SShadowMapEntry *pEntry = inShadowMapManager->GetShadowMapEntry(lightIdx); - if (pEntry) { - // add fixed scale bias matrix - QT3DSMat44 bias(QT3DSVec4(0.5, 0.0, 0.0, 0.0), QT3DSVec4(0.0, 0.5, 0.0, 0.0), - QT3DSVec4(0.0, 0.0, 0.5, 0.0), QT3DSVec4(0.5, 0.5, 0.5, 1.0)); - - if (theLight->m_LightType != RenderLightTypes::Directional) { - theShadowMapProperties.m_ShadowCubeTexture.Set(pEntry->m_DepthCube); - theShadowMapProperties.m_ShadowmapMatrix.Set(pEntry->m_LightView); - } else { - theShadowMapProperties.m_ShadowmapTexture.Set(pEntry->m_DepthMap); - theShadowMapProperties.m_ShadowmapMatrix.Set(bias * pEntry->m_LightVP); - } - - theShadowMapProperties.m_ShadowmapSettings.Set( - QT3DSVec4(theLight->m_ShadowBias, theLight->m_ShadowFactor, - theLight->m_ShadowMapFar, 0.0f)); - } else { - // if we have a light casting shadow we should find an entry - QT3DS_ASSERT(false); - } - } - - if (theLight->m_LightType == RenderLightTypes::Point) { - theLightProperties.m_LightData.m_position = QT3DSVec4(theLight->GetGlobalPos(), 1.0); - theLightProperties.m_LightData.m_constantAttenuation = 1.0; - theLightProperties.m_LightData.m_linearAttenuation = - TranslateLinearAttenuation(theLight->m_LinearFade); - theLightProperties.m_LightData.m_quadraticAttenuation = - TranslateQuadraticAttenuation(theLight->m_ExponentialFade); - } else if (theLight->m_LightType == RenderLightTypes::Area) { - theLightProperties.m_LightData.m_position = QT3DSVec4(theLight->GetGlobalPos(), 1.0); - - QT3DSVec3 upDir = theLight->m_GlobalTransform.getUpper3x3().transform(QT3DSVec3(0, 1, 0)); - QT3DSVec3 rtDir = theLight->m_GlobalTransform.getUpper3x3().transform(QT3DSVec3(1, 0, 0)); - - theLightProperties.m_LightData.m_up = QT3DSVec4(upDir, theLight->m_AreaHeight); - theLightProperties.m_LightData.m_right = QT3DSVec4(rtDir, theLight->m_AreaWidth); - } - theLightAmbientTotal += theLight->m_AmbientColor; - } - shader.m_LightAmbientTotal = theLightAmbientTotal; - } - - // Also sets the blend function on the render context. - void SetMaterialProperties(NVRenderShaderProgram &inProgram, const SDefaultMaterial &inMaterial, - const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inSSaoTexture, - SImage *inLightProbe, SImage *inLightProbe2, QT3DSF32 inProbeHorizon, - QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, - QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) - { - - NVRenderContext &context(m_RenderContext.GetRenderContext()); - SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(inProgram)); - shader.m_MVP.Set(inModelViewProjection); - shader.m_NormalMatrix.Set(inNormalMatrix); - shader.m_GlobalTransform.Set(inGlobalTransform); - shader.m_DepthTexture.Set(inDepthTexture); - - shader.m_AOTexture.Set(inSSaoTexture); - - qt3ds::render::SImage *theLightProbe = inLightProbe; - qt3ds::render::SImage *theLightProbe2 = inLightProbe2; - - // If the material has its own IBL Override, we should use that image instead. - if ((inMaterial.m_IblProbe) && (inMaterial.m_IblProbe->m_TextureData.m_Texture)) { - theLightProbe = inMaterial.m_IblProbe; - } - - if (theLightProbe) { - if (theLightProbe->m_TextureData.m_Texture) { - NVRenderTextureCoordOp::Enum theHorzLightProbeTilingMode = - theLightProbe->m_HorizontalTilingMode; - NVRenderTextureCoordOp::Enum theVertLightProbeTilingMode = - theLightProbe->m_VerticalTilingMode; - theLightProbe->m_TextureData.m_Texture->SetTextureWrapS( - theHorzLightProbeTilingMode); - theLightProbe->m_TextureData.m_Texture->SetTextureWrapT( - theVertLightProbeTilingMode); - const QT3DSMat44 &textureTransform = theLightProbe->m_TextureTransform; - // We separate rotational information from offset information so that just maybe the - // shader - // will attempt to push less information to the card. - const QT3DSF32 *dataPtr(textureTransform.front()); - // The third member of the offsets contains a flag indicating if the texture was - // premultiplied or not. - // We use this to mix the texture alpha. - QT3DSVec4 offsets(dataPtr[12], dataPtr[13], - theLightProbe->m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f - : 0.0f, - (float)theLightProbe->m_TextureData.m_Texture->GetNumMipmaps()); - - // Grab just the upper 2x2 rotation matrix from the larger matrix. - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - - shader.m_LightProbeRot.Set(rotations); - shader.m_LightProbeOfs.Set(offsets); - - if ((!inMaterial.m_IblProbe) && (inProbeFOV < 180.f)) { - shader.m_LightProbeOpts.Set( - QT3DSVec4(0.01745329251994329547f * inProbeFOV, 0.0f, 0.0f, 0.0f)); - } - - // Also make sure to add the secondary texture, but it should only be added if the - // primary - // (i.e. background) texture is also there. - if (theLightProbe2 && theLightProbe2->m_TextureData.m_Texture) { - theLightProbe2->m_TextureData.m_Texture->SetTextureWrapS( - theHorzLightProbeTilingMode); - theLightProbe2->m_TextureData.m_Texture->SetTextureWrapT( - theVertLightProbeTilingMode); - shader.m_LightProbe2.Set(theLightProbe2->m_TextureData.m_Texture); - shader.m_LightProbe2Props.Set( - QT3DSVec4(inProbe2Window, inProbe2Pos, inProbe2Fade, 1.0f)); - - const QT3DSMat44 &xform2 = theLightProbe2->m_TextureTransform; - const QT3DSF32 *dataPtr(xform2.front()); - shader.m_LightProbeProps.Set( - QT3DSVec4(dataPtr[12], dataPtr[13], inProbeHorizon, inProbeBright * 0.01f)); - } else { - shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - shader.m_LightProbeProps.Set( - QT3DSVec4(0.0f, 0.0f, inProbeHorizon, inProbeBright * 0.01f)); - } - NVRenderTexture2D *textureImage = theLightProbe->m_TextureData.m_Texture; - shader.m_LightProbe.Set(textureImage); - shader.m_LightProbeSize.Set(QT3DSVec2(textureImage->GetTextureDetails().m_Width, - textureImage->GetTextureDetails().m_Height)); - } else { - shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); - shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } - } else { - shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); - shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } - - QT3DSF32 emissivePower = 1.0; - - QT3DSU32 hasLighting = inMaterial.m_Lighting != DefaultMaterialLighting::NoLighting; - if (hasLighting) - emissivePower = inMaterial.m_EmissivePower / 100.0f; - - QT3DSVec4 material_diffuse = QT3DSVec4(inMaterial.m_EmissiveColor[0] * emissivePower, - inMaterial.m_EmissiveColor[1] * emissivePower, - inMaterial.m_EmissiveColor[2] * emissivePower, inOpacity); - shader.m_MaterialDiffuse.Set(material_diffuse); - shader.m_DiffuseColor.Set(inMaterial.m_DiffuseColor); - QT3DSVec4 material_specular = - QT3DSVec4(inMaterial.m_SpecularTint[0], inMaterial.m_SpecularTint[1], - inMaterial.m_SpecularTint[2], inMaterial.m_IOR); - shader.m_MaterialSpecular.Set(material_specular); - shader.m_CameraProperties.Set(inCameraVec); - shader.m_FresnelPower.Set(inMaterial.m_FresnelPower); - - if (context.GetConstantBufferSupport()) { - NVRenderConstantBuffer *pLightCb = GetLightConstantBuffer(shader.m_Lights.size()); - // if we have lights we need a light buffer - QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightCb); - - for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); idx < end && pLightCb; ++idx) { - shader.m_Lights[idx].m_LightData.m_diffuse = - QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x, - shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y, - shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0); - - // this is our final change update memory - pLightCb->UpdateRaw(idx * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), - NVDataRef((QT3DSU8 *)&shader.m_Lights[idx].m_LightData, - sizeof(SLightSourceShader))); - } - // update light buffer to hardware - if (pLightCb) { - QT3DSI32 cgLights = shader.m_Lights.size(); - pLightCb->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); - shader.m_LightsBuffer.Set(); - } - } else { - SLightConstantProperties *pLightConstants - = GetLightConstantProperties(shader); - - // if we have lights we need a light buffer - QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightConstants); - - for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); - idx < end && pLightConstants; ++idx) { - shader.m_Lights[idx].m_LightData.m_diffuse = - QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x, - shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y, - shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0); - } - // update light buffer to hardware - if (pLightConstants) - pLightConstants->updateLights(shader); - } - - shader.m_MaterialDiffuseLightAmbientTotal.Set( - QT3DSVec3(shader.m_LightAmbientTotal.x * inMaterial.m_DiffuseColor[0], - shader.m_LightAmbientTotal.y * inMaterial.m_DiffuseColor[1], - shader.m_LightAmbientTotal.z * inMaterial.m_DiffuseColor[2])); - - shader.m_MaterialProperties.Set(QT3DSVec4( - inMaterial.m_SpecularAmount, inMaterial.m_SpecularRoughness, emissivePower, 0.0f)); - shader.m_BumpAmount.Set(inMaterial.m_BumpAmount); - shader.m_DisplaceAmount.Set(inMaterial.m_DisplaceAmount); - shader.m_TranslucentFalloff.Set(inMaterial.m_TranslucentFalloff); - shader.m_DiffuseLightWrap.Set(inMaterial.m_DiffuseLightWrap); - QT3DSU32 imageIdx = 0; - for (SRenderableImage *theImage = inFirstImage; theImage; - theImage = theImage->m_NextImage, ++imageIdx) - SetImageShaderVariables(shader, *theImage, imageIdx); - - qt3ds::render::NVRenderBlendFunctionArgument blendFunc; - qt3ds::render::NVRenderBlendEquationArgument blendEqua(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - // The blend function goes: - // src op - // dst op - // src alpha op - // dst alpha op - // All of our shaders produce non-premultiplied values. - switch (inMaterial.m_BlendMode) { - case DefaultMaterialBlendMode::Screen: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - break; - case DefaultMaterialBlendMode::Multiply: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::DstColor, NVRenderDstBlendFunc::Zero, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - break; - case DefaultMaterialBlendMode::Overlay: - // SW fallback is not using blend equation - // note blend func is not used here anymore - if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) - blendEqua = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Overlay, NVRenderBlendEquation::Overlay); - break; - case DefaultMaterialBlendMode::ColorBurn: - // SW fallback is not using blend equation - // note blend func is not used here anymore - if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) - blendEqua = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorBurn, NVRenderBlendEquation::ColorBurn); - break; - case DefaultMaterialBlendMode::ColorDodge: - // SW fallback is not using blend equation - // note blend func is not used here anymore - if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) - blendEqua = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorDodge, NVRenderBlendEquation::ColorDodge); - break; - default: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); - break; - } - context.SetBlendFunction(blendFunc); - context.SetBlendEquation(blendEqua); - } - void SetMaterialProperties(NVRenderShaderProgram &inProgram, - const SGraphObject &inMaterial, const QT3DSVec2 &inCameraVec, - const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, - const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - SLayerGlobalRenderProperties inRenderProperties) override - { - const SDefaultMaterial &theMaterial(static_cast(inMaterial)); - QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::DefaultMaterial); - - SetGlobalProperties(inProgram, inRenderProperties.m_Layer, inRenderProperties.m_Camera, - inRenderProperties.m_CameraDirection, inRenderProperties.m_Lights, - inRenderProperties.m_LightDirections, - inRenderProperties.m_ShadowMapManager); - SetMaterialProperties(inProgram, theMaterial, inCameraVec, inModelViewProjection, - inNormalMatrix, inGlobalTransform, inFirstImage, inOpacity, - inRenderProperties.m_DepthTexture, inRenderProperties.m_SSaoTexture, - inRenderProperties.m_LightProbe, inRenderProperties.m_LightProbe2, - inRenderProperties.m_ProbeHorizon, inRenderProperties.m_ProbeBright, - inRenderProperties.m_Probe2Window, inRenderProperties.m_Probe2Pos, - inRenderProperties.m_Probe2Fade, inRenderProperties.m_ProbeFOV); - } - - SLightConstantProperties *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader) - { - if (!shader.m_lightConstantProperties - || int(shader.m_Lights.size()) - > shader.m_lightConstantProperties->m_constants.size()) { - if (shader.m_lightConstantProperties) - delete shader.m_lightConstantProperties; - shader.m_lightConstantProperties - = new SLightConstantProperties( - shader, m_LightsAsSeparateUniforms); - } - return shader.m_lightConstantProperties; - } -}; -} - -IDefaultMaterialShaderGenerator & -IDefaultMaterialShaderGenerator::CreateDefaultMaterialShaderGenerator(IQt3DSRenderContext &inRc) -{ - return *QT3DS_NEW(inRc.GetAllocator(), SShaderGenerator)(inRc); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDynamicObjectSystem.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDynamicObjectSystem.cpp deleted file mode 100644 index 00de6c3d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderDynamicObjectSystem.cpp +++ /dev/null @@ -1,1531 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderContextCore.h" -#include "render/Qt3DSRenderShaderConstant.h" -#include "Qt3DSRenderDynamicObject.h" -#include "foundation/SerializationTypes.h" -#include "foundation/FileTools.h" -#include "foundation/PreAllocatedAllocator.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderString.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRenderDynamicObjectSystemCommands.h" -#include "Qt3DSRenderDynamicObjectSystemUtil.h" -#include "Qt3DSRenderShaderCodeGenerator.h" -#include "foundation/Qt3DSMutex.h" - -using namespace qt3ds; -using namespace qt3ds::render; -using namespace qt3ds::render::dynamic; - -namespace { -typedef eastl::pair TStrStrPair; -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const TStrStrPair &item) const - { - return hash()(item.first) ^ hash()(item.second); - } -}; -} - -namespace qt3ds { -namespace render { - namespace dynamic { - - QT3DSU32 SCommand::GetSizeofCommand(const SCommand &inCommand) - { - switch (inCommand.m_Type) { - case CommandTypes::AllocateBuffer: - return sizeof(SAllocateBuffer); - case CommandTypes::BindBuffer: - return sizeof(SBindBuffer); - case CommandTypes::BindTarget: - return sizeof(SBindTarget); - case CommandTypes::BindShader: - return sizeof(SBindShader); - case CommandTypes::Render: - return sizeof(SRender); - case CommandTypes::ApplyBufferValue: - return sizeof(SApplyBufferValue); - case CommandTypes::ApplyDepthValue: - return sizeof(SApplyDepthValue); - case CommandTypes::ApplyInstanceValue: - return sizeof(SApplyInstanceValue); - case CommandTypes::ApplyBlending: - return sizeof(SApplyBlending); - case CommandTypes::ApplyRenderState: - return sizeof(SApplyRenderState); - case CommandTypes::ApplyBlitFramebuffer: - return sizeof(SApplyBlitFramebuffer); - case CommandTypes::ApplyValue: - return sizeof(SApplyValue) - + static_cast(inCommand).m_Value.mSize; - case CommandTypes::DepthStencil: - return sizeof(SDepthStencil); - case CommandTypes::AllocateImage: - return sizeof(SAllocateImage); - case CommandTypes::ApplyImageValue: - return sizeof(SApplyImageValue); - case CommandTypes::AllocateDataBuffer: - return sizeof(SAllocateDataBuffer); - case CommandTypes::ApplyDataBufferValue: - return sizeof(SApplyDataBufferValue); - default: - break; - } - QT3DS_ASSERT(false); - return 0; - } - - template - inline void CopyConstructCommandT(QT3DSU8 *inDataBuffer, const SCommand &inCommand, - IStringTable &inStrTable) - { - TCommandType *theCommand = (TCommandType *)inDataBuffer; - theCommand = new (theCommand) - TCommandType(static_cast(inCommand), inStrTable); - } - - void SCommand::CopyConstructCommand(QT3DSU8 *inDataBuffer, const SCommand &inCommand, - IStringTable &inStrTable) - { - switch (inCommand.m_Type) { - case CommandTypes::AllocateBuffer: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::BindBuffer: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::BindTarget: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::BindShader: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::Render: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyBufferValue: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyDepthValue: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyInstanceValue: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyBlending: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyRenderState: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyBlitFramebuffer: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyValue: { - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - SApplyValue &dest = *reinterpret_cast(inDataBuffer); - QT3DSU8 *destMem = inDataBuffer + sizeof(SApplyValue); - const SApplyValue &src = static_cast(inCommand); - memcpy(destMem, src.m_Value.mData, src.m_Value.mSize); - dest.m_Value.mData = destMem; - break; - } - case CommandTypes::DepthStencil: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::AllocateImage: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyImageValue: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::AllocateDataBuffer: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - case CommandTypes::ApplyDataBufferValue: - CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - } -} -} - -namespace { - -template -struct SCommandRemapping -{ - template - static void RemapCommandData(TCommandType &, TRemapper &) - { - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SAllocateBuffer &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_Name); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SAllocateImage &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_Name); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SAllocateDataBuffer &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_Name); - if (cmd.m_WrapName) - remapper.Remap(cmd.m_WrapName); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SBindBuffer &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_BufferName); - } -}; -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SBindShader &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_ShaderPath); - remapper.Remap(cmd.m_ShaderDefine); - } -}; -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SApplyInstanceValue &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_PropertyName); - } -}; -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SApplyBufferValue &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_BufferName); - remapper.Remap(cmd.m_ParamName); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SApplyDepthValue &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_ParamName); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SApplyBlitFramebuffer &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_SourceBufferName); - remapper.Remap(cmd.m_DestBufferName); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SApplyValue &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_PropertyName); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SApplyDataBufferValue &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_ParamName); - } -}; - -template <> -struct SCommandRemapping -{ - template - static void RemapCommandData(SDepthStencil &cmd, TRemapper &remapper) - { - remapper.Remap(cmd.m_BufferName); - } -}; - -QT3DSU32 Align(QT3DSU32 inValue) -{ - if (inValue % 4) - return inValue + (4 - (inValue % 4)); - return inValue; -} - -QT3DSU32 Align8(QT3DSU32 inValue) -{ - if (inValue % 8) - return inValue + (8 - (inValue % 8)); - return inValue; -} - -inline const char *GetShaderDatatypeName(NVRenderShaderDataTypes::Enum inValue) -{ - switch (inValue) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ - case NVRenderShaderDataTypes::type: \ - return #type; - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return ""; -} - -inline qt3ds::QT3DSU32 getSizeofShaderDataType(NVRenderShaderDataTypes::Enum value) -{ - using namespace qt3ds; - using namespace qt3ds::render; - switch (value) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(x) \ - case NVRenderShaderDataTypes::x: \ - return sizeof(x); - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - break; - } - QT3DS_ASSERT(false); - return 0; -} - -struct SDynamicObjectShaderInfo -{ - CRegisteredString m_Type; ///< shader type (GLSL or HLSL) - CRegisteredString m_Version; ///< shader version (e.g. 330 vor GLSL) - bool m_HasGeomShader; - bool m_IsComputeShader; - - SDynamicObjectShaderInfo() - : m_HasGeomShader(false) - , m_IsComputeShader(false) - { - } - SDynamicObjectShaderInfo(CRegisteredString inType, CRegisteredString inVersion, - bool inHasGeomShader, bool inIsComputeShader) - : m_Type(inType) - , m_Version(inVersion) - , m_HasGeomShader(inHasGeomShader) - , m_IsComputeShader(inIsComputeShader) - { - } -}; - -struct SDynamicObjClassImpl : public IDynamicObjectClass -{ - NVAllocatorCallback *m_Allocator; - CRegisteredString m_Id; - NVConstDataRef m_PropertyDefinitions; - QT3DSU32 m_PropertySectionByteSize; - QT3DSU32 m_BaseObjectSize; - GraphObjectTypes::Enum m_GraphObjectType; - QT3DSU8 *m_PropertyDefaultData; - NVConstDataRef m_RenderCommands; - volatile QT3DSI32 mRefCount; - bool m_RequiresDepthTexture; - bool m_RequiresCompilation; - NVRenderTextureFormats::Enum m_OutputFormat; - - SDynamicObjClassImpl( - NVAllocatorCallback &alloc, CRegisteredString id, - NVConstDataRef definitions, QT3DSU32 propertySectionByteSize, - QT3DSU32 baseObjectSize, GraphObjectTypes::Enum objectType, QT3DSU8 *propDefaultData, - bool inRequiresDepthTexture = false, - NVRenderTextureFormats::Enum inOutputFormat = NVRenderTextureFormats::RGBA8) - : m_Allocator(&alloc) - , m_Id(id) - , m_PropertyDefinitions(definitions) - , m_PropertySectionByteSize(propertySectionByteSize) - , m_BaseObjectSize(baseObjectSize) - , m_GraphObjectType(objectType) - , m_PropertyDefaultData(propDefaultData) - , mRefCount(0) - , m_RequiresDepthTexture(inRequiresDepthTexture) - , m_RequiresCompilation(false) - , m_OutputFormat(inOutputFormat) - { - } - - ~SDynamicObjClassImpl() - { - if (m_PropertyDefinitions.size()) { - for (QT3DSU32 idx = 0, end = m_PropertyDefinitions.size(); idx < end; ++idx) { - if (m_PropertyDefinitions[idx].m_EnumValueNames.size()) - m_Allocator->deallocate( - (void *)m_PropertyDefinitions[idx].m_EnumValueNames.begin()); - } - } - ReleaseCommands(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator) - - template - static void RemapCommand(SCommand &inCommand, TRemapperType &inRemapper) - { - switch (inCommand.m_Type) { -#define QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(type) \ - case CommandTypes::type: \ - SCommandRemapping::RemapCommandData(static_cast(inCommand), \ - inRemapper); \ - break; - QT3DS_RENDER_EFFECTS_ITERATE_COMMAND_TYPES -#undef QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES - default: - QT3DS_ASSERT(false); - break; - } - } - template - void SetupThisObjectFromMemory(NVAllocatorCallback &inAlloc, TRemapper &inRemapper, - QT3DSU8 *inCommandStart, QT3DSU32 numEffectCommands) - { - m_Allocator = &inAlloc; - mRefCount = 0; - QT3DSU8 *theCommandPtrBegin = inCommandStart; - QT3DSU32 theCommandOffset = 0; - for (QT3DSU32 idx = 0; idx < numEffectCommands; ++idx) { - SCommand *theCommand = reinterpret_cast(inCommandStart + theCommandOffset); - theCommandOffset += SCommand::GetSizeofCommand(*theCommand); - } - SCommand **theCommandPtrStart = - reinterpret_cast(theCommandPtrBegin + theCommandOffset); - m_RenderCommands = NVConstDataRef(theCommandPtrStart, numEffectCommands); - // Now run through the commands, fixup strings and setup the command ptrs - theCommandOffset = 0; - for (QT3DSU32 idx = 0; idx < numEffectCommands; ++idx) { - SCommand *theCommand = - reinterpret_cast(theCommandPtrBegin + theCommandOffset); - theCommandPtrStart[idx] = theCommand; - RemapCommand(*theCommand, inRemapper); - theCommandOffset += SCommand::GetSizeofCommand(*theCommand); - } - } - - void ReleaseCommands() - { - if (m_RenderCommands.size()) { - m_Allocator->deallocate(const_cast(*m_RenderCommands.begin())); - m_RenderCommands = NVConstDataRef(); - } - } - - CRegisteredString GetId() const override { return m_Id; } - NVConstDataRef GetProperties() const override - { - return m_PropertyDefinitions; - } - QT3DSU32 GetPropertySectionByteSize() const override { return m_PropertySectionByteSize; } - const QT3DSU8 *GetDefaultValueBuffer() const override { return m_PropertyDefaultData; } - QT3DSU32 GetBaseObjectSize() const override { return m_BaseObjectSize; } - GraphObjectTypes::Enum GraphObjectType() const override { return m_GraphObjectType; } - const SPropertyDefinition *FindDefinition(CRegisteredString &str) const - { - for (QT3DSU32 idx = 0, end = m_PropertyDefinitions.size(); idx < end; ++idx) { - const SPropertyDefinition &def(m_PropertyDefinitions[idx]); - if (def.m_Name == str) - return &def; - } - return NULL; - } - const SPropertyDefinition *FindPropertyByName(CRegisteredString inName) const override - { - return FindDefinition(inName); - } - NVConstDataRef GetRenderCommands() const override - { - return m_RenderCommands; - } - bool RequiresDepthTexture() const override { return m_RequiresDepthTexture; } - void SetRequiresDepthTexture(bool inVal) override { m_RequiresDepthTexture = inVal; } - virtual bool RequiresCompilation() const override { return m_RequiresCompilation; } - virtual void SetRequiresCompilation(bool inVal) override { m_RequiresCompilation = inVal; } - NVRenderTextureFormats::Enum GetOutputTextureFormat() const override { return m_OutputFormat; } -}; - -struct SDataRemapper -{ - template - void Remap(QT3DSU8 *inData, SPropertyDefinition &item, TRemapper &remapper) - { - switch (item.m_DataType) { - default: - break; // no remapping necessary - case NVRenderShaderDataTypes::NVRenderTexture2DPtr: - CRegisteredString *realData = reinterpret_cast(inData); - remapper.Remap(*realData); - break; - } - } -}; - -struct SShaderMapKey -{ - TStrStrPair m_Name; - eastl::vector m_Features; - TessModeValues::Enum m_TessMode; - bool m_WireframeMode; - size_t m_HashCode; - SShaderMapKey(TStrStrPair inName, TShaderFeatureSet inFeatures, TessModeValues::Enum inTessMode, - bool inWireframeMode) - : m_Name(inName) - , m_Features(inFeatures.begin(), inFeatures.end()) - , m_TessMode(inTessMode) - , m_WireframeMode(inWireframeMode) - { - m_HashCode = eastl::hash()(m_Name) - ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size())) - ^ eastl::hash()(m_TessMode) ^ eastl::hash()(m_WireframeMode); - } - bool operator==(const SShaderMapKey &inKey) const - { - return m_Name == inKey.m_Name && m_Features == inKey.m_Features - && m_TessMode == inKey.m_TessMode && m_WireframeMode == inKey.m_WireframeMode; - } -}; -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SShaderMapKey &inKey) const { return inKey.m_HashCode; } -}; -} - -namespace { - -typedef nvhash_map> TStringClassMap; -typedef nvhash_map TPathDataMap; -typedef nvhash_map TShaderInfoMap; -typedef nvhash_set TPathSet; -typedef nvhash_map TShaderMap; - -struct SDynamicObjectSystemCoreImpl : public IDynamicObjectSystem -{ -}; - -struct SDynamicObjectSystemImpl : public IDynamicObjectSystem -{ - NVFoundationBase &m_Foundation; - mutable qt3ds::render::SPreAllocatedAllocator m_Allocator; - IQt3DSRenderContextCore &m_CoreContext; - IQt3DSRenderContext *m_Context; - TStringClassMap m_Classes; - TPathDataMap m_ExpandedFiles; - CRenderString m_ShaderKeyBuilder; - TShaderMap m_ShaderMap; - TShaderInfoMap m_ShaderInfoMap; - CRenderString m_IncludePath; - CRenderString m_IncludeSearch; - CRenderString m_VertShader; - CRenderString m_FragShader; - CRenderString m_GeometryShader; - QString m_shaderLibraryVersion; - QString m_shaderLibraryPlatformDirectory; - mutable Mutex m_PropertyLoadMutex; - QT3DSI32 mRefCount; - - SDynamicObjectSystemImpl(IQt3DSRenderContextCore &inCore) - : m_Foundation(inCore.GetFoundation()) - , m_Allocator(inCore.GetAllocator()) - , m_CoreContext(inCore) - , m_Context(NULL) - , m_Classes(inCore.GetAllocator(), "Classes") - , m_ExpandedFiles(inCore.GetAllocator(), "ExpandedShaderFiles") - , m_ShaderMap(inCore.GetAllocator(), "ShaderMap") - , m_ShaderInfoMap(inCore.GetAllocator(), "ShaderInfoMap") - , m_PropertyLoadMutex(inCore.GetAllocator()) - , mRefCount(0) - { - m_IncludeSearch = "#include \""; - } - - virtual ~SDynamicObjectSystemImpl() - { - for (TPathDataMap::iterator iter = m_ExpandedFiles.begin(), end = m_ExpandedFiles.end(); - iter != end; ++iter) - m_Allocator.deallocate(iter->second); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - bool IsRegistered(CRegisteredString inStr) override - { - return m_Classes.find(inStr) != m_Classes.end(); - } - - bool Register(CRegisteredString inName, - NVConstDataRef inProperties, QT3DSU32 inBaseObjectSize, - GraphObjectTypes::Enum inGraphObjectType) override - { - if (IsRegistered(inName)) { - QT3DS_ASSERT(false); - return false; - } - nvvector definitions(m_Foundation.getAllocator(), - "PropertyDefinitions"); - QT3DSU32 theCurrentOffset = 0; - for (QT3DSU32 idx = 0, end = inProperties.size(); idx < end; ++idx) { - const SPropertyDeclaration &thePropDec = inProperties[idx]; - CRegisteredString thePropName( - m_CoreContext.GetStringTable().RegisterStr(thePropDec.m_Name)); - QT3DSU32 propSize = getSizeofShaderDataType(thePropDec.m_DataType); - definitions.push_back(SPropertyDefinition(thePropName, thePropDec.m_DataType, - theCurrentOffset, propSize)); - theCurrentOffset += propSize; - theCurrentOffset = Align(theCurrentOffset); - } - QT3DSU32 dataSectionSize = theCurrentOffset; - QT3DSU32 clsSize = Align(sizeof(SDynamicObjClassImpl)); - QT3DSU32 defSize = Align(sizeof(SPropertyDefinition) * inProperties.size()); - QT3DSU32 defaultSize = dataSectionSize; - QT3DSU32 allocSize = clsSize + defSize + defaultSize; - QT3DSU8 *allocData = reinterpret_cast( - m_Allocator.allocate(allocSize, "SDynamicObjClassImpl", __FILE__, __LINE__)); - QT3DSU8 *defData = allocData + clsSize; - QT3DSU8 *defaultData = defData + defSize; - SPropertyDefinition *defPtr = reinterpret_cast(defData); - if (defSize) - memCopy(defPtr, definitions.data(), defSize); - if (defaultSize) - memZero(defaultData, defaultSize); - SDynamicObjClassImpl *theClass = new (allocData) - SDynamicObjClassImpl(m_Allocator, inName, toDataRef(defPtr, inProperties.size()), - dataSectionSize, inBaseObjectSize, inGraphObjectType, defaultData); - m_Classes.insert(eastl::make_pair(inName, theClass)); - return true; - } - - bool Unregister(CRegisteredString inName) override { - if (!IsRegistered(inName)) { - QT3DS_ASSERT(false); - return false; - } - TStringClassMap::iterator iter = m_Classes.find(inName); - if (iter != m_Classes.end()) - m_Classes.erase(iter); - return true; - } - - SDynamicObjClassImpl *FindClass(CRegisteredString inName) - { - TStringClassMap::iterator iter = m_Classes.find(inName); - if (iter != m_Classes.end()) - return iter->second.mPtr; - return NULL; - } - - eastl::pair - FindProperty(CRegisteredString inName, CRegisteredString inPropName) - { - SDynamicObjClassImpl *cls = FindClass(inName); - if (cls) { - const SPropertyDefinition *def = cls->FindDefinition(inPropName); - if (def) - return eastl::make_pair(def, cls); - } - return eastl::pair(NULL, NULL); - } - - void SetPropertyDefaultValue(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inDefaultData) override - { - eastl::pair def = - FindProperty(inName, inPropName); - if (def.first && inDefaultData.size() >= def.first->m_ByteSize) { - memCopy(def.second->m_PropertyDefaultData + def.first->m_Offset, inDefaultData.begin(), - def.first->m_ByteSize); - } else { - QT3DS_ASSERT(false); - } - } - - void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inNames) override - { - - eastl::pair def = - FindProperty(inName, inPropName); - SPropertyDefinition *theDefinitionPtr = const_cast(def.first); - if (theDefinitionPtr == NULL) { - QT3DS_ASSERT(false); - return; - } - if (theDefinitionPtr->m_EnumValueNames.size()) { - m_Foundation.getAllocator().deallocate( - (void *)theDefinitionPtr->m_EnumValueNames.begin()); - theDefinitionPtr->m_EnumValueNames = NVConstDataRef(); - } - theDefinitionPtr->m_IsEnumProperty = true; - if (inNames.size()) { - CRegisteredString *theNameValues = (CRegisteredString *)m_Allocator.allocate( - inNames.size() * sizeof(CRegisteredString), "PropertyEnumNames", __FILE__, - __LINE__); - - memCopy(theNameValues, inNames.begin(), inNames.size() * sizeof(CRegisteredString)); - theDefinitionPtr->m_EnumValueNames = - NVConstDataRef(theNameValues, inNames.size()); - } - } - - virtual NVConstDataRef - GetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName) const override - { - eastl::pair def = - const_cast(*this).FindProperty(inName, inPropName); - if (def.first) - return def.first->m_EnumValueNames; - return NVConstDataRef(); - } - - // Called during loading which is pretty heavily multithreaded. - virtual NVConstDataRef - GetProperties(CRegisteredString inName) const override - { - Mutex::ScopedLock __locker(m_PropertyLoadMutex); - SDynamicObjClassImpl *cls = const_cast(*this).FindClass(inName); - if (cls) - return cls->m_PropertyDefinitions; - return NVConstDataRef(); - } - - void SetPropertyTextureSettings(CRegisteredString inName, CRegisteredString inPropName, - CRegisteredString inPropPath, - NVRenderTextureTypeValue::Enum inTexType, - NVRenderTextureCoordOp::Enum inCoordOp, - NVRenderTextureMagnifyingOp::Enum inMagFilterOp, - NVRenderTextureMinifyingOp::Enum inMinFilterOp) override - { - eastl::pair def = - FindProperty(inName, inPropName); - SPropertyDefinition *theDefinitionPtr = const_cast(def.first); - if (theDefinitionPtr == NULL) { - QT3DS_ASSERT(false); - return; - } - theDefinitionPtr->m_ImagePath = inPropPath; - theDefinitionPtr->m_TexUsageType = inTexType; - theDefinitionPtr->m_CoordOp = inCoordOp; - theDefinitionPtr->m_MagFilterOp = inMagFilterOp; - theDefinitionPtr->m_MinFilterOp = inMinFilterOp; - } - - IDynamicObjectClass *GetDynamicObjectClass(CRegisteredString inName) override - { - return FindClass(inName); - } - - void SetRenderCommands(CRegisteredString inClassName, - NVConstDataRef inCommands) override - { - SDynamicObjClassImpl *theClass = - const_cast(*this).FindClass(inClassName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - theClass->ReleaseCommands(); - QT3DSU32 commandAllocationSize = 0; - for (QT3DSU32 idx = 0, end = inCommands.size(); idx < end; ++idx) { - QT3DSU32 commandSize = Align(SCommand::GetSizeofCommand(*inCommands[idx])); - commandAllocationSize += commandSize; - } - QT3DSU32 commandPtrSize = inCommands.size() * sizeof(SCommand *); - QT3DSU32 totalAllocationSize = Align8(commandAllocationSize) + commandPtrSize; - QT3DSU8 *theCommandDataBegin = (QT3DSU8 *)m_Allocator.allocate( - totalAllocationSize, "dynamic::SCommand", __FILE__, __LINE__); - QT3DSU8 *theCurrentCommandData(theCommandDataBegin); - SCommand **theCommandPtrBegin = - reinterpret_cast(theCommandDataBegin + Align8(commandAllocationSize)); - SCommand **theCurrentCommandPtr = theCommandPtrBegin; - memZero(theCommandDataBegin, totalAllocationSize); - - theClass->m_RequiresDepthTexture = false; - for (QT3DSU32 idx = 0, end = inCommands.size(); idx < end; ++idx) { - SCommand &theCommand(*inCommands[idx]); - QT3DSU32 theCommandSize = SCommand::GetSizeofCommand(theCommand); - SCommand::CopyConstructCommand(theCurrentCommandData, theCommand, - m_CoreContext.GetStringTable()); - if (theCommand.m_Type == CommandTypes::ApplyDepthValue) - theClass->m_RequiresDepthTexture = true; - if (theCommand.m_Type == CommandTypes::BindTarget) { - SBindTarget *bt = reinterpret_cast(&theCommand); - theClass->m_OutputFormat = bt->m_OutputFormat; - } - - *theCurrentCommandPtr = reinterpret_cast(theCurrentCommandData); - ++theCurrentCommandPtr; - theCurrentCommandData += Align(theCommandSize); - } - QT3DS_ASSERT(theCurrentCommandData - theCommandDataBegin == (int)commandAllocationSize); - QT3DS_ASSERT((QT3DSU8 *)theCurrentCommandPtr - theCommandDataBegin == (int)totalAllocationSize); - theClass->m_RenderCommands = - NVConstDataRef(theCommandPtrBegin, inCommands.size()); - } - - virtual NVConstDataRef - GetRenderCommands(CRegisteredString inClassName) const override - { - SDynamicObjClassImpl *cls = - const_cast(*this).FindClass(inClassName); - if (cls) - return cls->m_RenderCommands; - return NVConstDataRef(); - } - - SDynamicObject *CreateInstance(CRegisteredString inClassName, - NVAllocatorCallback &inSceneGraphAllocator) override - { - SDynamicObjClassImpl *theClass = FindClass(inClassName); - if (!theClass) { - QT3DS_ASSERT(false); - return NULL; - } - QT3DSU32 totalObjectSize = theClass->m_BaseObjectSize + theClass->m_PropertySectionByteSize; - SDynamicObject *retval = reinterpret_cast(inSceneGraphAllocator.allocate( - totalObjectSize, inClassName.c_str(), __FILE__, __LINE__)); - new (retval) - SDynamicObject(theClass->m_GraphObjectType, inClassName, - theClass->m_PropertySectionByteSize, theClass->m_BaseObjectSize); - memCopy(retval->GetDataSectionBegin(), theClass->m_PropertyDefaultData, - theClass->m_PropertySectionByteSize); - return retval; - } - - void SetShaderData(CRegisteredString inPath, const char8_t *inData, - const char8_t *inShaderType, const char8_t *inShaderVersion, - bool inHasGeomShader, bool inIsComputeShader) override - { - inData = inData ? inData : ""; - eastl::pair theInserter = - m_ExpandedFiles.insert(eastl::make_pair(inPath, (char8_t *)"")); - if (theInserter.second == false) { - // Delete the existing entry. - m_Allocator.deallocate(theInserter.first->second); - } - QT3DSU32 theLen = (QT3DSU32)strlen(inData) + 1; - char8_t *newData = (char8_t *)m_Allocator.allocate( - theLen, "SDynamicObjectSystem::SetShaderData", __FILE__, __LINE__); - memCopy(newData, inData, theLen); - theInserter.first->second = newData; - - // set shader type and version if available - if (inShaderType || inShaderVersion || inHasGeomShader || inIsComputeShader) { - // UdoL TODO: Add this to the load / save setction - // In addition we should merge the source code into SDynamicObjectShaderInfo as well - SDynamicObjectShaderInfo &theShaderInfo = - m_ShaderInfoMap.insert(eastl::make_pair(inPath, SDynamicObjectShaderInfo())) - .first->second; - IStringTable &theStringTable(m_CoreContext.GetStringTable()); - theShaderInfo.m_Type = theStringTable.RegisterStr(nonNull(inShaderType)); - theShaderInfo.m_Version = theStringTable.RegisterStr(nonNull(inShaderVersion)); - theShaderInfo.m_HasGeomShader = inHasGeomShader; - theShaderInfo.m_IsComputeShader = inIsComputeShader; - } - - return; - } - - CRegisteredString GetShaderCacheKey(const char8_t *inId, const char8_t *inProgramMacro, - const dynamic::SDynamicShaderProgramFlags &inFlags) - { - m_ShaderKeyBuilder.assign(inId); - if (inProgramMacro && *inProgramMacro) { - m_ShaderKeyBuilder.append("#"); - m_ShaderKeyBuilder.append(inProgramMacro); - } - if (inFlags.IsTessellationEnabled()) { - m_ShaderKeyBuilder.append("#"); - m_ShaderKeyBuilder.append(TessModeValues::toString(inFlags.m_TessMode)); - } - if (inFlags.IsGeometryShaderEnabled() && inFlags.m_WireframeMode) { - m_ShaderKeyBuilder.append("#"); - m_ShaderKeyBuilder.append(inFlags.wireframeToString(inFlags.m_WireframeMode)); - } - - return m_CoreContext.GetStringTable().RegisterStr(m_ShaderKeyBuilder.c_str()); - } - - void InsertShaderHeaderInformation(CRenderString &theReadBuffer, - const char8_t *inPathToEffect) override - { - DoInsertShaderHeaderInformation(theReadBuffer, inPathToEffect); - } - - void DoInsertShaderHeaderInformation(CRenderString &theReadBuffer, - const char8_t *inPathToEffect) - { - // Now do search and replace for the headers - for (CRenderString::size_type thePos = theReadBuffer.find(m_IncludeSearch); - thePos != CRenderString::npos; - thePos = theReadBuffer.find(m_IncludeSearch, thePos + 1)) { - CRenderString::size_type theEndQuote = - theReadBuffer.find('\"', thePos + m_IncludeSearch.size() + 1); - // Indicates an unterminated include file. - if (theEndQuote == CRenderString::npos) { - qCCritical(INVALID_OPERATION, "Unterminated include in file: %s", inPathToEffect); - theReadBuffer.clear(); - break; - } - CRenderString::size_type theActualBegin = thePos + m_IncludeSearch.size(); - CRenderString::iterator theIncludeBegin = theReadBuffer.begin() + theActualBegin; - CRenderString::iterator theIncludeEnd = theReadBuffer.begin() + theEndQuote; - m_IncludePath.clear(); - m_IncludePath.append(theIncludeBegin, theIncludeEnd); - // If we haven't included the file yet this round - CRenderString theIncludeBuffer; - const char8_t *theHeader = DoLoadShader(m_IncludePath.c_str(), theIncludeBuffer); - QT3DSU32 theLen = (QT3DSU32)strlen(theHeader); - theReadBuffer = - theReadBuffer.replace(theReadBuffer.begin() + thePos, - theReadBuffer.begin() + theEndQuote + 1, theHeader, theLen); - } - } - - const char8_t *DoLoadShader(const char8_t *inPathToEffect, CRenderString &outShaderData) - { - eastl::pair theInsert = - m_ExpandedFiles.insert(eastl::make_pair( - m_CoreContext.GetStringTable().RegisterStr(inPathToEffect), (char8_t *)"")); - - CRenderString &theReadBuffer(outShaderData); - if (theInsert.second) { - - const QString defaultDir = m_Context->GetDynamicObjectSystem() - .GetShaderCodeLibraryDirectory(); - const QString platformDir = m_Context->GetDynamicObjectSystem() - .shaderCodeLibraryPlatformDirectory(); - - QString fullPath; - NVScopedRefCounted theStream; - if (!platformDir.isEmpty()) { - QTextStream stream(&fullPath); - stream << platformDir << QLatin1Char('/') << inPathToEffect; - theStream = m_CoreContext.GetInputStreamFactory() - .GetStreamForFile(fullPath.toLatin1().data()); - } - - if (theStream.mPtr == NULL) { - fullPath.clear(); - QTextStream stream(&fullPath); - stream << defaultDir << QLatin1Char('/') << inPathToEffect; - theStream = m_CoreContext.GetInputStreamFactory() - .GetStreamForFile(fullPath.toLatin1().data()); - if (theStream.mPtr == NULL) { - fullPath.clear(); - QTextStream stream(&fullPath); - stream << defaultDir << QLatin1Char('/') << inPathToEffect; - theStream = m_CoreContext.GetInputStreamFactory() - .GetStreamForFile(fullPath.toLatin1().data()); - } - } - if (theStream.mPtr != NULL) { - QT3DSU8 readBuf[1024]; - QT3DSU32 amountRead = 0; - do { - amountRead = theStream->Read(NVDataRef(readBuf, 1024)); - if (amountRead) - theReadBuffer.append((const char8_t *)readBuf, amountRead); - } while (amountRead); - } else { - qCCritical(INVALID_OPERATION, "Failed to find include file %s", inPathToEffect); - QT3DS_ASSERT(false); - } - theInsert.first->second = (char8_t *)m_Allocator.allocate( - theReadBuffer.size() + 1, "SDynamicObjectSystem::DoLoadShader", __FILE__, __LINE__); - memCopy(theInsert.first->second, theReadBuffer.c_str(), - QT3DSU32(theReadBuffer.size()) + 1); - } else - theReadBuffer.assign(theInsert.first->second); - DoInsertShaderHeaderInformation(theReadBuffer, inPathToEffect); - return theReadBuffer.c_str(); - } - - void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, const char8_t *inProjectDir) const override - { - QT3DSU32 startOffset = ioBuffer.size(); - ioBuffer.write((QT3DSU32)m_ExpandedFiles.size()); - for (TPathDataMap::const_iterator theIter = m_ExpandedFiles.begin(); - theIter != m_ExpandedFiles.end(); ++theIter) { - CRegisteredString thePath(theIter->first); - char8_t *theData = theIter->second; - theData = theData ? theData : (char8_t *)""; - QT3DSU32 theLen = (QT3DSU32)strlen(theData); - thePath.Remap(inRemapMap); - ioBuffer.write(thePath); - ioBuffer.write(theLen + 1); - ioBuffer.write(theData, theLen + 1); - ioBuffer.align(sizeof(void *)); - } - ioBuffer.write((QT3DSU32)m_Classes.size()); - SStringSaveRemapper theRemapper(m_Allocator, inRemapMap, inProjectDir, - m_CoreContext.GetStringTable()); - for (TStringClassMap::const_iterator iter = m_Classes.begin(), end = m_Classes.end(); - iter != end; ++iter) { - const SDynamicObjClassImpl *theClass = iter->second; - ioBuffer.align(4); - QT3DSU32 objOffset = ioBuffer.size(); - QT3DSU32 classOffset = objOffset - startOffset; - (void)classOffset; - QT3DSU32 defOffset = objOffset + sizeof(SDynamicObjClassImpl); - QT3DSU32 dataOffset = - defOffset + theClass->m_PropertyDefinitions.size() * sizeof(SPropertyDefinition); - QT3DSU32 dataEnd = dataOffset + theClass->m_PropertySectionByteSize; - QT3DSU32 writeAmount = dataEnd - objOffset; - ioBuffer.write((const QT3DSU8 *)theClass, writeAmount); - ioBuffer.align(4); - QT3DSU32 cmdOffset = 0; - QT3DSU8 *writeCommandStart = NULL; - if (theClass->m_RenderCommands.size()) { - // We know commands are allocated in a block. - const SCommand &firstCommand = *theClass->m_RenderCommands[0]; - const QT3DSU8 *commandStart = reinterpret_cast(&firstCommand); - const SCommand &lastCommand( - *theClass->m_RenderCommands[theClass->m_RenderCommands.size() - 1]); - const QT3DSU8 *commandEnd = reinterpret_cast(&lastCommand) - + SCommand::GetSizeofCommand(lastCommand); - cmdOffset = ioBuffer.size(); - ioBuffer.write(commandStart, (QT3DSU32)(commandEnd - commandStart)); - // Write location of the actual storage for the command ptr array. - ioBuffer.writeZeros(theClass->m_RenderCommands.size() * sizeof(SCommand **)); - } - ioBuffer.align(4); - if (cmdOffset) - writeCommandStart = ioBuffer.begin() + cmdOffset; - - SDynamicObjClassImpl *writeClass = - (SDynamicObjClassImpl *)(ioBuffer.begin() + objOffset); - writeClass->m_Id.Remap(inRemapMap); - writeClass->SetupThisObjectFromMemory(m_Allocator, theRemapper, writeCommandStart, - theClass->m_RenderCommands.size()); - for (QT3DSU32 idx = 0, end = theClass->m_PropertyDefinitions.size(); idx < end; ++idx) { - // Moved into the loop because writing the enumerations may resize the data buffer. - SPropertyDefinition *theDefinitions = - (SPropertyDefinition *)(ioBuffer.begin() + defOffset); - theDefinitions[idx].m_Name.Remap(inRemapMap); - const SPropertyDefinition &theDefinition(theClass->m_PropertyDefinitions[idx]); - if (theDefinitions[idx].m_EnumValueNames.size()) { - QT3DSU32 enumOffset = ioBuffer.size(); - ioBuffer.write(theDefinition.m_EnumValueNames.begin(), - theDefinition.m_EnumValueNames.size() - * sizeof(CRegisteredString)); - CRegisteredString *strPtr = - (CRegisteredString *)(ioBuffer.begin() + enumOffset); - for (QT3DSU32 enumIdx = 0, enumEnd = theDefinition.m_EnumValueNames.size(); - enumIdx < enumEnd; ++enumIdx) - strPtr[enumIdx].Remap(inRemapMap); - } - if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - QT3DSU8 *theDataPtr = ioBuffer.begin() + dataOffset; - CRegisteredString *realData = - reinterpret_cast(theDataPtr + theDefinition.m_Offset); - realData->Remap(inRemapMap); - } - } - } - - // Write out meta information about the shader system - QT3DSU32 numShaderInfos = (QT3DSU32)m_ShaderInfoMap.size(); - ioBuffer.write(numShaderInfos); - for (TShaderInfoMap::const_iterator iter = m_ShaderInfoMap.begin(), - end = m_ShaderInfoMap.end(); - iter != end; ++iter) { - CRegisteredString infoName = iter->first; - infoName.Remap(inRemapMap); - ioBuffer.write(infoName); - const SDynamicObjectShaderInfo &theInfo = iter->second; - CRegisteredString infoType(theInfo.m_Type); - CRegisteredString infoVersion(theInfo.m_Version); - infoType.Remap(inRemapMap); - infoVersion.Remap(inRemapMap); - ioBuffer.write(infoType); - ioBuffer.write(infoVersion); - } - } - - void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t *inProjectDir) override - { - m_Allocator.m_PreAllocatedBlock = inData; - m_Allocator.m_OwnsMemory = false; - TStr workspaceStr(ForwardingAllocator(m_Foundation.getAllocator(), "ProjPath")); - qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); - QT3DSU32 numMappedPaths = theReader.LoadRef(); - for (QT3DSU32 idx = 0, end = numMappedPaths; idx < end; ++idx) { - CRegisteredString theStr(theReader.LoadRef()); - QT3DSU32 theCharLen = theReader.LoadRef(); - char8_t *thePathData = reinterpret_cast(theReader.m_CurrentPtr); - theReader.m_CurrentPtr += theCharLen; - theReader.Align(); - theStr.Remap(inStrDataBlock); - m_ExpandedFiles.insert(eastl::make_pair(theStr, thePathData)); - } - SStringLoadRemapper theRemapper(m_Allocator, inStrDataBlock, inProjectDir, - m_CoreContext.GetStringTable()); - QT3DSU32 numClasses = theReader.LoadRef(); - for (QT3DSU32 idx = 0, end = numClasses; idx < end; ++idx) { - theReader.Align(4); - size_t classOffset = static_cast(theReader.m_CurrentPtr - inData.mData); - (void)classOffset; - SDynamicObjClassImpl *theClass = (SDynamicObjClassImpl *)theReader.m_CurrentPtr; - theClass->m_Allocator = &m_Allocator; - theReader.m_CurrentPtr += sizeof(SDynamicObjClassImpl); - SPropertyDefinition *theDefinitions = (SPropertyDefinition *)theReader.m_CurrentPtr; - theReader.m_CurrentPtr += - theClass->m_PropertyDefinitions.size() * sizeof(SPropertyDefinition); - QT3DSU8 *theDataBuffer = theReader.m_CurrentPtr; - theReader.m_CurrentPtr += theClass->m_PropertySectionByteSize; - theClass->m_Id.Remap(inStrDataBlock); - theClass->m_PropertyDefinitions = NVConstDataRef( - theDefinitions, theClass->m_PropertyDefinitions.size()); - theClass->m_PropertyDefaultData = theDataBuffer; - theReader.Align(4); - QT3DSU8 *theCommandStart = theReader.m_CurrentPtr; - - QT3DSU32 numRenderCommands = theClass->m_RenderCommands.size(); - new (theClass) SDynamicObjClassImpl( - m_Allocator, theClass->m_Id, theClass->m_PropertyDefinitions, - theClass->m_PropertySectionByteSize, theClass->m_BaseObjectSize, - theClass->m_GraphObjectType, theClass->m_PropertyDefaultData, - theClass->m_RequiresDepthTexture, theClass->m_OutputFormat); - - theClass->SetupThisObjectFromMemory(m_Allocator, theRemapper, theCommandStart, - numRenderCommands); - - if (theClass->m_RenderCommands.size()) { - const SCommand &theLastCommand = - *theClass->m_RenderCommands[theClass->m_RenderCommands.size() - 1]; - const QT3DSU8 *theCommandEnd = reinterpret_cast(&theLastCommand) - + SCommand::GetSizeofCommand(theLastCommand); - theReader.m_CurrentPtr = const_cast(theCommandEnd); - theReader.m_CurrentPtr += theClass->m_RenderCommands.size() * sizeof(SCommand **); - } - theReader.Align(4); - - for (QT3DSU32 defIdx = 0, defEnd = theClass->m_PropertyDefinitions.size(); defIdx < defEnd; - ++defIdx) { - SPropertyDefinition &theDef(theDefinitions[defIdx]); - theDef.m_Name.Remap(inStrDataBlock); - if (theDef.m_EnumValueNames.size()) { - CRegisteredString *theNames = (CRegisteredString *)theReader.m_CurrentPtr; - theReader.m_CurrentPtr += - theDef.m_EnumValueNames.size() * sizeof(CRegisteredString); - theDef.m_EnumValueNames = - NVDataRef(theNames, theDef.m_EnumValueNames.size()); - for (QT3DSU32 enumIdx = 0, enumEnd = theDef.m_EnumValueNames.size(); - enumIdx < enumEnd; ++enumIdx) - theNames[enumIdx].Remap(inStrDataBlock); - } - if (theDef.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - CRegisteredString *realData = - reinterpret_cast(theDataBuffer + theDef.m_Offset); - realData->Remap(inStrDataBlock); - } - } - m_Classes.insert(eastl::make_pair(theClass->m_Id, theClass)); - } - QT3DSU32 theNumShaderInfos = theReader.LoadRef(); - for (QT3DSU32 idx = 0, end = theNumShaderInfos; idx < end; ++idx) { - CRegisteredString name, type, version; - name = theReader.LoadRef(); - type = theReader.LoadRef(); - version = theReader.LoadRef(); - name.Remap(inStrDataBlock); - type.Remap(inStrDataBlock); - version.Remap(inStrDataBlock); - SDynamicObjectShaderInfo &theInfo = - m_ShaderInfoMap.insert(eastl::make_pair(name, SDynamicObjectShaderInfo())) - .first->second; - theInfo.m_Type = type; - theInfo.m_Version = version; - } - } - - IDynamicObjectSystem &CreateDynamicSystem(IQt3DSRenderContext &rc) override - { - m_Context = &rc; - return *this; - } - - QStringList getParameters(const QString &str, int begin, int end) - { - const QString s = str.mid(begin, end - begin + 1); - return s.split(","); - } - - void insertSnapperDirectives(QString &str) - { - int beginIndex = 0; - // Snapper macros: - // #define SNAPPER_SAMPLER2D(propName, propNiceName, texFilter, texWrap, showUI ) \ - // uniform sampler2D propName; \ - // uniform int flag##propName; \ - // uniform vec4 propName##Info; \ - // vec4 texture2D_##propName(vec2 uv) \ - // { \ - // return GetTextureValue( propName, uv, propName##Info.z ); \ - // } - // - // #define SNAPPER_SAMPLER2DWITHDEFAULT(propName, propNiceName, texFilter, texWrap, defaultPath, showUI ) \ - // SNAPPER_SAMPLER2D( propName, propNiceName, texFilter, texWrap, showUI ) - // - // #define SNAPPER_SAMPLERCUBE(propName, propNiceName, texFilter, texWrap ) \ - // uniform samplerCube propName; \ - // uniform vec2 propName##UVRange; \ - // uniform int flag##propName; \ - // uniform vec2 propName##Size; - QString snapperSampler = QStringLiteral("SNAPPER_SAMPLER2D("); - QString snapperSamplerDefault = QStringLiteral("SNAPPER_SAMPLER2DWITHDEFAULT("); - QString snapperSamplerCube = QStringLiteral("SNAPPER_SAMPLERCUBE("); - QString endingBracket = QStringLiteral(")"); - - while ((beginIndex = str.indexOf(snapperSampler, beginIndex)) >= 0) { - int endIndex = str.indexOf(endingBracket, beginIndex); - const QStringList list = getParameters(str, beginIndex + snapperSampler.length(), - endIndex); - str.remove(beginIndex, endIndex - beginIndex + 1); - if (list.size() == 5) { - QString insertStr; - QTextStream stream(&insertStr); - stream << "uniform sampler2D " << list[0] << ";\n"; - stream << "uniform int flag" << list[0] << ";\n"; - stream << "vec4 " << list[0] << "Info;\n"; - stream << "vec4 texture2D_" << list[0] << "(vec2 uv) " - << "{ return GetTextureValue( " << list[0] << ", uv, " - << list[0] <<"Info.z ); }\n"; - str.insert(beginIndex, insertStr); - } - } - beginIndex = 0; - while ((beginIndex = str.indexOf(snapperSamplerDefault, beginIndex)) >= 0) { - int endIndex = str.indexOf(endingBracket, beginIndex); - const QStringList list = getParameters(str, beginIndex + snapperSamplerDefault.length(), - endIndex); - str.remove(beginIndex, endIndex - beginIndex + 1); - if (list.size() == 5) { - QString insertStr; - QTextStream stream(&insertStr); - stream << "uniform sampler2D " << list[0] << ";\n"; - stream << "uniform int flag" << list[0] << ";\n"; - stream << "vec4 " << list[0] << "Info;\n"; - stream << "vec4 texture2D_" << list[0] << "(vec2 uv) " - << "{ return GetTextureValue( " << list[0] << ", uv, " - << list[0] <<"Info.z ); }\n"; - str.insert(beginIndex, insertStr); - } - } - beginIndex = 0; - while ((beginIndex = str.indexOf(snapperSamplerCube, beginIndex)) >= 0) { - int endIndex = str.indexOf(endingBracket, beginIndex); - const QStringList list = getParameters(str, beginIndex + snapperSamplerCube.length(), - endIndex); - str.remove(beginIndex, endIndex - beginIndex + 1); - if (list.size() == 4) { - QString insertStr; - QTextStream stream(&insertStr); - stream << "uniform samplerCube " << list[0] << ";\n"; - stream << "uniform vec2 "<< list[0] << "UVRange;\n"; - stream << "uniform int flag" << list[0] << ";\n"; - stream << "uniform vec2 "<< list[0] << "Size;\n"; - str.insert(beginIndex, insertStr); - } - } - } - - NVRenderShaderProgram *CompileShader(CRegisteredString inId, const char8_t *inProgramSource, - const char8_t *inGeomSource, - CRegisteredString inProgramMacroName, - TShaderFeatureSet inFeatureSet, - const dynamic::SDynamicShaderProgramFlags &inFlags, - bool inForceCompilation = false) - { - m_VertShader.clear(); - m_FragShader.clear(); - m_GeometryShader.clear(); - SShaderCacheProgramFlags theFlags; - - m_VertShader.append("#define VERTEX_SHADER\n"); - m_FragShader.append("#define FRAGMENT_SHADER\n"); - - if (inProgramMacroName.IsValid()) { - m_VertShader.append("#define "); - m_VertShader.append(inProgramMacroName.c_str()); - m_VertShader.append("\n"); - - m_FragShader.append("#define "); - m_FragShader.append(inProgramMacroName.c_str()); - m_FragShader.append("\n"); - } - - if (inGeomSource && inFlags.IsGeometryShaderEnabled()) { - theFlags.SetGeometryShaderEnabled(true); - - m_GeometryShader.append("#define GEOMETRY_SHADER 1\n"); - m_GeometryShader.append(inGeomSource); - - m_VertShader.append("#define GEOMETRY_SHADER 1\n"); - } else if (inFlags.IsGeometryShaderEnabled()) { - theFlags.SetGeometryShaderEnabled(true); - m_GeometryShader.append("#define USER_GEOMETRY_SHADER 1\n"); - m_GeometryShader.append(inProgramSource); - m_VertShader.append("#define GEOMETRY_SHADER 0\n"); - m_FragShader.append("#define GEOMETRY_WIREFRAME_SHADER 0\n"); - } else { - m_VertShader.append("#define GEOMETRY_SHADER 0\n"); - m_FragShader.append("#define GEOMETRY_WIREFRAME_SHADER 0\n"); - } - - if (strstr(inProgramSource, "SNAPPER_SAMPLER")) { - QString programSource(inProgramSource); - insertSnapperDirectives(programSource); - QByteArray data = programSource.toLatin1(); - const char *source = data.constData(); - - m_VertShader.append(source); - m_FragShader.append(source); - } else { - m_VertShader.append(inProgramSource); - m_FragShader.append(inProgramSource); - } - - IShaderCache &theShaderCache = m_Context->GetShaderCache(); - - CRegisteredString theKey = m_Context->GetStringTable().RegisterStr( - GetShaderCacheKey(inId, inProgramMacroName, inFlags)); - - if (inForceCompilation) { - return theShaderCache.ForceCompileProgram(theKey, m_VertShader.c_str(), - m_FragShader.c_str(), NULL, NULL, - m_GeometryShader.c_str(), theFlags, - inFeatureSet, false); - } - return theShaderCache.CompileProgram(theKey, m_VertShader.c_str(), m_FragShader.c_str(), - NULL, NULL, m_GeometryShader.c_str(), theFlags, - inFeatureSet); - } - - // This just returns the custom material shader source without compiling - const char8_t *GetShaderSource(CRegisteredString inPath, CRenderString &inBuffer) override - { - inBuffer.clear(); - inBuffer.append("#define FRAGMENT_SHADER\n"); - - const char8_t *source = DoLoadShader(inPath, inBuffer); - return source; - } - - TShaderAndFlags GetShaderProgram(CRegisteredString inPath, - CRegisteredString inProgramMacro, - TShaderFeatureSet inFeatureSet, - const SDynamicShaderProgramFlags &inFlags, - bool inForceCompilation) override - { - eastl::pair theInserter( - SShaderMapKey(TStrStrPair(inPath, inProgramMacro), inFeatureSet, inFlags.m_TessMode, - inFlags.m_WireframeMode), - TShaderAndFlags()); - eastl::pair theInsertResult(m_ShaderMap.insert(theInserter)); - if (theInsertResult.second || inForceCompilation) { - NVRenderShaderProgram *theProgram = m_Context->GetShaderCache().GetProgram( - GetShaderCacheKey(inPath, inProgramMacro, inFlags), inFeatureSet); - SDynamicShaderProgramFlags theFlags(inFlags); - if (!theProgram || inForceCompilation) { - SDynamicObjectShaderInfo &theShaderInfo = - m_ShaderInfoMap.insert(eastl::make_pair(inPath, SDynamicObjectShaderInfo())) - .first->second; - if (theShaderInfo.m_IsComputeShader == false) { - CRenderString theShaderBuffer; - const char8_t *programSource = DoLoadShader(inPath, theShaderBuffer); - if (theShaderInfo.m_HasGeomShader) - theFlags.SetGeometryShaderEnabled(true); - theProgram = CompileShader(inPath, programSource, NULL, inProgramMacro, - inFeatureSet, theFlags, inForceCompilation); - } else { - CRenderString theShaderBuffer; - const char8_t *shaderVersionStr = "#version 430\n"; - if ((QT3DSU32)m_Context->GetRenderContext().GetRenderContextType() - == NVRenderContextValues::GLES3PLUS) - shaderVersionStr = "#version 310 es\n"; - DoLoadShader(inPath, theShaderBuffer); - theShaderBuffer.insert(0, shaderVersionStr); - const char8_t *programSource = theShaderBuffer.c_str(); - QT3DSU32 len = (QT3DSU32)strlen(nonNull(programSource)) + 1; - theProgram = - m_Context->GetRenderContext() - .CompileComputeSource(inPath.c_str(), - NVConstDataRef((QT3DSI8 *)programSource, len)) - .mShader; - } - } - theInsertResult.first->second = TShaderAndFlags(theProgram, theFlags); - } - return theInsertResult.first->second; - } - - TShaderAndFlags GetDepthPrepassShader(CRegisteredString inPath, - CRegisteredString inPMacro, - TShaderFeatureSet inFeatureSet) override - { - SDynamicObjectShaderInfo &theShaderInfo = - m_ShaderInfoMap.insert(eastl::make_pair(inPath, SDynamicObjectShaderInfo())) - .first->second; - if (theShaderInfo.m_HasGeomShader == false) - return TShaderAndFlags(); - // else, here we go... - SDynamicShaderProgramFlags theFlags; - m_ShaderKeyBuilder.assign(inPMacro.c_str()); - m_ShaderKeyBuilder.append("depthprepass"); - - CRegisteredString theProgramMacro = - m_Context->GetStringTable().RegisterStr(m_ShaderKeyBuilder.c_str()); - - eastl::pair theInserter( - SShaderMapKey(TStrStrPair(inPath, theProgramMacro), inFeatureSet, theFlags.m_TessMode, - theFlags.m_WireframeMode), - TShaderAndFlags()); - eastl::pair theInsertResult(m_ShaderMap.insert(theInserter)); - if (theInsertResult.second) { - NVRenderShaderProgram *theProgram = m_Context->GetShaderCache().GetProgram( - GetShaderCacheKey(inPath, theProgramMacro, theFlags), inFeatureSet); - SDynamicShaderProgramFlags flags(theFlags); - if (!theProgram) { - CRenderString theShaderBuffer; - const char8_t *geomSource = DoLoadShader(inPath, theShaderBuffer); - SShaderVertexCodeGenerator vertexShader( - m_Context->GetStringTable(), m_Allocator, - m_Context->GetRenderContext().GetRenderContextType()); - SShaderFragmentCodeGenerator fragmentShader( - vertexShader, m_Allocator, - m_Context->GetRenderContext().GetRenderContextType()); - - vertexShader.AddAttribute("attr_pos", "vec3"); - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader.Append("void main() {"); - vertexShader.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - vertexShader.Append("}"); - fragmentShader.Append("void main() {"); - fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); - fragmentShader.Append("}"); - const char8_t *vertexSource = vertexShader.BuildShaderSource(); - const char8_t *fragmentSource = fragmentShader.BuildShaderSource(); - - CRenderString programBuffer; - programBuffer.assign("#ifdef VERTEX_SHADER\n"); - programBuffer.append(vertexSource); - programBuffer.append("\n#endif\n"); - programBuffer.append("\n#ifdef FRAGMENT_SHADER\n"); - programBuffer.append(fragmentSource); - programBuffer.append("\n#endif"); - flags.SetGeometryShaderEnabled(true); - theProgram = CompileShader(inPath, programBuffer.c_str(), geomSource, - theProgramMacro, inFeatureSet, flags); - } - theInsertResult.first->second = TShaderAndFlags(theProgram, flags); - } - return theInsertResult.first->second; - } - - virtual void setShaderCodeLibraryPlatformDirectory(const QString &directory) override - { - m_shaderLibraryPlatformDirectory = directory; - } - - virtual QString shaderCodeLibraryPlatformDirectory() override - { - return m_shaderLibraryPlatformDirectory; - } -}; -} - -IDynamicObjectSystemCore & -IDynamicObjectSystemCore::CreateDynamicSystemCore(IQt3DSRenderContextCore &rc) -{ - return *QT3DS_NEW(rc.GetAllocator(), SDynamicObjectSystemImpl)(rc); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEffectSystem.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEffectSystem.cpp deleted file mode 100644 index d86c100d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEffectSystem.cpp +++ /dev/null @@ -1,1847 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderEffectSystem.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderString.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSRenderEffect.h" -#include "Qt3DSRenderResourceManager.h" -#include "Qt3DSRenderDynamicObjectSystemCommands.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderShaderConstant.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSOffscreenRenderManager.h" -#include "foundation/PreAllocatedAllocator.h" -#include "foundation/SerializationTypes.h" -#include "Qt3DSRenderShaderCache.h" -#include "foundation/FileTools.h" -#include "Qt3DSOffscreenRenderKey.h" -#include "Qt3DSRenderDynamicObjectSystemUtil.h" - -using namespace qt3ds::render; -using namespace qt3ds::render::dynamic; -using qt3ds::render::NVRenderContextScopedProperty; -using qt3ds::render::NVRenderCachedShaderProperty; -using qt3ds::render::NVRenderCachedShaderBuffer; - -// None of this code will work if the size of void* changes because that would mean that -// the alignment of some of the objects isn't 4 bytes but would be 8 bytes. - -typedef eastl::pair TStrStrPair; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const TStrStrPair &item) const - { - return hash()(item.first) ^ hash()(item.second); - } -}; -} - -namespace { - -/* - ApplyBufferValue, - //Apply the depth buffer as an input texture. - ApplyDepthValue, - Render, //Render to current FBO - */ - -struct SEffectClass -{ - NVAllocatorCallback *m_Allocator; - IDynamicObjectClass *m_DynamicClass; - volatile QT3DSI32 mRefCount; - - SEffectClass(NVAllocatorCallback &inFnd, IDynamicObjectClass &dynClass) - : m_Allocator(&inFnd) - , m_DynamicClass(&dynClass) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator) - - void SetupThisObjectFromMemory(NVAllocatorCallback &inAlloc, IDynamicObjectClass &inClass) - { - m_Allocator = &inAlloc; - m_DynamicClass = &inClass; - mRefCount = 0; - } -}; - -struct SAllocatedBufferEntry -{ - CRegisteredString m_Name; - NVScopedRefCounted m_FrameBuffer; - NVScopedRefCounted m_Texture; - SAllocateBufferFlags m_Flags; - bool m_NeedsClear; - - SAllocatedBufferEntry(CRegisteredString inName, NVRenderFrameBuffer &inFb, - NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags) - : m_Name(inName) - , m_FrameBuffer(&inFb) - , m_Texture(&inTexture) - , m_Flags(inFlags) - , m_NeedsClear(true) - { - } - SAllocatedBufferEntry() {} -}; - -struct SAllocatedImageEntry -{ - CRegisteredString m_Name; - NVScopedRefCounted m_Image; - NVScopedRefCounted m_Texture; - SAllocateBufferFlags m_Flags; - - SAllocatedImageEntry(CRegisteredString inName, NVRenderImage2D &inImage, - NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags) - : m_Name(inName) - , m_Image(&inImage) - , m_Texture(&inTexture) - , m_Flags(inFlags) - { - } - SAllocatedImageEntry() {} -}; - -struct SImageEntry -{ - NVScopedRefCounted m_Shader; - NVRenderCachedShaderProperty m_Image; - volatile QT3DSI32 mRefCount; - - SImageEntry(NVRenderShaderProgram &inShader, const char *inImageName) - : m_Shader(inShader) - , m_Image(inImageName, inShader) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) - - void Set(NVRenderImage2D *inImage) { m_Image.Set(inImage); } - - static SImageEntry CreateImageEntry(NVRenderShaderProgram &inShader, const char *inStem) - { - return SImageEntry(inShader, inStem); - } -}; - -struct SAllocatedDataBufferEntry -{ - CRegisteredString m_Name; - NVScopedRefCounted m_DataBuffer; - NVRenderBufferBindValues::Enum m_BufferType; - NVDataRef m_BufferData; - SAllocateBufferFlags m_Flags; - bool m_NeedsClear; - - SAllocatedDataBufferEntry(CRegisteredString inName, - qt3ds::render::NVRenderDataBuffer &inDataBuffer, - NVRenderBufferBindValues::Enum inType, NVDataRef data, - SAllocateBufferFlags inFlags) - : m_Name(inName) - , m_DataBuffer(&inDataBuffer) - , m_BufferType(inType) - , m_BufferData(data) - , m_Flags(inFlags) - , m_NeedsClear(false) - { - } - SAllocatedDataBufferEntry() {} -}; - -struct SDataBufferEntry -{ - NVScopedRefCounted m_Shader; - NVRenderCachedShaderBuffer m_DataBuffer; - volatile QT3DSI32 mRefCount; - - SDataBufferEntry(NVRenderShaderProgram &inShader, const char *inBufferName) - : m_Shader(inShader) - , m_DataBuffer(inBufferName, inShader) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) - - void Set(qt3ds::render::NVRenderDataBuffer *inBuffer) - { - if (inBuffer) - inBuffer->Bind(); - - m_DataBuffer.Set(); - } - - static SDataBufferEntry CreateDataBufferEntry(NVRenderShaderProgram &inShader, - const char *inStem) - { - return SDataBufferEntry(inShader, inStem); - } -}; - -struct SEffectTextureData -{ - NVRenderTexture2D *m_Texture; - bool m_NeedsAlphaMultiply; - SEffectTextureData(NVRenderTexture2D *inTexture, bool inNeedsMultiply) - : m_Texture(inTexture) - , m_NeedsAlphaMultiply(inNeedsMultiply) - { - } - SEffectTextureData() - : m_Texture(NULL) - , m_NeedsAlphaMultiply(false) - { - } -}; - -struct STextureEntry -{ - NVScopedRefCounted m_Shader; - NVRenderCachedShaderProperty m_Texture; - NVRenderCachedShaderProperty m_TextureData; - NVRenderCachedShaderProperty m_TextureFlags; - volatile QT3DSI32 mRefCount; - - STextureEntry(NVRenderShaderProgram &inShader, const char *inTexName, const char *inDataName, - const char *inFlagName) - : m_Shader(inShader) - , m_Texture(inTexName, inShader) - , m_TextureData(inDataName, inShader) - , m_TextureFlags(inFlagName, inShader) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) - - void Set(NVRenderTexture2D *inTexture, bool inNeedsAlphaMultiply, - const SPropertyDefinition *inDefinition) - { - QT3DSF32 theMixValue(inNeedsAlphaMultiply ? 0.0f : 1.0f); - if (inTexture && inDefinition) { - inTexture->SetMagFilter(inDefinition->m_MagFilterOp); - inTexture->SetMinFilter( - static_cast(inDefinition->m_MagFilterOp)); - inTexture->SetTextureWrapS(inDefinition->m_CoordOp); - inTexture->SetTextureWrapT(inDefinition->m_CoordOp); - } - m_Texture.Set(inTexture); - if (inTexture) { - STextureDetails theDetails(inTexture->GetTextureDetails()); - m_TextureData.Set( - QT3DSVec4((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height, theMixValue, 0.0f)); - // I have no idea what these flags do. - m_TextureFlags.Set(1); - } else - m_TextureFlags.Set(0); - } - - static STextureEntry CreateTextureEntry(NVRenderShaderProgram &inShader, const char *inStem, - CRenderString &inBuilder, CRenderString &inBuilder2) - { - inBuilder.assign(inStem); - inBuilder.append("Info"); - inBuilder2.assign("flag"); - inBuilder2.append(inStem); - return STextureEntry(inShader, inStem, inBuilder.c_str(), inBuilder2.c_str()); - } -}; - -typedef eastl::pair> TNamedTextureEntry; -typedef eastl::pair> TNamedImageEntry; -typedef eastl::pair> TNamedDataBufferEntry; -} - -namespace qt3ds { -namespace render { - - struct SEffectContext - { - CRegisteredString m_ClassName; - IQt3DSRenderContext &m_Context; - IResourceManager *m_ResourceManager; - nvvector m_AllocatedBuffers; - nvvector m_AllocatedImages; - nvvector m_AllocatedDataBuffers; - nvvector m_TextureEntries; - nvvector m_ImageEntries; - nvvector m_DataBufferEntries; - - SEffectContext(CRegisteredString inName, IQt3DSRenderContext &ctx, IResourceManager *inManager) - : m_ClassName(inName) - , m_Context(ctx) - , m_ResourceManager(inManager) - , m_AllocatedBuffers(ctx.GetAllocator(), "SEffectContext::m_AllocatedBuffers") - , m_AllocatedImages(ctx.GetAllocator(), "SEffectContext::m_AllocatedImages") - , m_AllocatedDataBuffers(ctx.GetAllocator(), "SEffectContext::m_AllocatedDataBuffers") - , m_TextureEntries(ctx.GetAllocator(), "SEffectContext::m_TextureEntries") - , m_ImageEntries(ctx.GetAllocator(), "SEffectContext::m_ImageEntries") - , m_DataBufferEntries(ctx.GetAllocator(), "SEffectContext::m_DataBufferEntries") - { - } - - ~SEffectContext() - { - while (m_AllocatedBuffers.size()) - ReleaseBuffer(0); - - while (m_AllocatedImages.size()) - ReleaseImage(0); - - while (m_AllocatedDataBuffers.size()) - ReleaseDataBuffer(0); - } - - void ReleaseBuffer(QT3DSU32 inIdx) - { - SAllocatedBufferEntry &theEntry(m_AllocatedBuffers[inIdx]); - theEntry.m_FrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer()); - m_ResourceManager->Release(*theEntry.m_FrameBuffer); - m_ResourceManager->Release(*theEntry.m_Texture); - m_AllocatedBuffers.replace_with_last(inIdx); - } - - void ReleaseImage(QT3DSU32 inIdx) - { - SAllocatedImageEntry &theEntry(m_AllocatedImages[inIdx]); - m_ResourceManager->Release(*theEntry.m_Image); - m_ResourceManager->Release(*theEntry.m_Texture); - m_AllocatedImages.replace_with_last(inIdx); - } - - void ReleaseDataBuffer(QT3DSU32 inIdx) - { - SAllocatedDataBufferEntry &theEntry(m_AllocatedDataBuffers[inIdx]); - m_Context.GetAllocator().deallocate(theEntry.m_BufferData.begin()); - - m_AllocatedDataBuffers.replace_with_last(inIdx); - } - - QT3DSU32 FindBuffer(CRegisteredString inName) - { - for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx) - if (m_AllocatedBuffers[idx].m_Name == inName) - return idx; - return m_AllocatedBuffers.size(); - } - - QT3DSU32 FindImage(CRegisteredString inName) - { - for (QT3DSU32 idx = 0, end = m_AllocatedImages.size(); idx < end; ++idx) - if (m_AllocatedImages[idx].m_Name == inName) - return idx; - - return m_AllocatedImages.size(); - } - - QT3DSU32 FindDataBuffer(CRegisteredString inName) - { - for (QT3DSU32 idx = 0, end = m_AllocatedDataBuffers.size(); idx < end; ++idx) { - if (m_AllocatedDataBuffers[idx].m_Name == inName) - return idx; - } - - return m_AllocatedDataBuffers.size(); - } - - void SetTexture(NVRenderShaderProgram &inShader, CRegisteredString inPropName, - NVRenderTexture2D *inTexture, bool inNeedsMultiply, - CRenderString &inStringBuilder, CRenderString &inStringBuilder2, - const SPropertyDefinition *inPropDec = NULL) - { - STextureEntry *theTextureEntry(NULL); - for (QT3DSU32 idx = 0, end = m_TextureEntries.size(); idx < end && theTextureEntry == NULL; - ++idx) { - if (m_TextureEntries[idx].first == inPropName - && m_TextureEntries[idx].second->m_Shader.mPtr == &inShader) - theTextureEntry = m_TextureEntries[idx].second; - } - if (theTextureEntry == NULL) { - NVScopedRefCounted theNewEntry = QT3DS_NEW( - m_Context.GetAllocator(), STextureEntry)(STextureEntry::CreateTextureEntry( - inShader, inPropName, inStringBuilder, inStringBuilder2)); - m_TextureEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); - theTextureEntry = theNewEntry.mPtr; - } - theTextureEntry->Set(inTexture, inNeedsMultiply, inPropDec); - } - - void SetImage(NVRenderShaderProgram &inShader, CRegisteredString inPropName, - NVRenderImage2D *inImage) - { - SImageEntry *theImageEntry(NULL); - for (QT3DSU32 idx = 0, end = m_ImageEntries.size(); idx < end && theImageEntry == NULL; - ++idx) { - if (m_ImageEntries[idx].first == inPropName - && m_ImageEntries[idx].second->m_Shader.mPtr == &inShader) - theImageEntry = m_ImageEntries[idx].second; - } - if (theImageEntry == NULL) { - NVScopedRefCounted theNewEntry = - QT3DS_NEW(m_Context.GetAllocator(), - SImageEntry)(SImageEntry::CreateImageEntry(inShader, inPropName)); - m_ImageEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); - theImageEntry = theNewEntry.mPtr; - } - - theImageEntry->Set(inImage); - } - - void SetDataBuffer(NVRenderShaderProgram &inShader, CRegisteredString inPropName, - qt3ds::render::NVRenderDataBuffer *inBuffer) - { - SDataBufferEntry *theDataBufferEntry(NULL); - for (QT3DSU32 idx = 0, end = m_DataBufferEntries.size(); - idx < end && theDataBufferEntry == NULL; ++idx) { - if (m_DataBufferEntries[idx].first == inPropName - && m_DataBufferEntries[idx].second->m_Shader.mPtr == &inShader) - theDataBufferEntry = m_DataBufferEntries[idx].second; - } - if (theDataBufferEntry == NULL) { - NVScopedRefCounted theNewEntry = - QT3DS_NEW(m_Context.GetAllocator(), SDataBufferEntry)( - SDataBufferEntry::CreateDataBufferEntry(inShader, inPropName)); - m_DataBufferEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); - theDataBufferEntry = theNewEntry.mPtr; - } - - theDataBufferEntry->Set(inBuffer); - } - }; -} -} - -namespace { - -using qt3ds::render::NVRenderCachedShaderProperty; -/* We setup some shared state on the effect shaders */ -struct SEffectShader -{ - NVScopedRefCounted m_Shader; - NVRenderCachedShaderProperty m_MVP; - NVRenderCachedShaderProperty m_FragColorAlphaSettings; - NVRenderCachedShaderProperty m_DestSize; - NVRenderCachedShaderProperty m_AppFrame; - NVRenderCachedShaderProperty m_FPS; - NVRenderCachedShaderProperty m_CameraClipRange; - STextureEntry m_TextureEntry; - volatile QT3DSI32 mRefCount; - SEffectShader(NVRenderShaderProgram &inShader) - : m_Shader(inShader) - , m_MVP("ModelViewProjectionMatrix", inShader) - , m_FragColorAlphaSettings("FragColorAlphaSettings", inShader) - , m_DestSize("DestSize", inShader) - , m_AppFrame("AppFrame", inShader) - , m_FPS("FPS", inShader) - , m_CameraClipRange("CameraClipRange", inShader) - , m_TextureEntry(inShader, "Texture0", "Texture0Info", "Texture0Flags") - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) -}; - -struct SEffectSystem : public IEffectSystem -{ - typedef nvhash_map TPathDataMap; - typedef nvhash_set TPathSet; - typedef nvhash_map> TEffectClassMap; - typedef nvhash_map> TShaderMap; - typedef nvvector TContextList; - - IQt3DSRenderContextCore &m_CoreContext; - IQt3DSRenderContext *m_Context; - NVScopedRefCounted m_ResourceManager; - mutable qt3ds::render::SPreAllocatedAllocator m_Allocator; - // Keep from dual-including headers. - TEffectClassMap m_EffectClasses; - nvvector m_EffectList; - TContextList m_Contexts; - CRenderString m_TextureStringBuilder; - CRenderString m_TextureStringBuilder2; - TShaderMap m_ShaderMap; - NVScopedRefCounted m_DefaultStencilState; - nvvector> m_DepthStencilStates; - volatile QT3DSI32 mRefCount; - - SEffectSystem(IQt3DSRenderContextCore &inContext) - : m_CoreContext(inContext) - , m_Context(NULL) - , m_Allocator(inContext.GetAllocator()) - , m_EffectClasses(inContext.GetAllocator(), "SEffectSystem::m_EffectClasses") - , m_EffectList(inContext.GetAllocator(), "SEffectSystem::m_EffectList") - , m_Contexts(inContext.GetAllocator(), "SEffectSystem::m_Contexts") - , m_ShaderMap(inContext.GetAllocator(), "SEffectSystem::m_ShaderMap") - , m_DepthStencilStates(inContext.GetAllocator(), "SEffectSystem::m_DepthStencilStates") - , mRefCount(0) - { - } - - ~SEffectSystem() - { - for (QT3DSU32 idx = 0, end = m_Contexts.size(); idx < end; ++idx) - NVDelete(m_Allocator, m_Contexts[idx]); - m_Contexts.clear(); - } - - SEffectContext &GetEffectContext(SEffect &inEffect) - { - if (inEffect.m_Context == NULL) { - inEffect.m_Context = - QT3DS_NEW(m_Allocator, SEffectContext)(inEffect.m_ClassName, - *m_Context, m_ResourceManager); - m_Contexts.push_back(inEffect.m_Context); - } - return *inEffect.m_Context; - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_CoreContext.GetAllocator()); - - SEffectClass *GetEffectClass(CRegisteredString inStr) - { - TEffectClassMap::iterator theIter = m_EffectClasses.find(inStr); - if (theIter != m_EffectClasses.end()) - return theIter->second; - return NULL; - } - const SEffectClass *GetEffectClass(CRegisteredString inStr) const - { - return const_cast(this)->GetEffectClass(inStr); - } - - bool IsEffectRegistered(CRegisteredString inStr) override - { - return GetEffectClass(inStr) != NULL; - } - NVConstDataRef GetRegisteredEffects() override - { - m_EffectList.clear(); - for (TEffectClassMap::iterator theIter = m_EffectClasses.begin(), - theEnd = m_EffectClasses.end(); - theIter != theEnd; ++theIter) - m_EffectList.push_back(theIter->first); - return m_EffectList; - } - - // Registers an effect that runs via a single GLSL file. - bool RegisterGLSLEffect(CRegisteredString inName, const char8_t *inPathToEffect, - NVConstDataRef inProperties) override - { - if (IsEffectRegistered(inName)) - return false; - - m_CoreContext.GetDynamicObjectSystemCore().Register(inName, inProperties, sizeof(SEffect), - GraphObjectTypes::Effect); - IDynamicObjectClass &theClass = - *m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); - - SEffectClass *theEffect = QT3DS_NEW(m_Allocator, SEffectClass)(m_Allocator, theClass); - m_EffectClasses.insert(eastl::make_pair(inName, theEffect)); - - // Setup the commands required to run this effect - StaticAssert<(sizeof(SBindShader) % 4 == 0)>::valid_expression(); - StaticAssert<(sizeof(SApplyInstanceValue) % 4 == 0)>::valid_expression(); - StaticAssert<(sizeof(SRender) % 4 == 0)>::valid_expression(); - - QT3DSU32 commandAllocationSize = sizeof(SBindTarget); - commandAllocationSize += sizeof(SBindShader); - commandAllocationSize += sizeof(SApplyInstanceValue) * inProperties.size(); - commandAllocationSize += sizeof(SRender); - - QT3DSU32 commandCount = 3 + inProperties.size(); - QT3DSU32 commandPtrAllocationSize = commandCount * sizeof(SCommand *); - QT3DSU32 allocationSize = Align8(commandAllocationSize) + commandPtrAllocationSize; - QT3DSU8 *startBuffer = - (QT3DSU8 *)m_Allocator.allocate(allocationSize, "dynamic::SCommand", __FILE__, __LINE__); - QT3DSU8 *dataBuffer = startBuffer; - // Setup the command buffer such that the ptrs to the commands and the commands themselves - // are - // all in the same block of memory. This enables quicker iteration (trivially quicker, most - // likely) - // but it also enables simpler memory management (single free). - // Furthermore, for a single glsl file the effect properties map precisely into the - // glsl file itself. - SCommand **theFirstCommandPtr = - (reinterpret_cast(dataBuffer + Align8(commandAllocationSize))); - SCommand **theCommandPtr = theFirstCommandPtr; - memZero(dataBuffer, commandAllocationSize); - - new (dataBuffer) SBindTarget(); - *theCommandPtr = (SCommand *)dataBuffer; - ++theCommandPtr; - dataBuffer += sizeof(SBindTarget); - - new (dataBuffer) SBindShader(m_CoreContext.GetStringTable().RegisterStr(inPathToEffect)); - *theCommandPtr = (SCommand *)dataBuffer; - ++theCommandPtr; - dataBuffer += sizeof(SBindShader); - - for (QT3DSU32 idx = 0, end = inProperties.size(); idx < end; ++idx) { - const SPropertyDefinition &theDefinition( - theEffect->m_DynamicClass->GetProperties()[idx]); - new (dataBuffer) SApplyInstanceValue(theDefinition.m_Name, theDefinition.m_DataType, - theDefinition.m_Offset); - *theCommandPtr = (SCommand *)dataBuffer; - ++theCommandPtr; - dataBuffer += sizeof(SApplyInstanceValue); - } - new (dataBuffer) SRender(false); - *theCommandPtr = (SCommand *)dataBuffer; - ++theCommandPtr; - dataBuffer += sizeof(SRender); - // Ensure we end up *exactly* where we expected to. - QT3DS_ASSERT(dataBuffer == startBuffer + commandAllocationSize); - QT3DS_ASSERT(theCommandPtr - theFirstCommandPtr == (int)inProperties.size() + 3); - m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands( - inName, NVConstDataRef(theFirstCommandPtr, commandCount)); - m_Allocator.deallocate(startBuffer); - return true; - } - - void SetEffectPropertyDefaultValue(CRegisteredString inName, - CRegisteredString inPropName, - NVConstDataRef inDefaultData) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetPropertyDefaultValue(inName, inPropName, - inDefaultData); - } - - void SetEffectPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, - NVConstDataRef inNames) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetPropertyEnumNames(inName, inPropName, - inNames); - } - - bool RegisterEffect(CRegisteredString inName, - NVConstDataRef inProperties) override - { - if (IsEffectRegistered(inName)) - return false; - m_CoreContext.GetDynamicObjectSystemCore().Register(inName, inProperties, sizeof(SEffect), - GraphObjectTypes::Effect); - IDynamicObjectClass &theClass = - *m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); - SEffectClass *theEffect = QT3DS_NEW(m_Allocator, SEffectClass)(m_Allocator, theClass); - m_EffectClasses.insert(eastl::make_pair(inName, theEffect)); - return true; - } - - bool UnregisterEffect(CRegisteredString inName) override - { - if (!IsEffectRegistered(inName)) - return false; - - m_CoreContext.GetDynamicObjectSystemCore().Unregister(inName); - - TEffectClassMap::iterator iter = m_EffectClasses.find(inName); - if (iter != m_EffectClasses.end()) - m_EffectClasses.erase(iter); - - for (QT3DSU32 idx = 0, end = m_Contexts.size(); idx < end; ++idx) { - if (m_Contexts[idx]->m_ClassName == inName) - ReleaseEffectContext(m_Contexts[idx]); - } - return true; - } - - virtual NVConstDataRef - GetEffectPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName) const override - { - const SEffectClass *theClass = GetEffectClass(inName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - NVConstDataRef(); - } - const SPropertyDefinition *theDefinitionPtr = - theClass->m_DynamicClass->FindPropertyByName(inPropName); - if (theDefinitionPtr) - return theDefinitionPtr->m_EnumValueNames; - return NVConstDataRef(); - } - - virtual NVConstDataRef - GetEffectProperties(CRegisteredString inEffectName) const override - { - const SEffectClass *theClass = GetEffectClass(inEffectName); - if (theClass) - return theClass->m_DynamicClass->GetProperties(); - return NVConstDataRef(); - } - - void SetEffectPropertyTextureSettings(CRegisteredString inName, - CRegisteredString inPropName, - CRegisteredString inPropPath, - NVRenderTextureTypeValue::Enum inTexType, - NVRenderTextureCoordOp::Enum inCoordOp, - NVRenderTextureMagnifyingOp::Enum inMagFilterOp, - NVRenderTextureMinifyingOp::Enum inMinFilterOp) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetPropertyTextureSettings( - inName, inPropName, inPropPath, inTexType, inCoordOp, inMagFilterOp, inMinFilterOp); - } - - void SetEffectRequiresDepthTexture(CRegisteredString inEffectName, bool inValue) override - { - SEffectClass *theClass = GetEffectClass(inEffectName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - theClass->m_DynamicClass->SetRequiresDepthTexture(inValue); - } - - bool DoesEffectRequireDepthTexture(CRegisteredString inEffectName) const override - { - const SEffectClass *theClass = GetEffectClass(inEffectName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - return false; - } - return theClass->m_DynamicClass->RequiresDepthTexture(); - } - - void SetEffectRequiresCompilation(CRegisteredString inEffectName, bool inValue) override - { - SEffectClass *theClass = GetEffectClass(inEffectName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - return; - } - theClass->m_DynamicClass->SetRequiresCompilation(inValue); - } - - bool DoesEffectRequireCompilation(CRegisteredString inEffectName) const override - { - const SEffectClass *theClass = GetEffectClass(inEffectName); - if (theClass == NULL) { - QT3DS_ASSERT(false); - return false; - } - return theClass->m_DynamicClass->RequiresCompilation(); - } - - void SetEffectCommands(CRegisteredString inEffectName, - NVConstDataRef inCommands) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands(inEffectName, inCommands); - } - - virtual NVConstDataRef - GetEffectCommands(CRegisteredString inEffectName) const override - { - return m_CoreContext.GetDynamicObjectSystemCore().GetRenderCommands(inEffectName); - } - - SEffect *CreateEffectInstance(CRegisteredString inEffectName, - NVAllocatorCallback &inSceneGraphAllocator) override - { - SEffectClass *theClass = GetEffectClass(inEffectName); - if (theClass == NULL) - return NULL; - StaticAssert<(sizeof(SEffect) % 4 == 0)>::valid_expression(); - - SEffect *theEffect = (SEffect *)m_CoreContext.GetDynamicObjectSystemCore().CreateInstance( - inEffectName, inSceneGraphAllocator); - theEffect->Initialize(); - return theEffect; - } - - void AllocateBuffer(SEffect &inEffect, const SAllocateBuffer &inCommand, QT3DSU32 inFinalWidth, - QT3DSU32 inFinalHeight, NVRenderTextureFormats::Enum inSourceTextureFormat) - { - // Check to see if it is already allocated and if it is, is it the correct size. If both of - // these assumptions hold, then we are good. - NVRenderTexture2D *theBufferTexture = NULL; - QT3DSU32 theWidth = - ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalWidth * inCommand.m_SizeMultiplier)); - QT3DSU32 theHeight = - ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalHeight * inCommand.m_SizeMultiplier)); - NVRenderTextureFormats::Enum resultFormat = inCommand.m_Format; - if (resultFormat == NVRenderTextureFormats::Unknown) - resultFormat = inSourceTextureFormat; - - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - // size intentionally requiried every loop; - QT3DSU32 bufferIdx = theContext.FindBuffer(inCommand.m_Name); - if (bufferIdx < theContext.m_AllocatedBuffers.size()) { - SAllocatedBufferEntry &theEntry(theContext.m_AllocatedBuffers[bufferIdx]); - STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails(); - if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight - && theDetails.m_Format == resultFormat) { - theBufferTexture = theEntry.m_Texture; - } else { - theContext.ReleaseBuffer(bufferIdx); - } - } - } - if (theBufferTexture == NULL) { - SEffectContext &theContext(GetEffectContext(inEffect)); - NVRenderFrameBuffer *theFB(m_ResourceManager->AllocateFrameBuffer()); - NVRenderTexture2D *theTexture( - m_ResourceManager->AllocateTexture2D(theWidth, theHeight, resultFormat)); - theTexture->SetMagFilter(inCommand.m_FilterOp); - theTexture->SetMinFilter( - static_cast(inCommand.m_FilterOp)); - theTexture->SetTextureWrapS(inCommand.m_TexCoordOp); - theTexture->SetTextureWrapT(inCommand.m_TexCoordOp); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *theTexture); - theContext.m_AllocatedBuffers.push_back(SAllocatedBufferEntry( - inCommand.m_Name, *theFB, *theTexture, inCommand.m_BufferFlags)); - theBufferTexture = theTexture; - } - } - - void AllocateImage(SEffect &inEffect, const SAllocateImage &inCommand, QT3DSU32 inFinalWidth, - QT3DSU32 inFinalHeight) - { - NVRenderImage2D *theImage = NULL; - QT3DSU32 theWidth = - ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalWidth * inCommand.m_SizeMultiplier)); - QT3DSU32 theHeight = - ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalHeight * inCommand.m_SizeMultiplier)); - - QT3DS_ASSERT(inCommand.m_Format != NVRenderTextureFormats::Unknown); - - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - // size intentionally requiried every loop; - QT3DSU32 imageIdx = theContext.FindImage(inCommand.m_Name); - if (imageIdx < theContext.m_AllocatedImages.size()) { - SAllocatedImageEntry &theEntry(theContext.m_AllocatedImages[imageIdx]); - STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails(); - if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight - && theDetails.m_Format == inCommand.m_Format) { - theImage = theEntry.m_Image; - } else { - theContext.ReleaseImage(imageIdx); - } - } - } - - if (theImage == NULL) { - SEffectContext &theContext(GetEffectContext(inEffect)); - // allocate an immutable texture - NVRenderTexture2D *theTexture(m_ResourceManager->AllocateTexture2D( - theWidth, theHeight, inCommand.m_Format, 1, true)); - theTexture->SetMagFilter(inCommand.m_FilterOp); - theTexture->SetMinFilter( - static_cast(inCommand.m_FilterOp)); - theTexture->SetTextureWrapS(inCommand.m_TexCoordOp); - theTexture->SetTextureWrapT(inCommand.m_TexCoordOp); - NVRenderImage2D *theImage = - (m_ResourceManager->AllocateImage2D(theTexture, inCommand.m_Access)); - theContext.m_AllocatedImages.push_back(SAllocatedImageEntry( - inCommand.m_Name, *theImage, *theTexture, inCommand.m_BufferFlags)); - } - } - - void AllocateDataBuffer(SEffect &inEffect, const SAllocateDataBuffer &inCommand) - { - QT3DSU32 theBufferSize = (QT3DSU32)inCommand.m_Size; - QT3DS_ASSERT(theBufferSize); - qt3ds::render::NVRenderDataBuffer *theDataBuffer = NULL; - qt3ds::render::NVRenderDataBuffer *theDataWrapBuffer = NULL; - - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - // size intentionally requiried every loop; - QT3DSU32 bufferIdx = theContext.FindDataBuffer(inCommand.m_Name); - if (bufferIdx < theContext.m_AllocatedDataBuffers.size()) { - SAllocatedDataBufferEntry &theEntry(theContext.m_AllocatedDataBuffers[bufferIdx]); - if (theEntry.m_BufferType == inCommand.m_DataBufferType - && theEntry.m_BufferData.size() == theBufferSize) { - theDataBuffer = theEntry.m_DataBuffer; - } else { - // if type and size don't match something is wrong - QT3DS_ASSERT(false); - } - } - } - - if (theDataBuffer == NULL) { - SEffectContext &theContext(GetEffectContext(inEffect)); - NVRenderContext &theRenderContext(m_Context->GetRenderContext()); - QT3DSU8 *initialData = (QT3DSU8 *)theContext.m_Context.GetAllocator().allocate( - theBufferSize, "SEffectContext::AllocateDataBuffer", __FILE__, __LINE__); - NVDataRef data((QT3DSU8 *)initialData, theBufferSize); - memset(initialData, 0x0L, theBufferSize); - if (inCommand.m_DataBufferType == NVRenderBufferBindValues::Storage) { - theDataBuffer = theRenderContext.CreateStorageBuffer( - inCommand.m_Name, qt3ds::render::NVRenderBufferUsageType::Dynamic, theBufferSize, - data, NULL); - } else if (inCommand.m_DataBufferType == NVRenderBufferBindValues::Draw_Indirect) { - QT3DS_ASSERT(theBufferSize == sizeof(qt3ds::render::DrawArraysIndirectCommand)); - // init a draw call - QT3DSU32 *pIndirectDrawCall = (QT3DSU32 *)initialData; - // vertex count we draw points right now only - // the rest we fill in by GPU - pIndirectDrawCall[0] = 1; - theDataBuffer = theRenderContext.CreateDrawIndirectBuffer( - qt3ds::render::NVRenderBufferUsageType::Dynamic, theBufferSize, data); - } else - QT3DS_ASSERT(false); - - theContext.m_AllocatedDataBuffers.push_back(SAllocatedDataBufferEntry( - inCommand.m_Name, *theDataBuffer, inCommand.m_DataBufferType, data, - inCommand.m_BufferFlags)); - - // create wrapper buffer - if (inCommand.m_DataBufferWrapType == NVRenderBufferBindValues::Storage - && inCommand.m_WrapName && theDataBuffer) { - theDataWrapBuffer = theRenderContext.CreateStorageBuffer( - inCommand.m_WrapName, qt3ds::render::NVRenderBufferUsageType::Dynamic, - theBufferSize, data, theDataBuffer); - theContext.m_AllocatedDataBuffers.push_back(SAllocatedDataBufferEntry( - inCommand.m_WrapName, *theDataWrapBuffer, inCommand.m_DataBufferWrapType, - NVDataRef(), inCommand.m_BufferFlags)); - } - } - } - - NVRenderTexture2D *FindTexture(SEffect &inEffect, CRegisteredString inName) - { - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - QT3DSU32 bufferIdx = theContext.FindBuffer(inName); - if (bufferIdx < theContext.m_AllocatedBuffers.size()) { - return theContext.m_AllocatedBuffers[bufferIdx].m_Texture; - } - } - QT3DS_ASSERT(false); - return NULL; - } - - NVRenderFrameBuffer *BindBuffer(SEffect &inEffect, const SBindBuffer &inCommand, - QT3DSMat44 &outMVP, QT3DSVec2 &outDestSize) - { - NVRenderFrameBuffer *theBuffer = NULL; - NVRenderTexture2D *theTexture = NULL; - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - QT3DSU32 bufferIdx = theContext.FindBuffer(inCommand.m_BufferName); - if (bufferIdx < theContext.m_AllocatedBuffers.size()) { - theBuffer = theContext.m_AllocatedBuffers[bufferIdx].m_FrameBuffer; - theTexture = theContext.m_AllocatedBuffers[bufferIdx].m_Texture; - theContext.m_AllocatedBuffers[bufferIdx].m_NeedsClear = false; - } - } - if (theBuffer == NULL) { - qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", - inEffect.m_ClassName.c_str(), inCommand.m_BufferName.c_str()); - QString errorMsg = QObject::tr("Failed to compile \"%1\" effect.\nConsider" - " removing it from the presentation.") - .arg(inEffect.m_ClassName.c_str()); - QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); - outMVP = QT3DSMat44::createIdentity(); - return NULL; - } - - if (theTexture) { - SCamera::SetupOrthographicCameraForOffscreenRender(*theTexture, outMVP); - STextureDetails theDetails(theTexture->GetTextureDetails()); - m_Context->GetRenderContext().SetViewport( - NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); - outDestSize = QT3DSVec2((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); - } - - return theBuffer; - } - - SEffectShader *BindShader(CRegisteredString &inEffectId, const SBindShader &inCommand) - { - SEffectClass *theClass = GetEffectClass(inEffectId); - if (!theClass) { - QT3DS_ASSERT(false); - return NULL; - } - - bool forceCompilation = theClass->m_DynamicClass->RequiresCompilation(); - - eastl::pair> theInserter( - TStrStrPair(inCommand.m_ShaderPath, inCommand.m_ShaderDefine), - NVScopedRefCounted()); - eastl::pair theInsertResult(m_ShaderMap.insert(theInserter)); - - if (theInsertResult.second || forceCompilation) { - NVRenderShaderProgram *theProgram = - m_Context->GetDynamicObjectSystem() - .GetShaderProgram(inCommand.m_ShaderPath, inCommand.m_ShaderDefine, - TShaderFeatureSet(), SDynamicShaderProgramFlags(), - forceCompilation).first; - if (theProgram) - theInsertResult.first->second = QT3DS_NEW(m_Allocator, SEffectShader)(*theProgram); - } - if (theInsertResult.first->second) { - NVRenderContext &theContext(m_Context->GetRenderContext()); - theContext.SetActiveShader(theInsertResult.first->second->m_Shader); - } - - return theInsertResult.first->second; - } - - void DoApplyInstanceValue(SEffect &inEffect, QT3DSU8 *inDataPtr, CRegisteredString inPropertyName, - NVRenderShaderDataTypes::Enum inPropertyType, - NVRenderShaderProgram &inShader, - const SPropertyDefinition &inDefinition) - { - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(inPropertyName); - using namespace qt3ds::render; - if (theConstant) { - if (theConstant->GetShaderConstantType() == inPropertyType) { - if (inPropertyType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - StaticAssert::valid_expression(); - CRegisteredString *theStrPtr = reinterpret_cast(inDataPtr); - IBufferManager &theBufferManager(m_Context->GetBufferManager()); - IOffscreenRenderManager &theOffscreenRenderer( - m_Context->GetOffscreenRenderManager()); - bool needsAlphaMultiply = true; - NVRenderTexture2D *theTexture = NULL; - if (theStrPtr->IsValid()) { - if (theOffscreenRenderer.HasOffscreenRenderer(*theStrPtr)) { - SOffscreenRenderResult theResult = - theOffscreenRenderer.GetRenderedItem(*theStrPtr); - needsAlphaMultiply = false; - theTexture = theResult.m_Texture; - } else { - SImageTextureData theTextureData = - theBufferManager.LoadRenderImage(*theStrPtr); - needsAlphaMultiply = true; - theTexture = theTextureData.m_Texture; - } - } - GetEffectContext(inEffect).SetTexture( - inShader, inPropertyName, theTexture, needsAlphaMultiply, - m_TextureStringBuilder, m_TextureStringBuilder2, &inDefinition); - } else if (inPropertyType == NVRenderShaderDataTypes::NVRenderImage2DPtr) { - StaticAssert::valid_expression(); - NVRenderImage2D *theImage = NULL; - GetEffectContext(inEffect).SetImage(inShader, inPropertyName, theImage); - } else if (inPropertyType == NVRenderShaderDataTypes::NVRenderDataBufferPtr) { - // we don't handle this here - } else { - switch (inPropertyType) { -#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ - case NVRenderShaderDataTypes::type: \ - inShader.SetPropertyValue(theConstant, *(reinterpret_cast(inDataPtr))); \ - break; - ITERATE_QT3DS_SHADER_DATA_TYPES -#undef HANDLE_QT3DS_SHADER_DATA_TYPE - default: - QT3DS_ASSERT(false); - break; - } - } - } else { - qCCritical(INVALID_OPERATION, - "Effect ApplyInstanceValue command datatype " - "and shader datatypes differ for property %s", - inPropertyName.c_str()); - QT3DS_ASSERT(false); - } - } - } - - void ApplyInstanceValue(SEffect &inEffect, SEffectClass &inClass, - NVRenderShaderProgram &inShader, const SApplyInstanceValue &inCommand) - { - // sanity check - if (inCommand.m_PropertyName.IsValid()) { - bool canGetData = - inCommand.m_ValueOffset + getSizeofShaderDataType(inCommand.m_ValueType) - <= inEffect.m_DataSectionByteSize; - if (canGetData == false) { - QT3DS_ASSERT(false); - return; - } - QT3DSU8 *dataPtr = inEffect.GetDataSectionBegin() + inCommand.m_ValueOffset; - const SPropertyDefinition *theDefinition = - inClass.m_DynamicClass->FindPropertyByName(inCommand.m_PropertyName); - if (theDefinition) - DoApplyInstanceValue(inEffect, dataPtr, inCommand.m_PropertyName, - inCommand.m_ValueType, inShader, *theDefinition); - } else { - NVConstDataRef theDefs = inClass.m_DynamicClass->GetProperties(); - for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) { - const SPropertyDefinition &theDefinition(theDefs[idx]); - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(theDefinition.m_Name); - - // This is fine, the property wasn't found and we continue, no problem. - if (!theConstant) - continue; - QT3DSU8 *dataPtr = inEffect.GetDataSectionBegin() + theDefinition.m_Offset; - DoApplyInstanceValue(inEffect, dataPtr, theDefinition.m_Name, - theDefinition.m_DataType, inShader, theDefinition); - } - } - } - - void ApplyValue(SEffect &inEffect, SEffectClass &inClass, NVRenderShaderProgram &inShader, - const SApplyValue &inCommand) - { - if (inCommand.m_PropertyName.IsValid()) { - QT3DSU8 *dataPtr = inCommand.m_Value.mData; - const SPropertyDefinition *theDefinition = - inClass.m_DynamicClass->FindPropertyByName(inCommand.m_PropertyName); - if (theDefinition) - DoApplyInstanceValue(inEffect, dataPtr, inCommand.m_PropertyName, - inCommand.m_ValueType, inShader, *theDefinition); - } - } - - bool ApplyBlending(const SApplyBlending &inCommand) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - - theContext.SetBlendingEnabled(true); - - qt3ds::render::NVRenderBlendFunctionArgument blendFunc = - qt3ds::render::NVRenderBlendFunctionArgument( - inCommand.m_SrcBlendFunc, inCommand.m_DstBlendFunc, inCommand.m_SrcBlendFunc, - inCommand.m_DstBlendFunc); - - qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - - theContext.SetBlendFunction(blendFunc); - theContext.SetBlendEquation(blendEqu); - - return true; - } - - // This has the potential to change the source texture for the current render pass - SEffectTextureData ApplyBufferValue(SEffect &inEffect, NVRenderShaderProgram &inShader, - const SApplyBufferValue &inCommand, - NVRenderTexture2D &inSourceTexture, - SEffectTextureData inCurrentSourceTexture) - { - SEffectTextureData theTextureToBind; - if (inCommand.m_BufferName.IsValid()) { - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - QT3DSU32 bufferIdx = theContext.FindBuffer(inCommand.m_BufferName); - if (bufferIdx < theContext.m_AllocatedBuffers.size()) { - SAllocatedBufferEntry &theEntry(theContext.m_AllocatedBuffers[bufferIdx]); - if (theEntry.m_NeedsClear) { - NVRenderContext &theRenderContext(m_Context->GetRenderContext()); - - theRenderContext.SetRenderTarget(theEntry.m_FrameBuffer); - // Note that depth/stencil buffers need an explicit clear in their bind - // commands in order to ensure - // we clear the least amount of information possible. - - if (theEntry.m_Texture) { - NVRenderTextureFormats::Enum theTextureFormat = - theEntry.m_Texture->GetTextureDetails().m_Format; - if (theTextureFormat != NVRenderTextureFormats::Depth16 - && theTextureFormat != NVRenderTextureFormats::Depth24 - && theTextureFormat != NVRenderTextureFormats::Depth32 - && theTextureFormat != NVRenderTextureFormats::Depth24Stencil8) { - NVRenderContextScopedProperty __clearColor( - theRenderContext, &NVRenderContext::GetClearColor, - &NVRenderContext::SetClearColor, QT3DSVec4(0.0f)); - theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); - } - } - theEntry.m_NeedsClear = false; - } - theTextureToBind = SEffectTextureData(theEntry.m_Texture, false); - } - } - if (theTextureToBind.m_Texture == NULL) { - QT3DS_ASSERT(false); - qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", - inEffect.m_ClassName.c_str(), inCommand.m_BufferName.c_str()); - QT3DS_ASSERT(false); - } - } else // no name means bind the source - theTextureToBind = SEffectTextureData(&inSourceTexture, false); - - if (inCommand.m_ParamName.IsValid()) { - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(inCommand.m_ParamName); - - if (theConstant) { - if (theConstant->GetShaderConstantType() - != NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - qCCritical(INVALID_OPERATION, - "Effect %s: Binding buffer to parameter %s that is not a texture", - inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); - QT3DS_ASSERT(false); - } else { - GetEffectContext(inEffect).SetTexture( - inShader, inCommand.m_ParamName, theTextureToBind.m_Texture, - theTextureToBind.m_NeedsAlphaMultiply, m_TextureStringBuilder, - m_TextureStringBuilder2); - } - } - return inCurrentSourceTexture; - } else { - return theTextureToBind; - } - } - - void ApplyDepthValue(SEffect &inEffect, NVRenderShaderProgram &inShader, - const SApplyDepthValue &inCommand, NVRenderTexture2D *inTexture) - { - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(inCommand.m_ParamName); - - if (theConstant) { - if (theConstant->GetShaderConstantType() - != NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - qCCritical(INVALID_OPERATION, - "Effect %s: Binding buffer to parameter %s that is not a texture", - inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); - QT3DS_ASSERT(false); - } else { - GetEffectContext(inEffect).SetTexture(inShader, inCommand.m_ParamName, inTexture, - false, m_TextureStringBuilder, - m_TextureStringBuilder2); - } - } - } - - void ApplyImageValue(SEffect &inEffect, NVRenderShaderProgram &inShader, - const SApplyImageValue &inCommand) - { - SAllocatedImageEntry theImageToBind; - if (inCommand.m_ImageName.IsValid()) { - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - QT3DSU32 bufferIdx = theContext.FindImage(inCommand.m_ImageName); - if (bufferIdx < theContext.m_AllocatedImages.size()) { - theImageToBind = SAllocatedImageEntry(theContext.m_AllocatedImages[bufferIdx]); - } - } - } - - if (theImageToBind.m_Image == NULL) { - qCCritical(INVALID_OPERATION, "Effect %s: Failed to find image %s for bind", - inEffect.m_ClassName.c_str(), inCommand.m_ImageName.c_str()); - QT3DS_ASSERT(false); - } - - if (inCommand.m_ParamName.IsValid()) { - qt3ds::render::NVRenderShaderConstantBase *theConstant = - inShader.GetShaderConstant(inCommand.m_ParamName); - - if (theConstant) { - if (inCommand.m_NeedSync) { - NVRenderBufferBarrierFlags flags( - qt3ds::render::NVRenderBufferBarrierValues::TextureFetch - | qt3ds::render::NVRenderBufferBarrierValues::TextureUpdate); - inShader.GetRenderContext().SetMemoryBarrier(flags); - } - - if (theConstant->GetShaderConstantType() - == NVRenderShaderDataTypes::NVRenderImage2DPtr - && !inCommand.m_BindAsTexture) { - GetEffectContext(inEffect).SetImage(inShader, inCommand.m_ParamName, - theImageToBind.m_Image); - } else if (theConstant->GetShaderConstantType() - == NVRenderShaderDataTypes::NVRenderTexture2DPtr - && inCommand.m_BindAsTexture) { - GetEffectContext(inEffect).SetTexture( - inShader, inCommand.m_ParamName, theImageToBind.m_Texture, false, - m_TextureStringBuilder, m_TextureStringBuilder2); - } else { - qCCritical(INVALID_OPERATION, - "Effect %s: Binding buffer to parameter %s that is not a texture", - inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); - QT3DS_ASSERT(false); - } - } - } - } - - void ApplyDataBufferValue(SEffect &inEffect, NVRenderShaderProgram &inShader, - const SApplyDataBufferValue &inCommand) - { - SAllocatedDataBufferEntry theBufferToBind; - if (inCommand.m_ParamName.IsValid()) { - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - QT3DSU32 bufferIdx = theContext.FindDataBuffer(inCommand.m_ParamName); - if (bufferIdx < theContext.m_AllocatedDataBuffers.size()) { - theBufferToBind = - SAllocatedDataBufferEntry(theContext.m_AllocatedDataBuffers[bufferIdx]); - if (theBufferToBind.m_NeedsClear) { - NVDataRef pData = theBufferToBind.m_DataBuffer->MapBuffer(); - memset(pData.begin(), 0x0L, theBufferToBind.m_BufferData.size()); - theBufferToBind.m_DataBuffer->UnmapBuffer(); - theBufferToBind.m_NeedsClear = false; - } - } - } - - if (theBufferToBind.m_DataBuffer == NULL) { - qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", - inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); - QT3DS_ASSERT(false); - } - - qt3ds::render::NVRenderShaderBufferBase *theConstant = - inShader.GetShaderBuffer(inCommand.m_ParamName); - - if (theConstant) { - GetEffectContext(inEffect).SetDataBuffer(inShader, inCommand.m_ParamName, - theBufferToBind.m_DataBuffer); - } else if (theBufferToBind.m_BufferType - == qt3ds::render::NVRenderBufferBindValues::Draw_Indirect) { - // since we filled part of this buffer on the GPU we need a sync before usage - NVRenderBufferBarrierFlags flags( - qt3ds::render::NVRenderBufferBarrierValues::CommandBuffer); - inShader.GetRenderContext().SetMemoryBarrier(flags); - } - } - } - - void ApplyRenderStateValue(NVRenderFrameBuffer *inTarget, - NVRenderTexture2D *inDepthStencilTexture, - const SApplyRenderState &theCommand) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - QT3DSU32 inState = (QT3DSU32)theCommand.m_RenderState; - bool inEnable = theCommand.m_Enabled; - - switch (inState) { - case NVRenderState::StencilTest: { - if (inEnable && inTarget) { - inTarget->Attach(NVRenderFrameBufferAttachments::DepthStencil, - *inDepthStencilTexture); - } else if (inTarget) { - inTarget->Attach(NVRenderFrameBufferAttachments::DepthStencil, - NVRenderTextureOrRenderBuffer()); - } - - theContext.SetStencilTestEnabled(inEnable); - } break; - default: - QT3DS_ASSERT(false); - break; - } - } - - static bool CompareDepthStencilState(NVRenderDepthStencilState &inState, - SDepthStencil &inStencil) - { - qt3ds::render::NVRenderStencilFunctionArgument theFunction = - inState.GetStencilFunc(qt3ds::render::NVRenderFaces::Front); - qt3ds::render::NVRenderStencilOperationArgument theOperation = - inState.GetStencilOp(qt3ds::render::NVRenderFaces::Front); - - return theFunction.m_Function == inStencil.m_StencilFunction - && theFunction.m_Mask == inStencil.m_Mask - && theFunction.m_ReferenceValue == inStencil.m_Reference - && theOperation.m_StencilFail == inStencil.m_StencilFailOperation - && theOperation.m_DepthFail == inStencil.m_DepthFailOperation - && theOperation.m_DepthPass == inStencil.m_DepthPassOperation; - } - - void RenderPass(SEffectShader &inShader, const QT3DSMat44 &inMVP, - SEffectTextureData inSourceTexture, NVRenderFrameBuffer *inFrameBuffer, - QT3DSVec2 &inDestSize, const QT3DSVec2 &inCameraClipRange, - NVRenderTexture2D *inDepthStencil, Option inDepthStencilCommand, - bool drawIndirect) - { - NVRenderContext &theContext(m_Context->GetRenderContext()); - theContext.SetRenderTarget(inFrameBuffer); - if (inDepthStencil && inFrameBuffer) { - inFrameBuffer->Attach(NVRenderFrameBufferAttachments::DepthStencil, *inDepthStencil); - if (inDepthStencilCommand.hasValue()) { - SDepthStencil &theDepthStencil(*inDepthStencilCommand); - QT3DSU32 clearFlags = 0; - if (theDepthStencil.m_Flags.HasClearStencil()) - clearFlags |= NVRenderClearValues::Stencil; - if (theDepthStencil.m_Flags.HasClearDepth()) - clearFlags |= NVRenderClearValues::Depth; - - if (clearFlags) - theContext.Clear(qt3ds::render::NVRenderClearFlags(clearFlags)); - - NVRenderDepthStencilState *targetState = NULL; - for (QT3DSU32 idx = 0, end = m_DepthStencilStates.size(); - idx < end && targetState == NULL; ++idx) { - NVRenderDepthStencilState &theState = *m_DepthStencilStates[idx]; - if (CompareDepthStencilState(theState, theDepthStencil)) - targetState = &theState; - } - if (targetState == NULL) { - qt3ds::render::NVRenderStencilFunctionArgument theFunctionArg( - theDepthStencil.m_StencilFunction, theDepthStencil.m_Reference, - theDepthStencil.m_Mask); - qt3ds::render::NVRenderStencilOperationArgument theOpArg( - theDepthStencil.m_StencilFailOperation, - theDepthStencil.m_DepthFailOperation, theDepthStencil.m_DepthPassOperation); - targetState = theContext.CreateDepthStencilState( - theContext.IsDepthTestEnabled(), theContext.IsDepthWriteEnabled(), - theContext.GetDepthFunction(), true, theFunctionArg, theFunctionArg, - theOpArg, theOpArg); - m_DepthStencilStates.push_back(targetState); - } - theContext.SetDepthStencilState(targetState); - } - } - - theContext.SetActiveShader(inShader.m_Shader); - inShader.m_MVP.Set(inMVP); - if (inSourceTexture.m_Texture) { - inShader.m_TextureEntry.Set(inSourceTexture.m_Texture, - inSourceTexture.m_NeedsAlphaMultiply, NULL); - } else { - qCCritical(INTERNAL_ERROR, "Failed to setup pass due to null source texture"); - QT3DS_ASSERT(false); - } - inShader.m_FragColorAlphaSettings.Set(QT3DSVec2(1.0f, 0.0f)); - inShader.m_DestSize.Set(inDestSize); - if (inShader.m_AppFrame.IsValid()) - inShader.m_AppFrame.Set((QT3DSF32)m_Context->GetFrameCount()); - if (inShader.m_FPS.IsValid()) - inShader.m_FPS.Set((QT3DSF32)m_Context->GetFPS().first); - if (inShader.m_CameraClipRange.IsValid()) - inShader.m_CameraClipRange.Set(inCameraClipRange); - - if (!drawIndirect) - m_Context->GetRenderer().RenderQuad(); - else - m_Context->GetRenderer().RenderPointsIndirect(); - - if (inDepthStencil && inFrameBuffer) { - inFrameBuffer->Attach(NVRenderFrameBufferAttachments::DepthStencil, - NVRenderTextureOrRenderBuffer()); - theContext.SetDepthStencilState(m_DefaultStencilState); - } - } - - void DoRenderEffect(SEffect &inEffect, SEffectClass &inClass, - NVRenderTexture2D &inSourceTexture, QT3DSMat44 &inMVP, - NVRenderFrameBuffer *inTarget, bool inEnableBlendWhenRenderToTarget, - NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inDepthStencilTexture, - const QT3DSVec2 inCameraClipRange) - { - // Run through the effect commands and render the effect. - // NVRenderTexture2D* theCurrentTexture(&inSourceTexture); - NVRenderContext &theContext = m_Context->GetRenderContext(); - - // Context variables that are updated during the course of a pass. - SEffectTextureData theCurrentSourceTexture(&inSourceTexture, false); - NVRenderTexture2D *theCurrentDepthStencilTexture = NULL; - NVRenderFrameBuffer *theCurrentRenderTarget(inTarget); - SEffectShader *theCurrentShader(NULL); - NVRenderRect theOriginalViewport(theContext.GetViewport()); - bool wasScissorEnabled = theContext.IsScissorTestEnabled(); - bool wasBlendingEnabled = theContext.IsBlendingEnabled(); - // save current blending setup - qt3ds::render::NVRenderBlendFunctionArgument theBlendFunc = theContext.GetBlendFunction(); - qt3ds::render::NVRenderBlendEquationArgument theBlendEqu = theContext.GetBlendEquation(); - bool intermediateBlendingEnabled = false; - STextureDetails theDetails(inSourceTexture.GetTextureDetails()); - QT3DSU32 theFinalWidth = (QT3DSU32)(theDetails.m_Width); - QT3DSU32 theFinalHeight = (QT3DSU32)(theDetails.m_Height); - QT3DSVec2 theDestSize; - { - // Ensure no matter the command run goes we replace the rendering system to some - // semblance of the approprate - // setting. - NVRenderContextScopedProperty __framebuffer( - theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - NVRenderContextScopedProperty __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - NVRenderContextScopedProperty __scissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled); - NVRenderContextScopedProperty __stencilTest( - theContext, &NVRenderContext::IsStencilTestEnabled, - &NVRenderContext::SetStencilTestEnabled); - NVRenderContextScopedProperty __depthFunction( - theContext, &NVRenderContext::GetDepthFunction, &NVRenderContext::SetDepthFunction); - Option theCurrentDepthStencil; - - theContext.SetScissorTestEnabled(false); - theContext.SetBlendingEnabled(false); - theContext.SetCullingEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetDepthWriteEnabled(false); - - QT3DSMat44 theMVP(QT3DSMat44::createIdentity()); - NVConstDataRef theCommands = - inClass.m_DynamicClass->GetRenderCommands(); - for (QT3DSU32 commandIdx = 0, commandEnd = theCommands.size(); commandIdx < commandEnd; - ++commandIdx) { - const SCommand &theCommand(*theCommands[commandIdx]); - switch (theCommand.m_Type) { - case CommandTypes::AllocateBuffer: - AllocateBuffer(inEffect, static_cast(theCommand), - theFinalWidth, theFinalHeight, theDetails.m_Format); - break; - - case CommandTypes::AllocateImage: - AllocateImage(inEffect, static_cast(theCommand), - theFinalWidth, theFinalHeight); - break; - - case CommandTypes::AllocateDataBuffer: - AllocateDataBuffer(inEffect, - static_cast(theCommand)); - break; - - case CommandTypes::BindBuffer: - theCurrentRenderTarget = - BindBuffer(inEffect, static_cast(theCommand), theMVP, - theDestSize); - break; - - case CommandTypes::BindTarget: { - m_Context->GetRenderContext().SetRenderTarget(inTarget); - theCurrentRenderTarget = inTarget; - theMVP = inMVP; - theContext.SetViewport(theOriginalViewport); - theDestSize = QT3DSVec2((QT3DSF32)theFinalWidth, (QT3DSF32)theFinalHeight); - // This isn't necessary if we are rendering to an offscreen buffer and not - // compositing - // with other objects. - if (inEnableBlendWhenRenderToTarget) { - theContext.SetBlendingEnabled(wasBlendingEnabled); - theContext.SetScissorTestEnabled(wasScissorEnabled); - // The blending setup was done before we apply the effect - theContext.SetBlendFunction(theBlendFunc); - theContext.SetBlendEquation(theBlendEqu); - } - } break; - case CommandTypes::BindShader: - theCurrentShader = BindShader(inEffect.m_ClassName, - static_cast(theCommand)); - break; - case CommandTypes::ApplyInstanceValue: - if (theCurrentShader) - ApplyInstanceValue(inEffect, inClass, *theCurrentShader->m_Shader, - static_cast(theCommand)); - break; - case CommandTypes::ApplyValue: - if (theCurrentShader) - ApplyValue(inEffect, inClass, *theCurrentShader->m_Shader, - static_cast(theCommand)); - break; - case CommandTypes::ApplyBlending: - intermediateBlendingEnabled = - ApplyBlending(static_cast(theCommand)); - break; - case CommandTypes::ApplyBufferValue: - if (theCurrentShader) - theCurrentSourceTexture = - ApplyBufferValue(inEffect, *theCurrentShader->m_Shader, - static_cast(theCommand), - inSourceTexture, theCurrentSourceTexture); - break; - case CommandTypes::ApplyDepthValue: - if (theCurrentShader) - ApplyDepthValue(inEffect, *theCurrentShader->m_Shader, - static_cast(theCommand), - inDepthTexture); - if (!inDepthTexture) { - qCCritical(INVALID_OPERATION, - "Depth value command detected but no " - "depth buffer provided for effect %s", - inEffect.m_ClassName.c_str()); - QT3DS_ASSERT(false); - } - break; - case CommandTypes::ApplyImageValue: - if (theCurrentShader) - ApplyImageValue(inEffect, *theCurrentShader->m_Shader, - static_cast(theCommand)); - break; - case CommandTypes::ApplyDataBufferValue: - if (theCurrentShader) - ApplyDataBufferValue( - inEffect, *theCurrentShader->m_Shader, - static_cast(theCommand)); - break; - case CommandTypes::DepthStencil: { - const SDepthStencil &theDepthStencil = - static_cast(theCommand); - theCurrentDepthStencilTexture = - FindTexture(inEffect, theDepthStencil.m_BufferName); - if (theCurrentDepthStencilTexture) - theCurrentDepthStencil = theDepthStencil; - } break; - case CommandTypes::Render: - if (theCurrentShader && theCurrentSourceTexture.m_Texture) { - RenderPass(*theCurrentShader, theMVP, theCurrentSourceTexture, - theCurrentRenderTarget, theDestSize, inCameraClipRange, - theCurrentDepthStencilTexture, theCurrentDepthStencil, - static_cast(theCommand).m_DrawIndirect); - } - // Reset the source texture regardless - theCurrentSourceTexture = SEffectTextureData(&inSourceTexture, false); - theCurrentDepthStencilTexture = NULL; - theCurrentDepthStencil = Option(); - // reset intermediate blending state - if (intermediateBlendingEnabled) { - theContext.SetBlendingEnabled(false); - intermediateBlendingEnabled = false; - } - break; - case CommandTypes::ApplyRenderState: - ApplyRenderStateValue(theCurrentRenderTarget, inDepthStencilTexture, - static_cast(theCommand)); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - SetEffectRequiresCompilation(inEffect.m_ClassName, false); - - // reset to default stencil state - if (inDepthStencilTexture) { - theContext.SetDepthStencilState(m_DefaultStencilState); - } - - // Release any per-frame buffers - if (inEffect.m_Context) { - SEffectContext &theContext(*inEffect.m_Context); - // Query for size on every loop intentional - for (QT3DSU32 idx = 0; idx < theContext.m_AllocatedBuffers.size(); ++idx) { - if (theContext.m_AllocatedBuffers[idx].m_Flags.IsSceneLifetime() == false) { - theContext.ReleaseBuffer(idx); - --idx; - } - } - for (QT3DSU32 idx = 0; idx < theContext.m_AllocatedImages.size(); ++idx) { - if (theContext.m_AllocatedImages[idx].m_Flags.IsSceneLifetime() == false) { - theContext.ReleaseImage(idx); - --idx; - } - } - } - } - } - - NVRenderTexture2D *RenderEffect(SEffectRenderArgument inRenderArgument) override - { - SEffectClass *theClass = GetEffectClass(inRenderArgument.m_Effect.m_ClassName); - if (!theClass) { - QT3DS_ASSERT(false); - return NULL; - } - QT3DSMat44 theMVP; - SCamera::SetupOrthographicCameraForOffscreenRender(inRenderArgument.m_ColorBuffer, theMVP); - // setup a render target - NVRenderContext &theContext(m_Context->GetRenderContext()); - IResourceManager &theManager(m_Context->GetResourceManager()); - NVRenderContextScopedProperty __framebuffer( - theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - STextureDetails theDetails(inRenderArgument.m_ColorBuffer.GetTextureDetails()); - QT3DSU32 theFinalWidth = ITextRenderer::NextMultipleOf4((QT3DSU32)(theDetails.m_Width)); - QT3DSU32 theFinalHeight = ITextRenderer::NextMultipleOf4((QT3DSU32)(theDetails.m_Height)); - NVRenderFrameBuffer *theBuffer = theManager.AllocateFrameBuffer(); - // UdoL Some Effects may need to run before HDR tonemap. This means we need to keep the - // input format - NVRenderTextureFormats::Enum theOutputFormat = NVRenderTextureFormats::RGBA8; - if (theClass->m_DynamicClass->GetOutputTextureFormat() == NVRenderTextureFormats::Unknown) - theOutputFormat = theDetails.m_Format; - NVRenderTexture2D *theTargetTexture = - theManager.AllocateTexture2D(theFinalWidth, theFinalHeight, theOutputFormat); - theBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *theTargetTexture); - theContext.SetRenderTarget(theBuffer); - NVRenderContextScopedProperty __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, - NVRenderRect(0, 0, theFinalWidth, theFinalHeight)); - - NVRenderContextScopedProperty __scissorEnable( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, false); - - DoRenderEffect(inRenderArgument.m_Effect, *theClass, inRenderArgument.m_ColorBuffer, theMVP, - m_Context->GetRenderContext().GetRenderTarget(), false, - inRenderArgument.m_DepthTexture, inRenderArgument.m_DepthStencilBuffer, - inRenderArgument.m_CameraClipRange); - - theBuffer->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); - theManager.Release(*theBuffer); - return theTargetTexture; - } - - // Render the effect to the currently bound render target using this MVP - bool RenderEffect(SEffectRenderArgument inRenderArgument, QT3DSMat44 &inMVP, - bool inEnableBlendWhenRenderToTarget) override - { - SEffectClass *theClass = GetEffectClass(inRenderArgument.m_Effect.m_ClassName); - if (!theClass) { - QT3DS_ASSERT(false); - return false; - } - - DoRenderEffect(inRenderArgument.m_Effect, *theClass, inRenderArgument.m_ColorBuffer, inMVP, - m_Context->GetRenderContext().GetRenderTarget(), - inEnableBlendWhenRenderToTarget, inRenderArgument.m_DepthTexture, - inRenderArgument.m_DepthStencilBuffer, inRenderArgument.m_CameraClipRange); - return true; - } - - void ReleaseEffectContext(SEffectContext *inContext) override - { - if (inContext == NULL) - return; - for (QT3DSU32 idx = 0, end = m_Contexts.size(); idx < end; ++idx) { - if (m_Contexts[idx] == inContext) { - m_Contexts.replace_with_last(idx); - NVDelete(m_Allocator, inContext); - } - } - } - - void ResetEffectFrameData(SEffectContext &inContext) override - { // Query for size on every loop intentional - for (QT3DSU32 idx = 0; idx < inContext.m_AllocatedBuffers.size(); ++idx) { - SAllocatedBufferEntry &theBuffer(inContext.m_AllocatedBuffers[idx]); - if (theBuffer.m_Flags.IsSceneLifetime() == true) - theBuffer.m_NeedsClear = true; - } - for (QT3DSU32 idx = 0; idx < inContext.m_AllocatedDataBuffers.size(); ++idx) { - SAllocatedDataBufferEntry &theDataBuffer(inContext.m_AllocatedDataBuffers[idx]); - if (theDataBuffer.m_Flags.IsSceneLifetime() == true) - theDataBuffer.m_NeedsClear = true; - } - } - - void SetShaderData(CRegisteredString path, const char8_t *data, - const char8_t *inShaderType, const char8_t *inShaderVersion, - bool inHasGeomShader, bool inIsComputeShader) override - { - m_CoreContext.GetDynamicObjectSystemCore().SetShaderData( - path, data, inShaderType, inShaderVersion, inHasGeomShader, inIsComputeShader); - } - - void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, const char8_t *inProjectDir) const override - { - ioBuffer.write((QT3DSU32)m_EffectClasses.size()); - SStringSaveRemapper theRemapper(m_Allocator, inRemapMap, inProjectDir, - m_CoreContext.GetStringTable()); - for (TEffectClassMap::const_iterator theIter = m_EffectClasses.begin(), - end = m_EffectClasses.end(); - theIter != end; ++theIter) { - const SEffectClass &theClass = *theIter->second; - CRegisteredString theClassName = theClass.m_DynamicClass->GetId(); - theClassName.Remap(inRemapMap); - ioBuffer.write(theClassName); - // Effect classes do not store any additional data from the dynamic object class. - ioBuffer.write(theClass); - } - } - - void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t *inProjectDir) override - { - m_Allocator.m_PreAllocatedBlock = inData; - m_Allocator.m_OwnsMemory = false; - qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); - QT3DSU32 numEffectClasses = theReader.LoadRef(); - SStringLoadRemapper theRemapper(m_Allocator, inStrDataBlock, inProjectDir, - m_CoreContext.GetStringTable()); - for (QT3DSU32 idx = 0, end = numEffectClasses; idx < end; ++idx) { - CRegisteredString theClassName = theReader.LoadRef(); - theClassName.Remap(inStrDataBlock); - IDynamicObjectClass *theBaseClass = - m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(theClassName); - if (theBaseClass == NULL) { - QT3DS_ASSERT(false); - return; - } - SEffectClass *theClass = theReader.Load(); - theClass->SetupThisObjectFromMemory(m_Allocator, *theBaseClass); - NVScopedRefCounted theClassPtr(theClass); - m_EffectClasses.insert(eastl::make_pair(theBaseClass->GetId(), theClassPtr)); - } - } - - IEffectSystem &GetEffectSystem(IQt3DSRenderContext &context) override - { - m_Context = &context; - - NVRenderContext &theContext(m_Context->GetRenderContext()); - - m_ResourceManager = &IResourceManager::CreateResourceManager(theContext); - - // create default stencil state - qt3ds::render::NVRenderStencilFunctionArgument stencilDefaultFunc( - qt3ds::render::NVRenderBoolOp::AlwaysTrue, 0x0, 0xFF); - qt3ds::render::NVRenderStencilOperationArgument stencilDefaultOp( - qt3ds::render::NVRenderStencilOp::Keep, qt3ds::render::NVRenderStencilOp::Keep, - qt3ds::render::NVRenderStencilOp::Keep); - m_DefaultStencilState = theContext.CreateDepthStencilState( - theContext.IsDepthTestEnabled(), theContext.IsDepthWriteEnabled(), - theContext.GetDepthFunction(), theContext.IsStencilTestEnabled(), stencilDefaultFunc, - stencilDefaultFunc, stencilDefaultOp, stencilDefaultOp); - - return *this; - } - - IResourceManager &GetResourceManager() override - { - return *m_ResourceManager; - } -}; -} - -IEffectSystemCore &IEffectSystemCore::CreateEffectSystemCore(IQt3DSRenderContextCore &inContext) -{ - return *QT3DS_NEW(inContext.GetAllocator(), SEffectSystem)(inContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEulerAngles.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEulerAngles.cpp deleted file mode 100644 index 2732f031..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderEulerAngles.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//============================================================================== -// Includes -//============================================================================== -#include -#include -#include -#include -#include "Qt3DSRenderEulerAngles.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4365) // warnings on conversion from unsigned int to int -#endif - -//============================================================================== -// Namespace -//============================================================================== -namespace qt3ds { -namespace render { - - //============================================================================== - /** - * Constructor - */ - CEulerAngleConverter::CEulerAngleConverter() { m_OrderInfoBuffer[0] = '\0'; } - - //============================================================================== - /** - * Destructor - */ - CEulerAngleConverter::~CEulerAngleConverter() {} - - //============================================================================== - /** - * Constructs a Euler angle & holds it in a EulerAngles struct - * @param theI x rotation ( radians ) - * @param theJ y rotation ( radians ) - * @param theH z rotation ( radians ) - * @param theOrder the order this angle is in namely XYZ( static ), etc. - * use the EulOrd**** macros to generate values - * 0 to 23 is valid - * @return the euler angle - */ - EulerAngles CEulerAngleConverter::Eul_(float theI, float theJ, float theH, int theOrder) - { - EulerAngles theEulerAngle; - theEulerAngle.x = theI; - theEulerAngle.y = theJ; - theEulerAngle.z = theH; - theEulerAngle.w = (float)theOrder; - return theEulerAngle; - } - - //============================================================================== - /** - * Construct quaternion from Euler angles (in radians). - * @param theEulerAngle incoming angle( radians ) - * @return the Quaternion - */ - Quat CEulerAngleConverter::Eul_ToQuat(EulerAngles theEulerAngle) - { - Quat theQuaternion; - double a[3], ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; - int i, j, k, h, n, s, f; - - EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); - if (f == EulFrmR) { - float t = theEulerAngle.x; - theEulerAngle.x = theEulerAngle.z; - theEulerAngle.z = t; - } - - if (n == EulParOdd) - theEulerAngle.y = -theEulerAngle.y; - - ti = theEulerAngle.x * 0.5; - tj = theEulerAngle.y * 0.5; - th = theEulerAngle.z * 0.5; - - ci = cos(ti); - cj = cos(tj); - ch = cos(th); - - si = sin(ti); - sj = sin(tj); - sh = sin(th); - - cc = ci * ch; - cs = ci * sh; - sc = si * ch; - ss = si * sh; - - if (s == EulRepYes) { - a[i] = cj * (cs + sc); /* Could speed up with */ - a[j] = sj * (cc + ss); /* trig identities. */ - a[k] = sj * (cs - sc); - theQuaternion.w = (float)(cj * (cc - ss)); - } else { - a[i] = cj * sc - sj * cs; - a[j] = cj * ss + sj * cc; - a[k] = cj * cs - sj * sc; - theQuaternion.w = (float)(cj * cc + sj * ss); - } - if (n == EulParOdd) - a[j] = -a[j]; - - theQuaternion.x = (float)a[X]; - theQuaternion.y = (float)a[Y]; - theQuaternion.z = (float)a[Z]; - return theQuaternion; - } - - //============================================================================== - /** - * Construct matrix from Euler angles (in radians). - * @param theEulerAngle incoming angle - * @param theMatrix outgoing matrix - */ - void CEulerAngleConverter::Eul_ToHMatrix(EulerAngles theEulerAngle, HMatrix theMatrix) - { - double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; - int i, j, k, h, n, s, f; - EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); - - if (f == EulFrmR) { - float t = theEulerAngle.x; - theEulerAngle.x = theEulerAngle.z; - theEulerAngle.z = t; - } - - if (n == EulParOdd) { - theEulerAngle.x = -theEulerAngle.x; - theEulerAngle.y = -theEulerAngle.y; - theEulerAngle.z = -theEulerAngle.z; - } - - ti = theEulerAngle.x; - tj = theEulerAngle.y; - th = theEulerAngle.z; - - ci = cos(ti); - cj = cos(tj); - ch = cos(th); - - si = sin(ti); - sj = sin(tj); - sh = sin(th); - - cc = ci * ch; - cs = ci * sh; - sc = si * ch; - ss = si * sh; - - if (s == EulRepYes) { - theMatrix[i][i] = (float)cj; - theMatrix[i][j] = (float)(sj * si); - theMatrix[i][k] = (float)(sj * ci); - theMatrix[j][i] = (float)(sj * sh); - theMatrix[j][j] = (float)(-cj * ss + cc); - theMatrix[j][k] = (float)(-cj * cs - sc); - theMatrix[k][i] = (float)(-sj * ch); - theMatrix[k][j] = (float)(cj * sc + cs); - theMatrix[k][k] = (float)(cj * cc - ss); - } else { - theMatrix[i][i] = (float)(cj * ch); - theMatrix[i][j] = (float)(sj * sc - cs); - theMatrix[i][k] = (float)(sj * cc + ss); - theMatrix[j][i] = (float)(cj * sh); - theMatrix[j][j] = (float)(sj * ss + cc); - theMatrix[j][k] = (float)(sj * cs - sc); - theMatrix[k][i] = (float)(-sj); - theMatrix[k][j] = (float)(cj * si); - theMatrix[k][k] = (float)(cj * ci); - } - - theMatrix[W][X] = 0.0; - theMatrix[W][Y] = 0.0; - theMatrix[W][Z] = 0.0; - theMatrix[X][W] = 0.0; - theMatrix[Y][W] = 0.0; - theMatrix[Z][W] = 0.0; - theMatrix[W][W] = 1.0; - } - - //============================================================================== - /** - * Convert matrix to Euler angles (in radians). - * @param theMatrix incoming matrix - * @param theOrder 0-23, use EulOrd**** to generate this value - * @return a set of angles in radians!!!! - */ - EulerAngles CEulerAngleConverter::Eul_FromHMatrix(HMatrix theMatrix, int theOrder) - { - EulerAngles theEulerAngle; - int i, j, k, h, n, s, f; - - EulGetOrd(theOrder, i, j, k, h, n, s, f); - if (s == EulRepYes) { - double sy = sqrt(theMatrix[i][j] * theMatrix[i][j] + theMatrix[i][k] * theMatrix[i][k]); - if (sy > 16 * FLT_EPSILON) { - theEulerAngle.x = (float)(atan2((double)theMatrix[i][j], (double)theMatrix[i][k])); - theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); - theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], -(double)theMatrix[k][i])); - } else { - theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); - theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); - theEulerAngle.z = 0; - } - } else { - double cy = sqrt(theMatrix[i][i] * theMatrix[i][i] + theMatrix[j][i] * theMatrix[j][i]); - if (cy > 16 * FLT_EPSILON) { - theEulerAngle.x = (float)(atan2((double)theMatrix[k][j], (double)theMatrix[k][k])); - theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); - theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], (double)theMatrix[i][i])); - } else { - theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); - theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); - theEulerAngle.z = 0; - } - } - - if (n == EulParOdd) { - theEulerAngle.x = -theEulerAngle.x; - theEulerAngle.y = -theEulerAngle.y; - theEulerAngle.z = -theEulerAngle.z; - } - - if (f == EulFrmR) { - float t = theEulerAngle.x; - theEulerAngle.x = theEulerAngle.z; - theEulerAngle.z = t; - } - theEulerAngle.w = (float)theOrder; - return theEulerAngle; - } - - //============================================================================== - /** - * Convert quaternion to Euler angles (in radians). - * @param theQuaternion incoming quaternion - * @param theOrder 0-23, use EulOrd**** to generate this value - * @return the generated angles ( radians ) - */ - EulerAngles CEulerAngleConverter::Eul_FromQuat(Quat theQuaternion, int theOrder) - { - HMatrix theMatrix; - double Nq = theQuaternion.x * theQuaternion.x + theQuaternion.y * theQuaternion.y - + theQuaternion.z * theQuaternion.z + theQuaternion.w * theQuaternion.w; - double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; - double xs = theQuaternion.x * s; - double ys = theQuaternion.y * s; - double zs = theQuaternion.z * s; - double wx = theQuaternion.w * xs; - double wy = theQuaternion.w * ys; - double wz = theQuaternion.w * zs; - double xx = theQuaternion.x * xs; - double xy = theQuaternion.x * ys; - double xz = theQuaternion.x * zs; - double yy = theQuaternion.y * ys; - double yz = theQuaternion.y * zs; - double zz = theQuaternion.z * zs; - - theMatrix[X][X] = (float)(1.0 - (yy + zz)); - theMatrix[X][Y] = (float)(xy - wz); - theMatrix[X][Z] = (float)(xz + wy); - theMatrix[Y][X] = (float)(xy + wz); - theMatrix[Y][Y] = (float)(1.0 - (xx + zz)); - theMatrix[Y][Z] = (float)(yz - wx); - theMatrix[Z][X] = (float)(xz - wy); - theMatrix[Z][Y] = (float)(yz + wx); - theMatrix[Z][Z] = (float)(1.0 - (xx + yy)); - theMatrix[W][X] = 0.0; - theMatrix[W][Y] = 0.0; - theMatrix[W][Z] = 0.0; - theMatrix[X][W] = 0.0; - theMatrix[Y][W] = 0.0; - theMatrix[Z][W] = 0.0; - theMatrix[W][W] = 1.0; - - return Eul_FromHMatrix(theMatrix, theOrder); - } - - //============================================================================== - /** - * Dump the Order information - */ - const char *CEulerAngleConverter::DumpOrderInfo() - { - long theCount = 0; - long theOrder[24]; - char theOrderStr[24][16]; - - ::strcpy(theOrderStr[theCount++], "EulOrdXYZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdXYXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXYXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXZr"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXZr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXYZr"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYZr"); - - theCount = 0; - theOrder[theCount++] = EulOrdXYZs; - theOrder[theCount++] = EulOrdXYXs; - theOrder[theCount++] = EulOrdXZYs; - theOrder[theCount++] = EulOrdXZXs; - theOrder[theCount++] = EulOrdYZXs; - theOrder[theCount++] = EulOrdYZYs; - theOrder[theCount++] = EulOrdYXZs; - theOrder[theCount++] = EulOrdYXYs; - theOrder[theCount++] = EulOrdZXYs; - theOrder[theCount++] = EulOrdZXZs; - theOrder[theCount++] = EulOrdZYXs; - theOrder[theCount++] = EulOrdZYZs; - - theOrder[theCount++] = EulOrdZYXr; - theOrder[theCount++] = EulOrdXYXr; - theOrder[theCount++] = EulOrdYZXr; - theOrder[theCount++] = EulOrdXZXr; - theOrder[theCount++] = EulOrdXZYr; - theOrder[theCount++] = EulOrdYZYr; - theOrder[theCount++] = EulOrdZXYr; - theOrder[theCount++] = EulOrdYXYr; - theOrder[theCount++] = EulOrdYXZr; - theOrder[theCount++] = EulOrdZXZr; - theOrder[theCount++] = EulOrdXYZr; - theOrder[theCount++] = EulOrdZYZr; - - char theSubBuf[256]; - m_OrderInfoBuffer[0] = '\0'; - for (long theIndex = 0; theIndex < 24; ++theIndex) { - ::sprintf(theSubBuf, " %16s - %ld\n ", theOrderStr[theIndex], theOrder[theIndex]); - ::strcat(m_OrderInfoBuffer, theSubBuf); - } - - return m_OrderInfoBuffer; - } -} -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGpuProfiler.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGpuProfiler.cpp deleted file mode 100644 index 740d8a71..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGpuProfiler.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2014 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderProfiler.h" - -#include "EASTL/string.h" -#include "EASTL/hash_map.h" - -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSFoundation.h" - -#include "Qt3DSRenderContextCore.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderTimerQuery.h" -#include "render/Qt3DSRenderSync.h" - -#define RECORDED_FRAME_DELAY 3 -#define RECORDED_FRAME_DELAY_MASK 0x0003 - -using namespace qt3ds::render; - -namespace { - -using eastl::make_pair; - -struct SGpuTimerInfo -{ - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - bool m_AbsoluteTime; - QT3DSU16 m_WriteID; - QT3DSU16 m_ReadID; - QT3DSU16 m_AverageTimeWriteID; - QT3DSU64 m_AverageTime[10]; - QT3DSU32 m_FrameID[RECORDED_FRAME_DELAY]; - NVScopedRefCounted m_TimerStartQueryObjects[RECORDED_FRAME_DELAY]; - NVScopedRefCounted m_TimerEndQueryObjects[RECORDED_FRAME_DELAY]; - NVScopedRefCounted m_TimerSyncObjects[RECORDED_FRAME_DELAY]; - - SGpuTimerInfo(NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , mRefCount(0) - , m_AbsoluteTime(false) - , m_WriteID(0) - , m_ReadID(0) - , m_AverageTimeWriteID(0) - { - memset(m_AverageTime, 0x0, 10 * sizeof(QT3DSU64)); - } - - ~SGpuTimerInfo() {} - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void IncrementWriteCounter() - { - m_WriteID++; - m_WriteID %= RECORDED_FRAME_DELAY_MASK; - } - - void IncrementReadCounter() - { - m_ReadID++; - m_ReadID %= RECORDED_FRAME_DELAY_MASK; - } - - void IncrementAveragedWriteCounter() - { - m_AverageTimeWriteID++; - m_AverageTimeWriteID %= 10; - } - - void StartTimerQuery(QT3DSU32 frameID) - { - m_FrameID[m_WriteID] = frameID; - - if (m_AbsoluteTime) - m_TimerStartQueryObjects[m_WriteID]->SetTimerQuery(); - else - m_TimerStartQueryObjects[m_WriteID]->Begin(); - } - - void EndTimerQuery() - { - if (m_AbsoluteTime) - m_TimerEndQueryObjects[m_WriteID]->SetTimerQuery(); - else - m_TimerStartQueryObjects[m_WriteID]->End(); - - IncrementWriteCounter(); - } - - void AddSync() - { - m_TimerSyncObjects[m_WriteID]->Sync(); - m_TimerSyncObjects[m_WriteID]->Wait(); - } - - QT3DSF64 GetAveragedElapsedTimeInMs() - { - QT3DSF64 time = - QT3DSF64(((m_AverageTime[0] + m_AverageTime[1] + m_AverageTime[2] + m_AverageTime[3] - + m_AverageTime[4] + m_AverageTime[5] + m_AverageTime[6] + m_AverageTime[7] - + m_AverageTime[8] + m_AverageTime[9]) - / 10) - / 1e06); - - return time; - } - - QT3DSF64 GetElapsedTimeInMs(QT3DSU32 frameID) - { - QT3DSF64 time = 0; - - if (((frameID - m_FrameID[m_ReadID]) < 2) || (m_ReadID == m_WriteID)) - return time; - - if (m_AbsoluteTime) { - QT3DSU64 startTime, endTime; - - m_TimerStartQueryObjects[m_ReadID]->GetResult(&startTime); - m_TimerEndQueryObjects[m_ReadID]->GetResult(&endTime); - - m_AverageTime[m_AverageTimeWriteID] = endTime - startTime; - } else { - QT3DSU64 elapsedTime; - - m_TimerStartQueryObjects[m_ReadID]->GetResult(&elapsedTime); - - m_AverageTime[m_AverageTimeWriteID] = elapsedTime; - } - - IncrementReadCounter(); - IncrementAveragedWriteCounter(); - - return GetAveragedElapsedTimeInMs(); - } -}; - -class Qt3DSCRenderGpuProfiler : public IRenderProfiler -{ - typedef nvhash_map> TStrGpuTimerInfoMap; - -private: - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_RenderContext; - IQt3DSRenderContext &m_Context; - volatile QT3DSI32 mRefCount; - - TStrGpuTimerInfoMap m_StrToGpuTimerMap; - IRenderProfiler::TStrIDVec m_StrToIDVec; - mutable QT3DSU32 m_VertexCount; - -public: - Qt3DSCRenderGpuProfiler(NVFoundationBase &inFoundation, IQt3DSRenderContext &inContext, - NVRenderContext &inRenderContext) - : m_Foundation(inFoundation) - , m_RenderContext(inRenderContext) - , m_Context(inContext) - , mRefCount(0) - , m_StrToGpuTimerMap(inContext.GetAllocator(), "Qt3DSRenderGpuProfiler::m_StrToGpuTimerMap") - , m_StrToIDVec(inContext.GetAllocator(), "Qt3DSRenderGpuProfiler::m_StrToIDVec") - , m_VertexCount(0) - { - } - - virtual ~Qt3DSCRenderGpuProfiler() { m_StrToGpuTimerMap.clear(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void StartTimer(CRegisteredString &nameID, bool absoluteTime, bool sync) override - { - SGpuTimerInfo *theGpuTimerData = GetOrCreateGpuTimerInfo(nameID); - - if (theGpuTimerData) { - if (sync) - theGpuTimerData->AddSync(); - - theGpuTimerData->m_AbsoluteTime = absoluteTime; - theGpuTimerData->StartTimerQuery(m_Context.GetFrameCount()); - } - } - - void EndTimer(CRegisteredString &nameID) override - { - SGpuTimerInfo *theGpuTimerData = GetOrCreateGpuTimerInfo(nameID); - - if (theGpuTimerData) { - theGpuTimerData->EndTimerQuery(); - } - } - - QT3DSF64 GetElapsedTime(const CRegisteredString &nameID) const override - { - QT3DSF64 time = 0; - SGpuTimerInfo *theGpuTimerData = GetGpuTimerInfo(nameID); - - if (theGpuTimerData) { - time = theGpuTimerData->GetElapsedTimeInMs(m_Context.GetFrameCount()); - } - - return time; - } - - const TStrIDVec &GetTimerIDs() const override { return m_StrToIDVec; } - - void AddVertexCount(QT3DSU32 count) override { m_VertexCount += count; } - - QT3DSU32 GetAndResetTriangleCount() const override - { - QT3DSU32 tris = m_VertexCount / 3; - m_VertexCount = 0; - return tris; - } - -private: - SGpuTimerInfo *GetOrCreateGpuTimerInfo(CRegisteredString &nameID) - { - TStrGpuTimerInfoMap::const_iterator theIter = m_StrToGpuTimerMap.find(nameID); - if (theIter != m_StrToGpuTimerMap.end()) - return const_cast(theIter->second.mPtr); - - SGpuTimerInfo *theGpuTimerData = - QT3DS_NEW(m_Context.GetAllocator(), SGpuTimerInfo)(m_Foundation); - - if (theGpuTimerData) { - // create queries - for (QT3DSU32 i = 0; i < RECORDED_FRAME_DELAY; i++) { - theGpuTimerData->m_TimerStartQueryObjects[i] = m_RenderContext->CreateTimerQuery(); - theGpuTimerData->m_TimerEndQueryObjects[i] = m_RenderContext->CreateTimerQuery(); - theGpuTimerData->m_TimerSyncObjects[i] = m_RenderContext->CreateSync(); - theGpuTimerData->m_FrameID[i] = 0; - } - m_StrToGpuTimerMap.insert(make_pair(nameID, theGpuTimerData)); - m_StrToIDVec.push_back(nameID); - } - - return theGpuTimerData; - } - - SGpuTimerInfo *GetGpuTimerInfo(const CRegisteredString &nameID) const - { - TStrGpuTimerInfoMap::const_iterator theIter = m_StrToGpuTimerMap.find(nameID); - if (theIter != m_StrToGpuTimerMap.end()) - return const_cast(theIter->second.mPtr); - - return NULL; - } -}; -} - -IRenderProfiler &IRenderProfiler::CreateGpuProfiler(NVFoundationBase &inFnd, - IQt3DSRenderContext &inContext, - NVRenderContext &inRenderContext) -{ - return *QT3DS_NEW(inFnd.getAllocator(), Qt3DSCRenderGpuProfiler)(inFnd, inContext, inRenderContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGraphObjectSerializer.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGraphObjectSerializer.cpp deleted file mode 100644 index 8fc7e5aa..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderGraphObjectSerializer.cpp +++ /dev/null @@ -1,670 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderGraphObjectSerializer.h" -#include "Qt3DSRenderPresentation.h" -#include "Qt3DSRenderNode.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderModel.h" -#include "Qt3DSRenderText.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSRenderEffect.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSRenderEffectSystem.h" -#include "foundation/SerializationTypes.h" -#include "Qt3DSRenderString.h" -#include "foundation/FileTools.h" -#include "Qt3DSRenderPluginGraphObject.h" -#include "Qt3DSRenderReferencedMaterial.h" -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderPathSubPath.h" -#include "Qt3DSRenderPathManager.h" - -using namespace qt3ds::render; -using namespace qt3ds::render::dynamic; - -namespace { -typedef nvhash_set TPtrSet; - -void Align(MemoryBuffer<> &inBuffer) -{ - inBuffer.align(sizeof(void *)); -} -typedef nvvector> TObjectFileStatList; -typedef SPtrOffsetMap TPtrOffsetMap; - -struct SSerializerWriteContext -{ - SPtrOffsetMap &m_OffsetMap; - SWriteBuffer &m_MemoryBuffer; - const SStrRemapMap &m_StrRemapMap; - QT3DSU32 m_DataBlockStart; - IDynamicObjectSystem &m_DynamicObjectSystem; - IPathManager &m_PathManager; - TObjectFileStatList &m_FileSizeStats; - CRenderString m_PathMapper; - CRenderString m_BasePath; - CRenderString m_RelativePath; - IStringTable &m_StringTable; - SSerializerWriteContext(SPtrOffsetMap &inOffsetMap, SWriteBuffer &inWriteBuffer, - const SStrRemapMap &inStrMap, QT3DSU32 inDataBlockStart, - IDynamicObjectSystem &inDynamicObjectSystem, - IPathManager &inPathManager, TObjectFileStatList &inStats, - NVAllocatorCallback &inAllocator, const char8_t *inProjectDirectory, - IStringTable &inStringTable) - : m_OffsetMap(inOffsetMap) - , m_MemoryBuffer(inWriteBuffer) - , m_StrRemapMap(inStrMap) - , m_DataBlockStart(inDataBlockStart) - , m_DynamicObjectSystem(inDynamicObjectSystem) - , m_PathManager(inPathManager) - , m_FileSizeStats(inStats) - , m_StringTable(inStringTable) - { - Q_UNUSED(inAllocator) - m_BasePath.assign(inProjectDirectory); - } - - bool HasWrittenObject(const void *inObject) { return m_OffsetMap.contains(inObject); } - - QT3DSU32 &GetStatEntry(GraphObjectTypes::Enum inType) const - { - for (QT3DSU32 idx = 0, end = m_FileSizeStats.size(); idx < end; ++idx) - if (m_FileSizeStats[idx].first == inType) - return m_FileSizeStats[idx].second; - m_FileSizeStats.push_back(eastl::make_pair(inType, (QT3DSU32)0)); - return m_FileSizeStats.back().second; - } - - template - void AddPtrOffset(const TObjType *inObject) - { - QT3DSU32 objOffset = m_MemoryBuffer.size() - m_DataBlockStart; - m_OffsetMap.insert(eastl::make_pair(inObject, objOffset)); -// In debug we keep stats on how much each type of object -// contributes to the file size. -#ifdef _DEBUG - GetStatEntry(inObject->m_Type) += sizeof(TObjType); -#endif - } - - void Remap(CRegisteredString &inStr) { inStr.Remap(m_StrRemapMap); } - - template - void Remap(TObjType *&inPtr) - { - if (inPtr) { - TPtrOffsetMap::iterator theIter = m_OffsetMap.find(inPtr); - if (theIter != m_OffsetMap.end()) - inPtr = reinterpret_cast(theIter->second); - else { - QT3DS_ASSERT(false); - } - } - } - - void RemapMaterial(SGraphObject *&inPtr) { Remap(inPtr); } - - template - void NullPtr(TObjType *&inPtr) - { - inPtr = NULL; - } -}; - -/////////////////////////////////////////////////////////////////////// -// --** Reading the scene graph is heavily threaded when we are loading -// multiple presentations in one application --** -/////////////////////////////////////////////////////////////////////// -struct SSerializerReadContext : public SDataReader -{ - IPathManagerCore &m_PathManager; - IDynamicObjectSystemCore &m_DynamicObjectSystem; - NVDataRef m_DataBlock; - NVDataRef m_StrTableBlock; - CRenderString m_PathMapper; - const char8_t *m_ProjectDirectory; - - SSerializerReadContext(IPathManagerCore &inPathManager, IDynamicObjectSystemCore &inDynSystem, - NVDataRef inDataBlock, NVDataRef inStrTable, - NVAllocatorCallback &inAllocator, const char8_t *inProjectDirectory) - : SDataReader(inDataBlock.begin(), inDataBlock.end()) - , m_PathManager(inPathManager) - , m_DynamicObjectSystem(inDynSystem) - , m_DataBlock(inDataBlock) - , m_StrTableBlock(inStrTable) - , m_ProjectDirectory(inProjectDirectory) - { - Q_UNUSED(inAllocator) - } - void Remap(CRegisteredString &inStr) { inStr.Remap(m_StrTableBlock); } - template - void Remap(TObjType *&inPtr) - { - if (inPtr) { - TObjType *purePtr = inPtr; - size_t ptrValue = reinterpret_cast(purePtr); - if (ptrValue < m_DataBlock.size()) - inPtr = reinterpret_cast(m_DataBlock.begin() + ptrValue); - else { - QT3DS_ASSERT(false); - inPtr = NULL; - } - } - } - void RemapMaterial(SGraphObject *&inPtr) { Remap(inPtr); } - // Nulling out pointers was done on write, so we don't do it here. - template - void NullPtr(TObjType *&) - { - } -}; - -template -struct SGraphObjectSerializerImpl -{ - static TObjType *Write(const TObjType &ioObject, SSerializerWriteContext &outSavedBuffer); - static void Remap(TObjType &inObject, SSerializerWriteContext &inRemapContext); - static TObjType *Read(SSerializerReadContext &inReadContext); -}; - -struct SWriteRemapper -{ - SSerializerWriteContext &m_WriteBuffer; - SWriteRemapper(SSerializerWriteContext &buf) - : m_WriteBuffer(buf) - { - } - // This will happen later - void Remap(const CRegisteredString &) {} - void RemapPath(const CRegisteredString &) {} - - // We ignore objects that are saved out explicitly below. - void Remap(const SScene *) {} - - void Remap(const SLayer *) {} - // Nodes are ignored because we save them out *not* in depth first order, - // with models, text, lights and camera saved out contiguously for in-memory - // traversal. - void Remap(const SNode *) {} -#ifdef _INTEGRITYPLATFORM - // explicit specialization of class "::SGraphObjectSerializerImpl" - // must precede its first use struct SGraphObjectSerializerImpl - template - void Remap(const TObjType *inObj); -#else - template - void Remap(const TObjType *inObj) - { - if (inObj) - SGraphObjectSerializerImpl::Write(*inObj, m_WriteBuffer); - } -#endif - - void RemapMaterial(const SGraphObject *inObj) - { - if (inObj) { - if (inObj->m_Type == GraphObjectTypes::DefaultMaterial) - Remap(static_cast(inObj)); - else if (inObj->m_Type == GraphObjectTypes::CustomMaterial) - Remap(static_cast(inObj)); - else if (inObj->m_Type == GraphObjectTypes::ReferencedMaterial) - Remap(static_cast(inObj)); - else { - QT3DS_ASSERT(false); - } - } - } - template - void NullPtr(const TObjType *) - { - } -}; - -void PrepareFirstPass(const SNode &inNode, nvvector &ioLightCameras, - nvvector &ioRenderable) -{ - if (GraphObjectTypes::IsRenderableType(inNode.m_Type)) - ioRenderable.push_back(&inNode); - else if (GraphObjectTypes::IsLightCameraType(inNode.m_Type)) - ioLightCameras.push_back(&inNode); - - for (const SNode *theChild = inNode.m_FirstChild; theChild; theChild = theChild->m_NextSibling) - PrepareFirstPass(*theChild, ioLightCameras, ioRenderable); -} - -template -TObject *WriteGenericGraphObjectNoRemap(const TObject &ioObject, - SSerializerWriteContext &outSavedBuffer) -{ - if (outSavedBuffer.HasWrittenObject(&ioObject)) - return NULL; - - outSavedBuffer.AddPtrOffset(&ioObject); - QT3DSU32 theOffset = outSavedBuffer.m_MemoryBuffer.size(); - outSavedBuffer.m_MemoryBuffer.write(ioObject); - // Probably the buffer stays aligned but we want to work to keep it that way. - Align(outSavedBuffer.m_MemoryBuffer); - return reinterpret_cast(outSavedBuffer.m_MemoryBuffer.begin() + theOffset); -} - -template -TObject *WriteGenericGraphObject(const TObject &ioObject, SSerializerWriteContext &outSavedBuffer) -{ - TObject *theObject = WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer); - if (theObject) // The object may have already been written. - { - // Write mappers just follow pointers and ensure all the associated objects - // are written out. - SWriteRemapper theWriteRemapper(outSavedBuffer); - const_cast(ioObject).Remap(theWriteRemapper); - } - return theObject; -} - -template -TObject *ReadGenericGraphObject(SSerializerReadContext &inReadContext) -{ - TObject *retval = inReadContext.Load(); - inReadContext.Align(); - if (retval) { - retval->Remap(inReadContext); - } - return retval; -} - -template -TObjType *SGraphObjectSerializerImpl::Write(const TObjType &ioObject, - SSerializerWriteContext &outSavedBuffer) -{ - return WriteGenericGraphObject(ioObject, outSavedBuffer); -} -template -void SGraphObjectSerializerImpl::Remap(TObjType &ioObject, - SSerializerWriteContext &inRemapContext) -{ - return ioObject.Remap(inRemapContext); -} - -template -TObjType *SGraphObjectSerializerImpl::Read(SSerializerReadContext &inReadContext) -{ - return ReadGenericGraphObject(inReadContext); -} - -void RemapProperties(SDynamicObject &ioObject, SSerializerWriteContext &outSavedBuffer, - CRegisteredString inClassName) -{ - NVConstDataRef theObjectProps = - outSavedBuffer.m_DynamicObjectSystem.GetProperties(inClassName); - for (QT3DSU32 idx = 0, end = theObjectProps.size(); idx < end; ++idx) { - const SPropertyDefinition &theDef(theObjectProps[idx]); - if (theDef.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - CRegisteredString *theStr = reinterpret_cast( - ioObject.GetDataSectionBegin() + theDef.m_Offset); - outSavedBuffer.Remap(*theStr); - } - } -} - -void RemapProperties(SDynamicObject &ioObject, SSerializerReadContext &inReadContext) -{ - // CN - !!Note this call is done on multiple threads simultaneously. I added a mutex just to be - // sure even though - // this is a read-only call; I am not certain how good the arm memory locking is when it is - // completely unprotected. - NVConstDataRef theProperties = - inReadContext.m_DynamicObjectSystem.GetProperties(ioObject.m_ClassName); - for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { - const SPropertyDefinition &theDefinition(theProperties[idx]); - if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - CRegisteredString *theString = reinterpret_cast( - ioObject.GetDataSectionBegin() + theDefinition.m_Offset); - inReadContext.Remap(*theString); - } - } -} - -template <> -struct SGraphObjectSerializerImpl -{ - static SGraphObject *Write(const SEffect &ioObject, SSerializerWriteContext &outSavedBuffer) - { - size_t itemOffset = outSavedBuffer.m_MemoryBuffer.size(); - SEffect *theNewEffect = - static_cast(WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer)); - if (theNewEffect) { - theNewEffect->m_Context = NULL; - // Writing it out is easy. Reading it back in means we have to have a correctly setup - // IEffectManager so we - // can remap strings. - outSavedBuffer.m_MemoryBuffer.write(ioObject.GetDataSectionBegin(), - ioObject.m_DataSectionByteSize); - Align(outSavedBuffer.m_MemoryBuffer); - SWriteRemapper theWriteRemapper(outSavedBuffer); - // Write any connected objects. - theNewEffect = - reinterpret_cast(outSavedBuffer.m_MemoryBuffer.begin() + itemOffset); - theNewEffect->Remap(theWriteRemapper); - } - return theNewEffect; - } - - static void Remap(SEffect &ioObject, SSerializerWriteContext &outSavedBuffer) - { - CRegisteredString theClassName = ioObject.m_ClassName; - ioObject.Remap(outSavedBuffer); - RemapProperties(ioObject, outSavedBuffer, theClassName); - } - - static SEffect *Read(SSerializerReadContext &inReadContext) - { - SEffect *theEffect = ReadGenericGraphObject(inReadContext); - if (theEffect) { - inReadContext.m_CurrentPtr += theEffect->m_DataSectionByteSize; - inReadContext.Align(); - RemapProperties(*theEffect, inReadContext); - } - return theEffect; - } -}; - -template <> -struct SGraphObjectSerializerImpl -{ - static SGraphObject *Write(const SCustomMaterial &ioObject, - SSerializerWriteContext &outSavedBuffer) - { - size_t itemOffset = outSavedBuffer.m_MemoryBuffer.size(); - SCustomMaterial *theNewObject = static_cast( - WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer)); - if (theNewObject) { - // Writing it out is easy. Reading it back in means we have to have a correctly setup - // IEffectManager so we - // can remap strings. - outSavedBuffer.m_MemoryBuffer.write(ioObject.GetDataSectionBegin(), - ioObject.m_DataSectionByteSize); - Align(outSavedBuffer.m_MemoryBuffer); - theNewObject = reinterpret_cast(outSavedBuffer.m_MemoryBuffer.begin() - + itemOffset); - SWriteRemapper theWriteRemapper(outSavedBuffer); - // Write any connected objects. - theNewObject->Remap(theWriteRemapper); - } - return theNewObject; - } - - static void Remap(SCustomMaterial &ioObject, SSerializerWriteContext &outSavedBuffer) - { - CRegisteredString theClassName(ioObject.m_ClassName); - ioObject.Remap(outSavedBuffer); - RemapProperties(ioObject, outSavedBuffer, theClassName); - } - - static SCustomMaterial *Read(SSerializerReadContext &inReadContext) - { - SCustomMaterial *theMaterial = ReadGenericGraphObject(inReadContext); - if (theMaterial) { - inReadContext.m_CurrentPtr += theMaterial->m_DataSectionByteSize; - inReadContext.Align(); - RemapProperties(*theMaterial, inReadContext); - } - return theMaterial; - } -}; - -#ifdef _INTEGRITYPLATFORM - template - void SWriteRemapper::Remap(const TObjType *inObj) - { - if (inObj) - SGraphObjectSerializerImpl::Write(*inObj, m_WriteBuffer); - } -#endif - -template <> -struct SGraphObjectSerializerImpl -{ - static SGraphObject *Write(const SPathSubPath &ioObject, - SSerializerWriteContext &outSavedBuffer) - { - SPathSubPath *theObject = WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer); - if (theObject) // The object may have already been written. - { - NVConstDataRef thePoints = - outSavedBuffer.m_PathManager.GetPathSubPathBuffer(ioObject); - outSavedBuffer.m_MemoryBuffer.write((QT3DSU32)thePoints.size()); - outSavedBuffer.m_MemoryBuffer.write(thePoints.begin(), thePoints.size()); - // Write mappers just follow pointers and ensure all the associated objects - // are written out. - SWriteRemapper theWriteRemapper(outSavedBuffer); - const_cast(ioObject).Remap(theWriteRemapper); - } - return theObject; - } - - static void Remap(SPathSubPath &ioObject, SSerializerWriteContext &outSavedBuffer) - { - ioObject.Remap(outSavedBuffer); - } - - static SPathSubPath *Read(SSerializerReadContext &inReadContext) - { - SPathSubPath *theSubPath = ReadGenericGraphObject(inReadContext); - if (theSubPath) { - QT3DSU32 numPoints = *inReadContext.Load(); - SPathAnchorPoint *theAnchorPointBuffer = - reinterpret_cast(inReadContext.m_CurrentPtr); - inReadContext.m_CurrentPtr += sizeof(SPathAnchorPoint) * numPoints; - - // CN - !!Note this call is done on multiple threads simultaneously. I added a mutex to - // the path manager object - // so this exact call is always protected. This absolutely caused crashing when it was - // not protected approriately. - inReadContext.m_PathManager.SetPathSubPathData( - *theSubPath, toConstDataRef(theAnchorPointBuffer, numPoints)); - } - return theSubPath; - } -}; - -void WriteGraphObject(const SGraphObject &inObject, SSerializerWriteContext &outSavedBuffer) -{ - SGraphObject *newObject = NULL; - switch (inObject.m_Type) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case GraphObjectTypes::type: \ - newObject = SGraphObjectSerializerImpl::Write( \ - static_cast(inObject), outSavedBuffer); \ - break; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - QT3DS_ASSERT(false); - break; - } -} - -void WriteNodeList(nvvector &inList, SSerializerWriteContext &outSavedBuffer) -{ - for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) - WriteGraphObject(*inList[idx], outSavedBuffer); -} - -// Now write everything you haven't written so far, skip writing renderables or cameras or lights -void WriteNonRenderableNonCLNode(const SNode &inNode, SSerializerWriteContext &outSavedBuffer) -{ - if (GraphObjectTypes::IsLightCameraType(inNode.m_Type) == false - && GraphObjectTypes::IsRenderableType(inNode.m_Type) == false) { - WriteGraphObject(inNode, outSavedBuffer); - } - for (const SNode *theChild = inNode.m_FirstChild; theChild; theChild = theChild->m_NextSibling) - WriteNonRenderableNonCLNode(*theChild, outSavedBuffer); -} - -SGraphObject *ReadGraphObject(SSerializerReadContext &inContext) -{ - if (inContext.m_CurrentPtr + sizeof(SGraphObject) < inContext.m_EndPtr) { - SGraphObject *theObject = reinterpret_cast(inContext.m_CurrentPtr); - switch (theObject->m_Type) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case GraphObjectTypes::type: \ - SGraphObjectSerializerImpl::Read(inContext); \ - break; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - QT3DS_ASSERT(false); - theObject = NULL; - break; - } - return theObject; - } - return NULL; -} -} - -void SGraphObjectSerializer::Save(NVFoundationBase &inFoundation, - const SPresentation &inPresentation, - qt3ds::render::SWriteBuffer &outSavedData, - IDynamicObjectSystem &inDynamicObjectSystem, - IPathManager &inPathManager, SPtrOffsetMap &outSceneGraphOffsets, - IStringTable &inStringTable, - NVDataRef inExtraGraphObjects) -{ - using namespace qt3ds::foundation; - nvvector theLightCameraList(inFoundation.getAllocator(), - "SGraphObjectSerializer::theLightCameraList"); - nvvector theRenderableList(inFoundation.getAllocator(), - "SGraphObjectSerializer::theRenderableList"); - TObjectFileStatList theStatList(inFoundation.getAllocator(), - "SGraphObjectSerializer::FileSizeStats"); - // We want to save out the scene graph in the order we are going to traverse it normally. - // This is reverse depth first for the lights, cameras, and renderables and depth first for - // everything else so we go - // in two passes per layer. - // We expect the incoming data buffer to be aligned already. - QT3DS_ASSERT(outSavedData.size() % 4 == 0); - if (inPresentation.m_Scene) { - QT3DSU32 theDataSectionStart = outSavedData.size(); - outSavedData.writeZeros(4); - SSerializerWriteContext theWriteContext( - outSceneGraphOffsets, outSavedData, inStringTable.GetRemapMap(), theDataSectionStart, - inDynamicObjectSystem, inPathManager, theStatList, inFoundation.getAllocator(), - inPresentation.m_PresentationDirectory, inStringTable); - // First pass, just write out the data. - WriteGraphObject(inPresentation, theWriteContext); - WriteGraphObject(*inPresentation.m_Scene, theWriteContext); - for (const SLayer *theLayer = inPresentation.m_Scene->m_FirstChild; theLayer; - theLayer = static_cast(theLayer->m_NextSibling)) { - theLightCameraList.clear(); - theRenderableList.clear(); - PrepareFirstPass(*theLayer, theLightCameraList, theRenderableList); - eastl::reverse(theLightCameraList.begin(), theLightCameraList.end()); - eastl::reverse(theRenderableList.begin(), theRenderableList.end()); - WriteNodeList(theLightCameraList, theWriteContext); - WriteNodeList(theRenderableList, theWriteContext); - } - // Now just write everything *but* renderable objects and cameras. - for (const SLayer *theLayer = inPresentation.m_Scene->m_FirstChild; theLayer; - theLayer = static_cast(theLayer->m_NextSibling)) { - WriteNonRenderableNonCLNode(*theLayer, theWriteContext); - } - // Write out any extra objects we haven't covered yet. - for (QT3DSU32 idx = 0, end = inExtraGraphObjects.size(); idx < end; ++idx) - WriteGraphObject(*inExtraGraphObjects[idx], theWriteContext); - - QT3DSU32 theNumObjects = theWriteContext.m_OffsetMap.size(); - QT3DSU32 *theCountPtr = reinterpret_cast(outSavedData.begin() + theDataSectionStart); - *theCountPtr = theNumObjects; - - // Second pass, perform remapping on all the objects to change their pointers to offsets - for (SPtrOffsetMap::iterator theIter = outSceneGraphOffsets.begin(), - theEnd = outSceneGraphOffsets.end(); - theIter != theEnd; ++theIter) { - QT3DSU8 *theDataPtr = outSavedData.begin() + theDataSectionStart + theIter->second; - SGraphObject *theGraphObj = reinterpret_cast(theDataPtr); - switch (theGraphObj->m_Type) { -#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ - case GraphObjectTypes::type: \ - SGraphObjectSerializerImpl::Remap(static_cast(*theGraphObj), \ - theWriteContext); \ - break; - QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES -#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE - default: - QT3DS_ASSERT(false); - break; - } - } - } -#ifdef _DEBUG - qCDebug(TRACE_INFO, "--File size stats:"); - // Tell the users how much space is used in the file based on object type: - for (QT3DSU32 idx = 0, end = theStatList.size(); idx < end; ++idx) { - const char *theObjType = GraphObjectTypes::GetObjectTypeName(theStatList[idx].first); - qCDebug(TRACE_INFO, "%s - %d bytes:", theObjType, theStatList[idx].second); - } - qCDebug(TRACE_INFO, "--End file size stats:"); -#endif -}; - -SPresentation *SGraphObjectSerializer::Load(NVDataRef inData, NVDataRef inStrDataBlock, - IDynamicObjectSystemCore &inDynamicObjectSystem, - IPathManagerCore &inPathManager, - NVAllocatorCallback &inAllocator, - const char8_t *inProjectDirectory) -{ - SSerializerReadContext theReadContext(inPathManager, inDynamicObjectSystem, inData, - inStrDataBlock, inAllocator, inProjectDirectory); - SPresentation *retval = NULL; - if (inData.size() < 4) { - QT3DS_ASSERT(false); - return NULL; - } - QT3DSU32 theNumObjects = theReadContext.LoadRef(); - for (QT3DSU32 idx = 0, end = theNumObjects; idx < end; ++idx) { - SGraphObject *theObject = ReadGraphObject(theReadContext); - if (theObject) { - if (theObject->m_Type == GraphObjectTypes::Presentation) - retval = static_cast(theObject); - } else { - QT3DS_ASSERT(false); - } - } - return retval; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderImageScaler.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderImageScaler.cpp deleted file mode 100644 index d699179f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderImageScaler.cpp +++ /dev/null @@ -1,883 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2001 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSRender.h" -#include "foundation/Qt3DSMath.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "Qt3DSRenderImageScaler.h" -#include "foundation/Qt3DSMemoryBuffer.h" - -using namespace qt3ds::render; -//============================================================================== -// Namespace -//============================================================================== -CImageScaler::CImageScaler(NVAllocatorCallback &inAlloc) - : m_Allocator(inAlloc) -{ -} -//============================================================================== -/** - * Scales the given image by the given scale factor. - * - * This method creates a new image based on the parameters given. - * - * @param inScaleMethod type of scaling operation - * @param inOldBuffer points to the old picture - * @param inOldWidth width of the old picture - * @param inOldHeight height of the old picture - * @param inNewBuffer will point to the scaled picture - * @param inNewWidth width of the new picture - * @param inNewHeight height of the new picture - * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) - * also equivalent to the return value of the CTextureType::PixelSize method. - */ -void CImageScaler::Scale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, - unsigned long inOldWidth, unsigned long inOldHeight, - unsigned char *&outNewBuffer, unsigned long inNewWidth, - unsigned long inNewHeight, unsigned long inPlanes) -{ - switch (inScaleMethod) { - case SCALEMETHOD_CROP: - CImageScaler::Crop(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, - inNewHeight, inPlanes); - break; - - case SCALEMETHOD_BILINEAR: - CImageScaler::Bilinear(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, - inNewHeight, inPlanes); - break; - - default: - QT3DS_ASSERT(false); - break; - } -} - -//============================================================================== -/** - * Scales the given image by the given scale factor. - * - * This method creates a new image based on the parameters given. - * - * @param inScaleMethod type of scaling operation - * @param inOldBuffer points to the old picture - * @param inOldWidth width of the old picture - * @param inOldHeight height of the old picture - * @param inNewBuffer will point to the scaled picture - * @param inNewWidth width of the new picture - * @param inNewHeight height of the new picture - * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) - * also equivalent to the return value of the CTextureType::PixelSize method. - */ -void CImageScaler::FastScale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, - unsigned long inOldWidth, unsigned long inOldHeight, - unsigned char *&outNewBuffer, unsigned long inNewWidth, - unsigned long inNewHeight, unsigned long inPlanes) -{ - switch (inScaleMethod) { - case SCALEMETHOD_CROP: - CImageScaler::Crop(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, - inNewHeight, inPlanes); - break; - - case SCALEMETHOD_POINTSAMPLE: - CImageScaler::FastPointSample(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, - inNewWidth, inNewHeight, inPlanes); - break; - - default: - QT3DS_ASSERT(false); - break; - } -} - -//============================================================================== -/** - * Debug method that simply crops the picture instead of scaling. - * - * Not for use in production. This is a test method to exercise the framework. - * - * @param inOldBuffer points to the old picture - * @param inOldWidth width of the old picture - * @param inOldHeight height of the old picture - * @param inNewBuffer will point to the scaled picture - * @param inNewWidth width of the new picture - * @param inNewHeight height of the new picture - * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) - * also equivalent to the return value of the CTextureType::PixelSize method. -*/ -void CImageScaler::Crop(unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, unsigned long inPlanes) -{ - Q_UNUSED(inOldHeight); - - QT3DS_ASSERT(inNewWidth <= inOldWidth); - QT3DS_ASSERT(inNewHeight <= inOldHeight); - - long theMinWidth = NVMin(inOldWidth, inNewWidth); - - outNewBuffer = new unsigned char[inNewWidth * inNewHeight * inPlanes]; - ::memset(outNewBuffer, 0, inNewWidth * inNewHeight * inPlanes); - - for (unsigned long theRow = 0; theRow < inNewHeight; ++theRow) { - ::memcpy(outNewBuffer + theRow * inNewWidth * inPlanes, - inOldBuffer + theRow * inOldWidth * inPlanes, theMinWidth * inPlanes); - } -} - -//============================================================================== -/** - * Plain scaling. - * - * Code adopted from http://www.codeguru.com/bitmap/SmoothBitmapResizing.html - * Preliminary formatting completed but still needs work. - * - * @param inOldBuffer points to the old picture - * @param inOldWidth width of the old picture - * @param inOldHeight height of the old picture - * @param inNewBuffer will point to the scaled picture - * @param inNewWidth width of the new picture - * @param inNewHeight height of the new picture - * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) - * also equivalent to the return value of the CTextureType::PixelSize method. -*/ -void CImageScaler::Bilinear(unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, - unsigned long inPlanes) -{ - QT3DS_ASSERT(inPlanes > 0); - - outNewBuffer = new unsigned char[inNewWidth * inNewHeight * inPlanes]; - CImageScaler::Resize(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, - inNewHeight, inPlanes); -} - -//============================================================================== -/** - * Fast removal of selected pixels. - * - * Really fast scanning of every n-th pixel. This algorithm works basically by - * adding a fraction to the source pointer for each pixel destination, using - * fixed point arithmetic. - * - * @param inOldBuffer points to the old picture - * @param inOldWidth width of the old picture - * @param inOldHeight height of the old picture - * @param inNewBuffer will point to the scaled picture - * @param inNewWidth width of the new picture - * @param inNewHeight height of the new picture - * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) - * also equivalent to the return value of the CTextureType::PixelSize method. -*/ -void CImageScaler::FastPointSample(unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, - unsigned long inPlanes) -{ - unsigned long theXAccum; - unsigned long theYAccum; - unsigned long theXConst; - unsigned long theYConst; - unsigned long theRow; - unsigned long theColumn; - unsigned long theAdd; - unsigned long theSrcIndex; - outNewBuffer = new unsigned char[inNewWidth * inNewHeight * inPlanes]; - - // *** Debug *** - // char dMessage[100]; - //::sprintf( dMessage, "PointSample: %ldx%ld to %ldx%ld\n",inOldInfo.m_Width, inOldInfo.m_Height, outNewInfo.m_Width, outNewInfo.m_Height ); - //::OutputDebugString( dMessage ); - - switch (inPlanes) { - case 4: { - long *theSrc; - long *theDst; - theSrc = reinterpret_cast(inOldBuffer); - theDst = reinterpret_cast(outNewBuffer); - theYAccum = 0; - theXConst = (inOldWidth << 16) / inNewWidth; - theYConst = (inOldHeight << 16) / inNewHeight; - unsigned long theAdd; - for (theRow = 0; theRow < inNewHeight; theRow++) { - theXAccum = 0; - theSrcIndex = 0; - for (theColumn = 0; theColumn < inNewWidth; theColumn++) { - - theXAccum += theXConst; - theAdd = theXAccum >> 16; - *theDst = theSrc[theSrcIndex]; - theDst++; - theSrcIndex += theAdd; - // Clear out the integer portion of the accumulator. - theXAccum = theXAccum & 0xFFFF; - } - - theYAccum += theYConst; - theAdd = (theYAccum) >> 16; - theSrc += theAdd * inOldWidth; - // Clear out the integer portion of the accumulator. - theYAccum = theYAccum & 0xFFFF; - } - } break; - - case 3: { - unsigned char *theDest; - unsigned char *theSource; - theDest = reinterpret_cast(outNewBuffer); - theSource = reinterpret_cast(inOldBuffer); - theYAccum = 0; - theXConst = (inOldWidth << 16) / inNewWidth; - theYConst = (inOldHeight << 16) / inNewHeight; - for (theRow = 0; theRow < inNewHeight; ++theRow) { - theXAccum = 0; - theSrcIndex = 0; - for (theColumn = 0; theColumn < inNewWidth; ++theColumn) { - theDest[0] = theSource[0]; - theDest[1] = theSource[1]; - theDest[2] = theSource[2]; - theDest += 3; - theSrcIndex += 3 * (theXAccum) >> 16; - theXAccum = theXAccum & 0xFFFF; - } - theYAccum += theYConst; - theAdd = (theYAccum) >> 16; - theSource += theAdd * inOldWidth * 3; - theYAccum = theYAccum & 0xFFFF; - } - } break; - - case 2: { - short *theDest; - short *theSource; - theDest = reinterpret_cast(outNewBuffer); - theSource = reinterpret_cast(inOldBuffer); - theYAccum = 0; - theXConst = (inOldWidth << 16) / inNewWidth; - theYConst = (inOldHeight << 16) / inNewHeight; - for (unsigned long theY = 0; theY < inNewHeight; ++theY) { - theXAccum = 0; - theSrcIndex = 0; - for (unsigned long theX = 0; theX < inNewWidth; ++theX) { - *theDest = *theSource; - ++theDest; - theXAccum += theXConst; - theSrcIndex += (theXAccum) >> 16; - theXAccum = theXAccum & 0xFFFF; - } - theYAccum += theYConst; - theAdd = (theYAccum) >> 16; - theSource += theAdd * inOldWidth; - theYAccum = theYAccum & 0xFFFF; - } - } break; - - case 1: { - unsigned char *theDest; - unsigned char *theSource; - theDest = reinterpret_cast(outNewBuffer); - theSource = reinterpret_cast(inOldBuffer); - theYAccum = 0; - theXConst = (inOldWidth << 16) / inNewWidth; - theYConst = (inOldHeight << 16) / inNewHeight; - for (unsigned long theY = 0; theY < inNewHeight; ++theY) { - theXAccum = 0; - theSrcIndex = 0; - for (unsigned long theX = 0; theX < inNewWidth; ++theX) { - *theDest = *theSource; - ++theDest; - theXAccum += theXConst; - theSrcIndex += (theXAccum) >> 16; - theXAccum = theXAccum & 0xFFFF; - } - theYAccum += theYConst; - theAdd = (theYAccum) >> 16; - theSource += theAdd * inOldWidth; - theYAccum = theYAccum & 0xFFFF; - } - } break; - - default: - QT3DS_ASSERT(false); - break; - } -} - -//============================================================================== -/** - * @param inWidth - * @param inHeight - * @return unsigned char* - */ -unsigned char *CImageScaler::AllocateBuffer(long inWidth, long inHeight) -{ - unsigned char *theBuffer = new unsigned char[inHeight * inWidth * 4]; - return theBuffer; -} - -//============================================================================== -/** - * @param ioBuffer the buffer to release - */ -void CImageScaler::ReleaseBuffer(unsigned char *&ioBuffer) -{ - delete[] ioBuffer; - ioBuffer = NULL; -} - -//============================================================================== -/** - * @param inOldBuffer points to the old picture - * @param inOldWidth width of the old picture - * @param inOldHeight height of the old picture - * @param inNewBuffer will point to the scaled picture - * @param inNewWidth width of the new picture - * @param inNewHeight height of the new picture - * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) - * also equivalent to the return value of the CTextureType::PixelSize method. - */ -void CImageScaler::Resize(unsigned char *inOldBuffer, unsigned long inOldWidth, - unsigned long inOldHeight, unsigned char *&outNewBuffer, - unsigned long inNewWidth, unsigned long inNewHeight, - unsigned long inPlanes) -{ - QT3DS_ASSERT(inPlanes == 4); - - // only do the temporary allocation if necessary - if (inOldWidth < inNewWidth || inOldHeight < inNewHeight) { - CImageScaler::ExpandRowsAndColumns(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, - inNewWidth, inNewHeight, inPlanes); - return; - } else { - // The downsampling algorithms *do* assume four planes. - if (inOldWidth > inNewWidth && inOldHeight > inNewHeight) { - MemoryBuffer<> theBuffer(ForwardingAllocator(m_Allocator, "ImageScaler::TempBuffer")); - theBuffer.reserve(inNewWidth * inOldHeight * 4); - unsigned char *theTempBuffer = theBuffer.begin(); - CImageScaler::ReduceCols(inOldBuffer, inOldWidth, inOldHeight, theTempBuffer, - inNewWidth); - CImageScaler::ReduceRows(theTempBuffer, inNewWidth, inOldHeight, outNewBuffer, - inNewHeight); - } else if (inOldWidth > inNewWidth) { - CImageScaler::ReduceCols(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, - inNewWidth); - } else if (inOldHeight > inNewHeight) { - CImageScaler::ReduceRows(inOldBuffer, inNewWidth, inOldHeight, outNewBuffer, - inNewHeight); - } - } -} - -void CImageScaler::ExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, - unsigned long inHeight, unsigned char *outBuffer, - unsigned long inDstWidth, unsigned long inDstHeight, - unsigned long inPlanes) -{ - if (inDstWidth < inWidth || inDstHeight < inHeight) { - return; - } - /*if( inPlanes == 4 ) - { - FastExpandRowsAndColumns( inBuffer, inWidth, inHeight, - outBuffer, inDstWidth, inDstHeight ); - return; - }*/ - unsigned long theYPosition; - unsigned short theYRatio; - unsigned short theYInvRatio; - unsigned long theXPosition; - unsigned short theXRatio; - unsigned short theXInvRatio; - - unsigned long theRow; - unsigned long theColumn; - unsigned long theSrcIndex; - unsigned long theDstIndex; - unsigned long theSrcLineLength; - unsigned long theTemp; - unsigned long thePixel; - - theDstIndex = 0; - theSrcIndex = 0; - theSrcLineLength = inWidth * inPlanes; - theYPosition = inDstHeight; - theYRatio = 1 << 8; - theYInvRatio = 0; - theXInvRatio = 0; - // Here we go.... - // This algorithm will be quite a bit hairy, if you want - // to understand it, then look at the two expand alogorithms above - // and realize the this is just the logical combination of the two - for (theRow = 0; theRow < inDstHeight; theRow++) { - // Run through all the rows, multiplying if necessary the two ratio's together - theXPosition = inDstWidth; - if (theYPosition < inHeight) { - // We have crossed a row boundary - theYRatio = (unsigned short)((theYPosition << 8) / inHeight); - theYInvRatio = (unsigned short)((1 << 8) - theYRatio); - - for (theColumn = 0; theColumn < inDstWidth; theColumn++) { - if (theXPosition < inWidth) { - theXRatio = (unsigned short)((theXPosition << 8) / inWidth); - theXInvRatio = (unsigned short)((1 << 8) - theXRatio); - - // The combination of both the x and y ratio's - unsigned long theLeftRatio = (theXRatio * theYRatio) >> 8; - unsigned long theRightRatio = (theXInvRatio * theYRatio) >> 8; - unsigned long theLowLeftRatio = (theXRatio * theYInvRatio) >> 8; - unsigned long theLowRightRatio = (theXInvRatio * theYInvRatio) >> 8; - // We are on a row and column boundary, thus each pixel here is the - // combination of four pixels (left right, low left, low right) - for (thePixel = 0; thePixel < inPlanes; thePixel++) { - // Left side first - theTemp = (theLeftRatio * inBuffer[theSrcIndex]); - theTemp += (theRightRatio * inBuffer[theSrcIndex + inPlanes]); - theTemp += (theLowLeftRatio * inBuffer[theSrcIndex + theSrcLineLength]); - theTemp += (theLowRightRatio - * inBuffer[theSrcIndex + theSrcLineLength + inPlanes]); - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 8); - theDstIndex++; - theSrcIndex++; - } - // Reset our position calculation - theXPosition = inDstWidth - inWidth + theXPosition; - } else { - for (thePixel = 0; thePixel < inPlanes; thePixel++) { - theTemp = theYRatio * inBuffer[theSrcIndex + thePixel]; - theTemp += - theYInvRatio * inBuffer[theSrcIndex + theSrcLineLength + thePixel]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 8); - theDstIndex++; - } - // Reset our position calculation - theXPosition -= inWidth; - } - } - // Reset our position calculation - theYPosition = inDstHeight - inHeight + theYPosition; - // Make the src index point to the next line - theSrcIndex += inPlanes; - } // Ends the if to check if we are crossing a row boundary - // Else we are not crossing a row boundary - else { - for (theColumn = 0; theColumn < inDstWidth; theColumn++) { - // If we are crossing a column boundary - if (theXPosition < inWidth) { - theXRatio = (unsigned short)((theXPosition << 8) / inWidth); - theXInvRatio = (unsigned short)((1 << 8) - theXRatio); - for (thePixel = 0; thePixel < inPlanes; thePixel++) { - theTemp = theXRatio * inBuffer[theSrcIndex]; - theTemp += theXInvRatio * inBuffer[theSrcIndex + inPlanes]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 8); - theSrcIndex++; - theDstIndex++; - } - - theXPosition = inDstWidth - inWidth + theXPosition; - } - // Else we are not crossing a column boundary - else { - for (thePixel = 0; thePixel < inPlanes; thePixel++) { - outBuffer[theDstIndex] = inBuffer[theSrcIndex + thePixel]; - theDstIndex++; - } - theXPosition -= inWidth; - } - } - // reset our y position indicator - theYPosition -= inHeight; - // reset the src index to the beginning the next line - theSrcIndex += inPlanes; - // reset src index to the beginning of this line - theSrcIndex -= theSrcLineLength; - } // End of else for row boundary - } // End of for loop for iterating through all rows -} - -// Assuming the number of planes is four - -void CImageScaler::FastExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, - unsigned long inHeight, unsigned char *outBuffer, - unsigned long inDstWidth, unsigned long inDstHeight) -{ - - if (inDstWidth < inWidth || inDstHeight < inHeight) { - return; - } - unsigned long theYPosition; - unsigned short theYRatio; - unsigned short theYInvRatio; - unsigned long theXPosition; - unsigned short theXRatio; - unsigned short theXInvRatio; - // The combination of both the x and y ratio's - unsigned long theLeftRatio; - unsigned long theRightRatio; - unsigned long theLowLeftRatio; - unsigned long theLowRightRatio; - - unsigned long theRow; - unsigned long theColumn; - unsigned long theSrcIndex; - unsigned long theDstIndex; - unsigned long theSrcLineLength; - unsigned long theTemp; - - theDstIndex = 0; - theSrcIndex = 0; - theSrcLineLength = inWidth * 4; - theYPosition = inDstHeight; - theYInvRatio = 0; - theXInvRatio = 0; - // Here we go.... - // This algorithm will be quite a bit hairy, if you want - // to understand it, then look at the two expand alogorithms above - // and realize the this is just the logical combination of the two - for (theRow = 0; theRow < inDstHeight; theRow++) { - // Run through all the rows, multiplying if necessary the two ratio's together - theXPosition = inDstWidth; - if (theYPosition < inHeight) { - // We have crossed a row boundary - theYRatio = (unsigned short)((theYPosition << 8) / inHeight); - theYInvRatio = (unsigned short)((1 << 8) - theYRatio); - - for (theColumn = 0; theColumn < inDstWidth; theColumn++) { - if (theXPosition < inWidth) { - theXRatio = (unsigned short)((theXPosition << 8) / inWidth); - theXInvRatio = (unsigned short)((1 << 8) - theXRatio); - theLeftRatio = (theXRatio * theYRatio) >> 8; - theRightRatio = (theXInvRatio * theYRatio) >> 8; - theLowLeftRatio = (theXRatio * theYInvRatio) >> 8; - theLowRightRatio = (theXInvRatio * theYInvRatio) >> 8; - // We are on a row and column boundary, thus each pixel here is the - // combination of four pixels (left right, low left, low right) - - // Left side first - theTemp = (inBuffer[theSrcIndex]); - theTemp += (inBuffer[theSrcIndex + 4]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); - theDstIndex++; - theSrcIndex++; - // Left side first - theTemp = (inBuffer[theSrcIndex]); - theTemp += (inBuffer[theSrcIndex + 4]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); - theDstIndex++; - theSrcIndex++; - // Left side first - theTemp = (inBuffer[theSrcIndex]); - theTemp += (inBuffer[theSrcIndex + 4]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); - theDstIndex++; - theSrcIndex++; - // Left side first - theTemp = (inBuffer[theSrcIndex]); - theTemp += (inBuffer[theSrcIndex + 4]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); - theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); - theDstIndex++; - theSrcIndex++; - // Reset our position calculation - theXPosition = inDstWidth - inWidth + theXPosition; - } else { - - theTemp = inBuffer[theSrcIndex]; - theTemp += inBuffer[theSrcIndex + theSrcLineLength]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theDstIndex++; - theTemp = inBuffer[theSrcIndex + 1]; - theTemp += inBuffer[theSrcIndex + theSrcLineLength + 1]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theDstIndex++; - theTemp = inBuffer[theSrcIndex + 2]; - theTemp += inBuffer[theSrcIndex + theSrcLineLength + 2]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theDstIndex++; - theTemp = inBuffer[theSrcIndex + 3]; - theTemp += inBuffer[theSrcIndex + theSrcLineLength + 3]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theDstIndex++; - // Reset our position calculation - theXPosition -= inWidth; - } - } - // Reset our position calculation - theYPosition = inDstHeight - inHeight + theYPosition; - // Make the src index point to the next line - theSrcIndex += 4; - } // Ends the if to check if we are crossing a row boundary - // Else we are not crossing a row boundary - else { - for (theColumn = 0; theColumn < inDstWidth; theColumn++) { - // If we are crossing a column boundary - if (theXPosition < inWidth) { - theXRatio = (unsigned short)((theXPosition << 8) / inWidth); - theXInvRatio = (unsigned short)((1 << 8) - theXRatio); - - theTemp = inBuffer[theSrcIndex]; - theTemp += inBuffer[theSrcIndex + 4]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theSrcIndex++; - theDstIndex++; - theTemp = inBuffer[theSrcIndex]; - theTemp += inBuffer[theSrcIndex + 4]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theSrcIndex++; - theDstIndex++; - theTemp = inBuffer[theSrcIndex]; - theTemp += inBuffer[theSrcIndex + 4]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theSrcIndex++; - theDstIndex++; - theTemp = inBuffer[theSrcIndex]; - theTemp += inBuffer[theSrcIndex + 4]; - outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); - theSrcIndex++; - theDstIndex++; - - theXPosition = inDstWidth - inWidth + theXPosition; - } - // Else we are not crossing a column boundary - else { - *((long *)(outBuffer + theDstIndex)) = *((long *)(inBuffer + theSrcIndex)); - theDstIndex += 4; - theXPosition -= inWidth; - } - } - // reset our y position indicator - theYPosition -= inHeight; - // reset the src index to the beginning the next line - theSrcIndex += 4; - // reset src index to the beginning of this line - theSrcIndex -= theSrcLineLength; - } // End of else for row boundary - } // End of for loop for iterating through all rows -} - -//============================================================================== -/** - * @param inSrcBuffer - */ -void CImageScaler::ReduceCols(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, - unsigned char *&outDstBuffer, long inDstWidth) -{ - long theDDAConst = static_cast(1024.0 * inDstWidth / inSrcWidth); - long theDDAAccum = 0L; - long thePixelCount; - - long theSrcRow; - long theSrcCol; - long theDstCol; - - long theRedAccum; - long theGreenAccum; - long theBlueAccum; - long theAlphaAccum; - - unsigned char *theDstPointer = outDstBuffer; - unsigned char *theSrcPointer = inSrcBuffer; - unsigned char *theSrcRowPointer; - unsigned char *theDstRowPointer; - - long theSrcStepSize = 4; - long theDstStepSize = 4; - - for (theSrcRow = 0; theSrcRow < inSrcHeight; ++theSrcRow) { - - theSrcRowPointer = theSrcPointer + (theSrcRow * inSrcWidth * theSrcStepSize); - theDstRowPointer = theDstPointer + (theSrcRow * inDstWidth * theDstStepSize); - - theSrcCol = 0L; - theDstCol = 0L; - theRedAccum = 0L; - theGreenAccum = 0L; - theBlueAccum = 0L; - theAlphaAccum = 0L; - thePixelCount = 0L; - theDDAAccum = 0L; - - while (theSrcCol < inSrcWidth) { - while ((theDDAAccum < 1024L) && (theSrcCol < inSrcWidth)) { - theRedAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 0]; - theGreenAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 1]; - theBlueAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 2]; - theAlphaAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 3]; - - theDDAAccum += theDDAConst; - thePixelCount += 1024L; - ++theSrcCol; - } - - theDDAAccum = (theSrcCol < inSrcWidth) ? (theDDAAccum - 1024L) : (0L); - thePixelCount -= theDDAAccum; - - theRedAccum -= - theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 0]; - theGreenAccum -= - theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 1]; - theBlueAccum -= - theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 2]; - theAlphaAccum -= - theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 3]; - - theDstRowPointer[(theDstCol * theDstStepSize) + 0] = - (unsigned char)(theRedAccum / thePixelCount); - theDstRowPointer[(theDstCol * theDstStepSize) + 1] = - (unsigned char)(theGreenAccum / thePixelCount); - theDstRowPointer[(theDstCol * theDstStepSize) + 2] = - (unsigned char)(theBlueAccum / thePixelCount); - theDstRowPointer[(theDstCol * theDstStepSize) + 3] = - (unsigned char)(theAlphaAccum / thePixelCount); - - thePixelCount = 1024L - theDDAAccum; - ++theDstCol; - - if (theDstCol >= inDstWidth) { - break; - } - - theRedAccum = - thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 0]; - theGreenAccum = - thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 1]; - theBlueAccum = - thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 2]; - theAlphaAccum = - thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 3]; - } - } -} - -//============================================================================== -/** - * @param inSrcBuffer - */ -void CImageScaler::ReduceRows(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, - unsigned char *&outDstBuffer, long inDstHeight) -{ - long theDDAConst = static_cast(1024.0 * inDstHeight / inSrcHeight); - long theDDAAccum = 0; - long thePixelCount; - - long theSrcRow; - long theSrcCol; - long theDstRow; - - long theRedAccum; - long theGreenAccum; - long theBlueAccum; - long theAlphaAccum; - - unsigned char *theDstPointer = outDstBuffer; - unsigned char *theSrcPointer = inSrcBuffer; - unsigned char *theSrcColPointer = NULL; - unsigned char *theDstColPointer = NULL; - - long theStepSize = 4; - long theSrcStride = 4 * inSrcWidth; - long theDstStride = 4 * inSrcWidth; - - for (theSrcCol = 0; theSrcCol < inSrcWidth; ++theSrcCol) { - theSrcColPointer = theSrcPointer + (theSrcCol * theStepSize); - theDstColPointer = theDstPointer + (theSrcCol * theStepSize); - - theSrcRow = 0L; - theDstRow = 0L; - theRedAccum = 0L; - theGreenAccum = 0L; - theBlueAccum = 0L; - theAlphaAccum = 0L; - thePixelCount = 0L; - - theDDAAccum = 0L; - - while (theSrcRow < inSrcHeight) { - while ((theDDAAccum < 1024L) && (theSrcRow < inSrcHeight)) { - theRedAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 0]; - theGreenAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 1]; - theBlueAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 2]; - theAlphaAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 3]; - - theDDAAccum += theDDAConst; - thePixelCount += 1024L; - ++theSrcRow; - } - - theDDAAccum = (theSrcRow < inSrcHeight) ? (theDDAAccum - 1024L) : (0L); - thePixelCount -= theDDAAccum; - - theRedAccum -= - theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 0]; - theGreenAccum -= - theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 1]; - theBlueAccum -= - theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 2]; - theAlphaAccum -= - theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 3]; - - theDstColPointer[(theDstRow * theDstStride) + 0] = - (unsigned char)(theRedAccum / thePixelCount); - theDstColPointer[(theDstRow * theDstStride) + 1] = - (unsigned char)(theGreenAccum / thePixelCount); - theDstColPointer[(theDstRow * theDstStride) + 2] = - (unsigned char)(theBlueAccum / thePixelCount); - theDstColPointer[(theDstRow * theDstStride) + 3] = - (unsigned char)(theAlphaAccum / thePixelCount); - - thePixelCount = 1024L - theDDAAccum; - ++theDstRow; - - if (theDstRow >= inDstHeight) { - break; - } - - theRedAccum = - thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 0]; - theGreenAccum = - thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 1]; - theBlueAccum = - thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 2]; - theAlphaAccum = - thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 3]; - } - } -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderInputStreamFactory.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderInputStreamFactory.cpp deleted file mode 100644 index 1a418b1e..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderInputStreamFactory.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderInputStreamFactory.h" - -#include "stdio.h" - -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/string.h" -#include "EASTL/vector.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/FileTools.h" -#include "foundation/Qt3DSMutex.h" - -#include -#include -#include -#include -#include - -using namespace qt3ds::render; - -namespace { -struct SInputStream : public IRefCountedInputStream -{ - NVFoundationBase &m_Foundation; - QString m_Path; - QFile m_File; - volatile QT3DSI32 mRefCount; - - SInputStream(NVFoundationBase &inFoundation, const QString &inPath) - : m_Foundation(inFoundation) - , m_Path(inPath) - , m_File(inPath) - , mRefCount(0) - { - m_File.open(QIODevice::ReadOnly); - } - virtual ~SInputStream() - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - QT3DSU32 Read(NVDataRef data) override - { - return m_File.read((char *)data.begin(), data.size()); - } - - bool Write(NVConstDataRef /*data*/) override - { - QT3DS_ASSERT(false); - return false; - } - - void SetPosition(QT3DSI64 inOffset, qt3ds::foundation::SeekPosition::Enum inEnum) override - { - if (inOffset > QT3DS_MAX_I32 || inOffset < QT3DS_MIN_I32) { - qCCritical(INVALID_OPERATION, "Attempt to seek further than platform allows"); - QT3DS_ASSERT(false); - return; - } else { - CFileTools::SetStreamPosition(m_File, inOffset, inEnum); - } - } - QT3DSI64 GetPosition() const override - { - return m_File.pos(); - } - - static SInputStream *OpenFile(const QString &inPath, NVFoundationBase &inFoundation) - { - return QT3DS_NEW(inFoundation.getAllocator(), SInputStream)(inFoundation, inPath); - } -}; - -typedef eastl::basic_string TStrType; -struct SFactory : public IInputStreamFactory -{ - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - - Mutex m_Mutex; - typedef Mutex::ScopedLock TScopedLock; - - const QString QT3DSTUDIO_TAG = QStringLiteral("qt3dstudio"); - - SFactory(NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , mRefCount(0) - , m_Mutex(inFoundation.getAllocator()) - { - // Add the top-level qrc directory - if (!QDir::searchPaths(QT3DSTUDIO_TAG).contains(QLatin1String(":/"))) - QDir::addSearchPath(QT3DSTUDIO_TAG, QStringLiteral(":/")); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - QFileInfo matchCaseInsensitiveFile(const QString& file, bool inQuiet) - { - if (!inQuiet) { - // Some assets are searched for in several levels in the project structure, - // we don't want to alert user of things that can't be fixed in the presentation - // itself. - qCWarning(WARNING, PERF_INFO, "Case-insensitive matching with file: %s", - file.toLatin1().constData()); - } - const QStringList searchDirectories = QDir::searchPaths(QT3DSTUDIO_TAG); - for (const auto &directoryPath : searchDirectories) { - QFileInfo fileInfo(file); - QDirIterator it(directoryPath, {fileInfo.fileName()}, QDir::NoFilter, - QDirIterator::Subdirectories); - while (it.hasNext()) { - QString filePath = it.next(); - if (filePath.compare(QDir::cleanPath(directoryPath + '/' + file), - Qt::CaseInsensitive) == 0) { - return QFileInfo(filePath); - } - } - } - - return QFileInfo(); - } - - void AddSearchDirectory(const char8_t *inDirectory) override - { - TScopedLock __factoryLocker(m_Mutex); - QString localDir = CFileTools::NormalizePathForQtUsage(inDirectory); - QDir directory(localDir); - if (!directory.exists()) { - qCCritical(INTERNAL_ERROR, "Adding search directory: %s", inDirectory); - return; - } - - if (!QDir::searchPaths(QT3DSTUDIO_TAG).contains(localDir)) - QDir::addSearchPath(QT3DSTUDIO_TAG, localDir); - } - - - IRefCountedInputStream *GetStreamForFile(const QString &inFilename, bool inQuiet) override - { - TScopedLock __factoryLocker(m_Mutex); - QString localFile = CFileTools::NormalizePathForQtUsage(inFilename); - QFileInfo fileInfo = QFileInfo(localFile); - SInputStream *inputStream = nullptr; - // Try to match the file with the search paths - if (!fileInfo.exists()) - fileInfo.setFile(QStringLiteral("qt3dstudio:") + localFile); - - // Try to match the case-insensitive file with the given search paths - if (!fileInfo.exists()) - fileInfo = matchCaseInsensitiveFile(localFile, inQuiet); - - if (fileInfo.exists()) - inputStream = SInputStream::OpenFile(fileInfo.absoluteFilePath(), m_Foundation); - - if (!inputStream && !inQuiet) { - // Print extensive debugging information. - qCCritical(INTERNAL_ERROR, "Failed to find file: %s", localFile.toLatin1().constData()); - qCCritical(INTERNAL_ERROR, "Searched path: %s", - QDir::searchPaths(QT3DSTUDIO_TAG).join(',').toLatin1().constData()); - } - return inputStream; - } - - bool GetPathForFile(const QString &inFilename, QString &outFile, - bool inQuiet = false) override - { - NVScopedRefCounted theStream = - GetStreamForFile(inFilename, inQuiet); - if (theStream) { - SInputStream *theRealStream = static_cast(theStream.mPtr); - outFile = theRealStream->m_Path; - return true; - } - return false; - } -}; -} - -IInputStreamFactory &IInputStreamFactory::Create(NVFoundationBase &inFoundation) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SFactory)(inFoundation); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPathManager.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPathManager.cpp deleted file mode 100644 index 44e06681..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPathManager.cpp +++ /dev/null @@ -1,1964 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderPathManager.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSContainers.h" -#include "EASTL/string.h" -#include "Qt3DSRenderContextCore.h" -#include "foundation/Utils.h" -#include "foundation/StringConversionImpl.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderInputAssembler.h" -#include "Qt3DSRenderPath.h" -#include "EASTL/sort.h" -#include "render/Qt3DSRenderContext.h" -#include "render/Qt3DSRenderVertexBuffer.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderShaderCodeGenerator.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderPathRenderContext.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include "Qt3DSRenderCustomMaterialShaderGenerator.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "../RendererImpl/Qt3DSVertexPipelineImpl.h" -#include "foundation/Qt3DSMathUtils.h" -#include "render/Qt3DSRenderPathRender.h" -#include "render/Qt3DSRenderPathSpecification.h" -#include "Qt3DSRenderPathSubPath.h" -#include "Qt3DSImportPath.h" -#include "Qt3DSRenderPathMath.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "foundation/Qt3DSMutex.h" - -using namespace qt3ds::render; -using qt3ds::render::NVRenderCachedShaderProperty; -using qt3ds::render::NVRenderCachedShaderBuffer; -using qt3ds::render::NVRenderStencilFunctionArgument; -using qt3ds::render::NVRenderBoolOp; -using qt3ds::render::NVRenderStencilOperationArgument; -using qt3ds::render::NVRenderStencilOp; - -typedef qt3dsimp::SPathBuffer TImportPathBuffer; -using namespace qt3ds::render::path; - -typedef eastl::pair TStrStrPair; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const TStrStrPair &item) const - { - return eastl::hash()(item.first) - ^ eastl::hash()(item.second); - } -}; -} - -struct SPathShaderMapKey -{ - CRegisteredString m_Name; - SShaderDefaultMaterialKey m_MaterialKey; - size_t m_HashCode; - SPathShaderMapKey(CRegisteredString inName, SShaderDefaultMaterialKey inKey) - : m_Name(inName) - , m_MaterialKey(inKey) - { - m_HashCode = eastl::hash()(m_Name) ^ m_MaterialKey.hash(); - } - bool operator==(const SPathShaderMapKey &inKey) const - { - return m_Name == inKey.m_Name && m_MaterialKey == inKey.m_MaterialKey; - } -}; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SPathShaderMapKey &inKey) const { return inKey.m_HashCode; } -}; -} - -namespace { - -struct SPathSubPathBuffer -{ - NVAllocatorCallback &m_Allocator; - nvvector m_SourceData; - SPathDirtyFlags m_Flags; - SPathSubPath &m_SubPath; - bool m_Closed; - - QT3DSI32 m_RefCount; - - SPathSubPathBuffer(NVAllocatorCallback &alloc, SPathSubPath &inSubPath) - : m_Allocator(alloc) - , m_SourceData(alloc, "m_SourceData") - , m_SubPath(inSubPath) - , m_Closed(false) - , m_RefCount(0) - { - } - - void addRef() { atomicIncrement(&m_RefCount); } - void release() - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Allocator); - NVDelete(alloc, this); - } - } -}; - -struct SImportPathWrapper -{ - NVAllocatorCallback &m_Alloc; - qt3dsimp::SPathBuffer *m_Path; - QT3DSI32 m_RefCount; - - SImportPathWrapper(NVAllocatorCallback &inAlloc, qt3dsimp::SPathBuffer &inPath) - : m_Alloc(inAlloc) - , m_Path(&inPath) - , m_RefCount(0) - { - } - - ~SImportPathWrapper() { m_Path->Free(m_Alloc); } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Alloc); - NVDelete(alloc, this); - } - } -}; - -typedef NVScopedRefCounted TPathBufferPtr; - -struct SPathBuffer -{ - NVAllocatorCallback &m_Allocator; - nvvector> m_SubPaths; - TPathBufferPtr m_PathBuffer; - - NVScopedRefCounted m_PatchData; - NVScopedRefCounted m_InputAssembler; - NVScopedRefCounted m_PathRender; - - QT3DSVec2 m_BeginTaperData; - QT3DSVec2 m_EndTaperData; - QT3DSU32 m_NumVertexes; - PathTypes::Enum m_PathType; - QT3DSF32 m_Width; - QT3DSF32 m_CPUError; - NVBounds3 m_Bounds; - Option m_BeginTaper; - Option m_EndTaper; - CRegisteredString m_SourcePath; - - // Cached data for geometry paths - - SPathDirtyFlags m_Flags; - - QT3DSI32 m_RefCount; - - SPathBuffer(NVAllocatorCallback &alloc) - : m_Allocator(alloc) - , m_SubPaths(alloc, "m_SubPaths") - , m_NumVertexes(0) - , m_PathType(PathTypes::Geometry) - , m_Width(0.0f) - , m_CPUError(0.0f) - , m_Bounds(NVBounds3::empty()) - , m_RefCount(0) - { - } - - void addRef() { atomicIncrement(&m_RefCount); } - void release() - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Allocator); - NVDelete(alloc, this); - } - } - - void ClearGeometryPathData() - { - m_PatchData = NULL; - m_InputAssembler = NULL; - } - - void ClearPaintedPathData() { m_PathRender = NULL; } - - qt3dsimp::SPathBuffer GetPathData(qt3dsimp::IPathBufferBuilder &inSpec) - { - if (m_SubPaths.size()) { - inSpec.Clear(); - for (QT3DSU32 idx = 0, end = m_SubPaths.size(); idx < end; ++idx) { - const SPathSubPathBuffer &theSubPathBuffer(*m_SubPaths[idx]); - for (QT3DSU32 equationIdx = 0, equationEnd = theSubPathBuffer.m_SourceData.size(); - equationIdx < equationEnd; ++equationIdx) { - const SPathAnchorPoint &thePoint = theSubPathBuffer.m_SourceData[equationIdx]; - if (equationIdx == 0) { - inSpec.MoveTo(thePoint.m_Position); - } else { - const SPathAnchorPoint &thePrevPoint = - theSubPathBuffer.m_SourceData[equationIdx - 1]; - QT3DSVec2 c1 = IPathManager::GetControlPointFromAngleDistance( - thePrevPoint.m_Position, thePrevPoint.m_OutgoingAngle, - thePrevPoint.m_OutgoingDistance); - QT3DSVec2 c2 = IPathManager::GetControlPointFromAngleDistance( - thePoint.m_Position, thePoint.m_IncomingAngle, - thePoint.m_IncomingDistance); - QT3DSVec2 p2 = thePoint.m_Position; - inSpec.CubicCurveTo(c1, c2, p2); - } - } - if (theSubPathBuffer.m_Closed) - inSpec.Close(); - } - return inSpec.GetPathBuffer(); - } else if (m_PathBuffer.mPtr) - return *m_PathBuffer.mPtr->m_Path; - return qt3dsimp::SPathBuffer(); - } - - void SetPathType(PathTypes::Enum inPathType) - { - if (inPathType != m_PathType) { - switch (m_PathType) { - case PathTypes::Geometry: - ClearGeometryPathData(); - break; - case PathTypes::Painted: - ClearPaintedPathData(); - break; - default: - QT3DS_ALWAYS_ASSERT_MESSAGE("Unexpected path type"); - // No further processing for unexpected path type - return; - } - m_Flags.clearOrSet(true, PathDirtyFlagValues::PathType); - } - m_PathType = inPathType; - } - - static Option ToTaperInfo(PathCapping::Enum capping, QT3DSF32 capOffset, - QT3DSF32 capOpacity, QT3DSF32 capWidth) - { - if (capping == PathCapping::Noner) - return Empty(); - - return STaperInformation(capOffset, capOpacity, capWidth); - } - - void SetBeginTaperInfo(PathCapping::Enum capping, QT3DSF32 capOffset, QT3DSF32 capOpacity, - QT3DSF32 capWidth) - { - Option newBeginInfo = - ToTaperInfo(capping, capOffset, capOpacity, capWidth); - if (!OptionEquals(newBeginInfo, m_BeginTaper)) { - m_BeginTaper = newBeginInfo; - m_Flags.clearOrSet(true, PathDirtyFlagValues::BeginTaper); - } - } - - void SetEndTaperInfo(PathCapping::Enum capping, QT3DSF32 capOffset, QT3DSF32 capOpacity, - QT3DSF32 capWidth) - { - Option newEndInfo = - ToTaperInfo(capping, capOffset, capOpacity, capWidth); - if (!OptionEquals(newEndInfo, m_EndTaper)) { - m_EndTaper = newEndInfo; - m_Flags.clearOrSet(true, PathDirtyFlagValues::EndTaper); - } - } - - void SetWidth(QT3DSF32 inWidth) - { - if (inWidth != m_Width) { - m_Width = inWidth; - m_Flags.clearOrSet(true, PathDirtyFlagValues::Width); - } - } - - void SetCPUError(QT3DSF32 inError) - { - if (inError != m_CPUError) { - m_CPUError = inError; - m_Flags.clearOrSet(true, PathDirtyFlagValues::CPUError); - } - } -}; - -struct SPathGeneratedShader -{ - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_Width; - NVRenderCachedShaderProperty m_InnerTessAmount; - NVRenderCachedShaderProperty m_EdgeTessAmount; - NVRenderCachedShaderProperty m_BeginTaperData; - NVRenderCachedShaderProperty m_EndTaperData; - NVRenderCachedShaderProperty m_WireframeViewMatrix; - - QT3DSI32 m_RefCount; - - SPathGeneratedShader(NVRenderShaderProgram &sh, NVAllocatorCallback &alloc) - : m_Allocator(alloc) - , m_Shader(sh) - , m_Width("pathWidth", sh) - , m_InnerTessAmount("tessInnerLevel", sh) - , m_EdgeTessAmount("tessEdgeLevel", sh) - , m_BeginTaperData("beginTaperInfo", sh) - , m_EndTaperData("endTaperInfo", sh) - , m_WireframeViewMatrix("viewport_matrix", sh) - , m_RefCount(0) - { - m_Shader.addRef(); - } - ~SPathGeneratedShader() { m_Shader.release(); } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) { - NVAllocatorCallback &allocator(m_Allocator); - NVDelete(allocator, this); - } - } -}; - -struct SPathVertexPipeline : public SVertexPipelineImpl -{ - - SPathVertexPipeline(IShaderProgramGenerator &inProgGenerator, - IMaterialShaderGenerator &inMaterialGenerator, NVAllocatorCallback &inAlloc, - IStringTable &inStringTable, bool inWireframe) - : SVertexPipelineImpl(inAlloc, inMaterialGenerator, inProgGenerator, inStringTable, - inWireframe) - { - } - - // Trues true if the code was *not* set. - bool SetCode(GenerationFlagValues::Enum inCode) - { - if (((QT3DSU32)m_GenerationFlags & inCode) != 0) - return true; - m_GenerationFlags |= inCode; - return false; - } - - void AssignTessEvalVarying(const char8_t *inVarName, const char8_t *inVarValueExpr) - { - const char8_t *ext = ""; - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) - ext = "TE"; - TessEval() << "\t" << inVarName << ext << " = " << inVarValueExpr << ";" << Endl; - } - - void AssignOutput(const char8_t *inVarName, const char8_t *inVarValueExpr) override - { - AssignTessEvalVarying(inVarName, inVarValueExpr); - } - - void InitializeTessShaders() - { - IShaderStageGenerator &theTessControl(TessControl()); - IShaderStageGenerator &theTessEval(TessEval()); - - // first setup tessellation control shader - theTessControl.AddUniform("tessEdgeLevel", "float"); - theTessControl.AddUniform("tessInnerLevel", "float"); - - theTessControl.AddInclude("tessellationPath.glsllib"); - - theTessControl.Append("void main() {\n"); - theTessControl.Append( - "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); - theTessControl.Append("\ttessShader( tessEdgeLevel, tessInnerLevel );\n"); - - bool hasGeometryShader = - ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry) != NULL; - - // second setup tessellation control shader - eastl::string outExt(""); - if (hasGeometryShader) - outExt = "TE"; - - theTessEval.AddInclude("tessellationPath.glsllib"); - theTessEval.AddUniform("normal_matrix", "mat3"); - theTessEval.AddUniform("model_view_projection", "mat4"); - theTessEval.AddUniform("pathWidth", "float"); - theTessEval.AddUniform("material_diffuse", "vec4"); - AddInterpolationParameter("varTexCoord0", "vec2"); - AddInterpolationParameter("varTessOpacity", "float"); - - theTessEval.Append("void main() {\n"); - theTessEval.Append("\tSTessShaderResult shaderResult = tessShader( pathWidth );\n"); - theTessEval.Append("\tvec3 pos = shaderResult.m_Position;\n"); - AssignTessEvalVarying("varTessOpacity", "shaderResult.m_Opacity"); - AssignTessEvalVarying("varTexCoord0", "shaderResult.m_TexCoord.xy"); - if (hasGeometryShader) - theTessEval << "\tvec2 varTexCoord0 = shaderResult.m_TexCoord.xy;\n"; - - theTessEval << "\tvec3 object_normal = vec3(0.0, 0.0, 1.0);\n"; - theTessEval << "\tvec3 world_normal = normal_matrix * object_normal;\n"; - theTessEval << "\tvec3 tangent = vec3( shaderResult.m_Tangent, 0.0 );\n"; - theTessEval << "\tvec3 binormal = vec3( shaderResult.m_Binormal, 0.0 );\n"; - - // These are necessary for texture generation. - theTessEval << "\tvec3 uTransform;" << Endl; - theTessEval << "\tvec3 vTransform;" << Endl; - - if (m_DisplacementImage) { - MaterialGenerator().GenerateImageUVCoordinates(*this, m_DisplacementIdx, 0, - *m_DisplacementImage); - theTessEval.AddUniform("displaceAmount", "float"); - theTessEval.AddUniform("model_matrix", "mat4"); - theTessEval.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - IDefaultMaterialShaderGenerator::SImageVariableNames theVarNames = - MaterialGenerator().GetImageVariableNames(m_DisplacementIdx); - - theTessEval.AddUniform(theVarNames.m_ImageSampler, "sampler2D"); - IDefaultMaterialShaderGenerator::SImageVariableNames theNames = - MaterialGenerator().GetImageVariableNames(m_DisplacementIdx); - theTessEval << "\tpos = defaultMaterialFileDisplacementTexture( " - << theNames.m_ImageSampler << ", displaceAmount, " - << theNames.m_ImageFragCoords << outExt.c_str() << ", vec3( 0.0, 0.0, 1.0 )" - << ", pos.xyz );" << Endl; - } - } - void FinalizeTessControlShader() {} - - void FinalizeTessEvaluationShader() - { - eastl::string outExt(""); - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) - outExt = "TE"; - - IShaderStageGenerator &tessEvalShader( - *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); - tessEvalShader.Append("\tgl_Position = model_view_projection * vec4( pos, 1.0 );\n"); - } - - void BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override - { - SetupDisplacement(displacementImageIdx, displacementImage); - - TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); - theStages |= ShaderGeneratorStages::TessControl; - theStages |= ShaderGeneratorStages::TessEval; - if (m_Wireframe) { - theStages |= ShaderGeneratorStages::Geometry; - } - ProgramGenerator().BeginProgram(theStages); - InitializeTessShaders(); - if (m_Wireframe) { - InitializeWireframeGeometryShader(); - } - // Open up each stage. - IShaderStageGenerator &vertexShader(Vertex()); - - vertexShader.AddIncoming("attr_pos", "vec4"); - - // useless vert shader because real work is done in TES. - vertexShader << "void main()\n" - "{\n"; - vertexShader << "\tgl_Position = attr_pos;\n"; // if tessellation is enabled pass down - // object coordinates; - vertexShader << "}\n"; - } - - void BeginFragmentGeneration() override - { - Fragment().AddUniform("material_diffuse", "vec4"); - Fragment() << "void main()" << Endl << "{" << Endl; - // We do not pass object opacity through the pipeline. - Fragment() << "\tfloat object_opacity = varTessOpacity * material_diffuse.a;" << Endl; - } - void DoGenerateUVCoords(QT3DSU32) override - { - // these are always generated regardless - } - - // fragment shader expects varying vertex normal - // lighting in vertex pipeline expects world_normal - void DoGenerateWorldNormal() override { AssignTessEvalVarying("varNormal", "world_normal"); } - void DoGenerateObjectNormal() override - { - AssignTessEvalVarying("varObjectNormal", "object_normal"); - } - void DoGenerateWorldPosition() override - { - TessEval().AddUniform("model_matrix", "mat4"); - TessEval() - << "\tvec3 local_model_world_position = vec3((model_matrix * vec4(pos, 1.0)).xyz);\n"; - } - void DoGenerateVarTangentAndBinormal() override - { - TessEval().AddUniform("normal_matrix", "mat3"); - AssignOutput("varTangent", "normal_matrix * tangent"); - AssignOutput("varBinormal", "normal_matrix * binormal"); - } - - void DoGenerateVertexColor() override - { - Vertex().AddIncoming("attr_color", "vec3"); - Vertex() << "\tvarColor = attr_color;" << Endl; - } - - void EndVertexGeneration() override - { - - if (HasTessellation()) { - // finalize tess control shader - FinalizeTessControlShader(); - // finalize tess evaluation shader - FinalizeTessEvaluationShader(); - - TessControl().Append("}"); - TessEval().Append("}"); - } - if (m_Wireframe) { - // finalize geometry shader - FinalizeWireframeGeometryShader(); - Geometry().Append("}"); - } - } - - void EndFragmentGeneration() override { Fragment().Append("}"); } - - void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override - { - m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); - Fragment().AddIncoming(inName, inType); - if (HasTessellation()) { - eastl::string nameBuilder; - nameBuilder.assign(inName); - if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) - nameBuilder.append("TE"); - - TessEval().AddOutgoing(nameBuilder.c_str(), inType); - } - } - - IShaderStageGenerator &ActiveStage() override { return TessEval(); } -}; - -struct SPathXYGeneratedShader -{ - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - NVRenderCachedShaderProperty m_RectDimensions; - NVRenderCachedShaderProperty m_ModelMatrix; - NVRenderCachedShaderProperty m_CameraPosition; - NVRenderCachedShaderProperty m_CameraProperties; - QT3DSI32 m_RefCount; - - SPathXYGeneratedShader(NVRenderShaderProgram &sh, NVAllocatorCallback &alloc) - : m_Allocator(alloc) - , m_Shader(sh) - , m_RectDimensions("uni_rect_dimensions", sh) - , m_ModelMatrix("model_matrix", sh) - , m_CameraPosition("camera_position", sh) - , m_CameraProperties("camera_properties", sh) - , m_RefCount(0) - { - m_Shader.addRef(); - } - virtual ~SPathXYGeneratedShader() { m_Shader.release(); } - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) { - NVAllocatorCallback &allocator(m_Allocator); - NVDelete(allocator, this); - } - } -}; - -// Helper implements the vertex pipeline for mesh subsets when bound to the default material. -// Should be completely possible to use for custom materials with a bit of refactoring. -struct SXYRectVertexPipeline : public SVertexPipelineImpl -{ - - SXYRectVertexPipeline(IShaderProgramGenerator &inProgGenerator, - IMaterialShaderGenerator &inMaterialGenerator, - NVAllocatorCallback &inAlloc, IStringTable &inStringTable) - : SVertexPipelineImpl(inAlloc, inMaterialGenerator, inProgGenerator, inStringTable, false) - { - } - - void BeginVertexGeneration(QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override - { - m_DisplacementIdx = displacementImageIdx; - m_DisplacementImage = displacementImage; - - TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); - ProgramGenerator().BeginProgram(theStages); - // Open up each stage. - IShaderStageGenerator &vertexShader(Vertex()); - vertexShader.AddIncoming("attr_pos", "vec2"); - vertexShader.AddUniform("uni_rect_dimensions", "vec4"); - - vertexShader << "void main()" << Endl << "{" << Endl; - vertexShader << "\tvec3 uTransform;" << Endl; - vertexShader << "\tvec3 vTransform;" << Endl; - - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader - << "\tfloat posX = mix( uni_rect_dimensions.x, uni_rect_dimensions.z, attr_pos.x );" - << Endl; - vertexShader - << "\tfloat posY = mix( uni_rect_dimensions.y, uni_rect_dimensions.w, attr_pos.y );" - << Endl; - vertexShader << "\tvec3 pos = vec3(posX, posY, 0.0 );" << Endl; - vertexShader.Append("\tgl_Position = model_view_projection * vec4(pos, 1.0);"); - } - - void OutputParaboloidDepthShaders() - { - TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); - ProgramGenerator().BeginProgram(theStages); - IShaderStageGenerator &vertexShader(Vertex()); - vertexShader.AddIncoming("attr_pos", "vec2"); - vertexShader.AddUniform("uni_rect_dimensions", "vec4"); - vertexShader.AddUniform("model_view_projection", "mat4"); - vertexShader << "void main()" << Endl << "{" << Endl; - vertexShader - << "\tfloat posX = mix( uni_rect_dimensions.x, uni_rect_dimensions.z, attr_pos.x );" - << Endl; - vertexShader - << "\tfloat posY = mix( uni_rect_dimensions.y, uni_rect_dimensions.w, attr_pos.y );" - << Endl; - vertexShader << "\tvec3 pos = vec3(posX, posY, 0.0 );" << Endl; - IShaderProgramGenerator::OutputParaboloidDepthTessEval(vertexShader); - vertexShader << "}" << Endl; - - IShaderProgramGenerator::OutputParaboloidDepthFragment(Fragment()); - } - - void OutputCubeFaceDepthShaders() - { - TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); - ProgramGenerator().BeginProgram(theStages); - IShaderStageGenerator &vertexShader(Vertex()); - IShaderStageGenerator &fragmentShader(Fragment()); - vertexShader.AddIncoming("attr_pos", "vec2"); - vertexShader.AddUniform("uni_rect_dimensions", "vec4"); - vertexShader.AddUniform("model_matrix", "mat4"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.AddOutgoing("world_pos", "vec4"); - vertexShader.Append("void main() {"); - vertexShader.Append( - " float posX = mix( uni_rect_dimensions.x, uni_rect_dimensions.z, attr_pos.x );"); - vertexShader.Append( - " float posY = mix( uni_rect_dimensions.y, uni_rect_dimensions.w, attr_pos.y );"); - vertexShader.Append(" world_pos = model_matrix * vec4( posX, posY, 0.0, 1.0 );"); - vertexShader.Append(" world_pos /= world_pos.w;"); - vertexShader.Append( - " gl_Position = model_view_projection * vec4( posX, posY, 0.0, 1.0 );"); - vertexShader.Append("}"); - - fragmentShader.AddUniform("camera_position", "vec3"); - fragmentShader.AddUniform("camera_properties", "vec2"); - - BeginFragmentGeneration(); - fragmentShader.Append( - "\tfloat dist = 0.5 * length( world_pos.xyz - camera_position );"); // Why? - fragmentShader.Append( - "\tdist = (dist - camera_properties.x) / (camera_properties.y - camera_properties.x);"); - fragmentShader.Append("\tfragOutput = vec4(dist);"); - fragmentShader.Append("}"); - } - - void BeginFragmentGeneration() override - { - Fragment().AddUniform("material_diffuse", "vec4"); - Fragment() << "void main()" << Endl << "{" << Endl; - // We do not pass object opacity through the pipeline. - Fragment() << "\tfloat object_opacity = material_diffuse.a;" << Endl; - } - - void AssignOutput(const char8_t *inVarName, const char8_t *inVarValue) override - { - Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n"; - } - void DoGenerateUVCoords(QT3DSU32) override { Vertex() << "\tvarTexCoord0 = attr_pos;" << Endl; } - - // fragment shader expects varying vertex normal - // lighting in vertex pipeline expects world_normal - void DoGenerateWorldNormal() override - { - IShaderStageGenerator &vertexGenerator(Vertex()); - vertexGenerator.AddUniform("normal_matrix", "mat3"); - vertexGenerator.Append( - "\tvec3 world_normal = normalize(normal_matrix * vec3( 0.0, 0.0, 1.0) ).xyz;"); - vertexGenerator.Append("\tvarNormal = world_normal;"); - } - - void DoGenerateObjectNormal() override - { - AddInterpolationParameter("varObjectNormal", "vec3"); - Vertex().Append("\tvarObjectNormal = vec3(0.0, 0.0, 1.0 );"); - } - - void DoGenerateWorldPosition() override - { - Vertex().Append("\tvec3 local_model_world_position = (model_matrix * vec4(pos, 1.0)).xyz;"); - AssignOutput("varWorldPos", "local_model_world_position"); - } - - void DoGenerateVarTangentAndBinormal() override - { - Vertex().AddIncoming("attr_textan", "vec3"); - Vertex().AddIncoming("attr_binormal", "vec3"); - Vertex() << "\tvarTangent = normal_matrix * vec3(1.0, 0.0, 0.0);" << Endl - << "\tvarBinormal = normal_matrix * vec3(0.0, 1.0, 0.0);" << Endl; - } - - void DoGenerateVertexColor() override - { - Vertex().AddIncoming("attr_color", "vec3"); - Vertex() << "\tvarColor = attr_color;" << Endl; - } - - void EndVertexGeneration() override { Vertex().Append("}"); } - - void EndFragmentGeneration() override { Fragment().Append("}"); } - - void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override - { - m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); - Vertex().AddOutgoing(inName, inType); - Fragment().AddIncoming(inName, inType); - } - - IShaderStageGenerator &ActiveStage() override { return Vertex(); } -}; - -struct SPathManager : public IPathManager -{ - typedef nvhash_map> TPathBufferHash; - typedef nvhash_map> - TPathSubPathBufferHash; - typedef nvhash_map> TShaderMap; - typedef nvhash_map> - TPaintedShaderMap; - typedef nvhash_map TStringPathBufferMap; - - IQt3DSRenderContextCore &m_CoreContext; - IQt3DSRenderContext *m_RenderContext; - eastl::string m_IdBuilder; - TPathSubPathBufferHash m_SubPathBuffers; - TPathBufferHash m_Buffers; - nvvector m_SubdivResult; - nvvector m_KeyPointVec; - nvvector m_PatchBuffer; - TShaderMap m_PathGeometryShaders; - TPaintedShaderMap m_PathPaintedShaders; - TStringPathBufferMap m_SourcePathBufferMap; - Mutex m_PathBufferMutex; - - NVScopedRefCounted m_DepthShader; - NVScopedRefCounted m_DepthDisplacementShader; - NVScopedRefCounted m_GeometryShadowShader; - NVScopedRefCounted m_GeometryCubeShadowShader; - NVScopedRefCounted m_GeometryDisplacementShadowShader; - - NVScopedRefCounted m_PaintedDepthShader; - NVScopedRefCounted m_PaintedShadowShader; - NVScopedRefCounted m_PaintedCubeShadowShader; - NVScopedRefCounted m_PaintedRectInputAssembler; - NVScopedRefCounted m_PaintedRectVertexBuffer; - NVScopedRefCounted m_PaintedRectIndexBuffer; - - nvvector> m_DepthStencilStates; - - NVScopedRefCounted m_PathSpecification; - NVScopedRefCounted m_PathBuilder; - - QT3DSI32 m_RefCount; - - SPathManager(IQt3DSRenderContextCore &inRC) - : m_CoreContext(inRC) - , m_RenderContext(NULL) - , m_SubPathBuffers(inRC.GetAllocator(), "m_SubPathBuffers") - , m_Buffers(inRC.GetAllocator(), "m_Buffers") - , m_SubdivResult(inRC.GetAllocator(), "m_SubdivResult") - , m_KeyPointVec(inRC.GetAllocator(), "m_KeyPointVec") - , m_PatchBuffer(inRC.GetAllocator(), "m_QuadStrip") - , m_PathGeometryShaders(inRC.GetAllocator(), "m_PathGeometryShaders") - , m_PathPaintedShaders(inRC.GetAllocator(), "m_PathPaintedShaders") - , m_SourcePathBufferMap(inRC.GetAllocator(), "m_SourcePathBufferMap") - , m_PathBufferMutex(inRC.GetAllocator()) - , m_DepthStencilStates(inRC.GetAllocator(), "m_DepthStencilStates") - , m_RefCount(0) - { - } - - virtual ~SPathManager() { m_PaintedRectInputAssembler = NULL; } - - NVAllocatorCallback &GetAllocator() { return m_CoreContext.GetAllocator(); } - IStringTable &GetStringTable() { return m_CoreContext.GetStringTable(); } - NVFoundationBase &GetFoundation() { return m_CoreContext.GetFoundation(); } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(GetAllocator()); - NVDelete(alloc, this); - } - } - // Called during binary load which is heavily threaded. - void SetPathSubPathData(const SPathSubPath &inPath, - NVConstDataRef inPathCubicCurves) override - { - Mutex::ScopedLock __locker(m_PathBufferMutex); - eastl::pair inserter = - m_SubPathBuffers.insert(eastl::make_pair((SPathSubPath *)&inPath, - NVScopedRefCounted(NULL))); - if (!inserter.first->second) - inserter.first->second = QT3DS_NEW(GetAllocator(), SPathSubPathBuffer)( - GetAllocator(), const_cast(inPath)); - SPathSubPathBuffer &theBuffer = *inserter.first->second.mPtr; - theBuffer.m_SourceData.assign(inPathCubicCurves.begin(), inPathCubicCurves.end()); - theBuffer.m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); - } - - SPathBuffer *GetPathBufferObject(const SPath &inPath) - { - eastl::pair inserter = m_Buffers.insert( - eastl::make_pair((SPath *)&inPath, NVScopedRefCounted(NULL))); - if (inserter.second) { - inserter.first->second = QT3DS_NEW(GetAllocator(), SPathBuffer)(GetAllocator()); - } - return inserter.first->second.mPtr; - } - - SPathSubPathBuffer *GetPathBufferObject(const SPathSubPath &inSubPath) - { - TPathSubPathBufferHash::iterator iter = m_SubPathBuffers.find((SPathSubPath *)&inSubPath); - if (iter != m_SubPathBuffers.end()) - return iter->second.mPtr; - return NULL; - } - - NVDataRef GetPathSubPathBuffer(const SPathSubPath &inPath) override - { - SPathSubPathBuffer *theBuffer = GetPathBufferObject(inPath); - if (theBuffer) - return toDataRef(theBuffer->m_SourceData.data(), (QT3DSU32)theBuffer->m_SourceData.size()); - return NVDataRef(); - } - - NVDataRef ResizePathSubPathBuffer(const SPathSubPath &inPath, - QT3DSU32 inNumAnchors) override - { - SPathSubPathBuffer *theBuffer = GetPathBufferObject(inPath); - if (theBuffer == NULL) - SetPathSubPathData(inPath, NVConstDataRef()); - theBuffer = GetPathBufferObject(inPath); - theBuffer->m_SourceData.resize(inNumAnchors); - theBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); - return toDataRef(theBuffer->m_SourceData.data(), (QT3DSU32)theBuffer->m_SourceData.size()); - } - - // This needs to be done using roots of the first derivative. - NVBounds3 GetBounds(const SPath &inPath) override - { - NVBounds3 retval(NVBounds3::empty()); - - SPathBuffer *thePathBuffer = GetPathBufferObject(inPath); - if (thePathBuffer) { - SPathDirtyFlags geomDirtyFlags( - PathDirtyFlagValues::SourceData | PathDirtyFlagValues::BeginTaper - | PathDirtyFlagValues::EndTaper | PathDirtyFlagValues::Width - | PathDirtyFlagValues::CPUError); - - if ((((QT3DSU32)thePathBuffer->m_Flags) & (QT3DSU32)geomDirtyFlags) == 0) { - return thePathBuffer->m_Bounds; - } - } - - for (SPathSubPath *theSubPath = inPath.m_FirstSubPath; theSubPath; - theSubPath = theSubPath->m_NextSubPath) { - SPathSubPathBuffer *theBuffer = GetPathBufferObject(*theSubPath); - if (!theBuffer) - continue; - - QT3DSU32 numAnchors = theBuffer->m_SourceData.size(); - for (QT3DSU32 idx = 0, end = numAnchors; idx < end; ++idx) { - const SPathAnchorPoint &thePoint(theBuffer->m_SourceData[idx]); - QT3DSVec2 position(thePoint.m_Position); - retval.include(QT3DSVec3(position.x, position.y, 0.0f)); - if (idx) { - QT3DSVec2 incoming(IPathManagerCore::GetControlPointFromAngleDistance( - thePoint.m_Position, thePoint.m_IncomingAngle, - thePoint.m_IncomingDistance)); - retval.include(QT3DSVec3(incoming.x, incoming.y, 0.0f)); - } - - if (idx < (numAnchors - 1)) { - QT3DSVec2 outgoing(IPathManagerCore::GetControlPointFromAngleDistance( - thePoint.m_Position, thePoint.m_OutgoingAngle, - thePoint.m_OutgoingDistance)); - retval.include(QT3DSVec3(outgoing.x, outgoing.y, 0.0f)); - } - } - } - - return retval; - } - - IPathManager &OnRenderSystemInitialize(IQt3DSRenderContext &context) override - { - m_RenderContext = &context; - return *this; - } - - // find a point that will join these two curves *if* they are not first derivative continuous - static Option GetAdjoiningPoint(QT3DSVec2 prevC2, QT3DSVec2 point, QT3DSVec2 C1, QT3DSF32 pathWidth) - { - QT3DSVec2 incomingDxDy = (point - prevC2); - QT3DSVec2 outgoingDxDy = (C1 - point); - incomingDxDy.normalize(); - outgoingDxDy.normalize(); - float determinant = (incomingDxDy.x * outgoingDxDy.y) - (incomingDxDy.y * outgoingDxDy.x); - if (fabs(determinant) > .001f) { - float mult = determinant > 0.0f ? 1.0f : -1.0f; - QT3DSVec2 incomingNormal(incomingDxDy.y, -incomingDxDy.x); - QT3DSVec2 outgoingNormal(outgoingDxDy.y, -outgoingDxDy.x); - - QT3DSVec2 leftEdge = point + mult * incomingNormal * pathWidth; - QT3DSVec2 rightEdge = point + mult * outgoingNormal * pathWidth; - - return (leftEdge + rightEdge) / 2.0f; - } - return Empty(); - } - - Option> FindBreakEquation(QT3DSF32 inTaperStart) - { - QT3DSF32 lengthTotal = 0; - for (QT3DSU32 idx = 0, end = m_SubdivResult.size(); idx < end; ++idx) { - if (lengthTotal + m_SubdivResult[idx].m_Length > inTaperStart) { - QT3DSF32 breakTValue = (inTaperStart - lengthTotal) / m_SubdivResult[idx].m_Length; - nvvector::iterator breakIter = m_SubdivResult.begin() + idx; - SCubicBezierCurve theCurve(breakIter->m_P1, breakIter->m_C1, breakIter->m_C2, - breakIter->m_P2); - eastl::pair subdivCurve = - theCurve.SplitCubicBezierCurve(breakTValue); - QT3DSF32 originalBreakT = - breakIter->m_TStart + (breakIter->m_TStop - breakIter->m_TStart) * breakTValue; - // Update the existing item to point to the second equation - breakIter->m_P1 = subdivCurve.second.m_Points[0]; - breakIter->m_C1 = subdivCurve.second.m_Points[1]; - breakIter->m_C2 = subdivCurve.second.m_Points[2]; - breakIter->m_P2 = subdivCurve.second.m_Points[3]; - QT3DSF32 originalLength = breakIter->m_Length; - QT3DSF32 originalStart = breakIter->m_TStart; - breakIter->m_Length *= (1.0f - breakTValue); - breakIter->m_TStart = originalBreakT; - SResultCubic newCubic(subdivCurve.first.m_Points[0], subdivCurve.first.m_Points[1], - subdivCurve.first.m_Points[2], subdivCurve.first.m_Points[3], - breakIter->m_EquationIndex, originalStart, originalBreakT, - originalLength * breakTValue); - - m_SubdivResult.insert(breakIter, newCubic); - return eastl::make_pair(idx, breakTValue); - } - lengthTotal += m_SubdivResult[idx].m_Length; - } - return Empty(); - } - - bool PrepareGeometryPathForRender(const SPath &inPath, SPathBuffer &inPathBuffer) - { - - m_SubdivResult.clear(); - m_KeyPointVec.clear(); - const SPath &thePath(inPath); - - inPathBuffer.SetBeginTaperInfo(thePath.m_BeginCapping, thePath.m_BeginCapOffset, - thePath.m_BeginCapOpacity, thePath.m_BeginCapWidth); - inPathBuffer.SetEndTaperInfo(thePath.m_EndCapping, thePath.m_EndCapOffset, - thePath.m_EndCapOpacity, thePath.m_EndCapWidth); - inPathBuffer.SetWidth(inPath.m_Width); - inPathBuffer.SetCPUError(inPath.m_LinearError); - - SPathDirtyFlags geomDirtyFlags(PathDirtyFlagValues::SourceData - | PathDirtyFlagValues::BeginTaper - | PathDirtyFlagValues::EndTaper | PathDirtyFlagValues::Width - | PathDirtyFlagValues::CPUError); - - bool retval = false; - if (!inPathBuffer.m_PatchData - || (((QT3DSU32)inPathBuffer.m_Flags) & (QT3DSU32)geomDirtyFlags) != 0) { - qt3dsimp::SPathBuffer thePathData = inPathBuffer.GetPathData(*m_PathBuilder); - - QT3DSU32 dataIdx = 0; - QT3DSVec2 prevPoint(0, 0); - QT3DSU32 equationIdx = 0; - for (QT3DSU32 commandIdx = 0, commandEnd = thePathData.m_Commands.size(); - commandIdx < commandEnd; ++commandIdx) { - switch (thePathData.m_Commands[commandIdx]) { - case qt3dsimp::PathCommand::MoveTo: - prevPoint = - QT3DSVec2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - break; - case qt3dsimp::PathCommand::CubicCurveTo: { - QT3DSVec2 c1(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - QT3DSVec2 c2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - QT3DSVec2 p2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - OuterAdaptiveSubdivideBezierCurve( - m_SubdivResult, m_KeyPointVec, SCubicBezierCurve(prevPoint, c1, c2, p2), - NVMax(inPath.m_LinearError, 1.0f), equationIdx); - ++equationIdx; - prevPoint = p2; - } break; - case qt3dsimp::PathCommand::Close: - break; - - default: - QT3DS_ASSERT(false); - break; - } - } - - QT3DSF32 theLocalWidth = inPath.m_Width / 2.0f; - - QT3DSVec2 theBeginTaperData(theLocalWidth, thePath.m_GlobalOpacity); - QT3DSVec2 theEndTaperData(theLocalWidth, thePath.m_GlobalOpacity); - - QT3DSF32 pathLength = 0.0f; - for (QT3DSU32 idx = 0, end = m_SubdivResult.size(); idx < end; ++idx) - pathLength += m_SubdivResult[idx].m_Length; - - if (thePath.m_BeginCapping == PathCapping::Taper - || thePath.m_EndCapping == PathCapping::Taper) { - QT3DSF32 maxTaperStart = pathLength / 2.0f; - if (thePath.m_BeginCapping == PathCapping::Taper) { - // Can't start more than halfway across the path. - QT3DSF32 taperStart = NVMin(thePath.m_BeginCapOffset, maxTaperStart); - QT3DSF32 endTaperWidth = thePath.m_BeginCapWidth; - QT3DSF32 endTaperOpacity = thePath.m_GlobalOpacity * thePath.m_BeginCapOpacity; - theBeginTaperData = QT3DSVec2(endTaperWidth, endTaperOpacity); - // Find where we need to break the current equations. - Option> breakEquationAndT( - FindBreakEquation(taperStart)); - if (breakEquationAndT.hasValue()) { - QT3DSU32 breakEquation = breakEquationAndT->first; - - QT3DSF32 lengthTotal = 0; - for (QT3DSU32 idx = 0, end = breakEquation; idx <= end; ++idx) { - SResultCubic &theCubic = m_SubdivResult[idx]; - theCubic.m_Mode = SResultCubic::BeginTaper; - - theCubic.m_TaperMultiplier[0] = lengthTotal / taperStart; - lengthTotal += theCubic.m_Length; - theCubic.m_TaperMultiplier[1] = lengthTotal / taperStart; - } - } - } - if (thePath.m_EndCapping == PathCapping::Taper) { - QT3DSF32 taperStart = NVMin(thePath.m_EndCapOffset, maxTaperStart); - QT3DSF32 endTaperWidth = thePath.m_EndCapWidth; - QT3DSF32 endTaperOpacity = thePath.m_GlobalOpacity * thePath.m_EndCapOpacity; - theEndTaperData = QT3DSVec2(endTaperWidth, endTaperOpacity); - // Invert taper start so that the forward search works. - Option> breakEquationAndT( - FindBreakEquation(pathLength - taperStart)); - - if (breakEquationAndT.hasValue()) { - QT3DSU32 breakEquation = breakEquationAndT->first; - ++breakEquation; - - QT3DSF32 lengthTotal = 0; - for (QT3DSU32 idx = breakEquation, end = m_SubdivResult.size(); idx < end; - ++idx) { - SResultCubic &theCubic = m_SubdivResult[idx]; - theCubic.m_Mode = SResultCubic::EndTaper; - - theCubic.m_TaperMultiplier[0] = 1.0f - (lengthTotal / taperStart); - lengthTotal += theCubic.m_Length; - theCubic.m_TaperMultiplier[1] = 1.0f - (lengthTotal / taperStart); - } - } - } - } - - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - // Create quads out of each point. - if (m_SubdivResult.empty()) - return false; - - // Generate patches. - m_PatchBuffer.clear(); - QT3DSF32 pathWidth = thePath.m_Width / 2.0f; - // texture coords - float texCoordU = 0.0; - - for (QT3DSU32 idx = 0, end = m_SubdivResult.size(); idx < end; ++idx) { - // create patches - SResultCubic thePoint(m_SubdivResult[idx]); - - m_PatchBuffer.push_back(CreateVec4(thePoint.m_P1, thePoint.m_C1)); - m_PatchBuffer.push_back(CreateVec4(thePoint.m_C2, thePoint.m_P2)); - - // Now we need to take care of cases where the control points of the adjoining - // SubPaths - // do not line up; i.e. there is a discontinuity of the 1st derivative - // The simplest way to do this is to move the edge vertex to a halfway point - // between a line bisecting the two control lines - QT3DSVec2 incomingAdjoining(thePoint.m_P1); - QT3DSVec2 outgoingAdjoining(thePoint.m_P2); - if (idx) { - SResultCubic previousCurve = m_SubdivResult[idx - 1]; - if (previousCurve.m_EquationIndex != thePoint.m_EquationIndex) { - QT3DSF32 anchorWidth = - thePoint.GetP1Width(pathWidth, theBeginTaperData.x, theEndTaperData.x); - Option adjoining = GetAdjoiningPoint( - previousCurve.m_C2, thePoint.m_P1, thePoint.m_C1, anchorWidth); - if (adjoining.hasValue()) - incomingAdjoining = *adjoining; - } - } - if (idx < (end - 1)) { - SResultCubic nextCurve = m_SubdivResult[idx + 1]; - if (nextCurve.m_EquationIndex != thePoint.m_EquationIndex) { - QT3DSF32 anchorWidth = - thePoint.GetP2Width(pathWidth, theBeginTaperData.x, theEndTaperData.x); - Option adjoining = GetAdjoiningPoint(thePoint.m_C2, thePoint.m_P2, - nextCurve.m_C1, anchorWidth); - if (adjoining.hasValue()) - outgoingAdjoining = *adjoining; - } - } - m_PatchBuffer.push_back(CreateVec4(incomingAdjoining, outgoingAdjoining)); - - QT3DSVec4 taperData(0.0f); - taperData.x = thePoint.m_TaperMultiplier.x; - taperData.y = thePoint.m_TaperMultiplier.y; - // Note we could put a *lot* more data into this thing. - taperData.z = (QT3DSF32)thePoint.m_Mode; - m_PatchBuffer.push_back(taperData); - - // texture coord generation - // note we only generate u here. v is generated in the tess shader - // u coord for P1 and C1 - QT3DSVec2 udata(texCoordU, texCoordU + (thePoint.m_Length / pathLength)); - texCoordU = udata.y; - m_PatchBuffer.push_back(QT3DSVec4(udata.x, udata.y, 0.0, 0.0)); - } - - // buffer size is 3.0*4.0*bufSize - QT3DSU32 bufSize = (QT3DSU32)m_PatchBuffer.size() * sizeof(QT3DSVec4); - QT3DSU32 stride = sizeof(QT3DSVec4); - - if ((!inPathBuffer.m_PatchData) || inPathBuffer.m_PatchData->Size() < bufSize) { - inPathBuffer.m_PatchData = theRenderContext.CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Dynamic, bufSize, stride, - toU8DataRef(m_PatchBuffer.data(), (QT3DSU32)m_PatchBuffer.size())); - inPathBuffer.m_NumVertexes = (QT3DSU32)m_PatchBuffer.size(); - inPathBuffer.m_InputAssembler = NULL; - } else { - QT3DS_ASSERT(inPathBuffer.m_PatchData->Size() >= bufSize); - inPathBuffer.m_PatchData->UpdateBuffer( - toU8DataRef(m_PatchBuffer.data(), (QT3DSU32)m_PatchBuffer.size())); - } - - if (!inPathBuffer.m_InputAssembler) { - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry( - "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 4), - }; - - NVRenderDrawMode::Enum primType = NVRenderDrawMode::Patches; - - NVRenderAttribLayout *theLayout = - theRenderContext.CreateAttributeLayout(toConstDataRef(theEntries, 1)); - // How many vertices the TCS shader has access to in order to produce its output - // array of vertices. - const QT3DSU32 inputPatchVertexCount = 5; - inPathBuffer.m_InputAssembler = theRenderContext.CreateInputAssembler( - theLayout, toConstDataRef(inPathBuffer.m_PatchData.mPtr), NULL, - toConstDataRef(stride), toConstDataRef((QT3DSU32)0), primType, - inputPatchVertexCount); - } - inPathBuffer.m_BeginTaperData = theBeginTaperData; - inPathBuffer.m_EndTaperData = theEndTaperData; - - // cache bounds - NVBounds3 bounds = GetBounds(inPath); - inPathBuffer.m_Bounds.minimum = bounds.minimum; - inPathBuffer.m_Bounds.maximum = bounds.maximum; - } - - return retval; - } - - IMaterialShaderGenerator *GetMaterialShaderGenertator(SPathRenderContext &inRenderContext) - { - bool isDefaultMaterial = - (inRenderContext.m_Material.m_Type == GraphObjectTypes::DefaultMaterial); - - IMaterialShaderGenerator *theMaterialGenerator = NULL; - if (isDefaultMaterial) - theMaterialGenerator = &m_RenderContext->GetDefaultMaterialShaderGenerator(); - else - theMaterialGenerator = &m_RenderContext->GetCustomMaterialShaderGenerator(); - - return theMaterialGenerator; - } - - CRegisteredString GetMaterialNameForKey(SPathRenderContext &inRenderContext) - { - bool isDefaultMaterial = - (inRenderContext.m_Material.m_Type == GraphObjectTypes::DefaultMaterial); - - if (!isDefaultMaterial) { - ICustomMaterialSystem &theMaterialSystem(m_RenderContext->GetCustomMaterialSystem()); - const SCustomMaterial &theCustomMaterial( - reinterpret_cast(inRenderContext.m_Material)); - - return m_RenderContext->GetStringTable().RegisterStr( - theMaterialSystem.GetShaderName(theCustomMaterial)); - } - - return m_RenderContext->GetStringTable().RegisterStr(""); - } - - bool PreparePaintedPathForRender(const SPath &inPath, SPathBuffer &inPathBuffer) - { - NVRenderContext &theContext(this->m_RenderContext->GetRenderContext()); - if (!inPathBuffer.m_PathRender - || (((QT3DSU32)inPathBuffer.m_Flags) & PathDirtyFlagValues::SourceData)) { - if (!inPathBuffer.m_PathRender) { - inPathBuffer.m_PathRender = theContext.CreatePathRender(); - } - - if (inPathBuffer.m_PathRender == NULL || m_PathSpecification == NULL) { - // QT3DS_ASSERT( false ); - return false; - } - - m_PathSpecification->Reset(); - qt3dsimp::SPathBuffer thePathData = inPathBuffer.GetPathData(*m_PathBuilder); - - QT3DSU32 dataIdx = 0; - for (QT3DSU32 commandIdx = 0, commandEnd = thePathData.m_Commands.size(); - commandIdx < commandEnd; ++commandIdx) { - - switch (thePathData.m_Commands[commandIdx]) { - case qt3dsimp::PathCommand::MoveTo: - m_PathSpecification->MoveTo( - QT3DSVec2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1])); - dataIdx += 2; - break; - case qt3dsimp::PathCommand::CubicCurveTo: { - QT3DSVec2 c1(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - QT3DSVec2 c2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - QT3DSVec2 p2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); - dataIdx += 2; - m_PathSpecification->CubicCurveTo(c1, c2, p2); - } break; - case qt3dsimp::PathCommand::Close: - m_PathSpecification->ClosePath(); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - inPathBuffer.m_PathRender->SetPathSpecification(*m_PathSpecification); - - // cache bounds - NVBounds3 bounds = GetBounds(inPath); - inPathBuffer.m_Bounds.minimum = bounds.minimum; - inPathBuffer.m_Bounds.maximum = bounds.maximum; - - return true; - } - - return false; - } - - bool PrepareForRender(const SPath &inPath) override - { - SPathBuffer *thePathBuffer = GetPathBufferObject(inPath); - if (!thePathBuffer) { - return false; - } - NVRenderContext &theContext(this->m_RenderContext->GetRenderContext()); - if (!m_PathSpecification) - m_PathSpecification = theContext.CreatePathSpecification(); - if (!m_PathSpecification) - return false; - if (!m_PathBuilder) - m_PathBuilder = qt3dsimp::IPathBufferBuilder::CreateBuilder(GetFoundation()); - - thePathBuffer->SetPathType(inPath.m_PathType); - bool retval = false; - if (inPath.m_PathBuffer.IsValid() == false) { - thePathBuffer->m_PathBuffer = NULL; - // Ensure the SubPath list is identical and clear, percolating any dirty flags up to the - // path buffer. - QT3DSU32 SubPathIdx = 0; - for (const SPathSubPath *theSubPath = inPath.m_FirstSubPath; theSubPath; - theSubPath = theSubPath->m_NextSubPath, ++SubPathIdx) { - SPathSubPathBuffer *theSubPathBuffer = GetPathBufferObject(*theSubPath); - if (theSubPathBuffer == NULL) - continue; - thePathBuffer->m_Flags = - (QT3DSU32)(thePathBuffer->m_Flags | theSubPathBuffer->m_Flags); - - if (theSubPathBuffer->m_Closed != theSubPath->m_Closed) { - thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); - theSubPathBuffer->m_Closed = theSubPath->m_Closed; - } - - if (thePathBuffer->m_SubPaths.size() <= SubPathIdx - || thePathBuffer->m_SubPaths[SubPathIdx] != theSubPathBuffer) { - thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); - if (thePathBuffer->m_SubPaths.size() <= SubPathIdx) - thePathBuffer->m_SubPaths.push_back(theSubPathBuffer); - else - thePathBuffer->m_SubPaths[SubPathIdx] = theSubPathBuffer; - } - - theSubPathBuffer->m_Flags.Clear(); - } - - if (SubPathIdx != thePathBuffer->m_SubPaths.size()) { - thePathBuffer->m_SubPaths.resize(SubPathIdx); - thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); - } - } else { - thePathBuffer->m_SubPaths.clear(); - eastl::pair inserter = - m_SourcePathBufferMap.insert( - eastl::make_pair(inPath.m_PathBuffer, TPathBufferPtr())); - if (inserter.second) { - NVScopedRefCounted theStream = - m_CoreContext.GetInputStreamFactory().GetStreamForFile( - inPath.m_PathBuffer.c_str()); - if (theStream) { - qt3dsimp::SPathBuffer *theNewBuffer = - qt3dsimp::SPathBuffer::Load(*theStream, GetFoundation()); - if (theNewBuffer) - inserter.first->second = QT3DS_NEW(GetAllocator(), SImportPathWrapper)( - GetAllocator(), *theNewBuffer); - } - } - if (thePathBuffer->m_PathBuffer != inserter.first->second) { - thePathBuffer->m_PathBuffer = inserter.first->second; - thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); - } - } - - if (inPath.m_PathType == PathTypes::Geometry) - retval = PrepareGeometryPathForRender(inPath, *thePathBuffer); - else - retval = PreparePaintedPathForRender(inPath, *thePathBuffer); - thePathBuffer->m_Flags.Clear(); - return retval; - } - - void SetMaterialProperties(NVRenderShaderProgram &inShader, SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties &inRenderProperties) - { - IMaterialShaderGenerator *theMaterialGenerator = - GetMaterialShaderGenertator(inRenderContext); - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - theRenderContext.SetActiveShader(&inShader); - - theMaterialGenerator->SetMaterialProperties( - inShader, inRenderContext.m_Material, inRenderContext.m_CameraVec, - inRenderContext.m_ModelViewProjection, inRenderContext.m_NormalMatrix, - inRenderContext.m_Path.m_GlobalTransform, inRenderContext.m_FirstImage, - inRenderContext.m_Opacity, inRenderProperties); - } - - void DoRenderGeometryPath(SPathGeneratedShader &inShader, SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties &inRenderProperties, - SPathBuffer &inPathBuffer) - { - if (inPathBuffer.m_InputAssembler == NULL) - return; - - SetMaterialProperties(inShader.m_Shader, inRenderContext, inRenderProperties); - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - - inShader.m_BeginTaperData.Set(inPathBuffer.m_BeginTaperData); - inShader.m_EndTaperData.Set(inPathBuffer.m_EndTaperData); - if (inRenderContext.m_EnableWireframe) { - // we need the viewport matrix - NVRenderRect theViewport(theRenderContext.GetViewport()); - QT3DSMat44 vpMatrix; - vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0); - vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0); - vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0); - vpMatrix.column3 = - QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X, - (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0); - - inShader.m_WireframeViewMatrix.Set(vpMatrix); - } - - QT3DSF32 tessEdgeValue = NVMin(64.0f, NVMax(1.0f, inRenderContext.m_Path.m_EdgeTessAmount)); - QT3DSF32 tessInnerValue = NVMin(64.0f, NVMax(1.0f, inRenderContext.m_Path.m_InnerTessAmount)); - inShader.m_EdgeTessAmount.Set(tessEdgeValue); - inShader.m_InnerTessAmount.Set(tessInnerValue); - inShader.m_Width.Set(inRenderContext.m_Path.m_Width / 2.0f); - theRenderContext.SetInputAssembler(inPathBuffer.m_InputAssembler); - theRenderContext.SetCullingEnabled(false); - NVRenderDrawMode::Enum primType = NVRenderDrawMode::Patches; - theRenderContext.Draw(primType, (QT3DSU32)inPathBuffer.m_NumVertexes, 0); - } - - NVRenderDepthStencilState *GetDepthStencilState() - { - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - NVRenderBoolOp::Enum theDepthFunction = theRenderContext.GetDepthFunction(); - bool isDepthEnabled = theRenderContext.IsDepthTestEnabled(); - bool isStencilEnabled = theRenderContext.IsStencilTestEnabled(); - bool isDepthWriteEnabled = theRenderContext.IsDepthWriteEnabled(); - for (QT3DSU32 idx = 0, end = m_DepthStencilStates.size(); idx < end; ++idx) { - NVRenderDepthStencilState &theState = *m_DepthStencilStates[idx]; - if (theState.GetDepthFunc() == theDepthFunction - && theState.GetDepthEnabled() == isDepthEnabled - && theState.GetDepthMask() == isDepthWriteEnabled) - return &theState; - } - NVRenderStencilFunctionArgument theArg(NVRenderBoolOp::NotEqual, 0, 0xFF); - NVRenderStencilOperationArgument theOpArg(NVRenderStencilOp::Keep, NVRenderStencilOp::Keep, - NVRenderStencilOp::Zero); - m_DepthStencilStates.push_back(theRenderContext.CreateDepthStencilState( - isDepthEnabled, isDepthWriteEnabled, theDepthFunction, isStencilEnabled, theArg, theArg, - theOpArg, theOpArg)); - return m_DepthStencilStates.back(); - } - - static void DoSetCorrectiveScale(const QT3DSMat44 &mvp, QT3DSMat44 &outScale, NVBounds3 pathBounds) - { - // Compute the projected locations for the paraboloid and regular projection - // and thereby set the appropriate scaling factor. - QT3DSVec3 points[4]; - QT3DSVec3 projReg[4], projParab[4]; - points[0] = pathBounds.minimum; - points[1] = QT3DSVec3(pathBounds.maximum.x, pathBounds.minimum.y, pathBounds.minimum.z); - points[2] = pathBounds.maximum; - points[3] = QT3DSVec3(pathBounds.minimum.x, pathBounds.maximum.y, pathBounds.maximum.z); - - // Do the two different projections. - for (int i = 0; i < 4; ++i) { - QT3DSVec4 tmp; - tmp = mvp.transform(QT3DSVec4(points[i], 1.0f)); - tmp /= tmp.w; - projReg[i] = tmp.getXYZ(); - projParab[i] = tmp.getXYZ().getNormalized(); - projParab[i] /= projParab[i].z + 1.0f; - } - - NVBounds3 boundsA, boundsB; - for (int i = 0; i < 4; ++i) { - boundsA.include(projReg[i]); - boundsB.include(projParab[i]); - } - QT3DSF32 xscale = - (boundsB.maximum.x - boundsB.minimum.x) / (boundsA.maximum.x - boundsA.minimum.x); - QT3DSF32 yscale = - (boundsB.maximum.y - boundsB.minimum.y) / (boundsA.maximum.y - boundsA.minimum.y); - QT3DSF32 zscale = (boundsB.maximum - boundsB.minimum).magnitudeSquared() - / (boundsA.maximum - boundsA.minimum).magnitudeSquared(); - // The default minimum here is just a stupid figure that looks good on our content because - // we'd - // been using it for a little while before. Just for demo. - xscale = NVMin(0.5333333f, NVMin(xscale, yscale)); - yscale = NVMin(0.5333333f, NVMin(xscale, yscale)); - outScale.scale(QT3DSVec4(xscale, yscale, zscale, 1.0f)); - } - - void DoRenderPaintedPath(SPathXYGeneratedShader &inShader, SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties &inRenderProperties, - SPathBuffer &inPathBuffer, bool isParaboloidPass = false) - { - if (!inPathBuffer.m_PathRender) - return; - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - if (!m_PaintedRectInputAssembler) { - QT3DSVec2 vertexes[] = { - QT3DSVec2(0.0, 0.0), QT3DSVec2(1.0, 0.0), QT3DSVec2(1.0, 1.0), QT3DSVec2(0.0, 1.0), - }; - - QT3DSU8 indexes[] = { - 0, 1, 2, 2, 3, 0, - }; - - QT3DSU32 stride = sizeof(QT3DSVec2); - - NVRenderVertexBufferEntry theBufferEntries[] = { NVRenderVertexBufferEntry( - "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 0) }; - - m_PaintedRectVertexBuffer = theRenderContext.CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, 4 * sizeof(QT3DSVec2), sizeof(QT3DSVec2), - toU8DataRef(vertexes, 4)); - m_PaintedRectIndexBuffer = theRenderContext.CreateIndexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, - qt3ds::render::NVRenderComponentTypes::QT3DSU8, 6, toU8DataRef(indexes, 6)); - NVRenderAttribLayout *theAttribLayout = - theRenderContext.CreateAttributeLayout(toConstDataRef(theBufferEntries, 1)); - m_PaintedRectInputAssembler = theRenderContext.CreateInputAssembler( - theAttribLayout, toConstDataRef(m_PaintedRectVertexBuffer.mPtr), - m_PaintedRectIndexBuffer.mPtr, toConstDataRef(stride), toConstDataRef((QT3DSU32)0), - qt3ds::render::NVRenderDrawMode::Triangles); - } - - // our current render target needs stencil - QT3DS_ASSERT(theRenderContext.GetStencilBits() > 0); - - theRenderContext.SetDepthStencilState(GetDepthStencilState()); - - // http://developer.download.nvidia.com/assets/gamedev/files/Mixing_Path_Rendering_and_3D.pdf - theRenderContext.SetPathStencilDepthOffset(-.05f, -1.0f); - - // Stencil out the geometry. - QT3DSMat44 pathMdlView = QT3DSMat44::createIdentity(); - // Why is this happening? Well, it's because the painted-on path rendering is always - // a flat splatted 2D object. This is bad because a paraboloid projection demands a very - // different - // non-linear space into which we must draw. Path Rendering does not allow this sort of - // spatial - // warping internally, and all we end up passing in as a simple perspective projection. - // So for the fix, I'm scaling the actual "object" size so that it fits into the correctly - // projected - // polygon inside the paraboloid depth pass. Obviously, this scaling factor is wrong, and - // not generic - // enough to cover cases like polygons covering a large spread of the FOV and so on. It's - // really - // just a filthy awful, morally deplorable HACK. But it's basically the quickest fix at - // hand. - // This is also about the only possible approach that *could* work short of rendering the - // paths in - // a render-to-texture pass and splatting that texture on a sufficiently tessellated quad. - // Unless - // there's a way to program NVPR's internal projection scheme, that is. - // Geometry-based paths will work out better, I think, because they're actually creating - // geometry. - // This is essentially a 2D painting process inside a quad where the actual rendered region - // isn't - // exactly where NVPR thinks it should be because they're not projecting points the same - // way. - if (isParaboloidPass) { - DoSetCorrectiveScale(inRenderContext.m_ModelViewProjection, pathMdlView, - inPathBuffer.m_PathRender->GetPathObjectStrokeBox()); - } - - bool isStencilEnabled = theRenderContext.IsStencilTestEnabled(); - theRenderContext.SetStencilTestEnabled(true); - theRenderContext.SetPathProjectionMatrix(inRenderContext.m_ModelViewProjection); - theRenderContext.SetPathModelViewMatrix(pathMdlView); - - if (inRenderContext.m_IsStroke) { - inPathBuffer.m_PathRender->SetStrokeWidth(inRenderContext.m_Path.m_Width); - inPathBuffer.m_PathRender->StencilStroke(); - } else - inPathBuffer.m_PathRender->StencilFill(); - - // The stencil buffer will dictate whether this object renders or not. So we need to ignore - // the depth test result. - NVRenderBoolOp::Enum theDepthFunc = theRenderContext.GetDepthFunction(); - theRenderContext.SetDepthFunction(NVRenderBoolOp::AlwaysTrue); - // Now render the path; this resets the stencil buffer. - SetMaterialProperties(inShader.m_Shader, inRenderContext, inRenderProperties); - NVBounds3 rectBounds = inPathBuffer.m_PathRender->GetPathObjectStrokeBox(); - if (isParaboloidPass) { - rectBounds.scale(1.570796326795f); - } // PKC : More of the same ugly hack. - inShader.m_RectDimensions.Set(QT3DSVec4(rectBounds.minimum.x, rectBounds.minimum.y, - rectBounds.maximum.x, rectBounds.maximum.y)); - theRenderContext.SetInputAssembler(m_PaintedRectInputAssembler); - theRenderContext.SetCullingEnabled(false); - // Render exactly two triangles - theRenderContext.Draw(NVRenderDrawMode::Triangles, 6, 0); - theRenderContext.SetStencilTestEnabled(isStencilEnabled); - theRenderContext.SetDepthFunction(theDepthFunc); - } - - void RenderDepthPrepass(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) override - { - SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); - if (!thePathBuffer) { - return; - } - - if (thePathBuffer->m_PathType == PathTypes::Geometry) { - QT3DSU32 displacementIdx = 0; - QT3DSU32 imageIdx = 0; - SRenderableImage *displacementImage = 0; - - for (SRenderableImage *theImage = inRenderContext.m_FirstImage; - theImage != NULL && displacementImage == NULL; - theImage = theImage->m_NextImage, ++imageIdx) { - if (theImage->m_MapType == ImageMapTypes::Displacement) { - displacementIdx = imageIdx; - displacementImage = theImage; - } - } - - NVScopedRefCounted &theDesiredDepthShader = - displacementImage == NULL ? m_DepthShader : m_DepthDisplacementShader; - - if (!theDesiredDepthShader) { - IDefaultMaterialShaderGenerator &theMaterialGenerator( - m_RenderContext->GetDefaultMaterialShaderGenerator()); - SPathVertexPipeline thePipeline( - m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, - m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable(), false); - thePipeline.BeginVertexGeneration(displacementIdx, displacementImage); - thePipeline.BeginFragmentGeneration(); - thePipeline.Fragment().Append("\tfragOutput = vec4(1.0, 1.0, 1.0, 1.0);"); - thePipeline.EndVertexGeneration(); - thePipeline.EndFragmentGeneration(); - const char8_t *shaderName = "path depth"; - if (displacementImage) - shaderName = "path depth displacement"; - - SShaderCacheProgramFlags theFlags; - NVRenderShaderProgram *theProgram = - thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, - inFeatureSet); - if (theProgram) { - theDesiredDepthShader = - QT3DS_NEW(m_RenderContext->GetAllocator(), - SPathGeneratedShader)(*theProgram, m_RenderContext->GetAllocator()); - } - } - if (theDesiredDepthShader) { - DoRenderGeometryPath(*theDesiredDepthShader, inRenderContext, inRenderProperties, - *thePathBuffer); - } - } else { - // painted path, go stroke route for now. - if (!m_PaintedDepthShader) { - IDefaultMaterialShaderGenerator &theMaterialGenerator( - m_RenderContext->GetDefaultMaterialShaderGenerator()); - SXYRectVertexPipeline thePipeline( - m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, - m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); - thePipeline.BeginVertexGeneration(0, NULL); - thePipeline.BeginFragmentGeneration(); - thePipeline.Fragment().Append("\tfragOutput = vec4(1.0, 1.0, 1.0, 1.0);"); - thePipeline.EndVertexGeneration(); - thePipeline.EndFragmentGeneration(); - const char8_t *shaderName = "path painted depth"; - SShaderCacheProgramFlags theFlags; - NVRenderShaderProgram *theProgram = - thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, - inFeatureSet); - if (theProgram) { - m_PaintedDepthShader = - QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( - *theProgram, m_RenderContext->GetAllocator()); - } - } - if (m_PaintedDepthShader) { - - DoRenderPaintedPath(*m_PaintedDepthShader, inRenderContext, inRenderProperties, - *thePathBuffer); - } - } - } - - void RenderShadowMapPass(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) override - { - SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); - if (!thePathBuffer) { - return; - } - - if (inRenderContext.m_Material.m_Type != GraphObjectTypes::DefaultMaterial) - return; - - if (thePathBuffer->m_PathType == PathTypes::Painted) { - // painted path, go stroke route for now. - if (!m_PaintedShadowShader) { - IDefaultMaterialShaderGenerator &theMaterialGenerator( - m_RenderContext->GetDefaultMaterialShaderGenerator()); - SXYRectVertexPipeline thePipeline( - m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, - m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); - thePipeline.OutputParaboloidDepthShaders(); - const char8_t *shaderName = "path painted paraboloid depth"; - SShaderCacheProgramFlags theFlags; - NVRenderShaderProgram *theProgram = - thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, - inFeatureSet); - if (theProgram) { - m_PaintedShadowShader = - QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( - *theProgram, m_RenderContext->GetAllocator()); - } - } - if (m_PaintedShadowShader) { - // Setup the shader paraboloid information. - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - theRenderContext.SetActiveShader(&m_PaintedShadowShader->m_Shader); - - DoRenderPaintedPath(*m_PaintedShadowShader, inRenderContext, inRenderProperties, - *thePathBuffer, true); - } - } else { - // Until we've also got a proper path render path for this, we'll call the old-fashioned - // stuff. - RenderDepthPrepass(inRenderContext, inRenderProperties, inFeatureSet); - // QT3DS_ASSERT( false ); - } - } - - void RenderCubeFaceShadowPass(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) override - { - SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); - if (!thePathBuffer) { - return; - } - - if (inRenderContext.m_Material.m_Type != GraphObjectTypes::DefaultMaterial) - return; - - if (thePathBuffer->m_PathType == PathTypes::Painted) { - if (!m_PaintedCubeShadowShader) { - IDefaultMaterialShaderGenerator &theMaterialGenerator( - m_RenderContext->GetDefaultMaterialShaderGenerator()); - SXYRectVertexPipeline thePipeline( - m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, - m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); - thePipeline.OutputCubeFaceDepthShaders(); - const char8_t *shaderName = "path painted cube face depth"; - SShaderCacheProgramFlags theFlags; - NVRenderShaderProgram *theProgram = - thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, - inFeatureSet); - if (theProgram) { - m_PaintedCubeShadowShader = - QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( - *theProgram, m_RenderContext->GetAllocator()); - } - } - if (m_PaintedCubeShadowShader) { - // Setup the shader information. - NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); - theRenderContext.SetActiveShader(&m_PaintedCubeShadowShader->m_Shader); - - m_PaintedCubeShadowShader->m_CameraPosition.Set( - inRenderContext.m_Camera.GetGlobalPos()); - m_PaintedCubeShadowShader->m_CameraProperties.Set( - QT3DSVec2(1.0f, inRenderContext.m_Camera.m_ClipFar)); - m_PaintedCubeShadowShader->m_ModelMatrix.Set(inRenderContext.m_ModelMatrix); - - DoRenderPaintedPath(*m_PaintedCubeShadowShader, inRenderContext, inRenderProperties, - *thePathBuffer, false); - } - } else { - // Until we've also got a proper path render path for this, we'll call the old-fashioned - // stuff. - RenderDepthPrepass(inRenderContext, inRenderProperties, inFeatureSet); - } - } - - void RenderPath(SPathRenderContext &inRenderContext, - SLayerGlobalRenderProperties inRenderProperties, - TShaderFeatureSet inFeatureSet) override - { - SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); - if (!thePathBuffer) { - return; - } - - bool isDefaultMaterial = - (inRenderContext.m_Material.m_Type == GraphObjectTypes::DefaultMaterial); - - if (thePathBuffer->m_PathType == PathTypes::Geometry) { - IMaterialShaderGenerator *theMaterialGenerator = - GetMaterialShaderGenertator(inRenderContext); - - // we need a more evolved key her for custom materials - // the same key can still need a different shader - SPathShaderMapKey sPathkey = SPathShaderMapKey(GetMaterialNameForKey(inRenderContext), - inRenderContext.m_MaterialKey); - eastl::pair inserter = m_PathGeometryShaders.insert( - eastl::make_pair(sPathkey, NVScopedRefCounted(NULL))); - if (inserter.second) { - SPathVertexPipeline thePipeline( - m_RenderContext->GetShaderProgramGenerator(), *theMaterialGenerator, - m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable(), - m_RenderContext->GetWireframeMode()); - - NVRenderShaderProgram *theProgram = NULL; - - if (isDefaultMaterial) { - theProgram = theMaterialGenerator->GenerateShader( - inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, - inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, - inRenderContext.m_Opacity < 1.0, "path geometry pipeline-- "); - } else { - ICustomMaterialSystem &theMaterialSystem( - m_RenderContext->GetCustomMaterialSystem()); - const SCustomMaterial &theCustomMaterial( - reinterpret_cast(inRenderContext.m_Material)); - - theProgram = theMaterialGenerator->GenerateShader( - inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, - inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, - inRenderContext.m_Opacity < 1.0, "path geometry pipeline-- ", - theMaterialSystem.GetShaderName(theCustomMaterial)); - } - - if (theProgram) - inserter.first->second = - QT3DS_NEW(m_RenderContext->GetAllocator(), - SPathGeneratedShader)(*theProgram, m_RenderContext->GetAllocator()); - } - if (!inserter.first->second) - return; - - DoRenderGeometryPath(*inserter.first->second.mPtr, inRenderContext, inRenderProperties, - *thePathBuffer); - } else { - IMaterialShaderGenerator *theMaterialGenerator = - GetMaterialShaderGenertator(inRenderContext); - - // we need a more evolved key her for custom materials - // the same key can still need a different shader - SPathShaderMapKey sPathkey = SPathShaderMapKey(GetMaterialNameForKey(inRenderContext), - inRenderContext.m_MaterialKey); - eastl::pair inserter = m_PathPaintedShaders.insert( - eastl::make_pair(sPathkey, NVScopedRefCounted(NULL))); - - if (inserter.second) { - SXYRectVertexPipeline thePipeline( - m_RenderContext->GetShaderProgramGenerator(), *theMaterialGenerator, - m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); - - NVRenderShaderProgram *theProgram = NULL; - - if (isDefaultMaterial) { - theProgram = theMaterialGenerator->GenerateShader( - inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, - inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, - inRenderContext.m_Opacity < 1.0, "path painted pipeline-- "); - } else { - ICustomMaterialSystem &theMaterialSystem( - m_RenderContext->GetCustomMaterialSystem()); - const SCustomMaterial &theCustomMaterial( - reinterpret_cast(inRenderContext.m_Material)); - - theProgram = theMaterialGenerator->GenerateShader( - inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, - inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, - inRenderContext.m_Opacity < 1.0, "path painted pipeline-- ", - theMaterialSystem.GetShaderName(theCustomMaterial)); - } - - if (theProgram) - inserter.first->second = - QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( - *theProgram, m_RenderContext->GetAllocator()); - } - if (!inserter.first->second) - return; - - DoRenderPaintedPath(*inserter.first->second.mPtr, inRenderContext, inRenderProperties, - *thePathBuffer); - } - } -}; -} - -QT3DSVec2 IPathManagerCore::GetControlPointFromAngleDistance(QT3DSVec2 inPosition, float inIncomingAngle, - float inIncomingDistance) -{ - if (inIncomingDistance == 0.0f) - return inPosition; - float angleRad = degToRad(inIncomingAngle); - float angleSin = NVSin(angleRad); - float angleCos = NVCos(angleRad); - QT3DSVec2 relativeAngles = QT3DSVec2(angleCos * inIncomingDistance, angleSin * inIncomingDistance); - return inPosition + relativeAngles; -} - -QT3DSVec2 IPathManagerCore::GetAngleDistanceFromControlPoint(QT3DSVec2 inPosition, QT3DSVec2 inControlPoint) -{ - QT3DSVec2 relative = inControlPoint - inPosition; - float angleRad = atan2(relative.y, relative.x); - float distance = relative.magnitude(); - return QT3DSVec2(radToDeg(angleRad), distance); -} - -IPathManagerCore &IPathManagerCore::CreatePathManagerCore(IQt3DSRenderContextCore &ctx) -{ - return *QT3DS_NEW(ctx.GetAllocator(), SPathManager)(ctx); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsRenderer.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsRenderer.cpp deleted file mode 100644 index 43f7c0b4..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsRenderer.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderPixelGraphicsRenderer.h" -#include "Qt3DSRenderPixelGraphicsTypes.h" -#include "foundation/Qt3DSAtomic.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderShaderCodeGenerator.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderShaderCache.h" - -using namespace qt3ds; -using namespace qt3ds::render; - -namespace { - -struct SPGRectShader -{ - NVScopedRefCounted m_RectShader; - NVRenderShaderConstantBase *mvp; - NVRenderShaderConstantBase *rectColor; - NVRenderShaderConstantBase *leftright; - NVRenderShaderConstantBase *bottomtop; - - SPGRectShader() - : mvp(NULL) - , rectColor(NULL) - , leftright(NULL) - , bottomtop(NULL) - { - } - void SetShader(NVRenderShaderProgram *program) - { - m_RectShader = program; - if (program) { - mvp = program->GetShaderConstant("model_view_projection"); - rectColor = program->GetShaderConstant("rect_color"); - leftright = program->GetShaderConstant("leftright[0]"); - bottomtop = program->GetShaderConstant("bottomtop[0]"); - } - } - - void Apply(QT3DSMat44 &inVP, const SPGRect &inObject) - { - if (mvp) - m_RectShader->SetConstantValue(mvp, toConstDataRef(inVP), 1); - if (rectColor) - m_RectShader->SetConstantValue(rectColor, inObject.m_FillColor, 1); - if (leftright) { - QT3DSF32 theData[] = { inObject.m_Left, inObject.m_Right }; - m_RectShader->SetConstantValue(leftright, *theData, 2); - } - if (bottomtop) { - QT3DSF32 theData[] = { inObject.m_Bottom, inObject.m_Top }; - m_RectShader->SetConstantValue(bottomtop, *theData, 2); - } - } - - operator bool() { return m_RectShader.mPtr != NULL; } -}; - -struct SPGRenderer : public IPixelGraphicsRenderer -{ - IQt3DSRenderContext &m_RenderContext; - IStringTable &m_StringTable; - NVScopedRefCounted m_QuadVertexBuffer; - NVScopedRefCounted m_QuadIndexBuffer; - NVScopedRefCounted m_QuadInputAssembler; - NVScopedRefCounted m_QuadAttribLayout; - SShaderVertexCodeGenerator m_VertexGenerator; - SShaderFragmentCodeGenerator m_FragmentGenerator; - SPGRectShader m_RectShader; - QT3DSI32 mRefCount; - - SPGRenderer(IQt3DSRenderContext &ctx, IStringTable &strt) - : m_RenderContext(ctx) - , m_StringTable(strt) - , m_VertexGenerator(m_StringTable, ctx.GetAllocator(), - m_RenderContext.GetRenderContext().GetRenderContextType()) - , m_FragmentGenerator(m_VertexGenerator, ctx.GetAllocator(), - m_RenderContext.GetRenderContext().GetRenderContextType()) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) - void GetRectShaderProgram() - { - if (!m_RectShader) { - m_VertexGenerator.Begin(); - m_FragmentGenerator.Begin(); - m_VertexGenerator.AddAttribute("attr_pos", "vec2"); - m_VertexGenerator.AddUniform("model_view_projection", "mat4"); - m_VertexGenerator.AddUniform("leftright[2]", "float"); - m_VertexGenerator.AddUniform("bottomtop[2]", "float"); - m_FragmentGenerator.AddVarying("rect_uvs", "vec2"); - m_FragmentGenerator.AddUniform("rect_color", "vec4"); - m_VertexGenerator << "void main() {" << Endl - << "\tgl_Position = model_view_projection * vec4( " - "leftright[int(attr_pos.x)], bottomtop[int(attr_pos.y)], 0.0, 1.0 " - ");" - << Endl << "\trect_uvs = attr_pos;" << Endl << "}" << Endl; - - m_FragmentGenerator << "void main() {" << Endl << "\tfragOutput = rect_color;" << Endl - << "}" << Endl; - - m_VertexGenerator.BuildShaderSource(); - m_FragmentGenerator.BuildShaderSource(); - - m_RectShader.SetShader(m_RenderContext.GetShaderCache().CompileProgram( - m_StringTable.RegisterStr("PixelRectShader"), - m_VertexGenerator.m_FinalShaderBuilder.c_str(), - m_FragmentGenerator.m_FinalShaderBuilder.c_str(), NULL // no tess control shader - , - NULL // no tess eval shader - , - NULL // no geometry shader - , - SShaderCacheProgramFlags(), ShaderCacheNoFeatures())); - } - } - void GenerateXYQuad() - { - NVRenderContext &theRenderContext(m_RenderContext.GetRenderContext()); - - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2), - }; - - QT3DSVec2 pos[] = { QT3DSVec2(0, 0), QT3DSVec2(0, 1), QT3DSVec2(1, 1), QT3DSVec2(1, 0) }; - - if (m_QuadVertexBuffer == NULL) { - size_t bufSize = sizeof(pos); - m_QuadVertexBuffer = theRenderContext.CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, bufSize, 2 * sizeof(QT3DSF32), - toU8DataRef(pos, 4)); - } - - if (m_QuadIndexBuffer == NULL) { - QT3DSU8 indexData[] = { - 0, 1, 2, 0, 2, 3, - }; - m_QuadIndexBuffer = theRenderContext.CreateIndexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, - qt3ds::render::NVRenderComponentTypes::QT3DSU8, sizeof(indexData), - toU8DataRef(indexData, sizeof(indexData))); - } - - if (m_QuadAttribLayout == NULL) { - // create our attribute layout - m_QuadAttribLayout = - theRenderContext.CreateAttributeLayout(toConstDataRef(theEntries, 1)); - } - - if (m_QuadInputAssembler == NULL) { - - // create input assembler object - QT3DSU32 strides = m_QuadVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_QuadInputAssembler = theRenderContext.CreateInputAssembler( - m_QuadAttribLayout, toConstDataRef(&m_QuadVertexBuffer.mPtr, 1), m_QuadIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - } - - void RenderPixelObject(QT3DSMat44 &inProjection, const SPGRect &inObject) - { - GenerateXYQuad(); - GetRectShaderProgram(); - if (m_RectShader) { - m_RenderContext.GetRenderContext().SetActiveShader(m_RectShader.m_RectShader.mPtr); - m_RectShader.Apply(inProjection, inObject); - - m_RenderContext.GetRenderContext().SetInputAssembler(m_QuadInputAssembler.mPtr); - m_RenderContext.GetRenderContext().Draw(NVRenderDrawMode::Triangles, - m_QuadInputAssembler->GetIndexCount(), 0); - } - } - - void RenderPixelObject(QT3DSMat44 &inProjection, const SPGVertLine &inObject) - { - // lines are really just rects, but they grow in width in a sort of odd way. - // specifically, they grow the increasing coordinate on even boundaries and centered on odd - // boundaries. - SPGRect theRect; - theRect.m_Top = inObject.m_Top; - theRect.m_Bottom = inObject.m_Bottom; - theRect.m_FillColor = inObject.m_LineColor; - theRect.m_Left = inObject.m_X; - theRect.m_Right = theRect.m_Left + 1.0f; - RenderPixelObject(inProjection, theRect); - } - - void RenderPixelObject(QT3DSMat44 &inProjection, const SPGHorzLine &inObject) - { - SPGRect theRect; - theRect.m_Right = inObject.m_Right; - theRect.m_Left = inObject.m_Left; - theRect.m_FillColor = inObject.m_LineColor; - theRect.m_Bottom = inObject.m_Y; - theRect.m_Top = theRect.m_Bottom + 1.0f; - RenderPixelObject(inProjection, theRect); - } - - void Render(NVConstDataRef inObjects) override - { - NVRenderContext &theRenderContext(m_RenderContext.GetRenderContext()); - theRenderContext.PushPropertySet(); - // Setup an orthographic camera that places the center at the - // lower left of the viewport. - NVRenderRectF theViewport = theRenderContext.GetViewport(); - // With no projection at all, we are going to get a square view box - // with boundaries from -1,1 in all dimensions. This is close to what we want. - theRenderContext.SetDepthTestEnabled(false); - theRenderContext.SetDepthWriteEnabled(false); - theRenderContext.SetScissorTestEnabled(false); - theRenderContext.SetBlendingEnabled(true); - theRenderContext.SetCullingEnabled(false); - // Colors are expected to be non-premultiplied, so we premultiply alpha into them at this - // point. - theRenderContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); - theRenderContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); - - SCamera theCamera; - theCamera.m_Position.z = -5; - theCamera.m_ClipNear = 1.0f; - theCamera.m_ClipFar = 10.0f; - theCamera.m_Flags.SetOrthographic(true); - // Setup camera projection - theCamera.ComputeFrustumOrtho(theViewport, - QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); - // Translate such that 0, 0 is lower left of screen. - NVRenderRectF theIdealViewport = theViewport; - theIdealViewport.m_X -= theViewport.m_Width / 2.0f; - theIdealViewport.m_Y -= theViewport.m_Height / 2.0f; - QT3DSMat44 theProjectionMatrix = NVRenderContext::ApplyVirtualViewportToProjectionMatrix( - theCamera.m_Projection, theViewport, theIdealViewport); - theCamera.m_Projection = theProjectionMatrix; - // Explicitly call the node's calculate global variables so that the camera doesn't attempt - // to change the projection we setup. - static_cast(theCamera).CalculateGlobalVariables(); - QT3DSMat44 theVPMatrix(QT3DSMat44::createIdentity()); - theCamera.CalculateViewProjectionMatrix(theVPMatrix); - - QT3DSVec4 theTest(60, 200, 0, 1); - QT3DSVec4 theResult = theVPMatrix.transform(theTest); - - (void)theTest; - (void)theResult; - - for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { - const SPGGraphObject &theObject(*inObjects[idx]); - - switch (theObject.m_Type) { - case SGTypes::VertLine: - RenderPixelObject(theVPMatrix, static_cast(theObject)); - break; - case SGTypes::HorzLine: - RenderPixelObject(theVPMatrix, static_cast(theObject)); - break; - case SGTypes::Rect: - RenderPixelObject(theVPMatrix, static_cast(theObject)); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - theRenderContext.PopPropertySet(false); - } -}; -} - -IPixelGraphicsRenderer &IPixelGraphicsRenderer::CreateRenderer(IQt3DSRenderContext &ctx, - IStringTable &strt) -{ - return *QT3DS_NEW(ctx.GetAllocator(), SPGRenderer)(ctx, strt); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsTypes.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsTypes.cpp deleted file mode 100644 index fe32437f..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPixelGraphicsTypes.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderPixelGraphicsTypes.h" - -using namespace qt3ds; -using namespace qt3ds::render; - -SPGGraphObject::SPGGraphObject(SGTypes::Enum inType) - : m_Type(inType) -{ -} - -SPGRect::SPGRect() - : SPGGraphObject(SGTypes::Rect) - , m_Left(0) - , m_Top(0) - , m_Right(0) - , m_Bottom(0) - , m_FillColor(0, 0, 0, 0) -{ -} - -SPGVertLine::SPGVertLine() - : SPGGraphObject(SGTypes::VertLine) - , m_X(0) - , m_Top(0) - , m_Bottom(0) - , m_LineColor(0, 0, 0, 0) -{ -} - -SPGHorzLine::SPGHorzLine() - : SPGGraphObject(SGTypes::HorzLine) - , m_Y(0) - , m_Left(0) - , m_Right(0) - , m_LineColor(0, 0, 0, 0) -{ -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp deleted file mode 100644 index aca90ce3..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp +++ /dev/null @@ -1,936 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderPlugin.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/SerializationTypes.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSSystem.h" -#include "foundation/FileTools.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderString.h" -#include "Qt3DSRenderPluginPropertyValue.h" -#include "Qt3DSRenderInputStreamFactory.h" - -#if defined(QT3DS_WINDOWS) -#include "WINDOWS/DynamicLibLoader.h" -#elif defined(QT3DS_ANDROID) -#include "ANDROID/DynamicLibLoader.h" -#elif defined(QT3DS_LINUX) -#include "LINUX/DynamicLibLoader.h" -#elif defined(QT3DS_APPLE) -#include "OSX/DynamicLibLoader.h" -#elif defined(QT3DS_QNX) -#include "QNX/DynamicLibLoader.h" -#else -#error "Must define an operating system type (QT3DS_WINDOWS, QT3DS_ANDROID, QT3DS_LINUX, QT3DS_APPLE, QT3DS_QNX)" -#endif - -using namespace qt3ds::render; - -namespace { -// Legacy definitions... -// API version 1 definitions -typedef struct _RenderPluginSurfaceDescriptionV1 -{ - long m_Width; - long m_Height; - enum QT3DSRenderPluginDepthTypes m_DepthBuffer; - enum QT3DSRenderPluginTextureTypes m_ColorBuffer; - TBool m_HasStencilBuffer; -} TRenderPluginSurfaceDescriptionV1; - -typedef TNeedsRenderResult (*TNeedsRenderFunctionV1)(TRenderPluginClassPtr cls, - TRenderPluginInstancePtr instance, - TRenderPluginSurfaceDescriptionV1 surface, - TVec2 presScaleFactor); - -typedef void (*TRenderFunctionV1)(TRenderPluginClassPtr cls, TRenderPluginInstancePtr instance, - TRenderPluginSurfaceDescriptionV1 surface, - TVec2 presScaleFactor, - QT3DSRenderPluginColorClearState inClearColorBuffer); - -// End API version 1 definitions - -TRenderPluginSurfaceDescription ToCInterface(const SOffscreenRendererEnvironment &env) -{ - TRenderPluginSurfaceDescription retval; - retval.m_Width = (long)env.m_Width; - retval.m_Height = (long)env.m_Height; - retval.m_ColorBuffer = static_cast(env.m_Format); - retval.m_DepthBuffer = static_cast(env.m_Depth); - retval.m_HasStencilBuffer = env.m_Stencil ? TTRUE : TFALSE; - retval.m_MSAALevel = QT3DSRenderPluginMSAALevelNoMSAA; - // note no supersampling AA support for plugins - // we fall back to 4xMSAA - switch (env.m_MSAAMode) { - case AAModeValues::X2: - retval.m_MSAALevel = QT3DSRenderPluginMSAALevelTwo; - break; - case AAModeValues::SSAA: - case AAModeValues::X4: - retval.m_MSAALevel = QT3DSRenderPluginMSAALevelFour; - break; - case AAModeValues::X8: - retval.m_MSAALevel = QT3DSRenderPluginMSAALevelEight; - break; - default: - QT3DS_ASSERT(false); - // fallthrough intentional. - case AAModeValues::NoAA: - break; - }; - return retval; -} - -TRenderPluginSurfaceDescriptionV1 ToCInterfaceV1(const SOffscreenRendererEnvironment &env) -{ - TRenderPluginSurfaceDescriptionV1 retval; - retval.m_Width = (long)env.m_Width; - retval.m_Height = (long)env.m_Height; - retval.m_ColorBuffer = static_cast(env.m_Format); - retval.m_DepthBuffer = static_cast(env.m_Depth); - retval.m_HasStencilBuffer = env.m_Stencil ? TTRUE : TFALSE; - return retval; -} - -TVec2 ToCInterface(const QT3DSVec2 &item) -{ - TVec2 retval = { item.x, item.y }; - return retval; -} - -QT3DSRenderPluginColorClearState ToCInterface(SScene::RenderClearCommand inClearCommand) -{ - switch (inClearCommand) { - case SScene::DoNotClear: - return QT3DSRenderPluginColorClearStateDoNotClear; - case SScene::AlwaysClear: - return QT3DSRenderPluginColorClearStateAlwaysClear; - default: - QT3DS_ASSERT(false); // fallthrough intentional - case SScene::ClearIsOptional: - return QT3DSRenderPluginColorClearStateClearIsOptional; - }; -} - -class SRenderPluginPropertyData -{ - SRenderPluginPropertyValue m_Value; - bool m_Dirty; - -public: - SRenderPluginPropertyData() - : m_Dirty(false) - { - } - SRenderPluginPropertyData(const SRenderPluginPropertyData &other) - : m_Value(other.m_Value) - , m_Dirty(other.m_Dirty) - { - } - SRenderPluginPropertyData &operator=(const SRenderPluginPropertyData &other) - { - m_Value = other.m_Value; - m_Dirty = other.m_Dirty; - return *this; - } - - bool IsDirty() const - { - return m_Value.getType() != RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue - && m_Dirty; - } - void SetValue(const SRenderPluginPropertyValue &value) - { - m_Value = value; - m_Dirty = true; - } - - TRenderPluginPropertyUpdate ClearDirty(CRegisteredString inPropName) - { - m_Dirty = false; - TRenderPluginPropertyUpdate retval; - memset(&retval, 0, sizeof(TRenderPluginPropertyUpdate)); - retval.m_PropName = inPropName.c_str(); - switch (m_Value.getType()) { - case RenderPluginPropertyValueTypes::Long: { - retval.m_PropertyType = QT3DSRenderPluginPropertyTypeLong; - long temp = (long)m_Value.getData(); - retval.m_PropertyValue = *reinterpret_cast(&temp); - } break; - case RenderPluginPropertyValueTypes::Float: { - retval.m_PropertyType = QT3DSRenderPluginPropertyTypeFloat; - float temp = m_Value.getData(); - retval.m_PropertyValue = *reinterpret_cast(&temp); - } break; - case RenderPluginPropertyValueTypes::Boolean: { - retval.m_PropertyType = QT3DSRenderPluginPropertyTypeLong; - long temp = m_Value.getData() ? TTRUE : TFALSE; - retval.m_PropertyValue = *reinterpret_cast(&temp); - } break; - case RenderPluginPropertyValueTypes::String: { - retval.m_PropertyType = QT3DSRenderPluginPropertyTypeCharPtr; - const char *temp = m_Value.getData().c_str(); - retval.m_PropertyValue = reinterpret_cast(const_cast(temp)); - } break; - default: - QT3DS_ASSERT(false); - } - return retval; - } -}; - -typedef nvvector TPropertyValueList; - -struct IInternalPluginClass : public IRenderPluginClass -{ - virtual void PushUpdates(TRenderPluginInstancePtr instance, - TPropertyValueList &propertyValues) = 0; - virtual void Update(NVConstDataRef updateBuffer, - TPropertyValueList &propertyValues) = 0; - virtual QT3DSI32 GetAPIVersion() = 0; -}; - -static NVRenderTextureFormats::Enum ToTextureFormat(QT3DSRenderPluginTextureTypes inTextureType) -{ - switch (inTextureType) { - default: - case QT3DSRenderPluginTextureTypeRGBA8: - return NVRenderTextureFormats::RGBA8; - case QT3DSRenderPluginTextureTypeRGB8: - return NVRenderTextureFormats::RGB8; - case QT3DSRenderPluginTextureTypeRGB565: - return NVRenderTextureFormats::RGB565; - case QT3DSRenderPluginTextureTypeRGBA5551: - return NVRenderTextureFormats::RGBA5551; - } -} - -static OffscreenRendererDepthValues::Enum ToDepthValue(QT3DSRenderPluginDepthTypes inType) -{ - switch (inType) { - default: - case QT3DSRenderPluginDepthTypeDepth16: - return OffscreenRendererDepthValues::Depth16; - case QT3DSRenderPluginDepthTypeDepth24: - return OffscreenRendererDepthValues::Depth24; - case QT3DSRenderPluginDepthTypeDepth32: - return OffscreenRendererDepthValues::Depth32; - } -} - -static AAModeValues::Enum ToAAMode(QT3DSRenderPluginMSAALevel inMode) -{ - switch (inMode) { - case QT3DSRenderPluginMSAALevelTwo: - return AAModeValues::X2; - case QT3DSRenderPluginMSAALevelFour: - return AAModeValues::X4; - case QT3DSRenderPluginMSAALevelEight: - return AAModeValues::X8; - default: - QT3DS_ASSERT(false); // fallthrough intentional - case QT3DSRenderPluginMSAALevelNoMSAA: - return AAModeValues::NoAA; - } -} - -struct InstanceImpl : public IRenderPluginInstance -{ - NVFoundationBase &m_Foundation; - TRenderPluginInstancePtr m_Instance; - TRenderPluginClass m_Class; - NVScopedRefCounted m_Owner; - CRegisteredString m_RendererType; - // Backing store of property values - nvvector m_PropertyValues; - bool m_Dirty; - NVRenderContext *m_RenderContext; - QT3DSI32 mRefCount; - - InstanceImpl(NVFoundationBase &fnd, TRenderPluginInstancePtr instance, TRenderPluginClass cls, - IInternalPluginClass &owner, IStringTable &strTable) - : m_Foundation(fnd) - , m_Instance(instance) - , m_Class(cls) - , m_Owner(owner) - , m_RendererType( - strTable.RegisterStr(IRenderPluginInstance::IRenderPluginOffscreenRendererType())) - , m_PropertyValues(m_Foundation.getAllocator(), "InstanceImpl::m_PropertyValues") - , m_Dirty(false) - , m_RenderContext(NULL) - , mRefCount(0) - { - } - - virtual ~InstanceImpl() { m_Class.ReleaseInstance(m_Class.m_Class, m_Instance); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void addCallback(IOffscreenRendererCallback *cb) override - { - - } - void CreateScriptProxy(script_State *state) override - { - if (m_Class.CreateInstanceScriptProxy) - m_Class.CreateInstanceScriptProxy(m_Class.m_Class, m_Instance, state); - } - - // Arbitrary const char* returned to indicate the type of this renderer - // Can be overloaded to form the basis of an RTTI type system. - // Not currently used by the rendering system. - CRegisteredString GetOffscreenRendererType() override { return m_RendererType; } - - SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresentationScaleFactor) override - { - if (m_Class.QueryInstanceRenderSurface) { - QT3DSRenderPluginMSAALevel theLevel = QT3DSRenderPluginMSAALevelNoMSAA; - TRenderPluginSurfaceDescription desc = m_Class.QueryInstanceRenderSurface( - m_Class.m_Class, m_Instance, ToCInterface(inPresentationScaleFactor)); - if (m_Owner->GetAPIVersion() > 1) - theLevel = desc.m_MSAALevel; - - return SOffscreenRendererEnvironment( - (QT3DSU32)desc.m_Width, (QT3DSU32)desc.m_Height, ToTextureFormat(desc.m_ColorBuffer), - ToDepthValue(desc.m_DepthBuffer), desc.m_HasStencilBuffer ? true : false, - ToAAMode(theLevel)); - } else { - QT3DS_ASSERT(false); - } - return SOffscreenRendererEnvironment(); - } - - // Returns true of this object needs to be rendered, false if this object is not dirty - SOffscreenRenderFlags NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, - QT3DSVec2 inPresentationScaleFactor, - const SRenderInstanceId instanceId) override - { - if (m_Dirty) { - m_Dirty = false; - m_Owner->PushUpdates(m_Instance, m_PropertyValues); - } - if (m_Class.NeedsRenderFunction) { - if (m_Owner->GetAPIVersion() > 1) { - TNeedsRenderResult result = m_Class.NeedsRenderFunction( - m_Class.m_Class, m_Instance, ToCInterface(inEnvironment), - ToCInterface(inPresentationScaleFactor)); - return SOffscreenRenderFlags(result.HasTransparency ? true : false, - result.HasChangedSinceLastFrame ? true : false); - } else { - TNeedsRenderFunctionV1 theV1Function = - reinterpret_cast(m_Class.NeedsRenderFunction); - - TNeedsRenderResult result = - theV1Function(m_Class.m_Class, m_Instance, ToCInterfaceV1(inEnvironment), - ToCInterface(inPresentationScaleFactor)); - return SOffscreenRenderFlags(result.HasTransparency ? true : false, - result.HasChangedSinceLastFrame ? true : false); - } - } - return SOffscreenRenderFlags(true, true); - } - // Returns true if the rendered result image has transparency, or false - // if it should be treated as a completely opaque image. - // It is the IOffscreenRenderer's job to clear any buffers (color, depth, stencil) that it - // needs to. It should not assume that it's buffers are clear; - // Sometimes we scale the width and height of the main presentation in order to fit a window. - // If we do so, the scale factor tells the subpresentation renderer how much the system has - // scaled. - void Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, - SScene::RenderClearCommand inColorBufferNeedsClear, - const SRenderInstanceId instanceId) override - { - m_RenderContext = &inRenderContext; - if (m_Class.RenderInstance) { - inRenderContext.PushPropertySet(); - if (m_Owner->GetAPIVersion() > 1) { - m_Class.RenderInstance(m_Class.m_Class, m_Instance, ToCInterface(inEnvironment), - ToCInterface(inPresentationScaleFactor), - ToCInterface(inColorBufferNeedsClear)); - } else { - TRenderFunctionV1 theV1Function = - reinterpret_cast(m_Class.RenderInstance); - theV1Function(m_Class.m_Class, m_Instance, ToCInterfaceV1(inEnvironment), - ToCInterface(inPresentationScaleFactor), - ToCInterface(inColorBufferNeedsClear)); - } - - inRenderContext.PopPropertySet(true); - } - } - - void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, - SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, - const SRenderInstanceId id) - { - Q_ASSERT(false); - } - - // Implementors should implement one of the two interfaces below. - - // If this renderer supports picking that can return graph objects - // then return an interface here. - IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId) override { return NULL; } - - // If you *don't* support the GraphObjectPickIterator interface, then you should implement this - // interface - // The system will just ask you to pick. - // If you return true, then we will assume that you swallowed the pick and will continue no - // further. - // else we will assume you did not and will continue the picking algorithm. - bool Pick(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, - const SRenderInstanceId instanceId) override - { - if (m_Class.Pick) { - if (m_RenderContext) { - m_RenderContext->PushPropertySet(); - bool retval = m_Class.Pick(m_Class.m_Class, m_Instance, ToCInterface(inMouseCoords), - ToCInterface(inViewportDimensions)) - ? true - : false; - m_RenderContext->PopPropertySet(true); - return retval; - } - } - return false; - } - - TRenderPluginInstancePtr GetRenderPluginInstance() override { return m_Instance; } - void Update(NVConstDataRef updateBuffer) override - { - m_Dirty = true; - m_Owner->Update(updateBuffer, m_PropertyValues); - } - IRenderPluginClass &GetPluginClass() override { return *m_Owner; } -}; - -typedef eastl::pair TStringTypePair; - -struct PluginClassImpl : public IInternalPluginClass -{ - typedef nvhash_map TStringIndexMap; - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - TRenderPluginClass m_Class; - CRegisteredString m_Type; - CLoadedDynamicLibrary *m_DynamicLibrary; - nvvector m_RegisteredProperties; - TStringIndexMap m_ComponentNameToComponentIndexMap; - nvvector m_FullPropertyList; - nvvector m_UpdateBuffer; - CRenderString m_TempString; - QT3DSI32 m_APIVersion; - - QT3DSI32 mRefCount; - - PluginClassImpl(NVFoundationBase &fnd, IStringTable &strTable, TRenderPluginClass inClass, - CRegisteredString inType, CLoadedDynamicLibrary *inLibrary) - : m_Foundation(fnd) - , m_StringTable(strTable) - , m_Class(inClass) - , m_Type(inType) - , m_DynamicLibrary(inLibrary) - , m_RegisteredProperties(m_Foundation.getAllocator(), - "PluginClassImpl::m_RegisteredProperties") - , m_ComponentNameToComponentIndexMap(m_Foundation.getAllocator(), - "PluginClassImpl::m_ComponentNameToComponentIndexMap") - , m_FullPropertyList(m_Foundation.getAllocator(), "PluginClassImpl::m_FullPropertyList") - , m_UpdateBuffer(m_Foundation.getAllocator(), "PluginClassImpl::m_UpdateBuffer") - , m_APIVersion(m_Class.GetRenderPluginAPIVersion(m_Class.m_Class)) - , mRefCount(0) - { - } - ~PluginClassImpl() - { - if (m_Class.ReleaseClass) - m_Class.ReleaseClass(m_Class.m_Class); - if (m_DynamicLibrary) - NVDelete(m_Foundation.getAllocator(), m_DynamicLibrary); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - NVScopedRefCounted CreateInstance() override - { - if (m_Class.CreateInstance) { - TRenderPluginInstancePtr instance = - m_Class.CreateInstance(m_Class.m_Class, m_Type.c_str()); - if (instance) { - InstanceImpl *retval = QT3DS_NEW(m_Foundation.getAllocator(), InstanceImpl)( - m_Foundation, instance, m_Class, *this, m_StringTable); - return retval; - } - } - return NVScopedRefCounted(); - } - - QT3DSI32 GetAPIVersion() override { return m_APIVersion; } - - void AddFullPropertyType(const char *name, RenderPluginPropertyValueTypes::Enum inType) - { - QT3DSU32 itemIndex = (QT3DSU32)m_FullPropertyList.size(); - CRegisteredString regName = m_StringTable.RegisterStr(name); - bool inserted = - m_ComponentNameToComponentIndexMap.insert(eastl::make_pair(regName, itemIndex)).second; - if (inserted) { - m_FullPropertyList.push_back(eastl::make_pair(regName, inType)); - } else { - // Duplicate property declaration. - QT3DS_ASSERT(false); - } - } - - void AddFullPropertyType(const char *name, const char *extension, - RenderPluginPropertyValueTypes::Enum inType) - { - m_TempString.assign(name); - if (!isTrivial(extension)) { - m_TempString.append("."); - m_TempString.append(extension); - } - AddFullPropertyType(m_TempString.c_str(), inType); - } - - void RegisterProperty(const SRenderPluginPropertyDeclaration &dec) override - { - QT3DSU32 startOffset = (QT3DSU32)m_FullPropertyList.size(); - - switch (dec.m_Type) { - - case SRenderPluginPropertyTypes::Vector2: - AddFullPropertyType(dec.m_Name, "x", RenderPluginPropertyValueTypes::Float); - AddFullPropertyType(dec.m_Name, "y", RenderPluginPropertyValueTypes::Float); - break; - case SRenderPluginPropertyTypes::Color: - AddFullPropertyType(dec.m_Name, "r", RenderPluginPropertyValueTypes::Float); - AddFullPropertyType(dec.m_Name, "g", RenderPluginPropertyValueTypes::Float); - AddFullPropertyType(dec.m_Name, "b", RenderPluginPropertyValueTypes::Float); - break; - case SRenderPluginPropertyTypes::Vector3: - AddFullPropertyType(dec.m_Name, "x", RenderPluginPropertyValueTypes::Float); - AddFullPropertyType(dec.m_Name, "y", RenderPluginPropertyValueTypes::Float); - AddFullPropertyType(dec.m_Name, "z", RenderPluginPropertyValueTypes::Float); - break; - case SRenderPluginPropertyTypes::Boolean: - AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::Boolean); - break; - case SRenderPluginPropertyTypes::Float: - AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::Float); - break; - case SRenderPluginPropertyTypes::Long: - AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::Long); - break; - case SRenderPluginPropertyTypes::String: - AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::String); - break; - default: - QT3DS_ASSERT(false); - break; - } - m_RegisteredProperties.push_back(dec); - m_RegisteredProperties.back().m_StartOffset = startOffset; - } - - NVConstDataRef GetRegisteredProperties() override - { - return m_RegisteredProperties; - } - - SRenderPluginPropertyDeclaration GetPropertyDeclaration(CRegisteredString inPropName) override - { - for (QT3DSU32 idx = 0, end = m_RegisteredProperties.size(); idx < end; ++idx) { - if (m_RegisteredProperties[idx].m_Name == inPropName) - return m_RegisteredProperties[idx]; - } - QT3DS_ASSERT(false); - return SRenderPluginPropertyDeclaration(); - } - - // From which you can get the property name breakdown - virtual eastl::pair - GetPropertyValueInfo(QT3DSU32 inIndex) override - { - if (inIndex < m_FullPropertyList.size()) - return m_FullPropertyList[inIndex]; - QT3DS_ASSERT(false); - return eastl::pair( - CRegisteredString(), RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue); - } - - void PushUpdates(TRenderPluginInstancePtr instance, TPropertyValueList &propertyValues) override - { - m_UpdateBuffer.clear(); - for (QT3DSU32 idx = 0, end = propertyValues.size(); idx < end; ++idx) { - SRenderPluginPropertyData &theData(propertyValues[idx]); - if (theData.IsDirty()) - m_UpdateBuffer.push_back(theData.ClearDirty(m_FullPropertyList[idx].first)); - } - if (m_Class.UpdateInstance) - m_Class.UpdateInstance(m_Class.m_Class, instance, m_UpdateBuffer.data(), - (long)m_UpdateBuffer.size()); - } - - void Update(NVConstDataRef updateBuffer, - TPropertyValueList &propertyValues) override - { - for (QT3DSU32 idx = 0, end = updateBuffer.size(); idx < end; ++idx) { - const SRenderPropertyValueUpdate &update = updateBuffer[idx]; - TStringIndexMap::iterator iter = - m_ComponentNameToComponentIndexMap.find(update.m_PropertyName); - if (iter == m_ComponentNameToComponentIndexMap.end()) { - QT3DS_ASSERT(false); - continue; - } - - QT3DSU32 propIndex = iter->second; - if (update.m_Value.getType() != m_FullPropertyList[propIndex].second) { - QT3DS_ASSERT(false); - continue; - } - if (propIndex >= propertyValues.size()) - propertyValues.resize(propIndex + 1); - propertyValues[propIndex].SetValue(update.m_Value); - } - } -}; - -struct PluginInstanceKey -{ - CRegisteredString m_Path; - void *m_InstanceKey; - PluginInstanceKey(CRegisteredString p, void *ik) - : m_Path(p) - , m_InstanceKey(ik) - { - } - bool operator==(const PluginInstanceKey &rhs) const - { - return m_Path == rhs.m_Path && m_InstanceKey == rhs.m_InstanceKey; - } -}; -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const PluginInstanceKey &k) const - { - return hash()(k.m_Path) - ^ hash()(reinterpret_cast(k.m_InstanceKey)); - } - bool operator()(const PluginInstanceKey &lhs, const PluginInstanceKey &rhs) const - { - return lhs.m_Path == rhs.m_Path && lhs.m_InstanceKey == rhs.m_InstanceKey; - } -}; -} - -namespace { - -struct SLoadedPluginData -{ - CRegisteredString m_PluginPath; - eastl::vector m_Properties; -}; - -typedef eastl::vector TLoadedPluginDataList; - -struct PluginManagerImpl : public IRenderPluginManager, public IRenderPluginManagerCore -{ - typedef nvhash_map> TLoadedClassMap; - typedef nvhash_map> TInstanceMap; - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - TLoadedClassMap m_LoadedClasses; - TInstanceMap m_Instances; - NVScopedRefCounted m_RenderContext; - IInputStreamFactory &m_InputStreamFactory; - QT3DSI32 mRefCount; - TStr m_DllDir; - TLoadedPluginDataList m_LoadedPluginData; - - PluginManagerImpl(NVFoundationBase &fnd, IStringTable &st, IInputStreamFactory &inFactory) - : m_Foundation(fnd) - , m_StringTable(st) - , m_LoadedClasses(fnd.getAllocator(), "PluginManagerImpl::m_LoadedClasses") - , m_Instances(fnd.getAllocator(), "PluginManagerImpl::m_Instances") - , m_InputStreamFactory(inFactory) - , mRefCount(0) - , m_DllDir(ForwardingAllocator(fnd.getAllocator(), "PluginManagerImpl::m_DllDir")) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - IRenderPluginClass *GetRenderPlugin(CRegisteredString inRelativePath) override - { - TLoadedClassMap::iterator iter = m_LoadedClasses.find(inRelativePath); - if (iter != m_LoadedClasses.end()) - return iter->second; - - return NVScopedRefCounted(); - } - - IRenderPluginClass *GetOrCreateRenderPlugin(CRegisteredString inRelativePath) override - { - TLoadedClassMap::iterator iter = m_LoadedClasses.find(inRelativePath); - if (iter != m_LoadedClasses.end()) { - return iter->second; - } - - // We insert right here to keep us from going down this path potentially for every instance. - iter = - m_LoadedClasses - .insert(eastl::make_pair(inRelativePath, NVScopedRefCounted())) - .first; - eastl::string xmlDir, fname, extension; - - CFileTools::Split(inRelativePath.c_str(), xmlDir, fname, extension); - - eastl::string sharedLibrary(xmlDir); - eastl::string subdir(qt3ds::foundation::System::getPlatformGLStr()); - eastl::string libdir; - eastl::string libpath; - - CFileTools::CombineBaseAndRelative(xmlDir.c_str(), subdir.c_str(), libdir); - CFileTools::CombineBaseAndRelative(libdir.c_str(), fname.c_str(), libpath); -#ifdef _DEBUG - libpath.append("d"); -#endif - libpath.append(qt3ds::foundation::System::g_DLLExtension); - eastl::string loadPath; - if (m_DllDir.size()) { - // Then we have to copy the dll to the dll directory before loading because the - // filesystem - // the plugin is on may not be executable. - eastl::string targetFile; - CFileTools::CombineBaseAndRelative(m_DllDir.c_str(), fname.c_str(), targetFile); -#ifdef _DEBUG - targetFile.append("d"); -#endif - targetFile.append(qt3ds::foundation::System::g_DLLExtension); - - qCInfo(TRACE_INFO, "Copying plugin shared library from %s to %s", - libpath.c_str(), targetFile.c_str()); - - // try to open the library. - NVScopedRefCounted theStream = - m_InputStreamFactory.GetStreamForFile(libpath.c_str()); - if (!theStream) { - qCCritical(INVALID_OPERATION, "Failed to load render plugin %s", - libpath.c_str()); - return NULL; - } - CFileSeekableIOStream outStream(targetFile.c_str(), FileWriteFlags()); - if (!outStream.IsOpen()) { - qCCritical(INVALID_OPERATION, "Failed to load render plugin %s", - targetFile.c_str()); - return NULL; - } - - QT3DSU8 buf[1024] = { 0 }; - for (QT3DSU32 len = theStream->Read(toDataRef(buf, 1024)); len; - len = theStream->Read(toDataRef(buf, 1024))) { - outStream.Write(toDataRef(buf, len)); - } - loadPath = targetFile; - } else { - QString path; - m_InputStreamFactory.GetPathForFile(libpath.c_str(), path); - loadPath = path.toUtf8().data(); - } - CLoadedDynamicLibrary *library = NULL; - TRenderPluginClass newPluginClass; - memSet(&newPluginClass, 0, sizeof(newPluginClass)); - - // Do not load plugin dlls during compilation steps or when we don't have a valid render - // context. - // They may try opengl access at some point and that would end in disaster during binary - // save steps. - if ((QT3DSU32)m_RenderContext->GetRenderContextType() != NVRenderContextValues::NullContext) { - library = CLoadedDynamicLibrary::Create(loadPath.c_str(), m_Foundation); - if (!library) { - // try loading it from the system instead of from this specific path. This means do - // not use any extensions or any special - // sauce. - loadPath = fname; -#ifdef _DEBUG - loadPath.append("d"); -#endif - library = CLoadedDynamicLibrary::Create(loadPath.c_str(), m_Foundation); - } - } - - if (library) { - TCreateRenderPluginClassFunction CreateClass = - reinterpret_cast( - library->FindFunction("CreateRenderPlugin")); - if (CreateClass) { - newPluginClass = CreateClass(fname.c_str()); - if (newPluginClass.m_Class) { - // Check that the required functions are there. - if (newPluginClass.CreateInstance == NULL - || newPluginClass.QueryInstanceRenderSurface == NULL - || newPluginClass.RenderInstance == NULL - || newPluginClass.ReleaseInstance == NULL - || newPluginClass.ReleaseClass == NULL) { - if (newPluginClass.ReleaseClass) - newPluginClass.ReleaseClass(newPluginClass.m_Class); - qCCritical(INVALID_OPERATION, - "Failed to load render plugin: %s, required functions " - "missing. Required functions are:" - "CreateInstance, QueryInstanceRenderSurface, " - "RenderInstance, ReleaseInstance, ReleaseClass", - inRelativePath.c_str()); - NVDelete(m_Foundation.getAllocator(), library); - memSet(&newPluginClass, 0, sizeof(newPluginClass)); - } - } - } - } - if (newPluginClass.m_Class) { - PluginClassImpl *retval = QT3DS_NEW(m_Foundation.getAllocator(), PluginClassImpl)( - m_Foundation, m_StringTable, newPluginClass, - m_StringTable.RegisterStr(fname.c_str()), library); - - iter->second = retval; - if (newPluginClass.InitializeClassGLResources) { - m_RenderContext->PushPropertySet(); - newPluginClass.InitializeClassGLResources(newPluginClass.m_Class, loadPath.c_str()); - m_RenderContext->PopPropertySet(true); - } - return iter->second; - } - return NULL; - } - - void SetDllDir(const char *inDllDir) override { m_DllDir.assign(nonNull(inDllDir)); } - - IRenderPluginInstance *GetOrCreateRenderPluginInstance(CRegisteredString inRelativePath, - void *inKey) override - { - PluginInstanceKey theKey(inRelativePath, inKey); - TInstanceMap::iterator iter = m_Instances.find(theKey); - if (iter == m_Instances.end()) { - IRenderPluginClass *theClass = GetOrCreateRenderPlugin(inRelativePath); - NVScopedRefCounted theInstance; - if (theClass) - theInstance = theClass->CreateInstance(); - - iter = m_Instances.insert(eastl::make_pair(theKey, theInstance)).first; - } - return iter->second.mPtr; - } - - void Save(qt3ds::render::SWriteBuffer &ioBuffer, - const qt3ds::render::SStrRemapMap &inRemapMap, - const char8_t * /*inProjectDir*/) const override - { - QT3DSU32 numClasses = m_LoadedClasses.size(); - ioBuffer.write(numClasses); - for (TLoadedClassMap::const_iterator iter = m_LoadedClasses.begin(), - end = m_LoadedClasses.end(); - iter != end; ++iter) { - CRegisteredString saveStr = iter->first; - saveStr.Remap(inRemapMap); - ioBuffer.write(saveStr); - if (iter->second) { - NVConstDataRef theProperties = - const_cast((*iter->second)).GetRegisteredProperties(); - ioBuffer.write(theProperties.size()); - for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { - SRenderPluginPropertyDeclaration theDec(theProperties[idx]); - theDec.m_Name.Remap(inRemapMap); - ioBuffer.write(theDec); - } - } else - ioBuffer.write((QT3DSU32)0); - } - } - - void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, - const char8_t * /*inProjectDir*/) override - { - qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); - QT3DSU32 numClasses = theReader.LoadRef(); - ForwardingAllocator alloc(m_Foundation.getAllocator(), "tempstrings"); - qt3ds::foundation::TStr workStr(alloc); - nvvector propertyBuffer(m_Foundation.getAllocator(), - "tempprops"); - for (QT3DSU32 classIdx = 0; classIdx < numClasses; ++classIdx) { - CRegisteredString classPath = theReader.LoadRef(); - classPath.Remap(inStrDataBlock); - QT3DSU32 numProperties = theReader.LoadRef(); - propertyBuffer.clear(); - for (QT3DSU32 propIdx = 0; propIdx < numProperties; ++propIdx) { - propertyBuffer.push_back(theReader.LoadRef()); - propertyBuffer.back().m_Name.Remap(inStrDataBlock); - } - m_LoadedPluginData.push_back(SLoadedPluginData()); - m_LoadedPluginData.back().m_PluginPath = classPath; - m_LoadedPluginData.back().m_Properties.assign(propertyBuffer.begin(), - propertyBuffer.end()); - } - } - IRenderPluginManager &GetRenderPluginManager(NVRenderContext &rc) override - { - m_RenderContext = rc; - for (QT3DSU32 idx = 0, end = m_LoadedPluginData.size(); idx < end; ++idx) { - // Now we can attempt to load the class. - IRenderPluginClass *theClass = - GetOrCreateRenderPlugin(m_LoadedPluginData[idx].m_PluginPath); - if (theClass) { - eastl::vector &propertyBuffer( - m_LoadedPluginData[idx].m_Properties); - for (QT3DSU32 propIdx = 0, propEnd = propertyBuffer.size(); propIdx < propEnd; - ++propIdx) { - theClass->RegisterProperty(propertyBuffer[propIdx]); - } - } - } - m_LoadedPluginData.clear(); - return *this; - } -}; -} - -IRenderPluginManagerCore &IRenderPluginManagerCore::Create(NVFoundationBase &inFoundation, - IStringTable &strTable, - IInputStreamFactory &inFactory) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), PluginManagerImpl)(inFoundation, strTable, - inFactory); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRay.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRay.cpp deleted file mode 100644 index 5376b8b9..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRay.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderRay.h" -#include "foundation/Qt3DSPlane.h" - -using namespace qt3ds::render; - -// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm - -Option SRay::Intersect(const NVPlane &inPlane) const -{ - QT3DSF32 Vd = inPlane.n.dot(m_Direction); - if (fabs(Vd) < .0001f) - return Empty(); - QT3DSF32 V0 = -1.0f * (inPlane.n.dot(m_Origin) + inPlane.d); - QT3DSF32 t = V0 / Vd; - return m_Origin + (m_Direction * t); -} - -Option SRay::IntersectWithAABB(const QT3DSMat44 &inGlobalTransform, - const NVBounds3 &inBounds, - bool inForceIntersect) const -{ - // Intersect the origin with the AABB described by bounds. - - // Scan each axis separately. This code basically finds the distance - // distance from the origin to the near and far bbox planes for a given - // axis. It then divides this distance by the direction for that axis to - // get a range of t [near,far] that the ray intersects assuming the ray is - // described via origin + t*(direction). Running through all three axis means - // that you need to min/max those ranges together to find a global min/max - // that the pick could possibly be in. - - // Transform pick origin and direction into the subset's space. - QT3DSMat44 theOriginTransform = inGlobalTransform.getInverse(); - - QT3DSVec3 theTransformedOrigin = theOriginTransform.transform(m_Origin); - QT3DSF32 *outOriginTransformPtr(theOriginTransform.front()); - outOriginTransformPtr[12] = outOriginTransformPtr[13] = outOriginTransformPtr[14] = 0.0f; - QT3DSVec3 theTransformedDirection = theOriginTransform.rotate(m_Direction); - - static const QT3DSF32 KD_FLT_MAX = 3.40282346638528860e+38; - static const QT3DSF32 kEpsilon = 1e-5f; - - QT3DSF32 theMinWinner = -KD_FLT_MAX; - QT3DSF32 theMaxWinner = KD_FLT_MAX; - - for (QT3DSU32 theAxis = 0; theAxis < 3; ++theAxis) { - // Extract the ranges and direction for this axis - QT3DSF32 theMinBox = inBounds.minimum[theAxis]; - QT3DSF32 theMaxBox = inBounds.maximum[theAxis]; - QT3DSF32 theDirectionAxis = theTransformedDirection[theAxis]; - QT3DSF32 theOriginAxis = theTransformedOrigin[theAxis]; - - QT3DSF32 theMinAxis = -KD_FLT_MAX; - QT3DSF32 theMaxAxis = KD_FLT_MAX; - if (theDirectionAxis > kEpsilon) { - theMinAxis = (theMinBox - theOriginAxis) / theDirectionAxis; - theMaxAxis = (theMaxBox - theOriginAxis) / theDirectionAxis; - } else if (theDirectionAxis < -kEpsilon) { - theMinAxis = (theMaxBox - theOriginAxis) / theDirectionAxis; - theMaxAxis = (theMinBox - theOriginAxis) / theDirectionAxis; - } else if ((theOriginAxis < theMinBox || theOriginAxis > theMaxBox) - && inForceIntersect == false) { - // Pickray is roughly parallel to the plane of the slab - // so, if the origin is not in the range, we have no intersection - return Empty(); - } - - // Shrink the intersections to find the closest hit - theMinWinner = NVMax(theMinWinner, theMinAxis); - theMaxWinner = NVMin(theMaxWinner, theMaxAxis); - - if ((theMinWinner > theMaxWinner || theMaxWinner < 0) && inForceIntersect == false) - return Empty(); - } - - QT3DSVec3 scaledDir = theTransformedDirection * theMinWinner; - QT3DSVec3 newPosInLocal = theTransformedOrigin + scaledDir; - QT3DSVec3 newPosInGlobal = inGlobalTransform.transform(newPosInLocal); - QT3DSVec3 cameraToLocal = m_Origin - newPosInGlobal; - - QT3DSF32 rayLengthSquared = cameraToLocal.magnitudeSquared(); - - QT3DSF32 xRange = inBounds.maximum.x - inBounds.minimum.x; - QT3DSF32 yRange = inBounds.maximum.y - inBounds.minimum.y; - - QT3DSVec2 relXY; - relXY.x = (newPosInLocal[0] - inBounds.minimum.x) / xRange; - relXY.y = (newPosInLocal[1] - inBounds.minimum.y) / yRange; - - return SRayIntersectionResult(rayLengthSquared, relXY); -} - -Option SRay::GetRelative(const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, - SBasisPlanes::Enum inPlane) const -{ - QT3DSMat44 theOriginTransform = inGlobalTransform.getInverse(); - - QT3DSVec3 theTransformedOrigin = theOriginTransform.transform(m_Origin); - QT3DSF32 *outOriginTransformPtr(theOriginTransform.front()); - outOriginTransformPtr[12] = outOriginTransformPtr[13] = outOriginTransformPtr[14] = 0.0f; - QT3DSVec3 theTransformedDirection = theOriginTransform.rotate(m_Direction); - - // The XY plane is going to be a plane with either positive or negative Z direction that runs - // through - QT3DSVec3 theDirection(0, 0, 1); - QT3DSVec3 theRight(1, 0, 0); - QT3DSVec3 theUp(0, 1, 0); - switch (inPlane) { - case SBasisPlanes::XY: - break; - case SBasisPlanes::XZ: - theDirection = QT3DSVec3(0, 1, 0); - theUp = QT3DSVec3(0, 0, 1); - break; - case SBasisPlanes::YZ: - theDirection = QT3DSVec3(1, 0, 0); - theRight = QT3DSVec3(0, 0, 1); - break; - } - NVPlane thePlane(theDirection, theDirection.dot(theTransformedDirection) > 0.0f - ? theDirection.dot(inBounds.maximum) - : theDirection.dot(inBounds.minimum)); - - SRay relativeRay(theTransformedOrigin, theTransformedDirection); - Option localIsect = relativeRay.Intersect(thePlane); - if (localIsect.hasValue()) { - QT3DSF32 xRange = theRight.dot(inBounds.maximum) - theRight.dot(inBounds.minimum); - QT3DSF32 yRange = theUp.dot(inBounds.maximum) - theUp.dot(inBounds.minimum); - QT3DSF32 xOrigin = xRange / 2.0f + theRight.dot(inBounds.minimum); - QT3DSF32 yOrigin = yRange / 2.0f + theUp.dot(inBounds.minimum); - return QT3DSVec2((theRight.dot(*localIsect) - xOrigin) / xRange, - (theUp.dot(*localIsect) - yOrigin) / yRange); - } - return Empty(); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRenderList.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRenderList.cpp deleted file mode 100644 index 118c855d..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderRenderList.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderRenderList.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "render/Qt3DSRenderBaseTypes.h" - -using namespace qt3ds::render; - -namespace { - -struct SRenderList : public IRenderList -{ - typedef eastl::pair TTaskIdTaskPair; - typedef nvvector TTaskList; - - NVFoundationBase &m_Foundation; - TTaskList m_Tasks; - QT3DSU32 m_NextTaskId; - QT3DSI32 mRefCount; - bool m_ScissorEnabled; - NVRenderRect m_ScissorRect; - NVRenderRect m_Viewport; - - SRenderList(NVFoundationBase &fnd) - : m_Foundation(fnd) - , m_Tasks(fnd.getAllocator(), "m_Tasks") - , m_NextTaskId(1) - , mRefCount(0) - , m_ScissorEnabled(false) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void BeginFrame() override - { - m_NextTaskId = 1; - m_Tasks.clear(); - } - - QT3DSU32 AddRenderTask(IRenderTask &inTask) override - { - QT3DSU32 taskId = m_NextTaskId; - ++m_NextTaskId; - m_Tasks.push_back(eastl::make_pair(taskId, &inTask)); - return taskId; - } - - void DiscardRenderTask(QT3DSU32 inTaskId) override - { - TTaskList::iterator iter, end; - for (iter = m_Tasks.begin(), end = m_Tasks.end(); iter != end && iter->first != inTaskId; - ++iter) { - } - if (iter != end) - m_Tasks.erase(iter); - } - // This runs through the added tasks in reverse order. This is used to render dependencies - // before rendering to the main render target. - void RunRenderTasks() override - { - for (TTaskList::reverse_iterator iter = m_Tasks.rbegin(), end = m_Tasks.rend(); iter != end; - ++iter) - iter->second->Run(); - BeginFrame(); - } - - void SetScissorTestEnabled(bool enabled) override { m_ScissorEnabled = enabled; } - void SetScissorRect(NVRenderRect rect) override { m_ScissorRect = rect; } - void SetViewport(NVRenderRect rect) override { m_Viewport = rect; } - bool IsScissorTestEnabled() const override { return m_ScissorEnabled; } - NVRenderRect GetScissor() const override { return m_ScissorRect; } - NVRenderRect GetViewport() const override { return m_Viewport; } -}; -} - -IRenderList &IRenderList::CreateRenderList(NVFoundationBase &fnd) -{ - return *QT3DS_NEW(fnd.getAllocator(), SRenderList)(fnd); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCache.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCache.cpp deleted file mode 100644 index 0c7c4997..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCache.cpp +++ /dev/null @@ -1,768 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderShaderCache.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSRenderString.h" -#include "foundation/XML.h" -#include "foundation/IOStreams.h" -#include "foundation/StringConversionImpl.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "foundation/FileTools.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderer.h" -#include -#include "foundation/Qt3DSTime.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "EASTL/sort.h" - -#include -#include - -using namespace qt3ds::render; - -namespace { -using qt3ds::render::NVRenderContextScopedProperty; -const char *TessellationEnabledStr = "TessellationStageEnabled"; -const char *GeometryEnabledStr = "GeometryStageEnabled"; -inline void AppendFlagValue(CRenderString &inStr, const char *flag) -{ - if (inStr.length()) - inStr.append(1, ','); - inStr.append(flag); -} -inline void CacheFlagsToStr(const SShaderCacheProgramFlags &inFlags, CRenderString &inString) -{ - inString.clear(); - if (inFlags.IsTessellationEnabled()) - AppendFlagValue(inString, TessellationEnabledStr); - if (inFlags.IsGeometryShaderEnabled()) - AppendFlagValue(inString, GeometryEnabledStr); -} - -struct ShaderType -{ - enum Enum { Vertex, TessControl, TessEval, Fragment, Geometry, Compute }; -}; - -inline ShaderType::Enum StringToShaderType(CRenderString &inShaderType) -{ - ShaderType::Enum retval = ShaderType::Vertex; - - if (inShaderType.size() == 0) - return retval; - - if (!inShaderType.compare("VertexCode")) - retval = ShaderType::Vertex; - else if (!inShaderType.compare("FragmentCode")) - retval = ShaderType::Fragment; - else if (!inShaderType.compare("TessControlCode")) - retval = ShaderType::TessControl; - else if (!inShaderType.compare("TessEvalCode")) - retval = ShaderType::TessEval; - else if (!inShaderType.compare("GeometryCode")) - retval = ShaderType::Geometry; - else - QT3DS_ASSERT(false); - - return retval; -} - -inline SShaderCacheProgramFlags CacheFlagsToStr(const CRenderString &inString) -{ - SShaderCacheProgramFlags retval; - if (inString.find(TessellationEnabledStr) != CRenderString::npos) - retval.SetTessellationEnabled(true); - if (inString.find(GeometryEnabledStr) != CRenderString::npos) - retval.SetGeometryShaderEnabled(true); - return retval; -} - -typedef eastl::pair TStringToContextValuePair; - -/*GLES2 = 1 << 0, -GL2 = 1 << 1, -GLES3 = 1 << 2, -GL3 = 1 << 3, -GL4 = 1 << 4, -NullContext = 1 << 5,*/ -TStringToContextValuePair g_StringToContextTypeValue[] = { - TStringToContextValuePair("GLES2", NVRenderContextValues::GLES2), - TStringToContextValuePair("GL2", NVRenderContextValues::GL2), - TStringToContextValuePair("GLES3", NVRenderContextValues::GLES3), - TStringToContextValuePair("GLES3PLUS", NVRenderContextValues::GLES3PLUS), - TStringToContextValuePair("GL3", NVRenderContextValues::GL3), - TStringToContextValuePair("GL4", NVRenderContextValues::GL4), - TStringToContextValuePair("NullContext", NVRenderContextValues::NullContext), -}; - -size_t g_NumStringToContextValueEntries = - sizeof(g_StringToContextTypeValue) / sizeof(*g_StringToContextTypeValue); - -inline void ContextTypeToString(qt3ds::render::NVRenderContextType inType, - CRenderString &outContextType) -{ - outContextType.clear(); - for (size_t idx = 0, end = g_NumStringToContextValueEntries; idx < end; ++idx) { - if (inType & g_StringToContextTypeValue[idx].second) { - if (outContextType.size()) - outContextType.append(1, '|'); - outContextType.append(g_StringToContextTypeValue[idx].first); - } - } -} - -inline qt3ds::render::NVRenderContextType StringToContextType(const CRenderString &inContextType) -{ - qt3ds::render::NVRenderContextType retval; - char tempBuffer[128]; - memZero(tempBuffer, 128); - const eastl::string::size_type lastTempBufIdx = 127; - eastl::string::size_type pos = 0, lastpos = 0; - if (inContextType.size() == 0) - return retval; - - do { - pos = int(inContextType.find('|', lastpos)); - if (pos == eastl::string::npos) - pos = int(inContextType.size()); - { - - eastl::string::size_type sectionLen = NVMin(pos - lastpos, lastTempBufIdx); - qt3ds::intrinsics::memCopy(tempBuffer, inContextType.c_str() + lastpos, sectionLen); - tempBuffer[lastTempBufIdx] = 0; - for (size_t idx = 0, end = g_NumStringToContextValueEntries; idx < end; ++idx) { - if (strcmp(g_StringToContextTypeValue[idx].first, tempBuffer) == 0) - retval = retval | g_StringToContextTypeValue[idx].second; - } - } - // iterate past the bar - ++pos; - lastpos = pos; - } while (pos < inContextType.size() && pos != eastl::string::npos); - - return retval; -} - -struct SShaderCacheKey -{ - CRegisteredString m_Key; - eastl::vector m_Features; - size_t m_HashCode; - - SShaderCacheKey(CRegisteredString key = CRegisteredString()) - : m_Key(key) - , m_HashCode(0) - { - } - - SShaderCacheKey(const SShaderCacheKey &other) - : m_Key(other.m_Key) - , m_Features(other.m_Features) - , m_HashCode(other.m_HashCode) - { - } - - SShaderCacheKey &operator=(const SShaderCacheKey &other) - { - m_Key = other.m_Key; - m_Features = other.m_Features; - m_HashCode = other.m_HashCode; - return *this; - } - - void GenerateHashCode() - { - m_HashCode = m_Key.hash(); - m_HashCode = m_HashCode - ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size())); - } - bool operator==(const SShaderCacheKey &inOther) const - { - return m_Key == inOther.m_Key && m_Features == inOther.m_Features; - } -}; -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SShaderCacheKey &inKey) const { return inKey.m_HashCode; } -}; -} - -namespace { - -struct ShaderCache : public IShaderCache -{ - typedef nvhash_map> TShaderMap; - NVRenderContext &m_RenderContext; - IPerfTimer &m_PerfTimer; - TShaderMap m_Shaders; - CRenderString m_CacheFilePath; - CRenderString m_VertexCode; - CRenderString m_TessCtrlCode; - CRenderString m_TessEvalCode; - CRenderString m_GeometryCode; - CRenderString m_FragmentCode; - CRenderString m_InsertStr; - CRenderString m_FlagString; - CRenderString m_ContextTypeString; - SShaderCacheKey m_TempKey; - - NVScopedRefCounted m_ShaderCache; - IInputStreamFactory &m_InputStreamFactory; - bool m_ShaderCompilationEnabled; - volatile QT3DSI32 mRefCount; - - ShaderCache(NVRenderContext &ctx, IInputStreamFactory &inInputStreamFactory, - IPerfTimer &inPerfTimer) - : m_RenderContext(ctx) - , m_PerfTimer(inPerfTimer) - , m_Shaders(ctx.GetAllocator(), "ShaderCache::m_Shaders") - , m_InputStreamFactory(inInputStreamFactory) - , m_ShaderCompilationEnabled(true) - , mRefCount(0) - { - } - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) - - NVRenderShaderProgram *GetProgram(CRegisteredString inKey, - NVConstDataRef inFeatures) override - { - m_TempKey.m_Key = inKey; - m_TempKey.m_Features.assign(inFeatures.begin(), inFeatures.end()); - m_TempKey.GenerateHashCode(); - TShaderMap::iterator theIter = m_Shaders.find(m_TempKey); - if (theIter != m_Shaders.end()) - return theIter->second; - return NULL; - } - - void AddBackwardCompatibilityDefines(ShaderType::Enum shaderType) - { - if (shaderType == ShaderType::Vertex || shaderType == ShaderType::TessControl - || shaderType == ShaderType::TessEval || shaderType == ShaderType::Geometry) { - m_InsertStr += "#define attribute in\n"; - m_InsertStr += "#define varying out\n"; - } else if (shaderType == ShaderType::Fragment) { - m_InsertStr += "#define varying in\n"; - m_InsertStr += "#define texture2D texture\n"; - m_InsertStr += "#define gl_FragColor fragOutput\n"; - - if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) - m_InsertStr += "layout(blend_support_all_equations) out;\n "; - m_InsertStr += "out vec4 fragOutput;\n"; - } - } - - void AddShaderExtensionStrings(ShaderType::Enum shaderType, bool isGLES) - { - if (isGLES) { - if (m_RenderContext.IsStandardDerivativesSupported()) - m_InsertStr += "#extension GL_OES_standard_derivatives : enable\n"; - else - m_InsertStr += "#extension GL_OES_standard_derivatives : disable\n"; - } - - if (IQt3DSRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) { - if (shaderType == ShaderType::TessControl || shaderType == ShaderType::TessEval) { - m_InsertStr += "#extension GL_EXT_tessellation_shader : enable\n"; - } else if (shaderType == ShaderType::Geometry) { - m_InsertStr += "#extension GL_EXT_geometry_shader : enable\n"; - } else if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment) { - if (m_RenderContext.GetRenderBackendCap(render::NVRenderBackend::NVRenderBackendCaps::gpuShader5)) - m_InsertStr += "#extension GL_EXT_gpu_shader5 : enable\n"; - if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) - m_InsertStr += "#extension GL_KHR_blend_equation_advanced : enable\n"; - } - } else { - if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment - || shaderType == ShaderType::Geometry) { - if (m_RenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) { - m_InsertStr += "#extension GL_ARB_gpu_shader5 : enable\n"; - m_InsertStr += "#extension GL_ARB_shading_language_420pack : enable\n"; - } - if (isGLES && m_RenderContext.IsTextureLodSupported()) - m_InsertStr += "#extension GL_EXT_shader_texture_lod : enable\n"; - if (m_RenderContext.IsShaderImageLoadStoreSupported()) - m_InsertStr += "#extension GL_ARB_shader_image_load_store : enable\n"; - if (m_RenderContext.IsAtomicCounterBufferSupported()) - m_InsertStr += "#extension GL_ARB_shader_atomic_counters : enable\n"; - if (m_RenderContext.IsStorageBufferSupported()) - m_InsertStr += "#extension GL_ARB_shader_storage_buffer_object : enable\n"; - if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) - m_InsertStr += "#extension GL_KHR_blend_equation_advanced : enable\n"; - } - } - } - - void AddShaderPreprocessor(CRenderString &str, CRegisteredString inKey, - ShaderType::Enum shaderType, - NVConstDataRef inFeatures) - { - // Don't use shading language version returned by the driver as it might - // differ from the context version. Instead use the context type to specify - // the version string. - bool isGlES = IQt3DSRenderer::IsGlEsContext(m_RenderContext.GetRenderContextType()); - m_InsertStr.clear(); - int minor = m_RenderContext.format().minorVersion(); - QString versionStr; - QTextStream stream(&versionStr); - stream << "#version "; - const QT3DSU32 type = (QT3DSU32)m_RenderContext.GetRenderContextType(); - switch (type) { - case NVRenderContextValues::GLES2: - stream << "1" << minor << "0\n"; - break; - case NVRenderContextValues::GL2: - stream << "1" << minor << "0\n"; - break; - case NVRenderContextValues::GLES3PLUS: - case NVRenderContextValues::GLES3: - stream << "3" << minor << "0 es\n"; - break; - case NVRenderContextValues::GL3: - if (minor == 3) - stream << "3" << minor << "0\n"; - else - stream << "1" << 3 + minor << "0\n"; - break; - case NVRenderContextValues::GL4: - stream << "4" << minor << "0\n"; - break; - default: - QT3DS_ASSERT(false); - break; - } - - m_InsertStr.append(versionStr.toLatin1().data()); - - if (isGlES) { - if (!IQt3DSRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) { - if (shaderType == ShaderType::Fragment) { - m_InsertStr += "#define fragOutput gl_FragData[0]\n"; - } - } else { - m_InsertStr += "#define texture2D texture\n"; - } - - // add extenions strings before any other non-processor token - AddShaderExtensionStrings(shaderType, isGlES); - - // add precision qualifier depending on backend - if (IQt3DSRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) { - m_InsertStr.append("precision highp float;\n" - "precision highp int;\n"); - if( m_RenderContext.GetRenderBackendCap(render::NVRenderBackend::NVRenderBackendCaps::gpuShader5) ) { - m_InsertStr.append("precision mediump sampler2D;\n" - "precision mediump sampler2DArray;\n" - "precision mediump sampler2DShadow;\n"); - if (m_RenderContext.IsShaderImageLoadStoreSupported()) { - m_InsertStr.append("precision mediump image2D;\n"); - } - } - - AddBackwardCompatibilityDefines(shaderType); - } else { - // GLES2 - m_InsertStr.append("precision mediump float;\n" - "precision mediump int;\n" - "#define texture texture2D\n"); - if (m_RenderContext.IsTextureLodSupported()) - m_InsertStr.append("#define textureLod texture2DLodEXT\n"); - else - m_InsertStr.append("#define textureLod(s, co, lod) texture2D(s, co)\n"); - } - } else { - if (!IQt3DSRenderer::IsGl2Context(m_RenderContext.GetRenderContextType())) { - m_InsertStr += "#define texture2D texture\n"; - - AddShaderExtensionStrings(shaderType, isGlES); - - m_InsertStr += "#if __VERSION__ >= 330\n"; - - AddBackwardCompatibilityDefines(shaderType); - - m_InsertStr += "#else\n"; - if (shaderType == ShaderType::Fragment) { - m_InsertStr += "#define fragOutput gl_FragData[0]\n"; - } - m_InsertStr += "#endif\n"; - } - } - - if (inKey.IsValid()) { - m_InsertStr += "//Shader name -"; - m_InsertStr += inKey.c_str(); - m_InsertStr += "\n"; - } - - if (shaderType == ShaderType::TessControl) { - m_InsertStr += "#define TESSELLATION_CONTROL_SHADER 1\n"; - m_InsertStr += "#define TESSELLATION_EVALUATION_SHADER 0\n"; - } else if (shaderType == ShaderType::TessEval) { - m_InsertStr += "#define TESSELLATION_CONTROL_SHADER 0\n"; - m_InsertStr += "#define TESSELLATION_EVALUATION_SHADER 1\n"; - } - - str.insert(0, m_InsertStr); - if (inFeatures.size()) { - eastl::string::size_type insertPos = int(m_InsertStr.size()); - m_InsertStr.clear(); - for (QT3DSU32 idx = 0, end = inFeatures.size(); idx < end; ++idx) { - SShaderPreprocessorFeature feature(inFeatures[idx]); - m_InsertStr.append("#define "); - m_InsertStr.append(inFeatures[idx].m_Name.c_str()); - m_InsertStr.append(" "); - m_InsertStr.append(feature.m_Enabled ? "1" : "0"); - m_InsertStr.append("\n"); - } - str.insert(insertPos, m_InsertStr); - } - } - // Compile this program overwriting any existing ones. - NVRenderShaderProgram * - ForceCompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, - const char8_t *inTessCtrl, const char8_t *inTessEval, const char8_t *inGeom, - const SShaderCacheProgramFlags &inFlags, - NVConstDataRef inFeatures, - bool separableProgram, bool fromDisk = false) override - { - if (m_ShaderCompilationEnabled == false) - return NULL; - SShaderCacheKey tempKey(inKey); - tempKey.m_Features.assign(inFeatures.begin(), inFeatures.end()); - tempKey.GenerateHashCode(); - - eastl::pair theInserter = m_Shaders.insert(tempKey); - if (fromDisk) { - qCInfo(TRACE_INFO) << "Loading from persistent shader cache: '<" - << tempKey.m_Key << ">'"; - } else { - qCInfo(TRACE_INFO) << "Compiling into shader cache: '" - << tempKey.m_Key << ">'"; - } - - if (!inVert) - inVert = ""; - if (!inTessCtrl) - inTessCtrl = ""; - if (!inTessEval) - inTessEval = ""; - if (!inGeom) - inGeom = ""; - if (!inFrag) - inFrag = ""; - - SStackPerfTimer __perfTimer(m_PerfTimer, "Shader Compilation"); - m_VertexCode.assign(inVert); - m_TessCtrlCode.assign(inTessCtrl); - m_TessEvalCode.assign(inTessEval); - m_GeometryCode.assign(inGeom); - m_FragmentCode.assign(inFrag); - // Add defines and such so we can write unified shaders that work across platforms. - // vertex and fragment shaders are optional for separable shaders - if (!separableProgram || !m_VertexCode.empty()) - AddShaderPreprocessor(m_VertexCode, inKey, ShaderType::Vertex, inFeatures); - if (!separableProgram || !m_FragmentCode.empty()) - AddShaderPreprocessor(m_FragmentCode, inKey, ShaderType::Fragment, inFeatures); - // optional shaders - if (inFlags.IsTessellationEnabled()) { - QT3DS_ASSERT(m_TessCtrlCode.size() && m_TessEvalCode.size()); - AddShaderPreprocessor(m_TessCtrlCode, inKey, ShaderType::TessControl, inFeatures); - AddShaderPreprocessor(m_TessEvalCode, inKey, ShaderType::TessEval, inFeatures); - } - if (inFlags.IsGeometryShaderEnabled()) - AddShaderPreprocessor(m_GeometryCode, inKey, ShaderType::Geometry, inFeatures); - - theInserter.first->second = - m_RenderContext - .CompileSource(inKey, m_VertexCode.c_str(), QT3DSU32(m_VertexCode.size()), - m_FragmentCode.c_str(), QT3DSU32(m_FragmentCode.size()), - m_TessCtrlCode.c_str(), QT3DSU32(m_TessCtrlCode.size()), - m_TessEvalCode.c_str(), QT3DSU32(m_TessEvalCode.size()), - m_GeometryCode.c_str(), QT3DSU32(m_GeometryCode.size()), - separableProgram).mShader; - if (theInserter.first->second) { - if (m_ShaderCache) { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "Program"); - m_ShaderCache->Att("key", inKey.c_str()); - CacheFlagsToStr(inFlags, m_FlagString); - if (m_FlagString.size()) - m_ShaderCache->Att("glflags", m_FlagString.c_str()); - // write out the GL version. - { - qt3ds::render::NVRenderContextType theContextType = - m_RenderContext.GetRenderContextType(); - ContextTypeToString(theContextType, m_ContextTypeString); - m_ShaderCache->Att("gl-context-type", m_ContextTypeString.c_str()); - } - if (inFeatures.size()) { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "Features"); - for (QT3DSU32 idx = 0, end = inFeatures.size(); idx < end; ++idx) { - m_ShaderCache->Att(inFeatures[idx].m_Name, inFeatures[idx].m_Enabled); - } - } - - { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "VertexCode"); - m_ShaderCache->Value(inVert); - } - { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "FragmentCode"); - m_ShaderCache->Value(inFrag); - } - if (m_TessCtrlCode.size()) { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "TessControlCode"); - m_ShaderCache->Value(inTessCtrl); - } - if (m_TessEvalCode.size()) { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "TessEvalCode"); - m_ShaderCache->Value(inTessEval); - } - if (m_GeometryCode.size()) { - IDOMWriter::Scope __writeScope(*m_ShaderCache, "GeometryCode"); - m_ShaderCache->Value(inGeom); - } - } - } - return theInserter.first->second; - } - - virtual NVRenderShaderProgram * - CompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, - const char8_t *inTessCtrl, const char8_t *inTessEval, const char8_t *inGeom, - const SShaderCacheProgramFlags &inFlags, - NVConstDataRef inFeatures, bool separableProgram) override - { - NVRenderShaderProgram *theProgram = GetProgram(inKey, inFeatures); - if (theProgram) - return theProgram; - - NVRenderShaderProgram *retval = - ForceCompileProgram(inKey, inVert, inFrag, inTessCtrl, inTessEval, inGeom, inFlags, - inFeatures, separableProgram); - if (m_CacheFilePath.c_str() && m_ShaderCache && m_ShaderCompilationEnabled) { - CFileSeekableIOStream theStream(m_CacheFilePath.c_str(), FileWriteFlags()); - if (theStream.IsOpen()) { - NVScopedRefCounted theStringTable( - IStringTable::CreateStringTable(m_RenderContext.GetAllocator())); - CDOMSerializer::WriteXMLHeader(theStream); - CDOMSerializer::Write(m_RenderContext.GetAllocator(), - *m_ShaderCache->GetTopElement(), theStream, *theStringTable); - } - } - return retval; - } - - void BootupDOMWriter() - { - NVScopedRefCounted theStringTable( - IStringTable::CreateStringTable(m_RenderContext.GetAllocator())); - m_ShaderCache = IDOMWriter::CreateDOMWriter(m_RenderContext.GetAllocator(), - "Qt3DSShaderCache", theStringTable) - .first; - m_ShaderCache->Att("cache_version", IShaderCache::GetShaderVersion()); - } - - void SetShaderCachePersistenceEnabled(const char8_t *inDirectory) override - { - if (inDirectory == NULL) { - m_ShaderCache = NULL; - return; - } - BootupDOMWriter(); - m_CacheFilePath = QDir(inDirectory).filePath(GetShaderCacheFileName()).toStdString(); - - NVScopedRefCounted theInStream = - m_InputStreamFactory.GetStreamForFile(m_CacheFilePath.c_str()); - if (theInStream) { - SStackPerfTimer __perfTimer(m_PerfTimer, "ShaderCache - Load"); - NVScopedRefCounted theStringTable( - IStringTable::CreateStringTable(m_RenderContext.GetAllocator())); - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_RenderContext.GetAllocator(), theStringTable)); - eastl::vector theFeatures; - - SDOMElement *theElem = CDOMSerializer::Read(*theFactory, *theInStream).second; - if (theElem) { - NVScopedRefCounted theReader = IDOMReader::CreateDOMReader( - m_RenderContext.GetAllocator(), *theElem, theStringTable, theFactory); - QT3DSU32 theAttValue = 0; - theReader->Att("cache_version", theAttValue); - if (theAttValue == IShaderCache::GetShaderVersion()) { - CRenderString loadVertexData; - CRenderString loadFragmentData; - CRenderString loadTessControlData; - CRenderString loadTessEvalData; - CRenderString loadGeometryData; - CRenderString shaderTypeString; - IStringTable &theStringTable(m_RenderContext.GetStringTable()); - for (bool success = theReader->MoveToFirstChild(); success; - success = theReader->MoveToNextSibling()) { - const char8_t *theKeyStr = NULL; - theReader->UnregisteredAtt("key", theKeyStr); - - CRegisteredString theKey = theStringTable.RegisterStr(theKeyStr); - if (theKey.IsValid()) { - m_FlagString.clear(); - const char8_t *theFlagStr = ""; - SShaderCacheProgramFlags theFlags; - if (theReader->UnregisteredAtt("glflags", theFlagStr)) { - m_FlagString.assign(theFlagStr); - theFlags = CacheFlagsToStr(m_FlagString); - } - - m_ContextTypeString.clear(); - if (theReader->UnregisteredAtt("gl-context-type", theFlagStr)) - m_ContextTypeString.assign(theFlagStr); - - theFeatures.clear(); - { - IDOMReader::Scope __featureScope(*theReader); - if (theReader->MoveToFirstChild("Features")) { - for (SDOMAttribute *theAttribute = - theReader->GetFirstAttribute(); - theAttribute; - theAttribute = theAttribute->m_NextAttribute) { - bool featureValue = false; - StringConversion().StrTo(theAttribute->m_Value, - featureValue); - theFeatures.push_back(SShaderPreprocessorFeature( - theStringTable.RegisterStr( - theAttribute->m_Name.c_str()), - featureValue)); - } - } - } - - qt3ds::render::NVRenderContextType theContextType = - StringToContextType(m_ContextTypeString); - if (((QT3DSU32)theContextType != 0) - && (theContextType & m_RenderContext.GetRenderContextType()) - == theContextType) { - IDOMReader::Scope __readerScope(*theReader); - loadVertexData.clear(); - loadFragmentData.clear(); - loadTessControlData.clear(); - loadTessEvalData.clear(); - loadGeometryData.clear(); - - // Vertex *MUST* be the first - // Todo deal with pure compute shader programs - if (theReader->MoveToFirstChild("VertexCode")) { - const char8_t *theValue = NULL; - theReader->Value(theValue); - loadVertexData.assign(theValue); - while (theReader->MoveToNextSibling()) { - theReader->Value(theValue); - - shaderTypeString.assign( - theReader->GetElementName().c_str()); - ShaderType::Enum shaderType = - StringToShaderType(shaderTypeString); - - if (shaderType == ShaderType::Fragment) - loadFragmentData.assign(theValue); - else if (shaderType == ShaderType::TessControl) - loadTessControlData.assign(theValue); - else if (shaderType == ShaderType::TessEval) - loadTessEvalData.assign(theValue); - else if (shaderType == ShaderType::Geometry) - loadGeometryData.assign(theValue); - } - } - - if (loadVertexData.size() - && (loadFragmentData.size() || loadGeometryData.size())) { - - NVRenderShaderProgram *theShader = ForceCompileProgram( - theKey, loadVertexData.c_str(), loadFragmentData.c_str(), - loadTessControlData.c_str(), loadTessEvalData.c_str(), - loadGeometryData.c_str(), theFlags, - qt3ds::foundation::toDataRef(theFeatures.data(), - (QT3DSU32)theFeatures.size()), - false, true /*fromDisk*/); - // If something doesn't save or load correctly, get the runtime - // to re-generate. - if (!theShader) - m_Shaders.erase(theKey); - } - } - } - } - } - } - } - } - - bool IsShaderCachePersistenceEnabled() const override { return m_ShaderCache != NULL; } - - void SetShaderCompilationEnabled(bool inEnableShaderCompilation) override - { - m_ShaderCompilationEnabled = inEnableShaderCompilation; - } -}; -} - -size_t qt3ds::render::HashShaderFeatureSet(NVConstDataRef inFeatureSet) -{ - size_t retval(0); - for (QT3DSU32 idx = 0, end = inFeatureSet.size(); idx < end; ++idx) { - // From previous implementation, it seems we need to ignore the order of the features. - // But we need to bind the feature flag together with its name, so that the flags will - // influence - // the final hash not only by the true-value count. - retval = retval - ^ (inFeatureSet[idx].m_Name.hash() * eastl::hash()(inFeatureSet[idx].m_Enabled)); - } - return retval; -} - -bool SShaderPreprocessorFeature::operator<(const SShaderPreprocessorFeature &other) const -{ - return strcmp(m_Name.c_str(), other.m_Name.c_str()) < 0; -} - -bool SShaderPreprocessorFeature::operator==(const SShaderPreprocessorFeature &other) const -{ - return m_Name == other.m_Name && m_Enabled == other.m_Enabled; -} - -IShaderCache &IShaderCache::CreateShaderCache(NVRenderContext &inContext, - IInputStreamFactory &inInputStreamFactory, - IPerfTimer &inPerfTimer) -{ - return *QT3DS_NEW(inContext.GetAllocator(), ShaderCache)(inContext, inInputStreamFactory, - inPerfTimer); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGenerator.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGenerator.cpp deleted file mode 100644 index 1cc9e9c7..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGenerator.cpp +++ /dev/null @@ -1,526 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderShaderCodeGenerator.h" - -using namespace qt3ds::render; - -using eastl::make_pair; - -SShaderCodeGeneratorBase::SShaderCodeGeneratorBase(IStringTable &inStringTable, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType) - : m_StringTable(inStringTable) - , m_Codes(alloc, "SShaderCodeGenerator::m_Codes") - , m_Includes(alloc, "SShaderCodeGenerator::m_Includes") - , m_Uniforms(alloc, "SShaderCodeGenerator::m_Uniforms") - , m_ConstantBuffers(alloc, "SShaderCodeGenerator::m_ConstantBuffers") - , m_ConstantBufferParams(alloc, "SShaderCodeGenerator::m_ConstantBufferParams") - , m_Attributes(alloc, "SShaderCodeGenerator::m_Uniforms") - , m_RenderContextType(ctxType) -{ -} -void SShaderCodeGeneratorBase::Begin() -{ - m_Uniforms.clear(); - GetVaryings().clear(); - m_Attributes.clear(); - m_Includes.clear(); - m_Codes.clear(); - m_FinalShaderBuilder.clear(); - m_CodeBuilder.clear(); - m_ConstantBuffers.clear(); - m_ConstantBufferParams.clear(); -} -void SShaderCodeGeneratorBase::Append(const char *data) -{ - m_CodeBuilder.append(data); - m_CodeBuilder.append("\n"); -} -// don't add the newline -void SShaderCodeGeneratorBase::AppendPartial(const char *data) -{ - m_CodeBuilder.append(data); -} -void SShaderCodeGeneratorBase::AddUniform(const char *name, const char *type) -{ - m_Uniforms.insert(make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(type))); -} -void SShaderCodeGeneratorBase::AddUniform(TStrType &name, const char *type) -{ - AddUniform(name.c_str(), type); -} - -void SShaderCodeGeneratorBase::AddConstantBuffer(const char *name, const char *layout) -{ - m_ConstantBuffers.insert( - make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(layout))); -} -void SShaderCodeGeneratorBase::AddConstantBufferParam(const char *cbName, const char *paramName, - const char *type) -{ - TParamPair theParamPair(m_StringTable.RegisterStr(paramName), m_StringTable.RegisterStr(type)); - TConstantBufferParamPair theBufferParamPair(m_StringTable.RegisterStr(cbName), theParamPair); - m_ConstantBufferParams.push_back(theBufferParamPair); -} -void SShaderCodeGeneratorBase::AddAttribute(const char *name, const char *type) -{ - m_Attributes.insert( - make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(type))); -} -void SShaderCodeGeneratorBase::AddAttribute(TStrType &name, const char *type) -{ - AddAttribute(name.c_str(), type); -} -void SShaderCodeGeneratorBase::AddVarying(const char *name, const char *type) -{ - GetVaryings().insert( - make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(type))); -} -void SShaderCodeGeneratorBase::AddVarying(TStrType &name, const char *type) -{ - AddVarying(name.c_str(), type); -} -void SShaderCodeGeneratorBase::AddLocalVariable(const char *name, const char *type, int tabCount) -{ - for (; tabCount >= 0; --tabCount) - m_CodeBuilder.append("\t"); - m_CodeBuilder.append(type); - m_CodeBuilder.append(" "); - m_CodeBuilder.append(name); - m_CodeBuilder.append(";\n"); -} - -void SShaderCodeGeneratorBase::AddInclude(const char *name) -{ - m_Includes.insert(m_StringTable.RegisterStr(name)); -} -void SShaderCodeGeneratorBase::AddInclude(TStrType &name) -{ - AddInclude(name.c_str()); -} -void SShaderCodeGeneratorBase::AddLocalVariable(TStrType &name, const char *type, int tabCount) -{ - AddLocalVariable(name.c_str(), type, tabCount); -} -bool SShaderCodeGeneratorBase::HasCode(Enum value) -{ - return m_Codes.contains(value); -} -void SShaderCodeGeneratorBase::SetCode(Enum value) -{ - m_Codes.insert((QT3DSU32)value); -} - -void SShaderCodeGeneratorBase::SetupWorldPosition() -{ - if (!HasCode(WorldPosition)) { - SetCode(WorldPosition); - AddUniform("model_matrix", "mat4"); - Append("\tvec3 varWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); - } -} - -void SShaderCodeGeneratorBase::GenerateViewVector() -{ - if (!HasCode(ViewVector)) { - SetCode(ViewVector); - SetupWorldPosition(); - AddInclude("viewProperties.glsllib"); - Append("\tvec3 view_vector = normalize(camera_position - varWorldPos);"); - } -} - -void SShaderCodeGeneratorBase::GenerateWorldNormal() -{ - if (!HasCode(WorldNormal)) { - SetCode(WorldNormal); - AddAttribute("attr_norm", "vec3"); - AddUniform("normal_matrix", "mat3"); - Append("\tvec3 world_normal = normalize(normal_matrix * objectNormal).xyz;"); - } -} - -void SShaderCodeGeneratorBase::GenerateEnvMapReflection(SShaderCodeGeneratorBase &inFragmentShader) -{ - if (!HasCode(EnvMapReflection)) { - SetCode(EnvMapReflection); - SetupWorldPosition(); - GenerateWorldNormal(); - AddInclude("viewProperties.glsllib"); - AddVarying("var_object_to_camera", "vec3"); - Append("\tvar_object_to_camera = normalize( varWorldPos - camera_position );"); - // World normal cannot be relied upon in the vertex shader because of bump maps. - inFragmentShader.Append("\tvec3 environment_map_reflection = reflect( " - "vec3(var_object_to_camera.x, var_object_to_camera.y, " - "var_object_to_camera.z), world_normal.xyz );"); - inFragmentShader.Append("\tenvironment_map_reflection *= vec3( 0.5, 0.5, 0 );"); - inFragmentShader.Append("\tenvironment_map_reflection += vec3( 0.5, 0.5, 1.0 );"); - } -} - -void SShaderCodeGeneratorBase::GenerateUVCoords() -{ - if (!HasCode(UVCoords)) { - SetCode(UVCoords); - AddAttribute("attr_uv0", "vec2"); - Append("\tvec2 uv_coords = attr_uv0;"); - } -} - -void SShaderCodeGeneratorBase::GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, - eastl::basic_string &texSwizzle, - eastl::basic_string &lookupSwizzle) -{ - qt3ds::render::NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - - if (!(m_RenderContextType & deprecatedContextFlags)) { - switch (swizzleMode) { - case NVRenderTextureSwizzleMode::L8toR8: - case NVRenderTextureSwizzleMode::L16toR16: - texSwizzle.append(".rgb"); - lookupSwizzle.append(".rrr"); - break; - case NVRenderTextureSwizzleMode::L8A8toRG8: - texSwizzle.append(".rgba"); - lookupSwizzle.append(".rrrg"); - break; - case NVRenderTextureSwizzleMode::A8toR8: - texSwizzle.append(".a"); - lookupSwizzle.append(".r"); - break; - default: - break; - } - } -} - -void SShaderCodeGeneratorBase::GenerateShadedWireframeBase() -{ - // how this all work see - // http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf - Append("// project points to screen space\n" - "\tvec3 p0 = vec3(viewport_matrix * (gl_in[0].gl_Position / gl_in[0].gl_Position.w));\n" - "\tvec3 p1 = vec3(viewport_matrix * (gl_in[1].gl_Position / gl_in[1].gl_Position.w));\n" - "\tvec3 p2 = vec3(viewport_matrix * (gl_in[2].gl_Position / gl_in[2].gl_Position.w));\n" - "// compute triangle heights\n" - "\tfloat e1 = length(p1 - p2);\n" - "\tfloat e2 = length(p2 - p0);\n" - "\tfloat e3 = length(p1 - p0);\n" - "\tfloat alpha = acos( (e2*e2 + e3*e3 - e1*e1) / (2.0*e2*e3) );\n" - "\tfloat beta = acos( (e1*e1 + e3*e3 - e2*e2) / (2.0*e1*e3) );\n" - "\tfloat ha = abs( e3 * sin( beta ) );\n" - "\tfloat hb = abs( e3 * sin( alpha ) );\n" - "\tfloat hc = abs( e2 * sin( alpha ) );\n"); -} - -void SShaderCodeGeneratorBase::AddShaderItemMap(const char *itemType, - const TStrTableStrMap &itemMap) -{ - m_FinalShaderBuilder.append("\n"); - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; - ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(";\n"); - } -} - -void SShaderCodeGeneratorBase::AddShaderConstantBufferItemMap( - const char *itemType, const TStrTableStrMap &cbMap, TConstantBufferParamArray cbParamsArray) -{ - m_FinalShaderBuilder.append("\n"); - - // iterate over all constant buffers - for (TStrTableStrMap::const_iterator iter = cbMap.begin(), end = cbMap.end(); iter != end; - ++iter) { - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(" {\n"); - // iterate over all param entries and add match - for (TConstantBufferParamArray::const_iterator iter1 = cbParamsArray.begin(), - end = cbParamsArray.end(); - iter1 != end; ++iter1) { - if (iter1->first == iter->first) { - m_FinalShaderBuilder.append(iter1->second.second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter1->second.first); - m_FinalShaderBuilder.append(";\n"); - } - } - - m_FinalShaderBuilder.append("};\n"); - } -} - -const char *SShaderCodeGeneratorBase::BuildShaderSource() -{ - for (nvhash_set::const_iterator iter = m_Includes.begin(), - end = m_Includes.end(); - iter != end; ++iter) { - m_FinalShaderBuilder.append("#include \""); - m_FinalShaderBuilder.append(iter->c_str()); - m_FinalShaderBuilder.append("\"\n"); - } - AddShaderItemMap("attribute", m_Attributes); - AddShaderItemMap("uniform", m_Uniforms); - AddShaderConstantBufferItemMap("uniform", m_ConstantBuffers, m_ConstantBufferParams); - AddShaderItemMap("varying", GetVaryings()); - m_FinalShaderBuilder.append("\n"); - m_FinalShaderBuilder.append(m_CodeBuilder); - return m_FinalShaderBuilder.c_str(); -} -SShaderCodeGeneratorBase &SShaderCodeGeneratorBase::operator<<(const char *data) -{ - m_CodeBuilder.append(data); - return *this; -} -SShaderCodeGeneratorBase &SShaderCodeGeneratorBase::operator<<(const TStrType &data) -{ - m_CodeBuilder.append(data); - return *this; -} - -SShaderCodeGeneratorBase &SShaderCodeGeneratorBase::operator<<(const SEndlType & /*data*/) -{ - m_CodeBuilder.append("\n"); - return *this; -} - -SShaderVertexCodeGenerator::SShaderVertexCodeGenerator(IStringTable &inStringTable, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType) - : SShaderCodeGeneratorBase(inStringTable, alloc, ctxType) - , m_Varyings(alloc, "SShaderVertexCodeGenerator::m_Varyings") -{ -} -TStrTableStrMap &SShaderVertexCodeGenerator::GetVaryings() -{ - return m_Varyings; -} - -SShaderTessControlCodeGenerator::SShaderTessControlCodeGenerator( - SShaderVertexCodeGenerator &vert, NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType) - : SShaderCodeGeneratorBase(vert.m_StringTable, alloc, ctxType) - , m_VertGenerator(vert) - , m_Varyings(alloc, "SShaderTessControlCodeGenerator::m_Varyings") -{ -} - -// overwritten from base -void SShaderTessControlCodeGenerator::AddShaderItemMap(const char *itemType, - const TStrTableStrMap &itemMap) -{ - eastl::string extVtx(""); - eastl::string extTC(""); - eastl::string type(itemType); - if (!type.compare("varying")) { - extVtx = "[]"; - extTC = "TC[]"; - itemType = "attribute"; - } - - m_FinalShaderBuilder.append("\n"); - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; - ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(extVtx.c_str()); - m_FinalShaderBuilder.append(";\n"); - } - - // if this is varyings write output of tess control shader - if (!extVtx.empty()) { - m_FinalShaderBuilder.append("\n"); - itemType = "varying"; - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); - iter != end; ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(extTC.c_str()); - m_FinalShaderBuilder.append(";\n"); - } - } -} -TStrTableStrMap &SShaderTessControlCodeGenerator::GetVaryings() -{ - return m_VertGenerator.m_Varyings; -} - -SShaderTessEvalCodeGenerator::SShaderTessEvalCodeGenerator(SShaderTessControlCodeGenerator &tc, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType) - : SShaderCodeGeneratorBase(tc.m_StringTable, alloc, ctxType) - , m_TessControlGenerator(tc) - , m_hasGeometryStage(false) -{ -} -// overwritten from base -void SShaderTessEvalCodeGenerator::AddShaderItemMap(const char *itemType, - const TStrTableStrMap &itemMap) -{ - eastl::string extTC(""); - eastl::string extTE(""); - eastl::string type(itemType); - if (!type.compare("varying")) { - extTC = "TC[]"; - itemType = "attribute"; - } - if (m_hasGeometryStage) { - extTE = "TE"; - } - - m_FinalShaderBuilder.append("\n"); - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; - ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(extTC.c_str()); - m_FinalShaderBuilder.append(";\n"); - } - - // if this are varyings write output of tess eval shader - if (!extTC.empty()) { - m_FinalShaderBuilder.append("\n"); - itemType = "varying"; - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); - iter != end; ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(extTE.c_str()); - m_FinalShaderBuilder.append(";\n"); - } - } -} -TStrTableStrMap &SShaderTessEvalCodeGenerator::GetVaryings() -{ - return m_TessControlGenerator.m_VertGenerator.GetVaryings(); -} -void SShaderTessEvalCodeGenerator::SetGeometryStage(bool hasGeometryStage) -{ - m_hasGeometryStage = hasGeometryStage; -} - -SShaderGeometryCodeGenerator::SShaderGeometryCodeGenerator(SShaderVertexCodeGenerator &vert, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType) - : SShaderCodeGeneratorBase(vert.m_StringTable, alloc, ctxType) - , m_VertGenerator(vert) - , m_hasTessellationStage(true) -{ -} - -// overwritten from base -void SShaderGeometryCodeGenerator::AddShaderItemMap(const char *itemType, - const TStrTableStrMap &itemMap) -{ - eastl::string inExt(""); - eastl::string type(itemType); - if (!type.compare("varying")) { - itemType = "attribute"; - if (m_hasTessellationStage) - inExt = "TE[]"; - else - inExt = "[]"; - } - - m_FinalShaderBuilder.append("\n"); - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; - ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(inExt.c_str()); - m_FinalShaderBuilder.append(";\n"); - } - - // if this are varyings write output of geometry shader - if (!type.compare("varying")) { - m_FinalShaderBuilder.append("\n"); - itemType = "varying"; - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); - iter != end; ++iter) { - m_FinalShaderBuilder.append(itemType); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->second); - m_FinalShaderBuilder.append(" "); - m_FinalShaderBuilder.append(iter->first); - m_FinalShaderBuilder.append(";\n"); - } - } -} -TStrTableStrMap &SShaderGeometryCodeGenerator::GetVaryings() -{ - return m_VertGenerator.m_Varyings; -} -void SShaderGeometryCodeGenerator::SetTessellationStage(bool hasTessellationStage) -{ - m_hasTessellationStage = hasTessellationStage; -} - -SShaderFragmentCodeGenerator::SShaderFragmentCodeGenerator(SShaderVertexCodeGenerator &vert, - NVAllocatorCallback &alloc, - qt3ds::render::NVRenderContextType ctxType) - : SShaderCodeGeneratorBase(vert.m_StringTable, alloc, ctxType) - , m_VertGenerator(vert) -{ -} -TStrTableStrMap &SShaderFragmentCodeGenerator::GetVaryings() -{ - return m_VertGenerator.m_Varyings; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGeneratorV2.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGeneratorV2.cpp deleted file mode 100644 index 173ba431..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShaderCodeGeneratorV2.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Utils.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderDynamicObjectSystem.h" - -#include - -using namespace qt3ds::render; - -namespace { -struct SStageGeneratorBase : public IShaderStageGenerator -{ - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - TStrTableStrMap m_Incoming; - TStrTableStrMap *m_Outgoing; - nvhash_set m_Includes; - TStrTableStrMap m_Uniforms; - TStrTableStrMap m_ConstantBuffers; - TConstantBufferParamArray m_ConstantBufferParams; - CRenderString m_CodeBuilder; - CRenderString m_FinalBuilder; - ShaderGeneratorStages::Enum m_Stage; - TShaderGeneratorStageFlags m_EnabledStages; - QStringList m_addedFunctions; - - SStageGeneratorBase(NVFoundationBase &inFnd, IStringTable &strTable, - ShaderGeneratorStages::Enum inStage) - - : m_Foundation(inFnd) - , m_StringTable(strTable) - , m_Incoming(inFnd.getAllocator(), "m_Incoming") - , m_Outgoing(NULL) - , m_Includes(inFnd.getAllocator(), "m_Includes") - , m_Uniforms(inFnd.getAllocator(), "m_Uniforms") - , m_ConstantBuffers(inFnd.getAllocator(), "m_ConstantBuffers") - , m_ConstantBufferParams(inFnd.getAllocator(), "m_ConstantBufferParams") - , m_Stage(inStage) - { - } - - virtual void Begin(TShaderGeneratorStageFlags inEnabledStages) - { - m_Incoming.clear(); - m_Outgoing = NULL; - m_Includes.clear(); - m_Uniforms.clear(); - m_ConstantBuffers.clear(); - m_ConstantBufferParams.clear(); - m_CodeBuilder.clear(); - m_FinalBuilder.clear(); - m_EnabledStages = inEnabledStages; - m_addedFunctions.clear(); - // the shared buffers will be cleared elsewhere. - } - - CRegisteredString Str(const char8_t *var) { return m_StringTable.RegisterStr(var); } - - void AddIncoming(const char8_t *name, const char8_t *type) override - { - m_Incoming.insert(eastl::make_pair(Str(name), Str(type))); - } - virtual const char8_t *GetIncomingVariableName() - { - return "in"; - } - - void AddIncoming(const TStrType &name, const char8_t *type) override - { - AddIncoming(name.c_str(), type); - } - void AddOutgoing(const char8_t *name, const char8_t *type) override - { - if (m_Outgoing == NULL) { - QT3DS_ASSERT(false); - return; - } - m_Outgoing->insert(eastl::make_pair(Str(name), Str(type))); - } - void AddOutgoing(const TStrType &name, const char8_t *type) override - { - AddOutgoing(name.c_str(), type); - } - - void AddUniform(const char8_t *name, const char8_t *type) override - { - m_Uniforms.insert(eastl::make_pair(Str(name), Str(type))); - } - void AddUniform(const TStrType &name, const char8_t *type) override - { - AddUniform(name.c_str(), type); - } - - void AddConstantBuffer(const char *name, const char *layout) override - { - m_ConstantBuffers.insert(eastl::make_pair(Str(name), Str(layout))); - } - void AddConstantBufferParam(const char *cbName, const char *paramName, const char *type) override - { - TParamPair theParamPair(m_StringTable.RegisterStr(paramName), - m_StringTable.RegisterStr(type)); - TConstantBufferParamPair theBufferParamPair(m_StringTable.RegisterStr(cbName), - theParamPair); - m_ConstantBufferParams.push_back(theBufferParamPair); - } - - IShaderStageGenerator &operator<<(const char *data) override - { - m_CodeBuilder.append(nonNull(data)); - return *this; - } - IShaderStageGenerator &operator<<(const TStrType &data) override - { - m_CodeBuilder.append(data); - return *this; - } - IShaderStageGenerator &operator<<(const SEndlType & /*data*/) override - { - m_CodeBuilder.append("\n"); - return *this; - } - void Append(const char *data) override - { - m_CodeBuilder.append(nonNull(data)); - m_CodeBuilder.append("\n"); - } - void AppendPartial(const char *data) override { m_CodeBuilder.append(nonNull(data)); } - ShaderGeneratorStages::Enum Stage() const override { return m_Stage; } - - virtual void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap, - const char8_t *inItemSuffix = "") - { - m_FinalBuilder.append("\n"); - - for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); - iter != end; ++iter) { - m_FinalBuilder.append(itemType); - m_FinalBuilder.append(" "); - m_FinalBuilder.append(iter->second); - m_FinalBuilder.append(" "); - m_FinalBuilder.append(iter->first); - m_FinalBuilder.append(inItemSuffix); - m_FinalBuilder.append(";\n"); - } - } - - virtual void AddShaderIncomingMap() { AddShaderItemMap(GetIncomingVariableName(), m_Incoming); } - - virtual void AddShaderUniformMap() { AddShaderItemMap("uniform", m_Uniforms); } - - virtual void AddShaderOutgoingMap() - { - if (m_Outgoing) - AddShaderItemMap("varying", *m_Outgoing); - } - - virtual void AddShaderConstantBufferItemMap(const char *itemType, const TStrTableStrMap &cbMap, - TConstantBufferParamArray cbParamsArray) - { - m_FinalBuilder.append("\n"); - - // iterate over all constant buffers - for (TStrTableStrMap::const_iterator iter = cbMap.begin(), end = cbMap.end(); iter != end; - ++iter) { - m_FinalBuilder.append(iter->second); - m_FinalBuilder.append(" "); - m_FinalBuilder.append(itemType); - m_FinalBuilder.append(" "); - m_FinalBuilder.append(iter->first); - m_FinalBuilder.append(" {\n"); - // iterate over all param entries and add match - for (TConstantBufferParamArray::const_iterator iter1 = cbParamsArray.begin(), - end = cbParamsArray.end(); - iter1 != end; ++iter1) { - if (iter1->first == iter->first) { - m_FinalBuilder.append(iter1->second.second); - m_FinalBuilder.append(" "); - m_FinalBuilder.append(iter1->second.first); - m_FinalBuilder.append(";\n"); - } - } - - m_FinalBuilder.append("};\n"); - } - } - - virtual void AppendShaderCode() { m_FinalBuilder.append(m_CodeBuilder); } - - virtual void UpdateShaderCacheFlags(SShaderCacheProgramFlags &) {} - - void AddInclude(const char8_t *name) override { m_Includes.insert(Str(name)); } - - void AddInclude(const TStrType &name) override { AddInclude(name.c_str()); } - - void AddInclude(const QString &name) override - { - QByteArray arr = name.toLatin1(); - AddInclude(arr.data()); - } - - virtual const char8_t *BuildShaderSource() - { - for (nvhash_set::const_iterator iter = m_Includes.begin(), - end = m_Includes.end(); - iter != end; ++iter) { - m_FinalBuilder.append("#include \""); - m_FinalBuilder.append(iter->c_str()); - m_FinalBuilder.append("\"\n"); - } - AddShaderIncomingMap(); - AddShaderUniformMap(); - AddShaderConstantBufferItemMap("uniform", m_ConstantBuffers, m_ConstantBufferParams); - AddShaderOutgoingMap(); - m_FinalBuilder.append("\n"); - AppendShaderCode(); - return m_FinalBuilder.c_str(); - } - - void AddFunction(const QString &functionName) override - { - if (!m_addedFunctions.contains(functionName)) { - m_addedFunctions.push_back(functionName); - QString includeName; - QTextStream stream(&includeName); - stream << "func" << functionName << ".glsllib"; - AddInclude(includeName); - } - } -}; - -struct SVertexShaderGenerator : public SStageGeneratorBase -{ - SVertexShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) - : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Vertex) - { - } - - const char8_t *GetIncomingVariableName() override { return "attribute"; } - virtual void AddIncomingInterpolatedMap() {} - - virtual const char8_t *GetInterpolatedIncomingSuffix() const { return "_attr"; } - virtual const char8_t *GetInterpolatedOutgoingSuffix() const { return ""; } -}; - -struct STessControlShaderGenerator : public SStageGeneratorBase -{ - STessControlShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) - : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::TessControl) - { - } - - void AddShaderIncomingMap() override { AddShaderItemMap("attribute", m_Incoming, "[]"); } - - void AddShaderOutgoingMap() override - { - if (m_Outgoing) - AddShaderItemMap("varying", *m_Outgoing, "[]"); - } - - void UpdateShaderCacheFlags(SShaderCacheProgramFlags &inFlags) override - { - inFlags.SetTessellationEnabled(true); - } -}; - -struct STessEvalShaderGenerator : public SStageGeneratorBase -{ - STessEvalShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) - : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::TessEval) - { - } - - void AddShaderIncomingMap() override { AddShaderItemMap("attribute", m_Incoming, "[]"); } - - void UpdateShaderCacheFlags(SShaderCacheProgramFlags &inFlags) override - { - inFlags.SetTessellationEnabled(true); - } -}; - -struct SGeometryShaderGenerator : public SStageGeneratorBase -{ - SGeometryShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) - : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Geometry) - { - } - - void AddShaderIncomingMap() override { AddShaderItemMap("attribute", m_Incoming, "[]"); } - - void AddShaderOutgoingMap() override - { - if (m_Outgoing) - AddShaderItemMap("varying", *m_Outgoing); - } - void UpdateShaderCacheFlags(SShaderCacheProgramFlags &inFlags) override - { - inFlags.SetGeometryShaderEnabled(true); - } -}; - -struct SFragmentShaderGenerator : public SStageGeneratorBase -{ - SFragmentShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) - : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Fragment) - { - } - void AddShaderIncomingMap() override { AddShaderItemMap("varying", m_Incoming); } - void AddShaderOutgoingMap() override {} -}; - -struct SShaderGeneratedProgramOutput -{ - // never null; so safe to call strlen on. - const char8_t *m_VertexShader; - const char8_t *m_TessControlShader; - const char8_t *m_TessEvalShader; - const char8_t *m_GeometryShader; - const char8_t *m_FragmentShader; - - SShaderGeneratedProgramOutput() - : m_VertexShader("") - , m_TessControlShader("") - , m_TessEvalShader("") - , m_GeometryShader("") - , m_FragmentShader("") - { - } - - SShaderGeneratedProgramOutput(const char8_t *vs, const char8_t *tc, const char8_t *te, - const char8_t *gs, const char8_t *fs) - : m_VertexShader(vs) - , m_TessControlShader(tc) - , m_TessEvalShader(te) - , m_GeometryShader(gs) - , m_FragmentShader(fs) - { - } -}; - -struct SProgramGenerator : public IShaderProgramGenerator -{ - IQt3DSRenderContext &m_Context; - SVertexShaderGenerator m_VS; - STessControlShaderGenerator m_TC; - STessEvalShaderGenerator m_TE; - SGeometryShaderGenerator m_GS; - SFragmentShaderGenerator m_FS; - - TShaderGeneratorStageFlags m_EnabledStages; - - QT3DSI32 m_RefCount; - - SProgramGenerator(IQt3DSRenderContext &inContext) - : m_Context(inContext) - , m_VS(inContext.GetFoundation(), inContext.GetStringTable()) - , m_TC(inContext.GetFoundation(), inContext.GetStringTable()) - , m_TE(inContext.GetFoundation(), inContext.GetStringTable()) - , m_GS(inContext.GetFoundation(), inContext.GetStringTable()) - , m_FS(inContext.GetFoundation(), inContext.GetStringTable()) - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVFoundationBase &theFoundation(m_Context.GetFoundation()); - NVDelete(theFoundation.getAllocator(), this); - } - } - - void LinkStages() - { - // Link stages incoming to outgoing variables. - SStageGeneratorBase *previous = NULL; - QT3DSU32 theStageId = 1; - for (QT3DSU32 idx = 0, end = (QT3DSU32)ShaderGeneratorStages::StageCount; idx < end; - ++idx, theStageId = theStageId << 1) { - SStageGeneratorBase *thisStage = NULL; - ShaderGeneratorStages::Enum theStageEnum = - static_cast(theStageId); - if ((m_EnabledStages & theStageEnum)) { - thisStage = &InternalGetStage(theStageEnum); - if (previous) - previous->m_Outgoing = &thisStage->m_Incoming; - previous = thisStage; - } - } - } - - void BeginProgram(TShaderGeneratorStageFlags inEnabledStages) override - { - m_VS.Begin(inEnabledStages); - m_TC.Begin(inEnabledStages); - m_TE.Begin(inEnabledStages); - m_GS.Begin(inEnabledStages); - m_FS.Begin(inEnabledStages); - m_EnabledStages = inEnabledStages; - LinkStages(); - } - - TShaderGeneratorStageFlags GetEnabledStages() const override { return m_EnabledStages; } - - SStageGeneratorBase &InternalGetStage(ShaderGeneratorStages::Enum inStage) - { - switch (inStage) { - case ShaderGeneratorStages::Vertex: - return m_VS; - case ShaderGeneratorStages::TessControl: - return m_TC; - case ShaderGeneratorStages::TessEval: - return m_TE; - case ShaderGeneratorStages::Geometry: - return m_GS; - case ShaderGeneratorStages::Fragment: - return m_FS; - default: - QT3DS_ASSERT(false); - break; - } - return m_VS; - } - // get the stage or NULL if it has not been created. - IShaderStageGenerator *GetStage(ShaderGeneratorStages::Enum inStage) override - { - if (inStage > 0 || inStage < ShaderGeneratorStages::StageCount) { - if ((m_EnabledStages & inStage)) - return &InternalGetStage(inStage); - } else { - QT3DS_ASSERT(false); - } - return NULL; - } - - qt3ds::render::NVRenderShaderProgram * - CompileGeneratedShader(const char *inShaderName, const SShaderCacheProgramFlags &inFlags, - TShaderFeatureSet inFeatureSet, bool separableProgram) override - { - // No stages enabled - if (((QT3DSU32)m_EnabledStages) == 0) { - QT3DS_ASSERT(false); - return NULL; - } - - qt3ds::render::IDynamicObjectSystem &theDynamicSystem(m_Context.GetDynamicObjectSystem()); - SShaderCacheProgramFlags theCacheFlags(inFlags); - for (QT3DSU32 stageIdx = 0, stageEnd = ShaderGeneratorStages::StageCount; stageIdx < stageEnd; - ++stageIdx) { - ShaderGeneratorStages::Enum stageName = - static_cast(1 << stageIdx); - if (m_EnabledStages & stageName) { - SStageGeneratorBase &theStage(InternalGetStage(stageName)); - theStage.BuildShaderSource(); - theStage.UpdateShaderCacheFlags(theCacheFlags); - theDynamicSystem.InsertShaderHeaderInformation(theStage.m_FinalBuilder, - inShaderName); - } - } - - const char *vertexShaderSource = m_VS.m_FinalBuilder.c_str(); - const char *tcShaderSource = m_TC.m_FinalBuilder.c_str(); - const char *teShaderSource = m_TE.m_FinalBuilder.c_str(); - const char *geShaderSource = m_GS.m_FinalBuilder.c_str(); - const char *fragmentShaderSource = m_FS.m_FinalBuilder.c_str(); - - IShaderCache &theCache = m_Context.GetShaderCache(); - CRegisteredString theCacheKey = m_Context.GetStringTable().RegisterStr(inShaderName); - return theCache.CompileProgram(theCacheKey, vertexShaderSource, fragmentShaderSource, - tcShaderSource, teShaderSource, geShaderSource, - theCacheFlags, inFeatureSet, separableProgram); - } -}; -}; - -IShaderProgramGenerator & -IShaderProgramGenerator::CreateProgramGenerator(IQt3DSRenderContext &inContext) -{ - return *QT3DS_NEW(inContext.GetAllocator(), SProgramGenerator)(inContext); -} - -void IShaderProgramGenerator::OutputParaboloidDepthVertex(IShaderStageGenerator &vertexShader) -{ - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddInclude("shadowMapping.glsllib"); - vertexShader.AddUniform("model_view_projection", "mat4"); - // vertexShader.AddUniform("model_view", "mat4"); - vertexShader.AddUniform("camera_properties", "vec2"); - // vertexShader.AddOutgoing("view_pos", "vec4"); - vertexShader.AddOutgoing("world_pos", "vec4"); - - // Project the location onto screen space. - // This will be horrible if you have a single large polygon. Tessellation is your friend here! - vertexShader.Append("void main() {"); - vertexShader.Append( - " ParaboloidMapResult data = VertexParaboloidDepth( attr_pos, model_view_projection );"); - vertexShader.Append(" gl_Position = data.m_Position;"); - vertexShader.Append(" world_pos = data.m_WorldPos;"); - vertexShader.Append("}"); -} - -void IShaderProgramGenerator::OutputParaboloidDepthTessEval(IShaderStageGenerator &tessEvalShader) -{ - tessEvalShader.AddInclude("shadowMapping.glsllib"); - tessEvalShader.AddUniform("model_view_projection", "mat4"); - tessEvalShader.AddOutgoing("world_pos", "vec4"); - tessEvalShader.Append(" ParaboloidMapResult data = VertexParaboloidDepth( vec3(pos.xyz), " - "model_view_projection );"); - tessEvalShader.Append(" gl_Position = data.m_Position;"); - tessEvalShader.Append(" world_pos = data.m_WorldPos;"); -} - -void IShaderProgramGenerator::OutputParaboloidDepthFragment(IShaderStageGenerator &fragmentShader) -{ - fragmentShader.AddInclude("shadowMappingFragment.glsllib"); - fragmentShader.AddUniform("model_view_projection", "mat4"); - fragmentShader.AddUniform("camera_properties", "vec2"); - fragmentShader.Append("void main() {"); - fragmentShader.Append(" gl_FragDepth = FragmentParaboloidDepth( world_pos, " - "model_view_projection, camera_properties );"); - fragmentShader.Append("}"); -} - -void IShaderProgramGenerator::OutputCubeFaceDepthVertex(IShaderStageGenerator &vertexShader) -{ - vertexShader.AddIncoming("attr_pos", "vec3"); - vertexShader.AddUniform("model_matrix", "mat4"); - vertexShader.AddUniform("model_view_projection", "mat4"); - - vertexShader.AddOutgoing("raw_pos", "vec4"); - vertexShader.AddOutgoing("world_pos", "vec4"); - - vertexShader.Append("void main() {"); - vertexShader.Append(" world_pos = model_matrix * vec4( attr_pos, 1.0 );"); - vertexShader.Append(" world_pos /= world_pos.w;"); - vertexShader.Append(" gl_Position = model_view_projection * vec4( attr_pos, 1.0 );"); - vertexShader.Append(" raw_pos = vec4( attr_pos, 1.0 );"); - // vertexShader.Append(" gl_Position = vec4( attr_pos, 1.0 );"); - vertexShader.Append("}"); -} - -void IShaderProgramGenerator::OutputCubeFaceDepthGeometry(IShaderStageGenerator &geometryShader) -{ - geometryShader.Append("layout(triangles) in;"); - geometryShader.Append("layout(triangle_strip, max_vertices = 18) out;"); - // geometryShader.AddUniform("shadow_mvp[6]", "mat4"); - - geometryShader.AddUniform("shadow_mv0", "mat4"); - geometryShader.AddUniform("shadow_mv1", "mat4"); - geometryShader.AddUniform("shadow_mv2", "mat4"); - geometryShader.AddUniform("shadow_mv3", "mat4"); - geometryShader.AddUniform("shadow_mv4", "mat4"); - geometryShader.AddUniform("shadow_mv5", "mat4"); - geometryShader.AddUniform("projection", "mat4"); - - geometryShader.AddUniform("model_matrix", "mat4"); - geometryShader.AddOutgoing("world_pos", "vec4"); - - geometryShader.Append("void main() {"); - geometryShader.Append(" mat4 layerMVP[6];"); - geometryShader.Append(" layerMVP[0] = projection * shadow_mv0;"); - geometryShader.Append(" layerMVP[1] = projection * shadow_mv1;"); - geometryShader.Append(" layerMVP[2] = projection * shadow_mv2;"); - geometryShader.Append(" layerMVP[3] = projection * shadow_mv3;"); - geometryShader.Append(" layerMVP[4] = projection * shadow_mv4;"); - geometryShader.Append(" layerMVP[5] = projection * shadow_mv5;"); - geometryShader.Append(" for (int i = 0; i < 6; ++i)"); - geometryShader.Append(" {"); - geometryShader.Append(" gl_Layer = i;"); - geometryShader.Append(" for(int j = 0; j < 3; ++j)"); - geometryShader.Append(" {"); - geometryShader.Append(" world_pos = model_matrix * raw_pos[j];"); - geometryShader.Append(" world_pos /= world_pos.w;"); - geometryShader.Append(" gl_Position = layerMVP[j] * raw_pos[j];"); - geometryShader.Append(" world_pos.w = gl_Position.w;"); - geometryShader.Append(" EmitVertex();"); - geometryShader.Append(" }"); - geometryShader.Append(" EndPrimitive();"); - geometryShader.Append(" }"); - geometryShader.Append("}"); -} - -void IShaderProgramGenerator::OutputCubeFaceDepthFragment(IShaderStageGenerator &fragmentShader) -{ - fragmentShader.AddUniform("camera_position", "vec3"); - fragmentShader.AddUniform("camera_properties", "vec2"); - - fragmentShader.Append("void main() {"); - fragmentShader.Append( - "\tvec3 camPos = vec3( camera_position.x, camera_position.y, -camera_position.z );"); - fragmentShader.Append("\tfloat dist = length( world_pos.xyz - camPos );"); - fragmentShader.Append( - "\tdist = (dist - camera_properties.x) / (camera_properties.y - camera_properties.x);"); - // fragmentShader.Append("\tgl_FragDepth = dist;"); - fragmentShader.Append("\tfragOutput = vec4(dist, dist, dist, 1.0);"); - fragmentShader.Append("}"); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShadowMap.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShadowMap.cpp deleted file mode 100644 index cfc49d61..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderShadowMap.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderShadowMap.h" -#include "Qt3DSRenderResourceManager.h" -#include "../RendererImpl/Qt3DSRendererImplLayerRenderData.h" -#include "render/Qt3DSRenderShaderConstant.h" -#include "render/Qt3DSRenderShaderProgram.h" - -using namespace qt3ds::render; -using qt3ds::render::NVRenderContextScopedProperty; -using qt3ds::render::NVRenderCachedShaderProperty; - -Qt3DSShadowMap::Qt3DSShadowMap(IQt3DSRenderContext &inContext) - : m_Context(inContext) - , mRefCount(0) - , m_ShadowMapList(inContext.GetAllocator(), "Qt3DSShadowMap::m_ShadowMapList") -{ -} - -Qt3DSShadowMap::~Qt3DSShadowMap() -{ - m_ShadowMapList.clear(); -} - -namespace { -bool IsDepthFormat(NVRenderTextureFormats::Enum format) -{ - switch (format) { - case NVRenderTextureFormats::Depth16: - case NVRenderTextureFormats::Depth24: - case NVRenderTextureFormats::Depth32: - case NVRenderTextureFormats::Depth24Stencil8: - return true; - default: - return false; - } -} -} - -void Qt3DSShadowMap::AddShadowMapEntry(QT3DSU32 index, QT3DSU32 width, QT3DSU32 height, - NVRenderTextureFormats::Enum format, QT3DSU32 samples, - ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter) -{ - IResourceManager &theManager(m_Context.GetResourceManager()); - SShadowMapEntry *pEntry = NULL; - - if (index < m_ShadowMapList.size()) - pEntry = &m_ShadowMapList[index]; - - if (pEntry) { - if ((NULL != pEntry->m_DepthMap) && (mode == ShadowMapModes::CUBE)) { - theManager.Release(*pEntry->m_DepthMap); - theManager.Release(*pEntry->m_DepthCopy); - theManager.Release(*pEntry->m_DepthRender); - pEntry->m_DepthCube = theManager.AllocateTextureCube(width, height, format, samples); - pEntry->m_CubeCopy = theManager.AllocateTextureCube(width, height, format, samples); - pEntry->m_DepthRender = theManager.AllocateTexture2D( - width, height, NVRenderTextureFormats::Depth24Stencil8, samples); - pEntry->m_DepthMap = NULL; - pEntry->m_DepthCopy = NULL; - } else if ((NULL != pEntry->m_DepthCube) && (mode != ShadowMapModes::CUBE)) { - theManager.Release(*pEntry->m_DepthCube); - theManager.Release(*pEntry->m_CubeCopy); - theManager.Release(*pEntry->m_DepthRender); - pEntry->m_DepthMap = theManager.AllocateTexture2D(width, height, format, samples); - pEntry->m_DepthCopy = theManager.AllocateTexture2D(width, height, format, samples); - pEntry->m_DepthCube = NULL; - pEntry->m_CubeCopy = NULL; - pEntry->m_DepthRender = theManager.AllocateTexture2D( - width, height, NVRenderTextureFormats::Depth24Stencil8, samples); - } else if (NULL != pEntry->m_DepthMap) { - STextureDetails theDetails(pEntry->m_DepthMap->GetTextureDetails()); - - // If anything differs about the map we're looking for, let's recreate it. - if (theDetails.m_Format != format || theDetails.m_Width != width - || theDetails.m_Height != height || theDetails.m_SampleCount != samples) { - // release texture - theManager.Release(*pEntry->m_DepthMap); - theManager.Release(*pEntry->m_DepthCopy); - theManager.Release(*pEntry->m_DepthRender); - pEntry->m_DepthMap = theManager.AllocateTexture2D(width, height, format, samples); - pEntry->m_DepthCopy = theManager.AllocateTexture2D(width, height, format, samples); - pEntry->m_DepthCube = NULL; - pEntry->m_CubeCopy = NULL; - pEntry->m_DepthRender = theManager.AllocateTexture2D( - width, height, NVRenderTextureFormats::Depth24Stencil8, samples); - } - } else { - STextureDetails theDetails(pEntry->m_DepthCube->GetTextureDetails()); - - // If anything differs about the map we're looking for, let's recreate it. - if (theDetails.m_Format != format || theDetails.m_Width != width - || theDetails.m_Height != height || theDetails.m_SampleCount != samples) { - // release texture - theManager.Release(*pEntry->m_DepthCube); - theManager.Release(*pEntry->m_CubeCopy); - theManager.Release(*pEntry->m_DepthRender); - pEntry->m_DepthCube = - theManager.AllocateTextureCube(width, height, format, samples); - pEntry->m_CubeCopy = theManager.AllocateTextureCube(width, height, format, samples); - pEntry->m_DepthRender = theManager.AllocateTexture2D( - width, height, NVRenderTextureFormats::Depth24Stencil8, samples); - pEntry->m_DepthMap = NULL; - pEntry->m_DepthCopy = NULL; - } - } - - pEntry->m_ShadowMapMode = mode; - pEntry->m_ShadowFilterFlags = filter; - } else if (mode == ShadowMapModes::CUBE) { - NVRenderTextureCube *theDepthTex = - theManager.AllocateTextureCube(width, height, format, samples); - NVRenderTextureCube *theDepthCopy = - theManager.AllocateTextureCube(width, height, format, samples); - NVRenderTexture2D *theDepthTemp = theManager.AllocateTexture2D( - width, height, NVRenderTextureFormats::Depth24Stencil8, samples); - - m_ShadowMapList.push_back( - SShadowMapEntry(index, mode, filter, *theDepthTex, *theDepthCopy, *theDepthTemp)); - - pEntry = &m_ShadowMapList.back(); - } else { - NVRenderTexture2D *theDepthMap = - theManager.AllocateTexture2D(width, height, format, samples); - NVRenderTexture2D *theDepthCopy = - theManager.AllocateTexture2D(width, height, format, samples); - NVRenderTexture2D *theDepthTemp = theManager.AllocateTexture2D( - width, height, NVRenderTextureFormats::Depth24Stencil8, samples); - - m_ShadowMapList.push_back( - SShadowMapEntry(index, mode, filter, *theDepthMap, *theDepthCopy, *theDepthTemp)); - - pEntry = &m_ShadowMapList.back(); - } - - if (pEntry) { - // setup some texture settings - if (pEntry->m_DepthMap) { - pEntry->m_DepthMap->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - pEntry->m_DepthMap->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - pEntry->m_DepthMap->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - pEntry->m_DepthMap->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - - pEntry->m_DepthCopy->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - pEntry->m_DepthCopy->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - pEntry->m_DepthCopy->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - pEntry->m_DepthCopy->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - - pEntry->m_DepthRender->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - pEntry->m_DepthRender->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - pEntry->m_DepthRender->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - pEntry->m_DepthRender->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - } else { - pEntry->m_DepthCube->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - pEntry->m_DepthCube->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - pEntry->m_DepthCube->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - pEntry->m_DepthCube->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - - pEntry->m_CubeCopy->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - pEntry->m_CubeCopy->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - pEntry->m_CubeCopy->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - pEntry->m_CubeCopy->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - - pEntry->m_DepthRender->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - pEntry->m_DepthRender->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - pEntry->m_DepthRender->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - pEntry->m_DepthRender->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - } - - pEntry->m_LightIndex = index; - } -} - -SShadowMapEntry *Qt3DSShadowMap::GetShadowMapEntry(QT3DSU32 index) -{ - SShadowMapEntry *pEntry = NULL; - - for (QT3DSU32 i = 0; i < m_ShadowMapList.size(); i++) { - pEntry = &m_ShadowMapList[i]; - if (pEntry->m_LightIndex == index) - return pEntry; - } - - return NULL; -} - -Qt3DSShadowMap *Qt3DSShadowMap::Create(IQt3DSRenderContext &inContext) -{ - return QT3DS_NEW(inContext.GetFoundation().getAllocator(), Qt3DSShadowMap)(inContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderSubpresentation.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderSubpresentation.cpp deleted file mode 100644 index cd83f036..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderSubpresentation.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderSubpresentation.h" -#include "Qt3DSRenderRenderList.h" -#ifdef _WIN32 -#pragma warning(disable : 4355) // this used in initializer list. I have never seen this result in - // a physical error -#endif -namespace qt3ds { -namespace render { - - Qt3DSRenderPickResult CSubPresentationPickQuery::Pick(const QT3DSVec2 &inMouseCoords, - const QT3DSVec2 &inViewportDimensions, - bool inPickEverything) - { - return m_Renderer.DoGraphQueryPick(inMouseCoords, inViewportDimensions, inPickEverything); - } - - CSubPresentationRenderer::CSubPresentationRenderer(IQt3DSRenderContext &inRenderContext, - SPresentation &inPresentation) - : m_RenderContext(inRenderContext) - , m_Presentation(inPresentation) - , mRefCount(0) - , m_PickQuery(*this) - , m_OffscreenRendererType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) - { - } - - SOffscreenRendererEnvironment - CSubPresentationRenderer::GetDesiredEnvironment(QT3DSVec2 /*inPresScale*/) - { - // If we aren't using a clear color, then we are expected to blend with the background - bool hasTransparency = m_Presentation.m_Scene->m_UseClearColor ? false : true; - NVRenderTextureFormats::Enum format = - hasTransparency ? NVRenderTextureFormats::RGBA8 : NVRenderTextureFormats::RGB8; - return SOffscreenRendererEnvironment((QT3DSU32)(m_Presentation.m_PresentationDimensions.x), - (QT3DSU32)(m_Presentation.m_PresentationDimensions.y), - format, OffscreenRendererDepthValues::Depth16, false, - AAModeValues::NoAA); - } - - SOffscreenRenderFlags - CSubPresentationRenderer::NeedsRender(const SOffscreenRendererEnvironment & /*inEnvironment*/, - QT3DSVec2 /*inPresScale*/, - const SRenderInstanceId instanceId) - { - bool hasTransparency = m_Presentation.m_Scene->m_UseClearColor ? false : true; - NVRenderRect theViewportSize(m_RenderContext.GetRenderList().GetViewport()); - bool wasDirty = m_Presentation.m_Scene->PrepareForRender( - QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), - m_RenderContext, instanceId); - return SOffscreenRenderFlags(hasTransparency, wasDirty); - } - - // Returns true if the rendered result image has transparency, or false - // if it should be treated as a completely opaque image. - void CSubPresentationRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2, - SScene::RenderClearCommand inClearColorBuffer, - const SRenderInstanceId instanceId) - { - SSubPresentationHelper theHelper( - m_RenderContext, - QSize((QT3DSU32)inEnvironment.m_Width, (QT3DSU32)inEnvironment.m_Height)); - NVRenderRect theViewportSize(inRenderContext.GetViewport()); - m_Presentation.m_Scene->Render( - QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), - m_RenderContext, inClearColorBuffer, instanceId); - m_LastRenderedEnvironment = inEnvironment; - } - - void CSubPresentationRenderer::RenderWithClear( - const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, - SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, - const SRenderInstanceId id) - { - Q_UNUSED(inEnvironment); - Q_UNUSED(inPresScale); - NVRenderRect theViewportSize(inRenderContext.GetViewport()); - m_Presentation.m_Scene->RenderWithClear( - QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), - m_RenderContext, inClearBuffer, inClearColor, id); - } - - // You know the viewport dimensions because - Qt3DSRenderPickResult CSubPresentationRenderer::DoGraphQueryPick( - const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, bool inPickEverything) - { - Qt3DSRenderPickResult thePickResult; - - if (m_Presentation.m_Scene && m_Presentation.m_Scene->m_FirstChild) { - thePickResult = m_RenderContext.GetRenderer().Pick( - *m_Presentation.m_Scene->m_FirstChild, inViewportDimensions, - QT3DSVec2(inMouseCoords.x, inMouseCoords.y), true, inPickEverything); - } - return thePickResult; - } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureAtlas.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureAtlas.cpp deleted file mode 100644 index 81c1d232..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureAtlas.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderTextTextureAtlas.h" -#include "Qt3DSTextRenderer.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderContext.h" - -using namespace qt3ds::render; - -namespace { - -struct STextTextureAtlas : public ITextTextureAtlas -{ - static const QT3DSI32 TEXTURE_ATLAS_DIM = - 256; // if you change this you need to adjust Qt3DSOnscreenTextRenderer size as well - - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - NVScopedRefCounted m_TextRenderer; - NVScopedRefCounted m_RenderContext; - - STextTextureAtlas(NVFoundationBase &inFnd, ITextRenderer &inRenderer, - NVRenderContext &inRenderContext) - : m_Foundation(inFnd) - , mRefCount(0) - , m_TextRenderer(inRenderer) - , m_RenderContext(inRenderContext) - , m_TextureAtlasInitialized(false) - , m_textureAtlas(NULL) - { - } - - virtual ~STextTextureAtlas() - { - if (m_textureAtlas) { - m_textureAtlas->release(); - } - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - TTextRenderAtlasDetailsAndTexture RenderText(const STextRenderInfo &inText) override - { - SRenderTextureAtlasDetails theDetails = m_TextRenderer->RenderText(inText); - - return TTextRenderAtlasDetailsAndTexture(theDetails, m_textureAtlas); - } - - bool IsInitialized() override { return m_TextureAtlasInitialized && m_textureAtlas; } - - TTextTextureAtlasDetailsAndTexture PrepareTextureAtlas() override - { - if (!m_TextureAtlasInitialized && !m_textureAtlas) { - // create the texture atlas entries - QT3DSI32 count = m_TextRenderer->CreateTextureAtlas(); - - m_textureAtlas = m_RenderContext->CreateTexture2D(); - if (m_textureAtlas && count) { - m_TextureAtlasInitialized = true; - m_textureAtlas->addRef(); - // if you change the size you need to adjust Qt3DSOnscreenTextRenderer too - if (m_RenderContext->GetRenderContextType() == NVRenderContextValues::GLES2) { - m_textureAtlas->SetTextureData(NVDataRef(), 0, TEXTURE_ATLAS_DIM, - TEXTURE_ATLAS_DIM, NVRenderTextureFormats::RGBA8); - } else { - m_textureAtlas->SetTextureData(NVDataRef(), 0, TEXTURE_ATLAS_DIM, - TEXTURE_ATLAS_DIM, NVRenderTextureFormats::Alpha8); - } - m_textureAtlas->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - m_textureAtlas->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - m_textureAtlas->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); - m_textureAtlas->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); - qt3ds::render::STextureDetails texTexDetails = m_textureAtlas->GetTextureDetails(); - return TTextTextureAtlasDetailsAndTexture( - STextTextureAtlasDetails(texTexDetails.m_Height, texTexDetails.m_Height, false, - count), - m_textureAtlas); - } - } - - return TTextTextureAtlasDetailsAndTexture(STextTextureAtlasDetails(), NULL); - } - -private: - bool m_TextureAtlasInitialized; - NVRenderTexture2D *m_textureAtlas; // this is the actual texture which has application lifetime -}; - -} // namespace - -ITextTextureAtlas &ITextTextureAtlas::CreateTextureAtlas(NVFoundationBase &inFnd, - ITextRenderer &inTextRenderer, - NVRenderContext &inRenderContext) -{ - return *QT3DS_NEW(inFnd.getAllocator(), STextTextureAtlas)(inFnd, inTextRenderer, inRenderContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureCache.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureCache.cpp deleted file mode 100644 index 304e64b6..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextTextureCache.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderTextTextureCache.h" -#include "Qt3DSTextRenderer.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSPool.h" - -using namespace qt3ds::render; - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const qt3ds::render::STextRenderInfo &inInfo) const - { - size_t retval = hash()(reinterpret_cast(inInfo.m_Text.c_str())); - retval = retval ^ hash()(reinterpret_cast(inInfo.m_Font.c_str())); - retval = retval ^ hash()(inInfo.m_FontSize); - retval = retval ^ hash()(static_cast(inInfo.m_HorizontalAlignment)); - retval = retval ^ hash()(static_cast(inInfo.m_VerticalAlignment)); - retval = retval ^ hash()(inInfo.m_Leading); - retval = retval ^ hash()(inInfo.m_Tracking); - retval = retval ^ hash()(inInfo.m_DropShadow); - retval = retval ^ hash()(inInfo.m_DropShadowStrength); - retval = retval ^ hash()(inInfo.m_DropShadowOffset); // To be removed in 2.x (when UIP version is next updated) - retval = retval ^ hash()(inInfo.m_DropShadowOffsetX); - retval = retval ^ hash()(inInfo.m_DropShadowOffsetY); - retval = retval ^ hash()(inInfo.m_BoundingBox.x); - retval = retval ^ hash()(inInfo.m_BoundingBox.y); - retval = retval ^ hash()(static_cast(inInfo.m_Elide)); - retval = retval ^ hash()(static_cast(inInfo.m_DropShadowHorizontalAlignment)); // To be removed in 2.x (when UIP version is next updated) - retval = retval ^ hash()(static_cast(inInfo.m_DropShadowVerticalAlignment)); // To be removed in 2.x (when UIP version is next updated) - retval = retval ^ hash()(static_cast(inInfo.m_WordWrap)); - retval = retval ^ hash()(inInfo.m_EnableAcceleratedFont); - return retval; - } -}; -} - -namespace { -struct STextRenderInfoAndHash -{ - STextRenderInfo m_Info; - QT3DSF32 m_ScaleFactor; - size_t m_Hashcode; - STextRenderInfoAndHash(const STextRenderInfo &inInfo, QT3DSF32 inScaleFactor) - : m_Info(inInfo) - , m_ScaleFactor(inScaleFactor) - , m_Hashcode(eastl::hash()(inInfo) ^ eastl::hash()(inScaleFactor)) - { - } - bool operator==(const STextRenderInfoAndHash &inOther) const - { - return m_Info.m_Text == inOther.m_Info.m_Text && m_Info.m_Font == inOther.m_Info.m_Font - && m_Info.m_FontSize == inOther.m_Info.m_FontSize - && m_Info.m_HorizontalAlignment == inOther.m_Info.m_HorizontalAlignment - && m_Info.m_VerticalAlignment == inOther.m_Info.m_VerticalAlignment - && m_Info.m_Leading == inOther.m_Info.m_Leading - && m_Info.m_Tracking == inOther.m_Info.m_Tracking - && m_Info.m_DropShadow == inOther.m_Info.m_DropShadow - && m_Info.m_DropShadowStrength == inOther.m_Info.m_DropShadowStrength - && m_Info.m_DropShadowOffset == inOther.m_Info.m_DropShadowOffset - && m_Info.m_DropShadowHorizontalAlignment - == inOther.m_Info.m_DropShadowHorizontalAlignment - && m_Info.m_DropShadowVerticalAlignment == inOther.m_Info.m_DropShadowVerticalAlignment - && m_Info.m_BoundingBox == inOther.m_Info.m_BoundingBox - && m_Info.m_WordWrap == inOther.m_Info.m_WordWrap - && m_Info.m_EnableAcceleratedFont == inOther.m_Info.m_EnableAcceleratedFont - && m_ScaleFactor == inOther.m_ScaleFactor; - } -}; -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const STextRenderInfoAndHash &inInfo) const { return inInfo.m_Hashcode; } -}; -}; - -namespace { - -struct STextCacheNode -{ - STextCacheNode *m_PreviousSibling; - STextCacheNode *m_NextSibling; - STextRenderInfoAndHash m_RenderInfo; - TTPathObjectAndTexture m_TextInfo; - QT3DSU32 m_FrameCount; - - STextCacheNode(const STextRenderInfoAndHash &inRenderInfo, - const TTPathObjectAndTexture &inTextInfo) - : m_PreviousSibling(NULL) - , m_NextSibling(NULL) - , m_RenderInfo(inRenderInfo) - , m_TextInfo(inTextInfo) - , m_FrameCount(0) - { - } -}; - -typedef nvhash_map TTextureInfoHash; - -DEFINE_INVASIVE_LIST(TextCacheNode); -IMPLEMENT_INVASIVE_LIST(TextCacheNode, m_PreviousSibling, m_NextSibling); - -struct STextTextureCache : public ITextTextureCache -{ - typedef Pool TPoolType; - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - NVScopedRefCounted m_TextRenderer; - TTextureInfoHash m_TextureCache; - TTextCacheNodeList m_LRUList; - TPoolType m_CacheNodePool; - QT3DSU32 m_HighWaterMark; - QT3DSU32 m_FrameCount; - QT3DSU32 m_TextureTotalBytes; - NVScopedRefCounted m_RenderContext; - bool m_CanUsePathRendering; ///< true if we use hardware accelerated font rendering - - STextTextureCache(NVFoundationBase &inFnd, ITextRenderer &inRenderer, - NVRenderContext &inRenderContext) - : m_Foundation(inFnd) - , mRefCount(0) - , m_TextRenderer(inRenderer) - , m_TextureCache(m_Foundation.getAllocator(), "STextTextureCache::m_TextureCache") - , m_CacheNodePool(ForwardingAllocator(m_Foundation.getAllocator(), - "STextTextureCache::m_CacheNodePool")) - , m_HighWaterMark(0x100000) - , m_FrameCount(0) - , m_TextureTotalBytes(0) - , m_RenderContext(inRenderContext) - { - // hardware accelerate font rendering not ready yet - m_CanUsePathRendering = (m_RenderContext->IsPathRenderingSupported() - && m_RenderContext->IsProgramPipelineSupported()); - } - - virtual ~STextTextureCache() - { - for (TTextCacheNodeList::iterator iter = m_LRUList.begin(), end = m_LRUList.end(); - iter != end; ++iter) - iter->~STextCacheNode(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) - - static inline QT3DSU32 GetNumBytes(NVRenderTexture2D &inTexture) - { - STextureDetails theDetails(inTexture.GetTextureDetails()); - return theDetails.m_Width * theDetails.m_Height - * NVRenderTextureFormats::getSizeofFormat(theDetails.m_Format); - } - - NVScopedRefCounted InvalidateLastItem() - { - NVScopedRefCounted nextTexture; - if (m_LRUList.empty() == false) { - STextCacheNode &theEnd = m_LRUList.back(); - if (theEnd.m_FrameCount != m_FrameCount) { - nextTexture = theEnd.m_TextInfo.second.second; - STextureDetails theDetails = nextTexture->GetTextureDetails(); - m_TextureTotalBytes -= GetNumBytes(*nextTexture.mPtr); - m_LRUList.remove(theEnd); - // copy the key because the next statement will destroy memory - m_TextureCache.erase(theEnd.m_RenderInfo); - theEnd.~STextCacheNode(); - m_CacheNodePool.deallocate(&theEnd); - } - } - return nextTexture; - } - - TTPathObjectAndTexture RenderText(const STextRenderInfo &inText, QT3DSF32 inScaleFactor) override - { - STextRenderInfoAndHash theKey(inText, inScaleFactor); - TTextureInfoHash::iterator theFind( - m_TextureCache.find(STextRenderInfoAndHash(inText, inScaleFactor))); - STextCacheNode *retval = NULL; - if (theFind != m_TextureCache.end()) { - retval = theFind->second; - m_LRUList.remove(*retval); - } else { - NVScopedRefCounted nextTexture; - if (m_TextureTotalBytes >= m_HighWaterMark && m_LRUList.empty() == false) - nextTexture = InvalidateLastItem(); - - if (nextTexture.mPtr == NULL) - nextTexture = m_RenderContext->CreateTexture2D(); - - NVScopedRefCounted nextPathFontItemObject; - NVScopedRefCounted nextPathFontObject; - // HW acceleration for fonts not supported - //if (m_CanUsePathRendering && inText.m_EnableAcceleratedFont) { - // nextPathFontItemObject = m_RenderContext->CreatePathFontItem(); - // nextPathFontObject = m_RenderContext->CreatePathFontSpecification(inText.m_Font); - //} - - STextRenderInfo theTextInfo(inText); - theTextInfo.m_FontSize *= inScaleFactor; - STextTextureDetails theDetails; - - - // HW acceleration for fonts not supported - //if (!m_CanUsePathRendering || !inText.m_EnableAcceleratedFont) - theDetails = m_TextRenderer->RenderText(theTextInfo, *nextTexture.mPtr); - //else - // theDetails = m_TextRenderer->RenderText(theTextInfo, *nextPathFontItemObject.mPtr, - // *nextPathFontObject.mPtr); - - if (fabs(inScaleFactor - 1.0f) > .001f) { - TTPathObjectAndTexture theCanonicalDetails = RenderText(inText, 1.0f); - theDetails.m_ScaleFactor.x = - (QT3DSF32)theDetails.m_TextWidth / theCanonicalDetails.second.first.m_TextWidth; - theDetails.m_ScaleFactor.y = - (QT3DSF32)theDetails.m_TextHeight / theCanonicalDetails.second.first.m_TextHeight; - } - theKey = STextRenderInfoAndHash(inText, inScaleFactor); - retval = m_CacheNodePool.construct( - theKey, TTPathObjectAndTexture( - TPathFontSpecAndPathObject(nextPathFontObject, nextPathFontItemObject), - TTextTextureDetailsAndTexture(theDetails, nextTexture)), - __FILE__, __LINE__); - TTextureInfoHash::iterator insert = - m_TextureCache.insert(eastl::make_pair(theKey, retval)).first; - if (!m_CanUsePathRendering) - m_TextureTotalBytes += GetNumBytes(*(retval->m_TextInfo.second.second.mPtr)); - } - retval->m_FrameCount = m_FrameCount; - m_LRUList.push_front(*retval); - return retval->m_TextInfo; - } - // We may have one more texture in cache than this byte count, but this will be the limiting - // factor. - QT3DSU32 GetCacheHighWaterBytes() const override { return m_HighWaterMark; } - // default cache size is 10 MB. - void SetCacheHighWaterBytes(QT3DSU32 inByteCount) override { m_HighWaterMark = inByteCount; } - - void BeginFrame() override {} - void EndFrame() override - { - // algorithm is resistant to rollover. - ++m_FrameCount; - // Release any texture that put us over the limit. - // This almost guarantees thrashing if the limit is set too low. Enable at your - // own risk at *TEST CAREFULLY* - /* - while( m_TextureTotalBytes >= m_HighWaterMark && m_LRUList.empty() == false ) - InvalidateLastItem(); - */ - } -}; -} - -ITextTextureCache &ITextTextureCache::CreateTextureCache(NVFoundationBase &inFnd, - ITextRenderer &inTextRenderer, - NVRenderContext &inRenderContext) -{ - return *QT3DS_NEW(inFnd.getAllocator(), STextTextureCache)(inFnd, inTextRenderer, inRenderContext); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextureAtlas.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextureAtlas.cpp deleted file mode 100644 index 062e7d57..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderTextureAtlas.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderTextureAtlas.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "render/Qt3DSRenderTexture2D.h" -#include "render/Qt3DSRenderContext.h" - -using namespace qt3ds::render; - -namespace { - -// a algorithm based on http://clb.demon.fi/files/RectangleBinPack/ -struct STextureAtlasBinPackSL -{ -public: - STextureAtlasBinPackSL(NVRenderContext &inContext, QT3DSI32 width, QT3DSI32 height) - : m_BinWidth(width) - , m_BinHeight(height) - , m_SkyLine(inContext.GetAllocator(), "STextureAtlasBinPackSL::m_SkyLine") - { - // setup first entry - SSkylineNode theNode = { 0, 0, width }; - m_SkyLine.push_back(theNode); - } - - ~STextureAtlasBinPackSL() { m_SkyLine.clear(); } - - /* insert new rect - * - */ - STextureAtlasRect Insert(QT3DSI32 width, QT3DSI32 height) - { - QT3DSI32 binHeight; - QT3DSI32 binWidth; - QT3DSI32 binIndex; - - STextureAtlasRect newNode = findPosition(width, height, &binWidth, &binHeight, &binIndex); - - if (binIndex != -1) { - // adjust skyline nodes - addSkylineLevelNode(binIndex, newNode); - } - - return newNode; - } - -private: - /// Represents a single level (a horizontal line) of the skyline/horizon/envelope. - struct SSkylineNode - { - int x; ///< The starting x-coordinate (leftmost). - int y; ///< The y-coordinate of the skyline level line. - int width; /// The line width. The ending coordinate (inclusive) will be x+width-1. - }; - - /* find position - * - */ - STextureAtlasRect findPosition(QT3DSI32 width, QT3DSI32 height, QT3DSI32 *binWidth, QT3DSI32 *binHeight, - QT3DSI32 *binIndex) - { - *binWidth = m_BinWidth; - *binHeight = m_BinHeight; - *binIndex = -1; - STextureAtlasRect newRect; - - for (QT3DSU32 i = 0; i < m_SkyLine.size(); ++i) { - QT3DSI32 y = getSkylineLevel(i, width, height); - - if (y >= 0) { - if ((y + height < *binHeight) - || ((y + height == *binHeight) && m_SkyLine[i].width < *binWidth)) { - *binHeight = y + height; - *binIndex = i; - *binWidth = m_SkyLine[i].width; - newRect.m_X = m_SkyLine[i].x; - newRect.m_Y = y; - newRect.m_Width = width; - newRect.m_Height = height; - } - } - } - - return newRect; - } - - /* @brief check if rectangle can be placed into the the bin - * - * return skyline hight - */ - int getSkylineLevel(QT3DSU32 binIndex, QT3DSI32 width, QT3DSI32 height) - { - // first check width exceed - QT3DSI32 x = m_SkyLine[binIndex].x; - if (x + width > m_BinWidth) - return -1; - - QT3DSI32 leftAlign = width; - QT3DSU32 index = binIndex; - QT3DSI32 y = m_SkyLine[index].y; - - while (leftAlign > 0) { - y = (y > m_SkyLine[index].y) ? y : m_SkyLine[index].y; - // check hight - if (y + height > m_BinHeight) - return -1; - - leftAlign -= m_SkyLine[index].width; - ++index; - - if (index > m_SkyLine.size()) - return -1; - } - - return y; - } - - /* @brief add an new skyline entry - * - * return no return - */ - void addSkylineLevelNode(QT3DSI32 binIndex, const STextureAtlasRect &newRect) - { - SSkylineNode newNode; - - newNode.x = newRect.m_X; - newNode.y = newRect.m_Y + newRect.m_Height; - newNode.width = newRect.m_Width; - m_SkyLine.insert(m_SkyLine.begin() + binIndex, newNode); - - // iterate over follow up nodes and adjust - for (QT3DSU32 i = binIndex + 1; i < m_SkyLine.size(); ++i) { - if (m_SkyLine[i].x < m_SkyLine[i - 1].x + m_SkyLine[i - 1].width) { - int shrink = m_SkyLine[i - 1].x + m_SkyLine[i - 1].width - m_SkyLine[i].x; - - m_SkyLine[i].x += shrink; - m_SkyLine[i].width -= shrink; - - if (m_SkyLine[i].width <= 0) { - m_SkyLine.erase(m_SkyLine.begin() + i); - --i; - } else { - break; - } - } else { - break; - } - } - - mergeSkylineLevelNodes(); - } - - /* @brief merge skyline node - * - * return no return - */ - void mergeSkylineLevelNodes() - { - // check if we can merge nodes - for (QT3DSU32 i = 0; i < m_SkyLine.size() - 1; ++i) { - if (m_SkyLine[i].y == m_SkyLine[i + 1].y) { - m_SkyLine[i].width += m_SkyLine[i + 1].width; - m_SkyLine.erase(m_SkyLine.begin() + (i + 1)); - --i; - } - } - } - - QT3DSI32 m_BinWidth; - QT3DSI32 m_BinHeight; - - nvvector m_SkyLine; -}; - -struct STextureAtlasEntry -{ - STextureAtlasEntry() - : m_X(0) - , m_Y(0) - , m_Width(0) - , m_Height(0) - , m_pBuffer(NVDataRef()) - { - } - STextureAtlasEntry(QT3DSF32 x, QT3DSF32 y, QT3DSF32 w, QT3DSF32 h, NVDataRef buffer) - : m_X(x) - , m_Y(y) - , m_Width(w) - , m_Height(h) - , m_pBuffer(buffer) - { - } - STextureAtlasEntry(const STextureAtlasEntry &entry) - { - m_X = entry.m_X; - m_Y = entry.m_Y; - m_Width = entry.m_Width; - m_Height = entry.m_Height; - m_pBuffer = entry.m_pBuffer; - } - ~STextureAtlasEntry() {} - - QT3DSF32 m_X, m_Y; - QT3DSF32 m_Width, m_Height; - NVDataRef m_pBuffer; -}; - -struct STextureAtlas : public ITextureAtlas -{ - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - NVScopedRefCounted m_RenderContext; - - STextureAtlas(NVFoundationBase &inFnd, NVRenderContext &inRenderContext, QT3DSI32 width, - QT3DSI32 height) - : m_Foundation(inFnd) - , mRefCount(0) - , m_RenderContext(inRenderContext) - , m_Width(width) - , m_Height(height) - , m_Spacing(1) - , m_AtlasEntrys(inFnd.getAllocator(), "STextureAtlas::m_SkyLine") - { - m_pBinPack = - QT3DS_NEW(inFnd.getAllocator(), STextureAtlasBinPackSL)(inRenderContext, width, height); - } - - virtual ~STextureAtlas() - { - RelaseEntries(); - - if (m_pBinPack) - NVDelete(m_Foundation.getAllocator(), m_pBinPack); - } - - void RelaseEntries() override - { - nvvector::iterator it; - - for (it = m_AtlasEntrys.begin(); it != m_AtlasEntrys.end(); it++) { - QT3DS_FREE(m_Foundation.getAllocator(), it->m_pBuffer.begin()); - } - - m_AtlasEntrys.clear(); - } - QT3DSI32 GetWidth() const override { return m_Width; } - QT3DSI32 GetHeight() const override { return m_Height; } - - QT3DSI32 GetAtlasEntryCount() const override { return m_AtlasEntrys.size(); } - - TTextureAtlasEntryAndBuffer GetAtlasEntryByIndex(QT3DSU32 index) override - { - if (index >= m_AtlasEntrys.size()) - return eastl::make_pair(STextureAtlasRect(), NVDataRef()); - - return eastl::make_pair(STextureAtlasRect((QT3DSI32)m_AtlasEntrys[index].m_X, - (QT3DSI32)m_AtlasEntrys[index].m_Y, - (QT3DSI32)m_AtlasEntrys[index].m_Width, - (QT3DSI32)m_AtlasEntrys[index].m_Height), - m_AtlasEntrys[index].m_pBuffer); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - STextureAtlasRect AddAtlasEntry(QT3DSI32 width, QT3DSI32 height, QT3DSI32 pitch, - QT3DSI32 dataWidth, NVConstDataRef bufferData) override - { - STextureAtlasRect rect; - - // pitch is the number of bytes per line in bufferData - // dataWidth is the relevant data width in bufferData. Rest is padding that can be ignored. - if (m_pBinPack) { - QT3DSI32 paddedWith, paddedPitch, paddedHeight; - // add spacing around the character - paddedWith = width + 2 * m_Spacing; - paddedPitch = dataWidth + 2 * m_Spacing; - paddedHeight = height + 2 * m_Spacing; - // first get entry in the texture atlas - rect = m_pBinPack->Insert(paddedWith, paddedHeight); - if (rect.m_Width == 0) - return rect; - - // we align the data be to 4 byte - int alignment = (4 - (paddedPitch % 4)) % 4; - paddedPitch += alignment; - - // since we do spacing around the character we need to copy line by line - QT3DSU8 *glyphBuffer = - (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), - paddedHeight * paddedPitch * sizeof(QT3DSU8), "STextureAtlas"); - if (glyphBuffer) { - memset(glyphBuffer, 0, paddedHeight * paddedPitch); - - QT3DSU8 *pDst = glyphBuffer + paddedPitch + m_Spacing; - QT3DSU8 *pSrc = const_cast(bufferData.begin()); - for (QT3DSI32 i = 0; i < height; ++i) { - memcpy(pDst, pSrc, dataWidth); - - pDst += paddedPitch; - pSrc += pitch; - } - - // add new entry - m_AtlasEntrys.push_back(STextureAtlasEntry( - (QT3DSF32)rect.m_X, (QT3DSF32)rect.m_Y, (QT3DSF32)paddedWith, (QT3DSF32)paddedHeight, - NVDataRef(glyphBuffer, paddedHeight * paddedPitch * sizeof(QT3DSU8)))); - - // normalize texture coordinates - rect.m_NormX = (QT3DSF32)rect.m_X / (QT3DSF32)m_Width; - rect.m_NormY = (QT3DSF32)rect.m_Y / (QT3DSF32)m_Height; - rect.m_NormWidth = (QT3DSF32)paddedWith / (QT3DSF32)m_Width; - rect.m_NormHeight = (QT3DSF32)paddedHeight / (QT3DSF32)m_Height; - } - } - - return rect; - } - -private: - QT3DSI32 m_Width; ///< texture atlas width - QT3DSI32 m_Height; ///< texture atlas height - QT3DSI32 m_Spacing; ///< spacing around the entry - nvvector m_AtlasEntrys; ///< our entries in the atlas - STextureAtlasBinPackSL *m_pBinPack; ///< our bin packer which actually does most of the work -}; - -} // namespace - -ITextureAtlas &ITextureAtlas::CreateTextureAtlas(NVFoundationBase &inFnd, - NVRenderContext &inRenderContext, QT3DSI32 width, - QT3DSI32 height) -{ - return *QT3DS_NEW(inFnd.getAllocator(), STextureAtlas)(inFnd, inRenderContext, width, height); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderThreadPool.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderThreadPool.cpp deleted file mode 100644 index 70499c62..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderThreadPool.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderThreadPool.h" -#include "foundation/Qt3DSThread.h" -#include "EASTL/utility.h" -#include "EASTL/list.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" - -using namespace qt3ds::render; - -namespace { -struct STask -{ - void *m_UserData; - TTaskFunction m_Function; - TTaskFunction m_CancelFunction; - QT3DSU64 m_Id; - TaskStates::Enum m_TaskState; - STask *m_NextTask; - STask *m_PreviousTask; - - STask(void *ud, TTaskFunction func, TTaskFunction cancelFunc, QT3DSU64 inId) - : m_UserData(ud) - , m_Function(func) - , m_CancelFunction(cancelFunc) - , m_Id(inId) - , m_TaskState(TaskStates::Queued) - , m_NextTask(NULL) - , m_PreviousTask(NULL) - { - } - STask() - : m_UserData(NULL) - , m_Function(NULL) - , m_CancelFunction(NULL) - , m_Id(0) - , m_TaskState(TaskStates::UnknownTask) - , m_NextTask(NULL) - , m_PreviousTask(NULL) - { - } - void CallFunction() - { - if (m_Function) - m_Function(m_UserData); - } - void Cancel() - { - if (m_CancelFunction) - m_CancelFunction(m_UserData); - } -}; - -struct STaskHeadOp -{ - STask *get(STask &inTask) { return inTask.m_PreviousTask; } - void set(STask &inTask, STask *inItem) { inTask.m_PreviousTask = inItem; } -}; - -struct STaskTailOp -{ - STask *get(STask &inTask) { return inTask.m_NextTask; } - void set(STask &inTask, STask *inItem) { inTask.m_NextTask = inItem; } -}; - -typedef InvasiveLinkedList TTaskList; - -class IInternalTaskManager -{ -protected: - virtual ~IInternalTaskManager() {} -public: - virtual STask GetNextTask() = 0; - virtual void TaskFinished(QT3DSU64 inId) = 0; -}; - -struct SThreadPoolThread : public Thread -{ - IInternalTaskManager &m_Mgr; - SThreadPoolThread(NVFoundationBase &foundation, IInternalTaskManager &inMgr) - : Thread(foundation) - , m_Mgr(inMgr) - { - } - void execute(void) override - { - setName("Qt3DSRender Thread manager thread"); - while (!quitIsSignalled()) { - STask task = m_Mgr.GetNextTask(); - if (task.m_Function) { - task.CallFunction(); - m_Mgr.TaskFinished(task.m_Id); - } - } - quit(); - } -}; - -struct SThreadPool : public IThreadPool, public IInternalTaskManager -{ - typedef nvhash_map TIdTaskMap; - typedef Mutex::ScopedLock TLockType; - typedef Pool TTaskPool; - - NVFoundationBase &m_Foundation; - volatile QT3DSI32 mRefCount; - nvvector m_Threads; - TIdTaskMap m_Tasks; - Sync m_TaskListEvent; - volatile bool m_Running; - Mutex m_TaskListMutex; - TTaskPool m_TaskPool; - TTaskList m_TaskList; - - QT3DSU64 m_NextId; - - SThreadPool(NVFoundationBase &inBase, QT3DSU32 inMaxThreads) - : m_Foundation(inBase) - , mRefCount(0) - , m_Threads(inBase.getAllocator(), "SThreadPool::m_Threads") - , m_Tasks(inBase.getAllocator(), "SThreadPool::m_Tasks") - , m_TaskListEvent(inBase.getAllocator()) - , m_Running(true) - , m_TaskListMutex(m_Foundation.getAllocator()) - , m_TaskPool(ForwardingAllocator(m_Foundation.getAllocator(), "SThreadPool::m_TaskPool")) - , m_NextId(1) - { - // Fire up our little pools of chaos. - for (QT3DSU32 idx = 0; idx < inMaxThreads; ++idx) { - m_Threads.push_back( - QT3DS_NEW(m_Foundation.getAllocator(), SThreadPoolThread)(m_Foundation, *this)); - m_Threads.back()->start(Thread::DEFAULT_STACK_SIZE); - } - } - - void MutexHeldRemoveTaskFromList(STask *theTask) - { - if (theTask) - m_TaskList.remove(*theTask); - QT3DS_ASSERT(theTask->m_NextTask == NULL); - QT3DS_ASSERT(theTask->m_PreviousTask == NULL); - } - - STask *MutexHeldNextTask() - { - STask *theTask = m_TaskList.front_ptr(); - if (theTask) { - MutexHeldRemoveTaskFromList(theTask); - } - if (theTask) { - QT3DS_ASSERT(m_TaskList.m_Head != theTask); - QT3DS_ASSERT(m_TaskList.m_Tail != theTask); - } - return theTask; - } - - virtual ~SThreadPool() - { - m_Running = false; - - m_TaskListEvent.set(); - - for (QT3DSU32 idx = 0, end = m_Threads.size(); idx < end; ++idx) - m_Threads[idx]->signalQuit(); - - for (QT3DSU32 idx = 0, end = m_Threads.size(); idx < end; ++idx) { - m_Threads[idx]->waitForQuit(); - NVDelete(m_Foundation.getAllocator(), m_Threads[idx]); - } - - m_Threads.clear(); - - TLockType __listMutexLocker(m_TaskListMutex); - - for (STask *theTask = MutexHeldNextTask(); theTask; theTask = MutexHeldNextTask()) { - theTask->Cancel(); - } - - m_Tasks.clear(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void VerifyTaskList() - { - STask *theLastTask = NULL; - for (STask *theTask = m_TaskList.m_Head; theTask; theTask = theTask->m_NextTask) { - QT3DS_ASSERT(theTask->m_PreviousTask == theLastTask); - theLastTask = theTask; - } - theLastTask = NULL; - for (STask *theTask = m_TaskList.m_Tail; theTask; theTask = theTask->m_PreviousTask) { - QT3DS_ASSERT(theTask->m_NextTask == theLastTask); - theLastTask = theTask; - } - } - - QT3DSU64 AddTask(void *inUserData, TTaskFunction inFunction, - TTaskFunction inCancelFunction) override - { - if (inFunction && m_Running) { - TLockType __listMutexLocker(m_TaskListMutex); - QT3DSU64 taskId = m_NextId; - ++m_NextId; - - STask *theTask = (STask *)m_TaskPool.allocate(__FILE__, __LINE__); - new (theTask) STask(inUserData, inFunction, inCancelFunction, taskId); - TIdTaskMap::iterator theTaskIter = - m_Tasks.insert(eastl::make_pair(taskId, theTask)).first; - - m_TaskList.push_back(*theTask); - QT3DS_ASSERT(m_TaskList.m_Tail == theTask); - -#ifdef _DEBUG - VerifyTaskList(); -#endif - m_TaskListEvent.set(); - m_TaskListEvent.reset(); - return taskId; - } - QT3DS_ASSERT(false); - return 0; - } - - TaskStates::Enum GetTaskState(QT3DSU64 inTaskId) override - { - TLockType __listMutexLocker(m_TaskListMutex); - TIdTaskMap::iterator theTaskIter = m_Tasks.find(inTaskId); - if (theTaskIter != m_Tasks.end()) - return theTaskIter->second->m_TaskState; - return TaskStates::UnknownTask; - } - - CancelReturnValues::Enum CancelTask(QT3DSU64 inTaskId) override - { - TLockType __listMutexLocker(m_TaskListMutex); - TIdTaskMap::iterator theTaskIter = m_Tasks.find(inTaskId); - if (theTaskIter == m_Tasks.end()) - return CancelReturnValues::TaskCanceled; - if (theTaskIter->second->m_TaskState == TaskStates::Running) - return CancelReturnValues::TaskRunning; - - STask *theTask = theTaskIter->second; - theTask->Cancel(); - MutexHeldRemoveTaskFromList(theTask); - m_Tasks.erase(inTaskId); - m_TaskPool.deallocate(theTask); - - return CancelReturnValues::TaskCanceled; - } - - STask GetNextTask() override - { - - if (m_Running) { - { - TLockType __listMutexLocker(m_TaskListMutex); - STask *retval = MutexHeldNextTask(); - if (retval) - return *retval; - } - // If we couldn't get a task then wait. - m_TaskListEvent.wait(1000); - } - return STask(); - } - - void TaskFinished(QT3DSU64 inId) override - { - TLockType __listMutexLocker(m_TaskListMutex); - TIdTaskMap::iterator theTaskIter = m_Tasks.find(inId); - if (theTaskIter == m_Tasks.end()) { - QT3DS_ASSERT(false); - return; - } - - STask *theTask(theTaskIter->second); - -#ifdef _DEBUG - QT3DS_ASSERT(theTask->m_NextTask == NULL); - QT3DS_ASSERT(theTask->m_PreviousTask == NULL); -#endif - m_TaskPool.deallocate(theTask); - m_Tasks.erase(inId); - return; - } -}; -} - -IThreadPool &IThreadPool::CreateThreadPool(NVFoundationBase &inFoundation, QT3DSU32 inNumThreads) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SThreadPool)(inFoundation, inNumThreads); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp deleted file mode 100644 index f64efbcc..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp +++ /dev/null @@ -1,2065 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifdef QT3DS_RENDER_ENABLE_LOAD_UIP - -#include "Qt3DSRenderUIPLoader.h" -#include "Qt3DSRenderPresentation.h" -#include "Qt3DSRenderNode.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderModel.h" -#include "Qt3DSRenderDefaultMaterial.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderUIPSharedTranslation.h" -#include -#include -#include -#ifdef EA_PLATFORM_WINDOWS -#pragma warning(disable : 4201) -#endif -#include "Qt3DSDMXML.h" -#include "Qt3DSTypes.h" -#include "Qt3DSVector3.h" -#include "Qt3DSMetadata.h" -#include "Qt3DSDMWStrOps.h" -#include "Qt3DSDMWStrOpsImpl.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSDMComposerTypeDefinitions.h" -#include "EASTL/string.h" -#include "foundation/StrConvertUTF.h" -#include "Qt3DSRenderEffectSystem.h" -#include "Qt3DSRenderString.h" -#include "foundation/FileTools.h" -#include "Qt3DSRenderDynamicObjectSystemCommands.h" -#include "EASTL/map.h" -#include "Qt3DSRenderEffect.h" -#include "Qt3DSDMMetaDataTypes.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderPluginGraphObject.h" -#include "Qt3DSRenderPluginPropertyValue.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderMaterialHelpers.h" -#include "Qt3DSRenderPath.h" -#include "Qt3DSRenderPathSubPath.h" -#include "Qt3DSRenderPathManager.h" -#include "q3dsvariantconfig_p.h" - -using qt3ds::foundation::Option; -using qt3ds::foundation::Empty; -using qt3ds::QT3DSF32; -using qt3ds::QT3DSVec3; -using qt3ds::foundation::nvvector; -using qt3ds::QT3DSU32; -using qt3ds::render::RenderLightTypes; -using qt3ds::render::DefaultMaterialLighting; -using qt3ds::render::ImageMappingModes; -using qt3ds::render::DefaultMaterialBlendMode; -using qt3ds::render::NVRenderTextureCoordOp; -using qt3ds::foundation::IStringTable; -using qt3ds::NVFoundationBase; -using namespace qt3ds; -using namespace qt3ds::foundation; -using qt3ds::render::TIdObjectMap; -using qt3ds::render::IBufferManager; -using qt3ds::render::IEffectSystem; -using qt3ds::render::SPresentation; -using qt3ds::render::SScene; -using qt3ds::render::SLayer; -using qt3ds::render::SNode; -using qt3ds::render::SLight; -using qt3ds::render::SCamera; -using qt3ds::render::SModel; -using qt3ds::render::SText; -using qt3ds::render::SDefaultMaterial; -using qt3ds::render::SImage; -using qt3ds::render::SGraphObject; -using qt3ds::render::SDynamicObject; -using qt3ds::render::SEffect; -using qt3ds::render::SCustomMaterial; -using qt3ds::render::GraphObjectTypes; -using qt3ds::render::NodeFlags; -using qt3ds::foundation::CRegisteredString; -using qt3ds::render::CRenderString; -using qt3ds::foundation::CFileTools; -using qt3ds::render::SReferencedMaterial; -using qt3ds::render::IUIPReferenceResolver; -using qt3ds::render::SPath; -using qt3ds::render::SPathSubPath; -using qt3ds::render::SLightmaps; - -namespace qt3dsdm { -template <> -struct WStrOps -{ - void StrTo(const char8_t *buffer, SFloat2 &item, nvvector &ioTempBuf) - { - QT3DSU32 len = (QT3DSU32)strlen(buffer); - ioTempBuf.resize(len + 1); - memCopy(ioTempBuf.data(), buffer, (len + 1) * sizeof(char8_t)); - MemoryBuffer unused; - qt3dsdm::IStringTable *theTable(NULL); - WCharTReader reader(ioTempBuf.begin(), unused, *theTable); - reader.ReadRef(NVDataRef(item.m_Floats, 2)); - } -}; - -template <> -struct WStrOps -{ - void StrTo(const char8_t *buffer, SFloat3 &item, nvvector &ioTempBuf) - { - QT3DSU32 len = (QT3DSU32)strlen(buffer); - ioTempBuf.resize(len + 1); - memCopy(ioTempBuf.data(), buffer, (len + 1) * sizeof(char8_t)); - MemoryBuffer unused; - qt3dsdm::IStringTable *theTable(NULL); - WCharTReader reader(ioTempBuf.begin(), unused, *theTable); - reader.ReadRef(NVDataRef(item.m_Floats, 3)); - } -}; -} - -namespace { - -typedef eastl::basic_string TStrType; -struct IPropertyParser -{ - virtual ~IPropertyParser() {} - virtual Option ParseStr(const char8_t *inName) = 0; - virtual Option ParseFloat(const char8_t *inName) = 0; - virtual Option ParseVec2(const char8_t *inName) = 0; - virtual Option ParseVec3(const char8_t *inName) = 0; - virtual Option ParseBool(const char8_t *inName) = 0; - virtual Option ParseU32(const char8_t *inName) = 0; - virtual Option ParseI32(const char8_t *inName) = 0; - virtual Option ParseGraphObject(const char8_t *inName) = 0; - virtual Option ParseNode(const char8_t *inName) = 0; -}; -struct SMetaPropertyParser : public IPropertyParser -{ - Q3DStudio::IRuntimeMetaData &m_MetaData; - TStrType m_TempStr; - qt3ds::foundation::CRegisteredString m_Type; - qt3ds::foundation::CRegisteredString m_ClassId; - - SMetaPropertyParser(const char8_t *inType, const char8_t *inClass, - Q3DStudio::IRuntimeMetaData &inMeta) - : m_MetaData(inMeta) - , m_Type(inMeta.GetStringTable()->GetRenderStringTable().RegisterStr(inType)) - , m_ClassId(inMeta.GetStringTable()->GetRenderStringTable().RegisterStr(inClass)) - { - } - - qt3ds::foundation::CRegisteredString Register(const char8_t *inName) - { - return m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr(inName); - } - - Option ParseStr(const char8_t *inName) override - { - qt3ds::foundation::CRegisteredString theName(Register(inName)); - Q3DStudio::ERuntimeDataModelDataType theType( - m_MetaData.GetPropertyType(m_Type, theName, m_ClassId)); - if (theType != Q3DStudio::ERuntimeDataModelDataTypeObjectRef - && theType != Q3DStudio::ERuntimeDataModelDataTypeLong4) { - return m_MetaData.GetPropertyValueString(m_Type, theName, m_ClassId); - } - return Empty(); - } - Option ParseFloat(const char8_t *inName) override - { - return m_MetaData.GetPropertyValueFloat(m_Type, Register(inName), m_ClassId); - } - Option ParseVec2(const char8_t *inName) override - { - Option theProperty = - m_MetaData.GetPropertyValueVector2(m_Type, Register(inName), m_ClassId); - if (theProperty.hasValue()) { - return QT3DSVec2(theProperty->x, theProperty->y); - } - return Empty(); - } - Option ParseVec3(const char8_t *inName) override - { - Option theProperty = - m_MetaData.GetPropertyValueVector3(m_Type, Register(inName), m_ClassId); - if (theProperty.hasValue()) { - return *theProperty; - } - return Empty(); - } - Option ParseBool(const char8_t *inName) override - { - return m_MetaData.GetPropertyValueBool(m_Type, Register(inName), m_ClassId); - } - - Option ParseU32(const char8_t *inName) override - { - Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); - if (retval.hasValue()) - return (QT3DSU32)retval.getValue(); - return Empty(); - } - - Option ParseI32(const char8_t *inName) override - { - Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); - if (retval.hasValue()) - return (QT3DSI32)retval.getValue(); - return Empty(); - } - - Option ParseGraphObject(const char8_t *) override { return Empty(); } - Option ParseNode(const char8_t *) override { return Empty(); } -}; - -class IDOMReferenceResolver -{ -protected: - virtual ~IDOMReferenceResolver() {} -public: - virtual SGraphObject *ResolveReference(SGraphObject &inRootObject, const char *path) = 0; -}; - -struct SDomReaderPropertyParser : public IPropertyParser -{ - qt3dsdm::IDOMReader &m_Reader; - nvvector &m_TempBuf; - IDOMReferenceResolver &m_Resolver; - SGraphObject &m_Object; - - SDomReaderPropertyParser(qt3dsdm::IDOMReader &reader, nvvector &inTempBuf, - IDOMReferenceResolver &inResolver, SGraphObject &inObject) - : m_Reader(reader) - , m_TempBuf(inTempBuf) - , m_Resolver(inResolver) - , m_Object(inObject) - { - } - Option ParseStr(const char8_t *inName) override - { - const char8_t *retval; - if (m_Reader.Att(inName, retval)) - return TStrType(retval); - return Empty(); - } - Option ParseFloat(const char8_t *inName) override - { - QT3DSF32 retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - Option ParseVec2(const char8_t *inName) override - { - qt3dsdm::SFloat2 retval; - const char8_t *tempData; - if (m_Reader.UnregisteredAtt(inName, tempData)) { - qt3dsdm::WStrOps().StrTo(tempData, retval, m_TempBuf); - return QT3DSVec2(retval.m_Floats[0], retval.m_Floats[1]); - } - return Empty(); - } - Option ParseVec3(const char8_t *inName) override - { - qt3dsdm::SFloat3 retval; - const char8_t *tempData; - if (m_Reader.UnregisteredAtt(inName, tempData)) { - qt3dsdm::WStrOps().StrTo(tempData, retval, m_TempBuf); - return QT3DSVec3(retval.m_Floats[0], retval.m_Floats[1], retval.m_Floats[2]); - } - return Empty(); - } - Option ParseBool(const char8_t *inName) override - { - bool retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - - Option ParseU32(const char8_t *inName) override - { - QT3DSU32 retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - - Option ParseI32(const char8_t *inName) override - { - QT3DSI32 retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - - Option ParseGraphObject(const char8_t *inName) override - { - const char *temp; - if (m_Reader.UnregisteredAtt(inName, temp)) { - // Now we need to figure out if this is an element reference or if it is a relative path - // from the current element. - SGraphObject *retval = m_Resolver.ResolveReference(m_Object, temp); - if (retval) - return retval; - } - return Empty(); - } - - Option ParseNode(const char8_t *inName) override - { - Option obj = ParseGraphObject(inName); - if (obj.hasValue()) { - if (GraphObjectTypes::IsNodeType((*obj)->m_Type)) - return static_cast((*obj)); - } - return Empty(); - } -}; - -template -struct SParserHelper -{ -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseStr(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseFloat(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseVec2(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseVec3(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseBool(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseU32(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseI32(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseGraphObject(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseNode(inName); - } -}; - -struct SPathAndAnchorIndex -{ - SPathSubPath *m_Segment; - QT3DSU32 m_AnchorIndex; - SPathAndAnchorIndex(SPathSubPath *inSegment, QT3DSU32 inAnchorIndex) - : m_Segment(inSegment) - , m_AnchorIndex(inAnchorIndex) - { - } - SPathAndAnchorIndex() - : m_Segment(NULL) - , m_AnchorIndex(0) - { - } -}; - -struct SRenderUIPLoader : public IDOMReferenceResolver -{ - typedef qt3dsdm::IDOMReader::Scope TScope; - typedef eastl::map TIdStringMap; - typedef eastl::hash_map TIdPathAnchorIndexMap; - qt3dsdm::IDOMReader &m_Reader; - Q3DStudio::IRuntimeMetaData &m_MetaData; - IStringTable &m_StrTable; - NVFoundationBase &m_Foundation; - NVAllocatorCallback &m_PresentationAllocator; - qt3ds::render::TIdObjectMap &m_ObjectMap; - IBufferManager &m_BufferManager; - SPresentation *m_Presentation; - nvvector m_TempBuf; - TStrType m_TempParseString; - IEffectSystem &m_EffectSystem; - const char8_t *m_PresentationDir; - CRenderString m_PathString; - qt3ds::render::IRenderPluginManager &m_RenderPluginManager; - qt3ds::render::ICustomMaterialSystem &m_CustomMaterialSystem; - qt3ds::render::IDynamicObjectSystem &m_DynamicObjectSystem; - qt3ds::render::IPathManager &m_PathManager; - TIdStringMap m_RenderPluginSourcePaths; - IUIPReferenceResolver *m_ReferenceResolver; - MemoryBuffer m_TempBuffer; - MemoryBuffer m_ValueBuffer; - TIdPathAnchorIndexMap m_AnchorIdToPathAndAnchorIndexMap; - const Q3DSVariantConfig &m_variantConfig; - - SRenderUIPLoader(qt3dsdm::IDOMReader &inReader, const char8_t *inFullPathToPresentationFile, - Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable - // Allocator for datastructures we need to parse the file. - , - NVFoundationBase &inFoundation - // Allocator used for the presentation objects themselves - , - NVAllocatorCallback &inPresentationAllocator - // Map of string ids to objects - , - TIdObjectMap &ioObjectMap, IBufferManager &inBufferManager, - IEffectSystem &inEffectSystem, const char8_t *inPresentationDir, - qt3ds::render::IRenderPluginManager &inRPM, - qt3ds::render::ICustomMaterialSystem &inCMS, - qt3ds::render::IDynamicObjectSystem &inDynamicSystem, - qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver, - const Q3DSVariantConfig &variantConfig) - : m_Reader(inReader) - , m_MetaData(inMetaData) - , m_StrTable(inStrTable) - , m_Foundation(inFoundation) - , m_PresentationAllocator(inPresentationAllocator) - , m_ObjectMap(ioObjectMap) - , m_BufferManager(inBufferManager) - , m_Presentation(QT3DS_NEW(inPresentationAllocator, SPresentation)()) - , m_TempBuf(inFoundation.getAllocator(), "SRenderUIPLoader::m_TempBuf") - , m_EffectSystem(inEffectSystem) - , m_PresentationDir(inPresentationDir) - , m_RenderPluginManager(inRPM) - , m_CustomMaterialSystem(inCMS) - , m_DynamicObjectSystem(inDynamicSystem) - , m_PathManager(inPathManager) - , m_ReferenceResolver(inResolver) - , m_variantConfig(variantConfig) - { - std::string presentationFile = inFullPathToPresentationFile; - std::string::size_type pos = presentationFile.find_last_of("\\/"); - if (pos != std::string::npos) { - std::string path = presentationFile.substr(0, pos); - m_Presentation->m_PresentationDirectory = inStrTable.RegisterStr(path.c_str()); - } - } - - SGraphObject *ResolveReference(SGraphObject &inRoot, const char *path) override - { - if (m_ReferenceResolver) { - CRegisteredString resolvedReference = - m_ReferenceResolver->ResolveReference(inRoot.m_Id, path); - if (resolvedReference.IsValid()) { - qt3ds::render::TIdObjectMap::iterator iter = m_ObjectMap.find(resolvedReference); - if (iter != m_ObjectMap.end()) - return iter->second; - } - } - return NULL; - } - - static bool IsNode(GraphObjectTypes::Enum inType) - { - return GraphObjectTypes::IsNodeType(inType); - } - template - bool ParseProperty(IPropertyParser &inParser, const char8_t *inName, TDataType &outData) - { - Option theValue(SParserHelper::Parse(inName, inParser)); - if (theValue.hasValue()) { - outData = theValue; - return true; - } - return false; - } - bool ParseOpacityProperty(IPropertyParser &inParser, const char8_t *inName, QT3DSF32 &outOpacity) - { - if (ParseProperty(inParser, inName, outOpacity)) { - outOpacity /= 100.0f; - return true; - } - return false; - } - - bool ParseRadianProperty(IPropertyParser &inParser, const char8_t *inName, QT3DSVec3 &ioRotation) - { - if (ParseProperty(inParser, inName, ioRotation)) { - TORAD(ioRotation.x); - TORAD(ioRotation.y); - TORAD(ioRotation.z); - return true; - } - return false; - } - bool ParseRadianProperty(IPropertyParser &inParser, const char8_t *inName, QT3DSF32 &ioRotation) - { - if (ParseProperty(inParser, inName, ioRotation)) { - TORAD(ioRotation); - return true; - } - return false; - } - - void ParseRotationOrder(IPropertyParser &inParser, const char8_t *inName, - QT3DSU32 &ioRotationOrder) - { - if (ParseProperty(inParser, inName, m_TempParseString)) - ioRotationOrder = qt3ds::render::MapRotationOrder(m_TempParseString.c_str()); - } - void ParseOrientation(IPropertyParser &inParser, const char8_t *inName, NodeFlags &ioFlags) - { - if (ParseProperty(inParser, inName, m_TempParseString)) { - if (m_TempParseString == "Left Handed") - ioFlags.SetLeftHanded(true); - else - ioFlags.SetLeftHanded(false); - } - } - void ParseOrthographicProperty(IPropertyParser &inParser, const char8_t *inName, - NodeFlags &ioFlags) - { - bool isOrthographic; - if (ParseProperty(inParser, inName, isOrthographic)) - ioFlags.SetOrthographic(isOrthographic); - } - template - static bool ConvertEnumFromStr(const char8_t *inStr, TEnumType &ioEnum) - { - qt3ds::render::SEnumNameMap *theMap = qt3ds::render::SEnumParseMap::GetMap(); - for (qt3ds::render::SEnumNameMap *item = theMap; item->m_Name; ++item) { - // hack to match advanced overlay types, whose name start with a '*' - const char8_t *p = inStr; - if (*p == '*') - ++p; - if (qt3dsdm::AreEqual(p, item->m_Name)) { - ioEnum = static_cast(item->m_Enum); - return true; - } - } - return false; - } - - template - void ParseEnumProperty(IPropertyParser &inParser, const char8_t *inName, TEnumType &ioEnum) - { - if (ParseProperty(inParser, inName, m_TempParseString)) { - ConvertEnumFromStr(m_TempParseString.c_str(), ioEnum); - } - } - void ParseAndResolveSourcePath(IPropertyParser &inParser, const char8_t *inName, - CRegisteredString &ioString) - { - if (ParseProperty(inParser, inName, m_TempParseString)) - ioString = m_StrTable.RegisterStr(m_TempParseString.c_str()); - } - void ParseProperty(IPropertyParser &inParser, const char8_t *inName, SImage *&ioImage) - { - if (ParseProperty(inParser, inName, m_TempParseString)) { - TIdObjectMap::iterator theIter = - m_ObjectMap.find(m_StrTable.RegisterStr(m_TempParseString.c_str() + 1)); - if (theIter != m_ObjectMap.end() - && theIter->second->m_Type == GraphObjectTypes::Image) { - ioImage = static_cast(theIter->second); - } else { - QT3DS_ASSERT(false); - } - } - } - void ParseProperty(IPropertyParser &inParser, const char8_t *inName, CRegisteredString &ioStr) - { - if (ParseProperty(inParser, inName, m_TempParseString)) - ioStr = m_StrTable.RegisterStr(m_TempParseString.c_str()); - } - - void ParseNodeFlagsProperty(IPropertyParser &inParser, const char8_t *inName, - qt3ds::render::NodeFlags &ioFlags, - qt3ds::render::NodeFlagValues::Enum prop) - { - bool temp; - if (ParseProperty(inParser, inName, temp)) - ioFlags.ClearOrSet(temp, prop); - } - - void ParseNodeFlagsInverseProperty(IPropertyParser &inParser, const char8_t *inName, - qt3ds::render::NodeFlags &ioFlags, - qt3ds::render::NodeFlagValues::Enum prop) - { - bool temp; - if (ParseProperty(inParser, inName, temp)) - ioFlags.ClearOrSet(!temp, prop); - } - -// Create a mapping from UICRenderPropertyNames to the string in the UIP file. -#define Scene_ClearColor "backgroundcolor" -#define Scene_UseClearColor "bgcolorenable" -#define Node_Rotation "rotation" -#define Node_Position "position" -#define Node_Scale "scale" -#define Node_Pivot "pivot" -#define Node_LocalOpacity "opacity" -#define Node_RotationOrder "rotationorder" -#define Node_LeftHanded "orientation" -#define Layer_Variants "variants" -#define Layer_TemporalAAEnabled "temporalaa" -#define Layer_LayerEnableDepthTest "disabledepthtest" -#define Layer_LayerEnableDepthPrePass "disabledepthprepass" -#define Layer_ClearColor "backgroundcolor" -#define Layer_Background "background" -#define Layer_BlendType "blendtype" -#define Layer_Size "size" -#define Layer_Location "location" -#define Layer_TexturePath "sourcepath" -#define Layer_HorizontalFieldValues "horzfields" -#define Layer_Left "left" -#define Layer_LeftUnits "leftunits" -#define Layer_Width "width" -#define Layer_WidthUnits "widthunits" -#define Layer_Right "right" -#define Layer_RightUnits "rightunits" -#define Layer_VerticalFieldValues "vertfields" -#define Layer_Top "top" -#define Layer_TopUnits "topunits" -#define Layer_Height "height" -#define Layer_HeightUnits "heightunits" -#define Layer_Bottom "bottom" -#define Layer_BottomUnits "bottomunits" -#define Layer_AoStrength "aostrength" -#define Layer_AoDistance "aodistance" -#define Layer_AoSoftness "aosoftness" -#define Layer_AoBias "aobias" -#define Layer_AoSamplerate "aosamplerate" -#define Layer_AoDither "aodither" -#define Layer_ShadowStrength "shadowstrength" -#define Layer_ShadowDist "shadowdist" -#define Layer_ShadowSoftness "shadowsoftness" -#define Layer_ShadowBias "shadowbias" -#define Layer_LightProbe "lightprobe" -#define Layer_ProbeBright "probebright" -#define Layer_FastIbl "fastibl" -#define Layer_ProbeHorizon "probehorizon" -#define Layer_ProbeFov "probefov" -#define Layer_LightProbe2 "lightprobe2" -#define Layer_Probe2Fade "probe2fade" -#define Layer_Probe2Window "probe2window" -#define Layer_Probe2Pos "probe2pos" -#define Camera_ClipNear "clipnear" -#define Camera_ClipFar "clipfar" -#define Camera_FOV "fov" -#define Camera_FOVHorizontal "fovhorizontal" -#define Camera_Orthographic "orthographic" -#define Camera_ScaleMode "scalemode" -#define Camera_ScaleAnchor "scaleanchor" -#define Light_LightType "lighttype" -#define Light_DiffuseColor "lightdiffuse" -#define Light_SpecularColor "lightspecular" -#define Light_AmbientColor "lightambient" -#define Light_Brightness "brightness" -#define Light_LinearFade "linearfade" -#define Light_ExponentialFade "expfade" -#define Light_AreaWidth "areawidth" -#define Light_AreaHeight "areaheight" -#define Light_CastShadow "castshadow" -#define Light_ShadowBias "shdwbias" -#define Light_ShadowFactor "shdwfactor" -#define Light_ShadowMapRes "shdwmapres" -#define Light_ShadowMapFar "shdwmapfar" -#define Light_ShadowMapFov "shdwmapfov" -#define Light_ShadowFilter "shdwfilter" -#define Model_MeshPath "sourcepath" -#define Model_ShadowCaster "shadowcaster" -#define Model_TessellationMode "tessellation" -#define Model_EdgeTess "edgetess" -#define Model_InnerTess "innertess" -#define Lightmaps_LightmapIndirect "lightmapindirect" -#define Lightmaps_LightmapRadiosity "lightmapradiosity" -#define Lightmaps_LightmapShadow "lightmapshadow" -#define Material_Lighting "shaderlighting" -#define Material_BlendMode "blendmode" -#define MaterialBase_IblProbe "iblprobe" -#define Material_DiffuseColor "diffuse" -#define Material_DiffuseMaps_0 "diffusemap" -#define Material_DiffuseMaps_1 "diffusemap2" -#define Material_DiffuseMaps_2 "diffusemap3" -#define Material_EmissivePower "emissivepower" -#define Material_EmissiveColor "emissivecolor" -#define Material_EmissiveMap "emissivemap" -#define Material_EmissiveMap2 "emissivemap2" -#define Material_SpecularReflection "specularreflection" -#define Material_SpecularMap "specularmap" -#define Material_SpecularModel "specularmodel" -#define Material_SpecularTint "speculartint" -#define Material_IOR "ior" -#define Material_FresnelPower "fresnelPower" -#define Material_SpecularAmount "specularamount" -#define Material_SpecularRoughness "specularroughness" -#define Material_RoughnessMap "roughnessmap" -#define Material_Opacity "opacity" -#define Material_OpacityMap "opacitymap" -#define Material_BumpMap "bumpmap" -#define Material_BumpAmount "bumpamount" -#define Material_NormalMap "normalmap" -#define Material_DisplacementMap "displacementmap" -#define Material_DisplaceAmount "displaceamount" -#define Material_TranslucencyMap "translucencymap" -#define Material_TranslucentFalloff "translucentfalloff" -#define Material_DiffuseLightWrap "diffuselightwrap" -#define Material_ReferencedMaterial "referencedmaterial" -#define Material_VertexColors "vertexcolors" -#define Image_ImagePath "sourcepath" -#define Image_OffscreenRendererId "subpresentation" -#define Image_Scale_X "scaleu" -#define Image_Scale_Y "scalev" -#define Image_Pivot_X "pivotu" -#define Image_Pivot_Y "pivotv" -#define Image_Rotation "rotationuv" -#define Image_Position_X "positionu" -#define Image_Position_Y "positionv" -#define Image_MappingMode "mappingmode" -#define Image_HorizontalTilingMode "tilingmodehorz" -#define Image_VerticalTilingMode "tilingmodevert" -#define Text_Text "textstring" -#define Text_Font "font" -#define Text_FontSize "size" -#define Text_HorizontalAlignment "horzalign" -#define Text_VerticalAlignment "vertalign" -#define Text_Leading "leading" -#define Text_Tracking "tracking" -#define Text_DropShadow "dropshadow" -#define Text_DropShadowStrength "dropshadowstrength" -#define Text_DropShadowOffset "dropshadowoffset" // To be removed in 2.x (when UIP version is next updated) -#define Text_DropShadowOffsetX "dropshadowoffsetx" -#define Text_DropShadowOffsetY "dropshadowoffsety" -#define Text_DropShadowHorizontalAlignment "dropshadowhorzalign" // To be removed in 2.x (when UIP version is next updated) -#define Text_DropShadowVerticalAlignment "dropshadowvertalign" // To be removed in 2.x (when UIP version is next updated) -#define Text_WordWrap "wordwrap" -#define Text_BoundingBox "boundingbox" -#define Text_Elide "elide" -#define Text_TextColor "textcolor" -#define Text_BackColor "backcolor" -#define Text_EnableAcceleratedFont "enableacceleratedfont" -#define Layer_ProgressiveAAMode "progressiveaa" -#define Layer_MultisampleAAMode "multisampleaa" -#define Light_Scope "scope" -#define Path_PathType "pathtype" -#define Path_PaintStyle "paintstyle" -#define Path_Width "width" -#define Path_Opacity "opacity" -#define Path_LinearError "linearerror" -#define Path_EdgeTessAmount "edgetessamount" -#define Path_InnerTessAmount "innertessamount" -#define Path_BeginCapping "begincap" -#define Path_BeginCapOffset "begincapoffset" -#define Path_BeginCapOpacity "begincapopacity" -#define Path_BeginCapWidth "begincapwidth" -#define Path_EndCapping "endcap" -#define Path_EndCapOffset "endcapoffset" -#define Path_EndCapOpacity "endcapopacity" -#define Path_EndCapWidth "endcapwidth" -#define Path_PathBuffer "sourcepath" -#define SubPath_Closed "closed" - -// Fill in implementations for the actual parse tables. -#define HANDLE_QT3DS_RENDER_PROPERTY(type, name, dirty) \ - ParseProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_REAL_VEC2_PROPERTY(type, name, dirty) \ - ParseProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_VEC3_PROPERTY(type, name, dirty) \ - ParseProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_COLOR_PROPERTY(type, name, dirty) \ - ParseProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(type, name, dirty) \ - ParseRadianProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_VEC3_RADIAN_PROPERTY(type, name, dirty) \ - ParseRadianProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(type, name, dirty) \ - ParseOpacityProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_ROTATION_ORDER_PROPERTY(type, name, dirty) \ - ParseRotationOrder(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY(type, name, dirty) \ - ParseOrientation(inParser, type##_##name, inItem.m_Flags); -#define HANDLE_QT3DS_RENDER_DEPTH_TEST_PROPERTY(type, name, dirty) \ - if (ParseProperty(inParser, type##_##name, inItem.m_##name)) \ - inItem.m_##name = !inItem.m_##name; -#define HANDLE_QT3DS_NODE_FLAGS_PROPERTY(type, name, dirty) \ - ParseNodeFlagsProperty(inParser, type##_##name, inItem.m_Flags, \ - qt3ds::render::NodeFlagValues::name); -#define HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(type, name, dirty) \ - ParseNodeFlagsInverseProperty(inParser, type##_##name, inItem.m_Flags, \ - qt3ds::render::NodeFlagValues::name); -#define HANDLE_QT3DS_RENDER_ENUM_PROPERTY(type, name, dirty) \ - ParseEnumProperty(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(type, name, dirty) \ - ParseAndResolveSourcePath(inParser, type##_##name, inItem.m_##name); -#define HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(type, name, index, dirty) \ - ParseProperty(inParser, type##_##name##_##index, inItem.m_##name[index]); -#define HANDLE_QT3DS_RENDER_VEC2_PROPERTY(type, name, dirty) \ - ParseProperty(inParser, type##_##name##_##X, inItem.m_##name.x); \ - ParseProperty(inParser, type##_##name##_##Y, inItem.m_##name.y); -#define HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY( \ - type, name, dirty) // noop by intention already handled by HANDLE_QT3DS_RENDER_COLOR_PROPERTY -#define HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY( \ - type, name, dirty) // noop by intention already handled by HANDLE_QT3DS_RENDER_VEC3_PROPERTY - - // Call the correct parser functions. - void ParseProperties(SScene &inItem, IPropertyParser &inParser) - { - ITERATE_QT3DS_RENDER_SCENE_PROPERTIES - } - void ParseProperties(SNode &inItem, IPropertyParser &inParser) - { - bool eyeball; - if (ParseProperty(inParser, "eyeball", eyeball)) - inItem.m_Flags.SetActive(eyeball); - ITERATE_QT3DS_RENDER_NODE_PROPERTIES - ParseProperty(inParser, "boneid", inItem.m_SkeletonId); - bool ignoreParent = false; - if (ParseProperty(inParser, "ignoresparent", ignoreParent)) - inItem.m_Flags.SetIgnoreParentTransform(ignoreParent); - } - void ParseProperties(SLayer &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ITERATE_QT3DS_RENDER_LAYER_PROPERTIES - ParseProperty(inParser, "aosamplerate", inItem.m_AoSamplerate); - } - void ParseProperties(SCamera &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ITERATE_QT3DS_RENDER_CAMERA_PROPERTIES - } - void ParseProperties(SLight &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ITERATE_QT3DS_RENDER_LIGHT_PROPERTIES - ParseProperty(inParser, "shdwmapres", inItem.m_ShadowMapRes); - } - void ParseProperties(SModel &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ITERATE_QT3DS_RENDER_MODEL_PROPERTIES - ParseProperty(inParser, "poseroot", inItem.m_SkeletonRoot); - } - - void ParseProperties(SText &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ITERATE_QT3DS_RENDER_TEXT_PROPERTIES - } - void ParseProperties(SLightmaps &inItem, IPropertyParser &inParser) - { - ITERATE_QT3DS_RENDER_LIGHTMAP_PROPERTIES - } - void ParseProperties(SDefaultMaterial &inItem, IPropertyParser &inParser) - { - ITERATE_QT3DS_RENDER_MATERIAL_PROPERTIES - ParseProperties(inItem.m_Lightmaps, inParser); - } - void ParseProperties(SReferencedMaterial &inItem, IPropertyParser &inParser) - { - ITERATE_QT3DS_RENDER_REFERENCED_MATERIAL_PROPERTIES - // Propagate lightmaps - if (inItem.m_ReferencedMaterial - && inItem.m_ReferencedMaterial->m_Type == GraphObjectTypes::DefaultMaterial) - ParseProperties( - static_cast(inItem.m_ReferencedMaterial)->m_Lightmaps, - inParser); - else if (inItem.m_ReferencedMaterial - && inItem.m_ReferencedMaterial->m_Type == GraphObjectTypes::CustomMaterial) - ParseProperties( - static_cast(inItem.m_ReferencedMaterial)->m_Lightmaps, inParser); - } - void ParseProperties(SImage &inItem, IPropertyParser &inParser) - { - ITERATE_QT3DS_RENDER_IMAGE_PROPERTIES - } - template - void SetDynamicObjectProperty(SDynamicObject &inEffect, - const qt3ds::render::dynamic::SPropertyDefinition &inPropDesc, - const TDataType &inProp) - { - memCopy(inEffect.GetDataSectionBegin() + inPropDesc.m_Offset, &inProp, sizeof(TDataType)); - } - template - void SetDynamicObjectProperty(SDynamicObject &inEffect, - const qt3ds::render::dynamic::SPropertyDefinition &inPropDesc, - Option inProp) - { - if (inProp.hasValue()) { - SetDynamicObjectProperty(inEffect, inPropDesc, *inProp); - } - } - void ParseProperties(SCustomMaterial &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ParseProperties(inItem.m_Lightmaps, inParser); - ITERATE_QT3DS_RENDER_CUSTOM_MATERIAL_PROPERTIES - } - void ParseProperties(SDynamicObject &inDynamicObject, IPropertyParser &inParser) - { - NVConstDataRef theProperties = - m_DynamicObjectSystem.GetProperties(inDynamicObject.m_ClassName); - - for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { - const qt3ds::render::dynamic::SPropertyDefinition &theDefinition(theProperties[idx]); - switch (theDefinition.m_DataType) { - case qt3ds::render::NVRenderShaderDataTypes::QT3DSRenderBool: - SetDynamicObjectProperty(inDynamicObject, theDefinition, - inParser.ParseBool(theDefinition.m_Name)); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSF32: - SetDynamicObjectProperty(inDynamicObject, theDefinition, - inParser.ParseFloat(theDefinition.m_Name)); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSI32: - if (theDefinition.m_IsEnumProperty == false) - SetDynamicObjectProperty(inDynamicObject, theDefinition, - inParser.ParseU32(theDefinition.m_Name)); - else { - Option theEnum = inParser.ParseStr(theDefinition.m_Name); - if (theEnum.hasValue()) { - NVConstDataRef theEnumNames = - theDefinition.m_EnumValueNames; - for (QT3DSU32 idx = 0, end = theEnumNames.size(); idx < end; ++idx) { - if (theEnum->compare(theEnumNames[idx].c_str()) == 0) { - SetDynamicObjectProperty(inDynamicObject, theDefinition, idx); - break; - } - } - } - } - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec3: - SetDynamicObjectProperty(inDynamicObject, theDefinition, - inParser.ParseVec3(theDefinition.m_Name)); - break; - case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec2: - SetDynamicObjectProperty(inDynamicObject, theDefinition, - inParser.ParseVec2(theDefinition.m_Name)); - break; - case qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr: - case qt3ds::render::NVRenderShaderDataTypes::NVRenderImage2DPtr: { - Option theTexture = inParser.ParseStr(theDefinition.m_Name); - if (theTexture.hasValue()) { - CRegisteredString theStr; - if (theTexture->size()) - theStr = m_StrTable.RegisterStr(theTexture->c_str()); - - SetDynamicObjectProperty(inDynamicObject, theDefinition, theStr); - } - } break; - case qt3ds::render::NVRenderShaderDataTypes::NVRenderDataBufferPtr: - break; - default: - QT3DS_ASSERT(false); - break; - } - } - } - void ParseProperties(SPath &inItem, IPropertyParser &inParser) - { - ParseProperties(static_cast(inItem), inParser); - ITERATE_QT3DS_RENDER_PATH_PROPERTIES - } - void ParseProperties(SPathSubPath &inItem, IPropertyParser &inParser) - { - ITERATE_QT3DS_RENDER_PATH_SUBPATH_PROPERTIES - } - - void AddPluginPropertyUpdate(eastl::vector &ioUpdates, - qt3ds::render::IRenderPluginClass &, - const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, - Option data) - { - if (data.hasValue()) { - ioUpdates.push_back( - qt3ds::render::SRenderPropertyValueUpdate(inDeclaration.m_Name, *data)); - } - } - void AddPluginPropertyUpdate(eastl::vector &ioUpdates, - qt3ds::render::IRenderPluginClass &inClass, - const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, - Option data) - { - if (data.hasValue()) { - ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( - inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset).first, data->x)); - ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( - inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset + 1).first, data->y)); - } - } - void AddPluginPropertyUpdate(eastl::vector &ioUpdates, - qt3ds::render::IRenderPluginClass &inClass, - const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, - Option data) - { - if (data.hasValue()) { - ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( - inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset).first, data->x)); - ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( - inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset + 1).first, data->y)); - ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( - inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset + 2).first, data->z)); - } - } - void AddPluginPropertyUpdate(eastl::vector &ioUpdates, - qt3ds::render::IRenderPluginClass &, - const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, - Option dataOpt) - { - if (dataOpt.hasValue()) { - long data = static_cast(*dataOpt); - ioUpdates.push_back( - qt3ds::render::SRenderPropertyValueUpdate(inDeclaration.m_Name, (QT3DSI32)data)); - } - } - void AddPluginPropertyUpdate(eastl::vector &ioUpdates, - qt3ds::render::IRenderPluginClass &, - const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, - Option dataOpt) - { - if (dataOpt.hasValue()) { - eastl::string &data = dataOpt.getValue(); - ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( - inDeclaration.m_Name, m_StrTable.RegisterStr(data.c_str()))); - } - } - void AddPluginPropertyUpdate(eastl::vector &ioUpdates, - qt3ds::render::IRenderPluginClass &, - const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, - Option dataOpt) - { - if (dataOpt.hasValue()) { - bool &data = dataOpt.getValue(); - ioUpdates.push_back( - qt3ds::render::SRenderPropertyValueUpdate(inDeclaration.m_Name, data)); - } - } - void ParseProperties(qt3ds::render::SRenderPlugin &inRenderPlugin, IPropertyParser &inParser) - { - qt3ds::render::IRenderPluginClass *theClass = - m_RenderPluginManager.GetRenderPlugin(inRenderPlugin.m_PluginPath); - if (theClass) { - qt3ds::foundation::NVConstDataRef - theClassProps = theClass->GetRegisteredProperties(); - if (theClassProps.size()) { - qt3ds::render::IRenderPluginInstance *theInstance = - m_RenderPluginManager.GetOrCreateRenderPluginInstance( - inRenderPlugin.m_PluginPath, &inRenderPlugin); - if (theInstance) { - eastl::vector theUpdates; - for (QT3DSU32 idx = 0, end = theClassProps.size(); idx < end; ++idx) { - const qt3ds::render::SRenderPluginPropertyDeclaration &theDec( - theClassProps[idx]); - eastl::string tempStr; - switch (theDec.m_Type) { - case qt3ds::render::SRenderPluginPropertyTypes::Float: - AddPluginPropertyUpdate(theUpdates, *theClass, theDec, - inParser.ParseFloat(theDec.m_Name.c_str())); - break; - case qt3ds::render::SRenderPluginPropertyTypes::Vector2: - AddPluginPropertyUpdate(theUpdates, *theClass, theDec, - inParser.ParseVec2(theDec.m_Name.c_str())); - break; - case qt3ds::render::SRenderPluginPropertyTypes::Color: - case qt3ds::render::SRenderPluginPropertyTypes::Vector3: - AddPluginPropertyUpdate(theUpdates, *theClass, theDec, - inParser.ParseVec3(theDec.m_Name.c_str())); - break; - case qt3ds::render::SRenderPluginPropertyTypes::Long: - AddPluginPropertyUpdate(theUpdates, *theClass, theDec, - inParser.ParseI32(theDec.m_Name.c_str())); - break; - case qt3ds::render::SRenderPluginPropertyTypes::String: - AddPluginPropertyUpdate(theUpdates, *theClass, theDec, - inParser.ParseStr(theDec.m_Name.c_str())); - break; - case qt3ds::render::SRenderPluginPropertyTypes::Boolean: - AddPluginPropertyUpdate(theUpdates, *theClass, theDec, - inParser.ParseBool(theDec.m_Name.c_str())); - break; - default: - QT3DS_ASSERT(false); - } - } - theInstance->Update( - qt3ds::foundation::toConstDataRef(theUpdates.data(), theUpdates.size())); - } - } - } - } - -#undef HANDLE_QT3DS_RENDER_PROPERTY -#undef HANDLE_QT3DS_RENDER_ENUM_PROPERTY -#undef HANDLE_QT3DS_RENDER_RADIAN_PROPERTY -#undef HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY -#undef HANDLE_QT3DS_RENDER_ARRAY_PROPERTY -#undef HANDLE_QT3DS_NODE_FLAGS_PROPERTY -#undef HANDLE_QT3DS_ROTATION_ORDER_PROPERTY -#undef HANDLE_QT3DS_RENDER_OPACITY_PROPERTY -#undef HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY -#undef HANDLE_QT3DS_RENDER_DEPTH_TEST_PROPERTY -#undef HANDLE_QT3DS_RENDER_VEC2_PROPERTY - - void ParseGraphPass1(SGraphObject *inParent) - { - TScope __elemScope(m_Reader); - qt3dsdm::ComposerObjectTypes::Enum theObjType = - qt3dsdm::ComposerObjectTypes::Convert(m_Reader.GetElementName()); - SGraphObject *theNewObject(NULL); - const char8_t *theId; - const char8_t *theVariants; - m_Reader.Att("id", theId); - m_Reader.Att("variants", theVariants); - - QString theString(theVariants); - QStringRef theStringRef(&theString); - bool isPartOfConfig = m_variantConfig.isPartOfConfig(theStringRef); - if (isPartOfConfig) { - switch (theObjType) { - case qt3dsdm::ComposerObjectTypes::Scene: { - SScene *theScene = QT3DS_NEW(m_PresentationAllocator, SScene)(); - theNewObject = theScene; - m_Presentation->m_Scene = theScene; - theScene->m_Presentation = m_Presentation; - } break; - case qt3dsdm::ComposerObjectTypes::Layer: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SLayer)(); - break; - case qt3dsdm::ComposerObjectTypes::Group: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); - break; - case qt3dsdm::ComposerObjectTypes::Component: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); - break; - case qt3dsdm::ComposerObjectTypes::Camera: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SCamera)(); - break; - case qt3dsdm::ComposerObjectTypes::Light: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SLight)(); - break; - case qt3dsdm::ComposerObjectTypes::Model: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SModel)(); - break; - case qt3dsdm::ComposerObjectTypes::Material: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SDefaultMaterial)(); - break; - case qt3dsdm::ComposerObjectTypes::ReferencedMaterial: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SReferencedMaterial)(); - break; - case qt3dsdm::ComposerObjectTypes::Image: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SImage)(); - break; - case qt3dsdm::ComposerObjectTypes::Text: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SText)(); - break; - case qt3dsdm::ComposerObjectTypes::Path: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SPath)(); - break; - case qt3dsdm::ComposerObjectTypes::SubPath: { - SPathSubPath *thePath = QT3DS_NEW(m_PresentationAllocator, SPathSubPath)(); - theNewObject = thePath; - QT3DSU32 anchorCount = 0; - TScope _childScope(m_Reader); - for (bool success = m_Reader.MoveToFirstChild("PathAnchorPoint"); success; - success = m_Reader.MoveToNextSibling("PathAnchorPoint")) { - const char8_t *theId; - m_Reader.Att("id", theId); - CRegisteredString theIdStr = m_StrTable.RegisterStr(theId); - m_AnchorIdToPathAndAnchorIndexMap.insert( - eastl::make_pair(theIdStr, SPathAndAnchorIndex(thePath, anchorCount))); - ++anchorCount; - } - m_PathManager.ResizePathSubPathBuffer(*thePath, anchorCount); - } break; - case qt3dsdm::ComposerObjectTypes::Effect: { - const char8_t *effectClassId; - m_Reader.Att("class", effectClassId); - CRegisteredString theStr = m_StrTable.RegisterStr(effectClassId + 1); - if (m_EffectSystem.IsEffectRegistered(theStr)) - theNewObject = m_EffectSystem.CreateEffectInstance(theStr, m_PresentationAllocator); - } break; - case qt3dsdm::ComposerObjectTypes::RenderPlugin: { - const char8_t *classId; - m_Reader.Att("class", classId); - if (!qt3ds::foundation::isTrivial(classId)) { - ++classId; - TIdStringMap::iterator iter = - m_RenderPluginSourcePaths.find(m_StrTable.RegisterStr(classId)); - if (iter != m_RenderPluginSourcePaths.end()) { - CRegisteredString thePluginPath = m_StrTable.RegisterStr(iter->second.c_str()); - qt3ds::render::IRenderPluginClass *theClass = - m_RenderPluginManager.GetRenderPlugin(thePluginPath); - if (theClass) { - qt3ds::render::SRenderPlugin *thePlugin = - QT3DS_NEW(m_PresentationAllocator, qt3ds::render::SRenderPlugin)(); - thePlugin->m_PluginPath = thePluginPath; - thePlugin->m_Flags.SetActive(true); - theNewObject = thePlugin; - } - } - } - } break; - case qt3dsdm::ComposerObjectTypes::CustomMaterial: { - const char8_t *materialClassId; - m_Reader.Att("class", materialClassId); - CRegisteredString theStr = m_StrTable.RegisterStr(materialClassId + 1); - if (m_CustomMaterialSystem.IsMaterialRegistered(theStr)) { - theNewObject = - m_CustomMaterialSystem.CreateCustomMaterial(theStr, m_PresentationAllocator); - } - } break; - default: - // Ignoring unknown objects entirely at this point - break; - } - } - if (theNewObject) { - CRegisteredString theObjectId(m_StrTable.RegisterStr(theId)); - m_ObjectMap.insert(eastl::make_pair(theObjectId, theNewObject)); - theNewObject->m_Id = theObjectId; - // setup hierarchy - bool isParentNode; - bool isChildNode; - if (inParent) { - switch (inParent->m_Type) { - case GraphObjectTypes::Scene: - if (theNewObject->m_Type == GraphObjectTypes::Layer) { - static_cast(inParent)->AddChild( - *static_cast(theNewObject)); - } - break; - - case GraphObjectTypes::DefaultMaterial: - if (theNewObject->m_Type == GraphObjectTypes::Image) { - static_cast(theNewObject)->m_Parent = - static_cast(inParent); - eastl::string thePath = eastl::string(theNewObject->m_Id.c_str()); - if (thePath.find("probe") != eastl::string::npos) - static_cast(theNewObject)->m_MappingMode = - ImageMappingModes::LightProbe; - } - break; - - case GraphObjectTypes::CustomMaterial: - if (theNewObject->m_Type == GraphObjectTypes::Image) { - static_cast(theNewObject)->m_Parent = - static_cast(inParent); - eastl::string thePath = eastl::string(theNewObject->m_Id.c_str()); - if (thePath.find("probe") != eastl::string::npos) { - static_cast(theNewObject)->m_MappingMode = - ImageMappingModes::LightProbe; - } - } else { - QT3DS_ASSERT(false); - } - break; - case GraphObjectTypes::ReferencedMaterial: - if (theNewObject->m_Type == GraphObjectTypes::Image) { - // nothing to do yet - } else { - QT3DS_ASSERT(false); - } - break; - case GraphObjectTypes::Path: - - if (GraphObjectTypes::IsMaterialType(theNewObject->m_Type)) - static_cast(inParent)->AddMaterial(theNewObject); - - else if (theNewObject->m_Type == GraphObjectTypes::PathSubPath) - static_cast(inParent)->AddSubPath( - *static_cast(theNewObject)); - - break; - - default: - isParentNode = IsNode(inParent->m_Type); - isChildNode = IsNode(theNewObject->m_Type); - if (isParentNode && isChildNode) { - static_cast(inParent)->AddChild( - *static_cast(theNewObject)); - } else if (isParentNode) { - if (inParent->m_Type == GraphObjectTypes::Model - && IsMaterial(theNewObject)) { - static_cast(inParent)->AddMaterial(*theNewObject); - } else { - if (inParent->m_Type == GraphObjectTypes::Layer - && theNewObject->m_Type == GraphObjectTypes::Effect) { - static_cast(inParent)->AddEffect( - *static_cast(theNewObject)); - } else if (inParent->m_Type == GraphObjectTypes::Layer - && theNewObject->m_Type == GraphObjectTypes::Image) { - eastl::string thePath = eastl::string(theNewObject->m_Id.c_str()); - if (thePath.find("probe2") != eastl::string::npos) { - static_cast(inParent)->m_LightProbe2 = - static_cast(theNewObject); - } else { - static_cast(inParent)->m_LightProbe = - static_cast(theNewObject); - } - } else { - if (theNewObject->m_Type == GraphObjectTypes::RenderPlugin) { - qt3ds::render::SRenderPlugin *childObj = - static_cast(theNewObject); - if (inParent->m_Type == GraphObjectTypes::Layer) { - static_cast(inParent)->m_RenderPlugin = childObj; - } else { - QT3DS_ASSERT(false); - } - } else { - QT3DS_ASSERT(false); - } - } - } - } else { - if (inParent->m_Type == GraphObjectTypes::Image - && theNewObject->m_Type == GraphObjectTypes::RenderPlugin) { - static_cast(inParent)->m_RenderPlugin = - static_cast(theNewObject); - } else { - QT3DS_ASSERT(false); - } - } - } - } - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) - ParseGraphPass1(theNewObject); - } else { - if (isPartOfConfig) { - // Object was of unknown type -> parse children with NULL parent - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) { - ParseGraphPass1(NULL); - } - } - // If object wasn't part of variant config -> skip children. - // Continue parsing from next sibling with same parent. - } - } - - template - void ParsePass2Properties(TObjType &inObject, const char8_t *inClassId) - { - const char8_t *theTypeName = m_Reader.GetNarrowElementName(); - SMetaPropertyParser theMetaParser(theTypeName, inClassId, m_MetaData); - // Set default values - ParseProperties(inObject, theMetaParser); - - // Now setup property values from the element itself. - SDomReaderPropertyParser theReaderParser(m_Reader, m_TempBuf, *this, inObject); - ParseProperties(inObject, theReaderParser); - } - - // Parse the instance properties from the graph. - void ParseGraphPass2() - { - TScope __instanceScope(m_Reader); - const char8_t *theId; - m_Reader.Att("id", theId); - const char8_t *theClass = ""; - const char8_t *theVariants = ""; - m_Reader.Att("class", theClass); - m_Reader.Att("variants", theVariants); - - QString theString(theVariants); - QStringRef theStringRef(&theString); - bool isPartOfConfig = m_variantConfig.isPartOfConfig(theStringRef); - if (isPartOfConfig) { - TIdObjectMap::iterator theObject = m_ObjectMap.find(m_StrTable.RegisterStr(theId)); - if (theObject != m_ObjectMap.end()) { - switch (theObject->second->m_Type) { - case GraphObjectTypes::Scene: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Node: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Layer: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Camera: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Light: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Model: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::DefaultMaterial: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::ReferencedMaterial: - ParsePass2Properties(*static_cast(theObject->second), - theClass); - break; - case GraphObjectTypes::Image: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Text: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Effect: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::RenderPlugin: - ParsePass2Properties(*static_cast(theObject->second), - theClass); - break; - case GraphObjectTypes::CustomMaterial: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::Path: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - case GraphObjectTypes::PathSubPath: - ParsePass2Properties(*static_cast(theObject->second), theClass); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - } - - // If not part of variant config -> ignore children - if (isPartOfConfig) { - for (bool valid = m_Reader.MoveToFirstChild(); valid; valid = m_Reader.MoveToNextSibling()) - ParseGraphPass2(); - } - } - - static bool ParseVec2(SDomReaderPropertyParser &inParser, const char *inName, QT3DSVec2 &outValue) - { - Option result = inParser.ParseVec2(inName); - - if (result.hasValue()) - outValue = *result; - - return result.hasValue(); - } - - static bool ParseFloat(SDomReaderPropertyParser &inParser, const char *inName, QT3DSF32 &outValue) - { - Option result = inParser.ParseFloat(inName); - if (result.hasValue()) - outValue = *result; - return result.hasValue(); - } - - void ParseState(bool inSetSetValues) - { - TScope __slideScope(m_Reader); - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) { - if (strcmp(m_Reader.GetNarrowElementName(), "Add") == 0 - || (inSetSetValues && strcmp(m_Reader.GetNarrowElementName(), "Set") == 0)) { - const char8_t *theId; - m_Reader.Att("ref", theId); - CRegisteredString theIdStr(m_StrTable.RegisterStr(theId + 1)); - if (m_ObjectMap.contains(theIdStr)) { - TIdObjectMap::iterator theObject = m_ObjectMap.find(theIdStr); - if (theObject != m_ObjectMap.end()) { - SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, *theObject->second); - switch (theObject->second->m_Type) { - case GraphObjectTypes::Scene: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::Node: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::Layer: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::Camera: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::Light: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::Model: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::DefaultMaterial: - ParseProperties(*reinterpret_cast(theObject->second), - parser); - break; - case GraphObjectTypes::ReferencedMaterial: - ParseProperties(*static_cast(theObject->second), - parser); - break; - case GraphObjectTypes::Image: - ParseProperties(*reinterpret_cast(theObject->second), parser); - break; - case GraphObjectTypes::Text: - ParseProperties(*static_cast(theObject->second), parser); - break; - case GraphObjectTypes::Effect: - ParseProperties(*static_cast(theObject->second), parser); - break; - case GraphObjectTypes::RenderPlugin: - ParseProperties( - *static_cast(theObject->second), parser); - break; - case GraphObjectTypes::CustomMaterial: - ParseProperties( - *static_cast(theObject->second), - parser); - break; - case GraphObjectTypes::Path: - ParseProperties(*static_cast(theObject->second), - parser); - break; - case GraphObjectTypes::PathSubPath: - ParseProperties( - *static_cast(theObject->second), parser); - break; - default: - QT3DS_ASSERT(false); - break; - } - } else { - TIdPathAnchorIndexMap::iterator iter = - m_AnchorIdToPathAndAnchorIndexMap.find(theIdStr); - if (iter != m_AnchorIdToPathAndAnchorIndexMap.end()) { - SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, - *iter->second.m_Segment); - NVDataRef thePathBuffer = - m_PathManager.GetPathSubPathBuffer(*iter->second.m_Segment); - QT3DSU32 anchorIndex = iter->second.m_AnchorIndex; - QT3DSU32 numAnchors = thePathBuffer.size(); - if (anchorIndex < numAnchors) { - qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); - ParseVec2(parser, "position", thePoint.m_Position); - ParseFloat(parser, "incomingangle", thePoint.m_IncomingAngle); - thePoint.m_OutgoingAngle = thePoint.m_IncomingAngle + 180.0f; - ParseFloat(parser, "incomingdistance", thePoint.m_IncomingDistance); - ParseFloat(parser, "outgoingdistance", thePoint.m_OutgoingDistance); - } - } - } - } - } - } - } - - void AddPluginProperty(qt3ds::render::IRenderPluginClass &pluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Enum inPropType, - eastl::string &tempStr, const char *propName) - { - tempStr.assign(propName); - qt3ds::render::SRenderPluginPropertyDeclaration theDec( - m_StrTable.RegisterStr(tempStr.c_str()), inPropType); - pluginClass.RegisterProperty(theDec); - } - - SPresentation *Load(bool inSetValuesFromSlides) - { - { - TScope __outerScope(m_Reader); - if (m_Reader.MoveToFirstChild("ProjectSettings")) { - m_Reader.Att("presentationWidth", m_Presentation->m_PresentationDimensions.x); - m_Reader.Att("presentationHeight", m_Presentation->m_PresentationDimensions.y); - // Upsize them to a multiple of four. - m_Presentation->m_PresentationDimensions.x = - (QT3DSF32)qt3ds::render::ITextRenderer::NextMultipleOf4( - (QT3DSU32)m_Presentation->m_PresentationDimensions.x); - m_Presentation->m_PresentationDimensions.y = - (QT3DSF32)qt3ds::render::ITextRenderer::NextMultipleOf4( - (QT3DSU32)m_Presentation->m_PresentationDimensions.y); - const char8_t *thePresentationRotation = ""; - if (m_Reader.Att("presentationRotation", thePresentationRotation)) { - bool success = SRenderUIPLoader::ConvertEnumFromStr( - thePresentationRotation, m_Presentation->m_PresentationRotation); - (void)success; - QT3DS_ASSERT(success); - } - m_Reader.Att("preferKTX", m_Presentation->m_preferKTX); - } - } - { - TScope __outerScope(m_Reader); - if (m_Reader.MoveToFirstChild("Classes")) { - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) { - const char8_t *idStr = "", *name = "", *sourcepath = ""; - m_Reader.Att("id", idStr); - m_Reader.Att("name", name); - m_Reader.Att("sourcepath", sourcepath); - if (AreEqual(m_Reader.GetNarrowElementName(), "Effect")) { - CRegisteredString theId(m_StrTable.RegisterStr(idStr)); - if (m_EffectSystem.IsEffectRegistered(theId) == false) { - // File should already be loaded. - Option theEffectMetaData = - m_MetaData.GetEffectMetaDataBySourcePath(sourcepath); - if (theEffectMetaData.hasValue()) { - qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect( - theId, m_Foundation, m_EffectSystem, *theEffectMetaData, - m_StrTable); - } else { - QT3DS_ASSERT(false); - } - } - } else if (AreEqual(m_Reader.GetNarrowElementName(), "CustomMaterial")) { - CRegisteredString theId(m_StrTable.RegisterStr(idStr)); - if (m_CustomMaterialSystem.IsMaterialRegistered(theId) == false) { - // File should already be loaded. - Option theMetaData = - m_MetaData.GetMaterialMetaDataBySourcePath(sourcepath); - if (theMetaData.hasValue()) { - qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial( - theId, m_Foundation, m_CustomMaterialSystem, *theMetaData, - m_StrTable); - } else { - QT3DS_ASSERT(false); - } - } - } else if (AreEqual(m_Reader.GetNarrowElementName(), "RenderPlugin")) { - CRegisteredString theId(m_StrTable.RegisterStr(idStr)); - m_MetaData.LoadPluginXMLFile(m_Reader.GetNarrowElementName(), idStr, name, - sourcepath); - eastl::vector theProperties; - qt3ds::render::IRenderPluginClass *thePluginClass = - m_RenderPluginManager.GetOrCreateRenderPlugin( - m_StrTable.RegisterStr(sourcepath)); - if (thePluginClass) { - m_RenderPluginSourcePaths.insert( - eastl::make_pair(m_StrTable.RegisterStr(idStr), sourcepath)); - m_MetaData.GetInstanceProperties(m_Reader.GetNarrowElementName(), idStr, - theProperties, false); - eastl::string thePropertyStr; - CRegisteredString metaType = - m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr( - m_Reader.GetNarrowElementName()); - CRegisteredString metaId = - m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr( - idStr); - for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { - using namespace Q3DStudio; - CRegisteredString metaProp = - m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr( - theProperties[idx].c_str()); - Q3DStudio::ERuntimeDataModelDataType thePropType = - m_MetaData.GetPropertyType(metaType, metaProp, metaId); - switch (thePropType) { - case ERuntimeDataModelDataTypeFloat: - AddPluginProperty( - *thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Float, - thePropertyStr, metaProp.c_str()); - break; - case ERuntimeDataModelDataTypeFloat2: - AddPluginProperty( - *thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Vector2, - thePropertyStr, metaProp.c_str()); - break; - case ERuntimeDataModelDataTypeFloat3: - if (m_MetaData.GetAdditionalType(metaType, metaProp, metaId) - != ERuntimeAdditionalMetaDataTypeColor) - AddPluginProperty( - *thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Vector3, - thePropertyStr, metaProp.c_str()); - else - AddPluginProperty( - *thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Color, - thePropertyStr, metaProp.c_str()); - break; - case ERuntimeDataModelDataTypeLong: - AddPluginProperty(*thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Long, - thePropertyStr, metaProp.c_str()); - break; - case ERuntimeDataModelDataTypeString: - case ERuntimeDataModelDataTypeStringRef: - AddPluginProperty( - *thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::String, - thePropertyStr, metaProp.c_str()); - break; - case ERuntimeDataModelDataTypeBool: - AddPluginProperty( - *thePluginClass, - qt3ds::render::SRenderPluginPropertyTypes::Boolean, - thePropertyStr, metaProp.c_str()); - break; - default: - QT3DS_ASSERT(false); - } - } - } - } - } - } - } - { - TScope __outerScope(m_Reader); - if (m_Reader.MoveToFirstChild("BufferData")) { - { - TScope __imageScope(m_Reader); - for (bool valid = m_Reader.MoveToFirstChild("ImageBuffer"); valid; - valid = m_Reader.MoveToNextSibling()) { - const char8_t *srcPath; - m_Reader.UnregisteredAtt("sourcepath", srcPath); - CRegisteredString imgPath = m_StrTable.RegisterStr(srcPath); - bool hasTransparency = false; - m_Reader.Att("hasTransparency", hasTransparency); - m_BufferManager.SetImageHasTransparency(imgPath, hasTransparency); - } - } - } - } - { - TScope __outerScope(m_Reader); - { - if (m_Reader.MoveToFirstChild("Graph")) { - { - TScope __graphScope(m_Reader); - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) - ParseGraphPass1(NULL); - } - { - TScope __graphScope(m_Reader); - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) - ParseGraphPass2(); - } - } - } - } - TScope __outerScope(m_Reader); - if (m_Reader.MoveToFirstChild("Logic")) { - for (bool valid = m_Reader.MoveToFirstChild("State"); valid; - valid = m_Reader.MoveToNextSibling()) { - { - TScope __slideScope(m_Reader); - ParseState(true); // parse master - for (bool subSlide = m_Reader.MoveToFirstChild("State"); subSlide; - subSlide = m_Reader.MoveToNextSibling("State")) { - TScope __subSlideScope(m_Reader); - ParseState(false); // parse slide setting only *add* values - } - } - { - TScope __slideScope(m_Reader); - if (inSetValuesFromSlides && m_Reader.MoveToFirstChild("State")) - ParseState(true); // parse slide setting only *set* values - } - } - } - - return m_Presentation; - } -}; -} - -SPresentation *qt3ds::render::IUIPLoader::LoadUIPFile( - qt3dsdm::IDOMReader &inReader, const char8_t *inFullPathToPresentationFile, - Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable, - NVFoundationBase &inFoundation - // Allocator used for the presentation objects themselves - // this allows clients to pre-allocate a block of memory just for - // the scene graph - , - NVAllocatorCallback &inPresentationAllocator - // Map of string ids to objects - , - TIdObjectMap &ioObjectMap, IBufferManager &inBufferManager, IEffectSystem &inEffectSystem, - const char8_t *inPresentationDir, IRenderPluginManager &inPluginManager, - ICustomMaterialSystem &inCMS, IDynamicObjectSystem &inDynamicSystem, - qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver, - const Q3DSVariantConfig &variantConfig, bool inSetValuesFromSlides) -{ - SRenderUIPLoader theLoader(inReader, inFullPathToPresentationFile, inMetaData, inStrTable, - inFoundation, inPresentationAllocator, ioObjectMap, inBufferManager, - inEffectSystem, inPresentationDir, inPluginManager, inCMS, - inDynamicSystem, inPathManager, inResolver, variantConfig); - return theLoader.Load(inSetValuesFromSlides); -} -using namespace qt3dsdm; - -inline qt3ds::render::NVRenderTextureFormats::Enum -ConvertTypeAndFormatToTextureFormat(const char8_t *inType, const char8_t *inFormat, - NVFoundationBase &inFoundation) -{ - qt3ds::render::NVRenderTextureFormats::Enum retval = qt3ds::render::NVRenderTextureFormats::RGBA8; - if (AreEqual(inType, "ubyte")) { - if (AreEqual(inFormat, "rgb")) - retval = qt3ds::render::NVRenderTextureFormats::RGB8; - else if (AreEqual(inFormat, "rgba")) - retval = qt3ds::render::NVRenderTextureFormats::RGBA8; - else if (AreEqual(inFormat, "alpha")) - retval = qt3ds::render::NVRenderTextureFormats::Alpha8; - else if (AreEqual(inFormat, "lum")) - retval = qt3ds::render::NVRenderTextureFormats::Luminance8; - else if (AreEqual(inFormat, "lum_alpha")) - retval = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; - } else if (AreEqual(inType, "ushort")) { - if (AreEqual(inFormat, "rgb")) - retval = qt3ds::render::NVRenderTextureFormats::RGB565; - else if (AreEqual(inFormat, "rgba")) - retval = qt3ds::render::NVRenderTextureFormats::RGBA5551; - } else { - qCCritical(INVALID_PARAMETER, "Unsupported texture type %s, defaulting to RGBA8", - inType); - } - return retval; -} - -inline qt3ds::render::NVRenderTextureMagnifyingOp::Enum -ConvertFilterToMagOp(const char8_t *inFilter, NVFoundationBase &inFoundation) -{ - if (AreEqual(inFilter, "linear")) - return qt3ds::render::NVRenderTextureMagnifyingOp::Linear; - if (AreEqual(inFilter, "nearest")) - return qt3ds::render::NVRenderTextureMagnifyingOp::Nearest; - else { - qCCritical(INVALID_PARAMETER, "Unsupported filter type %s, defaulting to linear", - inFilter); - return qt3ds::render::NVRenderTextureMagnifyingOp::Linear; - } -} - -inline qt3ds::render::NVRenderTextureCoordOp::Enum -ConvertTextureCoordOp(const char8_t *inWrap, NVFoundationBase &inFoundation) -{ - if (AreEqual(inWrap, "clamp")) - return qt3ds::render::NVRenderTextureCoordOp::ClampToEdge; - if (AreEqual(inWrap, "repeat")) - return qt3ds::render::NVRenderTextureCoordOp::Repeat; - else { - qCCritical(INVALID_PARAMETER, "Unsupported wrap type %s, defaulting to clamp", - inWrap); - return qt3ds::render::NVRenderTextureCoordOp::ClampToEdge; - } -} - -template -QString ConvertUTFtoQString(const TCharStr *string); - -template <> -QString ConvertUTFtoQString(const char16_t *string) -{ - return QString::fromUtf16(string); -} - -template <> -QString ConvertUTFtoQString(const char32_t *string) -{ - return QString::fromUcs4(string); -} - -template <> -QString ConvertUTFtoQString(const wchar_t *string) -{ - return QString::fromWCharArray(string); -} - -// Re-register all strings because we can't be sure that the meta data system and the effect -// system are sharing the same string table. -void qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect( - CRegisteredString inEffectName, NVFoundationBase &inFoundation, IEffectSystem &inEffectSystem, - const qt3dsdm::SMetaDataEffect &inMetaDataEffect, IStringTable &inStrTable) -{ - using namespace qt3ds::render::dynamic; - if (inEffectSystem.IsEffectRegistered(inEffectName)) { - qCCritical(INVALID_OPERATION, "Effect %s is already registered", - inEffectName.c_str()); - QT3DS_ASSERT(false); - return; - } - nvvector thePropertyDeclarations( - inFoundation.getAllocator(), "qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect"); - nvvector theEnumNames( - inFoundation.getAllocator(), "qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect"); - CRenderString theConvertStr; - CRenderString theConvertShaderTypeStr; - CRenderString theConvertShaderVersionStr; - - for (QT3DSU32 idx = 0, end = inMetaDataEffect.m_Properties.size(); idx < end; ++idx) - thePropertyDeclarations.push_back( - SPropertyDeclaration(inMetaDataEffect.m_Properties[idx].m_Name.c_str(), - inMetaDataEffect.m_Properties[idx].m_DataType)); - inEffectSystem.RegisterEffect(inEffectName, thePropertyDeclarations); - for (QT3DSU32 idx = 0, end = inMetaDataEffect.m_Properties.size(); idx < end; ++idx) { - const SPropertyDefinition &theDefinition(inMetaDataEffect.m_Properties[idx]); - if (theDefinition.m_EnumValueNames.size()) { - theEnumNames.clear(); - for (QT3DSU32 enumIdx = 0, enumEnd = theDefinition.m_EnumValueNames.size(); - enumIdx < enumEnd; ++enumIdx) - theEnumNames.push_back( - inStrTable.RegisterStr(theDefinition.m_EnumValueNames[enumIdx])); - inEffectSystem.SetEffectPropertyEnumNames( - inEffectName, inStrTable.RegisterStr(theDefinition.m_Name), theEnumNames); - } - if (theDefinition.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) - inEffectSystem.SetEffectPropertyTextureSettings( - inEffectName, inStrTable.RegisterStr(theDefinition.m_Name), - inStrTable.RegisterStr(theDefinition.m_ImagePath), theDefinition.m_TexUsageType, - theDefinition.m_CoordOp, theDefinition.m_MagFilterOp, theDefinition.m_MinFilterOp); - } - for (QT3DSU32 idx = 0, end = inMetaDataEffect.m_Shaders.size(); idx < end; ++idx) { - const qt3dsdm::SMetaDataShader &theShader = inMetaDataEffect.m_Shaders[idx]; - theConvertStr.clear(); - theConvertStr = ConvertUTFtoQString( - theShader.m_Code.c_str()).toStdString(); - theConvertShaderTypeStr = ConvertUTFtoQString( - theShader.m_Type.c_str()).toStdString(); - theConvertShaderVersionStr = ConvertUTFtoQString( - theShader.m_Version.c_str()).toStdString(); - - inEffectSystem.SetShaderData(inStrTable.RegisterStr(theShader.m_Name.c_str()), - theConvertStr.c_str(), theConvertShaderVersionStr.c_str(), - theConvertStr.c_str(), theShader.m_HasGeomShader, - theShader.m_IsComputeShader); - } - - inEffectSystem.SetEffectCommands(inEffectName, inMetaDataEffect.m_EffectCommands); -} - -void qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial( - CRegisteredString inClassName, NVFoundationBase &inFoundation, - ICustomMaterialSystem &inMaterialSystem, - const qt3dsdm::SMetaDataCustomMaterial &inMetaDataMaterial, IStringTable &inStrTable) -{ - using namespace qt3ds::render::dynamic; - if (inMaterialSystem.IsMaterialRegistered(inClassName)) { - qCCritical(INVALID_OPERATION, "Effect %s is already registered", - inClassName.c_str()); - QT3DS_ASSERT(false); - return; - } - nvvector thePropertyDeclarations( - inFoundation.getAllocator(), - "qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial"); - nvvector theEnumNames( - inFoundation.getAllocator(), - "qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial"); - CRenderString theConvertStr; - CRenderString theConvertShaderTypeStr; - CRenderString theConvertShaderVersionStr; - for (QT3DSU32 idx = 0, end = inMetaDataMaterial.m_Properties.size(); idx < end; ++idx) - thePropertyDeclarations.push_back( - SPropertyDeclaration(inMetaDataMaterial.m_Properties[idx].m_Name.c_str(), - inMetaDataMaterial.m_Properties[idx].m_DataType)); - inMaterialSystem.RegisterMaterialClass(inClassName, thePropertyDeclarations); - for (QT3DSU32 idx = 0, end = inMetaDataMaterial.m_Properties.size(); idx < end; ++idx) { - const SPropertyDefinition &theDefinition(inMetaDataMaterial.m_Properties[idx]); - if (theDefinition.m_EnumValueNames.size()) { - theEnumNames.clear(); - for (QT3DSU32 enumIdx = 0, enumEnd = theDefinition.m_EnumValueNames.size(); - enumIdx < enumEnd; ++enumIdx) - theEnumNames.push_back( - inStrTable.RegisterStr(theDefinition.m_EnumValueNames[enumIdx])); - inMaterialSystem.SetPropertyEnumNames( - inClassName, inStrTable.RegisterStr(theDefinition.m_Name), theEnumNames); - } - if (theDefinition.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) - inMaterialSystem.SetPropertyTextureSettings( - inClassName, inStrTable.RegisterStr(theDefinition.m_Name), - inStrTable.RegisterStr(theDefinition.m_ImagePath), theDefinition.m_TexUsageType, - theDefinition.m_CoordOp, theDefinition.m_MagFilterOp, theDefinition.m_MinFilterOp); - } - if (inMetaDataMaterial.m_Shaders.size()) { - for (QT3DSU32 idx = 0, end = (QT3DSU32)inMetaDataMaterial.m_Shaders.size(); idx < end; ++idx) { - const qt3dsdm::SMetaDataShader &theShader = inMetaDataMaterial.m_Shaders[idx]; - theConvertStr = ConvertUTFtoQString( - theShader.m_Code.c_str()).toStdString(); - theConvertShaderTypeStr = ConvertUTFtoQString( - theShader.m_Type.c_str()).toStdString(); - theConvertShaderVersionStr = ConvertUTFtoQString( - theShader.m_Version.c_str()).toStdString(); - inMaterialSystem.SetMaterialClassShader( - inStrTable.RegisterStr(theShader.m_Name.c_str()), theConvertShaderTypeStr.c_str(), - theConvertShaderVersionStr.c_str(), theConvertStr.c_str(), - theShader.m_HasGeomShader, theShader.m_IsComputeShader); - } - } - - inMaterialSystem.SetCustomMaterialCommands(inClassName, - inMetaDataMaterial.m_CustomMaterialCommands); - inMaterialSystem.SetCustomMaterialTransparency(inClassName, - inMetaDataMaterial.m_HasTransparency); - inMaterialSystem.SetCustomMaterialRefraction(inClassName, inMetaDataMaterial.m_HasRefraction); - inMaterialSystem.SetCustomMaterialAlwaysDirty(inClassName, inMetaDataMaterial.m_AlwaysDirty); - inMaterialSystem.SetCustomMaterialShaderKey(inClassName, inMetaDataMaterial.m_ShaderKey); - inMaterialSystem.SetCustomMaterialLayerCount(inClassName, inMetaDataMaterial.m_LayerCount); -} - -#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPSharedTranslation.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPSharedTranslation.cpp deleted file mode 100644 index a0594933..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPSharedTranslation.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderUIPSharedTranslation.h" - -namespace qt3ds { -namespace render { - -#define WCHAR_T_Directional L"Directional" -#define WCHAR_T_Point L"Point" -#define WCHAR_T_Area L"Area" -#define WCHAR_T_None L"None" -#define WCHAR_T_Vertex L"Vertex" -#define WCHAR_T_Pixel L"Pixel" -#define WCHAR_T_Normal L"Normal" -#define WCHAR_T_Screen L"Screen" -#define WCHAR_T_Multiply L"Multiply" -#define WCHAR_T_Overlay L"Overlay" -#define WCHAR_T_ColorBurn L"ColorBurn" -#define WCHAR_T_ColorDodge L"ColorDodge" -#define WCHAR_T_Add L"Add" -#define WCHAR_T_Subtract L"Subtract" -#define WCHAR_T_UV_Mapping L"UV Mapping" -#define WCHAR_T_Environmental_Mapping L"Environmental Mapping" -#define WCHAR_T_Light_Probe L"Light Probe" -#define WCHAR_T_No_Tiling L"No Tiling" -#define WCHAR_T_Mirrored L"Mirrored" -#define WCHAR_T_Tiled L"Tiled" -#define WCHAR_T_Left L"Left" -#define WCHAR_T_Center L"Center" -#define WCHAR_T_Right L"Right" -#define WCHAR_T_Top L"Top" -#define WCHAR_T_Middle L"Middle" -#define WCHAR_T_Bottom L"Bottom" -#define WCHAR_T_ElideNone L"ElideNone" -#define WCHAR_T_ElideLeft L"ElideLeft" -#define WCHAR_T_ElideMiddle L"ElideMiddle" -#define WCHAR_T_ElideRight L"ElideRight" -#define WCHAR_T_2x L"2x" -#define WCHAR_T_4x L"4x" -#define WCHAR_T_8x L"8x" -#define WCHAR_T_SSAA L"SSAA" -#define WCHAR_T_NoRotation L"NoRotation" -#define WCHAR_T_Clockwise90 L"90" -#define WCHAR_T_Clockwise180 L"180" -#define WCHAR_T_Clockwise270 L"270" -#define WCHAR_T_Fit L"Fit" -#define WCHAR_T_Same_Size L"Same Size" -#define WCHAR_T_CENTER L"Center" -#define WCHAR_T_North L"N" -#define WCHAR_T_NorthEast L"NE" -#define WCHAR_T_East L"E" -#define WCHAR_T_SouthEast L"SE" -#define WCHAR_T_South L"S" -#define WCHAR_T_SouthWest L"SW" -#define WCHAR_T_West L"W" -#define WCHAR_T_NorthWest L"NW" -#define WCHAR_T_LeftWidth L"Left/Width" -#define WCHAR_T_LeftRight L"Left/Right" -#define WCHAR_T_WidthRight L"Width/Right" -#define WCHAR_T_TopHeight L"Top/Height" -#define WCHAR_T_TopBottom L"Top/Bottom" -#define WCHAR_T_HeightBottom L"Height/Bottom" -#define WCHAR_T_Percent L"percent" -#define WCHAR_T_Pixels L"pixels" -#define WCHAR_T_Fit_Horizontal L"Fit Horizontal" -#define WCHAR_T_Fit_Vertical L"Fit Vertical" -#define WCHAR_T_Default L"Default" -#define WCHAR_T_KGGX L"KGGX" -#define WCHAR_T_KWard L"KWard" -#define WCHAR_T_Transparent L"Transparent" -#define WCHAR_T_Unspecified L"Unspecified" -#define WCHAR_T_Color L"SolidColor" -#define WCHAR_T_Linear L"Linear" -#define WCHAR_T_Phong L"Phong" -#define WCHAR_T_NPatch L"NPatch" -#define WCHAR_T_Taper L"Taper" -#define WCHAR_T_Geometry L"Geometry" -#define WCHAR_T_Painted L"Painted" -#define WCHAR_T_Filled L"Filled" -#define WCHAR_T_Stroked L"Stroked" -#define WCHAR_T_FilledAndStroked L"Filled and Stroked" -#define WCHAR_T_Simple L"Simple" -#define WCHAR_T_Smoke L"Smoke" -#define WCHAR_T_Cloud L"Cloud" -#define WCHAR_T_Fluid L"Fluid" -#define WCHAR_T_User L"User" -#define WCHAR_T_Clip L"Clip" -#define WCHAR_T_WrapWord L"WrapWord" -#define WCHAR_T_WrapAnywhere L"WrapAnywhere" - -#define CHAR_T_Directional "Directional" -#define CHAR_T_Point "Point" -#define CHAR_T_Area "Area" -#define CHAR_T_None "None" -#define CHAR_T_Vertex "Vertex" -#define CHAR_T_Pixel "Pixel" -#define CHAR_T_Normal "Normal" -#define CHAR_T_Screen "Screen" -#define CHAR_T_Multiply "Multiply" -#define CHAR_T_Overlay "Overlay" -#define CHAR_T_ColorBurn "ColorBurn" -#define CHAR_T_ColorDodge "ColorDodge" -#define CHAR_T_Add "Add" -#define CHAR_T_Subtract "Subtract" -#define CHAR_T_UV_Mapping "UV Mapping" -#define CHAR_T_Environmental_Mapping "Environmental Mapping" -#define CHAR_T_Light_Probe "Light Probe" -#define CHAR_T_No_Tiling "No Tiling" -#define CHAR_T_Mirrored "Mirrored" -#define CHAR_T_Tiled "Tiled" -#define CHAR_T_Left "Left" -#define CHAR_T_Center "Center" -#define CHAR_T_Right "Right" -#define CHAR_T_Top "Top" -#define CHAR_T_Middle "Middle" -#define CHAR_T_Bottom "Bottom" -#define CHAR_T_ElideNone "ElideNone" -#define CHAR_T_ElideLeft "ElideLeft" -#define CHAR_T_ElideMiddle "ElideMiddle" -#define CHAR_T_ElideRight "ElideRight" -#define CHAR_T_2x "2x" -#define CHAR_T_4x "4x" -#define CHAR_T_8x "8x" -#define CHAR_T_SSAA "SSAA" -#define CHAR_T_NoRotation "NoRotation" -#define CHAR_T_Clockwise90 "90" -#define CHAR_T_Clockwise180 "180" -#define CHAR_T_Clockwise270 "270" -#define CHAR_T_Fit "Fit" -#define CHAR_T_Same_Size "Same Size" -#define CHAR_T_CENTER "Center" -#define CHAR_T_North "N" -#define CHAR_T_NorthEast "NE" -#define CHAR_T_East "E" -#define CHAR_T_SouthEast "SE" -#define CHAR_T_South "S" -#define CHAR_T_SouthWest "SW" -#define CHAR_T_West "W" -#define CHAR_T_NorthWest "NW" -#define CHAR_T_LeftWidth "Left/Width" -#define CHAR_T_LeftRight "Left/Right" -#define CHAR_T_WidthRight "Width/Right" -#define CHAR_T_TopHeight "Top/Height" -#define CHAR_T_TopBottom "Top/Bottom" -#define CHAR_T_HeightBottom "Height/Bottom" -#define CHAR_T_Percent "percent" -#define CHAR_T_Pixels "pixels" -#define CHAR_T_Fit_Horizontal "Fit Horizontal" -#define CHAR_T_Fit_Vertical "Fit Vertical" -#define CHAR_T_Default "Default" -#define CHAR_T_KGGX "KGGX" -#define CHAR_T_KWard "KWard" -#define CHAR_T_Transparent "Transparent" -#define CHAR_T_Unspecified "Unspecified" -#define CHAR_T_Color "SolidColor" -#define CHAR_T_Linear "Linear" -#define CHAR_T_Phong "Phong" -#define CHAR_T_NPatch "NPatch" -#define CHAR_T_Taper "Taper" -#define CHAR_T_Geometry "Geometry" -#define CHAR_T_Painted "Painted" -#define CHAR_T_Filled "Filled" -#define CHAR_T_Stroked "Stroked" -#define CHAR_T_FilledAndStroked "Filled and Stroked" -#define CHAR_T_Simple "Simple" -#define CHAR_T_Smoke "Smoke" -#define CHAR_T_Cloud "Cloud" -#define CHAR_T_Fluid "Fluid" -#define CHAR_T_User "User" -#define CHAR_T_Clip "Clip" -#define CHAR_T_WrapWord "WrapWord" -#define CHAR_T_WrapAnywhere "WrapAnywhere" - -#define DEFINE_NAME_MAP_ENTRY(enumval, name) \ - { \ - enumval, WCHAR_T_##name, CHAR_T_##name \ - } - SEnumNameMap g_LightTypesMap[] = { - DEFINE_NAME_MAP_ENTRY(RenderLightTypes::Directional, Directional), - DEFINE_NAME_MAP_ENTRY(RenderLightTypes::Point, Point), - DEFINE_NAME_MAP_ENTRY(RenderLightTypes::Area, Area), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_MaterialLightingMap[] = { - DEFINE_NAME_MAP_ENTRY(DefaultMaterialLighting::NoLighting, None), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialLighting::VertexLighting, Vertex), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialLighting::FragmentLighting, Pixel), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_BlendModeMap[] = { - DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Normal, Normal), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Screen, Screen), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Multiply, Multiply), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Overlay, Overlay), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::ColorBurn, ColorBurn), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::ColorDodge, ColorDodge), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_ImageMappingModeMap[] = { - DEFINE_NAME_MAP_ENTRY(ImageMappingModes::Normal, UV_Mapping), - DEFINE_NAME_MAP_ENTRY(ImageMappingModes::Environment, Environmental_Mapping), - DEFINE_NAME_MAP_ENTRY(ImageMappingModes::LightProbe, Light_Probe), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_RenderTextureCoordOpMap[] = { - DEFINE_NAME_MAP_ENTRY(NVRenderTextureCoordOp::ClampToEdge, No_Tiling), - DEFINE_NAME_MAP_ENTRY(NVRenderTextureCoordOp::MirroredRepeat, Mirrored), - DEFINE_NAME_MAP_ENTRY(NVRenderTextureCoordOp::Repeat, Tiled), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_TextHorizontalAlignmentMap[] = { - DEFINE_NAME_MAP_ENTRY(TextHorizontalAlignment::Left, Left), - DEFINE_NAME_MAP_ENTRY(TextHorizontalAlignment::Center, Center), - DEFINE_NAME_MAP_ENTRY(TextHorizontalAlignment::Right, Right), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_TextVerticalAlignmentMap[] = { - DEFINE_NAME_MAP_ENTRY(TextVerticalAlignment::Top, Top), - DEFINE_NAME_MAP_ENTRY(TextVerticalAlignment::Middle, Middle), - DEFINE_NAME_MAP_ENTRY(TextVerticalAlignment::Bottom, Bottom), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_TextWordWrapMap[] = { - DEFINE_NAME_MAP_ENTRY(TextWordWrap::Clip, Clip), - DEFINE_NAME_MAP_ENTRY(TextWordWrap::WrapWord, WrapWord), - DEFINE_NAME_MAP_ENTRY(TextWordWrap::WrapAnywhere, WrapAnywhere), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_TextElideMap[] = { - DEFINE_NAME_MAP_ENTRY(TextElide::ElideNone, ElideNone), - DEFINE_NAME_MAP_ENTRY(TextElide::ElideLeft, ElideLeft), - DEFINE_NAME_MAP_ENTRY(TextElide::ElideMiddle, ElideMiddle), - DEFINE_NAME_MAP_ENTRY(TextElide::ElideRight, ElideRight), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_ProgressiveAAValuesMap[] = { - DEFINE_NAME_MAP_ENTRY(AAModeValues::NoAA, None), - DEFINE_NAME_MAP_ENTRY(AAModeValues::SSAA, SSAA), - DEFINE_NAME_MAP_ENTRY(AAModeValues::X2, 2x), - DEFINE_NAME_MAP_ENTRY(AAModeValues::X4, 4x), - DEFINE_NAME_MAP_ENTRY(AAModeValues::X8, 8x), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_LayerBlendTypesMap[] = { - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Normal, Normal), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Screen, Screen), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Multiply, Multiply), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Add, Add), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Subtract, Subtract), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Overlay, Overlay), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::ColorBurn, ColorBurn), - DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::ColorDodge, ColorDodge), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_RenderRotationValuesMap[] = { - DEFINE_NAME_MAP_ENTRY(RenderRotationValues::NoRotation, None), - DEFINE_NAME_MAP_ENTRY(RenderRotationValues::Clockwise90, Clockwise90), - DEFINE_NAME_MAP_ENTRY(RenderRotationValues::Clockwise180, Clockwise180), - DEFINE_NAME_MAP_ENTRY(RenderRotationValues::Clockwise270, Clockwise270), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_CameraScaleModesMap[] = { - DEFINE_NAME_MAP_ENTRY(CameraScaleModes::Fit, Fit), - DEFINE_NAME_MAP_ENTRY(CameraScaleModes::SameSize, Same_Size), - DEFINE_NAME_MAP_ENTRY(CameraScaleModes::FitHorizontal, Fit_Horizontal), - DEFINE_NAME_MAP_ENTRY(CameraScaleModes::FitVertical, Fit_Vertical), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_CameraScaleAnchorsMap[] = { - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::Center, Center), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::North, North), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::NorthEast, NorthEast), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::East, East), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::SouthEast, SouthEast), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::South, South), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::SouthWest, SouthWest), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::West, West), - DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::NorthWest, NorthWest), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_HorizontalFieldValuesMap[] = { - DEFINE_NAME_MAP_ENTRY(HorizontalFieldValues::LeftWidth, LeftWidth), - DEFINE_NAME_MAP_ENTRY(HorizontalFieldValues::LeftRight, LeftRight), - DEFINE_NAME_MAP_ENTRY(HorizontalFieldValues::WidthRight, WidthRight), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_VerticalFieldValuesMap[] = { - DEFINE_NAME_MAP_ENTRY(VerticalFieldValues::TopHeight, TopHeight), - DEFINE_NAME_MAP_ENTRY(VerticalFieldValues::TopBottom, TopBottom), - DEFINE_NAME_MAP_ENTRY(VerticalFieldValues::HeightBottom, HeightBottom), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_LayerUnitTypesMap[] = { - DEFINE_NAME_MAP_ENTRY(LayerUnitTypes::Percent, Percent), - DEFINE_NAME_MAP_ENTRY(LayerUnitTypes::Pixels, Pixels), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_LayerBackgroundMap[] = { - DEFINE_NAME_MAP_ENTRY(LayerBackground::Transparent, Transparent), - DEFINE_NAME_MAP_ENTRY(LayerBackground::Unspecified, Unspecified), - DEFINE_NAME_MAP_ENTRY(LayerBackground::Color, Color), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_SpecularTypesMap[] = { - DEFINE_NAME_MAP_ENTRY(DefaultMaterialSpecularModel::Default, Default), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialSpecularModel::KGGX, KGGX), - DEFINE_NAME_MAP_ENTRY(DefaultMaterialSpecularModel::KWard, KWard), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_TessellationValuesMap[] = { - DEFINE_NAME_MAP_ENTRY(TessModeValues::NoTess, None), - DEFINE_NAME_MAP_ENTRY(TessModeValues::TessLinear, Linear), - DEFINE_NAME_MAP_ENTRY(TessModeValues::TessPhong, Phong), - DEFINE_NAME_MAP_ENTRY(TessModeValues::TessNPatch, NPatch), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_PathCappingValuesMap[] = { - DEFINE_NAME_MAP_ENTRY(PathCapping::Noner, None), - DEFINE_NAME_MAP_ENTRY(PathCapping::Taper, Taper), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_PathTypesMap[] = { - DEFINE_NAME_MAP_ENTRY(PathTypes::Noner, None), - DEFINE_NAME_MAP_ENTRY(PathTypes::Painted, Painted), - DEFINE_NAME_MAP_ENTRY(PathTypes::Geometry, Geometry), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap g_PathPaintStylesMap[] = { - DEFINE_NAME_MAP_ENTRY(PathPaintStyles::Noner, None), - DEFINE_NAME_MAP_ENTRY(PathPaintStyles::FilledAndStroked, FilledAndStroked), - DEFINE_NAME_MAP_ENTRY(PathPaintStyles::Filled, Filled), - DEFINE_NAME_MAP_ENTRY(PathPaintStyles::Stroked, Stroked), - { (QT3DSU32)-1, NULL }, - }; - - SEnumNameMap *SEnumParseMap::GetMap() { return g_LightTypesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_MaterialLightingMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_BlendModeMap; } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_ImageMappingModeMap; } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_RenderTextureCoordOpMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_TextHorizontalAlignmentMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_TextVerticalAlignmentMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_TextWordWrapMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_TextElideMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_ProgressiveAAValuesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_LayerBlendTypesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_RenderRotationValuesMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_CameraScaleModesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_CameraScaleAnchorsMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_HorizontalFieldValuesMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_VerticalFieldValuesMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_LayerUnitTypesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_LayerBackgroundMap; } - - SEnumNameMap *SEnumParseMap::GetMap() - { - return g_SpecularTypesMap; - } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_TessellationValuesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_PathCappingValuesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_PathTypesMap; } - - SEnumNameMap *SEnumParseMap::GetMap() { return g_PathPaintStylesMap; } -} -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderWidgets.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderWidgets.cpp deleted file mode 100644 index 311b2189..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderWidgets.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRenderWidgets.h" -#include "Qt3DSRenderNode.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "render/Qt3DSRenderShaderProgram.h" - -using namespace qt3ds::render; - -namespace { - -struct SWidgetBBox : public IRenderWidget -{ - NVBounds3 m_Bounds; - QT3DSVec3 m_Color; - NVRenderVertexBuffer *m_BoxVertexBuffer; - NVRenderIndexBuffer *m_BoxIndexBuffer; - NVRenderInputAssembler *m_BoxInputAssembler; - NVRenderShaderProgram *m_BoxShader; - CRegisteredString m_ItemName; - SWidgetBBox(SNode &inNode, const NVBounds3 &inBounds, const QT3DSVec3 &inColor) - : IRenderWidget(inNode) - , m_Bounds(inBounds) - , m_Color(inColor) - , m_BoxVertexBuffer(NULL) - , m_BoxIndexBuffer(NULL) - , m_BoxInputAssembler(NULL) - , m_BoxShader(NULL) - { - } - - void SetupBoxShader(IRenderWidgetContext &inContext) - { - m_BoxShader = inContext.GetShader(m_ItemName); - if (!m_BoxShader) { - qt3ds::render::IShaderProgramGenerator &theGenerator(inContext.GetProgramGenerator()); - theGenerator.BeginProgram(); - qt3ds::render::IShaderStageGenerator &theVertexGenerator( - *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Vertex)); - qt3ds::render::IShaderStageGenerator &theFragmentGenerator( - *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Fragment)); - - theVertexGenerator.AddIncoming("attr_pos", "vec3"); - theVertexGenerator.AddUniform("model_view_projection", "mat4"); - theVertexGenerator.Append("void main() {"); - theVertexGenerator.Append( - "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - theVertexGenerator.Append("}"); - theFragmentGenerator.AddUniform("output_color", "vec3"); - theFragmentGenerator.Append("void main() {"); - theFragmentGenerator.Append("\tgl_FragColor.rgb = output_color;"); - theFragmentGenerator.Append("\tgl_FragColor.a = 1.0;"); - theFragmentGenerator.Append("}"); - m_BoxShader = inContext.CompileAndStoreShader(m_ItemName); - } - } - - void SetupBoundingBoxGraphicsObjects(IRenderWidgetContext &inContext, - NVDataRef thePoints) - { - qt3ds::render::NVRenderVertexBufferEntry theEntry( - "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3); - m_BoxVertexBuffer = &inContext.GetOrCreateVertexBuffer( - m_ItemName, 3 * sizeof(QT3DSF32), toU8DataRef(thePoints.begin(), thePoints.size())); - m_BoxIndexBuffer = inContext.GetIndexBuffer(m_ItemName); - if (!m_BoxIndexBuffer) { - // The way the bounds lays out the bounds for the box - // capitalization indicates whether this was a max or min value. - enum _Indexes { - xyz = 0, - Xyz, - xYz, - xyZ, - XYZ, - xYZ, - XyZ, - XYz, - }; - QT3DSU8 indexes[] = { - // The toBoxBounds function lays out points such that - // xyz, Xyz, xYz, xyZ, XYZ, xYZ, XyZ, XYz - // Min corner - xyz, Xyz, xyz, xYz, xyz, xyZ, - - // Max corner - XYZ, xYZ, XYZ, XyZ, XYZ, XYz, - - // Now connect the rest of the dots. - // the rules are that only one letter can change - // else you are connecting *across* the box somehow. - - Xyz, XYz, Xyz, XyZ, - - xYz, XYz, xYz, xYZ, - - xyZ, XyZ, xyZ, xYZ, - }; - m_BoxIndexBuffer = &inContext.GetOrCreateIndexBuffer( - m_ItemName, qt3ds::render::NVRenderComponentTypes::QT3DSU8, sizeof(indexes), - toU8DataRef(indexes, sizeof(indexes))); - } - - m_BoxInputAssembler = inContext.GetInputAssembler(m_ItemName); - if (!m_BoxInputAssembler && m_BoxIndexBuffer && m_BoxVertexBuffer) { - // create our attribute layout - NVRenderAttribLayout *theAttribLAyout = - &inContext.CreateAttributeLayout(toConstDataRef(&theEntry, 1)); - - QT3DSU32 strides = m_BoxVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_BoxInputAssembler = &inContext.GetOrCreateInputAssembler( - m_ItemName, theAttribLAyout, toConstDataRef(&m_BoxVertexBuffer, 1), - m_BoxIndexBuffer, toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - SetupBoxShader(inContext); - } - - void Render(IRenderWidgetContext &inWidgetContext, NVRenderContext &inRenderContext) override - { - m_ItemName = inRenderContext.GetStringTable().RegisterStr("SWidgetBBox"); - SWidgetRenderInformation theInfo(inWidgetContext.GetWidgetRenderInformation( - *m_Node, m_Node->m_Position, RenderWidgetModes::Local)); - TNVBounds2BoxPoints thePoints; - m_Bounds.expand(thePoints); - QT3DSMat44 theNodeRotation; - QT3DSMat44 theNodeToCamera = theInfo.m_NodeParentToCamera * m_Node->m_LocalTransform; - for (QT3DSU32 idx = 0; idx < 8; ++idx) - thePoints[idx] = theNodeToCamera.transform(thePoints[idx]); - SetupBoundingBoxGraphicsObjects(inWidgetContext, toDataRef(thePoints, 8)); - if (m_BoxShader && m_BoxInputAssembler) { - inRenderContext.SetBlendingEnabled(false); - inRenderContext.SetDepthWriteEnabled(true); - inRenderContext.SetDepthTestEnabled(true); - inRenderContext.SetCullingEnabled(false); - inRenderContext.SetActiveShader(m_BoxShader); - m_BoxShader->SetPropertyValue("model_view_projection", theInfo.m_LayerProjection); - m_BoxShader->SetPropertyValue("output_color", m_Color); - inRenderContext.SetInputAssembler(m_BoxInputAssembler); - inRenderContext.Draw(qt3ds::render::NVRenderDrawMode::Lines, - m_BoxInputAssembler->GetIndexCount(), 0); - } - } -}; - -struct SWidgetAxis : public IRenderWidget -{ - NVRenderVertexBuffer *m_AxisVertexBuffer; - NVRenderInputAssembler *m_AxisInputAssembler; - NVRenderShaderProgram *m_AxisShader; - CRegisteredString m_ItemName; - - SWidgetAxis(SNode &inNode) - : IRenderWidget(inNode) - , m_AxisVertexBuffer(NULL) - , m_AxisInputAssembler(NULL) - , m_AxisShader(NULL) - { - } - - void SetupAxisShader(IRenderWidgetContext &inContext) - { - m_AxisShader = inContext.GetShader(m_ItemName); - if (!m_AxisShader) { - qt3ds::render::IShaderProgramGenerator &theGenerator(inContext.GetProgramGenerator()); - theGenerator.BeginProgram(); - qt3ds::render::IShaderStageGenerator &theVertexGenerator( - *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Vertex)); - qt3ds::render::IShaderStageGenerator &theFragmentGenerator( - *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Fragment)); - theVertexGenerator.AddIncoming("attr_pos", "vec3"); - theVertexGenerator.AddIncoming("attr_color", "vec3"); - theVertexGenerator.AddOutgoing("output_color", "vec3"); - theVertexGenerator.AddUniform("model_view_projection", "mat4"); - theVertexGenerator.Append("void main() {"); - theVertexGenerator.Append( - "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); - theVertexGenerator.Append("\toutput_color = attr_color;"); - theVertexGenerator.Append("}"); - theFragmentGenerator.Append("void main() {"); - theFragmentGenerator.Append("\tgl_FragColor.rgb = output_color;"); - theFragmentGenerator.Append("\tgl_FragColor.a = 1.0;"); - theFragmentGenerator.Append("}"); - m_AxisShader = inContext.CompileAndStoreShader(m_ItemName); - } - } - - void SetupAxesGraphicsObjects(IRenderWidgetContext &inContext, NVDataRef theAxes) - { - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry("attr_color", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3, 12), - }; - - m_AxisVertexBuffer = &inContext.GetOrCreateVertexBuffer( - m_ItemName, 6 * sizeof(QT3DSF32), toU8DataRef(theAxes.begin(), theAxes.size())); - m_AxisInputAssembler = inContext.GetInputAssembler(m_ItemName); - if (!m_AxisInputAssembler && m_AxisVertexBuffer) { - // create our attribute layout - NVRenderAttribLayout *theAttribLAyout = - &inContext.CreateAttributeLayout(toConstDataRef(theEntries, 2)); - - QT3DSU32 strides = m_AxisVertexBuffer->GetStride(); - QT3DSU32 offsets = 0; - m_AxisInputAssembler = &inContext.GetOrCreateInputAssembler( - m_ItemName, theAttribLAyout, toConstDataRef(&m_AxisVertexBuffer, 1), nullptr, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); - } - } - - inline QT3DSVec3 TransformDirection(const QT3DSMat33 &inMatrix, const QT3DSVec3 &inDir) - { - QT3DSVec3 retval = inMatrix.transform(inDir); - return retval; - } - - void Render(IRenderWidgetContext &inWidgetContext, NVRenderContext &inRenderContext) override - { - m_ItemName = inRenderContext.GetStringTable().RegisterStr("SWidgetAxis"); - - SetupAxisShader(inWidgetContext); - - if (m_AxisShader) { - static const QT3DSVec3 pivotCol = QT3DSVec3(0, 0, 1); - if (m_Node->m_Parent && m_Node->m_Parent->m_Type != GraphObjectTypes::Layer) { - m_Node->m_Parent->CalculateGlobalVariables(); - } - QT3DSVec3 thePivot(m_Node->m_Pivot); - if (m_Node->m_Flags.IsLeftHanded()) - thePivot.z *= -1; - - SWidgetRenderInformation theInfo(inWidgetContext.GetWidgetRenderInformation( - *m_Node, QT3DSVec3(0, 0, 0), RenderWidgetModes::Local)); - - QT3DSMat44 theNodeRotation; - m_Node->CalculateRotationMatrix(theNodeRotation); - if (m_Node->m_Flags.IsLeftHanded()) - SNode::FlipCoordinateSystem(theNodeRotation); - - QT3DSMat33 theRotationMatrix(theNodeRotation.column0.getXYZ(), - theNodeRotation.column1.getXYZ(), - theNodeRotation.column2.getXYZ()); - - // Move the camera position into camera space. This is so that when we render we don't - // have to account - // for scaling done in the camera's MVP. - QT3DSVec3 theItemPosition = theInfo.m_Position; - - QT3DSMat33 theAxisTransform = theInfo.m_NormalMatrix * theRotationMatrix; - - // Scale the effective pivot line end point according to node scale - // so that pivot line always hits object center. - thePivot = thePivot.multiply(m_Node->m_Scale); - QT3DSVec3 pivotVec = TransformDirection( - theAxisTransform, QT3DSVec3(-thePivot.x, -thePivot.y, -thePivot.z)); - - QT3DSVec3 thePivotLine[] = { - theItemPosition, pivotCol, theItemPosition + pivotVec, pivotCol - }; - - SetupAxesGraphicsObjects(inWidgetContext, toDataRef(thePivotLine, 4)); - - if (m_AxisInputAssembler) { - inRenderContext.SetBlendingEnabled(false); - inRenderContext.SetDepthWriteEnabled(false); - inRenderContext.SetDepthTestEnabled(false); - inRenderContext.SetCullingEnabled(false); - inRenderContext.SetActiveShader(m_AxisShader); - m_AxisShader->SetPropertyValue("model_view_projection", theInfo.m_LayerProjection); - inRenderContext.SetInputAssembler(m_AxisInputAssembler); - // Draw line from pivot to object center. - inRenderContext.Draw(qt3ds::render::NVRenderDrawMode::Lines, 2, 0); - } - } - } -}; -} - -IRenderWidget &IRenderWidget::CreateBoundingBoxWidget(SNode &inNode, const NVBounds3 &inBounds, - const QT3DSVec3 &inColor, - NVAllocatorCallback &inAlloc) -{ - return *QT3DS_NEW(inAlloc, SWidgetBBox)(inNode, inBounds, inColor); -} - -IRenderWidget &IRenderWidget::CreateAxisWidget(SNode &inNode, NVAllocatorCallback &inAlloc) -{ - return *QT3DS_NEW(inAlloc, SWidgetAxis)(inNode); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRendererUtil.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRendererUtil.cpp deleted file mode 100644 index 7bc108e0..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRendererUtil.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRendererUtil.h" -#include "Qt3DSRenderResourceBufferObjects.h" -#include "Qt3DSRenderResourceTexture2D.h" - -using namespace qt3ds::render; - -void CRendererUtil::ResolveMutisampleFBOColorOnly(IResourceManager &inManager, - CResourceTexture2D &ioResult, - NVRenderContext &inRenderContext, QT3DSU32 inWidth, - QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inColorFormat, - NVRenderFrameBuffer &inSourceFBO) -{ - // create resolve FBO - CResourceFrameBuffer theResolveFB(inManager); - // Allocates the frame buffer which has the side effect of setting the current render target to - // that frame buffer. - theResolveFB.EnsureFrameBuffer(); - // set copy flags - qt3ds::render::NVRenderClearFlags copyFlags(NVRenderClearValues::Color); - - // get / create resolve targets and attach - ioResult.EnsureTexture(inWidth, inHeight, inColorFormat); - theResolveFB->Attach(NVRenderFrameBufferAttachments::Color0, *ioResult); - // CN - I don't believe we have to resolve the depth. - // The reason is we render the depth texture specially unresolved. So there is no need to - // resolve - // the depth prepass texture to anything else. - - // 1. Make resolve buffer be the render target ( already happend ) - // 2. Make the current layer FBO the current read target - // 3. Do the blit from MSAA to non MSAA - - // 2. - inRenderContext.SetReadTarget(&inSourceFBO); - inRenderContext.SetReadBuffer(NVReadFaces::Color0); - // 3. - inRenderContext.BlitFramebuffer(0, 0, inWidth, inHeight, 0, 0, inWidth, inHeight, copyFlags, - NVRenderTextureMagnifyingOp::Nearest); -} - -void CRendererUtil::ResolveSSAAFBOColorOnly(IResourceManager &inManager, - CResourceTexture2D &ioResult, QT3DSU32 outWidth, - QT3DSU32 outHeight, NVRenderContext &inRenderContext, - QT3DSU32 inWidth, QT3DSU32 inHeight, - NVRenderTextureFormats::Enum inColorFormat, - NVRenderFrameBuffer &inSourceFBO) -{ - // create resolve FBO - CResourceFrameBuffer theResolveFB(inManager); - // Allocates the frame buffer which has the side effect of setting the current render target to - // that frame buffer. - theResolveFB.EnsureFrameBuffer(); - // set copy flags - qt3ds::render::NVRenderClearFlags copyFlags(NVRenderClearValues::Color); - - // get / create resolve targets and attach - ioResult.EnsureTexture(outWidth, outHeight, inColorFormat); - theResolveFB->Attach(NVRenderFrameBufferAttachments::Color0, *ioResult); - // CN - I don't believe we have to resolve the depth. - // The reason is we render the depth texture specially unresolved. So there is no need to - // resolve - // the depth prepass texture to anything else. - - // 1. Make resolve buffer be the render target ( already happend ) - // 2. Make the current layer FBO the current read target - // 3. Do the blit from High res to low res buffer - - // 2. - inRenderContext.SetReadTarget(&inSourceFBO); - inRenderContext.SetReadBuffer(NVReadFaces::Color0); - // 3. - inRenderContext.BlitFramebuffer(0, 0, inWidth, inHeight, 0, 0, outWidth, outHeight, copyFlags, - NVRenderTextureMagnifyingOp::Linear); -} - -void CRendererUtil::GetSSAARenderSize(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 &outWidth, - QT3DSU32 &outHeight) -{ - // we currently double width and height - outWidth = inWidth * 2; - outHeight = inHeight * 2; - - // keep aspect ration? - // clamp to max - if (outWidth > MAX_SSAA_DIM) - outWidth = MAX_SSAA_DIM; - if (outHeight > MAX_SSAA_DIM) - outHeight = MAX_SSAA_DIM; -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSTextRenderer.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSTextRenderer.cpp deleted file mode 100644 index 91a5eb78..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSTextRenderer.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSTextRenderer.h" -#include "render/Qt3DSRenderTexture2D.h" - -using namespace qt3ds::render; - -// http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html -QT3DSU32 ITextRenderer::NextPowerOf2(QT3DSU32 input) -{ - // Algorithm doesn't work for 0 or QT3DS_MAX_U32 - QT3DS_ASSERT(input > 0 && input < QT3DS_MAX_U32); - input--; - input = (input >> 1) | input; - input = (input >> 2) | input; - input = (input >> 4) | input; - input = (input >> 8) | input; - input = (input >> 16) | input; - input++; // input is now the next highest power of 2. - return input; -} - -QT3DSU32 ITextRenderer::NextMultipleOf4(QT3DSU32 inValue) -{ - QT3DSU32 remainder(inValue % 4); - if (remainder != 0) - inValue = inValue + (4 - remainder); - - return inValue; -} - -STextTextureDetails ITextRenderer::UploadData(NVDataRef inTextureData, - NVRenderTexture2D &inTexture, QT3DSU32 inDataWidth, - QT3DSU32 inDataHeight, QT3DSU32 inTextWidth, - QT3DSU32 inTextHeight, - NVRenderTextureFormats::Enum inFormat, - bool inFlipYAxis) -{ - if (inTextWidth == 0 || inTextHeight == 0) { - QT3DSU32 black[] = { 0, 0, 0, 0 }; - inTexture.SetTextureData(toU8DataRef(black, 4), 0, 2, 2, NVRenderTextureFormats::RGBA8); - return STextTextureDetails(2, 2, false, QT3DSVec2(1.0)); - } - QT3DS_ASSERT(NextMultipleOf4(inDataWidth) == inDataWidth); - QT3DSU32 theNecessaryHeight = NextMultipleOf4(inTextHeight); - QT3DSU32 dataStride = inDataWidth * NVRenderTextureFormats::getSizeofFormat(inFormat); - if (inTextureData.size() < dataStride * inDataHeight) { - QT3DS_ASSERT(false); - return STextTextureDetails(); - } - - STextureDetails theTextureDetails = inTexture.GetTextureDetails(); - QT3DSU32 theUploadSize = theNecessaryHeight * dataStride; - - NVDataRef theUploadData = NVDataRef(inTextureData.begin(), theUploadSize); - inTexture.SetTextureData(theUploadData, 0, inDataWidth, theNecessaryHeight, inFormat); - inTexture.SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); - inTexture.SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); - return STextTextureDetails(inTextWidth, inTextHeight, inFlipYAxis, QT3DSVec2(1.0f, 1.0f)); -} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp deleted file mode 100644 index f1bdd4d9..00000000 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "q3dsqmlrender.h" -#include "q3dsqmlstreamservice.h" -#include "render/Qt3DSRenderContext.h" - -#include -#include - -Q3DSQmlRender::Q3DSQmlRender(IQt3DSRenderContext &inRenderContext, const char *asset) - : m_RenderContext(inRenderContext) - , m_qmlStreamRenderer(nullptr) - , m_offscreenRenderType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) - , m_assetString(inRenderContext.GetStringTable().RegisterStr(asset)) - , m_callback(nullptr) - , mRefCount(0) -{ - -} - -Q3DSQmlRender::~Q3DSQmlRender() -{ - m_qmlStreamRenderer = - IQ3DSQmlStreamService::getQmlStreamService()->getRenderer(m_assetString.c_str()); - if (m_qmlStreamRenderer) - m_qmlStreamRenderer->uninitialize(); -} - -CRegisteredString Q3DSQmlRender::GetOffscreenRendererType() -{ - return m_offscreenRenderType; -} - -NVRenderTextureFormats::Enum convertTextureFormat(E_TEXTURE_FORMAT fmt) -{ - NVRenderTextureFormats::Enum ret; - - switch (fmt) { - case E_TEXTURE_RGBA8: - ret = NVRenderTextureFormats::RGBA8; - break; - default: - ret = NVRenderTextureFormats::Unknown; - break; - } - - return ret; -} - -SOffscreenRendererEnvironment Q3DSQmlRender::GetDesiredEnvironment(QT3DSVec2 inPresScale) -{ - QSize size(0, 0); - E_TEXTURE_FORMAT format = E_TEXTURE_UNKNOWN; - - if (!m_qmlStreamRenderer) - initializeRenderer(); - - if (m_qmlStreamRenderer) { - size = m_qmlStreamRenderer->getDesiredSize(); - format = m_qmlStreamRenderer->getDesiredFormat(); - } - return SOffscreenRendererEnvironment( - (QT3DSU32)(size.width() * inPresScale.x), (QT3DSU32)(size.height() * inPresScale.y), - convertTextureFormat(format), OffscreenRendererDepthValues::Depth24, false, - AAModeValues::NoAA); -} - -SOffscreenRenderFlags Q3DSQmlRender::NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, - QT3DSVec2 inPresentationScaleFactor, - const SRenderInstanceId instanceId) -{ - Q_UNUSED(inEnvironment); - Q_UNUSED(inPresentationScaleFactor); - Q_UNUSED(instanceId); - bool render = false; - if (!m_qmlStreamRenderer) - initializeRenderer(); - if (m_qmlStreamRenderer) - render = m_qmlStreamRenderer->isUpdateRequested(); - return SOffscreenRenderFlags(false, render); -} - -void Q3DSQmlRender::Render(const SOffscreenRendererEnvironment &inEnvironment, - NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, - SScene::RenderClearCommand inColorBufferNeedsClear, - const SRenderInstanceId instanceId) -{ - Q_UNUSED(inEnvironment) - Q_UNUSED(inPresentationScaleFactor) - Q_UNUSED(inColorBufferNeedsClear) - Q_UNUSED(instanceId) - if (m_qmlStreamRenderer) { - inRenderContext.PushPropertySet(); - - m_qmlStreamRenderer->render(); - - inRenderContext.PopPropertySet(true); - - if (m_callback) - m_callback->onOffscreenRendererFrame(QString(m_assetString.c_str())); - } -} - -void Q3DSQmlRender::initializeRenderer() -{ - m_qmlStreamRenderer - = IQ3DSQmlStreamService::getQmlStreamService()->getRenderer(m_assetString.c_str()); - if (m_qmlStreamRenderer) { - if (!m_qmlStreamRenderer->initialize( - QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(), - QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->surface())) { - m_qmlStreamRenderer = nullptr; - } else if (m_callback) { - m_callback->onOffscreenRendererInitialized(QString(m_assetString.c_str())); - } - } -} diff --git a/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateConfig.h b/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateConfig.h deleted file mode 100644 index 0252d1f7..00000000 --- a/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateConfig.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#ifdef _WIN32 -#if defined QT3DS_STATE_EXPORTS -#define QT3DS_STATE_API __declspec(dllexport) -#elif defined QT3DS_STATE_NO_EXPORTS -#define QT3DS_STATE_API -#else -#define QT3DS_STATE_API __declspec(dllimport) -#endif -#else -#define QT3DS_STATE_API -#endif diff --git a/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateEngine.h b/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateEngine.h deleted file mode 100644 index 464fd3a5..00000000 --- a/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateEngine.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "foundation/Qt3DSRefCounted.h" - -#include "Qt3DSStateConfig.h" - -namespace qt3ds { - -class NVFoundation; - -namespace foundation { - class IStringTable; -} -} - -namespace Q3DStudio { -class ITimeProvider; -} - -namespace qt3ds { -namespace state { - - class IInputStreamFactory; - - class INDDStateEngine - { - public: - enum EStateEvent { - STATE_EVENT_UNKNOWN = 0, - STATE_EVENT_STATE_ENTER, - STATE_EVENT_STATE_EXIT, - STATE_EVENT_TRANSITION, - }; - class IStateEventHandler - { - public: - virtual ~IStateEventHandler() {} - virtual void OnEvent() = 0; - }; - class IStateEventHandlerConnection : public qt3ds::foundation::NVRefCounted - { - protected: - virtual ~IStateEventHandlerConnection() {} - public: - }; - - typedef qt3ds::foundation::NVScopedRefCounted - TStateEventHandlerConnectionPtr; - - public: - virtual ~INDDStateEngine() {} - - virtual bool Load(const char *inApplicationPath) = 0; - virtual bool Step() = 0; - virtual TStateEventHandlerConnectionPtr - RegisterEventHandler(EStateEvent inEvent, const char *inEventId, - IStateEventHandler &inHandler) = 0; - virtual void FireEvent(const char *inEventName, unsigned long long inDelay, - const char *inCancelId, bool inIsExternal = true) = 0; - virtual void FireEvent(const char *inEventName, bool inIsExternal = true) = 0; - virtual void CancelEvent(const char *inCancelId) = 0; - - QT3DS_STATE_API static INDDStateEngine * - Create(qt3ds::foundation::NVScopedRefCounted inFoundation, - qt3ds::foundation::NVScopedRefCounted inStringTable, - qt3ds::foundation::NVScopedRefCounted - inInputStreamFactory, - Q3DStudio::ITimeProvider &inTimeProvider); - - QT3DS_STATE_API static INDDStateEngine *Create(); - }; -} -} diff --git a/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateInputStreamFactory.h b/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateInputStreamFactory.h deleted file mode 100644 index a4e387ab..00000000 --- a/src/Runtime/Source/Qt3DSState/Include/Qt3DSStateInputStreamFactory.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/string.h" - -#include "Qt3DSStateConfig.h" - -namespace qt3ds { -namespace state { - - class IRefCountedInputStream : public qt3ds::foundation::ISeekableIOStream, - public qt3ds::foundation::NVRefCounted - { - protected: - virtual ~IRefCountedInputStream() {} - }; - - // This class is threadsafe. - class IInputStreamFactory : public qt3ds::foundation::NVRefCounted - { - protected: - virtual ~IInputStreamFactory() {} - public: - // These directories must have a '/' on them - virtual void AddSearchDirectory(const char8_t *inDirectory) = 0; - virtual IRefCountedInputStream *GetStreamForFile(const char8_t *inFilename, - bool inQuiet = false) = 0; - // Return a path for this file. Returns true if GetStreamForFile would return a valid - // stream. - // else returns false - virtual bool GetPathForFile(const char8_t *inFilename, eastl::string &outFile, - bool inQuiet = false) = 0; - - // Create an input stream factory using this foundation and an platform-optional app - // directory - // on android the app directory has no effect; use use the assets bundled with the APK file. - QT3DS_STATE_API static IInputStreamFactory &Create(qt3ds::NVFoundationBase &inFoundation); - }; -} -} diff --git a/src/Runtime/Source/Qt3DSState/InternalInclude/Qt3DSStateApplication.h b/src/Runtime/Source/Qt3DSState/InternalInclude/Qt3DSStateApplication.h deleted file mode 100644 index ca8f44d5..00000000 --- a/src/Runtime/Source/Qt3DSState/InternalInclude/Qt3DSStateApplication.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSTypes.h" - -namespace qt3ds { -namespace state { - - class INDDStateApplication : public qt3ds::foundation::NVRefCounted - { - public: - virtual ~INDDStateApplication() {} - - virtual double GetMillisecondsSinceLastFrame() = 0; - virtual Q3DStudio::INT32 GetFrameCount() = 0; - }; -} -} diff --git a/src/Runtime/Source/Qt3DSState/Source/Qt3DSStateInputStreamFactory.cpp b/src/Runtime/Source/Qt3DSState/Source/Qt3DSStateInputStreamFactory.cpp deleted file mode 100644 index 2fd3dffa..00000000 --- a/src/Runtime/Source/Qt3DSState/Source/Qt3DSStateInputStreamFactory.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateInputStreamFactory.h" - -#include "stdio.h" - -#include "foundation/Qt3DSLogging.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/string.h" -#include "EASTL/vector.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/FileTools.h" -#include "foundation/Qt3DSMutex.h" -#include - -using namespace qt3ds::state; -using qt3ds::foundation::CFileTools; - -namespace { - -using qt3ds::foundation::atomicIncrement; -using qt3ds::foundation::atomicDecrement; -using qt3ds::QT3DSI32; - -struct SInputStream : public IRefCountedInputStream -{ - qt3ds::NVFoundationBase &m_Foundation; - eastl::string m_Path; - QFile m_File; - volatile qt3ds::QT3DSI32 mRefCount; - - SInputStream(qt3ds::NVFoundationBase &inFoundation, const eastl::string &inPath) - : m_Foundation(inFoundation) - , m_Path(inPath) - , m_File(inPath.c_str()) - , mRefCount(0) - { - m_File.open(QIODevice::ReadOnly); - } - virtual ~SInputStream() - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - qt3ds::QT3DSU32 Read(qt3ds::foundation::NVDataRef data) override - { - return m_File.read((char *)data.begin(), data.size()); - } - - bool Write(qt3ds::foundation::NVConstDataRef /*data*/) override - { - QT3DS_ASSERT(false); - return false; - } - - void SetPosition(qt3ds::QT3DSI64 inOffset, qt3ds::foundation::SeekPosition::Enum inEnum) override - { - if (inOffset > QT3DS_MAX_I32 || inOffset < QT3DS_MIN_I32) { - qCCritical(qt3ds::INVALID_OPERATION, "Attempt to seek further than platform allows"); - QT3DS_ASSERT(false); - return; - } else { - CFileTools::SetStreamPosition(m_File, inOffset, inEnum); - } - } - qt3ds::QT3DSI64 GetPosition() const override - { - return m_File.pos(); - } - - static SInputStream *OpenFile(const char8_t *inPath, qt3ds::NVFoundationBase &inFoundation) - { - eastl::string finalPath = CFileTools::GetFileOrAssetPath(inPath); - QFile tmp(finalPath.c_str()); - if (tmp.exists()) - return QT3DS_NEW(inFoundation.getAllocator(), SInputStream)(inFoundation, finalPath); - return NULL; - } -}; - -typedef eastl::basic_string TStrType; -struct SFactory : public IInputStreamFactory -{ - qt3ds::NVFoundationBase &m_Foundation; - volatile qt3ds::QT3DSI32 mRefCount; - TStrType m_SearchString; - qt3ds::foundation::nvvector m_SearchPaths; - TStrType m_TempAddSearch; - - qt3ds::foundation::Mutex m_Mutex; - typedef qt3ds::foundation::Mutex::ScopedLock TScopedLock; - - SFactory(qt3ds::NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , mRefCount(0) - , m_SearchString(qt3ds::foundation::ForwardingAllocator(inFoundation.getAllocator(), - "SFactory::m_SearchString")) - , m_SearchPaths(inFoundation.getAllocator(), "SFactory::m_SearchPaths") - , m_TempAddSearch(qt3ds::foundation::ForwardingAllocator(inFoundation.getAllocator(), - "SFactory::m_TempAddSearch")) - , m_Mutex(inFoundation.getAllocator()) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void AddSearchDirectory(const char8_t *inDirectory) override - { - TScopedLock __factoryLocker(m_Mutex); - if (inDirectory && *inDirectory) { - bool foundPath = false; - m_TempAddSearch.assign(inDirectory); - qt3ds::foundation::CFileTools::NormalizePath(m_TempAddSearch); - for (qt3ds::QT3DSU32 idx = 0, end = m_SearchPaths.size(); idx < end && foundPath == false; - ++idx) { - foundPath = m_SearchPaths[idx].compare(m_TempAddSearch.c_str()) == 0; - } - if (!foundPath) { - qCInfo(qt3ds::TRACE_INFO, "Adding search path: %s", inDirectory); - m_SearchPaths.push_back(m_TempAddSearch); - } - } - } - void AttemptCFileOpen() - { - qCInfo(qt3ds::TRACE_INFO, "attempting C file api for %s", m_SearchString.c_str()); - FILE *theTest = fopen(m_SearchString.c_str(), "rb"); - if (theTest) { - qCInfo(qt3ds::TRACE_INFO, "C file api succeeded for %s", m_SearchString.c_str()); - fclose(theTest); - } else { - qCInfo(qt3ds::TRACE_INFO, "C file api failed for %s", m_SearchString.c_str()); - } - } - - // Remove the ./ from the relative path as this allows APK lookup to succeed - static void CheckRelative(TStrType &ioStr) - { - if (ioStr.find("./") == 0) - ioStr.erase(ioStr.begin(), ioStr.begin() + 2); - } - - IRefCountedInputStream *GetStreamForFile(const char8_t *inFilename, bool inQuiet) override - { - TScopedLock __factoryLocker(m_Mutex); - SInputStream *theFile = NULL; - for (qt3ds::QT3DSU32 idx = 0, end = m_SearchPaths.size() + 1; theFile == NULL && idx < end; - ++idx) { - if (idx) { - qt3ds::foundation::CFileTools::CombineBaseAndRelative(m_SearchPaths[idx - 1].c_str(), - inFilename, m_SearchString); - } else { - m_SearchString.assign(inFilename); - } - qt3ds::foundation::CFileTools::ToPlatformPath(m_SearchString); - CheckRelative(m_SearchString); - theFile = SInputStream::OpenFile(m_SearchString.c_str(), m_Foundation); - } - if (theFile) { - qCInfo(qt3ds::TRACE_INFO, "file %s resolved to: %s", inFilename, m_SearchString.c_str()); - } else { - if (inQuiet == false) { - // Print extensive debugging information. - qCWarning(qt3ds::WARNING, "Failed to find file: %s", inFilename); - qCWarning(qt3ds::WARNING, "Searched paths: %s", inFilename); - m_SearchString.assign(inFilename); - qt3ds::foundation::CFileTools::ToPlatformPath(m_SearchString); - qCWarning(qt3ds::WARNING, "%s", m_SearchString.c_str()); - for (qt3ds::QT3DSU32 idx = 0, end = m_SearchPaths.size(); idx < end; ++idx) { - qt3ds::foundation::CFileTools::CombineBaseAndRelative(m_SearchPaths[idx].c_str(), - inFilename, m_SearchString); - qt3ds::foundation::CFileTools::ToPlatformPath(m_SearchString); - CheckRelative(m_SearchString); - if (m_SearchString.compare(inFilename) != 0) - qCWarning(qt3ds::WARNING, "%s", m_SearchString.c_str()); - } - } - } - return theFile; - } - - bool GetPathForFile(const char8_t *inFilename, eastl::string &outFile, - bool inQuiet = false) override - { - qt3ds::foundation::NVScopedRefCounted theStream = - GetStreamForFile(inFilename, inQuiet); - if (theStream) { - SInputStream *theRealStream = static_cast(theStream.mPtr); - outFile = theRealStream->m_Path; - return true; - } - return false; - } -}; -} - -IInputStreamFactory &IInputStreamFactory::Create(qt3ds::NVFoundationBase &inFoundation) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SFactory)(inFoundation); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.cpp b/src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.cpp deleted file mode 100644 index cd89d52f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateApplication.h" -#include "foundation/FileTools.h" -#include "EASTL/vector.h" -#include "foundation/IOStreams.h" -#include "foundation/XML.h" - -#include - -typedef eastl::string TAppStr; - -using namespace qt3ds::foundation; -using namespace qt3ds::state; -using namespace eastl; - -eastl::string IApplication::GetLaunchFile(const char *inFullUIPPath) -{ - eastl::string directory; - eastl::string filestem; - eastl::string extension; - - CFileTools::Split(inFullUIPPath, directory, filestem, extension); - eastl::string uiaPath; - - eastl::vector dirFiles; - CFileTools::GetDirectoryEntries(directory, dirFiles); - - for (qt3ds::QT3DSU32 idx = 0, end = dirFiles.size(); idx < end && uiaPath.empty(); ++idx) { - eastl::string fileExt; - CFileTools::GetExtension(dirFiles[idx].c_str(), fileExt); - if (fileExt.comparei("uia") == 0) - CFileTools::CombineBaseAndRelative(directory.c_str(), dirFiles[idx].c_str(), uiaPath); - } - return uiaPath.empty() == false ? uiaPath : eastl::string(inFullUIPPath); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.h b/src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.h deleted file mode 100644 index 3ebe0d4f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Application/Qt3DSStateApplication.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_APPLICATION_H -#define QT3DS_STATE_APPLICATION_H -#include "EASTL/string.h" -#include - -namespace qt3ds { -namespace state { - // Shared code for dealing with .uia files. - class IApplication - { - public: - static eastl::string GetLaunchFile(const char *inFullUIPPath); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebugger.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebugger.h deleted file mode 100644 index 38a0b74f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebugger.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_SCENE_GRAPH_DEBUGGER_H -#define QT3DS_SCENE_GRAPH_DEBUGGER_H -#pragma once -#include "Qt3DSStateDebugger.h" -#include "Qt3DSUIADatamodel.h" - -namespace qt3ds { -namespace state { - namespace debugger { - - struct SSGValue; - - struct SSGPropertyChange; - - struct SGElemIdMap - { - void *m_Elem; - const char *m_Id; - }; - - // Persistant item that sticks around and appends some information to the binary file. - // The runtime debugger must exist for the entire time the runtime is running, not just - // during connection because the mapping from element->id only exists at file loading time. - class ISceneGraphRuntimeDebugger : public NVRefCounted, public IDebugStreamListener - { - public: - static const char *GetProtocolName() { return "Scene Graph Debugger"; } - // Nothing is returned if the object isn't connected. The returned value may not be - // valid - // after next GetOrCreateCall, so don't hold on to it. - virtual void MapPresentationId(void *presentation, const char *id) = 0; - virtual void MapElementIds(void *presentation, NVConstDataRef inIds) = 0; - virtual void OnPropertyChanged(void *elem, - NVConstDataRef changes) = 0; - virtual void OnConnection(IDebugOutStream &outStream) = 0; - virtual void BinarySave(IOutStream &stream) = 0; - // Load the main datastructures, although we know the ids are wrong - virtual void BinaryLoad(IInStream &stream, NVDataRef inStringTableData) = 0; - // Remap the presentation element points using id to map old presentation ptr to new - // presentation ptr. - virtual void BinaryLoadPresentation(void *presentation, const char *id, - size_t inElemOffset) = 0; - virtual void EndFrame() = 0; - virtual bool IsConnected() = 0; - - static ISceneGraphRuntimeDebugger &Create(NVFoundationBase &fnd, - IStringTable &strTable); - }; - - class ISceneGraphArchitectDebuggerListener - { - public: - virtual void OnItemsDirty(NVConstDataRef inDirtySet) = 0; - }; - - // The architect debugger only exists when debugging. - class ISceneGraphArchitectDebugger : public NVRefCounted, public IDebugStreamListener - { - public: - virtual void SetListener(ISceneGraphArchitectDebuggerListener *listener) = 0; - // Note that we wrap the att or arg list and the initial values to provide extra - // information. - virtual Q3DStudio::TAttOrArgList GetElementAttributes(app::SAppElement &elem) = 0; - - // These may be empty, so don't expect them. Also they are all string, no registered - // strings - // regardless of the type. - virtual eastl::vector - GetElementAttributeValues(app::SAppElement &elem) = 0; - virtual app::IDatamodel &GetDatamodel() = 0; - - virtual void AttachToStream(IDebugOutStream &inStream) = 0; - - virtual void RefreshData(bool inNeedReloadData) = 0; - - static ISceneGraphArchitectDebugger &Create(qt3ds::app::IDatamodel &inDatamodel); - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerProtocol.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerProtocol.h deleted file mode 100644 index 4fea4322..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerProtocol.h +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_SCENE_GRAPH_DEBUGGER_PROTOCOL_H -#define QT3DS_SCENE_GRAPH_DEBUGGER_PROTOCOL_H -#include "Qt3DSSceneGraphDebugger.h" -#include "Qt3DSSceneGraphDebuggerValue.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "foundation/SerializationTypes.h" - -namespace qt3ds { -namespace state { - namespace debugger { - - // These are the datatypes we will communicate information with - static QT3DSU32 GetSceneGraphProtocolVersion() { return 1; } - - struct SValueUpdate - { - QT3DSI32 m_Hash; - SSGValue m_Value; - SValueUpdate(QT3DSI32 h, const SSGValue &v) - : m_Hash(h) - , m_Value(v) - { - } - SValueUpdate() - : m_Hash(0) - { - } - template - void IterateProperties(Listener &inListener) - { - inListener.Handle(m_Hash); - inListener.Handle(m_Value); - }; - }; - - struct SElemUpdate - { - QT3DSU64 m_Elem; - NVDataRef m_Updates; - template - void IterateProperties(Listener &inListener) - { - inListener.Handle(m_Elem); - inListener.HandleRef(m_Updates); - }; - }; - - struct SElemMap - { - QT3DSU64 m_Elem; - CRegisteredString m_Id; - SElemMap() - : m_Elem(0) - { - } - SElemMap(QT3DSU64 ptr, CRegisteredString name) - : m_Elem(ptr) - , m_Id(name) - { - } - - template - void IterateProperties(Listener &inListener) - { - inListener.Handle(m_Elem); - inListener.Handle(m_Id); - } - }; - - struct SIdUpdate - { - QT3DSU64 m_Presentation; - CRegisteredString m_PresentationId; - NVDataRef m_IdUpdates; - - template - void IterateProperties(Listener &inListener) - { - inListener.Handle(m_Presentation); - inListener.Handle(m_PresentationId); - inListener.HandleRef(m_IdUpdates); - } - }; - - struct SSGProtocolMessageTypes - { - enum Enum { - UnknownMessage = 0, - Initialization, - IdUpdate, - ElemUpdate, - Frame, - }; - }; - - // Implemented on runtime side. - struct SSGProtocolWriter - { - IOutStream &m_Stream; - MemoryBuffer<> m_WriteBuffer; - QT3DSU32 m_HighWaterMark; - - SSGProtocolWriter(IOutStream &s, NVAllocatorCallback &alloc, QT3DSU32 highWaterMark = 4096) - : m_Stream(s) - , m_WriteBuffer(ForwardingAllocator(alloc, "WriteBuffer")) - , m_HighWaterMark(highWaterMark) - { - } - - void Handle(QT3DSU64 data) { m_WriteBuffer.write(data); } - - void Handle(QT3DSI32 data) { m_WriteBuffer.write(data); } - - void Handle(CRegisteredString str) - { - QT3DSU32 len = static_cast(strlen(str.c_str()) + 1); - m_WriteBuffer.write(len); - m_WriteBuffer.write(str.c_str(), len); - } - void Handle(SSGValue &value) - { - QT3DSU32 valType = static_cast(value.getType()); - m_WriteBuffer.write(valType); - switch (value.getType()) { - case SGPropertyValueTypes::Float: - m_WriteBuffer.write(value.getData()); - break; - case SGPropertyValueTypes::I32: - m_WriteBuffer.write(value.getData()); - break; - case SGPropertyValueTypes::String: - Handle(value.getData()); - break; - case SGPropertyValueTypes::Elem: - Handle(value.getData()); - break; - case SGPropertyValueTypes::NoSGValue: - break; - default: - QT3DS_ASSERT(false); - } - } - - template - void HandleRef(NVDataRef &ref) - { - m_WriteBuffer.write(ref.size()); - for (QT3DSU32 idx = 0, end = ref.size(); idx < end; ++idx) - Handle(ref[idx]); - } - - template - void Handle(TDataType &dtype) - { - dtype.IterateProperties(*this); - } - - void Flush() - { - if (m_WriteBuffer.size()) { - NVConstDataRef writeData(m_WriteBuffer); - m_Stream.Write(writeData); - m_WriteBuffer.clear(); - } - } - - void CheckBuffer() - { - if (m_WriteBuffer.size() > m_HighWaterMark) - Flush(); - } - - void Write(SIdUpdate &inIdUpdate) - { - m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::IdUpdate); - inIdUpdate.IterateProperties(*this); - Flush(); - } - - void Write(SElemUpdate &inIdUpdate) - { - m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::ElemUpdate); - inIdUpdate.IterateProperties(*this); - CheckBuffer(); - } - - void WriteInitialization() - { - m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::Initialization); - m_WriteBuffer.write(GetSceneGraphProtocolVersion()); - Flush(); - } - void WriteFrame() - { - m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::Frame); - Flush(); - } - }; - - struct SSGProtocolReader - { - NVConstDataRef m_Message; - SDataReader m_Reader; - IStringTable &m_StringTable; - eastl::vector m_DataBuffer; - eastl::string m_TempString; - QT3DSU32 m_Allocated; - bool m_RestartRead; - SSGProtocolReader(NVConstDataRef msg, IStringTable &strTable) - : m_Message(msg) - , m_Reader(const_cast(msg.begin()), const_cast(msg.end())) - , m_StringTable(strTable) - , m_Allocated(0) - , m_RestartRead(false) - { - } - - SSGProtocolMessageTypes::Enum MessageType() - { - QT3DSU32 data = m_Reader.LoadRef(); - return static_cast(data); - } - - template - Option> AllocateData(size_t size) - { - if (m_RestartRead) - return Empty(); - if (size == 0) - return NVDataRef(); - - QT3DSU32 current = m_Allocated; - QT3DSU32 newAlloc = (QT3DSU32)(size * sizeof(TDataType)); - // 8 byte align - if (newAlloc % 8) - newAlloc += 8 - (newAlloc % 8); - - QT3DSU32 required = current + newAlloc; - - if (required > m_DataBuffer.size()) { - m_RestartRead = true; - m_DataBuffer.resize(required * 2); - return Empty(); - } - TDataType *offset = reinterpret_cast(&m_DataBuffer[current]); - m_Allocated += newAlloc; - return toDataRef(offset, (QT3DSU32)size); - } - - void Handle(QT3DSU64 &data) { data = m_Reader.LoadRef(); } - - void Handle(QT3DSI32 &data) { data = m_Reader.LoadRef(); } - - void Handle(CRegisteredString &str) - { - QT3DSU32 len = m_Reader.LoadRef(); - m_TempString.clear(); - if (len) - m_TempString.assign((const char *)m_Reader.m_CurrentPtr, (size_t)(len - 1)); - m_Reader.m_CurrentPtr += len; - if (m_Reader.m_CurrentPtr > m_Reader.m_EndPtr) - m_Reader.m_CurrentPtr = m_Reader.m_EndPtr; - - str = m_StringTable.RegisterStr(m_TempString.c_str()); - } - - void Handle(SSGValue &value) - { - QT3DSU32 valType = m_Reader.LoadRef(); - switch (valType) { - case SGPropertyValueTypes::Float: - value = SSGValue(m_Reader.LoadRef()); - break; - case SGPropertyValueTypes::I32: - value = SSGValue(m_Reader.LoadRef()); - break; - case SGPropertyValueTypes::String: { - CRegisteredString temp; - Handle(temp); - value = SSGValue(temp); - } break; - case SGPropertyValueTypes::Elem: - value = m_Reader.LoadRef(); - break; - case SGPropertyValueTypes::NoSGValue: - break; - default: - QT3DS_ASSERT(false); - } - } - - template - void HandleRef(NVDataRef &ref) - { - QT3DSU32 numItems = m_Reader.LoadRef(); - Option> refOpt = AllocateData(numItems); - if (refOpt.hasValue()) { - ref = *refOpt; - for (QT3DSU32 idx = 0, end = ref.size(); idx < end && m_RestartRead == false; - ++idx) - Handle(ref[idx]); - } - } - - template - void Handle(TDataType &dtype) - { - dtype.IterateProperties(*this); - } - - template - void DoRead(TDataType &ioValue) - { - QT3DSU8 *startPtr = m_Reader.m_CurrentPtr; - QT3DSU32 restartCount = 0; - do { - m_RestartRead = false; - m_Allocated = 0; - m_Reader.m_CurrentPtr = startPtr; - ioValue.IterateProperties(*this); - ++restartCount; - } while (m_RestartRead); - } - - SIdUpdate ReadIdUpdate() - { - SIdUpdate retval; - DoRead(retval); - return retval; - }; - - SElemUpdate ReadElemUpdate() - { - SElemUpdate retval; - DoRead(retval); - return retval; - }; - - QT3DSU32 ReadInitialization() { return m_Reader.LoadRef(); } - - bool Finished() { return m_Reader.m_CurrentPtr >= m_Reader.m_EndPtr; } - }; - } -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerValue.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerValue.h deleted file mode 100644 index 3b6a4172..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphDebuggerValue.h +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_SCENE_GRAPH_DEBUGGER_VALUE_H -#define QT3DS_SCENE_GRAPH_DEBUGGER_VALUE_H -#include "Qt3DSSceneGraphDebugger.h" -#include "Qt3DSUIADatamodel.h" -#include "Qt3DSUIADatamodelValue.h" -#include "Qt3DSStateEditorValue.h" - -namespace qt3ds { -namespace state { - namespace debugger { - struct SGPropertyValueTypes - { - enum Enum { - NoSGValue = 0, - Float, - I32, - String, - Elem, - }; - }; - - template - struct SGValueTypeMap - { - }; - - template <> - struct SGValueTypeMap - { - static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::Float; } - }; - - template <> - struct SGValueTypeMap - { - static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::I32; } - }; - - template <> - struct SGValueTypeMap - { - static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::String; } - }; - - template <> - struct SGValueTypeMap - { - static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::Elem; } - }; - - struct SSGValueUnionTraits - { - typedef SGPropertyValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(QT3DSU64), - }; - - static TIdType getNoDataId() { return SGPropertyValueTypes::NoSGValue; } - - template - static TIdType getType() - { - return SGValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case SGPropertyValueTypes::Float: - return inVisitor(*NVUnionCast(inData)); - case SGPropertyValueTypes::I32: - return inVisitor(*NVUnionCast(inData)); - case SGPropertyValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case SGPropertyValueTypes::Elem: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case SGPropertyValueTypes::NoSGValue: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case SGPropertyValueTypes::Float: - return inVisitor(*NVUnionCast(inData)); - case SGPropertyValueTypes::I32: - return inVisitor(*NVUnionCast(inData)); - case SGPropertyValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case SGPropertyValueTypes::Elem: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case SGPropertyValueTypes::NoSGValue: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SSGValueUnionTraits::TBufferSize> - TSGValueUnionType; - - struct SSGValue : public TSGValueUnionType - { - SSGValue() {} - SSGValue(const SSGValue &other) - : TSGValueUnionType(static_cast(other)) - { - } - SSGValue(float val) - : TSGValueUnionType(val) - { - } - SSGValue(QT3DSI32 val) - : TSGValueUnionType(val) - { - } - SSGValue(CRegisteredString val) - : TSGValueUnionType(val) - { - } - SSGValue(QT3DSU64 val) - : TSGValueUnionType(val) - { - } - - SSGValue &operator=(const SSGValue &other) - { - TSGValueUnionType::operator=(static_cast(other)); - return *this; - } - }; - - struct SSGPropertyChange - { - QT3DSI32 m_Hash; - SSGValue m_Value; - SSGPropertyChange(QT3DSI32 h, const SSGValue &v) - : m_Hash(h) - , m_Value(v) - { - } - SSGPropertyChange() - : m_Hash(0) - { - } - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphRuntimeDebugger.cpp b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphRuntimeDebugger.cpp deleted file mode 100644 index 403fb580..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSSceneGraphRuntimeDebugger.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSSceneGraphDebugger.h" -#include "Qt3DSSceneGraphDebuggerValue.h" -#include "Qt3DSSceneGraphDebuggerProtocol.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "EASTL/sort.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::debugger; - -namespace { - -typedef eastl::pair TElemStringHandlePair; - -struct SRegisteredIDComparator -{ - bool operator()(const TElemStringHandlePair &lhs, const TElemStringHandlePair &rhs) const - { - return lhs.first < rhs.first; - } -}; - -struct SPresentationIdMap -{ - void *m_Presentation; - CRegisteredString m_PresentationId; - nvvector m_RegisteredIdBackingStore; - NVDataRef m_RegisteredIds; - SPresentationIdMap(NVAllocatorCallback &alloc) - : m_RegisteredIdBackingStore(alloc, "registered ids") - { - } -}; - -struct RuntimeDebuggerImpl : public ISceneGraphRuntimeDebugger -{ - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - NVScopedRefCounted m_OutStream; - nvvector m_ElemMapBuffer; - nvvector m_PresentationIdMap; - nvvector m_ValueUpdates; - // Filter mechanism so we don't send the same thing twice. - nvhash_map> m_LastUpdates; - SSGProtocolWriter *m_Writer; - SSAutoDeallocatorAllocator m_DataAllocator; - nvhash_map m_ElemToNameMap; - QT3DSI32 mRefCount; - - RuntimeDebuggerImpl(NVFoundationBase &fnd, IStringTable &strt) - : m_Foundation(fnd) - , m_StringTable(strt) - , m_ElemMapBuffer(fnd.getAllocator(), "elem map buffer") - , m_PresentationIdMap(fnd.getAllocator(), "Presentations") - , m_ValueUpdates(fnd.getAllocator(), "Value updates") - , m_LastUpdates(fnd.getAllocator(), "Last updates") - , m_Writer(NULL) - , m_DataAllocator(fnd) - , m_ElemToNameMap(fnd.getAllocator(), "ElemToNameMap") - , mRefCount(0) - { - } - - ~RuntimeDebuggerImpl() - { - Disconnect(); - for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) - delete m_PresentationIdMap[idx]; - // the auto-deallocator takes care of the load data. - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void Disconnect() - { - if (m_Writer) - delete m_Writer; - m_Writer = NULL; - } - - bool CheckConnection() - { - if (m_OutStream) { - bool connected = m_OutStream->Connected(); - if (!connected) - Disconnect(); - - return connected; - } - return false; - } - - void MapPresentationId(void *presentation, const char *id) override - { - CRegisteredString newId = m_StringTable.RegisterStr(nonNull(id)); - for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) { - if (m_PresentationIdMap[idx]->m_Presentation == presentation) { - m_PresentationIdMap[idx]->m_PresentationId = newId; - return; - } - } - - SPresentationIdMap *map = new SPresentationIdMap(m_Foundation.getAllocator()); - map->m_Presentation = presentation; - map->m_PresentationId = newId; - m_PresentationIdMap.push_back(map); - } - - void SendElemIdMap(SPresentationIdMap &map) - { - if (m_ElemMapBuffer.size() && CheckConnection()) { - SIdUpdate theUpdate; - theUpdate.m_Presentation = (QT3DSU64)map.m_Presentation; - theUpdate.m_PresentationId = map.m_PresentationId; - theUpdate.m_IdUpdates = m_ElemMapBuffer; - m_Writer->Write(theUpdate); - } - m_ElemMapBuffer.clear(); - } - - void MapElementIds(void *presentation, NVConstDataRef inIds) override - { - SPresentationIdMap *map = NULL; - for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end && map == NULL; ++idx) - if (m_PresentationIdMap[idx]->m_Presentation == presentation) - map = m_PresentationIdMap[idx]; - if (map == NULL) { - QT3DS_ASSERT(false); - return; - } - m_ElemMapBuffer.clear(); - m_ElemToNameMap.clear(); - for (QT3DSU32 idx = 0, end = inIds.size(); idx < end; ++idx) { - const SGElemIdMap &item(inIds[idx]); - SElemMap newMap; - newMap.m_Elem = (QT3DSU64)item.m_Elem; - CStringHandle idHandle = m_StringTable.GetHandle(nonNull(item.m_Id)); - newMap.m_Id = m_StringTable.HandleToStr(idHandle); - m_ElemMapBuffer.push_back(newMap); - m_ElemToNameMap[item.m_Elem] = idHandle; - } - SendElemIdMap(*map); - - // store them for later. - map->m_RegisteredIdBackingStore.reserve(m_ElemToNameMap.size()); - for (nvhash_map::iterator iter = m_ElemToNameMap.begin(), - end = m_ElemToNameMap.end(); - iter != end; ++iter) { - map->m_RegisteredIdBackingStore.push_back( - eastl::make_pair((QT3DSU64)iter->first, iter->second)); - } - - eastl::sort(map->m_RegisteredIdBackingStore.begin(), map->m_RegisteredIdBackingStore.end(), - SRegisteredIDComparator()); - - map->m_RegisteredIds = NVDataRef( - map->m_RegisteredIdBackingStore.data(), (QT3DSU32)map->m_RegisteredIdBackingStore.size()); - } - - static bool Equals(const SValueUpdate &lhs, const SValueUpdate &rhs) - { - return lhs.m_Hash == rhs.m_Hash && lhs.m_Value == rhs.m_Value; - } - - void OnPropertyChanged(void *elem, NVConstDataRef changes) override - { - if (CheckConnection() == false) - return; - eastl::vector &updates = m_LastUpdates[elem]; - updates.resize(changes.size()); - for (QT3DSU32 changeIdx = 0, changeEnd = changes.size(); changeIdx < changeEnd; ++changeIdx) { - SValueUpdate theUpdate; - theUpdate.m_Hash = changes[changeIdx].m_Hash; - theUpdate.m_Value = changes[changeIdx].m_Value; - if (Equals(theUpdate, updates[changeIdx]) == false) { - updates[changeIdx] = theUpdate; - m_ValueUpdates.push_back(theUpdate); - } - } - if (m_ValueUpdates.size()) { - SElemUpdate theUpdate; - theUpdate.m_Elem = (QT3DSU64)elem; - theUpdate.m_Updates = m_ValueUpdates; - m_Writer->Write(theUpdate); - m_ValueUpdates.clear(); - } - } - - void SendPresentation(SPresentationIdMap &pres) - { - if (m_OutStream) { - m_ElemMapBuffer.clear(); - for (TElemStringHandlePair *iter = pres.m_RegisteredIds.begin(), - *end = pres.m_RegisteredIds.end(); - iter != end; ++iter) { - SElemMap newMap; - newMap.m_Elem = (QT3DSU64)iter->first; - newMap.m_Id = m_StringTable.HandleToStr(iter->second); - m_ElemMapBuffer.push_back(newMap); - } - SendElemIdMap(pres); - } - } - - void OnConnection(IDebugOutStream &outStream) override - { - Disconnect(); - m_OutStream = outStream; - m_Writer = new SSGProtocolWriter(outStream, m_Foundation.getAllocator()); - m_Writer->WriteInitialization(); - for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) { - SPresentationIdMap *map = m_PresentationIdMap[idx]; - SendPresentation(*map); - } - } - - bool IsConnected() override { return CheckConnection(); } - - void BinarySave(IOutStream &ioStream) override - { - qt3ds::foundation::SWriteBuffer theWriteBuffer(m_Foundation.getAllocator(), - "BinarySave::writebuffer"); - - theWriteBuffer.writeZeros(4); // Overall binary size - theWriteBuffer.write((QT3DSU32)m_PresentationIdMap.size()); - for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) { - // There is no use to writing out the presentation pointer address. - /* - void* - m_Presentation; - CRegisteredString m_PresentationId; - nvhash_map m_RegisteredIds; - */ - - SPresentationIdMap *map = m_PresentationIdMap[idx]; - CRegisteredString presId(map->m_PresentationId); - presId.Remap(m_StringTable.GetRemapMap()); - theWriteBuffer.write(presId); - theWriteBuffer.write((QT3DSU32)map->m_RegisteredIds.size()); - theWriteBuffer.write(map->m_RegisteredIds.begin(), map->m_RegisteredIds.size()); - } - - QT3DSU32 totalSize = theWriteBuffer.size(); - QT3DSU32 *data = (QT3DSU32 *)theWriteBuffer.begin(); - data[0] = totalSize - 4; - ioStream.Write((QT3DSU8 *)data, totalSize); - } - - void BinaryLoad(IInStream &ioStream, NVDataRef strTableData) override - { - QT3DSU32 length; - ioStream.Read(length); - QT3DSU8 *data = (QT3DSU8 *)m_DataAllocator.allocate(length, "Binaryload", __FILE__, __LINE__); - ioStream.Read(data, length); - SDataReader theReader(data, data + length); - QT3DSU32 numPresentations = theReader.LoadRef(); - QT3DS_ASSERT(m_PresentationIdMap.size() == 0); - m_PresentationIdMap.resize(numPresentations); - for (QT3DSU32 idx = 0, end = numPresentations; idx < end; ++idx) { - m_PresentationIdMap[idx] = new SPresentationIdMap(m_Foundation.getAllocator()); - SPresentationIdMap *map = m_PresentationIdMap[idx]; - map->m_PresentationId = theReader.LoadRef(); - map->m_PresentationId.Remap(strTableData); - QT3DSU32 numElems = theReader.LoadRef(); - map->m_RegisteredIds = - toDataRef((TElemStringHandlePair *)theReader.m_CurrentPtr, numElems); - theReader.m_CurrentPtr += numElems * sizeof(TElemStringHandlePair); - } - } - - void BinaryLoadPresentation(void *presPtr, const char *id, size_t elemOffset) override - { - CRegisteredString presId(m_StringTable.RegisterStr(id)); - SPresentationIdMap *foundPres = NULL; - for (QT3DSU32 idx = 0, end = (QT3DSU32)m_PresentationIdMap.size(); idx < end && foundPres == NULL; - ++idx) { - if (m_PresentationIdMap[idx]->m_PresentationId == presId) - foundPres = m_PresentationIdMap[idx]; - } - if (foundPres == NULL) { - QT3DS_ASSERT(false); - return; - } - - foundPres->m_Presentation = presPtr; - nvvector> newElemIds(m_Foundation.getAllocator(), - "Temp load map"); - newElemIds.reserve(foundPres->m_RegisteredIds.size()); - for (TElemStringHandlePair *iter = foundPres->m_RegisteredIds.begin(), - *end = foundPres->m_RegisteredIds.end(); - iter != end; ++iter) { - size_t oldId = (size_t)iter->first; - size_t newId = elemOffset + oldId; - iter->first = (QT3DSU64)newId; - } - SendPresentation(*foundPres); - } - - void EndFrame() override - { - if (CheckConnection()) - m_Writer->WriteFrame(); - } - - void OnMessageReceived(const SDebugStreamMessage &) override { QT3DS_ASSERT(false); } -}; -} - -ISceneGraphRuntimeDebugger &ISceneGraphRuntimeDebugger::Create(NVFoundationBase &fnd, - IStringTable &strTable) -{ - return *QT3DS_NEW(fnd.getAllocator(), RuntimeDebuggerImpl)(fnd, strTable); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDataTest.cpp b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDataTest.cpp deleted file mode 100644 index ced1397b..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDataTest.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateTest.h" -#include "foundation/IOStreams.h" -#include "EASTL/string.h" -#include "foundation/Utils.h" -#include "foundation/FileTools.h" -#include "foundation/XML.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/TrackingAllocator.h" -#include "foundation/StringTable.h" -#include "Qt3DSStateContext.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSStateExecutionContext.h" -#include "Qt3DSStateInterpreter.h" - -using namespace qt3ds::state::test; -using namespace qt3ds::state; - -namespace { - -struct XMLHandler : public qt3ds::foundation::CXmlErrorHandler -{ - IDataLogger &m_Logger; - const char8_t *m_File; - eastl::string m_ErrorString; - XMLHandler(IDataLogger &logger, const char8_t *fname) - : m_Logger(logger) - , m_File(fname) - { - } - - void OnXmlError(qt3ds::foundation::TXMLCharPtr errorName, int line, int /*column*/) override - { - m_ErrorString.assign("Failed to parse test file: "); - m_ErrorString.append(m_File); - m_Logger.Log(LogType::Error, m_File, line, errorName); - } -}; - -Option RunTest(const char8_t *inFullPath, const char8_t *inRoot, - IDataLogger &inLogger) -{ - return STestResults(1, 1); -} -} - -Option IDataTest::RunFile(const char8_t *fname, const char8_t *inRootDir, - IDataLogger &inLogger) -{ - return RunTest(fname, inRootDir, inLogger); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.cpp b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.cpp deleted file mode 100644 index 707ea73e..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateDebugStreams.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include "EASTL/string.h" - -using namespace qt3ds; -using namespace qt3ds::state; -using namespace qt3ds::state::debugger; - -namespace { - -struct MultiProtocolMessageTypes -{ - enum Enum { - UnknownMessageType = 0, - NewProtocol = 1, - ProtocolMessage = 1 << 2, - }; -}; - -struct SMultiProtocolMessageFlags : public NVFlags -{ - bool IsNewProtocol() { return this->operator&(MultiProtocolMessageTypes::NewProtocol); } - void SetNewProtocol(bool inValue) - { - this->clearOrSet(inValue, MultiProtocolMessageTypes::NewProtocol); - } - - bool IsProtocolMessage() { return this->operator&(MultiProtocolMessageTypes::ProtocolMessage); } - void SetProtocolMessage(bool inValue) - { - this->clearOrSet(inValue, MultiProtocolMessageTypes::ProtocolMessage); - } -}; - -struct SMultiProtocolInitializer -{ - static QT3DSU16 GetCurrentMultiProtocolVersion() { return 1; } - - QT3DSU64 m_TimeNumerator; - QT3DSU64 m_TimeDenominator; - QT3DSU32 m_ProtocolVersion; - - SMultiProtocolInitializer() - : m_TimeNumerator(Time::sCounterFreq.mNumerator) - , m_TimeDenominator(Time::sCounterFreq.mDenominator) - , m_ProtocolVersion(GetCurrentMultiProtocolVersion()) - { - } -}; - -struct SMultiProtocolMessageHeader -{ - - SMultiProtocolMessageFlags m_Flags; - QT3DSU32 m_Size; - QT3DSU32 m_ProtocolId; - QT3DSU64 m_Timestamp; - SMultiProtocolMessageHeader(MultiProtocolMessageTypes::Enum inMessageType, QT3DSU32 size, - QT3DSU32 protocolId, QT3DSU64 timestamp) - : m_Size(size) - , m_ProtocolId(protocolId) - , m_Timestamp(timestamp) - { - m_Flags.clearOrSet(true, inMessageType); - } - SMultiProtocolMessageHeader() {} -}; - -struct IProtocolMessageHandler -{ -protected: - virtual ~IProtocolMessageHandler() {} -public: - virtual void OnMessageReceived(SDebugStreamMessage msgData) = 0; -}; - -struct IProtocolHandler -{ -protected: - virtual ~IProtocolHandler() {} -public: - virtual void OnNewProtocol(CRegisteredString inProtocolName) = 0; -}; - -struct SSharedStreamImpl : public NVRefCounted -{ - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_Stream; - IOutStream &m_WriteStream; - SMultiProtocolInitializer m_Initializer; - eastl::hash_map m_ProtocolIdMap; - eastl::hash_map m_MessageHandlers; - MemoryBuffer<> m_ReadBuffer; - IStringTable &m_StringTable; - IProtocolHandler *m_ProtocolHandler; - QT3DSU32 m_NextProtocolId; - QT3DSI32 mRefCount; - - SSharedStreamImpl(NVFoundationBase &fnd, SocketStream &stream, IOutStream &writeStream, - IStringTable &strTable, IProtocolHandler &pHandler) - : m_Foundation(fnd) - , m_Stream(stream) - , m_WriteStream(writeStream) - , m_ReadBuffer(ForwardingAllocator(fnd.getAllocator(), "ReadBuffer")) - , m_StringTable(strTable) - , m_ProtocolHandler(&pHandler) - , m_NextProtocolId(1) - , mRefCount(0) - { - NVConstDataRef msgData = toU8DataRef(m_Initializer); - bool streamValid = m_Stream->Write(msgData); - if (streamValid == false) - m_Stream = NULL; - } - ~SSharedStreamImpl() {} - - bool Initialize() - { - if (m_Stream) { - NVDataRef msgData = toU8DataRef(m_Initializer); - QT3DSU32 numBytes = m_Stream->Read(msgData); - if (numBytes != sizeof(SMultiProtocolInitializer) - || m_Initializer.m_ProtocolVersion - > SMultiProtocolInitializer::GetCurrentMultiProtocolVersion()) { - m_Stream = NULL; - return false; - } - return true; - } - return false; - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - QT3DSU32 GetIdForProtocol(CRegisteredString protocol) - { - if (protocol.IsValid() == false) - return 0; - eastl::pair::iterator, bool> inserter = - m_ProtocolIdMap.insert(eastl::make_pair(protocol, m_NextProtocolId)); - if (inserter.second) { - QT3DSU32 newId = m_NextProtocolId; - ++m_NextProtocolId; - if (m_Stream) { - QT3DSU32 msgLen = (QT3DSU32)strlen(protocol) + 1; - NVConstDataRef writeBuf(reinterpret_cast(protocol.c_str()), - msgLen); - WriteMessage(MultiProtocolMessageTypes::NewProtocol, writeBuf, newId); - } - } - return inserter.first->second; - } - - CRegisteredString GetProtocolForId(QT3DSU32 id) - { - for (eastl::hash_map::iterator iter = m_ProtocolIdMap.begin(), - end = m_ProtocolIdMap.end(); - iter != end; ++iter) { - if (iter->second == id) - return iter->first; - } - return CRegisteredString(); - } - - void AddMessageHandler(CRegisteredString protocol, IProtocolMessageHandler &hdl) - { - m_MessageHandlers.insert(eastl::make_pair(GetIdForProtocol(protocol), &hdl)); - } - - void RemoveMessageHandler(CRegisteredString protocol) - { - m_MessageHandlers.erase(GetIdForProtocol(protocol)); - } - - IProtocolMessageHandler *GetMessageHandler(CRegisteredString protocol) - { - return GetMessageHandler(GetIdForProtocol(protocol)); - } - - IProtocolMessageHandler *GetMessageHandler(QT3DSU32 protocolId) - { - eastl::hash_map::iterator iter = - m_MessageHandlers.find(protocolId); - if (iter != m_MessageHandlers.end()) - return iter->second; - return NULL; - } - - void ProtocolHandlerLeaving() { m_ProtocolHandler = NULL; } - - void DispatchMessage(SMultiProtocolMessageHeader inHeader, NVConstDataRef msg) - { - if (inHeader.m_Flags.IsNewProtocol()) { - char *pId = reinterpret_cast(const_cast(msg.begin())); - // Ensure null terminated, which should be done anyway but we don't know it will be. - pId[inHeader.m_Size] = 0; - CRegisteredString protocolName = m_StringTable.RegisterStr(pId); - eastl::pair::iterator, bool> inserter = - m_ProtocolIdMap.insert(eastl::make_pair(protocolName, inHeader.m_ProtocolId)); - if (inserter.second == false) { - // remap id to higher id to reduce the chance of conflicts. - QT3DSU32 potentialNewId = NVMax(inserter.first->second, inHeader.m_ProtocolId); - if (potentialNewId != inserter.first->second) { - m_NextProtocolId = NVMax(m_NextProtocolId, potentialNewId + 1); - CRegisteredString existing = GetProtocolForId(potentialNewId); - if (existing.IsValid()) { - m_ProtocolIdMap.erase(protocolName); - GetIdForProtocol(protocolName); - return; - } else { - inserter.first->second = potentialNewId; - } - } - } else { - if (m_ProtocolHandler != NULL) { - m_ProtocolHandler->OnNewProtocol(protocolName); - } - } - } else { - IProtocolMessageHandler *handler = GetMessageHandler(inHeader.m_ProtocolId); - if (handler != NULL) - handler->OnMessageReceived(SDebugStreamMessage(inHeader.m_Timestamp, msg)); - } - } - - NVDataRef ReadChunk(NVDataRef target) - { - QT3DSU32 totalRead = 0; - do { - NVDataRef nextBuf(target.begin() + totalRead, target.size() - totalRead); - QT3DSU32 readResult = m_Stream->Read(nextBuf); - totalRead += readResult; - if (totalRead < target.size()) { - totalRead = totalRead; - } - } while (connected() && totalRead < target.size()); - - return toDataRef(m_ReadBuffer.begin(), totalRead); - } - - NVDataRef ReadChunk(QT3DSU32 size) - { - m_ReadBuffer.reserve(size); - return ReadChunk(toDataRef(m_ReadBuffer.begin(), size)); - } - - virtual SDebugStreamMessage WaitForNextMessage(CRegisteredString protocol) - { - QT3DSU32 msgId = GetIdForProtocol(protocol); - - while (m_Stream) { - SMultiProtocolMessageHeader header; - NVDataRef buf = toU8DataRef(header); - buf = ReadChunk(buf); - if (buf.size() < sizeof(header)) { - m_Stream = NULL; - QT3DS_ASSERT(false); - } else { - NVDataRef readResult = ReadChunk(header.m_Size); - if (readResult.mSize != header.m_Size) { - m_Stream = NULL; - QT3DS_ASSERT(false); - } else { - if (header.m_ProtocolId == msgId) { - SDebugStreamMessage message; - message.m_Timestamp = header.m_Timestamp; - message.m_Data = readResult; - return message; - } else - DispatchMessage(header, readResult); - } - } - } - - return SDebugStreamMessage(); - } - - virtual void MessagePump() - { - if (m_Stream == NULL) - return; - bool lastMessage = true; - do { - SMultiProtocolMessageHeader header; - NVDataRef buf = toU8DataRef(header); - QT3DSU32 amountRead = m_Stream->nonBlockingRead(buf); - if (amountRead == 0) { - if (m_Stream->connected() == false) - m_Stream = NULL; - lastMessage = false; - } else { - // read the rest of the header. - QT3DSU32 leftover = buf.size() - amountRead; - if (leftover) { - NVDataRef nextPiece(buf.begin() + amountRead, leftover); - nextPiece = ReadChunk(nextPiece); - amountRead += nextPiece.size(); - } - - if (amountRead < sizeof(SMultiProtocolMessageHeader)) { - m_Stream = NULL; - QT3DS_ASSERT(false); - - } else { - NVDataRef msgData = ReadChunk(header.m_Size); - if (msgData.size() == header.m_Size) { - DispatchMessage(header, msgData); - } else { - m_Stream = NULL; - QT3DS_ASSERT(false); - } - } - } - - } while (lastMessage && m_Stream); - } - - SMultiProtocolMessageHeader CreateHeader(MultiProtocolMessageTypes::Enum type, QT3DSU32 size, - QT3DSU32 protocolId) - { - SMultiProtocolMessageHeader retval; - retval.m_Flags.clearOrSet(true, type); - retval.m_ProtocolId = protocolId; - retval.m_Size = size; - retval.m_Timestamp = Time::getCurrentCounterValue(); - return retval; - } - - bool WriteMessage(MultiProtocolMessageTypes::Enum type, NVConstDataRef data, - QT3DSU32 protocolId) - { - if (connected()) { - SMultiProtocolMessageHeader header(CreateHeader(type, data.size(), protocolId)); - NVConstDataRef writeBuf = toU8DataRef(header); - bool success = m_WriteStream.Write(writeBuf); - if (success) { - success = m_WriteStream.Write(data); - } - if (!success) - m_Stream = NULL; - return success; - } - return false; - } - - virtual bool Write(CRegisteredString protocol, NVConstDataRef data) - { - return WriteMessage(MultiProtocolMessageTypes::ProtocolMessage, data, - GetIdForProtocol(protocol)); - } - - bool connected() { return m_Stream != NULL && m_Stream->connected(); } -}; - -struct SMultiProtocolSocketStreamImpl : public IMultiProtocolSocketStream, - public IProtocolMessageHandler -{ - NVFoundationBase &m_Foundation; - CRegisteredString m_Protocol; - IDebugStreamListener *m_Listener; - NVScopedRefCounted m_SharedStream; - bool m_StreamValid; - QT3DSI32 mRefCount; - - SMultiProtocolSocketStreamImpl(NVFoundationBase &fnd, CRegisteredString protocol, - IDebugStreamListener *listener, SSharedStreamImpl &stream) - : m_Foundation(fnd) - , m_Protocol(protocol) - , m_Listener(listener) - , m_SharedStream(stream) - , m_StreamValid(true) - , mRefCount(0) - { - m_SharedStream->AddMessageHandler(m_Protocol, *this); - } - - ~SMultiProtocolSocketStreamImpl() { m_SharedStream->RemoveMessageHandler(m_Protocol); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - IDebugStreamListener *GetListener() override { return m_Listener; } - CRegisteredString GetProtocolName() override { return m_Protocol; } - - void SetListener(IDebugStreamListener *listener) override { m_Listener = listener; } - - bool Write(NVConstDataRef data) override - { - if (m_StreamValid) - m_StreamValid = m_SharedStream->Write(m_Protocol, data); - - return m_StreamValid; - } - - SDebugStreamMessage WaitForNextMessage() override - { - if (m_StreamValid) - return m_SharedStream->WaitForNextMessage(m_Protocol); - return SDebugStreamMessage(); - } - - void OnMessageReceived(SDebugStreamMessage data) override - { - if (m_Listener) - m_Listener->OnMessageReceived(data); - } - - bool Connected() override { return m_SharedStream->connected(); } -}; - -struct SMultiProtocolSocketImpl : public IMultiProtocolSocket, public IProtocolHandler -{ - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_SharedStream; - NVScopedRefCounted m_ProtocolListener; - QT3DSI32 mRefCount; - SMultiProtocolSocketImpl(NVFoundationBase &fnd, SocketStream &inStream, IStringTable &strTable, - IMultiProtocolSocketListener *protocolListener) - : m_Foundation(fnd) - , m_ProtocolListener(protocolListener) - , mRefCount(0) - { - // At some point I may switch the writer to a buffered stream, at least on the client side. - m_SharedStream = QT3DS_NEW(m_Foundation.getAllocator(), SSharedStreamImpl)( - m_Foundation, inStream, inStream, strTable, *this); - } - - ~SMultiProtocolSocketImpl() { m_SharedStream->ProtocolHandlerLeaving(); } - - bool Initialize() override { return m_SharedStream->Initialize(); } - - bool Connected() override { return m_SharedStream->connected(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - virtual NVScopedRefCounted - CreateProtocol(const char *name, IDebugStreamListener *inListener) override - { - NVScopedRefCounted retval = GetProtocol(name); - if (retval) { - QT3DS_ASSERT(false); - return retval; - } - CRegisteredString protocolName = m_SharedStream->m_StringTable.RegisterStr(name); - if (protocolName.IsValid() == false) { - QT3DS_ASSERT(false); - return retval; - } - SMultiProtocolSocketStreamImpl *newStream = - QT3DS_NEW(m_Foundation.getAllocator(), SMultiProtocolSocketStreamImpl)( - m_Foundation, protocolName, inListener, *m_SharedStream); - return newStream; - } - - NVScopedRefCounted GetProtocol(const char *name) override - { - CRegisteredString protocolName = m_SharedStream->m_StringTable.RegisterStr(name); - IProtocolMessageHandler *handler = m_SharedStream->GetMessageHandler(protocolName); - if (handler) { - SMultiProtocolSocketStreamImpl *theImpl = - static_cast(handler); - return theImpl; - } - return NVScopedRefCounted(); - } - - void OnNewProtocol(CRegisteredString inProtocolName) override - { - if (m_ProtocolListener) { - // We can expect the user to call create protocol at this point. - IDebugStreamListener *handler = m_ProtocolListener->OnNewProtocol(inProtocolName); - if (handler) { - SMultiProtocolSocketStreamImpl *newStream = - QT3DS_NEW(m_Foundation.getAllocator(), SMultiProtocolSocketStreamImpl)( - m_Foundation, inProtocolName, handler, *m_SharedStream); - m_ProtocolListener->OnNewProtocolStream(inProtocolName, *newStream); - } - } - } - - CounterFrequencyToTensOfNanos SourceConversion() override - { - return CounterFrequencyToTensOfNanos(m_SharedStream->m_Initializer.m_TimeNumerator, - m_SharedStream->m_Initializer.m_TimeDenominator); - } - - void MessagePump() override { m_SharedStream->MessagePump(); } -}; -} - -NVScopedRefCounted -IMultiProtocolSocket::CreateProtocolSocket(NVFoundationBase &fnd, SocketStream &inStream, - IStringTable &strTable, - IMultiProtocolSocketListener *protocolListener) -{ - return QT3DS_NEW(fnd.getAllocator(), SMultiProtocolSocketImpl)(fnd, inStream, strTable, - protocolListener); -} - diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.h deleted file mode 100644 index 5bbc0b26..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugStreams.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_DEBUG_STREAMS_H -#define QT3DS_STATE_DEBUG_STREAMS_H -#pragma once -#include "Qt3DSState.h" -#include "foundation/Socket.h" -#include "foundation/Qt3DSTime.h" -#include "Qt3DSStateDebugger.h" - -struct script_State; - -namespace qt3ds { -namespace state { - namespace debugger { - - class IMultiProtocolSocketStream : public IDebugOutStream - { - public: - virtual CRegisteredString GetProtocolName() = 0; - }; - - class IMultiProtocolSocketListener : public NVRefCounted - { - public: - // If a listener is returned from on new protocol, the system creates a stream - // with the returned listener - virtual IDebugStreamListener *OnNewProtocol(CRegisteredString inProtocolName) = 0; - // Created with the listener returned from OnNewProtocol. - virtual void OnNewProtocolStream(CRegisteredString inProtocolName, - IMultiProtocolSocketStream &inStream) = 0; - }; - - // Create a system of multiplexing multipler unrelated protocols - // through a single network socket. - class IMultiProtocolSocket : public NVRefCounted - { - public: - virtual bool Initialize() = 0; - virtual NVScopedRefCounted - CreateProtocol(const char *name, IDebugStreamListener *inListener) = 0; - virtual NVScopedRefCounted - GetProtocol(const char *name) = 0; - virtual bool Connected() = 0; - - // Upon connection the multi protocol system does a handshake where both sides send - // their nanosecond - // conversions across. Note that the times sent on the multi protocol packets are in a - // system-specific 64 bit quantity that - // needs conversion to actual nanoseconds to be useful (identical to - // QueryHighPerformanceFrequency, QueryHighPerformanceCounter - virtual CounterFrequencyToTensOfNanos SourceConversion() = 0; - - // Manually do a nonblocking check on the network socket for any new information and - // call the various stream listeners - // with information packets if found. - virtual void MessagePump() = 0; - - static NVScopedRefCounted - CreateProtocolSocket(NVFoundationBase &fnd, SocketStream &inStream, - IStringTable &strTable, - IMultiProtocolSocketListener *protocolListener); - }; - - class CProtocolNames - { - public: - static const char *getMobdebugProtocolName() { return "mobdebug"; } - static const char *getSCXMLProtocolName() { return "scxml"; } - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggedInterpreter.cpp b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggedInterpreter.cpp deleted file mode 100644 index a64e8589..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggedInterpreter.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateDebugger.h" -#include "Qt3DSStateDebuggerProtocol.h" -#include "EASTL/map.h" -#include "EASTL/set.h" -#include "foundation/Qt3DSAtomic.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::debugger; - -namespace { - -// Horrible name, I know. -struct SDebuggedInterpreter : public IDebuggedInterpreter -{ - typedef eastl::set TDebugStrSet; - typedef eastl::vector TBreakpointList; - typedef eastl::map TDataModelTable; - typedef eastl::hash_map TTableMap; - typedef eastl::vector TTableEntryList; - // Null is the datamodel table. - - NVAllocatorCallback &m_Allocator; - NVScopedRefCounted m_Stream; - QT3DSI32 mRefCount; - TEditorPtr m_Editor; - TDebugStr m_Filename; - SMessageSerializer m_Serializer; - QT3DSI32 m_StreamId; - TBreakpointList m_Breakpoints; - TDebugStrList m_StrList; - TDebugStrSet m_Configuration; - bool m_BreakOnMicrostep; - bool m_IsBroken; - Option m_BrokenBreakpoint; - IDebuggerMasterListener &m_Listener; - TTableMap m_DatamodelValues; - mutable TTableEntryList m_TempEntries; - bool m_MicrostepHasData; - SMicrostepData m_MicrostepData; - TDebugStr m_MicrostepEvent; - TDebugStrList m_ConfigurationList; - TDebugStrList m_PreviousConfiguration; - - SDebuggedInterpreter(NVAllocatorCallback &inAlloc, IDebugOutStream &inStream, - TEditorPtr inEditor, const TDebugStr &inFname, QT3DSI32 inStreamId, - NVConstDataRef inConfiguration, - IDebuggerMasterListener &inListener) - : m_Allocator(inAlloc) - , m_Stream(inStream) - , mRefCount(0) - , m_Editor(inEditor) - , m_Filename(inFname) - , m_StreamId(inStreamId) - , m_BreakOnMicrostep(false) - , m_IsBroken(false) - , m_Listener(inListener) - , m_MicrostepHasData(false) - { - m_ConfigurationList.assign(inConfiguration.begin(), inConfiguration.end()); - m_Configuration.insert(inConfiguration.begin(), inConfiguration.end()); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) - - // Get the editor that represents the state graph for this debugged interpreter. - TEditorPtr GetEditor() override { return m_Editor; } - TDebugStr GetFilename() const override { return m_Filename; } - - template - void SendMessage(const TMessageType &inMessage) - { - m_Serializer.Serialize(m_StreamId, inMessage, 0); - m_Stream->Write(m_Serializer.ToRawMessage()); - } - - // Used when connecting to a live session. - void SetBreakpoint(const SBreakpoint &inBreakpoint) override - { - TBreakpointList::iterator iter = - eastl::find(m_Breakpoints.begin(), m_Breakpoints.end(), inBreakpoint); - if (iter == m_Breakpoints.end()) { - SendMessage(SSetBreakpoint(inBreakpoint)); - m_Breakpoints.push_back(inBreakpoint); - } - } - - void ClearBreakpoint(const SBreakpoint &inBreakpoint) override - { - TBreakpointList::iterator iter = - eastl::find(m_Breakpoints.begin(), m_Breakpoints.end(), inBreakpoint); - if (iter != m_Breakpoints.end()) { - SendMessage(SClearBreakpoint(inBreakpoint)); - m_Breakpoints.erase(iter); - } - } - - NVConstDataRef GetBreakpoints() override - { - return toDataRef(m_Breakpoints.data(), m_Breakpoints.size()); - } - - void ClearAllBreakpoints() override - { - SendMessage(SClearAllBreakpoints()); - m_Breakpoints.clear(); - } - - // break at the *end* of the microstep so you can see the data of the microstep. - void SetBreakOnMicrostep(bool inBreak) override - { - if (m_BreakOnMicrostep != inBreak) { - m_BreakOnMicrostep = inBreak; - SendMessage(SBreakOnMicrostep(inBreak)); - } - } - bool IsBreakOnMicrostep() const override { return m_BreakOnMicrostep; } - - NVConstDataRef TableToList(const TDataModelTable &inTable) const - { - m_TempEntries.resize(inTable.size()); - QT3DSU32 idx = 0; - for (TDataModelTable::const_iterator iter = inTable.begin(), end = inTable.end(); - iter != end; ++iter, ++idx) - m_TempEntries[idx] = STableEntry(iter->first, iter->second); - return toConstDataRef(m_TempEntries.data(), m_TempEntries.size()); - } - - NVConstDataRef GetTableValues(SDatamodelTable *inTable) const override - { - TTableMap::const_iterator iter = m_DatamodelValues.find(inTable); - if (iter != m_DatamodelValues.end()) - return TableToList(iter->second); - return NVConstDataRef(); - } - - NVConstDataRef GetPreviousConfiguration() const override - { - return toConstDataRef(m_PreviousConfiguration.data(), m_PreviousConfiguration.size()); - } - NVConstDataRef GetConfiguration() const override - { - return toConstDataRef(m_ConfigurationList.data(), m_ConfigurationList.size()); - } - const TDebugStr &GetMicrostepEvent() const override { return m_MicrostepEvent; } - NVConstDataRef GetMicrostepTransitions() const override - { - return toConstDataRef(m_MicrostepData.m_Transitions.data(), - m_MicrostepData.m_Transitions.size()); - } - NVConstDataRef GetMicrostepEnterStates() const override - { - return toConstDataRef(m_MicrostepData.m_EnterStates.data(), - m_MicrostepData.m_EnterStates.size()); - } - NVConstDataRef GetMicrostepExitStates() const override - { - return toConstDataRef(m_MicrostepData.m_ExitStates.data(), - m_MicrostepData.m_ExitStates.size()); - } - void Continue() override - { - SendMessage(SContinue()); - m_IsBroken = false; - m_BrokenBreakpoint = Option(); - } - - void Disconnect() override - { - ClearAllBreakpoints(); - SetBreakOnMicrostep(false); - if (m_IsBroken == true) - Continue(); - - SendMessage(SDisconnect()); - } - - void BreakpointHit(const SBreakpoint &inBreakpoint) override - { - m_BrokenBreakpoint = inBreakpoint; - m_IsBroken = true; - m_Listener.OnInterpreterBroken(*this, inBreakpoint); - } - - void OnEventQueued(const SEventQueued &inMsg) override - { - m_Listener.OnEventQueued(inMsg.m_Event, inMsg.m_Internal); - } - - void OnBeginStep(const SBeginStep &) override { m_Listener.OnBeginStep(*this); } - - void OnBeginMicrostep(const SBeginMicrostep &) override - { - m_MicrostepEvent.clear(); - m_MicrostepData.m_Transitions.clear(); - m_MicrostepData.m_EnterStates.clear(); - m_MicrostepData.m_ExitStates.clear(); - m_MicrostepHasData = false; - m_Listener.OnBeginMicrostep(*this); - } - - void OnMicrostepEvent(const SMicrostepEvent &inMsg) override - { - m_MicrostepEvent = inMsg.m_Event; - } - - void OnMicrostepData(const SMicrostepData &inMsg) override - { - m_MicrostepData = inMsg; - m_MicrostepHasData = true; - } - void OnEndMicrostep(const SEndMicrostep & /*inMsg*/) override - { - if (m_MicrostepHasData == false && m_MicrostepEvent.empty() == false) { - m_Listener.OnEventProcessed(m_MicrostepEvent, false); - } else { - m_PreviousConfiguration = m_ConfigurationList; - - for (TDebugStrList::const_iterator iter = m_MicrostepData.m_ExitStates.begin(), - end = m_MicrostepData.m_ExitStates.end(); - iter != end; ++iter) - m_Configuration.erase(*iter); - - m_Configuration.insert(m_MicrostepData.m_EnterStates.begin(), - m_MicrostepData.m_EnterStates.end()); - - m_ConfigurationList.clear(); - m_ConfigurationList.insert(m_ConfigurationList.end(), m_Configuration.begin(), - m_Configuration.end()); - if (m_BreakOnMicrostep) { - m_IsBroken = true; - m_Listener.OnInterpreterBroken(*this, Option()); - } else - m_Listener.OnMicrostep(*this); - } - } - - void OnModifyTable(const SModifyTableValues &inValues) override - { - TTableMap::iterator iter = - m_DatamodelValues.insert(eastl::make_pair(inValues.m_TablePtr, TDataModelTable())) - .first; - for (QT3DSU32 idx = 0, end = inValues.m_Modifications.size(); idx < end; ++idx) { - const STableModification &theMod(inValues.m_Modifications[idx]); - switch (theMod.m_Type) { - case TableModificationType::RemoveKey: - iter->second.erase(theMod.m_Entry.m_Key); - break; - case TableModificationType::SetKey: - (iter->second)[theMod.m_Entry.m_Key] = theMod.m_Entry.m_Value; - break; - default: - QT3DS_ASSERT(false); - break; - } - } - m_Listener.OnDatamodelChange( - *this, inValues.m_TablePtr, - toConstDataRef(inValues.m_Modifications.data(), inValues.m_Modifications.size())); - } - - bool IsBroken() const override { return m_IsBroken; } -}; -} - -IDebuggedInterpreter &IDebuggedInterpreter::Create(NVAllocatorCallback &inAlloc, - IDebugOutStream &inStream, TEditorPtr inEditor, - const TDebugStr &inFilename, QT3DSI32 inStreamId, - NVConstDataRef inConfiguration, - IDebuggerMasterListener &inListener) -{ - return *QT3DS_NEW(inAlloc, SDebuggedInterpreter)(inAlloc, inStream, inEditor, inFilename, - inStreamId, inConfiguration, inListener); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.cpp b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.cpp deleted file mode 100644 index 5917db60..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateDebugger.h" -#include "Qt3DSStateDebuggerValues.h" -#include "Qt3DSStateDebuggerProtocol.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/IOStreams.h" - -using namespace qt3ds::state::debugger; -using namespace qt3ds::state; - -namespace { - -static MallocAllocator g_MallocAlloc; - -struct SDebugger : public IDebugger -{ - typedef eastl::vector> TDebugList; - typedef eastl::hash_map TMachineIdMap; - typedef eastl::hash_map, - NVScopedRefCounted>> - TIdMachineMap; - QT3DSI32 mRefCount; - QT3DSI32 m_NextStateMachineId; - TDebugList m_StateMachineList; - TMachineIdMap m_StateMachines; - TIdMachineMap m_IdToStateMachines; - QT3DSU64 m_StartTime; - NVScopedRefCounted m_OutStream; - SMessageParser m_Parser; - SMessageSerializer m_MessageSerializer; - TDebugStr m_MessageStr; - - SDebugger() - : mRefCount(0) - , m_NextStateMachineId(1) - , m_StartTime(Time::getCurrentCounterValue()) - { - } - - virtual ~SDebugger() { DisconnectFromServer(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_MallocAlloc) - - void ConnectStateMachine(IStateMachineDebugInterface &inMachine) - { - TMachineIdMap::iterator theIter = m_StateMachines.find(&inMachine); - if (theIter != m_StateMachines.end()) - return; - QT3DSI32 theId(m_NextStateMachineId); - ++m_NextStateMachineId; - IStateMachineListener *theListener = - &IStateMachineListener::Create(g_MallocAlloc, theId, *m_OutStream.mPtr, m_StartTime, - *this, inMachine.GetScriptContext()); - inMachine.SetStateMachineListener(theListener); - m_StateMachines.insert(eastl::make_pair(&inMachine, theId)); - m_IdToStateMachines.insert( - eastl::make_pair(theId, eastl::make_pair(&inMachine, theListener))); - } - - void OnServerConnected(IDebugOutStream &inStream) override - { - m_OutStream = inStream; - inStream.SetListener(this); - m_MessageSerializer.Serialize(0, SInitialization(), m_StartTime); - m_OutStream->Write(m_MessageSerializer.ToRawMessage()); - for (QT3DSU32 idx = 0, end = m_StateMachineList.size(); idx < end; ++idx) - ConnectStateMachine(*m_StateMachineList[idx]); - } - - void Connect(IStateMachineDebugInterface &inMachine) override - { - TDebugList::iterator theFind = - eastl::find(m_StateMachineList.begin(), m_StateMachineList.end(), &inMachine); - if (theFind == m_StateMachineList.end()) { - m_StateMachineList.push_back(&inMachine); - if (m_OutStream) - ConnectStateMachine(inMachine); - } - } - - void DisconnectStateMachine(IStateMachineDebugInterface &inMachine) - { - TMachineIdMap::iterator theIter = m_StateMachines.find(&inMachine); - if (theIter == m_StateMachines.end()) - return; - - QT3DSI32 theId = theIter->second; - m_MessageSerializer.Serialize(theId, SDisconnect(), - Time::getCurrentCounterValue() - m_StartTime); - m_OutStream->Write(m_MessageSerializer.ToRawMessage()); - inMachine.SetStateMachineListener(NULL); - m_StateMachines.erase(&inMachine); - m_IdToStateMachines.erase(theId); - } - void Disconnect(IStateMachineDebugInterface &inMachine) override - { - TDebugList::iterator theFind = - eastl::find(m_StateMachineList.begin(), m_StateMachineList.end(), &inMachine); - if (theFind != m_StateMachineList.end()) { - DisconnectStateMachine(inMachine); - m_StateMachineList.erase(theFind); - } - } - - void DisconnectFromServer() override - { - if (m_OutStream) { - m_MessageSerializer.Serialize(-1, SDisconnect(), - Time::getCurrentCounterValue() - m_StartTime); - m_OutStream->Write(m_MessageSerializer.ToRawMessage()); - } - m_StateMachines.clear(); - m_IdToStateMachines.clear(); - m_StateMachineList.clear(); - m_OutStream = NULL; - } - - void OnMessageReceived(const SDebugStreamMessage &msg) override - { - if (msg.m_Data.size()) - m_Parser.Parse(msg.m_Data, *this); - } - -// Set of ignored messages -#define IGNORE_DEBUG_MESSAGE_TYPE(tname) \ - void OnMessage(QT3DSI32, QT3DSU64, const S##tname &) { QT3DS_ASSERT(false); } - - // this are outgoing messages; we shouldn't be receiving them. - IGNORE_DEBUG_MESSAGE_TYPE(Initialization) - IGNORE_DEBUG_MESSAGE_TYPE(Connect) - IGNORE_DEBUG_MESSAGE_TYPE(BreakpointHit) - IGNORE_DEBUG_MESSAGE_TYPE(DebugLog) - IGNORE_DEBUG_MESSAGE_TYPE(EventQueued) - IGNORE_DEBUG_MESSAGE_TYPE(BeginStep) - IGNORE_DEBUG_MESSAGE_TYPE(BeginMicrostep) - IGNORE_DEBUG_MESSAGE_TYPE(MicrostepEvent) - IGNORE_DEBUG_MESSAGE_TYPE(MicrostepData) - IGNORE_DEBUG_MESSAGE_TYPE(EndMicrostep) - IGNORE_DEBUG_MESSAGE_TYPE(ModifyTableValues) - - IStateMachineDebugInterface *GetStateMachine(QT3DSI32 inStreamId) - { - TIdMachineMap::iterator theIter = m_IdToStateMachines.find(inStreamId); - if (theIter == m_IdToStateMachines.end()) - return NULL; - return theIter->second.first.mPtr; - } - - IStateMachineListener *GetStateMachineListener(QT3DSI32 inStreamId) - { - TIdMachineMap::iterator theIter = m_IdToStateMachines.find(inStreamId); - if (theIter == m_IdToStateMachines.end()) - return NULL; - return theIter->second.second.mPtr; - } - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SSetBreakpoint &inBp) - { - IStateMachineListener *iface = GetStateMachineListener(sid); - if (iface) - iface->SetBreakpoint(inBp.m_Breakpoint); - } - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SClearBreakpoint &inBp) - { - IStateMachineListener *iface = GetStateMachineListener(sid); - if (iface) - iface->ClearBreakpoint(inBp.m_Breakpoint); - } - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SClearAllBreakpoints &) - { - IStateMachineListener *iface = GetStateMachineListener(sid); - if (iface) - iface->ClearAllBreakpoints(); - } - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SBreakOnMicrostep &inCmd) - { - IStateMachineListener *iface = GetStateMachineListener(sid); - if (iface) - iface->SetBreakOnMicrostep(inCmd.m_Value); - } - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SContinue &) - { - IStateMachineListener *iface = GetStateMachineListener(sid); - if (iface) - iface->Continue(); - } - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SDisconnect &) - { - if (sid != 0 && sid != (QT3DSI32)QT3DS_MAX_U32) { - IStateMachineDebugInterface *iface = GetStateMachine(sid); - if (iface) - Disconnect(*iface); - } else { - if (sid == (QT3DSI32)QT3DS_MAX_U32) - DisconnectFromServer(); - } - } - - void error(const char8_t *, const char8_t *) {} -}; - -static inline NVConstDataRef ToRef(const TDebugStr &str) -{ - return NVConstDataRef((const QT3DSU8 *)str.begin(), str.size()); -} - -bool TestBasicParseRobustness() -{ - typedef STestMessageHandler THandlerType; - typedef SMessageParser TParserType; - // Just ensure things don't crash. - SInitialization testType; - THandlerType theHandler(2, 5, testType); - TDebugStr theStr; - TParserType theParser; - theParser.Parse(ToRef(theStr), theHandler); - - theStr = "Initialization"; - theParser.Parse(ToRef(theStr), theHandler); - - theStr = "Initialization "; - theParser.Parse(ToRef(theStr), theHandler); - return true; -} - -template -bool TestSerialization(const TDataType &testType, SMessageSerializer &ioSerializer, - QT3DSU64 inTimestamp) -{ - typedef STestMessageHandler THandlerType; - typedef SMessageParser TParserType; - - ioSerializer.Serialize(5, testType, inTimestamp); - THandlerType theHandler(5, inTimestamp, testType); - TParserType theParser; - theParser.Parse(ioSerializer.ToRawMessage(), theHandler); - return theHandler.m_Result; -} -} - -IDebugger &IDebugger::CreateDebugger() -{ - return *QT3DS_NEW(g_MallocAlloc, SDebugger)(); -} - -bool CDebuggerTests::TestStreamProtocol() -{ - // for each message type, fill on some values, serialize to string and back and see what happens - TDebugStrList theList; - theList.push_back("one"); - theList.push_back("two"); - TTransitionIdList theTransList; - theTransList.push_back(STransitionId("one", 2)); - theTransList.push_back(STransitionId("two", -1)); - SBreakpoint bp1(SStateEnterBreakpoint("one")); - SBreakpoint bp2(SStateExitBreakpoint("two")); - SBreakpoint bp3(STransitionId("three", 4)); - SMessageSerializer theSerializer; - bool retval = TestBasicParseRobustness(); - // breaking out the large && statement to make testing easier. - retval = retval && TestSerialization(SInitialization(), theSerializer, 5); - retval = retval && TestSerialization(SConnect("abe.scxml", "hey you", theList), - theSerializer, 6); - retval = retval - && TestSerialization(SDebugLog(TDebugStr("Hey joe, where you goin'")), theSerializer, 7); - retval = retval && TestSerialization(SBeginMicrostep(), theSerializer, 8); - retval = retval && TestSerialization(SMicrostepEvent("evt1", true), theSerializer, 9); - retval = retval - && TestSerialization(SMicrostepData(theTransList, theList, theList), theSerializer, 9); - retval = retval && TestSerialization(SEndMicrostep(), theSerializer, 10); - retval = retval && TestSerialization(SEventQueued("evt1", false), theSerializer, 11); - retval = retval && TestSerialization(SEventQueued("evt1", false), theSerializer, 12); - retval = retval && TestSerialization(SSetBreakpoint(bp1), theSerializer, 13); - retval = retval && TestSerialization(SSetBreakpoint(bp2), theSerializer, 14); - retval = retval && TestSerialization(SSetBreakpoint(bp3), theSerializer, 15); - retval = retval && TestSerialization(SClearBreakpoint(bp1), theSerializer, 16); - retval = retval && TestSerialization(SClearAllBreakpoints(), theSerializer, 17); - return retval; -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.h deleted file mode 100644 index 00814e42..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebugger.h +++ /dev/null @@ -1,386 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_DEBUGGER_H -#define QT3DS_STATE_DEBUGGER_H -#pragma once -#include "Qt3DSState.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/StringTable.h" -#include "foundation/IOStreams.h" -#include "Qt3DSStateEditor.h" - -namespace qt3ds { -namespace state { - namespace debugger { - using namespace editor; - - typedef TEditorStr TDebugStr; - struct SDebugValue; - struct SBreakpoint; - struct SNil; - struct SDatamodelTable; - struct SDatamodelUserData; - struct SDatamodelFunction; - struct SDatamodelCFunction; - struct SDatamodelThread; - - typedef eastl::vector TBreakpointList; - - struct BreakpointTypes - { - enum Enum { - UnknownBreakpointType = 0, - StateEnter, - StateExit, - Transition, - }; - }; - - struct SDebugStreamMessage - { - // Timestamp needs to be converted using the SourceConversion on the protocol socket. - QT3DSU64 m_Timestamp; - NVConstDataRef m_Data; - SDebugStreamMessage() - : m_Timestamp(0) - { - } - SDebugStreamMessage(QT3DSU64 ts, NVConstDataRef msg) - : m_Timestamp(ts) - , m_Data(msg) - { - } - }; - - // Note the stream listeners are not ref counted. - // it is your job to ensure it lasts as long as debug stream. - class IDebugStreamListener - { - protected: - virtual ~IDebugStreamListener() {} - public: - // Async message interface. Clients must provide this. Only called on main thread - virtual void OnMessageReceived(const SDebugStreamMessage &inMessage) = 0; - }; - - class IDebugOutStream : public NVRefCounted, public IOutStream - { - protected: - virtual ~IDebugOutStream() {} - public: - virtual void SetListener(IDebugStreamListener *listener) = 0; - virtual IDebugStreamListener *GetListener() = 0; - // return true if the stream is still connected to an output, false if - // something caused the connection to fail or close. - virtual SDebugStreamMessage WaitForNextMessage() = 0; - virtual bool Connected() = 0; - }; - - struct STransitionId - { - TDebugStr m_StateId; - // Index in file order of the transition. - //-1 means initial or history::transition, depending on if the state is - // a normal state or history state. - QT3DSI32 m_TransitionIndex; - STransitionId(const TDebugStr &inId = TDebugStr(), QT3DSI32 inIdx = -2) - : m_StateId(inId) - , m_TransitionIndex(inIdx) - { - } - bool operator==(const STransitionId &inOther) const - { - return m_StateId == inOther.m_StateId - && m_TransitionIndex == inOther.m_TransitionIndex; - } - }; - - typedef eastl::vector TTransitionIdList; - - /////////////////////////////////////////////////////////////////////// - // Client (runtime) side types - /////////////////////////////////////////////////////////////////////// - - struct DatamodelValueTypes - { - enum Enum { - UnknownType = 0, - Nil, - Boolean, - Number, - String, - Table, - UserData, - Function, - CFunction, - Thread, - }; - }; - - struct SDatamodelValue; - - struct SDatamodelTable; - struct SDatamodelUserData; - struct SDatamodelFunction; - struct SDatamodelCFunction; - struct SDatamodelThread; - struct STableEntry; - - class IScriptStateListener - { - protected: - virtual ~IScriptStateListener() {} - public: - virtual void SetKey(void *inTable, const TDebugStr &inStr, - const SDatamodelValue &inValue) = 0; - virtual void RemoveKey(void *inTable, const TDebugStr &inStr) = 0; - }; - - class IDebugger; - // Information coming from the state machine - class IStateMachineListener : public NVRefCounted - { - protected: - virtual ~IStateMachineListener() {} - public: - // Events coming from the interpreter and sent over the interface. - virtual void OnConnect(const TDebugStr &SCXMLFilename, const TDebugStr &SCXMLFileData, - NVConstDataRef inConfiguration) = 0; - - virtual void Log(const TDebugStr &inStr) = 0; - virtual void EventQueued(const TDebugStr &inEventName, bool inInternal) = 0; - virtual void BeginStep() = 0; - virtual void BeginMicroStep() = 0; - virtual void SetEvent(const TDebugStr &inEventName, bool inInternal) = 0; - virtual void SetTransitionSet(NVConstDataRef inTransitions) = 0; - virtual void SetExitSet(NVConstDataRef inSet) = 0; - virtual void SetEnterSet(NVConstDataRef inSet) = 0; - // Log statements run through the debugger as well. - virtual void EndMicroStep() = 0; - virtual void EndStep() = 0; - - // So far the breakpoints have all been things that are internal to the - // state machine. - virtual void SetBreakOnMicrostep(bool inEnableStep) = 0; - virtual void SetBreakpoint(const SBreakpoint &inBreakpoint) = 0; - virtual void ClearBreakpoint(const SBreakpoint &inBreakpoint) = 0; - virtual void ClearAllBreakpoints() = 0; - - // Called internally. - virtual void Continue() = 0; - virtual void OnExternalBreak() = 0; - - static IStateMachineListener &Create(NVAllocatorCallback &inAlloc, QT3DSU32 inStreamId, - IDebugOutStream &inOutStr, QT3DSU64 inStartTime, - IDebugger &inDebugger, - IScriptContext &inScriptContext); - }; - - // Information coming from the network stream will call these iterfaces - class IStateMachineDebugInterface : public NVRefCounted - { - protected: - virtual ~IStateMachineDebugInterface() {} - public: - virtual void SetStateMachineListener(IStateMachineListener *inListener) = 0; - virtual void OnExternalBreak() = 0; - virtual IScriptContext &GetScriptContext() = 0; - }; - - // The debugger element is the object that sits in the debug process interpreter and sends - // information. - // There should be only one of these per network connection. - class IDebugger : public IDebugStreamListener, public NVRefCounted - { - protected: - virtual ~IDebugger() {} - public: - virtual void OnServerConnected(IDebugOutStream &inStream) = 0; - virtual void Connect(IStateMachineDebugInterface &inMachine) = 0; - virtual void Disconnect(IStateMachineDebugInterface &inMachine) = 0; - // Release any references to any state machines and to the output stream - virtual void DisconnectFromServer() = 0; - - static IDebugger &CreateDebugger(); - }; - - /////////////////////////////////////////////////////////////////////// - // Server (Architect) side types - /////////////////////////////////////////////////////////////////////// - - struct DebugValueTypes - { - enum Enum { NoDebugValue = 0, String, StringList, TransitionIdList }; - }; - - typedef eastl::vector TDebugStrList; - - struct STableModification; - - class IDebuggedInterpreter; - - class IDebuggerMasterListener : public NVRefCounted - { - protected: - virtual ~IDebuggerMasterListener() {} - public: - virtual void OnInterpreterConnected(IDebuggedInterpreter &inInterpreter) = 0; - // If no breakpoint then the interpreter was broken on microstep. - virtual void OnEventQueued(const TDebugStr &inEvent, bool inInternal) = 0; - virtual void OnInterpreterBroken(IDebuggedInterpreter &inInterpreter, - const Option &inBreakpoint) = 0; - // Event processed but no microstep was taken. - virtual void OnEventProcessed(const TDebugStr &inEvent, bool inInternal) = 0; - virtual void OnBeginStep(IDebuggedInterpreter &inInterpreter) = 0; - virtual void OnBeginMicrostep(IDebuggedInterpreter &inInterpreter) = 0; - // Event processed and microstep was taken. - virtual void OnMicrostep(IDebuggedInterpreter &inInterpreter) = 0; - // if inmodifications is empty the table needs to be replaced. - virtual void OnDatamodelChange(IDebuggedInterpreter &inInterpreter, - SDatamodelTable *inTable, - NVConstDataRef inModifications) = 0; - virtual void OnInterpreterDisconnected(IDebuggedInterpreter &inInterpreter) = 0; - virtual void OnLog(IDebuggedInterpreter *inInterpreter, const TDebugStr &inMessage) = 0; - }; - - struct STableEntry; - - typedef eastl::vector TTableEntryList; - - // defined in UICStateDebuggerProtocol.h" - struct SBeginStep; - struct SBeginMicrostep; - struct SMicrostepEvent; - struct SMicrostepData; - struct SEndMicrostep; - struct SEventQueued; - struct SModifyTableValues; - struct SDatamodelTable; - - // Represents the data stream coming from a single interpreter - class IDebuggedInterpreter : public NVRefCounted - { - protected: - virtual ~IDebuggedInterpreter() {} - public: - /* Playback interface, leaving until basic functionality is working. - virtual QT3DSU32 GetStepCount() = 0; - virtual void SetCurrentStep( QT3DSU32 inStep ) = 0; - virtual QT3DSU32 GetMicrostepCount() = 0; - virtual QT3DSU32 SetCurrentMicroStep( QT3DSU32 inStep ) = 0; - */ - - // Get the editor that represents the state graph for this debugged interpreter. - virtual TEditorPtr GetEditor() = 0; - virtual TDebugStr GetFilename() const = 0; - - // Used when connecting to a live session. - virtual void SetBreakpoint(const SBreakpoint &inBreakpoint) = 0; - virtual void ClearBreakpoint(const SBreakpoint &inBreakpoint) = 0; - virtual NVConstDataRef GetBreakpoints() = 0; - virtual void ClearAllBreakpoints() = 0; - // break at the *end* of the microstep so you can see the data of the microstep. - virtual void SetBreakOnMicrostep(bool inBreak) = 0; - virtual bool IsBreakOnMicrostep() const = 0; - - // Return values not valid after *next* call. - // Null means the root. - virtual NVConstDataRef - GetTableValues(SDatamodelTable *inTable = NULL) const = 0; - - virtual NVConstDataRef GetPreviousConfiguration() const = 0; - virtual NVConstDataRef GetConfiguration() const = 0; - virtual const TDebugStr &GetMicrostepEvent() const = 0; - virtual NVConstDataRef GetMicrostepTransitions() const = 0; - virtual NVConstDataRef GetMicrostepEnterStates() const = 0; - virtual NVConstDataRef GetMicrostepExitStates() const = 0; - - virtual bool IsBroken() const = 0; - virtual void Continue() = 0; - // Get the set of changed properties since the last time you asked. Obviously this is - // assuming there - // is only one 'you' asking. - virtual void Disconnect() = 0; - - // Semi-advanced debugger functionality that we don't need for version 1. - - // virtual void SetPropertyValue( const char8_t* inName, const SDebugValue& inValue ) = - // 0; - // Set a property value on the running state machine. - // virtual void SetPropertyValue( TObjPtr inEditorObj, const char8_t* inName, const - // SValueOpt& inValue ) = 0; - - // Eval code in the current state machine context. Works when connected live, wouldn't - // work if you - // were not connected live. - // virtual TDebugStr EvalCode( const TDebugStr& inStr ) = 0; - - // Information coming from the stream, clients should not call these functions - virtual void BreakpointHit(const SBreakpoint &inBreakpoint) = 0; - virtual void OnEventQueued(const SEventQueued &inMsg) = 0; - virtual void OnBeginStep(const SBeginStep &inMsg) = 0; - virtual void OnBeginMicrostep(const SBeginMicrostep &inMsg) = 0; - virtual void OnMicrostepEvent(const SMicrostepEvent &inMsg) = 0; - virtual void OnMicrostepData(const SMicrostepData &inMsg) = 0; - virtual void OnEndMicrostep(const SEndMicrostep &inMsg) = 0; - virtual void OnModifyTable(const SModifyTableValues &inValues) = 0; - - static IDebuggedInterpreter &Create(NVAllocatorCallback &inAlloc, - IDebugOutStream &inStream, TEditorPtr inEditor, - const TDebugStr &inFilename, QT3DSI32 inStreamId, - NVConstDataRef inConfiguration, - IDebuggerMasterListener &inListener); - }; - - // Debugger sites in the master process (Architect process) and controls one or more - // debuggers - // for one or more state machines running in the debug process. - class IDebuggerMaster : public IDebugStreamListener, public NVRefCounted - { - protected: - virtual ~IDebuggerMaster() {} - public: - virtual void Disconnect() = 0; - - static IDebuggerMaster &CreateMaster(IDebugOutStream &outStream, - IDebuggerMasterListener &inListener); - }; - - class CDebuggerTests - { - public: - static bool TestStreamProtocol(); - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerListener.cpp b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerListener.cpp deleted file mode 100644 index 2045f84f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerListener.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateDebugger.h" -#include "Qt3DSStateDebuggerValues.h" -#include "Qt3DSStateDebuggerProtocol.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSStateScriptContext.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::debugger; - -namespace { - -// Component sits in the state machine and receives messages from the state machine -// itself. -struct SListener : public IStateMachineListener, public IScriptStateListener -{ - typedef eastl::hash_map TTableModificationMap; - NVAllocatorCallback &m_Allocator; - QT3DSI32 mRefCount; - QT3DSU32 m_StreamId; - NVScopedRefCounted m_OutStream; - SMessageSerializer m_Serializer; - TDebugStrList m_DebugStrList; - TDebugStrList m_DebugStrAltList; - TTransitionIdList m_TransitionIdList; - QT3DSU64 m_StartTime; - bool m_BreakOnMicrostep; - bool m_Blocking; - IDebugger &m_Debugger; - TDebugStr m_BreakStr; - NVScopedRefCounted m_ScriptContext; - TTableModificationMap m_TableModifications; - TBreakpointList m_Breakpoints; - SMicrostepData m_MicrostepData; - bool m_MicrostepBeginSent; - bool m_StepSent; - - SListener(NVAllocatorCallback &alloc, QT3DSU32 inStreamId, IDebugOutStream &inOutStr, - QT3DSU64 inStartTime, IDebugger &inDebugger, IScriptContext &inScriptContext) - : m_Allocator(alloc) - , mRefCount(0) - , m_StreamId(inStreamId) - , m_OutStream(inOutStr) - , m_StartTime(inStartTime) - , m_BreakOnMicrostep(false) - , m_Blocking(false) - , m_Debugger(inDebugger) - , m_ScriptContext(inScriptContext) - , m_MicrostepBeginSent(false) - , m_StepSent(false) - { - } - - virtual ~SListener() { m_Blocking = false; } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) - - template - static const eastl::vector &RefToList(NVConstDataRef inRef, - eastl::vector &outList) - { - outList.assign(inRef.begin(), inRef.end()); - return outList; - } - - template - void Serialize(const TDataType &dtype, QT3DSU64 inTime) - { - m_Serializer.Serialize(m_StreamId, dtype, inTime); - m_OutStream->Write(m_Serializer.ToRawMessage()); - } - - template - void Serialize(const TDataType &dtype) - { - Serialize(dtype, CurrentTime()); - } - - void OnConnect(const TDebugStr &SCXMLFilename, const TDebugStr &SCXMLFileData, - NVConstDataRef inConfiguration) override - { - Serialize( - SConnect(SCXMLFilename, SCXMLFileData, RefToList(inConfiguration, m_DebugStrList))); - DumpScriptState(); - } - - QT3DSU64 CurrentTime() { return Time::getCurrentCounterValue() - m_StartTime; } - - void DumpScriptState() - { - // Run through the global state and output any keys that have changed. - m_TableModifications.clear(); - m_ScriptContext->DumpState(*this); - for (TTableModificationMap::iterator iter = m_TableModifications.begin(), - end = m_TableModifications.end(); - iter != end; ++iter) { - Serialize(iter->second); - } - m_TableModifications.clear(); - } - virtual void OnBreakpointHit(const SBreakpoint &inBreakpointId) - { - DumpScriptState(); - Serialize(SBreakpointHit(inBreakpointId)); - Break(); - } - - void Log(const TDebugStr &inStr) override { Serialize(SDebugLog(inStr)); } - - void SetBreakpoint(const SBreakpoint &inBreakpoint) override - { - m_Breakpoints.push_back(inBreakpoint); - } - - void ClearBreakpoint(const SBreakpoint &inBreakpoint) override - { - TBreakpointList::iterator removeIter = - eastl::remove(m_Breakpoints.begin(), m_Breakpoints.end(), inBreakpoint); - if (removeIter != m_Breakpoints.end()) - m_Breakpoints.erase(removeIter, m_Breakpoints.end()); - } - void ClearAllBreakpoints() override { m_Breakpoints.clear(); } - void EventQueued(const TDebugStr &inEventName, bool inInternal) override - { - Serialize(SEventQueued(inEventName, inInternal)); - } - void SendMicrostepBegin() - { - if (m_MicrostepBeginSent == false) { - if (m_StepSent == false) { - m_StepSent = true; - Serialize(SBeginStep()); - } - - m_MicrostepBeginSent = true; - Serialize(SBeginMicrostep()); - } - } - - void BeginStep() override { m_StepSent = false; } - - void BeginMicroStep() override - { - m_MicrostepBeginSent = false; - m_MicrostepData.m_Transitions.clear(); - m_MicrostepData.m_EnterStates.clear(); - m_MicrostepData.m_ExitStates.clear(); - } - - void SetEvent(const TDebugStr &inEvent, bool inInternal) override - { - if (!inEvent.empty()) { - SendMicrostepBegin(); - Serialize(SMicrostepEvent(inEvent, inInternal)); - } - } - void SetTransitionSet(NVConstDataRef inTransitions) override - { - SendMicrostepBegin(); - RefToList(inTransitions, m_MicrostepData.m_Transitions); - } - void SetExitSet(NVConstDataRef inSet) override - { - SendMicrostepBegin(); - RefToList(inSet, m_MicrostepData.m_ExitStates); - } - void SetEnterSet(NVConstDataRef inSet) override - { - SendMicrostepBegin(); - RefToList(inSet, m_MicrostepData.m_EnterStates); - } - - static inline bool FindInList(const TDebugStr &inStr, const TDebugStrList &inStrList) - { - if (eastl::find(inStrList.begin(), inStrList.end(), inStr) != inStrList.end()) - return true; - return false; - } - - static inline bool FindInList(const STransitionId &inStr, const TTransitionIdList &inStrList) - { - if (eastl::find(inStrList.begin(), inStrList.end(), inStr) != inStrList.end()) - return true; - return false; - } - - const SBreakpoint *FindHitBreakpoint() - { - // Now check for breakpoints. - for (QT3DSU32 breakIdx = 0, breakEnd = m_Breakpoints.size(); breakIdx < breakEnd; ++breakIdx) { - const SBreakpoint &theBreakpoint = m_Breakpoints[breakIdx]; - switch (theBreakpoint.getType()) { - case BreakpointTypes::StateEnter: - if (FindInList(theBreakpoint.getData().m_ObjectId, - m_MicrostepData.m_EnterStates)) - return &theBreakpoint; - case BreakpointTypes::StateExit: - if (FindInList(theBreakpoint.getData().m_ObjectId, - m_MicrostepData.m_ExitStates)) - return &theBreakpoint; - case BreakpointTypes::Transition: - if (FindInList(theBreakpoint.getData(), - m_MicrostepData.m_Transitions)) - return &theBreakpoint; - default: - QT3DS_ASSERT(false); - break; - } - } - - return NULL; - } - - // Log statements run through the debugger as well. - void EndMicroStep() override - { - DumpScriptState(); - if (m_MicrostepBeginSent) { - if (m_MicrostepData.m_Transitions.empty() == false) - Serialize(m_MicrostepData); - - Serialize(SEndMicrostep()); - const SBreakpoint *theHitBreakpoint = FindHitBreakpoint(); - if (theHitBreakpoint) - OnBreakpointHit(*theHitBreakpoint); - else if (m_BreakOnMicrostep) - Break(); - } - } - - void EndStep() override { m_StepSent = false; } - - void SetBreakOnMicrostep(bool inEnableStep) override { m_BreakOnMicrostep = inEnableStep; } - - virtual void Break() - { - if (!m_Blocking) { - // We may get disconnected *while* we are breaking. - // We need to ensure we don't get nuked while we are breaking. - NVScopedRefCounted tempVar(this); - m_Blocking = true; - while (m_Blocking) { - SDebugStreamMessage msg = m_OutStream->WaitForNextMessage(); - // Some out streams will have a reference to the debugger and some will not. - // If they do, then we do not have to hand our string to the debugger, we can assume - // the underlying implementation will have done that. If not, then we need to - // pass the message to the debugger. - if (m_Blocking && msg.m_Data.size()) - m_Debugger.OnMessageReceived(msg); - - if (!m_OutStream->Connected()) { - m_Blocking = false; - m_Debugger.DisconnectFromServer(); - } - } - } - } - - void Continue() override { m_Blocking = false; } - - void OnExternalBreak() override { DumpScriptState(); } - - // IScriptStateListener - void SetKey(void *inTable, const TDebugStr &inStr, const SDatamodelValue &inValue) override - { - SDatamodelTable *theTable((SDatamodelTable *)inTable); - SModifyTableValues &theModification = - m_TableModifications.insert(eastl::make_pair(theTable, SModifyTableValues(theTable))) - .first->second; - theModification.m_Modifications.push_back( - STableModification(STableEntry(inStr, inValue), TableModificationType::SetKey)); - } - - void RemoveKey(void *inTable, const TDebugStr &inStr) override - { - SDatamodelTable *theTable((SDatamodelTable *)inTable); - SModifyTableValues &theModification = - m_TableModifications.insert(eastl::make_pair(theTable, SModifyTableValues(theTable))) - .first->second; - theModification.m_Modifications.push_back( - STableModification(STableEntry(inStr), TableModificationType::RemoveKey)); - } -}; -} - -IStateMachineListener &IStateMachineListener::Create(NVAllocatorCallback &inAlloc, QT3DSU32 inStreamId, - IDebugOutStream &inOutStr, QT3DSU64 inStartTime, - IDebugger &inDebugger, - IScriptContext &inScriptContext) -{ - return *QT3DS_NEW(inAlloc, SListener)(inAlloc, inStreamId, inOutStr, inStartTime, inDebugger, - inScriptContext); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerProtocol.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerProtocol.h deleted file mode 100644 index 03230a61..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerProtocol.h +++ /dev/null @@ -1,925 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_DEBUGGER_PROTOCOL_H -#define QT3DS_STATE_DEBUGGER_PROTOCOL_H -#include "Qt3DSStateDebugger.h" -#include "Qt3DSStateDebuggerValues.h" -#include "foundation/StringConversion.h" -#include "foundation/StringConversionImpl.h" -#include "foundation/Qt3DSTime.h" - -// Stream protocol, regardless of binary vs. text. -namespace qt3ds { -namespace state { - namespace debugger { - - struct SInitialization - { - QT3DSI32 m_Version; - QT3DSI32 m_Padding; - CounterFrequencyToTensOfNanos m_TimerFrequency; - static QT3DSI32 GetCurrentVersion() { return 1; } - SInitialization() - : m_Version(GetCurrentVersion()) - , m_Padding(0) - , m_TimerFrequency(Time::sCounterFreq) - { - } - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visit(m_Version); - inVisitor.visit(m_TimerFrequency.mNumerator); - inVisitor.visit(m_TimerFrequency.mDenominator); - } - bool operator==(const SInitialization &inOther) const - { - return m_Version == inOther.m_Version - && m_TimerFrequency.mNumerator == inOther.m_TimerFrequency.mNumerator - && m_TimerFrequency.mDenominator == inOther.m_TimerFrequency.mDenominator; - } - }; - - // Listener interface. For on connect, we send the current timestamp for that state - // machine. - struct SConnect - { - TDebugStr m_Filename; - TDebugStr m_SCXMLData; // scxml file contents - TDebugStrList m_Configuration; - SConnect() {} - SConnect(const TDebugStr &fn, const TDebugStr &xmlData, const TDebugStrList &config) - : m_Filename(fn) - , m_SCXMLData(xmlData) - , m_Configuration(config) - { - } - - template - void Visit(TVisitor &inVisitor) - { - inVisitor.randomText(m_Filename); - inVisitor.randomText(m_SCXMLData); - inVisitor.visitIdList(m_Configuration); - } - bool operator==(const SConnect &inOther) const - { - return m_Filename == inOther.m_Filename && m_SCXMLData == inOther.m_SCXMLData - && m_Configuration == inOther.m_Configuration; - } - }; - - struct SBreakpointHit - { - SBreakpoint m_Breakpoint; - SBreakpointHit() {} - SBreakpointHit(const SBreakpoint &bp) - : m_Breakpoint(bp) - { - } - - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visit(m_Breakpoint); - } - bool operator==(const SBreakpointHit &inOther) const - { - return m_Breakpoint == inOther.m_Breakpoint; - } - }; - - struct SDebugLog - { - TDebugStr m_Message; - SDebugLog() {} - SDebugLog(const TDebugStr &msg) - : m_Message(msg) - { - } - template - void Visit(TVisitor &inVisitor) - { - inVisitor.randomText(m_Message); - } - bool operator==(const SDebugLog &inOther) const - { - return m_Message == inOther.m_Message; - } - }; - - struct SModifyTableValues - { - SDatamodelTable *m_TablePtr; - TTableModificationList m_Modifications; - - SModifyTableValues(SDatamodelTable *inTable = NULL, - const TTableModificationList &inList = TTableModificationList()) - : m_TablePtr(inTable) - , m_Modifications(inList) - { - } - - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visit(m_TablePtr); - inVisitor.visit(m_Modifications); - } - - bool operator==(const SModifyTableValues &inOther) const - { - return m_TablePtr == inOther.m_TablePtr - && m_Modifications == inOther.m_Modifications; - } - }; - - struct SBeginStep - { - SBeginStep() {} - template - void Visit(TVisitor &) - { - } - - bool operator==(const SBeginStep &) const { return true; } - }; - - struct SBeginMicrostep - { - SBeginMicrostep() {} - template - void Visit(TVisitor &) - { - } - - bool operator==(const SBeginMicrostep &) const { return true; } - }; - - struct SMicrostepEvent - { - TDebugStr m_Event; - bool m_Internal; - - SMicrostepEvent(const TDebugStr &inEvent = TDebugStr(), bool inIsInternal = false) - : m_Event(inEvent) - , m_Internal(inIsInternal) - { - } - - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visitId(m_Event); - inVisitor.visit(m_Internal); - } - - bool operator==(const SMicrostepEvent &inOther) const - { - return m_Event == inOther.m_Event && m_Internal == inOther.m_Internal; - } - }; - - struct SMicrostepData - { - TTransitionIdList m_Transitions; - TDebugStrList m_ExitStates; - TDebugStrList m_EnterStates; - - SMicrostepData() {} - SMicrostepData(const TTransitionIdList &inTransitions, - const TDebugStrList &inExitStates, const TDebugStrList &inEnterStates) - : m_Transitions(inTransitions) - , m_ExitStates(inExitStates) - , m_EnterStates(inEnterStates) - { - } - - template - void Visit(TVisitor &inVisitor) - { - // Eventless transitions cause us to need to always write the string length. - inVisitor.visit(m_Transitions); - inVisitor.visitIdList(m_ExitStates); - inVisitor.visitIdList(m_EnterStates); - } - bool operator==(const SMicrostepData &inOther) const - { - return m_Transitions == inOther.m_Transitions - && m_ExitStates == inOther.m_ExitStates - && m_EnterStates == inOther.m_EnterStates; - } - }; - - struct SEndMicrostep - { - SEndMicrostep() {} - template - void Visit(TVisitor & /*inVisitor*/) - { - } - - bool operator==(const SEndMicrostep &) const { return true; } - }; - - struct SEventQueued - { - TDebugStr m_Event; - bool m_Internal; - SEventQueued() - : m_Internal(false) - { - } - SEventQueued(const TDebugStr &evt, bool intern) - : m_Event(evt) - , m_Internal(intern) - { - } - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visitEventName(m_Event); - inVisitor.visit(m_Internal); - } - bool operator==(const SEventQueued &inOther) const - { - return m_Event == inOther.m_Event && m_Internal == inOther.m_Internal; - } - }; - - // Debug interface - - struct SSetBreakpoint - { - SBreakpoint m_Breakpoint; - SSetBreakpoint() {} - SSetBreakpoint(const SBreakpoint &bp) - : m_Breakpoint(bp) - { - } - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visit(m_Breakpoint); - } - bool operator==(const SSetBreakpoint &inOther) const - { - return m_Breakpoint == inOther.m_Breakpoint; - } - }; - - struct SClearBreakpoint - { - SBreakpoint m_Breakpoint; - SClearBreakpoint() {} - SClearBreakpoint(const SBreakpoint &bp) - : m_Breakpoint(bp) - { - } - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visit(m_Breakpoint); - } - bool operator==(const SClearBreakpoint &inOther) const - { - return m_Breakpoint == inOther.m_Breakpoint; - } - }; - - struct SClearAllBreakpoints - { - SClearAllBreakpoints() {} - template - void Visit(TVisitor & /*inVisitor*/) - { - } - bool operator==(const SClearAllBreakpoints & /*inOther*/) const { return true; } - }; - - struct SBreakOnMicrostep - { - bool m_Value; - SBreakOnMicrostep(bool val = false) - : m_Value(val) - { - } - template - void Visit(TVisitor &inVisitor) - { - inVisitor.visit(m_Value); - } - bool operator==(const SBreakOnMicrostep &inOther) const - { - return m_Value == inOther.m_Value; - } - }; - - struct SContinue - { - SContinue() {} - template - void Visit(TVisitor & /*inVisitor*/) - { - } - bool operator==(const SContinue & /*inOther*/) const { return true; } - }; - - struct SDisconnect - { - SDisconnect() {} - template - void Visit(TVisitor & /*inVisitor*/) - { - } - bool operator==(const SDisconnect & /*inOther*/) const { return true; } - }; - - // Visitors to handle the breakpoint subtypes. - // The empty top visitor will force a compile error if there is a breakpoint type we don't - // recognize. - template - struct SBreakpointSerializationVisitor - { - }; - - template <> - struct SBreakpointSerializationVisitor - { - enum { Type = BreakpointTypes::StateEnter }; - template - static void Visit(TVisitor &inVisitor, SStateEnterBreakpoint &inBp) - { - inVisitor.visitId(inBp.m_ObjectId); - } - }; - - template <> - struct SBreakpointSerializationVisitor - { - enum { Type = BreakpointTypes::StateExit }; - template - static void Visit(TVisitor &inVisitor, SStateExitBreakpoint &inBp) - { - inVisitor.visitId(inBp.m_ObjectId); - } - }; - - template <> - struct SBreakpointSerializationVisitor - { - enum { Type = BreakpointTypes::Transition }; - template - static void Visit(TVisitor &inVisitor, STransitionId &inBp) - { - inVisitor.visitId(inBp.m_StateId); - inVisitor.visit(inBp.m_TransitionIndex); - } - }; - -#define ITERATE_BREAKPOINT_TYPES \ - HANDLE_BREAKPOINT_TYPE(StateEnter, SStateEnterBreakpoint) \ - HANDLE_BREAKPOINT_TYPE(StateExit, SStateExitBreakpoint) \ - HANDLE_BREAKPOINT_TYPE(Transition, STransitionId) - -#define ITERATE_DEBUG_MESSAGE_TYPES \ - HANDLE_DEBUG_MESSAGE_TYPE(Initialization) \ - HANDLE_DEBUG_MESSAGE_TYPE(Connect) \ - HANDLE_DEBUG_MESSAGE_TYPE(BreakpointHit) \ - HANDLE_DEBUG_MESSAGE_TYPE(DebugLog) \ - HANDLE_DEBUG_MESSAGE_TYPE(ModifyTableValues) \ - HANDLE_DEBUG_MESSAGE_TYPE(BeginStep) \ - HANDLE_DEBUG_MESSAGE_TYPE(BeginMicrostep) \ - HANDLE_DEBUG_MESSAGE_TYPE(MicrostepEvent) \ - HANDLE_DEBUG_MESSAGE_TYPE(MicrostepData) \ - HANDLE_DEBUG_MESSAGE_TYPE(EndMicrostep) \ - HANDLE_DEBUG_MESSAGE_TYPE(EventQueued) \ - HANDLE_DEBUG_MESSAGE_TYPE(SetBreakpoint) \ - HANDLE_DEBUG_MESSAGE_TYPE(ClearBreakpoint) \ - HANDLE_DEBUG_MESSAGE_TYPE(ClearAllBreakpoints) \ - HANDLE_DEBUG_MESSAGE_TYPE(Disconnect) \ - HANDLE_DEBUG_MESSAGE_TYPE(BreakOnMicrostep) \ - HANDLE_DEBUG_MESSAGE_TYPE(Continue) - - template - struct STypeToName - { - }; - -#define HANDLE_BREAKPOINT_TYPE(enumType, structType) \ - template <> \ - struct STypeToName \ - { \ - static const char8_t *GetName() { return #enumType; } \ - }; -#define HANDLE_DEBUG_MESSAGE_TYPE(msgType) \ - template <> \ - struct STypeToName \ - { \ - static const char8_t *GetName() { return #msgType; } \ - }; - - ITERATE_BREAKPOINT_TYPES - ITERATE_DEBUG_MESSAGE_TYPES - -#undef HANDLE_BREAKPOINT_TYPE -#undef HANDLE_DEBUG_MESSAGE_TYPE - - template - struct SMessageParser - { - TDebugStr m_MessageHeaderStr; - TDebugStr m_TimestampStr; - TDebugStr m_ParseStr; - TDebugStr m_BreakpointTypeStr; - TDebugStr m_TempStr[4]; - TMessageHandler *m_CurrentHandler; - bool m_Valid; - static void Trim(TDebugStr &inStr) - { - if (inStr.empty()) - return; - eastl::string::size_type nonSpace = inStr.find_first_not_of(' '); - eastl::string::size_type lastNonSpace = inStr.find_last_not_of(' '); - if (nonSpace == TDebugStr::npos || lastNonSpace == TDebugStr::npos) { - inStr.clear(); - return; - } - - eastl::string::size_type msgLen = lastNonSpace - nonSpace; - inStr.erase(inStr.begin(), inStr.begin() + nonSpace); - inStr.resize(msgLen + 1); - } - - void TrimForward(eastl::string::size_type startPos) - { - eastl::string::size_type nextPos = m_ParseStr.find_first_not_of(' ', startPos); - if (nextPos != TDebugStr::npos) - m_ParseStr.erase(m_ParseStr.begin(), m_ParseStr.begin() + nextPos); - else - m_ParseStr.clear(); - } - - void TrimForward() - { - eastl::string::size_type nextSpace = m_ParseStr.find_first_of(' '); - TrimForward(nextSpace); - } - - void visitId(TDebugStr &inStr) - { - eastl::string::size_type nextSpace = m_ParseStr.find_first_of(' '); - if (nextSpace == TDebugStr::npos) - nextSpace = m_ParseStr.size(); - inStr.assign(m_ParseStr.begin(), m_ParseStr.begin() + nextSpace); - TrimForward(nextSpace); - } - void visit(TDebugStr &inStr) { randomText(inStr); } - void visit(QT3DSI32 &inData) - { - StringConversion().StrTo(m_ParseStr.c_str(), inData); - TrimForward(); - } - void visit(QT3DSU32 &inData) - { - StringConversion().StrTo(m_ParseStr.c_str(), inData); - TrimForward(); - } - - void visit(QT3DSU64 &inData) - { - StringConversion().StrTo(m_ParseStr.c_str(), inData); - TrimForward(); - } - - void visit(float &inData) - { - StringConversion().StrTo(m_ParseStr.c_str(), inData); - TrimForward(); - } - - void visit(bool &inData) - { - if (CompareNChars(m_ParseStr.c_str(), "True", 4) == 0) - inData = true; - else - inData = false; - - TrimForward(); - } - - template - void visitOpaquePtr(TPtrType *&inPtr) - { - QT3DSU64 temp; - visit(temp); - inPtr = reinterpret_cast(static_cast(temp)); - } - - void visit(SDatamodelTable *&inData) { visitOpaquePtr(inData); } - void visit(SDatamodelUserData *&inData) { visitOpaquePtr(inData); } - void visit(SDatamodelFunction *&inData) { visitOpaquePtr(inData); } - void visit(SDatamodelCFunction *&inData) { visitOpaquePtr(inData); } - void visit(SDatamodelThread *&inData) { visitOpaquePtr(inData); } - void visit(SNil &) {} - - void visit(SDatamodelValue &inValue) - { - visitId(m_TempStr[0]); -#define HANDLE_DATAMODEL_VALUE_TYPE(name, dtype) \ - if (AreEqual(m_TempStr[0].c_str(), #name)) { \ - dtype theData; \ - visit(theData); \ - inValue = theData; \ - } else - ITERATE_DATAMODEL_VALUE_TYPES -#undef HANDLE_DATAMODEL_VALUE_TYPE - { - QT3DS_ASSERT(false); - } - } - - void visit(TTableModificationList &inModifications) - { - QT3DSU32 numMods = 0; - visit(numMods); - inModifications.resize(numMods); - for (QT3DSU32 idx = 0, end = inModifications.size(); idx < end; ++idx) { - STableModification &theModification(inModifications[idx]); - visitId(m_TempStr[0]); - if (AreEqual(m_TempStr[0].c_str(), "SetKey")) - theModification.m_Type = TableModificationType::SetKey; - else if (AreEqual(m_TempStr[0].c_str(), "RemoveKey")) - theModification.m_Type = TableModificationType::RemoveKey; - else { - QT3DS_ASSERT(false); - continue; - } - visit(theModification.m_Entry.m_Key); - if (theModification.m_Type == TableModificationType::SetKey) - visit(theModification.m_Entry.m_Value); - } - } - - void visit(TTableEntryList &inEntryList) - { - QT3DSU32 numMods = 0; - visit(numMods); - inEntryList.resize(numMods); - for (QT3DSU32 idx = 0, end = inEntryList.size(); idx < end; ++idx) { - STableEntry &theEntry(inEntryList[idx]); - visit(theEntry.m_Key); - visit(theEntry.m_Value); - } - } - - void randomText(TDebugStr &outStr) - { - QT3DSU32 strLen = 0; - visit(strLen); - outStr.assign(m_ParseStr.begin(), m_ParseStr.begin() + strLen); - TrimForward(strLen); - } - - void visitIdList(TDebugStrList &inList) - { - QT3DSU32 numItems = 0; - visit(numItems); - inList.resize(numItems); - for (QT3DSU32 idx = 0, end = numItems; idx < end; ++idx) - visitId(inList[idx]); - } - - void visit(TTransitionIdList &inList) - { - QT3DSU32 numItems = 0; - visit(numItems); - inList.resize(numItems); - for (QT3DSU32 idx = 0, end = numItems; idx < end; ++idx) - inList[idx] = BreakpointTransition(); - } - - void visitEventName(TDebugStr &outStr) { visitId(outStr); } - - SStateEnterBreakpoint BreakpointStateEnter() - { - SStateEnterBreakpoint retval; - SBreakpointSerializationVisitor::Visit(*this, retval); - return retval; - } - - SStateExitBreakpoint BreakpointStateExit() - { - SStateExitBreakpoint retval; - SBreakpointSerializationVisitor::Visit(*this, retval); - return retval; - } - - STransitionId BreakpointTransition() - { - STransitionId retval; - SBreakpointSerializationVisitor::Visit(*this, retval); - return retval; - } - - void visit(SBreakpoint &breakpoint) - { - visitId(m_BreakpointTypeStr); -#define HANDLE_BREAKPOINT_TYPE(enumType, bpType) \ - if (AreEqual(STypeToName::GetName(), m_BreakpointTypeStr.c_str())) { \ - breakpoint = Breakpoint##enumType(); \ - } else - ITERATE_BREAKPOINT_TYPES -#undef HANDLE_BREAKPOINT_TYPE - // else is defined in the iterate breakpoints. - { - m_Valid = false; - m_CurrentHandler->error("Unrecognized breakpoint type: ", - m_BreakpointTypeStr.c_str()); - } - } - - template - void DoParseT(TDebugStr &inStr, QT3DSU64 inTimestamp, QT3DSI32 streamId, - TMessageHandler &inHandler) - { - TDataType theType; - m_ParseStr = inStr; - m_Valid = true; - m_CurrentHandler = &inHandler; - theType.Visit(*this); - if (m_Valid) - inHandler.OnMessage(streamId, inTimestamp, theType); - } - - // destructive parsing. - void Parse(NVConstDataRef data, TMessageHandler &inHandler) - { - m_ParseStr.assign((const char *)data.begin(), (const char *)data.end()); - Trim(m_ParseStr); - size_t spacePos = m_ParseStr.find_first_of(' '); - if (spacePos == TDebugStr::npos) { - m_ParseStr.assign((const char *)data.begin(), (const char *)data.end()); - inHandler.error("Failed to parse message: ", m_ParseStr.c_str()); - return; - } - qt3ds::QT3DSI32 streamId = 0; - visitId(m_MessageHeaderStr); - visit(streamId); - qt3ds::QT3DSU64 timestamp = 0; - visit(timestamp); -#define HANDLE_DEBUG_MESSAGE_TYPE(name) \ - if (AreEqual(STypeToName::GetName(), m_MessageHeaderStr.c_str())) { \ - DoParseT(m_ParseStr, timestamp, streamId, inHandler); \ - } else - ITERATE_DEBUG_MESSAGE_TYPES -#undef HANDLE_DEBUG_MESSAGE_TYPE - { - inHandler.error("Failed to parse message type: ", m_MessageHeaderStr.c_str()); - } - } - }; - - struct SMessageSerializer - { - TDebugStr m_Message; - void appendSpace() { m_Message.append(1, ' '); } - - void visitId(const TDebugStr &inStr) - { - m_Message.append(inStr); - appendSpace(); - } - template - void rawTypeToStr(const TDataType &inType) - { - char8_t buf[256] = { 0 }; - StringConversion().ToStr(inType, toDataRef(buf, 256)); - m_Message.append(buf); - appendSpace(); - } - void visit(QT3DSI32 inData) { rawTypeToStr(inData); } - void visit(QT3DSU32 inData) { rawTypeToStr(inData); } - - void visit(QT3DSU64 inData) { rawTypeToStr(inData); } - - void visit(bool inData) { rawTypeToStr(inData); } - - void visit(const TDebugStr &inStr) { randomText(inStr); } - - void visit(const SNil &) {} - - void visit(const TTransitionIdList &inData) - { - QT3DSU32 len = (QT3DSU32)inData.size(); - visit(len); - for (QT3DSU32 idx = 0; idx < len; ++idx) - Breakpoint(inData[idx]); - } - - void randomText(const TDebugStr &outStr) - { - QT3DSU32 len = (QT3DSU32)outStr.size(); - visit(len); - if (len) - m_Message.append(outStr); - appendSpace(); - } - - void visitIdList(const TDebugStrList &inList) - { - QT3DSU32 numItems = (QT3DSU32)inList.size(); - visit(numItems); - for (QT3DSU32 idx = 0; idx < numItems; ++idx) - visitId(inList[idx]); - } - - void visitEventName(const TDebugStr &outStr) { visitId(outStr); } - void visit(float inValue) { rawTypeToStr(inValue); } - template - void visitOpaquePtr(const TPtrType *inPtr) - { - size_t ptrValue = reinterpret_cast(inPtr); - QT3DSU64 fullValue = static_cast(ptrValue); - visit(fullValue); - } - - void visit(SDatamodelTable *inData) { visitOpaquePtr(inData); } - void visit(SDatamodelUserData *inData) { visitOpaquePtr(inData); } - void visit(SDatamodelFunction *inData) { visitOpaquePtr(inData); } - void visit(SDatamodelCFunction *inData) { visitOpaquePtr(inData); } - void visit(SDatamodelThread *inData) { visitOpaquePtr(inData); } - - void visit(const SDatamodelValue &inValue) - { - switch (inValue.getType()) { -#define HANDLE_DATAMODEL_VALUE_TYPE(name, dtype) \ - case DatamodelValueTypes::name: { \ - m_Message.append(#name); \ - appendSpace(); \ - visit(inValue.getData()); \ - break; \ - } - ITERATE_DATAMODEL_VALUE_TYPES -#undef HANDLE_DATAMODEL_VALUE_TYPE - default: - QT3DS_ASSERT(false); - break; - } - } - - void visit(const TTableModificationList &inModifications) - { - QT3DSU32 numItems = (QT3DSU32)inModifications.size(); - visit(numItems); - for (QT3DSU32 idx = 0, end = inModifications.size(); idx < end; ++idx) { - const STableModification &theMod(inModifications[idx]); - switch (theMod.m_Type) { - case TableModificationType::SetKey: { - m_Message.append("SetKey"); - appendSpace(); - visit(theMod.m_Entry.m_Key); - visit(theMod.m_Entry.m_Value); - break; - } - case TableModificationType::RemoveKey: { - m_Message.append("RemoveKey"); - appendSpace(); - visit(theMod.m_Entry.m_Key); - break; - } - default: - QT3DS_ASSERT(false); - m_Message.append("badvalue"); - appendSpace(); - continue; - } - } - } - void visit(TTableEntryList &inEntries) - { - QT3DSU32 numItems = (QT3DSU32)inEntries.size(); - visit(numItems); - for (QT3DSU32 idx = 0, end = inEntries.size(); idx < end; ++idx) { - const STableEntry &theEntry(inEntries[idx]); - visit(theEntry.m_Key); - visit(theEntry.m_Value); - } - } - - template - void Breakpoint(const TBreakpointType &inBp) - { - SBreakpointSerializationVisitor::Visit( - *this, const_cast(inBp)); - } - - void visit(const SBreakpoint &inBp) - { - switch (inBp.getType()) { -#define HANDLE_BREAKPOINT_TYPE(enumName, typeName) \ - case BreakpointTypes::enumName: \ - m_Message.append(STypeToName::GetName()); \ - appendSpace(); \ - Breakpoint(inBp.getData()); \ - break; - ITERATE_BREAKPOINT_TYPES -#undef HANDLE_BREAKPOINT_TYPE - default: - QT3DS_ASSERT(false); - break; - } - } - - template - void Serialize(QT3DSI32 inStreamId, const TMsgType &inMsg, QT3DSU64 inTimestamp) - { - m_Message.clear(); - m_Message.append(STypeToName::GetName()); - appendSpace(); - visit(inStreamId); - visit(inTimestamp); - const_cast(inMsg).Visit(*this); - } - - NVConstDataRef ToRawMessage() - { - if (m_Message.size() == 0) - return NVConstDataRef(); - return NVConstDataRef(reinterpret_cast(m_Message.c_str()), - (QT3DSU32)m_Message.size()); - } - }; - - template - struct SMsgComparer - { - static bool Compare(const TLhs &, const TRhs &) { return false; } - }; -#define HANDLE_DEBUG_MESSAGE_TYPE(typeName) \ - template <> \ - struct SMsgComparer \ - { \ - static bool Compare(const S##typeName &lhs, const S##typeName &rhs) { return lhs == rhs; } \ - }; - ITERATE_DEBUG_MESSAGE_TYPES; -#undef HANDLE_DEBUG_MESSAGE_TYPE - - template - struct STestMessageHandler - { - bool m_Result; - QT3DSU64 m_Timestamp; - QT3DSU32 m_StreamId; - const TMessageType &m_ExpectedResult; - - STestMessageHandler(QT3DSU32 sid, QT3DSU64 ts, const TMessageType &res) - : m_Result(false) - , m_Timestamp(ts) - , m_StreamId(sid) - , m_ExpectedResult(res) - { - } - - template - void OnMessage(QT3DSU32 sid, QT3DSU64 ts, const TCrapType &msgType) - { - if (ts == m_Timestamp && m_StreamId == sid) - m_Result = - SMsgComparer::Compare(msgType, m_ExpectedResult); - } - - void error(const char8_t *, const char8_t *) {} - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerValues.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerValues.h deleted file mode 100644 index 340f46cb..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateDebuggerValues.h +++ /dev/null @@ -1,540 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_DEBUGGER_VALUES_H -#define QT3DS_STATE_DEBUGGER_VALUES_H -#pragma once -#include "Qt3DSStateDebugger.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" - -namespace qt3ds { -namespace state { - namespace debugger { - using namespace qt3ds::state::editor; - - // Force compile error if unsupported datatype requested - template - struct SDebugValueTypeMap - { - }; - - template <> - struct SDebugValueTypeMap - { - static DebugValueTypes::Enum GetType() { return DebugValueTypes::String; } - }; - template <> - struct SDebugValueTypeMap - { - static DebugValueTypes::Enum GetType() { return DebugValueTypes::StringList; } - }; - template <> - struct SDebugValueTypeMap - { - static DebugValueTypes::Enum GetType() { return DebugValueTypes::TransitionIdList; } - }; - - struct SDebugValueUnionTraits - { - typedef DebugValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(TDebugStrList), - }; - - static TIdType getNoDataId() { return DebugValueTypes::NoDebugValue; } - - template - static TIdType getType() - { - return SDebugValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case DebugValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case DebugValueTypes::StringList: - return inVisitor(*NVUnionCast(inData)); - case DebugValueTypes::TransitionIdList: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case DebugValueTypes::NoDebugValue: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case DebugValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case DebugValueTypes::StringList: - return inVisitor(*NVUnionCast(inData)); - case DebugValueTypes::TransitionIdList: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case DebugValueTypes::NoDebugValue: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SDebugValueUnionTraits::TBufferSize> - TDebugValueUnionType; - - struct SDebugValue : public TDebugValueUnionType - { - SDebugValue() {} - - SDebugValue(const SDebugValue &inOther) - : TDebugValueUnionType(static_cast(inOther)) - { - } - - SDebugValue(const char8_t *inOther) - : TDebugValueUnionType(TDebugStr(inOther)) - { - } - - template - SDebugValue(const TDataType &inDt) - : TDebugValueUnionType(inDt) - { - } - - SDebugValue &operator=(const SDebugValue &inOther) - { - TDebugValueUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SDebugValue &inOther) const - { - return TDebugValueUnionType::operator==(inOther); - } - bool operator!=(const SDebugValue &inOther) const - { - return TDebugValueUnionType::operator!=(inOther); - } - - bool empty() const { return getType() == DebugValueTypes::NoDebugValue; } - }; - - struct SDebugValueOpt : public Option - { - SDebugValueOpt(const SDebugValueOpt &inOther) - : Option(inOther) - { - } - SDebugValueOpt(const Empty &) - : Option() - { - } - SDebugValueOpt() {} - template - SDebugValueOpt(const TDataType &inOther) - : Option(SDebugValue(inOther)) - { - } - SDebugValueOpt &operator=(const SDebugValueOpt &inOther) - { - Option::operator=(inOther); - return *this; - } - }; - - // Breakpoint subtypes - - struct SStateEnterBreakpoint - { - TDebugStr m_ObjectId; - SStateEnterBreakpoint(const TDebugStr &inObj = TDebugStr()) - : m_ObjectId(inObj) - { - } - bool operator==(const SStateEnterBreakpoint &inOther) const - { - return m_ObjectId == inOther.m_ObjectId; - } - }; - - struct SStateExitBreakpoint - { - TDebugStr m_ObjectId; - SStateExitBreakpoint(const TDebugStr &inObj = TDebugStr()) - : m_ObjectId(inObj) - { - } - bool operator==(const SStateExitBreakpoint &inOther) const - { - return m_ObjectId == inOther.m_ObjectId; - } - }; - - template - struct SBreakpointTypeMap - { - static BreakpointTypes::Enum GetType() - { - return BreakpointTypes::UnknownBreakpointType; - } - }; - - template <> - struct SBreakpointTypeMap - { - static BreakpointTypes::Enum GetType() { return BreakpointTypes::StateEnter; } - }; - template <> - struct SBreakpointTypeMap - { - static BreakpointTypes::Enum GetType() { return BreakpointTypes::StateExit; } - }; - template <> - struct SBreakpointTypeMap - { - static BreakpointTypes::Enum GetType() { return BreakpointTypes::Transition; } - }; - - struct SBreakpointUnionTraits - { - typedef BreakpointTypes::Enum TIdType; - enum { - TBufferSize = sizeof(STransitionId), - }; - - static TIdType getNoDataId() { return BreakpointTypes::UnknownBreakpointType; } - - template - static TIdType getType() - { - return SBreakpointTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case BreakpointTypes::StateEnter: - return inVisitor(*NVUnionCast(inData)); - case BreakpointTypes::StateExit: - return inVisitor(*NVUnionCast(inData)); - case BreakpointTypes::Transition: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case BreakpointTypes::UnknownBreakpointType: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case BreakpointTypes::StateEnter: - return inVisitor(*NVUnionCast(inData)); - case BreakpointTypes::StateExit: - return inVisitor(*NVUnionCast(inData)); - case BreakpointTypes::Transition: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case BreakpointTypes::UnknownBreakpointType: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SBreakpointUnionTraits::TBufferSize> - TBreakpointUnionType; - - struct SBreakpoint : public TBreakpointUnionType - { - SBreakpoint() {} - - SBreakpoint(const SBreakpoint &inOther) - : TBreakpointUnionType(static_cast(inOther)) - { - } - - SBreakpoint(const char8_t *inOther) - : TBreakpointUnionType(TEditorStr(inOther)) - { - } - - template - SBreakpoint(const TDataType &inDt) - : TBreakpointUnionType(inDt) - { - } - - SBreakpoint &operator=(const SBreakpoint &inOther) - { - TBreakpointUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SBreakpoint &inOther) const - { - return TBreakpointUnionType::operator==(inOther); - } - bool operator!=(const SBreakpoint &inOther) const - { - return TBreakpointUnionType::operator!=(inOther); - } - - bool empty() const { return getType() == SBreakpointUnionTraits::getNoDataId(); } - }; - - struct SNil - { - bool operator==(const SNil &) const { return true; } - }; - -#define ITERATE_DATAMODEL_VALUE_TYPES \ - HANDLE_DATAMODEL_VALUE_TYPE(Number, float) \ - HANDLE_DATAMODEL_VALUE_TYPE(String, TDebugStr) \ - HANDLE_DATAMODEL_VALUE_TYPE(Nil, SNil) \ - HANDLE_DATAMODEL_VALUE_TYPE(Boolean, bool) \ - HANDLE_DATAMODEL_VALUE_TYPE(Table, SDatamodelTable *) \ - HANDLE_DATAMODEL_VALUE_TYPE(UserData, SDatamodelUserData *) \ - HANDLE_DATAMODEL_VALUE_TYPE(Function, SDatamodelFunction *) \ - HANDLE_DATAMODEL_VALUE_TYPE(CFunction, SDatamodelCFunction *) \ - HANDLE_DATAMODEL_VALUE_TYPE(Thread, SDatamodelThread *) - - template - struct SDatamodelValueTypeMap - { - }; - -#define HANDLE_DATAMODEL_VALUE_TYPE(name, type) \ - template <> \ - struct SDatamodelValueTypeMap \ - { \ - static DatamodelValueTypes::Enum GetType() { return DatamodelValueTypes::name; } \ - }; - ITERATE_DATAMODEL_VALUE_TYPES -#undef HANDLE_DATAMODEL_VALUE_TYPE - - struct SDatamodelValueUnionTraits - { - typedef DatamodelValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(TDebugStr), - }; - - static TIdType getNoDataId() { return DatamodelValueTypes::UnknownType; } - - template - static TIdType getType() - { - return SDatamodelValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { -#define HANDLE_DATAMODEL_VALUE_TYPE(name, type) \ - case DatamodelValueTypes::name: \ - return inVisitor(*NVUnionCast(inData)); - ITERATE_DATAMODEL_VALUE_TYPES -#undef HANDLE_DATAMODEL_VALUE_TYPE - default: - QT3DS_ASSERT(false); - case DatamodelValueTypes::UnknownType: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { -#define HANDLE_DATAMODEL_VALUE_TYPE(name, type) \ - case DatamodelValueTypes::name: \ - return inVisitor(*NVUnionCast(inData)); - ITERATE_DATAMODEL_VALUE_TYPES -#undef HANDLE_DATAMODEL_VALUE_TYPE - default: - QT3DS_ASSERT(false); - case DatamodelValueTypes::UnknownType: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SDatamodelValueUnionTraits::TBufferSize> - TDatamodelValueUnionType; - - struct SDatamodelValue : public TDatamodelValueUnionType - { - SDatamodelValue() {} - - SDatamodelValue(const SDatamodelValue &inOther) - : TDatamodelValueUnionType(static_cast(inOther)) - { - } - - SDatamodelValue(const char8_t *inOther) - : TDatamodelValueUnionType(TDebugStr(inOther)) - { - } - - template - SDatamodelValue(const TDataType &inDt) - : TDatamodelValueUnionType(inDt) - { - } - - SDatamodelValue &operator=(const SDatamodelValue &inOther) - { - TDatamodelValueUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SDatamodelValue &inOther) const - { - return TDatamodelValueUnionType::operator==(inOther); - } - bool operator!=(const SDatamodelValue &inOther) const - { - return TDatamodelValueUnionType::operator!=(inOther); - } - - bool empty() const { return getType() == SDatamodelValueUnionTraits::getNoDataId(); } - }; - - struct STableEntry - { - TDebugStr m_Key; - SDatamodelValue m_Value; - STableEntry(const TDebugStr &inKey = TDebugStr(), - const SDatamodelValue &inValue = SDatamodelValue()) - : m_Key(inKey) - , m_Value(inValue) - { - } - - bool operator==(const STableEntry &inOther) const - { - return m_Key == inOther.m_Key && m_Value == inOther.m_Value; - } - }; - - struct TableModificationType - { - enum Enum { - UnknownModification = 0, - SetKey = 1, - RemoveKey = 2, - }; - }; - - struct STableModification - { - STableEntry m_Entry; - TableModificationType::Enum m_Type; - STableModification( - const STableEntry &inEntry = STableEntry(), - TableModificationType::Enum inEnum = TableModificationType::UnknownModification) - : m_Entry(inEntry) - , m_Type(inEnum) - { - } - bool operator==(const STableModification &inMod) const - { - return inMod.m_Entry == m_Entry && inMod.m_Type == m_Type; - } - }; - - typedef eastl::vector TTableModificationList; - } -} -} - -#ifndef _INTEGRITYPLATFORM -namespace qt3ds { -namespace foundation { - template <> - struct DestructTraits - { - void destruct(qt3ds::state::debugger::SNil &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::debugger::SDatamodelTable *) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::debugger::SDatamodelUserData *) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::debugger::SDatamodelFunction *) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::debugger::SDatamodelCFunction *) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::debugger::SDatamodelThread *) {} - }; -} -} -#endif - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateTest.h b/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateTest.h deleted file mode 100644 index 6edbe366..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Debugger/Qt3DSStateTest.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_TEST_H -#define QT3DS_STATE_TEST_H -#include "Qt3DSState.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" - -namespace qt3ds { -namespace state { - namespace test { - - struct LogType - { - enum Enum { - Error = 0, - Info = 1, - }; - }; - - struct STestResults - { - QT3DSU32 m_TotalTests; - QT3DSU32 m_PassingTests; - STestResults(QT3DSU32 totalTests = 0, QT3DSU32 testPassed = 0) - : m_TotalTests(totalTests) - , m_PassingTests(testPassed) - { - } - STestResults &operator+=(const STestResults &inOther) - { - m_TotalTests += inOther.m_TotalTests; - m_PassingTests += inOther.m_PassingTests; - return *this; - } - - bool Failed() const { return m_TotalTests != m_PassingTests; } - bool Passed() const { return !Failed(); } - }; - - class IDataLogger - { - protected: - virtual ~IDataLogger() {} - public: - virtual void Log(LogType::Enum inLogType, const char8_t *file, int line, - const char8_t *message) = 0; - }; - - // Run a data test returning a true/false result for pass/fail. - class IDataTest - { - public: - static Option RunFile(const char8_t *fname, const char8_t *inRootDir, - IDataLogger &inLogger); - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSSceneGraphArchitectDebugger.cpp b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSSceneGraphArchitectDebugger.cpp deleted file mode 100644 index e15f587d..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSSceneGraphArchitectDebugger.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSSceneGraphDebugger.h" -#include "Qt3DSSceneGraphDebuggerValue.h" -#include "Qt3DSSceneGraphDebuggerProtocol.h" -#include "Qt3DSUIADatamodel.h" -#include "Qt3DSStateEditorValue.h" -#include "Qt3DSUIADatamodelValue.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSContainers.h" -#include "Qt3DSKernelTypes.h" -#include "Qt3DSHash.h" //we need to duplicate the hash attribute calls -#include "EASTL/set.h" - -using namespace qt3ds; -using namespace qt3ds::state; -using namespace qt3ds::app; -using namespace qt3ds::state::debugger; - -namespace { - -struct SAppElemVectorSet -{ - nvvector m_Elements; - eastl::hash_set, eastl::equal_to, - ForwardingAllocator> - m_Set; - SAppElemVectorSet(NVAllocatorCallback &alloc) - : m_Elements(alloc, "AppElemVectorSet") - , m_Set(ForwardingAllocator(alloc, "AppElemVectorSet")) - { - } - - void insert(SAppElement *elem) - { - if (m_Set.insert(elem).second) - m_Elements.push_back(elem); - } - - void clear() - { - m_Elements.clear(); - m_Set.clear(); - } - NVConstDataRef ToDataRef() { return m_Elements; } -}; - -struct SValueIndex -{ - QT3DSU32 m_ValueIndex; - QT3DSU32 m_Component; - SValueIndex(QT3DSU32 vi, QT3DSU32 component) - : m_ValueIndex(vi) - , m_Component(component) - { - } -}; - -struct SAppElementEntry -{ - Q3DStudio::TAttOrArgList m_AttList; - eastl::hash_map m_HashToIndexMap; - eastl::vector m_RuntimeValues; -}; - -struct SPresentationEntry -{ - CRegisteredString m_Id; - eastl::hash_map m_ElementMap; -}; - -Option ValueToFloat(const SSGValue &val) -{ - if (val.getType() == SGPropertyValueTypes::Float) - return val.getData(); - return Empty(); -} - -Option ValueToInteger(const SSGValue &val) -{ - if (val.getType() == SGPropertyValueTypes::I32) - return val.getData(); - return Empty(); -} - -Option ValueToString(const SSGValue &val) -{ - if (val.getType() == SGPropertyValueTypes::String) - return val.getData(); - return Empty(); -} - -template -struct SValueSetter -{ -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue &incoming, float &outgoing, QT3DSU32 /*component*/) - { - Option val = ValueToFloat(incoming); - if (val.hasValue()) - outgoing = *val; - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue &incoming, QT3DSVec2 &outgoing, QT3DSU32 component) - { - Option val = ValueToFloat(incoming); - if (val.hasValue()) { - switch (component) { - case 0: - outgoing.x = *val; - break; - case 1: - outgoing.y = *val; - break; - default: - QT3DS_ASSERT(false); - break; - } - } - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue &incoming, QT3DSVec3 &outgoing, QT3DSU32 component) - { - Option val = ValueToFloat(incoming); - if (val.hasValue()) { - switch (component) { - case 0: - outgoing.x = *val; - break; - case 1: - outgoing.y = *val; - break; - case 2: - outgoing.z = *val; - break; - default: - QT3DS_ASSERT(false); - break; - } - } - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue &incoming, QT3DSI32 &outgoing, QT3DSU32 /*component*/) - { - Option val = ValueToInteger(incoming); - if (val.hasValue()) - outgoing = *val; - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue &incoming, eastl::string &outgoing, QT3DSU32 /*component*/) - { - Option val = ValueToString(incoming); - if (val.hasValue()) - outgoing = eastl::string(val->c_str()); - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue &incoming, bool &outgoing, QT3DSU32 /*component*/) - { - Option val = ValueToInteger(incoming); - if (val.hasValue()) - outgoing = (*val) != 0 ? true : false; - } -}; - -// Element ref. Not sure what to do about this right now -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue & /*incoming*/, SGuid & /*outgoing*/, QT3DSU32 /*component*/) - { - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue & /*incoming*/, CRegisteredString & /*outgoing*/, - QT3DSU32 /*component*/) - { - QT3DS_ASSERT(false); - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue & /*incoming*/, SObjectRef & /*outgoing*/, - QT3DSU32 /*component*/) - { - } -}; - -template <> -struct SValueSetter -{ - static void SetValue(const SSGValue & /*incoming*/, CStringOrInt & /*outgoing*/, - QT3DSU32 /*component*/) - { - } -}; - -struct SValueSetterVisitor -{ - const SSGValue &m_Incoming; - QT3DSU32 m_Component; - SValueSetterVisitor &operator=(const SValueSetterVisitor &); - SValueSetterVisitor(const SSGValue &i, QT3DSU32 c) - : m_Incoming(i) - , m_Component(c) - { - } - template - void operator()(TDataType &dt) - { - SValueSetter::SetValue(m_Incoming, dt, m_Component); - } - // object refs can generate this response. - void operator()() {} -}; - -void SetComponentValue(const SSGValue &incoming, app::SDatamodelValue &outgoing, QT3DSU32 component) -{ - SValueSetterVisitor visitor(incoming, component); - outgoing.visit(visitor); -} - -struct SArchitectDebuggerImpl : public ISceneGraphArchitectDebugger -{ - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_Datamodel; - NVScopedRefCounted m_Stream; - ISceneGraphArchitectDebuggerListener *m_Listener; - nvhash_map m_ElemAppElemMap; - nvhash_map m_RuntimeValues; - SAppElemVectorSet m_DirtySet; - eastl::vector m_Presentations; - bool m_Valid; - QT3DSI32 mRefCount; - - SArchitectDebuggerImpl(IDatamodel &dm) - : m_Foundation(dm.GetFoundation()) - , m_Datamodel(dm) - , m_Stream(NULL) - , m_Listener(NULL) - , m_ElemAppElemMap(dm.GetFoundation().getAllocator(), "ElemAppMap") - , m_RuntimeValues(dm.GetFoundation().getAllocator(), "RuntimeValues") - , m_DirtySet(dm.GetFoundation().getAllocator()) - , m_Valid(true) - , mRefCount(0) - { - } - - void addRef() { atomicIncrement(&mRefCount); } - void release() - { - // ensure the datamodel sticks around until after we are destroyed - NVScopedRefCounted dm(m_Datamodel); - atomicDecrement(&mRefCount); - if (mRefCount <= 0) { - NVDelete(m_Foundation.getAllocator(), this); - } - } - - virtual IDatamodel &GetDatamodel() { return *m_Datamodel; } - - static QT3DSI32 GetHashValue(const char *name, const char *component, eastl::string &ioWorkspace) - { - ioWorkspace.assign(nonNull(name)); - ioWorkspace.append("."); - ioWorkspace.append(component); - return Q3DStudio::CHash::HashAttribute(ioWorkspace.c_str()); - } - - void AppendAttribute(const char *name, const char *formalName, ERuntimeDataModelDataType dtype, - SAppElementEntry &theEntry) - { - SAttOrArg newValue; - newValue.m_Name = name; - newValue.m_FormalName = formalName; - newValue.m_DataType = dtype; - theEntry.m_AttList.push_back(newValue); - theEntry.m_RuntimeValues.push_back(qt3ds::app::SDatamodelValue()); - } - - void LoadAppElement(SAppElement &elem, SPresentationEntry &entry) - { - entry.m_ElementMap.insert(eastl::make_pair( - m_Datamodel->GetStringTable().RegisterStr(m_Datamodel->GetElementId(elem).c_str()), - &elem)); - SAppElementEntry &theEntry = m_RuntimeValues[&elem]; - theEntry.m_AttList = m_Datamodel->GetElementAttributes(elem); - theEntry.m_RuntimeValues = m_Datamodel->GetElementAttributeInitialValues(elem); - AppendAttribute("active", "Active", ERuntimeDataModelDataTypeBool, theEntry); - - if (m_Datamodel->IsComponent(elem)) { - AppendAttribute("slide", "(Slide)", ERuntimeDataModelDataTypeLong, theEntry); - AppendAttribute("time", "(Time)", ERuntimeDataModelDataTypeLong, theEntry); - AppendAttribute("paused", "(Mode)", ERuntimeDataModelDataTypeBool, theEntry); - } - eastl::string hashTemp; - for (QT3DSU32 idx = 0, end = (QT3DSU32)theEntry.m_AttList.size(); idx < end; ++idx) { - // Build out the component hash names. - const Q3DStudio::SAttOrArg &theProp(theEntry.m_AttList[idx]); - switch (theProp.m_DataType) { - // one component, one hash, just hash the name - default: - theEntry.m_HashToIndexMap.insert( - eastl::make_pair((QT3DSI32)Q3DStudio::CHash::HashAttribute(theProp.m_Name.c_str()), - SValueIndex(idx, 0))); - break; - case ERuntimeDataModelDataTypeFloat2: { - theEntry.m_HashToIndexMap.insert(eastl::make_pair( - GetHashValue(theProp.m_Name.c_str(), "x", hashTemp), SValueIndex(idx, 0))); - theEntry.m_HashToIndexMap.insert(eastl::make_pair( - GetHashValue(theProp.m_Name.c_str(), "y", hashTemp), SValueIndex(idx, 1))); - } break; - case ERuntimeDataModelDataTypeFloat3: { - const char *compNames[3] = { "x", "y", "z" }; - if (theProp.m_MetaType == ERuntimeAdditionalMetaDataTypeColor) { - compNames[0] = "r"; - compNames[1] = "g"; - compNames[2] = "b"; - } - - theEntry.m_HashToIndexMap.insert( - eastl::make_pair(GetHashValue(theProp.m_Name.c_str(), compNames[0], hashTemp), - SValueIndex(idx, 0))); - theEntry.m_HashToIndexMap.insert( - eastl::make_pair(GetHashValue(theProp.m_Name.c_str(), compNames[1], hashTemp), - SValueIndex(idx, 1))); - theEntry.m_HashToIndexMap.insert( - eastl::make_pair(GetHashValue(theProp.m_Name.c_str(), compNames[2], hashTemp), - SValueIndex(idx, 2))); - } break; - } - // Set a value - if (theEntry.m_RuntimeValues[idx].getType() == ERuntimeDataModelDataTypeNone) { - switch (theProp.m_DataType) { - case ERuntimeDataModelDataTypeFloat: - theEntry.m_RuntimeValues[idx] = 0.0f; - break; - case ERuntimeDataModelDataTypeFloat2: - theEntry.m_RuntimeValues[idx] = QT3DSVec2(0, 0); - break; - case ERuntimeDataModelDataTypeFloat3: - theEntry.m_RuntimeValues[idx] = QT3DSVec3(0, 0, 0); - break; - case ERuntimeDataModelDataTypeLong: - theEntry.m_RuntimeValues[idx] = (QT3DSI32)0; - break; - case ERuntimeDataModelDataTypeString: - theEntry.m_RuntimeValues[idx] = eastl::string(); - break; - case ERuntimeDataModelDataTypeBool: - theEntry.m_RuntimeValues[idx] = false; - break; - case ERuntimeDataModelDataTypeStringRef: - theEntry.m_RuntimeValues[idx] = eastl::string(); - break; - // object references are stored as string values. - case ERuntimeDataModelDataTypeObjectRef: - theEntry.m_RuntimeValues[idx] = eastl::string(); - break; - case ERuntimeDataModelDataTypeStringOrInt: - theEntry.m_RuntimeValues[idx] = eastl::string(); - break; - } - } - } - eastl::vector children = m_Datamodel->GetElementChildren(elem); - for (size_t childIdx = 0, childEnd = children.size(); childIdx < childEnd; ++childIdx) { - LoadAppElement(*children[childIdx], entry); - } - } - - void LoadDatamodel() - { - eastl::vector presentations = m_Datamodel->GetPresentations(); - m_Presentations.clear(); - m_RuntimeValues.clear(); - m_ElemAppElemMap.clear(); - m_Presentations.resize(presentations.size()); - for (size_t idx = 0, end = presentations.size(); idx < end; ++idx) { - app::SPresentation &incoming(presentations[idx]); - SPresentationEntry &pres = m_Presentations[idx]; - pres.m_Id = m_Datamodel->GetStringTable().RegisterStr(incoming.m_Id.c_str()); - if (incoming.m_Scene) - LoadAppElement(*incoming.m_Scene, pres); - } - } - - SAppElementEntry *GetRuntimeValues(app::SAppElement &elem) - { - nvhash_map::iterator iter = m_RuntimeValues.find(&elem); - if (iter != m_RuntimeValues.end()) - return &iter->second; - return NULL; - } - - SPresentationEntry *FindPresentation(CRegisteredString &str) - { - for (size_t idx = 0, end = m_Presentations.size(); idx < end; ++idx) - if (m_Presentations[idx].m_Id == str) - return &m_Presentations[idx]; - return NULL; - } - - /*External interface for clients*/ - - void SetListener(ISceneGraphArchitectDebuggerListener *listener) { m_Listener = listener; } - - Q3DStudio::TAttOrArgList GetElementAttributes(app::SAppElement &elem) - { - SAppElementEntry *entry = GetRuntimeValues(elem); - if (entry) - return entry->m_AttList; - return Q3DStudio::TAttOrArgList(); - } - - eastl::vector GetElementAttributeValues(app::SAppElement &elem) - { - SAppElementEntry *entry = GetRuntimeValues(elem); - if (entry) - return entry->m_RuntimeValues; - return eastl::vector(); - } - - void OnMessageReceived(const SDebugStreamMessage &inMessage) - { - if (!m_Valid) - return; - SSGProtocolReader theReader(inMessage.m_Data, m_Datamodel->GetStringTable()); - while (theReader.Finished() == false && m_Valid) { - SSGProtocolMessageTypes::Enum theMessageType = theReader.MessageType(); - switch (theMessageType) { - case SSGProtocolMessageTypes::Initialization: { - QT3DSU32 version = theReader.ReadInitialization(); - if (version > GetSceneGraphProtocolVersion()) { - QT3DS_ASSERT(false); - m_Foundation.error(QT3DS_INVALID_OPERATION, - "Invalid scene graph debugger protocol version"); - m_Valid = false; - } - } break; - case SSGProtocolMessageTypes::IdUpdate: { - SIdUpdate theUpdate = theReader.ReadIdUpdate(); - SPresentationEntry *theEntry = FindPresentation(theUpdate.m_PresentationId); - if (theEntry) { - for (size_t idx = 0, end = theUpdate.m_IdUpdates.size(); idx < end; ++idx) { - const SElemMap &elemMap(theUpdate.m_IdUpdates[idx]); - eastl::hash_map::iterator iter = - theEntry->m_ElementMap.find(elemMap.m_Id); - if (iter != theEntry->m_ElementMap.end()) - m_ElemAppElemMap[elemMap.m_Elem] = iter->second; - else { - QT3DS_ASSERT(false); - m_Foundation.error(QT3DS_WARN, "Failed to map element"); - } - } - } - } break; - case SSGProtocolMessageTypes::ElemUpdate: { - SElemUpdate theUpdate = theReader.ReadElemUpdate(); - nvhash_map::iterator ptrToElem = - m_ElemAppElemMap.find(theUpdate.m_Elem); - if (ptrToElem != m_ElemAppElemMap.end()) { - nvhash_map::iterator elemToEntry = - m_RuntimeValues.find(ptrToElem->second); - if (elemToEntry != m_RuntimeValues.end()) { - SAppElementEntry &theEntry(elemToEntry->second); - m_DirtySet.insert(elemToEntry->first); - for (size_t idx = 0, end = theUpdate.m_Updates.size(); idx < end; ++idx) { - const SValueUpdate &theValue(theUpdate.m_Updates[idx]); - eastl::hash_map::iterator hashIndex = - theEntry.m_HashToIndexMap.find(theValue.m_Hash); - if (hashIndex != theEntry.m_HashToIndexMap.end()) { - const SValueIndex theIdx = hashIndex->second; - SetComponentValue(theValue.m_Value, - theEntry.m_RuntimeValues[theIdx.m_ValueIndex], - theIdx.m_Component); - } - } - } else { - QT3DS_ASSERT(false); - m_Foundation.error(QT3DS_WARN, "Failed to map element"); - } - } else { - QT3DS_ASSERT(false); - m_Foundation.error(QT3DS_WARN, "Failed to map element"); - } - } break; - case SSGProtocolMessageTypes::Frame: { - NVConstDataRef dirtyItems = m_DirtySet.ToDataRef(); - if (dirtyItems.size() && m_Listener) { - m_Listener->OnItemsDirty(dirtyItems); - m_DirtySet.clear(); - } - } break; - } - } // end while - } - - void AttachToStream(IDebugOutStream &inStream) { m_Stream = &inStream; } - - void RefreshData(bool inNeedReloadData) - { - if (inNeedReloadData) - m_Datamodel->RefreshFile(); - LoadDatamodel(); - } -}; -} - -ISceneGraphArchitectDebugger & -ISceneGraphArchitectDebugger::Create(qt3ds::app::IDatamodel &inDatamodel) -{ - SArchitectDebuggerImpl &retval = - *QT3DS_NEW(inDatamodel.GetFoundation().getAllocator(), SArchitectDebuggerImpl)(inDatamodel); - retval.LoadDatamodel(); - return retval; -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateDebuggerMaster.cpp b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateDebuggerMaster.cpp deleted file mode 100644 index 83fe016f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateDebuggerMaster.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateDebugger.h" -#include "Qt3DSStateDebuggerProtocol.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSAtomic.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::debugger; - -namespace { -MallocAllocator g_MallocAlloc; - -struct SDebugStrInStream : public IInStream -{ - size_t m_Pos; - const TDebugStr &m_Str; - SDebugStrInStream(const TDebugStr &inStr) - : m_Pos(0) - , m_Str(inStr) - { - } - virtual QT3DSU32 Read(NVDataRef data) - { - size_t available = NVMin((size_t)data.size(), m_Str.size() - m_Pos); - if (available) { - memCopy(data.begin(), m_Str.data() + m_Pos, (QT3DSU32)available); - m_Pos += available; - } - return (QT3DSU32)available; - } -}; - -struct SDebuggerMaster : public IDebuggerMaster -{ - typedef eastl::hash_map> TIdInterpreterMap; - - QT3DSI32 mRefCount; - NVScopedRefCounted m_OutStream; - TIdInterpreterMap m_Interpreters; - IDebuggerMasterListener &m_Listener; - SMessageSerializer m_Serializer; - SMessageParser m_Parser; - TDebugStr m_LogStr; - TDebugStr m_MessageStr; - bool m_Invalid; - - SDebuggerMaster(IDebugOutStream &inStream, IDebuggerMasterListener &listener) - : mRefCount(0) - , m_OutStream(inStream) - , m_Listener(listener) - , m_Invalid(false) - { - } - - virtual ~SDebuggerMaster() - { - // Disconnect(); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_MallocAlloc); - - template - void SendMessage(QT3DSI32 inStreamId, const TMessageType &inMessage) - { - m_Serializer.Serialize(inStreamId, inMessage, 0); - m_OutStream->Write(m_Serializer.ToRawMessage()); - } - - virtual void OnMessageReceived(const SDebugStreamMessage &inMessage) - { - if (m_Invalid) - return; - m_Parser.Parse(inMessage.m_Data, *this); - } - - void ReleaseAllInterpreters() - { - for (TIdInterpreterMap::iterator iter = m_Interpreters.begin(), end = m_Interpreters.end(); - iter != end; ++iter) { - iter->second->Disconnect(); - m_Listener.OnInterpreterDisconnected(*iter->second.mPtr); - } - m_Interpreters.clear(); - } - - virtual void Disconnect() - { - SendMessage(-1, SDisconnect()); - ReleaseAllInterpreters(); - } - - IDebuggedInterpreter *FindInterpreter(QT3DSI32 inStreamId) - { - TIdInterpreterMap::iterator iter = m_Interpreters.find(inStreamId); - if (iter != m_Interpreters.end()) - return iter->second.mPtr; - return NULL; - } - -// Set of ignored messages -#define IGNORE_DEBUG_MESSAGE_TYPE(tname) \ - void OnMessage(QT3DSU32, QT3DSU64, const S##tname &) { QT3DS_ASSERT(false); } - - // this are outgoing messages; we shouldn't be receiving them. - IGNORE_DEBUG_MESSAGE_TYPE(SetBreakpoint) - IGNORE_DEBUG_MESSAGE_TYPE(ClearBreakpoint) - IGNORE_DEBUG_MESSAGE_TYPE(BreakOnMicrostep) - IGNORE_DEBUG_MESSAGE_TYPE(ClearAllBreakpoints) - IGNORE_DEBUG_MESSAGE_TYPE(Continue) - - void OnMessage(QT3DSU32 sid, QT3DSU64, const SConnect &inMessage) - { - SDebugStrInStream theStream(inMessage.m_SCXMLData); - TEditorPtr theEditor(IEditor::CreateEditor(inMessage.m_Filename.c_str(), theStream)); - if (theEditor) { - IDebuggedInterpreter &theInterpreter = IDebuggedInterpreter::Create( - g_MallocAlloc, *m_OutStream.mPtr, theEditor, inMessage.m_Filename, sid, - toConstDataRef(inMessage.m_Configuration.data(), - (QT3DSU32)inMessage.m_Configuration.size()), - m_Listener); - m_Interpreters.insert(eastl::make_pair(sid, &theInterpreter)); - m_Listener.OnInterpreterConnected(theInterpreter); - } else { - m_LogStr.assign("Connection failed: "); - m_LogStr.append(inMessage.m_Filename); - // log the failure somehow. - m_Listener.OnLog(NULL, m_LogStr); - } - } - - void OnMessage(QT3DSU32 sid, QT3DSU64, const SBreakpointHit &inMessage) - { - IDebuggedInterpreter *interp = FindInterpreter(sid); - if (interp) - interp->BreakpointHit(inMessage.m_Breakpoint); - } - - void OnMessage(QT3DSU32, QT3DSU64, const SInitialization &inMessage) - { - if (inMessage.m_Version != SInitialization::GetCurrentVersion()) { - QT3DS_ASSERT(false); - m_Invalid = true; - } - } - - void OnMessage(QT3DSU32 sid, QT3DSU64, const SDebugLog &inMessage) - { - IDebuggedInterpreter *interp = FindInterpreter(sid); - m_Listener.OnLog(interp, inMessage.m_Message); - } - -#define FORWARD_INTERPRETER_EVENT(evnType, interpFun) \ - void OnMessage(QT3DSI32 sid, QT3DSU64, const evnType &inMsg) \ - { \ - IDebuggedInterpreter *interp = FindInterpreter(sid); \ - if (interp) \ - interp->interpFun(inMsg); \ - } - - FORWARD_INTERPRETER_EVENT(SEventQueued, OnEventQueued); - FORWARD_INTERPRETER_EVENT(SBeginStep, OnBeginStep); - FORWARD_INTERPRETER_EVENT(SBeginMicrostep, OnBeginMicrostep); - FORWARD_INTERPRETER_EVENT(SMicrostepEvent, OnMicrostepEvent); - FORWARD_INTERPRETER_EVENT(SMicrostepData, OnMicrostepData); - FORWARD_INTERPRETER_EVENT(SEndMicrostep, OnEndMicrostep); - FORWARD_INTERPRETER_EVENT(SModifyTableValues, OnModifyTable); - - void OnMessage(QT3DSI32 sid, QT3DSU64, const SDisconnect &) - { - if (sid > 0) { - IDebuggedInterpreter *interp = FindInterpreter(sid); - if (interp) { - m_Listener.OnInterpreterDisconnected(*interp); - m_Interpreters.erase(sid); - } - } else { - ReleaseAllInterpreters(); - } - } - - void error(const char8_t *inPrefix, const char8_t *inSuffix) - { - m_LogStr.assign(nonNull(inPrefix)); - m_LogStr.append(nonNull(inSuffix)); - m_Listener.OnLog(NULL, m_LogStr); - } -}; -} - -IDebuggerMaster &IDebuggerMaster::CreateMaster(IDebugOutStream &outStream, - IDebuggerMasterListener &inListener) -{ - return *QT3DS_NEW(g_MallocAlloc, SDebuggerMaster)(outStream, inListener); -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.cpp b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.cpp deleted file mode 100644 index 6891fab0..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.cpp +++ /dev/null @@ -1,1880 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSState.h" -#include "Qt3DSStateEditorEditorsImpl.h" -#include "Qt3DSStateExecutionContext.h" -#include "EASTL/sort.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::editor; - -namespace qt3ds { -namespace state { - namespace editor { - -#pragma warning(disable : 4355) - - SEditorImpl::SEditorImpl(TFoundationPtr inFoundation, - NVScopedRefCounted inStringTable) - : m_EditorFoundation(inFoundation) - , m_StringTable(inStringTable) - , m_AutoAllocator(m_EditorFoundation->getFoundation()) - , m_StateContext(IStateContext::Create(m_EditorFoundation->getFoundation())) - , m_Editors(m_EditorFoundation->getAllocator(), "SEditorImpl::m_Editors") - , mRefCount(0) - , m_TransactionManager( - QT3DS_NEW(inFoundation->getAllocator(), STransactionManagerImpl)(inFoundation)) - , m_Accessors(m_EditorFoundation->getAllocator(), "SEditorImpl::m_Accessors") - , m_CopyPasteListener(NULL) - { - } - - void SEditorImpl::addRef() { atomicIncrement(&mRefCount); } - - void SEditorImpl::release() - { - QT3DSI32 count = atomicDecrement(&mRefCount); - if (count <= 0) { - TFoundationPtr theFoundation(m_EditorFoundation); - NVDelete(theFoundation->getAllocator(), this); - } - } - - TObjPtr SEditorImpl::InsertEditor(void *inData, IEditorObject *inEditor) - { - if (inEditor) { - bool insertResult = m_Editors.insert(eastl::make_pair(inData, inEditor)).second; - QT3DS_ASSERT(insertResult); - (void)insertResult; - } - return inEditor; - } - - template - TObjPtr SEditorImpl::ToEditor(TStateType &inItem) - { - TStateEditorMap::iterator iter = m_Editors.find(&inItem); - if (iter != m_Editors.end()) - return iter->second; - - TObjPtr retval = SStateEditorMap::CreateEditor(inItem, *this, m_Accessors); - if (retval) - InsertEditor(&inItem, retval.mPtr); - return retval; - } - - template - TObjPtr SEditorImpl::ToEditor(TStateType *inItem) - { - if (inItem == NULL) - return TObjPtr(); - - return ToEditor(*inItem); - } - - TObjPtr SEditorImpl::ToEditor(SStateNode &inItem) - { - switch (inItem.m_Type) { - case StateNodeTypes::State: - return ToEditor(static_cast(inItem)); - case StateNodeTypes::Parallel: - return ToEditor(static_cast(inItem)); - case StateNodeTypes::Transition: - return ToEditor(static_cast(inItem)); - case StateNodeTypes::Final: - return ToEditor(static_cast(inItem)); - case StateNodeTypes::SCXML: - return ToEditor(static_cast(inItem)); - case StateNodeTypes::History: - return ToEditor(static_cast(inItem)); - default: - QT3DS_ASSERT(false); - return TObjPtr(); - } - } - - TObjPtr SEditorImpl::ExecutableContentToEditor(SExecutableContent &inItem) - { - TStateEditorMap::iterator iter = m_Editors.find(&inItem); - if (iter != m_Editors.end()) - return iter->second; - - switch (inItem.m_Type) { - case ExecutableContentTypes::Send: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::Raise: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::Log: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::Assign: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::If: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::ElseIf: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::Else: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::Script: - return ToEditor(static_cast(inItem)); - case ExecutableContentTypes::Cancel: - return ToEditor(static_cast(inItem)); - default: - QT3DS_ASSERT(false); - return TObjPtr(); - } - } - - template - TStateType *SEditorImpl::FromEditor(TObjPtr inPtr) - { - if (inPtr.mPtr == NULL) - return NULL; - const char8_t *typeName = inPtr->TypeName(); - typedef typename SStateEditorMap::TEditorType TProspectiveType; - if (AreEqual(typeName, TProspectiveType::GetTypeStr())) { - return reinterpret_cast( - &static_cast(inPtr.mPtr)->m_Data); - } - return NULL; - } - - SStateNode *SEditorImpl::StateNodeFromEditor(TObjPtr inPtr) - { - if (inPtr.mPtr == NULL) - return NULL; - const char8_t *typeName = inPtr->TypeName(); - if (AreEqual(typeName, SSCXMLEditor::GetTypeStr())) - return FromEditor(inPtr); - if (AreEqual(typeName, SStateEditor::GetTypeStr())) - return FromEditor(inPtr); - if (AreEqual(typeName, STransitionEditor::GetTypeStr())) - return FromEditor(inPtr); - if (AreEqual(typeName, SParallelEditor::GetTypeStr())) - return FromEditor(inPtr); - if (AreEqual(typeName, SFinalEditor::GetTypeStr())) - return FromEditor(inPtr); - if (AreEqual(typeName, SHistoryEditor::GetTypeStr())) - return FromEditor(inPtr); - return NULL; - } - - SExecutableContent *SEditorImpl::ExecutableContentFromEditor(TObjPtr inPtr) - { - if (inPtr.mPtr == NULL) - return NULL; - const char8_t *typeName = inPtr->TypeName(); - if (AreEqual(typeName, SSendEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SRaiseEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SLogEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SAssignEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SIfEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SElseIfEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SElseEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SScriptEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - if (AreEqual(typeName, SCancelEditor::GetTypeStr())) { - return FromEditor(inPtr); - } - - return NULL; - } - - void SEditorImpl::GenerateUniqueId(SStateNode &inNode, const char8_t *inStem) - { - QT3DS_ASSERT(inNode.m_Id.IsValid() == false); - CXMLIO::GenerateUniqueId(inNode, inStem, *m_StateContext, *m_StringTable); - } - - void SEditorImpl::GenerateUniqueId(SSend &inNode, const char8_t *inStem) - { - CXMLIO::GenerateUniqueId(inNode, inStem, *m_StateContext, *m_StringTable); - } - - TObjPtr SEditorImpl::GetRoot() { return ToEditor(m_StateContext->GetRoot()); } - - template - eastl::pair SEditorImpl::CreateEditorAndObject() - { - typedef typename SStateEditorMap::TEditorType TEditorType; - TObjPtr newEditor = SStateEditorMap::CreateEditor(*this, m_Accessors); - TStateType *theState = &static_cast(newEditor.mPtr)->m_Data; - eastl::pair retval = eastl::make_pair(theState, newEditor); - InsertEditor(retval.first, retval.second.mPtr); - return retval; - } - - TObjPtr SEditorImpl::DoCreate(const char8_t *inTypeName, const char8_t *inId) - { - if (AreEqual(inTypeName, SSCXMLEditor::GetTypeStr())) { - QT3DS_ASSERT(m_StateContext->GetRoot() == NULL); - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, inId == NULL ? "scxml" : inId); - m_StateContext->SetRoot(*theNewEditor.first); - return theNewEditor.second; - } else if (AreEqual(inTypeName, SStateEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, inId == NULL ? "state" : inId); - return theNewEditor.second; - } else if (AreEqual(inTypeName, SParallelEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, inId == NULL ? "parallel" : inId); - return theNewEditor.second; - } else if (AreEqual(inTypeName, SFinalEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, inId == NULL ? "final" : inId); - return theNewEditor.second; - } else if (AreEqual(inTypeName, SHistoryEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, inId == NULL ? "history" : inId); - return theNewEditor.second; - } else if (AreEqual(inTypeName, STransitionEditor::GetTypeStr())) { - eastl::pair theNewEditor = - CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, inId == NULL ? "transition" : inId); - return theNewEditor.second; - } else if (AreEqual(inTypeName, SDataModelEditor::GetTypeStr())) { - eastl::pair theNewEditor = - CreateEditorAndObject(); - return theNewEditor.second; - } else if (AreEqual(inTypeName, SDataEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - return theNewEditor.second; - } - - QT3DS_ASSERT(false); - return TObjPtr(); - } - - TObjPtr SEditorImpl::Create(const char8_t *inTypeName, const char8_t *inId) - { - TObjPtr retval = DoCreate(inTypeName, inId); - m_TransactionManager->OnObjectCreated(retval); - return retval; - } - - TObjPtr SEditorImpl::GetOrCreate(SSCXML &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(SState &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(STransition &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(SParallel &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(SFinal &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(SHistory &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(SDataModel &inData) { return ToEditor(inData); } - TObjPtr SEditorImpl::GetOrCreate(SData &inData) { return ToEditor(inData); } - - TObjPtr SEditorImpl::GetObjectById(const char8_t *inId) - { - if (isTrivial(inId)) - return TObjPtr(); - SStateNode *theNode = m_StateContext->FindStateNode(RegisterStr(inId)); - if (theNode) - return ToEditor(*theNode); - return TObjPtr(); - } - - TObjPtr SEditorImpl::GetEditor(void *inGraphData) - { - TStateEditorMap::iterator iter = m_Editors.find(inGraphData); - if (iter != m_Editors.end()) - return iter->second; - return TObjPtr(); - } - - TSignalConnectionPtr SEditorImpl::AddChangeListener(IEditorChangeListener &inListener) - { - return m_TransactionManager->AddChangeListener(inListener); - } - - TTransactionPtr SEditorImpl::BeginTransaction(const TEditorStr &inName) - { - return m_TransactionManager->BeginTransaction(inName); - } - - TTransactionPtr SEditorImpl::GetOpenTransaction() - { - return m_TransactionManager->GetOpenTransaction(); - } - - void SEditorImpl::RollbackTransaction() { m_TransactionManager->RollbackTransaction(); } - - void SEditorImpl::EndTransaction() { m_TransactionManager->EndTransaction(); } - - TEditorStr SEditorImpl::Copy(TObjList inObjects, const QT3DSVec2 &inMousePos) - { - eastl::vector theNodeList; - for (size_t idx = 0, end = inObjects.size(); idx < end; ++idx) { - SStateNode *theNode = StateNodeFromEditor(inObjects[idx]); - if (theNode && theNode->m_Type != StateNodeTypes::Transition - && theNode->m_Type != StateNodeTypes::SCXML) { - theNodeList.push_back(theNode); - } - } - eastl::vector theNamespaces; - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable)); - NVScopedRefCounted theWriter( - IDOMWriter::CreateDOMWriter(m_EditorFoundation->getAllocator(), "scxml_fragment", - m_StringTable) - .first); - - eastl::vector rootNodes = CXMLIO::SaveSCXMLFragment( - *m_StateContext, *m_EditorFoundation->m_Foundation, *m_StringTable, *theWriter, - toDataRef(theNodeList.data(), theNodeList.size()), *this, inMousePos, - theNamespaces); - - if (m_CopyPasteListener) - m_CopyPasteListener->OnCopy(this, rootNodes, *theWriter, theNamespaces); - - SEditorImplStrIOStream theStream; - CDOMSerializer::WriteXMLHeader(theStream); - CDOMSerializer::Write(m_EditorFoundation->getAllocator(), *theWriter->GetTopElement(), - theStream, *m_StringTable, - toDataRef(theNamespaces.data(), theNamespaces.size()), false); - return theStream.m_Str; - } - - bool SEditorImpl::CanPaste(TObjPtr inTarget) - { - SStateNode *theNode = StateNodeFromEditor(inTarget); - if (theNode) { - return theNode->m_Type != StateNodeTypes::Transition - && theNode->m_Type != StateNodeTypes::History - && theNode->m_Type != StateNodeTypes::Final; - } - - return false; - } - - void SEditorImpl::AddNewPasteObjectToTransaction(SStateNode &inNode) - { - TObjPtr editorPtr = ToEditor(inNode); - if (editorPtr) { - m_TransactionManager->m_Transaction->m_Changes.push_back(new SChange(*editorPtr)); - m_TransactionManager->OnObjectCreated(editorPtr); - Option children = editorPtr->GetPropertyValue("children"); - if (children.hasValue()) { - TObjList childList = children->getData(); - for (size_t idx = 0, end = childList.size(); idx < end; ++idx) { - SStateNode *childNode = StateNodeFromEditor(childList[idx]); - if (childNode) - AddNewPasteObjectToTransaction(*childNode); - } - } - } - } - - void RecurseAndCheckForValidHistoryAfterPaste(TObjPtr inNode, SEditorImpl &inEditor) - { - if (AreEqual(inNode->TypeName(), "history")) { - inEditor.CheckAndSetValidHistoryDefault(inNode); - } else { - Option childrenOpt = inNode->GetPropertyValue("children"); - if (childrenOpt.hasValue() == false) { - return; - } - TObjList children = childrenOpt->getData(); - for (size_t childIdx = 0, childEnd = children.size(); childIdx < childEnd; - ++childIdx) { - RecurseAndCheckForValidHistoryAfterPaste(children[childIdx], inEditor); - } - } - } - - void SEditorImpl::Paste(const TEditorStr &inCopiedObjects, TObjPtr inTarget, - const QT3DSVec2 &inMousePos) - { - Option childrenOpt = inTarget->GetPropertyValue("children"); - if (childrenOpt.hasValue() == false) { - QT3DS_ASSERT(false); - return; - } - - TObjList children = childrenOpt->getData(); - - SEditorImplStrInStream inStream(inCopiedObjects); - NVScopedRefCounted theFactory = - IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable); - eastl::pair readResult = - CDOMSerializer::Read(*theFactory, inStream); - SDOMElement *elem = readResult.second; - if (elem == NULL) { - QT3DS_ASSERT(false); - return; - } - NVScopedRefCounted theReader = IDOMReader::CreateDOMReader( - m_EditorFoundation->getAllocator(), *elem, m_StringTable, *theFactory); - eastl::pair, CXMLIO::TIdRemapMap> theRootsPair; - { - IDOMReader::Scope __readerScope(*theReader); - theRootsPair = - CXMLIO::LoadSCXMLFragment(m_AutoAllocator, *m_EditorFoundation->m_Foundation, - *theReader, *m_StringTable, *m_StateContext, *this); - } - eastl::vector &theObjects(theRootsPair.first); - if (m_CopyPasteListener) - m_CopyPasteListener->OnPaste(this, *theReader, theRootsPair.second); - // Merge any namespaces into the context's namespace list. - if (m_StateContext->GetDOMFactory()) { - for (SNamespacePairNode *fragNode = readResult.first; fragNode; - fragNode = fragNode->m_NextNode) { - bool found = false; - for (SNamespacePairNode *ctxNode = m_StateContext->GetFirstNSNode(); - ctxNode && !found; ctxNode = ctxNode->m_NextNode) { - if (ctxNode->m_Namespace == fragNode->m_Namespace) - found = true; - } - if (!found) { - SNamespacePairNode *newNode = - m_StateContext->GetDOMFactory()->NextNSPairNode( - fragNode->m_Namespace, fragNode->m_Abbreviation); - newNode->m_NextNode = m_StateContext->GetFirstNSNode(); - m_StateContext->SetFirstNSNode(*newNode); - } - } - } - QT3DSVec2 globalPos(0, 0); - if (inTarget) { - for (TObjPtr posObj = inTarget; posObj; posObj = posObj->Parent()) { - Option theData = posObj->GetPropertyValue("position"); - if (theData.hasValue()) - globalPos += theData->getData(); - } - } - QT3DSVec2 theMousePos = inMousePos - globalPos; - for (size_t idx = 0, end = theObjects.size(); idx < end; ++idx) { - SStateNode *currentObject = theObjects[idx]; - QT3DSVec2 objPos(0, 0); - if (currentObject->m_StateNodeFlags.HasPosition()) - objPos = currentObject->m_Position; - currentObject->SetPosition(objPos + theMousePos); - if (m_TransactionManager->m_Transaction) - AddNewPasteObjectToTransaction(*currentObject); - TObjPtr editorPtr = ToEditor(*currentObject); - if (editorPtr.mPtr) - children.push_back(editorPtr); - } - // This sets up the valid parents. Without that, checking if a history node is valid - // is meaningless. - inTarget->SetPropertyValue("children", children); - for (size_t idx = 0, end = children.size(); idx < end; ++idx) { - RecurseAndCheckForValidHistoryAfterPaste(children[idx], *this); - } - } - - bool SEditorImpl::IsDerivedFrom(SStateNode &child, SStateNode &parent) - { - if (&child == &parent) - return true; - if (child.m_Parent) - return IsDerivedFrom(*child.m_Parent, parent); - return false; - } - - // This method should always return a value because the scxml root item - // is the parent of everyone else. - SStateNode &SEditorImpl::GetLeastCommonAncestor(SStateNode &lhs, SStateNode &rhs) - { - // If lhs is derived from rhs, return rhs - if (IsDerivedFrom(lhs, rhs)) - return rhs; - // vice versa - else if (IsDerivedFrom(rhs, lhs)) - return lhs; - - // Else wander up the tree till we find a common ancestor. - QT3DS_ASSERT(lhs.m_Parent != NULL); - if (lhs.m_Parent != NULL) - return GetLeastCommonAncestor(*lhs.m_Parent, rhs); - - return lhs; - } - - TObjPtr SEditorImpl::GetLeastCommonAncestor(NVConstDataRef inObjects) - { - SStateNode *lastAncestor = NULL; - if (inObjects.size() == 0) - return TObjPtr(); - - for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { - if (lastAncestor == NULL) { - lastAncestor = StateNodeFromEditor(inObjects[idx]); - } else { - SStateNode *nextNode = StateNodeFromEditor(inObjects[idx]); - if (nextNode != NULL) { - lastAncestor = &GetLeastCommonAncestor(*lastAncestor, *nextNode); - } - } - } - - if (lastAncestor) - return ToEditor(*lastAncestor); - else - return TObjPtr(); - } - - void GetCancelableSendIds(TExecutableContentList &inList, TObjList &outList, - SEditorImpl &inEditor); - - void RecursiveGetCancelableSendIds(SExecutableContent &inNode, TObjList &outList, - SEditorImpl &inEditor) - { - if (inNode.m_Type == ExecutableContentTypes::Send) { - SSend &theSend = static_cast(inNode); - if (IExecutionContext::ParseTimeStrToMilliseconds(theSend.m_Delay) - || !isTrivial(theSend.m_DelayExpr)) { - outList.push_back(inEditor.ExecutableContentToEditor(theSend)); - } - } - GetCancelableSendIds(inNode.m_Children, outList, inEditor); - } - - void GetCancelableSendIds(TExecutableContentList &inList, TObjList &outList, - SEditorImpl &inEditor) - { - for (TExecutableContentList::iterator iter = inList.begin(), end = inList.end(); - iter != end; ++iter) - RecursiveGetCancelableSendIds(*iter, outList, inEditor); - } - - void RecursiveGetCancelableSendIds(SStateNode &inNode, TObjList &outList, - SEditorImpl &inEditor) - { - if (inNode.m_Type == StateNodeTypes::Transition) { - STransition &transition = static_cast(inNode); - GetCancelableSendIds(transition.m_ExecutableContent, outList, inEditor); - } else { - TOnEntryList *entryList = inNode.GetOnEntryList(); - TOnExitList *exitList = inNode.GetOnExitList(); - if (entryList) { - for (TOnEntryList::iterator iter = entryList->begin(), end = entryList->end(); - iter != end; ++iter) - GetCancelableSendIds(iter->m_ExecutableContent, outList, inEditor); - } - if (exitList) { - for (TOnExitList::iterator iter = exitList->begin(), end = exitList->end(); - iter != end; ++iter) - GetCancelableSendIds(iter->m_ExecutableContent, outList, inEditor); - } - } - TStateNodeList *childList = inNode.GetChildren(); - if (childList) { - for (TStateNodeList::iterator childIter = childList->begin(), - childEnd = childList->end(); - childIter != childEnd; ++childIter) - RecursiveGetCancelableSendIds(*childIter, outList, inEditor); - } - } - - // TODO - think about a fast and easy way to cache things (and keep the cache correct). - TObjList SEditorImpl::GetCancelableSendIds() - { - TObjList retval; - if (m_StateContext->GetRoot()) - RecursiveGetCancelableSendIds(*m_StateContext->GetRoot(), retval, *this); - return retval; - } - - static const char8_t *whitespace = "\n\r\t "; - - void StripIfLastChar(TEditorStr &str, char data) - { - if (str.size() && str.back() == data) - str.resize(str.size() - 1); - } - - void AddUnique(TEditorStrList &list, const TEditorStr &str) - { - if (eastl::find(list.begin(), list.end(), str) == list.end()) - list.push_back(str); - } - - void RecursiveScanExecutableContentForEvents(TExecutableContentList &contentList, - TEditorStrList &ioStrList) - { - for (TExecutableContentList::iterator iter = contentList.begin(), - end = contentList.end(); - iter != end; ++iter) { - if (iter->m_Type == ExecutableContentTypes::Send) { - SSend &theSend = static_cast(*iter); - if (!isTrivial(theSend.m_Event)) { - AddUnique(ioStrList, theSend.m_Event.c_str()); - } - } else if (iter->m_Type == ExecutableContentTypes::Raise) { - SRaise &theRaise = static_cast(*iter); - if (!isTrivial(theRaise.m_Event)) { - AddUnique(ioStrList, theRaise.m_Event.c_str()); - } - } - RecursiveScanExecutableContentForEvents(iter->m_Children, ioStrList); - } - } - - template - void ScanItemListForEvents(TListType *itemList, TEditorStrList &ioEvents) - { - if (itemList) { - typedef typename TListType::iterator iterator; - for (iterator iter = itemList->begin(), end = itemList->end(); iter != end; - ++iter) { - RecursiveScanExecutableContentForEvents(iter->m_ExecutableContent, ioEvents); - } - } - } - - void RecursiveGetStateMachineEvents(SStateNode &inNode, TEditorStrList &ioList) - { - if (inNode.m_Type == StateNodeTypes::Transition) { - STransition &theTransition = static_cast(inNode); - TEditorStr transStr(theTransition.m_Event); - for (size_t pos = transStr.find_first_not_of(whitespace); pos != TEditorStr::npos; - pos = transStr.find_first_not_of(whitespace, pos)) { - size_t end = transStr.find_first_of(whitespace, pos); - if (end == TEditorStr::npos) - end = transStr.size(); - TEditorStr subStr = transStr.substr(pos, end - pos); - pos = end; - StripIfLastChar(subStr, '*'); - StripIfLastChar(subStr, '.'); - AddUnique(ioList, subStr); - } - RecursiveScanExecutableContentForEvents(theTransition.m_ExecutableContent, ioList); - } else { - ScanItemListForEvents(inNode.GetOnEntryList(), ioList); - ScanItemListForEvents(inNode.GetOnExitList(), ioList); - } - TStateNodeList *children = inNode.GetChildren(); - if (children) { - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) - RecursiveGetStateMachineEvents(*iter, ioList); - } - } - - TEditorStrList SEditorImpl::GetStateMachineEvents() - { - TEditorStrList retval; - if (m_StateContext->GetRoot()) - RecursiveGetStateMachineEvents(*m_StateContext->GetRoot(), retval); - eastl::sort(retval.begin(), retval.end()); - return retval; - } - - eastl::pair - SEditorImpl::CreateExecutableContent(const char8_t *inTypeName) - { - SExecutableContent *newExecutable = NULL; - TObjPtr newObj; - if (AreEqual(inTypeName, SSendEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, "send"); - newExecutable = theNewEditor.first; - newObj = theNewEditor.second; - } else if (AreEqual(inTypeName, SScriptEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - newExecutable = theNewEditor.first; - newObj = theNewEditor.second; - } else if (AreEqual(inTypeName, SCancelEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - newExecutable = theNewEditor.first; - newObj = theNewEditor.second; - } else { - QT3DS_ASSERT(false); - } - return eastl::make_pair(newExecutable, newObj); - } - - struct SExecListAddChange : public IChange - { - TExecutableContentList &parentList; - SExecutableContent *prevSibling; - SExecutableContent &item; - TObjPtr editorObj; - QT3DSI32 mRefCount; - bool m_AddOnDo; - SExecListAddChange(TExecutableContentList &plist, SExecutableContent *prev, - SExecutableContent &_item, TObjPtr objPtr, bool addOnDo) - : parentList(plist) - , prevSibling(prev) - , item(_item) - , editorObj(objPtr) - , mRefCount(0) - , m_AddOnDo(addOnDo) - { - } - - void Add() - { - if (prevSibling) - parentList.insert_after(*prevSibling, item); - else - parentList.push_front(item); - } - void Remove() { parentList.remove(item); } - - virtual void Do() - { - if (m_AddOnDo) - Add(); - else - Remove(); - } - - virtual void Undo() - { - if (m_AddOnDo) - Remove(); - else - Add(); - } - - virtual TObjPtr GetEditor() { return editorObj; } - - virtual void addRef() { ++mRefCount; } - - virtual void release() - { - --mRefCount; - if (mRefCount <= 0) - delete this; - } - }; - - void SEditorImpl::ReplaceExecutableContent(SExecutableContent &oldContent, - SExecutableContent &newContent) - { - SStateNode *stateNodeParent = oldContent.m_StateNodeParent; - SExecutableContent *execContentParent = oldContent.m_Parent; - SExecutableContentParentInfo parentInfo(oldContent, *this); - SExecutableContent *prevSibling = oldContent.m_PreviousSibling; - - // Can't use remove object from graph here because it is too aggressive. - NVScopedRefCounted oldChange = new SExecListAddChange( - *parentInfo.parentList, prevSibling, oldContent, parentInfo.editorObj, false); - oldChange->Do(); - newContent.m_StateNodeParent = stateNodeParent; - newContent.m_Parent = execContentParent; - NVScopedRefCounted newChange = new SExecListAddChange( - *parentInfo.parentList, prevSibling, newContent, parentInfo.editorObj, true); - newChange->Do(); - if (GetOpenTransactionImpl()) { - GetOpenTransactionImpl()->m_Changes.push_back(oldChange.mPtr); - GetOpenTransactionImpl()->m_Changes.push_back(newChange.mPtr); - } - } - - TObjPtr SEditorImpl::ChangeExecutableContentType(TObjPtr inContent, const char8_t *newType) - { - SExecutableContent *theContent = ExecutableContentFromEditor(inContent); - if (!theContent) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - SExecutableContentParentInfo parentInfo(*theContent, *this); - // find the index of the item in the parent list. - if (parentInfo.parentList == NULL) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - - eastl::pair theNewContent = - CreateExecutableContent(newType); - if (!theNewContent.first) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - ReplaceExecutableContent(*theContent, *theNewContent.first); - return theNewContent.second; - } - - TEditorStr SEditorImpl::ToXML(TObjPtr inContent) - { - SExecutableContent *theContent = ExecutableContentFromEditor(inContent); - if (!theContent) { - QT3DS_ASSERT(false); - return TEditorStr(); - } - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable)); - NVScopedRefCounted theWriter( - IDOMWriter::CreateDOMWriter(m_EditorFoundation->getAllocator(), "innerXML", - m_StringTable, 0) - .first); - CXMLIO::ToEditableXml(*m_StateContext, m_EditorFoundation->getFoundation(), - *m_StringTable, *theWriter, *theContent, *this); - SDOMElement *theTopElem = theWriter->GetTopElement(); - SDOMElement *xmlElem = &theTopElem->m_Children.front(); - SEditorImplStrIOStream theStream; - if (xmlElem) { - - eastl::vector theNamespaces; - for (SNamespacePairNode *theNode = m_StateContext->GetFirstNSNode(); theNode; - theNode = theNode->m_NextNode) - theNamespaces.push_back(*theNode); - if (theNamespaces.empty()) { - theNamespaces.push_back(SNamespacePair( - m_StringTable->RegisterStr("http://www.w3.org/2005/07/scxml"))); - theNamespaces.push_back( - SNamespacePair(m_StringTable->RegisterStr("http://qt.io/qt3dstudio/uicstate"), - m_StringTable->RegisterStr("Qt3DS"))); - } - CDOMSerializer::Write( - m_EditorFoundation->getAllocator(), *xmlElem, theStream, *m_StringTable, - toDataRef(theNamespaces.data(), theNamespaces.size()), false, 0, false); - } - return theStream.m_Str; - } - - struct SStrXMLErrorHandler : public CXmlErrorHandler - { - TEditorStr m_Error; - virtual void OnXmlError(TXMLCharPtr errorName, int line, int /*column*/) - { - char buf[256]; - sprintf(buf, "Error on line %d: ", line); - m_Error.assign(buf); - m_Error.append(nonNull(errorName)); - } - }; - - eastl::pair SEditorImpl::FromXML(TObjPtr inContent, - const TEditorStr &ioEditedXML) - { - TEditorStr wrappedXML(" theNamespaces; - for (SNamespacePairNode *theNode = m_StateContext->GetFirstNSNode(); theNode; - theNode = theNode->m_NextNode) - theNamespaces.push_back(*theNode); - if (theNamespaces.empty()) { - theNamespaces.push_back( - SNamespacePair(m_StringTable->RegisterStr("http://www.w3.org/2005/07/scxml"))); - theNamespaces.push_back( - SNamespacePair(m_StringTable->RegisterStr("http://qt.io/qt3dstudio/uicstate"), - m_StringTable->RegisterStr("Qt3DS"))); - } - for (size_t idx = 0, end = theNamespaces.size(); idx < end; ++idx) { - SNamespacePair &theNode(theNamespaces[idx]); - wrappedXML.append(" xmlns"); - if (theNode.m_Abbreviation.IsValid()) { - wrappedXML.append(":"); - wrappedXML.append(theNode.m_Abbreviation.c_str()); - } - wrappedXML.append("=\""); - wrappedXML.append(theNode.m_Namespace.c_str()); - wrappedXML.append("\""); - } - wrappedXML.append(">"); - wrappedXML.append(ioEditedXML); - wrappedXML.append(""); - SEditorImplStrInStream theStream(wrappedXML); - - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable)); - SStrXMLErrorHandler errorHandler; - SDOMElement *theElem = - CDOMSerializer::Read(*theFactory, theStream, &errorHandler).second; - TObjPtr retval; - if (theElem) { - NVScopedRefCounted theReader(IDOMReader::CreateDOMReader( - m_EditorFoundation->getAllocator(), theElem->m_Children.front(), m_StringTable, - theFactory)); - SExecutableContent *oldContent = ExecutableContentFromEditor(inContent); - SExecutableContent *theContent = - CXMLIO::FromEditableXML(*theReader, m_EditorFoundation->getFoundation(), - *m_StateContext, *m_StringTable, m_AutoAllocator, *this, - oldContent->m_StateNodeParent, oldContent->m_Parent); - if (theContent) { - ReplaceExecutableContent(*oldContent, *theContent); - retval = ExecutableContentToEditor(*theContent); - } else { - errorHandler.m_Error.assign("The \""); - errorHandler.m_Error.append(theReader->GetElementName().c_str()); - errorHandler.m_Error.append("\" action is not recognized. It must be one of:"); - eastl::vector contentNames = - CXMLIO::GetSupportedExecutableContentNames(); - for (size_t idx = 0, end = contentNames.size(); idx < end; ++idx) { - if (idx != 0) - errorHandler.m_Error.append(","); - - errorHandler.m_Error.append(" \""); - errorHandler.m_Error.append(contentNames[idx].c_str()); - errorHandler.m_Error.append("\""); - } - errorHandler.m_Error.append("."); - } - } - - return eastl::make_pair(errorHandler.m_Error, retval); - } - - void SEditorImpl::ReleaseEditor(void *inData) - { - TStateEditorMap::iterator iter = m_Editors.find(inData); - if (iter != m_Editors.end()) - m_Editors.erase(iter); - } - - bool SEditorImpl::Save(const char8_t *inFileName) - { - CFileSeekableIOStream theFile(inFileName, FileWriteFlags()); - if (theFile.IsOpen() == false) { - QT3DS_ASSERT(false); - return false; - } - - Save(theFile); - return true; - } - - void SEditorImpl::Save(IOutStream &inStream) { m_StateContext->Save(inStream, this); } - - bool SEditorImpl::Load(IInStream &inStream, const char8_t *inFilename) - { - bool theRetval = false; - m_StateContext = IStateContext::Load(m_AutoAllocator, *m_EditorFoundation->m_Foundation, - inStream, inFilename, m_StringTable.mPtr, this); - if (m_StateContext.mPtr == 0) - m_StateContext = IStateContext::Create(*m_EditorFoundation->m_Foundation); - else - theRetval = true; - return theRetval; - } - - STransaction *SEditorImpl::GetOpenTransactionImpl() - { - return m_TransactionManager->m_Transaction.mPtr; - } - - void SEditorImpl::SetIdProperty(SStateNode &inNode, const SValue &inData, - CRegisteredString & /*inTarget*/) - { - IStateContext &theContext = *m_StateContext; - theContext.EraseId(inNode.m_Id); - TEditorStr potentialId = inData.getData(); - if (potentialId.size() == 0) { - switch (inNode.m_Type) { - case StateNodeTypes::State: - potentialId = "state"; - break; - case StateNodeTypes::Parallel: - potentialId = "parallel"; - break; - case StateNodeTypes::Transition: - potentialId = "transition"; - break; - case StateNodeTypes::Final: - potentialId = "final"; - break; - case StateNodeTypes::History: - potentialId = "history"; - break; - case StateNodeTypes::SCXML: - potentialId = "scxml"; - break; - default: - QT3DS_ASSERT(false); - potentialId = "id"; - break; - } - } - CRegisteredString oldId = inNode.m_Id; - inNode.m_Id = CRegisteredString(); - GenerateUniqueId(inNode, potentialId.c_str()); - // This is a bad hack to get around: - // 1. user changes id calling this function - if (m_CopyPasteListener) { - m_CopyPasteListener->OnIDChange(this, inNode, oldId); - } - } - - void SEditorImpl::SetIdProperty(SSend &inNode, const SValue &inData, - CRegisteredString & /*inTarget*/) - { - IStateContext &theContext = *m_StateContext; - theContext.EraseId(inNode.m_Id); - TEditorStr potentialId = inData.getData(); - if (potentialId.size() == 0) - potentialId = "send"; - - inNode.m_Id = CRegisteredString(); - GenerateUniqueId(inNode, potentialId.c_str()); - } - - void SEditorImpl::Set(const Option &inData, NVConstDataRef &inTarget) - { - if (inTarget.mData != NULL) { - m_AutoAllocator.deallocate((void *)inTarget.mData); - inTarget.mData = NULL; - inTarget.mSize = 0; - } - if (inData.hasValue()) { - TObjList inList(inData->getData()); - eastl::vector validObjects; - for (size_t idx = 0, end = inList.size(); idx < end; ++idx) { - TObjPtr theObj = inList[idx]; - SStateNode *theNode = StateNodeFromEditor(theObj); - if (theNode) { - validObjects.push_back(theNode); - } else { - QT3DS_ASSERT(false); - } - } - - if (validObjects.empty() == false) { - NVConstDataRef &outList(inTarget); - size_t byteCount = validObjects.size() * sizeof(SStateNode *); - outList.mData = (SStateNode * const *)m_AutoAllocator.allocate( - byteCount, "graph ref list data", __FILE__, __LINE__); - memCopy((void *)outList.mData, validObjects.data(), byteCount); - outList.mSize = validObjects.size(); - } - } - } - - SValue SEditorImpl::Get(NVConstDataRef &inTarget) - { - TObjList retval; - NVConstDataRef inRefList(inTarget); - for (QT3DSU32 idx = 0, end = inRefList.size(); idx < end; ++idx) { - TObjPtr obj = ToEditor(inRefList[idx]); - if (obj) - retval.push_back(obj); - else { - // This shouldn't ever happen, but it might when loading - // an invalid file. - QT3DS_ASSERT(false); - } - } - return retval; - } - - void SEditorImpl::Set(const Option &inData, STransition *&inTarget) - { - inTarget = NULL; - if (inData.hasValue()) { - TObjPtr theData(inData->getData()); - inTarget = FromEditor(theData); - } - } - - Option SEditorImpl::Get(STransition *&inTarget) - { - return SValue(ToEditor(inTarget)); - } - - void SEditorImpl::SetInitial(const TObjList &inList, STransition *&outTransitionPtr) - { - if (outTransitionPtr) { - Set(SValue(inList), outTransitionPtr->m_Target); - if (outTransitionPtr->m_Target.mSize == 0 - && outTransitionPtr->m_ExecutableContent.empty()) - outTransitionPtr = NULL; - } else { - NVConstDataRef theTemp; - Set(SValue(inList), theTemp); - if (theTemp.mSize) { - outTransitionPtr = QT3DS_NEW(m_AutoAllocator, STransition)(); - outTransitionPtr->m_Target = theTemp; - } - } - } - - SValue SEditorImpl::GetInitial(STransition *inInitialTrans) - { - if (inInitialTrans) - return Get(inInitialTrans->m_Target); - - return TObjList(); - } - static inline STransition **GetInitialTransitionPtr(SStateNode &inParent) - { - StateNodeTypes::Enum typeEnum(inParent.m_Type); - STransition **theParentTransPtr = NULL; - if (typeEnum == StateNodeTypes::SCXML) - theParentTransPtr = &static_cast(inParent).m_Initial; - else if (typeEnum == StateNodeTypes::State) - theParentTransPtr = &static_cast(inParent).m_Initial; - return theParentTransPtr; - } - - static inline bool IsFirstChild(SStateNode &inChild, SStateNode &inParent) - { - TStateNodeList *childList = inParent.GetChildren(); - SStateNode *firstViableChild = NULL; - if (childList) { - for (TStateNodeList::iterator iter = childList->begin(), end = childList->end(); - iter != end && firstViableChild == NULL; ++iter) { - StateNodeTypes::Enum typeEnum = iter->m_Type; - if (typeEnum == StateNodeTypes::State || typeEnum == StateNodeTypes::Parallel - || typeEnum == StateNodeTypes::Final) { - firstViableChild = &(*iter); - } - } - } - return firstViableChild == &inChild; - } - - struct SInitialTargetChange : public IChange - { - TObjPtr m_EditorObj; - SStateNode &m_Parent; - STransition *m_InitialTransition; - STransition *m_FinalTransition; - QT3DSI32 m_RefCount; - // Implicitly setting c to be the initial target. - SInitialTargetChange(TObjPtr editorObj, SStateNode &p, SStateNode &c, - SEditorImpl &editor) - : m_EditorObj(editorObj) - , m_Parent(p) - , m_InitialTransition(NULL) - , m_FinalTransition(NULL) - , m_RefCount(0) - { - STransition **theTransitionPtr = GetInitialTransitionPtr(m_Parent); - QT3DS_ASSERT(theTransitionPtr); - if (theTransitionPtr) { - m_InitialTransition = *theTransitionPtr; - theTransitionPtr[0] = NULL; - bool firstChild = IsFirstChild(c, p); - if (!firstChild) { - TObjPtr editorObj = editor.Create("transition", ""); - TObjList targets; - targets.push_back(editor.ToEditor(c)); - editorObj->SetPropertyValue("target", targets); - SStateNode *stateNode = editor.StateNodeFromEditor(editorObj); - m_FinalTransition = static_cast(stateNode); - m_FinalTransition->m_Parent = &p; - *theTransitionPtr = m_FinalTransition; - } - } - } - virtual void addRef() { ++m_RefCount; } - virtual void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - virtual TObjPtr GetEditor() { return m_EditorObj; } - - template - void Apply(STransition *trans, TNodeType &node) - { - node.m_Initial = trans; - } - - virtual void Do() - { - if (m_Parent.m_Type == StateNodeTypes::SCXML) - Apply(m_FinalTransition, static_cast(m_Parent)); - else if (m_Parent.m_Type == StateNodeTypes::State) - Apply(m_FinalTransition, static_cast(m_Parent)); - } - - virtual void Undo() - { - if (m_Parent.m_Type == StateNodeTypes::SCXML) - Apply(m_InitialTransition, static_cast(m_Parent)); - else if (m_Parent.m_Type == StateNodeTypes::State) - Apply(m_InitialTransition, static_cast(m_Parent)); - } - }; - - void SEditorImpl::SetInitialTarget(const Option &inData, SStateNode &inNode) - { - if (inNode.m_Type == StateNodeTypes::Transition - /**|| inNode.m_Type == StateNodeTypes::History **/) { - QT3DS_ASSERT(false); - } - SStateNode *theParent = inNode.m_Parent; - if (theParent) { - STransition **theParentTransPtr = GetInitialTransitionPtr(*theParent); - - if (theParentTransPtr) { - bool newValue = false; - if (inData.hasValue()) - newValue = inData->getData(); - - NVScopedRefCounted theChange = - new SInitialTargetChange(ToEditor(*theParent), *theParent, inNode, *this); - theChange->Do(); - STransaction *theTransaction = GetOpenTransactionImpl(); - if (theTransaction) { - theTransaction->m_Changes.push_back(theChange.mPtr); - TStateNodeList *children = theParent->GetChildren(); - for (TStateNodeList::iterator iter = children->begin(), - end = children->end(); - iter != end; ++iter) { - theTransaction->m_Changes.push_back(new SChange(*ToEditor(*iter))); - } - } - } - } - } - - SValue SEditorImpl::IsInitialTarget(SStateNode &inNode) - { - if (inNode.m_Type == StateNodeTypes::Transition - /** || inNode.m_Type == StateNodeTypes::History **/) - return SValue(false); - - SStateNode *theParent(inNode.m_Parent); - if (theParent) { - if (!isTrivial(theParent->GetInitialExpression())) - return false; - - STransition *theTransition = theParent->GetInitialTransition(); - if (theTransition) { - for (QT3DSU32 idx = 0, end = theTransition->m_Target.size(); idx < end; ++idx) - if (&inNode == theTransition->m_Target[idx]) - return SValue(true); - } else { - if (GetInitialTransitionPtr(*theParent)) - return SValue(IsFirstChild(inNode, *theParent)); - } - } - return SValue(false); - } - - TEditorStr SEditorImpl::GetDefaultInitialValue(SStateNode &inNode) - { - TStateNodeList *children = inNode.GetChildren(); - if (children == NULL) - return TEditorStr(); - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) { - if (iter->m_Type != StateNodeTypes::History - && iter->m_Type != StateNodeTypes::Transition) - return TEditorStr(iter->m_Id.c_str()); - } - - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) { - if (iter->m_Type != StateNodeTypes::Transition) - return TEditorStr(iter->m_Id.c_str()); - } - - return TEditorStr(); - } - - void SEditorImpl::GetLegalInitialValues(SStateNode &inNode, - eastl::vector &outValues) - { - TStateNodeList *children = inNode.GetChildren(); - if (children == NULL) - return; - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) { - if (/** iter->m_Type != StateNodeTypes::History && **/ iter->m_Type - != StateNodeTypes::Transition) - outValues.push_back(iter->m_Id); - } - } - - struct SInitialComboChange : public IChange - { - SStateNode &m_Node; - TObjPtr m_EditorObj; - const TEditorStr m_PreEditorComboValue; - const TEditorStr m_PostEditorComboValue; - const char8_t *m_PreInitialExpression; - const char8_t *m_PostInitialExpression; - STransition *m_PreComboTransition; - STransition *m_PostComboTransition; - QT3DSI32 m_RefCount; - SInitialComboChange(SStateNode &node, TObjPtr editObj, const char8_t *preExpr, - const char8_t *postExpr, STransition *preCombo, - STransition *postCombo, const TEditorStr &preEditorComboValue, - const TEditorStr &postEditorComboValue) - : m_Node(node) - , m_EditorObj(editObj) - , m_RefCount(0) - , m_PreInitialExpression(preExpr) - , m_PostInitialExpression(postExpr) - , m_PreComboTransition(preCombo) - , m_PostComboTransition(postCombo) - , m_PreEditorComboValue(preEditorComboValue) - , m_PostEditorComboValue(postEditorComboValue) - { - } - - virtual void addRef() { ++m_RefCount; } - virtual void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - virtual TObjPtr GetEditor() { return m_EditorObj; } - - template - void Apply(const char8_t *expr, STransition *trans, const TEditorStr &comboValue, - TNodeType &node, TEditorType &editor) - { - node.m_Initial = trans; - node.m_InitialExpr = expr; - editor.ApplyInitial(comboValue); - // editor.m_InitialComboValue = comboValue; - } - - virtual void Do() - { - if (m_Node.m_Type == StateNodeTypes::SCXML) - Apply(m_PostInitialExpression, m_PostComboTransition, m_PostEditorComboValue, - static_cast(m_Node), static_cast(*m_EditorObj)); - else if (m_Node.m_Type == StateNodeTypes::State) - Apply(m_PostInitialExpression, m_PostComboTransition, m_PostEditorComboValue, - static_cast(m_Node), static_cast(*m_EditorObj)); - } - - virtual void Undo() - { - if (m_Node.m_Type == StateNodeTypes::SCXML) - Apply(m_PreInitialExpression, m_PreComboTransition, m_PreEditorComboValue, - static_cast(m_Node), static_cast(*m_EditorObj)); - else if (m_Node.m_Type == StateNodeTypes::State) - Apply(m_PreInitialExpression, m_PreComboTransition, m_PreEditorComboValue, - static_cast(m_Node), static_cast(*m_EditorObj)); - } - }; - - void SEditorImpl::SetInitialAttribute(const Option &inData, SStateNode &inNode) - { - TObjPtr theEditor = ToEditor(inNode); - STransition **targetPtr = NULL; - const char8_t **exprPtr = NULL; - TEditorStr comboValue; - if (inNode.m_Type == StateNodeTypes::State) { - targetPtr = &static_cast(inNode).m_Initial; - exprPtr = &static_cast(inNode).m_InitialExpr; - comboValue = static_cast(*theEditor).m_InitialComboValue; - } else if (inNode.m_Type == StateNodeTypes::SCXML) { - targetPtr = &static_cast(inNode).m_Initial; - exprPtr = &static_cast(inNode).m_InitialExpr; - comboValue = static_cast(*theEditor).m_InitialComboValue; - } - - if (targetPtr == NULL) { - QT3DS_ASSERT(false); - return; - } - - STransition *initialTrans = *targetPtr; - const char8_t *initialExpr = *exprPtr; - TEditorStr initialComboValue = comboValue; - - if (inData.isEmpty()) { - *targetPtr = NULL; - comboValue = "(script expression)"; - } else { - TEditorStr stateId = inData->getData(); - SStateNode *theNode = - this->m_StateContext->FindStateNode(RegisterStr(stateId.c_str())); - if (theNode) { - *targetPtr = QT3DS_NEW(this->m_AutoAllocator, STransition)(); - SStateNode **newNode = - reinterpret_cast(this->m_AutoAllocator.allocate( - sizeof(SStateNode *), "TargetList", __FILE__, __LINE__)); - targetPtr[0]->m_Target = toDataRef(newNode, 1); - *const_cast(targetPtr[0]->m_Target.begin()) = theNode; - targetPtr[0]->m_Target.mSize = 1; - comboValue = stateId; - } else { - *targetPtr = NULL; - comboValue = ""; - } - *exprPtr = ""; - } - STransition *postTrans = *targetPtr; - const char8_t *postExpr = *exprPtr; - TEditorStr postComboValue = comboValue; - STransaction *theTransaction = GetOpenTransactionImpl(); - if (theTransaction) { - SInitialComboChange *theChange = new SInitialComboChange( - inNode, ToEditor(inNode), initialExpr, postExpr, initialTrans, postTrans, - initialComboValue, postComboValue); - theChange->Do(); - theTransaction->m_Changes.push_back(theChange); - TStateNodeList *children = inNode.GetChildren(); - if (children) { - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) { - theTransaction->m_Changes.push_back(new SChange(*ToEditor(*iter))); - } - } - } - } - - void SEditorImpl::Set(const Option &inData, SDataModel *&inTarget) - { - if (inData.hasValue()) { - TObjPtr thePtr = inData->getData(); - if (thePtr) - inTarget = FromEditor(thePtr); - else - inTarget = NULL; - } else - inTarget = NULL; - } - - SValue SEditorImpl::Get(SDataModel *inTarget) { return ToEditor(inTarget); } - - void SEditorImpl::Set(const Option &inData, TDataList &inTarget) - { - while (inTarget.empty() == false) - inTarget.remove(inTarget.front()); - if (inData.hasValue()) { - TObjList newData = inData->getData(); - for (TObjList::iterator iter = newData.begin(), end = newData.end(); iter != end; - ++iter) { - SData *entry = FromEditor(*iter); - if (entry) - inTarget.push_back(*entry); - } - } - } - - SValue SEditorImpl::Get(TDataList &inTarget) - { - TObjList retval; - for (TDataList::iterator iter = inTarget.begin(), end = inTarget.end(); iter != end; - ++iter) { - TObjPtr item = ToEditor(*iter); - if (item) - retval.push_back(item); - } - return retval; - } - - void SEditorImpl::Set(const Option &inData, NVConstDataRef &inTarget) - { - if (inTarget.size()) { - m_AutoAllocator.deallocate((void *)inTarget.mData); - inTarget.mData = NULL; - inTarget.mSize = 0; - } - if (inData.hasValue()) { - TVec2List newData(inData->getData()); - if (newData.size()) { - size_t newDataSize = newData.size() * sizeof(QT3DSVec2); - QT3DSVec2 *newTargetData = (QT3DSVec2 *)m_AutoAllocator.allocate( - newDataSize, "Transition::m_Path", __FILE__, __LINE__); - memCopy(newTargetData, newData.data(), newDataSize); - inTarget = toDataRef(newTargetData, newData.size()); - } - } - } - - SValue SEditorImpl::Get(const NVConstDataRef &inTarget) - { - TVec2List retval; - if (inTarget.mSize) - retval.insert(retval.end(), inTarget.begin(), inTarget.end()); - return retval; - } - - void SEditorImpl::Set(const Option &inData, SSend *&inTarget) - { - inTarget = NULL; - if (inData.hasValue() && inData->getType() == ValueTypes::ObjPtr) { - TObjPtr object = inData->getData(); - SSend *newPtr = FromEditor(object); - inTarget = newPtr; - } - } - - SValue SEditorImpl::Get(SSend *inTarget) - { - if (!inTarget) - return SValue(TObjPtr()); - return ToEditor(inTarget); - } - - TObjPtr SEditorImpl::CreateExecutableContent(SStateNode &inParent, - const char8_t *inTypeName) - { - SExecutableContent *newExecutable = NULL; - TObjPtr newObj; - if (AreEqual(inTypeName, SSendEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - GenerateUniqueId(*theNewEditor.first, "send"); - newExecutable = theNewEditor.first; - newObj = theNewEditor.second; - } else if (AreEqual(inTypeName, SScriptEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - newExecutable = theNewEditor.first; - newObj = theNewEditor.second; - } else if (AreEqual(inTypeName, SCancelEditor::GetTypeStr())) { - eastl::pair theNewEditor = CreateEditorAndObject(); - newExecutable = theNewEditor.first; - newObj = theNewEditor.second; - } else { - QT3DS_ASSERT(false); - return TObjPtr(); - } - if (newExecutable) - newExecutable->m_StateNodeParent = &inParent; - return newObj; - } - - SValue SEditorImpl::GetSendId(const char8_t *expression) - { - if (isTrivial(expression)) - return SValue((QT3DSU32)0); - return static_cast(IExecutionContext::ParseTimeStrToMilliseconds(expression)); - } - - void SEditorImpl::SetSendId(const Option &inData, const char8_t *&outExpression) - { - if (!isTrivial(outExpression)) - m_AutoAllocator.deallocate(const_cast(outExpression)); - - outExpression = ""; - - if (inData.hasValue() && inData->getType() == ValueTypes::U32) { - QT3DSU32 expr = inData->getData(); - char buffer[64]; - sprintf(buffer, "%u", expr); - int len = strlen(buffer); - if (len < 61) { - buffer[len] = 'm'; - buffer[len + 1] = 's'; - buffer[len + 2] = 0; - } - outExpression = ToGraphStr(buffer); - } - } - - IStateContext &SEditorImpl::GetStateContext() { return *m_StateContext; } - - void SEditorImpl::SetTransactionManager(STransactionManagerImpl &manager) - { - m_TransactionManager = &manager; - } - - bool IsLegalHistoryTarget(StateNodeTypes::Enum inType) - { - return inType == StateNodeTypes::State || inType == StateNodeTypes::Final - || inType == StateNodeTypes::Parallel; - } - - void RecurseGetChildrenForHistoryTarget(SState &inNode, - eastl::vector &retval) - { - for (TStateNodeList::iterator iter = inNode.m_Children.begin(), - end = inNode.m_Children.end(); - iter != end; ++iter) { - if (IsLegalHistoryTarget(iter->m_Type)) { - retval.push_back(iter->m_Id); - if (iter->m_Type == StateNodeTypes::State) - RecurseGetChildrenForHistoryTarget(static_cast(*iter), retval); - } - } - } - - eastl::vector SEditorImpl::GetLegalHistoryDefaultValues(SHistory &inData) - { - eastl::vector retval; - if (inData.m_Parent && inData.m_Parent->m_Type == StateNodeTypes::State) { - SState &theState = static_cast(*inData.m_Parent); - for (TStateNodeList::iterator iter = theState.m_Children.begin(), - end = theState.m_Children.end(); - iter != end; ++iter) { - if (IsLegalHistoryTarget(iter->m_Type)) { - retval.push_back(iter->m_Id); - if (inData.m_Flags.IsDeep()) { - if (iter->m_Type == StateNodeTypes::State) - RecurseGetChildrenForHistoryTarget(static_cast(*iter), - retval); - } - } - } - } - return retval; - } - - void RecurseGetLegalParents(eastl::vector &outResult, - SStateNode &inTarget, SStateNode &inCurrent) - { - // Basic checks - if (inCurrent.m_Type == StateNodeTypes::History - || inCurrent.m_Type == StateNodeTypes::Final || &inCurrent == &inTarget) - return; - - // Parallel's cannot have finals, but their children could - bool isIllegalChild = (inTarget.m_Type == StateNodeTypes::Final - && inCurrent.m_Type == StateNodeTypes::Parallel) - || inCurrent.m_Type == StateNodeTypes::SCXML; - - if (isIllegalChild == false) { - outResult.push_back(inCurrent.m_Id); - } - TStateNodeList *children = inCurrent.GetChildren(); - if (children) { - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) { - RecurseGetLegalParents(outResult, inTarget, *iter); - } - } - } - - static bool lexi(CRegisteredString lhs, CRegisteredString rhs) - { - return strcmp(lhs.c_str(), rhs.c_str()) < 0; - } - - eastl::vector SEditorImpl::GetLegalParentIds(SStateNode &inNode) - { - // Do a depth first search and just do not include this node or any history or final - // nodes. - eastl::vector retval; - RecurseGetLegalParents(retval, inNode, *m_StateContext->GetRoot()); - eastl::sort(retval.begin(), retval.end(), lexi); - return retval; - } - - struct SParentChange : public IChange - { - TObjPtr m_ChildObj; - TStateNodeList *m_OldList; - TStateNodeList &m_NewList; - SStateNode *m_OldParent; - SStateNode &m_NewParent; - SStateNode &m_Child; - QT3DSI32 m_RefCount; - SParentChange(TObjPtr childObj, TStateNodeList *oldL, TStateNodeList &newL, - SStateNode *oldp, SStateNode &newp, SStateNode &c) - : m_ChildObj(childObj) - , m_OldList(oldL) - , m_NewList(newL) - , m_OldParent(oldp) - , m_NewParent(newp) - , m_Child(c) - , m_RefCount(0) - { - } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - - virtual void Do() - { - if (m_OldList) - m_OldList->remove(m_Child); - m_NewList.push_back(m_Child); - m_Child.m_Parent = &m_NewParent; - } - virtual void Undo() - { - m_NewList.remove(m_Child); - if (m_OldList) - m_OldList->push_back(m_Child); - m_Child.m_Parent = m_OldParent; - } - - virtual TObjPtr GetEditor() { return m_ChildObj; } - }; - - void SEditorImpl::SetParent(SStateNode &inNode, const Option &inValue) - { - STransaction *theTransaction = m_TransactionManager->GetOpenTransactionImpl(); - SStateNode *oldParent = inNode.m_Parent; - TEditorStr newParentId; - if (inValue.hasValue()) - newParentId = inValue->getData(); - - SStateNode *newParent = - m_StateContext->FindStateNode(m_StringTable->RegisterStr(newParentId.c_str())); - if (newParent == NULL) - newParent = m_StateContext->GetRoot(); - TStateNodeList *newList = newParent->GetChildren(); - if (newList == NULL) { - QT3DS_ASSERT(false); - return; - } - SParentChange *theChange = - new SParentChange(ToEditor(inNode), oldParent ? oldParent->GetChildren() : NULL, - *newList, oldParent, *newParent, inNode); - theChange->Do(); - if (theTransaction) { - theTransaction->m_Changes.push_back(theChange); - if (oldParent) - theTransaction->m_Changes.push_back(new SChange(*ToEditor(*oldParent))); - theTransaction->m_Changes.push_back(new SChange(*ToEditor(*newParent))); - } - CheckAndSetValidHistoryDefault(ToEditor(inNode)); - // Fix the initial state of the old parent if it exists - if (oldParent) { - if (isTrivial(oldParent->GetInitialExpression()) - && oldParent->GetInitialTransition()) { - STransition *theTransition = oldParent->GetInitialTransition(); - if (theTransition != NULL && theTransition->m_Target.size()) { - bool foundItem = false; - for (QT3DSU32 idx = 0, end = theTransition->m_Target.size(); - idx < end && foundItem == false; ++idx) { - if (theTransition->m_Target[idx] == &inNode) - foundItem = true; - } - if (foundItem) { - SetInitialAttribute(SValue(TEditorStr()), *oldParent); - } - } - } - // fix all history nodes - TStateNodeList *parentChildren = oldParent->GetChildren(); - if (parentChildren) { - for (TStateNodeList::iterator iter = parentChildren->begin(), - end = parentChildren->end(); - iter != end; ++iter) { - if (iter->m_Type == StateNodeTypes::History) { - CheckAndSetValidHistoryDefault(ToEditor(*iter)); - } - } - } - } - // Set the new object inside the new parent. - ToEditor(inNode)->SetPropertyValue("position", QT3DSVec2(0, 0)); - } - - void SEditorImpl::CheckAndSetValidHistoryDefault(TObjPtr inHistoryNode) - { - if (inHistoryNode && AreEqual(inHistoryNode->TypeName(), "history")) { - eastl::vector validChildren = - inHistoryNode->GetLegalValues("default"); - TObjList existing = inHistoryNode->GetPropertyValue("default")->getData(); - if (existing.size()) { - // Ensure all of the existing nodes are in the valid children list. - bool allValid = true; - for (size_t existingIdx = 0, existingEnd = existing.size(); - existingIdx < existingEnd && allValid; ++existingIdx) { - CRegisteredString idStr = - m_StringTable->RegisterStr(existing[existingIdx]->GetId().c_str()); - if (eastl::find(validChildren.begin(), validChildren.end(), idStr) - == validChildren.end()) - allValid = false; - } - if (allValid) - return; - } - SetValidHistoryDefault(inHistoryNode); - } - } - - void SEditorImpl::SetValidHistoryDefault(TObjPtr inHistoryNode) - { - if (inHistoryNode && AreEqual(inHistoryNode->TypeName(), "history")) { - eastl::vector legalValues = - inHistoryNode->GetLegalValues("default"); - if (legalValues.size()) { - TObjPtr firstLegal = GetObjectById(legalValues[0]); - TObjList propValue; - propValue.push_back(firstLegal); - inHistoryNode->SetPropertyValue("default", propValue); - } - } - } - - MallocAllocator SBaseEditorFoundation::g_BaseAlloc; - - bool SPropertyDecNameFinder::operator()(const SPropertyDeclaration &dec) const - { - return AreEqual(m_NameStr, dec.m_Name.c_str()); - } - - void IEditorObject::Append(const char8_t *inPropName, TObjPtr inObj) - { - Option theProp = GetPropertyValue(inPropName); - if (theProp.hasValue() && theProp->getType() == ValueTypes::ObjPtrList - && inObj != NULL) { - TObjList theData = theProp->getData(); - theData.push_back(inObj); - SetPropertyValue(inPropName, theData); - } - } - - void IEditorObject::Remove(const char8_t *inPropName, TObjPtr inObj) - { - Option theProp = GetPropertyValue(inPropName); - if (theProp.hasValue() && theProp->getType() == ValueTypes::ObjPtrList - && inObj != NULL) { - TObjList theData = theProp->getData(); - TObjList::iterator theFind = eastl::find(theData.begin(), theData.end(), inObj); - if (theFind != theData.end()) - theData.erase(theFind); - SetPropertyValue(inPropName, theData); - } - } - - IEditor &IEditor::CreateEditor() - { - TFoundationPtr theFoundation = SBaseEditorFoundation::Create(); - return *QT3DS_NEW(theFoundation->getAllocator(), SEditorImpl)( - theFoundation, IStringTable::CreateStringTable(theFoundation->getAllocator())); - } - - IEditor *IEditor::CreateEditor(const char8_t *inFname) - { - CFileSeekableIOStream theFile(inFname, FileReadFlags()); - if (theFile.IsOpen() == false) - return NULL; - - return CreateEditor(inFname, theFile); - } - - IEditor *IEditor::CreateEditor(const char8_t *inFname, IInStream &inStream) - { - IEditor &theEditor(CreateEditor()); - if (static_cast(theEditor).Load(inStream, inFname)) - return &theEditor; - - theEditor.release(); - return NULL; - } - } -} -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.h deleted file mode 100644 index 31c83afe..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditor.h +++ /dev/null @@ -1,315 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_H -#define QT3DS_STATE_EDITOR_H -#pragma once -#include "Qt3DSState.h" -#include "Qt3DSStateSignalConnection.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/TaggedPointer.h" -#include "EASTL/vector.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec3.h" -#include "Qt3DSStateInterpreter.h" - -namespace qt3ds { -namespace state { - namespace editor { - - class IEditorObject; - typedef NVScopedRefCounted TObjPtr; - typedef eastl::vector TObjList; - - class IEditorChangeListener - { - protected: - virtual ~IEditorChangeListener() {} - public: - // The same object may be represented multiple times in this list. - virtual void OnDataChange(const TObjList &inChangedObjects, - const TObjList &inRemovedObjects) = 0; - }; - - struct EditorPropertyTypes - { - enum Enum { - NoProperty = 0, - Event, // string - Id, // string - Object, // IEditorObject - ObjectList, // IEditorObject list - // A string, but one from a set of strings. - StringSet, // string - String, // string, single line - BigString, // string than may be multiple lines long - Position, // vec2 - Dimension, // vec2 - PositionList, // vector - Script, // string - Color, - Boolean, - U32, - }; - }; - - struct SPropertyDeclaration - { - CRegisteredString m_Name; - EditorPropertyTypes::Enum m_Type; - // for enumerations, the list of enumerations - SPropertyDeclaration() {} - SPropertyDeclaration(CRegisteredString inName, EditorPropertyTypes::Enum inType) - : m_Name(inName) - , m_Type(inType) - { - } - }; - - typedef eastl::vector TPropertyDeclarationList; - - struct SPropertyDecNameFinder - { - const char8_t *m_NameStr; - SPropertyDecNameFinder(const char8_t *nmStr) - : m_NameStr(nmStr) - { - } - // Implemented in UICStateEditor.cpp to include "foundation/Utils.h" - bool operator()(const SPropertyDeclaration &dec) const; - }; - - typedef eastl::vector TVec2List; - typedef eastl::string TEditorStr; - typedef eastl::vector TEditorStrList; - - // Our generic discriminated union type for all property values. - struct SValue; - struct SValueOpt; - - class IEditor; - - class IEditorObject : public NVRefCounted - { - protected: - virtual ~IEditorObject() {} - const char8_t *m_TypeName; - - public: - IEditorObject(const char8_t *tn) - : m_TypeName(tn) - { - } - const char8_t *TypeName() const { return m_TypeName; } - // implemented in UICStateEditor.cpp using getpropertyvalue. - virtual TEditorStr GetId() = 0; - virtual TEditorStr GetDescription() = 0; - virtual void SetId(const TEditorStr &inId) = 0; - virtual void SetDescription(const TEditorStr &inName) = 0; - // Things only have one canonical parent. - virtual TObjPtr Parent() = 0; - - virtual void GetProperties(eastl::vector &outProperties) = 0; - virtual Option FindProperty(const char8_t *propName) = 0; - // The legal values for a property tend to be something that have to be calculated - // dynamically. - virtual eastl::vector GetLegalValues(const char8_t *propName) = 0; - - virtual Option GetPropertyValue(const char8_t *inPropName) = 0; - virtual void SetPropertyValue(const char8_t *inPropName, const SValueOpt &inValue) = 0; - virtual bool endEdit() { return false; } // should SetPropertyValue end property edit - - // Utility function implemented in UICStateEditor.cpp - virtual void Append(const char8_t *inPropName, TObjPtr inObj); - virtual void Remove(const char8_t *inPropName, TObjPtr inObj); - - // Remove this from any parents. Remove any transitions pointing to this. - // Only works for state-node derived types. - // Executable content, onEntry onExit and such will not work with this. - // Also removes this item id from the id map. This is what is used to delete objects. - // Do not reattach yourself; callers should release all references to this object after - // calling - // this. - virtual void RemoveObjectFromGraph() = 0; - - // Internal calls, don't call externally - virtual void RemoveIdFromContext() = 0; - virtual void AddIdToContext() = 0; - - // Most things do not have any executable content. - virtual NVConstDataRef GetExecutableContentTypes() - { - return NVConstDataRef(); - } - - // Be aware that there are more types of executable content than indicated in the store; - // a lot more. - // So just ignore the types the story ignores. - virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum /*inType*/) - { - return TObjList(); - } - - // inName can be an executable content: - //'script', 'send', 'cancel' - virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum /*inType*/, - const char8_t * /*inName*/) - { - return TObjPtr(); - } - - virtual IEditor &GetEditor() = 0; - }; - - class ITransaction : public NVRefCounted - { - protected: - virtual ~ITransaction() {} - TEditorStr m_Name; - - public: - ITransaction(const TEditorStr inName = TEditorStr()) - : m_Name(inName) - { - } - TEditorStr GetName() const { return m_Name; } - // Send the signals collected during the creation of this transaction - virtual void SendDoSignals() = 0; - virtual TObjList GetEditedObjects() = 0; - virtual void Do() = 0; - virtual void Undo() = 0; - virtual bool Empty() = 0; - }; - - typedef NVScopedRefCounted TTransactionPtr; - - class ITransactionManager : public NVRefCounted - { - protected: - virtual ~ITransactionManager() {} - public: - virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener) = 0; - // Undo/redo is supported via a transparent transaction system. - // calls are reentrant but last call will close the transaction object. - // Any changes to any editor objects will go through this transaction when they happen. - virtual TTransactionPtr BeginTransaction(const TEditorStr &inName = TEditorStr()) = 0; - virtual TTransactionPtr GetOpenTransaction() = 0; - virtual void RollbackTransaction() = 0; - virtual void EndTransaction() = 0; - }; - - // Editor interface to a UICState dataset - class IEditor : public ITransactionManager - { - protected: - virtual ~IEditor() {} - public: - // Traditional editor interface. - virtual TObjPtr GetRoot() = 0; - // You can force the id to be a particular ID in some cases, this is useful for testing. - // ID is ignored for objects that don't have an id. - virtual TObjPtr Create(const char8_t *inTypeName, const char8_t *inId = 0) = 0; - virtual TObjPtr GetOrCreate(SSCXML &inData) = 0; - virtual TObjPtr GetOrCreate(SState &inData) = 0; - virtual TObjPtr GetOrCreate(STransition &inData) = 0; - virtual TObjPtr GetOrCreate(SParallel &inData) = 0; - virtual TObjPtr GetOrCreate(SHistory &inData) = 0; - virtual TObjPtr GetOrCreate(SFinal &inData) = 0; - virtual TObjPtr GetOrCreate(SDataModel &inData) = 0; - virtual TObjPtr GetOrCreate(SData &inData) = 0; - virtual TObjPtr ToEditor(SStateNode &inItem) = 0; - - // Get a particular object by id. Useful in testing scenarios. - virtual TObjPtr GetObjectById(const char8_t *inId) = 0; - - // Get an editor, if it already has been created, for this piece of graph data. - // Note that if it has not been created, this function couldn't possibly create it - // due to lack of type information. - virtual TObjPtr GetEditor(void *inGraphData) = 0; - - // Copy save a subgraph to a string. Converts all top level positions to be relative to - // mouse pos. - virtual TEditorStr Copy(TObjList inObjects, const QT3DSVec2 &inMousePos) = 0; - virtual bool CanPaste(TObjPtr inTarget) = 0; - // Paste in, adding relative pos to all top level positions. - virtual void Paste(const TEditorStr &inCopiedObjects, TObjPtr inTarget, - const QT3DSVec2 &inRelativePos) = 0; - - virtual TObjPtr GetLeastCommonAncestor(NVConstDataRef inObjects) = 0; - - // Returns the list of send ids that have a delay on them. - virtual TObjList GetCancelableSendIds() = 0; - - // Return the set of events in use in the state machine. - virtual TEditorStrList GetStateMachineEvents() = 0; - - // Change content from one type to another. - virtual TObjPtr ChangeExecutableContentType(TObjPtr inContent, - const char8_t *newType) = 0; - - virtual TEditorStr ToXML(TObjPtr inContent) = 0; - // Returns the error from parsing the xml or if everything went correctly replaces - // inContent - // with the result of parsing the xml and returns the new content. - virtual eastl::pair FromXML(TObjPtr inContent, - const TEditorStr &ioEditedXML) = 0; - - virtual bool Save(const char8_t *inFname) = 0; - virtual void Save(IOutStream &inStream) = 0; - - // This must be called on history creation once it has been added to the proper parent. - virtual void SetValidHistoryDefault(TObjPtr inHistoryNode) = 0; - - static IEditor &CreateEditor(); - - static IEditor *CreateEditor(const char8_t *inFname); - static IEditor *CreateEditor(const char8_t *inFname, IInStream &inStream); - }; - - typedef NVScopedRefCounted TEditorPtr; - - struct SEditorImplTransactionScope - { - ITransactionManager &m_Editor; - TTransactionPtr m_Transaction; - SEditorImplTransactionScope(ITransactionManager &inEditor) - : m_Editor(inEditor) - , m_Transaction(inEditor.BeginTransaction()) - { - } - ~SEditorImplTransactionScope() { m_Editor.EndTransaction(); } - - TTransactionPtr operator->() { return m_Transaction; } - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorEditorsImpl.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorEditorsImpl.h deleted file mode 100644 index fc9411d2..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorEditorsImpl.h +++ /dev/null @@ -1,1772 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_EDITORS_IMPL_H -#define QT3DS_STATE_EDITOR_EDITORS_IMPL_H -#include "Qt3DSState.h" -#include "Qt3DSStateEditor.h" -#include "Qt3DSStateEditorValue.h" -#include "Qt3DSStateEditorTransactionImpl.h" -#include "Qt3DSStateTypes.h" -#include "Qt3DSStateEditorFoundation.h" -#include "Qt3DSStateEditorProperties.h" -#include "foundation/Utils.h" -#include "foundation/XML.h" -#include "Qt3DSStateXMLIO.h" -#include "foundation/IOStreams.h" -#include "Qt3DSStateExecutionTypes.h" -#include "Qt3DSStateContext.h" -#include "Qt3DSStateEditorImpl.h" - -namespace qt3ds { -namespace state { - namespace editor { - - struct EditorTypes - { - enum Enum { - UnknownEditor = 0, - SCXML, - State, - Parallel, - Transition, - History, - Final, - ExecutableContent, - OnEntry, - OnExit, - Send, - Raise, - If, - Else, - ElseIf, - Log, - Assign, - Script, - DataModel, - Data, - Cancel, - }; - }; - - struct SEditorImplObject : public IEditorObject - { - TFoundationPtr m_Foundation; - SEditorImpl &m_Editor; - volatile QT3DSI32 mRefCount; - eastl::string m_Id; - eastl::string m_Description; - Option m_Color; - TPropertyAccessorList m_PropertyAccessors; - - static void CreateAccessors(SEditorImpl &inData, TPropertyAccessorList &outAccessors, - bool includeId, bool includeColor) - { - if (includeId) - outAccessors.push_back(CreateEditorAccessor(inData, &SEditorImplObject::m_Id, - "id", EditorPropertyTypes::String)); - - outAccessors.push_back( - CreateEditorAccessor(inData, &SEditorImplObject::m_Description, "description", - EditorPropertyTypes::String)); - if (includeColor) - outAccessors.push_back(CreateEditorAccessor( - inData, &SEditorImplObject::m_Color, "color", EditorPropertyTypes::Color)); - } - - SEditorImplObject(const char8_t *tn, SEditorImpl &inData, - const TPropertyAccessorList &inAccessors) - : IEditorObject(tn) - , m_Foundation(inData.m_EditorFoundation) - , m_Editor(inData) - , mRefCount(0) - , m_PropertyAccessors(inAccessors) - { - } - - IPropertyAccessor *FindPropertyAccessor(const char8_t *inName) - { - CRegisteredString nameStr = m_Editor.m_StringTable->RegisterStr(inName); - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) - if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) - return m_PropertyAccessors[idx].mPtr; - return NULL; - } - - virtual void GetProperties(eastl::vector &outProperties) - { - outProperties.clear(); - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } - - virtual Option FindProperty(const char8_t *propName) - { - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { - if (AreEqual(m_PropertyAccessors[idx]->m_Declaration.m_Name.c_str(), propName)) - return m_PropertyAccessors[idx]->m_Declaration; - } - return Empty(); - } - - virtual eastl::vector GetLegalValues(const char8_t *propName) - { - IPropertyAccessor *accessor = FindPropertyAccessor(propName); - if (accessor) - return accessor->GetLegalValues(*this); - return eastl::vector(); - } - - virtual Option GetPropertyValue(const char8_t *inPropName) - { - IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); - if (accessor) { - return accessor->Get(*this); - } - return Empty(); - } - virtual void SetPropertyValue(const char8_t *inPropName, const SValueOpt &inValue) - { - IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); - if (accessor) { - if (accessor->HandlesTransaction() == false) { - STransaction *theTransaction = m_Editor.GetOpenTransactionImpl(); - if (theTransaction) { - Option existing = accessor->Get(*this); - theTransaction->m_Changes.push_back( - new SChange(existing, inValue, *accessor, *this)); - } - } - accessor->Set(*this, inValue); - } else { - QT3DS_ASSERT(false); - } - } - - virtual TEditorStr GetId() - { - Option propValue = GetPropertyValue("id"); - if (propValue.hasValue()) - return propValue->getData(); - return TEditorStr(); - } - virtual TEditorStr GetDescription() { return m_Description; } - // We have to go through the SPV interface to take transactions into account. - - virtual void SetId(const TEditorStr &inName) { SetPropertyValue("id", SValue(inName)); } - virtual void SetDescription(const TEditorStr &inName) - { - SetPropertyValue("description", SValue(inName)); - } - - virtual TObjPtr Parent() { return TObjPtr(); } - virtual void RemoveObjectFromGraph() { QT3DS_ASSERT(false); } - - virtual IEditor &GetEditor() { return m_Editor; } - }; - -#define QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE \ - void addRef() { atomicIncrement(&mRefCount); } \ - void release() \ - { \ - TFoundationPtr fnd(m_Foundation); \ - /*Ensure the editor sticks around till *after* we are gone. */ \ - /*This is because our objects will keep several bits of the editor around */ \ - QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Foundation->getAllocator()); \ - } - - struct SSCXMLEditor : public SEditorImplObject - { - typedef SSCXML TStateType; - enum { EditorType = EditorTypes::SCXML }; - - SSCXML &m_Data; - eastl::string m_InitialComboValue; - bool m_endEdit; - - static const char8_t *GetTypeStr() { return "scxml"; } - - static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - typedef SDataProp TInitialProp; - typedef SFlagBooleanProperty TBindingProp; - TPropertyAccessorList &retval(inList); - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - typedef SDataProp TNameProp; - typedef SInitialComboProp TInitialComboProp; - typedef SDataProp TCharProp; - IPropertyAccessor *newAccessor = - QT3DS_NEW(alloc, TNameProp)(inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("name"), - EditorPropertyTypes::String), - &SSCXML::m_Name); - retval.push_back(newAccessor); - retval.push_back(CreateEditorAccessor(inEditorData, - &SEditorImplObject::m_Description, - "description", EditorPropertyTypes::String)); - newAccessor = QT3DS_NEW(alloc, TBindingProp)( - inEditorData.m_EditorFoundation, *inEditorData.m_StringTable, "binding", - "early", "late", &SSCXMLFlags::IsLateBinding, &SSCXMLFlags::SetLateBinding); - retval.push_back(newAccessor); - - TInitialComboProp *theInitialCombo = QT3DS_NEW(alloc, TInitialComboProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("initial"), - EditorPropertyTypes::StringSet)); - retval.push_back(theInitialCombo); - - TCharProp *theInitialExprProp = QT3DS_NEW(alloc, TCharProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("initialexpr"), - EditorPropertyTypes::BigString), - &SSCXML::m_InitialExpr); - retval.push_back(theInitialExprProp); - - retval.push_back(CreateDataAccessor( - inEditorData, &SSCXML::m_DataModel, "datamodel", EditorPropertyTypes::Object)); - newAccessor = QT3DS_NEW(alloc, SChildrenProperty)( - inEditorData.m_EditorFoundation, *inEditorData.m_StringTable); - retval.push_back(newAccessor); - // Replace the name property with one that writes to our data - return retval; - } - - SSCXMLEditor(SSCXML &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SEditorImplObject(GetTypeStr(), inEditorData, - CreateAccessors(inEditorData, inList)) - , m_Data(inData) - , m_endEdit(false) - { - } - - void ApplyInitial(const TEditorStr &comboValue) - { - m_endEdit = false; - - if (m_InitialComboValue == "(script expression)" - || comboValue == "(script expression)") - m_endEdit = true; - - m_InitialComboValue = comboValue; - } - - virtual bool endEdit() - { - bool bTemp = m_endEdit; - m_endEdit = false; - return bTemp; - } - - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual void RemoveObjectFromGraph() { QT3DS_ASSERT(false); } - - virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } - - virtual void AddIdToContext() - { - if (m_Data.m_Id.IsValid()) - m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); - } - - virtual void GetProperties(eastl::vector &outProperties) - { - outProperties.clear(); - eastl::vector temp; - m_Editor.GetLegalInitialValues(m_Data, temp); - bool hasInitialState = temp.size() > 1; - bool hasInitialExpr = false; - CRegisteredString nameStr = m_Editor.RegisterStr("initial"); - CRegisteredString initialExprStr = m_Editor.RegisterStr("initialexpr"); - - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { - if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { - if (hasInitialState) - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } else if (m_PropertyAccessors[idx]->m_Declaration.m_Name == initialExprStr) { - if (hasInitialExpr) - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } else { - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } - - if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { - TEditorStr initialValue = - m_PropertyAccessors[idx]->Get(*this)->getData(); - if (initialValue == "(script expression)") - hasInitialExpr = true; - } - } - } - }; - - struct SPositionalEditor : public SEditorImplObject - { - SPositionalEditor(const char8_t *inTypeName, SEditorImpl &inData, - const TPropertyAccessorList &inAccessors) - : SEditorImplObject(inTypeName, inData, inAccessors) - { - } - }; - - template - struct TListInsertDeleteChange : public IChange - { - TObjPtr m_EditorObject; - QT3DSI32 mRefCount; - TListType *m_ParentList; - TListItem *m_TargetContent; - QT3DSI32 m_ContentIdx; - bool m_AddOnDo; - // The item must be in the list for this to work. - TListInsertDeleteChange(TObjPtr inEditor, TListType *plist, TListItem *tc, bool addOnDo) - : m_EditorObject(inEditor) - , mRefCount(0) - , m_ParentList(plist) - , m_TargetContent(tc) - , m_ContentIdx(-1) - , m_AddOnDo(addOnDo) - { - for (typename TListType::iterator iter = m_ParentList->begin(), - end = m_ParentList->end(); - iter != end; ++iter) { - if (&(*iter) == m_TargetContent) - break; - // setup content idx to point to the item just our target item. - ++m_ContentIdx; - } - } - virtual void addRef() { atomicIncrement(&mRefCount); } - virtual void release() - { - atomicDecrement(&mRefCount); - if (mRefCount <= 0) { - delete this; - } - } - void add() - { - if (m_ContentIdx > -1) { - QT3DSI32 idx = m_ContentIdx - 1; - typename TListType::iterator iter = m_ParentList->begin(); - - for (typename TListType::iterator end = m_ParentList->end(); - iter != end && idx > -1; ++iter, --idx) { - }; - - if (iter != m_ParentList->end()) - m_ParentList->insert_after(*iter, *m_TargetContent); - else - m_ParentList->push_back(*m_TargetContent); - } else - m_ParentList->push_front(*m_TargetContent); - } - void remove() { m_ParentList->remove(*m_TargetContent); } - - virtual void Do() - { - if (m_AddOnDo) - add(); - else - remove(); - } - virtual void Undo() - { - if (m_AddOnDo) - remove(); - else - add(); - } - virtual TObjPtr GetEditor() { return m_EditorObject; } - }; - - struct SExecutableContentChange - : public TListInsertDeleteChange - { - typedef TListInsertDeleteChange TBase; - SExecutableContentChange(TObjPtr inEditor, TExecutableContentList *plist, - SExecutableContent *tc, bool addOnDo) - : TBase(inEditor, plist, tc, addOnDo) - { - } - }; - - struct SStateEditor : public SPositionalEditor - { - typedef SState TStateType; - enum { EditorType = EditorTypes::State }; - SState &m_Data; - eastl::string m_InitialComboValue; - bool m_endEdit; - static const char8_t *GetTypeStr() { return "state"; } - - template - static void CreateStateNodeChildren(SEditorImpl &inEditorData, - TPropertyAccessorList &retval) - { - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - IPropertyAccessor *newAccessor = QT3DS_NEW(alloc, SChildrenProperty)( - inEditorData.m_EditorFoundation, *inEditorData.m_StringTable); - retval.push_back(newAccessor); - } - - template - static void CreatePositionColorAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &retval) - { - typedef SOptionAccessorProp TVec2Access; - typedef SOptionAccessorProp TVec3Access; - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - retval.push_back(QT3DS_NEW(alloc, TVec2Access)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("position"), - EditorPropertyTypes::Position), - &SStateNode::GetPosition, &SStateNode::SetPosition)); - retval.push_back(QT3DS_NEW(alloc, TVec2Access)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("dimension"), - EditorPropertyTypes::Position), - &SStateNode::GetDimension, &SStateNode::SetDimension)); - - retval.push_back(QT3DS_NEW(alloc, TVec3Access)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("color"), - EditorPropertyTypes::Color), - &SStateNode::GetColor, &SStateNode::SetColor)); - } - - static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - typedef SDataProp TInitialProp; - typedef SDataIdProp TIdPropType; - typedef SInitialTargetProp TInitialTargetProp; - typedef SInitialComboProp TInitialComboProp; - typedef SDataProp TCharProp; - - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - - TPropertyAccessorList &retval(inList); - retval.push_back(QT3DS_NEW(alloc, TIdPropType)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), - &SState::m_Id)); - - typedef SParentProp TParentPropType; - retval.push_back(QT3DS_NEW(alloc, TParentPropType)(inEditorData.m_EditorFoundation, - *inEditorData.m_StringTable)); - SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); - - TInitialComboProp *theInitialCombo = QT3DS_NEW(alloc, TInitialComboProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("initial"), - EditorPropertyTypes::StringSet)); - retval.push_back(theInitialCombo); - - TCharProp *theInitialExprProp = QT3DS_NEW(alloc, TCharProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("initialexpr"), - EditorPropertyTypes::BigString), - &SState::m_InitialExpr); - retval.push_back(theInitialExprProp); - retval.push_back(CreateDataAccessor( - inEditorData, &SState::m_DataModel, "datamodel", EditorPropertyTypes::Object)); - CreateStateNodeChildren(inEditorData, retval); - CreatePositionColorAccessors(inEditorData, retval); - retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), - EditorPropertyTypes::Boolean))); - // Replace the name property with one that writes to our data - return retval; - } - SStateEditor(SState &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SPositionalEditor(GetTypeStr(), inEditorData, - CreateAccessors(inEditorData, inList)) - , m_Data(inData) - , m_endEdit(false) - { - } - - virtual void GetProperties(eastl::vector &outProperties) - { - outProperties.clear(); - eastl::vector temp; - m_Editor.GetLegalInitialValues(m_Data, temp); - bool hasInitialState = temp.size() > 1; - bool hasInitialExpr = false; - CRegisteredString nameStr = m_Editor.RegisterStr("initial"); - CRegisteredString initialExprStr = m_Editor.RegisterStr("initialexpr"); - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { - if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { - if (hasInitialState) - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } else if (m_PropertyAccessors[idx]->m_Declaration.m_Name == initialExprStr) { - if (hasInitialExpr) - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } else - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - - if (hasInitialState - && m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { - TEditorStr initialValue = - m_PropertyAccessors[idx]->Get(*this)->getData(); - if (initialValue == "(script expression)") - hasInitialExpr = true; - } - } - } - - void ApplyInitial(const TEditorStr &comboValue) - { - m_endEdit = false; - - if (m_InitialComboValue == "(script expression)" - || comboValue == "(script expression)") - m_endEdit = true; - - m_InitialComboValue = comboValue; - } - - virtual bool endEdit() - { - bool bTemp = m_endEdit; - m_endEdit = false; - return bTemp; - } - - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } - virtual void AddIdToContext() - { - if (m_Data.m_Id.IsValid()) - m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - struct SObjListContains - { - const TObjList &m_Targets; - SObjListContains(const TObjList &t) - : m_Targets(t) - { - } - bool operator()(const TObjPtr &inObj) const - { - return eastl::find(m_Targets.begin(), m_Targets.end(), inObj.mPtr) - != m_Targets.end(); - } - }; - - static void CheckAndRemoveStateFromTransitionProperty(TObjList &removedItems, - IEditorObject &inEditorObj, - const char8_t *propName) - { - Option propVal = inEditorObj.GetPropertyValue(propName); - if (propVal.hasValue()) { - if (propVal->getType() == ValueTypes::ObjPtr) { - TObjPtr transProp = propVal->getData(); - if (transProp) { - TObjList propValValues = - transProp->GetPropertyValue("target")->getData(); - TObjList::iterator lastIter = - eastl::remove_if(propValValues.begin(), propValValues.end(), - SObjListContains(removedItems)); - if (lastIter != propValValues.end()) { - propValValues.erase(lastIter, propValValues.end()); - if (propValValues.empty()) - inEditorObj.SetPropertyValue(propName, TObjPtr()); - else - transProp->SetPropertyValue("target", propValValues); - } - } - } else if (propVal->getType() == ValueTypes::String) { - TEditorStr theIdStr = propVal->getData(); - for (size_t idx = 0, end = removedItems.size(); idx < end; ++idx) { - if (removedItems[idx]->GetId() == theIdStr) { - inEditorObj.SetPropertyValue(propName, TEditorStr()); - break; - } - } - } - } - } - - static void RemoveTransitionsPointingTo(TObjList &removedItems, - IEditorObject &inEditorObj) - { - if (AreEqual(inEditorObj.TypeName(), "transition")) { - TObjList targets = inEditorObj.GetPropertyValue("target")->getData(); - TObjList::iterator lastIter = eastl::remove_if(targets.begin(), targets.end(), - SObjListContains(removedItems)); - if (lastIter != targets.end()) { - targets.erase(lastIter, targets.end()); - inEditorObj.SetPropertyValue("target", targets); - if (targets.size() == 0) - inEditorObj.RemoveObjectFromGraph(); - } - } else { - // state and parallel - CheckAndRemoveStateFromTransitionProperty(removedItems, inEditorObj, "initial"); - // history - CheckAndRemoveStateFromTransitionProperty(removedItems, inEditorObj, - "transition"); - } - Option childListOpt = inEditorObj.GetPropertyValue("children"); - if (childListOpt.hasValue()) { - TObjList childList = childListOpt->getData(); - for (size_t idx = 0, end = childList.size(); idx < end; ++idx) - RemoveTransitionsPointingTo(removedItems, *childList[idx]); - } - } - static void RemoveObjectFromGraph(IEditorObject &inEditorObj, - TObjList &outRemovedObjects) - { - TObjPtr parentPtr = inEditorObj.Parent(); - outRemovedObjects.push_back(&inEditorObj); - if (parentPtr) - parentPtr->Remove("children", &inEditorObj); - - Option nodeChildrenOpt = inEditorObj.GetPropertyValue("children"); - if (nodeChildrenOpt.hasValue()) { - TObjList nodeChildren(nodeChildrenOpt->getData()); - for (size_t idx = 0, end = nodeChildren.size(); idx < end; ++idx) - RemoveObjectFromGraph(*nodeChildren[idx], outRemovedObjects); - } - } - - virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } - - // Simple and slow as hell. - static void RemoveObjectFromGraph(SEditorImplObject &inEditorObj) - { - TObjList removedItems; - TObjPtr oldParent = inEditorObj.Parent(); - RemoveObjectFromGraph(inEditorObj, removedItems); - RemoveTransitionsPointingTo(removedItems, *inEditorObj.m_Editor.GetRoot()); - for (size_t idx = 0, end = removedItems.size(); idx < end; ++idx) { - inEditorObj.m_Editor.m_TransactionManager->OnObjectDeleted(removedItems[idx]); - inEditorObj.RemoveIdFromContext(); - } - if (oldParent) { - TObjList children = - oldParent->GetPropertyValue("children")->getData(); - for (size_t childIdx = 0, childEnd = children.size(); childIdx < childEnd; - ++childIdx) { - inEditorObj.m_Editor.CheckAndSetValidHistoryDefault(children[childIdx]); - } - } - } - - virtual void RemoveObjectFromGraph() { RemoveObjectFromGraph(*this); } - - virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } - - virtual NVConstDataRef GetExecutableContentTypes() - { - static InterpreterEventTypes::Enum retval[] = { InterpreterEventTypes::StateEnter, - InterpreterEventTypes::StateExit }; - return toConstDataRef(retval, 2); - } - - template - static TObjList ListDataToEditor(TListType &inList, SEditorImplObject &ioObj) - { - TObjList retval; - typename TListType::iterator iter = inList.begin(); - // Take the first one. - if (iter != inList.end()) { - for (TExecutableContentList::iterator - contentIter = iter->m_ExecutableContent.begin(), - contentEnd = iter->m_ExecutableContent.end(); - contentIter != contentEnd; ++contentIter) { - TObjPtr editorData = ioObj.m_Editor.ExecutableContentToEditor(*contentIter); - retval.push_back(editorData); - } - } - return retval; - } - - static TObjList ListDataToEditor(InterpreterEventTypes::Enum inType, - SEntryExitBase &inItem, SEditorImplObject &ioObj) - { - switch (inType) { - case InterpreterEventTypes::StateEnter: - return ListDataToEditor(inItem.m_OnEntry, ioObj); - case InterpreterEventTypes::StateExit: - return ListDataToEditor(inItem.m_OnExit, ioObj); - default: - break; - } - QT3DS_ASSERT(false); - return TObjList(); - } - - virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) - { - return SStateEditor::ListDataToEditor(inType, m_Data, *this); - } - - template - static TObjPtr DoCreateAppendExecutableContent(SEditorImplObject &inObj, - TListType &inList, const char8_t *inName, - SStateNode &inNode) - { - NVScopedRefCounted theNewListItemChange; - if (inList.empty()) { - TListItemType *newType = - QT3DS_NEW(inObj.m_Editor.m_AutoAllocator, TListItemType)(); - inList.push_back(*newType); - theNewListItemChange = new TListInsertDeleteChange( - inObj, &inList, newType, true); - } - TListItemType &theFront = *inList.begin(); - TObjPtr retval = inObj.m_Editor.CreateExecutableContent(inNode, inName); - SExecutableContent *theContent = inObj.m_Editor.ExecutableContentFromEditor(retval); - theFront.m_ExecutableContent.push_back(*theContent); - if (inObj.m_Editor.GetOpenTransactionImpl()) { - if (theNewListItemChange) - inObj.m_Editor.GetOpenTransactionImpl()->m_Changes.push_back( - theNewListItemChange); - - NVScopedRefCounted newChange = - new SExecutableContentChange(inObj, &theFront.m_ExecutableContent, - theContent, true); - inObj.m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(newChange.mPtr); - } - return retval; - } - - static TObjPtr DoCreateAppendExecutableContent(InterpreterEventTypes::Enum inType, - const char8_t *inName, - SEditorImplObject &inObj, - SEntryExitBase &inItem) - { - switch (inType) { - case InterpreterEventTypes::StateEnter: - return DoCreateAppendExecutableContent(inObj, inItem.m_OnEntry, - inName, inItem); - case InterpreterEventTypes::StateExit: - return DoCreateAppendExecutableContent(inObj, inItem.m_OnExit, inName, - inItem); - default: - break; - } - - QT3DS_ASSERT(false); - return TObjPtr(); - } - - virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, - const char8_t *inName) - { - return SStateEditor::DoCreateAppendExecutableContent(inType, inName, *this, m_Data); - } - }; - - struct SParallelEditor : public SPositionalEditor - { - typedef SParallel TStateType; - enum { EditorType = EditorTypes::Parallel }; - SParallel &m_Data; - static const char8_t *GetTypeStr() { return "parallel"; } - - static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - - typedef SInitialTargetProp TInitialTargetProp; - TPropertyAccessorList &retval(inList); - typedef SDataIdProp TIdPropType; - typedef SParentProp TParallelParentProp; - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - retval.push_back(QT3DS_NEW(alloc, TIdPropType)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), - &SParallel::m_Id)); - - retval.push_back(QT3DS_NEW(alloc, TParallelParentProp)(inEditorData.m_EditorFoundation, - *inEditorData.m_StringTable)); - - SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); - retval.push_back(CreateDataAccessor( - inEditorData, &SState::m_DataModel, "datamodel", EditorPropertyTypes::Object)); - SStateEditor::CreateStateNodeChildren(inEditorData, retval); - SStateEditor::CreatePositionColorAccessors(inEditorData, retval); - // Replace the name property with one that writes to our data - retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), - EditorPropertyTypes::Boolean))); - return retval; - } - - SParallelEditor(SParallel &inData, SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - : SPositionalEditor(GetTypeStr(), inEditorData, - CreateAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } - - virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } - - virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } - virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } - - virtual void AddIdToContext() - { - if (m_Data.m_Id.IsValid()) - m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); - } - - virtual NVConstDataRef GetExecutableContentTypes() - { - static InterpreterEventTypes::Enum retval[] = { InterpreterEventTypes::StateEnter, - InterpreterEventTypes::StateExit }; - return toConstDataRef(retval, 2); - } - - virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) - { - return SStateEditor::ListDataToEditor(inType, m_Data, *this); - } - - virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, - const char8_t *inName) - { - return SStateEditor::DoCreateAppendExecutableContent(inType, inName, *this, m_Data); - } - }; - - struct SFinalEditor : public SPositionalEditor - { - typedef SFinal TStateType; - enum { EditorType = EditorTypes::Final }; - - SFinal &m_Data; - static const char8_t *GetTypeStr() { return "final"; } - - static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - typedef SDataIdProp TIdPropType; - typedef SInitialTargetProp TInitialTargetProp; - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - typedef SParentProp TFinalParentProp; - retval.push_back(QT3DS_NEW(alloc, TIdPropType)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), - &SFinal::m_Id)); - retval.push_back(QT3DS_NEW(alloc, TFinalParentProp)(inEditorData.m_EditorFoundation, - *inEditorData.m_StringTable)); - SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); - SStateEditor::CreatePositionColorAccessors(inEditorData, retval); - retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), - EditorPropertyTypes::Boolean))); - // Replace the name property with one that writes to our data - return retval; - } - - SFinalEditor(SFinal &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SPositionalEditor(GetTypeStr(), inEditorData, - CreateAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } - - virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } - - virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } - virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } - - virtual void AddIdToContext() - { - if (m_Data.m_Id.IsValid()) - m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); - } - - virtual NVConstDataRef GetExecutableContentTypes() - { - static InterpreterEventTypes::Enum retval[] = { InterpreterEventTypes::StateEnter, - InterpreterEventTypes::StateExit }; - return toConstDataRef(retval, 2); - } - - virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) - { - return SStateEditor::ListDataToEditor(inType, m_Data, *this); - } - - virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, - const char8_t *inName) - { - return SStateEditor::DoCreateAppendExecutableContent(inType, inName, *this, m_Data); - } - }; - - struct SHistoryEditor : public SPositionalEditor - { - typedef SHistory TStateType; - enum { EditorType = EditorTypes::History }; - SHistory &m_Data; - static const char8_t *GetTypeStr() { return "history"; } - - static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - typedef SDataProp TTransitionProp; - - typedef SFlagBooleanProperty THistoryFlagsProp; - typedef SDataIdProp TIdPropType; - typedef SHistoryTransitionProp THistoryTransitionProp; - typedef SParentProp THistoryParentProp; - typedef SInitialTargetProp TInitialTargetProp; - - TPropertyAccessorList &retval(inList); - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - retval.push_back(QT3DS_NEW(alloc, TIdPropType)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), - &SHistory::m_Id)); - retval.push_back(QT3DS_NEW(alloc, THistoryParentProp)(inEditorData.m_EditorFoundation, - *inEditorData.m_StringTable)); - SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); - SStateEditor::CreatePositionColorAccessors(inEditorData, retval); - retval.push_back(QT3DS_NEW( - alloc, THistoryFlagsProp(inEditorData.m_EditorFoundation, - *inEditorData.m_StringTable, "type", "shallow", "deep", - &SHistoryFlags::IsDeep, &SHistoryFlags::SetDeep))); - - retval.push_back(QT3DS_NEW(alloc, TTransitionProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("transition"), - EditorPropertyTypes::ObjectList), - &SHistory::m_Transition)); - - retval.push_back(QT3DS_NEW(alloc, THistoryTransitionProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("default"), - EditorPropertyTypes::ObjectList))); - - retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), - EditorPropertyTypes::Boolean))); - - return retval; - } - - SHistoryEditor(SHistory &inData, SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - : SPositionalEditor(GetTypeStr(), inEditorData, - CreateAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } - - virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } - - virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } - virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } - - virtual void AddIdToContext() - { - if (m_Data.m_Id.IsValid()) - m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); - } - }; - - struct STransitionEditor : public SEditorImplObject - { - typedef STransition TStateType; - STransition &m_Data; - enum { EditorType = EditorTypes::Transition }; - static const char8_t *GetTypeStr() { return "transition"; } - TVec2List m_PathList; - - static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - typedef SDataProp TTransCharProp; - typedef SDataProp - TTransRegStrProp; - typedef SDataProp> - TTransTargetProp; - typedef SDataProp> - TTransPathProp; - typedef SFlagBooleanProperty - TTransitionFlagsProp; - typedef SDataIdProp TIdPropType; - typedef SOptionAccessorProp TVec2Access; - typedef SOptionAccessorProp TVec3Access; - typedef SDataIdProp TIdPropType; - - TPropertyAccessorList &retval(inList); - NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); - - retval.push_back( - QT3DS_NEW(alloc, TIdPropType)(inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("id"), - EditorPropertyTypes::String), - &STransition::m_Id)); - - retval.push_back(QT3DS_NEW(alloc, TTransRegStrProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("event"), - EditorPropertyTypes::String), - &STransition::m_Event)); - - SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); - IPropertyAccessor *accessor = QT3DS_NEW(alloc, TTransCharProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("cond"), - EditorPropertyTypes::BigString), - &STransition::m_Condition); - - retval.push_back(accessor); - accessor = QT3DS_NEW(alloc, TTransTargetProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("target"), - EditorPropertyTypes::ObjectList), - &STransition::m_Target); - retval.push_back(accessor); - retval.push_back(QT3DS_NEW(alloc, TTransitionFlagsProp)( - inEditorData.m_EditorFoundation, *inEditorData.m_StringTable, "type", - "external", "internal", &STransitionFlags::IsInternal, - &STransitionFlags::SetInternal)); - - accessor = QT3DS_NEW(alloc, TTransPathProp)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("path"), - EditorPropertyTypes::PositionList), - &STransition::m_Path); - retval.push_back(accessor); - retval.push_back(QT3DS_NEW(alloc, TVec2Access)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("position"), - EditorPropertyTypes::PositionList), - &STransition::GetPosition, &STransition::SetPosition)); - - retval.push_back(QT3DS_NEW(alloc, TVec2Access)( - inEditorData.m_EditorFoundation, - SPropertyDeclaration(inEditorData.RegisterStr("end position"), - EditorPropertyTypes::PositionList), - &STransition::GetEndPosition, &STransition::SetEndPosition)); - - return retval; - } - - STransitionEditor(STransition &inData, SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - : SEditorImplObject(GetTypeStr(), inEditorData, - CreateAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } - - virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } - virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } - - virtual void AddIdToContext() - { - if (m_Data.m_Id.IsValid()) - m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); - } - - virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } - - virtual NVConstDataRef GetExecutableContentTypes() - { - static InterpreterEventTypes::Enum data[] = { InterpreterEventTypes::Transition }; - return toConstDataRef(data, 1); - } - - virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) - { - TObjList retval; - if (inType == InterpreterEventTypes::Transition) { - for (TExecutableContentList::iterator iter = m_Data.m_ExecutableContent.begin(), - end = m_Data.m_ExecutableContent.end(); - iter != end; ++iter) { - retval.push_back(m_Editor.ExecutableContentToEditor(*iter)); - } - } - return retval; - } - virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, - const char8_t *inName) - { - TObjPtr retval; - if (inType == InterpreterEventTypes::Transition) { - retval = m_Editor.CreateExecutableContent(m_Data, inName); - SExecutableContent *theContent = m_Editor.ExecutableContentFromEditor(retval); - m_Data.m_ExecutableContent.push_back(*theContent); - if (m_Editor.GetOpenTransactionImpl()) { - NVScopedRefCounted newChange = - new SExecutableContentChange(*this, &m_Data.m_ExecutableContent, - theContent, true); - m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(newChange.mPtr); - } - } - return retval; - } - }; - - struct SExecutableContentParentInfo - { - SExecutableContent &content; - SEditorImpl &m_Editor; - TExecutableContentList *parentList; - TObjPtr editorObj; - TOnEntryList *entryList; - SOnEntry *entryItem; - TOnExitList *exitList; - SOnExit *exitItem; - SExecutableContentParentInfo(SExecutableContent &c, SEditorImpl &e) - : content(c) - , m_Editor(e) - , parentList(NULL) - , entryList(NULL) - , entryItem(NULL) - , exitList(NULL) - , exitItem(NULL) - { - if (GetContent().m_StateNodeParent) { - editorObj = m_Editor.ToEditor(*GetContent().m_StateNodeParent); - if (GetContent().m_StateNodeParent->m_Type == StateNodeTypes::Transition) - parentList = &static_cast(GetContent().m_StateNodeParent) - ->m_ExecutableContent; - else { - SExecutableContent *targetContent = &GetContent(); - entryList = GetContent().m_StateNodeParent->GetOnEntryList(); - exitList = GetContent().m_StateNodeParent->GetOnExitList(); - if (entryList) { - for (TOnEntryList::iterator iter = entryList->begin(), - end = entryList->end(); - iter != end && parentList == NULL; ++iter) { - for (TExecutableContentList::iterator - contentIter = iter->m_ExecutableContent.begin(), - contentEnd = iter->m_ExecutableContent.end(); - contentIter != contentEnd && parentList == NULL; - ++contentIter) { - if (&(*contentIter) == targetContent) { - parentList = &iter->m_ExecutableContent; - exitList = NULL; - entryItem = &(*iter); - } - } - } - } - if (parentList == NULL && exitList != NULL) { - for (TOnExitList::iterator iter = exitList->begin(), - end = exitList->end(); - iter != end && parentList == NULL; ++iter) { - for (TExecutableContentList::iterator - contentIter = iter->m_ExecutableContent.begin(), - contentEnd = iter->m_ExecutableContent.end(); - contentIter != contentEnd && parentList == NULL; - ++contentIter) { - if (&(*contentIter) == targetContent) { - parentList = &iter->m_ExecutableContent; - entryList = NULL; - exitItem = &(*iter); - } - } - } - } - } - } else { - editorObj = m_Editor.ToEditor(GetContent().m_Parent); - parentList = &GetContent().m_Parent->m_Children; - } - } - SExecutableContent &GetContent() { return content; } - }; - - struct SExecutableContentEditor : public SEditorImplObject - { - SExecutableContentEditor(const char8_t *inTypeStr, SEditorImpl &inEditorData, - const TPropertyAccessorList &inList) - : SEditorImplObject(inTypeStr, inEditorData, inList) - { - } - - virtual SExecutableContent &GetContent() = 0; - - virtual void RemoveObjectFromGraph() - { - SExecutableContentParentInfo parentInfo(GetContent(), m_Editor); - TExecutableContentList *parentList = parentInfo.parentList; - TObjPtr editorObj = parentInfo.editorObj; - TOnEntryList *entryList = parentInfo.entryList; - SOnEntry *entryItem = parentInfo.entryItem; - TOnExitList *exitList = parentInfo.exitList; - SOnExit *exitItem = parentInfo.exitItem; - - if (parentList) { - NVScopedRefCounted change = - new SExecutableContentChange(editorObj, parentList, &GetContent(), false); - change->Do(); - if (m_Editor.GetOpenTransactionImpl()) - m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(change.mPtr); - // Perhaps remove the item itself - if (parentList->empty()) { - NVScopedRefCounted newChange; - if (entryItem) - newChange = new TListInsertDeleteChange( - editorObj, entryList, entryItem, false); - else if (exitItem) - newChange = new TListInsertDeleteChange( - editorObj, exitList, exitItem, false); - - if (newChange) { - newChange->Do(); - if (m_Editor.GetOpenTransactionImpl()) - m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(newChange); - } - } - } - } - }; - - struct SSendEditor : public SExecutableContentEditor - { - typedef SSend TStateType; - enum { EditorType = EditorTypes::Send }; - SSend &m_Data; - static const char8_t *GetTypeStr() { return "send"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - typedef SDataIdProp TIdPropType; - - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor(inData, &SSend::m_Event, "event", - EditorPropertyTypes::String)); - NVFoundationBase &fnd = inData.m_EditorFoundation->getFoundation(); - - retval.push_back(QT3DS_NEW(fnd.getAllocator(), TIdPropType)( - inData.m_EditorFoundation, - SPropertyDeclaration(inData.RegisterStr("id"), EditorPropertyTypes::Id), - &SSend::m_Id)); - - retval.push_back(QT3DS_NEW(fnd.getAllocator(), SDelayProp)( - inData.m_EditorFoundation, - SPropertyDeclaration(inData.RegisterStr("delay"), EditorPropertyTypes::U32))); - return retval; - } - SSendEditor(SSend &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SRaiseEditor : public SExecutableContentEditor - { - typedef SRaise TStateType; - enum { EditorType = EditorTypes::Raise }; - SRaise &m_Data; - static const char8_t *GetTypeStr() { return "raise"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor(inData, &SRaise::m_Event, "event", - EditorPropertyTypes::String)); - return retval; - } - SRaiseEditor(SRaise &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SLogEditor : public SExecutableContentEditor - { - typedef SLog TStateType; - enum { EditorType = EditorTypes::Log }; - SLog &m_Data; - static const char8_t *GetTypeStr() { return "log"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor(inData, &SLog::m_Label, "label", - EditorPropertyTypes::String)); - retval.push_back(CreateDataAccessor(inData, &SLog::m_Expression, "expr", - EditorPropertyTypes::String)); - return retval; - } - SLogEditor(SLog &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SAssignEditor : public SExecutableContentEditor - { - typedef SAssign TStateType; - enum { EditorType = EditorTypes::Assign }; - SAssign &m_Data; - static const char8_t *GetTypeStr() { return "assign"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor( - inData, &SAssign::m_Location, "location", EditorPropertyTypes::String)); - retval.push_back(CreateDataAccessor( - inData, &SAssign::m_Expression, "expr", EditorPropertyTypes::String)); - return retval; - } - SAssignEditor(SAssign &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SIfEditor : public SExecutableContentEditor - { - typedef SIf TStateType; - enum { EditorType = EditorTypes::If }; - SIf &m_Data; - static const char8_t *GetTypeStr() { return "if"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor(inData, &SIf::m_Cond, "cond", - EditorPropertyTypes::String)); - return retval; - } - - SIfEditor(SIf &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SElseIfEditor : public SExecutableContentEditor - { - typedef SElseIf TStateType; - enum { EditorType = EditorTypes::ElseIf }; - SElseIf &m_Data; - static const char8_t *GetTypeStr() { return "elseif"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor(inData, &SElseIf::m_Cond, "cond", - EditorPropertyTypes::String)); - return retval; - } - - SElseIfEditor(SElseIf &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SElseEditor : public SExecutableContentEditor - { - typedef SElse TStateType; - enum { EditorType = EditorTypes::Else }; - SElse &m_Data; - static const char8_t *GetTypeStr() { return "else"; } - - SElseEditor(SElse &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, inList) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SScriptEditor : public SExecutableContentEditor - { - typedef SScript TStateType; - enum { EditorType = EditorTypes::Script }; - SScript &m_Data; - static const char8_t *GetTypeStr() { return "script"; } - - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor( - inData, &SScript::m_Data, "content", EditorPropertyTypes::BigString)); - return retval; - } - - SScriptEditor(SScript &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SCancelEditor : public SExecutableContentEditor - { - typedef SData TStateType; - enum { EditorType = EditorTypes::Cancel }; - SCancel &m_Data; - static const char8_t *GetTypeStr() { return "cancel"; } - - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList retval; - retval.push_back(CreateDataAccessor( - inData, &SCancel::m_Send, "sendid", EditorPropertyTypes::Object)); - retval.push_back(CreateDataAccessor( - inData, &SCancel::m_IdExpression, "sendidexpr", EditorPropertyTypes::String)); - return retval; - } - - SCancelEditor(SCancel &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SExecutableContentEditor(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual SExecutableContent &GetContent() { return m_Data; } - virtual void *GetWrappedObject() { return &m_Data; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SDataModelEditor : public SEditorImplObject - { - typedef SDataModel TStateType; - enum { EditorType = EditorTypes::DataModel }; - SDataModel &m_Data; - static const char8_t *GetTypeStr() { return "datamodel"; } - - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList &retval(inList); - retval.push_back(CreateDataAccessor( - inData, &SDataModel::m_Data, "data", EditorPropertyTypes::ObjectList)); - return retval; - } - - SDataModelEditor(SDataModel &inData, SEditorImpl &inEditorData, - TPropertyAccessorList &inList) - : SEditorImplObject(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SDataEditor : public SEditorImplObject - { - typedef SData TStateType; - enum { EditorType = EditorTypes::Data }; - SData &m_Data; - static const char8_t *GetTypeStr() { return "data"; } - static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, - TPropertyAccessorList &inList) - { - if (inList.size()) - return inList; - TPropertyAccessorList retval; - retval.push_back(CreateDataAccessor(inData, &SData::m_Id, "id", - EditorPropertyTypes::String)); - retval.push_back(CreateDataAccessor( - inData, &SData::m_Expression, "expr", EditorPropertyTypes::String)); - return retval; - } - - SDataEditor(SData &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) - : SEditorImplObject(GetTypeStr(), inEditorData, - GetPropertyAccessors(inEditorData, inList)) - , m_Data(inData) - { - } - - QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; - - virtual void *GetWrappedObject() { return &m_Data; } - - virtual CRegisteredString GetId() const { return m_Data.m_Id; } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - }; - - struct SNullEditor - { - int m_Data; - static const char8_t *GetTypeStr() { return ""; } - }; - - template - struct SStateEditorMap - { - typedef SNullEditor TEditorType; - template - static TObjPtr CreateEditor(TIgnored &, SEditorImpl &, TAccessorMap &) - { - return TObjPtr(); - } - }; - - template - struct SEditorImplStateMap - { - typedef int TStateType; - }; - - static inline TPropertyAccessorList &GetAccessorList(TAccessorMap &inMap, int inAccessor) - { - return inMap.insert(eastl::make_pair(inAccessor, TPropertyAccessorList())) - .first->second; - } - - template <> - struct SStateEditorMap - { - typedef STransition stateType; - typedef STransitionEditor TEditorType; - typedef STransitionEditor editorType; - static TObjPtr CreateEditor(stateType &inData, SEditorImpl &inEditorData, - TAccessorMap &inAccessors) - { - return QT3DS_NEW(inEditorData.m_EditorFoundation->getAllocator(), TEditorType)( - inData, inEditorData, - GetAccessorList(inAccessors, (int)editorType::EditorType)); - } - static TObjPtr CreateEditor(SEditorImpl &inEditorData, TAccessorMap &inAccessors) - { - STransition *newTransition = QT3DS_NEW(inEditorData.m_AutoAllocator, stateType)(); - newTransition->m_Flags.SetInternal(true); - return CreateEditor(*newTransition, inEditorData, inAccessors); - } - }; - template <> - struct SEditorImplStateMap - { - typedef STransition TStateType; - }; - -#define DEFINE_STATE_EDITOR_TYPE_MAP(stateType, editorType) \ - template <> \ - struct SStateEditorMap \ - { \ - typedef editorType TEditorType; \ - static TObjPtr CreateEditor(stateType &inData, SEditorImpl &inEditorData, \ - TAccessorMap &inAccessors) \ - { \ - return QT3DS_NEW(inEditorData.m_EditorFoundation->getAllocator(), TEditorType)( \ - inData, inEditorData, GetAccessorList(inAccessors, (int)editorType::EditorType)); \ - } \ - static TObjPtr CreateEditor(SEditorImpl &inEditorData, TAccessorMap &inAccessors) \ - { \ - return CreateEditor(*QT3DS_NEW(inEditorData.m_AutoAllocator, stateType)(), inEditorData, \ - inAccessors); \ - } \ - }; \ - template <> \ - struct SEditorImplStateMap \ - { \ - typedef stateType TStateType; \ - }; - - DEFINE_STATE_EDITOR_TYPE_MAP(SSCXML, SSCXMLEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SState, SStateEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SParallel, SParallelEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SHistory, SHistoryEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SFinal, SFinalEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SSend, SSendEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SRaise, SRaiseEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SLog, SLogEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SAssign, SAssignEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SIf, SIfEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SElseIf, SElseIfEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SElse, SElseEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SScript, SScriptEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SDataModel, SDataModelEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SData, SDataEditor); - DEFINE_STATE_EDITOR_TYPE_MAP(SCancel, SCancelEditor); - -#undef DEFINE_STATE_EDITOR_TYPE_MAP - } -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorFoundation.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorFoundation.h deleted file mode 100644 index edb55ee3..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorFoundation.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_FOUNDATION_H -#define QT3DS_STATE_EDITOR_FOUNDATION_H -#pragma once - -#include "Qt3DSState.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "foundation/TrackingAllocator.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/IOStreams.h" - -namespace qt3ds { -namespace state { - namespace editor { - - struct SBaseEditorFoundation - { - static MallocAllocator g_BaseAlloc; - QT3DSI32 mRefCount; - CAllocator m_BaseAllocator; - NVScopedRefCounted m_Foundation; - SBaseEditorFoundation() - : mRefCount(0) - , m_BaseAllocator() - , m_Foundation(NVCreateFoundation(QT3DS_FOUNDATION_VERSION, m_BaseAllocator)) - { - } - - ~SBaseEditorFoundation() {} - - NVFoundationBase &getFoundation() { return *m_Foundation; } - NVAllocatorCallback &getAllocator() { return m_Foundation->getAllocator(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_BaseAlloc); - - static SBaseEditorFoundation &Create() - { - SBaseEditorFoundation *fndPtr = - (SBaseEditorFoundation *)malloc(sizeof(SBaseEditorFoundation)); - new (fndPtr) SBaseEditorFoundation(); - return *fndPtr; - } - }; - - typedef NVScopedRefCounted TFoundationPtr; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorImpl.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorImpl.h deleted file mode 100644 index c1a691ee..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorImpl.h +++ /dev/null @@ -1,406 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_IMPL_H -#define QT3DS_STATE_EDITOR_IMPL_H -#include "Qt3DSStateEditor.h" -#include "Qt3DSStateEditorValue.h" -#include "Qt3DSStateTypes.h" -#include "Qt3DSStateEditorFoundation.h" -#include "foundation/Utils.h" -#include "foundation/XML.h" -#include "Qt3DSStateXMLIO.h" -#include "foundation/IOStreams.h" -#include "Qt3DSStateExecutionTypes.h" -#include "Qt3DSStateContext.h" - -namespace qt3ds { -namespace state { - namespace editor { - - struct SEditorImpl; - - typedef nvhash_map TStateEditorMap; - - class IPropertyAccessor : public NVRefCounted - { - protected: - virtual ~IPropertyAccessor() {} - public: - SPropertyDeclaration m_Declaration; - IPropertyAccessor(const SPropertyDeclaration &inDec) - : m_Declaration(inDec) - { - } - virtual eastl::vector GetLegalValues(IEditorObject & /*inObj*/) - { - return eastl::vector(); - } - - virtual Option Get(IEditorObject &inObj) = 0; - virtual void Set(IEditorObject &inObj, const Option &inValue) = 0; - // Return true if this access handles the transaction code itself. - // Currently only used for the is initial target property. - virtual bool HandlesTransaction() { return false; } - }; - - typedef NVScopedRefCounted TPropertyAccessorPtr; - typedef eastl::vector TPropertyAccessorList; - typedef nvhash_map TAccessorMap; - -#define QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(foundationPtr, refcountVar) \ - void addRef() { atomicIncrement(&(refcountVar)); } \ - void release() \ - { \ - TFoundationPtr temp(foundationPtr); \ - QT3DSI32 value = atomicDecrement(&(refcountVar)); \ - if (value <= 0) \ - NVDelete(foundationPtr->getAllocator(), this); \ - } - - struct SEditorImplStrIOStream : public IOutStream - { - TEditorStr m_Str; - bool Write(NVConstDataRef data) - { - if (data.size()) - m_Str.append((const char8_t *)data.begin(), (const char8_t *)data.end()); - return true; - } - }; - - struct SEditorImplStrInStream : public IInStream - { - const char8_t *m_Pos; - const char8_t *m_End; - SEditorImplStrInStream(const TEditorStr &inStr) - : m_Pos(inStr.data()) - , m_End(inStr.data() + inStr.size()) - { - } - - virtual QT3DSU32 Read(NVDataRef data) - { - QT3DSU32 amountLeft = (QT3DSU32)(m_End - m_Pos); - QT3DSU32 amountToRead = NVMin(amountLeft, data.size()); - memCopy(data.mData, m_Pos, amountToRead); - m_Pos += amountToRead; - return amountToRead; - } - }; - - struct STransaction; - - typedef eastl::vector TChangeListenerList; - struct STransactionManagerImpl; - - class IEditorCopyPasteListener - { - protected: - virtual ~IEditorCopyPasteListener() {} - - public: - virtual void OnCopy(TEditorPtr inEditor, eastl::vector &ioCopiedRoots, - IDOMWriter &ioWriter, - eastl::vector &ioNamespaces) = 0; - virtual void OnPaste(TEditorPtr inEditor, IDOMReader &ioReader, - CXMLIO::TIdRemapMap &inStateIdRemapMap) = 0; - virtual void OnIDChange(TEditorPtr inEditor, SStateNode &inNode, - const char8_t *inOldId) = 0; - }; - - // Forward declaration of the editor interface that the properties and the editor objects - // can all use. Implementation in UICStateEditor.cpp - struct SEditorImpl : public IEditor - { - // Note that *we* keep references to our editors - // but our editor objects *cannot* keep a reference to us. - // This means that our editor objects need to be able to function (not crash) if we - // ourselves go out of scope. - TFoundationPtr m_EditorFoundation; - NVScopedRefCounted m_StringTable; - SSAutoDeallocatorAllocator m_AutoAllocator; - NVScopedRefCounted m_StateContext; - TStateEditorMap m_Editors; - volatile QT3DSI32 mRefCount; - NVScopedRefCounted m_TransactionManager; - TAccessorMap m_Accessors; - IEditorCopyPasteListener *m_CopyPasteListener; - - SEditorImpl(TFoundationPtr inFoundation, - NVScopedRefCounted inStringTable); - void addRef(); - void release(); - - TObjPtr InsertEditor(void *inData, IEditorObject *inEditor); - - template - TObjPtr ToEditor(TStateType &inItem); - - template - TObjPtr ToEditor(TStateType *inItem); - TObjPtr ToEditor(SStateNode &inItem); - TObjPtr ExecutableContentToEditor(SExecutableContent &inItem); - - template - TStateType *FromEditor(TObjPtr inPtr); - - SStateNode *StateNodeFromEditor(TObjPtr inPtr); - - SExecutableContent *ExecutableContentFromEditor(TObjPtr inPtr); - void GenerateUniqueId(SStateNode &inNode, const char8_t *inStem); - void GenerateUniqueId(SSend &inNode, const char8_t *inStem); - - virtual TObjPtr GetRoot(); - - template - eastl::pair CreateEditorAndObject(); - - TObjPtr DoCreate(const char8_t *inTypeName, const char8_t *inId); - - virtual TObjPtr Create(const char8_t *inTypeName, const char8_t *inId); - - virtual TObjPtr GetOrCreate(SSCXML &inData); - virtual TObjPtr GetOrCreate(SState &inData); - virtual TObjPtr GetOrCreate(STransition &inData); - virtual TObjPtr GetOrCreate(SParallel &inData); - virtual TObjPtr GetOrCreate(SFinal &inData); - virtual TObjPtr GetOrCreate(SHistory &inData); - virtual TObjPtr GetOrCreate(SDataModel &inData); - virtual TObjPtr GetOrCreate(SData &inData); - - virtual TObjPtr GetObjectById(const char8_t *inId); - - virtual TObjPtr GetEditor(void *inGraphData); - - virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener); - - void RemoveChangeListener(IEditorChangeListener &inListener); - - virtual TTransactionPtr BeginTransaction(const TEditorStr &inName); - - virtual TTransactionPtr GetOpenTransaction(); - - STransaction *GetOpenTransactionImpl(); - - virtual void RollbackTransaction(); - - virtual void EndTransaction(); - - virtual TEditorStr Copy(TObjList inObjects, const QT3DSVec2 &inMousePos); - - virtual bool CanPaste(TObjPtr inTarget); - - void AddNewPasteObjectToTransaction(SStateNode &inNode); - - virtual void Paste(const TEditorStr &inCopiedObjects, TObjPtr inTarget, - const QT3DSVec2 &inMousePos); - - static bool IsDerivedFrom(SStateNode &child, SStateNode &parent); - - // This method should always return a value because the scxml root item - // is the parent of everyone else. - static SStateNode &GetLeastCommonAncestor(SStateNode &lhs, SStateNode &rhs); - - TObjPtr GetLeastCommonAncestor(NVConstDataRef inObjects); - - TObjList GetCancelableSendIds(); - - TObjPtr ChangeExecutableContentType(TObjPtr inContent, const char8_t *newType); - - TEditorStr ToXML(TObjPtr inContent); - - eastl::pair FromXML(TObjPtr inContent, - const TEditorStr &ioEditedXML); - - // Return the set of events in use in the state machine. - TEditorStrList GetStateMachineEvents(); - - void ReleaseEditor(void *inData); - - virtual bool Save(const char8_t *inFileName); - virtual void Save(IOutStream &inStream); - - bool Load(IInStream &inStream, const char8_t *inFilename); - - ///////////////////////////////////////////////////////////////////// - // Property access helpers - ///////////////////////////////////////////////////////////////////// - void SetIdProperty(SStateNode &inNode, const SValue &inData, - CRegisteredString &inTarget); - void SetIdProperty(SSend &inNode, const SValue &inData, CRegisteredString &inTarget); - - void Set(const SValue &inData, CRegisteredString &inTarget) - { - TEditorStr theStr(inData.getData()); - inTarget = m_StringTable->RegisterStr(theStr.c_str()); - } - - void Set(const SValue &inData, const char8_t *&inTarget) - { - TEditorStr theStr(inData.getData()); - const char8_t *theData(theStr.c_str()); - - if (inTarget && *inTarget != 0) - m_AutoAllocator.deallocate(const_cast(inTarget)); - - size_t len = StrLen(theData); - if (len == 0) - inTarget = NULL; - - ++len; // account for null terminate - - char8_t *newTarget = (char8_t *)m_AutoAllocator.allocate(len + 1, "graph string", - __FILE__, __LINE__); - memCopy(newTarget, theData, len); - inTarget = newTarget; - } - SValue Get(CRegisteredString &inTarget) { return inTarget.c_str(); } - SValue Get(const char8_t *inItem) { return nonNull(inItem); } - - void Set(const Option &inData, NVConstDataRef &inTarget); - SValue Get(NVConstDataRef &inTarget); - - void Set(const Option &inData, STransition *&inTarget); - Option Get(STransition *&inTarget); - - void SetInitial(const TObjList &inList, STransition *&outInitialTransition); - SValue GetInitial(STransition *inInitialTransition); - - void SetInitialTarget(const Option &inData, SStateNode &inNode); - SValue IsInitialTarget(SStateNode &inNode); - - void Set(const Option &inData, SDataModel *&inTarget); - SValue Get(SDataModel *inTarget); - - void Set(const Option &inData, TDataList &inTarget); - SValue Get(TDataList &inTarget); - - void Set(const Option &inData, NVConstDataRef &inTarget); - SValue Get(const NVConstDataRef &inTarget); - - void Set(const Option &inData, SSend *&inTarget); - SValue Get(SSend *inTarget); - - void Set(const Option &inData, TEditorStr &inTarget) - { - inTarget.clear(); - if (inData.hasValue()) - inTarget = inData->getData(); - } - - SValue Get(const TEditorStr &inTarget) { return inTarget; } - - void Set(const Option &inData, Option &inTarget) - { - if (inData.hasValue()) { - inTarget = inData->getData(); - } else { - inTarget = Empty(); - } - } - Option Get(const Option &inTarget) - { - Option retval; - if (inTarget.hasValue()) - retval = SValue(inTarget.getValue()); - return retval; - } - - void Set(const Option &inData, TVec2List &inTarget) - { - if (inData.hasValue()) { - inTarget = inData->getData(); - } else { - inTarget.clear(); - } - } - SValue Get(const TVec2List &inTarget) { return inTarget; } - - void Set(const Option &inData, Option &inTarget) - { - if (inData.hasValue()) { - inTarget = inData->getData(); - } else { - inTarget = Empty(); - } - } - const Option Get(const Option &inTarget) - { - Option retval; - if (inTarget.hasValue()) - retval = SValue(inTarget.getValue()); - return retval; - } - - const char8_t *ToGraphStr(const char8_t *inStr) - { - if (isTrivial(inStr)) - return ""; - QT3DSU32 len = StrLen(inStr) + 1; - char8_t *retval = - (char8_t *)m_AutoAllocator.allocate(len, "GraphStr", __FILE__, __LINE__); - memCopy(retval, inStr, len); - return retval; - } - - SValue GetSendId(const char8_t *expression); - void SetSendId(const Option &inData, const char8_t *&outExpression); - - TObjPtr CreateExecutableContent(SStateNode &inParent, const char8_t *inTypeName); - eastl::pair - CreateExecutableContent(const char8_t *inTypeName); - - CRegisteredString RegisterStr(const char8_t *str) - { - return m_StringTable->RegisterStr(str); - } - IStateContext &GetStateContext(); - - TEditorStr GetDefaultInitialValue(SStateNode &inNode); - void GetLegalInitialValues(SStateNode &inNode, - eastl::vector &outValues); - void SetInitialAttribute(const Option &inData, SStateNode &inNode); - - void SetTransactionManager(STransactionManagerImpl &trans); - - void ReplaceExecutableContent(SExecutableContent &oldContent, - SExecutableContent &newContent); - - eastl::vector GetLegalHistoryDefaultValues(SHistory &inData); - - eastl::vector GetLegalParentIds(SStateNode &inNode); - void SetParent(SStateNode &inNode, const Option &inValue); - void CheckAndSetValidHistoryDefault(TObjPtr inHistoryNode); - void SetValidHistoryDefault(TObjPtr inHistoryNode); - }; - } -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorProperties.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorProperties.h deleted file mode 100644 index 5f06fbdb..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorProperties.h +++ /dev/null @@ -1,599 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_PROPERTIES_H -#define QT3DS_STATE_EDITOR_PROPERTIES_H -#pragma once - -#include "Qt3DSStateEditorFoundation.h" -#include "Qt3DSStateEditorImpl.h" - -namespace qt3ds { -namespace state { - namespace editor { - - template - struct SPropertyAccessorBase : public IPropertyAccessor - { - TFoundationPtr m_Allocator; - volatile QT3DSI32 mRefCount; - - SPropertyAccessorBase(TFoundationPtr alloc, const SPropertyDeclaration &inDec) - : IPropertyAccessor(inDec) - , m_Allocator(alloc) - , mRefCount(0) - { - } - - virtual Option Get(IEditorObject &inObj) - { - return DoGet(static_cast(inObj)); - } - virtual void Set(IEditorObject &inObj, const Option &inValue) - { - DoSet(static_cast(inObj), inValue); - } - - virtual Option DoGet(TEditorType &inObj) = 0; - virtual void DoSet(TEditorType &inObj, const Option &inValue) = 0; - }; - - template - struct SInitialProperty : SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - static SPropertyDeclaration CreatePropertyDeclaration(IStringTable &inStrTable) - { - SPropertyDeclaration theDeclaration; - theDeclaration.m_Name = inStrTable.RegisterStr("initial"); - theDeclaration.m_Type = EditorPropertyTypes::Object; - return theDeclaration; - } - SInitialProperty(TFoundationPtr inAlloc, IStringTable &inStrTable) - : TBaseType(inAlloc, CreatePropertyDeclaration(inStrTable)) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - return SValue(inObj.Get(inObj.m_Data.m_Initial)); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.m_Initial = - inObj.template FromEditor(inValue->getData()); - } - }; - - template - struct SFlagBooleanProperty : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - typedef bool (TFlagsType::*TGetPropPtr)() const; - typedef void (TFlagsType::*TSetPropPtr)(bool); - - TGetPropPtr m_GetProp; - TSetPropPtr m_SetProp; - eastl::vector m_LegalValues; - virtual eastl::vector GetLegalValues(IEditorObject & /*inObj*/) - { - return m_LegalValues; - } - - static SPropertyDeclaration CreatePropertyDeclaration(IStringTable &inStrTable, - const char8_t *propName) - { - SPropertyDeclaration theDeclaration; - theDeclaration.m_Name = inStrTable.RegisterStr(propName); - theDeclaration.m_Type = EditorPropertyTypes::StringSet; - return theDeclaration; - } - SFlagBooleanProperty(TFoundationPtr inFnd, IStringTable &inStrTable, - const char8_t *inPropName, const char8_t *falseName, - const char8_t *trueName, TGetPropPtr inGetProp, - TSetPropPtr inSetProp) - : TBaseType(inFnd, CreatePropertyDeclaration(inStrTable, inPropName)) - , m_GetProp(inGetProp) - , m_SetProp(inSetProp) - { - m_LegalValues.push_back(inStrTable.RegisterStr(falseName)); - m_LegalValues.push_back(inStrTable.RegisterStr(trueName)); - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - bool boolVal = (inObj.m_Data.m_Flags.*m_GetProp)(); - TEditorStr retval = boolVal ? TEditorStr(m_LegalValues[1].c_str()) - : TEditorStr(m_LegalValues[0].c_str()); - return SValue(retval); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValueOpt) - { - if (inValueOpt.hasValue()) { - TEditorStr data = inValueOpt->getData(); - - if (AreEqual(data.c_str(), m_LegalValues[1].c_str())) - (inObj.m_Data.m_Flags.*m_SetProp)(true); - - else if (AreEqual(data.c_str(), m_LegalValues[0].c_str())) - (inObj.m_Data.m_Flags.*m_SetProp)(false); - - else { - QT3DS_ASSERT(false); - } - } - } - }; - - template - struct SChildrenProperty : SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - static SPropertyDeclaration CreatePropertyDeclaration(IStringTable &inStrTable) - { - SPropertyDeclaration theDeclaration; - theDeclaration.m_Name = inStrTable.RegisterStr("children"); - theDeclaration.m_Type = EditorPropertyTypes::ObjectList; - return theDeclaration; - } - - SChildrenProperty(TFoundationPtr inAlloc, IStringTable &inStrTable) - : TBaseType(inAlloc, CreatePropertyDeclaration(inStrTable)) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - TObjList retval; - for (TStateNodeList::iterator iter = inObj.m_Data.m_Children.begin(), - end = inObj.m_Data.m_Children.end(); - iter != end; ++iter) - retval.push_back(inObj.m_Editor.ToEditor(*iter)); - return SValue(retval); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - if (inValue.hasValue()) { - const TObjList &data = inValue->getData(); - TStateNodeList &theChildren(inObj.m_Data.m_Children); - // De-set all children. - while (theChildren.empty() == false) - inObj.m_Data.RemoveChild(theChildren.front()); - - for (TObjList::const_iterator iter = data.begin(), end = data.end(); - iter != end; ++iter) { - SStateNode *theNode = inObj.m_Editor.StateNodeFromEditor(*iter); - if (theNode) - inObj.m_Data.AppendChild(*theNode); - else { - QT3DS_ASSERT(false); - } - } - } - } - }; - - // Property that is represented by a data item's member. - template - struct SDataProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - typedef TDataType TStateType::*TPropertyPtr; - TPropertyPtr m_Ptr; - eastl::vector m_LegalValues; - - SDataProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, TPropertyPtr inPtr) - : TBaseType(inAlloc, inDec) - , m_Ptr(inPtr) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual eastl::vector GetLegalValues(IEditorObject & /*inObj*/) - { - return m_LegalValues; - } - - virtual Option DoGet(TEditorType &inObj) - { - return inObj.m_Editor.Get(inObj.m_Data.*(this->m_Ptr)); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.m_Editor.Set(inValue, inObj.m_Data.*(this->m_Ptr)); - } - }; - - template - struct SInitialTargetProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - - SInitialTargetProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) - : TBaseType(inAlloc, inDec) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - return inObj.m_Editor.IsInitialTarget(inObj.m_Data); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.m_Editor.SetInitialTarget(inValue, inObj.m_Data); - } - - virtual bool HandlesTransaction() { return true; } - }; - - template - struct SInitialComboProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - - SInitialComboProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) - : TBaseType(inAlloc, inDec) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual eastl::vector GetLegalValues(IEditorObject &inEditor) - { - eastl::vector retval; - TEditorType &theEditor = static_cast(inEditor); - retval.push_back(theEditor.m_Editor.RegisterStr("(script expression)")); - theEditor.m_Editor.GetLegalInitialValues(theEditor.m_Data, retval); - return retval; - } - - virtual Option DoGet(TEditorType &inObj) - { - TEditorType &theEditor = inObj; - if (theEditor.m_InitialComboValue.size() == 0) { - if (!isTrivial(inObj.m_Data.GetInitialExpression())) - theEditor.m_InitialComboValue = "(script expression)"; - else if (inObj.m_Data.GetInitialTransition() - && inObj.m_Data.GetInitialTransition()->m_Target.size()) - theEditor.m_InitialComboValue.assign( - inObj.m_Data.GetInitialTransition()->m_Target[0]->m_Id.c_str()); - else - theEditor.m_InitialComboValue = - theEditor.m_Editor.GetDefaultInitialValue(theEditor.m_Data); - } - return theEditor.m_InitialComboValue; - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - if (inValue->getData() != "(script expression)") { - inObj.m_Editor.SetInitialAttribute(inValue, inObj.m_Data); - } else { - inObj.m_Editor.SetInitialAttribute(Option(), inObj.m_Data); - } - } - virtual bool HandlesTransaction() { return true; } - }; - - template - struct SOptionAccessorProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - typedef Option TOptType; - typedef TOptType (TStateType::*TGetPtr)() const; - typedef void (TStateType::*TSetPtr)(const TOptType &inOpt); - TGetPtr m_Getter; - TSetPtr m_Setter; - - SOptionAccessorProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, - TGetPtr inPtr, TSetPtr inSetPtr) - : TBaseType(inAlloc, inDec) - , m_Getter(inPtr) - , m_Setter(inSetPtr) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - TOptType theOpt = (inObj.m_Data.*m_Getter)(); - if (theOpt.hasValue()) - return SValue(*theOpt); - return Empty(); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - TOptType theNewValue; - if (inValue.hasValue()) - theNewValue = TOptType(inValue->getData()); - (inObj.m_Data.*m_Setter)(theNewValue); - } - }; - - template - struct SDataIdProp : SDataProp - { - typedef SDataProp TBaseType; - typedef CRegisteredString TStateType::*TPropertyPtr; - - SDataIdProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, - TPropertyPtr inPtr) - : TBaseType(inAlloc, inDec, inPtr) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - // This may mangle the id in order to find a unique id. - inObj.m_Editor.SetIdProperty(inObj.m_Data, inValue, inObj.m_Data.*(this->m_Ptr)); - } - }; - - template - IPropertyAccessor *CreateDataAccessor(SEditorImpl &inData, TDataType TStateType::*inDataPtr, - const char8_t *inName, - EditorPropertyTypes::Enum inPropType) - { - typedef SDataProp TPropType; - return QT3DS_NEW(inData.m_EditorFoundation->getAllocator(), TPropType)( - inData.m_EditorFoundation, - SPropertyDeclaration(inData.RegisterStr(inName), inPropType), inDataPtr); - } - - template - struct SEditorImplProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - typedef TDataType TEditorType::*TPropertyPtr; - TPropertyPtr m_Ptr; - - SEditorImplProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, - TPropertyPtr inPtr) - : TBaseType(inAlloc, inDec) - , m_Ptr(inPtr) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - return inObj.m_Editor.Get(inObj.*(this->m_Ptr)); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.m_Editor.Set(inValue, inObj.*(this->m_Ptr)); - } - }; - - template - IPropertyAccessor * - CreateEditorAccessor(SEditorImpl &inData, TDataType TEditorObject::*inDataPtr, - const char8_t *inName, EditorPropertyTypes::Enum inPropType) - { - typedef SEditorImplProp TPropType; - return QT3DS_NEW(inData.m_EditorFoundation->getAllocator(), TPropType)( - inData.m_EditorFoundation, - SPropertyDeclaration(inData.RegisterStr(inName), inPropType), inDataPtr); - } - - // General property for initial and history transition properties - template - struct SSCXMLInitialPtr : public SPropertyAccessorBase - { - typedef STransition *TStateType::*TPropertyType; - typedef SPropertyAccessorBase TBaseType; - TPropertyType m_PropPtr; - - SSCXMLInitialPtr(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, - TPropertyType inPropPtr) - : TBaseType(inAlloc, inDec) - , m_PropPtr(inPropPtr) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - return inObj.GetInitial(inObj.m_Data.*m_PropPtr); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.SetInitial(inValue->getData(), inObj.m_Data.*m_PropPtr); - } - }; - - template - struct SSCXMLInitialContent : public SPropertyAccessorBase - { - typedef STransition *TStateType::*TPropertyType; - typedef SPropertyAccessorBase TBaseType; - TPropertyType m_PropPtr; - - SSCXMLInitialContent(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, - TPropertyType inPropPtr) - : TBaseType(inAlloc, inDec) - , m_PropPtr(inPropPtr) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - return inObj.GetInitialContent(inObj.m_Data.*m_PropPtr); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - if (inValue.hasValue()) { - inObj.SetInitialContent(inValue->getData(), inObj.m_Data.*m_PropPtr); - } else { - inObj.SetInitialContent(TObjList(), inObj.m_Data.*m_PropPtr); - } - } - }; - - template - struct SDelayProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - - SDelayProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) - : TBaseType(inAlloc, inDec) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - if (!isTrivial(inObj.m_Data.m_DelayExpr)) - return Empty(); - - return inObj.m_Editor.GetSendId(inObj.m_Data.m_Delay); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.m_Data.m_DelayExpr = ""; - inObj.m_Editor.SetSendId(inValue, inObj.m_Data.m_Delay); - } - }; - - template - struct SHistoryTransitionProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - - SHistoryTransitionProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) - : TBaseType(inAlloc, inDec) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual eastl::vector GetLegalValues(IEditorObject &inEditor) - { - TEditorType &theEditor = static_cast(inEditor); - return theEditor.m_Editor.GetLegalHistoryDefaultValues(theEditor.m_Data); - } - - virtual Option DoGet(TEditorType &inObj) - { - if (inObj.m_Data.m_Transition) - return inObj.m_Editor.Get(inObj.m_Data.m_Transition->m_Target); - - return SValue(TObjList()); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - TObjList newObjects; - - if (inValue.hasValue()) - newObjects = inValue->getData(); - - if (newObjects.size()) { - if (!inObj.m_Data.m_Transition) { - inObj.m_Data.m_Transition = - (STransition *)inObj.m_Editor.m_AutoAllocator.allocate( - sizeof(STransition), "transition", __FILE__, __LINE__); - new (inObj.m_Data.m_Transition) STransition(); - inObj.m_Data.m_Transition->m_Parent = &inObj.m_Data; - } - inObj.m_Editor.Set(inValue, inObj.m_Data.m_Transition->m_Target); - } else - inObj.m_Data.m_Transition = NULL; - } - }; - - template - struct SParentProp : public SPropertyAccessorBase - { - typedef SPropertyAccessorBase TBaseType; - - SParentProp(TFoundationPtr inAlloc, IStringTable &inStrTable) - : TBaseType(inAlloc, SPropertyDeclaration(inStrTable.RegisterStr("parent"), - EditorPropertyTypes::StringSet)) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - static const char *SCXMLParentName() { return "(none)"; } - - virtual Option DoGet(TEditorType &inObj) - { - TObjPtr current = inObj.Parent(); - if (current && AreEqual(current->TypeName(), "scxml") == false) - return SValue(current->GetId()); - return Option(SValue(eastl::string(SCXMLParentName()))); - } - - virtual eastl::vector GetLegalValues(IEditorObject &inEditor) - { - TEditorType &theEditor = static_cast(inEditor); - eastl::vector retval = - theEditor.m_Editor.GetLegalParentIds(theEditor.m_Data); - CRegisteredString parentName(theEditor.m_Editor.RegisterStr(SCXMLParentName())); - retval.insert(retval.begin(), parentName); - return retval; - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - inObj.m_Editor.SetParent(inObj.m_Data, inValue); - } - - virtual bool HandlesTransaction() { return true; } - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.cpp b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.cpp deleted file mode 100644 index 1bc0faf7..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateEditorTransactionImpl.h" - -namespace qt3ds { -namespace state { - namespace editor { - - // Some things have to be implemented below so that we can take advantage of the full - // SEditorImpl definition. - - STransaction::STransaction(TFoundationPtr alloc, STransactionManagerImpl &inEditor, - const TEditorStr &inName) - : ITransaction(inName) - , m_Alloc(alloc) - , mRefCount(0) - , m_Editor(inEditor) - { - } - - STransaction::~STransaction() {} - - void STransaction::addRef() { atomicIncrement(&mRefCount); } - - void STransaction::release() - { - atomicDecrement(&mRefCount); - if (mRefCount <= 0) { - TFoundationPtr fnd(m_Alloc); - NVDelete(fnd->getAllocator(), this); - } - } - - void STransaction::ChangesToEditors() - { - m_EditorsList.clear(); - m_EditorsList.resize(m_Changes.size()); - eastl::transform(m_Changes.begin(), m_Changes.end(), m_EditorsList.begin(), - SChangeToEditor()); - } - - void STransaction::SendDoSignals() - { - ChangesToEditors(); - CreateRemovedEditorsList(true); - for (TChangeListenerList::iterator listenerIter = m_Editor->m_ChangeListeners.begin(), - listenerEnd = m_Editor->m_ChangeListeners.end(); - listenerIter != listenerEnd; ++listenerIter) - (*listenerIter)->OnDataChange(m_EditorsList, m_RemovedEditorsList); - } - - void STransaction::Do() - { - for (TChangeList::iterator iter = m_Changes.begin(), end = m_Changes.end(); iter != end; - ++iter) - (*iter)->Do(); - - for (TRemovePairList::iterator iter = m_RemovedPairs.begin(), - end = m_RemovedPairs.end(); - iter != end; ++iter) { - if (iter->first) - iter->second->RemoveIdFromContext(); - else - iter->second->AddIdToContext(); - } - - SendDoSignals(); - } - - void STransaction::SilentUndo() - { - for (TChangeList::reverse_iterator iter = m_Changes.rbegin(), end = m_Changes.rend(); - iter != end; ++iter) - (*iter)->Undo(); - - for (TRemovePairList::iterator iter = m_RemovedPairs.begin(), - end = m_RemovedPairs.end(); - iter != end; ++iter) { - if (iter->first) - iter->second->AddIdToContext(); - else - iter->second->RemoveIdFromContext(); - } - } - - void STransaction::Undo() - { - SilentUndo(); - m_EditorsList.clear(); - m_EditorsList.resize(m_Changes.size()); - eastl::transform(m_Changes.rbegin(), m_Changes.rend(), m_EditorsList.begin(), - SChangeToEditor()); - CreateRemovedEditorsList(false); - for (TChangeListenerList::iterator listenerIter = m_Editor->m_ChangeListeners.begin(), - listenerEnd = m_Editor->m_ChangeListeners.end(); - listenerIter != listenerEnd; ++listenerIter) - (*listenerIter)->OnDataChange(m_EditorsList, m_RemovedEditorsList); - } - - struct STransactionImplConnection : public IStateSignalConnection - { - TFoundationPtr &m_Alloc; - QT3DSI32 mRefCount; - STransactionManagerImpl &m_Editor; - IEditorChangeListener &m_ChangeListener; - STransactionImplConnection(TFoundationPtr &alloc, STransactionManagerImpl &e, - IEditorChangeListener &listener) - : m_Alloc(alloc) - , mRefCount(0) - , m_Editor(e) - , m_ChangeListener(listener) - { - } - // Implemented below editor to use editor's interfaces - virtual ~STransactionImplConnection() - { - m_Editor.RemoveChangeListener(m_ChangeListener); - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc, mRefCount); - }; - - void STransactionManagerImpl::addRef() { atomicIncrement(&mRefCount); } - void STransactionManagerImpl::release() - { - atomicDecrement(&mRefCount); - if (mRefCount <= 0) { - TFoundationPtr fnd(m_EditorFoundation); - NVDelete(fnd->getAllocator(), this); - } - } - - TSignalConnectionPtr - STransactionManagerImpl::AddChangeListener(IEditorChangeListener &inListener) - { - m_ChangeListeners.push_back(&inListener); - // If we have any listeners, then we can't be destroyed as their connections will still - // need - // to talk to us to release its stuff. - if (m_ChangeListeners.size() == 1) - addRef(); - return QT3DS_NEW(m_EditorFoundation->getAllocator(), - STransactionImplConnection)(m_EditorFoundation, *this, inListener); - } - - void STransactionManagerImpl::RemoveChangeListener(IEditorChangeListener &inListener) - { - TChangeListenerList::iterator iter = - eastl::find(m_ChangeListeners.begin(), m_ChangeListeners.end(), &inListener); - if (iter != m_ChangeListeners.end()) - m_ChangeListeners.erase(iter); - if (m_ChangeListeners.size() == 0) - release(); - } - TTransactionPtr STransactionManagerImpl::BeginTransaction(const TEditorStr &inName) - { - if (!m_Transaction) { - QT3DS_ASSERT(m_OpenCount == 0); - m_Transaction = QT3DS_NEW(m_EditorFoundation->getAllocator(), - STransaction)(m_EditorFoundation, *this, inName); - } - ++m_OpenCount; - return m_Transaction.mPtr; - } - - TTransactionPtr STransactionManagerImpl::GetOpenTransaction() { return m_Transaction.mPtr; } - STransaction *STransactionManagerImpl::GetOpenTransactionImpl() - { - return m_Transaction.mPtr; - } - - void STransactionManagerImpl::RollbackTransaction() - { - --m_OpenCount; - if (m_OpenCount <= 0) { - if (m_Transaction) { - m_Transaction->Undo(); - m_Transaction = NULL; - } - } - QT3DS_ASSERT(m_OpenCount == 0); - m_OpenCount = 0; - } - - void STransactionManagerImpl::EndTransaction() - { - TTransactionPtr retval = m_Transaction.mPtr; - --m_OpenCount; - if (m_OpenCount <= 0) - m_Transaction = NULL; - QT3DS_ASSERT(m_OpenCount >= 0); - m_OpenCount = 0; - } - - void STransactionManagerImpl::OnObjectDeleted(TObjPtr inObj) - { - if (m_Transaction) - m_Transaction->m_RemovedPairs.push_back(eastl::make_pair(true, inObj)); - - if (m_ObjListener) - m_ObjListener->OnObjectDeleted(inObj); - } - void STransactionManagerImpl::OnObjectCreated(TObjPtr inObj) - { - if (m_Transaction) - m_Transaction->m_RemovedPairs.push_back(eastl::make_pair(false, inObj)); - - if (m_ObjListener) - m_ObjListener->OnObjectCreated(inObj); - } - } -} -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.h deleted file mode 100644 index 9996c351..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransactionImpl.h +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_TRANSACTION_IMPL_H -#define QT3DS_STATE_EDITOR_TRANSACTION_IMPL_H -#include "Qt3DSStateEditor.h" -#include "Qt3DSStateEditorFoundation.h" -#include "Qt3DSStateEditorProperties.h" - -namespace qt3ds { -namespace state { - namespace editor { - - class IChange : public NVRefCounted - { - protected: - virtual ~IChange() {} - public: - virtual void Do() = 0; - virtual void Undo() = 0; - virtual TObjPtr GetEditor() = 0; - }; - - typedef eastl::vector> TChangeList; - - struct SChange : public IChange - { - Option m_OldVal; - Option m_NewVal; - TPropertyAccessorPtr m_Accessor; - TObjPtr m_Editor; - QT3DSI32 mRefCount; - - SChange(const Option &inOldVal, const Option &inNewVal, - IPropertyAccessor &inAccessor, IEditorObject &inEditor) - : m_OldVal(inOldVal) - , m_NewVal(inNewVal) - , m_Accessor(inAccessor) - , m_Editor(inEditor) - , mRefCount(0) - { - } - // Sometimes we need to create a change just to signal a new object. - // In this case there isn't an accessor and there aren't old values and - // new values. - SChange(IEditorObject &inEditor) - : m_Editor(inEditor) - , mRefCount(0) - { - } - SChange() - : mRefCount(0) - { - } - void Do() - { - if (m_Accessor) - m_Accessor->Set(*m_Editor, m_NewVal); - } - - void Undo() - { - if (m_Accessor) - m_Accessor->Set(*m_Editor, m_OldVal); - } - void addRef() { atomicIncrement(&mRefCount); } - void release() - { - atomicDecrement(&mRefCount); - if (mRefCount <= 0) - delete this; - } - - TObjPtr GetEditor() { return m_Editor; } - }; - - // true if removed on do, false if removed on false; - typedef eastl::pair TRemovePair; - typedef eastl::vector TRemovePairList; - - struct STransactionManagerImpl; - - struct STransaction : public ITransaction - { - TFoundationPtr m_Alloc; - TChangeList m_Changes; - volatile QT3DSI32 mRefCount; - // We have to keep a refcount to the editor ourselves. - NVScopedRefCounted m_Editor; - TObjList m_EditorsList; - TObjList m_RemovedEditorsList; - TRemovePairList m_RemovedPairs; - - STransaction(TFoundationPtr alloc, STransactionManagerImpl &inEditor, - const TEditorStr &inName); - virtual ~STransaction(); - virtual void addRef(); - virtual void release(); - - void CreateRemovedEditorsList(bool inDo) - { - m_RemovedEditorsList.clear(); - for (TRemovePairList::iterator iter = m_RemovedPairs.begin(), - end = m_RemovedPairs.end(); - iter != end; ++iter) - if (iter->first == inDo) - m_RemovedEditorsList.push_back(iter->second); - } - - struct SChangeToEditor - { - TObjPtr operator()(IChange *inChange) const { return inChange->GetEditor(); } - }; - virtual void SendDoSignals(); - virtual void Do(); - virtual void SilentUndo(); - virtual void Undo(); - virtual bool Empty() { return m_Changes.empty() && m_RemovedPairs.empty(); } - virtual TObjList GetEditedObjects() - { - ChangesToEditors(); - return m_EditorsList; - } - void ChangesToEditors(); - }; - - class ITransManagerImplListener - { - protected: - virtual ~ITransManagerImplListener() {} - public: - virtual void OnObjectDeleted(TObjPtr inObj) = 0; - virtual void OnObjectCreated(TObjPtr inObj) = 0; - }; - - struct STransactionManagerImpl : public ITransactionManager - { - TFoundationPtr m_EditorFoundation; - volatile QT3DSI32 mRefCount; - TChangeListenerList m_ChangeListeners; - NVScopedRefCounted m_Transaction; - QT3DSI32 m_OpenCount; - ITransManagerImplListener *m_ObjListener; - - STransactionManagerImpl(TFoundationPtr fnd) - : m_EditorFoundation(fnd) - , mRefCount(0) - , m_OpenCount(0) - , m_ObjListener(NULL) - { - } - virtual void addRef(); - virtual void release(); - virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener); - virtual TTransactionPtr BeginTransaction(const TEditorStr &inName = TEditorStr()); - virtual TTransactionPtr GetOpenTransaction(); - STransaction *GetOpenTransactionImpl(); - virtual void RollbackTransaction(); - virtual void EndTransaction(); - - void OnObjectDeleted(TObjPtr inObj); - void OnObjectCreated(TObjPtr inObj); - - void RemoveChangeListener(IEditorChangeListener &inListener); - }; - } -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.cpp b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.cpp deleted file mode 100644 index 7fb4ab9f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.cpp +++ /dev/null @@ -1,813 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateEditorTransitionPath.h" - -namespace { - -using namespace qt3ds::state::editor; -using namespace qt3ds::state; - -bool inBounds(QT3DSF32 item, QT3DSF32 lower, QT3DSF32 upper) -{ - if (item >= lower && item <= upper) - return true; - return false; -} - -DirectionTypes::Enum EdgeTypeToDirectionType(EdgeTypes::Enum inEdgeType) -{ - switch (inEdgeType) { - case EdgeTypes::Bottom: - case EdgeTypes::Top: - return DirectionTypes::Vertical; - default: - return DirectionTypes::Horizontal; - } -} - -static inline SEndPoint DoGetActualEndPoint(const SEndPoint &inPoint, const SRect &inMyRect, - const QT3DSVec2 &inOtherCenter) -{ - SEndPoint theEndPoint = inPoint; - if (inPoint.m_EdgeType == EdgeTypes::UnsetEdgeType) - theEndPoint = CEditorTransitionPath::CalculateDefaultEndPoint(inMyRect, inOtherCenter); - return theEndPoint; -} - -static inline eastl::pair -GetEndpointPoint(const SEndPoint &inPoint, const SRect &inMyRect, const QT3DSVec2 &inOtherCenter) -{ - SEndPoint theEndPoint = DoGetActualEndPoint(inPoint, inMyRect, inOtherCenter); - SLine theRectLine; - switch (theEndPoint.m_EdgeType) { - case EdgeTypes::Top: - theRectLine = inMyRect.topEdge(); - break; - case EdgeTypes::Bottom: - theRectLine = inMyRect.bottomEdge(); - break; - case EdgeTypes::Left: - theRectLine = inMyRect.leftEdge(); - break; - default: - QT3DS_ASSERT(false); - // fallthrough intentional - case EdgeTypes::Right: - theRectLine = inMyRect.rightEdge(); - break; - } - - return eastl::make_pair(theRectLine.toPoint(theEndPoint.m_Interp), theEndPoint.m_EdgeType); -} - -inline bool RectDiffers(const Option &inLhs, const SRect &inRhs) -{ - if (inLhs.isEmpty()) - return true; - SRect lhs = *inLhs; - return CEditorTransitionPath::AreAlmostEqual(lhs.m_TopLeft, inRhs.m_TopLeft) == false - || CEditorTransitionPath::AreAlmostEqual(lhs.m_WidthHeight, inRhs.m_WidthHeight) == false; -} -} - -namespace qt3ds { -namespace state { - namespace editor { - - bool SRect::contains(const QT3DSVec2 &inPoint) const - { - if (inPoint.x >= left() && inPoint.x <= right() && inPoint.y >= top() - && inPoint.y <= bottom()) - return true; - return false; - } - - void CEditorTransitionPath::SetPathType(TransitionPathTypes::Enum inType) - { - m_TransitionPathType = inType; - if (m_TransitionPathType == TransitionPathTypes::BeginToBegin - || m_TransitionPathType == TransitionPathTypes::Targetless) - m_ControlPoints.clear(); - MarkDirty(); - } - - bool CEditorTransitionPath::UpdateBeginEndRects(const SRect &inStartRect, - const SRect &inEndRect) - { - bool dataChanged = false; - - if (m_BeginRect.hasValue() && m_EndRect.hasValue()) { - QT3DSVec2 beginDiff = inStartRect.center() - m_BeginRect->center(); - QT3DSVec2 endDiff = inEndRect.center() - m_EndRect->center(); - - if (AreAlmostEqual(beginDiff, QT3DSVec2(0, 0)) == false - && AreAlmostEqual(beginDiff, endDiff, 1)) { - dataChanged = m_ControlPoints.empty() == false; - // Move all the control points. - for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) { - SControlPoint &thePoint(m_ControlPoints[idx]); - QT3DSF32 diffComponent = - SControlPoint::GetComponent(beginDiff, thePoint.m_Direction); - thePoint.m_Position += diffComponent; - } - } - } - bool rectDiffers = - RectDiffers(m_BeginRect, inStartRect) || RectDiffers(m_EndRect, inEndRect); - m_BeginRect = inStartRect; - m_EndRect = inEndRect; - if (rectDiffers) - MarkDirty(); - m_TransitionPathType = TransitionPathTypes::BeginToEnd; - return dataChanged; - } - - bool CEditorTransitionPath::UpdateBeginEndRects(const SRect &inStartRect, - TransitionPathTypes::Enum inPathType) - { - bool dataChanged = m_ControlPoints.empty() == false; - QT3DS_ASSERT(inPathType == TransitionPathTypes::BeginToBegin - || inPathType == TransitionPathTypes::Targetless); - bool rectDiffers = m_EndRect.hasValue() || RectDiffers(m_BeginRect, inStartRect); - m_BeginRect = inStartRect; - m_EndRect = Empty(); - if (rectDiffers || dataChanged) - MarkDirty(); - m_TransitionPathType = inPathType; - return dataChanged; - } - - eastl::pair CEditorTransitionPath::GetBeginPointAndEdge() const - { - eastl::pair theStartPoint(QT3DSVec2(0, 0), - EdgeTypes::UnsetEdgeType); - if (m_BeginRect.hasValue()) { - QT3DSVec2 center(m_BeginRect->center()); - center.x += 1; - if (m_EndRect.hasValue()) - center = m_EndRect->center(); - theStartPoint = GetEndpointPoint(m_Begin, *m_BeginRect, center); - } - return theStartPoint; - } - - eastl::pair CEditorTransitionPath::GetBeginEndPoints() const - { - eastl::pair theStartPoint(GetBeginPointAndEdge()); - eastl::pair theEndPoint(QT3DSVec2(0, 0), - EdgeTypes::UnsetEdgeType); - if (m_EndRect.hasValue()) - theEndPoint = GetEndpointPoint(m_End, *m_EndRect, m_BeginRect->center()); - - return eastl::make_pair(theStartPoint.first, theEndPoint.first); - } - - SEndPoint CEditorTransitionPath::CalculateEndPoint(const SRect &inRect, - const QT3DSVec2 &inPoint, - QT3DSF32 inEdgeBoundary) - { - if (inRect.width() == 0 || inRect.height() == 0) { - QT3DS_ASSERT(false); - return SEndPoint(); - } - - SLine centerToPoint = SLine(inRect.center(), inPoint); - SLine leftOrRight; - SLine topOrBottom; - Option isect; - EdgeTypes::Enum theEdge = EdgeTypes::UnsetEdgeType; - // If line runs right, test against right edge - QT3DSF32 distance = 0; - SLine theRectLine; - if (centerToPoint.dx() > 0) { - theRectLine = inRect.rightEdge(); - isect = theRectLine.intersect(centerToPoint); - // If we are out of range for the right edge - if (isect.hasValue() && inBounds(*isect, 0.0f, 1.0f)) { - distance = theRectLine.dy(); - theEdge = EdgeTypes::Right; - } - } else { - theRectLine = inRect.leftEdge(); - isect = theRectLine.intersect(centerToPoint); - if (isect.hasValue() && inBounds(*isect, 0.0f, 1.0f)) { - distance = theRectLine.dy(); - theEdge = EdgeTypes::Left; - } - } - // If we haven't resolved the edge type - if (theEdge == EdgeTypes::UnsetEdgeType) { - if (centerToPoint.dy() < 0) { - theRectLine = inRect.topEdge(); - isect = theRectLine.intersect(centerToPoint); - theEdge = EdgeTypes::Top; - distance = theRectLine.dx(); - } else { - theRectLine = inRect.bottomEdge(); - isect = theRectLine.intersect(centerToPoint); - theEdge = EdgeTypes::Bottom; - distance = theRectLine.dx(); - } - } - // Now drop a perpendicular from the point to the rect line. - SLine normalLine(inPoint, inPoint + QT3DSVec2(theRectLine.dy(), -theRectLine.dx())); - isect = theRectLine.intersect(normalLine); - if (isect.isEmpty()) { - theEdge = EdgeTypes::Right; - isect = .5f; - } - SEndPoint retval(theEdge, *isect); - QT3DSF32 normalizedBoundary = - NVMax(0.0f, inEdgeBoundary / static_cast(fabs(distance))); - - QT3DSF32 edgeLowerBound = NVMax(0.0f, normalizedBoundary); - QT3DSF32 edgeUpperBound = NVMin(1.0f, 1.0f - normalizedBoundary); - retval.m_Interp = NVMax(edgeLowerBound, retval.m_Interp); - retval.m_Interp = NVMin(edgeUpperBound, retval.m_Interp); - return retval; - } - - // Default end points always are in the middle of the rect edge - SEndPoint CEditorTransitionPath::CalculateDefaultEndPoint(const SRect &inRect, - const QT3DSVec2 &inPoint) - { - SEndPoint ep = CalculateEndPoint(inRect, inPoint, 0.0f); - return SEndPoint(ep.m_EdgeType, .5f); - } - - void CEditorTransitionPath::SetEndPoint(const QT3DSVec2 &inWorldPoint) - { - QT3DS_ASSERT(m_EndRect.hasValue()); - m_End = CalculateEndPoint(*m_EndRect, inWorldPoint, m_StateEdgeBuffer); - MarkDirty(); - } - - void CEditorTransitionPath::SetBeginPoint(const QT3DSVec2 &inWorldPoint) - { - QT3DS_ASSERT(m_BeginRect.hasValue()); - m_Begin = CalculateEndPoint(*m_BeginRect, inWorldPoint, m_StateEdgeBuffer); - MarkDirty(); - } - - SEndPoint CEditorTransitionPath::GetActualBeginPoint() const - { - return DoGetActualEndPoint(m_Begin, *m_BeginRect, m_EndRect->center()); - } - - SEndPoint CEditorTransitionPath::GetActualEndPoint() const - { - return DoGetActualEndPoint(m_End, *m_EndRect, m_BeginRect->center()); - } - - void CEditorTransitionPath::SetControlPoint(QT3DSI32 idx, const QT3DSVec2 &inPosition, - bool inMoveAdjacentEndPoint) - { - if (idx < 0 || idx >= (QT3DSI32)m_ControlPoints.size()) { - QT3DS_ASSERT(false); - return; - } - m_ControlPoints[idx].Set(inPosition); - if (inMoveAdjacentEndPoint) { - // Move the end points adjacent to the handle. - QT3DSI32 possiblePoint = MapControlPointToPossibleControlPoint(idx); - size_t numPossible = m_PossibleControlPoints.size(); - if (possiblePoint == 0) - SetBeginPoint(inPosition); - if (possiblePoint == ((QT3DSI32)numPossible - 1)) - SetEndPoint(inPosition); - } - - MarkDirty(); - } - - void CEditorTransitionPath::SetControlPoints(const TPointList &inList) - { - QT3DS_ASSERT(inList.size() == m_Path.size()); - for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) { - SControlPoint &theControlPoint(m_ControlPoints[idx]); - if (theControlPoint.m_PathIndex >= 0 - && theControlPoint.m_PathIndex < (QT3DSI32)inList.size()) - theControlPoint.Set(inList[theControlPoint.m_PathIndex]); - else { - QT3DS_ASSERT(false); - } - } - } - - TPointList CEditorTransitionPath::GetPath() const - { - MaybeRegeneratePath(); - return m_Path; - } - - TControlPointList CEditorTransitionPath::GetPossibleControlPoints() const - { - MaybeRegeneratePath(); - return m_PossibleControlPoints; - } - - SControlPoint CEditorTransitionPath::GetPossibleControlPoint(QT3DSI32 inIdx) const - { - MaybeRegeneratePath(); - if (inIdx >= 0 && inIdx < (QT3DSI32)m_PossibleControlPoints.size()) - return m_PossibleControlPoints[inIdx]; - QT3DS_ASSERT(false); - return SControlPoint(); - } - - // This may create a new control point thus invalidating the path and possible control - // points. - QT3DSI32 - CEditorTransitionPath::MapPossibleControlPointToControlPoint(QT3DSI32 inPossiblePointIndex) - { - if (inPossiblePointIndex < 0 - || inPossiblePointIndex >= (QT3DSI32)m_PossibleControlPoints.size()) { - QT3DS_ASSERT(false); - return -1; - } - const SControlPoint &thePossiblePoint(m_PossibleControlPoints[inPossiblePointIndex]); - TControlPointList::iterator iter = eastl::lower_bound( - m_ControlPoints.begin(), m_ControlPoints.end(), thePossiblePoint); - QT3DSI32 retval = (QT3DSI32)m_ControlPoints.size(); - if (iter != m_ControlPoints.end()) { - retval = (QT3DSI32)(iter - m_ControlPoints.begin()); - if (iter->m_PathIndex == thePossiblePoint.m_PathIndex) - return retval; - } - - m_ControlPoints.insert(iter, thePossiblePoint); - return retval; - } - - QT3DSI32 CEditorTransitionPath::MapControlPointToPossibleControlPoint(QT3DSI32 inPointIndex) - { - if (inPointIndex < 0 || inPointIndex >= (QT3DSI32)m_ControlPoints.size()) { - QT3DS_ASSERT(false); - return -1; - } - const SControlPoint &theControlPoint(m_ControlPoints[inPointIndex]); - TControlPointList::iterator iter = eastl::lower_bound( - m_PossibleControlPoints.begin(), m_PossibleControlPoints.end(), theControlPoint); - if (iter != m_PossibleControlPoints.end()) { - QT3DSI32 retval = (QT3DSI32)(iter - m_PossibleControlPoints.begin()); - if (iter->m_PathIndex == theControlPoint.m_PathIndex) - return retval; - } - QT3DS_ASSERT(false); - return -1; - } - - bool CEditorTransitionPath::DoesControlPointExist(QT3DSI32 inPossiblePointIndex) const - { - if (inPossiblePointIndex < 0 - || inPossiblePointIndex >= (QT3DSI32)m_PossibleControlPoints.size()) { - QT3DS_ASSERT(false); - return false; - } - const SControlPoint &thePossiblePoint(m_PossibleControlPoints[inPossiblePointIndex]); - TControlPointList::const_iterator iter = eastl::lower_bound( - m_ControlPoints.begin(), m_ControlPoints.end(), thePossiblePoint); - if (iter != m_ControlPoints.end() && iter->m_PathIndex == thePossiblePoint.m_PathIndex) - return true; - return false; - } - - // Run through the control point list and if you find another control point on the line, - // return it's index. Else - // bail. - // If you are finding the remove algorithm is too specific or hard to use increase the 2.0f - // numbers below. - inline Option NextParallelControlPointOnLine(const SControlPoint &inItem, - const SControlPoint &inEndPoint, - const TControlPointList &inList, - size_t inStartIdx) - { - for (size_t idx = inStartIdx, end = inList.size(); idx < end; ++idx) { - const SControlPoint &theTestPoint(inList[idx]); - if (theTestPoint.m_Direction == inItem.m_Direction) { - if (CEditorTransitionPath::AreAlmostEqual(inItem.m_Position, - theTestPoint.m_Position, 2.0f)) - return idx + 1; - else - return Empty(); - } - } - - // Check if beginning and end lie in the same path, or within just a couple pixels. - if (inItem.m_Direction == inEndPoint.m_Direction - && CEditorTransitionPath::AreAlmostEqual(inItem.m_Position, inEndPoint.m_Position, - 2.0f)) - return inList.size(); - - return Empty(); - } - - // We try to find control point that point the same direction and lie on the same line with - // only control points with - // orthogonal directions in between. If we find points that fullfill this criteria, we know - // we can remove all intermediate - // points because the transition path will end up making a straight line. - bool CEditorTransitionPath::RemoveRedundantControlPoints() - { - if (m_ControlPoints.empty()) - return false; - - eastl::pair theStartPoint = GetBeginPointAndEdge(); - eastl::pair theEndPoint; - if (m_EndRect.hasValue()) - theEndPoint = GetEndpointPoint(m_End, *m_EndRect, m_BeginRect->center()); - else - theEndPoint = theStartPoint; - // Find runs of control points in the same line. Remove the points in the middle of the - // line. - SControlPoint theLastControlPoint(EdgeTypeToDirectionType(theStartPoint.second)); - theLastControlPoint.Set(theStartPoint.first); - SControlPoint theEndControlPoint(EdgeTypeToDirectionType(theEndPoint.second)); - theEndControlPoint.Set(theEndPoint.first); - size_t numControlPoints(m_ControlPoints.size()); - for (size_t idx = 0, end = numControlPoints; idx < end; ++idx) { - Option removeEnd = NextParallelControlPointOnLine( - theLastControlPoint, theEndControlPoint, m_ControlPoints, idx); - if (removeEnd.isEmpty() == false) { - size_t lastItem = *removeEnd; - m_ControlPoints.erase(m_ControlPoints.begin() + idx, - m_ControlPoints.begin() + lastItem); - --idx; - end = m_ControlPoints.size(); - } else - theLastControlPoint = m_ControlPoints[idx]; - } - if (m_ControlPoints.size() != numControlPoints) { - MarkDirty(); - return true; - } - return false; - } - - void CEditorTransitionPath::RestoreAutoTransition() - { - m_ControlPoints.clear(); - m_Begin = SEndPoint(); - m_End = SEndPoint(); - MarkDirty(); - } - - bool CEditorTransitionPath::IsManualMode() const - { - return m_Begin.m_EdgeType != EdgeTypes::UnsetEdgeType - || m_End.m_EdgeType != EdgeTypes::UnsetEdgeType || m_ControlPoints.empty() == false; - } - - SPointQueryResult CEditorTransitionPath::Pick(QT3DSVec2 inPoint, QT3DSVec2 inControlBoxDims, - QT3DSVec2 inEndBoxDims) - { - MaybeRegeneratePath(); - - if (inEndBoxDims.x && inEndBoxDims.y) { - SRect endBox(QT3DSVec2(-1.0f * inEndBoxDims.x / 2, -1.0f * inEndBoxDims.y / 2), - inEndBoxDims); - SRect testRect(endBox); - testRect.translate(m_Path.front()); - if (testRect.contains(inPoint)) - return SPointQueryResult(PointQueryResultType::Begin); - testRect = SRect(endBox); - testRect.translate(m_Path.back()); - if (testRect.contains(inPoint)) - return SPointQueryResult(PointQueryResultType::End); - } - if (inControlBoxDims.x && inControlBoxDims.y) { - SRect theControlBox( - QT3DSVec2(-1.0f * inControlBoxDims.x / 2.0f, -1.0f * inControlBoxDims.y / 2.0f), - inControlBoxDims); - for (size_t idx = 0, end = m_PossibleControlPoints.size(); idx < end; ++idx) { - const SControlPoint &thePoint(m_PossibleControlPoints[idx]); - QT3DSVec2 startPoint = m_Path[thePoint.m_PathIndex]; - QT3DSVec2 endPoint = m_Path[thePoint.m_PathIndex + 1]; - // We stretch the rect to contain the entire line, not just where we display the - // point. - QT3DSVec2 lineDims = endPoint - startPoint; - QT3DSF32 lineRectHeight = SControlPoint::GetComponent(theControlBox.m_WidthHeight, - thePoint.m_Direction); - QT3DSF32 lineRectLength = - fabs(SControlPoint::GetOrthogonalComponent(lineDims, thePoint.m_Direction)); - QT3DSVec2 rectDims = SControlPoint::FromComponentToVector( - lineRectHeight, lineRectLength, thePoint.m_Direction); - QT3DSVec2 rectTopLeft = - QT3DSVec2(NVMin(startPoint.x, endPoint.x), NVMin(startPoint.y, endPoint.y)); - QT3DSF32 rectComponent = - SControlPoint::GetComponent(rectTopLeft, thePoint.m_Direction); - rectComponent -= lineRectHeight / 2.0f; // Center the box about the line. - rectTopLeft = SControlPoint::SetComponent(rectTopLeft, rectComponent, - thePoint.m_Direction); - SRect testRect(rectTopLeft, rectDims); - if (testRect.contains(inPoint)) - return SPointQueryResult(PointQueryResultType::Control, (QT3DSI32)idx); - } - } - return PointQueryResultType::NoPoint; - } - - SPointQueryResult - CEditorTransitionPath::PickClosestControlPoint(QT3DSVec2 inPoint, - DirectionTypes::Enum inDirectionType) - { - MaybeRegeneratePath(); - QT3DSI32 closestIdx = -1; - QT3DSF32 minDistance = QT3DS_MAX_F32; - - for (size_t idx = 0, end = m_PossibleControlPoints.size(); idx < end; ++idx) { - const SControlPoint &thePoint(m_PossibleControlPoints[idx]); - QT3DSVec2 startPoint = m_Path[thePoint.m_PathIndex]; - QT3DSVec2 endPoint = m_Path[thePoint.m_PathIndex + 1]; - SLine theLine(startPoint, endPoint); - QT3DSF32 distance = theLine.distance(inPoint); - - if (distance < minDistance && thePoint.m_Direction == inDirectionType) { - closestIdx = idx; - minDistance = distance; - } - } - if (closestIdx == -1) - return SPointQueryResult(); - return SPointQueryResult(PointQueryResultType::Control, closestIdx); - } - - // The output functions are both setup under these assumptions: - // 1. The current point does *not* have representation in the possible control points list. - // 2. The last point *does* have representation in the possible control points list. - // 3. The algorithm should output all path elements up and to but not including the - // current point. - // So, given straight line do not output any possible points. - // Given zig-zag, output two points. - SControlPoint - CEditorTransitionPath::OutputParallelPoints(const SControlPoint &inLastPoint, - const SControlPoint &inCurrentPoint, - QT3DSF32 runWidth) const - { - const SControlPoint &theRunPoint(inCurrentPoint); - const SControlPoint theLastControlPoint(inLastPoint); - DirectionTypes::Enum runDirection(inLastPoint.m_Direction); - if (AreAlmostEqual(theRunPoint.m_Position, theLastControlPoint.m_Position, 1.0)) { - // Straigh line. Perhaps remove this point? - theRunPoint.m_PathIndex = theLastControlPoint.m_PathIndex; - return theRunPoint; - } else { - // First, output a possible control point inline with inLastPoint - SControlPoint possiblePoint(inLastPoint); - possiblePoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); - m_PossibleControlPoints.push_back(possiblePoint); - // Output zig-zag, we zig zag from last control point to theRunPoint. We need to - // push two points and two control points. - QT3DSVec2 startPos(m_Path.back()); - QT3DSF32 startComponent = SControlPoint::GetComponent(startPos, runDirection); - QT3DSF32 orthoStartComponent = - SControlPoint::GetOrthogonalComponent(startPos, runDirection); - QT3DSF32 endComponent = theRunPoint.m_Position; - QT3DSF32 orthoEndComponent = orthoStartComponent + runWidth; - QT3DSVec2 endPos = SControlPoint::FromComponentToVector( - endComponent, orthoEndComponent, runDirection); - QT3DSF32 zigZagOrthoPos = orthoStartComponent + runWidth / 2; - QT3DSI32 crossbarIndex = (QT3DSI32)m_Path.size(); - QT3DSVec2 crossbarStart = SControlPoint::FromComponentToVector( - startComponent, zigZagOrthoPos, runDirection); - m_Path.push_back(crossbarStart); - m_PossibleControlPoints.push_back( - SControlPoint(SControlPoint::OppositeDirection(theRunPoint.m_Direction), - orthoStartComponent, crossbarIndex)); - QT3DSVec2 crossbarEnd = SControlPoint::FromComponentToVector( - endComponent, zigZagOrthoPos, theRunPoint.m_Direction); - m_Path.push_back(crossbarEnd); - theRunPoint.m_PathIndex = crossbarIndex + 1; - // Do not, however, output the run point. This will happen in the next step. - return inCurrentPoint; - } - } - - // Given right angle, output 1 point. - SControlPoint - CEditorTransitionPath::OutputOrthogonalPoints(const SControlPoint &inLastPoint, - const SControlPoint &inCurrentPoint) const - { - SLine lastLine = inLastPoint.ToLine(); - SLine currentLine = inCurrentPoint.ToLine(); - Option isect = lastLine.intersect(currentLine); - QT3DS_ASSERT(isect.hasValue()); - inLastPoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); - m_PossibleControlPoints.push_back(inLastPoint); - if (isect.hasValue()) { - QT3DSVec2 theIsectPoint = lastLine.toPoint(*isect); - m_Path.push_back(theIsectPoint); - } - inCurrentPoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); - return inCurrentPoint; - } - - void CEditorTransitionPath::MaybeRegeneratePath() const - { - if (IsDirty() == false) - return; - - if (m_TransitionPathType == TransitionPathTypes::BeginToEnd) { - // Ensure intermediate information is cleared. - const_cast(this)->MarkDirty(); - // We don't have the begin and end states. - if (m_BeginRect.isEmpty() || m_EndRect.isEmpty()) { - QT3DS_ASSERT(false); - return; - } - // Find the start and end points. - eastl::pair theStartPoint = - GetEndpointPoint(m_Begin, *m_BeginRect, m_EndRect->center()); - eastl::pair theEndPoint = - GetEndpointPoint(m_End, *m_EndRect, m_BeginRect->center()); - m_Path.push_back(theStartPoint.first); - SControlPoint theLastControlPoint(EdgeTypeToDirectionType(theStartPoint.second)); - theLastControlPoint.Set(theStartPoint.first); - theLastControlPoint.m_PathIndex = 0; - SControlPoint theEndControlPoint(EdgeTypeToDirectionType(theEndPoint.second)); - theEndControlPoint.Set(theEndPoint.first); - for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) { - const SControlPoint &thePoint(m_ControlPoints[idx]); - if (thePoint.m_Direction == theLastControlPoint.m_Direction) { - // zig zag. Requires us to find the first point that *isn't a zig zag in - // order to - // calculate where the zig zag should be. We could have a section composed - // of only - // parallel directions and we can't lay then out until we find how much - // distance we have - // to space each on out. - // Image you get to this point and you find you have a set of control points - // with vertical direction. - // Their positions will tell us how far left each one should sit. But we - // don't have enough information - // to lay them out without knowing how much vertical space this section - // should fill. So we would have to - // search forward until we can figure this out. - QT3DSVec2 runStart = m_Path.back(); - // Search forward until either we run out of points or until we find a point - // who's direction - // does not match the current direction. We call a contiguous set of - // control points who all - // have the same direction a 'run'. - size_t runEnd; - size_t zigzagCount = 1; - DirectionTypes::Enum runDirection = theLastControlPoint.m_Direction; - // Search forward till we find a point that is different. - for (runEnd = idx + 1; runEnd < end - && m_ControlPoints[runEnd].m_Direction == thePoint.m_Direction; - ++runEnd) { - // Skip items that are in line. They shouldn't be counted towards our - // zigzag count. - if (AreAlmostEqual(m_ControlPoints[runEnd].m_Position, - m_ControlPoints[runEnd - 1].m_Position) - == false) - ++zigzagCount; - } - // Two possible cases. Either we find a control point that has a different - // direction in which case we then figure out - // how much space we need overall *or* we ran out of control points in which - // case we use the end point. - QT3DSVec2 runEndPoint(0, 0); - if (runEnd == end) { - // check if the end point direction is the same. This could be the - // final zig zag. Else it will be a righthand turn - if (EdgeTypeToDirectionType(theEndPoint.second) == runDirection - && AreAlmostEqual(theEndControlPoint.m_Position, - thePoint.m_Position) - == false) - ++zigzagCount; - - runEndPoint = theEndPoint.first; - } else { - SLine thePointLine(thePoint.ToLine()); - Option isect = - thePointLine.intersect(m_ControlPoints[runEnd].ToLine()); - if (isect.hasValue()) - runEndPoint = thePointLine.toPoint(*isect); - else { - QT3DS_ASSERT(false); - } - } - QT3DSF32 runOrthoStart = - SControlPoint::GetOrthogonalComponent(runStart, runDirection); - QT3DSF32 runOrthoEnd = - SControlPoint::GetOrthogonalComponent(runEndPoint, runDirection); - QT3DSF32 runRange = runOrthoEnd - runOrthoStart; - QT3DSF32 runWidth = runRange / (QT3DSF32)zigzagCount; - // Now we iterate through the run itself and output path elements. - for (; idx < runEnd; ++idx) { - theLastControlPoint = OutputParallelPoints( - theLastControlPoint, m_ControlPoints[idx], runWidth); - } - // Subtract one to account for the loop upate that happens next - --idx; - } else // right angle - { - theLastControlPoint = - OutputOrthogonalPoints(theLastControlPoint, m_ControlPoints[idx]); - } - } - // Finished iterating through the control points. Now we have the sticky situation - // of the very last point - // and how it joins with the end point. - QT3DSVec2 lastPoint(m_Path.back()); - if (theEndControlPoint.m_Direction == theLastControlPoint.m_Direction) { - QT3DSF32 lastPointOrthoComponent = SControlPoint::GetOrthogonalComponent( - lastPoint, theLastControlPoint.m_Direction); - QT3DSF32 endOrthoComponent = SControlPoint::GetOrthogonalComponent( - theEndPoint.first, theLastControlPoint.m_Direction); - QT3DSF32 runWidth = endOrthoComponent - lastPointOrthoComponent; - OutputParallelPoints(theLastControlPoint, theEndControlPoint, runWidth); - } else { - theLastControlPoint = - OutputOrthogonalPoints(theLastControlPoint, theEndControlPoint); - } - // Now output the last possible point which matches the end control point's - // direction and such. - theEndControlPoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); -#ifdef _DEBUG - // The directly previous possible point in the list should not match this point. In - // fact, it really should be orthogonal. - if (m_PossibleControlPoints.size()) { - QT3DS_ASSERT(m_PossibleControlPoints.back().m_Direction - != theEndControlPoint.m_Direction - || AreAlmostEqual(m_PossibleControlPoints.back().m_Position, - theEndControlPoint.m_Position) - == false); - } -#endif - m_PossibleControlPoints.push_back(theEndControlPoint); - // Finally push back the last item. - m_Path.push_back(theEndPoint.first); - } else if (m_TransitionPathType == TransitionPathTypes::BeginToBegin - || m_TransitionPathType == TransitionPathTypes::Targetless) { - QT3DSVec2 beginCenter(m_BeginRect->center()); - beginCenter.x += 1; - eastl::pair theStartPoint = - GetEndpointPoint(m_Begin, *m_BeginRect, beginCenter); - QT3DSVec2 lineDir; - m_Path.push_back(theStartPoint.first); - if (m_TransitionPathType == TransitionPathTypes::BeginToBegin) { - switch (theStartPoint.second) { - case EdgeTypes::Top: - lineDir = QT3DSVec2(0, -1); - break; - case EdgeTypes::Bottom: - lineDir = QT3DSVec2(0, 1); - break; - case EdgeTypes::Left: - lineDir = QT3DSVec2(-1, 0); - break; - case EdgeTypes::Right: - lineDir = QT3DSVec2(1, 0); - break; - default: - QT3DS_ASSERT(false); - break; - } - QT3DSF32 squareDiagLen = 30; - QT3DSF32 halfDiag = squareDiagLen / 2.0f; - QT3DSVec2 theOppPoint = theStartPoint.first + lineDir * squareDiagLen; - QT3DSVec2 middle = (theStartPoint.first + theOppPoint) / 2.0f; - QT3DSVec2 orthoLineDir = QT3DSVec2(lineDir.y, lineDir.x); - QT3DSVec2 loopTop = middle + orthoLineDir * halfDiag; - QT3DSVec2 loopBottom = middle - orthoLineDir * halfDiag; - m_Path.push_back(loopTop); - m_Path.push_back(theOppPoint); - m_Path.push_back(loopBottom); - m_Path.push_back(theStartPoint.first); - } - } else { - QT3DS_ASSERT(false); - } - } - } -} -} \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.h deleted file mode 100644 index bacf60f2..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorTransitionPath.h +++ /dev/null @@ -1,467 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_TRANSITION_PATH_H -#define QT3DS_STATE_EDITOR_TRANSITION_PATH_H -#pragma once -#include "Qt3DSState.h" -#include "foundation/Qt3DSVec2.h" -#include "EASTL/vector.h" -#include "foundation/Qt3DSOption.h" - -namespace qt3ds { -namespace state { - namespace editor { - - struct EdgeTypes - { - enum Enum { - UnsetEdgeType = 0, - Left, - Right, - Top, - Bottom, - }; - }; - - struct SEndPoint - { - // Which edge are we on - EdgeTypes::Enum m_EdgeType; - // How far from the start of the edge are we. - QT3DSF32 m_Interp; - SEndPoint(EdgeTypes::Enum inType = EdgeTypes::UnsetEdgeType, QT3DSF32 interp = .5f) - : m_EdgeType(inType) - , m_Interp(interp) - { - } - }; - - struct DirectionTypes - { - enum Enum { - UnknownDirection = 0, - Horizontal, - Vertical, - }; - }; - - struct SLine - { - QT3DSVec2 m_Begin; - QT3DSVec2 m_End; - - SLine(const QT3DSVec2 &beg = QT3DSVec2(0, 0), const QT3DSVec2 &end = QT3DSVec2(0, 0)) - : m_Begin(beg) - , m_End(end) - { - } - - QT3DSF32 dx() const { return m_End.x - m_Begin.x; } - QT3DSF32 dy() const { return m_End.y - m_Begin.y; } - QT3DSVec2 begin() const { return m_Begin; } - QT3DSVec2 end() const { return m_End; } - QT3DSVec2 toPoint(QT3DSF32 interp) { return m_Begin + QT3DSVec2(dx() * interp, dy() * interp); } - Option slope() const - { - QT3DSF32 run = dx(); - if (fabs(run) > .0001f) - return dy() / dx(); - return Empty(); - } - // If this function returns a value, it returns an interpolation value such that if you - // call toPoint on the return value it gives you the intersection point. - // http://tog.acm.org/resources/GraphicsGems/gemsiii/insectc.c - // Simplifications taken from Qt's line intersect - Option intersect(const SLine &other) const - { - // ipmlementation is based on Graphics Gems III's "Faster Line Segment Intersection" - QT3DSVec2 a = m_End - m_Begin; - QT3DSVec2 b = other.m_End - other.m_Begin; - QT3DSVec2 c = m_Begin - other.m_Begin; - - QT3DSF32 denominator = a.y * b.x - a.x * b.y; - - if (denominator == 0 || fabs(denominator) < .0001f) - return Empty(); - - QT3DSF32 reciprocal = 1.0f / denominator; - return (b.y * c.x - b.x * c.y) * reciprocal; - } - - // Caculates the top half of the distance to line equation with the fabs or sqrt. - QT3DSF32 distanceNumerator(const QT3DSVec2 &inPoint) const - { - QT3DSF32 x2 = inPoint.x; - QT3DSF32 y2 = inPoint.y; - - QT3DSF32 x1 = m_End.x; - QT3DSF32 y1 = m_End.y; - - QT3DSF32 x0 = m_Begin.x; - QT3DSF32 y0 = m_Begin.y; - return ((x2 - x1) * (y1 - y0)) - ((x1 - x0) * (y2 - y1)); - } - - QT3DSF32 distance(const QT3DSVec2 &inPoint) const - { - QT3DSF32 theDx = dx(); - QT3DSF32 theDy = dy(); - return fabs(distanceNumerator(inPoint)) / sqrtf(theDx * theDx + theDy * theDy); - } - }; - - // Rect in same coordinate space as QT. - struct SRect - { - QT3DSVec2 m_TopLeft; - QT3DSVec2 m_WidthHeight; - SRect(const QT3DSVec2 &tl = QT3DSVec2(0, 0), const QT3DSVec2 &wh = QT3DSVec2(0, 0)) - : m_TopLeft(tl) - , m_WidthHeight(wh) - { - } - QT3DSF32 left() const { return m_TopLeft.x; } - QT3DSF32 top() const { return m_TopLeft.y; } - QT3DSF32 right() const { return m_TopLeft.x + width(); } - QT3DSF32 bottom() const { return m_TopLeft.y + height(); } - QT3DSF32 width() const { return m_WidthHeight.x; } - QT3DSF32 height() const { return m_WidthHeight.y; } - QT3DSVec2 topLeft() const { return m_TopLeft; } - QT3DSVec2 bottomLeft() const { return QT3DSVec2(left(), bottom()); } - QT3DSVec2 bottomRight() const { return QT3DSVec2(right(), bottom()); } - QT3DSVec2 topRight() const { return QT3DSVec2(right(), top()); } - QT3DSVec2 center() const - { - return QT3DSVec2(left() + width() / 2.0f, top() + height() / 2.0f); - } - SLine leftEdge() const { return SLine(topLeft(), bottomLeft()); } - SLine rightEdge() const { return SLine(topRight(), bottomRight()); } - SLine topEdge() const { return SLine(topLeft(), topRight()); } - SLine bottomEdge() const { return SLine(bottomLeft(), bottomRight()); } - void translate(QT3DSF32 x, QT3DSF32 y) - { - m_TopLeft.x += x; - m_TopLeft.y += y; - } - void translate(const QT3DSVec2 &vec) - { - m_TopLeft.x += vec.x; - m_TopLeft.y += vec.y; - } - bool contains(const QT3DSVec2 &inPoint) const; - }; - - struct SControlPoint - { - DirectionTypes::Enum m_Direction; - // World space position - QT3DSF32 m_Position; - // This is a calculated value. Values set will be ignored in favor of recaculating by - // re-deriving - // the transition path. - mutable QT3DSI32 m_PathIndex; - SControlPoint(DirectionTypes::Enum inDir = DirectionTypes::UnknownDirection, - QT3DSF32 pos = 0.0f, QT3DSI32 idx = -1) - : m_Direction(inDir) - , m_Position(pos) - , m_PathIndex(idx) - { - } - bool operator<(const SControlPoint &inOther) const - { - return m_PathIndex < inOther.m_PathIndex; - } - static QT3DSF32 GetComponent(const QT3DSVec2 &inPoint, DirectionTypes::Enum inDir) - { - switch (inDir) { - case DirectionTypes::Horizontal: - return inPoint.y; - break; - case DirectionTypes::Vertical: - return inPoint.x; - break; - default: - QT3DS_ASSERT(false); - break; - } - return 0; - } - static DirectionTypes::Enum OppositeDirection(DirectionTypes::Enum inDir) - { - switch (inDir) { - case DirectionTypes::Horizontal: - return DirectionTypes::Vertical; - default: - return DirectionTypes::Horizontal; - } - } - static QT3DSF32 GetOrthogonalComponent(const QT3DSVec2 &inPoint, DirectionTypes::Enum inDir) - { - switch (inDir) { - case DirectionTypes::Horizontal: - return inPoint.x; - default: - return inPoint.y; - } - } - static QT3DSVec2 FromComponentToVector(QT3DSF32 inComponent, QT3DSF32 orthoComponent, - DirectionTypes::Enum inDir) - { - switch (inDir) { - case DirectionTypes::Horizontal: - return QT3DSVec2(orthoComponent, inComponent); - default: - return QT3DSVec2(inComponent, orthoComponent); - } - } - static QT3DSVec2 SetComponent(const QT3DSVec2 &inPoint, QT3DSF32 inValue, - DirectionTypes::Enum inDir) - { - switch (inDir) { - case DirectionTypes::Horizontal: - return QT3DSVec2(inPoint.x, inValue); - default: - return QT3DSVec2(inValue, inPoint.y); - } - } - void Set(const QT3DSVec2 &inPoint) { m_Position = GetComponent(inPoint, m_Direction); } - SLine ToLine() const - { - switch (m_Direction) { - case DirectionTypes::Horizontal: - return SLine(QT3DSVec2(0, m_Position), QT3DSVec2(1, m_Position)); - default: - return SLine(QT3DSVec2(m_Position, 0), QT3DSVec2(m_Position, 1)); - } - } - }; - - typedef eastl::vector TControlPointList; - typedef eastl::vector TPointList; - - struct PointQueryResultType - { - enum Enum { - NoPoint = 0, - Begin, - End, - Control, - }; - }; - - struct SPointQueryResult - { - PointQueryResultType::Enum m_QueryType; - QT3DSI32 m_Index; - SPointQueryResult( - PointQueryResultType::Enum inResultType = PointQueryResultType::NoPoint, - QT3DSI32 inIndex = -1) - : m_QueryType(inResultType) - , m_Index(inIndex) - { - } - }; - - struct TransitionPathTypes - { - enum Enum { - UnknownPathType = 0, - BeginToEnd = 1, - BeginToBegin = 2, - Targetless = 3, - }; - }; - - class CEditorTransitionPath - { - QT3DSF32 m_StateEdgeBuffer; - Option m_BeginRect; - Option m_EndRect; - SEndPoint m_Begin; - SEndPoint m_End; - // Control points that the user has edited. - TControlPointList m_ControlPoints; - TransitionPathTypes::Enum m_TransitionPathType; - - // ephemeral data, can be derived from start,end points (along with start/end state) and - // the - // user control points. - mutable TPointList m_Path; - // The full set of possible control points can be derived from the path. - mutable TControlPointList m_PossibleControlPoints; - - public: - CEditorTransitionPath(QT3DSF32 inStateEdgeBuffer = 10.0f) - : m_StateEdgeBuffer(inStateEdgeBuffer) - , m_TransitionPathType(TransitionPathTypes::BeginToEnd) - { - } - Option GetBeginRect() const { return m_BeginRect; } - void SetBeginRect(const Option &inRect) - { - m_BeginRect = inRect; - MarkDirty(); - } - - Option GetEndRect() const { return m_EndRect; } - void SetEndRect(const Option &inRect) - { - m_EndRect = inRect; - MarkDirty(); - } - - TransitionPathTypes::Enum GetPathType() const { return m_TransitionPathType; } - // May delete all the control points. - void SetPathType(TransitionPathTypes::Enum inType); - // This may move control points if instart rect and inendrect have shifted by similar - // amounts - // Returns true if persistent data changed, false otherwise. - bool UpdateBeginEndRects(const SRect &inStartRect, const SRect &inEndRect); - bool UpdateBeginEndRects(const SRect &inStartRect, - TransitionPathTypes::Enum inPathType); - eastl::pair GetBeginEndPoints() const; - - SEndPoint GetEndPoint() const { return m_End; } - void SetEndPoint(const SEndPoint &pt) - { - m_End = pt; - MarkDirty(); - } - void SetEndPoint(const QT3DSVec2 &inWorldPoint); - - SEndPoint GetBeginPoint() const { return m_Begin; } - void SetBeginPoint(const SEndPoint &pt) - { - m_Begin = pt; - MarkDirty(); - } - void SetBeginPoint(const QT3DSVec2 &inWorldPoint); - // Return where the end point will be. Will not return an invalid in point - // or an end point where information is not set. - SEndPoint GetActualBeginPoint() const; - SEndPoint GetActualEndPoint() const; - - TControlPointList GetControlPoints() const { return m_ControlPoints; } - SControlPoint GetControlPoint(QT3DSI32 inIndex) const - { - if (inIndex < (QT3DSI32)m_ControlPoints.size()) - return m_ControlPoints[inIndex]; - return SControlPoint(); - } - void SetControlPoints(const TControlPointList &list) - { - m_ControlPoints = list; - MarkDirty(); - } - void SetControlPoint(QT3DSI32 inControlPointIndex, const QT3DSVec2 &inPosition, - bool inMoveAdjacentEndPoint); - - // Set the control points by updating the individual items in the path list. - // This works if you do not add/remove points from the list. - // - // list = GetPath - // move points, don't add,delete - // setControlPoints(list) - void SetControlPoints(const TPointList &inList); - TPointList GetPath() const; - TControlPointList GetPossibleControlPoints() const; - SControlPoint GetPossibleControlPoint(QT3DSI32 inIdx) const; - - // This may create a new control point thus invalidating the path and possible control - // points. - QT3DSI32 MapPossibleControlPointToControlPoint(QT3DSI32 inPossiblePointIndex); - QT3DSI32 MapControlPointToPossibleControlPoint(QT3DSI32 inPointIndex); - // Returns true if MapPossibleControlPointToControlPoint will *not* create a new point - // false otherwise. - bool DoesControlPointExist(QT3DSI32 inPossiblePointIndex) const; - - // Returns true if any points were removed. - bool RemoveRedundantControlPoints(); - - void RestoreAutoTransition(); - - bool IsManualMode() const; - - // Query against the dataset to see what got picked. Includes the endoints. - // The rects should be centered about the original and just describe the picking - // rect to hit against. Empty rects will not get hit. - // Note that the result is the index into the possible point list where the hit - // happened. - // If you intend to manipulate the point, you need to call - // MapPossibleControlPointToControlPoint, - // Which may add a control point which you then can manipulate. - SPointQueryResult Pick(QT3DSVec2 inPoint, QT3DSVec2 inControlBoxDims, - QT3DSVec2 inEndBoxDims = QT3DSVec2(0, 0)); - SPointQueryResult PickClosestControlPoint(QT3DSVec2 inPoint, - DirectionTypes::Enum inDirectionType); - - void MarkDirty() - { - m_Path.clear(); - m_PossibleControlPoints.clear(); - for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) - m_ControlPoints[idx].m_PathIndex = -1; - } - - bool IsDirty() const { return m_Path.empty(); } - - static SEndPoint CalculateEndPoint(const SRect &inRect, const QT3DSVec2 &inPoint, - QT3DSF32 inEdgeBoundary); - static SEndPoint CalculateDefaultEndPoint(const SRect &inRect, const QT3DSVec2 &inPoint); - static bool AreAlmostEqual(QT3DSF32 lhs, QT3DSF32 rhs, QT3DSF32 error = .001f) - { - if (fabs(lhs - rhs) < error) - return true; - return false; - } - - static bool AreAlmostEqual(const QT3DSVec2 &lhs, const QT3DSVec2 &rhs, QT3DSF32 error = .001f) - { - return AreAlmostEqual(lhs.x, rhs.x, error) && AreAlmostEqual(lhs.y, rhs.y, error); - } - - // Regenerates the path if this object is dirty. - void MaybeRegeneratePath() const; - - eastl::pair GetBeginPointAndEdge() const; - - protected: - // Output the path between points that have the same direction. - SControlPoint OutputParallelPoints(const SControlPoint &inLastPoint, - const SControlPoint &inCurrentPoint, - QT3DSF32 inRunWidth) const; - SControlPoint OutputOrthogonalPoints(const SControlPoint &inLastPoint, - const SControlPoint &inCurrentPoint) const; - }; - } -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorValue.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorValue.h deleted file mode 100644 index d47e6c99..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSStateEditorValue.h +++ /dev/null @@ -1,271 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EDITOR_VALUE_H -#define QT3DS_STATE_EDITOR_VALUE_H -#pragma once -#include "Qt3DSState.h" -#include "Qt3DSStateEditor.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" -#include "foundation/Qt3DSVec3.h" - -namespace qt3ds { -namespace state { - namespace editor { - - struct ValueTypes - { - enum Enum { - NoEditorValue = 0, - String, - ObjPtr, - ObjPtrList, - Vec2, - Vec2List, - Vec3, - Boolean, - U32, - }; - }; - - template - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::NoEditorValue; } - }; - - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::String; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::ObjPtr; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::ObjPtrList; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::Vec2; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::Vec2List; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::Vec3; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::Boolean; } - }; - template <> - struct SValueTypeMap - { - static ValueTypes::Enum GetType() { return ValueTypes::U32; } - }; - - struct SValueUnionTraits - { - typedef ValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(TVec2List), - }; - - static TIdType getNoDataId() { return ValueTypes::NoEditorValue; } - - template - static TIdType getType() - { - return SValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case ValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::ObjPtr: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::ObjPtrList: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Vec2: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Vec2List: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Vec3: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Boolean: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::U32: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case ValueTypes::NoEditorValue: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case ValueTypes::String: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::ObjPtr: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::ObjPtrList: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Vec2: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Vec2List: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Vec3: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::Boolean: - return inVisitor(*NVUnionCast(inData)); - case ValueTypes::U32: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case ValueTypes::NoEditorValue: - return inVisitor(); - } - } - }; - } -} -} - -#ifndef _INTEGRITYPLATFORM -// need some specializations in the original nv foundation namespace -namespace qt3ds { -namespace foundation { - - template <> - struct DestructTraits - { - void destruct(QT3DSVec2 &) {} - }; - template <> - struct DestructTraits - { - void destruct(QT3DSVec3 &) {} - }; -} -} -#endif - -namespace qt3ds { -namespace state { - namespace editor { - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SValueUnionTraits::TBufferSize> - TEditorUnionType; - - struct SValue : public TEditorUnionType - { - SValue() {} - - SValue(const SValue &inOther) - : TEditorUnionType(static_cast(inOther)) - { - } - - SValue(const char8_t *inOther) - : TEditorUnionType(TEditorStr(inOther)) - { - } - - template - SValue(const TDataType &inDt) - : TEditorUnionType(inDt) - { - } - - SValue &operator=(const SValue &inOther) - { - TEditorUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SValue &inOther) const - { - return TEditorUnionType::operator==(inOther); - } - bool operator!=(const SValue &inOther) const - { - return TEditorUnionType::operator!=(inOther); - } - - bool empty() const { return getType() == ValueTypes::NoEditorValue; } - }; - - struct SValueOpt : public Option - { - SValueOpt(const SValueOpt &inOther) - : Option(inOther) - { - } - SValueOpt(const Empty &) - : Option() - { - } - SValueOpt() {} - template - SValueOpt(const TDataType &inOther) - : Option(SValue(inOther)) - { - } - SValueOpt &operator=(const SValueOpt &inOther) - { - Option::operator=(inOther); - return *this; - } - }; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.cpp b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.cpp deleted file mode 100644 index f21fb27b..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.cpp +++ /dev/null @@ -1,2527 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSUIADatamodel.h" -#include "foundation/IOStreams.h" -#include "foundation/XML.h" -#include "foundation/FileTools.h" -#include "Qt3DSStateEditorFoundation.h" -#include "Qt3DSStateApplication.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "EASTL/map.h" -#include "EASTL/sort.h" -#include "Qt3DSStateEditorTransactionImpl.h" -#include "Qt3DSUIADatamodelValue.h" -#include "foundation/StringConversion.h" -#include "foundation/StringConversionImpl.h" -#include "Qt3DSDMStringTable.h" - -using namespace qt3ds::app; -using qt3ds::render::IInputStreamFactory; - -namespace qt3ds { -namespace app { - - struct ElementSubTypes - { - enum Enum { - NoSubType = 0, - Component = 1, - Behavior = 2, - }; - }; - - struct SAppElement - { - TEditorStr m_Path; - TEditorStr m_Type; - TEditorStr m_Name; - TEditorStr m_Id; - Q3DStudio::TAttOrArgList m_Attributes; - Q3DStudio::TVisualEventList m_VisualEvents; - eastl::vector> m_Children; - eastl::vector m_InitialValues; - - private: - QT3DSI32 m_RefCount; - - public: - SAppElement() - : m_RefCount(0) - { - } - - virtual ~SAppElement() {} - - void addRef() { ++m_RefCount; } - - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - - virtual ElementSubTypes::Enum GetSubType() { return ElementSubTypes::NoSubType; } - }; -} -} - -namespace { - -typedef eastl::basic_string TStrType; -struct IPropertyParser -{ - virtual ~IPropertyParser() {} - virtual Option ParseStr(const char8_t *inName) = 0; - virtual Option ParseFloat(const char8_t *inName) = 0; - virtual Option ParseVec2(const char8_t *inName) = 0; - virtual Option ParseVec3(const char8_t *inName) = 0; - virtual Option ParseBool(const char8_t *inName) = 0; - virtual Option ParseU32(const char8_t *inName) = 0; - virtual Option ParseI32(const char8_t *inName) = 0; -}; - -struct SMetaPropertyParser : public IPropertyParser -{ - Q3DStudio::IRuntimeMetaData &m_MetaData; - IStringTable &m_StringTable; - TStrType m_TempStr; - qt3ds::foundation::CRegisteredString m_Type; - qt3ds::foundation::CRegisteredString m_ClassId; - - SMetaPropertyParser(const char8_t *inType, const char8_t *inClass, - Q3DStudio::IRuntimeMetaData &inMeta, IStringTable &stringTable) - : m_MetaData(inMeta) - , m_StringTable(stringTable) - , m_Type(stringTable.RegisterStr(inType)) - , m_ClassId(stringTable.RegisterStr(inClass)) - { - } - - qt3ds::foundation::CRegisteredString Register(const char8_t *inName) - { - return m_StringTable.RegisterStr(inName); - } - - virtual Option ParseStr(const char8_t *inName) - { - qt3ds::foundation::CRegisteredString theName(Register(inName)); - Q3DStudio::ERuntimeDataModelDataType theType( - m_MetaData.GetPropertyType(m_Type, theName, m_ClassId)); - if (theType != Q3DStudio::ERuntimeDataModelDataTypeObjectRef - && theType != Q3DStudio::ERuntimeDataModelDataTypeLong4) { - return m_MetaData.GetPropertyValueString(m_Type, theName, m_ClassId); - } - return Empty(); - } - virtual Option ParseFloat(const char8_t *inName) - { - return m_MetaData.GetPropertyValueFloat(m_Type, Register(inName), m_ClassId); - } - virtual Option ParseVec2(const char8_t *inName) - { - Option theProperty = - m_MetaData.GetPropertyValueVector2(m_Type, Register(inName), m_ClassId); - if (theProperty.hasValue()) { - return QT3DSVec2(theProperty->x, theProperty->y); - } - return Empty(); - } - virtual Option ParseVec3(const char8_t *inName) - { - Option theProperty = - m_MetaData.GetPropertyValueVector3(m_Type, Register(inName), m_ClassId); - if (theProperty.hasValue()) { - return *theProperty; - } - return Empty(); - } - virtual Option ParseBool(const char8_t *inName) - { - return m_MetaData.GetPropertyValueBool(m_Type, Register(inName), m_ClassId); - } - - virtual Option ParseU32(const char8_t *inName) - { - Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); - if (retval.hasValue()) - return (QT3DSU32)retval.getValue(); - return Empty(); - } - - virtual Option ParseI32(const char8_t *inName) - { - Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); - if (retval.hasValue()) - return (QT3DSI32)retval.getValue(); - return Empty(); - } -}; - -struct SDomReaderPropertyParser : public IPropertyParser -{ - IDOMReader &m_Reader; - nvvector &m_TempBuf; - MemoryBuffer &m_ReadBuffer; - - SDomReaderPropertyParser(IDOMReader &reader, nvvector &inTempBuf, - MemoryBuffer &readBuf) - : m_Reader(reader) - , m_TempBuf(inTempBuf) - , m_ReadBuffer(readBuf) - { - } - virtual Option ParseStr(const char8_t *inName) - { - const char8_t *retval; - if (m_Reader.UnregisteredAtt(inName, retval)) - return TStrType(retval); - return Empty(); - } - virtual Option ParseFloat(const char8_t *inName) - { - QT3DSF32 retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - virtual Option ParseVec2(const char8_t *inName) - { - QT3DSVec2 retval; - const char8_t *tempVal; - - if (m_Reader.UnregisteredAtt(inName, tempVal)) { - eastl::string tempBuffer(tempVal); - Char8TReader theReader(const_cast(tempBuffer.c_str()), m_ReadBuffer); - NVDataRef theDataRef(toDataRef(&retval.x, 2)); - theReader.ReadRef(theDataRef); - return retval; - } - return Empty(); - } - virtual Option ParseVec3(const char8_t *inName) - { - QT3DSVec3 retval; - const char8_t *tempVal; - if (m_Reader.UnregisteredAtt(inName, tempVal)) { - eastl::string tempBuffer(tempVal); - Char8TReader theReader(const_cast(tempBuffer.c_str()), m_ReadBuffer); - NVDataRef theDataRef(toDataRef(&retval.x, 3)); - theReader.ReadRef(theDataRef); - return retval; - } - return Empty(); - } - virtual Option ParseBool(const char8_t *inName) - { - bool retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - - virtual Option ParseU32(const char8_t *inName) - { - QT3DSU32 retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } - - virtual Option ParseI32(const char8_t *inName) - { - QT3DSI32 retval; - if (m_Reader.Att(inName, retval)) - return retval; - return Empty(); - } -}; - -template -struct SParserHelper -{ -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseStr(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseFloat(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseVec2(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseVec3(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseBool(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseU32(inName); - } -}; -template <> -struct SParserHelper -{ - static Option Parse(const char8_t *inName, IPropertyParser &inParser) - { - return inParser.ParseI32(inName); - } -}; - -struct SSlideInfo -{ - TEditorStr m_Name; -}; - -struct SAppComponent : public SAppElement -{ - TEditorStrList m_Slides; - virtual ElementSubTypes::Enum GetSubType() { return ElementSubTypes::Component; } -}; - -struct SAppBehavior : public SAppElement -{ - Q3DStudio::THandlerList m_Handlers; - virtual ElementSubTypes::Enum GetSubType() { return ElementSubTypes::Behavior; } -}; - -struct SVSEditorObject; - -struct SVSEditor -{ - TFoundationPtr m_Foundation; - NVScopedRefCounted m_TransactionManager; - NVScopedRefCounted m_StringTable; - SVSEditor(TFoundationPtr fnd, IStringTable &inStringTable) - : m_Foundation(fnd) - , m_TransactionManager(QT3DS_NEW(m_Foundation->getAllocator(), STransactionManagerImpl)(fnd)) - , m_StringTable(inStringTable) - { - } - - virtual void RemoveObjectFromGraph(SVSEditorObject &inObj) = 0; - STransaction *GetOpenTransactionImpl() - { - return m_TransactionManager->GetOpenTransactionImpl(); - } -}; - -struct SVSEditorObject : public IEditorObject -{ - TFoundationPtr m_Foundation; - SVSEditor &m_Editor; - TObjPtr m_ParentObject; - TPropertyAccessorList m_PropertyAccessors; - QT3DSI32 mRefCount; - SVSEditorObject(SVSEditor &editor, TObjPtr parent, const char8_t *typeName, - const TPropertyAccessorList &ioList) - : IEditorObject(typeName) - , m_Foundation(editor.m_Foundation) - , m_Editor(editor) - , m_ParentObject(parent) - , m_PropertyAccessors(ioList) - , mRefCount(0) - { - } - - virtual TEditorStr GetId() { return TEditorStr(); } - virtual TEditorStr GetDescription() { return TEditorStr(); } - virtual void SetId(const TEditorStr &) { QT3DS_ASSERT(false); } - virtual void SetDescription(const TEditorStr &) { QT3DS_ASSERT(false); } - - virtual TObjPtr Parent() { return m_ParentObject; } - - IPropertyAccessor *FindPropertyAccessor(const char8_t *inName) - { - CRegisteredString nameStr = m_Editor.m_StringTable->RegisterStr(inName); - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) - if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) - return m_PropertyAccessors[idx].mPtr; - return NULL; - } - - virtual void GetProperties(eastl::vector &outProperties) - { - outProperties.clear(); - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) - outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); - } - - virtual Option FindProperty(const char8_t *propName) - { - for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { - if (AreEqual(m_PropertyAccessors[idx]->m_Declaration.m_Name.c_str(), propName)) - return m_PropertyAccessors[idx]->m_Declaration; - } - return Empty(); - } - - virtual eastl::vector GetLegalValues(const char8_t *) - { - return eastl::vector(); - } - - virtual Option GetPropertyValue(const char8_t *inPropName) - { - IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); - if (accessor) { - return accessor->Get(*this); - } - return Empty(); - } - virtual void SetPropertyValue(const char8_t *inPropName, const SValueOpt &inValue) - { - IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); - if (accessor) { - STransaction *theTransaction = m_Editor.GetOpenTransactionImpl(); - if (theTransaction) { - Option existing = accessor->Get(*this); - theTransaction->m_Changes.push_back( - new SChange(existing, inValue, *accessor, *this)); - } - accessor->Set(*this, inValue); - } else { - QT3DS_ASSERT(false); - } - } - - virtual void RemoveObjectFromGraph() { m_Editor.RemoveObjectFromGraph(*this); } - virtual void RemoveIdFromContext() {} - virtual void AddIdToContext() {} - virtual IEditor &GetEditor() { return m_ParentObject->GetEditor(); } -}; - -template -struct SGenericPropertyStringAccessor : public SPropertyAccessorBase -{ - typedef TEditorStr TDataType; - typedef TDataType TEditorType::*TPropertyPtr; - typedef SPropertyAccessorBase TBaseType; - - TPropertyPtr m_Property; - - SGenericPropertyStringAccessor(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, - TPropertyPtr inPtr) - : TBaseType(inAlloc, inDec) - , m_Property(inPtr) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - TDataType &dtype = inObj.*(this->m_Property); - return SValue(dtype); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - TDataType &dtype = inObj.*(this->m_Property); - dtype.clear(); - if (inValue.hasValue() && inValue->getType() == ValueTypes::String) - dtype = inValue->getData(); - } -}; - -template -struct SGenericPropertyStringFunctionAccessor : public SPropertyAccessorBase -{ - typedef TEditorStr TDataType; - typedef TDataType (TEditorType::*TGetter)() const; - typedef void (TEditorType::*TSetter)(const TDataType &); - typedef SPropertyAccessorBase TBaseType; - - TGetter m_Getter; - TSetter m_Setter; - - SGenericPropertyStringFunctionAccessor(TFoundationPtr inAlloc, - const SPropertyDeclaration &inDec, TGetter inGetter, - TSetter inSetter) - : TBaseType(inAlloc, inDec) - , m_Getter(inGetter) - , m_Setter(inSetter) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); - - virtual Option DoGet(TEditorType &inObj) - { - TDataType dtype = (inObj.*m_Getter)(); - return SValue(dtype); - } - - virtual void DoSet(TEditorType &inObj, const Option &inValue) - { - TDataType dtype; - dtype.clear(); - if (inValue.hasValue() && inValue->getType() == ValueTypes::String) - dtype = inValue->getData(); - - (inObj.*m_Setter)(dtype); - } -}; - -struct SGotoSlideEditor : public SVSEditorObject -{ - TEditorStr m_Component; - TEditorStr m_Slide; - TEditorStr m_Rel; - TEditorStr m_Wrap; - TEditorStr m_Direction; - TEditorStr m_State; - TEditorStr m_Mode; - TEditorStr m_PlayThroughTo; - TEditorStr m_Rate; - TEditorStr m_Time; - static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) - { - if (ioList.size()) - return; - - typedef SGenericPropertyStringAccessor TStrProp; - typedef SGenericPropertyStringFunctionAccessor TStrFunProp; - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_Component)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrFunProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("slide"), - EditorPropertyTypes::String), - &SGotoSlideEditor::GetSlide, &SGotoSlideEditor::SetSlide)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrFunProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("rel"), - EditorPropertyTypes::String), - &SGotoSlideEditor::GetRel, &SGotoSlideEditor::SetRel)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("wrap"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_Wrap)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, - SPropertyDeclaration(editor.m_StringTable->RegisterStr("direction"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_Direction)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("state"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_State)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("mode"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_Mode)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, - SPropertyDeclaration(editor.m_StringTable->RegisterStr("playthroughto"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_PlayThroughTo)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("rate"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_Rate)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("time"), - EditorPropertyTypes::String), - &SGotoSlideEditor::m_Time)); - } - - SGotoSlideEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) - : SVSEditorObject(editor, parent, ElementName(), ioList) - { - } - - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); - - static const char8_t *ElementName() { return "goto-slide"; } - - void SetSlide(const TEditorStr &inSlide) - { - if (inSlide.empty() == false) { - if (m_Editor.GetOpenTransactionImpl()) - SetPropertyValue("rel", SValueOpt()); - else - m_Rel.clear(); - } - m_Slide = inSlide; - } - - TEditorStr GetSlide() const { return m_Slide; } - - void SetRel(const TEditorStr &inRel) - { - if (inRel.empty() == false) { - if (m_Editor.GetOpenTransactionImpl()) - SetPropertyValue("slide", SValueOpt()); - else - m_Slide.clear(); - } - m_Rel = inRel; - } - - TEditorStr GetRel() const { return m_Rel; } -}; - -struct SRunHandlerEditor : public SVSEditorObject -{ - TEditorStr m_Behavior; - TEditorStr m_Handler; - TEditorStr m_ArgumentStr; - static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) - { - if (ioList.size()) - return; - - typedef SGenericPropertyStringAccessor TStrProp; - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), - EditorPropertyTypes::String), - &SRunHandlerEditor::m_Behavior)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("handler"), - EditorPropertyTypes::String), - &SRunHandlerEditor::m_Handler)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, - SPropertyDeclaration(editor.m_StringTable->RegisterStr("arguments"), - EditorPropertyTypes::String), - &SRunHandlerEditor::m_ArgumentStr)); - } - SRunHandlerEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) - : SVSEditorObject(editor, parent, ElementName(), ioList) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); - static const char8_t *ElementName() { return "call"; } -}; - -struct SSetAttributeEditor : public SVSEditorObject -{ - TEditorStr m_Element; - TEditorStr m_Attribute; - TEditorStr m_Value; - - static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) - { - if (ioList.size()) - return; - - typedef SGenericPropertyStringAccessor TStrProp; - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), - EditorPropertyTypes::String), - &SSetAttributeEditor::m_Element)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, - SPropertyDeclaration(editor.m_StringTable->RegisterStr("attribute"), - EditorPropertyTypes::String), - &SSetAttributeEditor::m_Attribute)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("value"), - EditorPropertyTypes::String), - &SSetAttributeEditor::m_Value)); - } - SSetAttributeEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) - : SVSEditorObject(editor, parent, ElementName(), ioList) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); - static const char8_t *ElementName() { return "set-attribute"; } -}; - -struct SFireEventEditor : public SVSEditorObject -{ - TEditorStr m_Element; - TEditorStr m_Event; - - static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) - { - if (ioList.size()) - return; - - typedef SGenericPropertyStringAccessor TStrProp; - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), - EditorPropertyTypes::String), - &SFireEventEditor::m_Element)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("event"), - EditorPropertyTypes::String), - &SFireEventEditor::m_Event)); - } - SFireEventEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) - : SVSEditorObject(editor, parent, ElementName(), ioList) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); - static const char8_t *ElementName() { return "fire-event"; } -}; - -struct SSetPresentationEditor : public SVSEditorObject -{ - TEditorStr m_Ref; - TEditorStr m_Attribute; - TEditorStr m_Value; - - static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) - { - if (ioList.size()) - return; - - typedef SGenericPropertyStringAccessor TStrProp; - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("ref"), - EditorPropertyTypes::String), - &SSetPresentationEditor::m_Ref)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, - SPropertyDeclaration(editor.m_StringTable->RegisterStr("attribute"), - EditorPropertyTypes::String), - &SSetPresentationEditor::m_Attribute)); - - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("value"), - EditorPropertyTypes::String), - &SSetPresentationEditor::m_Value)); - } - SSetPresentationEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) - : SVSEditorObject(editor, parent, ElementName(), ioList) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); - static const char8_t *ElementName() { return "set-presentation"; } -}; - -struct SPlaySoundEditor : public SVSEditorObject -{ - TEditorStr m_FilePath; - - static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) - { - if (ioList.size()) - return; - - typedef SGenericPropertyStringAccessor TStrProp; - ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( - editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("file"), - EditorPropertyTypes::String), - &SPlaySoundEditor::m_FilePath)); - } - SPlaySoundEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) - : SVSEditorObject(editor, parent, ElementName(), ioList) - { - } - QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); - static const char8_t *ElementName() { return "play-sound"; } -}; - -struct SVSEntry -{ - QT3DSI32 mRefCount; - InterpreterEventTypes::Enum m_EventType; - TObjList m_Editors; - - SVSEntry(InterpreterEventTypes::Enum evtType = InterpreterEventTypes::UnknownInterpreterEvent) - : mRefCount(0) - , m_EventType(evtType) - { - } - void addRef() { ++mRefCount; } - void release() - { - --mRefCount; - if (mRefCount <= 0) - delete this; - } -}; - -struct SVSEntryListChange : public IChange -{ - TObjPtr m_Object; - NVScopedRefCounted m_Entry; - QT3DSI32 m_Index; - bool m_AddOnDo; - TObjPtr m_EditorObj; - QT3DSI32 m_RefCount; - - SVSEntryListChange(TObjPtr inObj, TObjPtr inPositionObj, SVSEntry &entry, bool addOnDo, - TObjPtr inEditorObj) - : m_Object(inObj) - , m_Entry(entry) - , m_AddOnDo(addOnDo) - , m_EditorObj(inEditorObj) - , m_RefCount(0) - { - TObjList::iterator iter = - eastl::find(entry.m_Editors.begin(), entry.m_Editors.end(), inPositionObj); - m_Index = iter - entry.m_Editors.begin(); - } - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - void add() { m_Entry->m_Editors.insert(m_Entry->m_Editors.begin() + m_Index, m_Object); } - void remove() - { - TObjList::iterator iter = - eastl::find(m_Entry->m_Editors.begin(), m_Entry->m_Editors.end(), m_Object); - if (iter != m_Entry->m_Editors.end()) - m_Entry->m_Editors.erase(iter); - else { - QT3DS_ASSERT(false); - } - } - - virtual void Do() - { - if (m_AddOnDo) - add(); - else - remove(); - } - virtual void Undo() - { - if (m_AddOnDo) - remove(); - else - add(); - } - virtual TObjPtr GetEditor() { return m_EditorObj; } -}; - -typedef eastl::pair, NVScopedRefCounted> TEntryExitPair; -typedef eastl::map TIdEntryExitMap; -typedef eastl::map TIdStateMapMap; - -struct SIdEntryExitDeleteChange : public IChange -{ - TIdEntryExitMap &m_Map; - TEditorStr m_Id; - TEntryExitPair m_Data; - QT3DSI32 m_RefCount; - TObjPtr m_EditorObject; - bool m_RemoveOnDo; - SIdEntryExitDeleteChange(TIdEntryExitMap &inMap, const TEditorStr &inId, TObjPtr inObj, - bool removeOnDo = true) - : m_Map(inMap) - , m_Id(inId) - , m_RefCount(0) - , m_EditorObject(inObj) - , m_RemoveOnDo(removeOnDo) - { - m_Data = m_Map[m_Id]; - } - virtual void addRef() { ++m_RefCount; } - virtual void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - void remove() - { - TIdEntryExitMap::iterator iter = m_Map.find(m_Id); - if (iter != m_Map.end()) - m_Map.erase(iter); - else { - QT3DS_ASSERT(false); - } - } - void insert() { m_Map[m_Id] = m_Data; } - virtual void Do() - { - if (m_RemoveOnDo) - remove(); - else - insert(); - } - virtual void Undo() - { - if (m_RemoveOnDo) - insert(); - else - remove(); - } - virtual TObjPtr GetEditor() { return m_EditorObject; } -}; - -struct SEditorEntry -{ - TEditorPtr m_Editor; - TEditorStr m_Id; - TEditorStr m_FilePath; -}; - -template -SDatamodelValue ParseInitialProperty(const char8_t *inName, IPropertyParser &metaParser, - IPropertyParser &runtimeParser) -{ - Option val = SParserHelper::Parse(inName, runtimeParser); - if (val.isEmpty()) - val = SParserHelper::Parse(inName, metaParser); - if (val.hasValue()) - return SDatamodelValue(*val); - return SDatamodelValue(); -} - -template -SDatamodelValue ParseSlideProperty(const char8_t *inName, IPropertyParser &runtimeParser) -{ - Option val = SParserHelper::Parse(inName, runtimeParser); - if (val.hasValue()) - return *val; - return SDatamodelValue(); -} - -struct DatamodelImpl : public IDatamodel, - public ITransManagerImplListener, - public SVSEditor, - public IEditorCopyPasteListener -{ - TEditorStr m_FilePath; - QT3DSI32 mRefCount; - NVScopedRefCounted m_InputStreamFactory; - eastl::pair, NVScopedRefCounted> m_UIADocument; - nvvector m_UIANamespaces; - bool m_Dirty; - nvvector> m_Elements; - NVScopedRefCounted m_FinderElement; - nvvector m_Editors; - TIdStateMapMap m_IdToStateMaps; - eastl::vector m_Presentations; - nvvector m_ParseBuf; - Q3DStudio::TAttOrArgList m_SlideProperties; - eastl::string m_LoadingErrorString; - IStateMachineEditorManager &m_StateMachineEditorManager; - - DatamodelImpl(TFoundationPtr inFoundation, const TEditorStr &inPath, const TEditorStr &inAppDir, - IStateMachineEditorManager &inStateMachineEditorManager, - IStringTable &inStringTable) - : SVSEditor(inFoundation, inStringTable) - , m_FilePath(inPath) - , mRefCount(0) - , m_InputStreamFactory(IInputStreamFactory::Create(m_Foundation->getFoundation())) - , m_UIANamespaces(m_Foundation->getAllocator(), "m_UIANamespaces") - , m_Dirty(false) - , m_Elements(m_Foundation->getAllocator(), "m_Elements") - , m_Editors(m_Foundation->getAllocator(), "m_Editors") - , m_ParseBuf(inFoundation->getAllocator(), "tempbuf") - , m_StateMachineEditorManager(inStateMachineEditorManager) - { - TEditorStr ext; - CFileTools::GetExtension(m_FilePath.c_str(), ext); - if (ext.comparei("uia") != 0) { - m_FilePath = IApplication::GetLaunchFile(inPath.c_str()); - } - // Check extension, if it isn't what we expect then just set it to uia - ext.clear(); - CFileTools::GetExtension(m_FilePath.c_str(), ext); - if (ext.comparei("uia") != 0) - CFileTools::SetExtension(m_FilePath, "uia"); - - m_InputStreamFactory->AddSearchDirectory(inAppDir.c_str()); - - m_TransactionManager->m_ObjListener = this; - } - - ~DatamodelImpl() {} - - void addRef() { atomicIncrement(&mRefCount); } - - void release() - { - TFoundationPtr tempFoundation(m_Foundation); - atomicDecrement(&mRefCount); - if (mRefCount <= 0) { - NVDelete(m_Foundation->getAllocator(), this); - } - } - typedef eastl::map TIdHandlerMap; - typedef eastl::map TIdVisualEventMap; - typedef eastl::map> TIdElemMap; - - SAppElement &ParseElement(IDOMReader &inReader, Q3DStudio::IRuntimeMetaData &inMetaData, - eastl::vector> &ioChildList, - TIdElemMap &ioElemMap) - { - IDOMReader::Scope __elemScope(inReader); - const char8_t *className = inReader.GetElementName(); - const char8_t *classRef; - inReader.UnregisteredAtt("class", classRef); - const char8_t *id; - inReader.UnregisteredAtt("id", id); - Q3DStudio::SElementInfo elemInfo = inMetaData.LoadElement(className, classRef, id); - NVScopedRefCounted newElem; - if (elemInfo.m_ClassName.compare("Behavior") == 0) { - SAppBehavior *behavior = new SAppBehavior(); - behavior->m_Handlers = inMetaData.GetCustomHandlers(id); - newElem = behavior; - } else if (elemInfo.m_IsComponent) { - SAppComponent *component = new SAppComponent(); - newElem = component; - } else { - newElem = new SAppElement(); - } - newElem->m_Attributes = elemInfo.m_Attributes; - newElem->m_VisualEvents = inMetaData.GetVisualEvents(id); - newElem->m_Type = elemInfo.m_ClassName; - newElem->m_Id = id; - const char8_t *elemName; - if (inReader.UnregisteredAtt("name", elemName)) - newElem->m_Name.assign(elemName); - else { - Q3DStudio::TRuntimeMetaDataStrType str = inMetaData.GetPropertyValueString( - inMetaData.Register(className), inMetaData.Register("name"), - inMetaData.Register(id)); - newElem->m_Name = str; - } - - ioChildList.push_back(newElem); - m_Elements.push_back(newElem); - ioElemMap.insert(eastl::make_pair(TEditorStr(id), newElem)); - { - SMetaPropertyParser theMetaParser(newElem->m_Type.c_str(), classRef, inMetaData, - inMetaData.GetStringTable()->GetRenderStringTable()); - SDomReaderPropertyParser theDOMParser(inReader, m_ParseBuf, inReader.m_TempBuf); - for (size_t idx = 0, end = newElem->m_Attributes.size(); idx < end; ++idx) { - const SAttOrArg &theAtt(newElem->m_Attributes[idx]); - SDatamodelValue newValue; - switch (theAtt.m_DataType) { - case ERuntimeDataModelDataTypeFloat: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, - theDOMParser); - break; - case ERuntimeDataModelDataTypeFloat2: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, - theDOMParser); - break; - case ERuntimeDataModelDataTypeFloat3: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, - theDOMParser); - break; - case ERuntimeDataModelDataTypeLong: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, - theDOMParser); - break; - case ERuntimeDataModelDataTypeString: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), - theMetaParser, theDOMParser); - break; - case ERuntimeDataModelDataTypeBool: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, - theDOMParser); - break; - case ERuntimeDataModelDataTypeStringRef: - newValue = ParseInitialProperty(theAtt.m_Name.c_str(), - theMetaParser, theDOMParser); - break; - case ERuntimeDataModelDataTypeObjectRef: - newValue = - ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); - break; - default: - break; - } - newElem->m_InitialValues.push_back(newValue); - } - } - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) - ParseElement(inReader, inMetaData, newElem->m_Children, ioElemMap); - - return *newElem; - } - - // Get the item names if not overridden - // Pull the names off so we can construct the item path. - void LoadSlide(IDOMReader &inReader, TIdElemMap &inMap) - { - IDOMReader::Scope __topScope(inReader); - for (bool commandSuccess = inReader.MoveToFirstChild(); commandSuccess; - commandSuccess = inReader.MoveToNextSibling()) { - IDOMReader::Scope __commandScope(inReader); - const char8_t *elemName = inReader.GetElementName(); - if (AreEqual(elemName, "Set") || AreEqual(elemName, "Add")) { - const char8_t *name; - TIdElemMap::iterator iter = inMap.end(); - const char8_t *itemRef; - inReader.UnregisteredAtt("ref", itemRef); - if (!isTrivial(itemRef)) { - if (itemRef[0] == '#') - ++itemRef; - iter = inMap.find(TEditorStr(itemRef)); - } - - if (inReader.UnregisteredAtt("name", name)) { - if (iter != inMap.end()) { - iter->second->m_Name.assign(name); - } else { - QT3DS_ASSERT(false); - } - } - if (iter != inMap.end() && AreEqual(elemName, "Add")) { - nvvector theTempBuf(this->m_Foundation->getAllocator(), "tempbuf"); - SDomReaderPropertyParser theDOMParser(inReader, m_ParseBuf, inReader.m_TempBuf); - SAppElement *newElem = iter->second.mPtr; - for (size_t idx = 0, end = newElem->m_Attributes.size(); idx < end; ++idx) { - const SAttOrArg &theAtt(newElem->m_Attributes[idx]); - SDatamodelValue newValue; - switch (theAtt.m_DataType) { - case ERuntimeDataModelDataTypeFloat: - newValue = - ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); - break; - case ERuntimeDataModelDataTypeFloat2: - newValue = - ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); - break; - case ERuntimeDataModelDataTypeFloat3: - newValue = - ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); - break; - case ERuntimeDataModelDataTypeLong: - newValue = - ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); - break; - case ERuntimeDataModelDataTypeString: - newValue = ParseSlideProperty(theAtt.m_Name.c_str(), - theDOMParser); - break; - case ERuntimeDataModelDataTypeBool: - newValue = - ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); - break; - case ERuntimeDataModelDataTypeStringRef: - newValue = ParseSlideProperty(theAtt.m_Name.c_str(), - theDOMParser); - break; - case ERuntimeDataModelDataTypeObjectRef: - newValue = ParseSlideProperty(theAtt.m_Name.c_str(), - theDOMParser); - break; - default: - break; - } - if (newValue.getType() != ERuntimeDataModelDataTypeNone) - newElem->m_InitialValues[idx] = newValue; - } - } - } - } - } - - void ResolveElemPath(SAppElement &inElem, const eastl::string &parentId) - { - inElem.m_Path = parentId; - if (inElem.m_Path.back() != ':') - inElem.m_Path.append(1, '.'); - inElem.m_Path.append(inElem.m_Name); - for (size_t idx = 0, end = inElem.m_Children.size(); idx < end; ++idx) - ResolveElemPath(*inElem.m_Children[idx], inElem.m_Path); - } - - void LoadUIPFile(const char *inRelativePath, const char *inUIPId, - Q3DStudio::IRuntimeMetaData &inMetaData) - { - eastl::string appDir(m_FilePath); - CFileTools::GetDirectory(appDir); - eastl::string uipPath; - CFileTools::CombineBaseAndRelative(appDir.c_str(), inRelativePath, uipPath); - CFileSeekableIOStream uipStream(uipPath.c_str(), FileReadFlags()); - if (!uipStream.IsOpen()) { - QT3DS_ASSERT(false); - return; - } - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_Foundation->getAllocator(), m_StringTable)); - SDOMElement *domElem = CDOMSerializer::Read(*theFactory, uipStream).second; - if (!domElem) { - QT3DS_ASSERT(false); - return; - } - - NVScopedRefCounted theReader(IDOMReader::CreateDOMReader( - m_Foundation->getAllocator(), *domElem, m_StringTable, theFactory)); - if (!theReader->MoveToFirstChild("Project")) { - QT3DS_ASSERT(false); - return; - } - - Q3DStudio::IRuntimeMetaData &theMetaData(inMetaData); - theMetaData.ClearPerProjectData(); - - TEditorStr rootPath(inUIPId); - rootPath.append(1, ':'); - eastl::vector> topElements; - TIdElemMap idElemMap; - m_Presentations.push_back(SPresentation()); - SPresentation ¤tPresentation(m_Presentations.back()); - currentPresentation.m_Id.assign(inUIPId); - currentPresentation.m_SrcPath.assign(inRelativePath); - { - IDOMReader::Scope __projectScope(*theReader); - if (theReader->MoveToFirstChild("ProjectSettings")) { - const char8_t *temp; - theReader->UnregisteredAtt("author", temp); - currentPresentation.m_Author.assign(nonNull(temp)); - theReader->UnregisteredAtt("company", temp); - currentPresentation.m_Company.assign(nonNull(temp)); - theReader->Att("presentationWidth", currentPresentation.m_Width); - theReader->Att("presentationHeight", currentPresentation.m_Height); - } - // Presentation width and height as specified in the file. - } - // Classes/handlers - { - IDOMReader::Scope __projectScope(*theReader); - if (theReader->MoveToFirstChild("Classes")) { - // Load each class system into the meta data and then pull back the handlers - for (bool success = theReader->MoveToFirstChild(); success; - success = theReader->MoveToNextSibling()) { - const char8_t *id, *srcPath, *name; - theReader->UnregisteredAtt("id", id); - theReader->UnregisteredAtt("sourcepath", srcPath); - theReader->UnregisteredAtt("name", name); - eastl::string classItemPath; - CFileTools::CombineBaseAndRelative(appDir.c_str(), srcPath, classItemPath); - - if (AreEqual(theReader->GetElementName().c_str(), "Behavior")) { - bool theScriptFile = - theMetaData.LoadScriptFile("Behavior", id, name, classItemPath.c_str()); - QT3DS_ASSERT(theScriptFile); - (void)theScriptFile; - } else if (AreEqual(theReader->GetElementName().c_str(), "Effect")) { - bool theEffectFile = theMetaData.LoadEffectXMLFile("Effect", id, name, - classItemPath.c_str()); - QT3DS_ASSERT(theEffectFile); - (void)theEffectFile; - } else if (AreEqual(theReader->GetElementName().c_str(), "RenderPlugin")) { - theMetaData.LoadPluginXMLFile("RenderPlugin", id, name, - classItemPath.c_str()); - } else if (AreEqual(theReader->GetElementName().c_str(), "CustomMaterial")) { - theMetaData.LoadMaterialXMLFile("CustomMaterial", id, name, - classItemPath.c_str()); - } else { - QT3DS_ASSERT(false); - } - } - } - } - - // Graph - { - IDOMReader::Scope __projectScope(*theReader); - if (theReader->MoveToFirstChild("Graph")) { - for (bool success = theReader->MoveToFirstChild(); success; - success = theReader->MoveToNextSibling()) { - currentPresentation.m_Scene = - &ParseElement(*theReader, theMetaData, topElements, idElemMap); - } - } - } - // States/Slides - { - // This is where the name *may* be set, - IDOMReader::Scope __projectScope(*theReader); - if (theReader->MoveToFirstChild("Logic")) { - // Slides are just slightly hierarchical, master and then nonmaster children. - for (bool success = theReader->MoveToFirstChild(); success; - success = theReader->MoveToNextSibling()) { - IDOMReader::Scope __masterScope(*theReader); - LoadSlide(*theReader, idElemMap); - const char8_t *component; - theReader->UnregisteredAtt("component", component); - NVScopedRefCounted theComponent; - if (!isTrivial(component)) { - if (component[0] == '#') - ++component; - TIdElemMap::iterator iter = idElemMap.find(TEditorStr(component)); - if (iter != idElemMap.end()) { - if (iter->second->GetSubType() == ElementSubTypes::Component) - theComponent = static_cast(iter->second.mPtr); - else { - QT3DS_ASSERT(false); - } - } else { - QT3DS_ASSERT(false); - } - } - - for (bool childSuccess = theReader->MoveToFirstChild("State"); childSuccess; - childSuccess = theReader->MoveToNextSibling("State")) { - IDOMReader::Scope __slideScope(*theReader); - const char8_t *slideName; - if (theReader->UnregisteredAtt("name", slideName)) - theComponent->m_Slides.push_back(TEditorStr(slideName)); - LoadSlide(*theReader, idElemMap); - } - } - } - } - // Now resolve all the names to create full paths. - for (size_t idx = 0, end = topElements.size(); idx < end; ++idx) { - ResolveElemPath(*topElements[idx], rootPath); - } - } - - struct SElemLessThan - { - bool operator()(NVScopedRefCounted lhs, - NVScopedRefCounted rhs) const - { - return lhs->m_Path < rhs->m_Path; - } - }; - - static const char *GetNamespace() { return "http://qt.io/qt3dstudio/uia"; } - static const char *GetOldNamespace() { return "http://qt.io/qt3dstudio/uicomposer"; } - - void LoadUIADatabase() - { - CFileSeekableIOStream theStream(m_FilePath.c_str(), FileReadFlags()); - if (theStream.IsOpen()) { - LoadUIADatabaseFromStream(theStream); - } - } - - struct SXmlErrorHandler : public CXmlErrorHandler - { - SXmlErrorHandler(const eastl::string &inFilePath, eastl::string &inErrorString) - : m_FilePath(inFilePath) - , m_ErrorString(inErrorString) - { - } - virtual ~SXmlErrorHandler() {} - virtual void OnXmlError(TXMLCharPtr errorName, int line, int column) - { - if (m_ErrorString.empty()) - m_ErrorString.sprintf("%s(%d, %d): %s", m_FilePath.c_str(), line, column, - errorName); - } - eastl::string m_FilePath; - eastl::string &m_ErrorString; - }; - - void LoadUIADatabaseFromStream(IInStream &inStream) - { - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_Foundation->getAllocator(), m_StringTable)); - m_UIADocument.first = NULL; - m_UIADocument.second = NULL; - m_UIANamespaces.clear(); - m_Elements.clear(); - m_IdToStateMaps.clear(); - m_Editors.clear(); - m_Presentations.clear(); - m_SlideProperties.clear(); - m_LoadingErrorString.clear(); - eastl::string appDir(m_FilePath); - CFileTools::GetDirectory(appDir); - - SXmlErrorHandler theXmlErrorWriter(m_FilePath, m_LoadingErrorString); - eastl::pair parseResult = - CDOMSerializer::Read(*theFactory, inStream, &theXmlErrorWriter); - if (parseResult.second != NULL) { - qt3ds::foundation::CRegisteredString theRegisteredOldNamespace = - m_StringTable->RegisterStr(GetOldNamespace()); - qt3ds::foundation::CRegisteredString theRegisteredNamespace = - m_StringTable->RegisterStr(GetNamespace()); - - ReplaceDOMNamespace(*parseResult.second, theRegisteredOldNamespace, - theRegisteredNamespace); - - m_UIADocument = - IDOMWriter::CreateDOMWriter(theFactory, *parseResult.second, m_StringTable); - for (SNamespacePairNode *nodePtr = parseResult.first; nodePtr; - nodePtr = nodePtr->m_NextNode) { - if (nodePtr->m_Namespace == theRegisteredOldNamespace) - nodePtr->m_Namespace = theRegisteredNamespace; - m_UIANamespaces.push_back(*nodePtr); - } - } - - if (m_UIADocument.first.mPtr == NULL) { - m_UIADocument = IDOMWriter::CreateDOMWriter(m_Foundation->getAllocator(), "application", - m_StringTable, GetNamespace()); - m_Dirty = true; - } - if (m_UIANamespaces.empty()) - m_UIANamespaces.push_back( - SNamespacePair(m_StringTable->RegisterStr(GetNamespace()))); - - { - NVScopedReleasable theMetaData( - Q3DStudio::IRuntimeMetaData::Create(*m_InputStreamFactory)); - - if (theMetaData) { - m_SlideProperties = theMetaData->GetSlideAttributes(); - - eastl::vector> machinePathsAndIds; - IDOMReader::Scope __appScope(m_UIADocument.second); - - if (m_UIADocument.second->MoveToFirstChild("assets")) { - IDOMReader::Scope __assetsScope(m_UIADocument.second); - for (bool success = m_UIADocument.second->MoveToFirstChild(); success; - success = m_UIADocument.second->MoveToNextSibling()) { - IDOMReader::Scope __assetScope(m_UIADocument.second); - const char8_t *elemName = m_UIADocument.second->GetElementName(); - if (AreEqual(elemName, "presentation")) { - const char8_t *id, *relativePath; - m_UIADocument.second->UnregisteredAtt("id", id); - m_UIADocument.second->UnregisteredAtt("src", relativePath); - LoadUIPFile(relativePath, id, *theMetaData); - } else if (AreEqual(elemName, "statemachine")) { - const char8_t *id, *relativePath; - m_UIADocument.second->UnregisteredAtt("id", id); - m_UIADocument.second->UnregisteredAtt("src", relativePath); - TEditorStr fullPath; - CFileTools::CombineBaseAndRelative(appDir.c_str(), relativePath, - fullPath); - CreateSCXMLEditor(fullPath, nonNull(id)); - } - } - } - - // Now sort our list of elements by path after we have loaded all uip files. - eastl::sort(m_Elements.begin(), m_Elements.end(), SElemLessThan()); - } else { - QT3DS_ASSERT(false); - } - } - { - IDOMReader::Scope __appScope(m_UIADocument.second); - for (bool success = m_UIADocument.second->MoveToFirstChild("statemachine"); success; - success = m_UIADocument.second->MoveToNextSibling("statemachine")) { - IDOMReader::Scope __machineScope(m_UIADocument.second); - const char8_t *idref; - m_UIADocument.second->UnregisteredAtt("ref", idref); - if (!isTrivial(idref)) { - if (idref[0] == '#') - ++idref; - for (size_t idx = 0, end = m_Editors.size(); idx < end; ++idx) { - if (m_Editors[idx].m_Id.compare(idref) == 0) - ParseStateMachine(m_Editors[idx].m_Id, m_Editors[idx].m_Editor); - } - } - } - } - } - - virtual bool IsDirty() const { return m_Dirty; } - // General queries of the dataset defined by the uia file and all uip files and scxml files it - // includes. - - SAppElement *FindElementByPath(const TEditorStr &inPath) - { - if (!m_FinderElement) - m_FinderElement = new SAppElement(); - - m_FinderElement->m_Path = inPath; - - nvvector>::iterator iter = eastl::lower_bound( - m_Elements.begin(), m_Elements.end(), m_FinderElement, SElemLessThan()); - if (iter != m_Elements.end() && (*iter)->m_Path == m_FinderElement->m_Path) { - return iter->mPtr; - } - return NVScopedRefCounted(); - } - - virtual TEditorStrList GetComponents() - { - TEditorStrList retval; - for (size_t idx = 0, end = m_Elements.size(); idx < end; ++idx) { - if (m_Elements[idx]->GetSubType() == ElementSubTypes::Component) - retval.push_back(m_Elements[idx]->m_Path); - } - return retval; - } - - virtual TEditorStrList GetComponentSlides(const TEditorStr &inComponent) - { - SAppElement *elem = FindElementByPath(inComponent); - if (elem != NULL && elem->GetSubType() == ElementSubTypes::Component) - return static_cast(elem)->m_Slides; - return TEditorStrList(); - } - - virtual TEditorStrList GetBehaviors() - { - TEditorStrList retval; - for (size_t idx = 0, end = m_Elements.size(); idx < end; ++idx) { - if (m_Elements[idx]->GetSubType() == ElementSubTypes::Behavior) - retval.push_back(m_Elements[idx]->m_Path); - } - return retval; - } - - virtual Q3DStudio::THandlerList GetHandlers(const TEditorStr &inBehavior) - { - SAppElement *elem = FindElementByPath(inBehavior); - if (elem != NULL && elem->GetSubType() == ElementSubTypes::Behavior) - return static_cast(elem)->m_Handlers; - return Q3DStudio::THandlerList(); - } - - virtual Q3DStudio::TVisualEventList GetVisualEvents(const TEditorStr &inElement) - { - SAppElement *elem = FindElementByPath(inElement); - if (elem) - return elem->m_VisualEvents; - return Q3DStudio::TVisualEventList(); - } - - virtual TEditorStrList GetElements() - { - TEditorStrList retval; - for (size_t idx = 0, end = m_Elements.size(); idx < end; ++idx) - retval.push_back(m_Elements[idx]->m_Path); - return retval; - } - - virtual Q3DStudio::TAttOrArgList GetElementAttributes(const TEditorStr &inElement) - { - SAppElement *elem = FindElementByPath(inElement); - if (elem) - return elem->m_Attributes; - return Q3DStudio::TAttOrArgList(); - } - - TEditorPtr CreateSCXMLEditor(const TEditorStr &inPath, const TEditorStr &inId) - { - TEditorPtr newEditor = m_StateMachineEditorManager.GetOrCreateEditor(inPath, 0); - if (newEditor) { - SEditorEntry theEntry; - theEntry.m_Editor = newEditor.mPtr; - theEntry.m_FilePath = inPath; - theEntry.m_Id = inId; - m_Editors.push_back(theEntry); - } - return newEditor.mPtr; - } - - virtual TEditorPtr GetOrCreateEditor(const TEditorStr &inFullPath, bool *outLoadStatus) - { - (void)outLoadStatus; - TEditorStr normalizedPath(inFullPath); - CFileTools::NormalizePath(normalizedPath); - for (size_t idx = 0, end = m_Editors.size(); idx < end; ++idx) { - if (m_Editors[idx].m_FilePath == normalizedPath) - return m_Editors[idx].m_Editor; - } - - // Is file full path under our application directory; - TEditorStr appDir(m_FilePath); - CFileTools::GetDirectory(appDir); - TEditorStr editorDir(inFullPath); - CFileTools::GetDirectory(editorDir); - - // For scxml files outside our app dir, let the user create an editor manually. - // We will have nothing to do with it. - if (editorDir.find(appDir) == eastl::string::npos) - return TEditorPtr(); - - // Get an ID for the editor - IDOMReader::Scope __appScope(*m_UIADocument.second); - if (!m_UIADocument.second->MoveToFirstChild("assets")) { - m_UIADocument.first->Begin("assets", GetNamespace()); - } - - { - IDOMReader::Scope __assetsScope(*m_UIADocument.second); - for (bool success = m_UIADocument.second->MoveToFirstChild("statemachine"); success; - success = m_UIADocument.second->MoveToNextSibling("statemachine")) { - const char8_t *srcPath; - const char8_t *id; - m_UIADocument.second->UnregisteredAtt("src", srcPath); - m_UIADocument.second->UnregisteredAtt("id", id); - TEditorStr docPath; - CFileTools::CombineBaseAndRelative(appDir.c_str(), srcPath, docPath); - CFileTools::NormalizePath(docPath); - if (docPath == normalizedPath) { - return CreateSCXMLEditor(normalizedPath, nonNull(id)); - } - } - } - - eastl::string dirname, fname, extension; - CFileTools::Split(normalizedPath.c_str(), dirname, fname, extension); - m_UIADocument.first->Begin("statemachine", GetNamespace()); - m_UIADocument.first->Att("id", fname.c_str(), GetNamespace()); - eastl::string relativePath; - CFileTools::GetRelativeFromBase(appDir, normalizedPath, relativePath); - m_UIADocument.first->Att("src", relativePath.c_str()); - m_Dirty = true; - return CreateSCXMLEditor(normalizedPath, nonNull(fname.c_str())); - } - - static bool CouldHaveVisualStateExecutableContent(TObjPtr inObject) - { - return inObject->GetExecutableContentTypes().size() > 0; - } - template - TEditorType &CreateEditor(TObjPtr inParent) - { - TPropertyAccessorList accessors; - TEditorType::CreateProperties(accessors, *this); - return *QT3DS_NEW(m_Foundation->getAllocator(), TEditorType)(*this, inParent, accessors); - } - - SVSEntry *GetEntryForPair(TEntryExitPair &inPair, InterpreterEventTypes::Enum inType) - { - SVSEntry *theEntry; - if (inType == InterpreterEventTypes::StateEnter - || inType == InterpreterEventTypes::Transition) { - if (inPair.first == NULL) - inPair.first = new SVSEntry(inType); - theEntry = inPair.first.mPtr; - } else { - if (inPair.second == NULL) - inPair.second = new SVSEntry(inType); - theEntry = inPair.second.mPtr; - } - return theEntry; - } - - void ParseExecutableContent(IDOMReader &inReader, const TEditorStr &inId, - TIdEntryExitMap &ioMap, InterpreterEventTypes::Enum inType, - TObjPtr parentPtr) - { - IDOMReader::Scope __contentScope(inReader); - { - IDOMReader::Scope __testScope(inReader); - // See if there is any executable content to begin with. - if (inReader.MoveToFirstChild() == false) - return; - } - - TEntryExitPair &thePair = - ioMap.insert(eastl::make_pair(inId, TEntryExitPair())).first->second; - SVSEntry *theEntry = GetEntryForPair(thePair, inType); - QT3DS_ASSERT(theEntry->m_EventType == inType); - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - IDOMReader::Scope __elemScope(inReader); - const char8_t *elemName(inReader.GetElementName()); - if (AreEqual(elemName, SGotoSlideEditor::ElementName())) { - const char8_t *component, *slide, *rel, *wrap, *direction, *state, *mode, - *playthroughto, *rate, *time; - inReader.UnregisteredAtt("element", component); - if (inReader.UnregisteredAtt("slide", slide) == false) - inReader.UnregisteredAtt("rel", rel); - else - rel = ""; - inReader.UnregisteredAtt("wrap", wrap); - inReader.UnregisteredAtt("direction", direction); - inReader.UnregisteredAtt("state", state); - inReader.UnregisteredAtt("mode", mode); - inReader.UnregisteredAtt("playthroughto", playthroughto); - inReader.UnregisteredAtt("rate", rate); - inReader.UnregisteredAtt("time", time); - SGotoSlideEditor &theEditor = CreateEditor(parentPtr); - theEditor.m_Component.assign(nonNull(component)); - theEditor.m_Slide.assign(nonNull(slide)); - theEditor.m_Rel.assign(nonNull(rel)); - theEditor.m_Wrap.assign(nonNull(wrap)); - theEditor.m_Direction.assign(nonNull(direction)); - theEditor.m_State.assign(nonNull(state)); - theEditor.m_Mode.assign(nonNull(mode)); - theEditor.m_PlayThroughTo.assign(nonNull(playthroughto)); - theEditor.m_Rate.assign(nonNull(rate)); - theEditor.m_Time.assign(nonNull(time)); - theEntry->m_Editors.push_back(theEditor); - } else if (AreEqual(elemName, SSetAttributeEditor::ElementName())) { - const char8_t *element, *att, *val; - inReader.UnregisteredAtt("element", element); - inReader.UnregisteredAtt("attribute", att); - inReader.UnregisteredAtt("value", val); - SSetAttributeEditor &theEditor = CreateEditor(parentPtr); - theEditor.m_Element.assign(nonNull(element)); - theEditor.m_Attribute.assign(nonNull(att)); - theEditor.m_Value.assign(nonNull(val)); - theEntry->m_Editors.push_back(theEditor); - } else if (AreEqual(elemName, SFireEventEditor::ElementName())) { - const char8_t *element, *evt; - inReader.UnregisteredAtt("element", element); - inReader.UnregisteredAtt("event", evt); - SFireEventEditor &theEditor = CreateEditor(parentPtr); - theEditor.m_Element.assign(nonNull(element)); - theEditor.m_Event.assign(nonNull(evt)); - theEntry->m_Editors.push_back(theEditor); - } else if (AreEqual(elemName, SRunHandlerEditor::ElementName())) { - const char8_t *element, *handler, *args; - inReader.UnregisteredAtt("element", element); - inReader.UnregisteredAtt("handler", handler); - inReader.UnregisteredAtt("arguments", args); - SRunHandlerEditor &theEditor = CreateEditor(parentPtr); - theEditor.m_Behavior.assign(nonNull(element)); - theEditor.m_Handler.assign(nonNull(handler)); - theEditor.m_ArgumentStr.assign(nonNull(args)); - theEntry->m_Editors.push_back(theEditor); - } else if (AreEqual(elemName, SSetPresentationEditor::ElementName())) { - const char8_t *ref, *attribute, *value; - inReader.UnregisteredAtt("ref", ref); - inReader.UnregisteredAtt("attribute", attribute); - inReader.UnregisteredAtt("value", value); - SSetPresentationEditor &theEditor = CreateEditor(parentPtr); - theEditor.m_Ref.assign(nonNull(ref)); - theEditor.m_Attribute.assign(nonNull(attribute)); - theEditor.m_Value.assign(nonNull(value)); - theEntry->m_Editors.push_back(theEditor); - } else if (AreEqual(elemName, SPlaySoundEditor::ElementName())) { - const char8_t *file; - inReader.UnregisteredAtt("file", file); - SPlaySoundEditor &theEditor = CreateEditor(parentPtr); - theEditor.m_FilePath.assign(nonNull(file)); - theEntry->m_Editors.push_back(theEditor); - } - } - } - - void ParseVisualStateEntry(IDOMReader &inReader, TEditorPtr inEditor, TIdEntryExitMap &retval, - const char8_t *stateId) - { - TObjPtr parentPtr = inEditor->GetObjectById(stateId); - if (parentPtr) { - if (AreEqual(inReader.GetElementName().c_str(), "state")) { - for (bool entryExitSucces = inReader.MoveToFirstChild(); entryExitSucces; - entryExitSucces = inReader.MoveToNextSibling()) { - const char8_t *signalName(inReader.GetElementName()); - if (AreEqual(signalName, "enter")) { - ParseExecutableContent(inReader, stateId, retval, - InterpreterEventTypes::StateEnter, parentPtr); - } else if (AreEqual(signalName, "exit")) { - ParseExecutableContent(inReader, stateId, retval, - InterpreterEventTypes::StateExit, parentPtr); - } else { - QT3DS_ASSERT(false); - } - } - } else if (AreEqual(inReader.GetElementName().c_str(), "transition")) { - ParseExecutableContent(inReader, stateId, retval, InterpreterEventTypes::Transition, - parentPtr); - } else { - QT3DS_ASSERT(false); - } - } - } - - TIdEntryExitMap &ParseStateMachine(const TEditorStr &inId, TEditorPtr inEditor) - { - TIdEntryExitMap &retval = - m_IdToStateMaps.insert(eastl::make_pair(inId, TIdEntryExitMap())).first->second; - if (m_UIADocument.second->MoveToFirstChild("visual-states")) { - for (bool stateSuccess = m_UIADocument.second->MoveToFirstChild(); stateSuccess; - stateSuccess = m_UIADocument.second->MoveToNextSibling()) { - IDOMReader::Scope __stateScope(*m_UIADocument.second); - const char8_t *stateId; - m_UIADocument.second->UnregisteredAtt("ref", stateId); - if (!isTrivial(stateId)) { - if (stateId[0] == '#') - ++stateId; - - ParseVisualStateEntry(*m_UIADocument.second, inEditor, retval, stateId); - } - } - } - return retval; // found a statemachine with the right id. - } - - TIdEntryExitMap &GetOrCreateStateMap(const TEditorStr &inId, TEditorPtr inEditor) - { - TIdEntryExitMap &retval = - m_IdToStateMaps.insert(eastl::make_pair(inId, TIdEntryExitMap())).first->second; - - if (retval.empty()) { - IDOMReader::Scope __appScope(*m_UIADocument.second); - for (bool success = m_UIADocument.second->MoveToFirstChild("statemachine"); - success && retval.empty(); - success = m_UIADocument.second->MoveToNextSibling("statemachine")) { - IDOMReader::Scope __machineScope(*m_UIADocument.second); - const char8_t *idref; - m_UIADocument.second->UnregisteredAtt("ref", idref); - if (!isTrivial(idref)) { - if (idref[0] == '#') - ++idref; - if (inId.compare(idref) == 0) { - return ParseStateMachine(inId, inEditor); - } - } - } // for (statemachines) - } - - return retval; - } - - TIdEntryExitMap *GetStateMapForObject(TObjPtr inObject) - { - if (!CouldHaveVisualStateExecutableContent(inObject)) - return NULL; - - TEditorPtr theEditor = inObject->GetEditor(); - // Find the id for the editor - TIdEntryExitMap *stateMap(NULL); - - for (size_t idx = 0, end = m_Editors.size(); idx < end && stateMap == NULL; ++idx) { - if (m_Editors[idx].m_Editor == theEditor) - return &GetOrCreateStateMap(m_Editors[idx].m_Id, m_Editors[idx].m_Editor); - } - return NULL; - } - - // The editor obj has a remove from graph function that really is delete - virtual TObjList GetVisualStateExecutableContent(TObjPtr inObject, - InterpreterEventTypes::Enum inEventType) - { - TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); - if (stateMap == NULL) - return TObjList(); - - TEditorStr objId(inObject->GetId()); - TIdEntryExitMap::iterator iter = stateMap->find(objId); - for (TIdEntryExitMap::iterator temp = stateMap->begin(), end = stateMap->end(); temp != end; - ++temp) { - objId = temp->first; - objId.clear(); - } - if (iter != stateMap->end()) { - TEntryExitPair thePair = iter->second; - if (thePair.first && thePair.first->m_EventType == inEventType) - return thePair.first->m_Editors; - else if (thePair.second && thePair.second->m_EventType == inEventType) - return thePair.second->m_Editors; - } - - return TObjList(); - } - - // Type name is the element name, so set-attribute, goto-slide, or fire-event - virtual TObjPtr AppendVisualStateExecutableContent(TObjPtr inObject, - InterpreterEventTypes::Enum inEventType, - const char8_t *inElementName) - { - TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); - if (stateMap == NULL) - return TObjPtr(); - - NVConstDataRef supportedTypes = - inObject->GetExecutableContentTypes(); - bool foundEventType = false; - for (size_t idx = 0, end = supportedTypes.size(); idx < end && foundEventType == false; - ++idx) - if (inEventType == supportedTypes[idx]) - foundEventType = true; - - if (foundEventType == false) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - - TEntryExitPair &thePair = - stateMap->insert(eastl::make_pair(inObject->GetId(), TEntryExitPair())).first->second; - SVSEntry *entry = GetEntryForPair(thePair, inEventType); - if (!entry) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - - if (AreEqual(inElementName, SGotoSlideEditor::ElementName())) { - entry->m_Editors.push_back(CreateEditor(inObject)); - } else if (AreEqual(inElementName, SRunHandlerEditor::ElementName())) { - entry->m_Editors.push_back(CreateEditor(inObject)); - } else if (AreEqual(inElementName, SSetAttributeEditor::ElementName())) { - entry->m_Editors.push_back(CreateEditor(inObject)); - } else if (AreEqual(inElementName, SFireEventEditor::ElementName())) { - entry->m_Editors.push_back(CreateEditor(inObject)); - } else if (AreEqual(inElementName, SSetPresentationEditor::ElementName())) { - entry->m_Editors.push_back(CreateEditor(inObject)); - } else if (AreEqual(inElementName, SPlaySoundEditor::ElementName())) { - entry->m_Editors.push_back(CreateEditor(inObject)); - } else { - QT3DS_ASSERT(false); - return TObjPtr(); - } - TObjPtr retval = entry->m_Editors.back(); - STransaction *theTrans = GetOpenTransactionImpl(); - if (theTrans) { - SVSEntryListChange *theChange = - new SVSEntryListChange(TObjPtr(), retval, *entry, true, inObject); - theTrans->m_Changes.push_back(theChange); - } - return retval; - } - - virtual TObjPtr ChangeVisualStateExecutableContentName(TObjPtr inContent, - const char8_t *inElementName) - { - TObjPtr theParent = inContent->Parent(); - if (!CouldHaveVisualStateExecutableContent(theParent)) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - TIdEntryExitMap *stateMap = GetStateMapForObject(theParent); - if (stateMap == NULL) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - - TIdEntryExitMap::iterator iter = stateMap->find(theParent->GetId()); - if (iter == stateMap->end()) { - QT3DS_ASSERT(false); - return TObjPtr(); - } - TEntryExitPair thePair = iter->second; - NVScopedRefCounted theEntryFound; - if (!theEntryFound) { - NVScopedRefCounted theEntry = thePair.first; - TObjPtr theObj = inContent; - if (theEntry) { - TObjList::iterator iter = - eastl::find(theEntry->m_Editors.begin(), theEntry->m_Editors.end(), theObj); - if (iter != theEntry->m_Editors.end()) { - theEntryFound = theEntry; - } - } - } - if (!theEntryFound) { - NVScopedRefCounted theEntry = thePair.second; - TObjPtr theObj = inContent; - if (theEntry) { - TObjList::iterator iter = - eastl::find(theEntry->m_Editors.begin(), theEntry->m_Editors.end(), theObj); - if (iter != theEntry->m_Editors.end()) { - theEntryFound = theEntry; - } - } - } - if (!theEntryFound) - return TObjPtr(); - - TObjPtr theRetval; - if (AreEqual(inElementName, SGotoSlideEditor::ElementName())) { - theRetval = CreateEditor(theParent); - } else if (AreEqual(inElementName, SRunHandlerEditor::ElementName())) { - theRetval = CreateEditor(theParent); - } else if (AreEqual(inElementName, SSetAttributeEditor::ElementName())) { - theRetval = CreateEditor(theParent); - } else if (AreEqual(inElementName, SFireEventEditor::ElementName())) { - theRetval = CreateEditor(theParent); - } else if (AreEqual(inElementName, SSetPresentationEditor::ElementName())) { - theRetval = CreateEditor(theParent); - } else if (AreEqual(inElementName, SPlaySoundEditor::ElementName())) { - theRetval = CreateEditor(theParent); - } else { - QT3DS_ASSERT(false); - return TObjPtr(); - } - - NVScopedRefCounted theOldChange = - new SVSEntryListChange(inContent, inContent, *theEntryFound, false, theParent); - NVScopedRefCounted theNewChange = - new SVSEntryListChange(theRetval, inContent, *theEntryFound, true, theParent); - theOldChange->Do(); - theNewChange->Do(); - if (GetOpenTransactionImpl()) { - GetOpenTransactionImpl()->m_Changes.push_back(theOldChange.mPtr); - GetOpenTransactionImpl()->m_Changes.push_back(theNewChange.mPtr); - } - - return theRetval; - } - - // Called when the source uia changes. - virtual void RefreshFile() { LoadUIADatabase(); } - - virtual void RefreshFromStream(qt3ds::foundation::IInStream &inStream) - { - LoadUIADatabaseFromStream(inStream); - } - - // Returns the path that was passed in on create. - virtual TEditorStr GetFilePath() { return m_FilePath; } - - void CopyDOM(IDOMReader &inReader, IDOMWriter &inWriter) - { - IDOMReader::Scope __itemScope(inReader); - const SDOMElement &theElement(*inReader.GetElement()); - IDOMWriter::Scope __writeScope(inWriter, theElement.m_Name, theElement.m_Namespace); - if (theElement.m_Attributes.empty() && theElement.m_Children.empty()) { - if (!isTrivial(theElement.m_Value)) - inWriter.Value(theElement.m_Value); - } else { - for (TAttributeList::iterator iter = theElement.m_Attributes.begin(), - end = theElement.m_Attributes.end(); - iter != end; ++iter) { - inWriter.Att(iter->m_Name, iter->m_Value, iter->m_Namespace); - } - - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - IDOMReader::Scope __loopScope(inReader); - CopyDOM(inReader, inWriter); - } - } - } - void ReplaceDOMNamespace(SDOMElement &inDom, - qt3ds::foundation::CRegisteredString &inNamespaceToReplace, - qt3ds::foundation::CRegisteredString &inNewNamespace) - { - if (!inNamespaceToReplace.IsValid() || !inNewNamespace.IsValid()) - return; - if (inDom.m_Namespace == inNamespaceToReplace) - inDom.m_Namespace = inNewNamespace; - // Set attributes namespace - for (qt3ds::foundation::TAttributeList::iterator theIter = inDom.m_Attributes.begin(), - theEnd = inDom.m_Attributes.end(); - theIter != theEnd; ++theIter) { - if (theIter->m_Namespace == inNamespaceToReplace) - theIter->m_Namespace = inNewNamespace; - } - // Recursive - for (qt3ds::foundation::SDOMElement::TElementChildList::iterator - theIter = inDom.m_Children.begin(), - theEnd = inDom.m_Children.end(); - theIter != theEnd; ++theIter) { - ReplaceDOMNamespace(*theIter, inNamespaceToReplace, inNewNamespace); - } - } - struct SEditorIDFinder - { - TEditorStr m_Id; - SEditorIDFinder(const TEditorStr &id) - : m_Id(id) - { - } - bool operator()(const SEditorEntry &entry) const { return m_Id == entry.m_Id; } - }; - - void WriteExecutableContent(IDOMWriter &inWriter, NVScopedRefCounted inEntry) - { - if (inEntry == NULL) - return; - const char *elemName = ""; - switch (inEntry->m_EventType) { - case InterpreterEventTypes::Transition: - break; - case InterpreterEventTypes::StateEnter: - elemName = "enter"; - break; - case InterpreterEventTypes::StateExit: - elemName = "exit"; - break; - default: - QT3DS_ASSERT(false); - break; - } - if (!isTrivial(elemName)) - inWriter.Begin(elemName, GetNamespace()); - - eastl::vector properties; - for (size_t idx = 0, end = inEntry->m_Editors.size(); idx < end; ++idx) { - TObjPtr editor(inEntry->m_Editors[idx]); - IDOMWriter::Scope __contentScope(inWriter, editor->TypeName(), GetNamespace()); - editor->GetProperties(properties); - bool theNoProperty = true; - for (size_t idx = 0, end = properties.size(); idx < end; ++idx) { - TEditorStr theProp = - editor->GetPropertyValue(properties[idx].m_Name)->getData(); - if (theProp.empty() == false) { - inWriter.Att(properties[idx].m_Name.c_str(), theProp.c_str(), - GetNamespace()); - theNoProperty = false; - } - } - if (theNoProperty && properties.size() > 0) - inWriter.Att(properties[0].m_Name.c_str(), "", GetNamespace()); - } - - if (!isTrivial(elemName)) - inWriter.End(); - } - - void WriteStateEntry(TIdEntryExitMap::const_iterator stateIter, IDOMWriter &writer, - const char *typeName, const char *id) - { - const char8_t *stateName = "state"; - if (AreEqual(typeName, "transition")) - stateName = "transition"; - eastl::string tempAtt; - IDOMWriter::Scope __stateScope(writer, stateName, GetNamespace()); - tempAtt.assign("#"); - tempAtt.append(id); - writer.Att("ref", tempAtt.c_str()); - WriteExecutableContent(writer, stateIter->second.first); - WriteExecutableContent(writer, stateIter->second.second); - } - - // Returns false if unable to save, ask users to check the file out. - bool SaveInner(qt3ds::foundation::IOutStream &inStream) - { - IDOMReader::Scope __saveScope(m_UIADocument.second); - NVScopedRefCounted theFactory( - IDOMFactory::CreateDOMFactory(m_Foundation->getAllocator(), m_StringTable)); - NVScopedRefCounted outgoingDoc = - IDOMWriter::CreateDOMWriter(m_Foundation->getAllocator(), "application", m_StringTable, - GetNamespace()) - .first; - { - m_UIADocument.second->MoveToFirstChild("application"); - for (SDOMAttribute *theAtt = m_UIADocument.second->GetFirstAttribute(); theAtt; - theAtt = m_UIADocument.second->GetNextAttribute()) { - outgoingDoc->Att(theAtt->m_Name, theAtt->m_Value, theAtt->m_Namespace); - } - } - - { - IDOMReader::Scope __appScope(m_UIADocument.second); - if (m_UIADocument.second->MoveToFirstChild("assets")) { - CopyDOM(*m_UIADocument.second, *outgoingDoc); - } - } - { - eastl::string tempAtt; - for (TIdStateMapMap::const_iterator iter = m_IdToStateMaps.begin(), - end = m_IdToStateMaps.end(); - iter != end; ++iter) { - nvvector::iterator editorEntry = eastl::find_if( - m_Editors.begin(), m_Editors.end(), SEditorIDFinder(iter->first)); - if (editorEntry == m_Editors.end()) { - QT3DS_ASSERT(false); - return false; - } - IDOMWriter::Scope __machineScope(*outgoingDoc, "statemachine", GetNamespace()); - tempAtt.assign("#"); - tempAtt.append(iter->first); - outgoingDoc->Att("ref", tempAtt.c_str()); - IDOMWriter::Scope __vsScope(*outgoingDoc, "visual-states", GetNamespace()); - const TIdEntryExitMap &itemMap = iter->second; - for (TIdEntryExitMap::const_iterator stateIter = itemMap.begin(), - stateEnd = itemMap.end(); - stateIter != stateEnd; ++stateIter) { - TObjPtr editorObj = - editorEntry->m_Editor->GetObjectById(stateIter->first.c_str()); - if (!editorObj) { - QT3DS_ASSERT(false); - continue; - } - WriteStateEntry(stateIter, *outgoingDoc, editorObj->TypeName(), - stateIter->first.c_str()); - } - } - } - - SDOMElement *topElem = outgoingDoc->GetTopElement(); - CDOMSerializer::WriteXMLHeader(inStream); - CDOMSerializer::Write(m_Foundation->getAllocator(), *topElem, inStream, *m_StringTable, - m_UIANamespaces); - m_Dirty = false; - return true; - } - - virtual bool Save() - { - CFileSeekableIOStream theStream(m_FilePath.c_str(), FileWriteFlags()); - if (!theStream.IsOpen()) - return false; - return SaveInner(theStream); - } - - virtual bool Save(qt3ds::foundation::IOutStream &inStream) { return SaveInner(inStream); } - - virtual eastl::vector GetPresentations() { return m_Presentations; } - virtual eastl::string GetElementType(SAppElement &elem) { return elem.m_Type; } - - virtual eastl::string GetElementId(SAppElement &elem) { return elem.m_Id; } - virtual bool IsComponent(SAppElement &elem) - { - return elem.GetSubType() == ElementSubTypes::Component; - } - virtual Q3DStudio::TAttOrArgList GetElementAttributes(SAppElement &elem) - { - return elem.m_Attributes; - } - virtual Q3DStudio::TAttOrArgList GetSlideAttributes() { return m_SlideProperties; } - virtual eastl::vector GetElementAttributeInitialValues(SAppElement &elem) - { - return elem.m_InitialValues; - } - virtual eastl::vector GetElementChildren(SAppElement &elem) - { - eastl::vector retval; - retval.resize(elem.m_Children.size()); - for (size_t idx = 0, end = elem.m_Children.size(); idx < end; ++idx) - retval[idx] = elem.m_Children[idx].mPtr; - return retval; - } - virtual eastl::string GetLastLoadingErrorString() { return m_LoadingErrorString; } - // The file may either exist or not. You can pass in a uip file as well as a uia file. - - virtual NVFoundationBase &GetFoundation() { return m_Foundation->getFoundation(); } - - virtual IStringTable &GetStringTable() { return *m_StringTable; } - - // ITransactionManager - // Undo/redo is supported via a transparent transaction system. - // calls are reentrant but last call will close the transaction object. - // Any changes to any editor objects will go through this transaction when they happen. - virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener) - { - return m_TransactionManager->AddChangeListener(inListener); - } - virtual TTransactionPtr BeginTransaction(const TEditorStr &inName) - { - return m_TransactionManager->BeginTransaction(inName); - } - - virtual TTransactionPtr GetOpenTransaction() - { - return m_TransactionManager->GetOpenTransaction(); - } - - virtual void RollbackTransaction() { m_TransactionManager->RollbackTransaction(); } - virtual void EndTransaction() { m_TransactionManager->EndTransaction(); } - - virtual void OnObjectCreated(TObjPtr) {} - - virtual void OnObjectDeleted(TObjPtr inObject) - { - // don't care. - if (!CouldHaveVisualStateExecutableContent(inObject)) - return; - - TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); - if (stateMap == NULL) - return; - - TIdEntryExitMap::iterator iter = stateMap->find(inObject->GetId()); - if (iter == stateMap->end()) - return; - NVScopedRefCounted theChange = - new SIdEntryExitDeleteChange(*stateMap, inObject->GetId(), inObject); - theChange->Do(); - if (GetOpenTransactionImpl()) - GetOpenTransactionImpl()->m_Changes.push_back(theChange.mPtr); - } - bool RemoveObjectFromEntry(NVScopedRefCounted inEntry, SVSEditorObject &inObj) - { - if (inEntry) { - TObjList::iterator iter = - eastl::find(inEntry->m_Editors.begin(), inEntry->m_Editors.end(), TObjPtr(inObj)); - if (iter != inEntry->m_Editors.end()) { - NVScopedRefCounted theChange = new SVSEntryListChange( - TObjPtr(inObj), TObjPtr(inObj), *inEntry, false, inObj.m_ParentObject); - theChange->Do(); - if (GetOpenTransactionImpl()) - GetOpenTransactionImpl()->m_Changes.push_back(theChange.mPtr); - return true; - } - } - return false; - } - - virtual void RemoveObjectFromGraph(SVSEditorObject &inObj) - { - TObjPtr parentPtr = inObj.m_ParentObject; - if (!CouldHaveVisualStateExecutableContent(parentPtr)) { - QT3DS_ASSERT(false); - return; - } - TIdEntryExitMap *stateMap = GetStateMapForObject(parentPtr); - if (stateMap == NULL) { - QT3DS_ASSERT(false); - return; - } - - TIdEntryExitMap::iterator iter = stateMap->find(parentPtr->GetId()); - if (iter == stateMap->end()) { - QT3DS_ASSERT(false); - return; - } - TEntryExitPair thePair = iter->second; - if (!RemoveObjectFromEntry(thePair.first, inObj)) { - RemoveObjectFromEntry(thePair.second, inObj); - } - } - - struct SEditorFinder - { - TEditorPtr m_Editor; - SEditorFinder(TEditorPtr editor) - : m_Editor(editor) - { - } - bool operator()(const SEditorEntry &entry) const { return entry.m_Editor == m_Editor; } - }; - - void CopyStateNode(SStateNode &inNode, TIdEntryExitMap &idMap, IDOMWriter &writer) - { - TIdEntryExitMap::iterator iter = idMap.find(inNode.m_Id.c_str()); - if (iter != idMap.end()) { - const char *typeName = "state"; - if (inNode.m_Type == StateNodeTypes::Transition) - typeName = "transition"; - WriteStateEntry(iter, writer, typeName, inNode.m_Id.c_str()); - } - TStateNodeList *childList = inNode.GetChildren(); - if (childList) { - for (TStateNodeList::iterator iter = childList->begin(), end = childList->end(); - iter != end; ++iter) { - CopyStateNode(*iter, idMap, writer); - } - } - } - - virtual void OnCopy(TEditorPtr inEditor, eastl::vector &ioCopiedRoots, - IDOMWriter &ioWriter, eastl::vector &ioNamespaces) - { - ioNamespaces.push_back(SNamespacePair(m_StringTable->RegisterStr(GetNamespace()), - m_StringTable->RegisterStr("uia"))); - eastl::vector::iterator entry = - eastl::find_if(m_Editors.begin(), m_Editors.end(), SEditorFinder(inEditor)); - if (entry == m_Editors.end()) - return; - TIdStateMapMap::iterator mapEntry = m_IdToStateMaps.find(entry->m_Id); - if (mapEntry == m_IdToStateMaps.end()) - return; - IDOMWriter::Scope __modelScope(ioWriter, "datamodel_fragment", GetNamespace()); - for (size_t idx = 0, end = ioCopiedRoots.size(); idx < end; ++idx) { - CopyStateNode(*ioCopiedRoots[idx], mapEntry->second, ioWriter); - } - } - - virtual void OnPaste(TEditorPtr inEditor, IDOMReader &ioReader, - CXMLIO::TIdRemapMap &inStateIdRemapMap) - { - eastl::vector::iterator entry = - eastl::find_if(m_Editors.begin(), m_Editors.end(), SEditorFinder(inEditor)); - if (entry == m_Editors.end()) - return; - - IDOMReader::Scope __fragmentScope(ioReader); - if (ioReader.MoveToFirstChild("datamodel_fragment")) { - TIdEntryExitMap &stateMap = - m_IdToStateMaps.insert(eastl::make_pair(entry->m_Id, TIdEntryExitMap())) - .first->second; - for (bool success = ioReader.MoveToFirstChild(); success; - success = ioReader.MoveToNextSibling()) { - IDOMReader::Scope __childScope(ioReader); - const char8_t *idRef; - ioReader.UnregisteredAtt("ref", idRef); - if (isTrivial(idRef)) - continue; - if (idRef[0] == '#') - ++idRef; - - CXMLIO::TIdRemapMap::iterator finder = inStateIdRemapMap.find(idRef); - if (finder != inStateIdRemapMap.end()) - idRef = finder->second.c_str(); - - TEditorStr idStr(idRef); - TObjPtr parentObj = inEditor->GetObjectById(idRef); - if (parentObj) { - ParseVisualStateEntry(ioReader, inEditor, stateMap, idRef); - if (stateMap.find(idStr) != stateMap.end() - && m_TransactionManager->GetOpenTransactionImpl()) { - m_TransactionManager->GetOpenTransactionImpl()->m_Changes.push_back( - new SIdEntryExitDeleteChange(stateMap, idStr, parentObj, false)); - } - } - } - } - } - - virtual void OnIDChange(TEditorPtr inEditor, SStateNode &inNode, const char8_t *inOldId) - { - eastl::vector::iterator entry = - eastl::find_if(m_Editors.begin(), m_Editors.end(), SEditorFinder(inEditor)); - if (entry == m_Editors.end()) - return; - - TIdEntryExitMap &stateMap = - m_IdToStateMaps.insert(eastl::make_pair(entry->m_Id, TIdEntryExitMap())).first->second; - TEditorStr oldIdStr(inOldId); - TEditorStr newIdStr(inNode.m_Id.c_str()); - TIdEntryExitMap::iterator iter = stateMap.find(oldIdStr); - if (iter != stateMap.end()) { - TEntryExitPair thePair(iter->second); - stateMap.erase(iter); - stateMap.insert(eastl::make_pair(newIdStr, thePair)); - } - } - virtual bool OnDeleteState(TObjPtr inObject) - { - // don't care. - if (!CouldHaveVisualStateExecutableContent(inObject)) - return false; - - TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); - if (stateMap == NULL) - return false; - - TIdEntryExitMap::iterator iter = stateMap->find(inObject->GetId()); - if (iter == stateMap->end()) - return false; - NVScopedRefCounted theChange = - new SIdEntryExitDeleteChange(*stateMap, inObject->GetId(), inObject); - theChange->Do(); - if (GetOpenTransactionImpl()) - GetOpenTransactionImpl()->m_Changes.push_back(theChange.mPtr); - return true; - } - virtual bool OnReloadStateMachine(TEditorPtr inStateMachineEditor) - { - bool theRetval = false; - TEditorPtr theEditor = inStateMachineEditor; - - for (size_t idx = 0, end = m_Editors.size(); idx < end; ++idx) { - if (m_Editors[idx].m_Editor == theEditor) { - TIdStateMapMap::iterator theFind = m_IdToStateMaps.find(m_Editors[idx].m_Id); - if (theFind != m_IdToStateMaps.end()) { - TIdEntryExitMap &theStateMap = theFind->second; - for (TIdEntryExitMap::iterator theIter = theStateMap.begin(), - theEnd = theStateMap.end(); - theIter != theEnd;) { - TEditorStr theStateId = theIter->first; - TObjPtr theState = inStateMachineEditor->GetObjectById(theStateId.c_str()); - if (theState) { - { - NVScopedRefCounted theEntry = theIter->second.first; - if (theEntry) { - for (TObjList::iterator theIter = theEntry->m_Editors.begin(), - theEnd = theEntry->m_Editors.end(); - theIter != theEnd; ++theIter) { - SVSEditorObject *theExecutableContent = - static_cast(theIter->mPtr); - if (theExecutableContent) { - theExecutableContent->m_ParentObject = theState; - } - } - } - } - { - NVScopedRefCounted theEntry = theIter->second.second; - if (theEntry) { - for (TObjList::iterator theIter = theEntry->m_Editors.begin(), - theEnd = theEntry->m_Editors.end(); - theIter != theEnd; ++theIter) { - SVSEditorObject *theExecutableContent = - static_cast(theIter->mPtr); - if (theExecutableContent) { - theExecutableContent->m_ParentObject = theState; - } - } - } - } - ++theIter; - } else { - theStateMap.erase(theIter++); - theRetval = true; - } - } - } - break; - } - } - return theRetval; - } - virtual void RegisterChangeListener(IStateMachineChangeListener &) {} - virtual void UnregisterChangeListener(IStateMachineChangeListener &) {} -}; -} - -IDatamodel &IDatamodel::Create(qt3ds::state::editor::TFoundationPtr inFoundation, - const TEditorStr &inPath, const TEditorStr &inAppDir, - IStateMachineEditorManager &inStateMachineEditorManager, - IInStream *inStream) -{ - return IDatamodel::Create(inFoundation, inPath, inAppDir, inStateMachineEditorManager, - IStringTable::CreateStringTable(inFoundation->getAllocator()), - inStream); -} - -IDatamodel &IDatamodel::Create(qt3ds::state::editor::TFoundationPtr inFoundation, - const TEditorStr &inPath, const TEditorStr &inAppDir, - IStateMachineEditorManager &inStateMachineEditorManager, - IStringTable &inStringTable, IInStream *inStream) -{ - DatamodelImpl &theDatamodel = *QT3DS_NEW(inFoundation->getAllocator(), DatamodelImpl)( - inFoundation, inPath, inAppDir, inStateMachineEditorManager, inStringTable); - if (inStream) - theDatamodel.LoadUIADatabaseFromStream(*inStream); - else - theDatamodel.LoadUIADatabase(); - return theDatamodel; -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.h deleted file mode 100644 index e064529a..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodel.h +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef UIA_DATAMODEL_H -#define UIA_DATAMODEL_H -#include "Qt3DSState.h" -#include "Qt3DSStateEditor.h" -#include "Qt3DSMetadata.h" -#include "Qt3DSStateInterpreter.h" -#include "Qt3DSStateEditorFoundation.h" - -namespace qt3ds { -namespace app { - using namespace qt3ds::state; - using namespace qt3ds::state::editor; - - typedef eastl::pair - TDataType; - - struct SDatamodelValue; - - struct SAppElement; - - struct SPresentation - { - eastl::string m_Id; - eastl::string m_SrcPath; - eastl::string m_Author; - eastl::string m_Company; - QT3DSU32 m_Width; - QT3DSU32 m_Height; - SAppElement *m_Scene; - SPresentation() - : m_Width(800) - , m_Height(480) - , m_Scene(NULL) - { - } - }; - - class IStateMachineChangeListener - { - public: - virtual ~IStateMachineChangeListener() {} - virtual bool OnDeleteState(TObjPtr inObject) = 0; - virtual bool OnReloadStateMachine(TEditorPtr inStateMachineEditor) = 0; - }; - - class IStateMachineEditorManager - { - public: - virtual ~IStateMachineEditorManager() {} - virtual TEditorPtr GetOrCreateEditor(const TEditorStr &inFullPath, bool *outLoadStatus) = 0; - virtual void RegisterChangeListener(IStateMachineChangeListener &inListener) = 0; - virtual void UnregisterChangeListener(IStateMachineChangeListener &inListener) = 0; - }; - - class IDatamodel : public ITransactionManager, - public IStateMachineEditorManager, - public IStateMachineChangeListener - { - protected: - virtual ~IDatamodel() {} - public: - // Returns true if we had to create the file. Users should always keep track of the - // transaction stack also - // this does not include that. - virtual bool IsDirty() const = 0; - // General queries of the dataset defined by the uia file and all uip files and scxml files - // it includes. - - virtual TEditorStrList GetComponents() = 0; - virtual TEditorStrList GetComponentSlides(const TEditorStr &inComponent) = 0; - - virtual TEditorStrList GetBehaviors() = 0; - - virtual Q3DStudio::THandlerList GetHandlers(const TEditorStr &inBehavior) = 0; - - virtual Q3DStudio::TVisualEventList GetVisualEvents(const TEditorStr &inElement) = 0; - - virtual TEditorStrList GetElements() = 0; - - virtual Q3DStudio::TAttOrArgList GetElementAttributes(const TEditorStr &inElement) = 0; - - // Necessary to share transaction info and trigger deletes of related information but not - // going to get - // done right now. - // virtual TEditorPtr GetOrCreateEditor( const TEditorStr& inFullPath ) = 0; - - // The editor obj has a remove from graph function that really is delete - virtual TObjList - GetVisualStateExecutableContent(TObjPtr inObject, - InterpreterEventTypes::Enum inEventType) = 0; - // Type name is the element name, so set-attribute, goto-slide, or fire-event - virtual TObjPtr AppendVisualStateExecutableContent(TObjPtr inObject, - InterpreterEventTypes::Enum inEventType, - const char8_t *inElementName) = 0; - virtual TObjPtr ChangeVisualStateExecutableContentName(TObjPtr inContent, - const char8_t *inElementName) = 0; - - // Called when the source uia changes. - virtual void RefreshFile() = 0; - virtual void RefreshFromStream(qt3ds::foundation::IInStream &inStream) = 0; - // Returns the path that was passed in on create. - virtual TEditorStr GetFilePath() = 0; - - // Returns false if unable to save, ask users to check the file out. - virtual bool Save() = 0; - virtual bool Save(qt3ds::foundation::IOutStream &inStream) = 0; - - // The section below allows someone to build an initial scene graph. - // Note that components have additional properties - // Get a list of presentations found while parsing uia file. - virtual eastl::vector GetPresentations() = 0; - virtual eastl::string GetElementType(SAppElement &elem) = 0; - virtual eastl::string GetElementId(SAppElement &elem) = 0; - virtual bool IsComponent(SAppElement &elem) = 0; - virtual Q3DStudio::TAttOrArgList GetElementAttributes(SAppElement &elem) = 0; - // These are found either on the slide or on the component depending on if you are working - // in uip space or runtime space. - virtual Q3DStudio::TAttOrArgList GetSlideAttributes() = 0; - virtual eastl::vector - GetElementAttributeInitialValues(SAppElement &elem) = 0; - virtual eastl::vector GetElementChildren(SAppElement &elem) = 0; - - virtual eastl::string GetLastLoadingErrorString() = 0; - - virtual NVFoundationBase &GetFoundation() = 0; - virtual IStringTable &GetStringTable() = 0; - - // inPath may either exist or not. You can pass in a uip file as well as a uia file. - // application dir is so we can find the meta data. - // inStream provides a way to load from memory, it will be used if it's not NULL. - static IDatamodel &Create(qt3ds::state::editor::TFoundationPtr inFoundation, - const TEditorStr &inPath, const TEditorStr &inApplicationDir, - IStateMachineEditorManager &inStateMachineEditorManager, - IInStream *inStream = 0); - static IDatamodel &Create(qt3ds::state::editor::TFoundationPtr inFoundation, - const TEditorStr &inPath, const TEditorStr &inApplicationDir, - IStateMachineEditorManager &inStateMachineEditorManager, - IStringTable &inStringTable, IInStream *inStream = 0); - }; - - typedef NVScopedRefCounted TDatamodelPtr; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodelValue.h b/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodelValue.h deleted file mode 100644 index 7698809c..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Editor/Qt3DSUIADatamodelValue.h +++ /dev/null @@ -1,291 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef UIA_DATAMODEL_VALUE_H -#define UIA_DATAMODEL_VALUE_H -#include "foundation/Qt3DSDiscriminatedUnion.h" -#include "Qt3DSUIADatamodel.h" - -namespace qt3ds { -namespace app { - - using namespace Q3DStudio; - - template - struct SDatamodelValueTypeMap - { - }; - -#define QT3DS_UIA_DATAMODEL_TYPE_MAP(type, enumname) \ - template <> \ - struct SDatamodelValueTypeMap \ - { \ - static Q3DStudio::ERuntimeDataModelDataType GetType() { return Q3DStudio::enumname; } \ - }; - - struct SGuid - { - long m_Data[4]; - }; - - struct SObjectRef - { - CRegisteredString m_Presentation; - CRegisteredString m_Id; - }; - - class CStringOrInt - { - bool m_IsString; - CRegisteredString m_String; - int m_IntValue; - - public: - CStringOrInt(CRegisteredString val = CRegisteredString()) - : m_IsString(true) - , m_String(val) - , m_IntValue(0) - { - } - CStringOrInt(int val) - : m_IsString(false) - , m_IntValue(val) - { - } - CStringOrInt(const CStringOrInt &other) - : m_IsString(other.m_IsString) - , m_String(other.m_String) - , m_IntValue(other.m_IntValue) - { - } - CStringOrInt &operator=(const CStringOrInt &other) - { - m_IsString = other.m_IsString; - m_String = other.m_String; - m_IntValue = other.m_IntValue; - return *this; - } - bool IsString() const { return m_IsString; } - CRegisteredString StringValue() const - { - QT3DS_ASSERT(m_IsString); - return m_String; - } - int IntValue() const - { - QT3DS_ASSERT(m_IsString == false); - return m_IntValue; - } - }; - - QT3DS_UIA_DATAMODEL_TYPE_MAP(float, ERuntimeDataModelDataTypeFloat); - QT3DS_UIA_DATAMODEL_TYPE_MAP(QT3DSVec2, ERuntimeDataModelDataTypeFloat2); - QT3DS_UIA_DATAMODEL_TYPE_MAP(QT3DSVec3, ERuntimeDataModelDataTypeFloat3); - QT3DS_UIA_DATAMODEL_TYPE_MAP(QT3DSI32, ERuntimeDataModelDataTypeLong); - QT3DS_UIA_DATAMODEL_TYPE_MAP(eastl::string, ERuntimeDataModelDataTypeString); - QT3DS_UIA_DATAMODEL_TYPE_MAP(bool, ERuntimeDataModelDataTypeBool); - QT3DS_UIA_DATAMODEL_TYPE_MAP(SGuid, ERuntimeDataModelDataTypeLong4); - QT3DS_UIA_DATAMODEL_TYPE_MAP(CRegisteredString, ERuntimeDataModelDataTypeStringRef); - QT3DS_UIA_DATAMODEL_TYPE_MAP(SObjectRef, ERuntimeDataModelDataTypeObjectRef); - QT3DS_UIA_DATAMODEL_TYPE_MAP(CStringOrInt, ERuntimeDataModelDataTypeStringOrInt); - - struct SDatamodelValueUnionTraits - { - typedef ERuntimeDataModelDataType TIdType; - enum { - TBufferSize = sizeof(eastl::string), - }; - - static TIdType getNoDataId() { return ERuntimeDataModelDataTypeNone; } - - template - static TIdType getType() - { - return SDatamodelValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case ERuntimeDataModelDataTypeFloat: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeFloat2: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeFloat3: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeLong: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeString: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeBool: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeLong4: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeStringRef: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeObjectRef: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeStringOrInt: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case ERuntimeDataModelDataTypeNone: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case ERuntimeDataModelDataTypeFloat: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeFloat2: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeFloat3: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeLong: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeString: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeBool: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeLong4: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeStringRef: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeObjectRef: - return inVisitor(*NVUnionCast(inData)); - case ERuntimeDataModelDataTypeStringOrInt: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case ERuntimeDataModelDataTypeNone: - return inVisitor(); - } - } - }; -} -} - -// need some specializations in the original nv foundation namespace -namespace qt3ds { -namespace foundation { - - template <> - struct DestructTraits - { - void destruct(qt3ds::app::SGuid &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::app::SObjectRef &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::app::CStringOrInt &) {} - }; - template <> - struct DestructTraits - { - void destruct(CRegisteredString &) {} - }; -} -} - -namespace qt3ds { -namespace app { - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SDatamodelValueUnionTraits::TBufferSize> - TDatamodelUnionType; - - struct SDatamodelValue : public TDatamodelUnionType - { - SDatamodelValue() {} - SDatamodelValue(const SDatamodelValue &other) - : TDatamodelUnionType(static_cast(other)) - { - } - SDatamodelValue(float other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(QT3DSVec2 other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(QT3DSVec3 other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(QT3DSI32 other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(const eastl::string &other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(bool other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(SGuid other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(CRegisteredString other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(SObjectRef other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue(CStringOrInt other) - : TDatamodelUnionType(other) - { - } - SDatamodelValue &operator=(const SDatamodelValue &other) - { - TDatamodelUnionType::operator=(other); - return *this; - } - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSState.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSState.h deleted file mode 100644 index b5686c25..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSState.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_STATE_H -#define QT3DS_STATE_H - -namespace qt3ds { -class NVAllocatorCallback; -class NVFoundationBase; -namespace foundation { - class CRegisteredString; - class IStringTable; - class IOutStream; - class IInStream; - class IDOMFactory; - struct SDOMAttribute; - struct SDOMElement; - struct SNamespacePairNode; - class SocketStream; -} - -namespace intrinsics { -} -} - -namespace qt3ds { -namespace state { - - using namespace qt3ds; - using namespace qt3ds::foundation; - using namespace qt3ds::intrinsics; - using qt3ds::foundation::CRegisteredString; - using qt3ds::foundation::IStringTable; - class IStateContext; - class IStateInterpreter; - class IStateLogger; - class IExecutionContext; - class IScriptContext; - struct SSCXML; - struct SState; - struct STransition; - struct SParallel; - struct SFinal; - struct SHistory; - struct SOnEntry; - struct SOnExit; - struct SSend; - struct SRaise; - struct SIf; - struct SElseIf; - struct SElse; - struct SLog; - struct SAssign; - struct SScript; - struct SDataModel; - struct SData; - struct SStateNode; - struct SCancel; - - namespace editor { - class IEditor; - class IEditorObject; - } - - namespace debugger { - class IDebugOutStream; - struct STransitionId; - class IStateMachineListener; - class IStateMachineDebugInterface; - class IDebugger; - struct SDebugPropertyDeclaration; - class IDebuggedInterpreter; - class IDebuggerMasterListener; - class IDebuggedInterpreter; - struct SMicrostep; - class IScriptStateListener; - } -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateContext.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateContext.h deleted file mode 100644 index 31098938..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateContext.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_CONTEXT_H -#define QT3DS_STATE_CONTEXT_H -#include "Qt3DSState.h" -#include "Qt3DSStateTypes.h" - -namespace qt3ds { -namespace state { - - // Thanks to the crazy world we live in, we have to store xml extension information - // on the state context. - struct SItemExtensionInfo - { - void *m_ItemPtr; - TDOMElementNodeList m_ExtensionNodes; - TDOMAttributeNodeList m_ExtensionAttributes; - SItemExtensionInfo(void *inItemPtr) - : m_ItemPtr(inItemPtr) - { - } - }; - typedef nvhash_map TPtrExtensionMap; - // Parsing produces a list of send objects that need to be added into the script - // context if they have their idlocation attribute set. - typedef nvvector TSendList; - - class IStateContext : public NVRefCounted - { - public: - // Can only be done once. - virtual void SetRoot(SSCXML &inRoot) = 0; - virtual SSCXML *GetRoot() = 0; - virtual void AddSendToList(SSend &inSend) = 0; - virtual NVConstDataRef GetSendList() = 0; - virtual void SetDOMFactory(IDOMFactory *inFactory) = 0; - virtual IDOMFactory *GetDOMFactory() = 0; - virtual NVConstDataRef> GetSubContexts() = 0; - virtual bool ContainsId(const CRegisteredString &inId) = 0; - virtual bool InsertId(const CRegisteredString &inId, const SIdValue &inValue) = 0; - virtual void EraseId(const CRegisteredString &inId) = 0; - virtual SStateNode *FindStateNode(const CRegisteredString &inStr) = 0; - virtual SSend *FindSend(const CRegisteredString &inStr) = 0; - - virtual SItemExtensionInfo *GetExtensionInfo(void *inItem) = 0; - virtual SItemExtensionInfo &GetOrCreateExtensionInfo(void *inItem) = 0; - - virtual void SetFirstNSNode(SNamespacePairNode &inNode) = 0; - virtual SNamespacePairNode *GetFirstNSNode() = 0; - - virtual void Save(IOutStream &inOutStream, editor::IEditor *inEditor = NULL) = 0; - - // The graph allocator is expected to release anything allocated via it; the general - // allocator doesn't need to do this. - // Filename is stored on the context for debugging purposes, editor is used if during - // loading so we can load extra - // information that is associated with but not stored on the state graph. - // String table will be created if not passed in, editor is optional. - static IStateContext *Load(NVAllocatorCallback &inGraphAllocator, - NVFoundationBase &inFoundation, IInStream &inStream, - const char8_t *inFilename, IStringTable *inStrTable = NULL, - editor::IEditor *inEditor = NULL); - - static IStateContext *Create(NVFoundationBase &inGeneralAlloc); - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionContext.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionContext.h deleted file mode 100644 index 31ff0e22..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionContext.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EXECUTION_CONTEXT_H -#define QT3DS_STATE_EXECUTION_CONTEXT_H -#pragma once -#include "Qt3DSState.h" -#include "Qt3DSStateTypes.h" -#include "foundation/Qt3DSRefCounted.h" - -namespace qt3ds { -namespace state { - - class IStateLogger : public NVRefCounted - { - protected: - virtual ~IStateLogger() {} - public: - virtual void Log(const char8_t *inLabel, const char8_t *inExpression) = 0; - }; - // Implementation of the execution context of the scxml state specification. - // Implementations if,send,raise,foreach,etc working closely with the scripting - // system. - class IExecutionContext : public NVRefCounted - { - protected: - virtual ~IExecutionContext() {} - public: - virtual void SetInterpreter(IStateInterpreter &inInterpreter) = 0; - virtual void SetMachineDebugLogger(IStateLogger &inDebugLogger) = 0; - virtual void Execute(STransition &inTransaction) = 0; - // These functions take the node as well as the list so a context can cache a fast - // execution path if necessary. - virtual void Execute(SStateNode &inNode, TOnEntryList &inList) = 0; - virtual void Execute(SStateNode &inNode, TOnExitList &inList) = 0; - - // Returns the time string in milliseconds. - static QT3DSU64 ParseTimeStrToMilliseconds(const char8_t *timeStr); - - static IExecutionContext &Create(NVFoundationBase &inFoundation, - IStringTable &inStringTable, IStateLogger &inLogger, - IScriptContext &inScriptContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionTypes.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionTypes.h deleted file mode 100644 index 6dc7674f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateExecutionTypes.h +++ /dev/null @@ -1,392 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_EXECUTION_TYPES_H -#define QT3DS_STATE_EXECUTION_TYPES_H -#pragma once -#include "Qt3DSStateTypes.h" - -namespace qt3ds { -namespace state { - - struct ExecutableContentTypes - { - enum Enum { - NoType = 0, - Raise, - If, - ElseIf, - Else, - Foreach, - Log, - Assign, - Script, - Send, - Cancel, - Param, - Content, - }; - static const char8_t *ToString(Enum inVal) - { - switch (inVal) { - case Raise: - return "Raise"; - case If: - return "If"; - case ElseIf: - return "ElseIf"; - case Else: - return "Else"; - case Foreach: - return "Foreach"; - case Log: - return "Log"; - case Assign: - return "Assign"; - case Script: - return "Script"; - case Send: - return "Send"; - case Cancel: - return "Cancel"; - case Param: - return "Param"; - case Content: - return "Content"; - default: - return "Unknown execution type"; - } - } - }; - - struct SRaise; - struct SIf; - struct SElseIf; - struct SElse; - struct SForeach; - struct SLog; - struct SAssign; - struct SScript; - struct SSend; - struct SCancel; - struct SParam; - struct SContent; - - template - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::NoType; - } - }; - - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Raise; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() { return ExecutableContentTypes::If; } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::ElseIf; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Else; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Foreach; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() { return ExecutableContentTypes::Log; } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Assign; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Script; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Send; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Cancel; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Param; - } - }; - template <> - struct SExecutableContentTypeMap - { - static ExecutableContentTypes::Enum GetContentType() - { - return ExecutableContentTypes::Content; - } - }; - - // Defined by the execution context to speed up evaluation of executable data. - struct SExecutionData; - - struct SExecutableContent - { - const ExecutableContentTypes::Enum m_Type; - SStateNode *m_StateNodeParent; - SExecutableContent *m_Parent; - SExecutableContent *m_NextSibling; - SExecutableContent *m_PreviousSibling; - TExecutableContentList m_Children; - - SExecutableContent(ExecutableContentTypes::Enum inType) - : m_Type(inType) - , m_StateNodeParent(NULL) - , m_Parent(NULL) - , m_NextSibling(NULL) - , m_PreviousSibling(NULL) - { - } - - template - TDataType *CastTo() - { - if (m_Type == SExecutableContentTypeMap::GetContentType()) - return static_cast(this); - return NULL; - } - - template - const TDataType *CastTo() const - { - if (m_Type == SExecutableContentTypeMap::GetContentType()) - return static_cast(this); - return NULL; - } - }; - - IMPLEMENT_INVASIVE_LIST(ExecutableContent, m_PreviousSibling, m_NextSibling); - - struct SRaise : public SExecutableContent - { - CRegisteredString m_Event; - SRaise() - : SExecutableContent(ExecutableContentTypes::Raise) - { - } - }; - - struct SIf : public SExecutableContent - { - const char8_t *m_Cond; - SIf() - : SExecutableContent(ExecutableContentTypes::If) - , m_Cond(NULL) - { - } - }; - - struct SElseIf : public SExecutableContent - { - const char8_t *m_Cond; - SElseIf() - : SExecutableContent(ExecutableContentTypes::ElseIf) - , m_Cond(NULL) - { - } - }; - - struct SElse : public SExecutableContent - { - SElse() - : SExecutableContent(ExecutableContentTypes::Else) - { - } - }; - - struct SForeach : public SExecutableContent - { - CRegisteredString m_Array; - CRegisteredString m_Item; - CRegisteredString m_Index; - SForeach() - : SExecutableContent(ExecutableContentTypes::Foreach) - { - } - }; - - struct SLog : public SExecutableContent - { - CRegisteredString m_Label; - const char8_t *m_Expression; - SLog() - : SExecutableContent(ExecutableContentTypes::Log) - , m_Expression(NULL) - { - } - }; - - struct SAssign : public SExecutableContent - { - const char8_t *m_Location; - const char8_t *m_Expression; - SAssign() - : SExecutableContent(ExecutableContentTypes::Assign) - , m_Location(NULL) - , m_Expression(NULL) - { - } - }; - - struct SScript : public SExecutableContent - { - const char8_t *m_URL; - const char8_t *m_Data; - SScript() - : SExecutableContent(ExecutableContentTypes::Script) - , m_URL(NULL) - , m_Data(NULL) - { - } - }; - - struct SSend : public SExecutableContent - { - CRegisteredString m_Event; - const char8_t *m_EventExpr; - const char8_t *m_Target; - const char8_t *m_TargetExpr; - const char8_t *m_Type; - const char8_t *m_TypeExpr; - CRegisteredString m_Id; - const char8_t *m_IdLocation; - const char8_t *m_Delay; - const char8_t *m_DelayExpr; - const char8_t *m_NameList; - - SSend() - : SExecutableContent(ExecutableContentTypes::Send) - , m_EventExpr(NULL) - , m_Target(NULL) - , m_TargetExpr(NULL) - , m_Type(NULL) - , m_TypeExpr(NULL) - , m_IdLocation(NULL) - , m_Delay(NULL) - , m_DelayExpr(NULL) - , m_NameList(NULL) - { - } - }; - struct SCancel : public SExecutableContent - { - // If we have an id. - SSend *m_Send; - const char8_t *m_IdExpression; - - SCancel() - : SExecutableContent(ExecutableContentTypes::Cancel) - , m_Send(NULL) - , m_IdExpression(NULL) - { - } - }; - - struct SParam : public SExecutableContent - { - CRegisteredString m_Name; - const char8_t *m_Expr; - CRegisteredString m_Location; - SParam() - : SExecutableContent(ExecutableContentTypes::Param) - , m_Expr(NULL) - { - } - }; - - struct SContent : public SExecutableContent - { - const char8_t *m_Expr; - const char8_t *m_ContentValue; - SContent() - : SExecutableContent(ExecutableContentTypes::Content) - , m_Expr(NULL) - , m_ContentValue(NULL) - { - } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateIdValue.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateIdValue.h deleted file mode 100644 index ed5beb13..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateIdValue.h +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_STATE_ID_TYPE_VALUE_H -#define QT3DS_STATE_ID_TYPE_VALUE_H -#include "Qt3DSState.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" - -// Discriminated union to unify different things that may be identified by an id -namespace qt3ds { -namespace state { - - struct IdValueTypes - { - enum Enum { - NoIdValue = 0, - StateNode, - Send, - }; - }; - - template - struct SIdValueTypeMap - { - static IdValueTypes::Enum GetType() { return IdValueTypes::NoIdValue; } - }; - - template <> - struct SIdValueTypeMap - { - static IdValueTypes::Enum GetType() { return IdValueTypes::StateNode; } - }; - template <> - struct SIdValueTypeMap - { - static IdValueTypes::Enum GetType() { return IdValueTypes::Send; } - }; - - struct SIdValueUnionTraits - { - typedef IdValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(void *), - }; - - static TIdType getNoDataId() { return IdValueTypes::NoIdValue; } - - template - static TIdType getType() - { - return SIdValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case IdValueTypes::StateNode: - return inVisitor(*NVUnionCast(inData)); - case IdValueTypes::Send: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case IdValueTypes::NoIdValue: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case IdValueTypes::StateNode: - return inVisitor(*NVUnionCast(inData)); - case IdValueTypes::Send: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case IdValueTypes::NoIdValue: - return inVisitor(); - } - } - }; -} -} - -// need some specializations in the original nv foundation namespace -namespace qt3ds { -namespace foundation { - - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SStateNode *) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SSend *) {} - }; -} -} - -namespace qt3ds { -namespace state { - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SIdValueUnionTraits::TBufferSize> - TIdUnionType; - - struct SIdValue : public TIdUnionType - { - SIdValue() {} - - SIdValue(const SIdValue &inOther) - : TIdUnionType(static_cast(inOther)) - { - } - - SIdValue(SStateNode *inDt) - : TIdUnionType(inDt) - { - } - SIdValue(SSend *inDt) - : TIdUnionType(inDt) - { - } - - SIdValue &operator=(const SIdValue &inOther) - { - TIdUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SIdValue &inOther) const { return TIdUnionType::operator==(inOther); } - bool operator!=(const SIdValue &inOther) const { return TIdUnionType::operator!=(inOther); } - - bool empty() const { return getType() == IdValueTypes::NoIdValue; } - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateInterpreter.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateInterpreter.h deleted file mode 100644 index d615d21f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateInterpreter.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_INTERPRETER_H -#define QT3DS_STATE_INTERPRETER_H -#pragma once -#include "Qt3DSState.h" -#include "Qt3DSStateTypes.h" -#include "Qt3DSStateSignalConnection.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace state { - struct InterpreterEventTypes - { - enum Enum { - UnknownInterpreterEvent = 0, - StateEnter, - StateExit, - Transition, - }; - }; - - struct IStateInterpreterEventHandler - { - protected: - virtual ~IStateInterpreterEventHandler() {} - - public: - virtual void OnInterpreterEvent(InterpreterEventTypes::Enum inEvent, - CRegisteredString inEventId) = 0; - }; - - class IStateInterpreter : public NVRefCounted - { - protected: - virtual ~IStateInterpreter() {} - public: - // Setup of the state system, you can add a set of roots to the state graph. - virtual NVConstDataRef GetConfiguration() = 0; - // State context is referenced by this object. - // We can optionally validate the transitions to ensure that no transition can put us into - // an invalid state - // and so that simple loops don't exist. It is highly recommended to use this; it is done - // once via startup and - // shouldn't add appreciably to the initialization time but it makes the transition system a - // lot more robust. - virtual bool Initialize(IStateContext &inContext, bool inValidateTransitions = true) = 0; - // Bring the state machine to the internal state. - // Returns the list of states for the initial configuration - virtual NVConstDataRef Start() = 0; - - // Execute transitions, internal events and external events until nothing is left to - // be done. - virtual NVConstDataRef Execute() = 0; - - virtual bool IsRunning() const = 0; - virtual bool EventsPending() const = 0; - - // Queue an event with an optional delay (0 means no delay). - // If the event has a delay then it can optionally be cancelled. - virtual void QueueEvent(const char8_t *inEventName, QT3DSU64 inDelay, - CRegisteredString inCancelId, bool inIsExternal = true) = 0; - virtual void QueueEvent(TEventPtr inEvent, QT3DSU64 inDelay, CRegisteredString inCancelId, - bool inIsExternal = true) = 0; - virtual void QueueEvent(TEventPtr inEvent, bool inIsExternal = true) = 0; - virtual void QueueEvent(const char8_t *inEventName, bool inIsExternal = true) = 0; - - // Cancel an event with a particular id. Only cancels delayed events that have not fired - // yet. - virtual void CancelEvent(CRegisteredString inCancelId) = 0; - - // When the connection gets destroyed, the hander will get no more events. - virtual TSignalConnectionPtr - RegisterEventHandler(IStateInterpreterEventHandler &inHandler) = 0; - - virtual debugger::IStateMachineDebugInterface &GetDebugInterface() = 0; - - virtual NVFoundationBase &GetFoundation() = 0; - - virtual IScriptContext &GetScriptContext() = 0; - - virtual IStateContext *GetStateContext() = 0; - - // The only code that needs to happen in the state system is the code that executes a - // condition. - static IStateInterpreter &Create(NVFoundationBase &inFnd, IStringTable &inStrTable, - IScriptContext &inScriptContext, - IExecutionContext &inExecutionContext); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateScriptContext.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateScriptContext.h deleted file mode 100644 index 110770a1..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateScriptContext.h +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_SCRIPT_CONTEXT_H -#define QT3DS_STATE_SCRIPT_CONTEXT_H -#pragma once -#include "Qt3DSState.h" -#include "Qt3DSStateTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace state { - - class IScriptEvent : public IEvent - { - public: - // returns true on success, false if error.execution should be signaled. - virtual bool SetParam(CRegisteredString inName, const char8_t *inExpression) = 0; - // Sets the expression as a string - virtual bool SetParamStr(CRegisteredString inName, const char8_t *inStr) = 0; - virtual bool SetDataExpr(const char8_t *inExpression) = 0; - virtual bool SetDataStr(const char8_t *inStr) = 0; - }; - - struct SScriptExecutionResult - { - const char8_t *m_Result; - const char8_t *m_Error; - SScriptExecutionResult(const char8_t *inData, const char8_t *inError) - : m_Result(inData) - , m_Error(inError) - { - } - SScriptExecutionResult() - : m_Result("") - , m_Error("") - { - } - bool Valid() const { return m_Error == NULL || *m_Error == 0; } - const char8_t *Result() const - { - QT3DS_ASSERT(Valid()); - return m_Result; - } - const char8_t *Error() const - { - QT3DS_ASSERT(!Valid()); - return m_Error; - } - }; - - class IScriptContext : public NVRefCounted - { - protected: - virtual ~IScriptContext() {} - public: - // Should functions returning options return othing - virtual Option ExecuteCondition(const char8_t *inCond) = 0; - // Used for logging. - // Error and result are good until next call into the script context. - virtual SScriptExecutionResult ExecuteExpressionToString(const char8_t *inExpr) = 0; - - // If return value is false, error is signaled with GetErrorInfo. - virtual bool Assign(const char8_t *inVariable, const char8_t *inExpr) = 0; - // Assign a string to this variable location. - virtual void AssignStr(const char8_t *inVariable, const char8_t *inStr) = 0; - - // If return value is false, error is signaled via GetErrorInfo. - // The actual pointer and content used for inscript is expected to not change during - // execution of the system. - // it is legal for contexts to cache information based off the script pointer value. - virtual bool ExecuteScript(const char8_t *inScript) = 0; - // Always return 1 result - virtual int ExecuteStr(const char8_t *inScript, bool withRet) = 0; - - // Return true on success, false on failure, and Empty on error. - virtual Option BeginForeach(const char8_t *inArray, const char8_t *inItem, - const char8_t *inIdxVar = "") = 0; - virtual Option NextForeach(const char8_t *inItem, const char8_t *inIdxVar = "") = 0; - virtual void CancelForeach() = 0; - - virtual void SetCurrentEvent(TEventPtr inEvent) = 0; - virtual void ClearCurrentEvent() = 0; - // Create an event we can attach extra data do. - virtual IScriptEvent *CreateScriptEvent(CRegisteredString inName) = 0; - - virtual const char8_t *GetErrorInfo() = 0; - - virtual void SetInterpreter(IStateInterpreter &inInterpreter) = 0; - - virtual CRegisteredString GetContextType() { return CRegisteredString(); } - - // Dumps a differential state from the last time someone asked. This is a debug interface; - // not meant to be used - // by multiple listeners concurrently. - virtual void DumpState(debugger::IScriptStateListener &inListener) = 0; - }; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSharedImpl.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSharedImpl.h deleted file mode 100644 index 0b82cc3c..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSharedImpl.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_SHARED_IMPL_H -#define QT3DS_STATE_SHARED_IMPL_H -#include "Qt3DSState.h" -#include "foundation/Utils.h" - -namespace qt3ds { -namespace state { - namespace impl { - - inline bool NameMatchesInternal(const char8_t *inTransEvent, QT3DSU32 transLen, - const char8_t *inEventName, QT3DSU32 eventLen) - { - QT3DSU32 idx, end; - // Empty loop intentional to find first nonmatching character - for (idx = 0, end = NVMin(transLen, eventLen); - idx < end && inTransEvent[idx] == inEventName[idx]; ++idx) { - } - // Note that in this case we point to the first nonmatching character which may be off - // the end of either - // eventStr or transStr - bool match = false; - if (idx == transLen) { - if (idx == eventLen) - match = true; - else if (inEventName[idx] == '.') - match = true; - else if (inTransEvent[idx - 1] == '.') - match = true; - } else if (idx == eventLen) { - if ((transLen - idx) == 1) - match = inTransEvent[idx] == '*' || inTransEvent[idx] == '.'; - - else if ((transLen - idx) == 2) - match = inTransEvent[idx] == '.' && inTransEvent[idx + 1] == '*'; - } else { - if (inTransEvent[idx] == '*') - match = true; - } - return match; - } - - inline const char8_t *FindNextNonSpace(const char8_t *inPtr) - { - for (; *inPtr == ' '; ++inPtr) { - } - return inPtr; - } - - inline const char8_t *FindNextSpaceOrNull(const char8_t *inPtr) - { - for (; *inPtr && *inPtr != ' '; ++inPtr) { - } - return inPtr; - } - - inline bool NameMatches(const char8_t *inTransEvent, const char8_t *inEventName) - { - inTransEvent = nonNull(inTransEvent); - inEventName = nonNull(inEventName); - - QT3DSU32 transLen = StrLen(inTransEvent); - - QT3DSU32 eventLen = StrLen(inEventName); - if (transLen == 0) { - QT3DS_ASSERT(false); - return false; - } - if (eventLen == 0) { - QT3DS_ASSERT(false); - return false; - } - - for (inTransEvent = FindNextNonSpace(inTransEvent); inTransEvent && *inTransEvent; - inTransEvent = FindNextNonSpace(inTransEvent)) { - const char8_t *end = FindNextSpaceOrNull(inTransEvent); - QT3DSU32 len = (QT3DSU32)(end - inTransEvent); - - if (len && NameMatchesInternal(inTransEvent, len, inEventName, eventLen)) - return true; - inTransEvent = end; - } - - return false; - } - } -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSignalConnection.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSignalConnection.h deleted file mode 100644 index 5bfa59ad..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateSignalConnection.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_SIGNAL_CONNECTION_H -#define QT3DS_STATE_SIGNAL_CONNECTION_H -#pragma once -#include "Qt3DSState.h" -#include "foundation/Qt3DSRefCounted.h" -namespace qt3ds { -namespace state { - - class IStateSignalConnection : public NVRefCounted - { - protected: - virtual ~IStateSignalConnection() {} - public: - }; - - typedef NVScopedRefCounted TSignalConnectionPtr; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateTypes.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateTypes.h deleted file mode 100644 index 41e759fb..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateTypes.h +++ /dev/null @@ -1,720 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_STATE_TYPES_H -#define QT3DS_STATE_TYPES_H -#include "Qt3DSState.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/StringTable.h" -#include "foundation/TaggedPointer.h" -#include "foundation/Qt3DSVec2.h" -#include "foundation/Qt3DSVec3.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Utils.h" -#include "Qt3DSStateIdValue.h" - -namespace qt3ds { -namespace state { - - // Link list definitions. - DEFINE_INVASIVE_LIST(StateNode); - DEFINE_INVASIVE_SINGLE_LIST(OnEntry); - DEFINE_INVASIVE_SINGLE_LIST(OnExit); - DEFINE_INVASIVE_SINGLE_LIST(DataModel); - DEFINE_INVASIVE_LIST(Invoke); - - // Externally defined objects - These objects are defined by the implementation of the - // interpreter and the execution context. They are not used and cannot be manipulated by - // core state types. - - // Standard content defined in another file so as to not clutter up the core state definitions. - struct SExecutableContent; - DEFINE_INVASIVE_LIST(ExecutableContent); - struct SScript; - struct SDataModel; - - // Defined by the execution context; These objects can be defined by the implementation of the - // scripting - // system. - struct STransitionCondition; - - // Defined by the interpreter. Really just a placeholder so the interpreter can cache - // item-specific data on an object. - struct SInterpreterData; - - // We *have* to keep some subset of the data in document order because the algorithms - // defined in the specification rely on this. - struct StateNodeTypes - { - enum Enum { - UnknownType, - State, - Parallel, - Transition, - Final, - SCXML, - History, - }; - static bool CanHaveChildren(StateNodeTypes::Enum val) - { - return val == State || val == Parallel || val == SCXML; - } - static bool CanHaveTransitions(StateNodeTypes::Enum val) - { - return val == State || val == Parallel; - } - static bool IsStateType(StateNodeTypes::Enum val) - { - return CanHaveChildren(val) || val == Final; - } - static bool IsTransitionType(StateNodeTypes::Enum val) { return val == Transition; } - static bool CanHaveInitializeNode(StateNodeTypes::Enum val) { return val == State; } - static bool IsAtomicType(StateNodeTypes::Enum val) { return val == State || val == Final; } - }; - - struct SState; - struct SParallel; - struct STransition; - struct SFinal; - struct SSCXML; - struct SHistory; - - template - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::UnknownType; } - }; - - template <> - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::State; } - }; - template <> - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::Parallel; } - }; - template <> - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::Transition; } - }; - template <> - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::Final; } - }; - template <> - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::SCXML; } - }; - template <> - struct SStateNodeTypeMap - { - static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::History; } - }; - // Some editor info has to be contained on the state node. Description I am fine with eliding - // but - // most of the other information needs to sit on the nodes themselves. - struct StateNodeFlagValues - { - enum Enum { - HasNothing = 0, - HasPosition = 1, - HasDimension = 1 << 1, - HasColor = 1 << 2, - HasEndPosition = 1 << 3, - }; - }; - - struct SStateNodeFlags : NVFlags - { - bool HasPosition() const { return this->operator&(StateNodeFlagValues::HasPosition); } - void SetHasPosition(bool val) { clearOrSet(val, StateNodeFlagValues::HasPosition); } - bool HasDimension() const { return this->operator&(StateNodeFlagValues::HasDimension); } - void SetHasDimension(bool val) { clearOrSet(val, StateNodeFlagValues::HasDimension); } - bool HasColor() const { return this->operator&(StateNodeFlagValues::HasColor); } - void SetHasColor(bool val) { clearOrSet(val, StateNodeFlagValues::HasColor); } - bool HasEndPosition() const { return this->operator&(StateNodeFlagValues::HasEndPosition); } - void SetHasEndPosition(bool val) { clearOrSet(val, StateNodeFlagValues::HasEndPosition); } - }; - - struct SStateNode - { - const StateNodeTypes::Enum m_Type; - CRegisteredString m_Id; - SStateNode *m_Parent; - SStateNode *m_NextSibling; - SStateNode *m_PreviousSibling; - SInterpreterData *m_InterpreterData; - SStateNodeFlags m_StateNodeFlags; - QT3DSVec2 m_Position; - QT3DSVec2 m_Dimension; - QT3DSVec3 m_Color; - - SStateNode(StateNodeTypes::Enum inType) - : m_Type(inType) - , m_Parent(NULL) - , m_NextSibling(NULL) - , m_PreviousSibling(NULL) - , m_InterpreterData(NULL) - { - } - - template - TDataType *CastTo() - { - if (m_Type == SStateNodeTypeMap::GetStateNodeType()) - return static_cast(this); - QT3DS_ASSERT(false); - return NULL; - } - - template - const TDataType *CastTo() const - { - if (m_Type == SStateNodeTypeMap::GetStateNodeType()) - return static_cast(this); - QT3DS_ASSERT(false); - return NULL; - } - // Helper functions that take care of the drama around getting the various - // shared properties - bool IsCompound() const; - bool IsAtomic() const; - void AppendChild(SStateNode &inChild); - TOnEntryList *GetOnEntryList(); - TOnExitList *GetOnExitList(); - STransition *GetInitialTransition(); - const char8_t *GetInitialExpression(); - TStateNodeList *GetChildren(); - SDataModel *GetDataModel(); - Option GetPosition() const - { - if (m_StateNodeFlags.HasPosition()) - return m_Position; - return Empty(); - } - void SetPosition(const Option &pos) - { - if (pos.hasValue()) { - m_Position = *pos; - } - m_StateNodeFlags.SetHasPosition(pos.hasValue()); - } - Option GetDimension() const - { - if (m_StateNodeFlags.HasDimension()) - return m_Dimension; - return Empty(); - } - void SetDimension(const Option &pos) - { - if (pos.hasValue()) { - m_Dimension = *pos; - } - m_StateNodeFlags.SetHasDimension(pos.hasValue()); - } - Option GetColor() const - { - if (m_StateNodeFlags.HasColor()) - return m_Color; - return Empty(); - } - void SetColor(const Option &pos) - { - if (pos.hasValue()) { - m_Color = *pos; - } - m_StateNodeFlags.SetHasColor(pos.hasValue()); - } - }; - - struct SEntryExitBase : public SStateNode - { - TOnEntryList m_OnEntry; - TOnExitList m_OnExit; - SEntryExitBase(StateNodeTypes::Enum inType) - : SStateNode(inType) - { - } - }; - - // State and parallel objects can have states as children. Nothing aside from - // SCXML can have this. - struct SStateParallelBase : public SEntryExitBase - { - TStateNodeList m_Children; - SDataModel *m_DataModel; - TInvokeList m_InvokeList; - - SStateParallelBase(StateNodeTypes::Enum inType) - : SEntryExitBase(inType) - , m_DataModel(NULL) - { - } - - void RemoveChild(SStateNode &inChild) - { - QT3DS_ASSERT(inChild.m_Parent == this); - m_Children.remove(inChild); - inChild.m_Parent = NULL; - } - - void AppendChild(SStateNode &inChild, SStateNode *inLoc = NULL) - { - if (inChild.m_Parent != NULL) - static_cast(inChild.m_Parent)->RemoveChild(inChild); - if (inLoc) - m_Children.insert_after(*inLoc, inChild); - else - m_Children.push_back(inChild); - inChild.m_Parent = this; - } - - void PrependChild(SStateNode &inChild, SStateNode *inLoc = NULL) - { - if (inChild.m_Parent != NULL) - static_cast(inChild.m_Parent)->RemoveChild(inChild); - if (inLoc) - m_Children.insert_before(*inLoc, inChild); - else - m_Children.push_front(inChild); - inChild.m_Parent = this; - } - - bool IsAtomic() const - { - for (TStateNodeList::const_iterator iter = m_Children.begin(), end = m_Children.end(); - iter != end; ++iter) { - if (iter->m_Type != StateNodeTypes::Transition) - return false; - } - return true; - } - bool IsCompound() const { return !IsAtomic(); } - }; - - struct SCXMLFlagValues - { - enum Enum { - Late = 1, - }; - }; - - struct SSCXMLFlags : public NVFlags - { - SSCXMLFlags() {} - - void SetLateBinding(bool inValue) { clearOrSet(inValue, SCXMLFlagValues::Late); } - bool IsLateBinding() const { return this->operator&(SCXMLFlagValues::Late); } - }; - - // Begin standard object definitions - - struct SSCXML : public SStateNode - { - STransition *m_Initial; - CRegisteredString m_Name; - TStateNodeList m_Children; - SScript *m_Script; - SSCXMLFlags m_Flags; - SDataModel *m_DataModel; - QT3DSI32 m_Version; - const char8_t *m_Filename; - const char8_t *m_InitialExpr; - - static QT3DSI32 GetCurrentVersion() { return 1; } - SSCXML() - : SStateNode(StateNodeTypes::SCXML) - , m_Initial(NULL) - , m_Script(NULL) - , m_DataModel(NULL) - , m_Version(GetCurrentVersion()) - , m_InitialExpr(NULL) - { - } - - void RemoveChild(SStateNode &inChild) - { - QT3DS_ASSERT(inChild.m_Parent == this); - m_Children.remove(inChild); - inChild.m_Parent = NULL; - } - - void AppendChild(SStateNode &inChild, SStateNode *inLoc = NULL) - { - if (inChild.m_Parent != NULL) - static_cast(inChild.m_Parent)->RemoveChild(inChild); - if (inLoc) - m_Children.insert_after(*inLoc, inChild); - else - m_Children.push_back(inChild); - inChild.m_Parent = this; - } - }; - - struct SState : public SStateParallelBase - { - // transition, state, parallel, and final are all handed by SStateNode - STransition *m_Initial; - const char8_t *m_InitialExpr; - - SState() - : SStateParallelBase(StateNodeTypes::State) - , m_Initial(NULL) - , m_InitialExpr(NULL) - { - } - }; - - struct SParallel : public SStateParallelBase - { - SParallel() - : SStateParallelBase(StateNodeTypes::Parallel) - { - } - }; - - struct TransitionFlagValues - { - enum Enum { - Internal = 1, - }; - }; - - struct STransitionFlags : public NVFlags - { - STransitionFlags() {} - - void SetInternal(bool inValue) { clearOrSet(inValue, TransitionFlagValues::Internal); } - bool IsInternal() const { return this->operator&(TransitionFlagValues::Internal); } - }; - - struct STransition : public SStateNode - { - CRegisteredString m_Event; - const char8_t *m_Condition; - NVConstDataRef m_Target; - STransitionFlags m_Flags; - TExecutableContentList m_ExecutableContent; - NVConstDataRef m_Path; - // If we have multiple end targets, on order to lay them out we need a branch point - // along with the number of control points in each target. The first index points to the - // branch point in the path vector, then next index tells the number of control points - // for the first end point, etc. - NVConstDataRef m_PathIndexes; - QT3DSVec2 m_EndPosition; - // m_Source of the transition is its parent - - STransition() - : SStateNode(StateNodeTypes::Transition) - , m_Condition(NULL) - , m_EndPosition(0, 0) - { - } - - SStateNode *GetSource() { return m_Parent; } - - Option GetEndPosition() const - { - if (m_StateNodeFlags.HasEndPosition()) - return m_EndPosition; - return Empty(); - } - void SetEndPosition(const Option &pos) - { - if (pos.hasValue()) { - m_EndPosition = *pos; - } - m_StateNodeFlags.SetHasEndPosition(pos.hasValue()); - } - }; - - // TODO: DoneData - struct SFinal : public SEntryExitBase - { - SFinal() - : SEntryExitBase(StateNodeTypes::Final) - { - } - }; - - struct HistoryFlagValues - { - enum Enum { - Deep = 1, - }; - }; - - struct SHistoryFlags : public NVFlags - { - SHistoryFlags() {} - - void SetDeep(bool inValue) { clearOrSet(inValue, HistoryFlagValues::Deep); } - bool IsDeep() const { return this->operator&(HistoryFlagValues::Deep); } - }; - - struct SHistory : public SStateNode - { - SHistoryFlags m_Flags; - qt3ds::foundation::STaggedPointer m_UserData; - STransition *m_Transition; - - SHistory() - : SStateNode(StateNodeTypes::History) - , m_Transition(NULL) - { - } - }; - - struct SOnEntry - { - SOnEntry *m_NextSibling; - TExecutableContentList m_ExecutableContent; - qt3ds::foundation::STaggedPointer m_UserData; - SOnEntry() - : m_NextSibling(NULL) - { - } - }; - - struct SOnExit - { - SOnExit *m_NextSibling; - TExecutableContentList m_ExecutableContent; - qt3ds::foundation::STaggedPointer m_UserData; - SOnExit() - : m_NextSibling(NULL) - { - } - }; - - struct SInvoke - { - SInvoke *m_NextSibling; - SInvoke *m_PreviousSibling; - // Will have either SCXML content or dom content but not both. - SSCXML *m_SCXMLContent; - SDOMElement *m_DOMContent; - SInvoke() - : m_NextSibling(NULL) - , m_PreviousSibling(NULL) - , m_SCXMLContent(NULL) - , m_DOMContent(NULL) - { - } - }; - - // Events, because they created both inside and outside - // the state system by various parties. - class IEvent : public NVRefCounted - { - protected: - virtual ~IEvent() {} - public: - virtual CRegisteredString GetName() const = 0; - // Optional type string for rtti. No string means this is an opaque event - // that cannot be safely cast to any specific event type. - virtual CRegisteredString GetEventType() const { return CRegisteredString(); } - }; - - typedef NVScopedRefCounted TEventPtr; - - struct SIdValue; - - typedef nvhash_map TIDStateMap; - - struct SDOMElementNode - { - SDOMElementNode *m_NextNode; - SDOMElement *m_Element; - SDOMElementNode(SDOMElement *elem = NULL) - : m_NextNode(NULL) - , m_Element(elem) - { - } - }; - - struct SDOMAttributeNode - { - SDOMAttributeNode *m_NextNode; - SDOMAttribute *m_Attribute; - SDOMAttributeNode(SDOMAttribute *inAtt = NULL) - : m_NextNode(NULL) - , m_Attribute(inAtt) - { - } - }; - DEFINE_INVASIVE_SINGLE_LIST(DOMElementNode); - DEFINE_INVASIVE_SINGLE_LIST(DOMAttributeNode); - - inline bool SStateNode::IsCompound() const - { - if (m_Type == StateNodeTypes::SCXML) - return true; - if (m_Type == StateNodeTypes::State) - return !IsAtomic(); - return false; - } - - inline bool SStateNode::IsAtomic() const - { - if (m_Type == StateNodeTypes::SCXML) - return false; - - if (m_Type == StateNodeTypes::State) { - const SState *theState = CastTo(); - for (TStateNodeList::iterator iter = theState->m_Children.begin(), - end = theState->m_Children.end(); - iter != end; ++iter) { - if (iter->m_Type != StateNodeTypes::Transition - && iter->m_Type != StateNodeTypes::History) - return false; - } - return true; - } else if (m_Type == StateNodeTypes::Final) - return true; - return false; - } - - inline void SStateNode::AppendChild(SStateNode &inChild) - { - if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) { - static_cast(this)->AppendChild(inChild); - } else if (m_Type == StateNodeTypes::SCXML) { - static_cast(this)->AppendChild(inChild); - } else { - QT3DS_ASSERT(false); - } - } - - inline TOnEntryList *SStateNode::GetOnEntryList() - { - if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) - return &static_cast(this)->m_OnEntry; - if (m_Type == StateNodeTypes::Final) - return &CastTo()->m_OnEntry; - return NULL; - } - - inline TOnExitList *SStateNode::GetOnExitList() - { - if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) - return &static_cast(this)->m_OnExit; - if (m_Type == StateNodeTypes::Final) - return &CastTo()->m_OnExit; - return NULL; - } - - inline STransition *SStateNode::GetInitialTransition() - { - if (m_Type == StateNodeTypes::State) - return static_cast(this)->m_Initial; - if (m_Type == StateNodeTypes::SCXML) - return static_cast(this)->m_Initial; - return NULL; - } - - inline const char8_t *SStateNode::GetInitialExpression() - { - if (m_Type == StateNodeTypes::State) - return nonNull(static_cast(this)->m_InitialExpr); - if (m_Type == StateNodeTypes::SCXML) - return nonNull(static_cast(this)->m_InitialExpr); - return ""; - } - - inline TStateNodeList *SStateNode::GetChildren() - { - if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) - return &static_cast(this)->m_Children; - if (m_Type == StateNodeTypes::SCXML) - return &static_cast(this)->m_Children; - return NULL; - } - - inline SDataModel *SStateNode::GetDataModel() - { - if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) - return static_cast(this)->m_DataModel; - if (m_Type == StateNodeTypes::SCXML) - return static_cast(this)->m_DataModel; - return NULL; - } - - IMPLEMENT_INVASIVE_LIST(Invoke, m_PreviousSibling, m_NextSibling); - IMPLEMENT_INVASIVE_LIST(StateNode, m_PreviousSibling, m_NextSibling); - IMPLEMENT_INVASIVE_SINGLE_LIST(OnEntry, m_NextSibling); - IMPLEMENT_INVASIVE_SINGLE_LIST(OnExit, m_NextSibling); - IMPLEMENT_INVASIVE_SINGLE_LIST(DOMElementNode, m_NextNode); - IMPLEMENT_INVASIVE_SINGLE_LIST(DOMAttributeNode, m_NextNode); - - DEFINE_INVASIVE_SINGLE_LIST(Data); - - struct SDataModel - { - CRegisteredString m_Id; - const char8_t *m_Source; - const char8_t *m_Expression; - TDataList m_Data; - - SDataModel() - : m_Source(NULL) - , m_Expression(NULL) - { - } - }; - - struct SData - { - CRegisteredString m_Id; - const char8_t *m_Source; - const char8_t *m_Expression; - SData *m_NextSibling; - SData() - : m_Source(NULL) - , m_Expression(NULL) - , m_NextSibling(NULL) - { - } - }; - - IMPLEMENT_INVASIVE_SINGLE_LIST(Data, m_NextSibling); -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContext.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContext.h deleted file mode 100644 index 192181e4..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContext.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_STATE_VISUAL_BINDING_CONTEXT_H -#define QT3DS_STATE_VISUAL_BINDING_CONTEXT_H -#include "Qt3DSState.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/StringTable.h" -#include "Qt3DSStateVisualBindingContextCommands.h" - -namespace qt3ds { -namespace foundation { - class IDOMReader; - class CStrTableOrDataRef; -} -} - -namespace qt3ds { -namespace state { - - struct SVisualStateCommand; - struct SSetAttribute; - - // Entity responsible for implementing the various visual state commands. - class IVisualStateCommandHandler : public NVRefCounted - { - protected: - virtual ~IVisualStateCommandHandler() {} - public: - virtual void Handle(const SVisualStateCommand &inCommand, - IScriptContext &inScriptContext) = 0; - }; - - class IVisualStateInterpreterFactory : public NVRefCounted - { - protected: - virtual ~IVisualStateInterpreterFactory() {} - }; - - // It is important that the visual state context list the elements it expects to find in a uip - // file - // so that during parse of the uip file, we can generate an error if some element isn't found. - struct SElementReference - { - CRegisteredString m_ElementPath; - CRegisteredString m_Attribute; - SElementReference(CRegisteredString elemPath = CRegisteredString(), - CRegisteredString att = CRegisteredString()) - : m_ElementPath(elemPath) - , m_Attribute(att) - { - } - }; - - class IVisualStateContext : public NVRefCounted - { - protected: - virtual ~IVisualStateContext() {} - public: - // All machines are loaded execute is called on the first update call. - // made after LoadVisualStateMapping - virtual void LoadStateMachine(const char8_t *id, const char8_t *inRelativePath, - const char8_t *inDatamodelFunction) = 0; - virtual void LoadVisualStateMapping(IDOMReader &inReader) = 0; - // We have to pre-parse the xml so we can reference everything in the various presentations - // We run this pass, then during uip file parsing we output errors if things don't match up. - virtual NVConstDataRef PreParseDocument(IDOMReader &inReader) = 0; - virtual void SetCommandHandler(IVisualStateCommandHandler *inHandler) = 0; - virtual void SetInterpreterFactory(IVisualStateInterpreterFactory *inHandler) = 0; - - // Initialize the state machines. Machines are initialized in order of LoadStateMachine - // calls. - virtual void Initialize() = 0; - virtual void Start() = 0; - - // Initialize the state machines. Machines are updated in order of LoadStateMachine calls. - virtual void Update() = 0; - - // Save out to a format that allows very rapid loading. - virtual void BinarySave(IOutStream &stream) = 0; - virtual void BinaryLoad(IInStream &stream, NVDataRef inStringTableData) = 0; - - static IVisualStateContext &Create(NVFoundationBase &inFoundation, - IStringTable &inStrTable); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextCommands.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextCommands.h deleted file mode 100644 index 4d08f695..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextCommands.h +++ /dev/null @@ -1,348 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_STATE_VISUAL_BINDING_CONTEXT_COMMANDS_H -#define QT3DS_STATE_VISUAL_BINDING_CONTEXT_COMMANDS_H -#include "Qt3DSState.h" -#include "foundation/StringTable.h" - -namespace qt3ds { -namespace state { - - struct VisualStateCommandTypes - { - enum Enum { - NoVisualStateCommand = 0, - GotoSlide, - CallFunction, - SetAttribute, - GotoSlideRelative, - FireEvent, - PresentationAttribute, - PlaySound, - }; - }; - - struct SlidePlaybackModes - { - enum Enum { - StopAtEnd = 0, - Looping, - PingPong, - Ping, - PlaythroughTo, - }; - }; - - struct SGotoSlideData - { - Option m_Mode; - Option m_PlaythroughTo; - Option m_StartTime; - QT3DSF32 m_Rate; - bool m_Reverse; - Option m_Paused; - SGotoSlideData() - : m_Rate(1.0f) - , m_Reverse(false) - { - } - }; - - // All the element references in this file need to be absolute, meaning they - // must begin with a presentationid:. The is because the state machine exists at the - // application level where all presentations are pretty much equal and must be referenced - // by id. - - // Go to a particular slide. - - /* - a. If the slide attribute references a slide name not present on the time context an error must - be logged each time the executable would have been run, and the executable ignored. - b. If the time context is already on the slide referenced, no change is made to the time - context. - The slide does not restart. */ - struct SGotoSlide - { - CRegisteredString m_Component; - CRegisteredString m_Slide; - SGotoSlideData m_GotoSlideData; - SGotoSlide(CRegisteredString cmd = CRegisteredString(), - CRegisteredString slide = CRegisteredString()) - : m_Component(cmd) - , m_Slide(slide) - { - } - bool operator==(const SGotoSlide &inOther) const - { - return m_Component == inOther.m_Component && m_Slide == inOther.m_Slide; - } - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_Component); - inRemapper.Remap(m_Slide); - } - }; - - /* - 1. A executable must have a element="..." attribute that references a behavior - element in one of the presentation assets for the application. - a. If the element attribute is missing, or references an element that cannot be found, - an error must be logged each time the executable would have been run, and the executable - ignored. - b. If the element attribute references an element that is not a behavior then an error - must be logged each time the executable would have been run, and the executable ignored. - 2. A executable must have a handler="..." attribute that references a function value - in the table associated with the behavior element. - a. If the handler attribute is missing, or references a value that is not a function - value, an error must be logged each time the executable would have been run, and the executable - ignored. - 3. A executable may have an args="..." attribute that specifies an expression to - evaluate. - a. If the result of evaluating this expression is a single value, it is passed as the - first argument to the behavior's function. - b. If the result of evaluating this expression is a table, it is treated as a list that - is unpack'd, the numeric properties sent as arguments in order. - c. If the result of evaluating this expression is an error, an error message must be - logged and the executable ignored. - The function is not invoked with no parameters. - */ - struct SCallFunction - { - CRegisteredString m_Behavior; - CRegisteredString m_Handler; - CRegisteredString m_Arguments; - SCallFunction(CRegisteredString behavior = CRegisteredString(), - CRegisteredString hdler = CRegisteredString(), - CRegisteredString args = CRegisteredString()) - : m_Behavior(behavior) - , m_Handler(hdler) - , m_Arguments(args) - { - } - bool operator==(const SCallFunction &inOther) const - { - return m_Behavior == inOther.m_Behavior && m_Handler == inOther.m_Handler - && m_Arguments == inOther.m_Arguments; - } - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_Behavior); - inRemapper.Remap(m_Handler); - inRemapper.Remap(m_Arguments); - } - }; - - /* - 1. A executable must have an element="..." attribute that references an - element in one of the presentation assets for the application. - a. If the element attribute is missing, or references an element that cannot be found, - an error must be logged each time the executable would have been run, and the executable - ignored. - 2. A executable must have an attribute="..." attribute that references an - attribute on the referenced element. - a. If the attribute attribute is missing, or references an attribute not present on the - element, an error must be logged each time the executable would have been run, and the - executable ignored. - 3. A executable must have an value="..." attribute that describes the value - to set. - a. The contents of this attribute are evaluated as an expression and the result used - to set the attribute. - i. If the result of evaluating this expression does not match the type of the - attribute on the element then an error must be logged and the executable ignored. - 4. If a single visual state has both and executables, and the - slide change affects the same attribute as the set-attribute executable, then the set-attribute - executable must take effect (be applied after the slide change occurs). - In the future we may wish to have the order of this interaction controllable by the - ordering of the executables. - */ - struct SSetAttribute - { - CRegisteredString m_Element; - CRegisteredString m_Attribute; - CRegisteredString m_Value; - SSetAttribute(CRegisteredString elem = CRegisteredString(), - CRegisteredString att = CRegisteredString(), - CRegisteredString val = CRegisteredString()) - : m_Element(elem) - , m_Attribute(att) - , m_Value(val) - { - } - bool operator==(const SSetAttribute &inOther) const - { - return m_Element == inOther.m_Element && m_Attribute == inOther.m_Attribute - && m_Value == inOther.m_Value; - } - - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_Element); - inRemapper.Remap(m_Attribute); - inRemapper.Remap(m_Value); - } - }; - - /* - 4. A rel="..." attribute must have either the value next or prev. - a. If the rel attribute has a different value an error must be logged each time the - executable would have been run, and the executable ignored. - b. A value of next causes the time context to go to the next slide. - i. If the time context is at the last slide, and there is no wrap attribute, or - the wrap attribute does not have a value of true, then no change occurs to the time context. - The slide does not restart. - ii. If the time context is at the last slide and there exists a wrap attribute - with a value of true then the time context is taken to the first slide. - c. A value of prev causes the time context to go to the previous slide. - i. If the time context is at the first slide, and there is no wrap attribute, or - the wrap attribute does not have a value of true, then no change occurs to the time context. - The slide does not restart. - ii. If the time context is at the last first and there exists a wrap attribute - with a value of true then the time context is taken to the last slide. - */ - struct SGotoSlideRelative - { - CRegisteredString m_Component; - enum Enum { - Next = 0, - Previous, - Error, - }; - Enum m_Direction; - bool m_Wrap; - SGotoSlideData m_GotoSlideData; - SGotoSlideRelative(CRegisteredString comp = CRegisteredString(), Enum dir = Next, - bool wrap = false) - : m_Component(comp) - , m_Direction(dir) - , m_Wrap(wrap) - { - } - bool operator==(const SGotoSlideRelative &inOther) const - { - return m_Component == inOther.m_Component && m_Direction == inOther.m_Direction - && m_Wrap == inOther.m_Wrap; - } - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_Component); - } - }; - - /* - 1. A executable must have an element="..." attribute that references an element - in one of the presentation assets for the application. - a. If the element attribute is missing, or references an element that cannot be found, - an error must be logged each time the executable would have been run, and the executable - ignored. - 2. A executable must have an event="..." attribute that describes the event - name to fire. - a. If the event attribute is missing an error must be logged each time the executable - would have been run, and the executable ignored. - */ - struct SFireEvent - { - CRegisteredString m_Element; - CRegisteredString m_Event; - SFireEvent(CRegisteredString elem, CRegisteredString evt) - : m_Element(elem) - , m_Event(evt) - { - } - SFireEvent() {} - bool operator==(const SFireEvent &inOther) const - { - return m_Element == inOther.m_Element && m_Event == inOther.m_Event; - } - - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_Element); - inRemapper.Remap(m_Event); - } - }; - - struct SPresentationAttribute - { - CRegisteredString m_Presentation; - CRegisteredString m_Attribute; - CRegisteredString m_Value; - SPresentationAttribute(CRegisteredString pres, CRegisteredString att, CRegisteredString val) - : m_Presentation(pres) - , m_Attribute(att) - , m_Value(val) - { - } - SPresentationAttribute() {} - bool operator==(const SPresentationAttribute &inOther) const - { - return m_Presentation == inOther.m_Presentation && m_Attribute == inOther.m_Attribute - && m_Value == inOther.m_Value; - } - - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_Presentation); - inRemapper.Remap(m_Attribute); - inRemapper.Remap(m_Value); - } - }; - - struct SPlaySound - { - CRegisteredString m_SoundFilePath; - SPlaySound(CRegisteredString inSoundFilePath) - : m_SoundFilePath(inSoundFilePath) - { - } - SPlaySound() {} - bool operator==(const SPlaySound &inOther) const - { - return m_SoundFilePath == inOther.m_SoundFilePath; - } - - template - void Remap(TRemapper &inRemapper) - { - inRemapper.Remap(m_SoundFilePath); - } - }; - - // defined in UICStateVisualBindingContextValues.h - struct SVisualStateCommand; -} -} -#endif diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextValues.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextValues.h deleted file mode 100644 index 7bad9b33..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateVisualBindingContextValues.h +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_STATE_VISUAL_BINDING_CONTEXT_VALUES_H -#define QT3DS_STATE_VISUAL_BINDING_CONTEXT_VALUES_H -#include "Qt3DSStateVisualBindingContext.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" -#include "Qt3DSStateVisualBindingContextCommands.h" - -namespace qt3ds { -namespace state { - - template - struct SVisualStateCommandTypeMap - { - }; - - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::GotoSlide; - } - }; - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::CallFunction; - } - }; - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::SetAttribute; - } - }; - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::GotoSlideRelative; - } - }; - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::FireEvent; - } - }; - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::PresentationAttribute; - } - }; - template <> - struct SVisualStateCommandTypeMap - { - static VisualStateCommandTypes::Enum GetType() - { - return VisualStateCommandTypes::PlaySound; - } - }; - - struct SVisualStateCommandUnionTraits - { - typedef VisualStateCommandTypes::Enum TIdType; - enum { - TBufferSize = sizeof(SGotoSlideRelative), - }; - - static TIdType getNoDataId() { return VisualStateCommandTypes::NoVisualStateCommand; } - - template - static TIdType getType() - { - return SVisualStateCommandTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case VisualStateCommandTypes::GotoSlide: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::CallFunction: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::SetAttribute: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::GotoSlideRelative: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::FireEvent: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::PresentationAttribute: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::PlaySound: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case VisualStateCommandTypes::NoVisualStateCommand: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case VisualStateCommandTypes::GotoSlide: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::CallFunction: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::SetAttribute: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::GotoSlideRelative: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::FireEvent: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::PresentationAttribute: - return inVisitor(*NVUnionCast(inData)); - case VisualStateCommandTypes::PlaySound: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case VisualStateCommandTypes::NoVisualStateCommand: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SVisualStateCommandUnionTraits::TBufferSize> - TVisualStateCommandUnionType; - - struct SVisualStateCommand : public TVisualStateCommandUnionType - { - SVisualStateCommand() {} - - SVisualStateCommand(const SVisualStateCommand &inOther) - : TVisualStateCommandUnionType( - static_cast(inOther)) - { - } - - template - SVisualStateCommand(const TDataType &inDt) - : TVisualStateCommandUnionType(inDt) - { - } - - SVisualStateCommand &operator=(const SVisualStateCommand &inOther) - { - TVisualStateCommandUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SVisualStateCommand &inOther) const - { - return TVisualStateCommandUnionType::operator==(inOther); - } - bool operator!=(const SVisualStateCommand &inOther) const - { - return TVisualStateCommandUnionType::operator!=(inOther); - } - - bool empty() const { return getType() == VisualStateCommandTypes::NoVisualStateCommand; } - }; -} -} -#ifndef _INTEGRITYPLATFORM -namespace qt3ds { -namespace foundation { - - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SGotoSlide &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SCallFunction &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SSetAttribute &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SGotoSlideRelative &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SFireEvent &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SPresentationAttribute &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::state::SPlaySound &) {} - }; -} -} -#endif -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateXMLIO.h b/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateXMLIO.h deleted file mode 100644 index 3a639845..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Include/Qt3DSStateXMLIO.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_STATE_XML_IO_H -#define QT3DS_STATE_XML_IO_H -#pragma once -#include "Qt3DSState.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/StringTable.h" -#include "foundation/XML.h" -#include "EASTL/map.h" -#include "EASTL/string.h" - -namespace qt3ds { -namespace foundation { - class IDOMReader; - class IDOMWriter; -} -} - -namespace qt3ds { -namespace state { - - struct SExecutableContent; - class CXMLIO - { - public: - typedef eastl::map TIdRemapMap; - - static void GenerateUniqueId(SStateNode &inNode, const char8_t *inStem, - IStateContext &ioContext, IStringTable &ioStringTable); - static void GenerateUniqueId(SSend &inNode, const char8_t *inStem, IStateContext &ioContext, - IStringTable &ioStringTable); - // Load an SCXML file and return the root states - // All states, transitions, and memory used in the graph is allocated using the graph - // allocator. - // This makes freeing the memory much easier because you can just free it by releasing the - // graph - // allocator and you don't have to go object by object. - // Filename is just used as another tag or name on the scxml object. - static bool LoadSCXMLFile(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, - IDOMReader &inReader, IStringTable &inStringTable, - const char8_t *inFilename, IStateContext &outContext, - editor::IEditor *inEditor = NULL); - - // Loading fragments remaps their ids to avoid conflics. Returns the top nodes from the - // scxml graph. - static eastl::pair, TIdRemapMap> - LoadSCXMLFragment(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, - IDOMReader &inReader, IStringTable &inStringTable, - IStateContext &ioContext, editor::IEditor &inEditor); - - // We write all the way to file instead of a DOM writer because we have to add xml - // namespaces and those can only - // be added during the actual serialization process. - static void SaveSCXMLFile(IStateContext &inContext, NVFoundationBase &inFnd, - IStringTable &inStringTable, IOutStream &outStream, - editor::IEditor *inEditor = NULL); - - static void FindRoots(NVConstDataRef inObjects, - eastl::vector &outRoots); - - // Returns the roots of the copied list - static eastl::vector - SaveSCXMLFragment(IStateContext &inContext, NVFoundationBase &inFnd, - IStringTable &inStringTable, IDOMWriter &ioWriter, - NVDataRef inObjects, editor::IEditor &inEditor, - const QT3DSVec2 &inMousePos, eastl::vector &outNamespaces); - - static void ToEditableXml(IStateContext &inContext, NVFoundationBase &inFnd, - IStringTable &inStringTable, IDOMWriter &ioWriter, - SExecutableContent &inContent, editor::IEditor &inEditor); - - static SExecutableContent * - FromEditableXML(IDOMReader &inReader, NVFoundationBase &inFnd, IStateContext &inContext, - IStringTable &inStringTable, NVAllocatorCallback &inGraphAllocator, - editor::IEditor &inEditor, SStateNode *inStateNodeParent, - SExecutableContent *inExecContentParent); - - static eastl::vector GetSupportedExecutableContentNames(); - }; -} -} - -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateContext.cpp b/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateContext.cpp deleted file mode 100644 index 60814ed5..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateContext.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateContext.h" -#include "Qt3DSStateXMLIO.h" -#include "foundation/XML.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" - -using namespace qt3ds::state; - -namespace { - -struct SStateContext : public IStateContext -{ - NVFoundationBase &m_Foundation; - TIDStateMap m_IDStateMap; - TSendList m_SendList; - SSCXML *m_Root; - - // the factory needs to be here in order that we can easily just assign variables - // left and right and make things work. - NVScopedRefCounted m_DOMFactory; - TPtrExtensionMap m_ExtensionInfo; - SNamespacePairNode *m_NamespacePairs; - QT3DSI32 mRefCount; - - SStateContext(NVFoundationBase &alloc) - : m_Foundation(alloc) - , m_IDStateMap(alloc.getAllocator(), "SStateContext::m_IDStateMap") - , m_SendList(alloc.getAllocator(), "SStateContext::m_SendList") - , m_Root(NULL) - , m_DOMFactory(NULL) - , m_ExtensionInfo(alloc.getAllocator(), "SStateContext::m_ExtensionInfo") - , m_NamespacePairs(NULL) - , mRefCount(0) - { - } - virtual ~SStateContext() {} - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - void SetDOMFactory(IDOMFactory *inFactory) override; - - void SetRoot(SSCXML &inRoot) override - { - QT3DS_ASSERT(m_Root == NULL); - if (!m_Root) - m_Root = &inRoot; - } - SSCXML *GetRoot() override { return m_Root; } - void AddSendToList(SSend &inSend) override { m_SendList.push_back(&inSend); } - NVConstDataRef GetSendList() override - { - return toConstDataRef(m_SendList.data(), (QT3DSU32)m_SendList.size()); - } - IDOMFactory *GetDOMFactory() override { return m_DOMFactory; } - NVConstDataRef> GetSubContexts() override - { - return NVConstDataRef>(); - } - - // UICStateInterpreter.cpp; - bool InsertId(const CRegisteredString &inId, const SIdValue &inValue) override; - void EraseId(const CRegisteredString &inId) override; - bool ContainsId(const CRegisteredString &inStr) override; - SStateNode *FindStateNode(const CRegisteredString &inStr) override; - SSend *FindSend(const CRegisteredString &inStr) override; - - SItemExtensionInfo *GetExtensionInfo(void *inItem) override; - SItemExtensionInfo &GetOrCreateExtensionInfo(void *inItem) override; - - void SetFirstNSNode(SNamespacePairNode &inNode) override { m_NamespacePairs = &inNode; } - SNamespacePairNode *GetFirstNSNode() override { return m_NamespacePairs; } - - void Save(IOutStream &inOutStream, editor::IEditor *inEditor) override; -}; - -void SStateContext::SetDOMFactory(IDOMFactory *inFactory) -{ - m_DOMFactory = inFactory; -} - -bool SStateContext::InsertId(const CRegisteredString &inId, const SIdValue &inValue) -{ - return m_IDStateMap.insert(eastl::make_pair(inId, inValue)).second; -} - -void SStateContext::EraseId(const CRegisteredString &inId) -{ - m_IDStateMap.erase(inId); -} - -bool SStateContext::ContainsId(const CRegisteredString &inStr) -{ - return m_IDStateMap.find(inStr) != m_IDStateMap.end(); -} - -SStateNode *SStateContext::FindStateNode(const CRegisteredString &inStr) -{ - TIDStateMap::iterator iter = m_IDStateMap.find(inStr); - - if (iter != m_IDStateMap.end()) { - IdValueTypes::Enum typeEnum = iter->second.getType(); - if (typeEnum == IdValueTypes::StateNode) - return iter->second.getData(); - } - return NULL; -} - -SSend *SStateContext::FindSend(const CRegisteredString &inStr) -{ - TIDStateMap::iterator iter = m_IDStateMap.find(inStr); - if (iter != m_IDStateMap.end() && iter->second.getType() == IdValueTypes::Send) - return iter->second.getData(); - return NULL; -} - -SItemExtensionInfo *SStateContext::GetExtensionInfo(void *inItem) -{ - TPtrExtensionMap::iterator iter = m_ExtensionInfo.find(inItem); - if (iter != m_ExtensionInfo.end()) - return &iter->second; - return NULL; -} - -SItemExtensionInfo &SStateContext::GetOrCreateExtensionInfo(void *inItem) -{ - return m_ExtensionInfo.insert(eastl::make_pair(inItem, SItemExtensionInfo(inItem))) - .first->second; -} - -void SStateContext::Save(IOutStream &inOutStream, editor::IEditor *inEditor) -{ - CXMLIO::SaveSCXMLFile(*this, m_Foundation, *m_DOMFactory->GetStringTable(), inOutStream, - inEditor); -} -} - -IStateContext *IStateContext::Load(NVAllocatorCallback &inGraphAllocator, - NVFoundationBase &inFoundation, IInStream &inStream, - const char8_t *inFilename, IStringTable *inStrTable, - editor::IEditor *inEditor) -{ - - NVScopedRefCounted theStringTable = inStrTable; - if (!theStringTable) - theStringTable = IStringTable::CreateStringTable(inFoundation.getAllocator()); - NVScopedRefCounted theFactory = - IDOMFactory::CreateDOMFactory(inFoundation.getAllocator(), theStringTable); - eastl::pair readResult = - CDOMSerializer::Read(*theFactory, inStream); - SDOMElement *elem = readResult.second; - if (elem == NULL) - return NULL; - - NVScopedRefCounted theReader = IDOMReader::CreateDOMReader( - inFoundation.getAllocator(), *elem, theStringTable, *theFactory); - IStateContext *retval = QT3DS_NEW(inFoundation.getAllocator(), SStateContext)(inFoundation); - retval->SetDOMFactory(theFactory.mPtr); - CXMLIO::LoadSCXMLFile(inGraphAllocator, inFoundation, *theReader, *theStringTable, inFilename, - *retval, inEditor); - if (readResult.first) - retval->SetFirstNSNode(*readResult.first); - return retval; -} - -IStateContext *IStateContext::Create(NVFoundationBase &inFoundation) -{ - NVScopedRefCounted theStringTable = - IStringTable::CreateStringTable(inFoundation.getAllocator()); - NVScopedRefCounted theFactory = - IDOMFactory::CreateDOMFactory(inFoundation.getAllocator(), theStringTable); - - SStateContext *retval = QT3DS_NEW(inFoundation.getAllocator(), SStateContext)(inFoundation); - retval->SetDOMFactory(theFactory); - return retval; -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateExecutionContext.cpp b/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateExecutionContext.cpp deleted file mode 100644 index 4516c2f9..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateExecutionContext.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateExecutionContext.h" -#include "Qt3DSStateExecutionTypes.h" -#include "Qt3DSStateInterpreter.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/StringConversionImpl.h" -#include "Qt3DSStateScriptContext.h" -#include "foundation/Utils.h" -#include "EASTL/string.h" - -using namespace qt3ds::state; - -namespace { -struct SExecContext : public IExecutionContext -{ - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_StringTable; - // Referencing this here would create circular references - IStateInterpreter *m_Interpreter; - IStateLogger *m_DebugLogger; - NVScopedRefCounted m_Logger; - NVScopedRefCounted m_ScriptContext; - bool m_Error; - QT3DSI32 mRefCount; - eastl::string m_DelayStr; - - SExecContext(NVFoundationBase &inFnd, IStringTable &inStrTable, IStateLogger &inLogger, - IScriptContext &inContext) - : m_Foundation(inFnd) - , m_StringTable(inStrTable) - , m_Interpreter(NULL) - , m_DebugLogger(NULL) - , m_Logger(inLogger) - , m_ScriptContext(inContext) - , m_Error(false) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void SetInterpreter(IStateInterpreter &inInterpreter) override - { - m_Interpreter = &inInterpreter; - } - - void SetMachineDebugLogger(IStateLogger &inDebugLogger) override - { - m_DebugLogger = &inDebugLogger; - } - - void SignalError() - { - const char8_t *errorInfo = m_ScriptContext->GetErrorInfo(); - if (errorInfo && *errorInfo) { - m_Interpreter->QueueEvent("error.execution", false); - } - m_Error = true; - } - void ExecuteContent(SExecutableContent &content) - { - switch (content.m_Type) { - case ExecutableContentTypes::Send: { - SSend &theSend = *content.CastTo(); - CRegisteredString theEvent; - if (!isTrivial(theSend.m_EventExpr)) { - SScriptExecutionResult theStr = - m_ScriptContext->ExecuteExpressionToString(theSend.m_EventExpr); - if (theStr.Valid()) - theEvent = m_StringTable->RegisterStr(theStr.Result()); - } else - theEvent = theSend.m_Event; - - QT3DSU64 theDelay(0); - m_DelayStr.clear(); - if (!isTrivial(theSend.m_DelayExpr)) { - SScriptExecutionResult theStr = - m_ScriptContext->ExecuteExpressionToString(theSend.m_DelayExpr); - if (theStr.Valid()) - m_DelayStr.assign(nonNull(theStr.Result())); - } else - m_DelayStr.assign(nonNull(theSend.m_Delay)); - if (m_DelayStr.size()) - theDelay = ParseTimeStrToMilliseconds(m_DelayStr.c_str()); - - if (theEvent.IsValid()) { - TEventPtr theEventPtr; - if (theSend.m_Children.empty() == false) { - IScriptEvent *theNewEvent = m_ScriptContext->CreateScriptEvent(theEvent); - theEventPtr = theNewEvent; - for (TExecutableContentList::iterator iter = theSend.m_Children.begin(), - end = theSend.m_Children.end(); - iter != end && m_Error == false; ++iter) { - if (iter->m_Type == ExecutableContentTypes::Param) { - SParam &theParam = static_cast(*iter); - if (theParam.m_Location.IsValid() == false) { - bool success = - theNewEvent->SetParam(theParam.m_Name, theParam.m_Expr); - if (!success) - SignalError(); - } else { - QT3DS_ASSERT(false); - } - } else if (iter->m_Type == ExecutableContentTypes::Content) { - SContent &theContent = static_cast(*iter); - if (!isTrivial(theContent.m_Expr)) { - bool success = theNewEvent->SetDataExpr(theContent.m_Expr); - if (!success) - SignalError(); - } else if (!isTrivial(theContent.m_ContentValue)) { - bool success = theNewEvent->SetDataStr(theContent.m_ContentValue); - if (!success) - SignalError(); - } - } else { - QT3DS_ASSERT(false); - } - } - } - if (m_Error == false) { - bool isExternal = true; - if (AreEqual("#_internal", theSend.m_Target)) - isExternal = false; - if (theEventPtr) - m_Interpreter->QueueEvent(theEventPtr, theDelay, theSend.m_Id, isExternal); - else - m_Interpreter->QueueEvent(theEvent, theDelay, theSend.m_Id, isExternal); - } - } - } break; - case ExecutableContentTypes::Cancel: { - SCancel &theCancel = *content.CastTo(); - if (theCancel.m_Send) { - m_Interpreter->CancelEvent(theCancel.m_Send->m_Id); - } else if (!isTrivial(theCancel.m_IdExpression)) { - SScriptExecutionResult theStr = - m_ScriptContext->ExecuteExpressionToString(theCancel.m_IdExpression); - if (theStr.Valid()) { - const char8_t *theStrVal(theStr.Result()); - if (!isTrivial(theStrVal)) - m_Interpreter->CancelEvent(m_StringTable->RegisterStr(theStrVal)); - } - } - } break; - case ExecutableContentTypes::Raise: { - SRaise &theRaise = *content.CastTo(); - m_Interpreter->QueueEvent(theRaise.m_Event, false); - } break; - case ExecutableContentTypes::Log: { - SLog *theLog = content.CastTo(); - SScriptExecutionResult str = - m_ScriptContext->ExecuteExpressionToString(theLog->m_Expression); - if (str.Valid()) { - m_Logger->Log(theLog->m_Label, str.Result()); - if (m_DebugLogger) - m_DebugLogger->Log(theLog->m_Label, str.Result()); - } else - SignalError(); - } break; - case ExecutableContentTypes::If: { - SIf &theIf = *content.CastTo(); - Option theCondResult = m_ScriptContext->ExecuteCondition(theIf.m_Cond); - if (theCondResult.hasValue()) { - bool currentConditionResult = *theCondResult; - for (TExecutableContentList::iterator ifIter = theIf.m_Children.begin(), - ifEnd = theIf.m_Children.end(); - ifIter != ifEnd && m_Error == false; ++ifIter) { - if (currentConditionResult) { - switch (ifIter->m_Type) { - case ExecutableContentTypes::Else: - case ExecutableContentTypes::ElseIf: - return; - default: - ExecuteContent(*ifIter); - break; - } - } else { - switch (ifIter->m_Type) { - case ExecutableContentTypes::ElseIf: { - SElseIf &theElseIf = *ifIter->CastTo(); - theCondResult = m_ScriptContext->ExecuteCondition(theElseIf.m_Cond); - if (theCondResult.hasValue()) - currentConditionResult = *theCondResult; - else { - SignalError(); - return; - } - } break; - case ExecutableContentTypes::Else: - currentConditionResult = true; - break; - // Ignore all content that isn't if or else if we shouldn't be currently - // executing it. - default: - break; - } - } - } - } else - SignalError(); - } break; - case ExecutableContentTypes::Foreach: { - SForeach &theItem = *content.CastTo(); - Option success; - for (success = m_ScriptContext->BeginForeach(theItem.m_Array, theItem.m_Item, - theItem.m_Index); - success.hasValue() && *success && m_Error == false; - success = m_ScriptContext->NextForeach(theItem.m_Item, theItem.m_Index)) { - ExecuteContent(theItem.m_Children); - } - if (m_Error) { - - } else if (success.hasValue() == false) - SignalError(); - } break; - // We shouldn't get top level else or else if statements, they can only be inside an if - // statement. - case ExecutableContentTypes::Else: - case ExecutableContentTypes::ElseIf: - QT3DS_ASSERT(false); - break; - - case ExecutableContentTypes::Assign: { - SAssign &theAssign = *content.CastTo(); - bool success = m_ScriptContext->Assign(theAssign.m_Location, theAssign.m_Expression); - if (!success) - SignalError(); - } break; - case ExecutableContentTypes::Script: { - SScript &theScript = *content.CastTo(); - if (!isTrivial(theScript.m_Data)) - m_ScriptContext->ExecuteScript(theScript.m_Data); - } break; - default: - qCCritical(INTERNAL_ERROR, "Unimplemented executable content %s", - ExecutableContentTypes::ToString(content.m_Type)); - } - } - - void ExecuteContent(TExecutableContentList &inContent) - { - for (TExecutableContentList::iterator iter = inContent.begin(), end = inContent.end(); - iter != end && m_Error == false; ++iter) { - ExecuteContent(*iter); - } - } - - void Execute(STransition &inTransaction) override - { - m_Error = false; - ExecuteContent(inTransaction.m_ExecutableContent); - } - - // These functions take the node as well as the list so a context can cache a fast - // execution path if necessary. - void Execute(SStateNode & /*inNode*/, TOnEntryList &inList) override - { - for (TOnEntryList::iterator iter = inList.begin(), end = inList.end(); iter != end; - ++iter) { - m_Error = false; - ExecuteContent(iter->m_ExecutableContent); - } - } - - void Execute(SStateNode & /*inNode*/, TOnExitList &inList) override - { - for (TOnExitList::iterator iter = inList.begin(), end = inList.end(); iter != end; ++iter) { - m_Error = false; - ExecuteContent(iter->m_ExecutableContent); - } - } -}; -} - -QT3DSU64 IExecutionContext::ParseTimeStrToMilliseconds(const char8_t *timeStr) -{ - if (isTrivial(timeStr)) - return 0; - - char *endPtr; - double theData = strtod(timeStr, &endPtr); - if (!isTrivial(endPtr)) { - if (AreEqual(endPtr, "s")) { - theData *= 1000; - } else if (AreEqual(endPtr, "ms")) { - // empty intentional - } else - theData = 0; - } else - theData = 0; - if (theData < 0) - theData = 0.0; - return static_cast(theData); -} - -IExecutionContext &IExecutionContext::Create(NVFoundationBase &inFoundation, - IStringTable &inStringTable, IStateLogger &inLogger, - IScriptContext &inScriptContext) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SExecContext)(inFoundation, inStringTable, inLogger, - inScriptContext); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateInterpreter.cpp b/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateInterpreter.cpp deleted file mode 100644 index 9fc72406..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateInterpreter.cpp +++ /dev/null @@ -1,2057 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateTypes.h" -#include "Qt3DSStateInterpreter.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Utils.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSTime.h" -#include "EASTL/string.h" -#include "EASTL/set.h" -#include "EASTL/sort.h" -#include "EASTL/list.h" -#include "Qt3DSStateExecutionContext.h" -#include "Qt3DSStateExecutionTypes.h" -#include "Qt3DSStateScriptContext.h" -#include "Qt3DSStateSharedImpl.h" -#include "foundation/XML.h" -#include "Qt3DSStateIdValue.h" -#include "Qt3DSStateDebugger.h" -#include "Qt3DSStateXMLIO.h" -#include "Qt3DSStateDebuggerValues.h" -#include "Qt3DSStateContext.h" -#include "foundation/FastAllocator.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::debugger; - -#ifdef _DEBUG -#define QT3DS_LOG_ENTER_EXIT 1 -#define QT3DS_LOG_ACTIVE_EVENT 1 -#endif - -namespace qt3ds { -namespace state { - struct SInterpreterData - { - }; -} -} - -namespace { -struct SSimpleEvent : public IEvent -{ - NVAllocatorCallback &m_Alloc; - volatile QT3DSI32 mRefCount; - CRegisteredString m_Name; - - SSimpleEvent(NVAllocatorCallback &alloc, CRegisteredString nm) - : m_Alloc(alloc) - , mRefCount(0) - , m_Name(nm) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc) - - CRegisteredString GetName() const override { return m_Name; } -}; - -struct SStateNodeInterpreterData : public SInterpreterData -{ - - QT3DSI32 m_DocumentOrder; - bool m_Entered; - SStateNode *m_TransitionSubgraphRoot; - - SStateNodeInterpreterData(QT3DSI32 inDocOrder) - : m_DocumentOrder(inDocOrder) - , m_Entered(false) - , m_TransitionSubgraphRoot(NULL) - { - } -}; - -template , - typename TEqOp = eastl::equal_to> -struct SOrderedSet -{ - typedef eastl::hash_set TSetType; - typedef nvvector TListType; - - TSetType m_Set; - TListType m_List; - typedef typename TListType::iterator iterator; - - SOrderedSet(NVAllocatorCallback &alloc, const char *inTypeName) - : m_Set(ForwardingAllocator(alloc, inTypeName)) - , m_List(alloc, inTypeName) - { - } - - bool insert(const TDataType &inDtype) - { - if (m_Set.insert(inDtype).second) { - m_List.push_back(inDtype); - return true; - } - return false; - } - - void clear() - { - m_Set.clear(); - m_List.clear(); - } - - iterator begin() { return m_List.begin(); } - iterator end() { return m_List.end(); } - QT3DSU32 size() const { return m_List.size(); } - bool contains(const TDataType &inType) const { return m_Set.find(inType) != m_Set.end(); } - TDataType operator[](int inIndex) - { - if (inIndex < (int)size()) - return m_List[inIndex]; - return TDataType(); - } - void erase(const TDataType &inType) - { - typename TSetType::iterator iter = m_Set.find(inType); - if (iter != m_Set.end()) { - m_Set.erase(iter); - typename TListType::iterator iter = eastl::find(m_List.begin(), m_List.end(), inType); - if (iter != m_List.end()) - m_List.erase(iter); - else { - QT3DS_ASSERT(false); - } - } - } -}; - -struct SStateNodeNode -{ - SStateNode *m_Node; - SStateNodeNode *m_NextSibling; - SStateNodeNode() - : m_Node(NULL) - , m_NextSibling(NULL) - { - } - SStateNodeNode(SStateNode *inNode) - : m_Node(inNode) - , m_NextSibling(NULL) - { - } -}; - -DEFINE_INVASIVE_SINGLE_LIST(StateNodeNode); -IMPLEMENT_INVASIVE_SINGLE_LIST(StateNodeNode, m_NextSibling); - -struct SFutureEvent -{ - TEventPtr m_Event; - QT3DSU64 m_FireTime; - CRegisteredString m_CancelId; - bool m_IsExternal; - SFutureEvent(TEventPtr evt, QT3DSU64 ft, CRegisteredString id, bool inExternal) - : m_Event(evt) - , m_FireTime(ft) - , m_CancelId(id) - , m_IsExternal(inExternal) - { - } - SFutureEvent() - : m_FireTime((QT3DSU64)-1) - , m_IsExternal(false) - { - } - // We want the events sorted in *reverse* time order. - bool operator<(const SFutureEvent &inOther) const { return m_FireTime < inOther.m_FireTime; } -}; - -struct StateSystem; - -typedef SOrderedSet TStateNodeSet; -typedef SOrderedSet TTransitionSet; -typedef nvvector TTransitionList; - -struct SDebugInterface : public IStateMachineDebugInterface, public IStateLogger -{ - StateSystem &m_StateSystem; - // No listener means no events and no active breakpoints of course - NVScopedRefCounted m_Listener; - TDebugStr m_LogStr; - TDebugStr m_TempStr; - TDebugStrList m_EnterList; - TDebugStrList m_ExitList; - TTransitionIdList m_TransitionList; - - SDebugInterface(StateSystem &ss) - : m_StateSystem(ss) - , m_Listener(NULL) - { - } - // ignored as this object is part of the state system. - void addRef() override; - void release() override; - bool valid() { return m_Listener.mPtr != NULL; } - - void SetStateMachineListener(IStateMachineListener *inListener) override - { - if (m_Listener.mPtr != inListener) { - m_Listener = inListener; - if (m_Listener) - OnConnect(); - } - } - - // IStateLogger interface - void Log(const char8_t *inLabel, const char8_t *inExpression) override - { - if (m_Listener) { - m_LogStr.assign(nonNull(inLabel)); - m_LogStr.append(" - "); - m_LogStr.append(nonNull(inExpression)); - m_Listener->Log(m_LogStr); - } - } - - IScriptContext &GetScriptContext() override; - - // Functions implemented after StateSystem in order to take advantage of the StateSystem struct - // members directly. - void OnConnect(); - - void EventQueued(const char8_t *inEventName, bool inInternal) - { - m_Listener->EventQueued(inEventName, inInternal); - } - // Functions should not be called in there is not a valid listener - void BeginStep(); - void BeginMicrostep(); - void SetCurrentEvent(const char8_t *inEventName, bool inInternal); - void SetTransitionSet(const TTransitionList &inTransitions); - void SetExitSet(const TStateNodeSet &inSet); - void SetEnterSet(const TStateNodeSet &inSet); - // Log statements run through the debugger as well. - void EndMicrostep(); - void EndStep(); - void OnExternalBreak() override; -}; - -#define DEBUGGER_CALL(function) \ - if (m_DebugInterface.valid()) \ - m_DebugInterface.function(); -#define DEBUGGER_CALL1(function, arg) \ - if (m_DebugInterface.valid()) \ - m_DebugInterface.function(arg); -#define DEBUGGER_CALL2(function, arg, arg2) \ - if (m_DebugInterface.valid()) \ - m_DebugInterface.function(arg, arg2); - -#ifdef _WIN32 -#pragma warning(disable : 4355) -#endif -struct SStateSignalSender : public IStateSignalConnection -{ - NVAllocatorCallback &m_Alloc; - StateSystem *m_System; - IStateInterpreterEventHandler &m_Handler; - volatile QT3DSI32 mRefCount; - SStateSignalSender(NVAllocatorCallback &inAlloc, StateSystem &inSystem, - IStateInterpreterEventHandler &inHandler) - : m_Alloc(inAlloc) - , m_System(&inSystem) - , m_Handler(inHandler) - , mRefCount(0) - { - } - virtual ~SStateSignalSender(); - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc) -}; - -// Note that we explicity don't addref the signal sender internally. This is by design. -typedef nvvector TSignalSenderList; - -struct StateSystem : public IStateInterpreter -{ - typedef eastl::basic_string TStrType; - typedef Pool TInterperterDataPool; - typedef eastl::list TEventQueue; - typedef nvhash_map THistoryMap; - typedef Pool TStateNodeNodePool; - typedef nvvector TFutureEventList; - typedef nvhash_set TTransitionHashSet; - typedef Pool TTransitionPool; - - NVFoundationBase &m_Foundation; - NVScopedRefCounted m_Context; - volatile QT3DSI32 mRefCount; - // Holds the leaves of the current state. - NVScopedRefCounted m_StringTable; - NVScopedRefCounted m_ScriptContext; - NVScopedRefCounted m_ExecutionContext; - nvvector m_ParentComparisonLHS; - nvvector m_ParentComparisonRHS; - nvvector m_AncestorsList; - nvvector m_IDRefList; - - THistoryMap m_HistoryMap; - - SOrderedSet m_Configuration; - nvvector m_StatesToInvoke; - nvvector m_TransitionTargetList; - TTransitionList m_EnabledTransitions; - - TEventQueue m_InternalQueue; - TEventQueue m_ExternalQueue; - - SOrderedSet m_TransitionSet; - - TStateNodeSet m_StatesToEnter; - TStateNodeSet m_StatesForDefaultEntry; - TStateNodeSet m_StatesToExit; - - TInterperterDataPool m_InterpreterDataPool; - TStateNodeNodePool m_StateNodeNodePool; - - TStrType m_Workspace; - - TFutureEventList m_FutureEvents; - - bool m_Initialized; - bool m_Running; - - SDebugInterface m_DebugInterface; - TSignalSenderList m_SignalSenders; - - TTransitionHashSet m_InvalidTransitions; - - TTransitionPool m_TransitionPool; - nvvector m_TemporaryTransitions; - nvhash_map m_StateInitialTransitionMap; - SFastAllocator<> m_TemporaryAllocator; - TStrType m_IdSplitter; - nvvector m_TempNodeList; - - StateSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, IScriptContext &inScriptContext, - IExecutionContext &inExecutionContext) - : m_Foundation(inFnd) - , mRefCount(0) - , m_StringTable(inStrTable) - , m_ScriptContext(inScriptContext) - , m_ExecutionContext(inExecutionContext) - , m_ParentComparisonLHS(inFnd.getAllocator(), "StateSystem::m_ParentComparisonLHS") - , m_ParentComparisonRHS(inFnd.getAllocator(), "StateSystem::m_ParentComparisonRHS") - , m_AncestorsList(inFnd.getAllocator(), "StateSystem::m_AncestorsList") - , m_IDRefList(inFnd.getAllocator(), "StateSystem::m_IDRefList") - , m_HistoryMap(inFnd.getAllocator(), "StateSystem::m_HistoryMap") - , m_Configuration(inFnd.getAllocator(), "StateSystem::m_Configuration") - , m_StatesToInvoke(inFnd.getAllocator(), "StateSystem::m_InvokeList") - , m_TransitionTargetList(inFnd.getAllocator(), "StateSystem::m_TransitionTargetList") - , m_EnabledTransitions(inFnd.getAllocator(), "StateSystem::m_TransitionList") - , m_InternalQueue(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_InternalQueue")) - , m_ExternalQueue(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_ExternalQueue")) - , m_TransitionSet(inFnd.getAllocator(), "StateSystem::m_TransitionSet") - , m_StatesToEnter(inFnd.getAllocator(), "StateSystem::m_StatesToEnter") - , m_StatesForDefaultEntry(inFnd.getAllocator(), "StateSystem::m_StatesForDefaultEntry") - , m_StatesToExit(inFnd.getAllocator(), "StateSystem::m_StatesToExit") - , m_InterpreterDataPool( - ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_InterpretDataPool")) - , m_StateNodeNodePool( - ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_StateNodeNodePool")) - , m_Workspace(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_Workspace")) - , m_FutureEvents(inFnd.getAllocator(), "StateSystem::m_FutureEvents") - , m_Initialized(false) - , m_Running(false) - , m_DebugInterface(*this) - , m_SignalSenders(inFnd.getAllocator(), "StateSystem::m_SignalSenders") - , m_InvalidTransitions(inFnd.getAllocator(), "StateSystem::m_InvalidTransitions") - , m_TransitionPool( - ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_TransitionPool")) - , m_TemporaryTransitions(inFnd.getAllocator(), "StateSystem::m_TemporaryTransitions") - , m_StateInitialTransitionMap(inFnd.getAllocator(), - "StateSystem::m_StateInitialTempTransitionMap") - , m_TemporaryAllocator(inFnd.getAllocator(), "StateSystem::m_TemporaryAllocator") - , m_IdSplitter(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_IdSplitter")) - , m_TempNodeList(inFnd.getAllocator(), "StateSystem::m_TempNodeList") - { - inExecutionContext.SetInterpreter(*this); - inExecutionContext.SetMachineDebugLogger(m_DebugInterface); - inScriptContext.SetInterpreter(*this); - } - - ~StateSystem() - { - // Ensure the signallers will not attempt to communicate to this object. - for (TSignalSenderList::iterator iter = m_SignalSenders.begin(), - end = m_SignalSenders.end(); - iter != end; ++iter) - (*iter)->m_System = NULL; - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void InitializeDataStructures() - { - m_Configuration.clear(); - m_StatesToInvoke.clear(); - m_EnabledTransitions.clear(); - m_Running = true; - } - - STransition &CreateTemporaryTransition() - { - STransition *newTrans = m_TransitionPool.construct(__FILE__, __LINE__); - m_TemporaryTransitions.push_back(newTrans); - return *newTrans; - } - - void ReleaseInitialAndTemporaryTransitions() - { - for (QT3DSU32 idx = 0, end = m_TemporaryTransitions.size(); idx < end; ++idx) - m_TransitionPool.deallocate(m_TemporaryTransitions[idx]); - m_TemporaryTransitions.clear(); - m_StateInitialTransitionMap.clear(); - m_TemporaryAllocator.reset(); - } - - void FreeHistoryData(SHistory &inHistory) - { - THistoryMap::iterator historyData = m_HistoryMap.find(&inHistory); - if (historyData != m_HistoryMap.end()) { - for (TStateNodeNodeList::iterator iter = historyData->second.begin(), - end = historyData->second.end(); - iter != end; ++iter) - m_StateNodeNodePool.deallocate(&(*iter)); - // Force clear the list. - historyData->second.m_Head = NULL; - } - } - - TStateNodeNodeList *GetHistoryData(SHistory &inHistory) - { - THistoryMap::iterator historyData = m_HistoryMap.find(&inHistory); - if (historyData != m_HistoryMap.end()) - return &historyData->second; - return NULL; - } - - TStateNodeNodeList &GetOrCreateHistoryData(SHistory &inHistory) - { - THistoryMap::iterator historyData = m_HistoryMap.find(&inHistory); - if (historyData != m_HistoryMap.end()) - return historyData->second; - return m_HistoryMap.insert(eastl::make_pair(&inHistory, TStateNodeNodeList())) - .first->second; - } - - // Setup of the state system, you can add a set of roots to the state graph. - NVConstDataRef GetConfiguration() override { return m_Configuration.m_List; } - - void GetPathToRoot(SStateNode &state, nvvector &inParents, bool inProper) - { - inParents.clear(); - SStateNode *stateIter = &state; - if (inProper) - stateIter = state.m_Parent; - for (; stateIter; stateIter = stateIter->m_Parent) - inParents.push_back(stateIter); - } - - // Given these two states, get the nearest parent they share in common. - // Return valid is the index taken from the end of the m_ParentComparison* lists. - // the index is valid in both of them. - QT3DSI32 GetSharedParentState(SStateNode &lhs, SStateNode &rhs, bool inProper) - { - GetPathToRoot(lhs, m_ParentComparisonLHS, inProper); - GetPathToRoot(rhs, m_ParentComparisonRHS, inProper); - if (m_ParentComparisonLHS.empty() || m_ParentComparisonRHS.empty()) { - QT3DS_ASSERT(false); - return -1; - } - QT3DS_ASSERT(m_ParentComparisonLHS.back() == m_ParentComparisonRHS.back()); - QT3DSI32 retval = 0; - for (nvvector::reverse_iterator lhsComp = m_ParentComparisonLHS.rbegin(), - rhsComp = m_ParentComparisonRHS.rbegin(), - lhsEnd = m_ParentComparisonLHS.rend(), - rhsEnd = m_ParentComparisonRHS.rend(); - lhsComp != lhsEnd && rhsComp != rhsEnd && *lhsComp == *rhsComp; - ++lhsComp, ++rhsComp, ++retval) { - } - // Walk the path to the root backwards and note where it differs. - return retval - 1; - } - - void CreateStateNodeInterpreterData(SStateNode &inNode, QT3DSI32 &inIdx) - { - inNode.m_InterpreterData = m_InterpreterDataPool.construct(inIdx, __FILE__, __LINE__); - ++inIdx; - if (inNode.m_Type == StateNodeTypes::SCXML) { - SSCXML *item = inNode.CastTo(); - if (item->m_Initial) - CreateStateNodeInterpreterData(*item->m_Initial, inIdx); - } else if (inNode.m_Type == StateNodeTypes::State) { - SState *item = inNode.CastTo(); - if (item->m_Initial) - CreateStateNodeInterpreterData(*item->m_Initial, inIdx); - } - if (StateNodeTypes::CanHaveChildren(inNode.m_Type)) { - SStateParallelBase &theBase = static_cast(inNode); - for (TStateNodeList::iterator iter = theBase.m_Children.begin(), - end = theBase.m_Children.end(); - iter != end; ++iter) - CreateStateNodeInterpreterData(*iter, inIdx); - } - } - - // Creates the interpreter data for the entire graph. - void CreateStateNodeInterpreterData() - { - if (m_Context->GetRoot() == NULL) { - QT3DS_ASSERT(false); - return; - } - QT3DSI32 nodeIdx = 1; - CreateStateNodeInterpreterData(*m_Context->GetRoot(), nodeIdx); - } - - SStateNodeInterpreterData &GetOrCreateInterpreterData(SStateNode &inNode) - { - if (!inNode.m_InterpreterData) - CreateStateNodeInterpreterData(); - - return *static_cast(inNode.m_InterpreterData); - } - struct SStateNodeSorter - { - StateSystem &m_System; - SStateNodeSorter(StateSystem &inS) - : m_System(inS) - { - } - bool operator()(SStateNode *lhs, SStateNode *rhs) const - { - return m_System.GetOrCreateInterpreterData(*lhs).m_DocumentOrder - < m_System.GetOrCreateInterpreterData(*rhs).m_DocumentOrder; - } - }; - - void SortByDocumentOrder(nvvector &inList) - { - eastl::sort(inList.begin(), inList.end(), SStateNodeSorter(*this)); - } - - void SortConfiguration() { SortByDocumentOrder(m_Configuration.m_List); } - - void RunDataModel(SDataModel &inDM) - { - QT3DS_ASSERT(inDM.m_Source == NULL); - QT3DS_ASSERT(inDM.m_Expression == NULL); - for (TDataList::iterator iter = inDM.m_Data.begin(), end = inDM.m_Data.end(); iter != end; - ++iter) { - if (iter->m_Source == NULL) - m_ScriptContext->Assign(iter->m_Id.c_str(), iter->m_Expression); - else { - QT3DS_ASSERT(false); - } - } - } - - void RecursiveInitializeDataModel(SStateNode &inState) - { - SDataModel *theDataModel = inState.GetDataModel(); - if (theDataModel) - RunDataModel(*theDataModel); - - TStateNodeList *children = inState.GetChildren(); - if (children) { - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) - RecursiveInitializeDataModel(*iter); - } - } - - // Called during initialization for early binding of the datamodel - void RecursiveInitializeDataModel() - { - QT3DS_ASSERT(m_Context->GetRoot()); - QT3DS_ASSERT(m_Context->GetRoot()->m_Flags.IsLateBinding() == false); - RecursiveInitializeDataModel(*m_Context->GetRoot()); - } - - void MarkTransitionAsInvalid(STransition &inTransition, SStateNode &inParent, int inIndex) - { - if (inIndex >= 0) { - qCCritical(INVALID_OPERATION, "Detected invalid transition %s:%d", - inParent.m_Id.c_str(), inIndex); - } else { - const char *transitionType = "initial"; - if (inIndex == -1) - transitionType = "history"; - qCCritical(INVALID_OPERATION, "Detected invalid %s transition on node %s:%d", - transitionType, inParent.m_Id.c_str(), inIndex); - } - m_InvalidTransitions.insert(&inTransition); - } - - bool IsTransitionValid(STransition &inTransition) - { - return m_InvalidTransitions.find(&inTransition) == m_InvalidTransitions.end(); - } - - bool IsTransitionValid(STransition *inTransition) - { - if (inTransition) - return IsTransitionValid(*inTransition); - - // NULL transitions are of course, invalid. - return false; - } - - bool ValidateTransitionTargetList(STransition &inTransition, SStateNode &inParent, int inIndex) - { - for (QT3DSU32 idx = 0, end = inTransition.m_Target.size(); idx < end; ++idx) { - for (QT3DSU32 outerIdx = idx + 1; outerIdx < end; ++outerIdx) { - // We handle this case dynamically during transition activation - if (IsDescendant(*inTransition.m_Target[idx], *inTransition.m_Target[outerIdx]) - || IsDescendant(*inTransition.m_Target[outerIdx], *inTransition.m_Target[idx])) - continue; - - // If they aren't directly related they must be related indirectly via a parallel. - SStateNode *theLCA = - FindLCA(*inTransition.m_Target[idx], *inTransition.m_Target[outerIdx]); - if (theLCA && theLCA->m_Type != StateNodeTypes::Parallel) { - MarkTransitionAsInvalid(inTransition, inParent, inIndex); - return false; - } - } - } - return true; - } - - void ValidateInitialOrHistoryTransition(STransition *inTransition, SStateNode &inParent, - bool inIsInitial = false) - { - if (inTransition == NULL) - return; - int transIndex = inIsInitial ? -2 : -1; - if (inTransition->m_Target.size() == 0) { - MarkTransitionAsInvalid(*inTransition, inParent, transIndex); - } else { - ValidateTransitionTargetList(*inTransition, inParent, transIndex); - } - } - - void ValidateGeneralTransition(STransition &inTransition, SStateNode &inParent, int inIndex) - { - // Three distinct ways a transition could be invalid. - // 1. targetless, eventless and conditionless - if (inTransition.m_Target.size() == 0 && inTransition.m_Event.IsValid() == false - && isTrivial(inTransition.m_Condition)) - MarkTransitionAsInvalid(inTransition, inParent, inIndex); - else { - // Else eventless ,targetless, and points back to source state - if (inTransition.m_Target.size() == 1) { - if (inTransition.m_Target[0] == inTransition.m_Parent - && inTransition.m_Event.IsValid() == false - && isTrivial(inTransition.m_Condition)) { - MarkTransitionAsInvalid(inTransition, inParent, inIndex); - } - } else { - ValidateTransitionTargetList(inTransition, inParent, inIndex); - } - } - } - - void RecursiveValidateTransitions(SStateNode &inNode, SStateNode *inParent, int inIndex) - { - switch (inNode.m_Type) { - case StateNodeTypes::SCXML: - ValidateInitialOrHistoryTransition(inNode.GetInitialTransition(), inNode); - break; - case StateNodeTypes::State: - ValidateInitialOrHistoryTransition(inNode.GetInitialTransition(), inNode); - break; - case StateNodeTypes::Parallel: - ValidateInitialOrHistoryTransition(inNode.GetInitialTransition(), inNode); - break; - case StateNodeTypes::History: - ValidateInitialOrHistoryTransition(static_cast(inNode).m_Transition, inNode, - false); - break; - case StateNodeTypes::Transition: - if (inParent) - ValidateGeneralTransition(static_cast(inNode), *inParent, inIndex); - break; - default: // don't care - break; - } - RecursiveValidateTransitions(inNode, inNode.GetChildren()); - } - - void RecursiveValidateTransitions(SStateNode &inParent, TStateNodeList *inNodes) - { - if (inNodes) { - int idx = 0; - for (TStateNodeList::iterator iter = inNodes->begin(), end = inNodes->end(); - iter != end; ++iter, ++idx) - RecursiveValidateTransitions(*iter, &inParent, idx); - } - } - - // The state machine is pretty robust but there are is one category of input that can - // put the machine in a bad state. Transitions with either multiple targets or no target - // or a single target that points back to its owner may be bad depending on different criteria. - // For multiple targets, we invalidate a transition that puts us into a bad state. - // For no targets, in invalidate a transition that would cause the interpreter to loop - // infinitely - // For a single target, we invalidate a transition if it points back to its source but it has no - // condition - // or event. We don't attempt any more sophisticated analysis at this point although one could - // conceive of - // an analysis that could find loops depending on how long you wanted it to run. - void RecursiveValidateTransitions() - { - QT3DS_ASSERT(m_Context->GetRoot()); - RecursiveValidateTransitions(*m_Context->GetRoot(), NULL, 0); - } - - NVConstDataRef GetRefList(NVConstDataRef inIds) { return inIds; } - - // unsorted, may contain duplicates. - NVDataRef GetRefList(NVConstDataRef inIds) - { - m_IDRefList.clear(); - for (QT3DSU32 idx = 0, end = inIds.size(); idx < end; ++idx) { - SStateNode *theNode = m_Context->FindStateNode(inIds[idx]); - if (theNode != NULL) { - m_IDRefList.push_back(theNode); - } - } - return m_IDRefList; - } - - NVConstDataRef GetTargetStates(STransition *inTransition) - { - if (inTransition) - return inTransition->m_Target; - return NVDataRef(); - } - - static bool IsCompoundState(const SStateNode *inNode) - { - if (inNode == NULL) - return false; - return inNode->IsCompound(); - } - - static bool IsDescendant(SStateNode &inParent, SStateNode &inChild) - { - if (&inChild == &inParent) - return false; - - for (SStateNode *theNode = &inChild; theNode; theNode = theNode->m_Parent) - if (theNode == &inParent) - return true; - return false; - } - - static bool AllAreDescendants(SStateNode &inParent, NVConstDataRef inList) - { - for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) - if (IsDescendant(inParent, *inList[idx]) == false) - return false; - return true; - } - struct SRefListPlusOne - { - NVConstDataRef m_List; - SStateNode *m_Extra; - - SRefListPlusOne(NVConstDataRef l, SStateNode *e) - : m_List(l) - , m_Extra(e) - { - } - - QT3DSU32 size() { return m_List.size() + (m_Extra ? 1 : 0); } - - SStateNode *operator[](int idx) - { - if (idx < (int)m_List.size()) - return m_List[idx]; - if (idx == (int)m_List.size()) - return m_Extra; - QT3DS_ASSERT(false); - return NULL; - } - }; - - SStateNode *FindLCA(SStateNode &lhs, SStateNode &rhs) - { - QT3DSU32 sharedIdx = GetSharedParentState(lhs, rhs, false); - return *(m_ParentComparisonLHS.rbegin() + sharedIdx); - } - - SStateNode *FindLCCA(NVConstDataRef inList, SStateNode *inExtra = NULL) - { - SRefListPlusOne theList(inList, inExtra); - if (theList.size() == 0) - return NULL; - if (theList.size() == 1) { - for (SStateNode *item = theList[0]; item; item = item->m_Parent) { - if (item->IsCompound()) - return item; - } - } - SStateNode *lhs = theList[0]; - for (QT3DSU32 idx = 1, end = theList.size(); idx < end; ++idx) { - SStateNode *rhs = theList[idx]; - QT3DSU32 sharedIdx = GetSharedParentState(*lhs, *rhs, false); - lhs = *(m_ParentComparisonLHS.rbegin() + sharedIdx); - } - for (SStateNode *item = lhs; item; item = item->m_Parent) { - if (item->IsCompound()) - return item; - } - QT3DS_ASSERT(false); - return m_Context->GetRoot(); - } - NVDataRef GetProperAncestors(SStateNode &inChild, SStateNode *inStop) - { - m_AncestorsList.clear(); - for (SStateNode *parent = inChild.m_Parent; parent && parent != inStop; - parent = parent->m_Parent) - m_AncestorsList.push_back(parent); - return m_AncestorsList; - } - - bool AddStateToEnterToSet(SStateNode &inNode) - { - if (m_Configuration.contains(&inNode) == false) { - m_StatesToEnter.insert(&inNode); - return true; - } - return false; - } - - void AddStatesToEnter(SHistory &inState) - { - TStateNodeNodeList *history = GetHistoryData(inState); - if (history) { - for (TStateNodeNodeList::iterator iter = history->begin(), end = history->end(); - iter != end; ++iter) { - AddStatesToEnter(*iter->m_Node); - NVDataRef ancestors = - GetProperAncestors(*iter->m_Node, inState.m_Parent); - for (QT3DSU32 ancIdx = 0, ancEnd = ancestors.size(); ancIdx < ancEnd; ++ancIdx) - AddStateToEnterToSet(*ancestors[ancIdx]); - } - } else { - if (IsTransitionValid(inState.m_Transition)) { - NVConstDataRef theList = GetRefList(inState.m_Transition->m_Target); - for (QT3DSU32 idx = 0, end = theList.size(); idx < end; ++idx) { - AddStatesToEnter(*theList[idx]); - NVDataRef ancestors = - GetProperAncestors(*theList[idx], inState.m_Parent); - for (QT3DSU32 ancIdx = 0, ancEnd = ancestors.size(); ancIdx < ancEnd; ++ancIdx) - AddStateToEnterToSet(*ancestors[ancIdx]); - } - } else { - qCCritical(INVALID_OPERATION, - "History node %s with no history, no transition, or invalid transition visited", - inState.m_Id.c_str()); - SStateNode *theParent = inState.m_Parent; - if (theParent != NULL) { - if (theParent->m_Type != StateNodeTypes::Parallel) { - NVConstDataRef theDefaultInitial( - GetDefaultInitialState(*theParent)); - - QT3DS_ASSERT(theDefaultInitial.size() != 0); - for (QT3DSU32 idx = 0, end = theDefaultInitial.size(); idx < end; ++idx) - AddStatesToEnter(*theDefaultInitial[idx]); - - EnterAncestors(theDefaultInitial, theParent); - } else { - SParallel *pstate = theParent->CastTo(); - for (TStateNodeList::iterator iter = pstate->m_Children.begin(), - end = pstate->m_Children.end(); - iter != end; ++iter) { - if (StateNodeTypes::IsStateType(iter->m_Type)) - AddStatesToEnter(*iter); - } - } - } else { - QT3DS_ASSERT(false); // invalid configuration - } - } - } - } - NVConstDataRef GetDefaultInitialState(SStateNode &inState) - { - TStateNodeList *theChildren = inState.GetChildren(); - NVConstDataRef retval; - if (theChildren) { - for (TStateNodeList::iterator iter = theChildren->begin(), end = theChildren->end(); - iter != end && retval.size() == 0; ++iter) { - if (iter->m_Type == StateNodeTypes::State - || iter->m_Type == StateNodeTypes::Parallel - || iter->m_Type == StateNodeTypes::Final) { - SStateNode **newData = - reinterpret_cast(m_TemporaryAllocator.allocate( - sizeof(SStateNode *), "TempNode", __FILE__, __LINE__)); - newData[0] = &(*iter); - retval = toDataRef(newData, 1); - } - } - } - return retval; - } - - STransition *GetStateInitialTransition(SStateNode &inNode) - { - // Initialexpr, if it exists, takes precedence over the initial transition. - // they should not both exist but coding defensively, we have to take this into account. - eastl::pair::iterator, bool> inserter = - m_StateInitialTransitionMap.insert(eastl::make_pair(&inNode, (STransition *)NULL)); - if (inserter.second) { - const char8_t *initialExpr = inNode.GetInitialExpression(); - if (!isTrivial(initialExpr)) { - STransition *newTransition = &CreateTemporaryTransition(); - newTransition->m_Parent = &inNode; - inserter.first->second = newTransition; - SScriptExecutionResult exprResultData = - m_ScriptContext->ExecuteExpressionToString(initialExpr); - if (exprResultData.Valid()) { - const char8_t *exprResult(exprResultData.Result()); - // split this string into parts and extract ids. - m_IdSplitter.assign(nonNull(exprResult)); - const char8_t *whitespaceData = " \n\t\r"; - size_t charPos = m_IdSplitter.find_first_not_of(whitespaceData); - if (charPos == eastl::string::npos) { - m_IdSplitter.clear(); - m_Workspace.clear(); - } - if (charPos != 0) - m_IdSplitter.erase(m_IdSplitter.begin(), m_IdSplitter.begin() + charPos); - // Loop runs under assumption that idSplitter is empty or position 0 holds start - // of next id - while (m_IdSplitter.size()) { - // Trim to first character - eastl::string::size_type spacePos = - m_IdSplitter.find_first_of(whitespaceData); - - if (spacePos != eastl::string::npos) { - charPos = m_IdSplitter.find_first_not_of(whitespaceData, spacePos); - m_Workspace = m_IdSplitter.c_str(); - m_Workspace.resize(spacePos); - if (charPos != eastl::string::npos) - m_IdSplitter.erase(m_IdSplitter.begin(), - m_IdSplitter.begin() + charPos); - else - m_IdSplitter.clear(); - } else { - m_Workspace = m_IdSplitter; - m_IdSplitter.clear(); - } - - if (m_Workspace.empty() == false) { - CRegisteredString stateId = - m_StringTable->RegisterStr(m_Workspace.c_str()); - qt3ds::state::SStateNode *transitionNode = - m_Context->FindStateNode(stateId); - if (!transitionNode) { - m_TempNodeList.clear(); - m_IdSplitter.clear(); - qCCritical(INVALID_OPERATION, - "initialexpr=\"%s\" evaluated to \"%s\", but " - "this does not match the states in this " - "document. Using the default initial state " - "instead.", - nonNull(initialExpr), nonNull(exprResult)); - - eastl::string errorBuf; - IScriptEvent *newEvent = m_ScriptContext->CreateScriptEvent( - m_StringTable->RegisterStr("error.execution.initialexpr")); - newEvent->SetParamStr(m_StringTable->RegisterStr("expr"), - nonNull(initialExpr)); - errorBuf.assign(nonNull(exprResult)); - errorBuf.append(" does not match the states in this document."); - newEvent->SetParamStr(m_StringTable->RegisterStr("error"), - errorBuf.c_str()); - QueueEvent(*newEvent, false); - } else - m_TempNodeList.push_back(transitionNode); - } - } - if (m_TempNodeList.empty() == false) { - QT3DSU32 allocSize = sizeof(SStateNode *) * m_TempNodeList.size(); - SStateNode **nodeData = - reinterpret_cast(m_TemporaryAllocator.allocate( - allocSize, "TempNodes", __FILE__, __LINE__)); - memCopy(nodeData, m_TempNodeList.data(), allocSize); - newTransition->m_Target = toDataRef(nodeData, m_TempNodeList.size()); - m_TempNodeList.clear(); - } - if (newTransition->m_Target.size() != 0) { - bool isTransValid = ValidateTransitionTargetList(*newTransition, inNode, 0); - if (!isTransValid) { - m_InvalidTransitions.erase(newTransition); - // Reset the transition so that we get just the default initial state - // below - newTransition->m_Target = NVConstDataRef(); - // Create appropriate messages and events. - qCCritical(INVALID_OPERATION, - "initialexpr=\"%s\" evaluated to \"%s\", but this " - "results in an invalid transition. Using the " - "default initial state instead.", - nonNull(initialExpr), nonNull(exprResult)); - eastl::string errorBuf; - IScriptEvent *newEvent = m_ScriptContext->CreateScriptEvent( - m_StringTable->RegisterStr("error.execution.initialexpr")); - newEvent->SetParamStr(m_StringTable->RegisterStr("expr"), - nonNull(initialExpr)); - errorBuf.assign(nonNull(exprResult)); - errorBuf.append(" results in invalid transition."); - newEvent->SetParamStr(m_StringTable->RegisterStr("error"), - errorBuf.c_str()); - QueueEvent(*newEvent, false); - } - } - } // if script executed successfully - else { - const char8_t *runtimeError = exprResultData.Error(); - IScriptEvent *newEvent = m_ScriptContext->CreateScriptEvent( - m_StringTable->RegisterStr("error.execution.initialexpr")); - newEvent->SetParamStr(m_StringTable->RegisterStr("expr"), nonNull(initialExpr)); - newEvent->SetParamStr(m_StringTable->RegisterStr("error"), - nonNull(runtimeError)); - QueueEvent(*newEvent, false); - } - if (newTransition->m_Target.size() == 0) { - newTransition->m_Target = GetDefaultInitialState(inNode); - } - } - if (inserter.first->second == NULL) { - // Assume already validated - inserter.first->second = inNode.GetInitialTransition(); - } - } - return inserter.first->second; - } - - void AddStatesToEnter(SStateNode &inState) - { - if (inState.m_Type == StateNodeTypes::History) - AddStatesToEnter(*inState.CastTo()); - else { - AddStateToEnterToSet(inState); - if (inState.IsCompound()) { - m_StatesForDefaultEntry.insert(&inState); - NVConstDataRef targets; - STransition *initialTrans = GetStateInitialTransition(inState); - if (IsTransitionValid(initialTrans)) - targets = GetTargetStates(initialTrans); - - if (targets.size() == 0) - targets = GetDefaultInitialState(inState); - - QT3DS_ASSERT(targets.size() != 0); - for (QT3DSU32 idx = 0, end = targets.size(); idx < end; ++idx) - AddStatesToEnter(*targets[idx]); - - EnterAncestors(targets, &inState); - } else if (inState.m_Type == StateNodeTypes::Parallel) { - SParallel *pstate = inState.CastTo(); - for (TStateNodeList::iterator iter = pstate->m_Children.begin(), - end = pstate->m_Children.end(); - iter != end; ++iter) { - if (StateNodeTypes::IsStateType(iter->m_Type)) - AddStatesToEnter(*iter); - } - } - } - } - bool AllChildrenInFinalStates(SStateNode &inNode) - { - TStateNodeList *children = inNode.GetChildren(); - if (children) { - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) - if (!IsInFinalState(*iter)) - return false; - return true; - } - return true; - } - - void EraseState(nvvector &inList, SStateNode *inItem) - { - nvvector::iterator iter = eastl::find(inList.begin(), inList.end(), inItem); - if (iter != inList.end()) - inList.erase(iter); - } - - void ExitStates(NVDataRef inTransitions) - { - m_StatesToExit.clear(); - for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { - STransition &transition(*inTransitions[idx]); - if (transition.GetSource() == NULL) { - QT3DS_ASSERT(false); - continue; - } - NVConstDataRef theList = GetRefList(transition.m_Target); - SStateNode *ancestor = GetTransitionSubgraphRoot(transition, theList); - if (theList.size() && transition.GetSource()) { - for (QT3DSU32 idx = 0, end = m_Configuration.size(); idx < end; ++idx) - if (IsDescendant(*ancestor, *m_Configuration[idx])) - m_StatesToExit.insert(m_Configuration[idx]); - } - } - - /* - for s in m_StatesToExit: - statesToInvoke.delete(s) - */ - - SortByDocumentOrder(m_StatesToExit.m_List); - DEBUGGER_CALL1(SetExitSet, m_StatesToExit); - // Run through the list in reverse order. - for (nvvector::reverse_iterator iter = m_StatesToExit.m_List.rbegin(), - end = m_StatesToExit.m_List.rend(); - iter != end; ++iter) { -#ifdef QT3DS_LOG_ENTER_EXIT - qCInfo(TRACE_INFO, "Exiting state: %s", (*iter)->m_Id.c_str()); -#endif - TStateNodeList *children = (*iter)->GetChildren(); - if (children) { - for (TStateNodeList::iterator iter = children->begin(), end = children->end(); - iter != end; ++iter) { - if (iter->m_Type == StateNodeTypes::History) { - SHistory &theHistory = *iter->CastTo(); - FreeHistoryData(theHistory); - TStateNodeNodeList &theHistoryData = GetOrCreateHistoryData(theHistory); - - if (theHistory.m_Parent == NULL) { - QT3DS_ASSERT(false); - continue; - } - - // If deep, then record the leaves - if (theHistory.m_Flags.IsDeep()) { - for (TStateNodeSet::iterator configIter = m_Configuration.begin(), - configEnd = m_Configuration.end(); - configIter != configEnd; ++configIter) { - if ((*configIter)->IsAtomic() - && IsDescendant(*theHistory.m_Parent, **configIter)) - theHistoryData.push_back(*m_StateNodeNodePool.construct( - *configIter, __FILE__, __LINE__)); - } - } - // Else record what may be branches. - else { - for (TStateNodeSet::iterator configIter = m_Configuration.begin(), - configEnd = m_Configuration.end(); - configIter != configEnd; ++configIter) { - if ((*configIter)->m_Parent == theHistory.m_Parent) - theHistoryData.push_back(*m_StateNodeNodePool.construct( - *configIter, __FILE__, __LINE__)); - } - } - } - } - } - } - - for (nvvector::reverse_iterator iter = m_StatesToExit.m_List.rbegin(), - end = m_StatesToExit.m_List.rend(); - iter != end; ++iter) { - SStateNode *theState = *iter; - TOnExitList *theExitList = theState->GetOnExitList(); - if (theExitList) - m_ExecutionContext->Execute(*theState, *theExitList); - for (QT3DSU32 idx = 0, end = m_SignalSenders.size(); idx < end; ++idx) - m_SignalSenders[idx]->m_Handler.OnInterpreterEvent(InterpreterEventTypes::StateExit, - theState->m_Id); - EraseState(m_StatesToInvoke, theState); - m_Configuration.erase(theState); - } - } - - void EnterAncestor(SStateNode &inNode) - { - m_StatesToEnter.insert(&inNode); - if (inNode.m_Type == StateNodeTypes::Parallel) { - SParallel *anc = inNode.CastTo(); - for (TStateNodeList::iterator childIter = anc->m_Children.begin(), - endChild = anc->m_Children.end(); - childIter != endChild; ++childIter) { - if (!StateNodeTypes::IsStateType(childIter->m_Type)) - continue; - bool hasDescendent = false; - for (TStateNodeSet::iterator existingIter = m_StatesToEnter.begin(), - existingEnd = m_StatesToEnter.end(); - existingIter != existingEnd && hasDescendent == false; ++existingIter) { - hasDescendent = IsDescendant(*childIter, *(*existingIter)); - } - if (hasDescendent == false) - AddStatesToEnter(*childIter); - } - } - } - - void EnterAncestors(NVConstDataRef inList, SStateNode *ancestor) - { - for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) { - NVDataRef theAncestors = GetProperAncestors(*inList[idx], ancestor); - for (QT3DSU32 ancIdx = 0, ancEnd = theAncestors.size(); ancIdx < ancEnd; ++ancIdx) { - EnterAncestor(*theAncestors[ancIdx]); - // Break earlier if we have gone back and included the ancestor. - if (theAncestors[ancIdx] == ancestor) - break; - } - } - } - - void EnterStates(NVDataRef inTransitions) - { - m_StatesToEnter.clear(); - m_StatesForDefaultEntry.clear(); - - for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { - STransition &transition = *inTransitions[idx]; - NVConstDataRef theList = GetRefList(transition.m_Target); - if (transition.GetSource() == NULL) { - QT3DS_ASSERT(false); - continue; - } - - // Multi-target transitions present their own set of problems. One is that a perfectly - // valid - // multi-target transition may - if (theList.size() > 1) { - m_TransitionTargetList.clear(); - // We have to ensure that if two targets are directly related, we take the most - // derived one. - for (QT3DSU32 targetIdx = 0, targetEnd = theList.size(); targetIdx < targetEnd; - ++targetIdx) { - SStateNode *nextTarget = theList[targetIdx]; - for (QT3DSU32 takenTargetListIdx = 0, - takenTargetListEnd = m_TransitionTargetList.size(); - takenTargetListIdx < takenTargetListEnd && nextTarget; - ++takenTargetListIdx) { - SStateNode *previousTarget = m_TransitionTargetList[takenTargetListIdx]; - // If the previous target is more descendant than the original target - if (IsDescendant(*nextTarget, *previousTarget)) { - // Then we don't need to consider next target at all and we can - // continue. - nextTarget = NULL; - } else if (IsDescendant(*previousTarget, *nextTarget)) { - // If next target derives from previous target, then we remove previous - // target from - // the list. - m_TransitionTargetList.erase(m_TransitionTargetList.begin() - + takenTargetListIdx); - --takenTargetListIdx; - takenTargetListEnd = m_TransitionTargetList.size(); - } - // Else we don't care, we will add next target to the list. - } - if (nextTarget != NULL) - m_TransitionTargetList.push_back(nextTarget); - } - theList = m_TransitionTargetList; - } - - for (QT3DSU32 idx = 0, end = theList.size(); idx < end; ++idx) - AddStatesToEnter(*theList[idx]); - } - - for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { - STransition &transition = *inTransitions[idx]; - NVConstDataRef theList = GetRefList(transition.m_Target); - - if (transition.GetSource() == NULL) { - QT3DS_ASSERT(false); - continue; - } - - SStateNode *ancestor = GetTransitionSubgraphRoot(transition, theList); - EnterAncestors(theList, ancestor); - } - EnterStatesSecondHalf(); - } - - void EnterStatesSecondHalf() - { - nvvector &theEnterList(m_StatesToEnter.m_List); - SortByDocumentOrder(theEnterList); - - DEBUGGER_CALL1(SetEnterSet, m_StatesToEnter); - for (QT3DSU32 idx = 0, end = theEnterList.size(); idx < end; ++idx) { - SStateNode *theEnterState(theEnterList[idx]); -#ifdef QT3DS_LOG_ENTER_EXIT - qCInfo(TRACE_INFO, "Entering state: %s", theEnterState->m_Id.c_str()); -#endif - m_Configuration.insert(theEnterState); - m_StatesToInvoke.push_back(theEnterState); - SStateNodeInterpreterData &theData = GetOrCreateInterpreterData(*theEnterState); - if (theData.m_Entered == false) { - theData.m_Entered = true; - if (m_Context->GetRoot()->m_Flags.IsLateBinding()) { - SDataModel *theDataModel = theEnterState->GetDataModel(); - if (theDataModel) - RunDataModel(*theDataModel); - } - } - - TOnEntryList *theList = theEnterState->GetOnEntryList(); - if (theList) - m_ExecutionContext->Execute(*theEnterState, *theList); - for (QT3DSU32 idx = 0, end = m_SignalSenders.size(); idx < end; ++idx) - m_SignalSenders[idx]->m_Handler.OnInterpreterEvent( - InterpreterEventTypes::StateEnter, theEnterState->m_Id); - - if (m_StatesForDefaultEntry.contains(theEnterState)) { - SState *theState = theEnterState->CastTo(); - if (theState && IsTransitionValid(theState->m_Initial)) - m_ExecutionContext->Execute(*theState->m_Initial); - } - if (theEnterState->m_Type == StateNodeTypes::Final) { - SStateNode *parent = theEnterState->m_Parent; - SStateNode *grandparent = parent->m_Parent; - if (parent && grandparent) { - m_Workspace.assign("done.state."); - m_Workspace.append(parent->m_Id); - - // TODO - donedata - QueueEvent(m_Workspace.c_str(), false); - - if (grandparent && grandparent->m_Type == StateNodeTypes::Parallel - && AllChildrenInFinalStates(*grandparent)) { - m_Workspace.assign("done.state."); - m_Workspace.append(grandparent->m_Id); - QueueEvent(m_Workspace.c_str(), false); - } - } - } - } - - if (IsInFinalState(m_Context->GetRoot())) - m_Running = false; - SortConfiguration(); - } - - bool InConfiguration(SStateNode &inState) - { - return eastl::find(m_Configuration.begin(), m_Configuration.end(), &inState) - != m_Configuration.end(); - } - - bool IsInFinalState(SStateNode &inState) - { - if (inState.m_Type == StateNodeTypes::State && inState.IsCompound()) { - SState *theState = inState.CastTo(); - for (TStateNodeList::iterator childIter = theState->m_Children.begin(), - endIter = theState->m_Children.end(); - childIter != endIter; ++childIter) { - if (IsInFinalState(*childIter)) - return true; - } - } else if (inState.m_Type == StateNodeTypes::SCXML) { - SSCXML *theState = inState.CastTo(); - for (TStateNodeList::iterator childIter = theState->m_Children.begin(), - endIter = theState->m_Children.end(); - childIter != endIter; ++childIter) { - if (childIter->m_Type == StateNodeTypes::Final && InConfiguration(*childIter)) - return true; - } - } else if (inState.m_Type == StateNodeTypes::Parallel) { - SParallel *parallel = inState.CastTo(); - for (TStateNodeList::iterator childIter = parallel->m_Children.begin(), - endIter = parallel->m_Children.end(); - childIter != endIter; ++childIter) { - if (!IsInFinalState(*childIter)) - return false; - } - return true; - } else if (inState.m_Type == StateNodeTypes::Final && InConfiguration(inState)) - return true; - - return false; - } - - bool IsInFinalState(SStateNode *inState) - { - if (inState) - return IsInFinalState(*inState); - return false; - } - - SStateNode *GetTransitionSubgraphRoot(STransition &inTransition, - NVConstDataRef inTargetList) - { - SStateNodeInterpreterData &data = GetOrCreateInterpreterData(inTransition); - if (data.m_TransitionSubgraphRoot != NULL) - return data.m_TransitionSubgraphRoot; - if (inTransition.GetSource() == NULL) { - QT3DS_ASSERT(false); - return NULL; - } - SStateNode &source = *inTransition.GetSource(); - if (inTransition.m_Target.size() == 0) - data.m_TransitionSubgraphRoot = &source; - else { - if (inTransition.m_Flags.IsInternal() && source.IsCompound() - && AllAreDescendants(source, inTargetList)) - data.m_TransitionSubgraphRoot = &source; - else - data.m_TransitionSubgraphRoot = FindLCCA(inTargetList, &source); - } - - return data.m_TransitionSubgraphRoot; - } - SStateNode *GetTransitionSubgraphRoot(STransition &inTransition) - { - SStateNodeInterpreterData &data = GetOrCreateInterpreterData(inTransition); - if (data.m_TransitionSubgraphRoot != NULL) - return data.m_TransitionSubgraphRoot; - - return GetTransitionSubgraphRoot(inTransition, GetRefList(inTransition.m_Target)); - } - enum PreemptRule { AddNew, KeepExisting, ReplaceExisting }; - - PreemptRule IsPreempted(STransition &existing, STransition &nextTransition) - { - // Targetless transitions can get preempted and can preempt - SStateNode *existingRoot = GetTransitionSubgraphRoot(existing); - SStateNode *nextRoot = GetTransitionSubgraphRoot(nextTransition); - /* - http://www.w3.org/TR/scxml/#SelectingTransitions - - A transition T is optimally enabled by event E in atomic state S if - a) T is enabled by E in S and - b) no transition that precedes T in document order in T's source state is enabled by E in S - and - c) no transition is enabled by E in S in any descendant of T's source state. - */ - - // static bool IsDescendant( SStateNode& inParent, SStateNode& inChild ) - - if (IsDescendant(*nextRoot, *existingRoot)) - return KeepExisting; - if (IsDescendant(*existingRoot, *nextRoot)) - return ReplaceExisting; - - // Else these transactions are completely unrelated - return AddNew; - } - - void FilterPreempted(TTransitionSet &inTransitionSet, TTransitionList &outTransitions) - { - outTransitions.clear(); - for (TTransitionSet::iterator iter = inTransitionSet.begin(), end = inTransitionSet.end(); - iter != end; ++iter) { - PreemptRule preempted = AddNew; - QT3DSU32 idx, endIdx; - for (idx = 0, endIdx = outTransitions.size(); idx < endIdx && preempted == AddNew; - ++idx) - preempted = IsPreempted(*outTransitions[idx], **iter); - - switch (preempted) { - case KeepExisting: // Ignore the result. - break; - case ReplaceExisting: - // The iteration statement is evaluated before the exit test. - outTransitions[idx - 1] = *iter; - break; - case AddNew: - outTransitions.push_back(*iter); - break; - } - } - } - - bool SelectEventlessTransitions(SStateNode &inNode, TTransitionSet &inSet) - { - TStateNodeList *theChildren = inNode.GetChildren(); - if (theChildren == NULL) { - return false; - } - for (TStateNodeList::iterator iter = theChildren->begin(), end = theChildren->end(); - iter != end; ++iter) { - if (iter->m_Type == StateNodeTypes::Transition) { - STransition &trans = *iter->CastTo(); - if (IsTransitionValid(&trans)) { - if (trans.m_Event.IsValid() == false) { - if (!isTrivial(trans.m_Condition)) { - Option condEval = - m_ScriptContext->ExecuteCondition(trans.m_Condition); - if (condEval.hasValue()) { - if (*condEval) { - inSet.insert(&trans); - return true; - } - } else { - QueueEvent("error.execution", false); - return false; - } - } - // Extension for running scxml documents with transitions with nothing but - // content - else { - inSet.insert(&trans); - return true; - } - } - } - } - } - if (inNode.m_Parent) - SelectEventlessTransitions(*inNode.m_Parent, inSet); - return false; - } - - // Precondition - m_Configuration is in document order. - // Postcondition - m_EnabledTransitions contains only the transitions selected - void SelectEventlessTransitions() - { - m_TransitionSet.clear(); - static QT3DSU32 callCount = 0; - ++callCount; - for (QT3DSU32 idx = 0, end = m_Configuration.size(); idx < end; ++idx) { - if (idx) { - QT3DS_ASSERT(GetOrCreateInterpreterData(*m_Configuration[idx]).m_DocumentOrder - > GetOrCreateInterpreterData(*m_Configuration[idx - 1]).m_DocumentOrder); - } - if (m_Configuration[idx]->IsAtomic() == false) - continue; - SelectEventlessTransitions(*m_Configuration[idx], m_TransitionSet); - } - m_EnabledTransitions.clear(); - FilterPreempted(m_TransitionSet, m_EnabledTransitions); - } - void SelectTransition(SStateNode &inNode, IEvent &inEvent, TTransitionSet &outTransitions) - { - TStateNodeList *theChildren = inNode.GetChildren(); - if (theChildren) { - for (TStateNodeList::iterator iter = theChildren->begin(), end = theChildren->end(); - iter != end; ++iter) { - if (iter->m_Type == StateNodeTypes::Transition) { - STransition &theTransition = *iter->CastTo(); - if (IsTransitionValid(theTransition)) { - if (theTransition.m_Event.IsValid()) { - if (qt3ds::state::impl::NameMatches(theTransition.m_Event.c_str(), - inEvent.GetName().c_str())) { - if (!isTrivial(theTransition.m_Condition)) { - Option condResult = m_ScriptContext->ExecuteCondition( - theTransition.m_Condition); - if (condResult.hasValue()) { - if (*condResult) { - outTransitions.insert(&theTransition); - return; - } - } else { - QueueEvent("error.execution", false); - return; - } - } else { - outTransitions.insert(&theTransition); - return; - } - } - } - } - } - } - } - if (inNode.m_Parent) - SelectTransition(*inNode.m_Parent, inEvent, outTransitions); - } - - // Precondition is that m_Configuration is in document order. - void SelectTransitions(IEvent &inEvent) - { - m_TransitionSet.clear(); - for (QT3DSU32 idx = 0, end = m_Configuration.size(); idx < end; ++idx) { - // Ensure that m_Configuration is in document order. - if (idx) { - QT3DS_ASSERT(GetOrCreateInterpreterData(*m_Configuration[idx]).m_DocumentOrder - > GetOrCreateInterpreterData(*m_Configuration[idx - 1]).m_DocumentOrder); - } - - if (!m_Configuration[idx]->IsAtomic()) - continue; - SelectTransition(*m_Configuration[idx], inEvent, m_TransitionSet); - } - - FilterPreempted(m_TransitionSet, m_EnabledTransitions); - } - - bool Initialize(IStateContext &inContext, bool inValidateTransitions) override - { - m_Initialized = false; - InitializeDataStructures(); - m_Context = inContext; - QT3DS_ASSERT(m_Context->GetRoot()); - if (m_Context->GetRoot() == NULL) { - QT3DS_ASSERT(false); - m_Running = false; - return false; - } - - // Disable transitions that can put us into a bad state - if (inValidateTransitions) - RecursiveValidateTransitions(); - m_Initialized = true; - return true; - } - NVConstDataRef Start() override - { - if (!m_Initialized) { - QT3DS_ASSERT(false); - return NVConstDataRef(); - } - m_Running = true; - SSCXML &rootState = *m_Context->GetRoot(); - if (!rootState.m_Flags.IsLateBinding()) - RecursiveInitializeDataModel(); - eastl::string theSendLocExpr; - NVConstDataRef theSendData = m_Context->GetSendList(); - for (QT3DSU32 idx = 0, end = theSendData.size(); idx < end; ++idx) { - SSend &theSend(*theSendData[idx]); - if (!isTrivial(theSend.m_IdLocation)) { - QT3DS_ASSERT(theSend.m_Id.IsValid()); - m_ScriptContext->AssignStr(theSend.m_IdLocation, theSend.m_Id.c_str()); - } - } - - STransition *initialTrans = this->GetStateInitialTransition(rootState); - if (IsTransitionValid(initialTrans)) { - m_Configuration.insert(&rootState); - m_ExecutionContext->Execute(*initialTrans); - AddStatesToEnter(rootState); - EnterAncestors(initialTrans->m_Target, &rootState); - QT3DS_ASSERT(m_EnabledTransitions.empty()); - m_EnabledTransitions.clear(); - m_EnabledTransitions.push_back(initialTrans); - DEBUGGER_CALL1(SetTransitionSet, m_EnabledTransitions); - m_EnabledTransitions.clear(); - EnterStatesSecondHalf(); - ReleaseInitialAndTemporaryTransitions(); - DEBUGGER_CALL(EndMicrostep); - DEBUGGER_CALL(EndStep); - } else { - m_Running = false; - qFatal("Invalid state machine: root initial configuration is invalid"); - } - return m_Configuration.m_List; - } - - void Microstep(TTransitionList &inTransitions) - { - DEBUGGER_CALL1(SetTransitionSet, inTransitions); - ExitStates(inTransitions); - for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { - m_ExecutionContext->Execute(*inTransitions[idx]); - for (QT3DSU32 sigIdx = 0, sigEnd = m_SignalSenders.size(); sigIdx < sigEnd; ++sigIdx) - m_SignalSenders[sigIdx]->m_Handler.OnInterpreterEvent( - InterpreterEventTypes::Transition, inTransitions[idx]->m_Id); - } - - EnterStates(inTransitions); - // Allow them to be selected again at some point. - inTransitions.clear(); - ReleaseInitialAndTemporaryTransitions(); - DEBUGGER_CALL(EndMicrostep); - } - - void CheckForDelayedEvents() - { - QT3DSU64 currentTime = Time::getCurrentTimeInTensOfNanoSeconds(); - TFutureEventList::iterator removeIter = m_FutureEvents.begin(); - TFutureEventList::iterator endIter = m_FutureEvents.end(); - // Future events list is sorted so all we have to do is iterate forward until - // fire time is greater than current time. - - for (; removeIter != endIter && removeIter->m_FireTime < currentTime; ++removeIter) { - } - // remove iter points either to the end or to the first event who's time has come. - for (TFutureEventList::iterator evtIter = m_FutureEvents.begin(); evtIter != removeIter; - ++evtIter) { - qCInfo(TRACE_INFO, "Sending delayed event: %s", evtIter->m_Event->GetName().c_str()); - QT3DS_ASSERT(evtIter->m_FireTime <= currentTime); - QueueEvent(evtIter->m_Event, evtIter->m_IsExternal); - } - if (removeIter != m_FutureEvents.begin()) { - m_FutureEvents.erase(m_FutureEvents.begin(), removeIter); - } - } - - bool CheckForStable() - { - CheckForDelayedEvents(); - if (m_EnabledTransitions.empty()) { - m_ScriptContext->ClearCurrentEvent(); - DEBUGGER_CALL(BeginMicrostep); - SelectEventlessTransitions(); - } - - return m_EnabledTransitions.empty() && m_InternalQueue.empty() && m_ExternalQueue.empty(); - } - - // Execute these events, return what state you are in. - // We process all internal and all external events before returning, so you are free to - // free or just deal with all userdata after this. - NVConstDataRef Execute() override - { - if (m_Running == false) - return m_Configuration.m_List; - - DEBUGGER_CALL(BeginStep); - DEBUGGER_CALL(BeginMicrostep); - - m_EnabledTransitions.clear(); - - QT3DSU32 iterationCount = 0; - QT3DSU32 MAX_ITERATION_COUNT = 1000; - - // Here we handle eventless transitions and transitions - // triggered by internal events until machine is stable - while (iterationCount < MAX_ITERATION_COUNT && m_Running && !CheckForStable()) { - ++iterationCount; - if (m_EnabledTransitions.empty() == false) { - Microstep(m_EnabledTransitions); - DEBUGGER_CALL(BeginMicrostep); - } else if (m_InternalQueue.empty() == false) { - NVScopedRefCounted theEvent = m_InternalQueue.front(); - m_ScriptContext->SetCurrentEvent(theEvent); - m_InternalQueue.pop_front(); - DEBUGGER_CALL2(SetCurrentEvent, theEvent->GetName().c_str(), true); -#ifdef QT3DS_LOG_ACTIVE_EVENT - qCInfo(TRACE_INFO, "Current event: %s", theEvent->GetName().c_str()); -#endif - SelectTransitions(*theEvent); - } else if (m_ExternalQueue.empty() == false) { - NVScopedRefCounted theEvent = m_ExternalQueue.front(); - m_ScriptContext->SetCurrentEvent(theEvent); - m_ExternalQueue.pop_front(); - - DEBUGGER_CALL2(SetCurrentEvent, theEvent->GetName().c_str(), false); - -#ifdef QT3DS_LOG_ACTIVE_EVENT - qCInfo(TRACE_INFO, "Current event: %s", theEvent->GetName().c_str()); -#endif - - /* - if isCancelEvent(externalEvent) - running = false - continue - */ - - // TODO datamodel - // datamodel["_event"] = theEvent; - - // TODO invoke - /* - for state in configuration: - for inv in state.invoke: - if inv.invokeid == externalEvent.invokeid: - applyFinalize(inv, externalEvent) - if inv.autoforward: - send(inv.id, externalEvent) - */ - SelectTransitions(*theEvent); - } - } - if (m_Running == false) { - for (nvvector::reverse_iterator iter = m_Configuration.m_List.rbegin(), - end = m_Configuration.m_List.rend(); - iter != end; ++iter) { - TOnExitList *theExitList = (*iter)->GetOnExitList(); - if (theExitList) - m_ExecutionContext->Execute(**iter, *theExitList); - /* - for inv in s.invoke: - cancelInvoke(inv) - */ - - // Set final done data. - /* - if isFinalState(s) and isScxmlState(s.parent): - returnDoneEvent(s.donedata) - */ - } - } - DEBUGGER_CALL(EndStep); - return m_Configuration.m_List; - } - - bool EventsPending() const override - { - return m_InternalQueue.empty() == false || m_ExternalQueue.empty() == false - || m_FutureEvents.empty() == false; - } - - bool IsRunning() const override { return m_Running; } - - void QueueEvent(const char8_t *inEventName, QT3DSU64 inDelay, CRegisteredString inCancelId, - bool inIsExternal) override - { - TEventPtr theEvent = QT3DS_NEW(m_Foundation.getAllocator(), SSimpleEvent)( - m_Foundation.getAllocator(), m_StringTable->RegisterStr(inEventName)); - QueueEvent(theEvent, inDelay, inCancelId, inIsExternal); - } - - void QueueEvent(TEventPtr inEvent, QT3DSU64 inDelay, CRegisteredString inCancelId, - bool inIsExternal) override - { - if (inDelay == 0) { - QueueEvent(inEvent, inIsExternal); - } else { - static QT3DSU64 sTensOfNanoSecondsInAMillisecond = - Time::sNumTensOfNanoSecondsInASecond / 1000; - QT3DSU64 fireTime = Time::getCurrentTimeInTensOfNanoSeconds() - + inDelay * sTensOfNanoSecondsInAMillisecond; - SFutureEvent theNewEvent(inEvent, fireTime, inCancelId, inIsExternal); - TFutureEventList::iterator iter = - eastl::upper_bound(m_FutureEvents.begin(), m_FutureEvents.end(), theNewEvent); - m_FutureEvents.insert(iter, theNewEvent); - } - } - - void QueueEvent(TEventPtr inEvent, bool inIsExternal) override - { - if (inIsExternal) - m_ExternalQueue.push_back(inEvent); - else - m_InternalQueue.push_back(inEvent); - DEBUGGER_CALL2(EventQueued, inEvent->GetName().c_str(), inIsExternal); - } - - void QueueEvent(const char8_t *inEventName, bool inIsExternal) override - { - TEventPtr theEvent = QT3DS_NEW(m_Foundation.getAllocator(), SSimpleEvent)( - m_Foundation.getAllocator(), m_StringTable->RegisterStr(inEventName)); - QueueEvent(theEvent, inIsExternal); - } - - void CancelEvent(CRegisteredString inCancelId) override - { - if (inCancelId.IsValid() == false) - return; - qCInfo(TRACE_INFO, "Cancel of id %s requested", inCancelId.c_str()); - for (QT3DSU32 idx = 0; idx < m_FutureEvents.size(); ++idx) { - if (m_FutureEvents[idx].m_CancelId == inCancelId) { - TFutureEventList::iterator iter = m_FutureEvents.begin() + idx; - qCInfo(TRACE_INFO, "Cancelling event: %s, %s", - iter->m_Event->GetName().c_str(), iter->m_CancelId.c_str()); - m_FutureEvents.erase(iter); - --idx; - } - } - } - - TSignalConnectionPtr RegisterEventHandler(IStateInterpreterEventHandler &inHandler) override - { - SStateSignalSender *sender = QT3DS_NEW(m_Foundation.getAllocator(), SStateSignalSender)( - m_Foundation.getAllocator(), *this, inHandler); - m_SignalSenders.push_back(sender); - return sender; - } - - IScriptContext &GetScriptContext() override { return *m_ScriptContext; } - - IStateContext *GetStateContext() override { return m_Context; } - - debugger::IStateMachineDebugInterface &GetDebugInterface() override { return m_DebugInterface; } - - NVFoundationBase &GetFoundation() override { return m_Foundation; } -}; - -//////////////////////////////////////////////////////////////////////////////////// -// SDebugInterface implementation -//////////////////////////////////////////////////////////////////////////////////// - -void SDebugInterface::addRef() -{ - m_StateSystem.addRef(); -} - -void SDebugInterface::release() -{ - m_StateSystem.release(); -} - -struct SDebugStrOutStream : public IOutStream -{ - TDebugStr m_Str; - bool Write(NVConstDataRef data) override - { - m_Str.append((char8_t *)data.begin(), (char8_t *)data.end()); - return true; - } -}; - -NVConstDataRef ListToRef(const nvvector &inList, TDebugStrList &outData) -{ - outData.resize(inList.size()); - for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) - outData[idx].assign(nonNull(inList[idx]->m_Id.c_str())); - return toConstDataRef(outData.data(), outData.size()); -} - -IScriptContext &SDebugInterface::GetScriptContext() -{ - return *m_StateSystem.m_ScriptContext.mPtr; -} - -// Functions implemented after StateSystem in order to take advantage of the StateSystem struct -// members directly. -void SDebugInterface::OnConnect() -{ - TDebugStr theFilename; - SDebugStrOutStream theOutStream; - if (m_StateSystem.m_Context->GetRoot()) - theFilename.assign(nonNull(m_StateSystem.m_Context->GetRoot()->m_Filename)); - CXMLIO::SaveSCXMLFile(*m_StateSystem.m_Context, m_StateSystem.m_Foundation, - *m_StateSystem.m_StringTable, theOutStream); - m_Listener->OnConnect(theFilename, theOutStream.m_Str, - ListToRef(m_StateSystem.m_Configuration.m_List, m_EnterList)); -} - -// Functions should not be called in there is not a valid listener -void SDebugInterface::BeginStep() -{ - m_Listener->BeginStep(); -} - -void SDebugInterface::BeginMicrostep() -{ - m_Listener->BeginMicroStep(); -} - -void SDebugInterface::SetCurrentEvent(const char8_t *inEventName, bool inInternal) -{ - m_TempStr.assign(nonNull(inEventName)); - m_Listener->SetEvent(m_TempStr, inInternal); -} - -STransitionId TransitionToId(const STransition &inTransition) -{ - SStateNode *parent(inTransition.m_Parent); - STransitionId retval; - if (parent == NULL) { - QT3DS_ASSERT(false); - return retval; - } - - retval.m_StateId.assign(nonNull(parent->m_Id.c_str())); - if (&inTransition == parent->GetInitialTransition()) - retval.m_TransitionIndex = -1; - else if (parent->m_Type == StateNodeTypes::History) { - SHistory &theHistory = static_cast(*parent); - if (&inTransition == theHistory.m_Transition) - retval.m_TransitionIndex = -1; - } - - if (retval.m_TransitionIndex == -2) { - TStateNodeList *childList = parent->GetChildren(); - if (childList) { - QT3DSI32 index = 0; - for (TStateNodeList::iterator iter = childList->begin(), end = childList->end(); - iter != end && retval.m_TransitionIndex == -2; ++iter, ++index) { - SStateNode &theNode(*iter); - if (theNode.m_Type == StateNodeTypes::Transition && &inTransition == (&theNode)) - retval.m_TransitionIndex = index; - } - } - } - - return retval; -} - -void SDebugInterface::SetTransitionSet(const TTransitionList &inTransitions) -{ - m_TransitionList.resize(inTransitions.size()); - for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) - m_TransitionList[idx] = TransitionToId(*inTransitions[idx]); - m_Listener->SetTransitionSet(toDataRef(m_TransitionList.data(), m_TransitionList.size())); -} - -void SDebugInterface::SetExitSet(const TStateNodeSet &inSet) -{ - NVConstDataRef theSet(ListToRef(inSet.m_List, this->m_ExitList)); - m_Listener->SetExitSet(theSet); -} -void SDebugInterface::SetEnterSet(const TStateNodeSet &inSet) -{ - NVConstDataRef theSet(ListToRef(inSet.m_List, this->m_EnterList)); - m_Listener->SetEnterSet(theSet); -} -// Log statements run through the debugger as well. -void SDebugInterface::EndMicrostep() -{ - m_Listener->EndMicroStep(); -} -void SDebugInterface::EndStep() -{ - m_Listener->EndStep(); -} - -void SDebugInterface::OnExternalBreak() -{ - if (m_Listener) - m_Listener->OnExternalBreak(); -} - -SStateSignalSender::~SStateSignalSender() -{ - if (m_System) { - m_System->m_SignalSenders.erase( - eastl::find(m_System->m_SignalSenders.begin(), m_System->m_SignalSenders.end(), this)); - } -} -} - -IStateInterpreter &IStateInterpreter::Create(NVFoundationBase &inFnd, IStringTable &inStrTable, - IScriptContext &inScriptContext, - IExecutionContext &inExecutionContext) -{ - return *QT3DS_NEW(inFnd.getAllocator(), StateSystem)(inFnd, inStrTable, inScriptContext, - inExecutionContext); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateVisualBindingContext.cpp b/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateVisualBindingContext.cpp deleted file mode 100644 index 62413bae..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateVisualBindingContext.cpp +++ /dev/null @@ -1,626 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateVisualBindingContext.h" - -#include "Qt3DSStateVisualBindingContextValues.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "EASTL/string.h" -#include "EASTL/hash_map.h" -#include "Qt3DSStateInterpreter.h" -#include "Qt3DSStateContext.h" -#include "foundation/XML.h" -#include "foundation/FileTools.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/SerializationTypes.h" -#include "foundation/StringConversionImpl.h" - -using namespace qt3ds::state; - -namespace { - -struct SStateEventKey -{ - InterpreterEventTypes::Enum m_Event; - CRegisteredString m_Id; - SStateEventKey(InterpreterEventTypes::Enum inEvt, CRegisteredString inId) - : m_Event(inEvt) - , m_Id(inId) - { - } - bool operator==(const SStateEventKey &inOther) const - { - return m_Event == inOther.m_Event && m_Id == inOther.m_Id; - } -}; -} -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SStateEventKey &inKey) const - { - return hash()((int)inKey.m_Event) - ^ hash()(inKey.m_Id); - } -}; -} - -namespace { -struct SVisualStateCommandNode -{ - SVisualStateCommand m_Command; - SVisualStateCommandNode *m_NextSibling; - SVisualStateCommandNode(const SVisualStateCommand &inCommand = SVisualStateCommand()) - : m_Command(inCommand) - , m_NextSibling(NULL) - { - } -}; - -DEFINE_INVASIVE_SINGLE_LIST(VisualStateCommandNode); -IMPLEMENT_INVASIVE_SINGLE_LIST(VisualStateCommandNode, m_NextSibling); - -typedef TVisualStateCommandNodeList TCommandList; - -// Apparently eastl::hash_multimap isn't order preserving for items. -typedef eastl::hash_map, - eastl::equal_to, ForwardingAllocator> - TStateEventCommandMap; - -struct SStateMachineSystem : public IStateInterpreterEventHandler, public NVRefCounted -{ - NVAllocatorCallback &m_Allocator; - CRegisteredString m_Path; - CRegisteredString m_Id; - CRegisteredString m_DatamodelFunction; - - NVScopedRefCounted m_StringTable; - NVScopedRefCounted m_Interpreter; - TStateEventCommandMap m_CommandMap; - QT3DSI32 mRefCount; - bool m_Error; - bool m_Running; - - TSignalConnectionPtr m_InterpreterEventConnection; - NVScopedRefCounted m_CommandHandler; - NVScopedRefCounted m_InterpreterFactory; - - SStateMachineSystem(const char8_t *inPath, const char8_t *inId, const char8_t *inFunction, - IStringTable &inStrTable, NVAllocatorCallback &inAlloc) - : m_Allocator(inAlloc) - , m_Path(inStrTable.RegisterStr(inPath)) - , m_Id(inStrTable.RegisterStr(inId)) - , m_DatamodelFunction(inStrTable.RegisterStr(inFunction)) - , m_StringTable(inStrTable) - , m_CommandMap(ForwardingAllocator(inAlloc, "SStateMachineSystem::m_CommandMap")) - , mRefCount(0) - , m_Error(false) - , m_Running(false) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) - - void Initialize() - { - } - - void Start() - { - if (m_Error || m_Running || !m_Interpreter) - return; - m_Running = true; - m_Interpreter->Start(); - // Event handler must be replaced after interpreter started - m_InterpreterEventConnection = m_Interpreter->RegisterEventHandler(*this); - // Run throw the initial configuration and fire any enter events. This takes care of - // initial states. - NVConstDataRef initialConfig = m_Interpreter->GetConfiguration(); - for (QT3DSU32 nodeIdx = 0, nodeEnd = initialConfig.size(); nodeIdx < nodeEnd; ++nodeIdx) { - SStateNode *theNode(initialConfig[nodeIdx]); - OnInterpreterEvent(InterpreterEventTypes::StateEnter, theNode->m_Id); - } - } - - void Update() - { - if (m_Interpreter) { - m_Interpreter->Execute(); - } - } - - void OnInterpreterEvent(InterpreterEventTypes::Enum inEvent, - CRegisteredString inEventId) override - { - if (m_CommandHandler) { - CRegisteredString theId = m_StringTable->RegisterStr(inEventId.c_str()); - SStateEventKey theKey(inEvent, theId); - TStateEventCommandMap::iterator theItem = m_CommandMap.find(theKey); - if (theItem != m_CommandMap.end()) { - for (TCommandList::iterator iter = theItem->second.begin(), - end = theItem->second.end(); - iter != end; ++iter) - m_CommandHandler->Handle(iter->m_Command, m_Interpreter->GetScriptContext()); - } - } - } -}; - -typedef eastl::vector> TStateMachineList; - -struct SVisualStateContext : public IVisualStateContext -{ - NVFoundationBase &m_Foundation; - SSAutoDeallocatorAllocator m_DataAllocator; - QT3DSI32 mRefCount; - TStateMachineList m_StateMachines; - NVScopedRefCounted m_CommandHandler; - NVScopedRefCounted m_InterpreterFactory; - NVScopedRefCounted m_StringTable; - nvvector m_PreparseResults; - - SVisualStateContext(NVFoundationBase &fnd, IStringTable &inStrTable) - : m_Foundation(fnd) - , m_DataAllocator(fnd) - , mRefCount(0) - , m_StringTable(inStrTable) - , m_PreparseResults(fnd.getAllocator(), "SVisualStateContext::m_PreparseResults") - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - void LoadStateMachine(const char8_t *id, const char8_t *inRelativePath, - const char8_t *inDatamodelFunction) override - { - SStateMachineSystem *theSystem = QT3DS_NEW(m_Foundation.getAllocator(), SStateMachineSystem)( - inRelativePath, id, inDatamodelFunction, *m_StringTable, m_Foundation.getAllocator()); - theSystem->m_CommandHandler = m_CommandHandler; - theSystem->m_InterpreterFactory = m_InterpreterFactory; - m_StateMachines.push_back(theSystem); - } - - CRegisteredString ParseStrAtt(IDOMReader &inReader, const char8_t *attName) - { - const char8_t *temp = ""; - if (inReader.UnregisteredAtt(attName, temp)) { - return m_StringTable->RegisterStr(temp); - } - return CRegisteredString(); - } - - void PreparseExecutableContent(IDOMReader &inReader) - { - for (bool setatt = inReader.MoveToFirstChild(); setatt; - setatt = inReader.MoveToNextSibling()) { - IDOMReader::Scope __commandScope(inReader); - const char8_t *elemName = inReader.GetElementName(); - - SElementReference theReference; - if (AreEqual(elemName, "goto-slide")) { - theReference = SElementReference(ParseStrAtt(inReader, "element")); - } else if (AreEqual(elemName, "call")) { - theReference = SElementReference(ParseStrAtt(inReader, "element")); - } else if (AreEqual(elemName, "set-attribute")) { - theReference = SElementReference(ParseStrAtt(inReader, "element"), - ParseStrAtt(inReader, "attribute")); - } else if (AreEqual(elemName, "fire-event")) { - theReference = SElementReference(ParseStrAtt(inReader, "element")); - } else if (AreEqual(elemName, "set-presentation")) { - } else { - qCCritical(INVALID_PARAMETER, "Unrecognized child in an enter/exit node: %s", elemName); - } - if (theReference.m_ElementPath.IsValid()) { - m_PreparseResults.push_back(theReference); - } - } - } - - NVConstDataRef PreParseDocument(IDOMReader &inReader) override - { - m_PreparseResults.clear(); - for (bool success = inReader.MoveToFirstChild("statemachine"); success; - success = inReader.MoveToNextSibling("statemachine")) { - IDOMReader::Scope __readerScope(inReader); - if (inReader.MoveToFirstChild("visual-states")) { - IDOMReader::Scope __bindingsScope(inReader); - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - IDOMReader::Scope __stateScope(inReader); - if (AreEqual(inReader.GetElementName().c_str(), "transition")) { - PreparseExecutableContent(inReader); - } else { - for (bool enterExitSuccess = inReader.MoveToFirstChild(); enterExitSuccess; - enterExitSuccess = inReader.MoveToNextSibling()) { - IDOMReader::Scope __enterExitScope(inReader); - PreparseExecutableContent(inReader); - } - } - } - } - } - return m_PreparseResults; - } - - void ParseGotoSlideData(IDOMReader &inReader, SGotoSlideData &inData) - { - const char *tempData; - if (inReader.UnregisteredAtt("direction", tempData) && AreEqual(tempData, "reverse")) - inData.m_Reverse = true; - - if (inReader.UnregisteredAtt("mode", tempData)) { - if (AreEqual(tempData, "stopatend")) { - inData.m_Mode = SlidePlaybackModes::StopAtEnd; - inData.m_PlaythroughTo = CRegisteredString(); - } else if (AreEqual(tempData, "looping")) - inData.m_Mode = SlidePlaybackModes::Looping; - else if (AreEqual(tempData, "pingpong")) - inData.m_Mode = SlidePlaybackModes::PingPong; - else if (AreEqual(tempData, "ping")) - inData.m_Mode = SlidePlaybackModes::Ping; - else if (AreEqual(tempData, "playthrough")) { - if (!inReader.UnregisteredAtt("playthroughto", tempData) || isTrivial(tempData)) { - qCCritical(INVALID_OPERATION, "Goto slide command has playthough " - "mode but no playthroughto attribute; mode will be ignored"); - } else { - inData.m_PlaythroughTo = m_StringTable->RegisterStr(tempData); - } - - if (inData.m_PlaythroughTo.hasValue()) - inData.m_Mode = SlidePlaybackModes::StopAtEnd; - } - } - - if (inReader.UnregisteredAtt("state", tempData)) - inData.m_Paused = AreEqual(tempData, "pause"); - - if (inReader.UnregisteredAtt("rate", tempData)) { - QT3DSF32 temp = 1.0f; - if (StringConversion().StrTo(tempData, temp)) - inData.m_Rate = temp; - } - - if (inReader.UnregisteredAtt("time", tempData)) { - QT3DSF32 temp = 0.0f; - if (StringConversion().StrTo(tempData, temp)) - inData.m_StartTime = static_cast(NVMax(0.0f, temp) * 1000.0f + .5f); - } - } - - void ParseExecutableContent(IDOMReader &inReader, CRegisteredString &inStateId, - InterpreterEventTypes::Enum inEvent, - TStateEventCommandMap &inCommandMap) - { - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - IDOMReader::Scope __itemScope(inReader); - const char8_t *elemName = inReader.GetElementName(); - SVisualStateCommand theCommand; - if (AreEqual(elemName, "goto-slide")) { - const char8_t *rel; - if (inReader.UnregisteredAtt("rel", rel)) { - const char8_t *wrap; - inReader.UnregisteredAtt("wrap", wrap); - SGotoSlideRelative::Enum direction = SGotoSlideRelative::Error; - if (AreEqual(rel, "next")) - direction = SGotoSlideRelative::Next; - else if (AreEqual(rel, "previous")) - direction = SGotoSlideRelative::Previous; - else { - qCCritical(INVALID_OPERATION, "Goto slide relative has invalid " - "attribute (neither 'next' nor 'previous')"); - } - bool doWrap = AreEqual(wrap, "true") ? true : false; - - SGotoSlideRelative theCommandData(ParseStrAtt(inReader, "element"), direction, - doWrap); - ParseGotoSlideData(inReader, theCommandData.m_GotoSlideData); - theCommand = SVisualStateCommand(theCommandData); - } else { - SGotoSlide theCommandData(ParseStrAtt(inReader, "element"), - ParseStrAtt(inReader, "slide")); - ParseGotoSlideData(inReader, theCommandData.m_GotoSlideData); - theCommand = SVisualStateCommand(theCommandData); - } - } else if (AreEqual(elemName, "call")) { - theCommand = SVisualStateCommand(SCallFunction(ParseStrAtt(inReader, "element"), - ParseStrAtt(inReader, "handler"), - ParseStrAtt(inReader, "arguments"))); - } else if (AreEqual(elemName, "set-attribute")) { - theCommand = SVisualStateCommand(SSetAttribute(ParseStrAtt(inReader, "element"), - ParseStrAtt(inReader, "attribute"), - ParseStrAtt(inReader, "value"))); - } else if (AreEqual(elemName, "fire-event")) { - theCommand = SVisualStateCommand( - SFireEvent(ParseStrAtt(inReader, "element"), ParseStrAtt(inReader, "event"))); - } else if (AreEqual(elemName, "set-presentation")) { - theCommand = SVisualStateCommand(SPresentationAttribute( - ParseStrAtt(inReader, "ref"), ParseStrAtt(inReader, "attribute"), - ParseStrAtt(inReader, "value"))); - } else if (AreEqual(elemName, "play-sound")) { - theCommand = SVisualStateCommand(SPlaySound(ParseStrAtt(inReader, "file"))); - } else { - qCCritical(INVALID_PARAMETER, "Unrecognized child in an enter/exit node: %s", elemName); - } - if (theCommand.getType() != VisualStateCommandTypes::NoVisualStateCommand) { - TCommandList &theList = inCommandMap - .insert(eastl::make_pair( - SStateEventKey(inEvent, inStateId), TCommandList())) - .first->second; - theList.push_back(*QT3DS_NEW(m_DataAllocator, SVisualStateCommandNode)(theCommand)); - } - } - } - - SStateMachineSystem *FindStateMachine(const char8_t *inId) - { - if (isTrivial(inId)) - return NULL; - if (inId[0] == '#') - ++inId; - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) - if (AreEqual(m_StateMachines[idx].mPtr->m_Id.c_str(), inId)) - return m_StateMachines[idx].mPtr; - return NULL; - } - - // We have to be careful of string table values coming from the state machine and from the - // reader - // because we don't necessarily share the same string table. - void LoadVisualStateMapping(IDOMReader &inReader) override - { - for (bool success = inReader.MoveToFirstChild("statemachine"); success; - success = inReader.MoveToNextSibling("statemachine")) { - IDOMReader::Scope __readerScope(inReader); - const char8_t *machineId = ""; - if (inReader.UnregisteredAtt("ref", machineId)) { - SStateMachineSystem *theSystem = FindStateMachine(machineId + 1); - if (theSystem == NULL) { - qCCritical(INVALID_OPERATION, "Unknown state machine id: %s", - nonNull(machineId)); - continue; - } - - if (inReader.MoveToFirstChild("visual-states")) { - IDOMReader::Scope __bindingsScope(inReader); - for (bool bindingsSuccess = inReader.MoveToFirstChild(); bindingsSuccess; - bindingsSuccess = inReader.MoveToNextSibling()) { - IDOMReader::Scope __stateScope(inReader); - const char8_t *rawStateId = ""; - inReader.UnregisteredAtt("ref", rawStateId); - if (isTrivial(rawStateId)) - continue; - - if (rawStateId[0] == '#') - ++rawStateId; - CRegisteredString elemName = m_StringTable->RegisterStr(rawStateId); - - if (AreEqual(inReader.GetElementName().c_str(), "transition")) { - ParseExecutableContent(inReader, elemName, - InterpreterEventTypes::Transition, - theSystem->m_CommandMap); - } else { - for (bool stateSuccess = inReader.MoveToFirstChild(); stateSuccess; - stateSuccess = inReader.MoveToNextSibling()) { - IDOMReader::Scope __enterExitScope(inReader); - const char8_t *stateChildName = inReader.GetElementName(); - if (AreEqual(stateChildName, "enter")) { - ParseExecutableContent(inReader, elemName, - InterpreterEventTypes::StateEnter, - theSystem->m_CommandMap); - } else if (AreEqual(stateChildName, "exit")) { - ParseExecutableContent(inReader, elemName, - InterpreterEventTypes::StateExit, - theSystem->m_CommandMap); - } else { - qCCritical(INVALID_PARAMETER, - "Unrecognized child in a visual state bindings state: %s", - stateChildName); - } - } - } - } - } - } else { - qCCritical(INVALID_OPERATION, "visual-state element has no machine attribute"); - } - } - } - - void SetCommandHandler(IVisualStateCommandHandler *inHandler) override - { - m_CommandHandler = inHandler; - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) - m_StateMachines[idx]->m_CommandHandler = inHandler; - } - - void SetInterpreterFactory(IVisualStateInterpreterFactory *inHandler) override - { - m_InterpreterFactory = inHandler; - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) - m_StateMachines[idx]->m_InterpreterFactory = inHandler; - } - - void Initialize() override - { - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) - m_StateMachines[idx]->Initialize(); - } - - void Start() override - { - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) - m_StateMachines[idx]->Start(); - } - - void Update() override - { - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) - m_StateMachines[idx]->Update(); - } - - QT3DSU32 CountItems(TCommandList &list) - { - QT3DSU32 retval = 0; - for (TCommandList::iterator iter = list.begin(), end = list.end(); iter != end; ++iter) - ++retval; - return retval; - } - - struct SSaveVisitor - { - const SStrRemapMap &m_RemapMap; - SSaveVisitor(const SStrRemapMap &map) - : m_RemapMap(map) - { - } - template - SVisualStateCommand operator()(const TItemType &item) - { - TItemType newItem(item); - newItem.Remap(*this); - return newItem; - } - void Remap(CRegisteredString &inStr) { inStr.Remap(m_RemapMap); } - SVisualStateCommand operator()() { return SVisualStateCommand(); } - }; - - void BinarySave(IOutStream &stream) override - { - qt3ds::foundation::SWriteBuffer theWriteBuffer(m_Foundation.getAllocator(), - "BinarySave::writebuffer"); - // Allocate space for overall size of the data section - theWriteBuffer.writeZeros(4); - theWriteBuffer.write((QT3DSU32)m_StateMachines.size()); - const SStrRemapMap &theRemapMap(m_StringTable->GetRemapMap()); - for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) { - SStateMachineSystem &theSystem = *m_StateMachines[idx]; - CRegisteredString path(theSystem.m_Path); - CRegisteredString id(theSystem.m_Id); - CRegisteredString fn(theSystem.m_DatamodelFunction); - path.Remap(theRemapMap); - id.Remap(theRemapMap); - fn.Remap(theRemapMap); - theWriteBuffer.write(path); - theWriteBuffer.write(id); - theWriteBuffer.write(fn); - theWriteBuffer.write((QT3DSU32)theSystem.m_CommandMap.size()); - for (TStateEventCommandMap::iterator iter = theSystem.m_CommandMap.begin(), - mapEnd = theSystem.m_CommandMap.end(); - iter != mapEnd; ++iter) { - theWriteBuffer.write((QT3DSU32)iter->first.m_Event); - CRegisteredString stateId(iter->first.m_Id); - stateId.Remap(theRemapMap); - theWriteBuffer.write(stateId); - - theWriteBuffer.write(CountItems(iter->second)); - for (TCommandList::iterator cmdIter = iter->second.begin(), - cmdEnd = iter->second.end(); - cmdIter != cmdEnd; ++cmdIter) { - SVisualStateCommand remapped = - cmdIter->m_Command.visit(SSaveVisitor(theRemapMap)); - SVisualStateCommandNode theNode(remapped); - theWriteBuffer.write(theNode); - } - } - } - QT3DSU32 totalSize = theWriteBuffer.size(); - QT3DSU32 *data = (QT3DSU32 *)theWriteBuffer.begin(); - data[0] = totalSize - 4; - stream.Write((QT3DSU8 *)data, totalSize); - } - - struct SLoadVisitor - { - NVDataRef m_RemapMap; - SLoadVisitor(const NVDataRef map) - : m_RemapMap(map) - { - } - template - void operator()(TItemType &item) - { - item.Remap(*this); - } - - void Remap(CRegisteredString &inStr) { inStr.Remap(m_RemapMap); } - void operator()() {} - }; - - void BinaryLoad(IInStream &stream, NVDataRef inStringTableData) override - { - QT3DSU32 length; - stream.Read(length); - QT3DSU8 *data = (QT3DSU8 *)m_DataAllocator.allocate(length, "Binaryload", __FILE__, __LINE__); - stream.Read(data, length); - - SDataReader theReader(data, data + length); - QT3DSU32 numMachines = theReader.LoadRef(); - m_StateMachines.clear(); - m_StateMachines.reserve(numMachines); - for (QT3DSU32 idx = 0, end = numMachines; idx < end; ++idx) { - CRegisteredString path = theReader.LoadRef(); - CRegisteredString id = theReader.LoadRef(); - CRegisteredString fn = theReader.LoadRef(); - path.Remap(inStringTableData); - id.Remap(inStringTableData); - fn.Remap(inStringTableData); - LoadStateMachine(id, path, fn); - SStateMachineSystem &theSystem(*m_StateMachines.back()); - QT3DSU32 mapSize = theReader.LoadRef(); - for (QT3DSU32 mapIdx = 0; mapIdx < mapSize; ++mapIdx) { - InterpreterEventTypes::Enum evt = - static_cast(theReader.LoadRef()); - CRegisteredString stateId = theReader.LoadRef(); - stateId.Remap(inStringTableData); - QT3DSU32 numCommands = theReader.LoadRef(); - TCommandList &theList = - theSystem.m_CommandMap - .insert(eastl::make_pair(SStateEventKey(evt, stateId), TCommandList())) - .first->second; - for (QT3DSU32 cmdIdx = 0, cmdEnd = numCommands; cmdIdx < cmdEnd; ++cmdIdx) { - SVisualStateCommandNode *nextNode = theReader.Load(); - nextNode->m_Command.visit(SLoadVisitor(inStringTableData)); - theList.push_back(*nextNode); - } - } - } - } -}; -} - -IVisualStateContext &IVisualStateContext::Create(NVFoundationBase &inFoundation, - IStringTable &inStrTable) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SVisualStateContext)(inFoundation, inStrTable); -} diff --git a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateXMLIO.cpp b/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateXMLIO.cpp deleted file mode 100644 index 44f3242f..00000000 --- a/src/Runtime/Source/Qt3DSStateApplication/Source/Qt3DSStateXMLIO.cpp +++ /dev/null @@ -1,1948 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSStateXMLIO.h" -#include "foundation/XML.h" -#include "Qt3DSStateTypes.h" -#include "Qt3DSStateContext.h" -#include "foundation/Utils.h" -#include "foundation/StringConversionImpl.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "EASTL/hash_map.h" -#include "Qt3DSStateExecutionTypes.h" -#include "Qt3DSStateEditor.h" -#include "Qt3DSStateEditorValue.h" - -using namespace qt3ds::state; -using namespace qt3ds::state::editor; - -namespace { -#define ITERATE_XML_ELEMENT_NAMES \ - HANDLE_XML_ELEMENT_NAME(scxml) \ - HANDLE_XML_ELEMENT_NAME(state) \ - HANDLE_XML_ELEMENT_NAME(parallel) \ - HANDLE_XML_ELEMENT_NAME(transition) \ - HANDLE_XML_ELEMENT_NAME(initial) \ - HANDLE_XML_ELEMENT_NAME(final) \ - HANDLE_XML_ELEMENT_NAME(onentry) \ - HANDLE_XML_ELEMENT_NAME(onexit) \ - HANDLE_XML_ELEMENT_NAME(history) \ - HANDLE_XML_ELEMENT_NAME(raise) \ - HANDLE_XML_ELEMENT_NAME(if) \ - HANDLE_XML_ELEMENT_NAME(elseif) \ - HANDLE_XML_ELEMENT_NAME(else) \ - HANDLE_XML_ELEMENT_NAME(foreach) \ - HANDLE_XML_ELEMENT_NAME(log) \ - HANDLE_XML_ELEMENT_NAME(param) \ - HANDLE_XML_ELEMENT_NAME(assign) \ - HANDLE_XML_ELEMENT_NAME(script) \ - HANDLE_XML_ELEMENT_NAME(send) \ - HANDLE_XML_ELEMENT_NAME(cancel) \ - HANDLE_XML_ELEMENT_NAME(invoke) \ - HANDLE_XML_ELEMENT_NAME(finalize) \ - HANDLE_XML_ELEMENT_NAME(cond) \ - HANDLE_XML_ELEMENT_NAME(event) \ - HANDLE_XML_ELEMENT_NAME(datamodel) \ - HANDLE_XML_ELEMENT_NAME(data) \ - HANDLE_XML_ELEMENT_NAME(content) \ - HANDLE_XML_ELEMENT_NAME(external_transition) - -struct SXMLName -{ - enum Enum { -#define HANDLE_XML_ELEMENT_NAME(nm) e##nm, - ITERATE_XML_ELEMENT_NAMES -#undef HANDLE_XML_ELEMENT_NAME - LastName, - }; - static const char *GetNameForElemName(Enum inName) - { - switch (inName) { -#define HANDLE_XML_ELEMENT_NAME(nm) \ - case e##nm: \ - return #nm; - ITERATE_XML_ELEMENT_NAMES -#undef HANDLE_XML_ELEMENT_NAME - default: - break; - } - QT3DS_ASSERT(false); - return "unknown element"; - } -}; - -const char8_t *GetSCXMLNamespace() -{ - return "http://www.w3.org/2005/07/scxml"; -} -const char8_t *GetStudioStateNamespace() -{ - return "http://qt.io/qt3dstudio/uicstate"; -} - -typedef eastl::pair *> TIdListPtrPair; -typedef eastl::pair TIdSendPair; - -TEditorStr DoGenerateUniqueId(const char *inRoot, IStateContext &ioContext, - IStringTable &ioStringTable) -{ - if (isTrivial(inRoot)) - inRoot = "id"; - TEditorStr stem(inRoot); - TEditorStr idStr(stem); - // Make the stem a valid possible id according xml specifications - if (idStr.size()) { - // Replace all spaces with undre - // Check that the first item isn't a space or a number. We can't do a real check here - // because we don't have unicode tables of letters and such. - // replace spaces with underscores. - for (TEditorStr::size_type thePos = idStr.find(' '); thePos != TEditorStr::npos; - thePos = idStr.find(' ', thePos + 1)) - idStr.replace(thePos, 1, "_"); - if (idStr[0] >= '0' && idStr[0] <= '9') - idStr.insert(idStr.begin(), 1, ':'); - } - - QT3DSU32 idx = 0; - - while (ioContext.ContainsId(ioStringTable.RegisterStr(idStr.c_str()))) { - ++idx; - char temp[64]; - sprintf(temp, "%d", idx); - idStr.assign(stem); - idStr.append("_"); - idStr.append(temp); - } - - return idStr; -} - -struct SParseContext -{ - typedef nvvector> TExternalTransitionList; - - NVAllocatorCallback &m_GraphAllocator; - NVFoundationBase &m_Foundation; - IDOMReader &m_Reader; - IStateContext &m_Context; - IStringTable &m_StrTable; - IEditor *m_Editor; - CRegisteredString m_Names[SXMLName::LastName]; - MemoryBuffer m_ParseBuffer; - nvvector m_TempBuffer; - // To be filled in on the second parse pass - nvvector m_References; - nvvector m_SendReferences; - CXMLIO::TIdRemapMap m_RemapMap; - nvvector m_GenerateIdList; - TExternalTransitionList m_ExternalTransitions; - CRegisteredString m_SCXMLNamespace; - CRegisteredString m_StudioNamespace; - QT3DSI32 m_Version; - - SParseContext(NVAllocatorCallback &inGraphAlloc, NVFoundationBase &inFnd, IDOMReader &inReader, - IStateContext &inCtx, IStringTable &inStrTable, IEditor *inEditor) - : m_GraphAllocator(inGraphAlloc) - , m_Foundation(inFnd) - , m_Reader(inReader) - , m_Context(inCtx) - , m_StrTable(inStrTable) - , m_Editor(inEditor) - , m_ParseBuffer(ForwardingAllocator(inFnd.getAllocator(), "ParseBuffer")) - , m_TempBuffer(inFnd.getAllocator(), "TempBuffer") - , m_References(inFnd.getAllocator(), "m_References") - , m_SendReferences(inFnd.getAllocator(), "m_StrReferences") - , m_GenerateIdList(inFnd.getAllocator(), "m_GenerateIdList") - , m_ExternalTransitions(inFnd.getAllocator(), "m_ExternalTransitions") - , m_Version(SSCXML::GetCurrentVersion()) - { -#define HANDLE_XML_ELEMENT_NAME(nm) m_Names[SXMLName::e##nm] = inStrTable.RegisterStr(#nm); - ITERATE_XML_ELEMENT_NAMES -#undef HANDLE_XML_ELEMENT_NAME - m_SCXMLNamespace = inStrTable.RegisterStr(GetSCXMLNamespace()); - m_StudioNamespace = inStrTable.RegisterStr(GetStudioStateNamespace()); - } - - inline bool eq(CRegisteredString lhs, SXMLName::Enum rhs) { return lhs == m_Names[rhs]; } - const char8_t *ToGraphStr(const char8_t *temp) - { - temp = nonNull(temp); - QT3DSU32 len = StrLen(temp) + 1; - char8_t *retval = - (char8_t *)m_GraphAllocator.allocate(len, "graph string", __FILE__, __LINE__); - memCopy(retval, temp, len); - // Force null termination regardless. - retval[len] = 0; - return retval; - } - const char8_t *ParseStrAtt(const char8_t *attName) - { - const char8_t *temp; - if (m_Reader.UnregisteredAtt(attName, temp) && temp && *temp) - return ToGraphStr(temp); - return NULL; - } - void ParseStrAtt(const char8_t *attName, const char8_t *&outVal) - { - outVal = ParseStrAtt(attName); - } - void ParseStrAtt(const char8_t *attName, CRegisteredString &outVal) - { - m_Reader.Att(attName, outVal); - } - - SItemExtensionInfo &GetExtensionInfo(void *inItem) - { - return m_Context.GetOrCreateExtensionInfo(inItem); - } - - // Extension attributes are indicated by their namespace. If they have a namespace - // and they aren't scxml namespace and they aren't studio namespace, they are extension. - void ParseExtensionAttributes(void *inItem) - { - for (SDOMAttribute *theAttribute = m_Reader.GetFirstAttribute(); theAttribute; - theAttribute = theAttribute->m_NextAttribute) { - if (theAttribute->m_Namespace != m_StudioNamespace - && theAttribute->m_Namespace != m_SCXMLNamespace - && theAttribute->m_Namespace.IsValid()) { - GetExtensionInfo(inItem).m_ExtensionAttributes.push_back( - *QT3DS_NEW(m_GraphAllocator, SDOMAttributeNode)(theAttribute)); - } - } - } - bool ParseExtensionElement(void *inItem) - { - SDOMElement &theElement(*m_Reader.GetElement()); - - if (theElement.m_Namespace != m_StudioNamespace - && theElement.m_Namespace != m_SCXMLNamespace && theElement.m_Namespace.IsValid()) { - GetExtensionInfo(inItem).m_ExtensionNodes.push_back( - *QT3DS_NEW(m_GraphAllocator, SDOMElementNode)(&theElement)); - return true; - } - return false; - } - - void ParseExtensionElements(void *inItem) - { - IDOMReader::Scope _childElemScope(m_Reader); - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - ParseExtensionElement(inItem); - } - } - - NVConstDataRef ParseFloats(const char8_t *inData) - { - size_t len = StrLen(inData) + 1; - if (len == 1) - return NVConstDataRef(); - m_TempBuffer.resize((QT3DSU32)len); - memCopy(m_TempBuffer.data(), inData, (QT3DSU32)len); - m_ParseBuffer.clear(); - Char8TReader theReader(m_TempBuffer.data(), m_ParseBuffer); - NVConstDataRef retval; - theReader.ReadBuffer(retval); - return retval; - } - bool ParseVec2Att(const char8_t *attName, QT3DSVec2 &outVal) - { - const char8_t *tempVal; - if (m_Reader.UnregisteredAtt(attName, tempVal, GetStudioStateNamespace())) { - NVConstDataRef floats = ParseFloats(tempVal); - if (floats.mSize >= 2) { - memCopy(&outVal.x, floats.mData, sizeof(outVal)); - return true; - } - } - return false; - } - - bool ParseVec3Att(const char8_t *attName, QT3DSVec3 &outVal) - { - const char8_t *tempVal; - if (m_Reader.UnregisteredAtt(attName, tempVal, GetStudioStateNamespace())) { - NVConstDataRef floats = ParseFloats(tempVal); - if (floats.mSize >= 3) { - memCopy(&outVal.x, floats.mData, sizeof(outVal)); - return true; - } - } - return false; - } - - CRegisteredString RemapStr(CRegisteredString inStr) - { - CXMLIO::TIdRemapMap::iterator iter = m_RemapMap.find(inStr.c_str()); - if (iter != m_RemapMap.end()) - inStr = m_StrTable.RegisterStr(iter->second.c_str()); - return inStr; - } - - SStateNode *FindStateNode(CRegisteredString inString) - { - return m_Context.FindStateNode(RemapStr(inString)); - } - - SSend *ParseSendIdSecondPass(const char8_t *inStr) - { - if (isTrivial(inStr)) - return NULL; - return m_Context.FindSend(RemapStr(m_StrTable.RegisterStr(inStr))); - } - - NVConstDataRef ParseIDRefSecondPass(const char8_t *inStr) - { - typedef eastl::basic_string TStrType; - TStrType workspace(ForwardingAllocator(m_Foundation.getAllocator(), "ParseIDRef")); - TStrType str(ForwardingAllocator(m_Foundation.getAllocator(), "ParseIDRef")); - nvvector tempVal(m_Foundation.getAllocator(), "ParseIDRef"); - - workspace.assign(inStr); - for (TStrType::size_type startPos = workspace.find_first_not_of(' '), - endPos = workspace.find_first_of(' ', startPos); - startPos != TStrType::npos; startPos = workspace.find_first_not_of(' ', endPos), - endPos = workspace.find_first_of(' ', startPos)) { - if (endPos == TStrType::npos) - endPos = workspace.size(); - str = workspace.substr(startPos, endPos - startPos); - CRegisteredString theStr(m_StrTable.RegisterStr(str.c_str())); - SStateNode *theNode = FindStateNode(theStr); - if (theNode) - tempVal.push_back(theNode); - } - if (tempVal.size() == 0) - return NVConstDataRef(); - - SStateNode **dataPtr = (SStateNode **)m_GraphAllocator.allocate( - tempVal.size() * sizeof(SStateNode *), "IDRef", __FILE__, __LINE__); - memCopy(dataPtr, tempVal.data(), tempVal.size() * sizeof(SStateNode *)); - return toDataRef(dataPtr, tempVal.size()); - } - - void ParseIDRef(const char8_t *inStr, NVConstDataRef &ioNodes) - { - if (inStr == NULL || *inStr == 0) { - ioNodes = NVConstDataRef(); - return; - } - m_References.push_back(eastl::make_pair(inStr, &ioNodes)); - } - - static void AppendChild(SStateNode &inParent, TStateNodeList &outChildren, SStateNode &inChild) - { - inChild.m_Parent = &inParent; - outChildren.push_back(inChild); - } - - static void AppendChild(SStateNode *inNodeParent, SExecutableContent *inParent, - TExecutableContentList &outChildren, SExecutableContent &inChild) - { - if (inNodeParent) { - QT3DS_ASSERT(inParent == NULL); - } else { - QT3DS_ASSERT(inParent); - } - inChild.m_StateNodeParent = inNodeParent; - inChild.m_Parent = inParent; - outChildren.push_back(inChild); - } - - template - void ParseEditorAttributes(TStateType &inNode) - { - ParseExtensionAttributes(&inNode); - if (m_Editor) { - const char8_t *name; - if (m_Reader.UnregisteredAtt("id", name, GetStudioStateNamespace())) - m_Editor->GetOrCreate(inNode)->SetPropertyValue("id", eastl::string(nonNull(name))); - - QT3DSVec2 temp; - if (ParseVec2Att("position", temp)) - m_Editor->GetOrCreate(inNode)->SetPropertyValue("position", temp); - - if (ParseVec2Att("dimension", temp)) - m_Editor->GetOrCreate(inNode)->SetPropertyValue("dimension", temp); - - QT3DSVec3 tempv3; - if (ParseVec3Att("color", tempv3)) - m_Editor->GetOrCreate(inNode)->SetPropertyValue("dimension", tempv3); - } - } - - void ParseStateNodeEditorAttributes(SStateNode &inNode) - { - ParseExtensionAttributes(&inNode); - CRegisteredString Id; - if (inNode.m_Id.IsValid() == false) - m_Reader.Att("id", inNode.m_Id); - - QT3DSVec2 temp; - if (ParseVec2Att("position", temp)) - inNode.SetPosition(temp); - - if (ParseVec2Att("dimension", temp)) - inNode.SetDimension(temp); - - QT3DSVec3 tempv3; - if (ParseVec3Att("color", tempv3)) - inNode.SetColor(tempv3); - - if (m_Editor) { - const char8_t *desc; - if (m_Reader.UnregisteredAtt("description", desc, GetStudioStateNamespace())) - m_Editor->ToEditor(inNode)->SetPropertyValue("description", - eastl::string(nonNull(desc))); - } - } - - // Parse the node id. IF it exists, then schedule the id for remapping. - template - void ParseNodeId(TDataType &inNode) - { - m_Reader.Att("id", inNode.m_Id); - if (inNode.m_Id.IsValid() == false || m_Context.ContainsId(inNode.m_Id)) { - m_GenerateIdList.push_back(&inNode); - } else { - bool success = m_Context.InsertId(inNode.m_Id, &inNode); - (void)success; - QT3DS_ASSERT(success); - } - } - - SParam &ParseParam() - { - IDOMReader::Scope _itemScope(m_Reader); - SParam *retval = QT3DS_NEW(m_GraphAllocator, SParam)(); - ParseStrAtt("name", retval->m_Name); - ParseStrAtt("expr", retval->m_Expr); - ParseStrAtt("location", retval->m_Location); - ParseExtensionAttributes(retval); - ParseExtensionElements(retval); - return *retval; - } - - SContent &ParseContent() - { - IDOMReader::Scope _itemScope(m_Reader); - SContent *retval = QT3DS_NEW(m_GraphAllocator, SContent)(); - ParseStrAtt("expr", retval->m_Expr); - if (isTrivial(retval->m_Expr)) { - if (m_Reader.CountChildren() == 0) { - const char8_t *val = NULL; - m_Reader.Value(val); - if (!isTrivial(val)) - retval->m_ContentValue = this->ToGraphStr(val); - } - // We don't implement any extensions, so this is most certainly going into the - // extensions bin for this content. - else { - } - } - ParseExtensionAttributes(retval); - ParseExtensionElements(retval); - return *retval; - } - - SExecutableContent &ParseSend() - { - IDOMReader::Scope _itemScope(m_Reader); - SSend *retval = QT3DS_NEW(m_GraphAllocator, SSend)(); - ParseStrAtt("event", retval->m_Event); - ParseStrAtt("eventexpr", retval->m_EventExpr); - ParseStrAtt("target", retval->m_Target); - ParseStrAtt("targetexpr", retval->m_TargetExpr); - ParseStrAtt("type", retval->m_Type); - ParseStrAtt("typeExpr", retval->m_TypeExpr); - ParseNodeId(*retval); - ParseStrAtt("idlocation", retval->m_IdLocation); - ParseStrAtt("delay", retval->m_Delay); - ParseStrAtt("delayexpr", retval->m_DelayExpr); - ParseStrAtt("namelist", retval->m_NameList); - ParseExtensionAttributes(retval); - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (eq(elemName, SXMLName::eparam)) - AppendChild(NULL, retval, retval->m_Children, ParseParam()); - else if (eq(elemName, SXMLName::econtent)) - retval->m_Children.push_back(ParseContent()); - else { - if (!ParseExtensionElement(retval)) { - qCCritical(INTERNAL_ERROR, "Failed to parse send child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - } - m_Context.AddSendToList(*retval); - return *retval; - } - SExecutableContent &ParseIf() - { - IDOMReader::Scope _itemScope(m_Reader); - SIf *retval = QT3DS_NEW(m_GraphAllocator, SIf)(); - ParseStrAtt("cond", retval->m_Cond); - ParseExtensionAttributes(retval); - ParseExecutableContent(NULL, retval, retval->m_Children, retval); - return *retval; - } - - SExecutableContent &ParseElseIf() - { - IDOMReader::Scope _itemScope(m_Reader); - SElseIf *retval = QT3DS_NEW(m_GraphAllocator, SElseIf)(); - ParseStrAtt("cond", retval->m_Cond); - ParseExtensionAttributes(retval); - ParseExecutableContent(NULL, retval, retval->m_Children, retval); - return *retval; - } - - SExecutableContent &ParseElse() - { - IDOMReader::Scope _itemScope(m_Reader); - SElse *retval = QT3DS_NEW(m_GraphAllocator, SElse)(); - ParseExtensionAttributes(retval); - ParseExecutableContent(NULL, retval, retval->m_Children, retval); - return *retval; - } - SExecutableContent &ParseForEach() - { - IDOMReader::Scope _itemScope(m_Reader); - SForeach *retval = QT3DS_NEW(m_GraphAllocator, SForeach)(); - ParseStrAtt("array", retval->m_Array); - ParseStrAtt("item", retval->m_Item); - ParseStrAtt("index", retval->m_Index); - ParseExtensionAttributes(retval); - ParseExecutableContent(NULL, retval, retval->m_Children, retval); - return *retval; - } - - SExecutableContent &ParseRaise() - { - IDOMReader::Scope _itemScope(m_Reader); - SRaise *retval = QT3DS_NEW(m_GraphAllocator, SRaise)(); - ParseStrAtt("event", retval->m_Event); - ParseExtensionAttributes(retval); - ParseExtensionElements(retval); - return *retval; - } - - SExecutableContent &ParseLog() - { - IDOMReader::Scope _itemScope(m_Reader); - SLog *retval = QT3DS_NEW(m_GraphAllocator, SLog)(); - ParseStrAtt("label", retval->m_Label); - ParseStrAtt("expr", retval->m_Expression); - ParseExtensionAttributes(retval); - ParseExtensionElements(retval); - return *retval; - } - - SData &ParseData() - { - IDOMReader::Scope _itemScope(m_Reader); - SData *retval = QT3DS_NEW(m_GraphAllocator, SData)(); - ParseStrAtt("id", retval->m_Id); - ParseStrAtt("src", retval->m_Source); - ParseStrAtt("expr", retval->m_Expression); - ParseEditorAttributes(*retval); - ParseExtensionElements(retval); - const char8_t *value; - m_Reader.Value(value); - // Not handling arbitrary content under data right now. - if (isTrivial(retval->m_Expression) && !isTrivial(value)) { - retval->m_Expression = ToGraphStr(value); - } - return *retval; - } - - SDataModel *ParseDataModel() - { - IDOMReader::Scope _itemScope(m_Reader); - SDataModel *retval = QT3DS_NEW(m_GraphAllocator, SDataModel)(); - ParseStrAtt("id", retval->m_Id); - ParseStrAtt("src", retval->m_Source); - ParseStrAtt("expr", retval->m_Expression); - ParseEditorAttributes(*retval); - for (bool success = m_Reader.MoveToFirstChild("data"); success; - success = m_Reader.MoveToNextSibling("data")) - retval->m_Data.push_back(ParseData()); - - ParseExtensionElements(retval); - - return retval; - } - - SExecutableContent &ParseAssign() - { - IDOMReader::Scope _itemScope(m_Reader); - SAssign *retval = QT3DS_NEW(m_GraphAllocator, SAssign)(); - ParseStrAtt("location", retval->m_Location); - ParseStrAtt("expr", retval->m_Expression); - ParseExtensionAttributes(retval); - ParseExtensionElements(retval); - // Not dealing with children. - return *retval; - } - - SExecutableContent &ParseScript() - { - IDOMReader::Scope _itemScope(m_Reader); - SScript *retval = QT3DS_NEW(m_GraphAllocator, SScript)(); - ParseStrAtt("src", retval->m_URL); - ParseExtensionAttributes(retval); - if (m_Reader.Value(retval->m_Data)) - retval->m_Data = ToGraphStr(retval->m_Data); - ParseExtensionElements(retval); - return *retval; - } - - SExecutableContent &ParseCancel() - { - IDOMReader::Scope _itemScope(m_Reader); - SCancel *retval = QT3DS_NEW(m_GraphAllocator, SCancel)(); - const char8_t *sendId; - if (m_Reader.UnregisteredAtt("sendid", sendId)) - m_SendReferences.push_back(eastl::make_pair(sendId, &retval->m_Send)); - ParseStrAtt("sendidexpr", retval->m_IdExpression); - ParseExtensionAttributes(retval); - ParseExtensionElements(retval); - return *retval; - } - struct SExecutableContentParseBinding - { - SXMLName::Enum m_Name; - typedef SExecutableContent &(SParseContext::*TParseFunc)(); - TParseFunc m_ParseFunc; - }; - - static NVDataRef GetParseBindings() - { - static SExecutableContentParseBinding s_ExecContentParseBindings[10] = { - { SXMLName::esend, &SParseContext::ParseSend }, - { SXMLName::eif, &SParseContext::ParseIf }, - { SXMLName::eelseif, &SParseContext::ParseElseIf }, - { SXMLName::eelse, &SParseContext::ParseElse }, - { SXMLName::eforeach, &SParseContext::ParseForEach }, - { SXMLName::eraise, &SParseContext::ParseRaise }, - { SXMLName::elog, &SParseContext::ParseLog }, - { SXMLName::eassign, &SParseContext::ParseAssign }, - { SXMLName::escript, &SParseContext::ParseScript }, - { SXMLName::ecancel, &SParseContext::ParseCancel }, - }; - - return toDataRef(s_ExecContentParseBindings, 10); - } - - bool ParseExecutableContentItem(SStateNode *inNodeParent, SExecutableContent *inParent, - TExecutableContentList &outContent) - { - CRegisteredString elemName = m_Reader.GetElementName(); - NVDataRef theBindingList(GetParseBindings()); - for (QT3DSU32 idx = 0, end = theBindingList.size(); idx < end; ++idx) { - SExecutableContentParseBinding theBinding(theBindingList[idx]); - if (eq(elemName, theBinding.m_Name)) { - AppendChild(inNodeParent, inParent, outContent, (this->*theBinding.m_ParseFunc)()); - return true; - } - } - return false; - } - - void ParseExecutableContent(SStateNode *inStateNodeParent, SExecutableContent *inParent, - TExecutableContentList &outContent, void *inExtensionPtr) - { - IDOMReader::Scope _itemScope(m_Reader); - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (!ParseExecutableContentItem(inStateNodeParent, inParent, outContent)) { - if (!ParseExtensionElement(inExtensionPtr)) { - qCCritical(INTERNAL_ERROR, "Failed to parse extension child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - } - } - - SOnEntry &ParseOnEntry(SStateNode &inParent) - { - IDOMReader::Scope _itemScope(m_Reader); - SOnEntry *retval = QT3DS_NEW(m_GraphAllocator, SOnEntry)(); - ParseExecutableContent(&inParent, NULL, retval->m_ExecutableContent, retval); - return *retval; - } - - SOnExit &ParseOnExit(SStateNode &inParent) - { - IDOMReader::Scope _itemScope(m_Reader); - SOnExit *retval = QT3DS_NEW(m_GraphAllocator, SOnExit)(); - ParseExecutableContent(&inParent, NULL, retval->m_ExecutableContent, retval); - return *retval; - } - - SHistory &ParseHistory() - { - IDOMReader::Scope _itemScope(m_Reader); - SHistory *retval = QT3DS_NEW(m_GraphAllocator, SHistory)(); - ParseNodeId(*retval); - const char8_t *temp; - if (m_Reader.UnregisteredAtt("type", temp) && AreEqual(temp, "deep")) - retval->m_Flags.SetDeep(true); - ParseStateNodeEditorAttributes(*retval); - if (m_Reader.MoveToFirstChild("transition")) { - retval->m_Transition = &ParseTransition(); - retval->m_Transition->m_Parent = retval; - } - ParseExtensionElements(retval); - return *retval; - } - - STransition &ParseTransition() - { - IDOMReader::Scope _itemScope(m_Reader); - STransition *retval = QT3DS_NEW(m_GraphAllocator, STransition)(); - m_Reader.Att("event", retval->m_Event); - ParseNodeId(*retval); - const char8_t *temp; - if (m_Reader.UnregisteredAtt("target", temp)) { - ParseIDRef(temp, retval->m_Target); - } - if (m_Reader.UnregisteredAtt("type", temp) && AreEqual(temp, "internal")) - retval->m_Flags.SetInternal(true); - ParseStateNodeEditorAttributes(*retval); - - retval->m_Condition = ParseStrAtt("cond"); - // Position and such is only valid for transitions after UIC version 0. - if (m_Version > 0) { - QT3DSVec2 endPos; - if (ParseVec2Att("end_position", endPos)) - retval->SetEndPosition(endPos); - - if (m_Reader.UnregisteredAtt("path", temp)) { - NVConstDataRef pathData = ParseFloats(temp); - QT3DS_ASSERT((pathData.size() % 2) == 0); - size_t newDataSize = pathData.size() * sizeof(QT3DSF32); - QT3DSVec2 *newData = (QT3DSVec2 *)m_GraphAllocator.allocate( - newDataSize, "STransition::m_Path", __FILE__, __LINE__); - memCopy(newData, pathData.begin(), (QT3DSU32)newDataSize); - retval->m_Path = toDataRef(newData, (QT3DSU32)(newDataSize / sizeof(QT3DSVec2))); - } - } else { - retval->SetPosition(Empty()); - } - - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (!ParseExecutableContentItem(retval, NULL, retval->m_ExecutableContent)) { - if (!ParseExtensionElement(retval)) { - qCCritical(INTERNAL_ERROR, "Failed to parse transition child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - } - return *retval; - } - - SFinal &ParseFinal() - { - IDOMReader::Scope _itemScope(m_Reader); - SFinal *retval = QT3DS_NEW(m_GraphAllocator, SFinal)(); - - ParseNodeId(*retval); - ParseStateNodeEditorAttributes(*retval); - - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (eq(elemName, SXMLName::eonentry)) - retval->m_OnEntry.push_back(ParseOnEntry(*retval)); - else if (eq(elemName, SXMLName::eonexit)) - retval->m_OnExit.push_back(ParseOnExit(*retval)); - else if (!ParseExtensionElement(retval)) { - qCCritical(INTERNAL_ERROR, "Failed to parse final child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - return *retval; - } - - bool ParseStateParallelChildren(SStateNode &inParent, CRegisteredString &inElemName, - TStateNodeList &outChildren, TOnEntryList &inOnEntry, - TOnExitList &inOnExit, SDataModel *&dmPtr) - { - if (eq(inElemName, SXMLName::estate)) - AppendChild(inParent, outChildren, ParseState()); - else if (eq(inElemName, SXMLName::etransition)) - AppendChild(inParent, outChildren, ParseTransition()); - else if (eq(inElemName, SXMLName::eparallel)) - AppendChild(inParent, outChildren, ParseParallel()); - else if (eq(inElemName, SXMLName::eonentry)) - inOnEntry.push_back(ParseOnEntry(inParent)); - else if (eq(inElemName, SXMLName::eonexit)) - inOnExit.push_back(ParseOnExit(inParent)); - else if (eq(inElemName, SXMLName::ehistory)) - AppendChild(inParent, outChildren, ParseHistory()); - else if (eq(inElemName, SXMLName::efinal)) - AppendChild(inParent, outChildren, ParseFinal()); - else if (eq(inElemName, SXMLName::edatamodel)) - dmPtr = ParseDataModel(); - else { - return false; - } - return true; - } - - SStateNode &ParseParallel() - { - IDOMReader::Scope _itemScope(m_Reader); - SParallel *retval = QT3DS_NEW(m_GraphAllocator, SParallel)(); - ParseNodeId(*retval); - ParseStateNodeEditorAttributes(*retval); - - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (!ParseStateParallelChildren(*retval, elemName, retval->m_Children, - retval->m_OnEntry, retval->m_OnExit, - retval->m_DataModel)) { - if (!ParseExtensionElement(retval)) { - qCCritical(INTERNAL_ERROR, "Failed to parse parallel child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - } - return *retval; - } - - void SetStateInitialTransition(STransition *&ioInitial, TStateNodeList &inChildren, - SStateNode &inSource) - { - if (ioInitial) { - ioInitial->m_Parent = &inSource; - return; - } - SStateNode *firstStateChild = NULL; - for (TStateNodeList::iterator iter = inChildren.begin(); - iter != inChildren.end() && firstStateChild == NULL; ++iter) { - if (iter->m_Type == StateNodeTypes::State || iter->m_Type == StateNodeTypes::Parallel - || iter->m_Type == StateNodeTypes::Final) { - firstStateChild = &(*iter); - } - } - - if (firstStateChild) { - STransition *theTransition = QT3DS_NEW(m_GraphAllocator, STransition)(); - size_t byteSize = sizeof(SStateNode *); - SStateNode **theData = (SStateNode **)m_GraphAllocator.allocate( - byteSize, "InitialTransition", __FILE__, __LINE__); - *theData = firstStateChild; - theTransition->m_Target = toDataRef(theData, 1); - theTransition->m_Parent = &inSource; - ioInitial = theTransition; - } - } - - STransition *ParseInitial() - { - if (m_Reader.MoveToFirstChild("transition")) - return &ParseTransition(); - else { - QT3DS_ASSERT(false); - } - return NULL; - } - - SStateNode &ParseState() - { - IDOMReader::Scope _stateScope(m_Reader); - SState *theNewState = QT3DS_NEW(m_GraphAllocator, SState)(); - ParseNodeId(*theNewState); - const char8_t *initialAtt; - if (m_Reader.UnregisteredAtt("initialexpr", initialAtt, GetStudioStateNamespace())) { - theNewState->m_InitialExpr = ToGraphStr(initialAtt); - const char8_t *errorTest; - if (m_Reader.UnregisteredAtt("initial", errorTest)) { - qCCritical(INVALID_OPERATION, "Attribute initial=\"%s\" conflicts with " - "attribute initialexpr=\"%s\" on ; using initialexpr.", - nonNull(errorTest), nonNull(initialAtt), - nonNull(theNewState->m_Id.c_str())); - } - } else if (m_Reader.UnregisteredAtt("initial", initialAtt) && !isTrivial(initialAtt)) { - STransition *theTransition = QT3DS_NEW(m_GraphAllocator, STransition)(); - ParseIDRef(initialAtt, theTransition->m_Target); - theTransition->m_Parent = theNewState; - theNewState->m_Initial = theTransition; - } - - ParseStateNodeEditorAttributes(*theNewState); - - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (!ParseStateParallelChildren(*theNewState, elemName, theNewState->m_Children, - theNewState->m_OnEntry, theNewState->m_OnExit, - theNewState->m_DataModel)) { - // InitialExpr takes precedence over initial transition - if (eq(elemName, SXMLName::einitial) && isTrivial(theNewState->m_InitialExpr)) { - if (!theNewState->m_Initial) - theNewState->m_Initial = ParseInitial(); - } else { - if (!ParseExtensionElement(theNewState)) { - qCCritical(INTERNAL_ERROR, "Failed to parse state child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - } - } - if (isTrivial(theNewState->m_InitialExpr)) - SetStateInitialTransition(theNewState->m_Initial, theNewState->m_Children, - *theNewState); - return *theNewState; - } - - static const char8_t *GetDefaultIdName(SStateNode &theNode) - { - const char8_t *theTemp = "id"; - switch (theNode.m_Type) { - case StateNodeTypes::State: - theTemp = "state"; - break; - case StateNodeTypes::Parallel: - theTemp = "parallel"; - break; - case StateNodeTypes::Final: - theTemp = "final"; - break; - case StateNodeTypes::History: - theTemp = "history"; - break; - case StateNodeTypes::Transition: - theTemp = "transition"; - break; - default: - break; - } - return theTemp; - } - - static const char8_t *GetDefaultIdName(SSend &) { return "send"; } - - template - void GenerateIdValue(TDataType &theNode) - { - if (theNode.m_Id.IsValid() == true) { - bool preexisting = m_Context.ContainsId(theNode.m_Id); - if (preexisting) { - CRegisteredString oldId = theNode.m_Id; - theNode.m_Id = CRegisteredString(); - CXMLIO::GenerateUniqueId(theNode, oldId.c_str(), m_Context, m_StrTable); - bool success = m_RemapMap.insert(eastl::make_pair(oldId, theNode.m_Id)).second; - (void)success; - QT3DS_ASSERT(success); - } - } else { - CXMLIO::GenerateUniqueId(theNode, GetDefaultIdName(theNode), m_Context, m_StrTable); - } - } - - void FinishParsing() - { - for (QT3DSU32 idx = 0, end = m_GenerateIdList.size(); idx < end; ++idx) { - SIdValue &theNode(m_GenerateIdList[idx]); - switch (theNode.getType()) { - case IdValueTypes::StateNode: - GenerateIdValue(*(theNode.getData())); - break; - case IdValueTypes::Send: - GenerateIdValue(*(theNode.getData())); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - for (QT3DSU32 idx = 0, end = m_References.size(); idx < end; ++idx) - *(m_References[idx].second) = ParseIDRefSecondPass(m_References[idx].first); - - for (QT3DSU32 idx = 0, end = m_SendReferences.size(); idx < end; ++idx) - *(m_SendReferences[idx].second) = ParseSendIdSecondPass(m_SendReferences[idx].first); - - if (m_Editor) { - for (QT3DSU32 idx = 0, end = m_ExternalTransitions.size(); idx < end; ++idx) { - SStateNode *theNode = FindStateNode(m_ExternalTransitions[idx].first); - if (theNode) { - TObjPtr transObj = m_Editor->GetOrCreate(*m_ExternalTransitions[idx].second); - TObjPtr stateObj = m_Editor->ToEditor(*theNode); - stateObj->Append("children", transObj); - } - } - } - } - SSCXML &ParseSCXML() - { - IDOMReader::Scope _stateScope(m_Reader); - SSCXML *retval = QT3DS_NEW(m_GraphAllocator, SSCXML)(); - - if (m_Reader.Att("id", retval->m_Id)) - m_Context.InsertId(retval->m_Id, retval); - const char8_t *initial; - if (m_Reader.UnregisteredAtt("initialexpr", initial, GetStudioStateNamespace())) { - retval->m_InitialExpr = ToGraphStr(initial); - } else if (m_Reader.UnregisteredAtt("initial", initial)) { - STransition *theTransition = QT3DS_NEW(m_GraphAllocator, STransition)(); - ParseIDRef(initial, theTransition->m_Target); - theTransition->m_Parent = retval; - retval->m_Initial = theTransition; - } - ParseStrAtt("name", retval->m_Name); - const char8_t *uicVersion; - if (!m_Reader.UnregisteredAtt("version", uicVersion, GetStudioStateNamespace())) - retval->m_Version = 0; - else { - StringConversion().StrTo(uicVersion, retval->m_Version); - } - m_Version = retval->m_Version; - const char8_t *desc; - if (m_Editor && m_Reader.UnregisteredAtt("description", desc)) - m_Editor->GetOrCreate(*retval)->SetPropertyValue("description", desc); - - const char8_t *temp; - if (m_Reader.UnregisteredAtt("binding", temp) && AreEqual(temp, "late")) - retval->m_Flags.SetLateBinding(true); - - ParseExtensionAttributes(retval); - - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (eq(elemName, SXMLName::estate)) - AppendChild(*retval, retval->m_Children, ParseState()); - else if (eq(elemName, SXMLName::eparallel)) - AppendChild(*retval, retval->m_Children, ParseParallel()); - else if (eq(elemName, SXMLName::etransition)) - AppendChild(*retval, retval->m_Children, ParseTransition()); - else if (eq(elemName, SXMLName::efinal)) - AppendChild(*retval, retval->m_Children, ParseFinal()); - else if (eq(elemName, SXMLName::einitial)) - retval->m_Initial = ParseInitial(); - else if (eq(elemName, SXMLName::edatamodel)) - retval->m_DataModel = ParseDataModel(); - else { - if (!ParseExtensionElement(retval)) { - qCCritical(INTERNAL_ERROR, "Failed to parse scxml child %s", elemName.c_str()); - QT3DS_ASSERT(false); - } - } - } - if (isTrivial(retval->m_InitialExpr)) { - SetStateInitialTransition(retval->m_Initial, retval->m_Children, *retval); - } - FinishParsing(); - return *retval; - } - eastl::vector ParseFragment() - { - eastl::vector retval; - - for (bool success = m_Reader.MoveToFirstChild(); success; - success = m_Reader.MoveToNextSibling()) { - IDOMReader::Scope _loopScope(m_Reader); - CRegisteredString elemName = m_Reader.GetElementName(); - if (eq(elemName, SXMLName::estate)) - retval.push_back(&ParseState()); - else if (eq(elemName, SXMLName::eparallel)) - retval.push_back(&ParseParallel()); - else if (eq(elemName, SXMLName::efinal)) - retval.push_back(&ParseFinal()); - else if (eq(elemName, SXMLName::ehistory)) - retval.push_back(&ParseHistory()); - else if (eq(elemName, SXMLName::eexternal_transition)) { - CRegisteredString src; - m_Reader.Att("source", src); - if (src.IsValid()) - m_ExternalTransitions.push_back(eastl::make_pair(src, &ParseTransition())); - } else { - qCCritical(INTERNAL_ERROR, "Failed to parse scxml child %s", elemName.c_str() ); - QT3DS_ASSERT(false); - } - } - - FinishParsing(); - return retval; - } -}; - -struct SWriteContext -{ - IDOMWriter &m_Writer; - IStateContext &m_Context; - IStringTable &m_StringTable; - const char8_t *m_CurrentNamespace; - const char8_t *m_Names[SXMLName::LastName]; - eastl::string m_IdStr; - eastl::string m_RefListWorkspace; - IEditor *m_Editor; - MemoryBuffer m_Buffer; - Option m_MousePos; - nvvector m_WrittenNodes; - nvvector m_ExternalTransitions; - - SWriteContext(IDOMWriter &inWriter, IStateContext &inContext, IStringTable &inStrTable, - IEditor *inEditor, NVAllocatorCallback &inAlloc) - : m_Writer(inWriter) - , m_Context(inContext) - , m_StringTable(inStrTable) - , m_CurrentNamespace(GetSCXMLNamespace()) - , m_Editor(inEditor) - , m_Buffer(ForwardingAllocator(inAlloc, "WriteBuffer")) - , m_WrittenNodes(inAlloc, "m_WrittenNodes") - , m_ExternalTransitions(inAlloc, "m_ExternalTransitions") - { -#define HANDLE_XML_ELEMENT_NAME(nm) m_Names[SXMLName::e##nm] = #nm; - ITERATE_XML_ELEMENT_NAMES -#undef HANDLE_XML_ELEMENT_NAME - } - - void GenerateId(SStateNode &inNode, const char8_t *stem) - { - if (inNode.m_Id.IsValid() == false) - CXMLIO::GenerateUniqueId(inNode, stem, m_Context, m_StringTable); - } - - void WriteExtensionElement(SDOMElement &elem) - { - IDOMWriter::Scope _elemScope(m_Writer, elem.m_Name.c_str(), elem.m_Namespace.c_str()); - for (TAttributeList::iterator iter = elem.m_Attributes.begin(), - end = elem.m_Attributes.end(); - iter != end; ++iter) { - SDOMAttribute &theAttribute(*iter); - m_Writer.Att(theAttribute.m_Name, theAttribute.m_Value, - theAttribute.m_Namespace.c_str()); - } - for (SDOMElement::TElementChildList::iterator iter = elem.m_Children.begin(), - end = elem.m_Children.end(); - iter != end; ++iter) { - WriteExtensionElement(elem); - } - if (!isTrivial(elem.m_Value)) { - m_Writer.Value(elem.m_Value); - } - } - - void WriteExtensionData(void *inItem) - { - SItemExtensionInfo *infoPtr = m_Context.GetExtensionInfo(inItem); - if (infoPtr) { - SItemExtensionInfo &theInfo(*infoPtr); - for (TDOMAttributeNodeList::iterator iter = theInfo.m_ExtensionAttributes.begin(), - end = theInfo.m_ExtensionAttributes.end(); - iter != end; ++iter) { - SDOMAttribute &theAttribute(*iter->m_Attribute); - m_Writer.Att(theAttribute.m_Name.c_str(), theAttribute.m_Value, - theAttribute.m_Namespace.c_str()); - } - for (TDOMElementNodeList::iterator iter = theInfo.m_ExtensionNodes.begin(), - end = theInfo.m_ExtensionNodes.end(); - iter != end; ++iter) { - WriteExtensionElement(*iter->m_Element); - } - } - } - - void Att(const char8_t *inName, const char8_t *inData) - { - if (!isTrivial(inData)) - m_Writer.Att(inName, inData, m_CurrentNamespace); - } - - void Att(const char8_t *inName, CRegisteredString inData) - { - if (inData.IsValid()) - m_Writer.Att(inName, inData.c_str(), m_CurrentNamespace); - } - - void Att(const char8_t *inName, NVConstDataRef inData) - { - m_RefListWorkspace.clear(); - for (QT3DSU32 idx = 0, end = inData.size(); idx < end; ++idx) { - if (m_RefListWorkspace.size()) - m_RefListWorkspace.append(" "); - m_RefListWorkspace.append(inData[idx].c_str()); - } - if (m_RefListWorkspace.size()) - Att(inName, m_RefListWorkspace.c_str()); - } - void Att(const char8_t *inName, NVConstDataRef inData) - { - m_RefListWorkspace.clear(); - for (QT3DSU32 idx = 0, end = inData.size(); idx < end; ++idx) { - if (m_RefListWorkspace.size()) - m_RefListWorkspace.append(" "); - if (inData[idx]) - m_RefListWorkspace.append(inData[idx]->m_Id.c_str()); - } - if (m_RefListWorkspace.size()) - Att(inName, m_RefListWorkspace.c_str()); - } - void Att(const char8_t *inName, const QT3DSVec2 &inData) - { - m_Buffer.clear(); - Char8TWriter writer(m_Buffer); - writer.Write(NVConstDataRef(&inData.x, 2)); - m_Buffer.writeZeros(1); - m_Writer.Att(inName, (const char8_t *)m_Buffer.begin(), GetStudioStateNamespace()); - } - - void Att(const char8_t *inName, const QT3DSVec3 &inData) - { - m_Buffer.clear(); - Char8TWriter writer(m_Buffer); - writer.Write(NVConstDataRef(&inData.x, 3)); - m_Buffer.writeZeros(1); - m_Writer.Att(inName, (const char8_t *)m_Buffer.begin(), GetStudioStateNamespace()); - } - - void WriteEditorAttributes(void *inType, bool idId, bool inAdjustPos = false) - { - if (m_Editor) { - TObjPtr editorObj = m_Editor->GetEditor(inType); - if (editorObj != NULL) { - if (idId) { - eastl::string name = editorObj->GetId(); - if (name.empty() == false) - m_Writer.Att("id", name.c_str(), GetStudioStateNamespace()); - } - eastl::string description = editorObj->GetDescription(); - if (description.empty() == false) - m_Writer.Att("description", description.c_str(), GetStudioStateNamespace()); - - Option tempData = editorObj->GetPropertyValue("position"); - if (tempData.hasValue()) { - QT3DSVec2 thePos(tempData->getData()); - if (inAdjustPos && m_MousePos.hasValue()) { - // Get the global pos, not the local position. - for (TObjPtr parentPtr = editorObj->Parent(); parentPtr; - parentPtr = parentPtr->Parent()) { - Option parentPos = parentPtr->GetPropertyValue("position"); - if (parentPos.hasValue()) - thePos += parentPos->getData(); - } - // Store pos in global coords adjusted. - thePos -= *m_MousePos; - } - Att("position", thePos); - } - - tempData = editorObj->GetPropertyValue("dimension"); - if (tempData.hasValue()) - Att("dimension", tempData->getData()); - - tempData = editorObj->GetPropertyValue("color"); - if (tempData.hasValue()) - Att("color", tempData->getData()); - } - } - } - - void WriteSend(SSend &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "send", m_CurrentNamespace); - Att("event", inContent.m_Event); - Att("eventexpr", inContent.m_EventExpr); - Att("target", inContent.m_Target); - Att("targetexpr", inContent.m_TargetExpr); - Att("type", inContent.m_Type); - Att("typeExpr", inContent.m_TypeExpr); - Att("id", inContent.m_Id); - Att("idlocation", inContent.m_IdLocation); - Att("delay", inContent.m_Delay); - Att("delayexpr", inContent.m_DelayExpr); - Att("namelist", inContent.m_NameList); - WriteExecutableContentList(inContent.m_Children); - WriteEditorAttributes(&inContent, false); - WriteExtensionData(&inContent); - } - - void WriteParam(SParam &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "param", m_CurrentNamespace); - Att("name", inContent.m_Name); - - if (!isTrivial(inContent.m_Expr)) - Att("expr", inContent.m_Expr); - else if (!isTrivial(inContent.m_Location)) - Att("location", inContent.m_Location); - - WriteEditorAttributes(&inContent, false); - WriteExtensionData(&inContent); - } - - void WriteContent(SContent &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "content", m_CurrentNamespace); - if (!isTrivial(inContent.m_Expr)) - Att("expr", inContent.m_Expr); - else if (!isTrivial(inContent.m_ContentValue)) - m_Writer.Value(inContent.m_ContentValue); - - WriteEditorAttributes(&inContent, false); - WriteExtensionData(&inContent); - } - - void WriteRaise(SRaise &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "raise", m_CurrentNamespace); - Att("event", inContent.m_Event); - WriteEditorAttributes(&inContent, false); - WriteExtensionData(&inContent); - } - - void WriteAssign(SAssign &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "assign", m_CurrentNamespace); - Att("location", inContent.m_Location); - Att("expr", inContent.m_Expression); - WriteEditorAttributes(&inContent, false); - WriteExtensionData(&inContent); - } - - void WriteIf(SIf &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "if", m_CurrentNamespace); - Att("cond", inContent.m_Cond); - WriteEditorAttributes(&inContent, false); - WriteExecutableContentList(inContent.m_Children); - WriteExtensionData(&inContent); - } - - void WriteElseIf(SElseIf &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "elseif", m_CurrentNamespace); - WriteEditorAttributes(&inContent, false); - Att("cond", inContent.m_Cond); - WriteExtensionData(&inContent); - } - - void WriteElse(SElse &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "else", m_CurrentNamespace); - WriteEditorAttributes(&inContent, false); - WriteExtensionData(&inContent); - } - - void WriteLog(SLog &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "log", m_CurrentNamespace); - WriteEditorAttributes(&inContent, false); - Att("label", inContent.m_Label); - Att("expr", inContent.m_Expression); - WriteExtensionData(&inContent); - } - - void WriteScript(SScript &inContent) - { - IDOMWriter::Scope _itemScope(m_Writer, "script", m_CurrentNamespace); - WriteEditorAttributes(&inContent, false); - if (isTrivial(inContent.m_Data) && !isTrivial(inContent.m_URL)) - Att("src", inContent.m_URL); - else - m_Writer.Value(inContent.m_Data); - WriteExtensionData(&inContent); - } - - void WriteCancel(SCancel &inContent) - { - // Do not serialize invalid cancel items. - if (isTrivial(inContent.m_IdExpression) && inContent.m_Send == NULL) - return; - - IDOMWriter::Scope _itemScope(m_Writer, "cancel", m_CurrentNamespace); - if (!inContent.m_Send && inContent.m_IdExpression) - Att("sendidexpr", inContent.m_IdExpression); - else - Att("sendid", inContent.m_Send->m_Id); - - WriteEditorAttributes(&inContent, true); - WriteExtensionData(&inContent); - } - - void WriteExecutableContent(SExecutableContent &inContent) - { - switch (inContent.m_Type) { - case ExecutableContentTypes::Send: - WriteSend(static_cast(inContent)); - break; - case ExecutableContentTypes::Raise: - WriteRaise(static_cast(inContent)); - break; - case ExecutableContentTypes::Assign: - WriteAssign(static_cast(inContent)); - break; - case ExecutableContentTypes::If: - WriteIf(static_cast(inContent)); - break; - case ExecutableContentTypes::ElseIf: - WriteElseIf(static_cast(inContent)); - break; - case ExecutableContentTypes::Else: - WriteElse(static_cast(inContent)); - break; - case ExecutableContentTypes::Log: - WriteLog(static_cast(inContent)); - break; - case ExecutableContentTypes::Script: - WriteScript(static_cast(inContent)); - break; - case ExecutableContentTypes::Cancel: - WriteCancel(static_cast(inContent)); - break; - case ExecutableContentTypes::Param: - WriteParam(static_cast(inContent)); - break; - case ExecutableContentTypes::Content: - WriteContent(static_cast(inContent)); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - void WriteExecutableContentList(TExecutableContentList &inList) - { - for (TExecutableContentList::iterator contentIter = inList.begin(), - contentEnd = inList.end(); - contentIter != contentEnd; ++contentIter) - WriteExecutableContent(*contentIter); - } - - void WriteOnEntry(SOnEntry &inItem) - { - IDOMWriter::Scope _itemScope(m_Writer, "onentry", m_CurrentNamespace); - WriteEditorAttributes(&inItem, true); - WriteExecutableContentList(inItem.m_ExecutableContent); - WriteExtensionData(&inItem); - } - - void WriteOnEntryList(TOnEntryList &inList) - { - for (TOnEntryList::iterator iter = inList.begin(), end = inList.end(); iter != end; ++iter) - WriteOnEntry(*iter); - } - - void WriteOnExit(SOnExit &inItem) - { - IDOMWriter::Scope _itemScope(m_Writer, "onexit", m_CurrentNamespace); - WriteEditorAttributes(&inItem, true); - WriteExecutableContentList(inItem.m_ExecutableContent); - WriteExtensionData(&inItem); - } - - void WriteOnExitList(TOnExitList &inList) - { - for (TOnExitList::iterator iter = inList.begin(), end = inList.end(); iter != end; ++iter) - WriteOnExit(*iter); - } - - void WriteDataModel(SDataModel &inDataModel) - { - IDOMWriter::Scope _transitionScope(m_Writer, "datamodel", m_CurrentNamespace); - WriteEditorAttributes(&inDataModel, true); - for (TDataList::iterator iter = inDataModel.m_Data.begin(), end = inDataModel.m_Data.end(); - iter != end; ++iter) { - IDOMWriter::Scope _transitionScope(m_Writer, "data", m_CurrentNamespace); - Att("id", iter->m_Id); - Att("expr", iter->m_Expression); - WriteEditorAttributes(&(*iter), true); - WriteExtensionData(&(*iter)); - } - WriteExtensionData(&inDataModel); - } - - static inline SStateNode *FirstValidChild(SState &inNode) - { - for (TStateNodeList::iterator iter = inNode.m_Children.begin(), - end = inNode.m_Children.end(); - iter != end; ++iter) { - switch (iter->m_Type) { - case StateNodeTypes::State: - case StateNodeTypes::Parallel: - case StateNodeTypes::Final: - return iter.m_Obj; - default: - break; - } - } - return NULL; - } - - void WriteState(SState &inNode, bool inAdjustPos) - { - m_WrittenNodes.push_back(&inNode); - IDOMWriter::Scope _transitionScope(m_Writer, "state", m_CurrentNamespace); - GenerateId(inNode, "state"); - Att("id", inNode.m_Id); - WriteEditorAttributes(&inNode, false, inAdjustPos); - if (!isTrivial(inNode.m_InitialExpr)) { - m_Writer.Att("initialexpr", inNode.m_InitialExpr, GetStudioStateNamespace()); - } else if (inNode.m_Initial) { - // First check to see if this could be an attribute - if (inNode.m_Initial->m_ExecutableContent.empty()) { - // Now check if it has one child and if it has only one child and that child is the - // first valid possible child - // then we don't write out the attribute - bool canElideInitial = inNode.m_Initial->m_Target.size() == 0 - || (inNode.m_Initial->m_Target.size() == 1 - && inNode.m_Initial->m_Target[0] == FirstValidChild(inNode)); - if (!canElideInitial) - Att("initial", inNode.m_Initial->m_Target); - } else { - IDOMWriter::Scope _transitionScope(m_Writer, "initial", m_CurrentNamespace); - WriteTransition(*inNode.m_Initial, false); - } - } - WriteOnEntryList(inNode.m_OnEntry); - WriteOnExitList(inNode.m_OnExit); - WriteStateNodeList(inNode.m_Children); - if (inNode.m_DataModel) - WriteDataModel(*inNode.m_DataModel); - WriteExtensionData(&inNode); - } - - void WriteParallel(SParallel &inNode, bool inAdjustPos) - { - m_WrittenNodes.push_back(&inNode); - IDOMWriter::Scope _transitionScope(m_Writer, "parallel", m_CurrentNamespace); - GenerateId(inNode, "parallel"); - Att("id", inNode.m_Id); - WriteEditorAttributes(&inNode, false, inAdjustPos); - WriteOnEntryList(inNode.m_OnEntry); - WriteOnExitList(inNode.m_OnExit); - WriteStateNodeList(inNode.m_Children); - if (inNode.m_DataModel) - WriteDataModel(*inNode.m_DataModel); - WriteExtensionData(&inNode); - } - - void WriteHistory(SHistory &inNode, bool inAdjustPos) - { - m_WrittenNodes.push_back(&inNode); - IDOMWriter::Scope _transitionScope(m_Writer, "history", m_CurrentNamespace); - GenerateId(inNode, "history"); - Att("id", inNode.m_Id); - if (inNode.m_Flags.IsDeep()) - Att("type", "deep"); - WriteEditorAttributes(&inNode, false, inAdjustPos); - if (inNode.m_Transition) - WriteTransition(*inNode.m_Transition, false); - WriteExtensionData(&inNode); - } - void WriteTransitionData(STransition &inNode) - { - Att("event", inNode.m_Event); - Att("cond", inNode.m_Condition); - Att("target", inNode.m_Target); - if (inNode.m_Flags.IsInternal()) - Att("type", "internal"); - WriteEditorAttributes(&inNode, true, false); - if (inNode.m_StateNodeFlags.HasEndPosition()) { - Att("end_position", inNode.m_EndPosition); - } - if (inNode.m_Path.mSize) { - m_Buffer.clear(); - Char8TWriter writer(m_Buffer); - writer.Write( - NVConstDataRef((const QT3DSF32 *)inNode.m_Path.mData, 2 * inNode.m_Path.mSize), - QT3DS_MAX_U32); - m_Buffer.writeZeros(1); - m_Writer.Att("path", (const char8_t *)m_Buffer.begin(), GetStudioStateNamespace()); - } - WriteExecutableContentList(inNode.m_ExecutableContent); - WriteExtensionData(&inNode); - } - void WriteTransition(STransition &inNode, bool /*inAdjustPos*/) - { - IDOMWriter::Scope _transitionScope(m_Writer, "transition", m_CurrentNamespace); - WriteTransitionData(inNode); - } - void WriteExternalTransition(STransition &inNode) - { - if (inNode.m_Parent != NULL) { - IDOMWriter::Scope _transitionScope(m_Writer, "external_transition", - GetStudioStateNamespace()); - m_Writer.Att("source", inNode.m_Parent->m_Id.c_str(), GetStudioStateNamespace()); - WriteTransitionData(inNode); - } else { - QT3DS_ASSERT(false); - } - } - - void WriteFinal(SFinal &inNode, bool inAdjustPos) - { - m_WrittenNodes.push_back(&inNode); - IDOMWriter::Scope _transitionScope(m_Writer, "final", m_CurrentNamespace); - GenerateId(inNode, "history"); - Att("id", inNode.m_Id); - WriteEditorAttributes(&inNode, false, inAdjustPos); - WriteOnEntryList(inNode.m_OnEntry); - WriteOnExitList(inNode.m_OnExit); - WriteExtensionData(&inNode); - } - - void Write(SStateNode &inNode, bool inAdjustPos) - { - switch (inNode.m_Type) { - case StateNodeTypes::State: - WriteState(static_cast(inNode), inAdjustPos); - break; - case StateNodeTypes::Parallel: - WriteParallel(static_cast(inNode), inAdjustPos); - break; - case StateNodeTypes::History: - WriteHistory(static_cast(inNode), inAdjustPos); - break; - case StateNodeTypes::Transition: - WriteTransition(static_cast(inNode), inAdjustPos); - break; - case StateNodeTypes::Final: - WriteFinal(static_cast(inNode), inAdjustPos); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - void WriteStateNodeList(TStateNodeList &inNodeList) - { - for (TStateNodeList::iterator iter = inNodeList.begin(), end = inNodeList.end(); - iter != end; ++iter) { - Write((*iter), false); - } - } - - void Write() - { - SSCXML &item = *m_Context.GetRoot(); - GenerateId(item, "scxml"); - Att("name", item.m_Name); - if (item.m_Flags.IsLateBinding()) - Att("binding", "late"); - Att("version", "1"); - m_Writer.Att("version", SSCXML::GetCurrentVersion(), GetStudioStateNamespace()); - - if (!isTrivial(item.m_InitialExpr)) { - m_Writer.Att("initialexpr", item.m_InitialExpr, GetStudioStateNamespace()); - } else if (item.m_Initial) - Att("initial", item.m_Initial->m_Target); - - WriteStateNodeList(item.m_Children); - if (item.m_DataModel) - WriteDataModel(*item.m_DataModel); - WriteExtensionData(&item); - } - - void CheckTransitionForWrittenNodesList(STransition *transition) - { - if (transition == NULL) - return; - for (QT3DSU32 targetIdx = 0, targetEnd = transition->m_Target.size(); targetIdx < targetEnd; - ++targetIdx) { - if (eastl::find(m_WrittenNodes.begin(), m_WrittenNodes.end(), - transition->m_Target[targetIdx]) - != m_WrittenNodes.end()) { - m_ExternalTransitions.push_back(transition); - return; - } - } - } - - // Not sure the right answer here. I know you can't just blindly work with initials and such - // because you can't create new transitions for them. - void CheckForExternalTransitions(SStateNode &inNode, const eastl::vector &inRoots) - { - switch (inNode.m_Type) { - case StateNodeTypes::SCXML: { - SSCXML &theNode(static_cast(inNode)); - // CheckTransitionForWrittenNodesList( theNode.m_Initial ); - CheckForExternalTransitions(theNode.m_Children, inRoots); - } break; - case StateNodeTypes::State: { - SState &theNode(static_cast(inNode)); - // CheckTransitionForWrittenNodesList( theNode.m_Initial ); - CheckForExternalTransitions(theNode.m_Children, inRoots); - } break; - case StateNodeTypes::Parallel: { - SParallel &theNode(static_cast(inNode)); - CheckForExternalTransitions(theNode.m_Children, inRoots); - } break; - case StateNodeTypes::Final: - break; - case StateNodeTypes::History: { - // CheckTransitionForWrittenNodesList( theNode.m_Transition ); - } break; - case StateNodeTypes::Transition: { - STransition &theNode(static_cast(inNode)); - CheckTransitionForWrittenNodesList(&theNode); - } break; - default: - QT3DS_ASSERT(false); - break; - } - } - - void CheckForExternalTransitions(TStateNodeList &ioList, - const eastl::vector &inRoots) - { - for (TStateNodeList::iterator iter = ioList.begin(), end = ioList.end(); iter != end; - ++iter) { - if (eastl::find(inRoots.begin(), inRoots.end(), &(*iter)) == inRoots.end()) - CheckForExternalTransitions(*iter, inRoots); - } - } - - void WriteFragment(eastl::vector &inRoots, const QT3DSVec2 &inMousePos) - { - m_MousePos = inMousePos; - for (QT3DSU32 idx = 0, end = inRoots.size(); idx < end; ++idx) { - Write(*inRoots[idx], true); - } - if (m_Context.GetRoot()) - CheckForExternalTransitions(*m_Context.GetRoot(), inRoots); - m_CurrentNamespace = GetStudioStateNamespace(); - for (QT3DSU32 idx = 0, end = m_ExternalTransitions.size(); idx < end; ++idx) { - WriteExternalTransition(*m_ExternalTransitions[idx]); - } - } -}; - -// True if child is a descedent of parent. False otherwise. -inline bool IsDescendent(SStateNode &parent, SStateNode &child) -{ - if (&parent == &child) - return false; - if (&parent == child.m_Parent) - return true; - - if (child.m_Parent) - return IsDescendent(parent, *child.m_Parent); - - return false; -} - -template -void GenerateUniqueIdT(TDataType &inNode, const char8_t *inStem, IStateContext &ioContext, - IStringTable &ioStringTable) -{ - QT3DS_ASSERT(inNode.m_Id.IsValid() == false); - inNode.m_Id = - ioStringTable.RegisterStr(DoGenerateUniqueId(inStem, ioContext, ioStringTable).c_str()); - bool insertResult = ioContext.InsertId(inNode.m_Id, &inNode); - QT3DS_ASSERT(insertResult); - (void)insertResult; -} -} - -namespace qt3ds { -namespace state { - - void CXMLIO::GenerateUniqueId(SStateNode &inNode, const char8_t *inStem, - IStateContext &ioContext, IStringTable &ioStringTable) - { - GenerateUniqueIdT(inNode, inStem, ioContext, ioStringTable); - } - - void CXMLIO::GenerateUniqueId(SSend &inNode, const char8_t *inStem, IStateContext &ioContext, - IStringTable &ioStringTable) - { - GenerateUniqueIdT(inNode, inStem, ioContext, ioStringTable); - } - - bool CXMLIO::LoadSCXMLFile(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, - IDOMReader &inReader, IStringTable &inStringTable, - const char8_t *inFilename, IStateContext &outContext, - editor::IEditor *inEditor) - { - // the topmost scxml node is a state, so go from there. - if (AreEqual(inReader.GetElementName().c_str(), "scxml")) { - SParseContext theParseContext(inGraphAllocator, inFnd, inReader, outContext, - inStringTable, inEditor); - outContext.SetRoot(theParseContext.ParseSCXML()); - if (outContext.GetRoot()) { - inFilename = nonNull(inFilename); - outContext.GetRoot()->m_Filename = theParseContext.ToGraphStr(inFilename); - } - return true; - } else { - return false; - } - } - - eastl::pair, CXMLIO::TIdRemapMap> - CXMLIO::LoadSCXMLFragment(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, - IDOMReader &inReader, IStringTable &inStringTable, - IStateContext &ioContext, editor::IEditor &inEditor) - { - if (AreEqual(inReader.GetElementName().c_str(), "scxml_fragment")) { - SParseContext theParseContext(inGraphAllocator, inFnd, inReader, ioContext, - inStringTable, &inEditor); - eastl::vector retval = theParseContext.ParseFragment(); - return eastl::make_pair(retval, theParseContext.m_RemapMap); - } - return eastl::make_pair(eastl::vector(), CXMLIO::TIdRemapMap()); - } - - void CXMLIO::SaveSCXMLFile(IStateContext &inContext, NVFoundationBase &inFnd, - IStringTable &inStringTable, IOutStream &outStream, - editor::IEditor *inEditor) - { - NVScopedRefCounted theFactory = - IDOMFactory::CreateDOMFactory(inFnd.getAllocator(), inStringTable); - NVScopedRefCounted theWriter = - IDOMWriter::CreateDOMWriter(inFnd.getAllocator(), "scxml", inStringTable, - GetSCXMLNamespace()) - .first; - SWriteContext theWriteContext(*theWriter, inContext, inStringTable, inEditor, - inFnd.getAllocator()); - theWriteContext.Write(); - - // Now we actually serialize the data. - eastl::vector thePairs; - thePairs.push_back( - SNamespacePair(inStringTable.RegisterStr(GetSCXMLNamespace()), CRegisteredString())); - thePairs.push_back(SNamespacePair(inStringTable.RegisterStr(GetStudioStateNamespace()), - inStringTable.RegisterStr("Qt3DS"))); - - for (SNamespacePairNode *theNode = inContext.GetFirstNSNode(); theNode; - theNode = theNode->m_NextNode) { - if (AreEqual(theNode->m_Namespace.c_str(), GetSCXMLNamespace()) == false - && AreEqual(theNode->m_Namespace.c_str(), GetStudioStateNamespace()) == false - && theNode->m_Abbreviation.IsValid()) - thePairs.push_back(*theNode); - } - - CDOMSerializer::WriteXMLHeader(outStream); - CDOMSerializer::Write(inFnd.getAllocator(), *theWriter->GetTopElement(), outStream, - inStringTable, toDataRef(thePairs.data(), thePairs.size()), false); - } - - void CXMLIO::FindRoots(NVConstDataRef inObjects, - eastl::vector &outRoots) - { - // Stupid but effective algorithm. - for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { - // Transitions never make it into the root, nor does the top scxml object - if (inObjects[idx]->m_Type == StateNodeTypes::Transition - || inObjects[idx]->m_Type == StateNodeTypes::SCXML) - continue; - SStateNode *newNode(inObjects[idx]); - // Note that re-querying size is important. - bool skip = false; - for (QT3DSU32 existingIdx = 0; existingIdx < outRoots.size() && skip == false; - ++existingIdx) { - SStateNode *existingNode(outRoots[existingIdx]); - if (newNode == existingNode || IsDescendent(*existingNode, *newNode)) - skip = true; - - // If the existing item is a descendent of new node, - // then get the existing item out of the list. - if (IsDescendent(*newNode, *existingNode)) { - // Get the existing item out of the list. - outRoots.erase(outRoots.begin() + existingIdx); - --existingIdx; - } - } - if (!skip) - outRoots.push_back(newNode); - } - } - - eastl::vector CXMLIO::SaveSCXMLFragment( - IStateContext &inContext, NVFoundationBase &inFnd, IStringTable &inStringTable, - IDOMWriter &ioWriter, NVDataRef inObjects, editor::IEditor &inEditor, - const QT3DSVec2 &inMousePos, eastl::vector &outNamespaces) - { - eastl::vector theRoots; - FindRoots(inObjects, theRoots); - NVScopedRefCounted theWriter(ioWriter); - SWriteContext theWriteContext(*theWriter, inContext, inStringTable, &inEditor, - inFnd.getAllocator()); - theWriteContext.WriteFragment(theRoots, inMousePos); - - outNamespaces.push_back( - SNamespacePair(inStringTable.RegisterStr(GetSCXMLNamespace()), CRegisteredString())); - outNamespaces.push_back(SNamespacePair(inStringTable.RegisterStr(GetStudioStateNamespace()), - inStringTable.RegisterStr("Qt3DS"))); - return theRoots; - } - - void CXMLIO::ToEditableXml(IStateContext &inContext, NVFoundationBase &inFnd, - IStringTable &inStringTable, IDOMWriter &ioWriter, - SExecutableContent &inContent, editor::IEditor &inEditor) - { - SWriteContext theWriteContext(ioWriter, inContext, inStringTable, &inEditor, - inFnd.getAllocator()); - theWriteContext.WriteExecutableContent(inContent); - } - - SExecutableContent * - CXMLIO::FromEditableXML(IDOMReader &inReader, NVFoundationBase &inFnd, IStateContext &inContext, - IStringTable &inStringTable, NVAllocatorCallback &inGraphAllocator, - editor::IEditor &inEditor, SStateNode *inStateNodeParent, - SExecutableContent *inExecContentParent) - { - SParseContext theParseContext(inGraphAllocator, inFnd, inReader, inContext, inStringTable, - &inEditor); - TExecutableContentList theContentList; - theParseContext.ParseExecutableContentItem(inStateNodeParent, inExecContentParent, - theContentList); - return &(*theContentList.begin()); - } - - eastl::vector CXMLIO::GetSupportedExecutableContentNames() - { - eastl::vector retval; - NVConstDataRef theBindingList = - SParseContext::GetParseBindings(); - for (QT3DSU32 idx = 0, end = theBindingList.size(); idx < end; ++idx) - retval.push_back( - eastl::string(SXMLName::GetNameForElemName(theBindingList[idx].m_Name))); - return retval; - } -} -} diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSActivationManager.h b/src/Runtime/Source/Runtime/Include/Qt3DSActivationManager.h deleted file mode 100644 index f343ac9b..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSActivationManager.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_ACTIVATION_MANAGER_H -#define QT3DS_ACTIVATION_MANAGER_H -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Utils.h" -#include "Qt3DSKernelTypes.h" -#include "Qt3DSMetadata.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSTimePolicy.h" - -namespace Q3DStudio { -struct IComponentTimeOverrideFinishedCallback; -struct SComponentTimePolicyOverride; -class CPresentation; -} - -namespace qt3ds { -namespace foundation { - class IPerfTimer; -} -} - -namespace qt3ds { -namespace render { - class IThreadPool; -} -} - -namespace qt3ds { -namespace runtime { - using namespace qt3ds::foundation; - using namespace qt3ds; - using Q3DStudio::CTimePolicy; - using Q3DStudio::SComponentTimePolicyOverride; - using Q3DStudio::IComponentTimeOverrideFinishedCallback; - using Q3DStudio::CPresentation; - using Q3DStudio::TTimeUnit; - using qt3ds::render::IThreadPool; - - class IActivationManager; - - typedef element::SElement &TActivityItem; - typedef element::SElement *TActivityItemPtr; - - typedef eastl::pair TElementAndSortKey; - - typedef NVConstDataRef TActivityItemBuffer; - - // Items can have user active and time active. Time active is controlled by this object - // but user active can be set. An item is only active if it both actives are true. - // Inactive items have completely inactive children. - class IActivityZone - { - protected: - virtual ~IActivityZone() {} - public: - virtual Q3DStudio::CPresentation &GetPresentation() = 0; - - // Items activated this cycle - virtual TActivityItemBuffer GetActivatedItems() = 0; - // Items deactivated this cycle - virtual TActivityItemBuffer GetDeactivatedItems() = 0; - // All active items that are script enabled. - virtual TActivityItemBuffer GetScriptItems() = 0; - - // Inactive zones don't update their item lists when the manager updates. - virtual void SetZoneActive(bool inActive) = 0; - virtual bool IsZoneActive() = 0; - - virtual void AddActivityItems(TActivityItem root) = 0; - - // Get the time policy that is owned by this element. - virtual CTimePolicy *GetOwnedTimePolicy(TActivityItem item) = 0; - // Get the local time for this element. This is the time the animation system should see - virtual TTimeUnit GetItemLocalTime(TActivityItem item) = 0; - // Get the local time if this isn't independent, else get the time context time for the - // component. - virtual TTimeUnit GetItemComponentTime(TActivityItem item) = 0; - - virtual SComponentTimePolicyOverride * - GetOrCreateItemComponentOverride(TActivityItem item, float inMultiplier, - TTimeUnit inEndTime, - IComponentTimeOverrideFinishedCallback *inCallback) = 0; - - // If this item is independent, return this item. - // else get time parent of my parent. - virtual TActivityItemPtr GetItemTimeParent(TActivityItem item) = 0; - - bool IsIndependent(TActivityItem item) { return GetOwnedTimePolicy(item) != NULL; } - - // Any time the item has script flag changes after its initial creation. - // Note that this flag cannot change due to slide changes, it can only change due - // to something that had a script error and thus is disabled. - virtual void UpdateItemScriptStatus(TActivityItem item) = 0; - - // If the start, end, or explicit active flags change *outside* of a slide change. - virtual void UpdateItemInfo(TActivityItem item) = 0; - virtual bool GetItemUserActive(TActivityItem item) = 0; - - // Callback when the slide changes, the time context needs to be rebuilt in this case. - virtual void OnSlideChange(TActivityItem item) = 0; - - virtual bool GetItemTimeActive(TActivityItem item) = 0; - - virtual void BeginUpdate(QT3DSI64 inGlobalTime, IPerfTimer &inPerfTimer, - IThreadPool &inThreadPool) = 0; - virtual bool IsUpdating() = 0; - virtual void EndUpdate() = 0; - - virtual void GoToTime(TActivityItem item, TTimeUnit inTime) = 0; - }; - - class IActivityZoneManager : public NVRefCounted - { - protected: - virtual ~IActivityZoneManager() {} - public: - virtual IActivityZone &CreateActivityZone(Q3DStudio::CPresentation &inPresentation) = 0; - - static IActivityZoneManager &CreateActivityZoneManager(NVFoundationBase &inFoundation, - IStringTable &inStrTable); - }; -} -} -#endif diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSAnimationSystem.h b/src/Runtime/Source/Runtime/Include/Qt3DSAnimationSystem.h deleted file mode 100644 index 24542ad9..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSAnimationSystem.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_ANIMATION_SYSTEM_H -#define QT3DS_ANIMATION_SYSTEM_H -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSRefCounted.h" - -#pragma once -namespace qt3ds { -namespace foundation { - class IOutStream; -} -} - -namespace qt3ds { -namespace runtime { - using namespace qt3ds; - using namespace qt3ds::foundation; - - namespace element { - struct SElement; - } - class IElementAllocator; - - class IAnimationSystem : public NVRefCounted - { - public: - virtual QT3DSI32 CreateAnimationTrack(element::SElement &inElement, QT3DSU32 inPropertyName, - bool inDynamic) = 0; - virtual void AddKey(QT3DSF32 inTime, QT3DSF32 inValue, QT3DSF32 inC1Time, QT3DSF32 inC1Value, - QT3DSF32 inC2Time, QT3DSF32 inC2Value) = 0; - virtual void Update() = 0; - virtual void SetActive(QT3DSI32 inTrackId, bool inActive) = 0; - virtual void UpdateDynamicKey(QT3DSI32 inTrackId) = 0; - - static IAnimationSystem &CreateAnimationSystem(NVFoundationBase &inFoundation); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h b/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h deleted file mode 100644 index d825fe0f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h +++ /dev/null @@ -1,240 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_APPLICATION_H -#define QT3DS_APPLICATION_H -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Utils.h" -#include "Qt3DSKernelTypes.h" -#include "Qt3DSMetadata.h" -#include "QtQml/qjsengine.h" - -namespace Q3DStudio { -class IRuntimeFactory; -class IRuntimeFactoryCore; -class CRuntime; -class CPresentation; -class CInputEngine; -class IAudioPlayer; -} - -namespace qt3ds { -namespace state { -namespace debugger { -class IDebugger; -class ISceneGraphRuntimeDebugger; -} -} -} - -namespace qt3ds { -class Qt3DSAssetVisitor; -namespace runtime { -using namespace qt3ds::foundation; -using namespace qt3ds; - -class IElementAllocator; -class IActivityZoneManager; - -class CAppStr : public eastl::basic_string -{ - typedef eastl::basic_string TBase; - -public: - CAppStr(NVAllocatorCallback &alloc, const char8_t *inStr = NULL); - CAppStr(const CAppStr &inOther); - CAppStr(); - CAppStr &operator=(const CAppStr &inOther); -}; - -class IApplication; - -class IAppRunnable : public NVRefCounted -{ -public: - virtual void Run() = 0; -}; - -class QT3DS_AUTOTEST_EXPORT IApplicationCore : public NVRefCounted -{ -public: - // threadsafe call. - virtual void QueueForMainThread(IAppRunnable &inRunnable) = 0; - - // The directory that contains the executable and the root resource path - virtual CRegisteredString GetApplicationDirectory() const = 0; - // Directory that contained the UIA file. - virtual CRegisteredString GetProjectDirectory() const = 0; - // Directory where we will copy shared object files to before we load them. - // This is specifically for android and the case where the place where the project exists - // is not always the place where we can load the project. - virtual CRegisteredString GetDllDir() const = 0; - virtual void SetDllDir(const char *inDllDir) = 0; - virtual Q3DStudio::THashValue HashString(const char *inStr) = 0; - virtual const char *ReverseHash(Q3DStudio::THashValue theValue) = 0; - - virtual Q3DStudio::IRuntimeMetaData &GetMetaData() = 0; - // Element handles are unique across all presentations. - virtual Q3DStudio::TElement *GetElementByHandle(Q3DStudio::UINT32 inHandle) = 0; - // Passing in NULL gets you zero as the return handle. - virtual Q3DStudio::UINT32 GetHandleForElement(Q3DStudio::TElement *inElement) = 0; - - virtual Q3DStudio::IRuntimeFactoryCore &GetRuntimeFactoryCore() = 0; - virtual void HideFPS(bool flag) = 0; - - virtual qt3ds::state::debugger::ISceneGraphRuntimeDebugger &GetSceneGraphDebugger() = 0; - virtual qt3ds::state::debugger::IDebugger &GetStateDebugger() = 0; - virtual IActivityZoneManager &GetActivityZoneManager() = 0; - virtual IElementAllocator &GetElementAllocator() = 0; - - // Debugging is disabled by default. - // This is expected be be called before load and will not immediately connect. - // until we have a valid presentation directory (which is required for the debug system - // at the other end of the connection). - // listen - either list for a connection else actively connect to a server. - // inServer - if listen is false, then the server addr to connect to. Ignored if server is - // true - // inPort - If listen is false, the port on server to connect to, else port to open up - // socket on. - virtual void EnableDebugging(bool inListen = false, const char8_t *inServer = NULL, - int inPort = 0) = 0; - - // State machine is enabled by default - // Disable state machine is meant to disable internal statemachine, but may plug in an - // external statemachine - virtual void DisableStateMachine() = 0; - - // nonblocking call to begin loading, loads uia file alone and returns. - virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; - - // blocking call to end all loading threads and such/wait till finished - virtual void EndLoad() = 0; - // Will EndLoad cause nontrivial blocking. - // Runs any queued runnables. - virtual bool HasCompletedLoading() = 0; - - virtual void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) = 0; - - // will force loading to end if endLoad hasn't been called yet. Will fire off loading - // of resources that need to be uploaded to opengl. Maintains reference to runtime factory - virtual IApplication &CreateApplication(Q3DStudio::CInputEngine &inInputEngine, - Q3DStudio::IAudioPlayer *inAudioPlayer, - Q3DStudio::IRuntimeFactory &inFactory) = 0; - - // maintains reference to runtime factory core. AppDir is where the executable is located; - // the system will expect res directory - // next to executable. - static IApplicationCore &CreateApplicationCore(Q3DStudio::IRuntimeFactoryCore &inFactory, - const char8_t *inApplicationDirectory); - static bool isPickingEvent(Q3DStudio::TEventCommandHash event); -}; - -struct DataInputControlledAttribute -{ - QByteArray elementPath; - QVector attributeName; - Q3DStudio::EAttributeType propertyType = Q3DStudio::ATTRIBUTETYPE_NONE; -}; - -enum DataInputType { - DataInputTypeInvalid = 0, - DataInputTypeRangedNumber, - DataInputTypeString, - DataInputTypeFloat, - DataInputTypeEvaluator, - DataInputTypeBoolean, - DataInputTypeVector3, - DataInputTypeVector2, - DataInputTypeVariant -}; - -struct DataInputDef -{ - QVector controlledAttributes; - DataInputType type = DataInputTypeInvalid; - float min = 0.0f; - float max = 0.0f; - QString evaluator; - QJSValue evalFunc; // keep both evaluator string and JS function - // to avoid having to evaluate string several times - QVariant value; // most recently set value - // evaluator datainputs that need to re-evaluate when this datainput changes value - QVector dependents; - -}; - -typedef QMap DataInputMap; - -class IApplication : public IApplicationCore -{ -public: - virtual Q3DStudio::IRuntimeFactory &GetRuntimeFactory() const = 0; - - virtual void SetFrameCount(Q3DStudio::INT32 inFrameCount) = 0; - virtual Q3DStudio::INT32 GetFrameCount() = 0; - - // Allow overriding the global wall time. This way animations can be - // advanced at an arbitrary rate when rendering offscreen. Set to 0 to - // disable (the default). - virtual void SetTimeMilliSecs(Q3DStudio::INT64 inMilliSecs) = 0; - - virtual Q3DStudio::INT64 GetTimeMilliSecs() = 0; - virtual void ResetTime() = 0; - - // Setup during UpdateAndRender. Returns 0 for first frame. - virtual double GetMillisecondsSinceLastFrame() = 0; - - virtual Q3DStudio::CInputEngine &GetInputEngine() = 0; - - virtual Q3DStudio::CPresentation *GetPrimaryPresentation() = 0; - - virtual Q3DStudio::CPresentation *GetPresentationById(const char8_t *inId) = 0; - - virtual QList GetPresentationList() = 0; - - // Update all the presentations and render them. Called exactly once per frame. - virtual void UpdateAndRender() = 0; - - virtual bool IsApplicationDirty() = 0; - - virtual void MarkApplicationDirty() = 0; - - virtual Q3DStudio::IAudioPlayer &GetAudioPlayer() = 0; - - virtual bool createSuccessful() = 0; - - virtual DataInputMap &dataInputMap() = 0; -}; -} -} - -#endif diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSApplicationValues.h b/src/Runtime/Source/Runtime/Include/Qt3DSApplicationValues.h deleted file mode 100644 index 80e8f73f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSApplicationValues.h +++ /dev/null @@ -1,369 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#include "Qt3DSApplication.h" -#include "foundation/Qt3DSDiscriminatedUnion.h" -#include "foundation/StringTable.h" - -namespace qt3ds { - -class Qt3DSAssetVisitor -{ -public: - virtual void visit(const char *path) = 0; - virtual void visit(const char *type, const char *id, const char *src, const char *args) = 0; -}; - -namespace runtime { - - using qt3ds::foundation::CRegisteredString; - - struct AssetValueTypes - { - enum Enum { - NoAssetValue = 0, - Presentation, - SCXML, - RenderPlugin, - Behavior, - QmlPresentation, - }; - }; - struct SAssetBase - { - CRegisteredString m_Id; - CRegisteredString m_Src; - CRegisteredString m_Args; - SAssetBase(CRegisteredString inId = CRegisteredString(), - CRegisteredString inSrc = CRegisteredString(), - CRegisteredString inArgs = CRegisteredString()) - : m_Id(inId) - , m_Src(inSrc) - , m_Args(inArgs) - { - } - bool operator==(const SAssetBase &inOther) const - { - return m_Id == inOther.m_Id && m_Src == inOther.m_Src - && m_Args == inOther.m_Args; - } - template - void Remap(TRemapper &item) - { - item.Remap(m_Id); - item.Remap(m_Src); - item.Remap(m_Args); - } - virtual const char *Type() const - { - return nullptr; - } - }; - - struct SPresentationAsset : public SAssetBase - { - Q3DStudio::CPresentation *m_Presentation; - bool m_Active; - - SPresentationAsset(CRegisteredString inId = CRegisteredString(), - CRegisteredString inRelPath = CRegisteredString(), - Q3DStudio::CPresentation *inPresentation = NULL) - : SAssetBase(inId, inRelPath, CRegisteredString()) - , m_Presentation(inPresentation) - , m_Active(true) - { - } - - bool operator==(const SPresentationAsset &inOther) const - { - return SAssetBase::operator==(inOther) && m_Presentation == inOther.m_Presentation - && m_Active == inOther.m_Active; - } - - template - void Remap(TRemapper &item) - { - m_Presentation = NULL; - SAssetBase::Remap(item); - } - const char *Type() const override - { - return "presentation"; - } - }; - - struct SSCXMLAsset : public SAssetBase - { - CRegisteredString m_Datamodel; - SSCXMLAsset(CRegisteredString inId = CRegisteredString(), - CRegisteredString inRelPath = CRegisteredString(), - CRegisteredString inDatamodel = CRegisteredString()) - : SAssetBase(inId, inRelPath, CRegisteredString()) - , m_Datamodel(inDatamodel) - { - } - bool operator==(const SSCXMLAsset &inOther) const - { - return SAssetBase::operator==(inOther) && m_Datamodel == inOther.m_Datamodel; - } - template - void Remap(TRemapper &item) - { - SAssetBase::Remap(item); - item.Remap(m_Datamodel); - } - const char *Type() const override - { - return "scxml"; - } - }; - - struct SRenderPluginAsset : public SAssetBase - { - SRenderPluginAsset(CRegisteredString inId = CRegisteredString(), - CRegisteredString inRelPath = CRegisteredString(), - CRegisteredString inArgs = CRegisteredString()) - : SAssetBase(inId, inRelPath, inArgs) - { - } - const char *Type() const override - { - return "renderplugin"; - } - }; - - struct SQmlPresentationAsset : public SAssetBase - { - SQmlPresentationAsset(CRegisteredString inId = CRegisteredString(), - CRegisteredString inRelPath = CRegisteredString(), - CRegisteredString inArgs = CRegisteredString()) - : SAssetBase(inId, inRelPath, inArgs) - { - } - const char *Type() const override - { - return "presentation-qml"; - } - }; - - struct SBehaviorAsset : public SAssetBase - { - Q3DStudio::INT32 m_Handle; - SBehaviorAsset(CRegisteredString inId = CRegisteredString(), - CRegisteredString inRelPath = CRegisteredString(), - Q3DStudio::INT32 inHandle = 0) - : SAssetBase(inId, inRelPath, CRegisteredString()) - , m_Handle(inHandle) - { - } - bool operator==(const SBehaviorAsset &inOther) const - { - return SAssetBase::operator==(inOther) && m_Handle == inOther.m_Handle; - } - template - void Remap(TRemapper &item) - { - m_Handle = -1; - SAssetBase::Remap(item); - } - const char *Type() const override - { - return "behaviour"; - } - }; -} -} - -namespace qt3ds { -namespace foundation { - template <> - struct DestructTraits - { - void destruct(qt3ds::runtime::SPresentationAsset &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::runtime::SSCXMLAsset &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::runtime::SRenderPluginAsset &) {} - }; - template <> - struct DestructTraits - { - void destruct(qt3ds::runtime::SBehaviorAsset &) {} - }; -} -} - -namespace qt3ds { -namespace runtime { - - // Force compile error if unsupported datatype requested - template - struct SAssetValueTypeMap - { - }; - - template <> - struct SAssetValueTypeMap - { - static AssetValueTypes::Enum GetType() { return AssetValueTypes::Presentation; } - }; - template <> - struct SAssetValueTypeMap - { - static AssetValueTypes::Enum GetType() { return AssetValueTypes::SCXML; } - }; - template <> - struct SAssetValueTypeMap - { - static AssetValueTypes::Enum GetType() { return AssetValueTypes::RenderPlugin; } - }; - template <> - struct SAssetValueTypeMap - { - static AssetValueTypes::Enum GetType() { return AssetValueTypes::QmlPresentation; } - }; - template <> - struct SAssetValueTypeMap - { - static AssetValueTypes::Enum GetType() { return AssetValueTypes::Behavior; } - }; - - struct SAssetValueUnionTraits - { - typedef AssetValueTypes::Enum TIdType; - enum { - TBufferSize = sizeof(SPresentationAsset), - }; - - static TIdType getNoDataId() { return AssetValueTypes::NoAssetValue; } - - template - static TIdType getType() - { - return SAssetValueTypeMap().GetType(); - } - - template - static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case AssetValueTypes::Presentation: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::SCXML: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::RenderPlugin: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::Behavior: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::QmlPresentation: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case AssetValueTypes::NoAssetValue: - return inVisitor(); - } - } - - template - static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) - { - switch (inType) { - case AssetValueTypes::Presentation: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::SCXML: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::RenderPlugin: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::Behavior: - return inVisitor(*NVUnionCast(inData)); - case AssetValueTypes::QmlPresentation: - return inVisitor(*NVUnionCast(inData)); - default: - QT3DS_ASSERT(false); - case AssetValueTypes::NoAssetValue: - return inVisitor(); - } - } - }; - - typedef qt3ds::foundation:: - DiscriminatedUnion, - SAssetValueUnionTraits::TBufferSize> - TAssetValueUnionType; - - struct SAssetValue : public TAssetValueUnionType - { - SAssetValue() {} - - SAssetValue(const SAssetValue &inOther) - : TAssetValueUnionType(static_cast(inOther)) - { - } - - template - SAssetValue(const TDataType &inDt) - : TAssetValueUnionType(inDt) - { - } - - SAssetValue &operator=(const SAssetValue &inOther) - { - TAssetValueUnionType::operator=(inOther); - return *this; - } - - bool operator==(const SAssetValue &inOther) const - { - return TAssetValueUnionType::operator==(inOther); - } - bool operator!=(const SAssetValue &inOther) const - { - return TAssetValueUnionType::operator!=(inOther); - } - - bool empty() const { return getType() == AssetValueTypes::NoAssetValue; } - - CRegisteredString GetSource() - { - if (empty()) - return CRegisteredString(); - return reinterpret_cast(m_Data)->m_Src; - } - }; -} -} diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.h b/src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.h deleted file mode 100644 index 02dda069..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.h +++ /dev/null @@ -1,279 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -// !!!!! AUTOGENERATED CODE - DO NOT MODIFY MANUALLY !!!!! - -// Run the AttributeHashes project to regenerate this file from Attributehashes.txt list - -/// Key for the CElement attribute-value pair -enum EAttribute { - ATTRIBUTE_NAME = 0x02B79D95, // name - ATTRIBUTE_TYPE = 0x005F9806, // type - ATTRIBUTE_OPACITY = 0x0191C315, // opacity - ATTRIBUTE_STARTTIME = 0x010A57B1, // starttime - ATTRIBUTE_ENDTIME = 0x003BF5F8, // endtime - ATTRIBUTE_SOURCEPATH = 0x0009EA60, // sourcepath - ATTRIBUTE_IMPORTID = 0x008F7900, // importid - ATTRIBUTE_EYEBALL = 0x02F454F0, // eyeball - ATTRIBUTE_POSITION = 0x00E9B7D7, // position - ATTRIBUTE_POSITION_X = 0x027C230D, // position.x - ATTRIBUTE_POSITION_Y = 0x027D234C, // position.y - ATTRIBUTE_POSITION_Z = 0x027E238B, // position.z - ATTRIBUTE_ROTATION = 0x03E51862, // rotation - ATTRIBUTE_ROTATION_X = 0x0239EE18, // rotation.x - ATTRIBUTE_ROTATION_Y = 0x023AEE57, // rotation.y - ATTRIBUTE_ROTATION_Z = 0x023BEE96, // rotation.z - ATTRIBUTE_SCALE = 0x01012856, // scale - ATTRIBUTE_SCALE_X = 0x0065440C, // scale.x - ATTRIBUTE_SCALE_Y = 0x0066444B, // scale.y - ATTRIBUTE_SCALE_Z = 0x0067448A, // scale.z - ATTRIBUTE_PIVOT = 0x009E907E, // pivot - ATTRIBUTE_PIVOT_X = 0x03811834, // pivot.x - ATTRIBUTE_PIVOT_Y = 0x03821873, // pivot.y - ATTRIBUTE_PIVOT_Z = 0x038318B2, // pivot.z - ATTRIBUTE_ROTATIONORDER = 0x03CE5F70, // rotationorder - ATTRIBUTE_ORIENTATION = 0x001A90B0, // orientation - ATTRIBUTE_SHADOWCASTER = 0x0363F874, // shadowcaster - ATTRIBUTE_TESSELLATION = 0x0335861F, // tessellation - ATTRIBUTE_EDGETESS = 0x023933D2, // edgetess - ATTRIBUTE_INNERTESS = 0x01529259, // innertess - ATTRIBUTE_ORTHOGRAPHIC = 0x0244BB70, // orthographic - ATTRIBUTE_CLIPNEAR = 0x0068FF28, // clipnear - ATTRIBUTE_CLIPFAR = 0x037EF699, // clipfar - ATTRIBUTE_FOV = 0x00D60213, // fov - ATTRIBUTE_FOVHORIZONTAL = 0x01BDB34F, // fovhorizontal - ATTRIBUTE_SCALEMODE = 0x01FD2FD3, // scalemode - ATTRIBUTE_SCALEANCHOR = 0x02CFCF41, // scaleanchor - ATTRIBUTE_BRIGHTNESS = 0x0230D3AF, // brightness - ATTRIBUTE_LINEARFADE = 0x0104E9FF, // linearfade - ATTRIBUTE_EXPFADE = 0x006B9267, // expfade - ATTRIBUTE_LIGHTTYPE = 0x0033F1D0, // lighttype - ATTRIBUTE_SCOPE = 0x0258D0CC, // scope - ATTRIBUTE_LIGHTDIFFUSE = 0x01246FD4, // lightdiffuse - ATTRIBUTE_LIGHTDIFFUSE_R = 0x035AAB10, // lightdiffuse.r - ATTRIBUTE_LIGHTDIFFUSE_G = 0x034FA85B, // lightdiffuse.g - ATTRIBUTE_LIGHTDIFFUSE_B = 0x034AA720, // lightdiffuse.b - ATTRIBUTE_LIGHTAMBIENT_R = 0x0179AD1A, // lightambient.r - ATTRIBUTE_LIGHTAMBIENT = 0x00DA56DE, // lightambient - ATTRIBUTE_LIGHTAMBIENT_G = 0x016EAA65, // lightambient.g - ATTRIBUTE_LIGHTAMBIENT_B = 0x0169A92A, // lightambient.b - ATTRIBUTE_LIGHTSPECULAR = 0x03E39A07, // lightspecular - ATTRIBUTE_LIGHTSPECULAR_R = 0x0241EBC3, // lightspecular.r - ATTRIBUTE_LIGHTSPECULAR_G = 0x0236E90E, // lightspecular.g - ATTRIBUTE_LIGHTSPECULAR_B = 0x0231E7D3, // lightspecular.b - ATTRIBUTE_AREAWIDTH = 0x005A8BE7, // areawidth - ATTRIBUTE_AREAHEIGHT = 0x00334D2C, // areaheight - ATTRIBUTE_CASTSHADOW = 0x0335FD81, // castshadow - ATTRIBUTE_SHDWBIAS = 0x0125E79F, // shdwbias - ATTRIBUTE_SHDWFACTOR = 0x01B11BE9, // shdwfactor - ATTRIBUTE_SHDWMAPRES = 0x01E53834, // shdwmapres - ATTRIBUTE_SHDWMAPFAR = 0x019A30FD, // shdwmapfar - ATTRIBUTE_SHDWMAPFOV = 0x00830B07, // shdwmapfov - ATTRIBUTE_SHDWFILTER = 0x0176E1E0, // shdwfilter - ATTRIBUTE_LIGHTMAPINDIRECT = 0x004F1D6C, // lightmapindirect - ATTRIBUTE_LIGHTMAPRADIOSITY = 0x00AC7C50, // lightmapradiosity - ATTRIBUTE_LIGHTMAPSHADOW = 0x00191F3A, // lightmapshadow - ATTRIBUTE_IBLPROBE = 0x0039FD03, // iblprobe - ATTRIBUTE_SHADERLIGHTING = 0x0068A84F, // shaderlighting - ATTRIBUTE_EMISSIVEPOWER = 0x03D6F9F2, // emissivepower - ATTRIBUTE_EMISSIVECOLOR = 0x00B7AC94, // emissivecolor - ATTRIBUTE_EMISSIVECOLOR_R = 0x039B87D0, // emissivecolor.r - ATTRIBUTE_EMISSIVECOLOR_G = 0x0390851B, // emissivecolor.g - ATTRIBUTE_EMISSIVECOLOR_B = 0x038B83E0, // emissivecolor.b - ATTRIBUTE_DIFFUSE = 0x0105521E, // diffuse - ATTRIBUTE_DIFFUSE_R = 0x015B085A, // diffuse.r - ATTRIBUTE_DIFFUSE_G = 0x015005A5, // diffuse.g - ATTRIBUTE_DIFFUSE_B = 0x014B046A, // diffuse.b - ATTRIBUTE_SPECULARMAP = 0x034CD047, // specularmap - ATTRIBUTE_SPECULARMODEL = 0x039EBE5A, // specularmodel - ATTRIBUTE_SPECULARTINT = 0x03535E02, // speculartint - ATTRIBUTE_SPECULARTINT_R = 0x0399623E, // speculartint.r - ATTRIBUTE_SPECULARTINT_G = 0x038E5F89, // speculartint.g - ATTRIBUTE_SPECULARTINT_B = 0x03895E4E, // speculartint.b - ATTRIBUTE_IOR = 0x00667354, // ior - ATTRIBUTE_FRESNELPOWER = 0x022178B6, // fresnelPower - ATTRIBUTE_SPECULARAMOUNT = 0x01144425, // specularamount - ATTRIBUTE_SPECULARROUGHNESS = 0x03925653, // specularroughness - ATTRIBUTE_ROUGHNESSMAP = 0x01088174, // roughnessmap - ATTRIBUTE_BLENDMODE = 0x01923A6C, // blendmode - ATTRIBUTE_CULLING = 0x03C539F0, // culling - ATTRIBUTE_ZBUFFERWRITE = 0x03E19B3B, // zbufferwrite - ATTRIBUTE_DIFFUSEMAP = 0x00FF8126, // diffusemap - ATTRIBUTE_DIFFUSEMAP2 = 0x0038D4A8, // diffusemap2 - ATTRIBUTE_DIFFUSEMAP3 = 0x0039D4E7, // diffusemap3 - ATTRIBUTE_SPECULARREFLECTION = 0x006B4C12, // specularreflection - ATTRIBUTE_OPACITYMAP = 0x00DA796F, // opacitymap - ATTRIBUTE_EMISSIVEMAP = 0x00F6427B, // emissivemap - ATTRIBUTE_EMISSIVEMAP2 = 0x03476893, // emissivemap2 - ATTRIBUTE_BUMPMAP = 0x024EE11A, // bumpmap - ATTRIBUTE_BUMPAMOUNT = 0x01BC4192, // bumpamount - ATTRIBUTE_NORMALMAP = 0x03BD578B, // normalmap - ATTRIBUTE_DISPLACEMENTMAP = 0x01BCD1FB, // displacementmap - ATTRIBUTE_DISPLACEAMOUNT = 0x01EC1EAF, // displaceamount - ATTRIBUTE_TRANSLUCENCYMAP = 0x01D8F015, // translucencymap - ATTRIBUTE_TRANSLUCENTFALLOFF = 0x0097E985, // translucentfalloff - ATTRIBUTE_DIFFUSELIGHTWRAP = 0x038F6522, // diffuselightwrap - ATTRIBUTE_REFERENCEDMATERIAL = 0x035FDA80, // referencedmaterial - ATTRIBUTE_VERTEXCOLORS = 0x000814EC, // vertexcolors - ATTRIBUTE_ROTATIONUV = 0x012E3A61, // rotationuv - ATTRIBUTE_POSITIONU = 0x01D05AB4, // positionu - ATTRIBUTE_POSITIONV = 0x01D15AF3, // positionv - ATTRIBUTE_SCALEU = 0x001409F5, // scaleu - ATTRIBUTE_SCALEV = 0x00150A34, // scalev - ATTRIBUTE_PIVOTU = 0x03F8ABCD, // pivotu - ATTRIBUTE_PIVOTV = 0x03F9AC0C, // pivotv - ATTRIBUTE_TILINGMODEHORZ = 0x02562203, // tilingmodehorz - ATTRIBUTE_TILINGMODEVERT = 0x03F92B21, // tilingmodevert - ATTRIBUTE_MAPPINGTYPE = 0x02CA9058, // mappingtype - ATTRIBUTE_MAPPINGMODE = 0x002715CF, // mappingmode - ATTRIBUTE_SUBPRESENTATION = 0x03CA7426, // subpresentation - ATTRIBUTE_URI = 0x00296894, // uri - ATTRIBUTE_TRANSPARENT = 0x0316BA2E, // transparent - ATTRIBUTE_PROGRESSIVEAA = 0x019F1955, // progressiveaa - ATTRIBUTE_MULTISAMPLEAA = 0x013D29FD, // multisampleaa - ATTRIBUTE_TEMPORALAA = 0x00212AFE, // temporalaa - ATTRIBUTE_BLENDTYPE = 0x0035B4F5, // blendtype - ATTRIBUTE_HORZFIELDS = 0x02B8A818, // horzfields - ATTRIBUTE_LEFT = 0x0196B9B9, // left - ATTRIBUTE_LEFTUNITS = 0x02F9D2D8, // leftunits - ATTRIBUTE_WIDTH = 0x00C4D65A, // width - ATTRIBUTE_WIDTHUNITS = 0x01D7DF77, // widthunits - ATTRIBUTE_RIGHT = 0x039EAB44, // right - ATTRIBUTE_RIGHTUNITS = 0x0357EF0D, // rightunits - ATTRIBUTE_VERTFIELDS = 0x03462436, // vertfields - ATTRIBUTE_TOP = 0x002F6B0B, // top - ATTRIBUTE_TOPUNITS = 0x03D58806, // topunits - ATTRIBUTE_HEIGHT = 0x00CE9F79, // height - ATTRIBUTE_HEIGHTUNITS = 0x00C91D18, // heightunits - ATTRIBUTE_BOTTOM = 0x00F4EE75, // bottom - ATTRIBUTE_BOTTOMUNITS = 0x0174091C, // bottomunits - ATTRIBUTE_AOSTRENGTH = 0x010F7ED1, // aostrength - ATTRIBUTE_AODISTANCE = 0x01DC349D, // aodistance - ATTRIBUTE_AOSOFTNESS = 0x02CCDC71, // aosoftness - ATTRIBUTE_AOBIAS = 0x01818219, // aobias - ATTRIBUTE_AOSAMPLERATE = 0x0039B568, // aosamplerate - ATTRIBUTE_AODITHER = 0x0274316C, // aodither - ATTRIBUTE_SHADOWSTRENGTH = 0x0039ED5F, // shadowstrength - ATTRIBUTE_SHADOWDIST = 0x038213FA, // shadowdist - ATTRIBUTE_SHADOWSOFTNESS = 0x01F74AFF, // shadowsoftness - ATTRIBUTE_SHADOWBIAS = 0x02CB3EA7, // shadowbias - ATTRIBUTE_LIGHTPROBE = 0x02D47DC6, // lightprobe - ATTRIBUTE_PROBEBRIGHT = 0x029DC5B6, // probebright - ATTRIBUTE_FASTIBL = 0x02559509, // fastibl - ATTRIBUTE_PROBEHORIZON = 0x014DAAF5, // probehorizon - ATTRIBUTE_PROBEFOV = 0x03D66903, // probefov - ATTRIBUTE_LIGHTPROBE2 = 0x00430008, // lightprobe2 - ATTRIBUTE_PROBE2FADE = 0x02ED0742, // probe2fade - ATTRIBUTE_PROBE2WINDOW = 0x016B224E, // probe2window - ATTRIBUTE_PROBE2POS = 0x024B0C0E, // probe2pos - ATTRIBUTE_DISABLEDEPTHTEST = 0x000B8353, // disabledepthtest - ATTRIBUTE_DISABLEDEPTHPREPASS = 0x02AE1EA7, // disabledepthprepass - ATTRIBUTE_TEXTCOLOR = 0x02D9114A, // textcolor - ATTRIBUTE_TEXTCOLOR_R = 0x00E9F186, // textcolor.r - ATTRIBUTE_TEXTCOLOR_G = 0x00DEEED1, // textcolor.g - ATTRIBUTE_TEXTCOLOR_B = 0x00D9ED96, // textcolor.b - ATTRIBUTE_SIZE = 0x00F2C81F, // size - ATTRIBUTE_FONT = 0x03412331, // font - ATTRIBUTE_DROPSHADOW = 0x03E3F231, // dropshadow - ATTRIBUTE_DROPSHADOWSTRENGTH = 0x03F8B7D0, // dropshadowstrength - ATTRIBUTE_DROPSHADOWOFFSET = 0x024A9C5E, // dropshadowoffset - ATTRIBUTE_DROPSHADOWOFFSETX = 0x013298AA, // dropshadowoffsetx - ATTRIBUTE_DROPSHADOWOFFSETY = 0x013398E9, // dropshadowoffsety - ATTRIBUTE_DROPSHADOWHORZALIGN = 0x00D1BC39, // dropshadowhorzalign - ATTRIBUTE_DROPSHADOWVERTALIGN = 0x038D589B, // dropshadowvertalign - ATTRIBUTE_BOUNDINGBOX = 0x02F3B6D9, // boundingbox - ATTRIBUTE_BOUNDINGBOX_X = 0x0272C10F, // boundingbox.x - ATTRIBUTE_BOUNDINGBOX_Y = 0x0273C14E, // boundingbox.y - ATTRIBUTE_ELIDE = 0x022937DD, // elide - ATTRIBUTE_TRACKING = 0x02A25049, // tracking - ATTRIBUTE_LEADING = 0x016A6BDA, // leading - ATTRIBUTE_RENDERSTYLE = 0x03567B85, // renderstyle - ATTRIBUTE_TEXTSTRING = 0x01124062, // textstring - ATTRIBUTE_BACKCOLOR_R = 0x0290CCE0, // backcolor.r - ATTRIBUTE_BACKCOLOR_G = 0x0285CA2B, // backcolor.g - ATTRIBUTE_BACKCOLOR_B = 0x0280C8F0, // backcolor.b - ATTRIBUTE_TEXTTYPE = 0x0240ADD9, // texttype - ATTRIBUTE_USEBACKCOLOR = 0x0243BACB, // usebackcolor - ATTRIBUTE_WORDWRAP = 0x0134B04C, // wordwrap - ATTRIBUTE_HORZSCROLL = 0x005B3CC4, // horzscroll - ATTRIBUTE_HORZALIGN = 0x00BA002A, // horzalign - ATTRIBUTE_VERTSCROLL = 0x00E8B8E2, // vertscroll - ATTRIBUTE_VERTALIGN = 0x03759C8C, // vertalign - ATTRIBUTE_BOXHEIGHT = 0x0079AF8E, // boxheight - ATTRIBUTE_BOXWIDTH = 0x016B7105, // boxwidth - ATTRIBUTE_REMOTESTRINGSOURCE = 0x025DFEEE, // remotestringsource - ATTRIBUTE_CACHEDTEXTSTRING = 0x0095DBA0, // cachedtextstring - ATTRIBUTE_ENABLEACCELERATEDFONT = 0x0053A92D, // enableacceleratedfont - ATTRIBUTE_BEHAVIORSCRIPTS = 0x01DF916A, // BehaviorScripts - ATTRIBUTE_UICCUSTOMOBJTYPE = 0x029F1BCF, // UICCustomObjType - ATTRIBUTE_BGCOLORENABLE = 0x0021EE1F, // bgcolorenable - ATTRIBUTE_BACKGROUND = 0x006AA932, // background - ATTRIBUTE_BACKGROUNDCOLOR_R = 0x02AF0767, // backgroundcolor.r - ATTRIBUTE_BACKGROUNDCOLOR_G = 0x02A404B2, // backgroundcolor.g - ATTRIBUTE_BACKGROUNDCOLOR_B = 0x029F0377, // backgroundcolor.b - ATTRIBUTE_PATHTYPE = 0x02D2A5E1, // pathtype - ATTRIBUTE_LINEARERROR = 0x0378A51D, // linearerror - ATTRIBUTE_EDGETESSAMOUNT = 0x02577E3A, // edgetessamount - ATTRIBUTE_INNERTESSAMOUNT = 0x0027A241, // innertessamount - ATTRIBUTE_BEGINCAP = 0x03373D37, // begincap - ATTRIBUTE_BEGINCAPOFFSET = 0x01FEFE64, // begincapoffset - ATTRIBUTE_BEGINCAPOPACITY = 0x02C2761E, // begincapopacity - ATTRIBUTE_BEGINCAPWIDTH = 0x0102BDE3, // begincapwidth - ATTRIBUTE_ENDCAP = 0x00ADB3A9, // endcap - ATTRIBUTE_ENDCAPOFFSET = 0x0382A9D6, // endcapoffset - ATTRIBUTE_ENDCAPOPACITY = 0x019BA72C, // endcapopacity - ATTRIBUTE_ENDCAPWIDTH = 0x03A315F1, // endcapwidth - ATTRIBUTE_PAINTSTYLE = 0x03ADEC8D, // paintstyle - ATTRIBUTE_CLOSED = 0x01807034, // closed - ATTRIBUTE_INCOMINGANGLE = 0x03890AB3, // incomingangle - ATTRIBUTE_INCOMINGDISTANCE = 0x005EB2A5, // incomingdistance - ATTRIBUTE_OUTGOINGDISTANCE = 0x017C597F, // outgoingdistance - ATTRIBUTE_PARTICLETYPE = 0x01C01260, // particletype - ATTRIBUTE_MAXPARTICLES = 0x00BE66B7, // maxparticles - ATTRIBUTE_PARTICLESIZE = 0x02534279, // particlesize - ATTRIBUTE_LIFETIME = 0x0033D297, // lifetime - ATTRIBUTE_CONTROLLEDPROPERTY = 0x022C0A1D, // controlledproperty - ATTRIBUTE_QT_IO = 0x010EF2CF, // qt.io -}; // enum EAttribute - -#define AK_STRING_QT_IO "qt.io" - -/// Function providing reverse hash lookup -const char *GetAttributeString(const EAttribute inAttribute); - -} // namespace Q3DStudio - diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.txt b/src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.txt deleted file mode 100644 index 7c38c875..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSAttributeHashes.txt +++ /dev/null @@ -1,242 +0,0 @@ -name -type -opacity - -starttime -endtime - -sourcepath -importid -eyeball -position -position.x -position.y -position.z -rotation -rotation.x -rotation.y -rotation.z -scale -scale.x -scale.y -scale.z -pivot -pivot.x -pivot.y -pivot.z -rotationorder -orientation -shadowcaster -tessellation -edgetess -innertess - -orthographic -clipnear -clipfar -fov -fovhorizontal -scalemode -scaleanchor - -brightness -linearfade -expfade -lighttype -scope -lightdiffuse -lightdiffuse.r -lightdiffuse.g -lightdiffuse.b -lightambient.r -lightambient -lightambient.g -lightambient.b -lightspecular -lightspecular.r -lightspecular.g -lightspecular.b -areawidth -areaheight -castshadow -shdwbias -shdwfactor -shdwmapres -shdwmapfar -shdwmapfov -shdwfilter - -lightmapindirect -lightmapradiosity -lightmapshadow - -iblprobe - -shaderlighting -emissivepower -emissivecolor -emissivecolor.r -emissivecolor.g -emissivecolor.b -diffuse -diffuse.r -diffuse.g -diffuse.b -specularmap -specularmodel -speculartint -speculartint.r -speculartint.g -speculartint.b -ior -fresnelPower -specularamount -specularroughness -roughnessmap -blendmode -culling -zbufferwrite -diffusemap -diffusemap2 -diffusemap3 -specularreflection -opacitymap -emissivemap -emissivemap2 -bumpmap -bumpamount -normalmap -displacementmap -displaceamount -translucencymap -translucentfalloff -diffuselightwrap -referencedmaterial -vertexcolors - -rotationuv -positionu -positionv -scaleu -scalev -pivotu -pivotv -tilingmodehorz -tilingmodevert -mappingtype -mappingmode -subpresentation -uri - -transparent -progressiveaa -multisampleaa -temporalaa -blendtype -horzfields -left -leftunits -width -widthunits -right -rightunits -vertfields -top -topunits -height -heightunits -bottom -bottomunits -aostrength -aodistance -aosoftness -aobias -aosamplerate -aodither -shadowstrength -shadowdist -shadowsoftness -shadowbias -lightprobe -probebright -fastibl -probehorizon -probefov -lightprobe2 -probe2fade -probe2window -probe2pos -disabledepthtest -disabledepthprepass - -textcolor -textcolor.r -textcolor.g -textcolor.b -size -font -dropshadow -dropshadowstrength -dropshadowoffset -dropshadowoffsetx -dropshadowoffsety -dropshadowhorzalign -dropshadowvertalign -boundingbox -boundingbox.x -boundingbox.y -elide -tracking -leading -renderstyle -textstring -backcolor.r -backcolor.g -backcolor.b -texttype -usebackcolor -wordwrap -horzscroll -horzalign -vertscroll -vertalign -boxheight -boxwidth -remotestringsource -cachedtextstring -enableacceleratedfont - -BehaviorScripts -UICCustomObjType - -bgcolorenable -background -backgroundcolor.r -backgroundcolor.g -backgroundcolor.b - -pathtype -linearerror -edgetessamount -innertessamount -begincap -begincapoffset -begincapopacity -begincapwidth -endcap -endcapoffset -endcapopacity -endcapwidth -paintstyle -closed - -incomingangle -incomingdistance -outgoingdistance - -particletype -maxparticles -particlesize -lifetime - -controlledproperty diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSCommandEventTypes.h b/src/Runtime/Source/Runtime/Include/Qt3DSCommandEventTypes.h deleted file mode 100644 index 01a12b44..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSCommandEventTypes.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSHash.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Commands -//============================================================================== - -// Command types are 31-bit hash instead of 32-bit -// The 1 bit flag is being used to differentiate between a Command and an Event -// Commands trigger execution, both commands and events can trigger logic - -// Asset -const TEventCommandHash COMMAND_SETPROPERTY = CHash::HashEventCommand("COMMAND_SETPROPERTY"); -const TEventCommandHash COMMAND_FIREEVENT = CHash::HashEventCommand("COMMAND_FIREEVENT"); -const TEventCommandHash COMMAND_SCRIPTLET = CHash::HashEventCommand("COMMAND_SCRIPTLET"); -const TEventCommandHash COMMAND_PLAYSOUND = CHash::HashEventCommand("COMMAND_PLAYSOUND"); -const TEventCommandHash COMMAND_EMITSIGNAL = CHash::HashEventCommand("COMMAND_EMITSIGNAL"); - -// Time -const TEventCommandHash COMMAND_PLAY = CHash::HashEventCommand("COMMAND_PLAY"); -const TEventCommandHash COMMAND_PAUSE = CHash::HashEventCommand("COMMAND_PAUSE"); -const TEventCommandHash COMMAND_GOTOTIME = CHash::HashEventCommand("COMMAND_GOTOTIME"); -const TEventCommandHash COMMAND_GOTOTIMELABEL = CHash::HashEventCommand("COMMAND_GOTOTIMELABEL"); - -// Slide -const TEventCommandHash COMMAND_GOTOSLIDE = CHash::HashEventCommand("COMMAND_GOTOSLIDE"); -const TEventCommandHash COMMAND_GOTOSLIDENAME = CHash::HashEventCommand("COMMAND_GOTOSLIDENAME"); -const TEventCommandHash COMMAND_GOTONEXTSLIDE = CHash::HashEventCommand("COMMAND_GOTONEXTSLIDE"); -const TEventCommandHash COMMAND_GOTOPREVIOUSSLIDE = - CHash::HashEventCommand("COMMAND_GOTOPREVIOUSSLIDE"); -const TEventCommandHash COMMAND_BACKSLIDE = CHash::HashEventCommand("COMMAND_BACKSLIDE"); - -// Behavior -const TEventCommandHash COMMAND_CUSTOMACTION = CHash::HashEventCommand("COMMAND_CUSTOMACTION"); -const TEventCommandHash COMMAND_CUSTOMCALLBACK = CHash::HashEventCommand("COMMAND_CALLBACK"); -//============================================================================== -// Events -//============================================================================== - -// Slide Events -const TEventCommandHash EVENT_ONSLIDEENTER = CHash::HashEventCommand("onSlideEnter"); -const TEventCommandHash EVENT_ONSLIDEEXIT = CHash::HashEventCommand("onSlideExit"); - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSCommandHelper.h b/src/Runtime/Source/Runtime/Include/Qt3DSCommandHelper.h deleted file mode 100644 index 412a51a1..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSCommandHelper.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "Qt3DSIScriptBridge.h" - -namespace Q3DStudio { - -class CCommandHelper -{ -private: - CCommandHelper(); - CCommandHelper(const CCommandHelper &); - CCommandHelper &operator=(const CCommandHelper &); - virtual ~CCommandHelper(); - -public: - static bool SetupGotoSlideCommand(TElement &inElement, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs); - static bool SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlide, - const SScriptEngineGotoSlideArgs &inArgs); - -public: - static TElement *GetComponentParent(TElement *inParent); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSComponentManager.h b/src/Runtime/Source/Runtime/Include/Qt3DSComponentManager.h deleted file mode 100644 index 865b8aa9..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSComponentManager.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSIComponentManager.h" -#include "EASTL/hash_map.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { -class CTimePolicy; -class CPresentation; -struct SComponentTimePolicyOverride -{ - TElement *m_Element; - FLOAT m_TimeMultiplier; - TTimeUnit m_EndTime; - IComponentTimeOverrideFinishedCallback *m_TimeCallback; - SComponentTimePolicyOverride(TElement *inElement, FLOAT inMultiplier, TTimeUnit inEndTime, - IComponentTimeOverrideFinishedCallback *inCallback) - : m_Element(inElement) - , m_TimeMultiplier(inMultiplier) - , m_EndTime(inEndTime) - , m_TimeCallback(inCallback) - { - } - // Returns the local time and a boolean indicating if we have reached the end. - // Implemented in UICTimePolicy.cpp so that I can compare the CTimePolicy::ComputeTime method - // with - // SComponentTimePolicyOverride::ComputLocalTime method - eastl::pair ComputeLocalTime(CTimePolicy &inTimePolicy, - TTimeUnit inGlobalTime); - // Implemented in UICTimePolicy.cpp - void SetTime(CTimePolicy &inTimePolicy, TTimeUnit inLocalTime); -}; - -typedef eastl::hash_map TComponentGotoSlideDataMap; -typedef eastl::hash_map TComponentIntMap; - -//============================================================================== -/** - * The Component Manager is a factory and container of all components - * within the presentation. - */ -class CComponentManager : public IComponentManager -{ - CPresentation &m_Presentation; - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CComponentManager(IPresentation &inPresentation); - -public: // Slide - void GotoSlideIndex(TElement *inComponent, const SComponentGotoSlideData &inGotoData, - BOOL inSlideExit = true) override; - void GotoSlideName(TElement *inComponent, const TStringHash inSlideHashName) override; - void GoToBackSlide(TElement *inComponent) override; - void GoToNextSlide(TElement *inComponent, const INT32 inDecrement = 1) override; - void GoToPreviousSlide(TElement *inComponent, const INT32 inDecrement = 1) override; - void PlaythroughToSlide(TElement *inComponent); - - UINT8 GetSlideCount(TElement *inComponent) override; - UINT8 GetCurrentSlide(TElement *inComponent) override; - const CHAR *GetCurrentSlideName(TElement *inComponent) override; - - void OnElementDeactivated(TElement *inElement) override; - - void SetComponentTimeOverride(TElement *inElement, TTimeUnit inEndTime, FLOAT inInterpolation, - IComponentTimeOverrideFinishedCallback *inCallback) override; - - // Allows multiple gotoslide command operating on the same element to work correctly. - // This API is meant to fix a scenario where gotoslide is called multiple times in a frame - // on the same component. This isn't avoidable in some cases without very complex scene logic. - - // later calls override earlier calls - void SetupComponentGotoSlideCommand(TElement *inElement, - const SComponentGotoSlideData &inSlide) override; - bool HasComponentGotoSlideCommand(TElement *inElement) override; - SComponentGotoSlideData GetComponentGotoSlideCommand(TElement *inElement) override; - void ReleaseComponentGotoSlideCommand(TElement *inElement) override; - -public: // Time - void GoToTime(TElement *inComponent, const TTimeUnit inTime) override; - void SetPause(TElement *inComponent, const BOOL inPause) override; - void SetTimePolicy(TElement *inComponent, const TTimeUnit inLoopDuration, - const UINT32 inRepetitions, const BOOL inPingPong, const BOOL inPlayThrough) override; - - TTimeUnit ComputeComponentLocalTime(TElement *inComponent, const TTimeUnit inGlobalTime); - BOOL GetPause(TElement *inComponent) override; - BOOL GetPlayBackDirection(TElement *inComponent) override; - -protected: // Promotion - TComponent *GetComponent(TElement *inElement) override; - -private: - // Disabled Copy Construction - CComponentManager(const CComponentManager &); - CComponentManager &operator=(const CComponentManager &); - - TComponentGotoSlideDataMap m_ComponentInitialSlideMap; - TComponentGotoSlideDataMap m_ComponentGotoSlideMap; - TComponentIntMap m_PlaythroughOverrideMap; - - //============================================================================== - // Friends - //============================================================================== - friend class CSlideBuilder; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSElementHelper.h b/src/Runtime/Source/Runtime/Include/Qt3DSElementHelper.h deleted file mode 100644 index df2afddb..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSElementHelper.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -namespace qt3ds { -namespace runtime { - class IApplication; -} -} - -namespace Q3DStudio { - -class IPresentation; - -class CElementHelper -{ -private: - CElementHelper(); - CElementHelper(const CElementHelper &); - CElementHelper &operator=(const CElementHelper &); - virtual ~CElementHelper(); - -public: - static TElement *GetElement(qt3ds::runtime::IApplication &inApplication, - IPresentation *inDefaultPresentation, const char *inPath, - TElement *inStartElement = nullptr); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSElementSystem.h b/src/Runtime/Source/Runtime/Include/Qt3DSElementSystem.h deleted file mode 100644 index b9355c55..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSElementSystem.h +++ /dev/null @@ -1,606 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_ELEMENT_SYSTEM_H -#define QT3DS_ELEMENT_SYSTEM_H -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSAllocator.h" -#include "foundation/Utils.h" -#include "foundation/StringTable.h" -#include "Qt3DSKernelTypes.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSInvasiveSet.h" -#include "Qt3DSMetadata.h" - -// The qt3ds runtime element system contains the element graph and the data in the element -// graph. - -namespace Q3DStudio { -// class CPresentation; -class IPresentation; -class CTimePolicy; -} - -namespace qt3ds { -namespace foundation { - class IInStream; - class IOutStream; -} -} - -namespace qt3ds { -namespace runtime { - using namespace qt3ds::foundation; - using namespace qt3ds; - class IActivityZone; - namespace element { - struct SPropertyDesc - { - CRegisteredString m_Name; - Q3DStudio::EAttributeType m_Type; - SPropertyDesc() - : m_Type(Q3DStudio::ATTRIBUTETYPE_NONE) - { - } - SPropertyDesc(CRegisteredString inStr, Q3DStudio::EAttributeType inType) - : m_Name(inStr) - , m_Type(inType) - { - } - QT3DSU32 GetNameHash() const; // CHash::HashAttribute - Q3DStudio::SAttributeKey GetAttributeKey() const; - }; - - struct STypeDesc - { - CRegisteredString m_TypeName; - CRegisteredString m_SubtypeName; - // Properties are sorted so that we can quickly create new type descriptions - // when necessary. - NVConstDataRef m_Properties; - eastl::vector m_DynamicProperties; - - private: - QT3DSU32 m_HashValue; // Cached hash value for this type descriptor - public: - STypeDesc() - : m_HashValue(0) - { - } - bool operator==(const STypeDesc &inOther) const; - // Q3DStudio::CHash::HashAttribute - Option FindProperty(QT3DSU32 inNameHash) const; - Option FindProperty(CRegisteredString inName) const; - Option FindDynamicProperty(QT3DSU32 inNameHash) const; - void SetHashValue(); - QT3DSU32 HashCode() const { return m_HashValue; } - }; - - struct SActivationManagerNodeFlagValues - { - enum Enum { - TimeActive = 1 << 1, - TempTimeActive = 1 << 4, - ParticipatesInTimeGraph = 1 << 5, - Script = 1 << 6, - ChildDirty = 1 << 7, - }; - }; - - struct SActivationManagerNodeFlags : public NVFlags - { - bool IsTimeActive() const - { - return operator&(SActivationManagerNodeFlagValues::TimeActive); - } - void SetTimeActive(bool active) - { - clearOrSet(active, SActivationManagerNodeFlagValues::TimeActive); - } - - bool IsTempTimeActive() const - { - return operator&(SActivationManagerNodeFlagValues::TempTimeActive); - } - void SetTempTimeActive(bool value) - { - clearOrSet(value, SActivationManagerNodeFlagValues::TempTimeActive); - } - - // Is this item in the activation manager's scripts list. - bool HasScript() const { return operator&(SActivationManagerNodeFlagValues::Script); } - void SetHasScript(bool value) - { - clearOrSet(value, SActivationManagerNodeFlagValues::Script); - } - - bool IsChildDirty() const - { - return operator&(SActivationManagerNodeFlagValues::ChildDirty); - } - void SetChildDirty() { clearOrSet(true, SActivationManagerNodeFlagValues::ChildDirty); } - void ClearChildDirty() - { - clearOrSet(false, SActivationManagerNodeFlagValues::ChildDirty); - } - }; - - struct SElement; - - struct SActivationManagerNode - { - // IT may seem wasteful to always have start,end time on the node. We need to do this - // however - // in order to transmit information down the timeline at times. Furthermore the - // activation manager - // is free to mangle these times as it sees fit; unlike the attribute start,end time. - QT3DSU32 m_StartTime; - QT3DSU32 m_StopTime; - // Used by the activation manager specifically. - QT3DSU32 m_DirtyIndex; - - // If m_Flags.IsIndependent(), first child is implicitly zero and instead - // this records the time context index assocated with this element node. - // Else this records the first child index. - // These could perhaps be moved to the element flags except it breaks some isolation and - // it just doesn't seem worth it. - SActivationManagerNodeFlags m_Flags; - - SActivationManagerNode() - : m_StartTime(QT3DS_MAX_U32) - , m_StopTime(QT3DS_MAX_U32) - , m_DirtyIndex(QT3DS_MAX_U32) - { - } - }; - - struct SElementFlag : public NVFlags - { - void SetDirty(bool inDirty) { clearOrSet(inDirty, Q3DStudio::ELEMENTFLAG_DIRTY); } - bool IsDirty() const { return this->operator&(Q3DStudio::ELEMENTFLAG_DIRTY); } - - bool IsComponent() const { return this->operator&(Q3DStudio::ELEMENTFLAG_COMPONENT); } - - void SetExplicitActive(bool inValue) - { - clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE); - } - bool IsExplicitActive() const - { - return this->operator&(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE); - } - - void SetActive(bool inValue) - { - clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_GLOBALACTIVE); - } - bool IsActive() const { return this->operator&(Q3DStudio::ELEMENTFLAG_GLOBALACTIVE); } - - void SetPickEnabled(bool inValue) - { - clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_PICKENABLED); - } - bool IsPickEnabled() const - { - return this->operator&(Q3DStudio::ELEMENTFLAG_PICKENABLED); - } - - void SetPlayThrough(bool inValue) - { - clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_PLAYTHROUGH); - } - bool IsPlayThrough() const - { - return this->operator&(Q3DStudio::ELEMENTFLAG_PLAYTHROUGH); - } - - void SetScriptCallbacks(bool inValue) - { - clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS); - } - bool HasScriptCallbacks() const - { - return this->operator&(Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS); - } - - bool HasStartEndTime() const - { - return this->operator&(Q3DStudio::ELEMENTFLAG_TIMELINE); - } - }; - - typedef eastl::pair TPropertyDescAndValuePtr; - typedef eastl::pair - TPropertyDescAndConstValuePtr; - typedef eastl::pair TPropertyDescAndValue; - // There is probably some balance here between number of values in a group - // and number of groups. A heuristic of a large application would tell you - // the optimum number of values to groups. - struct SPropertyValueGroup - { - enum { - NumValues = 4, - }; - Q3DStudio::UVariant m_Data[4]; - SPropertyValueGroup *m_NextNode; - SPropertyValueGroup() - : m_NextNode(NULL) - { - for (QT3DSU32 idx = 0; idx < NumValues; ++idx) - m_Data[idx].m_INT32 = 0; - } - }; - - struct SElement - { - CRegisteredString m_Name; // const, do not set after creation. - CRegisteredString m_Path; - const STypeDesc *m_TypeDescription; ///< static information created on load time - // The property values are in order described in the type description. - SPropertyValueGroup *m_PropertyValues; - // dynamic section - STypeDesc *m_DynamicTypeDescription; ///< we may create this on the fly - SPropertyValueGroup *m_DynamicPropertyValues; - - protected: - SElementFlag m_Flags; // Setting these changes things. - public: - QT3DSU32 m_Handle; - QT3DSU32 m_ScriptID; ///< Superfluous, could use handle to link to script representation - QT3DSU32 m_Depth; ///< Distance from this node to the root of the graph. - SElement *m_Parent; ///< Parent element in activity graph - SElement *m_Sibling; ///< Next sibling element in activity graph - SElement *m_Child; ///< First child element in activity graph - void *m_Association; ///< Link to associated asset in scene - Q3DStudio::IPresentation *m_BelongedPresentation; - SActivationManagerNode m_ActivationManagerNode; - - SElement(const STypeDesc &inDesc) - : m_TypeDescription(&inDesc) - , m_PropertyValues(NULL) - , m_DynamicTypeDescription(NULL) - , m_DynamicPropertyValues(NULL) - , m_Handle(0) - , m_ScriptID(0) - , m_Depth(0) - , m_Parent(NULL) - , m_Sibling(NULL) - , m_Child(NULL) - , m_Association(NULL) - , m_BelongedPresentation(NULL) - { - } - QT3DSU32 GetHandle() const { return m_Handle; } - const STypeDesc &GetTypeDescription() const { return *m_TypeDescription; } - void SetTypeDescription(const STypeDesc *inDesc) { m_TypeDescription = inDesc; } - // Q3DStudio::CHash::HashString - QT3DSU32 GetNameHash() const; - const SPropertyValueGroup *GetFirstPropertyGroup() const { return m_PropertyValues; } - void SetFirstPropertyGroup(SPropertyValueGroup *inGroup) { m_PropertyValues = inGroup; } - - SPropertyValueGroup *&UnsafeGetFirstPropertyGroup() { return m_PropertyValues; } - - // In general, use these accessors for attributes, especially setting values. - // The other accessors are fast paths that do not: - // 1. Set dirty flags - // 2. Notify the activation zone of changes if setting start,end time. - // 3. Notify any other subsystems. - bool GetAttribute(QT3DSU32 inHashName, Q3DStudio::UVariant &outValue) const; - // Triggers updating various subcomponents based on attribute key. - void SetAttribute(const Q3DStudio::TAttributeHash inKey, - const Q3DStudio::UVariant inValue); - // Triggers updating various subcomponents without requiring a new property lookup. - void SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVariant inNewValue); - - // Q3DStudio::CHash::HashAttribute - Option FindPropertyIndex(QT3DSU32 inNameHash) const; - Option FindPropertyIndex(CRegisteredString inName) const; - - Option FindDynamicPropertyIndex(QT3DSU32 inNameHash) const; - - QT3DSU32 GetNumProperties() const; - QT3DSU32 GetAttributeCount() const { return GetNumProperties(); } - - QT3DSU32 GetNumDynamicProperties() const; - QT3DSU32 GetDynamicAttributeCount() const { return GetNumDynamicProperties(); } - - // Note that if you set a value then this object is dirty. - // Bypasses special checks in setAttribute. In general, use setAttribute. - Option GetPropertyByIndex(QT3DSU32 inIdx); - Option GetPropertyByIndex(QT3DSU32 inIdx) const; - - Option GetDynamicPropertyByIndex(QT3DSU32 inIdx); - - Q3DStudio::UVariant *FindPropertyValue(QT3DSU32 inNameHash) - { - Option idx = FindPropertyIndex(inNameHash); - if (idx.hasValue()) { - Option theVal = GetPropertyByIndex(idx); - if (theVal.hasValue()) - return theVal->second; - } - return NULL; - } - const Q3DStudio::UVariant *FindPropertyValue(QT3DSU32 inNameHash) const - { - Option idx = FindPropertyIndex(inNameHash); - if (idx.hasValue()) { - Option theVal = GetPropertyByIndex(idx); - if (theVal.hasValue()) - return theVal->second; - } - return NULL; - } - Q3DStudio::UVariant *FindPropertyValue(CRegisteredString inNameHash) - { - Option idx = FindPropertyIndex(inNameHash); - if (idx.hasValue()) { - Option theVal = GetPropertyByIndex(idx); - if (theVal.hasValue()) - return theVal->second; - } - return NULL; - } - - const Q3DStudio::UVariant *FindPropertyValue(CRegisteredString inNameHash) const - { - Option idx = FindPropertyIndex(inNameHash); - if (idx.hasValue()) { - Option theVal = GetPropertyByIndex(idx); - if (theVal.hasValue()) - return theVal->second; - } - return NULL; - } - - Option FindProperty(QT3DSU32 inNameHash) - { - Option idx = FindPropertyIndex(inNameHash); - if (idx.hasValue()) - return GetPropertyByIndex(*idx); - return Empty(); - } - - Option FindDynamicProperty(QT3DSU32 inNameHash) - { - Option idx = FindDynamicPropertyIndex(inNameHash); - if (idx.hasValue()) - return GetDynamicPropertyByIndex(*idx); - - return Empty(); - } - - SElement *GetParent() { return m_Parent; } - const SElement *GetParent() const { return m_Parent; } - SElement *GetSibling() { return m_Sibling; } - const SElement *GetSibling() const { return m_Sibling; } - SElement *GetChild() { return m_Child; } - const SElement *GetChild() const { return m_Child; } - CRegisteredString GetType() const { return m_TypeDescription->m_TypeName; } - bool IsComponent() const { return m_Flags.IsComponent(); } - - Q3DStudio::IPresentation *GetBelongedPresentation() { return m_BelongedPresentation; } - void SetBelongedPresentation(Q3DStudio::IPresentation &inPresentation) - { - m_BelongedPresentation = &inPresentation; - } - - // Set flags bypassing the dirty system *and* updates to the activity zone. - // do not do this unless you are sure you do not want any side effects. - SElementFlag &Flags() { return m_Flags; } - - // User flag that is set and is persistent - void SetExplicitActive(bool inValue) - { - SetFlag(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE, inValue); - } - bool IsExplicitActive() const { return m_Flags.IsExplicitActive(); } - - // Flag set by the activity manager. - void SetActive(bool inValue) { SetFlag(Q3DStudio::ELEMENTFLAG_GLOBALACTIVE, inValue); } - bool GetActive() const { return m_Flags.IsActive(); } - - void SetPickEnabled(bool inValue) - { - SetFlag(Q3DStudio::ELEMENTFLAG_PICKENABLED, inValue); - } - bool IsPickEnabled() const { return m_Flags.IsPickEnabled(); } - - void SetPlayThrough(bool inValue) - { - SetFlag(Q3DStudio::ELEMENTFLAG_PLAYTHROUGH, inValue); - } - bool IsPlayThrough() const { return m_Flags.IsPlayThrough(); } - - void SetScriptCallbacks(bool inValue) - { - SetFlag(Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS, inValue); - } - bool HasScriptCallbacks() const { return m_Flags.HasScriptCallbacks(); } - - bool IsDirty() const { return m_Flags.IsDirty(); } - - bool GetFlag(Q3DStudio::EElementFlag inFlag) const { return m_Flags.operator&(inFlag); } - - void SetDirty(); - void SetFlag(Q3DStudio::EElementFlag inFlag, bool inValue); - void SetFlag(Q3DStudio::EElementFlag inFlag, int inValue) - { - SetFlag(inFlag, inValue ? true : false); - } - qt3ds::runtime::IActivityZone &GetActivityZone() const; - bool HasActivityZone() const; - // Floating point number differences above this trigger a setDirty call. - static float SmallestDifference() { return 0.000001f; } - SElement &GetComponentParent(); - const SElement &GetComponentParent() const; - SElement *FindChild(QT3DSU32 inNameHash); - // Get the time of my first noncomponent child or - // my time if I am not a component. - Q3DStudio::TTimeUnit GetInnerTime() const; - // Get the time I am animating at. - Q3DStudio::TTimeUnit GetOuterTime() const; - bool IsDescendent(SElement &inPossibleParent) const; - void *GetAssociation() const { return m_Association; } - void SetAssociation(void *inAssoc) { m_Association = inAssoc; } - QT3DSU32 GetUncachedDepth() const - { - if (m_Parent) - return m_Parent->GetUncachedDepth() + 1; - return 0; - } - void SetDepth() { m_Depth = GetUncachedDepth(); } - QT3DSU32 Depth() const { return m_Depth; } - - bool IsUserActive() const; - - bool IsIndependent() const; - - bool IsGlobalActive() const; - // This may require a mutex to be held. - void SetGlobalActive(bool active); - - bool IsTimeActive() const - { - if (m_Parent != NULL) - return m_ActivationManagerNode.m_Flags.IsTimeActive(); - return true; - } - - bool DoesParticipateInTimeGraph() const { return m_Flags.HasStartEndTime(); } - - bool IsGlobalActive(bool inParentActive) const - { - bool ta = IsTimeActive(); - bool ua = IsUserActive(); - - return ta && ua && inParentActive; - } - }; - - struct SGetElementNodeDirtyIndex - { - QT3DSU32 operator()(const SElement &inNode) - { - return inNode.m_ActivationManagerNode.m_DirtyIndex; - } - }; - struct SSetElementNodeDirtyIndex - { - void operator()(SElement &inNode, QT3DSU32 val) - { - inNode.m_ActivationManagerNode.m_DirtyIndex = val; - } - }; - - struct SActivationManagerNodeDirtyList - : public InvasiveSet - { - typedef InvasiveSet - TBaseType; - SActivationManagerNodeDirtyList(NVAllocatorCallback &callback) - : TBaseType(callback, "SActivationManagerNodeDirtyList") - { - } - }; - - struct SComponent : public SElement - { - Q3DStudio::SAlignedTimeUnit m_BeginTime; - Q3DStudio::SAlignedTimeUnit m_Duration; - - // Slide related - QT3DSU8 m_SlideCount; ///< Number of slides starting from base index - QT3DSU8 m_CurrentSlide; ///< Current slide number - QT3DSU8 m_PreviousSlide; ///< Previous slide number - SComponent(const STypeDesc &inDesc) - : SElement(inDesc) - , m_SlideCount(0) - , m_CurrentSlide(0) - , m_PreviousSlide(0) - { - } - - QT3DSU8 GetCurrentSlide() const { return m_CurrentSlide; } - void SetCurrentSlide(QT3DSU8 inSlide) - { - m_PreviousSlide = m_CurrentSlide; - m_CurrentSlide = inSlide; - } - QT3DSU8 GetSlideCount() const { return m_SlideCount; } - QT3DSU8 GetPreviousSlide() const { return m_PreviousSlide; } - bool GetPaused() const; - bool GetPlayBackDirection() const; - Q3DStudio::CTimePolicy &GetTimePolicy(); - const Q3DStudio::CTimePolicy &GetTimePolicy() const; - }; - } - // Global store of all elements, values. - class IElementAllocator : public NVRefCounted - { - public: - // Performs coalesing of element types so that there are the least number of type - // descriptions - // Certain properties, like name, eyeball, are never in the property description. - virtual element::SElement & - CreateElement(CRegisteredString inName, CRegisteredString inType, - CRegisteredString inSubType, - NVConstDataRef inPropertyDescriptions, - Q3DStudio::IPresentation *inPresentation, element::SElement *inParent, - bool inIsComponent) = 0; - - virtual void ReleaseElement(element::SElement &inElement, bool inRecurse) = 0; - - virtual Option - CreateDynamicProperty(Q3DStudio::IRuntimeMetaData &theMetaData, element::SElement &element, - CRegisteredString inName) = 0; - - virtual element::SElement *FindElementByHandle(QT3DSU32 inElementHandle) = 0; - // Returns an element pointer that when added to the return value of load will be a valid - // element. - virtual element::SElement * - GetRemappedElementAddress(element::SElement *inElement) const = 0; - virtual const element::STypeDesc * - GetRemappedTypeDescAddress(const element::STypeDesc *inTypeDesc) const = 0; - // If load is successful, then returns an address that can be added to elements and the root - // element. - - static IElementAllocator &CreateElementAllocator(NVFoundationBase &inFoundation, - IStringTable &inStringTable); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSEvent.h b/src/Runtime/Source/Runtime/Include/Qt3DSEvent.h deleted file mode 100644 index aef317a5..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSEvent.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSKernelTypes.h" -#include "Qt3DSElementSystem.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -/// Common structure used as both Events and Commands -struct SEventCommand -{ - TElement *m_Target; ///< The target of this action - TEventCommandHash m_Type; ///< Type of action to perform - UVariant m_Arg1; ///< Argument 1 - UVariant m_Arg2; ///< Argument 2 - UINT8 m_Arg1Type; ///< EAttributeType for arg1 variant - UINT8 m_Arg2Type; ///< EAttributeType for arg2 variant - - BOOL m_IsEvent : 1; ///< This is an Event or Command - BOOL m_BubbleUp : 1; ///< Bubble up to scene parent (2.4.2: theEvent:stopPropagation) - BOOL m_BubbleDown : 1; ///< Bubble down to scene children (2.4.2: theEvent:stopPropagation) - BOOL m_Done : 1; ///< Stop further handling (2.4.3: theEvent:stopImmediatePropagation) - - UINT8 m_Unused; ///< (padding) -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSEventCallbacks.h b/src/Runtime/Source/Runtime/Include/Qt3DSEventCallbacks.h deleted file mode 100644 index 5c17477d..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSEventCallbacks.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "Qt3DSEvent.h" -#include "Qt3DSMemory.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Typedefs -//============================================================================== -typedef void (*TEventCallback)(void *inContextData, SEventCommand &ioEvent); - -//============================================================================== -/** - * Manages the various events callbacks in the system. It fires the - * registered callbacks when an event was triggered. - */ -class CEventCallbacks -{ - //============================================================================== - // Structs - //============================================================================== -protected: - struct SCallbackEntry - { - TEventCallback m_Function; ///< Callback function pointer - void *m_ContextData; ///< User data - }; - typedef CArray TCallbackList; ///< Array of callbacks regisgtered - - struct SEventCallbackEntry - { - SEventCallbackEntry() - : m_EventHash(0) - { - } - ~SEventCallbackEntry() {} - - TEventCommandHash m_EventHash; ///< The event of interest - TCallbackList m_Callbacks; ///< List of callbacks listening to this event - - private: // Disabled Copy Construction - SEventCallbackEntry(const SEventCallbackEntry &); - SEventCallbackEntry &operator=(const SEventCallbackEntry &); - }; - typedef CArray TEventCallbacksList; ///< Array of events with callback - - struct SElementCallbackEntry - { - SElementCallbackEntry() - : m_Element(NULL) - { - } - ~SElementCallbackEntry() - { - FOR_ARRAY(SEventCallbackEntry *, theEntry, m_EventEntries) - Q3DStudio_delete(*theEntry, SEventCallbackEntry); - } - - TElement *m_Element; ///< Element to monitor for event - TEventCallbacksList m_EventEntries; ///< List of events listened on this element - - private: // Disabled Copy Construction - SElementCallbackEntry(const SElementCallbackEntry &); - SElementCallbackEntry &operator=(const SElementCallbackEntry &); - }; - typedef CArray - TElementCallbacksList; ///< Array of elements with callbacks - - //============================================================================== - // Fields - //============================================================================== -protected: - TElementCallbacksList m_EventCallbacksList; ///< List of event callbacks - TCallbackList m_CallbackList; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CEventCallbacks(); - ~CEventCallbacks(); - -public: // Registration - void RegisterCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData); - BOOL UnregisterCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData, BOOL &outLast); - void UnregisterAllCallbacks(); - -public: // Operation - void FireCallbacks(SEventCommand &ioEvent); - -protected: - void PerformCallbacks(TCallbackList &inCallbackList, SEventCommand &ioEvent); - -private: // Disabled Copy Construction - CEventCallbacks(const CEventCallbacks &); - CEventCallbacks &operator=(const CEventCallbacks &); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSFrameworkTypes.h b/src/Runtime/Source/Runtime/Include/Qt3DSFrameworkTypes.h deleted file mode 100644 index 8cb5c3b8..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSFrameworkTypes.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTypes.h" -#include "Qt3DSArray.h" -#include "Qt3DSVector3.h" -#include "Qt3DSMatrix.h" -#include "Qt3DSBoundingBox.h" -#include "Qt3DSKernelTypes.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSIComponentManager.h b/src/Runtime/Source/Runtime/Include/Qt3DSIComponentManager.h deleted file mode 100644 index 8185da2d..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSIComponentManager.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSTimePolicy.h" -#include "foundation/Qt3DSOption.h" - -//============================================================================== -// Includes -//============================================================================== - -namespace qt3ds { -namespace runtime { - namespace element { - struct TElement; - struct TComponent; - } -} -} -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -struct IComponentTimeOverrideFinishedCallback -{ -protected: - virtual ~IComponentTimeOverrideFinishedCallback() {} -public: - virtual void OnTimeFinished() = 0; - virtual void Release() = 0; -}; - -typedef qt3ds::foundation::Option TTimePolicyModeOption; -typedef qt3ds::foundation::Option TInt32Option; -typedef qt3ds::foundation::Option TULongOption; -typedef qt3ds::foundation::Option TBoolOption; - -struct SComponentGotoSlideData -{ - INT32 m_Slide; - TTimePolicyModeOption m_Mode; - //-2 means previous, -1 means next, 1-N means slide - TInt32Option m_PlaythroughTo; - TULongOption m_StartTime; - FLOAT m_Rate; - bool m_Reverse; - TBoolOption m_Paused; - - // No mode means use the mode in the slide data. - SComponentGotoSlideData(INT32 inSlide = 0, - TTimePolicyModeOption inMode = TTimePolicyModeOption(), - TInt32Option inPlayThrough = TInt32Option(), - TULongOption inStartTime = TULongOption(), FLOAT inRate = 1.0f, - bool inReverse = false, TBoolOption inPaused = TBoolOption()) - : m_Slide(inSlide) - , m_Mode(inMode) - , m_PlaythroughTo(inPlayThrough) - , m_StartTime(inStartTime) - , m_Rate(inRate) - , m_Reverse(inReverse) - , m_Paused(inPaused) - { - } -}; - -//============================================================================== -/** - * @interface IComponentManager - * Base interface of the container of all the components in the presentation. - * This specify the basic operations required to implement a Component manager - * object that works well with the kernel. - */ -class IComponentManager -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - virtual ~IComponentManager() {} - -public: // Promotion - virtual TComponent *GetComponent(TElement *inElement) = 0; - -public: // Slides - virtual void GotoSlideIndex(TElement *inComponent, const SComponentGotoSlideData &inGotoData, - BOOL inSlideExit = true) = 0; - virtual void GotoSlideName(TElement *inComponent, const TStringHash inSlideHashName) = 0; - virtual void GoToBackSlide(TElement *inComponent) = 0; - virtual void GoToNextSlide(TElement *inComponent, const INT32 inDecrement = 1) = 0; - virtual void GoToPreviousSlide(TElement *inComponent, const INT32 inDecrement = 1) = 0; - - virtual UINT8 GetSlideCount(TElement *inComponent) = 0; - virtual UINT8 GetCurrentSlide(TElement *inComponent) = 0; - virtual const CHAR *GetCurrentSlideName(TElement *inComponent) = 0; - - virtual void OnElementDeactivated(TElement *inElement) = 0; - - virtual void SetComponentTimeOverride(TElement *inElement, TTimeUnit inEndTime, - FLOAT inInterpolation, - IComponentTimeOverrideFinishedCallback *inCallback) = 0; - - virtual void SetupComponentGotoSlideCommand(TElement *inElement, - const SComponentGotoSlideData &inGotoSlideData) = 0; - virtual bool HasComponentGotoSlideCommand(TElement *inElement) = 0; - virtual SComponentGotoSlideData GetComponentGotoSlideCommand(TElement *inElement) = 0; - virtual void ReleaseComponentGotoSlideCommand(TElement *inElement) = 0; - -public: // Time - virtual void GoToTime(TElement *inComponent, const TTimeUnit inTime) = 0; - virtual void SetPause(TElement *inComponent, const BOOL inPause) = 0; - virtual void SetTimePolicy(TElement *inComponent, const TTimeUnit inLoopDuration, - const UINT32 inRepetitions, const BOOL inPingPong, - const BOOL inPlayThrough) = 0; - - virtual BOOL GetPause(TElement *inComponent) = 0; - virtual BOOL GetPlayBackDirection(TElement *inComponent) = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSIInputSystem.h b/src/Runtime/Source/Runtime/Include/Qt3DSIInputSystem.h deleted file mode 100644 index 6cd201fb..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSIInputSystem.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "Qt3DSInputEngine.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Input system interface - */ -class IInputSystem : public CInputEngine -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - virtual ~IInputSystem() {} - -public: // Processing - virtual void UpdateInput() = 0; - virtual void ProcessInput() = 0; - -protected: // Input System handler - virtual void CheckMouseEvent() = 0; - virtual void CheckKeyboardEvent() = 0; - virtual void CheckJoystickEvent() = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSIScene.h b/src/Runtime/Source/Runtime/Include/Qt3DSIScene.h deleted file mode 100644 index 8872b93f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSIScene.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/StringTable.h" -#include "foundation/Qt3DSBounds3.h" -#include "Qt3DSBoundingBox.h" -namespace qt3ds { -namespace render { - class IImageLoadListener; -} -} - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class IPresentation; -class RuntimeMatrix; -struct SPickFrame; - -//============================================================================== -/** -* @interface IScene -* -* Runtime interface to the renderer's representation of a presentation. Scenes are -* created by the SceneManager and rendered via a lower level rendering system. -*/ -struct STextSizes -{ - INT32 m_Width; - INT32 m_Height; - STextSizes() - : m_Width(0) - , m_Height(0) - { - } - STextSizes(INT32 w, INT32 h) - : m_Width(w) - , m_Height(h) - { - } -}; - -struct SMousePosition -{ - INT32 m_X; - INT32 m_Y; - SMousePosition(INT32 x, INT32 y) - : m_X(x) - , m_Y(y) - { - } - SMousePosition() - : m_X(0) - , m_Y(0) - { - } -}; - -struct SCameraRect -{ - float m_Left; - float m_Top; - float m_Right; - float m_Bottom; - SCameraRect(float l = 0.0f, float t = 0.0f, float r = 0.0f, float b = 0.0f) - : m_Left(l) - , m_Top(t) - , m_Right(r) - , m_Bottom(b) - { - } - - bool IsValid() const { return fabs(m_Right - m_Left) > 0.0f; } -}; - -class IScene -{ - //============================================================================== - // Methods - //============================================================================== -protected: - virtual ~IScene() {} - -public: // Base Interface - virtual IPresentation &GetPresentation() = 0; - - virtual void SetUserData(void *inUserData) = 0; - virtual void *GetUserData() = 0; - - // virtual void Clone( TElementList& inElements, TElementList& inElementClones, TElement* - // inNewParent = NULL ) = 0; - virtual void CalculateGlobalTransform(TElement *inElement, RuntimeMatrix &outTransform) = 0; - virtual void SetLocalTransformMatrix(TElement *inElement, const RuntimeMatrix &inTransform) = 0; - // Get bounding box in global space - virtual CBoundingBox GetBoundingBox(TElement *inElement, bool inSelfOnly) = 0; - // Get bounding box in local space. - virtual CBoundingBox GetLocalBoundingBox(TElement *inElement, bool inSelfOnly) = 0; - - // The final argument, inHasTransparency has 3 possible values, - // 0 for no transparency, 1 for hasTransparency, -1 for unknown - virtual void SetTextureData(TElement *inElement, const unsigned char *inBuffer, - INT32 inBufferLength, INT32 inWidth, INT32 inHeight, - qt3ds::render::NVRenderTextureFormats::Enum inFormat, - INT32 inHasTransparency = -1) = 0; - - virtual bool CreateOrSetMeshData(const char *inPathStr, unsigned char *vertData, - unsigned int numVerts, unsigned int vertStride, - unsigned int *indexData, unsigned int numIndices, - qt3ds::NVBounds3 &objBounds) = 0; - - virtual STextSizes MeasureText(TElement *inElement, const char *inTextStr) = 0; - - virtual STextSizes GetPresentationDesignDimensions() = 0; - // If the rect's right - left == 0.0, this method failed. Possibly because the layer is just - // direct-rendering - // a sub-presentation. - virtual SCameraRect GetCameraBounds(TElement &inElement) = 0; - - virtual void PositionToScreen(TElement &inElement, qt3ds::QT3DSVec3 &inPos, - qt3ds::QT3DSVec3 &outScreen) = 0; - virtual void ScreenToPosition(TElement &inElement, qt3ds::QT3DSVec3 &inScreen, - qt3ds::QT3DSVec3 &outPos) = 0; - - // This is the best place for now... - virtual void GetImageInfoFromRenderEngine(TElement *inElement, INT32 &ioWidth, - INT32 &ioHeight) = 0; - - virtual qt3ds::foundation::CRegisteredString RegisterStr(const char *inStr) = 0; - - virtual Q3DStudio::INT32 - LoadImageBatch(qt3ds::foundation::CRegisteredString *inFullPaths, INT32 inNumPaths, - qt3ds::foundation::CRegisteredString inDefaultImage, - qt3ds::render::IImageLoadListener *inLoadCallback = NULL) = 0; - - virtual SMousePosition WindowToPresentation(const SMousePosition &inWindowPos) = 0; - - virtual void RegisterOffscreenRenderer(const char *inKey) = 0; - - virtual void Release() = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSIScriptBridge.h b/src/Runtime/Source/Runtime/Include/Qt3DSIScriptBridge.h deleted file mode 100644 index 6dd04074..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSIScriptBridge.h +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSIComponentManager.h" -#include "EASTL/vector.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSRefCounted.h" -//============================================================================== -// Namespace -//============================================================================== -namespace qt3ds { -namespace runtime { - class IApplication; - class IApplicationCore; -} -} -namespace qt3ds { -namespace state { - namespace debugger { - class IMultiProtocolSocket; - } -} -} -namespace qt3ds { -namespace render { - class IThreadPool; -} -} - -struct script_State; - -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -struct SEventCommand; -class IPresentation; - -//============================================================================== -/** - * @interface IScriptBridge - * @brief Callback and load interface for a script engine. - */ - -class IScriptTableProvider -{ -protected: - virtual ~IScriptTableProvider() {} -public: - virtual void CreateTable(script_State *inState) = 0; -}; - -struct SScriptEngineGotoSlideArgs -{ - TTimePolicyModeOption m_Mode; - //-2 means previous, -1 means next, 1-N means slide - const char *m_PlaythroughTo; - TULongOption m_StartTime; - float m_Rate; - bool m_Reverse; - TBoolOption m_Paused; - SScriptEngineGotoSlideArgs() - : m_PlaythroughTo(NULL) - , m_Rate(1.0f) - , m_Reverse(false) - { - } -}; - -class CScriptEngineCallFunctionArgRetriever -{ -public: - CScriptEngineCallFunctionArgRetriever(const char *inArguments) - : m_ArgumentString(inArguments) - { - } - virtual ~CScriptEngineCallFunctionArgRetriever() {} - // Retrieve argument - // Return value: -1 error; otherwise it indicates argument count - virtual int RetrieveArgument(script_State *inState); - virtual eastl::string GetArgDescription(); - -protected: - const char *m_ArgumentString; -}; - -class IScriptBridge : public qt3ds::foundation::NVRefCounted -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - virtual ~IScriptBridge() {} - -public: // thread - // After this call all public functions are protected by a mutex - virtual void EnableMultithreadedAccess() = 0; - // After this call all public functions are not threadsafe. - virtual void DisableMultithreadedAccess() = 0; - -public: // Settings - virtual void SetApplicationCore(qt3ds::runtime::IApplicationCore &inApplication) = 0; - virtual void SetApplication(qt3ds::runtime::IApplication &inApplication) = 0; - -public: // Scripts - // Both loads script, create an self table -> scriptIndex in a behaviors table - // LoadScript goes further by registering scriptIndex->inPresentation, and inOwner->m_ScriptID= - // scriptIndex - virtual void LoadScript(IPresentation *inPresentation, TElement *inOwner, - const CHAR *inName) = 0; - virtual Q3DStudio::INT32 InitializeApplicationBehavior(const char *inProjectRelativePath) = 0; - -public: // Script functions and Callbacks - virtual void ProcessFrameCallbacks(IPresentation *inPresentation) = 0; - // Call a member function inFnName from self table whose script index is given by inApp - virtual void ExecuteApplicationScriptFunction(Q3DStudio::INT32 inApp, const char *inFnName) = 0; - virtual void CallFunction(const char *behavior, const char *handler, - CScriptEngineCallFunctionArgRetriever &inArgRetriever) = 0; - -public: // Custom Actions - virtual void ProcessSignal(IPresentation *inPresentation, - const SEventCommand &inCommand) = 0; - virtual void ProcessCustomActions(IPresentation *inPresentation, - const SEventCommand &inCommand) = 0; - virtual void ProcessCustomCallback(IPresentation *inPresentation, - const SEventCommand &inCommand) = 0; - -public: // Elements - // Use inProvider to create a new table and associate with inElement: currently a render plugin - // element this mimics render plugin as an behavior element - virtual void SetTableForElement(TElement &inElement, IScriptTableProvider &inProvider) = 0; - virtual void SetAttribute(const char *element, const char *attName, const char *value) = 0; - virtual void FireEvent(const char *element, const char *evtName) = 0; - virtual void SetDataInputValue(const QString &name, const QVariant &value) = 0; - -public: // Components - virtual void GotoSlide(const char *component, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs) = 0; - virtual void GotoSlideRelative(const char *component, bool inNextSlide, bool inWrap, - const SScriptEngineGotoSlideArgs &inArgs) = 0; - -public: // Presentation - virtual void SetPresentationAttribute(const char *presId, const char *attName, - const char *attValue) = 0; - -public: // Multimedia - virtual bool PlaySoundFile(const char *soundPath) = 0; - -public: // Miscellaneous - virtual void EnableDebugging(qt3ds::state::debugger::IMultiProtocolSocket &socket) = 0; - virtual void EnableProfiling() = 0; - virtual void StepGC() = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSIStateful.h b/src/Runtime/Source/Runtime/Include/Qt3DSIStateful.h deleted file mode 100644 index 0eca293e..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSIStateful.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSArray.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -class IStatefulStackBase -{ -public: - virtual void PushState() = 0; - virtual void PopState() = 0; -}; - -template -class IStatefulStack : public IStatefulStackBase -{ -public: - IStatefulStack(T &inStateProperty) - : m_StateProperty(inStateProperty) - { - } - - virtual ~IStatefulStack(){}; - -public: - virtual void PushState() { m_States.Push(m_StateProperty); } - virtual void PopState() { m_StateProperty = m_States.Pop(); } - -protected: - T &m_StateProperty; - CArray m_States; -}; - -} // namespace Q3DStudio \ No newline at end of file diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSIText.h b/src/Runtime/Source/Runtime/Include/Qt3DSIText.h deleted file mode 100644 index c4694fe2..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSIText.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class CWorld; -class CRenderStateManager; - -class IText -{ -public: // Text update - virtual void Update(CWorld &inWorld, CVector3 &outBoxMin, CVector3 &outBoxMax) = 0; - virtual void Apply(CRenderStateManager &inRenderStateManager) = 0; - static IText *GetIText(INT32 inAssociation); -}; - -} // namespace Q3DStudio \ No newline at end of file diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSInputDefs.h b/src/Runtime/Source/Runtime/Include/Qt3DSInputDefs.h deleted file mode 100644 index 447e424b..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSInputDefs.h +++ /dev/null @@ -1,413 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Mouse button state flags - * There is some discrepancy between mouse state and mouse events. - * - * Mouse button state refers to the actual state of the button as captured - * by the input engine. The logical states are: up, pressed, down and released. - * - * Mouse events are generated by Kernel (in CKernel::SetPickFrame), and current - * support is only for pressed and released. This translates to the respective - * MOUSE_DOWN and MOUSE_UP. - * - * Therefore, a mapping would be: - * STATE_MOUSE_PRESSED -> EVENT_MOUSE_DOWN - * STATE_MOUSE_RELEASED -> EVENT_MOUSE_UP - * STATE_MOUSE_UP -> No corresponding event - * STATE_MOUSE_DOWN -> No corresponding event - * - */ -enum EMouseInputFlags { - NO_INPUT = 0, - // - LMOUSE_PRESSED = 1 << 0, - LMOUSE_RELEASED = 1 << 1, - MMOUSE_PRESSED = 1 << 2, - MMOUSE_RELEASED = 1 << 3, - RMOUSE_PRESSED = 1 << 4, - RMOUSE_RELEASED = 1 << 5, - // - LMOUSE_DOWN = 1 << 6, - LMOUSE_UP = 1 << 7, - MMOUSE_DOWN = 1 << 8, - MMOUSE_UP = 1 << 9, - RMOUSE_DOWN = 1 << 10, - RMOUSE_UP = 1 << 11, - MOUSEBUTTONCOUNT = 3, // left, middle, right - could potentially have more mouse buttons - - HSCROLLWHEEL = 1 << 12, - VSCROLLWHEEL = 1 << 13, -}; - -//============================================================================== -/** - * Key code/index to SInputFrame::m_KeyStates - */ -// enum EKeyCode -//{ -// KEY_NOKEY = 0x00, -// KEY_ESCAPE, -// KEY_1, -// KEY_2, -// KEY_3, -// KEY_4, -// KEY_5, -// KEY_6, -// KEY_7, -// KEY_8, -// KEY_9, -// KEY_0, -// KEY_MINUS, /* - on main keyboard */ -// KEY_EQUALS, -// KEY_BACK, /* backspace */ -// KEY_TAB, -// KEY_Q, -// KEY_W, -// KEY_E, -// KEY_R, -// KEY_T, -// KEY_Y, -// KEY_U, -// KEY_I, -// KEY_O, -// KEY_P, -// KEY_LBRACKET, -// KEY_RBRACKET, -// KEY_RETURN, /* Enter on main keyboard */ -// KEY_LCONTROL, -// KEY_A, -// KEY_S, -// KEY_D, -// KEY_F, -// KEY_G, -// KEY_H, -// KEY_J, -// KEY_K, -// KEY_L, -// KEY_SEMICOLON, -// KEY_APOSTROPHE, -// KEY_GRAVE, /* accent grave */ -// KEY_LSHIFT, -// KEY_BACKSLASH, -// KEY_Z, -// KEY_X, -// KEY_C, -// KEY_V, -// KEY_B, -// KEY_N, -// KEY_M, -// KEY_COMMA, -// KEY_PERIOD, /* . on main keyboard */ -// KEY_SLASH, /* / on main keyboard */ -// KEY_RSHIFT, -// KEY_MULTIPLY, /* * on numeric keypad */ -// KEY_LMENU, /* left Alt */ -// KEY_SPACE, -// KEY_CAPITAL, -// KEY_F1, -// KEY_F2, -// KEY_F3, -// KEY_F4, -// KEY_F5, -// KEY_F6, -// KEY_F7, -// KEY_F8, -// KEY_F9, -// KEY_F10, -// KEY_NUMLOCK, -// KEY_SCROLL, /* Scroll Lock */ -// KEY_NUMPAD7, -// KEY_NUMPAD8, -// KEY_NUMPAD9, -// KEY_SUBTRACT, /* - on numeric keypad */ -// KEY_NUMPAD4, -// KEY_NUMPAD5, -// KEY_NUMPAD6, -// KEY_ADD, /* + on numeric keypad */ -// KEY_NUMPAD1, -// KEY_NUMPAD2, -// KEY_NUMPAD3, -// KEY_NUMPAD0, -// KEY_DECIMAL, /* . on numeric keypad */ -// KEY_OEM_102, /* <> or \| on RT 102-key keyboard (Non-U.S.) */ -// KEY_F11, -// KEY_F12, -// KEY_F13, /* (NEC PC98) */ -// KEY_F14, /* (NEC PC98) */ -// KEY_F15, /* (NEC PC98) */ -// KEY_KANA, /* (Japanese keyboard) */ -// KEY_ABNT_C1, /* /? on Brazilian keyboard */ -// KEY_CONVERT, /* (Japanese keyboard) */ -// KEY_NOCONVERT, /* (Japanese keyboard) */ -// KEY_YEN, /* (Japanese keyboard) */ -// KEY_ABNT_C2, /* Numpad . on Brazilian keyboard */ -// KEY_NUMPADEQUALS, /* = on numeric keypad (NEC PC98) */ -// KEY_PREVTRACK, /* Previous Track -// (DIK_CIRCUMFLEX on Japanese keyboard) */ -// KEY_AT, /* (NEC PC98) */ -// KEY_COLON, /* (NEC PC98) */ -// KEY_UNDERLINE, /* (NEC PC98) */ -// KEY_KANJI, /* (Japanese keyboard) */ -// KEY_STOP, /* (NEC PC98) */ -// KEY_AX, /* (Japan AX) */ -// KEY_UNLABELED, /* (J3100) */ -// KEY_NEXTTRACK, /* Next Track */ -// KEY_NUMPADENTER, /* Enter on numeric keypad */ -// KEY_RCONTROL, -// KEY_MUTE, /* Mute */ -// KEY_CALCULATOR, /* Calculator */ -// KEY_PLAYPAUSE, /* Play / Pause */ -// KEY_MEDIASTOP, /* Media Stop */ -// KEY_VOLUMEDOWN, /* Volume - */ -// KEY_VOLUMEUP, /* Volume + */ -// KEY_WEBHOME, /* Web home */ -// KEY_NUMPADPERIOD, /* . on numeric keypad (NEC PC98) */ -// KEY_DIVIDE, /* / on numeric keypad */ -// KEY_SYSRQ, -// KEY_RMENU, /* right Alt */ -// KEY_PAUSE, /* Pause */ -// KEY_HOME, /* Home on arrow keypad */ -// KEY_UP, /* UpArrow on arrow keypad */ -// KEY_PRIOR, /* PgUp on arrow keypad */ -// KEY_LEFT, /* LeftArrow on arrow keypad */ -// KEY_RIGHT, /* RightArrow on arrow keypad */ -// KEY_END, /* End on arrow keypad */ -// KEY_DOWN, /* DownArrow on arrow keypad */ -// KEY_NEXT, /* PgDn on arrow keypad */ -// KEY_INSERT, /* Insert on arrow keypad */ -// KEY_DELETE, /* Delete on arrow keypad */ -// KEY_LWIN, /* Left Windows key */ -// KEY_RWIN, /* Right Windows key */ -// KEY_APPS, /* AppMenu key */ -// KEY_POWER, /* System Power */ -// KEY_SLEEP, /* System Sleep */ -// KEY_WAKE, /* System Wake */ -// KEY_WEBSEARCH, /* Web Search */ -// KEY_WEBFAVORITES, /* Web Favorites */ -// KEY_WEBREFRESH, /* Web Refresh */ -// KEY_WEBSTOP, /* Web Stop */ -// KEY_WEBFORWARD, /* Web Forward */ -// KEY_WEBBACK, /* Web Back */ -// KEY_MYCOMPUTER, /* My Computer */ -// KEY_MAIL, /* Mail */ -// KEY_MEDIASELECT, /* Media Select */ -// // -// KEY_TOTAL_COUNT -//}; - -typedef enum _EKeyCode { - KEY_NOKEY = 0, - KEY_ESCAPE, - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_0, - KEY_SUBTRACT, - KEY_EQUALS, - KEY_BACK, - KEY_TAB, - KEY_Q, - KEY_W, - KEY_E, - KEY_R, - KEY_T, - KEY_Y, - KEY_U, - KEY_I, - KEY_O, - KEY_P, - KEY_LBRACKET, - KEY_RBRACKET, - KEY_RETURN, - KEY_LCONTROL, - KEY_A, // 30 - KEY_S, - KEY_D, - KEY_F, - KEY_G, - KEY_H, - KEY_J, - KEY_K, - KEY_L, - KEY_SEMICOLON, - KEY_APOSTROPHE, // 40 - KEY_GRAVE, - KEY_LSHIFT, - KEY_BACKSLASH, - KEY_Z, - KEY_X, - KEY_C, - KEY_V, - KEY_B, - KEY_N, - KEY_M, - KEY_COMMA, - KEY_PERIOD, - KEY_SLASH, - KEY_RSHIFT, - KEY_MULTIPLY, - KEY_LALT, - KEY_SPACE, - KEY_CAPITAL, - KEY_F1, - KEY_F2, // 60 - KEY_F3, - KEY_F4, - KEY_F5, - KEY_F6, - KEY_F7, - KEY_F8, - KEY_F9, - KEY_F10, - KEY_NUMLOCK, - KEY_SCROLL, // 70 - KEY_NUMPAD7, - KEY_NUMPAD8, - KEY_NUMPAD9, - KEY_NUMPADSUBTRACT, - KEY_NUMPAD4, - KEY_NUMPAD5, - KEY_NUMPAD6, - KEY_NUMPADADD, - KEY_NUMPAD1, - KEY_NUMPAD2, // 80 - KEY_NUMPAD3, - KEY_NUMPAD0, - KEY_NUMPADDECIMAL, - KEY_NOOP, - KEY_ZENKAKUHANKAKU, - KEY_102ND, - KEY_F11, - KEY_F12, - KEY_F13, - KEY_F14, // 90 - KEY_HIRAGANA, - KEY_HENKAN, - KEY_KATAKANAHIRAGANA, - KEY_MUHENKAN, - KEY_KPJPCOMMA, - KEY_NUMPADENTER, - KEY_RCONTROL, - KEY_NUMPADDIVIDE, - KEY_PRINTSCREEN, - KEY_RALT, // 100 - KEY_LINEFEED, - KEY_HOME, - KEY_UP, - KEY_PGUP, - KEY_LEFT, - KEY_RIGHT, - KEY_END, - KEY_DOWN, - KEY_PGDN, - KEY_INSERT, // 110 - KEY_DELETE, - KEY_MACRO, - KEY_MUTE, - KEY_VOLUMEDOWN, - KEY_VOLUMEUP, - KEY_POWER, - KEY_KPEQUAL, - KEY_KPPLUSMINUS, - KEY_PAUSE, - KEY_SCALE, - KEY_TOTAL_COUNT -} EKeyCode; - -//============================================================================== -/** - * Keyboard modifier flags - */ -enum EKeyboardModifierFlags { - MODIFIER_NONE = 0, - MODIFIER_SHIFT = 1 << 0, - MODIFIER_CTRL = 1 << 1, - MODIFIER_ALT = 1 << 2, - MODIFIER_KEYDOWN = 1 << 3, ///< One or more key is down -}; - -//============================================================================== -/** - * Button codes - */ -enum EButtonCodes { - BUTTON_A = 0, - BUTTON_B, - BUTTON_X, - BUTTON_Y, - BUTTON_L1, - BUTTON_R1, - BUTTON_THUMBL, - BUTTON_THUMBR, - BUTTON_SELECT, - BUTTON_START, - BUTTON_MODE, - BUTTON_UP, - BUTTON_DOWN, - BUTTON_LEFT, - BUTTON_RIGHT, - BUTTON_CENTER, - BUTTON_ENTER, - BUTTON_TOTAL_COUNT -}; - -//============================================================================== -/** - * Axis codes - */ -enum EAxisCodes { - AXIS_X = 0, - AXIS_Y, - AXIS_Z, - AXIS_RZ, - AXIS_HAT_X, - AXIS_HAT_Y, - AXIS_LTRIGGER, - AXIS_RTRIGGER, - AXIS_TOTAL_COUNT -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSInputEngine.h b/src/Runtime/Source/Runtime/Include/Qt3DSInputEngine.h deleted file mode 100644 index bf75e5a1..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSInputEngine.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSKernelTypes.h" -#include "Qt3DSPickFrame.h" -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/vector.h" -#include "foundation/Qt3DSDataRef.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace qt3ds { -namespace runtime { - class IApplication; -} -} -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class CRuntime; -union UVariant; -class CInputEventProvider; - -//============================================================================== -/** -* @class CInputEngine -* @brief The basic input engine -*/ -class CInputEngine -{ - //============================================================================== - // Fields - //============================================================================== -protected: - SInputFrame m_InputFrame; ///< The data describing the input state - eastl::vector> m_PickInput; - bool m_BeginPickInput; - qt3ds::runtime::IApplication *m_Application; ///< The Runtime object - qt3ds::foundation::NVScopedRefCounted - m_InputEventProvider; ///< The event provider for keyboard - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - typedef qt3ds::foundation::NVConstDataRef> TPickInputList; - CInputEngine(); - virtual ~CInputEngine(); - -public: // Runtime interfaces - void SetApplication(qt3ds::runtime::IApplication *inApplication); - -public: - // Access - virtual SInputFrame &GetInputFrame(); - virtual SKeyInputFrame &GetKeyInputFrame(); - - // Setters - // Multitouch is handled by using BeginPickInput, SetPickInput (several times), and EndPickInput - // pairs. - // The assumption here is that the pick input is static until changed. So to clear it you need - // a - // begin, end pair without any other pieces. - virtual void BeginPickInput(); - virtual void SetPickInput(FLOAT inX, FLOAT inY, BOOL inValid = true); - virtual void EndPickInput(); - virtual TPickInputList GetPickInput() const; - virtual void SetPickFlags(INT32 inFlags); - virtual void SetKeyState(INT32 inKeyCode, BOOL inDown); - virtual void SetButtonState(INT32 inButtonCode, BOOL inDown); - virtual void SetScrollValue(INT32 inFlags, INT16 value); - virtual void SetModifierFlag(INT32 inFlag); - - // Keyboard hook - virtual void HandleKeyboard(INT32 inKeyCode, INT32 inPressed, INT32 inRepeat = 0); - - // Other input - virtual void HandleButton(INT32 inButtonCode, INT32 inPressed, INT32 inRepeat = 0); - virtual void HandleAxis(INT32 inAxisCode, FLOAT inValue); - - // Helpers - // virtual INT32 ConvertKeyCode( INT32 inKeyCode, BOOL inShift ); - // TODO: SK - To quickly restore functionality, but this is should be in tegra-specific project. - virtual void ClearInputFrame(); - virtual BOOL TranslateEvent(const CHAR *inEvent); - - void MarkApplicationDirty(); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSInputEventTypes.h b/src/Runtime/Source/Runtime/Include/Qt3DSInputEventTypes.h deleted file mode 100644 index 0b3c3981..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSInputEventTypes.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSHash.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -// Mouse events -const TEventCommandHash ON_MOUSEOVER = CHash::HashEventCommand("onMouseOver"); -const TEventCommandHash ON_MOUSEOUT = CHash::HashEventCommand("onMouseOut"); -const TEventCommandHash ON_GROUPEDMOUSEOVER = CHash::HashEventCommand("onGroupedMouseOver"); -const TEventCommandHash ON_GROUPEDMOUSEOUT = CHash::HashEventCommand("onGroupedMouseOut"); - -// Crude hack to pretend mouse events are gesture events, since gesture events are all you -// can specify in studio. -// TODO: Fix properly, preferably by bringing back gesture support -const TEventCommandHash ON_MOUSEDOWN = CHash::HashEventCommand("onPressureDown"); -const TEventCommandHash ON_MOUSEUP = CHash::HashEventCommand("onPressureUp"); -const TEventCommandHash ON_MOUSECLICK = CHash::HashEventCommand("onTap"); -const TEventCommandHash ON_MOUSEDBLCLICK = CHash::HashEventCommand("onDoubleTap"); -//const TEventCommandHash ON_MOUSEDOWN = CHash::HashEventCommand("onMouseDown"); -//const TEventCommandHash ON_MOUSEUP = CHash::HashEventCommand("onMouseUp"); -//const TEventCommandHash ON_MOUSECLICK = CHash::HashEventCommand("onMouseClick"); -//const TEventCommandHash ON_MOUSEDBLCLICK = CHash::HashEventCommand("onMouseDblClick"); - -const TEventCommandHash ON_MIDDLEMOUSEDOWN = CHash::HashEventCommand("onMiddleMouseDown"); -const TEventCommandHash ON_MIDDLEMOUSEUP = CHash::HashEventCommand("onMiddleMouseUp"); -const TEventCommandHash ON_MIDDLEMOUSECLICK = CHash::HashEventCommand("onMiddleMouseClick"); -const TEventCommandHash ON_MIDDLEDBLMOUSECLICK = CHash::HashEventCommand("onMiddleMouseDblClick"); - -const TEventCommandHash ON_RIGHTMOUSEDOWN = CHash::HashEventCommand("onRightMouseDown"); -const TEventCommandHash ON_RIGHTMOUSEUP = CHash::HashEventCommand("onRightMouseUp"); -const TEventCommandHash ON_RIGHTMOUSECLICK = CHash::HashEventCommand("onRightMouseClick"); -const TEventCommandHash ON_RIGHTDBLMOUSECLICK = CHash::HashEventCommand("onRightMouseDblClick"); - -const TEventCommandHash ON_HORIZONTALSCROLLWHEEL = - CHash::HashEventCommand("onHorizontalScrollWheel"); -const TEventCommandHash ON_VERTICALSCROLLWHEEL = CHash::HashEventCommand("onVerticalScrollWheel"); - -const TEventCommandHash ON_KEYUP = - CHash::HashEventCommand("onKeyUp"); ///< Studio's keyboard event string -const TEventCommandHash ON_KEYDOWN = - CHash::HashEventCommand("onKeyDown"); ///< Studio's keyboard event string -const TEventCommandHash ON_KEYREPEAT = - CHash::HashEventCommand("onKeyRepeat"); ///< Studio's keyboard event string - -const TEventCommandHash ON_BUTTONUP = CHash::HashEventCommand("onButtonUp"); -const TEventCommandHash ON_BUTTONDOWN = CHash::HashEventCommand("onButtonDown"); -const TEventCommandHash ON_BUTTONREPEAT = CHash::HashEventCommand("onButtonRepeat"); - -const TEventCommandHash ON_AXISMOVED = CHash::HashEventCommand("onAxisMoved"); - -// Used by UIContract -const TEventCommandHash ON_LEFT = CHash::HashEventCommand("onLeft"); -const TEventCommandHash ON_RIGHT = CHash::HashEventCommand("onRight"); -const TEventCommandHash ON_UP = CHash::HashEventCommand("onUp"); -const TEventCommandHash ON_DOWN = CHash::HashEventCommand("onDown"); -const TEventCommandHash ON_BACK = CHash::HashEventCommand("onBack"); -const TEventCommandHash ON_SELECT = CHash::HashEventCommand("onSelect"); - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSInputFrame.h b/src/Runtime/Source/Runtime/Include/Qt3DSInputFrame.h deleted file mode 100644 index f80f3ebc..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSInputFrame.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSPlatformSpecific.h" -#include "Qt3DSInputDefs.h" - -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Input structure defining the values for keyboard input - */ -struct SKeyInputFrame -{ - UINT16 m_ModifierFlags; ///< Keyboard modifier state flags - typedef eastl::map MAP_KEYCODE_COUNT; - MAP_KEYCODE_COUNT - m_KeyStates; ///< Keycode map representing number of frames since the keys are down - ///< 0 - up, 255 - down for more than 254 frames - - SKeyInputFrame() - : m_ModifierFlags(MODIFIER_NONE) - { - } - - UINT16 GetKeyCount(INT32 inKeyCode) - { - MAP_KEYCODE_COUNT::iterator theIter = m_KeyStates.find(inKeyCode); - return theIter != m_KeyStates.end() ? theIter->second : 0; - } -}; - -//============================================================================== -/** - * Input structure defining the values fed into input processing - */ -struct SInputFrame -{ - SKeyInputFrame m_KeyInputFrame; ///< Data for keyboard input - - typedef eastl::map MAP_BUTTONCODE_COUNT; - MAP_BUTTONCODE_COUNT m_ButtonStates; - - FLOAT m_AxisStates[AXIS_TOTAL_COUNT]; - - FLOAT m_PickX; ///< Horizontal screen location - FLOAT m_PickY; ///< Vertical screen location - - INT32 m_MouseFlags; ///< Mouse button state flags - - // SK - gesture-specific variables should NOT be in core runtime, its tegra-specific - INT32 m_GestureID; ///< a running counter/unique-id - INT32 m_GestureKind; ///< Gesture state flags - - /* different gestures will interpret as different values. could be: - * DRAG: delta position - * FLICK: velocities - * ZOOM: second finger or quantized delta */ - INT16 m_DeltaX; - INT16 m_DeltaY; - - BOOL m_PickValid; ///< X and Y are valid inputs - INT16 m_ScrollValue; //< Value of scrollwheel scrolled - - CHAR m_Padding[1]; - - SInputFrame() - : m_PickX(0) - , m_PickY(0) - , m_MouseFlags(NO_INPUT) - , m_GestureID(0) - , m_GestureKind(0) - , m_DeltaX(0) - , m_DeltaY(0) - , m_PickValid(false) - { - Q3DStudio_memset(m_AxisStates, 0, sizeof(m_AxisStates)); - } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSKernelTypes.h b/src/Runtime/Source/Runtime/Include/Qt3DSKernelTypes.h deleted file mode 100644 index db290996..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSKernelTypes.h +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSArray.h" - -namespace qt3ds { -namespace runtime { - namespace element { - struct SElement; - struct SComponent; - } -} -} - -namespace Q3DStudio { -typedef qt3ds::runtime::element::SElement TElement; -typedef qt3ds::runtime::element::SComponent TComponent; -} -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class CString; - -//============================================================================== -// Typedefs -//============================================================================== -typedef CArray TElementList; ///< Dynamic list of CElements -typedef CArray TEventList; ///< Dynamic list of CStrings -typedef CArray TAssociationList; ///< Dynamic list of IDs used for the association process - -typedef UINT32 TEventCommandHash; ///< Value from CHash::Hash31 -typedef UINT32 TStringHash; ///< Value from CHash::Hash -typedef UINT32 TAttributeHash; ///< Value from CHash::Hash27 -typedef UINT32 THashValue; ///< 32 bit value indicating a hash - -//============================================================================== -// Enumerations -//============================================================================== - -/// Each attribute knows the type of its value and uses 4 bits for this enum -enum EAttributeType { - ATTRIBUTETYPE_NONE = 0, - ATTRIBUTETYPE_INT32, - ATTRIBUTETYPE_HASH, - ATTRIBUTETYPE_FLOAT, - ATTRIBUTETYPE_BOOL, - ATTRIBUTETYPE_STRING, - ATTRIBUTETYPE_POINTER, - ATTRIBUTETYPE_ELEMENTREF, - ATTRIBUTETYPE_DATADRIVEN_PARENT, - ATTRIBUTETYPE_DATADRIVEN_CHILD, - ATTRIBUTETYPE_FLOAT3, - ATTRIBUTETYPE_FLOAT2, - ATTRIBUTETYPE_DATAINPUT_TIMELINE, - ATTRIBUTETYPE_DATAINPUT_SLIDE, - ATTRIBUTETYPECOUNT -}; - -/// Elements represent various types of objects -enum EElementType { - ELEMENTTYPE_UNKNOWN = 0, - ELEMENTTYPE_NODE, - ELEMENTTYPE_CAMERA, - ELEMENTTYPE_LIGHT, - ELEMENTTYPE_TEXT, - ELEMENTTYPE_MATERIAL, - ELEMENTTYPE_TEXTURE, - ELEMENTTYPE_COMPONENT, - ELEMENTTYPE_BEHAVIOR, - ELEMENTTYPE_PATH, - ELEMENTTYPE_PATHANCHORPOINT, - ELEMENTTYPE_SUBPATH, - ELEMENTTYPECOUNT -}; - -//============================================================================== -// Enumerations -//============================================================================== - -/// Various bit flags packed into a single 16bit space. -enum EElementFlag { - // Persistent flags (set only at creation) - ELEMENTFLAG_COMPONENT = 1, ///< Element is a component - ELEMENTFLAG_TIMELINE = 1 << 1, ///< Element has start time and duration attributes - ELEMENTFLAG_CLONE = 1 << 2, ///< Element is a clone - ELEMENTFLAG_ATTRIBUTELOCK = - 1 << 3, ///< No more attributes can be added (always true during runtime) - - // Configuration flags (seldom changed) - ELEMENTFLAG_SCRIPTCALLBACKS = 1 - << 4, ///< At least one script has requested notify on onActivate, onDeactivate, onUpdate - ELEMENTFLAG_SCRIPTINITIALIZE = 1 - << 5, ///< At least one script has requested notify on onInitialize - ELEMENTFLAG_REGISTEREDFORATTRIBUTECHANGE = 1 << 6, ///< Element monitored for attribute change - ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK = 1 << 7, ///< Element registered for event callbacks - ELEMENTFLAG_PICKENABLED = 1 << 8, ///< At least one script or action has registered for mouse - ///events based on this element - - // Runtime flags - ELEMENTFLAG_GLOBALACTIVE = - 1 << 9, ///< Combination active flag based on explicit, time and parent active - ELEMENTFLAG_EXPLICITACTIVE = 1 << 10, ///< Explicit On/Off switch on each element - ELEMENTFLAG_PLAYTHROUGH = 1 << 11, ///< Playthrough slides enabled if this is a component - ELEMENTFLAG_DIRTY = 1 << 12, ///< Attributes or user visible flags have changed - - // Flags used by the activation manager - ELEMENTFLAG_AMGR_TIMEACTIVE = 1 << 13, ///< Is the element alive according to time information -}; - -// Four byte aligned time unit structure. -struct SAlignedTimeUnit -{ - UINT32 m_LowWord; - UINT32 m_HighWord; - - SAlignedTimeUnit() {} - SAlignedTimeUnit(const TTimeUnit &inUnit); - SAlignedTimeUnit(const SAlignedTimeUnit &inOther) - : m_LowWord(inOther.m_LowWord) - , m_HighWord(inOther.m_HighWord) - { - } - SAlignedTimeUnit &operator=(const SAlignedTimeUnit &inOther) - { - m_LowWord = inOther.m_LowWord; - m_HighWord = inOther.m_HighWord; - return *this; - } - operator TTimeUnit() const; - - void operator-=(const TTimeUnit &inTime); - void operator%=(const TTimeUnit &inTime); -}; - -//============================================================================== -// Defines -//============================================================================== -#define Q3DStudio_ATTRIBUTEKEYBITS 26 /* Number of bits to store attributes index */ -#define Q3DStudio_ATTRIBUTEKEYMASK 0x03ffffff /* Bit mask covering 26 bits */ - -//============================================================================== -// Structs -//============================================================================== - -/// Each element has a number of attributes associated with it - This is the key. -struct SAttributeKey -{ - TAttributeHash m_Hash : Q3DStudio_ATTRIBUTEKEYBITS; ///< hash of attribute name - TAttributeHash m_Type : 4; ///< Attribute type such as INT32, FLOAT, STRING - TAttributeHash m_Dirty : 1; ///< Dirty bit signalling that the attribute value has been modified - TAttributeHash - m_DontOptimize : 1; ///< Used by the exporter/optimizer to flag attributes as un-optimizable - - void Convert(const UINT32 &inKey) - { - m_Hash = inKey & Q3DStudio_ATTRIBUTEKEYMASK; - m_Type = (inKey & 0x3c000000) >> Q3DStudio_ATTRIBUTEKEYBITS; - m_Dirty = (inKey & 0x40000000) >> (Q3DStudio_ATTRIBUTEKEYBITS + 4); - m_DontOptimize = (inKey & 0x80000000) >> (Q3DStudio_ATTRIBUTEKEYBITS + 5); - } -}; - -/// The structure to store a memory pool for clones. -/// The actual data pool will start at the address after these 8 bytes. -struct SClone -{ - SClone *m_Next; ///< Pointer to the next block of memory - UINT32 m_Size; ///< Size of the current block of memory -}; - -//============================================================================== -// Unions -//============================================================================== - -/// Each element has a number of attributes associated with it - This is the value. -union UVariant { - INT32 m_INT32; ///< Integer representation - FLOAT m_FLOAT; ///< Float representation - THashValue m_Hash; ///< Explicit hash representation - UINT32 m_StringHandle; ///< Handle into the IStringTable member of the presentation - void *m_VoidPointer; ///< Generic data Pointer - UINT32 m_ElementHandle; ///< Element handle. Resolve using IApplication object. - FLOAT m_FLOAT3[3]; ///< Vector 3 representation -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSLogicSystem.h b/src/Runtime/Source/Runtime/Include/Qt3DSLogicSystem.h deleted file mode 100644 index af13c91f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSLogicSystem.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#pragma once -#ifndef QT3DS_LOGIC_SYSTEM_H -#define QT3DS_LOGIC_SYSTEM_H -#include "Qt3DSElementSystem.h" - -namespace qt3ds { -namespace runtime { - - class ILogicSystem : public NVRefCounted - { - public: - // returns the action id - virtual QT3DSI32 AddAction(element::SElement &inTrigger, - Q3DStudio::TEventCommandHash inEventNameHash, - element::SElement *inTarget, element::SElement *inOwner, - Q3DStudio::TEventCommandHash inType, Q3DStudio::UVariant inArg1, - Q3DStudio::UVariant inArg2, bool inActive) = 0; - - virtual void OnEvent(Q3DStudio::TEventCommandHash inEventName, element::SElement &inTarget, - Q3DStudio::IPresentation &inPresentation) const = 0; - virtual void SetActive(QT3DSI32 inActionIndex, bool inActive, - IElementAllocator &inElemAllocator) = 0; - - virtual void SaveBinaryData(qt3ds::foundation::IOutStream &ioStream) = 0; - virtual void LoadBinaryData(NVDataRef inLoadData) = 0; - - static ILogicSystem &CreateLogicSystem(NVFoundationBase &inFnd); - }; -} -} -#endif \ No newline at end of file diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSOutputMemoryStream.h b/src/Runtime/Source/Runtime/Include/Qt3DSOutputMemoryStream.h deleted file mode 100644 index da28245f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSOutputMemoryStream.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSHash.h" -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4820) // X bytes padding added after data member -#pragma warning( \ - disable : 4061) // enumerator X in switch of enum Y is not explicitly handled by a case label -#pragma warning(disable : 4062) // enumerator X in switch of enum Y is not handled -#pragma warning(disable : 4548) // xlocale warnings -#pragma warning( \ - disable : 4738) // storing 32-bit float result in memory, possible loss of performance -#endif -#include -#include -#include -#include - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Class -//============================================================================== -class COutputMemoryStream -{ - //============================================================================== - // Fields - //============================================================================== -public: - std::vector m_Data; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - COutputMemoryStream(); - virtual ~COutputMemoryStream(); - -public: // Access - void Reset(); - UINT32 GetSize() const; - const UINT8 *GetData() const; - -public: // Output - void WriteStringHash(const CHAR *inItem); - void WriteEventCommandHash(const CHAR *inItem); - -public: // Operators - COutputMemoryStream &operator<<(const COutputMemoryStream &inStream); - COutputMemoryStream &operator<<(const std::string &inString); - COutputMemoryStream &operator<<(const EAttributeType inType); - - //============================================================================== - // Template Methods - //============================================================================== -public: - template - COutputMemoryStream &operator<<(const T &inItem) - { - size_t theSize = sizeof(T); - const UINT8 *thePtr = reinterpret_cast(&inItem); - for (size_t theCounter = 0; theCounter < theSize; ++theCounter) { - m_Data.push_back(*thePtr); - ++thePtr; - } - return *this; - } - - template - void SetData(const T &inItem, UINT32 inByteOffset) - { - UINT8 *theSourcePtr = &m_Data[inByteOffset]; - size_t theSize = sizeof(T); - const UINT8 *thePtr = reinterpret_cast(&inItem); - for (size_t theCounter = 0; theCounter < theSize; ++theCounter) { - *theSourcePtr = *thePtr; - ++thePtr; - ++theSourcePtr; - } - } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSParametersSystem.h b/src/Runtime/Source/Runtime/Include/Qt3DSParametersSystem.h deleted file mode 100644 index 50a4652d..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSParametersSystem.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT3DS_PARAMETERS_SYSTEM_H -#define QT3DS_PARAMETERS_SYSTEM_H -#pragma once -#include "Qt3DSKernelTypes.h" -#include "foundation/Qt3DSRefCounted.h" -#include "EASTL/utility.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSDataRef.h" - -namespace qt3ds { -namespace foundation { - class IOutStream; -} -} - -namespace qt3ds { -namespace runtime { - using namespace qt3ds; - using namespace qt3ds::foundation; - - typedef eastl::pair TIdValuePair; - - class IParametersSystem : public NVRefCounted - { - public: - virtual QT3DSI32 CreateParameterGroup() = 0; - virtual void AddParameter(QT3DSI32 inGroup, QT3DSU32 inNameHash, Q3DStudio::UVariant inParam) = 0; - - virtual QT3DSU32 GetNumParameters(QT3DSI32 inGroupId) const = 0; - virtual TIdValuePair GetParameter(QT3DSI32 inGroupId, QT3DSU32 inIndex) const = 0; - - static IParametersSystem &CreateParametersSystem(NVFoundationBase &inFoundation); - }; -} -} - -#endif diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSPickFrame.h b/src/Runtime/Source/Runtime/Include/Qt3DSPickFrame.h deleted file mode 100644 index 15da72c9..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSPickFrame.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSInputFrame.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class IPresentation; - -//============================================================================== -/** - * Reporting structure describing a complete mouse pick including initial - * mouse XY screen position, which element was hit, UV point of hit, global - * intersection point and more. - */ -struct SPickFrame -{ - SInputFrame m_InputFrame; ///< Input values to process - - FLOAT m_PickOrigin[3]; ///< 3D pick ray start - FLOAT m_PickDirection[3]; ///< 3D pick ray direction - - FLOAT m_LocalHit[2]; ///< 2D pick ray intersection - FLOAT m_SquaredDistance; ///< Distance from camera to intersection - TElement *m_Model; ///< Element picked - // IPresentation* m_SubPresentation; ///< The picked element has a subpresentation - - BOOL m_ResultValid; ///< Model found - Whole structure is valid - INT8 m_Unused[3]; ///< Padding -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSPresentation.h b/src/Runtime/Source/Runtime/Include/Qt3DSPresentation.h deleted file mode 100644 index 0f0b1b0f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSPresentation.h +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "RuntimePrefix.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSPresentationFrameData.h" -#include "Qt3DSAnimationSystem.h" -#include "Qt3DSCircularArray.h" -#include "Qt3DSEventCallbacks.h" -#include "Qt3DSTimePolicy.h" -#include "EASTL/hash_map.h" -#include "foundation/StringTable.h" -#include "Qt3DSComponentManager.h" - -#include - -class QPresentationSignalProxy : public QObject -{ - Q_OBJECT -Q_SIGNALS: - void SigSlideEntered(const QString &elementPath, unsigned int index, const QString &name); - void SigSlideExited(const QString &elementPath, unsigned int index, const QString &name); -}; - -namespace qt3ds { -namespace runtime { - class IApplication; - class IActivityZone; -} -} - -namespace qt3ds { -namespace render { - class ILoadedBuffer; -} -} - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { -//============================================================================== -/** - * Intelligent representation of a Studio presentation. - */ -class CPresentation : public IPresentation -{ - //============================================================================== - // Fields - //============================================================================== -protected: - QString m_Name; ///< Name of ths presentation - QString m_FilePath; ///< The full path from which this presentation was loaded - qt3ds::runtime::IApplication *m_Application; ///< Runtime object - IScene *m_Scene; ///< Connection to the associated scene (render) for this presentation - qt3ds::runtime::IActivityZone *m_ActivityZone; ///< Controls element active status. - TElement *m_RootElement; - - CPresentationFrameData m_FrameData; ///< Storage of data of the current frame - CCircularArray m_EventCommandQueue; ///< The Event/Command integrated queue - bool m_IsProcessingEventCommandQueue; - CEventCallbacks m_EventCallbacks; ///< Handles event callbacks on registered elements - SPresentationSize m_Size; ///< Native width, height and mode exported from Studio - - qt3ds::foundation::NVScopedRefCounted - m_LoadedBuffer; ///< Reference to loaded data when loading from binary. - - CComponentManager m_ComponentManager; - qt3ds::foundation::NVScopedRefCounted - m_SlideSystem; ///< Container and factory of all logics - qt3ds::foundation::NVScopedRefCounted - m_LogicSystem; ///< Container and factory of all logics - qt3ds::foundation::NVScopedRefCounted - m_AnimationSystem; ///< Container and factory of all animation tracks - qt3ds::foundation::NVScopedRefCounted - m_ParametersSystem; ///< Container and factory of all custom actions - - TTimeUnit m_Offset; - TTimeUnit m_LocalTime; - TTimeUnit m_PreviousGlobalTime; - bool m_Paused; - bool m_OffsetInvalid; - bool m_Active; - - typedef eastl::hash_map TElemStringMap; - TElemStringMap m_ElementPathMap; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CPresentation(const CHAR *inName, qt3ds::runtime::IApplication *inRuntime); - virtual ~CPresentation(); - -public: // Execution - void Initialize(); - // Clear dirty elements - void ClearDirtyList() override; - // Run events - void PreUpdate(const TTimeUnit inGlobalTime) override; - // update element graph - void BeginUpdate() override; - // end update element graph - void EndUpdate() override; - // Run behaviors. - void PostUpdate(const TTimeUnit inGlobalTime) override; - -public: // Bridge Control - IScene *GetScene() const override; - IScriptBridge *GetScriptBridgeQml() override; - void SetScene(IScene *inScene) override; - - void SetActivityZone(qt3ds::runtime::IActivityZone *inZone); - qt3ds::runtime::IActivityZone *GetActivityZone() override { return m_ActivityZone; } - void SetActive(bool inValue); - bool GetActive() const; - TElement *GetRoot() override { return m_RootElement; } - void SetRoot(TElement &inRoot) override { m_RootElement = &inRoot; } - -public: // Commands and Events - void FireEvent(const SEventCommand &inEvent); - void FireEvent(const TEventCommandHash inEventType, TElement *inTarget, - const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, - const EAttributeType inType1 = ATTRIBUTETYPE_NONE, - const EAttributeType inType2 = ATTRIBUTETYPE_NONE) override; - void FireCommand(const TEventCommandHash inCommandType, TElement *inTarget, - const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, - const EAttributeType inType1 = ATTRIBUTETYPE_NONE, - const EAttributeType inType2 = ATTRIBUTETYPE_NONE) override; - void FlushEventCommandQueue(void) override; - void ProcessEvent(SEventCommand &inEvent) override; - - QPresentationSignalProxy *signalProxy(); - -public: // Event Callbacks - void RegisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) override; - BOOL UnregisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) override; - -protected: // Execution Helper Methods - void ProcessAllCallbacks(); - BOOL ProcessEventCommandQueue(); - void ProcessEvent(SEventCommand &ioEvent, INT32 &ioEventCount); - void ProcessEventBubbling(SEventCommand &ioEvent, INT32 &ioEventCount); - void ProcessCommand(const SEventCommand &inCommand); - -public: // Managers - IComponentManager &GetComponentManager() override; - ISlideSystem &GetSlideSystem() override; - IAnimationSystem &GetAnimationSystem() override; - ILogicSystem &GetLogicSystem() override; - IParametersSystem &GetParametersSystem() override; - qt3ds::foundation::IStringTable &GetStringTable() override; - qt3ds::runtime::IApplication &GetApplication() override - { - QT3DS_ASSERT(m_Application); - return *m_Application; - } - void SetLoadedBuffer(qt3ds::render::ILoadedBuffer &inBuffer); - - void SetElementPath(TElement &inElement, const char8_t *inPath) override; - qt3ds::foundation::CRegisteredString GetElementPath(TElement &inElement) override; - -public: // Helpers - CPresentationFrameData &GetFrameData() override; - TTimeUnit GetTime() { return m_LocalTime; } - -public: // Hooks and callbacks - void OnPresentationLoaded() override; - -public: // Configuration access - SPresentationSize GetSize() const override; - BOOL GetPause() const; - const QByteArray GetName() const; - - void SetSize(const SPresentationSize &inSize) override; - void SetPause(const BOOL inPause); - void SetHide(const BOOL inHide); - void SetUpdateLock(const BOOL inLockUpdate); - void SetVCAA(const BOOL inVCAA); - -public: // Full file path - void SetFilePath(const CHAR *inPath) override; - QString GetFilePath() override; - -private: // Disabled Copy Construction - CPresentation(CPresentation &); - CPresentation &operator=(const CPresentation &); -private: - QPresentationSignalProxy m_SignalProxy; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSPresentationFrameData.h b/src/Runtime/Source/Runtime/Include/Qt3DSPresentationFrameData.h deleted file mode 100644 index 332cc84a..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSPresentationFrameData.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Presentation update cycle data storage class. - * - * This is the data collected from the Presentation on each frame. Other subsystems - * or external system uses these data to perform their specific operation - */ -class CPresentationFrameData -{ - //============================================================================== - // Fields - //============================================================================== -protected: - TElementList m_DirtyList; ///< List of elements with modified attributes - TElementList m_TraversalList; ///< List of active elements - TElementList m_ScriptsList; ///< List of elements where scripts are active - TElementList - m_ActivationList; ///< List of elements whose global active flips from false to true - TElementList - m_DeactivationList; ///< List of elements whose global active flops from true to false - // TElementList m_SlideExitList; ///< List of components that exits their - // slides - // TElementList m_SlideEnterList; ///< List of components that enters their - // slides - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CPresentationFrameData(); - void Reserve(const INT32 inElementCount); - -public: // Data Management - void Reset(); - - TElementList &GetDirtyList() { return m_DirtyList; } - TElementList &GetTraversalList() { return m_TraversalList; } - TElementList &GetScriptsList() { return m_ScriptsList; } - TElementList &GetActivationList() { return m_ActivationList; } - TElementList &GetDeactivationList() { return m_DeactivationList; } - // TElementList& GetSlideExitList( ) { return m_SlideExitList; - // } - // TElementList& GetSlideEnterList( ) { return m_SlideEnterList; } - -private: // Disabled Copy Construction - CPresentationFrameData(const CPresentationFrameData &); - CPresentationFrameData &operator=(const CPresentationFrameData &); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSQmlElementHelper.h b/src/Runtime/Source/Runtime/Include/Qt3DSQmlElementHelper.h deleted file mode 100644 index ec36c8ed..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSQmlElementHelper.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_QML_ELEMENT_HELPER_H -#define QT3DS_QML_ELEMENT_HELPER_H - -#include "Qt3DSApplication.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSKernelTypes.h" - -namespace Q3DStudio { - -class CQmlElementHelper -{ -private: - CQmlElementHelper(); - virtual ~CQmlElementHelper(); - -public: - static TElement *GetElement(qt3ds::runtime::IApplication &inApplication, - IPresentation *inDefaultPresentation, const char *inPath, - TElement *inStartElement = NULL); - - static bool SetAttribute(TElement *inElement, const char *inAttribute, const void *value, - bool inDelay); - static bool GetAttribute(TElement *inElement, const char *inAttribute, void *value); -}; -} - -#endif // QT3DS_QML_ELEMENT_HELPER_H diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSQmlEngine.h b/src/Runtime/Source/Runtime/Include/Qt3DSQmlEngine.h deleted file mode 100644 index 71ef1b3f..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSQmlEngine.h +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-20016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#ifndef QT3DS_QML_ENGINE_H -#define QT3DS_QML_ENGINE_H - -#include "Qt3DSIScriptBridge.h" -#include "Qt3DSIComponentManager.h" -#include "EASTL/vector.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSRefCounted.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSSync.h" -#include "foundation/Qt3DSMutex.h" -#include "Qt3DSTimer.h" - -//============================================================================== -// Namespace -//============================================================================== - -namespace Q3DStudio { -//============================================================================== -// Typedefs -//============================================================================== -typedef void (*TScriptCallback)(void *inUserData); - -//============================================================================== -// Defines -//============================================================================== -#define SCRIPT_ON_INITIALIZE 1 -#define SCRIPT_ON_UPDATE 2 - -//============================================================================== -// Forwards -//============================================================================== -struct SEventCommand; -class IPresentation; - -//============================================================================== -/** -* Manages the various events callbacks in the system. It fires the -* registered callbacks when an event was triggered. -*/ -class CScriptCallbacks -{ - //============================================================================== - // Structs - //============================================================================== -protected: - struct SScriptCallbackEntry - { - SScriptCallbackEntry() {} - ~SScriptCallbackEntry() {} - - TScriptCallback m_Function; ///< Callback function pointer - void *m_UserData; ///< User data - Q3DStudio::UINT32 - m_CallbackType; ///< callback type. determines when and/or how often it is called - bool m_Processed; ///< Only used if the callback is of - - private: // Disabled Copy Construction - SScriptCallbackEntry(const SScriptCallbackEntry &); - SScriptCallbackEntry &operator=(const SScriptCallbackEntry &); - }; - typedef CArray TCallbackList; ///< Array of callbacks regisgtered - - struct SFrameCallbackEntry - { - SFrameCallbackEntry() {} - ~SFrameCallbackEntry() - { - FOR_ARRAY(SScriptCallbackEntry *, theEntry, m_Callbacks) - Q3DStudio_delete(*theEntry, SScriptCallbackEntry); - } - - TCallbackList m_Callbacks; ///< List of callbacks listening to this event - - private: // Disabled Copy Construction - SFrameCallbackEntry(const SFrameCallbackEntry &); - SFrameCallbackEntry &operator=(const SFrameCallbackEntry &); - }; - - typedef CArray TFrameCallbacksList; ///< Array of frame callbacks - -public: // Construction - CScriptCallbacks(); - ~CScriptCallbacks(); - - bool RegisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback, - void *inUserData); - void UnregisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback); - - void ProcessCallbacks(); - -private: - TFrameCallbacksList m_CallbackList; - -private: // Disabled Copy Construction - CScriptCallbacks(const CScriptCallbacks &); - CScriptCallbacks &operator=(const CScriptCallbacks &); -}; - -class CQmlEngine : public IScriptBridge -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - virtual ~CQmlEngine() {} - -public: // Public functions but not functions on the script bridge - /** - * @brief Peek a custom action from the queue - * - * @param[out] outElement Target Element - * @param[out] outSignal Signal Name - * - * @return true if signal available - */ - virtual bool PeekSignal(TElement *&outElement, char *&outName) = 0; - - /** - * @brief Select a slide by index - * - * @param[in] component Component Name - * @param[in] slideIndex Slide index - * @param[in] inArgs Arguemnts for slide switch - * - * @return none - */ - virtual void GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex, - const SScriptEngineGotoSlideArgs &inArgs) = 0; - - virtual bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) = 0; - - /** - * @brief Go to specified time - * - * @param[in] component Component Name - * @param[in] time New time - * - * @return none - */ - virtual void GotoTime(const char *component, const Q3DStudio::FLOAT time) = 0; - - /** - * @brief Return values of an attribute - * - * @param[in] element Element Name - * @param[in] attName Attribute name - * @param[out] value Attribute value - * - * @return none - */ - virtual bool GetAttribute(const char *element, const char *attName, char *value) = 0; - - /** - * @brief Register a callback - * - * @param[in] callbackType callback type -* @param[in] inCallback pointer to callback -* @param[in] inUserData pointer to user data - * - * @return true on success - */ - virtual bool RegisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback, - void *inUserData) = 0; - - /** - * @brief Shutdown QML engine - * - * @param[in] inFoundation Pointer to foundation - * - * @return no return - */ - virtual void Shutdown(qt3ds::NVFoundationBase &inFoundation) = 0; - - virtual qt3ds::runtime::IApplication *GetApplication() = 0; - - virtual void Initialize() = 0; - -public: - /** - * @brief Create QML engine - * - * @param[in] inFoundation Pointer to foundation - * @param[in] inTimeProvider Pointer to time provider - * - * @return no return - */ - static CQmlEngine *Create(qt3ds::NVFoundationBase &inFoundation, ITimeProvider &inTimeProvider); -}; - -} // namespace Q3DStudio - -#endif diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSRuntimeFactory.h b/src/Runtime/Source/Runtime/Include/Qt3DSRuntimeFactory.h deleted file mode 100644 index 1df732a6..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSRuntimeFactory.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "Qt3DSTimer.h" -#include "foundation/Qt3DSRefCounted.h" - -namespace qt3ds { -namespace render { - class IInputStreamFactory; - class IQt3DSRenderContext; - class IQt3DSRenderContextCore; -} -} - -namespace qt3ds { -namespace runtime { - class IApplication; - class IApplicationCore; -} -} - -namespace qt3ds { -namespace state { - class IVisualStateContext; -} -} - -namespace qt3ds { -namespace evt { - class IEventSystem; -} -} - -namespace qt3ds { -class NVFoundationBase; -namespace foundation { - class IStringTable; - class IPerfTimer; -} -} - -namespace Q3DStudio { - -class IScene; -class CRenderEngine; -class ISceneManager; -class IRender; -class CInputEngine; -class IScriptBridge; -class CPresentation; -class IPresentation; -class ITimeProvider; -class ISceneBinaryLoader; - -// All of the interfaces available without opengl initialized. -class IRuntimeFactoryCore : public qt3ds::foundation::NVRefCounted -{ -public: - virtual ISceneBinaryLoader &GetSceneLoader() = 0; - virtual IScriptBridge &GetScriptEngineQml() = 0; - virtual qt3ds::render::IQt3DSRenderContextCore &GetRenderContextCore() = 0; - virtual qt3ds::render::IInputStreamFactory &GetInputStreamFactory() = 0; - virtual qt3ds::state::IVisualStateContext &GetVisualStateContext() = 0; - virtual qt3ds::evt::IEventSystem &GetEventSystem() = 0; - virtual ITimeProvider &GetTimeProvider() = 0; - virtual qt3ds::NVFoundationBase &GetFoundation() = 0; - virtual qt3ds::foundation::IPerfTimer &GetPerfTimer() = 0; - virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; - virtual void AddSearchPath(const char8_t *inFile) = 0; - virtual void SetDllDir(const char *inDir) = 0; - virtual qt3ds::runtime::IApplicationCore *GetApplicationCore() = 0; - virtual void SetApplicationCore(qt3ds::runtime::IApplicationCore *app) = 0; -}; - -class IRuntimeFactory : public IRuntimeFactoryCore -{ -protected: - virtual ~IRuntimeFactory() {} - -public: - virtual ISceneManager &GetSceneManager() = 0; - virtual qt3ds::render::IQt3DSRenderContext &GetQt3DSRenderContext() = 0; - virtual qt3ds::runtime::IApplication *GetApplication() = 0; - virtual void SetApplication(qt3ds::runtime::IApplication *app) = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h b/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h deleted file mode 100644 index 7b8a4aab..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSPickFrame.h" -#include "Qt3DSIStateful.h" -#include "foundation/Qt3DSDataRef.h" -#include "foundation/Qt3DSRefCounted.h" -#include "Qt3DSIScene.h" - -namespace qt3ds { -namespace foundation { - class IInStream; - class IOutStream; - class Mutex; -} -} - -namespace qt3ds { -class Q3DSVariantConfig; -namespace render { - class IQt3DSRenderContextCore; - class ILoadedBuffer; -} -} - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class IScene; -class IPresentation; -class CRenderEngine; -class CRenderEngine; -class IUIPParser; -class CFileStream; -class IRuntimeFactory; -class IScriptBridge; -class ISceneManager; - -class ISceneBinaryLoader : public qt3ds::foundation::NVRefCounted -{ -protected: - virtual ~ISceneBinaryLoader() {} - -public: - virtual qt3ds::foundation::NVDataRef - BinaryLoadManagerData(qt3ds::foundation::IInStream &inStream, const char *inBinaryDir) = 0; - - // threadsafe - // Can be called from any thread - virtual bool GetBinaryLoadFileName(eastl::string &inPresentationFilename, - eastl::string &outResult) = 0; - - // threadsafe - // returns a handle to the loaded object. Return value of zero means error. - virtual qt3ds::QT3DSU32 LoadSceneStage1(qt3ds::foundation::CRegisteredString inPresentationDirectory, - qt3ds::render::ILoadedBuffer &inData) = 0; - - // threadsafe - // still does not require openGL context but has dependency on a few other things. - virtual void LoadSceneStage2(qt3ds::QT3DSU32 inSceneHandle, IPresentation &inPresentation, - size_t inElementMemoryOffset, IScriptBridge &inBridge) = 0; -}; -struct FacePositionPlanes -{ - enum Enum { XY = 0, YZ, XZ }; -}; - -//============================================================================== -/** -* @class ISceneManager -* @brief Container class that creates and manages all the Scenes. -*/ -class ISceneManager : public qt3ds::foundation::NVRefCounted -{ -protected: - virtual ~ISceneManager(){} - -public: // Presentations - //============================================================================== - /** - * Load a new scene based on an existing presentation. This will create a new - * CScene-based class from the factory method at "CreateScene". To supply - * your own class, simply set "CreateScene" to the desired factory method. - * After creating the new scene, a load will be triggered. - * @param inPresentation the current presentation loaded - */ - virtual IScene *LoadScene(IPresentation *inPresentation, IUIPParser *inParser, - IScriptBridge &inBridge, - const qt3ds::Q3DSVariantConfig &variantConfig) = 0; - virtual void LoadRenderPlugin(const CHAR *inAssetIDString, const CHAR *inPath, - const CHAR *inArgs) = 0; - - virtual void LoadQmlStreamerPlugin(const CHAR *inAssetIDString) = 0; - - virtual void BinarySaveManagerData(qt3ds::foundation::IOutStream &inStream, - const char *inBinaryDir) = 0; - // Loading flow data needs to return the string table memory block. This allows - // other systems to use remap their string table strings assuming they had mapped them before - // serialization. In general this is a horrible hack and abstraction leak but assuming you have - // a string - // table I guess it isn't too bad. - virtual qt3ds::foundation::NVDataRef - BinaryLoadManagerData(qt3ds::foundation::IInStream &inStream, const char *inBinaryDir) = 0; - - virtual void BinarySave(Q3DStudio::IScene &inScene) = 0; - -public: // Update Cycle - virtual BOOL Update() = 0; - virtual BOOL RenderPresentation(IPresentation *inPresentation) = 0; - virtual void OnViewResize(INT32 inViewWidth, INT32 inViewHeight) = 0; - virtual void GetViewSize(INT32 &outWidth, INT32 &outHeight) = 0; - - virtual STextSizes GetDisplayDimensions(Q3DStudio::IPresentation *inPrimaryPresentation) = 0; - -public: // Picking - virtual Q3DStudio::TElement *UserPick(float mouseX, float mouseY) = 0; - virtual SPickFrame AdvancePickFrame(const SInputFrame &inInputFrame) = 0; - // Get the relative UV coord position of an element. This matches how mouse picking works where - // we pick out - virtual qt3ds::foundation::Option - FacePosition(Q3DStudio::TElement &inElement, float mouseX, float mouseY, - qt3ds::foundation::NVDataRef inMapperElements, - FacePositionPlanes::Enum inPlane) = 0; - - virtual void Release() = 0; - - static ISceneManager &Create(IRuntimeFactory &inFactory, CRenderEngine &inRenderEngine); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSSlideSystem.h b/src/Runtime/Source/Runtime/Include/Qt3DSSlideSystem.h deleted file mode 100644 index de2ddbbc..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSSlideSystem.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "Qt3DSElementSystem.h" - -namespace Q3DStudio { -class ILogicManager; -} - -namespace qt3ds { -namespace runtime { - class ILogicSystem; - class IAnimationSystem; - - struct SSlideKey - { - element::SElement *m_Component; - QT3DSU32 m_Index; - SSlideKey() - : m_Component(NULL) - , m_Index(0) - { - } - SSlideKey(element::SElement &inElem, QT3DSU32 inIdx) - : m_Component(&inElem) - , m_Index(inIdx) - { - } - - bool IsValid() const { return m_Component != NULL; } - - bool operator==(const SSlideKey &inOther) const - { - return m_Component == inOther.m_Component && m_Index == inOther.m_Index; - } - }; - - struct PlayMode - { - enum Enum { - Looping = 0, - StopAtEnd, - PingPong, - Ping, - PlayThroughTo, - }; - }; - - struct SSlidePlayInformation - { - PlayMode::Enum m_PlayMode; - bool m_Paused; - QT3DSU8 m_PlayThroughTo; - - SSlidePlayInformation() - : m_PlayMode(PlayMode::Looping) - , m_Paused(false) - , m_PlayThroughTo(0xFF) - { - } - }; - - struct SSlideAnimAction - { - QT3DSI32 m_Id; - bool m_Active; - bool m_IsAnimation; - SSlideAnimAction() - : m_Id(0) - , m_Active(false) - , m_IsAnimation(false) - { - } - SSlideAnimAction(QT3DSI32 inId, bool inActive, bool inAnimation) - : m_Id(inId) - , m_Active(inActive) - , m_IsAnimation(inAnimation) - { - } - }; - - // Throughout this object, a slide index of 0xFF means invalid slide index. - class ISlideSystem : public NVRefCounted - { - public: - static QT3DSU8 InvalidSlideIndex() { return 0xFF; } - // Building out a dataset. - // Returns the index - // This slide is now the active cursor. The rest of the building functions will implicitly - // refer - // to the last added slide - // Playthroughto is either an index of the new slide or -1 meaning no playthough value. - virtual QT3DSU32 AddSlide(element::SElement &inComponent, const char8_t *inName, - PlayMode::Enum inPlayMode = PlayMode::Looping, bool inPaused = false, - QT3DSU8 inPlaythroughTo = InvalidSlideIndex(), QT3DSU32 inMinTime = 0, - QT3DSU32 inMaxTime = 0) = 0; - - virtual void SetSlideMaxTime(QT3DSU32 inMaxTime) = 0; - virtual void AddSlideElement(element::SElement &inElement, bool inActive) = 0; - virtual void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, - Q3DStudio::UVariant inValue) = 0; - virtual SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inIndex, - bool inActive) = 0; - - // Using the dataset - virtual void InitializeDynamicKeys(SSlideKey inKey, - IAnimationSystem &inAnimationSystem) const = 0; - virtual void ExecuteSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, - ILogicSystem &inLogicManager) const = 0; - virtual void RollbackSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, - ILogicSystem &inLogicManager) const = 0; - virtual QT3DSU8 FindSlide(element::SElement &inComponent, - const char8_t *inSlideName) const = 0; - virtual QT3DSU8 FindSlide(element::SElement &inComponent, QT3DSU32 inSlideHashName) const = 0; - virtual const char8_t *GetSlideName(SSlideKey inKey) const = 0; - virtual QT3DSU8 GetPlaythroughToSlideIndex(SSlideKey inKey) const = 0; - - static ISlideSystem &CreateSlideSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, - IElementAllocator &inElemAllocator); - }; -} -} diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSTimePolicy.h b/src/Runtime/Source/Runtime/Include/Qt3DSTimePolicy.h deleted file mode 100644 index 6a137196..00000000 --- a/src/Runtime/Source/Runtime/Include/Qt3DSTimePolicy.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "foundation/Qt3DSOption.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -struct TimePolicyModes -{ - enum Enum { - StopAtEnd = 0, - Looping, - PingPong, - Ping, - }; -}; - -//============================================================================== -/** - * Filter time based of parameters such as loop, duration, ping-pong etc. - * - * The time policy is an agnostic class that transforms time units based on - * internal settings and times given to it. Think of it as the minimal - * intelligence needed to support the time playback modes we use. It is simply - * a function that takes in a source time variable, adjusts it accordingly, - * and returns a filtered version. - */ - -QT3DS_ALIGN_PREFIX(4) class CTimePolicy -{ - //============================================================================== - // Fields and Constants - //============================================================================== -public: - const static TTimeUnit FOREVER; ///< Forever repetitions means loop forever, Forever duration - ///means infinite duration - friend struct SComponentTimePolicyOverride; ///< This class needs to mangle some of our internal - ///members to keep everything consistent - -protected: - // Time policy related ( 20 bytes ) - unsigned long m_LocalTime; ///< Component current local time; transformed by playmodes - unsigned long m_LoopingDuration; ///< Looping duration - SAlignedTimeUnit m_Offset; ///< Subtraction modifier - FLOAT m_Rate; ///< Time policy rate - UINT8 m_TimePadding[12]; ///< Padding to keep the size of the time policy the same. - - UINT8 - m_TimePolicyMode : 2; ///< Number of durations before halting - FOREVER means infinite reps - UINT8 m_Paused : 1; ///< Paused or playing - UINT8 m_OffsetInvalid : 1; ///< True if we need to reset our offset - UINT8 m_Backward : 1; ///< True if are in 'reverse' mode - - UINT8 m_Unused[3]; ///< (Padding 3 bytes) - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - void Initialize(const TTimeUnit inLoopingDuration = FOREVER, - TimePolicyModes::Enum inMode = TimePolicyModes::StopAtEnd); - void Initialize(const TTimeUnit inLoopingDuration, UINT32 inRepetitions, BOOL inPingPong); - -public: // Access Methods - FLOAT GetRate() const { return m_Rate; } - void SetRate(float inRate) { m_Rate = inRate; } - - bool IsReverse() const { return m_Backward; } - void SetReverse(bool inIsReverse) { m_Backward = inIsReverse ? 1 : 0; } - - TTimeUnit GetTime() const; - void SetTime(TTimeUnit inTime); - - TTimeUnit GetLoopingDuration() const; - void SetLoopingDuration(const TTimeUnit inTime); - - BOOL GetPaused() const; - void SetPaused(const BOOL inPaused); - - BOOL GetPlayBackDirection() const; - -public: // Time update - // The addendum contains extra parameters used that can be specified in a goto-slide command - // in the uia file. - BOOL ComputeTime(const TTimeUnit inTime); - -private: - TTimeUnit InternalGetTime() const; - - BOOL UpdateTime(const TTimeUnit inTime); -} QT3DS_ALIGN_SUFFIX(4); - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Include/RuntimePrefix.h b/src/Runtime/Source/Runtime/Include/RuntimePrefix.h deleted file mode 100644 index bf729ebf..00000000 --- a/src/Runtime/Source/Runtime/Include/RuntimePrefix.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "render/backends/gl/Qt3DSOpenGLPrefix.h" - -#ifdef _WIN32 -//============================================================================== -// DISABLED WARNINGS -// -// Note that most of these warnings are tuned off by default by the compiler -// even at warning level 4. Using option /Wall turns on all warnings and makes -// even standard Microsoft include files cry. We had to turn off these or -// turn off warnings individually for each standard include file which was -// too much work. Point is that /Wall is like Warning Level 5 and this brings -// it down to about Warning level 4.5, still way above /W4. -//#pragma warning( disable : 4189 ) // local variable is initialized but not referenced -#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union -#pragma warning(disable : 4511) // copy constructor could not be generated -#pragma warning(disable : 4512) // assignment operator could not be generated -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#pragma warning(disable : 4619) // #pragma warning : there is no warning number '4619' (in string.h) -#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy - // constructor is inaccessible -#pragma warning(disable : 4626) // assignment operator could not be generated because a base class - // assignment operator is inaccessible -#pragma warning( \ - disable : 4668) // not defined as a preprocessor macro, replacing with '0' for '#if/#elif' -#pragma warning(disable : 4826) // Conversion from 'const void *' to 'void *' is sign-extended -#pragma warning(disable : 4996) // _snprintf' was declared deprecated -#pragma warning(disable : 4711) // function selected for automatic inline expansion -#pragma warning(disable : 4710) // function not inlined -#pragma warning( \ - disable : 4738) // storing 32-bit float result in memory, possible loss of performance - -#pragma warning(disable : 4640) // construction of local static object is not thread-safe -#pragma warning(disable : 4127) // conditional expression is constant - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#endif //_WIN32 - -//============================================================================== -// STD INCLUDES - Standard includes MUST come first -#include // Standard functions -#include // File and IO -#ifndef _INTEGRITYPLATFORM -#include // memset, memcpy -#endif -#include // strlen - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -#include - -#define UNREFERENCED_PARAMETER(theParam) theParam; -#endif - -//============================================================================== -// ROOT INCLUDES FOR FRAMEWORK -//============================================================================== -#include "Qt3DSTypes.h" -#include "Qt3DSPlatformSpecific.h" -#include "Qt3DSAssert.h" -#include "Qt3DSMacros.h" -#include "Qt3DSConfig.h" -#include "Qt3DSMemorySettings.h" -#include "Qt3DSMemory.h" -#include "Qt3DSFrameworkTypes.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTimer.h" -#include "Qt3DSIScene.h" -#include "foundation/Qt3DSRefCounted.h" //scoped releasable auto ptr. -#include "EASTL/hash_map.h" -#include "EASTL/string.h" diff --git a/src/Runtime/Source/Runtime/Include/q3dsqmlbehavior.h b/src/Runtime/Source/Runtime/Include/q3dsqmlbehavior.h deleted file mode 100644 index 76f4a4a0..00000000 --- a/src/Runtime/Source/Runtime/Include/q3dsqmlbehavior.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef Q3DSQMLBEHAVIOR_H -#define Q3DSQMLBEHAVIOR_H - -#include -#include -#include -#include -#include -#include - -namespace Q3DStudio { - -class Q3DSQmlScript; - -class Q3DSQmlBehavior : public QObject -{ - Q_OBJECT -public: - Q3DSQmlBehavior(QObject *parent = nullptr); - - void setScript(Q3DSQmlScript *script); - - Q_INVOKABLE float getDeltaTime(); - Q_INVOKABLE float getAttribute(const QString &attribute); - Q_INVOKABLE void setAttribute(const QString &attribute, const QVariant &value); - Q_INVOKABLE void setAttribute(const QString &handle, const QString &attribute, - const QVariant &value); - Q_INVOKABLE void fireEvent(const QString &event); - Q_INVOKABLE void registerForEvent(const QString &event, const QJSValue &function); - Q_INVOKABLE void registerForEvent(const QString &handle, const QString &event, - const QJSValue &function); - Q_INVOKABLE void unregisterForEvent(const QString &event); - Q_INVOKABLE void unregisterForEvent(const QString &handle, const QString &event); - Q_INVOKABLE QVector2D getMousePosition(); - Q_INVOKABLE QMatrix4x4 calculateGlobalTransform(const QString &handle = QString()); - Q_INVOKABLE QVector3D lookAt(const QVector3D &target); - Q_INVOKABLE QVector3D matrixToEuler(const QMatrix4x4 &matrix); - Q_INVOKABLE QString getParent(const QString &handle = QString()); - Q_REVISION(1) Q_INVOKABLE void setDataInputValue(const QString &name, const QVariant &value); - - -Q_SIGNALS: - void initialize(); - void activate(); - void update(); - void deactivate(); - -private: - Q3DSQmlScript *m_script; -}; - -} - -#endif diff --git a/src/Runtime/Source/Runtime/Include/q3dsqmlscript.h b/src/Runtime/Source/Runtime/Include/q3dsqmlscript.h deleted file mode 100644 index 1049bd86..00000000 --- a/src/Runtime/Source/Runtime/Include/q3dsqmlscript.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef Q3DSQMLSCRIPT_H -#define Q3DSQMLSCRIPT_H - -#include -#include -#include -#include -#include -#include - -#include "Qt3DSTypes.h" -#include "Qt3DSKernelTypes.h" -#include "Qt3DSEvent.h" -#include "q3dsqmlbehavior.h" - -namespace Q3DStudio { -class CQmlEngine; - -class Q3DSQmlScript : public QObject -{ - Q_OBJECT -public: - Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, TElement &element, TElement &parent); - ~Q3DSQmlScript(); - - void update(); - void call(const QString &function); - void updateProperties(); - bool hasBehavior(const TElement *behavior); - - float getDeltaTime(); - float getAttribute(const QString &attribute); - void setAttribute(const QString &attribute, const QVariant &value); - void setAttribute(const QString &handle, const QString &attribute, - const QVariant &value); - void fireEvent(const QString &event); - void registerForEvent(const QString &event, const QJSValue &function); - void registerForEvent(const QString &handle, const QString &event, - const QJSValue &function); - void unregisterForEvent(const QString &event); - void unregisterForEvent(const QString &handle, const QString &event); - QVector2D getMousePosition(); - QMatrix4x4 calculateGlobalTransform(const QString &handle); - QVector3D lookAt(const QVector3D &target); - QVector3D matrixToEuler(const QMatrix4x4 &matrix); - QString getParent(const QString &handle); - void setDataInputValue(const QString &name, const QVariant &value); - - struct EventData { - QJSValue function; - }; - -private: - TElement *getElementByPath(const QString &path); - - CQmlEngine &m_api; - Q3DSQmlBehavior &m_object; - TElement &m_behavior; - TElement &m_owner; - - bool m_initialized; - bool m_lastActivationState; - - float m_deltaTime; - TTimeUnit m_lastTime; - struct EventCallbackInfo { - TElement *element; - TEventCommandHash eventHash; - EventData *data; - }; - - QVector m_eventCallbacks; -}; -} - -#endif // Q3DSQMLSCRIPT_H diff --git a/src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h b/src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h deleted file mode 100644 index 1905f44a..00000000 --- a/src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef Q3DSVARIANTCONFIG_P_H -#define Q3DSVARIANTCONFIG_P_H - -#include -#include -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of a number of Qt sources files. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// -namespace qt3ds { - -class Q3DSVariantConfig -{ -public: - Q3DSVariantConfig(); - ~Q3DSVariantConfig(); - - inline bool operator==(const Q3DSVariantConfig &other) const - { - return (this->m_variantList == other.m_variantList); - } - - inline bool operator!=(const Q3DSVariantConfig &other) const - { - return (this->m_variantList != other.m_variantList); - } - - inline bool isEmpty() const { return m_variantList.isEmpty(); } - - void setVariantList(const QStringList &variantList); - - bool isPartOfConfig(const QStringRef &variantAttributes) const; - - inline const QStringList &variantList() const { return m_variantList; } - -private: - QStringList m_variantList; - QList m_internalVariantList; - QHash> m_variantFilter; -}; - -}; -#endif // Q3DSVARIANTCONFIG_P_H diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSActivationManager.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSActivationManager.cpp deleted file mode 100644 index 3d052742..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSActivationManager.cpp +++ /dev/null @@ -1,1027 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "RuntimePrefix.h" -#include "Qt3DSActivationManager.h" -#include "Qt3DSElementSystem.h" -#include "Qt3DSComponentManager.h" -#include "foundation/Qt3DSFlags.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSInvasiveSet.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/StringTable.h" -#include "EASTL/sort.h" -#include "Qt3DSAttributeHashes.h" -#include "Qt3DSPresentation.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSync.h" -#include "Qt3DSRenderThreadPool.h" - -using namespace qt3ds::runtime; -using namespace qt3ds::runtime::element; -using qt3ds::render::IThreadPool; -using qt3ds::foundation::Time; - -namespace { - -typedef nvvector TElementAndSortKeyList; - -struct STimeEvent -{ - enum Type { - Start = 0, - Stop, - }; - - Type m_Type; - TTimeUnit m_Time; - nvvector m_AffectedNodes; - - STimeEvent(Type inType, NVAllocatorCallback &alloc, TTimeUnit inTime) - : m_Type(inType) - , m_Time(inTime) - , m_AffectedNodes(alloc, "TimeEvent") - { - } - - void Reset() - { - m_Time = 0; - m_AffectedNodes.clear(); - } -}; - -struct STimeEventGreaterThan -{ - bool operator()(const STimeEvent *lhs, const STimeEvent *rhs) const - { - if (lhs->m_Time == rhs->m_Time) - return lhs->m_Type > rhs->m_Type; - - return lhs->m_Time > rhs->m_Time; - } -}; - -struct STimeEventLessThan -{ - bool operator()(const STimeEvent *lhs, const STimeEvent *rhs) const - { - if (lhs->m_Time == rhs->m_Time) - return lhs->m_Type < rhs->m_Type; - - return lhs->m_Time < rhs->m_Time; - } -}; - -typedef nvvector TTimeEventList; -struct STimeContext; -typedef NVDataRef> TTimeContextSet; - -// Tree navigation - -SElement *GetElementNodeFirstChild(SElement &inNode) -{ - return inNode.m_Child; -} -SElement *GetElementNodeNextSibling(SElement &inNode) -{ - return inNode.m_Sibling; -} -SElement *GetElementNodeParent(SElement &inNode) -{ - return inNode.m_Parent; -} - -struct SScanBufferEntry -{ - SElement *m_Node; - QT3DSU32 m_StartTime; - QT3DSU32 m_EndTime; - - SScanBufferEntry() - : m_Node(NULL) - , m_StartTime(0) - , m_EndTime(QT3DS_MAX_U32) - { - } - SScanBufferEntry(SElement *inNode) - : m_Node(inNode) - , m_StartTime(0) - , m_EndTime(QT3DS_MAX_U32) - { - } - SScanBufferEntry(SElement *inNode, QT3DSU32 start, QT3DSU32 end) - : m_Node(inNode) - , m_StartTime(start) - , m_EndTime(end) - { - } - - SScanBufferEntry(SElement *inNode, bool inParentActive) - : m_Node(inNode) - , m_StartTime(inParentActive ? 1 : 0) - , m_EndTime(0) - { - } - - bool IsParentActive() const { return m_StartTime ? true : false; } -}; - -typedef nvvector TScanBuffer; -typedef nvvector TElementNodePtrList; - -struct SElementIndexPairSorter -{ - bool operator()(const eastl::pair &lhs, - const eastl::pair &rhs) const - { - return lhs.second < rhs.second; - } -}; - -struct SElementPtrSort -{ - bool operator()(const SElement *lhs, const SElement *rhs) - { - return lhs->Depth() < rhs->Depth(); - } -}; - -DEFINE_INVASIVE_SINGLE_LIST(TimeContext); - -struct STimeContext -{ - NVAllocatorCallback &m_Allocator; - SComponent &m_Component; - CTimePolicy m_TimePolicy; - SComponentTimePolicyOverride *m_TimePolicyOverride; - TTimeUnit m_CurrentTime; - TElementNodePtrList m_Elements; - TTimeEventList m_TimeEventBackingStore; - TTimeEventList m_TimeEvents; - SActivationManagerNodeDirtyList m_DirtyList; - QT3DSU32 m_TimeEventBackingStoreIndex; - QT3DSI32 mRefCount; - STimeContext *m_NextSibling; - TTimeContextList m_Children; - Mutex &m_ElementAccessMutex; - bool m_AllNodesDirty; - bool m_TimeDataNeedsUpdate; - - STimeContext(NVAllocatorCallback &alloc, SComponent &inComponent, Mutex &inElementAccessMutex) - : m_Allocator(alloc) - , m_Component(inComponent) - , m_TimePolicyOverride(NULL) - , m_CurrentTime(-1) - , m_Elements(alloc, "m_Elements") - , m_TimeEventBackingStore(alloc, "TimeEventBackingStore") - , m_TimeEvents(alloc, "TimeEvents") - , m_DirtyList(alloc) - , m_TimeEventBackingStoreIndex(0) - , mRefCount(0) - , m_NextSibling(NULL) - , m_ElementAccessMutex(inElementAccessMutex) - , m_AllNodesDirty(true) - , m_TimeDataNeedsUpdate(true) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) - ~STimeContext() - { - Reset(); - for (TTimeEventList::iterator iter = m_TimeEventBackingStore.begin(), - end = m_TimeEventBackingStore.end(); - iter != end; ++iter) { - NVDelete(m_Allocator, *iter); - } - - m_TimeEventBackingStore.clear(); - RemoveOverride(); - } - - void Reset() - { - for (TTimeEventList::iterator iter = m_TimeEvents.begin(), end = m_TimeEvents.end(); - iter != end; ++iter) - (*iter)->Reset(); - - m_TimeEvents.clear(); - m_TimeEventBackingStoreIndex = 0; - m_CurrentTime = -1; - m_DirtyList.clear(); - m_AllNodesDirty = true; - m_TimeDataNeedsUpdate = true; - } - - STimeEvent &GetTimeEventForTime(TTimeUnit inTime, STimeEvent::Type inType) - { - TTimeEventList::iterator inserter = m_TimeEvents.end(); - for (TTimeEventList::iterator iter = m_TimeEvents.begin(), end = m_TimeEvents.end(); - iter != end && inserter == end; ++iter) { - if ((*iter)->m_Time == inTime) { - if ((*iter)->m_Type == inType) - return **iter; - // Start comes before stop - if ((*iter)->m_Type == STimeEvent::Stop) - inserter = iter; - } - - if ((*iter)->m_Time > inTime) - inserter = iter; - } - - if (m_TimeEventBackingStoreIndex == m_TimeEventBackingStore.size()) - m_TimeEventBackingStore.push_back( - QT3DS_NEW(m_Allocator, STimeEvent)(inType, m_Allocator, inTime)); - - STimeEvent *newEvent = m_TimeEventBackingStore[m_TimeEventBackingStoreIndex]; - ++m_TimeEventBackingStoreIndex; - - newEvent->m_Time = inTime; - newEvent->m_Type = inType; - newEvent->m_AffectedNodes.clear(); - - if (inserter == m_TimeEvents.end()) - m_TimeEvents.push_back(newEvent); - else - m_TimeEvents.insert(inserter, newEvent); - - return *newEvent; - }; - - void UpdateNodeList(nvvector &inList, bool timeActive) - { - for (QT3DSU32 elemIdx = 0, endIdx = inList.size(); elemIdx < endIdx; ++elemIdx) { - SActivationManagerNode &theNode = inList[elemIdx]->m_ActivationManagerNode; - if (timeActive != theNode.m_Flags.IsTimeActive()) { - theNode.m_Flags.SetTimeActive(timeActive); - SetElementDirty(*inList[elemIdx]); - } - } - } - - // Returns true if we have reached the end time. - bool CalculateNewTime(TTimeUnit inGlobalTime) - { - Option theNewTime; - if (m_TimePolicyOverride) { - SComponentTimePolicyOverride *theOverride = m_TimePolicyOverride; - eastl::pair theEvalResult = - theOverride->ComputeLocalTime(m_TimePolicy, inGlobalTime); - if (theEvalResult.first && theOverride->m_TimeCallback) { - Mutex::ScopedLock __locker(m_ElementAccessMutex); - theOverride->m_TimeCallback->OnTimeFinished(); - theOverride->m_TimeCallback->Release(); - theOverride->m_TimeCallback = NULL; - } - return false; - } else { - Q3DStudio::BOOL theReachedEndTime = m_TimePolicy.ComputeTime(inGlobalTime); - if (theReachedEndTime) - return true; - - return false; - } - } - - // There are four conditions this happens: - // 1. This object is getting destroyed - // 2. A new override is being set. - // 3. The compoent switched slides. - // 4. The component was deactivated. - void RemoveOverride() - { - if (m_TimePolicyOverride) { - if (m_TimePolicyOverride->m_TimeCallback) { - Mutex::ScopedLock __locker(m_ElementAccessMutex); - m_TimePolicyOverride->m_TimeCallback->Release(); - m_TimePolicyOverride->m_TimeCallback = NULL; - } - - NVDelete(m_Allocator, m_TimePolicyOverride); - m_TimePolicyOverride = NULL; - } - } - - void UpdateLocalTime(TTimeUnit inNewTime, TScanBuffer &inScanBuffer, IActivityZone &inZone) - { - if (m_TimeDataNeedsUpdate) { - BuildTimeContext(inScanBuffer, inZone); - } - - TTimeUnit newTime = inNewTime; - if (newTime != m_CurrentTime) { - SComponent &myNode = m_Component; - { - Mutex::ScopedLock __locker(m_ElementAccessMutex); - myNode.SetDirty(); - } - STimeEvent searchEvent(STimeEvent::Start, m_Allocator, m_CurrentTime); - bool forward = newTime > m_CurrentTime; - m_CurrentTime = NVMax((TTimeUnit)0, newTime); - - if (forward) { - TTimeEventList::iterator iter = eastl::lower_bound( - m_TimeEvents.begin(), m_TimeEvents.end(), &searchEvent, STimeEventLessThan()); - - for (TTimeEventList::iterator end = m_TimeEvents.end(); - iter != end && (*iter)->m_Time <= newTime; ++iter) { - // Stop only works if the time is greater. - // start works if the time is equal. - bool isActive = true; - if ((*iter)->m_Type == STimeEvent::Stop) - isActive = newTime <= (*iter)->m_Time; - - UpdateNodeList((*iter)->m_AffectedNodes, isActive); - } - } else { - searchEvent.m_Type = STimeEvent::Stop; - TTimeEventList::reverse_iterator iter = - eastl::lower_bound(m_TimeEvents.rbegin(), m_TimeEvents.rend(), &searchEvent, - STimeEventGreaterThan()); - - for (TTimeEventList::reverse_iterator end = m_TimeEvents.rend(); - iter != end && (*iter)->m_Time >= newTime; ++iter) { - bool isActive = true; - if ((*iter)->m_Type == STimeEvent::Start) - isActive = newTime >= (*iter)->m_Time; - - UpdateNodeList((*iter)->m_AffectedNodes, isActive); - } - } - } - } - - void UpdateNodeElementInformation(SElement &inNode) - { - Q3DStudio::UVariant attValue; - if (inNode.GetAttribute(Q3DStudio::ATTRIBUTE_STARTTIME, attValue)) - inNode.m_ActivationManagerNode.m_StartTime = (QT3DSU32)attValue.m_INT32; - - if (inNode.GetAttribute(Q3DStudio::ATTRIBUTE_ENDTIME, attValue)) - inNode.m_ActivationManagerNode.m_StopTime = (QT3DSU32)attValue.m_INT32; - - inNode.m_ActivationManagerNode.m_Flags.SetTimeActive(false); - // Note that we don't set the script information here. The reason is that this requires the - // script list - // and we don't have access to it. Plus it can't change when a slide changes so it is kind - // of irrelevant. - } - - bool BuildTimeContextElementNode(SElement &inNode, QT3DSU32 inGlobalMin, QT3DSU32 inGlobalMax) - { - // Note that just because a node itself does not participate in the time graph, - // this does not mean that its children do not participate in the time graph. - if (inNode.DoesParticipateInTimeGraph()) { - UpdateNodeElementInformation(inNode); - if (inNode.IsUserActive()) { - inGlobalMin = NVMax(inNode.m_ActivationManagerNode.m_StartTime, inGlobalMin); - inGlobalMax = NVMin(inNode.m_ActivationManagerNode.m_StopTime, inGlobalMax); - if (inGlobalMin < inGlobalMax) { - GetTimeEventForTime(inGlobalMin, STimeEvent::Start) - .m_AffectedNodes.push_back(&inNode); - GetTimeEventForTime(inGlobalMax, STimeEvent::Stop) - .m_AffectedNodes.push_back(&inNode); - } - } - } else { - inNode.m_ActivationManagerNode.m_Flags.SetTimeActive(true); - // Carry global min/max information down so children get setup correctly. - inNode.m_ActivationManagerNode.m_StartTime = inGlobalMin; - inNode.m_ActivationManagerNode.m_StopTime = inGlobalMax; - } - // Is it worth looking at children at all - return inNode.IsUserActive(); - } - - void BuildTimeContext(TScanBuffer &inScanBuffer, IActivityZone &inZone) - { - Mutex::ScopedLock __locker(m_ElementAccessMutex); - QT3DS_ASSERT(m_TimeDataNeedsUpdate); - m_TimeDataNeedsUpdate = false; - SComponent &myNode = m_Component; - SElement *theChild = myNode.m_Child; - if (theChild == NULL) { - return; - } - inScanBuffer.clear(); - for (SElement *theChild = myNode.m_Child; theChild; theChild = theChild->m_Sibling) { - inScanBuffer.push_back(theChild); - } - for (QT3DSU32 idx = 0, end = (QT3DSU32)inScanBuffer.size(); idx < end; ++idx) { - SScanBufferEntry theEntry(inScanBuffer[idx]); - bool careAboutChildren = BuildTimeContextElementNode( - *theEntry.m_Node, theEntry.m_StartTime, theEntry.m_EndTime); - if (careAboutChildren && theEntry.m_Node->IsComponent() == false) { - for (SElement *theChild = theEntry.m_Node->m_Child; theChild; - theChild = theChild->m_Sibling) { - inScanBuffer.push_back(SScanBufferEntry( - theChild, theEntry.m_Node->m_ActivationManagerNode.m_StartTime, - theEntry.m_Node->m_ActivationManagerNode.m_StopTime)); - } - end = (QT3DSU32)inScanBuffer.size(); - } - if (theEntry.m_Node->IsComponent()) - inZone.AddActivityItems(*theEntry.m_Node); - } - } - - void SetElementDirty(SElement &inNode) - { - SElement *theComponentParent = &inNode.GetComponentParent(); - if (inNode.IsComponent() && inNode.m_Parent) - theComponentParent = &inNode.m_Parent->GetComponentParent(); - - QT3DS_ASSERT(theComponentParent == &m_Component); - if (m_AllNodesDirty == false) { - // We check independent items every frame anyway so it isn't worth setting them dirty - // here. - if (inNode.IsIndependent() == false) { - m_DirtyList.insert(inNode); - } - - // Dirty to root time context. This ensures that if we run an activate scan starting at - // a parent - // we won't have to re-run the scan at this node because it will not be dirty. - // This also makes sure that if we mark all nodes dirty we continue the activate scan - // till we hit at least - // this node. - SElement *theParent = inNode.m_Parent; - while (theParent) { - if (theParent->IsComponent() - || theParent->m_ActivationManagerNode.m_Flags.IsChildDirty()) - theParent = NULL; - else { - SActivationManagerNode &theNode = theParent->m_ActivationManagerNode; - theNode.m_Flags.SetChildDirty(); - theParent = theParent->m_Parent; - } - } - } - } - - static void UpdateItemScriptStatus(SElement &inNode, bool activeAndHasScript, - TElementAndSortKeyList &scriptBuffer) - { - QT3DSU32 theIndex = inNode.Depth(); - eastl::pair theInsertedItem(&inNode, theIndex); - if (activeAndHasScript) { - if (inNode.m_ActivationManagerNode.m_Flags.HasScript() == false) { - scriptBuffer.push_back(theInsertedItem); - inNode.m_ActivationManagerNode.m_Flags.SetHasScript(true); - } - } else { - if (inNode.m_ActivationManagerNode.m_Flags.HasScript() == true) { - TElementAndSortKeyList::iterator theFind = - eastl::find(scriptBuffer.begin(), scriptBuffer.end(), theInsertedItem); - if (theFind != scriptBuffer.end()) - scriptBuffer.erase(theFind); - inNode.m_ActivationManagerNode.m_Flags.SetHasScript(false); - } - } - } - - static void HandleActivationChange(SElement &inNode, TElementAndSortKeyList &activateBuffer, - TElementAndSortKeyList &deactivateBuffer, - TElementAndSortKeyList &scriptBuffer, - Mutex &inElementAccessMutex, bool &scriptBufferRequiresSort, - bool inIsActive) - { - Mutex::ScopedLock __locker(inElementAccessMutex); - TElementAndSortKey theKey(&inNode, inNode.Depth()); - if (inIsActive) { - activateBuffer.push_back(TElementAndSortKey(theKey)); - } else { - deactivateBuffer.push_back(theKey); - } - - if (inNode.Flags().HasScriptCallbacks()) { - UpdateItemScriptStatus(inNode, inIsActive, scriptBuffer); - scriptBufferRequiresSort = true; - } - inNode.SetGlobalActive(inIsActive); - } - - // Runs once we notice that the item's global active status has changed. - // Note we explicitly do not update independent items because those are updated - // as the first step of each time context update itself. - // We do, however, remove them from the dirty list here. - static void RunActivateScan(SElement &inNode, TScanBuffer &inScanBuffer, - TElementAndSortKeyList &activateBuffer, - TElementAndSortKeyList &deactivateBuffer, - TElementAndSortKeyList &scriptBuffer, Mutex &inElementAccessMutex, - bool &scriptBufferRequiresSort, bool inRunFullScan) - { - inScanBuffer.clear(); - - // Block used to hide variables to avoid an error. - { - bool parentActive = true; - SElement *theParent = inNode.m_Parent; - if (theParent != NULL) - parentActive = theParent->IsGlobalActive(); - - inScanBuffer.push_back(SScanBufferEntry(&inNode, parentActive)); - } - - for (QT3DSU32 idx = 0, end = inScanBuffer.size(); idx < end; ++idx) { - SScanBufferEntry theEntry(inScanBuffer[idx]); - SElement *theScanNode = theEntry.m_Node; - QT3DS_ASSERT(theScanNode->IsIndependent() == false); - bool parentActive = theEntry.IsParentActive(); - bool wasActive = theScanNode->IsGlobalActive(); - bool isActive = theScanNode->IsGlobalActive(parentActive); - bool wasChildDirty = theScanNode->m_ActivationManagerNode.m_Flags.IsChildDirty(); - theScanNode->m_ActivationManagerNode.m_Flags.ClearChildDirty(); - bool activateChange = isActive != wasActive; - bool checkChildren = activateChange || (isActive && (wasChildDirty || inRunFullScan)); - if (activateChange) { - HandleActivationChange(*theScanNode, activateBuffer, deactivateBuffer, scriptBuffer, - inElementAccessMutex, scriptBufferRequiresSort, isActive); - } - - if (checkChildren && theScanNode->m_Child) { - for (SElement *theScanNodeChild = theScanNode->m_Child; theScanNodeChild; - theScanNodeChild = theScanNodeChild->m_Sibling) { - if (theScanNodeChild->IsIndependent() == false) - inScanBuffer.push_back(SScanBufferEntry(theScanNodeChild, isActive)); - } - end = inScanBuffer.size(); - } - } - } - - void RunDirtyScan(TScanBuffer &inScanBuffer, TElementNodePtrList &inTempDirtyList, - TElementAndSortKeyList &activateBuffer, - TElementAndSortKeyList &deactivateBuffer, - TElementAndSortKeyList &scriptBuffer, bool &scriptBufferRequiresSort) - { - if (m_AllNodesDirty == true) { - inTempDirtyList.clear(); - SComponent &myNode = m_Component; - for (SElement *theChild = myNode.m_Child; theChild; theChild = theChild->m_Sibling) { - // Independent nodes don't need to be in the dirty list. - if (theChild->IsIndependent() == false) - inTempDirtyList.push_back(theChild); - } - } else { - inTempDirtyList.assign(m_DirtyList.begin(), m_DirtyList.end()); - // Reset nodes that are dirty to *not* be dirty. - m_DirtyList.clear(); - // We have to sort the dirty list because it may have nodes out of order and the active - // algorithm requires parents before children. We use the depth member variable to - // achieve this. - eastl::sort(inTempDirtyList.begin(), inTempDirtyList.end(), SElementPtrSort()); - } - for (QT3DSU32 idx = 0, end = (QT3DSU32)inTempDirtyList.size(); idx < end; ++idx) { - SElement &dirtyNode(*inTempDirtyList[idx]); - // This is slightly inefficient in the case where a both a child and parent are in the - // dirty list. - // This case has got to be extremely rare in practice, however. - RunActivateScan(dirtyNode, inScanBuffer, activateBuffer, deactivateBuffer, scriptBuffer, - m_ElementAccessMutex, scriptBufferRequiresSort, m_AllNodesDirty); - } - // Set at end so while debugging you can see if all nodes were dirty on method entry. - m_AllNodesDirty = false; - } - - bool Update(TTimeUnit inGlobalTime, TScanBuffer &inScanBuffer, - TElementNodePtrList &inTempDirtyList, TElementAndSortKeyList &activateBuffer, - TElementAndSortKeyList &deactivateBuffer, TElementAndSortKeyList &scriptBuffer, - bool &scriptBufferRequiresSort, Q3DStudio::CComponentManager &inComponentManager, - IPerfTimer &inPerfTimer, IActivityZone &inZone) - { - QT3DSU64 start = qt3ds::foundation::Time::getCurrentCounterValue(); - SComponent &theContextNode = m_Component; - bool parentActive = true; - SElement *theParent = theContextNode.m_Parent; - if (theParent != NULL) - parentActive = theParent->IsGlobalActive(); - - bool wasActive = theContextNode.IsGlobalActive(); - bool isActive = theContextNode.IsGlobalActive(parentActive); - bool activationChange = isActive != wasActive; - inPerfTimer.Update("ActivationManager - Update Initial Vars", - qt3ds::foundation::Time::getCurrentCounterValue() - start); - if (activationChange) { - SStackPerfTimer __timer(inPerfTimer, "ActivationManager - Activation Change"); - HandleActivationChange(theContextNode, activateBuffer, deactivateBuffer, scriptBuffer, - m_ElementAccessMutex, scriptBufferRequiresSort, isActive); - m_DirtyList.clear(); - m_AllNodesDirty = true; - if (isActive) { - Mutex::ScopedLock __locker(m_ElementAccessMutex); - inComponentManager.GotoSlideIndex(&theContextNode, 1, false); - } else - RemoveOverride(); - } - if (isActive) { - SStackPerfTimer __timer(inPerfTimer, "ActivationManager - Update Local Time"); - bool atEndOfTime = CalculateNewTime(inGlobalTime); - if (atEndOfTime) { - Mutex::ScopedLock __locker(m_ElementAccessMutex); - if (theContextNode.IsPlayThrough()) - inComponentManager.PlaythroughToSlide(&theContextNode); - } - // Note the slide may have changed here and thus updated our time policy. - // Set time active flags based on time. - UpdateLocalTime(m_TimePolicy.GetTime(), inScanBuffer, inZone); - } - if (isActive || activationChange) { - if (m_AllNodesDirty || m_DirtyList.size()) { - SStackPerfTimer __timer(inPerfTimer, "ActivationManager - Dirty Scan"); - RunDirtyScan(inScanBuffer, inTempDirtyList, activateBuffer, deactivateBuffer, - scriptBuffer, scriptBufferRequiresSort); - } - } - return isActive || activationChange; - } - - void GoToTime(TTimeUnit inTime) - { - if (m_TimePolicyOverride) { - m_TimePolicyOverride->SetTime(m_TimePolicy, inTime); - } else { - m_TimePolicy.SetTime(inTime); - } - } -}; - -IMPLEMENT_INVASIVE_SINGLE_LIST(TimeContext, m_NextSibling); - -struct SActivityZone : public IActivityZone -{ - typedef nvhash_map> TComponentTimeContextMap; - NVFoundationBase &m_Foundation; - Q3DStudio::CPresentation &m_Presentation; - IStringTable &m_StringTable; - nvvector m_RootElements; - TComponentTimeContextMap m_TimeContexts; - // These could potentially not be sorted but for 7.5 and TZ3 I don't want to risk the - // bugs assocated with not producing the exact same output as the original algorithm. - TElementAndSortKeyList m_ActivatedItems; - TElementAndSortKeyList m_DeactivatedItems; - - // This will always need to be sorted because it is maintained across update calls - TElementAndSortKeyList m_ScriptItems; - - // Temporaries used while scanning nodes for various features. - TScanBuffer m_ScanBuffer; - TElementNodePtrList m_TempDirtyList; - nvvector m_TimeContextScanBuffer; - - TTimeContextList m_RootContexts; - Mutex &m_ElementAccessMutex; - Mutex m_UpdateCheckMutex; - Sync m_UpdateSync; - TTimeUnit m_GlobalTime; - IPerfTimer *m_PerfTimer; - STypeDesc m_DummyTypeDesc; - SComponent m_DummyComponent; - STimeContext m_DummyContext; - bool m_Active; - // True if m_ScriptItems needs to be resorted. - bool m_ScriptRequiresSort; - bool m_Updating; - - QT3DSI32 mRefCount; - - SActivityZone(NVFoundationBase &inFnd, Q3DStudio::CPresentation &inPres, - IStringTable &inStrTable, Mutex &inElementAccessMutex) - : m_Foundation(inFnd) - , m_Presentation(inPres) - , m_StringTable(inStrTable) - , m_RootElements(inFnd.getAllocator(), "Elements") - , m_TimeContexts(inFnd.getAllocator(), "TimeContexts") - , m_ActivatedItems(inFnd.getAllocator(), "m_ActivatedItems") - , m_DeactivatedItems(inFnd.getAllocator(), "m_DeactivatedItems") - , m_ScriptItems(inFnd.getAllocator(), "m_ScriptItems") - , m_ScanBuffer(inFnd.getAllocator(), "m_ScanBuffer") - , m_TempDirtyList(inFnd.getAllocator(), "m_TempDirtyList") - , m_TimeContextScanBuffer(inFnd.getAllocator(), "m_TimeContextScanBuffer") - , m_ElementAccessMutex(inElementAccessMutex) - , m_UpdateCheckMutex(inFnd.getAllocator()) - , m_UpdateSync(inFnd.getAllocator()) - , m_GlobalTime(0) - , m_PerfTimer(NULL) - , m_DummyComponent(m_DummyTypeDesc) - , m_DummyContext(m_Foundation.getAllocator(), m_DummyComponent, m_ElementAccessMutex) - , m_Active(true) - , m_ScriptRequiresSort(true) - , m_Updating(false) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - Q3DStudio::CPresentation &GetPresentation() override { return m_Presentation; } - - static void SortElementBuffer(nvvector> &inBuffer) - { - eastl::sort(inBuffer.begin(), inBuffer.end(), SElementIndexPairSorter()); - } - - static void AddElementNodeToBuffer(nvvector> &inBuffer, - SElement &inNode) - { - eastl::pair insertItem(&inNode, inNode.Depth()); - QT3DS_ASSERT(eastl::find(inBuffer.begin(), inBuffer.end(), insertItem) == inBuffer.end()); - inBuffer.push_back(insertItem); - } - - TActivityItemBuffer GetActivatedItems() override { return m_ActivatedItems; } - - TActivityItemBuffer GetDeactivatedItems() override { return m_DeactivatedItems; } - // All active items that are script enabled. - TActivityItemBuffer GetScriptItems() override - { - // Created in a delayed way. - if (m_ScriptRequiresSort) { - m_ScriptRequiresSort = false; - SortElementBuffer(m_ScriptItems); - } - return m_ScriptItems; - } - - void SetZoneActive(bool inActive) override { m_Active = inActive; } - bool IsZoneActive() override { return m_Active; } - - SActivationManagerNode *GetElementNodeForElement(TActivityItem item) - { - return &item.m_ActivationManagerNode; - } - - STimeContext &GetItemTimeContext(SElement &inNode) - { - SElement &theComponent = inNode.GetComponentParent(); - if (!theComponent.IsComponent()) { - QT3DS_ASSERT(false); - return m_DummyContext; - } - - eastl::pair inserter = m_TimeContexts.insert( - eastl::make_pair(&theComponent, NVScopedRefCounted())); - if (inserter.second) { - inserter.first->second = QT3DS_NEW(m_Foundation.getAllocator(), STimeContext)( - m_Foundation.getAllocator(), static_cast(theComponent), - m_ElementAccessMutex); - STimeContext &theNewContext = *inserter.first->second; - if (theComponent.m_Parent == NULL) - m_RootContexts.push_back(theNewContext); - else { - STimeContext &parentContext = GetItemTimeContext(*theComponent.m_Parent); - parentContext.m_Children.push_back(theNewContext); - } - } - return *inserter.first->second.mPtr; - } - - void AddActivityItems(TActivityItem inNode) override - { - if (inNode.m_Parent == NULL) - m_RootElements.push_back(&inNode); - - GetItemTimeContext(inNode); - } - - CTimePolicy *GetOwnedTimePolicy(TActivityItem item) override - { - return &GetItemTimeContext(item).m_TimePolicy; - } - - virtual SComponentTimePolicyOverride * - GetOrCreateItemComponentOverride(TActivityItem item, float inMultiplier, TTimeUnit inEndTime, - IComponentTimeOverrideFinishedCallback *inCallback) override - { - STimeContext &theContext = GetItemTimeContext(item); - - theContext.RemoveOverride(); - theContext.m_TimePolicyOverride = - QT3DS_NEW(m_Foundation.getAllocator(), - SComponentTimePolicyOverride)(&item, inMultiplier, inEndTime, inCallback); - theContext.m_TimePolicy.SetPaused(false); - - return theContext.m_TimePolicyOverride; - } - - // If I am independent, then I am my own time parent. - // else travel up the chain till you find an indpendent node. - SElement &GetItemTimeParentNode(SElement &inNode) - { - if (inNode.m_Parent != NULL) { - SElement &theParent = *inNode.m_Parent; - if (theParent.IsIndependent()) - return theParent; - return GetItemTimeParentNode(theParent); - } - // All roots are time independent by definition. - return inNode; - } - - TActivityItemPtr GetItemTimeParent(SElement &inNode) override - { - return &GetItemTimeParentNode(inNode); - } - - void InsertIntoAppropriateDirtyList(SElement &inNode) - { - // This may need to be faster at some point... - GetItemTimeContext(inNode).SetElementDirty(inNode); - } - - bool GetItemUserActive(TActivityItem item) override { return item.IsExplicitActive(); } - - void UpdateItemScriptStatus(TActivityItem item) override - { - if (item.IsGlobalActive()) { - STimeContext::UpdateItemScriptStatus(item, item.Flags().HasScriptCallbacks(), - m_ScriptItems); - m_ScriptRequiresSort = true; - } - } - - void UpdateItemInfo(TActivityItem item) override { GetItemTimeContext(item).Reset(); } - - // Order of events will be: - // 1. On Slide Change - // 2. Time Update - // 3. On Slide Change - // 4. Update Local Time - void OnSlideChange(TActivityItem item) override - { - STimeContext &theContext = GetItemTimeContext(item); - // Rebuilding the context sets all the elements dirty. - // This takes care of everything *but* the script item changes. - theContext.Reset(); - theContext.RemoveOverride(); - } - - bool GetItemTimeActive(TActivityItem item) override - { - SActivationManagerNode *theNode = GetElementNodeForElement(item); - if (theNode) - return theNode->m_Flags.IsTimeActive(); - return false; - } - - TTimeUnit GetItemLocalTime(TActivityItem item) override - { - SElement *theElem = &item.GetComponentParent(); - if (item.IsComponent() && item.m_Parent) - theElem = &item.m_Parent->GetComponentParent(); - - return GetItemTimeContext(*theElem).m_CurrentTime; - } - - TTimeUnit GetItemComponentTime(TActivityItem item) override - { - return GetItemTimeContext(item).m_CurrentTime; - } - - bool IsUpdating() override - { - Mutex::ScopedLock __locker(m_UpdateCheckMutex); - return m_Updating; - } - - void EndUpdate() override - { - m_UpdateSync.reset(); - while (IsUpdating()) - m_UpdateSync.wait(); - } - - void DoUpdate() - { - SStackPerfTimer __timer(m_PerfTimer, "ActivationManager - DoUpdate"); - if (m_Active) { - // We know that parent elements are added before children. - // So we know the time contexts are in an appropriate order, assuming they completely - // resolve their results before the next time context runs. - Q3DStudio::CComponentManager &theManager = - static_cast(m_Presentation.GetComponentManager()); - m_TimeContextScanBuffer.clear(); - - for (TTimeContextList::iterator iter = m_RootContexts.begin(), - end = m_RootContexts.end(); - iter != end; ++iter) - m_TimeContextScanBuffer.push_back(&(*iter)); - - for (QT3DSU32 idx = 0, end = m_TimeContextScanBuffer.size(); idx < end; ++idx) { - STimeContext &theContext = *m_TimeContextScanBuffer[idx]; - bool checkChildren = - theContext.Update(m_GlobalTime, m_ScanBuffer, m_TempDirtyList, m_ActivatedItems, - m_DeactivatedItems, m_ScriptItems, m_ScriptRequiresSort, - theManager, *m_PerfTimer, *this); - if (checkChildren) { - for (TTimeContextList::iterator timeIter = theContext.m_Children.begin(), - timeEnd = theContext.m_Children.end(); - timeIter != timeEnd; ++timeIter) { - m_TimeContextScanBuffer.push_back(&(*timeIter)); - } - end = m_TimeContextScanBuffer.size(); - } - } - } - - eastl::sort(m_ActivatedItems.begin(), m_ActivatedItems.end(), SElementIndexPairSorter()); - eastl::sort(m_DeactivatedItems.begin(), m_DeactivatedItems.end(), - SElementIndexPairSorter()); - Mutex::ScopedLock __locker(m_UpdateCheckMutex); - { - m_Updating = false; - m_UpdateSync.set(); - } - } - - static void UpdateCallback(void *data) - { - SActivityZone *theZone = reinterpret_cast(data); - theZone->DoUpdate(); - } - - void BeginUpdate(TTimeUnit inGlobalTime, IPerfTimer &inPerfTimer, - IThreadPool &inThreadPool) override - { - // It is expected that an update is not running. - m_ActivatedItems.clear(); - m_DeactivatedItems.clear(); - m_GlobalTime = inGlobalTime; - m_PerfTimer = &inPerfTimer; - m_Updating = true; - inThreadPool.AddTask(this, UpdateCallback, NULL); - } - - void GoToTime(TActivityItem inItem, TTimeUnit inTime) override - { - GetItemTimeContext(inItem).GoToTime(inTime); - } -}; - -struct SActivityZoneManager : public IActivityZoneManager -{ - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - // Zones may access the element mutex on destruction *so* it is important that - // it is destroyed *after* the zone list. - Mutex m_ElementAccessMutex; - nvvector> m_Zones; - QT3DSI32 mRefCount; - - SActivityZoneManager(NVFoundationBase &fnd, IStringTable &inStrTable) - : m_Foundation(fnd) - , m_StringTable(inStrTable) - , m_ElementAccessMutex(m_Foundation.getAllocator()) - , m_Zones(m_Foundation.getAllocator(), "m_Zones") - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - IActivityZone &CreateActivityZone(Q3DStudio::CPresentation &inPresentation) override - { - m_Zones.push_back(QT3DS_NEW(m_Foundation.getAllocator(), SActivityZone)( - m_Foundation, inPresentation, m_StringTable, m_ElementAccessMutex)); - return *m_Zones.back().mPtr; - } -}; -} - -IActivityZoneManager & -IActivityZoneManager::CreateActivityZoneManager(NVFoundationBase &inFoundation, - IStringTable &inStrTable) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SActivityZoneManager)(inFoundation, inStrTable); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSAnimationSystem.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSAnimationSystem.cpp deleted file mode 100644 index 84d1c6db..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSAnimationSystem.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "RuntimePrefix.h" -#include "Qt3DSTypes.h" -#include "Qt3DSAnimationSystem.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSInvasiveSet.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSPool.h" -#include "Qt3DSElementSystem.h" -#include "Qt3DSCubicRoots.h" -#include "Qt3DSBezierEval.h" -#include "foundation/SerializationTypes.h" -#include "foundation/IOStreams.h" -#include "EASTL/sort.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSIndexableLinkedList.h" - -using namespace qt3ds::runtime; -using namespace qt3ds::runtime::element; - -namespace { - -struct SAnimationKey -{ - QT3DSF32 m_Time; ///< Time - QT3DSF32 m_Value; ///< Value - QT3DSF32 m_C1Time; ///< Control 1 time - QT3DSF32 m_C1Value; ///< Control 1 value - QT3DSF32 m_C2Time; ///< Control 2 time - QT3DSF32 m_C2Value; ///< Control 2 value - SAnimationKey() - : m_Time(0) - , m_Value(0) - , m_C1Time(0) - , m_C1Value(0) - , m_C2Time(0) - , m_C2Value(0) - { - } - - SAnimationKey(float time, float val, float c1time, float c1value, float c2time, float c2value) - : m_Time(time) - , m_Value(val) - , m_C1Time(c1time) - , m_C1Value(c1value) - , m_C2Time(c2time) - , m_C2Value(c2value) - { - } -}; - -struct SAnimationKeyNode -{ - enum { - AnimationKeyArraySize = 4, - }; - - SAnimationKey m_Data[AnimationKeyArraySize]; - SAnimationKeyNode *m_NextNode; - SAnimationKeyNode() - : m_NextNode(NULL) - { - } -}; - -typedef IndexableLinkedList - TAnimationKeyNodeList; - -struct SAnimationTrack -{ - SElement *m_Element; - QT3DSI32 m_Id; - QT3DSU32 m_PropertyIndex; - QT3DSU32 m_KeyCount; - SAnimationKeyNode *m_Keys; - QT3DSU32 m_ActiveSetIndex; - bool m_Dynamic; - - SAnimationTrack() - : m_Element(NULL) - , m_Id(0) - , m_PropertyIndex(0) - , m_KeyCount(0) - , m_Keys(NULL) - , m_ActiveSetIndex(QT3DS_MAX_U32) - , m_Dynamic(false) - { - } - SAnimationTrack(SElement &inElement, QT3DSI32 inId, QT3DSU32 inPropertyIndex, bool inIsDynamic) - : m_Element(&inElement) - , m_Id(inId) - , m_PropertyIndex(inPropertyIndex) - , m_KeyCount(0) - , m_Keys(NULL) - , m_ActiveSetIndex(QT3DS_MAX_U32) - , m_Dynamic(inIsDynamic) - { - } -}; - -struct GetAnimationTrackActiveSetIndex -{ - QT3DSU32 operator()(const SAnimationTrack &inTrack) const { return inTrack.m_ActiveSetIndex; } -}; - -struct SetAnimationTrackActiveSetIndex -{ - void operator()(SAnimationTrack &inTrack, QT3DSU32 inIdx) { inTrack.m_ActiveSetIndex = inIdx; } -}; - -typedef InvasiveSet - TAnimationTrackActiveSet; - -struct SAnimationTrackComparator -{ - bool operator()(SAnimationTrack *lhs, SAnimationTrack *rhs) const - { - return lhs->m_Id < rhs->m_Id; - } -}; - -struct SAnimSystem : public IAnimationSystem -{ - typedef nvhash_map TAnimationTrackHash; - - NVFoundationBase &m_Foundation; - Pool m_AnimationTrackPool; - Pool m_AnimationKeyNodePool; - TAnimationTrackHash m_Tracks; - SAnimationTrack *m_LastInsertedTrack; - TAnimationTrackActiveSet m_ActiveSet; - NVDataRef m_LoadData; - QT3DSI32 m_NextTrackId; - QT3DSI32 m_RefCount; - - SAnimSystem(NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , m_AnimationTrackPool( - ForwardingAllocator(inFoundation.getAllocator(), "AnimationTrackPool")) - , m_AnimationKeyNodePool( - ForwardingAllocator(inFoundation.getAllocator(), "AnimationKeyNodePool")) - , m_Tracks(inFoundation.getAllocator(), "m_Tracks") - , m_LastInsertedTrack(NULL) - , m_ActiveSet(inFoundation.getAllocator(), "m_ActiveSet") - , m_NextTrackId(1) - , m_RefCount(0) - { - } - - static QT3DSI32 IncrementTrackId(QT3DSI32 inTrackId) - { - ++inTrackId; - if (!inTrackId) - ++inTrackId; - return inTrackId; - } - - void addRef() override { atomicIncrement(&m_RefCount); } - - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc = m_Foundation.getAllocator(); - NVDelete(alloc, this); - } - } - - QT3DSI32 CreateAnimationTrack(element::SElement &inElement, QT3DSU32 inPropertyName, - bool inDynamic) override - { - // first, make sure we can find the property. - Option theIndex = inElement.FindPropertyIndex(inPropertyName); - Option theProperty; - if (theIndex.hasValue()) - theProperty = inElement.GetPropertyByIndex(*theIndex); - - if (theProperty.hasValue() == false - || theProperty->first.m_Type != Q3DStudio::ATTRIBUTETYPE_FLOAT) { - QT3DS_ASSERT(false); - return 0; - } - - eastl::pair inserter; - // Find unused track id. - for (inserter = m_Tracks.insert(eastl::make_pair(m_NextTrackId, (SAnimationTrack *)NULL)); - inserter.second == false; m_NextTrackId = IncrementTrackId(m_NextTrackId)) { - } - - SAnimationTrack *theNewTrack = - reinterpret_cast(m_AnimationTrackPool.allocate(__FILE__, __LINE__)); - new (theNewTrack) SAnimationTrack(inElement, inserter.first->first, *theIndex, inDynamic); - inserter.first->second = theNewTrack; - m_LastInsertedTrack = theNewTrack; - ++m_NextTrackId; - return inserter.first->first; - } - - SAnimationKey *GetKeyByIndex(QT3DSU32 inIndex, SAnimationTrack &inTrack) - { - if (inIndex >= inTrack.m_KeyCount) - return 0; - - return &TAnimationKeyNodeList::GetObjAtIdx(inTrack.m_Keys, inIndex); - } - - SAnimationKey &GetOrCreateKeyByIndex(QT3DSU32 inIndex, SAnimationTrack &inTrack) - { - if (inIndex < inTrack.m_KeyCount) - return *GetKeyByIndex(inIndex, inTrack); - - return TAnimationKeyNodeList::Create(inTrack.m_Keys, inTrack.m_KeyCount, - m_AnimationKeyNodePool); - } - - void AddKey(QT3DSF32 inTime, QT3DSF32 inValue, QT3DSF32 inC1Time, QT3DSF32 inC1Value, - QT3DSF32 inC2Time, QT3DSF32 inC2Value) override - { - if (m_LastInsertedTrack == NULL) { - QT3DS_ASSERT(false); - return; - } - SAnimationKey &theNewKey = - GetOrCreateKeyByIndex(m_LastInsertedTrack->m_KeyCount, *m_LastInsertedTrack); - theNewKey = SAnimationKey(inTime, inValue, inC1Time, inC1Value, inC2Time, inC2Value); - } - - SAnimationTrack *GetAnimationTrack(QT3DSI32 inTrackId) - { - TAnimationTrackHash::iterator iter = m_Tracks.find(inTrackId); - if (iter != m_Tracks.end()) - return iter->second; - return NULL; - } - - struct SNextKeyRetVal - { - SAnimationKeyNode *m_Node; - SAnimationKey *m_Start; - SAnimationKey *m_End; - - SNextKeyRetVal(SAnimationKeyNode &inNode) - : m_Node(&inNode) - , m_Start(NULL) - , m_End(NULL) - { - } - SNextKeyRetVal(SAnimationKeyNode &inNode, SAnimationKey &inLastKey) - : m_Node(&inNode) - , m_Start(NULL) - , m_End(&inLastKey) - { - } - SNextKeyRetVal(SAnimationKeyNode &inNode, SAnimationKey &inStart, SAnimationKey &inLastKey) - : m_Node(&inNode) - , m_Start(&inStart) - , m_End(&inLastKey) - { - } - SNextKeyRetVal() - : m_Node(NULL) - , m_Start(NULL) - , m_End(NULL) - { - } - }; - - SNextKeyRetVal NextKeyIsGreaterThan(TAnimationKeyNodeList::iterator iter, QT3DSF32 inTime) - { - SAnimationKey *theStartKey = &(*iter); - QT3DSU32 nextIdx = iter.m_Idx + 1; - if (nextIdx == iter.m_Count) - return SNextKeyRetVal(*iter.m_Node, *theStartKey); - - TAnimationKeyNodeList::iterator next = iter; - ++next; - - SAnimationKey &nextKey = *next; - - if (nextKey.m_Time >= inTime) - return SNextKeyRetVal(*iter.m_Node, *theStartKey, nextKey); - return SNextKeyRetVal(*iter.m_Node); - } - - QT3DSF32 Evaluate(SAnimationTrack &inTrack, QT3DSF32 inTime) - { - if (inTrack.m_KeyCount < 2) { - if (inTrack.m_KeyCount == 1) - return GetKeyByIndex(0, inTrack)->m_Value; - return 0.0f; - } - - TAnimationKeyNodeList::iterator iter = - TAnimationKeyNodeList::begin(inTrack.m_Keys, inTrack.m_KeyCount); - - if ((*iter).m_Time >= inTime) { - return (*iter).m_Value; - } - - // We know it isn't the first key. - SNextKeyRetVal theKeyData; - for (theKeyData = NextKeyIsGreaterThan(iter, inTime); theKeyData.m_End == NULL; - ++iter, theKeyData = NextKeyIsGreaterThan(iter, inTime)) { - } - - if (theKeyData.m_Node == NULL && theKeyData.m_End == NULL) { - QT3DS_ASSERT(false); - return 0.0f; - } - - if (theKeyData.m_Start != NULL) { - SAnimationKey &start(*theKeyData.m_Start); - SAnimationKey &end(*theKeyData.m_End); - return Q3DStudio::EvaluateBezierKeyframe( - inTime, start.m_Time, start.m_Value, start.m_C1Time, start.m_C1Value, - start.m_C2Time, start.m_C2Value, end.m_Time, end.m_Value); - } - return theKeyData.m_End->m_Value; - } - - void Update() override - { - for (QT3DSU32 idx = 0, end = m_ActiveSet.size(); idx < end; ++idx) { - SAnimationTrack &theTrack = *m_ActiveSet[idx]; - SElement &theElement = *theTrack.m_Element; - QT3DSF32 theTime = static_cast(theElement.GetOuterTime()); - TPropertyDescAndValuePtr theProperty = - *theElement.GetPropertyByIndex(theTrack.m_PropertyIndex); - Q3DStudio::UVariant &theValue(*theProperty.second); - QT3DSF32 newValue = Evaluate(theTrack, theTime); - if (fabs(theValue.m_FLOAT - newValue) > SElement::SmallestDifference()) { - theValue.m_FLOAT = newValue; - theElement.SetDirty(); - } - } - } - - void SetActive(QT3DSI32 inTrackId, bool inActive) override - { - SAnimationTrack *theTrack = GetAnimationTrack(inTrackId); - if (theTrack) { - if (inActive) - m_ActiveSet.insert(*theTrack); - else - m_ActiveSet.remove(*theTrack); - } - } - //============================================================================== - /** - * Recomputes control point values for Studio animation based off of new start - * value. - * @param inNewStartValue new start value for the keyframe - * @param inKeyStart start index of the keyframes - */ - void RecomputeControlPoints(QT3DSF32 inNewStartValue, SAnimationTrack &inTrack) - { - SAnimationKey &theFirstKey = *GetKeyByIndex(0, inTrack); - SAnimationKey &theSecondKey = *GetKeyByIndex(1, inTrack); - - // Determine original control point ratios - Q3DStudio::FLOAT theOriginalInterval = - (theSecondKey.m_Value - theFirstKey.m_Value) * (1.0f / 3.0f); - Q3DStudio::FLOAT theEaseOutRatio = theOriginalInterval != 0.0f - ? (theFirstKey.m_C1Value - theFirstKey.m_Value) / theOriginalInterval - : 0.0f; - Q3DStudio::FLOAT theEaseInRatio = theOriginalInterval != 0.0f - ? (theSecondKey.m_Value - theFirstKey.m_C2Value) / theOriginalInterval - : 0.0f; - - // Apply ratios based off new start value - Q3DStudio::FLOAT theNewInterval = (theSecondKey.m_Value - inNewStartValue) * (1.0f / 3.0f); - theFirstKey.m_C1Value = inNewStartValue + (theNewInterval * theEaseOutRatio); - theFirstKey.m_C2Value = theSecondKey.m_Value - (theNewInterval * theEaseInRatio); - } - - void UpdateDynamicKey(QT3DSI32 inTrackId) override - { - SAnimationTrack *theTrack = GetAnimationTrack(inTrackId); - if (theTrack && theTrack->m_Dynamic) { - SAnimationKey *theFirstKey = GetKeyByIndex(0, *theTrack); - if (theFirstKey) { - Q3DStudio::UVariant *thePropData = - theTrack->m_Element->GetPropertyByIndex(theTrack->m_PropertyIndex)->second; - - // Recompute interpolation - if (theTrack->m_KeyCount > 1) - RecomputeControlPoints(thePropData->m_FLOAT, *theTrack); - - // Update start value - theFirstKey->m_Value = thePropData->m_FLOAT; - } - } - } -}; -} - -IAnimationSystem &IAnimationSystem::CreateAnimationSystem(NVFoundationBase &inFoundation) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SAnimSystem)(inFoundation); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp deleted file mode 100644 index 249070c2..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp +++ /dev/null @@ -1,1831 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// We need a Qt header first here because Qt's metatype system insists that Bool -// can not be defined first before Qt headers are included and the includes below -// define Bool by way of Xll/XLib.h via khronos -> egl -> X11 -#include - -#include "RuntimePrefix.h" -#include "Qt3DSApplication.h" -#include "Qt3DSApplicationValues.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSMemory.h" -#include "Qt3DSRuntimeFactory.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/FileTools.h" -#include "Qt3DSIScriptBridge.h" -#include "foundation/Qt3DSOption.h" -#include "foundation/XML.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSContainers.h" -#include "EASTL/hash_map.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSInputEventTypes.h" -#include "Qt3DSSceneManager.h" -#include "Qt3DSIScene.h" -#include "Qt3DSInputEngine.h" -#include "Qt3DSStateVisualBindingContext.h" -#include "Qt3DSMetadata.h" -#include "Qt3DSUIPParser.h" -#include "foundation/Socket.h" -#include "Qt3DSStateDebugStreams.h" -#include "Qt3DSSceneGraphDebugger.h" -#include "Qt3DSSceneGraphDebuggerValue.h" -#include "EventPollingSystem.h" -#include "Qt3DSRenderContextCore.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/SerializationTypes.h" -#include "EASTL/sort.h" -#include "Qt3DSRenderBufferLoader.h" -#include "foundation/Qt3DSMutex.h" -#include "foundation/Qt3DSSync.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderThreadPool.h" -#include "foundation/StringConversionImpl.h" -#include "Qt3DSRenderLoadedTexture.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSActivationManager.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRenderShaderCache.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSAudioPlayer.h" -#include "Qt3DSElementSystem.h" -#include -#include -#include -#include "q3dsvariantconfig_p.h" - -using namespace qt3ds; -using namespace qt3ds::runtime; -using namespace Q3DStudio; -using qt3ds::state::debugger::ISceneGraphRuntimeDebugger; -using qt3ds::state::debugger::SSGPropertyChange; - -namespace qt3ds { -namespace foundation { -template <> -struct StringConversion -{ - void StrTo(const char8_t *buffer, QT3DSVec2 &item) - { - char *endPtr = NULL; - item.x = (float)strtod(buffer, &endPtr); - if (endPtr) - item.y = (float)strtod(endPtr, NULL); - } -}; -} -} - -namespace { -struct SDebugSettings -{ - eastl::string m_Server; - int m_Port; - bool m_Listen; - SDebugSettings() - : m_Port(0) - , m_Listen(false) - { - } -}; - -struct SFrameTimer -{ - int m_FrameCount; - QT3DSU64 m_FrameTime; - SFrameTimer(QT3DSU64 fc = 0) - : m_FrameCount(fc) - , m_FrameTime(qt3ds::foundation::Time::getCurrentCounterValue()) - { - } - - QT3DSF32 GetElapsedSeconds(QT3DSU64 currentTime) const - { - QT3DSU64 diff = currentTime - m_FrameTime; - QT3DSF32 diffNanos - = static_cast(qt3ds::foundation::Time::sCounterFreq.toTensOfNanos(diff)); - return diffNanos / qt3ds::foundation::Time::sNumTensOfNanoSecondsInASecond; - } - - QT3DSF32 GetElapsedSeconds() const - { - return GetElapsedSeconds(qt3ds::foundation::Time::getCurrentCounterValue()); - } - - QPair GetFPS(int updateFC) - { - int elapsedFrames = updateFC - m_FrameCount; - QT3DSU64 currentTime = qt3ds::foundation::Time::getCurrentCounterValue(); - QT3DSF32 elapsedSeconds = GetElapsedSeconds(currentTime); - QT3DSF32 retval = elapsedFrames / elapsedSeconds; - m_FrameCount = updateFC; - m_FrameTime = currentTime; - return qMakePair(retval, elapsedFrames); - } -}; - -struct SRefCountedAssetValue : public SAssetValue -{ - NVFoundationBase &m_Foundation; - QT3DSI32 mRefCount; - SRefCountedAssetValue(NVFoundationBase &fnd) - : SAssetValue() - , m_Foundation(fnd) - , mRefCount(0) - { - } - - SRefCountedAssetValue(NVFoundationBase &fnd, const SAssetValue &asset) - : SAssetValue(asset) - , m_Foundation(fnd) - , mRefCount(0) - { - } - - SRefCountedAssetValue(NVFoundationBase &fnd, const SPresentationAsset &asset) - : SAssetValue(asset) - , m_Foundation(fnd) - , mRefCount(0) - { - } - - SRefCountedAssetValue(NVFoundationBase &fnd, const SBehaviorAsset &asset) - : SAssetValue(asset) - , m_Foundation(fnd) - , mRefCount(0) - { - } - - SRefCountedAssetValue(NVFoundationBase &fnd, const SRenderPluginAsset &asset) - : SAssetValue(asset) - , m_Foundation(fnd) - , mRefCount(0) - { - } - - SRefCountedAssetValue(NVFoundationBase &fnd, const SSCXMLAsset &asset) - : SAssetValue(asset) - , m_Foundation(fnd) - , mRefCount(0) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) -}; - -typedef nvhash_map> TIdAssetMap; -typedef nvhash_map THashStrMap; -typedef nvvector>> -TIdAssetList; -typedef eastl::pair THandleElementPair; -typedef NVConstDataRef THandleElementDataBuffer; -typedef nvvector THandleElementDataBufferList; -typedef nvhash_map THandleElementMap; - -struct SHandleElementPairComparator -{ - bool operator()(const THandleElementPair &lhs, const THandleElementPair &rhs) const - { - return lhs.first < rhs.first; - } -}; - -struct SApp; - -class IAppLoadContext : public NVRefCounted -{ -public: - virtual void EndLoad() = 0; - virtual bool OnGraphicsInitialized(IRuntimeFactory &inFactory) = 0; - virtual bool HasCompletedLoading() = 0; - static IAppLoadContext &CreateXMLLoadContext( - SApp &inApp, NVConstDataRef inStateReferences, - const char8_t *inScaleMode); -}; - -inline float Clamp(float val, float inMin = 0.0f, float inMax = 1.0f) -{ - if (val < inMin) - return inMin; - if (val > inMax) - return inMax; - return val; -} - -// A set of common settings that may come from the UIA or from the command line. -// command line settings always override uia settings. -struct SApplicationSettings -{ - Option m_LayerCacheEnabled; - Option m_LayerGpuProfilingEnabled; - Option m_ShaderCachePersistenceEnabled; - - SApplicationSettings() {} - - template - static Option Choose(const Option &inCommandLine, - const Option &inUIAFile) - { - if (inCommandLine.hasValue()) - return inCommandLine; - return inUIAFile; - } - - SApplicationSettings(const SApplicationSettings &inCommandLine, - const SApplicationSettings &inUIAFileSettings) - : m_LayerCacheEnabled( - Choose(inCommandLine.m_LayerCacheEnabled, inUIAFileSettings.m_LayerCacheEnabled)) - , m_LayerGpuProfilingEnabled(Choose(inCommandLine.m_LayerGpuProfilingEnabled, - inUIAFileSettings.m_LayerGpuProfilingEnabled)) - , m_ShaderCachePersistenceEnabled(Choose(inCommandLine.m_ShaderCachePersistenceEnabled, - inUIAFileSettings.m_ShaderCachePersistenceEnabled)) - { - } - - static const char8_t *LayerCacheName() { return "layer-caching"; } - static const char8_t *LayerGpuProfilerName() { return "layer-gpu-profiling"; } - static const char8_t *ShaderCacheName() { return "shader-cache-persistence"; } - - void ParseBoolEnableDisableItem(const IDOMReader &inReader, const char8_t *itemName, - Option &itemValue) - { - const char8_t *inItem; - if (const_cast(inReader).UnregisteredAtt(itemName, inItem)) { - if (AreEqualCaseless(inItem, "disabled")) - itemValue = false; - else - itemValue = true; - } - } - - void ParseBoolEnableDisableItem(const eastl::vector &inCommandLine, - const char8_t *itemName, Option &itemValue) - { - eastl::string temp; - temp.assign("-"); - temp.append(itemName); - for (QT3DSU32 idx = 0, end = inCommandLine.size(); idx < end; ++idx) { - if (inCommandLine[idx].find(temp) == 0) { - if (inCommandLine[idx].length() == temp.size()) { - qCWarning(qt3ds::INVALID_OPERATION) - << "Unable to parse parameter %s. Please pass =enable|disable as " - << "part of the parameter. " << temp.c_str(); - } else { - temp = inCommandLine[idx].substr(temp.size() + 1); - eastl::string::size_type start = temp.find_first_of("'\""); - if (start != eastl::string::npos) - temp.erase(0, start); - - eastl::string::size_type end = temp.find_first_of("'\""); - if (end != eastl::string::npos) - temp.erase(end); - if (AreEqualCaseless(temp.c_str(), "disabled")) - itemValue = false; - else - itemValue = true; - qCInfo(qt3ds::INVALID_OPERATION) - << "Item " << itemName - << (itemValue ? " enabled" : " disabled"); - } - } - } - } - - template - void ParseItems(const TReaderType &inReader) - { - ParseBoolEnableDisableItem(inReader, LayerCacheName(), m_LayerCacheEnabled); - ParseBoolEnableDisableItem(inReader, LayerGpuProfilerName(), m_LayerGpuProfilingEnabled); - ParseBoolEnableDisableItem(inReader, ShaderCacheName(), m_ShaderCachePersistenceEnabled); - } - - void Parse(IDOMReader &inReader) { ParseItems(inReader); } - - void Parse(const eastl::vector &inCommandLine) { ParseItems(inCommandLine); } - - struct SOptionSerializer - { - bool m_HasValue; - bool m_Value; - QT3DSU8 m_Padding[2]; - SOptionSerializer(const Option &inValue = Empty()) - : m_HasValue(inValue.hasValue()) - , m_Value(inValue.hasValue() ? *inValue : false) - { - m_Padding[0] = 0; - m_Padding[1] = 0; - } - - operator Option() const - { - if (m_HasValue) - return m_Value; - return Empty(); - } - }; - - void Save(IOutStream &outStream) const - { - outStream.Write(SOptionSerializer(m_LayerCacheEnabled)); - outStream.Write(SOptionSerializer(m_LayerGpuProfilingEnabled)); - outStream.Write(SOptionSerializer(m_ShaderCachePersistenceEnabled)); - } - - void Load(IInStream &inStream) - { - SOptionSerializer s; - inStream.Read(s); - m_LayerCacheEnabled = s; - inStream.Read(s); - m_LayerGpuProfilingEnabled = s; - inStream.Read(s); - m_ShaderCachePersistenceEnabled = s; - } -}; - -struct SDummyAudioPlayer : public IAudioPlayer -{ - virtual ~SDummyAudioPlayer() {} - bool PlaySoundFile(const char *inFilePath) override - { - (void *)inFilePath; - qCWarning(qt3ds::TRACE_INFO) - << "Qt3DSTegraApplication: Unimplemented method IAudioPlayer::PlaySoundFile"; - return false; - } -} g_DummyAudioPlayer; - -struct SAudioPlayerWrapper : public IAudioPlayer -{ -private: - IApplication *m_Application; - IAudioPlayer *m_RealPlayer; - -public: - SAudioPlayerWrapper() - : m_Application(0) - , m_RealPlayer(&g_DummyAudioPlayer) - { - } - virtual ~SAudioPlayerWrapper() {} - - void SetApplication(IApplication &inApplication) { m_Application = &inApplication; } - - void SetPlayer(IAudioPlayer *inPlayer) - { - if (inPlayer) - m_RealPlayer = inPlayer; - else - m_RealPlayer = &g_DummyAudioPlayer; - } - - bool PlaySoundFile(const char *inFilePath) override - { - eastl::string theFilePath(nonNull(inFilePath)); - if (m_RealPlayer != &g_DummyAudioPlayer) { - qt3ds::foundation::CFileTools::CombineBaseAndRelative( - m_Application->GetProjectDirectory().c_str(), inFilePath, theFilePath); - } - return m_RealPlayer->PlaySoundFile(theFilePath.c_str()); - } -}; - -struct SApp : public IApplication -{ - - NVScopedRefCounted m_CoreFactory; - NVScopedRefCounted m_RuntimeFactory; - - Q3DStudio::CInputEngine *m_InputEnginePtr; - CAppStr m_ApplicationDir; - CAppStr m_ProjectDir; - Option m_DebugSettings; - CAppStr m_InitialPresentationId; - CAppStr m_DLLDirectory; - TIdAssetMap m_AssetMap; - // Keep the assets ordered. This enables the uia order to mean something. - TIdAssetList m_OrderedAssets; - SPickFrame m_PickFrame; - SPickFrame m_MousePickCache; - SPickFrame m_MouseOverCache; - THashStrMap m_HashStrMap; - CTimer m_Timer; - Q3DStudio::INT64 m_ManualTime; - SFrameTimer m_FrameTimer; - Q3DStudio::INT32 m_FrameCount; - // the name of the file without extension. - eastl::string m_Filename; - Q3DSVariantConfig m_variantConfig; - - qt3ds::foundation::NVScopedReleasable m_MetaData; - nvvector> m_Behaviors; - NVScopedRefCounted m_SocketSystem; - NVScopedRefCounted m_ServerStream; - NVScopedRefCounted m_ProtocolSocket; - NVScopedRefCounted m_StateDebugger; - NVScopedRefCounted m_SceneGraphDebugger; - NVScopedRefCounted m_ActivityZoneManager; - NVScopedRefCounted m_ElementAllocator; - nvvector m_ChangeBuffer; - - // Handles are loaded sorted but only added to the handle map when needed. - nvvector m_LoadBuffer; - nvvector m_PresentationBuffer; - Mutex m_RunnableMutex; - nvvector> m_ThreadRunnables; - nvvector> m_MainThreadRunnables; - NVScopedRefCounted m_AppLoadContext; - bool m_HideFPS; - bool m_DisableState; - bool m_ProfileLogging; - bool m_LastRenderWasDirty; - QT3DSU64 m_LastFrameStartTime; - QT3DSU64 m_ThisFrameStartTime; - double m_MillisecondsSinceLastFrame; - // We get odd oscillations if we do are too quick to report that the frame wasn't dirty - // after input. - int m_DirtyCountdown; - SApplicationSettings m_UIAFileSettings; - eastl::pair, size_t> m_ElementLoadResult; - - SAudioPlayerWrapper m_AudioPlayer; - - Qt3DSAssetVisitor *m_visitor; - - bool m_createSuccessful; - - DataInputMap m_dataInputs; - - QT3DSI32 mRefCount; - SApp(Q3DStudio::IRuntimeFactoryCore &inFactory, const char8_t *inAppDir) - : m_CoreFactory(inFactory) - , m_InputEnginePtr(NULL) - , m_ApplicationDir(inFactory.GetFoundation().getAllocator()) - , m_ProjectDir(inFactory.GetFoundation().getAllocator()) - , m_InitialPresentationId(inFactory.GetFoundation().getAllocator()) - , m_DLLDirectory(inFactory.GetFoundation().getAllocator()) - , m_AssetMap(inFactory.GetFoundation().getAllocator(), "SApp::m_AssetMap") - , m_OrderedAssets(inFactory.GetFoundation().getAllocator(), "SApp::m_OrderedAssets") - , m_HashStrMap(inFactory.GetFoundation().getAllocator(), "SApp::m_HashStrMap") - , m_Timer(inFactory.GetTimeProvider()) - , m_ManualTime(0) - , m_FrameCount(0) - , m_Behaviors(inFactory.GetFoundation().getAllocator(), "SApp::m_Behaviors") - , m_ActivityZoneManager(IActivityZoneManager::CreateActivityZoneManager( - inFactory.GetFoundation(), inFactory.GetStringTable())) - , m_ElementAllocator(IElementAllocator::CreateElementAllocator(inFactory.GetFoundation(), - inFactory.GetStringTable())) - , m_ChangeBuffer(inFactory.GetFoundation().getAllocator(), "SApp::m_ChangeBuffer") - , m_LoadBuffer(inFactory.GetFoundation().getAllocator(), "SApp::m_LoadBuffer") - , m_PresentationBuffer(inFactory.GetFoundation().getAllocator(), - "SApp::m_PresentationBuffer") - , m_RunnableMutex(inFactory.GetFoundation().getAllocator()) - , m_ThreadRunnables(inFactory.GetFoundation().getAllocator(), "SApp::m_ThreadRunnables") - , m_MainThreadRunnables(inFactory.GetFoundation().getAllocator(), - "SApp::m_MainThreadRunnables") - , m_HideFPS(true) - , m_DisableState(false) - , m_ProfileLogging(false) - , m_LastRenderWasDirty(true) - , m_LastFrameStartTime(0) - , m_ThisFrameStartTime(0) - , m_MillisecondsSinceLastFrame(0) - , m_DirtyCountdown(5) - , m_createSuccessful(false) - , mRefCount(0) - , m_visitor(nullptr) - { - m_AudioPlayer.SetApplication(*this); - eastl::string tempStr(inAppDir); - CFileTools::NormalizePath(tempStr); - m_ApplicationDir.assign(tempStr.c_str()); - - Q3DStudio_memset(&m_PickFrame, 0, sizeof(SPickFrame)); - Q3DStudio_memset(&m_MousePickCache, 0, sizeof(SPickFrame)); - Q3DStudio_memset(&m_MouseOverCache, 0, sizeof(SPickFrame)); - - m_Timer.Start(); - - m_CoreFactory->SetApplicationCore(this); - m_CoreFactory->GetScriptEngineQml().SetApplicationCore(*this); - - m_CoreFactory->AddSearchPath(tempStr.c_str()); - } - - ~SApp() - { - EndLoad(); - { - Mutex::ScopedLock __locker(m_RunnableMutex); - m_ThreadRunnables.clear(); - } - // Ensure we stop the timer. - HasCompletedLoading(); - m_AppLoadContext = NULL; - - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - SAssetValue &theAsset = *m_OrderedAssets[idx].second; - if (theAsset.getType() == AssetValueTypes::Presentation) { - SPresentationAsset &thePresAsset = *theAsset.getDataPtr(); - if (thePresAsset.m_Presentation) { - Q3DStudio_delete(thePresAsset.m_Presentation, CPresentation); - thePresAsset.m_Presentation = NULL; - } - } - } - } - - void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *v) override - { - m_visitor = v; - } - - NVDataRef GetPresentations() - { - if (m_PresentationBuffer.empty()) { - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - SAssetValue &theAsset = *m_OrderedAssets[idx].second; - if (theAsset.getType() == AssetValueTypes::Presentation) { - SPresentationAsset &thePresAsset = *theAsset.getDataPtr(); - if (thePresAsset.m_Presentation) - m_PresentationBuffer.push_back(thePresAsset.m_Presentation); - } - } - } - return m_PresentationBuffer; - } - - void addRef() override { atomicIncrement(&mRefCount); } - - void release() override - { - atomicDecrement(&mRefCount); - if (mRefCount <= 0) - NVDelete(m_CoreFactory->GetFoundation().getAllocator(), this); - } - - void QueueForMainThread(IAppRunnable &inRunnable) override - { - Mutex::ScopedLock __locker(m_RunnableMutex); - m_ThreadRunnables.push_back(inRunnable); - } - - // Debugging is disabled by default. - void EnableDebugging(bool inListen, const char8_t *inServer = NULL, int inPort = 0) override - { - SDebugSettings theSettings; - theSettings.m_Server.assign(nonNull(inServer)); - if (theSettings.m_Server.size() == 0) - theSettings.m_Server = "localhost"; - theSettings.m_Port = inPort; - if (!inPort) - theSettings.m_Port = 8172; - theSettings.m_Listen = inListen; - m_DebugSettings = theSettings; - // Done at load time only. - } - - // state machine is enabled by default - void DisableStateMachine() override { m_DisableState = true; } - - virtual void EnableProfileLogging() - { - m_ProfileLogging = true; - if (m_RuntimeFactory) - m_RuntimeFactory->GetScriptEngineQml().EnableProfiling(); - } - - // Verbose logging is disabled by default. - virtual void SetVerboseLogging(bool inEnableVerboseLogging) - { - - } - - //////////////////////////////////////////////////////////////////////////// - // Update rhythm implementations - //////////////////////////////////////////////////////////////////////////// - - void SetPickFrame(const SPickFrame &inPickFrame) - { - // The model has changed, fire enter and exit mouse events - if (inPickFrame.m_Model != m_PickFrame.m_Model) { - // For determining onGroupedMouseOver/Out: - // arg1 = the original onMouseOut model and arg2 = the original onMouseOver model - UVariant theMouseOutModel; - UVariant theMouseOverModel; - theMouseOutModel.m_VoidPointer = m_PickFrame.m_Model; - theMouseOverModel.m_VoidPointer = inPickFrame.m_Model; - - // It seems like you would want to 'onMouseOut' before you 'onMouseOver' something new? - if (m_PickFrame.m_Model) { - m_PickFrame.m_Model->GetBelongedPresentation()->FireEvent( - ON_MOUSEOUT, m_PickFrame.m_Model, &theMouseOutModel, &theMouseOverModel, - ATTRIBUTETYPE_POINTER, ATTRIBUTETYPE_POINTER); - } - if (inPickFrame.m_Model) { - inPickFrame.m_Model->GetBelongedPresentation()->FireEvent( - ON_MOUSEOVER, inPickFrame.m_Model, &theMouseOutModel, &theMouseOverModel, - ATTRIBUTETYPE_POINTER, ATTRIBUTETYPE_POINTER); - m_MouseOverCache = inPickFrame; - } - } - - const TEventCommandHash *theEventArray[] = { &ON_MOUSEDOWN, &ON_MOUSEUP, - &ON_MIDDLEMOUSEDOWN, &ON_MIDDLEMOUSEUP, - &ON_RIGHTMOUSEDOWN, &ON_RIGHTMOUSEUP }; - const TEventCommandHash *theClickEventArray[] = { &ON_MOUSECLICK, &ON_MIDDLEMOUSECLICK, - &ON_RIGHTMOUSECLICK }; - - // Click events... - // NOTE: This is a fancy way to iterate programatically over all the handled mouse inputs - // handled (declared in AKPickFrame.h for now) - // we iterate to INPUTBUTTONCOUNT (see comment in AKPickFrame.h) * 2, because we handle - // mouse down and up - for (QT3DSI32 theMouseEvtIter = 0; theMouseEvtIter < MOUSEBUTTONCOUNT - 1; - theMouseEvtIter++) { - // we effectively iterate to MOUSEBUTTONCOUNT * 2 (see comment in AKPickFrame.h) to - // handle mouse down and up - QT3DSI32 theMouseDownFlag = 1 << (theMouseEvtIter * 2); - QT3DSI32 theMouseUpFlag = 1 << (theMouseEvtIter * 2 + 1); - - // on*MouseDown - // if this frame, the mouse button is down, and last frame it wasn't (new down click) - if (inPickFrame.m_Model && inPickFrame.m_InputFrame.m_MouseFlags & theMouseDownFlag - && !(m_PickFrame.m_InputFrame.m_MouseFlags & theMouseDownFlag)) { - // fire the 'on*MouseDown' event - which is at the even indices since the down - // events for each button are before the up - inPickFrame.m_Model->GetBelongedPresentation()->FireEvent( - *theEventArray[theMouseEvtIter * 2], inPickFrame.m_Model); - - // cache this as the last item we 'onMouseDown' on - m_MousePickCache = inPickFrame; - } - - // on*MouseUp - // if we mouse up on anything, send the event - if (inPickFrame.m_InputFrame.m_MouseFlags & theMouseUpFlag) { - // fire the 'on*MouseUp' event - odd indices (1,3,5 etc) - if (m_MousePickCache.m_Model) { - m_MousePickCache.m_Model->GetBelongedPresentation()->FireEvent( - *theEventArray[theMouseEvtIter * 2 + 1], m_MousePickCache.m_Model); - } - - // on*MouseClick - // if we had a up click on the same item we were mouse down on last frame ... we had - // a click - if (inPickFrame.m_Model && inPickFrame.m_Model == m_MousePickCache.m_Model) { - inPickFrame.m_Model->GetBelongedPresentation()->FireEvent( - *theClickEventArray[theMouseEvtIter], inPickFrame.m_Model); - } - - // clear the stored 'last mouse down' since we just got a mouse up - Q3DStudio_memset(&m_MousePickCache, 0, sizeof(SPickFrame)); - } - - // on*MouseDblClick - } - - if (m_MouseOverCache.m_Model) { - - if (inPickFrame.m_InputFrame.m_MouseFlags & VSCROLLWHEEL) { - UVariant theScrollValue; - theScrollValue.m_INT32 = inPickFrame.m_InputFrame.m_ScrollValue; - m_MouseOverCache.m_Model->GetBelongedPresentation()->FireEvent( - ON_VERTICALSCROLLWHEEL, m_MouseOverCache.m_Model, &theScrollValue, - NULL, ATTRIBUTETYPE_INT32); - } else if (inPickFrame.m_InputFrame.m_MouseFlags & HSCROLLWHEEL) { - UVariant theScrollValue; - theScrollValue.m_INT32 = inPickFrame.m_InputFrame.m_ScrollValue; - m_MouseOverCache.m_Model->GetBelongedPresentation()->FireEvent( - ON_HORIZONTALSCROLLWHEEL, m_MouseOverCache.m_Model, &theScrollValue, - NULL, ATTRIBUTETYPE_INT32); - } - } - - // Do this last - m_PickFrame = inPickFrame; - } - - void ClearPresentationDirtyLists() - { - NVDataRef thePresentations(GetPresentations()); - for (QT3DSU32 idx = 0, end = thePresentations.size(); idx < end; ++idx) - thePresentations[idx]->ClearDirtyList(); - } - - void UpdatePresentations() - { - SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), "UpdatePresentations"); - // Transfer the input frame to the kernel for pick processing - // the scene manager now handles the picking on each of its scenes - SetPickFrame(m_RuntimeFactory->GetSceneManager().AdvancePickFrame( - m_InputEnginePtr->GetInputFrame())); - // clear up mouse flag for horizontal and vertical scroll - m_InputEnginePtr->GetInputFrame().m_MouseFlags &= !(HSCROLLWHEEL | VSCROLLWHEEL); - - // Update all the presentations. - // Animations are advanced based on m_Timer by default, but this can be overridden via - // SetTimeMilliSecs(). - Q3DStudio::INT64 globalTime(GetTimeMilliSecs()); - - NVDataRef thePresentations(GetPresentations()); - - { - SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), - "UpdatePresentations - pre update"); - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { - SPresentationAsset &theAsset( - *m_OrderedAssets[idx].second->getDataPtr()); - CPresentation *thePresentation = theAsset.m_Presentation; - if (thePresentation && thePresentation->GetActive()) - thePresentation->PreUpdate(globalTime); - } - } - } - { - SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), - "UpdatePresentations - begin update"); - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { - SPresentationAsset &theAsset( - *m_OrderedAssets[idx].second->getDataPtr()); - CPresentation *thePresentation = theAsset.m_Presentation; - if (thePresentation && thePresentation->GetActive()) - thePresentation->BeginUpdate(); - } - } - } - { - SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), - "UpdatePresentations - end update"); - - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { - SPresentationAsset &theAsset( - *m_OrderedAssets[idx].second->getDataPtr()); - CPresentation *thePresentation = theAsset.m_Presentation; - // allow EndUpdate also for inactive presentations so that we can - // activate it - if (thePresentation) - thePresentation->EndUpdate(); - } - } - } - { - SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), - "UpdatePresentations - postupdate"); - - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { - SPresentationAsset &theAsset( - *m_OrderedAssets[idx].second->getDataPtr()); - CPresentation *thePresentation = theAsset.m_Presentation; - // allow PostUpdate also for inactive presentations so that we can - // activate it - if (thePresentation) - thePresentation->PostUpdate(globalTime); - } - } - } - - // Run the garbage collection - m_CoreFactory->GetScriptEngineQml().StepGC(); - } - - void UpdateScenes() { m_RuntimeFactory->GetSceneManager().Update(); } - - void Render() - { - SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), "Render"); - CPresentation *pres = GetPrimaryPresentation(); - if (pres) - m_LastRenderWasDirty = m_RuntimeFactory->GetSceneManager().RenderPresentation(pres); - } - - void ResetDirtyCounter() { m_DirtyCountdown = 5; } - - // Update all the presentations and render them. - void UpdateAndRender() override - { - QT3DS_ASSERT(m_AppLoadContext.mPtr == NULL); - m_ThisFrameStartTime = qt3ds::foundation::Time::getCurrentCounterValue(); - if (m_LastFrameStartTime) { - QT3DSU64 durationSinceLastFrame = m_ThisFrameStartTime - m_LastFrameStartTime; - m_MillisecondsSinceLastFrame = - qt3ds::foundation::Time::sCounterFreq.toTensOfNanos(durationSinceLastFrame) - * (1.0 / 100000.0); - } else { - m_MillisecondsSinceLastFrame = 0; - } - - if (m_ProtocolSocket) - m_ProtocolSocket->MessagePump(); - ++m_FrameCount; - - // Update any state systems - if (!m_DisableState) - m_CoreFactory->GetVisualStateContext().Initialize(); - - // First off, update any application level behaviors. - IScriptBridge &theScriptEngine = m_CoreFactory->GetScriptEngineQml(); - for (QT3DSU32 idx = 0, end = m_Behaviors.size(); idx < end; ++idx) { - eastl::pair &entry(m_Behaviors[idx]); - if (!entry.second) { - entry.second = true; - theScriptEngine.ExecuteApplicationScriptFunction(entry.first.m_Handle, - "onInitialize"); - } - } - - // TODO: Initialize presentations - - // Start any state systems - if (!m_DisableState) - m_CoreFactory->GetVisualStateContext().Start(); - - for (QT3DSU32 idx = 0, end = m_Behaviors.size(); idx < end; ++idx) { - eastl::pair &entry(m_Behaviors[idx]); - theScriptEngine.ExecuteApplicationScriptFunction(entry.first.m_Handle, "onUpdate"); - } - - if (!m_DisableState) - m_CoreFactory->GetVisualStateContext().Update(); - - UpdatePresentations(); - - if (m_ProtocolSocket) { - m_ProtocolSocket->MessagePump(); - if (m_ProtocolSocket->Connected() == false) - exit(0); - } - - UpdateScenes(); - - Render(); - - GetSceneGraphDebugger(); - - if (m_SceneGraphDebugger->IsConnected()) { - NVDataRef thePresentations(GetPresentations()); - size_t thePresentationCount = thePresentations.size(); - for (QT3DSU32 thePresentationIndex = 0; thePresentationIndex < thePresentationCount; - thePresentationIndex++) { - CPresentation *thePresentation = thePresentations[thePresentationIndex]; - Q3DStudio::TElementList &theDirtyList = - thePresentation->GetFrameData().GetDirtyList(); - for (QT3DSU32 idx = 0, end = theDirtyList.GetCount(); idx < end; ++idx) { - Q3DStudio::TElement &theElement = *theDirtyList[idx]; - // Set active - m_ChangeBuffer.push_back(SSGPropertyChange()); - QT3DSI32 active = theElement.GetActive() ? 1 : 0; - m_ChangeBuffer.back().m_Hash = CHash::HashAttribute("active"); - m_ChangeBuffer.back().m_Value = qt3ds::state::debugger::SSGValue(active); - for (long attIdx = 0, attEnd = theElement.GetAttributeCount(); attIdx < attEnd; - ++attIdx) { - Option theValue = - theElement.GetPropertyByIndex(attIdx); - m_ChangeBuffer.push_back(SSGPropertyChange()); - SSGPropertyChange &theChange(m_ChangeBuffer.back()); - theChange.m_Hash = theValue->first.GetNameHash(); - Q3DStudio::EAttributeType theAttType = theValue->first.m_Type; - switch (theAttType) { - case ATTRIBUTETYPE_HASH: - case ATTRIBUTETYPE_BOOL: - case ATTRIBUTETYPE_INT32: - theChange.m_Value = - qt3ds::state::debugger::SSGValue( - (QT3DSI32)theValue->second->m_INT32); - break; - case ATTRIBUTETYPE_FLOAT: - theChange.m_Value = - qt3ds::state::debugger::SSGValue(theValue->second->m_FLOAT); - break; - case ATTRIBUTETYPE_STRING: { - CRegisteredString data = m_CoreFactory->GetStringTable().HandleToStr( - theValue->second->m_StringHandle); - theChange.m_Value = qt3ds::state::debugger::SSGValue(data); - } break; - case ATTRIBUTETYPE_POINTER: { - void *ptrVal = theValue->second->m_VoidPointer; - QT3DSU64 coercedVal = (QT3DSU64)ptrVal; - theChange.m_Value = qt3ds::state::debugger::SSGValue(coercedVal); - } break; - case ATTRIBUTETYPE_ELEMENTREF: { - void *ptrVal = GetElementByHandle(theValue->second->m_ElementHandle); - QT3DSU64 coercedVal = (QT3DSU64)ptrVal; - theChange.m_Value = qt3ds::state::debugger::SSGValue(coercedVal); - } break; - default: - QT3DS_ASSERT(false); - break; - } - } - // If this is a component element, we have a few more properties we need to - // grab. - if (theElement.IsComponent()) { - TComponent &theComponent = static_cast(theElement); - QT3DSI32 slide = theComponent.GetCurrentSlide(); - QT3DSI32 isPaused = theComponent.GetPaused() ? 1 : 0; - QT3DSI32 time - =(QT3DSI32)thePresentation->GetActivityZone()->GetItemComponentTime( - theComponent); - m_ChangeBuffer.push_back( - SSGPropertyChange(CHash::HashAttribute("slide"), slide)); - m_ChangeBuffer.push_back( - SSGPropertyChange(CHash::HashAttribute("paused"), isPaused)); - m_ChangeBuffer.push_back( - SSGPropertyChange(CHash::HashAttribute("time"), time)); - } - if (m_ChangeBuffer.size()) { - m_SceneGraphDebugger->OnPropertyChanged(&theElement, m_ChangeBuffer); - m_ChangeBuffer.clear(); - } - } - } - m_SceneGraphDebugger->EndFrame(); - } - - m_InputEnginePtr->ClearInputFrame(); - ClearPresentationDirtyLists(); - - if (m_ProtocolSocket) - m_ProtocolSocket->MessagePump(); - - if (!m_CoreFactory->GetEventSystem().GetAndClearEventFetchedFlag()) - m_CoreFactory->GetEventSystem().PurgeEvents(); // GetNextEvents of event system has not - // been called in this round, so clear - // events to avoid events to be piled up - - QT3DSU64 updateEndTime = qt3ds::foundation::Time::getCurrentCounterValue(); - QT3DSU64 updateDuration = updateEndTime - m_ThisFrameStartTime; - double millis - = qt3ds::foundation::Time::sCounterFreq.toTensOfNanos(updateDuration) - * (1.0 / 100000); - if (floor(m_FrameTimer.GetElapsedSeconds()) > 0.0f) { - QPair fps = m_FrameTimer.GetFPS(m_FrameCount); - m_RuntimeFactory->GetQt3DSRenderContext().SetFPS(fps); - if (m_ProfileLogging || !m_HideFPS) { - qCInfo(PERF_INFO, "Render Statistics: %3.2ffps, frame count %d", - fps.first, fps.second); - } - } - - (void)millis; - - /*if ( millis > 30.0 ) - { - m_CoreFactory->GetFoundation().error( NVErrorCode::eDEBUG_INFO, __FILE__, __LINE__, - "Qt3DS Long Frame: %3.2fms", millis ); - //Useful for figuring out where the frame time comes from. - m_CoreFactory->GetPerfTimer().OutputTimerData(); - - } - else*/ - m_CoreFactory->GetPerfTimer().ResetTimerData(); - - fflush(stdout); - m_LastFrameStartTime = m_ThisFrameStartTime; - if (m_LastRenderWasDirty) - ResetDirtyCounter(); - else - m_DirtyCountdown = NVMax(0, m_DirtyCountdown - 1); - } - - // hook this up to -layer-caching. - // otherwise it might be hard to measure performance - bool IsApplicationDirty() override - { - return (m_DirtyCountdown > 0); - } - - double GetMillisecondsSinceLastFrame() override { return m_MillisecondsSinceLastFrame; } - - void MarkApplicationDirty() override { ResetDirtyCounter(); } - - Q3DStudio::IAudioPlayer &GetAudioPlayer() override { return m_AudioPlayer; } - //////////////////////////////////////////////////////////////////////////////// - // Generalized save/load - //////////////////////////////////////////////////////////////////////////////// - - bool LoadUIP(SPresentationAsset &inAsset, - NVConstDataRef inExternalReferences) - { - GetMetaData(); - eastl::string theFile; - CFileTools::CombineBaseAndRelative(GetProjectDirectory().c_str(), inAsset.m_Src.c_str(), - theFile); - // Check if the file event exists - eastl::string fullPath; - NVScopedRefCounted theStream - = m_CoreFactory->GetRenderContextCore().GetInputStreamFactory().GetStreamForFile( - theFile.c_str()); - if (theStream) { - theStream = NULL; - CPresentation *thePresentation - = Q3DStudio_new(CPresentation) CPresentation(inAsset.m_Id.c_str(), this); - inAsset.m_Presentation = thePresentation; - thePresentation->SetFilePath(theFile.c_str()); - NVScopedReleasable theUIPParser(IUIPParser::Create( - theFile.c_str(), *m_MetaData, - m_CoreFactory->GetInputStreamFactory(), - m_CoreFactory->GetStringTable())); - Q3DStudio::IScene *newScene = NULL; - ISceneGraphRuntimeDebugger &theDebugger = GetSceneGraphDebugger(); - m_PresentationBuffer.clear(); - // Map presentation id has to be called before load so that when we send the element - // id updates the system can also send the presentationid->id mapping. - theDebugger.MapPresentationId(thePresentation, inAsset.m_Id.c_str()); - if (theUIPParser->Load(*thePresentation, inExternalReferences, - GetSceneGraphDebugger())) { - // Load the scene graph portion of the scene. - newScene = m_RuntimeFactory->GetSceneManager().LoadScene( - thePresentation, theUIPParser.mPtr, - m_CoreFactory->GetScriptEngineQml(), - m_variantConfig); - } - - if (newScene == NULL) { - Q3DStudio_delete(thePresentation, CPresentation); - qCWarning(qt3ds::INVALID_OPERATION) - << "Unable to load presentation " << theFile.c_str(); - inAsset.m_Presentation = NULL; - return false; - } else { - if (inAsset.m_Id.IsValid() && m_InitialPresentationId.empty()) - m_InitialPresentationId.assign(inAsset.m_Id); - - if (inAsset.m_Id.IsValid()) - newScene->RegisterOffscreenRenderer(inAsset.m_Id); - return true; - } - } - qCWarning(qt3ds::INVALID_OPERATION) << "Unable to load presentation " << theFile.c_str(); - return false; - } - - bool LoadUIA(IDOMReader &inReader, NVFoundationBase &fnd) - { - NVConstDataRef theStateReferences; - { - IDOMReader::Scope __preparseScope(inReader); - theStateReferences = m_CoreFactory->GetVisualStateContext().PreParseDocument(inReader); - } - { - m_UIAFileSettings.Parse(inReader); - } - { - IDOMReader::Scope __assetsScope(inReader); - if (!inReader.MoveToFirstChild("assets")) { - qCCritical(INVALID_OPERATION, - "UIA input xml doesn't contain tag; load failed"); - return false; - } - - eastl::string pathString; - - const char8_t *initialItem = ""; - inReader.UnregisteredAtt("initial", initialItem); - m_InitialPresentationId.clear(); - if (!isTrivial(initialItem)) { - if (initialItem[0] == '#') - ++initialItem; - - m_InitialPresentationId.assign(initialItem); - } - eastl::vector theUIPReferences; - eastl::string tempString; - - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - IDOMReader::Scope __assetScope(inReader); - const char8_t *itemId(""); - inReader.UnregisteredAtt("id", itemId); - const char8_t *src = ""; - inReader.UnregisteredAtt("src", src); - pathString.clear(); - if (!isTrivial(src)) - CFileTools::CombineBaseAndRelative(m_ProjectDir.c_str(), src, pathString); - - const char8_t *assetName = inReader.GetElementName(); - if (AreEqual(assetName, "presentation")) { - SPresentationAsset theAsset(RegisterStr(itemId), RegisterStr(src)); - bool activeFlag; - if (inReader.Att("active", activeFlag)) - theAsset.m_Active = activeFlag; - RegisterAsset(theAsset); - } else if (AreEqual(assetName, "dataInput")) { - DataInputDef diDef; - const char8_t *name = ""; - const char8_t *type = ""; - const char8_t *evaluator = ""; - diDef.value = QVariant::Invalid; - inReader.UnregisteredAtt("name", name); - inReader.UnregisteredAtt("type", type); - inReader.Att("min", diDef.min); - inReader.Att("max", diDef.max); - inReader.UnregisteredAtt("evaluator", evaluator); - if (AreEqual(type, "Ranged Number")) - diDef.type = DataInputTypeRangedNumber; - else if (AreEqual(type, "String")) - diDef.type = DataInputTypeString; - else if (AreEqual(type, "Float")) - diDef.type = DataInputTypeFloat; - else if (AreEqual(type, "Vector3")) - diDef.type = DataInputTypeVector3; - else if (AreEqual(type, "Vector2")) - diDef.type = DataInputTypeVector2; - else if (AreEqual(type, "Boolean")) - diDef.type = DataInputTypeBoolean; - else if (AreEqual(type, "Variant")) - diDef.type = DataInputTypeVariant; - - if (AreEqual(type, "Evaluator")) { - diDef.type = DataInputTypeEvaluator; - diDef.evaluator = QString::fromUtf8(evaluator); - } - - m_dataInputs.insert(QString::fromUtf8(name), diDef); - } else if (AreEqual(assetName, "renderplugin")) { - const char8_t *pluginArgs = ""; - inReader.UnregisteredAtt("args", pluginArgs); - RegisterAsset(SRenderPluginAsset(RegisterStr(itemId), RegisterStr(src), - RegisterStr(pluginArgs))); - } else if (AreEqual(assetName, "statemachine")) { - const char8_t *dm = ""; - inReader.UnregisteredAtt("datamodel", dm); - m_CoreFactory->GetVisualStateContext().LoadStateMachine(itemId, src, - nonNull(dm)); - RegisterAsset( - SSCXMLAsset(RegisterStr(itemId), RegisterStr(src), RegisterStr(dm))); - - } else if (AreEqual(assetName, "behavior")) { - SBehaviorAsset theAsset(RegisterStr(itemId), RegisterStr(src), 0); - RegisterAsset(theAsset); - } else if (AreEqual(assetName, "presentation-qml")) { - const char8_t *args = ""; - inReader.UnregisteredAtt("args", args); - RegisterAsset(SQmlPresentationAsset(RegisterStr(itemId), RegisterStr(src), - RegisterStr(args))); - } else { - qCWarning(WARNING, "Unrecognized child %s", assetName); - } - } - } // end assets scope - const char8_t *initialScaleMode = ""; - inReader.UnregisteredAtt("scalemode", initialScaleMode); - - { - IDOMReader::Scope __machineScope(inReader); - m_CoreFactory->GetVisualStateContext().LoadVisualStateMapping(inReader); - } - m_AppLoadContext - = IAppLoadContext::CreateXMLLoadContext(*this, theStateReferences, - initialScaleMode); - return true; - } - - DataInputMap &dataInputMap() override - { - return m_dataInputs; - } - - struct SAppXMLErrorHandler : public qt3ds::foundation::CXmlErrorHandler - { - NVFoundationBase &m_Foundation; - const char8_t *m_FilePath; - SAppXMLErrorHandler(NVFoundationBase &fnd, const char8_t *filePath) - : m_Foundation(fnd) - , m_FilePath(filePath) - { - } - - void OnXmlError(TXMLCharPtr errorName, int line, int /*column*/) override - { - qCWarning(INVALID_OPERATION, m_FilePath, line, "%s", errorName); - } - }; - - void ConnectDebugger() - { - NVFoundationBase &fnd(m_CoreFactory->GetFoundation()); - Q3DStudio::IScriptBridge &theBridge = m_CoreFactory->GetScriptEngineQml(); - if (m_DebugSettings.hasValue()) { - m_SocketSystem = SocketSystem::createSocketSystem(fnd); - if (m_DebugSettings->m_Listen) { - // Wait for connection request from debug server - qCInfo(TRACE_INFO, "Listening for debug connection on port %d", - m_DebugSettings->m_Port); - NVScopedRefCounted theServer - = m_SocketSystem->createServer(m_DebugSettings->m_Port); - theServer->setTimeout(1000); - m_ServerStream = theServer->nextClient(); - } else { - // Attempt to connect to the debug server - qCInfo(TRACE_INFO, "Attempt to connect to debug server %s:%d", - m_DebugSettings->m_Server.c_str(), m_DebugSettings->m_Port); - m_ServerStream = m_SocketSystem->createStream(m_DebugSettings->m_Server.c_str(), - m_DebugSettings->m_Port, 1000); - } - if (m_ServerStream) { - m_ServerStream->setTimeout(QT3DS_MAX_U32); - // This system declares protocols, we don't listen for new ones. - m_ProtocolSocket = qt3ds::state::debugger::IMultiProtocolSocket::CreateProtocolSocket( - fnd, *m_ServerStream, m_CoreFactory->GetStringTable(), NULL); - if (!m_ProtocolSocket->Initialize()) { - m_ProtocolSocket = NULL; - m_ServerStream = NULL; - m_SocketSystem = NULL; - qCWarning(WARNING, - "Initialization failed after connection to server, debug server %s:%d", - m_DebugSettings->m_Server.c_str(), m_DebugSettings->m_Port); - - } else { - using namespace qt3ds::state::debugger; - theBridge.EnableDebugging(*m_ProtocolSocket); - NVScopedRefCounted socketStream - = m_ProtocolSocket->CreateProtocol( - CProtocolNames::getSCXMLProtocolName(), NULL); - GetStateDebugger().OnServerConnected(*socketStream); - - NVScopedRefCounted theSGStream - = m_ProtocolSocket->CreateProtocol( - ISceneGraphRuntimeDebugger::GetProtocolName(), NULL); - GetSceneGraphDebugger().OnConnection(*theSGStream); - theSGStream->SetListener(&GetSceneGraphDebugger()); - } - } else { - qCWarning(WARNING, "Failed to connect to debug server %s:%d", - m_DebugSettings->m_Server.c_str(), m_DebugSettings->m_Port); - } - } - } - - virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override - { - SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), "Application: Begin Load"); - eastl::string directory; - eastl::string filename; - eastl::string extension; - CFileTools::Split(sourcePath.toUtf8().constData(), directory, filename, extension); - eastl::string projectDirectory(directory); - - m_ProjectDir.assign(projectDirectory.c_str()); - m_CoreFactory->AddSearchPath(projectDirectory.c_str()); - - // add additional search path - QString projectDir = CFileTools::NormalizePathForQtUsage(projectDirectory.c_str()); - if (!projectDir.startsWith(QStringLiteral(":"))) { - eastl::string relativeProjectDir; - CFileTools::CombineBaseAndRelative(m_ApplicationDir.c_str(), projectDirectory.c_str(), - relativeProjectDir); - m_CoreFactory->AddSearchPath(relativeProjectDir.c_str()); - } - - NVFoundationBase &fnd(m_CoreFactory->GetFoundation()); - - if (m_CoreFactory->GetRenderContextCore().GetTextRendererCore()) { - m_CoreFactory->GetRenderContextCore().GetTextRendererCore()->AddProjectFontDirectory( - projectDirectory.c_str()); - m_CoreFactory->GetRenderContextCore().GetTextRendererCore()->BeginPreloadFonts( - m_CoreFactory->GetRenderContextCore().GetThreadPool(), - m_CoreFactory->GetRenderContextCore().GetPerfTimer()); - } - m_Filename = filename; - m_variantConfig.setVariantList(variantList); - bool retval = false; - if (extension.comparei("uip") == 0) { -#if !defined(_LINUXPLATFORM) && !defined(_INTEGRITYPLATFORM) - ConnectDebugger(); -#endif - m_InitialPresentationId.assign(filename.c_str()); - eastl::string relativePath = "./"; - relativePath.append(filename); - relativePath.append("."); - relativePath.append("uip"); - RegisterAsset(SPresentationAsset(RegisterStr(filename.c_str()), - RegisterStr(relativePath.c_str()))); - m_AppLoadContext = IAppLoadContext::CreateXMLLoadContext( - *this, NVDataRef(), ""); - - retval = true; - } else if (extension.comparei("uia") == 0) { -#if !defined(_LINUXPLATFORM) && !defined(_INTEGRITYPLATFORM) - ConnectDebugger(); -#endif - CFileSeekableIOStream inputStream(sourcePath, FileReadFlags()); - if (inputStream.IsOpen()) { - NVScopedRefCounted strTable( - IStringTable::CreateStringTable(fnd.getAllocator())); - NVScopedRefCounted domFactory( - IDOMFactory::CreateDOMFactory(fnd.getAllocator(), strTable)); - SAppXMLErrorHandler errorHandler(fnd, sourcePath.toUtf8().constData()); - eastl::pair readResult = - CDOMSerializer::Read(*domFactory, inputStream, &errorHandler); - if (!readResult.second) { - qCCritical(INVALID_PARAMETER, "%s doesn't appear to be valid xml", - sourcePath.toUtf8().constData()); - } else { - NVScopedRefCounted domReader = IDOMReader::CreateDOMReader( - fnd.getAllocator(), *readResult.second, strTable, domFactory); - if (m_visitor) - m_visitor->visit(sourcePath.toUtf8().constData()); - retval = LoadUIA(*domReader, fnd); - } - } else { - qCCritical(INVALID_PARAMETER, "Unable to open input file %s", - sourcePath.toUtf8().constData()); - } - } else { - QT3DS_ASSERT(false); - } - return retval; - } - - void EndLoad() override - { - if (m_AppLoadContext) - m_AppLoadContext->EndLoad(); - } - - void RunAllRunnables() - { - { - Mutex::ScopedLock __locker(m_RunnableMutex); - m_MainThreadRunnables = m_ThreadRunnables; - m_ThreadRunnables.clear(); - } - for (QT3DSU32 idx = 0, end = m_MainThreadRunnables.size(); idx < end; ++idx) - m_MainThreadRunnables[idx]->Run(); - m_MainThreadRunnables.clear(); - } - - bool HasCompletedLoading() override - { - RunAllRunnables(); - if (m_AppLoadContext) - return m_AppLoadContext->HasCompletedLoading(); - - return true; - } - - bool createSuccessful() override - { - return m_createSuccessful; - } - - // will force loading to end if endLoad hasn't been called yet. Will fire off loading - // of resources that need to be uploaded to opengl. Maintains reference to runtime factory - IApplication &CreateApplication(Q3DStudio::CInputEngine &inInputEngine, - Q3DStudio::IAudioPlayer *inAudioPlayer, - Q3DStudio::IRuntimeFactory &inFactory) override - { - { - SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), - "Application: Initialize Graphics"); - - { - SStackPerfTimer __timer(m_CoreFactory->GetPerfTimer(), "Application: EndLoad"); - EndLoad(); - } - m_InputEnginePtr = &inInputEngine; - m_RuntimeFactory = inFactory; - - { - SStackPerfTimer __timer(m_CoreFactory->GetPerfTimer(), - "Application: Load Context Graphics Initialized"); - if (m_AppLoadContext) - m_createSuccessful = m_AppLoadContext->OnGraphicsInitialized(inFactory); - // Guarantees the end of the multithreaded access to the various components - m_AppLoadContext = NULL; - if (!m_createSuccessful) - return *this; - } - - { - SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), - "Application: End Font Preload"); - if (m_CoreFactory->GetRenderContextCore().GetTextRendererCore()) - m_CoreFactory->GetRenderContextCore() - .GetTextRendererCore() - ->EndPreloadFonts(); - } - - RunAllRunnables(); - // Moving set application to the end ensures that the application load context is not - // accessing - // the lua state in another thread while we are calling set application. This - // apparently may cause - // the call to set application to fail miserably. - m_RuntimeFactory->SetApplication(this); - m_RuntimeFactory->GetStringTable().DisableMultithreadedAccess(); - - for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { - if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { - SPresentationAsset &theAsset( - *m_OrderedAssets[idx].second->getDataPtr()); - CPresentation *thePresentation = theAsset.m_Presentation; - if (thePresentation) { - SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), - "Application: SetActivityZone"); - thePresentation->SetActivityZone( - &m_ActivityZoneManager->CreateActivityZone(*thePresentation)); - thePresentation->SetActive(theAsset.m_Active); - } - } - } - - inInputEngine.SetApplication(this); - } - SApplicationSettings finalSettings(/*m_CommandLineSettings, */m_UIAFileSettings); - if (finalSettings.m_LayerCacheEnabled.hasValue()) { - inFactory.GetQt3DSRenderContext().GetRenderer().EnableLayerCaching( - *finalSettings.m_LayerCacheEnabled); - } - if (finalSettings.m_LayerGpuProfilingEnabled.hasValue()) { - inFactory.GetQt3DSRenderContext().GetRenderer().EnableLayerGpuProfiling( - *finalSettings.m_LayerGpuProfilingEnabled); - } - - m_CoreFactory->GetPerfTimer().OutputTimerData(); - - m_AudioPlayer.SetPlayer(inAudioPlayer); - - return *this; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // Getters/Setters - ////////////////////////////////////////////////////////////////////////////////////////////////////// - CRegisteredString RegisterStr(const char8_t *inStr) - { - return m_CoreFactory->GetStringTable().RegisterStr(inStr); - } - - // The directory that contains the executable and the root resource path - CRegisteredString GetApplicationDirectory() const override - { - return const_cast(*this).m_CoreFactory->GetStringTable().RegisterStr( - m_ApplicationDir.c_str()); - } - // Directory that contained the XIF file. - CRegisteredString GetProjectDirectory() const override - { - QT3DS_ASSERT(m_ProjectDir.size()); - return const_cast(*this).m_CoreFactory->GetStringTable().RegisterStr( - m_ProjectDir.c_str()); - } - - CRegisteredString GetDllDir() const override - { - if (m_DLLDirectory.size()) { - return const_cast(*this).m_CoreFactory->GetStringTable().RegisterStr( - m_DLLDirectory.c_str()); - } - return CRegisteredString(); - } - - void SetDllDir(const char *inDllDir) override - { - m_DLLDirectory.assign(nonNull(inDllDir)); - m_CoreFactory->SetDllDir(inDllDir); - } - - Q3DStudio::IRuntimeFactory &GetRuntimeFactory() const override { return *m_RuntimeFactory.mPtr; } - Q3DStudio::IRuntimeFactoryCore &GetRuntimeFactoryCore() override { return *m_CoreFactory; } - - Q3DStudio::CPresentation *GetPrimaryPresentation() override - { - return GetPresentationById(m_InitialPresentationId.c_str()); - } - - Q3DStudio::CPresentation *GetPresentationById(const char8_t *inId) override - { - if (!isTrivial(inId)) { - TIdAssetMap::iterator iter - = m_AssetMap.find(m_CoreFactory->GetStringTable().RegisterStr(inId)); - if (iter != m_AssetMap.end() - && iter->second->getType() == AssetValueTypes::Presentation) { - return iter->second->getData().m_Presentation; - } - } - return NULL; - } - - // Returns a list of all presentations in the application - // The primary presentation is returned at index 0 - QList GetPresentationList() override - { - QList list; - for (TIdAssetMap::iterator iter = m_AssetMap.begin(); iter != m_AssetMap.end(); ++iter) { - if (iter->second->getType() == AssetValueTypes::Presentation) { - Q3DStudio::CPresentation *presentation - = iter->second->getData().m_Presentation; - if (presentation) { - if (iter->first == m_InitialPresentationId) - list.prepend(presentation); - else - list.append(presentation); - } - } - } - return list; - } - - template - void RegisterAsset(const TAssetType &inAsset) - { - NVScopedRefCounted theValue( - QT3DS_NEW(m_CoreFactory->GetFoundation().getAllocator(), - SRefCountedAssetValue(m_CoreFactory->GetFoundation(), inAsset))); - if (inAsset.m_Id.IsValid()) - m_AssetMap.insert(eastl::make_pair(inAsset.m_Id, theValue)); - - m_OrderedAssets.push_back(eastl::make_pair(inAsset.m_Id, theValue)); - - if (m_visitor) { - m_visitor->visit(inAsset.Type(), inAsset.m_Id.c_str(), inAsset.m_Src.c_str(), - inAsset.m_Args.c_str()); - } - } - - THashValue HashString(const char *inStr) override - { - if (inStr == NULL) - inStr = ""; - THashValue retval = CHash::HashString(inStr); - eastl::pair insertResult - = m_HashStrMap.insert(eastl::make_pair(retval, CRegisteredString())); - if (insertResult.second) - insertResult.first->second = m_CoreFactory->GetStringTable().RegisterStr(inStr); - return retval; - } - - const char *ReverseHash(THashValue theValue) override - { - THashStrMap::iterator find = m_HashStrMap.find(theValue); - if (find != m_HashStrMap.end()) - return find->second.c_str(); - return ""; - } - - void SetFrameCount(Q3DStudio::INT32 inFrameCount) override { m_FrameCount = inFrameCount; } - - Q3DStudio::INT32 GetFrameCount() override { return m_FrameCount; } - - void SetTimeMilliSecs(Q3DStudio::INT64 inMilliSecs) override { m_ManualTime = inMilliSecs; } - - Q3DStudio::INT64 GetTimeMilliSecs() override - { - return m_ManualTime == 0 ? m_Timer.GetTimeMilliSecs() : m_ManualTime; - } - - void ResetTime() override - { - m_Timer.Reset(); - m_ManualTime = 0; - } - - void HideFPS(bool flag) override { m_HideFPS = flag; } - - Q3DStudio::CInputEngine &GetInputEngine() override - { - QT3DS_ASSERT(m_InputEnginePtr); - return *m_InputEnginePtr; - } - - Q3DStudio::IRuntimeMetaData &GetMetaData() override - { - if (!m_MetaData) { - m_MetaData = &IRuntimeMetaData::Create(m_CoreFactory->GetInputStreamFactory()); - if (!m_MetaData) { - qCCritical(qt3ds::INVALID_OPERATION) - << "IRuntimeMetaData::Create: Failed to create meta data"; - } - } - return *m_MetaData; - } - - qt3ds::state::debugger::IDebugger &GetStateDebugger() override - { - if (!m_StateDebugger) - m_StateDebugger = qt3ds::state::debugger::IDebugger::CreateDebugger(); - return *m_StateDebugger; - } - - qt3ds::state::debugger::ISceneGraphRuntimeDebugger &GetSceneGraphDebugger() override - { - if (!m_SceneGraphDebugger) - m_SceneGraphDebugger = qt3ds::state::debugger::ISceneGraphRuntimeDebugger::Create( - m_CoreFactory->GetFoundation(), m_CoreFactory->GetStringTable()); - return *m_SceneGraphDebugger; - } - - IActivityZoneManager &GetActivityZoneManager() override { return *m_ActivityZoneManager; } - - IElementAllocator &GetElementAllocator() override { return *m_ElementAllocator; } - - Q3DStudio::UINT32 GetHandleForElement(Q3DStudio::TElement *inElement) override - { - return inElement->GetHandle(); - } - - Q3DStudio::TElement *GetElementByHandle(Q3DStudio::UINT32 inHandle) override - { - return GetElementAllocator().FindElementByHandle(inHandle); - } -}; - -struct SXMLLoader : public IAppLoadContext -{ - SApp &m_App; - eastl::string m_ScaleMode; - eastl::vector m_References; - QT3DSI32 mRefCount; - - SXMLLoader(SApp &inApp, const char8_t *sc, NVConstDataRef refs) - : m_App(inApp) - , m_ScaleMode(nonNull(sc)) - , mRefCount(0) - { - m_References.assign(refs.begin(), refs.end()); - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_App.m_CoreFactory->GetFoundation().getAllocator()) - - void EndLoad() override {} - - bool HasCompletedLoading() override { return true; } - - bool OnGraphicsInitialized(IRuntimeFactory &inFactory) override - { - eastl::vector theUIPReferences; - eastl::string tempString; - for (QT3DSU32 idx = 0, end = m_App.m_OrderedAssets.size(); idx < end; ++idx) { - SAssetValue &theAsset = *m_App.m_OrderedAssets[idx].second; - eastl::string thePathStr; - - CFileTools::CombineBaseAndRelative(m_App.GetProjectDirectory().c_str(), - theAsset.GetSource(), thePathStr); - switch (theAsset.getType()) { - case AssetValueTypes::Presentation: { - QDir::addSearchPath(QStringLiteral("qt3dstudio"), - QFileInfo(QString(thePathStr.c_str())) - .absoluteDir().absolutePath()); - SPresentationAsset &thePresentationAsset - = *theAsset.getDataPtr(); - theUIPReferences.clear(); - for (QT3DSU32 refIdx = 0, refEnd = m_References.size(); refIdx < refEnd; ++refIdx) { - tempString.assign(m_References[refIdx].m_ElementPath.c_str()); - eastl::string::size_type colonPos = tempString.find_first_of(':'); - if (colonPos != eastl::string::npos) { - tempString = tempString.substr(0, colonPos); - if (tempString.compare(thePresentationAsset.m_Id.c_str()) == 0) { - SElementAttributeReference newReference( - m_References[refIdx].m_ElementPath.c_str() + colonPos + 1, - m_References[refIdx].m_Attribute.c_str()); - theUIPReferences.push_back(newReference); - } - } - } - - if (!m_App.LoadUIP(thePresentationAsset, - toConstDataRef(theUIPReferences.data(), - (QT3DSU32)theUIPReferences.size()))) { - qCCritical(INVALID_OPERATION, "Unable to load presentation %s", - thePathStr.c_str()); - } - } break; - case AssetValueTypes::Behavior: { - SBehaviorAsset &theBehaviorAsset = *theAsset.getDataPtr(); - Q3DStudio::INT32 scriptId - = m_App.m_CoreFactory->GetScriptEngineQml().InitializeApplicationBehavior( - theBehaviorAsset.m_Src); - if (scriptId == 0) { - qCCritical(INVALID_OPERATION, "Unable to load application behavior %s", - theBehaviorAsset.m_Src.c_str()); - } else { - theBehaviorAsset.m_Handle = scriptId; - m_App.m_Behaviors.push_back(eastl::make_pair(theBehaviorAsset, false)); - } - } break; - case AssetValueTypes::RenderPlugin: { - SRenderPluginAsset &thePluginAsset = *theAsset.getDataPtr(); - - inFactory.GetSceneManager().LoadRenderPlugin( - thePluginAsset.m_Id, thePathStr.c_str(), thePluginAsset.m_Args); - } break; - - case AssetValueTypes::QmlPresentation: { - SQmlPresentationAsset &asset = *theAsset.getDataPtr(); - inFactory.GetSceneManager().LoadQmlStreamerPlugin(asset.m_Id); - } break; - // SCXML, NoAssetValue do not need processing here - default: - break; - } - } - if (m_ScaleMode.empty() == false) { - const char8_t *initialScaleMode(m_ScaleMode.c_str()); - // Force loading to finish here, just like used to happen. - if (AreEqual(initialScaleMode, "center")) { - inFactory.GetQt3DSRenderContext().SetScaleMode(qt3ds::render::ScaleModes::ExactSize); - } else if (AreEqual(initialScaleMode, "fit")) { - inFactory.GetQt3DSRenderContext().SetScaleMode(qt3ds::render::ScaleModes::ScaleToFit); - } else if (AreEqual(initialScaleMode, "fill")) { - inFactory.GetQt3DSRenderContext().SetScaleMode(qt3ds::render::ScaleModes::ScaleToFill); - } else { - qCCritical(INVALID_PARAMETER, "Unrecognized scale mode attribute value: ", - initialScaleMode); - } - } - return true; - } - - virtual void OnFirstRender() {} -}; - -IAppLoadContext &IAppLoadContext::CreateXMLLoadContext( - SApp &inApp, NVConstDataRef inStateReferences, - const char8_t *inScaleMode) -{ - return *QT3DS_NEW(inApp.m_CoreFactory->GetFoundation().getAllocator(), - SXMLLoader)(inApp, inScaleMode, inStateReferences); -} -} - -CAppStr::CAppStr(NVAllocatorCallback &alloc, const char8_t *inStr) - : TBase(inStr, ForwardingAllocator(alloc, "CAppStr")) -{ -} - -CAppStr::CAppStr(const CAppStr &inOther) - : TBase(inOther) -{ -} - -CAppStr::CAppStr() - : TBase() -{ -} - -CAppStr &CAppStr::operator=(const CAppStr &inOther) -{ - TBase::operator=(inOther); - return *this; -} - -IApplicationCore &IApplicationCore::CreateApplicationCore(Q3DStudio::IRuntimeFactoryCore &inFactory, - const char8_t *inApplicationDirectory) -{ - return *QT3DS_NEW(inFactory.GetFoundation().getAllocator(), SApp)(inFactory, - inApplicationDirectory); -} - -// Checks if the event is one that can cause picking -bool IApplicationCore::isPickingEvent(TEventCommandHash event) -{ - return (event == ON_MOUSEDOWN - || event == ON_MOUSEUP - || event == ON_MIDDLEMOUSEDOWN - || event == ON_MIDDLEMOUSEUP - || event == ON_RIGHTMOUSEDOWN - || event == ON_RIGHTMOUSEUP - || event == ON_MOUSECLICK - || event == ON_MIDDLEMOUSECLICK - || event == ON_RIGHTMOUSECLICK - || event == ON_MOUSEOVER - || event == ON_MOUSEOUT - || event == ON_GROUPEDMOUSEOVER - || event == ON_GROUPEDMOUSEOUT); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSAttributeHashes.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSAttributeHashes.cpp deleted file mode 100644 index 1409901f..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSAttributeHashes.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSAttributeHashes.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -// !!!!! AUTOGENERATED CODE - DO NOT MODIFY MANUALLY !!!!! - -// Run the AttributeHashes project to regenerate this file from Attributehashes.txt list - - - -/// Function providing reverse hash lookup -const char *GetAttributeString(const EAttribute inAttribute) -{ - switch (inAttribute) { - case ATTRIBUTE_NAME: return "name"; - case ATTRIBUTE_TYPE: return "type"; - case ATTRIBUTE_OPACITY: return "opacity"; - case ATTRIBUTE_STARTTIME: return "starttime"; - case ATTRIBUTE_ENDTIME: return "endtime"; - case ATTRIBUTE_SOURCEPATH: return "sourcepath"; - case ATTRIBUTE_IMPORTID: return "importid"; - case ATTRIBUTE_EYEBALL: return "eyeball"; - case ATTRIBUTE_POSITION: return "position"; - case ATTRIBUTE_POSITION_X: return "position.x"; - case ATTRIBUTE_POSITION_Y: return "position.y"; - case ATTRIBUTE_POSITION_Z: return "position.z"; - case ATTRIBUTE_ROTATION: return "rotation"; - case ATTRIBUTE_ROTATION_X: return "rotation.x"; - case ATTRIBUTE_ROTATION_Y: return "rotation.y"; - case ATTRIBUTE_ROTATION_Z: return "rotation.z"; - case ATTRIBUTE_SCALE: return "scale"; - case ATTRIBUTE_SCALE_X: return "scale.x"; - case ATTRIBUTE_SCALE_Y: return "scale.y"; - case ATTRIBUTE_SCALE_Z: return "scale.z"; - case ATTRIBUTE_PIVOT: return "pivot"; - case ATTRIBUTE_PIVOT_X: return "pivot.x"; - case ATTRIBUTE_PIVOT_Y: return "pivot.y"; - case ATTRIBUTE_PIVOT_Z: return "pivot.z"; - case ATTRIBUTE_ROTATIONORDER: return "rotationorder"; - case ATTRIBUTE_ORIENTATION: return "orientation"; - case ATTRIBUTE_SHADOWCASTER: return "shadowcaster"; - case ATTRIBUTE_TESSELLATION: return "tessellation"; - case ATTRIBUTE_EDGETESS: return "edgetess"; - case ATTRIBUTE_INNERTESS: return "innertess"; - case ATTRIBUTE_ORTHOGRAPHIC: return "orthographic"; - case ATTRIBUTE_CLIPNEAR: return "clipnear"; - case ATTRIBUTE_CLIPFAR: return "clipfar"; - case ATTRIBUTE_FOV: return "fov"; - case ATTRIBUTE_FOVHORIZONTAL: return "fovhorizontal"; - case ATTRIBUTE_SCALEMODE: return "scalemode"; - case ATTRIBUTE_SCALEANCHOR: return "scaleanchor"; - case ATTRIBUTE_BRIGHTNESS: return "brightness"; - case ATTRIBUTE_LINEARFADE: return "linearfade"; - case ATTRIBUTE_EXPFADE: return "expfade"; - case ATTRIBUTE_LIGHTTYPE: return "lighttype"; - case ATTRIBUTE_SCOPE: return "scope"; - case ATTRIBUTE_LIGHTDIFFUSE: return "lightdiffuse"; - case ATTRIBUTE_LIGHTDIFFUSE_R: return "lightdiffuse.r"; - case ATTRIBUTE_LIGHTDIFFUSE_G: return "lightdiffuse.g"; - case ATTRIBUTE_LIGHTDIFFUSE_B: return "lightdiffuse.b"; - case ATTRIBUTE_LIGHTAMBIENT_R: return "lightambient.r"; - case ATTRIBUTE_LIGHTAMBIENT: return "lightambient"; - case ATTRIBUTE_LIGHTAMBIENT_G: return "lightambient.g"; - case ATTRIBUTE_LIGHTAMBIENT_B: return "lightambient.b"; - case ATTRIBUTE_LIGHTSPECULAR: return "lightspecular"; - case ATTRIBUTE_LIGHTSPECULAR_R: return "lightspecular.r"; - case ATTRIBUTE_LIGHTSPECULAR_G: return "lightspecular.g"; - case ATTRIBUTE_LIGHTSPECULAR_B: return "lightspecular.b"; - case ATTRIBUTE_AREAWIDTH: return "areawidth"; - case ATTRIBUTE_AREAHEIGHT: return "areaheight"; - case ATTRIBUTE_CASTSHADOW: return "castshadow"; - case ATTRIBUTE_SHDWBIAS: return "shdwbias"; - case ATTRIBUTE_SHDWFACTOR: return "shdwfactor"; - case ATTRIBUTE_SHDWMAPRES: return "shdwmapres"; - case ATTRIBUTE_SHDWMAPFAR: return "shdwmapfar"; - case ATTRIBUTE_SHDWMAPFOV: return "shdwmapfov"; - case ATTRIBUTE_SHDWFILTER: return "shdwfilter"; - case ATTRIBUTE_LIGHTMAPINDIRECT: return "lightmapindirect"; - case ATTRIBUTE_LIGHTMAPRADIOSITY: return "lightmapradiosity"; - case ATTRIBUTE_LIGHTMAPSHADOW: return "lightmapshadow"; - case ATTRIBUTE_IBLPROBE: return "iblprobe"; - case ATTRIBUTE_SHADERLIGHTING: return "shaderlighting"; - case ATTRIBUTE_EMISSIVEPOWER: return "emissivepower"; - case ATTRIBUTE_EMISSIVECOLOR: return "emissivecolor"; - case ATTRIBUTE_EMISSIVECOLOR_R: return "emissivecolor.r"; - case ATTRIBUTE_EMISSIVECOLOR_G: return "emissivecolor.g"; - case ATTRIBUTE_EMISSIVECOLOR_B: return "emissivecolor.b"; - case ATTRIBUTE_DIFFUSE: return "diffuse"; - case ATTRIBUTE_DIFFUSE_R: return "diffuse.r"; - case ATTRIBUTE_DIFFUSE_G: return "diffuse.g"; - case ATTRIBUTE_DIFFUSE_B: return "diffuse.b"; - case ATTRIBUTE_SPECULARMAP: return "specularmap"; - case ATTRIBUTE_SPECULARMODEL: return "specularmodel"; - case ATTRIBUTE_SPECULARTINT: return "speculartint"; - case ATTRIBUTE_SPECULARTINT_R: return "speculartint.r"; - case ATTRIBUTE_SPECULARTINT_G: return "speculartint.g"; - case ATTRIBUTE_SPECULARTINT_B: return "speculartint.b"; - case ATTRIBUTE_IOR: return "ior"; - case ATTRIBUTE_FRESNELPOWER: return "fresnelPower"; - case ATTRIBUTE_SPECULARAMOUNT: return "specularamount"; - case ATTRIBUTE_SPECULARROUGHNESS: return "specularroughness"; - case ATTRIBUTE_ROUGHNESSMAP: return "roughnessmap"; - case ATTRIBUTE_BLENDMODE: return "blendmode"; - case ATTRIBUTE_CULLING: return "culling"; - case ATTRIBUTE_ZBUFFERWRITE: return "zbufferwrite"; - case ATTRIBUTE_DIFFUSEMAP: return "diffusemap"; - case ATTRIBUTE_DIFFUSEMAP2: return "diffusemap2"; - case ATTRIBUTE_DIFFUSEMAP3: return "diffusemap3"; - case ATTRIBUTE_SPECULARREFLECTION: return "specularreflection"; - case ATTRIBUTE_OPACITYMAP: return "opacitymap"; - case ATTRIBUTE_EMISSIVEMAP: return "emissivemap"; - case ATTRIBUTE_EMISSIVEMAP2: return "emissivemap2"; - case ATTRIBUTE_BUMPMAP: return "bumpmap"; - case ATTRIBUTE_BUMPAMOUNT: return "bumpamount"; - case ATTRIBUTE_NORMALMAP: return "normalmap"; - case ATTRIBUTE_DISPLACEMENTMAP: return "displacementmap"; - case ATTRIBUTE_DISPLACEAMOUNT: return "displaceamount"; - case ATTRIBUTE_TRANSLUCENCYMAP: return "translucencymap"; - case ATTRIBUTE_TRANSLUCENTFALLOFF: return "translucentfalloff"; - case ATTRIBUTE_DIFFUSELIGHTWRAP: return "diffuselightwrap"; - case ATTRIBUTE_REFERENCEDMATERIAL: return "referencedmaterial"; - case ATTRIBUTE_VERTEXCOLORS: return "vertexcolors"; - case ATTRIBUTE_ROTATIONUV: return "rotationuv"; - case ATTRIBUTE_POSITIONU: return "positionu"; - case ATTRIBUTE_POSITIONV: return "positionv"; - case ATTRIBUTE_SCALEU: return "scaleu"; - case ATTRIBUTE_SCALEV: return "scalev"; - case ATTRIBUTE_PIVOTU: return "pivotu"; - case ATTRIBUTE_PIVOTV: return "pivotv"; - case ATTRIBUTE_TILINGMODEHORZ: return "tilingmodehorz"; - case ATTRIBUTE_TILINGMODEVERT: return "tilingmodevert"; - case ATTRIBUTE_MAPPINGTYPE: return "mappingtype"; - case ATTRIBUTE_MAPPINGMODE: return "mappingmode"; - case ATTRIBUTE_SUBPRESENTATION: return "subpresentation"; - case ATTRIBUTE_URI: return "uri"; - case ATTRIBUTE_TRANSPARENT: return "transparent"; - case ATTRIBUTE_PROGRESSIVEAA: return "progressiveaa"; - case ATTRIBUTE_MULTISAMPLEAA: return "multisampleaa"; - case ATTRIBUTE_TEMPORALAA: return "temporalaa"; - case ATTRIBUTE_BLENDTYPE: return "blendtype"; - case ATTRIBUTE_HORZFIELDS: return "horzfields"; - case ATTRIBUTE_LEFT: return "left"; - case ATTRIBUTE_LEFTUNITS: return "leftunits"; - case ATTRIBUTE_WIDTH: return "width"; - case ATTRIBUTE_WIDTHUNITS: return "widthunits"; - case ATTRIBUTE_RIGHT: return "right"; - case ATTRIBUTE_RIGHTUNITS: return "rightunits"; - case ATTRIBUTE_VERTFIELDS: return "vertfields"; - case ATTRIBUTE_TOP: return "top"; - case ATTRIBUTE_TOPUNITS: return "topunits"; - case ATTRIBUTE_HEIGHT: return "height"; - case ATTRIBUTE_HEIGHTUNITS: return "heightunits"; - case ATTRIBUTE_BOTTOM: return "bottom"; - case ATTRIBUTE_BOTTOMUNITS: return "bottomunits"; - case ATTRIBUTE_AOSTRENGTH: return "aostrength"; - case ATTRIBUTE_AODISTANCE: return "aodistance"; - case ATTRIBUTE_AOSOFTNESS: return "aosoftness"; - case ATTRIBUTE_AOBIAS: return "aobias"; - case ATTRIBUTE_AOSAMPLERATE: return "aosamplerate"; - case ATTRIBUTE_AODITHER: return "aodither"; - case ATTRIBUTE_SHADOWSTRENGTH: return "shadowstrength"; - case ATTRIBUTE_SHADOWDIST: return "shadowdist"; - case ATTRIBUTE_SHADOWSOFTNESS: return "shadowsoftness"; - case ATTRIBUTE_SHADOWBIAS: return "shadowbias"; - case ATTRIBUTE_LIGHTPROBE: return "lightprobe"; - case ATTRIBUTE_PROBEBRIGHT: return "probebright"; - case ATTRIBUTE_FASTIBL: return "fastibl"; - case ATTRIBUTE_PROBEHORIZON: return "probehorizon"; - case ATTRIBUTE_PROBEFOV: return "probefov"; - case ATTRIBUTE_LIGHTPROBE2: return "lightprobe2"; - case ATTRIBUTE_PROBE2FADE: return "probe2fade"; - case ATTRIBUTE_PROBE2WINDOW: return "probe2window"; - case ATTRIBUTE_PROBE2POS: return "probe2pos"; - case ATTRIBUTE_DISABLEDEPTHTEST: return "disabledepthtest"; - case ATTRIBUTE_DISABLEDEPTHPREPASS: return "disabledepthprepass"; - case ATTRIBUTE_TEXTCOLOR: return "textcolor"; - case ATTRIBUTE_TEXTCOLOR_R: return "textcolor.r"; - case ATTRIBUTE_TEXTCOLOR_G: return "textcolor.g"; - case ATTRIBUTE_TEXTCOLOR_B: return "textcolor.b"; - case ATTRIBUTE_SIZE: return "size"; - case ATTRIBUTE_FONT: return "font"; - case ATTRIBUTE_DROPSHADOW: return "dropshadow"; - case ATTRIBUTE_DROPSHADOWSTRENGTH: return "dropshadowstrength"; - case ATTRIBUTE_DROPSHADOWOFFSET: return "dropshadowoffset"; - case ATTRIBUTE_DROPSHADOWOFFSETX: return "dropshadowoffsetx"; - case ATTRIBUTE_DROPSHADOWOFFSETY: return "dropshadowoffsety"; - case ATTRIBUTE_DROPSHADOWHORZALIGN: return "dropshadowhorzalign"; - case ATTRIBUTE_DROPSHADOWVERTALIGN: return "dropshadowvertalign"; - case ATTRIBUTE_BOUNDINGBOX: return "boundingbox"; - case ATTRIBUTE_BOUNDINGBOX_X: return "boundingbox.x"; - case ATTRIBUTE_BOUNDINGBOX_Y: return "boundingbox.y"; - case ATTRIBUTE_ELIDE: return "elide"; - case ATTRIBUTE_TRACKING: return "tracking"; - case ATTRIBUTE_LEADING: return "leading"; - case ATTRIBUTE_RENDERSTYLE: return "renderstyle"; - case ATTRIBUTE_TEXTSTRING: return "textstring"; - case ATTRIBUTE_BACKCOLOR_R: return "backcolor.r"; - case ATTRIBUTE_BACKCOLOR_G: return "backcolor.g"; - case ATTRIBUTE_BACKCOLOR_B: return "backcolor.b"; - case ATTRIBUTE_TEXTTYPE: return "texttype"; - case ATTRIBUTE_USEBACKCOLOR: return "usebackcolor"; - case ATTRIBUTE_WORDWRAP: return "wordwrap"; - case ATTRIBUTE_HORZSCROLL: return "horzscroll"; - case ATTRIBUTE_HORZALIGN: return "horzalign"; - case ATTRIBUTE_VERTSCROLL: return "vertscroll"; - case ATTRIBUTE_VERTALIGN: return "vertalign"; - case ATTRIBUTE_BOXHEIGHT: return "boxheight"; - case ATTRIBUTE_BOXWIDTH: return "boxwidth"; - case ATTRIBUTE_REMOTESTRINGSOURCE: return "remotestringsource"; - case ATTRIBUTE_CACHEDTEXTSTRING: return "cachedtextstring"; - case ATTRIBUTE_ENABLEACCELERATEDFONT: return "enableacceleratedfont"; - case ATTRIBUTE_BEHAVIORSCRIPTS: return "BehaviorScripts"; - case ATTRIBUTE_UICCUSTOMOBJTYPE: return "UICCustomObjType"; - case ATTRIBUTE_BGCOLORENABLE: return "bgcolorenable"; - case ATTRIBUTE_BACKGROUND: return "background"; - case ATTRIBUTE_BACKGROUNDCOLOR_R: return "backgroundcolor.r"; - case ATTRIBUTE_BACKGROUNDCOLOR_G: return "backgroundcolor.g"; - case ATTRIBUTE_BACKGROUNDCOLOR_B: return "backgroundcolor.b"; - case ATTRIBUTE_PATHTYPE: return "pathtype"; - case ATTRIBUTE_LINEARERROR: return "linearerror"; - case ATTRIBUTE_EDGETESSAMOUNT: return "edgetessamount"; - case ATTRIBUTE_INNERTESSAMOUNT: return "innertessamount"; - case ATTRIBUTE_BEGINCAP: return "begincap"; - case ATTRIBUTE_BEGINCAPOFFSET: return "begincapoffset"; - case ATTRIBUTE_BEGINCAPOPACITY: return "begincapopacity"; - case ATTRIBUTE_BEGINCAPWIDTH: return "begincapwidth"; - case ATTRIBUTE_ENDCAP: return "endcap"; - case ATTRIBUTE_ENDCAPOFFSET: return "endcapoffset"; - case ATTRIBUTE_ENDCAPOPACITY: return "endcapopacity"; - case ATTRIBUTE_ENDCAPWIDTH: return "endcapwidth"; - case ATTRIBUTE_PAINTSTYLE: return "paintstyle"; - case ATTRIBUTE_CLOSED: return "closed"; - case ATTRIBUTE_INCOMINGANGLE: return "incomingangle"; - case ATTRIBUTE_INCOMINGDISTANCE: return "incomingdistance"; - case ATTRIBUTE_OUTGOINGDISTANCE: return "outgoingdistance"; - case ATTRIBUTE_PARTICLETYPE: return "particletype"; - case ATTRIBUTE_MAXPARTICLES: return "maxparticles"; - case ATTRIBUTE_PARTICLESIZE: return "particlesize"; - case ATTRIBUTE_LIFETIME: return "lifetime"; - case ATTRIBUTE_CONTROLLEDPROPERTY: return "controlledproperty"; - case ATTRIBUTE_QT_IO: return "qt.io"; - default: { - static char s_UnknownHash[16]; - sprintf(s_UnknownHash, "(0x%08X)", inAttribute); - return s_UnknownHash; - } - } -} - -} // namespace Q3DStudio - diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSCommandHelper.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSCommandHelper.cpp deleted file mode 100644 index 53c7648a..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSCommandHelper.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -#include "Qt3DSCommandHelper.h" -#include "Qt3DSCommandEventTypes.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSApplication.h" -#include "Qt3DSSlideSystem.h" - -namespace Q3DStudio { - -CCommandHelper::CCommandHelper() -{ -} - -CCommandHelper::~CCommandHelper() -{ -} - -static Option FindSlide(TElement &inElement, const char *slideName) -{ - IPresentation *thePresentation = inElement.GetBelongedPresentation(); - - int theSlideHashName = thePresentation->GetApplication().HashString(slideName); - TComponent *theComponent = thePresentation->GetComponentManager().GetComponent(&inElement); - UINT8 theSlideIndex = - thePresentation->GetSlideSystem().FindSlide(*theComponent, theSlideHashName); - if (theSlideIndex >= theComponent->GetSlideCount()) { - qt3ds::foundation::CRegisteredString elemPath = thePresentation->GetElementPath(inElement); - if (elemPath.IsValid()) { - qCCritical(qt3ds::INVALID_PARAMETER) - << "CCommandHelper: FindSlide: Unable to find slide " - << slideName << " on element " << elemPath.c_str(); - } else { - qCCritical(qt3ds::INVALID_PARAMETER) - << "CCommandHelper: FindSlide: Unable to find slide " << slideName; - } - return Empty(); - } - - return theSlideIndex; -} - -bool CCommandHelper::SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlideIndex, - const SScriptEngineGotoSlideArgs &inArgs) -{ - IPresentation *thePresentation = inElement.GetBelongedPresentation(); - TElement *theTarget = GetComponentParent(&inElement); - SComponentGotoSlideData theSlideData(inSlideIndex); - theSlideData.m_Mode = inArgs.m_Mode; - theSlideData.m_Paused = inArgs.m_Paused; - theSlideData.m_Rate = inArgs.m_Rate; - theSlideData.m_Reverse = inArgs.m_Reverse; - theSlideData.m_StartTime = inArgs.m_StartTime; - // Resolve playthroughto if it has a valid value. - if (!isTrivial(inArgs.m_PlaythroughTo)) { - if (AreEqual(inArgs.m_PlaythroughTo, "next")) - theSlideData.m_PlaythroughTo = -1; - else if (AreEqual(inArgs.m_PlaythroughTo, "previous")) - theSlideData.m_PlaythroughTo = -2; - else { - // Find the slide if possible. If not, then just error leave things as they are. - - Option theSlideIndex = FindSlide(inElement, inArgs.m_PlaythroughTo); - if (theSlideIndex.hasValue()) - theSlideData.m_PlaythroughTo = *theSlideIndex; - } - } - thePresentation->GetComponentManager().SetupComponentGotoSlideCommand(theTarget, theSlideData); - UVariant theArg1; - UVariant theArg2; - qt3ds::intrinsics::memZero(&theArg1, sizeof(UVariant)); - qt3ds::intrinsics::memZero(&theArg2, sizeof(UVariant)); - thePresentation->FireCommand(COMMAND_GOTOSLIDE, theTarget, &theArg1, &theArg2); - return true; -} - -bool CCommandHelper::SetupGotoSlideCommand(TElement &inElement, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs) -{ - Option theSlideIndex = FindSlide(inElement, slideName); - if (theSlideIndex.hasValue()) - return SetupGotoSlideCommand(inElement, *theSlideIndex, inArgs); - return false; -} - -//============================================================================== -/** - * Checks if the given element is a component. If it isn't walks up the tree and looks for one. - * @param inElementManager the object that manages the elements in the presentation - * @param inElement the element to check if it's a component - * @return the component - */ -TElement *CCommandHelper::GetComponentParent(TElement *inElement) -{ - Q3DStudio_ASSERT(inElement); - return &inElement->GetComponentParent(); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSComponentManager.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSComponentManager.cpp deleted file mode 100644 index 2cfb2311..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSComponentManager.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSComponentManager.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSSlideSystem.h" -#include "Qt3DSCommandEventTypes.h" -#include "Qt3DSPresentationFrameData.h" -#include "Qt3DSApplication.h" -#include "Qt3DSActivationManager.h" -#include "Qt3DSPresentation.h" - -using qt3ds::runtime::SSlideKey; -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - * @param inPresentation reference to its presentation - */ -CComponentManager::CComponentManager(IPresentation &inPresentation) - : m_Presentation(static_cast(inPresentation)) -{ -} - -//============================================================================== -/** - * Enforces the contract that slide switching requires a reset to the master - * slide (slide 0) before switching to the desired slide index. - * Also updates the TComponent's current slide number. - * @param inComponent TComponent to set slide on - * @param inSlideIndex relative index of the slide to switch to - * @param inSlideExit true if exiting the slide, false otherwise - */ -void CComponentManager::GotoSlideIndex(TElement *inComponent, - const SComponentGotoSlideData &inGotoData, - BOOL inSlideExit /*= true*/) -{ - TComponent *theComponent = GetComponent(inComponent); - - if (theComponent == NULL) { - return; - } - - if (inGotoData.m_Slide < 1 || inGotoData.m_Slide >= theComponent->GetSlideCount()) { - qCCritical(qt3ds::INVALID_PARAMETER) - << "GotoSlide: Index out of range: Index " << inGotoData.m_Slide - << " SlideCount: "<< theComponent->GetSlideCount(); - return; - } - - if (theComponent->GetActive() == false) { - m_ComponentInitialSlideMap[inComponent] = inGotoData; - return; - } - - SComponentGotoSlideData theGotoSlideData(inGotoData); - - TComponentGotoSlideDataMap::iterator iter = m_ComponentInitialSlideMap.find(inComponent); - if (iter != m_ComponentInitialSlideMap.end()) { - theGotoSlideData = iter->second; - m_ComponentInitialSlideMap.erase(iter); - } - - const UINT8 theCurrentSlideIndex = theComponent->GetCurrentSlide(); - - QString elementPath = QString::fromUtf8(inComponent->m_Path.c_str()); - - if (inSlideExit) { - SEventCommand theEvent = { inComponent, EVENT_ONSLIDEEXIT }; - theEvent.m_IsEvent = true; - m_Presentation.ProcessEvent(theEvent); - - // Signal previous slide change - m_Presentation.signalProxy()->SigSlideExited(elementPath, theCurrentSlideIndex, - GetCurrentSlideName(inComponent)); - - // m_Presentation.FireEvent(EVENT_ONSLIDEEXIT, inComponent); - // m_Presentation.FlushEventCommandQueue(); - } - - // Update dynamic keys to use current values before slide switching, with the exception of - // master slides because playback only starts from non-master slides. - if (theCurrentSlideIndex > 0) { - m_Presentation.GetSlideSystem().InitializeDynamicKeys( - SSlideKey(*theComponent, (qt3ds::QT3DSU8)theGotoSlideData.m_Slide), - m_Presentation.GetAnimationSystem()); - // deactivate actions and animation tracks on the current slide. - m_Presentation.GetSlideSystem().RollbackSlide( - SSlideKey(*inComponent, (qt3ds::QT3DSU8)theCurrentSlideIndex), - m_Presentation.GetAnimationSystem(), m_Presentation.GetLogicSystem()); - } else { - m_Presentation.GetSlideSystem().ExecuteSlide(SSlideKey(*inComponent, 0), - m_Presentation.GetAnimationSystem(), - m_Presentation.GetLogicSystem()); - } - // Execute new slide. - m_Presentation.GetSlideSystem().ExecuteSlide( - SSlideKey(*inComponent, (qt3ds::QT3DSU8)theGotoSlideData.m_Slide), - m_Presentation.GetAnimationSystem(), m_Presentation.GetLogicSystem()); - CTimePolicy &thePolicy(theComponent->GetTimePolicy()); - TTimeUnit theLoopingDuration = thePolicy.GetLoopingDuration(); - if (theGotoSlideData.m_Mode.hasValue()) { - inComponent->SetPlayThrough(false); - switch (*theGotoSlideData.m_Mode) { - case TimePolicyModes::Looping: - thePolicy.Initialize(theLoopingDuration, 0, false); - break; - case TimePolicyModes::PingPong: - thePolicy.Initialize(theLoopingDuration, 0, true); - break; - case TimePolicyModes::StopAtEnd: - thePolicy.Initialize(theLoopingDuration, 1, false); - break; - case TimePolicyModes::Ping: - thePolicy.Initialize(theLoopingDuration, 1, true); - break; - default: - QT3DS_ASSERT(false); - break; - } - } - - // Update the current index which also updates the back index - theComponent->SetCurrentSlide(static_cast(theGotoSlideData.m_Slide)); - m_PlaythroughOverrideMap.erase(inComponent); - if (theGotoSlideData.m_PlaythroughTo.hasValue()) { - m_PlaythroughOverrideMap.insert( - eastl::make_pair(inComponent, *theGotoSlideData.m_PlaythroughTo)); - theComponent->SetPlayThrough(true); - } - - // Reset time for component to 0 - - if (theGotoSlideData.m_Paused.hasValue()) - thePolicy.SetPaused(*theGotoSlideData.m_Paused); - - thePolicy.SetRate(theGotoSlideData.m_Rate); - thePolicy.SetReverse(theGotoSlideData.m_Reverse); - - if (theGotoSlideData.m_StartTime.hasValue()) - thePolicy.SetTime(*theGotoSlideData.m_StartTime); - - inComponent->SetDirty(); - m_Presentation.FireEvent(EVENT_ONSLIDEENTER, inComponent); - qt3ds::runtime::IActivityZone *theZone = m_Presentation.GetActivityZone(); - if (theZone) - theZone->OnSlideChange(*inComponent); - - // Signal current slide change - m_Presentation.signalProxy()->SigSlideEntered(elementPath, GetCurrentSlide(inComponent), - GetCurrentSlideName(inComponent)); -} - -//============================================================================== -/** - * Sets a component to a specified slide using the slide name hash. - * Performs a switch to Slide 0 (master) first, before switching to the - * required slide. - * @param inComponent reference to the TComponent - * @param inSlideHashName hash of the slide to switch to - */ -void CComponentManager::GotoSlideName(TElement *inComponent, const TStringHash inSlideHashName) -{ - TComponent *theComponent = GetComponent(inComponent); - UINT8 theSlideIndex = m_Presentation.GetSlideSystem().FindSlide(*theComponent, inSlideHashName); - - if (theSlideIndex < 1 || theSlideIndex >= theComponent->GetSlideCount()) { - const char *slideName = m_Presentation.GetApplication().ReverseHash(inSlideHashName); - if (slideName && *slideName) - qCCritical(qt3ds::INVALID_PARAMETER) << "GotoSlide: Name not found: " << slideName; - else - qCCritical(qt3ds::INVALID_PARAMETER) << "GotoSlide: Name not found: " << inSlideHashName; - - } else - GotoSlideIndex(inComponent, theSlideIndex); -} - -//============================================================================== -/** - * Return the index of the current slide of the component. - * @param inComponent reference to the TComponent - * @return the index of current slide - */ -UINT8 CComponentManager::GetCurrentSlide(TElement *inComponent) -{ - return GetComponent(inComponent)->GetCurrentSlide(); -} - -//============================================================================== -/** - * Return the number of slides on a component. - * @param inComponent reference to the TComponent - * @return the number of slides - */ -UINT8 CComponentManager::GetSlideCount(TElement *inComponent) -{ - return GetComponent(inComponent)->GetSlideCount(); -} - -//============================================================================== -/** - * Performs a switch to the slide following the current slide (current slide + 1). - * @param inComponent reference to the TComponent - * @param inIncrement slide increment offset - */ -void CComponentManager::GoToNextSlide(TElement *inComponent, const INT32 inIncrement) -{ - TComponent *theComponent = GetComponent(inComponent); - INT32 theNewIndex = Q3DStudio_clamp(inIncrement + theComponent->GetCurrentSlide(), 1L, - theComponent->GetSlideCount() - 1); - - // Trigger goto to slide only if the next slide is not the current - if (theComponent->GetActive()) { - if (theNewIndex != theComponent->GetCurrentSlide()) - GotoSlideIndex(inComponent, theNewIndex); - } else { - qCCritical(qt3ds::INVALID_PARAMETER) - << "Runtime: Attempt to goto slide on an inactive component!"; - } -} - -//============================================================================== -/** - * Performs a switch to the slide following the current slide (current slide - 1). - * @param inComponent reference to the TComponent - * @param inDecrement slide decrement offset - */ -void CComponentManager::GoToPreviousSlide(TElement *inComponent, const INT32 inDecrement) -{ - TComponent *theComponent = GetComponent(inComponent); - INT32 theNewIndex = Q3DStudio_clamp(theComponent->GetCurrentSlide() - inDecrement, 1L, - theComponent->GetSlideCount() - 1); - - // Trigger goto to slide only if the next slide is not the current - if (theNewIndex != theComponent->GetCurrentSlide()) - GotoSlideIndex(inComponent, theNewIndex); -} - -//============================================================================== -/** - * Playthrough to the next slide that is specified. - * @param inComponent reference to the TComponent - */ -void CComponentManager::PlaythroughToSlide(TElement *inComponent) -{ - TComponent *theComponent = GetComponent(inComponent); - TComponentIntMap::iterator iter = m_PlaythroughOverrideMap.find(inComponent); - INT32 thePlaythroughTo = 0; - if (iter != m_PlaythroughOverrideMap.end()) { - thePlaythroughTo = iter->second; - m_PlaythroughOverrideMap.erase(iter); - } else { - thePlaythroughTo = m_Presentation.GetSlideSystem().GetPlaythroughToSlideIndex( - SSlideKey(*theComponent, (qt3ds::QT3DSU8)theComponent->GetCurrentSlide())); - if (thePlaythroughTo == -1) { - qCCritical(qt3ds::INVALID_OPERATION) << "Missing slide to play through to"; - inComponent->SetPlayThrough( - false); // clear this flag, so that this is equivalent to a "Stop At End" - } - } - - if (thePlaythroughTo == -2) { - GoToPreviousSlide(inComponent, 1); - } else if (thePlaythroughTo == -1) { - GoToNextSlide(inComponent, 1); - } else { - GotoSlideIndex(inComponent, thePlaythroughTo); - } -} - -//============================================================================== -/** - * Performs a switch to the previous slide. - * @param inComponent reference to the TComponent - */ -void CComponentManager::GoToBackSlide(TElement *inComponent) -{ - TComponent *theComponent = GetComponent(inComponent); - GotoSlideIndex(theComponent, theComponent->GetPreviousSlide()); -} - -//============================================================================== -/** - * Set the component's local time using the supplied time. - * @param inComponent reference to the TComponent - * @param inTime supplied time - */ -void CComponentManager::GoToTime(TElement *inComponent, const TTimeUnit inTime) -{ - if (inComponent == NULL) - return; - if (inComponent->GetActive() == false) { - qCCritical(qt3ds::INVALID_OPERATION) - << "Runtime: Attempt to goto time on inactive component!"; - return; - } - m_Presentation.GetActivityZone()->GoToTime(*inComponent, inTime); - inComponent->SetDirty(); -} - -//============================================================================== -/** - * Get the component's playback state - * @param inComponent reference to the TComponent - * @return true if it's paused, false if it's playing - */ -BOOL CComponentManager::GetPause(TElement *inComponent) -{ - CTimePolicy &theTimePolicy = GetComponent(inComponent)->GetTimePolicy(); - return theTimePolicy.GetPaused(); -} - -//============================================================================== -/** - * Get the component's ping pong direction - * @param inComponent reference to the TComponent - * @return true if it's pingponging forward, false if it's pingponging backwards - */ -BOOL CComponentManager::GetPlayBackDirection(TElement *inComponent) -{ - return GetComponent(inComponent)->GetPlayBackDirection(); -} - -//============================================================================== -/** - * Update time policy of the component during each slide execution - * @param inComponent reference to the TComponent - * @param inLoopDuration loop duration of component at that slide - * @param inRepetitions number of repetitions - * @param inPingPong if true the component will move with respect to reverse time - *sequence - * @param inPlayThrough if true the component will continue to execute next slide - */ -void CComponentManager::SetTimePolicy(TElement *inComponent, const TTimeUnit inLoopDuration, - const UINT32 inRepetitions, const BOOL inPingPong, - const BOOL inPlayThrough) -{ - CTimePolicy &theTimePolicy = GetComponent(inComponent)->GetTimePolicy(); - theTimePolicy.Initialize(inLoopDuration, inRepetitions, inPingPong); - inComponent->SetPlayThrough(inPlayThrough); -} - -//============================================================================== -/** - * Set the component's playback to either play or pause - * @param inComponent reference to the TComponent - * @param inPause true = pause, false = play - */ -void CComponentManager::SetPause(TElement *inComponent, const BOOL inPause) -{ - CTimePolicy &theTimePolicy = GetComponent(inComponent)->GetTimePolicy(); - BOOL wasPaused = theTimePolicy.GetPaused(); - theTimePolicy.SetPaused(inPause); - if (wasPaused != inPause) - inComponent->SetDirty(); -} - -//============================================================================== -/** - * Promote from TElement* to TComponent. - * @param inElement TElement pointer to be recast as TComponent - * @return pointer to the component - */ -TComponent *CComponentManager::GetComponent(TElement *inElement) -{ - Q3DStudio_ASSERT(inElement->IsComponent()); - return static_cast(inElement); -} - -//============================================================================== -/** - * Gets the string name of the current slide. - * @param inComponent the component to query for it's current slide name - * @return the char buffer storing the name - */ -const CHAR *CComponentManager::GetCurrentSlideName(TElement *inComponent) -{ - TComponent *theComponent = GetComponent(inComponent); - return m_Presentation.GetSlideSystem().GetSlideName( - SSlideKey(*theComponent, (qt3ds::QT3DSU8)theComponent->GetCurrentSlide())); -} - -void CComponentManager::OnElementDeactivated(TElement *) -{ -} - -void CComponentManager::SetComponentTimeOverride(TElement *inElement, TTimeUnit inEndTime, - FLOAT inInterpolation, - IComponentTimeOverrideFinishedCallback *inCallback) -{ - if (inElement->IsComponent()) { - qCCritical(qt3ds::INVALID_OPERATION) - << "ComponentManager: SetComponentTimeOverride called on object that " - << "wasn't an element"; - if (inCallback) - inCallback->Release(); - Q3DStudio_ASSERT(false); - return; - } - // sanitize end time. - CTimePolicy &theTimePolicy = GetComponent(inElement)->GetTimePolicy(); - if (inEndTime < 0) - inEndTime = 0; - if (inEndTime > theTimePolicy.GetLoopingDuration()) - inEndTime = theTimePolicy.GetLoopingDuration(); - m_Presentation.GetActivityZone()->GetOrCreateItemComponentOverride(*inElement, inInterpolation, - inEndTime, inCallback); - - // Force the time policy object to respect its own time. If we played through till the end and - // sat there for a while - // we need the actual time will travel further and further from the time policy's local time. - // If we then play backward we - // will jump until the offset is synchronized with the actual time. - theTimePolicy.SetTime(theTimePolicy.GetTime()); - inElement->SetDirty(); -} - -void CComponentManager::SetupComponentGotoSlideCommand(TElement *inElement, - const SComponentGotoSlideData &inSlide) -{ - m_ComponentGotoSlideMap[inElement] = inSlide; -} - -bool CComponentManager::HasComponentGotoSlideCommand(TElement *inElement) -{ - return m_ComponentGotoSlideMap.find(inElement) != m_ComponentGotoSlideMap.end(); -} - -SComponentGotoSlideData CComponentManager::GetComponentGotoSlideCommand(TElement *inElement) -{ - TComponentGotoSlideDataMap::iterator iter = m_ComponentGotoSlideMap.find(inElement); - if (iter != m_ComponentGotoSlideMap.end()) - return iter->second; - return -1; -} - -void CComponentManager::ReleaseComponentGotoSlideCommand(TElement *inElement) -{ - TComponentGotoSlideDataMap::iterator iter = m_ComponentGotoSlideMap.find(inElement); - if (iter != m_ComponentGotoSlideMap.end()) - m_ComponentGotoSlideMap.erase(iter); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSElementHelper.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSElementHelper.cpp deleted file mode 100644 index acf8849e..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSElementHelper.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -#include "Qt3DSElementHelper.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSApplication.h" -#include "Qt3DSCommandEventTypes.h" - -using namespace qt3ds; - -namespace Q3DStudio { - -const char PRESENTATION_DELIMITER = ':'; -const char NODE_DELIMITER = '.'; -const TStringHash RESERVED_THIS = CHash::HashString("this"); -const TStringHash RESERVED_PARENT = CHash::HashString("parent"); -const TStringHash RESERVED_SCENE = CHash::HashString("Scene"); - -CElementHelper::CElementHelper() -{ -} - -CElementHelper::~CElementHelper() -{ -} - -TElement *CElementHelper::GetElement(qt3ds::runtime::IApplication &inApplication, - IPresentation *inDefaultPresentation, const char *inPath, - TElement *inStartElement) -{ - if (!inPath || *inPath == 0) - return nullptr; - const char *thePath(inPath); - const char *theSubPath = nullptr; - IPresentation *thePresentation = nullptr; - size_t thePathLength = ::strlen(thePath) + 1; - char *theToken = Q3DStudio_allocate_desc(CHAR, thePathLength, "Token:TempPath"); - // Try to get the specified presentation - theSubPath = ::strchr(thePath, PRESENTATION_DELIMITER); - TElement *theElement = inStartElement; - if (theSubPath) { - UINT32 theSubPathLength = static_cast(theSubPath - thePath); - - ::strncpy(theToken, thePath, theSubPathLength); - theToken[theSubPathLength] = '\0'; - - thePath = theSubPath + 1; - - const CHAR *thePresentationName = theToken; - - thePresentation = inApplication.GetPresentationById(thePresentationName); - } - - if (!thePresentation) - thePresentation = inDefaultPresentation; - - // Return nil if the inStartElement is not in the specified presentation - if (theElement - && (!theSubPath && theElement->GetBelongedPresentation() != thePresentation)) { - thePresentation = theElement->GetBelongedPresentation(); - } - - if (!thePresentation) - return nullptr; - - TStringHash theName; - INT32 theParseCounter = 0; - - while (thePath && thePath[0] != '\0') { - ++theParseCounter; - - // Do some strtok() work here - theSubPath = ::strchr(thePath, NODE_DELIMITER); - if (theSubPath) { - UINT32 theSubPathLength = static_cast(theSubPath - thePath); - Q3DStudio_ASSERT(theSubPathLength < thePathLength); - - ::strncpy(theToken, thePath, theSubPathLength); - theToken[theSubPathLength] = '\0'; - - thePath = theSubPath + 1; - } else { - ::strcpy(theToken, thePath); - thePath = nullptr; - } - - // Hash the token and do some element searching - theName = CHash::HashString(theToken); - - if (theName == RESERVED_PARENT) { - if (theElement) - theElement = theElement->GetParent(); - } else if (theName == RESERVED_THIS) { - ; - } else { - if (theName == RESERVED_SCENE && theParseCounter == 1) { - // theElement is nullptr, so using absolute path - theElement = thePresentation->GetRoot(); - } else if (theElement) { - // Using relative path - theElement = theElement->FindChild(theName); - } - } - - if (!theElement) - thePath = nullptr; - } // while - - Q3DStudio_free(theToken, CHAR, thePathLength); - return theElement; -} -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSElementSystem.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSElementSystem.cpp deleted file mode 100644 index 44850859..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSElementSystem.cpp +++ /dev/null @@ -1,855 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "RuntimePrefix.h" -#include "Qt3DSElementSystem.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "EASTL/sort.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "Qt3DSHash.h" -#include "Qt3DSActivationManager.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSPresentationFrameData.h" -#include "Qt3DSAttributeHashes.h" -#include "foundation/SerializationTypes.h" -#include "foundation/IOStreams.h" -#include "foundation/Qt3DSIndexableLinkedList.h" - -using namespace qt3ds::runtime::element; -using namespace qt3ds; -using namespace qt3ds::foundation; -using namespace qt3ds::intrinsics; -namespace eastl { -template <> -struct hash -{ - size_t operator()(const STypeDesc &inDesc) const { return inDesc.HashCode(); } -}; -} - -namespace { -typedef IndexableLinkedList - TElementPropertyList; -struct SPropertyDescSorter -{ - bool operator()(const TPropertyDescAndValue &lhs, const TPropertyDescAndValue &rhs) const - { - return strcmp(lhs.first.m_Name.c_str(), rhs.first.m_Name.c_str()) < 0; - } -}; -QT3DSU32 GetNumValueAllocations(const STypeDesc &inTypeDesc) -{ - return ((inTypeDesc.m_Properties.size() + SPropertyValueGroup::NumValues - 1) - / SPropertyValueGroup::NumValues); -} -struct SElementAllocator : public qt3ds::runtime::IElementAllocator -{ - typedef Pool TElementPool; - typedef Pool TComponentPool; - typedef TElementPropertyList::TPoolType TValuePool; - typedef nvhash_map THandleElementMap; - typedef nvhash_map TElementOffsetMap; - typedef nvhash_set TTypeDescSet; - typedef nvhash_map TTypeDescOffsetMap; - typedef nvhash_map TOffsetTypeDescMap; - typedef nvvector> TLoadBufferList; - - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - TElementPool m_Elements; - TComponentPool m_Components; - TValuePool m_Values; - THandleElementMap m_HandleToElements; - TElementOffsetMap m_ElementOffsets; - TTypeDescOffsetMap m_TypeDescOffsets; - TOffsetTypeDescMap m_OffsetsToTypeDescs; - TTypeDescSet m_TypeDescriptors; - nvvector m_TempPropertyDescsAndValues; - nvvector m_TempPropertyDescs; - nvvector m_IgnoredProperties; - // Upon load we allocate a set of buffers - nvvector m_LoadBuffer; - TLoadBufferList m_AllocatedBuffers; - SSAutoDeallocatorAllocator m_AutoAllocator; - nvvector m_LoadElements; - - QT3DSU32 m_NextElementHandle; - - eastl::string m_Workspace; - eastl::string m_WorkspaceExt; - - QT3DSI32 m_RefCount; - - SElementAllocator(NVFoundationBase &inFoundation, IStringTable &inStrTable) - : m_Foundation(inFoundation) - , m_StringTable(inStrTable) - , m_Elements(ForwardingAllocator(m_Foundation.getAllocator(), "m_Elements")) - , m_Components(ForwardingAllocator(m_Foundation.getAllocator(), "m_Components")) - , m_Values(ForwardingAllocator(m_Foundation.getAllocator(), "m_Values")) - , m_HandleToElements(m_Foundation.getAllocator(), "m_HandleToElements") - , m_ElementOffsets(m_Foundation.getAllocator(), "m_ElementOffsets") - , m_TypeDescOffsets(m_Foundation.getAllocator(), "m_TypeDescOffsets") - , m_OffsetsToTypeDescs(m_Foundation.getAllocator(), "m_OffsetsToTypeDescs") - , m_TypeDescriptors(m_Foundation.getAllocator(), "m_TypeDescriptors") - , m_TempPropertyDescsAndValues(m_Foundation.getAllocator(), "m_TempPropertyDescsAndValues") - , m_TempPropertyDescs(m_Foundation.getAllocator(), "m_TempPropertyDescs") - , m_IgnoredProperties(m_Foundation.getAllocator(), "m_IgnoredProperties") - , m_LoadBuffer(m_Foundation.getAllocator(), "m_LoadBuffer") - , m_AllocatedBuffers(m_Foundation.getAllocator(), "m_AllocatedBuffers") - , m_AutoAllocator(inFoundation) - , m_LoadElements(inFoundation.getAllocator(), "m_LoadElements") - , m_NextElementHandle(1) - , m_RefCount(0) - { - } - - ~SElementAllocator() {} - - void GetIgnoredProperties() - { - if (m_IgnoredProperties.empty()) - m_IgnoredProperties.push_back(m_StringTable.RegisterStr("name")); - } - - void addRef() override { atomicIncrement(&m_RefCount); } - - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Foundation.getAllocator()); - NVDelete(alloc, this); - } - } - - SElement &CreateElement(CRegisteredString inName, CRegisteredString inType, - CRegisteredString inSubType, - NVConstDataRef inPropertyDescriptions, - Q3DStudio::IPresentation *inPresentation, SElement *inParent, - bool inIsComponent) override - { - m_TempPropertyDescsAndValues.clear(); - m_TempPropertyDescs.clear(); - bool participatesInTimeGraph = false; - GetIgnoredProperties(); - for (QT3DSU32 idx = 0, end = inPropertyDescriptions.size(); idx < end; ++idx) { - QT3DSU32 nameHash = inPropertyDescriptions[idx].first.GetNameHash(); - if (nameHash == Q3DStudio::ATTRIBUTE_STARTTIME - || nameHash == Q3DStudio::ATTRIBUTE_ENDTIME) - participatesInTimeGraph = true; - if (eastl::find(m_IgnoredProperties.begin(), m_IgnoredProperties.end(), - inPropertyDescriptions[idx].first.m_Name) - == m_IgnoredProperties.end()) { - m_TempPropertyDescsAndValues.push_back(inPropertyDescriptions[idx]); - } - } - eastl::sort(m_TempPropertyDescsAndValues.begin(), m_TempPropertyDescsAndValues.end(), - SPropertyDescSorter()); - - for (QT3DSU32 idx = 0, end = m_TempPropertyDescsAndValues.size(); idx < end; ++idx) { - m_TempPropertyDescs.push_back(m_TempPropertyDescsAndValues[idx].first); - } - - STypeDesc theDesc; - theDesc.m_TypeName = inType; - theDesc.m_SubtypeName = inSubType; - theDesc.m_Properties = m_TempPropertyDescs; - theDesc.SetHashValue(); - eastl::pair inserter = m_TypeDescriptors.insert(theDesc); - - const STypeDesc &theTypeDesc = *inserter.first; - if (inserter.second) { - size_t allocSize = theDesc.m_Properties.size() * sizeof(SPropertyDesc); - if (allocSize) { - SPropertyDesc *newProps = (SPropertyDesc *)m_AutoAllocator.allocate( - allocSize, "TypeDescData", __FILE__, __LINE__, 0); - memCopy(newProps, theDesc.m_Properties.begin(), (QT3DSU32)allocSize); - // Note that this does not change the hash value. - const_cast(theTypeDesc).m_Properties = - toConstDataRef(newProps, theDesc.m_Properties.size()); - } - } - - SElement *retval = inIsComponent ? m_Components.construct(theTypeDesc, __FILE__, __LINE__) - : m_Elements.construct(theTypeDesc, __FILE__, __LINE__); - retval->m_BelongedPresentation = inPresentation; - retval->m_Name = inName; - // children - if (inParent) { - retval->m_Parent = inParent; - if (inParent->m_Child == NULL) { - inParent->m_Child = retval; - } else { - SElement *lastChild = inParent->m_Child; - while (lastChild->m_Sibling) - lastChild = lastChild->m_Sibling; - lastChild->m_Sibling = retval; - } - } - while (FindElementByHandle(m_NextElementHandle)) { - ++m_NextElementHandle; - if (!m_NextElementHandle) - ++m_NextElementHandle; - } - - // required flags - retval->m_Handle = m_NextElementHandle; - if (inIsComponent) - retval->Flags().clearOrSet(true, Q3DStudio::ELEMENTFLAG_COMPONENT); - - if (participatesInTimeGraph) - retval->Flags().clearOrSet(true, Q3DStudio::ELEMENTFLAG_TIMELINE); - - retval->Flags().clearOrSet(true, Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE); - - retval->SetDepth(); - - retval->SetDirty(); - - m_HandleToElements.insert(eastl::make_pair(retval->m_Handle, retval)); - - // property values; - QT3DSU32 propIdx = 0; - TElementPropertyList::CreateAll(retval->m_PropertyValues, theTypeDesc.m_Properties.size(), - m_Values); - for (TElementPropertyList::iterator - iter = TElementPropertyList::begin(retval->m_PropertyValues, - theTypeDesc.m_Properties.size()), - end = TElementPropertyList::end(retval->m_PropertyValues, - theTypeDesc.m_Properties.size()); - iter != end; ++iter, ++propIdx) { - (*iter) = m_TempPropertyDescsAndValues[propIdx].second; - } - - return *retval; - } - - void ReleaseElement(SElement &inElement, bool inRecurse) override - { - if (inRecurse) { - while (inElement.m_Child) - ReleaseElement(*inElement.m_Child, true); - } - // Trim out the element. - if (inElement.m_Parent) { - SElement *theParent = inElement.m_Parent; - if (theParent->m_Child == &inElement) - theParent->m_Child = inElement.m_Sibling; - else { - SElement *thePreviousChild = NULL; - // Empty loop to find the previous child - for (thePreviousChild = theParent->m_Child; - thePreviousChild->m_Sibling != &inElement && thePreviousChild; - thePreviousChild = thePreviousChild->m_Sibling) { - } - if (thePreviousChild) - thePreviousChild->m_Sibling = inElement.m_Sibling; - } - } - - m_HandleToElements.erase(inElement.m_Handle); - - QT3DSU8 *elemAddr = reinterpret_cast(&inElement); - for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx) { - NVDataRef theBuffer(m_AllocatedBuffers[idx]); - // Preloaded element, do not release back to element pools - if (elemAddr >= theBuffer.begin() && elemAddr < theBuffer.end()) - return; - } - - SPropertyValueGroup *theValueGroup = inElement.m_PropertyValues; - while (theValueGroup) { - SPropertyValueGroup *currentGroup = theValueGroup; - theValueGroup = theValueGroup->m_NextNode; - m_Values.deallocate(currentGroup); - } - - if (inElement.IsComponent()) - m_Components.deallocate(&inElement); - else - m_Elements.deallocate(&inElement); - } - - QT3DSI32 GetExtensionIndex(eastl::string &inExt) - { - QT3DSI32 retVal = 0; - - if (!inExt.compare(".x") || !inExt.compare(".r")) - retVal = 0; - else if (!inExt.compare(".y") || !inExt.compare(".g")) - retVal = 1; - if (!inExt.compare(".z") || !inExt.compare(".b")) - retVal = 2; - - return retVal; - } - - virtual Option - CreateDynamicProperty(Q3DStudio::IRuntimeMetaData &theMetaData, SElement &element, - CRegisteredString inName) override - { - SPropertyDesc *newProp = NULL; - m_TempPropertyDescsAndValues.clear(); - m_TempPropertyDescs.clear(); - - // create dynamic descriptor - if (!element.m_DynamicTypeDescription) { - STypeDesc *theDesc; - theDesc = (STypeDesc *)m_AutoAllocator.allocate(sizeof(STypeDesc), "TypeDescData", - __FILE__, __LINE__, 0); - theDesc->m_TypeName = element.m_TypeDescription->m_TypeName; - theDesc->m_SubtypeName = element.m_TypeDescription->m_SubtypeName; - theDesc->m_Properties = m_TempPropertyDescs; - theDesc->SetHashValue(); - // we need this palcement new here - ::new (theDesc) STypeDesc(); - element.m_DynamicTypeDescription = const_cast(theDesc); - } - - STypeDesc *theTypeDesc = element.m_DynamicTypeDescription; - - // remove the extension that we can find the property - QT3DSI32 extIndex = 0; - m_Workspace.assign(inName.c_str()); - eastl::string::size_type theCharPos = m_Workspace.rfind('.'); - if (theCharPos != eastl::string::npos) { - m_WorkspaceExt.assign(m_Workspace, theCharPos, m_Workspace.length()); - m_Workspace.resize(theCharPos); - extIndex = GetExtensionIndex(m_WorkspaceExt); - } - - CRegisteredString theWorkSpaceString = m_StringTable.RegisterStr(m_Workspace.c_str()); - Q3DStudio::ERuntimeDataModelDataType thePropertyType = - theMetaData.GetPropertyType(element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - - // using separate properties - bool separateProperties = theCharPos != eastl::string::npos; - - // single property - size_t allocSize = sizeof(SPropertyDesc); - if (allocSize) { - newProp = (SPropertyDesc *)m_AutoAllocator.allocate(allocSize, "SPropertyDesc", - __FILE__, __LINE__, 0); - - newProp->m_Name = inName; - - // convert to appropriate type - if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat) { - float value = theMetaData.GetPropertyValueFloat( - element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; - - Q3DStudio::UVariant theValue; - theValue.m_FLOAT = value; - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), theValue)); - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat2) { - qt3ds::QT3DSVec3 value = theMetaData.GetPropertyValueVector2( - element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; - - Q3DStudio::UVariant theVarValue; - theVarValue.m_FLOAT = value[extIndex]; - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), - theVarValue)); - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat3) { - qt3ds::QT3DSVec3 value = theMetaData.GetPropertyValueVector3( - element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - - if (separateProperties) { - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; - - Q3DStudio::UVariant theVarValue; - theVarValue.m_FLOAT = value[extIndex]; - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), - theVarValue)); - } else { - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT3; - - Q3DStudio::UVariant theVarValue; - theVarValue.m_FLOAT3[0] = value[0]; - theVarValue.m_FLOAT3[1] = value[1]; - theVarValue.m_FLOAT3[2] = value[2]; - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT3), - theVarValue)); - } - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeLong) { - QT3DSI32 value = (QT3DSI32)theMetaData.GetPropertyValueLong( - element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_INT32; - - Q3DStudio::UVariant theVarValue; - theVarValue.m_INT32 = value; - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_INT32), - theVarValue)); - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeBool) { - bool value = theMetaData.GetPropertyValueBool( - element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_BOOL; - - Q3DStudio::UVariant theVarValue; - theVarValue.m_INT32 = value; - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_BOOL), theVarValue)); - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeString) { - Option theRuntimeStr = theMetaData.GetPropertyValueString( - element.m_TypeDescription->m_TypeName, theWorkSpaceString, - element.m_TypeDescription->m_SubtypeName); - - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_STRING; - - CStringHandle theString = m_StringTable.GetHandle(theRuntimeStr->c_str()); - Q3DStudio::UVariant theVarValue; - theVarValue.m_StringHandle = theString.handle(); - m_TempPropertyDescsAndValues.push_back(eastl::make_pair( - SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_STRING), - theVarValue)); - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } else { - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; - - theTypeDesc->m_DynamicProperties.push_back(*newProp); - } - } - - // property values; - QT3DSU32 newListSize = theTypeDesc->m_DynamicProperties.size() - 1; - TElementPropertyList::Create(element.m_DynamicPropertyValues, newListSize, m_Values); - - Q3DStudio::UVariant &propertyValue = - TElementPropertyList::GetObjAtIdx(element.m_DynamicPropertyValues, newListSize - 1); - propertyValue = m_TempPropertyDescsAndValues[0].second; - - return eastl::make_pair( - element.m_DynamicTypeDescription->m_DynamicProperties[newListSize - 1], - &TElementPropertyList::GetObjAtIdx(element.m_DynamicPropertyValues, newListSize - 1)); - } - - SElement *FindElementByHandle(QT3DSU32 inElementHandle) override - { - THandleElementMap::iterator theFind = m_HandleToElements.find(inElementHandle); - if (theFind != m_HandleToElements.end()) - return theFind->second; - return NULL; - } - - // Returns an element pointer that when added to the return value of load will be a valid - // element. - SElement *GetRemappedElementAddress(SElement *inElement) const override - { - if (inElement == NULL) - return NULL; - TElementOffsetMap::const_iterator iter = m_ElementOffsets.find(inElement); - if (iter != m_ElementOffsets.end()) - return reinterpret_cast(iter->second); - return NULL; - } - - const STypeDesc *GetRemappedTypeDescAddress(const STypeDesc *inTypeDesc) const override - { - TTypeDescOffsetMap::const_iterator iter = m_TypeDescOffsets.find((STypeDesc *)inTypeDesc); - if (iter != m_TypeDescOffsets.end()) - return reinterpret_cast(iter->second); - return NULL; - } - const STypeDesc *RemapTypeDesc(const STypeDesc *inOffset) - { - size_t memoryOffset = reinterpret_cast(inOffset); - TOffsetTypeDescMap::iterator iter = - m_OffsetsToTypeDescs.find(static_cast(memoryOffset)); - if (iter != m_OffsetsToTypeDescs.end()) - return iter->second; - return NULL; - } - - SElement *RemapElement(SElement *inElem, size_t memoryOffset) - { - if (inElem) - return reinterpret_cast(reinterpret_cast(inElem) + memoryOffset); - return NULL; - } -}; -} - -bool STypeDesc::operator==(const STypeDesc &inOther) const -{ - if (m_TypeName == inOther.m_TypeName && m_SubtypeName == inOther.m_SubtypeName - && m_Properties.size() == inOther.m_Properties.size()) { - for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { - const SPropertyDesc &lhs = m_Properties[idx]; - const SPropertyDesc &rhs = inOther.m_Properties[idx]; - if (lhs.m_Name != rhs.m_Name || lhs.m_Type != rhs.m_Type) - return false; - } - return true; - } - return false; -} - -Option STypeDesc::FindProperty(QT3DSU32 inNameHash) const -{ - for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { - const SPropertyDesc &theDesc = m_Properties[idx]; - if (Q3DStudio::CHash::HashAttribute(theDesc.m_Name) == inNameHash) - return idx; - } - return Empty(); -} - -Option STypeDesc::FindProperty(CRegisteredString inName) const -{ - for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { - const SPropertyDesc &theDesc = m_Properties[idx]; - if (theDesc.m_Name == inName) - return idx; - } - return Empty(); -} - -Option STypeDesc::FindDynamicProperty(QT3DSU32 inNameHash) const -{ - for (QT3DSU32 idx = 0, end = m_DynamicProperties.size(); idx < end; ++idx) { - const SPropertyDesc &theDesc = m_DynamicProperties[idx]; - if (Q3DStudio::CHash::HashAttribute(theDesc.m_Name) == inNameHash) - return idx; - } - return Empty(); -} - -void STypeDesc::SetHashValue() -{ - size_t typeDescHash = m_TypeName.hash() ^ m_SubtypeName.hash(); - for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { - typeDescHash = typeDescHash ^ m_Properties[idx].m_Name.hash(); - typeDescHash = typeDescHash ^ eastl::hash()(m_Properties[idx].m_Type); - } - // TODO check 64 bit compatibility - m_HashValue = (QT3DSU32)typeDescHash; -} - -QT3DSU32 SPropertyDesc::GetNameHash() const -{ - return Q3DStudio::CHash::HashAttribute(m_Name.c_str()); -} - -Q3DStudio::SAttributeKey SPropertyDesc::GetAttributeKey() const -{ - Q3DStudio::SAttributeKey retval; - memZero(&retval, sizeof(retval)); - retval.m_Type = m_Type; - retval.m_Hash = GetNameHash(); - return retval; -} - -bool SElement::IsUserActive() const -{ - return m_Flags.IsExplicitActive(); -} - -bool SElement::IsIndependent() const -{ - return IsComponent(); -} - -bool SElement::IsGlobalActive() const -{ - return GetActive(); -} -// This may require a mutex to be held. -void SElement::SetGlobalActive(bool active) -{ - SetActive(active); -} - -bool SElement::GetAttribute(QT3DSU32 inHashName, Q3DStudio::UVariant &outValue) const -{ - if (inHashName == Q3DStudio::ATTRIBUTE_NAME) { - outValue.m_StringHandle = m_BelongedPresentation->GetStringTable().GetHandle(m_Name); - return true; - } - if (inHashName == Q3DStudio::CHash::HashAttribute("path")) { - outValue.m_StringHandle = m_BelongedPresentation->GetStringTable().GetHandle(m_Path); - return true; - } - const Q3DStudio::UVariant *valPtr = FindPropertyValue(inHashName); - if (valPtr) { - outValue = *valPtr; - return true; - } - return false; -} - -void SElement::SetAttribute(const Q3DStudio::TAttributeHash inKey, - const Q3DStudio::UVariant inValue) -{ - Option existing = FindProperty(inKey); - if (existing.hasValue() == false) - return; - SetAttribute(*existing, inValue); -} - -void SElement::SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVariant inValue) -{ - Q3DStudio::EAttributeType theType = inKey.first.m_Type; - Q3DStudio::UVariant *currentValue = inKey.second; - QT3DSU32 attHash = inKey.first.GetNameHash(); - switch (theType) { - case Q3DStudio::ATTRIBUTETYPE_FLOAT: // Early return - if (fabs(currentValue->m_FLOAT - inValue.m_FLOAT) < SmallestDifference()) - return; - break; - case Q3DStudio::ATTRIBUTETYPE_FLOAT3: // Early return - if (fabs(currentValue->m_FLOAT3[0] - inValue.m_FLOAT3[0]) < SmallestDifference() - && fabs(currentValue->m_FLOAT3[1] - inValue.m_FLOAT3[1]) < SmallestDifference() - && fabs(currentValue->m_FLOAT3[2] - inValue.m_FLOAT3[2]) < SmallestDifference()) { - return; - } - break; - case Q3DStudio::ATTRIBUTETYPE_STRING: - if (currentValue->m_StringHandle == inValue.m_StringHandle) - return; - break; - default: // Early return - if (currentValue->m_INT32 == inValue.m_INT32) - return; - break; - } - *currentValue = inValue; - - if (Q3DStudio::ATTRIBUTE_EYEBALL == attHash) - SetFlag(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE, inValue.m_INT32 ? true : false); - - if (Q3DStudio::ATTRIBUTE_STARTTIME == attHash || Q3DStudio::ATTRIBUTE_ENDTIME == attHash) - GetActivityZone().UpdateItemInfo(*this); - - /* - if ( inElement->m_Flags & ELEMENTFLAG_REGISTEREDFORATTRIBUTECHANGE ) - m_AttributeChangeCallbacks.FireCallbacks( inElement, theAttribute->m_Key, - thePreviousValue, inValue ); - */ - SetDirty(); -} - -// SElement implementation -QT3DSU32 SElement::GetNameHash() const -{ - return Q3DStudio::CHash::HashString(m_Name.c_str()); -} - -// Q3DStudio::CHash::HashAttribute -Option SElement::FindPropertyIndex(QT3DSU32 inNameHash) const -{ - return m_TypeDescription->FindProperty(inNameHash); -} - -Option SElement::FindPropertyIndex(CRegisteredString inName) const -{ - return m_TypeDescription->FindProperty(inName); -} - -Option SElement::FindDynamicPropertyIndex(QT3DSU32 inNameHash) const -{ - if (m_DynamicTypeDescription) - return m_DynamicTypeDescription->FindDynamicProperty(inNameHash); - else - return Empty(); -} - -QT3DSU32 SElement::GetNumProperties() const -{ - return m_TypeDescription->m_Properties.size(); -} - -QT3DSU32 SElement::GetNumDynamicProperties() const -{ - if (m_DynamicTypeDescription) - return m_DynamicTypeDescription->m_DynamicProperties.size(); - else - return 0; -} - -Option SElement::GetPropertyByIndex(QT3DSU32 inIdx) -{ - if (inIdx < this->m_TypeDescription->m_Properties.size()) - return eastl::make_pair(m_TypeDescription->m_Properties[inIdx], - &TElementPropertyList::GetObjAtIdx(m_PropertyValues, inIdx)); - - return Empty(); -} - -Option SElement::GetDynamicPropertyByIndex(QT3DSU32 inIdx) -{ - if (inIdx < this->m_DynamicTypeDescription->m_DynamicProperties.size()) - return eastl::make_pair(m_DynamicTypeDescription->m_DynamicProperties[inIdx], - &TElementPropertyList::GetObjAtIdx(m_DynamicPropertyValues, inIdx)); - - return Empty(); -} - -Option SElement::GetPropertyByIndex(QT3DSU32 inIdx) const -{ - Option retval = - const_cast(*this).GetPropertyByIndex(inIdx); - if (retval.hasValue()) - return TPropertyDescAndConstValuePtr(*retval); - return Empty(); -} - -void SElement::SetDirty() -{ - if (!m_Flags.IsDirty()) { - m_Flags.SetDirty(true); - // The element is dirty, so place it on the frame data dirty list - m_BelongedPresentation->GetFrameData().GetDirtyList().Push(this); - m_Flags.SetDirty(true); - } -} - -void SElement::SetFlag(Q3DStudio::EElementFlag inFlag, bool inValue) -{ - bool existing = m_Flags & inFlag; - if (existing != inValue && HasActivityZone()) { - m_Flags.clearOrSet(inValue, inFlag); - if (inFlag == Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE) - GetActivityZone().UpdateItemInfo(*this); - else if (inFlag == Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS) - GetActivityZone().UpdateItemScriptStatus(*this); - SetDirty(); - } -} - -bool SElement::HasActivityZone() const -{ - return m_BelongedPresentation->GetActivityZone() != NULL; -} - -qt3ds::runtime::IActivityZone &SElement::GetActivityZone() const -{ - return *m_BelongedPresentation->GetActivityZone(); -} - -SElement &SElement::GetComponentParent() -{ - if (IsComponent()) - return *this; - - SElement *theParent = GetActivityZone().GetItemTimeParent(*this); - if (theParent) - return *theParent; - QT3DS_ASSERT(false); - return *this; -} - -const SElement &SElement::GetComponentParent() const -{ - return const_cast(this)->GetComponentParent(); -} - -SElement *SElement::FindChild(QT3DSU32 inNameHash) -{ - for (SElement *theChild = m_Child; theChild; theChild = theChild->m_Sibling) { - if (theChild->GetNameHash() == inNameHash) - return theChild; - } - return NULL; -} - -Q3DStudio::TTimeUnit SElement::GetInnerTime() const -{ - return GetActivityZone().GetItemComponentTime(const_cast(*this)); -} -// Get the time I am animating at. -Q3DStudio::TTimeUnit SElement::GetOuterTime() const -{ - return GetActivityZone().GetItemLocalTime(const_cast(*this)); -} - -bool SElement::IsDescendent(SElement &inPossibleParent) const -{ - if (m_Parent == NULL) - return false; - if (m_Parent == &inPossibleParent) - return true; - return m_Parent->IsDescendent(inPossibleParent); -} - -bool SComponent::GetPaused() const -{ - return GetTimePolicy().GetPaused(); -} - -bool SComponent::GetPlayBackDirection() const -{ - return GetTimePolicy().GetPlayBackDirection(); -} - -Q3DStudio::CTimePolicy &SComponent::GetTimePolicy() -{ - return *GetActivityZone().GetOwnedTimePolicy(*this); -} - -const Q3DStudio::CTimePolicy &SComponent::GetTimePolicy() const -{ - return const_cast(this)->GetTimePolicy(); -} - -qt3ds::runtime::IElementAllocator & -qt3ds::runtime::IElementAllocator::CreateElementAllocator(NVFoundationBase &inFoundation, - IStringTable &inStringTable) -{ - return *QT3DS_NEW(inFoundation.getAllocator(), SElementAllocator)(inFoundation, inStringTable); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSEventCallbacks.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSEventCallbacks.cpp deleted file mode 100644 index 25d720ea..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSEventCallbacks.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSEventCallbacks.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - */ -CEventCallbacks::CEventCallbacks() - : m_EventCallbacksList(0, 0, "EventCallbacksList") - , m_CallbackList(0, 0, "CallbackList") -{ -} - -//============================================================================== -/** - * Destructor - */ -CEventCallbacks::~CEventCallbacks() -{ - UnregisterAllCallbacks(); -} - -//============================================================================== -/** - * Registers a callback to be triggered when a specific event is fired on an - * element. - * @param inElement element to monitor - * @param inEventHash event hash to monitor - * @param inCallback static callback function - * @param inContextData arbitary data pointer - */ -void CEventCallbacks::RegisterCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) -{ - TEventCallbacksList *theEventCallbackList = NULL; - - // Look for the list of callbacks for this element - FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) - { - if (inElement == (*theEntry)->m_Element) { - theEventCallbackList = &(*theEntry)->m_EventEntries; - break; - } - } - - // Create a new list of callbacks if it does not already exist - if (!theEventCallbackList) { - SElementCallbackEntry *theElementCallbackEntry = - Q3DStudio_new(SElementCallbackEntry) SElementCallbackEntry(); - theElementCallbackEntry->m_Element = inElement; - m_EventCallbacksList.Push(theElementCallbackEntry); - theEventCallbackList = &m_EventCallbacksList.Top()->m_EventEntries; - } - - TCallbackList *theElementCallbackList = NULL; - - // Look for the list of callbacks for this event - FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList)) - { - if (inEventHash == (*theEntry)->m_EventHash) { - theElementCallbackList = &(*theEntry)->m_Callbacks; - break; - } - } - - // Create a new list of callbacks if it does not already exist - if (!theElementCallbackList) { - SEventCallbackEntry *theEventCallbackEntry = - Q3DStudio_new(SEventCallbackEntry) SEventCallbackEntry(); - theEventCallbackEntry->m_EventHash = inEventHash; - theEventCallbackList->Push(theEventCallbackEntry); - theElementCallbackList = &theEventCallbackList->Top()->m_Callbacks; - } - - // Insert callback - SCallbackEntry theCallbackEntry = { inCallback, inContextData }; - theElementCallbackList->Push(theCallbackEntry); -} - -//============================================================================== -/** - * Unregisters an event callback. - * @param inElement element to monitor - * @param inEventHash event hash to monitor - * @param inCallback static callback function - * @param inContextData arbitary data pointer - * @param outLast indicates if element no longer has callbacks registered - * @return BOOL true if callback is unregistered successfully - */ -BOOL CEventCallbacks::UnregisterCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData, - BOOL &outLast) -{ - outLast = false; - - TEventCallbacksList *theEventCallbackList = NULL; - - INT32 theEventListIndex = 0; - SElementCallbackEntry *theFoundEntry = NULL; - FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) - { - if (inElement == (*theEntry)->m_Element) { - theFoundEntry = *theEntry; - theEventCallbackList = &(*theEntry)->m_EventEntries; - break; - } - ++theEventListIndex; - } - - if (!theEventCallbackList) - return false; - - TCallbackList *theElementCallbackList = NULL; - - INT32 theElementListIndex = 0; - SEventCallbackEntry *theEventCallbackEntry = NULL; - FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList)) - { - if (inEventHash == (*theEntry)->m_EventHash) { - theEventCallbackEntry = *theEntry; - theElementCallbackList = &(*theEntry)->m_Callbacks; - break; - } - ++theElementListIndex; - } - - if (!theElementCallbackList) - return false; - - INT32 theCallbackIndex = 0; - FOR_ARRAY(SCallbackEntry, theEntry, (*theElementCallbackList)) - { - if (inCallback == theEntry->m_Function && inContextData == theEntry->m_ContextData) { - theElementCallbackList->Remove(theCallbackIndex); - - if (theElementCallbackList->GetCount() == 0) { - Q3DStudio_delete(theEventCallbackEntry, SEventCallbackEntry); - theEventCallbackList->Remove(theElementListIndex); - } - - if (theEventCallbackList->GetCount() == 0) { - Q3DStudio_delete(theFoundEntry, SElementCallbackEntry); - m_EventCallbacksList.Remove(theEventListIndex); - outLast = true; - } - - return true; - } - ++theCallbackIndex; - } - - return false; -} - -//============================================================================== -/** - * Unregisters all callbacks. - */ -void CEventCallbacks::UnregisterAllCallbacks() -{ - FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) - Q3DStudio_delete(*theEntry, SElementCallbackEntry); - m_EventCallbacksList.Clear(); -} - -//============================================================================== -/** - * Fires event callbacks - * @param ioEvent the event that was fired - */ -void CEventCallbacks::FireCallbacks(SEventCommand &ioEvent) -{ - TEventCallbacksList *theEventCallbackList = NULL; - - // Look for the list of callbacks for this element - FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) - { - if (ioEvent.m_Target == (*theEntry)->m_Element) { - theEventCallbackList = &(*theEntry)->m_EventEntries; - break; - } - } - - if (!theEventCallbackList) - return; - - // Look for the list of callbacks for this event - FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList)) - { - if (ioEvent.m_Type == (*theEntry)->m_EventHash) { - PerformCallbacks((*theEntry)->m_Callbacks, ioEvent); - break; - } - } -} - -//============================================================================== -/** - * Executing a list of callbacks - * @param inCallbackList the list of callbacks to invoke - * @param ioEvent the event to pass to the callbacks - */ -void CEventCallbacks::PerformCallbacks(TCallbackList &inCallbackList, SEventCommand &ioEvent) -{ - // As the callbacks can potentially do a register/unregister that would alter the call list, - // it is safer to get a clean copy of the call list to iterate through. - - // Clumsy way to do a m_CallbackList = inCallbackList - m_CallbackList.Clear(false); - m_CallbackList.Reserve(inCallbackList.GetCount()); - FOR_ARRAY(SCallbackEntry, theEntry, inCallbackList) - m_CallbackList.Push(*theEntry); - - // Invoking the callbacks - FOR_ARRAY(SCallbackEntry, theEntry, m_CallbackList) - theEntry->m_Function(theEntry->m_ContextData, ioEvent); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSInputEngine.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSInputEngine.cpp deleted file mode 100644 index d3cbe423..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSInputEngine.cpp +++ /dev/null @@ -1,849 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" -#include -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSInputEngine.h" -#include "Qt3DSSceneManager.h" -#include "Qt3DSInputEventTypes.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSApplication.h" -#include "Qt3DSRuntimeFactory.h" -#include "EventPollingSystem.h" -#include "foundation/Qt3DSAssert.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -class CInputEventProvider : public qt3ds::evt::IEventProvider -{ - int m_RefCount; - -public: - CInputEventProvider() - : m_RefCount(0) - { - } - ~CInputEventProvider() - { - while (!m_Events.empty()) { - delete m_Events.front(); - m_Events.pop_front(); - } - } - struct SEvent - { - enum EType { TYPE_NONE = 0, TYPE_KEYBOARD, TYPE_BUTTON, TYPE_COUNT }; - SEvent(EType inType) - : m_Type(inType) - { - } - EType m_Type; - - virtual SEvent *Clone() const = 0; - virtual Qt3DSEventSystemEvent *GenEventSystemEvent(qt3ds::evt::IEventFactory &inFactory) = 0; - }; - struct SKeyboardEvent : public SEvent - { - SKeyboardEvent() - : SEvent(TYPE_KEYBOARD) - , m_KeyCode(KEY_NOKEY) - , m_KeyEvent(0) - { - } - SKeyboardEvent(INT32 inKeyCode, UINT32 inKeyEvent) - : SEvent(TYPE_KEYBOARD) - , m_KeyCode(inKeyCode) - , m_KeyEvent(inKeyEvent) - { - } - SEvent *Clone() const override - { - return new SKeyboardEvent(this->m_KeyCode, this->m_KeyEvent); - } - Qt3DSEventSystemEvent *GenEventSystemEvent(qt3ds::evt::IEventFactory &inFactory) override - { - if (m_KeyEvent == ON_KEYDOWN || m_KeyEvent == ON_KEYUP || m_KeyEvent == ON_KEYREPEAT) { - Qt3DSEventSystemEvent &theEvent = inFactory.CreateEvent(3); - int theIndex = 0; - theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("category"); - theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("kb"); - ++theIndex; - theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("code"); - theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesNumber; - theEvent.m_Data[theIndex].m_Value.m_Number = m_KeyCode; - ++theIndex; - theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("action"); - theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; - if (m_KeyEvent == ON_KEYDOWN) - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("down"); - else if (m_KeyEvent == ON_KEYUP) - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("up"); - else if (m_KeyEvent == ON_KEYREPEAT) - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("repeat"); - ++theIndex; - return &theEvent; - } - QT3DS_ASSERT(false); - return 0; - } - INT32 m_KeyCode; - UINT32 m_KeyEvent; - }; - struct SButtonEvent : public SEvent - { - SButtonEvent() - : SEvent(TYPE_BUTTON) - , m_ButtonCode(BUTTON_TOTAL_COUNT) - , m_ButtonEvent(0) - { - } - SButtonEvent(INT32 inButtonCode, UINT32 inButtonEvent) - : SEvent(TYPE_BUTTON) - , m_ButtonCode(inButtonCode) - , m_ButtonEvent(inButtonEvent) - { - } - SEvent *Clone() const override - { - return new SKeyboardEvent(this->m_ButtonCode, this->m_ButtonEvent); - } - Qt3DSEventSystemEvent *GenEventSystemEvent(qt3ds::evt::IEventFactory &inFactory) override - { - if (m_ButtonEvent == ON_BUTTONDOWN || m_ButtonEvent == ON_BUTTONUP - || m_ButtonEvent == ON_BUTTONREPEAT) { - Qt3DSEventSystemEvent &theEvent = inFactory.CreateEvent(3); - int theIndex = 0; - theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("category"); - theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("button"); - ++theIndex; - theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("code"); - theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesNumber; - theEvent.m_Data[theIndex].m_Value.m_Number = m_ButtonCode; - ++theIndex; - theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("action"); - theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; - if (m_ButtonEvent == ON_BUTTONDOWN) - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("down"); - else if (m_ButtonEvent == ON_BUTTONUP) - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("up"); - else if (m_ButtonEvent == ON_BUTTONREPEAT) - theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("repeat"); - ++theIndex; - return &theEvent; - } - QT3DS_ASSERT(false); - return 0; - } - INT32 m_ButtonCode; - UINT32 m_ButtonEvent; - }; - size_t GetNextEvents(qt3ds::evt::IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, - size_t inBufLenInEvent) override - { - size_t theEventCount = 0; - while (!m_Events.empty() && inBufLenInEvent--) { - SEvent *theBufferedEvent = m_Events.front(); - Qt3DSEventSystemEvent *theEventSystemEvent = - theBufferedEvent->GenEventSystemEvent(inFactory); - if (theEventSystemEvent) - outBuffer[theEventCount++] = theEventSystemEvent; - m_Events.pop_front(); - } - return theEventCount; - } - - void addRef() { ++m_RefCount; } - - void release() - { - --m_RefCount; - if (m_RefCount <= 0) - delete this; - } - - void Release() override { release(); } - - void AddEvent(const SEvent &inEvent) - { - SEvent *theEvent = inEvent.Clone(); - if (theEvent) - m_Events.push_back(theEvent); - else - QT3DS_ASSERT(false); - } - -private: - eastl::list m_Events; -}; - -//============================================================================== -/** - * Constructor - */ -CInputEngine::CInputEngine() - : m_BeginPickInput(false) - , m_Application(NULL) - , m_InputEventProvider(NULL) -{ - m_InputFrame.m_PickValid = false; - m_InputFrame.m_PickX = 0; - m_InputFrame.m_PickY = 0; - - // TODO: SK - To quickly restore functionality, but this is should be in tegra-specific project. - m_InputFrame.m_DeltaX = 0; - m_InputFrame.m_DeltaY = 0; -} - -//============================================================================== -/** - * Destructor - */ -CInputEngine::~CInputEngine() -{ -} - -//============================================================================== -/** - * Set the top-level interface of the Runtime object - * @param inRuntime the top-level interface of the Runtime object - */ -void CInputEngine::SetApplication(qt3ds::runtime::IApplication *inApplication) -{ - m_Application = inApplication; - // Create this here. If we die before the application does, then the system will crash unless - // the application event system is reponsibe for the keyboard provider. Since the provider - // never - // access back to this object, this is the most sensible relationship. Furthermore if we have - // never been given an application, it doesn't make sense to have a keyboard event provider. - // In reality, this entire system should be ref counted. - m_InputEventProvider = new CInputEventProvider(); - - // Add a ref for the event system because it does not add its own ref. - m_InputEventProvider->addRef(); - m_Application->GetRuntimeFactory().GetEventSystem().AddProvider(*m_InputEventProvider); - MarkApplicationDirty(); -} - -//============================================================================== -/** - * Get the input information for the current frame - * @return the SInputFrame that defines the current frame input information - */ -SInputFrame &CInputEngine::GetInputFrame() -{ - return m_InputFrame; -} - -//============================================================================== -/** - * Return the key input portion of the input frame. - */ -SKeyInputFrame &CInputEngine::GetKeyInputFrame() -{ - return m_InputFrame.m_KeyInputFrame; -} - -void CInputEngine::BeginPickInput() -{ - m_PickInput.clear(); - m_BeginPickInput = true; -} - -//============================================================================== -/** - * Set the pick information the the input frame structure - * @param inX the X value of the pick position - * @param inY the Y value of the pick position - * @param inValid whether the X and Y value are valid - */ -void CInputEngine::SetPickInput(FLOAT inX, FLOAT inY, BOOL inValid /*= true*/) -{ - m_InputFrame.m_PickValid = inValid; - m_InputFrame.m_PickX = inX; - m_InputFrame.m_PickY = inY; - m_InputFrame.m_MouseFlags = 0; - MarkApplicationDirty(); - if (m_BeginPickInput && m_PickInput.size() < 1000) - m_PickInput.push_back(eastl::make_pair(inX, inY)); -} - -void CInputEngine::EndPickInput() -{ - m_BeginPickInput = false; -} - -CInputEngine::TPickInputList CInputEngine::GetPickInput() const -{ - return qt3ds::foundation::toDataRef(m_PickInput.data(), m_PickInput.size()); -} - -//============================================================================== -/** - * Set the mouse button state flag - * @param inFlags the current mouse state - */ -void CInputEngine::SetPickFlags(INT32 inFlags) -{ - m_InputFrame.m_MouseFlags |= inFlags; -} - -//============================================================================== -/** - * Set the keyboard status - * @param inKeyCode the identifier of the key - * @param inDown identify whether the key is down - */ -void CInputEngine::SetKeyState(INT32 inKeyCode, BOOL inDown) -{ - if (!inDown) - m_InputFrame.m_KeyInputFrame.m_KeyStates.erase(inKeyCode); - else { - SKeyInputFrame::MAP_KEYCODE_COUNT::iterator theIter = - m_InputFrame.m_KeyInputFrame.m_KeyStates.find(inKeyCode); - if (theIter == m_InputFrame.m_KeyInputFrame.m_KeyStates.end()) - m_InputFrame.m_KeyInputFrame.m_KeyStates.insert( - eastl::make_pair(inKeyCode, 1)); - else if (theIter->second < 255) - ++theIter->second; - } - MarkApplicationDirty(); -} - -//============================================================================== -/** - * Set the button status - * @param inButtonCode the identifier of the button - * @param inDown identify whether the button is down - */ -void CInputEngine::SetButtonState(INT32 inButtonCode, BOOL inDown) -{ - if (!inDown) - m_InputFrame.m_ButtonStates.erase(inButtonCode); - else { - SInputFrame::MAP_BUTTONCODE_COUNT::iterator theIter = - m_InputFrame.m_ButtonStates.find(inButtonCode); - if (theIter == m_InputFrame.m_ButtonStates.end()) - m_InputFrame.m_ButtonStates.insert(eastl::make_pair(inButtonCode, 1)); - else if (theIter->second < 255) - ++theIter->second; - } - MarkApplicationDirty(); -} - -//============================================================================== -/** - * Set the scroll value - * @param inMouseFlag flag to indicate whether this is a vertical or horizontal - *scroll - * @param inValue value of scroll performed - */ -void CInputEngine::SetScrollValue(INT32 inMouseFlag, INT16 inValue) -{ - m_InputFrame.m_MouseFlags = inMouseFlag; - m_InputFrame.m_ScrollValue = inValue; - MarkApplicationDirty(); -} -//============================================================================== -/** - * Set whether the keyboard is modified - * @param inFlag true if the keyboard status is modified - */ -void CInputEngine::SetModifierFlag(INT32 inFlag) -{ - m_InputFrame.m_KeyInputFrame.m_ModifierFlags |= inFlag; -} - -// Currently unused -//============================================================================== -/** - * Converts KeyCode in index format to ASCII format. - * This will translate upper/lower-case letters too. - * @param inKeyCode the index format keycode - * @param inShift whether the shift button is pressed - * @return the ASCII format keycode - */ -// INT32 CInputEngine::ConvertKeyCode( INT32 inKeyCode, BOOL inShift ) -//{ -// static INT32 s_ASCIILowerCase[] = -// { -// 0,//KEY_NOKEY = 0x00, -// 27,//KEY_ESCAPE, -// '1',//KEY_1, -// '2',//KEY_2, -// '3',//KEY_3, -// '4',//KEY_4, -// '5',//KEY_5, -// '6',//KEY_6, -// '7',//KEY_7, -// '8',//KEY_8, -// '9',//KEY_9, -// '0',//KEY_0, -// '-',//KEY_MINUS, /* - on main keyboard */ -// '=',//KEY_EQUALS, -// 8,//KEY_BACK, /* backspace */ -// '\t',//KEY_TAB, -// 'q',//KEY_Q, -// 'w',//KEY_W, -// 'e',//KEY_E, -// 'r',//KEY_R, -// 't',//KEY_T, -// 'y',//KEY_Y, -// 'u',//KEY_U, -// 'i',//KEY_I, -// 'o',//KEY_O, -// 'p',//KEY_P, -// '[',//KEY_LBRACKET, -// ']',//KEY_RBRACKET, -// '\n',//KEY_RETURN, /* Enter on main keyboard */ -// 0,//KEY_LCONTROL, -// 'a',//KEY_A, -// 's',//KEY_S, -// 'd',//KEY_D, -// 'f',//KEY_F, -// 'g',//KEY_G, -// 'h',//KEY_H, -// 'j',//KEY_J, -// 'k',//KEY_K, -// 'l',//KEY_L, -// ';',//KEY_SEMICOLON, -// '\'',//KEY_APOSTROPHE, -// '`',//KEY_GRAVE, /* accent grave */ -// 0,//KEY_LSHIFT, -// '\\',//KEY_BACKSLASH, -// 'z',//KEY_Z, -// 'x',//KEY_X, -// 'c',//KEY_C, -// 'v',//KEY_V, -// 'b',//KEY_B, -// 'n',//KEY_N, -// 'm',//KEY_M, -// ',',//KEY_COMMA, -// '.',//KEY_PERIOD, /* . on main keyboard */ -// '/',//KEY_SLASH, /* / on main keyboard */ -// 0,//KEY_RSHIFT, -// '*',//KEY_MULTIPLY, /* * on numeric keypad */ -// 0,//KEY_LMENU, /* left Alt */ -// ' ',//KEY_SPACE, -// 0,//KEY_CAPITAL, -// 0,//KEY_F1, -// 0,//KEY_F2, -// 0,//KEY_F3, -// 0,//KEY_F4, -// 0,//KEY_F5, -// 0,//KEY_F6, -// 0,//KEY_F7, -// 0,//KEY_F8, -// 0,//KEY_F9, -// 0,//KEY_F10, -// 0,//KEY_NUMLOCK, -// 0,//KEY_SCROLL, /* Scroll Lock */ -// '7',//KEY_NUMPAD7, -// '8',//KEY_NUMPAD8, -// '9',//KEY_NUMPAD9, -// '-',//KEY_SUBTRACT, /* - on numeric keypad */ -// '4',//KEY_NUMPAD4, -// '5',//KEY_NUMPAD5, -// '6',//KEY_NUMPAD6, -// '+',//KEY_ADD, /* + on numeric keypad */ -// '1',//KEY_NUMPAD1, -// '2',//KEY_NUMPAD2, -// '3',//KEY_NUMPAD3, -// '0',//KEY_NUMPAD0, -// '.',//KEY_DECIMAL, /* . on numeric keypad */ -// 0,//KEY_OEM_102, /* <> or \| on RT 102-key keyboard (Non-U.S.) */ -// 0,//KEY_F11, -// 0,//KEY_F12, -// 0,//KEY_F13, /* (NEC PC98) */ -// 0,//KEY_F14, /* (NEC PC98) */ -// 0,//KEY_F15, /* (NEC PC98) */ -// 0,//KEY_KANA, /* (Japanese keyboard) */ -// 0,//KEY_ABNT_C1, /* /? on Brazilian keyboard */ -// 0,//KEY_CONVERT, /* (Japanese keyboard) */ -// 0,//KEY_NOCONVERT, /* (Japanese keyboard) */ -// 0,//KEY_YEN, /* (Japanese keyboard) */ -// 0,//KEY_ABNT_C2, /* Numpad . on Brazilian keyboard */ -// 0,//KEY_NUMPADEQUALS, /* = on numeric keypad (NEC PC98) */ -// 0,//KEY_PREVTRACK, /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ -// 0,//KEY_AT, /* (NEC PC98) */ -// 0,//KEY_COLON, /* (NEC PC98) */ -// 0,//KEY_UNDERLINE, /* (NEC PC98) */ -// 0,//KEY_KANJI, /* (Japanese keyboard) */ -// 0,//KEY_STOP, /* (NEC PC98) */ -// 0,//KEY_AX, /* (Japan AX) */ -// 0,//KEY_UNLABELED, /* (J3100) */ -// 0,//KEY_NEXTTRACK, /* Next Track */ -// 0,//KEY_NUMPADENTER, /* Enter on numeric keypad */ -// 0,//KEY_RCONTROL, -// 0,//KEY_MUTE, /* Mute */ -// 0,//KEY_CALCULATOR, /* Calculator */ -// 0,//KEY_PLAYPAUSE, /* Play / Pause */ -// 0,//KEY_MEDIASTOP, /* Media Stop */ -// 0,//KEY_VOLUMEDOWN, /* Volume - */ -// 0,//KEY_VOLUMEUP, /* Volume + */ -// 0,//KEY_WEBHOME, /* Web home */ -// 0,//KEY_NUMPADCOMMA, /* , on numeric keypad (NEC PC98) */ -// 0,//KEY_DIVIDE, /* / on numeric keypad */ -// 0,//KEY_SYSRQ, -// 0,//KEY_RMENU, /* right Alt */ -// 0,//KEY_PAUSE, /* Pause */ -// 0,//KEY_HOME, /* Home on arrow keypad */ -// 0,//KEY_UP, /* UpArrow on arrow keypad */ -// 0,//KEY_PRIOR, /* PgUp on arrow keypad */ -// 0,//KEY_LEFT, /* LeftArrow on arrow keypad */ -// 0,//KEY_RIGHT, /* RightArrow on arrow keypad */ -// 0,//KEY_END, /* End on arrow keypad */ -// 0,//KEY_DOWN, /* DownArrow on arrow keypad */ -// 0,//KEY_NEXT, /* PgDn on arrow keypad */ -// 0,//KEY_INSERT, /* Insert on arrow keypad */ -// 127,//KEY_DELETE, /* Delete on arrow keypad */ -// 0,//KEY_LWIN, /* Left Windows key */ -// 0,//KEY_RWIN, /* Right Windows key */ -// 0,//KEY_APPS, /* AppMenu key */ -// 0,//KEY_POWER, /* System Power */ -// 0,//KEY_SLEEP, /* System Sleep */ -// 0,//KEY_WAKE, /* System Wake */ -// 0,//KEY_WEBSEARCH, /* Web Search */ -// 0,//KEY_WEBFAVORITES, /* Web Favorites */ -// 0,//KEY_WEBREFRESH, /* Web Refresh */ -// 0,//KEY_WEBSTOP, /* Web Stop */ -// 0,//KEY_WEBFORWARD, /* Web Forward */ -// 0,//KEY_WEBBACK, /* Web Back */ -// 0,//KEY_MYCOMPUTER, /* My Computer */ -// 0,//KEY_MAIL, /* Mail */ -// 0//KEY_MEDIASELECT, /* Media Select */ -// }; -// -// static INT32 s_ASCIIUpperCase[] = -// { -// 0,//KEY_NOKEY = 0x00, -// 27,//KEY_ESCAPE, -// '!',//KEY_1, -// '@',//KEY_2, -// '#',//KEY_3, -// '$',//KEY_4, -// '%',//KEY_5, -// '^',//KEY_6, -// '&',//KEY_7, -// '*',//KEY_8, -// '(',//KEY_9, -// ')',//KEY_0, -// '_',//KEY_MINUS, /* - on main keyboard */ -// '+',//KEY_EQUALS, -// 8,//KEY_BACK, /* backspace */ -// '\t',//KEY_TAB, -// 'Q',//KEY_Q, -// 'W',//KEY_W, -// 'E',//KEY_E, -// 'R',//KEY_R, -// 'T',//KEY_T, -// 'Y',//KEY_Y, -// 'U',//KEY_U, -// 'I',//KEY_I, -// 'O',//KEY_O, -// 'P',//KEY_P, -// '{',//KEY_LBRACKET, -// '}',//KEY_RBRACKET, -// '\n',//KEY_RETURN, /* Enter on main keyboard */ -// 0,//KEY_LCONTROL, -// 'A',//KEY_A, -// 'S',//KEY_S, -// 'D',//KEY_D, -// 'F',//KEY_F, -// 'G',//KEY_G, -// 'H',//KEY_H, -// 'J',//KEY_J, -// 'K',//KEY_K, -// 'L',//KEY_L, -// ':',//KEY_SEMICOLON, -// '\"',//KEY_APOSTROPHE, -// '~',//KEY_GRAVE, /* accent grave */ -// 0,//KEY_LSHIFT, -// '|',//KEY_BACKSLASH, -// 'Z',//KEY_Z, -// 'X',//KEY_X, -// 'C',//KEY_C, -// 'V',//KEY_V, -// 'B',//KEY_B, -// 'N',//KEY_N, -// 'M',//KEY_M, -// '<',//KEY_COMMA, -// '>',//KEY_PERIOD, /* . on main keyboard */ -// '?',//KEY_SLASH, /* / on main keyboard */ -// 0,//KEY_RSHIFT, -// '*',//KEY_MULTIPLY, /* * on numeric keypad */ -// 0,//KEY_LMENU, /* left Alt */ -// ' ',//KEY_SPACE, -// 0,//KEY_CAPITAL, -// 0,//KEY_F1, -// 0,//KEY_F2, -// 0,//KEY_F3, -// 0,//KEY_F4, -// 0,//KEY_F5, -// 0,//KEY_F6, -// 0,//KEY_F7, -// 0,//KEY_F8, -// 0,//KEY_F9, -// 0,//KEY_F10, -// 0,//KEY_NUMLOCK, -// 0,//KEY_SCROLL, /* Scroll Lock */ -// '7',//KEY_NUMPAD7, -// '8',//KEY_NUMPAD8, -// '9',//KEY_NUMPAD9, -// '-',//KEY_SUBTRACT, /* - on numeric keypad */ -// '4',//KEY_NUMPAD4, -// '5',//KEY_NUMPAD5, -// '6',//KEY_NUMPAD6, -// '+',//KEY_ADD, /* + on numeric keypad */ -// '1',//KEY_NUMPAD1, -// '2',//KEY_NUMPAD2, -// '3',//KEY_NUMPAD3, -// '0',//KEY_NUMPAD0, -// '.',//KEY_DECIMAL, /* . on numeric keypad */ -// 0,//KEY_OEM_102, /* <> or \| on RT 102-key keyboard (Non-U.S.) */ -// 0,//KEY_F11, -// 0,//KEY_F12, -// 0,//KEY_F13, /* (NEC PC98) */ -// 0,//KEY_F14, /* (NEC PC98) */ -// 0,//KEY_F15, /* (NEC PC98) */ -// 0,//KEY_KANA, /* (Japanese keyboard) */ -// 0,//KEY_ABNT_C1, /* /? on Brazilian keyboard */ -// 0,//KEY_CONVERT, /* (Japanese keyboard) */ -// 0,//KEY_NOCONVERT, /* (Japanese keyboard) */ -// 0,//KEY_YEN, /* (Japanese keyboard) */ -// 0,//KEY_ABNT_C2, /* Numpad . on Brazilian keyboard */ -// 0,//KEY_NUMPADEQUALS, /* = on numeric keypad (NEC PC98) */ -// 0,//KEY_PREVTRACK, /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ -// 0,//KEY_AT, /* (NEC PC98) */ -// 0,//KEY_COLON, /* (NEC PC98) */ -// 0,//KEY_UNDERLINE, /* (NEC PC98) */ -// 0,//KEY_KANJI, /* (Japanese keyboard) */ -// 0,//KEY_STOP, /* (NEC PC98) */ -// 0,//KEY_AX, /* (Japan AX) */ -// 0,//KEY_UNLABELED, /* (J3100) */ -// 0,//KEY_NEXTTRACK, /* Next Track */ -// 0,//KEY_NUMPADENTER, /* Enter on numeric keypad */ -// 0,//KEY_RCONTROL, -// 0,//KEY_MUTE, /* Mute */ -// 0,//KEY_CALCULATOR, /* Calculator */ -// 0,//KEY_PLAYPAUSE, /* Play / Pause */ -// 0,//KEY_MEDIASTOP, /* Media Stop */ -// 0,//KEY_VOLUMEDOWN, /* Volume - */ -// 0,//KEY_VOLUMEUP, /* Volume + */ -// 0,//KEY_WEBHOME, /* Web home */ -// 0,//KEY_NUMPADCOMMA, /* , on numeric keypad (NEC PC98) */ -// 0,//KEY_DIVIDE, /* / on numeric keypad */ -// 0,//KEY_SYSRQ, -// 0,//KEY_RMENU, /* right Alt */ -// 0,//KEY_PAUSE, /* Pause */ -// 0,//KEY_HOME, /* Home on arrow keypad */ -// 0,//KEY_UP, /* UpArrow on arrow keypad */ -// 0,//KEY_PRIOR, /* PgUp on arrow keypad */ -// 0,//KEY_LEFT, /* LeftArrow on arrow keypad */ -// 0,//KEY_RIGHT, /* RightArrow on arrow keypad */ -// 0,//KEY_END, /* End on arrow keypad */ -// 0,//KEY_DOWN, /* DownArrow on arrow keypad */ -// 0,//KEY_NEXT, /* PgDn on arrow keypad */ -// 0,//KEY_INSERT, /* Insert on arrow keypad */ -// 127,//KEY_DELETE, /* Delete on arrow keypad */ -// 0,//KEY_LWIN, /* Left Windows key */ -// 0,//KEY_RWIN, /* Right Windows key */ -// 0,//KEY_APPS, /* AppMenu key */ -// 0,//KEY_POWER, /* System Power */ -// 0,//KEY_SLEEP, /* System Sleep */ -// 0,//KEY_WAKE, /* System Wake */ -// 0,//KEY_WEBSEARCH, /* Web Search */ -// 0,//KEY_WEBFAVORITES, /* Web Favorites */ -// 0,//KEY_WEBREFRESH, /* Web Refresh */ -// 0,//KEY_WEBSTOP, /* Web Stop */ -// 0,//KEY_WEBFORWARD, /* Web Forward */ -// 0,//KEY_WEBBACK, /* Web Back */ -// 0,//KEY_MYCOMPUTER, /* My Computer */ -// 0,//KEY_MAIL, /* Mail */ -// 0//KEY_MEDIASELECT, /* Media Select */ -// }; -// -// if ( inKeyCode < 0 || inKeyCode > KEY_TOTAL_COUNT ) -// return 0; -// -// if ( inShift ) -// return s_ASCIIUpperCase[inKeyCode]; -// -// return s_ASCIILowerCase[inKeyCode]; -//} - -//============================================================================== -/** - * Clear the current input frame data, typically after the event has been processed. - */ -void CInputEngine::ClearInputFrame() -{ - // TODO: SK - To quickly restore functionality, but this is should be in tegra-specific project. - m_InputFrame.m_PickValid = false; -} - -//============================================================================== -/** - * Can be more appropriately named and perhaps moved to a COutputEngine class. - * to translate event triggered from script back to a "device" event - * e.g to simulate clicking on Home button. - * - * Base class does nothing. - */ -BOOL CInputEngine::TranslateEvent(const CHAR *inEvent) -{ - Q3DStudio_UNREFERENCED_PARAMETER(inEvent); - return false; -} - -//============================================================================== -/** - * Handle firing of keyboard events when a scancode is received. - */ -void CInputEngine::HandleKeyboard(INT32 inKeyCode, INT32 inPressed, INT32 inRepeat) -{ - if (inKeyCode >= KEY_TOTAL_COUNT || inKeyCode <= KEY_NOKEY) { - qCDebug(qt3ds::TRACE_INFO) - << "Input: Key input out of range. key code: " << inKeyCode - << " pressed: " << inPressed << " repeat: " << inRepeat; - } - if (m_Application == NULL) - return; - MarkApplicationDirty(); - - SetKeyState(inKeyCode, inPressed ? true : false); - - CPresentation *theActivePresentation(m_Application->GetPrimaryPresentation()); - if (theActivePresentation) { - TElement *theScene = theActivePresentation->GetRoot(); - UVariant theKeycode; - theKeycode.m_INT32 = inKeyCode; - - TEventCommandHash theEvent; - if (inPressed) { - UINT16 theKeyCount = m_InputFrame.m_KeyInputFrame.GetKeyCount(inKeyCode); - QT3DS_ASSERT(theKeyCount >= 1); - if (theKeyCount == 1 && inRepeat == 0) - theEvent = ON_KEYDOWN; - else - theEvent = ON_KEYREPEAT; - } else { - theEvent = ON_KEYUP; - } - - theActivePresentation->FireEvent(theEvent, theScene, &theKeycode, NULL, ATTRIBUTETYPE_INT32, - ATTRIBUTETYPE_NONE); - if (m_InputEventProvider) - m_InputEventProvider->AddEvent( - CInputEventProvider::SKeyboardEvent(theKeycode.m_INT32, theEvent)); - } -} - -//============================================================================== -/** - * Handle button events. - */ -void CInputEngine::HandleButton(INT32 inButtonCode, INT32 inPressed, INT32 inRepeat) -{ - if (inButtonCode >= BUTTON_TOTAL_COUNT || inButtonCode < 0) { - qCDebug(qt3ds::TRACE_INFO) - << "Input: Key input out of range. key code: " << inButtonCode - << " pressed: " << inPressed << " repeat: " << inRepeat; - } - if (m_Application == NULL) - return; - MarkApplicationDirty(); - - SetButtonState(inButtonCode, inPressed ? true : false); - - CPresentation *theActivePresentation(m_Application->GetPrimaryPresentation()); - if (theActivePresentation) { - TElement *theScene = theActivePresentation->GetRoot(); - UVariant theButtonCode; - theButtonCode.m_INT32 = inButtonCode; - - TEventCommandHash theEvent; - if (inPressed) { - if (inRepeat == 0) - theEvent = ON_BUTTONDOWN; - else - theEvent = ON_BUTTONREPEAT; - } else { - theEvent = ON_BUTTONUP; - } - - theActivePresentation->FireEvent(theEvent, theScene, &theButtonCode, NULL, - ATTRIBUTETYPE_INT32, ATTRIBUTETYPE_NONE); - if (m_InputEventProvider) - m_InputEventProvider->AddEvent( - CInputEventProvider::SButtonEvent(theButtonCode.m_INT32, theEvent)); - } -} - -//============================================================================== -/** - * Handle joystick events. - */ -void CInputEngine::HandleAxis(INT32 inAxisCode, FLOAT inValue) -{ - if (m_Application == NULL) - return; - MarkApplicationDirty(); - if (m_InputFrame.m_AxisStates[inAxisCode] != inValue) { - m_InputFrame.m_AxisStates[inAxisCode] = inValue; - - CPresentation *theActivePresentation(m_Application->GetPrimaryPresentation()); - if (theActivePresentation) { - TElement *theScene = theActivePresentation->GetRoot(); - UVariant theAxisCode; - theAxisCode.m_INT32 = inAxisCode; - UVariant theValue; - theValue.m_FLOAT = inValue; - - theActivePresentation->FireEvent(ON_AXISMOVED, theScene, &theAxisCode, &theValue, - ATTRIBUTETYPE_INT32, ATTRIBUTETYPE_FLOAT); - } - } -} - -void CInputEngine::MarkApplicationDirty() -{ - if (m_Application) - m_Application->MarkApplicationDirty(); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSLogicSystem.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSLogicSystem.cpp deleted file mode 100644 index 1aec08f1..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSLogicSystem.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "RuntimePrefix.h" -#include "Qt3DSLogicSystem.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSApplication.h" -#include "foundation/SerializationTypes.h" -#include "foundation/IOStreams.h" - -using namespace qt3ds::runtime; -using namespace qt3ds::foundation; -using namespace qt3ds; -using namespace qt3ds::runtime::element; - -namespace { -struct SLogicKey -{ - QT3DSU32 m_ElementHandle; - Q3DStudio::TEventCommandHash m_CommandHash; - SLogicKey(QT3DSU32 hdl = 0, Q3DStudio::TEventCommandHash hash = 0) - : m_ElementHandle(hdl) - , m_CommandHash(hash) - { - } - - bool operator==(const SLogicKey &other) const - { - return m_ElementHandle == other.m_ElementHandle && m_CommandHash == other.m_CommandHash; - } - size_t hash() const - { - return eastl::hash()(m_ElementHandle) ^ eastl::hash()((QT3DSU32)m_CommandHash); - } -}; - -struct SLogicData -{ - SLogicData *m_NextLogicData; - QT3DSU32 m_Owner; - QT3DSU32 m_Target; - Q3DStudio::TEventCommandHash m_Type; - Q3DStudio::UVariant m_Arg1; - Q3DStudio::UVariant m_Arg2; - QT3DSI32 m_Id; - bool m_Active; - - SLogicData() - : m_NextLogicData(NULL) - , m_Owner(0) - , m_Target(0) - , m_Type(0) - , m_Id(0) - , m_Active(false) - { - m_Arg1.m_INT32 = 0; - m_Arg2.m_INT32 = 0; - } - - SLogicData(QT3DSU32 owner, QT3DSU32 target, Q3DStudio::TEventCommandHash type, Q3DStudio::UVariant a1, - Q3DStudio::UVariant a2, bool active, QT3DSI32 inId) - : m_NextLogicData(NULL) - , m_Owner(owner) - , m_Target(target) - , m_Type(type) - , m_Arg1(a1) - , m_Arg2(a2) - , m_Id(inId) - , m_Active(active) - { - } -}; - -DEFINE_INVASIVE_SINGLE_LIST(LogicData); -IMPLEMENT_INVASIVE_SINGLE_LIST(LogicData, m_NextLogicData); -} - -namespace eastl { -template <> -struct hash -{ - size_t operator()(const SLogicKey &inKey) const { return inKey.hash(); } -}; -} - -namespace { - -struct SLogicSystem : public ILogicSystem -{ - typedef nvhash_map TLogicKeyHash; - typedef nvhash_map TIdLogicKeyHash; - typedef Pool TLogicDataPool; - - NVFoundationBase &m_Foundation; - - TLogicKeyHash m_LogicKeys; - TIdLogicKeyHash m_IdToLogicKeys; - TLogicDataPool m_LogicDataPool; - QT3DSI32 m_NextId; - NVDataRef m_LoadData; - - QT3DSI32 m_RefCount; - - SLogicSystem(NVFoundationBase &inFoundation) - : m_Foundation(inFoundation) - , m_LogicKeys(inFoundation.getAllocator(), "m_LogicKeys") - , m_IdToLogicKeys(inFoundation.getAllocator(), "m_IdToLogicKeys") - , m_LogicDataPool(ForwardingAllocator(inFoundation.getAllocator(), "m_LogicDataPool")) - , m_NextId(1) - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Foundation.getAllocator()); - NVDelete(alloc, this); - } - } - void IncrementNextId() - { - ++m_NextId; - if (m_NextId == 0) - ++m_NextId; - } - static QT3DSU32 GetHandle(element::SElement *elem) - { - if (elem) - return elem->GetHandle(); - return 0; - } - // returns the action id - QT3DSI32 AddAction(element::SElement &inTrigger, - Q3DStudio::TEventCommandHash inEventNameHash, - element::SElement *inTarget, element::SElement *inOwner, - Q3DStudio::TEventCommandHash inType, Q3DStudio::UVariant inArg1, - Q3DStudio::UVariant inArg2, bool inActive) override - { - SLogicKey theKey(inTrigger.GetHandle(), inEventNameHash); - eastl::pair inserter = - m_LogicKeys.insert(eastl::make_pair(theKey, TLogicDataList())); - - eastl::pair idInserter; - for (idInserter = m_IdToLogicKeys.insert(eastl::make_pair(m_NextId, theKey)); - idInserter.second == false; - idInserter = m_IdToLogicKeys.insert(eastl::make_pair(m_NextId, theKey))) { - IncrementNextId(); - } - IncrementNextId(); - - SLogicData *theData = m_LogicDataPool.construct(__FILE__, __LINE__); - *theData = SLogicData(GetHandle(inOwner), GetHandle(inTarget), inType, inArg1, inArg2, - inActive, idInserter.first->first); - inserter.first->second.push_back(*theData); - return idInserter.first->first; - } - - void OnEvent(Q3DStudio::TEventCommandHash inEventName, element::SElement &inTarget, - Q3DStudio::IPresentation &inPresentation) const override - { - SLogicKey theKey(inTarget.GetHandle(), inEventName); - TLogicKeyHash::const_iterator iter = m_LogicKeys.find(theKey); - if (iter != m_LogicKeys.end()) { - qt3ds::runtime::IApplication &theApplication = inPresentation.GetApplication(); - qt3ds::runtime::IElementAllocator &theElemAllocator = - theApplication.GetElementAllocator(); - for (TLogicDataList::const_iterator listIter = iter->second.begin(), - endIter = iter->second.end(); - listIter != endIter; ++listIter) { - if (listIter->m_Active) { - inPresentation.FireCommand( - listIter->m_Type, theElemAllocator.FindElementByHandle(listIter->m_Target), - &listIter->m_Arg1, &listIter->m_Arg2); - } - } - } - } - - void SetActive(QT3DSI32 inActionIndex, bool inActive, IElementAllocator &inElemAllocator) override - { - TIdLogicKeyHash::iterator iter = m_IdToLogicKeys.find(inActionIndex); - if (iter != m_IdToLogicKeys.end()) { - TLogicKeyHash::iterator logicIter = m_LogicKeys.find(iter->second); - if (logicIter != m_LogicKeys.end()) { - for (TLogicDataList::iterator listIter = logicIter->second.begin(), - listEnd = logicIter->second.end(); - listIter != listEnd; ++listIter) - if (listIter->m_Id == inActionIndex) { - listIter->m_Active = inActive; - if (IApplicationCore::isPickingEvent(logicIter->first.m_CommandHash)) { - SElement *theElement = inElemAllocator.FindElementByHandle( - logicIter->first.m_ElementHandle); - if (theElement && inActive) - theElement->SetFlag(Q3DStudio::ELEMENTFLAG_PICKENABLED, true); - } - } - } - } - } - - void SaveBinaryData(qt3ds::foundation::IOutStream &ioStream) override - { - qt3ds::foundation::SWriteBuffer theWriter(m_Foundation.getAllocator(), "WriteBuffer"); - theWriter.write(m_NextId); - theWriter.write((QT3DSU32)m_LogicKeys.size()); - for (TLogicKeyHash::iterator iter = m_LogicKeys.begin(), end = m_LogicKeys.end(); - iter != end; ++iter) { - if (iter->second.m_Head == NULL) - continue; - - theWriter.write(iter->first); - QT3DSU32 datumOffset = theWriter.size(); - theWriter.write((QT3DSU32)0); - QT3DSU32 datumCount = 0; - for (SLogicData *theDatum = iter->second.m_Head; theDatum; - theDatum = theDatum->m_NextLogicData, ++datumCount) { - theWriter.write(*theDatum); - } - QT3DSU32 *countPtr = reinterpret_cast(theWriter.begin() + datumOffset); - *countPtr = datumCount; - } - ioStream.Write(theWriter.begin(), theWriter.size()); - } - - void LoadBinaryData(NVDataRef inLoadData) override - { - m_LoadData = inLoadData; - SDataReader theReader(inLoadData.begin(), inLoadData.end()); - m_NextId = *theReader.Load(); - QT3DSU32 numKeys = *theReader.Load(); - for (QT3DSU32 idx = 0, end = numKeys; idx < end; ++idx) { - SLogicKey theKey = *theReader.Load(); - QT3DSU32 numActions = *theReader.Load(); - if (numActions == 0) - continue; - - TLogicKeyHash::iterator inserter = - m_LogicKeys.insert(eastl::make_pair(theKey, TLogicDataList())).first; - SLogicData *lastDatum = NULL; - for (QT3DSU32 actIdx = 0, actEnd = numActions; actIdx < actEnd; ++actIdx) { - SLogicData *nextDatum = theReader.Load(); - if (lastDatum == NULL) - inserter->second.m_Head = nextDatum; - else - lastDatum->m_NextLogicData = nextDatum; - lastDatum = nextDatum; - m_IdToLogicKeys.insert(eastl::make_pair(nextDatum->m_Id, theKey)); - } - if (lastDatum) - lastDatum->m_NextLogicData = NULL; - } - } -}; -} - -ILogicSystem &ILogicSystem::CreateLogicSystem(NVFoundationBase &inFnd) -{ - return *QT3DS_NEW(inFnd.getAllocator(), SLogicSystem)(inFnd); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSOutputMemoryStream.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSOutputMemoryStream.cpp deleted file mode 100644 index 06d0eee6..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSOutputMemoryStream.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSOutputMemoryStream.h" -#include "Qt3DSHash.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * XXX - */ -COutputMemoryStream::COutputMemoryStream() -{ -} - -//============================================================================== -/** - * XXX - */ -COutputMemoryStream::~COutputMemoryStream() -{ -} - -//============================================================================== -/** - * XXX - */ -void COutputMemoryStream::Reset() -{ - m_Data.clear(); -} - -//============================================================================== -/** - * XXX - */ -COutputMemoryStream &COutputMemoryStream::operator<<(const COutputMemoryStream &inStream) -{ - size_t theSize = inStream.m_Data.size(); - for (size_t theCount = 0; theCount < theSize; ++theCount) - m_Data.push_back(inStream.m_Data[theCount]); - return *this; -} - -//============================================================================== -/** - * XXX - */ -void COutputMemoryStream::WriteStringHash(const CHAR *inItem) -{ - TStringHash theHash = CHash::HashString(inItem); - // DEBUG - //{FILE*fp=fopen("hashed.txt","a");if(fp){fprintf(fp,"%ul %s\n",theHash,inItem);fclose(fp);}} - operator<<(theHash); -} - -//============================================================================== -/** - * XXX - */ -void COutputMemoryStream::WriteEventCommandHash(const CHAR *inItem) -{ - TStringHash theHash = CHash::HashEventCommand(inItem); - // DEBUG - //{FILE*fp=fopen("hashed.txt","a");if(fp){fprintf(fp,"%ul %s\n",theHash,inItem);fclose(fp);}} - operator<<(theHash); -} - -//============================================================================== -/** - * XXX - */ -COutputMemoryStream &COutputMemoryStream::operator<<(const std::string &inString) -{ - const UINT8 *thePtr = reinterpret_cast(inString.c_str()); - for (size_t theCounter = 0; theCounter < inString.size(); ++theCounter) { - m_Data.push_back(*thePtr); - ++thePtr; - } - - return *this; -} - -//============================================================================== -/** - * XXX - */ -COutputMemoryStream &COutputMemoryStream::operator<<(const EAttributeType inType) -{ - UINT8 theType = static_cast(inType); - m_Data.push_back(theType); - - return *this; -} - -//============================================================================== -/** - * XXX - */ -UINT32 COutputMemoryStream::GetSize() const -{ - return static_cast(m_Data.size()); -} - -//============================================================================== -/** - * XXX - */ -const UINT8 *COutputMemoryStream::GetData() const -{ - return &m_Data[0]; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSParametersSystem.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSParametersSystem.cpp deleted file mode 100644 index 84b642cd..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSParametersSystem.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" -#include "Qt3DSParametersSystem.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSIndexableLinkedList.h" -#include "foundation/Qt3DSContainers.h" -#include "foundation/SerializationTypes.h" -#include "foundation/IOStreams.h" - -using namespace qt3ds::runtime; - -namespace { - -struct SParameterGroup -{ - enum { - NumParametersPerGroup = 4, - }; - TIdValuePair m_Data[NumParametersPerGroup]; - SParameterGroup *m_NextNode; - - SParameterGroup() - : m_NextNode(NULL) - { - } -}; - -struct SParameterGroupEntry -{ - QT3DSU32 m_ParameterCount; - SParameterGroup *m_FirstGroup; - SParameterGroupEntry() - : m_ParameterCount(0) - , m_FirstGroup(NULL) - { - } -}; - -typedef IndexableLinkedList - TParametersList; - -struct SParamSystem : public IParametersSystem -{ - typedef nvhash_map TIdGroupHash; - - NVFoundationBase &m_Foundation; - TParametersList::TPoolType m_ParametersPool; - TIdGroupHash m_Groups; - QT3DSI32 m_NextId; - NVDataRef m_LoadData; - QT3DSI32 m_RefCount; - - SParamSystem(NVFoundationBase &fnd) - : m_Foundation(fnd) - , m_ParametersPool(ForwardingAllocator(fnd.getAllocator(), "ParametersPool")) - , m_Groups(fnd.getAllocator(), "m_Groups") - , m_NextId(1) - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc = m_Foundation.getAllocator(); - NVDelete(alloc, this); - } - } - - void IncrementId() - { - ++m_NextId; - if (!m_NextId) - ++m_NextId; - } - - QT3DSI32 CreateParameterGroup() override - { - eastl::pair inserter = - m_Groups.insert(eastl::make_pair(m_NextId, SParameterGroupEntry())); - while (inserter.second == false) { - IncrementId(); - inserter = m_Groups.insert(eastl::make_pair(m_NextId, SParameterGroupEntry())); - } - return inserter.first->first; - } - - void AddParameter(QT3DSI32 inGroup, QT3DSU32 inNameHash, Q3DStudio::UVariant inParam) override - { - TIdGroupHash::iterator iter = m_Groups.find(inGroup); - if (iter == m_Groups.end()) { - QT3DS_ASSERT(false); - return; - } - - SParameterGroupEntry &theEntry(iter->second); - TIdValuePair &thePair = TParametersList::Create( - theEntry.m_FirstGroup, theEntry.m_ParameterCount, m_ParametersPool); - thePair = eastl::make_pair(inNameHash, inParam); - } - - QT3DSU32 GetNumParameters(QT3DSI32 inGroup) const override - { - TIdGroupHash::const_iterator iter = m_Groups.find(inGroup); - if (iter == m_Groups.end()) { - QT3DS_ASSERT(false); - return 0; - } - - const SParameterGroupEntry &theEntry(iter->second); - return theEntry.m_ParameterCount; - } - TIdValuePair GetParameter(QT3DSI32 inGroup, QT3DSU32 inIndex) const override - { - Q3DStudio::UVariant dummyValue; - dummyValue.m_INT32 = 0; - TIdValuePair retval = TIdValuePair(0, dummyValue); - - TIdGroupHash::const_iterator iter = m_Groups.find(inGroup); - if (iter == m_Groups.end()) { - QT3DS_ASSERT(false); - return retval; - } - - const SParameterGroupEntry &theEntry(iter->second); - - if (inIndex < theEntry.m_ParameterCount) - return TParametersList::GetObjAtIdx(theEntry.m_FirstGroup, inIndex); - - QT3DS_ASSERT(false); - return retval; - } -}; -} - -IParametersSystem &IParametersSystem::CreateParametersSystem(NVFoundationBase &fnd) -{ - return *QT3DS_NEW(fnd.getAllocator(), SParamSystem)(fnd); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSPresentation.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSPresentation.cpp deleted file mode 100644 index 358b3abb..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSPresentation.cpp +++ /dev/null @@ -1,784 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSPresentation.h" -#include "Qt3DSCommandEventTypes.h" -#include "Qt3DSIScriptBridge.h" -#include "Qt3DSInputEventTypes.h" -#include "Qt3DSDataLogger.h" -#include "Qt3DSApplication.h" -#include "Qt3DSRuntimeFactory.h" -#include "Qt3DSCommandHelper.h" -#include "Qt3DSActivationManager.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSComponentManager.h" -#include "Qt3DSRenderBufferLoader.h" -#include "Qt3DSSlideSystem.h" -#include "Qt3DSLogicSystem.h" -#include "Qt3DSParametersSystem.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -/// Maximum number of Event/Command that can be queued in an Update cycle -const INT32 Q3DStudio_EVENTCOMMANDQUEUECAPACITY = 512; - -/// Limit to prevent infinite loop during queue processing -const INT32 Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT = Q3DStudio_EVENTCOMMANDQUEUECAPACITY * 10; - -#ifdef WIN32 -#pragma warning(push) -#pragma warning(disable : 4355) -#endif -//============================================================================== -/** - * Constructor - */ -CPresentation::CPresentation(const CHAR *inName, qt3ds::runtime::IApplication *inApplication) - : m_Name(inName) - , m_Application(inApplication) - , m_Scene(NULL) - , m_ActivityZone(NULL) - , m_RootElement(NULL) - , m_EventCommandQueue(Q3DStudio_EVENTCOMMANDQUEUECAPACITY, "EventCommandQueue") - , m_IsProcessingEventCommandQueue(false) - , m_ComponentManager(*this) - , m_Offset(0) - , m_LocalTime(0) - , m_PreviousGlobalTime(-1) - , m_Paused(false) - , m_OffsetInvalid(true) - , m_Active(true) -{ - m_Size.m_Width = 0; - m_Size.m_Height = 0; - m_Size.m_ScaleMode = SCALEMODE_UNKNOWN; - m_AnimationSystem = IAnimationSystem::CreateAnimationSystem( - inApplication->GetRuntimeFactoryCore().GetFoundation()); - m_SlideSystem = - ISlideSystem::CreateSlideSystem(inApplication->GetRuntimeFactoryCore().GetFoundation(), - inApplication->GetRuntimeFactoryCore().GetStringTable(), - inApplication->GetElementAllocator()); - m_LogicSystem = - ILogicSystem::CreateLogicSystem(inApplication->GetRuntimeFactoryCore().GetFoundation()); - m_ParametersSystem = IParametersSystem::CreateParametersSystem( - inApplication->GetRuntimeFactoryCore().GetFoundation()); -} -#ifdef _WIN32 -#pragma warning(pop) -#endif - -//============================================================================== -/** - * Destructor - */ -CPresentation::~CPresentation() -{ -} - -//============================================================================== -/** - * Registers an element for notification when events fired on it. - * @param inElement target element to monitor - * @param inEventHash event hash to register for - * @param inCallback static callback function - * @param inContextData arbitrary data pointer - */ -void CPresentation::RegisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) -{ - m_EventCallbacks.RegisterCallback(inElement, inEventHash, inCallback, inContextData); - inElement->SetFlag(ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK, true); - - if (qt3ds::runtime::IApplicationCore::isPickingEvent(inEventHash)) - inElement->SetFlag(ELEMENTFLAG_PICKENABLED, true); -} - -//============================================================================== -/** - * Unregisters a previously registered event callback. - * @param inElement target element to monitor - * @param inEventHash event hash to register for - * @param inCallback static callback function - * @param inContextData arbitrary data pointer - */ -BOOL CPresentation::UnregisterEventCallback(TElement *inElement, - const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) -{ - BOOL theLast = false; - BOOL theResult = m_EventCallbacks.UnregisterCallback(inElement, inEventHash, inCallback, - inContextData, theLast); - - // Unflag element if there are no longer any callbacks on it - if (theLast) - inElement->SetFlag(ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK, false); - - if (qt3ds::runtime::IApplicationCore::isPickingEvent(inEventHash)) - inElement->SetFlag(ELEMENTFLAG_PICKENABLED, false); - - return theResult; -} - -void CPresentation::ClearDirtyList() -{ - FOR_ARRAY(TElement *, theElement, GetFrameData().GetDirtyList()) - { - (*theElement)->Flags().SetDirty(false); - } - GetFrameData().Reset(); -} - -inline void ConvertActivityZoneBufferToElementList(qt3ds::runtime::TActivityItemBuffer inSource, - TElementList &outResult) -{ - for (qt3ds::QT3DSU32 idx = 0, end = inSource.size(); idx < end; ++idx) - outResult.Push(inSource[idx].first); -} - -void CPresentation::PreUpdate(const TTimeUnit inGlobalTime) -{ - if (m_OffsetInvalid || m_Paused) { - m_OffsetInvalid = false; - m_Offset = m_LocalTime - inGlobalTime; - } else - m_LocalTime = inGlobalTime + m_Offset; - - // Event/Command Processing Stage - ProcessEventCommandQueue(); -} - -//============================================================================== -/** - * Update the presentation to the current time. This will start triggering the - * various stages of the presentation frame rhythm - * @param inGlobalTime time at which to update each presentation - * @return true if there were events to be processed. - */ -void CPresentation::BeginUpdate() -{ - // Active Scan Stage - if (m_ActivityZone) { - m_ActivityZone->BeginUpdate( - m_LocalTime, m_Application->GetRuntimeFactory().GetPerfTimer(), - m_Application->GetRuntimeFactory().GetQt3DSRenderContext().GetThreadPool()); - } -} - -void CPresentation::EndUpdate() -{ - if (m_ActivityZone) { - m_ActivityZone->EndUpdate(); - CPresentationFrameData &theFrameData = GetFrameData(); - ConvertActivityZoneBufferToElementList(m_ActivityZone->GetActivatedItems(), - theFrameData.GetActivationList()); - ConvertActivityZoneBufferToElementList(m_ActivityZone->GetDeactivatedItems(), - theFrameData.GetDeactivationList()); - ConvertActivityZoneBufferToElementList(m_ActivityZone->GetScriptItems(), - theFrameData.GetScriptsList()); - } - - if (!m_Paused) { - // Animation Track Evaluation Stage - m_AnimationSystem->Update(); - } -} - -void CPresentation::PostUpdate(const TTimeUnit inGlobalTime) -{ - if (!m_Paused) { - // Callback Stage - if (m_Application && m_PreviousGlobalTime != inGlobalTime) - m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessFrameCallbacks(this); - } - - m_PreviousGlobalTime = inGlobalTime; -} - -//============================================================================== -/** - * Process the Event/Command queue completely - * PostEventCommand is the method that will add new Event/Command to the queue. - * - * The contract for Event/Command processing: - * 1. If an Event or Command is posted during the processing stage, it will be added - * to the end of the queue and is guaranteed to be processed in the current cycle. - * For example, if an Event (which is processed) triggers a Command to set a model to red, - * the model will turn red in the current frame. - * - * 2. If an Event or Command is posted after the processing stage, such as during the - * Callback stage, it will only be processed on the next Update cycle. - * For example, if the "turn mode to red" Command is posted in a script callback, the - * model will turn red in the next frame. - * - * 3. If an Event or Command is posted before the processing stage, for example an - * external Event posted just before the Update cycle, it will be processed in the current - *cycle. - * For example, if the "turn mode to red" Command is posted from the game engine prior to - * the Update cycle, the model will turn red in the current frame. - * - * @see PostEventCommand - * @return true if there were events that were processed. - */ -BOOL CPresentation::ProcessEventCommandQueue() -{ - PerfLogGeneralEvent2(DATALOGGER_PROCESSEVENTS); - - m_IsProcessingEventCommandQueue = true; - - BOOL theResult = !m_EventCommandQueue.IsEmpty(); - INT32 theEventProcessedCount = 0; - while (!m_EventCommandQueue.IsEmpty()) { - SEventCommand &theEventCommand = m_EventCommandQueue.Top(); - if (theEventCommand.m_IsEvent) - ProcessEvent(theEventCommand, theEventProcessedCount); - else - ProcessCommand(theEventCommand); - - // Infinite-loop check - if (theEventProcessedCount > Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT) { - // Breakout policy: Dump remaining Event/Commands - qCCritical(qt3ds::INVALID_OPERATION) - << "ProcessEventCommandQueue exceeded maximum loop count" - << "Remaining Event/Commands will be cleared. Event count: " - << theEventProcessedCount << "Limit: " << Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT; - m_EventCommandQueue.Clear(); - } else { - m_EventCommandQueue.Pop(); - } - } - - m_IsProcessingEventCommandQueue = false; - - return theResult; -} - -//============================================================================== -/** - * Pass incoming event to event consumers immediately - * @param ioEvent the incoming event - */ -void CPresentation::ProcessEvent(SEventCommand &ioEvent, INT32 &ioEventCount) -{ - if (ioEventCount < Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT) { - ++ioEventCount; - PerfLogPresentationEvent1(DATALOGGER_PROCESSEVENT); - - // Callbacks can change ioEvent's bubbling flags - if (ioEvent.m_Target->GetFlag(ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK)) { - m_EventCallbacks.FireCallbacks(ioEvent); - } - - // Do an early return if callback do a "stopImmediatePropagation" - if (ioEvent.m_Done) - return; - - if (ioEvent.m_Target) { - // Logic should not be able to change ioEvent's bubbling flags - // ...or can it? - m_LogicSystem->OnEvent(ioEvent.m_Type, *ioEvent.m_Target, *this); - } - - ProcessEventBubbling(ioEvent, ioEventCount); - } -} - -//============================================================================== -/** - * Handle event bubbling - * @param ioEvent the incoming event - */ -void CPresentation::ProcessEventBubbling(SEventCommand &ioEvent, INT32 &ioEventCount) -{ - PerfLogPresentationEvent1(DATALOGGER_PROCESSEVENTBUBBLING); - - // Check for onGroupedMouseOver/Out - // arg1 = the original onMouseOut model and arg2 = the original onMouseOver model - if (ioEvent.m_Type == ON_MOUSEOUT) { - // If original onMouseOver model is NULL or not a descendent, fire onGroupedMouseOut - TElement *theMouseOverModel = static_cast(ioEvent.m_Arg2.m_VoidPointer); - if (!theMouseOverModel || !ioEvent.m_Target->IsDescendent(*theMouseOverModel)) { - SEventCommand theEvent = ioEvent; - theEvent.m_Type = ON_GROUPEDMOUSEOUT; - theEvent.m_BubbleUp = 0; // no bubbling - theEvent.m_BubbleDown = 0; - FireEvent(theEvent); - } - // set the original onMouseOver model to the target to make IsDescendent queries less - // expensive - else if (theMouseOverModel) { - ioEvent.m_Arg2.m_VoidPointer = ioEvent.m_Target; - } - } else if (ioEvent.m_Type == ON_MOUSEOVER) { - // If original onMouseOut model is NULL or not a descendent, fire onGroupedMouseOver - TElement *theMouseOutModel = static_cast(ioEvent.m_Arg1.m_VoidPointer); - if (!theMouseOutModel || !ioEvent.m_Target->IsDescendent(*theMouseOutModel)) { - SEventCommand theEvent = ioEvent; - theEvent.m_Type = ON_GROUPEDMOUSEOVER; - theEvent.m_BubbleUp = 0; // no bubbling - theEvent.m_BubbleDown = 0; - FireEvent(theEvent); - } - // set the original onMouseOut model to the target to make IsDescendent queries less - // expensive - else if (theMouseOutModel) { - ioEvent.m_Arg1.m_VoidPointer = ioEvent.m_Target; - } - } - - // Do NOT bubble up onSlideEnter and onSlideExit events from current component to its parent - // scene - // since each component has its own slides. - if (ioEvent.m_BubbleUp && (ioEvent.m_Target->Flags() & ELEMENTFLAG_COMPONENT) - && (ioEvent.m_Type == EVENT_ONSLIDEENTER || ioEvent.m_Type == EVENT_ONSLIDEEXIT)) { - ioEvent.m_BubbleUp = FALSE; - } - - // Event bubbling - if (ioEvent.m_BubbleUp) { - TElement *theParent = ioEvent.m_Target->m_Parent; - if (theParent) { - ioEvent.m_Target = theParent; - ProcessEvent(ioEvent, ioEventCount); - } - } -} - -//============================================================================== -/** - * Execute command immediately - * @param inCommand incoming command structure - */ -void CPresentation::ProcessCommand(const SEventCommand &inCommand) -{ - PerfLogPresentationEvent1(DATALOGGER_PROCESSCOMMAND); - - // Attributes (Arg1 = key, Arg2 = value) - if (inCommand.m_Type == COMMAND_SETPROPERTY) { - SAttributeKey theAttributeKey; - UINT32 theHash = static_cast(inCommand.m_Arg1.m_Hash); - theAttributeKey.Convert( - theHash); // Need this conversion to prevent problems arising due to endianess - inCommand.m_Target->SetAttribute(theAttributeKey.m_Hash, inCommand.m_Arg2); - - // Events (Arg1 = hashed event name) - } else if (inCommand.m_Type == COMMAND_FIREEVENT) { - FireEvent(inCommand.m_Arg1.m_Hash, inCommand.m_Target); - - // Time (Arg1 = time) - } else if (inCommand.m_Type == COMMAND_PLAY) { - GetComponentManager().SetPause(inCommand.m_Target, false); - } else if (inCommand.m_Type == COMMAND_PAUSE) { - GetComponentManager().SetPause(inCommand.m_Target, true); - } else if (inCommand.m_Type == COMMAND_GOTOTIME) { - GetComponentManager().GoToTime(inCommand.m_Target, inCommand.m_Arg1.m_INT32); - - // Slide (Arg1 = slide index or slide name) - } else if (inCommand.m_Type == COMMAND_GOTOSLIDE) { - // Goto slide commands are handled differently. - IComponentManager &theManager(GetComponentManager()); - Q3DStudio::SComponentGotoSlideData theGotoSlideData = - theManager.GetComponentGotoSlideCommand(inCommand.m_Target); - if (theGotoSlideData.m_Slide > 0) - theManager.GotoSlideIndex(inCommand.m_Target, theGotoSlideData); - - theManager.ReleaseComponentGotoSlideCommand(inCommand.m_Target); - } else if (inCommand.m_Type == COMMAND_GOTOSLIDENAME) { - GetComponentManager().GotoSlideName(inCommand.m_Target, inCommand.m_Arg1.m_Hash); - } else if (inCommand.m_Type == COMMAND_GOTONEXTSLIDE) { - GetComponentManager().GoToNextSlide(inCommand.m_Target); - } else if (inCommand.m_Type == COMMAND_GOTOPREVIOUSSLIDE) { - GetComponentManager().GoToPreviousSlide(inCommand.m_Target); - } else if (inCommand.m_Type == COMMAND_BACKSLIDE) { - GetComponentManager().GoToBackSlide(inCommand.m_Target); - - // Behavior - } else if (inCommand.m_Type == COMMAND_CUSTOMACTION) { - m_Application->GetRuntimeFactoryCore().GetScriptEngineQml() - .ProcessCustomActions(this, inCommand); - } else if (inCommand.m_Type == COMMAND_CUSTOMCALLBACK) { - m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessCustomCallback( - this, inCommand); - } else if (inCommand.m_Type == COMMAND_PLAYSOUND) { - CRegisteredString theSoundPathReg = GetStringTable().HandleToStr(inCommand.m_Arg1.m_INT32); - if (theSoundPathReg.IsValid()) { - const char *theSoundPath = theSoundPathReg.c_str(); - if (strlen(theSoundPath) > 0) { - m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().PlaySoundFile( - theSoundPath); - } - } - } else if (inCommand.m_Type == COMMAND_EMITSIGNAL) { - m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessSignal(this, inCommand); - } else { - qCCritical(qt3ds::INVALID_OPERATION) << "Command not implemented: " << inCommand.m_Type; - } -} - -//============================================================================== -/** - * Put an Event in the queue to be processed later during the Event/Command - * processing stage in Update - * This method is used by Event-bubbling during ProcessEvent - * - * @param inEvent the incoming event - * @see PostEvent - */ -void CPresentation::FireEvent(const SEventCommand &inEvent) -{ - SEventCommand &theEventCommand = m_EventCommandQueue.NewEntry(); - - theEventCommand = inEvent; - - theEventCommand.m_IsEvent = true; -} - -//============================================================================== -/** - * Put an Event in the queue to be processed later during the Event/Command - * processing stage in Update See ProcessEventCommandQueue for more - * information on the contract for Event/Command processing. - * - * @param inEventType the incoming event type - * @param inTarget the target for the event - * @param inArg1 optional argument #1 - * @param inArg2 optional argument #2 - * @param inType1 optional type for argument #1 - * @param inType2 optional type for argument #2 - * @see ProcessEventCommandQueue - * @see PostEventCommand - */ -void CPresentation::FireEvent(const TEventCommandHash inEventType, TElement *inTarget, - const UVariant *inArg1, const UVariant *inArg2, - const EAttributeType inType1, const EAttributeType inType2) -{ - - SEventCommand theEvent = { inTarget, inEventType }; - - theEvent.m_IsEvent = true; - theEvent.m_BubbleUp = true; - - theEvent.m_Arg1Type = static_cast(inType1); - theEvent.m_Arg2Type = static_cast(inType2); - - if (inArg1) - theEvent.m_Arg1 = *inArg1; - if (inArg2) - theEvent.m_Arg2 = *inArg2; - - m_EventCommandQueue.NewEntry() = theEvent; -} - -//============================================================================== -/** - * Put a Command in the queue to be processed later during the Event/Command - * processing stage in Update. See ProcessEventCommandQueue for more information - * on the contract for Event/Command processing. - * - * For cases where the Commands need to be synchronized with the Frame-Rhythm - * An example would be calling "SetSlide" in scripts. - * - * @see ProcessEventCommandQueue - * @see PostEventCommand - * @param inEventType the incoming command type - * @param inTarget the target for the command - * @param inArg1 optional argument #1 - * @param inArg2 optional argument #2 - * @param inType1 optional type for argument #1 - * @param inType2 optional type for argument #2 - */ -void CPresentation::FireCommand(const TEventCommandHash inEventType, TElement *inTarget, - const UVariant *inArg1, const UVariant *inArg2, - const EAttributeType inType1, const EAttributeType inType2) -{ - // Pre-filter gotoslidename commands. - if (inEventType == COMMAND_GOTOSLIDENAME) { - int theSlideHashName = inArg1->m_INT32; - TComponent *theComponent = GetComponentManager().GetComponent(inTarget); - UINT8 theSlideIndex = GetSlideSystem().FindSlide(*theComponent, theSlideHashName); - // Translate into a slide index command. - CCommandHelper::SetupGotoSlideCommand(*inTarget, theSlideIndex, - SScriptEngineGotoSlideArgs()); - } else { - SEventCommand theCommand = { inTarget, inEventType }; - - theCommand.m_Arg1Type = static_cast(inType1); - theCommand.m_Arg2Type = static_cast(inType2); - - if (inArg1) - theCommand.m_Arg1 = *inArg1; - if (inArg2) - theCommand.m_Arg2 = *inArg2; - - m_EventCommandQueue.NewEntry() = theCommand; - } -} - -void CPresentation::FlushEventCommandQueue(void) -{ - if (!m_IsProcessingEventCommandQueue) - ProcessEventCommandQueue(); -} - -void CPresentation::ProcessEvent(SEventCommand &inEvent) -{ - INT32 theEventProcessedCount = 0; - ProcessEvent(inEvent, theEventProcessedCount); -} -//============================================================================== -/** - * This method is triggered after the presentation is streamed in. At this point, - * all the stores will be loaded up. - */ -void CPresentation::OnPresentationLoaded() -{ - m_FrameData.Reserve(1000 /*m_ElementManager.GetElementCount( )*/); -} - -//============================================================================== -/** - * Set the full path for this presentation. This can be used by anyone who - * knows the presentation to form relative paths. - * @param inPath the path to which to set. - */ -void CPresentation::SetFilePath(const CHAR *inPath) -{ - m_FilePath = inPath; -} - -//============================================================================== -/** - * Gets the full file path for this presentation. This can be used by anyone who - * knows the presentation to form relative correct paths. - */ -QString CPresentation::GetFilePath() -{ - return m_FilePath; -} - -//============================================================================== -/** - * Gets the pause state - * @return true if the presentation is paused, false if otherwise - */ -BOOL CPresentation::GetPause() const -{ - return m_Paused; -} - -//============================================================================== -/** - * Sets the pause state - * @param inPause set true to pause, set false if otherwise - */ -void CPresentation::SetPause(const BOOL inPause) -{ - m_Paused = inPause ? true : false; -} - -//============================================================================== -/** - * Simple manager access: Scene - */ -void CPresentation::SetScene(IScene *inScene) -{ - m_Scene = inScene; -} - -void CPresentation::SetActivityZone(qt3ds::runtime::IActivityZone *inZone) -{ - m_ActivityZone = inZone; - m_ActivityZone->SetZoneActive(m_Active); - TElement *theSceneElement = m_RootElement; - qt3ds::runtime::IActivityZone &theZone(*GetActivityZone()); - // The activity zone requires elements described to it in breadth first search order. - theZone.AddActivityItems(*theSceneElement); -} - -void CPresentation::SetActive(bool inValue) -{ - m_Active = inValue; - m_ActivityZone->SetZoneActive(m_Active); -} - -bool CPresentation::GetActive() const -{ - return m_Active; -} - -//============================================================================== -/** - * Simple manager access: Scene - */ -IScene *CPresentation::GetScene() const -{ - return m_Scene; -} - -//============================================================================== -/** -* Simple manager access: Script Bridge Qml -*/ -IScriptBridge *CPresentation::GetScriptBridgeQml() -{ - if (m_Application) - return &m_Application->GetRuntimeFactoryCore().GetScriptEngineQml(); - - return NULL; -} - -//============================================================================== -/** - * Simple manager access: Component Manager - */ -IComponentManager &CPresentation::GetComponentManager() -{ - return m_ComponentManager; -} - -//============================================================================== -/** - * Simple manager access: Slide Manager - */ -ISlideSystem &CPresentation::GetSlideSystem() -{ - return *m_SlideSystem; -} - -//============================================================================== -/** - * Simple manager access: Animation Manager - */ -qt3ds::runtime::IAnimationSystem &CPresentation::GetAnimationSystem() -{ - return *m_AnimationSystem; -} - -//============================================================================== -/** - * Simple manager access: Logic Manager - */ -ILogicSystem &CPresentation::GetLogicSystem() -{ - return *m_LogicSystem; -} - -//============================================================================== -/** - * Simple manager access: Params Manager - */ -IParametersSystem &CPresentation::GetParametersSystem() -{ - return *m_ParametersSystem; -} - -void CPresentation::SetElementPath(TElement &inElement, const char8_t *inPath) -{ - CRegisteredString str; - if (m_Application) - str = m_Application->GetRuntimeFactoryCore().GetStringTable().RegisterStr( - qt3ds::foundation::nonNull(inPath)); - - if (str.IsValid()) - m_ElementPathMap.insert(eastl::make_pair(&inElement, str)); -} - -qt3ds::foundation::CRegisteredString CPresentation::GetElementPath(TElement &inElement) -{ - TElemStringMap::iterator iter = m_ElementPathMap.find(&inElement); - if (iter != m_ElementPathMap.end()) - return iter->second; - - return qt3ds::foundation::CRegisteredString(); -} - -qt3ds::foundation::IStringTable &CPresentation::GetStringTable() -{ - return GetApplication().GetRuntimeFactoryCore().GetStringTable(); -} - -//============================================================================== -/** - * Current frame data stores traversal lists for use later - */ -CPresentationFrameData &CPresentation::GetFrameData() -{ - return m_FrameData; -} - -void CPresentation::SetLoadedBuffer(qt3ds::render::ILoadedBuffer &inBuffer) -{ - m_LoadedBuffer = inBuffer; -} - -//============================================================================== -/** - * Retrieve the name of the presentation. This is actually the file path. - * @return the name of this presentation - */ -const QByteArray CPresentation::GetName() const -{ - return m_Name.toLatin1(); -} - -//============================================================================== -/** - * Retrieve the size of the presentation in Studio - * @return the size of this presentation - */ -SPresentationSize CPresentation::GetSize() const -{ - return m_Size; -} - -//============================================================================== -/** - * Set the size of the presentation as reflected in Studio - * @param inSize size of presentation ( width, height, scale mode ) in Studio - */ -void CPresentation::SetSize(const SPresentationSize &inSize) -{ - m_Size = inSize; -} - -QPresentationSignalProxy *CPresentation::signalProxy() -{ - return &m_SignalProxy; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSPresentationFrameData.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSPresentationFrameData.cpp deleted file mode 100644 index 649462aa..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSPresentationFrameData.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSPresentationFrameData.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -const FLOAT DIRTY_STORE_RATIO = 0.1f; -const FLOAT TRAVERSAL_STORE_RATIO = 0.5f; -const FLOAT ACTIVATION_STORE_RATIO = 0.3f; -const FLOAT DEACTIVATION_STORE_RATIO = 0.3f; - -//============================================================================== -/** - * Constructor - */ -CPresentationFrameData::CPresentationFrameData() - : m_DirtyList(0, 0, "Frame:DirtyList") - , m_TraversalList(0, 0, "Frame:TraversalList") - , m_ScriptsList(0, 0, "Frame:ScriptsList") - , m_ActivationList(0, 0, "Frame:ActivationList") - , m_DeactivationList(0, 0, "Frame:DeactivationList") /*,*/ -// m_SlideExitList( 0, 0, "Frame:SlideExitList" ), -// m_SlideEnterList( 0, 0, "Frame:SlideEnterList" ) -{ -} - -//============================================================================== -/** - * Reserve memory from the memory subsytem to store the various arrays. - * @param inElementCount the number of elements loaded - */ -void CPresentationFrameData::Reserve(const INT32 /*inElementCount*/) -{ -} - -//============================================================================== -/** - * Clean up the data. This is usually called at the start of the frame rhythm to - * clean up the data from previous frame - * Memory allocation should be clear by default. - * Previous list could be a lot longer than current or future list which means - * the appliation is using more memory than needed. The heuristics of both - * initialization and runtime freeing is dependent on the presentation. - */ -void CPresentationFrameData::Reset() -{ - // Keep the capacity of these lists every frame since they have consistent - // sizes from frame to frame - m_TraversalList.Clear(false); - m_ScriptsList.Clear(false); - - // These lists are more sporatic (slide changes) for now, clear them as - // above but potential memory saving could occur by calling Clear( true ) instead - m_ActivationList.Clear(false); - m_DeactivationList.Clear(false); - - // NOTE: When we clear the dirty list, we also must ensure that the elements - // themselves are un-dirtied to prepare for the next frame. This is done - // by the caller of "CPresentationFrameData::Reset" - m_DirtyList.Clear(false); - - // m_SlideExitList.Clear( false ); - // m_SlideEnterList.Clear( false ); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSQmlElementHelper.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSQmlElementHelper.cpp deleted file mode 100644 index f5f42396..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSQmlElementHelper.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSQmlElementHelper.h" -#include "Qt3DSCommandEventTypes.h" -#include "Qt3DSHash.h" -#include "Qt3DSAttributeHashes.h" -#include "Qt3DSElementSystem.h" -#include "Qt3DSRuntimeFactory.h" -#include "qmath.h" - -using namespace Q3DStudio; -using namespace qt3ds; - -//============================================================================== -// Constants -//============================================================================== -const char PRESENTATION_DELIMITER = ':'; -const char NODE_DELIMITER = '.'; -const TStringHash RESERVED_THIS = CHash::HashString("this"); -const TStringHash RESERVED_PARENT = CHash::HashString("parent"); -const TStringHash RESERVED_SCENE = CHash::HashString("Scene"); - -//============================================================================== -/** -* Constructor -*/ -CQmlElementHelper::CQmlElementHelper() -{ -} - -//============================================================================== -/** -* Destructor -*/ -CQmlElementHelper::~CQmlElementHelper() -{ -} - -TElement *CQmlElementHelper::GetElement(qt3ds::runtime::IApplication &inApplication, - IPresentation *inDefaultPresentation, const char *inPath, - TElement *inStartElement) -{ - if (inPath == nullptr || *inPath == 0) - return nullptr; - const char *thePath(inPath); - const char *theSubPath = nullptr; - IPresentation *thePresentation = nullptr; - size_t thePathLength = ::strlen(thePath) + 1; - char *theToken = - Q3DStudio_allocate_desc(CHAR, thePathLength, "Token:TempPath"); // Temporary token storage - // Try to get the specified presentation - theSubPath = ::strchr(thePath, PRESENTATION_DELIMITER); - TElement *theElement = inStartElement; - if (theSubPath != nullptr) { - UINT32 theSubPathLength = static_cast(theSubPath - thePath); - - ::strncpy(theToken, thePath, theSubPathLength); - theToken[theSubPathLength] = '\0'; - - thePath = theSubPath + 1; - - const CHAR *thePresentationName = theToken; - - thePresentation = inApplication.GetPresentationById(thePresentationName); - } - if (thePresentation == nullptr) - thePresentation = inDefaultPresentation; - - // Return nil if the inStartElement is not in the specified presentation - if (theElement != nullptr - && (theSubPath == nullptr && theElement->GetBelongedPresentation() != thePresentation)) { - thePresentation = theElement->GetBelongedPresentation(); - } - - if (thePresentation == nullptr) - return nullptr; - - TStringHash theName; - INT32 theParseCounter = 0; - - while (thePath != nullptr && thePath[0] != '\0') { - ++theParseCounter; - - // Do some strtok() work here - theSubPath = ::strchr(thePath, NODE_DELIMITER); - if (theSubPath) { - UINT32 theSubPathLength = static_cast(theSubPath - thePath); - Q3DStudio_ASSERT(theSubPathLength < thePathLength); - - ::strncpy(theToken, thePath, theSubPathLength); - theToken[theSubPathLength] = '\0'; - - thePath = theSubPath + 1; - } else { - ::strcpy(theToken, thePath); - thePath = nullptr; - } - - // Hash the token and do some element searching - theName = CHash::HashString(theToken); - - if (theName == RESERVED_PARENT) { - if (theElement) - theElement = theElement->GetParent(); - } else if (theName == RESERVED_THIS) { - //Keep the original element if "this" wanted - } else { - if (theName == RESERVED_SCENE && theParseCounter == 1) - theElement = - thePresentation->GetRoot(); // theElement is nullptr, so using absolute path - - else if (theElement) - theElement = theElement->FindChild(theName); // Using relative path - } - - if (!theElement) - thePath = nullptr; - } // while - - Q3DStudio_free(theToken, CHAR, thePathLength); - return theElement; -} - -bool CQmlElementHelper::SetAttribute(TElement *theElement, const char *theAttName, - const void *value, bool inDelay) -{ - SAttributeKey theAttributeKey; - theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); - - // Early out for our single 'read only' attribute - if (ATTRIBUTE_URI == theAttributeKey.m_Hash) { - // we didn't push anything onto the stack - return false; - } - - // first search if it is a static property - Option thePropertyInfo = - theElement->FindProperty(theAttributeKey.m_Hash); - - if (!thePropertyInfo.hasValue()) { - // if not search in the dynamic properties - thePropertyInfo = theElement->FindDynamicProperty(theAttributeKey.m_Hash); - if (!thePropertyInfo.hasValue()) { - // create a new dynamic porperty - qt3ds::runtime::IElementAllocator &theElemAllocator( - theElement->GetBelongedPresentation()->GetApplication().GetElementAllocator()); - qt3ds::foundation::IStringTable &theStringTable( - theElement->GetBelongedPresentation()->GetStringTable()); - IRuntimeMetaData &theMetaData = - theElement->GetBelongedPresentation()->GetApplication().GetMetaData(); - thePropertyInfo = theElemAllocator.CreateDynamicProperty( - theMetaData, *theElement, theStringTable.RegisterStr(theAttName)); - } - } - - if (thePropertyInfo.hasValue()) { - UVariant theNewValue; - QString name(thePropertyInfo->first.m_Name.c_str()); - EAttributeType theAttributeType = thePropertyInfo->first.m_Type; - switch (theAttributeType) { - case ATTRIBUTETYPE_INT32: - case ATTRIBUTETYPE_HASH: - theNewValue.m_INT32 = *(INT32 *)value; - break; - - case ATTRIBUTETYPE_FLOAT: - theNewValue.m_FLOAT = *(FLOAT *)value; - if (name.startsWith(QLatin1String("rotation."))) - theNewValue.m_FLOAT = qDegreesToRadians(theNewValue.m_FLOAT); - break; - - case ATTRIBUTETYPE_BOOL: - theNewValue.m_INT32 = *(INT32 *)value; - break; - - case ATTRIBUTETYPE_STRING: - theNewValue.m_StringHandle = - theElement->GetBelongedPresentation()->GetStringTable().GetHandle( - (const char *)value); - break; - - case ATTRIBUTETYPE_POINTER: - qCCritical(INVALID_OPERATION, "setAttribute: pointer attributes not handled."); - return false; - break; - - case ATTRIBUTETYPE_ELEMENTREF: - qCCritical(INVALID_OPERATION, "setAttribute: ElementRef attributes are read only."); - return false; - break; - - case ATTRIBUTETYPE_FLOAT3: { - FLOAT *vec3 = (FLOAT *)value; - theNewValue.m_FLOAT3[0] = vec3[0]; - theNewValue.m_FLOAT3[1] = vec3[1]; - theNewValue.m_FLOAT3[2] = vec3[2]; - if (name == QLatin1String("rotation")) { - theNewValue.m_FLOAT3[0]= qDegreesToRadians(theNewValue.m_FLOAT3[0]); - theNewValue.m_FLOAT3[1]= qDegreesToRadians(theNewValue.m_FLOAT3[1]); - theNewValue.m_FLOAT3[2]= qDegreesToRadians(theNewValue.m_FLOAT3[2]); - } - } break; - - case ATTRIBUTETYPE_NONE: - case ATTRIBUTETYPE_DATADRIVEN_PARENT: - case ATTRIBUTETYPE_DATADRIVEN_CHILD: - case ATTRIBUTETYPECOUNT: - default: - qCCritical(INVALID_OPERATION, "setAttribute: Attribute has no type!"); - return false; - break; - } - - if (inDelay) { - UVariant arg1; - arg1.m_INT32 = theAttributeKey.m_Hash; - theElement->GetBelongedPresentation()->FireCommand( - COMMAND_SETPROPERTY, theElement, &arg1, &theNewValue, ATTRIBUTETYPE_HASH, - theAttributeType); - } else { - theElement->SetAttribute(*thePropertyInfo, theNewValue); - } - } else { - return false; - } - return true; -} - -bool CQmlElementHelper::GetAttribute(TElement *inElement, const char *inAttribute, void *value) -{ - SAttributeKey theAttributeKey; - theAttributeKey.m_Hash = CHash::HashAttribute(inAttribute); - - Option thePropertyInfo = - inElement->FindDynamicProperty(theAttributeKey.m_Hash); - - if (thePropertyInfo.hasValue()) { - UVariant *theValuePtr = thePropertyInfo->second; - EAttributeType theAttributeType = thePropertyInfo->first.m_Type; - switch (theAttributeType) { - case ATTRIBUTETYPE_INT32: - case ATTRIBUTETYPE_HASH: - *(INT32 *)value = theValuePtr->m_INT32; - break; - - case ATTRIBUTETYPE_FLOAT: - *(FLOAT *)value = theValuePtr->m_FLOAT; - break; - - case ATTRIBUTETYPE_BOOL: - *(INT32 *)value = (theValuePtr->m_INT32 != 0); - break; - - case ATTRIBUTETYPE_STRING: - *(char *)value = *inElement->GetBelongedPresentation() - ->GetStringTable() - .HandleToStr(theValuePtr->m_StringHandle) - .c_str(); - break; - - case ATTRIBUTETYPE_POINTER: - qCCritical(INVALID_OPERATION, "getAttribute: pointer attributes not handled."); - return false; - break; - - case ATTRIBUTETYPE_ELEMENTREF: - qCCritical(INVALID_OPERATION, "getAttribute: ElementRef attributes are read only."); - return false; - break; - - case ATTRIBUTETYPE_FLOAT3: { - FLOAT *vec3 = (FLOAT *)value; - vec3[0] = theValuePtr->m_FLOAT3[0]; - vec3[1] = theValuePtr->m_FLOAT3[1]; - vec3[2] = theValuePtr->m_FLOAT3[2]; - } break; - - case ATTRIBUTETYPE_NONE: - case ATTRIBUTETYPE_DATADRIVEN_PARENT: - case ATTRIBUTETYPE_DATADRIVEN_CHILD: - case ATTRIBUTETYPECOUNT: - default: - qCCritical(INVALID_OPERATION, "getAttribute: Attribute has no type!"); - return false; - break; - } - } else { - return false; - } - return true; -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSQmlEngine.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSQmlEngine.cpp deleted file mode 100644 index 1ba1a5a6..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSQmlEngine.cpp +++ /dev/null @@ -1,1346 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSQmlEngine.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSInputEngine.h" -#include "Qt3DSSceneManager.h" -#include "Qt3DSVector3.h" -#include "Qt3DSColor.h" -#include "Qt3DSAttributeHashes.h" -#include "Qt3DSFileStream.h" -#include "Qt3DSDataLogger.h" -#include "render/Qt3DSRenderBaseTypes.h" -#include "foundation/FileTools.h" -#include "foundation/Qt3DSSystem.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSStateDebugger.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSSlideSystem.h" - -#include "EASTL/vector.h" -#include "EASTL/list.h" -#include -#include "Qt3DSCommandEventTypes.h" -#include "Qt3DSApplication.h" -#include "Qt3DSRuntimeFactory.h" -#include "Qt3DSStateDebugStreams.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "Qt3DSRenderThreadPool.h" -#include "Qt3DSRenderImageBatchLoader.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSAudioPlayer.h" -#include "Qt3DSActivationManager.h" -#include "Qt3DSParametersSystem.h" -#include "Qt3DSQmlElementHelper.h" -#include "q3dsqmlscript.h" - -#include -#include -#include -#include -#include -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -#if defined(_DEBUG) || (_PROFILE) -#define Q3DStudio_LOG_EVENT(S) // something -#else -#define Q3DStudio_LOG_EVENT(S) -#endif - -using qt3ds::runtime::IApplicationCore; -using qt3ds::runtime::IApplication; -using namespace qt3ds; - -namespace __SQmlEngineImpl_Basic_Structs__ { - struct QmlScopedLock - { - qt3ds::foundation::Mutex *m_Mutex; - - QmlScopedLock(qt3ds::foundation::Mutex *mtx) - : m_Mutex(mtx) - { - if (m_Mutex) - m_Mutex->lock(); - } - - ~QmlScopedLock() - { - if (m_Mutex) - m_Mutex->unlock(); - } - }; -} - -using namespace __SQmlEngineImpl_Basic_Structs__; -#define QML_ENGINE_MULTITHREAD_PROTECT_METHOD QmlScopedLock __locker(m_MultithreadedMutex); - -//============================================================================== -// Callback handling -/** -* Constructor -*/ -CScriptCallbacks::CScriptCallbacks() - : m_CallbackList(0, 0, "CallbackList") -{ -} - -/** -* Destructor -*/ -CScriptCallbacks::~CScriptCallbacks() -{ - FOR_ARRAY(SFrameCallbackEntry *, theEntry, m_CallbackList) - Q3DStudio_delete(*theEntry, SFrameCallbackEntry); - - m_CallbackList.Clear(); -} - -bool CScriptCallbacks::RegisterCallback(Q3DStudio::UINT32 callbackType, - const TScriptCallback inCallback, void *inUserData) -{ - // currently we only support these two types of callbacks - if (callbackType != SCRIPT_ON_INITIALIZE && callbackType != SCRIPT_ON_UPDATE) { - return false; - } - - SFrameCallbackEntry *theFrameCallbackEntry = NULL; - - try { - // note we don't care if someone registers the same function twice. - theFrameCallbackEntry = Q3DStudio_new(SFrameCallbackEntry) SFrameCallbackEntry(); - - if (!theFrameCallbackEntry) { - throw "failed to allocated SFrameCallbackEntry"; - } - - SScriptCallbackEntry *theScriptCallbackEntry = - Q3DStudio_new(SScriptCallbackEntry) SScriptCallbackEntry(); - if (!theScriptCallbackEntry) { - throw "failed to allocated SScriptCallbackEntry"; - } - - theScriptCallbackEntry->m_CallbackType = callbackType; - theScriptCallbackEntry->m_Function = inCallback; - theScriptCallbackEntry->m_UserData = inUserData; - theScriptCallbackEntry->m_Processed = false; - - theFrameCallbackEntry->m_Callbacks.Push(theScriptCallbackEntry); - - m_CallbackList.Push(theFrameCallbackEntry); - - } catch (const char *) { - if (theFrameCallbackEntry) - Q3DStudio_delete(theFrameCallbackEntry, SFrameCallbackEntry); - - return false; - } - - return true; -} - -void CScriptCallbacks::UnregisterCallback(Q3DStudio::UINT32, const TScriptCallback) -{ - // not used so far -} - -void CScriptCallbacks::ProcessCallbacks() -{ - // Call onInitialize function - FOR_ARRAY(SFrameCallbackEntry *, theFrameEntry, m_CallbackList) - { - FOR_ARRAY(SScriptCallbackEntry *, theEntry, (*theFrameEntry)->m_Callbacks) - { - if (((*theEntry)->m_CallbackType == SCRIPT_ON_INITIALIZE) && !(*theEntry)->m_Processed - && (*theEntry)->m_Function) { - (*theEntry)->m_Function((*theEntry)->m_UserData); - (*theEntry)->m_Processed = true; - } - } - } - - // Call onUpdate functions - FOR_ARRAY(SFrameCallbackEntry *, theFrameEntry, m_CallbackList) - { - FOR_ARRAY(SScriptCallbackEntry *, theEntry, (*theFrameEntry)->m_Callbacks) - { - // int type = (*theEntry)->m_CallbackType; - if ((*theEntry)->m_CallbackType == SCRIPT_ON_UPDATE && (*theEntry)->m_Function) { - (*theEntry)->m_Function((*theEntry)->m_UserData); - } - } - } -} - -//============================================================================== -//* End of helper class handling element operations -//============================================================================== - -//============================================================================== -/** -* Helper class handling command operations -*/ -class CQmlCommandHelper -{ - //============================================================================== - // Methods - //============================================================================== -private: // Constructors - CQmlCommandHelper(); - virtual ~CQmlCommandHelper(); - -public: // static Functions - static bool SetupGotoSlideCommand(TElement &inElement, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs); - static bool SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlideIndex, - const SScriptEngineGotoSlideArgs &inArgs); - -protected: // Static Hidden Helpers - // static TElement* FireCommand(TEventCommandHash inCommand); - -public: // Static Helpers - static TElement *GetComponentParent(TElement *inParent); -}; - -//============================================================================== -/** -* Constructor -*/ -CQmlCommandHelper::CQmlCommandHelper() -{ -} - -//============================================================================== -/** -* Destructor -*/ -CQmlCommandHelper::~CQmlCommandHelper() -{ -} - -static Option FindSlide(TElement &inElement, const char *slideName) -{ - IPresentation *thePresentation = inElement.GetBelongedPresentation(); - - int theSlideHashName = thePresentation->GetApplication().HashString(slideName); - TComponent *theComponent = thePresentation->GetComponentManager().GetComponent(&inElement); - UINT8 theSlideIndex = - thePresentation->GetSlideSystem().FindSlide(*theComponent, theSlideHashName); - if (theSlideIndex >= theComponent->GetSlideCount()) { - qt3ds::foundation::CRegisteredString elemPath = thePresentation->GetElementPath(inElement); - if (elemPath.IsValid()) { - qCCritical(qt3ds::INVALID_OPERATION) - << "QMLCommandHelper: goToSlide: Unable to find slide " - << slideName <<"on element " << elemPath.c_str(); - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "QMLCommandHelper: goToSlide: Unable to find slide " - << slideName; - } - return Empty(); - } - - return theSlideIndex; -} - -TElement *CQmlCommandHelper::GetComponentParent(TElement *inElement) -{ - Q3DStudio_ASSERT(inElement); - return &inElement->GetComponentParent(); -} - -bool CQmlCommandHelper::SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlideIndex, - const SScriptEngineGotoSlideArgs &inArgs) -{ - IPresentation *thePresentation = inElement.GetBelongedPresentation(); - TElement *theTarget = GetComponentParent(&inElement); - SComponentGotoSlideData theSlideData(inSlideIndex); - theSlideData.m_Mode = inArgs.m_Mode; - theSlideData.m_Paused = inArgs.m_Paused; - theSlideData.m_Rate = inArgs.m_Rate; - theSlideData.m_Reverse = inArgs.m_Reverse; - theSlideData.m_StartTime = inArgs.m_StartTime; - // Resolve playthroughto if it has a valid value. - if (!isTrivial(inArgs.m_PlaythroughTo)) { - if (AreEqual(inArgs.m_PlaythroughTo, "next")) - theSlideData.m_PlaythroughTo = -1; - else if (AreEqual(inArgs.m_PlaythroughTo, "previous")) - theSlideData.m_PlaythroughTo = -2; - else { - // Find the slide if possible. If not, then just error leave things as they are. - - Option theSlideIndex = FindSlide(inElement, inArgs.m_PlaythroughTo); - if (theSlideIndex.hasValue()) - theSlideData.m_PlaythroughTo = *theSlideIndex; - } - } - thePresentation->GetComponentManager().SetupComponentGotoSlideCommand(theTarget, theSlideData); - UVariant theArg1; - UVariant theArg2; - qt3ds::intrinsics::memZero(&theArg1, sizeof(UVariant)); - qt3ds::intrinsics::memZero(&theArg2, sizeof(UVariant)); - thePresentation->FireCommand(COMMAND_GOTOSLIDE, theTarget, &theArg1, &theArg2); - return true; -} - -bool CQmlCommandHelper::SetupGotoSlideCommand(TElement &inElement, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs) -{ - Option theSlideIndex = FindSlide(inElement, slideName); - if (theSlideIndex.hasValue()) - return SetupGotoSlideCommand(inElement, *theSlideIndex, inArgs); - - return false; -} - -//============================================================================== -//* End of helper class handling command operations -//============================================================================== - -struct SEmitSignalData : public NVRefCounted -{ - NVAllocatorCallback &m_Alloc; - volatile QT3DSI32 mRefCount; - INT32 m_SignalNameHandler; ///< The name of the signal to emit - TElement *m_TargetElement; ///< The source element where the event is going to occur - - SEmitSignalData(NVAllocatorCallback &alloc, INT32 inSignalName, TElement *inElement) - : m_Alloc(alloc) - , mRefCount(0) - , m_SignalNameHandler(inSignalName) - , m_TargetElement(inElement) - { - } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc) -}; - -class CQmlEngineImpl : public CQmlEngine -{ - typedef NVScopedRefCounted TEmitSignalPtr; - typedef eastl::list TEmitSignalQueue; - - static const int MAX_ACTION_QUEUE_SIZE = 100; - -private: - qt3ds::NVFoundationBase &m_Foundation; - IApplication *m_Application; - IApplicationCore *m_ApplicationCore; - qt3ds::foundation::Mutex m_PreloadMutex; - qt3ds::foundation::Mutex *m_MultithreadedMutex; - - TEmitSignalQueue m_EmitSignalDataList; - - QT3DSI32 mRefCount; - - CScriptCallbacks m_ScriptCallbacks; - - QQmlEngine m_engine; - QMap m_components; - QVector m_scripts; - -public: - CQmlEngineImpl(NVFoundationBase &fnd, ITimeProvider &inTimeProvider); - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) - - // functions from IScriptBridge - void EnableMultithreadedAccess() override; - void DisableMultithreadedAccess() override; - - void SetApplicationCore(qt3ds::runtime::IApplicationCore &inApplication) override; - void SetApplication(qt3ds::runtime::IApplication &inApplication) override; - qt3ds::runtime::IApplication *GetApplication() override; - void Initialize() override; - - void LoadScript(IPresentation *presentation, TElement *element, const CHAR *path) override; - Q3DStudio::INT32 InitializeApplicationBehavior(const char *) override - { - return -1; - } - - void ProcessFrameCallbacks(IPresentation *) override; - void ExecuteApplicationScriptFunction(Q3DStudio::INT32, const char *) override {} - void CallFunction(const char *, const char *, - CScriptEngineCallFunctionArgRetriever &) override {} - - void ProcessSignal(IPresentation *inPresentation, - const SEventCommand &inCommand) override; - void ProcessCustomActions(IPresentation *inPresentation, - const SEventCommand &inCommand) override; - void ProcessCustomCallback(IPresentation *, const SEventCommand &) override {} - - void SetTableForElement(TElement &, IScriptTableProvider &) override {} - void SetAttribute(const char *element, const char *attName, const char *value) override; - bool GetAttribute(const char *element, const char *attName, char *value) override; - void FireEvent(const char *element, const char *evtName) override; - void SetDataInputValue(const QString &name, const QVariant &value) override; - - void GotoSlide(const char *component, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs) override; - void GotoSlideRelative(const char *, bool, bool, const SScriptEngineGotoSlideArgs &) override; - - void SetPresentationAttribute(const char *, const char *, const char *) override; - - // No need to implement here, as sound playing is done in Qt3DSViewerApp - bool PlaySoundFile(const char *) override { return false; } - - void EnableDebugging(qt3ds::state::debugger::IMultiProtocolSocket &) override {} - void EnableProfiling() override {} - void StepGC() override {} - - // functions from CQMLEngine - bool PeekSignal(TElement *&outElement, char *&outName) override; - void GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex, - const SScriptEngineGotoSlideArgs &inArgs) override; - bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) override; - void GotoTime(const char *component, const Q3DStudio::FLOAT time) override; - bool RegisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback, - void *inUserData) override; - void Shutdown(qt3ds::NVFoundationBase &inFoundation) override; - -private: - void createComponent(QQmlComponent *component, TElement *element); - TElement *getTarget(const char *component); - void listAllElements(TElement *root, QList &elements); - void initializeDataInputsInPresentation(CPresentation &presentation, bool isPrimary); - // Splits down vector attributes to components as Runtime does not really - // handle vectors at this level anymore - bool getAttributeVector3(QVector &outAttVec, const QByteArray &attName, - TElement *elem); - bool getAttributeVector2(QVector &outAttVec, const QByteArray &attName, - TElement *elem); - // build and evaluate Evaluator datainput type expression - QJSValue buildJSFunc(const QString &userFunc); - // pass controller name for error reporting purposes - QVariant callJSFunc(const QString &controllerName, qt3ds::runtime::DataInputDef &diDef, - const QVariant::Type type); - // matches all numeric datatypes so we do not get datatype mismatch when JS - // decides to change result datatype (f.ex from double to int when result - // fractional part for specific input values happens to be exactly zero) - bool isMatchingDatatype(QVariant::Type resultType, QVariant::Type propertyType); - // find out which datainputs are used in the expression - QVector resolveDependentDatainputs(const QString &expression, - const QString &controllerName); -}; - -CQmlEngineImpl::CQmlEngineImpl(NVFoundationBase &fnd, ITimeProvider &) - : m_Foundation(fnd) - , m_Application(NULL) - , m_ApplicationCore(NULL) - , m_PreloadMutex(fnd.getAllocator()) - , m_MultithreadedMutex(NULL) - , m_EmitSignalDataList( - ForwardingAllocator(fnd.getAllocator(), "CQmlEngineImpl::m_EmitSignalDataList")) - , mRefCount(0) -{ - qmlRegisterType("QtStudio3D.Behavior", 1, 0, "Behavior"); - qmlRegisterType("QtStudio3D.Behavior", 1, 1, "Behavior"); -} - -void CQmlEngineImpl::Shutdown(qt3ds::NVFoundationBase &inFoundation) -{ -} - -void CQmlEngineImpl::EnableMultithreadedAccess() -{ - m_MultithreadedMutex = &m_PreloadMutex; -} - -void CQmlEngineImpl::DisableMultithreadedAccess() -{ - m_MultithreadedMutex = NULL; -} - -void CQmlEngineImpl::SetApplicationCore(qt3ds::runtime::IApplicationCore &inApplication) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - m_ApplicationCore = &inApplication; -} - -void CQmlEngineImpl::SetApplication(qt3ds::runtime::IApplication &inApplication) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - m_Application = &inApplication; -} - -qt3ds::runtime::IApplication *CQmlEngineImpl::GetApplication() -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - return m_Application; -} - -void CQmlEngineImpl::Initialize() -{ - // Gather data input controlled properties - QList presentations = m_Application->GetPresentationList(); - - for (int i = 0; i < presentations.size(); ++i) - initializeDataInputsInPresentation(*presentations[i], i == 0); -} - -void CQmlEngineImpl::SetAttribute(const char *element, const char *attName, const char *value) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - - TElement *theTarget = getTarget(element); - if (theTarget) { - bool success = CQmlElementHelper::SetAttribute(theTarget, attName, value, false); - if (!success) { - qCCritical(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::SetAttribute: " - << "failed to set attribute on element" - << element << ":" << attName << ":" << value; - } - } -} - -bool CQmlEngineImpl::GetAttribute(const char *element, const char *attName, char *value) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - - TElement *theTarget = getTarget(element); - if (theTarget) { - bool success = CQmlElementHelper::GetAttribute(theTarget, attName, value); - if (!success) { - qCCritical(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::SetAttribute: " - << "failed to set attribute on element" - << element << ":" << attName << ":" << value; - } - return success; - } - - return false; -} - -void CQmlEngineImpl::LoadScript(IPresentation *presentation, TElement *element, const CHAR *path) -{ - QString presPath = QFileInfo(presentation->GetFilePath()).absolutePath(); - - QString sourcePath(presPath + QLatin1Char('/') + path); - sourcePath.replace(QLatin1Char('\\'), QLatin1Char('/')); - - TElement *parent = element->GetParent(); - if (!parent) - return; - - if (!m_components.contains(sourcePath)) { - m_components[sourcePath] = new QQmlComponent(&m_engine, QUrl::fromLocalFile(sourcePath), - &m_engine); - } - - QQmlComponent *component = m_components[sourcePath]; - if (component->status() == QQmlComponent::Ready) { - createComponent(component, element); - } else if (component->status() == QQmlComponent::Error) { - qWarning() << "Error while loading script" - << component->url().toString() - << ":" << component->errorString(); - } else { - QObject::connect(component, &QQmlComponent::statusChanged, - [this, component, element] (QQmlComponent::Status status) { - if (status == QQmlComponent::Ready) { - createComponent(component, element); - } else { - qWarning() << "Error while loading script" - << component->url().toString() - << ":" << component->errorString(); - } - } - ); - } -} - -void CQmlEngineImpl::FireEvent(const char *element, const char *evtName) -{ - TElement *theElement = getTarget(element); - if (theElement && theElement->GetActive() == true) { - IPresentation *thePresentation = theElement->GetBelongedPresentation(); - thePresentation->FireEvent(CHash::HashEventCommand(evtName), theElement); - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::FireEvent: " - << "failed to find element: " - << element << " " << evtName; - } -} - -void CQmlEngineImpl::SetDataInputValue(const QString &name, const QVariant &value) -{ - qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); - if (diMap.contains(name)) { - qt3ds::runtime::DataInputDef &diDef = diMap[name]; - diDef.value = value; - const QVector &ctrlAtt - = diDef.controlledAttributes; - for (const qt3ds::runtime::DataInputControlledAttribute &ctrlElem : ctrlAtt) { - switch (ctrlElem.propertyType) { - case ATTRIBUTETYPE_DATAINPUT_TIMELINE: { - // Quietly ignore other than number type data inputs when adjusting timeline - if (diDef.type == qt3ds::runtime::DataInputTypeRangedNumber) { - TTimeUnit endTime = 0; - TElement *element = getTarget(ctrlElem.elementPath.constData()); - TComponent *component = static_cast(element); - endTime = component->GetTimePolicy().GetLoopingDuration(); - - // Normalize the value to dataInput range - qreal newTime = qreal(endTime) * (qreal(value.toFloat() - diDef.min) - / qreal(diDef.max - diDef.min)); - GotoTime(ctrlElem.elementPath.constData(), float(newTime / 1000.0)); - } - break; - } - case ATTRIBUTETYPE_DATAINPUT_SLIDE: { - // Quietly ignore other than string type when adjusting slide - if (diDef.type == qt3ds::runtime::DataInputTypeString) { - const QByteArray valueStr = value.toString().toUtf8(); - GotoSlide(ctrlElem.elementPath.constData(), valueStr.constData(), - SScriptEngineGotoSlideArgs()); - } - break; - } - // Silently ignore invalid incoming type if it does not - // match with the datainput type except with type Variant, for which - // the incoming value is cast to target property type without checking. - // Caveat emptor. - - // For Evaluator, typecheck the JS evaluation result to see if it - // matches with the target property. - - // Handle ranged number similarly to generic float - // if it is bound to properties other - // than timeline animation i.e. disregard range min and max - - case ATTRIBUTETYPE_FLOAT: { - float valueFloat; - if (diDef.type == qt3ds::runtime::DataInputTypeFloat - || diDef.type == qt3ds::runtime::DataInputTypeRangedNumber - || diDef.type == qt3ds::runtime::DataInputTypeVariant) { - valueFloat = value.toFloat(); - } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { - valueFloat = callJSFunc(name, diDef, QVariant::Type::Double).toFloat(); - } else { - qWarning() << __FUNCTION__ << "Property type " - << ctrlElem.propertyType - << " not matching with Datainput " << name - << " data type " - << diDef.type; - break; - } - - SetAttribute(ctrlElem.elementPath.constData(), - ctrlElem.attributeName.first().constData(), - reinterpret_cast(&valueFloat)); - break; - } - case ATTRIBUTETYPE_FLOAT3: { - QVector3D valueVec; - if (diDef.type == qt3ds::runtime::DataInputTypeVector3 - || diDef.type == qt3ds::runtime::DataInputTypeVariant) { - valueVec = value.value(); - } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { - const QVariant res = callJSFunc(name, diDef, QVariant::Type::Vector3D); - valueVec = res.value(); - } else { - qWarning() << __FUNCTION__ << "Property type " - << ctrlElem.propertyType - << " not matching with Datainput " << name - << " data type " - << diDef.type; - break; - } - // Set the values of vector attribute components separately - for (int i = 0; i < 3; i++) { - const float val = valueVec[i]; - SetAttribute(ctrlElem.elementPath.constData(), - ctrlElem.attributeName[i].constData(), - reinterpret_cast(&val)); - } - break; - } - case ATTRIBUTETYPE_FLOAT2: - { - QVector2D valueVec; - if (diDef.type == qt3ds::runtime::DataInputTypeVector2 - || diDef.type == qt3ds::runtime::DataInputTypeVariant) { - valueVec = value.value(); - } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { - const QVariant res = callJSFunc(name, diDef, QVariant::Type::Vector2D); - valueVec = res.value(); - } else { - qWarning() << __FUNCTION__ << "Property type " - << ctrlElem.propertyType - << " not matching with Datainput " << name - << " data type " - << diDef.type; - break; - } - // Set the values of vector attribute components separately - for (int i = 0; i < 2; i++) { - const float val = valueVec[i]; - SetAttribute(ctrlElem.elementPath.constData(), - ctrlElem.attributeName[i].constData(), - reinterpret_cast(&val)); - } - break; - } - case ATTRIBUTETYPE_BOOL: { - bool valueBool; - if (diDef.type == qt3ds::runtime::DataInputTypeBoolean - || diDef.type == qt3ds::runtime::DataInputTypeVariant) { - valueBool = value.toBool(); - } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { - valueBool = callJSFunc(name, diDef, QVariant::Type::Bool).toBool(); - } else { - qWarning() << __FUNCTION__ << "Property type " - << ctrlElem.propertyType - << " not matching with Datainput " << name - << " data type " - << diDef.type; - break; - } - - SetAttribute(ctrlElem.elementPath.constData(), - ctrlElem.attributeName.first().constData(), - reinterpret_cast(&valueBool)); - break; - } - case ATTRIBUTETYPE_STRING: { - QByteArray valueStr; - // Allow scalar number types also as inputs to string attribute - if (diDef.type == qt3ds::runtime::DataInputTypeString - || diDef.type == qt3ds::runtime::DataInputTypeRangedNumber - || diDef.type == qt3ds::runtime::DataInputTypeFloat - || diDef.type == qt3ds::runtime::DataInputTypeVariant) { - valueStr = value.toString().toUtf8(); - } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { - valueStr = callJSFunc(name, diDef, QVariant::Type::String) - .toString().toUtf8(); - } else { - qWarning() << __FUNCTION__ << "Property type " - << ctrlElem.propertyType - << " not matching with Datainput " << name - << " data type " - << diDef.type; - break; - } - - SetAttribute(ctrlElem.elementPath.constData(), - ctrlElem.attributeName.first().constData(), - valueStr.constData()); - break; - } - default: - QT3DS_ALWAYS_ASSERT_MESSAGE("Unexpected data input type"); - break; - } - } - - // Trigger re-evaluation of Evaluator datainputs that use this datainput - // as source data. Do this by calling setDataInputValue for evaluator - // with the current set value of the Evaluator (_not_ the evaluator result) - for (auto dependent : diDef.dependents) { - // Dependent list also contains the name of this datainput if - // the value of this datainput is used as source data. In this case - // obviously do not cause infinite recursion. - if (dependent != name) - SetDataInputValue(dependent, diMap[dependent].value); - } - } -} - -void CQmlEngineImpl::GotoSlide(const char *component, const char *slideName, - const SScriptEngineGotoSlideArgs &inArgs) -{ - TElement *theTarget = getTarget(component); - if (theTarget) { - CQmlCommandHelper::SetupGotoSlideCommand(*theTarget, slideName, inArgs); - } else { - qCWarning(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::GotoSlide: Unable to find component " << component; - } -} - -void CQmlEngineImpl::GotoSlideRelative(const char *component, bool inNextSlide, bool inWrap, - const SScriptEngineGotoSlideArgs &inArgs) -{ - TElement *theTarget = getTarget(component); - if (theTarget) { - theTarget = &theTarget->GetComponentParent(); - if (theTarget && theTarget->GetActive()) { - TComponent *theComponent = static_cast(theTarget); - Q3DStudio::INT32 theSlide = theComponent->GetCurrentSlide(); - Q3DStudio::INT32 theSlideCount = theComponent->GetSlideCount(); - theSlide = inNextSlide ? theSlide + 1 : theSlide - 1; - if (theSlide < 1) { - if (inWrap) - theSlide = theSlideCount - 1; - else - theSlide = 1; - } else if (theSlide == theSlideCount) { - if (inWrap) - theSlide = 1; - else - theSlide = theSlideCount - 1; - } - if (theSlide != theComponent->GetCurrentSlide()) { - CQmlCommandHelper::SetupGotoSlideCommand(*theTarget, theSlide, inArgs); - } - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "QmlEngine::GotoSlideRelative: Component is not active: " << component; - } - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "QmlEngine::GotoSlideRelative: failed to find component: " << component; - } -} - -void CQmlEngineImpl::SetPresentationAttribute(const char *presId, const char *, const char *value) -{ - if (isTrivial(presId)) - return; - if (presId[0] == '#') - ++presId; - CPresentation *thePresentation = m_Application->GetPresentationById(presId); - if (thePresentation) { - bool active = AreEqualCaseless(nonNull(value), "True"); - thePresentation->SetActive(active); - } -} - -void CQmlEngineImpl::GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex, - const SScriptEngineGotoSlideArgs &inArgs) -{ - TElement *theTarget = getTarget(component); - if (theTarget) { - CQmlCommandHelper::SetupGotoSlideCommand(*theTarget, slideIndex, inArgs); - } else { - qCWarning(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::GotoSlide: Unable to find component " << component; - } -} - -bool CQmlEngineImpl::GetSlideInfo(const char *element, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - - TElement *theTarget = getTarget(element); - if (theTarget && theTarget->IsComponent()) { - IPresentation *thePresentation = theTarget->GetBelongedPresentation(); - TComponent *theComponent = thePresentation->GetComponentManager().GetComponent(theTarget); - currentIndex = int(theComponent->GetCurrentSlide()); - previousIndex = int(theComponent->GetPreviousSlide()); - if (currentIndex > 0) { - currentName = QString::fromLocal8Bit( - thePresentation->GetSlideSystem().GetSlideName( - qt3ds::runtime::SSlideKey(*theComponent, QT3DSU32(currentIndex)))); - } else { - currentName.clear(); - } - if (previousIndex > 0) { - previousName = QString::fromLocal8Bit( - thePresentation->GetSlideSystem().GetSlideName( - qt3ds::runtime::SSlideKey(*theComponent, QT3DSU32(previousIndex)))); - } else { - previousName.clear(); - } - return true; - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::GetSlideInfo: Supplied element is not a component " << element; - } - return false; -} - -void CQmlEngineImpl::GotoTime(const char *component, const Q3DStudio::FLOAT time) -{ - TElement *theTarget = getTarget(component); - if (theTarget && theTarget->GetActive()) { - UVariant theArg1; - UVariant theArg2; - - IPresentation *thePresentation = theTarget->GetBelongedPresentation(); - - theArg1.m_INT32 = static_cast(time * 1000); - - TElement *theParentTarget = &theTarget->GetComponentParent(); - - thePresentation->FireCommand(COMMAND_GOTOTIME, theParentTarget, &theArg1, &theArg2); - } -} - -bool CQmlEngineImpl::RegisterCallback(Q3DStudio::UINT32 callbackType, - const TScriptCallback inCallback, void *inUserData) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - return m_ScriptCallbacks.RegisterCallback(callbackType, inCallback, inUserData); -} - -void CQmlEngineImpl::ProcessFrameCallbacks(IPresentation *) -{ - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - m_ScriptCallbacks.ProcessCallbacks(); - - for (Q3DSQmlScript *script : m_scripts) - script->update(); -} - -void CQmlEngineImpl::ProcessSignal(IPresentation *inPresentation, - const SEventCommand &inCommand) -{ - using qt3ds::runtime::TIdValuePair; - QML_ENGINE_MULTITHREAD_PROTECT_METHOD; - TElement *theElement = inCommand.m_Target; // the element that is a behavior - - CPresentation *thePresentation = (CPresentation *)inPresentation; - // IParametersSystem& theParametersManager = thePresentation->GetParametersSystem(); - qt3ds::foundation::IStringTable &theStrTable(thePresentation->GetStringTable()); - - CRegisteredString theSignal = theStrTable.HandleToStr(inCommand.m_Arg1.m_INT32); - - if (!theSignal.IsValid() || m_EmitSignalDataList.size() > CQmlEngineImpl::MAX_ACTION_QUEUE_SIZE) - return; - - TEmitSignalPtr theTemp = QT3DS_NEW(m_Foundation.getAllocator(), SEmitSignalData)( - m_Foundation.getAllocator(), inCommand.m_Arg1.m_INT32, theElement); - m_EmitSignalDataList.push_back(theTemp); -} - - -//============================================================================== -/** -* Handle custom actions -* @param inCommand carrier of command and parameter information -*/ -void CQmlEngineImpl::ProcessCustomActions(IPresentation *presentation, - const SEventCommand &command) -{ - TElement *element = command.m_Target; - for (Q3DSQmlScript *script : m_scripts) { - if (script->hasBehavior(element)) { - IParametersSystem ¶metersManager - = static_cast(presentation)->GetParametersSystem(); - INT32 groupId = command.m_Arg1.m_INT32; - UINT32 numParams = parametersManager.GetNumParameters(groupId); - if (numParams == 0) { - QT3DS_ASSERT(false); - return; - } - - qt3ds::runtime::TIdValuePair tempData = parametersManager.GetParameter(groupId, 0); - if (tempData.first != CHash::HashString("string")) { - QT3DS_ASSERT(false); - return; - } - - CRegisteredString functionName = presentation->GetStringTable().HandleToStr( - tempData.second.m_StringHandle); - script->call(functionName.c_str()); - return; - } - } -} - -bool CQmlEngineImpl::PeekSignal(TElement *&outElement, char *&outName) -{ - if (m_EmitSignalDataList.empty()) - return false; - - NVScopedRefCounted theAction = m_EmitSignalDataList.front(); - m_EmitSignalDataList.pop_front(); - - outElement = theAction->m_TargetElement; - if (outElement) { - IPresentation *thePresentation = outElement->GetBelongedPresentation(); - qt3ds::foundation::IStringTable &theStrTable(thePresentation->GetStringTable()); - CRegisteredString theSignal = theStrTable.HandleToStr(theAction->m_SignalNameHandler); - outName = (char *)theSignal.c_str(); - } else { - qCWarning(qt3ds::INVALID_OPERATION) - << "CQmlEngineImpl::PeekCustomAction: Unable to find element: EmitSignal queue error"; - outName = NULL; - } - - return true; -} - -void CQmlEngineImpl::createComponent(QQmlComponent *component, TElement *element) -{ - TElement *parent = element->GetParent(); - if (!parent) - return; - - QQmlContext *context = new QQmlContext(&m_engine, &m_engine); - QObject *obj = component->beginCreate(context); - if (!obj) { - context->deleteLater(); - return; - } - Q3DSQmlBehavior *behaviorObject = qobject_cast(obj); - if (behaviorObject == nullptr) { - obj->deleteLater(); - context->deleteLater(); - return; - } - - auto script = new Q3DSQmlScript(*this, *behaviorObject, *element, *parent); - component->completeCreate(); - behaviorObject->setScript(script); - - script->setParent(component); - obj->setParent(script); - m_scripts.push_back(script); -} - -TElement *CQmlEngineImpl::getTarget(const char *component) { - TElement *target = NULL; - QStringList split = QString(component).split(":"); - if (split.size() > 1) { - target = CQmlElementHelper::GetElement( - *m_Application, - m_Application->GetPresentationById(split.at(0).toStdString().c_str()), - split.at(1).toStdString().c_str(), NULL); - } else { - target = CQmlElementHelper::GetElement( - *m_Application, - m_Application->GetPrimaryPresentation(), - split.at(0).toStdString().c_str(), NULL); - } - return target; -} - -void CQmlEngineImpl::listAllElements(TElement *root, QList &elements) -{ - elements.append(root); - TElement *nextChild = root->GetChild(); - while (nextChild) { - listAllElements(nextChild, elements); - nextChild = nextChild->GetSibling(); - } -} - -void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentation, - bool isPrimary) -{ - TElement *parent = presentation.GetRoot(); - QList elements; - listAllElements(parent, elements); - qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); - qt3ds::foundation::IStringTable &strTable(presentation.GetStringTable()); - - for (TElement *element : qAsConst(elements)) { - Option ctrlIndex = element->FindPropertyIndex(ATTRIBUTE_CONTROLLEDPROPERTY); - if (ctrlIndex.hasValue()) { - Option propertyInfo = - element->GetPropertyByIndex(*ctrlIndex); - UVariant *valuePtr = propertyInfo->second; - QString valueStr = - QString::fromUtf8(strTable.HandleToStr(valuePtr->m_StringHandle)); - if (!valueStr.isEmpty()) { - QStringList splitValues = valueStr.split(QChar(' ')); - for (int i = 1; i < splitValues.size(); i += 2) { - QString controllerName = splitValues[i - 1]; - // remove datainput name prefix "$" - controllerName.remove(0, 1); - if (diMap.contains(controllerName)) { - qt3ds::runtime::DataInputControlledAttribute ctrlElem; - if (!isPrimary) { - // Prepend presentation id to element path - ctrlElem.elementPath = presentation.GetName(); - ctrlElem.elementPath.append(QByteArrayLiteral(":")); - } - ctrlElem.attributeName.append(splitValues[i].toUtf8()); - if (ctrlElem.attributeName.first() == QByteArrayLiteral("@timeline")) { - ctrlElem.propertyType = ATTRIBUTETYPE_DATAINPUT_TIMELINE; - TElement *component = &element->GetComponentParent(); - ctrlElem.elementPath.append(component->m_Path); - } else if (ctrlElem.attributeName.first() == QByteArrayLiteral("@slide")) { - ctrlElem.propertyType = ATTRIBUTETYPE_DATAINPUT_SLIDE; - TElement *component = &element->GetComponentParent(); - ctrlElem.elementPath.append(component->m_Path); - } else if (diMap[controllerName].type - == qt3ds::runtime::DataInputTypeVector3) { - // special handling for vector datatype to handle - // expansion from to .x .y .z - QVector attVec; - bool success = getAttributeVector3( - attVec, ctrlElem.attributeName.first().constData(), - element); - if (!attVec.empty() && success) { - ctrlElem.attributeName = attVec; - ctrlElem.elementPath.append(element->m_Path); - ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT3; - } else { - qWarning() << __FUNCTION__ << "Property " - << ctrlElem.attributeName.first() - << " was not expanded to vector"; - ctrlElem.propertyType = ATTRIBUTETYPE_NONE; - } - } else if (diMap[controllerName].type - == qt3ds::runtime::DataInputTypeVector2) { - // special handling for vector datatype to handle - // expansion from to .x .y - QVector attVec; - bool success = getAttributeVector2( - attVec, ctrlElem.attributeName.first().constData(), - element); - if (!attVec.empty() && success) { - ctrlElem.attributeName = attVec; - ctrlElem.elementPath.append(element->m_Path); - ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT2; - } else { - qWarning() << __FUNCTION__ << "Property " - << ctrlElem.attributeName.first() - << " was not expanded to vector"; - ctrlElem.propertyType = ATTRIBUTETYPE_NONE; - } - } else if (diMap[controllerName].type - == qt3ds::runtime::DataInputTypeEvaluator) { - diMap[controllerName].evalFunc - = buildJSFunc(diMap[controllerName].evaluator); - auto referencedDIs = resolveDependentDatainputs( - diMap[controllerName].evaluator, controllerName); - // add this evaluator datainput to the dependent list - // for those datainputs that are used in the expression - // for this evaluator - for (auto ref : referencedDIs) - diMap[ref].dependents.append(controllerName); - - ctrlElem.elementPath.append(element->m_Path); - TStringHash attHash = CHash::HashAttribute( - ctrlElem.attributeName.first().constData()); - Option attInfo - = element->FindProperty(attHash); - if (attInfo.hasValue()) - ctrlElem.propertyType = attInfo->first.m_Type; - } else { - // all other scalar datatypes - ctrlElem.elementPath.append(element->m_Path); - TStringHash attHash = CHash::HashAttribute( - ctrlElem.attributeName.first().constData()); - Option attInfo - = element->FindProperty(attHash); - if (attInfo.hasValue()) { - ctrlElem.propertyType = attInfo->first.m_Type; - } else { - ctrlElem.propertyType = ATTRIBUTETYPE_NONE; - qWarning() << __FUNCTION__ << "Property " - << ctrlElem.attributeName.first() << " not existing!"; - } - } - qt3ds::runtime::DataInputDef &diDef = diMap[controllerName]; - diDef.controlledAttributes.append(ctrlElem); - } - } - } - } - } -} - -// Bit clumsy way of getting from "position" to "position .x .y .z" and enabling datainput -// support for vectorized types. UIP parser has already thrown away all vector -// type attributes and at this point we are operating with scalar components only. -// We check if this element has a property attName.x or attName.r to find out it -// we should expand property attName to XYZ or RGB vector -bool CQmlEngineImpl::getAttributeVector3(QVector &outAttVec, - const QByteArray &attName, - TElement *elem) -{ - auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); - - if (!elem->FindProperty(hashName).isEmpty()) { - outAttVec.append(attName + ".x"); - outAttVec.append(attName + ".y"); - outAttVec.append(attName + ".z"); - return true; - } - hashName = Q3DStudio::CHash::HashAttribute(attName + ".r"); - if (!elem->FindProperty(hashName).isEmpty()) { - outAttVec.append(attName + ".r"); - outAttVec.append(attName + ".g"); - outAttVec.append(attName + ".b"); - return true; - } - return false; -} - -bool CQmlEngineImpl::getAttributeVector2(QVector &outAttVec, - const QByteArray &attName, - TElement *elem) -{ - auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); - - if (!elem->FindProperty(hashName).isEmpty()) { - outAttVec.append(attName + ".x"); - outAttVec.append(attName + ".y"); - return true; - } - - hashName = Q3DStudio::CHash::HashAttribute(attName + ".u"); - if (!elem->FindProperty(hashName).isEmpty()) { - outAttVec.append(attName + ".u"); - outAttVec.append(attName + ".v"); - return true; - } - return false; -} - -QJSValue CQmlEngineImpl::buildJSFunc(const QString &userFunc) -{ - auto res = this->m_engine.evaluate(userFunc); - if (res.isError()) { - qWarning() << __FUNCTION__ - << "Uncaught exception during datainput evaluation. Evaluator function" << userFunc; - } - return res; -} - -QVariant CQmlEngineImpl::callJSFunc(const QString &controllerName, - qt3ds::runtime::DataInputDef &diDef, - const QVariant::Type type) -{ - qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); - QJSValueList args; - QVector sourceDIs = resolveDependentDatainputs(diDef.evaluator, controllerName); - - // get the most recent set values for datainput sources (arguments) in the expression - for (auto diVal : sourceDIs) - args << this->m_engine.toScriptValue(diMap[diVal].value); - - if (diDef.evalFunc.isCallable()) { - QJSValue res = diDef.evalFunc.call(args); - if (res.isError()) { - qWarning() << __FUNCTION__ << "Error during datainput" << controllerName - << "evaluator call:" << res.toString() << "\nEvaluator function" - << diDef.evaluator; - return QVariant::Invalid; - } - - QVariant ret = res.toVariant(); - if (ret.isValid() && isMatchingDatatype(ret.type(), type)) { - // further check if the result is valid number - if (ret.type() == QVariant::Double && qIsNaN(res.toNumber())) { - qWarning() << __FUNCTION__ << "Datainput" << controllerName << "evaluator" - << "result not a number (NaN)." - << "\nEvaluator function" << diDef.evaluator; - return QVariant::Invalid; - } else { - return ret; - } - } else { - qWarning() << __FUNCTION__ << "Datainput" << controllerName << "evaluator" - << "result not valid or matching with target attribute type. Result type" - << QVariant::typeToName(ret.type()) << " target attribute type " - << QVariant::typeToName(type) << "\nEvaluator function" << diDef.evaluator; - } - } else { - qWarning() << __FUNCTION__ << "Datainput" << controllerName << "evaluator" - << diDef.evaluator << " not valid callable"; - } - return QVariant::Invalid; -} - -bool CQmlEngineImpl::isMatchingDatatype(QVariant::Type resultType, QVariant::Type propertyType) -{ - if (resultType == propertyType) - return true; - // Allow binding from numeric datainput to string target - if ((resultType == QVariant::Double || resultType == QVariant::Int - || resultType == QVariant::LongLong) - && (propertyType == QVariant::Double || propertyType == QVariant::Int - || propertyType == QVariant::LongLong || propertyType == QVariant::String)) { - return true; - } - return false; -} - -QVector CQmlEngineImpl::resolveDependentDatainputs(const QString &expression, - const QString &controllerName) -{ - QVector ret; - qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); - if (!expression.contains("function", Qt::CaseInsensitive)) { - qWarning() << __FUNCTION__ << "Function keyword not found in datainput" - << controllerName << "evaluator"; - return QVector(); - } - - int argListStart = expression.indexOf("function(") + 9; - int argListStop = expression.indexOf(')', argListStart); - QString argstr = expression.mid(argListStart , argListStop - argListStart); - QStringList args = argstr.split(','); - - for (auto di : args) { - auto diTrim = di.trimmed(); - if (diMap.contains(diTrim)) { - if (diMap[diTrim].type == qt3ds::runtime::DataInputTypeEvaluator - && diTrim != controllerName) { - qWarning() << __FUNCTION__ << "Invalid evaluator function in" << controllerName - << ". Another evaluator is used as source data."; - } else { - ret.append(diTrim); - } - } else { - qWarning() << __FUNCTION__ << "Evaluator in" << controllerName << "evaluator" - << "is using unknown datainput" << diTrim << " as input argument name"; - } - } - return ret; -} - -/** -* @brief Create QML engine -* -* @param[in] inFoundation Pointer to foundation -* @param[in] inTimeProvider Pointer to time provider -* -* @return no return -*/ -CQmlEngine *CQmlEngine::Create(qt3ds::NVFoundationBase &inFoundation, ITimeProvider &inTimeProvider) -{ - return QT3DS_NEW(inFoundation.getAllocator(), CQmlEngineImpl)(inFoundation, inTimeProvider); -} -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSSlideSystem.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSSlideSystem.cpp deleted file mode 100644 index e7cc0983..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSSlideSystem.cpp +++ /dev/null @@ -1,541 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "RuntimePrefix.h" -#include "Qt3DSSlideSystem.h" -#include "foundation/Qt3DSInvasiveLinkedList.h" -#include "foundation/Qt3DSPool.h" -#include "foundation/Qt3DSAtomic.h" -#include "foundation/Qt3DSFoundation.h" -#include "foundation/Qt3DSBroadcastingAllocator.h" -#include "Qt3DSAnimationSystem.h" -#include "Qt3DSLogicSystem.h" -#include "foundation/SerializationTypes.h" -#include "foundation/IOStreams.h" -#include "Qt3DSHash.h" -#include "Qt3DSTimePolicy.h" -#include "foundation/Qt3DSIndexableLinkedList.h" - -using namespace qt3ds::runtime; -using namespace qt3ds::runtime::element; - -namespace { -struct SSlideAttribute -{ - QT3DSU32 m_Index; - Q3DStudio::UVariant m_Value; - SSlideAttribute() - : m_Index(0) - { - m_Value.m_INT32 = 0; - } - SSlideAttribute(QT3DSU32 idx, Q3DStudio::UVariant val) - : m_Index(idx) - , m_Value(val) - { - } -}; - -struct SSlideAttributeNode -{ - enum { - AttributeCount = 8, - }; - - SSlideAttribute m_Data[AttributeCount]; - SSlideAttributeNode *m_NextNode; - - SSlideAttributeNode() - : m_NextNode(NULL) - { - } -}; - -typedef IndexableLinkedList - TSlideAttributeNodeList; - -struct SSlideElement -{ - QT3DSU32 m_ElementHandle; - QT3DSU32 m_AttributeCount : 31; - QT3DSU32 m_Active : 1; - SSlideElement *m_NextElement; - SSlideAttributeNode *m_AttributeNodes; - - SSlideElement() - : m_ElementHandle(0) - , m_AttributeCount(0) - , m_Active(false) - , m_NextElement(NULL) - , m_AttributeNodes(NULL) - { - } -}; - -struct SSlideAnimActionNode -{ - enum { - AnimActionCount = 8, - }; - SSlideAnimAction m_Data[AnimActionCount]; - SSlideAnimActionNode *m_NextNode; - SSlideAnimActionNode() - : m_NextNode(NULL) - { - } -}; - -typedef IndexableLinkedList - TSlideAnimActionNodeList; - -struct SSlide -{ - SSlide *m_NextSlide; - CRegisteredString m_Name; - QT3DSU32 m_PlayMode : 3; - QT3DSU32 m_PlayThroughTo : 8; // OXFF means no playthrough - QT3DSU32 m_Paused : 1; - QT3DSU32 m_StartTime; - QT3DSU32 m_EndTime; - QT3DSU32 m_AnimActionCount; - SSlideElement *m_FirstElement; - SSlideAnimActionNode *m_FirstAnimActionNode; - - SSlide() - : m_NextSlide(NULL) - , m_PlayMode(PlayMode::StopAtEnd) - , m_PlayThroughTo(0xFF) - , m_Paused(false) - , m_StartTime(0) - , m_EndTime(0) - , m_AnimActionCount(0) - , m_FirstElement(NULL) - , m_FirstAnimActionNode(NULL) - { - } - - void Initialize(CRegisteredString inName, PlayMode::Enum inMode, QT3DSU8 inPlayThrough, - bool inPaused, QT3DSU32 inStartTime, QT3DSU32 inEndTime) - { - m_Name = inName; - m_PlayMode = inMode; - m_PlayThroughTo = inPlayThrough; - m_Paused = inPaused; - m_StartTime = inStartTime; - m_EndTime = inEndTime; - } -}; - -struct SSlideSystem : public ISlideSystem -{ - typedef nvhash_map TComponentSlideHash; - typedef Pool TAttributeNodePool; - typedef Pool TSlideAnimActionPool; - typedef Pool TSlideElementPool; - typedef Pool TSlidePool; - - NVFoundationBase &m_Foundation; - IStringTable &m_StringTable; - IElementAllocator &m_ElementSystem; - TAttributeNodePool m_AttributeNodePool; - TSlideAnimActionPool m_AnimActionPool; - TSlideElementPool m_SlideElements; - TSlidePool m_SlidePool; - TComponentSlideHash m_Slides; - - SSlide *m_CurrentSlide; - SSlideElement *m_CurrentSlideElement; - - NVDataRef m_LoadData; - - QT3DSI32 m_RefCount; - - SSlideSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, IElementAllocator &inAllocator) - : m_Foundation(inFnd) - , m_StringTable(inStrTable) - , m_ElementSystem(inAllocator) - , m_AttributeNodePool(ForwardingAllocator(inFnd.getAllocator(), "m_AttributeNodePool")) - , m_AnimActionPool(ForwardingAllocator(inFnd.getAllocator(), "m_AnimActionPool")) - , m_SlidePool(ForwardingAllocator(inFnd.getAllocator(), "m_SlidePool")) - , m_SlideElements(ForwardingAllocator(inFnd.getAllocator(), "m_SlideElements")) - , m_Slides(inFnd.getAllocator(), "m_Slides") - , m_CurrentSlide(NULL) - , m_CurrentSlideElement(NULL) - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Foundation.getAllocator()); - NVDelete(alloc, this); - } - } - - QT3DSU32 AddSlide(element::SElement &inComponent, const char8_t *inName, - PlayMode::Enum inPlayMode, bool inPaused, QT3DSU8 inPlayThroughTo, - QT3DSU32 inMinTime, QT3DSU32 inMaxTime) override - { - eastl::pair inserter = - m_Slides.insert(eastl::make_pair(&inComponent, (SSlide *)NULL)); - SSlide *newSlide = m_SlidePool.construct(__FILE__, __LINE__); - QT3DSU32 slideIndex = 0; - if (inserter.first->second == NULL) { - inserter.first->second = newSlide; - } else { - SSlide *theSlide = NULL; - for (theSlide = inserter.first->second; theSlide->m_NextSlide != NULL; - theSlide = theSlide->m_NextSlide) { - ++slideIndex; - } - theSlide->m_NextSlide = newSlide; - } - m_CurrentSlide = newSlide; - newSlide->Initialize(m_StringTable.RegisterStr(inName), inPlayMode, inPlayThroughTo, - inPaused, inMinTime, inMaxTime); - m_CurrentSlideElement = NULL; - if (inComponent.IsComponent()) { - SComponent &theComponent = static_cast(inComponent); - theComponent.m_SlideCount++; - } - return slideIndex; - } - - void SetSlideMaxTime(QT3DSU32 inMaxTime) override - { - if (m_CurrentSlide != NULL) - m_CurrentSlide->m_EndTime = inMaxTime; - } - - void AddSlideElement(element::SElement &inElement, bool inActive) override - { - if (m_CurrentSlide != NULL) { - SSlideElement *lastSlideElement = m_CurrentSlideElement; - m_CurrentSlideElement = m_SlideElements.construct(__FILE__, __LINE__); - m_CurrentSlideElement->m_Active = inActive; - m_CurrentSlideElement->m_ElementHandle = inElement.GetHandle(); - if (lastSlideElement == NULL) { - QT3DS_ASSERT(m_CurrentSlide->m_FirstElement == NULL); - m_CurrentSlide->m_FirstElement = m_CurrentSlideElement; - } else { - lastSlideElement->m_NextElement = m_CurrentSlideElement; - } - m_CurrentSlideElement->m_Active = inActive; - } else { - QT3DS_ASSERT(false); - } - } - void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, Q3DStudio::UVariant inValue) override - { - if (m_CurrentSlideElement != NULL) { - - SElement *theElement = - m_ElementSystem.FindElementByHandle(m_CurrentSlideElement->m_ElementHandle); - Option theIdx = theElement->FindPropertyIndex(inKey.m_Hash); - if (theIdx.hasValue() == false) { - QT3DS_ASSERT(false); - return; - } - QT3DSU32 count = m_CurrentSlideElement->m_AttributeCount; - TSlideAttributeNodeList::Create(m_CurrentSlideElement->m_AttributeNodes, count, - m_AttributeNodePool) = - SSlideAttribute(*theIdx, inValue); - m_CurrentSlideElement->m_AttributeCount = count; - } - } - - SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inId, bool inActive) override - { - if (m_CurrentSlide != NULL) { - SSlideAnimAction &theAnimAction = TSlideAnimActionNodeList::Create( - m_CurrentSlide->m_FirstAnimActionNode, m_CurrentSlide->m_AnimActionCount, - m_AnimActionPool); - theAnimAction = SSlideAnimAction((QT3DSI32)inId, inActive, inAnimation); - &theAnimAction; - } - - return NULL; - } - - const SSlide *FindSlide(SSlideKey inKey) const - { - TComponentSlideHash::const_iterator iter = m_Slides.find(inKey.m_Component); - if (iter == m_Slides.end()) - return NULL; - - SSlide *theSlide = iter->second; - for (QT3DSU32 idx = inKey.m_Index; idx; --idx) { - if (theSlide) - theSlide = theSlide->m_NextSlide; - } - - return theSlide; - } - - template - static void IterateSlideAnimActions(const SSlide &inSlide, TOperator inOp) - { - for (TSlideAnimActionNodeList::const_iterator - iter = TSlideAnimActionNodeList::begin(inSlide.m_FirstAnimActionNode, - inSlide.m_AnimActionCount), - end = TSlideAnimActionNodeList::end(inSlide.m_FirstAnimActionNode, - inSlide.m_AnimActionCount); - iter != end; ++iter) { - inOp(*iter); - } - } - - template - static void IterateSlideElementAttributes(const SSlide &inSlide, TOperator inOp, - IElementAllocator &inAlloc) - { - for (SSlideElement *theElement = inSlide.m_FirstElement; theElement; - theElement = theElement->m_NextElement) { - SElement *theElem = inAlloc.FindElementByHandle(theElement->m_ElementHandle); - if (!theElem) { - QT3DS_ASSERT(false); - } else { - if (inOp.handleElementActive(*theElem, theElement->m_Active)) { - for (TSlideAttributeNodeList::const_iterator - iter = TSlideAttributeNodeList::begin(theElement->m_AttributeNodes, - theElement->m_AttributeCount), - end = TSlideAttributeNodeList::end(theElement->m_AttributeNodes, - theElement->m_AttributeCount); - iter != end; ++iter) { - inOp.handleElementAttribute(*theElem, *iter); - } - } - } - } - } - - struct SDynamicKeyOperator - { - IAnimationSystem &m_AnimationSystem; - SDynamicKeyOperator(IAnimationSystem &anim) - : m_AnimationSystem(anim) - { - } - void operator()(const SSlideAnimAction &theAction) - { - if (theAction.m_IsAnimation && theAction.m_Active) - m_AnimationSystem.UpdateDynamicKey(theAction.m_Id); - } - }; - - struct SExecuteAnimActionOperator - { - IElementAllocator &m_ElementAllocator; - IAnimationSystem &m_AnimationSystem; - ILogicSystem &m_LogicManager; - bool m_Invert; - - SExecuteAnimActionOperator(IElementAllocator &inElemAllocator, IAnimationSystem &anim, - ILogicSystem &logic, bool inInvert = false) - : m_ElementAllocator(inElemAllocator) - , m_AnimationSystem(anim) - , m_LogicManager(logic) - , m_Invert(inInvert) - { - } - - void operator()(const SSlideAnimAction &theAction) - { - bool active = theAction.m_Active; - if (m_Invert) - active = !active; - if (theAction.m_IsAnimation) - m_AnimationSystem.SetActive(theAction.m_Id, active); - else - m_LogicManager.SetActive(theAction.m_Id, active, m_ElementAllocator); - } - }; - - struct SElementOperator - { - bool m_InvertActive; - SElementOperator(bool inInvert = false) - : m_InvertActive(inInvert) - { - } - bool handleElementActive(SElement &inElement, bool inActive) - { - if (m_InvertActive && inElement.Flags().IsExplicitActive()) - inActive = !inActive; - inElement.Flags().SetExplicitActive(inActive); - - if (m_InvertActive) - return false; - - return inActive; - } - - void handleElementAttribute(SElement &inElement, const SSlideAttribute &inAttribute) - { - Option theProperty = - inElement.GetPropertyByIndex(inAttribute.m_Index); - if (theProperty.hasValue()) { - inElement.SetAttribute(*theProperty, inAttribute.m_Value); - } else { - QT3DS_ASSERT(false); - } - } - }; - - void InitializeDynamicKeys(SSlideKey inKey, IAnimationSystem &inAnimationSystem) const override - { - const SSlide *theSlide = FindSlide(inKey); - if (theSlide != NULL) { - IterateSlideAnimActions(*theSlide, SDynamicKeyOperator(inAnimationSystem)); - } - } - - void ExecuteSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, - ILogicSystem &inLogicManager) const override - { - const SSlide *theSlide = FindSlide(inKey); - - if (theSlide == NULL) { - QT3DS_ASSERT(false); - return; - } - if (inKey.m_Component->IsComponent()) { - Q3DStudio::TTimeUnit theLoopDuration = theSlide->m_EndTime - theSlide->m_StartTime; - SComponent &theComponent = static_cast(*inKey.m_Component); - Q3DStudio::CTimePolicy &thePolicy = theComponent.GetTimePolicy(); - Q3DStudio::TimePolicyModes::Enum theMode = Q3DStudio::TimePolicyModes::StopAtEnd; - switch (theSlide->m_PlayMode) { - case PlayMode::Looping: - theMode = Q3DStudio::TimePolicyModes::Looping; - break; - case PlayMode::PingPong: - theMode = Q3DStudio::TimePolicyModes::PingPong; - break; - case PlayMode::Ping: - theMode = Q3DStudio::TimePolicyModes::Ping; - break; - - case PlayMode::StopAtEnd: - case PlayMode::PlayThroughTo: - default: - theMode = Q3DStudio::TimePolicyModes::StopAtEnd; - break; - } - thePolicy.Initialize(theLoopDuration, theMode); - thePolicy.SetPaused(theSlide->m_Paused); - - theComponent.SetPlayThrough(theSlide->m_PlayMode == PlayMode::PlayThroughTo); - } - - IterateSlideElementAttributes(*theSlide, SElementOperator(false), m_ElementSystem); - IterateSlideAnimActions(*theSlide, SExecuteAnimActionOperator( - m_ElementSystem, inAnimationSystem, inLogicManager)); - } - - void RollbackSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, - ILogicSystem &inLogicManager) const override - { - const SSlide *theSlide = FindSlide(inKey); - - if (theSlide == NULL) { - QT3DS_ASSERT(false); - return; - } - - IterateSlideElementAttributes(*theSlide, SElementOperator(true), m_ElementSystem); - IterateSlideAnimActions( - *theSlide, - SExecuteAnimActionOperator(m_ElementSystem, inAnimationSystem, inLogicManager, true)); - } - - QT3DSU8 FindSlide(element::SElement &inComponent, const char8_t *inSlideName) const override - { - TComponentSlideHash::const_iterator theFindResult = m_Slides.find(&inComponent); - if (theFindResult == m_Slides.end()) { - QT3DS_ASSERT(false); - return 0xFF; - } - CRegisteredString theRegName = m_StringTable.RegisterStr(inSlideName); - QT3DSU8 idx = 0; - for (const SSlide *theSlide = theFindResult->second; theSlide; - theSlide = theSlide->m_NextSlide, ++idx) { - if (theSlide->m_Name == theRegName) - return idx; - } - return 0xFF; - } - - QT3DSU8 FindSlide(element::SElement &inComponent, QT3DSU32 inSlideHashName) const override - { - TComponentSlideHash::const_iterator theFindResult = m_Slides.find(&inComponent); - if (theFindResult == m_Slides.end()) { - QT3DS_ASSERT(false); - return 0xFF; - } - - QT3DSU8 idx = 0; - for (const SSlide *theSlide = theFindResult->second; theSlide; - theSlide = theSlide->m_NextSlide, ++idx) { - if (Q3DStudio::CHash::HashString(theSlide->m_Name) == inSlideHashName) - return idx; - } - return 0xFF; - } - - const char8_t *GetSlideName(SSlideKey inKey) const override - { - const SSlide *theSlide = FindSlide(inKey); - if (theSlide) - return theSlide->m_Name.c_str(); - QT3DS_ASSERT(false); - return ""; - } - - QT3DSU8 GetPlaythroughToSlideIndex(SSlideKey inKey) const override - { - const SSlide *theSlide = FindSlide(inKey); - if (theSlide) - return theSlide->m_PlayThroughTo; - QT3DS_ASSERT(false); - return 0xFF; - } -}; -} - -ISlideSystem &ISlideSystem::CreateSlideSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, - IElementAllocator &inElemAllocator) -{ - return *QT3DS_NEW(inFnd.getAllocator(), SSlideSystem)(inFnd, inStrTable, inElemAllocator); -} diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSTimePolicy.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSTimePolicy.cpp deleted file mode 100644 index e1efb8e0..00000000 --- a/src/Runtime/Source/Runtime/Source/Qt3DSTimePolicy.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTimePolicy.h" -#include "foundation/Qt3DSUnionCast.h" -#include "foundation/Qt3DSIntrinsics.h" -#include "Qt3DSComponentManager.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -const TTimeUnit CTimePolicy::FOREVER = 0; - -SAlignedTimeUnit::SAlignedTimeUnit(const TTimeUnit &inUnit) -{ - StaticAssert::valid_expression(); - qt3ds::intrinsics::memCopy(this, &inUnit, sizeof(TTimeUnit)); -} - -SAlignedTimeUnit::operator TTimeUnit() const -{ - TTimeUnit retval; - qt3ds::intrinsics::memCopy(&retval, this, sizeof(TTimeUnit)); - return retval; -} - -void SAlignedTimeUnit::operator-=(const TTimeUnit &inTime) -{ - TTimeUnit theThis(*this); - theThis -= inTime; - *this = SAlignedTimeUnit(theThis); -} - -void SAlignedTimeUnit::operator%=(const TTimeUnit &inTime) -{ - TTimeUnit theThis(*this); - theThis %= inTime; - *this = SAlignedTimeUnit(theThis); -} - -//============================================================================== -/** - * Initialization - */ - -void CTimePolicy::Initialize(const TTimeUnit inLoopingDuration, TimePolicyModes::Enum inMode) -{ - m_LocalTime = 0; - m_LoopingDuration = (unsigned long)inLoopingDuration; - m_TimePolicyMode = inMode; - m_Offset = 0; - m_Paused = false; - m_OffsetInvalid = 1; - m_Backward = 0; - m_Rate = 1.0f; -} - -void CTimePolicy::Initialize(const TTimeUnit inLoopingDuration /*= FOREVER*/, - UINT32 inRepetitions /*= 1*/, BOOL inPingPong /*= false*/) -{ - // UINT8 m_Repetitions : 2; ///< Number of traversal ( 0 = forever, 1 = stop at end, 2 = - // ping ) - TimePolicyModes::Enum theMode = TimePolicyModes::StopAtEnd; - if (inRepetitions == 1) - theMode = TimePolicyModes::StopAtEnd; - else if (inRepetitions == 0) { - if (inPingPong) - theMode = TimePolicyModes::PingPong; - else - theMode = TimePolicyModes::Looping; - } else - theMode = TimePolicyModes::Ping; - - Initialize(inLoopingDuration, theMode); -} - -//============================================================================== -/** - * Return the last computed time. This is subjected to playmodes. - * @return local time - */ -TTimeUnit CTimePolicy::InternalGetTime() const -{ - if (m_LocalTime < m_LoopingDuration) - return m_LocalTime; - else { - if (m_LoopingDuration == 0) - return m_LocalTime; - - switch (m_TimePolicyMode) { - case TimePolicyModes::StopAtEnd: - return m_LoopingDuration; - case TimePolicyModes::Looping: - return m_LocalTime % m_LoopingDuration; - case TimePolicyModes::Ping: { - unsigned long interval = m_LocalTime / m_LoopingDuration; - unsigned long leftover = m_LocalTime % m_LoopingDuration; - if (interval == 1) - return m_LoopingDuration - leftover; - return 0; - } - case TimePolicyModes::PingPong: { - unsigned long interval = m_LocalTime / m_LoopingDuration; - unsigned long leftover = m_LocalTime % m_LoopingDuration; - if (interval % 2) - return m_LoopingDuration - leftover; - return leftover; - } - default: - QT3DS_ASSERT(false); - return 0; - break; - } - } -} - -TTimeUnit CTimePolicy::GetTime() const -{ - TTimeUnit retval = InternalGetTime(); - // Apply direction and rate. - bool isPlayingBack = m_Backward; - if (m_Rate < 0) - isPlayingBack = !isPlayingBack; - - if (isPlayingBack) - retval = m_LoopingDuration - retval; - return retval; -} - -static unsigned long clampTime(long inTime, unsigned long inDuration) -{ - if (inTime < 0) - return 0; - if (inTime > (long)inDuration) - return inDuration; - return (unsigned long)inTime; -} - -//============================================================================== -/** - * Trigger the policy to return inTime next GetTime is called. - * This is tricky math and the m_Offset field is being used both normally to - * simply change the time and here to calibrate itself next time ComputeTime - * is called. - * @param inTime time to be returned next ComputeTime - */ -void CTimePolicy::SetTime(TTimeUnit inTime) -{ - - bool isPlayingBack = m_Backward; - if (m_Rate < 0) - isPlayingBack = !isPlayingBack; - - if (isPlayingBack) - inTime = m_LoopingDuration - inTime; - - m_OffsetInvalid = 1; - - // Setup m_LocalTime such that it reflects intime. - if (m_LoopingDuration == 0) { - m_LocalTime = (unsigned long)inTime; - return; - } - - switch (m_TimePolicyMode) { - case TimePolicyModes::StopAtEnd: - m_LocalTime = clampTime((long)inTime, m_LoopingDuration); - break; - case TimePolicyModes::Looping: { - long input = (long)inTime; - while (input < 0) - input += (long)m_LoopingDuration; - m_LocalTime = ((unsigned long)input) % m_LoopingDuration; - } break; - case TimePolicyModes::Ping: { - long input = (long)inTime; - if (input < 0) - input = 0; - - long totalInterval = (long)(m_LoopingDuration * 2); - if (input > totalInterval) - m_LocalTime = (unsigned long)totalInterval; - else - m_LocalTime = (unsigned long)input; - } break; - case TimePolicyModes::PingPong: { - long totalInterval = (long)(m_LoopingDuration * 2); - long input = (long)inTime; - while (input < 0) - input += totalInterval; - m_LocalTime = (unsigned long)(input % totalInterval); - } break; - default: - QT3DS_ASSERT(false); - } -} - -//============================================================================== -/** - * Retrieves the looping duration. - * @see CTimePolicy::SetLoopingDuration( ) - * @return TTimeUnit looping duration - */ -TTimeUnit CTimePolicy::GetLoopingDuration() const -{ - return m_LoopingDuration; -} - -//============================================================================== -/** - * Set the looping duration. - * Looping duration is defined as the time it takes before stopping, pinging or - * looping. - * @param inTime looping duration - */ -void CTimePolicy::SetLoopingDuration(const TTimeUnit inTime) -{ - m_LoopingDuration = (unsigned long)inTime; -} - -//============================================================================== -/** - * Return the paused state. - * @return BOOL pause state - */ -BOOL CTimePolicy::GetPaused() const -{ - return m_Paused; -} - -BOOL CTimePolicy::GetPlayBackDirection() const -{ - bool reversePlaybackDirection = m_Backward; - if (m_Rate < 0) - reversePlaybackDirection = !reversePlaybackDirection; - - bool retval = m_LocalTime < m_LoopingDuration; - - if (reversePlaybackDirection) - retval = !retval; - return retval; -} - -//============================================================================== -/** - * Sets the paused state - * @param inPaused pause state - */ -void CTimePolicy::SetPaused(const BOOL inPaused) -{ - m_Paused = static_cast(inPaused); -} - -BOOL CTimePolicy::UpdateTime(const TTimeUnit inTime) -{ - if (fabs(m_Rate) > .001f) - m_LocalTime = - static_cast(((unsigned long)(inTime + m_Offset)) * fabs(m_Rate)); - // else we are effectively stopped and we can't update the time. - - if (m_LoopingDuration == 0) - return FALSE; - - unsigned long maxUsefulDuration = m_LoopingDuration * 2; - BOOL retval = 0; - switch (m_TimePolicyMode) { - case TimePolicyModes::StopAtEnd: - if (m_LocalTime > m_LoopingDuration) { - retval = 1; - m_LocalTime = m_LoopingDuration; - } - break; - case TimePolicyModes::Looping: - m_LocalTime = m_LocalTime % m_LoopingDuration; - break; - case TimePolicyModes::Ping: - if (m_LocalTime > maxUsefulDuration) { - retval = 1; - m_LocalTime = maxUsefulDuration; - } - break; - case TimePolicyModes::PingPong: - m_LocalTime = m_LocalTime % maxUsefulDuration; - break; - default: - QT3DS_ASSERT(false); - break; - } - return retval; -} -//============================================================================== -/** - * Compute the local time based off the current global time and the settings - * such as duration, repetitions and ping-pong. - * @param inTime global time being fed - * @return BOOL true if policy has reached it's end time - */ -BOOL CTimePolicy::ComputeTime(const TTimeUnit inTime) -{ - // Return the last computed time if paused - if (m_Paused || m_OffsetInvalid) { - // m_LocalTime = inTime + m_Offset; - if (fabs(m_Rate) > .001) - m_Offset = (TTimeUnit)(m_LocalTime / fabs(m_Rate)) - inTime; - else // rate is zero, this should not happen. - m_Offset = (TTimeUnit)(m_LocalTime)-inTime; - m_OffsetInvalid = 0; - return false; - } - return UpdateTime(inTime); -} - -eastl::pair -SComponentTimePolicyOverride::ComputeLocalTime(CTimePolicy &inTimePolicy, TTimeUnit inGlobalTime) -{ - TTimeUnit retval = 0; - BOOL finished = FALSE; - if (inTimePolicy.m_Paused || inTimePolicy.m_OffsetInvalid) { - finished = inTimePolicy.ComputeTime(inGlobalTime); - } else { - Q3DStudio_ASSERT(m_EndTime <= inTimePolicy.GetLoopingDuration()); - unsigned long newLocalTime = (unsigned long)(inGlobalTime + inTimePolicy.m_Offset); - - float diff = static_cast(newLocalTime - inTimePolicy.GetTime()); - diff *= m_TimeMultiplier; - float updatedLocalTime = static_cast(inTimePolicy.m_LocalTime) + diff; - - if (updatedLocalTime < 0.0f) - updatedLocalTime = 0.0f; - - inTimePolicy.m_LocalTime = static_cast(updatedLocalTime); - - bool runningBackwards = m_TimeMultiplier < 0; - - if (runningBackwards) { - if (inTimePolicy.m_LocalTime <= m_EndTime) { - finished = TRUE; - inTimePolicy.m_LocalTime = (unsigned long)m_EndTime; - } - } else // running forwards - { - if (inTimePolicy.m_LocalTime >= m_EndTime) { - finished = TRUE; - inTimePolicy.m_LocalTime = (unsigned long)m_EndTime; - } - } - inTimePolicy.m_Offset = inTimePolicy.m_LocalTime - inGlobalTime; - } - retval = inTimePolicy.GetTime(); - return eastl::make_pair(finished, retval); -} - -void SComponentTimePolicyOverride::SetTime(CTimePolicy &inTimePolicy, TTimeUnit inLocalTime) -{ - if (inLocalTime < 0) - inLocalTime = 0; - if (m_TimeMultiplier < 0) { - if (inLocalTime <= m_EndTime) { - inLocalTime = m_EndTime; - } - } else // running forwards - { - if (inLocalTime >= m_EndTime) { - inLocalTime = m_EndTime; - } - } - inTimePolicy.SetTime(inLocalTime); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/Runtime/Source/q3dsqmlbehavior.cpp b/src/Runtime/Source/Runtime/Source/q3dsqmlbehavior.cpp deleted file mode 100644 index 83b706eb..00000000 --- a/src/Runtime/Source/Runtime/Source/q3dsqmlbehavior.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "q3dsqmlbehavior.h" -#include "q3dsqmlscript.h" - -namespace Q3DStudio { - -Q3DSQmlBehavior::Q3DSQmlBehavior(QObject *parent) - : QObject(parent), m_script(nullptr) -{ - -} - -void Q3DSQmlBehavior::setScript(Q3DSQmlScript *script) -{ - m_script = script; -} - -float Q3DSQmlBehavior::getDeltaTime() -{ - return m_script->getDeltaTime(); -} - -float Q3DSQmlBehavior::getAttribute(const QString &attribute) -{ - return m_script->getAttribute(attribute); -} - -void Q3DSQmlBehavior::setAttribute(const QString &attribute, const QVariant &value) -{ - m_script->setAttribute(attribute, value); -} - -void Q3DSQmlBehavior::setAttribute(const QString &handle, const QString &attribute, - const QVariant &value) -{ - m_script->setAttribute(handle, attribute, value); -} - -void Q3DSQmlBehavior::fireEvent(const QString &event) -{ - m_script->fireEvent(event); -} - -void Q3DSQmlBehavior::registerForEvent(const QString &event, const QJSValue &function) -{ - m_script->registerForEvent(event, function); -} - -void Q3DSQmlBehavior::registerForEvent(const QString &handle, const QString &event, - const QJSValue &function) -{ - m_script->registerForEvent(handle, event, function); -} - -void Q3DSQmlBehavior::unregisterForEvent(const QString &event) -{ - m_script->unregisterForEvent(event); -} - -void Q3DSQmlBehavior::unregisterForEvent(const QString &handle, const QString &event) -{ - m_script->unregisterForEvent(handle, event); -} - -QVector2D Q3DSQmlBehavior::getMousePosition() -{ - return m_script->getMousePosition(); -} - -QMatrix4x4 Q3DSQmlBehavior::calculateGlobalTransform(const QString &handle) -{ - return m_script->calculateGlobalTransform(handle); -} - -QVector3D Q3DSQmlBehavior::lookAt(const QVector3D &target) -{ - return m_script->lookAt(target); -} - -QVector3D Q3DSQmlBehavior::matrixToEuler(const QMatrix4x4 &matrix) -{ - return m_script->matrixToEuler(matrix); -} - -QString Q3DSQmlBehavior::getParent(const QString &handle) -{ - return m_script->getParent(handle); -} - -void Q3DSQmlBehavior::setDataInputValue(const QString &name, const QVariant &value) -{ - return m_script->setDataInputValue(name, value); -} - -} diff --git a/src/Runtime/Source/Runtime/Source/q3dsqmlscript.cpp b/src/Runtime/Source/Runtime/Source/q3dsqmlscript.cpp deleted file mode 100644 index 09f18148..00000000 --- a/src/Runtime/Source/Runtime/Source/q3dsqmlscript.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "q3dsqmlscript.h" - -#include "Qt3DSQmlEngine.h" -#include "Qt3DSElementSystem.h" -#include "Qt3DSApplication.h" -#include "Qt3DSPresentation.h" -#include "Qt3DSInputEngine.h" -#include "Qt3DSInputFrame.h" -#include "Qt3DSQmlElementHelper.h" -#include "Qt3DSHash.h" -#include "Qt3DSEulerAngles.h" - -using namespace Q3DStudio; - -QJSValue argToQJSValue(qt3ds::foundation::IStringTable &strTable, - Q3DStudio::UINT8 type, const UVariant &value) { - switch (type) { - case ATTRIBUTETYPE_INT32: - case ATTRIBUTETYPE_HASH: - return QJSValue(value.m_INT32); - case ATTRIBUTETYPE_FLOAT: - return QJSValue(value.m_FLOAT); - case ATTRIBUTETYPE_BOOL: - return QJSValue(value.m_INT32 != 0); - case ATTRIBUTETYPE_STRING: - return QJSValue(strTable.HandleToStr(value.m_StringHandle)); - case ATTRIBUTETYPE_NONE: - return QJSValue(); - default: - qCCritical(qt3ds::INVALID_OPERATION) - << "Pushed event argument value of unknown type: "<< type; - } - return QJSValue(); -} - -void eventCallback(void *contextData, SEventCommand &event) -{ - auto data = static_cast(contextData); - qt3ds::foundation::IStringTable &strTable( - event.m_Target->GetBelongedPresentation()->GetStringTable()); - QJSValue arg1 = argToQJSValue(strTable, event.m_Arg1Type, event.m_Arg1); - QJSValue arg2 = argToQJSValue(strTable, event.m_Arg2Type, event.m_Arg2); - data->function.call({arg1, arg2}); -} - -Q3DSQmlScript::Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, - TElement &behavior, TElement &owner) - : QObject(nullptr) - , m_api(api) - , m_object(object) - , m_behavior(behavior) - , m_owner(owner) - , m_initialized(false) - , m_lastActivationState(false) - , m_deltaTime(0.0f) - , m_lastTime(0) -{ - updateProperties(); -} - -Q3DSQmlScript::~Q3DSQmlScript() -{ - for (const EventCallbackInfo &callback : m_eventCallbacks) - delete callback.data; -} - -void Q3DSQmlScript::update() -{ - updateProperties(); - - bool active = m_behavior.GetActive(); - - if (active && !m_initialized) { - m_initialized = true; - Q_EMIT m_object.initialize(); - } - - TTimeUnit time = static_cast(m_behavior.GetBelongedPresentation())->GetTime(); - m_deltaTime = (time - m_lastTime) / 1000.0f; - m_lastTime = time; - - if (m_lastActivationState != active) { - if (active) - Q_EMIT m_object.activate(); - else - Q_EMIT m_object.deactivate(); - } - m_lastActivationState = active; - if (active) - Q_EMIT m_object.update(); -} - -void Q3DSQmlScript::call(const QString &function) -{ - const QMetaObject *meta = m_object.metaObject(); - const QString normalized = function + "()"; - if (meta->indexOfMethod(normalized.toUtf8().constData()) != -1) - QMetaObject::invokeMethod(&m_object, function.toUtf8().constData()); -} - -void Q3DSQmlScript::updateProperties() -{ - using namespace qt3ds::foundation; - using namespace qt3ds::runtime::element; - - if (!m_behavior.GetActive()) - return; - - unsigned int numProperties = m_behavior.GetNumProperties(); - for (unsigned int i = 0; i < numProperties; ++i) { - Option property = m_behavior.GetPropertyByIndex(i); - if (!property.hasValue()) - break; - - TPropertyDescAndValuePtr value = property.getValue(); - const char *name = value.first.m_Name.c_str(); - - UVariant *valuePtr = value.second; - switch (value.first.m_Type) { - case ATTRIBUTETYPE_INT32: - case ATTRIBUTETYPE_HASH: - m_object.setProperty(name, valuePtr->m_INT32); - break; - case ATTRIBUTETYPE_FLOAT: - m_object.setProperty(name, valuePtr->m_FLOAT); - break; - case ATTRIBUTETYPE_BOOL: - m_object.setProperty(name, valuePtr->m_INT32 != 0); - break; - case ATTRIBUTETYPE_STRING: - m_object.setProperty( - name, - m_behavior.GetBelongedPresentation()->GetStringTable() - .HandleToStr(valuePtr->m_StringHandle) - .c_str()); - break; - default: - QT3DS_ASSERT(false); - } - } -} - -bool Q3DSQmlScript::hasBehavior(const TElement *behavior) -{ - return &m_behavior == behavior; -} - -float Q3DSQmlScript::getDeltaTime() -{ - return m_deltaTime; -} - -float Q3DSQmlScript::getAttribute(const QString &attribute) -{ - if (!m_behavior.GetActive()) - return 0; - - float floatValue = 0; - m_api.GetAttribute(m_owner.m_Path, - attribute.toUtf8().constData(), - (char *)&floatValue); - return floatValue; -} - -void Q3DSQmlScript::setAttribute(const QString &attribute, const QVariant &value) -{ - setAttribute("", attribute, value); -} - -void Q3DSQmlScript::setAttribute(const QString &handle, const QString &attribute, - const QVariant &value) -{ - if (!m_behavior.GetActive()) - return; - - TElement *element = &m_owner; - if (!handle.isEmpty()) - element = getElementByPath(handle); - if (!element) - return; - - QByteArray valueStr; - float valueFloat; - - const char *valuePtr = nullptr; - switch (static_cast(value.type())) { - case QMetaType::Bool: - case QMetaType::Int: - case QMetaType::Double: - case QMetaType::Float: - valueFloat = value.toFloat(); - valuePtr = (const char *)&valueFloat; - break; - case QMetaType::QString: - default: - valueStr = value.toString().toUtf8(); - valuePtr = valueStr.constData(); - break; - } - - m_api.SetAttribute(element->m_Path, - attribute.toUtf8().constData(), - valuePtr); -} - -void Q3DSQmlScript::fireEvent(const QString &event) -{ - if (!m_behavior.GetActive()) - return; - m_api.FireEvent(m_behavior.m_Path, event.toUtf8().constData()); -} - -void Q3DSQmlScript::registerForEvent(const QString &event, const QJSValue &function) -{ - registerForEvent("", event, function); -} - -void Q3DSQmlScript::registerForEvent(const QString &handle, const QString &event, - const QJSValue &function) -{ - if (!m_behavior.GetActive()) - return; - - TElement *element = &m_owner; - if (!handle.isEmpty()) - element = getElementByPath(handle); - if (!element) - return; - - if (!function.isCallable()) - return; - - CPresentation *presentation - = static_cast(m_behavior.GetBelongedPresentation()); - TEventCommandHash eventHash = CHash::HashEventCommand(event.toUtf8().constData()); - - for (auto &&callback : m_eventCallbacks) { - if (callback.element == element && callback.eventHash == eventHash) - return; - } - - EventData *data = new EventData(); - data->function = function; - - m_eventCallbacks.push_back({element, eventHash, data}); - - presentation->RegisterEventCallback(element, eventHash, &eventCallback, data); -} - -void Q3DSQmlScript::unregisterForEvent(const QString &event) -{ - unregisterForEvent("", event); -} - -void Q3DSQmlScript::unregisterForEvent(const QString &handle, const QString &event) -{ - if (!m_behavior.GetActive()) - return; - - TElement *element = &m_owner; - if (!handle.isEmpty()) - element = getElementByPath(handle); - if (!element) - return; - - CPresentation *presentation - = static_cast(m_behavior.GetBelongedPresentation()); - TEventCommandHash eventHash = CHash::HashEventCommand(event.toUtf8().constData()); - EventData *data = nullptr; - - for (int i = 0; i < m_eventCallbacks.size(); ++i) { - if (m_eventCallbacks[i].element == element && m_eventCallbacks[i].eventHash == eventHash) { - data = m_eventCallbacks[i].data; - m_eventCallbacks.erase(m_eventCallbacks.begin() + i); - break; - } - } - - if (data) { - presentation->UnregisterEventCallback(element, eventHash, &eventCallback, data); - delete data; - } -} - -QVector2D Q3DSQmlScript::getMousePosition() -{ - CPresentation *presentation - = static_cast(m_behavior.GetBelongedPresentation()); - qt3ds::runtime::IApplication &app = presentation->GetApplication(); - - SInputFrame input = app.GetInputEngine().GetInputFrame(); - if (app.GetPrimaryPresentation()) { - Q3DStudio::SMousePosition position = - app.GetPrimaryPresentation()->GetScene()->WindowToPresentation( - Q3DStudio::SMousePosition(static_cast(input.m_PickX), - static_cast(input.m_PickY))); - - return QVector2D(position.m_X, position.m_Y); - } - return QVector2D(0, 0); -} - -QMatrix4x4 Q3DSQmlScript::calculateGlobalTransform(const QString &handle) -{ - TElement *element = &m_owner; - if (!handle.isEmpty()) - element = getElementByPath(handle); - if (!element) - return QMatrix4x4(); - - RuntimeMatrix transform; - IScene *scene = element->GetBelongedPresentation()->GetScene(); - scene->CalculateGlobalTransform(element, transform); - transform.FlipCoordinateSystem(); - - return QMatrix4x4(&transform.m_Data[0][0]); -} - -QVector3D Q3DSQmlScript::lookAt(const QVector3D &target) -{ - RuntimeVector3 rotation; - - FLOAT theMag = ::sqrtf(target.x() * target.x() + target.z() * target.z()); - FLOAT thePitch = -::atan2f(target.y(), theMag); - FLOAT theYaw = ::atan2f(target.x(), target.z()); - - rotation.Set(thePitch, theYaw, 0.0f); - - return QVector3D(rotation.m_X, rotation.m_Y, rotation.m_Z); -} - -QVector3D Q3DSQmlScript::matrixToEuler(const QMatrix4x4 &matrix) -{ - CEulerAngleConverter converter; - const float *qMatrix = matrix.constData(); - HMatrix hHatrix; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) - hHatrix[i][j] = qMatrix[j * 4 + i]; - } - EulerAngles eulerAngles = converter.Eul_FromHMatrix(hHatrix, EulOrdYXZs); - return QVector3D(-eulerAngles.y, -eulerAngles.x, -eulerAngles.z); -} - -QString Q3DSQmlScript::getParent(const QString &handle) -{ - TElement *element = &m_owner; - if (!handle.isEmpty()) - element = getElementByPath(handle); - if (!element) - return ""; - - TElement *parent = element->GetParent(); - if (!parent) - return ""; - return parent->m_Path.c_str(); -} - -void Q3DSQmlScript::setDataInputValue(const QString &name, const QVariant &value) -{ - m_api.SetDataInputValue(name, value); -} - -TElement *Q3DSQmlScript::getElementByPath(const QString &path) -{ - if (!m_api.GetApplication()) - return nullptr; - - TElement *element = CQmlElementHelper::GetElement( - *m_api.GetApplication(), - m_api.GetApplication()->GetPrimaryPresentation(), - path.toUtf8().constData(), &m_owner); - return element; -} diff --git a/src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp b/src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp deleted file mode 100644 index e1fa04c6..00000000 --- a/src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "q3dsvariantconfig_p.h" - -namespace qt3ds { - -Q3DSVariantConfig::Q3DSVariantConfig() -{ - -} - -Q3DSVariantConfig::~Q3DSVariantConfig() -{ - for (auto str : qAsConst(m_internalVariantList)) - delete str; - m_internalVariantList.clear(); -} - -void Q3DSVariantConfig::setVariantList(const QStringList &variantList) -{ - // Store the QStringList to be returned from the API - m_variantList = variantList; - - for (auto str : qAsConst(m_internalVariantList)) - delete str; - m_internalVariantList.clear(); - - // Build a fixed (in mem location) list of the variant strings - for (auto tag : variantList) - m_internalVariantList.append(new QString(tag)); - - // Parse the variantGroup:variant list to map using the fixed list - m_variantFilter.clear(); - for (auto tag : qAsConst(m_internalVariantList)) { - QStringRef refTag = QStringRef(tag); - int separatorIdx = refTag.indexOf(QLatin1Char(':')); - QStringRef group = refTag.left(separatorIdx); - QStringRef variant = refTag.mid(separatorIdx + 1); - m_variantFilter[group].append(variant); - } -} - -bool Q3DSVariantConfig::isPartOfConfig(const QStringRef &variantAttributes) const -{ - // Variant filter is ignored when it's not defined - // or if the object has no variant attributes - if (m_variantFilter.isEmpty() || variantAttributes.isEmpty()) - return true; - - // Collect all variant tags per group from the element - QHash> groupToVariants; - const QVector variantTags = variantAttributes.split( - QLatin1Char(','), - QString::SkipEmptyParts); - - for (auto tag : variantTags) { - // Break each variantGroup:value to group and value strings - int groupSeparatorIdx = tag.indexOf(QLatin1Char(':')); - QStringRef group = tag.left(groupSeparatorIdx); - - // Only collect variant tags that are relevant to variant filtering - if (m_variantFilter.contains(group)) { - QStringRef variant = tag.mid(groupSeparatorIdx + 1); - groupToVariants[group].append(variant); - } - } - - // If no relevant variant tags found in element, load the element - if (groupToVariants.isEmpty()) - return true; - - // Verify that the element matches the variant filtering per group. - // To match the element must either: - // - Have no variant tag defined for the group - // - Have a matching tag for the group - bool isLoaded = true; - const auto filteredGroups = m_variantFilter.keys(); - for (auto group : filteredGroups) { - const QVector variants = groupToVariants[group]; - const QVector filteredVariants = m_variantFilter[group]; - - if (variants.size() > 0) { - // Check if ANY of the variant values of the element matches ANY - // of the included variants in the filter for this variant group - bool matchesFilter = false; - for (auto variant : variants) - matchesFilter |= filteredVariants.contains(variant); - - isLoaded &= matchesFilter; - } - } - - return isLoaded; -} - -} diff --git a/src/Runtime/Source/System/Include/Qt3DSArray.h b/src/Runtime/Source/System/Include/Qt3DSArray.h deleted file mode 100644 index 805b8b0a..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSArray.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSMemorySettings.h" -#include "Qt3DSMemory.h" -#include "Qt3DSPlatformSpecific.h" - -#ifdef WIN32 -#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy - // constructor is inaccessible -#pragma warning(disable : 4626) // assignment operator could not be generated because a base class - // assignment operator is inaccessible -#endif - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -#define NVARRAY_NOTFOUND -1 - -//============================================================================== -/** - * Ordered Collection also knows as a vector. - * - * Use Reserve or the constructor parameter if you know how many slots - * will be needed to prevent frequent reallocations during growth. - * - * The array grows by DEFAULT_GROWFACTOR aka 20% whenever it overflows. By - * setting the factor to 0 it will still clamp to 1 and instead grow the - * array by one slot at a time. This is not ideal but given a pooled memory - * manager you will not thrash memory too much since you will grow inside - * each pool chunk and only reallocate when switching pools. - * - * Naming of CArray instances are used to enable memory tracking of arrays - * that have gone berzerk or less frequently used instances that could be - * released after usage. - * - * The FOR_ARRAY macro is the preferred way to process all array slots. - */ -template -class CArray -{ -//============================================================================== -// Constants -//============================================================================== -#define DEFAULT_GROWFACTOR 1.2f - - //============================================================================== - // Types - //============================================================================== -public: - typedef T TType; ///< Easy access to template type - - //============================================================================== - // Fields - //============================================================================== -protected: - CHAR m_Name[32]; ///< Allows easy ID using memory reporting - T *m_Data; ///< Allocated memory containing array data - INT32 m_Capacity; ///< Max number of slots possible - INT32 m_Count; ///< Current number of slots in array - FLOAT m_GrowFactor; ///< Factor by which array grows when out of space - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - inline CArray(const INT32 inCapacity = 0, const FLOAT inGrowFactor = DEFAULT_GROWFACTOR, - const CHAR *inName = NULL); - inline CArray(const CArray &); - inline ~CArray(); - -public: // Management - inline void SetName(const CHAR *inName = NULL); - inline INT32 GetCount() const; - inline INT32 GetCapacity() const; - inline void Clear(const BOOL inRelease = true); - inline void Reserve(const INT32 inCapacity, const BOOL inExpand = false); - -public: // Stack access - void Push(const T &inValue); - inline const T &Pop(); - inline const T &Top() const; - -public: // Random access - inline INT32 GetIndex(const T &inValue) const; - inline T &operator[](const INT32 inIndex) const; - inline void Remove(const INT32 inIndex); - -public: // FOR_ARRAY iteration - inline T *Begin() const; - inline T *End() const; - -private: // Disabled Copy Construction - inline CArray &operator=(const CArray &); -}; - -} // namespace Q3DStudio - -//============================================================================== -// Template code -//============================================================================== -#include "Qt3DSArray.inl" diff --git a/src/Runtime/Source/System/Include/Qt3DSArray.inl b/src/Runtime/Source/System/Include/Qt3DSArray.inl deleted file mode 100644 index a9667fd2..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSArray.inl +++ /dev/null @@ -1,287 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2007 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - * - * @param inCapacity preallocated number of slots to avoid growth reallocation - * @param inGrowFactor factor by which the array grows when out of space - * @param inName 32 byte unique identifier for memory tracking - */ -template inline -CArray::CArray( const INT32 inCapacity, const FLOAT inGrowFactor, const CHAR* inName ) : - m_Data( NULL ), - m_Capacity( 0 ), - m_Count( 0 ), - m_GrowFactor( inGrowFactor ) -{ - // Disallow negative growth - if ( m_GrowFactor < 1.0f ) - m_GrowFactor = DEFAULT_GROWFACTOR; - - SetName( inName ); - Reserve( inCapacity ); -} - -//============================================================================== -/** - * Berger's Copy Constructor. - */ -template inline -CArray::CArray( const CArray& inOther ) : - m_Data( NULL ), - m_Capacity( 0 ), - m_Count( 0 ), - m_GrowFactor( inOther.m_GrowFactor ) -{ - // Disallow negative growth - if ( m_GrowFactor < 1.0f ) - m_GrowFactor = DEFAULT_GROWFACTOR; - - SetName( inOther.m_Name ); - Reserve( inOther.m_Capacity ); - FOR_ARRAY( T, theTemp, inOther ) - { - Push( *theTemp ); - } -} - -//============================================================================== -/** - * Destructor - */ -template inline -CArray::~CArray( ) -{ - Clear( true ); -} - -//============================================================================== -/** - * Name an array instance to easily identify it during memory reporting. - * @param inName 32 byte unique identifier - */ -template inline -void CArray::SetName( const CHAR* inName /*= NULL*/ ) -{ - Q3DStudio_sprintf( m_Name, sizeof( m_Name ), "%s", inName ? inName : "CArray" ); -} - -//============================================================================== -/** - * Count is the number of elements in the array. - * @return current count of the array - */ -template inline -INT32 CArray::GetCount( ) const -{ - return m_Count; -} - -//============================================================================== -/** - * Get the capacity of the array - * Capacity reflects the max count before reallocation happens. - * @return capacity of the array - */ -template inline -INT32 CArray::GetCapacity( ) const -{ - return m_Capacity; -} - -//============================================================================== -/** - * Clear the array by reducing the number of elements to zero. - * - * Using the release flag keeps the memory load low but could be - * suboptimal in situations where you are always using roughly the same - * number of elements. In that scenario, the array would have to build up - * and reallocate up to the same number of elements every time causing - * stress on the system. Clearing but keeping the buffer by setting - * release to false is optimal in that case. - * - * @param inRelease true to release memory, false keeps old buffer - */ -template inline -void CArray::Clear( const BOOL inRelease ) -{ - m_Count = 0; - - if ( inRelease ) - { - Q3DStudio_free( m_Data, T, m_Capacity ); - m_Capacity = 0; - m_Data = NULL; - } - else - Q3DStudio_memset( m_Data, 0 , sizeof( T ) * m_Capacity ); -} - -//============================================================================== -/** - * Allocate enough memory to store T. - * - * If current memory is not sufficient, new block of memory is allocated and - * data in current memory is copied to the new block of memory. Data pointer will - * point to the new block of memory and current memory is released. - * - * @param inCapacity indicate the amount of memory required. - * @param inExpand true to not only allocate but also extend array - */ -template inline -void CArray::Reserve( const INT32 inCapacity, const BOOL inExpand ) -{ - if ( inCapacity > m_Capacity ) - { - T* theData = Q3DStudio_allocate_desc( T, inCapacity, m_Name ); - Q3DStudio_memset( theData, 0 , sizeof( T ) * inCapacity ); - if ( m_Data != NULL ) - { - Q3DStudio_memcpy( theData, m_Data, sizeof( T ) * m_Count ); - Q3DStudio_free( m_Data, T, m_Capacity ); - } - m_Data = theData; - m_Capacity = inCapacity; - } - - if ( inExpand ) - m_Count = inCapacity; -} - -//============================================================================== -/** - * Insert T to the end of the array - * @param inValue value of datatype T - */ -template inline -void CArray::Push( const T& inValue ) -{ - if ( m_Count == m_Capacity ) - Reserve( static_cast( m_GrowFactor * m_Capacity ) + 1 ); - - m_Data[m_Count++] = inValue; -} - -//============================================================================== -/** - * Remove and retrieve T which is at the end of the array - * @return value of datatype T - */ -template inline -const T& CArray::Pop( ) -{ - return m_Data[--m_Count]; -} - -//============================================================================== -/** - * Get T which is at the end of the array - * @return reference of value of datatype T - */ -template inline -const T& CArray::Top( ) const -{ - return m_Data[m_Count - 1]; -} - -//============================================================================== -/** - * Get index of first element that matches inValue - * @return index of element matching T or INDEX_NOTFOUND - */ -template inline -INT32 CArray::GetIndex( const T& inValue ) const -{ - for ( INT32 theIndex = 0; theIndex < m_Count; ++theIndex ) - if ( inValue == m_Data[theIndex] ) - return theIndex; - return NVARRAY_NOTFOUND; -} - -//============================================================================== -/** - * Get the element at a particular index position of the array. - * @note Range checking is only done is debug builds. - * @param inIndex the index of the array - * @return reference of value of datatype T - */ -template inline -T& CArray::operator[]( const INT32 inIndex ) const -{ - Q3DStudio_ASSERT( inIndex >= 0 && inIndex < m_Capacity ); - return m_Data[inIndex]; -} - -//============================================================================== -/** - * Remove T that resides at a particular index position of the array. - * Other T data with higher index value is shifted to occupy the empty slot - * created in the removal process. - * @param inIndex the index of the array - */ -template inline -void CArray::Remove( const INT32 inIndex ) -{ - Q3DStudio_memmove( m_Data + inIndex, m_Data + inIndex + 1, sizeof( T ) * ( m_Count - inIndex - 1 ) ); - --m_Count; -} - -//============================================================================== -/** - * Get T at the first index of the array. - * Mainly used for FOR_ARRAY macro implementation - * @return pointer to first value in array - */ -template inline -T* CArray::Begin( ) const -{ - return m_Data; -} - -//============================================================================== -/** - * Get T at the last index of the array. - * Mainly used for FOR_ARRAY macro implementation - * @return pointer to one beyond last value in array - */ -template inline -T* CArray::End( ) const -{ - return m_Data + m_Count; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSAssert.h b/src/Runtime/Source/System/Include/Qt3DSAssert.h deleted file mode 100644 index a64ca7f6..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSAssert.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "Qt3DSTypes.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Static gateway for all asserts. - * - * By setting your own assert function you can redirect all Runtime asserts. - * By default it uses the internal Default method that uses CLog for output - * and displays a dialog on Windows PCs. - */ -class CAssert -{ - //============================================================================== - // Typedefs - //============================================================================== -public: - typedef void (*TFunction)(const Q3DStudio::CHAR *inAssert, const Q3DStudio::CHAR *inFile, - Q3DStudio::INT32 inLine, const Q3DStudio::CHAR *inFunction); - - //============================================================================== - // Fields - //============================================================================== -protected: - static TFunction s_AssertFunction; ///< Function pointer to active assert function - - //============================================================================== - // Methods - //============================================================================== -private: // Hidden Constructor - CAssert(); - -public: // Static Usage - static void Default(const Q3DStudio::CHAR *inAssert, const Q3DStudio::CHAR *inFile, - Q3DStudio::INT32 inLine, const Q3DStudio::CHAR *inFunction); - -public: // Static Configuration - static void SetFunction(TFunction inAssert); - static TFunction GetFunction(); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSAudioPlayer.h b/src/Runtime/Source/System/Include/Qt3DSAudioPlayer.h deleted file mode 100644 index 3b6f3ef8..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSAudioPlayer.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -namespace Q3DStudio { - -class IAudioPlayer -{ -public: - virtual ~IAudioPlayer() {} - virtual bool PlaySoundFile(const char *inFilePath) = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSBasicPluginDLL.h b/src/Runtime/Source/System/Include/Qt3DSBasicPluginDLL.h deleted file mode 100644 index 63a2d1f6..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSBasicPluginDLL.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//============================================================================== -// Includes -//============================================================================== -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -//============================================================================== -// Enums -//============================================================================== -typedef enum _EDLLSTATUS { EDLLSTATUS_FAIL = 0, EDLLSTATUS_OK } EDLLSTATUS; - -// GetPluginType should return this -typedef enum _EDLLTYPE { - EDLLTYPE_UNKNOWN = 0, - EDLLTYPE_RENDERABLE_PLUGIN, - EDLLTYPE_CUSTOM_OBJECT, -} EDLLTYPE; - -//============================================================================== -// Function declarations -//============================================================================== - -//============================================================================== -/** - * Return the plugin type. - * @return plugin type - */ -typedef long (*PROC_GetPluginType)(); -Q_DECL_EXPORT long GetPluginType(); - -#ifdef __cplusplus -} -#endif diff --git a/src/Runtime/Source/System/Include/Qt3DSBezierEval.h b/src/Runtime/Source/System/Include/Qt3DSBezierEval.h deleted file mode 100644 index c4d733a3..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSBezierEval.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -namespace Q3DStudio { - -//============================================================================== -/** - * Generic Bezier parametric curve evaluation at a given parametric value. - * @param inP0 control point P0 - * @param inP1 control point P1 - * @param inP2 control point P2 - * @param inP3 control point P3 - * @param inS the variable - * @return the evaluated value on the bezier curve - */ -inline FLOAT EvaluateBezierCurve(FLOAT inP0, FLOAT inP1, FLOAT inP2, FLOAT inP3, const FLOAT inS) -{ - // Using: - // Q(s) = Sum i=0 to 3 ( Pi * Bi,3(s)) - // where: - // Pi is a control point and - // Bi,3 is a basis function such that: - // - // B0,3(s) = (1 - s)^3 - // B1,3(s) = (3 * s) * (1 - s)^2 - // B2,3(s) = (3 * s^2) * (1 - s) - // B3,3(s) = s^3 - - /* FLOAT theSSquared = inS * inS; // - t^2 - FLOAT theSCubed = theSSquared * inS; // - t^3 - - FLOAT theSDifference = 1 - inS; // (1 - - t) - FLOAT theSDifferenceSquared = theSDifference * theSDifference; // (1 - - t)^2 - FLOAT theSDifferenceCubed = theSDifferenceSquared * theSDifference; // (1 - t)^3 - - FLOAT theFirstTerm = theSDifferenceCubed; // (1 - - t)^3 - FLOAT theSecondTerm = ( 3 * inS ) * theSDifferenceSquared; // (3 * t) * (1 - - t)^2 - FLOAT theThirdTerm = ( 3 * theSSquared ) * theSDifference; // (3 * t^2) * - (1 - t) - FLOAT theFourthTerm = theSCubed; // - t^3 - - // Q(t) = ( p0 * (1 - t)^3 ) + ( p1 * (3 * t) * (1 - t)^2 ) + ( p2 * (3 * t^2) * (1 - t) - ) + ( p3 * t^3 ) - return ( inP0 * theFirstTerm ) + ( inP1 * theSecondTerm ) + ( inP2 * theThirdTerm ) + ( - inP3 * theFourthTerm );*/ - - FLOAT theFactor = inS * inS; - inP1 *= 3 * inS; - inP2 *= 3 * theFactor; - theFactor *= inS; - inP3 *= theFactor; - - theFactor = 1 - inS; - inP2 *= theFactor; - theFactor *= 1 - inS; - inP1 *= theFactor; - theFactor *= 1 - inS; - inP0 *= theFactor; - - return inP0 + inP1 + inP2 + inP3; -} - -//============================================================================== -/** - * Inverse Bezier parametric curve evaluation to get parametric value for a given output. - * This is equal to finding the root(s) of the Bezier cubic equation. - * @param inP0 control point P0 - * @param inP1 control point P1 - * @param inP2 control point P2 - * @param inP3 control point P3 - * @param inX the variable - * @return the evaluated value - */ -inline FLOAT EvaluateInverseBezierCurve(const FLOAT inP0, const FLOAT inP1, const FLOAT inP2, - const FLOAT inP3, const FLOAT inX) -{ - FLOAT theResult = 0; - - // Using: - // Q(s) = Sum i=0 to 3 ( Pi * Bi,3(s)) - // where: - // Pi is a control point and - // Bi,3 is a basis function such that: - // - // B0,3(s) = (1 - s)^3 - // B1,3(s) = (3 * s) * (1 - s)^2 - // B2,3(s) = (3 * s^2) * (1 - s) - // B3,3(s) = s^3 - - // The Bezier cubic equation: - // inX = inP0*(1-s)^3 + inP1*(3*s)*(1-s)^2 + inP2*(3*s^2)*(1-s) + inP3*s^3 - // = s^3*( -inP0 + 3*inP1 - 3*inP2 +inP3 ) + s^2*( 3*inP0 - 6*inP1 + 3*inP2 ) + s*( -3*inP0 - // + 3*inP1 ) + inP0 - // For cubic eqn of the form: c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 = 0 - FLOAT theConstants[4]; - theConstants[0] = static_cast(inP0 - inX); - theConstants[1] = static_cast(-3 * inP0 + 3 * inP1); - theConstants[2] = static_cast(3 * inP0 - 6 * inP1 + 3 * inP2); - theConstants[3] = static_cast(-inP0 + 3 * inP1 - 3 * inP2 + inP3); - - FLOAT theSolution[3] = { 0 }; - - if (theConstants[3] == 0) { - if (theConstants[2] == 0) { - if (theConstants[1] == 0) - theResult = 0; - else - theResult = -theConstants[0] / theConstants[1]; // linear - } else { - // quadratic - INT32 theNumRoots = CCubicRoots::SolveQuadric(theConstants, theSolution); - theResult = static_cast(theSolution[theNumRoots / 2]); - } - } else { - INT32 theNumRoots = CCubicRoots::SolveCubic(theConstants, theSolution); - theResult = static_cast(theSolution[theNumRoots / 3]); - } - - return theResult; -} - -inline FLOAT EvaluateBezierKeyframe(FLOAT inTime, FLOAT inTime1, FLOAT inValue1, FLOAT inC1Time, - FLOAT inC1Value, FLOAT inC2Time, FLOAT inC2Value, FLOAT inTime2, - FLOAT inValue2) -{ - - // The special case of C1Time=0 and C2Time=0 is used to indicate Studio-native animation. - // Studio uses a simplified version of the bezier animation where the time control points - // are equally spaced between the starting and ending times. This avoids calling the expensive - // InverseBezierCurve function to find the right 's' given 't'. - FLOAT theParameter; - if (inC1Time == 0 && inC2Time == 0) { - // Special case signaling that it's ok to treat time as "s" - // This is done by assuming that Key1Val,Key1C1,Key1C2,Key2Val (aka P0,P1,P2,P3) - // are evenly distributed over time. - theParameter = (inTime - inTime1) / (inTime2 - inTime1); - } else { - // Compute the "s" parameter on the Bezier given the time - theParameter = EvaluateInverseBezierCurve(inTime1, inC1Time, inC2Time, inTime2, inTime); - if (theParameter <= 0.0f) - return inValue1; - if (theParameter >= 1.0f) - return inValue2; - } - - return EvaluateBezierCurve(inValue1, inC1Value, inC2Value, inValue2, theParameter); -} -} diff --git a/src/Runtime/Source/System/Include/Qt3DSBoundingBox.h b/src/Runtime/Source/System/Include/Qt3DSBoundingBox.h deleted file mode 100644 index 988a9ba8..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSBoundingBox.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSVector3.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class RuntimeMatrix; - -//============================================================================== -/** - * Axis aligned 3D bounding box construction and manipulation. - * - * Initial construction creates an inverted box signifying an Empty box instead - * of an infinitely small box at 0,0,0. Keep this in mind when asking for - * Min or max on a box that has had no points added to it. - * - * Transforming a box simply transforms all eight corners to span a new - * axis aligned bounding box. Successive transformations can thus create a - * non-optimal box, much larger than needed. - */ -class CBoundingBox -{ - //============================================================================== - // Fields - //============================================================================== -public: - RuntimeVector3 m_Min; ///< box minimum corner point - RuntimeVector3 m_Max; ///< box maximum corner point - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CBoundingBox(); - -public: // Functions - BOOL IsEmpty() const; - void SetEmpty(); - void Add(const RuntimeVector3 &inPoint); - void Add(const CBoundingBox &inBox); - const RuntimeVector3 &GetMin() const; - const RuntimeVector3 &GetMax() const; - void Transform(const RuntimeMatrix &inMatrix); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSCircularArray.h b/src/Runtime/Source/System/Include/Qt3DSCircularArray.h deleted file mode 100644 index be921673..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSCircularArray.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Circular array. Not growable for now. - * The "streamlined" interface acts like a resource pool where construction of - * item T is minimized. - */ -template -class CCircularArray -{ - //============================================================================== - // Types - //============================================================================== -public: - typedef T TType; ///< Easy access to template type - - //============================================================================== - // Fields - //============================================================================== -protected: - CHAR m_Name[32]; ///< Allows easy ID if it grows too much - T *m_Data; ///< Allocated memory containing array data - INT32 m_Capacity; ///< Max number of elements possible - INT32 m_Count; ///< Current number of elements in array - - INT32 m_Begin; ///< circular list indices - INT32 m_End; ///< circular list indices - - // For 32-bit alignment - BOOL m_Full; ///< flag to indicate circular list is full - BOOL m_Paddings[3]; ///< Padding - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - inline CCircularArray(const INT32 inCapacity = 0, const CHAR *inName = NULL); - inline ~CCircularArray(); - -public: // Management - inline INT32 GetCount() const; - inline INT32 GetCapacity() const; - inline void Clear(const BOOL inRelease = false); - inline void Reserve(const INT32 inCapacity); - -public: // Stack access - inline T &NewEntry(); - inline void Pop(); - inline T &Top(); - -public: // Status - BOOL IsEmpty() const; - BOOL IsFull() const; - -protected: // Internal methods - void Increment(INT32 &outIndex); - void Decrement(INT32 &outIndex); - void UpdateFullStatus(); -}; - -} // namespace Q3DStudio - -//============================================================================== -// Template code -//============================================================================== -#include "Qt3DSCircularArray.inl" diff --git a/src/Runtime/Source/System/Include/Qt3DSCircularArray.inl b/src/Runtime/Source/System/Include/Qt3DSCircularArray.inl deleted file mode 100644 index 0d7f081f..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSCircularArray.inl +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2007 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - */ -template inline -CCircularArray::CCircularArray( const INT32 inCapacity, const CHAR* inName ) : - m_Data( NULL ), - m_Capacity( 0 ), - m_Count( 0 ), - m_Begin( 0 ), - m_End( 0 ), - m_Full( false ) -{ - Q3DStudio_sprintf( m_Name, sizeof( m_Name ), "%s", inName ? inName : "CircularArray" ); - Reserve( inCapacity ); -} - -//============================================================================== -/** - * Destructor - */ -template inline -CCircularArray::~CCircularArray( ) -{ - Clear( true ); -} - -//============================================================================== -/** - * Get the number of items in the array - * @return the number of items in the array - */ -template inline -INT32 CCircularArray::GetCount( ) const -{ - return m_Count; -} - -//============================================================================== -/** - * Get the capacity of the array - * @return the capacity of the array - */ -template inline -INT32 CCircularArray::GetCapacity( ) const -{ - return m_Capacity; -} - -//============================================================================== -/** - * Remove all items from the array - * @param inRelease if true, release the allocated memory, if false, reset - * parameters back to zero. - */ -template inline -void CCircularArray::Clear( const BOOL inRelease ) -{ - m_Count = 0; - m_Begin = 0; - m_End = 0; - m_Full = false; - - if ( inRelease ) - { - Q3DStudio_free( m_Data, T, m_Capacity ); - m_Capacity = 0; - m_Data = NULL; - } -} - -//============================================================================== -/** - * Change capacity of the array - * Assume no expansion for circular array - * @param inCapacity the new capacity to set - */ -template inline -void CCircularArray::Reserve( const INT32 inCapacity ) -{ - Q3DStudio_ASSERT( !m_Data ); - T* theData = Q3DStudio_allocate_desc( T, inCapacity, m_Name ); - m_Data = theData; - m_Capacity = inCapacity; -} - -//============================================================================== -/** - * Create a new uninitialized item at the end of the array. - * The returned reference is used to initialize the item. - * @return a reference to the item - */ -template inline -T& CCircularArray::NewEntry( ) -{ - Q3DStudio_ASSERT( !IsFull( ) ); - T& theResult = m_Data[m_End]; - Increment( m_End ); - UpdateFullStatus( ); - ++m_Count; - return theResult; -} - -//============================================================================== -/** - * Remove the top entry from the array - */ -template inline -void CCircularArray::Pop( ) -{ - Q3DStudio_ASSERT( !IsEmpty( ) ); - Increment( m_Begin ); - m_Full = false; - --m_Count; -} - -//============================================================================== -/** - * Get the top item from the - * @return a reference to the item - */ -template inline -T& CCircularArray::Top( ) -{ - Q3DStudio_ASSERT( !IsEmpty( ) ); - return m_Data[m_Begin]; -} - -//============================================================================== -/** - * Check if the array is empty - * @return true if empty, false otherwise. - */ -template inline -BOOL CCircularArray::IsEmpty( ) const -{ - return ( m_Begin == m_End ) && !m_Full; -} - -//============================================================================== -/** - * Check if the array is full - * @return true if full, false otherwise. - */ -template inline -BOOL CCircularArray::IsFull( ) const -{ - return m_Full; -} - -//============================================================================== -/** - * Increment index of the array - * @param outIndex the index to increment - */ -template inline -void CCircularArray::Increment( INT32& outIndex ) -{ - ++outIndex; - // circular list wrap-around - if ( outIndex >= m_Capacity ) - outIndex = 0; -} - -//============================================================================== -/** - * Decrement index of the array - * @param outIndex the index to decrement - */ -template inline -void CCircularArray::Decrement( INT32& outIndex ) -{ - --outIndex; - // circular list wrap-around - if ( outIndex < 0 ) - outIndex = m_Capacity - 1; -} - -//============================================================================== -/** - * Update the status of the m_Full flag. - * This is an internal method for use ONLY AFTER a item has been added to the array. - */ -template inline -void CCircularArray::UpdateFullStatus( ) -{ - m_Full = ( m_End == m_Begin ); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSColor.h b/src/Runtime/Source/System/Include/Qt3DSColor.h deleted file mode 100644 index b917f46b..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSColor.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Express a color and transparency using 32 bits. - */ -class CColor -{ - //============================================================================== - // Fields - //============================================================================== -public: - union { - UINT32 m_Color; ///< 32bit representation of the color - struct - { - UINT8 m_Red; ///< Red component 0-255 - UINT8 m_Green; ///< Green component 0-255 - UINT8 m_Blue; ///< Blue component 0-255 - UINT8 m_Alpha; ///< Transparency component 0-255 - }; - }; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CColor(const UINT32 inColor); - CColor(const UINT8 inRed = 255, const UINT8 inGreen = 255, const UINT8 inBlue = 255, - const UINT8 inAlpha = 255); - -public: // Setters - void SetColor(const UINT32 inColor) { m_Color = inColor; } - void SetRed(const UINT8 inRed) { m_Red = inRed; } - void SetGreen(const UINT8 inGreen) { m_Green = inGreen; } - void SetBlue(const UINT8 inBlue) { m_Blue = inBlue; } - void SetAlpha(const UINT8 inAlpha) { m_Alpha = inAlpha; } - -public: // Getters - UINT32 GetColor() const { return m_Color; } - UINT8 GetRed() const { return m_Red; } - UINT8 GetGreen() const { return m_Green; } - UINT8 GetBlue() const { return m_Blue; } - UINT8 GetAlpha() const { return m_Alpha; } - -public: // Utilities - void Interpolate(const CColor &inColor1, const CColor &inColor2, const FLOAT inFactor); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSConfig.h b/src/Runtime/Source/System/Include/Qt3DSConfig.h deleted file mode 100644 index 49c644da..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSConfig.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// This file should only contain macros that configure the build environment -// and build options. -//============================================================================== -#include "Qt3DSMemorySettings.h" - -/// Number of chars to evaluate when generating a hash from a string. -/// Verify that hash strings are unique after changing this value. -#ifndef HASH_LIMIT -#define HASH_LIMIT 100 -#endif // HASH_LIMIT - -/// Define this macro use use sync primitives(mutex/critical sections) when accessing -/// shared data structures -#ifndef Q3DStudio_USE_SYNC_PRIMITIVES -#define Q3DStudio_USE_SYNC_PRIMITIVES 1 -#endif // Q3DStudio_USE_SYNC_PRIMITIVES diff --git a/src/Runtime/Source/System/Include/Qt3DSCubicRoots.h b/src/Runtime/Source/System/Include/Qt3DSCubicRoots.h deleted file mode 100644 index b5ac0530..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSCubicRoots.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Wrapper class to functions that solve cubic equations. - * - * The function suite is taken from Graphics Gems: - * Roots3And4.c - * - * Utility functions to find cubic and quartic roots, - * coefficients are passed like this: - * - * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0 - * - * The functions return the number of non-complex roots and - * put the values into the s array. - * - * Author: Jochen Schwarze (schwarze@isa.de) - * - * Jan 26, 1990 Version for Graphics Gems - * Oct 11, 1990 Fixed sign problem for negative q's in SolveQuartic - * (reported by Mark Podlipec), - * Old-style function definitions, - * IsZero() as a macro - * Nov 23, 1990 Some systems do not declare acos() and cbrt() in - * , though the functions exist in the library. - * If large coefficients are used, EQN_EPS should be - * reduced considerably (e.g. to 1E-30), results will be - * correct but multiple roots might be reported more - * than once. - */ -class CCubicRoots -{ - //============================================================================== - // Methods - //============================================================================== -public: - static INT32 SolveQuadric(FLOAT inConstants[3], FLOAT outSolutions[2]); - static INT32 SolveCubic(FLOAT inConstants[4], FLOAT outSolutions[3]); - // static int SolveQuartic( FLOAT c[5], FLOAT s[4] ); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSCubicRootsImpl.h b/src/Runtime/Source/System/Include/Qt3DSCubicRootsImpl.h deleted file mode 100644 index 8cca59f9..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSCubicRootsImpl.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants used by the functions -//============================================================================== -const FLOAT M_PHI = 3.14159265358979323846f; - -/* epsilon surrounding for near zero values */ -const FLOAT EQN_EPS = 1e-9f; - -#define ISZERO(x) ((x) > -EQN_EPS && (x) < EQN_EPS) - -// cube-root -#ifndef CUBEROOT -#define CUBEROOT(x) \ - ((x) > 0.0 ? static_cast(pow((x), 1.0f / 3.0f)) \ - : ((x) < 0.0 ? -static_cast(pow(-(x), 1.0f / 3.0f)) : 0.0f)) -#endif - -//============================================================================== -/** - * Find the root/s to a quadratic equation. - * - * The equation is of the form: c[2]*x^2 + c[1]*x + c[0] = 0 - * Note that this will fail if c[2] is zero, or this is a linear equation. - * - * @param inConstants The array of constants to the equation; see form above - * @param outSolutions The array of solutions to the equation - * @return the number of solutions for the equation - */ -INT32 CCubicRoots::SolveQuadric(FLOAT inConstants[3], FLOAT outSolutions[2]) -{ -#ifdef _PERF_LOG - PerfLogMathEvent1 thePerfLog(DATALOGGER_CUBICROOT); -#endif - FLOAT theP, theQ, theD; - INT32 theResult = 0; - - /* normal form: x^2 + px + theQ = 0 */ - - theP = inConstants[1] / (2 * inConstants[2]); - theQ = inConstants[0] / inConstants[2]; - - theD = theP * theP - theQ; - - if (ISZERO(theD)) { - outSolutions[0] = -theP; - theResult = 1; - } else if (theD < 0.0f) { - theResult = 0; - } else if (theD > 0.0f) { - FLOAT theSquareRootD = sqrtf(theD); - - outSolutions[0] = theSquareRootD - theP; - outSolutions[1] = -theSquareRootD - theP; - theResult = 2; - } - - return theResult; -} - -//============================================================================== -/** - * Find the root/s to a cubic equation. - * - * The equation is of the form: c[3]*x^3 + c[2]*x^2 + c[1]*x + c[0] = 0 - * Note that this will fail if c[3] is zero, or this is a quadratic equation. - * - * @param inConstants The array of constants to the equation; see form above - * @param outSolutions The array of solutions to the equation - * @return the number of solutions for the equation - */ -INT32 CCubicRoots::SolveCubic(FLOAT inConstants[4], FLOAT outSolutions[3]) -{ -#ifdef _PERF_LOG - PerfLogMathEvent1 thePerfLog(DATALOGGER_CUBICROOT); -#endif - - INT32 theResult; - FLOAT theSubstitute; - FLOAT theVariableA, theVariableB, theVariableC; - FLOAT theASquared, theVariableP, theVariableQ; - FLOAT thePCubed, theVariableD; - - /* normal form: x^3 + Ax^2 + Bx + C = 0 */ - - theVariableA = inConstants[2] / inConstants[3]; - theVariableB = inConstants[1] / inConstants[3]; - theVariableC = inConstants[0] / inConstants[3]; - - /* substitute x = y - A/3 to eliminate quadric term: - x^3 +px + q = 0 */ - - theASquared = theVariableA * theVariableA; - theVariableP = 1.0f / 3.0f * (-1.0f / 3.0f * theASquared + theVariableB); - theVariableQ = 1.0f / 2.0f * (2.0f / 27.0f * theVariableA * theASquared - - 1.0f / 3.0f * theVariableA * theVariableB + theVariableC); - - /* use Cardano's formula */ - - thePCubed = theVariableP * theVariableP * theVariableP; - theVariableD = theVariableQ * theVariableQ + thePCubed; - - if (ISZERO(theVariableD)) { - if (ISZERO(theVariableQ)) /* one triple solution */ - { - outSolutions[0] = 0; - theResult = 1; - } else /* one single and one double solution */ - { - FLOAT theVariableU = CUBEROOT(-theVariableQ); - outSolutions[0] = 2.0f * theVariableU; - outSolutions[1] = -theVariableU; - theResult = 2; - } - } else if (theVariableD < 0.0f) /* Casus irreducibilis: three real solutions */ - { - FLOAT thePhi = 1.0f / 3.0f * static_cast(acos(-theVariableQ / sqrtf(-thePCubed))); - FLOAT theVariableT = 2.0f * sqrtf(-theVariableP); - - outSolutions[0] = theVariableT * static_cast(cos(thePhi)); - outSolutions[1] = -theVariableT * static_cast(cos(thePhi + M_PHI / 3.0f)); - outSolutions[2] = -theVariableT * static_cast(cos(thePhi - M_PHI / 3.0f)); - theResult = 3; - } else /* one real solution */ - { - FLOAT theSquareRootD = sqrtf(theVariableD); - FLOAT theVariableU = CUBEROOT(theSquareRootD - theVariableQ); - FLOAT theVariableV = -CUBEROOT(theSquareRootD + theVariableQ); - - outSolutions[0] = theVariableU + theVariableV; - theResult = 1; - } - - /* resubstitute */ - theSubstitute = 1.0f / 3.0f * theVariableA; - - for (INT32 theIndex = 0; theIndex < theResult; ++theIndex) - outSolutions[theIndex] -= theSubstitute; - - return theResult; -} - -}; // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSDLLManager.h b/src/Runtime/Source/System/Include/Qt3DSDLLManager.h deleted file mode 100644 index d670af2e..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSDLLManager.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//============================================================================== -// Includes -//============================================================================== -#pragma once - -#ifdef _PCPLATFORM -#pragma warning(push, 3) -#include -#pragma warning(pop) -#endif - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -#ifdef _PCPLATFORM -typedef HMODULE DLLHANDLE; -#endif - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -typedef void *DLLHANDLE; -#endif - -typedef struct _SDLLInfo -{ - long m_Type; ///< Plugin type - DLLHANDLE m_Handle; ///< DLL handle - - _SDLLInfo() - : m_Type(0) - , m_Handle(NULL) - - { - } - -} SDLLInfo; - -//============================================================================== -/** - * Loads DLLs and queries for DLL functions - */ -class CDLLManager -{ -public: - static CDLLManager &GetDLLManager(); - -protected: - CDLLManager(); - virtual ~CDLLManager(); - -public: - long LoadLibrary(const char *inLibraryPath, long inPluginType); - void UnloadLibrary(const long inHandle); - void *GetProc(const char *inProcName, long inHandle); - template - EEnumType GetPluginType(long inHandle); - void Cleanup(); - -protected: - void *GetProc(const char *inProcName, const DLLHANDLE inHandle); - -protected: - CArray m_LoadedLibraries; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSDataLogger.h b/src/Runtime/Source/System/Include/Qt3DSDataLogger.h deleted file mode 100644 index b834edab..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSDataLogger.h +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _DATA_LOGGER_H_ -#define _DATA_LOGGER_H_ - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTypes.h" -#include "Qt3DSDataLoggerEnums.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -typedef TTimeUnit TDataLoggerTimeUnit; - -//============================================================================== -/** -* The structure that holds all the info we collect -*/ -struct SPerfLogEntry -{ - UINT32 m_EntryEnum : 31; - UINT32 m_StartBool : 1; - - TDataLoggerTimeUnit m_Time; - - SPerfLogEntry(UINT32 inEntryEnum, BOOL inStartFlag, TDataLoggerTimeUnit inTime) - : m_EntryEnum(inEntryEnum) - , m_StartBool(inStartFlag ? 1U : 0U) - , m_Time(inTime) - { - // Make sure our enums never use the high bit - Q3DStudio_ASSERT(false == (inEntryEnum & (1 << 31))); - } -}; - -//============================================================================== -/** -* The stack based helper class that wraps the actually logging of start and end messages -* for use with start/end time logging. -*/ -template -class CPerfLogPairedEventWrapper -{ -public: - typedef void (*TLogEntryInternal)(UINT32 inEntryEnum, BOOL inStartFlag); - -private: - UINT32 m_EntryEnum; - static TLogEntryInternal m_InternalLogFunc; - -private: - static void LogEntry(UINT32 inEntryEnum, BOOL inStartFlag); - -public: - CPerfLogPairedEventWrapper(UINT32 inEntryEnum); - ~CPerfLogPairedEventWrapper(); - - static void Enable(); - static void Disable(); -}; - -//============================================================================== -/** -*/ -class CPerfLogPairedEventWrapperDummy -{ -public: - CPerfLogPairedEventWrapperDummy(UINT32 /*inEntryEnum*/) {} - ~CPerfLogPairedEventWrapperDummy() {} -}; - -// Dummy structs, so we get one 'type' of class per log event -// so we can turn things on and off -struct SPerfLogGeneralEvent1 -{ -}; -struct SPerfLogGeneralEvent2 -{ -}; - -struct SPerfLogRenderEvent1 -{ -}; -struct SPerfLogSceneEvent1 -{ -}; - -struct SPerfLogMathEvent1 -{ -}; -struct SPerfLogPresentationEvent1 -{ -}; -struct SPerfLogRenderEvent2 -{ -}; - -// level 0 -// no profiling at all... - -// level 1 -typedef CPerfLogPairedEventWrapper - TPerfLogGeneralEvent1; // Frame, update presentations, update scene, render scene -typedef CPerfLogPairedEventWrapper - TPerfLogGeneralEvent2; // Event processing and manager updates, -// call frame and slide callbacks, -// opaque, transparent, layer render, finalize drawlist and pick -// level 2 -typedef CPerfLogPairedEventWrapper - TPerfLogRenderEvent1; // More detailed rendering -typedef CPerfLogPairedEventWrapper - TPerfLogSceneEvent1; // More detailed scene update - -// level 3 -typedef CPerfLogPairedEventWrapper TPerfLogMathEvent1; // vector and matrix math -typedef CPerfLogPairedEventWrapper - TPerfLogPresentationEvent1; // More detailed scene update -typedef CPerfLogPairedEventWrapper TPerfLogRenderEvent2; // - -// Defines -#ifdef _PERF_LOG -#define PerfLogGeneralEvent1(inEventID) TPerfLogGeneralEvent1 thePerfLog(inEventID); -#define PerfLogGeneralEvent2(inEventID) TPerfLogGeneralEvent2 thePerfLog(inEventID); - -#define PerfLogRenderEvent1(inEventID) TPerfLogRenderEvent1 thePerfLog(inEventID); -#define PerfLogSceneEvent1(inEventID) TPerfLogSceneEvent1 thePerfLog(inEventID); - -#define PerfLogMathEvent1(inEventID) TPerfLogMathEvent1 thePerfLog(inEventID); -#define PerfLogPresentationEvent1(inEventID) TPerfLogPresentationEvent1 thePerfLog(inEventID); -#define PerfLogRenderEvent2(inEventID) TPerfLogRenderEvent2 thePerfLog(inEventID); -#else -#define PerfLogGeneralEvent1(inEventID) -#define PerfLogGeneralEvent2(inEventID) - -#define PerfLogRenderEvent1(inEventID) -#define PerfLogSceneEvent1(inEventID) - -#define PerfLogMathEvent1(inEventID) -#define PerfLogPresentationEvent1(inEventID) -#define PerfLogRenderEvent2(inEventID) -#endif - -//============================================================================== -/** -*/ -class CDataLogger -{ -private: - // App level function to write this out to a stream/file... set externally - typedef void (*TDataLoggerWriteFunc)(void *inUserData, SPerfLogEntry inEntry); - typedef TDataLoggerTimeUnit (*TGetTimeFunc)(void *inUserData); - -public: - struct SExternalFunctors - { - void *m_UserData; - TDataLoggerWriteFunc m_WriteFunc; - TGetTimeFunc m_GetTimeFunc; - - SExternalFunctors() - : m_UserData(NULL) - , m_WriteFunc(NULL) - , m_GetTimeFunc(NULL) - { - } - }; - - enum EDataLoggerLevel { - LOG_LEVEL_NONE, - LOG_LEVEL_1, - LOG_LEVEL_2, - LOG_LEVEL_3, - LOG_LEVEL_INVALID, // use this if you want to selectively enable or disable loggers - }; - -private: - static SExternalFunctors m_Functors; - static EDataLoggerLevel m_LogLevel; - static BOOL m_Enabled; - -public: - static void SetFunctors(SExternalFunctors inFunctors); - static void LogEntry(UINT32 inEntryEnum, BOOL inStartFlag); - static void Enable(); - static void Disable(); - - static void SetLogLevel(EDataLoggerLevel inLogLevel); -}; - -} // namespace Q3DStudio - -#include "Qt3DSDataLogger.hpp" - -#endif // _DATA_LOGGER_H_ diff --git a/src/Runtime/Source/System/Include/Qt3DSDataLogger.hpp b/src/Runtime/Source/System/Include/Qt3DSDataLogger.hpp deleted file mode 100644 index 0900c4a4..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSDataLogger.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSDataLogger.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** -* Constructor -*/ -template -CPerfLogPairedEventWrapper::CPerfLogPairedEventWrapper(UINT32 inEntryEnum) - : m_EntryEnum(inEntryEnum) -{ - if (m_InternalLogFunc) - m_InternalLogFunc(m_EntryEnum, true); -} - -//============================================================================== -/** -* Destructor -*/ -template -CPerfLogPairedEventWrapper::~CPerfLogPairedEventWrapper() -{ - if (m_InternalLogFunc) - m_InternalLogFunc(m_EntryEnum, false); -} - -//============================================================================== -/** -* Logger functions -*/ -template -void CPerfLogPairedEventWrapper::LogEntry(UINT32 inEntryEnum, BOOL inStartFlag) -{ - CDataLogger::LogEntry(inEntryEnum, inStartFlag); -} - -//============================================================================== -/** - * Enable logging - */ -template -void CPerfLogPairedEventWrapper::Enable() -{ - m_InternalLogFunc = LogEntry; -} - -//============================================================================== -/** -* Disable logging -*/ -template -void CPerfLogPairedEventWrapper::Disable() -{ - m_InternalLogFunc = NULL; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSDataLoggerEnums.h b/src/Runtime/Source/System/Include/Qt3DSDataLoggerEnums.h deleted file mode 100644 index 27320e19..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSDataLoggerEnums.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef _DATA_LOGGER_ENUMS_H_ -#define _DATA_LOGGER_ENUMS_H_ - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -// TODO ah - for now, these are all specific to paired events. Later we will -// extend this to support single events which may or may not have timestamps -// for example, every matrix multiple would log a single event with no time -enum EDataLoggerEvents { - // - DATALOGGER_FRAME, /// Time spent in a application frame ( UpdatePresentations, UpdateScenes, and - /// Render ) - - // DATALOGGER_FRAME - // CRuntime - DATALOGGER_UPDATEPRESENTATIONS, /// Time spent updating all presentations - DATALOGGER_UPDATESCENES, /// Time spent updating all scenes - DATALOGGER_RENDERSCENES, /// Time spent rendering all scenes - - // DATALOGGER_UPDATEPRESENTATIONS - // CPresentation::Update - DATALOGGER_PROCESSEVENTS, /// Time spent in ProcessEventCommandQueue - DATALOGGER_ELEMENTMANAGERUPDATE, /// Time spent in CElementManager::Update doing activate and - /// deactivate scans - DATALOGGER_ANIMATIONMANAGERUPDATE, /// Time spent in CAnimationManager::Update - - // More detailed presentation update - DATALOGGER_PROCESSCOMMAND, /// xxx - DATALOGGER_PROCESSEVENT, /// xxx - DATALOGGER_PROCESSEVENTBUBBLING, /// xxx - - // DATALOGGER_UPDATESCENES - // CScene::Update - DATALOGGER_PROCESSDIRTYLIST, /// Time spent in CScene::ProcessDirtyList - DATALOGGER_CALCULATETRANSFORM, /// Time spent in CScene::CalculateGlobalTransform - DATALOGGER_SCENEUPDATE, /// Time spent in CScene::Update recursion - - // More detailed scene update - DATALOGGER_SCANNODEATTRIBUTES, /// Time - DATALOGGER_PUSHNODE, /// Time - - // DATALOGGER_RENDERSCENES - // CRenderEngine - DATALOGGER_RENDERLAYER, /// Time spent rendering the contents of a layer - DATALOGGER_RENDEROPAQUE, /// Time spent rendering all opaque items - DATALOGGER_RENDERTRANSPARENT, /// Time spent rendering all transparent items - DATALOGGER_FINALIZEDRAWLIST, /// Time spent finalizing the draw list - DATALOGGER_PICK, /// Time spent in pick code - - // More detailed rendering - DATALOGGER_RENDER_SORTDISTANCE, /// asdf - DATALOGGER_RENDER_SETOPACITY, /// asdf - DATALOGGER_RENDER_DRAWMODEL, /// asdf - DATALOGGER_RENDER_DRAWTEXT, /// asdf - DATALOGGER_RENDER_CLEARBUFFER, /// asdf - DATALOGGER_RENDER_ZWRITEENABLE, /// asdf - DATALOGGER_RENDER_CHECKRESIZE, /// asdf - DATALOGGER_RENDER_SETATTRIBUTES, /// asdf - DATALOGGER_RENDER_TEXTUPDATE, /// asdf - DATALOGGER_RENDER_CAMERAUPDATE, /// asdf - - // super specific low level gl calls - DATALOGGER_TEXTURESTATE_APPLY, /// asdf - DATALOGGER_GEOMETRY_DRAW, /// asdf - DATALOGGER_MATERIAL_APPLY, /// asdf - DATALOGGER_SETSHADER, /// asdf - - // vector math - DATALOGGER_VECTOR, /// asdf - DATALOGGER_MATRIX, /// asdf - DATALOGGER_CUBICROOT, /// asdf - - // - DATALOGGER_COUNTERTEST, /// Time spent in counter test code - DATALOGGER_COUNTERTESTX, /// Time spent in counter test code - - DATALOGGEREVENTCOUNT /// Event count -}; - -// CPerfLogPairedEventWrapperx thePerfLog( xxx ); - -} // namespace Q3DStudio - -#endif // _DATA_LOGGER_ENUMS_H_ diff --git a/src/Runtime/Source/System/Include/Qt3DSDataLoggerViewer.h b/src/Runtime/Source/System/Include/Qt3DSDataLoggerViewer.h deleted file mode 100644 index 0eaf9f6a..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSDataLoggerViewer.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AKDATALOGGERVIEWER_H_INCLUDED -#define AKDATALOGGERVIEWER_H_INCLUDED - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTypes.h" -#include "Qt3DSDataLogger.h" -#include "Qt3DSDataLoggerEnums.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { -// Helps interpret and analyse data logger entries -class CDataLoggerViewer -{ -public: - typedef CArray TPerfLogEntryList; - -public: - CDataLoggerViewer(TPerfLogEntryList *inPerfLogEntryList); - CDataLoggerViewer(const char *inFilename); - virtual ~CDataLoggerViewer(); - -public: - float GetAverageTimeInMsForEntry(enum EDataLoggerEvents inEventType); - void ResetPerfLogEntry(enum EDataLoggerEvents inEventType); - void ResetAllEntries(); - -public: - static bool ProcessKeyEvent(char inKey, TPerfLogEntryList *inList); - -protected: - TPerfLogEntryList *m_PerfLogEntryList; - bool m_Dispose; -}; - -} // namespace NVUI - -#endif // AKDATALOGGERVIEWER_H_INCLUDED diff --git a/src/Runtime/Source/System/Include/Qt3DSEGLTimer.h b/src/Runtime/Source/System/Include/Qt3DSEGLTimer.h deleted file mode 100644 index 4c9f4ce2..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSEGLTimer.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSTimer.h" -#include "Qt3DSTypes.h" - -// You have to include egl before including this file. - -typedef EGLuint64NV(EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void); -typedef EGLuint64NV(EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void); -extern EGLuint64NV eglSystemTimeFrequency; -extern PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC eglGetSystemTimeFrequencyNVProc; -extern PFNEGLGETSYSTEMTIMENVPROC eglGetSystemTimeNVProc; - -namespace Q3DStudio { - -struct SEGLTimeProvider : public Q3DStudio::ITimeProvider -{ -public: - Q3DStudio::INT64 m_TimeFrequency; - SEGLTimeProvider() - : m_TimeFrequency(0) - { - } - virtual Q3DStudio::INT64 GetCurrentTimeMicroSeconds() - { - // This can be called before EGL is initialized. - if (eglGetSystemTimeFrequencyNVProc == NULL || eglGetSystemTimeNVProc == NULL) - return 0; - - if (!m_TimeFrequency) { - // Time frequency converts to seconds. - m_TimeFrequency = eglGetSystemTimeFrequencyNVProc(); - // We need it to conver to microseconds - m_TimeFrequency = m_TimeFrequency / 1000000ULL; - } - Q3DStudio::INT64 currentTime = eglGetSystemTimeNVProc(); - currentTime = currentTime / m_TimeFrequency; - return currentTime; - } -}; -} \ No newline at end of file diff --git a/src/Runtime/Source/System/Include/Qt3DSEndian.h b/src/Runtime/Source/System/Include/Qt3DSEndian.h deleted file mode 100644 index f8913a72..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSEndian.h +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2010 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Constants -//============================================================================== - -#define QT3DS_LITTLE_ENDIAN false -#define QT3DS_BIG_ENDIAN true diff --git a/src/Runtime/Source/System/Include/Qt3DSEulerAngles.h b/src/Runtime/Source/System/Include/Qt3DSEulerAngles.h deleted file mode 100644 index d0f53c56..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSEulerAngles.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -namespace Q3DStudio { -//============================================================================== -// Description -//============================================================================== -// QuatTypes.h - Basic type declarations -// by Ken Shoemake, shoemake@graphics.cis.upenn.edu -// in "Graphics Gems IV", Academic Press, 1994 -typedef struct -{ - float x, y, z, w; -} Quat; /* Quaternion */ -typedef float HMatrix[4][4]; /* Right-handed, for column vectors */ -enum QuatPart { X, Y, Z, W }; -typedef Quat EulerAngles; /* (x,y,z)=ang 1,2,3, w=order code */ - -#define EulFrmS 0 -#define EulFrmR 1 -#define EulFrm(ord) ((unsigned)(ord)&1) -#define EulRepNo 0 -#define EulRepYes 1 -#define EulRep(ord) (((unsigned)(ord) >> 1) & 1) -#define EulParEven 0 -#define EulParOdd 1 -#define EulPar(ord) (((unsigned)(ord) >> 2) & 1) -#define EulSafe "\000\001\002\000" -#define EulNext "\001\002\000\001" -#define EulAxI(ord) ((int)(EulSafe[(((unsigned)(ord) >> 3) & 3)])) -#define EulAxJ(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) == EulParOdd)])) -#define EulAxK(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) != EulParOdd)])) -#define EulAxH(ord) ((EulRep(ord) == EulRepNo) ? EulAxK(ord) : EulAxI(ord)) - -// EulGetOrd unpacks all useful information about order simultaneously. -#define EulGetOrd(ord, i, j, k, h, n, s, f) \ - { \ - unsigned o = ord; \ - f = o & 1; \ - o = o >> 1; \ - s = o & 1; \ - o = o >> 1; \ - n = o & 1; \ - o = o >> 1; \ - i = EulSafe[o & 3]; \ - j = EulNext[i + n]; \ - k = EulNext[i + 1 - n]; \ - h = s ? k : i; \ - } - -// EulOrd creates an order value between 0 and 23 from 4-tuple choices. -#define EulOrd(i, p, r, f) (((((((i) << 1) + (p)) << 1) + (r)) << 1) + (f)) - -// Static axes -// X = 0, Y = 1, Z = 2 ref QuatPart -#define EulOrdXYZs EulOrd(0, EulParEven, EulRepNo, EulFrmS) -#define EulOrdXYXs EulOrd(0, EulParEven, EulRepYes, EulFrmS) -#define EulOrdXZYs EulOrd(0, EulParOdd, EulRepNo, EulFrmS) -#define EulOrdXZXs EulOrd(0, EulParOdd, EulRepYes, EulFrmS) -#define EulOrdYZXs EulOrd(1, EulParEven, EulRepNo, EulFrmS) -#define EulOrdYZYs EulOrd(1, EulParEven, EulRepYes, EulFrmS) -#define EulOrdYXZs EulOrd(1, EulParOdd, EulRepNo, EulFrmS) -#define EulOrdYXYs EulOrd(1, EulParOdd, EulRepYes, EulFrmS) -#define EulOrdZXYs EulOrd(2, EulParEven, EulRepNo, EulFrmS) -#define EulOrdZXZs EulOrd(2, EulParEven, EulRepYes, EulFrmS) -#define EulOrdZYXs EulOrd(2, EulParOdd, EulRepNo, EulFrmS) -#define EulOrdZYZs EulOrd(2, EulParOdd, EulRepYes, EulFrmS) - -// Rotating axes -#define EulOrdZYXr EulOrd(0, EulParEven, EulRepNo, EulFrmR) -#define EulOrdXYXr EulOrd(0, EulParEven, EulRepYes, EulFrmR) -#define EulOrdYZXr EulOrd(0, EulParOdd, EulRepNo, EulFrmR) -#define EulOrdXZXr EulOrd(0, EulParOdd, EulRepYes, EulFrmR) -#define EulOrdXZYr EulOrd(1, EulParEven, EulRepNo, EulFrmR) -#define EulOrdYZYr EulOrd(1, EulParEven, EulRepYes, EulFrmR) -#define EulOrdZXYr EulOrd(1, EulParOdd, EulRepNo, EulFrmR) -#define EulOrdYXYr EulOrd(1, EulParOdd, EulRepYes, EulFrmR) -#define EulOrdYXZr EulOrd(2, EulParEven, EulRepNo, EulFrmR) -#define EulOrdZXZr EulOrd(2, EulParEven, EulRepYes, EulFrmR) -#define EulOrdXYZr EulOrd(2, EulParOdd, EulRepNo, EulFrmR) -#define EulOrdZYZr EulOrd(2, EulParOdd, EulRepYes, EulFrmR) - -#ifndef M_PI -#define M_PI 3.1415926535898 -#endif - -#define TODEG(x) x = (float)(x * 180 / M_PI); -#define TORAD(x) x = (float)(x / 180 * M_PI); - -class CEulerAngleConverter -{ -private: - char m_OrderInfoBuffer[1024]; - -public: - CEulerAngleConverter(); - virtual ~CEulerAngleConverter(); - -public: - EulerAngles Eul_(float ai, float aj, float ah, int order); - Quat Eul_ToQuat(EulerAngles ea); - void Eul_ToHMatrix(EulerAngles ea, HMatrix M); - EulerAngles Eul_FromHMatrix(HMatrix M, int order); - EulerAngles Eul_FromQuat(Quat q, int order); - - // Debug Stuff - const char *DumpOrderInfo(); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSFNDTimer.h b/src/Runtime/Source/System/Include/Qt3DSFNDTimer.h deleted file mode 100644 index 8241e2ed..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSFNDTimer.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSTimer.h" -#include "Qt3DSTypes.h" -#include "foundation/Qt3DSTime.h" - -namespace Q3DStudio { -class Qt3DSFNDTimer : public ITimeProvider -{ - Q3DStudio::INT64 GetCurrentTimeMicroSeconds() override - { - return qt3ds::foundation::Time::getCurrentTimeInTensOfNanoSeconds() / 100; - } -}; -} diff --git a/src/Runtime/Source/System/Include/Qt3DSFile.h b/src/Runtime/Source/System/Include/Qt3DSFile.h deleted file mode 100644 index e970cd2d..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSFile.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTypes.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Single overridable exit point for all low level file calls. - */ -class CFile -{ - //============================================================================== - // Typedefs - //============================================================================== -public: - typedef enum _E_SEEK { - E_SEEK_SET = SEEK_SET, - E_SEEK_CUR = SEEK_CUR, - E_SEEK_END = SEEK_END - } E_SEEK; - - typedef TFile *(*TOpen)(const char *inFileName, const char *inMode); - typedef int (*TClose)(TFile *inFile); - typedef TFileSize (*TRead)(void *inBuffer, TFileSize inSize, TFileSize inCount, TFile *inFile); - typedef TFileSize (*TWrite)(const void *inBuffer, TFileSize inSize, TFileSize inCount, - TFile *inFile); - typedef long (*TTell)(TFile *inFile); - typedef int (*TSeek)(TFile *inFile, long inOffset, int inOrigin); - - //============================================================================== - // Fields - //============================================================================== -protected: - static TOpen s_Open; ///< function pointer to fopen operation - static TClose s_Close; ///< function pointer to fclose operation - static TRead s_Read; ///< function pointer to fread operation - static TWrite s_Write; ///< function pointer to fwrite operation - static TTell s_Tell; ///< function pointer to ftell operation - static TSeek s_Seek; ///< function pointer to fseek operation - - //============================================================================== - // Methods - //============================================================================== -public: // Memory override - static void SetFileFunctions(const TOpen inOpen, const TClose inClose, const TRead inRead, - const TWrite inWrite, const TTell inTell, const TSeek inSeek); - -public: // Function access - static TOpen Open() { return s_Open; } - static TClose Close() { return s_Close; } - static TRead Read() { return s_Read; } - static TWrite Write() { return s_Write; } - static TTell Tell() { return s_Tell; } - static TSeek Seek() { return s_Seek; } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSFileStream.h b/src/Runtime/Source/System/Include/Qt3DSFileStream.h deleted file mode 100644 index 49e272f4..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSFileStream.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSIFileStream.h" -#include "Qt3DSArray.h" -#include "Qt3DSEndian.h" - -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * File stream base class. - */ -class CFileStream : public IFileStream -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CFileStream(const CHAR *inFilePath = NULL, const CHAR *inMode = "rb", - BOOL inKeepTrying = false); - virtual ~CFileStream(); - -public: // Serializing - INT32 ReadRawCopy(void *inDestination, const UINT32 inByteCount) override; - INT32 ReadRaw(const void *&inPtr, const UINT32 inByteCount) override; - INT32 WriteRaw(const void *inSource, const UINT32 inByteCount) override; - - // Seeking - void Offset(const INT32 inOffset) override; - TStreamPosition Current() override; - void Set(const TStreamPosition &inPosition) override; - -public: // File Operation - void Open(const CHAR *inFilePath, const CHAR *inMode) override; - void Close() override; - BOOL IsOpen() const override; - const CHAR *GetFilePath() const override; - -public: // Endianess - void SetEndian(const BOOL inEndian); - BOOL GetEndian(); - - //============================================================================== - // Fields - //============================================================================== -protected: - TFile *m_FileStream; - QString m_FilePath; - CArray m_TempBuffer; - BOOL m_Endian; - BOOL m_KeepTrying; - CHAR m_Unused[2]; ///< (padding) -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSFixedArray.h b/src/Runtime/Source/System/Include/Qt3DSFixedArray.h deleted file mode 100644 index 9f971d81..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSFixedArray.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Fixed size Ordered Collection that doesn't support growing. - */ -template -class CFixedArray -{ - //============================================================================== - // Typedefs - //============================================================================== -public: - typedef T TType; ///< Easy access to template type - - //============================================================================== - // Fields - //============================================================================== -protected: - T m_Data[Size]; ///< Allocated memory containing array data - INT32 m_Capacity; ///< Max number of elements possible - INT32 m_Count; ///< Current number of elements in array - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - inline CFixedArray(); - inline ~CFixedArray(); - -public: // Management - inline void Clear(); - inline INT32 GetCount() const; - inline INT32 GetCapacity() const; - -public: // Stack access - inline void Push(const T &inValue); - inline const T &Pop(); - -public: // Array access - inline T &operator[](const INT32 inIndex); - inline void Remove(const INT32 inIndex); -}; - -} // namespace Q3DStudio - -//============================================================================== -// Template code -//============================================================================== -#include "Qt3DSFixedArray.inl" diff --git a/src/Runtime/Source/System/Include/Qt3DSFixedArray.inl b/src/Runtime/Source/System/Include/Qt3DSFixedArray.inl deleted file mode 100644 index 55242243..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSFixedArray.inl +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1999-2007 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - */ -template -inline CFixedArray::CFixedArray() - : m_Capacity(Size) - , m_Count(0) -{ -} - -//============================================================================== -/** - * Destructor - */ -template -inline CFixedArray::~CFixedArray() -{ -} - -//============================================================================== -/** - * Remove all elements in the array - */ -template -inline void CFixedArray::Clear() -{ - m_Count = 0; -} - -//============================================================================== -/** - * Get current count of T in the array - * @return current count of the array - */ -template -inline INT32 CFixedArray::GetCount() const -{ - return m_Count; -} - -//============================================================================== -/** - * Get the capacity of the array - * Capacity reflects the allocated memory size - * @return capacity of the array - */ -template -inline INT32 CFixedArray::GetCapacity() const -{ - return m_Capacity; -} - -//============================================================================== -/** - * Insert T to the end of the array - * @param inValue value of datatype T - */ -template -inline void CFixedArray::Push(const T &inValue) -{ - if (m_Count == m_Capacity) { - qWarning("Trying to push to many objects onto a CFixedArray", "Capacity=%d", m_Capacity); - return; - } - - m_Data[m_Count] = inValue; - ++m_Count; -} - -//============================================================================== -/** - * Remove and retrieve T which is at the end of the array - * @return value of datatype T - */ -template -inline const T &CFixedArray::Pop() -{ - if (m_Count == 0) - return {}; - - --m_Count; - return m_Data[m_Count]; -} - -//============================================================================== -/** - * Get T at a particular index position of the array. - * Need to ensure only valid index is allowed - * Clear( ) will set the m_counter = 0 - * @param inIndex the index of the array - * @return reference of value of datatype T - */ -template -inline T &CFixedArray::operator[](const INT32 inIndex) -{ - Q3DStudio_ASSERT(inIndex < m_Capacity); - - return m_Data[inIndex]; -} - -//============================================================================== -/** - * Removes a specific entry from the array. - * Moves all entries below it up, expensive. - * @param inIndex the index of the entry - */ -template -inline void CFixedArray::Remove(const INT32 inIndex) -{ - Q3DStudio_memmove(m_Data + inIndex, m_Data + inIndex + 1, sizeof(T) * (m_Count - inIndex - 1)); - --m_Count; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSFunctionWrappers.h b/src/Runtime/Source/System/Include/Qt3DSFunctionWrappers.h deleted file mode 100644 index 8fff62de..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSFunctionWrappers.h +++ /dev/null @@ -1,416 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2010 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== - -namespace Q3DStudio { - -//============================================================================== -/** -* Interface for a function wrapper with an associated cost. -*/ -class IFunctionWrapper -{ -public: - IFunctionWrapper(); - virtual ~IFunctionWrapper(){} - -public: - virtual void Execute() = 0; - INT32 GetCost(); - void SetCost(const INT32 inCost); - -protected: - INT32 m_Cost; -}; - -//============================================================================== -/** -* 2 arguments function wrapper -*/ -template -class CFunctionWrapper2Args : public IFunctionWrapper -{ -public: - typedef void (*TFunction)(TArg1 inArg1, TArg2 inArg2); - -public: - CFunctionWrapper2Args(TFunction, TArg1 inArg1, TArg2 inArg2); - -public: - virtual void Execute(); - -protected: - TFunction m_Function; - TArg1 m_Arg1; - TArg2 m_Arg2; -}; - -// Unused -/* -template -class CFunctionWrapper3Args : public IFunctionWrapper -{ - public: - typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3 ); - - public: - CFunctionWrapper3Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 -inArg3 ); - - public: - virtual void Execute( ); - - protected: - TFunction m_Function; - TArg1 m_Arg1; - TArg2 m_Arg2; - TArg3 m_Arg3; -}; - -template -class CFunctionWrapper4Args : public IFunctionWrapper -{ - public: - typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4 -); - - public: - CFunctionWrapper4Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 -inArg3, TArg4 inArg4 ); - - public: - virtual void Execute( ); - - protected: - TFunction m_Function; - TArg1 m_Arg1; - TArg2 m_Arg2; - TArg3 m_Arg3; - TArg4 m_Arg4; -}; - -template -class CFunctionWrapper8Args : public IFunctionWrapper -{ - public: - typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4, -TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8 ); - - public: - CFunctionWrapper8Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 -inArg3, TArg4 inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8 ); - - public: - virtual void Execute( ); - - protected: - TFunction m_Function; - TArg1 m_Arg1; - TArg2 m_Arg2; - TArg3 m_Arg3; - TArg4 m_Arg4; - TArg5 m_Arg5; - TArg6 m_Arg6; - TArg7 m_Arg7; - TArg8 m_Arg8; -}; - -template -class CFunctionWrapper9Args : public IFunctionWrapper -{ - public: - typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4, -TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8, TArg9 inArg9 ); - - public: - CFunctionWrapper9Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 -inArg3, TArg4 inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8, TArg9 inArg9 ); - - public: - virtual void Execute( ); - - protected: - TFunction m_Function; - TArg1 m_Arg1; - TArg2 m_Arg2; - TArg3 m_Arg3; - TArg4 m_Arg4; - TArg5 m_Arg5; - TArg6 m_Arg6; - TArg7 m_Arg7; - TArg8 m_Arg8; - TArg9 m_Arg9; -}; -*/ - -//============================================================================== -/** -* 1 argument member function wrapper -*/ -template -class CMemberFunctionWrapper1Args : public IFunctionWrapper -{ -public: - typedef TReturn (TObject::*TFunction)(TArg1 inArg1); - -public: - CMemberFunctionWrapper1Args(TObject *inObject, TFunction inFunction, TArg1 inArg1); - -public: - virtual void Execute(); - -protected: - TFunction m_Function; - TObject *m_Object; - TArg1 m_Arg1; -}; - -//============================================================================== -/** -* 2 argument member function wrapper -*/ -template -class CMemberFunctionWrapper2Args : public IFunctionWrapper -{ -public: - typedef TReturn (TObject::*TFunction)(TArg1 inArg1, TArg2 inArg2); - -public: - CMemberFunctionWrapper2Args(TObject *inObject, TFunction inFunction, TArg1 inArg1, - TArg2 inArg2); - -public: - virtual void Execute(); - -protected: - TFunction m_Function; - TObject *m_Object; - TArg1 m_Arg1; - TArg2 m_Arg2; -}; - -//============================================================================== -/** -* 6 argument member function wrapper -*/ -template -class CMemberFunctionWrapper6Args : public IFunctionWrapper -{ -public: - typedef TReturn (TObject::*TFunction)(TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4, - TArg5 inArg5, TArg6 inArg6); - -public: - CMemberFunctionWrapper6Args(TObject *inObject, TFunction inFunction, TArg1 inArg1, TArg2 inArg2, - TArg3 inArg3, TArg4 inArg4, TArg5 inArg5, TArg6 inArg6); - -public: - virtual void Execute(); - -protected: - TFunction m_Function; - TObject *m_Object; - TArg1 m_Arg1; - TArg2 m_Arg2; - TArg3 m_Arg3; - TArg4 m_Arg4; - TArg5 m_Arg5; - TArg6 m_Arg6; -}; - -// Implementation -template -CFunctionWrapper2Args::CFunctionWrapper2Args(TFunction inFunction, TArg1 inArg1, - TArg2 inArg2) - : m_Function(inFunction) - , m_Arg1(inArg1) - , m_Arg2(inArg2) -{ -} - -template -void CFunctionWrapper2Args::Execute() -{ - m_Function(m_Arg1, m_Arg2); -} - -// Unused -/* -template -CFunctionWrapper3Args::CFunctionWrapper3Args( TFunction inFunction, TArg1 -inArg1, TArg2 inArg2, TArg3 inArg3 ) -: m_Function( inFunction ), - m_Arg1( inArg1 ), - m_Arg2( inArg2 ), - m_Arg3( inArg3 ) -{ -} - -template -void CFunctionWrapper3Args::Execute( ) -{ - m_Function( m_Arg1, m_Arg2, m_Arg3 ); -} - -template -CFunctionWrapper4Args::CFunctionWrapper4Args( TFunction inFunction, -TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4 ) -: m_Function( inFunction ), - m_Arg1( inArg1 ), - m_Arg2( inArg2 ), - m_Arg3( inArg3 ), - m_Arg4( inArg4 ) -{ -} - -template -void CFunctionWrapper4Args::Execute( ) -{ - m_Function( m_Arg1, m_Arg2, m_Arg3, m_Arg4 ); -} - -template -CFunctionWrapper8Args::CFunctionWrapper8Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 -inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8 ) -: m_Function( inFunction ), - m_Arg1( inArg1 ), - m_Arg2( inArg2 ), - m_Arg3( inArg3 ), - m_Arg4( inArg4 ), - m_Arg5( inArg5 ), - m_Arg6( inArg6 ), - m_Arg7( inArg7 ), - m_Arg8( inArg8 ) - -{ -} - -template -void CFunctionWrapper8Args::Execute( ) -{ - m_Function( m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6, m_Arg7, m_Arg8 ); -} - -template -CFunctionWrapper9Args::CFunctionWrapper9Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 -inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8, TArg9 inArg9 ) -: m_Function( inFunction ), - m_Arg1( inArg1 ), - m_Arg2( inArg2 ), - m_Arg3( inArg3 ), - m_Arg4( inArg4 ), - m_Arg5( inArg5 ), - m_Arg6( inArg6 ), - m_Arg7( inArg7 ), - m_Arg8( inArg8 ), - m_Arg9( inArg9 ) -{ -} - -template -void CFunctionWrapper9Args::Execute( -) -{ - m_Function( m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6, m_Arg7, m_Arg8, m_Arg9 ); -} -*/ - -template -CMemberFunctionWrapper1Args::CMemberFunctionWrapper1Args( - TObject *inObject, TFunction inFunction, TArg1 inArg1) - : m_Function(inFunction) - , m_Object(inObject) - , m_Arg1(inArg1) -{ -} - -template -void CMemberFunctionWrapper1Args::Execute() -{ - (m_Object->*m_Function)(m_Arg1); -} - -template -CMemberFunctionWrapper2Args::CMemberFunctionWrapper2Args( - TObject *inObject, TFunction inFunction, TArg1 inArg1, TArg2 inArg2) - : m_Function(inFunction) - , m_Object(inObject) - , m_Arg1(inArg1) - , m_Arg2(inArg2) -{ -} - -template -void CMemberFunctionWrapper2Args::Execute() -{ - (m_Object->*m_Function)(m_Arg1, m_Arg2); -} - -template -CMemberFunctionWrapper6Args::CMemberFunctionWrapper6Args(TObject *inObject, - TFunction inFunction, TArg1 inArg1, - TArg2 inArg2, TArg3 inArg3, - TArg4 inArg4, TArg5 inArg5, - TArg6 inArg6) - : m_Function(inFunction) - , m_Object(inObject) - , m_Arg1(inArg1) - , m_Arg2(inArg2) - , m_Arg3(inArg3) - , m_Arg4(inArg4) - , m_Arg5(inArg5) - , m_Arg6(inArg6) -{ -} - -template -void CMemberFunctionWrapper6Args::Execute() -{ - (m_Object->*m_Function)(m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6); -} -} diff --git a/src/Runtime/Source/System/Include/Qt3DSHash.h b/src/Runtime/Source/System/Include/Qt3DSHash.h deleted file mode 100644 index 8baa2dba..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSHash.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSConfig.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Utility class transforming a string into a hash value. - */ -class CHash -{ - //============================================================================== - // Methods - //============================================================================== -public: // Static utility - //============================================================================== - /** - * We use the hashing algorithm called "sdbm". - * - * This algorithm was created from sdbm (a public-domain reimplementation - * of ndbm) database library. It was found to do well in scrambling bits, - * causing better distribution of the keys and fewer splits. it also happens - * to be a good general hashing function with good distribution. the actual - * function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below - * is the faster version used in gawk. [there is even a faster, duff-device - * version] the magic constant 65599 was picked out of thin air while - * experimenting with different constants, and turns out to be a prime. this - * is one of the algorithms used in berkeley db (see sleepycat) and elsewhere. - * - * @param inString the string to hash - * @return the hash value - */ - static TStringHash HashString(const CHAR *inString) - { - TStringHash theHash = 0; - INT32 theChar = *inString; - INT32 theCount = 0; - while (theChar && (theCount < HASH_LIMIT)) { - theChar = *inString++; - theHash = theChar + (theHash << 6) + (theHash << 16) - theHash; - ++theCount; - } - - return theHash; - } - - //============================================================================== - /** - * 31-bit hash with MSB set to 0 - * - * @param inString the string to hash - * @return the 31-bit hash value - */ - static TEventCommandHash HashEventCommand(const CHAR *inString) - { - return HashString(inString) & 0x7fffffff; - } - - //============================================================================== - /** - * 26-bit hash with MSBs all set to 0 - * - * @param inString the string to hash - * @return the 26-bit hash value - */ - static TAttributeHash HashAttribute(const CHAR *inString) - { - return HashString(inString) & 0x03ffffff; - } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSIFileStream.h b/src/Runtime/Source/System/Include/Qt3DSIFileStream.h deleted file mode 100644 index 0b432601..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSIFileStream.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSIStream.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * File stream interface - */ -class IFileStream : public IStream -{ -public: - virtual void Open(const CHAR *inFilePath, const CHAR *inMode) = 0; - virtual void Close() = 0; - virtual BOOL IsOpen() const = 0; - virtual const CHAR *GetFilePath() const = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSIStream.h b/src/Runtime/Source/System/Include/Qt3DSIStream.h deleted file mode 100644 index a4c11955..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSIStream.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Pure virtual interface providing the stream for class serialization. - */ -class IStream -{ - //============================================================================== - // Typedef - //============================================================================== -public: - typedef INT32 TStreamPosition; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - virtual ~IStream(){} - -public: // Serializing - virtual INT32 ReadRawCopy(void *inDestination, const UINT32 inByteCount) = 0; - virtual INT32 ReadRaw(const void *&inPtr, const UINT32 inByteCount) = 0; - virtual INT32 WriteRaw(const void *inSource, const UINT32 inByteCount) = 0; - - // Seeking - virtual void Offset(const INT32 inOffset) = 0; - virtual TStreamPosition Current() = 0; - virtual void Set(const TStreamPosition &inPosition) = 0; - -public: // Template Readers that make a copy - template - INT32 ReadCopy(T &outValue); - template - INT32 ReadArrayCopy(T *outValue, const UINT32 inCount); - -public: // Template Readers that access value directly - template - INT32 Read(const T *&inPtr); - template - INT32 ReadArray(const T *&inPtr, UINT32 inCount); - -public: // Template Writers - template - INT32 Write(const T &inValue); - template - INT32 WriteArray(const T *inValue, const UINT32 inCount); -}; - -/** Notes concerning usage of Read or ReadCopy (and ReadArray and ReadArrayCopy)**/ -/** -If the value being read fits into 4 bytes (i.e float, int/long), either Read/ReadCopy can be used. -However, if the read value is going to be accessed frequently (in loops etc), ReadCopy is -recommended so a copy is available instead of dereferencing. - -ReadCopy should be used if the data read is an array or is significantly larger than 4 bytes (like -vectors or matrixes). - -For cases where the value is to be stored in a persistant data structures, ReadCopy should be used. - -One important thing about Read/ReadArray, is that the pointer returned is only valid before the next -Read/ReadyArray is called. -There is no guarantee that the pointer data will remain unchanged during subsequent calls to -Read/ReadArray. -**/ - -//============================================================================== -/** - * Read and assign a value by copying. - */ -template -INT32 IStream::ReadCopy(T &outValue) -{ - return ReadRawCopy(&outValue, sizeof(T)); -} - -//============================================================================== -/** - * Read and copy data to a preallocated array. - */ -template -INT32 IStream::ReadArrayCopy(T *outValue, const UINT32 inCount) -{ - return ReadRawCopy(outValue, sizeof(T) * inCount); -} - -//============================================================================== -/** - * Obtain a pointer directly to the data. - */ -template -INT32 IStream::Read(const T *&inPtr) -{ - return ReadRaw(reinterpret_cast(inPtr), sizeof(T)); -} - -//============================================================================== -/** - * Obtain a pointer directly to the array data. - */ -template -INT32 IStream::ReadArray(const T *&inPtr, const UINT32 inCount) -{ - return ReadRaw(reinterpret_cast(inPtr), sizeof(T) * inCount); -} - -//============================================================================== -/** - * Write a value. - */ -template -INT32 IStream::Write(const T &inValue) -{ - return WriteRaw(&inValue, sizeof(T)); -} - -//============================================================================== -/** - * Write an array of values. - */ -template -INT32 IStream::WriteArray(const T *inValue, const UINT32 inCount) -{ - return WriteRaw(inValue, sizeof(T) * inCount); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSITimer.h b/src/Runtime/Source/System/Include/Qt3DSITimer.h deleted file mode 100644 index e73fbb95..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSITimer.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * @interface ITimer - * The base functionality of the timer used by the Kernel - * - * Implement this interface per-platform to obtain the required functionality - */ -class ITimer -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - virtual ~ITimer() {} - -public: // Operation - virtual void Start() = 0; - virtual void Stop() = 0; - virtual void Reset() = 0; - virtual TTimeUnit GetTimeMilliSecs() = 0; - virtual TMicroSeconds GetTimeMicroSecs() = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMacros.h b/src/Runtime/Source/System/Include/Qt3DSMacros.h deleted file mode 100644 index fbc40b4d..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMacros.h +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSAssert.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Easy iterations over arrays. - * @param array_type element type - * @param array_element element variable name getting each entry - * @param array_container element array we are traversing - */ -#define FOR_ARRAY(array_type, array_element, array_container) \ - for (array_type *array_element = (array_container).Begin(); \ - array_element != (array_container).End(); ++array_element) - -#define FOR_ARRAY_REVERSE(array_type, array_element, array_container) \ - for (array_type *array_element = (array_container).End() - 1; \ - array_element != (array_container).Begin() - 1; --array_element) - -//============================================================================== -/** - * Return the smallest of two numbers/objects. - * @param inA one value to compare - * @param inB another value to compare - * @return a reference, not a copy, to the smallest of the two values - */ -template -inline const T Q3DStudio_abs(const T &inVal) -{ - return inVal >= 0 ? inVal : -inVal; -} - -//============================================================================== -/** - * Return the smallest of two numbers/objects. - * @param inA one value to compare - * @param inB another value to compare - * @return a reference, not a copy, to the smallest of the two values - */ -template -inline const T &Q3DStudio_min(const T &inA, const T &inB) -{ - return inA < inB ? inA : inB; -} - -//============================================================================== -/** - * Return the largest of two numbers/objects. - * @param inA one value to compare - * @param inB another value to compare - * @return a reference, not a copy, to the largest of the two values - */ -template -inline const T &Q3DStudio_max(const T &inA, const T &inB) -{ - return inA > inB ? inA : inB; -} - -//============================================================================== -/** - * Return the smallest of three values. - * @param inA one value to compare - * @param inB another value to compare - * @param inC a third value to compare - * @return a reference, not a copy, to the smallest of the three values - */ -template -inline const T &Q3DStudio_min3(const T &inA, const T &inB, const T &inC) -{ - return inA < inB ? Q3DStudio_min(inA, inC) : Q3DStudio_min(inB, inC); -} - -//============================================================================== -/** - * Return the largest of three values. - * @param inA one value to compare - * @param inB another value to compare - * @param inC a third value to compare - * @return a reference, not a copy, to the largest of the three values - */ -template -inline const T &Q3DStudio_max3(const T &inA, const T &inB, const T &inC) -{ - return inA > inB ? Q3DStudio_max(inA, inC) : Q3DStudio_max(inB, inC); -} - -//============================================================================== -/** - * Make sure a value is in-bounds between two other values. - * @param inVal the value to clamp - * @param inMin the lowest inclusive value - * @param inMax the highest inclusive value - * @return a reference to inVal if the value is in bounds, - inMin if lower than the minimum value, or - inMax if higher than maximum value. - */ -template -inline const T &Q3DStudio_clamp(const T &inVal, const T &inMin, const T &inMax) -{ - if (inVal <= inMin) - return inMin; - else if (inVal >= inMax) - return inMax; - - return inVal; -} - -//============================================================================== -/** - * Return the identified lower and higher values. - * @param inA one value to compare - * @param inB another value to compare - * @param outMin is assigned to the lower of the two compared values - * @param outMax is assigned to the higher of the two compared values - */ -template -inline void Q3DStudio_minmax(const T &inA, const T &inB, T &outMin, T &outMax) -{ - if (inA < inB) { - outMin = inA; - outMax = inB; - } else { - outMin = inB; - outMax = inA; - } -} - -//============================================================================== -/** - * Identify needed parameters that are not currently referenced. - */ -#define Q3DStudio_UNREFERENCED_PARAMETER(P) \ - { \ - (void)P; \ - } - -//============================================================================== -/** - * Assert - */ -#if defined(_DEBUG) || defined(_PROFILE) -#define Q3DStudio_ASSERT(inExpression) \ - { \ - if (!(inExpression)) \ - Q3DStudio::CAssert::GetFunction()(#inExpression, __FILE__, __LINE__, __FUNCTION__); \ - } -#else -#define Q3DStudio_ASSERT(inExpression) ((void)0) -#endif // _DEBUG or _PROFILE - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMatrix.h b/src/Runtime/Source/System/Include/Qt3DSMatrix.h deleted file mode 100644 index 4ef74420..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMatrix.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class RuntimeVector3; - -//============================================================================== -/** - * A row major matrix for 3D transformation. - * - * Matrix[row][column] -@code - | 0 1 2 3 | or | 00 01 02 03 | or | Xx Xy Xz w | - | 4 5 6 7 | | 10 11 12 13 | | Yx Yy Yz w | - | 8 9 A B | | 20 21 22 23 | | Zx Zy Zz w | - | C D E F | | 30 31 32 33 | | Tx Ty Tz w | -@endcode - * Rotations are concatenated in the the following order: YXZ - * All rotations are clockwise when viewed down the positive axis - * towards the origin. - */ -class RuntimeMatrix -{ - //============================================================================== - // Enumerations - //============================================================================== -public: - enum ERotationOrder { - ROTATIONORDER_XYZ = 0, - ROTATIONORDER_YZX, - ROTATIONORDER_ZXY, - ROTATIONORDER_XZY, - ROTATIONORDER_YXZ, - ROTATIONORDER_ZYX, - - ROTATIONORDER_XYZR, - ROTATIONORDER_YZXR, - ROTATIONORDER_ZXYR, - ROTATIONORDER_XZYR, - ROTATIONORDER_YXZR, - ROTATIONORDER_ZYXR - }; - - enum EOrientation { ORIENTATION_LEFT_HANDED = 0, ORIENTATION_RIGHT_HANDED }; - - //============================================================================== - // Constants - //============================================================================== -public: - static const RuntimeMatrix IDENTITY; ///< Enabling fast initialization from static identity matrix - - //============================================================================== - // Fields - //============================================================================== -public: - FLOAT m_Data[4][4]; ///< 16 elements in a 4 x 4 - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - RuntimeMatrix(const BOOL inInitializeIdentity = true); - RuntimeMatrix(const RuntimeMatrix &inMatrix); - RuntimeMatrix(const FLOAT inComponents[4][4]); - -public: // Initialization - RuntimeMatrix &Zero(); - RuntimeMatrix &Identity(); - - RuntimeMatrix &Set(const RuntimeMatrix &inMatrix); - RuntimeMatrix &Set(const FLOAT inComponents[4][4]); - RuntimeMatrix &Set(const RuntimeVector3 &inTranslation, const RuntimeVector3 &inRotation, const RuntimeVector3 &inScale, - const RuntimeVector3 &inPivot, const UINT8 inRotationOrder, - const UINT8 inCoordinateSystem); - - RuntimeMatrix &SetTranslate(const RuntimeVector3 &inTranslate); - RuntimeMatrix &SetRotate(const RuntimeVector3 &inRotation, const UINT8 inRotationOrder = ROTATIONORDER_XYZ, - const UINT8 inCoordinateSystem = ORIENTATION_LEFT_HANDED); - RuntimeMatrix &SetScale(const RuntimeVector3 &inScale); - -public: // Functions - BOOL IsIdentity() const; - BOOL IsAffine() const; - RuntimeMatrix &Translate(const RuntimeVector3 &inTranslate); - RuntimeMatrix &Scale(const RuntimeVector3 &inScale); - RuntimeMatrix &Transpose(); - FLOAT Invert(); - RuntimeMatrix &MultiplyAffine(const RuntimeMatrix &inMatrix); - RuntimeMatrix &Multiply(const RuntimeMatrix &inMatrix); - RuntimeMatrix &FlipCoordinateSystem(); - RuntimeMatrix &CloneRotation(const RuntimeMatrix &inMatrix, BOOL inMirrorFlag = false); - FLOAT SquareDistance(const RuntimeMatrix &inMatrix) const; - -public: // Operators - RuntimeMatrix &operator=(const RuntimeMatrix &inMatrix); - BOOL operator==(const RuntimeMatrix &inMatrix) const; - BOOL operator!=(const RuntimeMatrix &inMatrix) const; - -public: // Script based accessors - inline FLOAT Get(const INT32 inRow, const INT32 inColumn) const - { - return m_Data[inRow][inColumn]; - } - inline void Set(const INT32 inRow, const INT32 inColumn, const FLOAT inValue) - { - m_Data[inRow][inColumn] = inValue; - } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemory.h b/src/Runtime/Source/System/Include/Qt3DSMemory.h deleted file mode 100644 index cc04bf73..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemory.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#ifndef _INTEGRITYPLATFORM -#include -#endif -#include "Qt3DSMemoryHeap.h" -#include "Qt3DSMemoryManager.h" -#include "Qt3DSMemoryFilter.h" -#include "Qt3DSMemoryStatistics.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Single overridable exit point for all low level memory calls. - */ -class CMemory -{ - //============================================================================== - // Typedefs - //============================================================================== -public: - typedef void *(*TMalloc)(size_t inSize); - typedef void (*TFree)(void *inPtr); - typedef void *(*TRealloc)(void *inPtr, size_t inSize); - - //============================================================================== - // Fields - //============================================================================== -protected: - static TMalloc s_Malloc; ///< function pointer to malloc operation - static TFree s_Free; ///< function pointer to free operation - static TRealloc s_Realloc; ///< function pointer to realloc operation - - //============================================================================== - // Methods - //============================================================================== -public: // Memory override - static void SetMemoryFunctions(const TMalloc inMalloc, const TFree inFree, - const TRealloc inRealloc); - -public: // Function access - static TMalloc Malloc() { return s_Malloc; } - static TFree Free() { return s_Free; } - static TRealloc Realloc() { return s_Realloc; } -}; - -} // namespace Q3DStudio - -//============================================================================== -// Globals -//============================================================================== -Q3DStudio::CMemoryManager &GetMemoryManager(); -Q3DStudio::CMemoryHeap &GetMemoryHeap(); - -//============================================================================== -// Handlers -//============================================================================== -#ifndef Q3DStudio_HANDLER_NEW -#define Q3DStudio_HANDLER_NEW GetMemoryManager() -#endif // Q3DStudio_HANDLER_NEW - -#ifndef Q3DStudio_HANDLER_ALLOC -#define Q3DStudio_HANDLER_ALLOC GetMemoryManager() -#endif // Q3DStudio_HANDLER_ALLOC - -#ifndef Q3DStudio_HANDLER_FILTER -#define Q3DStudio_HANDLER_FILTER GetMemoryManager() -#endif // Q3DStudio_HANDLER_FILTER - -//============================================================================== -// Q3DStudio new defines -//============================================================================== -#undef new -#undef delete - -#ifndef Q3DStudio_new -#define Q3DStudio_new(type) new (sizeof(type), "class " #type, __FILE__, __LINE__) -#endif // Q3DStudio_new - -#ifndef Q3DStudio_delete -#define Q3DStudio_delete(ptr, type) \ - if (ptr) { \ - reinterpret_cast(ptr)->~type(); \ - Q3DStudio_HANDLER_NEW.Free(ptr, sizeof(type)); \ - } -#endif // Q3DStudio_delete - -#ifndef Q3DStudio_virtual_new -#define Q3DStudio_virtual_new(type) new ("class " #type, __FILE__, __LINE__) -#endif // Q3DStudio_virtual_new - -#ifndef Q3DStudio_virtual_delete -#define Q3DStudio_virtual_delete(ptr, type) \ - if (ptr) { \ - static_cast(ptr)->~type(); \ - Q3DStudio::CMemoryFilter::Free(ptr); \ - } -#endif // Q3DStudio_virtual_delete - -//============================================================================== -// Q3DStudio alloc defines -//============================================================================== -#ifndef Q3DStudio_allocate -#define Q3DStudio_allocate(type, count) \ - reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Allocate( \ - static_cast(sizeof(type) * (count)), #type "[]", __FILE__, __LINE__)) -#endif // Q3DStudio_allocate - -#ifndef Q3DStudio_allocate_desc -#define Q3DStudio_allocate_desc(type, count, desc) \ - reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Allocate( \ - static_cast(sizeof(type) * (count)), desc, __FILE__, __LINE__)) -#endif // Q3DStudio_allocate_desc - -#ifndef Q3DStudio_reallocate -#define Q3DStudio_reallocate(ptr, type, oldcount, newcount) \ - reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Reallocate( \ - ptr, static_cast(sizeof(type) * (oldcount)), \ - static_cast(sizeof(type) * (newcount)), #type "[]", __FILE__, __LINE__)) -#endif // Q3DStudio_reallocate - -#ifndef Q3DStudio_reallocate_desc -#define Q3DStudio_reallocate_desc(ptr, type, oldcount, newcount, desc) \ - reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Reallocate( \ - ptr, static_cast(sizeof(type) * (oldcount)), \ - static_cast(sizeof(type) * (newcount)), desc, __FILE__, __LINE__)) -#endif // Q3DStudio_reallocate_desc - -#ifndef Q3DStudio_free -#define Q3DStudio_free(ptr, type, count) \ - Q3DStudio_HANDLER_ALLOC.Free(ptr, static_cast(sizeof(type) * (count))) -#endif // Q3DStudio_free - -//============================================================================== -// Q3DStudio_new - operator prototypes (5 args) -//============================================================================== -void *operator new(size_t inReportedSize, size_t inOfficialSize, const char *inType, - const char *inFile, int inLine); -void operator delete(void *inReportedAddress, size_t inOfficialSize, const char *, const char *, - int); - -//============================================================================== -// Q3DStudio_virtual_new and new - operator prototypes (4 args) -//============================================================================== -void *operator new(size_t inReportedSize, const char *inType, const char *inFile, int inLine); -void operator delete(void *inReportedAddress, const char *, const char *, int); diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryFilter.h b/src/Runtime/Source/System/Include/Qt3DSMemoryFilter.h deleted file mode 100644 index df9367da..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryFilter.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Aggregation interface for legacy calls that don't remember allocation size. - * - * CMemoryManager and its pools require that the size must be sent along with - * any call, including the Free call. Normal memory calls do not require this - * information and this filter class is used to intercept these calls and - * add a header to each call before forwarded to the manager. This thin class - * allows old school calls such as malloc and free to still use the advantages - * of a pooled memory system without impacting the cleanliness and memory - * footprint of the modern system. - */ -class CMemoryFilter -{ - //============================================================================== - // Constants - //============================================================================== -protected: - const static INT32 FILTER_DOGTAG = 0x1337f1d0; - - //============================================================================== - // Methods - //============================================================================== -public: // Allocation Deallocation - static void *Allocate(const INT32 inSize, const CHAR *inType, const CHAR *inFile, - const INT32 inLine, const BOOL inClear); - static void Free(void *inPointer); - static void *Reallocate(void *inPointer, const INT32 inNewSize, const CHAR *inNewType, - const CHAR *inFile, const INT32 inLine); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryHeap.h b/src/Runtime/Source/System/Include/Qt3DSMemoryHeap.h deleted file mode 100644 index ba7c1306..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryHeap.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryProbe.h" -#include "Qt3DSFixedArray.h" -#include "Qt3DSMemorySettings.h" - -//============================================================================== -/** - * Low level entry points to the heap. - * - * Do not call these directly. Use Q3DStudio_new or Q3DStudio_allocate instead since - * those use the pools. - * @see CMemoryHeap - */ -#define Q3DStudio_heap_allocate(size, desc) \ - Q3DStudio::CMemoryHeap::Allocate(size, desc, __FILE__, __LINE__) -#define Q3DStudio_heap_reallocate(ptr, oldsize, newsize, newdesc) \ - Q3DStudio::CMemoryHeap::Reallocate(ptr, oldsize, newsize, newdesc, __FILE__, _LINE__) -#define Q3DStudio_heap_free(ptr, size) Q3DStudio::CMemoryHeap::Free(ptr, size) - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class IStream; - -//============================================================================== -/** - * Last memory interface before calls to memory callbacks or OS malloc. - * - * First of all, don't call this class directy. Use the macros - * Q3DStudio_heap_allocate and Q3DStudio_heap_free instead since they fill out file, - * line and function parameters for the tracking system. - * - * This is the single exit point for all heap memory allocations. Change this - * code to redirect memory to your own subsystems or add more tracking code to - * measure memory usage. Note however that most memory requests during runtime - * will never reach this point since memory pools will handle those requests. - * Large memory requests and emergency scenarios will still end up here. - * - * @note This class contains the only three real memory calls in Runtime. - */ -class CMemoryHeap -{ - //============================================================================== - // Structs - //============================================================================== -public: - /// Simple memory log entry - struct SReportEntry - { - const void *m_AllocatedPointer; ///< allocated pointer - INT32 m_Size; ///< size in bytes - const CHAR *m_Description; ///< simple description - const CHAR *m_File; ///< filename - INT32 m_Line; ///< line number - }; - - //============================================================================== - // Typedefs - //============================================================================== -public: - typedef CFixedArray TMemoryReport; - - //============================================================================== - // Fields - //============================================================================== -protected: - static CMemoryProbe s_Probe; ///< Light overall allocation statistics -#if Q3DStudio_MEMORY_HEAPTRACKING - static TMemoryReport s_MemoryReport; ///< Storage for memory logs -#endif // Q3DStudio_MEMORY_HEAPTRACKING - - //============================================================================== - // Methods - //============================================================================== -public: // Allocation/Deallocation - static void *Allocate(const INT32 inSize, const CHAR *inDescription, const CHAR *inFile, - const INT32 inLine); - static void Free(void *inPointer, INT32 inSize); - static void *Reallocate(void *inPointer, const INT32 inOldSize, const INT32 inNewSize, - const CHAR *inNewDescription, const CHAR *inFile, const INT32 inLine); - -public: // Statistics - static CMemoryProbe &GetProbe(); - static TMemoryReport *GetReport(); - -protected: // Low level memory overview - static SReportEntry *FindReport(void *inPointer); - static void RemoveReport(void *inPointer); - -public: // Report request - static void Report(IStream *inStream = NULL); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryManager.h b/src/Runtime/Source/System/Include/Qt3DSMemoryManager.h deleted file mode 100644 index fa54fce7..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryManager.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryPool.h" -#include "Qt3DSMemoryProbe.h" -#include "Qt3DSMemoryTracker.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class CMemoryTracker; - -//============================================================================== -/** - * Allocation switch-board forwarding requests to pools. - * - * This is a memory pool hub acting as a complete heap replacement. The number - * of pools is hardcoded in Q3DStudio_MEMORY_POOLCOUNT but can be changed with a - * recompile. The main manager is created in AKMemory and is preconfigured to - * be generous with memory. Tune these values to match your title since - * unused chunks are wasteful. - * - * @note A pool manager survives fine even when not initialized. In this state - * it simply forwards each request to the CMemoryHeap. This setup is intentional - * to enable the default manager to survive long enough to allow future runtime - * initialization based on complexity of the level or presentation being loaded. - */ -class CMemoryManager -{ - //============================================================================== - // Structs - //============================================================================== -public: - /// External pool usage information - struct SPoolData - { - CMemoryProbe - m_Aligned; ///< Exact sum of memory use (28byte struct in 32byte pool is still 28 here) - CMemoryProbe m_Overflow; ///< Failed memory allocation because the pool was full - }; - - //============================================================================== - // Fields - //============================================================================== -protected: - CHAR m_Name[32]; ///< Manager identifier for statistics - CMemoryPool m_Pool[Q3DStudio_MEMORY_POOLCOUNT]; ///< Actual pool memory objects - SPoolData m_ManagerData; ///< Track allocations forwarded to heap because they were too large - -#if Q3DStudio_MEMORY_POOLTRACKING - SPoolData - m_PoolData[Q3DStudio_MEMORY_POOLCOUNT]; ///< Trace pools of different sizes with their usage - CMemoryProbe::SValue - m_Histogram[512]; ///< Allocation histogram if active using Q3DStudio_MEMORY_HEAPTRACKING -#endif // Q3DStudio_MEMORY_POOLTRACKING - -#if Q3DStudio_MEMORY_LINETRACKING - CMemoryTracker - m_LineTracker; ///< Line allocation tracker if active using Q3DStudio_MEMORY_LINETRACKING -#endif // Q3DStudio_MEMORY_LINETRACKING - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CMemoryManager(); - CMemoryManager(const CHAR *inName, const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], - const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]); - ~CMemoryManager(); - -public: // Initialization - void Initialize(const CHAR *inName, const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], - const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]); - void Release(); - -public: // Allocation and Deallocation - void *Allocate(INT32 inSize, const CHAR *inType, const CHAR *inFile, const INT32 inLine); - void Free(void *inOldPointer, INT32 inSize); - void *Reallocate(void *inOldPointer, const INT32 inOldSize, const INT32 inNewSize, - const CHAR *inNewType, const CHAR *inFile, const INT32 inLine); - -protected: // Implementation - INT32 FetchPoolIndex(const void *inPointer); - -public: // Statistics - void Reset(); - const CHAR *GetName(); - CMemoryPool &GetPool(const INT32 inPoolIndex); - SPoolData *GetPoolData(const INT32 inPoolIndex); - SPoolData &GetManagerData(); - CMemoryProbe GetProbe(); - CMemoryTracker *GetLineTracker(); - const CMemoryProbe::SValue *GetHistogram(); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryPool.h b/src/Runtime/Source/System/Include/Qt3DSMemoryPool.h deleted file mode 100644 index 01b2e418..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryPool.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryProbe.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Managed memory allocation using fixed-size chunks. - * - * The pool class implements a generic algorithm that favors reusing recently - * used memory chunks instead of returning memory continously. Yet, a fresh - * pool will always return chunks positioned side by side. - * - * If a chunk is freed it will be the first to be returned next time a fresh - * chunk is new'ed. This makes the cache lines happier. Deleted chunks are - * maintained by linking to each other instead of being stored in a separate - * memory consuming array. - */ -class CMemoryPool -{ - //============================================================================== - // Fields - //============================================================================== -protected: - INT32 m_ChunkSize; ///< size in bytes of each chunk - INT32 m_ChunkCount; ///< number of chunks in pool - - INT8 *m_Ceiling; ///< ceiling memory pointer - INT8 *m_Memory; ///< base memory pointer, INT8 for easy pointer arithemtic - INT8 *m_Top; ///< edge of free continous memory - void *m_Hole; ///< first dis-continous memory chunk if any - - CMemoryProbe m_Probe; ///< call and byte data on pool usage - CHAR m_Description[32]; ///< short description of this pool - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CMemoryPool(); - ~CMemoryPool(); - -public: // Initialization - void Initialize(const CHAR *inName, const INT32 inChunkSize, const INT32 inChunkCount); - void Release(); - -public: // Allocation and Deallocation - void *Allocate(); - void Free(void *inChunk); - BOOL IsFull() const; - BOOL OwnsChunk(const void *inChunk) const; - -protected: // Implementation - void *UseTop(); - void PushHole(void *inChunk); - void *PopHole(); - -public: // Statistics and reports - INT32 GetFreeHoles() const; - INT32 GetFreeTops() const; - INT32 GetFreeChunks() const; - INT32 GetChunkSize() const { return m_ChunkSize; } - INT32 GetChunkCount() const { return m_ChunkCount; } - CMemoryProbe &GetProbe() { return m_Probe; } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryProbe.h b/src/Runtime/Source/System/Include/Qt3DSMemoryProbe.h deleted file mode 100644 index 5f0844e8..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryProbe.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -#include "Qt3DSMacros.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Memory Tracking Enums -//============================================================================== - -/// Track a value - remembering peak and add/del count -enum EMemoryValue { - MEMVALUE_ADDS = 0, ///< For example: allocation call count or bytes allocated - MEMVALUE_DELETES, ///< For example: free call count or bytes deallocated - MEMVALUE_PEAK, ///< Peak of the current value since the last reset - MEMVALUE_CURRENT, ///< Current count - MEMVALUECOUNT -}; - -/// Differentiate between full session (global) or since last reset (local) -enum EMemoryScope { - MEMSCOPE_RESET = 0, ///< Since last reset - MEMSCOPE_GLOBAL, ///< Since process start - MEMSCOPECOUNT -}; - -//============================================================================== -/** - * Memory allocation counter tracking bytes or calls. - * - * A probe instance can be placed to track either number of allocations - * or the bytes of each allocation. CMemoryManager and CMemoryHeap both - * record statistics using this class. 64 bytes. - */ -class CMemoryProbe -{ - //============================================================================== - // Structs - //============================================================================== -public: - //============================================================================== - /** - * Intelligent number that tracks current, peak, incr. and decr. - * - * This value remembers how the amount added, the amount deleted, the highest - * value, while keeping a current value. These are used by CMemoryProbe when - * tracking memory allocations. - */ - struct SValue - { - // Fields - INT32 m_Value[MEMVALUECOUNT]; ///< Four aspects (add,del,current,peak) we are tracking - - // Methods - SValue() { Reset(); } - void Reset() - { - m_Value[MEMVALUE_ADDS] = 0; - m_Value[MEMVALUE_DELETES] = 0; - m_Value[MEMVALUE_PEAK] = 0; - m_Value[MEMVALUE_CURRENT] = 0; - } - - void Delete(INT32 inAmount) - { - Q3DStudio_ASSERT(inAmount >= 0); - m_Value[MEMVALUE_DELETES] += inAmount; - m_Value[MEMVALUE_CURRENT] -= inAmount; - } - - void Add(INT32 inAmount) - { - Q3DStudio_ASSERT(inAmount >= 0); - m_Value[MEMVALUE_ADDS] += inAmount; - m_Value[MEMVALUE_CURRENT] += inAmount; - m_Value[MEMVALUE_PEAK] = - Q3DStudio_max(m_Value[MEMVALUE_PEAK], m_Value[MEMVALUE_CURRENT]); - } - }; - - //============================================================================== - // Fields - //============================================================================== -protected: - SValue m_Calls[MEMSCOPECOUNT]; ///< Memory call count - SValue m_Bytes[MEMSCOPECOUNT]; ///< Memory allocation amount - - //============================================================================== - // Methods - //============================================================================== -public: // Constructor - CMemoryProbe(); - ~CMemoryProbe(); - -public: // Operations - void Reset(); - void Allocate(const INT32 inByteAmount); - void Free(const INT32 inByteAmount); - void Combine(const CMemoryProbe &inProbe); - -public: // Accessors - INT32 GetCalls(const EMemoryScope inScope, const EMemoryValue inValue) const - { - return m_Calls[inScope].m_Value[inValue]; - } - INT32 GetBytes(const EMemoryScope inScope, const EMemoryValue inValue) const - { - return m_Bytes[inScope].m_Value[inValue]; - } -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemorySettings.h b/src/Runtime/Source/System/Include/Qt3DSMemorySettings.h deleted file mode 100644 index 54002424..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemorySettings.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTypes.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * GlobalMemoryManager constants - * NOTE THAT THESE NUMBERS BELOW SHOULD BE ADJUSTED TO FIT YOUR APPLICATION. - * - * See the Memory Management section in the documentation for guidelines - * on memory diagnostics that enable you to optimize these values: - */ - -//============================================================================== -// Memory Pool Configuration -//============================================================================== - -#ifndef Q3DStudio_MEMORY_POOLCOUNT -#define Q3DStudio_MEMORY_POOLCOUNT 12 -#endif // Q3DStudio_MEMORY_POOLCOUNT - -/// A memory pool has a chunk size that defines he size in bytes of each slot -/// and a chunk count defining how many slots there are of that size. -/// The pools below thus has 128 slots of 4 bytes, 256 slots of 8 bytes etc: -const INT32 g_ChunkSize[Q3DStudio_MEMORY_POOLCOUNT] = { 4, 8, 16, 32, 48, 64, - 96, 128, 160, 256, 384, 640 }; -const INT32 g_ChunkCount[Q3DStudio_MEMORY_POOLCOUNT] = { 128, 256, 256, 1536, 128, 128, - 256, 64, 32, 32, 32, 32 }; - -//============================================================================== -// Memory Settings -//============================================================================== - -/// Define the upper memory limit used by Runtime. -/// 0 = unlimited -#ifndef Q3DStudio_MEMORY_LIMIT -#define Q3DStudio_MEMORY_LIMIT 0 -#endif // Q3DStudio_MEMORY_LIMIT - -// Pool sizes and diagnostics are aligned to the required boundary. -#ifndef Q3DStudio_MEMORY_ALIGNMENT -#define Q3DStudio_MEMORY_ALIGNMENT 8 -#endif // Q3DStudio_MEMORY_ALIGNMENT - -//============================================================================== -// Memory Diagnostics -//============================================================================== - -/// Note that the simple report is always on. (F1 in Quarterback) - -/// CMemoryHeap usage report. (F2 in Quarterback) -/// Tracks large allocations such as pool buffers, managers and overflows. -/// Not much overhead since most allocations should be intercepted by pools. -#ifndef Q3DStudio_MEMORY_HEAPTRACKING -#define Q3DStudio_MEMORY_HEAPTRACKING 0 -#endif // Q3DStudio_MEMORY_HEAPTRACKING - -/// Max number of 20 byte SReportEntry heap entries -/// Increase this number if you get a log warning but you should really tune -/// your memory pools to avoid hitting the heap. -#ifndef Q3DStudio_MEMORY_HEAPTRACKINGSIZE -#define Q3DStudio_MEMORY_HEAPTRACKINGSIZE 4000 -#endif // Q3DStudio_MEMORY_HEAPTRACKINGSIZE - -/// Invasive allocation tracker. (F3 in Quarterback) -/// Track detailed memory usage per allocation through CMemoryManager by tracking -/// every Runtime allocation, line by line using __FILE__ and __LINE__. -/// Note that this adds a 16byte SMemoryInfo to each allocation and thus -/// changes pool usage. -/// === Do not tune pools with line tracking enabled! === -#ifndef Q3DStudio_MEMORY_LINETRACKING -#define Q3DStudio_MEMORY_LINETRACKING 0 -#endif // Q3DStudio_MEMORY_LINETRACKING - -// Hashbin size of entries pointing to SMemoryInfo allocation headers -#ifndef Q3DStudio_MEMORY_LINETRACKINGSIZE -#define Q3DStudio_MEMORY_LINETRACKINGSIZE (128 * 1024) -#endif // Q3DStudio_MEMORY_LINETRACKINGSIZE - -/// CMemoryManager pooled memory usage report. (F5-F8 in Quarterback) -/// Track most used allocation sizes to tune pool sizes and count. -/// Enabled by default since it allows tracking precise presentation -/// memory usage without much of an overhead. -/// It also includes a histogram when showing Reset data (F5,F6) -#ifndef Q3DStudio_MEMORY_POOLTRACKING -#ifdef _DEBUG -#define Q3DStudio_MEMORY_POOLTRACKING 1 -#else -#define Q3DStudio_MEMORY_POOLTRACKING 0 -#endif -#endif // Q3DStudio_MEMORY_POOLTRACKING - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryStatistics.h b/src/Runtime/Source/System/Include/Qt3DSMemoryStatistics.h deleted file mode 100644 index 81e30434..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryStatistics.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryManager.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Static facade to memory statistics and allocation tracking data. - * - * Use this class to examine the memory state of the system at any point. - * Heap, managers and pools are are connected to this point by registering - * themselves on creation. Initiate the extraction of the collected data - * using this interface. - */ -class CMemoryStatistics -{ - //============================================================================== - // Constants - //============================================================================== -public: - const static INT32 REPORTSIZE = 256; ///< Max size of single report string - const static INT32 MANAGERCOUNT = 5; ///< Fixed number of managers tracked - const static INT32 HISTOGRAMCOUNT = 10; ///< Fixed number of managers tracked - - //============================================================================== - // Structs - //============================================================================== -public: - /// One row of statistics on allocation - struct SFactoid - { - CHAR m_Name[32]; ///< Ascii identifier - manager name or pool description - INT32 m_Bytes; ///< Bytes used - full pool size for example - zero if factoid unused - INT32 m_Calls; ///< Function calls, i.e number of allocations - INT32 m_Used; ///< Discrete chunk usage in percent - 10 used of 200 gives a value 5 - INT32 m_Align; ///< Packed efficiency in percent - all 24byte structs in 32byte pool give a - ///value 75 - INT32 m_Miss; ///< Allocation misses - due to full pools for example - }; - - /// Tuple describing one data point in a histogram - struct SHistogramScore - { - INT32 m_Size; ///< Allocation request in bytes - INT32 m_Count; ///< Number of allocation requests - }; - - /// Set of factoids describing a system memory state - struct SFactSheet - { - SFactoid m_HeapState; ///< Heap facts - SFactoid m_ManagerState; ///< Combined manager facts - SFactoid m_Manager[MANAGERCOUNT]; ///< Individual manager facts - SHistogramScore m_Histogram[MANAGERCOUNT][HISTOGRAMCOUNT]; ///< Top allocation requests - ///sorted by bytes, global and - ///never reset - SFactoid m_Pool[MANAGERCOUNT][Q3DStudio_MEMORY_POOLCOUNT]; ///< Individual pool facts - }; - - //============================================================================== - // Fields - //============================================================================== -protected: - static INT32 s_Overhead; ///< Memory tracking structures report in here - static CMemoryManager - *s_PoolManagers[MANAGERCOUNT]; ///< Pointers to all created memory pool managers - - //============================================================================== - // Methods - //============================================================================== -public: // Registration - static void AddManager(CMemoryManager *inManager); - static void RemoveManager(CMemoryManager *inManager); - static INT32 &Overhead(); - -public: // Access - static void Reset(); - static void GetFacts(SFactSheet &outFacts, const BOOL inPeak = false, - const BOOL inGlobal = false); - static INT32 GetRequestedBytes(const BOOL inPeak = false); - static INT32 GetHeapBytes(const BOOL inPeak = false); - -public: // Reporting - static void SimpleReport(IStream *inStream = NULL); - static void HeapReport(IStream *inStream = NULL); - static void PoolReport(const BOOL inPeak = false, const BOOL inGlobal = false, - IStream *inStream = NULL); - static void LineReport(IStream *inStream = NULL); - - static void FullReport(IStream *inStream = NULL); - static void Report(IStream *inStream, const CHAR *inString); - -protected: // Utility - static void CullHistogram(const CMemoryProbe::SValue *inHistogram, const EMemoryValue inValue, - SHistogramScore outResults[HISTOGRAMCOUNT]); - static int CompareHeap(const void *arg1, const void *arg2); - static int CompareHistogram(const void *arg1, const void *arg2); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSMemoryTracker.h b/src/Runtime/Source/System/Include/Qt3DSMemoryTracker.h deleted file mode 100644 index ee6ce699..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSMemoryTracker.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Low level memory statistics tracking each individual allocation. - * - * This class is instantiated in each CMemoryManager if tracking is enabled - * by setting ENABLE_MEMORY_LINETRACKING to 1 in AKConfig.h for the build - * configuration you want. - * - * Tracking is much more invasive than simple statistics since it records each - * individual allocation and deallocation. The overhead can be seen mostly in - * the memory load since we store a tracking hashbin of all memory allocation - * and a 16 byte SMemoryInfo structure is prepended to each allocation no matter - * how small. This mode should be used when debugging memory to track down - * individual allocations. It's turned off by default and should stay off - * most of the time. - * - * The tracking information is usually dumped to a comma delimited .csv file - * for easy viewing as a spreadsheet of data. This action is initiated by - * pressing CTRL-F1 in Quarterback on the PC but can be added to any viewer - * by calling CMemoryStatistics::TrackingDump. - */ -class CMemoryTracker -{ - //============================================================================== - // Constants - //============================================================================== -public: - const static UINT16 TRACKER_DOGTAG = 0xbead; ///< Watch guard value in SMemoryTrackInfo - - //============================================================================== - // Structs - //============================================================================== -public: - /// 16 bytes of details on each allocation when tracking is enabled - struct SMemoryInfo - { - UINT16 m_DogTag; ///< 0xbead - asserting this to track overwrites - INT16 m_Line; ///< line from which the allocation occurred - INT32 m_Size; ///< allocation size in bytes - const CHAR *m_File; ///< file from which the allocation occurred - const CHAR *m_Type; ///< type of allocation, usually class name - }; - - //============================================================================== - // Fields - //============================================================================== -protected: - INT32 m_TrackingOverhead; ///< memory used to track allocations in bytes - SMemoryInfo *m_TrackingHashBin[Q3DStudio_MEMORY_LINETRACKINGSIZE]; ///< hash table of all - ///tracked allocations - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CMemoryTracker(); - ~CMemoryTracker(); - -public: // Tracking - void Remember(SMemoryInfo *inData); - void Forget(SMemoryInfo *inData); - -public: // Reporting - INT32 Report(IStream *inStream = NULL); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSPlatformSpecific.h b/src/Runtime/Source/System/Include/Qt3DSPlatformSpecific.h deleted file mode 100644 index 3fc34016..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSPlatformSpecific.h +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#if defined(_PCPLATFORM) - -#define Q3DStudio_memcpy(inDest, inSource, inCount) \ - memcpy(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memmove(inDest, inSource, inCount) \ - memmove(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memset(inDest, inChar, inCount) \ - memset(inDest, inChar, static_cast(inCount)) -#define Q3DStudio_memcmp(inDest, inSource, inCount) \ - memcmp(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_sprintf _snprintf -#define Q3DStudio_stricmp(inStr1, inStr2) _stricmp(inStr1, inStr2) -#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) _strnicmp(inStr1, inStr2, inCount) -#define Q3DStudio_tolower tolower -#define Q3DStudio_restrict /*__restrict*/ -#define Q3DStudio_dcbt(inOffset, inAddress) -#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy_s(inDest, inSize, inSource) -#define Q3DStudio_strcat(inDest, inSize, inSource) strcat_s(inDest, inSize, inSource) -#define Q3DStudio_fopen fopen_s -#define Q3DStudio_sleepmillisec(inMillisec) Sleep(inMillisec) -#define Q3DStudio_getpid GetCurrentProcessId - -#elif defined(_TEGRAPLATFORM) - -#define Q3DStudio_memcpy(inDest, inSource, inCount) \ - memcpy(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memmove(inDest, inSource, inCount) \ - memmove(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memset(inDest, inChar, inCount) \ - memset(inDest, inChar, static_cast(inCount)) -#define Q3DStudio_memcmp(inDest, inSource, inCount) \ - memcmp(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_sprintf _snprintf -#define Q3DStudio_stricmp(inStr1, inStr2) _stricmp(inStr1, inStr2) -#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) _strnicmp(inStr1, inStr2, inCount) -#define Q3DStudio_tolower tolower -#define Q3DStudio_restrict /*__restrict*/ -#define Q3DStudio_dcbt(inOffset, inAddress) -#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy_s(inDest, inSize, inSource) -#define Q3DStudio_strcat(inDest, inSize, inSource) strcat_s(inDest, inSize, inSource) -#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) fopen_s(inFilePtr, inFilename, inMode) -#define Q3DStudio_sleepmillisec(inMillisec) Sleep(inMillisec) -#define Q3DStudio_getpid GetCurrentProcessId - -#elif defined(_XENONPLATFORM) - -#include -#define Q3DStudio_memcpy(inDest, inSource, inCount) \ - memcpy(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memmove(inDest, inSource, inCount) \ - memmove(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memset(inDest, inChar, inCount) \ - memset(inDest, inChar, static_cast(inCount)) -#define Q3DStudio_memcmp(inDest, inSource, inCount) \ - memcmp(inDest, inSource, static_cast(inCount)) -//#define Q3DStudio_memcpy( inDest, inSource, inCount ) XMemCpy( inDest, inSource, -//static_cast( inCount ) ) -//#define Q3DStudio_memset( inDest, inChar, inCount ) XMemSet( inDest, inChar, -//static_cast( inCount ) ) -#define Q3DStudio_sprintf _snprintf -#define Q3DStudio_tolower tolower -#define Q3DStudio_restrict /*__restrict*/ -#define Q3DStudio_dcbt(inOffset, inAddress) __dcbt(inOffset, inAddress) -#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy_s(inDest, inSize, inSource) -#define Q3DStudio_strcat(inDest, inSize, inSource) strcat_s(inDest, inSize, inSource) -#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) fopen_s(inFilePtr, inFilename, inMode) -#define Q3DStudio_sleepmillisec(inMillisec) Sleep(inMillisec) -#define Q3DStudio_getpid GetCurrentProcessId -#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) _strnicmp(inStr1, inStr2, inCount) -#define Q3DStudio_stricmp(inStr1, inStr2) _stricmp(inStr1, inStr2) - -#elif defined(_PS3PLATFORM) - -#define Q3DStudio_memcpy(inDest, inSource, inCount) \ - memcpy(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memmove(inDest, inSource, inCount) \ - memmove(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memset(inDest, inChar, inCount) \ - memset(inDest, inChar, static_cast(inCount)) -#define Q3DStudio_memcmp(inDest, inSource, inCount) \ - memcmp(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_sprintf snprintf -#define Q3DStudio_tolower std::tolower -#define Q3DStudio_restrict -#define Q3DStudio_dcbt(inOffset, inAddress) -#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy(inDest, inSource) -#define Q3DStudio_strcat(inDest, inSize, inSource) strcat(inDest, inSource) -#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) *(inFilePtr) = fopen(inFilename, inMode) -#define Q3DStudio_sleepmillisec(inMillisec) \ - { \ - struct timespec theSleepTime = { inMillisec / 1000, (inMillisec % 1000) * 1000000 }; \ - ::nanosleep(&theSleepTime, NULL); \ - } -#define Q3DStudio_getpid getpid -#define Q3DStudio_stricmp(inStr1, inStr2) strcasecmp(inStr1, inStr2) -#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) strncasecmp(inStr1, inStr2, inCount) - -#elif defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -#include -#define Q3DStudio_memcpy(inDest, inSource, inCount) \ - memcpy(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memmove(inDest, inSource, inCount) \ - memmove(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_memset(inDest, inChar, inCount) \ - memset(inDest, inChar, static_cast(inCount)) -#define Q3DStudio_memcmp(inDest, inSource, inCount) \ - memcmp(inDest, inSource, static_cast(inCount)) -#define Q3DStudio_sprintf snprintf -#define Q3DStudio_stricmp(inStr1, inStr2) strcasecmp(inStr1, inStr2) -#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) strncasecmp(inStr1, inStr2, inCount) -#define Q3DStudio_tolower tolower -#define Q3DStudio_restrict /*__restrict*/ -#define Q3DStudio_dcbt(inOffset, inAddress) -#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy(inDest, inSource) -#define Q3DStudio_strcat(inDest, inSize, inSource) strcat(inDest, inSource) -#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) *(inFilePtr) = fopen(inFilename, inMode) -#define Q3DStudio_sleepmillisec(inMillisec) \ - { \ - struct timespec theSleepTime = { inMillisec / 1000, (inMillisec % 1000) * 1000000 }; \ - ::nanosleep(&theSleepTime, NULL); \ - } -#define Q3DStudio_getpid getpid - -#else -#error "A platform must be defined" -#endif - -//============================================================================== -/** @def Q3DStudio_dcbt( inOffset, inAddress ) - * @brief Data Cache Block Touch - Loads the block of memory containing - * the specified address into the data cache. - * - * A program uses the dcbt instruction to request a cache block fetch before - * it is actually needed by the program. This prevents stalls in the pipeline. - */ - -//============================================================================== -/** @def Q3DStudio_restrict - * @brief Cross platform macro for pointer aliasing. - * - * Performance Implications of Pointer Aliasing - * - * Doug Cook - * Silicon Graphics, Inc. - * August, 1997 - * - * Pointer aliasing can have a severe impact on program performance. - * Understanding its implications is critical to writing high-performance code. - * This document provides a brief introduction to the problem, and suggests - * several approaches to solving it through source-code restructuring, compiler - * options, and C or C++ language extensions. - * - * *Aliasing* - * - * Here's a brief overview of aliasing. Consider the following function: - * - * void process_data(float *in, float *out, float gain, int nsamps) - * { - * int i; - * for (i = 0; i < nsamps; i++) { - * out[i] = in[i] * gain; - * } - * } - * - * In C or C++, it is legal for the parameters in and out to point to - * overlapping regions in memory. When this happens, in and out are said to be - * aliases. When the compiler optimizes the function, it does not in general - * know whether in and out are aliases. It must therefore assume that any - * store through out can affect the memory pointed to by in, which severely - * limits its ability to reorder or parallelize the code (For some simple - * cases, the compiler could analyze the entire program to determine that two - * pointers cannot be aliases. But in general, it is impossible for the - * compiler to determine whether or not two pointers are aliases, so to be - * safe, it must assume that they are). - */ diff --git a/src/Runtime/Source/System/Include/Qt3DSTimer.h b/src/Runtime/Source/System/Include/Qt3DSTimer.h deleted file mode 100644 index 278bd4b4..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSTimer.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSITimer.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== - -//============================================================================== -/** - * Time provider interface abstracting time from the usage of time. - */ -class ITimeProvider -{ -protected: - virtual ~ITimeProvider() {} -public: - virtual INT64 GetCurrentTimeMicroSeconds() = 0; -}; - -// Pause in a way that is completely transparent to the underlying system. -class CPausingTimeProvider : public ITimeProvider -{ - ITimeProvider &m_Provider; - INT64 m_PauseOffset; - INT64 m_Offset; - bool m_Paused; - -public: - CPausingTimeProvider(ITimeProvider &inProvider) - : m_Provider(inProvider) - , m_PauseOffset(0) - , m_Offset(0) - , m_Paused(false) - { - } - - INT64 GetCurrentTimeMicroSeconds() override - { - INT64 currentTime = 0; - if (m_Paused) - currentTime = m_PauseOffset; - else - currentTime = m_Provider.GetCurrentTimeMicroSeconds(); - - return currentTime - m_Offset; - } - - void Pause() - { - if (!m_Paused) { - m_Paused = true; - m_PauseOffset = m_Provider.GetCurrentTimeMicroSeconds(); - } - } - - void UnPause() - { - if (m_Paused) { - m_Paused = false; - INT64 timePaused = m_Provider.GetCurrentTimeMicroSeconds() - m_PauseOffset; - m_Offset += timePaused; - } - } - - bool IsPaused() { return m_Paused; } - - void Reset() { m_PauseOffset = m_Offset = 0; } -}; - -//============================================================================== -/** - * @class CTimer - * @brief A very simple platform optimized utility class to return lapsed time - * - * Gets current time based on the time lapsed from the point where timer is started. - */ - -class CTimer : public ITimer -{ - - //============================================================================== - // Fields - //============================================================================== -protected: - ITimeProvider &m_TimeProvider; - INT64 m_StartTime; - BOOL m_IsRunning; // Whether this timer is running or stopped - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CTimer(ITimeProvider &inProvider); - -public: // Operation - void Start() override; - void Stop() override; - void Reset() override; - TTimeUnit GetTimeMilliSecs() override; - TMicroSeconds GetTimeMicroSecs() override; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSTypes.h b/src/Runtime/Source/System/Include/Qt3DSTypes.h deleted file mode 100644 index 6330919c..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSTypes.h +++ /dev/null @@ -1,236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Typedefs -//============================================================================== -typedef bool BOOL; ///< true or false, usually 8 bits -typedef signed char INT8; ///< A signed 8-bit integer, not a character -typedef unsigned char UINT8; ///< An unsigned 8-bit integer 0-255, not a character -typedef signed short INT16; ///< A signed 16-bit integer -typedef unsigned short UINT16; ///< An unsigned 16-bit integer -typedef int INT32; ///< A signed 32-bit integer -typedef unsigned int UINT32; ///< An unsigned 32-bit integer -typedef float FLOAT; ///< A 32-bit floating point number -typedef char CHAR; ///< String character, not a number - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -//============================================================================== -// Max constants and computation -//============================================================================== -INT32 Q3DStudio_maxbits(const INT32 inBitCount, const BOOL inUnsigned); - -#define AKMAX_INT8 static_cast(0x7F) -#define AKMAX_UINT8 static_cast(0xFF) -#define AKMAX_INT16 static_cast(0x7FFF) -#define AKMAX_UINT16 static_cast(0xFFFF) -#define AKMAX_INT32 0x7FFFFFFFL -#define AKMAX_UINT32 0xFFFFFFFFUL - -//============================================================================== -// Platform specific vectors and matrices -//============================================================================== -#if defined(_PCPLATFORM) - -typedef FILE TFile; -typedef size_t TFileSize; - -#define Q3DStudio_INT64_C(x) x -#define Q3DStudio_UINT64_C(x) x - -typedef __int64 INT64; -typedef unsigned __int64 UINT64; - -struct VECTOR4 -{ - union { - FLOAT v[4]; - UINT32 u[4]; - }; - - FLOAT &x() { return v[0]; } - FLOAT &y() { return v[1]; } - FLOAT &z() { return v[2]; } - FLOAT &w() { return v[3]; } -}; - -struct MATRIX16 -{ - union { - VECTOR4 v[4]; - FLOAT m[4][4]; - FLOAT f[16]; - }; - - FLOAT &_11() { return f[0]; } - FLOAT &_12() { return f[1]; } - FLOAT &_13() { return f[2]; } - FLOAT &_14() { return f[3]; } - FLOAT &_21() { return f[4]; } - FLOAT &_22() { return f[5]; } - FLOAT &_23() { return f[6]; } - FLOAT &_24() { return f[7]; } - FLOAT &_31() { return f[8]; } - FLOAT &_32() { return f[9]; } - FLOAT &_33() { return f[10]; } - FLOAT &_34() { return f[11]; } - FLOAT &_41() { return f[12]; } - FLOAT &_42() { return f[13]; } - FLOAT &_43() { return f[14]; } - FLOAT &_44() { return f[15]; } -}; - -#elif defined(_TEGRAPLATFORM) - -// TODO: sk - We used both WinCE and OpenKode file system utilities. Using non-OpenKode restores -// functionality in a hacky way -// but ultimately sticking to just 1 system would definitely be cleaner. -typedef FILE TFile; -typedef size_t TFileSize; -// typedef KDFile TFile; -// typedef KDsize TFileSize; - -#define Q3DStudio_INT64_C(x) x -#define Q3DStudio_UINT64_C(x) x - -typedef __int64 INT64; -typedef unsigned __int64 UINT64; - -struct VECTOR4 -{ - union { - FLOAT v[4]; - UINT32 u[4]; - }; - FLOAT &x() { return v[0]; } - FLOAT &y() { return v[1]; } - FLOAT &z() { return v[2]; } - FLOAT &w() { return v[3]; } -}; - -struct MATRIX16 -{ - union { - VECTOR4 v[4]; - FLOAT m[4][4]; - FLOAT f[16]; - }; - - FLOAT &_11() { return f[0]; } - FLOAT &_12() { return f[1]; } - FLOAT &_13() { return f[2]; } - FLOAT &_14() { return f[3]; } - FLOAT &_21() { return f[4]; } - FLOAT &_22() { return f[5]; } - FLOAT &_23() { return f[6]; } - FLOAT &_24() { return f[7]; } - FLOAT &_31() { return f[8]; } - FLOAT &_32() { return f[9]; } - FLOAT &_33() { return f[10]; } - FLOAT &_34() { return f[11]; } - FLOAT &_41() { return f[12]; } - FLOAT &_42() { return f[13]; } - FLOAT &_43() { return f[14]; } - FLOAT &_44() { return f[15]; } -}; - -#elif defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - -typedef FILE TFile; -typedef size_t TFileSize; - -#define Q3DStudio_INT64_C(x) x -#define Q3DStudio_UINT64_C(x) x - -typedef int64_t INT64; -typedef uint64_t UINT64; - -struct VECTOR4 -{ - union { - FLOAT v[4]; - UINT32 u[4]; - }; - - FLOAT &x() { return v[0]; } - FLOAT &y() { return v[1]; } - FLOAT &z() { return v[2]; } - FLOAT &w() { return v[3]; } -}; - -struct MATRIX16 -{ - union { - VECTOR4 v[4]; - FLOAT m[4][4]; - FLOAT f[16]; - }; - - FLOAT &_11() { return f[0]; } - FLOAT &_12() { return f[1]; } - FLOAT &_13() { return f[2]; } - FLOAT &_14() { return f[3]; } - FLOAT &_21() { return f[4]; } - FLOAT &_22() { return f[5]; } - FLOAT &_23() { return f[6]; } - FLOAT &_24() { return f[7]; } - FLOAT &_31() { return f[8]; } - FLOAT &_32() { return f[9]; } - FLOAT &_33() { return f[10]; } - FLOAT &_34() { return f[11]; } - FLOAT &_41() { return f[12]; } - FLOAT &_42() { return f[13]; } - FLOAT &_43() { return f[14]; } - FLOAT &_44() { return f[15]; } -}; - -#else - -#error "A platform must be defined" - -#endif - -typedef INT64 TMicroSeconds; ///< Time in microseconds -typedef INT64 TTimeUnit; ///< Time in milliseconds - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/Qt3DSVector3.h b/src/Runtime/Source/System/Include/Qt3DSVector3.h deleted file mode 100644 index 08df028b..00000000 --- a/src/Runtime/Source/System/Include/Qt3DSVector3.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#ifdef WIN32 -#pragma warning(disable : 4201) -#endif - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class RuntimeMatrix; - -//============================================================================== -/** - * 3D vector with automatic notification on change. - * - * This implementation of a 3D vector along with all the sibling and helper - * classes in the geometry section, try to strike a balance between clean code, - * ease-of-use and speed. Fields are public and most methods are designed to - * give the impression of a very intelligent and capable structure. Heavier - * code such as intersections is encouraged to be added externally instead - * of here. - * - * The vector is a member of the geometry classes next to CMatrix and CRotation - * @see CMatrix - * @see CRotation - */ -class RuntimeVector3 -{ - //============================================================================== - // Fields - //============================================================================== -public: - union { - float m[3]; - struct - { - float m_X; - float m_Y; - float m_Z; - }; - }; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - RuntimeVector3(); - RuntimeVector3(const float inVector[3]); - RuntimeVector3(const float inX, const float inY, const float inZ); - RuntimeVector3(const RuntimeVector3 &inVector); - -public: // Initialization - RuntimeVector3 &Set(const float inX, const float inY, const float inZ); - RuntimeVector3 &Set(const RuntimeVector3 &inVector); - -public: // Functions - float DistanceSquared(const RuntimeVector3 &inVector) const; - float Distance(const RuntimeVector3 &inVector) const; - float LengthSquared() const; - float Length() const; - float DotProduct(const RuntimeVector3 &inVector) const; - RuntimeVector3 &CrossProduct(const RuntimeVector3 &inVector); - RuntimeVector3 &Normalize(); - RuntimeVector3 &Minimize(const RuntimeVector3 &inVector); - RuntimeVector3 &Maximize(const RuntimeVector3 &inVector); - RuntimeVector3 &InterpolateLinear(const RuntimeVector3 &inDestVector, float inFactor); - RuntimeVector3 &Transform(const RuntimeMatrix &inMatrix); - -public: // Operators - bool operator==(const RuntimeVector3 &inVector) const; - bool operator!=(const RuntimeVector3 &inVector) const; - RuntimeVector3 operator+(const RuntimeVector3 &inVector) const; - RuntimeVector3 operator-(const RuntimeVector3 &inVector) const; - RuntimeVector3 operator*(float inFactor) const; - RuntimeVector3 &operator=(const RuntimeVector3 &inVector); - RuntimeVector3 &operator+=(const RuntimeVector3 &inVector); - RuntimeVector3 &operator-=(const RuntimeVector3 &inVector); - RuntimeVector3 &operator*=(float inFactor); - RuntimeVector3 operator-() const; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Include/SystemPrefix.h b/src/Runtime/Source/System/Include/SystemPrefix.h deleted file mode 100644 index aa1ba185..00000000 --- a/src/Runtime/Source/System/Include/SystemPrefix.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#ifdef _WIN32 -//============================================================================== -// DEFINES -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -//============================================================================== -// DISABLED WARNINGS -// -// Note that most of these warnings are tuned off by default by the compiler -// even at warning level 4. Using option /Wall turns on all warnings and makes -// even standard Microsoft include files cry. We had to turn off these or -// turn off warnings individually for each standard include file which was -// too much work. Point is that /Wall is like Warning Level 5 and this brings -// it down to about Warning level 4.5, still way above /W4. -#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union -#pragma warning(disable : 4511) // copy constructor could not be generated -#pragma warning(disable : 4512) // assignment operator could not be generated -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#pragma warning(disable : 4619) // #pragma warning : there is no warning number '4619' (in string.h) -#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy - // constructor is inaccessible -#pragma warning(disable : 4626) // assignment operator could not be generated because a base class - // assignment operator is inaccessible -#pragma warning(disable : 4826) // Conversion from 'const void *' to 'void *' is sign-extended -#pragma warning(disable : 4996) // _snprintf' was declared deprecated -#pragma warning(disable : 4711) // function selected for automatic inline expansion -#pragma warning(disable : 4710) // function not inlined -#pragma warning(disable : 4355) // 'this' : used in base member initializer list - -#pragma warning(disable : 4640) // construction of local static object is not thread-safe -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning( \ - disable : 4738) // storing 32-bit float result in memory, possible loss of performance -#endif //_WIN32 - -//============================================================================== -// STD INCLUDES - Standard includes MUST come first -#include // Standard functions -#include // File and IO -#ifndef _INTEGRITYPLATFORM -#include // memset, memcpy -#endif -#include // strlen -#include // Bezier math - pow, acos, cos, sqrt -#include // _tolower - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -#include -#endif - -//============================================================================== -// OUR INCLUDES -#include "Qt3DSTypes.h" -#include "Qt3DSPlatformSpecific.h" -#include "Qt3DSAssert.h" -#include "Qt3DSMacros.h" -#include "Qt3DSConfig.h" -#include "Qt3DSMemorySettings.h" -#include "Qt3DSMemory.h" -#include "Qt3DSArray.h" diff --git a/src/Runtime/Source/System/Source/Qt3DSAssert.cpp b/src/Runtime/Source/System/Source/Qt3DSAssert.cpp deleted file mode 100644 index 63d38768..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSAssert.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSAssert.h" -#include "foundation/Qt3DSLogging.h" -//============================================================================== -// Platform Specific Includes -//============================================================================== -#if defined(_PCPLATFORM) -#pragma warning(push, 3) -#include -#include -#pragma warning(pop) -#endif // #if defined (_PCPLATFORM) - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Global Variables -//============================================================================== -CAssert::TFunction CAssert::s_AssertFunction = CAssert::Default; ///< Default assert function - -//============================================================================== -/** - * Default method for asserts - */ -void CAssert::Default(const CHAR *inAssert, const CHAR *inFile, INT32 inLine, - const CHAR *inFunction) -{ - // Use logger to report the string first - qCCritical (qt3ds::INTERNAL_ERROR) << "Assertion failed: " << inFile << " " << inLine - << " " << inAssert << " " << inFunction; - -#if defined(_DEBUG) && defined(_PCPLATFORM) && defined(QT3DS_VC) - if (_CrtDbgReport(_CRT_ASSERT, inFile, inLine, inFunction, "Assertion Failed") == 1) - ::DebugBreak(); -#endif // _DEBUG & _PCPLATFORM -} - -//============================================================================== -/** - * Method for setting the assert function - */ -void CAssert::SetFunction(TFunction inAssert) -{ - s_AssertFunction = inAssert; -} - -//============================================================================== -/** - * Method for getting the assert function - */ -CAssert::TFunction CAssert::GetFunction() -{ - return s_AssertFunction; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSBoundingBox.cpp b/src/Runtime/Source/System/Source/Qt3DSBoundingBox.cpp deleted file mode 100644 index 2a9331d1..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSBoundingBox.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSBoundingBox.h" -#include "Qt3DSMatrix.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - creates an empty BoundingBox - */ -CBoundingBox::CBoundingBox() - : m_Min(1.0f, 1.0f, 1.0f) - , m_Max(-1.0f, -1.0f, -1.0f) -{ -} - -//============================================================================== -/** - * Make BoundingBox invalid - */ -void CBoundingBox::SetEmpty() -{ - m_Min.Set(1.0f, 1.0f, 1.0f); - m_Max.Set(-1.0f, -1.0f, -1.0f); -} - -//============================================================================== -/** - * Is the BoundingBox empty? - * @return true if bounding box is empty, false otherwise - */ -BOOL CBoundingBox::IsEmpty() const -{ - return (m_Min.m_X > m_Max.m_X); -} - -//============================================================================== -/** - * Add a point to the BoundingBox - * @param inPoint a 3D point - */ -void CBoundingBox::Add(const RuntimeVector3 &inPoint) -{ - if (IsEmpty()) { - m_Min = inPoint; - m_Max = inPoint; - } else { - m_Min.Minimize(inPoint); - m_Max.Maximize(inPoint); - } -} - -//============================================================================== -/** - * Add another BoundingBox to this BoundingBox - * @param inBox a 3D BoundingBox - */ -void CBoundingBox::Add(const CBoundingBox &inBox) -{ - if (!inBox.IsEmpty()) { - Add(inBox.GetMin()); - Add(inBox.GetMax()); - } -} - -//============================================================================== -/** - * Get the bounding box's smallest position - * @return the smallest position of the bounding box - */ -const RuntimeVector3 &CBoundingBox::GetMin() const -{ - return m_Min; -} - -//============================================================================== -/** - * Get the bounding box's largest position - * @return the largest position of the bounding box - */ -const RuntimeVector3 &CBoundingBox::GetMax() const -{ - return m_Max; -} - -//============================================================================== -/** - * Apply a transform to the BoundingBox - * @param inMatrix a 4x4 trasnform matrix - */ -void CBoundingBox::Transform(const RuntimeMatrix &inMatrix) -{ - // Apply transform to the 8 corners of the BoundingBox and renormalize to majox axes - CBoundingBox theTransformedBox; - RuntimeVector3 theCorners[8]; - - theCorners[0].Set(m_Min.m_X, m_Min.m_Y, m_Min.m_Z); - theCorners[1].Set(m_Min.m_X, m_Min.m_Y, m_Max.m_Z); - theCorners[2].Set(m_Min.m_X, m_Max.m_Y, m_Min.m_Z); - theCorners[3].Set(m_Min.m_X, m_Max.m_Y, m_Max.m_Z); - theCorners[4].Set(m_Max.m_X, m_Min.m_Y, m_Min.m_Z); - theCorners[5].Set(m_Max.m_X, m_Min.m_Y, m_Max.m_Z); - theCorners[6].Set(m_Max.m_X, m_Max.m_Y, m_Min.m_Z); - theCorners[7].Set(m_Max.m_X, m_Max.m_Y, m_Max.m_Z); - - for (INT32 theIndex = 0; theIndex < 8; ++theIndex) { - theCorners[theIndex].Transform(inMatrix); - theTransformedBox.Add(theCorners[theIndex]); - } - *this = theTransformedBox; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSColor.cpp b/src/Runtime/Source/System/Source/Qt3DSColor.cpp deleted file mode 100644 index a44d488b..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSColor.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSColor.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - * @param inColor 32 bit represenation of the color - */ -CColor::CColor(const Q3DStudio::UINT32 inColor) - : m_Color(inColor) -{ -} - -//============================================================================== -/** - * Constructor - * @param inRed 8 bit represenation of the red component - * @param inGreen 8 bit representation of the green component - * @param inBlue 8 bit representation of the blue component - * @param inAlpha 8 bit representation of the transparency component - */ -CColor::CColor(const UINT8 inRed, const UINT8 inGreen, const UINT8 inBlue, const UINT8 inAlpha) - : m_Red(inRed) - , m_Green(inGreen) - , m_Blue(inBlue) - , m_Alpha(inAlpha) -{ -} - -//============================================================================== -/** - * Set the color to a blend between the two given colors. - * @param inColor1 Color representing factor 0 - * @param inColor2 Color representing factor 1.0 - * @param inFactor Blend factor where 0.5 is an even mix of the two colors - */ -void CColor::Interpolate(const CColor &inColor1, const CColor &inColor2, const FLOAT inFactor) -{ - // m_Red = static_cast( rand() % 256 );//( 1.0f - inFactor ) * inColor1.m_Red + - //inFactor * inColor2.m_Red ); - // m_Green = static_cast( rand() % 256 );//( 1.0f - inFactor ) * inColor1.m_Green + - //inFactor * inColor2.m_Green ); - // m_Blue = static_cast( rand() % 256 );//( 1.0f - inFactor ) * inColor1.m_Blue + - //inFactor * inColor2.m_Blue ); - // m_Alpha = 255;//static_cast( ( 1.0f - inFactor ) * inColor1.m_Alpha + inFactor * - //inColor2.m_Alpha ); - - m_Red = static_cast((1.0f - inFactor) * inColor1.m_Red + inFactor * inColor2.m_Red); - m_Green = - static_cast((1.0f - inFactor) * inColor1.m_Green + inFactor * inColor2.m_Green); - m_Blue = static_cast((1.0f - inFactor) * inColor1.m_Blue + inFactor * inColor2.m_Blue); - m_Alpha = - static_cast((1.0f - inFactor) * inColor1.m_Alpha + inFactor * inColor2.m_Alpha); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSCubicRoots.cpp b/src/Runtime/Source/System/Source/Qt3DSCubicRoots.cpp deleted file mode 100644 index ebcc54b8..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSCubicRoots.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSCubicRoots.h" -#include "Qt3DSDataLogger.h" -#include "Qt3DSCubicRootsImpl.h" diff --git a/src/Runtime/Source/System/Source/Qt3DSDLLManager.cpp b/src/Runtime/Source/System/Source/Qt3DSDLLManager.cpp deleted file mode 100644 index c6f6d80d..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSDLLManager.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//============================================================================== -// Includes -//============================================================================== -#include "SystemPrefix.h" -#include "Qt3DSDLLManager.h" -#include "Qt3DSBasicPluginDLL.h" -#include -#ifdef _LINUXPLATFORM -#include -#endif - -using namespace Q3DStudio; - -//============================================================================== -/** - * Comparator for DLL instances. - * Compares by plugin type and handle - */ -namespace Q3DStudio { -bool operator==(const _SDLLInfo &inInfo1, const _SDLLInfo &inInfo2) -{ - return (inInfo1.m_Type == inInfo2.m_Type) && (inInfo1.m_Handle == inInfo2.m_Handle); -} -} - -//============================================================================== -/** - * Singleton getter - */ -CDLLManager &CDLLManager::GetDLLManager() -{ - static CDLLManager theDLLManager = CDLLManager(); - return theDLLManager; -} - -//============================================================================== -/** - * CTOR - */ -CDLLManager::CDLLManager() -{ -} - -//============================================================================== -/** - * DTOR - */ -CDLLManager::~CDLLManager() -{ -} - -//============================================================================== -/** - * Cleanup - */ -void CDLLManager::Cleanup() -{ - m_LoadedLibraries.Clear(true); -} - -//============================================================================== -/** - * Loads a DLL/shared library given a path to the library plugin and the plugin - * type to expect. - */ -long CDLLManager::LoadLibrary(const char *inLibraryPath, long inPluginType) -{ - long theEmptyIndex = NVARRAY_NOTFOUND; -#ifdef _PCPLATFORM - DLLHANDLE theHandle = ::LoadLibraryA(inLibraryPath); -#endif - -#ifdef _LINUXPLATFORM - DLLHANDLE theHandle = ::dlopen(inLibraryPath, RTLD_NOW); - - if (!theHandle) { - const char *error = ::dlerror(); - qWarning() << "Failed to load shared library, error:" << QStringLiteral("%1, full path: %2").arg(error).arg(inLibraryPath); - } - -#endif - -#ifdef _INTEGRITYPLATFORM - DLLHANDLE theHandle = 0; - qWarning() << "CDLLManager::LoadLibrary handle is zero!"; -#endif - - Q3DStudio_ASSERT(theHandle); - - if (theHandle != NULL) { - SDLLInfo theInfo; - PROC_GetPluginType theProc = - reinterpret_cast(GetProc("GetPluginType", theHandle)); - Q3DStudio_ASSERT(theProc); - - if (theProc) { - theInfo.m_Type = theProc(); - - if (theInfo.m_Type == inPluginType) { - theEmptyIndex = m_LoadedLibraries.GetIndex(theInfo); - theInfo.m_Handle = theHandle; - - if (theEmptyIndex == NVARRAY_NOTFOUND) { - m_LoadedLibraries.Push(theInfo); - theEmptyIndex = m_LoadedLibraries.GetCount() - 1; - } else - m_LoadedLibraries[theEmptyIndex] = theInfo; - } - } - - if (theEmptyIndex == NVARRAY_NOTFOUND) { -#ifdef _PCPLATFORM - ::FreeLibrary(theHandle); -#endif - -#ifdef _LINUXPLATFORM - ::dlclose(theHandle); -#endif - } - } - - return theEmptyIndex; -} - -//============================================================================== -/** - * Unloads a DLL given a handle - */ -void CDLLManager::UnloadLibrary(const long inHandle) -{ - if (inHandle >= 0 && inHandle < m_LoadedLibraries.GetCount()) { -#ifdef _PCPLATFORM - ::FreeLibrary(m_LoadedLibraries[inHandle].m_Handle); -#endif - -#ifdef _LINUXPLATFORM - ::dlclose(m_LoadedLibraries[inHandle].m_Handle); -#endif - - m_LoadedLibraries[inHandle] = SDLLInfo(); - } -} - -//============================================================================== -/** - * Retrieves a DLL proc given the proc name - */ -void *CDLLManager::GetProc(const char *inProcName, long inHandle) -{ - if (inHandle >= 0 && inHandle < m_LoadedLibraries.GetCount()) - return GetProc(inProcName, m_LoadedLibraries[inHandle].m_Handle); - - return NULL; -} - -//============================================================================== -/** - * Retrieves a DLL proc fiven the proc name - */ -void *CDLLManager::GetProc(const char *inProcName, const DLLHANDLE inHandle) -{ -#ifdef _PCPLATFORM -#ifdef QT3DS_VC - return ::GetProcAddress(inHandle, inProcName); -#else - return (void *)(::GetProcAddress(inHandle, inProcName)); -#endif -#endif - -#ifdef _LINUXPLATFORM - return ::dlsym(inHandle, inProcName); -#endif - -#ifdef _INTEGRITYPLATFORM - qWarning() << "CDLLManager::GetProc returns NULL!"; - return NULL; -#endif -} - -//============================================================================== -/** - * Retrieves the plugin type for the DLL - */ -template -EEnumType CDLLManager::GetPluginType(long inHandle) -{ - if (inHandle >= 0 && inHandle < m_LoadedLibraries.GetCount()) - return static_cast(m_LoadedLibraries[inHandle].m_Type); - - return 0; -} diff --git a/src/Runtime/Source/System/Source/Qt3DSDataLogger.cpp b/src/Runtime/Source/System/Source/Qt3DSDataLogger.cpp deleted file mode 100644 index 2f45f012..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSDataLogger.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSDataLogger.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -CDataLogger::SExternalFunctors CDataLogger::m_Functors; -CDataLogger::EDataLoggerLevel CDataLogger::m_LogLevel = CDataLogger::LOG_LEVEL_INVALID; -BOOL CDataLogger::m_Enabled = false; - -// Developers - change out the = NULL to = class::LogEntry to log specific stuff. -template <> -TPerfLogGeneralEvent1::TLogEntryInternal TPerfLogGeneralEvent1::m_InternalLogFunc = NULL; -template <> -TPerfLogGeneralEvent2::TLogEntryInternal TPerfLogGeneralEvent2::m_InternalLogFunc = NULL; - -template <> -TPerfLogRenderEvent1::TLogEntryInternal TPerfLogRenderEvent1::m_InternalLogFunc = NULL; -template <> -TPerfLogSceneEvent1::TLogEntryInternal TPerfLogSceneEvent1::m_InternalLogFunc = NULL; - -template <> -TPerfLogMathEvent1::TLogEntryInternal TPerfLogMathEvent1::m_InternalLogFunc = NULL; -template <> -TPerfLogPresentationEvent1::TLogEntryInternal TPerfLogPresentationEvent1::m_InternalLogFunc = NULL; -template <> -TPerfLogRenderEvent2::TLogEntryInternal TPerfLogRenderEvent2::m_InternalLogFunc = NULL; - -//============================================================================== -/** - * Set the application supplied functors to use for getting time and handling - * the writing out of data - */ -void CDataLogger::SetFunctors(SExternalFunctors inFunctors) -{ - m_Functors = inFunctors; -} - -//============================================================================== -/** -* Call into the specified functors to make stuff happen -*/ -void CDataLogger::LogEntry(UINT32 inEntryEnum, BOOL inStartFlag) -{ - if (m_Enabled && m_Functors.m_GetTimeFunc && m_Functors.m_WriteFunc && m_Functors.m_UserData) { - // Initialize to the correct values - SPerfLogEntry theEntry(inEntryEnum, inStartFlag, - m_Functors.m_GetTimeFunc(m_Functors.m_UserData)); - m_Functors.m_WriteFunc(m_Functors.m_UserData, theEntry); - } -} - -//============================================================================== -/** -* Enable logging -*/ -void CDataLogger::Enable() -{ - SetLogLevel(m_LogLevel); - m_Enabled = true; -} - -//============================================================================== -/** -* Disable logging -*/ -void CDataLogger::Disable() -{ - m_Enabled = false; -} - -//============================================================================== -/** - * XXX - */ -void CDataLogger::SetLogLevel(EDataLoggerLevel inLogLevel) -{ - switch (inLogLevel) { - // No logging - case LOG_LEVEL_NONE: - TPerfLogGeneralEvent1::Disable(); - TPerfLogGeneralEvent2::Disable(); - - TPerfLogRenderEvent1::Disable(); - TPerfLogSceneEvent1::Disable(); - - TPerfLogMathEvent1::Disable(); - TPerfLogPresentationEvent1::Disable(); - TPerfLogRenderEvent2::Disable(); - break; - - case LOG_LEVEL_3: - TPerfLogMathEvent1::Enable(); - TPerfLogPresentationEvent1::Enable(); - TPerfLogRenderEvent2::Enable(); - - case LOG_LEVEL_2: - TPerfLogRenderEvent1::Enable(); - TPerfLogSceneEvent1::Enable(); - - case LOG_LEVEL_1: - TPerfLogGeneralEvent1::Enable(); - TPerfLogGeneralEvent2::Enable(); - break; - - case LOG_LEVEL_INVALID: - default: - m_LogLevel = LOG_LEVEL_INVALID; - return; - break; - } - m_LogLevel = inLogLevel; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSEulerAngles.cpp b/src/Runtime/Source/System/Source/Qt3DSEulerAngles.cpp deleted file mode 100644 index 7c4364fc..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSEulerAngles.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include -#include -#include -#include -#include "Qt3DSEulerAngles.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4365) // warnings on conversion from unsigned int to int -#endif - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - */ -CEulerAngleConverter::CEulerAngleConverter() -{ - m_OrderInfoBuffer[0] = '\0'; -} - -//============================================================================== -/** - * Destructor - */ -CEulerAngleConverter::~CEulerAngleConverter() -{ -} - -//============================================================================== -/** - * Constructs a Euler angle & holds it in a EulerAngles struct - * @param theI x rotation ( radians ) - * @param theJ y rotation ( radians ) - * @param theH z rotation ( radians ) - * @param theOrder the order this angle is in namely XYZ( static ), etc. - * use the EulOrd**** macros to generate values - * 0 to 23 is valid - * @return the euler angle - */ -EulerAngles CEulerAngleConverter::Eul_(float theI, float theJ, float theH, int theOrder) -{ - EulerAngles theEulerAngle; - theEulerAngle.x = theI; - theEulerAngle.y = theJ; - theEulerAngle.z = theH; - theEulerAngle.w = (float)theOrder; - return theEulerAngle; -} - -//============================================================================== -/** - * Construct quaternion from Euler angles (in radians). - * @param theEulerAngle incoming angle( radians ) - * @return the Quaternion - */ -Quat CEulerAngleConverter::Eul_ToQuat(EulerAngles theEulerAngle) -{ - Quat theQuaternion; - double a[3], ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; - int i, j, k, h, n, s, f; - - EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); - if (f == EulFrmR) { - float t = theEulerAngle.x; - theEulerAngle.x = theEulerAngle.z; - theEulerAngle.z = t; - } - - if (n == EulParOdd) - theEulerAngle.y = -theEulerAngle.y; - - ti = theEulerAngle.x * 0.5; - tj = theEulerAngle.y * 0.5; - th = theEulerAngle.z * 0.5; - - ci = cos(ti); - cj = cos(tj); - ch = cos(th); - - si = sin(ti); - sj = sin(tj); - sh = sin(th); - - cc = ci * ch; - cs = ci * sh; - sc = si * ch; - ss = si * sh; - - if (s == EulRepYes) { - a[i] = cj * (cs + sc); /* Could speed up with */ - a[j] = sj * (cc + ss); /* trig identities. */ - a[k] = sj * (cs - sc); - theQuaternion.w = (float)(cj * (cc - ss)); - } else { - a[i] = cj * sc - sj * cs; - a[j] = cj * ss + sj * cc; - a[k] = cj * cs - sj * sc; - theQuaternion.w = (float)(cj * cc + sj * ss); - } - if (n == EulParOdd) - a[j] = -a[j]; - - theQuaternion.x = (float)a[X]; - theQuaternion.y = (float)a[Y]; - theQuaternion.z = (float)a[Z]; - return theQuaternion; -} - -//============================================================================== -/** - * Construct matrix from Euler angles (in radians). - * @param theEulerAngle incoming angle - * @param theMatrix outgoing matrix - */ -void CEulerAngleConverter::Eul_ToHMatrix(EulerAngles theEulerAngle, HMatrix theMatrix) -{ - double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; - int i, j, k, h, n, s, f; - EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); - - if (f == EulFrmR) { - float t = theEulerAngle.x; - theEulerAngle.x = theEulerAngle.z; - theEulerAngle.z = t; - } - - if (n == EulParOdd) { - theEulerAngle.x = -theEulerAngle.x; - theEulerAngle.y = -theEulerAngle.y; - theEulerAngle.z = -theEulerAngle.z; - } - - ti = theEulerAngle.x; - tj = theEulerAngle.y; - th = theEulerAngle.z; - - ci = cos(ti); - cj = cos(tj); - ch = cos(th); - - si = sin(ti); - sj = sin(tj); - sh = sin(th); - - cc = ci * ch; - cs = ci * sh; - sc = si * ch; - ss = si * sh; - - if (s == EulRepYes) { - theMatrix[i][i] = (float)cj; - theMatrix[i][j] = (float)(sj * si); - theMatrix[i][k] = (float)(sj * ci); - theMatrix[j][i] = (float)(sj * sh); - theMatrix[j][j] = (float)(-cj * ss + cc); - theMatrix[j][k] = (float)(-cj * cs - sc); - theMatrix[k][i] = (float)(-sj * ch); - theMatrix[k][j] = (float)(cj * sc + cs); - theMatrix[k][k] = (float)(cj * cc - ss); - } else { - theMatrix[i][i] = (float)(cj * ch); - theMatrix[i][j] = (float)(sj * sc - cs); - theMatrix[i][k] = (float)(sj * cc + ss); - theMatrix[j][i] = (float)(cj * sh); - theMatrix[j][j] = (float)(sj * ss + cc); - theMatrix[j][k] = (float)(sj * cs - sc); - theMatrix[k][i] = (float)(-sj); - theMatrix[k][j] = (float)(cj * si); - theMatrix[k][k] = (float)(cj * ci); - } - - theMatrix[W][X] = 0.0; - theMatrix[W][Y] = 0.0; - theMatrix[W][Z] = 0.0; - theMatrix[X][W] = 0.0; - theMatrix[Y][W] = 0.0; - theMatrix[Z][W] = 0.0; - theMatrix[W][W] = 1.0; -} - -//============================================================================== -/** - * Convert matrix to Euler angles (in radians). - * @param theMatrix incoming matrix - * @param theOrder 0-23, use EulOrd**** to generate this value - * @return a set of angles in radians!!!! - */ -EulerAngles CEulerAngleConverter::Eul_FromHMatrix(HMatrix theMatrix, int theOrder) -{ - EulerAngles theEulerAngle; - int i, j, k, h, n, s, f; - - EulGetOrd(theOrder, i, j, k, h, n, s, f); - if (s == EulRepYes) { - double sy = sqrt(theMatrix[i][j] * theMatrix[i][j] + theMatrix[i][k] * theMatrix[i][k]); - if (sy > 16 * FLT_EPSILON) { - theEulerAngle.x = (float)(atan2((double)theMatrix[i][j], (double)theMatrix[i][k])); - theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); - theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], -(double)theMatrix[k][i])); - } else { - theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); - theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); - theEulerAngle.z = 0; - } - } else { - double cy = sqrt(theMatrix[i][i] * theMatrix[i][i] + theMatrix[j][i] * theMatrix[j][i]); - if (cy > 16 * FLT_EPSILON) { - theEulerAngle.x = (float)(atan2((double)theMatrix[k][j], (double)theMatrix[k][k])); - theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); - theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], (double)theMatrix[i][i])); - } else { - theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); - theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); - theEulerAngle.z = 0; - } - } - - if (n == EulParOdd) { - theEulerAngle.x = -theEulerAngle.x; - theEulerAngle.y = -theEulerAngle.y; - theEulerAngle.z = -theEulerAngle.z; - } - - if (f == EulFrmR) { - float t = theEulerAngle.x; - theEulerAngle.x = theEulerAngle.z; - theEulerAngle.z = t; - } - theEulerAngle.w = (float)theOrder; - return theEulerAngle; -} - -//============================================================================== -/** - * Convert quaternion to Euler angles (in radians). - * @param theQuaternion incoming quaternion - * @param theOrder 0-23, use EulOrd**** to generate this value - * @return the generated angles ( radians ) - */ -EulerAngles CEulerAngleConverter::Eul_FromQuat(Quat theQuaternion, int theOrder) -{ - HMatrix theMatrix; - double Nq = theQuaternion.x * theQuaternion.x + theQuaternion.y * theQuaternion.y - + theQuaternion.z * theQuaternion.z + theQuaternion.w * theQuaternion.w; - double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; - double xs = theQuaternion.x * s; - double ys = theQuaternion.y * s; - double zs = theQuaternion.z * s; - double wx = theQuaternion.w * xs; - double wy = theQuaternion.w * ys; - double wz = theQuaternion.w * zs; - double xx = theQuaternion.x * xs; - double xy = theQuaternion.x * ys; - double xz = theQuaternion.x * zs; - double yy = theQuaternion.y * ys; - double yz = theQuaternion.y * zs; - double zz = theQuaternion.z * zs; - - theMatrix[X][X] = (float)(1.0 - (yy + zz)); - theMatrix[X][Y] = (float)(xy - wz); - theMatrix[X][Z] = (float)(xz + wy); - theMatrix[Y][X] = (float)(xy + wz); - theMatrix[Y][Y] = (float)(1.0 - (xx + zz)); - theMatrix[Y][Z] = (float)(yz - wx); - theMatrix[Z][X] = (float)(xz - wy); - theMatrix[Z][Y] = (float)(yz + wx); - theMatrix[Z][Z] = (float)(1.0 - (xx + yy)); - theMatrix[W][X] = 0.0; - theMatrix[W][Y] = 0.0; - theMatrix[W][Z] = 0.0; - theMatrix[X][W] = 0.0; - theMatrix[Y][W] = 0.0; - theMatrix[Z][W] = 0.0; - theMatrix[W][W] = 1.0; - - return Eul_FromHMatrix(theMatrix, theOrder); -} - -//============================================================================== -/** - * Dump the Order information - */ -const char *CEulerAngleConverter::DumpOrderInfo() -{ - long theCount = 0; - long theOrder[24]; - char theOrderStr[24][16]; - - ::strcpy(theOrderStr[theCount++], "EulOrdXYZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdXYXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXYs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYXs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYZs"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXYXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZXr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXZYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYZYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXYr"); - ::strcpy(theOrderStr[theCount++], "EulOrdYXZr"); - ::strcpy(theOrderStr[theCount++], "EulOrdZXZr"); - ::strcpy(theOrderStr[theCount++], "EulOrdXYZr"); - ::strcpy(theOrderStr[theCount++], "EulOrdZYZr"); - - theCount = 0; - theOrder[theCount++] = EulOrdXYZs; - theOrder[theCount++] = EulOrdXYXs; - theOrder[theCount++] = EulOrdXZYs; - theOrder[theCount++] = EulOrdXZXs; - theOrder[theCount++] = EulOrdYZXs; - theOrder[theCount++] = EulOrdYZYs; - theOrder[theCount++] = EulOrdYXZs; - theOrder[theCount++] = EulOrdYXYs; - theOrder[theCount++] = EulOrdZXYs; - theOrder[theCount++] = EulOrdZXZs; - theOrder[theCount++] = EulOrdZYXs; - theOrder[theCount++] = EulOrdZYZs; - - theOrder[theCount++] = EulOrdZYXr; - theOrder[theCount++] = EulOrdXYXr; - theOrder[theCount++] = EulOrdYZXr; - theOrder[theCount++] = EulOrdXZXr; - theOrder[theCount++] = EulOrdXZYr; - theOrder[theCount++] = EulOrdYZYr; - theOrder[theCount++] = EulOrdZXYr; - theOrder[theCount++] = EulOrdYXYr; - theOrder[theCount++] = EulOrdYXZr; - theOrder[theCount++] = EulOrdZXZr; - theOrder[theCount++] = EulOrdXYZr; - theOrder[theCount++] = EulOrdZYZr; - - char theSubBuf[256]; - m_OrderInfoBuffer[0] = '\0'; - for (long theIndex = 0; theIndex < 24; ++theIndex) { - ::sprintf(theSubBuf, " %16s - %ld\n ", theOrderStr[theIndex], theOrder[theIndex]); - ::strcat(m_OrderInfoBuffer, theSubBuf); - } - - return m_OrderInfoBuffer; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSFile.cpp b/src/Runtime/Source/System/Source/Qt3DSFile.cpp deleted file mode 100644 index a26b7351..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSFile.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSFile.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// OS level memory routines -//============================================================================== -#if defined(_XENONPLATFORM) || defined(_PCPLATFORM) || defined(_PS3PLATFORM) \ - || defined(_TEGRAPLATFORM) || defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -CFile::TOpen CFile::s_Open = &fopen; -CFile::TClose CFile::s_Close = &fclose; -CFile::TRead CFile::s_Read = &fread; -CFile::TWrite CFile::s_Write = &fwrite; -CFile::TTell CFile::s_Tell = &ftell; -CFile::TSeek CFile::s_Seek = &fseek; -#else -#error "A platform must be defined" -#endif - -//============================================================================== -/** - * Overrides basic memory allocation/deallocation routines - * @param inOpen fopen replacement method - * @param inClose fclose replacement method - * @param inRead fread replacement method - * @param inWrite fwrite replacement method - */ -void CFile::SetFileFunctions(const TOpen inOpen, const TClose inClose, const TRead inRead, - const TWrite inWrite, const TTell inTell, const TSeek inSeek) -{ - s_Open = inOpen; - s_Close = inClose; - s_Read = inRead; - s_Write = inWrite; - s_Tell = inTell; - s_Seek = inSeek; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSFileStream.cpp b/src/Runtime/Source/System/Source/Qt3DSFileStream.cpp deleted file mode 100644 index 202e4ae7..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSFileStream.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "SystemPrefix.h" -#include "Qt3DSFile.h" -#include "Qt3DSFileStream.h" -#include "foundation/Qt3DSLogging.h" - -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - * @param inFilename the file to open - * @param inMode the file mode to use - */ -CFileStream::CFileStream(const CHAR *inFilePath, const CHAR *inMode, BOOL inKeepTrying) - : m_FileStream(NULL) - , m_Endian(QT3DS_LITTLE_ENDIAN) - , m_KeepTrying(inKeepTrying) -{ - m_TempBuffer.Reserve(sizeof(MATRIX16)); // Preallocated some space - if (inFilePath) - Open(inFilePath, inMode); -} - -//============================================================================== -/** - * Destructor - */ -CFileStream::~CFileStream() -{ - Close(); -} - -//============================================================================== -/** - * Open file. - * @param inFilename the file to open - * @param inMode the file mode ( read/write ) to use - */ -void CFileStream::Open(const CHAR *inFilePath, const CHAR *inMode) -{ - Close(); - m_FileStream = CFile::Open()(inFilePath, inMode); - while (m_KeepTrying && !m_FileStream) { - QThread::msleep(10); - m_FileStream = CFile::Open()(inFilePath, inMode); - } - - if (m_FileStream) - m_FilePath = inFilePath; -} - -//============================================================================== -/** - * Close file. - */ -void CFileStream::Close() -{ - if (m_FileStream) { - CFile::Close()(m_FileStream); - m_FileStream = NULL; - } -} - -//============================================================================== -/** - * Check if there is an opened file. - * @return TRUE if opened, FALSE otherwise. - */ -BOOL CFileStream::IsOpen() const -{ - return m_FileStream != NULL; -} - -//============================================================================== -/** - * Access the source path of a file stream. - * @return an empty string if the stream is not open - */ -const CHAR *CFileStream::GetFilePath() const -{ - return m_FilePath.toLatin1().constData(); -} - -//============================================================================== -/** - * Read from stream into memory. - * @param outMemory the destination of the read - * @param inByteCount the amount to read - * @return the number of bytes actually read - */ -INT32 CFileStream::ReadRawCopy(void *inDestination, const UINT32 inByteCount) -{ - INT32 lastRead = 0; - INT32 totalRead = 0; - do { - if (totalRead) { - qCWarning(qt3ds::INVALID_OPERATION) - << "Failed to read expected amount, retrying, expected " - << inByteCount << " bytes, got "<< totalRead <<" bytes"; - } - lastRead = static_cast(CFile::Read()(((char *)inDestination) + totalRead, 1, - inByteCount - totalRead, m_FileStream)); - totalRead += lastRead; - } while (lastRead && totalRead < (INT32)inByteCount); - - if (totalRead != (INT32)inByteCount) { - qCWarning(qt3ds::INVALID_OPERATION) - << "Failed to read expected amount, retrying, expected " - << inByteCount << " bytes, got "<< totalRead <<" bytes"; - - // Zero out remaining destination buffer. - // This can, in some cases, avoid a crash and allow the system to survive a partial - // read. - INT32 amountLeft = inByteCount - totalRead; - memset(((char *)inDestination) + totalRead, 0, amountLeft); - } - return totalRead; -} - -//============================================================================== -/** - * Reads data into internal buffer and return the data pointer for it. - * @param outMemory pointer to internal data buffer - * @param inByteCount the amount to read - * @return the number of bytes actually read - */ -INT32 CFileStream::ReadRaw(const void *&inPtr, const UINT32 inByteCount) -{ - m_TempBuffer.Reserve(static_cast(inByteCount)); - INT32 theReadSize = ReadRawCopy(m_TempBuffer.Begin(), inByteCount); - if (theReadSize != (INT32)inByteCount) { - qCWarning(qt3ds::INVALID_OPERATION) - << "Failed to read expected amount, retrying, expected "<< inByteCount - << " bytes, got "<< theReadSize <<" bytes"; - } - inPtr = m_TempBuffer.Begin(); - return theReadSize; -} - -//============================================================================== -/** - * Write from memory to stream. - * @param inMemory the buffer to write from - * @param inByteCount the amount to write - * @return the number of bytes actually written - */ -INT32 CFileStream::WriteRaw(const void *inSource, const UINT32 inByteCount) -{ - return static_cast(CFile::Write()(inSource, 1, inByteCount, m_FileStream)); -} - -//============================================================================== -/** - * Offsets the file position by the specified number of bytes - */ -void CFileStream::Offset(const INT32 inByteCount) -{ - CFile::Seek()(m_FileStream, inByteCount, CFile::E_SEEK_CUR); -} - -//============================================================================== -/** - * Returns the current position of the file stream - */ -IStream::TStreamPosition CFileStream::Current() -{ - return static_cast(CFile::Tell()(m_FileStream)); -} - -//============================================================================== -/** - * Sets the stream to the specified position within the file - */ -void CFileStream::Set(const TStreamPosition &inPosition) -{ - CFile::Seek()(m_FileStream, inPosition, CFile::E_SEEK_SET); -} - -//============================================================================== -/** - * Set the endianess of the file. - * @warning endian support not implemented - */ -void CFileStream::SetEndian(const BOOL inEndian) -{ - m_Endian = inEndian; -} - -//============================================================================== -/** - * Get the endianess of the file. - * @warning endian support not implemented - */ -BOOL CFileStream::GetEndian() -{ - return m_Endian; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSFunctionWrappers.cpp b/src/Runtime/Source/System/Source/Qt3DSFunctionWrappers.cpp deleted file mode 100644 index e96c3ce1..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSFunctionWrappers.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2010 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "SystemPrefix.h" -#include "Qt3DSFunctionWrappers.h" - -using namespace Q3DStudio; - -//============================================================================== -/** -* CTOR -*/ -IFunctionWrapper::IFunctionWrapper() - : m_Cost(0) -{ -} - -//============================================================================== -/** -* Retrieve the cost associated with this function. -* Should be zero or greater -*/ -INT32 IFunctionWrapper::GetCost() -{ - return m_Cost; -} - -//============================================================================== -/** -* Sets the cost associated with this function. -*/ -void IFunctionWrapper::SetCost(const INT32 inCost) -{ - m_Cost = inCost; -} \ No newline at end of file diff --git a/src/Runtime/Source/System/Source/Qt3DSMatrix.cpp b/src/Runtime/Source/System/Source/Qt3DSMatrix.cpp deleted file mode 100644 index b5310d0e..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMatrix.cpp +++ /dev/null @@ -1,897 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMatrix.h" -#include "Qt3DSVector3.h" -#include "Qt3DSEulerAngles.h" -#include "Qt3DSDataLogger.h" -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -FLOAT g_IdentityInit[4][4] = { { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } }; - -const RuntimeMatrix RuntimeMatrix::IDENTITY = RuntimeMatrix(g_IdentityInit); -extern const FLOAT RUNTIME_EPSILON; - -//============================================================================== -/** - * Empty constructor. - * Initializes this matrix to the identity matrix. - */ -RuntimeMatrix::RuntimeMatrix(const BOOL inInitializeIdentity /*= true*/) -{ - if (inInitializeIdentity) - Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); -} - -//============================================================================== -/** - * Copy constructor. - * @param inMatrix the source matrix to copy - */ -RuntimeMatrix::RuntimeMatrix(const RuntimeMatrix &inMatrix) -{ - Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); -} - -//============================================================================== -/** - * Assignment constructor. - * Initializes the matrix from an array. - * @param inComponents an array of 16 values - */ -RuntimeMatrix::RuntimeMatrix(const FLOAT inComponents[4][4]) -{ - if (inComponents) - Q3DStudio_memcpy(&m_Data, inComponents, sizeof(m_Data)); -} - -//============================================================================== -/** - * Sets this matrix to a NULL matrix with all values at zero. - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Zero() -{ - Q3DStudio_memset(&m_Data, 0, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Sets the matrix to the identity matrix. - * @return reference to this matrix - */ -RuntimeMatrix &RuntimeMatrix::Identity() -{ - Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Copies the elements from another matrix. - * @param inMatrix the source matrix - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Set(const RuntimeMatrix &inMatrix) -{ - Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Copies the given components to this matrix. - * @param inComponents an array of 16 components - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Set(const FLOAT inComponents[4][4]) -{ - if (inComponents) - Q3DStudio_memcpy(&m_Data, inComponents, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Heavily optimized assignment method. This has the same result as creating - * four full 4x4 matrices and multiplying them together. - * @todo Look into optimized code. - * @param inTranslation translation coordinates - * @param inRotation Euler angle rotations - * @param inScale scaling dimensions - * @param inPivot pivot offset vector - * @param inRotationOrder rotation order - * @param inCoordinateSystem the coordindate system - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Set(const RuntimeVector3 &inTranslation, const RuntimeVector3 &inRotation, - const RuntimeVector3 &inScale, const RuntimeVector3 &inPivot, const UINT8 inRotationOrder, - const UINT8 inCoordinateSystem) -{ - // *this = m_ScaleMatrix * m_PivotMatrix * m_RotMatrix * m_TransMatrix; // Distributed - //original - plain speak - - RuntimeVector3 theScaledPivot; - theScaledPivot.m_X = -inPivot.m_X * inScale.m_X; - theScaledPivot.m_Y = -inPivot.m_Y * inScale.m_Y; - theScaledPivot.m_Z = -inPivot.m_Z * inScale.m_Z; - - // This would take care of rotation in the right order - RuntimeMatrix theRotation; - theRotation.SetRotate(inRotation, inRotationOrder, inCoordinateSystem); - - Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); - m_Data[0][0] = inScale.m_X; - m_Data[1][1] = inScale.m_Y; - m_Data[2][2] = inScale.m_Z; - - m_Data[3][0] = theScaledPivot.m_X; - m_Data[3][1] = theScaledPivot.m_Y; - - if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) - m_Data[3][2] = theScaledPivot.m_Z; - else - m_Data[3][2] = -theScaledPivot.m_Z; - - MultiplyAffine(theRotation); // This could be optimized to only 9 multiplications instead of 16 - // if you do them by hand - - m_Data[3][0] += inTranslation.m_X; - m_Data[3][1] += inTranslation.m_Y; - - if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) - m_Data[3][2] += inTranslation.m_Z; - else - m_Data[3][2] += -inTranslation.m_Z; - - if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) - return FlipCoordinateSystem(); - - return *this; -} - -//============================================================================== -/** - * Sets the translation portion of the matrix without affecting the rest. - * - * If you want a pure translation matrix you must make sure to start with - * the identity matrix. - * @param inTranslate a translation vector - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::SetTranslate(const RuntimeVector3 &inTranslate) -{ - m_Data[3][0] = inTranslate.m_X; - m_Data[3][1] = inTranslate.m_Y; - m_Data[3][2] = inTranslate.m_Z; - return *this; -} - -//============================================================================== -/** - * Sets the rotation portion of the matrix without affecting the rest. - * - * FYI: The rotate and scale portions overlap. If you want a pure scale matrix - * you must make sure to start with the identity matrix. - * @param inRotation a quaternion describing the rotation - * @return reference to this modified matrix - */ -// CMatrix& CMatrix::SetRotate( const CQuaternion& inRotation ) -//{ -// inRotation.ToMatrix( *this ); -// return *this; -//} - -//============================================================================== -/** - * Sets the rotation portion of the matrix without affecting the rest. - * - * FYI: The rotate and scale portions overlap. If you want a pure rotation matrix - * you must make sure to start with the identity matrix. - * @param inRotation Euler angle rotation - * @param inRotationOrder rotation order - * @param inCoordinateSystem the coordindate system - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::SetRotate(const RuntimeVector3 &inRotation, const UINT8 inRotationOrder, - const UINT8 inCoordinateSystem) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - Q3DStudio_UNREFERENCED_PARAMETER(inCoordinateSystem); - - EulerAngles theEulerAngles; - switch (inRotationOrder) { - case ROTATIONORDER_XYZ: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdXYZs; - break; - case ROTATIONORDER_XYZR: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdXYZr; - break; - case ROTATIONORDER_YZX: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdYZXs; - break; - case ROTATIONORDER_YZXR: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdYZXr; - break; - case ROTATIONORDER_ZXY: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdZXYs; - break; - case ROTATIONORDER_ZXYR: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdZXYr; - break; - case ROTATIONORDER_XZY: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdXZYs; - break; - case ROTATIONORDER_XZYR: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdXZYr; - break; - case ROTATIONORDER_YXZ: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdYXZs; - break; - case ROTATIONORDER_YXZR: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdYXZr; - break; - case ROTATIONORDER_ZYX: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdZYXs; - break; - case ROTATIONORDER_ZYXR: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdZYXr; - break; - default: // defaults to Studio's rotation type - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdYXZs; - break; - } - - theEulerAngles.x *= -1; - theEulerAngles.y *= -1; - theEulerAngles.z *= -1; - - CEulerAngleConverter theConverter; - theConverter.Eul_ToHMatrix(theEulerAngles, m_Data); - - return *this; -} - -//============================================================================== -/** - * Sets the scale portion of the matrix without affecting the rest. - * - * FYI: The rotate and scale portions overlap. If you want a pure scale matrix - * you must make sure to start with the identity matrix. - * @param inScale scale vector - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::SetScale(const RuntimeVector3 &inScale) -{ - m_Data[0][0] = inScale.m_X; - m_Data[1][1] = inScale.m_Y; - m_Data[2][2] = inScale.m_Z; - return *this; -} - -//============================================================================== -/** - * Check this matrix against the identity matrix. - * @return true if this matrix is equivalent to the identity matrix - */ -BOOL RuntimeMatrix::IsIdentity() const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - return *this == IDENTITY; -} - -//============================================================================== -/** - * Checks to see if this matrix is affine. - * An affine matrix has the last row being [ 0 0 0 1 ] - * @return true if the matrix is affine - */ -BOOL RuntimeMatrix::IsAffine() const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - return m_Data[0][3] == 0 && m_Data[1][3] == 0 && m_Data[2][3] == 0 && m_Data[3][3] == 1.0f; -} - -//============================================================================== -/** - * Appends the matrix to include a translation. Equivalent to post-multiplying - * this matrix with a transformation matrix derived from the given vector. - * @param inTranslation transformation vector applied - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Translate(const RuntimeVector3 &inTranslation) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - m_Data[3][0] += inTranslation.m_X; - m_Data[3][1] += inTranslation.m_Y; - m_Data[3][2] += inTranslation.m_Z; - return *this; -} - -//============================================================================== -/** - * Appends the matrix to include a rotation. Equivalent to post-multiplying - * this matrix with a rotation matrix derived from the given quaternion. - * @param inRotation the rotation quaternion applied - * @return reference to this modified matrix - */ -// CMatrix& CMatrix::Rotate( const CQuaternion& inRotation ) -//{ -// CMatrix theRotation; -// return MultiplyAffine( inRotation.ToMatrix( theRotation ) ); -//} - -//============================================================================== -/** - * Appends the matrix to include scaling. Equivalent to post-multiplying - * this matrix with a scale matrix derived from the given vector. - * @param inScale the scale vector applied - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Scale(const RuntimeVector3 &inScale) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - m_Data[0][0] *= inScale.m_X; - m_Data[0][1] *= inScale.m_X; - m_Data[0][2] *= inScale.m_X; - - m_Data[1][0] *= inScale.m_Y; - m_Data[1][1] *= inScale.m_Y; - m_Data[1][2] *= inScale.m_Y; - - m_Data[2][0] *= inScale.m_Z; - m_Data[2][1] *= inScale.m_Z; - m_Data[2][2] *= inScale.m_Z; - return *this; -} - -//============================================================================== -/** - * Flips the matrix elements around the identity diagonal. - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Transpose() -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theSwap = m_Data[1][0]; - m_Data[1][0] = m_Data[0][1]; - m_Data[0][1] = theSwap; - - theSwap = m_Data[2][0]; - m_Data[2][0] = m_Data[0][2]; - m_Data[0][2] = theSwap; - - theSwap = m_Data[3][0]; - m_Data[3][0] = m_Data[0][3]; - m_Data[0][3] = theSwap; - - theSwap = m_Data[2][1]; - m_Data[2][1] = m_Data[1][2]; - m_Data[1][2] = theSwap; - - theSwap = m_Data[3][1]; - m_Data[3][1] = m_Data[1][3]; - m_Data[1][3] = theSwap; - - theSwap = m_Data[3][2]; - m_Data[3][2] = m_Data[2][3]; - m_Data[2][3] = theSwap; - - return *this; -} - -//============================================================================== -/** - * Compute the inverse of a 3D affine matrix; i.e. a matrix with a - * dimensionality of 4 where the bottom row has the entries (0, 0, 0, 1). - * - * This procedure treats the 4 by 4 matrix as a block matrix and - * calculates the inverse of one submatrix for a significant performance - * improvement over a general procedure that can invert any non-singular matrix: -@code - | | -1 | -1 -1 | - | A C | | A -C A | - -1 | | | | - M = | | = | | - | 0 1 | | 0 1 | - | | | | -@endcode - * where M is a 4 by 4 matrix, - * A is the 3 by 3 upper left submatrix of M, - * C is the 3 by 1 upper right submatrix of M. - * - * @return the determinant of matrix - */ -FLOAT RuntimeMatrix::Invert() -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - const FLOAT PRECISIONLIMIT = 1.0e-07f; - FLOAT thePositiveDet = 0.0f; - FLOAT theNegativeDet = 0.0f; - FLOAT theTempDet; - - // Calculate the determinant of submatrix A and determine if the - // the matrix is singular as limited by the float precision. - theTempDet = m_Data[0][0] * m_Data[1][1] * m_Data[2][2]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = m_Data[0][1] * m_Data[1][2] * m_Data[2][0]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = m_Data[0][2] * m_Data[1][0] * m_Data[2][1]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = -m_Data[0][2] * m_Data[1][1] * m_Data[2][0]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = -m_Data[0][1] * m_Data[1][0] * m_Data[2][2]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = -m_Data[0][0] * m_Data[1][2] * m_Data[2][1]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - // Is the submatrix A nonsingular? (i.e. there is an inverse?) - FLOAT theDeterminant = thePositiveDet + theNegativeDet; - if (theDeterminant != 0 - || ::fabs(theDeterminant / (thePositiveDet - theNegativeDet)) >= PRECISIONLIMIT) { - RuntimeMatrix theInverse; - FLOAT theInvDeterminant = 1.0f / theDeterminant; - - // Calculate inverse(A) = adj(A) / det(A) - theInverse.m_Data[0][0] = - (m_Data[1][1] * m_Data[2][2] - m_Data[1][2] * m_Data[2][1]) * theInvDeterminant; - theInverse.m_Data[1][0] = - -(m_Data[1][0] * m_Data[2][2] - m_Data[1][2] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[2][0] = - (m_Data[1][0] * m_Data[2][1] - m_Data[1][1] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[0][1] = - -(m_Data[0][1] * m_Data[2][2] - m_Data[0][2] * m_Data[2][1]) * theInvDeterminant; - theInverse.m_Data[1][1] = - (m_Data[0][0] * m_Data[2][2] - m_Data[0][2] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[2][1] = - -(m_Data[0][0] * m_Data[2][1] - m_Data[0][1] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[0][2] = - (m_Data[0][1] * m_Data[1][2] - m_Data[0][2] * m_Data[1][1]) * theInvDeterminant; - theInverse.m_Data[1][2] = - -(m_Data[0][0] * m_Data[1][2] - m_Data[0][2] * m_Data[1][0]) * theInvDeterminant; - theInverse.m_Data[2][2] = - (m_Data[0][0] * m_Data[1][1] - m_Data[0][1] * m_Data[1][0]) * theInvDeterminant; - - // Calculate -C * inverse(A) - theInverse.m_Data[3][0] = - -(m_Data[3][0] * theInverse.m_Data[0][0] + m_Data[3][1] * theInverse.m_Data[1][0] - + m_Data[3][2] * theInverse.m_Data[2][0]); - theInverse.m_Data[3][1] = - -(m_Data[3][0] * theInverse.m_Data[0][1] + m_Data[3][1] * theInverse.m_Data[1][1] - + m_Data[3][2] * theInverse.m_Data[2][1]); - theInverse.m_Data[3][2] = - -(m_Data[3][0] * theInverse.m_Data[0][2] + m_Data[3][1] * theInverse.m_Data[1][2] - + m_Data[3][2] * theInverse.m_Data[2][2]); - - // assign ourselves to the inverse - *this = theInverse; - } - - return theDeterminant; -} - -//============================================================================== -/** - * Fast multiplication of two affine 4x4 matrices. No affine pre-check. - * @todo MF - Convert to SSE Assembly Code - * @param inMatrix the source matrix - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::MultiplyAffine(const RuntimeMatrix &inMatrix) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theMult[4][4]; - - theMult[0][0] = m_Data[0][0] * inMatrix.m_Data[0][0] + m_Data[0][1] * inMatrix.m_Data[1][0] - + m_Data[0][2] * inMatrix.m_Data[2][0]; - theMult[0][1] = m_Data[0][0] * inMatrix.m_Data[0][1] + m_Data[0][1] * inMatrix.m_Data[1][1] - + m_Data[0][2] * inMatrix.m_Data[2][1]; - theMult[0][2] = m_Data[0][0] * inMatrix.m_Data[0][2] + m_Data[0][1] * inMatrix.m_Data[1][2] - + m_Data[0][2] * inMatrix.m_Data[2][2]; - theMult[0][3] = 0; - - theMult[1][0] = m_Data[1][0] * inMatrix.m_Data[0][0] + m_Data[1][1] * inMatrix.m_Data[1][0] - + m_Data[1][2] * inMatrix.m_Data[2][0]; - theMult[1][1] = m_Data[1][0] * inMatrix.m_Data[0][1] + m_Data[1][1] * inMatrix.m_Data[1][1] - + m_Data[1][2] * inMatrix.m_Data[2][1]; - theMult[1][2] = m_Data[1][0] * inMatrix.m_Data[0][2] + m_Data[1][1] * inMatrix.m_Data[1][2] - + m_Data[1][2] * inMatrix.m_Data[2][2]; - theMult[1][3] = 0; - - theMult[2][0] = m_Data[2][0] * inMatrix.m_Data[0][0] + m_Data[2][1] * inMatrix.m_Data[1][0] - + m_Data[2][2] * inMatrix.m_Data[2][0]; - theMult[2][1] = m_Data[2][0] * inMatrix.m_Data[0][1] + m_Data[2][1] * inMatrix.m_Data[1][1] - + m_Data[2][2] * inMatrix.m_Data[2][1]; - theMult[2][2] = m_Data[2][0] * inMatrix.m_Data[0][2] + m_Data[2][1] * inMatrix.m_Data[1][2] - + m_Data[2][2] * inMatrix.m_Data[2][2]; - theMult[2][3] = 0; - - theMult[3][0] = m_Data[3][0] * inMatrix.m_Data[0][0] + m_Data[3][1] * inMatrix.m_Data[1][0] - + m_Data[3][2] * inMatrix.m_Data[2][0] + inMatrix.m_Data[3][0]; - theMult[3][1] = m_Data[3][0] * inMatrix.m_Data[0][1] + m_Data[3][1] * inMatrix.m_Data[1][1] - + m_Data[3][2] * inMatrix.m_Data[2][1] + inMatrix.m_Data[3][1]; - theMult[3][2] = m_Data[3][0] * inMatrix.m_Data[0][2] + m_Data[3][1] * inMatrix.m_Data[1][2] - + m_Data[3][2] * inMatrix.m_Data[2][2] + inMatrix.m_Data[3][2]; - theMult[3][3] = 1.0f; - - return Set(theMult); -} - -//============================================================================== -/** - * Standard matrix multiplication - * @todo MF - Convert to SSE Assembly Code - * @param inMatrix matrix to multiply with - */ -RuntimeMatrix &RuntimeMatrix::Multiply(const RuntimeMatrix &inMatrix) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theMult[4][4]; - - theMult[0][0] = m_Data[0][0] * inMatrix.m_Data[0][0] + m_Data[1][0] * inMatrix.m_Data[0][1] - + m_Data[2][0] * inMatrix.m_Data[0][2] + m_Data[3][0] * inMatrix.m_Data[0][3]; - theMult[0][1] = m_Data[0][1] * inMatrix.m_Data[0][0] + m_Data[1][1] * inMatrix.m_Data[0][1] - + m_Data[2][1] * inMatrix.m_Data[0][2] + m_Data[3][1] * inMatrix.m_Data[0][3]; - theMult[0][2] = m_Data[0][2] * inMatrix.m_Data[0][0] + m_Data[1][2] * inMatrix.m_Data[0][1] - + m_Data[2][2] * inMatrix.m_Data[0][2] + m_Data[3][2] * inMatrix.m_Data[0][3]; - theMult[0][3] = m_Data[0][3] * inMatrix.m_Data[0][0] + m_Data[1][3] * inMatrix.m_Data[0][1] - + m_Data[2][3] * inMatrix.m_Data[0][2] + m_Data[3][3] * inMatrix.m_Data[0][3]; - theMult[1][0] = m_Data[0][0] * inMatrix.m_Data[1][0] + m_Data[1][0] * inMatrix.m_Data[1][1] - + m_Data[2][0] * inMatrix.m_Data[1][2] + m_Data[3][0] * inMatrix.m_Data[1][3]; - theMult[1][1] = m_Data[0][1] * inMatrix.m_Data[1][0] + m_Data[1][1] * inMatrix.m_Data[1][1] - + m_Data[2][1] * inMatrix.m_Data[1][2] + m_Data[3][1] * inMatrix.m_Data[1][3]; - theMult[1][2] = m_Data[0][2] * inMatrix.m_Data[1][0] + m_Data[1][2] * inMatrix.m_Data[1][1] - + m_Data[2][2] * inMatrix.m_Data[1][2] + m_Data[3][2] * inMatrix.m_Data[1][3]; - theMult[1][3] = m_Data[0][3] * inMatrix.m_Data[1][0] + m_Data[1][3] * inMatrix.m_Data[1][1] - + m_Data[2][3] * inMatrix.m_Data[1][2] + m_Data[3][3] * inMatrix.m_Data[1][3]; - theMult[2][0] = m_Data[0][0] * inMatrix.m_Data[2][0] + m_Data[1][0] * inMatrix.m_Data[2][1] - + m_Data[2][0] * inMatrix.m_Data[2][2] + m_Data[3][0] * inMatrix.m_Data[2][3]; - theMult[2][1] = m_Data[0][1] * inMatrix.m_Data[2][0] + m_Data[1][1] * inMatrix.m_Data[2][1] - + m_Data[2][1] * inMatrix.m_Data[2][2] + m_Data[3][1] * inMatrix.m_Data[2][3]; - theMult[2][2] = m_Data[0][2] * inMatrix.m_Data[2][0] + m_Data[1][2] * inMatrix.m_Data[2][1] - + m_Data[2][2] * inMatrix.m_Data[2][2] + m_Data[3][2] * inMatrix.m_Data[2][3]; - theMult[2][3] = m_Data[0][3] * inMatrix.m_Data[2][0] + m_Data[1][3] * inMatrix.m_Data[2][1] - + m_Data[2][3] * inMatrix.m_Data[2][2] + m_Data[3][3] * inMatrix.m_Data[2][3]; - - theMult[3][0] = m_Data[0][0] * inMatrix.m_Data[3][0] + m_Data[1][0] * inMatrix.m_Data[3][1] - + m_Data[2][0] * inMatrix.m_Data[3][2] + m_Data[3][0] * inMatrix.m_Data[3][3]; - theMult[3][1] = m_Data[0][1] * inMatrix.m_Data[3][0] + m_Data[1][1] * inMatrix.m_Data[3][1] - + m_Data[2][1] * inMatrix.m_Data[3][2] + m_Data[3][1] * inMatrix.m_Data[3][3]; - theMult[3][2] = m_Data[0][2] * inMatrix.m_Data[3][0] + m_Data[1][2] * inMatrix.m_Data[3][1] - + m_Data[2][2] * inMatrix.m_Data[3][2] + m_Data[3][2] * inMatrix.m_Data[3][3]; - theMult[3][3] = m_Data[0][3] * inMatrix.m_Data[3][0] + m_Data[1][3] * inMatrix.m_Data[3][1] - + m_Data[2][3] * inMatrix.m_Data[3][2] + m_Data[3][3] * inMatrix.m_Data[3][3]; - - return Set(theMult); -} - -//============================================================================== -/** - * Toggle between left-hand and right-hand coordinate system - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::FlipCoordinateSystem() -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - // rotation conversion - m_Data[0][2] *= -1; - m_Data[1][2] *= -1; - m_Data[2][0] *= -1; - m_Data[2][1] *= -1; - - // translation conversion - m_Data[3][2] *= -1; - - return *this; -} - -//============================================================================== -/** - * Rotate this matrix to align with the rotation of the specified matrix. - * - * @param inMatrix the maxtrix we are cloning. - * @param inMirrorFlag flag indicating that we should flip the z and face the opposite - *direction. - * @return This matrix after the rotation. - */ -RuntimeMatrix &RuntimeMatrix::CloneRotation(const RuntimeMatrix &inMatrix, BOOL inMirrorFlag /*= false*/) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - // Create the axes - RuntimeVector3 theZ(inMatrix.Get(2, 0), inMatrix.Get(2, 1), inMatrix.Get(2, 2)); - if (inMirrorFlag) - theZ *= -1; - RuntimeVector3 theY(inMatrix.Get(1, 0), inMatrix.Get(1, 1), inMatrix.Get(1, 2)); - RuntimeVector3 theX(theY); - theX.CrossProduct(theZ); - - // Normalize - theX.Normalize(); - theY.Normalize(); - theZ.Normalize(); - - // Copy it into the matrix - m_Data[0][0] = theX.m_X; - m_Data[0][1] = theX.m_Y; - m_Data[0][2] = theX.m_Z; - - m_Data[1][0] = theY.m_X; - m_Data[1][1] = theY.m_Y; - m_Data[1][2] = theY.m_Z; - - m_Data[2][0] = theZ.m_X; - m_Data[2][1] = theZ.m_Y; - m_Data[2][2] = theZ.m_Z; - - return *this; -} - -//============================================================================== -/** - * Compute the square distance between the position vectors of two transforms. - * @param inMatrix the other transform, signifying a global object position for example - * @return the square of the "distance" between the two transforms - */ -FLOAT RuntimeMatrix::SquareDistance(const RuntimeMatrix &inMatrix) const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theResult = 0; - FLOAT theFactor; - - theFactor = m_Data[3][0] - inMatrix.m_Data[3][0]; - theFactor *= theFactor; - theResult += theFactor; - - theFactor = m_Data[3][1] - inMatrix.m_Data[3][1]; - theFactor *= theFactor; - theResult += theFactor; - - theFactor = m_Data[3][2] - inMatrix.m_Data[3][2]; - theFactor *= theFactor; - theResult += theFactor; - - return theResult; -} - -//============================================================================== -/** - * Simple assignment operator. - * @param inMatrix new matrix being assigned - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::operator=(const RuntimeMatrix &inMatrix) -{ - Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Compares this matrix's elements with another matrix's and returns true - * if the matrices are equivalent. - * @param inMatrix the matrix we are comparing against - * @return true if all elements are within EPSILON of each other. - */ -BOOL RuntimeMatrix::operator==(const RuntimeMatrix &inMatrix) const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - for (INT32 iRow = 0; iRow < 4; ++iRow) { - for (INT32 iCol = 0; iCol < 4; ++iCol) { - if (::fabs(m_Data[iRow][iCol] - inMatrix.m_Data[iRow][iCol]) > RUNTIME_EPSILON) - return false; - } - } - return true; -} - -//============================================================================== -/** - * Compares this matrix's elements with another matrix's and returns true - * if the matrices are not equivalent. - * @param inMatrix the matrix we are comparing against - * @return true if one or more elements are more than EPSILON from each other - */ -BOOL RuntimeMatrix::operator!=(const RuntimeMatrix &inMatrix) const -{ - // Reuse same code path.. - return !(*this == inMatrix); -} - -//============================================================================== -/** - * Standardized conversion to string. - * @param outString string becoming a representation for the matrix - */ -// void CMatrix::ToString( AK_STRING& outString ) const -//{ -// INT8 theBuffer[ 256 ]; -// -// Q3DStudio_sprintf -// ( -// theBuffer, 255, -// "%.2f %.2f %.2f %.2f " -// "%.2f %.2f %.2f %.2f " -// "%.2f %.2f %.2f %.2f " -// "%.2f %.2f %.2f %.2f", -// -// m_Data.m[ 0 ][ 0 ], -// m_Data.m[ 0 ][ 1 ], -// m_Data.m[ 0 ][ 2 ], -// m_Data.m[ 0 ][ 3 ], -// -// m_Data.m[ 1 ][ 0 ], -// m_Data.m[ 1 ][ 1 ], -// m_Data.m[ 1 ][ 2 ], -// m_Data.m[ 1 ][ 3 ], -// -// m_Data.m[ 2 ][ 0 ], -// m_Data.m[ 2 ][ 1 ], -// m_Data.m[ 2 ][ 2 ], -// m_Data.m[ 2 ][ 3 ], -// -// m_Data.m[ 3 ][ 0 ], -// m_Data.m[ 3 ][ 1 ], -// m_Data.m[ 3 ][ 2 ], -// m_Data.m[ 3 ][ 3 ] -// ); -// -// outString = theBuffer; -//} -// -////============================================================================== -///** -// * Standardized conversion from string. -// * @param inString string being a representation for the matrix -// */ -// void CMatrix::FromString( const AK_STRING& inString ) -//{ -// std::sscanf -// ( -// inString.c_str( ), -// -// "%f %f %f %f " -// "%f %f %f %f " -// "%f %f %f %f " -// "%f %f %f %f", -// -// &m_Data.m[ 0 ][ 0 ], -// &m_Data.m[ 0 ][ 1 ], -// &m_Data.m[ 0 ][ 2 ], -// &m_Data.m[ 0 ][ 3 ], -// -// &m_Data.m[ 1 ][ 0 ], -// &m_Data.m[ 1 ][ 1 ], -// &m_Data.m[ 1 ][ 2 ], -// &m_Data.m[ 1 ][ 3 ], -// -// &m_Data.m[ 2 ][ 0 ], -// &m_Data.m[ 2 ][ 1 ], -// &m_Data.m[ 2 ][ 2 ], -// &m_Data.m[ 2 ][ 3 ], -// -// &m_Data.m[ 3 ][ 0 ], -// &m_Data.m[ 3 ][ 1 ], -// &m_Data.m[ 3 ][ 2 ], -// &m_Data.m[ 3 ][ 3 ] -// ); -//} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemory.cpp b/src/Runtime/Source/System/Source/Qt3DSMemory.cpp deleted file mode 100644 index 17fa5c86..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemory.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemory.h" - -//============================================================================== -// OS level memory routines -//============================================================================== -Q3DStudio::CMemory::TMalloc Q3DStudio::CMemory::s_Malloc = NULL; -Q3DStudio::CMemory::TRealloc Q3DStudio::CMemory::s_Realloc = NULL; -Q3DStudio::CMemory::TFree Q3DStudio::CMemory::s_Free = NULL; - -//============================================================================== -/** - * Overrides basic memory allocation/deallocation routines - * @param inMalloc memory allocation routine - * @param inFree memory deallocation routine - * @param inRealloc memory reallocation routine - */ -void Q3DStudio::CMemory::SetMemoryFunctions(const TMalloc inMalloc, const TFree inFree, - const TRealloc inRealloc) -{ - s_Malloc = inMalloc; - s_Realloc = inRealloc; - s_Free = inFree; -} - -static Q3DStudio::CMemoryManager *s_globalManager = nullptr; -static Q3DStudio::CMemoryHeap *s_globalHeap = nullptr; - -//============================================================================== -/** - * Boot up the pooled memory manager and return it. - * @note The manager has to be initialized before use: - * GetMemoryManager( ).Initialize( "GlobalManager", g_ChunkSize, g_ChunkCount ); - * @return Q3DStudio::CMemoryManager reference to the global object - */ -Q3DStudio::CMemoryManager &GetMemoryManager() -{ - if (!s_globalManager) - s_globalManager = new Q3DStudio::CMemoryManager; - return *s_globalManager; -} - -//============================================================================== -/** - * Return a reference to the global heap object. - * @return Q3DStudio::CMemoryHeap reference to the global object - */ -Q3DStudio::CMemoryHeap &GetMemoryHeap() -{ - if (!s_globalHeap) - s_globalHeap = new Q3DStudio::CMemoryHeap; - return *s_globalHeap; -} - -//============================================================================== -// Q3DStudio_new operator prototypes (5 args) -//============================================================================== -void *operator new(size_t inReportedSize, size_t inOfficialSize, const char *inType, - const char *inFile, int inLine) -{ - Q3DStudio_UNREFERENCED_PARAMETER(inReportedSize); - Q3DStudio_ASSERT(inReportedSize == inOfficialSize); - - return Q3DStudio_HANDLER_NEW.Allocate(static_cast(inOfficialSize), - inType, inFile, inLine); -} - -//============================================================================== -/** - * Override 'operator delete' in order to track memory usage. - * - * So what's the use of the overloaded delete with special arguments? There is - * actually one case in which it will be called--when an exception is thrown - * during object construction. As you might recall, there is a contract implicit - * in the language that if an exception happens during the construction of an object, - * the memory for this object will be automatically deallocated. It so happens - * that during object's construction the compiler is still aware of which version - * of operator new was called to allocate memory. It is therefore able to generate - * a call to the corresponding version of delete, in case an exception is thrown. - * After the successful completion of construction, this information is no longer - * available and the compiler has no means to guess which version of global delete - * is appropriate for a given object. - */ -void operator delete(void *inReportedAddress, size_t inOfficialSize, const char *, const char *, - int) -{ - Q3DStudio_HANDLER_NEW.Free(inReportedAddress, - static_cast(inOfficialSize)); -} - -//============================================================================== -// Q3DStudio_virtual_new operators (4 args) -//============================================================================== -void *operator new(size_t inReportedSize, const char *inType, const char *inFile, int inLine) -{ - return Q3DStudio::CMemoryFilter::Allocate(static_cast(inReportedSize), inType, - inFile, inLine, false); -} - -void operator delete(void *inReportedAddress, const char *, const char *, int) -{ - Q3DStudio::CMemoryFilter::Free(inReportedAddress); -} diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryFilter.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryFilter.cpp deleted file mode 100644 index f6d6591c..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryFilter.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryFilter.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Allocate a chunk of memory and add a header to track it. - * @param inSize size of requested memory block, in bytes - * @param inType allocation description - * @param inFile file name - * @param inFunction method name - * @param inLine line number - * @param inClear true to clear allocated memory to zero - * @return void* a pointer to a memory block large enough to hold inSize bytes - */ -void *CMemoryFilter::Allocate(const INT32 inSize, const CHAR *inType, const CHAR *inFile, - const INT32 inLine, const BOOL inClear) -{ - const INT32 theTotalSize = inSize + Q3DStudio_MEMORY_ALIGNMENT; - - INT32 *theMemory = reinterpret_cast( - Q3DStudio_HANDLER_FILTER.Allocate(theTotalSize, inType, inFile, inLine)); - - theMemory[0] = FILTER_DOGTAG; - theMemory[1] = theTotalSize; - - if (inClear) - Q3DStudio_memset(reinterpret_cast(theMemory) + Q3DStudio_MEMORY_ALIGNMENT, 0, - inSize); - - return reinterpret_cast(theMemory) + Q3DStudio_MEMORY_ALIGNMENT; -} - -//============================================================================== -/** - * Free a block of memory that was allocated and tagged here. - * @param inPointer pointer given in a previous filter allocation - */ -void CMemoryFilter::Free(void *inPointer) -{ - if (!inPointer) - return; - - INT32 *theMemory = - reinterpret_cast(reinterpret_cast(inPointer) - Q3DStudio_MEMORY_ALIGNMENT); - - // Sanity check: Did we allocate this memory in the first place? - // If this throws we may be calling Q3DStudio_virtual_delete on memory that was getten from - // Q3DStudio_new - Q3DStudio_ASSERT(FILTER_DOGTAG == theMemory[0]); - Q3DStudio_HANDLER_FILTER.Free(theMemory, theMemory[1]); -} - -//============================================================================== -/** - * Re-allocate an existing chunk of memory and track it. - * @param inPointer pointer given in a previous allocation - * @param inNewSize size of requested memory block, in bytes - * @param inNewType new allocation description - * @param inFile file name - * @param inFunction method name - * @param inLine line number - * @return void* a pointer to a memory block large enough to hold inSize bytes - */ -void *CMemoryFilter::Reallocate(void *inPointer, const INT32 inNewSize, const CHAR *inNewType, - const CHAR *inFile, const INT32 inLine) -{ - INT32 *theNewMemory = NULL; - const INT32 theTotalSize = inNewSize + Q3DStudio_MEMORY_ALIGNMENT; - - // Dogtag is not valid if the old pointer is NULL - if (inPointer) { - INT32 *theOldMemory = reinterpret_cast(reinterpret_cast(inPointer) - - Q3DStudio_MEMORY_ALIGNMENT); - Q3DStudio_ASSERT(FILTER_DOGTAG == theOldMemory[0]); - theNewMemory = reinterpret_cast(Q3DStudio_HANDLER_FILTER.Reallocate( - theOldMemory, theOldMemory[1], theTotalSize, inNewType, inFile, inLine)); - } else { - theNewMemory = reinterpret_cast( - Q3DStudio_HANDLER_FILTER.Reallocate(NULL, 0, theTotalSize, inNewType, inFile, inLine)); - } - - theNewMemory[0] = FILTER_DOGTAG; - theNewMemory[1] = theTotalSize; - return reinterpret_cast(theNewMemory) + Q3DStudio_MEMORY_ALIGNMENT; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryHeap.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryHeap.cpp deleted file mode 100644 index 4ab36178..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryHeap.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemory.h" -#include "Qt3DSMemoryHeap.h" -#include "Qt3DSMemoryStatistics.h" -#include "Qt3DSIStream.h" -#include "foundation/Qt3DSLogging.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Static Initialzation -//============================================================================== -CMemoryProbe CMemoryHeap::s_Probe; - -#if Q3DStudio_MEMORY_HEAPTRACKING -CMemoryHeap::TMemoryReport CMemoryHeap::s_MemoryReport; -#endif // Q3DStudio_MEMORY_HEAPTRACKING - -//============================================================================== -/** - * Allocate a chunk of memory and potentially track it. - * @param inSize size of requested memory block, in bytes - * @param inDescription allocation description such as class name or pool name - * @param inFile file name - * @param inFunction method name - * @param inLine line number - * @return void* a pointer to a memory block large enough to hold inSize bytes - */ -void *CMemoryHeap::Allocate(const INT32 inSize, const CHAR *inDescription, const CHAR *inFile, - const INT32 inLine) -{ - // Always track stats and trigger snapshot if this is a new record - s_Probe.Allocate(inSize); - - // Check if we are exceeding the max memory limit - if (Q3DStudio_MEMORY_LIMIT > 0 - && s_Probe.GetBytes(Q3DStudio::MEMSCOPE_GLOBAL, Q3DStudio::MEMVALUE_CURRENT) - > Q3DStudio_MEMORY_LIMIT) { - qCCritical (qt3ds::OUT_OF_MEMORY) - << "Q3DStudio_MEMORY_UNIT exceeded " << Q3DStudio_MEMORY_LIMIT; - Q3DStudio_ASSERT(false); - } - -#if Q3DStudio_MEMORY_HEAPTRACKING - void *theAllocatedPtr = CMemory::Malloc()(static_cast(inSize)); - if (s_MemoryReport.GetCount() < s_MemoryReport.GetCapacity()) { - SReportEntry theEntry = { theAllocatedPtr, inSize, inDescription, inFile, inLine }; - s_MemoryReport.Push(theEntry); - } else { - static BOOL s_FullWarning = false; - if (!s_FullWarning) { - qCWarning (qt3ds::TRACE_INFO) << "HeapTracker full. " - << "Please increase Q3DStudio_MEMORY_HEAPTRACKINGSIZE(" - << Q3DStudio_MEMORY_HEAPTRACKINGSIZE << ") " - << "to track all allocation and tune your pools to avoid " - << "hitting the heap."; - s_FullWarning = true; - } - } - return theAllocatedPtr; -#else - Q3DStudio_UNREFERENCED_PARAMETER(inLine); - Q3DStudio_UNREFERENCED_PARAMETER(inFile); - Q3DStudio_UNREFERENCED_PARAMETER(inDescription); - - return CMemory::Malloc()(static_cast(inSize)); -#endif // Q3DStudio_MEMORY_HEAPTRACKING -} - -//============================================================================== -/** - * Free a block of memory allocated using CMemoryHeap::Allocate - * @param inPointer pointer given in a previous allocation - * @param inSize size of given memory block, in bytes - */ -void CMemoryHeap::Free(void *inPointer, INT32 inSize) -{ - // No-Op on NULL - if (!inPointer) - return; - -#if Q3DStudio_MEMORY_HEAPTRACKING - RemoveReport(inPointer); -#endif // Q3DStudio_MEMORY_HEAPTRACKING - - s_Probe.Free(inSize); - return CMemory::Free()(inPointer); -} - -//============================================================================== -/** - * Re-allocate an existing chunk of memory and potentially track it. - * @param inPointer pointer given in a previous allocation - * @param inOldSize size of current memory block, in bytes - * @param inNewSize size of requested memory block, in bytes - * @param inNewDescription allocation description such as class name or pool name - * @param inFile file name - * @param inFunction method name - * @param inLine line number - * @return void* a pointer to a memory block large enough to hold inSize bytes - */ -void *CMemoryHeap::Reallocate(void *inPointer, const INT32 inOldSize, const INT32 inNewSize, - const CHAR *inNewDescription, const CHAR *inFile, const INT32 inLine) -{ - // Make sure this isn't a new malloc - if (!inPointer) - return Allocate(inNewSize, inNewDescription, inFile, inLine); - - // Always track stats and record new high if it's a record - s_Probe.Allocate(inNewSize); - s_Probe.Free(inOldSize); - - // Check if we are exceeding the max memory limit - Q3DStudio_ASSERT(Q3DStudio_MEMORY_LIMIT == 0 - ? true - : s_Probe.GetBytes(Q3DStudio::MEMSCOPE_GLOBAL, Q3DStudio::MEMVALUE_CURRENT) - < Q3DStudio_MEMORY_LIMIT); - -#if Q3DStudio_MEMORY_HEAPTRACKING - RemoveReport(inPointer); - - void *theReallocatedPtr = CMemory::Realloc()(inPointer, static_cast(inNewSize)); - - SReportEntry theEntry = { theReallocatedPtr, inNewSize, inNewDescription, inFile, inLine }; - s_MemoryReport.Push(theEntry); - - return theReallocatedPtr; -#else - return CMemory::Realloc()(inPointer, static_cast(inNewSize)); -#endif // Q3DStudio_MEMORY_HEAPTRACKING -} - -//============================================================================== -/** - * Retrieves memory info about a particular allocation - * @param inPointer allocated memory - * @return SMemoryHeapReportEntry* memory report - */ -CMemoryHeap::SReportEntry *CMemoryHeap::FindReport(void *inPointer) -{ - Q3DStudio_UNREFERENCED_PARAMETER(inPointer); - -#if Q3DStudio_MEMORY_HEAPTRACKING - INT32 theEnd = s_MemoryReport.GetCount(); - for (INT32 theIndex = 0; theIndex < theEnd; ++theIndex) - if (s_MemoryReport[theIndex].m_AllocatedPointer == inPointer) - return &s_MemoryReport[theIndex]; - - Q3DStudio_ASSERT(false); -#endif // Q3DStudio_MEMORY_HEAPTRACKING - - return NULL; -} - -//============================================================================== -/** - * Removes memory info due to a deallocation. - * @param inPointer allocated memory - */ -void CMemoryHeap::RemoveReport(void *inPointer) -{ - Q3DStudio_UNREFERENCED_PARAMETER(inPointer); - -#if Q3DStudio_MEMORY_HEAPTRACKING - INT32 theEnd = s_MemoryReport.GetCount(); - for (INT32 theIndex = 0; theIndex < theEnd; ++theIndex) { - if (s_MemoryReport[theIndex].m_AllocatedPointer == inPointer) { - s_MemoryReport.Remove(theIndex); - return; - } - } -#endif // Q3DStudio_MEMORY_HEAPTRACKING -} - -//============================================================================== -/** - * The memory probe records basic heap activity - * @return reference to probe - */ -CMemoryProbe &CMemoryHeap::GetProbe() -{ - return s_Probe; -} - -//============================================================================== -/** - * The report records all heap activity - * @return pointer to report if tracking is on, or NULL - */ -CMemoryHeap::TMemoryReport *CMemoryHeap::GetReport() -{ -#if Q3DStudio_MEMORY_HEAPTRACKING - return &s_MemoryReport; -#else - return NULL; -#endif // Q3DStudio_MEMORY_HEAPTRACKING -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryManager.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryManager.cpp deleted file mode 100644 index a1ace59e..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryManager.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemory.h" -#include "Qt3DSMemoryManager.h" -#include "Qt3DSMemoryHeap.h" -#include "Qt3DSMemoryProbe.h" -#include "Qt3DSMemoryTracker.h" -#include "Qt3DSMemoryStatistics.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Create a new empty memory pool manager. - * - * The manager must be initialized before use or it will forward all requests - * to the heap. - */ -CMemoryManager::CMemoryManager() -{ - // Set default allocations functions if they are not already set - if (NULL == CMemory::Malloc()) - CMemory::SetMemoryFunctions(&malloc, &free, &realloc); - - CMemoryStatistics::AddManager(this); - -#if Q3DStudio_MEMORY_POOLTRACKING - Q3DStudio_memset(m_Histogram, 0, sizeof(m_Histogram)); - CMemoryStatistics::Overhead() += sizeof(m_Histogram); -#endif // Q3DStudio_MEMORY_POOLTRACKING -} - -//============================================================================== -/** - * Create a new initialized memory pool manager. - * - * @param inName short description of manager used in tracker - * @param inChunkSize array of values describing the chunk size of each pool - * @param inChunkCount array of values describing the number of chunks in each pool - */ -CMemoryManager::CMemoryManager(const CHAR *inName, - const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], - const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]) -{ - // Set default allocations functions if they are not already set - if (NULL == CMemory::Malloc()) - CMemory::SetMemoryFunctions(&malloc, &free, &realloc); - - CMemoryStatistics::AddManager(this); - Initialize(inName, inChunkSize, inChunkCount); - -#if Q3DStudio_MEMORY_POOLTRACKING - Q3DStudio_memset(m_Histogram, 0, sizeof(m_Histogram)); - CMemoryStatistics::Overhead() -= sizeof(m_Histogram); -#endif // Q3DStudio_MEMORY_POOLTRACKING -} - -//============================================================================== -/** - * Release the memory manager and all owned pools. - * - * Nobody better point to memory in these pool because the it will be - * invalid after this. - */ -CMemoryManager::~CMemoryManager() -{ - CMemoryStatistics::RemoveManager(this); - Release(); -} - -//============================================================================== -/** - * Configure the pool manager into separate pools of different chunk sizes. - * - * The chunk size array has to be increasing values such as: - * inChunkSize = { 8, 16, 32, 64, 96, 128, 256, 512, 1024 } - * but count doesn't: - * inChunkCount = { 500, 200, 1000, 200, 200, 100, 250, 50, 20 } - * - * The global memory manager settings are initialized in AKMemory.h - * - * @param inName short description of manager used in tracker - * @param inChunkSize array of Q3DStudio_MEMORY_POOLCOUNT values describing the chunk size - *of each pool - * @param inChunkCount array of Q3DStudio_MEMORY_POOLCOUNT values describing the number of - *chunks in each pool - */ -void CMemoryManager::Initialize(const CHAR *inName, - const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], - const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]) -{ - // Don't initialize more than once - Q3DStudio_ASSERT(m_Pool[0].GetChunkCount() == 0); - Q3DStudio_sprintf(m_Name, sizeof(m_Name), "%s", inName); - - for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) { - // Make sure pool are aligned to Q3DStudio_MEMORY_ALIGNMENT or smaller than - // Q3DStudio_MEMORY_ALIGNMENT - Q3DStudio_ASSERT(inChunkSize[thePoolIndex] < Q3DStudio_MEMORY_ALIGNMENT - || (inChunkSize[thePoolIndex] % Q3DStudio_MEMORY_ALIGNMENT) == 0); - m_Pool[thePoolIndex].Initialize(inName, inChunkSize[thePoolIndex], - inChunkCount[thePoolIndex]); - } -} - -//============================================================================== -/** - * Release all the memory allocated in Initialize - essentially "uninitialize". - */ -void CMemoryManager::Release() -{ - for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) - m_Pool[thePoolIndex].Release(); -} - -//============================================================================== -// ALLOCATION AND DEALLOCATION -//============================================================================== - -//============================================================================== -/** - * Fetch a new chunk of memory from the smallest pool possible - * @param inSize size of requested memory block, in bytes - * @param inType allocation description such as class name or pool name - * @param inFile file name - * @param inFunction method name - * @param inLine line number - * @return void* a pointer to a memory block large enough to hold inSize bytes - */ -void *CMemoryManager::Allocate(INT32 inSize, const CHAR *inType, const CHAR *inFile, - const INT32 inLine) -{ - Q3DStudio_ASSERT(inSize >= 0); - -#if Q3DStudio_MEMORY_POOLTRACKING - m_Histogram[Q3DStudio_min(inSize, 511)].Add(1); -#endif // Q3DStudio_MEMORY_POOLTRACKING - -#if Q3DStudio_MEMORY_LINETRACKING - inSize += sizeof(CMemoryTracker::SMemoryInfo); // make room for SMemoryInfo -#endif // Q3DStudio_MEMORY_LINETRACKING - - // Find the smallest pool that fits - void *thePointer = NULL; - INT32 thePoolIndex = 0; - while (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) { - // Does this pool fit? - if (inSize <= m_Pool[thePoolIndex].GetChunkSize()) { - thePointer = m_Pool[thePoolIndex].Allocate(); - break; - } - ++thePoolIndex; - } - - // // Record the amount of wasted bytes in this chunk - if (thePointer) { - // Basic tracking - m_ManagerData.m_Aligned.Allocate(inSize); -#if Q3DStudio_MEMORY_POOLTRACKING - m_PoolData[thePoolIndex].m_Aligned.Allocate(inSize); -#endif // Q3DStudio_MEMORY_POOLTRACKING - } - // If not, we go to the heap for now. - else { - // REFACTOR: Use the next pool size up instead? - thePointer = CMemoryHeap::Allocate(inSize, inType, inFile, inLine); - m_ManagerData.m_Overflow.Allocate(inSize); - -#if Q3DStudio_MEMORY_POOLTRACKING - if (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) - m_PoolData[thePoolIndex].m_Overflow.Allocate( - inSize); // Heap allocation due to full memory pool -#endif // Q3DStudio_MEMORY_POOLTRACKING - } - -#if Q3DStudio_MEMORY_LINETRACKING - CMemoryTracker::SMemoryInfo *theMemoryInfo = - reinterpret_cast(thePointer); - - theMemoryInfo->m_DogTag = CMemoryTracker::TRACKER_DOGTAG; - theMemoryInfo->m_Line = static_cast(inLine); - theMemoryInfo->m_Size = static_cast(inSize - sizeof(CMemoryTracker::SMemoryInfo)); - theMemoryInfo->m_File = inFile; - theMemoryInfo->m_Type = inType; - - m_LineTracker.Remember(theMemoryInfo); - thePointer = reinterpret_cast(thePointer) + 1; -#endif // Q3DStudio_MEMORY_LINETRACKING - - return thePointer; -} - -//============================================================================== -/** - * Release a chunk of memory. - * @param inPointer pointer to memory to be reused - * @param inSize size of the memory we are releasing, in bytes - */ -void CMemoryManager::Free(void *inPointer, INT32 inSize) -{ - if (!inPointer) - return; - - Q3DStudio_ASSERT(inSize >= 0); - -#if Q3DStudio_MEMORY_POOLTRACKING - m_Histogram[Q3DStudio_min(inSize, 511)].Delete(1); -#endif // Q3DStudio_MEMORY_POOLTRACKING - -#if Q3DStudio_MEMORY_LINETRACKING - inPointer = reinterpret_cast(inPointer) - 1; - m_LineTracker.Forget(reinterpret_cast(inPointer)); - inSize += sizeof(CMemoryTracker::SMemoryInfo); -#endif // Q3DStudio_MEMORY_LINETRACKING - - // Did we get a valid pool? - INT32 thePoolIndex = FetchPoolIndex(inPointer); - if (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) { - m_Pool[thePoolIndex].Free(inPointer); - m_ManagerData.m_Aligned.Free(inSize); -#if Q3DStudio_MEMORY_POOLTRACKING - m_PoolData[thePoolIndex].m_Aligned.Free(inSize); -#endif // Q3DStudio_MEMORY_POOLTRACKING - } else { - CMemoryHeap::Free(inPointer, inSize); - m_ManagerData.m_Overflow.Free(inSize); - -#if Q3DStudio_MEMORY_POOLTRACKING - if (inSize <= m_Pool[Q3DStudio_MEMORY_POOLCOUNT - 1].GetChunkSize()) - for (thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) - if (inSize <= m_Pool[thePoolIndex].GetChunkSize()) { - m_PoolData[thePoolIndex].m_Overflow.Free(inSize); - // This is driving me crazy -CN. - // Q3DStudio_ASSERT( m_PoolData[thePoolIndex].m_Overflow.GetCalls( - // MEMSCOPE_GLOBAL, MEMVALUE_CURRENT ) >= 0 ); - break; - } -#endif // Q3DStudio_MEMORY_POOLTRACKING - } -} - -//============================================================================== -/** - * Grow the existing memory allocated - * - * @param inOldPointer pointer given in a previous allocation - * @param inOldSize size of current memory block, in bytes - * @param inNewSize size of requested memory block, in bytes - * @param inNewType allocation description such as class name or pool name - * @param inFile file name - * @param inFunction method name - * @param inLine line number - * @return void* a pointer to a memory block large enough to hold inSize bytes - */ -void *CMemoryManager::Reallocate(void *inOldPointer, const INT32 inOldSize, const INT32 inNewSize, - const CHAR *inNewType, const CHAR *inFile, const INT32 inLine) -{ - Q3DStudio_ASSERT(inOldSize >= 0 && inNewSize >= 0); - - // It's legal to pass NULL as old pointer to realloc - if (!inOldPointer) - return Allocate(inNewSize, inNewType, inFile, inLine); - - if (inNewSize == 0) { - Free(inOldPointer, inOldSize); - return NULL; - } - - // Get a new bigger chunk and transfer old data to it - void *thePointer = Allocate(inNewSize, inNewType, inFile, inLine); - Q3DStudio_memcpy(thePointer, inOldPointer, Q3DStudio_min(inOldSize, inNewSize)); - - // Release old data - Free(inOldPointer, inOldSize); - return thePointer; -} - -//============================================================================== -// IMPLEMENTATION -//============================================================================== - -//============================================================================== -/** - * Find the pool that owns the given pointer. - * @param inPointer pointer to memory to be found - * @return INT32 index of pool or Q3DStudio_MEMORY_POOLCOUNT if the chunk can't be found - */ -INT32 CMemoryManager::FetchPoolIndex(const void *inPointer) -{ - // Find pool that owns the pointer - INT32 thePoolIndex = 0; - while (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) { - if (m_Pool[thePoolIndex].OwnsChunk(inPointer)) - return thePoolIndex; - ++thePoolIndex; - } - - return Q3DStudio_MEMORY_POOLCOUNT; -} - -//============================================================================== -// STATISTICS -//============================================================================== - -//============================================================================== -/** - * Return the text identifier of the manager - * @return the name, max 32 bytes long - */ -const CHAR *CMemoryManager::GetName() -{ - return m_Name; -} - -//============================================================================== -/** - * Reset all probe statistics - */ -void CMemoryManager::Reset() -{ - m_ManagerData.m_Aligned.Reset(); - m_ManagerData.m_Overflow.Reset(); - -#if Q3DStudio_MEMORY_POOLTRACKING - for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) { - m_Pool[thePoolIndex].GetProbe().Reset(); - m_PoolData[thePoolIndex].m_Aligned.Reset(); - m_PoolData[thePoolIndex].m_Overflow.Reset(); - } -#endif // Q3DStudio_MEMORY_POOLTRACKING -} - -//============================================================================== -/** - * Retrieve a particular memory pool - * @param inPoolIndex index of the pool - * @return SPoolData& is a reference to the indicated pool data - */ -CMemoryPool &CMemoryManager::GetPool(const INT32 inPoolIndex) -{ - Q3DStudio_ASSERT(inPoolIndex < Q3DStudio_MEMORY_POOLCOUNT && inPoolIndex >= 0); - return m_Pool[inPoolIndex]; -} - -//============================================================================== -/** - * Retrieve a particular memory pool - * @param inPoolIndex index of the pool - * @return SPoolData& is a reference to the indicated pool data - */ -CMemoryManager::SPoolData *CMemoryManager::GetPoolData(const INT32 inPoolIndex) -{ - Q3DStudio_UNREFERENCED_PARAMETER(inPoolIndex); - Q3DStudio_ASSERT(inPoolIndex < Q3DStudio_MEMORY_POOLCOUNT && inPoolIndex >= 0); - -#if Q3DStudio_MEMORY_POOLTRACKING - return m_PoolData + inPoolIndex; -#else - return NULL; -#endif // Q3DStudio_MEMORY_POOLTRACKING -} - -//============================================================================== -/** - * Retrieve the number of bytes that were allocated on the heap - * @return CMemoryProbe as the heap statistics - */ -CMemoryManager::SPoolData &CMemoryManager::GetManagerData() -{ - return m_ManagerData; -} - -//============================================================================== -/** - * Sum the high level statistics of all the pools. - * @return CMemoryProbe as the statistics, calculated on the spot - */ -CMemoryProbe CMemoryManager::GetProbe() -{ - CMemoryProbe theProbe; -#if Q3DStudio_MEMORY_POOLTRACKING - for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) - theProbe.Combine(m_Pool[thePoolIndex].GetProbe()); -#endif // Q3DStudio_MEMORY_POOLTRACKING - return theProbe; -} - -//============================================================================== -/** - * Fetch the tracker if enabled by setting Q3DStudio_MEMORY_LINETRACKING - * @return CMemoryTracker pointer or NULL - */ -CMemoryTracker *CMemoryManager::GetLineTracker() -{ -#if Q3DStudio_MEMORY_LINETRACKING - return &m_LineTracker; -#else - return NULL; -#endif // Q3DStudio_MEMORY_LINETRACKING -} - -//============================================================================== -/** - * Fetch the histogram if enabled by setting Q3DStudio_MEMORY_HISTOGRAM. - * The histogram counts all requested allocations of the specific size. - * @return UINT16 array of 512 values, or NULL - */ -const CMemoryProbe::SValue *CMemoryManager::GetHistogram() -{ -#if Q3DStudio_MEMORY_POOLTRACKING - return m_Histogram; -#else - return NULL; -#endif // Q3DStudio_MEMORY_POOLTRACKING -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryPool.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryPool.cpp deleted file mode 100644 index 44545d45..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryPool.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryPool.h" -#include "Qt3DSMemoryHeap.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Create a new memory pool. - * - */ -CMemoryPool::CMemoryPool() - : m_ChunkSize(0) - , m_ChunkCount(0) - , m_Ceiling(NULL) - , m_Memory(NULL) - , m_Top(NULL) - , m_Hole(NULL) -{ - m_Description[0] = '\0'; -} - -//============================================================================== -/** - * Release the memory pool. - * - * Nobody better point to this pool because it's illegal after this. - * We could blast the memory in debug mode to trigger bugs early but most - * compilers already do this. - */ -CMemoryPool::~CMemoryPool() -{ - Release(); -} - -//============================================================================== -/** - * Configure the memory pool. - * - * The pool will allocate inChunkSize * inChunkCount bytes of memory from - * the heap using Q3DStudio_new, aligned on 4 byte boundaries. - * - * @param inName short description of pool - used in tracker - * @param inChunkSize size in bytes of each memory block, aka chunk - * @param inChunkCount number of chunks the pool holds - */ -void CMemoryPool::Initialize(const CHAR *inName, const INT32 inChunkSize, const INT32 inChunkCount) -{ - Q3DStudio_ASSERT(!m_Memory); - - // Round up chunk size to the next even pointer size - // It needs to be at least pointer size to store the hole linked list - INT32 theRoundedChunkSize = - static_cast(((inChunkSize + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *)); - - // Create pool description - Q3DStudio_sprintf(m_Description, sizeof(m_Description), "POOL: %s(%dx%d)", inName, - theRoundedChunkSize, inChunkCount); - - // Reserve memory pool - m_ChunkSize = theRoundedChunkSize; - m_ChunkCount = inChunkCount; - m_Memory = reinterpret_cast( - Q3DStudio_heap_allocate(m_ChunkSize * m_ChunkCount, m_Description)); - m_Top = m_Memory; - m_Ceiling = m_Memory + m_ChunkSize * m_ChunkCount; -} - -//============================================================================== -/** - * Release all the memory allocated in Initialize - essentially "uninitialize". - */ -void CMemoryPool::Release() -{ - Q3DStudio_heap_free(m_Memory, m_ChunkSize * m_ChunkCount); - - m_ChunkSize = 0, m_ChunkCount = 0; - m_Ceiling = NULL; - m_Memory = NULL; - m_Top = NULL; - m_Hole = NULL; -} - -//============================================================================== -// ALLOCATION AND DEALLOCATION -//============================================================================== - -//============================================================================== -/** - * Fetch a new chunk of memory. - * - * If there is a pool hole we use that, otherwise feed of the head. - * Every alloction is tracked in m_Statistics. - * @return a pointer to inChunkSize bytes of usable memory - */ -void *CMemoryPool::Allocate() -{ - if (m_Hole) - return PopHole(); - else - return UseTop(); -} - -//============================================================================== -/** - * Release a chunk of memory and track changes in statistics - * @param inChunk a pointer to memory to be reused - */ -void CMemoryPool::Free(void *inChunk) -{ - Q3DStudio_ASSERT(OwnsChunk(inChunk)); - PushHole(inChunk); -} - -//============================================================================== -/** - * Verify that a pointer is owned by a specific pool - * @param inChunk a pointer to be checked - * @return BOOL true if the chunk is owned by this pool - */ -BOOL CMemoryPool::OwnsChunk(const void *inChunk) const -{ -#ifdef _DEBUG - // Scan all holes to prevent double releasing memory - if (!(inChunk >= m_Ceiling || inChunk < m_Memory)) { - // No freeing anything above the top? - Q3DStudio_ASSERT(inChunk < m_Top); - - // Not freeing any holes? - void *theHoleChunk = m_Hole; - while (theHoleChunk) { - Q3DStudio_ASSERT(inChunk != theHoleChunk); - theHoleChunk = reinterpret_cast(*reinterpret_cast(theHoleChunk)); - } - } -#endif // DEBUG - - return !(inChunk >= m_Ceiling || inChunk < m_Memory); -} - -//============================================================================== -/** - * Quick check to see if there are chunks available - * @return BOOL true if the pool has available chunks - */ -BOOL CMemoryPool::IsFull() const -{ - return m_Hole == NULL && GetFreeTops() == 0; -} - -//============================================================================== -/** - * Get the total number of free chunks in this pool. - * @return INT32 is the nunber of free chunks - */ -INT32 CMemoryPool::GetFreeChunks() const -{ - return GetFreeTops() + GetFreeHoles(); -} - -//============================================================================== -/** - * Get the number of holes in this pool. - * @return INT32 is the nunber of holes - */ -INT32 CMemoryPool::GetFreeHoles() const -{ - INT32 theHoleCounter = 0; - void *theHoleChunk = m_Hole; - - // Walk the hole list until there are no more holes - while (theHoleChunk) { - theHoleChunk = reinterpret_cast(*reinterpret_cast(theHoleChunk)); - ++theHoleCounter; - } - - return theHoleCounter; -} - -//============================================================================== -/** - * Get the number of chunks left at the top. - * @return INT32 is the nunber of continous chunks at the top - */ -INT32 CMemoryPool::GetFreeTops() const -{ - return static_cast((m_Ceiling - m_Top)) / m_ChunkSize; -} - -//============================================================================== -// IMPLEMENTATION -//============================================================================== - -//============================================================================== -/** - * Return a chunch from the top. - * - * The top is only used if no pool holes are available. - * @return a pointer to the chunk at the top - */ -void *CMemoryPool::UseTop() -{ - // Out of memory? - // This is not assert since it may happen during normal runtime. - if (m_Top >= m_Ceiling) - return NULL; - - void *theChunk = m_Top; - m_Top += m_ChunkSize; - -#if Q3DStudio_MEMORY_POOLTRACKING - m_Probe.Allocate(m_ChunkSize); -#endif // Q3DStudio_MEMORY_POOLTRACKING - return theChunk; -} - -//============================================================================== -/** - * Add a new hole to the pool list. - * - * The holes are used in a stack-like fashion so the chunk we push in most - * recently is the first one to be returned next New call. - * The holes are linked by using the first four bytes to point to the next - * chunk. We are hijacking them to create a linked list of free chunks. - * @param inChunk is the just deleted chunk - */ -void CMemoryPool::PushHole(void *inChunk) -{ -#if Q3DStudio_MEMORY_POOLTRACKING - m_Probe.Free(m_ChunkSize); -#endif // Q3DStudio_MEMORY_POOLTRACKING - - // Set the pushed chunk to be the new top hole after we - // link the content of the new chunk to the last top. - *reinterpret_cast(inChunk) = reinterpret_cast(m_Hole); - m_Hole = inChunk; -} - -//============================================================================== -/** - * Get the topmost hole as our chunk. - * - * Return the latest hole and relink the list of holes to the top. - * @return void* is the most recently deleted chunk - */ -void *CMemoryPool::PopHole() -{ - Q3DStudio_ASSERT(m_Hole); - - // Return the old hole as our new chunk after we - // set the hole to the second hole in the list. - void *theChunk = m_Hole; - m_Hole = reinterpret_cast(*reinterpret_cast(m_Hole)); - -#if Q3DStudio_MEMORY_POOLTRACKING - m_Probe.Allocate(m_ChunkSize); -#endif // Q3DStudio_MEMORY_POOLTRACKING - return theChunk; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryProbe.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryProbe.cpp deleted file mode 100644 index 4e977ee1..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryProbe.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryProbe.h" -#include "Qt3DSMemoryStatistics.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - records its size with the statistics class - */ -CMemoryProbe::CMemoryProbe() -{ - CMemoryStatistics::Overhead() += sizeof(CMemoryProbe); -} - -//============================================================================== -/** - * Destructor - */ -CMemoryProbe::~CMemoryProbe() -{ - CMemoryStatistics::Overhead() -= sizeof(CMemoryProbe); -} - -//============================================================================== -/** - * Track the number related to incrementing memory. - * @param inByteAmount amount of bytes being allocated - */ -void CMemoryProbe::Allocate(const INT32 inByteAmount) -{ - if (inByteAmount > 0) { - m_Calls[MEMSCOPE_RESET].Add(1); - m_Bytes[MEMSCOPE_RESET].Add(inByteAmount); - - m_Calls[MEMSCOPE_GLOBAL].Add(1); - m_Bytes[MEMSCOPE_GLOBAL].Add(inByteAmount); - } -} - -//============================================================================== -/** - * Track the number related to incrementing memory. - * @param inByteAmount amount of bytes being deallocted - */ -void CMemoryProbe::Free(const INT32 inByteAmount) -{ - Q3DStudio_ASSERT(inByteAmount >= 0); - if (inByteAmount > 0) { - m_Calls[MEMSCOPE_RESET].Delete(1); - m_Bytes[MEMSCOPE_RESET].Delete(inByteAmount); - - m_Calls[MEMSCOPE_GLOBAL].Delete(1); - m_Bytes[MEMSCOPE_GLOBAL].Delete(inByteAmount); - } -} - -//============================================================================== -/** - * Reset all local statistics. Global values are not reset. - */ -void CMemoryProbe::Reset() -{ - m_Calls[MEMSCOPE_RESET].Reset(); - m_Bytes[MEMSCOPE_RESET].Reset(); -} - -//============================================================================== -/** - * Helper method for adding statistics used by manager to add pool usage. - * @param inProbe is the stats being added - */ -void CMemoryProbe::Combine(const CMemoryProbe &inProbe) -{ - m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS] += - inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS]; - m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES] += - inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES]; - m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK] += - inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK]; - m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT] += - inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT]; - - m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS] += - inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS]; - m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES] += - inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES]; - m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK] += - inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK]; - m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT] += - inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT]; - - m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS] += - inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS]; - m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES] += - inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES]; - m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK] += - inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK]; - m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT] += - inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT]; - - m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS] += - inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS]; - m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES] += - inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES]; - m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK] += - inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK]; - m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT] += - inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT]; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryStatistics.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryStatistics.cpp deleted file mode 100644 index 2f5eba0e..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryStatistics.cpp +++ /dev/null @@ -1,647 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSIStream.h" -#include "Qt3DSMemoryStatistics.h" -#include "Qt3DSMemoryTracker.h" -#include "Qt3DSMemoryHeap.h" -#include "foundation/Qt3DSLogging.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Static Fields -//============================================================================== -INT32 CMemoryStatistics::s_Overhead = 0; -CMemoryManager *CMemoryStatistics::s_PoolManagers[MANAGERCOUNT] = { NULL }; - -//============================================================================== -// REGISTRATION -//============================================================================== - -//============================================================================== -/** - * Add the manager from the static list done automatically on manager construction. - * @param inManager the manager we are beginning to track - */ -void CMemoryStatistics::AddManager(CMemoryManager *inManager) -{ - INT32 theIndex = 0; - while (s_PoolManagers[theIndex] && theIndex < MANAGERCOUNT - 1) - ++theIndex; - - if (!s_PoolManagers[theIndex]) { - s_PoolManagers[theIndex] = inManager; - } else { - qCWarning(qt3ds::TRACE_INFO) - << "Could not add memory manager tracker. Limit: " << MANAGERCOUNT; - } -} - -//============================================================================== -/** - * Remove the manager from the static list done automatically on manager deletion. - * @param inManager the manager we are ceasing to track - */ -void CMemoryStatistics::RemoveManager(CMemoryManager *inManager) -{ - INT32 theIndex = 0; - while (inManager != s_PoolManagers[theIndex] && theIndex < MANAGERCOUNT - 1) - ++theIndex; - - if (inManager == s_PoolManagers[theIndex]) - s_PoolManagers[theIndex] = NULL; -} - -//============================================================================== -/** - * Read/write access to the static tracking field that keeps tab on how - * much memory we are spending _tracking_ memory. - * @return reference to the field tracking the overhead in bytes - */ -INT32 &CMemoryStatistics::Overhead() -{ - return s_Overhead; -} - -//============================================================================== -// OPERATION -//============================================================================== - -//============================================================================== -/** - * Reset all memory probes - */ -void CMemoryStatistics::Reset() -{ - qCInfo(qt3ds::TRACE_INFO) << "Resetting Memory Statistics"; - CMemoryHeap::GetProbe().Reset(); - - for (INT32 theIndex = 0; theIndex < MANAGERCOUNT; ++theIndex) - if (s_PoolManagers[theIndex]) - s_PoolManagers[theIndex]->Reset(); -} - -//============================================================================== -// ACCESS -//============================================================================== - -//============================================================================== -/** - * Quick access to memory usage of the first memory manager. - * @param inPeak is true if you want the peak, false if you want the current state - * @return the current explict usage in bytes - */ -INT32 CMemoryStatistics::GetRequestedBytes(BOOL inPeak /*=false*/) -{ - Q3DStudio_ASSERT(s_PoolManagers[0]); - - EMemoryValue theValue = inPeak ? MEMVALUE_PEAK : MEMVALUE_CURRENT; - CMemoryManager::SPoolData &theUsageData = s_PoolManagers[0]->GetManagerData(); - - return theUsageData.m_Aligned.GetBytes(MEMSCOPE_RESET, theValue) - + theUsageData.m_Overflow.GetBytes(MEMSCOPE_RESET, theValue); -} - -//============================================================================== -/** - * Quick access to heap usage. - * @param inPeak is true if you want the peak, false if you want the current state - * @return the current heap usage in bytes - */ -INT32 CMemoryStatistics::GetHeapBytes(BOOL inPeak /*=false*/) -{ - return Q3DStudio::CMemoryHeap::GetProbe().GetBytes(MEMSCOPE_RESET, - inPeak ? MEMVALUE_PEAK : MEMVALUE_CURRENT); -} - -//============================================================================== -/** - * Fill out a SFactSheet with memory statistics. - * @param outFacts is filled out with factoids showing the system state - * @param inPeak is true if you want the peak, false if you want the current state - * @param inGlobal is true if you want values since process start, false since last reset - */ -void CMemoryStatistics::GetFacts(SFactSheet &outFacts, BOOL inPeak /*= true*/, - BOOL inGlobal /*= true*/) -{ - INT32 thePresentationBytes = 0; - Q3DStudio_UNREFERENCED_PARAMETER(thePresentationBytes); - Q3DStudio_memset(&outFacts, 0, sizeof(SFactSheet)); - - // Translate flags to enumerations - EMemoryScope theScope = inGlobal ? MEMSCOPE_GLOBAL : MEMSCOPE_RESET; - EMemoryValue theValue = inPeak ? MEMVALUE_PEAK : MEMVALUE_CURRENT; - - // Capture heap state - outFacts.m_HeapState.m_Bytes = CMemoryHeap::GetProbe().GetBytes(theScope, theValue); - outFacts.m_HeapState.m_Calls = CMemoryHeap::GetProbe().GetCalls(theScope, theValue); - -#if Q3DStudio_MEMORY_POOLTRACKING - INT32 theTotalChunks = 0; - INT32 theTotalBytes = 0; - - // Scan all registered pool managers - Q3DStudio_sprintf(outFacts.m_ManagerState.m_Name, 32, "All Managers"); - for (INT32 theManagerIndex = 0; theManagerIndex < MANAGERCOUNT; ++theManagerIndex) { - CMemoryManager *theManager = s_PoolManagers[theManagerIndex]; - SFactoid &theManagerFact = outFacts.m_Manager[theManagerIndex]; - INT32 theManagerChunks = 0; - INT32 theManagerBytes = 0; - - // Ignore empty managers - if (!theManager) - break; - - // Scan each pool in the manager - Q3DStudio_sprintf(theManagerFact.m_Name, 32, " %s", theManager->GetName()); - for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) { - CMemoryPool &thePool = theManager->GetPool(thePoolIndex); - CMemoryManager::SPoolData *thePoolData = theManager->GetPoolData(thePoolIndex); - Q3DStudio_ASSERT(thePoolData); - - SFactoid &thePoolFact = outFacts.m_Pool[theManagerIndex][thePoolIndex]; - INT32 theUsed = thePool.GetProbe().GetCalls(theScope, theValue); - INT32 theAlign = thePoolData->m_Aligned.GetBytes(theScope, theValue); - - // Ignore empty pools - if (thePool.GetChunkCount() == 0) - break; - - // Extract all the factoids - Q3DStudio_sprintf(thePoolFact.m_Name, 32, " %d: %4db x %4d", thePoolIndex, - thePool.GetChunkSize(), thePool.GetChunkCount()); - thePoolFact.m_Bytes = thePool.GetChunkSize() * thePool.GetChunkCount(); - thePoolFact.m_Calls = thePool.GetProbe().GetCalls(theScope, theValue); - thePoolFact.m_Used = 100 * theUsed / thePool.GetChunkCount(); - - thePoolFact.m_Align = 100; - if (theUsed > 0) - thePoolFact.m_Align = 100 * theAlign / (theUsed * thePool.GetChunkSize()); - thePoolFact.m_Miss = thePoolData->m_Overflow.GetCalls(theScope, theValue); - - thePresentationBytes += theAlign + thePoolData->m_Overflow.GetBytes(theScope, theValue); - - theManagerFact.m_Bytes += thePoolFact.m_Bytes; - theManagerFact.m_Calls += thePoolFact.m_Calls; - theManagerFact.m_Used += theUsed; - theManagerFact.m_Align += theAlign; - theManagerFact.m_Miss += thePoolFact.m_Miss; - - outFacts.m_ManagerState.m_Bytes += thePoolFact.m_Bytes; - outFacts.m_ManagerState.m_Calls += thePoolFact.m_Calls; - outFacts.m_ManagerState.m_Used += theUsed; - outFacts.m_ManagerState.m_Align += theAlign; - outFacts.m_ManagerState.m_Miss += thePoolFact.m_Miss; - - theManagerChunks += thePool.GetChunkCount(); - theManagerBytes += theUsed * thePool.GetChunkSize(); - } - - thePresentationBytes += - theManager->GetManagerData().m_Overflow.GetBytes(theScope, theValue); - - // Both the manager sub-total and grand-total need to track bytes separately - // since the percentages can't just be added or averaged. Those totals - // are instead weighted and this is the tracking math that does it. - theTotalChunks += theManagerChunks; - theTotalBytes += theManagerBytes; - - theManagerFact.m_Used = 0; - if (theManagerChunks > 0) - theManagerFact.m_Used = 100 * theManagerFact.m_Used / theManagerChunks; - - theManagerFact.m_Align = 100; - if (theManagerBytes > 0) - theManagerFact.m_Align = 100 * theManagerFact.m_Align / theManagerBytes; - - CullHistogram(theManager->GetHistogram(), theValue, outFacts.m_Histogram[theManagerIndex]); - } - - // Again this is the grand-total separate percentage computation that has - // to be done in the end when all sums have been added. - outFacts.m_ManagerState.m_Used = 0; - if (theTotalChunks > 0) - outFacts.m_ManagerState.m_Used = 100 * outFacts.m_ManagerState.m_Used / theTotalChunks; - - outFacts.m_ManagerState.m_Align = 100; - if (theTotalBytes > 0) - outFacts.m_ManagerState.m_Align = 100 * outFacts.m_ManagerState.m_Align / theTotalBytes; - -#endif // Q3DStudio_MEMORY_POOLTRACKING - - // return thePresentationBytes; -} - -//============================================================================== -/** - * Find the HISTOGRAMLIMIT highest performers in the histogram. - * @param inHistogram array of CMemoryManager::HISTOGRAMCOUNT values - * each showing the number of allocation of that bytesize - * @param outResults collects the highest points of the histogram - */ -void CMemoryStatistics::CullHistogram(const CMemoryProbe::SValue *inHistogram, - const EMemoryValue inValue, - SHistogramScore outResults[HISTOGRAMCOUNT]) -{ - // Always clear even if there is no data - Q3DStudio_memset(outResults, 0, sizeof(SHistogramScore)); - - // Return quickly when no data - if (!inHistogram) - return; - - // Scan full histogram - INT32 theLowestIndex = 0; - for (UINT16 theSize = 0; theSize < 512; ++theSize) { - // Is this count higher than the lowest recorded count? - if (inHistogram[theSize].m_Value[inValue] > outResults[theLowestIndex].m_Count) { - outResults[theLowestIndex].m_Count = inHistogram[theSize].m_Value[inValue]; - outResults[theLowestIndex].m_Size = theSize; - - // Find new low in high score - theLowestIndex = 0; - for (UINT16 theResult = 1; theResult < HISTOGRAMCOUNT; ++theResult) - if (outResults[theResult].m_Count < outResults[theLowestIndex].m_Count) - theLowestIndex = theResult; - } - } - - // Sort histogram - brute force for now so don't call this all the time - ::qsort(outResults, 10, sizeof(SHistogramScore), CompareHistogram); -} - -//============================================================================== -/** - * Helper comparison function for CullHistogram - */ -int CMemoryStatistics::CompareHistogram(const void *arg1, const void *arg2) -{ - return reinterpret_cast(arg2)->m_Count - - reinterpret_cast(arg1)->m_Count; -} - -//============================================================================== -/** - * Helper comparison function for CMemoryStatistics::HeapReport - */ -int CMemoryStatistics::CompareHeap(const void *inEntry1, const void *inEntry2) -{ - return reinterpret_cast(inEntry1)->m_Size - - reinterpret_cast(inEntry2)->m_Size; -} - -//============================================================================== -// REPORTING -//============================================================================== - -//============================================================================== -/** - * Simple memory usage report covering both bytes allocated and call count. - * @param inStream the stream we are sending the report or NULL to use logger - */ -void CMemoryStatistics::SimpleReport(IStream *inStream /*=NULL*/) -{ - CHAR theReportBuffer[REPORTSIZE]; - CMemoryProbe theProbe; - - // Basic info is always available - Report(inStream, "\n --- RUNTIME SIMPLE MEMORY REPORT ---\n"); - - // Only the first manager is reported for now - Q3DStudio_ASSERT(s_PoolManagers[0]); - theProbe = s_PoolManagers[0]->GetManagerData().m_Aligned; - theProbe.Combine(s_PoolManagers[0]->GetManagerData().m_Overflow); - Report(inStream, "PRESENTATION: Current Peak Alloc Free\n"); - Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), - "Global:%12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT), - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_PEAK) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_PEAK), - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_ADDS) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_ADDS), - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_DELETES) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_DELETES)); - Report(inStream, theReportBuffer); - Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), - "Reset: %12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_CURRENT) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_CURRENT), - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_PEAK) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_PEAK), - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_ADDS) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_ADDS), - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_DELETES) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_DELETES)); - Report(inStream, theReportBuffer); - - // Overflow is memory not serviced by memory pools - removed to make the simple report... - // simpler - /* theProbe = s_PoolManagers[0]->GetManagerData( ).m_Overflow; - Report( inStream, "OVERFLOW:\n" ); - Q3DStudio_sprintf( theReportBuffer, sizeof( theReportBuffer ), - "Global:%12ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)\n", - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT ), - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_PEAK )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_PEAK ), - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_ADDS )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_ADDS ), - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_DELETES )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_DELETES ) ); - Report( inStream, theReportBuffer ); - Q3DStudio_sprintf( theReportBuffer, sizeof( theReportBuffer ), "Reset: - %12ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)\n", - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT ), - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_PEAK )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_PEAK ), - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_ADDS )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_ADDS ), - theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_DELETES )/1024, - theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_DELETES ) ); - Report( inStream, theReportBuffer );*/ - - // All managers share the same heap - theProbe = CMemoryHeap::GetProbe(); - Report(inStream, "HEAP:\n"); - Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), - "Global:%12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT), - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_PEAK) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_PEAK), - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_ADDS) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_ADDS), - theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_DELETES) / 1024, - theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_DELETES)); - Report(inStream, theReportBuffer); - Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), - "Reset: %12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_CURRENT) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_CURRENT), - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_PEAK) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_PEAK), - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_ADDS) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_ADDS), - theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_DELETES) / 1024, - theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_DELETES)); - Report(inStream, theReportBuffer); - - Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), "Tracking overhead: %dk\n", -#if Q3DStudio_MEMORY_HEAPTRACKING - (s_Overhead + sizeof(CMemoryHeap::TMemoryReport)) / 1024); -#else - s_Overhead / 1024); -#endif // Q3DStudio_MEMORY_HEAPTRACKING - - Report(inStream, theReportBuffer); -} - -//============================================================================== -/** - * Output the memory report log. - * - * The is always watched by a CMemoryProbe that records all activity. Most - * individual allocations will not be recorded though since they are handled - * by memory pools. - * - * A probe records three axis of information (value, scope and call/bytes). - * - * # Value (current,peak,add,del) tracks the current value along with its - * peak value, and also separately tracks adds(allocations) and deletes(frees) - * such that current = add - del. - * # Scope (local,global) tracks values since last reset or dawn of heap. - * # Call/Bytes tracks separately bytes and calls so you can distinguish between - * many small allocations and a few large. - * - * @param inStream the stream we are sending the report or NULL to use logger - */ -void CMemoryStatistics::HeapReport(IStream *inStream /*=NULL*/) -{ - Report(inStream, "\n --- RUNTIME HEAP MEMORY REPORT ---\n"); - -#if Q3DStudio_MEMORY_HEAPTRACKING - // Detailed info needs Q3DStudio_MEMORY_HEAPTRACKING defined - INT32 theCount = CMemoryHeap::GetReport()->GetCount(); - ::qsort(&CMemoryHeap::GetReport()[0], static_cast(theCount), - sizeof(CMemoryHeap::SReportEntry), CompareHeap); - - CHAR theReportBuffer[REPORTSIZE]; - for (INT32 theIndex = 0; theIndex < theCount; ++theIndex) { - CMemoryHeap::SReportEntry &theEntry = CMemoryHeap::GetReport()->operator[](theIndex); - Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), - "%3d. %8d bytes - \"%s\" - %s (%d)\n", theIndex, theEntry.m_Size, - theEntry.m_Description, theEntry.m_File, theEntry.m_Line); - Report(inStream, theReportBuffer); - } -#else - Report(inStream, " Unavailable: Q3DStudio_MEMORY_HEAPTRACKING not defined in this build\n"); -#endif -} - -/* Example output of CMemoryStatistics::Report - -=POOL= HEAP CALLS USED ALIGN MISSES ---------------------------------------------------------------- -All Managers 722k 38 72% 19% - - Global 482k - 0: 16b x 1024 16k 2182 3% 13% - 1: 32b x 2048 64k 4123 96% 9% 38 - 2: 48b x 512 24k 212 72% 21% - 3: 64b x 512 32k 454 11% 3% - . - 8: 512b x 128 64k 68 64% 22% -*/ - -//============================================================================== -/** - * Return a text buffer describing the state of the memory system. - */ -void CMemoryStatistics::PoolReport(BOOL inPeak /*= true*/, BOOL inGlobal /*= true*/, - IStream *inStream /*=NULL*/) -{ - CHAR theLine[256] = { 0 }; - SFactSheet theFacts; - - GetFacts(theFacts, inPeak, inGlobal); - - Report(inStream, "\n --- RUNTIME POOL MEMORY REPORT ---\n"); - Q3DStudio_sprintf(theLine, 256, - "Mode: %s %s\nTotal Heap: %7dk(%d)\nPresentation: %7dk\n", - inGlobal ? "GLOBAL" : "RESET", inPeak ? "PEAK" : "CURRENT", - theFacts.m_HeapState.m_Bytes / 1024, theFacts.m_HeapState.m_Calls, - GetRequestedBytes(inPeak) / 1024); - Report(inStream, theLine); - -#if Q3DStudio_MEMORY_POOLTRACKING - Report(inStream, "=POOLS= HEAP HITS USED ALIGN MISS" - "\n"); - Report(inStream, "-----------------------------------------------------------------" - "\n"); - Q3DStudio_sprintf(theLine, 256, "All Managers %7dk %8d %5d%% %5d%% %6d" - "\n\n", - theFacts.m_ManagerState.m_Bytes / 1024, theFacts.m_ManagerState.m_Calls, - theFacts.m_ManagerState.m_Used, theFacts.m_ManagerState.m_Align, - theFacts.m_ManagerState.m_Miss); - Report(inStream, theLine); - - for (INT32 theManagerIndex = 0; theManagerIndex < MANAGERCOUNT; ++theManagerIndex) { - SFactoid &theManagerFact = theFacts.m_Manager[theManagerIndex]; - if (theManagerFact.m_Bytes > 0) { - Q3DStudio_sprintf(theLine, 256, "%-20s %7dk %8d %5d%% %5d%% %6d\n", - theManagerFact.m_Name, theManagerFact.m_Bytes / 1024, - theManagerFact.m_Calls, theManagerFact.m_Used, theManagerFact.m_Align, - theManagerFact.m_Miss); - Report(inStream, theLine); - - for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; - ++thePoolIndex) { - SFactoid &thePoolFact = theFacts.m_Pool[theManagerIndex][thePoolIndex]; - if (theManagerFact.m_Bytes > 0) { - Q3DStudio_sprintf(theLine, 256, "%-20s %7dk %8d %5d%% %5d%% %6d\n", - thePoolFact.m_Name, thePoolFact.m_Bytes / 1024, - thePoolFact.m_Calls, thePoolFact.m_Used, thePoolFact.m_Align, - thePoolFact.m_Miss); - Report(inStream, theLine); - } - } - - // Histogram only valid for Current-Reset - if (inGlobal) { - Report(inStream, " Histogram: Only available in RESET mode\n"); - } else { - Q3DStudio_sprintf( - theLine, 256, - " Histogram: 1:%3db(%3d) 2:%3db(%3d) 3:%3db(%3d) 4:%3db(%3d) 5:%3db(%3d)\n", - theFacts.m_Histogram[theManagerIndex][0].m_Size, - theFacts.m_Histogram[theManagerIndex][0].m_Count, - theFacts.m_Histogram[theManagerIndex][1].m_Size, - theFacts.m_Histogram[theManagerIndex][1].m_Count, - theFacts.m_Histogram[theManagerIndex][2].m_Size, - theFacts.m_Histogram[theManagerIndex][2].m_Count, - theFacts.m_Histogram[theManagerIndex][3].m_Size, - theFacts.m_Histogram[theManagerIndex][3].m_Count, - theFacts.m_Histogram[theManagerIndex][4].m_Size, - theFacts.m_Histogram[theManagerIndex][4].m_Count); - Report(inStream, theLine); - Q3DStudio_sprintf( - theLine, 256, - " 6:%3db(%3d) 7:%3db(%3d) 8:%3db(%3d) 9:%3db(%3d) 10:%3db(%3d)\n", - theFacts.m_Histogram[theManagerIndex][5].m_Size, - theFacts.m_Histogram[theManagerIndex][5].m_Count, - theFacts.m_Histogram[theManagerIndex][6].m_Size, - theFacts.m_Histogram[theManagerIndex][6].m_Count, - theFacts.m_Histogram[theManagerIndex][7].m_Size, - theFacts.m_Histogram[theManagerIndex][7].m_Count, - theFacts.m_Histogram[theManagerIndex][8].m_Size, - theFacts.m_Histogram[theManagerIndex][8].m_Count, - theFacts.m_Histogram[theManagerIndex][9].m_Size, - theFacts.m_Histogram[theManagerIndex][9].m_Count); - Report(inStream, theLine); - } - } - } -#else - Report(inStream, " Unavailable: Q3DStudio_MEMORY_POOLTRACKING not defined in this build\n"); -#endif -} - -//============================================================================== -/** - * Dump the low-level memory list stored in each manager's hash bin. - * - * @note Q3DStudio_MEMORY_LINETRACKING has to be set to 1 in AKMemorySettings.h or - * the compiler for this method to save out any data. - * - * @param inStream the stream we are sending the report or NULL to use logger - */ -void CMemoryStatistics::LineReport(IStream *inStream /*=NULL*/) -{ - Report(inStream, "\n--- RUNTIME LINE MEMORY REPORT ---\n"); -#if Q3DStudio_MEMORY_LINETRACKING - Report(inStream, "ADDR, SIZE, TYPE, LINE, FILE, \n"); - - INT32 theTotalBytes = 0; - for (INT32 theManagerIndex = 0; theManagerIndex < MANAGERCOUNT; ++theManagerIndex) - if (s_PoolManagers[theManagerIndex] && s_PoolManagers[theManagerIndex]->GetLineTracker()) - theTotalBytes += s_PoolManagers[theManagerIndex]->GetLineTracker()->Report(inStream); - - CHAR theTotal[64]; - theTotal[0] = '\0'; - - Q3DStudio_sprintf(theTotal, sizeof(theTotal), "TOTAL: , %8d\n", theTotalBytes); - Report(inStream, theTotal); -#else - Report(inStream, " Unavailable: Q3DStudio_MEMORY_LINETRACKING not defined in this build\n"); -#endif // Q3DStudio_MEMORY_LINETRACKING -} - -//============================================================================== -/** - * Output to log or stream if available. - * @param inMessage string to be reported - * @param inStream stream to be used or output to log if NULL - */ -void CMemoryStatistics::Report(IStream *inStream, const CHAR *inMessage) -{ - if (inStream) - inStream->WriteRaw(inMessage, (INT32)::strlen(inMessage)); - else - qCInfo(qt3ds::TRACE_INFO) << inMessage; -} - -//============================================================================== -/** - * Output full memory report to log or stream if available. - * @param inStream stream to be used or output to log if NULL - */ -void CMemoryStatistics::FullReport(IStream *inStream /*=NULL*/) -{ - SimpleReport(inStream); - HeapReport(inStream); - LineReport(inStream); - PoolReport(false, false, inStream); - PoolReport(true, false, inStream); - PoolReport(false, true, inStream); - PoolReport(true, true, inStream); -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSMemoryTracker.cpp b/src/Runtime/Source/System/Source/Qt3DSMemoryTracker.cpp deleted file mode 100644 index 8aef9519..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSMemoryTracker.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMemoryTracker.h" -#include "foundation/Qt3DSLogging.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Construct and reset the tracker. - */ -CMemoryTracker::CMemoryTracker() - : m_TrackingOverhead(0) -{ - Q3DStudio_memset(&m_TrackingHashBin, 0, sizeof(m_TrackingHashBin)); - CMemoryStatistics::Overhead() += sizeof(m_TrackingHashBin); -} - -//============================================================================== -/** - * Destructor - */ -CMemoryTracker::~CMemoryTracker() -{ - CMemoryStatistics::Overhead() -= sizeof(m_TrackingHashBin); -} - -//============================================================================== -/** - * Add information about allocation - * @param inPtr contains info about a new allocation - */ -void CMemoryTracker::Remember(SMemoryInfo *inPointer) -{ - if (inPointer) { - // Update global tracking - m_TrackingOverhead += sizeof(SMemoryInfo); - - // Locate a suitable hashbin - size_t theHashBin = - (reinterpret_cast(inPointer) >> 2) % Q3DStudio_MEMORY_LINETRACKINGSIZE; - size_t theStartHashBin = theHashBin; - - while (m_TrackingHashBin[theHashBin]) { - ++theHashBin; - if (theHashBin >= Q3DStudio_MEMORY_LINETRACKINGSIZE) - theHashBin = 0; - - if (theHashBin == theStartHashBin) { - // We've run out of room in the hashbin. - // Abort and increase the bin size. - qCCritical(qt3ds::OUT_OF_MEMORY) - << "Memory Tracker Error: Ran out of room in tracker hashbin " - << Q3DStudio_MEMORY_LINETRACKINGSIZE; - // exit( -1 ); - } - } - - // Set WatchGuard and store the pointer in the hash bin - inPointer->m_DogTag = TRACKER_DOGTAG; - m_TrackingHashBin[theHashBin] = inPointer; - } -} - -//============================================================================== -/** - * Remove information on an allocation - * @param inPtr contains info about the allocation we are releasing - */ -void CMemoryTracker::Forget(SMemoryInfo *inPointer) -{ - if (inPointer) { - // Update global tracking - m_TrackingOverhead -= sizeof(SMemoryInfo); - - // Locate the pointer in the hash bin - size_t theHashBin = Q3DStudio_max(0, (reinterpret_cast(inPointer) >> 2) - % Q3DStudio_MEMORY_LINETRACKINGSIZE); - size_t theStartHashBin = theHashBin; - - while (m_TrackingHashBin[theHashBin] != inPointer) { - ++theHashBin; - if (theHashBin >= Q3DStudio_MEMORY_LINETRACKINGSIZE) - theHashBin = 0; - - if (theHashBin == theStartHashBin) { - // We were unable to locate the pointer in the hash bin. - // This is really bad, but not catastrophic - qCWarning(qt3ds::OUT_OF_MEMORY) - << "Memory Tracker Warning. Can't find pointer in tracker hashbin"; - return; - } - } - - // Verify watch guard. Something is trashing memory if this call fails. - Q3DStudio_ASSERT(m_TrackingHashBin[theHashBin]->m_DogTag == TRACKER_DOGTAG); - - // Clear the pointer from the hash bin - m_TrackingHashBin[theHashBin] = NULL; - } -} - -//============================================================================== -/** - * Dump the memory list stored in the hash bin. - * @param inFileName the report filename or NULL to dump to the logger - */ -INT32 CMemoryTracker::Report(IStream *inStream /*=NULL*/) -{ - INT32 theTotalBytes = 0; - CHAR theLine[256]; - - for (INT32 theBinIndex = 0; theBinIndex < Q3DStudio_MEMORY_LINETRACKINGSIZE; ++theBinIndex) { - if (m_TrackingHashBin[theBinIndex]) { - CMemoryTracker::SMemoryInfo *theInfo = m_TrackingHashBin[theBinIndex]; - - Q3DStudio_sprintf(theLine, sizeof(theLine), "0x%p, %8d, %s, %s(%hd)\n", theInfo, - theInfo->m_Size, theInfo->m_Type, theInfo->m_File, theInfo->m_Line); - - CMemoryStatistics::Report(inStream, theLine); - theTotalBytes += theInfo->m_Size; - } - } - - return theTotalBytes; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSTimer.cpp b/src/Runtime/Source/System/Source/Qt3DSTimer.cpp deleted file mode 100644 index d9e82eb9..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSTimer.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSTimer.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - */ -CTimer::CTimer(ITimeProvider &inProvider) - : m_TimeProvider(inProvider) - , m_IsRunning(false) -{ - Start(); -} - -//============================================================================== -/** - * Start the timer - */ -void CTimer::Start() -{ - if (!m_IsRunning) - m_StartTime = m_TimeProvider.GetCurrentTimeMicroSeconds(); - m_IsRunning = true; -} - -//============================================================================== -/** - * Stop the timer - */ -void CTimer::Stop() -{ - if (m_IsRunning) - m_StartTime = m_TimeProvider.GetCurrentTimeMicroSeconds() - m_StartTime; - - m_IsRunning = false; -} - -//============================================================================== -/** - * Reset the timer - */ -void CTimer::Reset() -{ - if (m_IsRunning) - m_StartTime = m_TimeProvider.GetCurrentTimeMicroSeconds(); - else - m_StartTime = 0; -} - -//============================================================================== -/** - * Gets the current time in milliseconds. - * @return the current time since timer was started(in miliseconds), - * or time when it was stopped - */ -TTimeUnit CTimer::GetTimeMilliSecs() -{ - return GetTimeMicroSecs() / 1000; -} - -//============================================================================= -/** - * Get the number of usecs elapsed since start was called. - * If the timer is running then this will return the time from when start was - * called. If the timer is stopped then this will return the amount of time - * between the start and last stop. - * @return returns the elasped micro second. - */ -TMicroSeconds CTimer::GetTimeMicroSecs() -{ - if (m_IsRunning) - return m_TimeProvider.GetCurrentTimeMicroSeconds() - m_StartTime; - else - return m_StartTime; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSTypes.cpp b/src/Runtime/Source/System/Source/Qt3DSTypes.cpp deleted file mode 100644 index 25d41c8b..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSTypes.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Return 2^inBitCount - 1. - * @param inBitCount number of bits available - * @param inUnsigned true if all bits are available - * @return the higest number the bits can represent - */ -INT32 Q3DStudio_maxbits(const INT32 inBitCount, const BOOL inUnsigned) -{ - Q3DStudio_ASSERT(inBitCount < 32); - if (inUnsigned) - return (1 << inBitCount) - 1; - else - return (1 << (inBitCount - 1)) - 1; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/System/Source/Qt3DSVector3.cpp b/src/Runtime/Source/System/Source/Qt3DSVector3.cpp deleted file mode 100644 index 2d790f95..00000000 --- a/src/Runtime/Source/System/Source/Qt3DSVector3.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSVector3.h" -#include "Qt3DSMatrix.h" -#include "Qt3DSDataLogger.h" -#include - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -extern const float RUNTIME_EPSILON = 0.0001f; -const float RUNTIME_SQUARE_EPSILON = 0.000001f; - -//============================================================================== -/** - * Simple constructor - creates a NULL vector. - */ -RuntimeVector3::RuntimeVector3() - : m_X(0.0f) - , m_Y(0.0f) - , m_Z(0.0f) -{ -} - -//============================================================================== -/** - * Construction from three array value. - * @param inVector the source array - */ -RuntimeVector3::RuntimeVector3(const float inVector[3]) - : m_X(inVector[0]) - , m_Y(inVector[1]) - , m_Z(inVector[2]) -{ -} - -//============================================================================== -/** - * Construction from three coordinates. - * @param inX the m_X coordinate - * @param inY the m_Y coordinate - * @param inZ the m_Z coordinate - */ -RuntimeVector3::RuntimeVector3(const float inX, const float inY, const float inZ) - : m_X(inX) - , m_Y(inY) - , m_Z(inZ) -{ -} - -//============================================================================== -/** - * Copy constructor - * @param inVector the source vector - */ -RuntimeVector3::RuntimeVector3(const RuntimeVector3 &inVector) - : m_X(inVector.m_X) - , m_Y(inVector.m_Y) - , m_Z(inVector.m_Z) -{ -} - -//============================================================================== -/** - * Assignment of coordinates. - * @param inX the m_X coordinate - * @param inY the m_Y coordinate - * @param inZ the m_Z coordinate - * @return a reference to this modified vector - */ -RuntimeVector3 &RuntimeVector3::Set(const float inX, const float inY, const float inZ) -{ - m_X = inX; - m_Y = inY; - m_Z = inZ; - return *this; -} - -//============================================================================== -/** - * Assignment of coordinates using another vector. - * @param inVector the vector to be copied. - * @return a reference to this modified vector - */ -RuntimeVector3 &RuntimeVector3::Set(const RuntimeVector3 &inVector) -{ - m_X = inVector.m_X; - m_Y = inVector.m_Y; - m_Z = inVector.m_Z; - return *this; -} - -//============================================================================== -/** - * Compare this vector with another. Exact match is not needed but instead - * an error of EPSILON is allowed. - * @param inVector the vector we are compared with - * @return true if the vectors are close to identical - * @see EPSILON - */ -bool RuntimeVector3::operator==(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - - return (::fabsf(m_X - inVector.m_X) < RUNTIME_EPSILON) && (::fabsf(m_Y - inVector.m_Y) < RUNTIME_EPSILON) - && (::fabsf(m_Z - inVector.m_Z) < RUNTIME_EPSILON); -} - -//============================================================================== -/** - * Compare this vector with another. Exact match is not needed but instead - * an error of EPSILON is allowed. - * @param inVector the vector we are compared with - * @return true if the vectors are not even close to identical - * @see EPSILON - */ -bool RuntimeVector3::operator!=(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - - return (::fabsf(m_X - inVector.m_X) > RUNTIME_EPSILON) || (::fabsf(m_Y - inVector.m_Y) > RUNTIME_EPSILON) - || (::fabsf(m_Z - inVector.m_Z) > RUNTIME_EPSILON); -} - -//============================================================================== -/** - * Add this vector with another but do not modify this vector. - * @param inVector the second vector being added - * @return a new vector - */ -RuntimeVector3 RuntimeVector3::operator+(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - - return RuntimeVector3(m_X + inVector.m_X, m_Y + inVector.m_Y, m_Z + inVector.m_Z); -} - -//============================================================================== -/** - * Add two vectors but do not modify this vector. - * @param inVector vector being subtracted - * @return a new vector - */ -RuntimeVector3 RuntimeVector3::operator-(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return RuntimeVector3(m_X - inVector.m_X, m_Y - inVector.m_Y, m_Z - inVector.m_Z); -} - -//============================================================================== -/** - * Get a scaled copy of this vector. - * @param inFactor the factor that scales each coordinate - * @return a new scaled vector - */ -RuntimeVector3 RuntimeVector3::operator*(float inFactor) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return RuntimeVector3(m_X * inFactor, m_Y * inFactor, m_Z * inFactor); -} - -//============================================================================== -/** - * Invert the vector. - * @return the inverted copy of this vector - */ -RuntimeVector3 RuntimeVector3::operator-() const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return RuntimeVector3(-m_X, -m_Y, -m_Z); -} - -//============================================================================== -/** - * Simple assignment. - * @param inVector the new vector - * @return a reference to this modified vector - */ -RuntimeVector3 &RuntimeVector3::operator=(const RuntimeVector3 &inVector) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - if (&inVector != this) { - m_X = inVector.m_X; - m_Y = inVector.m_Y; - m_Z = inVector.m_Z; - } - return *this; -} - -//============================================================================== -/** - * Increment this vector. - * @param inVector has the coordinates by which this vector will be incremented - * @return a reference to this modified vector - */ -RuntimeVector3 &RuntimeVector3::operator+=(const RuntimeVector3 &inVector) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - m_X += inVector.m_X; - m_Y += inVector.m_Y; - m_Z += inVector.m_Z; - return *this; -} - -//============================================================================== -/** - * Decrement this vector. - * @param inVector has the coordinates by which this vector will be decremented - * @return a reference to this modified vector - */ -RuntimeVector3 &RuntimeVector3::operator-=(const RuntimeVector3 &inVector) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - m_X -= inVector.m_X; - m_Y -= inVector.m_Y; - m_Z -= inVector.m_Z; - return *this; -} - -//============================================================================== -/** - * Scale this vector by a factor. - * @param inFactor the scale factor - * @return a reference to this modified vector - */ -RuntimeVector3 &RuntimeVector3::operator*=(float inFactor) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - m_X *= inFactor; - m_Y *= inFactor; - m_Z *= inFactor; - return *this; -} - -//============================================================================== -/** - * Calculates the squared distance between this vector and another. - * This is often used in sorting situations where the real distance isn't needed. - * @param inVector vector to which the distance is being calculated - * @return the squared distance between vectors - */ -float RuntimeVector3::DistanceSquared(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return (m_X - inVector.m_X) * (m_X - inVector.m_X) + (m_Y - inVector.m_Y) * (m_Y - inVector.m_Y) - + (m_Z - inVector.m_Z) * (m_Z - inVector.m_Z); -} - -//============================================================================== -/** - * Calculates the distance between this vector and another. - * @param inVector vector to which the distance is being calculated - * @return the distance between vectors - */ -float RuntimeVector3::Distance(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return ::sqrtf((m_X - inVector.m_X) * (m_X - inVector.m_X) - + (m_Y - inVector.m_Y) * (m_Y - inVector.m_Y) - + (m_Z - inVector.m_Z) * (m_Z - inVector.m_Z)); -} - -//============================================================================== -/** - * Calculates the squared length (squared magnitude) of the current vector. - * @return the squared length of this vector - */ -float RuntimeVector3::LengthSquared() const -{ - return m_X * m_X + m_Y * m_Y + m_Z * m_Z; -} - -//============================================================================== -/** - * Calculates the length (magnitude) of the current vector. - * @return the length of this vector - */ -float RuntimeVector3::Length() const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return ::sqrtf(m_X * m_X + m_Y * m_Y + m_Z * m_Z); -} - -//============================================================================== -/** - * Calculates the dot product of this vector and another. - * @param inVector vector measuring with - * @return the dot product - * @see operator* - */ -float RuntimeVector3::DotProduct(const RuntimeVector3 &inVector) const -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - return m_X * inVector.m_X + m_Y * inVector.m_Y + m_Z * inVector.m_Z; -} - -//============================================================================== -/** - * Calculates the cross product of this vector and another and modifies this vector - * @param inVector other vector - * @return this cross product vector - * @see operator% - * @see operator%= - */ -RuntimeVector3 &RuntimeVector3::CrossProduct(const RuntimeVector3 &inVector) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - float theX = m_Y * inVector.m_Z - m_Z * inVector.m_Y; - float theY = m_Z * inVector.m_X - m_X * inVector.m_Z; - float theZ = m_X * inVector.m_Y - m_Y * inVector.m_X; - - m_X = theX; - m_Y = theY; - m_Z = theZ; - - return *this; -} - -//============================================================================== -/** - * Normalizes the current vector making it a unit vector. - * The normalized vector is defined to be: V_norm = V / Magnitude(V). - * @return this normalized vector -*/ -RuntimeVector3 &RuntimeVector3::Normalize() -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - float theLengthSquared = LengthSquared(); - if ((theLengthSquared > RUNTIME_SQUARE_EPSILON) && ::fabsf(theLengthSquared - 1.0f) > RUNTIME_SQUARE_EPSILON) { - float theInvLength = 1.0f / ::sqrtf(theLengthSquared); - m_X *= theInvLength; - m_Y *= theInvLength; - m_Z *= theInvLength; - } - return *this; -} - -//============================================================================== -/** - * Modifies the current vector to contain elements that are the minimum between - * this vector and another. - * @param inVector vector that whose elements are tested against the - * current vector to build the minimum. - * @return this minimized vector -*/ -RuntimeVector3 &RuntimeVector3::Minimize(const RuntimeVector3 &inVector) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - m_X = Q3DStudio_min(m_X, inVector.m_X); - m_Y = Q3DStudio_min(m_Y, inVector.m_Y); - m_Z = Q3DStudio_min(m_Z, inVector.m_Z); - return *this; -} - -//============================================================================== -/** - * Modifies the current vector to contain elements that are the maximum between - * this vector and another. - * @param inVector vector that whose elements are tested against the - * current vector to build the maximum. - * @return this maximized vector -*/ -RuntimeVector3 &RuntimeVector3::Maximize(const RuntimeVector3 &inVector) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - m_X = Q3DStudio_max(m_X, inVector.m_X); - m_Y = Q3DStudio_max(m_Y, inVector.m_Y); - m_Z = Q3DStudio_max(m_Z, inVector.m_Z); - return *this; -} - -//============================================================================== -/** - * Modifies the current vector by performing a linear interpolation - * between the current vector and the given vector. - * - * If inFactor is 0.0 then this vector remains unchanged. If inFactor is - * 1.0 then this vector becomes inDestVector. If inFactor is between 0.0-1.0 - * then this vector becomes a vector between this old vector and inDestVector - * proportionally interpolated based in inFactor. If inFactor is less than 0 - * or more than 1 then this vector is extrapolated. - * - * @param inDestVector Second vector for the interpolation - * @param inFactor Weight for the interpolation - * @return this interpolated vector - */ -RuntimeVector3 &RuntimeVector3::InterpolateLinear(const RuntimeVector3 &inDestVector, float inFactor) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - m_X += inFactor * (inDestVector.m_X - m_X); - m_Y += inFactor * (inDestVector.m_Y - m_Y); - m_Z += inFactor * (inDestVector.m_Z - m_Z); - return *this; -} - -//============================================================================== -/** - * Transforms this vector by the given matrix. - * - * The matrix is row column of the form Matrix[row][column]: -@code - | m0 m1 m2 w | - | m4 m5 m6 w | - | m8 m9 m10 w | - | tX tY tZ w | -@endcode - * @param inMatrix transform matrix - * @return this transformed vector - */ -RuntimeVector3 &RuntimeVector3::Transform(const RuntimeMatrix &inMatrix) -{ - PerfLogMathEvent1(DATALOGGER_VECTOR); - float theX = m_X; - float theY = m_Y; - float theZ = m_Z; - - m_X = theX * inMatrix.Get(0, 0) + theY * inMatrix.Get(1, 0) + theZ * inMatrix.Get(2, 0); - m_Y = theX * inMatrix.Get(0, 1) + theY * inMatrix.Get(1, 1) + theZ * inMatrix.Get(2, 1); - m_Z = theX * inMatrix.Get(0, 2) + theY * inMatrix.Get(1, 2) + theZ * inMatrix.Get(2, 2); - - m_X += inMatrix.Get(3, 0); - m_Y += inMatrix.Get(3, 1); - m_Z += inMatrix.Get(3, 2); - - return *this; -} - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/UIPParser/Include/Qt3DSIPresentation.h b/src/Runtime/Source/UIPParser/Include/Qt3DSIPresentation.h deleted file mode 100644 index 00f3d15a..00000000 --- a/src/Runtime/Source/UIPParser/Include/Qt3DSIPresentation.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSEventCallbacks.h" - -namespace qt3ds { -namespace runtime { - class IApplication; - class IActivityZone; - class IAnimationSystem; - class ISlideSystem; - class ILogicSystem; - class IParametersSystem; -} -} - -namespace qt3ds { -namespace foundation { - class IStringTable; -} -} - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class IComponentManager; -class IEventManager; -class IScene; -class IScriptBridge; -class CPresentationFrameData; -class CTimePolicy; -using qt3ds::runtime::ISlideSystem; -using qt3ds::runtime::IAnimationSystem; -using qt3ds::runtime::ILogicSystem; -using qt3ds::runtime::IParametersSystem; - -//============================================================================== -// Enumeration -//============================================================================== -/// Method used to translate from presentation size to window size -enum EScaleMode { - SCALEMODE_FREE, ///< Free scaling mode - SCALEMODE_EXACT, ///< Fixed presentation size - SCALEMODE_ASPECT, ///< Maintain aspect ratio - SCALEMODE_UNKNOWN, ///< ERROR! - Uninitialized scale mode -}; - -//============================================================================== -// Structs -//============================================================================== -struct SPresentationSize -{ - SPresentationSize() - : m_Width(0) - , m_Height(0) - , m_ScaleMode(0) - { - } - UINT16 m_Width; ///< Native width of the presentation - UINT16 m_Height; ///< Native height of the presentation - UINT8 m_ScaleMode; ///< Presentation to window scale method - UINT8 m_Padding[3]; -}; - -//============================================================================== -/** - * @interface IPresentation - * Base interface of the presentation. - */ -class IPresentation -{ - //============================================================================== - // Methods - //============================================================================== -public: // Construction - IPresentation() {} - virtual ~IPresentation() {} - -public: // Execution - virtual void ClearDirtyList() = 0; - virtual void PreUpdate(const TTimeUnit inGlobalTime) = 0; - virtual void BeginUpdate() = 0; - virtual void EndUpdate() = 0; - virtual void PostUpdate(const TTimeUnit inGlobalTime) = 0; - -public: // Bridge Control - virtual void SetScene(IScene *inScene) = 0; - virtual IScene *GetScene() const = 0; - virtual IScriptBridge *GetScriptBridgeQml() = 0; - -public: // Commands and Events - virtual void FireEvent(const TEventCommandHash inEventType, TElement *inTarget, - const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, - const EAttributeType inType1 = ATTRIBUTETYPE_NONE, - const EAttributeType inType2 = ATTRIBUTETYPE_NONE) = 0; - virtual void FireCommand(const TEventCommandHash inEventType, TElement *inTarget, - const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, - const EAttributeType inType1 = ATTRIBUTETYPE_NONE, - const EAttributeType inType2 = ATTRIBUTETYPE_NONE) = 0; - virtual void FlushEventCommandQueue(void) = 0; - virtual void ProcessEvent(SEventCommand &) = 0; - -public: // Manager Access - virtual IComponentManager &GetComponentManager() = 0; - virtual ISlideSystem &GetSlideSystem() = 0; - virtual IAnimationSystem &GetAnimationSystem() = 0; - virtual ILogicSystem &GetLogicSystem() = 0; - virtual IParametersSystem &GetParametersSystem() = 0; - - virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; - virtual qt3ds::runtime::IApplication &GetApplication() = 0; - virtual qt3ds::runtime::IActivityZone *GetActivityZone() = 0; - -public: // Hooks and callbacks - virtual void OnPresentationLoaded() = 0; - -public: // Full file path - virtual void SetFilePath(const CHAR *inPath) = 0; - virtual QString GetFilePath() = 0; - virtual TElement *GetRoot() = 0; - virtual void SetRoot(TElement &inRoot) = 0; - -public: // Configuration access - virtual SPresentationSize GetSize() const = 0; - virtual void SetSize(const SPresentationSize &inSize) = 0; - virtual void SetElementPath(TElement &inElement, const char8_t *inPath) = 0; - virtual qt3ds::foundation::CRegisteredString GetElementPath(TElement &inElement) = 0; - -public: // Event Callbacks - virtual void RegisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) = 0; - virtual BOOL UnregisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, - const TEventCallback inCallback, void *inContextData) = 0; - -public: // FrameData access - virtual CPresentationFrameData &GetFrameData() = 0; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParser.h b/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParser.h deleted file mode 100644 index 1c31d457..00000000 --- a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParser.h +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "foundation/StringTable.h" -#include - -namespace qt3ds { -namespace state { - struct SSetAttribute; - namespace debugger { - class ISceneGraphRuntimeDebugger; - } -} -} - -namespace qt3ds { -namespace render { - class IInputStreamFactory; -} -} - -//============================================================================== -// Forwards -//============================================================================== -namespace qt3dsdm { -class IDOMReader; -class IStringTable; -} - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { -using namespace qt3ds::foundation; -//============================================================================== -// Forwards -//============================================================================== -class IRuntimeMetaData; -class IPresentation; - -struct UIPElementTypes -{ - enum Enum { - Unknown = 0, - Scene = 1, - Node, - Layer, - Component, - Group, - Behavior, - Model, - Light, - Camera, - Image, - Material, - Text, - Effect, - RenderPlugin, - CustomMaterial, - ReferencedMaterial, - Path, - PathAnchorPoint, - PathSubPath, - }; -}; - -struct SElementAndType -{ - UIPElementTypes::Enum m_Type; - TElement *m_Element; - SElementAndType(UIPElementTypes::Enum inType, TElement *elem) - : m_Type(inType) - , m_Element(elem) - { - } -}; - -// Ensure these elements exist and if the attribute isn't empty ensure the attribute is referenced. -struct SElementAttributeReference -{ - eastl::string m_Path; - eastl::string m_Attribute; - SElementAttributeReference(const eastl::string &p, const eastl::string &a) - : m_Path(p) - , m_Attribute(a) - { - } -}; -//============================================================================== -/** - * @class CUIPParser - * @brief Class for parsing UIP file - */ - -class IUIPParser : public NVReleasable -{ -protected: - virtual ~IUIPParser() {} -public: // Parse UIP file - virtual BOOL Load(IPresentation &inPresentation, - NVConstDataRef inStateReferences, - qt3ds::state::debugger::ISceneGraphRuntimeDebugger &inDebugger) = 0; - virtual qt3dsdm::IDOMReader &GetDOMReader() = 0; - virtual IRuntimeMetaData &GetMetaData() = 0; - // Mapping back from file id to element id, needed to hook elements up to their respective - // parsed - // counterparts. - virtual SElementAndType GetElementForID(const char *inStringId) = 0; - virtual eastl::string ResolveReference(const char *inStringId, const char *inReferance) = 0; - // The rendering system needs to know every sourcepath found during parse of the UIP file - // so that it can do things like register images as opaque/transparent as well as preload - // mesh files (and possibly font files). - virtual NVConstDataRef GetSourcePaths() const = 0; - - // Creation function - static IUIPParser &Create(const QString &inFileName, IRuntimeMetaData &inMetaData, - qt3ds::render::IInputStreamFactory &inStreamFactory, - qt3ds::foundation::IStringTable &inStrTable); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserActionHelper.h b/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserActionHelper.h deleted file mode 100644 index 3d9d44ce..00000000 --- a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserActionHelper.h +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSUIPParserImpl.h" - -namespace qt3ds { -namespace runtime { - class IParametersSystem; -} -} -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { -using qt3ds::runtime::IParametersSystem; -//============================================================================== -// Forwards -//============================================================================== - -//============================================================================== -/** - * @class CUIPParserActionHelper - * @brief Class for parsing UIP file - Action - */ -class CUIPParserActionHelper -{ - //============================================================================== - // Fields - //============================================================================== -protected: - CUIPParserImpl *m_UIPParser; - CUIPParserObjectRefHelper *m_ObjRefHelper; - IRuntimeMetaData &m_MetaData; ///< Reference to Metadata - - typedef eastl::map TActionIdentifierMap; ///< Mapping of the string that - ///uniquely identify the action - ///to the index created - TActionIdentifierMap m_ActionIdentifierMap; - - struct SHandlerArgumentInfo - { - eastl::string m_Name; - eastl::string m_Value; - - SHandlerArgumentInfo() {} - }; - typedef eastl::vector THandlerArguments; ///< List of handler arguments - struct SActionInfo - { - eastl::string m_Id; - - // Where the action is added to - eastl::string m_Owner; // Absolute path of owner object - - // Trigger object - eastl::string m_TriggerObject; // Absolute path of trigger object - eastl::string m_Event; - - // Target object - eastl::string m_TargetObject; // Absolute path of target object - eastl::string m_Handler; - THandlerArguments m_HandlerArgs; - - SActionInfo() {} - }; - typedef eastl::map TActionMap; ///< Map of action id and action info - - TActionMap m_ActionMap; - - // There are 2 tables involved: - // 1. The Listener-To-Events tables - multimap of each listener to all events it is listening to - // 2. The Listener-Event-To-Actions table - multimap of each listener-event pair to all actions - // it triggers - // note: The struct for Action is a pair of EventAction node and its owner - struct SListenerEventNamePair - { - eastl::string m_Listener; - eastl::string m_Event; - - SListenerEventNamePair(eastl::string inListener, const eastl::string &inEvent) - : m_Listener(inListener) - , m_Event(inEvent) - { - } - - bool operator<(const SListenerEventNamePair &inListenerEventPair) const - { - if (m_Listener == inListenerEventPair.m_Listener) - return m_Event < inListenerEventPair.m_Event; - return m_Listener < inListenerEventPair.m_Listener; - } - }; - - typedef eastl::pair - TEventActionOwnerPair; ///< One listener(source) can listen to multiple events - typedef eastl::multimap - TListenerEventsNameMap; ///< One listener(source)-event pair can trigger multiple actions - typedef eastl::multimap TListenerEventActionsMap; - - TListenerEventsNameMap m_ListenerEventsNameMap; - TListenerEventActionsMap m_ListenerEventActionsMap; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CUIPParserActionHelper(CUIPParserImpl *inUIPParser, CUIPParserObjectRefHelper *inObjRefHelper, - IRuntimeMetaData &inMetaData); - virtual ~CUIPParserActionHelper(); - -public: - void CacheAction(qt3dsdm::IDOMReader &inReader, const char8_t *inOwnerId); - void BuildActions(IPresentation &inPresentation); - void GetActionSectionCount(CUIPParserImpl::SActionSectionCount &outActionCount); - INT32 GetActionCount(const eastl::string &inActionId); - INT32 GetActionIndex(const eastl::string &inActionId); - -protected: // Action helper - void AddListenerEventPair(eastl::string inListener, const eastl::string &inEventName); - void CacheHandlerArguments(qt3dsdm::IDOMReader &inReader, SActionInfo &inAction); - void BuildAction(TElement &inElement, UINT32 inEventName, IPresentation &inPresentation, - const eastl::string &inActionId); - INT32 GetActionCount(const eastl::string &inActionId, INT32 &outStringAttrCount, - INT32 &outCustomParamCount); - bool IsCustomHandler(const SActionInfo &inAction); - void GetHandlerArgumentType(const SActionInfo &inAction, int inArgumentIndex, - ERuntimeDataModelDataType &outType, - ERuntimeAdditionalMetaDataType &outAdditionalType); - void GetCustomActionParametersCount(ERuntimeDataModelDataType inDataType, - ERuntimeAdditionalMetaDataType inAdditionalType, - INT32 &outStringAttrCount, INT32 &outCustomParamCount); - void ExportCustomActionParameters(IPresentation &inPresentation, - IParametersSystem &inParamSystem, QT3DSI32 inParamGroup, - const char *inDataValue, ERuntimeDataModelDataType inDataType, - ERuntimeAdditionalMetaDataType inAdditionalType); - - inline SElement *GetElement(const eastl::string &inElementName); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserImpl.h b/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserImpl.h deleted file mode 100644 index 1a7ac778..00000000 --- a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserImpl.h +++ /dev/null @@ -1,664 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -/* -This is the main file responsible for conversion from the uip format into the runtime's data format. -The runtime works in a sort of global space so any object, be it an animation, action or element, -once -activated stays activated. Furthermore it is important that the runtime declare and set the fewest -number -of properties possible to still get the right answer. In order to achieve this the runtime relies -on the -rendering system to have the initial state of the entire scene graph, including state that is only -"Add" -commands declared in slides. - -Given that you understand master slide/ slide distinction, an accurate description would be to do -this: -1. Move all parse objects (actions, animations, elements) to be master objects and deactivate them. -2. Running through the list of nonmaster slides, activate the objects on those slides that would be -activated. -3. Now remove properties that are both unreferenced and applied 1 or fewer times. - - -The parsing system does this in reverse order so the passes look like: -1. Load meta data information (scripts, effects) to have a complete meta data model. -1. Build element graph. This is used during attribute lookup -2. Figure out which attributes will be on the elements in the graph by resolving behavior -references, action references and - Animations, and Set command attribute applications. - - During this pass we also build the set of actions and animations which will appear on each -slide. This involves both promoting - actions/animations that appear on the master slide to child slides and pulling -animations/actions declared on all child slides - onto the master slide. - -3. Count the objects that we will need. The runtime currently requires fixed object counts that -can't be exceeded - thus we have to effectively preallocate all runtime objects. - -4. Run through the file again and build the actual runtime datastructures. Actions and animations -are built from - an intermediate memory representation but the set commands and element activations are built -via running through - the file. - - -Care needs to be taken so the runtime can survive poorly formed or just meaningless uip files. -Studio is only *one* -system for producing UIP files, clients are free to use code generates (like ruby scripts and such) -to build their final -uip files so we need to be careful that we are as robust as possible and can tolerate gracefully -some level of incorrect -uip file data. -*/ - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSUIPParser.h" -#include "Qt3DSTypes.h" -#include "Qt3DSMetadata.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSSlideSystem.h" -#include "Qt3DSDMDataTypes.h" -#include "foundation/Qt3DSMemoryBuffer.h" -#include -#include -#include -#include "Qt3DSElementSystem.h" -#include "Qt3DSSlideSystem.h" - -namespace qt3ds { -namespace render { - class IRefCountedInputStream; -} -} - -namespace qt3dsdm { -class IDOMReader; -class IDOMWriter; -} -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Forwards -//============================================================================== -class IPresentation; -class SElementBuilder; -class CContractBuilder; -class CAnimationBuilder; -class CLogicBuilder; -class CSlideBuilder; -class IRuntimeMetaData; -class CUIPParserActionHelper; -class CUIPParserObjectRefHelper; - -typedef eastl::vector TPropertyDescAndValueList; - -using qt3ds::render::IInputStreamFactory; -using qt3ds::render::IRefCountedInputStream; -typedef NVScopedRefCounted TInputStreamPtr; -typedef qt3ds::foundation::CRegisteredString TStrType; -using qt3ds::runtime::element::SElement; - -struct SElementPropertyInfo -{ - enum Enum { - MaxArity = 4, - }; - TStrType m_PropertyName; - ERuntimeDataModelDataType m_DataType; - ERuntimeAdditionalMetaDataType m_AdditionalType; - // Number of sub components of the property, 1-4 - qt3ds::QT3DSU32 m_Arity; - qt3ds::QT3DSU32 m_PropertyHashes[MaxArity]; - CRegisteredString m_PropertyNames[MaxArity]; - bool m_ElementFlag; // True if this property exists on the element. Some properties do not. - bool m_SlideFlag; // True if this property exists on the slides at all. - // starttime,endtime are forced to be on the slides whether they are in the UIP or not. - bool m_SlideForceFlag; // True if this property is *forced* on the slides whether it needs to be - // there or not - - SElementPropertyInfo(TStrType inPropName) - : m_PropertyName(inPropName) - , m_DataType(ERuntimeDataModelDataTypeNone) - , m_Arity(0) - , m_ElementFlag(false) - , m_SlideFlag(false) - , m_SlideForceFlag(false) - { - memZero(m_PropertyHashes, sizeof(m_PropertyHashes)); - } - bool operator<(const SElementPropertyInfo &inOther) const - { - return m_PropertyName < inOther.m_PropertyName; - } -}; - -typedef eastl::hash_map TAttrMap; - -struct SElementData -{ - SElement *m_Element; - TStrType m_Id; - TStrType m_Type; - TStrType m_Class; - TAttrMap m_PropertyMap; - - SElementData(TStrType inId) - : m_Element(NULL) - , m_Id(inId) - { - } - void SetElement(SElement *inElement, TStrType inType, TStrType inClass) - { - m_Element = inElement; - m_Type = inType; - m_Class = inClass; - } -}; - -typedef eastl::hash_map TIdElementMap; - -struct SParseElementManager -{ - IRuntimeMetaData &m_MetaData; - TIdElementMap m_ElementMap; - // Temporary variables for various algorithms - eastl::string m_Workspace; - eastl::vector m_PropertyList; - qt3ds::foundation::IStringTable &m_StringTable; - - SParseElementManager(IRuntimeMetaData &inMetaData, qt3ds::foundation::IStringTable &inStrTable) - : m_MetaData(inMetaData) - , m_StringTable(inStrTable) - { - } - TStrType RegisterStr(const char8_t *inStr); - SElementData &GetOrCreateElementData(const char8_t *inElemIdOrRef, const char8_t *inElemType, - const char8_t *inElemClassId); - SElementData *FindElementData(const char8_t *inIdOrRef); - // We don't allow creation of properties that don't exist in the meta data in the first place. - SElementPropertyInfo *GetOrCreateProperty(SElementData &inData, const char8_t *inPropertyName); - SElementPropertyInfo *GetOrCreateProperty(const char8_t *inIdOrRef, const char8_t *inElemType, - const char8_t *inElemClassId, - const char8_t *inPropertyName); - SElementPropertyInfo *FindProperty(SElementData &inElement, const char8_t *inPropertyName); - SElementPropertyInfo *FindProperty(const char8_t *inIdOrRef, const char8_t *inPropertyName); - eastl::pair - FindPropertyWithSubIndex(SElementData &inElement, const char8_t *inPropertyName); - // Attribute marking stage; mark which attributes will be kept on elements at all. - void MarkAttributeAsReferenced(SElementData &inElement, const char8_t *inPropertyName); - void MarkAttributeAsReferenced(const char8_t *inElement, const char8_t *inPropertyName); - void MarkAllAttributesAsReferenced(SElementData &inElement, bool searchParent = false); -}; - -struct SParseSlideActionEntry -{ - TStrType m_SlideId; - TStrType m_ActionId; - qt3ds::QT3DSI32 m_ActionCount; - bool m_Active; - qt3ds::runtime::SSlideAnimAction *m_Actions[SElementPropertyInfo::MaxArity]; - - SParseSlideActionEntry(TStrType inSlideId, TStrType inActionId, qt3ds::QT3DSI32 inActionCount, - bool inActive) - : m_SlideId(inSlideId) - , m_ActionId(inActionId) - , m_ActionCount(inActionCount) - , m_Active(inActive) - { - memZero(m_Actions, sizeof(m_Actions)); - } - SParseSlideActionEntry() - : m_ActionCount(0) - , m_Active(false) - { - } - // Partial equals, used for finding object in vector. - bool operator==(const SParseSlideActionEntry &inOther) const - { - return m_SlideId == inOther.m_SlideId && m_ActionId == inOther.m_ActionId; - } -}; - -typedef eastl::vector TActionList; - -struct SParseSlideAnimationTypes -{ - enum Enum { - NoAnimation = 0, - Linear, - EaseInOut, - Bezier, - }; -}; - -struct SParseSlideAnimationEntry -{ - TStrType m_SlideId; - TStrType m_InstanceId; - TStrType m_PropertyName; - qt3ds::QT3DSU32 m_PropertyHash; - qt3ds::QT3DSI32 m_AnimationIndex; - eastl::vector m_KeyframeData; - SParseSlideAnimationTypes::Enum m_AnimationType; - bool m_IsDynamic; - - SParseSlideAnimationEntry() - : m_AnimationIndex(-1) - , m_KeyframeData("") - , m_AnimationType(SParseSlideAnimationTypes::NoAnimation) - , m_IsDynamic(false) - { - } - SParseSlideAnimationEntry(TStrType inSlideId, TStrType inInstanceId, TStrType inPropertyName, - qt3ds::QT3DSU32 inPropHash, SParseSlideAnimationTypes::Enum inAnimType, - const float *inKeyframeData, qt3ds::QT3DSU32 inNumFloats, bool inIsDynamic) - : m_SlideId(inSlideId) - , m_InstanceId(inInstanceId) - , m_PropertyName(inPropertyName) - , m_PropertyHash(inPropHash) - , m_AnimationType(inAnimType) - , m_IsDynamic(inIsDynamic) - { - m_KeyframeData.insert(m_KeyframeData.begin(), inKeyframeData, inKeyframeData + inNumFloats); - } -}; - -struct SParseAnimationRef -{ - TStrType m_SlideId; - TStrType m_InstanceId; - TStrType m_PropertyName; - bool m_Active; - const SParseSlideAnimationEntry *m_Animation; - - SParseAnimationRef(TStrType inSlideId, TStrType inInstanceId, TStrType inPropName, - const SParseSlideAnimationEntry *inAnimation, bool inActive) - : m_SlideId(inSlideId) - , m_InstanceId(inInstanceId) - , m_PropertyName(inPropName) - , m_Active(inActive) - , m_Animation(inAnimation) - { - } - SParseAnimationRef() - : m_Active(false) - , m_Animation(NULL) - { - } - // Partial equals, used for finding object in vector. - bool operator==(const SParseAnimationRef &inOther) const - { - return m_SlideId == inOther.m_SlideId && m_InstanceId == inOther.m_InstanceId - && m_PropertyName == inOther.m_PropertyName; - } -}; - -typedef eastl::vector TAnimationList; - -typedef eastl::hash_map TInstanceIdAnimationMap; - -struct SParseSlide -{ - TStrType m_SlideId; - qt3ds::QT3DSI32 m_SlideIndex; - TActionList m_ActionList; - TInstanceIdAnimationMap m_Animations; - - SParseSlide(TStrType inId, qt3ds::QT3DSI32 inSlideIndex) - : m_SlideId(inId) - , m_SlideIndex(inSlideIndex) - { - } - SParseSlide() {} -}; - -typedef eastl::hash_map TSlideIdToParseSlideMap; - -struct SParseSlideManager -{ - IRuntimeMetaData &m_MetaData; - SParseElementManager &m_ElementManager; - TSlideIdToParseSlideMap m_SlideMap; - eastl::vector m_Animations; - qt3ds::QT3DSI32 m_SlideAnimationCount; - qt3ds::QT3DSI32 m_AnimationKeyframeCount; - qt3ds::QT3DSI32 m_ActionCount; - eastl::vector m_KeyframeParseFloatBuffer; - eastl::string m_KeyframeParseBuffer; - - SParseSlideManager(IRuntimeMetaData &inMD, SParseElementManager &inElemMgr) - : m_MetaData(inMD) - , m_ElementManager(inElemMgr) - , m_SlideAnimationCount(0) - , m_AnimationKeyframeCount(0) - , m_ActionCount(0) - { - } - ~SParseSlideManager(); - TStrType RegisterId(const char8_t *inStr); - TStrType RegisterStr(const char8_t *inStr) { return m_ElementManager.RegisterStr(inStr); } - SParseSlide &GetOrCreateSlide(const char8_t *inSlideId, qt3ds::QT3DSI32 inSlideIndex); - SParseSlide *FindSlide(const char8_t *inSlideId); - // Create an animation and reference that animation - void SetAnimationData(SParseSlide &inSlide, const char8_t *inInstanceId, - const char8_t *inPropertyName, const char8_t *inKeyframeData, - SParseSlideAnimationTypes::Enum inType, bool inIsDynamic, - bool inIsActive); - // Reference an animation. - void ReferenceAnimation(SParseSlide &inSlide, const SParseSlideAnimationEntry &inSource, - bool inIsActive); - TAnimationList *GetAnimationsForInstance(SParseSlide &inSlide, const char8_t *inInstanceId); - SParseSlideActionEntry &GetOrCreateAction(SParseSlide &inSlide, const char8_t *inActionId, - qt3ds::QT3DSI32 inActionCount, bool inEyeball); - SParseSlideActionEntry *FindAction(SParseSlide &inSlide, const char8_t *inActionId); -}; - -//============================================================================== -/** - * @class CUIPParserImpl - * @brief Class for parsing UIP file - */ -class CUIPParserImpl : public IUIPParser -{ - - typedef eastl::basic_string TNarrowStr; - - //============================================================================== - // Fields - //============================================================================== -protected: - std::shared_ptr m_DOMReader; - std::shared_ptr m_DOMWriter; - IRuntimeMetaData &m_MetaData; ///< Reference to Metadata - IInputStreamFactory &m_InputStreamFactory; - SParseElementManager m_ParseElementManager; ///< Map of id, SElement* - SParseSlideManager m_ParseSlideManager; - - CUIPParserActionHelper *m_ActionHelper; ///< Action Helper - CUIPParserObjectRefHelper *m_ObjectRefHelper; ///< Object Reference Helper - - typedef eastl::set TAddedSlideElements; - TAddedSlideElements m_SlideElements; ///< Caching of slide elements added, so that we don't need - ///to pass this around - - typedef eastl::map TIdSourcePathMap; - TIdSourcePathMap m_IdScriptMap; ///< Map of the class id and script sourcepath - - typedef eastl::map TIdClassMap; - TIdClassMap m_IdClassMap; ///< Map of id and class reference - - typedef eastl::set TStringSet; - typedef eastl::vector TStringVector; - - TStringSet m_SourcePathSet; - TStringVector m_SourcePathList; - - struct SElementRefCache - { - SElementData *m_Element; - eastl::string m_Name; - eastl::string m_Value; - }; - eastl::vector m_ElementRefCache; ///< Cache those element refs in the scene - ///graph that needs to be patch later - - struct SEaseInEaseOutKeyframe - { - float m_Time; - float m_Value; - float m_EaseIn; - float m_EaseOut; - }; - - struct SGraphSectionCount - { - INT32 m_ElementCount; - INT32 m_ComponentCount; - INT32 m_AttributeCount; - INT32 m_StringAttrCount; - - SGraphSectionCount() - : m_ElementCount(0) - , m_ComponentCount(0) - , m_AttributeCount(0) - , m_StringAttrCount(0) - { - } - }; - - struct SLogicSectionCount - { - INT32 m_SlideCount; - INT32 m_SlideElementCount; - INT32 m_SlideAttributeCount; - INT32 m_StringAttrCount; - INT32 m_PaddingCount; - - SLogicSectionCount() - : m_SlideCount(0) - , m_SlideElementCount(0) - , m_SlideAttributeCount(0) - , m_StringAttrCount(0) - , m_PaddingCount(0) - { - } - }; - - struct SActionSectionCount - { - INT32 m_TriggerElementCount; - INT32 m_TriggerEventCount; - INT32 m_ActionCount; - INT32 m_StringAttrCount; - INT32 m_CustomParamCount; - - SActionSectionCount() - : m_TriggerElementCount(0) - , m_TriggerEventCount(0) - , m_ActionCount(0) - , m_StringAttrCount(0) - , m_CustomParamCount(0) - { - } - }; - - long m_NumGraphElements; /// eclee testing only, must remove - long m_NumGraphComponents; /// eclee testing only, must remove - long m_NumGraphAttributes; /// eclee testing only, must remove - long m_NumSlides; /// eclee testing only, must remove - long m_NumSlideElements; /// eclee testing only, must remove - long m_NumSlideAttributes; /// eclee testing only, must remove - long m_NumAnimationTracks; /// eclee testing only, must remove - long m_NumAnimationKeys; /// eclee testing only, must remove - long m_NumSlideAnimations; /// eclee testing only, must remove - long m_NumSlideActions; /// klarinda testing only, must remove - - // temporarily this is here - qt3ds::foundation::MemoryBuffer m_TempBuffer; - qt3ds::foundation::MemoryBuffer m_ValueBuffer; - - IPresentation *m_CurrentPresentation; - - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CUIPParserImpl(const QString &inFileName, IRuntimeMetaData &inMetaData, - IInputStreamFactory &inFactory, qt3ds::foundation::IStringTable &inStringTable); - virtual ~CUIPParserImpl(); - -public: // Parse UIP file - BOOL Load(IPresentation &inPresentation, - NVConstDataRef inStateReferences, - qt3ds::state::debugger::ISceneGraphRuntimeDebugger &debugger) override; - qt3dsdm::IDOMReader &GetDOMReader() override; - IRuntimeMetaData &GetMetaData() override; - SElementAndType GetElementForID(const char *inStringId) override; - eastl::string ResolveReference(const char *inStringId, const char *inReferance) override; - NVConstDataRef GetSourcePaths() const override - { - return NVConstDataRef(m_SourcePathList.data(), m_SourcePathList.size()); - } - -protected: // Operation - BOOL LoadProjectSettings(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); - BOOL LoadClasses(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); - BOOL LoadGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); - BOOL LoadSceneGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, - qt3ds::runtime::element::SElement *inNewStyleParent = NULL); - BOOL LoadLogic(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); - BOOL LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); - -protected: // Memory Counter - void ComputeAndReserveMemory(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); - void DoGraphSectionCount(qt3dsdm::IDOMReader &inReader, SGraphSectionCount &outGraphCounter); - void DoLogicSectionCount(qt3dsdm::IDOMReader &inReader, SLogicSectionCount &outLogicCounter); - void DoStateSectionCount(qt3dsdm::IDOMReader &inReader, INT32 inSlideIndex, - SLogicSectionCount &outLogicCounter); - void DoRefSectionCount(qt3dsdm::IDOMReader &inReader, INT32 inNumSlideMultiplier, - INT32 inSlideIndex, SLogicSectionCount &outLogicCounter); - -protected: // Scene graph heler - void CacheGraphRequiredAttributes(qt3dsdm::IDOMReader &inReader); - BOOL CacheLogicRequiredAttributes(qt3dsdm::IDOMReader &inReader, qt3ds::QT3DSI32 inSlideIndex = 0, - SParseSlide *inParentSlide = NULL); - void CacheClassRequiredAttributes(qt3dsdm::IDOMReader &inReader); - void CacheClassSceneAttributes(qt3dsdm::IDOMReader &inReader); - void CacheClassStateAttributes(qt3dsdm::IDOMReader &inReader); - void AddElementRefToPatch(TPropertyDescAndValueList &outDescList, SElementData &inElement, - const char *inName, const char *inValue); - void PatchSceneElementRef(); - -protected: // Slide helper - BOOL LoadState(IPresentation &inPresentation, SElement *inComponent, INT32 inSlideIndex, - qt3dsdm::IDOMReader &inReader); - qt3ds::runtime::SSlidePlayInformation GetPlayMode(qt3dsdm::IDOMReader &inReader); - INT32 GetPlayThroughTo(INT32 inCurrentSlideIndex, qt3dsdm::IDOMReader &inReader); - eastl::string GetSlideName(qt3dsdm::IDOMReader &inReader); - eastl::string GetSlideId(qt3dsdm::IDOMReader &inReader); - BOOL LoadSlideElements(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, - bool inMaster, SElement *inComponent, INT32 *outMaxTime = NULL); - SElementData *AddSlideElement(IPresentation &inPresentation, bool inMaster, - qt3dsdm::IDOMReader &inReader, INT32 *outMaxTime = NULL); - BOOL LoadSlideElementAttrs(IPresentation &inPresentation, bool inMaster, - SElementData &inElementData, qt3dsdm::IDOMReader &inReader, - SElement *inComponent); - BOOL ProcessStateRef(IPresentation &inPresentation, SElement *inComponent, bool inMaster, - qt3dsdm::IDOMReader &inReader); - -protected: // Animation helper - void LoadAnimationTrack(IPresentation &inPresentation, SElementData &inElementData, - SParseSlideAnimationEntry &inAnimation); - void LoadAnimationKeys(IPresentation &inPresentation, - const SParseSlideAnimationEntry &inAnimation, bool inIsRotation); - BOOL LoadBezierKeys(IPresentation &inPresentation, NVConstDataRef &inValues, - bool inIsRotation); - BOOL LoadLinearKeys(IPresentation &inPresentation, NVConstDataRef &inValues, - bool inIsRotation); - BOOL LoadEaseInOutKeys(IPresentation &inPresentation, NVConstDataRef &inValues, - bool inIsRotation); - SEaseInEaseOutKeyframe ParseEaseInOutKey(const float *&inFloatIter); - BOOL ProcessSlideAnimAction(IPresentation &inPresentation, eastl::string &inSlideId, - bool inMaster, qt3dsdm::IDOMReader &inReader); - BOOL AddSlideAction(IPresentation &inPresentation, eastl::string &inSlideId, bool inActive, - qt3dsdm::IDOMReader &inReader); - void CreateBezierKeyframeFromEaseInEaseOutKeyframe(float *inPreviousValue, - SEaseInEaseOutKeyframe &inCurrent, - float *inNextValue, float *&outBezierValues); - -protected: // Helper methods - bool IsStringType(ERuntimeDataModelDataType inDataType); - void GetAttributeList(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, - TStrType inType, TStrType inName, TStrType inClassId, const char *inValue, - CRegisteredString *inPropNameStrs); - void GetAttributeList(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, - ERuntimeDataModelDataType inDataType, - ERuntimeAdditionalMetaDataType inAdditionalType, const char *inName, - const char *inValue, CRegisteredString *inPropNameStrs); - - SElementData *GetElementData(TStrType inElementName); - SElementData *GetElementData(const char8_t *inElementName); - SElement *GetElement(const char8_t *inElementName); - // Returns the data type and a boolean indicating if this attribute is actually used on a - // particular slide. - eastl::pair - GetAttributeType(const char8_t *inElementName, const char8_t *inPropertyName, - const SElementData &inElementData); - SElementData *ParseObjectRef(const eastl::string &inObjectPath, const char8_t *inOwnerId); - TStrType ParseObjectRefId(const eastl::string &inObjectPath, const char8_t *inOwnerId); - - void GetMetaAttribute(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, - TStrType inType, TStrType inName, TStrType inClassId, - CRegisteredString *inAttStrNames); - -protected: - void AddFloatAttribute(TPropertyDescAndValueList &outDescList, CRegisteredString inAttStrName, - float &inValue); - void AddLongAttribute(TPropertyDescAndValueList &outDescList, CRegisteredString inAttStrName, - qt3ds::QT3DSI32 &inValue); - void AddBoolAttribute(TPropertyDescAndValueList &outDescList, CRegisteredString inAttStrName, - bool &inValue); - void AddFloat2Attribute(TPropertyDescAndValueList &outDescList, - CRegisteredString *inAttStrNames, qt3dsdm::SFloat2 &inValue); - void AddFloat3Attribute(TPropertyDescAndValueList &outDescList, - ERuntimeAdditionalMetaDataType inAdditionalType, - CRegisteredString *inAttStrNames, qt3dsdm::SFloat3 &inValue); - void AddStringAttribute(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, const char *inValue); - void AddElementRefAttribute(TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, SElement *inElement); - - void AddSourcePath(const char *inValue) - { - if (m_SourcePathSet.find(inValue) == m_SourcePathSet.end()) { - m_SourcePathSet.insert(inValue); - m_SourcePathList.push_back(eastl::string(inValue)); - } - } - -public: // - void release() override { delete this; } - - //============================================================================== - // Friends - //============================================================================== - friend class CUIPParserActionHelper; -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserObjectRefHelper.h b/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserObjectRefHelper.h deleted file mode 100644 index fcd16985..00000000 --- a/src/Runtime/Source/UIPParser/Include/Qt3DSUIPParserObjectRefHelper.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSUIPParser.h" -#include "Qt3DSUIPParserImpl.h" - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * @class CUIPParserObjectRefHelper - * @brief Class for parsing UIP file - Object Reference Helper - */ -class CUIPParserObjectRefHelper -{ - typedef qt3ds::foundation::CRegisteredString TStrType; - -public: - typedef eastl::hash_map TStrToStrMap; - - /// Tree structure to cache scene graph information. This is used to resolve relative object - /// reference - struct SGraphNode - { - typedef eastl::vector TGraphNodeList; - - TStrType m_Id; // node id - TStrType m_Name; // name of the node. the name can be default from metadata, specified in - // graph section, or specified in logic section. - TStrType m_Type; // for example: Layer, Camera, Model - TStrType - m_Class; // class id. usually used by Behavior or objects that have custom properties. - void *m_ReaderContext; // Context to warp back to this node. - void *m_MasterSlide; - SGraphNode *m_Parent; - TGraphNodeList m_Children; - SGraphNode() - : m_ReaderContext(NULL) - , m_MasterSlide(NULL) - , m_Parent(NULL) - { - } - }; - //============================================================================== - // Fields - //============================================================================== -private: - typedef eastl::hash_set TImageNamePropertyList; - IRuntimeMetaData &m_MetaData; ///< Reference to Metadata - typedef eastl::hash_map TGraphNodeMap; - SGraphNode *m_RootNode; - TGraphNodeMap m_GraphNodeMap; - TImageNamePropertyList m_SlideIdSet; - - // List of Image property names, for example diffusemap, normalmap, etc - // This is to handle material and images. Material's Image properties point to instances. - TImageNamePropertyList m_ImageNamePropertyList; - TStrType m_MaterialStr; - eastl::vector m_SceneGraphAliasList; - - typedef eastl::pair TLightProbeAndNamePair; - typedef eastl::map TLightProbeIdToNameMap; - TLightProbeIdToNameMap m_LayerImageIdToNameMap; - //============================================================================== - // Methods - //============================================================================== -public: // Construction - CUIPParserObjectRefHelper(IRuntimeMetaData &inMetaData); - virtual ~CUIPParserObjectRefHelper(); - - void CacheGraph(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter); - SGraphNode *GetNode(const char *inId); - SGraphNode *GetNode(eastl::string inId); - TStrType GetName(const eastl::string &inId); // return the node name given the node id - TStrType GetType(const eastl::string &inId); // return the node type given the node id - TStrType GetClass(const eastl::string &inId); // return the node class given the node id - - TStrType ParseObjectRefId(const eastl::string &inObjectPath, const char8_t *inOwnerId); - eastl::string BuildReferenceString(eastl::string inObjectPath); - void MarkAllReferencedAttributes(eastl::string inId, - const eastl::vector &inReferences, - qt3dsdm::IDOMReader &inReader, - SParseElementManager &outIdAttributesMap); - -private: - void CacheSceneGraph(qt3dsdm::IDOMReader &inReader, SGraphNode *inParent = NULL); - SGraphNode &CacheSceneGraphNode(qt3dsdm::IDOMReader &inReader, SGraphNode *inParent = NULL); - void CacheStateGraph(qt3dsdm::IDOMReader &inReader); - - void CopySceneGraph(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter, - qt3dsdm::IDOMWriter &inSlideWriter, TStrToStrMap &inMap, - const char *inAliasName, const char *inAliasId, SGraphNode &inParent); - void CopyStates(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inSlideWriter, - TStrToStrMap &inMap, const char *inAliasName, const char *inAliasId); - void CopyAttributes(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inSlideWriter, - TStrToStrMap &inMap, const char *inAliasName, const char *inAliasId); - void CopyHierarchy(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inSlideWriter, - TStrToStrMap &inMap, const char *inAliasName, const char *inAliasId); - void CopyStateCommands(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter, - TStrToStrMap &oldToNewIdMap, const char *inAliasName, - const char *inOldId, const char *inNewId); - // Helper method for Preseve Attributes - SGraphNode *GetReferenceNode(SGraphNode *inInstance, eastl::string &inAssetName, - eastl::vector &outInstanceList, - qt3dsdm::IDOMReader &inReader); - bool MarkAttributeAsReferenced(SGraphNode *inBaseInstance, - eastl::vector &inInstanceList, - eastl::string &inAttributeName, qt3dsdm::IDOMReader &inReader, - SParseElementManager &outIdAttributesMap); - void MarkPreserveFlag(SGraphNode *inInstance, eastl::string inProperty, - SParseElementManager &outIdAttributesMap); - eastl::pair - ProcessAliasAttribute(const char8_t *inObjId, - eastl::pair inAttribute, - eastl::string &ioStrBuilder, TStrToStrMap &inMap); - - eastl::string BuildAbsoluteReferenceString(eastl::string inId); - eastl::string BuildAbsoluteReferenceString(SGraphNode *inNode); - - // Special case for material and images. Material's Image properties point to instances. - void BuildImageNamePropertyList(); -}; - -} // namespace Q3DStudio diff --git a/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserActionHelper.cpp b/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserActionHelper.cpp deleted file mode 100644 index ab6d751d..00000000 --- a/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserActionHelper.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" -#ifdef EA_PLATFORM_WINDOWS -#pragma warning(disable : 4396) // specializer warning nonsense -#endif - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSUIPParserActionHelper.h" -#include "Qt3DSUIPParserObjectRefHelper.h" -#include "Qt3DSIPresentation.h" -#include "Qt3DSCommandEventTypes.h" - -#include "Qt3DSDMPrefix.h" -#include "Qt3DSDMXML.h" -#include "Qt3DSDMWStrOpsImpl.h" -#include "Qt3DSMetadata.h" -#include "Qt3DSEulerAngles.h" -#include "Qt3DSLogicSystem.h" -#include "Qt3DSParametersSystem.h" - -using namespace qt3dsdm; - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -/** - * Constructor - */ -CUIPParserActionHelper::CUIPParserActionHelper(CUIPParserImpl *inUIPParser, - CUIPParserObjectRefHelper *inObjRefHelper, - IRuntimeMetaData &inMetaData) - : m_UIPParser(inUIPParser) - , m_ObjRefHelper(inObjRefHelper) - , m_MetaData(inMetaData) -{ -} - -//============================================================================== -/** - * Destructor - */ -CUIPParserActionHelper::~CUIPParserActionHelper() -{ -} - -void CUIPParserActionHelper::CacheAction(qt3dsdm::IDOMReader &inReader, - const char8_t *inActionOwnerId) -{ - if (IsTrivial(inActionOwnerId)) - return; - - IDOMReader::Scope __childScope(inReader); - - const char *theRef; - if (inReader.Att("ref", theRef)) { - // Ignore "ref" because we are only interested in new actions - return; - } - - // Parse the action - SActionInfo theAction; - inReader.Att("id", theAction.m_Id); - theAction.m_Owner = inActionOwnerId; - - const char *tempStr; - if (inReader.Att("triggerObject", tempStr)) - theAction.m_TriggerObject = m_UIPParser->ParseObjectRefId(tempStr, inActionOwnerId); - inReader.Att("event", theAction.m_Event); - if (inReader.Att("targetObject", tempStr)) - theAction.m_TargetObject = m_UIPParser->ParseObjectRefId(tempStr, inActionOwnerId); - if (inReader.Att("handler", tempStr)) { - theAction.m_Handler = tempStr; - CacheHandlerArguments(inReader, theAction); - } - - // Only proceeds if we can find the elements - if (theAction.m_TargetObject.empty() || theAction.m_TriggerObject.empty() - || theAction.m_Owner.empty()) { - qCWarning(qt3ds::INVALID_OPERATION) << "Action invalid, id: " << theAction.m_Id.c_str(); - return; - } - - m_ActionMap[theAction.m_Id] = theAction; - - // Build up logic tables to be processed by BuildAction later - // There are 2 tables involved: - // 1. The Listener-To-Events tables - multimap of each listener to all events it is listening to - // 2. The Listener-Event-To-Actions table - multimap of each listener-event pair to all actions - // it triggers - // note: The struct for Action is a pair of EventAction node and its owner - AddListenerEventPair(theAction.m_TriggerObject, theAction.m_Event); - - SListenerEventNamePair theListenerEventPair(theAction.m_TriggerObject, theAction.m_Event); - TEventActionOwnerPair theLogicOwnerPair(theAction.m_Id, theAction.m_Owner); - m_ListenerEventActionsMap.insert(eastl::make_pair(theListenerEventPair, theLogicOwnerPair)); -} - -void CUIPParserActionHelper::AddListenerEventPair(eastl::string inListener, - const eastl::string &inEventName) -{ - // Check for dupes - TListenerEventsNameMap::iterator theStartItr = m_ListenerEventsNameMap.lower_bound(inListener); - TListenerEventsNameMap::iterator theEndItr = m_ListenerEventsNameMap.upper_bound(inListener); - for (; theStartItr != theEndItr; ++theStartItr) { - if (theStartItr->second == inEventName) - return; - } - - m_ListenerEventsNameMap.insert(eastl::make_pair(inListener, inEventName)); -} - -void CUIPParserActionHelper::CacheHandlerArguments(qt3dsdm::IDOMReader &inReader, - SActionInfo &inAction) -{ - IDOMReader::Scope __handlerArgScope(inReader); - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - SHandlerArgumentInfo theArg; - inReader.Att("name", theArg.m_Name); - inReader.Att("value", theArg.m_Value); - inAction.m_HandlerArgs.push_back(theArg); - } - if (inAction.m_Handler == "Set Property") { - SHandlerArgumentInfo theHandlerArg1 = inAction.m_HandlerArgs[0]; - SElementData *targetData = m_UIPParser->GetElementData(inAction.m_TargetObject.c_str()); - if (targetData && !theHandlerArg1.m_Value.empty()) { - m_UIPParser->m_ParseElementManager.MarkAttributeAsReferenced( - *targetData, theHandlerArg1.m_Value.c_str()); - } - } -} - -SElement *CUIPParserActionHelper::GetElement(const eastl::string &inElementName) -{ - return m_UIPParser->GetElement(inElementName.c_str()); -} - -void CUIPParserActionHelper::GetActionSectionCount( - CUIPParserImpl::SActionSectionCount &outActionCount) -{ - // There are 2 tables involved: - // 1. The Listener-To-Events tables - multimap of each listener to all events it is listening to - // 2. The Listener-Event-To-Actions table - multimap of each listener-event pair to all actions - // it triggers - // note: The struct for Action is a pair of EventAction node and its owner - - // Get the count to reserve - // Iterate through each listener - for (TListenerEventsNameMap::iterator theListenerItr = m_ListenerEventsNameMap.begin(); - theListenerItr != m_ListenerEventsNameMap.end();) { - ++outActionCount.m_TriggerElementCount; - - INT32 theEventCount = - static_cast(m_ListenerEventsNameMap.count(theListenerItr->first)); - for (INT32 theEventCounter = 0; theEventCounter < theEventCount; - ++theEventCounter, ++theListenerItr) { - ++outActionCount.m_TriggerEventCount; - - // iterate through each listener-event pair - SListenerEventNamePair thePair(theListenerItr->first, theListenerItr->second); - TListenerEventActionsMap::iterator theActionsItr = - m_ListenerEventActionsMap.lower_bound(thePair); - INT32 theActionCount = static_cast(m_ListenerEventActionsMap.count(thePair)); - for (INT32 theActionCounter = 0; theActionCounter < theActionCount; - ++theActionCounter) { - eastl::string theActionId = theActionsItr->second.first; - outActionCount.m_ActionCount += - GetActionCount(theActionId, outActionCount.m_StringAttrCount, - outActionCount.m_CustomParamCount); - ++theActionsItr; - } - } - } -} - -void CUIPParserActionHelper::BuildActions(IPresentation &inPresentation) -{ - // Now we start building - // Iterate through each listener - for (TListenerEventsNameMap::iterator theListenerItr = m_ListenerEventsNameMap.begin(); - theListenerItr != m_ListenerEventsNameMap.end();) { - TElement *theElement = GetElement(theListenerItr->first); - - INT32 theEventCount = - static_cast(m_ListenerEventsNameMap.count(theListenerItr->first)); - for (INT32 theEventCounter = 0; theEventCounter < theEventCount; - ++theEventCounter, ++theListenerItr) { - UINT32 theEventName = - CHash::HashEventCommand(theListenerItr->second.c_str()); // UINT32: HashedName - - // iterate through each listener-event pair - SListenerEventNamePair thePair(theListenerItr->first, theListenerItr->second); - TListenerEventActionsMap::iterator theActionsItr = - m_ListenerEventActionsMap.lower_bound(thePair); - INT32 theActionCount = static_cast(m_ListenerEventActionsMap.count(thePair)); - for (INT32 theActionCounter = 0; theActionCounter < theActionCount; - ++theActionCounter) { - eastl::string theActionId = theActionsItr->second.first; - if (theElement) - BuildAction(*theElement, theEventName, inPresentation, theActionId); - ++theActionsItr; - } - } - } -} - -union UTypeConverter { - SAttributeKey m_Key; - INT32 m_IntData; -}; - -struct SActionAdder -{ - ILogicSystem &m_LogicSystem; - TElement &m_EventElement; - UINT32 m_EventName; - TElement *m_Owner; - TElement *m_Target; - - SActionAdder(ILogicSystem &inLogicSystem, TElement &inEventElement, UINT32 inEventName, - TElement *inOwner, TElement *inTarget) - : m_LogicSystem(inLogicSystem) - , m_EventElement(inEventElement) - , m_EventName(inEventName) - , m_Owner(inOwner) - , m_Target(inTarget) - { - } - - INT32 AddAction(TEventCommandHash inCommand, UINT32 inArg1 = 0, UINT32 inArg2 = 0) - { - UVariant arg1Var; - UVariant arg2Var; - arg1Var.m_INT32 = (INT32)inArg1; - arg2Var.m_INT32 = (INT32)inArg2; - return m_LogicSystem.AddAction(m_EventElement, m_EventName, m_Target, m_Owner, inCommand, - arg1Var, arg2Var, true); - } -}; - -void CUIPParserActionHelper::BuildAction(TElement &inElement, UINT32 inEventName, - IPresentation &inPresentation, - const eastl::string &inActionId) -{ - ILogicSystem &theLogicBuilder = inPresentation.GetLogicSystem(); - IParametersSystem &theParamSystem = inPresentation.GetParametersSystem(); - TActionMap::iterator theIter = m_ActionMap.find(inActionId); - if (theIter == m_ActionMap.end()) { - Q3DStudio_ASSERT(false); - qCWarning(qt3ds::INVALID_OPERATION) << "Can't find action, id: " << inActionId.c_str(); - return; - } - - SActionInfo theAction = theIter->second; - INT32 theAddActionIndex = -1; // the index of newly added action. If there are more than 1 - // actions, the index points to the firstly added action. - SActionAdder theAdder(theLogicBuilder, inElement, inEventName, GetElement(theAction.m_Owner), - GetElement(theAction.m_TargetObject)); - - // The list of applicable handler is loaded from metadata xml file (if it is non-custom handler) - bool theIsCustomHandler = IsCustomHandler(theAction); - - if (theIsCustomHandler) { - // Argument 1 - param table start index - INT32 paramGroup = theParamSystem.CreateParameterGroup(); - - // First param is the handler name we want to invoke for the custom action. - ExportCustomActionParameters(inPresentation, theParamSystem, paramGroup, - theAction.m_Handler.c_str(), ERuntimeDataModelDataTypeString, - ERuntimeAdditionalMetaDataTypeNone); - - int theHandlerArgumentCount = theAction.m_HandlerArgs.size(); - ERuntimeDataModelDataType theType; - ERuntimeAdditionalMetaDataType theAdditionalType; - // Actual handler parameters to pass in. - for (int theIndex = 0; theIndex < theHandlerArgumentCount; ++theIndex) { - GetHandlerArgumentType(theAction, theIndex, theType, theAdditionalType); - ExportCustomActionParameters(inPresentation, theParamSystem, paramGroup, - theAction.m_HandlerArgs[theIndex].m_Value.c_str(), theType, - theAdditionalType); - } - theAddActionIndex = theAdder.AddAction(COMMAND_CUSTOMACTION, (UINT32)paramGroup); - } else if (theAction.m_Handler == "Set Property") // Plain set action - { - // ArgumentOne - HashPropertyName - // ArgumentTwo - Value - SHandlerArgumentInfo theHandlerArg1 = theAction.m_HandlerArgs[0]; - SHandlerArgumentInfo theHandlerArg2 = theAction.m_HandlerArgs[1]; - - eastl::string thePropertyName = theHandlerArg1.m_Value; - SElementData *theTargetObject = - m_UIPParser->GetElementData(theAction.m_TargetObject.c_str()); - if (theTargetObject) { - SElementPropertyInfo *theProperty = m_UIPParser->m_ParseElementManager.FindProperty( - *theTargetObject, thePropertyName.c_str()); - if (theProperty) { - TPropertyDescAndValueList theProperties; - ERuntimeDataModelDataType theType = theProperty->m_DataType; - ERuntimeAdditionalMetaDataType theAdditionalType = theProperty->m_AdditionalType; - - m_UIPParser->GetAttributeList(inPresentation, theProperties, theType, - theAdditionalType, thePropertyName.c_str(), - theHandlerArg2.m_Value.c_str(), - theProperty->m_PropertyNames); - - UINT32 theActionCount = theProperties.size(); - Q3DStudio_ASSERT(theActionCount > 0); - for (UINT32 theActionIndex = 0; theActionIndex < theActionCount; ++theActionIndex) { - INT32 actionId = theAdder.AddAction( - COMMAND_SETPROPERTY, theProperties[theActionIndex].first.GetNameHash(), - theProperties[theActionIndex].second.m_INT32); - if (theActionIndex == 0) - theAddActionIndex = actionId; - } - } - } - } else if (theAction.m_Handler == "Fire Event") // Fire the selected event on the element - { - theAddActionIndex = theAdder.AddAction( - COMMAND_FIREEVENT, CHash::HashEventCommand(theAction.m_HandlerArgs[0].m_Value.c_str())); - } else if (theAction.m_Handler == "Go to Slide") // Switch slides - { - theAddActionIndex = theAdder.AddAction( - COMMAND_GOTOSLIDENAME, CHash::HashString(theAction.m_HandlerArgs[0].m_Value.c_str())); - } else if (theAction.m_Handler == "Next Slide") // Switch slides - { - theAddActionIndex = theAdder.AddAction(COMMAND_GOTONEXTSLIDE); - } else if (theAction.m_Handler == "Previous Slide") // Switch slides - { - theAddActionIndex = theAdder.AddAction(COMMAND_GOTOPREVIOUSSLIDE); - } else if (theAction.m_Handler == "Preceding Slide") // Switch slides - { - theAddActionIndex = theAdder.AddAction(COMMAND_BACKSLIDE); - } else if (theAction.m_Handler == "Play") // Play - { - theAddActionIndex = theAdder.AddAction(COMMAND_PLAY); - } else if (theAction.m_Handler == "Pause") // Pause - { - theAddActionIndex = theAdder.AddAction(COMMAND_PAUSE); - } else if (theAction.m_Handler == "Go to Time") // Goto Time - { - float theTime = 0; - const char *theValue = theAction.m_HandlerArgs[0].m_Value.c_str(); - if (!IsTrivial(theValue)) - WStrOps().StrTo(theValue, theTime); - - theAddActionIndex = - theAdder.AddAction(COMMAND_GOTOTIME, static_cast(theTime * 1000.0f)); - - bool thePause = false; - theValue = theAction.m_HandlerArgs[1].m_Value.c_str(); - if (!IsTrivial(theValue)) - WStrOps().StrTo(theValue, thePause); - theAdder.AddAction(thePause ? COMMAND_PAUSE : COMMAND_PLAY); - } else if (theAction.m_Handler == "Emit Signal") // Emit a signal - { - qt3ds::foundation::CStringHandle theStringHandle; - if (!theAction.m_HandlerArgs[0].m_Value.empty()) { - const char *theValue = theAction.m_HandlerArgs[0].m_Value.c_str(); - theStringHandle = inPresentation.GetStringTable().GetHandle(theValue); - } - theAddActionIndex = theAdder.AddAction(COMMAND_EMITSIGNAL, theStringHandle.handle()); - } else { - Q3DStudio_ASSERT(false); // what sort of crazy action is this? - } - - if (theAddActionIndex > -1) - m_ActionIdentifierMap[theAction.m_Id] = theAddActionIndex; -} - -INT32 CUIPParserActionHelper::GetActionCount(const eastl::string &inActionId) -{ - INT32 theStringAttrCount = 0; - INT32 theCustomParamCount = 0; - return GetActionCount(inActionId, theStringAttrCount, theCustomParamCount); -} - -INT32 CUIPParserActionHelper::GetActionCount(const eastl::string &inActionId, - INT32 &outStringAttrCount, INT32 &outCustomParamCount) -{ - INT32 theActionCount = 0; - - TActionMap::iterator theIter = m_ActionMap.find(inActionId); - if (theIter == m_ActionMap.end()) { - Q3DStudio_ASSERT(false); - qCWarning(qt3ds::INVALID_OPERATION) << "Can't find action, id: " << inActionId.c_str(); - return theActionCount; - } - - SActionInfo theAction = theIter->second; - - // The list of applicable handler is loaded from metadata xml file (if it is non-custom handler) - bool theIsCustomHandler = IsCustomHandler(theAction); - - if (theIsCustomHandler) { - theActionCount = 1; - - // First param is the handler name we want to invoke for the custom action. - ++outStringAttrCount; - ++outCustomParamCount; - - int theHandlerArgumentCount = theAction.m_HandlerArgs.size(); - ERuntimeDataModelDataType theType; - ERuntimeAdditionalMetaDataType theAdditionalType; - // Actual handler parameters to pass in. - for (int theIndex = 0; theIndex < theHandlerArgumentCount; ++theIndex) { - GetHandlerArgumentType(theAction, theIndex, theType, theAdditionalType); - GetCustomActionParametersCount(theType, theAdditionalType, outStringAttrCount, - outCustomParamCount); - } - } - - else if (theAction.m_Handler == "Set Property") // Plain set action - { - SHandlerArgumentInfo theHandlerArg1 = theAction.m_HandlerArgs[0]; - - eastl::string thePropertyName = theHandlerArg1.m_Value; - SElementData *theData = m_UIPParser->GetElementData(theAction.m_TargetObject.c_str()); - if (theData) { - SElementPropertyInfo *thePropertyInfo = - m_UIPParser->m_ParseElementManager.GetOrCreateProperty(*theData, - thePropertyName.c_str()); - if (thePropertyInfo) { - theActionCount = thePropertyInfo->m_Arity; - if (m_UIPParser->IsStringType(thePropertyInfo->m_DataType)) - ++outStringAttrCount; - } - } - } - - else if (theAction.m_Handler == "Fire Event" // Fire the selected event on the element - || theAction.m_Handler == "Go to Slide" // Switch slides - || theAction.m_Handler == "Next Slide" // Switch slides - || theAction.m_Handler == "Previous Slide" // Switch slides - || theAction.m_Handler == "Preceding Slide" // Switch slides - || theAction.m_Handler == "Play" // Play - || theAction.m_Handler == "Pause" // Pause - ) { - theActionCount = 1; - } - - else if (theAction.m_Handler == "Go to Time") // Goto Time - { - theActionCount = 2; - } else if (theAction.m_Handler == "Play Sound") // Play Sound - { - theActionCount = 1; - ++outStringAttrCount; - } else if (theAction.m_Handler == "Emit Signal") // Emit Signal - { - theActionCount = 1; - ++outStringAttrCount; - } else { - Q3DStudio_ASSERT(false); // what sort of crazy action is this? - } - - return theActionCount; -} - -INT32 CUIPParserActionHelper::GetActionIndex(const eastl::string &inActionId) -{ - TActionIdentifierMap::iterator theFind = m_ActionIdentifierMap.find(inActionId); - if (theFind != m_ActionIdentifierMap.end()) - return theFind->second; - Q3DStudio_ASSERT(false); - return -1; -} - -bool CUIPParserActionHelper::IsCustomHandler(const SActionInfo &inAction) -{ - const char *theClass = m_ObjRefHelper->GetClass(inAction.m_TargetObject); - if (!IsTrivial(theClass)) - return m_MetaData.IsCustomHandler(theClass, inAction.m_Handler.c_str()); - return false; -} - -void CUIPParserActionHelper::GetHandlerArgumentType( - const SActionInfo &inAction, int inArgumentIndex, ERuntimeDataModelDataType &outType, - ERuntimeAdditionalMetaDataType &outAdditionalType) -{ - const char *theClass = m_ObjRefHelper->GetClass(inAction.m_TargetObject); - return m_MetaData.GetHandlerArgumentType(theClass, inAction.m_Handler.c_str(), - inAction.m_HandlerArgs[inArgumentIndex].m_Name.c_str(), - outType, outAdditionalType); -} - -void CUIPParserActionHelper::GetCustomActionParametersCount( - ERuntimeDataModelDataType inDataType, ERuntimeAdditionalMetaDataType inAdditionalType, - INT32 &outStringAttrCount, INT32 &outCustomParamCount) -{ - // This function should match ExportCustomActionParameters - switch (inDataType) { - case ERuntimeDataModelDataTypeFloat: - case ERuntimeDataModelDataTypeLong: - case ERuntimeDataModelDataTypeBool: { - outCustomParamCount += 1; - break; - } - case ERuntimeDataModelDataTypeFloat2: { - outCustomParamCount += 2; - break; - } - case ERuntimeDataModelDataTypeFloat3: { - if (inAdditionalType == ERuntimeAdditionalMetaDataTypeColor) { - // Append rgba - outCustomParamCount += 4; - } else { - // Append xyz - outCustomParamCount += 3; - } - break; - } - // default to string - default: { - outCustomParamCount += 1; - outStringAttrCount += 1; - } - } -} - -namespace { - - using qt3ds::foundation::IStringTable; - - struct SCustomParameterParseInfoFloat - { - typedef float TParseType; - static const char8_t *Name() { return "float"; } - static TParseType Default() { return 0; } - static Q3DStudio::UVariant ToVariant(const TParseType &inParseType) - { - Q3DStudio::UVariant retval; - retval.m_FLOAT = inParseType; - return retval; - } - }; - - struct SCustomParameterParseInfoLong - { - typedef QT3DSI32 TParseType; - static const char8_t *Name() { return "long"; } - static TParseType Default() { return 0; } - static Q3DStudio::UVariant ToVariant(const TParseType &inParseType) - { - Q3DStudio::UVariant retval; - retval.m_FLOAT = static_cast(inParseType); - return retval; - } - }; - - struct SCustomParameterParseInfoBool - { - typedef bool TParseType; - static const char8_t *Name() { return "bool"; } - static TParseType Default() { return false; } - static Q3DStudio::UVariant ToVariant(const TParseType &inParseType) - { - Q3DStudio::UVariant retval; - retval.m_FLOAT = static_cast(inParseType); - return retval; - } - }; - - struct SCustomParameterParseInfoFloat2 - { - typedef SFloat2 TParseType; - static const char8_t *Name() { return "float2"; } - static TParseType Default() { return SFloat2(0, 0); } - static QT3DSU32 NumParameters() { return 2; } - static Q3DStudio::UVariant ToVariant(QT3DSU32 inIdx, const TParseType &inParseType) - { - Q3DStudio::UVariant retval; - retval.m_FLOAT = static_cast(inParseType[inIdx]); - return retval; - } - }; - - struct SCustomParameterParseInfoFloat3 - { - typedef SFloat3 TParseType; - static const char8_t *Name() { return "float3"; } - static const char8_t **Extensions() - { - static const char8_t *retval[] = { ".x", ".y", ".z", NULL }; - return retval; - } - static TParseType Default() { return SFloat3(0, 0, 0); } - static QT3DSU32 NumParameters() { return 3; } - static Q3DStudio::UVariant ToVariant(QT3DSU32 inIdx, const TParseType &inParseType) - { - Q3DStudio::UVariant retval; - retval.m_FLOAT = static_cast(inParseType[inIdx]); - return retval; - } - }; - - struct SCustomParameterParseInfoColor - { - typedef SFloat3 TParseType; - static const char8_t *Name() { return "color4"; } - static TParseType Default() { return SFloat3(0, 0, 0); } - static QT3DSU32 NumParameters() { return 4; } - static Q3DStudio::UVariant ToVariant(QT3DSU32 inIdx, const TParseType &inParseType) - { - if (inIdx < 3) { - Q3DStudio::UVariant retval; - retval.m_FLOAT = static_cast(inParseType[inIdx]) * 255.0f; - return retval; - } else { - Q3DStudio::UVariant retval; - retval.m_FLOAT = 255.0f; - return retval; - } - } - }; - - template - struct ParseParameter - { - void operator()(WCharTReader &inReader, const char *inValue, IParametersSystem &inSystem, - QT3DSI32 inGroupId) - { - typename TParseInfo::TParseType theValue = TParseInfo::Default(); - if (!IsTrivial(inValue)) - inReader.Read(theValue); - Q3DStudio::UVariant theVarValue = TParseInfo::ToVariant(theValue); - inSystem.AddParameter(inGroupId, CHash::HashString(TParseInfo::Name()), theVarValue); - } - }; - - template - struct ParseAggregateParameter - { - void operator()(WCharTReader &inReader, const char *inValue, IParametersSystem &inSystem, - QT3DSI32 inGroupId) - { - typename TParseInfo::TParseType theValue = TParseInfo::Default(); - if (!IsTrivial(inValue)) - inReader.ReadRef(NVDataRef(&theValue[0], TParseInfo::NumParameters())); - - for (QT3DSU32 idx = 0, end = TParseInfo::NumParameters(); idx < end; ++idx) { - Q3DStudio::UVariant theVarValue = TParseInfo::ToVariant(idx, theValue); - inSystem.AddParameter(inGroupId, CHash::HashString(TParseInfo::Name()), - theVarValue); - } - } - }; -} - -void CUIPParserActionHelper::ExportCustomActionParameters( - IPresentation &inPresentation, IParametersSystem &inParamSystem, QT3DSI32 inParamGroupId, - const char *inValue, ERuntimeDataModelDataType inDataType, - ERuntimeAdditionalMetaDataType inAdditionalType) -{ - // Create a destructible value - m_UIPParser->m_ValueBuffer.clear(); - m_UIPParser->m_ValueBuffer.write(inValue, (QT3DSU32)strlen(inValue) + 1); - // Clear the destination buffer - m_UIPParser->m_TempBuffer.clear(); - WCharTReader theReader((char8_t *)m_UIPParser->m_ValueBuffer.begin(), m_UIPParser->m_TempBuffer, - *m_UIPParser->GetDOMReader().GetStringTable()); - - // The function should match CUIPParserActionHelper::GetCustomActionParametersCount - switch (inDataType) { - case ERuntimeDataModelDataTypeFloat: { - ParseParameter()(theReader, inValue, inParamSystem, - inParamGroupId); - break; - } - case ERuntimeDataModelDataTypeLong: { - ParseParameter()(theReader, inValue, inParamSystem, - inParamGroupId); - break; - } - case ERuntimeDataModelDataTypeBool: { - ParseParameter()(theReader, inValue, inParamSystem, - inParamGroupId); - break; - } - case ERuntimeDataModelDataTypeFloat2: { - ParseAggregateParameter()(theReader, inValue, - inParamSystem, inParamGroupId); - break; - } - case ERuntimeDataModelDataTypeFloat3: { - if (inAdditionalType == ERuntimeAdditionalMetaDataTypeColor) { - ParseAggregateParameter()( - theReader, inValue, inParamSystem, inParamGroupId); - } else { - ParseAggregateParameter()( - theReader, inValue, inParamSystem, inParamGroupId); - } - break; - } - // default to string - default: { - UVariant theValue; - theValue.m_StringHandle = inPresentation.GetStringTable().GetHandle(inValue); - inParamSystem.AddParameter(inParamGroupId, CHash::HashString("string"), theValue); - break; - } - } -} -} diff --git a/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp b/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp deleted file mode 100644 index a9c581aa..00000000 --- a/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp +++ /dev/null @@ -1,2587 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" -#ifdef EA_PLATFORM_WINDOWS -#pragma warning(disable : 4396) // specializer warning nonsense -#endif - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSIPresentation.h" -#include "Qt3DSIScriptBridge.h" -#include "Qt3DSAttributeHashes.h" -#include "Qt3DSCommandEventTypes.h" -#include "Qt3DSDMPrefix.h" -#include "Qt3DSDMComposerTypeDefinitions.h" -#include "Qt3DSDMWStrOpsImpl.h" -#include "Qt3DSUIPParserActionHelper.h" -#include "Qt3DSUIPParserObjectRefHelper.h" -#include "Qt3DSApplication.h" -#include "Qt3DSRuntimeFactory.h" -#include "Qt3DSSceneGraphDebugger.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSElementSystem.h" -#include "Qt3DSAnimationSystem.h" -#include "Qt3DSSlideSystem.h" - -using namespace qt3dsdm; - -#ifndef M_PI -#define M_PI 3.1415926535898 -#endif - -#define TODEG(x) x = (float)(x * 180 / M_PI); -#define TORAD(x) x = (float)(x / 180 * M_PI); - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -TStrType SParseElementManager::RegisterStr(const char8_t *inStr) -{ - return m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr(inStr); -} -SElementData &SParseElementManager::GetOrCreateElementData(const char8_t *inIdOrRef, - const char8_t *inElemType, - const char8_t *inElemClassId) -{ - if (inIdOrRef == NULL) - inIdOrRef = ""; - if (inIdOrRef[0] == '#') - ++inIdOrRef; - if (inElemClassId == NULL) - inElemClassId = ""; - if (inElemClassId[0] == '#') - ++inElemClassId; - if (inElemType == NULL) - inElemType = ""; - TStrType theStr = RegisterStr(inIdOrRef); - eastl::pair theInserter = - m_ElementMap.insert(eastl::make_pair(theStr, SElementData(theStr))); - SElementData &retval(theInserter.first->second); - if (theInserter.second) { - retval.m_Class = RegisterStr(inElemClassId); - retval.m_Type = RegisterStr(inElemType); - } - return retval; -} -SElementData *SParseElementManager::FindElementData(const char8_t *inIdOrRef) -{ - if (inIdOrRef == NULL) - inIdOrRef = ""; - if (inIdOrRef[0] == '#') - ++inIdOrRef; - TStrType theStr = RegisterStr(inIdOrRef); - TIdElementMap::iterator theIter = m_ElementMap.find(theStr); - if (theIter != m_ElementMap.end()) - return &theIter->second; - return NULL; -} -static void SetPropertyValueHash(eastl::string &inWorkspace, const char8_t *inExtension, - qt3ds::QT3DSU32 *&ioHashes, eastl::string::size_type originalSize, - CRegisteredString *&ioPropNames, - qt3ds::foundation::IStringTable &ioStringTable) -{ - if (inExtension && *inExtension) - inWorkspace.append(inExtension); - *ioHashes = Q3DStudio::CHash::HashAttribute(inWorkspace.c_str()); - *ioPropNames = ioStringTable.RegisterStr(inWorkspace.c_str()); - ++ioHashes; - ++ioPropNames; - inWorkspace.resize(originalSize); -} -static eastl::pair -SetupPropertyWorkspace(const char8_t *inPropName, eastl::string &ioWorkspace) -{ - qt3ds::QT3DSU32 outSubIndex = 0; - ioWorkspace.assign(inPropName ? inPropName : ""); - eastl::string::size_type thePeriodPos = ioWorkspace.find('.'); - if (thePeriodPos != eastl::string::npos) { - if (thePeriodPos < ioWorkspace.size() - 1) { - switch (ioWorkspace[thePeriodPos + 1]) { - default: - QT3DS_ASSERT(false); - case 'r': - case 'x': - break; - case 'g': - case 'y': - outSubIndex = 1; - break; - case 'b': - case 'z': - outSubIndex = 2; - break; - case 'a': - case 'w': - outSubIndex = 3; - break; - } - } - ioWorkspace.resize(thePeriodPos); - } - return eastl::make_pair(ioWorkspace.size(), outSubIndex); -} -SElementPropertyInfo *SParseElementManager::GetOrCreateProperty(SElementData &inData, - const char8_t *inPropertyName) -{ - SElementData &theData(inData); - SElementPropertyInfo *retvalPtr = FindProperty(inData, inPropertyName); - if (retvalPtr) - return retvalPtr; - - eastl::string::size_type thePeriodPos = - SetupPropertyWorkspace(inPropertyName, m_Workspace).first; - TStrType theStr = RegisterStr(m_Workspace.c_str()); - - if (m_MetaData.IsPropertyExist(inData.m_Type, theStr, inData.m_Class) == false) - return NULL; - - eastl::pair theInserter = - theData.m_PropertyMap.insert(eastl::make_pair(theStr, SElementPropertyInfo(theStr))); - SElementPropertyInfo &retval(theInserter.first->second); - if (theInserter.second) { - qt3ds::intrinsics::memZero(retval.m_PropertyHashes, sizeof(retval.m_PropertyHashes)); - qt3ds::QT3DSU32 *thePropHashes(retval.m_PropertyHashes); - CRegisteredString *thePropNames(retval.m_PropertyNames); - retval.m_DataType = m_MetaData.GetPropertyType(theData.m_Type, theStr, theData.m_Class); - retval.m_AdditionalType = - m_MetaData.GetAdditionalType(theData.m_Type, theStr, theData.m_Class); - if (retval.m_DataType != ERuntimeDataModelDataTypeNone) { - switch (retval.m_DataType) { - default: - retval.m_Arity = 1; - break; - case ERuntimeDataModelDataTypeFloat2: - retval.m_Arity = 2; - break; - case ERuntimeDataModelDataTypeFloat3: - retval.m_Arity = 3; - break; - } - if (retval.m_Arity > 1) { - if (retval.m_Arity == 2) { - SetPropertyValueHash(m_Workspace, ".x", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - SetPropertyValueHash(m_Workspace, ".y", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - } else { - if (m_MetaData.GetAdditionalType(theData.m_Type, theStr, theData.m_Class) - == ERuntimeAdditionalMetaDataTypeColor) { - SetPropertyValueHash(m_Workspace, ".r", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - SetPropertyValueHash(m_Workspace, ".g", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - SetPropertyValueHash(m_Workspace, ".b", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - } else { - SetPropertyValueHash(m_Workspace, ".x", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - SetPropertyValueHash(m_Workspace, ".y", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - SetPropertyValueHash(m_Workspace, ".z", thePropHashes, thePeriodPos, - thePropNames, m_StringTable); - } - } - } else { - retval.m_PropertyHashes[0] = Q3DStudio::CHash::HashAttribute(theStr.c_str()); - retval.m_PropertyNames[0] = m_StringTable.RegisterStr(m_Workspace.c_str()); - } - } - } - return &retval; -} - -SElementPropertyInfo *SParseElementManager::GetOrCreateProperty(const char8_t *inIdOrRef, - const char8_t *inElemType, - const char8_t *inElemClassId, - const char8_t *inPropertyName) -{ - return GetOrCreateProperty(GetOrCreateElementData(inIdOrRef, inElemType, inElemClassId), - inPropertyName); -} - -eastl::pair -SParseElementManager::FindPropertyWithSubIndex(SElementData &inElement, - const char8_t *inPropertyName) -{ - qt3ds::QT3DSU32 subIndex = SetupPropertyWorkspace(inPropertyName, m_Workspace).second; - TStrType theStr = RegisterStr(m_Workspace.c_str()); - TAttrMap::iterator theIter = inElement.m_PropertyMap.find(theStr); - SElementPropertyInfo *retval = NULL; - if (theIter != inElement.m_PropertyMap.end()) - retval = &theIter->second; - return eastl::make_pair(retval, subIndex); -} - -SElementPropertyInfo *SParseElementManager::FindProperty(SElementData &inElement, - const char8_t *inPropertyName) -{ - return FindPropertyWithSubIndex(inElement, inPropertyName).first; -} -SElementPropertyInfo *SParseElementManager::FindProperty(const char8_t *inIdOrRef, - const char8_t *inPropertyName) -{ - SElementData *theData(FindElementData(inIdOrRef)); - if (theData) - return FindProperty(*theData, inPropertyName); - return NULL; -} - -void SParseElementManager::MarkAttributeAsReferenced(SElementData &inElement, - const char8_t *inPropertyName) -{ - SElementPropertyInfo *theProp = GetOrCreateProperty(inElement, inPropertyName); - if (theProp) - theProp->m_ElementFlag = true; -} - -void SParseElementManager::MarkAttributeAsReferenced(const char8_t *inElement, - const char8_t *inPropertyName) -{ - SElementData *theData = FindElementData(inElement); - if (theData) - MarkAttributeAsReferenced(*theData, inPropertyName); -} - -void SParseElementManager::MarkAllAttributesAsReferenced(SElementData &inElement, - bool searchParent) -{ - m_PropertyList.clear(); - m_MetaData.GetInstanceProperties(inElement.m_Type, inElement.m_Class, m_PropertyList, - searchParent); - for (QT3DSU32 idx = 0, end = m_PropertyList.size(); idx < end; ++idx) - MarkAttributeAsReferenced(inElement, m_PropertyList[idx].c_str()); -} - -TStrType SParseSlideManager::RegisterId(const char8_t *inStr) -{ - if (!inStr) - inStr = ""; - if (*inStr == '#') - ++inStr; - return RegisterStr(inStr); -} - -SParseSlideManager::~SParseSlideManager() -{ - for (QT3DSU32 idx = 0, end = m_Animations.size(); idx < end; ++idx) - delete m_Animations[idx]; - m_Animations.clear(); -} - -SParseSlide &SParseSlideManager::GetOrCreateSlide(const char8_t *inSlideId, qt3ds::QT3DSI32 inSlideIndex) -{ - TStrType theSlideId(RegisterId(inSlideId)); - return m_SlideMap.insert(eastl::make_pair(theSlideId, SParseSlide(theSlideId, inSlideIndex))) - .first->second; -} - -SParseSlide *SParseSlideManager::FindSlide(const char8_t *inSlideId) -{ - TStrType theSlideId(RegisterId(inSlideId)); - TSlideIdToParseSlideMap::iterator theIter = m_SlideMap.find(theSlideId); - if (theIter != m_SlideMap.end()) - return &theIter->second; - return NULL; -} - -void SParseSlideManager::SetAnimationData(SParseSlide &inSlide, const char8_t *inInstanceId, - const char8_t *inPropertyName, - const char8_t *inKeyframeData, - SParseSlideAnimationTypes::Enum inType, bool inIsDynamic, - bool inIsActive) -{ - TStrType thePropertyName(RegisterStr(inPropertyName)); - SElementData *theElemData = m_ElementManager.FindElementData(inInstanceId); - if (theElemData == NULL) { - QT3DS_ASSERT(false); - return; - } - eastl::pair theProperty = - m_ElementManager.FindPropertyWithSubIndex(*theElemData, thePropertyName); - if (theProperty.first == NULL) { - QT3DS_ASSERT(false); - return; - } - qt3ds::QT3DSU32 thePropertyHash = theProperty.first->m_PropertyHashes[theProperty.second]; - // Parse the keyframe data into floating point numbers. - if (inKeyframeData == NULL) - inKeyframeData = ""; - m_KeyframeParseBuffer.clear(); - m_KeyframeParseBuffer.assign(inKeyframeData); - m_KeyframeParseFloatBuffer.clear(); - char8_t *theBufData = const_cast(m_KeyframeParseBuffer.c_str()); - - char8_t *theStartPtr = qt3dsdm::FindNextNonWhitespace(theBufData); - while (theStartPtr && *theStartPtr) { - char8_t *nextPtr = qt3dsdm::FindNextWhitespace(theStartPtr); - if (nextPtr && *nextPtr) - *nextPtr = 0; - else - nextPtr = NULL; - QT3DSF32 temp; - WStrOps().StrTo(theStartPtr, temp); - m_KeyframeParseFloatBuffer.push_back(temp); - theStartPtr = nextPtr; - if (theStartPtr) - theStartPtr = FindNextNonWhitespace(theStartPtr + 1); - } - // Don't create animations with no keyframes. - if (m_KeyframeParseFloatBuffer.empty()) { - return; - } - - SParseSlideAnimationEntry *theEntry = - new SParseSlideAnimationEntry(inSlide.m_SlideId, theElemData->m_Id, thePropertyName, - thePropertyHash, inType, NULL, 0, inIsDynamic); - theEntry->m_KeyframeData = m_KeyframeParseFloatBuffer; - m_Animations.push_back(theEntry); - switch (inType) { - case SParseSlideAnimationTypes::Linear: - m_AnimationKeyframeCount += m_KeyframeParseFloatBuffer.size() / 2; - break; - case SParseSlideAnimationTypes::Bezier: - m_AnimationKeyframeCount += m_KeyframeParseFloatBuffer.size() / 6; - break; - default: - QT3DS_ASSERT(false); - break; - case SParseSlideAnimationTypes::EaseInOut: - m_AnimationKeyframeCount += m_KeyframeParseFloatBuffer.size() / 4; - break; - } - - ReferenceAnimation(inSlide, *theEntry, inIsActive); -} - -void SParseSlideManager::ReferenceAnimation(SParseSlide &inSlide, - const SParseSlideAnimationEntry &inSource, - bool inIsActive) -{ - TAnimationList &theList = - inSlide.m_Animations.insert(eastl::make_pair(inSource.m_InstanceId, TAnimationList())) - .first->second; - theList.push_back(SParseAnimationRef(inSlide.m_SlideId, inSource.m_InstanceId, - inSource.m_PropertyName, &inSource, inIsActive)); - m_SlideAnimationCount++; -} - -TAnimationList *SParseSlideManager::GetAnimationsForInstance(SParseSlide &inSlide, - const char8_t *inInstanceId) -{ - SElementData *theElemData = m_ElementManager.FindElementData(inInstanceId); - if (theElemData) { - TInstanceIdAnimationMap::iterator theAnimations = - inSlide.m_Animations.find(theElemData->m_Id); - if (theAnimations != inSlide.m_Animations.end()) - return &theAnimations->second; - } - return NULL; -} - -SParseSlideActionEntry &SParseSlideManager::GetOrCreateAction(SParseSlide &inSlide, - const char8_t *inActionId, - qt3ds::QT3DSI32 inActionCount, - bool inActive) -{ - TStrType theActionId(RegisterId(inActionId)); - SParseSlideActionEntry theAction(inSlide.m_SlideId, theActionId, inActionCount, inActive); - memZero(theAction.m_Actions, sizeof(theAction.m_Actions)); - TActionList::iterator theIter = - eastl::find(inSlide.m_ActionList.begin(), inSlide.m_ActionList.end(), theAction); - if (theIter != inSlide.m_ActionList.end()) - return *theIter; - inSlide.m_ActionList.push_back(theAction); - m_ActionCount += inActionCount; - return inSlide.m_ActionList.back(); -} - -SParseSlideActionEntry *SParseSlideManager::FindAction(SParseSlide &inSlide, - const char8_t *inActionId) -{ - TStrType theActionId(RegisterId(inActionId)); - SParseSlideActionEntry theAction(inSlide.m_SlideId, theActionId, 0, false); - TActionList::iterator theIter = - eastl::find(inSlide.m_ActionList.begin(), inSlide.m_ActionList.end(), theAction); - if (theIter != inSlide.m_ActionList.end()) - return &(*theIter); - return NULL; -} - -//============================================================================== -/** - * Constructor - * @param inFileName name of UIP file - */ -CUIPParserImpl::CUIPParserImpl(const QString &inFileName, IRuntimeMetaData &inMetaData, - IInputStreamFactory &inFactory, - qt3ds::foundation::IStringTable &inStringTable) - : m_MetaData(inMetaData) - , m_InputStreamFactory(inFactory) - , m_ParseElementManager(inMetaData, inStringTable) - , m_ParseSlideManager(inMetaData, m_ParseElementManager) -{ - // Setup DOMSerializer and DOMReader to read the file - std::shared_ptr theStrTable(inMetaData.GetStringTable()); - shared_ptr theFactory(qt3dsdm::IDOMFactory::CreateDOMFactory(theStrTable)); - TInputStreamPtr theInStream(inFactory.GetStreamForFile(inFileName)); - qt3dsdm::SDOMElement *topElement = NULL; - if (theInStream) - topElement = CDOMSerializer::Read(*theFactory, *theInStream); - if (!topElement) { - qCCritical(qt3ds::INVALID_OPERATION) - << "Could not open UIP file: " << inFileName.toLatin1().constData(); - } else { - eastl::pair, std::shared_ptr> theWriteReader = - IDOMWriter::CreateDOMWriter(theFactory, *topElement, theStrTable); - m_DOMWriter = theWriteReader.first; - m_DOMReader = theWriteReader.second; - if (!AreEqual(m_DOMReader->GetNarrowElementName(), "UIP")) { - qCCritical(qt3ds::INVALID_OPERATION) - << "Invalid UIP file: " << inFileName.toLatin1().constData(); - } - } - - // Create Helper class - m_ObjectRefHelper = new CUIPParserObjectRefHelper(m_MetaData); - m_ActionHelper = new CUIPParserActionHelper(this, m_ObjectRefHelper, m_MetaData); -} - -//============================================================================== -/** - * Destructor - */ -CUIPParserImpl::~CUIPParserImpl() -{ - // Delete Helper class - delete m_ObjectRefHelper; - m_ObjectRefHelper = NULL; - - delete m_ActionHelper; - m_ActionHelper = NULL; -} - -//============================================================================== -/** - * Load a presentation from a UIP file. - * @param inPresentation presentation written to - * @return a flag indicating whether or not we successfully loaded the file - */ -BOOL CUIPParserImpl::Load(IPresentation &inPresentation, - NVConstDataRef inStateReferences, - qt3ds::state::debugger::ISceneGraphRuntimeDebugger &debugger) -{ - m_CurrentPresentation = &inPresentation; - if (!m_DOMReader) { - qCCritical(qt3ds::INVALID_PARAMETER) << "CUIPParserImpl::Load, No DOM reader"; - return FALSE; - } - - BOOL theLoadResult = m_DOMReader->MoveToFirstChild("Project"); - - // Load project settings - if (theLoadResult) - theLoadResult &= LoadProjectSettings(inPresentation, *m_DOMReader); - - // First, we need to load the classes, because the class information will be stored in metadata - if (theLoadResult) - theLoadResult &= LoadClasses(inPresentation, *m_DOMReader); - - // Next is to cache the scene graph because we need the id-name information to resolve object - // reference - m_ObjectRefHelper->CacheGraph(*m_DOMReader, *m_DOMWriter); - - // Next is to cache the required attributes. This will be used to build Element - // We also need to cache the actions because we need to know the ActionCount to reserve the - // memory - { - IDOMReader::Scope __graphScope(*m_DOMReader); - m_DOMReader->MoveToFirstChild("Graph"); - CacheGraphRequiredAttributes(*m_DOMReader); - } - - { - IDOMReader::Scope __logicScope(*m_DOMReader); - m_DOMReader->MoveToFirstChild("Logic"); - { - - IDOMReader::Scope __stateScope(*m_DOMReader); - for (BOOL theSuccess = m_DOMReader->MoveToFirstChild("State"); theSuccess; - theSuccess = m_DOMReader->MoveToNextSibling("State")) { - IDOMReader::Scope __subSlideScope(*m_DOMReader); - if (theLoadResult) - theLoadResult &= CacheLogicRequiredAttributes(*m_DOMReader); - } - } - } - - // go through all the references and make sure the elements exist and if they do ensure the - // attributes are marked as referenced. - for (QT3DSU32 idx = 0, end = inStateReferences.size(); idx < end; ++idx) { - const SElementAttributeReference &reference = inStateReferences[idx]; - // All references are absolute, so the start node doesn't really matter. - CRegisteredString result = m_ObjectRefHelper->ParseObjectRefId(reference.m_Path, "Scene"); - if (result.IsValid() == false) { - qCCritical(INVALID_OPERATION, "Failed to resolve reference: %s", - reference.m_Path.c_str()); - } else { - m_ParseElementManager.MarkAttributeAsReferenced(result.c_str(), - reference.m_Attribute.c_str()); - } - } - - if (theLoadResult) - CacheClassRequiredAttributes(*m_DOMReader); - - ComputeAndReserveMemory(inPresentation, *m_DOMReader); - - // Now we are ready to load the scene graph - if (theLoadResult) - theLoadResult &= LoadGraph(inPresentation, *m_DOMReader); - if (theLoadResult) - theLoadResult &= LoadLogic(inPresentation, *m_DOMReader); - - if (theLoadResult) { - // Register all element ids with the debugger - eastl::vector elemMapBuffer; - for (TIdElementMap::iterator iter = m_ParseElementManager.m_ElementMap.begin(), - end = m_ParseElementManager.m_ElementMap.end(); - iter != end; ++iter) { - const SElementData &theData = iter->second; - if (theData.m_Element) { - qt3ds::state::debugger::SGElemIdMap mapEntry; - mapEntry.m_Elem = theData.m_Element; - mapEntry.m_Id = iter->first.c_str(); - elemMapBuffer.push_back(mapEntry); - } - } - debugger.MapElementIds(&inPresentation, - toDataRef(elemMapBuffer.data(), (QT3DSU32)elemMapBuffer.size())); - } - - return theLoadResult; -} - -IDOMReader &CUIPParserImpl::GetDOMReader() -{ - return *m_DOMReader.get(); -} - -//============================================================================== -/** - * Load Project Settings - * @param inPresentation presentation written to - * @return a flag indicating whether or not we successfully loaded the file - */ -BOOL CUIPParserImpl::LoadProjectSettings(IPresentation &inPresentation, IDOMReader &inReader) -{ - IDOMReader::Scope __projectSettingsScope(inReader); - - if (inReader.MoveToFirstChild("ProjectSettings")) { - SPresentationSize thePresentationSize; - qt3ds::QT3DSI32 theWidth, theHeight; - - if (inReader.Att("presentationWidth", theWidth)) - thePresentationSize.m_Width = static_cast(theWidth); - if (inReader.Att("presentationHeight", theHeight)) - thePresentationSize.m_Height = static_cast(theHeight); - thePresentationSize.m_ScaleMode = SCALEMODE_EXACT; // ScaleMode is always EXACT - - inPresentation.SetSize(thePresentationSize); - - return true; - } else - return false; -} - -BOOL CUIPParserImpl::LoadClasses(IPresentation & /*inPresentation*/, IDOMReader &inReader) -{ - IDOMReader::Scope __classesScope(inReader); - - if (inReader.MoveToFirstChild("Classes")) { - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - const char *theSourcePath; - const char *theId; - const char *theName; - // Read the sourcepath and id - if (inReader.Att("sourcepath", theSourcePath) && inReader.Att("id", theId)) { - // Read the name - if (!inReader.Att("name", theName)) - theName = theId; - - bool theLoadFlag = false; - QString theFullPath(theSourcePath); - - if (theFullPath.endsWith(".qml")) { - theLoadFlag = m_MetaData.LoadScriptFile(inReader.GetNarrowElementName(), theId, - theName, theFullPath.toUtf8().data()); - if (theLoadFlag) - m_IdScriptMap[theId] = theSourcePath; - } else if (theFullPath.endsWith(".effect")) { - theLoadFlag = m_MetaData.LoadEffectXMLFile(inReader.GetNarrowElementName(), - theId, theName, - theFullPath.toUtf8().data()); - } else if (theFullPath.endsWith(".material") || theFullPath.endsWith(".shader")) { - theLoadFlag = m_MetaData.LoadMaterialXMLFile( - inReader.GetNarrowElementName(), theId, theName, - theFullPath.toUtf8().data()); - } else if (theFullPath.endsWith(".plugin")) { - theLoadFlag = m_MetaData.LoadPluginXMLFile(inReader.GetNarrowElementName(), - theId, theName, - theFullPath.toUtf8().data()); - } - - if (!theLoadFlag) { - // What file is this?!? - qCCritical(qt3ds::INVALID_OPERATION) - << "Could not load sourcepath file: " - << theFullPath.toLatin1().constData(); - } - } - } - } - - // Always return true. Failing to load classes should not block the rest of the system. - return true; -} - -BOOL CUIPParserImpl::LoadGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __childScope(inReader); - - m_NumGraphElements = 0; - m_NumGraphComponents = 0; - m_NumGraphAttributes = 0; - - bool theLoadResult = inReader.MoveToFirstChild("Graph"); - if (theLoadResult) { - theLoadResult &= LoadSceneGraph(inPresentation, inReader); - if (theLoadResult) - PatchSceneElementRef(); - } - - return theLoadResult; -} - -inline RuntimeVector3 Convert(const QT3DSVec3 &input) -{ - return RuntimeVector3(input.x, input.y, input.z); -} -using qt3ds::runtime::element::SPropertyDesc; -using qt3ds::runtime::element::TPropertyDescAndValue; - -void CUIPParserImpl::GetMetaAttribute(IPresentation &inPresentation, - TPropertyDescAndValueList &outDescList, TStrType inType, - TStrType inName, TStrType inClassId, - CRegisteredString *inAttStrNames) -{ - ERuntimeDataModelDataType thePropertyType = - m_MetaData.GetPropertyType(inType, inName, inClassId); - - // TODO: Handle all other types - switch (thePropertyType) { - case ERuntimeDataModelDataTypeFloat: - AddFloatAttribute(outDescList, inAttStrNames[0], - m_MetaData.GetPropertyValueFloat(inType, inName, inClassId)); - break; - case ERuntimeDataModelDataTypeFloat2: { - RuntimeVector3 theVector3 = - Convert(m_MetaData.GetPropertyValueVector2(inType, inName, inClassId)); - SFloat2 theValue(theVector3.m_X, theVector3.m_Y); - AddFloat2Attribute(outDescList, inAttStrNames, theValue); - break; - } - case ERuntimeDataModelDataTypeFloat3: { - RuntimeVector3 theVector3 = - Convert(m_MetaData.GetPropertyValueVector3(inType, inName, inClassId)); - SFloat3 theValue(theVector3.m_X, theVector3.m_Y, theVector3.m_Z); - ERuntimeAdditionalMetaDataType theAdditionalType = - m_MetaData.GetAdditionalType(inType, inName, inClassId); - AddFloat3Attribute(outDescList, theAdditionalType, inAttStrNames, theValue); - break; - } - case ERuntimeDataModelDataTypeLong: - AddLongAttribute(outDescList, inAttStrNames[0], - m_MetaData.GetPropertyValueLong(inType, inName, inClassId)); - break; - case ERuntimeDataModelDataTypeString: { - Option theRuntimeStr = - m_MetaData.GetPropertyValueString(inType, inName, inClassId); - if (theRuntimeStr.hasValue()) - AddStringAttribute(inPresentation, outDescList, inAttStrNames[0], - theRuntimeStr->c_str()); - else - AddStringAttribute(inPresentation, outDescList, inAttStrNames[0], ""); - } break; - case ERuntimeDataModelDataTypeBool: - AddBoolAttribute(outDescList, inAttStrNames[0], - m_MetaData.GetPropertyValueBool(inType, inName, inClassId)); - break; - case ERuntimeDataModelDataTypeLong4: - AddElementRefAttribute(outDescList, inAttStrNames[0], NULL); - break; - case ERuntimeDataModelDataTypeObjectRef: { - // Object ref is converted to string path - eastl::string theRuntimeStr = - m_MetaData.GetPropertyValueObjectRef(inType, inName, inClassId); - eastl::string theObjectRef = m_ObjectRefHelper->BuildReferenceString(theRuntimeStr); - AddStringAttribute(inPresentation, outDescList, inAttStrNames[0], theObjectRef.c_str()); - break; - } - default: - QT3DS_ASSERT(false); - } -} - -void CUIPParserImpl::AddFloatAttribute(TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, float &inValue) -{ - UVariant theValue; - theValue.m_FLOAT = inValue; - outDescList.push_back( - eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_FLOAT), theValue)); -} - -void CUIPParserImpl::AddLongAttribute(TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, qt3ds::QT3DSI32 &inValue) -{ - UVariant theValue; - theValue.m_INT32 = inValue; - outDescList.push_back( - eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_INT32), theValue)); -} - -void CUIPParserImpl::AddBoolAttribute(TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, bool &inValue) -{ - UVariant theValue; - theValue.m_INT32 = inValue; - outDescList.push_back( - eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_BOOL), theValue)); -} - -void CUIPParserImpl::AddFloat2Attribute(TPropertyDescAndValueList &outDescList, - CRegisteredString *inAttStrNames, SFloat2 &inValue) -{ - for (long theIndex = 0; theIndex < 2; ++theIndex) { - UVariant theValue; - theValue.m_FLOAT = inValue[theIndex]; - outDescList.push_back(eastl::make_pair( - SPropertyDesc(inAttStrNames[theIndex], ATTRIBUTETYPE_FLOAT), theValue)); - } -} - -void CUIPParserImpl::AddFloat3Attribute(TPropertyDescAndValueList &outDescList, - ERuntimeAdditionalMetaDataType inAdditionalType, - CRegisteredString *inAttStrNames, SFloat3 &inValue) -{ - for (long theIndex = 0; theIndex < 3; ++theIndex) { - float theValue = inValue[theIndex]; - if (inAdditionalType == ERuntimeAdditionalMetaDataTypeRotation) - TORAD(theValue); - UVariant theVarValue; - theVarValue.m_FLOAT = theValue; - outDescList.push_back(eastl::make_pair( - SPropertyDesc(inAttStrNames[theIndex], ATTRIBUTETYPE_FLOAT), theVarValue)); - } -} - -void CUIPParserImpl::AddStringAttribute(IPresentation &inPresentation, - TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, const char *inValue) -{ - qt3ds::foundation::CStringHandle theString = inPresentation.GetStringTable().GetHandle(inValue); - UVariant theValue; - theValue.m_StringHandle = theString.handle(); - outDescList.push_back( - eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_STRING), theValue)); - if (CHash::HashAttribute(inAttStrName.c_str()) == Q3DStudio::ATTRIBUTE_SOURCEPATH && inValue - && *inValue) - AddSourcePath(inValue); -} - -void CUIPParserImpl::AddElementRefAttribute(TPropertyDescAndValueList &outDescList, - CRegisteredString inAttStrName, SElement *inElement) -{ - UVariant theValue; - if (inElement) { - theValue.m_ElementHandle = inElement->GetHandle(); - QT3DS_ASSERT(theValue.m_ElementHandle); - } else - theValue.m_ElementHandle = 0; - outDescList.push_back( - eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_ELEMENTREF), theValue)); -} - -void CUIPParserImpl::GetAttributeList(IPresentation &inPresentation, - TPropertyDescAndValueList &outDescList, TStrType inType, - TStrType inName, TStrType inClassId, const char *inValue, - CRegisteredString *inPropNameStrs) -{ - ERuntimeDataModelDataType theDataType = m_MetaData.GetPropertyType(inType, inName, inClassId); - ERuntimeAdditionalMetaDataType theAdditionalType = - m_MetaData.GetAdditionalType(inType, inName, inClassId); - - GetAttributeList(inPresentation, outDescList, theDataType, theAdditionalType, inName, inValue, - inPropNameStrs); -} - -void CUIPParserImpl::GetAttributeList(IPresentation &inPresentation, - TPropertyDescAndValueList &outDescList, - ERuntimeDataModelDataType inDataType, - ERuntimeAdditionalMetaDataType inAdditionalType, const char *, - const char *inValue, CRegisteredString *inPropNameStrs) -{ - // Create a destructible value - m_ValueBuffer.clear(); - m_TempBuffer.clear(); - m_ValueBuffer.write(inValue, (QT3DSU32)strlen(inValue) + 1); - WCharTReader theReader((char8_t *)m_ValueBuffer.begin(), m_TempBuffer, - *m_DOMReader->GetStringTable()); - - // TODO: Handle all other types - // Note that the default value should be consistent with the SetDefault method of - // TDataModelValue - switch (inDataType) { - case ERuntimeDataModelDataTypeLong: { - qt3ds::QT3DSI32 theValue = 0; - if (!IsTrivial(inValue)) - theReader.Read(theValue); - AddLongAttribute(outDescList, inPropNameStrs[0], theValue); - break; - } - case ERuntimeDataModelDataTypeFloat: { - float theValue = 0; - if (!IsTrivial(inValue)) - theReader.Read(theValue); - AddFloatAttribute(outDescList, inPropNameStrs[0], theValue); - break; - } - case ERuntimeDataModelDataTypeFloat2: { - SFloat2 theValue(0); - if (!IsTrivial(inValue)) - theReader.ReadRef(NVDataRef(&theValue[0], 2)); - AddFloat2Attribute(outDescList, inPropNameStrs, theValue); - break; - } - case ERuntimeDataModelDataTypeFloat3: { - SFloat3 theValue(0); - if (!IsTrivial(inValue)) - theReader.ReadRef(NVDataRef(&theValue[0], 3)); - AddFloat3Attribute(outDescList, inAdditionalType, inPropNameStrs, theValue); - break; - } - case ERuntimeDataModelDataTypeBool: { - bool theValue = false; - if (!IsTrivial(inValue)) - theReader.Read(theValue); - AddBoolAttribute(outDescList, inPropNameStrs[0], theValue); - break; - } - case ERuntimeDataModelDataTypeStringRef: - case ERuntimeDataModelDataTypeString: { - const char *theDataPtr = ""; - if (!IsTrivial(inValue)) - theReader.Read(theDataPtr); - AddStringAttribute(inPresentation, outDescList, inPropNameStrs[0], theDataPtr); - break; - } - case ERuntimeDataModelDataTypeLong4: { - const char *theDataPtr = NULL; - if (!IsTrivial(inValue)) - theReader.Read(theDataPtr); - SElement *theElementData = GetElement(theDataPtr); - AddElementRefAttribute(outDescList, inPropNameStrs[0], theElementData); - break; - } - case ERuntimeDataModelDataTypeObjectRef: { - // Object ref is converted to string path - const char *theDataPtr = NULL; - if (!IsTrivial(inValue)) - theReader.Read(theDataPtr); - if (theDataPtr) { - eastl::string theObjectRef = m_ObjectRefHelper->BuildReferenceString(theDataPtr); - AddStringAttribute(inPresentation, outDescList, inPropNameStrs[0], - theObjectRef.c_str()); - } - break; - } - default: - QT3DS_ASSERT(false); - } -} - -//============================================================================== -/** - * Looks up the EElementType from the asset type. - */ -EElementType GetElementType(const char *inType) -{ - if (AreEqual(inType, "Scene") || AreEqual(inType, "Layer") || AreEqual(inType, "Group") - || AreEqual(inType, "Model") || AreEqual(inType, "Path")) - return ELEMENTTYPE_NODE; - - else if (AreEqual(inType, "Camera")) - return ELEMENTTYPE_CAMERA; - - else if (AreEqual(inType, "Light")) - return ELEMENTTYPE_LIGHT; - - else if (AreEqual(inType, "Component")) - return ELEMENTTYPE_COMPONENT; - - else if (AreEqual(inType, "Material")) - return ELEMENTTYPE_MATERIAL; - - else if (AreEqual(inType, "Image")) - return ELEMENTTYPE_TEXTURE; - - else if (AreEqual(inType, "Behavior")) - return ELEMENTTYPE_BEHAVIOR; - - else if (AreEqual(inType, "Text")) - return ELEMENTTYPE_TEXT; - - else if (AreEqual(inType, "PathAnchorPoint")) - return ELEMENTTYPE_PATHANCHORPOINT; - - else if (AreEqual(inType, "SubPath")) - return ELEMENTTYPE_SUBPATH; - - else - return ELEMENTTYPE_UNKNOWN; -} - -//============================================================================== -/** - * Build out the graph. - * @param inPresentation presentation written to - * @return a flag indicating whether or not we successfully loaded the file - */ -BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &inReader, - qt3ds::runtime::element::SElement *inNewStyleParent) -{ - IDOMReader::Scope __childScope(inReader); - IScriptBridge *theScriptBridgeQml = inPresentation.GetScriptBridgeQml(); - - eastl::string theFileString; - qt3ds::runtime::IApplication &theApp(inPresentation.GetApplication()); - qt3ds::runtime::IElementAllocator &theElemAllocator(theApp.GetElementAllocator()); - TPropertyDescAndValueList theProperties; - using qt3ds::runtime::element::SPropertyDesc; - qt3ds::foundation::IStringTable &theStringTable(inPresentation.GetStringTable()); - // build out the graph. - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - theProperties.clear(); - const char *theId; - inReader.Att("id", theId); - const char *theClass; - inReader.Att("class", theClass); - const char *theType(inReader.GetNarrowElementName()); - eastl::string theName(m_ObjectRefHelper->GetName(theId).c_str()); - // Get default end time from metadata - UINT32 theLoopTime = 0; - bool isComponent = false; - bool isBehavior = false; - - // Create SElement - if (AreEqual(theType, "Scene") || AreEqual(theType, "Component")) { - // TDataModelValue theValue; - theLoopTime = m_MetaData.GetPropertyValueLong(m_MetaData.Register(theType), - m_MetaData.Register("endtime")); - Q3DStudio_ASSERT(theLoopTime != 0); // Something is wrong here - isComponent = true; - } else { - if (AreEqual(theType, "Behavior") && !IsTrivial(theClass)) { - // Find the sourcepath and load the script - ++theClass; // remove the '#' - TIdSourcePathMap::iterator theSourcePathIter = m_IdScriptMap.find(theClass); - if (theSourcePathIter != m_IdScriptMap.end()) { - theFileString.assign(theSourcePathIter->second); - -// For non-windows platforms, we need to reverse the slashes -#ifndef EA_PLATFORM_WINDOWS - for (eastl::string::size_type thePos = theFileString.find('\\'); - thePos != eastl::string::npos; - thePos = theFileString.find('\\', thePos + 1)) { - theFileString.replace(thePos, 1, 1, '/'); - } -#endif - isBehavior = true; - UVariant theValue; - theValue.m_StringHandle = - inPresentation.GetStringTable().GetHandle(theFileString.c_str()); - theProperties.push_back(eastl::make_pair( - SPropertyDesc(theStringTable.RegisterStr("behaviorscripts"), - ATTRIBUTETYPE_STRING), - theValue)); - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "Could not load Behavior script: " << theClass; - } - } - } - - SElementData &theElementData = - m_ParseElementManager.GetOrCreateElementData(theId, theType, theClass); - - const char8_t *theSourcePath; - if (inReader.UnregisteredAtt("sourcepath", theSourcePath)) - AddSourcePath(theSourcePath); - - TAttrMap &theList = theElementData.m_PropertyMap; - - const char *theAttribute; - for (TAttrMap::iterator theIter = theList.begin(), theMapEnd = theList.end(); - theIter != theMapEnd; ++theIter) { - if (theIter->second.m_ElementFlag) { - // Parse the property value from uip, this will overwrite the default value - const TStrType &thePropertyName(theIter->first); - CRegisteredString *thePropertyNames = theIter->second.m_PropertyNames; - size_t theListSize = theProperties.size(); - if (inReader.Att(thePropertyName.c_str(), theAttribute)) { - ERuntimeDataModelDataType theDataType = m_MetaData.GetPropertyType( - theElementData.m_Type, thePropertyName, theElementData.m_Class); - if (theDataType == ERuntimeDataModelDataTypeLong4) { - AddElementRefToPatch(theProperties, theElementData, thePropertyName.c_str(), - theAttribute); - } else - GetAttributeList(inPresentation, theProperties, theElementData.m_Type, - thePropertyName, theElementData.m_Class, theAttribute, - thePropertyNames); - } else { - GetMetaAttribute(inPresentation, theProperties, theElementData.m_Type, - thePropertyName, theElementData.m_Class, thePropertyNames); - } - size_t theNumAtts = theProperties.size() - theListSize; - QT3DS_ASSERT(theNumAtts == (size_t)theIter->second.m_Arity); - (void)theNumAtts; - } - } - qt3ds::runtime::element::SElement &theNewElem = theElemAllocator.CreateElement( - theStringTable.RegisterStr(theName.c_str()), theStringTable.RegisterStr(theType), - theStringTable.RegisterStr(theElementData.m_Class.c_str()), - toConstDataRef(theProperties.data(), (QT3DSU32)theProperties.size()), &inPresentation, - inNewStyleParent, isComponent); - theElementData.m_Element = &theNewElem; - - if (inPresentation.GetRoot() == NULL) - inPresentation.SetRoot(theNewElem); - - eastl::string thePath; - // build out the full path to the element for debugging - for (CUIPParserObjectRefHelper::SGraphNode *theNode = - this->m_ObjectRefHelper->GetNode(theId); - theNode; theNode = theNode->m_Parent) { - if (thePath.length()) - thePath.insert(0, "."); - thePath.insert(0, theNode->m_Name); - } - if (thePath.size()) - theNewElem.m_Path = m_ParseElementManager.m_StringTable.RegisterStr(thePath.c_str()); - - if (isBehavior) { - if (theFileString.find(".qml") != eastl::string::npos) { - theScriptBridgeQml->LoadScript(&inPresentation, &theNewElem, - theFileString.c_str()); - } - } - LoadSceneGraph(inPresentation, inReader, &theNewElem); - } - - return true; -} - -//============================================================================== -/** - * This method will parse through the graph sections to cache those attributes that - * should never be optimized - */ -void CUIPParserImpl::CacheGraphRequiredAttributes(qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __childScope(inReader); - - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - const char *theId; - inReader.Att("id", theId); - const char *theType(inReader.GetNarrowElementName()); - const char *theClass = ""; - inReader.Att("class", theClass); - SElementData &theData = - m_ParseElementManager.GetOrCreateElementData(theId, theType, theClass); - // name and sourcepath are never optimized out. - m_ParseElementManager.MarkAttributeAsReferenced(theData, "name"); - // not everything needs to be in the time graph. - if (AreEqual(theType, "Scene") == false && AreEqual(theType, "Material") == false - && AreEqual(theType, "CustomMaterial") == false && AreEqual(theType, "Image") == false - && AreEqual(theType, "RenderPlugin") == false) { - SElementPropertyInfo *theProp = - m_ParseElementManager.GetOrCreateProperty(theData, "starttime"); - theProp->m_SlideFlag = true; - theProp->m_SlideForceFlag = true; - theProp->m_ElementFlag = true; - theProp = m_ParseElementManager.GetOrCreateProperty(theData, "endtime"); - theProp->m_SlideFlag = true; - theProp->m_SlideForceFlag = true; - theProp->m_ElementFlag = true; - } - - // Probably not the most optimal thing to expose this attribute for all elements that - // support it, since it is not really needed except during initialization - m_ParseElementManager.MarkAttributeAsReferenced(theData, "controlledproperty"); - - // Behaviors need all attributes possible on the object on them all the time. - if (AreEqual(theType, "Behavior") || AreEqual(theType, "RenderPlugin")) { - m_ParseElementManager.MarkAllAttributesAsReferenced(theData); - } - - // Recursive - CacheGraphRequiredAttributes(inReader); - } -} - -//============================================================================== -/** - * This method will parse through the logic sections to cache those attributes that - * will be changed and thus needs to be at the SElement - */ -BOOL CUIPParserImpl::CacheLogicRequiredAttributes(qt3dsdm::IDOMReader &inReader, - qt3ds::QT3DSI32 inSlideIndex, - SParseSlide *inParentSlide) -{ - IDOMReader::Scope __stateScope(inReader); - eastl::string theSlideId = GetSlideId(inReader); - SParseSlide &theSlide = m_ParseSlideManager.GetOrCreateSlide(theSlideId.c_str(), inSlideIndex); - eastl::hash_set theCommandInstances; - QT3DSU32 slideAnimActions = 0; - - { - IDOMReader::Scope __commandLoopScope(inReader); - for (BOOL theSuccess = inReader.MoveToFirstChild(); theSuccess; - theSuccess = inReader.MoveToNextSibling()) { - IDOMReader::Scope __commandScope(inReader); - if (AreEqual(inReader.GetNarrowElementName(), "Add") - || AreEqual(inReader.GetNarrowElementName(), "Set")) { - bool isSet = AreEqual(inReader.GetNarrowElementName(), "Set"); - - const char *theRef; - if (inReader.Att("ref", theRef)) { - theRef++; // remove the '#' - - // Set/Add command applied to an element *not* in the scene graph. - SElementData *theData = m_ParseElementManager.FindElementData(theRef); - if (theData == NULL) { - QT3DS_ASSERT(false); - continue; - } - // If this element has controlledproperty, need to mark all as referenced - // in order for datainput initialisation to find attributes that - // are controlled - // TODO: we could parse out the exact controlled property names and - // set only those as referenced. In this case we might have to expand vec3 - // type attributes to component parts - const char *ctrldProp; - inReader.Att("controlledproperty", ctrldProp); - if (ctrldProp) - m_ParseElementManager.MarkAllAttributesAsReferenced(*theData, true); - - theCommandInstances.insert(theData->m_Id); - if (isSet) { - for (eastl::pair theAtt = - inReader.GetNarrowFirstAttribute(); - !IsTrivial(theAtt.first); theAtt = inReader.GetNarrowNextAttribute()) { - if (AreEqual(theAtt.first, "ref") || AreEqual(theAtt.first, "shy")) - continue; - - SElementPropertyInfo *theProperty = - m_ParseElementManager.GetOrCreateProperty(*theData, theAtt.first); - // This property exists on both the elements and the slides. - if (theProperty) { - theProperty->m_ElementFlag = true; - theProperty->m_SlideFlag = true; - } - } - // Run through parent animations and forward them *if* this set command does - // not have this property present. - if (inParentSlide) { - TAnimationList *theAnimations = - m_ParseSlideManager.GetAnimationsForInstance(*inParentSlide, - theData->m_Id); - if (theAnimations != NULL) { - for (QT3DSU32 animIdx = 0, animEnd = theAnimations->size(); - animIdx < animEnd; ++animIdx) { - SParseAnimationRef &theEntry((*theAnimations)[animIdx]); - const char8_t *propValue = ""; - SElementPropertyInfo *thePropInfo = - m_ParseElementManager.FindProperty( - *theData, theEntry.m_PropertyName.c_str()); - if (!thePropInfo) { - QT3DS_ASSERT(false); - continue; - } - // If the attribute doesn't exist in the command, then we - // forward the animation to here - if (inReader.Att(thePropInfo->m_PropertyName, propValue) - == false) { - ++slideAnimActions; - m_ParseSlideManager.ReferenceAnimation( - theSlide, *theEntry.m_Animation, true); - } - } - } - } - } - - // find all the animations, regardless of add or set. - { - IDOMReader::Scope __animationScope(inReader); - for (BOOL theAnimScopeSuccess = inReader.MoveToFirstChild("AnimationTrack"); - theAnimScopeSuccess; - theAnimScopeSuccess = inReader.MoveToNextSibling("AnimationTrack")) { - const char *theProperty; - const char8_t *theValue = ""; - inReader.Value(theValue); - if (theValue != NULL && *theValue - && inReader.UnregisteredAtt("property", theProperty)) { - m_ParseElementManager.MarkAttributeAsReferenced(*theData, - theProperty); - // PreParse the animation at this point. This allows us to easily - // count animations. - bool isDynamic = false; - inReader.Att("dynamic", isDynamic); - SParseSlideAnimationTypes::Enum theParseType = - SParseSlideAnimationTypes::EaseInOut; - const char8_t *animType; - if (inReader.Att("type", animType)) { - if (AreEqual(animType, "EaseInOut")) { - } else if (AreEqual(animType, "Bezier")) - theParseType = SParseSlideAnimationTypes::Bezier; - else if (AreEqual(animType, "Linear")) - theParseType = SParseSlideAnimationTypes::Linear; - else { - QT3DS_ASSERT(false); - } - } - ++slideAnimActions; - m_ParseSlideManager.SetAnimationData( - theSlide, theData->m_Id, theProperty, theValue, theParseType, - isDynamic, inSlideIndex != 0); - } - } - } - - // find all the actions - { - IDOMReader::Scope __actionScope(inReader); - for (BOOL theActionScopeSuccess = inReader.MoveToFirstChild("Action"); - theActionScopeSuccess; - theActionScopeSuccess = inReader.MoveToNextSibling("Action")) { - const char8_t *theActionId; - // Don't cache reference actions - if (inReader.Att("id", theActionId)) { - m_ActionHelper->CacheAction(inReader, theData->m_Id); - bool active = true; - inReader.Att("eyeball", active); - ++slideAnimActions; - m_ParseSlideManager.GetOrCreateAction( - theSlide, theActionId, - m_ActionHelper->GetActionCount(theActionId), active); - } - } - } - } - } - } - } - // Now forward all animations from the parent slide that are for instances that we haven't - // covered at all on this slide. - if (inParentSlide) { - for (TInstanceIdAnimationMap::iterator theIter = inParentSlide->m_Animations.begin(), - theEnd = inParentSlide->m_Animations.end(); - theIter != theEnd; ++theIter) { - if (theCommandInstances.find(theIter->first) == theCommandInstances.end()) { - TAnimationList &theList(theIter->second); - for (QT3DSU32 animIdx = 0, animEnd = theList.size(); animIdx < animEnd; ++animIdx) { - SParseAnimationRef &theEntry(theList[animIdx]); - m_ParseSlideManager.ReferenceAnimation(theSlide, *theEntry.m_Animation, true); - ++slideAnimActions; - } - } - } - // Forward action creation onto this slide. - for (TActionList::iterator theIter = inParentSlide->m_ActionList.begin(), - theEnd = inParentSlide->m_ActionList.end(); - theIter != theEnd; ++theIter) { - SParseSlideActionEntry &theAction(*theIter); - m_ParseSlideManager.GetOrCreateAction(theSlide, theAction.m_ActionId, - theAction.m_ActionCount, theAction.m_Active); - ++slideAnimActions; - } - } - - eastl::vector theChildSlideIds; - - for (BOOL theSuccess = inReader.MoveToFirstChild("State"); theSuccess; - theSuccess = inReader.MoveToNextSibling("State")) { - IDOMReader::Scope __subSlideScope(inReader); - ++inSlideIndex; - theChildSlideIds.push_back(GetSlideId(inReader)); - CacheLogicRequiredAttributes(inReader, inSlideIndex, &theSlide); - } - - // Pull all child animations up into this slide, but set them to deactivated. - for (QT3DSU32 childSlideIdx = 0, childSlideEnd = theChildSlideIds.size(); - childSlideIdx < childSlideEnd; ++childSlideIdx) { - SParseSlide *theChildSlide = - m_ParseSlideManager.FindSlide(theChildSlideIds[childSlideIdx].c_str()); - if (theChildSlide) { - // Add animations that did not original in this slide to this slide. - for (TInstanceIdAnimationMap::iterator theIter = theChildSlide->m_Animations.begin(), - theEnd = theChildSlide->m_Animations.end(); - theIter != theEnd; ++theIter) { - TAnimationList &theList(theIter->second); - for (QT3DSU32 animIdx = 0, animEnd = theList.size(); animIdx < animEnd; ++animIdx) { - SParseAnimationRef &theEntry(theList[animIdx]); - if (theEntry.m_Animation - && theEntry.m_Animation->m_SlideId != theSlide.m_SlideId) { - m_ParseSlideManager.ReferenceAnimation(theSlide, *theEntry.m_Animation, - false); - ++slideAnimActions; - } - } - } - for (TActionList::iterator theIter = theChildSlide->m_ActionList.begin(), - theEnd = theChildSlide->m_ActionList.end(); - theIter != theEnd; ++theIter) { - SParseSlideActionEntry &theEntry(*theIter); - // This deactivates actions that may be active on another slide. - m_ParseSlideManager.GetOrCreateAction(theSlide, theEntry.m_ActionId, - theEntry.m_ActionCount, false); - ++slideAnimActions; - } - } - } - // qt3ds::NVFoundationBase& fnd( - // m_CurrentPresentation->GetApplication().GetRuntimeFactory().GetFoundation() ); - // fnd.error( QT3DS_TRACE, "Loading slide %s, %d anim actions", theSlideId.c_str(), - // slideAnimActions ); - - return TRUE; -} - -void CUIPParserImpl::CacheClassRequiredAttributes(qt3dsdm::IDOMReader &inReader) -{ - { - // First, we parse Graph section to cache custom attributes specified by the class - IDOMReader::Scope __graphScope(inReader); - inReader.MoveToFirstChild("Graph"); - CacheClassSceneAttributes(inReader); - } - if (!m_IdClassMap.empty()) { - // Next, we parse Logic section to update the references - IDOMReader::Scope __logicScope(inReader); - inReader.MoveToFirstChild("Logic"); - CacheClassStateAttributes(inReader); - } -} - -void CUIPParserImpl::CacheClassSceneAttributes(IDOMReader &inReader) -{ - IDOMReader::Scope __childScope(inReader); - // build out the graph. - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - const char *theId; - const char *theClass; - if (inReader.Att("class", theClass) && inReader.Att("id", theId)) { - // Add to id-class map - m_IdClassMap[theId] = theClass; - } - CacheClassSceneAttributes(inReader); - } -} - -void CUIPParserImpl::CacheClassStateAttributes(IDOMReader &inReader) -{ - IDOMReader::Scope __childScope(inReader); - - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "State")) - CacheClassStateAttributes(inReader); - else if (AreEqual(inReader.GetNarrowElementName(), "Add") - || AreEqual(inReader.GetNarrowElementName(), "Set")) { - const char *theRef; - if (inReader.Att("ref", theRef)) { - theRef++; // remove the '#' - - // Find the class, if any - TIdClassMap::iterator theIter = m_IdClassMap.find(theRef); - if (theIter != m_IdClassMap.end()) { - // Get References of the class - eastl::vector theReferences; - m_MetaData.GetReferences("", theReferences, theIter->second.c_str()); - if (!theReferences.empty()) { - // Cache the references - m_ObjectRefHelper->MarkAllReferencedAttributes( - theRef, theReferences, inReader, m_ParseElementManager); - } - } - } - } - } -} - -//============================================================================== -/** - * For ElementRef type, there could be times where the SElement isn't created yet, thus - * this method cache those Long4 type and add an empty attribute into the SElement - */ -void CUIPParserImpl::AddElementRefToPatch(TPropertyDescAndValueList &outDescList, - SElementData &inElement, const char *inName, - const char *inValue) -{ - SElementRefCache theElementRefData; - theElementRefData.m_Element = &inElement; - theElementRefData.m_Name = inName; - theElementRefData.m_Value = inValue; - m_ElementRefCache.push_back(theElementRefData); - - UVariant theValue; - theValue.m_ElementHandle = 0; - outDescList.push_back( - eastl::make_pair(SPropertyDesc(m_ParseElementManager.m_StringTable.RegisterStr(inName), - ATTRIBUTETYPE_ELEMENTREF), - theValue)); -} - -//============================================================================== -/** - * For those Long4 type that was not loaded correctly, go through all of them and - * fix up the ElementRef - */ -void CUIPParserImpl::PatchSceneElementRef() -{ - for (eastl::vector::iterator theIter = m_ElementRefCache.begin(); - theIter != m_ElementRefCache.end(); ++theIter) { - SElementRefCache &theCache = *theIter; - - SElementData *theElementData = GetElementData(theCache.m_Value.c_str()); - - SElement *theElement = theCache.m_Element->m_Element; - UVariant *theValue = theElement->FindPropertyValue( - m_ParseElementManager.RegisterStr(theCache.m_Value.c_str())); - if (theValue) { - theValue->m_ElementHandle = 0; - if (theElementData->m_Element) { - theValue->m_ElementHandle = theElementData->m_Element->GetHandle(); - QT3DS_ASSERT(theValue->m_ElementHandle); - } - } - } -} - -BOOL CUIPParserImpl::LoadLogic(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __logicScope(inReader); - - m_NumSlides = 0; - m_NumSlideElements = 0; - m_NumSlideAttributes = 0; - m_NumAnimationTracks = 0; - m_NumAnimationKeys = 0; - m_NumSlideAnimations = 0; - m_NumSlideActions = 0; - - bool theStatus = true; - - // Build all of the animation objects that we have tallied up. - for (QT3DSU32 animIdx = 0, animEnd = m_ParseSlideManager.m_Animations.size(); animIdx < animEnd; - ++animIdx) { - SParseSlideAnimationEntry &theEntry = *m_ParseSlideManager.m_Animations[animIdx]; - SElementData *theData = m_ParseElementManager.FindElementData(theEntry.m_InstanceId); - // Generate valid animation indexes while we are at it. - LoadAnimationTrack(inPresentation, *theData, theEntry); - } - - if (inReader.MoveToFirstChild("Logic")) { - - // Action - m_ActionHelper->BuildActions(inPresentation); - - for (BOOL theSuccess = inReader.MoveToFirstChild("State"); theSuccess; - theSuccess = inReader.MoveToNextSibling("State")) { - theStatus &= LoadStateGraph(inPresentation, inReader); - } - } - - return theStatus; -} - -//============================================================================== -/** - * Load the State (Slides) - * @param inPresentation presentation written to - * @return a flag indicating whether or not we successfully loaded the file - */ -BOOL CUIPParserImpl::LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __slideScope(inReader); - - BOOL theStatus = true; - - SElement *theComponent = NULL; - const char8_t *theAttribute; - if (inReader.UnregisteredAtt("component", theAttribute)) - theComponent = GetElement(theAttribute); - if (theComponent) { - INT32 theSlideIndex = 0; - LoadState(inPresentation, theComponent, theSlideIndex, inReader); - - for (BOOL theResult = inReader.MoveToFirstChild("State"); theResult; - theResult = inReader.MoveToNextSibling("State")) { - if (theStatus) - theStatus &= LoadState(inPresentation, theComponent, ++theSlideIndex, inReader); - } - } else { - if (theAttribute) { - qCCritical(qt3ds::INVALID_OPERATION) - << "Slide load failure!! Failed to find component: " << theAttribute; - } else { - qCCritical(qt3ds::INVALID_OPERATION) - << "Slide load failure!! Failed to find component."; - } - } - - return theStatus; -} - -//============================================================================== -/** - * Load the State (Slides) - * @param inPresentation presentation written to - * @return a flag indicating whether or not we successfully loaded the file - */ -BOOL CUIPParserImpl::LoadState(IPresentation &inPresentation, SElement *inComponent, - INT32 inSlideIndex, qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __stateScope(inReader); - - BOOL theResult = true; - ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); - - eastl::string theSlideName = GetSlideName(inReader); - - qt3ds::runtime::SSlidePlayInformation thePlayMode = GetPlayMode(inReader); - thePlayMode.m_PlayThroughTo = (QT3DSU8)GetPlayThroughTo(inSlideIndex, inReader); - // Setup with the default value from the metadata - INT32 theMinTime = m_MetaData.GetPropertyValueLong(m_MetaData.Register("Asset"), - m_MetaData.Register("starttime")); - INT32 theMaxTime = m_MetaData.GetPropertyValueLong(m_MetaData.Register("Asset"), - m_MetaData.Register("endtime")); - - theBuilder.AddSlide(*inComponent, theSlideName.c_str(), thePlayMode.m_PlayMode, - thePlayMode.m_Paused, thePlayMode.m_PlayThroughTo, theMinTime, theMaxTime); - m_NumSlides++; - - m_SlideElements.clear(); - m_SlideElements.insert(inComponent); - - BOOL theActiveFlag = (inSlideIndex != 0); - theBuilder.AddSlideElement(*inComponent, theActiveFlag); - ProcessStateRef(inPresentation, inComponent, inSlideIndex == 0, inReader); - - m_NumSlideElements++; - - theMaxTime = 0; - theResult &= - LoadSlideElements(inPresentation, inReader, inSlideIndex == 0, inComponent, &theMaxTime); - if (theMaxTime != 0) - theBuilder.SetSlideMaxTime((QT3DSU32)theMaxTime); - - return theResult; -} - -//============================================================================== -/** - * Process the state information to add all the animations and actions that might be setup - */ -BOOL CUIPParserImpl::ProcessStateRef(IPresentation &inPresentation, SElement *inComponent, - bool inMaster, qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __stateScope(inReader); - eastl::string theSlideId = GetSlideId(inReader); - for (BOOL theResult = inReader.MoveToFirstChild("Set"); theResult; - theResult = inReader.MoveToNextSibling("Set")) { - const char8_t *theElementRef; - if (inReader.UnregisteredAtt("ref", theElementRef) - && GetElement(theElementRef) == inComponent) - ProcessSlideAnimAction(inPresentation, theSlideId, inMaster, inReader); - } - return TRUE; -} - -void CUIPParserImpl::ComputeAndReserveMemory(IPresentation & /*inPresentation*/, - qt3dsdm::IDOMReader &inReader) -{ - SGraphSectionCount theGraphSectionCount; - SLogicSectionCount theLogicSectionCount; - SActionSectionCount theActionSectionCount; - - { - IDOMReader::Scope __graphScope(inReader); - if (inReader.MoveToFirstChild("Graph")) - DoGraphSectionCount(inReader, theGraphSectionCount); - } - DoLogicSectionCount(inReader, theLogicSectionCount); - m_ActionHelper->GetActionSectionCount(theActionSectionCount); -} - -void CUIPParserImpl::DoGraphSectionCount(qt3dsdm::IDOMReader &inReader, - SGraphSectionCount &outGraphCounter) -{ - IDOMReader::Scope __graphScope(inReader); - - for (bool theResult = inReader.MoveToFirstChild(); theResult; - theResult = inReader.MoveToNextSibling()) { - const char *theTypeStr(inReader.GetNarrowElementName()); - if (AreEqual(theTypeStr, "Scene") || AreEqual(theTypeStr, "Component")) - outGraphCounter.m_ComponentCount++; - else - outGraphCounter.m_ElementCount++; - - const char *theIdStr; - inReader.Att("id", theIdStr); - const char *theClassStr; - inReader.Att("class", theClassStr); - - // For Behavior, we are adding a string attribute ATTRIBUTE_BEHAVIORSCRIPTS - if (AreEqual(theTypeStr, "Behavior") && !IsTrivial(theClassStr)) { - ++theClassStr; // remove the '#' - TIdSourcePathMap::iterator theSourcePathIter = m_IdScriptMap.find(theClassStr); - if (theSourcePathIter != m_IdScriptMap.end()) { - outGraphCounter.m_AttributeCount++; - outGraphCounter.m_StringAttrCount++; - } - } - SElementData *theData = m_ParseElementManager.FindElementData(theIdStr); - - if (theData) { - TAttrMap &thePropertyMap = theData->m_PropertyMap; - - // TODO: Maybe we should make m_IdAttributesMap only stores those valid attributes and - // also those attributes that already converted to Runtime type (e.g. position to - // position.x .y .z ) - // then we can really stop calling all the IsValidAttribute all over the place - // and we can simple just use the size of the vector here. - for (TAttrMap::iterator theIter = thePropertyMap.begin(), theEnd = thePropertyMap.end(); - theIter != theEnd; ++theIter) { - if (theIter->second.m_ElementFlag == false) - continue; - TStrType thePropertyName(theIter->first); - outGraphCounter.m_AttributeCount += theIter->second.m_Arity; - if (IsStringType(theIter->second.m_DataType)) - outGraphCounter.m_StringAttrCount += 1; - } - } - - DoGraphSectionCount(inReader, outGraphCounter); - } -} - -void CUIPParserImpl::DoLogicSectionCount(qt3dsdm::IDOMReader &inReader, - SLogicSectionCount &outLogicCounter) -{ - IDOMReader::Scope __logicCountScope(inReader); - - if (inReader.MoveToFirstChild("Logic")) { - for (bool theResult = inReader.MoveToFirstChild("State"); theResult; - theResult = inReader.MoveToNextSibling("State")) { - DoStateSectionCount(inReader, 0, outLogicCounter); - } - } -} - -void CUIPParserImpl::DoStateSectionCount(qt3dsdm::IDOMReader &inReader, Q3DStudio::INT32 inStateIndex, - SLogicSectionCount &outLogicCounter) -{ - IDOMReader::Scope __slideCountScope(inReader); - - outLogicCounter.m_SlideCount++; - - INT32 theChildSlideCount = inReader.CountChildren("State"); - outLogicCounter.m_SlideElementCount++; // this slide is also an element - Q3DStudio::INT32 theChildStateIndex(inStateIndex + 1); - - for (bool theResult = inReader.MoveToFirstChild(); theResult; - theResult = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "State")) { - DoStateSectionCount(inReader, theChildStateIndex, outLogicCounter); - ++theChildStateIndex; - } else if (AreEqual(inReader.GetNarrowElementName(), "Add") - || AreEqual(inReader.GetNarrowElementName(), "Set")) { - // SlideMultipler is used as follows: - // For every element, animation or action, the slide is used to turn on/off them - // Hence, if it is inside master, it will have an entry in the master and all the child - // slides in the SlideManager ( hence, theChildSlideCount + 1 ) - // if it is local, it will have an entry in the master and it's slide, ( thus 2 ) - // the assumption made here is that State in uip is definitely 2 level, hence if it has - // no child slides, it is definitely master - INT32 theSlideMultiplier; - if (theChildSlideCount == 0) - theSlideMultiplier = 2; - else - theSlideMultiplier = theChildSlideCount + 1; - DoRefSectionCount(inReader, theSlideMultiplier, inStateIndex, outLogicCounter); - } - } -} - -//============================================================================== -/** - * @ param inNumSlideMultiplier To know how this is used, see comments on the place - *where SlideMultipler is calculated - */ -void CUIPParserImpl::DoRefSectionCount(qt3dsdm::IDOMReader &inReader, INT32 inNumSlideMultiplier, - INT32, SLogicSectionCount &outLogicCounter) -{ - IDOMReader::Scope __refCountScope(inReader); - const char8_t *theElementRef; - inReader.UnregisteredAtt("ref", theElementRef); - SElementData *theData(m_ParseElementManager.FindElementData(theElementRef)); - if (theData == NULL) { - QT3DS_ASSERT(false); - return; - } - - if (AreEqual(inReader.GetNarrowElementName(), "Add")) - outLogicCounter.m_SlideElementCount += inNumSlideMultiplier; - - // There are cases where some attributes only appear in the local slide element, but not at the - // master slide. e.g. endTime. - // For these attributes, we must make sure that it is added to the slide element attribute of - // the master, so that everything will work correctly. - // This is done via the slide force flag on the element property object. - for (TAttrMap::iterator theIter = theData->m_PropertyMap.begin(), - theEnd = theData->m_PropertyMap.end(); - theIter != theEnd; ++theIter) { - const char8_t *theAttValue = ""; - bool hasAtt = inReader.UnregisteredAtt(theIter->first.c_str(), theAttValue); - if (theIter->second.m_SlideFlag == true - && (theIter->second.m_SlideForceFlag == true || hasAtt == true)) { - outLogicCounter.m_SlideAttributeCount += theIter->second.m_Arity * inNumSlideMultiplier; - } - // Strings we may still load regardless - if (hasAtt && IsStringType(theIter->second.m_DataType)) - outLogicCounter.m_StringAttrCount += 1; - } - // Always add padding for now till I can figure out exactly why padding is needed - // and find a minimal way to handle it. - outLogicCounter.m_PaddingCount += inNumSlideMultiplier; -} - -qt3ds::runtime::SSlidePlayInformation CUIPParserImpl::GetPlayMode(qt3dsdm::IDOMReader &inReader) -{ - using qt3ds::runtime::PlayMode; - - qt3ds::runtime::SSlidePlayInformation thePlayInformation; - // Setup with the default value from the metadata - eastl::string thePlayMode = m_MetaData.GetPropertyValueString(m_MetaData.Register("Slide"), - m_MetaData.Register("playmode")); - PlayMode::Enum theMode = PlayMode::StopAtEnd; - - if (thePlayMode == "Looping") { - theMode = PlayMode::Looping; - } else if (thePlayMode == "PingPong") { - theMode = PlayMode::PingPong; - } else if (thePlayMode == "Ping") { - theMode = PlayMode::Ping; - } else if (thePlayMode == "Play Through To...") { - theMode = PlayMode::PlayThroughTo; - } - thePlayInformation.m_PlayMode = theMode; - - eastl::string theInitialPlayState = m_MetaData.GetPropertyValueString( - m_MetaData.Register("Slide"), m_MetaData.Register("initialplaystate")); - if (theInitialPlayState == "Pause") - thePlayInformation.m_Paused = true; - - const char *theAttribute; - if (inReader.Att("playmode", theAttribute)) { - if (AreEqual(theAttribute, "Play Through To...")) { - thePlayInformation.m_PlayMode = PlayMode::PlayThroughTo; - } else if (AreEqual(theAttribute, "Stop at end")) { - thePlayInformation.m_PlayMode = PlayMode::StopAtEnd; - } else if (AreEqual(theAttribute, "Looping")) { - thePlayInformation.m_PlayMode = PlayMode::Looping; - } else if (AreEqual(theAttribute, "PingPong")) { - thePlayInformation.m_PlayMode = PlayMode::PingPong; - } else if (AreEqual(theAttribute, "Ping")) { - thePlayInformation.m_PlayMode = PlayMode::Ping; - } - } - - if (inReader.Att("initialplaystate", theAttribute)) { - if (AreEqual(theAttribute, "Play")) - thePlayInformation.m_Paused = false; - else - thePlayInformation.m_Paused = true; - } - - return thePlayInformation; -} - -INT32 CUIPParserImpl::GetPlayThroughTo(INT32 inCurrentSlideIndex, qt3dsdm::IDOMReader &inReader) -{ - // Just hardcode it to Next since we know from the metadata the default is Next. - // If we want to query from MetaData, need to write accessor to get back SStringOrInt - INT32 thePlayThroughTo = inCurrentSlideIndex + 1; - - const char *theAttribute; - if (inReader.Att("playthroughto", theAttribute) && *theAttribute) { - if (AreEqual(theAttribute, "Previous")) - thePlayThroughTo = inCurrentSlideIndex - 1; - else if (AreEqual(theAttribute, "Next")) - thePlayThroughTo = inCurrentSlideIndex + 1; - else if (theAttribute[0] == '#') { - theAttribute++; - SParseSlide *theSlide = m_ParseSlideManager.FindSlide(theAttribute); - if (theSlide) - thePlayThroughTo = theSlide->m_SlideIndex; - else - Q_ASSERT(!"Slide Not Found"); - } - } - - return thePlayThroughTo; -} - -eastl::string CUIPParserImpl::GetSlideName(qt3dsdm::IDOMReader &inReader) -{ - eastl::string theSlideName; - if (!inReader.Att("name", theSlideName)) - inReader.Att("id", theSlideName); - return theSlideName; -} - -eastl::string CUIPParserImpl::GetSlideId(qt3dsdm::IDOMReader &inReader) -{ - eastl::string theSlideId; - if (!inReader.Att("id", theSlideId)) - inReader.Att("component", theSlideId); - return theSlideId; -} - -// In the event we added something to the slide, we return the element data. -SElementData *CUIPParserImpl::AddSlideElement(IPresentation &inPresentation, bool inMaster, - qt3dsdm::IDOMReader &inReader, INT32 *outMaxTime) -{ - ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); - - SElementData *theElementData = NULL; - const char8_t *theElementRef = ""; - if (inReader.UnregisteredAtt("ref", theElementRef)) - theElementData = m_ParseElementManager.FindElementData(theElementRef); - - SElement *theElement = theElementData ? theElementData->m_Element : NULL; - if (theElement) { - if (m_SlideElements.find(theElement) == m_SlideElements.end()) { - const char *theEyeball; - bool theActiveFlag = !( - inMaster || (inReader.Att("eyeball", theEyeball) && AreEqual(theEyeball, "False"))); - - m_SlideElements.insert(theElement); - theBuilder.AddSlideElement(*theElement, theActiveFlag); - m_NumSlideElements++; - if (outMaxTime) { - INT32 theElementMaxTime = 0; - SElement *theParent = theElement->GetParent(); - if (theParent && theParent->IsComponent() && theElement) { - // Ignore material durations (in practice this is always a material container) - qt3dsdm::ComposerObjectTypes::Enum composerType( - qt3dsdm::ComposerObjectTypes::Convert(theElementData->m_Type.c_str())); - if (composerType != qt3dsdm::ComposerObjectTypes::Material - && inReader.Att("endtime", theElementMaxTime) == false) { - theElementMaxTime = m_MetaData.GetPropertyValueLong( - theElementData->m_Type, m_MetaData.Register("endtime"), - theElementData->m_Class); - } - *outMaxTime = NVMax(*outMaxTime, theElementMaxTime); - } - } - } else - theElementData = NULL; - } - - return theElementData; -} - -BOOL CUIPParserImpl::LoadSlideElements(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, - bool inMaster, SElement *inComponent, INT32 *outMaxTime) -{ - BOOL theSuccess = true; - - { - IDOMReader::Scope __childScope(inReader); - eastl::string theSlideId = GetSlideId(inReader); - eastl::string theActionIdStr; - // Setup the add/set commands for this slide. - { - IDOMReader::Scope __slideScope(inReader); - // Load all the animations for this slide right now: - - SParseSlide *theSlide = m_ParseSlideManager.FindSlide(theSlideId.c_str()); - // All animations and actions added to the master slide are deactivated. - QT3DSU32 animActions = 0; - if (theSlide) { - bool canActivateFlag = !inMaster; - ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); - for (TInstanceIdAnimationMap::iterator - theInstAnimIter = theSlide->m_Animations.begin(), - theInstAnimEnd = theSlide->m_Animations.end(); - theInstAnimIter != theInstAnimEnd; ++theInstAnimIter) { - const TAnimationList &theAnimList(theInstAnimIter->second); - for (QT3DSU32 theAnimIdx = 0, theAnimEnd = theAnimList.size(); - theAnimIdx < theAnimEnd; ++theAnimIdx) { - theBuilder.AddSlideAnimAction( - true, theAnimList[theAnimIdx].m_Animation->m_AnimationIndex, - theAnimList[theAnimIdx].m_Active && canActivateFlag); - ++animActions; - } - } - // Build the actions for this slide. - for (TActionList::iterator theActionIter = theSlide->m_ActionList.begin(), - theActionEnd = theSlide->m_ActionList.end(); - theActionIter != theActionEnd; ++theActionIter) { - SParseSlideActionEntry &theActionEntry(*theActionIter); - theActionIdStr.assign(theActionEntry.m_ActionId.c_str()); - qt3ds::QT3DSI32 theActionIndex = m_ActionHelper->GetActionIndex(theActionIdStr); - for (qt3ds::QT3DSI32 idx = 0; idx < theActionEntry.m_ActionCount; ++idx) { - qt3ds::runtime::SSlideAnimAction *theSlideData = - theBuilder.AddSlideAnimAction(false, theActionIndex + idx, - theActionEntry.m_Active - && canActivateFlag); - theActionEntry.m_Actions[idx] = theSlideData; - ++animActions; - } - } - - // qt3ds::NVFoundationBase& fnd( - // inPresentation.GetApplication().GetRuntimeFactory().GetFoundation() ); - // fnd.error( QT3DS_TRACE, "Loading slide %s, %d anim actions", theSlideId.c_str(), - // animActions ); - } - for (BOOL theResult = inReader.MoveToFirstChild(); theResult; - theResult = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "Add") - || AreEqual(inReader.GetNarrowElementName(), "Set")) { - SElementData *theAddedElement = - AddSlideElement(inPresentation, inMaster, inReader, outMaxTime); - if (theAddedElement && theAddedElement->m_Element) { - LoadSlideElementAttrs(inPresentation, inMaster, *theAddedElement, inReader, - inComponent); - // This can define actions or set the active - ProcessSlideAnimAction(inPresentation, theSlideId, inMaster, inReader); - } - } - } - } - // Pull add commands from child slides into master slide with active=false - // else things won't get reset when we switch slides. - { - // All child state adds go into this object with active set to false - IDOMReader::Scope __masterScope(inReader); - for (BOOL theResult = inReader.MoveToFirstChild("State"); theResult; - theResult = inReader.MoveToNextSibling("State")) { - IDOMReader::Scope __childScope(inReader); - for (BOOL theResult = inReader.MoveToFirstChild("Add"); theResult; - theResult = inReader.MoveToNextSibling("Add")) { - // Add the slide element, setting the active flag to false. - AddSlideElement(inPresentation, inMaster, inReader, outMaxTime); - } - } - } - // Pull add commands from master slide for objects in this slide. - // We do this after we process the add/set commands for this slide so that objects already - // added - // get ignored. If we do pull an object forward then we have to set all of the force-set - // properties as well - // as account for a possible end-time difference. - { - IDOMReader::Scope __childScope(inReader); - inReader.Leave(); - if (AreEqual(inReader.GetNarrowElementName(), "State")) { - TPropertyDescAndValueList theProperties; - for (BOOL theResult = inReader.MoveToFirstChild("Add"); theResult; - theResult = inReader.MoveToNextSibling("Add")) { - theProperties.clear(); - SElementData *theData = - AddSlideElement(inPresentation, inMaster, inReader, NULL); - if (theData) { - // Add all forced attributes to this slide. - for (TAttrMap::iterator theIter = theData->m_PropertyMap.begin(), - theEnd = theData->m_PropertyMap.end(); - theIter != theEnd; ++theIter) { - if (theIter->second.m_SlideForceFlag) { - GetMetaAttribute(inPresentation, theProperties, theData->m_Type, - theIter->first, theData->m_Class, - theIter->second.m_PropertyNames); - } - } - ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); - for (TPropertyDescAndValueList::iterator theIter = theProperties.begin(); - theIter != theProperties.end(); ++theIter) { - theBuilder.AddSlideAttribute(theIter->first.GetAttributeKey(), - theIter->second); - m_NumSlideAttributes++; - } - - // Ensure the actual end time is accounted for. - if (outMaxTime && theData->m_Element) { - SElement *theParent = theData->m_Element->GetParent(); - if (theParent && theParent->IsComponent()) { - // Ignore material durations - // (in practice this is always a material container) - qt3dsdm::ComposerObjectTypes::Enum composerType( - qt3dsdm::ComposerObjectTypes::Convert(theData->m_Type.c_str())); - if (composerType != qt3dsdm::ComposerObjectTypes::Material) { - long theoutMaxTime = (long)*outMaxTime; - long theMaxTime = m_MetaData.GetPropertyValueLong( - theData->m_Type, m_MetaData.Register("endtime"), - theData->m_Class); - *outMaxTime = NVMax(theoutMaxTime, theMaxTime); - } - } - } - } - } - } - } - } - return theSuccess; -} - -BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool, - SElementData &inElementData, qt3dsdm::IDOMReader &inReader, - SElement *inComponent) -{ - ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); - - TPropertyDescAndValueList theAttributeList; - - const char8_t *theRef = ""; - inReader.Att("ref", theRef); - if (theRef && *theRef && theRef[0] == '#') - ++theRef; - bool isSet = AreEqual(inReader.GetNarrowElementName(), "Set"); - const char8_t *sourcepath; - if (inReader.UnregisteredAtt("sourcepath", sourcepath)) - AddSourcePath(sourcepath); - - // We don't force set attributes when a given component has a set command within one of its - // child states. This happens in the case of actions (but nothing else). - bool shouldForce = inElementData.m_Element != inComponent; - for (TAttrMap::iterator theIter = inElementData.m_PropertyMap.begin(), - theEnd = inElementData.m_PropertyMap.end(); - theIter != theEnd; ++theIter) { - const char8_t *theAttValue = ""; - bool hasAtt = inReader.UnregisteredAtt(theIter->first, theAttValue); - QT3DSU32 previousListSize = theAttributeList.size(); - if (hasAtt == false) { - // StartTime and EndTime in Master Slide are useless, so set it to the value in the - // metadata. - // if we look at the uip file, if the element doesn't have endTime, it means is 10000ms, - // and not really the value in the master slide - // this make it special from other attributes - if (theIter->second.m_SlideForceFlag && shouldForce) - GetMetaAttribute(inPresentation, theAttributeList, inElementData.m_Type, - theIter->first, inElementData.m_Class, - theIter->second.m_PropertyNames); - } else { - // Only use the attribute list from set blocks to set values into the slide, not from - // add attributes - // This isn't completely correct - GetAttributeList(inPresentation, theAttributeList, inElementData.m_Type, theIter->first, - inElementData.m_Class, theAttValue, theIter->second.m_PropertyNames); - } - if (isSet == false && theIter->second.m_SlideForceFlag == false) { - if (inElementData.m_Element != NULL && theIter->second.m_ElementFlag) { - for (QT3DSU32 idx = previousListSize, end = theAttributeList.size(); idx < end; - ++idx) { - UVariant *theValue = inElementData.m_Element->FindPropertyValue( - theAttributeList[idx].first.m_Name); - if (theValue) { - *theValue = theAttributeList[idx].second; - } - } - } - theAttributeList.resize(previousListSize); - } - } - for (TPropertyDescAndValueList::iterator theIter = theAttributeList.begin(); - theIter != theAttributeList.end(); ++theIter) { - theBuilder.AddSlideAttribute(theIter->first.GetAttributeKey(), theIter->second); - m_NumSlideAttributes++; - } - - return TRUE; -} - -void CUIPParserImpl::LoadAnimationTrack(IPresentation &inPresentation, SElementData &inElementData, - SParseSlideAnimationEntry &inAnimation) -{ - SElementPropertyInfo *theInfo = - m_ParseElementManager.FindProperty(inElementData, inAnimation.m_PropertyName); - if (theInfo == NULL) - return; - UINT32 theHashedKey = inAnimation.m_PropertyHash; - bool theIsDynamic = inAnimation.m_IsDynamic; - INT32 theIndex = inPresentation.GetAnimationSystem().CreateAnimationTrack( - *inElementData.m_Element, theHashedKey, theIsDynamic); - inAnimation.m_AnimationIndex = theIndex; - m_NumAnimationTracks++; - bool isRotation = theInfo->m_AdditionalType == ERuntimeAdditionalMetaDataTypeRotation; - LoadAnimationKeys(inPresentation, inAnimation, isRotation); -} - -void CUIPParserImpl::LoadAnimationKeys(IPresentation &inPresentation, - const SParseSlideAnimationEntry &inAnimation, - bool inIsRotation) -{ - - NVConstDataRef theFloatValues(inAnimation.m_KeyframeData.data(), - (qt3ds::QT3DSU32)inAnimation.m_KeyframeData.size()); - switch (inAnimation.m_AnimationType) { - case SParseSlideAnimationTypes::Linear: - LoadLinearKeys(inPresentation, theFloatValues, inIsRotation); - break; - case SParseSlideAnimationTypes::Bezier: - LoadBezierKeys(inPresentation, theFloatValues, inIsRotation); - break; - default: - QT3DS_ASSERT(false); - case SParseSlideAnimationTypes::EaseInOut: - LoadEaseInOutKeys(inPresentation, theFloatValues, inIsRotation); - break; - } -} - -BOOL CUIPParserImpl::LoadBezierKeys(IPresentation &inPresentation, NVConstDataRef &inValues, - bool inIsRotation) -{ - QT3DS_ASSERT(inValues.size() % 6 == 0); - if (inValues.size() % 6 != 0) - return FALSE; - - IAnimationSystem &theBuilder = inPresentation.GetAnimationSystem(); - - float theTime; - float theValue; - float theC1Time; - float theC1Value; - float theC2Time; - float theC2Value; - - const float *theIter = inValues.begin(); - - long theNumKeys = inValues.size() / 6; - QT3DS_ASSERT(theNumKeys > 0); - for (long theIndex = 0; theIndex < theNumKeys; ++theIndex) { - theTime = *theIter * 1000.0f; - ++theIter; - theValue = *theIter; - ++theIter; - ++theIter; // just increment the iterator, C2Time is set below - ++theIter; // just increment the iterator, C2Value is set below - theC1Time = *theIter * 1000.0f; - ++theIter; - theC1Value = *theIter; - ++theIter; - - if (theIndex == theNumKeys - 1) { - // Last keyframe - theC2Time = 0.0f; - theC2Value = 0.0f; - } else { - theC2Time = *(theIter + 2) * 1000.0f; // access the next inTangentTime - theC2Value = *(theIter + 3); // access the next inTangentValue - } - - if (inIsRotation) { - TORAD(theValue); - TORAD(theC1Value); - TORAD(theC2Value); - } - - theBuilder.AddKey(theTime, theValue, theC1Time, theC1Value, theC2Time, theC2Value); - m_NumAnimationKeys++; - } - return TRUE; -} - -BOOL CUIPParserImpl::LoadLinearKeys(IPresentation &inPresentation, NVConstDataRef &inValues, - bool inIsRotation) -{ - QT3DS_ASSERT(inValues.size() % 2 == 0); - if (inValues.size() % 2 != 0) - return FALSE; - - const float *theIter = inValues.begin(); - - long theNumKeys = inValues.size() / 2; - float *theEaseInOutValues = new float[theNumKeys * 4]; - float *theEaseInOutPtr = theEaseInOutValues; - for (long theKeyIndex = 0; theKeyIndex < theNumKeys; ++theKeyIndex) { - *theEaseInOutPtr++ = *theIter++; - *theEaseInOutPtr++ = *theIter++; - *theEaseInOutPtr++ = 0.0f; - *theEaseInOutPtr++ = 0.0f; - } - - NVConstDataRef theFloatValues = - NVConstDataRef(theEaseInOutValues, theNumKeys * 4); - BOOL theStatus = LoadEaseInOutKeys(inPresentation, theFloatValues, inIsRotation); - - delete[] theEaseInOutValues; - - return theStatus; -} - -CUIPParserImpl::SEaseInEaseOutKeyframe CUIPParserImpl::ParseEaseInOutKey(const float *&inFloatIter) -{ - CUIPParserImpl::SEaseInEaseOutKeyframe theKeyframe; - theKeyframe.m_Time = *inFloatIter; - ++inFloatIter; - theKeyframe.m_Value = *inFloatIter; - ++inFloatIter; - theKeyframe.m_EaseIn = *inFloatIter; - ++inFloatIter; - theKeyframe.m_EaseOut = *inFloatIter; - ++inFloatIter; - return theKeyframe; -} - -BOOL CUIPParserImpl::LoadEaseInOutKeys(IPresentation &inPresentation, - NVConstDataRef &inValues, bool inIsRotation) -{ - QT3DS_ASSERT(inValues.size() % 4 == 0); - if (inValues.size() % 4 != 0) - return FALSE; - - long theNumKeys = inValues.size() / 4; - - float *theBezierValues = new float[theNumKeys * 6]; - float *theBezierPtr = theBezierValues; - - SEaseInEaseOutKeyframe thePreviousKeyframe; - thePreviousKeyframe.m_Value = 0.0f; - SEaseInEaseOutKeyframe theCurrentKeyframe; - theCurrentKeyframe.m_Value = 0.0f; - SEaseInEaseOutKeyframe theNextKeyframe; - theNextKeyframe.m_Value = 0.0f; - - const float *theIter = inValues.begin(); - - if (theNumKeys > 0) { - theCurrentKeyframe = ParseEaseInOutKey(theIter); - float *theNextValuePtr = NULL; - float theNextValue; - - if (theNumKeys > 1) { - theNextKeyframe = ParseEaseInOutKey(theIter); - theNextValue = theNextKeyframe.m_Value; - theNextValuePtr = &theNextValue; - } - CreateBezierKeyframeFromEaseInEaseOutKeyframe(NULL, theCurrentKeyframe, theNextValuePtr, - theBezierPtr); - } - - for (long theKeyIndex = 1; theKeyIndex < theNumKeys; ++theKeyIndex) { - thePreviousKeyframe = theCurrentKeyframe; - theCurrentKeyframe = theNextKeyframe; - - float theLastValue = thePreviousKeyframe.m_Value; - float *theNextValuePtr = NULL; - float theNextValue; - if (theKeyIndex + 1 < theNumKeys) { - theNextKeyframe = ParseEaseInOutKey(theIter); - theNextValue = theNextKeyframe.m_Value; - theNextValuePtr = &theNextValue; - } - CreateBezierKeyframeFromEaseInEaseOutKeyframe(&theLastValue, theCurrentKeyframe, - theNextValuePtr, theBezierPtr); - } - - NVConstDataRef theFloatValues = NVConstDataRef(theBezierValues, theNumKeys * 6); - BOOL theStatus = LoadBezierKeys(inPresentation, theFloatValues, inIsRotation); - - delete[] theBezierValues; - return theStatus; -} - -inline float AnimationClamp(float inLowerBound, float inUpperBound, float inValue) -{ - if (inValue < inLowerBound) - return inLowerBound; - if (inValue > inUpperBound) - return inUpperBound; - return inValue; -} - -void CUIPParserImpl::CreateBezierKeyframeFromEaseInEaseOutKeyframe( - float *inPreviousValue, SEaseInEaseOutKeyframe &inCurrent, float *inNextValue, - float *&outBezierValues) -{ - float theValue = inCurrent.m_Value; - float theSeconds = inCurrent.m_Time; - float inSeconds = 0.f; - float inValue = 0.f; - float outSeconds = 0.f; - float outValue = 0.f; - const double oneThird = 1.0 / 3.0; - if (inPreviousValue) { - float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseIn / 100.f); - double theAmount = 1.0f - thePercent * oneThird; - inValue = *inPreviousValue + (float)(((inCurrent.m_Value - *inPreviousValue) * theAmount)); - } - if (inNextValue) { - float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseOut / 100.f); - double theAmount = thePercent * oneThird; - outValue = (float)(inCurrent.m_Value + ((*inNextValue - inCurrent.m_Value) * theAmount)); - } - - *outBezierValues++ = theSeconds; - *outBezierValues++ = theValue; - *outBezierValues++ = inSeconds; - *outBezierValues++ = inValue; - *outBezierValues++ = outSeconds; - *outBezierValues++ = outValue; -} - -BOOL CUIPParserImpl::ProcessSlideAnimAction(IPresentation &inPresentation, eastl::string &inSlideId, - bool inMaster, qt3dsdm::IDOMReader &inReader) -{ - IDOMReader::Scope __animationScope(inReader); - - BOOL theStatus = true; - - for (BOOL theResult = inReader.MoveToFirstChild("Action"); theResult; - theResult = inReader.MoveToNextSibling("Action")) { - // Get the active flag - const char *theEyeball; - bool theActiveFlag = - !(inMaster || (inReader.Att("eyeball", theEyeball) && AreEqual(theEyeball, "False"))); - theStatus &= AddSlideAction(inPresentation, inSlideId, theActiveFlag, inReader); - } - - return theStatus; -} - -BOOL CUIPParserImpl::AddSlideAction(IPresentation &, eastl::string &inSlideId, bool inActive, - qt3dsdm::IDOMReader &inReader) -{ - SParseSlide *theSlide = m_ParseSlideManager.FindSlide(inSlideId.c_str()); - if (theSlide == NULL) { - QT3DS_ASSERT(false); - return false; - } - - // Get the Action id - const char *theRef; - if (inReader.Att("ref", theRef)) { - theRef++; // remove the '#' - SParseSlideActionEntry *theEntry = m_ParseSlideManager.FindAction(*theSlide, theRef); - if (theEntry == NULL) { - QT3DS_ASSERT(false); - return false; - } - for (qt3ds::QT3DSI32 actIdx = 0; actIdx < theEntry->m_ActionCount; ++actIdx) { - if (theEntry->m_Actions[actIdx]) - theEntry->m_Actions[actIdx]->m_Active = inActive ? 1 : 0; - } - } else { - const char8_t *theActionId; - inReader.Att("id", theActionId); - SParseSlideActionEntry *theEntry = m_ParseSlideManager.FindAction(*theSlide, theActionId); - QT3DS_ASSERT(theEntry); - // Check to ensure this action was created. - (void)theEntry; - } - - return TRUE; -} - -bool CUIPParserImpl::IsStringType(ERuntimeDataModelDataType inDataType) -{ - if (inDataType == ERuntimeDataModelDataTypeStringRef - || inDataType == ERuntimeDataModelDataTypeString - || inDataType == ERuntimeDataModelDataTypeObjectRef) - return true; - return false; -} - -SElementData *CUIPParserImpl::GetElementData(TStrType inElementName) -{ - return m_ParseElementManager.FindElementData(inElementName); -} - -//============================================================================== -/** - * Helper function to to get the SElement object from the element name - */ -SElementData *CUIPParserImpl::GetElementData(const char8_t *inElementName) -{ - const char8_t *theElementName(inElementName); - if (!IsTrivial(inElementName) && inElementName[0] == '#') - ++theElementName; - return GetElementData(m_MetaData.Register(theElementName)); -} - -SElement *CUIPParserImpl::GetElement(const char8_t *inElementName) -{ - SElementData *theData(GetElementData(inElementName)); - if (theData) - return theData->m_Element; - return NULL; -} - -SElementData *CUIPParserImpl::ParseObjectRef(const eastl::string &inObjectPath, - const char8_t *inOwnerId) -{ - TStrType theId(ParseObjectRefId(inObjectPath, inOwnerId)); - return GetElementData(theId); -} - -TStrType CUIPParserImpl::ParseObjectRefId(const eastl::string &inObjectPath, - const char8_t *inOwnerId) -{ - return m_ObjectRefHelper->ParseObjectRefId(inObjectPath, inOwnerId); -} - -SElementAndType CUIPParserImpl::GetElementForID(const char *inElementName) -{ - SElementData *theData = m_ParseElementManager.FindElementData(inElementName); - if (theData == NULL) - return SElementAndType(UIPElementTypes::Unknown, NULL); - - qt3dsdm::ComposerObjectTypes::Enum theComposerType( - qt3dsdm::ComposerObjectTypes::Convert(theData->m_Type.c_str())); - UIPElementTypes::Enum theUIPType(UIPElementTypes::Unknown); - switch (theComposerType) { - case qt3dsdm::ComposerObjectTypes::Scene: - theUIPType = UIPElementTypes::Scene; - break; - case qt3dsdm::ComposerObjectTypes::Layer: - theUIPType = UIPElementTypes::Layer; - break; - case qt3dsdm::ComposerObjectTypes::Group: - theUIPType = UIPElementTypes::Group; - break; - case qt3dsdm::ComposerObjectTypes::Component: - theUIPType = UIPElementTypes::Component; - break; - case qt3dsdm::ComposerObjectTypes::Camera: - theUIPType = UIPElementTypes::Camera; - break; - case qt3dsdm::ComposerObjectTypes::Light: - theUIPType = UIPElementTypes::Light; - break; - case qt3dsdm::ComposerObjectTypes::Model: - theUIPType = UIPElementTypes::Model; - break; - case qt3dsdm::ComposerObjectTypes::Material: - theUIPType = UIPElementTypes::Material; - break; - case qt3dsdm::ComposerObjectTypes::Image: - theUIPType = UIPElementTypes::Image; - break; - case qt3dsdm::ComposerObjectTypes::Behavior: - theUIPType = UIPElementTypes::Behavior; - break; - case qt3dsdm::ComposerObjectTypes::Text: - theUIPType = UIPElementTypes::Text; - break; - case qt3dsdm::ComposerObjectTypes::Effect: - theUIPType = UIPElementTypes::Effect; - break; - case qt3dsdm::ComposerObjectTypes::CustomMaterial: - theUIPType = UIPElementTypes::CustomMaterial; - break; - case qt3dsdm::ComposerObjectTypes::ReferencedMaterial: - theUIPType = UIPElementTypes::ReferencedMaterial; - break; - case qt3dsdm::ComposerObjectTypes::RenderPlugin: - theUIPType = UIPElementTypes::RenderPlugin; - break; - case qt3dsdm::ComposerObjectTypes::Path: - theUIPType = UIPElementTypes::Path; - break; - case qt3dsdm::ComposerObjectTypes::PathAnchorPoint: - theUIPType = UIPElementTypes::PathAnchorPoint; - break; - case qt3dsdm::ComposerObjectTypes::SubPath: - theUIPType = UIPElementTypes::PathSubPath; - break; - default: - QT3DS_ASSERT(false); - break; - } - return SElementAndType(theUIPType, theData->m_Element); -} - -eastl::string CUIPParserImpl::ResolveReference(const char *inStringId, const char *inReference) -{ - SElementData *theData = ParseObjectRef(inReference, inStringId); - if (theData) { - return theData->m_Id.c_str(); - } - return eastl::string(); -} - -IRuntimeMetaData &CUIPParserImpl::GetMetaData() -{ - return m_MetaData; -} - -IUIPParser &IUIPParser::Create(const QString &inFileName, IRuntimeMetaData &inMetaData, - IInputStreamFactory &inFactory, - qt3ds::foundation::IStringTable &inStrTable) -{ - CUIPParserImpl &retval = *new CUIPParserImpl(inFileName, inMetaData, inFactory, inStrTable); - return retval; -} -} diff --git a/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserObjectRefHelper.cpp b/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserObjectRefHelper.cpp deleted file mode 100644 index 19af2a9d..00000000 --- a/src/Runtime/Source/UIPParser/Source/Qt3DSUIPParserObjectRefHelper.cpp +++ /dev/null @@ -1,1005 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "RuntimePrefix.h" -#ifdef EA_PLATFORM_WINDOWS -#pragma warning(disable : 4100) // std::variant -#pragma warning(disable : 4396) // specializer warning nonsense -#endif - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSUIPParserObjectRefHelper.h" - -#include "Qt3DSDMPrefix.h" -#include "Qt3DSDMXML.h" -#include "Qt3DSMetadata.h" -using namespace qt3dsdm; - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -static const char PATH_DELIMITER = '.'; // can only be single char! -static const char PATH_LINE_END = '\n'; - -//============================================================================== -/** - * Constructor - */ -CUIPParserObjectRefHelper::CUIPParserObjectRefHelper(IRuntimeMetaData &inMetaData) - : m_MetaData(inMetaData) - , m_MaterialStr(m_MetaData.Register("Material")) -{ - BuildImageNamePropertyList(); - - if (m_LayerImageIdToNameMap.empty()) { - { - TLightProbeAndNamePair theNamePair = - eastl::make_pair("Layer_lightprobe", "lightprobe"); - m_LayerImageIdToNameMap.insert(theNamePair); - } - { - TLightProbeAndNamePair theNamePair = - eastl::make_pair("Layer_lightprobe2", "lightprobe2"); - m_LayerImageIdToNameMap.insert(theNamePair); - } - } -} - -//============================================================================== -/** - * Destructor - */ -CUIPParserObjectRefHelper::~CUIPParserObjectRefHelper() -{ - // Delete SGraphNode - for (TGraphNodeMap::iterator theIter = m_GraphNodeMap.begin(); theIter != m_GraphNodeMap.end(); - ++theIter) - delete theIter->second; - m_GraphNodeMap.clear(); - m_RootNode = NULL; -} - -namespace { - void StoreTopLevelAliasAttributes( - IDOMReader &inReader, - eastl::vector> &copiedAttributes) - { - for (eastl::pair att = inReader.GetNarrowFirstAttribute(); - !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { - if (!AreEqual(att.first, "scale") && !AreEqual(att.first, "position") - && !AreEqual(att.first, "rotation") && !AreEqual(att.first, "pivot") - && !AreEqual(att.first, "endtime") && !AreEqual(att.first, "eyeball") - && !AreEqual(att.first, "ref") && !AreEqual(att.first, "id") - && !AreEqual(att.first, "name") && !AreEqual(att.first, "orientation") - && !AreEqual(att.first, "rotationorder")) // note that sourcepath does come through. - { - copiedAttributes.push_back(eastl::make_pair(att.first, att.second)); - } - } - } -} - -void CUIPParserObjectRefHelper::CacheGraph(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter) -{ - { - // First, we parse Graph section to build the scene graph - IDOMReader::Scope __graphScope(inReader); - inReader.MoveToFirstChild("Graph"); - CacheSceneGraph(inReader); - } - void *logicScopeItem = NULL; - { - // Next, we parse Logic section to update the node name and image information - IDOMReader::Scope __logicScope(inReader); - inReader.MoveToFirstChild("Logic"); - logicScopeItem = inReader.GetScope(); - CacheStateGraph(inReader); - } - if (m_SceneGraphAliasList.empty() == false) { - IDOMReader::Scope __aliasScope(inReader); - // Now we expand aliases - eastl::hash_map oldToNewIdMap; - std::shared_ptr theFactory = inWriter.GetFactory(); - std::shared_ptr theStrTable = inReader.GetStringTable(); - qt3dsdm::SDOMElement *theSlidesRoot = theFactory->NextElement("AliasSlides"); - eastl::pair, std::shared_ptr> - slideWriterReaderPair = - qt3dsdm::IDOMWriter::CreateDOMWriter(theFactory, *theSlidesRoot, theStrTable); - std::shared_ptr slideWriter = slideWriterReaderPair.first; - - { - IDOMReader::Scope __loopScope(inReader); - for (QT3DSU32 idx = 0, end = m_SceneGraphAliasList.size(); idx < end; ++idx) { - inReader.SetScope(m_SceneGraphAliasList[idx]); - const char8_t *reference; - SGraphNode *referencedNode = NULL; - const char8_t *theIdStr; - inReader.Att("id", theIdStr); - SGraphNode *aliasNode = NULL; - TGraphNodeMap::iterator iter = m_GraphNodeMap.find(m_MetaData.Register(theIdStr)); - if (iter != m_GraphNodeMap.end()) - aliasNode = iter->second; - - if (inReader.UnregisteredAtt("referencednode", reference)) { - TStrType theSourceElemId = ParseObjectRefId(reference, theIdStr); - iter = m_GraphNodeMap.find(theSourceElemId); - if (iter != m_GraphNodeMap.end()) - referencedNode = iter->second; - } - if (referencedNode == NULL || aliasNode == NULL) { - QT3DS_ASSERT(false); - continue; - } - inReader.SetScope(referencedNode->m_ReaderContext); - oldToNewIdMap.clear(); - std::shared_ptr theFactory = inWriter.GetFactory(); - std::shared_ptr theStrTable = inReader.GetStringTable(); - qt3dsdm::SDOMElement *theRoot = theFactory->NextElement(inReader.GetElementName()); - std::shared_ptr copyWriter = - qt3dsdm::IDOMWriter::CreateDOMWriter(theFactory, *theRoot, theStrTable).first; - - // Step one is just to copy the scene graph generating ids. - SGraphNode *theParent = aliasNode->m_Parent; - aliasNode->m_Class = referencedNode->m_Class; - aliasNode->m_Type = referencedNode->m_Type; - // Copy the alias id - copyWriter->Att("id", theIdStr); - eastl::vector> copiedAttributes; - StoreTopLevelAliasAttributes(inReader, copiedAttributes); - for (QT3DSU32 idx = 0, end = copiedAttributes.size(); idx < end; ++idx) { - copyWriter->Att(copiedAttributes[idx].first.c_str(), - copiedAttributes[idx].second.c_str()); - } - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "Alias")) - continue; - qt3dsdm::IDOMReader::Scope __loopScoper(inReader); - qt3dsdm::IDOMWriter::Scope writerScope(*copyWriter, - inReader.GetNarrowElementName()); - CopySceneGraph(inReader, *copyWriter, *slideWriter, oldToNewIdMap, - aliasNode->m_Name.c_str(), theIdStr, *aliasNode); - } - if (referencedNode->m_MasterSlide) { - inReader.SetScope(referencedNode->m_MasterSlide); - CopyStates(inReader, *slideWriter, oldToNewIdMap, aliasNode->m_Name.c_str(), - theIdStr); - } - // Set the scope to point at the alias node. - inReader.SetScope(aliasNode->m_ReaderContext); - inWriter.ReplaceCurrent(*theRoot); - // Now find the owning component. - SGraphNode *theComponent = theParent; - while (theComponent && theComponent->m_MasterSlide == NULL) - theComponent = theComponent->m_Parent; - - if (theComponent && theComponent->m_MasterSlide) { - inReader.SetScope(theComponent->m_MasterSlide); - // Copy any state commands that have entries in the old to new map. - CopyStateCommands(inReader, inWriter, oldToNewIdMap, aliasNode->m_Name.c_str(), - referencedNode->m_Id, theIdStr); - } else { - QT3DS_ASSERT(false); - } - } - } // End of loop scope. - - { - // Next, we parse Logic section to update the node name and image information - { - IDOMReader::Scope __logicScope(inReader); - inReader.SetScope(theSlidesRoot); - // Cache the new items and their names and such. - CacheStateGraph(inReader); - } - - inReader.MoveToFirstChild("Logic"); - inWriter.AppendChildren(*theSlidesRoot); - } - - /* -#if defined _DEBUG && defined _WIN32 - { - qt3dsdm::SDOMElement* theElem = inWriter.GetTopElement(); - { - qt3ds::foundation::CFileSeekableIOStream theWriter( "c:\\temp.xml", -FileWriteFlags() ); - qt3dsdm::CDOMSerializer::Write( *theElem, theWriter ); - } - } -#endif - */ - } - -} - -void CUIPParserObjectRefHelper::CacheSceneGraph(IDOMReader &inReader, SGraphNode *inParent) -{ - IDOMReader::Scope __childScope(inReader); - - // build out the graph. - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "Alias")) { - CacheSceneGraphNode(inReader, inParent); - m_SceneGraphAliasList.push_back(inReader.GetScope()); - } else { - SGraphNode &theNode(CacheSceneGraphNode(inReader, inParent)); - CacheSceneGraph(inReader, &theNode); - } - } -} - -CUIPParserObjectRefHelper::SGraphNode & -CUIPParserObjectRefHelper::CacheSceneGraphNode(qt3dsdm::IDOMReader &inReader, SGraphNode *inParent) -{ - SGraphNode *theNode = new SGraphNode(); - const char8_t *theIdStr; - inReader.Att("id", theIdStr); - theNode->m_Id = m_MetaData.Register(theIdStr); - theNode->m_Type = m_MetaData.Register(inReader.GetNarrowElementName()); - const char8_t *theClassStr; - inReader.Att("class", theClassStr); - theNode->m_Class = m_MetaData.Register(theClassStr); - const char *theNameStr; - theNode->m_ReaderContext = inReader.GetScope(); - - if (inParent && inParent->m_Type == m_MetaData.Register("Layer") - && theNode->m_Type == m_MetaData.Register("Image")) { - TLightProbeIdToNameMap::iterator theFind = m_LayerImageIdToNameMap.find(theIdStr); - if (theFind != m_LayerImageIdToNameMap.end()) - theNode->m_Name = m_MetaData.Register(theFind->second.c_str()); - } else if (!inReader.Att("name", theNameStr)) { - Option theNameStrOpt = m_MetaData.GetPropertyValueString( - theNode->m_Type, m_MetaData.Register("name"), theNode->m_Class); - if (theNameStrOpt.hasValue()) - theNode->m_Name = m_MetaData.Register(theNameStrOpt->c_str()); - } else - theNode->m_Name = m_MetaData.Register(theNameStr); - - if (inParent) { - theNode->m_Parent = inParent; - inParent->m_Children.push_back(theNode); - } else { - m_RootNode = theNode; - } - - m_GraphNodeMap[theNode->m_Id] = theNode; - return *theNode; -} - -void CUIPParserObjectRefHelper::CacheStateGraph(IDOMReader &inReader) -{ - IDOMReader::Scope __childScope(inReader); - const char8_t *component; - if (inReader.UnregisteredAtt("component", component)) { - TGraphNodeMap::iterator iter = m_GraphNodeMap.find(m_MetaData.Register(component + 1)); - if (iter != m_GraphNodeMap.end()) { - iter->second->m_MasterSlide = inReader.GetScope(); - } - } - - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "State")) - CacheStateGraph(inReader); - else if (AreEqual(inReader.GetNarrowElementName(), "Add") - || AreEqual(inReader.GetNarrowElementName(), "Set")) { - const char *theRef; - const char *theName; - if (inReader.Att("ref", theRef)) { - theRef++; // remove the '#' - SGraphNode *theNode = GetNode(theRef); - if (theNode) { - // Overwrite the name. This assumes that "name" property is always linked. - if (inReader.Att("name", theName)) { - theNode->m_Name = m_MetaData.Register(theName); - } - - // Special case for material. Image properties refer to instances. - // For example: Scene.Layer.Rectangle.Material.diffusemap.rotationuv -> - // diffusemap refers to Image instance - // So if we find image instance, overwrite the name of the image with the - // property name. - // This assumes that user can't rename image property - if (theNode->m_Type == m_MaterialStr && !theNode->m_Children.empty()) { - for (TImageNamePropertyList::iterator theProp = - m_ImageNamePropertyList.begin(); - theProp != m_ImageNamePropertyList.end(); ++theProp) { - const char *theImageInstance; - if (inReader.Att(theProp->c_str(), theImageInstance)) { - ++theImageInstance; // remove the '#' - SGraphNode *theImageNode = GetNode(theImageInstance); - QT3DS_ASSERT(theImageNode && theImageNode->m_Parent == theNode); - if (theImageNode) - theImageNode->m_Name = *theProp; - } - } - } - - } - } - } - } -} - -void CUIPParserObjectRefHelper::CopySceneGraph(qt3dsdm::IDOMReader &inReader, - qt3dsdm::IDOMWriter &inWriter, - qt3dsdm::IDOMWriter &inSlideWriter, - TStrToStrMap &inMap, const char *inAliasName, - const char *inAliasId, SGraphNode &inParent) -{ - qt3dsdm::IDOMReader::Scope __graphScope(inReader); - // Assume the element itself is already copied. - // Run through attributes and duplicate them, but for any id attributes generate a new id. - const char8_t *tempItem; - if (!inReader.Att("id", tempItem)) { - QT3DS_ASSERT(false); - return; - } - SGraphNode *theParent = &inParent; - eastl::string idGenerator(inAliasName); - idGenerator.append("-"); - idGenerator.append(tempItem); - while (m_GraphNodeMap.find(m_MetaData.Register(idGenerator.c_str())) != m_GraphNodeMap.end()) - idGenerator.append("_"); - inWriter.Att("id", idGenerator.c_str()); - TStrType srcId = m_MetaData.Register(tempItem); - TStrType newId = m_MetaData.Register(idGenerator.c_str()); - inMap[srcId] = newId; - SGraphNode *srcNode = m_GraphNodeMap.find(srcId)->second; - SGraphNode *newNode = new SGraphNode(); - newNode->m_Class = srcNode->m_Class; - newNode->m_Id = newId; - newNode->m_Name = srcNode->m_Name; - newNode->m_Type = srcNode->m_Type; - newNode->m_Parent = &inParent; - theParent = newNode; - m_GraphNodeMap[newId] = newNode; - inParent.m_Children.push_back(newNode); - - { - qt3dsdm::IDOMReader::Scope __childrenScope(inReader); - - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "Alias")) - continue; - qt3dsdm::IDOMWriter::Scope __newNode(inWriter, inReader.GetNarrowElementName()); - CopySceneGraph(inReader, inWriter, inSlideWriter, inMap, inAliasName, inAliasId, - *theParent); - } - } - TGraphNodeMap::iterator iter = m_GraphNodeMap.find(m_MetaData.Register(tempItem)); - if (iter == m_GraphNodeMap.end()) { - QT3DS_ASSERT(false); - return; - } - SGraphNode *targetNode = iter->second; - - for (eastl::pair att = inReader.GetNarrowFirstAttribute(); - !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { - if (AreEqual(att.first, "id")) - continue; - Q3DStudio::ERuntimeDataModelDataType theDataType = m_MetaData.GetPropertyType( - targetNode->m_Type, m_MetaData.Register(att.first), targetNode->m_Class); - // Ensure we use new ids for this datatype. This ensures that we go - if (theDataType == ERuntimeDataModelDataTypeLong4) { - TStrToStrMap::iterator aliasIdName = inMap.find(m_MetaData.Register(att.second)); - if (aliasIdName != inMap.end()) - inWriter.Att(att.first, aliasIdName->second.c_str()); - else { - QT3DS_ASSERT(false); - } - } else - inWriter.Att(att.first, att.second); - } - if (targetNode->m_MasterSlide) { - inReader.SetScope(targetNode->m_MasterSlide); - CopyStates(inReader, inSlideWriter, inMap, inAliasName, inAliasId); - } -} - -void CUIPParserObjectRefHelper::CopyStates(qt3dsdm::IDOMReader &inReader, - qt3dsdm::IDOMWriter &inSlideWriter, TStrToStrMap &inMap, - const char *inAliasName, const char *inAliasId) -{ - qt3dsdm::IDOMReader::Scope __stateScope(inReader); - qt3dsdm::IDOMWriter::Scope stateScope(inSlideWriter, "State"); - CopyAttributes(inReader, inSlideWriter, inMap, inAliasName, inAliasId); - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - if (AreEqual(inReader.GetNarrowElementName(), "State")) - CopyStates(inReader, inSlideWriter, inMap, inAliasName, inAliasId); - else { - CopyHierarchy(inReader, inSlideWriter, inMap, inAliasName, inAliasId); - } - } -} - -eastl::pair CUIPParserObjectRefHelper::ProcessAliasAttribute( - const char8_t *inObjId, eastl::pair inAttribute, - eastl::string &ioStrBuilder, TStrToStrMap &inMap) -{ - inObjId = nonNull(inObjId); - if (inObjId[0] == '#') - ++inObjId; - SGraphNode *theNode = GetNode(nonNull(inObjId)); - if (theNode == NULL) - return inAttribute; - const char8_t *propName = inAttribute.first; - const char8_t *propValue = inAttribute.second; - ERuntimeAdditionalMetaDataType thePropertyType = m_MetaData.GetAdditionalType( - theNode->m_Type, m_MetaData.Register(propName), theNode->m_Class); - if (thePropertyType == ERuntimeAdditionalMetaDataTypeImage - || thePropertyType == ERuntimeAdditionalMetaDataTypeObjectRef) { - propValue = nonNull(propValue); - if (propValue[0] == '#') - ++propValue; - TStrToStrMap::iterator iter = inMap.find(m_MetaData.Register(propValue)); - if (iter != inMap.end()) { - ioStrBuilder.assign("#"); - ioStrBuilder.append(iter->second); - propValue = ioStrBuilder.c_str(); - } else - propValue = inAttribute.second; - } - return eastl::make_pair(propName, propValue); -} - -void CUIPParserObjectRefHelper::CopyAttributes(qt3dsdm::IDOMReader &inReader, - qt3dsdm::IDOMWriter &inSlideWriter, - TStrToStrMap &inMap, const char *inAliasName, - const char *inAliasId) -{ - eastl::string builder; - const char8_t *elemId = ""; - for (eastl::pair att = inReader.GetNarrowFirstAttribute(); - !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { - if (AreEqual(att.first, "component")) { - TStrToStrMap::iterator iter = inMap.find(m_MetaData.Register(att.second + 1)); - builder.assign("#"); - if (iter != inMap.end()) { - builder.append(iter->second); - } else { - builder.append(inAliasId); - } - inSlideWriter.Att(att.first, builder.c_str()); - } else if (AreEqual(att.first, "id")) { - builder.assign(inAliasName); - builder.append("-"); - builder.append(att.second); - // cannot be - while (m_SlideIdSet.find(m_MetaData.Register(builder.c_str())) != m_SlideIdSet.end()) - builder.append("_"); - inSlideWriter.Att(att.first, builder.c_str()); - m_SlideIdSet.insert(m_MetaData.Register(builder.c_str())); - inMap[m_MetaData.Register(att.second)] = m_MetaData.Register(builder.c_str()); - } else if (AreEqual(att.first, "ref")) { - const char8_t *refItem = att.second; - if (!isTrivial(refItem)) { - ++refItem; - elemId = refItem; - TStrToStrMap::iterator iter = inMap.find(m_MetaData.Register(refItem)); - if (iter != inMap.end()) { - builder.assign("#"); - builder.append(iter->second.c_str()); - inSlideWriter.Att("ref", builder.c_str()); - } else { - QT3DS_ASSERT(false); - } - } - } else { - att = ProcessAliasAttribute(elemId, att, builder, inMap); - inSlideWriter.Att(att.first, att.second); - } - } -} - -void CUIPParserObjectRefHelper::CopyHierarchy(qt3dsdm::IDOMReader &inReader, - qt3dsdm::IDOMWriter &inSlideWriter, TStrToStrMap &inMap, - const char *inAliasName, const char *inAliasId) -{ - qt3dsdm::IDOMReader::Scope __commandScope(inReader); - qt3dsdm::IDOMWriter::Scope __writerScope(inSlideWriter, inReader.GetNarrowElementName()); - CopyAttributes(inReader, inSlideWriter, inMap, inAliasName, inAliasId); - const char8_t *childData; - if (inReader.Value(childData)) { - inSlideWriter.Value(childData); - } - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) - CopyHierarchy(inReader, inSlideWriter, inMap, inAliasName, inAliasId); -} - -void CUIPParserObjectRefHelper::CopyStateCommands(qt3dsdm::IDOMReader &inReader, - qt3dsdm::IDOMWriter &inWriter, - TStrToStrMap &oldToNewIdMap, - const char *inAliasName, const char *inOldId, - const char *inNewId) -{ - qt3dsdm::IDOMReader::Scope __commandScope(inReader); - qt3dsdm::SDOMElement *theSlidesRoot = NULL; - eastl::pair, std::shared_ptr> - slideWriterReaderPair; - std::shared_ptr commandWriter; - { - qt3dsdm::IDOMReader::Scope __loopScope(inReader); - eastl::vector> copiedAttributes; - void *destCommand = NULL; - eastl::string strBuilder; - for (bool success = inReader.MoveToFirstChild(); success; - success = inReader.MoveToNextSibling()) { - qt3dsdm::IDOMReader::Scope childScope(inReader); - if (AreEqual(inReader.GetNarrowElementName(), "State")) - CopyStateCommands(inReader, inWriter, oldToNewIdMap, inAliasName, inOldId, inNewId); - else { - const char8_t *refItem = ""; - if (inReader.Att("ref", refItem) && !isTrivial(refItem)) { - ++refItem; - TStrToStrMap::iterator iter = oldToNewIdMap.find(m_MetaData.Register(refItem)); - if (iter != oldToNewIdMap.end()) { - if (theSlidesRoot == NULL) { - std::shared_ptr theFactory = - inWriter.GetFactory(); - std::shared_ptr theStrTable = - inReader.GetStringTable(); - theSlidesRoot = theFactory->NextElement("AliasSlides"); - slideWriterReaderPair = qt3dsdm::IDOMWriter::CreateDOMWriter( - theFactory, *theSlidesRoot, theStrTable); - commandWriter = slideWriterReaderPair.first; - } - qt3dsdm::IDOMWriter::Scope elemScope(*commandWriter, - inReader.GetNarrowElementName()); - for (eastl::pair att = - inReader.GetNarrowFirstAttribute(); - !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { - if (AreEqual(att.first, "ref")) { - strBuilder.assign("#"); - strBuilder.append(iter->second); - commandWriter->Att("ref", strBuilder.c_str()); - } else { - - att = - ProcessAliasAttribute(refItem, att, strBuilder, oldToNewIdMap); - commandWriter->Att(att.first, att.second); - } - } - for (bool commandChild = inReader.MoveToFirstChild(); commandChild; - commandChild = inReader.MoveToNextSibling()) { - qt3dsdm::IDOMReader::Scope commandChildScope(inReader); - CopyHierarchy(inReader, *commandWriter, oldToNewIdMap, inAliasName, ""); - } - } else if (AreEqual(refItem, inOldId)) { - StoreTopLevelAliasAttributes(inReader, copiedAttributes); - } else if (AreEqual(refItem, inNewId)) - destCommand = inReader.GetScope(); - } - } - } - if (copiedAttributes.size() && destCommand) { - inReader.SetScope(destCommand); - for (QT3DSU32 idx = 0, end = copiedAttributes.size(); idx < end; ++idx) { - eastl::pair &theItem(copiedAttributes[idx]); - inWriter.Att(theItem.first.c_str(), theItem.second.c_str()); - } - } - } - if (commandWriter) - inWriter.AppendChildren(*commandWriter->GetTopElement()); -} - -CUIPParserObjectRefHelper::SGraphNode *CUIPParserObjectRefHelper::GetNode(const char *inId) -{ - if (IsTrivial(inId)) - return NULL; - if (inId[0] == '#') - ++inId; - TGraphNodeMap::iterator theIter = m_GraphNodeMap.find(m_MetaData.Register(inId)); - if (theIter != m_GraphNodeMap.end()) - return theIter->second; - return NULL; -} - -CUIPParserObjectRefHelper::SGraphNode *CUIPParserObjectRefHelper::GetNode(eastl::string inId) -{ - return GetNode(inId.c_str()); -} - -CUIPParserObjectRefHelper::TStrType CUIPParserObjectRefHelper::GetName(const eastl::string &inId) -{ - SGraphNode *theNode = GetNode(inId.c_str()); - if (theNode) - return theNode->m_Name; - QT3DS_ASSERT(false); - return m_MetaData.Register(inId.c_str()); -} - -CUIPParserObjectRefHelper::TStrType CUIPParserObjectRefHelper::GetType(const eastl::string &inId) -{ - SGraphNode *theNode = GetNode(inId.c_str()); - if (theNode) - return theNode->m_Type; - QT3DS_ASSERT(false); - return m_MetaData.Register(inId.c_str()); -} - -CUIPParserObjectRefHelper::TStrType CUIPParserObjectRefHelper::GetClass(const eastl::string &inId) -{ - SGraphNode *theNode = GetNode(inId.c_str()); - if (theNode) - return theNode->m_Class; - QT3DS_ASSERT(false); - return m_MetaData.Register(inId.c_str()); -} - -CUIPParserObjectRefHelper::TStrType -CUIPParserObjectRefHelper::ParseObjectRefId(const eastl::string &inObjectPath, - const char8_t *inOwnerId) -{ - if (inObjectPath.empty()) { - QT3DS_ASSERT(false); - return TStrType(); - } else if (inObjectPath[0] == '#') { - // Absolute path - return m_MetaData.Register(inObjectPath.substr(1).c_str()); - } else { - // Relative path - SGraphNode *theNode = GetNode(inOwnerId); - - // Split the string based on PATH_DELIMITER - eastl::string theStr = inObjectPath; - eastl::string theCurrentPart; - eastl::string::size_type thePos; - while (theNode) { - thePos = theStr.find(PATH_DELIMITER); - theCurrentPart = theStr.substr(0, thePos); - - if (theCurrentPart == "parent") { - theNode = theNode->m_Parent; - } else if (theCurrentPart == "this") { - // Do nothing because theNode points to itself - } else if (theCurrentPart == "Scene") { - theNode = m_RootNode; - } else { - SGraphNode *theFoundChild = NULL; - for (QT3DSU32 childIdx = 0; - childIdx < theNode->m_Children.size() && theFoundChild == NULL; ++childIdx) { - if (AreEqual(theNode->m_Children[childIdx]->m_Name, theCurrentPart.c_str())) - theFoundChild = theNode->m_Children[childIdx]; - } - theNode = theFoundChild; - } - - if (thePos == eastl::string::npos) - break; - - // Move on to the next token - theStr = theStr.substr(thePos + 1); - } - - if (theNode) - return theNode->m_Id; - - return TStrType(); - } -} - -eastl::string CUIPParserObjectRefHelper::BuildReferenceString(eastl::string inObjectPath) -{ - if (inObjectPath.empty()) { - // QT3DS_ASSERT( false ); - return ""; - } else if (inObjectPath[0] == '#') { - // Absolute path - return BuildAbsoluteReferenceString(inObjectPath.substr(1)); - } else { - // Relative path - return inObjectPath; - } -} - -eastl::string CUIPParserObjectRefHelper::BuildAbsoluteReferenceString(eastl::string inId) -{ - return BuildAbsoluteReferenceString(GetNode(inId)); -} - -eastl::string CUIPParserObjectRefHelper::BuildAbsoluteReferenceString(SGraphNode *inNode) -{ - if (inNode == NULL) - return ""; - - eastl::string theNameStart; - eastl::string theNameEnd(inNode->m_Name); - - SGraphNode *theParent = inNode->m_Parent; - if (theParent) { - theNameStart.assign(BuildAbsoluteReferenceString(theParent)); - theNameStart.append("."); - } - theNameStart += theNameEnd; - return theNameStart; -} - -void CUIPParserObjectRefHelper::MarkAllReferencedAttributes( - eastl::string inId, const eastl::vector &inReferences, - qt3dsdm::IDOMReader &inReader, SParseElementManager &outIdAttributesMap) -{ - IDOMReader::Scope __scope(inReader); - eastl::string theReferencesTokenizer; - eastl::string theCurrentReference; - eastl::string theReferenceTokenizer; - eastl::string theCurrentString; - eastl::string::size_type startPos = 0; - eastl::string::size_type endPos = 0; - eastl::string::size_type theReferencesTokenizerPos = 0; - eastl::string::size_type theReferenceTokenizerPos = 0; - SGraphNode *theBaseInstance = GetNode(inId); - SGraphNode *theCurrentInstance = theBaseInstance; - eastl::vector theInstanceList; - - for (QT3DSU32 theRefIdx = 0, theRefEnd = inReferences.size(); theRefIdx < theRefEnd; ++theRefIdx) { - // Split the string based on PATH_LINE_END - theReferencesTokenizer = inReferences[theRefIdx]; - theReferencesTokenizerPos = 0; - while (theReferencesTokenizerPos != eastl::string::npos - && !theReferencesTokenizer.empty()) { - theCurrentInstance = theBaseInstance; - theReferencesTokenizerPos = theReferencesTokenizer.find(PATH_LINE_END); - theCurrentReference = theReferencesTokenizer.substr(0, theReferencesTokenizerPos); - - // Move to the next token - theReferencesTokenizer = theReferencesTokenizer.substr(theReferencesTokenizerPos + 1); - - // trim whitespace from the beginning and the end of the string - startPos = theCurrentReference.find_first_not_of("\n\r\t "); - endPos = theCurrentReference.find_last_not_of("\n\r\t "); - if (startPos != eastl::string::npos) - theCurrentReference = theCurrentReference.substr(startPos, endPos - startPos + 1); - - // Split the string based on PATH_DELIMITER - theReferenceTokenizer = theCurrentReference; - theReferenceTokenizerPos = 0; - theInstanceList.clear(); - while (theReferenceTokenizerPos != eastl::string::npos - && !theReferenceTokenizer.empty()) { - theReferenceTokenizerPos = theReferenceTokenizer.find(PATH_DELIMITER); - theCurrentString = theReferenceTokenizer.substr(0, theReferenceTokenizerPos); - - // Move to the next token - theReferenceTokenizer = theReferenceTokenizer.substr(theReferenceTokenizerPos + 1); - - if (theReferenceTokenizerPos != eastl::string::npos) { - theCurrentInstance = GetReferenceNode(theCurrentInstance, theCurrentString, - theInstanceList, inReader); - } else { - if (theInstanceList.size() == 0 && theCurrentInstance) - theInstanceList.push_back(theCurrentInstance); - if (!MarkAttributeAsReferenced(theBaseInstance, theInstanceList, - theCurrentString, inReader, - outIdAttributesMap)) { - qCCritical(qt3ds::INVALID_OPERATION) - << "Unable to parse reference: " - << theBaseInstance->m_Id.c_str() << " : " - << theCurrentReference.c_str(); - } - } - } - } - } -} - -//============================================================================== -/** - * Helper method to find the VAsset via the name which is the child of inAsset. - */ -CUIPParserObjectRefHelper::SGraphNode * -CUIPParserObjectRefHelper::GetReferenceNode(SGraphNode *inInstance, eastl::string &inAssetName, - eastl::vector &outInstanceList, - qt3dsdm::IDOMReader &inReader) -{ - if (!inInstance) - return NULL; - - SGraphNode *theReturnInstance = NULL; - - if (inAssetName == "Scene") { - theReturnInstance = m_RootNode; - } else if (inAssetName == "parent") { - theReturnInstance = inInstance->m_Parent; - } else if (inAssetName == "children") { - outInstanceList.insert(outInstanceList.end(), inInstance->m_Children.begin(), - inInstance->m_Children.end()); - } else if (inAssetName == "descendants") { - for (SGraphNode::TGraphNodeList::iterator theChildren = inInstance->m_Children.begin(); - theChildren != inInstance->m_Children.end(); ++theChildren) { - outInstanceList.push_back(*theChildren); - GetReferenceNode(*theChildren, inAssetName, outInstanceList, inReader); - } - } else if (inAssetName[0] == '[' && inAssetName[inAssetName.length() - 1] == ']') { - // For example: [targetElement].position - // targetElement should be an Object picker specifying which element to preserve. - eastl::string theAssetName = inAssetName.substr(1, inAssetName.length() - 2); - - // Check if the target element property exists and get the property value - eastl::string theValue; - if (!inReader.Att(theAssetName.c_str(), theValue)) { - // Try to find the parent context and get the element name from there. - if (AreEqual(inReader.GetElementName(), L"Set")) { - IDOMReader::Scope __setScope(inReader); - const char8_t *refValue = ""; - inReader.Att("ref", refValue); - inReader.Leave(); - inReader.Leave(); - for (bool success = inReader.MoveToFirstChild("Add"); success; - success = inReader.MoveToNextSibling("Add")) { - const char8_t *newRef; - inReader.Att("ref", newRef); - if (AreEqual(newRef, refValue)) { - inReader.Att(theAssetName.c_str(), theValue); - break; - } - } - } - if (theValue.empty()) { - Option theRef = m_MetaData.GetPropertyValueObjectRef( - inInstance->m_Type, m_MetaData.Register(theAssetName.c_str()), - inInstance->m_Class); - if (theRef.hasValue()) - theValue = *theRef; - } - } - if (!IsTrivial(theValue.c_str())) { - // Get the target element id - eastl::string theTargetElement = - ParseObjectRefId(theValue, inInstance->m_Id.c_str()).c_str(); - if (theTargetElement != "") { - // Get the corresponding instance - theReturnInstance = GetNode(theTargetElement); - } - } - } else { - // Get the child with the specified name. - // Note that name is not unique and so this will only return the first child that matches - // the name - for (SGraphNode::TGraphNodeList::iterator theChildren = inInstance->m_Children.begin(); - theChildren != inInstance->m_Children.end(); ++theChildren) { - if (AreEqual((*theChildren)->m_Name.c_str(), inAssetName.c_str())) { - theReturnInstance = *theChildren; - break; - } - } - } - return theReturnInstance; -} - -bool CUIPParserObjectRefHelper::MarkAttributeAsReferenced( - SGraphNode *inBaseInstance, eastl::vector &inInstanceList, - eastl::string &inAttributeName, qt3dsdm::IDOMReader &inReader, - SParseElementManager &outIdAttributesMap) -{ - bool theRet(false); - eastl::vector::iterator theIter = inInstanceList.begin(); - eastl::vector::iterator theEnd = inInstanceList.end(); - for (; theIter != theEnd; ++theIter) { - SGraphNode *theCurrentInstance = *theIter; - - if (inAttributeName == "all") { - eastl::vector theProperties; - m_MetaData.GetInstanceProperties(theCurrentInstance->m_Type.c_str(), - theCurrentInstance->m_Class.c_str(), theProperties, - true); - - if (theProperties.size() > 0) { - SElementData *theData = - outIdAttributesMap.FindElementData(theCurrentInstance->m_Id.c_str()); - if (theData) { - for (QT3DSU32 theIndex = 0; theIndex < theProperties.size(); ++theIndex) - outIdAttributesMap.MarkAttributeAsReferenced( - *theData, theProperties[theIndex].c_str()); - } - theRet = true; - } - } else { - eastl::string theAttributeName = inAttributeName; - if (inAttributeName[0] == '[' && inAttributeName[inAttributeName.length() - 1] == ']') { - // For example: parent.[targetProp] - // targetProp should be a string specifying which property to preserve - theAttributeName = theAttributeName.substr(1, theAttributeName.length() - 2); - - // Get the targetProp property value from the uip file - const char *theValue; - if (inReader.Att(theAttributeName.c_str(), theValue)) { - theAttributeName = theValue; - } else { - // Query metadata value of base instance - theAttributeName = m_MetaData.GetPropertyValueString( - inBaseInstance->m_Type, m_MetaData.Register(theAttributeName.c_str()), - inBaseInstance->m_Class); - } - } - - // Check if the property exists - if (m_MetaData.IsPropertyExist(theCurrentInstance->m_Type, - m_MetaData.Register(theAttributeName.c_str()), - theCurrentInstance->m_Class)) { - MarkPreserveFlag(theCurrentInstance, theAttributeName, outIdAttributesMap); - theRet = true; - } else { - // check whether the attribute name has ".", strip those after that and try again - eastl::string::size_type theIndex = theAttributeName.rfind('.'); - if (theIndex != eastl::string::npos) { - theAttributeName = theAttributeName.substr(0, theIndex); - if (m_MetaData.IsPropertyExist(theCurrentInstance->m_Type, - m_MetaData.Register(theAttributeName.c_str()), - theCurrentInstance->m_Class)) { - MarkPreserveFlag(theCurrentInstance, theAttributeName, outIdAttributesMap); - theRet = true; - } - } - } - } - } - - return theRet; -} - -void CUIPParserObjectRefHelper::MarkPreserveFlag(SGraphNode *inInstance, eastl::string inProperty, - SParseElementManager &outIdAttributesMap) -{ - outIdAttributesMap.MarkAttributeAsReferenced(inInstance->m_Id.c_str(), inProperty.c_str()); -} - -void CUIPParserObjectRefHelper::BuildImageNamePropertyList() -{ - // Special case for material - // Material's Image properties (such as diffuse map, etc) point to Image instances - eastl::vector theProperties; - m_MetaData.GetInstanceProperties("Material", NULL, theProperties, true); - - size_t thePropertyCount = theProperties.size(); - for (QT3DSU32 thePropertyIndex = 0; thePropertyIndex < thePropertyCount; ++thePropertyIndex) { - eastl::string theProperty = theProperties[thePropertyIndex]; - ERuntimeAdditionalMetaDataType theAdditionalMetaDataType = - m_MetaData.GetAdditionalType(m_MaterialStr, m_MetaData.Register(theProperty.c_str())); - - if (theAdditionalMetaDataType == ERuntimeAdditionalMetaDataTypeImage) { - m_ImageNamePropertyList.insert(m_MetaData.Register(theProperty.c_str())); - } - } -} -} diff --git a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.cpp b/src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.cpp deleted file mode 100644 index b8e290f8..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - -#include -#include -#include -#include -#include -#include - -#define ADDRINFO struct addrinfo -#define INVALID_SOCKET -1 -#define closesocket close -#define SD_BOTH SHUT_RDWR -#define SOCKET_ERROR -1 - -#endif - -#include "SimpleTCPClientSocket.h" - -//============================================================================== -/** - * CTOR - * Accepts a buffer size for internal storage and a flag to indicate if - * Recv should return fixed sized packets or not. - */ -SimpleTCPClientSocket::SimpleTCPClientSocket(long inBufferSize, bool inWaitForFull) - : m_ClientSocket(NULL) - , m_Data(NULL) - , m_BytesRead(0) - , m_BufferSize(inBufferSize) - , m_WaitForFull(inWaitForFull) -{ - m_Data = new char[m_BufferSize]; -} - -//============================================================================== -/** - * DTOR - */ -SimpleTCPClientSocket::~SimpleTCPClientSocket() -{ - if (m_ClientSocket) - Disconnect(); - - delete[] m_Data; -} - -//============================================================================== -/** - * Initializes TCP communications. - * Needs to be called once per app. - */ -bool SimpleTCPClientSocket::Initialize() -{ -#ifdef _PCPLATFORM - WSADATA theWsaData; - - if (WSAStartup(WINSOCK_VERSION, &theWsaData)) { - // WSAStartup failed - return false; - } -#endif - return true; -} - -//============================================================================== -/** - * Deinitializes TCP communications. - * Needs to be called once per app. - */ -void SimpleTCPClientSocket::DeInitialize() -{ -#ifdef _PCPLATFORM - WSACleanup(); -#endif -} - -//============================================================================== -/** - * Attempts to connect at the specified address and port. - */ -bool SimpleTCPClientSocket::Connect(const char *inServerAddress, const char *inServerPort) -{ - bool theReturn = false; - ADDRINFO theHints; - ADDRINFO *theAddrInfo = NULL; - ADDRINFO *theAddrInfoPtr = NULL; - - memset(&theHints, 0, sizeof(theHints)); - theHints.ai_family = PF_INET; - theHints.ai_socktype = SOCK_STREAM; - - if (getaddrinfo(inServerAddress, inServerPort, &theHints, &theAddrInfo) == 0) { - for (theAddrInfoPtr = theAddrInfo; theAddrInfoPtr != NULL; - theAddrInfoPtr = theAddrInfoPtr->ai_next) { - if ((theAddrInfoPtr->ai_family == PF_INET) - || (theAddrInfoPtr->ai_family == PF_INET6)) // only want PF_INET or PF_INET6 - { - m_ClientSocket = socket(theAddrInfoPtr->ai_family, theAddrInfoPtr->ai_socktype, - theAddrInfoPtr->ai_protocol); - - if (m_ClientSocket != INVALID_SOCKET) { - if (theAddrInfoPtr->ai_socktype == SOCK_STREAM) { - if (connect(m_ClientSocket, theAddrInfoPtr->ai_addr, - theAddrInfoPtr->ai_addrlen) - == 0) { -// Set this up to be a non-blocking socket -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - int theFlags = fcntl(m_ClientSocket, F_GETFL, 0); - fcntl(m_ClientSocket, F_SETFL, theFlags | O_NONBLOCK); -#endif - -#ifdef _PCPLATFORM - u_long theBlockMode = 1; - ioctlsocket(m_ClientSocket, FIONBIO, &theBlockMode); -#endif - - theReturn = true; - break; - } - - // Connect failed - closesocket(m_ClientSocket); - } - } - } - } - } - - freeaddrinfo(theAddrInfo); - return theReturn; -} - -//============================================================================== -/** - * Disconnect and closes the TCP connection. - */ -void SimpleTCPClientSocket::Disconnect() -{ - shutdown(m_ClientSocket, SD_BOTH); - closesocket(m_ClientSocket); - m_BytesRead = 0; - m_ClientSocket = 0; -} - -//============================================================================== -/** - * Receives a data packet from the socket. - * If m_WaitForFull is true, Recv will always return 0 until it reads m_BufferSize - * bytes. - * Else, it will return the number of bytes read (if any) per call. - */ -long SimpleTCPClientSocket::Recv() -{ - long theReturnValue = 0; - - if (m_WaitForFull) { - theReturnValue = recv(m_ClientSocket, m_Data + m_BytesRead, m_BufferSize - m_BytesRead, 0); - - if (theReturnValue > 0) - m_BytesRead += theReturnValue; - - if (m_BytesRead < m_BufferSize) - theReturnValue = 0; - else { - m_BytesRead = 0; - theReturnValue = m_BufferSize; - } - } else { - theReturnValue = recv(m_ClientSocket, m_Data, m_BufferSize, 0); - if (theReturnValue == SOCKET_ERROR) - theReturnValue = 0; - } - - return theReturnValue; -} - -//============================================================================== -/** - * Sends a data packet to the socket. - * If m_WaitForFull is true, Send will always return 0 until it receives m_BufferSize - * bytes. - * Else, it will return the number of bytes sent (if any) per call. - */ -long SimpleTCPClientSocket::Send() -{ - long theReturnValue = 0; - - if (m_WaitForFull) { - theReturnValue = send(m_ClientSocket, m_Data + m_BytesSent, m_BufferSize - m_BytesSent, 0); - - if (theReturnValue > 0) - m_BytesSent += theReturnValue; - - if (m_BytesSent < m_BufferSize) - theReturnValue = 0; - else { - m_BytesSent = 0; - theReturnValue = m_BufferSize; - } - } else { - theReturnValue = send(m_ClientSocket, m_Data, m_BufferSize, 0); - if (theReturnValue == SOCKET_ERROR) - theReturnValue = 0; - } - - return theReturnValue; -} diff --git a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.h b/src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.h deleted file mode 100644 index c320f7fd..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPClientSocket.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#pragma once - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -#define SOCKET int -#endif - -#ifdef _PCPLATFORM -#include -#include -#endif - -//============================================================================== -// Creates a TCP socket to an address and port. -// Can return either fixed sized packets or variable sized ones. -//============================================================================== -class SimpleTCPClientSocket -{ -public: - SimpleTCPClientSocket(long inBufferSize, bool inWaitForFull); - ~SimpleTCPClientSocket(); - -public: - static bool Initialize(); - static void DeInitialize(); - - // Client side - bool Connect(const char *inServerAddress, const char *inServerPort); - void Disconnect(); - - // General - long Recv(); - long Send(); - - // operator char*( ){ return m_Data; } - void *GetData() { return m_Data; } - -protected: - SOCKET m_ClientSocket; - char *m_Data; - long m_BytesRead; - long m_BytesSent; - const long m_BufferSize; - bool m_WaitForFull; -}; diff --git a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.cpp b/src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.cpp deleted file mode 100644 index 44202739..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - -#include -#include -#include -#include -#include -#include - -#define ADDRINFO struct addrinfo -#define INVALID_SOCKET -1 -#define closesocket close -#define SD_BOTH SHUT_RDWR -#define SOCKET_ERROR -1 - -#endif - -#include "SimpleTCPServerSocket.h" - -//============================================================================== -/** - * CTOR - * Accepts a buffer size for internal storage and a flag to indicate if - * Recv should return fixed sized packets or not. - */ -SimpleTCPServerSocket::SimpleTCPServerSocket(long inBufferSize, bool inWaitForFull) - : m_ServerSocket(NULL) - , m_ClientSocket(NULL) - , m_Data(NULL) - , m_BytesRead(0) - , m_BytesSent(0) - , m_BufferSize(inBufferSize) - , m_WaitForFull(inWaitForFull) - , m_Initialized(false) -{ - m_Data = new char[m_BufferSize]; -} - -//============================================================================== -/** - * DTOR - */ -SimpleTCPServerSocket::~SimpleTCPServerSocket() -{ - if (m_ClientSocket) - Disconnect(); - - delete[] m_Data; -} - -//============================================================================== -/** - * Initializes TCP communications. - * Needs to be called once per app. - */ -bool SimpleTCPServerSocket::Initialize() -{ -#ifdef _PCPLATFORM - WSADATA theWsaData; - - if (WSAStartup(WINSOCK_VERSION, &theWsaData)) { - // WSAStartup failed - return false; - } -#endif - return true; -} - -//============================================================================== -/** - * Deinitializes TCP communications. - * Needs to be called once per app. - */ -void SimpleTCPServerSocket::DeInitialize() -{ -#ifdef _PCPLATFORM - WSACleanup(); -#endif -} - -//============================================================================== -/** - * Creates server socket, bind it and listen for incoming connection from a client. - */ -bool SimpleTCPServerSocket::Accept(const char *inServerAddress /*=NULL*/, - unsigned short inServerPort /*=0*/) -{ - bool theReturn = false; - struct sockaddr_in sockaddrServer; - struct sockaddr_in sockaddrClient; - - if (!m_Initialized) { - /* Create the TCP socket */ - if ((m_ServerSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET) { - /* Construct the server sockaddr_in structure */ - memset(&sockaddrServer, 0, sizeof(sockaddrServer)); /* Clear struct */ - sockaddrServer.sin_family = AF_INET; /* Internet/IP */ - sockaddrServer.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */ - sockaddrServer.sin_port = htons(inServerPort); /* server port */ - - /* Bind the server socket */ - if (bind(m_ServerSocket, (struct sockaddr *)&sockaddrServer, sizeof(sockaddrServer)) - == 0) - m_Initialized = true; - } - } - - /* Listen on the server socket */ - if (listen(m_ServerSocket, 1) == 0) { - socklen_t theClientLen = sizeof(sockaddrClient); - /* Wait for client connection */ - if ((m_ClientSocket = - accept(m_ServerSocket, (struct sockaddr *)&sockaddrClient, &theClientLen)) - == 0) { - SetNonBlocking(m_ClientSocket); - theReturn = true; - } - } - - return theReturn; -} - -//============================================================================== -/** - * Sets socket to non blocking state - */ -bool SimpleTCPServerSocket::SetNonBlocking(SOCKET inSocket) -{ -// Set this up to be a non-blocking socket -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - int theFlags = fcntl(inSocket, F_GETFL, 0); - return fcntl(m_ClientSocket, F_SETFL, theFlags | O_NONBLOCK) == 0; -#endif - -#ifdef _PCPLATFORM - u_long theBlockMode = 1; - return ioctlsocket(inSocket, FIONBIO, &theBlockMode) == 0; -#endif -} - -//============================================================================== -/** - * Disconnect and closes the TCP connection. - */ -void SimpleTCPServerSocket::Disconnect(bool inShutdown /*= false*/) -{ - shutdown(m_ClientSocket, SD_BOTH); - closesocket(m_ClientSocket); - m_BytesRead = 0; - m_BytesSent = 0; - m_ClientSocket = 0; - - if (inShutdown) { - shutdown(m_ServerSocket, SD_BOTH); - closesocket(m_ServerSocket); - m_ServerSocket = 0; - } -} - -//============================================================================== -/** - * Receives a data packet from the socket. - * If m_WaitForFull is true, Recv will always return 0 until it reads m_BufferSize - * bytes. - * Else, it will return the number of bytes read (if any) per call. - */ -long SimpleTCPServerSocket::Recv() -{ - long theReturnValue = 0; - - if (m_WaitForFull) { - theReturnValue = recv(m_ClientSocket, m_Data + m_BytesRead, m_BufferSize - m_BytesRead, 0); - - if (theReturnValue > 0) - m_BytesRead += theReturnValue; - - if (m_BytesRead < m_BufferSize) - theReturnValue = 0; - else { - m_BytesRead = 0; - theReturnValue = m_BufferSize; - } - } else { - theReturnValue = recv(m_ClientSocket, m_Data, m_BufferSize, 0); - if (theReturnValue == SOCKET_ERROR) - theReturnValue = 0; - } - - return theReturnValue; -} - -//============================================================================== -/** - * Sends a data packet to the socket. - * If m_WaitForFull is true, Send will always return 0 until it receives m_BufferSize - * bytes. - * Else, it will return the number of bytes sent (if any) per call. - */ -long SimpleTCPServerSocket::Send() -{ - long theReturnValue = 0; - - if (m_WaitForFull) { - theReturnValue = send(m_ClientSocket, m_Data + m_BytesSent, m_BufferSize - m_BytesSent, 0); - - if (theReturnValue > 0) - m_BytesSent += theReturnValue; - - if (m_BytesSent < m_BufferSize) - theReturnValue = 0; - else { - m_BytesSent = 0; - theReturnValue = m_BufferSize; - } - } else { - theReturnValue = send(m_ClientSocket, m_Data, m_BufferSize, 0); - if (theReturnValue == SOCKET_ERROR) - theReturnValue = 0; - } - - return theReturnValue; -} diff --git a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.h b/src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.h deleted file mode 100644 index 565dd736..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/SimpleTCPServerSocket.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#pragma once - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -#define SOCKET int -#endif - -#ifdef _PCPLATFORM -#include -#include -#endif - -//============================================================================== -// Creates a TCP socket to an address and port. -// Can return either fixed sized packets or variable sized ones. -//============================================================================== -class SimpleTCPServerSocket -{ -public: - SimpleTCPServerSocket(long inBufferSize, bool inWaitForFull); - ~SimpleTCPServerSocket(); - -public: - static bool Initialize(); - static void DeInitialize(); - - // Client side - // bool Connect( const char* inServerAddress, const char* inServerPort ); - void Disconnect(bool inShutdown = false); - - bool Accept(const char *inServerAddress = 0, unsigned short inServerPort = 0); - - // General - long Recv(); - long Send(); - - // operator void*( ){ return m_Data; } - void *GetData() { return m_Data; } - -protected: - bool SetNonBlocking(SOCKET inSocket); - -protected: - SOCKET m_ServerSocket; - SOCKET m_ClientSocket; - char *m_Data; - long m_BytesRead; - long m_BytesSent; - const long m_BufferSize; - bool m_WaitForFull; - bool m_Initialized; -}; diff --git a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.cpp b/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.cpp deleted file mode 100644 index a8be5b27..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include "TCPPerfLogClient.h" -#include "Qt3DSMacros.h" -#include "Qt3DSPlatformSpecific.h" -#include -#include - -//============================================================================== -// Statics -//============================================================================== -static TCPPerfLogClient *s_PerfLogClient = NULL; -static SPerfLogDataExtra s_LogDataExtra = { 0 }; -static const KDust s_OneSec = 1000000000; - -//============================================================================== -/** - * Extern function to create and initialize the TCPPerfLogClient. - */ -int InitializePerfLogClient(const char *inServerAddress, const char *inPort, KDust inLogFreqMsec, - const char *inLocalLogFilename) -{ - int theReturn = 1; - - if (!s_PerfLogClient) { - s_PerfLogClient = - new TCPPerfLogClient(inServerAddress, inPort, inLogFreqMsec, inLocalLogFilename); - theReturn = s_PerfLogClient->IsConnected() || s_PerfLogClient->IsLocal(); - } - - return theReturn; -} - -void PerfLogMarkBegin(KDust inCurrentTimeMsec) -{ - if (s_PerfLogClient) - s_PerfLogClient->MarkLogBegin(inCurrentTimeMsec); -} - -void PerfLogMarkEnd(KDust inCurrentTimeMsec) -{ - if (s_PerfLogClient) - s_PerfLogClient->MarkLogEnd(inCurrentTimeMsec); -} - -void InitializeNVPerfMon(EGLDisplay inDisplay) -{ - if (s_PerfLogClient) - s_PerfLogClient->InitializeNVPerfMon(inDisplay); -} - -void CleanupPerfLogClient(EGLDisplay inDisplay) -{ - if (s_PerfLogClient) - s_PerfLogClient->CleanupPerfLogClient(inDisplay); - - delete s_PerfLogClient; -} - -void PerfLogGetShortDisplay(char *outMessageBuffer) -{ - if (s_PerfLogClient) - s_PerfLogClient->GetShortDisplay(outMessageBuffer); -} - -//============================================================================== -/** - * Extern function to send a log given a timestamp and the currently measured - * FPS - */ -void PerfLogSend(unsigned long inTimeStamp, float inFPS) -{ - if (s_PerfLogClient) - s_PerfLogClient->SendLog(inTimeStamp, inFPS); -} - -//============================================================================== -/** - * Extern function to set string data into the log packet. - */ -void PerfLogSetStringData(const char *inStringData) -{ - if (s_PerfLogClient) - s_PerfLogClient->SetStringData(inStringData); -} - -//============================================================================== -/** - * CTOR - * Attempts to make a connection to a specified server address and port. - */ -TCPPerfLogClient::TCPPerfLogClient(const char *inServerAddress, const char *inServerPort, - KDust inLogFreqUSec, const char *inLocalLogFilename) - : m_Socket(sizeof(SPerfLogData), true) - , m_ProcMeminfo(NULL) - , m_ProcStatinfo(NULL) - , m_NvRmHandle(NULL) - , m_Connected(false) - , m_SendLog(false) - , m_LocalLogFile(NULL) - , m_RequiredPasses(1) - , m_CurrentPass(0) - , m_FrameCount(0) - , m_LogFreq(inLogFreqUSec) - , m_LastLogTime(0) - , m_LastExtraLogTime(0) - , m_NVPerfMonitor(NULL) - , m_NVGPUIdleCounter(NULL) -{ - //::memset( &m_Data, 0, sizeof( m_Data) ); - m_Connected = m_Socket.Connect(inServerAddress, inServerPort); - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - // Open the meminfo procfs - m_ProcMeminfo = ::fopen("/proc/meminfo", "r"); - ::setvbuf(m_ProcMeminfo, NULL, _IONBF, 0); - - // Open the stat procfs - m_ProcStatinfo = ::fopen("/proc/stat", "r"); - ::setvbuf(m_ProcStatinfo, NULL, _IONBF, 0); -#endif - -#ifdef _TEGRA_LINUX - // Get a handle into vrm - NvRmOpen(m_NvRmHandle, 0); - - // Activate DFS so that we can retrieve the EMC utilization - if (NvRmDfsSetState(m_NvRmHandle, NvRmDfsRunState_ClosedLoop) != 0) - kdLogMessage("\nUnable to activate DFS"); -#endif - - if (inLocalLogFilename) - m_LocalLogFile = ::fopen(inLocalLogFilename, "w"); -} - -//============================================================================== -/** - * DTOR - * Closes opened handles. - */ -TCPPerfLogClient::~TCPPerfLogClient() -{ -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - fclose(m_ProcMeminfo); - fclose(m_ProcStatinfo); -#endif - -#ifdef _TEGRA_LINUX - NvRmClose(m_NvRmHandle); -#endif - m_Socket.Disconnect(); - - if (m_LocalLogFile) - ::fclose(m_LocalLogFile); -} - -//============================================================================== -/** - * Marks the beginning of perf logging. - */ -void TCPPerfLogClient::MarkLogBegin(KDust inCurrentTime) -{ - if (m_LogFreq > 0) { - if ((inCurrentTime - m_LastLogTime) > m_LogFreq) { - m_SendLog = true; // Signal to initiate logging (might required a few frames before log - // data is fully captured) - - // Starts the NV perf monitor for this frame - if (m_NVPerfMonitor) - m_NVPerfMonFuncs.eglPerfMonitorBeginExperimentNV(); - } - - if (m_SendLog) { - if (m_NVPerfMonitor) - m_NVPerfMonFuncs.eglPerfMonitorBeginPassNV(m_CurrentPass % m_RequiredPasses); - } - - if ((inCurrentTime - m_LastExtraLogTime) > s_OneSec) { - SPerfLogData *theData = static_cast(m_Socket.GetData()); - s_LogDataExtra.m_MinFPS = s_LogDataExtra.m_MaxFPS = theData->m_FPS; - s_LogDataExtra.m_MinCPULoad = s_LogDataExtra.m_MaxCPULoad = theData->m_CPULoad; - s_LogDataExtra.m_MinGPULoad = s_LogDataExtra.m_MaxGPULoad = theData->m_GPULoad; - m_LastExtraLogTime = inCurrentTime; - } - } -} - -//============================================================================== -/** - * Marks the end of perf logging. - */ -void TCPPerfLogClient::MarkLogEnd(KDust inCurrentTime) -{ - ++m_FrameCount; - - if (m_SendLog) { - if (m_NVPerfMonitor) { - // Signal the end of NV perf logging for this frame - m_NVPerfMonFuncs.eglPerfMonitorEndPassNV(); - ++m_CurrentPass; - } - - if ((m_CurrentPass % m_RequiredPasses == 0)) { - if (m_NVPerfMonitor) - m_NVPerfMonFuncs.eglPerfMonitorEndExperimentNV(); - - KDust theElaspedTime = inCurrentTime - m_LastLogTime; - SendLog(static_cast(inCurrentTime / 1000000), - static_cast(m_FrameCount / (theElaspedTime / 1000000000.0))); - m_LastLogTime = inCurrentTime; - m_FrameCount = 0; - m_SendLog = false; - } - } -} - -//============================================================================== -/** - * Sets timestamp and FPS into log and calls GatherStatistics. - * Sends log data into the socket. - */ -bool TCPPerfLogClient::SendLog(unsigned long inTimestamp, float inFPS) -{ - SPerfLogData *theData = static_cast(m_Socket.GetData()); - theData->m_Timestamp = inTimestamp; - theData->m_FPS = inFPS; - GatherStatistics(theData); - - s_LogDataExtra.m_MinFPS = Q3DStudio::Q3DStudio_min(inFPS, s_LogDataExtra.m_MinFPS); - s_LogDataExtra.m_MaxFPS = Q3DStudio::Q3DStudio_max(inFPS, s_LogDataExtra.m_MaxFPS); - - s_LogDataExtra.m_MinCPULoad = - Q3DStudio::Q3DStudio_min(theData->m_CPULoad, s_LogDataExtra.m_MinCPULoad); - s_LogDataExtra.m_MaxCPULoad = - Q3DStudio::Q3DStudio_max(theData->m_CPULoad, s_LogDataExtra.m_MaxCPULoad); - - s_LogDataExtra.m_MinGPULoad = - Q3DStudio::Q3DStudio_min(theData->m_GPULoad, s_LogDataExtra.m_MinGPULoad); - s_LogDataExtra.m_MaxGPULoad = - Q3DStudio::Q3DStudio_max(theData->m_GPULoad, s_LogDataExtra.m_MaxGPULoad); - - bool theResult = false; - - if (m_LocalLogFile) - theResult |= ::fputs(FormatPerfLogData(theData), m_LocalLogFile) > 0; - - if (IsConnected()) - theResult |= m_Socket.Send() > 0; - - return theResult; -} - -//============================================================================== -/** - * Sets string data into the next log packet to be sent. - */ -void TCPPerfLogClient::SetStringData(const char *inStringData) -{ - SPerfLogData *theData = static_cast(m_Socket.GetData()); - ::strcpy(theData->m_StringData, inStringData); -} - -//============================================================================== -/** - * Obtain memory usage using meminfo procfs. - */ -void TCPPerfLogClient::GetCPUMemoryUsage(unsigned long &outUsage) -{ - unsigned long theTotalMem = 0; - unsigned long theFreeMem = 0; - -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - rewind(m_ProcMeminfo); - fflush(m_ProcMeminfo); - - fscanf(m_ProcMeminfo, "MemTotal: %lu kB\nMemFree: %lu kB", &theTotalMem, &theFreeMem); -#endif - - outUsage = theTotalMem - theFreeMem; -} - -//============================================================================== -/** - * Obtain GPU memory usage from nvrm. - */ -void TCPPerfLogClient::GetGPUCarveoutUsage(unsigned long &outUsage) -{ - long theUsedCarveout = 0; - -#ifdef _TEGRA_LINUX - NvRmMemGetStat(NvRmMemStat_UsedCarveout, theUsedCarveout); -#endif - - outUsage = theUsedCarveout; -} - -//============================================================================== -/** - * Obtain CPU utilization from nvrm DFS. - */ -void TCPPerfLogClient::GetCPULoad(float &outPercentage) -{ -#ifdef _LINUXPLATFORM - // Get CPU load from /proc/stat - static SCPUInfo thePreviousInfo; - SCPUInfo theCurrentInfo; - - rewind(m_ProcStatinfo); - fflush(m_ProcStatinfo); - - // Read first line in /proc/stat which is a summary for all CPU cores on the system - fscanf(m_ProcStatinfo, "cpu %lu %lu %lu %lu %lu %lu %lu %lu", &theCurrentInfo.m_User, - &theCurrentInfo.m_Nice, &theCurrentInfo.m_System, &theCurrentInfo.m_Idle, - &theCurrentInfo.m_Wait, &theCurrentInfo.m_X, &theCurrentInfo.m_Y, &theCurrentInfo.m_Z); - - // Idle frames calculation - unsigned long theIdleFrames = theCurrentInfo.m_Idle - thePreviousInfo.m_Idle; - if (theIdleFrames < 0) - theIdleFrames = 0; // Appears to be a bug in 2.4.x kernels?? - - // Get the total number of timeslices - unsigned long theTotalFrames = (theCurrentInfo.m_User - thePreviousInfo.m_User) - + (theCurrentInfo.m_Nice - thePreviousInfo.m_Nice) - + (theCurrentInfo.m_System - thePreviousInfo.m_System) + theIdleFrames - + (theCurrentInfo.m_Wait - thePreviousInfo.m_Wait) - + (theCurrentInfo.m_X - thePreviousInfo.m_X) + (theCurrentInfo.m_Y - thePreviousInfo.m_Y) - + (theCurrentInfo.m_Z - thePreviousInfo.m_Z); - - if (theTotalFrames < 1) - theTotalFrames = 1; - - outPercentage = 1.0f - (theIdleFrames * 1.0f / theTotalFrames); - - thePreviousInfo = theCurrentInfo; // /proc/stat is an aggregation, so track this for the next - // time GetCPULoad is called - -#else - outPercentage = -.01f; -#endif -} - -//============================================================================== -/** - * Retrieve the GPU load performance counter - */ -void TCPPerfLogClient::GetGPULoad(long &outPercentage) -{ - EGLuint64NV theCycles = 0; - EGLuint64NV theGPUIdle = 0; - - if (m_NVPerfMonitor - && (m_NVPerfMonFuncs.eglGetPerfMarkerCounterNV(EGL_DEFAULT_PERFMARKER_NV, - m_NVGPUIdleCounter, &theGPUIdle, &theCycles) - == EGL_TRUE)) - outPercentage = static_cast(100 - theGPUIdle); - else - outPercentage = 0; -} - -//============================================================================== -/** - * Retrieve the external memory controller load. - * DFS must be running first. - */ -void TCPPerfLogClient::GetEMCLoad(float &outPercentage) -{ -// Get CPU clock utilization from DFS -#ifdef _TEGRA_LINUX - NvRmDfsClockUsage theUsage; - ::memset(&theUsage, 0, sizeof(theUsage)); - if (NvRmDfsGetClockUtilization(m_NvRmHandle, NvRmDfsClockId_Emc, theUsage) == 0) - outPercentage = theUsage.AverageKHz * 1.0f / theUsage.CurrentKHz; - else -#endif - outPercentage = -0.01f; -} - -//============================================================================== -/** - * Helper function to gather various statistics. - */ -void TCPPerfLogClient::GatherStatistics(SPerfLogData *inLogData) -{ - // Grab and set statistics here - GetGPUCarveoutUsage(inLogData->m_GPUMemoryUsage); - GetCPUMemoryUsage(inLogData->m_CPUMemoryUsage); - GetCPULoad(inLogData->m_CPULoad); - GetGPULoad(inLogData->m_GPULoad); - GetEMCLoad(inLogData->m_EMCLoad); -} - -//============================================================================== -/** - * Initialize NV perf monitor counters - * Currently only one counter requested (GPU Idle) - */ -void TCPPerfLogClient::InitializeNVPerfMon(EGLDisplay inDisplay) -{ -#ifdef _TEGRA_LINUX - EGLPerfCounterNV theCounters[50]; - EGLint theReturnedCounterSize = 0; - - m_NVPerfMonitor = m_NVPerfMonFuncs.eglCreatePerfMonitorNV( - inDisplay, EGL_PERFMONITOR_HARDWARE_COUNTERS_BIT_NV); - m_NVPerfMonFuncs.eglMakeCurrentPerfMonitorNV(m_NVPerfMonitor); - - m_NVPerfMonFuncs.eglGetPerfCountersNV(m_NVPerfMonitor, theCounters, 100, - &theReturnedCounterSize); - for (long theIndex = 0; theIndex < theReturnedCounterSize; ++theIndex) { - const char *theCounterName = m_NVPerfMonFuncs.eglQueryPerfCounterStringNV( - m_NVPerfMonitor, theCounters[theIndex], EGL_COUNTER_NAME_NV); - - // Look for a counter with the name 'gpu idle' - if (Q3DStudio_stricmp(theCounterName, "GPU Idle") == 0) { - m_NVPerfMonFuncs.eglPerfMonitorAddCountersNV(1, &theCounters[theIndex]); - m_NVGPUIdleCounter = theCounters[theIndex]; - break; - } - } - - m_NVPerfMonFuncs.eglValidatePerfMonitorNV(&m_RequiredPasses); -#else - UNREFERENCED_PARAMETER(inDisplay); -#endif -} - -//============================================================================== -/** - * Deinitializes the NV perf monitor - */ -void TCPPerfLogClient::CleanupPerfLogClient(EGLDisplay inDisplay) -{ - if (m_NVPerfMonitor) - m_NVPerfMonFuncs.eglDestroyPerfMonitorNV(inDisplay, m_NVPerfMonitor); -} - -//============================================================================== -/** - * Retrieve a formatted output string containing performance statistics - */ -void TCPPerfLogClient::GetShortDisplay(char *inMessageBuffer) -{ - SPerfLogData *theData = static_cast(m_Socket.GetData()); - FormatPerfLogDataExtra(theData, &s_LogDataExtra, inMessageBuffer); -} diff --git a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.h b/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.h deleted file mode 100644 index 8a39dab6..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClient.h +++ /dev/null @@ -1,376 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -//============================================================================== -// Includes -//============================================================================== -#include -#include -#include "SimpleTCPClientSocket.h" -#include "TCPPerfLogCommon.h" -#include "TCPPerfLogClientStub.h" - -#ifdef _PCPLATFORM -#include -#endif - -//============================================================================== -// Header definations copied from nvrm headers -//============================================================================== -extern "C" { - -/** - * NvRm heap statistics. See NvRmMemGetStat() for further details. - */ -enum NvRmMemStat { - /** - * Total number of bytes reserved for the carveout heap. - */ - NvRmMemStat_TotalCarveout = 1, - /** - * Number of bytes used in the carveout heap. - */ - NvRmMemStat_UsedCarveout, - /** - * Size of the largest free block in the carveout heap. - * Size can be less than the difference of total and - * used memory. - */ - NvRmMemStat_LargestFreeCarveoutBlock, - /** - * Total number of bytes in the GART heap. - */ - NvRmMemStat_TotalGart, - /** - * Number of bytes reserved from the GART heap. - */ - NvRmMemStat_UsedGart, - /** - * Size of the largest free block in GART heap. Size can be - * less than the difference of total and used memory. - */ - NvRmMemStat_LargestFreeGartBlock, -}; - -/** - * Defines SOC-wide clocks controlled by Dynamic Frequency Scaling (DFS) - * that can be targeted by Starvation and Busy hints - */ -enum NvRmDfsClockId { - /// Specifies CPU clock - NvRmDfsClockId_Cpu = 1, - - /// Specifies AVP clock - NvRmDfsClockId_Avp, - - /// Specifies System bus clock - NvRmDfsClockId_System, - - /// Specifies AHB bus clock - NvRmDfsClockId_Ahb, - - /// Specifies APB bus clock - NvRmDfsClockId_Apb, - - /// Specifies video pipe clock - NvRmDfsClockId_Vpipe, - - /// Specifies external memory controller clock - NvRmDfsClockId_Emc, -}; - -typedef unsigned long NvRmFreqKHz; - -/** - * Holds information on DFS clock domain utilization - */ -struct NvRmDfsClockUsage -{ - /// Minimum clock domain frequency - NvRmFreqKHz MinKHz; - - /// Maximum clock domain frequency - NvRmFreqKHz MaxKHz; - - /// Low corner frequency - current low boundary for DFS control algorithm. - /// Can be dynamically adjusted via APIs: NvRmDfsSetLowCorner() for all DFS - /// domains, NvRmDfsSetCpuEnvelope() for CPU, and NvRmDfsSetEmcEnvelope() - /// for EMC. When all DFS domains hit low corner, DFS stops waking up CPU - /// from low power state. - NvRmFreqKHz LowCornerKHz; - - /// High corner frequency - current high boundary for DFS control algorithm. - /// Can be dynamically adjusted via APIs: NvRmDfsSetCpuEnvelope() for Cpu, - /// NvRmDfsSetEmcEnvelope() for Emc, and NvRmDfsSetAvHighCorner() for other - // DFS domains. - NvRmFreqKHz HighCornerKHz; - - /// Current clock domain frequency - NvRmFreqKHz CurrentKHz; - - /// Average frequency of domain *activity* (not average frequency). For - /// domains that do not have activity monitors reported as unspecified. - NvRmFreqKHz AverageKHz; -}; - -/** - * Defines DFS manager run states - */ -enum NvRmDfsRunState { - /// DFS is in invalid, not initialized state - NvRmDfsRunState_Invalid = 0, - - /// DFS is disabled / not supported (terminal state) - NvRmDfsRunState_Disabled = 1, - - /// DFS is stopped - no automatic clock control. Starvation and Busy hints - /// are recorded but have no affect. - NvRmDfsRunState_Stopped, - - /// DFS is running in closed loop - full automatic control of SoC-wide - /// clocks based on clock activity measuremnets. Starvation and Busy hints - /// are functional as well. - NvRmDfsRunState_ClosedLoop, - - /// DFS is running in closed loop with profiling (can not be set on non - /// profiling build). - NvRmDfsRunState_ProfiledLoop, -}; - -typedef void *NvRmDeviceHandle; - -NvRmDfsRunState NvRmDfsGetState(NvRmDeviceHandle inRmDeviceHandle); -long NvRmDfsSetState(NvRmDeviceHandle inRmDeviceHandle, NvRmDfsRunState inDfsRunState); - -/** - * Gets information on DFS controlled clock utilization. If DFS is stopped - * or disabled the average frequency is always equal to current frequency. - * - * @param hRmDeviceHandle The RM device handle. - * @param ClockId The DFS ID of the clock targeted by this request. - * @param pClockInfo Output storage pointer for clock utilization information. - * - * @return NvSuccess if clock usage information is returned successfully. - */ -// NvError -// NvRmDfsGetClockUtilization( -// [in] NvRmDeviceHandle hRmDeviceHandle, -// [in] NvRmDfsClockId ClockId, -// [out] NvRmDfsClockUsage pClockUsage); -long NvRmDfsGetClockUtilization(NvRmDeviceHandle inRmDeviceHandle, NvRmDfsClockId inClockId, - NvRmDfsClockUsage &inClockUsage); - -/** - * Get a memory statistics value. - * - * Querying values may have an effect on system performance and may include - * processing, like heap traversal. - * - * @param Stat NvRmMemStat value that chooses the value to return. - * @param Result Result, if the call was successful. Otherwise value - * is not touched. - * @returns NvSuccess on success, NvError_BadParameter if Stat is - * not a valid value, NvError_NotSupported if the Stat is - * not available for some reason, or - * NvError_InsufficientMemory. - */ -// NvError -// NvRmMemGetStat([in] NvRmMemStat Stat, [out] NvS32 Result); -long NvRmMemGetStat(NvRmMemStat inStat, long &outResult); - -/** - * Opens the Resource Manager for a given device. - * - * Can be called multiple times for a given device. Subsequent - * calls will not necessarily return the same handle. Each call to - * NvRmOpen() must be paired with a corresponding call to NvRmClose(). - * - * Assert encountered in debug mode if DeviceId value is invalid. - * - * This call is not intended to perform any significant hardware - * initialization of the device; rather its primary purpose is to - * initialize RM's internal data structures that are involved in - * managing the device. - * - * @param pHandle the RM handle is stored here. - * @param DeviceId implementation-dependent value specifying the device - * to be opened. Currently must be set to zero. - * - * @retval NvSuccess Indicates that RM was successfully opened. - * @retval NvError_InsufficientMemory Indicates that RM was unable to allocate - * memory for its internal data structures. - */ -// NvError NvRmOpen( [out] NvRmDeviceHandle pHandle, [in] NvU32 DeviceId ); -long NvRmOpen(NvRmDeviceHandle &inHandle, unsigned long outDeviceId); - -/** - * Closes the Resource Manager for a given device. - * - * Each call to NvRmOpen() must be paired with a corresponding call - * to NvRmClose(). - * - * @param hDevice The RM handle. If hDevice is NULL, this API has no effect. - */ -// void NvRmClose( [in] NvRmDeviceHandle hDevice ); -void NvRmClose(void *inDevice); - -} // extern "C" - -// Represents information obtained from /proc/stat -typedef struct _SCPUInfo -{ - unsigned long m_User; // timeslices in userspace - unsigned long m_Nice; // timeslices for niced processed - unsigned long m_System; // timeslices in kernelspace - unsigned long m_Idle; // timeslices in idle - unsigned long m_Wait; // timeslices in wait - unsigned long m_X; // other timeslices - unsigned long m_Y; // other timeslices - unsigned long m_Z; // other timeslices - - _SCPUInfo() - : m_User(0) - , m_Nice(0) - , m_System(0) - , m_Idle(0) - , m_Wait(0) - , m_X(0) - , m_Y(0) - , m_Z(0) - { - } - -} SCPUInfo; - -//============================================================================== -// Utility function to grab EGL function pointers for NV perf monitor. -//============================================================================== -typedef struct _SNVPerfMonitorFuncs -{ - PFNEGLCREATEPERFMONITORNVPROC eglCreatePerfMonitorNV; - PFNEGLGETCURRENTPERFMONITORNVPROC eglGetCurrentPerfMonitorNV; - PFNEGLDESTROYPERFMONITORNVPROC eglDestroyPerfMonitorNV; - PFNEGLGETPERFCOUNTERSNVPROC eglGetPerfCountersNV; - PFNEGLQUERYPERFCOUNTERSTRINGNVPROC eglQueryPerfCounterStringNV; - PFNEGLPERFMONITORADDCOUNTERSNVPROC eglPerfMonitorAddCountersNV; - PFNEGLMAKECURRENTPERFMONITORNVPROC eglMakeCurrentPerfMonitorNV; - PFNEGLGETPERFMARKERCOUNTERNVPROC eglGetPerfMarkerCounterNV; - PFNEGLPERFMONITORBEGINEXPERIMENTNVPROC eglPerfMonitorBeginExperimentNV; - PFNEGLPERFMONITORENDEXPERIMENTNVPROC eglPerfMonitorEndExperimentNV; - PFNEGLPERFMONITORBEGINPASSNVPROC eglPerfMonitorBeginPassNV; - PFNEGLPERFMONITORENDPASSNVPROC eglPerfMonitorEndPassNV; - PFNEGLVALIDATEPERFMONITORNVPROC eglValidatePerfMonitorNV; - - _SNVPerfMonitorFuncs() - { - eglCreatePerfMonitorNV = - (PFNEGLCREATEPERFMONITORNVPROC)eglGetProcAddress("eglCreatePerfMonitorNV"); - eglDestroyPerfMonitorNV = - (PFNEGLDESTROYPERFMONITORNVPROC)eglGetProcAddress("eglDestroyPerfMonitorNV"); - eglGetCurrentPerfMonitorNV = - (PFNEGLGETCURRENTPERFMONITORNVPROC)eglGetProcAddress("eglGetCurrentPerfMonitorNV"); - eglGetPerfCountersNV = - (PFNEGLGETPERFCOUNTERSNVPROC)eglGetProcAddress("eglGetPerfCountersNV"); - eglQueryPerfCounterStringNV = - (PFNEGLQUERYPERFCOUNTERSTRINGNVPROC)eglGetProcAddress("eglQueryPerfCounterStringNV"); - eglPerfMonitorAddCountersNV = - (PFNEGLPERFMONITORADDCOUNTERSNVPROC)eglGetProcAddress("eglPerfMonitorAddCountersNV"); - eglMakeCurrentPerfMonitorNV = - (PFNEGLMAKECURRENTPERFMONITORNVPROC)eglGetProcAddress("eglMakeCurrentPerfMonitorNV"); - eglGetPerfMarkerCounterNV = - (PFNEGLGETPERFMARKERCOUNTERNVPROC)eglGetProcAddress("eglGetPerfMarkerCounterNV"); - eglPerfMonitorBeginExperimentNV = (PFNEGLPERFMONITORBEGINEXPERIMENTNVPROC)eglGetProcAddress( - "eglPerfMonitorBeginExperimentNV"); - eglPerfMonitorEndExperimentNV = (PFNEGLPERFMONITORENDEXPERIMENTNVPROC)eglGetProcAddress( - "eglPerfMonitorEndExperimentNV"); - eglPerfMonitorBeginPassNV = - (PFNEGLPERFMONITORBEGINPASSNVPROC)eglGetProcAddress("eglPerfMonitorBeginPassNV"); - eglPerfMonitorEndPassNV = - (PFNEGLPERFMONITORENDPASSNVPROC)eglGetProcAddress("eglPerfMonitorEndPassNV"); - eglValidatePerfMonitorNV = - (PFNEGLVALIDATEPERFMONITORNVPROC)eglGetProcAddress("eglValidatePerfMonitorNV"); - } - -} SNVPerfMonitorFuncs; - -//============================================================================== -// Handles gathering of performance statistics and sending them. -// Attempts to make a connection to a server that it will send data to. -//============================================================================== -class TCPPerfLogClient -{ -public: - TCPPerfLogClient(const char *inServerAddress, const char *inServerPort, KDust inLogFreqUSec, - const char *inLocalLogFilename); - ~TCPPerfLogClient(); - -public: - void MarkLogBegin(KDust inCurrentTime); - void MarkLogEnd(KDust inCurrentTime); - - bool SendLog(unsigned long inTimeStamp, float inFPS); - void SetStringData(const char *inStringData); - bool IsConnected() { return m_Connected; } - bool IsLocal() { return m_LocalLogFile != NULL; } - void InitializeNVPerfMon(EGLDisplay inDisplay); - void CleanupPerfLogClient(EGLDisplay inDisplay); - void GetShortDisplay(char *inMessageBuffer); - -protected: - void GatherStatistics(SPerfLogData *inLogData); - void GetCPUMemoryUsage(unsigned long &outUsage); - void GetGPUCarveoutUsage(unsigned long &outUsage); - void GetCPULoad(float &outPercentage); - void GetGPULoad(long &outPercentage); - void GetEMCLoad(float &outPercentage); - void GetGPUWaits(long &outPercentage); - -protected: - SimpleTCPClientSocket m_Socket; - FILE *m_ProcMeminfo; - FILE *m_ProcStatinfo; - void *m_NvRmHandle; - bool m_Connected; - bool m_SendLog; - FILE *m_LocalLogFile; - - EGLint m_RequiredPasses; - EGLint m_CurrentPass; - - long m_FrameCount; - KDust m_LogFreq; - KDust m_LastLogTime; - KDust m_LastExtraLogTime; - - const SNVPerfMonitorFuncs m_NVPerfMonFuncs; - EGLPerfMonitorNV m_NVPerfMonitor; - EGLPerfCounterNV m_NVGPUIdleCounter; -}; diff --git a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClientStub.h b/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClientStub.h deleted file mode 100644 index 2b6c0975..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogClientStub.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -//============================================================================== -// Includes -//============================================================================== - -//============================================================================== -// Extern interfaces -//============================================================================== - -#ifdef __cplusplus -extern "C" { -#endif - -int InitializePerfLogClient(const char *inServerAddress, const char *inPort, KDust inLogFreqMsec, - const char *inLocalLogFilename); -void InitializeNVPerfMon(EGLDisplay inDisplay); -void CleanupPerfLogClient(EGLDisplay inDisplay); - -void PerfLogMarkBegin(KDust inCurrentTimeMsec); -void PerfLogMarkEnd(KDust inCurrentTimeMsec); -void PerfLogSend(unsigned long inTimeStamp, float inFPS); -void PerfLogSetStringData(const char *inStringData); -void PerfLogGetShortDisplay(char *outMessageBuffer); - -#ifdef __cplusplus -} -#endif diff --git a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogCommon.h b/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogCommon.h deleted file mode 100644 index 23bc58f2..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogCommon.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#include - -//============================================================================== -// Structs -//============================================================================== -typedef struct _SPerfLogData -{ - unsigned long m_Timestamp; - float m_FPS; - unsigned long m_GPUMemoryUsage; - unsigned long m_CPUMemoryUsage; - float m_CPULoad; - long m_GPULoad; - float m_EMCLoad; - char m_StringData[128]; -} SPerfLogData; - -typedef struct _SPerfLogDataExtra -{ - float m_MinFPS; - float m_MaxFPS; - float m_MinCPULoad; - float m_MaxCPULoad; - long m_MinGPULoad; - long m_MaxGPULoad; -} SPerfLogDataExtra; - -//============================================================================== -/** - * Formats SPerfLogData into a user readable form. - */ -const char *FormatPerfLogData(const SPerfLogData *inData) -{ - static char theMessageBuffer[256]; - theMessageBuffer[0] = 0; - - static unsigned long thePrevTimestamp = 0; - static unsigned long theTimestampDiff = 0; - if (thePrevTimestamp != 0) - theTimestampDiff = inData->m_Timestamp - thePrevTimestamp; - - ::sprintf(theMessageBuffer, "Timestamp: %lu\tTimediff: %lu\tFPS: %.2f\tUsecase: " - "%s\tGPUMemoryUsage: %lu\tCPUMemoryUsage: %lu\tCPULoad: " - "%.2f\tGPULoad: %ld\tEMCLoad: %.2f\n", - inData->m_Timestamp, theTimestampDiff, inData->m_FPS, inData->m_StringData, - inData->m_GPUMemoryUsage, inData->m_CPUMemoryUsage, inData->m_CPULoad * 100, - inData->m_GPULoad, inData->m_EMCLoad * 100); - - thePrevTimestamp = inData->m_Timestamp; - - return theMessageBuffer; -} - -//============================================================================== -/** - * Formats SPerfLogDataExtra into a user readable form. - */ -void FormatPerfLogDataExtra(const SPerfLogData *inData, const SPerfLogDataExtra *inExtraData, - char *inMessageBuffer) -{ - ::sprintf(inMessageBuffer, "FPS: %.0f/%.0f/%.0f CPU: %.0f/%.0f/%.0f GPU: %ld/%ld/%ld EMC: %.0f", - inData->m_FPS, inExtraData->m_MaxFPS, inExtraData->m_MinFPS, inData->m_CPULoad * 100, - inExtraData->m_MaxCPULoad * 100, inExtraData->m_MinCPULoad * 100, inData->m_GPULoad, - inExtraData->m_MaxGPULoad, inExtraData->m_MinGPULoad, inData->m_EMCLoad * 100); -} diff --git a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.cpp b/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.cpp deleted file mode 100644 index b62663b2..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//============================================================================== -// Includes -//============================================================================== -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -#include -#include -#endif - -#ifdef _PCPLATFORM -#include -#endif - -#include -#include "TCPPerfLogServer.h" - -//============================================================================== -/** - * CTOR - * Sets up listening server at specificed address and port. - * Opens log file to be ready for writing. - */ -TCPPerfLogServer::TCPPerfLogServer(const char *inServerAddress, unsigned short inServerPort, - const char *inLogFilename) - : m_LogFileHandle(0) - , m_Socket(sizeof(SPerfLogData), true) -{ - m_LogFileHandle = ::fopen(inLogFilename, "w"); - m_Socket.Accept(inServerAddress, inServerPort); -} - -//============================================================================== -/** - * DTOR - * Closes log file and disconnects server. - */ -TCPPerfLogServer::~TCPPerfLogServer() -{ - ::fclose(m_LogFileHandle); - m_Socket.Disconnect(true); -} - -//============================================================================== -/** - * Checks for any received packets and write them into the log file - */ -const char *TCPPerfLogServer::Update() -{ - if (m_Socket.Recv() > 0) { - const char *theOutputMessage = Output(); - ::fputs(theOutputMessage, m_LogFileHandle); - return theOutputMessage; - } - - return NULL; -} - -//============================================================================== -/** - * Formats receieved data into a text string. - */ -const char *TCPPerfLogServer::Output() -{ - SPerfLogData *thePerfLogData = static_cast(m_Socket.GetData()); - - return FormatPerfLogData(thePerfLogData); -} - -//============================================================================== -/** - * Keyboard hittest for Linux - */ -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) -int kbhit(void) -{ - return 0; -} -#else -#define kbhit _kbhit -#endif - -//============================================================================== -/** - * Main - */ -int main(int argc, const char *argv[]) -{ - const char *theServerIP = "10.0.0.1"; - const char *theLogFile = "perf.log"; - if (argc > 1) - theServerIP = argv[1]; - - if (argc > 2) - theLogFile = argv[2]; - - SimpleTCPServerSocket::Initialize(); - - { - ::printf("\nLog file: %s", theLogFile); - ::printf("\nServer listening at: %s", theServerIP); - - ::printf("\nWaiting for client..."); - ::fflush(stdout); - TCPPerfLogServer theServer(theServerIP, 9997, theLogFile); - ::printf("\nClient connected..."); - ::fflush(stdout); - - while (true) { - const char *theReceivedMessage = theServer.Update(); - if (theReceivedMessage) - printf("\n%s", theReceivedMessage); - - if (kbhit()) { -#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) - char theKey = getchar(); -#endif -#ifdef _PCPLATFORM - char theKey = (char)_getch(); -#endif - if (theKey == 'q') - break; - } - } - } - - SimpleTCPServerSocket::DeInitialize(); - return 0; -} diff --git a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.h b/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.h deleted file mode 100644 index bfa6abcc..00000000 --- a/src/Runtime/Source/Viewer/PerfLog/TCPPerfLogServer.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once -//============================================================================== -// Includes -//============================================================================== -#include "SimpleTCPServerSocket.h" -#include "TCPPerfLogCommon.h" -#include - -//============================================================================== -// Creates a polling server that listens for incoming log packets. -// Creates a write received log data into a file. -//============================================================================== -class TCPPerfLogServer -{ -public: - TCPPerfLogServer(const char *inServerAddress, unsigned short inServerPort, - const char *inLogFilename); - ~TCPPerfLogServer(); - - const char *Update(); - -protected: - const char *Output(); - -protected: - FILE *m_LogFileHandle; - SimpleTCPServerSocket m_Socket; -}; diff --git a/src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.cpp b/src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.cpp deleted file mode 100644 index b9fb9763..00000000 --- a/src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 - 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSAudioPlayerImpl.h" -#include "foundation/Qt3DSLogging.h" -#include - -#ifdef PLATFORM_HAS_QT_MULTIMEDIA_LIB -#include -#endif // PLATFORM_HAS_QT_MULTIMEDIA_LIB - -namespace Q3DSViewer { - -Qt3DSAudioPlayerImpl::Qt3DSAudioPlayerImpl() -{ -} - -Qt3DSAudioPlayerImpl::~Qt3DSAudioPlayerImpl() -{ -} - -bool Qt3DSAudioPlayerImpl::PlaySoundFile(const char *inFilePath) -{ -#ifdef PLATFORM_HAS_QT_MULTIMEDIA_LIB - QSound::play(QString(inFilePath)); - return true; -#else - Q_UNUSED(inFilePath) - qCWarning(qt3ds::WARNING, "Qt3DSAudioPlayerImpl::PlaySoundFile: no QT multimedia lib on this platform"); - return false; -#endif // PLATFORM_HAS_QT_MULTIMEDIA_LIB -} -} diff --git a/src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.h b/src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.h deleted file mode 100644 index bba5bd6a..00000000 --- a/src/Runtime/Source/Viewer/Qt3DSAudioPlayerImpl.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 - 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_VIEWER_LIB_QT3DS_AUDIO_PLAYER_IMPL_H -#define QT3DS_VIEWER_LIB_QT3DS_AUDIO_PLAYER_IMPL_H - -#include "Qt3DSAudioPlayer.h" -#include "qt3dsruntimeglobal.h" - -namespace Q3DSViewer { - -class QT3DS_RUNTIME_API Qt3DSAudioPlayerImpl : public Q3DStudio::IAudioPlayer -{ -public: - Qt3DSAudioPlayerImpl(); - virtual ~Qt3DSAudioPlayerImpl(); - bool PlaySoundFile(const char *inFilePath) override; -}; -} - -#endif // !QT3DS_VIEWER_LIB_QT3DS_AUDIO_PLAYER_IMPL_H diff --git a/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp b/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp deleted file mode 100644 index d393f2af..00000000 --- a/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp +++ /dev/null @@ -1,766 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 - 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "EnginePrefix.h" -#include "Qt3DSTegraApplication.h" -#include "Qt3DSViewerApp.h" -#include "Qt3DSTegraInputEngine.h" -#include "Qt3DSInputFrame.h" // keyboard mapping -#include "foundation/Qt3DSTime.h" -#include "Qt3DSFNDTimer.h" -#include "Qt3DSAudioPlayer.h" - -#include -#include -#include - -#ifdef _MACOSX -#include -#endif - -namespace qt3ds { -void Qt3DSAssert(const char *exp, const char *file, int line, bool *ignore) -{ - Q_UNUSED(ignore) - qCritical() << "Assertion thrown: " << file << " " << line << " " << exp; -} -} - -#ifndef EASTL_DEBUG_BREAK -void EASTL_DEBUG_BREAK() -{ - qFatal("EASTL_DEBUG_BREAK: Assertion blown"); -} - -#endif - -#ifdef _WIN32 -#include -#include -#include "Qt3DSInputFrame.h" - -void HandleController(Q3DStudio::CTegraApplication &inApplication) -{ - static const class XInputLibrary - { - private: - typedef DWORD(__stdcall *GetStateFunction)(DWORD, XINPUT_STATE *); - - public: - XInputLibrary() - : m_module(NULL) - , GetState(NULL) - { - m_module = LoadLibraryA("XINPUT9_1_0.DLL"); - if (m_module != NULL) { - GetState = reinterpret_cast(GetProcAddress(m_module, - "XInputGetState")); - } - } - - ~XInputLibrary() - { - if (m_module != NULL) - FreeLibrary(m_module); - } - - GetStateFunction GetState; - - private: - HMODULE m_module; - } library; - - static const DWORD MAX_USERS = 4; - static const Q3DStudio::FLOAT STICK_RANGE = 32767; - static const Q3DStudio::FLOAT TRIGGER_RANGE = 255; - - static const struct ButtonEntry - { - WORD XBoxButton; - Q3DStudio::INT32 button; - } buttonMap[] = { - { XINPUT_GAMEPAD_START, Q3DStudio::BUTTON_START }, - { XINPUT_GAMEPAD_BACK, Q3DStudio::BUTTON_SELECT }, - { XINPUT_GAMEPAD_LEFT_THUMB, Q3DStudio::BUTTON_THUMBL }, - { XINPUT_GAMEPAD_RIGHT_THUMB, Q3DStudio::BUTTON_THUMBR }, - { XINPUT_GAMEPAD_LEFT_SHOULDER, Q3DStudio::BUTTON_L1 }, - { XINPUT_GAMEPAD_RIGHT_SHOULDER, Q3DStudio::BUTTON_R1 }, - { XINPUT_GAMEPAD_A, Q3DStudio::BUTTON_A }, - { XINPUT_GAMEPAD_B, Q3DStudio::BUTTON_B }, - { XINPUT_GAMEPAD_X, Q3DStudio::BUTTON_X }, - { XINPUT_GAMEPAD_Y, Q3DStudio::BUTTON_Y } }; - - static DWORD userLastPacketNumber[MAX_USERS] = { 0 }; - static WORD userLastButtons[MAX_USERS] = { 0 }; - - Q3DStudio::CInputEngine *input = inApplication.GetInputEngine(); - if (input != NULL && library.GetState) { - // for each controller - for (DWORD userIndex = 0; userIndex < MAX_USERS; ++userIndex) { - DWORD &lastPacketNumber = userLastPacketNumber[userIndex]; - WORD &lastButtons = userLastButtons[userIndex]; - - // get the state - XINPUT_STATE state = { 0 }; - if (library.GetState(userIndex, &state) == ERROR_SUCCESS - && state.dwPacketNumber != lastPacketNumber) { - using namespace Q3DStudio; - const XINPUT_GAMEPAD &gamepad = state.Gamepad; - const WORD &buttons = gamepad.wButtons; - - // handle button changes - DWORD buttonChanges = buttons ^ lastButtons; - for (size_t buttonMapIndex = 0; - buttonMapIndex < sizeof(buttonMap) / sizeof(buttonMap[0]); ++buttonMapIndex) { - const ButtonEntry &buttonEntry = buttonMap[buttonMapIndex]; - if (buttonEntry.XBoxButton & buttonChanges) { - input->HandleButton(buttonEntry.button, - buttons & buttonEntry.XBoxButton); - } - } - - // handle gamepad - if (buttons & XINPUT_GAMEPAD_DPAD_LEFT) - input->HandleAxis(AXIS_HAT_X, -1); - else if (buttons & XINPUT_GAMEPAD_DPAD_RIGHT) - input->HandleAxis(AXIS_HAT_X, 1); - else - input->HandleAxis(AXIS_HAT_X, 0); - if (buttons & XINPUT_GAMEPAD_DPAD_UP) - input->HandleAxis(AXIS_HAT_Y, -1); - else if (buttons & XINPUT_GAMEPAD_DPAD_DOWN) - input->HandleAxis(AXIS_HAT_Y, 1); - else - input->HandleAxis(AXIS_HAT_Y, 0); - - // handle sticks and triggers - input->HandleAxis(AXIS_X, gamepad.sThumbLX / STICK_RANGE); - input->HandleAxis(AXIS_Y, gamepad.sThumbLY / -STICK_RANGE); - input->HandleAxis(AXIS_Z, gamepad.sThumbRX / STICK_RANGE); - input->HandleAxis(AXIS_RZ, gamepad.sThumbRY / -STICK_RANGE); - input->HandleAxis(AXIS_LTRIGGER, gamepad.bLeftTrigger / TRIGGER_RANGE); - input->HandleAxis(AXIS_RTRIGGER, gamepad.bRightTrigger / TRIGGER_RANGE); - - // save the state - lastButtons = buttons; - lastPacketNumber = state.dwPacketNumber; - } - } - } -} -#endif - -using namespace Q3DStudio; - -struct WindowRect -{ - int x; - int y; - int width; - int height; -}; - -void PerfLogSetStringData(const char *) -{ -} // Dummy defination when TCP perf logging isnt used - -Q3DStudio::Qt3DSFNDTimer g_GlobalTimeProvider; - -qint64 GetTimeUST() -{ - // this needs to be nano seconds - Q3DStudio::ITimeProvider &theTimer = g_GlobalTimeProvider; - return theTimer.GetCurrentTimeMicroSeconds() * 1000; -} - -void initResource() { - // init runtime static resources - Q_INIT_RESOURCE(res); -} - -namespace Q3DSViewer { - -struct SWindowSystemImpl : public Q3DStudio::IWindowSystem -{ - QSize m_size; - int m_OffscreenID; - int m_DepthBitCount; - - QSize GetWindowDimensions() override { return m_size; } - void SetWindowDimensions(const QSize &inSize) override - { - m_size = inSize; - } - // For platforms that support it, we get the egl info for render plugins - // Feel free to return NULL. - SEGLInfo *GetEGLInfo() override { return NULL; } - // on some systems we allow our default render target to be a offscreen buffer - // otherwise return 0; - int GetDefaultRenderTargetID() override { return m_OffscreenID; } - // returns the depth buffer bit count for the render window - int GetDepthBitCount() override { return m_DepthBitCount; } -}; - -class Q3DSViewerAppImpl -{ -public: - Q3DSViewerAppImpl(Q3DStudio::IAudioPlayer *inAudioPlayer) - : m_tegraApp(0) - , m_appInitSuccessful(false) - , m_AudioPlayer(inAudioPlayer) - { -#ifndef EMBEDDED_LINUX - initResource(); -#endif - } - Q3DStudio::CTegraApplication *m_tegraApp; ///< pointer to internal "tegra appliction" - bool m_appInitSuccessful; ///< true if m_tegraApp is initialized successful - - std::vector m_mouseButtons; - Q3DStudio::IWindowSystem *m_WindowSystem; - - IAudioPlayer *m_AudioPlayer; - QVector m_pendingEvents; - - QString m_error; - - void queueMouseEvent(int button, int pressed, int x, int y) - { - QMouseEvent *e = new QMouseEvent(pressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease, - QPointF(x, y), (Qt::MouseButton)button, - (Qt::MouseButtons)button, 0); - e->setTimestamp(static_cast(GetTimeUST())); - m_pendingEvents.append(e); - } -}; - -///< @brief contructor -Q3DSViewerApp::Q3DSViewerApp(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer) - : m_Impl(*new Q3DSViewerAppImpl(inAudioPlayer)) -{ - Q_UNUSED(glContext) - m_Impl.m_WindowSystem = new SWindowSystemImpl(); -} - -///< @brief destructor -Q3DSViewerApp::~Q3DSViewerApp() -{ - qDeleteAll(m_Impl.m_pendingEvents); - - delete m_Impl.m_AudioPlayer; - - if (m_Impl.m_tegraApp) { - disconnect(m_Impl.m_tegraApp->getNDDView()->signalProxy(), 0); - - m_Impl.m_tegraApp->Cleanup(); - Q3DStudio_virtual_delete(m_Impl.m_tegraApp, CTegraApplication); - - if (GetMemoryManager().GetLineTracker()) - GetMemoryManager().GetLineTracker()->Report(); - - GetMemoryManager().Release(); - } - delete static_cast(m_Impl.m_WindowSystem); -} - -void Q3DSViewerApp::setOffscreenId(int offscreenID) -{ - static_cast(m_Impl.m_WindowSystem)->m_OffscreenID - = offscreenID; - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) - m_Impl.m_tegraApp->GetTegraRenderEngine()->ensureRenderTarget(); -} - -bool Q3DSViewerApp::InitializeApp(int winWidth, int winHeight, const QSurfaceFormat &format, - int offscreenID, const QString &source, - const QStringList &variantList, - qt3ds::Qt3DSAssetVisitor *assetVisitor) -{ - bool hasValidPresentationFile = !source.isEmpty(); - - QFileInfo info(source); - if (!info.exists()) { - m_Impl.m_error - = QObject::tr("Failed to initialize viewer, presentation doesn't exist"); - qCritical() << m_Impl.m_error; - return false; - } - - m_Impl.m_WindowSystem->SetWindowDimensions(QSize(winWidth, winHeight)); - - // create our internal application - if (hasValidPresentationFile && !m_Impl.m_tegraApp) { - static_cast(m_Impl.m_WindowSystem)->m_OffscreenID = offscreenID; - static_cast(m_Impl.m_WindowSystem)->m_DepthBitCount - = format.depthBufferSize(); - - // create memory manager - // GetMemoryManager( ).Initialize( "GlobalManager", g_ChunkSize, g_ChunkCount ); - // create internal app - m_Impl.m_tegraApp = Q3DStudio_virtual_new(CTegraApplication) - CTegraApplication(g_GlobalTimeProvider, *m_Impl.m_WindowSystem, - m_Impl.m_AudioPlayer); - - if (assetVisitor) - m_Impl.m_tegraApp->getNDDView()->setAssetVisitor(assetVisitor); - - m_Impl.m_appInitSuccessful = m_Impl.m_tegraApp->BeginLoad(source, variantList); - - // Simulate killing the application during loading. Useful for finding serious issues with - // loading. - /*for ( unsigned idx = 0; idx < 100; ++idx ) - { - Sleep( 10*idx ); - m_Impl.m_tegraApp->Cleanup(); - Q3DStudio_virtual_delete( m_Impl.m_tegraApp, CTegraApplication ); - - m_Impl.m_tegraApp = - Q3DStudio_virtual_new(CTegraApplication)CTegraApplication(g_GlobalTimeProvider, - *m_Impl.m_WindowSystem); - m_Impl.m_appInitSuccessful = m_Impl.m_tegraApp->BeginLoad( viewerArgs ) ? true : - false; - }*/ - - if (m_Impl.m_appInitSuccessful == false) { - m_Impl.m_error = QObject::tr("Viewer launch failure! Failed to load: '%1'").arg(source); - m_Impl.m_error.append("\n"); - qCritical() << m_Impl.m_error; - return false; - } - - bool success = m_Impl.m_tegraApp->InitializeGraphics(format); - if (!success) { - m_Impl.m_error = QObject::tr("Viewer launch failure! Failed to load: '%1'").arg(source); - m_Impl.m_error.append("\n"); - qCritical() << m_Impl.m_error; - return false; - } - - // Connect signals - connect(m_Impl.m_tegraApp->getNDDView()->signalProxy(), - &QINDDViewSignalProxy::SigSlideEntered, this, &Q3DSViewerApp::SigSlideEntered); - connect(m_Impl.m_tegraApp->getNDDView()->signalProxy(), - &QINDDViewSignalProxy::SigSlideExited, this, &Q3DSViewerApp::SigSlideExited); - - Resize(winWidth, winHeight); - - Q_EMIT SigPresentationReady(); - } - return true; -} - -bool Q3DSViewerApp::IsInitialised(void) -{ - return m_Impl.m_tegraApp != NULL && m_Impl.m_appInitSuccessful == true; -} - -int Q3DSViewerApp::GetWindowHeight() -{ - return m_Impl.m_WindowSystem->GetWindowDimensions().width(); -} - -int Q3DSViewerApp::GetWindowWidth() -{ - return m_Impl.m_WindowSystem->GetWindowDimensions().height(); -} - -void Q3DSViewerApp::setupSearchPath(std::vector &cmdLineArgs) -{ - // setup some additional search path - // index 0 contains the module directory -#ifdef _MACOSX - char buf[2056]; - uint32_t bufsize = 2056; - _NSGetExecutablePath(buf, &bufsize); - std::string theModuleDirectory = buf; -#else - std::string theModuleDirectory = cmdLineArgs[0]; -#endif - std::string::size_type pos = theModuleDirectory.rfind('\\'); - if (pos == std::string::npos) - pos = theModuleDirectory.rfind('/'); - - // Include the slash - theModuleDirectory = theModuleDirectory.substr(0, pos + 1); - - // TODO: Search path needs to be set up properly - //NvFAppendSearchPath(theModuleDirectory.c_str()); -} - -void Q3DSViewerApp::Render() -{ - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { - if (m_Impl.m_appInitSuccessful) { - for (QEvent *e : m_Impl.m_pendingEvents) { - m_Impl.m_tegraApp->HandleMessage(e); - delete e; - } - m_Impl.m_pendingEvents.clear(); -#ifdef WIN32 - HandleController(*m_Impl.m_tegraApp); -#endif - - m_Impl.m_tegraApp->Render(); - } - } -} - -void Q3DSViewerApp::SaveState() -{ - if (!m_Impl.m_tegraApp) - return; - - if (m_Impl.m_tegraApp->GetTegraRenderEngine()) { - ITegraRenderStateManager &manager = - m_Impl.m_tegraApp->GetTegraRenderEngine()->GetTegraRenderStateManager(); - - manager.SaveAllState(); - } -} - -void Q3DSViewerApp::RestoreState() -{ - if (!m_Impl.m_tegraApp) - return; - - if (m_Impl.m_tegraApp->GetTegraRenderEngine()) { - ITegraRenderStateManager &manager = - m_Impl.m_tegraApp->GetTegraRenderEngine()->GetTegraRenderStateManager(); - - manager.RestoreAllState(); - } -} - -bool Q3DSViewerApp::WasLastFrameDirty() -{ - if (m_Impl.m_tegraApp) - return m_Impl.m_tegraApp->WasLastFrameDirty(); - return false; -} - -QString Q3DSViewerApp::error() -{ - QString error = m_Impl.m_error; - m_Impl.m_error.clear(); - return error; -} - -void Q3DSViewerApp::Resize(int width, int height) -{ - QSize oldSize = m_Impl.m_WindowSystem->GetWindowDimensions(); - QSize newSize(width, height); - m_Impl.m_WindowSystem->SetWindowDimensions(newSize); - - if (m_Impl.m_appInitSuccessful && m_Impl.m_tegraApp - && m_Impl.m_tegraApp->GetTegraRenderEngine()) { - QResizeEvent event = QResizeEvent(newSize, oldSize); - m_Impl.m_tegraApp->HandleMessage(&event); - } -} - -void Q3DSViewerApp::HandleKeyInput(Q3DStudio::EKeyCode inKeyCode, bool isPressed) -{ - if (!m_Impl.m_tegraApp || inKeyCode == Q3DStudio::KEY_NOKEY) - return; - - CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); - if (input) - input->HandleKeyboard(inKeyCode, isPressed); -} - -void Q3DSViewerApp::HandleMouseMove(int x, int y, bool isPressed) -{ - if (!m_Impl.m_tegraApp) - return; - - CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); - if (input) { - input->BeginPickInput(); - input->EndPickInput(); - input->SetPickInput(static_cast(x), static_cast(y), - isPressed); - } - -} - -void Q3DSViewerApp::HandleMousePress(int x, int y, int mouseButton, bool isPressed) -{ - if (!m_Impl.m_tegraApp) - return; - - bool hasButton - = std::find(m_Impl.m_mouseButtons.begin(), m_Impl.m_mouseButtons.end(), mouseButton) - != m_Impl.m_mouseButtons.end(); - - if ((mouseButton == 1 || mouseButton == 2)) { - // We keep track of the mouse presses because there are situations where the application - // will not give us a mouse - // up for each mouse down. This ameleorates the effects of those slightly misbehaving - // applications. - if (isPressed == hasButton) { - bool localIsPressed = !isPressed; - // Slightly recursive call in order to handle situations where we aren't getting - // the mouse up with the corresponding mouse down or vice versa. - HandleMousePress(x, y, mouseButton, localIsPressed); - HandleMousePress(x, y, mouseButton, isPressed); - } else { - if (isPressed) { - m_Impl.m_mouseButtons.push_back(mouseButton); - qCInfo(qt3ds::TRACE_INFO) - << "ViewerApp: Mouse down of frame " - << m_Impl.m_tegraApp->GetFrameCount(); - } else { - m_Impl.m_mouseButtons.erase(std::remove(m_Impl.m_mouseButtons.begin(), - m_Impl.m_mouseButtons.end(), mouseButton), - m_Impl.m_mouseButtons.end()); - } - - CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); - - if (input) { - input->BeginPickInput(); - input->SetPickInput(static_cast(x), - static_cast(y), isPressed); - input->EndPickInput(); - - m_Impl.queueMouseEvent(mouseButton, isPressed ? 1 : 0, x, y); - } - } - } -} - -void Q3DSViewerApp::HandleMouseWheel(int x, int y, int orientation, int numSteps) -{ - if (!m_Impl.m_tegraApp) - return; - - CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); - if (input) { - input->SetPickInput(static_cast(x), static_cast(y), 0); - input->SetScrollValue(orientation == 0 ? VSCROLLWHEEL : HSCROLLWHEEL, numSteps); - } -} - -void Q3DSViewerApp::GoToSlideByName(const char *elementPath, const char *slideName) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->GoToSlideByName(elementPath, slideName); -} - -void Q3DSViewerApp::GoToSlideByIndex(const char *elementPath, const int slideIndex) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->GoToSlideByIndex(elementPath, slideIndex); -} - -void Q3DSViewerApp::GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->GoToSlideRelative(elementPath, next, wrap); -} - -bool Q3DSViewerApp::GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName) -{ - if (!m_Impl.m_tegraApp) - return false; - - return m_Impl.m_tegraApp->GetSlideInfo(elementPath, currentIndex, previousIndex, - currentName, previousName); -} - -void Q3DSViewerApp::SetPresentationActive(const char *presId, const bool active) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->SetPresentationAttribute(presId, nullptr, active ? "True" : "False"); -} - -void Q3DSViewerApp::GoToTime(const char *elementPath, const float time) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->GoToTime(elementPath, time); -} - -void Q3DSViewerApp::PlaySoundFile(const char *soundPath) -{ - if (!m_Impl.m_AudioPlayer || !soundPath) - return; - - m_Impl.m_AudioPlayer->PlaySoundFile(soundPath); -} - -void Q3DSViewerApp::SetAttribute(const char *elementPath, const char *attributeName, - const char *value) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->SetAttribute(elementPath, attributeName, value); -} - -bool Q3DSViewerApp::GetAttribute(const char *elementPath, const char *attributeName, void *value) -{ - if (!m_Impl.m_tegraApp) - return false; - - return m_Impl.m_tegraApp->GetAttribute(elementPath, attributeName, value); -} - -void Q3DSViewerApp::FireEvent(const char *elementPath, const char *evtName) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->FireEvent(elementPath, evtName); -} - -bool Q3DSViewerApp::PeekCustomAction(std::string &outElementPath, std::string &outActionName) -{ - if (!m_Impl.m_tegraApp) - return false; - - char *theElementPath = NULL; - char *theActioName = NULL; - bool retVal = m_Impl.m_tegraApp->PeekCustomAction(theElementPath, theActioName); - - if (theElementPath) - outElementPath = theElementPath; - if (theActioName) - outActionName = theActioName; - - return retVal; -} - -bool Q3DSViewerApp::RegisterScriptCallback(ViewerCallbackType::Enum inCallbackType, - const qml_Function inCallback, void *inUserData) -{ - if (!m_Impl.m_tegraApp) - return false; - - // convert to int - int callbackType = 0; - if (inCallbackType == Q3DSViewer::ViewerCallbackType::CALLBACK_ON_INIT) - callbackType = 1; - else if (inCallbackType == Q3DSViewer::ViewerCallbackType::CALLBACK_ON_UPDATE) - callbackType = 2; - else - return false; - - bool retVal = m_Impl.m_tegraApp->RegisterScriptCallback(callbackType, inCallback, inUserData); - - return retVal; -} - -void Q3DSViewerApp::SetScaleMode(ViewerScaleModes::Enum inScale) -{ - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { - m_Impl.m_tegraApp->GetTegraRenderEngine()->SetScaleMode( - static_cast(inScale)); - } -} - -ViewerScaleModes::Enum Q3DSViewerApp::GetScaleMode() -{ - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { - return static_cast( - m_Impl.m_tegraApp->GetTegraRenderEngine()->GetScaleMode()); - } - - return ViewerScaleModes::ExactSize; -} - -void Q3DSViewerApp::setMatteColor(const QColor &color) -{ - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { - m_Impl.m_tegraApp->GetTegraRenderEngine()->SetMatteColor( - qt3ds::QT3DSVec4(color.redF(), color.greenF(), - color.blueF(), color.alphaF())); - } -} - -void Q3DSViewerApp::setShowOnScreenStats(bool inShow) -{ - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) - m_Impl.m_tegraApp->getNDDView()->showOnScreenStats(inShow); -} - -void Q3DSViewerApp::SetShadeMode(ViewerShadeModes::Enum inShadeMode) -{ - if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { - StaticAssert::valid_expression(); - StaticAssert::valid_expression(); - StaticAssert::valid_expression(); - - m_Impl.m_tegraApp->GetTegraRenderEngine()->SetShadeMode( - static_cast(inShadeMode)); - } -} - -void Q3DSViewerApp::SetGlobalAnimationTime(qint64 inMilliSecs) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->SetGlobalAnimationTime(inMilliSecs); -} - -void Q3DSViewerApp::SetDataInputValue(const QString &name, const QVariant &value) -{ - if (!m_Impl.m_tegraApp) - return; - - m_Impl.m_tegraApp->SetDataInputValue(name, value); -} - -Q3DSViewerApp &Q3DSViewerApp::Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer) -{ - return *Q3DStudio_virtual_new(Q3DSViewerApp) Q3DSViewerApp(glContext, inAudioPlayer); -} - -void Q3DSViewerApp::Release() -{ - Q3DStudio_virtual_delete(this, Q3DSViewerApp); -} - -} // end namespace diff --git a/src/Runtime/Source/Viewer/Qt3DSViewerApp.h b/src/Runtime/Source/Viewer/Qt3DSViewerApp.h deleted file mode 100644 index 0d56c3a1..00000000 --- a/src/Runtime/Source/Viewer/Qt3DSViewerApp.h +++ /dev/null @@ -1,390 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 - 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_VIEWER_H -#define QT3DS_VIEWER_H - -#include "qt3dsruntimeglobal.h" - -#include -#include -#include - -#include "Qt3DSInputDefs.h" - -#include - -namespace Q3DStudio { -class CTegraApplication; -class IWindowSystem; -class IAudioPlayer; -} - -namespace qt3ds { -class Qt3DSAssetVisitor -{ -public: - virtual void visit(const char *path) = 0; - virtual void visit(const char *type, const char *id, const char *src, const char *args) = 0; -}; -} - -namespace Q3DSViewer { - -typedef void (*qml_Function)(void *inUserData); - -// not must match the NDDRuntime see -// UICQmlEngine.h -struct ViewerCallbackType -{ - enum Enum { - CALLBACK_ON_INIT = 1, - CALLBACK_ON_UPDATE = 2, - }; -}; - -struct ViewerContextType -{ - enum Enum { GL_ES2 = 0, GL_ES3, GL_ES31, GL_ES32, GL_2, GL_3_3, GL_4 }; -}; - -struct ViewerScaleModes -{ - enum Enum { - ExactSize = 0, // Ensure the viewport is exactly same size as application - ScaleToFit = 1, // Resize viewport keeping aspect ratio - ScaleToFill = 2, // Resize viewport to entire window - }; -}; - -struct ViewerShadeModes -{ - enum Enum { - Shaded = 0, // Geometry is shaded only - ShadedWireframe = 1, // Wireframe is drawn on top shaded geometry - Wireframe = 2, // Wireframe only - }; -}; - -class Q3DSViewerAppImpl; -class QT3DS_RUNTIME_API Q3DSViewerApp : public QObject -{ - Q_OBJECT -private: - Q3DSViewerApp(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer); - ~Q3DSViewerApp(); - -public: - /** - * @brief Initialize viewer app - * - * @param[in] winWidth window width - * @param[in] winHeight window height - * @param[in] format OpenGL API version - * @param[in] offscreenID ID of an OpenGL FBO we should render to by default - * @param[in] source string to presentation source - * - * @return true on success - */ - bool InitializeApp(int winWidth, int winHeight, const QSurfaceFormat& format, - int offscreenID, const QString &source, - const QStringList &variantList, - qt3ds::Qt3DSAssetVisitor *assetVisitor = nullptr); - - bool IsInitialised(void); - void setOffscreenId(int offscreenID); - - - /* - * @brief handle window resize - * - * @param[in] width new width - * @param[in] height new size - * - * @return no return - */ - void Resize(int width, int height); - - /* - * @brief does the actual scene rendering - * - * @return no return - */ - void Render(); - - /* - * @brief handle keyboard input - * - * @param[in] keyEvent event - * @param[in] isPressed true if key pressed - * - * @return no return - */ - void HandleKeyInput(Q3DStudio::EKeyCode inKeyCode, bool isPressed); - - /* - * @brief handle mouse move input - * - * @param[in] x mouse pos x - * @param[in] y mouse pos y - * @param[in] mouseButton mouse button id - * @param[in] isPressed true if key pressed - * - * @return no return - */ - void HandleMouseMove(int x, int y, bool isPressed); - - /* - * @brief handle mouse press events - * - * @param[in] x mouse pos x - * @param[in] y mouse pos y - * @param[in] mouseButton mouse button id - * @param[in] isPressed true if key pressed - * - * @return no return - */ - void HandleMousePress(int x, int y, int mouseButton, bool isPressed); - - /* - * @brief handle mouse wheel events - * - * @param[in] x mouse pos x - * @param[in] y mouse pos y - * @param[in] orientation 0 vertical, 1 horizontal - * @param[in] numSteps how much the wheel has turned - * - * @return no return - */ - void HandleMouseWheel(int x, int y, int orientation, int numSteps); - - /* - * @brief Scale scene to adjsut to window size regarding width and height - * - * @param[in] inScale true if scale false if unscale - * - * @return no return - */ - void SetScaleMode(ViewerScaleModes::Enum inScaleMode); - - ViewerScaleModes::Enum GetScaleMode(); - - void setMatteColor(const QColor &color); - void setShowOnScreenStats(bool s); - - /* - * @brief Set the shading mode - * - * @param[in] inShadeMode the selected shade mode - * - * @return no return - */ - void SetShadeMode(ViewerShadeModes::Enum inShadeMode); - - /* - * @brief Save current render state - * - * @return no return - */ - void SaveState(); - /* - * @brief Restore current render state - * - * @return no return - */ - void RestoreState(); - - /// event call back slots - - /* - * @brief Go to a slide by name - * - * @param[in] elementPath where to find the element - * @param[in] slideName slide name - * - * @return no return - */ - void GoToSlideByName(const char *elementPath, const char *slideName); - - /* - * @brief Go to a slide by index - * - * @param[in] elementPath where to find the element - * @param[in] slideIndex slide index - * - * @return no return - */ - void GoToSlideByIndex(const char *elementPath, const int slideIndex); - - /* - * @brief Go to relative slide - * - * @param[in] elementPath where to find the element - * @param[in] next next or previous - * @param[in] wrap wrap to beginning if end is reached - * - * @return no return - */ - void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap); - - bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, - QString ¤tName, QString &previousName); - - /* - * @brief Set presentation active or inactive - * - * @param[in] presId presentation id (name without .uip) - * @param[in] active set active or inactive - * - * @return no return - */ - void SetPresentationActive(const char *presId, const bool active); - - /* - * @brief Go to a certain time - * - * @param[in] elementPath where to find the element - * @param[in] time time to move - * - * @return no return - */ - void GoToTime(const char *elementPath, const float time); - - /* - * @brief Play a sound - * - * @param[in] soundPath sound file to play - * - * @return no return - */ - void PlaySoundFile(const char *soundPath); - - /* - * @brief Set attribute values - * - * @param[in] elementPath where to find the element - * @param[in] attributeName attribute name - * @param[in] value new value of the attribute - * - * @return no return - */ - void SetAttribute(const char *elementPath, const char *attributeName, const char *value); - - /* - * @brief Get attribute values - * - * @param[in] elementPath where to find the element - * @param[in] attributeName attribute name - * @param[out] value current attribute values - * - * @return true if successful - */ - bool GetAttribute(const char *elementPath, const char *attributeName, void *value); - - /* - * @brief Fire an event - * - * @param[in] elementPath where to find the element to fire the event on - * @param[in] evtName the string that identifies and defines the event - * - * @return no return - */ - void FireEvent(const char *elementPath, const char *evtName); - - /* - * @brief Peek a custom action from the queue - * Note the action is remvoved from the queue - * - * @param[out] outElementPath element path - * @param[out] actionName action name - * - * @return true if action available - */ - bool PeekCustomAction(std::string &outElementPath, std::string &actionName); - - /** - * @brief Register a callback - * - * @param[in] callbackType callback type - * @param[in] inCallback pointer to callback - * @param[in] inCallback pointer to user data - * - * @return true on success - */ - bool RegisterScriptCallback(ViewerCallbackType::Enum callbackType, - const qml_Function inCallback, void *inUserData); - - bool WasLastFrameDirty(); - - int GetWindowHeight(); - int GetWindowWidth(); - - void SetGlobalAnimationTime(qint64 inMilliSecs); - - void SetDataInputValue(const QString &name, const QVariant &value); - - QString error(); - -private: - /* - * @brief parse command line arguments this fills in our - * global command line variables - * - * @param[in] cmdLineArgs string to command line parameter - * - * @return no return - */ - void handleCmdLineArguments(std::vector &cmdLineArgs); - /* - * @brief setup search path. - * This functions setup additonal search path for resoruces - * - * @param[in] cmdLineArgs string to command line parameter - * - * @return no return - */ - void setupSearchPath(std::vector &cmdLineArgs); - -private: - Q3DSViewerAppImpl &m_Impl; - -public: - static Q3DSViewerApp &Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer = 0); - void Release(); - -Q_SIGNALS: - void SigSlideEntered(const QString &elementPath, unsigned int index, const QString &name); - void SigSlideExited(const QString &elementPath, unsigned int index, const QString &name); - void SigPresentationReady(); -}; - -} // end namespace - -#endif // QT3DS_VIEWER_H diff --git a/src/Runtime/Source/Viewer/Qt3DSViewerTimer.h b/src/Runtime/Source/Viewer/Qt3DSViewerTimer.h deleted file mode 100644 index de679ce9..00000000 --- a/src/Runtime/Source/Viewer/Qt3DSViewerTimer.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 - 2016 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DS_ELAPSED_TIMER_H -#define QT3DS_ELAPSED_TIMER_H -#include - -namespace Q3DSViewer { - -///< @brief this class implementes a elapsed timer using QElapsedTimer -class Qt3DSElapsedTimer -{ -public: - QElapsedTimer m_elapsedTimer; - QElapsedTimer::ClockType m_clockType; - - Qt3DSElapsedTimer() - { - m_clockType = QElapsedTimer::clockType(); - reset(); - } - - void reset() { m_elapsedTimer.start(); } - - qint64 getNanoSeconds() - { - qint64 time = m_elapsedTimer.nsecsElapsed(); - reset(); - return time; - } -}; - -///< @brief this class implementes a timer using QElapsedTimer -class Qt3DSTimer -{ -public: - QElapsedTimer m_timer; - - Qt3DSTimer() { start(); } - - void start() { m_timer.start(); } - - qint64 getNanoSeconds() { return static_cast(m_timer.elapsed() * 1000 * 1000); } -}; - -///< @brief this class implementes a circular buffer -template -struct NumericCircularBuffer -{ - unsigned long m_TotalNumElements; ///< holds the current number of elements - unsigned long m_NumElements; ///< restricts the size to TBufferSize and wrappes around - unsigned long m_NextIndex; ///< next index - TDataType m_RunningTotal; ///< summed value of all entries - TDataType m_Elements[TBufferSize]; ///< element buffer - - NumericCircularBuffer() { clear(); } - void clear() - { - m_TotalNumElements = 0; - m_NumElements = 0; - m_NextIndex = 0; - m_RunningTotal = 0; - memset(m_Elements, 0, sizeof(TDataType) * TBufferSize); - } - - void push_back(const TDataType &data) - { - if (m_NumElements < TBufferSize) - ++m_NumElements; - else - m_RunningTotal -= m_Elements[m_NextIndex]; - m_RunningTotal += data; - ++m_TotalNumElements; - m_Elements[m_NextIndex] = data; - m_NextIndex = (m_NextIndex + 1) % TBufferSize; - } - unsigned long size() const { return m_NumElements; } - TDataType average() const - { - TDataType mySize = ((TDataType)size()); - if (mySize) - return m_RunningTotal / mySize; - return 0; - } - - unsigned long getTotalItems() const { return m_TotalNumElements; } - - static unsigned long getBufferSize() { return TBufferSize; } -}; - -} // end namspace - -#endif // QT3DS_ELAPSED_TIMER_H diff --git a/src/Runtime/Source/Viewer/qt3dsruntimeglobal.h b/src/Runtime/Source/Viewer/qt3dsruntimeglobal.h deleted file mode 100644 index 6732c85d..00000000 --- a/src/Runtime/Source/Viewer/qt3dsruntimeglobal.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DSRUNTIMEGLOBAL_H -#define QT3DSRUNTIMEGLOBAL_H - -#include - -#ifndef _INTEGRITYPLATFORM -#if defined QT3DS_RUNTIME_EXPORTS -#define QT3DS_RUNTIME_API Q_DECL_EXPORT -#else -#define QT3DS_RUNTIME_API Q_DECL_IMPORT -#endif -#else -#define QT3DS_RUNTIME_API -#endif - -#endif // QT3DSRUNTIMEGLOBAL_H diff --git a/src/Runtime/Source/datamodel/DocumentResourceManagerCustomMaterialParser.h b/src/Runtime/Source/datamodel/DocumentResourceManagerCustomMaterialParser.h new file mode 100644 index 00000000..47a8092d --- /dev/null +++ b/src/Runtime/Source/datamodel/DocumentResourceManagerCustomMaterialParser.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2002 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef DOCUMENTRESOURCEMANAGERCUSTOMMATERIALPARSERH +#define DOCUMENTRESOURCEMANAGERCUSTOMMATERIALPARSERH + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "Qt3DSDMXML.h" +#include "Qt3DSDMDataTypes.h" +#include "Qt3DSDMMetaData.h" +#include "Qt3DSDMWStrOpsImpl.h" +#include "foundation/StrConvertUTF.h" +#include +#include "Qt3DSRenderInputStreamFactory.h" + +namespace Q3DStudio { +struct CCustomMaterialParser +{ + + static bool NavigateToMetadata(std::shared_ptr inReader) + { + return inReader->MoveToFirstChild("MetaData"); + } + + static std::shared_ptr + ParseFile(std::shared_ptr inFactory, + std::shared_ptr inStringTable, const char8_t *inFileData, + qt3dsdm::CXmlErrorHandler &inErrorHandler, + qt3ds::render::IInputStreamFactory &inStreamFactory) + { + using namespace qt3ds; + using namespace qt3ds::foundation; + + NVScopedRefCounted theStream( + inStreamFactory.GetStreamForFile(inFileData)); + if (!theStream) { + QT3DS_ASSERT(0); + return std::shared_ptr(); + } + + qt3dsdm::SDOMElement *theElem( + qt3dsdm::CDOMSerializer::Read(*inFactory, *theStream, &inErrorHandler)); + + if (theElem == NULL) { + return std::shared_ptr(); + } else + return qt3dsdm::IDOMReader::CreateDOMReader(*theElem, inStringTable, inFactory); + } +}; +} + +#endif diff --git a/src/Runtime/Source/datamodel/DocumentResourceManagerRenderPluginParser.h b/src/Runtime/Source/datamodel/DocumentResourceManagerRenderPluginParser.h new file mode 100644 index 00000000..e3eee1cf --- /dev/null +++ b/src/Runtime/Source/datamodel/DocumentResourceManagerRenderPluginParser.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2002 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef DOCUMENTRESOURCEMANAGERRENDERPLUGINPARSERH +#define DOCUMENTRESOURCEMANAGERRENDERPLUGINPARSERH + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "Qt3DSDMXML.h" +#include "Qt3DSDMDataTypes.h" +#include "Qt3DSDMMetaData.h" +#include "Qt3DSDMWStrOpsImpl.h" +#include "foundation/StrConvertUTF.h" +#include +#include "Qt3DSRenderInputStreamFactory.h" + +namespace Q3DStudio { +struct CRenderPluginParser +{ + + static bool NavigateToMetadata(std::shared_ptr inReader) + { + return inReader->MoveToFirstChild("metadata"); + } + + static std::shared_ptr + ParseFile(std::shared_ptr inFactory, + std::shared_ptr inStringTable, const char8_t *inFileData, + qt3dsdm::CXmlErrorHandler &inErrorHandler, + qt3ds::render::IInputStreamFactory &inStreamFactory) + { + using namespace qt3ds; + using namespace qt3ds::foundation; + + NVScopedRefCounted theStream( + inStreamFactory.GetStreamForFile(inFileData)); + if (!theStream) { + QT3DS_ASSERT(0); + return std::shared_ptr(); + } + + qt3dsdm::SDOMElement *theElem( + qt3dsdm::CDOMSerializer::Read(*inFactory, *theStream, &inErrorHandler)); + + if (theElem == NULL) { + return std::shared_ptr(); + } else + return qt3dsdm::IDOMReader::CreateDOMReader(*theElem, inStringTable, inFactory); + } +}; +} + +#endif diff --git a/src/Runtime/Source/datamodel/DocumentResourceManagerScriptParser.h b/src/Runtime/Source/datamodel/DocumentResourceManagerScriptParser.h new file mode 100644 index 00000000..4c2ce437 --- /dev/null +++ b/src/Runtime/Source/datamodel/DocumentResourceManagerScriptParser.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DOCUMENTRESOURCEMANAGERSCRIPTPARSER_H +#define DOCUMENTRESOURCEMANAGERSCRIPTPARSER_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "Qt3DSDMXML.h" +#include "Qt3DSDMDataTypes.h" +#include "Qt3DSDMMetaData.h" +#include "Qt3DSRenderInputStreamFactory.h" + +namespace Q3DStudio { +namespace ScriptParser { + + using namespace qt3dsdm; + using namespace Q3DStudio; + + struct StringInStream : qt3ds::foundation::IInStream + { + const QString &m_String; + QT3DSU32 m_Offset; + + StringInStream(const QString &str) + : m_String(str) + , m_Offset(0) + { + } + + QT3DSU32 Read(NVDataRef data) override + { + std::string str = m_String.toUtf8().constData(); + const char *theStart((const char *)str.c_str()); + const char *theEnd(theStart + str.size()); + + QT3DSU32 amountLeft = QT3DSU32(theEnd - theStart) - m_Offset; + QT3DSU32 amountToRead = qt3ds::NVMin(data.size(), amountLeft); + qt3ds::intrinsics::memCopy(data.begin(), theStart + m_Offset, amountToRead); + m_Offset += amountToRead; + return amountToRead; + } + }; + + struct SScriptParser + { + static std::shared_ptr + ParseScriptFile(std::shared_ptr factory, + std::shared_ptr stringTable, + const QString &fullPath, CXmlErrorHandler &errorHandler, + qt3ds::render::IInputStreamFactory &streamFactory) + { + QVector readBuf; + { + using namespace qt3ds; + using namespace qt3ds::foundation; + eastl::string strConvert; + NVScopedRefCounted stream( + streamFactory.GetStreamForFile(fullPath)); + if (!stream) { + QT3DS_ASSERT(0); + return std::shared_ptr(); + } + + QT3DSU32 readLen = 0; + do { + uint32_t offset = readBuf.size(); + readBuf.resize(offset + 4096); + readLen = stream->Read(NVDataRef(&readBuf[0] + offset, 4096)); + readBuf.resize(offset + readLen); + } while (readLen == 4096); + } + + QByteArray byteArray; + for (auto &&c : qAsConst(readBuf)) + byteArray.append(c); + + QString code = QString::fromUtf8(byteArray); + + bool skipXml = false; + auto start = code.indexOf("/*[["); + if (start == -1) + skipXml = true; + + QString tagged("\n"); + if (!skipXml) { + start += 4; + auto end = code.indexOf("]]*/", start); + if (end == -1) + return std::shared_ptr(); + + QString xml = code.mid(start, end - start).trimmed(); + + tagged.append(xml); + } + tagged.append("\n"); + tagged.replace("\r\n", "\n"); + + StringInStream xmlStream(tagged); + + SDOMElement *element(CDOMSerializer::Read(*factory, xmlStream, &errorHandler)); + if (element == NULL) + return std::shared_ptr(); + + return IDOMReader::CreateDOMReader(*element, stringTable, factory); + } + }; +} +} + +#endif // DOCUMENTRESOURCEMANAGERSCRIPTPARSER_H diff --git a/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp b/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp new file mode 100644 index 00000000..99d7cb8e --- /dev/null +++ b/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp @@ -0,0 +1,985 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSDMPrefix.h" +#include "Qt3DSMetadata.h" +#include "SimpleDataCore.h" +#include "Qt3DSDMXML.h" +#include "foundation/IOStreams.h" +#include "Qt3DSEulerAngles.h" +#include "Qt3DSDMWindowsCompatibility.h" +#include "Qt3DSDMComposerTypeDefinitions.h" +#include "DocumentResourceManagerScriptParser.h" +#include "foundation/StrConvertUTF.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "foundation/FileTools.h" +#include "foundation/TrackingAllocator.h" +#include "EASTL/hash_map.h" +#include "DocumentResourceManagerRenderPluginParser.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StringTable.h" + +using qt3ds::render::IInputStreamFactory; +using qt3ds::render::IRefCountedInputStream; + +using namespace qt3dsdm; +using namespace Q3DStudio; + +namespace { + + +struct SImportXmlErrorHandler : public CXmlErrorHandler +{ + void OnXmlError(const QString &errorName, int line, int) override + { + qCCritical(INTERNAL_ERROR) << "XML error:" + << errorName << "on line" << line; + } +}; + +struct SRuntimeMetaDataPropertyInfo +{ + ERuntimeDataModelDataType m_DataType; + ERuntimeAdditionalMetaDataType m_AdditionalType; + Option m_Value; + bool m_Exist; + SRuntimeMetaDataPropertyInfo(ERuntimeDataModelDataType inDataType, + ERuntimeAdditionalMetaDataType inAdditionalType, + const Option &inValue, bool inExist) + : m_DataType(inDataType) + , m_AdditionalType(inAdditionalType) + , m_Value(inValue) + , m_Exist(inExist) + { + } + SRuntimeMetaDataPropertyInfo() + : m_DataType(ERuntimeDataModelDataTypeNone) + , m_AdditionalType(ERuntimeAdditionalMetaDataTypeNone) + , m_Exist(false) + { + } +}; + +struct SPropertyKey +{ + const char8_t *m_TypeOrId; + const char8_t *m_PropertyName; + + // The character pointers are expected to have come from the string table + // thus we can safely use their exact pointer addresses for the hash code. + SPropertyKey(const char8_t *typeOrId, const char8_t *inPname) + : m_TypeOrId(typeOrId) + , m_PropertyName(inPname) + { + } + bool operator==(const SPropertyKey &inOther) const + { + // equality comparison safe since strings are assumed to come from string table. + return m_TypeOrId == inOther.m_TypeOrId && m_PropertyName == inOther.m_PropertyName; + } +}; +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SPropertyKey &inKey) const + { + return reinterpret_cast(inKey.m_TypeOrId) + ^ reinterpret_cast(inKey.m_PropertyName); + } +}; +} + +namespace { + +//=========================================================================== +/** + * @class SRuntimeMetaDataImpl + * @brief implements the IRumtimeMetaData interface class + */ +struct SRuntimeMetaDataImpl : public IRuntimeMetaData +{ + +private: + typedef std::map TIdToHandleMap; + typedef eastl::hash_map TPropertyLookupHash; + + //============================================================================== + // Fields + //============================================================================== + std::shared_ptr m_StrTable; + std::shared_ptr m_DataCore; + std::shared_ptr m_NewMetaData; + std::shared_ptr m_Objects; + std::vector m_TempReferences; + + TIdToHandleMap m_IdToHandleMap; + // We cache properties by id or by instance so that the same query for the same value + // will return an answer instantly instead of calling GetAggregateInstancePropertyByName which + // is really + // expensive. + TPropertyLookupHash m_PropertyLookupHash; + IInputStreamFactory &m_InputStreamFactory; + + // Helper to convert char to wchar_t + eastl::basic_string m_Buf[4]; + +public: + static void SimpleDataModelLogger(const char *inMessage) + { + qCInfo(TRACE_INFO) << SRuntimeMetaDataImpl::SimpleDataModelLogger + << inMessage; + } + //============================================================================== + /** + * Constructor + */ + SRuntimeMetaDataImpl(IInputStreamFactory &inFactory) + : m_InputStreamFactory(inFactory) + { + // Use this to enable some simple uicdm debug logging. Beware of a *lot* of log output. + // g_DataModelDebugLogger = SimpleDataModelLogger; + try { + // need to pause here to hook up the debugger + m_StrTable = qt3dsdm::IStringTable::CreateStringTable(); + m_DataCore = std::make_shared(m_StrTable); + m_NewMetaData = IMetaData::CreateNewMetaData(m_DataCore); + + m_Objects = std::make_shared(std::ref(*m_DataCore), + std::ref(*m_NewMetaData)); + } catch (qt3dsdm::Qt3DSDMError &error) { + qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl Qt3DSDMError: " + << m_StrTable->GetNarrowStr(error.m_Message); + } catch (std::runtime_error &exc) { + if (exc.what()) { + qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::runtime_error: " + << exc.what(); + } else { + qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::runtime_error"; + } + } catch (std::exception &exc) { + if (exc.what()) { + qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::exception: " + << exc.what(); + } else { + qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::exception"; + } + } + } + + void Load() + { + // Create the base types. + std::shared_ptr theFactory(IDOMFactory::CreateDOMFactory(m_StrTable)); + const char8_t *theMetaDataPath = GetMetaDataDirectory(); + NVScopedRefCounted theInStream( + m_InputStreamFactory.GetStreamForFile(theMetaDataPath)); + SDOMElement *topElement = NULL; + if (theInStream) + topElement = CDOMSerializer::Read(*theFactory, *theInStream); + if (topElement) { + shared_ptr theReader = + IDOMReader::CreateDOMReader(*topElement, m_StrTable, theFactory); + m_NewMetaData->Load(*theReader); + + } else { + qCCritical(INVALID_OPERATION) << "Metadata loading failed", "Failed to find meta data file"; + // Q3DStudio_ASSERT requires static linkage to UICSystem, which is only used + // by UICEngine and UICRuntime + // QT3DS_ASSERT requires the qt3ds foundation libraries which are used by all products. + QT3DS_ASSERT(false); + return; + } + } + + // Helper to convert wchar_t to eastl::string + static inline void ConvertWide(const wchar_t *inType, eastl::string &outStr) + { + if (inType && *inType) + qt3ds::foundation::ConvertUTF( + reinterpret_cast(inType), + 0, outStr); + else + outStr.clear(); + } + + // Helper to convert char to wchar_t + const wchar_t *ConvertChar(const char *inName, int inBufferIndex) + { + if (inName && *inName) { + qt3ds::foundation::ConvertUTF(inName, 0, m_Buf[inBufferIndex]); + return reinterpret_cast(m_Buf[inBufferIndex].c_str()); + } + return NULL; + } + inline const wchar_t *Convert0(const char *inName) { return ConvertChar(inName, 0); } + inline const wchar_t *Convert1(const char *inName) { return ConvertChar(inName, 1); } + inline const wchar_t *Convert2(const char *inName) { return ConvertChar(inName, 2); } + inline const wchar_t *Convert3(const char *inName) { return ConvertChar(inName, 3); } + + inline Qt3DSDMInstanceHandle GetInstanceForType(const wchar_t *inType) + { + return m_Objects->GetInstanceForType(ComposerObjectTypes::Convert(inType)); + } + + Qt3DSDMInstanceHandle GetInstanceById(const wchar_t *inId) + { + if (IsTrivial(inId)) + return 0; + if (inId[0] == '#') + ++inId; + + TIdToHandleMap::iterator find = m_IdToHandleMap.find(inId); + if (find != m_IdToHandleMap.end()) + return find->second; + return 0; + } + + virtual bool IsPropertyExist(const wchar_t *inType, const wchar_t *inProperty, + const wchar_t *inId) + { + Qt3DSDMInstanceHandle theInstance = + IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); + if (theInstance.Valid()) { + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); + + return theProperty.Valid(); + } + return false; + } + + ERuntimeDataModelDataType Convert(DataModelDataType::Value inType) + { + switch (inType) { + case DataModelDataType::None: + return ERuntimeDataModelDataTypeNone; + case DataModelDataType::Float: + return ERuntimeDataModelDataTypeFloat; + case DataModelDataType::Float2: + return ERuntimeDataModelDataTypeFloat2; + case DataModelDataType::Float3: + return ERuntimeDataModelDataTypeFloat3; + case DataModelDataType::Long: + return ERuntimeDataModelDataTypeLong; + case DataModelDataType::String: + return ERuntimeDataModelDataTypeString; + case DataModelDataType::Bool: + return ERuntimeDataModelDataTypeBool; + case DataModelDataType::Long4: + return ERuntimeDataModelDataTypeLong4; + case DataModelDataType::StringRef: + return ERuntimeDataModelDataTypeStringRef; + case DataModelDataType::ObjectRef: + return ERuntimeDataModelDataTypeObjectRef; + case DataModelDataType::StringOrInt: + return ERuntimeDataModelDataTypeStringOrInt; + default: + QT3DS_ASSERT(false); + return ERuntimeDataModelDataTypeNone; + } + } + + virtual ERuntimeDataModelDataType + GetPropertyType(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId) + { + Qt3DSDMInstanceHandle theInstance = + IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); + return Convert(m_DataCore->GetProperty(theProperty).m_Type); + } + + ERuntimeAdditionalMetaDataType Convert(AdditionalMetaDataType::Value inType) + { + switch (inType) { + case AdditionalMetaDataType::None: + return ERuntimeAdditionalMetaDataTypeNone; + case AdditionalMetaDataType::StringList: + return ERuntimeAdditionalMetaDataTypeStringList; + case AdditionalMetaDataType::Range: + return ERuntimeAdditionalMetaDataTypeRange; + case AdditionalMetaDataType::Image: + return ERuntimeAdditionalMetaDataTypeImage; + case AdditionalMetaDataType::Color: + return ERuntimeAdditionalMetaDataTypeColor; + case AdditionalMetaDataType::Rotation: + return ERuntimeAdditionalMetaDataTypeRotation; + case AdditionalMetaDataType::Font: + return ERuntimeAdditionalMetaDataTypeFont; + case AdditionalMetaDataType::FontSize: + return ERuntimeAdditionalMetaDataTypeFontSize; + case AdditionalMetaDataType::MultiLine: + return ERuntimeAdditionalMetaDataTypeMultiLine; + case AdditionalMetaDataType::ObjectRef: + return ERuntimeAdditionalMetaDataTypeObjectRef; + case AdditionalMetaDataType::Mesh: + return ERuntimeAdditionalMetaDataTypeMesh; + case AdditionalMetaDataType::Import: + return ERuntimeAdditionalMetaDataTypeImport; + case AdditionalMetaDataType::Texture: + return ERuntimeAdditionalMetaDataTypeTexture; + case AdditionalMetaDataType::Renderable: + return ERuntimeAdditionalMetaDataTypeRenderable; + case AdditionalMetaDataType::PathBuffer: + return ERuntimeAdditionalMetaDataTypePathBuffer; + case AdditionalMetaDataType::ShadowMapResolution: + return ERuntimeAdditionalMetaDataTypeShadowMapResolution; + case AdditionalMetaDataType::String: + return ERuntimeAdditionalMetaDataTypeString; + default: + QT3DS_ASSERT(false); + return ERuntimeAdditionalMetaDataTypeNone; + } + } + + virtual ERuntimeAdditionalMetaDataType + GetAdditionalType(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId) + { + Qt3DSDMInstanceHandle theInstance = + IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); + return Convert(m_NewMetaData->GetAdditionalMetaDataType(theInstance, theProperty)); + } + + bool GetPropertyValue(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId, + SValue &outValue) + { + Qt3DSDMInstanceHandle theInstance = + IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); + if (theInstance.Valid()) { + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); + return m_DataCore->GetInstancePropertyValue(theInstance, theProperty, outValue); + } else { + eastl::string typeStr; + eastl::string propertyStr; + eastl::string idStr; + ConvertWide(inType, typeStr); + ConvertWide(inProperty, propertyStr); + ConvertWide(inId, idStr); + qCCritical(INVALID_OPERATION) << "GetPropertyValueString: " + << typeStr.c_str() << " " + << propertyStr.c_str() << " " + << idStr.c_str(); + QT3DS_ASSERT(false); + } + return false; + } + + SRuntimeMetaDataPropertyInfo &FindProperty(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) + { + TStrTableStr theTypeOrId = inId.IsValid() ? inId : inType; + SPropertyKey theKey(theTypeOrId, inProperty); + eastl::pair theLookup = + m_PropertyLookupHash.insert(eastl::make_pair(theKey, SRuntimeMetaDataPropertyInfo())); + if (theLookup.second) { + const wchar_t *theType(Convert0(inType)); + const wchar_t *theProperty(Convert1(inProperty)); + const wchar_t *theId(Convert2(inId)); + if (IsPropertyExist(theType, theProperty, theId)) { + ERuntimeDataModelDataType theDataType(GetPropertyType(theType, theProperty, theId)); + ERuntimeAdditionalMetaDataType theAdditionalType( + GetAdditionalType(theType, theProperty, theId)); + Option theValue; + SValue theValueData; + if (GetPropertyValue(theType, theProperty, theId, theValueData)) + theValue = theValueData.toOldSkool(); + theLookup.first->second = + SRuntimeMetaDataPropertyInfo(theDataType, theAdditionalType, theValue, true); + } + } + return theLookup.first->second; + } + + bool IsPropertyExist(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override + { + return FindProperty(inType, inProperty, inId).m_Exist; + } + + ERuntimeDataModelDataType GetPropertyType(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) override + { + return FindProperty(inType, inProperty, inId).m_DataType; + } + + virtual ERuntimeAdditionalMetaDataType + GetAdditionalType(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override + { + return FindProperty(inType, inProperty, inId).m_AdditionalType; + } + + Option GetPropertyValueFloat(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) + return qt3dsdm::get(*theInfo.m_Value); + return Empty(); + } + + Option GetPropertyValueVector2(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) { + SFloat2 theFloat2 = qt3dsdm::get(*theInfo.m_Value); + return qt3ds::QT3DSVec3(theFloat2[0], theFloat2[1], 0); + } + return Empty(); + } + + Option GetPropertyValueVector3(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) { + SFloat3 theFloat3 = qt3dsdm::get(*theInfo.m_Value); + return qt3ds::QT3DSVec3(theFloat3[0], theFloat3[1], theFloat3[2]); + } + return Empty(); + } + + virtual Option GetPropertyValueLong(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) + return qt3dsdm::get(*theInfo.m_Value); + return Empty(); + } + + virtual Option + GetPropertyValueString(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) { + TDataStrPtr theStr = qt3dsdm::get(*theInfo.m_Value); + TRuntimeMetaDataStrType retval; + qt3ds::foundation::ConvertUTF( + reinterpret_cast( + theStr->GetData()), + 0, retval); + return retval; + } + return Empty(); + } + + virtual Option + GetPropertyValueObjectRef(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) { + SObjectRefType theObjectRef = ConvertToObjectRef(*theInfo.m_Value); + if (theObjectRef.GetReferenceType() == ObjectReferenceType::Relative) { + TDataStrPtr theStr = qt3dsdm::get(theObjectRef.m_Value); + TRuntimeMetaDataStrType retval; + qt3ds::foundation::ConvertUTF( + reinterpret_cast( + theStr->GetData()), + 0, retval); + return retval; + } else // we don't know how to solve absolute reference type + { + // QT3DS_ASSERT( false ); + return TRuntimeMetaDataStrType(""); + } + } + return Empty(); + } + + Option GetPropertyValueBool(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId) override + { + SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId)); + if (theInfo.m_Value.hasValue()) + return qt3dsdm::get(*theInfo.m_Value); + return Empty(); + } + + virtual void GetReferences(const wchar_t *inType, + eastl::vector &outReferences, + const wchar_t *inId) + { + Qt3DSDMInstanceHandle theInstance = + IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); + + if (theInstance.Valid()) { + m_TempReferences.clear(); + m_NewMetaData->GetReferences(theInstance, m_TempReferences); + outReferences.resize((uint32_t)m_TempReferences.size()); + for (uint32_t idx = 0, end = (uint32_t)m_TempReferences.size(); idx < end; ++idx) { + qt3ds::foundation::ConvertUTF(m_TempReferences[idx].c_str(), + m_TempReferences[idx].size(), outReferences[idx]); + } + } + } + + void GetReferences(const char *inType, + eastl::vector &outReferences, + const char *inId) override + { + GetReferences(Convert0(inType), outReferences, Convert2(inId)); + } + + virtual bool IsCustomProperty(const wchar_t *inId, const wchar_t *inProperty) + { + Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId); + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty); + return m_NewMetaData->IsCustomProperty(theInstance, theProperty); + } + + bool IsCustomProperty(const char *inId, const char *inProperty) override + { + return IsCustomProperty(Convert2(inId), Convert1(inProperty)); + } + + virtual bool IsCustomHandler(const wchar_t *inId, const wchar_t *inHandlerName) + { + Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId); + Qt3DSDMHandlerHandle theHandle = + m_NewMetaData->FindHandlerByName(theInstance, inHandlerName); + return m_NewMetaData->IsCustomHandler(theHandle); + } + + inline void SetDataType(SAttOrArg &arg, const SMetaPropertyBase &argInfo) + { + arg.m_DataType = Convert(argInfo.GetDataType()); + arg.m_MetaType = Convert(argInfo.GetAdditionalType()); + qt3ds::foundation::ConvertUTF(argInfo.m_Name.c_str(), argInfo.m_Name.size(), arg.m_Name); + qt3ds::foundation::ConvertUTF(argInfo.m_FormalName.c_str(), argInfo.m_FormalName.size(), + arg.m_FormalName); + switch (argInfo.GetAdditionalType()) { + case qt3dsdm::AdditionalMetaDataType::StringList: { + const eastl::vector &theData = + argInfo.m_MetaDataData.getData>(); + arg.m_MetaDataList.resize(theData.size()); + for (uint32_t metaIdx = 0, metaEnd = theData.size(); metaIdx < metaEnd; ++metaIdx) + qt3ds::foundation::ConvertUTF(theData[metaIdx].c_str(), theData[metaIdx].size(), + arg.m_MetaDataList[metaIdx]); + } break; + case qt3dsdm::AdditionalMetaDataType::Range: { + const SMetaDataRange &range = argInfo.m_MetaDataData.getData(); + arg.m_MetaDataRange = eastl::make_pair(range.m_Min, range.m_Max); + } break; + default: + break; + } + } + + THandlerList GetCustomHandlers(const char *inId) override + { + THandlerList retval; + Qt3DSDMInstanceHandle theInstance = GetInstanceById(Convert0(inId)); + THandlerHandleList handlerList; + m_NewMetaData->GetHandlers(theInstance, handlerList); + retval.reserve((uint32_t)handlerList.size()); + for (size_t idx = 0, end = handlerList.size(); idx < end; ++idx) { + if (m_NewMetaData->IsCustomHandler(handlerList[idx])) { + SHandlerInfo theInfo(m_NewMetaData->GetHandlerInfo(handlerList[idx])); + retval.push_back(SHandler()); + SHandler &handler(retval.back()); + qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), theInfo.m_Name.size(), + handler.m_Name); + qt3ds::foundation::ConvertUTF(theInfo.m_FormalName.c_str(), + theInfo.m_FormalName.size(), handler.m_FormalName); + vector theArgInfo; + m_NewMetaData->GetHandlerArguments(handlerList[idx], theArgInfo); + handler.m_Arguments.resize((uint32_t)theArgInfo.size()); + for (uint32_t argIdx = 0, argEnd = (uint32_t)theArgInfo.size(); argIdx < argEnd; + ++argIdx) { + const SMetaDataHandlerArgumentInfo &argInfo(theArgInfo[argIdx]); + SAttOrArg &arg = handler.m_Arguments[argIdx]; + SetDataType(arg, argInfo); + } + } + } + return retval; + } + + TVisualEventList GetVisualEvents(const char *inId) override + { + TVisualEventList theRetval; + Qt3DSDMInstanceHandle theInstance = GetInstanceById(Convert0(inId)); + TEventHandleList theEventList; + m_NewMetaData->GetEvents(theInstance, theEventList); + theRetval.reserve((uint32_t)theEventList.size()); + for (uint32_t idx = 0, end = (uint32_t)theEventList.size(); idx < end; ++idx) { + SEventInfo theInfo(m_NewMetaData->GetEventInfo(theEventList[idx])); + theRetval.push_back(SVisualEvent()); + SVisualEvent &theEvent(theRetval.back()); + qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), theInfo.m_Name.size(), + theEvent.m_Name); + qt3ds::foundation::ConvertUTF(theInfo.m_FormalName.c_str(), theInfo.m_FormalName.size(), + theEvent.m_FormalName); + } + return theRetval; + } + + void MetaPropertiesToAttList(vector &theProperties, + TAttOrArgList &outAtts) + { + outAtts.reserve((uint32_t)theProperties.size()); + for (uint32_t idx = 0, end = (uint32_t)theProperties.size(); idx < end; ++idx) { + SMetaDataPropertyInfo thePropInfo = + m_NewMetaData->GetMetaDataPropertyInfo(theProperties[idx]); + outAtts.push_back(SAttOrArg()); + SAttOrArg &arg(outAtts.back()); + arg.m_DataType = Convert(thePropInfo.GetDataType()); + arg.m_MetaType = Convert(thePropInfo.GetAdditionalType()); + qt3ds::foundation::ConvertUTF(thePropInfo.m_Name.c_str(), thePropInfo.m_Name.size(), + arg.m_Name); + qt3ds::foundation::ConvertUTF(thePropInfo.m_FormalName.c_str(), + thePropInfo.m_FormalName.size(), arg.m_FormalName); + SetDataType(arg, thePropInfo); + } + } + + SElementInfo LoadElement(const char *clsName, const char *clsRef, const char *inId) override + { + SElementInfo retval; + Qt3DSDMInstanceHandle theInstance; + Qt3DSDMInstanceHandle parentInstance; + if (!qt3ds::foundation::isTrivial(clsRef)) { + if (clsRef[0] == '#') + ++clsRef; + parentInstance = GetInstanceById(Convert0(clsRef)); + } else { + parentInstance = m_NewMetaData->GetCanonicalInstanceForType(Convert0(clsName)); + } + if (parentInstance.Valid() == false) { + QT3DS_ASSERT(false); + return retval; + } + theInstance = m_DataCore->CreateInstance(); + m_DataCore->DeriveInstance(theInstance, parentInstance); + m_IdToHandleMap.insert(std::make_pair(TCharStr(Convert0(inId)), theInstance)); + // setup isComponent + Qt3DSDMInstanceHandle slideOwner = m_NewMetaData->GetCanonicalInstanceForType(L"SlideOwner"); + retval.m_IsComponent = m_DataCore->IsInstanceOrDerivedFrom(theInstance, slideOwner); + TCharStr type = m_NewMetaData->GetTypeForInstance(theInstance); + qt3ds::foundation::ConvertUTF(type.c_str(), type.size(), retval.m_ClassName); + vector theProperties; + m_NewMetaData->GetMetaDataProperties(theInstance, theProperties); + MetaPropertiesToAttList(theProperties, retval.m_Attributes); + return retval; + } + + TAttOrArgList GetSlideAttributes() override + { + TAttOrArgList retval; + Qt3DSDMInstanceHandle slideOwner = m_NewMetaData->GetCanonicalInstanceForType(L"Slide"); + vector theProperties; + m_NewMetaData->GetSpecificMetaDataProperties(slideOwner, theProperties); + MetaPropertiesToAttList(theProperties, retval); + return retval; + } + + bool IsCustomHandler(const char *inId, const char *inHandlerName) override + { + return IsCustomHandler(Convert0(inId), Convert1(inHandlerName)); + } + + virtual void GetHandlerArgumentType(const wchar_t *inId, const wchar_t *inHandlerName, + const wchar_t *inArgumentName, + ERuntimeDataModelDataType &outType, + ERuntimeAdditionalMetaDataType &outAdditionalType) + { + outType = ERuntimeDataModelDataTypeNone; + outAdditionalType = ERuntimeAdditionalMetaDataTypeNone; + + Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId); + Qt3DSDMHandlerHandle theHandle = + m_NewMetaData->FindHandlerByName(theInstance, inHandlerName); + Option theArgMetaData( + m_NewMetaData->FindHandlerArgumentByName(theHandle, inArgumentName)); + if (theArgMetaData.hasValue()) { + outType = Convert(theArgMetaData->GetDataType()); + outAdditionalType = Convert(theArgMetaData->GetAdditionalType()); + } + + // Check if the type is something that we support + QT3DS_ASSERT(outType != ERuntimeDataModelDataTypeNone); + } + + void GetHandlerArgumentType(const char *inId, const char *inHandlerName, + const char *inArgumentName, + ERuntimeDataModelDataType &outType, + ERuntimeAdditionalMetaDataType &outAdditionalType) override + { + GetHandlerArgumentType(Convert0(inId), Convert1(inHandlerName), Convert2(inArgumentName), + outType, outAdditionalType); + } + + std::shared_ptr ParseScriptFile(const wchar_t *inFullPathToDocument, + std::shared_ptr inStringTable) + { + using namespace ScriptParser; + std::shared_ptr theStringTable(inStringTable); + std::shared_ptr theFactory(IDOMFactory::CreateDOMFactory(theStringTable)); + SImportXmlErrorHandler theXmlErrorHandler; + const QString path = QString::fromWCharArray(inFullPathToDocument); + std::shared_ptr theReaderPtr( + SScriptParser::ParseScriptFile(theFactory, inStringTable, + path, + theXmlErrorHandler, m_InputStreamFactory)); + if (!theReaderPtr) + qCCritical(INVALID_OPERATION) << "Failed to open script file: " << path; + return theReaderPtr; + } + + Qt3DSDMInstanceHandle CreateAndDeriveInstance(const wchar_t *inType, const wchar_t *inId) + { + // Make sure that the same id has not been created before + TCharStr theId(inId); + QT3DS_ASSERT(m_IdToHandleMap.find(theId) == m_IdToHandleMap.end()); + + Qt3DSDMInstanceHandle theCanonicalType(m_NewMetaData->GetCanonicalInstanceForType(inType)); + if (theCanonicalType.Valid() == false) { + QT3DS_ASSERT(false); + return 0; + } + + Qt3DSDMInstanceHandle theMaster = m_DataCore->CreateInstance(); + m_DataCore->DeriveInstance(theMaster, theCanonicalType); + m_IdToHandleMap.insert(std::make_pair(theId, theMaster)); + return theMaster; + } + + virtual bool LoadScriptFile(const wchar_t *inType, const wchar_t *inId, const wchar_t *inName, + const wchar_t *inSourcePath) + { + TCharStr theId(inId); + if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) + return true; + + Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(inType, inId); + if (!theMaster.Valid()) + return false; + + std::shared_ptr theScriptPtr = + ParseScriptFile(inSourcePath, m_DataCore->GetStringTablePtr()); + if (theScriptPtr) { + std::vector warnings; + // Now the magic section + m_NewMetaData->LoadInstance(*theScriptPtr, theMaster, inName, warnings); + + // Set the name + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theMaster, L"name"); + m_DataCore->SetInstancePropertyValue(theMaster, theProperty, + std::make_shared(inName)); + return true; + } + + return false; + } + + bool LoadScriptFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) override + { + return LoadScriptFile(Convert0(inType), Convert1(inId), Convert2(inName), + Convert3(inSourcePath)); + } + + bool LoadEffectXMLFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) override + { + const wchar_t *theType(Convert0(inType)); + const wchar_t *theId(Convert1(inId)); + const wchar_t *theName(Convert2(inName)); + if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) + return true; + + Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId); + if (!theMaster.Valid()) + return false; + NVScopedRefCounted theStream( + m_InputStreamFactory.GetStreamForFile(inSourcePath)); + if (theStream) { + std::vector warnings; + bool success = m_NewMetaData->LoadEffectXMLFromSourcePath( + inSourcePath, theMaster, theName, warnings, *theStream); + (void)success; + QT3DS_ASSERT(success); + return success; + } + return false; + } + + bool LoadMaterialXMLFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) override + { + const wchar_t *theType(Convert0(inType)); + const wchar_t *theId(Convert1(inId)); + const wchar_t *theName(Convert2(inName)); + (void)theName; + if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) + return true; + + Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId); + if (!theMaster.Valid()) + return false; + + NVScopedRefCounted theStream( + m_InputStreamFactory.GetStreamForFile(inSourcePath)); + if (theStream) { + std::vector warnings; + bool success = m_NewMetaData->LoadMaterialClassFromSourcePath( + inSourcePath, theMaster, theId, warnings, *theStream); + (void)success; + QT3DS_ASSERT(success); + return success; + } + return false; + } + + struct PluginErrorHandler : public qt3dsdm::CXmlErrorHandler + { + void OnXmlError(const QString &, int, int) override {} + }; + + bool LoadPluginXMLFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) override + { + const wchar_t *theType(Convert0(inType)); + const wchar_t *theId(Convert1(inId)); + const wchar_t *theName(Convert2(inName)); + if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end()) + return true; + + Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId); + if (!theMaster.Valid()) + return false; + + std::shared_ptr theFactory = + qt3dsdm::IDOMFactory::CreateDOMFactory(m_StrTable); + + PluginErrorHandler dummyHandler; + std::shared_ptr theReader = Q3DStudio::CRenderPluginParser::ParseFile( + theFactory, m_StrTable, inSourcePath, dummyHandler, m_InputStreamFactory); + if (theReader) { + Q3DStudio::CRenderPluginParser::NavigateToMetadata(theReader); + std::vector theWarnings; + m_NewMetaData->LoadInstance(*theReader, theMaster, theName, theWarnings); + Qt3DSDMPropertyHandle theProperty = + m_DataCore->GetAggregateInstancePropertyByName(theMaster, L"name"); + m_DataCore->SetInstancePropertyValue(theMaster, theProperty, + std::make_shared(theName)); + return true; + } + return false; + } + + Option GetEffectMetaDataBySourcePath(const char *inName) override + { + return m_NewMetaData->GetEffectBySourcePath(inName); + } + + virtual Option + GetMaterialMetaDataBySourcePath(const char *inName) override + { + return m_NewMetaData->GetMaterialBySourcePath(inName); + } + + virtual void GetInstanceProperties(const wchar_t *inType, const wchar_t *inId, + eastl::vector &outProperties, + bool inSearchParent) + { + // Get the instance handle given the type or id + Qt3DSDMInstanceHandle theInstance = + IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId); + if (!theInstance.Valid()) { + QT3DS_ASSERT(false); + return; + } + + vector theProperties; + if (inSearchParent) + // Get the meta data properties defined on this object or its derivation parents + m_NewMetaData->GetMetaDataProperties(theInstance, theProperties); + else + // Get the meta data properties defined on *only* this object, don't search parents + m_NewMetaData->GetSpecificMetaDataProperties(theInstance, theProperties); + + outProperties.clear(); + // Iterate each property and fill outProperties + for (size_t propIdx = 0, propEnd = theProperties.size(); propIdx < propEnd; ++propIdx) { + SMetaDataPropertyInfo theInfo( + m_NewMetaData->GetMetaDataPropertyInfo(theProperties[propIdx])); + outProperties.push_back(TRuntimeMetaDataStrType()); + qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), 0, outProperties.back()); + } + } + + void GetInstanceProperties(const char *inType, const char *inId, + eastl::vector &outProperties, + bool inSearchParent) override + { + GetInstanceProperties(Convert0(inType), Convert2(inId), outProperties, inSearchParent); + } + + std::shared_ptr GetStringTable() override { return m_StrTable; } + + TStrTableStr Register(const char *inStr) override + { + return m_StrTable->GetRenderStringTable().RegisterStr(inStr); + } + + //============================================================================== + /** + * @Self release + */ + void release() override { delete this; } + + void ClearPerProjectData() override + { + + m_IdToHandleMap.clear(); + m_PropertyLookupHash.clear(); + } + +}; // end of struct SRuntimeMetaDataImpl +} + +IRuntimeMetaData &IRuntimeMetaData::Create(IInputStreamFactory &inInputStreamFactory) +{ + SRuntimeMetaDataImpl &retval = *new SRuntimeMetaDataImpl(inInputStreamFactory); + retval.Load(); + return retval; +} diff --git a/src/Runtime/Source/datamodel/Qt3DSMetadata.h b/src/Runtime/Source/datamodel/Qt3DSMetadata.h new file mode 100644 index 00000000..a90d4fd6 --- /dev/null +++ b/src/Runtime/Source/datamodel/Qt3DSMetadata.h @@ -0,0 +1,380 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSVec3.h" +#include +#include +#include "foundation/StringTable.h" +#include + +namespace qt3ds { +namespace foundation { +} +} + +namespace qt3dsdm { +class IStringTable; +struct SMetaDataEffect; +struct SMetaDataCustomMaterial; +} + +namespace qt3ds { +namespace render { + class IInputStreamFactory; +} +} + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +using namespace qt3ds::foundation; + +//============================================================================== +// Redifinition of qt3dsdm::DataModelDataType::Value +//============================================================================== +enum ERuntimeDataModelDataType { + ERuntimeDataModelDataTypeNone, + ERuntimeDataModelDataTypeFloat, + ERuntimeDataModelDataTypeFloat2, + ERuntimeDataModelDataTypeFloat3, + ERuntimeDataModelDataTypeLong, + ERuntimeDataModelDataTypeString, + ERuntimeDataModelDataTypeBool, + ERuntimeDataModelDataTypeLong4, + ERuntimeDataModelDataTypeStringRef, + ERuntimeDataModelDataTypeObjectRef, + ERuntimeDataModelDataTypeStringOrInt, +}; + +//============================================================================== +// Redifinition of qt3dsdm::AdditionalMetaDataType +//============================================================================== +enum ERuntimeAdditionalMetaDataType { + ERuntimeAdditionalMetaDataTypeNone, + ERuntimeAdditionalMetaDataTypeStringList, + ERuntimeAdditionalMetaDataTypeRange, + ERuntimeAdditionalMetaDataTypeImage, + ERuntimeAdditionalMetaDataTypeColor, + ERuntimeAdditionalMetaDataTypeRotation, + ERuntimeAdditionalMetaDataTypeFont, + ERuntimeAdditionalMetaDataTypeFontSize, + ERuntimeAdditionalMetaDataTypeMultiLine, + ERuntimeAdditionalMetaDataTypeObjectRef, + ERuntimeAdditionalMetaDataTypeMesh, + ERuntimeAdditionalMetaDataTypeImport, + ERuntimeAdditionalMetaDataTypeTexture, + ERuntimeAdditionalMetaDataTypeRenderable, + ERuntimeAdditionalMetaDataTypePathBuffer, + ERuntimeAdditionalMetaDataTypeShadowMapResolution, + ERuntimeAdditionalMetaDataTypeString, +}; + +typedef eastl::basic_string TRuntimeMetaDataStrType; +typedef qt3ds::foundation::CRegisteredString TStrTableStr; + +struct SAttOrArg +{ + TRuntimeMetaDataStrType m_Name; + TRuntimeMetaDataStrType m_FormalName; + ERuntimeDataModelDataType m_DataType; + ERuntimeAdditionalMetaDataType m_MetaType; + eastl::vector m_MetaDataList; + eastl::pair m_MetaDataRange; +}; + +typedef eastl::vector TAttOrArgList; +struct SHandler +{ + TRuntimeMetaDataStrType m_Name; + TRuntimeMetaDataStrType m_FormalName; + TAttOrArgList m_Arguments; +}; + +typedef eastl::vector THandlerList; + +struct SVisualEvent +{ + TRuntimeMetaDataStrType m_Name; + TRuntimeMetaDataStrType m_FormalName; +}; + +typedef eastl::vector TVisualEventList; + +struct SElementInfo +{ + TRuntimeMetaDataStrType m_ClassName; + bool m_IsComponent; + TAttOrArgList m_Attributes; +}; + +//============================================================================== +/** + * @class IRuntimeMetaData + * @brief Declare interfaces for querying meta data values + */ +class QT3DS_AUTOTEST_EXPORT IRuntimeMetaData : public NVReleasable +{ + +public: + static const char *GetMetaDataDirectory() + { + return ":/res/DataModelMetadata/en-us/MetaData.xml"; + } + //============================================================================== + /** + * Check if a property for the specified type or id exists + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value type + */ + virtual bool IsPropertyExist(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value type + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value type + */ + virtual ERuntimeDataModelDataType GetPropertyType(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get additional metadata type + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property meta data type + */ + virtual ERuntimeAdditionalMetaDataType + GetAdditionalType(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value as float + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option GetPropertyValueFloat(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value as QT3DSVec3 + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option GetPropertyValueVector2(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value as QT3DSVec3 + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option GetPropertyValueVector3(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value as long + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option GetPropertyValueLong(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value as string + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option + GetPropertyValueString(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get object ref property value as string + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option + GetPropertyValueObjectRef(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get property value as bool + * @param inType default object type + * @param inProperty the property to query + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param return property value + */ + virtual Option GetPropertyValueBool(TStrTableStr inType, TStrTableStr inProperty, + TStrTableStr inId = TStrTableStr()) = 0; + + //============================================================================== + /** + * Get references + * @param inType default object type + * @param outReferences References of the object + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + */ + virtual void GetReferences(const char *inType, + eastl::vector &outReferences, + const char *inId = NULL) = 0; + + //============================================================================== + /** + * Check if the property is custom or built in (canonical) + * @param inId object id + * @param inProperty the property to query + */ + virtual bool IsCustomProperty(const char *inId, const char *inProperty) = 0; + + //============================================================================== + /** + * Check if the handle is custom or built in (canonical) + * @param inId object id + * @param inHandlerName the handler name + */ + virtual bool IsCustomHandler(const char *inId, const char *inHandlerName) = 0; + + virtual THandlerList GetCustomHandlers(const char *inId) = 0; + + virtual TVisualEventList GetVisualEvents(const char *inId) = 0; + + virtual SElementInfo LoadElement(const char *clsName, const char *clsRef, const char *inId) = 0; + + virtual TAttOrArgList GetSlideAttributes() = 0; + + //============================================================================== + /** + * Get the data type and additional type of the custom handler + * @param inId object id + * @param inHandlerName the handler name + * @param inArgumentName the handler argument name + * @param outType the type + * @param outAdditionalType the additional type + */ + virtual void GetHandlerArgumentType(const char *inId, const char *inHandlerName, + const char *inArgumentName, + ERuntimeDataModelDataType &outType, + ERuntimeAdditionalMetaDataType &outAdditionalType) = 0; + + //============================================================================== + /** + * Get properties of the object with the given id, with the option of searching the parent or + *only specific to this object. + * @param inType default object type + * @param inId object id. if this value is not trivial, the query is based on inId + *instead of inType + * @param outProperties the list of property names + * @param inSearchParent if true, get the properties defined on the object or its derivation + *parents + * else, get only the properties defined on the object, not properties + *derived from the parent. + */ + virtual void GetInstanceProperties(const char *inType, const char *inId, + eastl::vector &outProperties, + bool inSearchParent) = 0; + + virtual bool LoadScriptFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) = 0; + + virtual bool LoadEffectXMLFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) = 0; + + virtual bool LoadMaterialXMLFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) = 0; + + virtual bool LoadPluginXMLFile(const char *inType, const char *inId, const char *inName, + const char *inSourcePath) = 0; + + virtual Option GetEffectMetaDataBySourcePath(const char *inName) = 0; + + virtual Option + GetMaterialMetaDataBySourcePath(const char *inSourcePath) = 0; + + virtual std::shared_ptr GetStringTable() = 0; + + virtual TStrTableStr Register(const char *inStr) = 0; + + // Clear data that affects project loading (mainly id->instance map) + virtual void ClearPerProjectData() = 0; + +public: + //============================================================================== + /** + * Creation function creates an object implements the IRuntimeMetaData interface + * This takes an input stream factory because on android the metadata is installed + * in the APK file, so we don't have exact access to it on the filesystem. + */ + static IRuntimeMetaData &Create(qt3ds::render::IInputStreamFactory &inInputStreamFactory); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/engine/EnginePrefix.h b/src/Runtime/Source/engine/EnginePrefix.h new file mode 100644 index 00000000..d9017850 --- /dev/null +++ b/src/Runtime/Source/engine/EnginePrefix.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "render/backends/gl/Qt3DSOpenGLPrefix.h" + +#ifdef _WIN32 +//============================================================================== +// DEFINES +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +//============================================================================== +// DISABLED WARNINGS +// +// Note that most of these warnings are tuned off by default by the compiler +// even at warning level 4. Using option /Wall turns on all warnings and makes +// even standard Microsoft include files cry. We had to turn off these or +// turn off warnings individually for each standard include file which was +// too much work. Point is that /Wall is like Warning Level 5 and this brings +// it down to about Warning level 4.5, still way above /W4. +#pragma warning(disable : 4127) // conditional expression is constant +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +//#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +//#pragma warning( disable : 4511 ) // copy constructor could not be generated +#pragma warning(disable : 4512) // assignment operator could not be generated +#pragma warning(disable : 4514) // unreferenced inline function has been removed +//#pragma warning( disable : 4619 ) // #pragma warning : there is no warning number '4619' (in +//string.h) +#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy + // constructor is inaccessible +#pragma warning(disable : 4626) // assignment operator could not be generated because a base class + // assignment operator is inaccessible +//#pragma warning( disable : 4640 ) // TODO MF Remove - construction of local static object is +//not thread-safe +#pragma warning(disable : 4710) // function not inlined +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning( \ + disable : 4738) // storing 32-bit float result in memory, possible loss of performance +#pragma warning(disable : 4826) // Conversion from 'const void *' to 'void *' is sign-extended +//#pragma warning( disable : 4996 ) // _snprintf' was declared deprecated + +#endif //_WIN32 + +//============================================================================== +// Non-windows environments need to declare this +#ifndef MAX_PATH +#define MAX_PATH 260 +#endif + +//============================================================================== +// STD - Standard includes MUST come first +#ifdef _WIN32 +#pragma warning(push, 3) +#pragma warning( \ + disable : 4548) // expression before comma has no effect; expected expression with side-effect +#endif + +#include +#include + +#if defined(_PCPLATFORM) || defined(_TEGRAPLATFORM) +#include +#endif + +#ifdef _WIN32 +#pragma warning(pop) +#endif + +//============================================================================== +// Runtime +//============================================================================== +#include "Qt3DSAssert.h" +#include "Qt3DSMacros.h" +#include "Qt3DSElementSystem.h" +#include "Qt3DSQmlEngine.h" +#include "Qt3DSAttributeHashes.h" + +//============================================================================== +// Additional Linux only dependencies +//============================================================================== +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + +#pragma pack(1) +struct BITMAPFILEHEADER +{ + Q3DStudio::UINT16 bfType; + Q3DStudio::UINT32 bfSize; + Q3DStudio::UINT16 bfReserved1; + Q3DStudio::UINT16 bfReserved2; + Q3DStudio::UINT32 bfOffBits; +}; +#pragma pack() + +#pragma pack(1) + +typedef struct tagBITMAPINFOHEADER +{ + Q3DStudio::UINT32 biSize; + Q3DStudio::INT32 biWidth; + Q3DStudio::INT32 biHeight; + Q3DStudio::UINT16 biPlanes; + Q3DStudio::UINT16 biBitCount; + Q3DStudio::UINT32 biCompression; + Q3DStudio::UINT32 biSizeImage; + Q3DStudio::INT32 biXPelsPerMeter; + Q3DStudio::INT32 biYPelsPerMeter; + Q3DStudio::UINT32 biClrUsed; + Q3DStudio::UINT32 biClrImportant; +} BITMAPINFOHEADER; + +#pragma pack() + +#define UNREFERENCED_PARAMETER(theParam) theParam; + +#endif diff --git a/src/Runtime/Source/engine/NVImageScaler.h b/src/Runtime/Source/engine/NVImageScaler.h new file mode 100644 index 00000000..069604a6 --- /dev/null +++ b/src/Runtime/Source/engine/NVImageScaler.h @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +namespace Q3DStudio { +namespace ImageScaler { + + //============================================================================== + /** + * + */ + template + inline void BilinearReduceRows(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + CHAR *outDstBuffer, INT32 inDstHeight) + { + INT32 theDDAConst = static_cast(1024.0 * inDstHeight / inSrcHeight); + INT32 theDDAAccum = 0; + INT32 thePixelCount; + + INT32 theSrcRow; + INT32 theSrcCol; + INT32 theDstRow; + + INT32 theChannelAccum[TNumChannels] = { 0 }; + + CHAR *theDstPointer = outDstBuffer; + const CHAR *theSrcPointer = inSrcBuffer; + const CHAR *theSrcColPointer = NULL; + CHAR *theDstColPointer = NULL; + + INT32 theStepSize = TNumChannels; + INT32 theSrcStride = TNumChannels * inSrcWidth; + INT32 theDstStride = TNumChannels * inSrcWidth; + + for (theSrcCol = 0; theSrcCol < inSrcWidth; ++theSrcCol) { + theSrcColPointer = theSrcPointer + (theSrcCol * theStepSize); + theDstColPointer = theDstPointer + (theSrcCol * theStepSize); + + theSrcRow = 0L; + theDstRow = 0L; + thePixelCount = 0L; + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] = 0L; + + theDDAAccum = 0L; + + while (theSrcRow < inSrcHeight) { + while ((theDDAAccum < 1024L) && (theSrcRow < inSrcHeight)) { + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] += + 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + idx]; + + theDDAAccum += theDDAConst; + thePixelCount += 1024L; + ++theSrcRow; + } + + theDDAAccum = (theSrcRow < inSrcHeight) ? (theDDAAccum - 1024L) : (0L); + thePixelCount -= theDDAAccum; + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] -= theDDAAccum + * (INT32)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + idx]; + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theDstColPointer[(theDstRow * theDstStride) + idx] = + (CHAR)(theChannelAccum[idx] / thePixelCount); + + thePixelCount = 1024L - theDDAAccum; + ++theDstRow; + + if (theDstRow >= inDstHeight) + break; + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] = thePixelCount + * (INT32)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + idx]; + } + } + } + + inline void BilinearReduceRows(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + INT32 inChannels, CHAR *outDstBuffer, INT32 inDstHeight) + { + switch (inChannels) { + case 4: + BilinearReduceRows<4>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); + break; + case 3: + BilinearReduceRows<3>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); + break; + case 2: + BilinearReduceRows<2>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); + break; + case 1: + BilinearReduceRows<1>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstHeight); + break; + } + } + + template + inline void BilinearReduceCols(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + CHAR *outDstBuffer, INT32 inDstWidth) + { + INT32 theDDAConst = static_cast(1024.0 * inDstWidth / inSrcWidth); + INT32 theDDAAccum = 0L; + INT32 thePixelCount; + + INT32 theSrcRow; + INT32 theSrcCol; + INT32 theDstCol; + + INT32 theChannelAccum[TNumChannels]; + + CHAR *theDstPointer = outDstBuffer; + const CHAR *theSrcPointer = inSrcBuffer; + const CHAR *theSrcRowPointer; + CHAR *theDstRowPointer; + + INT32 theSrcStepSize = TNumChannels; + INT32 theDstStepSize = TNumChannels; + + for (theSrcRow = 0; theSrcRow < inSrcHeight; ++theSrcRow) { + + theSrcRowPointer = theSrcPointer + (theSrcRow * inSrcWidth * theSrcStepSize); + theDstRowPointer = theDstPointer + (theSrcRow * inDstWidth * theDstStepSize); + + theSrcCol = 0L; + theDstCol = 0L; + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] = 0L; + thePixelCount = 0L; + theDDAAccum = 0L; + + while (theSrcCol < inSrcWidth) { + while ((theDDAAccum < 1024L) && (theSrcCol < inSrcWidth)) { + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] += + 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + idx]; + + theDDAAccum += theDDAConst; + thePixelCount += 1024L; + ++theSrcCol; + } + + theDDAAccum = (theSrcCol < inSrcWidth) ? (theDDAAccum - 1024L) : (0L); + thePixelCount -= theDDAAccum; + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] -= theDDAAccum + * (INT32)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + idx]; + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theDstRowPointer[(theDstCol * theDstStepSize) + idx] = + (CHAR)(theChannelAccum[idx] / thePixelCount); + + thePixelCount = 1024L - theDDAAccum; + ++theDstCol; + + if (theDstCol >= inDstWidth) { + break; + } + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theChannelAccum[idx] = thePixelCount + * (INT32)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + idx]; + } + } + } + + inline void BilinearReduceCols(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + INT32 inChannels, CHAR *&outDstBuffer, INT32 inDstWidth) + { + switch (inChannels) { + case 4: + BilinearReduceCols<4>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); + break; + case 3: + BilinearReduceCols<3>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); + break; + case 2: + BilinearReduceCols<2>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); + break; + case 1: + BilinearReduceCols<1>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth); + break; + } + } + + template + inline void BilinearReduceImage(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + CHAR *outDstBuffer, INT32 inDstWidth, INT32 inDstHeight) + { + // Number larger than 1024 + // One pixel in the source image is equivalent to this much of a pixel + // in terms of dest pixels. + INT32 theXIncrement = static_cast(1024.f * inSrcWidth / inDstWidth); + // How many rows do we skip, in fixed point arithmetic, when we bump lines + INT32 theYIncrement = static_cast(1024.f * inSrcHeight / inDstHeight); + // We are starting at position .5 in textel space + INT32 theSrcYPtr = 0; + CHAR *theDstPtr = outDstBuffer; + for (INT32 theHeightIndex = 0; theHeightIndex < inDstHeight; + ++theHeightIndex, theSrcYPtr += theYIncrement) { + INT32 theSrcXPtr = 0; + for (INT32 theWidthIndex = 0; theWidthIndex < inDstWidth; + ++theWidthIndex, theSrcXPtr += theXIncrement, theDstPtr += TNumChannels) { + INT32 theAccum[TNumChannels] = { 0 }; + INT32 theNumPixels = 0; + // Pull all reasonable pixels from the source image. + INT32 theStartRow = (theSrcYPtr / 1024); + INT32 theStopRow = (theSrcYPtr + theYIncrement) / 1024; + INT32 theStartColumn = theSrcXPtr / 1024; + INT32 theStopColumn = (theSrcXPtr + theXIncrement) / 1024; + // Average everything between the columns + for (INT32 theRow = theStartRow; theRow < theStopRow; ++theRow) { + INT32 theSrcAddr = (theRow * inSrcWidth + theStartColumn) * TNumChannels; + for (INT32 theCol = theStartColumn; theCol < theStopColumn; + ++theCol, theSrcAddr += TNumChannels) { + ++theNumPixels; + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theAccum[idx] += inSrcBuffer[theSrcAddr + idx]; + } + } + + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theDstPtr[idx] = theAccum[idx] / theNumPixels; + } + } + } + + template + inline void NearestReduceImage(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + CHAR *outDstBuffer, INT32 inDstWidth, INT32 inDstHeight) + { + // Number larger than 1024 + // One pixel in the source image is equivalent to this much of a pixel + // in terms of dest pixels. + INT32 theXIncrement = static_cast(1024.f * inSrcWidth / inDstWidth); + // How many rows do we skip, in fixed point arithmetic, when we bump lines + INT32 theYIncrement = static_cast(1024.f * inSrcHeight / inDstHeight); + // We are starting at position .5 in textel space + INT32 theSrcYPtr = theYIncrement / 2; + CHAR *theDstPtr = outDstBuffer; + for (INT32 theHeightIndex = 0; theHeightIndex < inDstHeight; + ++theHeightIndex, theSrcYPtr += theYIncrement) { + INT32 theSrcRow = (theSrcYPtr / 1024) * inSrcWidth * TNumChannels; + INT32 theSrcXPtr = theXIncrement / 2; + for (INT32 theWidthIndex = 0; theWidthIndex < inDstWidth; + ++theWidthIndex, theSrcXPtr += theXIncrement, theDstPtr += TNumChannels) { + INT32 theSrcPtr = theSrcRow + (theSrcXPtr >> 10) * TNumChannels; + for (INT32 idx = 0; idx < TNumChannels; ++idx) + theDstPtr[idx] = inSrcBuffer[theSrcPtr + idx]; + } + } + } + + inline void NearestReduceImage(const CHAR *inSrcBuffer, INT32 inSrcWidth, INT32 inSrcHeight, + INT32 inChannels, CHAR *outDstBuffer, INT32 inDstWidth, + INT32 inDstHeight) + { + switch (inChannels) { + case 4: + NearestReduceImage<4>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, + inDstHeight); + break; + case 3: + NearestReduceImage<3>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, + inDstHeight); + break; + case 2: + NearestReduceImage<2>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, + inDstHeight); + break; + case 1: + NearestReduceImage<1>(inSrcBuffer, inSrcWidth, inSrcHeight, outDstBuffer, inDstWidth, + inDstHeight); + break; + } + } +} +} \ No newline at end of file diff --git a/src/Runtime/Source/engine/OpenKodeInclude.h b/src/Runtime/Source/engine/OpenKodeInclude.h new file mode 100644 index 00000000..06bdf006 --- /dev/null +++ b/src/Runtime/Source/engine/OpenKodeInclude.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== + +// Wrap the include so we can ensure it gets compiled with 8 byte alignment +// also, this means we need to compile nv_main.c (via right click -> properties) with 8 byte +// alignment too! + +#pragma pack(push) +#pragma pack(8) +#include +#pragma pack(pop) + +//============================================================================== +// Namespace +//============================================================================== +namespace NVUI { + +} // namespace NVUI diff --git a/src/Runtime/Source/engine/Qt3DSEGLInfo.h b/src/Runtime/Source/engine/Qt3DSEGLInfo.h new file mode 100644 index 00000000..7be2c09e --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSEGLInfo.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_EGLINFO_H +#define QT3DS_EGLINFO_H + +#ifdef _PLATFORM_USE_EGL +#include + +namespace Q3DStudio { +struct SEGLInfo +{ + EGLDisplay display; + EGLSurface surface; + EGLContext context; + EGLConfig config; + EGLNativeWindowType nativewin; +}; +}; + +#else +namespace Q3DStudio { +struct SEGLInfo +{ + void *display; + void *surface; + void *context; + void *config; + void *nativewin; +}; +}; +#endif + +#endif diff --git a/src/Runtime/Source/engine/Qt3DSEGLWindowSystem.h b/src/Runtime/Source/engine/Qt3DSEGLWindowSystem.h new file mode 100644 index 00000000..770f5c9f --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSEGLWindowSystem.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_EGL_WINDOW_SYSTEM_H +#define QT3DS_EGL_WINDOW_SYSTEM_H +#include "Qt3DSEGLInfo.h" +#include "Qt3DSWindowSystem.h" +#include "nv_main/nv_main.h" + +namespace Q3DStudio { +struct SEGLWindowSystemImpl : public IWindowSystem +{ + SEGLInfo m_EGLInfo; + + virtual QSize GetWindowDimensions() + { + int w, h; + + eglQuerySurface(gEGLHandles[0].display, gEGLHandles[0].surface, EGL_WIDTH, &w); + eglQuerySurface(gEGLHandles[0].display, gEGLHandles[0].surface, EGL_HEIGHT, &h); + + return QSize(w, h); + } + virtual void SetWindowDimensions(const QSize &) {} + // For platforms that support it, we get the egl info for render plugins + // Feel free to return NULL. + virtual SEGLInfo *GetEGLInfo() + { + m_EGLInfo.display = gEGLHandles[0].display; + m_EGLInfo.surface = gEGLHandles[0].surface; + m_EGLInfo.context = gEGLHandles[0].context; + m_EGLInfo.config = gEGLHandles[0].config; + m_EGLInfo.nativewin = gEGLHandles[0].nativewin; + return &m_EGLInfo; + } + // on some systems we allow our default render target to be a offscreen buffer + // otherwise return 0; + virtual int GetDefaultRenderTargetID() { return 0; } + // returns the depth buffer bit count for the render window + // overwrite this one for your own needs + virtual int GetDepthBitCount() + { + EGLint depth = 16; +#ifdef _PLATFORM_USE_EGL + if (gEGLHandles[0].display && gEGLHandles[0].config) + eglGetConfigAttrib(gEGLHandles[0].display, gEGLHandles[0].config, EGL_DEPTH_SIZE, + &depth); +#endif + + return depth; + } +}; +}; + +#endif diff --git a/src/Runtime/Source/engine/Qt3DSPluginDLL.h b/src/Runtime/Source/engine/Qt3DSPluginDLL.h new file mode 100644 index 00000000..1ba7cf08 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSPluginDLL.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//============================================================================== +// Includes +//============================================================================== +#pragma once +#include "Qt3DSBasicPluginDLL.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================== +// Enums +//============================================================================== +// Texture format +typedef enum _ETEXTUREFORMAT { + ETEXTUREFORMAT_Unknown = 0, + ETEXTUREFORMAT_RGBA8, + ETEXTUREFORMAT_RGB8, + ETEXTUREFORMAT_RGB565, + ETEXTUREFORMAT_RGBA5551, + ETEXTUREFORMAT_Alpha8, + ETEXTUREFORMAT_Luminance8, + ETEXTUREFORMAT_LuminanceAlpha8, + ETEXTUREFORMAT_RGBA_DXT1, + ETEXTUREFORMAT_RGB_DXT1, + ETEXTUREFORMAT_RGBA_DXT3, + ETEXTUREFORMAT_RGBA_DXT5, +} ETEXTUREFORMAT; + +//============================================================================== +// Functions declarations +//============================================================================== + +//============================================================================== +/** + * Perform plugin initialization. + * @param inArgs string arguments from XIF arg parameter + * @return EDLLSTATUS_OK if initialization suceeds + */ +typedef long (*PROC_Initialize)(const char *inArgs); +Q_DECL_EXPORT long Initialize(const char *inArgs); + +//============================================================================== +/** + * Passes the current screen size and format to the plugin. + * Plugin should override with it's own desired settings. + * This affects the size and format of the allocated offscreen texture. + * When resources are allocated, SetAllocatedRenderInfo will be called to + * inform the plugin of the allocated resources + * @param ioWidth width + * @param ioHeight height + * @param ioTextureFormat See ETEXTUREFORMAT + */ +typedef void (*PROC_GetDesiredTextureSize)(long *ioWidth, long *ioHeight, + ETEXTUREFORMAT *ioTextureFormat); +Q_DECL_EXPORT void GetDesiredTextureSize(long *ioWidth, long *ioHeight, + ETEXTUREFORMAT *ioTextureFormat); + +//============================================================================== +/** + * Information about the current EGL environment. + * Useful if plugin wishes to switch EGLContext to manage it's own state. + * Optional + * @param inEGLDisplay pointer to EGLDisplay + * @param inEGLCurrentContext pointer to current EGLContext + * @param inEGLSurface pointer to EGLSurface + * @param inEGLConfig pointer to EGLConfig attributes + */ +typedef void (*PROC_SetEGLInfo)(void *inEGLDisplay, void *inEGLCurrentContext, void *inEGLSurface, + void *inEGLConfig); +Q_DECL_EXPORT void SetEGLInfo(void *inEGLDisplay, void *inEGLCurrentContext, + void *inEGLSurface, void *inEGLConfig); + +//============================================================================== +/** + * Render pulse whenever the runtime requires a frame from the plugin. + * Note that if plugin wishes to switch EGLContext, + * it should restore the previous EGLContext(obtained from SetEGLInfo) at the end of this + *function. + * @param inHostWidth width of the host rectangle + * @param inHostHeight height of the host rectangle + * @param inDrawTime current time in milliseconds + */ +typedef void (*PROC_Render)(long inHostWidth, long inHostHeight, long inDrawTime); +Q_DECL_EXPORT void Render(long inHostWidth, long inHostHeight, long inDrawTime); + +//============================================================================== +/** + * Perform plugin uninitialization. + * @return EDLLSTATUS_OK if successful + */ +typedef long (*PROC_Uninitialize)(); +Q_DECL_EXPORT long Uninitialize(); + +#ifdef __cplusplus +} +#endif diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp new file mode 100644 index 00000000..8fa75792 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp @@ -0,0 +1,1990 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "EnginePrefix.h" +#include "Qt3DSRenderRuntimeBindingImpl.h" +#include "Qt3DSSceneManager.h" +#include "Qt3DSIScene.h" +#include "Qt3DSTegraApplication.h" +#include "Qt3DSQmlEngine.h" +#include "Qt3DSRenderUIPLoader.h" +#include "Qt3DSPresentationFrameData.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "Qt3DSRenderSubpresentation.h" +#include "Qt3DSIScriptBridge.h" +#include "Qt3DSFileStream.h" +#include "Qt3DSDMPrefix.h" +#include "foundation/IOStreams.h" +#include "Qt3DSDMStringTable.h" +#include "Qt3DSDMXML.h" +#include "Qt3DSRenderBufferManager.h" +#include "foundation/SerializationTypes.h" +#include "Qt3DSRenderGraphObjectSerializer.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderImageBatchLoader.h" +#include "Qt3DSPresentation.h" + +#include "Qt3DSDLLManager.h" +#include "Qt3DSBasicPluginDLL.h" +#include "Qt3DSPluginDLL.h" +#include "Qt3DSRenderPlugin.h" +#include "foundation/FileTools.h" +#include "Qt3DSStateVisualBindingContext.h" +#include "Qt3DSStateVisualBindingContextValues.h" +#include "Qt3DSStateScriptContext.h" +#include "EventPollingSystem.h" +#include "EventSystem.h" +#include "Qt3DSApplication.h" +#include "Qt3DSMatrix.h" +#include "Qt3DSWindowSystem.h" +#if !defined (Q_OS_MACOS) +#include "Qt3DSEGLInfo.h" +#endif +#include "Qt3DSOffscreenRenderKey.h" +#include "Qt3DSOldNBustedRenderPlugin.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "Qt3DSRenderBufferLoader.h" +#include "Qt3DSRenderRenderList.h" +#include "Qt3DSRenderPrefilterTexture.h" +#include "foundation/PoolingAllocator.h" +#include "q3dsqmlrender.h" + +#ifdef EA_PLATFORM_WINDOWS +#pragma warning(disable : 4355) +#endif + +using namespace qt3ds::render; +using eastl::make_pair; +using eastl::pair; +using qt3ds::runtime::IApplication; + +#ifndef _WIN32 +#define stricmp strcasecmp +#endif +namespace qt3ds { +namespace render { + qt3ds::foundation::MallocAllocator g_BaseAllocator; +} +} +namespace { +struct Qt3DSRenderScene; + +struct Qt3DSRenderSceneSubPresRenderer : public CSubPresentationRenderer +{ + Qt3DSRenderScene &m_Scene; + Qt3DSRenderSceneSubPresRenderer(Qt3DSRenderScene &inScene, IQt3DSRenderContext &inRenderContext, + SPresentation &inPresentation) + : CSubPresentationRenderer(inRenderContext, inPresentation) + , m_Scene(inScene) + { + } + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) + SOffscreenRenderFlags NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, + QT3DSVec2 inPresScale, + const SRenderInstanceId instanceId) override; + void Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, + SScene::RenderClearCommand inClearBuffer, + const SRenderInstanceId instanceId) override; + void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, + SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, + const SRenderInstanceId instanceId) override; +}; + +struct SSceneLoadData +{ + NVAllocatorCallback &m_Allocator; + NVScopedRefCounted m_Data; + SPresentation *m_Presentation; + NVDataRef m_TranslatorData; + NVDataRef m_SceneGraphData; + eastl::vector m_Translators; + SPoolingAllocator m_AutoAllocator; + Q3DStudio::IPresentation *m_RuntimePresentation; + QT3DSI32 mRefCount; + + SSceneLoadData(NVAllocatorCallback &alloc) + : m_Allocator(alloc) + , m_Presentation(NULL) + , m_AutoAllocator(alloc) + , m_RuntimePresentation(NULL) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) +}; + +struct Qt3DSRenderScene : public Q3DStudio::IScene +{ + SBindingCore &m_BindingCore; + NVScopedRefCounted m_Context; + NVScopedRefCounted m_LoadData; + // The scene graph gets allocated kind of on its own + // So do the smaller translation objects that translate TElement properties + // into the graph. + SPresentation *m_Presentation; + Q3DStudio::IPresentation *m_RuntimePresentation; + void *m_UserData; + TTranslatorDirytSet m_DirtySet; + CRegisteredString m_OffscreenRendererId; + IOffscreenRenderer *m_OffscreenRenderer; + CRegisteredString m_SubPresentationType; + nvvector m_GraphObjectList; + bool m_LoggedPickLastFrame; + NVRenderRect m_LastRenderViewport; + CRegisteredString m_PathSubPathType; + + Qt3DSRenderScene(SBindingCore &inBindingCore, IQt3DSRenderContext &inContext, + SSceneLoadData &inLoadData) + : m_BindingCore(inBindingCore) + , m_Context(inContext) + , m_LoadData(inLoadData) + , m_Presentation(inLoadData.m_Presentation) + , m_RuntimePresentation(inLoadData.m_RuntimePresentation) + , m_UserData(NULL) + , m_DirtySet(inContext.GetAllocator(), "Qt3DSRenderScene::m_DirtySet") + , m_OffscreenRenderer(NULL) + , m_SubPresentationType( + inContext.GetStringTable().RegisterStr(CSubPresentationRenderer::GetRendererName())) + , m_GraphObjectList(inContext.GetAllocator(), "Qt3DSDSRenderScene::m_GraphObjectList") + , m_LoggedPickLastFrame(false) + { + for (QT3DSU32 idx = 0, end = inLoadData.m_Translators.size(); idx < end; ++idx) { + m_DirtySet.insert(*inLoadData.m_Translators[idx]); + } + m_PathSubPathType = inContext.GetStringTable().RegisterStr("PathAnchorPoint"); + } + + virtual ~Qt3DSRenderScene() + { + if (m_OffscreenRenderer) + m_Context->GetOffscreenRenderManager().ReleaseOffscreenRenderer(m_OffscreenRendererId); + m_OffscreenRenderer = NULL; + if (m_Presentation && m_Presentation->m_Scene) { + for (SLayer *theLayer = m_Presentation->m_Scene->m_FirstChild; theLayer; + theLayer = static_cast(theLayer->m_NextSibling)) { + m_Context->GetRenderer().ReleaseLayerRenderResources(*theLayer, nullptr); + } + } + } + + Q3DStudio::IPresentation &GetPresentation() override { return *m_RuntimePresentation; } + + // Update really just adds objects to the dirty set + bool Update() + { + Q3DStudio::TElementList &theDirtyList = + m_RuntimePresentation->GetFrameData().GetDirtyList(); + for (QT3DSU32 idx = 0, end = theDirtyList.GetCount(); idx < end; ++idx) { + Q3DStudio::TElement &theElement = *theDirtyList[idx]; + Qt3DSTranslator *theTranslator = + reinterpret_cast(theElement.GetAssociation()); + if (!theTranslator && theElement.GetType() == m_PathSubPathType) { + Q3DStudio::TElement *theParent = theElement.GetParent(); + if (theParent) { + theTranslator = reinterpret_cast(theParent->GetAssociation()); + // The path translator responds to anchor point changes as well as its own data + // changes. + if (theTranslator + && theTranslator->RenderObject().m_Type != GraphObjectTypes::PathSubPath) + theTranslator = NULL; + } + } + if (theTranslator) + m_DirtySet.insert(*theTranslator); + } + return m_DirtySet.size() > 0; + } + + void TransferDirtyProperties() + { + if (m_Presentation) { + for (QT3DSU32 idx = 0, end = m_DirtySet.size(); idx < end; ++idx) { + QT3DS_ASSERT(m_DirtySet.size() == end); + m_DirtySet[idx]->OnElementChanged(*m_Presentation, *m_Context, + *m_RuntimePresentation); + } + m_DirtySet.clear(); + } + } + + bool PrepareForRender() + { + TransferDirtyProperties(); + m_LastRenderViewport = m_Context->GetRenderList().GetViewport(); + if (m_Presentation && m_Presentation->m_Scene) { + NVRenderRect theViewportSize(m_LastRenderViewport); + return m_Presentation->m_Scene->PrepareForRender( + QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), + *m_Context); + } + return false; + } + + void Render() + { + if (m_Presentation && m_Presentation->m_Scene) { + NVRenderRect theViewportSize(m_LastRenderViewport); + m_Presentation->m_Scene->Render( + QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), *m_Context, + SScene::DoNotClear); + } + } + + // Note that we do not need to call WindowToPresentation on the mouse coordinates because they + // are specifically + // supposed to be the return values from getMousePosition which applies that transformation. We + // do, however need + // to reverse part of this transformation; whatever part happens after + // m_Context->GetMousePickMouseCoords + Q3DStudio::TElement *UserPick(float mouseX, float mouseY) + { + // Note that the pick code below only calls GetMousePickMouseCoords + // while windowToPresentation subtracts the window positional offset from + // the mouse position. + // Thus we have to add it back. + QT3DSVec2 mousePos(mouseX + m_LastRenderViewport.m_X, mouseY + m_LastRenderViewport.m_Y); + + Qt3DSRenderPickResult thePickResult = m_Context->GetRenderer().Pick( + *m_Presentation->m_Scene->m_FirstChild, m_Context->GetMousePickViewport() + // GetMousePickMouseCoords is called by the renderer to setup the pick frame. + // This is so that the presentation's lastMouseX and lastMouseY variables are correctly + // setup. + , + mousePos, true, true); + + if (thePickResult.m_HitObject != NULL) { + SModel *theHitModel = + static_cast(const_cast(thePickResult.m_HitObject)); + return &Qt3DSTranslator::GetTranslatorFromGraphNode(*theHitModel)->Element(); + } + return NULL; + } + + virtual Option FacePosition(Q3DStudio::TElement &inElement, float mouseX, float mouseY, + NVDataRef inMapperElements, + Q3DStudio::FacePositionPlanes::Enum inPlane) + { + if (inElement.GetBelongedPresentation() != this->m_RuntimePresentation + && inMapperElements.size() == 0) { + return Empty(); + } + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement.GetAssociation()); + if (theTranslator == NULL) + return Empty(); + bool isValidPickObject = + GraphObjectTypes::IsNodeType(theTranslator->m_RenderObject->m_Type); + if (isValidPickObject == false) + return Empty(); + SNode &theNode = static_cast(*theTranslator->m_RenderObject); + NVBounds3 theBounds = GetNodeLocalBoundingBox(&inElement, false); + // See commens in UserPick + QT3DSVec2 mousePos(mouseX + m_LastRenderViewport.m_X, mouseY + m_LastRenderViewport.m_Y); + eastl::vector theMapperObjects(inMapperElements.size()); + for (QT3DSU32 idx = 0, end = inMapperElements.size(); idx < end; ++idx) { + Qt3DSTranslator *theMapperTranslator = + reinterpret_cast(inMapperElements[idx]->GetAssociation()); + SGraphObject *theMapperObject = NULL; + if (theMapperTranslator) { + theMapperObject = theMapperTranslator->m_RenderObject; + } + if (theMapperObject == NULL) { + QT3DS_ASSERT(false); + } else { + theMapperObjects[idx] = theMapperObject; + } + } + qt3ds::render::SBasisPlanes::Enum thePlane(qt3ds::render::SBasisPlanes::XY); + switch (inPlane) { + case Q3DStudio::FacePositionPlanes::XY: + thePlane = qt3ds::render::SBasisPlanes::XY; + break; + case Q3DStudio::FacePositionPlanes::YZ: + thePlane = qt3ds::render::SBasisPlanes::YZ; + break; + case Q3DStudio::FacePositionPlanes::XZ: + thePlane = qt3ds::render::SBasisPlanes::XZ; + break; + } + if (theBounds.isEmpty() == false) + return m_Context->GetRenderer().FacePosition( + theNode, theBounds, theNode.m_GlobalTransform, m_Context->GetMousePickViewport(), + mousePos, + NVDataRef(theMapperObjects.data(), (QT3DSU32)theMapperObjects.size()), + thePlane); + return Empty(); + } + + void Pick(Q3DStudio::SPickFrame &ioPickFrame) + { + // Presentation's m_Hide can disable rendering + bool wasPickLoggedLastFrame = m_LoggedPickLastFrame; + m_LoggedPickLastFrame = false; + if (ioPickFrame.m_InputFrame.m_PickValid) { + // If we have not already found a valid pick on a previous layer + if (!ioPickFrame.m_ResultValid && m_Presentation && m_Presentation->m_Scene + && m_Presentation->m_Scene->m_FirstChild) { + Qt3DSRenderPickResult thePickResult = m_Context->GetRenderer().Pick( + *m_Presentation->m_Scene->m_FirstChild, m_Context->GetMousePickViewport() + // GetMousePickMouseCoords is called by the renderer to setup the pick frame. + // This is so that the presentation's lastMouseX and lastMouseY variables are + // correctly setup. + , + m_Context->GetMousePickMouseCoords( + QT3DSVec2(ioPickFrame.m_InputFrame.m_PickX, ioPickFrame.m_InputFrame.m_PickY)), + true); + if (thePickResult.m_HitObject != NULL) { + SModel *theHitModel = static_cast( + const_cast(thePickResult.m_HitObject)); + ioPickFrame.m_Model = + &Qt3DSTranslator::GetTranslatorFromGraphNode(*theHitModel)->Element(); + // I don't think local hit is used any more, but not sure. If they are used, + // then the code below is probably wrong. + ioPickFrame.m_LocalHit[0] = thePickResult.m_LocalUVCoords.x; + ioPickFrame.m_LocalHit[1] = thePickResult.m_LocalUVCoords.y; + ioPickFrame.m_SquaredDistance = thePickResult.m_CameraDistanceSq; + ioPickFrame.m_ResultValid = true; + if (wasPickLoggedLastFrame == false) { + m_LoggedPickLastFrame = true; + Q3DStudio::IPresentation *thePresentation = + ioPickFrame.m_Model->GetBelongedPresentation(); + IApplication &theRuntime = thePresentation->GetApplication(); + // We are picking against the previous frame of information. + qCInfo(TRACE_INFO, "Model Picked: %s on frame %d", + theHitModel->m_Id.c_str(), + theRuntime.GetFrameCount() - 1); + } + } else { + // The scene is always picked if it is pickable; nothing else really makes + // sense. + Qt3DSTranslator *theTranslator = + Qt3DSTranslator::GetTranslatorFromGraphNode(*m_Presentation->m_Scene); + + if (theTranslator) { + ioPickFrame.m_Model = &theTranslator->Element(); + // I don't think local hit is used any more, but not sure. If they are + // used, then the code below is probably wrong. + ioPickFrame.m_LocalHit[0] = ioPickFrame.m_InputFrame.m_PickX + / m_Presentation->m_PresentationDimensions.x; + ioPickFrame.m_LocalHit[1] = 1.0f + - ioPickFrame.m_InputFrame.m_PickY + / m_Presentation->m_PresentationDimensions.y; + ioPickFrame.m_SquaredDistance = 0; + ioPickFrame.m_ResultValid = true; + } + } + } + } + } + + void SetUserData(void *inUserData) override { m_UserData = inUserData; } + void *GetUserData() override { return m_UserData; } + + // Unfortunately, you should expect the node to be dirty at this point so we may need to force + // an update + void CalculateGlobalTransform(Q3DStudio::TElement *inElement, + Q3DStudio::RuntimeMatrix &outTransform) override + { + if (inElement == NULL) { + QT3DS_ASSERT(false); + return; + } + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { + Update(); + TransferDirtyProperties(); + SNode *theNode = static_cast(&theTranslator->RenderObject()); + // Ensure the node stays dirty + bool wasDirty = theNode->m_Flags.IsDirty(); + theNode->CalculateGlobalVariables(); + theNode->m_Flags.SetDirty(wasDirty); + memCopy(outTransform.m_Data, theNode->m_GlobalTransform.front(), sizeof(QT3DSMat44)); + } else { + qCCritical(INVALID_OPERATION, "Calculate global transform called on invalide object"); + QT3DS_ASSERT(false); + } + } + + void SetLocalTransformMatrix(Q3DStudio::TElement *inElement, + const Q3DStudio::RuntimeMatrix &inTransform) override + { + if (inElement == NULL) { + QT3DS_ASSERT(false); + return; + } + + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { + SNode *theNode = static_cast(&theTranslator->RenderObject()); + QT3DSMat44 transform; + memCopy(transform.front(), inTransform.m_Data, sizeof(QT3DSMat44)); + theNode->SetLocalTransformFromMatrix(transform); + theNode->MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + } + } + + void EnsureNodeIsUpToDate(SNode &inNode, bool inIncludeChildren) + { + bool wasDirty = inNode.m_Flags.IsDirty(); + if (wasDirty) { + inNode.CalculateGlobalVariables(); + inNode.m_Flags.SetDirty(wasDirty); + if (inIncludeChildren) { + for (SNode *theChild = inNode.m_FirstChild; theChild; + theChild = theChild->m_NextSibling) + EnsureNodeIsUpToDate(*theChild, inIncludeChildren); + } + } + } + + NVBounds3 GetNodeLocalBoundingBox(Q3DStudio::TElement *inElement, bool inSelfOnly) + { + NVBounds3 retval(NVBounds3::empty()); + if (inElement == NULL) { + QT3DS_ASSERT(false); + return retval; + } + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { + Update(); + TransferDirtyProperties(); + SNode *theNode = static_cast(&theTranslator->RenderObject()); + bool theIncludeChildren = !inSelfOnly; + EnsureNodeIsUpToDate(*theNode, theIncludeChildren); + IBufferManager &theBufferManager(m_Context->GetBufferManager()); + return theNode->GetBounds(theBufferManager, m_Context->GetPathManager(), + theIncludeChildren); + } else { + qCCritical(INVALID_OPERATION, "GetBoundingBox called on invalid object"); + QT3DS_ASSERT(false); + } + return retval; + } + + static void Assign(Q3DStudio::CBoundingBox &lhs, NVBounds3 &rhs) + { + lhs.m_Min.m_X = rhs.minimum.x; + lhs.m_Min.m_Y = rhs.minimum.y; + lhs.m_Min.m_Z = rhs.minimum.z; + + lhs.m_Max.m_X = rhs.maximum.x; + lhs.m_Max.m_Y = rhs.maximum.y; + lhs.m_Max.m_Z = rhs.maximum.z; + } + + Q3DStudio::CBoundingBox GetBoundingBox(Q3DStudio::TElement *inElement, bool inSelfOnly) override + { + Q3DStudio::CBoundingBox retval; + retval.SetEmpty(); + NVBounds3 theLocalBox = GetNodeLocalBoundingBox(inElement, inSelfOnly); + if (theLocalBox.isEmpty() == false) { + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + if (theTranslator && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { + SNode *theNode = static_cast(&theTranslator->RenderObject()); + theLocalBox.transform(theNode->m_GlobalTransform); + Assign(retval, theLocalBox); + // Left handed nodes need to return values in their space, not in the global space + // This is a hack fix due to a bug. + if (theNode->m_Flags.IsLeftHanded()) { + eastl::swap(retval.m_Min.m_Z, retval.m_Max.m_Z); + retval.m_Min.m_Z *= -1; + retval.m_Max.m_Z *= -1; + } + } + } + return retval; + } + + Q3DStudio::CBoundingBox GetLocalBoundingBox(Q3DStudio::TElement *inElement, + bool inSelfOnly) override + { + Q3DStudio::CBoundingBox retval; + retval.SetEmpty(); + if (inElement == NULL) { + QT3DS_ASSERT(false); + return retval; + } + NVBounds3 theLocalBounds = GetNodeLocalBoundingBox(inElement, inSelfOnly); + if (theLocalBounds.isEmpty() == false) + Assign(retval, theLocalBounds); + + return retval; + } + + Q3DStudio::SCameraRect GetCameraBounds(Q3DStudio::TElement &inElem) override + { + Qt3DSTranslator *theTranslator = reinterpret_cast(inElem.GetAssociation()); + if (theTranslator && theTranslator->m_RenderObject) { + Option theRectOpt = + m_Context->GetRenderer().GetCameraBounds(*theTranslator->m_RenderObject); + if (theRectOpt.hasValue()) { + qt3ds::render::SCuboidRect theRect(*theRectOpt); + return Q3DStudio::SCameraRect(theRect.m_Left, theRect.m_Top, theRect.m_Right, + theRect.m_Bottom); + } + } + return Q3DStudio::SCameraRect(); + } + + void PositionToScreen(Q3DStudio::TElement &inElement, QT3DSVec3 &inPos, QT3DSVec3 &outScreen) override + { + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement.GetAssociation()); + if (theTranslator && theTranslator->m_RenderObject) { + SNode *theNode = reinterpret_cast(theTranslator->m_RenderObject); + QT3DSVec3 thePos = theNode->m_GlobalTransform.transform(inPos); + outScreen = m_Context->GetRenderer().ProjectPosition(*theNode, thePos); + } + } + + void ScreenToPosition(Q3DStudio::TElement &inElement, QT3DSVec3 &inScreen, QT3DSVec3 &outPos) override + { + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement.GetAssociation()); + if (theTranslator && theTranslator->m_RenderObject) { + SNode *theNode = reinterpret_cast(theTranslator->m_RenderObject); + QT3DSVec3 objPos = theNode->GetGlobalPos(); + outPos = m_Context->GetRenderer().UnprojectWithDepth(*(theNode), objPos, inScreen); + } + } + + static inline int wrapMod(int a, int base) { return (a >= 0) ? a % base : (a % base) + base; } + static inline float fMin(float a, float b) { return (a < b) ? a : b; } + static inline int iMax(int a, int b) { return (a > b) ? a : b; } + + static inline void getWrappedCoords(int &sX, int &sY, int width, int height) + { + if (sY < 0) { + sX -= width >> 1; + sY = -sY; + } + if (sY >= height) { + sX += width >> 1; + sY = height - sY; + } + sX = wrapMod(sX, width); + sY = wrapMod(sY, height); + } + + static void GenerateBsdfMipmaps(SImage *theImage, const unsigned char *inBuffer, + Q3DStudio::INT32 inBufferLength, Q3DStudio::INT32 inWidth, + Q3DStudio::INT32 inHeight, + qt3ds::render::NVRenderTextureFormats::Enum inFormat, + IQt3DSRenderContext *theContext) + { + NVRenderTextureFormats::Enum destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F; + + Qt3DSRenderPrefilterTexture *theBSDFMipMap = theImage->m_TextureData.m_BSDFMipMap; + if (theBSDFMipMap == NULL) { + theBSDFMipMap = Qt3DSRenderPrefilterTexture::Create( + &theContext->GetRenderContext(), inWidth, inHeight, + *theImage->m_TextureData.m_Texture, destFormat, theContext->GetFoundation()); + theImage->m_TextureData.m_BSDFMipMap = theBSDFMipMap; + } + + if (theBSDFMipMap) + theBSDFMipMap->Build((void *)inBuffer, inBufferLength, inFormat); + } + + // This could cause some significant drama. + void SetTextureData(Q3DStudio::TElement *inElement, const unsigned char *inBuffer, + Q3DStudio::INT32 inBufferLength, Q3DStudio::INT32 inWidth, + Q3DStudio::INT32 inHeight, + qt3ds::render::NVRenderTextureFormats::Enum inFormat, + Q3DStudio::INT32 inHasTransparency) override + { + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + if (theTranslator && theTranslator->GetUIPType() == GraphObjectTypes::Image) { + SImage *theImage = static_cast(&theTranslator->RenderObject()); + // Attempt to resolve the image's path + if (!theImage->m_TextureData.m_Texture) { + if (theImage->m_ImagePath.IsValid()) + theImage->m_TextureData = m_Context->GetBufferManager().LoadRenderImage( + theImage->m_ImagePath, false, + theImage->m_MappingMode == ImageMappingModes::LightProbe); + } + // Here we go, updating the texture. + if (theImage->m_TextureData.m_Texture) { + + if (theImage->m_MappingMode == ImageMappingModes::LightProbe) { + // theImage->m_TextureData.m_Texture->GenerateMipmaps(); + GenerateBsdfMipmaps(theImage, inBuffer, inBufferLength, inWidth, inHeight, + inFormat, m_Context); + } else + theImage->m_TextureData.m_Texture->SetTextureData( + NVDataRef((QT3DSU8 *)inBuffer, (QT3DSU32)inBufferLength), 0, inWidth, + inHeight, inFormat); + + if (inHasTransparency >= 0) { + bool hasTransparency = inHasTransparency ? true : false; + theImage->m_TextureData.m_TextureFlags.SetHasTransparency(hasTransparency); + m_Context->GetBufferManager().SetImageHasTransparency(theImage->m_ImagePath, + hasTransparency); + } + theImage->m_Flags.SetDirty(true); + } + } else { + qCCritical(INVALID_OPERATION, "SetTextureData called on object that is not an image"); + QT3DS_ASSERT(false); + } + } + + bool CreateOrSetMeshData(const char *inPathStr, unsigned char *vertData, + unsigned int numVerts, unsigned int vertStride, + unsigned int *indexData, unsigned int numIndices, + qt3ds::NVBounds3 &objBounds) override + { + SRenderMesh *theMesh = NULL; + + if (inPathStr && vertData && indexData) { + theMesh = m_Context->GetBufferManager().CreateMesh( + inPathStr, vertData, numVerts, vertStride, indexData, numIndices, objBounds); + } else { + qCCritical(INVALID_OPERATION, + "CreateOrSetMeshData was not supplied necessary buffers or object path"); + } + + return (theMesh != NULL); + } + + Q3DStudio::STextSizes MeasureText(Q3DStudio::TElement *inElement, const char *inTextStr) override + { + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + Q3DStudio::STextSizes retval; + if (theTranslator && theTranslator->GetUIPType() == GraphObjectTypes::Text) { + if (inElement->IsDirty()) { + theTranslator->OnElementChanged(*m_Presentation, *m_Context, + *m_RuntimePresentation); + } + SText *theText = static_cast(&theTranslator->RenderObject()); + if (theText) { + + STextDimensions theDimensions = + m_Context->GetTextRenderer()->MeasureText(*theText, 1.0f, inTextStr); + + retval = Q3DStudio::STextSizes((Q3DStudio::INT32)theDimensions.m_TextWidth, + (Q3DStudio::INT32)theDimensions.m_TextHeight); + } + } else { + qCCritical(INVALID_OPERATION, "MeasureText called on object that is not text"); + QT3DS_ASSERT(false); + + } + return retval; + } + + Q3DStudio::STextSizes GetPresentationDesignDimensions() override + { + if (m_Presentation) { + return Q3DStudio::STextSizes( + static_cast(m_Presentation->m_PresentationDimensions.x), + static_cast(m_Presentation->m_PresentationDimensions.y)); + } + QT3DS_ASSERT(false); + return Q3DStudio::STextSizes(); + } + + // This is the best place for now... + void GetImageInfoFromRenderEngine(Q3DStudio::TElement *inElement, + Q3DStudio::INT32 &ioWidth, Q3DStudio::INT32 &ioHeight) override + { + ioWidth = 0; + ioHeight = 0; + Qt3DSTranslator *theTranslator = + reinterpret_cast(inElement->GetAssociation()); + if (theTranslator->GetUIPType() == GraphObjectTypes::Image) { + SImage *theImage = static_cast(&theTranslator->RenderObject()); + if (theImage) { + SImageTextureData theTextureData( + m_Context->GetBufferManager().LoadRenderImage(theImage->m_ImagePath)); + if (theTextureData.m_Texture) { + STextureDetails theDetails = theTextureData.m_Texture->GetTextureDetails(); + ioWidth = theDetails.m_Width; + ioHeight = theDetails.m_Height; + } + } + } + } + + virtual Q3DStudio::SMousePosition + WindowToPresentation(const Q3DStudio::SMousePosition &inWindowCoords) override + { + // If there aren't any rotations, then account for the difference in width/height of the + // presentation and the window + QT3DSVec2 theCoords = m_Context->GetMousePickMouseCoords( + QT3DSVec2((QT3DSF32)inWindowCoords.m_X, (QT3DSF32)inWindowCoords.m_Y)); + theCoords.x -= m_LastRenderViewport.m_X; + // Note that the mouse Y is reversed. Thus a positive offset of the viewport will reduce + // the mouse value. + theCoords.y -= m_LastRenderViewport.m_Y; + return Q3DStudio::SMousePosition(theCoords.x, theCoords.y); + } + + qt3ds::foundation::CRegisteredString RegisterStr(const char *inStr) override + { + return m_Context->GetStringTable().RegisterStr(inStr); + } + + Q3DStudio::INT32 LoadImageBatch(qt3ds::foundation::CRegisteredString *inFullPaths, + Q3DStudio::INT32 inNumPaths, + qt3ds::foundation::CRegisteredString inDefaultImage, + qt3ds::render::IImageLoadListener *inLoadCallback) override + { + return static_cast(m_Context->GetImageBatchLoader().LoadImageBatch( + toConstDataRef(inFullPaths, (QT3DSU32)inNumPaths), inDefaultImage, inLoadCallback, + m_Context->GetRenderContext().GetRenderContextType(), m_Presentation->m_preferKTX)); + } + + void RegisterOffscreenRenderer(const char *inKey) override + { + m_OffscreenRenderer = QT3DS_NEW(m_Context->GetAllocator(), Qt3DSRenderSceneSubPresRenderer)( + *this, *m_Context, *m_Presentation); + m_OffscreenRendererId = m_Context->GetStringTable().RegisterStr(inKey); + m_Context->GetOffscreenRenderManager().RegisterOffscreenRenderer(m_OffscreenRendererId, + *m_OffscreenRenderer); + } + + void Release() override { NVDelete(m_Context->GetAllocator(), this); } +}; + +SOffscreenRenderFlags +Qt3DSRenderSceneSubPresRenderer::NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, + QT3DSVec2 inPresScale, + const SRenderInstanceId instanceId) +{ + m_Scene.TransferDirtyProperties(); + return CSubPresentationRenderer::NeedsRender(inEnvironment, inPresScale, instanceId); +} + +void Qt3DSRenderSceneSubPresRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, + QT3DSVec2 inPresScale, + SScene::RenderClearCommand inClearBuffer, + const SRenderInstanceId instanceId) +{ + CSubPresentationRenderer::Render(inEnvironment, inRenderContext, inPresScale, inClearBuffer, + instanceId); +} + +void Qt3DSRenderSceneSubPresRenderer::RenderWithClear( + const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, + SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, + const SRenderInstanceId id) +{ + CSubPresentationRenderer::RenderWithClear(inEnvironment, inRenderContext, + inPresScale, inClearBuffer, + inClearColor, id); +} + +////////////////////////////////////////////////////////////////// +// Scene Manager +////////////////////////////////////////////////////////////////// + +struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, + public Q3DStudio::ISceneBinaryLoader +{ + typedef nvhash_map TStrBoolMap; + + NVScopedRefCounted m_Context; + nvvector> m_Scenes; + nvvector> m_RenderPlugins; + Q3DStudio::INT32 m_ViewWidth; + Q3DStudio::INT32 m_ViewHeight; + Q3DStudio::SPickFrame m_PickFrame; + NVDataRef m_StrTableData; + // The boolean is to mark transparent images + nvvector> m_SourcePaths; + eastl::hash_set m_SourcePathSet; + + Qt3DSRenderScene *m_LastRenderedScene; + Q3DStudio::IWindowSystem &m_WindowSystem; + Mutex m_LoadingScenesMutex; + eastl::vector> m_LoadingScenes; + CRegisteredString m_ProjectDir; + CRegisteredString m_BinaryDir; + bool m_ProjectInitialized; + QT3DSI32 mRefCount; + + Qt3DSRenderSceneManager(SBindingCore &ctx, Q3DStudio::IWindowSystem &inWindowSystem) + : m_Context(ctx) + , m_Scenes(ctx.GetAllocator(), "Qt3DSRenderSceneManager::m_Scenes") + , m_RenderPlugins(ctx.GetAllocator(), "Qt3DSRenderSceneManager::m_RenderPlugins") + , m_ViewWidth(0) + , m_ViewHeight(0) + , m_SourcePaths(ctx.GetAllocator(), "Qt3DSRenderSceneManager::m_SourcePaths") + , m_LastRenderedScene(NULL) + , m_WindowSystem(inWindowSystem) + , m_LoadingScenesMutex(ctx.GetAllocator()) + , m_ProjectInitialized(false) + , mRefCount(0) + { + memZero(&m_PickFrame, sizeof(m_PickFrame)); + } + virtual ~Qt3DSRenderSceneManager() + { + for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end; ++idx) + m_Scenes[idx].second->Release(); + m_Scenes.clear(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Context->GetAllocator()) + + static QT3DSU32 GetFileTag() + { + const char *fileTag = "Qt3DSS"; + const QT3DSU32 *theTagPtr = reinterpret_cast(fileTag); + return *theTagPtr; + } + + static bool IsImage(const char *ending) + { + if (!ending) + return false; + return stricmp(ending, "jpg") == 0 || stricmp(ending, "peg") == 0 + || stricmp(ending, "png") == 0 || stricmp(ending, "dds") == 0 + || stricmp(ending, "hdr") == 0; + } + static bool IsMesh(const char *ending) + { + if (!ending) + return false; + return stricmp(ending, "mesh") == 0; + } + + void FinalizeScene(Q3DStudio::IPresentation &inPresentation, Qt3DSRenderScene &inScene) + { + inPresentation.SetScene(&inScene); + if (m_ProjectInitialized == false) { + m_ProjectInitialized = true; + if (m_Context->m_Context->GetTextRenderer()) + m_Context->m_Context->GetTextRenderer()->AddProjectFontDirectory( + inScene.m_Presentation->m_PresentationDirectory); + eastl::string theBinaryPath(inPresentation.GetFilePath().toLatin1().constData()); + qt3ds::foundation::CFileTools::AppendDirectoryInPathToFile(theBinaryPath, "binary"); + eastl::string theBinaryDir(theBinaryPath); + qt3ds::foundation::CFileTools::GetDirectory(theBinaryDir); + if (m_Context->m_WriteOutShaderCache) + qt3ds::foundation::CFileTools::CreateDir(theBinaryDir.c_str()); + } + inScene.m_RuntimePresentation = &inPresentation; + m_Scenes.push_back(make_pair(&inPresentation, &inScene)); + Qt3DSTranslator::AssignUserData(inPresentation, *inScene.m_Presentation); + } + + static const char *GetBinaryExtension() { return "uibsg"; } + + struct SPluginInstanceTableProvider : public Q3DStudio::IScriptTableProvider + { + IRenderPluginInstance &m_Instance; + SPluginInstanceTableProvider(IRenderPluginInstance &ins) + : m_Instance(ins) + { + } + void CreateTable(script_State *inState) override { m_Instance.CreateScriptProxy(inState); } + }; + + void InitializeTranslator(Qt3DSTranslator &inTranslator, Q3DStudio::IScriptBridge &inBridge) + { + if (inTranslator.m_RenderObject->m_Type == GraphObjectTypes::RenderPlugin) { + SRenderPlugin &theRenderPlugin = + static_cast(*inTranslator.m_RenderObject); + IRenderPluginInstance *thePluginInstance = + m_Context->m_Context->GetRenderPluginManager().GetOrCreateRenderPluginInstance( + theRenderPlugin.m_PluginPath, &theRenderPlugin); + if (thePluginInstance) { + SPluginInstanceTableProvider theProvider(*thePluginInstance); + inBridge.SetTableForElement(*inTranslator.m_Element, theProvider); + } + } + } + + struct SResolver : public qt3ds::render::IUIPReferenceResolver + { + IStringTable &m_StringTable; + Q3DStudio::IUIPParser &m_Parser; + SResolver(IStringTable &strt, Q3DStudio::IUIPParser &p) + : m_StringTable(strt) + , m_Parser(p) + { + } + + CRegisteredString ResolveReference(CRegisteredString inStart, + const char *inReference) override + { + eastl::string theResolvedId = m_Parser.ResolveReference(inStart, inReference); + if (theResolvedId.size()) + return m_StringTable.RegisterStr(theResolvedId.c_str()); + return CRegisteredString(); + } + }; + + Q3DStudio::IScene *LoadScene(Q3DStudio::IPresentation *inPresentation, + Q3DStudio::IUIPParser *inParser, + Q3DStudio::IScriptBridge &inBridge, + const qt3ds::Q3DSVariantConfig &variantConfig) override + { + // We have to initialize the tags late so that we can load flow data before adding anything + // to the string table. + Qt3DSTranslator::InitializePointerTags(m_Context->m_RenderContext->GetStringTable()); + NVScopedRefCounted theScene = + QT3DS_NEW(m_Context->GetAllocator(), SSceneLoadData)(m_Context->GetAllocator()); + Qt3DSRenderScene *theIScene = NULL; + if (inParser) { + QString thePath(inPresentation->GetFilePath()); + QFileInfo fileInfo(thePath); + TIdObjectMap theObjMap(m_Context->GetAllocator(), "LoadScene::theObjMap"); + SResolver theResolver(m_Context->m_CoreContext->GetStringTable(), *inParser); + + theScene->m_Presentation = IUIPLoader::LoadUIPFile( + inParser->GetDOMReader(), + fileInfo.absoluteFilePath().toLatin1().constData(), + inParser->GetMetaData(), + m_Context->m_CoreContext->GetStringTable(), + m_Context->m_RenderContext->GetFoundation(), + theScene->m_AutoAllocator, theObjMap, + m_Context->m_Context->GetBufferManager(), + m_Context->m_Context->GetEffectSystem(), + fileInfo.path().toLatin1().constData(), + m_Context->m_Context->GetRenderPluginManager(), + m_Context->m_Context->GetCustomMaterialSystem(), + m_Context->m_Context->GetDynamicObjectSystem(), + m_Context->m_Context->GetPathManager(), &theResolver, + variantConfig, false); + if (!theScene->m_Presentation) { + QT3DS_ASSERT(false); + return NULL; + } + + NVConstDataRef theSourcePathData(inParser->GetSourcePaths()); + IBufferManager &theManager(m_Context->m_Context->GetBufferManager()); + // List of image paths to be loaded in parallel at the end. + eastl::vector theSourcePathList; + for (QT3DSU32 idx = 0, end = theSourcePathData.size(); idx < end; ++idx) { + const eastl::string &theValue = theSourcePathData[idx]; + CRegisteredString theSourcePath = + m_Context->m_CoreContext->GetStringTable().RegisterStr(theValue.c_str()); + size_t theValueSize = theValue.size(); + if (theValueSize > 3) { + const char *ending = theValue.c_str() + theValueSize - 3; + CRegisteredString theObjectPath = theSourcePath; + if (IsImage(ending)) { + theManager.SetImageTransparencyToFalseIfNotSet(theObjectPath); + if (m_SourcePathSet.insert(theSourcePath).second) + m_SourcePaths.push_back(eastl::make_pair( + theSourcePath, theManager.GetImageHasTransparency(theObjectPath))); + theSourcePathList.push_back(theObjectPath); + } else if (theValue.find(".mesh") != eastl::string::npos) { + theManager.LoadMesh(theObjectPath); + } + } + } + + // Fire off parallel loading of the source paths + QT3DSU64 imageBatchId = m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( + toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), + CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() + .GetRenderContextType(), + theScene->m_Presentation->m_preferKTX); + m_Context->m_Context->GetImageBatchLoader().BlockUntilLoaded( + static_cast(imageBatchId)); + + theIScene = QT3DS_NEW(m_Context->GetAllocator(), + Qt3DSRenderScene)(*m_Context, *m_Context->m_Context, *theScene); + // Now we need to associate the presentation with everything else. + NVAllocatorCallback &translatorAllocator = theScene->m_AutoAllocator; + for (TIdObjectMap::iterator iter = theObjMap.begin(), end = theObjMap.end(); + iter != end; ++iter) { + theIScene->m_GraphObjectList.push_back(iter->second); + Q3DStudio::SElementAndType theElement = + inParser->GetElementForID(iter->first.c_str()); + if (theElement.m_Element + && theElement.m_Type != Q3DStudio::UIPElementTypes::Unknown) { + Qt3DSTranslator *theTranslator = Qt3DSTranslator::CreateTranslatorForElement( + *theElement.m_Element, *iter->second, translatorAllocator); + if (theTranslator) { + theIScene->m_DirtySet.insert(*theTranslator); + InitializeTranslator(*theTranslator, inBridge); + } + } + } + } else { + // Binary load path is quite different than normal load path and + // nothing else will load here. + QT3DS_ASSERT(false); + } + if (inPresentation && theIScene) + FinalizeScene(*inPresentation, *theIScene); + return theIScene; + } + + // threadsafe + // Can be called from any thread + bool GetBinaryLoadFileName(eastl::string &inPresentationFilename, + eastl::string &outResult) override + { + eastl::string theBinaryPath(inPresentationFilename.c_str()); + qt3ds::foundation::CFileTools::AppendDirectoryInPathToFile(theBinaryPath, "binary"); + qt3ds::foundation::CFileTools::SetExtension( + theBinaryPath, GetBinaryExtension()); // uibb: short for ui binary binding + outResult = theBinaryPath; + return true; + } + + // threadsafe + // returns a handle to the loaded object. Return value of zero means error. + qt3ds::QT3DSU32 LoadSceneStage1(CRegisteredString inPresentationDirectory, + qt3ds::render::ILoadedBuffer &inData) override + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load Scene Graph Stage 1"); + NVDataRef theLoadedData(inData.Data()); + SDataReader theReader(theLoadedData.begin(), theLoadedData.end()); + + QT3DSU32 theFileSig = theReader.LoadRef(); + QT3DSU32 theBinaryVersion = theReader.LoadRef(); + QT3DSU32 theDataSectionSize = (QT3DSU32)(theReader.m_EndPtr - theReader.m_CurrentPtr); + + if (theFileSig != GetFileTag() + || theBinaryVersion != SGraphObject::GetSceneGraphBinaryVersion()) { + QT3DS_ASSERT(false); + return 0; + } + QT3DSU32 theLoadingSceneIndex = 0; + SSceneLoadData *theScene; + { + Mutex::ScopedLock __locker(m_LoadingScenesMutex); + theLoadingSceneIndex = (QT3DSU32)m_LoadingScenes.size() + 1; + m_LoadingScenes.push_back( + QT3DS_NEW(m_Context->GetAllocator(), SSceneLoadData)(m_Context->GetAllocator())); + theScene = m_LoadingScenes.back(); + } + // preserve the data buffer because we run directly from it; there isn't a memcopy. + theScene->m_Data = inData; + + QT3DSU32 theTranslatorOffset = theReader.LoadRef(); + + NVDataRef theSGData = NVDataRef(theReader.m_CurrentPtr, theTranslatorOffset); + NVDataRef theTranslatorData = NVDataRef( + theReader.m_CurrentPtr + theTranslatorOffset, theDataSectionSize - theTranslatorOffset); + + CStrTableOrDataRef theStrTableData(m_Context->m_CoreContext->GetStringTable()); + if (m_StrTableData.size()) + theStrTableData = CStrTableOrDataRef(m_StrTableData); + + theScene->m_Presentation = SGraphObjectSerializer::Load( + theSGData, m_StrTableData, m_Context->m_CoreContext->GetDynamicObjectSystemCore(), + m_Context->m_CoreContext->GetPathManagerCore(), m_Context->GetAllocator(), + inPresentationDirectory); + if (theScene->m_Presentation) + theScene->m_Presentation->m_PresentationDirectory = inPresentationDirectory; + + theScene->m_TranslatorData = theTranslatorData; + theScene->m_SceneGraphData = theSGData; + + { + Mutex::ScopedLock __locker(m_LoadingScenesMutex); + m_LoadingScenes[theLoadingSceneIndex - 1] = theScene; + } + return theLoadingSceneIndex; + } + + // threadsafe + // still does not require openGL context but has dependency on a few other things. + void LoadSceneStage2(qt3ds::QT3DSU32 inSceneHandle, Q3DStudio::IPresentation &inPresentation, + size_t inElementMemoryOffset, Q3DStudio::IScriptBridge &inBridge) override + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load Scene Graph Stage 2"); + QT3DSU32 theSceneIndex = QT3DS_MAX_U32; + SSceneLoadData *theScene; + { + Mutex::ScopedLock __locker(m_LoadingScenesMutex); + QT3DSU32 numLoadingScenes = (QT3DSU32)m_LoadingScenes.size(); + if (inSceneHandle && inSceneHandle <= numLoadingScenes) { + theSceneIndex = inSceneHandle - 1; + theScene = m_LoadingScenes[theSceneIndex]; + } else { + QT3DS_ASSERT(false); + return; + } + } + SDataReader theReader(theScene->m_TranslatorData.begin(), theScene->m_TranslatorData.end()); + QT3DSU32 theNumTranslators = theReader.LoadRef(); + theScene->m_Translators.resize(theNumTranslators); + theScene->m_RuntimePresentation = &inPresentation; + for (QT3DSU32 idx = 0, end = theNumTranslators; idx < end; ++idx) { + Qt3DSTranslator *theTranslator = Qt3DSTranslator::LoadTranslator( + theReader, inElementMemoryOffset, theScene->m_SceneGraphData, + theScene->m_AutoAllocator); + if (theTranslator) { + InitializeTranslator(*theTranslator, inBridge); + } + theScene->m_Translators[idx] = theTranslator; + } + } + + void OnGraphicsInitialized() + { + QT3DS_ASSERT(m_Context->m_Context.mPtr); + // this means graphics have been initialized + eastl::string theSourcePathStr; + IBufferManager &theManager(m_Context->m_Context->GetBufferManager()); + nvvector theSourcePathList(m_Context->GetAllocator(), + "TempSourcePathList"); + for (QT3DSU32 idx = 0, end = m_SourcePaths.size(); idx < end; ++idx) { + theSourcePathStr.assign(m_SourcePaths[idx].first); + bool hasTransparency = m_SourcePaths[idx].second; + if (theSourcePathStr.size() > 4) { + CRegisteredString theObjectPath = m_SourcePaths[idx].first; + const char *theEnding = theSourcePathStr.c_str() + theSourcePathStr.size() - 3; + if (IsImage(theEnding)) { + theManager.SetImageHasTransparency(theObjectPath, hasTransparency); + theSourcePathList.push_back(theObjectPath); + } else { + if (theSourcePathStr.find(".mesh") != eastl::string::npos) + theManager.LoadMesh(theObjectPath); + } + } + } + + bool pktx = false; + for (int i = 0; i < m_Scenes.size(); ++i) { + if (m_Scenes[i].second->m_Presentation->m_preferKTX) { + pktx = true; + break; + } + } + + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Initial Batch Image Load"); + + m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( + toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), + CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() + .GetRenderContextType(), pktx); + } + + { + + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Initialize Scenes"); + for (QT3DSU32 idx = 0, end = m_LoadingScenes.size(); idx < end; ++idx) { + SSceneLoadData &theScene = *m_LoadingScenes[idx]; + // m_Context->m_Foundation->error( QT3DS_WARN, "Finalizing scene %d", (int)idx+1 ); + if (theScene.m_RuntimePresentation) { + Qt3DSRenderScene *theIScene = QT3DS_NEW(m_Context->GetAllocator(), Qt3DSRenderScene)( + *m_Context, *m_Context->m_Context, theScene); + FinalizeScene(*theScene.m_RuntimePresentation, *theIScene); + } else { + qCWarning(WARNING, "Failed to finalize scene %d", (int)idx + 1); + } + } + } + } + + void LoadRenderPlugin(const char *inAssetIDString, const char *inPath, + const char *inArgs) override + { + Q3DStudio::CDLLManager &theDLLManager = Q3DStudio::CDLLManager::GetDLLManager(); + long theHandle = theDLLManager.LoadLibrary(inPath, EDLLTYPE_RENDERABLE_PLUGIN); + if (theHandle >= 0) { + qt3ds::render::IOffscreenRenderer *theOffscreenRenderer = + QT3DS_NEW(m_Context->GetAllocator(), + qt3ds::render::COldNBustedPluginRenderer)(*m_Context->m_Context, theHandle); + qt3ds::foundation::CRegisteredString theAssetString = + m_Context->m_CoreContext->GetStringTable().RegisterStr(inAssetIDString); + + m_Context->m_Context->GetOffscreenRenderManager().RegisterOffscreenRenderer( + theAssetString, *theOffscreenRenderer); + + PROC_Initialize theInitializeProc = + reinterpret_cast(theDLLManager.GetProc("Initialize", theHandle)); + Q3DStudio_ASSERT(theInitializeProc); +#if !defined (Q_OS_MACOS) + PROC_SetEGLInfo theSetEGLInfoProc = + reinterpret_cast(theDLLManager.GetProc("SetEGLInfo", theHandle)); + // Set EGL parameters used for optional context creation + if (theSetEGLInfoProc) { + Q3DStudio::SEGLInfo *theInfo = m_WindowSystem.GetEGLInfo(); + if (theInfo) + theSetEGLInfoProc(theInfo->display, theInfo->context, theInfo->surface, + theInfo->config); + } +#endif + if (theInitializeProc && theInitializeProc(inArgs) == EDLLSTATUS_OK) + m_RenderPlugins.push_back(make_pair(theAssetString, theHandle)); + else + qCWarning(qt3ds::INVALID_OPERATION) << "Unable to load plugin " << inAssetIDString; + } else + qCWarning(qt3ds::INVALID_OPERATION) << "Unable to load plugin " << inAssetIDString; + + return; + } + + void LoadQmlStreamerPlugin(const char *inAssetIDString) override + { + qt3ds::render::IOffscreenRenderer *theOffscreenRenderer = + QT3DS_NEW(m_Context->GetAllocator(), + Q3DSQmlRender)(*m_Context->m_Context, inAssetIDString); + if (theOffscreenRenderer) { + qt3ds::foundation::CRegisteredString theAssetString = + m_Context->m_CoreContext->GetStringTable().RegisterStr(inAssetIDString); + m_Context->m_Context->GetOffscreenRenderManager().RegisterOffscreenRenderer( + SOffscreenRendererKey(theAssetString), *theOffscreenRenderer); + + m_RenderPlugins.push_back(make_pair(theAssetString, 0)); + } + } + + void BinarySave(Q3DStudio::IScene &inScene) override + { + Qt3DSRenderScene &theScene = static_cast(inScene); + qt3ds::render::SWriteBuffer theWriteBuffer(m_Context->GetAllocator(), "BinarySaveBuffer"); + qt3ds::render::SPtrOffsetMap theSGOffsetMap(m_Context->GetAllocator(), "PointerOffsetMap"); + // Start with some versioning and sanity checks. + theWriteBuffer.write(GetFileTag()); + theWriteBuffer.write(SGraphObject::GetSceneGraphBinaryVersion()); + QT3DSU32 theTranslatorOffsetAddress = theWriteBuffer.size(); + // Now the data section starts. Offsets should be relative to here, not the first + // 8 bytes. + theWriteBuffer.writeZeros(4); // offset where the translator data starts; + QT3DSU32 theDataSectionStart = theWriteBuffer.size(); + + // These offsets are after we have read in the data section + SGraphObjectSerializer::Save( + m_Context->m_RenderContext->GetFoundation(), *theScene.m_Presentation, theWriteBuffer, + m_Context->m_Context->GetDynamicObjectSystem(), + m_Context->m_Context->GetPathManager(), theSGOffsetMap, + m_Context->m_CoreContext->GetStringTable(), theScene.m_GraphObjectList); + + theWriteBuffer.align(sizeof(void *)); + QT3DSU32 theTranslatorCountAddress = theWriteBuffer.size(); + QT3DSU32 theTranslatorOffset = theTranslatorCountAddress - theDataSectionStart; + + theWriteBuffer.writeZeros(4); + // Now write out the translators verbatim. We get an adjustment parameter on save that + // allows a translation + // from old element ptr->new element ptr. + QT3DSU32 theTranslatorCount = 0; + for (QT3DSU32 idx = 0, end = theScene.m_GraphObjectList.size(); idx < end; ++idx) { + Qt3DSTranslator *theTranslator = + Qt3DSTranslator::GetTranslatorFromGraphNode(*theScene.m_GraphObjectList[idx]); + // Presentation nodes don't have translator + if (theTranslator) { + qt3ds::render::SPtrOffsetMap::iterator theIter = + theSGOffsetMap.find(theScene.m_GraphObjectList[idx]); + if (theIter != theSGOffsetMap.end()) { + QT3DSU32 theOffset = theIter->second; + theTranslator->Save(theWriteBuffer, theOffset); + ++theTranslatorCount; + } else { + QT3DS_ASSERT(false); + } + } + } + QT3DSU32 *theTranslatorCountPtr = + reinterpret_cast(theWriteBuffer.begin() + theTranslatorCountAddress); + *theTranslatorCountPtr = theTranslatorCount; + QT3DSU32 *theTranslatorOffsetPtr = + reinterpret_cast(theWriteBuffer.begin() + theTranslatorOffsetAddress); + *theTranslatorOffsetPtr = theTranslatorOffset; + + Q3DStudio::IPresentation &thePresentation = *theScene.m_RuntimePresentation; + eastl::string theBinaryPath(thePresentation.GetFilePath().toLatin1().constData()); + qt3ds::foundation::CFileTools::AppendDirectoryInPathToFile(theBinaryPath, "binary"); + eastl::string theBinaryDir(theBinaryPath); + qt3ds::foundation::CFileTools::GetDirectory(theBinaryDir); + qt3ds::foundation::CFileTools::SetExtension( + theBinaryPath, GetBinaryExtension()); // uibb: short for ui binary binding + + Q3DStudio::CFileStream theStream(theBinaryPath.c_str(), "wb"); + if (theStream.IsOpen() == false) { + QT3DS_ASSERT(false); + } + + theStream.WriteRaw(theWriteBuffer.begin(), theWriteBuffer.size()); + theStream.Close(); + } + + // We save in the reverse order that we load because the effect system may add strings + // to the string table when it is writing its data out, this the string table needs to come + // last. + // Loading, obviously, the string table needs to be the first object loaded. + void BinarySaveManagerData(qt3ds::foundation::IOutStream &inStream, + const char *inBinaryDir) override + { + qt3ds::render::SWriteBuffer theWriteBuffer(m_Context->GetAllocator(), "BinarySaveBuffer"); + IStringTable &theStrTable = m_Context->m_CoreContext->GetStringTable(); + eastl::string theProjectDir(inBinaryDir); + qt3ds::foundation::CFileTools::GetDirectory(theProjectDir); + + // We save everything before the string table because often times saving something creates + // new strings. + theWriteBuffer.writeZeros(4); // Total data size + // Dynamic object system + theWriteBuffer.writeZeros(4); // Effect system offset + // effect system + theWriteBuffer.writeZeros(4); // Material system offset + // material system + theWriteBuffer.writeZeros(4); // Binary path offset + // binary path data + theWriteBuffer.writeZeros(4); // Plugin manager offset + // plugin manager + theWriteBuffer.writeZeros(4); // String system offset + // string system last. + QT3DSU32 theOffsetStart = theWriteBuffer.size(); + m_Context->m_Context->GetDynamicObjectSystem().Save( + theWriteBuffer, theStrTable.GetRemapMap(), theProjectDir.c_str()); + theWriteBuffer.align(sizeof(void *)); + QT3DSU32 theEffectSystemOffset = theWriteBuffer.size() - theOffsetStart; + m_Context->m_Context->GetEffectSystem().Save(theWriteBuffer, theStrTable.GetRemapMap(), + theProjectDir.c_str()); + theWriteBuffer.align(sizeof(void *)); + QT3DSU32 theMaterialSystemOffset = theWriteBuffer.size() - theOffsetStart; + m_Context->m_Context->GetCustomMaterialSystem().Save( + theWriteBuffer, theStrTable.GetRemapMap(), theProjectDir.c_str()); + QT3DSU32 theBinaryPathOffset = theWriteBuffer.size() - theOffsetStart; + + theWriteBuffer.write((QT3DSU32)m_SourcePaths.size()); + for (nvvector>::iterator iter = m_SourcePaths.begin(), + end = m_SourcePaths.end(); + iter != end; ++iter) { + CRegisteredString theStr(iter->first); + theStr.Remap(theStrTable.GetRemapMap()); + theWriteBuffer.write((size_t)theStr.c_str()); + QT3DSU32 theSourcePathFlags = iter->second ? 1 : 0; + theWriteBuffer.write(theSourcePathFlags); + } + + QT3DSU32 thePluginManagerOffset = theWriteBuffer.size() - theOffsetStart; + + m_Context->m_Context->GetRenderPluginManager().Save( + theWriteBuffer, theStrTable.GetRemapMap(), theProjectDir.c_str()); + + QT3DSU32 theStringTableOffset = theWriteBuffer.size() - theOffsetStart; + + theStrTable.Save(theWriteBuffer); + + QT3DSU32 *theSizePtr = reinterpret_cast(theWriteBuffer.begin()); + + theSizePtr[0] = theWriteBuffer.size() - 4; // overall size + theSizePtr[1] = theEffectSystemOffset; + theSizePtr[2] = theMaterialSystemOffset; + theSizePtr[3] = theBinaryPathOffset; // thePathOffset + theSizePtr[4] = thePluginManagerOffset; + theSizePtr[5] = theStringTableOffset; + + inStream.Write(theWriteBuffer.begin(), theWriteBuffer.size()); + } + + NVDataRef BinaryLoadManagerData(qt3ds::foundation::IInStream &inStream, + const char *inBinaryDir) override + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - String Table + Render Objects"); + QT3DS_ASSERT(m_Context->m_FlowData == NULL); + QT3DSU32 dataSize = 0; + inStream.Read(dataSize); + m_Context->m_FlowData = (QT3DSU8 *)m_Context->m_CoreContext->GetAllocator().allocate( + dataSize, "SceneManager::BinaryFlowData", __FILE__, __LINE__); + + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - Initial Data Load"); + inStream.Read(m_Context->m_FlowData, dataSize); + } + SDataReader theReader(m_Context->m_FlowData, m_Context->m_FlowData + dataSize); + QT3DSU32 theEffectSystemOffset = theReader.LoadRef(); + QT3DSU32 theMaterialSystemOffset = theReader.LoadRef(); + QT3DSU32 theBinaryPathOffset = theReader.LoadRef(); + QT3DSU32 thePluginManagerOffset = theReader.LoadRef(); + QT3DSU32 theStringTableOffset = theReader.LoadRef(); + QT3DSU8 *theStartOffset = theReader.m_CurrentPtr; + IStringTable &theStrTable = m_Context->m_CoreContext->GetStringTable(); + + // Load string table. + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - Load String Table"); + m_StrTableData = toDataRef(theReader.m_CurrentPtr + theStringTableOffset, + dataSize - theStringTableOffset); + theStrTable.Load(m_StrTableData); + } + + // Load source paths to preload heavy data + theReader.m_CurrentPtr = theStartOffset + theBinaryPathOffset; + QT3DSU32 theNumSourcePaths = theReader.LoadRef(); + eastl::string theSourcePathStr; + eastl::string theProjectDir(inBinaryDir); + eastl::string theShaderCacheDir(inBinaryDir); + + // Up one moves to the project directory. + qt3ds::foundation::CFileTools::GetDirectory(theProjectDir); + const char8_t *theBasePath(theProjectDir.c_str()); + + m_ProjectDir = theStrTable.RegisterStr(theProjectDir.c_str()); + m_BinaryDir = theStrTable.RegisterStr(theShaderCacheDir.c_str()); + + // Preload the heavy buffers + m_SourcePaths.resize(theNumSourcePaths); + for (QT3DSU32 idx = 0, end = theNumSourcePaths; idx < end; ++idx) { + CRegisteredString thePath = theReader.LoadRef(); + QT3DSU32 theFlags = theReader.LoadRef(); + thePath.Remap(m_StrTableData); + bool theBoolFlagValue = theFlags ? true : false; + m_SourcePaths[idx] = eastl::make_pair(thePath, theBoolFlagValue); + } + + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - Base Dynamic System"); + // Load effect system. + NVDataRef theDynamicSystemData(theStartOffset, theEffectSystemOffset); + m_Context->m_CoreContext->GetDynamicObjectSystemCore().Load( + theDynamicSystemData, m_StrTableData, theBasePath); + } + + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - Effect System"); + NVDataRef theEffectSystemData(theStartOffset + theEffectSystemOffset, + theMaterialSystemOffset - theEffectSystemOffset); + m_Context->m_CoreContext->GetEffectSystemCore().Load(theEffectSystemData, + m_StrTableData, theBasePath); + } + + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - Material System"); + NVDataRef theMaterialSystemData(theStartOffset + theMaterialSystemOffset, + thePluginManagerOffset - theMaterialSystemOffset); + m_Context->m_CoreContext->GetMaterialSystemCore().Load(theMaterialSystemData, + m_StrTableData, theBasePath); + } + + { + SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), + "Load UIAB - Plugin Manager Data"); + NVDataRef thePluginManagerData(theStartOffset + thePluginManagerOffset, + theStringTableOffset - thePluginManagerOffset); + m_Context->m_CoreContext->GetRenderPluginCore().Load(thePluginManagerData, + m_StrTableData, theBasePath); + } + + return m_StrTableData; + } + + virtual void DeleteScene(Q3DStudio::IPresentation *inPresentation) + { + QT3DSU32 idx; + QT3DSU32 end; + for (idx = 0, end = m_Scenes.size(); idx < end; ++idx) { + if (m_Scenes[idx].first == inPresentation) + break; + } + if (idx < m_Scenes.size()) { + m_Scenes[idx].second->Release(); + m_Scenes.erase(m_Scenes.begin() + idx); + } + } + + Q3DStudio::BOOL Update() override + { + bool theResult = false; + long theSceneCount = m_Scenes.size(); + for (long theSceneIndex = 0; theSceneIndex < theSceneCount; ++theSceneIndex) { + Qt3DSRenderScene *theScene = m_Scenes[theSceneIndex].second; + theResult |= theScene->Update(); + } + return theResult; + } + + Q3DStudio::BOOL RenderPresentation(Q3DStudio::IPresentation *inPresentation) override + { + Qt3DSRenderScene *theFirstScene = NULL; + for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end && theFirstScene == NULL; ++idx) + if (m_Scenes[idx].second->m_RuntimePresentation == inPresentation) + theFirstScene = m_Scenes[idx].second; + + if (theFirstScene && theFirstScene->m_Presentation) { + m_LastRenderedScene = theFirstScene; + if (theFirstScene->m_Presentation->m_Scene + && theFirstScene->m_Presentation->m_Scene->m_UseClearColor) { + m_Context->m_Context->SetSceneColor( + QT3DSVec4(theFirstScene->m_Presentation->m_Scene->m_ClearColor, 1.0f)); + } else + m_Context->m_Context->SetSceneColor(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + + // Setup the render rotation *before* rendering so that the magic can happen on begin + // render. + if (m_Context->m_RenderRotationsEnabled) + m_Context->m_Context->SetRenderRotation( + theFirstScene->m_Presentation->m_PresentationRotation); + else + m_Context->m_Context->SetRenderRotation(RenderRotationValues::NoRotation); + + m_Context->m_Context->SetPresentationDimensions(QSize( + (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.x, + (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.y)); + } + + m_Context->m_Context->BeginFrame(); + m_Context->m_RenderContext->ResetBlendState(); + + // How exactly does this work, I have no idea. + // Should we only render the first scene and not every scene, perhaps? + bool wasDirty = false; + if (theFirstScene) + wasDirty = theFirstScene->PrepareForRender(); + else { + m_Context->m_RenderContext->SetClearColor(QT3DSVec4(0, 0, 0, 0)); + m_Context->m_RenderContext->Clear(qt3ds::render::NVRenderClearFlags( + NVRenderClearValues::Color | NVRenderClearValues::Depth)); + } + m_Context->m_Context->RunRenderTasks(); + if (theFirstScene) + theFirstScene->Render(); + + m_Context->m_Context->EndFrame(); + + return wasDirty; + } + // I think render::check resize is called so this isn't necessary + void OnViewResize(Q3DStudio::INT32 inViewWidth, Q3DStudio::INT32 inViewHeight) override + { + m_ViewWidth = inViewWidth; + m_ViewHeight = inViewHeight; + } + void GetViewSize(Q3DStudio::INT32 &outWidth, Q3DStudio::INT32 &outHeight) override + { + outWidth = m_ViewWidth; + outHeight = m_ViewHeight; + } + + Q3DStudio::STextSizes GetDisplayDimensions(Q3DStudio::IPresentation *inPresentation) override + { + Qt3DSRenderScene *theFirstScene = NULL; + for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end && theFirstScene == NULL; ++idx) + if (m_Scenes[idx].second->m_RuntimePresentation == inPresentation) + theFirstScene = m_Scenes[idx].second; + if (theFirstScene) { + m_Context->m_Context->SetPresentationDimensions(QSize( + (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.x, + (QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.y)); + render::NVRenderRectF theDisplayViewport = + m_Context->m_Context->GetDisplayViewport(); + return Q3DStudio::STextSizes( + static_cast(theDisplayViewport.m_Width), + static_cast(theDisplayViewport.m_Height)); + } + return Q3DStudio::STextSizes(static_cast(0), + static_cast(0)); + } + + Q3DStudio::TElement *UserPick(float mouseX, float mouseY) override + { + if (m_LastRenderedScene) { + return m_LastRenderedScene->UserPick(mouseX, mouseY); + } + return NULL; + } + + Option FacePosition(Q3DStudio::TElement &inElement, float mouseX, float mouseY, + NVDataRef inElements, + Q3DStudio::FacePositionPlanes::Enum inPlane) override + { + if (m_LastRenderedScene) { + + return m_LastRenderedScene->FacePosition(inElement, mouseX, mouseY, inElements, + inPlane); + } + return Empty(); + } + + Q3DStudio::SPickFrame AdvancePickFrame(const Q3DStudio::SInputFrame &inInputFrame) override + { + // We now have a new input frame, and our results are invalid but ready to be filled + m_PickFrame.m_InputFrame = inInputFrame; + m_PickFrame.m_Model = NULL; + m_PickFrame.m_ResultValid = false; + if (m_LastRenderedScene) { + if (m_PickFrame.m_InputFrame.m_PickValid) + m_LastRenderedScene->Pick(m_PickFrame); + } + return m_PickFrame; + } + + void Release() override + { + long theRenderPluginSize = m_RenderPlugins.size(); + Q3DStudio::CDLLManager &theDLLManager = Q3DStudio::CDLLManager::GetDLLManager(); + for (int theRenderPluginIndex = 0; theRenderPluginIndex < theRenderPluginSize; + ++theRenderPluginIndex) { + long theDLLHandle = m_RenderPlugins[theRenderPluginIndex].second; + PROC_Uninitialize theUninitializeProc = reinterpret_cast( + theDLLManager.GetProc("Uninitialize", theDLLHandle)); + Q3DStudio_ASSERT(theUninitializeProc); + theUninitializeProc &&theUninitializeProc(); + + theDLLManager.UnloadLibrary(theDLLHandle); + } + + // Ensure the binding core doesn't get released until after we get released. + NVScopedRefCounted theContext(m_Context); + NVDelete(m_Context->GetAllocator(), this); + } +}; + +struct SRenderFactory; + +struct SVisualStateHandler : public qt3ds::state::IVisualStateInterpreterFactory, + public qt3ds::state::IVisualStateCommandHandler +{ + NVAllocatorCallback &m_Allocator; + QT3DSI32 mRefCount; + SRenderFactory &m_Factory; + +public: + SVisualStateHandler(NVAllocatorCallback &alloc, SRenderFactory &inFactory) + : m_Allocator(alloc) + , mRefCount(0) + , m_Factory(inFactory) + { + } + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Allocator) + + void Handle(const qt3ds::state::SVisualStateCommand &inCommand, + qt3ds::state::IScriptContext &inScriptContext) override; +}; + +struct SRenderFactory : public IQt3DSRenderFactoryCore, public IQt3DSRenderFactory +{ + NVScopedRefCounted m_Context; + + NVScopedRefCounted m_ScriptBridgeQml; + NVScopedRefCounted m_SceneManager; + NVScopedRefCounted m_VisualStateContext; + NVScopedRefCounted m_EventSystem; + qt3ds::runtime::IApplicationCore *m_ApplicationCore; + qt3ds::runtime::IApplication *m_Application; + QT3DSI32 m_RefCount; + + SRenderFactory(SBindingCore &inCore) + : m_Context(inCore) + , m_ScriptBridgeQml(NULL) + , m_SceneManager(NULL) + , m_ApplicationCore(NULL) + , m_Application(NULL) + , m_RefCount(0) + { + } + + ~SRenderFactory() + { + using namespace Q3DStudio; + // Release the visual state context. + m_VisualStateContext = NULL; + // Release the event system, it must be released before script engine + m_EventSystem = NULL; + m_ScriptBridgeQml->Shutdown(*m_Context->m_Foundation); + } + + void addRef() override { atomicIncrement(&m_RefCount); } + + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVScopedRefCounted theContext(m_Context); + NVDelete(m_Context->GetAllocator(), this); + } + } + + qt3ds::render::IQt3DSRenderContextCore &GetRenderContextCore() override + { + return *m_Context->m_CoreContext; + } + + qt3ds::runtime::IApplicationCore *GetApplicationCore() override { return m_ApplicationCore; } + void SetApplicationCore(qt3ds::runtime::IApplicationCore *app) override + { + m_ApplicationCore = app; + } + + Q3DStudio::ISceneBinaryLoader &GetSceneLoader() override + { + if (m_SceneManager == NULL) + m_SceneManager = QT3DS_NEW(m_Context->GetAllocator(), + Qt3DSRenderSceneManager)(*m_Context, m_Context->m_WindowSystem); + return *m_SceneManager; + } + + Q3DStudio::ITegraApplicationRenderEngine &CreateRenderEngine() override + { + return m_Context->CreateRenderer(); + } + Q3DStudio::ISceneManager &GetSceneManager() override + { + if (m_SceneManager == NULL) + m_SceneManager = QT3DS_NEW(m_Context->GetAllocator(), + Qt3DSRenderSceneManager)(*m_Context, m_Context->m_WindowSystem); + return *m_SceneManager; + } + Q3DStudio::IScriptBridge &GetScriptEngineQml() override + { + if (m_ScriptBridgeQml == NULL) { + m_ScriptBridgeQml = + Q3DStudio::CQmlEngine::Create(*m_Context->m_Foundation, m_Context->m_TimeProvider); + } + + return *m_ScriptBridgeQml; + } + qt3ds::render::IInputStreamFactory &GetInputStreamFactory() override + { + return m_Context->m_CoreContext->GetInputStreamFactory(); + } + + qt3ds::render::IQt3DSRenderContext &GetQt3DSRenderContext() override + { + return *m_Context->m_Context; + } + qt3ds::state::IVisualStateContext &GetVisualStateContext() override + { + if (!m_VisualStateContext) { + m_VisualStateContext = qt3ds::state::IVisualStateContext::Create( + *m_Context->m_Foundation, m_Context->m_CoreContext->GetStringTable()); + SVisualStateHandler *newHandle = + QT3DS_NEW(m_Context->m_Foundation->getAllocator(), + SVisualStateHandler)(m_Context->m_Foundation->getAllocator(), *this); + m_VisualStateContext->SetCommandHandler(newHandle); + m_VisualStateContext->SetInterpreterFactory(newHandle); + } + return *m_VisualStateContext; + } + qt3ds::evt::IEventSystem &GetEventSystem() override + { + if (!m_EventSystem) { + m_EventSystem = qt3ds::evt::IEventSystem::Create(*m_Context->m_Foundation); + } + return *m_EventSystem; + } + Q3DStudio::ITimeProvider &GetTimeProvider() override { return m_Context->m_TimeProvider; } + qt3ds::foundation::IStringTable &GetStringTable() override + { + return m_Context->m_CoreContext->GetStringTable(); + } + qt3ds::NVFoundationBase &GetFoundation() override { return *m_Context->m_Foundation.mPtr; } + qt3ds::foundation::IPerfTimer &GetPerfTimer() override + { + return m_Context->m_CoreContext->GetPerfTimer(); + } + qt3ds::runtime::IApplication *GetApplication() override { return m_Application; } + void SetApplication(qt3ds::runtime::IApplication *app) override + { + m_Application = app; + if (app) { + // QML engine + GetScriptEngineQml(); + m_ScriptBridgeQml->SetApplication(*app); + m_ScriptBridgeQml->Initialize(); + } + } + void SetDllDir(const char *dllDir) override + { + m_Context->m_CoreContext->GetRenderPluginCore().SetDllDir(dllDir); + } + + void AddSearchPath(const char8_t *inFile) override + { + m_Context->m_CoreContext->GetInputStreamFactory().AddSearchDirectory(inFile); + } + virtual void Release() { NVDelete(m_Context->GetAllocator(), this); } + + struct SContextTypeRenderFactory : public IRuntimeFactoryRenderFactory + { + QSurfaceFormat format; + SContextTypeRenderFactory(const QSurfaceFormat &fmt) + : format(fmt) + { + } + + qt3ds::render::NVRenderContext *CreateRenderContext(qt3ds::NVFoundationBase &foundat, + IStringTable &strt) override + { +#ifndef Qt3DS_NO_RENDER_SYMBOLS + qt3ds::render::NVRenderContext &retval = NVRenderContext::CreateGL(foundat, strt, format); + return &retval; +#else + qt3ds::render::NVRenderContext &retval = NVRenderContext::CreateNULL(foundat, strt); + return &retval; +#endif + } + }; + + IQt3DSRenderFactory &CreateRenderFactory(const QSurfaceFormat& format) override + { + + SContextTypeRenderFactory theContextFactory(format); + m_Context->CreateRenderContext(theContextFactory); + + GetSceneLoader(); + { + SStackPerfTimer __loadTimer(GetPerfTimer(), "SceneManager OnGraphicsInitialized"); + m_SceneManager->OnGraphicsInitialized(); + } + return *this; + } +}; + +Q3DStudio::SScriptEngineGotoSlideArgs ToEngine(const qt3ds::state::SGotoSlideData &inData) +{ + using namespace qt3ds::state; + Q3DStudio::SScriptEngineGotoSlideArgs retval; + if (inData.m_Mode.hasValue()) { + switch (*inData.m_Mode) { + case SlidePlaybackModes::StopAtEnd: + retval.m_Mode = Q3DStudio::TimePolicyModes::StopAtEnd; + break; + case SlidePlaybackModes::Looping: + retval.m_Mode = Q3DStudio::TimePolicyModes::Looping; + break; + case SlidePlaybackModes::Ping: + retval.m_Mode = Q3DStudio::TimePolicyModes::Ping; + break; + case SlidePlaybackModes::PingPong: + retval.m_Mode = Q3DStudio::TimePolicyModes::PingPong; + break; + default: + QT3DS_ASSERT(false); + break; + } + } + if (inData.m_PlaythroughTo.hasValue()) + retval.m_PlaythroughTo = inData.m_PlaythroughTo->c_str(); + if (inData.m_Paused.hasValue()) + retval.m_Paused = inData.m_Paused; + retval.m_Rate = inData.m_Rate; + retval.m_Reverse = inData.m_Reverse; + if (inData.m_StartTime.hasValue()) + retval.m_StartTime = *inData.m_StartTime; + return retval; +} + +class CStateScriptEngineCallFunctionArgRetriever + : public Q3DStudio::CScriptEngineCallFunctionArgRetriever +{ +public: + CStateScriptEngineCallFunctionArgRetriever(const char *inArguments, + qt3ds::state::IScriptContext &inScriptContext) + : CScriptEngineCallFunctionArgRetriever(inArguments) + , m_ScriptContext(inScriptContext) + { + } + int RetrieveArgument(script_State *inState) override + { + (void *)inState; + return m_ScriptContext.ExecuteStr(m_ArgumentString, true) ? 1 : -1; + } + +private: + qt3ds::state::IScriptContext &m_ScriptContext; +}; + +void SVisualStateHandler::Handle(const qt3ds::state::SVisualStateCommand &inCommand, + qt3ds::state::IScriptContext &inScriptContext) +{ + using namespace qt3ds::state; + switch (inCommand.getType()) { + case VisualStateCommandTypes::GotoSlide: { + const SGotoSlide &theInfo(inCommand.getData()); + m_Factory.m_ScriptBridgeQml->GotoSlide(theInfo.m_Component.c_str(), + theInfo.m_Slide.c_str(), + ToEngine(theInfo.m_GotoSlideData)); + } break; + case VisualStateCommandTypes::SetAttribute: { + const SSetAttribute &theInfo(inCommand.getData()); + m_Factory.m_ScriptBridgeQml->SetAttribute( + theInfo.m_Element.c_str(), theInfo.m_Attribute.c_str(), + theInfo.m_Value.c_str()); + } break; + case VisualStateCommandTypes::GotoSlideRelative: { + const SGotoSlideRelative &theInfo(inCommand.getData()); + if (theInfo.m_Direction == SGotoSlideRelative::Error) { + qCCritical(INVALID_OPERATION, + "Goto slide relative has invalid attribute (neither 'next' nor 'previous')"); + } else { + m_Factory.m_ScriptBridgeQml->GotoSlideRelative( + theInfo.m_Component.c_str(), + theInfo.m_Direction == SGotoSlideRelative::Next, + theInfo.m_Wrap, ToEngine(theInfo.m_GotoSlideData)); + } + } break; + case VisualStateCommandTypes::FireEvent: { + const SFireEvent &theInfo(inCommand.getData()); + m_Factory.m_ScriptBridgeQml->FireEvent(theInfo.m_Element, theInfo.m_Event); + } break; + case VisualStateCommandTypes::PresentationAttribute: { + const SPresentationAttribute &theInfo(inCommand.getData()); + m_Factory.m_ScriptBridgeQml->SetPresentationAttribute(theInfo.m_Presentation, + theInfo.m_Attribute, + theInfo.m_Value); + } break; + case VisualStateCommandTypes::PlaySound: { + const SPlaySound &theInfo(inCommand.getData()); + m_Factory.m_ScriptBridgeQml->PlaySoundFile(theInfo.m_SoundFilePath); + } break; + default: + QT3DS_ASSERT(false); + break; + } +} +} + +IQt3DSRenderFactoryCore &IQt3DSRenderFactoryCore::CreateRenderFactoryCore( + const char8_t *inApplicationDirectory, + Q3DStudio::IWindowSystem &inWindowSystem, + Q3DStudio::ITimeProvider &inTimeProvider) +{ + SBindingCore *theCore = (SBindingCore *)malloc(sizeof(SBindingCore)); + new (theCore) SBindingCore(inApplicationDirectory, inWindowSystem, inTimeProvider); + return *QT3DS_NEW(theCore->GetAllocator(), SRenderFactory)(*theCore); +} diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.h b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.h new file mode 100644 index 00000000..ea95b943 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_RUNTIME_BINDING_H +#define QT3DS_RENDER_RUNTIME_BINDING_H + +#include "Qt3DSRuntimeFactory.h" +#include "EABase/eabase.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +#include + +namespace Q3DStudio { +class ITegraApplicationRenderEngine; +class ITimeProvider; +class IWindowSystem; +} + +namespace qt3ds { +namespace render { + + class ITextRenderer; + class IRuntimeFactoryRenderFactory + { + protected: + virtual ~IRuntimeFactoryRenderFactory() {} + public: + virtual qt3ds::render::NVRenderContext * + CreateRenderContext(qt3ds::NVFoundationBase &foundat, qt3ds::foundation::IStringTable &strt) = 0; + }; + + class IQt3DSRenderFactory; + + class QT3DS_AUTOTEST_EXPORT IQt3DSRenderFactoryCore : public Q3DStudio::IRuntimeFactoryCore + { + public: + virtual IQt3DSRenderFactory & + CreateRenderFactory(const QSurfaceFormat &format) = 0; + + static IQt3DSRenderFactoryCore & + CreateRenderFactoryCore(const char8_t *inApplicationDirectory, + Q3DStudio::IWindowSystem &inWindowSystem, + Q3DStudio::ITimeProvider &inTimeProvider); + }; + + class IQt3DSRenderFactory : public Q3DStudio::IRuntimeFactory + { + public: + virtual Q3DStudio::ITegraApplicationRenderEngine &CreateRenderEngine() = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h new file mode 100644 index 00000000..3ffe15ce --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_RUNTIME_BINDING_IMPL_H +#define QT3DS_RENDER_RUNTIME_BINDING_IMPL_H + +#include "Qt3DSRenderRuntimeBinding.h" +#include "foundation/TrackingAllocator.h" +#include "foundation/Utils.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSRender.h" +#include "Qt3DSRenderContextCore.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSIPresentation.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderPresentation.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderModel.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderImage.h" +#include "Qt3DSUIPParser.h" +#include "Qt3DSRenderEffect.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderEffectSystem.h" +#include "foundation/Qt3DSInvasiveSet.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderText.h" +#include "foundation/StrConvertUTF.h" +#include "Qt3DSMetadata.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSWindowSystem.h" +#include "Qt3DSRenderPluginGraphObject.h" +#include "Qt3DSRenderReferencedMaterial.h" +#include "Qt3DSRenderText.h" +#include "foundation/Qt3DSMutex.h" + +#ifdef EA_PLATFORM_WINDOWS +#pragma warning(disable : 4355) +#else +#define stricmp strcasecmp +#endif + +using namespace qt3ds::render; +using eastl::make_pair; +using eastl::pair; + +namespace qt3ds { +namespace render { + + extern qt3ds::foundation::MallocAllocator g_BaseAllocator; + // Small core object shared between the larger objects. + // creates the object stack needed by the rest of the system. + struct SBindingCore : public NVRefCounted + { + qt3ds::render::CAllocator m_Allocator; + QT3DSU8 *m_FlowData; + NVScopedRefCounted m_Foundation; + NVScopedRefCounted m_StringTable; + NVScopedRefCounted m_CoreContext; + NVScopedRefCounted m_RenderContext; + NVScopedRefCounted m_Context; + QSize m_WindowDimensions; + eastl::string m_PrimitivePath; + bool m_RenderRotationsEnabled; + bool m_WriteOutShaderCache; + volatile QT3DSI32 mRefCount; + Q3DStudio::IWindowSystem &m_WindowSystem; + Q3DStudio::ITimeProvider &m_TimeProvider; + + SBindingCore(const char8_t *inPrimitivePath, Q3DStudio::IWindowSystem &inWindowSystem, + Q3DStudio::ITimeProvider &inTimeProvider) + : m_Allocator() + , m_FlowData(NULL) + , m_Foundation(NVCreateFoundation(QT3DS_FOUNDATION_VERSION, m_Allocator)) + , m_StringTable(IStringTable::CreateStringTable(m_Foundation->getAllocator())) + , m_CoreContext(IQt3DSRenderContextCore::Create(*m_Foundation, *m_StringTable)) + , m_PrimitivePath(inPrimitivePath) + , m_RenderRotationsEnabled(false) + , m_WriteOutShaderCache(false) + , mRefCount(0) + , m_WindowSystem(inWindowSystem) + , m_TimeProvider(inTimeProvider) + { + m_CoreContext->SetTextRendererCore( + ITextRendererCore::CreateQtTextRenderer(*m_Foundation, *m_StringTable)); + + m_CoreContext->SetOnscreenTextRendererCore( + ITextRendererCore::CreateOnscreenTextRenderer(*m_Foundation)); + } + virtual ~SBindingCore() + { + m_CoreContext = NULL; + m_Context = NULL; + m_RenderContext = NULL; + if (m_FlowData) + m_Allocator.deallocate(m_FlowData); + m_FlowData = NULL; + } + + void CreateRenderContext(qt3ds::render::IRuntimeFactoryRenderFactory &inContextFactory) + { + m_RenderContext = inContextFactory.CreateRenderContext(*m_Foundation, *m_StringTable); + if (m_RenderContext) + m_Context = + m_CoreContext->CreateRenderContext(*m_RenderContext, m_PrimitivePath.c_str()); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_BaseAllocator) + + NVAllocatorCallback &GetAllocator() { return m_Allocator; } + + Q3DStudio::ITegraApplicationRenderEngine &CreateRenderer(); + }; + struct STranslatorContext + { + }; + + //////////////////////////////////////// + // Translators are the set of objects that translate + // changes in the elements to changes in the scene graph. + // TODO - get rid of the virtual functions and just do dispatch + // on the m_RenderObject.m_Type. + //////////////////////////////////////// + class Qt3DSTranslator + { + public: + QT3DSU32 m_DirtyIndex; + Q3DStudio::TElement *m_Element; + SGraphObject *m_RenderObject; + STranslatorContext *m_TranslatorContext; + + Qt3DSTranslator(Q3DStudio::TElement &inElement, SGraphObject &inRenderObject); + GraphObjectTypes::Enum GetUIPType() const { return m_RenderObject->m_Type; } + Q3DStudio::TElement &Element() { return *m_Element; } + SGraphObject &RenderObject() { return *m_RenderObject; } + + // This function is done via a dispatch mechanism on the graph object type. + void OnElementChanged(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &inStudioPresentation); + + void Save(SWriteBuffer &inWriteBuffer, QT3DSU32 inGraphObjectOffset); + // Most translators don't need an extra allocation but effects due because the mapping from + // effect property + // to runtime property is too complex to do quickly. + static Qt3DSTranslator *LoadTranslator(SDataReader &inReader, size_t inElemOffset, + NVDataRef inSGSection, + NVAllocatorCallback &inAllocator); + + static Qt3DSTranslator *GetTranslatorFromGraphNode(SGraphObject &inObject); + static Qt3DSTranslator *CreateTranslatorForElement(Q3DStudio::TElement &inElement, + SGraphObject &inGraphObject, + NVAllocatorCallback &inAlloc); + static Q3DStudio::IPresentation * + GetPresentationFromPresentation(SPresentation &inPresentation); + static void InitializePointerTags(IStringTable &inTable); + static void AssignUserData(Q3DStudio::IPresentation &inPresentation, + SPresentation &inGraphPresentation); + }; + + struct STranslatorGetOp + { + QT3DSU32 operator()(const Qt3DSTranslator &translator) { return translator.m_DirtyIndex; } + }; + struct STranslatorSetOp + { + void operator()(Qt3DSTranslator &translator, QT3DSU32 value) + { + translator.m_DirtyIndex = value; + } + }; + + typedef InvasiveSet TTranslatorDirytSet; +} +} + +#endif diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp new file mode 100644 index 00000000..eff57579 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "EnginePrefix.h" +#include "Qt3DSRenderRuntimeBindingImpl.h" +#include "Qt3DSTegraApplication.h" +#include "Qt3DSWindowSystem.h" +#include "Qt3DSRenderLoadedTexture.h" + +struct SRenderer; +struct SRendererRSM : public Q3DStudio::ITegraRenderStateManager +{ + SRenderer &m_Renderer; + +public: + SRendererRSM(SRenderer &renderer) + : m_Renderer(renderer) + { + } + + void SetViewport(Q3DStudio::INT32 inX, Q3DStudio::INT32 inY, Q3DStudio::INT32 inWidth, + Q3DStudio::INT32 inHeight) override; + void PushState() override; + void PopState() override; + void SetScissorTestEnabled(bool inValue) override; + void SaveAllState() override; + void RestoreAllState() override; +}; + +struct SRenderer : public Q3DStudio::ITegraApplicationRenderEngine +{ + NVScopedRefCounted m_BindingCore; + NVScopedRefCounted m_Context; + NVRenderRect m_Viewport; + nvvector m_StateStack; + QSize m_PresentationDimensions; + SRendererRSM m_RSM; + Q3DStudio::IWindowSystem &m_WindowSystem; + + SRenderer(SBindingCore &inCore, Q3DStudio::IWindowSystem &inWindowSystem) + : m_BindingCore(inCore) + , m_Context(*inCore.m_Context) + , m_StateStack(inCore.m_Context->GetAllocator(), "SRenderer::m_StateStack") + , m_RSM(*this) + , m_WindowSystem(inWindowSystem) + { + m_Context->SetSceneColor(QT3DSVec4(0, 0, 0, 0.0f)); + if (m_BindingCore->m_RenderContext) { + m_BindingCore->m_RenderContext->SetDefaultRenderTarget( + m_WindowSystem.GetDefaultRenderTargetID()); + m_BindingCore->m_RenderContext->SetDefaultDepthBufferBitCount( + m_WindowSystem.GetDepthBitCount()); + } + } + + void ensureRenderTarget() override + { + m_BindingCore->m_RenderContext->SetDefaultRenderTarget( + m_WindowSystem.GetDefaultRenderTargetID()); + } + + void CheckResize(bool, Q3DStudio::IPresentation & /*inPresentation*/) override + { + QSize theWindowDims(m_WindowSystem.GetWindowDimensions()); + m_BindingCore->m_WindowDimensions = theWindowDims; + m_BindingCore->m_Context->SetWindowDimensions(m_BindingCore->m_WindowDimensions); + } + Q3DStudio::BOOL LoadShaderCache(const char * /*inFilePath*/) override { return true; } + + void AbandonLoadingImages(Q3DStudio::IScene & /*inScene*/) override {} + + Q3DStudio::BOOL IsPickValid(Q3DStudio::FLOAT &outX, Q3DStudio::FLOAT &outY, + const Q3DStudio::IPresentation & /*inPresentation*/) const override + { + Q3DStudio::FLOAT theX = outX; + Q3DStudio::FLOAT theY = outY; + theX = theX / static_cast(m_BindingCore->m_WindowDimensions.width()); + theY = theY / static_cast(m_BindingCore->m_WindowDimensions.height()); + Q3DStudio::BOOL theValid = false; + + if ((theX >= 0.0f) && (theY >= 0.0f) && (theX <= 1.0f) && (theY <= 1.0f)) + theValid = true; + return theValid; + } + + void SetScaleMode(Q3DStudio::TegraRenderScaleModes::Enum inScale) override + { + if (m_BindingCore && m_BindingCore->m_Context) + m_BindingCore->m_Context->SetScaleMode(static_cast(inScale)); + } + Q3DStudio::TegraRenderScaleModes::Enum GetScaleMode() const override + { + if (m_BindingCore && m_BindingCore->m_Context) + return static_cast( + const_cast(*this).m_BindingCore->m_Context->GetScaleMode()); + + QT3DS_ASSERT(false); + return Q3DStudio::TegraRenderScaleModes::ExactSize; + } + + void SetShadeMode(Q3DStudio::TegraRenderShadeModes::Enum inShade) override + { + if (m_BindingCore && m_BindingCore->m_Context) { + m_BindingCore->m_Context->SetWireframeMode( + (inShade == Q3DStudio::TegraRenderShadeModes::Shaded) ? false : true); + } + } + + void EnableRenderRotation(bool inEnable) override + { + m_BindingCore->m_RenderRotationsEnabled = inEnable; + } + + void SetWriteOutShaderCache(bool inWriteOutShaderCache) override + { + m_BindingCore->m_WriteOutShaderCache = inWriteOutShaderCache; + } + + Q3DStudio::ITegraRenderStateManager &GetTegraRenderStateManager() override { return m_RSM; } + qt3ds::render::NVRenderContext &GetRenderContext() override + { + return *m_BindingCore->m_RenderContext; + } + + void Release() override + { + // Ensure the core doesn't die until after we do. + NVScopedRefCounted theContext(m_BindingCore); + NVDelete(m_Context->GetAllocator(), this); + } + + void SetViewport(Q3DStudio::INT32 inX, Q3DStudio::INT32 inY, Q3DStudio::INT32 inWidth, + Q3DStudio::INT32 inHeight) override + { + m_Viewport = NVRenderRect(inX, inY, inWidth, inHeight); + m_BindingCore->m_RenderContext->SetViewport(m_Viewport); + } + void SetApplicationViewport(const qt3ds::render::NVRenderRect &inViewport) override + { + m_BindingCore->m_Context->SetViewport(inViewport); + } + + void SetMatteColor(Option inColor) override { m_Context->SetMatteColor(inColor); } + virtual void PushState() { m_StateStack.push_back(m_Viewport); } + virtual void PopState() + { + m_Viewport = m_StateStack.back(); + m_StateStack.pop_back(); + SetViewport(m_Viewport.m_X, m_Viewport.m_Y, m_Viewport.m_Width, m_Viewport.m_Height); + } + + void RenderText2D(Q3DStudio::FLOAT x, Q3DStudio::FLOAT y, + qt3ds::foundation::Option inColor, const char *text) override + { + m_Context->RenderText2D(x, y, inColor, text); + } + + void RenderGpuProfilerStats(Q3DStudio::FLOAT x, Q3DStudio::FLOAT y, + qt3ds::foundation::Option inColor) override + { + m_Context->RenderGpuProfilerStats(x, y, inColor); + } +}; + +void SRendererRSM::SetViewport(Q3DStudio::INT32 inX, Q3DStudio::INT32 inY, Q3DStudio::INT32 inWidth, + Q3DStudio::INT32 inHeight) +{ + m_Renderer.SetViewport(inX, inY, inWidth, inHeight); +} +void SRendererRSM::PushState() +{ + m_Renderer.PushState(); +} +void SRendererRSM::PopState() +{ + m_Renderer.PopState(); +} +void SRendererRSM::SetScissorTestEnabled(bool inValue) +{ + m_Renderer.m_BindingCore->m_RenderContext->SetScissorTestEnabled(inValue); +} +void SRendererRSM::SaveAllState() +{ + m_Renderer.m_BindingCore->m_RenderContext->PushPropertySet(); +} +void SRendererRSM::RestoreAllState() +{ + m_Renderer.m_BindingCore->m_RenderContext->PopPropertySet(true); +} + +Q3DStudio::ITegraApplicationRenderEngine &SBindingCore::CreateRenderer() +{ + SRenderer *retval = NULL; + if (m_Context) + retval = QT3DS_NEW(m_Context->GetAllocator(), SRenderer)(*this, this->m_WindowSystem); + + return *retval; +} diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp new file mode 100644 index 00000000..daf6c0f1 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp @@ -0,0 +1,1811 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "EnginePrefix.h" +#include "Qt3DSRenderRuntimeBindingImpl.h" +#include "Qt3DSRenderUIPSharedTranslation.h" +#include "Qt3DSRenderBufferManager.h" +#include "foundation/SerializationTypes.h" +#include "Qt3DSRenderString.h" +#include "foundation/FileTools.h" +#include "Qt3DSHash.h" +#include "Qt3DSRenderPlugin.h" +#include "Qt3DSRenderPluginPropertyValue.h" +#include "Qt3DSElementHelper.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSApplication.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderPathSubPath.h" +#include "Qt3DSRenderPathManager.h" + +namespace Q3DStudio { +enum ExtendedAttributes { + ATTRIBUTE_NONE = 0, + ATTRIBUTE_NONE_R, + ATTRIBUTE_NONE_G, + ATTRIBUTE_NONE_B +}; +} + +namespace { +QT3DSU32 g_TranslatorTag; +QT3DSU32 g_PresentationTag; +} + +// Add specializations for the tagged pointer operations to make casting +// a bit safer and more transparent. +namespace qt3ds { +namespace render { + template <> + struct SPointerTag + { + static QT3DSU32 GetTag() { return g_TranslatorTag; } + }; + template <> + struct SPointerTag + { + static QT3DSU32 GetTag() { return g_PresentationTag; } + }; +} +} + +namespace { + +template +struct SDirtySetter +{ +}; + +template <> +struct SDirtySetter +{ + static void Set(bool &dirty, bool & /*transformDirty*/, bool & /*textDirty*/) { dirty = true; } +}; +template <> +struct SDirtySetter +{ + static void Set(bool &dirty, bool &transformDirty, bool & /*textDirty*/) + { + dirty = true; + transformDirty = true; + } +}; +template <> +struct SDirtySetter +{ + static void Set(bool &dirty, bool & /*transformDirty*/, bool &textDirty) + { + dirty = true; + textDirty = true; + } +}; +template <> +struct SDirtySetter +{ + static void Set(bool & /*dirty*/, bool & /*transformDirty*/, bool & /*textDirty*/) {} +}; + +// Translates individual property values from the runtime into the rendering system. +struct SRuntimePropertyParser +{ + QT3DSI32 m_PropertyName; + Q3DStudio::UVariant m_Value; + Q3DStudio::EAttributeType m_Type; + Q3DStudio::TElement &m_Element; + SPresentation &m_Presentation; + IQt3DSRenderContext &m_RenderContext; + bool m_Dirty; + bool m_TransformDirty; + bool m_TextDirty; + + SRuntimePropertyParser(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, + Q3DStudio::TElement &inElement) + : m_PropertyName(0) + , m_Type((Q3DStudio::EAttributeType)0) + , m_Element(inElement) + , m_Presentation(inPresentation) + , m_RenderContext(inRenderContext) + , m_Dirty(false) + , m_TransformDirty(false) + , m_TextDirty(false) + { + } + + void Setup(QT3DSI32 inPropName, Q3DStudio::UVariant inValue, Q3DStudio::EAttributeType inType) + { + m_PropertyName = inPropName; + m_Value = inValue; + m_Type = inType; + } + template + void SetDirty() + { + SDirtySetter::Set(m_Dirty, m_TransformDirty, m_TextDirty); + } + template + bool ParseProperty(QT3DSF32 &outValue) + { + if (m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT) { + QT3DSF32 newValue = m_Value.m_FLOAT; + if (outValue != newValue) { + outValue = newValue; + SetDirty(); + return true; + } + } else { + QT3DS_ASSERT(false); + } + return false; + }; + template + bool ParseProperty(QT3DSU32 &outValue) + { + if (m_Type == Q3DStudio::ATTRIBUTETYPE_INT32) { + QT3DSU32 newValue = (QT3DSU32)m_Value.m_INT32; + if (outValue != newValue) { + outValue = newValue; + SetDirty(); + return true; + } + } else { + QT3DS_ASSERT(false); + } + return false; + }; + template + bool ParseProperty(SGraphObject *&outValue) + { + Q3DStudio::TElement *theElem = NULL; + if (m_Type == Q3DStudio::ATTRIBUTETYPE_ELEMENTREF) { + theElem = m_Element.GetBelongedPresentation()->GetApplication().GetElementByHandle( + m_Value.m_ElementHandle); + } else if (m_Type == Q3DStudio::ATTRIBUTETYPE_STRING) { + CRegisteredString theString = + m_RenderContext.GetStringTable().HandleToStr(m_Value.m_StringHandle); + theElem = Q3DStudio::CElementHelper::GetElement( + m_Element.GetBelongedPresentation()->GetApplication(), + m_Element.GetBelongedPresentation(), theString.c_str(), &m_Element); + } + + SGraphObject *newValue = NULL; + if (theElem) { + Qt3DSTranslator *theTranslator = + reinterpret_cast(theElem->GetAssociation()); + if (theTranslator) + newValue = theTranslator->m_RenderObject; + } + if (outValue != newValue) { + outValue = newValue; + SetDirty(); + return true; + } + return false; + }; + template + bool ParseRadianProperty(QT3DSF32 &outValue) + { + if (ParseProperty(outValue)) { + TORAD(outValue); + return true; + } + return false; + } + template + bool ParseOpacityProperty(QT3DSF32 &outValue) + { + if (ParseProperty(outValue)) { + outValue *= 1.0f / 100.0f; + return true; + } + return false; + } + + template + bool ParseOrientationProperty(bool &ioCurrent) + { + if (m_Type == Q3DStudio::ATTRIBUTETYPE_STRING) { + CRegisteredString strValue = + m_RenderContext.GetStringTable().HandleToStr(m_Value.m_StringHandle); + bool newValue = AreEqual(strValue.c_str(), "Left Handed") ? true : false; + if (ioCurrent != newValue) { + ioCurrent = newValue; + SetDirty(); + return true; + } + } else { + QT3DS_ASSERT(false); + } + return false; + } + + template + bool ParseProperty(bool &ioCurrent) + { + if (m_Type == Q3DStudio::ATTRIBUTETYPE_BOOL || m_Type == Q3DStudio::ATTRIBUTETYPE_INT32) { + bool newValue = m_Value.m_INT32 ? true : false; + if (ioCurrent != newValue) { + ioCurrent = newValue; + SetDirty(); + return true; + } + } else { + QT3DS_ASSERT(false); + } + return false; + } + template + bool ParseInverseBoolean(bool &ioCurrent) + { + bool temp = !ioCurrent; + if (ParseProperty(temp)) { + ioCurrent = temp; + return true; + } + return false; + } + template + bool ParseProperty(QT3DSVec3 &outValue) + { + if (m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT3) { + QT3DSVec3 newValue(m_Value.m_FLOAT3[0], m_Value.m_FLOAT3[1], m_Value.m_FLOAT3[2]); + if (outValue != newValue) { + outValue = newValue; + SetDirty(); + return true; + } + } else { + QT3DS_ASSERT(false); + } + return false; + } + + template + bool ParseProperty(CRegisteredString &outValue) + { + if (m_Type == Q3DStudio::ATTRIBUTETYPE_STRING) { + CRegisteredString newValue = + m_RenderContext.GetStringTable().HandleToStr(m_Value.m_StringHandle); + if (newValue.c_str() != outValue.c_str()) { + outValue = newValue; + SetDirty(); + return true; + } + } else { + QT3DS_ASSERT(false); + } + return false; + } + + template + bool ParseRotationOrder(QT3DSU32 &outValue) + { + CRegisteredString theString; + ParseProperty(theString); + if (theString.IsValid()) { + QT3DSU32 newRotationOrder = MapRotationOrder(theString); + if (newRotationOrder != outValue) { + outValue = newRotationOrder; + SetDirty(); + return true; + } + } + return false; + } + + template + bool ParseOrientation(NodeFlags &outValue) + { + bool temp = false; + ParseOrientationProperty(temp); + bool wasLeftHanded = outValue.IsLeftHanded(); + if (wasLeftHanded != temp) { + outValue.SetLeftHanded(temp); + SetDirty(); + return true; + } + return false; + } + template + bool ParseNodeFlagsProperty(NodeFlags &outValue, NodeFlagValues::Enum inFlag) + { + bool temp = false; + ParseProperty(temp); + bool wasSet = outValue & inFlag; + if (temp != wasSet) { + outValue.ClearOrSet(temp, inFlag); + SetDirty(); + return true; + } + return false; + } + + template + bool ParseNodeFlagsInverseProperty(NodeFlags &outValue, NodeFlagValues::Enum inFlag) + { + bool temp = false; + ParseProperty(temp); + temp = !temp; + bool wasSet = outValue & inFlag; + if (temp != wasSet) { + outValue.ClearOrSet(temp, inFlag); + SetDirty(); + return true; + } + return false; + } + + template + bool ParseEnumProperty(TEnumType &outValue) + { + CRegisteredString theString; + ParseProperty(theString); + if (theString.IsValid()) { + SEnumNameMap *theMap = SEnumParseMap::GetMap(); + for (SEnumNameMap *theItem = theMap; theItem->m_Name && *theItem->m_Name; ++theItem) { + // hack to match advanced overlay types, whose name start with a '*' + const char8_t *p = theString.c_str(); + if (*p == '*') + ++p; + if (strcmp(p, theItem->m_Name) == 0) { + TEnumType theNewValue = static_cast(theItem->m_Enum); + if (outValue != theNewValue) { + outValue = theNewValue; + SetDirty(); + return true; + } + } + } + } + return false; + } + template + bool ParseAndResolveSourcePath(CRegisteredString &outValue) + { + CRegisteredString theTemp; + ParseProperty(theTemp); + CRegisteredString theNewStr = theTemp; + if (outValue.c_str() != theNewStr.c_str()) { + SetDirty(); + outValue = theNewStr; + return true; + } + return false; + } + + template + bool ParseProperty(SImage *&ioImagePtr) + { + Q3DStudio::TElement *theElem = + m_Element.GetBelongedPresentation()->GetApplication().GetElementByHandle( + m_Value.m_ElementHandle); + // Try to be very careful in here as casting things around like crazy is a sure + // way to crash the runtime at a bad point. + if (theElem != NULL) { + Qt3DSTranslator *theTranslator = + reinterpret_cast(theElem->GetAssociation()); + if (theTranslator != NULL && theTranslator->GetUIPType() == GraphObjectTypes::Image) { + SImage *theImage = static_cast(theTranslator->m_RenderObject); + if (ioImagePtr != theImage) { + ioImagePtr = theImage; + SetDirty(); + return true; + } + } + } + return false; + } + + template + bool ParseProperty(SNode *&ioNodePtr) + { + Q3DStudio::TElement *theElem = + m_Element.GetBelongedPresentation()->GetApplication().GetElementByHandle( + m_Value.m_ElementHandle); + // Try to be very careful in here as casting things around like crazy is a sure + // way to crash the runtime at a bad point. + SNode *theNode = NULL; + if (theElem != NULL + && theElem->GetBelongedPresentation() == m_Element.GetBelongedPresentation()) { + Qt3DSTranslator *theTranslator = + reinterpret_cast(theElem->GetAssociation()); + if (theTranslator != NULL + && GraphObjectTypes::IsNodeType(theTranslator->GetUIPType())) { + theNode = static_cast(theTranslator->m_RenderObject); + } + } + if (ioNodePtr != theNode) { + ioNodePtr = theNode; + SetDirty(); + return true; + } + return false; + } +}; + +// Fill out parse name table. +#define Scene_ClearColor_R ATTRIBUTE_BACKGROUNDCOLOR_R +#define Scene_ClearColor_G ATTRIBUTE_BACKGROUNDCOLOR_G +#define Scene_ClearColor_B ATTRIBUTE_BACKGROUNDCOLOR_B +#define Scene_UseClearColor ATTRIBUTE_BGCOLORENABLE +#define Node_Rotation ATTRIBUTE_ROTATION +#define Node_Rotation_X ATTRIBUTE_ROTATION_X +#define Node_Rotation_Y ATTRIBUTE_ROTATION_Y +#define Node_Rotation_Z ATTRIBUTE_ROTATION_Z +#define Node_Position ATTRIBUTE_POSITION +#define Node_Position_X ATTRIBUTE_POSITION_X +#define Node_Position_Y ATTRIBUTE_POSITION_Y +#define Node_Position_Z ATTRIBUTE_POSITION_Z +#define Node_Scale ATTRIBUTE_SCALE +#define Node_Scale_X ATTRIBUTE_SCALE_X +#define Node_Scale_Y ATTRIBUTE_SCALE_Y +#define Node_Scale_Z ATTRIBUTE_SCALE_Z +#define Node_Pivot ATTRIBUTE_PIVOT +#define Node_Pivot_X ATTRIBUTE_PIVOT_X +#define Node_Pivot_Y ATTRIBUTE_PIVOT_Y +#define Node_Pivot_Z ATTRIBUTE_PIVOT_Z +#define Node_LocalOpacity ATTRIBUTE_OPACITY +#define Node_RotationOrder ATTRIBUTE_ROTATIONORDER +#define Node_LeftHanded ATTRIBUTE_ORIENTATION +#define Layer_TemporalAAEnabled ATTRIBUTE_TEMPORALAA +#define Layer_LayerEnableDepthTest ATTRIBUTE_DISABLEDEPTHTEST +#define Layer_LayerEnableDepthPrePass ATTRIBUTE_DISABLEDEPTHPREPASS +#define Layer_ClearColor_R ATTRIBUTE_BACKGROUNDCOLOR_R +#define Layer_ClearColor_G ATTRIBUTE_BACKGROUNDCOLOR_G +#define Layer_ClearColor_B ATTRIBUTE_BACKGROUNDCOLOR_B +#define Layer_Background ATTRIBUTE_BACKGROUND +#define Layer_BlendType ATTRIBUTE_BLENDTYPE +#define Layer_ProgressiveAAMode ATTRIBUTE_PROGRESSIVEAA +#define Layer_MultisampleAAMode ATTRIBUTE_MULTISAMPLEAA +#define Layer_HorizontalFieldValues ATTRIBUTE_HORZFIELDS +#define Layer_Left ATTRIBUTE_LEFT +#define Layer_LeftUnits ATTRIBUTE_LEFTUNITS +#define Layer_Width ATTRIBUTE_WIDTH +#define Layer_WidthUnits ATTRIBUTE_WIDTHUNITS +#define Layer_Right ATTRIBUTE_RIGHT +#define Layer_RightUnits ATTRIBUTE_RIGHTUNITS +#define Layer_VerticalFieldValues ATTRIBUTE_VERTFIELDS +#define Layer_Top ATTRIBUTE_TOP +#define Layer_TopUnits ATTRIBUTE_TOPUNITS +#define Layer_Height ATTRIBUTE_HEIGHT +#define Layer_HeightUnits ATTRIBUTE_HEIGHTUNITS +#define Layer_Bottom ATTRIBUTE_BOTTOM +#define Layer_BottomUnits ATTRIBUTE_BOTTOMUNITS +#define Layer_AoStrength ATTRIBUTE_AOSTRENGTH +#define Layer_AoDistance ATTRIBUTE_AODISTANCE +#define Layer_AoSoftness ATTRIBUTE_AOSOFTNESS +#define Layer_AoBias ATTRIBUTE_AOBIAS +#define Layer_AoSamplerate ATTRIBUTE_AOSAMPLERATE +#define Layer_AoDither ATTRIBUTE_AODITHER +#define Layer_ShadowStrength ATTRIBUTE_SHADOWSTRENGTH +#define Layer_ShadowDist ATTRIBUTE_SHADOWDIST +#define Layer_ShadowSoftness ATTRIBUTE_SHADOWSOFTNESS +#define Layer_ShadowBias ATTRIBUTE_SHADOWBIAS +#define Layer_LightProbe ATTRIBUTE_LIGHTPROBE +#define Layer_ProbeBright ATTRIBUTE_PROBEBRIGHT +#define Layer_FastIbl ATTRIBUTE_FASTIBL +#define Layer_ProbeTheta ATTRIBUTE_PROBETHETA +#define Layer_ProbePhi ATTRIBUTE_PROBEPHI +#define Layer_ProbeHorizon ATTRIBUTE_PROBEHORIZON +#define Layer_LightProbe2 ATTRIBUTE_LIGHTPROBE2 +#define Layer_Probe2Fade ATTRIBUTE_PROBE2FADE +#define Layer_Probe2Window ATTRIBUTE_PROBE2WINDOW +#define Layer_Probe2Pos ATTRIBUTE_PROBE2POS +#define Layer_ProbeFov ATTRIBUTE_PROBEFOV +#define Layer_TexturePath ATTRIBUTE_SOURCEPATH +#define Camera_ClipNear ATTRIBUTE_CLIPNEAR +#define Camera_ClipFar ATTRIBUTE_CLIPFAR +#define Camera_FOV ATTRIBUTE_FOV +#define Camera_FOVHorizontal ATTRIBUTE_FOVHORIZONTAL +#define Camera_Orthographic ATTRIBUTE_ORTHOGRAPHIC +#define Camera_ScaleMode ATTRIBUTE_SCALEMODE +#define Camera_ScaleAnchor ATTRIBUTE_SCALEANCHOR +#define Light_ImageSource ATTRIBUTE_IMAGESOURCE +#define Light_Scope ATTRIBUTE_SCOPE +#define Light_ImageSetsColor ATTRIBUTE_IMAGESETSCOLOR +#define Light_ImageSetsRotation ATTRIBUTE_IMAGESETSROTATION +#define Light_ImageHFov ATTRIBUTE_IMAGEHFOV +#define Light_ImageIsFisheye ATTRIBUTE_IMAGEISFISHEYE +#define Light_LightType ATTRIBUTE_LIGHTTYPE +#define Light_DiffuseColor ATTRIBUTE_LIGHTDIFFUSE +#define Light_DiffuseColor_R ATTRIBUTE_LIGHTDIFFUSE_R +#define Light_DiffuseColor_G ATTRIBUTE_LIGHTDIFFUSE_G +#define Light_DiffuseColor_B ATTRIBUTE_LIGHTDIFFUSE_B +#define Light_SpecularColor ATTRIBUTE_LIGHTSPECULAR +#define Light_SpecularColor_R ATTRIBUTE_LIGHTSPECULAR_R +#define Light_SpecularColor_G ATTRIBUTE_LIGHTSPECULAR_G +#define Light_SpecularColor_B ATTRIBUTE_LIGHTSPECULAR_B +#define Light_AmbientColor ATTRIBUTE_LIGHTAMBIENT +#define Light_AmbientColor_R ATTRIBUTE_LIGHTAMBIENT_R +#define Light_AmbientColor_G ATTRIBUTE_LIGHTAMBIENT_G +#define Light_AmbientColor_B ATTRIBUTE_LIGHTAMBIENT_B +#define Light_Brightness ATTRIBUTE_BRIGHTNESS +#define Light_LinearFade ATTRIBUTE_LINEARFADE +#define Light_ExponentialFade ATTRIBUTE_EXPFADE +#define Light_AreaWidth ATTRIBUTE_AREAWIDTH +#define Light_AreaHeight ATTRIBUTE_AREAHEIGHT +#define Light_CastShadow ATTRIBUTE_CASTSHADOW +#define Light_ShadowBias ATTRIBUTE_SHDWBIAS +#define Light_ShadowFactor ATTRIBUTE_SHDWFACTOR +#define Light_ShadowMapRes ATTRIBUTE_SHDWMAPRES +#define Light_ShadowMapFar ATTRIBUTE_SHDWMAPFAR +#define Light_ShadowMapFov ATTRIBUTE_SHDWMAPFOV +#define Light_ShadowFilter ATTRIBUTE_SHDWFILTER +#define Model_MeshPath ATTRIBUTE_SOURCEPATH +#define Model_ShadowCaster ATTRIBUTE_SHADOWCASTER +#define Model_TessellationMode ATTRIBUTE_TESSELLATION +#define Model_EdgeTess ATTRIBUTE_EDGETESS +#define Model_InnerTess ATTRIBUTE_INNERTESS +#define Lightmaps_LightmapIndirect ATTRIBUTE_LIGHTMAPINDIRECT +#define Lightmaps_LightmapRadiosity ATTRIBUTE_LIGHTMAPRADIOSITY +#define Lightmaps_LightmapShadow ATTRIBUTE_LIGHTMAPSHADOW +#define Material_Lighting ATTRIBUTE_SHADERLIGHTING +#define Material_BlendMode ATTRIBUTE_BLENDMODE +#define MaterialBase_IblProbe ATTRIBUTE_IBLPROBE +#define Material_DiffuseColor ATTRIBUTE_DIFFUSE +#define Material_DiffuseColor_R ATTRIBUTE_DIFFUSE_R +#define Material_DiffuseColor_G ATTRIBUTE_DIFFUSE_G +#define Material_DiffuseColor_B ATTRIBUTE_DIFFUSE_B +#define Material_DiffuseMaps_0 ATTRIBUTE_DIFFUSEMAP +#define Material_DiffuseMaps_1 ATTRIBUTE_DIFFUSEMAP2 +#define Material_DiffuseMaps_2 ATTRIBUTE_DIFFUSEMAP3 +#define Material_EmissivePower ATTRIBUTE_EMISSIVEPOWER +#define Material_EmissiveColor ATTRIBUTE_EMISSIVECOLOR +#define Material_EmissiveColor_R ATTRIBUTE_EMISSIVECOLOR_R +#define Material_EmissiveColor_G ATTRIBUTE_EMISSIVECOLOR_G +#define Material_EmissiveColor_B ATTRIBUTE_EMISSIVECOLOR_B +#define Material_EmissiveMap ATTRIBUTE_EMISSIVEMAP +#define Material_EmissiveMap2 ATTRIBUTE_EMISSIVEMAP2 +#define Material_SpecularReflection ATTRIBUTE_SPECULARREFLECTION +#define Material_SpecularMap ATTRIBUTE_SPECULARMAP +#define Material_SpecularModel ATTRIBUTE_SPECULARMODEL +#define Material_SpecularTint ATTRIBUTE_SPECULARTINT +#define Material_SpecularTint_R ATTRIBUTE_SPECULARTINT_R +#define Material_SpecularTint_G ATTRIBUTE_SPECULARTINT_G +#define Material_SpecularTint_B ATTRIBUTE_SPECULARTINT_B +#define Material_IOR ATTRIBUTE_IOR +#define Material_FresnelPower ATTRIBUTE_FRESNELPOWER +#define Material_SpecularAmount ATTRIBUTE_SPECULARAMOUNT +#define Material_SpecularRoughness ATTRIBUTE_SPECULARROUGHNESS +#define Material_RoughnessMap ATTRIBUTE_ROUGHNESSMAP +#define Material_Opacity ATTRIBUTE_OPACITY +#define Material_OpacityMap ATTRIBUTE_OPACITYMAP +#define Material_BumpAmount ATTRIBUTE_BUMPAMOUNT +#define Material_BumpMap ATTRIBUTE_BUMPMAP +#define Material_NormalMap ATTRIBUTE_NORMALMAP +#define Material_DisplaceAmount ATTRIBUTE_DISPLACEAMOUNT +#define Material_DisplacementMap ATTRIBUTE_DISPLACEMENTMAP +#define Material_TranslucentFalloff ATTRIBUTE_TRANSLUCENTFALLOFF +#define Material_TranslucencyMap ATTRIBUTE_TRANSLUCENCYMAP +#define Material_DiffuseLightWrap ATTRIBUTE_DIFFUSELIGHTWRAP +#define Material_ReferencedMaterial ATTRIBUTE_REFERENCEDMATERIAL +#define Material_VertexColors ATTRIBUTE_VERTEXCOLORS +#define Image_ImagePath ATTRIBUTE_SOURCEPATH +#define Image_OffscreenRendererId ATTRIBUTE_SUBPRESENTATION +#define Image_Scale_X ATTRIBUTE_SCALEU +#define Image_Scale_Y ATTRIBUTE_SCALEV +#define Image_Pivot_X ATTRIBUTE_PIVOTU +#define Image_Pivot_Y ATTRIBUTE_PIVOTV +#define Image_Rotation ATTRIBUTE_ROTATIONUV +#define Image_Position_X ATTRIBUTE_POSITIONU +#define Image_Position_Y ATTRIBUTE_POSITIONV +#define Image_MappingMode ATTRIBUTE_MAPPINGMODE +#define Image_HorizontalTilingMode ATTRIBUTE_TILINGMODEHORZ +#define Image_VerticalTilingMode ATTRIBUTE_TILINGMODEVERT +#define Text_Text ATTRIBUTE_TEXTSTRING +#define Text_Font ATTRIBUTE_FONT +#define Text_FontSize ATTRIBUTE_SIZE +#define Text_HorizontalAlignment ATTRIBUTE_HORZALIGN +#define Text_VerticalAlignment ATTRIBUTE_VERTALIGN +#define Text_Leading ATTRIBUTE_LEADING +#define Text_Tracking ATTRIBUTE_TRACKING +#define Text_DropShadow ATTRIBUTE_DROPSHADOW +#define Text_DropShadowStrength ATTRIBUTE_DROPSHADOWSTRENGTH +#define Text_DropShadowOffset ATTRIBUTE_DROPSHADOWOFFSET +#define Text_DropShadowOffsetX ATTRIBUTE_DROPSHADOWOFFSETX +#define Text_DropShadowOffsetY ATTRIBUTE_DROPSHADOWOFFSETY +#define Text_DropShadowHorizontalAlignment ATTRIBUTE_DROPSHADOWHORZALIGN +#define Text_DropShadowVerticalAlignment ATTRIBUTE_DROPSHADOWVERTALIGN +#define Text_WordWrap ATTRIBUTE_WORDWRAP +#define Text_BoundingBox ATTRIBUTE_BOUNDINGBOX +#define Text_BoundingBox_X ATTRIBUTE_BOUNDINGBOX_X +#define Text_BoundingBox_Y ATTRIBUTE_BOUNDINGBOX_Y +#define Text_Elide ATTRIBUTE_ELIDE +#define Text_TextColor ATTRIBUTE_TEXTCOLOR +#define Text_TextColor_R ATTRIBUTE_TEXTCOLOR_R +#define Text_TextColor_G ATTRIBUTE_TEXTCOLOR_G +#define Text_TextColor_B ATTRIBUTE_TEXTCOLOR_B +#define Text_BackColor_R ATTRIBUTE_BACKCOLOR_R +#define Text_BackColor_G ATTRIBUTE_BACKCOLOR_G +#define Text_BackColor_B ATTRIBUTE_BACKCOLOR_B +#define Text_UseBackColor ATTRIBUTE_USEBACKCOLOR +#define Text_EnableAcceleratedFont ATTRIBUTE_ENABLEACCELERATEDFONT +#define Path_PathType ATTRIBUTE_PATHTYPE +#define Path_Width ATTRIBUTE_WIDTH +#define Path_LinearError ATTRIBUTE_LINEARERROR +#define Path_EdgeTessAmount ATTRIBUTE_EDGETESSAMOUNT +#define Path_InnerTessAmount ATTRIBUTE_INNERTESSAMOUNT +#define Path_BeginCapping ATTRIBUTE_BEGINCAP +#define Path_BeginCapOffset ATTRIBUTE_BEGINCAPOFFSET +#define Path_BeginCapOpacity ATTRIBUTE_BEGINCAPOPACITY +#define Path_BeginCapWidth ATTRIBUTE_BEGINCAPWIDTH +#define Path_EndCapping ATTRIBUTE_ENDCAP +#define Path_EndCapOffset ATTRIBUTE_ENDCAPOFFSET +#define Path_EndCapOpacity ATTRIBUTE_ENDCAPOPACITY +#define Path_EndCapWidth ATTRIBUTE_ENDCAPWIDTH +#define Path_PaintStyle ATTRIBUTE_PAINTSTYLE +#define Path_PathBuffer ATTRIBUTE_SOURCEPATH +#define SubPath_Closed ATTRIBUTE_CLOSED + +// Fill in implementations for the actual parse tables. +#define HANDLE_QT3DS_RENDER_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseProperty(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_RENDER_VEC3_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name##_X: \ + inParser.ParseProperty(theItem.m_##name.x); \ + break; \ + case Q3DStudio::type##_##name##_Y: \ + inParser.ParseProperty(theItem.m_##name.y); \ + break; \ + case Q3DStudio::type##_##name##_Z: \ + inParser.ParseProperty(theItem.m_##name.z); \ + break; + +#define HANDLE_QT3DS_RENDER_REAL_VEC2_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name##_X: \ + inParser.ParseProperty(theItem.m_##name.x); \ + break; \ + case Q3DStudio::type##_##name##_Y: \ + inParser.ParseProperty(theItem.m_##name.y); \ + break; + +#define HANDLE_QT3DS_RENDER_COLOR_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name##_R: \ + inParser.ParseProperty(theItem.m_##name.x); \ + break; \ + case Q3DStudio::type##_##name##_G: \ + inParser.ParseProperty(theItem.m_##name.y); \ + break; \ + case Q3DStudio::type##_##name##_B: \ + inParser.ParseProperty(theItem.m_##name.z); \ + break; + +#define HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseProperty(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseProperty(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseRadianProperty(theItem.m_##name); \ + break; + +// The runtime converts rotations for us. +#define HANDLE_QT3DS_RENDER_VEC3_RADIAN_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name##_X: \ + inParser.ParseProperty(theItem.m_##name.x); \ + break; \ + case Q3DStudio::type##_##name##_Y: \ + inParser.ParseProperty(theItem.m_##name.y); \ + break; \ + case Q3DStudio::type##_##name##_Z: \ + inParser.ParseProperty(theItem.m_##name.z); \ + break; + +#define HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseOpacityProperty(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_ROTATION_ORDER_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseRotationOrder(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseOrientation(theItem.m_Flags); \ + break; + +#define HANDLE_QT3DS_RENDER_DEPTH_TEST_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseInverseBoolean(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_NODE_FLAGS_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseNodeFlagsProperty(theItem.m_Flags, \ + NodeFlagValues::name); \ + break; + +#define HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseNodeFlagsInverseProperty(theItem.m_Flags, \ + NodeFlagValues::name); \ + break; + +#define HANDLE_QT3DS_RENDER_ENUM_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseEnumProperty(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name: \ + inParser.ParseAndResolveSourcePath(theItem.m_##name); \ + break; + +#define HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(type, name, index, dirty) \ + case Q3DStudio::type##_##name##_##index: \ + inParser.ParseProperty(theItem.m_##name[index]); \ + break; + +#define HANDLE_QT3DS_RENDER_VEC2_PROPERTY(type, name, dirty) \ + case Q3DStudio::type##_##name##_X: \ + inParser.ParseProperty(theItem.m_##name.x); \ + break; \ + case Q3DStudio::type##_##name##_Y: \ + inParser.ParseProperty(theItem.m_##name.y); \ + break; + +struct SSceneTranslator : public Qt3DSTranslator +{ + typedef SScene TNodeType; + SSceneTranslator(Q3DStudio::TElement &inElement, SScene &inRenderObject) + : Qt3DSTranslator(inElement, inRenderObject) + { + } + // Ignored, scenes are always active + void SetActive(bool /*inElementActive*/) {} + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SScene &theItem = *static_cast(m_RenderObject); + + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_SCENE_PROPERTIES + // These are ignored by the renderer + case Q3DStudio::ATTRIBUTE_NAME: + case Q3DStudio::ATTRIBUTE_STARTTIME: + case Q3DStudio::ATTRIBUTE_ENDTIME: + case Q3DStudio::ATTRIBUTE_IMPORTID: + case Q3DStudio::ATTRIBUTE_EYEBALL: + break; + default: + // Unknown attribute + // QT3DS_ASSERT( false ); + break; + } + } + void PostPropertyChanged(const SRuntimePropertyParser &, Q3DStudio::IPresentation &) {} +}; + +struct SNodeTranslator : public Qt3DSTranslator +{ + typedef SNode TNodeType; + SNodeTranslator(Q3DStudio::TElement &inElement, SNode &inRenderObject) + : Qt3DSTranslator(inElement, inRenderObject) + { + SNode &theItem = *static_cast(m_RenderObject); + theItem.m_Flags.SetLocallyPickable(false); + } + void SetActive(bool inElementActive) + { + SNode &theItem = *static_cast(m_RenderObject); + if (theItem.m_Flags.IsActive() != inElementActive) { + theItem.m_Flags.SetActive(inElementActive); + theItem.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + } + } + + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SNode &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_NODE_PROPERTIES + case Q3DStudio::ATTRIBUTE_NAME: + case Q3DStudio::ATTRIBUTE_STARTTIME: + case Q3DStudio::ATTRIBUTE_ENDTIME: + case Q3DStudio::ATTRIBUTE_IMPORTID: + case Q3DStudio::ATTRIBUTE_EYEBALL: + // Groups have a source path property on them that we like to ignore. + case Q3DStudio::ATTRIBUTE_SOURCEPATH: + break; + default: + // Unknown attribute + // QT3DS_ASSERT( false ); + break; + } + } + void PostPropertyChanged(const SRuntimePropertyParser &inParser, + Q3DStudio::IPresentation & /*inStudioPresentation*/) + { + SNode &theItem = *static_cast(m_RenderObject); + if (inParser.m_TransformDirty) + theItem.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + else if (inParser.m_Dirty) + theItem.MarkDirty(NodeTransformDirtyFlag::TransformNotDirty); + if (inParser.m_TextDirty) + theItem.m_Flags.SetTextDirty(true); + SetActive(Element().GetActive()); + bool isNodePickable = m_Element->IsPickEnabled(); + if (theItem.m_Flags.IsLocallyPickable() != isNodePickable) { + theItem.m_Flags.SetLocallyPickable(isNodePickable); + theItem.MarkDirty(NodeTransformDirtyFlag::TransformNotDirty); + } + } +}; + +struct SLayerTranslator : public SNodeTranslator +{ + typedef SLayer TNodeType; + SLayerTranslator(Q3DStudio::TElement &inElement, SLayer &inRenderObject) + : SNodeTranslator(inElement, inRenderObject) + { + } + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + const char *propName = + Q3DStudio::GetAttributeString((Q3DStudio::EAttribute)inParser.m_PropertyName); + (void)propName; + SLayer &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_LAYER_PROPERTIES + // Ignored + default: + SNodeTranslator::OnSpecificPropertyChange(inParser); + } + } +}; + +struct SLightTranslator : public SNodeTranslator +{ + typedef SLight TNodeType; + SLightTranslator(Q3DStudio::TElement &inElement, SLight &inRenderObject) + : SNodeTranslator(inElement, inRenderObject) + { + } + + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SLight &theItem = *static_cast(m_RenderObject); + // I guess there is no switching of light type in the runtime right now. + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_LIGHT_PROPERTIES + default: + SNodeTranslator::OnSpecificPropertyChange(inParser); + break; + } + } +}; +struct SCameraTranslator : public SNodeTranslator +{ + typedef SCamera TNodeType; + SCameraTranslator(Q3DStudio::TElement &inElement, SCamera &inRenderObject) + : SNodeTranslator(inElement, inRenderObject) + { + } + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SCamera &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_CAMERA_PROPERTIES + default: + SNodeTranslator::OnSpecificPropertyChange(inParser); + break; + } + } +}; + +struct SModelTranslator : public SNodeTranslator +{ + typedef SModel TNodeType; + SModelTranslator(Q3DStudio::TElement &inElement, SModel &inRenderObject) + : SNodeTranslator(inElement, inRenderObject) + { + } + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SModel &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_MODEL_PROPERTIES + default: + SNodeTranslator::OnSpecificPropertyChange(inParser); + break; + } + } +}; + +struct SPathTranslator : public SNodeTranslator +{ + typedef SPath TNodeType; + SPathTranslator(Q3DStudio::TElement &inElement, SPath &inRenderObject) + : SNodeTranslator(inElement, inRenderObject) + { + } + + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SPath &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_PATH_PROPERTIES + default: + SNodeTranslator::OnSpecificPropertyChange(inParser); + break; + } + } +}; + +struct SPathSubPathTranslator : public Qt3DSTranslator +{ + + typedef SPathSubPath TNodeType; + + SPathSubPathTranslator(Q3DStudio::TElement &inElement, SPathSubPath &inRenderObject) + : Qt3DSTranslator(inElement, inRenderObject) + { + } + + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SPathSubPath &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_PATH_SUBPATH_PROPERTIES + default: + break; + } + } + + void PostPropertyChanged(const SRuntimePropertyParser &inParser, + Q3DStudio::IPresentation & /*inStudioPresentation*/) + { + SPathSubPath &theItem = *static_cast(m_RenderObject); + qt3ds::render::IPathManager &theManager = inParser.m_RenderContext.GetPathManager(); + QT3DSU32 numAnchors = 0; + bool updatePath = false; + CRegisteredString theAnchorType = + inParser.m_RenderContext.GetStringTable().RegisterStr("PathAnchorPoint"); + for (Q3DStudio::TElement *theChild = Element().GetChild(); theChild; + theChild = theChild->GetSibling()) { + if (theChild->GetType() == theAnchorType) { + ++numAnchors; + if (theChild->IsDirty()) + updatePath = true; + } + } + if (updatePath) { + NVDataRef thePathBuffer = + theManager.ResizePathSubPathBuffer(theItem, numAnchors); + if (thePathBuffer.size()) { + QT3DSU32 anchorIndex = 0; + for (Q3DStudio::TElement *theChild = Element().GetChild(); theChild; + theChild = theChild->GetSibling()) { + if (theChild->GetType() == theAnchorType) { + if (theChild->IsDirty()) { + qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); + + for (QT3DSI32 idx = 0, end = theChild->GetAttributeCount(); idx < end; + ++idx) { + qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = + theChild->GetPropertyByIndex(idx); + switch (thePropInfo.first.GetNameHash()) { + case Q3DStudio::ATTRIBUTE_POSITION_X: + thePoint.m_Position.x = thePropInfo.second->m_FLOAT; + break; + case Q3DStudio::ATTRIBUTE_POSITION_Y: + thePoint.m_Position.y = thePropInfo.second->m_FLOAT; + break; + case Q3DStudio::ATTRIBUTE_INCOMINGANGLE: + thePoint.m_IncomingAngle = thePropInfo.second->m_FLOAT; + thePoint.m_OutgoingAngle = thePoint.m_IncomingAngle + 180.0f; + break; + case Q3DStudio::ATTRIBUTE_INCOMINGDISTANCE: + thePoint.m_IncomingDistance = thePropInfo.second->m_FLOAT; + break; + case Q3DStudio::ATTRIBUTE_OUTGOINGDISTANCE: + thePoint.m_OutgoingDistance = thePropInfo.second->m_FLOAT; + break; + default: // ignored + break; + } + } + } + ++anchorIndex; + } + } + } + } + } +}; + +struct SDefaultMaterialTranslator : public Qt3DSTranslator +{ + typedef SDefaultMaterial TNodeType; + SDefaultMaterialTranslator(Q3DStudio::TElement &inElement, SDefaultMaterial &inRenderObject) + : Qt3DSTranslator(inElement, inRenderObject) + { + } + // Right now materials do not respect the active flag + void SetActive(bool) {} + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SDefaultMaterial &theItem = *static_cast(m_RenderObject); + // There is no render-time caching on a material, so the dirty flag doesn't do much. + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_MATERIAL_PROPERTIES + + case Q3DStudio::ATTRIBUTE_NAME: + case Q3DStudio::ATTRIBUTE_STARTTIME: + case Q3DStudio::ATTRIBUTE_ENDTIME: + case Q3DStudio::ATTRIBUTE_IMPORTID: + case Q3DStudio::ATTRIBUTE_EYEBALL: + case Q3DStudio::ATTRIBUTE_SOURCEPATH: + break; + default: + // Unknown attribute + // QT3DS_ASSERT( false ); + break; + } + } + + void PostPropertyChanged(const SRuntimePropertyParser &, Q3DStudio::IPresentation &) + { + SDefaultMaterial &theItem = *static_cast(m_RenderObject); + theItem.m_Dirty.SetDirty(); + } +}; + +struct SImageTranslator : public Qt3DSTranslator +{ + typedef SImage TNodeType; + SImageTranslator(Q3DStudio::TElement &inElement, SImage &inRenderObject) + : Qt3DSTranslator(inElement, inRenderObject) + { + } + + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SImage &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_IMAGE_PROPERTIES + case Q3DStudio::ATTRIBUTE_STARTTIME: + case Q3DStudio::ATTRIBUTE_ENDTIME: + case Q3DStudio::ATTRIBUTE_NAME: + case Q3DStudio::ATTRIBUTE_EYEBALL: + break; + default: + // Unknown attribute + // QT3DS_ASSERT( false ); + break; + } + } + void PostPropertyChanged(const SRuntimePropertyParser &inParser, Q3DStudio::IPresentation &) + { + SImage &theItem = *static_cast(m_RenderObject); + if (inParser.m_Dirty) + theItem.m_Flags.SetDirty(true); + if (inParser.m_TransformDirty) + theItem.m_Flags.SetTransformDirty(true); + } +}; + +struct SReferencedMaterialTranslator : public Qt3DSTranslator +{ + typedef SReferencedMaterial TNodeType; + SReferencedMaterialTranslator(Q3DStudio::TElement &inElement, TNodeType &inRenderObject) + : Qt3DSTranslator(inElement, inRenderObject) + { + } + + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + TNodeType &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_REFERENCED_MATERIAL_PROPERTIES + case Q3DStudio::ATTRIBUTE_STARTTIME: + case Q3DStudio::ATTRIBUTE_ENDTIME: + case Q3DStudio::ATTRIBUTE_NAME: + case Q3DStudio::ATTRIBUTE_EYEBALL: + break; + default: + // Unknown attribute + // QT3DS_ASSERT( false ); + break; + } + } + void PostPropertyChanged(const SRuntimePropertyParser &inParser, Q3DStudio::IPresentation &) + { + TNodeType &theItem = *static_cast(m_RenderObject); + if (inParser.m_Dirty) + theItem.m_Dirty.SetDirty(); + } +}; + +struct STextTranslator : public SNodeTranslator +{ + typedef SText TNodeType; + STextTranslator(Q3DStudio::TElement &inElement, SText &inRenderObject) + : SNodeTranslator(inElement, inRenderObject) + { + } + void OnSpecificPropertyChange(SRuntimePropertyParser &inParser) + { + SText &theItem = *static_cast(m_RenderObject); + switch (inParser.m_PropertyName) { + ITERATE_QT3DS_RENDER_TEXT_PROPERTIES + case Q3DStudio::ATTRIBUTE_TEXTTYPE: + case Q3DStudio::ATTRIBUTE_RENDERSTYLE: + case Q3DStudio::ATTRIBUTE_HORZSCROLL: + case Q3DStudio::ATTRIBUTE_VERTSCROLL: + case Q3DStudio::ATTRIBUTE_BOXHEIGHT: + case Q3DStudio::ATTRIBUTE_BOXWIDTH: + case Q3DStudio::ATTRIBUTE_REMOTESTRINGSOURCE: + case Q3DStudio::ATTRIBUTE_CACHEDTEXTSTRING: + // These text properties are ignored for now. + break; + default: + SNodeTranslator::OnSpecificPropertyChange(inParser); + break; + } + } +}; + +struct SEffectPropertyEntry +{ + Q3DStudio::EAttributeType m_AttributeType; + QT3DSU32 m_PropertyOffset; // offset into the property array for the property def + QT3DSU32 m_DataOffset; + SEffectPropertyEntry(Q3DStudio::EAttributeType attType, QT3DSU32 poff, QT3DSU32 doff = 0) + : m_AttributeType(attType) + , m_PropertyOffset(poff) + , m_DataOffset(doff) + { + } +}; + +struct SDynamicObjectTranslatorContext : public STranslatorContext +{ + typedef nvhash_map THashToOffsetMap; + THashToOffsetMap m_PropertyHashes; + NVAllocatorCallback &m_Allocator; + CRenderString m_Workspace; + SDynamicObjectTranslatorContext(NVAllocatorCallback &inCallback) + : m_PropertyHashes(inCallback, "SEffectTranslatorContext::PropertyHashes") + , m_Allocator(inCallback) + { + } + ~SDynamicObjectTranslatorContext() {} + void AddEffectExtendedProperty(const qt3ds::render::dynamic::SPropertyDefinition &thePropDef, + const char *inExtension, Q3DStudio::EAttributeType inType, + CRenderString &ioStringBuilder, QT3DSU32 inOffset, QT3DSU32 dataOffset) + { + ioStringBuilder.assign(thePropDef.m_Name.c_str()); + ioStringBuilder.append(inExtension); + Q3DStudio::INT32 theHash = Q3DStudio::CHash::HashAttribute(ioStringBuilder.c_str()); + m_PropertyHashes.insert( + eastl::make_pair(theHash, SEffectPropertyEntry(inType, inOffset, dataOffset))); + } + void BuildPropertyHashes(NVConstDataRef inProperties) + { + if (m_PropertyHashes.size() == 0) { + qt3ds::render::CRenderString theNameBuilder; + for (QT3DSU32 idx = 0, end = inProperties.size(); idx < end; ++idx) { + const qt3ds::render::dynamic::SPropertyDefinition &thePropDef = inProperties[idx]; + switch (thePropDef.m_DataType) { + case qt3ds::render::NVRenderShaderDataTypes::QT3DSF32: + m_PropertyHashes.insert(eastl::make_pair( + Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), + SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_FLOAT, idx))); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSRenderBool: + m_PropertyHashes.insert( + eastl::make_pair(Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), + SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_BOOL, idx))); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSI32: + if (thePropDef.m_IsEnumProperty == false) { + m_PropertyHashes.insert(eastl::make_pair( + Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), + SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_INT32, idx))); + } else { + m_PropertyHashes.insert(eastl::make_pair( + Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), + SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_STRING, idx))); + } + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec2: + AddEffectExtendedProperty(thePropDef, ".x", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 0); + AddEffectExtendedProperty(thePropDef, ".y", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, sizeof(QT3DSF32)); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec3: + AddEffectExtendedProperty(thePropDef, ".x", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 0); + AddEffectExtendedProperty(thePropDef, ".y", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, sizeof(QT3DSF32)); + AddEffectExtendedProperty(thePropDef, ".z", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 2 * sizeof(QT3DSF32)); + + AddEffectExtendedProperty(thePropDef, ".r", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 0); + AddEffectExtendedProperty(thePropDef, ".g", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, sizeof(QT3DSF32)); + AddEffectExtendedProperty(thePropDef, ".b", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 2 * sizeof(QT3DSF32)); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4: + AddEffectExtendedProperty(thePropDef, ".x", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 0); + AddEffectExtendedProperty(thePropDef, ".y", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, sizeof(QT3DSF32)); + AddEffectExtendedProperty(thePropDef, ".z", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 2 * sizeof(QT3DSF32)); + AddEffectExtendedProperty(thePropDef, ".w", Q3DStudio::ATTRIBUTETYPE_FLOAT, + theNameBuilder, idx, 3 * sizeof(QT3DSF32)); + break; + case qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr: + case qt3ds::render::NVRenderShaderDataTypes::NVRenderImage2DPtr: + m_PropertyHashes.insert(eastl::make_pair( + Q3DStudio::CHash::HashAttribute(thePropDef.m_Name.c_str()), + SEffectPropertyEntry(Q3DStudio::ATTRIBUTETYPE_STRING, idx))); + break; + case qt3ds::render::NVRenderShaderDataTypes::NVRenderDataBufferPtr: + break; + default: + QT3DS_ASSERT(false); + break; + } + } + } + } + void ApplyChanges(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, + SDynamicObject &inObject, Q3DStudio::TElement &element, + IDynamicObjectSystem &inSystem) + { + if (element.GetActive()) { + NVConstDataRef theProperties = + inSystem.GetProperties(inObject.m_ClassName); + BuildPropertyHashes(theProperties); + SDynamicObject &theItem(inObject); + for (long idx = 0, end = element.GetAttributeCount(); idx < end; ++idx) { + qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = + *element.GetPropertyByIndex(idx); + THashToOffsetMap::iterator theFind = + m_PropertyHashes.find(thePropInfo.first.GetNameHash()); + if (theFind != m_PropertyHashes.end()) { + const SEffectPropertyEntry &theEntry(theFind->second); + const qt3ds::render::dynamic::SPropertyDefinition &theDefinition( + theProperties[theEntry.m_PropertyOffset]); + if (theEntry.m_AttributeType + == (Q3DStudio::EAttributeType)thePropInfo.first.m_Type) { + switch (theEntry.m_AttributeType) { + case Q3DStudio::ATTRIBUTETYPE_BOOL: + theItem.SetPropertyValue(theDefinition, + thePropInfo.second->m_INT32 ? true : false); + break; + case Q3DStudio::ATTRIBUTETYPE_FLOAT: + theItem.SetPropertyValue(theDefinition, thePropInfo.second->m_FLOAT, + theEntry.m_DataOffset); + break; + case Q3DStudio::ATTRIBUTETYPE_INT32: + theItem.SetPropertyValue(theDefinition, + (QT3DSI32)thePropInfo.second->m_INT32); + break; + case Q3DStudio::ATTRIBUTETYPE_STRING: { + CRegisteredString theStr = + element.GetBelongedPresentation()->GetStringTable().HandleToStr( + thePropInfo.second->m_StringHandle); + theItem.SetPropertyValue(theDefinition, theStr.c_str(), + inPresentation.m_PresentationDirectory.c_str(), + m_Workspace, inRenderContext.GetStringTable()); + } break; + default: + // QT3DS_ASSERT( false ); + break; + } + } else { + // QT3DS_ASSERT( false ); + } + } + } + theItem.m_Flags.SetDirty(true); + } + } +}; + +struct SEffectTranslator : public Qt3DSTranslator +{ + typedef SEffect TNodeType; + SEffectTranslator(Q3DStudio::TElement &inElement, SEffect &inRenderObject, + NVAllocatorCallback &inCallback) + : Qt3DSTranslator(inElement, inRenderObject) + { + m_TranslatorContext = QT3DS_NEW(inCallback, SDynamicObjectTranslatorContext)(inCallback); + } + + void OnElementChanged(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &) + { + SRuntimePropertyParser theParser(inPresentation, inRenderContext, *m_Element); + SEffect &theItem = *static_cast(m_RenderObject); + static_cast(m_TranslatorContext) + ->ApplyChanges(inPresentation, inRenderContext, theItem, Element(), + inRenderContext.GetDynamicObjectSystem()); + theItem.SetActive(Element().GetActive(), inRenderContext.GetEffectSystem()); + } +}; + +struct SCustomMaterialTranslator : public Qt3DSTranslator +{ + typedef SCustomMaterial TNodeType; + SCustomMaterialTranslator(Q3DStudio::TElement &inElement, SCustomMaterial &inRenderObject, + NVAllocatorCallback &inCallback) + : Qt3DSTranslator(inElement, inRenderObject) + { + m_TranslatorContext = QT3DS_NEW(inCallback, SDynamicObjectTranslatorContext)(inCallback); + } + + void OnElementChanged(SPresentation &inPresentation, IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &) + { + SRuntimePropertyParser theParser(inPresentation, inRenderContext, *m_Element); + SCustomMaterial &theItem = *static_cast(m_RenderObject); + static_cast(m_TranslatorContext) + ->ApplyChanges(inPresentation, inRenderContext, theItem, Element(), + inRenderContext.GetDynamicObjectSystem()); + bool active = m_Element->GetActive(); + if (active != theItem.m_Flags.IsActive()) { + theItem.m_Flags.SetActive(active); + ICustomMaterialSystem &theSystem(inRenderContext.GetCustomMaterialSystem()); + theSystem.OnMaterialActivationChange(theItem, active); + } + } +}; + +struct SRenderPluginTranslatorContext : public STranslatorContext +{ + NVAllocatorCallback &m_Allocator; + nvhash_map m_AttribHashIndexMap; + nvvector m_PropertyUpdates; + SRenderPluginTranslatorContext(NVAllocatorCallback &alloc) + : m_Allocator(alloc) + , m_AttribHashIndexMap(alloc, "SRenderPluginTranslatorContext::AttribIndexMap") + , m_PropertyUpdates(alloc, "SRenderPluginTranslatorContext::m_PropertyUpdates") + { + } + void ReverseMap(CRegisteredString str) + { + m_AttribHashIndexMap.insert( + eastl::make_pair(Q3DStudio::CHash::HashAttribute(str.c_str()), str)); + } +}; + +struct SRenderPluginTranslator : public Qt3DSTranslator +{ + typedef SRenderPlugin TNodeType; + SRenderPluginTranslator(Q3DStudio::TElement &inElement, SRenderPlugin &inRenderObject, + NVAllocatorCallback &inCallback) + : Qt3DSTranslator(inElement, inRenderObject) + { + m_TranslatorContext = QT3DS_NEW(inCallback, SRenderPluginTranslatorContext)(inCallback); + } + + void OnElementChanged(SPresentation & /*inPresentation*/, IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &) + { + SRenderPlugin &theItem = *static_cast(m_RenderObject); + theItem.m_Flags.SetActive(Element().GetActive()); + IRenderPluginInstance *theInstance = + inRenderContext.GetRenderPluginManager().GetOrCreateRenderPluginInstance( + theItem.m_PluginPath, &theItem); + if (theInstance != NULL) { + IRenderPluginClass &theClass(theInstance->GetPluginClass()); + SRenderPluginTranslatorContext &theTransContext = + static_cast(*m_TranslatorContext); + if (theTransContext.m_AttribHashIndexMap.empty()) { + NVConstDataRef theProperties( + theClass.GetRegisteredProperties()); + for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { + const SRenderPluginPropertyDeclaration &theDec(theProperties[idx]); + switch (theDec.m_Type) { + case SRenderPluginPropertyTypes::Boolean: + theTransContext.ReverseMap(theDec.m_Name); + break; + case SRenderPluginPropertyTypes::Float: + theTransContext.ReverseMap(theDec.m_Name); + break; + case SRenderPluginPropertyTypes::Long: + theTransContext.ReverseMap(theDec.m_Name); + break; + case SRenderPluginPropertyTypes::String: + theTransContext.ReverseMap(theDec.m_Name); + break; + case SRenderPluginPropertyTypes::Vector2: + theTransContext.ReverseMap( + theClass.GetPropertyValueInfo(theDec.m_StartOffset).first); + theTransContext.ReverseMap( + theClass.GetPropertyValueInfo(theDec.m_StartOffset + 1).first); + break; + case SRenderPluginPropertyTypes::Vector3: + case SRenderPluginPropertyTypes::Color: + theTransContext.ReverseMap( + theClass.GetPropertyValueInfo(theDec.m_StartOffset).first); + theTransContext.ReverseMap( + theClass.GetPropertyValueInfo(theDec.m_StartOffset + 1).first); + theTransContext.ReverseMap( + theClass.GetPropertyValueInfo(theDec.m_StartOffset + 2).first); + break; + default: + // QT3DS_ASSERT( false ); + break; + } + } + } // ok, now we have an efficient mapping from attribute to plugin value name. + theTransContext.m_PropertyUpdates.clear(); + for (long idx = 0, end = Element().GetAttributeCount(); idx < end; ++idx) { + qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = + *Element().GetPropertyByIndex(idx); + nvhash_map::iterator theFind = + theTransContext.m_AttribHashIndexMap.find(thePropInfo.first.GetNameHash()); + if (theFind != theTransContext.m_AttribHashIndexMap.end()) { + CRegisteredString thePropName(theFind->second); + Q3DStudio::EAttributeType theType = + (Q3DStudio::EAttributeType)thePropInfo.first.m_Type; + switch (theType) { + case Q3DStudio::ATTRIBUTETYPE_BOOL: + theTransContext.m_PropertyUpdates.push_back(SRenderPropertyValueUpdate( + thePropName, thePropInfo.second->m_INT32 ? true : false)); + break; + case Q3DStudio::ATTRIBUTETYPE_FLOAT: + theTransContext.m_PropertyUpdates.push_back( + SRenderPropertyValueUpdate(thePropName, thePropInfo.second->m_FLOAT)); + break; + case Q3DStudio::ATTRIBUTETYPE_INT32: + theTransContext.m_PropertyUpdates.push_back(SRenderPropertyValueUpdate( + thePropName, (QT3DSI32)thePropInfo.second->m_INT32)); + break; + case Q3DStudio::ATTRIBUTETYPE_STRING: { + CRegisteredString theStr = inRenderContext.GetStringTable().HandleToStr( + thePropInfo.second->m_StringHandle); + theTransContext.m_PropertyUpdates.push_back( + SRenderPropertyValueUpdate(thePropName, theStr)); + } break; + default: + // QT3DS_ASSERT( false ); + break; + } + } + } + if (theTransContext.m_PropertyUpdates.empty() == false) { + theInstance->Update(toConstDataRef(theTransContext.m_PropertyUpdates.data(), + theTransContext.m_PropertyUpdates.size())); + } + } + } +}; +} + +Qt3DSTranslator::Qt3DSTranslator(Q3DStudio::TElement &inElement, SGraphObject &inRenderObject) + : m_DirtyIndex(QT3DS_MAX_U32) + , m_Element(&inElement) + , m_RenderObject(&inRenderObject) + , m_TranslatorContext(NULL) +{ + Element().SetAssociation(reinterpret_cast(this)); + inRenderObject.m_UserData = STaggedPointer(this); +} + +void Qt3DSTranslator::Save(SWriteBuffer &inWriteBuffer, QT3DSU32 inGraphObjectOffset) +{ + // We have to start on pointer aligned boundaries. + QT3DS_ASSERT(inWriteBuffer.size() % 4 == 0); + QT3DSU32 theOffset = inWriteBuffer.size(); + inWriteBuffer.write(*this); + Qt3DSTranslator *theNewTranslator = + reinterpret_cast(inWriteBuffer.begin() + theOffset); + theNewTranslator->m_DirtyIndex = QT3DS_MAX_U32; + if (theNewTranslator->m_Element) + theNewTranslator->m_Element = m_Element->GetBelongedPresentation() + ->GetApplication() + .GetElementAllocator() + .GetRemappedElementAddress(m_Element); + size_t *graphObjPtr = reinterpret_cast(&theNewTranslator->m_RenderObject); + *graphObjPtr = inGraphObjectOffset; +} + +Qt3DSTranslator *Qt3DSTranslator::GetTranslatorFromGraphNode(SGraphObject &inObject) +{ + return inObject.m_UserData.DynamicCast(); +} + +namespace { +struct SPresentationTranslator; +struct SEffectTranslator; +template +struct STranslatorCreator +{ + static TTranslatorType *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, + NVAllocatorCallback &inAllocator) + { + typedef typename TTranslatorType::TNodeType TNodeType; + // This assert needs to be here because we serialize all translators generically without + // regard for type. + StaticAssert::valid_expression(); + return QT3DS_NEW(inAllocator, TTranslatorType)(inElement, static_cast(inObject)); + } + static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &) + { + typedef typename TTranslatorType::TNodeType TNodeType; + // Initialize the vtable. + new (&inTranslator) TTranslatorType(inTranslator.Element(), + static_cast(inTranslator.RenderObject())); + } + + static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, + IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &inStudioPresentation) + { + TTranslatorType &theTranslator(static_cast(inTranslator)); + SRuntimePropertyParser theParser(inPresentation, inRenderContext, *theTranslator.m_Element); + if (theTranslator.Element().GetActive()) { + // Don't push properties from inactive elements. + for (long idx = 0, end = theTranslator.Element().GetAttributeCount(); idx < end; + ++idx) { + qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = + *theTranslator.Element().GetPropertyByIndex(idx); + theParser.Setup(thePropInfo.first.GetNameHash(), *thePropInfo.second, + (Q3DStudio::EAttributeType)thePropInfo.first.m_Type); + // right now, this is the best we can do because the attribute's dirty system + // is all jacked up. + theTranslator.OnSpecificPropertyChange(theParser); + } + // same for dynamic properties + for (long idx = 0, end = theTranslator.Element().GetDynamicAttributeCount(); idx < end; + ++idx) { + qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = + *theTranslator.Element().GetDynamicPropertyByIndex(idx); + theParser.Setup(thePropInfo.first.GetNameHash(), *thePropInfo.second, + (Q3DStudio::EAttributeType)thePropInfo.first.m_Type); + // right now, this is the best we can do because the attribute's dirty system + // is all jacked up. + theTranslator.OnSpecificPropertyChange(theParser); + } + // Set appropriate dirty flags + } + theTranslator.PostPropertyChanged(theParser, inStudioPresentation); + } +}; + +template <> +struct STranslatorCreator +{ + static Qt3DSTranslator *Create(Q3DStudio::TElement &, SGraphObject &, NVAllocatorCallback &) + { + return NULL; + } + static void InitializeTranslator(Qt3DSTranslator &, NVAllocatorCallback &) {} + static void OnElementChanged(Qt3DSTranslator & /*inTranslator*/, + SPresentation & /*inPresentation*/ + , + IQt3DSRenderContext & /*inRenderContext*/, + Q3DStudio::IPresentation & /*inStudioPresentation*/) + { + QT3DS_ASSERT(false); + } +}; + +template <> +struct STranslatorCreator +{ + static SEffectTranslator *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, + NVAllocatorCallback &inAllocator) + { + typedef SEffectTranslator::TNodeType TNodeType; + // This assert needs to be here because we serialize all translators generically without + // regard for type. + StaticAssert::valid_expression(); + return QT3DS_NEW(inAllocator, SEffectTranslator)(inElement, static_cast(inObject), + inAllocator); + } + + static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &inAllocator) + { + typedef SEffectTranslator::TNodeType TNodeType; + // Initialize the vtable. + new (&inTranslator) + SEffectTranslator(inTranslator.Element(), + static_cast(inTranslator.RenderObject()), inAllocator); + } + static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, + IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &inStudioPresentation) + { + static_cast(inTranslator) + .OnElementChanged(inPresentation, inRenderContext, inStudioPresentation); + } +}; + +template <> +struct STranslatorCreator +{ + static SCustomMaterialTranslator *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, + NVAllocatorCallback &inAllocator) + { + typedef SCustomMaterialTranslator::TNodeType TNodeType; + // This assert needs to be here because we serialize all translators generically without + // regard for type. + StaticAssert::valid_expression(); + return QT3DS_NEW(inAllocator, SCustomMaterialTranslator)( + inElement, static_cast(inObject), inAllocator); + } + + static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &inAllocator) + { + typedef SCustomMaterialTranslator::TNodeType TNodeType; + // Initialize the vtable. + new (&inTranslator) SCustomMaterialTranslator( + inTranslator.Element(), static_cast(inTranslator.RenderObject()), + inAllocator); + } + + static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, + IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &inStudioPresentation) + { + static_cast(inTranslator) + .OnElementChanged(inPresentation, inRenderContext, inStudioPresentation); + } +}; + +template <> +struct STranslatorCreator +{ + static SRenderPluginTranslator *Create(Q3DStudio::TElement &inElement, SGraphObject &inObject, + NVAllocatorCallback &inAllocator) + { + typedef SRenderPluginTranslator::TNodeType TNodeType; + // This assert needs to be here because we serialize all translators generically without + // regard for type. + StaticAssert::valid_expression(); + return QT3DS_NEW(inAllocator, SRenderPluginTranslator)( + inElement, static_cast(inObject), inAllocator); + } + + static void InitializeTranslator(Qt3DSTranslator &inTranslator, NVAllocatorCallback &inAllocator) + { + typedef SRenderPluginTranslator::TNodeType TNodeType; + // Initialize the vtable. + new (&inTranslator) SRenderPluginTranslator( + inTranslator.Element(), static_cast(inTranslator.RenderObject()), + inAllocator); + } + static void OnElementChanged(Qt3DSTranslator &inTranslator, SPresentation &inPresentation, + IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &inStudioPresentation) + { + static_cast(inTranslator) + .OnElementChanged(inPresentation, inRenderContext, inStudioPresentation); + } +}; +} +Qt3DSTranslator *Qt3DSTranslator::CreateTranslatorForElement(Q3DStudio::TElement &inElement, + SGraphObject &inObject, + NVAllocatorCallback &inAlloc) +{ + Qt3DSTranslator *theTranslator = NULL; + switch (inObject.m_Type) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case GraphObjectTypes::type: \ + theTranslator = \ + STranslatorCreator::Create(inElement, inObject, inAlloc); \ + break; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + QT3DS_ASSERT(false); + break; + } + return theTranslator; +} + +void Qt3DSTranslator::OnElementChanged(SPresentation &inPresentation, + IQt3DSRenderContext &inRenderContext, + Q3DStudio::IPresentation &inStudioPresentation) +{ + switch (m_RenderObject->m_Type) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case GraphObjectTypes::type: \ + STranslatorCreator::OnElementChanged( \ + *this, inPresentation, inRenderContext, inStudioPresentation); \ + break; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + QT3DS_ASSERT(false); + break; + } +} + +Qt3DSTranslator *Qt3DSTranslator::LoadTranslator(SDataReader &inReader, size_t inElemOffset, + NVDataRef inSGSection, + NVAllocatorCallback &inAllocator) +{ + // Reader points to a new translator but we don't know what type + QT3DSU8 *theTranslatorStart = inReader.m_CurrentPtr; + // Make sure things are aligned + (void)theTranslatorStart; + QT3DS_ASSERT((size_t)theTranslatorStart % 4 == 0); + Qt3DSTranslator *theTranslator = inReader.Load(); + if (theTranslator) { + size_t *elemPtr = reinterpret_cast(&theTranslator->m_Element); + *elemPtr += inElemOffset; + size_t *graphObjPtr = reinterpret_cast(&theTranslator->m_RenderObject); + size_t sgSectionStart = reinterpret_cast(inSGSection.begin()); + *graphObjPtr += sgSectionStart; + // Call actual constructor to initialize vtable. + switch (theTranslator->RenderObject().m_Type) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case GraphObjectTypes::type: \ + STranslatorCreator::InitializeTranslator(*theTranslator, \ + inAllocator); \ + break; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + QT3DS_ASSERT(false); + break; + } + } + return theTranslator; +} +Q3DStudio::IPresentation * +Qt3DSTranslator::GetPresentationFromPresentation(SPresentation &inPresentation) +{ + return inPresentation.m_UserData.DynamicCast(); +} + +void Qt3DSTranslator::InitializePointerTags(IStringTable &) +{ + g_TranslatorTag = 0x0044FEED; + g_PresentationTag = 0x0022ABBA; +} + +void Qt3DSTranslator::AssignUserData(Q3DStudio::IPresentation &inPresentation, + SPresentation &inGraphPresentation) +{ + inGraphPresentation.m_UserData = STaggedPointer(&inPresentation); +} diff --git a/src/Runtime/Source/engine/Qt3DSTegraApplication.cpp b/src/Runtime/Source/engine/Qt3DSTegraApplication.cpp new file mode 100644 index 00000000..92c7f6cc --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSTegraApplication.cpp @@ -0,0 +1,746 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTegraApplication.h" +#include "Qt3DSTegraInputEngine.h" +#include "Qt3DSDataLogger.h" +#include "Qt3DSFileStream.h" +#include "Qt3DSArray.h" +#include "Qt3DSApplication.h" +#include "foundation/FileTools.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSPresentation.h" +#include "EASTL/string.h" +#include "Qt3DSMemory.h" +#include "Qt3DSKernelTypes.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderer.h" + +#include "Qt3DSDLLManager.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/TrackingAllocator.h" +// For perf log timestamp +#include +#include "Qt3DSArray.h" +// For perf log timestamp +#include + +#if Q_OS_WINDOWS +#include "qt3ds_launcher_defs.h" +#endif + +#ifdef _LINUXPLATFORM +#include +#include +#endif + +#ifdef ANDROID +#include +#endif + +#include +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace qt3ds { +namespace render { +extern qt3ds::foundation::MallocAllocator g_BaseAllocator; +} +} + +namespace Q3DStudio { + +namespace { + +bool CaselessEqual(const char *lhs, const char *rhs) +{ + if (lhs == NULL) + lhs = ""; + if (rhs == NULL) + rhs = ""; + return Q3DStudio_stricmp(lhs, rhs) == 0; +} + +CInputEngine *CreateInputEngine() +{ + return Q3DStudio_virtual_new(CTegraInputEngine) CTegraInputEngine(); +} + +static eastl::string *theAppDir = nullptr; +const eastl::string &GetAppDir(const eastl::string &inAppExe) +{ + if (!theAppDir) + theAppDir = new eastl::string; +#ifndef __ANDROID__ + theAppDir->assign(inAppExe.empty() == false ? inAppExe : ""); +#ifdef Qt3DS_OS_LINUX + char theBuf[1024] = { 0 }; + int rc = readlink("/proc/self/exe", theBuf, sizeof(theBuf)); + if (rc > 0) + theAppDir->assign(theBuf); +#endif +#ifdef Qt3DS_OS_QNX + char theBuf[1024] = { 0 }; + FILE *exefile = fopen("/proc/self/exefile", "r"); + if (exefile != NULL) { + fgets(theBuf, sizeof(theBuf), exefile); + fclose(exefile); + theAppDir->assign(theBuf); + } +#endif + eastl::string::size_type pos = theAppDir->find_last_of("\\/"); + if (pos != eastl::string::npos) + *theAppDir = theAppDir->substr(0, pos); + theAppDir->append("\\"); +#endif + return *theAppDir; +} +} + +using namespace qt3ds; +using namespace qt3ds::foundation; + +//============================================================================== +/** + * CNDDView + */ +class CNDDView : public INDDView +{ + //============================================================================== + // Fields + //============================================================================== +private: + ITegraApplicationRenderEngine *m_RenderEngine; ///< Handles all rendering functions + CTegraInputEngine *m_InputEngine; ///< Handles all user input events + // Pre graphics init objects + NVScopedRefCounted m_RuntimeFactoryCore; + NVScopedRefCounted + m_ApplicationCore; ///< Base application before graphis + + // Post graphics init objects + NVScopedRefCounted m_RuntimeFactory; + NVScopedRefCounted m_Application; ///< Application after graphics + CPresentation *m_Presentation; ///< Currently loaded presentation, this should be removed in the future + + CPausingTimeProvider m_TimeProvider; + IWindowSystem &m_WindowSystem; + IAudioPlayer *m_AudioPlayer; + + volatile QT3DSI32 mRefCount; + + qt3ds::Qt3DSAssetVisitor *m_visitor; + bool m_showOnScreenStats; + +public: + CNDDView(ITimeProvider &inTimeProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer); + ~CNDDView(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(qt3ds::render::g_BaseAllocator); + + bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override; + bool HasOfflineLoadingCompleted() override; + bool InitializeGraphics(const QSurfaceFormat &format) override; + + void Cleanup() override; + + bool CanRender() override; + void Render() override; + bool WasLastFrameDirty() override; + + bool HandleMessage(const QEvent *inEvent) override; + + void Pause() override; + void UnPause() override; + bool IsPaused() override; + void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) override; + + INT32 GetFrameCount() override; + void showOnScreenStats(bool) override; + + CInputEngine *GetInputEngine() override; + // Only valid after InitializeGraphics + ITegraApplicationRenderEngine *GetTegraRenderEngine() override { return m_RenderEngine; } + + void GoToSlideByName(const char *elementPath, const char *slideName) override; + void GoToSlideByIndex(const char *elementPath, const int slideIndex) override; + void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) override; + bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) override; + void SetPresentationAttribute(const char *presId, const char *, const char *value) override; + void GoToTime(const char *elementPath, const float time) override; + void SetGlobalAnimationTime(qint64 inMilliSecs) override; + void SetDataInputValue(const QString &name, const QVariant &value); + void SetAttribute(const char *elementPath, const char *attributeName, const char *value) override; + bool GetAttribute(const char *elementPath, const char *attributeName, void *value) override; + void FireEvent(const char *element, const char *evtName) override; + bool PeekCustomAction(char *&outElementPath, char *&outActionName) override; + bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) override; + void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) override; + qt3ds::foundation::Option GetPresentationSize() override; + + void BootupPreGraphicsInitObjects(); +}; + +CNDDView::CNDDView(ITimeProvider &inTimeProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer) + : m_RenderEngine(NULL) + , m_InputEngine(NULL) + , m_Application(NULL) + , m_Presentation(NULL) + , m_TimeProvider(inTimeProvider) + , m_WindowSystem(inWindowSystem) + , m_AudioPlayer(inAudioPlayer) + , mRefCount(0) + , m_visitor(nullptr) + , m_showOnScreenStats(false) +{ +} + +CNDDView::~CNDDView() +{ +} + +bool CNDDView::BeginLoad(const QString &sourcePath, const QStringList &variantList) +{ + bool theResult = false; + + // boot up the application + BootupPreGraphicsInitObjects(); + + // If there was a presentation file then we have to load it or something failed. + if (m_ApplicationCore->BeginLoad(sourcePath.toUtf8(), variantList)) + theResult = true; + else + theResult = false; + + // If Initialize wasn't successful - this means the CShaderFactory failed to initialize + // or, the presentation failed to load. + // + // NOTE: if no presentation was passed, this is 'ok' + if (!theResult) + Cleanup(); + + return theResult; +} + +bool CNDDView::HasOfflineLoadingCompleted() +{ + if (m_Application.mPtr == NULL) { + if (m_ApplicationCore) + return m_ApplicationCore->HasCompletedLoading(); + else + return false; + } + return true; +} + +bool CNDDView::InitializeGraphics(const QSurfaceFormat &format) +{ + m_ApplicationCore->EndLoad(); + // Next call will initialize the render portion of the scenes. This *must* have a loaded + // application to go further as it will bind scene graph data to application data. + m_RuntimeFactory = m_RuntimeFactoryCore->CreateRenderFactory(format); + m_Application + = m_ApplicationCore->CreateApplication(*m_InputEngine, m_AudioPlayer, + *m_RuntimeFactory); + if (!m_Application->createSuccessful()) + return false; + + m_Application->ResetTime(); + m_RenderEngine = &m_RuntimeFactory->CreateRenderEngine(); + m_Presentation = m_Application->GetPrimaryPresentation(); + + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigSlideEntered, + signalProxy(), &QINDDViewSignalProxy::SigSlideEntered); + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigSlideExited, + signalProxy(), &QINDDViewSignalProxy::SigSlideExited); + + m_TimeProvider.Reset(); + return true; +} + +void CNDDView::Cleanup() +{ + // Q3DStudio_virtual_delete( m_Timer, CTimer ); + // Q3DStudio_virtual_delete( m_PerfFileStream, CFileStream ); + m_Application = NULL; + Q3DStudio_virtual_delete(m_InputEngine, CTegraInputEngine); + if (m_RenderEngine) { + m_RenderEngine->Release(); + m_RenderEngine = NULL; + } + + CDLLManager &theDLLManager = CDLLManager::GetDLLManager(); + theDLLManager.Cleanup(); + if (m_Presentation) + QObject::disconnect(m_Presentation->signalProxy(), 0, signalProxy(), 0); + + m_InputEngine = NULL; + m_RenderEngine = NULL; + m_Presentation = NULL; +} + +bool CNDDView::CanRender() +{ + return m_Application.mPtr != NULL; +} + +//============================================================================== +/** + * nv_main APP-SPECIFIC rendering call + * returns KD_TRUE to call egl_render and swap properly, KD_FALSE if there has been no scene update + *or redraw. + */ +void CNDDView::Render() +{ + if (m_Application.mPtr == NULL) { + // InitializeGraphics has not been called + QT3DS_ASSERT(false); + } + + PerfLogGeneralEvent1(DATALOGGER_FRAME); + + m_Application->UpdateAndRender(); + + if (m_showOnScreenStats) { + ITegraRenderStateManager &manager + = GetTegraRenderEngine()->GetTegraRenderStateManager(); + manager.PushState(); + + QSize dim = m_WindowSystem.GetWindowDimensions(); + manager.SetScissorTestEnabled(false); + manager.SetViewport(0, 0, dim.width(), dim.height()); + + QPair fps + = m_RuntimeFactory->GetQt3DSRenderContext().GetFPS(); + + QString text; + QTextStream stream(&text); + stream << QStringLiteral("Render Statistics: "); + stream << QString::number(fps.first, 'f', 2); + stream << " fps, frame count "; + stream << QString::number(fps.second); + + // bottom left coordinates + GetTegraRenderEngine()->RenderText2D( + dim.width() / 4, dim.height() - 25, qt3ds::QT3DSVec3(0.0, 1.0, 0.0), + text.toLatin1().constData()); + GetTegraRenderEngine()->RenderGpuProfilerStats( + 20.0, dim.height() - 80, qt3ds::QT3DSVec3(0.0, 1.0, 0.0)); + + manager.PopState(); + } +} + +bool CNDDView::WasLastFrameDirty() +{ + if (m_Application) + return m_Application->IsApplicationDirty(); + return false; +} + +//============================================================================== +/** + * nv_main APP-SPECIFIC message call + * HandleMessage + */ +bool CNDDView::HandleMessage(const QEvent *inEvent) +{ + if (m_Application.mPtr == NULL || m_RenderEngine == NULL) + return 0; + + bool ret = false; + switch (inEvent->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + { + const QMouseEvent *event = static_cast(inEvent); + m_InputEngine->SetPickInput(static_cast(event->x()), + static_cast(event->y()), true); + m_InputEngine->SetPickFlags(inEvent->type() == QEvent::MouseButtonPress + ? LMOUSE_DOWN : LMOUSE_UP); + ret = true; + } + break; + case QEvent::Resize: + { + if (m_Application->GetPrimaryPresentation()) + m_RenderEngine->CheckResize(true, *m_Application->GetPrimaryPresentation()); + ret = true; + } + break; + default: + break; + } + + m_InputEngine->HandleMessage(inEvent, *m_RenderEngine, m_Application->GetPrimaryPresentation()); + return ret ? 1 : 0; +} + +void CNDDView::Pause() +{ + m_TimeProvider.Pause(); +} + +void CNDDView::UnPause() +{ + m_TimeProvider.UnPause(); +} + +bool CNDDView::IsPaused() +{ + return m_TimeProvider.IsPaused(); +} + +INT32 CNDDView::GetFrameCount() +{ + return m_Application->GetFrameCount(); +} + +void CNDDView::showOnScreenStats(bool show) +{ + m_showOnScreenStats = show; +} + +CInputEngine *CNDDView::GetInputEngine() +{ + return m_InputEngine; +} + +//============================================================================== +/** + * Generates an event in the presentation. + */ +void CNDDView::GoToSlideByName(const char *elementPath, const char *slideName) +{ + if (m_Application) { + if (!elementPath || !slideName) + return; + + CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); + IScriptBridge *theBridge = thePresentation->GetScriptBridgeQml(); + + if (!theBridge) + return; + + theBridge->GotoSlide(elementPath, slideName, SScriptEngineGotoSlideArgs()); + } +} + +void CNDDView::GoToSlideByIndex(const char *elementPath, const int slideIndex) +{ + if (m_Application) { + if (!elementPath || slideIndex < 0) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.GotoSlideIndex(elementPath, slideIndex, SScriptEngineGotoSlideArgs()); + } +} + +void CNDDView::GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) +{ + if (m_Application) { + if (!elementPath) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.GotoSlideRelative(elementPath, next, wrap, SScriptEngineGotoSlideArgs()); + } +} + +bool CNDDView::GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) +{ + if (m_Application && elementPath) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + return theBridgeEngine.GetSlideInfo(elementPath, currentIndex, previousIndex, + currentName, previousName); + } + return false; +} + +void CNDDView::SetPresentationAttribute(const char *presId, const char *, const char *value) +{ + if (m_Application) { + if (!presId || !value) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.SetPresentationAttribute(presId, nullptr, value); + } +} + +bool CNDDView::RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + return theBridgeEngine.RegisterCallback(callbackType, func, inUserData); + } + + return false; +} + +void CNDDView::GoToTime(const char *elementPath, const float time) +{ + if (m_Application) { + if (!elementPath || time < 0.0) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.GotoTime(elementPath, time); + } +} + +void CNDDView::SetGlobalAnimationTime(qint64 inMilliSecs) +{ + if (m_Application) + m_Application->SetTimeMilliSecs(inMilliSecs); +} + +void CNDDView::SetDataInputValue(const QString &name, const QVariant &value) +{ + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.SetDataInputValue(name, value); +} + +void CNDDView::SetAttribute(const char *elementPath, const char *attributeName, const char *value) +{ + if (m_Application) { + if (!elementPath || !attributeName || !value) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.SetAttribute(elementPath, attributeName, value); + } +} + +bool CNDDView::GetAttribute(const char *elementPath, const char *attributeName, void *value) +{ + if (m_Application) { + if (!elementPath || !attributeName || !value) + return false; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + return theBridgeEngine.GetAttribute(elementPath, attributeName, (char *)value); + } + + return false; +} + +void CNDDView::FireEvent(const char *element, const char *evtName) +{ + if (m_Application) { + if (!element || !evtName) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.FireEvent(element, evtName); + } +} + +bool CNDDView::PeekCustomAction(char *&outElementPath, char *&outActionName) +{ + bool actionAvailable = true; + + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + + Q3DStudio::TElement *theElement = NULL; + actionAvailable = theBridgeEngine.PeekSignal(theElement, outActionName); + if (actionAvailable && theElement) + outElementPath = (char *)theElement->m_Path.c_str(); + } + + return actionAvailable; +} + +void CNDDView::FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) +{ + if (m_Application) { + CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); + TElement *theScene = thePresentation->GetRoot(); + if (inArgument.empty()) { + thePresentation->FireEvent(inEventType, theScene, NULL, NULL, ATTRIBUTETYPE_NONE, + ATTRIBUTETYPE_NONE); + } else { + UVariant inArg; + inArg.m_StringHandle = thePresentation->GetStringTable().GetHandle(inArgument.c_str()); + thePresentation->FireEvent(inEventType, theScene, &inArg, NULL, ATTRIBUTETYPE_STRING, + ATTRIBUTETYPE_NONE); + } + } +} + +qt3ds::foundation::Option CNDDView::GetPresentationSize() +{ + if (m_Application) { + CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); + if (thePresentation) + return thePresentation->GetSize(); + } + return qt3ds::foundation::Empty(); +} + +//============================================================================== +/** + * Perform the initialization steps prior to loading any presentation. + */ +void CNDDView::BootupPreGraphicsInitObjects() +{ + qCInfo(TRACE_INFO) << "CNDDView::BootupPreGraphicsInitObjects: DoInitialize"; + // Create engines and runtime + const eastl::string &theAppDir = QCoreApplication::applicationDirPath().toLatin1().constData(); + + m_RuntimeFactoryCore = qt3ds::render::IQt3DSRenderFactoryCore::CreateRenderFactoryCore( + theAppDir.c_str(), m_WindowSystem, m_TimeProvider); + m_ApplicationCore = qt3ds::runtime::IApplicationCore::CreateApplicationCore(*m_RuntimeFactoryCore, + theAppDir.c_str()); + + if (m_ApplicationCore && m_visitor) + m_ApplicationCore->setAssetVisitor(m_visitor); + + m_InputEngine = static_cast(CreateInputEngine()); + Q3DStudio_ASSERT(m_InputEngine != NULL); + + qCInfo(TRACE_INFO) << "CNDDView::DoInitialize: Successfully initialized!"; +} + +void CNDDView::setAssetVisitor(qt3ds::Qt3DSAssetVisitor *v) +{ + m_visitor = v; + if (m_ApplicationCore) + m_ApplicationCore->setAssetVisitor(v); +} + +INDDView &INDDView::Create(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer) +{ + return *QT3DS_NEW(qt3ds::render::g_BaseAllocator, CNDDView)(inProvider, inWindowSystem, + inAudioPlayer); +} + +QINDDViewSignalProxy *INDDView::signalProxy() +{ + return &m_SignalProxy; +} + +//============================================================================== +/** + * CTegraApplication + */ +CTegraApplication::CTegraApplication(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer) +{ + m_NDDView = INDDView::Create(inProvider, inWindowSystem, inAudioPlayer); +} + +CTegraApplication::~CTegraApplication() +{ +} + +bool CTegraApplication::BeginLoad(const QString &sourcePath, const QStringList &variantList) +{ +#ifndef QT3DS_NO_SEARCH_PATH + // We need these later on in case we try to load any files + // such as images + NvFSAppendSearchPath("/res"); + NvFSAppendSearchPath("/res/.."); + NvFSAppendSearchPath("/data"); +#endif + + bool theResult = false; + + qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Attempting presentation beginload"; + + if (!sourcePath.isEmpty()) { + // If there was a presentation file then we have to load it or something failed. + if (m_NDDView->BeginLoad(sourcePath, variantList)) { + qCInfo(TRACE_INFO) + << "CTegraApplication::BeginLoad: Successfully begin loading presentation: " + << sourcePath; + theResult = true; + } else { + qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Failed to load presentation: " + << sourcePath; + theResult = false; + } + } else { + // If there wasn't, then we are still in an OK state. + qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Presentation file not provided"; + theResult = true; + } + + qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: End beginload"; + return theResult; +} + +bool CTegraApplication::InitializeGraphics(const QSurfaceFormat &format) +{ + return m_NDDView->InitializeGraphics(format); +} + +void CTegraApplication::Render() +{ + m_NDDView->Render(); +} + +bool CTegraApplication::HandleMessage(const QEvent *inEvent) +{ + return m_NDDView->HandleMessage(inEvent); +} +} // namespace Q3DStudio + diff --git a/src/Runtime/Source/engine/Qt3DSTegraApplication.h b/src/Runtime/Source/engine/Qt3DSTegraApplication.h new file mode 100644 index 00000000..91233355 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSTegraApplication.h @@ -0,0 +1,322 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_TEGRA_APPLICATION_H +#define QT3DS_TEGRA_APPLICATION_H + +#include "EnginePrefix.h" +#include "Qt3DSIStateful.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSOption.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSWindowSystem.h" +#include "Qt3DSTimer.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSRenderRuntimeBinding.h" +#include +#include + +//============================================================================== +// Namespace +//============================================================================== + +typedef void (*qml_Function)(void *inUserData); + +class QINDDViewSignalProxy : public QObject +{ + Q_OBJECT +Q_SIGNALS: + void SigSlideEntered(const QString &elementPath, unsigned int index, const QString &name); + void SigSlideExited(const QString &elementPath, unsigned int index, const QString &name); +}; + +namespace qt3ds { +class Qt3DSAssetVisitor; +} + +namespace qt3ds { +namespace render { +class NVRenderContext; +} +} + +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class CTegraInputEngine; +class CTegraRenderEngine; +class IScene; +class CInputEngine; +class IAudioPlayer; + +class ITegraRenderStateManager : public IStatefulStackBase +{ +protected: + virtual ~ITegraRenderStateManager() {} +public: + virtual void SetViewport(INT32 inX, INT32 inY, INT32 inWidth, INT32 inHeight) = 0; + virtual void SetScissorTestEnabled(bool inValue) = 0; + virtual void SaveAllState() = 0; + virtual void RestoreAllState() = 0; +}; + +struct TegraRenderScaleModes +{ + enum Enum { + ExactSize = 0, // Ensure the viewport is exactly same size as application + ScaleToFit = 1, // Resize viewport keeping aspect ratio + ScaleToFill = 2, // Resize viewport to entire window + }; +}; + +struct TegraRenderShadeModes +{ + enum Enum { + Shaded = 0, // Geometry is shaded only + ShadedWireframe = 1, // Wireframe is drawn on top shaded geometry + Wireframe = 2, // Wireframe only + }; +}; + +class ITegraApplicationRenderEngine +{ +protected: + virtual ~ITegraApplicationRenderEngine() {} + +public: + virtual void SetViewport(INT32 inX, INT32 inY, INT32 inWidth, INT32 inHeight) = 0; + virtual void SetApplicationViewport(const qt3ds::render::NVRenderRect &inViewport) = 0; + virtual void ensureRenderTarget() = 0; + virtual void CheckResize(bool inForce, IPresentation &inActivePresentation) = 0; + virtual BOOL LoadShaderCache(const CHAR *inFilePath) = 0; + virtual void AbandonLoadingImages(IScene &inScene) = 0; + virtual BOOL IsPickValid(FLOAT &outX, FLOAT &outY, + const IPresentation &inPresentation) const = 0; + virtual void SetScaleMode(TegraRenderScaleModes::Enum inScale) = 0; + virtual void SetShadeMode(TegraRenderShadeModes::Enum inShade) = 0; + virtual TegraRenderScaleModes::Enum GetScaleMode() const = 0; + + // TODO: To be removed, not used anywhere anymore + void CycleScaleMode() + { + int mode = (int)GetScaleMode(); + mode = (mode + 1) % 3; + SetScaleMode((TegraRenderScaleModes::Enum)mode); + } + + virtual ITegraRenderStateManager &GetTegraRenderStateManager() = 0; + virtual qt3ds::render::NVRenderContext &GetRenderContext() = 0; + virtual void SetMatteColor(qt3ds::foundation::Option inColor) = 0; + virtual void EnableRenderRotation(bool inEnable) = 0; + virtual void SetWriteOutShaderCache(bool inWriteOutShaderCache) = 0; + virtual void Release() = 0; + virtual void RenderText2D(FLOAT x, FLOAT y, qt3ds::foundation::Option inColor, + const char *text) = 0; + virtual void RenderGpuProfilerStats(FLOAT x, FLOAT y, + qt3ds::foundation::Option inColor) = 0; +}; + +class INDDView : public qt3ds::foundation::NVRefCounted +{ +public: + virtual ~INDDView(){} + +public: // loading + virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; + virtual bool HasOfflineLoadingCompleted() = 0; + virtual bool InitializeGraphics(const QSurfaceFormat &format) = 0; + + virtual void Cleanup() = 0; + + virtual bool CanRender() = 0; + + virtual void Render() = 0; + + virtual bool WasLastFrameDirty() = 0; + + virtual bool HandleMessage(const QEvent *inEvent) = 0; + + virtual void Pause() = 0; + virtual void UnPause() = 0; + virtual bool IsPaused() = 0; + virtual INT32 GetFrameCount() = 0; + virtual void showOnScreenStats(bool) = 0; + +public: // Input engine access + virtual CInputEngine *GetInputEngine() = 0; + // Only valid after InitializeGraphics + virtual ITegraApplicationRenderEngine *GetTegraRenderEngine() = 0; + +public: + virtual void GoToSlideByName(const char *elementPath, const char *slideName) = 0; + virtual void GoToSlideByIndex(const char *elementPath, const int slideIndex) = 0; + virtual void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) = 0; + virtual bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) = 0; + virtual void SetPresentationAttribute(const char *presId, const char *, const char *value) = 0; + virtual void GoToTime(const char *elementPath, const float time) = 0; + virtual void SetGlobalAnimationTime(qint64 inMilliSecs) = 0; + virtual void SetDataInputValue(const QString &name, const QVariant &value) = 0; + virtual void SetAttribute(const char *elementPath, const char *attributeName, + const char *value) = 0; + virtual bool GetAttribute(const char *elementPath, const char *attributeName, void *value) = 0; + virtual void FireEvent(const char *element, const char *evtName) = 0; + virtual bool PeekCustomAction(char *&outElementPath, char *&outActionName) = 0; + virtual bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) = 0; + virtual void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) = 0; + virtual qt3ds::foundation::Option GetPresentationSize() = 0; + + virtual void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) = 0; + +public: + static INDDView &Create(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer = NULL); + +public: + QINDDViewSignalProxy *signalProxy(); +private: + QINDDViewSignalProxy m_SignalProxy; +}; + +class CTegraApplication +{ + //============================================================================== + // Fields + //============================================================================== +private: + qt3ds::foundation::NVScopedRefCounted m_NDDView; + +public: + CTegraApplication(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer = 0); + virtual ~CTegraApplication(); + // loading + bool BeginLoad(const QString &sourcePath, const QStringList &variantList); + // asynchronous BeginLoad completed? That only valid for binary presentation, for text + // presentation, always true + bool HasOfflineLoadingCompleted() { return m_NDDView->HasOfflineLoadingCompleted(); } + // Invokes m_ApplicationCore->CreateApplication(), a blocking function ensures binary loading + // completed + bool InitializeGraphics(const QSurfaceFormat& format); + + void Cleanup() { m_NDDView->Cleanup(); } + bool CanRender() { return m_NDDView->CanRender(); } + void Render(); + bool WasLastFrameDirty() { return m_NDDView->WasLastFrameDirty(); } + + bool HandleMessage(const QEvent *inEvent); + void Pause() { m_NDDView->Pause(); } + void UnPause() { m_NDDView->UnPause(); } + bool IsPaused() { return m_NDDView->IsPaused(); } + INT32 GetFrameCount() { return m_NDDView->GetFrameCount(); } + +public: + CInputEngine *GetInputEngine() { return m_NDDView->GetInputEngine(); } + // Only valid after InitializeGraphics + ITegraApplicationRenderEngine *GetTegraRenderEngine() + { + return m_NDDView->GetTegraRenderEngine(); + } + +public: + void GoToSlideByName(const char *elementPath, const char *slideName) + { + m_NDDView->GoToSlideByName(elementPath, slideName); + } + void GoToSlideByIndex(const char *elementPath, const int slideIndex) + { + m_NDDView->GoToSlideByIndex(elementPath, slideIndex); + } + void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) + { + m_NDDView->GoToSlideRelative(elementPath, next, wrap); + } + bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) + { + return m_NDDView->GetSlideInfo(elementPath, currentIndex, previousIndex, + currentName, previousName); + } + void SetPresentationAttribute(const char *presId, const char *, const char *value) + { + m_NDDView->SetPresentationAttribute(presId, nullptr, value); + } + void GoToTime(const char *elementPath, const float time) + { + m_NDDView->GoToTime(elementPath, time); + } + void SetGlobalAnimationTime(qint64 inMilliSecs) + { + m_NDDView->SetGlobalAnimationTime(inMilliSecs); + } + void SetDataInputValue(const QString &name, const QVariant &value) + { + m_NDDView->SetDataInputValue(name, value); + } + void SetAttribute(const char *elementPath, const char *attributeName, const char *value) + { + m_NDDView->SetAttribute(elementPath, attributeName, value); + } + bool GetAttribute(const char *elementPath, const char *attributeName, void *value) + { + return m_NDDView->GetAttribute(elementPath, attributeName, value); + } + void FireEvent(const char *element, const char *evtName) + { + m_NDDView->FireEvent(element, evtName); + } + bool PeekCustomAction(char *&outElementPath, char *&outActionName) + { + return m_NDDView->PeekCustomAction(outElementPath, outActionName); + } + bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) + { + return m_NDDView->RegisterScriptCallback(callbackType, func, inUserData); + }; + void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) + { + m_NDDView->FireEvent(inEventType, inArgument); + } + qt3ds::foundation::Option GetPrimaryPresentationSize() + { + return m_NDDView->GetPresentationSize(); + } + qt3ds::foundation::NVScopedRefCounted getNDDView() + { + return m_NDDView; + } +}; +} // namespace Q3DStudio + +#endif // QT3DS_TEGRA_APPLICATION_H diff --git a/src/Runtime/Source/engine/Qt3DSTegraInputEngine.cpp b/src/Runtime/Source/engine/Qt3DSTegraInputEngine.cpp new file mode 100644 index 00000000..bb9a7f95 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSTegraInputEngine.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "EnginePrefix.h" +#include "Qt3DSTegraInputEngine.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * XXX + */ +CTegraInputEngine::CTegraInputEngine() +{ +} + +//============================================================================== +/** + * XXX + */ +CTegraInputEngine::~CTegraInputEngine() +{ +} + +//============================================================================== +/** + * Returns the structure that contains the input information for the current frame. + */ +SInputFrame &CTegraInputEngine::GetInputFrame() +{ + return m_InputFrame; +} + +//============================================================================== +/** + * Handles the input message. + */ +void CTegraInputEngine::HandleMessage(const QEvent *inEvent, + ITegraApplicationRenderEngine &inRenderEngine, + CPresentation *inPresentation) +{ + static bool s_PointerWasDown = false; + + if (NULL == inPresentation) + return; + + switch (inEvent->type()) { + + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + { + const QMouseEvent *event = static_cast(inEvent); + + QPointF pos = event->localPos(); + FLOAT x = pos.x(); + FLOAT y = pos.y(); + + const bool pressed = inEvent->type() == QEvent::MouseButtonPress; + + if (inRenderEngine.IsPickValid(x, y, *inPresentation)) { + // printf( "INPUT x %ld y %ld\n", (int)x, (int)y ); + SetPickInput(x, y, (pressed || s_PointerWasDown) ? true : false); + + if (pressed) { + if (s_PointerWasDown) + SetPickFlags(LMOUSE_DOWN); + else + SetPickFlags(LMOUSE_PRESSED); + + s_PointerWasDown = true; + } else { + if (s_PointerWasDown) + SetPickFlags(LMOUSE_RELEASED); + else + SetPickFlags(LMOUSE_UP); + + s_PointerWasDown = false; + } + } else { + if (s_PointerWasDown) + SetPickFlags(LMOUSE_RELEASED); + else + SetPickFlags(LMOUSE_UP); + + s_PointerWasDown = false; + } + } + break; + default: + break; + } +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/engine/Qt3DSTegraInputEngine.h b/src/Runtime/Source/engine/Qt3DSTegraInputEngine.h new file mode 100644 index 00000000..14047f16 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSTegraInputEngine.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_TEGRA_INPUT_ENGINE_H +#define QT3DS_TEGRA_INPUT_ENGINE_H + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSInputEngine.h" +#include "Qt3DSTegraApplication.h" +#include "Qt3DSInputEventTypes.h" +#include "Qt3DSPresentation.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class CTegraRenderEngine; +class CPresentation; +class ITegraApplicationRenderEngine; + +//============================================================================== +/** +* @class CTegraInputEngine +* @brief +*/ +class CTegraInputEngine : public CInputEngine +{ + //============================================================================== + // Fields + //============================================================================== + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CTegraInputEngine(); + virtual ~CTegraInputEngine(); + +public: // Access + SInputFrame &GetInputFrame() override; + + void HandleMessage(const QEvent *inEvent, ITegraApplicationRenderEngine &inRenderEngine, + CPresentation *inPresentation); +}; + +} // namespace Q3DStudio + +#endif // QT3DS_TEGRA_INPUT_ENGINE_H diff --git a/src/Runtime/Source/engine/Qt3DSWindowSystem.h b/src/Runtime/Source/engine/Qt3DSWindowSystem.h new file mode 100644 index 00000000..173dd837 --- /dev/null +++ b/src/Runtime/Source/engine/Qt3DSWindowSystem.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_WINDOW_SYSTEM_H +#define QT3DS_WINDOW_SYSTEM_H + +#include + +namespace Q3DStudio { + +struct SEGLInfo; + +class IWindowSystem +{ +protected: + virtual ~IWindowSystem() {} +public: + virtual QSize GetWindowDimensions() = 0; + virtual void SetWindowDimensions(const QSize &inSize) = 0; + // For platforms that support it, we get the egl info for render plugins + // Feel free to return NULL. + virtual SEGLInfo *GetEGLInfo() = 0; + // on some systems we allow our default render target to be a offscreen buffer + // otherwise return 0; + virtual int GetDefaultRenderTargetID() = 0; + // returns the depth buffer bit count for the render window + virtual int GetDepthBitCount() = 0; +}; +} + +#endif diff --git a/src/Runtime/Source/event/EventFactory.cpp b/src/Runtime/Source/event/EventFactory.cpp new file mode 100644 index 00000000..4bf776c6 --- /dev/null +++ b/src/Runtime/Source/event/EventFactory.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "EventFactory.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/StringTable.h" +#include "foundation/Utils.h" + +using namespace qt3ds::evt; + +typedef char TEventChar; +using qt3ds::QT3DSU32; + +class CInitableRegisteredStr : public Qt3DSEventSystemRegisteredStr +{ +public: + CInitableRegisteredStr(const TEventStr inString) { m_Data = inString; } +}; + +CFactory &CFactory::Create(qt3ds::NVFoundationBase &inFoundation) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), CFactory)(inFoundation); +} + +CFactory::CFactory(qt3ds::NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , m_Allocator(inFoundation.getAllocator(), "event factory allocator") + , m_StringTable(qt3ds::foundation::IStringTable::CreateStringTable(inFoundation.getAllocator())) +{ +} + +CFactory::~CFactory() +{ +} + +Qt3DSEventSystemEvent &CFactory::CreateEvent(int inNumData) +{ + // Ensure num data is in range + inNumData = qt3ds::NVMax(0, inNumData); + // Ensure we can actually allocate something that big + QT3DSU32 dataSize = static_cast( + qt3ds::NVMin((size_t)inNumData * sizeof(Qt3DSEventSystemEventData), + TEventAllocator::getSlabSize() - sizeof(Qt3DSEventSystemEvent))); + // get the actual num data after safety checks. + inNumData = (int)(dataSize / sizeof(Qt3DSEventSystemEventData)); + + QT3DSU32 allocSize = sizeof(Qt3DSEventSystemEvent) + inNumData * sizeof(Qt3DSEventSystemEventData); + + Qt3DSEventSystemEvent *theEvent = (Qt3DSEventSystemEvent *)m_Allocator.allocate( + allocSize, "Event allocation", __FILE__, __LINE__); + theEvent->m_NumData = inNumData; + theEvent->m_Data = reinterpret_cast(((qt3ds::QT3DSU8 *)theEvent) + + sizeof(Qt3DSEventSystemEvent)); + + // Initialize the event data to zero so that a free event won't cause a calamity. + qt3ds::intrinsics::memZero(theEvent->m_Data, dataSize); + + return *theEvent; +} + +size_t CFactory::GetMaxNumEventData() +{ + return m_Allocator.getSlabSize() - sizeof(Qt3DSEventSystemEvent); +} + +size_t CFactory::GetMaxStrLength() +{ + return m_Allocator.getSlabSize(); +} + +void CFactory::ReleaseOutstandingEvents() +{ + m_Allocator.reset(); +} + +Qt3DSEventSystemRegisteredStr CFactory::RegisterStr(TEventStr inSrc) +{ + return CInitableRegisteredStr(m_StringTable->RegisterStr(inSrc)); +} + +TEventStr CFactory::AllocateStr(TEventStr inSrc) +{ + size_t theSizeInByte = sizeof(TEventChar) * (strlen(qt3ds::foundation::nonNull(inSrc)) + 1); + theSizeInByte = qt3ds::NVMin(theSizeInByte, TEventAllocator::getSlabSize()); + + TEventChar *theNewString = (TEventChar *)m_Allocator.allocate( + theSizeInByte, "Qt3DS::evt::CFactory::UnManagedString", __FILE__, __LINE__); + + if (theNewString) + memcpy(theNewString, inSrc, theSizeInByte); + + theNewString[theSizeInByte - 1] = 0; + + return theNewString; +} + +TEventStr CFactory::AllocateStr(int inLength) +{ + ++inLength; + int safeLen = (int)qt3ds::NVMin((size_t)inLength, TEventAllocator::getSlabSize()); + // Either give the users what they ask for or return nothing. + if (safeLen != inLength) + return NULL; + + void *retval = m_Allocator.allocate(inLength * sizeof(TEventChar), + "Qt3DS::evt::CFactory::UnManagedString", __FILE__, __LINE__); + qt3ds::intrinsics::memZero(retval, inLength); + return (TEventStr)retval; +} + +void CFactory::Release() +{ + this->~CFactory(); + QT3DS_FREE(m_Foundation.getAllocator(), this); +} diff --git a/src/Runtime/Source/event/EventFactory.h b/src/Runtime/Source/event/EventFactory.h new file mode 100644 index 00000000..10fe6b72 --- /dev/null +++ b/src/Runtime/Source/event/EventFactory.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EVENT_FACTORY_H +#define EVENT_FACTORY_H + +#include "EventSystem.h" +#include "EventPollingSystem.h" + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/FastAllocator.h" + +namespace qt3ds { +class NVFoundationBase; +namespace foundation { + class IStringTable; +} +} + +namespace qt3ds { +namespace evt { + + class CEventProviderRefCounted; + + class CFactory : public IEventFactory + { + private: + explicit CFactory(qt3ds::NVFoundationBase &inFoundation); + virtual ~CFactory(); + + CFactory &operator=(const CFactory &) { return *this; } + public: + // Interfaces from IEventFactory + Qt3DSEventSystemEvent &CreateEvent(int inNumData) override; + size_t GetMaxNumEventData() override; + size_t GetMaxStrLength() override; + + Qt3DSEventSystemRegisteredStr RegisterStr(TEventStr inSrc) override; + // Null terminates if strlen(inSrc) > getMaxStrLength + TEventStr AllocateStr(TEventStr inSrc) override; + + // Returns null if inLength > getMaxStrLength + TEventStr AllocateStr(int inLength) override; + + void ReleaseOutstandingEvents(); + void Release(); + + static CFactory &Create(qt3ds::NVFoundationBase &inFoundation); + + private: + typedef qt3ds::foundation::SFastAllocator<> TEventAllocator; + + qt3ds::NVFoundationBase &m_Foundation; + TEventAllocator m_Allocator; + qt3ds::foundation::NVScopedRefCounted m_StringTable; + }; +} +} + +#endif // EVENT_FACTORY_H diff --git a/src/Runtime/Source/event/EventPoller.cpp b/src/Runtime/Source/event/EventPoller.cpp new file mode 100644 index 00000000..a8115953 --- /dev/null +++ b/src/Runtime/Source/event/EventPoller.cpp @@ -0,0 +1,375 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAllocator.h" + +#include "EventPoller.h" +#include "EventFactory.h" + +#define MAX_EVENTS 256 + +using namespace qt3ds::evt; +using qt3ds::QT3DSU32; + +IEventSystem &IEventSystem::Create(qt3ds::NVFoundationBase &inFoundation) +{ + return CPoller::Create(inFoundation); +} + +CPoller &CPoller::Create(qt3ds::NVFoundationBase &inFoundation) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), CPoller)(inFoundation); +} + +CPoller::~CPoller() +{ + for (QT3DSU32 idx = 0, end = m_Providers.size(); idx < end; ++idx) + m_Providers[idx].first->Release(); + m_Providers.clear(); + ReleaseEvents(); + m_EventFactory.Release(); +} + +void CPoller::ReleaseEvents() +{ + m_EventFactory.ReleaseOutstandingEvents(); + + m_EventList.clear(); + m_EventIndex = 0; +} + +static void AddProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) +{ + CPoller *thePoller = reinterpret_cast(inPoller); + thePoller->AddProvider(*thePoller->GetOrCreateEventProviderWrapper(inProvider)); +} + +static void RemoveProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) +{ + CPoller *thePoller = reinterpret_cast(inPoller); + CPoller::TProvider theProvider = thePoller->GetEventProviderWrapper(inProvider); + if (theProvider) + thePoller->RemoveProvider(*theProvider); + thePoller->ReleaseEventProviderWrapper(inProvider); +} + +static int IgnoreProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) +{ + CPoller *thePoller = reinterpret_cast(inPoller); + CPoller::TProvider theProvider = thePoller->GetEventProviderWrapper(inProvider); + if (theProvider) + return thePoller->IgnoreProvider(*theProvider); + return 0; +} + +static int ActivateProviderFn(void *inPoller, Qt3DSEventSystemEventProvider inProvider) +{ + CPoller *thePoller = reinterpret_cast(inPoller); + CPoller::TProvider theProvider = thePoller->GetEventProviderWrapper(inProvider); + if (theProvider) + return thePoller->ActivateProvider(*theProvider); + return 0; +} + +CPoller::CPoller(qt3ds::NVFoundationBase &inFoundation) + : mRefCount(0) + , m_Foundation(inFoundation) + , m_EventFactory(CFactory::Create(inFoundation)) + , m_Providers(inFoundation.getAllocator(), "CPoller::m_Providers") + , m_EventList(inFoundation.getAllocator(), "CPoller::m_EventList") + , m_EventIndex(0) + , m_EventFetched(false) +{ + m_CInterface.m_Poller = this; + m_CInterface.addProvider = AddProviderFn; + m_CInterface.removeProvider = RemoveProviderFn; + m_CInterface.ignoreProvider = IgnoreProviderFn; + m_CInterface.activateProvider = ActivateProviderFn; +} + +struct SProviderSearch +{ + IEventProvider *m_Provider; + SProviderSearch(IEventProvider &inProvider) + : m_Provider(&inProvider) + { + } + bool operator()(const eastl::pair &item) + { + return item.first == m_Provider; + } +}; + +void CPoller::AddProvider(IEventProvider &inProvider) +{ + TProviderList::iterator iter = + eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); + if (iter == m_Providers.end()) + m_Providers.push_back(eastl::make_pair(&inProvider, true)); +} + +void CPoller::RemoveProvider(IEventProvider &inProvider) +{ + TProviderList::iterator thePos = + eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); + if (thePos != m_Providers.end()) + m_Providers.erase(thePos); +} + +bool CPoller::IgnoreProvider(IEventProvider &inProvider) +{ + TProviderList::iterator thePos = + eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); + if (thePos != m_Providers.end()) { + thePos->second = false; + return true; + } + return false; +} + +bool CPoller::ActivateProvider(IEventProvider &inProvider) +{ + TProviderList::iterator thePos = + eastl::find_if(m_Providers.begin(), m_Providers.end(), SProviderSearch(inProvider)); + if (thePos != m_Providers.end()) { + thePos->second = true; + return true; + } + return false; +} + +Qt3DSEventSystemEvent *CPoller::GetNextEvent(bool inAllowResetBuffer) +{ + if (m_EventIndex < m_EventList.size()) { + Qt3DSEventSystemEvent *retval = m_EventList[m_EventIndex]; + ++m_EventIndex; + return retval; + } + if (inAllowResetBuffer) { + ReleaseEvents(); + } + size_t theNewEventCount = 0; + for (QT3DSU32 idx = 0, end = m_Providers.size(); idx < end; ++idx) { + if (m_Providers[idx].second) { + Qt3DSEventSystemEvent *evtBuffer[MAX_EVENTS]; + for (QT3DSU32 numEvents = (QT3DSU32)(m_Providers[idx].first) + ->GetNextEvents(m_EventFactory, evtBuffer, MAX_EVENTS); + numEvents; + numEvents = (QT3DSU32)(m_Providers[idx].first) + ->GetNextEvents(m_EventFactory, evtBuffer, MAX_EVENTS)) { + m_EventList.insert(m_EventList.end(), evtBuffer, evtBuffer + numEvents); + ++theNewEventCount; + } + } + } + if (theNewEventCount) + return GetNextEvent(inAllowResetBuffer); + + return NULL; +} + +size_t CPoller::GetNextEvents(Qt3DSEventSystemEvent **outBuffer, size_t bufLen) +{ + m_EventFetched = true; + size_t bufIdx = 0; + bool theAllowResetBuffer = true; + for (; bufIdx < bufLen; ++bufIdx) { + Qt3DSEventSystemEvent *evt = GetNextEvent(theAllowResetBuffer); + if (!evt) + break; + theAllowResetBuffer = false; + outBuffer[bufIdx] = evt; + } + return bufIdx; +} + +IEventFactory &CPoller::GetEventFactory() +{ + return m_EventFactory; +} + +Qt3DSEventSystemEventPoller *CPoller::GetCInterface() +{ + return &m_CInterface; +} + +bool CPoller::GetAndClearEventFetchedFlag() +{ + bool theOld = m_EventFetched; + m_EventFetched = false; + return theOld; +} + +void CPoller::PurgeEvents() +{ + // Get events from providers and drop, + // so the providers need not to provide an additional interface for clear events + static const size_t EVENTS_NUM_ONCE_CLEAR = 512; + Qt3DSEventSystemEvent *theEvents[EVENTS_NUM_ONCE_CLEAR]; + GetNextEvents(theEvents, EVENTS_NUM_ONCE_CLEAR); + ReleaseEvents(); +} + +void CPoller::addRef() +{ + qt3ds::foundation::atomicIncrement(&mRefCount); +} + +void CPoller::release() +{ + qt3ds::QT3DSI32 value = qt3ds::foundation::atomicDecrement(&mRefCount); + if (value <= 0) { + qt3ds::NVAllocatorCallback &alloc(m_Foundation.getAllocator()); + this->~CPoller(); + QT3DS_FREE(alloc, this); + } +} + +struct SProviderFinder +{ + void *m_Key; + SProviderFinder(void *k) + : m_Key(k) + { + } + bool operator()(const CPoller::TCEventProviderPair &inPair) + { + if (inPair.first == m_Key) + return true; + return false; + } +}; + +static Qt3DSEventSystemEvent *CreateEventFn(void *inFactory, int numData) +{ + IEventFactory *theFactory = reinterpret_cast(inFactory); + return &theFactory->CreateEvent(numData); +} + +static size_t MaxNumEventDataFn(void *inFactory) +{ + IEventFactory *theFactory = reinterpret_cast(inFactory); + return theFactory->GetMaxNumEventData(); +} + +static size_t MaxStrLenFn(void *inFactory) +{ + IEventFactory *theFactory = reinterpret_cast(inFactory); + return theFactory->GetMaxStrLength(); +} + +static Qt3DSEventSystemRegisteredStr RegisterStrFn(void *inFactory, Qt3DSEventSystemStr inStr) +{ + IEventFactory *theFactory = reinterpret_cast(inFactory); + return theFactory->RegisterStr(inStr); +} + +static Qt3DSEventSystemStr AllocateStrFn(void *inFactory, Qt3DSEventSystemStr inStr) +{ + IEventFactory *theFactory = reinterpret_cast(inFactory); + return theFactory->AllocateStr(inStr); +} + +static Qt3DSEventSystemStr AllocateStrLenFn(void *inFactory, int len) +{ + IEventFactory *theFactory = reinterpret_cast(inFactory); + return theFactory->AllocateStr(len); +} + +struct SWrappedProvider : public IEventProvider +{ + Qt3DSEventSystemEventProvider m_Provider; + SWrappedProvider(Qt3DSEventSystemEventProvider prov) + : m_Provider(prov) + { + } + + size_t GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, + size_t bufLen) override + { + if (m_Provider.m_Provider) { + Qt3DSEventSystemEventFactory theFactory; + theFactory.m_Factory = &inFactory; + theFactory.createEvent = CreateEventFn; + theFactory.getMaxNumEventData = MaxNumEventDataFn; + theFactory.getMaxStrLength = MaxStrLenFn; + theFactory.registerStr = RegisterStrFn; + theFactory.allocateStr = AllocateStrFn; + theFactory.allocateStrLen = AllocateStrLenFn; + return m_Provider.getNextEvents(m_Provider.m_Provider, theFactory, outBuffer, bufLen); + } + return 0; + } + + void Release() override + { + if (m_Provider.m_Provider) + m_Provider.release(m_Provider.m_Provider); + delete this; + } +}; + +CPoller::TProvider CPoller::GetEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider) +{ + TCEventProviderList::iterator iter = eastl::find_if( + m_CEventProviders.begin(), m_CEventProviders.end(), SProviderFinder(inProvider.m_Provider)); + if (iter != m_CEventProviders.end()) + return iter->second; + return TProvider(); +} + +CPoller::TProvider CPoller::GetOrCreateEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider) +{ + TCEventProviderList::iterator iter = eastl::find_if( + m_CEventProviders.begin(), m_CEventProviders.end(), SProviderFinder(inProvider.m_Provider)); + if (iter == m_CEventProviders.end()) { + TProvider retval = new SWrappedProvider(inProvider); + m_CEventProviders.push_back(eastl::make_pair(inProvider.m_Provider, retval)); + return retval; + } + return iter->second; +} + +void CPoller::ReleaseEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider) +{ + TCEventProviderList::iterator iter = eastl::find_if( + m_CEventProviders.begin(), m_CEventProviders.end(), SProviderFinder(inProvider.m_Provider)); + if (iter != m_CEventProviders.end()) { + SWrappedProvider &wrappedProvider = static_cast(*iter->second); + wrappedProvider.m_Provider.m_Provider = NULL; + m_CEventProviders.erase( + iter); // deletes the wrapper but does not release the wrapped provider. + } +} diff --git a/src/Runtime/Source/event/EventPoller.h b/src/Runtime/Source/event/EventPoller.h new file mode 100644 index 00000000..99ac27d6 --- /dev/null +++ b/src/Runtime/Source/event/EventPoller.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EVENT_POLLER_H +#define EVENT_POLLER_H + +#include + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSContainers.h" + +#include "EventSystem.h" +#include "EventPollingSystem.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace evt { + + class CFactory; + + class CPoller : public IEventSystem + { + public: + typedef IEventProvider *TProvider; + typedef qt3ds::foundation::nvvector> TProviderList; + typedef qt3ds::foundation::nvvector TEventList; + typedef eastl::pair TCEventProviderPair; + typedef eastl::vector TCEventProviderList; + + private: + explicit CPoller(qt3ds::NVFoundationBase &inFoundation); + virtual ~CPoller(); + + public: + // Providers once added are released if the poller goes out of scope. + void AddProvider(IEventProvider &inProvider) override; + void RemoveProvider(IEventProvider &inProvider) override; + bool IgnoreProvider(IEventProvider &inProvider) override; + bool ActivateProvider(IEventProvider &inProvider) override; + size_t GetNextEvents(Qt3DSEventSystemEvent **outBuffer, size_t bufLen) override; + IEventFactory &GetEventFactory() override; + Qt3DSEventSystemEventPoller *GetCInterface() override; + bool GetAndClearEventFetchedFlag() override; + void PurgeEvents() override; + + void ReleaseEvents(); + + void addRef() override; + void release() override; + + TProvider GetEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider); + TProvider GetOrCreateEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider); + void ReleaseEventProviderWrapper(Qt3DSEventSystemEventProvider inProvider); + + static CPoller &Create(qt3ds::NVFoundationBase &inFoundation); + + private: + Qt3DSEventSystemEvent *GetNextEvent(bool inAllowResetBuffer /* = true*/); + + qt3ds::QT3DSI32 mRefCount; + qt3ds::NVFoundationBase &m_Foundation; + CFactory &m_EventFactory; + TProviderList m_Providers; + TEventList m_EventList; + qt3ds::QT3DSU32 m_EventIndex; + Qt3DSEventSystemEventPoller m_CInterface; + TCEventProviderList m_CEventProviders; + bool m_EventFetched; + }; +} +} + +#endif // EVENT_POLLER_H diff --git a/src/Runtime/Source/event/EventPollingSystem.h b/src/Runtime/Source/event/EventPollingSystem.h new file mode 100644 index 00000000..4d414066 --- /dev/null +++ b/src/Runtime/Source/event/EventPollingSystem.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EVENT_SYSTEM_H +#define EVENT_SYSTEM_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSRefCounted.h" +#include "EventSystem.h" + +namespace qt3ds { +namespace evt { + + class CEventProviderRefCounted; + + class IEventSystem : public qt3ds::foundation::NVRefCounted + { + protected: + virtual ~IEventSystem() {} + public: + // Providers once added are released if the poller goes out of scope. + // Adding the same provider twice has no effect. + virtual void AddProvider(IEventProvider &inProvider) = 0; + + // removeProvider does not release the provider; callers are expected to release the + // provider themselves after calling remove provider. Calling remove provider + // with a provider that isn't in the system has no effect. + virtual void RemoveProvider(IEventProvider &inProvider) = 0; + + // Ignore events from this provider. Returns true if provider is added. + virtual bool IgnoreProvider(IEventProvider &inProvider) = 0; + + // Listen on this provider. Returns true if provider is added. + virtual bool ActivateProvider(IEventProvider &inProvider) = 0; + + // Get a set of events from the poller. The poller will simply run through and ask each + // provider + // for events and then begin returning the set of events. + // Note: this interface needs to set the event fetched flag. + virtual size_t GetNextEvents(Qt3DSEventSystemEvent **outBuffer, size_t bufLen) = 0; + + // Get the event factory used for this poller. + virtual IEventFactory &GetEventFactory() = 0; + + virtual Qt3DSEventSystemEventPoller *GetCInterface() = 0; + + // Get and clear the flag indicates whether GetNextEvents has been called after last call of + // this interface + // Note: the event fetched flag is set by GetNextEvents + virtual bool GetAndClearEventFetchedFlag() = 0; + + // Clear events in event system and events in all providers + virtual void PurgeEvents() = 0; + + static IEventSystem &Create(qt3ds::NVFoundationBase &inFoundation); + }; +} +} + +#endif // EVENT_SYSTEM_H diff --git a/src/Runtime/Source/event/EventSystem.h b/src/Runtime/Source/event/EventSystem.h new file mode 100644 index 00000000..a9e3dbc5 --- /dev/null +++ b/src/Runtime/Source/event/EventSystem.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MESSAGE_SYSTEM_H +#define MESSAGE_SYSTEM_H +#include +#include "EventSystemC.h" + +namespace qt3ds { +namespace evt { + + typedef Qt3DSEventSystemStr TEventStr; + + // Factory from the provider's perspective. + class IEventFactory + { + protected: + virtual ~IEventFactory() {} + public: + virtual Qt3DSEventSystemEvent &CreateEvent(int numData) = 0; + // Guaranteed to be at least 4K - sizeof(Qt3DSEventSystemEvent) + virtual size_t GetMaxNumEventData() = 0; + // Guaranteed to be at least 4K + virtual size_t GetMaxStrLength() = 0; + + virtual Qt3DSEventSystemRegisteredStr RegisterStr(TEventStr inSrc) = 0; + // Null terminates if strlen(inSrc) > getMaxStrLength + virtual TEventStr AllocateStr(TEventStr inSrc) = 0; + // Returns null if inLength > getMaxStrLength + virtual TEventStr AllocateStr(int inLength) = 0; + }; + + class IEventProvider + { + protected: + virtual ~IEventProvider() {} + public: + // Return the next N events, placed into the event buffer. + virtual size_t GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, + size_t bufLen) = 0; + virtual void Release() = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/event/EventSystemC.cpp b/src/Runtime/Source/event/EventSystemC.cpp new file mode 100644 index 00000000..8bfdb81c --- /dev/null +++ b/src/Runtime/Source/event/EventSystemC.cpp @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "EventSystemC.h" + +const char *PROVIDER_TABLE_ENTRY = "__provider_impl"; +const char *POLLER_TABLE_ENTRY = "__poller_impl"; \ No newline at end of file diff --git a/src/Runtime/Source/event/EventSystemC.h b/src/Runtime/Source/event/EventSystemC.h new file mode 100644 index 00000000..2517eae4 --- /dev/null +++ b/src/Runtime/Source/event/EventSystemC.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_EVENT_SYSTEM_C_H +#define QT3DS_EVENT_SYSTEM_C_H +#include //size_t + +// Interface we expect plugins to use in order to interace with the event system. +// This interface is design to avoid using c++ vtables and the C++ abi isn't stable +// across compilers. + +#ifdef _cplusplus +extern "C" { +#endif + +// Obnoxious long names to void namespace conflicts +enum QT3DSEventSystemEventTypes { + QT3DSEventSystemEventTypesNoData = 0, + QT3DSEventSystemEventTypesString = 1, + QT3DSEventSystemEventTypesNumber = 2, +}; + +typedef const char *Qt3DSEventSystemStr; + +typedef struct _Qt3DSEventSystemEventValue +{ + QT3DSEventSystemEventTypes m_Type; + double m_Number; + Qt3DSEventSystemStr m_String; +} Qt3DSEventSystemEventValue; + +typedef struct _Qt3DSEventSystemRegisteredStr +{ + Qt3DSEventSystemStr m_Data; +} Qt3DSEventSystemRegisteredStr; + +typedef struct _Qt3DSEventSystemEventData +{ + Qt3DSEventSystemRegisteredStr m_Name; + Qt3DSEventSystemEventValue m_Value; +} Qt3DSEventSystemEventData; + +typedef struct _Qt3DSEventSystemEvent +{ + Qt3DSEventSystemEventData *m_Data; // contiguous block of event data. + int m_NumData; +} Qt3DSEventSystemEvent; + +typedef Qt3DSEventSystemEvent *(*Qt3DSEventSystemEventFactoryCreateEventFn)(void *inFactory, + int numData); +typedef size_t (*Qt3DSEventSystemEventFactoryMaxNumEventDataFn)(void *inFactory); +typedef size_t (*Qt3DSEventSystemEventFactoryMaxStrLenFn)(void *inFactory); +typedef Qt3DSEventSystemRegisteredStr (*Qt3DSEventSystemEventFactoryRegisterStrFn)( + void *inFactory, Qt3DSEventSystemStr inStr); +typedef Qt3DSEventSystemStr (*Qt3DSEventSystemEventFactoryAllocateStrFn)(void *inFactory, + Qt3DSEventSystemStr inStr); +typedef Qt3DSEventSystemStr (*Qt3DSEventSystemEventFactoryAllocateStrLenFn)(void *inFactory, int len); + +// Factory from the provider's perspective. +typedef struct _Qt3DSEventSystemEventFactory +{ + void *m_Factory; + Qt3DSEventSystemEventFactoryCreateEventFn createEvent; + Qt3DSEventSystemEventFactoryMaxNumEventDataFn getMaxNumEventData; + Qt3DSEventSystemEventFactoryMaxStrLenFn getMaxStrLength; + Qt3DSEventSystemEventFactoryRegisterStrFn registerStr; + Qt3DSEventSystemEventFactoryAllocateStrFn allocateStr; + Qt3DSEventSystemEventFactoryAllocateStrLenFn allocateStrLen; + +} Qt3DSEventSystemEventFactory; + +typedef size_t (*Qt3DSEventSystemProviderGetNextEventsFn)(void *inProvider, + Qt3DSEventSystemEventFactory inFactory, + Qt3DSEventSystemEvent **outBuffer, + size_t outBufLen); +typedef void (*Qt3DSEventSystemProviderReleaseFn)(void *inProvider); + +typedef struct _Qt3DSEventSystemEventProvider +{ + void *m_Provider; + Qt3DSEventSystemProviderGetNextEventsFn getNextEvents; + Qt3DSEventSystemProviderReleaseFn release; +} Qt3DSEventSystemEventProvider; + +typedef void (*Qt3DSEventSystemPollerAddProviderFn)(void *inPoller, + Qt3DSEventSystemEventProvider inProvider); +typedef void (*Qt3DSEventSystemPollerRemoveProviderFn)(void *inPoller, + Qt3DSEventSystemEventProvider inProvider); +typedef int (*Qt3DSEventSystemPollerignoreProviderFn)(void *inPoller, + Qt3DSEventSystemEventProvider inProvider); +typedef int (*Qt3DSEventSystemPolleractivateProviderFn)(void *inPoller, + Qt3DSEventSystemEventProvider inProvider); + +typedef struct _Qt3DSEventSystemEventPoller +{ + void *m_Poller; + // Providers, once added, will be released by the event poller unless removed + Qt3DSEventSystemPollerAddProviderFn addProvider; + // Callers are responsible for releasing removed providers. + Qt3DSEventSystemPollerRemoveProviderFn removeProvider; + Qt3DSEventSystemPollerignoreProviderFn ignoreProvider; + Qt3DSEventSystemPolleractivateProviderFn activateProvider; + +} Qt3DSEventSystemEventPoller; + +extern const char *PROVIDER_TABLE_ENTRY; +extern const char *POLLER_TABLE_ENTRY; + +#ifdef _cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/event/test/CanProviderDemo.cpp b/src/Runtime/Source/event/test/CanProviderDemo.cpp new file mode 100644 index 00000000..dc51e9db --- /dev/null +++ b/src/Runtime/Source/event/test/CanProviderDemo.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "CanProviderDemo.h" + +CCanProviderDemo::CCanProviderDemo() + : m_Frame(0) + , m_LastClock(0) +{ +} + +CCanProviderDemo::~CCanProviderDemo() +{ +} + +unsigned short g_VehicleSpeedData[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 6, 8, 10, 12, 14, 16, + 18, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, + 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 256, 264, + 272, 280, 288, 296, 304, 312, 320, 328, 336, 344, 352, 360, 368, 376, 384, 392, + 400, 408, 416, 424, 432, 440, 448, 456, 462, 468, 474, 480, 486, 492, 498, 504, + 510, 516, 522, 528, 534, 540, 546, 552, 558, 564, 570, 576, 582, 588, 594, 600, + 606, 612, 618, 624, 630, 636, 642, 648, 654, 660, 666, 672, 678, 684, 690, 696, + 702, 708, 714, 720, 726, 732, 738, 744, 750, 756, 762, 768, 774, 780, 786, 792, + 798, 804, 810, 816, 820, 824, 828, 832, 836, 840, 844, 848, 852, 856, 860, 864, + 868, 872, 876, 880, 884, 888, 892, 896, 900, 904, 908, 912, 916, 920, 924, 928, + 932, 936, 940, 944, 948, 952, 956, 960, 964, 968, 972, 976, 980, 984, 988, 992, + 996, 1000, 1004, 1008, 1012, 1016, 1020, 1024, 1028, 1032, 1036, 1040, 1044, 1048, 1052, 1056, + 1054, 1052, 1050, 1048, 1046, 1044, 1042, 1040, 1038, 1036, 1034, 1032, 1030, 1028, 1026, 1024, + 1022, 1020, 1018, 1016, 1014, 1012, 1010, 1008, 1006, 1004, 1002, 1000, 998, 996, 994, 992, + 990, 988, 986, 984, 982, 980, 978, 976, 974, 972, 970, 968, 966, 964, 962, 960, + 958, 956, 954, 952, 950, 948, 946, 944, 942, 940, 938, 936, 934, 932, 930, 928, + 926, 924, 922, 920, 918, 916, 914, 912, 910, 908, 906, 904, 902, 900, 898, 896, + 894, 892, 890, 888, 886, 884, 882, 880, 878, 876, 874, 872, 870, 868, 866, 864, + 862, 860, 858, 856, 854, 852, 850, 848, 846, 844, 842, 840, 838, 836, 834, 832, + 830, 828, 826, 824, 822, 820, 818, 816, 823, 830, 837, 844, 851, 858, 865, 872, + 879, 886, 893, 900, 907, 914, 921, 928, 935, 942, 949, 956, 963, 970, 977, 984, + 991, 998, 1005, 1012, 1019, 1026, 1033, 1040, 1047, 1054, 1061, 1068, 1075, 1082, 1089, 1096, + 1103, 1110, 1117, 1124, 1131, 1138, 1145, 1152, 1159, 1166, 1173, 1180, 1187, 1194, 1201, 1208, + 1215, 1222, 1229, 1236, 1246, 1256, 1266, 1276, 1286, 1296, 1306, 1316, 1326, 1336, 1346, 1356, + 1366, 1376, 1386, 1396, 1406, 1416, 1426, 1436, 1446, 1456, 1466, 1476, 1486, 1496, 1506, 1516, + 1526, 1536, 1546, 1556, 1566, 1576, 1586, 1596, 1606, 1616, 1626, 1636, 1646, 1656, 1666, 1676, + 1686, 1696, 1706, 1716, 1726, 1736, 1746, 1756, 1766, 1776, 1786, 1796, 1806, 1816, 1826, 1836, + 1836, 1836, 1836, 1834, 1832, 1830, 1828, 1826, 1824, 1822, 1820, 1818, 1816, 1814, 1812, 1810, + 1808, 1806, 1804, 1802, 1800, 1798, 1796, 1794, 1792, 1790, 1788, 1786, 1784, 1782, 1780, 1778, + 1776, 1774, 1772, 1770, 1768, 1766, 1764, 1762, 1760, 1758, 1756, 1754, 1752, 1750, 1748, 1746, + 1744, 1742, 1740, 1738, 1736, 1734, 1732, 1730, 1728, 1726, 1724, 1722, 1723, 1724, 1725, 1726, + 1728, 1730, 1732, 1734, 1736, 1738, 1740, 1742, 1744, 1746, 1748, 1750, 1753, 1756, 1759, 1762, + 1765, 1768, 1771, 1774, 1777, 1780, 1783, 1786, 1789, 1792, 1795, 1798, 1801, 1804, 1807, 1810, + 1813, 1816, 1819, 1822, 1825, 1828, 1831, 1834, 1837, 1840, 1843, 1846, 1849, 1852, 1855, 1858, + 1861, 1864, 1867, 1870, 1873, 1876, 1879, 1882, 1885, 1888, 1891, 1894, 1897, 1900, 1903, 1906, + 1909, 1912, 1915, 1918, 1921, 1924, 1927, 1930, 1933, 1936, 1939, 1942, 1945, 1948, 1951, 1954, + 1957, 1960, 1963, 1966, 1969, 1972, 1975, 1978, 1981, 1984, 1987, 1990, 1993, 1996, 1999, 2002, + 2005, 2008, 2011, 2014, 2017, 2020, 2023, 2026, 2029, 2032, 2035, 2038, 2041, 2044, 2047, 2050, + 2053, 2056, 2059, 2062, 2064, 2066, 2068, 2070, 2072, 2074, 2076, 2078, 2080, 2082, 2084, 2086, + 2088, 2090, 2092, 2094, 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, 2112, 2114, 2116, 2118, + 2120, 2122, 2124, 2126, 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, 2144, 2146, 2148, 2150, + 2152, 2154, 2156, 2158, 2160, 2162, 2164, 2166, 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2182, + 2184, 2186, 2188, 2190, 2192, 2194, 2196, 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, 2214, + 2216, 2218, 2220, 2222, 2224, 2226, 2228, 2230, 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, + 2248, 2250, 2252, 2254, 2256, 2258, 2260, 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, + 2280, 2282, 2284, 2286, 2288, 2290, 2292, 2294, 2296, 2298, 2300, 2302, 2301, 2300, 2299, 2298, + 2297, 2296, 2295, 2294, 2293, 2292, 2291, 2290, 2289, 2288, 2287, 2286, 2285, 2284, 2283, 2282, + 2281, 2280, 2279, 2278, 2277, 2276, 2275, 2274, 2273, 2272, 2271, 2270, 2269, 2268, 2267, 2266, + 2265, 2264, 2263, 2262, 2261, 2260, 2259, 2258, 2257, 2256, 2255, 2254, 2253, 2252, 2251, 2250, + 2249, 2248, 2247, 2246, 2245, 2244, 2243, 2242, 2239, 2236, 2233, 2230, 2227, 2224, 2221, 2218, + 2215, 2212, 2209, 2206, 2203, 2200, 2197, 2194, 2191, 2188, 2185, 2182, 2179, 2176, 2173, 2170, + 2167, 2164, 2161, 2158, 2155, 2152, 2149, 2146, 2143, 2140, 2137, 2134, 2131, 2128, 2125, 2122, + 2119, 2116, 2113, 2110, 2107, 2104, 2101, 2098, 2095, 2092, 2089, 2086, 2083, 2080, 2077, 2074, + 2071, 2068, 2065, 2062, 2058, 2054, 2050, 2046, 2042, 2038, 2034, 2030, 2026, 2022, 2018, 2014, + 2010, 2006, 2001, 1996, 1991, 1986, 1981, 1976, 1971, 1966, 1961, 1956, 1951, 1946, 1941, 1936, + 1931, 1926, 1921, 1916, 1911, 1906, 1901, 1896, 1891, 1886, 1881, 1876, 1871, 1866, 1861, 1856, + 1851, 1846, 1841, 1836, 1831, 1826, 1821, 1816, 1811, 1806, 1801, 1796, 1791, 1786, 1781, 1776, + 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, + 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, + 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, + 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1779, 1782, 1785, 1788, + 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, 1827, 1830, 1833, 1836, + 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, + 1887, 1890, 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, + 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1958, 1960, 1962, 1964, 1966, 1968, 1970, 1972, + 1974, 1976, 1978, 1980, 1982, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2004, + 2006, 2008, 2010, 2012, 2014, 2016, 2018, 2020, 2022, 2024, 2026, 2028, 2030, 2032, 2034, 2036, + 2038, 2040, 2042, 2044, 2046, 2048, 2050, 2052, 2054, 2056, 2058, 2060, 2062, 2064, 2066, 2068, + 2070, 2072, 2074, 2076, 2078, 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, 2096, 2098, 2100, + 2102, 2104, 2106, 2108, 2110, 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, 2128, 2130, 2132, + 2134, 2136, 2138, 2140, 2142, 2144, 2146, 2148, 2150, 2152, 2154, 2156, 2158, 2160, 2162, 2164, + 2166, 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2182, 2184, 2186, 2188, 2190, 2192, 2194, 2196, + 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, 2214, 2216, 2218, 2220, 2222, 2224, 2226, 2228, + 2230, 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, 2248, 2250, 2252, 2254, 2256, 2258, 2260, + 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, 2280, 2282, 2284, 2286, 2288, 2290, 2292, + 2294, 2296, 2298, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, + 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, + 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, + 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, + 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2366, 2364, 2362, 2360, 2358, 2356, 2354, 2352, + 2350, 2348, 2346, 2344, 2342, 2340, 2338, 2336, 2334, 2332, 2330, 2328, 2326, 2324, 2322, 2320, + 2318, 2316, 2314, 2312, 2310, 2308, 2306, 2304, 2302, 2300, 2298, 2296, 2294, 2292, 2290, 2288, + 2286, 2284, 2282, 2280, 2278, 2276, 2274, 2272, 2270, 2268, 2266, 2264, 2262, 2260, 2258, 2256, + 2254, 2252, 2250, 2248, 2240, 2230, 2220, 2210, 2200, 2190, 2180, 2170, 2160, 2150, 2140, 2130, + 2120, 2110, 2100, 2090, 2080, 2070, 2060, 2050, 2040, 2030, 2020, 2010, 2000, 1990, 1980, 1970, + 1960, 1950, 1940, 1930, 1920, 1910, 1900, 1890, 1880, 1870, 1860, 1850, 1840, 1830, 1820, 1810, + 1800, 1790, 1780, 1770, 1760, 1750, 1740, 1730, 1720, 1710, 1700, 1690, 1680, 1670, 1660, 1650, + 1645, 1640, 1635, 1630, 1625, 1620, 1615, 1610, 1605, 1600, 1595, 1590, 1585, 1580, 1575, 1570, + 1565, 1560, 1555, 1550, 1545, 1540, 1535, 1530, 1525, 1520, 1515, 1510, 1505, 1500, 1495, 1490, + 1485, 1480, 1475, 1470, 1465, 1460, 1455, 1450, 1445, 1440, 1435, 1430, 1425, 1420, 1415, 1410, + 1405, 1400, 1395, 1390, 1385, 1380, 1375, 1370, 1365, 1360, 1355, 1350, 1345, 1340, 1335, 1330, + 1325, 1320, 1315, 1310, 1305, 1300, 1295, 1290, 1285, 1280, 1275, 1270, 1265, 1260, 1255, 1250, + 1245, 1240, 1235, 1230, 1225, 1220, 1215, 1210, 1205, 1200, 1195, 1190, 1185, 1180, 1175, 1170, + 1165, 1160, 1155, 1150, 1145, 1140, 1135, 1130, 1125, 1120, 1115, 1110, 1105, 1100, 1090, 1088, + 1086, 1084, 1082, 1080, 1078, 1076, 1074, 1072, 1070, 1065, 1060, 1055, 1050, 1045, 1040, 1035, + 1030, 1025, 1020, 1015, 1010, 1005, 1000, 995, 990, 985, 980, 975, 970, 965, 960, 955, + 950, 945, 940, 935, 930, 925, 920, 915, 910, 905, 900, 895, 890, 885, 880, 875, + 870, 865, 860, 855, 850, 845, 840, 835, 830, 825, 820, 815, 810, 805, 800, 795, + 790, 785, 780, 775, 772, 769, 766, 763, 760, 757, 754, 751, 748, 745, 742, 739, + 736, 733, 730, 727, 724, 721, 718, 715, 712, 709, 706, 703, 700, 697, 694, 691, + 688, 685, 682, 679, 676, 673, 670, 667, 664, 661, 658, 655, 652, 649, 646, 643, + 640, 637, 634, 631, 628, 625, 622, 619, 616, 613, 610, 607, 604, 601, 598, 595, + 597, 599, 601, 603, 605, 607, 609, 611, 613, 615, 617, 619, 621, 623, 625, 627, + 629, 631, 633, 635, 637, 639, 641, 643, 645, 647, 649, 651, 653, 655, 657, 659, + 661, 663, 665, 667, 669, 671, 673, 675, 677, 679, 681, 683, 685, 687, 689, 691, + 693, 695, 697, 699, 701, 703, 705, 707, 709, 711, 713, 715, 715, 715, 715, 715, + 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, + 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, + 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, + 715, 715, 715, 715, 715, 715, 715, 715, 710, 705, 700, 695, 690, 685, 680, 675, + 670, 665, 660, 655, 650, 645, 640, 635, 630, 625, 620, 615, 610, 605, 600, 595, + 590, 585, 580, 575, 570, 565, 560, 555, 550, 545, 540, 535, 530, 525, 520, 515, + 510, 505, 500, 495, 490, 485, 480, 475, 470, 465, 460, 455, 450, 445, 440, 435, + 430, 425, 420, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, + 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, 471, + 473, 475, 477, 479, 481, 483, 485, 487, 489, 491, 493, 495, 497, 499, 501, 503, + 505, 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, + 536, 532, 528, 524, 520, 516, 512, 508, 504, 500, 496, 492, 488, 484, 480, 476, + 472, 468, 464, 460, 456, 452, 448, 444, 440, 436, 432, 428, 424, 420, 416, 412, + 408, 404, 400, 396, 392, 388, 384, 380, 376, 372, 368, 364, 360, 356, 352, 348, + 344, 340, 336, 332, 328, 324, 320, 316, 312, 308, 304, 300, 295, 290, 285, 280, + 275, 270, 265, 260, 255, 250, 245, 240, 235, 230, 225, 220, 215, 210, 205, 200, + 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, + 115, 110, 105, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, + 35, 30, 25, 20, 15, 10, 5, 0 +}; + +Qt3DSEventSystemEvent *CCanProviderDemo::GetNextEvent(IEventFactory &inFactory) +{ + clock_t theCurClock = clock(); + if (theCurClock > m_LastClock + && (theCurClock - m_LastClock) / (CLOCKS_PER_SEC / 1000) < 1000 / 6) + return 0; + m_LastClock = theCurClock; + unsigned char theLength = 0; + unsigned char theData[8]; + theData[0] = 81; +#define SIN_SAMPLE(s, m) ((sin((float)s) / 2 + 0.5) * m) + switch (rand() % 2) { + case 0: + theData[1] = 1; + { // Vehicle speed + int theIndex = m_Frame % (sizeof(g_VehicleSpeedData) / sizeof(g_VehicleSpeedData[0])); + theData[2] = (unsigned short)(g_VehicleSpeedData[theIndex] * 0.06) >> 8; + theData[3] = (unsigned char)(g_VehicleSpeedData[theIndex] * 0.06); + } + { + unsigned short theOdo = m_Frame; + theData[4] = theOdo >> 8; + theData[5] = (unsigned char)theOdo; + } + theLength = 6; + break; + case 1: + theData[1] = 2; + { + unsigned short theTrip = m_Frame; + theData[2] = theTrip >> 8; + theData[3] = (unsigned char)theTrip; + } + { + unsigned short theCoolant = (unsigned char)SIN_SAMPLE(m_Frame / 170, 300); + theData[4] = theCoolant >> 8; + theData[5] = (unsigned char)theCoolant; + } + theLength = 6; + break; + default: + return 0; + } + ++m_Frame; + Qt3DSEventSystemEvent &theEvent = inFactory.CreateEvent(9); + Qt3DSEventSystemEventData *theCurrentData = theEvent.m_Data; + theCurrentData->m_Name = inFactory.RegisterStr("device_type"); + theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesString; + theCurrentData->m_Value.m_String = inFactory.AllocateStr("CAN"); + ++theCurrentData; + theCurrentData->m_Name = inFactory.RegisterStr("id"); + theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesNumber; + theCurrentData->m_Value.m_Number = 101; + ++theCurrentData; + theCurrentData->m_Name = inFactory.RegisterStr("length"); + theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesNumber; + theCurrentData->m_Value.m_Number = 6; + ++theCurrentData; + for (int i = 0; i < theLength; ++i) { + theCurrentData->m_Name = inFactory.RegisterStr("data"); + theCurrentData->m_Value.m_Type = QT3DSEventSystemEventTypesNumber; + theCurrentData->m_Value.m_Number = theData[i]; + ++theCurrentData; + } + + return &theEvent; +} + +size_t CCanProviderDemo::GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, + size_t bufLen) +{ + size_t bufIdx = 0; + Qt3DSEventSystemEvent *evt = NULL; + for (evt = GetNextEvent(inFactory); evt && bufIdx < bufLen; + evt = GetNextEvent(inFactory), ++bufIdx) + outBuffer[bufIdx] = evt; + return bufIdx; +} + +void CCanProviderDemo::Release() +{ + delete this; +} diff --git a/src/Runtime/Source/event/test/CanProviderDemo.h b/src/Runtime/Source/event/test/CanProviderDemo.h new file mode 100644 index 00000000..7d6788bc --- /dev/null +++ b/src/Runtime/Source/event/test/CanProviderDemo.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CAN_PROVIDER_DEMO_H +#define CAN_PROVIDER_DEMO_H + +#include + +#include + +using namespace qt3ds::evt; + +class CCanProviderDemo : public IEventProvider +{ +public: + CCanProviderDemo(); + virtual ~CCanProviderDemo(); + + Qt3DSEventSystemEvent *GetNextEvent(IEventFactory &inFactory); + virtual size_t GetNextEvents(IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, + size_t bufLen); + virtual void Release(); + +private: + unsigned int m_Frame; + clock_t m_LastClock; +}; + +#endif // CAN_PROVIDER_DEMO_H diff --git a/src/Runtime/Source/foundation/AutoDeallocatorAllocator.h b/src/Runtime/Source/foundation/AutoDeallocatorAllocator.h new file mode 100644 index 00000000..5cbbc8bb --- /dev/null +++ b/src/Runtime/Source/foundation/AutoDeallocatorAllocator.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_FOUNDATION_AUTO_DEALLOCATOR_ALLOCATOR_H +#define QT3DS_FOUNDATION_AUTO_DEALLOCATOR_ALLOCATOR_H +#pragma once + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" + +namespace qt3ds { +namespace foundation { + + using eastl::make_pair; + using eastl::pair; + + struct SSAutoDeallocatorAllocator : public NVAllocatorCallback + { + NVAllocatorCallback &m_Allocator; + nvhash_map m_Allocations; + SSAutoDeallocatorAllocator(NVFoundationBase &inFnd) + : m_Allocator(inFnd.getAllocator()) + , m_Allocations(inFnd.getAllocator(), "SSAutoDeallocatorAllocator::m_Allocations") + { + } + + SSAutoDeallocatorAllocator(NVAllocatorCallback &inAlloc) + : m_Allocator(inAlloc) + , m_Allocations(inAlloc, "SSAutoDeallocatorAllocator::m_Allocations") + { + } + + // Automatically deallocates everything that hasn't already been deallocated. + ~SSAutoDeallocatorAllocator() { deallocateAllAllocations(); } + + void deallocateAllAllocations() + { + for (nvhash_map::iterator iter = m_Allocations.begin(), + end = m_Allocations.end(); + iter != end; ++iter) + m_Allocator.deallocate(iter->first); + m_Allocations.clear(); + } + + void *allocate(size_t size, const char *typeName, const char *filename, int line, + int flags = 0) override + { + void *value = m_Allocator.allocate(size, typeName, filename, line, flags); + m_Allocations.insert(make_pair(value, size)); + return value; + } + + void *allocate(size_t size, const char *typeName, const char *filename, int line, + size_t alignment, size_t alignmentOffset) override + { + void *value = + m_Allocator.allocate(size, typeName, filename, line, alignment, alignmentOffset); + m_Allocations.insert(make_pair(value, size)); + return value; + } + void deallocate(void *ptr) override + { + nvhash_map::iterator iter = m_Allocations.find(ptr); + QT3DS_ASSERT(iter != m_Allocations.end()); + m_Allocator.deallocate(iter->first); + m_Allocations.erase(iter); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/ConvertUTF.cpp b/src/Runtime/Source/foundation/ConvertUTF.cpp new file mode 100644 index 00000000..a71a3aeb --- /dev/null +++ b/src/Runtime/Source/foundation/ConvertUTF.cpp @@ -0,0 +1,661 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* +* Copyright 2001-2004 Unicode, Inc. +* +* Disclaimer +* +* This source code is provided as is by Unicode, Inc. No claims are +* made as to fitness for any particular purpose. No warranties of any +* kind are expressed or implied. The recipient agrees to determine +* applicability of information provided. If this file has been +* purchased on magnetic or optical media from Unicode, Inc., the +* sole remedy for any claim will be exchange of defective media +* within 90 days of receipt. +* +* Limitations on Rights to Redistribute This Code +* +* Unicode, Inc. hereby grants the right to freely use the information +* supplied in this file in the creation of products supporting the +* Unicode Standard, and to make copies of this file in any form +* for internal or external distribution as long as this notice +* remains attached. +*/ + +/* --------------------------------------------------------------------- + Conversions between UTF32, UTF-16, and UTF-8. Source code file. + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Sept 2001: fixed const & error conditions per + mods suggested by S. Parent & A. Lillich. + June 2002: Tim Dodd added detection and handling of incomplete + source sequences, enhanced error detection, added casts + to eliminate compiler warnings. + July 2003: slight mods to back out aggressive FFFE detection. + Jan 2004: updated switches in from-UTF8 conversions. + Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. + See the header file "ConvertUTF.h" for complete documentation. +------------------------------------------------------------------------ */ + +#include "foundation/ConvertUTF.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4365) // warnings on conversion from unsigned int to int +#endif + +#ifdef CVTUTF_DEBUG +#include +#endif + +static const int halfShift = 10; /* used for shifting by 10 bits */ + +static const UTF32 halfBase = 0x0010000UL; +static const UTF32 halfMask = 0x3FFUL; + +#define UNI_SUR_HIGH_START (UTF32)0xD800 +#define UNI_SUR_HIGH_END (UTF32)0xDBFF +#define UNI_SUR_LOW_START (UTF32)0xDC00 +#define UNI_SUR_LOW_END (UTF32)0xDFFF +#define false 0 +#define true 1 + +/* --------------------------------------------------------------------- */ + +ConversionResult Q3DSConvertUTF32toUTF16(const UTF32 **sourceStart, const UTF32 *sourceEnd, + UTF16 **targetStart, UTF16 *targetEnd, + ConversionFlags flags) +{ + ConversionResult result = conversionOK; + const UTF32 *source = *sourceStart; + UTF16 *target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + if (target >= targetEnd) { + result = targetExhausted; + break; + } + ch = *source++; + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved + * values */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = (UTF16)ch; /* normal case */ + } + } else if (ch > UNI_MAX_LEGAL_UTF32) { + if (flags == strictConversion) { + result = sourceIllegal; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + --source; /* Back up source pointer! */ + result = targetExhausted; + break; + } + ch -= halfBase; + *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult Q3DSConvertUTF16toUTF32(const UTF16 **sourceStart, const UTF16 *sourceEnd, + UTF32 **targetStart, UTF32 *targetEnd, + ConversionFlags flags) +{ + ConversionResult result = conversionOK; + const UTF16 *source = *sourceStart; + UTF32 *target = *targetStart; + UTF32 ch, ch2; + while (source < sourceEnd) { + const UTF16 *oldSource = + source; /* In case we have to back up because of target overflow. */ + ch = *source++; + /* If we have a surrogate pair, convert to UTF32 first. */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { + /* If the 16 bits following the high surrogate are in the source buffer... */ + if (source < sourceEnd) { + ch2 = *source; + /* If it's a low surrogate, convert to UTF32. */ + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + + halfBase; + ++source; + } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else { /* We don't have the 16 bits following the high surrogate. */ + --source; /* return to the high surrogate */ + result = sourceExhausted; + break; + } + } else if (flags == strictConversion) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + if (target >= targetEnd) { + source = oldSource; /* Back up source pointer! */ + result = targetExhausted; + break; + } + *target++ = ch; + } + *sourceStart = source; + *targetStart = target; +#ifdef CVTUTF_DEBUG + if (result == sourceIllegal) { + fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); + fflush(stderr); + } +#endif + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Index into the table below with the first byte of a UTF-8 sequence to + * get the number of trailing bytes that are supposed to follow it. + * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is + * left as-is for anyone who may want to do such conversion, which was + * allowed in earlier algorithms. + */ +static const char trailingBytesForUTF8[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 +}; + +/* + * Magic values subtracted from a buffer value during UTF8 conversion. + * This table contains as many values as there might be trailing bytes + * in a UTF-8 sequence. + */ +static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; + +/* + * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed + * into the first byte, depending on how many bytes follow. There are + * as many entries in this table as there are UTF-8 sequence types. + * (I.e., one byte sequence, two byte... etc.). Remember that sequencs + * for *legal* UTF-8 will be 4 or fewer bytes total. + */ +static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +/* --------------------------------------------------------------------- */ + +/* The interface converts a whole buffer to avoid function-call overhead. + * Constants have been gathered. Loops & conditionals have been removed as + * much as possible for efficiency, in favor of drop-through switches. + * (See "Note A" at the bottom of the file for equivalent code.) + * If your compiler supports it, the "isLegalUTF8" call can be turned + * into an inline function. + */ + +/* --------------------------------------------------------------------- */ + +ConversionResult Q3DSConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, + UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) +{ + ConversionResult result = conversionOK; + const UTF16 *source = *sourceStart; + UTF8 *target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + const UTF16 *oldSource = + source; /* In case we have to back up because of target overflow. */ + ch = *source++; + /* If we have a surrogate pair, convert to UTF32 first. */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { + /* If the 16 bits following the high surrogate are in the source buffer... */ + if (source < sourceEnd) { + UTF32 ch2 = *source; + /* If it's a low surrogate, convert to UTF32. */ + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + + halfBase; + ++source; + } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else { /* We don't have the 16 bits following the high surrogate. */ + --source; /* return to the high surrogate */ + result = sourceExhausted; + break; + } + } else if (flags == strictConversion) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* Figure out how many bytes the result will require */ + if (ch < (UTF32)0x80) { + bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { + bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { + bytesToWrite = 3; + } else if (ch < (UTF32)0x110000) { + bytesToWrite = 4; + } else { + bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + } + + target += bytesToWrite; + if (target > targetEnd) { + source = oldSource; /* Back up source pointer! */ + target -= bytesToWrite; + result = targetExhausted; + break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: + *--target = (UTF8)((ch | byteMark) & byteMask); + ch >>= 6; + case 3: + *--target = (UTF8)((ch | byteMark) & byteMask); + ch >>= 6; + case 2: + *--target = (UTF8)((ch | byteMark) & byteMask); + ch >>= 6; + case 1: + *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Utility routine to tell whether a sequence of bytes is legal UTF-8. + * This must be called with the length pre-determined by the first byte. + * If not calling this from ConvertUTF8to*, then the length can be set by: + * length = trailingBytesForUTF8[*source]+1; + * and the sequence is illegal right away if there aren't that many bytes + * available. + * If presented with a length > 4, this returns false. The Unicode + * definition of UTF-8 goes up to 4-byte sequences. + */ + +static Boolean isLegalUTF8(const UTF8 *source, int length) +{ + UTF8 a; + const UTF8 *srcptr = source + length; + switch (length) { + default: + return false; + /* Everything else falls through when "true"... */ + case 4: + if ((a = (*--srcptr)) < 0x80 || a > 0xBF) + return false; + case 3: + if ((a = (*--srcptr)) < 0x80 || a > 0xBF) + return false; + case 2: + if ((a = (*--srcptr)) > 0xBF) + return false; + + switch (*source) { + /* no fall-through in this inner switch */ + case 0xE0: + if (a < 0xA0) + return false; + break; + case 0xED: + if (a > 0x9F) + return false; + break; + case 0xF0: + if (a < 0x90) + return false; + break; + case 0xF4: + if (a > 0x8F) + return false; + break; + default: + if (a < 0x80) + return false; + } + + case 1: + if (*source >= 0x80 && *source < 0xC2) + return false; + } + if (*source > 0xF4) + return false; + return true; +} + +/* --------------------------------------------------------------------- */ + +/* + * Exported function to return whether a UTF-8 sequence is legal or not. + * This is not used here; it's just exported. + */ +Boolean Q3DSIsLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) +{ + int length = trailingBytesForUTF8[*source] + 1; + if (source + length > sourceEnd) { + return false; + } + return isLegalUTF8(source, length); +} + +/* --------------------------------------------------------------------- */ + +ConversionResult Q3DSConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, + UTF16 **targetStart, UTF16 *targetEnd, + ConversionFlags flags) +{ + ConversionResult result = conversionOK; + const UTF8 *source = *sourceStart; + UTF16 *target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; + break; + } + /* Do this check whether lenient or strict */ + if (!isLegalUTF8(source, extraBytesToRead + 1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: + ch += *source++; + ch <<= 6; /* remember, illegal UTF-8 */ + case 4: + ch += *source++; + ch <<= 6; /* remember, illegal UTF-8 */ + case 3: + ch += *source++; + ch <<= 6; + case 2: + ch += *source++; + ch <<= 6; + case 1: + ch += *source++; + ch <<= 6; + case 0: + ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead + 1); /* Back up source pointer! */ + result = targetExhausted; + break; + } + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead + 1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = (UTF16)ch; /* normal case */ + } + } else if (ch > UNI_MAX_UTF16) { + if (flags == strictConversion) { + result = sourceIllegal; + source -= (extraBytesToRead + 1); /* return to the start */ + break; /* Bail out; shouldn't continue */ + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + source -= (extraBytesToRead + 1); /* Back up source pointer! */ + result = targetExhausted; + break; + } + ch -= halfBase; + *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult Q3DSConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, + UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) +{ + ConversionResult result = conversionOK; + const UTF32 *source = *sourceStart; + UTF8 *target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + ch = *source++; + if (flags == strictConversion) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* + * Figure out how many bytes the result will require. Turn any + * illegally large UTF32 things (> Plane 17) into replacement chars. + */ + if (ch < (UTF32)0x80) { + bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { + bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { + bytesToWrite = 3; + } else if (ch <= UNI_MAX_LEGAL_UTF32) { + bytesToWrite = 4; + } else { + bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + result = sourceIllegal; + } + + target += bytesToWrite; + if (target > targetEnd) { + --source; /* Back up source pointer! */ + target -= bytesToWrite; + result = targetExhausted; + break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: + *--target = (UTF8)((ch | byteMark) & byteMask); + ch >>= 6; + case 3: + *--target = (UTF8)((ch | byteMark) & byteMask); + ch >>= 6; + case 2: + *--target = (UTF8)((ch | byteMark) & byteMask); + ch >>= 6; + case 1: + *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult Q3DSConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, + UTF32 **targetStart, UTF32 *targetEnd, + ConversionFlags flags) +{ + ConversionResult result = conversionOK; + const UTF8 *source = *sourceStart; + UTF32 *target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; + break; + } + /* Do this check whether lenient or strict */ + if (!isLegalUTF8(source, extraBytesToRead + 1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: + ch += *source++; + ch <<= 6; + case 4: + ch += *source++; + ch <<= 6; + case 3: + ch += *source++; + ch <<= 6; + case 2: + ch += *source++; + ch <<= 6; + case 1: + ch += *source++; + ch <<= 6; + case 0: + ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead + 1); /* Back up the source pointer! */ + result = targetExhausted; + break; + } + if (ch <= UNI_MAX_LEGAL_UTF32) { + /* + * UTF-16 surrogate values are illegal in UTF-32, and anything + * over Plane 17 (> 0x10FFFF) is illegal. + */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead + 1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = ch; + } + } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ + result = sourceIllegal; + *target++ = UNI_REPLACEMENT_CHAR; + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- + + Note A. + The fall-through switches in UTF-8 reading code save a + temp variable, some decrements & conditionals. The switches + are equivalent to the following loop: + { + int tmpBytesToRead = extraBytesToRead+1; + do { + ch += *source++; + --tmpBytesToRead; + if (tmpBytesToRead) ch <<= 6; + } while (tmpBytesToRead > 0); + } + In UTF-8 writing code, the switches on "bytesToWrite" are + similarly unrolled loops. + + --------------------------------------------------------------------- */ diff --git a/src/Runtime/Source/foundation/ConvertUTF.h b/src/Runtime/Source/foundation/ConvertUTF.h new file mode 100644 index 00000000..93614a0c --- /dev/null +++ b/src/Runtime/Source/foundation/ConvertUTF.h @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +/* --------------------------------------------------------------------- + + Conversions between UTF32, UTF-16, and UTF-8. Header file. + + Several funtions are included here, forming a complete set of + conversions between the three formats. UTF-7 is not included + here, but is handled in a separate source file. + + Each of these routines takes pointers to input buffers and output + buffers. The input buffers are const. + + Each routine converts the text between *sourceStart and sourceEnd, + putting the result into the buffer between *targetStart and + targetEnd. Note: the end pointers are *after* the last item: e.g. + *(sourceEnd - 1) is the last item. + + The return result indicates whether the conversion was successful, + and if not, whether the problem was in the source or target buffers. + (Only the first encountered problem is indicated.) + + After the conversion, *sourceStart and *targetStart are both + updated to point to the end of last text successfully converted in + the respective buffers. + + Input parameters: + sourceStart - pointer to a pointer to the source buffer. + The contents of this are modified on return so that + it points at the next thing to be converted. + targetStart - similarly, pointer to pointer to the target buffer. + sourceEnd, targetEnd - respectively pointers to the ends of the + two buffers, for overflow checking only. + + These conversion functions take a ConversionFlags argument. When this + flag is set to strict, both irregular sequences and isolated surrogates + will cause an error. When the flag is set to lenient, both irregular + sequences and isolated surrogates are converted. + + Whether the flag is strict or lenient, all illegal sequences will cause + an error return. This includes sequences such as: , , + or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code + must check for illegal sequences. + + When the flag is set to lenient, characters over 0x10FFFF are converted + to the replacement character; otherwise (when the flag is set to strict) + they constitute an error. + + Output parameters: + The value "sourceIllegal" is returned from some routines if the input + sequence is malformed. When "sourceIllegal" is returned, the source + value will point to the illegal value that caused the problem. E.g., + in UTF-8 when a sequence is malformed, it points to the start of the + malformed sequence. + + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Fixes & updates, Sept 2001. + +------------------------------------------------------------------------ */ + +/* --------------------------------------------------------------------- + The following 4 definitions are compiler-specific. + The C standard does not guarantee that wchar_t has at least + 16 bits, so wchar_t is no less portable than unsigned short! + All should be unsigned values to avoid sign extension during + bit mask & shift operations. +------------------------------------------------------------------------ */ + +typedef unsigned int UTF32; /* at least 32 bits */ +typedef unsigned short UTF16; /* at least 16 bits */ +typedef unsigned char UTF8; /* typically 8 bits */ +typedef unsigned char Boolean; /* 0 or 1 */ + +/* Some fundamental constants */ + +#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD +#define UNI_MAX_BMP (UTF32)0x0000FFFF +#define UNI_MAX_UTF16 (UTF32)0x0010FFFF +#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF +#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF + +typedef enum { + conversionOK, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted, /* insuff. room in target for conversion */ + sourceIllegal /* source sequence is illegal/malformed */ +} ConversionResult; + +typedef enum { strictConversion = 0, lenientConversion } ConversionFlags; + +/* This is for C++ and does no harm in C */ +#ifdef __cplusplus +extern "C" { +#endif + +ConversionResult Q3DSConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, + UTF16 **targetStart, UTF16 *targetEnd, + ConversionFlags flags); + +ConversionResult Q3DSConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, + UTF8 **targetStart, UTF8 *targetEnd, + ConversionFlags flags); + +ConversionResult Q3DSConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, + UTF32 **targetStart, UTF32 *targetEnd, + ConversionFlags flags); + +ConversionResult Q3DSConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, + UTF8 **targetStart, UTF8 *targetEnd, + ConversionFlags flags); + +ConversionResult Q3DSConvertUTF16toUTF32(const UTF16 **sourceStart, const UTF16 *sourceEnd, + UTF32 **targetStart, UTF32 *targetEnd, + ConversionFlags flags); + +ConversionResult Q3DSConvertUTF32toUTF16(const UTF32 **sourceStart, const UTF32 *sourceEnd, + UTF16 **targetStart, UTF16 *targetEnd, + ConversionFlags flags); + +Boolean Q3DSIsLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); + +#ifdef __cplusplus +} +#endif + +/* --------------------------------------------------------------------- */ diff --git a/src/Runtime/Source/foundation/EASTL_new.cpp b/src/Runtime/Source/foundation/EASTL_new.cpp new file mode 100644 index 00000000..61e8e0b4 --- /dev/null +++ b/src/Runtime/Source/foundation/EASTL_new.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// we have some build dependencies which forces us to include +// this on linux to recognize malloc +#include +#include + +#if !defined(_MSC_VER) +#include +#endif + +#include "EASTL/allocator.h" + +void *operator new[](size_t size, const char *, int, unsigned, const char *, int) +{ + return malloc(size); +} + +void *operator new[](size_t size, size_t, size_t, const char *, int, unsigned, const char *, int) +{ + return malloc(size); +} +// EASTL also wants us to define this (see string.h line 197) +int Vsnprintf8(char8_t *pDestination, size_t n, const char8_t *pFormat, va_list arguments) +{ +#ifdef _MSC_VER + return _vsnprintf(pDestination, n, pFormat, arguments); +#else + return vsnprintf(pDestination, n, pFormat, arguments); +#endif +} +int Vsnprintf16(char8_t *pDestination, size_t n, const char16_t *pFormat, va_list arguments) +{ +#ifdef _MSC_VER + return _vsnprintf(pDestination, n, (char *)pFormat, arguments); +#else + return vsnprintf(pDestination, n, (char *)pFormat, arguments); +#endif +} +int Vsnprintf32(char8_t *pDestination, size_t n, const char32_t *pFormat, va_list arguments) +{ +#ifdef _MSC_VER + return _vsnprintf(pDestination, n, (char *)pFormat, arguments); +#else + return vsnprintf(pDestination, n, (char *)pFormat, arguments); +#endif +} diff --git a/src/Runtime/Source/foundation/FastAllocator.h b/src/Runtime/Source/foundation/FastAllocator.h new file mode 100644 index 00000000..c296bcb6 --- /dev/null +++ b/src/Runtime/Source/foundation/FastAllocator.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace foundation { + + /** + * Allocator that allocates slabs of a certain size and objects then + * get allocated from those slabs. This allocator is designed to reset, + * meaning every frame you can call reset and the objects get freed but + * not destructed. This allocator does not call destructors!! + */ + template + struct SFastAllocator : NVAllocatorCallback + { + ForwardingAllocator m_Allocator; + nvvector m_Slabs; + QT3DSU32 m_Offset; + + enum { + SlabSize = slabSize, + }; + + static size_t getSlabSize() { return slabSize; } + + SFastAllocator(NVAllocatorCallback &alloc, const char *memName) + : m_Allocator(alloc, memName) + , m_Slabs(alloc, "SFastAllocator::m_Slabs") + , m_Offset(0) + { + } + + ~SFastAllocator() + { + for (QT3DSU32 idx = 0, end = m_Slabs.size(); idx < end; ++idx) + m_Allocator.deallocate(m_Slabs[idx]); + m_Slabs.clear(); + m_Offset = 0; + } + void *allocate(size_t inSize, const char *inFile, int inLine, int inFlags = 0) + { + (void)inFlags; + if (inSize > slabSize) { + QT3DS_ASSERT(false); + return NULL; + } + QT3DSU32 misalign = m_Offset % alignmentInBytes; + if (misalign) + m_Offset = m_Offset + (alignmentInBytes - misalign); + + QT3DSU32 currentSlab = m_Offset / slabSize; + QT3DSU32 slabOffset = m_Offset % slabSize; + QT3DSU32 amountLeftInSlab = slabSize - slabOffset; + if (inSize > amountLeftInSlab) { + ++currentSlab; + slabOffset = 0; + m_Offset = currentSlab * slabSize; + } + while (currentSlab >= m_Slabs.size()) { + m_Slabs.push_back((QT3DSU8 *)m_Allocator.allocate(slabSize, inFile, inLine)); + } + QT3DSU8 *data = m_Slabs[currentSlab] + slabOffset; + // This would indicate the underlying allocator isn't handing back aligned memory. + QT3DS_ASSERT(reinterpret_cast(data) % alignmentInBytes == 0); + m_Offset += (QT3DSU32)inSize; + return data; + } + void *allocate(size_t size, const char * /*typeName*/, const char *filename, int line, + int flags = 0) override + { + return allocate(size, filename, line, flags); + } + void *allocate(size_t size, const char * /*typeName*/, const char *filename, int line, + size_t alignment, size_t /*alignmentOffset*/) override + { + QT3DS_ASSERT(alignment == alignmentInBytes); + if (alignment == alignmentInBytes) + return allocate(size, filename, line); + return NULL; + } + // only reset works with deallocation + void deallocate(void *) override {} + void reset() { m_Offset = 0; } + }; +} +} diff --git a/src/Runtime/Source/foundation/FileTools.cpp b/src/Runtime/Source/foundation/FileTools.cpp new file mode 100644 index 00000000..aa1e7384 --- /dev/null +++ b/src/Runtime/Source/foundation/FileTools.cpp @@ -0,0 +1,545 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/FileTools.h" +#include "foundation/Utils.h" +#include +# +#ifdef EA_PLATFORM_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#else // posix +#include +#include +#include +#include +#include +#endif +#include +#include +#include + +using namespace qt3ds::foundation; + +namespace { +// State machine where you can add a character +// and it will tell you how many characters to erase +struct SPathStateMachine +{ + struct States + { + enum Enum { + NoState = 0, // Don't care + Slash, // Last char was either a forward or backward slash + Period, // Last char was a period + TwoPeriods, // Last two characters were periods + }; + }; + struct Actions + { + enum Enum { + NoAction = 0, + DeleteBack1Slash, + DeleteBack2Slashes, + }; + }; + + States::Enum m_State; + + SPathStateMachine() + : m_State(States::NoState) + { + } + + Actions::Enum AnalyzeChar(char32_t inChar) + { + switch (inChar) { + case '\\': + case '/': + switch (m_State) { + case States::NoState: + m_State = States::Slash; + break; + case States::Period: + m_State = States::Slash; + return Actions::DeleteBack1Slash; + + case States::TwoPeriods: + m_State = States::Slash; + return Actions::DeleteBack2Slashes; + case States::Slash: + return Actions::DeleteBack1Slash; + } + break; + case '.': + switch (m_State) { + case States::Slash: + case States::NoState: + m_State = States::Period; + break; + case States::Period: + m_State = States::TwoPeriods; + break; + case States::TwoPeriods: + break; + } + break; + default: + m_State = States::NoState; + break; + } + return Actions::NoAction; + } +}; + +template +inline bool DoDeleteBack1Slash(TStr::size_type &idx, TStrType &ioPath) +{ + TStr::size_type slashLoc = ioPath.rfind('/', idx - 1); + if ((slashLoc != TStr::npos) && (slashLoc > 2) + // and the next *two* characters aren't both dots. + && ((ioPath[slashLoc - 1] != '.') || (ioPath[slashLoc - 2] != '.'))) { + + ioPath.erase(ioPath.begin() + slashLoc, ioPath.begin() + idx); + idx = slashLoc; + return true; + } + return false; +} + +template +void NormalizePathT(TStrType &ioPath) +{ + TStr::size_type pathLen = ioPath.size(); + SPathStateMachine theStateMachine; + for (TStr::size_type idx = 0; idx < pathLen; ++idx) { + char8_t ¤tChar = ioPath[idx]; + if (currentChar == '\\') + currentChar = '/'; + SPathStateMachine::Actions::Enum action = theStateMachine.AnalyzeChar(currentChar); + switch (action) { + case SPathStateMachine::Actions::DeleteBack2Slashes: + if (DoDeleteBack1Slash(idx, ioPath)) + DoDeleteBack1Slash(idx, ioPath); + pathLen = ioPath.size(); + break; + + case SPathStateMachine::Actions::DeleteBack1Slash: + DoDeleteBack1Slash(idx, ioPath); + pathLen = ioPath.size(); + break; + default: + break; + } + } +} + +bool IsAbsolute(const char8_t *inPath, size_t inLen) +{ + if (inLen > 2 && inPath[1] == ':') + return true; + else if (inLen > 1 && (inPath[0] == '\\' || inPath[0] == '/')) + return true; + return false; +} + +template +void CombineBaseAndRelativeT(const char8_t *inBase, const char8_t *inRelative, TStrType &outString) +{ + if (IsAbsolute(inRelative, StrLen(inRelative))) { + outString.assign(nonNull(inRelative)); + } else { + if (inRelative && *inRelative) { + if (inRelative[0] == '#') + outString.assign(inRelative); + else { + if (IsAbsolute(inRelative, strlen(inRelative))) { + outString.assign(inRelative); + } else { + outString = inBase ? inBase : ""; + if (outString.size()) + outString.append("/"); + outString.append(inRelative ? inRelative : (const char8_t *)L""); + } + NormalizePathT(outString); + } + } + } +} + +template +void GetRelativeFromBaseT(TStrType &inBaseStr, TStrType &inRelativeStr, TStrType &outString) +{ + outString.clear(); + NormalizePathT(inBaseStr); + NormalizePathT(inRelativeStr); + if (inBaseStr.size() == 0) { + outString.assign(inRelativeStr.c_str()); + return; + } + if (inRelativeStr.size() == 0) { + outString.clear(); + return; + } + // find longest common string + const char8_t *inBase = inBaseStr.c_str(); + const char8_t *baseEnd = inBaseStr.c_str() + inBaseStr.size(); + const char8_t *inRelative = inRelativeStr.c_str(); + size_t relativeLen = inRelativeStr.size(); + const char8_t *relativeEnd = inRelative + relativeLen; + + for (; inRelative < relativeEnd && inBase < baseEnd && *inRelative == *inBase; + ++inRelative, ++inBase) + ; + + // They had nothing in common. + if (inBase == inBaseStr.c_str()) { + outString.assign(inRelativeStr.c_str()); + return; + } + + if (inRelative && (*inRelative == '\\' || *inRelative == '/')) + ++inRelative; + + const char *common = inBase; + if (common == NULL || *common == 0) { + outString.assign("./"); + outString.append(inRelative); + NormalizePathT(outString); + return; + } + // Backtrack to the nearest slash. + while (*common && *common != '\\' && *common != '/') + --common; + + bool foundNonSlash = false; + for (; common != baseEnd; ++common) { + if (*common != '\\' && *common != '/') { + if (foundNonSlash == false) + outString.append("..\\"); + foundNonSlash = true; + } else + foundNonSlash = false; + } + if (inRelative < relativeEnd) { + if (outString.size() == 0) + outString.assign("./"); + outString.append(inRelative); + } + NormalizePathT(outString); +} +} + +void CFileTools::NormalizePath(TStr &ioPath) +{ + NormalizePathT(ioPath); +} + +void CFileTools::NormalizePath(eastl::string &ioPath) +{ + NormalizePathT(ioPath); +} + +QString CFileTools::NormalizePathForQtUsage(const QString &path) +{ + // path can be a file path or a qrc URL string. + + QString filePath = QDir::cleanPath(path); + + if (filePath.startsWith(QLatin1String("qrc:/"))) + return filePath.mid(3); + else + return filePath; +} + +void CFileTools::CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, + TStr &outString) +{ + CombineBaseAndRelativeT(inBase, inRelative, outString); +} + +void CFileTools::CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, + eastl::string &outString) +{ + CombineBaseAndRelativeT(inBase, inRelative, outString); +} + +void CFileTools::GetRelativeFromBase(TStr &inBaseStr, TStr &inRelativeStr, TStr &outString) +{ + GetRelativeFromBaseT(inBaseStr, inRelativeStr, outString); +} + +void CFileTools::GetRelativeFromBase(eastl::string &inBaseStr, eastl::string &inRelativeStr, + eastl::string &outString) +{ + GetRelativeFromBaseT(inBaseStr, inRelativeStr, outString); +} + +bool CFileTools::RequiresCombineBaseAndRelative(const char8_t *inPath) +{ + if (inPath && *inPath) + return inPath[0] == '.'; + return false; +} + +template +void ToPlatformPathT(TStrType &outString) +{ +#ifndef EA_PLATFORM_WINDOWS + for (TStr::size_type pos = outString.find('\\'); pos != TStr::npos; + pos = outString.find('\\', pos + 1)) + outString.replace(outString.begin() + pos, outString.begin() + pos + 1, "/"); +#else + (void)outString; +#endif +} + +void CFileTools::ToPlatformPath(TStr &outString) +{ + ToPlatformPathT(outString); +} + +void CFileTools::ToPlatformPath(eastl::string &outString) +{ + ToPlatformPathT(outString); +} + +CRegisteredString CFileTools::RemapPathToBinaryFormat(TStr &inPath, TStr &inPresentationDir, + TStr &ioWorkspaceStr, + IStringTable &inStringTable) +{ + GetRelativeFromBase(inPresentationDir, inPath, ioWorkspaceStr); + CRegisteredString theNewStr = inStringTable.RegisterStr(ioWorkspaceStr.c_str()); + theNewStr.Remap(inStringTable.GetRemapMap()); + return theNewStr; +} + +CRegisteredString CFileTools::RemapPathFromBinaryFormat(CRegisteredString inPath, + const char8_t *inPresDir, + TStr &ioWorkspaceStr, + const CStrTableOrDataRef &inRef, + IStringTable &inStringTable) +{ + inPath.Remap(inRef); + if (RequiresCombineBaseAndRelative(inPath.c_str())) { + CombineBaseAndRelative(inPresDir, inPath, ioWorkspaceStr); + return inStringTable.RegisterStr(ioWorkspaceStr.c_str()); + } + return inPath; +} + +void CFileTools::GetDirectory(eastl::string &ioPath) +{ + eastl::string::size_type theSlashPos = ioPath.find_last_of("\\/"); + if (theSlashPos == eastl::string::npos) { + ioPath.clear(); + return; + } + ioPath.resize(theSlashPos); +} + +bool CFileTools::DirectoryExists(const char8_t *inPath) +{ +#ifdef EA_PLATFORM_WINDOWS + DWORD theAtts = GetFileAttributesA(inPath); + return theAtts != INVALID_FILE_ATTRIBUTES && (theAtts & FILE_ATTRIBUTE_DIRECTORY); +#else // Posix style check for directory + int status; + struct stat st_buf; + status = stat(inPath, &st_buf); + if (status == 0 && S_ISDIR(st_buf.st_mode)) + return true; + return false; +#endif +} + +bool CFileTools::FileExists(const char8_t *inPath) +{ +#ifdef EA_PLATFORM_WINDOWS + DWORD theAtts = GetFileAttributesA(inPath); + return theAtts != INVALID_FILE_ATTRIBUTES; +#else // Posix style check for directory + int status; + struct stat st_buf; + status = stat(inPath, &st_buf); + if (status == 0) + return true; + return false; +#endif +} + +eastl::string CFileTools::GetFileOrAssetPath(const char8_t *inPath) +{ + QFile tmp(inPath); + if (tmp.exists()) + return inPath; + return eastl::string("assets:/") + inPath; +} + +void CFileTools::SetStreamPosition(QIODevice& device, qint64 inOffset, + qt3ds::foundation::SeekPosition::Enum inEnum) +{ + if (inEnum == qt3ds::foundation::SeekPosition::Begin) + device.seek(inOffset); + else if (inEnum == qt3ds::foundation::SeekPosition::Current) + device.seek(device.pos() + inOffset); + else if (inEnum == qt3ds::foundation::SeekPosition::End) + device.seek(device.size() + inOffset); +} + +void CFileTools::GetExtension(const char8_t *inPath, eastl::string &outExt) +{ + outExt.assign(nonNull(inPath)); + size_t dotPos = outExt.find_last_of('.'); + if (dotPos != eastl::string::npos) + outExt.erase(outExt.begin(), outExt.begin() + dotPos + 1); +} + +void CFileTools::Split(const char8_t *inPath, eastl::string &outDir, eastl::string &outFileStem, + eastl::string &outExtension) +{ + outDir.assign(nonNull(inPath)); + NormalizePath(outDir); + outFileStem = outDir; + GetDirectory(outDir); + size_t lenDiff = outFileStem.size() - outDir.size(); + if (lenDiff > 0) { + if (outDir.size()) + outFileStem = outFileStem.substr(outDir.size() + 1); + + eastl::string::size_type lastDot = outFileStem.find_last_of('.'); + if (lastDot != eastl::string::npos) { + outExtension = outFileStem.substr(lastDot + 1); + outFileStem.resize(lastDot); + } + } +} + +#ifdef EA_PLATFORM_WINDOWS +void CFileTools::GetDirectoryEntries(const eastl::string &inPath, + eastl::vector &outFiles) +{ + if (inPath.size() == 0) + return; + eastl::string tempPath(inPath); + NormalizePath(tempPath); + for (eastl::string::size_type pos = tempPath.find_first_of('/'); pos != eastl::string::npos; + pos = tempPath.find_first_of('/', pos + 1)) + tempPath[pos] = '\\'; + if (tempPath.back() != '\\') + tempPath.append("\\"); + tempPath.append(1, '*'); + WIN32_FIND_DATAA ffd; + HANDLE hFind = FindFirstFileA(tempPath.c_str(), &ffd); + outFiles.clear(); + if (INVALID_HANDLE_VALUE == hFind) + return; + + do { + if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0) + continue; + outFiles.push_back(eastl::string(ffd.cFileName)); + } while (FindNextFileA(hFind, &ffd) != 0); +} +#else +void CFileTools::GetDirectoryEntries(const eastl::string &inPath, + eastl::vector &outFiles) +{ + if (inPath.size() == 0) + return; + eastl::string tempPath(inPath); + NormalizePath(tempPath); + struct dirent *dent; + DIR *srcdir = opendir(tempPath.c_str()); + if (srcdir) { + while ((dent = readdir(srcdir)) != NULL) { + if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) + continue; + outFiles.push_back(eastl::string(dent->d_name)); + } + closedir(srcdir); + } +} +#endif + +bool CFileTools::CreateDir(const eastl::string &inPath, bool inRecurse) +{ + if (DirectoryExists(inPath.c_str())) + return true; + + eastl::string temp(inPath); + GetDirectory(temp); + if (temp.size() && !DirectoryExists(temp.c_str())) { + if (inRecurse) + CreateDir(temp, inRecurse); + else + return false; + } + +#ifdef EA_PLATFORM_WINDOWS + BOOL result = CreateDirectoryA(inPath.c_str(), NULL); + return result != 0; +#else + int result = mkdir(inPath.c_str(), 0777); + return result == 0; +#endif +} + +void CFileTools::AppendDirectoryInPathToFile(eastl::string &ioPath, const char8_t *dirName) +{ + eastl::string::size_type lastSlash = ioPath.find_last_of("\\/"); + if (lastSlash != eastl::string::npos) { + if (dirName == NULL) + dirName = ""; // avoid crashes on null strings + ioPath.insert(lastSlash + 1, "/"); + ioPath.insert(lastSlash + 1, dirName); + } else { + ioPath.insert(0, "/"); + ioPath.insert(0, dirName); + } +} + +void CFileTools::RemoveLastDirectoryInPathToFile(eastl::string &ioPath) +{ + eastl::string::size_type lastSlash = ioPath.find_last_of("\\/"); + if (lastSlash != eastl::string::npos) { + eastl::string::size_type secondToLastSlash = ioPath.find_last_of("\\/", lastSlash - 1); + if (secondToLastSlash != eastl::string::npos) + ioPath = ioPath.erase(secondToLastSlash, lastSlash - secondToLastSlash); + } +} + +void CFileTools::SetExtension(eastl::string &ioPath, const char8_t *inExt) +{ + eastl::string::size_type thePos = ioPath.find_last_of("."); + if (thePos != eastl::string::npos) { + ++thePos; + ioPath = ioPath.replace(thePos, ioPath.size() - thePos, inExt); + } +} diff --git a/src/Runtime/Source/foundation/FileTools.h b/src/Runtime/Source/foundation/FileTools.h new file mode 100644 index 00000000..57455256 --- /dev/null +++ b/src/Runtime/Source/foundation/FileTools.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_FILE_TOOLS_H +#define QT3DS_FOUNDATION_FILE_TOOLS_H + +#include "EASTL/string.h" +#include "EASTL/vector.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/StringTable.h" +#include "foundation/IOStreams.h" +#include + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +namespace qt3ds { +namespace foundation { + + typedef eastl::basic_string TStr; + + class CFileTools + { + public: + // Normalizes all slashes to be windows-like + static void NormalizePath(TStr &ioPath); + static void NormalizePath(eastl::string &ioPath); + + // This is kind of the opposite of the 'NormalizePath' methods above in + // that it forces usage of unix style directory separators rather than + // windows separators. In addition, the path here can be a file path or + // a qrc URL string. This function will eventually be refactored away + // when we've converted to using Qt's file system abstraction throughout + // the code base and use QUrl's throughout instead of raw strings to + // represent resources. + static QString NormalizePathForQtUsage(const QString &path); + + static void CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, + TStr &outString); + static void CombineBaseAndRelative(const char8_t *inBase, const char8_t *inRelative, + eastl::string &outString); + + // inBase and inRelative will get normalized + // This algorithm changes based on the platform. On windows it is not case sensitive, on + // not-windows it is. + static void GetRelativeFromBase(TStr &inBase, TStr &inRelative, TStr &outString); + static void GetRelativeFromBase(eastl::string &inBase, eastl::string &inRelative, + eastl::string &outString); + + // A remapped path is a file path that starts with a '.' or a '/'. GetRelativeFromBase + // *always* + // places a '.' or a '/' at the front of the path, so if you *know* the path came from + // GetRelativeFromBase then you also know this function returns true of GetRelativeFromBase + // actually generated a path that needs CombineBaseAndRelative. + static bool RequiresCombineBaseAndRelative(const char8_t *inPath); + + // Search/replace so that all slashes are unix-like but only on non-windows platforms + // Assumes the incoming path has been normalized + static void ToPlatformPath(TStr &ioPath); + static void ToPlatformPath(eastl::string &ioPath); + + static CRegisteredString RemapPathToBinaryFormat(TStr &inPath, TStr &inPresentationDir, + TStr &ioWorkspaceStr, + IStringTable &inStringTable); + static CRegisteredString RemapPathFromBinaryFormat(CRegisteredString inPath, + const char8_t *inPresDir, + TStr &ioWorkspaceStr, + const CStrTableOrDataRef &inRef, + IStringTable &inStringTable); + // I + static void GetDirectory(eastl::string &ioPath); + static bool DirectoryExists(const char8_t *inPath); + static void GetExtension(const char8_t *inPath, eastl::string &outExt); + static void Split(const char8_t *inPath, eastl::string &outDir, eastl::string &outFileStem, + eastl::string &outExtension); + + // Only implemented for windows. Does not return '.' and '..' special entries + // inPath is mangled in a platform specific way + static void GetDirectoryEntries(const eastl::string &inPath, + eastl::vector &outFiles); + + static bool CreateDir(const eastl::string &inPath, bool inRecurse = true); + + // Given a/b.txt, we will end up with a/dirName/b.txt + static void AppendDirectoryInPathToFile(eastl::string &ioPath, const char8_t *dirName); + static void RemoveLastDirectoryInPathToFile(eastl::string &ioPath); + + static void SetExtension(eastl::string &ioPath, const char8_t *inExt); + + static bool FileExists(const char8_t *inPath); + static eastl::string GetFileOrAssetPath(const char8_t *inPath); + static void SetStreamPosition(QIODevice& device, qint64 inOffset, + qt3ds::foundation::SeekPosition::Enum inEnum); + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/IOStreams.cpp b/src/Runtime/Source/foundation/IOStreams.cpp new file mode 100644 index 00000000..f1adfbc0 --- /dev/null +++ b/src/Runtime/Source/foundation/IOStreams.cpp @@ -0,0 +1,384 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/IOStreams.h" +#include "foundation/FileTools.h" +#include "foundation/StrConvertUTF.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSThread.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSMemoryBuffer.h" + +using namespace qt3ds::foundation; + +#ifndef _WIN32 + +inline int _fseeki64(FILE *inFile, int64_t pos, int seekFlags) +{ + return fseek(inFile, (int32_t)pos, seekFlags); +} + +inline int64_t _ftelli64(FILE *inFile) +{ + return ftell(inFile); +} + +#endif + +CFileSeekableIOStream::CFileSeekableIOStream(const char *inFileName, FileOpenFlags inFlags) +{ + openFile(QString(inFileName), inFlags); +} + +#ifdef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T + +CFileSeekableIOStream::CFileSeekableIOStream(const wchar_t *inFileName, FileOpenFlags inFlags) +{ + openFile(QString::fromWCharArray(inFileName), inFlags); +} + +#endif + +CFileSeekableIOStream::CFileSeekableIOStream(const char16_t *inWideName, FileOpenFlags inFlags) +{ + openFile(QString::fromUtf16(inWideName), inFlags); +} + +CFileSeekableIOStream::CFileSeekableIOStream(const QString &inFIle, FileOpenFlags inFlags) +{ + openFile(inFIle, inFlags); +} + +void CFileSeekableIOStream::openFile(const QString &path, FileOpenFlags inFlags) +{ + if (path.isEmpty()) + return; + + QIODevice::OpenMode fileFlags = QIODevice::ReadOnly; + if (inFlags & FileOpenFlagValues::Write) + fileFlags = QIODevice::ReadWrite; + if (inFlags & FileOpenFlagValues::Truncate) + fileFlags |= QIODevice::Truncate; + + m_File.setFileName(CFileTools::NormalizePathForQtUsage(path)); + if (!m_File.open(fileFlags)) { + qCCritical(INTERNAL_ERROR) << "failed to open file" + << path << "with error" << m_File.errorString(); + QT3DS_ASSERT(false); + } +} + +CFileSeekableIOStream::~CFileSeekableIOStream() +{ + m_File.close(); +} + +bool CFileSeekableIOStream::IsOpen() +{ + return m_File.isOpen(); +} + +void CFileSeekableIOStream::SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) +{ + if (inOffset > QT3DS_MAX_I32 || inOffset < QT3DS_MIN_I32) { + qCCritical(INVALID_OPERATION, "Attempt to seek further than platform allows"); + QT3DS_ASSERT(false); + return; + } else { + CFileTools::SetStreamPosition(m_File, inOffset, inEnum); + } +} + +QT3DSI64 CFileSeekableIOStream::GetPosition() const +{ + return m_File.pos(); +} + +QT3DSU32 CFileSeekableIOStream::Read(NVDataRef data) +{ + return m_File.read((char *)data.begin(), data.size()); +} + +bool CFileSeekableIOStream::Write(NVConstDataRef data) +{ + if (!m_File.isOpen()) { + QT3DS_ASSERT(false); + return 0; + } + qint64 numBytes = m_File.write((char*)data.begin(), data.size()); + return numBytes == data.size(); +} + +CMemorySeekableIOStream::CMemorySeekableIOStream(NVAllocatorCallback &inAlloc, + const char *inAllocName) + : m_Allocator(inAlloc) + , m_AllocationName(inAllocName) + , m_Data(NULL) + , m_Size(0) + , m_Offset(0) + , m_Capacity(0) +{ +} + +CMemorySeekableIOStream::~CMemorySeekableIOStream() +{ + if (m_Data) + m_Allocator.deallocate(m_Data); + m_Data = NULL; + m_Size = 0; + m_Capacity = 0; + m_Offset = 0; +} + +void CMemorySeekableIOStream::SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) +{ + QT3DSI64 startPos = 0; + + switch (inEnum) { + case SeekPosition::Begin: + startPos = 0; + break; + case SeekPosition::Current: + startPos = m_Offset; + break; + case SeekPosition::End: + startPos = m_Size; + break; + default: + QT3DS_ASSERT(false); + break; + } + + startPos += inOffset; + if (m_Size == 0 && inOffset != 0) { + QT3DS_ASSERT(false); + return; + } + if (startPos < 0) { + QT3DS_ASSERT(false); + startPos = 0; + } + if (startPos >= m_Size && startPos != 0) { + QT3DS_ASSERT(false); + startPos = m_Size - 1; + } + m_Offset = static_cast(startPos); +} + +QT3DSU32 CMemorySeekableIOStream::Read(NVDataRef data) +{ + if (m_Data == NULL) + return 0; + QT3DSU32 amountLeft = m_Size - m_Offset; + QT3DSU32 numBytes = NVMin(amountLeft, data.size()); + intrinsics::memCopy(data.begin(), m_Data + m_Offset, numBytes); + m_Offset += numBytes; + return numBytes; +} + +bool CMemorySeekableIOStream::Write(NVConstDataRef data) +{ + reserve(data.size() + m_Offset); + intrinsics::memCopy(m_Data + m_Offset, data.begin(), data.size()); + m_Offset += data.size(); + m_Size = NVMax(m_Size, m_Offset); + return true; +} + +void CMemorySeekableIOStream::reserve(QT3DSU32 inNewSize) +{ + if (inNewSize > m_Capacity) { + if (inNewSize < 100000) + inNewSize *= 2; + QT3DSU8 *newData = + (QT3DSU8 *)m_Allocator.allocate(inNewSize, m_AllocationName, __FILE__, __LINE__); + if (m_Size) { + intrinsics::memCopy(newData, m_Data, m_Size); + m_Allocator.deallocate(m_Data); + } + m_Data = newData; + m_Capacity = inNewSize; + } +} + +namespace { + +struct WriteBufferedStreamImpl; +struct WriteBufferThread : public Thread +{ + // When a buffer is available + WriteBufferedStreamImpl &m_Impl; + WriteBufferThread(NVFoundationBase &fnd, WriteBufferedStreamImpl &i) + : Thread(fnd) + , m_Impl(i) + { + setName("WriteBufferThread"); + } + void execute() override; +}; + +#ifdef _WIN32 +#pragma warning(disable : 4355) +#endif +/* Double buffered stream implementation with a sending thread constantly + * pulling data from the main thread and writing it out to socket. + */ +struct WriteBufferedStreamImpl : public WriteBufferedOutStream +{ + NVFoundationBase &m_Foundation; + IOutStream &m_Stream; + MemoryBuffer<> m_Buf1; + MemoryBuffer<> m_Buf2; + MemoryBuffer<> *m_CurrentBuffer; + MemoryBuffer<> *m_WriteBuffer; + QT3DSU32 m_BufferSize; + volatile bool m_StreamValid; + Mutex m_BufferLock; + Sync m_DataAvailable; + Sync m_WriteFinished; + WriteBufferThread m_Thread; + QT3DSI32 mRefCount; + + WriteBufferedStreamImpl(NVFoundationBase &fnd, QT3DSU32 totalBufSize, IOutStream &s) + : m_Foundation(fnd) + , m_Stream(s) + , m_Buf1(ForwardingAllocator(fnd.getAllocator(), "WriteBufferedStreamImpl::buffer")) + , m_Buf2(ForwardingAllocator(fnd.getAllocator(), "WriteBufferedStreamImpl::buffer")) + , m_CurrentBuffer(&m_Buf1) + , m_WriteBuffer(NULL) + , m_BufferSize(totalBufSize / 2) + , m_StreamValid(true) + , m_BufferLock(fnd.getAllocator()) + , m_DataAvailable(fnd.getAllocator()) + , m_WriteFinished(fnd.getAllocator()) + , m_Thread(fnd, *this) + , mRefCount(0) + { + m_Buf1.reserve(m_BufferSize); + m_Buf2.reserve(m_BufferSize); + } + ~WriteBufferedStreamImpl() + { + m_Thread.signalQuit(); + m_DataAvailable.set(); + m_Thread.waitForQuit(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + bool Write(NVConstDataRef data) override + { + while (data.size() && m_StreamValid) { + QT3DSU32 currentBufferSize; + QT3DSU32 amountCanWrite; + { + Mutex::ScopedLock locker(m_BufferLock); + currentBufferSize = m_CurrentBuffer->size(); + amountCanWrite = NVMin(data.size(), m_BufferSize - currentBufferSize); + m_CurrentBuffer->write(data.begin(), amountCanWrite); + currentBufferSize += amountCanWrite; + } + m_DataAvailable.set(); + if (currentBufferSize == m_BufferSize) { + m_WriteFinished.wait(); + m_WriteFinished.reset(); + // Blocking call if we are already sending data. + data = NVConstDataRef(data.begin() + amountCanWrite, + data.size() - amountCanWrite); + } + } + return m_StreamValid; + } + + IOutStream &wrappedStream() override { return m_Stream; } + + QT3DSU32 getTotalBufferSize() + { + Mutex::ScopedLock locker(m_BufferLock); + QT3DSU32 retval = m_CurrentBuffer->size(); + if (m_WriteBuffer) + retval += m_WriteBuffer->size(); + return retval; + } + + QT3DSU32 getWriteBufferSize() + { + Mutex::ScopedLock locker(m_BufferLock); + if (m_WriteBuffer) + return m_WriteBuffer->size(); + return 0; + } + + void flush() override + { + while (getTotalBufferSize()) { + m_WriteFinished.wait(); + m_WriteFinished.reset(); + } + } +}; + +void WriteBufferThread::execute() +{ + while (!quitIsSignalled()) { + m_Impl.m_DataAvailable.wait(); + + if (!quitIsSignalled() && m_Impl.m_StreamValid) { + m_Impl.m_DataAvailable.reset(); + { + Mutex::ScopedLock locker(m_Impl.m_BufferLock); + m_Impl.m_WriteBuffer = m_Impl.m_CurrentBuffer; + m_Impl.m_CurrentBuffer = + m_Impl.m_CurrentBuffer == &m_Impl.m_Buf1 ? &m_Impl.m_Buf2 : &m_Impl.m_Buf1; + QT3DS_ASSERT(m_Impl.m_WriteBuffer != m_Impl.m_CurrentBuffer); + } + NVConstDataRef dataBuffer(*m_Impl.m_WriteBuffer); + if (dataBuffer.size()) { + m_Impl.m_StreamValid = m_Impl.m_Stream.Write(dataBuffer); + { + Mutex::ScopedLock locker(m_Impl.m_BufferLock); + m_Impl.m_WriteBuffer->clear(); + m_Impl.m_WriteBuffer = NULL; + } + } + m_Impl.m_WriteFinished.set(); + } + } + quit(); +} +} + +NVScopedRefCounted +WriteBufferedOutStreamCreate(NVFoundationBase &fnd, IOutStream &stream, QT3DSU32 totalBufferSize) +{ + return QT3DS_NEW(fnd.getAllocator(), WriteBufferedStreamImpl)(fnd, totalBufferSize, stream); +} diff --git a/src/Runtime/Source/foundation/IOStreams.h b/src/Runtime/Source/foundation/IOStreams.h new file mode 100644 index 00000000..855e5209 --- /dev/null +++ b/src/Runtime/Source/foundation/IOStreams.h @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_IO_STREAMS_H +#define QT3DS_FOUNDATION_IO_STREAMS_H + +#include "EABase/eabase.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/TrackingAllocator.h" +#include "foundation/Qt3DSMath.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Utils.h" +#include "foundation/Qt3DSRefCounted.h" + +#include +#include + +namespace qt3ds { +class NVFoundationBase; + +namespace foundation { + + class IOutStream + { + protected: + virtual ~IOutStream() {} + public: + virtual bool Write(NVConstDataRef data) = 0; + void WriteWithLen(NVConstDataRef data) + { + Write(data.size()); + Write(data); + } + template + void Write(const TDataType &type) + { + Write(toU8ConstDataRef(type)); + } + template + void Write(const TDataType *data, QT3DSU32 numItems) + { + Write(toU8ConstDataRef(data, numItems)); + } + void Write(const wchar_t *data) + { + if (data == NULL) + data = L""; + // Write the null character at the end of the string. + // This just makes reading and debugging a lot less error prone. + // at the expense of 2 bytes. + Write(data, (QT3DSU32)StrLen(data) + 1); + } + template + void WriteWithLen(const TDataType *data, QT3DSU32 numItems) + { + WriteWithLen(toU8ConstDataRef(data, numItems)); + } + }; + + class IInStream + { + protected: + virtual ~IInStream() {} + public: + // Semantics are precisely that you return the amount read + virtual QT3DSU32 Read(NVDataRef data) = 0; + + QT3DSU32 SafeRead(NVDataRef data) + { + QT3DSU32 amountRead = Read(data); + QT3DS_ASSERT(amountRead == data.size()); + if (amountRead < data.size()) + intrinsics::memZero(data.begin() + amountRead, data.size() - amountRead); + return amountRead; + } + QT3DSU32 ReadWithLen(NVDataRef data) + { + QT3DSU32 len = 0; + Read(len); + return SafeRead(toDataRef(data.begin(), len)); + } + template + QT3DSU32 Read(TDataType &type) + { + return SafeRead(toU8DataRef(type)); + } + template + QT3DSU32 Read(TDataType *data, QT3DSU32 numItems) + { + return SafeRead(toU8DataRef(data, numItems)); + } + }; + + struct SeekPosition + { + enum Enum { + Unknown, + Begin, + Current, + End, + }; + }; + + class ISeekable + { + protected: + virtual ~ISeekable() {} + public: + virtual void SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) = 0; + virtual QT3DSI64 GetPosition() const = 0; + virtual QT3DSI64 GetLength() const + { + ISeekable &seekable(const_cast(*this)); + QT3DSI64 currentPos(GetPosition()); + seekable.SetPosition(0, SeekPosition::End); + QT3DSI64 retval(GetPosition()); + seekable.SetPosition(currentPos, SeekPosition::Begin); + return retval; + } + }; + + class ISeekableIOStream : public IInStream, public IOutStream, public ISeekable + { + }; + + struct FileOpenFlagValues + { + enum Enum { + Open = 1, // Without this flag, function fails if file exists + Truncate = 1 << 1, // Truncate the file so an immediate close will empty it. + Create = 1 << 2, + Write = 1 << 3, + }; + }; + + typedef NVFlags FileOpenFlags; + + static inline FileOpenFlags FileReadFlags() { return FileOpenFlags(FileOpenFlagValues::Open); } + + static inline FileOpenFlags FileWriteFlags() + { + return FileOpenFlags(FileOpenFlagValues::Create | FileOpenFlagValues::Open + | FileOpenFlagValues::Write | FileOpenFlagValues::Truncate); + } + static inline FileOpenFlags FileAppendFlags() + { + return FileOpenFlags(FileOpenFlagValues::Create | FileOpenFlagValues::Open + | FileOpenFlagValues::Write); + } + + class CFileSeekableIOStream : public ISeekableIOStream + { + protected: + QFile m_File; + + public: + // Enabling append also enables reading from the file while being able to + // write to it. + CFileSeekableIOStream(const char *inFile, FileOpenFlags inFlags); +#ifdef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T + CFileSeekableIOStream(const wchar_t *inFile, FileOpenFlags inFlags); +#endif + + CFileSeekableIOStream(const char16_t *inFile, FileOpenFlags inFlags); + CFileSeekableIOStream(const QString &inFIle, FileOpenFlags inFlags); + virtual ~CFileSeekableIOStream(); + virtual bool IsOpen(); + void SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) override; + QT3DSI64 GetPosition() const override; + QT3DSU32 Read(NVDataRef data) override; + bool Write(NVConstDataRef data) override; + + private: + void openFile(const QString &path, FileOpenFlags inFlags); + }; + + class CMemorySeekableIOStream : public ISeekableIOStream + { + protected: + NVAllocatorCallback &m_Allocator; + const char *m_AllocationName; + QT3DSU8 *m_Data; + QT3DSU32 m_Size; + QT3DSU32 m_Offset; + QT3DSU32 m_Capacity; + + public: + CMemorySeekableIOStream(NVAllocatorCallback &inAlloc, const char *inAllocName); + virtual ~CMemorySeekableIOStream(); + void SetPosition(QT3DSI64 inOffset, SeekPosition::Enum inEnum) override; + QT3DSI64 GetPosition() const override { return m_Offset; } + QT3DSI64 GetLength() const override { return m_Size; } + QT3DSU32 Read(NVDataRef data) override; + bool Write(NVConstDataRef data) override; + + // Add in the standard container functions + QT3DSU8 *begin() { return m_Data; } + QT3DSU8 *end() { return m_Data + m_Size; } + const QT3DSU8 *begin() const { return m_Data; } + const QT3DSU8 *end() const { return m_Data + m_Size; } + void clear() + { + m_Offset = 0; + m_Size = 0; + } + QT3DSU32 size() const { return m_Size; } + void reserve(QT3DSU32 inNewSize); + void resize(QT3DSU32 inNewSize) + { + reserve(inNewSize); + m_Size = inNewSize; + } + }; + + // Simple, one way input stream. + struct SMemoryInStream : public IInStream + { + const QT3DSU8 *m_Begin; + const QT3DSU8 *m_End; + SMemoryInStream(const QT3DSU8 *b, const QT3DSU8 *e) + : m_Begin(b) + , m_End(e) + { + } + + QT3DSU32 Read(NVDataRef data) override + { + size_t available = m_End - m_Begin; + size_t requested = data.size(); + size_t amount = NVMin(available, requested); + qt3ds::intrinsics::memCopy(data.mData, m_Begin, (QT3DSU32)amount); + m_Begin += amount; + return (QT3DSU32)amount; + } + }; + + class WriteBufferedOutStream : public IOutStream, public NVRefCounted + { + public: + virtual IOutStream &wrappedStream() = 0; + virtual void flush() = 0; + + static NVScopedRefCounted + Create(NVFoundationBase &fnd, IOutStream &stream, QT3DSU32 totalBufferSize = 128 * 1024); + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/LICENCE_SOCKET.TXT b/src/Runtime/Source/foundation/LICENCE_SOCKET.TXT new file mode 100644 index 00000000..9b9ab805 --- /dev/null +++ b/src/Runtime/Source/foundation/LICENCE_SOCKET.TXT @@ -0,0 +1,20 @@ +LuaSocket 3.0 license +Copyright (C) 2004-2013 Diego Nehab + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/Runtime/Source/foundation/LICENSE_CONVERTUTF.TXT b/src/Runtime/Source/foundation/LICENSE_CONVERTUTF.TXT new file mode 100644 index 00000000..254acdfe --- /dev/null +++ b/src/Runtime/Source/foundation/LICENSE_CONVERTUTF.TXT @@ -0,0 +1,19 @@ +Copyright 2001-2004 Unicode, Inc. + +Disclaimer + +This source code is provided as is by Unicode, Inc. No claims are +made as to fitness for any particular purpose. No warranties of any +kind are expressed or implied. The recipient agrees to determine +applicability of information provided. If this file has been +purchased on magnetic or optical media from Unicode, Inc., the +sole remedy for any claim will be exchange of defective media +within 90 days of receipt. + +Limitations on Rights to Redistribute This Code + +Unicode, Inc. hereby grants the right to freely use the information +supplied in this file in the creation of products supporting the +Unicode Standard, and to make copies of this file in any form +for internal or external distribution as long as this notice +remains attached. diff --git a/src/Runtime/Source/foundation/PoolingAllocator.h b/src/Runtime/Source/foundation/PoolingAllocator.h new file mode 100644 index 00000000..9d939fdc --- /dev/null +++ b/src/Runtime/Source/foundation/PoolingAllocator.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_FOUNDATION_POOLING_ALLOCATOR_H +#define QT3DS_FOUNDATION_POOLING_ALLOCATOR_H +#pragma once + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "foundation/Qt3DSMutex.h" + +// Pooling allocator. Not designed for small allocations +// starting at 64 bytes and up to 4 K, allocator uses pools. +// Above that, uses default allocator. THis object is absolutely not threadsafe. +// This addes 8 bytes to each allocation in order to safely track the allocation size. +// There is no strict requirement to deallocate; this allocator automatically deallocates +// anything allocated through it. +namespace qt3ds { +namespace foundation { + struct SPoolingAllocator : public NVAllocatorCallback + { + typedef Mutex TMutexType; + typedef Mutex::ScopedLock TLockType; + + NVAllocatorCallback &m_Allocator; + TMutexType m_Mutex; + + struct SAllocationTag + { + QT3DSU32 m_Tag; + size_t m_Size; + SAllocationTag(size_t inSize = 0) + : m_Tag(0xAB5534CD) + , m_Size(inSize) + { + } + }; + + template + struct SPoolObj + { + QT3DSU32 m_Buffer[TObjSize / 4]; + SPoolObj() {} + }; +#define ITERATE_POOLING_ALLOCATOR_POOL_SIZES \ + HANDLE_POOLING_ALLOCATOR_POOL_SIZE(64) \ + HANDLE_POOLING_ALLOCATOR_POOL_SIZE(128) \ + HANDLE_POOLING_ALLOCATOR_POOL_SIZE(256) \ + HANDLE_POOLING_ALLOCATOR_POOL_SIZE(512) \ + HANDLE_POOLING_ALLOCATOR_POOL_SIZE(1024) + +#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ + Pool, ForwardingAllocator, 4> m_Pool##sz; + ITERATE_POOLING_ALLOCATOR_POOL_SIZES +#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE + + SSAutoDeallocatorAllocator m_LargeAllocator; + +#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ + , m_Pool##sz(ForwardingAllocator(inAllocator, "PoolingAllocatorPool")) + + SPoolingAllocator(NVAllocatorCallback &inAllocator) + : m_Allocator(inAllocator) + , m_Mutex(inAllocator) ITERATE_POOLING_ALLOCATOR_POOL_SIZES + , m_LargeAllocator(inAllocator) + { + } +#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE + + void *doAllocateFromPool(size_t size) + { + TLockType locker(m_Mutex); + +#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ + if (size <= sz) \ + return m_Pool##sz.allocate(__FILE__, __LINE__); + ITERATE_POOLING_ALLOCATOR_POOL_SIZES +#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE + + return m_LargeAllocator.allocate(size, "largetype", __FILE__, __LINE__, 0); + } + + void *doAllocate(size_t size) + { + size += sizeof(SAllocationTag); + SAllocationTag *tag = reinterpret_cast(doAllocateFromPool(size)); + new (tag) SAllocationTag(size); + QT3DSU8 *data = reinterpret_cast(tag); + return data + sizeof(SAllocationTag); + } + + void *allocate(size_t size, const char * /*typeName*/, const char * /*filename*/, + int /*line*/, int /*flags*/ = 0) override + { + return doAllocate(size); + } + + void *allocate(size_t size, const char * /*typeName*/, const char * /*filename*/, + int /*line*/, size_t /*alignment*/, size_t /*alignmentOffset*/) override + { + return doAllocate(size); + } + + /** + \brief Frees memory previously allocated by allocate(). + + Threading: This function should be thread safe as it can be called in the context of + the user thread + and physics processing thread(s). + + \param ptr Memory to free. + */ + void deallocate(void *ptr) override + { + TLockType locker(m_Mutex); + + // Deallocate on null is fine. + if (ptr == NULL) + return; + + SAllocationTag tempTag; + QT3DSU8 *dataPtr = reinterpret_cast(ptr); + SAllocationTag *theTag = + reinterpret_cast(dataPtr - sizeof(SAllocationTag)); + if (theTag->m_Tag != tempTag.m_Tag) { + QT3DS_ASSERT(false); + return; + } + + size_t size = theTag->m_Size; + + // We add this offset at allocation time + ptr = dataPtr - sizeof(SAllocationTag); + +#define HANDLE_POOLING_ALLOCATOR_POOL_SIZE(sz) \ + if (size <= sz) { \ + m_Pool##sz.deallocate(ptr); \ + return; \ + } + ITERATE_POOLING_ALLOCATOR_POOL_SIZES +#undef HANDLE_POOLING_ALLOCATOR_POOL_SIZE + m_LargeAllocator.deallocate(ptr); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/PreAllocatedAllocator.h b/src/Runtime/Source/foundation/PreAllocatedAllocator.h new file mode 100644 index 00000000..aea03577 --- /dev/null +++ b/src/Runtime/Source/foundation/PreAllocatedAllocator.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_RENDER_PRE_ALLOCATED_ALLOCATOR_H +#define QT3DS_RENDER_PRE_ALLOCATED_ALLOCATOR_H +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace foundation { + + // Ignores deallocate calls if they originate withing the pre-allocation block + struct SPreAllocatedAllocator : public NVAllocatorCallback + { + NVAllocatorCallback &m_Allocator; + NVDataRef m_PreAllocatedBlock; + bool m_OwnsMemory; // then we attempt to deallocate on destruction + + SPreAllocatedAllocator(NVAllocatorCallback &inAllocator) + : m_Allocator(inAllocator) + , m_OwnsMemory(false) + { + } + + SPreAllocatedAllocator(NVAllocatorCallback &inAllocator, NVDataRef inData, + bool inOwnsMemory) + : m_Allocator(inAllocator) + , m_PreAllocatedBlock(inData) + , m_OwnsMemory(inOwnsMemory) + { + } + + virtual ~SPreAllocatedAllocator() + { + if (m_OwnsMemory) + m_Allocator.deallocate(m_PreAllocatedBlock.begin()); + } + + void *allocate(size_t size, const char *typeName, const char *filename, int line, + int flags = 0) override + { + return m_Allocator.allocate(size, typeName, filename, line, flags); + } + + void *allocate(size_t size, const char *typeName, const char *filename, int line, + size_t alignment, size_t alignmentOffset) override + { + return m_Allocator.allocate(size, typeName, filename, line, alignment, alignmentOffset); + } + + void deallocate(void *ptr) override + { + if (!ptr) + return; + if (ptr < m_PreAllocatedBlock.begin() || ptr >= m_PreAllocatedBlock.end()) + m_Allocator.deallocate(ptr); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DS.h b/src/Runtime/Source/foundation/Qt3DS.h new file mode 100644 index 00000000..041923c3 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DS.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_H +#define QT3DS_H +#include "EABase/eabase.h" +#include "foundation/Qt3DSPreprocessor.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSAssert.h" + +namespace eastl { +} + +namespace qt3ds { +class NVEmpty +{ +}; +class QT3DSMat33; +class QT3DSMat44; +class QT3DSVec2; +class QT3DSVec3; +class QT3DSVec4; +class NVTransform; + +#if !defined QT3DS_DONT_PRAGMA_WARNINGS && defined EA_COMPILER_MSVC +#pragma warning(disable : 4512) // assignment operator not generated +#endif + +#define QT3DS_SIGN_BITMASK 0x80000000 +} + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSAllocator.h b/src/Runtime/Source/foundation/Qt3DSAllocator.h new file mode 100644 index 00000000..cdbbe5f9 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSAllocator.h @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSALLOCATOR_H +#define QT3DS_FOUNDATION_PSALLOCATOR_H + +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" + +#if (defined(QT3DS_WINDOWS) | defined(QT3DS_X360)) +#include +#endif +#if (defined(QT3DS_APPLE)) +#include +#endif + +#include + +// Allocation macros going through user allocator +#define QT3DS_ALLOC(alloc, n, name) alloc.allocate(n, name, __FILE__, __LINE__) +#define QT3DS_ALLOC_TEMP(alloc, n, name) QT3DS_ALLOC(n, name) +#define QT3DS_FREE(alloc, x) alloc.deallocate(x) +#define QT3DS_FREE_AND_RESET(x) \ +{ \ + QT3DS_FREE(x); \ + x = 0; \ + } + +// The following macros support plain-old-types and classes derived from UserAllocated. +#define QT3DS_NEW(alloc, T) new (QT3DS_ALLOC(alloc, sizeof(T), #T)) T +#define QT3DS_NEW_TEMP(alloc, T) QT3DS_NEW(alloc, T) +#define QT3DS_DELETE_POD(x) \ +{ \ + QT3DS_FREE(x); \ + x = 0; \ + } + +namespace qt3ds { +namespace foundation { +template +inline void NVDelete(NVAllocatorCallback &alloc, TObjType *item) +{ + if (item) { + item->~TObjType(); + alloc.deallocate(item); + } +} +} +} + +//! placement new macro to make it easy to spot bad use of 'new' +#define QT3DS_PLACEMENT_NEW(p, T) new (p) T + +// Don't use inline for alloca !!! +#ifdef QT3DS_WINDOWS +#include +#define NVAlloca(x) _alloca(x) +#elif defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_QNX) +#if defined(__INTEGRITY) +#include +#else +#include +#endif +#define NVAlloca(x) alloca(x) +#elif defined(QT3DS_PSP2) +#include +#define NVAlloca(x) alloca(x) +#elif defined(QT3DS_APPLE) +#include +#include +#define NVAlloca(x) alloca(x) +#elif defined(QT3DS_PS3) +#include +#define NVAlloca(x) alloca(x) +#elif defined(QT3DS_X360) +#include +#define NVAlloca(x) _alloca(x) +#elif defined(QT3DS_WII) +#include +#define NVAlloca(x) alloca(x) +#endif + +namespace qt3ds { +namespace foundation { +/* + * Bootstrap allocator using malloc/free. + * Don't use unless your objects get allocated before foundation is initialized. + */ +class RawAllocator +{ +public: + RawAllocator(const char * = 0) {} + void *allocate(size_t size, const char *, int) + { +#if defined(QT3DS_APPLE) + // malloc returns valid pointer for size==0, no need to check + return malloc(size); +#else + // malloc returns valid pointer for size==0, no need to check + return ::malloc(size); +#endif + } + void deallocate(void *ptr) + { +#if defined(QT3DS_APPLE) + free(ptr); +#else + // free(0) is guaranteed to have no side effect, no need to check + ::free(ptr); +#endif + } +}; + +struct ForwardingAllocator +{ + NVAllocatorCallback *mAllocator; + const char *mTypeName; + ForwardingAllocator(const char *typeName) + : mTypeName(typeName) + { + } + ForwardingAllocator(NVAllocatorCallback &alloc, const char *typeName) + : mAllocator(&alloc) + , mTypeName(typeName) + { + } + ForwardingAllocator(NVAllocatorCallback *alloc = NULL) + : mAllocator(alloc) + , mTypeName("__error__") + { + QT3DS_ASSERT(false); + } + ForwardingAllocator(const ForwardingAllocator &other) + : mAllocator(other.mAllocator) + , mTypeName(other.mTypeName) + { + } + ForwardingAllocator &operator=(const ForwardingAllocator &other) + { + mAllocator = other.mAllocator; + mTypeName = other.mTypeName; + return *this; + } + bool operator==(const ForwardingAllocator &other) const + { + return mAllocator == other.mAllocator; + } + NVAllocatorCallback &getAllocator() { return *mAllocator; } + // flags are unused + void *allocate(size_t size, const char *filename, int line, int flags = 0) + { + return getAllocator().allocate(size, mTypeName, filename, line, flags); + } + void *allocate(size_t size, const char *filename, int line, size_t alignment, + size_t alignmentOffset) + { + return getAllocator().allocate(size, mTypeName, filename, line, alignment, + alignmentOffset); + } + void deallocate(void *ptr, size_t) { getAllocator().deallocate(ptr); } + void deallocate(void *ptr) { getAllocator().deallocate(ptr); } +}; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSAllocatorCallback.h b/src/Runtime/Source/foundation/Qt3DSAllocatorCallback.h new file mode 100644 index 00000000..ebbf8198 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSAllocatorCallback.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_ALLOCATOR_CALLBACK_H +#define QT3DS_FOUNDATION_QT3DS_ALLOCATOR_CALLBACK_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DS.h" +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/** +\brief Abstract base class for an application defined memory allocator that can be used by the NV +library. + +\note The SDK state should not be modified from within any allocation/free function. + +Threading: All methods of this class should be thread safe as it can be called from the user +thread +or the physics processing thread(s). +*/ + +class NVAllocatorCallback +{ +public: + /** + \brief destructor + */ + virtual ~NVAllocatorCallback() {} + + /** + \brief Allocates size bytes of memory, which must be 16-byte aligned. + + This method should never return NULL. If you run out of memory, then + you should terminate the app or take some other appropriate action. + + Threading: This function should be thread safe as it can be called in the context of the + user thread + and physics processing thread(s). + + \param size Number of bytes to allocate. + \param typeName Name of the datatype that is being allocated + \param filename The source file which allocated the memory + \param line The source line which allocated the memory + \return The allocated block of memory. + */ + virtual void *allocate(size_t size, const char *typeName, const char *filename, int line, + int flags = 0) = 0; + virtual void *allocate(size_t size, const char *typeName, const char *filename, int line, + size_t alignment, size_t alignmentOffset) = 0; + + /** + \brief Frees memory previously allocated by allocate(). + + Threading: This function should be thread safe as it can be called in the context of the + user thread + and physics processing thread(s). + + \param ptr Memory to free. + */ + virtual void deallocate(void *ptr) = 0; +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSAssert.h b/src/Runtime/Source/foundation/Qt3DSAssert.h new file mode 100644 index 00000000..a628159f --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSAssert.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_ASSERT_H +#define QT3DS_ASSERT_H +#include "foundation/Qt3DSPreprocessor.h" + +// Force the user to define the Qt3DSAssert function +namespace qt3ds { +void Qt3DSAssert(const char *exp, const char *file, int line, bool *ignore); +} + +#ifdef __CUDACC__ +#define QT3DS_ASSERT(exp) ((void)0) +#define QT3DS_ALWAYS_ASSERT_MESSAGE(exp) ((void)0) +#else // __CUDACC__ +#ifndef NDEBUG +#define QT3DS_ASSERT(exp) \ + { \ + static bool ignore = false; \ + (void)((!!(exp)) || (qt3ds::Qt3DSAssert(#exp, __FILE__, __LINE__, &ignore), false)); \ + } +#else // NDEBUG +#define QT3DS_ASSERT(exp) ((void)0) +#endif // NDEBUG +#define QT3DS_ALWAYS_ASSERT_MESSAGE(exp) \ + { \ + static bool ignore = false; \ + (void)((qt3ds::Qt3DSAssert(exp, __FILE__, __LINE__, &ignore), false)); \ + } +#endif // __CUDACC__ + +#define QT3DS_ALWAYS_ASSERT() QT3DS_ASSERT(0) + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSAtomic.h b/src/Runtime/Source/foundation/Qt3DSAtomic.h new file mode 100644 index 00000000..69c7d3b4 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSAtomic.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSATOMIC_H +#define QT3DS_FOUNDATION_PSATOMIC_H + +#include "foundation/Qt3DS.h" + +namespace qt3ds { +namespace foundation { + /* set *dest equal to val. Return the old value of *dest */ + QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicExchange(volatile QT3DSI32 *dest, QT3DSI32 val); + + /* if *dest == comp, replace with exch. Return original value of *dest */ + QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp); + + /* if *dest == comp, replace with exch. Return original value of *dest */ + QT3DS_AUTOTEST_EXPORT void *atomicCompareExchangePointer(volatile void **dest, void *exch, + void *comp); + + /* increment the specified location. Return the incremented value */ + QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicIncrement(volatile QT3DSI32 *val); + + /* decrement the specified location. Return the decremented value */ + QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicDecrement(volatile QT3DSI32 *val); + + /* add delta to *val. Return the new value */ + QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta); + + /* compute the maximum of dest and val. Return the new value */ + QT3DS_AUTOTEST_EXPORT QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2); + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSBasicTemplates.h b/src/Runtime/Source/foundation/Qt3DSBasicTemplates.h new file mode 100644 index 00000000..f14c7b32 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSBasicTemplates.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSBASICTEMPLATES_H +#define QT3DS_FOUNDATION_PSBASICTEMPLATES_H + +#include "foundation/Qt3DS.h" + +namespace qt3ds { +namespace foundation { + template + struct Equal + { + bool operator()(const A &a, const A &b) const { return a == b; } + }; + + template + struct Less + { + bool operator()(const A &a, const A &b) const { return a < b; } + }; + + template + struct Greater + { + bool operator()(const A &a, const A &b) const { return a > b; } + }; + + template + class Pair + { + public: + F first; + S second; + Pair() + : first(F()) + , second(S()) + { + } + Pair(const F &f, const S &s) + : first(f) + , second(s) + { + } + Pair(const Pair &p) + : first(p.first) + , second(p.second) + { + } + // CN - fix for /.../Qt3DSBasicTemplates.h(61) : warning C4512: 'nv::foundation::Pair' : + // assignment operator could not be generated + Pair &operator=(const Pair &p) + { + first = p.first; + second = p.second; + return *this; + } + bool operator==(const Pair &p) const { return first == p.first && second == p.second; } + }; + + template + struct LogTwo + { + static const unsigned int value = LogTwo<(A >> 1)>::value + 1; + }; + template <> + struct LogTwo<1> + { + static const unsigned int value = 0; + }; + + template + struct UnConst + { + typedef T Type; + }; + template + struct UnConst + { + typedef T Type; + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSBounds3.h b/src/Runtime/Source/foundation/Qt3DSBounds3.h new file mode 100644 index 00000000..fda4a6d4 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSBounds3.h @@ -0,0 +1,443 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_BOUNDS3_H +#define QT3DS_FOUNDATION_QT3DS_BOUNDS3_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSTransform.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DSMat44.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +typedef QT3DSVec3 TNVBounds2BoxPoints[8]; + +/** +\brief Class representing 3D range or axis aligned bounding box. + +Stored as minimum and maximum extent corners. Alternate representation +would be center and dimensions. +May be empty or nonempty. If not empty, minimum <= maximum has to hold. +*/ +class NVBounds3 +{ +public: + /** + \brief Default constructor, not performing any initialization for performance reason. + \remark Use empty() function below to construct empty bounds. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3() {} + + /** + \brief Construct from two bounding points + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3(const QT3DSVec3 &minimum, const QT3DSVec3 &maximum); + + /** + \brief Return empty bounds. + */ + static QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 empty(); + + /** + \brief returns the AABB containing v0 and v1. + \param v0 first point included in the AABB. + \param v1 second point included in the AABB. + */ + static QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 boundsOfPoints(const QT3DSVec3 &v0, + const QT3DSVec3 &v1); + + /** + \brief returns the AABB from center and extents vectors. + \param center Center vector + \param extent Extents vector + */ + static QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 centerExtents(const QT3DSVec3 ¢er, + const QT3DSVec3 &extent); + + /** + \brief Construct from center, extent, and (not necessarily orthogonal) basis + */ + static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 basisExtent(const QT3DSVec3 ¢er, + const QT3DSMat33 &basis, + const QT3DSVec3 &extent); + + /** + \brief Construct from pose and extent + */ + static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 poseExtent(const NVTransform &pose, + const QT3DSVec3 &extent); + + /** + \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB). + \param[in] matrix Transform to apply, can contain scaling as well + \param[in] bounds The bounds to transform. + */ + static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 transform(const QT3DSMat33 &matrix, + const NVBounds3 &bounds); + + /** + \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB). + \param[in] transform Transform to apply, can contain scaling as well + \param[in] bounds The bounds to transform. + */ + static QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 transform(const NVTransform &transform, + const NVBounds3 &bounds); + + /** + \brief Sets empty to true + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void setEmpty(); + + /** + \brief Sets infinite bounds + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void setInfinite(); + + /** + \brief expands the volume to include v + \param v Point to expand to. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void include(const QT3DSVec3 &v); + + /** + \brief expands the volume to include b. + \param b Bounds to perform union with. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void include(const NVBounds3 &b); + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isEmpty() const; + + /** + \brief indicates whether the intersection of this and b is empty or not. + \param b Bounds to test for intersection. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool intersects(const NVBounds3 &b) const; + + /** + \brief computes the 1D-intersection between two AABBs, on a given axis. + \param a the other AABB + \param axis the axis (0, 1, 2) + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool intersects1D(const NVBounds3 &a, QT3DSU32 axis) const; + + /** + \brief indicates if these bounds contain v. + \param v Point to test against bounds. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool contains(const QT3DSVec3 &v) const; + + /** + \brief checks a box is inside another box. + \param box the other AABB + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isInside(const NVBounds3 &box) const; + + /** + \brief returns the center of this axis aligned box. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getCenter() const; + + /** + \brief get component of the box's center along a given axis + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float getCenter(QT3DSU32 axis) const; + + /** + \brief get component of the box's extents along a given axis + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float getExtents(QT3DSU32 axis) const; + + /** + \brief returns the dimensions (width/height/depth) of this axis aligned box. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getDimensions() const; + + /** + \brief returns the extents, which are half of the width/height/depth. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getExtents() const; + + /** + \brief scales the AABB. + \param scale Factor to scale AABB by. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void scale(QT3DSF32 scale); + + /** + fattens the AABB in all 3 dimensions by the given distance. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void fatten(NVReal distance); + + /** + checks that the AABB values are not NaN + */ + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite() const; + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void expand(TNVBounds2BoxPoints &outPoints) const; + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void transform(const QT3DSMat44 &inMatrix); + + QT3DSVec3 minimum, maximum; +}; + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3::NVBounds3(const QT3DSVec3 &minimum, const QT3DSVec3 &maximum) + : minimum(minimum) + , maximum(maximum) +{ +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 NVBounds3::empty() +{ + return NVBounds3(QT3DSVec3(QT3DS_MAX_REAL), QT3DSVec3(-QT3DS_MAX_REAL)); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::isFinite() const +{ + return minimum.isFinite() && maximum.isFinite(); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 NVBounds3::boundsOfPoints(const QT3DSVec3 &v0, + const QT3DSVec3 &v1) +{ + return NVBounds3(v0.minimum(v1), v0.maximum(v1)); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVBounds3 NVBounds3::centerExtents(const QT3DSVec3 ¢er, + const QT3DSVec3 &extent) +{ + return NVBounds3(center - extent, center + extent); +} + +QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::basisExtent(const QT3DSVec3 ¢er, + const QT3DSMat33 &basis, + const QT3DSVec3 &extent) +{ + // extended basis vectors + QT3DSVec3 c0 = basis.column0 * extent.x; + QT3DSVec3 c1 = basis.column1 * extent.y; + QT3DSVec3 c2 = basis.column2 * extent.z; + + QT3DSVec3 w; + // find combination of base vectors that produces max. distance for each component = sum of + // abs() + w.x = NVAbs(c0.x) + NVAbs(c1.x) + NVAbs(c2.x); + w.y = NVAbs(c0.y) + NVAbs(c1.y) + NVAbs(c2.y); + w.z = NVAbs(c0.z) + NVAbs(c1.z) + NVAbs(c2.z); + + return NVBounds3(center - w, center + w); +} + +QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::poseExtent(const NVTransform &pose, + const QT3DSVec3 &extent) +{ + return basisExtent(pose.p, QT3DSMat33(pose.q), extent); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::setEmpty() +{ + minimum = QT3DSVec3(QT3DS_MAX_REAL); + maximum = QT3DSVec3(-QT3DS_MAX_REAL); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::setInfinite() +{ + minimum = QT3DSVec3(-QT3DS_MAX_REAL); + maximum = QT3DSVec3(QT3DS_MAX_REAL); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::include(const QT3DSVec3 &v) +{ + QT3DS_ASSERT(isFinite()); + minimum = minimum.minimum(v); + maximum = maximum.maximum(v); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::include(const NVBounds3 &b) +{ + QT3DS_ASSERT(isFinite()); + minimum = minimum.minimum(b.minimum); + maximum = maximum.maximum(b.maximum); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::isEmpty() const +{ + QT3DS_ASSERT(isFinite()); + // Consistency condition for (Min, Max) boxes: minimum < maximum + return minimum.x > maximum.x || minimum.y > maximum.y || minimum.z > maximum.z; +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::intersects(const NVBounds3 &b) const +{ + QT3DS_ASSERT(isFinite() && b.isFinite()); + return !(b.minimum.x > maximum.x || minimum.x > b.maximum.x || b.minimum.y > maximum.y + || minimum.y > b.maximum.y || b.minimum.z > maximum.z || minimum.z > b.maximum.z); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::intersects1D(const NVBounds3 &a, QT3DSU32 axis) const +{ + QT3DS_ASSERT(isFinite() && a.isFinite()); + return maximum[axis] >= a.minimum[axis] && a.maximum[axis] >= minimum[axis]; +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::contains(const QT3DSVec3 &v) const +{ + QT3DS_ASSERT(isFinite()); + + return !(v.x < minimum.x || v.x > maximum.x || v.y < minimum.y || v.y > maximum.y + || v.z < minimum.z || v.z > maximum.z); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVBounds3::isInside(const NVBounds3 &box) const +{ + QT3DS_ASSERT(isFinite() && box.isFinite()); + if (box.minimum.x > minimum.x) + return false; + if (box.minimum.y > minimum.y) + return false; + if (box.minimum.z > minimum.z) + return false; + if (box.maximum.x < maximum.x) + return false; + if (box.maximum.y < maximum.y) + return false; + if (box.maximum.z < maximum.z) + return false; + return true; +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 NVBounds3::getCenter() const +{ + QT3DS_ASSERT(isFinite()); + return (minimum + maximum) * NVReal(0.5); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVBounds3::getCenter(QT3DSU32 axis) const +{ + QT3DS_ASSERT(isFinite()); + return (minimum[axis] + maximum[axis]) * NVReal(0.5); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVBounds3::getExtents(QT3DSU32 axis) const +{ + QT3DS_ASSERT(isFinite()); + return (maximum[axis] - minimum[axis]) * NVReal(0.5); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 NVBounds3::getDimensions() const +{ + QT3DS_ASSERT(isFinite()); + return maximum - minimum; +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 NVBounds3::getExtents() const +{ + QT3DS_ASSERT(isFinite()); + return getDimensions() * NVReal(0.5); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::scale(QT3DSF32 scale) +{ + QT3DS_ASSERT(isFinite()); + *this = centerExtents(getCenter(), getExtents() * scale); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::fatten(NVReal distance) +{ + QT3DS_ASSERT(isFinite()); + minimum.x -= distance; + minimum.y -= distance; + minimum.z -= distance; + + maximum.x += distance; + maximum.y += distance; + maximum.z += distance; +} + +QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::transform(const QT3DSMat33 &matrix, + const NVBounds3 &bounds) +{ + QT3DS_ASSERT(bounds.isFinite()); + return bounds.isEmpty() ? bounds : NVBounds3::basisExtent(matrix * bounds.getCenter(), matrix, + bounds.getExtents()); +} + +QT3DS_CUDA_CALLABLE QT3DS_INLINE NVBounds3 NVBounds3::transform(const NVTransform &transform, + const NVBounds3 &bounds) +{ + QT3DS_ASSERT(bounds.isFinite()); + return bounds.isEmpty() ? bounds + : NVBounds3::basisExtent(transform.transform(bounds.getCenter()), + QT3DSMat33(transform.q), bounds.getExtents()); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::expand(TNVBounds2BoxPoints &outPoints) const +{ + if (isEmpty()) { + for (QT3DSU32 idx = 0; idx < 8; ++idx) + outPoints[idx] = QT3DSVec3(0, 0, 0); + } else { + // Min corner of box + outPoints[0] = QT3DSVec3(minimum[0], minimum[1], minimum[2]); + outPoints[1] = QT3DSVec3(maximum[0], minimum[1], minimum[2]); + outPoints[2] = QT3DSVec3(minimum[0], maximum[1], minimum[2]); + outPoints[3] = QT3DSVec3(minimum[0], minimum[1], maximum[2]); + + // Max corner of box + outPoints[4] = QT3DSVec3(maximum[0], maximum[1], maximum[2]); + outPoints[5] = QT3DSVec3(minimum[0], maximum[1], maximum[2]); + outPoints[6] = QT3DSVec3(maximum[0], minimum[1], maximum[2]); + outPoints[7] = QT3DSVec3(maximum[0], maximum[1], minimum[2]); + } +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void NVBounds3::transform(const QT3DSMat44 &inMatrix) +{ + if (!isEmpty()) { + TNVBounds2BoxPoints thePoints; + expand(thePoints); + setEmpty(); + for (QT3DSU32 idx = 0; idx < 8; ++idx) + include(inMatrix.transform(thePoints[idx])); + } +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_BOUNDS3_H diff --git a/src/Runtime/Source/foundation/Qt3DSBroadcastingAllocator.h b/src/Runtime/Source/foundation/Qt3DSBroadcastingAllocator.h new file mode 100644 index 00000000..dc6ae7b5 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSBroadcastingAllocator.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_BROADCASTING_ALLOCATOR_H +#define QT3DS_FOUNDATION_QT3DS_BROADCASTING_ALLOCATOR_H + +#include "foundation/Qt3DSAllocatorCallback.h" + +/** \addtogroup foundation + @{ +*/ +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/** +\brief Abstract listener class that listens to allocation and deallocation events from the + foundation memory system. + +Threading: All methods of this class should be thread safe as it can be called from the user +thread +or the physics processing thread(s). +*/ +class NVAllocationListener +{ +protected: + virtual ~NVAllocationListener() {} + +public: + /** + \brief callback when memory is allocated. + \param size Size of the allocation in bytes. + \param typeName Type this data is being allocated for. + \param filename File the allocation came from. + \param line the allocation came from. + \param allocatedMemory memory that will be returned from the allocation. + */ + virtual void onAllocation(size_t size, const char *typeName, const char *filename, int line, + void *allocatedMemory) = 0; + + /** + /brief callback when memory is deallocated. + /param allocatedMemory memory just before allocation. + */ + virtual void onDeallocation(void *allocatedMemory) = 0; +}; + +/** +\brief Abstract base class for an application defined memory allocator that allows an external +listener +to audit the memory allocations. + +Threading: Register/deregister are *not* threadsafe!!! +You need to be sure multiple threads are using this allocator when you are adding +new listeners. +*/ +class NVBroadcastingAllocator : public NVAllocatorCallback +{ +protected: + virtual ~NVBroadcastingAllocator() {} + +public: + /** + \brief Register an allocation listener. This object will be notified whenever an + allocation happens. + + Threading:Not threadsafe if you are allocating and deallocating in another + thread using this allocator. + */ + virtual void registerAllocationListener(NVAllocationListener &inListener) = 0; + /** + \brief Deregister an allocation listener. This object will no longer receive + notifications upon allocation. + + Threading:Not threadsafe if you are allocating and deallocating in another + thread using this allocator. + */ + virtual void deregisterAllocationListener(NVAllocationListener &inListener) = 0; +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_BROADCASTING_ALLOCATOR_H diff --git a/src/Runtime/Source/foundation/Qt3DSContainers.h b/src/Runtime/Source/foundation/Qt3DSContainers.h new file mode 100644 index 00000000..de86d856 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSContainers.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_CONTAINERS_H +#define QT3DS_CONTAINERS_H +#include "foundation/Qt3DS.h" +#include "EASTL/vector.h" +#include "EASTL/hash_map.h" +#include "EASTL/hash_set.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace foundation { + + template + class nvvector : public eastl::vector + { + typedef eastl::vector base_type; + + public: + using base_type::data; + using base_type::size; + + nvvector(NVAllocatorCallback &inAllocator, const char *inTypeName) + : eastl::vector(ForwardingAllocator(inAllocator, inTypeName)) + { + } + nvvector(const nvvector &inOther) + : eastl::vector(inOther) + { + } + nvvector &operator=(const nvvector &inOther) + { + eastl::vector::operator=(inOther); + return *this; + } + operator NVConstDataRef() const { return NVConstDataRef(data(), size()); } + operator NVDataRef() { return NVDataRef(data(), size()); } + }; + + template , + typename TPredicate = eastl::equal_to> + class nvhash_map : public eastl::hash_map + { + typedef eastl::hash_map base_type; + + public: + using base_type::find; + using base_type::end; + + nvhash_map(NVAllocatorCallback &inAllocator, const char *inTypeName) + : eastl::hash_map( + ForwardingAllocator(inAllocator, inTypeName)) + { + } + nvhash_map(const nvhash_map &inOther) + : eastl::hash_map(inOther) + { + } + nvhash_map & + operator=(const nvhash_map &inOther) + { + eastl::hash_map::operator=( + inOther); + return *this; + } + bool contains(const TKey &inKey) const { return find(inKey) != end(); } + }; + + template , + typename TPredicate = eastl::equal_to> + class nvhash_set : public eastl::hash_set + { + typedef eastl::hash_set base_type; + + public: + using base_type::find; + using base_type::end; + + nvhash_set(NVAllocatorCallback &inAllocator, const char *inTypeName) + : eastl::hash_set( + ForwardingAllocator(inAllocator, inTypeName)) + { + } + nvhash_set(const nvhash_map &inOther) + : eastl::hash_set(inOther) + { + } + nvhash_set & + operator=(const nvhash_set &inOther) + { + eastl::hash_set::operator=(inOther); + return *this; + } + bool contains(const TKey &inKey) const { return find(inKey) != end(); } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSDataRef.h b/src/Runtime/Source/foundation/Qt3DSDataRef.h new file mode 100644 index 00000000..ad860cef --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSDataRef.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_DATA_REF_H +#define QT3DS_FOUNDATION_DATA_REF_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" + +namespace qt3ds { +namespace foundation { + + template + struct NVConstDataRef + { + const TDataType *mData; + QT3DSU32 mSize; + + NVConstDataRef(const TDataType *inData, QT3DSU32 inSize) + : mData(inData) + , mSize(inSize) + { + } + NVConstDataRef() + : mData(0) + , mSize(0) + { + } + + QT3DSU32 size() const { return mSize; } + + const TDataType *begin() const { return mData; } + const TDataType *end() const { return mData + mSize; } + + const TDataType &operator[](QT3DSU32 index) const + { + QT3DS_ASSERT(index < mSize); + return mData[index]; + } + }; + + template + inline NVConstDataRef toConstDataRef(const TDataType &type) + { + return NVConstDataRef(&type, 1); + } + + template + inline NVConstDataRef toU8ConstDataRef(const TDataType &type) + { + return NVConstDataRef(reinterpret_cast(&type), sizeof(TDataType)); + } + + template + inline NVConstDataRef toConstDataRef(const TDataType *type, QT3DSU32 count) + { + return NVConstDataRef(type, count); + } + + template + inline NVConstDataRef toU8ConstDataRef(const TDataType *type, QT3DSU32 count) + { + return NVConstDataRef(reinterpret_cast(type), + sizeof(TDataType) * count); + } + + template + struct NVDataRef + { + TDataType *mData; + QT3DSU32 mSize; + + NVDataRef(TDataType *inData, QT3DSU32 inSize) + : mData(inData) + , mSize(inSize) + { + } + NVDataRef() + : mData(0) + , mSize(0) + { + } + QT3DSU32 size() const { return mSize; } + + TDataType *begin() { return mData; } + TDataType *end() { return mData + mSize; } + + TDataType *begin() const { return mData; } + TDataType *end() const { return mData + mSize; } + + TDataType &operator[](QT3DSU32 index) + { + QT3DS_ASSERT(index < mSize); + return mData[index]; + } + + const TDataType &operator[](QT3DSU32 index) const + { + QT3DS_ASSERT(index < mSize); + return mData[index]; + } + + operator NVConstDataRef() const + { + return NVConstDataRef(mData, mSize); + } + }; + + template + inline NVDataRef toDataRef(TDataType &type) + { + return NVDataRef(&type, 1); + } + + template + inline NVDataRef toU8DataRef(TDataType &type) + { + return NVDataRef(reinterpret_cast(&type), sizeof(TDataType)); + } + + template + inline NVDataRef toDataRef(TDataType *type, QT3DSU32 count) + { + return NVDataRef(type, count); + } + + template + inline NVDataRef toU8DataRef(TDataType *type, QT3DSU32 count) + { + return NVDataRef(reinterpret_cast(type), sizeof(TDataType) * count); + } +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSDiscriminatedUnion.h b/src/Runtime/Source/foundation/Qt3DSDiscriminatedUnion.h new file mode 100644 index 00000000..1957eb23 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSDiscriminatedUnion.h @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_DISCRIMINATED_UNION_H +#define QT3DS_FOUNDATION_DISCRIMINATED_UNION_H +#include "Qt3DSAssert.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSUnionCast.h" + +#ifdef WIN32 +#pragma warning(disable : 4100) +#endif + +namespace qt3ds { +namespace foundation { + + template + class DiscriminatedUnion + { + public: + typedef DiscriminatedUnion TThisType; + typedef TUnionTraits TTraits; + typedef typename TTraits::TIdType TIdType; + + protected: + char m_Data[TBufferSize]; + // Id type must include a no-data type. + TIdType m_DataType; + + public: + DiscriminatedUnion() { TTraits::defaultConstruct(m_Data, m_DataType); } + + DiscriminatedUnion(const TThisType &inOther) + : m_DataType(inOther.m_DataType) + { + TTraits::copyConstruct(m_Data, inOther.m_Data, m_DataType); + } + + template + DiscriminatedUnion(const TDataType &inType) + { + TTraits::copyConstruct(m_Data, m_DataType, inType); + } + + ~DiscriminatedUnion() { TTraits::destruct(m_Data, m_DataType); } + + TThisType &operator=(const TThisType &inType) + { + if (this != &inType) { + TTraits::destruct(m_Data, m_DataType); + m_DataType = inType.m_DataType; + TTraits::copyConstruct(m_Data, inType.m_Data, inType.m_DataType); + } + return *this; + } + + typename TTraits::TIdType getType() const { return m_DataType; } + + template + const TDataType *getDataPtr() const + { + return TTraits::template getDataPtr(m_Data, m_DataType); + } + + template + TDataType *getDataPtr() + { + return TTraits::template getDataPtr(m_Data, m_DataType); + } + + template + TDataType getData() const + { + const TDataType *dataPtr = getDataPtr(); + if (dataPtr) + return *dataPtr; + QT3DS_ASSERT(false); + return TDataType(); + } + + bool operator==(const TThisType &inOther) const + { + return m_DataType == inOther.m_DataType + && TTraits::areEqual(m_Data, inOther.m_Data, m_DataType); + } + + bool operator!=(const TThisType &inOther) const + { + return m_DataType != inOther.m_DataType + || TTraits::areEqual(m_Data, inOther.m_Data, m_DataType) == false; + } + + template + TRetType visit(TVisitorType inVisitor) + { + return TTraits::template visit(m_Data, m_DataType, inVisitor); + } + + template + TRetType visit(TVisitorType inVisitor) const + { + return TTraits::template visit(m_Data, m_DataType, inVisitor); + } + }; + + // Helper system to enable quicker and correct construction of union traits types + + struct CopyConstructVisitor + { + const char *m_Src; + CopyConstructVisitor(const char *inSrc) + : m_Src(inSrc) + { + } + + template + void operator()(TDataType &inDst) + { + new (&inDst) TDataType(*NVUnionCast(m_Src)); + } + void operator()() { QT3DS_ASSERT(false); } + }; + + template + struct DestructTraits + { + void destruct(TDataType &inType) { inType.~TDataType(); } + }; + + // Until compilers improve a bit, you need this for POD types else you get + // unused parameter warnings. + template <> + struct DestructTraits + { + void destruct(QT3DSU8 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSI8 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSU16 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSI16 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSU32 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSI32 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSU64 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSI64 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSF32 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSF64 &) {} + }; + template <> + struct DestructTraits + { + void destruct(bool &) {} + }; + template <> + struct DestructTraits + { + void destruct(void *&) {} + }; +#ifdef __INTEGRITY + template <> + struct DestructTraits + { + void destruct(QT3DSVec2 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSVec3 &) {} + }; +#endif + + struct DestructVisitor + { + template + void operator()(TDataType &inDst) + { + DestructTraits().destruct(inDst); + } + void operator()() { QT3DS_ASSERT(false); } + }; + + template + struct EqualVisitorTraits + { + bool operator()(const TDataType &lhs, const TDataType &rhs) { return lhs == rhs; } + }; + + struct EqualVisitor + { + const char *m_Rhs; + EqualVisitor(const char *rhs) + : m_Rhs(rhs) + { + } + template + bool operator()(const TDataType &lhs) + { + const TDataType &rhs(*NVUnionCast(m_Rhs)); + return EqualVisitorTraits()(lhs, rhs); + } + bool operator()() + { + QT3DS_ASSERT(false); + return true; + } + }; + + template + struct DiscriminatedUnionGenericBase : public TBase + { + typedef typename TBase::TIdType TIdType; + + static void zeroBuf(char *outDst) { qt3ds::intrinsics::memZero(outDst, TBufferSize); } + + static void defaultConstruct(char *outDst, TIdType &outType) + { + zeroBuf(outDst); + outType = TBase::getNoDataId(); + } + + template + static void copyConstruct(char *outDst, TIdType &outType, const TDataType &inSrc) + { + zeroBuf(outDst); + StaticAssert::valid_expression(); + outType = TBase::template getType(); + new (outDst) TDataType(inSrc); + } + + static void copyConstruct(char *inDst, const char *inSrc, TIdType inType) + { + if (inType == TBase::getNoDataId()) + zeroBuf(inDst); + else + TBase::template visit(inDst, inType, CopyConstructVisitor(inSrc)); + } + + static void destruct(char *inDst, TIdType inType) + { + if (inType != TBase::getNoDataId()) + TBase::template visit(inDst, inType, DestructVisitor()); + zeroBuf(inDst); + } + + template + static const TDataType *getDataPtr(const char *inData, const TIdType &inType) + { + if (TBase::template getType() == inType) + return NVUnionCast(inData); + QT3DS_ASSERT(false); + return NULL; + } + + template + static TDataType *getDataPtr(char *inData, const TIdType &inType) + { + if (TBase::template getType() == inType) + return NVUnionCast(inData); + QT3DS_ASSERT(false); + return NULL; + } + + static bool areEqual(const char *inLhs, const char *inRhs, TIdType inType) + { + if (inType != TBase::getNoDataId()) + return TBase::template visit(inLhs, inType, EqualVisitor(inRhs)); + else + return true; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSFPU.h b/src/Runtime/Source/foundation/Qt3DSFPU.h new file mode 100644 index 00000000..e4a47f0c --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSFPU.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSFPU_H +#define QT3DS_FOUNDATION_PSFPU_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSUnionCast.h" + +// unsigned integer representation of a floating-point value. +#ifdef QT3DS_PS3 +QT3DS_FORCE_INLINE unsigned int QT3DS_IR(const float x) +{ + return qt3ds::NVUnionCast(x); +} +#else +#define QT3DS_IR(x) ((QT3DSU32 &)(x)) +#endif + +// signed integer representation of a floating-point value. +#ifdef QT3DS_PS3 +QT3DS_FORCE_INLINE int QT3DS_SIR(const float x) +{ + return qt3ds::NVUnionCast(x); +} +#else +#define QT3DS_SIR(x) ((QT3DSI32 &)(x)) +#endif + +// Floating-point representation of a integer value. +#ifdef QT3DS_PS3 +QT3DS_FORCE_INLINE float QT3DS_FR(const unsigned int x) +{ + return qt3ds::NVUnionCast(x); +} +#else +#define QT3DS_FR(x) ((QT3DSF32 &)(x)) +#endif + +#ifdef QT3DS_PS3 +QT3DS_FORCE_INLINE float *QT3DS_FPTR(unsigned int *x) +{ + return qt3ds::NVUnionCast(x); +} + +QT3DS_FORCE_INLINE float *QT3DS_FPTR(int *x) +{ + return qt3ds::NVUnionCast(x); +} +#else +#define QT3DS_FPTR(x) ((QT3DSF32 *)(x)) +#endif + +#define QT3DS_SIGN_BITMASK 0x80000000 + +namespace qt3ds { +namespace foundation { +class QT3DS_FOUNDATION_API FPUGuard +{ +public: + FPUGuard(); // set fpu control word for PhysX + ~FPUGuard(); // restore fpu control word +private: + QT3DSU32 mControlWords[8]; +}; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSFastIPC.h b/src/Runtime/Source/foundation/Qt3DSFastIPC.h new file mode 100644 index 00000000..800c3dfd --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSFastIPC.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FAST_IPC_H +#define QT3DS_FAST_IPC_H + +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSIPC.h" + +namespace qt3ds { +namespace foundation { + + NVIPC *createFastIPC( + NVIPC::ErrorCode &errorCode, // error code return if creation fails + NVIPC::ConnectionType connectionType = + NVIPC::CT_CLIENT_OR_SERVER, // how to establish the connection + const char *mappingObject = "Global\\FastIPC", // Name of communications channel + QT3DSU32 serverRingBufferSize = 1024 * 4, // buffer size for outgoing server messages. + QT3DSU32 clientRingBufferSize = 1024 * 4, // buffer size for incoming client messages. + bool allowLongMessages = true, + bool bufferSends = false, + QT3DSU32 maxBufferSendSize = 1024 * 8); // True if we want to buffer sends, if true, then + // pumpSendBuffers should be called by the send thread. + + void releaseFastIPC(NVIPC *f); + +}; // end of namespace +}; // end of namespace + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSFlags.h b/src/Runtime/Source/foundation/Qt3DSFlags.h new file mode 100644 index 00000000..765f386f --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSFlags.h @@ -0,0 +1,360 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_FLAGS_H +#define QT3DS_FOUNDATION_QT3DS_FLAGS_H + +/** \addtogroup foundation + @{ +*/ + +#include "foundation/Qt3DS.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif +/** +\brief Container for bitfield flag variables associated with a specific enum type. + +This allows for type safe manipulation for bitfields. + +

Example

+ // enum that defines each bit... + struct MyEnum + { + enum Enum + { + eMAN = 1, + eBEAR = 2, + ePIG = 4, + }; + }; + + // implements some convenient global operators. + QT3DS_FLAGS_OPERATORS(MyEnum::Enum, QT3DSU8); + + NVFlags myFlags; + myFlags |= MyEnum::eMAN; + myFlags |= MyEnum::eBEAR | MyEnum::ePIG; + if(myFlags & MyEnum::eBEAR) + { + doSomething(); + } +*/ +template +class NVFlags +{ +public: + QT3DS_INLINE explicit NVFlags(const NVEmpty &) {} + QT3DS_INLINE NVFlags(void); + QT3DS_INLINE NVFlags(enumtype e); + QT3DS_INLINE NVFlags(const NVFlags &f); + QT3DS_INLINE explicit NVFlags(storagetype b); + + QT3DS_INLINE bool operator==(enumtype e) const; + QT3DS_INLINE bool operator==(const NVFlags &f) const; + QT3DS_INLINE bool operator==(bool b) const; + QT3DS_INLINE bool operator!=(enumtype e) const; + QT3DS_INLINE bool operator!=(const NVFlags &f) const; + + QT3DS_INLINE NVFlags &operator=(enumtype e); + + QT3DS_INLINE NVFlags &operator|=(enumtype e); + QT3DS_INLINE NVFlags &operator|=(const NVFlags &f); + QT3DS_INLINE NVFlags operator|(enumtype e) const; + QT3DS_INLINE NVFlags + operator|(const NVFlags &f) const; + + QT3DS_INLINE NVFlags &operator&=(enumtype e); + QT3DS_INLINE NVFlags &operator&=(const NVFlags &f); + QT3DS_INLINE NVFlags operator&(enumtype e) const; + QT3DS_INLINE NVFlags + operator&(const NVFlags &f) const; + + QT3DS_INLINE NVFlags &operator^=(enumtype e); + QT3DS_INLINE NVFlags &operator^=(const NVFlags &f); + QT3DS_INLINE NVFlags operator^(enumtype e) const; + QT3DS_INLINE NVFlags + operator^(const NVFlags &f) const; + + QT3DS_INLINE NVFlags operator~(void)const; + + QT3DS_INLINE operator bool(void) const; + QT3DS_INLINE operator QT3DSU8(void) const; + QT3DS_INLINE operator QT3DSU16(void) const; + QT3DS_INLINE operator QT3DSU32(void) const; + + QT3DS_INLINE void clear(enumtype e); + + QT3DS_INLINE void clearOrSet(bool value, enumtype enumVal); + +public: + friend QT3DS_INLINE NVFlags operator&(enumtype a, + NVFlags &b) + { + NVFlags out; + out.mBits = a & b.mBits; + return out; + } + +private: + storagetype mBits; +}; + +#define QT3DS_FLAGS_OPERATORS(enumtype, storagetype) \ + QT3DS_INLINE NVFlags operator|(enumtype a, enumtype b) \ +{ \ + NVFlags r(a); \ + r |= b; \ + return r; \ +} \ + QT3DS_INLINE NVFlags operator&(enumtype a, enumtype b) \ +{ \ + NVFlags r(a); \ + r &= b; \ + return r; \ +} \ + QT3DS_INLINE NVFlags operator~(enumtype a) \ +{ \ + return ~NVFlags(a); \ +} + +template +QT3DS_INLINE NVFlags::NVFlags(void) +{ + mBits = 0; +} + +template +QT3DS_INLINE NVFlags::NVFlags(enumtype e) +{ + mBits = static_cast(e); +} + +template +QT3DS_INLINE NVFlags::NVFlags(const NVFlags &f) +{ + mBits = f.mBits; +} + +template +QT3DS_INLINE NVFlags::NVFlags(storagetype b) +{ + mBits = b; +} + +template +QT3DS_INLINE bool NVFlags::operator==(enumtype e) const +{ + return mBits == static_cast(e); +} + +template +QT3DS_INLINE bool NVFlags:: +operator==(const NVFlags &f) const +{ + return mBits == f.mBits; +} + +template +QT3DS_INLINE bool NVFlags::operator==(bool b) const +{ + return ((bool)*this) == b; +} + +template +QT3DS_INLINE bool NVFlags::operator!=(enumtype e) const +{ + return mBits != static_cast(e); +} + +template +QT3DS_INLINE bool NVFlags:: +operator!=(const NVFlags &f) const +{ + return mBits != f.mBits; +} + +template +QT3DS_INLINE NVFlags &NVFlags::operator=(enumtype e) +{ + mBits = static_cast(e); + return *this; +} + +template +QT3DS_INLINE NVFlags &NVFlags::operator|=(enumtype e) +{ + mBits |= static_cast(e); + return *this; +} + +template +QT3DS_INLINE NVFlags &NVFlags:: +operator|=(const NVFlags &f) +{ + mBits |= f.mBits; + return *this; +} + +template +QT3DS_INLINE NVFlags NVFlags::operator|(enumtype e) const +{ + NVFlags out(*this); + out |= e; + return out; +} + +template +QT3DS_INLINE NVFlags NVFlags:: +operator|(const NVFlags &f) const +{ + NVFlags out(*this); + out |= f; + return out; +} + +template +QT3DS_INLINE NVFlags &NVFlags::operator&=(enumtype e) +{ + mBits &= static_cast(e); + return *this; +} + +template +QT3DS_INLINE NVFlags &NVFlags:: +operator&=(const NVFlags &f) +{ + mBits &= f.mBits; + return *this; +} + +template +QT3DS_INLINE NVFlags NVFlags::operator&(enumtype e) const +{ + NVFlags out = *this; + out.mBits &= static_cast(e); + return out; +} + +template +QT3DS_INLINE NVFlags NVFlags:: +operator&(const NVFlags &f) const +{ + NVFlags out = *this; + out.mBits &= f.mBits; + return out; +} + +template +QT3DS_INLINE NVFlags &NVFlags::operator^=(enumtype e) +{ + mBits ^= static_cast(e); + return *this; +} + +template +QT3DS_INLINE NVFlags &NVFlags:: +operator^=(const NVFlags &f) +{ + mBits ^= f.mBits; + return *this; +} + +template +QT3DS_INLINE NVFlags NVFlags::operator^(enumtype e) const +{ + NVFlags out = *this; + out.mBits ^= static_cast(e); + return out; +} + +template +QT3DS_INLINE NVFlags NVFlags:: +operator^(const NVFlags &f) const +{ + NVFlags out = *this; + out.mBits ^= f.mBits; + return out; +} + +template +QT3DS_INLINE NVFlags NVFlags::operator~(void)const +{ + NVFlags out; + out.mBits = ~mBits; + return out; +} + +template +QT3DS_INLINE NVFlags::operator bool(void) const +{ + return mBits ? true : false; +} + +template +QT3DS_INLINE NVFlags::operator QT3DSU8(void) const +{ + return static_cast(mBits); +} + +template +QT3DS_INLINE NVFlags::operator QT3DSU16(void) const +{ + return static_cast(mBits); +} + +template +QT3DS_INLINE NVFlags::operator QT3DSU32(void) const +{ + return static_cast(mBits); +} + +template +QT3DS_INLINE void NVFlags::clear(enumtype e) +{ + mBits &= ~static_cast(e); +} + +template +QT3DS_INLINE void NVFlags::clearOrSet(bool value, enumtype enumVal) +{ + if (value) + this->operator|=(enumVal); + else + clear(enumVal); +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // #ifndef QT3DS_FOUNDATION_QT3DS_FLAGS_H diff --git a/src/Runtime/Source/foundation/Qt3DSFoundation.cpp b/src/Runtime/Source/foundation/Qt3DSFoundation.cpp new file mode 100644 index 00000000..8687cd69 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSFoundation.cpp @@ -0,0 +1,237 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSFoundation.h" + +#include "foundation/Qt3DSQuat.h" +#include "foundation/Qt3DSThread.h" +#include "foundation/Qt3DSUtilities.h" +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSLogging.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "EASTL/hash_map.h" + +#include +#ifdef _WIN32 +#pragma warning(disable : 4996) // intentionally suppressing this warning message +#endif +namespace qt3ds { +namespace foundation { + using namespace intrinsics; + union TempAllocatorChunk; + + class NVAllocatorListenerManager; + + class QT3DS_FOUNDATION_API Foundation : public NVFoundation + { + + Foundation(NVAllocatorCallback &alloc); + ~Foundation(); + + public: + void addRef() override; + void release() override; + + // factory + static Foundation *createInstance(QT3DSU32 version, NVAllocatorCallback &alloc); + + NVBroadcastingAllocator &getAllocator() const override { return mAllocator; } + NVAllocatorCallback &getAllocatorCallback() const override; + NVAllocatorCallback &getCheckedAllocator() { return mAllocator; } + + private: + class AlignCheckAllocator : public NVBroadcastingAllocator + { + static const QT3DSU32 MaxListenerCount = 5; + + public: + AlignCheckAllocator(NVAllocatorCallback &originalAllocator) + : mAllocator(originalAllocator) + , mListenerCount(0) + { + } + + void deallocate(void *ptr) override + { + // So here, for performance reasons I don't grab the mutex. + // The listener array is very rarely changing; for most situations + // only at startup. So it is unlikely that using the mutex + // will help a lot but it could have serious perf implications. + QT3DSU32 theCount = mListenerCount; + for (QT3DSU32 idx = 0; idx < theCount; ++idx) + mListeners[idx]->onDeallocation(ptr); + mAllocator.deallocate(ptr); + } + void *allocate(size_t size, const char *typeName, const char *filename, int line, + int flags) override; + void *allocate(size_t size, const char *typeName, const char *filename, int line, + size_t alignment, size_t alignmentOffset) override; + NVAllocatorCallback &getBaseAllocator() const { return mAllocator; } + void registerAllocationListener(NVAllocationListener &inListener) override + { + QT3DS_ASSERT(mListenerCount < MaxListenerCount); + if (mListenerCount < MaxListenerCount) { + mListeners[mListenerCount] = &inListener; + ++mListenerCount; + } + } + void deregisterAllocationListener(NVAllocationListener &inListener) override + { + for (QT3DSU32 idx = 0; idx < mListenerCount; ++idx) { + if (mListeners[idx] == &inListener) { + mListeners[idx] = mListeners[mListenerCount - 1]; + --mListenerCount; + break; + } + } + } + + private: + NVAllocatorCallback &mAllocator; + // I am not sure about using a NVArray here. + // For now, this is fine. + NVAllocationListener *mListeners[MaxListenerCount]; + volatile QT3DSU32 mListenerCount; + }; + + mutable AlignCheckAllocator mAllocator; + QT3DSU32 mRefCount; + Mutex mRefCountMutex; + }; + + Foundation::Foundation(NVAllocatorCallback &alloc) + : mAllocator(alloc) + , mRefCount(0) + , mRefCountMutex(alloc) + + { + } + + Foundation::~Foundation() {} + + NVAllocatorCallback &Foundation::getAllocatorCallback() const + { + return mAllocator.getBaseAllocator(); + } + + Foundation *Foundation::createInstance(QT3DSU32 version, NVAllocatorCallback &alloc) + { + if (version != QT3DS_FOUNDATION_VERSION) { + qCCritical(INVALID_PARAMETER, "Wrong version: foundation version is %d, tried to create %d", + QT3DS_FOUNDATION_VERSION, version); + return 0; + } + Foundation *mInstance = NULL; + + if (!mInstance) { + // if we don't assign this here, the Foundation object can't create member + // subobjects which require the allocator + + mInstance = reinterpret_cast( + alloc.allocate(sizeof(Foundation), "Foundation", __FILE__, __LINE__)); + + if (mInstance) { + QT3DS_PLACEMENT_NEW(mInstance, Foundation)(alloc); + + QT3DS_ASSERT(mInstance->mRefCount == 0); + + return mInstance; + } else { + qCCritical(INTERNAL_ERROR, "Memory allocation for foundation object failed."); + } + } else { + qCCritical( + INVALID_OPERATION, + "Foundation object exists already. Only one instance per process can be created."); + } + + return 0; + } + + void Foundation::addRef() + { + mRefCountMutex.lock(); + ++mRefCount; + mRefCountMutex.unlock(); + } + + void Foundation::release() + { + mRefCountMutex.lock(); + if (mRefCount) + --mRefCount; + QT3DSU32 refCount = mRefCount; + mRefCountMutex.unlock(); + if (!refCount) { + NVAllocatorCallback &alloc = mAllocator.getBaseAllocator(); + this->~Foundation(); + alloc.deallocate(this); + } + } + + void *Foundation::AlignCheckAllocator::allocate(size_t size, const char *typeName, + const char *filename, int line, int) + { + void *addr = mAllocator.allocate(size, typeName, filename, line); + + if (!addr) + qFatal("User allocator returned NULL."); + + if (!(reinterpret_cast(addr) & 15)) { + // Same comment as before in the allocation system. + // We don't lock the listener array mutex because of an assumption + // where the listener array is rarely changing. + QT3DSU32 theCount = mListenerCount; + for (QT3DSU32 idx = 0; idx < theCount; ++idx) + mListeners[idx]->onAllocation(size, typeName, filename, line, addr); + return addr; + } + + qFatal("Allocations for qt3ds::foundation must be 16-byte aligned."); + return 0; + } + + void *Foundation::AlignCheckAllocator::allocate(size_t size, const char *typeName, + const char *filename, int line, + size_t /*alignment*/, + size_t /*alignmentOffset*/) + { + return allocate(size, typeName, filename, line, 0); + } + +} // namespace foundation +} // namespace qt3ds + +qt3ds::NVFoundation *NVCreateFoundation(qt3ds::QT3DSU32 version, qt3ds::NVAllocatorCallback &allocator) +{ + return qt3ds::foundation::Foundation::createInstance(version, allocator); +} diff --git a/src/Runtime/Source/foundation/Qt3DSFoundation.h b/src/Runtime/Source/foundation/Qt3DSFoundation.h new file mode 100644 index 00000000..19065d20 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSFoundation.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_FOUNDATION_H +#define QT3DS_FOUNDATION_QT3DS_FOUNDATION_H + +/** \addtogroup foundation + @{ +*/ + +#include +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSVersionNumber.h" +#include "foundation/Qt3DSLogging.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +class NVAllocatorCallback; +class NVProfilingZone; +class NVBroadcastingAllocator; + +class NVFoundationBase +{ +public: + /** + retrieves the current allocator. + */ + virtual NVBroadcastingAllocator &getAllocator() const = 0; +}; + +namespace foundation { +template +inline void NVDelete(NVFoundationBase &alloc, TObjType *item) +{ + NVDelete(alloc.getAllocator(), item); +} +} + +/** +\brief Foundation SDK singleton class. + +You need to have an instance of this class to instance the higher level SDKs. +*/ +class QT3DS_FOUNDATION_API NVFoundation : public NVFoundationBase +{ +public: + virtual void addRef() = 0; + /** + \brief Destroys the instance it is called on. + + The operation will fail, if there are still modules referencing the foundation object. Release + all dependent modules prior + to calling this method. + + @see NVCreateFoundation() + */ + virtual void release() = 0; + + /** + Retrieves the allocator this object was created with. + */ + virtual NVAllocatorCallback &getAllocatorCallback() const = 0; + +protected: + virtual ~NVFoundation() {} +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** +\brief Creates an instance of the foundation class + +\param version Version number we are expecting (should be QT3DS_FOUNDATION_VERSION) +\param allocator User supplied interface for allocating memory(see #NVAllocatorCallback) +\return Foundation instance on success, NULL if operation failed + +@see NVFoundation +*/ + +#ifdef QT3DS_FOUNDATION_NO_EXPORTS +QT3DS_AUTOTEST_EXPORT +#else +QT3DS_FOUNDATION_API +#endif +qt3ds::NVFoundation *QT3DS_CALL_CONV NVCreateFoundation( + qt3ds::QT3DSU32 version, qt3ds::NVAllocatorCallback &allocator); + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_FOUNDATION_H diff --git a/src/Runtime/Source/foundation/Qt3DSIPC.h b/src/Runtime/Source/foundation/Qt3DSIPC.h new file mode 100644 index 00000000..9bcea1af --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSIPC.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_IPC_H +#define QT3DS_IPC_H + +#include "foundation/Qt3DS.h" + +namespace qt3ds { +namespace foundation { + + class NVIPC + { + public: + enum ConnectionType { + CT_CLIENT, // start up as a client, will succeed even if the server has not yet been + // found. + CT_CLIENT_REQUIRE_SERVER, // start up as a client, but only if the server already + // exists. + CT_SERVER, // will start up as a server, will fail if an existing server is already + // open. + CT_CLIENT_OR_SERVER, // connect as either a client or server, don't care who is created + // first. + CT_LAST + }; + + enum ErrorCode { + EC_OK, // no error. + EC_FAIL, // generic failure. + EC_SERVER_ALREADY_EXISTS, // couldn't create a server, because the server already + // exists. + EC_CLIENT_ALREADY_EXISTS, // couldn't create a client, because an existing client is + // already registered. + EC_CLIENT_SERVER_ALREADY_EXISTS, // both the client and server channels are already used + EC_SERVER_NOT_FOUND, // client opened with a required server, which was not found. + EC_BUFFER_MISSMATCH, // the reserved buffers for client/server do not match up. + EC_MAPFILE_CREATE, // failed to create the shared memory map file. + EC_MAPFILE_VIEW, // failed to map the memory view of he + // communications errors. + EC_SEND_DATA_EXCEEDS_MAX_BUFFER, // trying to send more data than can even fit in the + // sednd buffe. + EC_SEND_DATA_TOO_LARGE, // the data we tried to send exceeds the available room int the + // output ring buffer. + EC_SEND_BUFFER_FULL, // the send buffer is completely full. + EC_SEND_FROM_WRONG_THREAD, // Tried to do a send from a different thread + EC_RECEIVE_FROM_WRONG_THREAD, // Tried to do a recieve from a different thread + EC_NO_RECEIVE_PENDING, // tried to acknowledge a receive but none was pending. + }; + + virtual bool pumpPendingSends(void) = 0; // give up a time slice to pending sends; returns + // true if there are still pends sending. + virtual ErrorCode sendData(const void *data, QT3DSU32 data_len, bool bufferIfFull) = 0; + virtual const void *receiveData(QT3DSU32 &data_len) = 0; + virtual ErrorCode receiveAcknowledge(void) = 0; // acknowledge that we have processed the + // incoming message and can advance the read + // buffer. + + virtual bool isServer(void) const = 0; // returns true if we are opened as a server. + + virtual bool haveConnection(void) const = 0; + + virtual bool canSend(QT3DSU32 len) = 0; // return true if we can send a message of this size. + + virtual void release(void) = 0; + + protected: + virtual ~NVIPC(void){} + }; +}; // end of namespace +}; // end of namespace + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h b/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h new file mode 100644 index 00000000..ff36b42a --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_INDEXABLE_LINKED_LIST_H +#define QT3DS_FOUNDATION_INDEXABLE_LINKED_LIST_H +#include "foundation/Qt3DSPool.h" + +namespace qt3ds { +namespace foundation { + // Set of helper functions for manipulation of lists that are + // somewhat indexable but also amenable to using a pool structure. + template + struct IndexableLinkedList + { + typedef TNodeType SNode; + + typedef Pool TPoolType; + + static TObjType &Create(SNode *&inInitialNode, QT3DSU32 &ioCurrentCount, TPoolType &ioPool) + { + QT3DSU32 idx = ioCurrentCount; + ++ioCurrentCount; + QT3DSU32 numGroups = (ioCurrentCount + TObjCount - 1) / TObjCount; + QT3DSU32 localIdx = idx % TObjCount; + + SNode *theCurrentNode = inInitialNode; + for (QT3DSU32 idx = 0, end = numGroups; idx < end; ++idx) { + if (idx == 0) { + if (theCurrentNode == NULL) + inInitialNode = ioPool.construct(__FILE__, __LINE__); + + theCurrentNode = inInitialNode; + } else { + if (theCurrentNode->m_NextNode == NULL) + theCurrentNode->m_NextNode = ioPool.construct(__FILE__, __LINE__); + theCurrentNode = theCurrentNode->m_NextNode; + } + } + return theCurrentNode->m_Data[localIdx]; + } + + static void CreateAll(SNode *&inInitialNode, QT3DSU32 inCount, TPoolType &ioPool) + { + QT3DSU32 numGroups = (inCount + TObjCount - 1) / TObjCount; + SNode *lastNode = NULL; + for (QT3DSU32 idx = 0, end = numGroups; idx < end; ++idx) { + SNode *nextNode = ioPool.construct(__FILE__, __LINE__); + if (idx == 0) + inInitialNode = nextNode; + else + lastNode->m_NextNode = nextNode; + lastNode = nextNode; + } + } + + static void DeleteList(SNode *&inInitialNode, TPoolType &ioPool) + { + SNode *theNode = inInitialNode; + inInitialNode = NULL; + while (theNode) { + SNode *theNext = theNode->m_NextNode; + theNode->m_NextNode = NULL; + ioPool.deallocate(theNode); + theNode = theNext; + } + } + + // Performs no checking, so you need to have already allocated what you need. + static const TObjType &GetObjAtIdx(const SNode *inInitialNode, QT3DSU32 inIdx) + { + QT3DSU32 groupIdx = inIdx / TObjCount; + QT3DSU32 localIdx = inIdx % TObjCount; + for (QT3DSU32 idx = 0; idx < groupIdx; ++idx) + inInitialNode = inInitialNode->m_NextNode; + return inInitialNode->m_Data[inIdx]; + } + + static TObjType &GetObjAtIdx(SNode *inInitialNode, QT3DSU32 inIdx) + { + QT3DSU32 groupIdx = inIdx / TObjCount; + QT3DSU32 localIdx = inIdx % TObjCount; + for (QT3DSU32 idx = 0; idx < groupIdx; ++idx) + inInitialNode = inInitialNode->m_NextNode; + return inInitialNode->m_Data[localIdx]; + } + + struct SIteratorType + { + QT3DSU32 m_Idx; + QT3DSU32 m_Count; + SNode *m_Node; + + SIteratorType() + : m_Idx(0) + , m_Count(0) + , m_Node(NULL) + { + } + SIteratorType(const SIteratorType &iter) + : m_Idx(iter.m_Idx) + , m_Count(iter.m_Count) + , m_Node(iter.m_Node) + { + } + SIteratorType(SNode *inNode, QT3DSU32 inCount, QT3DSU32 inIdx) + : m_Idx(inIdx) + , m_Count(inCount) + , m_Node(inNode) + { + } + + bool operator==(const SIteratorType &iter) const { return m_Idx == iter.m_Idx; } + + bool operator!=(const SIteratorType &iter) const { return m_Idx != iter.m_Idx; } + + TObjType &operator*() + { + QT3DSU32 localIdx = m_Idx % TObjCount; + return m_Node->m_Data[localIdx]; + } + + SIteratorType &operator++() + { + ++m_Idx; + if ((m_Idx % TObjCount) == 0) + m_Node = m_Node->m_NextNode; + + return *this; + } + }; + + struct SConstIteratorType + { + QT3DSU32 m_Idx; + QT3DSU32 m_Count; + const SNode *m_Node; + + SConstIteratorType() + : m_Idx(0) + , m_Count(0) + , m_Node(NULL) + { + } + SConstIteratorType(const SIteratorType &iter) + : m_Idx(iter.m_Idx) + , m_Count(iter.m_Count) + , m_Node(iter.m_Node) + { + } + SConstIteratorType(const SConstIteratorType &iter) + : m_Idx(iter.m_Idx) + , m_Count(iter.m_Count) + , m_Node(iter.m_Node) + { + } + SConstIteratorType(const SNode *inNode, QT3DSU32 inCount, QT3DSU32 inIdx) + : m_Idx(inIdx) + , m_Count(inCount) + , m_Node(inNode) + { + } + + bool operator==(const SConstIteratorType &iter) const { return m_Idx == iter.m_Idx; } + + bool operator!=(const SConstIteratorType &iter) const { return m_Idx != iter.m_Idx; } + + const TObjType &operator*() + { + QT3DSU32 localIdx = m_Idx % TObjCount; + return m_Node->m_Data[localIdx]; + } + + SConstIteratorType &operator++() + { + ++m_Idx; + if ((m_Idx % TObjCount) == 0) + m_Node = m_Node->m_NextNode; + + return *this; + } + }; + + typedef SIteratorType iterator; + typedef SConstIteratorType const_iterator; + + static iterator begin(SNode *inInitialNode, QT3DSU32 inItemCount) + { + return SIteratorType(inInitialNode, inItemCount, 0); + } + + static iterator end(SNode * /*inInitialNode*/, QT3DSU32 inItemCount) + { + return SIteratorType(NULL, inItemCount, inItemCount); + } + + static const_iterator begin(const SNode *inInitialNode, QT3DSU32 inItemCount) + { + return SConstIteratorType(inInitialNode, inItemCount, 0); + } + + static const_iterator end(const SNode * /*inInitialNode*/, QT3DSU32 inItemCount) + { + return SConstIteratorType(NULL, inItemCount, inItemCount); + } + + struct SNodeIteratorType + { + SNode *m_Node; + + SNodeIteratorType() + : m_Node(NULL) + { + } + SNodeIteratorType(const SNodeIteratorType &iter) + : m_Node(iter.m_Node) + { + } + SNodeIteratorType(SNode *inNode) + : m_Node(inNode) + { + } + + bool operator==(const SNodeIteratorType &iter) const { return m_Node == iter.m_Node; } + + bool operator!=(const SNodeIteratorType &iter) const { return m_Node != iter.m_Node; } + + TNodeType &operator*() { return *m_Node; } + + SNodeIteratorType &operator++() + { + if (m_Node) + m_Node = m_Node->m_NextNode; + + return *this; + } + }; + + typedef SNodeIteratorType node_iterator; + static node_iterator node_begin(SNode *inFirstNode) { return node_iterator(inFirstNode); } + static node_iterator node_end(SNode * /*inFirstNode*/) { return node_iterator(NULL); } + + // Iterates through the number of nodes required for a given count of objects + struct SCountIteratorType + { + QT3DSU32 m_Idx; + QT3DSU32 m_Count; + + SCountIteratorType() + : m_Idx(0) + , m_Count(0) + { + } + SCountIteratorType(const SCountIteratorType &iter) + : m_Idx(iter.m_Idx) + , m_Count(iter.m_Count) + { + } + SCountIteratorType(QT3DSU32 idx, QT3DSU32 count) + : m_Idx(idx) + , m_Count(count) + { + } + + bool operator==(const SCountIteratorType &iter) const { return m_Idx == iter.m_Idx; } + + bool operator!=(const SCountIteratorType &iter) const { return m_Idx != iter.m_Idx; } + + SCountIteratorType &operator++() + { + m_Idx = NVMin(m_Idx + TObjCount, m_Count); + return *this; + } + }; + + typedef SCountIteratorType count_iterator; + static count_iterator count_begin(QT3DSU32 count) { return SCountIteratorType(0, count); } + static count_iterator count_end(QT3DSU32 count) { return SCountIteratorType(count, count); } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSIntrinsics.h b/src/Runtime/Source/foundation/Qt3DSIntrinsics.h new file mode 100644 index 00000000..1d6ac7a5 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSIntrinsics.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_INTRINSICS_H +#define QT3DS_FOUNDATION_QT3DS_INTRINSICS_H + +#include "foundation/Qt3DSPreprocessor.h" + +#if defined QT3DS_WINDOWS || defined QT3DS_WIN8ARM +#include "windows/Qt3DSWindowsIntrinsics.h" +#elif defined QT3DS_X360 +#include "xbox360/NVXbox360Intrinsics.h" +#elif (defined QT3DS_LINUX || defined QT3DS_ANDROID || defined QT3DS_APPLE || defined QT3DS_QNX) +#include "linux/Qt3DSLinuxIntrinsics.h" +#elif defined QT3DS_PS3 +#include "ps3/NVPS3Intrinsics.h" +#elif defined QT3DS_PSP2 +#include "psp2/NVPSP2Intrinsics.h" +#else +#error "Platform not supported!" +#endif + +#endif // QT3DS_FOUNDATION_QT3DS_INTRINSICS_H diff --git a/src/Runtime/Source/foundation/Qt3DSInvasiveLinkedList.h b/src/Runtime/Source/foundation/Qt3DSInvasiveLinkedList.h new file mode 100644 index 00000000..da90e120 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSInvasiveLinkedList.h @@ -0,0 +1,361 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_INVASIVE_LINKED_LIST_H +#define QT3DS_FOUNDATION_INVASIVE_LINKED_LIST_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace foundation { + + // Base linked list without an included head or tail member. + template + struct SInvasiveLinkListBase + { + TObjType *tail(TObjType *inObj) + { + if (inObj) + return TObjTailOp().get(inObj); + return NULL; + } + + TObjType *head(TObjType *inObj) + { + if (inObj) + return TObjHeadOp().get(inObj); + return NULL; + } + + const TObjType *tail(const TObjType *inObj) + { + if (inObj) + return TObjTailOp().get(inObj); + return NULL; + } + + const TObjType *head(const TObjType *inObj) + { + if (inObj) + return TObjHeadOp().get(inObj); + return NULL; + } + + void remove(TObjType &inObj) + { + TObjHeadOp theHeadOp; + TObjTailOp theTailOp; + TObjType *theHead = theHeadOp.get(inObj); + TObjType *theTail = theTailOp.get(inObj); + if (theHead) + theTailOp.set(*theHead, theTail); + if (theTail) + theHeadOp.set(*theTail, theHead); + theHeadOp.set(inObj, NULL); + theTailOp.set(inObj, NULL); + } + + void insert_after(TObjType &inPosition, TObjType &inObj) + { + TObjTailOp theTailOp; + TObjType *theHead = &inPosition; + TObjType *theTail = theTailOp.get(inPosition); + insert(theHead, theTail, inObj); + } + + void insert_before(TObjType &inPosition, TObjType &inObj) + { + TObjHeadOp theHeadOp; + TObjType *theHead = theHeadOp.get(inPosition); + TObjType *theTail = &inPosition; + insert(theHead, theTail, inObj); + } + + void insert(TObjType *inHead, TObjType *inTail, TObjType &inObj) + { + TObjHeadOp theHeadOp; + TObjTailOp theTailOp; + if (inHead) + theTailOp.set(*inHead, &inObj); + if (inTail) + theHeadOp.set(*inTail, &inObj); + theHeadOp.set(inObj, inHead); + theTailOp.set(inObj, inTail); + } + }; + + template + struct SLinkedListIterator + { + typedef SLinkedListIterator TMyType; + TObjType *m_Obj; + SLinkedListIterator(TObjType *inObj = NULL) + : m_Obj(inObj) + { + } + + bool operator!=(const TMyType &inIter) const { return m_Obj != inIter.m_Obj; } + bool operator==(const TMyType &inIter) const { return m_Obj == inIter.m_Obj; } + + TMyType &operator++() + { + if (m_Obj) + m_Obj = TObjTailOp().get(*m_Obj); + return *this; + } + + TMyType &operator++(int) + { + TMyType retval(*this); + ++(*this); + return retval; + } + + TObjType &operator*() { return *m_Obj; } + TObjType *operator->() { return m_Obj; } + }; + + // Used for singly linked list where + // items have either no head or tail ptr. + template + struct SNullOp + { + void set(TObjType &, TObjType *) {} + TObjType *get(const TObjType &) { return NULL; } + }; + + template + struct InvasiveSingleLinkedList + : public SInvasiveLinkListBase, TObjTailOp> + { + typedef InvasiveSingleLinkedList TMyType; + typedef SInvasiveLinkListBase, TObjTailOp> TBaseType; + typedef SLinkedListIterator iterator; + typedef iterator const_iterator; + TObjType *m_Head; + InvasiveSingleLinkedList() + : m_Head(NULL) + { + } + InvasiveSingleLinkedList(const TMyType &inOther) + : m_Head(inOther.m_Head) + { + } + TMyType &operator=(const TMyType &inOther) + { + m_Head = inOther.m_Head; + return *this; + } + + TObjType &front() const { return *m_Head; } + + void push_front(TObjType &inObj) + { + if (m_Head != NULL) + TBaseType::insert_before(*m_Head, inObj); + m_Head = &inObj; + } + + void push_back(TObjType &inObj) + { + if (m_Head == NULL) + m_Head = &inObj; + else { + TObjType *lastObj = NULL; + for (iterator iter = begin(), endIter = end(); iter != endIter; ++iter) + lastObj = &(*iter); + + QT3DS_ASSERT(lastObj); + if (lastObj) + TObjTailOp().set(*lastObj, &inObj); + } + } + + void remove(TObjType &inObj) + { + if (m_Head == &inObj) + m_Head = TObjTailOp().get(inObj); + TBaseType::remove(inObj); + } + + bool empty() const { return m_Head == NULL; } + + iterator begin() { return iterator(m_Head); } + iterator end() { return iterator(NULL); } + + const_iterator begin() const { return iterator(m_Head); } + const_iterator end() const { return iterator(NULL); } + }; + + template + struct InvasiveLinkedList : public SInvasiveLinkListBase + { + typedef InvasiveLinkedList TMyType; + typedef SInvasiveLinkListBase TBaseType; + typedef SLinkedListIterator iterator; + typedef iterator const_iterator; + typedef SLinkedListIterator reverse_iterator; + typedef reverse_iterator const_reverse_iterator; + + TObjType *m_Head; + TObjType *m_Tail; + + InvasiveLinkedList() + : m_Head(NULL) + , m_Tail(NULL) + { + } + InvasiveLinkedList(const TMyType &inOther) + : m_Head(inOther.m_Head) + , m_Tail(inOther.m_Tail) + { + } + TMyType &operator=(const TMyType &inOther) + { + m_Head = inOther.m_Head; + m_Tail = inOther.m_Tail; + return *this; + } + + TObjType &front() const + { + QT3DS_ASSERT(m_Head); + return *m_Head; + } + TObjType &back() const + { + QT3DS_ASSERT(m_Tail); + return *m_Tail; + } + + TObjType *front_ptr() const { return m_Head; } + TObjType *back_ptr() const { return m_Tail; } + + void push_front(TObjType &inObj) + { + if (m_Head != NULL) + TBaseType::insert_before(*m_Head, inObj); + m_Head = &inObj; + + if (m_Tail == NULL) + m_Tail = &inObj; + } + + void push_back(TObjType &inObj) + { + if (m_Tail != NULL) + TBaseType::insert_after(*m_Tail, inObj); + m_Tail = &inObj; + + if (m_Head == NULL) + m_Head = &inObj; + } + + void remove(TObjType &inObj) + { + if (m_Head == &inObj) + m_Head = TObjTailOp().get(inObj); + if (m_Tail == &inObj) + m_Tail = TObjHeadOp().get(inObj); + + TBaseType::remove(inObj); + } + + bool empty() const { return m_Head == NULL; } + + iterator begin() { return iterator(m_Head); } + iterator end() { return iterator(NULL); } + + const_iterator begin() const { return iterator(m_Head); } + const_iterator end() const { return iterator(NULL); } + + reverse_iterator rbegin() { return reverse_iterator(m_Tail); } + reverse_iterator rend() { return reverse_iterator(NULL); } + + const_reverse_iterator rbegin() const { return reverse_iterator(m_Tail); } + const_reverse_iterator rend() const { return reverse_iterator(NULL); } + }; + +// Macros to speed up the definitely of invasive linked lists. +#define DEFINE_INVASIVE_SINGLE_LIST(type) \ + struct S##type; \ + struct S##type##NextOp \ + { \ + S##type *get(S##type &s); \ + const S##type *get(const S##type &s) const; \ + void set(S##type &inItem, S##type *inNext); \ + }; \ + typedef InvasiveSingleLinkedList T##type##List; + +#define DEFINE_INVASIVE_LIST(type) \ + struct S##type; \ + struct S##type##NextOp \ + { \ + S##type *get(S##type &s); \ + const S##type *get(const S##type &s) const; \ + void set(S##type &inItem, S##type *inNext); \ + }; \ + struct S##type##PreviousOp \ + { \ + S##type *get(S##type &s); \ + const S##type *get(const S##type &s) const; \ + void set(S##type &inItem, S##type *inNext); \ + }; \ + typedef InvasiveLinkedList T##type##List; + +#define IMPLEMENT_INVASIVE_LIST(type, prevMember, nextMember) \ + inline S##type *S##type##NextOp::get(S##type &s) { return s.nextMember; } \ + inline const S##type *S##type##NextOp::get(const S##type &s) const { return s.nextMember; } \ + inline void S##type##NextOp::set(S##type &inItem, S##type *inNext) \ + { \ + inItem.nextMember = inNext; \ + } \ + inline S##type *S##type##PreviousOp::get(S##type &s) { return s.prevMember; } \ + inline const S##type *S##type##PreviousOp::get(const S##type &s) const \ + { \ + return s.prevMember; \ + } \ + inline void S##type##PreviousOp::set(S##type &inItem, S##type *inNext) \ + { \ + inItem.prevMember = inNext; \ + } + +#define IMPLEMENT_INVASIVE_SINGLE_LIST(type, nextMember) \ + inline S##type *S##type##NextOp::get(S##type &s) { return s.nextMember; } \ + inline const S##type *S##type##NextOp::get(const S##type &s) const { return s.nextMember; } \ + inline void S##type##NextOp::set(S##type &inItem, S##type *inNext) \ + { \ + inItem.nextMember = inNext; \ + } +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSInvasiveSet.h b/src/Runtime/Source/foundation/Qt3DSInvasiveSet.h new file mode 100644 index 00000000..772a2308 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSInvasiveSet.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_INVASIVE_SET_H +#define QT3DS_FOUNDATION_INVASIVE_SET_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace foundation { + + template + class InvasiveSet + { + nvvector mSet; + + InvasiveSet(const InvasiveSet &other); + InvasiveSet &operator=(const InvasiveSet &other); + + public: + InvasiveSet(NVAllocatorCallback &callback, const char *allocName) + : mSet(callback, allocName) + { + } + + bool insert(TObjectType &inObject) + { + QT3DSU32 currentIdx = TGetSetIndexOp()(inObject); + if (currentIdx == QT3DS_MAX_U32) { + TSetSetIndexOp()(inObject, mSet.size()); + mSet.push_back(&inObject); + return true; + } + return false; + } + + bool remove(TObjectType &inObject) + { + QT3DSU32 currentIdx = TGetSetIndexOp()(inObject); + if (currentIdx != QT3DS_MAX_U32) { + TObjectType *theEnd = mSet.back(); + TObjectType *theObj = &inObject; + if (theEnd != theObj) { + TSetSetIndexOp()(*theEnd, currentIdx); + mSet[currentIdx] = theEnd; + } + mSet.pop_back(); + TSetSetIndexOp()(inObject, QT3DS_MAX_U32); + return true; + } + return false; + } + + bool contains(TObjectType &inObject) { return TGetSetIndexOp()(inObject) != QT3DS_MAX_U32; } + + void clear() + { + for (QT3DSU32 idx = 0; idx < mSet.size(); ++idx) + TSetSetIndexOp()(*(mSet[idx]), QT3DS_MAX_U32); + mSet.clear(); + } + + TObjectType *operator[](QT3DSU32 idx) { return mSet[idx]; } + const TObjectType *operator[](QT3DSU32 idx) const { return mSet[idx]; } + QT3DSU32 size() const { return mSet.size(); } + TObjectType **begin() { return mSet.begin(); } + TObjectType **end() { return mSet.end(); } + const TObjectType **begin() const { return mSet.begin(); } + const TObjectType **end() const { return mSet.end(); } + const TObjectType *back() const { return mSet.back(); } + TObjectType *back() { return mSet.back(); } + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSLogging.cpp b/src/Runtime/Source/foundation/Qt3DSLogging.cpp new file mode 100644 index 00000000..257b39b2 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSLogging.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSLogging.h" + +namespace qt3ds { + +Q_LOGGING_CATEGORY(GL_ERROR, "qt3ds.gl_error") +Q_LOGGING_CATEGORY(INVALID_PARAMETER, "qt3ds.invalid_parameter") +Q_LOGGING_CATEGORY(INVALID_OPERATION, "qt3ds.invalid_operation") +Q_LOGGING_CATEGORY(OUT_OF_MEMORY, "qt3ds.out_of_memory") +Q_LOGGING_CATEGORY(INTERNAL_ERROR, "qt3ds.internal_error") +Q_LOGGING_CATEGORY(PERF_WARNING, "qt3ds.perf_warning") +Q_LOGGING_CATEGORY(PERF_INFO, "qt3ds.perf_info") +Q_LOGGING_CATEGORY(TRACE_INFO, "qt3ds.trace_info") +Q_LOGGING_CATEGORY(WARNING, "qt3ds.warning") + +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/Qt3DSLogging.h b/src/Runtime/Source/foundation/Qt3DSLogging.h new file mode 100644 index 00000000..4fcb77b5 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSLogging.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_ERRORS_H +#define QT3DS_FOUNDATION_QT3DS_ERRORS_H + +#include +#include + +namespace qt3ds { + +Q_DECLARE_LOGGING_CATEGORY(GL_ERROR) +Q_DECLARE_LOGGING_CATEGORY(INVALID_PARAMETER) +Q_DECLARE_LOGGING_CATEGORY(INVALID_OPERATION) +Q_DECLARE_LOGGING_CATEGORY(OUT_OF_MEMORY) +Q_DECLARE_LOGGING_CATEGORY(INTERNAL_ERROR) +Q_DECLARE_LOGGING_CATEGORY(PERF_WARNING) +Q_DECLARE_LOGGING_CATEGORY(PERF_INFO) +Q_DECLARE_LOGGING_CATEGORY(TRACE_INFO) +Q_DECLARE_LOGGING_CATEGORY(WARNING) + +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSMat33.h b/src/Runtime/Source/foundation/Qt3DSMat33.h new file mode 100644 index 00000000..6fa69eb5 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMat33.h @@ -0,0 +1,385 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_MAT33_H +#define QT3DS_FOUNDATION_QT3DS_MAT33_H +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSQuat.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif +/*! +\brief 3x3 matrix class + +Some clarifications, as there have been much confusion about matrix formats etc in the past. + +Short: +- Matrix have base vectors in columns (vectors are column matrices, 3x1 matrices). +- Matrix is physically stored in column major format +- Matrices are concaternated from left + +Long: +Given three base vectors a, b and c the matrix is stored as + +|a.x b.x c.x| +|a.y b.y c.y| +|a.z b.z c.z| + +Vectors are treated as columns, so the vector v is + +|x| +|y| +|z| + +And matrices are applied _before_ the vector (pre-multiplication) +v' = M*v + +|x'| |a.x b.x c.x| |x| |a.x*x + b.x*y + c.x*z| +|y'| = |a.y b.y c.y| * |y| = |a.y*x + b.y*y + c.y*z| +|z'| |a.z b.z c.z| |z| |a.z*x + b.z*y + c.z*z| + + +Physical storage and indexing: +To be compatible with popular 3d rendering APIs (read D3d and OpenGL) +the physical indexing is + +|0 3 6| +|1 4 7| +|2 5 8| + +index = column*3 + row + +which in C++ translates to M[column][row] + +The mathematical indexing is M_row,column and this is what is used for _-notation +so _12 is 1st row, second column and operator(row, column)! + +@see QT3DSMat44 + +*/ +class QT3DSMat33 +{ +public: + //! Default constructor + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33() {} + + //! Construct from three base vectors + QT3DS_CUDA_CALLABLE QT3DSMat33(const QT3DSVec3 &col0, const QT3DSVec3 &col1, const QT3DSVec3 &col2) + : column0(col0) + , column1(col1) + , column2(col2) + { + } + + //! Construct from float[9] + QT3DS_CUDA_CALLABLE explicit QT3DS_INLINE QT3DSMat33(NVReal values[]) + : column0(values[0], values[1], values[2]) + , column1(values[3], values[4], values[5]) + , column2(values[6], values[7], values[8]) + { + } + + //! Construct from a quaternion + QT3DS_CUDA_CALLABLE explicit QT3DS_FORCE_INLINE QT3DSMat33(const QT3DSQuat &q) + { + const NVReal x = q.x; + const NVReal y = q.y; + const NVReal z = q.z; + const NVReal w = q.w; + + const NVReal x2 = x + x; + const NVReal y2 = y + y; + const NVReal z2 = z + z; + + const NVReal xx = x2 * x; + const NVReal yy = y2 * y; + const NVReal zz = z2 * z; + + const NVReal xy = x2 * y; + const NVReal xz = x2 * z; + const NVReal xw = x2 * w; + + const NVReal yz = y2 * z; + const NVReal yw = y2 * w; + const NVReal zw = z2 * w; + + column0 = QT3DSVec3(1.0f - yy - zz, xy + zw, xz - yw); + column1 = QT3DSVec3(xy - zw, 1.0f - xx - zz, yz + xw); + column2 = QT3DSVec3(xz + yw, yz - xw, 1.0f - xx - yy); + } + + //! Copy constructor + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33(const QT3DSMat33 &other) + : column0(other.column0) + , column1(other.column1) + , column2(other.column2) + { + } + + //! Assignment operator + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 &operator=(const QT3DSMat33 &other) + { + column0 = other.column0; + column1 = other.column1; + column2 = other.column2; + return *this; + } + + //! Set to identity matrix + QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat33 createIdentity() + { + return QT3DSMat33(QT3DSVec3(1, 0, 0), QT3DSVec3(0, 1, 0), QT3DSVec3(0, 0, 1)); + } + + //! Set to zero matrix + QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat33 createZero() + { + return QT3DSMat33(QT3DSVec3(0.0f), QT3DSVec3(0.0f), QT3DSVec3(0.0f)); + } + + //! Construct from diagonal, off-diagonals are zero. + QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat33 createDiagonal(const QT3DSVec3 &d) + { + return QT3DSMat33(QT3DSVec3(d.x, 0.0f, 0.0f), QT3DSVec3(0.0f, d.y, 0.0f), QT3DSVec3(0.0f, 0.0f, d.z)); + } + + //! Get transposed matrix + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 getTranspose() const + { + const QT3DSVec3 v0(column0.x, column1.x, column2.x); + const QT3DSVec3 v1(column0.y, column1.y, column2.y); + const QT3DSVec3 v2(column0.z, column1.z, column2.z); + + return QT3DSMat33(v0, v1, v2); + } + + //! Get the real inverse + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 getInverse() const + { + const NVReal det = getDeterminant(); + QT3DSMat33 inverse; + + if (det != 0) { + const NVReal invDet = 1.0f / det; + + inverse.column0[0] = invDet * (column1[1] * column2[2] - column2[1] * column1[2]); + inverse.column0[1] = invDet * -(column0[1] * column2[2] - column2[1] * column0[2]); + inverse.column0[2] = invDet * (column0[1] * column1[2] - column0[2] * column1[1]); + + inverse.column1[0] = invDet * -(column1[0] * column2[2] - column1[2] * column2[0]); + inverse.column1[1] = invDet * (column0[0] * column2[2] - column0[2] * column2[0]); + inverse.column1[2] = invDet * -(column0[0] * column1[2] - column0[2] * column1[0]); + + inverse.column2[0] = invDet * (column1[0] * column2[1] - column1[1] * column2[0]); + inverse.column2[1] = invDet * -(column0[0] * column2[1] - column0[1] * column2[0]); + inverse.column2[2] = invDet * (column0[0] * column1[1] - column1[0] * column0[1]); + + return inverse; + } else { + return createIdentity(); + } + } + + //! Get determinant + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal getDeterminant() const + { + return column0.dot(column1.cross(column2)); + } + + //! Unary minus + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator-() const + { + return QT3DSMat33(-column0, -column1, -column2); + } + + //! Add + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator+(const QT3DSMat33 &other) const + { + return QT3DSMat33(column0 + other.column0, column1 + other.column1, column2 + other.column2); + } + + //! Subtract + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator-(const QT3DSMat33 &other) const + { + return QT3DSMat33(column0 - other.column0, column1 - other.column1, column2 - other.column2); + } + + //! Scalar multiplication + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 operator*(NVReal scalar) const + { + return QT3DSMat33(column0 * scalar, column1 * scalar, column2 * scalar); + } + + friend QT3DSMat33 operator*(NVReal, const QT3DSMat33 &); + + //! Matrix vector multiplication (returns 'this->transform(vec)') + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 operator*(const QT3DSVec3 &vec) const { return transform(vec); } + + //! Matrix multiplication + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 operator*(const QT3DSMat33 &other) const + { + // Rows from this columns from other + // column0 = transform(other.column0) etc + return QT3DSMat33(transform(other.column0), transform(other.column1), + transform(other.column2)); + } + + // a = b operators + + //! Equals-add + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 &operator+=(const QT3DSMat33 &other) + { + column0 += other.column0; + column1 += other.column1; + column2 += other.column2; + return *this; + } + + //! Equals-sub + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 &operator-=(const QT3DSMat33 &other) + { + column0 -= other.column0; + column1 -= other.column1; + column2 -= other.column2; + return *this; + } + + //! Equals scalar multiplication + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 &operator*=(NVReal scalar) + { + column0 *= scalar; + column1 *= scalar; + column2 *= scalar; + return *this; + } + + //! Element access, mathematical way! + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal operator()(unsigned int row, unsigned int col) const + { + return (*this)[col][row]; + } + + //! Element access, mathematical way! + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator()(unsigned int row, unsigned int col) + { + return (*this)[col][row]; + } + + // Transform etc + + //! Transform vector by matrix, equal to v' = M*v + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 transform(const QT3DSVec3 &other) const + { + return column0 * other.x + column1 * other.y + column2 * other.z; + } + + //! Transform vector by matrix transpose, v' = M^t*v + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 transformTranspose(const QT3DSVec3 &other) const + { + return QT3DSVec3(column0.dot(other), column1.dot(other), column2.dot(other)); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal *front() const { return &column0.x; } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator[](int num) { return (&column0)[num]; } + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec3 &operator[](int num) const + { + return (&column0)[num]; + } + + // Data, see above for format! + + QT3DSVec3 column0, column1, column2; // the three base vectors +}; + +// implementation from Qt3DSQuat.h +QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat::QT3DSQuat(const QT3DSMat33 &m) +{ + NVReal tr = m(0, 0) + m(1, 1) + m(2, 2), h; + if (tr >= 0) { + h = NVSqrt(tr + 1); + w = NVReal(0.5) * h; + h = NVReal(0.5) / h; + + x = (m(2, 1) - m(1, 2)) * h; + y = (m(0, 2) - m(2, 0)) * h; + z = (m(1, 0) - m(0, 1)) * h; + } else { + int i = 0; + if (m(1, 1) > m(0, 0)) + i = 1; + if (m(2, 2) > m(i, i)) + i = 2; + switch (i) { + case 0: + h = NVSqrt((m(0, 0) - (m(1, 1) + m(2, 2))) + 1); + x = NVReal(0.5) * h; + h = NVReal(0.5) / h; + + y = (m(0, 1) + m(1, 0)) * h; + z = (m(2, 0) + m(0, 2)) * h; + w = (m(2, 1) - m(1, 2)) * h; + break; + case 1: + h = NVSqrt((m(1, 1) - (m(2, 2) + m(0, 0))) + 1); + y = NVReal(0.5) * h; + h = NVReal(0.5) / h; + + z = (m(1, 2) + m(2, 1)) * h; + x = (m(0, 1) + m(1, 0)) * h; + w = (m(0, 2) - m(2, 0)) * h; + break; + case 2: + h = NVSqrt((m(2, 2) - (m(0, 0) + m(1, 1))) + 1); + z = NVReal(0.5) * h; + h = NVReal(0.5) / h; + + x = (m(2, 0) + m(0, 2)) * h; + y = (m(1, 2) + m(2, 1)) * h; + w = (m(1, 0) - m(0, 1)) * h; + break; + default: // Make compiler happy + x = y = z = w = 0; + break; + } + } +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_MAT33_H diff --git a/src/Runtime/Source/foundation/Qt3DSMat44.h b/src/Runtime/Source/foundation/Qt3DSMat44.h new file mode 100644 index 00000000..53a66e2b --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMat44.h @@ -0,0 +1,497 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_MAT44_H +#define QT3DS_FOUNDATION_QT3DS_MAT44_H +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSQuat.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DSTransform.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/*! +\brief 4x4 matrix class + +This class is layout-compatible with D3D and OpenGL matrices. More notes on layout are given in the QT3DSMat33 +Graphics matrices always (by which I mean DX and OpenGL) have the rotation basis vectors stored contiguously +in 0-2, 3-5, 6-8 and the the translation stored contiguously in 12-14. However, DX calls this row major and GL calls it column-major. +http://www.mindcontrol.org/~hplus/graphics/matrix-layout.html + +you can blat these directly into GL (or DX) + +--Dilip Sequeira + +@see QT3DSMat33 NVTransform +*/ + +class QT3DSMat44 +{ +public: + //! Default constructor + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44() {} + + //! Construct from four 4-vectors + QT3DS_CUDA_CALLABLE QT3DSMat44(const QT3DSVec4 &col0, const QT3DSVec4 &col1, const QT3DSVec4 &col2, + const QT3DSVec4 &col3) + : column0(col0) + , column1(col1) + , column2(col2) + , column3(col3) + { + } + + //! Construct from three base vectors and a translation + QT3DS_CUDA_CALLABLE QT3DSMat44(const QT3DSVec3 &column0, const QT3DSVec3 &column1, const QT3DSVec3 &column2, + const QT3DSVec3 &column3) + : column0(column0, 0) + , column1(column1, 0) + , column2(column2, 0) + , column3(column3, 1) + { + } + + //! Construct from float[16] + explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(NVReal values[]) + : column0(values[0], values[1], values[2], values[3]) + , column1(values[4], values[5], values[6], values[7]) + , column2(values[8], values[9], values[10], values[11]) + , column3(values[12], values[13], values[14], values[15]) + { + } + + //! Construct from a quaternion + explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(const QT3DSQuat &q) + { + const NVReal x = q.x; + const NVReal y = q.y; + const NVReal z = q.z; + const NVReal w = q.w; + + const NVReal x2 = x + x; + const NVReal y2 = y + y; + const NVReal z2 = z + z; + + const NVReal xx = x2 * x; + const NVReal yy = y2 * y; + const NVReal zz = z2 * z; + + const NVReal xy = x2 * y; + const NVReal xz = x2 * z; + const NVReal xw = x2 * w; + + const NVReal yz = y2 * z; + const NVReal yw = y2 * w; + const NVReal zw = z2 * w; + + column0 = QT3DSVec4(1.0f - yy - zz, xy + zw, xz - yw, 0.0f); + column1 = QT3DSVec4(xy - zw, 1.0f - xx - zz, yz + xw, 0.0f); + column2 = QT3DSVec4(xz + yw, yz - xw, 1.0f - xx - yy, 0.0f); + column3 = QT3DSVec4(0.0f, 0.0f, 0.0f, 1.0f); + } + + //! Construct from a diagonal vector + explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(const QT3DSVec4 &diagonal) + : column0(diagonal.x, 0.0f, 0.0f, 0.0f) + , column1(0.0f, diagonal.y, 0.0f, 0.0f) + , column2(0.0f, 0.0f, diagonal.z, 0.0f) + , column3(0.0f, 0.0f, 0.0f, diagonal.w) + { + } + + QT3DS_CUDA_CALLABLE QT3DSMat44(const QT3DSMat33 &orientation, const QT3DSVec3 &position) + : column0(orientation.column0, 0.0f) + , column1(orientation.column1, 0.0f) + , column2(orientation.column2, 0.0f) + , column3(position, 1) + { + } + + QT3DS_CUDA_CALLABLE QT3DSMat44(const NVTransform &t) { *this = QT3DSMat44(QT3DSMat33(t.q), t.p); } + + //! Copy constructor + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44(const QT3DSMat44 &other) + : column0(other.column0) + , column1(other.column1) + , column2(other.column2) + , column3(other.column3) + { + } + + //! Assignment operator + QT3DS_CUDA_CALLABLE QT3DS_INLINE const QT3DSMat44 &operator=(const QT3DSMat44 &other) + { + column0 = other.column0; + column1 = other.column1; + column2 = other.column2; + column3 = other.column3; + return *this; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat44 createIdentity() + { + return QT3DSMat44(QT3DSVec4(1.0f, 0.0f, 0.0f, 0.0f), QT3DSVec4(0.0f, 1.0f, 0.0f, 0.0f), + QT3DSVec4(0.0f, 0.0f, 1.0f, 0.0f), QT3DSVec4(0.0f, 0.0f, 0.0f, 1.0f)); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE static QT3DSMat44 createZero() + { + return QT3DSMat44(QT3DSVec4(0.0f), QT3DSVec4(0.0f), QT3DSVec4(0.0f), QT3DSVec4(0.0f)); + } + + //! Get transposed matrix + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 getTranspose() const + { + return QT3DSMat44(QT3DSVec4(column0.x, column1.x, column2.x, column3.x), + QT3DSVec4(column0.y, column1.y, column2.y, column3.y), + QT3DSVec4(column0.z, column1.z, column2.z, column3.z), + QT3DSVec4(column0.w, column1.w, column2.w, column3.w)); + } + + //! Unary minus + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator-() const + { + return QT3DSMat44(-column0, -column1, -column2, -column3); + } + + //! Add + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator+(const QT3DSMat44 &other) const + { + return QT3DSMat44(column0 + other.column0, column1 + other.column1, column2 + other.column2, + column3 + other.column3); + } + + //! Subtract + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator-(const QT3DSMat44 &other) const + { + return QT3DSMat44(column0 - other.column0, column1 - other.column1, column2 - other.column2, + column3 - other.column3); + } + + //! Scalar multiplication + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator*(NVReal scalar) const + { + return QT3DSMat44(column0 * scalar, column1 * scalar, column2 * scalar, column3 * scalar); + } + + friend QT3DSMat44 operator*(NVReal, const QT3DSMat44 &); + + //! Matrix multiplication + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 operator*(const QT3DSMat44 &other) const + { + // Rows from this columns from other + // column0 = transform(other.column0) etc + return QT3DSMat44(transform(other.column0), transform(other.column1), transform(other.column2), + transform(other.column3)); + } + + // a = b operators + + //! Equals-add + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 &operator+=(const QT3DSMat44 &other) + { + column0 += other.column0; + column1 += other.column1; + column2 += other.column2; + column3 += other.column3; + return *this; + } + + //! Equals-sub + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 &operator-=(const QT3DSMat44 &other) + { + column0 -= other.column0; + column1 -= other.column1; + column2 -= other.column2; + column3 -= other.column3; + return *this; + } + + //! Equals scalar multiplication + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 &operator*=(NVReal scalar) + { + column0 *= scalar; + column1 *= scalar; + column2 *= scalar; + column3 *= scalar; + return *this; + } + + //! Element access, mathematical way! + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal operator()(unsigned int row, unsigned int col) const + { + return (*this)[col][row]; + } + + //! Element access, mathematical way! + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator()(unsigned int row, unsigned int col) + { + return (*this)[col][row]; + } + + //! Transform vector by matrix, equal to v' = M*v + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 transform(const QT3DSVec4 &other) const + { + return column0 * other.x + column1 * other.y + column2 * other.z + column3 * other.w; + } + + //! Transform vector by matrix, equal to v' = M*v + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 transform(const QT3DSVec3 &other) const + { + return transform(QT3DSVec4(other, 1)).getXYZ(); + } + + //! Rotate vector by matrix, equal to v' = M*v + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 rotate(const QT3DSVec4 &other) const + { + return column0 * other.x + column1 * other.y + column2 * other.z; // + column3*0; + } + + //! Rotate vector by matrix, equal to v' = M*v + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 rotate(const QT3DSVec3 &other) const + { + return rotate(QT3DSVec4(other, 1)).getXYZ(); + } + + /** +* Shamelessly pulled from gl-matrix.js + * Rotates a matrix by the given angle around the specified axis +* +* @param angle Angle (in radians) to rotate +* @param axis vec3 representing the axis to rotate around +*/ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool rotate(QT3DSF32 angleRadians, QT3DSVec3 axis) + { + QT3DSF32 x = axis[0], y = axis[1], z = axis[2], len = x * x + y * y + z * z, s, c, t, a00, a01, + a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, + b21, b22; + + if (!len) { + return false; + } + if (len != 1.0f) { + len = 1 / (NVSqrt(len)); + x *= len; + y *= len; + z *= len; + } + + s = NVSin(angleRadians); + c = NVCos(angleRadians); + t = 1 - c; + + QT3DSF32 *dataPtr(front()); + +// inverse algorithm was written for row-major matrixes. +#define mat(idx) dataPtr[idx] + + a00 = mat(0); + a01 = mat(1); + a02 = mat(2); + a03 = mat(3); + a10 = mat(4); + a11 = mat(5); + a12 = mat(6); + a13 = mat(7); + a20 = mat(8); + a21 = mat(9); + a22 = mat(10); + a23 = mat(11); +#undef mat + + // Construct the elements of the rotation matrix + b00 = x * x * t + c; + b01 = y * x * t + z * s; + b02 = z * x * t - y * s; + b10 = x * y * t - z * s; + b11 = y * y * t + c; + b12 = z * y * t + x * s; + b20 = x * z * t + y * s; + b21 = y * z * t - x * s; + b22 = z * z * t + c; + +// Perform rotation-specific matrix multiplication + +#define dest(idx) dataPtr[idx] + + dest(0) = a00 * b00 + a10 * b01 + a20 * b02; + dest(1) = a01 * b00 + a11 * b01 + a21 * b02; + dest(2) = a02 * b00 + a12 * b01 + a22 * b02; + dest(3) = a03 * b00 + a13 * b01 + a23 * b02; + + dest(4) = a00 * b10 + a10 * b11 + a20 * b12; + dest(5) = a01 * b10 + a11 * b11 + a21 * b12; + dest(6) = a02 * b10 + a12 * b11 + a22 * b12; + dest(7) = a03 * b10 + a13 * b11 + a23 * b12; + + dest(8) = a00 * b20 + a10 * b21 + a20 * b22; + dest(9) = a01 * b20 + a11 * b21 + a21 * b22; + dest(10) = a02 * b20 + a12 * b21 + a22 * b22; + dest(11) = a03 * b20 + a13 * b21 + a23 * b22; + +#undef dest + + return true; + }; + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getBasis(int num) const + { + QT3DS_ASSERT(num >= 0 && num < 3); + return (&column0)[num].getXYZ(); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getPosition() const { return column3.getXYZ(); } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE void setPosition(const QT3DSVec3 &position) + { + column3.x = position.x; + column3.y = position.y; + column3.z = position.z; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal *front() { return &column0.x; } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal *front() const { return &column0.x; } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec4 &operator[](int num) { return (&column0)[num]; } + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec4 &operator[](int num) const + { + return (&column0)[num]; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE void scale(const QT3DSVec4 &p) + { + column0 *= p.x; + column1 *= p.y; + column2 *= p.z; + column3 *= p.w; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 inverseRT(void) const + { + QT3DSVec3 r0(column0.x, column1.x, column2.x), r1(column0.y, column1.y, column2.y), + r2(column0.z, column1.z, column2.z); + + return QT3DSMat44(r0, r1, r2, -(r0 * column3.x + r1 * column3.y + r2 * column3.z)); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat44 getInverse(void) const + { + // inverse algorithm was written for row-major matrixes. + const QT3DSF32 *myPtr(front()); +#define mat(idx) myPtr[idx] + + QT3DSF32 a00 = mat(0), a01 = mat(1), a02 = mat(2), a03 = mat(3), a10 = mat(4), a11 = mat(5), + a12 = mat(6), a13 = mat(7), a20 = mat(8), a21 = mat(9), a22 = mat(10), a23 = mat(11), + a30 = mat(12), a31 = mat(13), a32 = mat(14), a33 = mat(15), +#undef mat + + b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, + b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, + b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, + b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, + + d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06), invDet; + + // Calculate the determinant + if (!d) { + QT3DS_ASSERT(false); + return QT3DSMat44::createIdentity(); + } + invDet = 1 / d; + + QT3DSMat44 retval; + QT3DSF32 *destPtr = retval.front(); + +#define dest(idx) destPtr[idx] + dest(0) = (a11 * b11 - a12 * b10 + a13 * b09) * invDet; + dest(1) = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet; + dest(2) = (a31 * b05 - a32 * b04 + a33 * b03) * invDet; + dest(3) = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet; + dest(4) = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet; + dest(5) = (a00 * b11 - a02 * b08 + a03 * b07) * invDet; + dest(6) = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet; + dest(7) = (a20 * b05 - a22 * b02 + a23 * b01) * invDet; + dest(8) = (a10 * b10 - a11 * b08 + a13 * b06) * invDet; + dest(9) = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet; + dest(10) = (a30 * b04 - a31 * b02 + a33 * b00) * invDet; + dest(11) = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet; + dest(12) = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet; + dest(13) = (a00 * b09 - a01 * b07 + a02 * b06) * invDet; + dest(14) = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet; + dest(15) = (a20 * b03 - a21 * b01 + a22 * b00) * invDet; +#undef dest + + return retval; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const + { + return column0.isFinite() && column1.isFinite() && column2.isFinite() && column3.isFinite(); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 getUpper3x3() const + { + return QT3DSMat33(column0.getXYZ(), column1.getXYZ(), column2.getXYZ()); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSMat33 getUpper3x3InverseTranspose() const + { + return getUpper3x3().getInverse().getTranspose(); + } + + // Data, see above for format! + + QT3DSVec4 column0, column1, column2, column3; // the four base vectors +}; + +// implementation from Qt3DSTransform.h +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform::NVTransform(const QT3DSMat44 &m) +{ + QT3DSVec3 column0 = QT3DSVec3(m.column0.x, m.column0.y, m.column0.z); + QT3DSVec3 column1 = QT3DSVec3(m.column1.x, m.column1.y, m.column1.z); + QT3DSVec3 column2 = QT3DSVec3(m.column2.x, m.column2.y, m.column2.z); + + q = QT3DSQuat(QT3DSMat33(column0, column1, column2)); + p = QT3DSVec3(m.column3.x, m.column3.y, m.column3.z); +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_MAT44_H diff --git a/src/Runtime/Source/foundation/Qt3DSMath.h b/src/Runtime/Source/foundation/Qt3DSMath.h new file mode 100644 index 00000000..931852e7 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMath.h @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_MATH_H +#define QT3DS_FOUNDATION_QT3DS_MATH_H + +/** \addtogroup foundation +@{ +*/ + +#include +#include +#include + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSAssert.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +// constants +static const NVReal NVPi = NVReal(3.141592653589793); +static const NVReal NVHalfPi = NVReal(1.57079632679489661923); +static const NVReal NVTwoPi = NVReal(6.28318530717958647692); +static const NVReal NVInvPi = NVReal(0.31830988618379067154); + +/** +\brief The return value is the greater of the two specified values. +*/ +template +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE T NVMax(T a, T b) +{ + return a < b ? b : a; +} + +//! overload for float to use fsel on xbox +template <> +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVMax(float a, float b) +{ + return intrinsics::selectMax(a, b); +} + +/** +\brief The return value is the lesser of the two specified values. +*/ +template +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE T NVMin(T a, T b) +{ + return a < b ? a : b; +} + +template <> +//! overload for float to use fsel on xbox +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float NVMin(float a, float b) +{ + return intrinsics::selectMin(a, b); +} + +/* +Many of these are just implemented as QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE calls to the C lib right now, +but later we could replace some of them with some approximations or more +clever stuff. +*/ + +/** +\brief abs returns the absolute value of its argument. +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAbs(QT3DSF32 a) +{ + return intrinsics::abs(a); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVEquals(QT3DSF32 a, QT3DSF32 b, QT3DSF32 epsilon) +{ + return (NVAbs(a - b) < epsilon); +} + +/** +\brief abs returns the absolute value of its argument. +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAbs(QT3DSF64 a) +{ + return ::fabs(a); +} + +/** +\brief abs returns the absolute value of its argument. +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSI32 NVAbs(QT3DSI32 a) +{ + return ::abs(a); +} + +/** +\brief Clamps v to the range [hi,lo] +*/ +template +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE T NVClamp(T v, T lo, T hi) +{ + QT3DS_ASSERT(lo <= hi); + return NVMin(hi, NVMax(lo, v)); +} + +//! \brief Square root. +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVSqrt(QT3DSF32 a) +{ + return intrinsics::sqrt(a); +} + +//! \brief Square root. +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVSqrt(QT3DSF64 a) +{ + return ::sqrt(a); +} + +//! \brief reciprocal square root. +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVRecipSqrt(QT3DSF32 a) +{ + return intrinsics::recipSqrt(a); +} + +//! \brief reciprocal square root. +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVRecipSqrt(QT3DSF64 a) +{ + return 1 / ::sqrt(a); +} + +//!trigonometry -- all angles are in radians. + +//! \brief Sine of an angle ( Unit: Radians ) +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVSin(QT3DSF32 a) +{ + return intrinsics::sin(a); +} + +//! \brief Sine of an angle ( Unit: Radians ) +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVSin(QT3DSF64 a) +{ + return ::sin(a); +} + +//! \brief Cosine of an angle (Unit: Radians) +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVCos(QT3DSF32 a) +{ + return intrinsics::cos(a); +} + +//! \brief Cosine of an angle (Unit: Radians) +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVCos(QT3DSF64 a) +{ + return ::cos(a); +} + +/** +\brief Tangent of an angle. +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVTan(QT3DSF32 a) +{ + return QT3DSF32(::tan(a)); +} + +/** +\brief Tangent of an angle. +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVTan(QT3DSF64 a) +{ + return ::tan(a); +} + +/** +\brief Arcsine. +Returns angle between -PI/2 and PI/2 in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAsin(QT3DSF32 f) +{ + return QT3DSF32(::asin(NVClamp(f, -1.0f, 1.0f))); +} + +/** +\brief Arcsine. +Returns angle between -PI/2 and PI/2 in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAsin(QT3DSF64 f) +{ + return ::asin(NVClamp(f, -1.0, 1.0)); +} + +/** +\brief Arccosine. +Returns angle between 0 and PI in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAcos(QT3DSF32 f) +{ + return QT3DSF32(::acos(NVClamp(f, -1.0f, 1.0f))); +} + +/** +\brief Arccosine. +Returns angle between 0 and PI in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAcos(QT3DSF64 f) +{ + return ::acos(NVClamp(f, -1.0, 1.0)); +} + +/** +\brief ArcTangent. +Returns angle between -PI/2 and PI/2 in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAtan(QT3DSF32 a) +{ + return QT3DSF32(::atan(a)); +} + +/** +\brief ArcTangent. +Returns angle between -PI/2 and PI/2 in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAtan(QT3DSF64 a) +{ + return ::atan(a); +} + +/** +\brief Arctangent of (x/y) with correct sign. +Returns angle between -PI and PI in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVAtan2(QT3DSF32 x, QT3DSF32 y) +{ + return QT3DSF32(::atan2(x, y)); +} + +/** +\brief Arctangent of (x/y) with correct sign. +Returns angle between -PI and PI in radians +Unit: Radians +*/ +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 NVAtan2(QT3DSF64 x, QT3DSF64 y) +{ + return ::atan2(x, y); +} + +//! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVIsFinite(QT3DSF32 f) +{ + return intrinsics::isFinite(f); +} + +//! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool NVIsFinite(QT3DSF64 f) +{ + return intrinsics::isFinite(f); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVFloor(QT3DSF32 a) +{ + return ::floorf(a); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVExp(QT3DSF32 a) +{ + return ::expf(a); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVCeil(QT3DSF32 a) +{ + return ::ceilf(a); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVSign(QT3DSF32 a) +{ + return qt3ds::intrinsics::sign(a); +} + +QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 NVPow(QT3DSF32 x, QT3DSF32 y) +{ + return ::powf(x, y); +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_MATH_H diff --git a/src/Runtime/Source/foundation/Qt3DSMathUtils.cpp b/src/Runtime/Source/foundation/Qt3DSMathUtils.cpp new file mode 100644 index 00000000..7eee7405 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMathUtils.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMathUtils.h" +#include "foundation/Qt3DSUtilities.h" +#include "foundation/Qt3DSMat33.h" + +using namespace qt3ds; +using namespace qt3ds::foundation; +using namespace qt3ds::intrinsics; + +QT3DSQuat qt3ds::foundation::computeQuatFromNormal(const QT3DSVec3 &n) +{ + // parallel or anti-parallel + if (n.x > 0.9999f) { + // parallel + return QT3DSQuat::createIdentity(); + } else if (n.x < -0.9999f) { + // anti-parallel + // contactQuaternion.fromAngleAxisFast(PXD_PI, Vector3(0.0f, 1.0f, 0.0f)); + return QT3DSQuat(0.0f, 1.0f, 0.0f, 0.0f); + } else { + QT3DSVec3 rotVec(0.0f, -n.z, n.y); + + // Convert to quat + NVReal angle = rotVec.magnitude(); + rotVec *= 1.0f / angle; + // if(angle > 1.0f) angle = 1.0f; + angle = selectMin(angle, 1.0f); + + // djs: injudiciously imbecilic use of trig functions, good thing Adam is going to trample + // this path like a + // frustrated rhinoceros in mating season + + angle = NVAsin(angle); + + // if(n.x < 0) + // angle = NVPi - angle; + angle = fsel(n.x, angle, NVPi - angle); + + return QT3DSQuat(angle, rotVec); + } +} + +/** +\brief computes a oriented bounding box around the scaled basis. +\param basis Input = skewed basis, Output = (normalized) orthogonal basis. +\return Bounding box extent. +*/ +QT3DSVec3 qt3ds::foundation::optimizeBoundingBox(QT3DSMat33 &basis) +{ + QT3DSVec3 *QT3DS_RESTRICT vec = &basis[0]; // PT: don't copy vectors if not needed... + + // PT: since we store the magnitudes to memory, we can avoid the FCMNV afterwards + QT3DSVec3 magnitude(vec[0].magnitudeSquared(), vec[1].magnitudeSquared(), + vec[2].magnitudeSquared()); + +// find indices sorted by magnitude +#ifdef QT3DS_X360 + int i = (QT3DSU32 &)(magnitude[1]) > (QT3DSU32 &)(magnitude[0]) ? 1 : 0; + int j = (QT3DSU32 &)(magnitude[2]) > (QT3DSU32 &)(magnitude[1 - i]) ? 2 : 1 - i; +#else + int i = magnitude[1] > magnitude[0] ? 1 : 0; + int j = magnitude[2] > magnitude[1 - i] ? 2 : 1 - i; +#endif + const int k = 3 - i - j; +#ifdef QT3DS_X360 + if ((QT3DSU32 &)(magnitude[i]) < (QT3DSU32 &)(magnitude[j])) +#else + if (magnitude[i] < magnitude[j]) +#endif + swap(i, j); + + // ortho-normalize basis + + NVReal invSqrt = NVRecipSqrt(magnitude[i]); + magnitude[i] *= invSqrt; + vec[i] *= invSqrt; // normalize the first axis + NVReal dotij = vec[i].dot(vec[j]); + NVReal dotik = vec[i].dot(vec[k]); + magnitude[i] += NVAbs(dotij) + NVAbs(dotik); // elongate the axis by projection of the other two + vec[j] -= vec[i] * dotij; // orthogonize the two remaining axii relative to vec[i] + vec[k] -= vec[i] * dotik; + + magnitude[j] = vec[j].normalize(); + NVReal dotjk = vec[j].dot(vec[k]); + magnitude[j] += NVAbs(dotjk); // elongate the axis by projection of the other one + vec[k] -= vec[j] * dotjk; // orthogonize vec[k] relative to vec[j] + + magnitude[k] = vec[k].normalize(); + + return magnitude; +} + +QT3DSQuat qt3ds::foundation::slerp(const NVReal t, const QT3DSQuat &left, const QT3DSQuat &right) +{ + const NVReal quatEpsilon = (NVReal(1.0e-8f)); + + NVReal cosine = left.dot(right); + NVReal sign = NVReal(1); + if (cosine < 0) { + cosine = -cosine; + sign = NVReal(-1); + } + + NVReal sine = NVReal(1) - cosine * cosine; + + if (sine >= quatEpsilon * quatEpsilon) { + sine = NVSqrt(sine); + const NVReal angle = NVAtan2(sine, cosine); + const NVReal i_sin_angle = NVReal(1) / sine; + + const NVReal leftw = NVSin(angle * (NVReal(1) - t)) * i_sin_angle; + const NVReal rightw = NVSin(angle * t) * i_sin_angle * sign; + + return left * leftw + right * rightw; + } + + return left; +} + +void qt3ds::foundation::integrateTransform(const NVTransform &curTrans, const QT3DSVec3 &linvel, + const QT3DSVec3 &angvel, NVReal timeStep, NVTransform &result) +{ + result.p = curTrans.p + linvel * timeStep; + + // from void NVsDynamicsContext::integrateAtomPose(NVsRigidBody* atom, Cm::BitMap + // &shapeChangedMap) const: + // Integrate the rotation using closed form quaternion integrator + NVReal w = angvel.magnitudeSquared(); + + if (w != 0.0f) { + w = NVSqrt(w); + if (w != 0.0f) { + const NVReal v = timeStep * w * 0.5f; + const NVReal q = NVCos(v); + const NVReal s = NVSin(v) / w; + + const QT3DSVec3 pqr = angvel * s; + const QT3DSQuat quatVel(pqr.x, pqr.y, pqr.z, 0); + QT3DSQuat out; // need to have temporary, otherwise we may overwrite input if &curTrans == + // &result. + out = quatVel * curTrans.q; + out.x += curTrans.q.x * q; + out.y += curTrans.q.y * q; + out.z += curTrans.q.z * q; + out.w += curTrans.q.w * q; + result.q = out; + return; + } + } + // orientation stays the same - convert from quat to matrix: + result.q = curTrans.q; +} diff --git a/src/Runtime/Source/foundation/Qt3DSMathUtils.h b/src/Runtime/Source/foundation/Qt3DSMathUtils.h new file mode 100644 index 00000000..6d3d0abc --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMathUtils.h @@ -0,0 +1,571 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSMATHUTILS_H +#define QT3DS_FOUNDATION_PSMATHUTILS_H + +#include "foundation/Qt3DSTransform.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSIntrinsics.h" +#include + +// General guideline is: if it's an abstract math function, it belongs here. +// If it's a math function where the inputs have specific semantics (e.g. +// separateSwingTwist) it doesn't. + +namespace qt3ds { +namespace foundation { + using namespace intrinsics; + /** + \brief sign returns the sign of its argument. The sign of zero is undefined. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 sign(const QT3DSF32 a) { + return intrinsics::sign(a); + } + + /** + \brief sign returns the sign of its argument. The sign of zero is undefined. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 sign(const QT3DSF64 a) { return (a >= 0.0) ? 1.0 : -1.0; } + + /** + \brief sign returns the sign of its argument. The sign of zero is undefined. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSI32 sign(const QT3DSI32 a) { return (a >= 0) ? 1 : -1; } + + /** + \brief Returns true if the two numbers are within eps of each other. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool equals(const QT3DSF32 a, const QT3DSF32 b, const QT3DSF32 eps) + { + return (NVAbs(a - b) < eps); + } + + /** + \brief Returns true if the two numbers are within eps of each other. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool equals(const QT3DSF64 a, const QT3DSF64 b, const QT3DSF64 eps) + { + return (NVAbs(a - b) < eps); + } + + /** + \brief The floor function returns a floating-point value representing the largest integer that + is less than or equal to x. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 floor(const QT3DSF32 a) { return floatFloor(a); } + + /** + \brief The floor function returns a floating-point value representing the largest integer that + is less than or equal to x. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 floor(const QT3DSF64 a) { return ::floor(a); } + + /** + \brief The ceil function returns a single value representing the smallest integer that is + greater than or equal to x. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 ceil(const QT3DSF32 a) { return ::ceilf(a); } + + /** + \brief The ceil function returns a double value representing the smallest integer that is + greater than or equal to x. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 ceil(const QT3DSF64 a) { return ::ceil(a); } + + /** + \brief mod returns the floating-point remainder of x / y. + + If the value of y is 0.0, mod returns a quiet NaN. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 mod(const QT3DSF32 x, const QT3DSF32 y) + { + return (QT3DSF32)::fmod(x, y); + } + + /** + \brief mod returns the floating-point remainder of x / y. + + If the value of y is 0.0, mod returns a quiet NaN. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 mod(const QT3DSF64 x, const QT3DSF64 y) + { + return ::fmod(x, y); + } + + /** + \brief Square. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 sqr(const QT3DSF32 a) { return a * a; } + + /** + \brief Square. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 sqr(const QT3DSF64 a) { return a * a; } + + /** + \brief Calculates x raised to the power of y. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 pow(const QT3DSF32 x, const QT3DSF32 y) + { + return ::powf(x, y); + } + + /** + \brief Calculates x raised to the power of y. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 pow(const QT3DSF64 x, const QT3DSF64 y) { return ::pow(x, y); } + + /** + \brief Calculates e^n + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 exp(const QT3DSF32 a) { return QT3DSF32(::exp(a)); } + /** + + \brief Calculates e^n + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 exp(const QT3DSF64 a) { return ::exp(a); } + + /** + \brief Calculates logarithms. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 logE(const QT3DSF32 a) { return QT3DSF32(::log(a)); } + + /** + \brief Calculates logarithms. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 logE(const QT3DSF64 a) { return ::log(a); } + + /** + \brief Calculates logarithms. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 log2(const QT3DSF32 a) + { + return QT3DSF32(::log(a)) / 0.693147180559945309417f; + } + + /** + \brief Calculates logarithms. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 log2(const QT3DSF64 a) + { + return ::log(a) / 0.693147180559945309417; + } + + /** + \brief Calculates logarithms. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 log10(const QT3DSF32 a) { return (QT3DSF32)::log10(a); } + + /** + \brief Calculates logarithms. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 log10(const QT3DSF64 a) { return ::log10(a); } + + /** + \brief Converts degrees to radians. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 degToRad(const QT3DSF32 a) + { + return (QT3DSF32)0.01745329251994329547 * a; + } + + /** + \brief Converts degrees to radians. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 degToRad(const QT3DSF64 a) + { + return (QT3DSF64)0.01745329251994329547 * a; + } + + /** + \brief Converts radians to degrees. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 radToDeg(const QT3DSF32 a) + { + return (QT3DSF32)57.29577951308232286465 * a; + } + + /** + \brief Converts radians to degrees. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF64 radToDeg(const QT3DSF64 a) + { + return (QT3DSF64)57.29577951308232286465 * a; + } + + //! \brief compute sine and cosine at the same time. There is a 'fsincos' on PC that we probably want to use here + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void sincos(const QT3DSF32 radians, QT3DSF32 &sin, QT3DSF32 &cos) + { + /* something like: + _asm fld Local + _asm fsincos + _asm fstp LocalCos + _asm fstp LocalSin + */ + sin = NVSin(radians); + cos = NVCos(radians); + } + + /** + \brief uniform random number in [a,b] + */ + QT3DS_FORCE_INLINE QT3DSI32 rand(const QT3DSI32 a, const QT3DSI32 b) + { + return a + (QT3DSI32)(::rand() % (b - a + 1)); + } + + /** + \brief uniform random number in [a,b] + */ + QT3DS_FORCE_INLINE QT3DSF32 rand(const QT3DSF32 a, const QT3DSF32 b) + { + return a + (b - a) * ::rand() / RAND_MAX; + } + + //! \brief return angle between two vectors in radians + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSF32 angle(const QT3DSVec3 &v0, const QT3DSVec3 &v1) + { + const QT3DSF32 cos = v0.dot(v1); // |v0|*|v1|*Cos(Angle) + const QT3DSF32 sin = (v0.cross(v1)).magnitude(); // |v0|*|v1|*Sin(Angle) + return NVAtan2(sin, cos); + } + + //! If possible use instead fsel on the dot product /*fsel(d.dot(p),onething,anotherthing);*/ + //! Compares orientations (more readable, user-friendly function) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool sameDirection(const QT3DSVec3 &d, const QT3DSVec3 &p) + { + return d.dot(p) >= 0.0f; + } + + //! Checks 2 values have different signs + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE IntBool differentSign(NVReal f0, NVReal f1) + { + union { + QT3DSU32 u; + NVReal f; + } u1, u2; + u1.f = f0; + u2.f = f1; + return (u1.u ^ u2.u) & QT3DS_SIGN_BITMASK; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSMat33 star(const QT3DSVec3 &v) + { + return QT3DSMat33(QT3DSVec3(0, v.z, -v.y), QT3DSVec3(-v.z, 0, v.x), QT3DSVec3(v.y, -v.x, 0)); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 log(const QT3DSQuat &q) + { + const NVReal s = q.getImaginaryPart().magnitude(); + if (s < 1e-12) + return QT3DSVec3(0.0f); + // force the half-angle to have magnitude <= pi/2 + NVReal halfAngle = q.w < 0 ? NVAtan2(-s, -q.w) : NVAtan2(s, q.w); + QT3DS_ASSERT(halfAngle >= -NVPi / 2 && halfAngle <= NVPi / 2); + + return q.getImaginaryPart().getNormalized() * 2 * halfAngle; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat exp(const QT3DSVec3 &v) + { + const NVReal m = v.magnitudeSquared(); + return m < 1e-24 ? QT3DSQuat::createIdentity() : QT3DSQuat(NVSqrt(m), v * NVRecipSqrt(m)); + } + + // quat to rotate v0 t0 v1 + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat rotationArc(const QT3DSVec3 &v0, const QT3DSVec3 &v1) + { + const QT3DSVec3 cross = v0.cross(v1); + const NVReal d = v0.dot(v1); + if (d <= -0.99999f) + return (NVAbs(v0.x) < 0.1f ? QT3DSQuat(0.0f, v0.z, -v0.y, 0.0f) + : QT3DSQuat(v0.y, -v0.x, 0.0, 0.0)) + .getNormalized(); + + const NVReal s = NVSqrt((1 + d) * 2), r = 1 / s; + + return QT3DSQuat(cross.x * r, cross.y * r, cross.z * r, s * 0.5f).getNormalized(); + } + + //! Computes the maximum delta to another transform + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal maxComponentDelta(const NVTransform &t0, + const NVTransform &t1) + { + NVReal delta = NVAbs(t0.p.x - t1.p.x); + delta = NVMax(delta, NVAbs(t0.p.y - t1.p.y)); + delta = NVMax(delta, NVAbs(t0.p.z - t1.p.z)); + delta = NVMax(delta, NVAbs(t0.q.x - t1.q.x)); + delta = NVMax(delta, NVAbs(t0.q.y - t1.q.y)); + delta = NVMax(delta, NVAbs(t0.q.z - t1.q.z)); + delta = NVMax(delta, NVAbs(t0.q.w - t1.q.w)); + + return delta; + } + + /** + \brief returns largest axis + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU32 largestAxis(const QT3DSVec3 &v) + { + QT3DSU32 m = v.y > v.x ? 1 : 0; + return v.z > v[m] ? 2 : m; + } + + /** + \brief returns axis with smallest absolute value + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU32 closestAxis(const QT3DSVec3 &v) + { + QT3DSU32 m = NVAbs(v.y) > NVAbs(v.x) ? 1 : 0; + return NVAbs(v.z) > NVAbs(v[m]) ? 2 : m; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSU32 closestAxis(const QT3DSVec3 &v, QT3DSU32 &j, QT3DSU32 &k) + { + // find largest 2D plane projection + const QT3DSF32 absNV = NVAbs(v.x); + const QT3DSF32 absNy = NVAbs(v.y); + const QT3DSF32 absNz = NVAbs(v.z); + + QT3DSU32 m = 0; // x biggest axis + j = 1; + k = 2; + if (absNy > absNV && absNy > absNz) { + // y biggest + j = 2; + k = 0; + m = 1; + } else if (absNz > absNV) { + // z biggest + j = 0; + k = 1; + m = 2; + } + return m; + } + + /*! + Extend an edge along its length by a factor + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void makeFatEdge(QT3DSVec3 &p0, QT3DSVec3 &p1, NVReal fatCoeff) + { + QT3DSVec3 delta = p1 - p0; + + const NVReal m = delta.magnitude(); + if (m > 0.0f) { + delta *= fatCoeff / m; + p0 -= delta; + p1 += delta; + } + } + + //! Compute point as combination of barycentric coordinates + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 computeBarycentricPoint(const QT3DSVec3 &p0, + const QT3DSVec3 &p1, + const QT3DSVec3 &p2, NVReal u, + NVReal v) + { + // This seems to confuse the compiler... + // return (1.0f - u - v)*p0 + u*p1 + v*p2; + const QT3DSF32 w = 1.0f - u - v; + return QT3DSVec3(w * p0.x + u * p1.x + v * p2.x, w * p0.y + u * p1.y + v * p2.y, + w * p0.z + u * p1.z + v * p2.z); + } + + // generates a pair of quaternions (swing, twist) such that in = swing * twist, with + // swing.x = 0 + // twist.y = twist.z = 0, and twist is a unit quat + QT3DS_FORCE_INLINE void separateSwingTwist(const QT3DSQuat &q, QT3DSQuat &swing, QT3DSQuat &twist) + { + twist = q.x != 0.0f ? QT3DSQuat(q.x, 0, 0, q.w).getNormalized() : QT3DSQuat::createIdentity(); + swing = q * twist.getConjugate(); + } + + // generate two tangent vectors to a given normal + QT3DS_FORCE_INLINE void normalToTangents(const QT3DSVec3 &normal, QT3DSVec3 &tangent0, QT3DSVec3 &tangent1) + { + tangent0 = NVAbs(normal.x) < 0.70710678f ? QT3DSVec3(0, -normal.z, normal.y) + : QT3DSVec3(-normal.y, normal.x, 0); + tangent0.normalize(); + tangent1 = normal.cross(tangent0); + } + + // todo: what is this function doing? + QT3DS_FOUNDATION_API QT3DSQuat computeQuatFromNormal(const QT3DSVec3 &n); + + /** + \brief computes a oriented bounding box around the scaled basis. + \param basis Input = skewed basis, Output = (normalized) orthogonal basis. + \return Bounding box extent. + */ + QT3DS_FOUNDATION_API QT3DSVec3 optimizeBoundingBox(QT3DSMat33 &basis); + + QT3DS_FOUNDATION_API QT3DSQuat slerp(const NVReal t, const QT3DSQuat &left, const QT3DSQuat &right); + + QT3DS_INLINE QT3DSVec3 ellipseClamp(const QT3DSVec3 &point, const QT3DSVec3 &radii) + { + // This function need to be implemented in the header file because + // it is included in a spu shader program. + + // finds the closest point on the ellipse to a given point + + // (p.y, p.z) is the input point + // (e.y, e.z) are the radii of the ellipse + + // lagrange multiplier method with Newton/Halley hybrid root-finder. + // see http://www.geometrictools.com/Documentation/DistancePointToEllipse2.pdf + // for proof of Newton step robustness and initial estimate. + // Halley converges much faster but sometimes overshoots - when that happens we take + // a newton step instead + + // converges in 1-2 iterations where D&C works well, and it's good with 4 iterations + // with any ellipse that isn't completely crazy + + const QT3DSU32 MAX_ITERATIONS = 20; + const NVReal convergenceThreshold = 1e-4f; + + // iteration requires first quadrant but we recover generality later + + QT3DSVec3 q(0, NVAbs(point.y), NVAbs(point.z)); + const NVReal tinyEps = + (NVReal)(1e-6f); // very close to minor axis is numerically problematic but trivial + if (radii.y >= radii.z) { + if (q.z < tinyEps) + return QT3DSVec3(0, point.y > 0 ? radii.y : -radii.y, 0); + } else { + if (q.y < tinyEps) + return QT3DSVec3(0, 0, point.z > 0 ? radii.z : -radii.z); + } + + QT3DSVec3 denom, e2 = radii.multiply(radii), eq = radii.multiply(q); + + // we can use any initial guess which is > maximum(-e.y^2,-e.z^2) and for which f(t) is > 0. + // this guess works well near the axes, but is weak along the diagonals. + + NVReal t = NVMax(eq.y - e2.y, eq.z - e2.z); + + for (QT3DSU32 i = 0; i < MAX_ITERATIONS; i++) { + denom = QT3DSVec3(0, 1 / (t + e2.y), 1 / (t + e2.z)); + QT3DSVec3 denom2 = eq.multiply(denom); + + QT3DSVec3 fv = denom2.multiply(denom2); + NVReal f = fv.y + fv.z - 1; + + // although in exact arithmetic we are guaranteed f>0, we can get here + // on the first iteration via catastrophic cancellation if the point is + // very close to the origin. In that case we just behave as if f=0 + + if (f < convergenceThreshold) + return e2.multiply(point).multiply(denom); + + NVReal df = fv.dot(denom) * -2.0f; + t = t - f / df; + } + + // we didn't converge, so clamp what we have + QT3DSVec3 r = e2.multiply(point).multiply(denom); + return r * NVRecipSqrt(sqr(r.y / radii.y) + sqr(r.z / radii.z)); + } + + QT3DS_INLINE NVReal tanHalf(NVReal sin, NVReal cos) { return sin / (1 + cos); } + + QT3DS_INLINE QT3DSQuat quatFromTanQVector(const QT3DSVec3 &v) + { + NVReal v2 = v.dot(v); + if (v2 < 1e-12f) + return QT3DSQuat::createIdentity(); + NVReal d = 1 / (1 + v2); + return QT3DSQuat(v.x * 2, v.y * 2, v.z * 2, 1 - v2) * d; + } + + QT3DS_FORCE_INLINE QT3DSVec3 cross100(const QT3DSVec3 &b) { return QT3DSVec3(0.0f, -b.z, b.y); } + QT3DS_FORCE_INLINE QT3DSVec3 cross010(const QT3DSVec3 &b) { return QT3DSVec3(b.z, 0.0f, -b.x); } + QT3DS_FORCE_INLINE QT3DSVec3 cross001(const QT3DSVec3 &b) { return QT3DSVec3(-b.y, b.x, 0.0f); } + + QT3DS_INLINE void decomposeVector(QT3DSVec3 &normalCompo, QT3DSVec3 &tangentCompo, + const QT3DSVec3 &outwardDir, const QT3DSVec3 &outwardNormal) + { + normalCompo = outwardNormal * (outwardDir.dot(outwardNormal)); + tangentCompo = outwardDir - normalCompo; + } + + //! \brief Return (i+1)%3 + // Avoid variable shift for XBox: + // QT3DS_INLINE QT3DSU32 NV::getNextIndex3(QT3DSU32 i) { return (1<> 1)) & 3; } + + QT3DS_INLINE QT3DSMat33 rotFrom2Vectors(const QT3DSVec3 &from, const QT3DSVec3 &to) + { + // See bottom of + // http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/index.htm + + // Early exit if to = from + if ((from - to).magnitudeSquared() < 1e-4f) + return QT3DSMat33::createIdentity(); + + // Early exit if to = -from + if ((from + to).magnitudeSquared() < 1e-4f) + return QT3DSMat33::createDiagonal(QT3DSVec3(1.0f, -1.0f, -1.0f)); + + QT3DSVec3 n = from.cross(to); + + NVReal C = from.dot(to), S = NVSqrt(1 - C * C), CC = 1 - C; + + NVReal xx = n.x * n.x, yy = n.y * n.y, zz = n.z * n.z, xy = n.x * n.y, yz = n.y * n.z, + xz = n.x * n.z; + + QT3DSMat33 R; + + R(0, 0) = 1 + CC * (xx - 1); + R(0, 1) = -n.z * S + CC * xy; + R(0, 2) = n.y * S + CC * xz; + + R(1, 0) = n.z * S + CC * xy; + R(1, 1) = 1 + CC * (yy - 1); + R(1, 2) = -n.x * S + CC * yz; + + R(2, 0) = -n.y * S + CC * xz; + R(2, 1) = n.x * S + CC * yz; + R(2, 2) = 1 + CC * (zz - 1); + + return R; + } + + QT3DS_FOUNDATION_API void integrateTransform(const NVTransform &curTrans, const QT3DSVec3 &linvel, + const QT3DSVec3 &angvel, NVReal timeStep, + NVTransform &result); + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSMemoryBuffer.h b/src/Runtime/Source/foundation/Qt3DSMemoryBuffer.h new file mode 100644 index 00000000..bee2f0c2 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMemoryBuffer.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_MEMORYBUFFER_H +#define QT3DS_FOUNDATION_MEMORYBUFFER_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSIntrinsics.h" + +#ifdef __INTEGRITY +#define __restrict +#endif + +namespace qt3ds { +namespace foundation { + using namespace intrinsics; + + template + class MemoryBuffer : public TAllocator + { + QT3DSU8 *mBegin; + QT3DSU8 *mEnd; + QT3DSU8 *mCapacityEnd; + + public: + MemoryBuffer(const TAllocator &inAlloc = TAllocator()) + : TAllocator(inAlloc) + , mBegin(0) + , mEnd(0) + , mCapacityEnd(0) + { + } + ~MemoryBuffer() + { + if (mBegin) + TAllocator::deallocate(mBegin); + } + QT3DSU32 size() const { return static_cast(mEnd - mBegin); } + QT3DSU32 capacity() const { return static_cast(mCapacityEnd - mBegin); } + QT3DSU8 *begin() { return mBegin; } + QT3DSU8 *end() { return mEnd; } + const QT3DSU8 *begin() const { return mBegin; } + const QT3DSU8 *end() const { return mEnd; } + void clear() { mEnd = mBegin; } + void write(QT3DSU8 inValue) { *growBuf(1) = inValue; } + + template + void write(const TDataType &inValue) + { + const QT3DSU8 *__restrict readPtr = reinterpret_cast(&inValue); + QT3DSU8 *__restrict writePtr = growBuf(sizeof(TDataType)); + for (QT3DSU32 idx = 0; idx < sizeof(TDataType); ++idx) + writePtr[idx] = readPtr[idx]; + } + + template + void write(const TDataType *inValue, QT3DSU32 inLength) + { + using namespace qt3ds::intrinsics; + if (inValue && inLength) { + QT3DSU32 writeSize = inLength * sizeof(TDataType); + memCopy(growBuf(writeSize), inValue, writeSize); + } + if (inLength && !inValue) { + QT3DS_ASSERT(false); + // You can't not write something, because that will cause + // the receiving end to crash. + QT3DSU32 writeSize = inLength * sizeof(TDataType); + for (QT3DSU32 idx = 0; idx < writeSize; ++idx) + write((QT3DSU8)0); + } + } + + void writeStrided(const QT3DSU8 *__restrict inData, QT3DSU32 inItemSize, QT3DSU32 inLength, + QT3DSU32 inStride) + { + if (inStride == 0 || inStride == inItemSize) + write(inData, inLength * inItemSize); + else if (inData && inLength) { + QT3DSU32 writeSize = inLength * inItemSize; + QT3DSU8 *__restrict writePtr = growBuf(writeSize); + for (QT3DSU32 idx = 0; idx < inLength; + ++idx, writePtr += inItemSize, inData += inStride) + memCopy(writePtr, inData, inItemSize); + } + } + QT3DSU8 *growBuf(QT3DSU32 inAmount) + { + QT3DSU32 offset = size(); + QT3DSU32 newSize = offset + inAmount; + reserve(newSize); + mEnd += inAmount; + return mBegin + offset; + } + void writeZeros(QT3DSU32 inAmount) + { + QT3DSU32 offset = size(); + growBuf(inAmount); + qt3ds::foundation::memZero(begin() + offset, inAmount); + } + void align(QT3DSU32 inAmount) + { + QT3DSU32 leftover = size() % inAmount; + if (leftover) + writeZeros(inAmount - leftover); + } + void reserve(QT3DSU32 newSize) + { + using namespace qt3ds::intrinsics; + QT3DSU32 currentSize = size(); + if (newSize && newSize >= capacity()) { + QT3DSU32 newDataSize = newSize * 2; + if (newDataSize > 8192) + newDataSize = (QT3DSU32)((QT3DSU32)newSize * 1.2f); + QT3DSU8 *newData = + static_cast(TAllocator::allocate(newDataSize, __FILE__, __LINE__)); + if (mBegin) { + memCopy(newData, mBegin, currentSize); + TAllocator::deallocate(mBegin); + } + mBegin = newData; + mEnd = mBegin + currentSize; + mCapacityEnd = mBegin + newDataSize; + } + } + operator NVDataRef() { return NVDataRef(begin(), size()); } + operator NVConstDataRef() const { return NVConstDataRef(begin(), size()); } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSMutex.h b/src/Runtime/Source/foundation/Qt3DSMutex.h new file mode 100644 index 00000000..5b717e5c --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSMutex.h @@ -0,0 +1,376 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSMUTEX_H +#define QT3DS_FOUNDATION_PSMUTEX_H + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSNoCopy.h" + +/* + * This inclusion is a best known fix for gcc 4.4.1 error: + * Creating object file for apex/src/NVAllocator.cpp ... + * In file included from apex/include/Qt3DSFoundation.h:30, + * from apex/src/NVAllocator.cpp:26: + * apex/include/Qt3DSMutex.h: In constructor 'nv::foundation::MutexT::MutexT(const Alloc&)': + * apex/include/Qt3DSMutex.h:92: error: no matching function for call to 'operator new(unsigned int, + * qt3ds::foundation::MutexImpl*&)' + * :0: note: candidates are: void* operator new(unsigned int) + */ +#include + +namespace qt3ds { +namespace foundation { +#ifdef QT3DS_FOUNDATION_NO_EXPORTS + class QT3DS_AUTOTEST_EXPORT MutexImpl +#else + class QT3DS_FOUNDATION_API MutexImpl +#endif + { + public: + /** + The constructor for Mutex creates a mutex. It is initially unlocked. + */ + MutexImpl(); + + /** + The destructor for Mutex deletes the mutex. + */ + ~MutexImpl(); + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method blocks until the mutex is + unlocked. + */ + bool lock(); + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method returns false without blocking. + */ + bool trylock(); + + /** + Release (unlock) the mutex. + */ + bool unlock(); + + /** + Size of this class. + */ + static const QT3DSU32 size; + }; + + class Mutex + { + public: + class ScopedLock : private NoCopy + { + Mutex &mMutex; + + public: + QT3DS_INLINE ScopedLock(Mutex &mutex) + : mMutex(mutex) + { + mMutex.lock(); + } + QT3DS_INLINE ~ScopedLock() { mMutex.unlock(); } + }; + + /** + The constructor for Mutex creates a mutex. It is initially unlocked. + */ + Mutex(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + mImpl = (MutexImpl *)QT3DS_ALLOC(alloc, MutexImpl::size, "MutexImpl"); + QT3DS_PLACEMENT_NEW(mImpl, MutexImpl)(); + } + + /** + The destructor for Mutex deletes the mutex. + */ + ~Mutex() + { + mImpl->~MutexImpl(); + QT3DS_FREE(mAllocator, mImpl); + } + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method blocks until the mutex is + unlocked. + */ + bool lock() const { return mImpl->lock(); } + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method returns false without blocking. + */ + bool trylock() const { return mImpl->trylock(); } + + /** + Release (unlock) the mutex. + */ + bool unlock() const { return mImpl->unlock(); } + + private: + NVAllocatorCallback &mAllocator; + MutexImpl *mImpl; + }; + + class QT3DS_FOUNDATION_API ReadWriteLock : private NoCopy + { + public: + ReadWriteLock(NVAllocatorCallback &alloc); + ~ReadWriteLock(); + + void lockReader(); + void lockWriter(); + + void unlockReader(); + void unlockWriter(); + + private: + class ReadWriteLockImpl *mImpl; + }; + + class ScopedReadLock : private NoCopy + { + public: + QT3DS_INLINE ScopedReadLock(ReadWriteLock &lock) + : mLock(lock) + { + mLock.lockReader(); + } + QT3DS_INLINE ~ScopedReadLock() { mLock.unlockReader(); } + + private: + ReadWriteLock &mLock; + }; + + class ScopedWriteLock : private NoCopy + { + public: + QT3DS_INLINE ScopedWriteLock(ReadWriteLock &lock) + : mLock(lock) + { + mLock.lockWriter(); + } + QT3DS_INLINE ~ScopedWriteLock() { mLock.unlockWriter(); } + + private: + ReadWriteLock &mLock; + }; + +/* + * Use this type of lock for mutex behaviour that must operate on SPU and PPU + * On non-PS3 platforms, it is implemented using Mutex + */ +#ifndef QT3DS_PS3 + + class AtomicLock : private NoCopy + { + Mutex mMutex; + + public: + AtomicLock(NVAllocatorCallback &alloc) + : mMutex(alloc) + { + } + + bool lock() { return mMutex.lock(); } + + bool trylock() { return mMutex.trylock(); } + + bool unlock() { return mMutex.unlock(); } + }; + + class AtomicLockCopy + { + AtomicLock *pLock; + + public: + AtomicLockCopy() + : pLock(NULL) + { + } + + AtomicLockCopy &operator=(AtomicLock &lock) + { + pLock = &lock; + return *this; + } + + bool lock() { return pLock->lock(); } + + bool trylock() { return pLock->trylock(); } + + bool unlock() { return pLock->unlock(); } + }; +#else + struct AtomicLockImpl + { + QT3DS_ALIGN(128, QT3DSU32 m_Lock); + QT3DSI32 m_LockId; + QT3DSU32 m_LockCount; + + AtomicLockImpl(); + }; + class AtomicLock //: private NoCopy + { + friend class AtomicLockCopy; + AtomicLockImpl *m_pImpl; + + public: + AtomicLock(); + + ~AtomicLock(); + + bool lock(); + + bool trylock(); + + bool unlock(); + }; + + // if an AtomicLock is copied and then the copy goes out of scope, it'll delete the atomic + // primitive + // (just a 128-byte aligned int) and cause a crash when it tries to delete it again + // This class just uses the atomic primitive without releasing it in the end. + + class AtomicLockCopy + { + AtomicLockImpl *m_pImpl; + + public: + AtomicLockCopy() + : m_pImpl(NULL) + { + } + + AtomicLockCopy(const AtomicLock &lock) + : m_pImpl(lock.m_pImpl) + { + } + + ~AtomicLockCopy() {} + + AtomicLockCopy &operator=(const AtomicLock &lock) + { + m_pImpl = lock.m_pImpl; + return *this; + } + + bool lock(); + + bool trylock(); + + bool unlock(); + }; +#endif + +#ifndef QT3DS_PS3 + + class AtomicRwLock : private NoCopy + { + ReadWriteLock m_Lock; + + public: + AtomicRwLock(NVAllocatorCallback &alloc) + : m_Lock(alloc) + { + } + + void lockReader() { m_Lock.lockReader(); } + void lockWriter() { m_Lock.lockWriter(); } + + bool tryLockReader() + { + // Todo - implement this + m_Lock.lockReader(); + return true; + } + + void unlockReader() { m_Lock.unlockReader(); } + void unlockWriter() { m_Lock.unlockWriter(); } + }; +#else + + struct AtomicRwLockImpl + { + QT3DS_ALIGN(128, volatile QT3DSU32 m_Lock); + QT3DS_ALIGN(128, volatile QT3DSU32 m_ReadCounter); + QT3DSI32 m_LockId; + QT3DSU32 m_LockCount; + + AtomicRwLockImpl(); + }; + + class AtomicRwLock : private NoCopy + { + AtomicRwLockImpl *m_pImpl; + + public: + AtomicRwLock(); + + ~AtomicRwLock(); + + void lockReader(); + + bool tryLockReader(); + + void lockWriter(); + + void unlockReader(); + + void unlockWriter(); + }; + +#endif + + class ScopedAtomicLock : private NoCopy + { + QT3DS_INLINE ScopedAtomicLock(AtomicLock &lock) + : mLock(lock) + { + mLock.lock(); + } + QT3DS_INLINE ~ScopedAtomicLock() { mLock.unlock(); } + + private: + AtomicLock &mLock; + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSNoCopy.h b/src/Runtime/Source/foundation/Qt3DSNoCopy.h new file mode 100644 index 00000000..817f5e19 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSNoCopy.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSNOCOPY_H +#define QT3DS_FOUNDATION_PSNOCOPY_H + +#include "foundation/Qt3DS.h" + +namespace qt3ds { +namespace foundation { + class NoCopy + { + NoCopy(const NoCopy &c); + NoCopy &operator=(const NoCopy &c); + + public: + NoCopy() {} + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSOption.h b/src/Runtime/Source/foundation/Qt3DSOption.h new file mode 100644 index 00000000..18d6c3b2 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSOption.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_OPTION_H +#define QT3DS_FOUNDATION_OPTION_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" + +namespace qt3ds { +namespace foundation { + + struct Empty + { + }; + + template + class Option + { + TDataType mData; + bool mHasValue; + + public: + Option(const TDataType &data) + : mData(data) + , mHasValue(true) + { + } + Option(const Empty &) + : mHasValue(false) + { + } + Option() + : mHasValue(false) + { + } + Option(const Option &other) + : mData(other.mData) + , mHasValue(other.mHasValue) + { + } + Option &operator=(const Option &other) + { + mData = other.mData; + mHasValue = other.mHasValue; + return *this; + } + + bool isEmpty() const { return !mHasValue; } + void setEmpty() { mHasValue = false; } + bool hasValue() const { return mHasValue; } + + const TDataType &getValue() const + { + QT3DS_ASSERT(mHasValue); + return mData; + } + TDataType &getValue() + { + QT3DS_ASSERT(mHasValue); + return mData; + } + TDataType &unsafeGetValue() { return mData; } + + operator const TDataType &() const { return getValue(); } + operator TDataType &() { return getValue(); } + + const TDataType *operator->() const { return &getValue(); } + TDataType *operator->() { return &getValue(); } + + const TDataType &operator*() const { return getValue(); } + TDataType &operator*() { return getValue(); } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSPerfTimer.cpp b/src/Runtime/Source/foundation/Qt3DSPerfTimer.cpp new file mode 100644 index 00000000..06fb5d38 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSPerfTimer.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "EASTL/hash_map.h" +#include "EASTL/string.h" +#include "EASTL/vector.h" +#include "EASTL/sort.h" + +using namespace qt3ds::foundation; +using namespace qt3ds; + +namespace { +struct STimerEntry +{ + QT3DSU64 m_Total; + QT3DSU64 m_Max; + QT3DSU32 m_UpdateCount; + CRegisteredString m_Tag; + size_t m_Order; + + STimerEntry(CRegisteredString tag, size_t order) + : m_Total(0) + , m_Max(0) + , m_UpdateCount(0) + , m_Tag(tag) + , m_Order(order) + { + } + void Update(QT3DSU64 increment) + { + m_Total += increment; + m_Max = increment > m_Max ? increment : m_Max; + ++m_UpdateCount; + } + + void Output(NVFoundationBase &fnd, QT3DSU32 inFramesPassed) + { + Q_UNUSED(fnd) + if (m_Total) { + QT3DSU64 tensNanos = Time::sCounterFreq.toTensOfNanos(m_Total); + QT3DSU64 maxNanos = Time::sCounterFreq.toTensOfNanos(m_Max); + + double milliseconds = tensNanos / 100000.0; + double maxMilliseconds = maxNanos / 100000.0; + if (inFramesPassed == 0) + qCWarning(WARNING, PERF_INFO, "%s - %fms", m_Tag.c_str(), milliseconds); + else { + milliseconds /= inFramesPassed; + qCWarning(WARNING, PERF_INFO, "%s - %fms/frame-total %fms-max %u hits", + m_Tag.c_str(), milliseconds, maxMilliseconds, m_UpdateCount); + } + } + } + + void Reset() + { + m_Total = 0; + m_Max = 0; + m_UpdateCount = 0; + } + + bool operator<(const STimerEntry &other) const { return m_Order < other.m_Order; } +}; +struct SPerfTimer : public IPerfTimer +{ + typedef eastl::hash_map THashMapType; + NVFoundationBase &m_Foundation; + // This object needs its own string table because it is used during the binary load process with + // the application string table gets booted up. + NVScopedRefCounted m_StringTable; + THashMapType m_Entries; + eastl::vector m_PrintEntries; + Mutex m_Mutex; + QT3DSI32 mRefCount; + + SPerfTimer(NVFoundationBase &fnd) + : m_Foundation(fnd) + , m_StringTable(IStringTable::CreateStringTable(fnd.getAllocator())) + , m_Mutex(fnd.getAllocator()) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + void Update(const char *inId, QT3DSU64 inAmount) override + { + Mutex::ScopedLock __locker(m_Mutex); + CRegisteredString theStr(m_StringTable->RegisterStr(inId)); + THashMapType::iterator theFind = + m_Entries.insert(eastl::make_pair(theStr, STimerEntry(theStr, m_Entries.size()))).first; + theFind->second.Update(inAmount); + } + + // Dump current summation of timer data. + void OutputTimerData(QT3DSU32 inFramesPassed = 0) override + { + Mutex::ScopedLock __locker(m_Mutex); + m_PrintEntries.clear(); + for (THashMapType::iterator iter = m_Entries.begin(), end = m_Entries.end(); iter != end; + ++iter) { + m_PrintEntries.push_back(iter->second); + iter->second.Reset(); + } + + eastl::sort(m_PrintEntries.begin(), m_PrintEntries.end()); + + for (QT3DSU32 idx = 0, end = (QT3DSU32)m_PrintEntries.size(); idx < end; ++idx) { + m_PrintEntries[idx].Output(m_Foundation, inFramesPassed); + } + } + + void ResetTimerData() override + { + Mutex::ScopedLock __locker(m_Mutex); + for (THashMapType::iterator iter = m_Entries.begin(), end = m_Entries.end(); iter != end; + ++iter) { + iter->second.Reset(); + } + } + + virtual void ClearPerfKeys() + { + Mutex::ScopedLock __locker(m_Mutex); + m_Entries.clear(); + } +}; +} + +IPerfTimer &IPerfTimer::CreatePerfTimer(NVFoundationBase &fnd) +{ + return *QT3DS_NEW(fnd.getAllocator(), SPerfTimer)(fnd); +} diff --git a/src/Runtime/Source/foundation/Qt3DSPerfTimer.h b/src/Runtime/Source/foundation/Qt3DSPerfTimer.h new file mode 100644 index 00000000..c63091c0 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSPerfTimer.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PERFTIMER_H +#define QT3DS_FOUNDATION_PERFTIMER_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSTime.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace foundation { + + class IPerfTimer : public NVRefCounted + { + protected: + virtual ~IPerfTimer() {} + public: + // amount is in counter frequency units + virtual void Update(const char *inTag, QT3DSU64 inAmount) = 0; + // Dump current summation of timer data. + virtual void OutputTimerData(QT3DSU32 inFrameCount = 0) = 0; + virtual void ResetTimerData() = 0; + + static IPerfTimer &CreatePerfTimer(NVFoundationBase &inFoundation); + }; + + // Specialize this struct to get the perf timer in different contexts. + template + struct STimerProvider + { + static IPerfTimer &getPerfTimer(TTimerProvider &inProvider) + { + return inProvider.getPerfTimer(); + } + }; + + template + IPerfTimer &getPerfTimer(TTimerProvider &inProvider) + { + return STimerProvider::getPerfTimer(inProvider); + } + + struct SStackPerfTimer + { + IPerfTimer *m_Timer; + QT3DSU64 m_Start; + const char *m_Id; + + SStackPerfTimer(IPerfTimer &destination, const char *inId) + : m_Timer(&destination) + , m_Start(Time::getCurrentCounterValue()) + , m_Id(inId) + { + } + + SStackPerfTimer(IPerfTimer *destination, const char *inId) + : m_Timer(destination) + , m_Start(Time::getCurrentCounterValue()) + , m_Id(inId) + { + } + + ~SStackPerfTimer() + { + if (m_Timer) { + QT3DSU64 theStop = Time::getCurrentCounterValue(); + QT3DSU64 theAmount = theStop - m_Start; + m_Timer->Update(m_Id, theAmount); + } + } + }; +} +} + +#define QT3DS_FOUNDATION_PERF_SCOPED_TIMER(context, name) \ + SStackPerfTimer __perfTimer(getPerfTimer(context), #name); + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSPlane.h b/src/Runtime/Source/foundation/Qt3DSPlane.h new file mode 100644 index 00000000..378c3bc9 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSPlane.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_PLANE_H +#define QT3DS_FOUNDATION_QT3DS_PLANE_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSMath.h" +#include "foundation/Qt3DSVec3.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/** +\brief Representation of a plane. + + Plane equation used: n.dot(v) + d = 0 +*/ +class NVPlane +{ +public: + /** + \brief Constructor + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane() {} + + /** + \brief Constructor from a normal and a distance + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(NVReal nx, NVReal ny, NVReal nz, NVReal distance) + : n(nx, ny, nz) + , d(distance) + { + } + + /** + \brief Constructor from a normal and a distance + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(const QT3DSVec3 &normal, NVReal distance) + : n(normal) + , d(distance) + { + } + + /** + \brief Constructor from a point on the plane and a normal + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(const QT3DSVec3 &point, const QT3DSVec3 &normal) + : n(normal) + , d(-point.dot(n)) // p satisfies normal.dot(p) + d = 0 + { + } + + /** + \brief Constructor from three points + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane(const QT3DSVec3 &p0, const QT3DSVec3 &p1, const QT3DSVec3 &p2) + { + n = (p1 - p0).cross(p2 - p0).getNormalized(); + d = -p0.dot(n); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal distance(const QT3DSVec3 &p) const { return p.dot(n) + d; } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool contains(const QT3DSVec3 &p) const + { + return NVAbs(distance(p)) < (1.0e-7f); + } + + /** + \brief projects p into the plane + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 project(const QT3DSVec3 &p) const + { + return p - n * distance(p); + } + + /** + \brief find an arbitrary point in the plane + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 pointInPlane() const { return -n * d; } + + /** + \brief equivalent plane with unit normal + */ + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void normalize() + { + NVReal denom = 1.0f / n.magnitude(); + n *= denom; + d *= denom; + } + + QT3DSVec3 n; //!< The normal to the plane + NVReal d; //!< The distance from the origin +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSPool.h b/src/Runtime/Source/foundation/Qt3DSPool.h new file mode 100644 index 00000000..5bd07f86 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSPool.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_POOL_H +#define QT3DS_POOL_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSMath.h" //NVMax +#include "EASTL/vector.h" + +namespace qt3ds { +namespace foundation { + // Pool of fixed size objects. + template + class Pool + { + protected: + TAllocator mAllocator; + struct Link + { + Link *mNext; + Link(Link *next = NULL) + : mNext(next) + { + } + }; + eastl::vector mSlabs; + Link *mFreeList; + + public: + Pool(const TAllocator &alloc = TAllocator()) + : mAllocator(alloc) + , mSlabs(alloc) + , mFreeList(NULL) + { + StaticAssert::valid_expression(); + } + ~Pool() + { + for (QT3DSU32 idx = 0, end = mSlabs.size(); idx < end; ++idx) + mAllocator.deallocate(mSlabs[idx], slabSize); + mSlabs.clear(); + mFreeList = NULL; + } + void appendToFreeList(Link *inLink) + { + inLink->mNext = mFreeList; + mFreeList = inLink; + } + void appendSlabToFreeList(void *slab) + { + QT3DSU8 *newMem = reinterpret_cast(slab); + QT3DSU32 objSize = (QT3DSU32)qt3ds::NVMax(sizeof(TObjType), sizeof(Link)); + // align the memory correctly + if (objSize % alignmentInBytes) + objSize += alignmentInBytes - (objSize % alignmentInBytes); + + QT3DSU32 numObjsInSlab = slabSize / objSize; + for (QT3DSU32 idx = 0; idx < numObjsInSlab; ++idx) { + QT3DSU8 *objPtr = newMem + idx * objSize; + appendToFreeList(reinterpret_cast(objPtr)); + } + } + void allocateSlab(const char *file, int line) + { + QT3DSU32 objSize = (QT3DSU32)NVMax(sizeof(TObjType), sizeof(Link)); + // align the memory correctly + if (objSize % alignmentInBytes) + objSize += alignmentInBytes - (objSize % alignmentInBytes); + + QT3DSU8 *newMem = (QT3DSU8 *)mAllocator.allocate(slabSize, file, line); + if (newMem == NULL) + return; // out of mem, bad error + mSlabs.push_back(newMem); + appendSlabToFreeList(newMem); + } + + void *allocate(const char *file, int line) + { + if (!mFreeList) + allocateSlab(file, line); + + if (mFreeList) { + Link *retval = mFreeList; + mFreeList = retval->mNext; + return retval; + } + + return NULL; + } + + void deallocate(void *inPtr) + { +#if _DEBUG + // Ensure inPtr came from a known slab. + bool found = false; + for (QT3DSU32 idx = 0, end = mSlabs.size(); idx < end && !found; ++idx) { + QT3DSU8 *slabMem = reinterpret_cast(mSlabs[idx]); + QT3DSU8 *slabEnd = slabMem + slabSize; + QT3DSU8 *memPtr = reinterpret_cast(inPtr); + + if (memPtr >= mSlabs[idx] && memPtr < slabEnd) + found = true; + } + QT3DS_ASSERT(found); +#endif + appendToFreeList(reinterpret_cast(inPtr)); + } + + template + TObjType *construct(const TArg1 &arg1, const TArg2 &arg2, const char *file, int line) + { + TObjType *newMem = (TObjType *)allocate(file, line); + return new (newMem) TObjType(arg1, arg2); + } + + template + TObjType *construct(const TArg1 &arg1, const char *file, int line) + { + TObjType *newMem = (TObjType *)allocate(file, line); + return new (newMem) TObjType(arg1); + } + + TObjType *construct(const char *file, int line) + { + TObjType *newMem = (TObjType *)allocate(file, line); + return new (newMem) TObjType(); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSPreprocessor.h b/src/Runtime/Source/foundation/Qt3DSPreprocessor.h new file mode 100644 index 00000000..371d3e67 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSPreprocessor.h @@ -0,0 +1,375 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_PREPROCESSOR_H +#define QT3DS_FOUNDATION_QT3DS_PREPROCESSOR_H + +#include +/** \addtogroup foundation + @{ +*/ + +/** +List of preprocessor defines used to configure the SDK +- NDEBUG/_DEBUG: enable asserts (exactly one needs to be defined) +- QT3DS_CHECKED: enable run time checks, mostly unused or equiv. to _DEBUG +- QT3DS_SUPPORT_VISUAL_DEBUGGER: ... +- AG_PERFMON: ... +*/ + +/** +Compiler define +*/ +#ifdef _MSC_VER +#define QT3DS_VC +#if _MSC_VER >= 1600 +#define QT3DS_VC10 +#elif _MSC_VER >= 1500 +#define QT3DS_VC9 +#elif _MSC_VER >= 1400 +#define QT3DS_VC8 +#elif _MSC_VER >= 1300 +#define QT3DS_VC7 +#else +#define QT3DS_VC6 +#endif +#elif __GNUC__ || __SNC__ +#define QT3DS_GNUC +#elif defined(__MWERKS__) +#define QT3DS_CW +#elif defined(__ghs__) +#define QT3DS_GHS +#else +#error "Unknown compiler" +#endif + +/** +Platform define +*/ +#ifdef QT3DS_VC +#ifdef _M_IX86 +#define QT3DS_X86 +#define QT3DS_WINDOWS +#elif defined(_M_X64) +#define QT3DS_X64 +#define QT3DS_WINDOWS +#elif defined(_M_PPC) +#define QT3DS_PPC +#define QT3DS_X360 +#define QT3DS_VMX +#elif defined(_M_ARM) +#define QT3DS_ARM +#define QT3DS_WIN8ARM +#define QT3DS_ARM_NEON +#else +#error "Unknown platform" +#endif +#elif defined QT3DS_GNUC +#ifdef __CELLOS_LV2__ +#define QT3DS_PS3 +#define QT3DS_VMX +#elif defined(__arm__) +#define QT3DS_ARM +#if defined(__SNC__) +#define QT3DS_PSP2 +#endif +#if defined(__ARM_PCS_VFP) +#define QT3DS_ARM_HARDFP +#else +#define QT3DS_ARM_SOFTFP +#endif +#elif defined(__aarch64__) +#define QT3DS_ARM +#elif defined(__i386__) +#define QT3DS_X86 +#define QT3DS_VMX +#elif defined(__x86_64__) +#define QT3DS_X64 +#elif defined(__ppc__) +#define QT3DS_PPC +#elif defined(__ppc64__) +#define QT3DS_PPC +#define QT3DS_PPC64 +//# elif defined(__aarch64__) +//# define QT3DS_ARM_64 +#else +#error "Unknown platform" +#endif +#if defined(ANDROID) +#define QT3DS_ANDROID +#elif defined(__linux__) +#define QT3DS_LINUX +#elif defined(__APPLE__) +#define QT3DS_APPLE +#if defined(__arm__) +#define QT3DS_APPLE_IOS +#endif +#elif defined(__CYGWIN__) +#define QT3DS_CYGWIN +#define QT3DS_LINUX +#elif defined(__QNX__) +#define QT3DS_QNX +#elif defined(_WIN32) +#define QT3DS_WINDOWS +#else +#error "Unkown OS" +#endif +#elif defined QT3DS_CW +#if defined(__PPCGEKKO__) +#if defined(RVL) +#define QT3DS_WII +#else +#define QT3DS_GC +#endif +#else +#error "Unknown platform" +#endif +#elif defined QT3DS_GHS +#define QT3DS_LINUX // INTEGRITY deviations flagged with __INTEGRITY +#if defined(__arm__) || defined(__aarch64__) || defined(__ARM64__) +#define QT3DS_ARM +#endif +#endif + +/** +DLL export macros +*/ +#ifndef QT3DS_C_EXPORT +#define QT3DS_C_EXPORT extern "C" +#endif + +/** +Define API function declaration + +QT3DS_FOUNDATION_EXPORTS - used by the DLL library (PhysXCommon) to export the API +QT3DS_FOUNDATION_NO_EXPORTS - exists because there are windows configurations where + the QT3DS_FOUNDATION_API is linked through standard +static linking +no definition - this will allow DLLs and libraries to use the exported API from PhysXCommon + +*/ +#if defined(QT3DS_WINDOWS) && !defined(__CUDACC__) +#if defined QT3DS_FOUNDATION_EXPORTS +#define QT3DS_FOUNDATION_API __declspec(dllexport) +#elif defined QT3DS_FOUNDATION_NO_EXPORTS +#define QT3DS_FOUNDATION_API +#else +#define QT3DS_FOUNDATION_API __declspec(dllimport) +#endif +#else +#define QT3DS_FOUNDATION_API +#endif + + +#if defined(QT3DS_AUTOTESTS_ENABLED) +#include +#if defined(QT3DS_BUILDING_LIBRARY) +#define QT3DS_AUTOTEST_EXPORT Q_DECL_EXPORT +#else +#define QT3DS_AUTOTEST_EXPORT Q_DECL_IMPORT +#endif +#else +#define QT3DS_AUTOTEST_EXPORT +#endif + +/** +Calling convention +*/ +#ifndef QT3DS_CALL_CONV +#if defined QT3DS_WINDOWS +#define QT3DS_CALL_CONV __cdecl +#else +#define QT3DS_CALL_CONV +#endif +#endif + +/** +Pack macros - disabled on SPU because they are not supported +*/ +#if defined(QT3DS_VC) +#define QT3DS_PUSH_PACK_DEFAULT __pragma(pack(push, 8)) +#define QT3DS_POP_PACK __pragma(pack(pop)) +#elif defined(QT3DS_GNUC) && !defined(__SPU__) +#define QT3DS_PUSH_PACK_DEFAULT _Pragma("pack(push, 8)") +#define QT3DS_POP_PACK _Pragma("pack(pop)") +#else +#define QT3DS_PUSH_PACK_DEFAULT +#define QT3DS_POP_PACK +#endif + +/** +Inline macro +*/ +#if defined(QT3DS_WINDOWS) || defined(QT3DS_X360) +#define QT3DS_INLINE inline +#ifdef QT3DS_VC +#pragma inline_depth(255) +#endif +#else +#define QT3DS_INLINE inline +#endif + +/** +Force inline macro +*/ +#if defined(QT3DS_VC) +#define QT3DS_FORCE_INLINE __forceinline +#elif defined(QT3DS_LINUX) \ + || defined(QT3DS_QNX) // Workaround; Fedora Core 3 do not agree with force inline and NVcPool +#define QT3DS_FORCE_INLINE inline +#elif defined(QT3DS_GNUC) +#define QT3DS_FORCE_INLINE inline __attribute__((always_inline)) +#else +#define QT3DS_FORCE_INLINE inline +#endif + +/** +Noinline macro +*/ +#if defined QT3DS_WINDOWS +#define QT3DS_NOINLINE __declspec(noinline) +#elif defined(QT3DS_GNUC) +#define QT3DS_NOINLINE __attribute__((noinline)) +#else +#define QT3DS_NOINLINE +#endif + +/*! restrict macro */ +#if __CUDACC__ +#define QT3DS_RESTRICT __restrict__ +#elif defined(QT3DS_GNUC) || defined(QT3DS_VC) +#define QT3DS_RESTRICT __restrict +#elif defined(QT3DS_CW) && __STDC_VERSION__ >= 199901L +#define QT3DS_RESTRICT restrict +#else +#define QT3DS_RESTRICT +#endif + +#if defined(QT3DS_WINDOWS) || defined(QT3DS_X360) +#define QT3DS_NOALIAS __declspec(noalias) +#else +#define QT3DS_NOALIAS +#endif + +/** +Alignment macros + +QT3DS_ALIGN_PREFIX and QT3DS_ALIGN_SUFFIX can be used for type alignment instead of aligning individual +variables as follows: +QT3DS_ALIGN_PREFIX(16) +struct A { +... +} QT3DS_ALIGN_SUFFIX(16); +This declaration style is parsed correctly by Visual Assist. + +*/ +#ifndef QT3DS_ALIGN +#if defined(QT3DS_VC) +#define QT3DS_ALIGN(alignment, decl) __declspec(align(alignment)) decl +#define QT3DS_ALIGN_PREFIX(alignment) __declspec(align(alignment)) +#define QT3DS_ALIGN_SUFFIX(alignment) +#elif defined(QT3DS_GNUC) +#define QT3DS_ALIGN(alignment, decl) decl __attribute__((aligned(alignment))) +#define QT3DS_ALIGN_PREFIX(alignment) +#define QT3DS_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment))) +#elif defined(QT3DS_CW) +#define QT3DS_ALIGN(alignment, decl) decl __attribute__((aligned(alignment))) +#define QT3DS_ALIGN_PREFIX(alignment) +#define QT3DS_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment))) +#else +#define QT3DS_ALIGN(alignment, decl) +#define QT3DS_ALIGN_PREFIX(alignment) +#define QT3DS_ALIGN_SUFFIX(alignment) +#endif +#endif + +/** +Deprecated marco +*/ +#if 0 // set to 1 to create warnings for deprecated functions +#define QT3DS_DEPRECATED __declspec(deprecated) +#else +#define QT3DS_DEPRECATED +#endif + +// VC6 no '__FUNCTION__' workaround +#if defined QT3DS_VC6 && !defined __FUNCTION__ +#define __FUNCTION__ "Undefined" +#endif + +/** +General defines +*/ + +// Assertion type +template +struct StaticAssert +{ +}; +// Specialisation with member function +template <> +struct StaticAssert +{ +public: + static void valid_expression(){} +}; + +// static assert +#define QT3DS_COMPILE_TIME_ASSERT(exp) typedef char NVCompileTimeAssert_Dummy[(exp) ? 1 : -1] + +#ifdef QT3DS_GNUC +#define QT3DS_OFFSET_OF(X, Y) __builtin_offsetof(X, Y) +#else +#define QT3DS_OFFSET_OF(X, Y) offsetof(X, Y) +#endif + +// avoid unreferenced parameter warning (why not just disable it?) +// PT: or why not just omit the parameter's name from the declaration???? +#define QT3DS_FORCE_PARAMETER_REFERENCE(_P) (void)(_P); +#define QT3DS_UNUSED(_P) QT3DS_FORCE_PARAMETER_REFERENCE(_P) + +// check that exactly one of NDEBUG and _DEBUG is defined +#if !(defined NDEBUG ^ defined _DEBUG) +#error Exactly one of NDEBUG and _DEBUG needs to be defined by preprocessor +#endif + +// make sure QT3DS_CHECKED is defined in all _DEBUG configurations as well +#if !defined(QT3DS_CHECKED) && _DEBUG +#define QT3DS_CHECKED +#endif + +#ifdef __CUDACC__ +#define QT3DS_CUDA_CALLABLE __host__ __device__ +#else +#define QT3DS_CUDA_CALLABLE +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_PREPROCESSOR_H diff --git a/src/Runtime/Source/foundation/Qt3DSQuat.h b/src/Runtime/Source/foundation/Qt3DSQuat.h new file mode 100644 index 00000000..2792f977 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSQuat.h @@ -0,0 +1,381 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_QUAT_H +#define QT3DS_FOUNDATION_QT3DS_QUAT_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSVec3.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/** +\brief This is a quaternion class. For more information on quaternion mathematics +consult a mathematics source on complex numbers. + +*/ + +class QT3DSQuat +{ +public: + /** + \brief Default constructor, does not do any initialization. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat() {} + + /** + \brief Constructor. Take note of the order of the elements! + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat(NVReal nx, NVReal ny, NVReal nz, NVReal nw) + : x(nx) + , y(ny) + , z(nz) + , w(nw) + { + } + + /** + \brief Creates from angle-axis representation. + + Axis must be normalized! + + Angle is in radians! + + Unit: Radians + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat(NVReal angleRadians, const QT3DSVec3 &unitAxis) + { + QT3DS_ASSERT(NVAbs(1.0f - unitAxis.magnitude()) < 1e-3f); + const NVReal a = angleRadians * 0.5f; + const NVReal s = NVSin(a); + w = NVCos(a); + x = unitAxis.x * s; + y = unitAxis.y * s; + z = unitAxis.z * s; + } + + /** + \brief Copy ctor. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat(const QT3DSQuat &v) + : x(v.x) + , y(v.y) + , z(v.z) + , w(v.w) + { + } + + /** + \brief Creates from orientation matrix. + + \param[in] m Rotation matrix to extract quaternion from. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE explicit QT3DSQuat(const QT3DSMat33 &m); /* defined in Qt3DSMat33.h */ + + /** + \brief returns true if all elements are finite (not NAN or INF, etc.) + */ + QT3DS_CUDA_CALLABLE bool isFinite() const + { + return NVIsFinite(x) && NVIsFinite(y) && NVIsFinite(z) && NVIsFinite(w); + } + + /** + \brief returns true if finite and magnitude is close to unit + */ + + QT3DS_CUDA_CALLABLE bool isUnit() const + { + const NVReal unitTolerance = NVReal(1e-4); + return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; + } + + /** + \brief returns true if finite and magnitude is reasonably close to unit to allow for some + accumulation of error vs isValid + */ + + QT3DS_CUDA_CALLABLE bool isSane() const + { + const NVReal unitTolerance = NVReal(1e-2); + return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; + } + + /** + \brief converts this quaternion to angle-axis representation + */ + + QT3DS_CUDA_CALLABLE QT3DS_INLINE void toRadiansAndUnitAxis(NVReal &angle, QT3DSVec3 &axis) const + { + const NVReal quatEpsilon = (NVReal(1.0e-8f)); + const NVReal s2 = x * x + y * y + z * z; + if (s2 < quatEpsilon * quatEpsilon) // can't extract a sensible axis + { + angle = 0; + axis = QT3DSVec3(1, 0, 0); + } else { + const NVReal s = NVRecipSqrt(s2); + axis = QT3DSVec3(x, y, z) * s; + angle = w < quatEpsilon ? NVPi : NVAtan2(s2 * s, w) * 2; + } + } + + /** + \brief Gets the angle between this quat and the identity quaternion. + + Unit: Radians + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal getAngle() const { return NVAcos(w) * NVReal(2); } + + /** + \brief Gets the angle between this quat and the argument + + Unit: Radians + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal getAngle(const QT3DSQuat &q) const + { + return NVAcos(dot(q)) * NVReal(2); + } + + /** + \brief This is the squared 4D vector length, should be 1 for unit quaternions. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitudeSquared() const + { + return x * x + y * y + z * z + w * w; + } + + /** + \brief returns the scalar product of this and other. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal dot(const QT3DSQuat &v) const + { + return x * v.x + y * v.y + z * v.z + w * v.w; + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat getNormalized() const + { + const NVReal s = 1.0f / magnitude(); + return QT3DSQuat(x * s, y * s, z * s, w * s); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE float magnitude() const { return NVSqrt(magnitudeSquared()); } + + // modifiers: + /** + \brief maps to the closest unit quaternion. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal normalize() // convert this QT3DSQuat to a unit quaternion + { + const NVReal mag = magnitude(); + if (mag) { + const NVReal imag = NVReal(1) / mag; + + x *= imag; + y *= imag; + z *= imag; + w *= imag; + } + return mag; + } + + /* + \brief returns the conjugate. + + \note for unit quaternions, this is the inverse. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat getConjugate() const { return QT3DSQuat(-x, -y, -z, w); } + + /* + \brief returns imaginary part. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getImaginaryPart() const { return QT3DSVec3(x, y, z); } + + /** brief computes rotation of x-axis */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getBasisVector0() const + { + // return rotate(QT3DSVec3(1,0,0)); + const QT3DSF32 x2 = x * 2.0f; + const QT3DSF32 w2 = w * 2.0f; + return QT3DSVec3((w * w2) - 1.0f + x * x2, (z * w2) + y * x2, (-y * w2) + z * x2); + } + + /** brief computes rotation of y-axis */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getBasisVector1() const + { + // return rotate(QT3DSVec3(0,1,0)); + const QT3DSF32 y2 = y * 2.0f; + const QT3DSF32 w2 = w * 2.0f; + return QT3DSVec3((-z * w2) + x * y2, (w * w2) - 1.0f + y * y2, (x * w2) + z * y2); + } + + /** brief computes rotation of z-axis */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getBasisVector2() const + { + // return rotate(QT3DSVec3(0,0,1)); + const QT3DSF32 z2 = z * 2.0f; + const QT3DSF32 w2 = w * 2.0f; + return QT3DSVec3((y * w2) + x * z2, (-x * w2) + y * z2, (w * w2) - 1.0f + z * z2); + } + + /** + rotates passed vec by this (assumed unitary) + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec3 rotate(const QT3DSVec3 &v) const + // QT3DS_CUDA_CALLABLE QT3DS_INLINE const QT3DSVec3 rotate(const QT3DSVec3& v) const + { + const QT3DSF32 vx = 2.0f * v.x; + const QT3DSF32 vy = 2.0f * v.y; + const QT3DSF32 vz = 2.0f * v.z; + const QT3DSF32 w2 = w * w - 0.5f; + const QT3DSF32 dot2 = (x * vx + y * vy + z * vz); + return QT3DSVec3((vx * w2 + (y * vz - z * vy) * w + x * dot2), + (vy * w2 + (z * vx - x * vz) * w + y * dot2), + (vz * w2 + (x * vy - y * vx) * w + z * dot2)); + /* + const QT3DSVec3 qv(x,y,z); + return (v*(w*w-0.5f) + (qv.cross(v))*w + qv*(qv.dot(v)))*2; + */ + } + + /** + inverse rotates passed vec by this (assumed unitary) + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const QT3DSVec3 rotateInv(const QT3DSVec3 &v) const + // QT3DS_CUDA_CALLABLE QT3DS_INLINE const QT3DSVec3 rotateInv(const QT3DSVec3& v) const + { + const QT3DSF32 vx = 2.0f * v.x; + const QT3DSF32 vy = 2.0f * v.y; + const QT3DSF32 vz = 2.0f * v.z; + const QT3DSF32 w2 = w * w - 0.5f; + const QT3DSF32 dot2 = (x * vx + y * vy + z * vz); + return QT3DSVec3((vx * w2 - (y * vz - z * vy) * w + x * dot2), + (vy * w2 - (z * vx - x * vz) * w + y * dot2), + (vz * w2 - (x * vy - y * vx) * w + z * dot2)); + // const QT3DSVec3 qv(x,y,z); + // return (v*(w*w-0.5f) - (qv.cross(v))*w + qv*(qv.dot(v)))*2; + } + + /** + \brief Assignment operator + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator=(const QT3DSQuat &p) + { + x = p.x; + y = p.y; + z = p.z; + w = p.w; + return *this; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator*=(const QT3DSQuat &q) + { + const NVReal tx = w * q.x + q.w * x + y * q.z - q.y * z; + const NVReal ty = w * q.y + q.w * y + z * q.x - q.z * x; + const NVReal tz = w * q.z + q.w * z + x * q.y - q.x * y; + + w = w * q.w - q.x * x - y * q.y - q.z * z; + x = tx; + y = ty; + z = tz; + + return *this; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator+=(const QT3DSQuat &q) + { + x += q.x; + y += q.y; + z += q.z; + w += q.w; + return *this; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator-=(const QT3DSQuat &q) + { + x -= q.x; + y -= q.y; + z -= q.z; + w -= q.w; + return *this; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat &operator*=(const NVReal s) + { + x *= s; + y *= s; + z *= s; + w *= s; + return *this; + } + + /** quaternion multiplication */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat operator*(const QT3DSQuat &q) const + { + return QT3DSQuat(w * q.x + q.w * x + y * q.z - q.y * z, w * q.y + q.w * y + z * q.x - q.z * x, + w * q.z + q.w * z + x * q.y - q.x * y, w * q.w - x * q.x - y * q.y - z * q.z); + } + + /** quaternion addition */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator+(const QT3DSQuat &q) const + { + return QT3DSQuat(x + q.x, y + q.y, z + q.z, w + q.w); + } + + /** quaternion subtraction */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator-() const { return QT3DSQuat(-x, -y, -z, -w); } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator-(const QT3DSQuat &q) const + { + return QT3DSQuat(x - q.x, y - q.y, z - q.z, w - q.w); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSQuat operator*(NVReal r) const + { + return QT3DSQuat(x * r, y * r, z * r, w * r); + } + + static QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSQuat createIdentity() { return QT3DSQuat(0, 0, 0, 1); } + + /** the quaternion elements */ + NVReal x, y, z, w; +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_QUAT_H diff --git a/src/Runtime/Source/foundation/Qt3DSRefCounted.h b/src/Runtime/Source/foundation/Qt3DSRefCounted.h new file mode 100644 index 00000000..b500b5fc --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSRefCounted.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_REFCOUNTED_H +#define QT3DS_FOUNDATION_QT3DS_REFCOUNTED_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSNoCopy.h" + +namespace qt3ds { +namespace foundation { + /** + Marker class for objects that have a release method that is expected + to destroy or release the object. + */ + class NVReleasable + { + protected: + virtual ~NVReleasable() {} + public: + virtual void release() = 0; + }; + + template + inline void NVSafeRelease(TObjType *&item) + { + if (item) { + item->release(); + item = NULL; + } + } + + /**Scoped pointer that releases its data + when it is being destroyed*/ + template + struct NVScopedReleasable : public NoCopy + { + TObjType *mPtr; + NVScopedReleasable() + : mPtr(NULL) + { + } + NVScopedReleasable(TObjType *item) + : mPtr(item) + { + } + NVScopedReleasable(TObjType &item) + : mPtr(&item) + { + } + ~NVScopedReleasable() { NVSafeRelease(mPtr); } + + NVScopedReleasable &operator=(TObjType *inItem) + { + if (inItem != mPtr) { + if (mPtr) + mPtr->release(); + mPtr = inItem; + } + return *this; + } + + NVScopedReleasable &operator=(const NVScopedReleasable inItem) + { + QT3DS_ASSERT(false); + // try to do the right thing. + mPtr = inItem.mPtr; + const_cast &>(inItem).mPtr = NULL; + return *this; + } + + TObjType *forget_unsafe() + { + mPtr = NULL; + return mPtr; + } + + TObjType *operator->() { return mPtr; } + const TObjType *operator->() const { return mPtr; } + TObjType &operator*() { return *mPtr; } + const TObjType &operator*() const { return *mPtr; } + operator TObjType *() { return mPtr; } + operator const TObjType *() const { return mPtr; } + }; + + // Marker class for objects that are ref counted. + class NVRefCounted : public NVReleasable + { + public: + virtual void addRef() = 0; + }; + +/**Helpers to make implementing ref counted objects as concise as possible*/ +#define QT3DS_IMPLEMENT_REF_COUNT_RELEASE(alloc) \ + QT3DSI32 value = atomicDecrement(&mRefCount); \ + if (value <= 0) \ + NVDelete(alloc, this); + +#define QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(alloc) \ + void addRef() { atomicIncrement(&mRefCount); } \ + void release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(alloc); } + + +#define QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(alloc) \ + void addRef() override { atomicIncrement(&mRefCount); } \ + void release() override { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(alloc); } + + /**Safe function that checks for null before addrefing the object*/ + template + inline TObjType *NVSafeAddRef(TObjType *item) + { + if (item) { + item->addRef(); + } + return item; + } + + /**Scoped pointer that addref's its data upon acquisition and releases its data + when it is being destroyed*/ + template + struct NVScopedRefCounted + { + TObjType *mPtr; + ~NVScopedRefCounted() { NVSafeRelease(mPtr); } + NVScopedRefCounted(TObjType *item = NULL) + : mPtr(item) + { + NVSafeAddRef(mPtr); + } + NVScopedRefCounted(TObjType &item) + : mPtr(&item) + { + NVSafeAddRef(mPtr); + } + NVScopedRefCounted(const NVScopedRefCounted &other) + : mPtr(const_cast(other.mPtr)) + { + NVSafeAddRef(mPtr); + } + NVScopedRefCounted &operator=(const NVScopedRefCounted &other) + { + if (other.mPtr != mPtr) { + NVSafeRelease(mPtr); + mPtr = const_cast(other.mPtr); + NVSafeAddRef(mPtr); + } + return *this; + } + TObjType *forget_unsafe() + { + mPtr = NULL; + return mPtr; + } + + TObjType *operator->() { return mPtr; } + const TObjType *operator->() const { return mPtr; } + TObjType &operator*() { return *mPtr; } + const TObjType &operator*() const { return *mPtr; } + operator TObjType *() { return mPtr; } + operator const TObjType *() const { return mPtr; } + bool operator==(NVScopedRefCounted &inOther) const + { + return mPtr == inOther.mPtr; + } + bool operator!=(NVScopedRefCounted &inOther) const + { + return mPtr != inOther.mPtr; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSSemaphore.h b/src/Runtime/Source/foundation/Qt3DSSemaphore.h new file mode 100644 index 00000000..f58bb6e0 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSSemaphore.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSSEMAPHORE_H +#define QT3DS_FOUNDATION_PSSEMAPHORE_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAllocatorCallback.h" + +namespace qt3ds { +namespace foundation { + class QT3DS_FOUNDATION_API Semaphore + { + public: + static const QT3DSU32 waitForever = 0xffffffff; + + Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount); + + ~Semaphore(); + + /**Decrements (locks) the semaphore. If the semaphore's value is greater than zero, + * then the decrement proceeds, and the function returns, immediately. Otherwise + * Wait for at most the given number of ms. Returns true if the Semaphore is signaled. + * Semaphore::waitForever will block forever or until the semaphore is signaled. + */ + + bool wait(QT3DSU32 milliseconds = waitForever); + + /** increments (unlocks) the semaphore */ + + void post(); + + private: + class SemaphoreImpl *mImpl; + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSSimpleTypes.h b/src/Runtime/Source/foundation/Qt3DSSimpleTypes.h new file mode 100644 index 00000000..d73be064 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSSimpleTypes.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_QT3DS_SIMPLE_TYPES_H +#define QT3DS_FOUNDATION_QT3DS_SIMPLE_TYPES_H + +/** \addtogroup foundation + @{ +*/ + +// Platform specific types: +// Design note: Its OK to use int for general loop variables and temps. + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSPreprocessor.h" +#include "EABase/eabase.h" +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif //#ifndef QT3DS_DOXYGEN + +typedef uint8_t QT3DSU8; +typedef int8_t QT3DSI8; +typedef uint16_t QT3DSU16; +typedef int16_t QT3DSI16; +typedef uint32_t QT3DSU32; +typedef int32_t QT3DSI32; +typedef uint64_t QT3DSU64; +typedef int64_t QT3DSI64; +typedef float QT3DSF32; +typedef double QT3DSF64; +typedef QT3DSI32 IntBool; + +struct QT3DSF16 +{ + QT3DSU16 mData; +}; + +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI8) == 1); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU8) == 1); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI16) == 2); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU16) == 2); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI32) == 4); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU32) == 4); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSI64) == 8); +QT3DS_COMPILE_TIME_ASSERT(sizeof(QT3DSU64) == 8); + +// Type ranges +#define QT3DS_MAX_I8 127 // maximum possible sbyte value, 0x7f +#define QT3DS_MIN_I8 (-128) // minimum possible sbyte value, 0x80 +#define QT3DS_MAX_U8 255U // maximum possible ubyte value, 0xff +#define QT3DS_MIN_U8 0 // minimum possible ubyte value, 0x00 +#define QT3DS_MAX_I16 32767 // maximum possible sword value, 0x7fff +#define QT3DS_MIN_I16 (-32768) // minimum possible sword value, 0x8000 +#define QT3DS_MAX_U16 65535U // maximum possible uword value, 0xffff +#define QT3DS_MIN_U16 0 // minimum possible uword value, 0x0000 +#define QT3DS_MAX_I32 2147483647 // maximum possible sdword value, 0x7fffffff +#define QT3DS_MIN_I32 (-2147483647 - 1) // minimum possible sdword value, 0x80000000 +#define QT3DS_MAX_U32 4294967295U // maximum possible udword value, 0xffffffff +#define QT3DS_MIN_U32 0 // minimum possible udword value, 0x00000000 +#define QT3DS_MAX_F32 3.4028234663852885981170418348452e+38F +// maximum possible float value +#define QT3DS_MAX_F64 DBL_MAX // maximum possible double value + +#define QT3DS_ENV_F32 FLT_EPSILON // maximum relative error of float rounding +#define QT3DS_ENV_F64 DBL_EPSILON // maximum relative error of double rounding + +#ifndef QT3DS_FOUNDATION_USE_F64 + +typedef QT3DSF32 NVReal; + +#define QT3DS_MAX_REAL QT3DS_MAX_F32 +#define QT3DS_ENV_REAL QT3DS_ENV_F32 +#define QT3DS_NORMALIZATION_EPSILON NVReal(1e-20f) + +#else + +typedef QT3DSF64 NVReal; + +#define QT3DS_MAX_REAL QT3DS_MAX_F64 +#define QT3DS_ENV_REAL QT3DS_ENV_F64 +#define QT3DS_NORMALIZATION_EPSILON NVReal(1e-180) + +#endif + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_SIMPLE_TYPES_H diff --git a/src/Runtime/Source/foundation/Qt3DSStringTokenizer.h b/src/Runtime/Source/foundation/Qt3DSStringTokenizer.h new file mode 100644 index 00000000..5229babd --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSStringTokenizer.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_STRING_TOKENIZER_H +#define QT3DS_FOUNDATION_STRING_TOKENIZER_H + +#include "EASTL/string.h" + +namespace qt3ds { +namespace foundation { + + template + class QT3DS_FOUNDATION_API StringTokenizer + { + typedef typename eastl::basic_string::size_type size_t; + + public: + StringTokenizer(const eastl::basic_string &inString, + const eastl::basic_string &inToken) + { + eastl::basic_string mStr = inString; + eastl::basic_string theTempString = inString.substr(0, inToken.length()); + + while (inToken.length() && theTempString.compare(inToken) == 0) { + mStr = mStr.substr(inToken.length()); + theTempString = mStr.substr(0, inToken.length()); + } + + theTempString = mStr.substr(mStr.length() - 1 - inToken.length()); + while (theTempString.compare(inToken) == 0) { + mStr = mStr.substr(0, mStr.length() - inToken.length()); + theTempString = mStr.substr(mStr.length() - 1 - inToken.length()); + } + + m_OriginalString = mStr; + m_Token = inToken; + m_Index = 0; + } + + eastl::basic_string GetCurrentPartition() + { + eastl::basic_string theReturnString; + if (m_Index != eastl::basic_string::npos) { + size_t theCurrentTokenIndex = m_OriginalString.find(m_Token, m_Index); + if (theCurrentTokenIndex == eastl::basic_string::npos) { + theReturnString = m_OriginalString.substr(m_Index); + } else { + theReturnString = + m_OriginalString.substr(m_Index, theCurrentTokenIndex - m_Index); + } + } + + return theReturnString; + } + + bool HasNextPartition() { return m_Index != eastl::basic_string::npos; } + + void operator++() + { + if (m_Index != eastl::basic_string::npos) { + size_t theCurrentTokenIndex = m_OriginalString.find(m_Token, m_Index); + if (theCurrentTokenIndex == eastl::basic_string::npos) { + m_Index = eastl::basic_string::npos; + } else { + m_Index = theCurrentTokenIndex + m_Token.length(); + if (m_Index > m_OriginalString.length()) + m_Index = eastl::basic_string::npos; + } + } + } + + private: + size_t m_Index; + eastl::basic_string m_Token; + eastl::basic_string m_OriginalString; + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSSync.h b/src/Runtime/Source/foundation/Qt3DSSync.h new file mode 100644 index 00000000..a36afaeb --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSSync.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSSYNC_H +#define QT3DS_FOUNDATION_PSSYNC_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAllocatorCallback.h" + +namespace qt3ds { +namespace foundation { + class QT3DS_FOUNDATION_API Sync + { + public: + static const QT3DSU32 waitForever = 0xffffffff; + + Sync(NVAllocatorCallback &alloc); + + ~Sync(); + + /** Wait on the object for at most the given number of ms. Returns + * true if the object is signaled. Sync::waitForever will block forever + * or until the object is signaled. + */ + + bool wait(QT3DSU32 milliseconds = waitForever); + + /** Signal the synchronization object, waking all threads waiting on it */ + + void set(); + + /** Reset the synchronization object */ + + void reset(); + + private: + class SyncImpl *mImpl; + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSSystem.cpp b/src/Runtime/Source/foundation/Qt3DSSystem.cpp new file mode 100644 index 00000000..e87a25ea --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSSystem.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSSystem.h" +#include "foundation/Qt3DSPreprocessor.h" +#include "EASTL/string.h" + +using namespace qt3ds; +using namespace qt3ds::foundation; + +#if defined(QT3DS_ANDROID) +const char *qt3ds::foundation::System::g_OS = "android"; +const char *qt3ds::foundation::System::g_DLLExtension = ".so"; +#elif defined(QT3DS_APPLE) +const char *qt3ds::foundation::System::g_OS = "osx"; +const char *qt3ds::foundation::System::g_DLLExtension = ".dylib"; +#elif defined(QT3DS_LINUX) +const char *qt3ds::foundation::System::g_OS = "linux"; +const char *qt3ds::foundation::System::g_DLLExtension = ".so"; +#elif defined(QT3DS_QNX) +const char *qt3ds::foundation::System::g_OS = "qnx"; +const char *qt3ds::foundation::System::g_DLLExtension = ".so"; +#elif defined(QT3DS_WINDOWS) +const char *qt3ds::foundation::System::g_OS = "windows"; +const char *qt3ds::foundation::System::g_DLLExtension = ".dll"; +#else +#error "Unknown Operating System" +#endif + +#if defined(QT3DS_X86) +const char *qt3ds::foundation::System::g_Processor = "x86"; +const char *qt3ds::foundation::System::g_BitWidth = "32"; +const char *qt3ds::foundation::System::g_FloatingPointModel = ""; +#elif defined(QT3DS_X64) +const char *qt3ds::foundation::System::g_Processor = "x64"; +const char *qt3ds::foundation::System::g_BitWidth = "64"; +const char *qt3ds::foundation::System::g_FloatingPointModel = ""; +#elif defined(QT3DS_ARM) +#if defined(__aarch64__) || defined(__ARM64__) +const char *qt3ds::foundation::System::g_Processor = "arm"; +const char *qt3ds::foundation::System::g_BitWidth = "64"; +const char *qt3ds::foundation::System::g_FloatingPointModel = "softfp"; +#else +const char *qt3ds::foundation::System::g_Processor = "arm"; +const char *qt3ds::foundation::System::g_BitWidth = "32"; +#if defined(QT3DS_ARM_HARDFP) +const char *qt3ds::foundation::System::g_FloatingPointModel = "hardfp"; +#elif defined(QT3DS_ARM_SOFTFP) +const char *qt3ds::foundation::System::g_FloatingPointModel = "softfp"; +#else +#error "Unknown floating point model!" +#endif +#endif +#else +#error "Unknown Platform" +#endif + +#if defined(QT3DS_ARM) +#if defined(QT3DS_GRAPHICS_API_GLES2) +const char *qt3ds::foundation::System::g_GPUType = "gles2"; +#elif defined(QT3DS_GRAPHICS_API_GL) +const char *qt3ds::foundation::System::g_GPUType = "gl"; +#elif defined(QT3DS_GRAPHICS_API_GLES3) +const char *qt3ds::foundation::System::g_GPUType = "gles3"; +#else +#error \ + "Must define a GPU type for arm platforms (QT3DS_GRAPHICS_API_GLES2, QT3DS_GRAPHICS_API_GLES3, QT3DS_GRAPHICS_API_GL)" +#endif +#elif defined(QT3DS_X86) +const char *qt3ds::foundation::System::g_GPUType = ""; +#elif defined(QT3DS_X64) +const char *qt3ds::foundation::System::g_GPUType = ""; +#else +#error "Must define a processor type (QT3DS_ARM or QT3DS_X86)" +#endif + +namespace { +static const unsigned SYSTEM_STR_SIZE = 100; +void SystemAppendString(eastl::string &str, const char *delim, const char *string) +{ + if (string && *string) { + str.append(delim); + str.append(string); + } +} +} +const char *System::getPlatformStr() +{ + static char text[SYSTEM_STR_SIZE]; + { + eastl::string str(g_Processor); + SystemAppendString(str, "_", g_BitWidth); + SystemAppendString(str, "_", g_FloatingPointModel); + SystemAppendString(str, "_", g_OS); + strcpy(text, str.c_str()); + } + return text; +} + +const char *System::getPlatformGLStr() +{ + static char text[SYSTEM_STR_SIZE]; + { + eastl::string str(g_Processor); + SystemAppendString(str, "_", g_BitWidth); + SystemAppendString(str, "_", g_FloatingPointModel); + SystemAppendString(str, "_", g_GPUType); + SystemAppendString(str, "_", g_OS); + strcpy(text, str.c_str()); + } + return text; +} \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Qt3DSSystem.h b/src/Runtime/Source/foundation/Qt3DSSystem.h new file mode 100644 index 00000000..84ca87d1 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSSystem.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_FOUNDATION_SYSTEM_H +#define QT3DS_FOUNDATION_SYSTEM_H + +#include "foundation/Qt3DS.h" + +namespace qt3ds { +namespace foundation { + class QT3DS_FOUNDATION_API System + { + public: + static const char *g_OS; + static const char *g_Processor; + static const char *g_BitWidth; + static const char *g_FloatingPointModel; + static const char *g_GPUType; + static const char *g_DLLExtension; + static const char *getPlatformStr(); + static const char *getPlatformGLStr(); + + private: + System(); + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSThread.h b/src/Runtime/Source/foundation/Qt3DSThread.h new file mode 100644 index 00000000..84e169d6 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSThread.h @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSTHREAD_H +#define QT3DS_FOUNDATION_PSTHREAD_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSFoundation.h" + +// dsequeira: according to existing comment here (David Black would be my guess) +// "This is useful to reduce bus contention on tight spin locks. And it needs +// to be a macro as the xenon compiler often ignores even __forceinline." What's not +// clear is why a pause function needs inlining...? (TODO: check with XBox team) + +// todo: these need to go somewhere else + +#if defined(QT3DS_WINDOWS) +#define NVSpinLockPause() __asm pause +#elif defined(QT3DS_X360) +#define NVSpinLockPause() __asm nop +#elif defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_APPLE) || defined(QT3DS_QNX) +#define NVSpinLockPause() asm("nop") +#elif defined(QT3DS_PS3) +#define NVSpinLockPause() asm("nop") // don't know if it's correct yet... +#define QT3DS_TLS_MAX_SLOTS 64 +#elif defined(QT3DS_WII) +#define NVSpinLockPause() asm { nop } // don't know if it's correct yet... +#endif + +namespace qt3ds { +namespace foundation { + struct ThreadPriority // todo: put in some other header file + { + enum Enum { + /** + \brief High priority + */ + eHIGH = 0, + + /** + \brief Above Normal priority + */ + eABOVE_NORMAL = 1, + + /** + \brief Normal/default priority + */ + eNORMAL = 2, + + /** + \brief Below Normal priority + */ + eBELOW_NORMAL = 3, + + /** + \brief Low priority. + */ + eLOW = 4, + + eFORCE_DWORD = 0xffFFffFF + }; + }; + + /** + Thread abstraction API + */ + + class QT3DS_FOUNDATION_API Thread + { + public: + static const QT3DSU32 DEFAULT_STACK_SIZE; + typedef size_t Id; // space for a pointer or an integer + typedef void *(*ExecuteFn)(void *); + + static Id getId(); + + /** + Construct (but do not start) the thread object. Executes in the context + of the spawning thread + */ + + Thread(NVFoundationBase &foundation); + + /** + Construct and start the the thread, passing the given arg to the given fn. (pthread style) + */ + + Thread(NVFoundationBase &foundation, ExecuteFn fn, void *arg); + + /** + Deallocate all resources associated with the thread. Should be called in the + context of the spawning thread. + */ + + virtual ~Thread(); + + /** + start the thread running. Called in the context of the spawning thread. + */ + + void start(QT3DSU32 stackSize); + + /** + Violently kill the current thread. Blunt instrument, not recommended since + it can leave all kinds of things unreleased (stack, memory, mutexes...) Should + be called in the context of the spawning thread. + */ + + void kill(); + + /** + The virtual execute() method is the user defined function that will + run in the new thread. Called in the context of the spawned thread. + */ + + virtual void execute(void); + + /** + stop the thread. Signals the spawned thread that it should stop, so the + thread should check regularly + */ + + void signalQuit(); + + /** + Wait for a thread to stop. Should be called in the context of the spawning + thread. Returns false if the thread has not been started. + */ + + bool waitForQuit(); + + /** + check whether the thread is signalled to quit. Called in the context of the + spawned thread. + */ + + bool quitIsSignalled(); + + /** + Cleanly shut down this thread. Called in the context of the spawned thread. + */ + void quit(); + + /** + Change the affinity mask for this thread. + On Xbox360, sets the hardware thread to the first non-zero bit. + + Returns previous mask if successful, or zero on failure + */ + virtual QT3DSU32 setAffinityMask(QT3DSU32 mask); + + static ThreadPriority::Enum getPriority(Id threadId); + + /** Set thread priority. */ + void setPriority(ThreadPriority::Enum prio); + + /** set the thread's name */ + void setName(const char *name); + + /** Put the current thread to sleep for the given number of milliseconds */ + static void sleep(QT3DSU32 ms); + + /** Yield the current thread's slot on the CPU */ + static void yield(); + + private: + class ThreadImpl *mImpl; + }; + + QT3DS_FOUNDATION_API QT3DSU32 TlsAlloc(); + QT3DS_FOUNDATION_API void TlsFree(QT3DSU32 index); + QT3DS_FOUNDATION_API void *TlsGet(QT3DSU32 index); + QT3DS_FOUNDATION_API QT3DSU32 TlsSet(QT3DSU32 index, void *value); + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSTime.h b/src/Runtime/Source/foundation/Qt3DSTime.h new file mode 100644 index 00000000..955bd7e0 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSTime.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSTIME_H +#define QT3DS_FOUNDATION_PSTIME_H + +#include "foundation/Qt3DS.h" + +#if defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_QNX) +#include +#endif + +namespace qt3ds { +namespace foundation { + + struct CounterFrequencyToTensOfNanos + { + QT3DSU64 mNumerator; + QT3DSU64 mDenominator; + CounterFrequencyToTensOfNanos(QT3DSU64 inNum, QT3DSU64 inDenom) + : mNumerator(inNum) + , mDenominator(inDenom) + { + } + + // quite slow. + QT3DSU64 toTensOfNanos(QT3DSU64 inCounter) const + { + return (inCounter * mNumerator) / mDenominator; + } + }; + + class QT3DS_FOUNDATION_API Time + { + public: + typedef double Second; + static const QT3DSU64 sNumTensOfNanoSecondsInASecond = 100000000; + // This is supposedly guaranteed to not change after system boot + // regardless of processors, speedstep, etc. + static const CounterFrequencyToTensOfNanos sCounterFreq; + + static CounterFrequencyToTensOfNanos getCounterFrequency(); + + static QT3DSU64 getCurrentCounterValue(); + + // SLOW!! + // Thar be a 64 bit divide in thar! + static QT3DSU64 getCurrentTimeInTensOfNanoSeconds() + { + QT3DSU64 ticks = getCurrentCounterValue(); + return sCounterFreq.toTensOfNanos(ticks); + } + + Time(); + Second getElapsedSeconds(); + Second peekElapsedSeconds(); + Second getLastTime() const; + + private: +#if defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_APPLE) || defined(QT3DS_PSP2) \ + || defined(QT3DS_QNX) + Second mLastTime; +#else + QT3DSI64 mTickCount; +#endif + }; +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSTransform.h b/src/Runtime/Source/foundation/Qt3DSTransform.h new file mode 100644 index 00000000..0fee0a81 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSTransform.h @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_TRANSFORM_H +#define QT3DS_FOUNDATION_QT3DS_TRANSFORM_H +/** \addtogroup foundation + @{ +*/ + +#include "foundation/Qt3DSQuat.h" +#include "foundation/Qt3DSPlane.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/*! +\brief class representing a rigid euclidean transform as a quaternion and a vector +*/ + +class NVTransform +{ +public: + QT3DSQuat q; + QT3DSVec3 p; + + //#define PXTRANSFORM_DEFAULT_CONSTRUCT_NAN + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform() +#ifdef PXTRANSFORM_DEFAULT_CONSTRUCT_IDENTITY + : q(0, 0, 0, 1) + , p(0, 0, 0) +#elif defined(PXTRANSFORM_DEFAULT_CONSTRUCT_NAN) +#define invalid NVSqrt(-1.0f) + : q(invalid, invalid, invalid, invalid) + , p(invalid, invalid, invalid) +#undef invalid +#endif + { + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE explicit NVTransform(const QT3DSVec3 &position) + : q(0, 0, 0, 1) + , p(position) + { + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE explicit NVTransform(const QT3DSQuat &orientation) + : q(orientation) + , p(0, 0, 0) + { + QT3DS_ASSERT(orientation.isSane()); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform(const QT3DSVec3 &p0, const QT3DSQuat &q0) + : q(q0) + , p(p0) + { + QT3DS_ASSERT(q0.isSane()); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE explicit NVTransform(const QT3DSMat44 &m); // defined in Qt3DSMat44.h + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform operator*(const NVTransform &x) const + { + QT3DS_ASSERT(x.isSane()); + return transform(x); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform getInverse() const + { + QT3DS_ASSERT(isFinite()); + return NVTransform(q.rotateInv(-p), q.getConjugate()); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 transform(const QT3DSVec3 &input) const + { + QT3DS_ASSERT(isFinite()); + return q.rotate(input) + p; + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 transformInv(const QT3DSVec3 &input) const + { + QT3DS_ASSERT(isFinite()); + return q.rotateInv(input - p); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 rotate(const QT3DSVec3 &input) const + { + QT3DS_ASSERT(isFinite()); + return q.rotate(input); + } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 rotateInv(const QT3DSVec3 &input) const + { + QT3DS_ASSERT(isFinite()); + return q.rotateInv(input); + } + + //! Transform transform to parent (returns compound transform: first src, then *this) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform transform(const NVTransform &src) const + { + QT3DS_ASSERT(src.isSane()); + QT3DS_ASSERT(isSane()); + // src = [srct, srcr] -> [r*srct + t, r*srcr] + return NVTransform(q.rotate(src.p) + p, q * src.q); + } + + /** + \brief returns true if finite and q is a unit quaternion + */ + + QT3DS_CUDA_CALLABLE bool isValid() const { return p.isFinite() && q.isFinite() && q.isUnit(); } + + /** + \brief returns true if finite and quat magnitude is reasonably close to unit to allow for some + accumulation of error vs isValid + */ + + QT3DS_CUDA_CALLABLE bool isSane() const { return isFinite() && q.isSane(); } + + /** + \brief returns true if all elems are finite (not NAN or INF, etc.) + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite() const { return p.isFinite() && q.isFinite(); } + + //! Transform transform from parent (returns compound transform: first src, then this->inverse) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVTransform transformInv(const NVTransform &src) const + { + QT3DS_ASSERT(src.isSane()); + QT3DS_ASSERT(isFinite()); + // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr] + QT3DSQuat qinv = q.getConjugate(); + return NVTransform(qinv.rotate(src.p - p), qinv * src.q); + } + + QT3DS_CUDA_CALLABLE static QT3DS_FORCE_INLINE NVTransform createIdentity() + { + return NVTransform(QT3DSVec3(0)); + } + + /** + \brief transform plane + */ + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane transform(const NVPlane &plane) const + { + QT3DSVec3 transformedNormal = rotate(plane.n); + return NVPlane(transformedNormal, plane.d - p.dot(transformedNormal)); + } + + /** + \brief inverse-transform plane + */ + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVPlane inverseTransform(const NVPlane &plane) const + { + QT3DSVec3 transformedNormal = rotateInv(plane.n); + return NVPlane(transformedNormal, plane.d + p.dot(plane.n)); + } +}; + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_TRANSFORM_H diff --git a/src/Runtime/Source/foundation/Qt3DSUnionCast.h b/src/Runtime/Source/foundation/Qt3DSUnionCast.h new file mode 100644 index 00000000..a3d03555 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSUnionCast.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_UNION_CAST_H +#define QT3DS_FOUNDATION_QT3DS_UNION_CAST_H + +#include "foundation/Qt3DSPreprocessor.h" + +/** \addtogroup foundation +@{ +*/ + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +template +QT3DS_FORCE_INLINE A NVUnionCast(B b) +{ + union AB { + AB(B bb) + : _b(bb) + { + } + B _b; + A _a; + } u(b); + return u._a; +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSUtilities.h b/src/Runtime/Source/foundation/Qt3DSUtilities.h new file mode 100644 index 00000000..cb9ae6a2 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSUtilities.h @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_PSUTILITIES_H +#define QT3DS_FOUNDATION_PSUTILITIES_H + +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSIntrinsics.h" + +namespace qt3ds { +namespace foundation { + + // PT: checked casts + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU16 to16(QT3DSU32 value) + { + QT3DS_ASSERT(value <= 0xffff); + return QT3DSU16(value); + } + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU8 to8(QT3DSU16 value) + { + QT3DS_ASSERT(value <= 0xff); + return QT3DSU8(value); + } + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSU8 to8(QT3DSU32 value) + { + QT3DS_ASSERT(value <= 0xff); + return QT3DSU8(value); + } + + template + QT3DS_CUDA_CALLABLE QT3DS_INLINE void swap(T &x, T &y) + { +// crash with optimizations enabled, ticket in Sony +#ifdef QT3DS_PSP2 +#pragma control % push O = 0 +#endif + T tmp = x; + x = y; + y = tmp; +#ifdef QT3DS_PSP2 +#pragma control % pop O +#endif + } + + /*! +Get number of elements in array +*/ + template + char (&ArraySizeHelper(T (&array)[N]))[N]; +#define QT3DS_ARRAY_SIZE(_array) (sizeof(qt3ds::foundation::ArraySizeHelper(_array))) + + /*! +Sort two elements using operator< + +On return x will be the smaller of the two +*/ + template + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void order(T &x, T &y) + { + if (y < x) + swap(x, y); + } + + // most architectures can do predication on real comparisons, and on VMX, it matters + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void order(NVReal &x, NVReal &y) + { + NVReal newX = NVMin(x, y); + NVReal newY = NVMax(x, y); + x = newX; + y = newY; + } + + /*! + Sort two elements using operator< and also keep order + of any extra data + */ + template + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE void order(T &x, T &y, E1 &xe1, E1 &ye1) + { + if (y < x) { + swap(x, y); + swap(xe1, ye1); + } + } + + QT3DS_INLINE void debugBreak() + { +#if defined(QT3DS_WINDOWS) + __debugbreak(); +#elif defined(QT3DS_LINUX) || defined(QT3DS_ANDROID) || defined(QT3DS_QNX) + asm("int $3"); +#elif defined(QT3DS_GNUC) + __builtin_trap(); +#else + QT3DS_ASSERT(false); +#endif + } + + bool checkValid(const float &); + bool checkValid(const QT3DSVec3 &); + bool checkValid(const QT3DSQuat &); + bool checkValid(const QT3DSMat33 &); + bool checkValid(const NVTransform &); + bool checkValid(const char *); + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSI32 getPadding2(size_t value, QT3DSU32 alignment) + { + const QT3DSI32 mask = alignment - 1; + const QT3DSI32 overhead = QT3DSI32(value) & mask; + return (alignment - overhead) & mask; + } + + // PT: "After doing a dcbz128, there is a delay of about 140 cycles before writes to that cache + // line can proceed without stalling. + // This is much faster than an L2 cache miss, but for ideal performance, it is best to avoid + // this stall by doing the cache-line + // zeroing a few cache lines ahead of where you are writing." + QT3DS_FORCE_INLINE void invalidateCache(void *QT3DS_RESTRICT voidPtr, QT3DSI32 size) + { +#ifdef QT3DS_X360 + QT3DSU8 *QT3DS_RESTRICT ptr = reinterpret_cast(voidPtr); + const QT3DSI32 padding = getPadding2(size_t(ptr), 128); + const QT3DSI32 sizeToCover = size - padding; + if (sizeToCover >= 128) { + QT3DSU8 *ptr128 = ptr + padding; + QT3DSU32 nb128 = sizeToCover / 128; + while (nb128--) { + // NV::memZero128(ptr128); + qt3ds::foundation::memZero128(ptr128); + ptr128 += 128; + } + } +#else + (void)voidPtr; + (void)size; +#endif + } + + // equivalent to std::max_element + template + inline const T *maxElement(const T *first, const T *last) + { + const T *m = first; + for (const T *it = first + 1; it < last; ++it) + if (*m < *it) + m = it; + + return m; + } + +} // namespace foundation +} // namespace qt3ds + +#define QT3DS_STRINGIZE_HELPER(X) #X +#define QT3DS_STRINGIZE(X) QT3DS_STRINGIZE_HELPER(X) + +#define QT3DS_CONCAT_HELPER(X, Y) X##Y +#define QT3DS_CONCAT(X, Y) QT3DS_CONCAT_HELPER(X, Y) + +#endif diff --git a/src/Runtime/Source/foundation/Qt3DSVec2.h b/src/Runtime/Source/foundation/Qt3DSVec2.h new file mode 100644 index 00000000..0d86c915 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSVec2.h @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_VEC2_H +#define QT3DS_FOUNDATION_QT3DS_VEC2_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSMath.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/** +\brief 2 Element vector class. + +This is a vector class with public data members. +This is not nice but it has become such a standard that hiding the xy data members +makes it difficult to reuse external code that assumes that these are public in the library. +The vector class can be made to use float or double precision by appropriately defining NVReal. +This has been chosen as a cleaner alternative to a template class. +*/ +class QT3DSVec2 +{ +public: + /** + \brief default constructor leaves data uninitialized. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2() {} + + /** + \brief Assigns scalar parameter to all elements. + + Useful to initialize to zero or one. + + \param[in] a Value to assign to elements. + */ + explicit QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2(NVReal a) + : x(a) + , y(a) + { + } + + /** + \brief Initializes from 2 scalar parameters. + + \param[in] nx Value to initialize X component. + \param[in] ny Value to initialize Y component. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2(NVReal nx, NVReal ny) + : x(nx) + , y(ny) + { + } + + /** + \brief Copy ctor. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2(const QT3DSVec2 &v) + : x(v.x) + , y(v.y) + { + } + + // Operators + + /** + \brief Assignment operator + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator=(const QT3DSVec2 &p) + { + x = p.x; + y = p.y; + return *this; + } + + /** + \brief element access + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator[](int index) + { + QT3DS_ASSERT(index >= 0 && index <= 1); + return (&x)[index]; + } + + /** + \brief element access + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal &operator[](int index) const + { + QT3DS_ASSERT(index >= 0 && index <= 1); + return (&x)[index]; + } + + /** + \brief returns true if the two vectors are exactly equal. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator==(const QT3DSVec2 &v) const + { + return x == v.x && y == v.y; + } + + /** + \brief returns true if the two vectors are not exactly equal. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator!=(const QT3DSVec2 &v) const + { + return x != v.x || y != v.y; + } + + /** + \brief tests for exact zero vector + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isZero() const { return x == 0.0f && y == 0.0f; } + + /** + \brief returns true if all 2 elems of the vector are finite (not NAN or INF, etc.) + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const { return NVIsFinite(x) && NVIsFinite(y); } + + /** + \brief is normalized - used by API parameter validation + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isNormalized() const + { + const float unitTolerance = NVReal(1e-4); + return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; + } + + /** + \brief returns the squared magnitude + + Avoids calling NVSqrt()! + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitudeSquared() const { return x * x + y * y; } + + /** + \brief returns the magnitude + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitude() const { return NVSqrt(magnitudeSquared()); } + + /** + \brief negation + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator-() const { return QT3DSVec2(-x, -y); } + + /** + \brief vector addition + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator+(const QT3DSVec2 &v) const + { + return QT3DSVec2(x + v.x, y + v.y); + } + + /** + \brief vector difference + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator-(const QT3DSVec2 &v) const + { + return QT3DSVec2(x - v.x, y - v.y); + } + + /** + \brief scalar post-multiplication + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator*(NVReal f) const + { + return QT3DSVec2(x * f, y * f); + } + + /** + \brief scalar division + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 operator/(NVReal f) const + { + f = NVReal(1) / f; // PT: inconsistent notation with operator /= + return QT3DSVec2(x * f, y * f); + } + + /** + \brief vector addition + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator+=(const QT3DSVec2 &v) + { + x += v.x; + y += v.y; + return *this; + } + + /** + \brief vector difference + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator-=(const QT3DSVec2 &v) + { + x -= v.x; + y -= v.y; + return *this; + } + + /** + \brief scalar multiplication + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator*=(NVReal f) + { + x *= f; + y *= f; + return *this; + } + /** + \brief scalar division + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 &operator/=(NVReal f) + { + f = 1.0f / f; // PT: inconsistent notation with operator / + x *= f; + y *= f; + return *this; + } + + /** + \brief returns the scalar product of this and other. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal dot(const QT3DSVec2 &v) const { return x * v.x + y * v.y; } + + /** return a unit vector */ + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 getNormalized() const + { + const NVReal m = magnitudeSquared(); + return m > 0 ? *this * NVRecipSqrt(m) : QT3DSVec2(0, 0); + } + + /** + \brief normalizes the vector in place + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalize() + { + const NVReal m = magnitude(); + if (m > 0) + *this /= m; + return m; + } + + /** + \brief a[i] * b[i], for all i. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 multiply(const QT3DSVec2 &a) const + { + return QT3DSVec2(x * a.x, y * a.y); + } + + /** + \brief element-wise minimum + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 minimum(const QT3DSVec2 &v) const + { + return QT3DSVec2(NVMin(x, v.x), NVMin(y, v.y)); + } + + /** + \brief returns MIN(x, y); + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float minElement() const { return NVMin(x, y); } + + /** + \brief element-wise maximum + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec2 maximum(const QT3DSVec2 &v) const + { + return QT3DSVec2(NVMax(x, v.x), NVMax(y, v.y)); + } + + /** + \brief returns MAX(x, y); + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float maxElement() const { return NVMax(x, y); } + + NVReal x, y; +}; + +QT3DS_CUDA_CALLABLE static QT3DS_FORCE_INLINE QT3DSVec2 operator*(NVReal f, const QT3DSVec2 &v) +{ + return QT3DSVec2(f * v.x, f * v.y); +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_VEC2_H diff --git a/src/Runtime/Source/foundation/Qt3DSVec3.h b/src/Runtime/Source/foundation/Qt3DSVec3.h new file mode 100644 index 00000000..24ab8231 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSVec3.h @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_VEC3_H +#define QT3DS_FOUNDATION_QT3DS_VEC3_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/Qt3DSMath.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +/** +\brief 3 Element vector class. + +This is a vector class with public data members. +This is not nice but it has become such a standard that hiding the xyz data members +makes it difficult to reuse external code that assumes that these are public in the library. +The vector class can be made to use float or double precision by appropriately defining NVReal. +This has been chosen as a cleaner alternative to a template class. +*/ +class QT3DSVec3 +{ +public: + /** + \brief default constructor leaves data uninitialized. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3() {} + + /** + \brief Assigns scalar parameter to all elements. + + Useful to initialize to zero or one. + + \param[in] a Value to assign to elements. + */ + explicit QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3(NVReal a) + : x(a) + , y(a) + , z(a) + { + } + + /** + \brief Initializes from 3 scalar parameters. + + \param[in] nx Value to initialize X component. + \param[in] ny Value to initialize Y component. + \param[in] nz Value to initialize Z component. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3(NVReal nx, NVReal ny, NVReal nz) + : x(nx) + , y(ny) + , z(nz) + { + } + + /** + \brief Copy ctor. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3(const QT3DSVec3 &v) + : x(v.x) + , y(v.y) + , z(v.z) + { + } + + // Operators + + /** + \brief Assignment operator + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator=(const QT3DSVec3 &p) + { + x = p.x; + y = p.y; + z = p.z; + return *this; + } + + /** + \brief element access + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal &operator[](int index) + { + QT3DS_ASSERT(index >= 0 && index <= 2); + return (&x)[index]; + } + + /** + \brief element access + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE const NVReal &operator[](int index) const + { + QT3DS_ASSERT(index >= 0 && index <= 2); + return (&x)[index]; + } + + /** + \brief returns true if the two vectors are exactly equal. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator==(const QT3DSVec3 &v) const + { + return x == v.x && y == v.y && z == v.z; + } + + /** + \brief returns true if the two vectors are not exactly equal. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool operator!=(const QT3DSVec3 &v) const + { + return x != v.x || y != v.y || z != v.z; + } + + /** + \brief tests for exact zero vector + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isZero() const + { + return x == 0.0f && y == 0.0f && z == 0.0f; + } + + /** + \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.) + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const + { + return NVIsFinite(x) && NVIsFinite(y) && NVIsFinite(z); + } + + /** + \brief is normalized - used by API parameter validation + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isNormalized() const + { + const float unitTolerance = NVReal(1e-4); + return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; + } + + /** + \brief returns the squared magnitude + + Avoids calling NVSqrt()! + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitudeSquared() const + { + return x * x + y * y + z * z; + } + + /** + \brief returns the magnitude + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal magnitude() const { return NVSqrt(magnitudeSquared()); } + + /** + \brief negation + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator-() const { return QT3DSVec3(-x, -y, -z); } + + /** + \brief vector addition + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator+(const QT3DSVec3 &v) const + { + return QT3DSVec3(x + v.x, y + v.y, z + v.z); + } + + /** + \brief vector difference + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator-(const QT3DSVec3 &v) const + { + return QT3DSVec3(x - v.x, y - v.y, z - v.z); + } + + /** + \brief scalar post-multiplication + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator*(NVReal f) const + { + return QT3DSVec3(x * f, y * f, z * f); + } + + /** + \brief scalar division + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 operator/(NVReal f) const + { + f = NVReal(1) / f; // PT: inconsistent notation with operator /= + return QT3DSVec3(x * f, y * f, z * f); + } + + /** + \brief vector addition + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator+=(const QT3DSVec3 &v) + { + x += v.x; + y += v.y; + z += v.z; + return *this; + } + + /** + \brief vector difference + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator-=(const QT3DSVec3 &v) + { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } + + /** + \brief scalar multiplication + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator*=(NVReal f) + { + x *= f; + y *= f; + z *= f; + return *this; + } + /** + \brief scalar division + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 &operator/=(NVReal f) + { + f = 1.0f / f; // PT: inconsistent notation with operator / + x *= f; + y *= f; + z *= f; + return *this; + } + + /** + \brief returns the scalar product of this and other. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal dot(const QT3DSVec3 &v) const + { + return x * v.x + y * v.y + z * v.z; + } + + /** + \brief cross product + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 cross(const QT3DSVec3 &v) const + { + return QT3DSVec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); + } + + /** return a unit vector */ + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 getNormalized() const + { + const NVReal m = magnitudeSquared(); + return m > 0 ? *this * NVRecipSqrt(m) : QT3DSVec3(0, 0, 0); + } + + /** + \brief normalizes the vector in place + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalize() + { + const NVReal m = magnitude(); + if (m > 0) + *this /= m; + return m; + } + + /** + \brief normalizes the vector in place. Does nothing if vector magnitude is under + QT3DS_NORMALIZATION_EPSILON. + Returns vector magnitude if >= QT3DS_NORMALIZATION_EPSILON and 0.0f otherwise. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalizeSafe() + { + const NVReal mag = magnitude(); + if (mag < QT3DS_NORMALIZATION_EPSILON) + return 0.0f; + *this *= NVReal(1) / mag; + return mag; + } + + /** + \brief normalizes the vector in place. Asserts if vector magnitude is under + QT3DS_NORMALIZATION_EPSILON. + returns vector magnitude. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE NVReal normalizeFast() + { + const NVReal mag = magnitude(); + QT3DS_ASSERT(mag >= QT3DS_NORMALIZATION_EPSILON); + *this *= NVReal(1) / mag; + return mag; + } + + /** + \brief a[i] * b[i], for all i. + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 multiply(const QT3DSVec3 &a) const + { + return QT3DSVec3(x * a.x, y * a.y, z * a.z); + } + + /** + \brief element-wise minimum + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 minimum(const QT3DSVec3 &v) const + { + return QT3DSVec3(NVMin(x, v.x), NVMin(y, v.y), NVMin(z, v.z)); + } + + /** + \brief returns MIN(x, y, z); + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float minElement() const { return NVMin(x, NVMin(y, z)); } + + /** + \brief element-wise maximum + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE QT3DSVec3 maximum(const QT3DSVec3 &v) const + { + return QT3DSVec3(NVMax(x, v.x), NVMax(y, v.y), NVMax(z, v.z)); + } + + /** + \brief returns MAX(x, y, z); + */ + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float maxElement() const { return NVMax(x, NVMax(y, z)); } + + NVReal x, y, z; +}; + +QT3DS_CUDA_CALLABLE static QT3DS_FORCE_INLINE QT3DSVec3 operator*(NVReal f, const QT3DSVec3 &v) +{ + return QT3DSVec3(f * v.x, f * v.y, f * v.z); +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_VEC3_H diff --git a/src/Runtime/Source/foundation/Qt3DSVec4.h b/src/Runtime/Source/foundation/Qt3DSVec4.h new file mode 100644 index 00000000..acccd48c --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSVec4.h @@ -0,0 +1,373 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_VEC4_H +#define QT3DS_FOUNDATION_QT3DS_VEC4_H +/** \addtogroup foundation +@{ +*/ +#include "foundation/Qt3DSMath.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSAssert.h" + +/** +\brief 4 Element vector class. + +This is a vector class with public data members. +This is not nice but it has become such a standard that hiding the xyz data members +makes it difficult to reuse external code that assumes that these are public in the library. +The vector class can be made to use float or double precision by appropriately defining NVReal. +This has been chosen as a cleaner alternative to a template class. +*/ +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +class QT3DSVec4 +{ +public: + /** + \brief default constructor leaves data uninitialized. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4() {} + + /** + \brief Assigns scalar parameter to all elements. + + Useful to initialize to zero or one. + + \param[in] a Value to assign to elements. + */ + explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(NVReal a) + : x(a) + , y(a) + , z(a) + , w(a) + { + } + + /** + \brief Initializes from 3 scalar parameters. + + \param[in] nx Value to initialize X component. + \param[in] ny Value to initialize Y component. + \param[in] nz Value to initialize Z component. + \param[in] nw Value to initialize W component. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(NVReal nx, NVReal ny, NVReal nz, NVReal nw) + : x(nx) + , y(ny) + , z(nz) + , w(nw) + { + } + + /** + \brief Initializes from 3 scalar parameters. + + \param[in] v Value to initialize the X, Y, and Z components. + \param[in] nw Value to initialize W component. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(const QT3DSVec3 &v, NVReal nw) + : x(v.x) + , y(v.y) + , z(v.z) + , w(nw) + { + } + + /** + \brief Initializes from an array of scalar parameters. + + \param[in] v Value to initialize with. + */ + explicit QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(const NVReal v[]) + : x(v[0]) + , y(v[1]) + , z(v[2]) + , w(v[3]) + { + } + + /** + \brief Copy ctor. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4(const QT3DSVec4 &v) + : x(v.x) + , y(v.y) + , z(v.z) + , w(v.w) + { + } + + // Operators + + /** + \brief Assignment operator + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator=(const QT3DSVec4 &p) + { + x = p.x; + y = p.y; + z = p.z; + w = p.w; + return *this; + } + + /** + \brief element access + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal &operator[](int index) + { + QT3DS_ASSERT(index >= 0 && index <= 3); + return (&x)[index]; + } + + /** + \brief element access + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE const NVReal &operator[](int index) const + { + QT3DS_ASSERT(index >= 0 && index <= 3); + return (&x)[index]; + } + + /** + \brief returns true if the two vectors are exactly equal. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool operator==(const QT3DSVec4 &v) const + { + return x == v.x && y == v.y && z == v.z && w == v.w; + } + + /** + \brief returns true if the two vectors are not exactly equal. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool operator!=(const QT3DSVec4 &v) const + { + return x != v.x || y != v.y || z != v.z || w != v.w; + } + + /** + \brief tests for exact zero vector + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isZero() const { return x == 0 && y == 0 && z == 0 && w == 0; } + + /** + \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.) + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isFinite() const + { + return NVIsFinite(x) && NVIsFinite(y) && NVIsFinite(z) && NVIsFinite(w); + } + + /** + \brief is normalized - used by API parameter validation + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE bool isNormalized() const + { + const float unitTolerance = NVReal(1e-4); + return isFinite() && NVAbs(magnitude() - 1) < unitTolerance; + } + + /** + \brief returns the squared magnitude + + Avoids calling NVSqrt()! + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal magnitudeSquared() const + { + return x * x + y * y + z * z + w * w; + } + + /** + \brief returns the magnitude + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal magnitude() const { return NVSqrt(magnitudeSquared()); } + + /** + \brief negation + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator-() const { return QT3DSVec4(-x, -y, -z, -w); } + + /** + \brief vector addition + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator+(const QT3DSVec4 &v) const + { + return QT3DSVec4(x + v.x, y + v.y, z + v.z, w + v.w); + } + + /** + \brief vector difference + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator-(const QT3DSVec4 &v) const + { + return QT3DSVec4(x - v.x, y - v.y, z - v.z, w - v.w); + } + + /** + \brief scalar post-multiplication + */ + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator*(NVReal f) const + { + return QT3DSVec4(x * f, y * f, z * f, w * f); + } + + /** + \brief scalar division + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 operator/(NVReal f) const + { + f = NVReal(1) / f; + return QT3DSVec4(x * f, y * f, z * f, w * f); + } + + /** + \brief vector addition + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator+=(const QT3DSVec4 &v) + { + x += v.x; + y += v.y; + z += v.z; + w += v.w; + return *this; + } + + /** + \brief vector difference + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator-=(const QT3DSVec4 &v) + { + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + return *this; + } + + /** + \brief scalar multiplication + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator*=(NVReal f) + { + x *= f; + y *= f; + z *= f; + w *= f; + return *this; + } + /** + \brief scalar division + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 &operator/=(NVReal f) + { + f = 1.0f / f; + x *= f; + y *= f; + z *= f; + w *= f; + return *this; + } + + /** + \brief returns the scalar product of this and other. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal dot(const QT3DSVec4 &v) const + { + return x * v.x + y * v.y + z * v.z + w * v.w; + } + + /** return a unit vector */ + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 getNormalized() const + { + NVReal m = magnitudeSquared(); + return m > 0 ? *this * NVRecipSqrt(m) : QT3DSVec4(0, 0, 0, 0); + } + + /** + \brief normalizes the vector in place + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE NVReal normalize() + { + NVReal m = magnitude(); + if (m > 0) + *this /= m; + return m; + } + + /** + \brief a[i] * b[i], for all i. + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 multiply(const QT3DSVec4 &a) const + { + return QT3DSVec4(x * a.x, y * a.y, z * a.z, w * a.w); + } + + /** + \brief element-wise minimum + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 minimum(const QT3DSVec4 &v) const + { + return QT3DSVec4(NVMin(x, v.x), NVMin(y, v.y), NVMin(z, v.z), NVMin(w, v.w)); + } + + /** + \brief element-wise maximum + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec4 maximum(const QT3DSVec4 &v) const + { + return QT3DSVec4(NVMax(x, v.x), NVMax(y, v.y), NVMax(z, v.z), NVMax(w, v.w)); + } + + QT3DS_CUDA_CALLABLE QT3DS_INLINE QT3DSVec3 getXYZ() const { return QT3DSVec3(x, y, z); } + + /** + \brief set vector elements to zero + */ + QT3DS_CUDA_CALLABLE QT3DS_INLINE void setZero() { x = y = z = w = NVReal(0); } + + NVReal x, y, z, w; +}; + +QT3DS_CUDA_CALLABLE static QT3DS_INLINE QT3DSVec4 operator*(NVReal f, const QT3DSVec4 &v) +{ + return QT3DSVec4(f * v.x, f * v.y, f * v.z, f * v.w); +} + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +/** @} */ +#endif // QT3DS_FOUNDATION_QT3DS_VEC4_H diff --git a/src/Runtime/Source/foundation/Qt3DSVersionNumber.h b/src/Runtime/Source/foundation/Qt3DSVersionNumber.h new file mode 100644 index 00000000..5942ef72 --- /dev/null +++ b/src/Runtime/Source/foundation/Qt3DSVersionNumber.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* +VersionNumbers: The combination of these +numbers uniquely identifies the API, and should +be incremented when the SDK API changes. This may +include changes to file formats. + +This header is included in the main SDK header files +so that the entire SDK and everything that builds on it +is completely rebuilt when this file changes. Thus, +this file is not to include a frequently changing +build number. See BuildNumber.h for that. + +Each of these three values should stay below 255 because +sometimes they are stored in a byte. +*/ +/** \addtogroup foundation + @{ +*/ +#ifndef QT3DS_FOUNDATION_QT3DS_VERSION_NUMBER_H +#define QT3DS_FOUNDATION_QT3DS_VERSION_NUMBER_H + +#define QT3DS_FOUNDATION_VERSION_MAJOR 3 +#define QT3DS_FOUNDATION_VERSION_MINOR 3 +#define QT3DS_FOUNDATION_VERSION_BUGFIX 0 + +/** +The constant QT3DS_FOUNDATION_VERSION is used when creating certain PhysX module objects. +This is to ensure that the application is using the same header version as the library was built +with. +*/ +#define QT3DS_FOUNDATION_VERSION \ + ((QT3DS_FOUNDATION_VERSION_MAJOR << 24) + (QT3DS_FOUNDATION_VERSION_MINOR << 16) \ + + (QT3DS_FOUNDATION_VERSION_BUGFIX << 8) + 0) + +#endif // QT3DS_FOUNDATION_QT3DS_VERSION_NUMBER_H + +/** @} */ diff --git a/src/Runtime/Source/foundation/SerializationTypes.h b/src/Runtime/Source/foundation/SerializationTypes.h new file mode 100644 index 00000000..c7fe5ce7 --- /dev/null +++ b/src/Runtime/Source/foundation/SerializationTypes.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SERIALIZATION_TYPES_H +#define QT3DS_RENDER_SERIALIZATION_TYPES_H +#include "EASTL/hash_map.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace foundation { + + struct SStrRemapMap : public nvhash_map + { + typedef nvhash_map TBaseType; + SStrRemapMap(NVAllocatorCallback &inAlloc, const char *inName) + : TBaseType(inAlloc, inName) + { + } + }; + + struct SPtrOffsetMap : public nvhash_map + { + typedef nvhash_map TBaseType; + SPtrOffsetMap(NVAllocatorCallback &inAlloc, const char *inName) + : TBaseType(inAlloc, inName) + { + } + }; + + struct SWriteBuffer : public MemoryBuffer<> + { + SWriteBuffer(NVAllocatorCallback &inAlloc, const char *inName) + : MemoryBuffer<>(ForwardingAllocator(inAlloc, inName)) + { + } + }; + + // Simple data reader that mimics a string + struct SDataReader + { + QT3DSU8 *m_CurrentPtr; + QT3DSU8 *m_EndPtr; + SDataReader(QT3DSU8 *inStartPtr, QT3DSU8 *inEndPtr) + : m_CurrentPtr(inStartPtr) + , m_EndPtr(inEndPtr) + { + } + + template + TDataType *Load() + { + if ((m_CurrentPtr + sizeof(TDataType)) > m_EndPtr) { + QT3DS_ASSERT(false); + return NULL; + } + TDataType *theType = reinterpret_cast(m_CurrentPtr); + m_CurrentPtr += sizeof(TDataType); + return theType; + } + + template + void MemCopy(TDataType *dt, QT3DSU32 count) + { + if (count) { + QT3DSU32 loadSize = count * sizeof(TDataType); + QT3DSU32 amountLeft = (QT3DSU32)(m_EndPtr - m_CurrentPtr); + QT3DSU32 amountLoaded = NVMin(loadSize, amountLeft); + memCopy(dt, m_CurrentPtr, amountLoaded); + m_CurrentPtr += amountLoaded; + if (amountLoaded < loadSize) { + QT3DS_ASSERT(false); + QT3DSU8 *rawPtr = (QT3DSU8 *)dt; + rawPtr += amountLoaded; + size_t leftover = loadSize - amountLoaded; + // zeroing things out at least is an attempt to provide ordered + // data that may prevent a crash in some cases. + memZero(rawPtr, (QT3DSU32)leftover); + } + } + } + + // Don't make a habit of using this a lot. + template + TDataType &LoadRef() + { + TDataType *retval = Load(); + if (!retval) + QT3DS_ASSERT(false); + return *retval; + } + + void Align(size_t alignment) + { + size_t offset = (size_t)(m_CurrentPtr); + if (offset % alignment) + m_CurrentPtr += (alignment - (offset % alignment)); + } + + void Align() { Align(sizeof(void *)); } + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/Socket.cpp b/src/Runtime/Source/foundation/Socket.cpp new file mode 100644 index 00000000..df00e606 --- /dev/null +++ b/src/Runtime/Source/foundation/Socket.cpp @@ -0,0 +1,472 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* +LuaSocket 3.0 license +Copyright � 2004-2013 Diego Nehab + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#include "foundation/Socket.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSMemoryBuffer.h" + +#if defined QT3DS_WINDOWS || defined QT3DS_WIN8ARM +#include "windows/SocketImpl.h" +#else +#include "linux/SocketImpl.h" +#endif + +using namespace qt3ds; +using namespace qt3ds::foundation; +using namespace qt3ds::foundation::socketimpl; + +namespace { + +#if defined QT3DS_WINDOWS || defined QT3DS_WIN8ARM +/*-------------------------------------------------------------------------*\ +* Some systems do not provide this so that we provide our own. It's not +* marvelously fast, but it works just fine. +\*-------------------------------------------------------------------------*/ +int inet_aton(const char *cp, struct in_addr *inp) +{ + unsigned int a = 0, b = 0, c = 0, d = 0; + int n = 0, r; + unsigned long int addr = 0; + r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n); + if (r == 0 || n == 0) + return 0; + cp += n; + if (*cp) + return 0; + if (a > 255 || b > 255 || c > 255 || d > 255) + return 0; + if (inp) { + addr += a; + addr <<= 8; + addr += b; + addr <<= 8; + addr += c; + addr <<= 8; + addr += d; + inp->s_addr = htonl(addr); + } + return 1; +} +#endif + +/*-------------------------------------------------------------------------*\ +* Tries to connect to remote address (address, port) +\*-------------------------------------------------------------------------*/ +int inet_tryconnect(p_socket ps, const char *address, unsigned short port, QT3DSU32 tm, SA *remoteAddr) +{ + struct sockaddr_in remote; + int err; + memset(&remote, 0, sizeof(remote)); + remote.sin_family = AF_INET; + remote.sin_port = htons(port); + if (strcmp(address, "*")) { + if (!inet_aton(address, &remote.sin_addr)) { + struct hostent *hp = NULL; + struct in_addr **addr; + err = socket_gethostbyname(address, &hp); + if (err != IO_DONE) + return err; + addr = (struct in_addr **)hp->h_addr_list; + memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); + } + } else + remote.sin_family = AF_UNSPEC; + if (remoteAddr) + memcpy(remoteAddr, &remote, sizeof(remote)); + err = socket_connect(ps, (SA *)&remote, sizeof(remote), tm); + return err; +} + +/*-------------------------------------------------------------------------*\ +* Tries to bind socket to (address, port) +\*-------------------------------------------------------------------------*/ +int inet_trybind(p_socket ps, const char *address, unsigned short port) +{ + struct sockaddr_in local; + int err; + memset(&local, 0, sizeof(local)); + /* address is either wildcard or a valid ip address */ + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(port); + local.sin_family = AF_INET; + if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { + struct hostent *hp = NULL; + struct in_addr **addr; + err = socket_gethostbyname(address, &hp); + if (err != IO_DONE) + return err; + addr = (struct in_addr **)hp->h_addr_list; + memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); + } + err = socket_bind(ps, (SA *)&local, sizeof(local)); + if (err != IO_DONE) + socket_destroy(ps); + return err; +} + +static bool is_socket_error(int errcode) +{ + return errcode != IO_DONE && errcode != IO_TIMEOUT; +} + +const char *generalized_strerror(int err) +{ + if (err <= 0) + return io_strerror(err); + else + return socket_strerror(err); +} + +struct SocketSystemCore : public NVRefCounted +{ + NVFoundationBase &m_Foundation; + QT3DSI32 mRefCount; + SocketSystemCore(NVFoundationBase &fnd) + : m_Foundation(fnd) + , mRefCount(0) + { + } + ~SocketSystemCore() { socket_close(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + static NVScopedRefCounted Create(NVFoundationBase &fnd) + { + int success = socket_open(); + if (!success) { + qCCritical(INVALID_OPERATION, "Failed to initialize network subsystem"); + return NVScopedRefCounted(); + } + return QT3DS_NEW(fnd.getAllocator(), SocketSystemCore)(fnd); + } +}; + +struct SocketStreamImpl : public SocketStream +{ + NVScopedRefCounted m_SocketCore; + NVFoundationBase &m_Foundation; + t_socket m_Socket; + SA m_Destination; + bool m_Connected; + QT3DSU32 m_Timeout; + QT3DSI32 mRefCount; + SocketStreamImpl(SocketSystemCore &core, NVFoundationBase &fnd, t_socket s, SA dest) + : m_SocketCore(core) + , m_Foundation(fnd) + , m_Socket(s) + , m_Destination(dest) + , m_Connected(true) + , m_Timeout(10000) + , mRefCount(0) + { + // We use wait functions in order to block. + socket_setnonblocking(&m_Socket); + } + + ~SocketStreamImpl() + { + shutdown(); + socket_destroy(&m_Socket); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + void setTimeout(QT3DSU32 milliseconds) override { m_Timeout = milliseconds; } + + bool Write(NVConstDataRef data) override + { + if (m_Connected == false) + return false; + + size_t totalSent = 0; + const char *writePtr(reinterpret_cast(data.begin())); + size_t amountLeft = data.size(); + do { + + size_t amountSent = 0; + int errcode = + socket_send(&m_Socket, writePtr + totalSent, amountLeft, &amountSent, m_Timeout); + + if (is_socket_error(errcode)) { + m_Connected = false; + qCWarning(WARNING, "Networking error during send: %s", generalized_strerror(errcode)); + return false; + } + totalSent += amountSent; + amountLeft -= amountSent; + } while (amountLeft); + return true; + } + + QT3DSU32 Read(NVDataRef data) override + { + if (m_Connected == false) + return 0; + size_t amountReceived = 0; + int errcode = socket_recv(&m_Socket, reinterpret_cast(data.begin()), data.size(), + &amountReceived, m_Timeout); + if (is_socket_error(errcode)) { + m_Connected = false; + qCWarning(WARNING, "Networking error during receive: %s", generalized_strerror(errcode)); + return false; + } + return static_cast(amountReceived); + } + + QT3DSU32 nonBlockingRead(NVDataRef data) override + { + if (m_Connected == false) + return 0; + size_t amountReceived = 0; + int errcode = socket_recv(&m_Socket, reinterpret_cast(data.begin()), data.size(), + &amountReceived, 0); + if (is_socket_error(errcode)) { + m_Connected = false; + qCWarning(WARNING, "Networking error during receive: %s", + generalized_strerror(errcode)); + return false; + } + return static_cast(amountReceived); + } + + bool connected() override { return m_Connected; } + + void shutdown() override + { + if (m_Connected) { + socket_shutdown(&m_Socket, 2); + m_Connected = false; + } + } +}; + +struct FileSocketStreamImpl : public SocketStream +{ + NVFoundationBase &m_Foundation; + CFileSeekableIOStream m_Stream; + FileOpenFlags m_FileFlags; + bool m_Connected; + QT3DSI32 mRefCount; + + FileSocketStreamImpl(NVFoundationBase &fnd, const char *fname, FileOpenFlags fileFlags) + : m_Foundation(fnd) + , m_Stream(fname, fileFlags) + , m_FileFlags(fileFlags) + , m_Connected(false) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + bool IsOpen() { return m_Connected && m_Stream.IsOpen(); } + + QT3DSU32 Read(NVDataRef data) override + { + if (IsOpen()) { + QT3DSU32 retval = m_Stream.Read(data); + if (retval < data.size()) + m_Connected = false; + return retval; + } + + return 0; + } + + bool Write(NVConstDataRef data) override + { + bool canWrite = m_FileFlags & FileOpenFlagValues::Write; + if (IsOpen() && canWrite) { + m_Stream.Write(data); + return true; + } + return false; + } + + void setTimeout(QT3DSU32) override {} + + QT3DSU32 nonBlockingRead(NVDataRef data) override { return Read(data); } + + bool connected() override { return m_Connected; } + + void shutdown() override { m_Connected = false; } +}; + +struct SocketServerImpl : public SocketServer +{ + NVScopedRefCounted m_SocketCore; + NVFoundationBase &m_Foundation; + t_socket m_Socket; + int m_Port; + QT3DSU32 m_Timeout; + QT3DSI32 mRefCount; + SocketServerImpl(SocketSystemCore &core, NVFoundationBase &fnd, t_socket s, int port) + : m_SocketCore(core) + , m_Foundation(fnd) + , m_Socket(s) + , m_Port(port) + , m_Timeout(10000) + , mRefCount(0) + { + } + + ~SocketServerImpl() { socket_destroy(&m_Socket); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + int port() override { return m_Port; } + + void setTimeout(QT3DSU32 milliseconds) override { m_Timeout = milliseconds; } + + NVScopedRefCounted nextClient() override + { + SA daddr; + memset(&daddr, 0, sizeof(daddr)); + t_socket new_socket; + int errcode = socket_accept(&m_Socket, &new_socket, NULL, NULL, m_Timeout); + + if (is_socket_error(errcode)) { + return NVScopedRefCounted(); + } else if (errcode == IO_DONE) { + return QT3DS_NEW(m_Foundation.getAllocator(), + SocketStreamImpl)(*m_SocketCore, m_Foundation, new_socket, daddr); + } + return NVScopedRefCounted(); + } +}; + +struct SocketSystemImpl : public SocketSystem +{ + NVScopedRefCounted m_SocketCore; + NVFoundationBase &m_Foundation; + QT3DSI32 mRefCount; + SocketSystemImpl(SocketSystemCore &core, NVFoundationBase &fnd) + : m_SocketCore(core) + , m_Foundation(fnd) + , mRefCount(0) + + { + } + ~SocketSystemImpl() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + NVScopedRefCounted createStream(const char *host, QT3DSI32 port, + QT3DSU32 timeoutMilliseconds) override + { + t_socket newSocket(SOCKET_INVALID); + int errcode = socket_create(&newSocket, PF_INET, SOCK_STREAM, 0); + if (is_socket_error(errcode)) { + qCWarning(WARNING, "Error during connect: %s", generalized_strerror(errcode)); + return NVScopedRefCounted(); + } + SA remoteAddr; + memset(&remoteAddr, 0, sizeof(SA)); + errcode = inet_tryconnect(&newSocket, host, (unsigned short)port, timeoutMilliseconds, + &remoteAddr); + if (is_socket_error(errcode)) { + qCWarning(WARNING, "Error during connect: %s", generalized_strerror(errcode)); + return NVScopedRefCounted(); + } else if (errcode == IO_DONE) { + return QT3DS_NEW(m_Foundation.getAllocator(), + SocketStreamImpl)(*m_SocketCore, m_Foundation, newSocket, remoteAddr); + } + return NVScopedRefCounted(); + } + + NVScopedRefCounted createServer(QT3DSI32 port) override + { + t_socket newSocket(SOCKET_INVALID); + int errcode = socket_create(&newSocket, PF_INET, SOCK_STREAM, 0); + if (is_socket_error(errcode)) { + qCWarning(WARNING, "Error during create server create socket: %s", + generalized_strerror(errcode)); + return NVScopedRefCounted(); + } + errcode = inet_trybind(&newSocket, "*", (unsigned short)port); + if (is_socket_error(errcode)) { + qCWarning(WARNING, "Error during create server bind: %s", + generalized_strerror(errcode)); + return NVScopedRefCounted(); + } else if (errcode == IO_DONE) { + errcode = socket_listen(&newSocket, 10); + if (errcode == IO_DONE) { + return QT3DS_NEW(m_Foundation.getAllocator(), + SocketServerImpl)(*m_SocketCore, m_Foundation, newSocket, port); + } else + qCWarning(WARNING, "Error during create server listen: %s", + generalized_strerror(errcode)); + } + return NVScopedRefCounted(); + } +}; +} + +NVScopedRefCounted +SocketStream::CreateFileStream(NVFoundationBase &fnd, const char *fname, FileOpenFlags flags) +{ + return QT3DS_NEW(fnd.getAllocator(), FileSocketStreamImpl)(fnd, fname, flags); +} + +NVScopedRefCounted SocketSystem::createSocketSystem(NVFoundationBase &fnd) +{ + NVScopedRefCounted theCore = SocketSystemCore::Create(fnd); + if (theCore) { + return QT3DS_NEW(fnd.getAllocator(), SocketSystemImpl)(*theCore, fnd); + } + return NVScopedRefCounted(); +} diff --git a/src/Runtime/Source/foundation/Socket.h b/src/Runtime/Source/foundation/Socket.h new file mode 100644 index 00000000..f561ab83 --- /dev/null +++ b/src/Runtime/Source/foundation/Socket.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_SOCKET_H +#define QT3DS_FOUNDATION_SOCKET_H +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSMemoryBuffer.h" + +namespace qt3ds { + +class NVFoundationBase; +namespace foundation { + + class SocketStream : public IInStream, public IOutStream, public NVRefCounted + { + public: + // set timeout for write and blocking read operations + // Setting to zero makes all operations nonblocking. + virtual void setTimeout(QT3DSU32 milliseconds) = 0; + virtual QT3DSU32 nonBlockingRead(NVDataRef ioBuffer) = 0; + virtual bool connected() = 0; + virtual void shutdown() = 0; + + // Useful to testing systems without going into the issues that a network connection can + // cause. + static NVScopedRefCounted + CreateFileStream(NVFoundationBase &fnd, const char *fname, FileOpenFlags flags); + }; + + class SocketServer : public NVRefCounted + { + public: + virtual int port() = 0; + virtual void setTimeout(QT3DSU32 milliseconds) = 0; + virtual NVScopedRefCounted nextClient() = 0; + }; + + class SocketSystem : public NVRefCounted + { + public: + // timeout of 0 means wait forever + virtual NVScopedRefCounted + createStream(const char *host, QT3DSI32 port, QT3DSU32 timeoutMilliseconds = 10000) = 0; + virtual NVScopedRefCounted createServer(QT3DSI32 port) = 0; + + static NVScopedRefCounted createSocketSystem(NVFoundationBase &fnd); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/StrConvertUTF.h b/src/Runtime/Source/foundation/StrConvertUTF.h new file mode 100644 index 00000000..965867c9 --- /dev/null +++ b/src/Runtime/Source/foundation/StrConvertUTF.h @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_RENDER_STR_CONVERT_UTF_H +#define QT3DS_RENDER_STR_CONVERT_UTF_H +#include +#include "foundation/ConvertUTF.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSSimpleTypes.h" + +namespace qt3ds { +namespace foundation { + + using namespace qt3ds; + template + struct ConverterType + { + }; + template <> + struct ConverterType + { + typedef UTF8 TConverterType; + }; + template <> + struct ConverterType + { + typedef UTF16 TConverterType; + }; + template <> + struct ConverterType + { + typedef UTF32 TConverterType; + }; + + template + struct WCharType + { + }; + + template <> + struct WCharType<2> + { + typedef char16_t TCharType; + }; + + template <> + struct WCharType<4> + { + typedef char32_t TCharType; + }; + + typedef WCharType TWCharEASTLConverter; + + template + struct UTFConversionSelector + { + }; + + template <> + struct UTFConversionSelector + { + static ConversionResult Convert(const UTF8 **sourceStart, const UTF8 *sourceEnd, + UTF16 **targetStart, UTF16 *targetEnd, + ConversionFlags flags) + { + return Q3DSConvertUTF8toUTF16(sourceStart, sourceEnd, targetStart, targetEnd, flags); + } + }; + + template <> + struct UTFConversionSelector + { + static ConversionResult Convert(const UTF8 **sourceStart, const UTF8 *sourceEnd, + UTF32 **targetStart, UTF32 *targetEnd, + ConversionFlags flags) + { + return Q3DSConvertUTF8toUTF32(sourceStart, sourceEnd, targetStart, targetEnd, flags); + } + }; + template <> + struct UTFConversionSelector + { + static ConversionResult Convert(const UTF16 **sourceStart, const UTF16 *sourceEnd, + UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) + { + return Q3DSConvertUTF16toUTF8(sourceStart, sourceEnd, targetStart, targetEnd, flags); + } + }; + template <> + struct UTFConversionSelector + { + static ConversionResult Convert(const UTF16 **sourceStart, const UTF16 *sourceEnd, + UTF32 **targetStart, UTF32 *targetEnd, + ConversionFlags flags) + { + return Q3DSConvertUTF16toUTF32(sourceStart, sourceEnd, targetStart, targetEnd, flags); + } + }; + template <> + struct UTFConversionSelector + { + static ConversionResult Convert(const UTF32 **sourceStart, const UTF32 *sourceEnd, + UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) + { + return Q3DSConvertUTF32toUTF8(sourceStart, sourceEnd, targetStart, targetEnd, flags); + } + }; + template <> + struct UTFConversionSelector + { + static ConversionResult Convert(const UTF32 **sourceStart, const UTF32 *sourceEnd, + UTF16 **targetStart, UTF16 *targetEnd, + ConversionFlags flags) + { + return Q3DSConvertUTF32toUTF16(sourceStart, sourceEnd, targetStart, targetEnd, flags); + } + }; + + // Convert into an EASTL string type. + // inSrcLen may be zero in which case we analyze the string looking for the zero element. + template + bool ConvertUTF(const TSrcType *inSrc, size_t inSrcLen, + eastl::basic_string &outString) + { + typedef typename ConverterType::TConverterType TDestUTFType; + typedef typename ConverterType::TConverterType TSrcUTFType; + if (inSrc == 0 || *inSrc == 0) { + outString.clear(); + return true; + } + + if (inSrcLen == 0) { + // empty loop intentional. + for (const TSrcType *ptr = inSrc; ptr && *ptr; ++ptr, ++inSrcLen) { + } + } + + typename eastl::basic_string::size_type capacity = + outString.capacity(); + if (capacity == 0) + outString.resize((QT3DSU32)inSrcLen * 2); + else + outString.resize(capacity); + + ConversionResult theConversionResult(conversionOK); + TDestUTFType *writePtr = NULL; + do { + writePtr = reinterpret_cast(const_cast(outString.data())); + TDestUTFType *writeEnd(writePtr + outString.size()); + const TSrcUTFType *readPtr(reinterpret_cast(inSrc)); + const TSrcUTFType *readEnd = readPtr + inSrcLen; + theConversionResult = UTFConversionSelector::Convert( + &readPtr, readEnd, &writePtr, writeEnd, lenientConversion); + if (theConversionResult == targetExhausted) { + capacity = outString.capacity() * 2; + outString.resize(capacity); + } + } while (theConversionResult == targetExhausted); + + if (theConversionResult == conversionOK) { + TDestUTFType *writeStart = + reinterpret_cast(const_cast(outString.data())); + outString.resize((QT3DSU32)(writePtr - writeStart)); + return true; + } else { + outString.clear(); + QT3DS_ASSERT(false); + return false; + } + } + +#ifdef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T + + template + bool ConvertWideUTF(const wchar_t *inSrc, size_t inSrcLen, + eastl::basic_string &outString) + { + return ConvertUTF((const TWCharEASTLConverter::TCharType *)inSrc, inSrcLen, outString); + } + +#endif +} +} + +#endif diff --git a/src/Runtime/Source/foundation/StringConversion.h b/src/Runtime/Source/foundation/StringConversion.h new file mode 100644 index 00000000..a55ebb3e --- /dev/null +++ b/src/Runtime/Source/foundation/StringConversion.h @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_STRING_CONVERSION_H +#define QT3DS_FOUNDATION_STRING_CONVERSION_H +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Utils.h" + +namespace qt3ds { +namespace foundation { + + // Template base class so that we can convert items to and from char* and wchar_t* + // representations + template + struct StringConversion + { + bool force_compile_error; + }; + + // Write the char8_t but exlude the null terminator + // Meant to write data model values. + // Memory buffer contains a non-null-terminated + // char8_t string + struct Char8TWriter + { + MemoryBuffer &m_Buffer; + Char8TWriter(MemoryBuffer &buf) + : m_Buffer(buf) + { + } + void Write(const char8_t *value, QT3DSU32 len = 0) + { + if (isTrivial(value)) + return; + if (len == 0) + len = (QT3DSU32)StrLen(value); + m_Buffer.write(value, len); + } + void Write(char8_t value) { m_Buffer.write(value); } + void Write(bool value) { Write(value ? "True" : "False"); } + + // Takes care of long and float + template + void Write(TDataType value) + { + char8_t buf[256]; + QT3DSU32 numWritten = + StringConversion().ToStr(value, NVDataRef(buf, 256)); + if (numWritten) + Write((const char8_t *)buf); + else { + QT3DS_ASSERT(false); + } + } + + template + void Write(NVConstDataRef values, QT3DSU32 grouping = 6, QT3DSU32 tabCount = 0) + { + for (QT3DSU32 idx = 0; idx < values.size(); ++idx) { + if (idx) { + if ((idx % grouping) == 0) { + Write((char8_t)'\n'); + for (QT3DSU32 tabIdx = 0; tabIdx < tabCount; ++tabIdx) + Write((char8_t)'\t'); + } else + Write((char8_t)' '); + } + Write(values[idx]); + } + } + + void Write(NVConstDataRef values, QT3DSU32 ignored = 6) + { + (void)ignored; + if (values.size() && values[0] != 0) { + QT3DSU32 lastItem = values.size() - 1; + if (values[lastItem] == 0) + --lastItem; + Write(values.begin(), lastItem + 1); + } + } + }; + + inline bool IsWhite(char8_t value) + { + return value == '\n' || value == '\r' || value == ' ' || value == '\t'; + } + + // skip until we find whitespace. + inline char8_t *FindNextWhitespace(char8_t *input) + { + if (input == NULL) + return input; + char8_t *marker = input; + // Empty loop intentional + for (; *marker && !IsWhite(*marker); ++marker) + ; + return marker; + } + + // skip until we find something that isn't whitespace. + inline char8_t *FindNextNonWhitespace(char8_t *input) + { + if (input == NULL) + return input; + char8_t *marker = input; + // Empty loop intentional + for (; *marker && IsWhite(*marker); ++marker) + ; + return marker; + } + + // Reading is destructive in the case of floating point lists, so we may + // destroy the incoming string. + // We are assuming the string is null-terminated at end ptr. + struct Char8TReader + { + char8_t *m_StartPtr; + // Buffer used for temp storage + MemoryBuffer &m_Buffer; + Char8TReader(char8_t *sp, MemoryBuffer &buf) + : m_StartPtr(sp) + , m_Buffer(buf) + { + } + void Read(const char8_t *&outPtr) { outPtr = m_StartPtr; } + + template + void Read(TDataType &data) + { + bool success = StringConversion().StrTo(m_StartPtr, data); + QT3DS_ASSERT(success); + (void)success; + } + // Destructive operation because we can't trust + // strtod to do the right thing. On windows, for long strings, + // it calls strlen every operation thus leading to basically N^2 + // behavior + template + void ReadRef(NVDataRef data) + { + QT3DSU32 idx = 0; + m_StartPtr = FindNextNonWhitespace(m_StartPtr); + for (; idx < data.size() && m_StartPtr && *m_StartPtr; ++idx) { + char8_t *nextPtr = FindNextWhitespace(m_StartPtr); + if (nextPtr && *nextPtr) + *nextPtr = 0; + else + nextPtr = NULL; + StringConversion().StrTo(m_StartPtr, data[idx]); + m_StartPtr = nextPtr; + if (m_StartPtr) + m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1); + } + QT3DS_ASSERT(idx == data.size()); + } + + void ReadBuffer(NVConstDataRef &outBuffer) + { + if (m_StartPtr && *m_StartPtr) { + QT3DSU32 len = (QT3DSU32)strlen(m_StartPtr); + outBuffer = NVConstDataRef(m_StartPtr, len + 1); + } + } + + // Destructive operation because we can't trust + // strtod to do the right thing. On windows, for long strings, + // it calls strlen every operation thus leading to basically N^2 + // behavior + template + void ReadBuffer(NVConstDataRef &outBuffer) + { + m_Buffer.clear(); + m_StartPtr = FindNextNonWhitespace(m_StartPtr); + while (m_StartPtr && *m_StartPtr) { + char8_t *nextPtr = FindNextWhitespace(m_StartPtr); + if (nextPtr && *nextPtr) + *nextPtr = 0; + else + nextPtr = NULL; + TDataType temp; + StringConversion().StrTo(m_StartPtr, temp); + m_Buffer.write(temp); + m_StartPtr = nextPtr; + if (m_StartPtr) + m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1); + } + QT3DSU32 numItems = m_Buffer.size() / sizeof(TDataType); + if (numItems) + outBuffer = NVConstDataRef((TDataType *)m_Buffer.begin(), numItems); + else + outBuffer = NVConstDataRef(); + } + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/StringConversionImpl.h b/src/Runtime/Source/foundation/StringConversionImpl.h new file mode 100644 index 00000000..c49c14b4 --- /dev/null +++ b/src/Runtime/Source/foundation/StringConversionImpl.h @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_STRING_CONVERSION_IMPL_H +#define QT3DS_FOUNDATION_STRING_CONVERSION_IMPL_H +#include "foundation/StringConversion.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "EABase/eabase.h" +#include "foundation/StringTable.h" +#include "foundation/Utils.h" +#include "stdlib.h" +#include "stdio.h" //snprintf + +#if !defined EA_PLATFORM_WINDOWS +#define _snprintf snprintf +#endif + +namespace qt3ds { +namespace foundation { + + template <> + struct StringConversion + { + QT3DSU32 ToStr(bool item, NVDataRef buffer) + { + return static_cast( + _snprintf(buffer.begin(), buffer.size(), "%s", item ? "True" : "False")); + } + bool StrTo(const char8_t *buffer, bool &item) + { + if (AreEqualCaseless(buffer, "True")) + item = true; + else + item = false; + return true; + } + }; + + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSU8 item, NVDataRef buffer) + { + return static_cast( + _snprintf(buffer.begin(), buffer.size(), "%hu", static_cast(item))); + } + bool StrTo(const char8_t *buffer, QT3DSU8 &item) + { + item = static_cast(strtoul(buffer, NULL, 10)); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSI8 item, NVDataRef buffer) + { + return static_cast( + _snprintf(buffer.begin(), buffer.size(), "%hd", static_cast(item))); + } + bool StrTo(const char8_t *buffer, QT3DSI8 &item) + { + item = static_cast(strtol(buffer, NULL, 10)); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSU16 item, NVDataRef buffer) + { + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%hu", item)); + } + bool StrTo(const char8_t *buffer, QT3DSU16 &item) + { + item = static_cast(strtoul(buffer, NULL, 10)); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSI16 item, NVDataRef buffer) + { + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%hd", item)); + } + bool StrTo(const char8_t *buffer, QT3DSI16 &item) + { + item = static_cast(strtol(buffer, NULL, 10)); + return true; + } + }; + + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSU32 item, NVDataRef buffer) + { + // hope the buffer is big enough... + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%u", item)); + } + bool StrTo(const char8_t *buffer, QT3DSU32 &item) + { + item = strtoul(buffer, NULL, 10); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSI32 item, NVDataRef buffer) + { + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%d", (int)item)); + } + bool StrTo(const char8_t *buffer, QT3DSI32 &item) + { + item = strtol(buffer, NULL, 10); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSU64 item, NVDataRef buffer) + { +#ifdef _WIN32 + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%I64u", item)); +#else + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%lu", item)); +#endif + } + bool StrTo(const char8_t *buffer, QT3DSU64 &item) + { + item = strtoul(buffer, NULL, 10); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSI64 item, NVDataRef buffer) + { +#ifdef _WIN32 + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%I64d", item)); +#else + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%ld", item)); +#endif + } + bool StrTo(const char8_t *buffer, QT3DSI64 &item) + { + item = strtol(buffer, NULL, 10); + return true; + } + }; + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSF32 item, NVDataRef buffer) + { + return static_cast( + _snprintf(buffer.begin(), buffer.size(), "%g", static_cast(item))); + } + bool StrTo(const char8_t *buffer, QT3DSF32 &item) + { + item = (QT3DSF32)strtod(buffer, NULL); + return true; + } + }; + + template <> + struct StringConversion + { + QT3DSU32 ToStr(QT3DSF64 item, NVDataRef buffer) + { + return static_cast(_snprintf(buffer.begin(), buffer.size(), "%g", item)); + } + bool StrTo(const char8_t *buffer, QT3DSF64 &item) + { + item = strtod(buffer, NULL); + return true; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/foundation/StringTable.cpp b/src/Runtime/Source/foundation/StringTable.cpp new file mode 100644 index 00000000..9e78cfd3 --- /dev/null +++ b/src/Runtime/Source/foundation/StringTable.cpp @@ -0,0 +1,672 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/StringTable.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "EASTL/string.h" +#include "EASTL/sort.h" +#include "foundation/StrConvertUTF.h" +#include "foundation/PreAllocatedAllocator.h" +#include "foundation/SerializationTypes.h" +#include "foundation/Qt3DSMutex.h" + +using namespace qt3ds; +using namespace qt3ds::foundation; +using namespace eastl; + +namespace eastl { +struct SCharAndHash +{ + const char8_t *m_Data; + size_t m_Hash; + // Cache the generated hash code. + SCharAndHash(const char8_t *inData) + : m_Data(inData) + , m_Hash(eastl::hash()(inData)) + { + } + SCharAndHash() + : m_Data(NULL) + , m_Hash(0) + { + } + operator const char *() const { return m_Data; } +}; +template <> +struct hash +{ + size_t operator()(const SCharAndHash &inItem) const { return inItem.m_Hash; } +}; + +template <> +struct equal_to +{ + bool operator()(const SCharAndHash &inLhs, const SCharAndHash &inRhs) const + { + return char_equal_to()(inLhs.m_Data, inRhs.m_Data); + } +}; +} + +void CRegisteredString::Remap(const IStringTable &inTable) +{ + Remap(const_cast(inTable).GetRemapMap()); +} + +void CRegisteredString::Remap(const SStrRemapMap &inMap) +{ + if (IsValid()) { + SStrRemapMap::const_iterator theIter = inMap.find((char8_t *)m_String); + if (theIter != inMap.end()) + m_String = reinterpret_cast(theIter->second); + else { + QT3DS_ASSERT(false); + // Ensure a failure here doesn't *guarantee* a crash somewhere else. + m_String = NULL; + } + } else { + // Indicates an invalid string. + m_String = reinterpret_cast(QT3DS_MAX_U32); + } +} + +void CRegisteredString::Remap(NVDataRef inDataPtr) +{ + size_t theOffset = reinterpret_cast(m_String); + if (theOffset >= QT3DS_MAX_U32) + m_String = ""; + else { + if (theOffset < inDataPtr.size()) + m_String = reinterpret_cast(inDataPtr.begin() + theOffset); + else { + QT3DS_ASSERT(false); + m_String = ""; + } + } +} + +namespace { + +const char16_t g_char16EmptyStr[] = { 0, 0, 0, 0 }; +const char32_t g_char32EmptyStr[] = { 0, 0, 0, 0 }; + +typedef eastl::basic_string TNarrowStr; +typedef eastl::basic_string TWideStr; + +inline bool isTrivialWide(const wchar_t *str) +{ + return str == NULL || *str == 0; +} + +QT3DSU8 *AlignPointer(QT3DSU8 *inStart, QT3DSU8 *inPtr) +{ + QT3DSU32 alignment = sizeof(void *); + size_t numBytes = (size_t)(inPtr - inStart); + QT3DS_ASSERT(inStart < inPtr); + if (numBytes % alignment) + inPtr += alignment - (numBytes % alignment); + return inPtr; +} + +QT3DSU32 Align(QT3DSU32 inValue) +{ + QT3DSU32 alignment = sizeof(void *); + QT3DSU32 leftover = inValue % alignment; + if (leftover) + inValue += alignment - leftover; + return inValue; +} + +// Structure that is written out to the file. +// Directly after this is the string character data. +// TWideStr& inConvertStr +struct SStringFileData +{ + QT3DSU32 m_StartOffset; + QT3DSU32 m_StrLen; + QT3DSU32 m_Handle; + char8_t *m_Str; + SStringFileData(QT3DSU32 len, QT3DSU32 off, QT3DSU32 handle, char8_t *data) + : m_StartOffset(off) + , m_StrLen(len) + , m_Handle(handle) + , m_Str(data) + { + } + SStringFileData() + : m_StartOffset(0) + , m_StrLen(0) + , m_Handle(0) + , m_Str(NULL) + { + } + void Deallocate(NVAllocatorCallback &inAlloc) + { + inAlloc.deallocate(m_Str); + m_Str = NULL; + } + const char8_t *GetNarrow() { return m_Str; } + operator CRegisteredString() const + { + return CRegisteredString::ISwearThisHasBeenRegistered(m_Str); + } + QT3DSU32 EndOffset() const { return m_StartOffset + m_StrLen; } + + // Used only for the lower bound operation to find a given object by offset. + bool operator<(const SStringFileData &inOther) const + { + return m_StartOffset < inOther.m_StartOffset; + } +}; + +struct SCharAndHandle +{ + const char8_t *m_Data; + QT3DSU32 m_Handle; + SCharAndHandle() + : m_Data(NULL) + , m_Handle(0) + { + } + SCharAndHandle(const char8_t *data, QT3DSU32 hdl) + : m_Data(data) + , m_Handle(hdl) + { + } + operator const char *() const { return m_Data; } +}; + +struct SStringFileHeader +{ + QT3DSU32 m_NumStrings; + QT3DSU32 m_NextHandleValue; + // offset to the items of fixed size. Variable sized data is stored + // up front. + QT3DSU32 m_FixedBufferOffset; + SStringFileHeader() + : m_NumStrings(0) + , m_NextHandleValue(0) + , m_FixedBufferOffset(0) + { + } + + SStringFileHeader(QT3DSU32 ns, QT3DSU32 hv, QT3DSU32 fbo) + : m_NumStrings(ns) + , m_NextHandleValue(hv) + , m_FixedBufferOffset(fbo) + { + } +}; + +// This is the core of the string table. +struct SStringFileDataList +{ + typedef nvhash_map TMapType; + typedef nvhash_map THandleMapType; + + mutable SPreAllocatedAllocator m_Allocator; + + // When we load from a file, we get a these items + NVConstDataRef m_DataBlock; + NVConstDataRef> m_HashDataBlockOffset; + NVConstDataRef> m_HandleDataBlockOffset; + + // When we are running normally, this items get mangled + nvvector m_AppendedStrings; + +protected: + // Built roughly on demand + SStrRemapMap m_StrRemapMap; + TMapType m_HashToStrMap; + THandleMapType m_HandleToStrMap; + QT3DSU32 m_NextHandleValue; + +public: + SStringFileDataList(NVAllocatorCallback &inAlloc) + : m_Allocator(inAlloc) + , m_AppendedStrings(inAlloc, "StringTable::m_AppendedStrings") + , m_StrRemapMap(inAlloc, "StringTable::m_StrRemapMap") + , m_HashToStrMap(inAlloc, "StringTable::m_HashToStrMap") + , m_HandleToStrMap(inAlloc, "StringTable::m_HashToStrMap") + , m_NextHandleValue(1) + { + } + ~SStringFileDataList() + { + for (QT3DSU32 idx = 0, end = m_AppendedStrings.size(); idx < end; ++idx) + m_AppendedStrings[idx].Deallocate(m_Allocator); + } + + SStrRemapMap &GetRemapMap() + { + if (m_StrRemapMap.empty()) { + for (QT3DSU32 idx = 0, end = m_DataBlock.size(); idx < end; ++idx) + m_StrRemapMap.insert( + eastl::make_pair(m_DataBlock[idx].m_Str, m_DataBlock[idx].m_StartOffset)); + for (QT3DSU32 idx = 0, end = m_AppendedStrings.size(); idx < end; ++idx) + m_StrRemapMap.insert(eastl::make_pair(m_AppendedStrings[idx].m_Str, + m_AppendedStrings[idx].m_StartOffset)); + } + return m_StrRemapMap; + } + + struct SHashPairComparator + { + bool operator()(const eastl::pair &lhs, + const eastl::pair &rhs) const + { + return lhs.first < rhs.first; + } + }; + + struct SHandlePairComparator + { + bool operator()(const eastl::pair &lhs, + const eastl::pair &rhs) const + { + return lhs.first < rhs.first; + } + }; + + SCharAndHandle DoFindStr(SCharAndHash hashCode) + { + if (isTrivial(hashCode.m_Data)) + return SCharAndHandle(); + TMapType::iterator theFind = m_HashToStrMap.find(hashCode); + if (theFind == m_HashToStrMap.end()) { + SCharAndHandle newStr = FindStrByHash(hashCode); + if (!newStr.m_Data) + newStr = Append(hashCode); + + // It may not be obvious why we have to reset the data member. + // we have to do this so the hashtable keys don't change if the user isn't + // passing in a persistent string. + hashCode.m_Data = newStr; + + theFind = m_HashToStrMap.insert(eastl::make_pair(hashCode, newStr)).first; + m_HandleToStrMap.insert(eastl::make_pair(theFind->second.m_Handle, newStr)); + } + return theFind->second; + } + + const CRegisteredString FindStr(SCharAndHash hashCode) + { + SCharAndHandle result = DoFindStr(hashCode); + if (result.m_Data) + return CRegisteredString::ISwearThisHasBeenRegistered(result.m_Data); + return CRegisteredString(); + } + + const CStringHandle FindStrHandle(SCharAndHash hashCode) + { + SCharAndHandle result = DoFindStr(hashCode); + return CStringHandle::ISwearThisHasBeenRegistered(result.m_Handle); + } + + const CRegisteredString FindStrByHandle(QT3DSU32 handle) + { + if (handle == 0) + return CRegisteredString(); + + THandleMapType::iterator theFind = m_HandleToStrMap.find(handle); + if (theFind == m_HandleToStrMap.end()) { + const char8_t *newStr = FindStrByHandleData(handle); + if (!newStr) + return CRegisteredString(); + theFind = m_HandleToStrMap.insert(eastl::make_pair(handle, newStr)).first; + } + return CRegisteredString::ISwearThisHasBeenRegistered(theFind->second); + } + + void Save(SWriteBuffer &ioBuffer) const + { + // Buffer should be aligned before we get to it. + QT3DS_ASSERT(ioBuffer.size() % 4 == 0); + + QT3DSU32 numStrs = Size(); + size_t bufferBegin = ioBuffer.size(); + SStringFileHeader theHeader; + ioBuffer.write(theHeader); + QT3DSU32 startOffset = ioBuffer.size(); + + eastl::vector> hashToStringIndex; + eastl::vector> handleToStringIndex; + hashToStringIndex.reserve(numStrs); + handleToStringIndex.reserve(numStrs); + WriteStringBlockData(m_DataBlock.begin(), m_DataBlock.end(), ioBuffer, hashToStringIndex, + handleToStringIndex); + WriteStringBlockData(m_AppendedStrings.data(), + m_AppendedStrings.data() + m_AppendedStrings.size(), ioBuffer, + hashToStringIndex, handleToStringIndex); + ioBuffer.align(4); + + QT3DSU32 fixedOffset = ioBuffer.size() - startOffset; + WriteStringBlock(m_DataBlock.begin(), m_DataBlock.end(), ioBuffer); + WriteStringBlock(m_AppendedStrings.data(), + m_AppendedStrings.data() + m_AppendedStrings.size(), ioBuffer); + + // sort by hash code so we can do binary lookups later. + eastl::sort(hashToStringIndex.begin(), hashToStringIndex.end(), SHashPairComparator()); + ioBuffer.write(hashToStringIndex.data(), (QT3DSU32)hashToStringIndex.size()); + + eastl::sort(handleToStringIndex.begin(), handleToStringIndex.end(), + SHandlePairComparator()); + ioBuffer.write(handleToStringIndex.data(), (QT3DSU32)handleToStringIndex.size()); + + SStringFileHeader *fixedOffsetPtr = + reinterpret_cast(ioBuffer.begin() + bufferBegin); + *fixedOffsetPtr = SStringFileHeader(numStrs, m_NextHandleValue, fixedOffset); + } + + void Load(NVDataRef inMemory) + { + QT3DS_ASSERT(m_AppendedStrings.empty()); + m_Allocator.m_PreAllocatedBlock = inMemory; + m_Allocator.m_OwnsMemory = false; + SDataReader theReader(inMemory.begin(), inMemory.end()); + SStringFileHeader theHeader = theReader.LoadRef(); + QT3DSU32 numStrs = theHeader.m_NumStrings; + m_NextHandleValue = theHeader.m_NextHandleValue; + QT3DSU32 fixedOffset = theHeader.m_FixedBufferOffset; + theReader.m_CurrentPtr += fixedOffset; + m_DataBlock = NVConstDataRef( + reinterpret_cast(theReader.m_CurrentPtr), numStrs); + theReader.m_CurrentPtr += sizeof(SStringFileData) * numStrs; + + m_HashDataBlockOffset = NVConstDataRef>( + reinterpret_cast *>(theReader.m_CurrentPtr), numStrs); + theReader.m_CurrentPtr += sizeof(eastl::pair) * numStrs; + + m_HandleDataBlockOffset = NVConstDataRef>( + reinterpret_cast *>(theReader.m_CurrentPtr), numStrs); + + for (QT3DSU32 idx = 0, end = m_DataBlock.size(); idx < end; ++idx) { + SStringFileData &theData = const_cast(m_DataBlock[idx]); + theData.m_Str = reinterpret_cast(inMemory.mData + theData.m_StartOffset); + } + } + +protected: + // When we load from a file, we do not put every string into the hash because building + // hashtables takes + // time. We only put them into the hash on demand; this avoids building a giant hashtable upon + // load. + // and since in general we do not need to lookup all hash values again it avoids building the + // hashtable + // in general. + SCharAndHandle FindStrByHash(SCharAndHash hashCode) const + { + const eastl::pair *iter = + eastl::lower_bound(m_HashDataBlockOffset.begin(), m_HashDataBlockOffset.end(), + eastl::make_pair(hashCode.m_Hash, (QT3DSU32)0), SHashPairComparator()); + + for (; iter != m_HashDataBlockOffset.end() && iter->first == hashCode.m_Hash; ++iter) { + if (AreEqual(m_DataBlock[iter->second].m_Str, hashCode.m_Data)) + return SCharAndHandle(m_DataBlock[iter->second].m_Str, + m_DataBlock[iter->second].m_Handle); + } + return SCharAndHandle(); + } + + const char8_t *FindStrByHandleData(QT3DSU32 handle) const + { + const eastl::pair *iter = + eastl::lower_bound(m_HandleDataBlockOffset.begin(), m_HandleDataBlockOffset.end(), + eastl::make_pair(handle, (QT3DSU32)0), SHandlePairComparator()); + + if (iter != m_HandleDataBlockOffset.end() && iter->first == handle + && m_DataBlock[iter->second].m_Handle == handle) + return m_DataBlock[iter->second].m_Str; + return NULL; + } + + void WriteStringBlockData(const SStringFileData *begin, const SStringFileData *end, + SWriteBuffer &ioBuffer, + eastl::vector> &ioHashToStringIndex, + eastl::vector> &ioHandleToStringIndex) const + { + for (const SStringFileData *iter = begin; iter != end; ++iter) { + size_t idx = ioHashToStringIndex.size(); + SCharAndHash theHash(iter->m_Str); + ioHashToStringIndex.push_back(eastl::make_pair(theHash.m_Hash, (QT3DSU32)idx)); + ioHandleToStringIndex.push_back(eastl::make_pair(iter->m_Handle, (QT3DSU32)idx)); + ioBuffer.write(iter->m_Str, iter->m_StrLen); + } + } + + void WriteStringBlock(const SStringFileData *begin, const SStringFileData *end, + SWriteBuffer &ioBuffer) const + { + for (const SStringFileData *iter = begin; iter != end; ++iter) + ioBuffer.write(*iter); + } + + SCharAndHandle Append(SCharAndHash inStrHash) + { + if (isTrivial(inStrHash.m_Data)) + return SCharAndHandle(); + + const char8_t *inStr(inStrHash.m_Data); + QT3DSU32 len = (QT3DSU32)strlen(inStr) + 1; + char8_t *newStr = (char8_t *)m_Allocator.allocate(len, "StringData", __FILE__, __LINE__); + memCopy(newStr, inStr, len); + + // We write the number of strings to the file just after the header. + QT3DSU32 theOffset = sizeof(SStringFileHeader); + if (Size()) + theOffset = Back().EndOffset(); + + QT3DSU32 handleValue = m_NextHandleValue; + ++m_NextHandleValue; + m_AppendedStrings.push_back(SStringFileData(len, theOffset, handleValue, newStr)); + + // Only add to the str map if necessary because building it could be expensive. + if (m_StrRemapMap.empty() == false) + m_StrRemapMap.insert(eastl::make_pair(newStr, theOffset)); + + return SCharAndHandle(newStr, handleValue); + } + // precondition is that size != 0 + const SStringFileData &Back() const + { + QT3DS_ASSERT(Size()); + + if (m_AppendedStrings.size()) { + return m_AppendedStrings.back(); + } else { + return m_DataBlock[m_DataBlock.size() - 1]; + } + } + + QT3DSU32 Size() const { return static_cast(m_AppendedStrings.size() + m_DataBlock.size()); } +}; + +struct SStringTableMutexScope +{ + Mutex *m_Mutex; + SStringTableMutexScope(Mutex *inM) + : m_Mutex(inM) + { + if (m_Mutex) + m_Mutex->lock(); + } + ~SStringTableMutexScope() + { + if (m_Mutex) + m_Mutex->unlock(); + } +}; + +#define STRING_TABLE_MULTITHREADED_METHOD SStringTableMutexScope __locker(m_MultithreadMutex) + +class StringTable : public IStringTable +{ + typedef nvhash_map TMapType; + typedef nvhash_map TNarrowToWideMapType; + SStringFileDataList m_FileData; + NVAllocatorCallback &m_Allocator; + TNarrowToWideMapType m_StrWideMap; + volatile QT3DSI32 mRefCount; // fnd's naming convention + eastl::basic_string m_ConvertBuffer; + TWideStr m_WideConvertBuffer; + Mutex m_MultithreadMutexBacker; + Mutex *m_MultithreadMutex; + // Data that will be written out to the file. + +public: + StringTable(NVAllocatorCallback &alloc) + : m_FileData(alloc) + , m_Allocator(m_FileData.m_Allocator) + , m_StrWideMap(alloc, "StringTable::m_StrWideMap") + , mRefCount(0) + , m_ConvertBuffer(ForwardingAllocator(alloc, "StringTable::m_ConvertBuffer")) + , m_WideConvertBuffer(ForwardingAllocator(alloc, "StringTable::m_WideConvertBuffer")) + , m_MultithreadMutexBacker(alloc) + , m_MultithreadMutex(NULL) + { + } + + virtual ~StringTable() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_FileData.m_Allocator.m_Allocator) + + void EnableMultithreadedAccess() override { m_MultithreadMutex = &m_MultithreadMutexBacker; } + + void DisableMultithreadedAccess() override { m_MultithreadMutex = NULL; } + + CRegisteredString RegisterStr(Qt3DSBCharPtr str) override + { + STRING_TABLE_MULTITHREADED_METHOD; + if (isTrivial(str)) + return CRegisteredString(); + return m_FileData.FindStr(str); + } + + // utf-16->utf-8 + CRegisteredString RegisterStr(const char16_t *str) override + { + STRING_TABLE_MULTITHREADED_METHOD; + qt3ds::foundation::ConvertUTF(str, 0, m_ConvertBuffer); + return RegisterStr(m_ConvertBuffer.c_str()); + } + // utf-32->utf-8 + CRegisteredString RegisterStr(const char32_t *str) override + { + STRING_TABLE_MULTITHREADED_METHOD; + qt3ds::foundation::ConvertUTF(str, 0, m_ConvertBuffer); + return RegisterStr(m_ConvertBuffer.c_str()); + } + + CRegisteredString RegisterStr(const wchar_t *str) override + { + STRING_TABLE_MULTITHREADED_METHOD; + if (isTrivialWide(str)) + return CRegisteredString(); + qt3ds::foundation::ConvertUTF( + reinterpret_cast(str), 0, + m_ConvertBuffer); + return RegisterStr(m_ConvertBuffer.c_str()); + } + + CStringHandle GetHandle(Qt3DSBCharPtr str) override + { + STRING_TABLE_MULTITHREADED_METHOD; + return m_FileData.FindStrHandle(str); + } + + CRegisteredString HandleToStr(QT3DSU32 strHandle) override + { + STRING_TABLE_MULTITHREADED_METHOD; + return m_FileData.FindStrByHandle(strHandle); + } + + const wchar_t *GetWideStr(CRegisteredString theStr) + { + STRING_TABLE_MULTITHREADED_METHOD; + eastl::pair pair_iter = m_StrWideMap.insert( + eastl::make_pair(theStr, TWideStr(ForwardingAllocator(m_Allocator, "WideString")))); + if (pair_iter.second) + qt3ds::foundation::ConvertUTF(theStr.c_str(), 0, pair_iter.first->second); + return reinterpret_cast(pair_iter.first->second.c_str()); + } + + const wchar_t *GetWideStr(Qt3DSBCharPtr src) override + { + STRING_TABLE_MULTITHREADED_METHOD; + if (isTrivial(src)) + return L""; + return GetWideStr(RegisterStr(src)); + } + + const wchar_t *GetWideStr(const wchar_t *str) override + { + STRING_TABLE_MULTITHREADED_METHOD; + if (isTrivialWide(str)) + return L""; + qt3ds::foundation::ConvertUTF( + reinterpret_cast(str), 0, + m_ConvertBuffer); + return GetWideStr(RegisterStr(m_ConvertBuffer.c_str())); + } + + const SStrRemapMap &GetRemapMap() override { return m_FileData.GetRemapMap(); } + + NVAllocatorCallback &GetAllocator() override { return m_FileData.m_Allocator.m_Allocator; } + + // Save to a block of memory. It is up the callers to deallocate using allocator + // from GetAllocator(). Returns a remap map that takes existing strings and changes their + // address such that they are offsets into the block of memory where this object + // started saving. Returns a map that converts registered strings into offsets of the + // written buffer. + void Save(SWriteBuffer &ioBuffer) const override + { + STRING_TABLE_MULTITHREADED_METHOD; + m_FileData.Save(ioBuffer); + } + + // Load all the strings from inMemory. inMemory is not freed by this object + // Finally, you will need to take inMemory and call remap on all strings + // from offsets back into their correct address into inMemory. + void Load(qt3ds::foundation::NVDataRef inMemory) override + { + STRING_TABLE_MULTITHREADED_METHOD; + m_FileData.Load(inMemory); + } +}; +} + +const char16_t *char16EmptyStr = g_char16EmptyStr; +const char32_t *char32EmptyStr = g_char32EmptyStr; + +IStringTable &IStringTable::CreateStringTable(NVAllocatorCallback &alloc) +{ + return *QT3DS_NEW(alloc, StringTable)(alloc); +} diff --git a/src/Runtime/Source/foundation/StringTable.h b/src/Runtime/Source/foundation/StringTable.h new file mode 100644 index 00000000..79529467 --- /dev/null +++ b/src/Runtime/Source/foundation/StringTable.h @@ -0,0 +1,291 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_STRING_TABLE_H +#define QT3DS_RENDER_STRING_TABLE_H + +#if defined(_WIN32) || defined(__QNXNTO__) +#include +#ifndef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T +#define WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T +#endif +#endif +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAllocator.h" +#include "EASTL/functional.h" +#include "EABase/eabase.h" //char16_t definition +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSOption.h" + +namespace qt3ds { +namespace foundation { + typedef char8_t Qt3DSBChar; + typedef const char8_t *Qt3DSBCharPtr; + class IStringTable; + + // Serialization types, NVRenderSerializationTypes.h + struct SStrRemapMap; + struct SWriteBuffer; + + class CRegisteredString; + + // Discriminated union of either data ref or str table + // used so clients can test serialization without actually saving + // the string table out and rebooting the entire system. + class CStrTableOrDataRef + { + Option> m_DataRef; + IStringTable *m_StrTable; + + public: + CStrTableOrDataRef() + : m_StrTable(NULL) + { + } + CStrTableOrDataRef(NVDataRef inData) + : m_DataRef(inData) + { + } + CStrTableOrDataRef(IStringTable &inStrTable) + : m_StrTable(&inStrTable) + { + } + CStrTableOrDataRef(const CStrTableOrDataRef &inOther) + : m_DataRef(inOther.m_DataRef) + , m_StrTable(inOther.m_StrTable) + { + } + CStrTableOrDataRef &operator=(const CStrTableOrDataRef &inOther) + { + m_DataRef = inOther.m_DataRef; + m_StrTable = inOther.m_StrTable; + return *this; + } + bool HasStrTable() const { return m_StrTable != NULL; } + bool HasDataRef() const { return m_DataRef.hasValue(); } + NVDataRef GetDataRef() const { return *m_DataRef; } + IStringTable *GetStringTable() const + { + QT3DS_ASSERT(m_StrTable); + return m_StrTable; + } + }; + + // String that can only be constructed from strings in the string table. + // These strings are valid utf-8 strings + class CRegisteredString + { + Qt3DSBCharPtr m_String; + + public: + CRegisteredString() + : m_String("") + { + } + CRegisteredString(const CRegisteredString &inOther) + : m_String(inOther.m_String) + { + } + CRegisteredString &operator=(const CRegisteredString &inOther) + { + m_String = inOther.m_String; + return *this; + } + + bool operator==(const CRegisteredString &inStr) const { return m_String == inStr.m_String; } + // If you use this in a real map then you will get them sorted roughly by the correct + // order. + bool operator<(const char *inStr) const + { + // Ensure non-null strings to strcmp. + const char *myStr = m_String ? m_String : ""; + inStr = inStr ? inStr : ""; + int answer; + while (*myStr && *inStr) { + answer = *inStr - *myStr; + if (answer) + return answer < 0; + ++myStr; + ++inStr; + } + answer = *inStr - *myStr; + return answer < 0; + } + size_t hash() const { return eastl::hash()(reinterpret_cast(m_String)); } + operator Qt3DSBCharPtr() const { return c_str(); } + Qt3DSBCharPtr c_str() const { return m_String ? m_String : ""; } + bool IsValid() const { return m_String && *m_String; } + + // If this string is in the map, changes it to the map value. + void Remap(const SStrRemapMap &inMap); + + void Remap(const IStringTable &inTable); + + // Using m_String as an offset, if possible remap into + // inDataPtr's block of memory + void Remap(NVDataRef inDataPtr); + + void Remap(const CStrTableOrDataRef &inRef) + { + if (inRef.HasDataRef()) + Remap(inRef.GetDataRef()); + else if (inRef.HasStrTable()) + Remap(*inRef.GetStringTable()); + else { + QT3DS_ASSERT(false); + } + } + + static CRegisteredString ISwearThisHasBeenRegistered(Qt3DSBCharPtr str) + { + CRegisteredString retval; + retval.m_String = str; + return retval; + } + }; + + class IStringTable; + + class CStringHandle + { + QT3DSU32 m_Data; + + CStringHandle(QT3DSU32 hdl) + : m_Data(hdl) + { + } + + public: + CStringHandle() + : m_Data(0) + { + } + CStringHandle(const CStringHandle &other) + : m_Data(other.m_Data) + { + } + CStringHandle &operator=(const CStringHandle &other) + { + m_Data = other.m_Data; + return *this; + } + bool IsValid() const { return m_Data != 0; } + QT3DSU32 handle() const { return m_Data; } + inline const char8_t *c_str(IStringTable &strTable) const; + operator QT3DSU32() const { return m_Data; } + static CStringHandle ISwearThisHasBeenRegistered(QT3DSU32 strHandle) + { + return CStringHandle(strHandle); + } + }; + + // String table stores strings in utf-8 format and does valid utf-16,utf-32 -> utf-8 + // also converts utf8 -> either utf-32 or utf-16, depending on sizeof( wchar_t ) if + // requested. + // UICStrConvertUTF.h + // Also generates offsets that are consistent so clients can convert their strings + // to offsets during save and convert from offset to string during load regardless + // of if they load before or after this table. + class QT3DS_AUTOTEST_EXPORT IStringTable : public NVRefCounted + { + public: + // default state is for multithreaded access to be disabled. + // remember to implement in CNullStringManager in UICTestPresentation.hxx + virtual void EnableMultithreadedAccess() = 0; + virtual void DisableMultithreadedAccess() = 0; + + virtual CRegisteredString RegisterStr(Qt3DSBCharPtr str) = 0; + // utf-16->utf-8 + virtual CRegisteredString RegisterStr(const char16_t *str) = 0; + // utf-32->utf-8 + virtual CRegisteredString RegisterStr(const char32_t *str) = 0; + + virtual CStringHandle GetHandle(Qt3DSBCharPtr str) = 0; + virtual CRegisteredString HandleToStr(QT3DSU32 strHandle) = 0; + + virtual CRegisteredString RegisterStr(const wchar_t *str) = 0; + + virtual const wchar_t *GetWideStr(Qt3DSBCharPtr src) = 0; + virtual const wchar_t *GetWideStr(const wchar_t *str) = 0; + + Qt3DSBCharPtr GetNarrowStr(const wchar_t *src) { return RegisterStr(src); } + Qt3DSBCharPtr GetNarrowStr(Qt3DSBCharPtr src) { return RegisterStr(src); } + + // The string table maintains a map that will tell clients where their strings will be + // in terms of offsets into the data that the string table writes. + // This map will change each time a new string is added to the string table. + // Conversion from string -> data offset. + virtual const SStrRemapMap &GetRemapMap() = 0; + + virtual NVAllocatorCallback &GetAllocator() = 0; + + // Save to a block of memory. It is up the callers to deallocate using allocator + // from GetAllocator(). Returns a remap map that takes existing strings and changes their + // address such that they are offsets into the block of memory where this object + // started saving. Returns a map that converts registered strings into offsets of the + // written buffer. + virtual void Save(SWriteBuffer &ioBuffer) const = 0; + + // Load all the strings from inMemory. inMemory is not freed by this object + // Finally, you will need to take inMemory and call remap on all strings + // from offsets back into their correct address into inMemory. + virtual void Load(qt3ds::foundation::NVDataRef inMemory) = 0; + + static IStringTable &CreateStringTable(NVAllocatorCallback &alloc); + }; + + inline const char8_t *CStringHandle::c_str(IStringTable &strTable) const + { + return strTable.HandleToStr(m_Data); + } +} +} + +// eastl extensions to allow easy hashtable creation using string table strings. +namespace eastl { + +template <> +struct hash +{ + size_t operator()(const qt3ds::foundation::CRegisteredString &str) const { return str.hash(); } +}; + +template <> +struct equal_to +{ + bool operator()(const qt3ds::foundation::CRegisteredString &lhs, + const qt3ds::foundation::CRegisteredString &rhs) const + { + return lhs == rhs; + } +}; +} + +#endif diff --git a/src/Runtime/Source/foundation/TaggedPointer.h b/src/Runtime/Source/foundation/TaggedPointer.h new file mode 100644 index 00000000..aa227250 --- /dev/null +++ b/src/Runtime/Source/foundation/TaggedPointer.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_TAGGED_POINTER_H +#define QT3DS_FOUNDATION_TAGGED_POINTER_H +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace foundation { + + template + struct SPointerTag + { + /* Expected API for runtime RTTI + static CRegisteredString GetTag() { return g_dtype_specific_string; } + */ + }; + + // A pointer tagged with an identifier so we can have generic + // user data that is still somewhat typesafe. + struct STaggedPointer + { + void *m_UserData; + CRegisteredString m_Tag; + STaggedPointer() + : m_UserData(NULL) + { + } + + STaggedPointer(void *inUserData, CRegisteredString inTag) + : m_UserData(inUserData) + , m_Tag(inTag) + { + } + + template + STaggedPointer(TDataType *inType) + : m_UserData(reinterpret_cast(inType)) + , m_Tag(SPointerTag::GetTag()) + { + } + + template + TDataType *DynamicCast() const + { + if (m_Tag == SPointerTag::GetTag()) + return reinterpret_cast(m_UserData); + return NULL; + } + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/ThreadSafeQueue.h b/src/Runtime/Source/foundation/ThreadSafeQueue.h new file mode 100644 index 00000000..462b6d49 --- /dev/null +++ b/src/Runtime/Source/foundation/ThreadSafeQueue.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_FOUNDATION_THREAD_SAFE_QUEUE_H +#define QT3DS_FOUNDATION_THREAD_SAFE_QUEUE_H +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSemaphore.h" +#include "EASTL/vector.h" + +namespace qt3ds { +namespace foundation { + + template + class ThreadSafeQueue + { + public: + static const QT3DSU32 MaxQueue = 0xffffffff; + + protected: + eastl::vector mQueue; + Semaphore mGetSemaphore; + Semaphore mPutSemaphore; + Mutex mMutex; + const QT3DSU32 mMaxCount; + + public: + ThreadSafeQueue(NVAllocatorCallback &alloc, QT3DSU32 maxCount = MaxQueue) + : mMutex(alloc) + , mGetSemaphore(alloc, 0, maxCount) + , mPutSemaphore(alloc, maxCount, maxCount) + , mMaxCount(maxCount) + { + mQueue.clear(); + } + + bool push(const TObjType &obj, QT3DSU32 milliseconds = MaxQueue) + { + if (mPutSemaphore.wait(milliseconds)) { + Mutex::ScopedLock __locker(mMutex); + mQueue.push_back(obj); + mGetSemaphore.post(); + return true; + } + return false; + } + + bool pop(TObjType &obj, QT3DSU32 milliseconds = 0) + { + if (mGetSemaphore.wait(milliseconds)) { + Mutex::ScopedLock __locker(mMutex); + obj = mQueue.back(); + mQueue.pop_back(); + mPutSemaphore.post(); + return true; + } + return false; + } + + bool isFull() + { + Mutex::ScopedLock __locker(mMutex); + return mQueue.size() >= mMaxCount; + } + + bool isEmpty() + { + Mutex::ScopedLock __locker(mMutex); + return mQueue.size() == 0; + } + + void clear() + { + Mutex::ScopedLock __locker(mMutex); + while (!mQueue.empty()) { + if (mGetSemaphore.wait(MaxQueue)) { + mQueue.pop_back(); + mPutSemaphore.post(); + } + } + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/TrackingAllocator.cpp b/src/Runtime/Source/foundation/TrackingAllocator.cpp new file mode 100644 index 00000000..242b0ac0 --- /dev/null +++ b/src/Runtime/Source/foundation/TrackingAllocator.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/TrackingAllocator.h" + +namespace qt3ds { +namespace foundation { + +CAllocator::~CAllocator() +{ + QT3DS_ASSERT(mAllocations.size() == 0); + MemInfo info; + for (PtrToInfoMap::iterator iter = mAllocations.begin(), end = mAllocations.end(); + iter != end; ++iter) { + info = iter->second; + qCCritical(INTERNAL_ERROR, "!!Outstanding allocation of %lu bytes from %s::%d, %s", + info.size, info.file, info.line, info.name ? info.name : ""); + } + QT3DS_UNUSED(info); +} + +} +} diff --git a/src/Runtime/Source/foundation/TrackingAllocator.h b/src/Runtime/Source/foundation/TrackingAllocator.h new file mode 100644 index 00000000..4fd58069 --- /dev/null +++ b/src/Runtime/Source/foundation/TrackingAllocator.h @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_RENDER_ALLOCATOR_H +#define QT3DS_RENDER_ALLOCATOR_H +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSMutex.h" +#include "EASTL/hash_map.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSLogging.h" + +namespace qt3ds { +namespace foundation { + + // The simplest allocator. Performs no alignment nor memory checking. + struct MallocAllocator : public NVAllocatorCallback + { + void *allocate(size_t size, const char *, const char *, int, int = 0) override + { + return malloc(size); + } + void *allocate(size_t size, const char *, const char *, int, size_t, size_t) override + { + return malloc(size); + } + void deallocate(void *ptr) override { free(ptr); } + }; + + struct MemInfo + { + size_t size; + void *originalAddress; + const char *name; + const char *file; + int line; + MemInfo(size_t _size = 0, void *addr = 0, const char *_name = "", const char *_file = "", + int _line = 0) + : size(_size) + , originalAddress(addr) + , name(_name) + , file(_file) + , line(_line) + { + } + }; + + struct FileAndLine + { + const char *mFile; + QT3DSU32 mLine; + FileAndLine(const char *f, QT3DSU32 l) + : mFile(f) + , mLine(l) + { + } + }; +} // namespace foundation +} // namespace qt3ds + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const qt3ds::foundation::FileAndLine &fl) const + { + return hash()((const void *)fl.mFile) ^ hash()(fl.mLine); + } +}; + +template <> +struct equal_to +{ + bool operator()(const qt3ds::foundation::FileAndLine &fl1, + const qt3ds::foundation::FileAndLine &fl2) const + { + size_t fl1File(reinterpret_cast(fl1.mFile)); + size_t fl2File(reinterpret_cast(fl2.mFile)); + + return fl1File == fl2File && fl1.mLine == fl2.mLine; + } +}; +} + +namespace qt3ds { +namespace foundation { + + struct MemInfoAndCount : MemInfo + { + QT3DSU32 mCount; + QT3DSU64 mTotalBytes; + MemInfoAndCount(const MemInfo &info) + : MemInfo(info) + , mCount(1) + , mTotalBytes(info.size) + { + } + void increment(const MemInfo &otherInfo) + { + ++mCount; + mTotalBytes += otherInfo.size; + } + }; + + typedef nvhash_map TFileAndLineMemHash; + + class AllocationCheckPrinter + { + protected: + virtual ~AllocationCheckPrinter() {} + public: + virtual void printMissing(const MemInfoAndCount &item) = 0; + virtual void printIncorrectCount(const MemInfoAndCount &later, + const MemInfoAndCount &earlier) = 0; + }; + + // All allocations are 16 byte aligned. + // Prints out unallocated memory at destruction. + class QT3DS_AUTOTEST_EXPORT CAllocator : public NVAllocatorCallback + { + public: + typedef Mutex TMutexType; + typedef Mutex::ScopedLock TLockType; + typedef nvhash_map PtrToInfoMap; + + private: + MallocAllocator mAlloc; + PtrToInfoMap mAllocations; + PtrToInfoMap mStoredAllocations; + TMutexType mMutex; + + public: + CAllocator() + : mAllocations(mAlloc, "MemInfo") + , mStoredAllocations(mAlloc, "MemInfo") + , mMutex(mAlloc) + { + } + virtual ~CAllocator(); + + void *allocate(size_t size, const char *tn, const char *fl, int ln, int flags) override + { + QT3DS_ASSERT(size); + if (size) { + size += 15; + TLockType locker(mMutex); + void *original = mAlloc.allocate(size, tn, fl, ln, flags); + size_t temp = (size_t)original; + temp = (temp + 15) & (~15); + void *retval = (void *)temp; + mAllocations.insert(eastl::make_pair(retval, MemInfo(size, original, tn, fl, ln))); + return retval; + } + return NULL; + } + void *allocate(size_t size, const char *tn, const char *fl, int ln, size_t, size_t) override + { + return allocate(size, tn, fl, ln, 0); + } + void deallocate(void *ptr) override + { + if (ptr) { + TLockType locker(mMutex); + PtrToInfoMap::iterator entry(mAllocations.find(ptr)); + if (entry != mAllocations.end()) { + mAlloc.deallocate(entry->second.originalAddress); + mAllocations.erase(ptr); + } else { + QT3DS_ASSERT(false); + } + } + } + const PtrToInfoMap &getOutstandingAllocations() const { return mAllocations; } + static void convert(const CAllocator::PtrToInfoMap &map, TFileAndLineMemHash &fl) + { + for (CAllocator::PtrToInfoMap::const_iterator iter = map.begin(), end = map.end(); + iter != end; ++iter) { + const MemInfo &info(iter->second); + FileAndLine flKey(info.file, info.line); + TFileAndLineMemHash::const_iterator find(fl.find(flKey)); + if (find == fl.end()) + fl.insert(eastl::make_pair(flKey, MemInfoAndCount(info))); + else + const_cast(find->second).increment(info); + } + } + static void copyMap(const CAllocator::PtrToInfoMap &map1, CAllocator::PtrToInfoMap &map2) + { + for (CAllocator::PtrToInfoMap::const_iterator iter = map1.begin(), end = map1.end(); + iter != end; ++iter) { + map2.insert(eastl::make_pair(iter->first, iter->second)); + } + } + + static void printDiffs(const TFileAndLineMemHash &fl1, const TFileAndLineMemHash &fl2, + AllocationCheckPrinter &printer) + { + using namespace std; + for (TFileAndLineMemHash::const_iterator iter = fl1.begin(), end = fl1.end(); + iter != end; ++iter) { + TFileAndLineMemHash::const_iterator entry = fl2.find(iter->first); + if (entry != fl2.end()) { + printer.printMissing(iter->second); + } else if (iter->second.mCount > entry->second.mCount) { + printer.printIncorrectCount(iter->second, entry->second); + } + } + } + + void printAllocationDiff(AllocationCheckPrinter &printer) + { + TFileAndLineMemHash map1fl(mAlloc, "printAllocationDiff"); + TFileAndLineMemHash map2fl(mAlloc, "printAllocationDiff"); + convert(mStoredAllocations, map1fl); + convert(mAllocations, map2fl); + printDiffs(map2fl, map1fl, printer); + } + void storeAllocations() + { + mStoredAllocations.clear(); + copyMap(mAllocations, mStoredAllocations); + } + bool hasStoredAllocations() { return mStoredAllocations.size() > 0; } + }; +} +} +#endif diff --git a/src/Runtime/Source/foundation/Utils.h b/src/Runtime/Source/foundation/Utils.h new file mode 100644 index 00000000..33c24004 --- /dev/null +++ b/src/Runtime/Source/foundation/Utils.h @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_UTILS_H +#define QT3DS_RENDER_UTILS_H +#include "EASTL/hash_map.h" +#include "EASTL/hash_set.h" +#include "EASTL/vector.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSMath.h" +#include + +namespace qt3ds { +namespace foundation { + + // Defined in IStringTable.cpp + extern const char16_t *char16EmptyStr; + extern const char32_t *char32EmptyStr; + + inline const char *nonNull(const char *src) { return src == NULL ? "" : src; } + inline bool isTrivial(const char *str) { return str == NULL || *str == 0; } + inline const char16_t *nonNull(const char16_t *src) + { + return src == NULL ? char16EmptyStr : src; + } + inline bool isTrivial(const char16_t *str) { return str == NULL || *str == 0; } + inline const char32_t *nonNull(const char32_t *src) + { + return src == NULL ? char32EmptyStr : src; + } + inline bool isTrivial(const char32_t *str) { return str == NULL || *str == 0; } + + // Note this is safe to call on null strings. + template + inline QT3DSU32 StrLen(const TCharType *inType) + { + QT3DSU32 retval = 0; + while (inType && *inType) { + ++retval; + ++inType; + } + return retval; + } + + template + inline QT3DSI32 Compare(const TCharType *inLhs, const TCharType *inRhs) + { + inLhs = nonNull(inLhs); + inRhs = nonNull(inRhs); + while (*inLhs && *inRhs) { + QT3DSI32 diff = *inLhs - *inRhs; + if (diff) + return diff; + ++inLhs; + ++inRhs; + } + return *inLhs - *inRhs; + } + + template + inline QT3DSI32 CompareCaseless(const TCharType *inLhs, const TCharType *inRhs) + { + inLhs = nonNull(inLhs); + inRhs = nonNull(inRhs); + while (*inLhs && *inRhs) { + QT3DSI32 diff = tolower(*inLhs) - tolower(*inRhs); + if (diff) + return diff; + ++inLhs; + ++inRhs; + } + return *inLhs - *inRhs; + } + + template + inline QT3DSI32 CompareNChars(const TCharType *inLhs, const TCharType *inRhs, QT3DSU32 inNumChars) + { + inLhs = nonNull(inLhs); + inRhs = nonNull(inRhs); + while (*inLhs && *inRhs && inNumChars) { + QT3DSI32 diff = *inLhs - *inRhs; + if (diff) + return diff; + ++inLhs; + ++inRhs; + --inNumChars; + } + if (inNumChars) + return *inLhs - *inRhs; + return 0; + } + + template + bool AreEqual(const TCharType *inLhs, const TCharType *inRhs) + { + return Compare(inLhs, inRhs) == 0; + } + + template + bool AreEqualCaseless(const TCharType *inLhs, const TCharType *inRhs) + { + return CompareCaseless(inLhs, inRhs) == 0; + } + + inline QT3DSU32 IsBitSetInBitmap(NVConstDataRef bitmap, QT3DSU32 entryIndex) + { + QT3DSU32 bitMapIndex = entryIndex / 32; + QT3DSU32 bitIndex = entryIndex % 32; + QT3DSU32 shouldApply = 0; + if (bitMapIndex < bitmap.mSize) + shouldApply = (1 << bitIndex) & bitmap[bitMapIndex]; + return shouldApply; + } + + inline void SetBitInBitmap(nvvector &bitmap, QT3DSU32 entryIndex) + { + QT3DSU32 bitMapIndex = entryIndex / 32; + QT3DSU32 bitIndex = entryIndex % 32; + while (bitmap.size() <= bitMapIndex) + bitmap.push_back(0); + bitmap[bitMapIndex] |= (QT3DSU32)(1 << bitIndex); + } + inline void UnsetBitInBitmap(nvvector &bitmap, QT3DSU32 entryIndex) + { + QT3DSU32 bitMapIndex = entryIndex / 32; + QT3DSU32 bitIndex = entryIndex % 32; + if (bitMapIndex < bitmap.size()) + bitmap[bitMapIndex] &= ~((QT3DSU32)(1 << bitIndex)); + } + +#define CHECK_CONDITION_AND_RETURN_FALSE(cond, errorType, message) \ + if (cond) { \ + m_Foundation.error(errorType, message); \ + QT3DS_ASSERT(false); \ + return false; \ + } +// Returns false if the property type doesn't match the incoming type. +#define CHECK_CONDITION_AND_RETURN(cond, errorType, message) \ + if (cond) { \ + m_Foundation.error(errorType, message); \ + QT3DS_ASSERT(false); \ + } + +#define QT3DS_FOREACH(varname, stop) for (QT3DSU32 varname = 0, end = stop; varname < end; ++varname) + + template + QT3DSU32 GetMapKeysOp(const eastl::hash_map &map, + TBufType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx, TOperator op) + { + QT3DSU32 numItems = static_cast(map.size()); + if (numItems == 0 || bufSize == 0) + return 0; + + startIdx = NVMin(numItems - 1, startIdx); + QT3DSU32 retval = 0; + for (typename eastl::hash_map::const_iterator iter = map.begin(), + end = map.end(); + iter != end && bufSize; ++iter) { + if (startIdx) + --startIdx; + else { + buffer[retval] = op(iter->first); + --bufSize; + ++retval; + } + } + return retval; + } + + struct IdOp + { + template + TDataType operator()(const TDataType &item) + { + return item; + } + }; + + template + QT3DSU32 + GetMapKeys(const eastl::hash_map &map, + TKeyType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx) + { + return GetMapKeysOp(map, buffer, bufSize, startIdx, IdOp()); + } + + struct DerefOp + { + template + TDataType operator()(const TDataType *item) + { + return *item; + } + }; + + template + QT3DSU32 GetMapValues( + const eastl::hash_map &map, + TBufType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx, TOp op) + { + QT3DSU32 numItems = static_cast(map.size()); + if (numItems == 0 || bufSize == 0) + return 0; + + startIdx = NVMin(numItems - 1, startIdx); + QT3DSU32 retval = 0; + for (typename eastl::hash_map::const_iterator iter = map.begin(), + end = map.end(); + iter != end && bufSize; ++iter) { + if (startIdx) + --startIdx; + else { + buffer[retval] = op(iter->second); + --bufSize; + ++retval; + } + } + return retval; + } + + template + QT3DSU32 GetArrayEntries(const nvvector &data, TBufType *buffer, QT3DSU32 bufSize, + QT3DSU32 startIdx) + { + QT3DSU32 numItems = static_cast(data.size()); + if (numItems == 0 || bufSize == 0) + return 0; + + startIdx = NVMin(numItems - 1, startIdx); + QT3DSU32 available = NVMin(numItems - startIdx, bufSize); + QT3DS_FOREACH(idx, available) + buffer[idx] = data[idx + startIdx]; + return available; + } + + template + QT3DSU32 GetDataRefEntries(const NVDataRef &data, TBufType *buffer, QT3DSU32 bufSize, + QT3DSU32 startIdx) + { + QT3DSU32 numItems = static_cast(data.size()); + if (numItems == 0 || bufSize == 0) + return 0; + + startIdx = NVMin(numItems - 1, startIdx); + QT3DSU32 available = NVMin(numItems - startIdx, bufSize); + QT3DS_FOREACH(idx, available) + buffer[idx] = data.mData[idx + startIdx]; + return available; + } + + template + QT3DSU32 GetDataRefEntries(const NVConstDataRef &data, TBufType *buffer, QT3DSU32 bufSize, + QT3DSU32 startIdx) + { + QT3DSU32 numItems = static_cast(data.size()); + if (numItems == 0 || bufSize == 0) + return 0; + + startIdx = NVMin(numItems - 1, startIdx); + QT3DSU32 available = NVMin(numItems - startIdx, bufSize); + QT3DS_FOREACH(idx, available) + buffer[idx] = data.mData[idx + startIdx]; + return available; + } + + template + QT3DSU32 GetHashSetEntries(eastl::hash_set &data, + TKeyType *buffer, QT3DSU32 bufSize, QT3DSU32 startIdx) + { + QT3DSU32 numItems = static_cast(data.size()); + if (numItems == 0 || bufSize == 0) + return 0; + startIdx = NVMin(numItems - 1, startIdx); + QT3DSU32 available = NVMin(numItems - startIdx, bufSize); + QT3DSU32 idx = 0; + for (typename eastl::hash_set::const_iterator + iter = data.begin(), + end = data.end(); + iter != end && idx < available; ++iter, ++idx) { + if (startIdx) { + --startIdx; + continue; + } + buffer[idx] = *iter; + } + return available; + } + + template + void memCopyT(TDataType *dest, const TDataType *src, QT3DSU32 size) + { + memCopy(dest, src, size * sizeof(TDataType)); + } + + template + NVDataRef PtrAtOffset(QT3DSU8 *baseData, QT3DSU32 offset, QT3DSU32 byteSize) + { + return NVDataRef(byteSize ? (TDataType *)(baseData + offset) : NULL, + byteSize / sizeof(TDataType)); + } + + struct char_hasher + { + size_t operator()(const char *item) const { return eastl::hash()(item); } + }; + + struct char_equal_to + { + bool operator()(const char *lhs, const char *rhs) const + { + if (lhs == NULL) + lhs = ""; + if (rhs == NULL) + rhs = ""; + return strcmp(lhs, rhs) == 0; + } + }; + + struct wide_char_hasher + { + size_t operator()(const char16_t *item) const + { + return eastl::hash()(item); + } + }; + + struct wide_char_equal_to + { + bool operator()(const char16_t *lhs, const char16_t *rhs) const + { + if (lhs == NULL) + lhs = reinterpret_cast(L""); + if (rhs == NULL) + rhs = reinterpret_cast(L""); + while (*lhs && *rhs) { + int answer = *lhs - *rhs; + if (answer) + return false; + ++lhs; + ++rhs; + } + return *lhs == *rhs; + } + }; +} +} +#endif diff --git a/src/Runtime/Source/foundation/XML.cpp b/src/Runtime/Source/foundation/XML.cpp new file mode 100644 index 00000000..34840103 --- /dev/null +++ b/src/Runtime/Source/foundation/XML.cpp @@ -0,0 +1,1008 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/XML.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "foundation/IOStreams.h" +#include "foundation/StringConversionImpl.h" +#include "foundation/StrConvertUTF.h" +#include "foundation/StringTable.h" +#include "foundation/Utils.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/hash_map.h" +#include "utf8.h" + +#ifdef QT3DS_VC +#include //output debug string +#endif + +#include + +using namespace qt3ds; +using namespace qt3ds::foundation; +using namespace qt3ds::intrinsics; + +typedef char XML_Char; + +namespace { + +const QT3DSU16 g_BOMMarker = (QT3DSU16)0xFEFF; + +// Some DOM parsing operations are destructive. If you need +// them to not be destructive, then we need to modify +// the reader. Specifically parsing lists of floats, due +// to a bug in strtod, is destructive. +struct SDOMReader : public IDOMReader +{ + SReaderScope m_TopElement; + eastl::vector m_ScopeStack; + NVScopedRefCounted m_Factory; + volatile QT3DSI32 mRefCount; + + SDOMReader(NVAllocatorCallback &inAlloc, SDOMElement &te, NVScopedRefCounted s, + NVScopedRefCounted inFactory) + : IDOMReader(inAlloc, s) + , m_TopElement(&te) + , m_Factory(inFactory) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Factory->GetAllocator()) + + SDOMElement *Current() const { return m_TopElement.m_Element; } + + void PushScope() override { m_ScopeStack.push_back(SReaderScope(m_TopElement)); } + + void PopScope() override + { + if (m_ScopeStack.size()) { + m_TopElement = m_ScopeStack.back(); + m_ScopeStack.pop_back(); + } else + m_TopElement = SReaderScope(); + } + + SReaderScope GetScope() override { return m_TopElement; } + + void SetScope(SReaderScope inScope) override { m_TopElement = inScope; } + + SDOMElement *GetElement() const override { return m_TopElement.m_Element; } + + Option RegisterNS(TXMLCharPtr ns) + { + if (ns) { + return m_StringTable->RegisterStr(ns); + } + return Empty(); + } + + bool UnregisteredAtt(TXMLCharPtr name, TXMLCharPtr &outValue, TXMLCharPtr ns = NULL) override + { + outValue = ""; + SDOMElement *current(Current()); + if (current) { + return current->AttValue(m_StringTable->RegisterStr(name), RegisterNS(ns), outValue); + } else { + QT3DS_ASSERT(false); + } + return false; + } + + bool Att(TXMLCharPtr name, CRegisteredString &outValue, TXMLCharPtr ns = NULL) override + { + const char8_t *unregValue = NULL; + if (UnregisteredAtt(name, unregValue, ns)) { + outValue = m_StringTable->RegisterStr(unregValue); + return true; + } + return false; + } + + QT3DSU32 CountChildren(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) override + { + SDOMElement *elem = Current(); + if (elem == NULL) { + QT3DS_ASSERT(false); + return 0; + } + return elem->GetNumChildren(m_StringTable->RegisterStr(childName), RegisterNS(ns)); + } + + SDOMAttribute *CurrentAtt() + { + if (m_TopElement.m_Attribute) + return m_TopElement.m_Attribute; + return NULL; + } + + SDOMAttribute *GetFirstAttribute() override + { + if (m_TopElement.m_Element) + m_TopElement.m_Attribute = m_TopElement.m_Element->m_Attributes.m_Head; + return m_TopElement.m_Attribute; + } + + SDOMAttribute *GetNextAttribute() override + { + if (m_TopElement.m_Attribute) + m_TopElement.m_Attribute = m_TopElement.m_Attribute->m_NextAttribute; + return CurrentAtt(); + } + + bool MoveToFirstChild(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) override + { + SDOMElement *elem = Current(); + if (elem == NULL) { + QT3DS_ASSERT(false); + return false; + } + SDOMElement *child = elem->FindChild(m_StringTable->RegisterStr(childName), RegisterNS(ns)); + if (child != NULL) { + m_TopElement = child; + return true; + } + return false; + } + + bool MoveToNextSibling(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) override + { + SDOMElement *elem = Current(); + if (elem == NULL) { + QT3DS_ASSERT(false); + return false; + } + SDOMElement *nextSibling = + elem->FindSibling(m_StringTable->RegisterStr(childName), RegisterNS(ns)); + if (nextSibling) { + m_TopElement = nextSibling; + return true; + } + return false; + } + // Leave element means go to its parent. + void Leave() override + { + QT3DS_ASSERT(m_TopElement.m_Element); + if (m_TopElement.m_Element) + m_TopElement = m_TopElement.m_Element->m_Parent; + } + + bool Value(TXMLCharPtr &outValue) override + { + SDOMElement *current(Current()); + if (!current) { + QT3DS_ASSERT(false); + return false; + } + outValue = current->m_Value; + return true; + } + + SDOMElement *GetTopElement() override + { + SDOMElement *current(Current()); + while (current && current->m_Parent) + current = current->m_Parent; + return current; + } + + virtual NVScopedRefCounted GetFactory() { return m_Factory; } +}; + +struct SDOMWriter : public IDOMWriter, public SDOMReader +{ + NVScopedRefCounted m_FactoryPtr; + IDOMFactory &m_Factory; + + SDOMWriter(NVScopedRefCounted inDOMFactory, + NVScopedRefCounted inStringTable, SDOMElement &inTopElem) + : SDOMReader(inDOMFactory->GetAllocator(), inTopElem, inStringTable, *inDOMFactory) + , m_FactoryPtr(inDOMFactory) + , m_Factory(*inDOMFactory) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Factory.GetAllocator()) + + void Begin(TXMLCharPtr inElemName, TXMLCharPtr inNamespace = NULL, int inLine = 0) override + { + if (!m_TopElement.m_Element) { + QT3DS_ASSERT(false); + return; + } + SDOMElement *current(Current()); + SDOMElement *newElement(m_Factory.NextElement(m_StringTable->RegisterStr(inElemName), + m_StringTable->RegisterStr(inNamespace), + inLine)); + current->AppendChild(*newElement); + m_TopElement = newElement; + } + + void Att(TXMLCharPtr name, TXMLCharPtr value, TXMLCharPtr ns, int inLine) override + { + if (!m_TopElement.m_Element) { + QT3DS_ASSERT(false); + return; + } + m_TopElement.m_Element->SetAttributeValue(m_StringTable->RegisterStr(name), RegisterNS(ns), + value, m_Factory, inLine); + } + + void Value(TXMLCharPtr value) override + { + if (!m_TopElement.m_Element) { + QT3DS_ASSERT(false); + return; + } + if (value == NULL) + value = ""; + size_t len = strlen(value); + m_Factory.AppendStrBuf(value, (QT3DSU32)len); + m_TopElement.m_Element->m_Value = m_Factory.FinalizeStrBuf(); + } + + void End() override + { + if (!m_TopElement.m_Element) { + QT3DS_ASSERT(false); + return; + } + Leave(); + } + void RemoveCurrent() override + { + SDOMElement *current(Current()); + if (!current) { + QT3DS_ASSERT(false); + return; + } + if (current->m_Parent) { + m_TopElement = current->m_Parent; + m_TopElement.m_Element->RemoveChild(*current); + } + } + void RemoveAttribute(TXMLCharPtr inItem, TXMLCharPtr inNamespace) override + { + SDOMElement *current(Current()); + if (!current) { + QT3DS_ASSERT(false); + return; + } + current->RemoveAttribute(m_StringTable->RegisterStr(inItem), RegisterNS(inNamespace)); + } + + void MoveBefore(TXMLCharPtr inItem, TXMLCharPtr inSibling, TXMLCharPtr inNs = NULL) override + { + SDOMElement *current(Current()); + if (!current) { + QT3DS_ASSERT(false); + return; + } + + SDOMElement *theItem = + current->FindChild(m_StringTable->RegisterStr(inItem), RegisterNS(inNs)); + SDOMElement *theSibling = + current->FindChild(m_StringTable->RegisterStr(inSibling), RegisterNS(inNs)); + QT3DS_ASSERT(theItem && theSibling); + if (theItem && theSibling) + current->PrependChild(*theItem, theSibling); + } + + // If current has no parent, then we are at the top + // of the tree and we should return 0. Or if there is no + // current. + // If there is one parent, we should return 1. + QT3DSU32 GetTabs() override + { + QT3DSU32 retval = 0; + SDOMElement *current(Current()); + do { + if (current) + current = current->m_Parent; + if (current) + ++retval; + } while (current); + return retval; + } + + SDOMElement *GetTopElement() override { return SDOMReader::GetTopElement(); } + + NVScopedRefCounted GetFactory() override { return m_FactoryPtr; } + + NVAllocatorCallback &GetAllocator() override { return m_Factory.GetAllocator(); } +}; + +struct SimpleXmlWriter +{ + + struct SNameNS + { + TXMLCharPtr name; + TXMLCharPtr ns; + SNameNS(TXMLCharPtr _name = NULL, TXMLCharPtr _ns = NULL) + : name(_name) + , ns(_ns) + { + } + }; + IOutStream &m_Stream; + eastl::vector> m_OpenElements; + bool m_ElementOpen; + char8_t m_PrintBuf[256]; + QT3DSU32 m_Tabs; + eastl::basic_string m_Buffer; + + SimpleXmlWriter(NVAllocatorCallback &inAlloc, IOutStream &stream, QT3DSU32 inTabs = 0) + : m_Stream(stream) + , m_ElementOpen(false) + , m_Tabs(inTabs) + , m_Buffer(ForwardingAllocator(inAlloc, "SimpleXMLWriter::m_Buffer")) + { + } + + void Write(const SNameNS &data) + { + if (data.ns && *data.ns) { + Write(data.ns); + Write(':'); + } + Write(data.name); + } + + void Write(const char8_t *data, QT3DSU32 inLen = 0) + { + if (!isTrivial(data)) { + if (inLen == 0) + inLen = StrLen(data); + m_Stream.Write(data, inLen); + } + } + void BeginWrite() { m_Buffer.clear(); } + void WriteTemp(char8_t data) { m_Buffer.append(1, data); } + void WriteTemp(const char8_t *data) { m_Buffer.append(data); } + void EndWrite() { Write(reinterpret_cast(m_Buffer.c_str()), m_Buffer.size()); } + void Write(char8_t data) { m_Stream.Write(data); } + void Tabs() + { + QT3DS_FOREACH(idx, (m_OpenElements.size() + m_Tabs)) + Write('\t'); + } + void Close(bool newline) + { + if (m_ElementOpen) { + Write(">"); + if (newline) + Write('\n'); + } + m_ElementOpen = false; + } + void Begin(TXMLCharPtr name, TXMLCharPtr ns) + { + Close(true); + Tabs(); + Write('<'); + SNameNS theName(name, ns); + Write(theName); + m_OpenElements.push_back(eastl::pair(theName, false)); + m_ElementOpen = true; + } + TXMLCharPtr ToStr(char8_t val) + { + m_PrintBuf[0] = val; + m_PrintBuf[1] = 0; + return m_PrintBuf; + } + template + TXMLCharPtr ToStr(TDataType val) + { + StringConversion().ToStr(val, NVDataRef(m_PrintBuf, 256)); + return m_PrintBuf; + } + void Att(TXMLCharPtr name, TXMLCharPtr ns, TXMLCharPtr value) + { + QT3DS_ASSERT(m_ElementOpen); + Write(' '); + Write(SNameNS(name, ns)); + + Write("=\""); + size_t valueLen = strlen(nonNull(value)); + TXMLCharPtr start = value; + TXMLCharPtr end = value + valueLen; + TXMLCharPtr last = start; + uint32_t item = 0; + // Write out the data escaping unicode values where necessary + // I am using utf8::internal because it returns an error code and does not through + // exceptions; we don't always know the system we are running on will support or handle + // exceptions gracefully. + for (utf8::internal::utf_error err_code = utf8::internal::validate_next(start, end, item); + last != end && err_code == utf8::internal::UTF8_OK; + err_code = utf8::internal::validate_next(start, end, item)) { + switch (item) { + case '\r': + break; + case '\n': + Write(" "); + break; + case '\t': + Write(" "); + break; + case '<': + Write("<"); + break; + case '>': + Write(">"); + break; + case '"': + Write("""); + break; + case '&': + Write("&"); + break; + default: + m_Stream.Write(NVConstDataRef((const QT3DSU8 *)last, (QT3DSU32)(start - last))); + break; + } + last = start; + } + Write("\""); + } + template + void Att(TXMLCharPtr name, TXMLCharPtr ns, TData value) + { + Att(name, ns, ToStr(value)); + } + + void Value(TXMLCharPtr value) + { + if (!isTrivial(value)) { + Close(false); + size_t valueLen = strlen(nonNull(value)); + TXMLCharPtr start = value; + TXMLCharPtr end = value + valueLen; + TXMLCharPtr last = start; + uint32_t item = 0; + // Write out the data escaping unicode values where necessary + for (utf8::internal::utf_error err_code = + utf8::internal::validate_next(start, end, item); + last != end && err_code == utf8::internal::UTF8_OK; + err_code = utf8::internal::validate_next(start, end, item)) { + switch (item) { + case '<': + Write("<"); + break; + case '>': + Write(">"); + break; + case '&': + Write("&"); + break; + default: + m_Stream.Write(NVConstDataRef((const QT3DSU8 *)last, (QT3DSU32)(start - last))); + break; + } + last = start; + } + m_OpenElements.back().second = true; + } + } + void ChildValue(TXMLCharPtr name, TXMLCharPtr ns, TXMLCharPtr value) + { + Begin(name, ns); + Value(value); + End(); + } + void End(bool newlineAfterClose = true) + { + QT3DS_ASSERT(m_OpenElements.size()); + eastl::pair topElem = m_OpenElements.back(); + m_OpenElements.pop_back(); + if (m_ElementOpen) + Write("/>"); + else { + if (topElem.second == false) + Tabs(); + Write(""); + } + m_ElementOpen = false; + if (newlineAfterClose == true) + Write('\n'); + } +}; + +struct DOMParser +{ + IDOMFactory &m_Factory; + SDOMElement *m_TopElement; + SDOMElement *m_FirstElement; + char8_t m_nsSeparator; + typedef eastl::basic_string TStrType; + TStrType m_NSBuffer; + TStrType m_NameBuffer; + CRegisteredString m_RegName; + CRegisteredString m_RegNS; + SNamespacePairNode *m_FirstPair; + SNamespacePairNode *m_LastPair; + QXmlStreamReader *m_XMLParser; + + DOMParser(IDOMFactory &factory, QXmlStreamReader &parser, char8_t nsSeparator) + : m_Factory(factory) + , m_FirstElement(NULL) + , m_nsSeparator(nsSeparator) + , m_NSBuffer(ForwardingAllocator(factory.GetAllocator(), "DOMParser::m_NSBuffer")) + , m_NameBuffer(ForwardingAllocator(factory.GetAllocator(), "DOMParser::m_NameBuffer")) + , m_FirstPair(NULL) + , m_LastPair(NULL) + , m_XMLParser(&parser) + { + } + + void ParseName(const XML_Char *name) + { + m_NSBuffer.assign(name); + eastl::string::size_type pos = m_NSBuffer.find(m_nsSeparator); + if (pos != TStrType::npos) { + m_NameBuffer.assign(m_NSBuffer.c_str() + pos + 1); + m_NSBuffer.resize(pos); + } else { + m_NameBuffer = m_NSBuffer; + m_NSBuffer.clear(); + // Find the namespace with no abbreviation. + for (SNamespacePairNode *theNode = m_FirstPair; theNode; + theNode = theNode->m_NextNode) { + if (theNode->m_Abbreviation.IsValid() == false) + m_NSBuffer.assign(theNode->m_Namespace.c_str()); + } + } + m_RegName = m_Factory.GetStringTable()->RegisterStr(m_NameBuffer.c_str()); + m_RegNS = m_Factory.GetStringTable()->RegisterStr(m_NSBuffer.c_str()); + } + + struct SimpleXmlErrorHandler : public CXmlErrorHandler + { + void OnXmlError(TXMLCharPtr errorName, int line, int column) override + { + char8_t buffer[1024]; + _snprintf(buffer, 1024, "%s(%d): Xml Error %s on line %d, column %d", __FILE__, + __LINE__, errorName, line, column); +#ifdef QT3DS_VC + OutputDebugStringA(buffer); +#endif + printf("%s\n", buffer); + } + }; + + template + struct SHeaderInStream : public IInStream + { + QT3DSU8 m_Header[THeaderLen]; + IInStream &m_InStream; + QT3DSU32 m_BytesRead; + + SHeaderInStream(IInStream &inStream) + : m_InStream(inStream) + , m_BytesRead(0) + { + } + bool readHeader() + { + QT3DSU32 amountRead = m_InStream.Read(NVDataRef(m_Header, THeaderLen)); + return amountRead == THeaderLen; + } + QT3DSU32 Read(NVDataRef data) override + { + if (data.size() == 0) + return 0; + QT3DSU8 *writePtr(data.begin()); + QT3DSU32 amountToRead(data.size()); + QT3DSU32 amountRead = 0; + if (m_BytesRead < THeaderLen) { + QT3DSU32 headerLeft = NVMin(THeaderLen - m_BytesRead, amountToRead); + memCopy(writePtr, m_Header + m_BytesRead, headerLeft); + writePtr += headerLeft; + amountToRead -= headerLeft; + amountRead += headerLeft; + } + if (amountToRead) + amountRead += m_InStream.Read(NVDataRef(writePtr, amountToRead)); + m_BytesRead += amountRead; + return amountRead; + } + }; + + static eastl::pair + ParseXMLFile(IDOMFactory &factory, IInStream &inStream, CXmlErrorHandler *handler = NULL) + { + SimpleXmlErrorHandler simpleHandler; + if (handler == NULL) + handler = &simpleHandler; + + // look for BOM (Byte-Order-Marker) in the file + // if found, pass in UTF-16 as the format. else + // pass in UTF-8 as the format. + SHeaderInStream theInStream(inStream); + if (theInStream.readHeader() == false) { + QT3DS_ASSERT(false); + return NULL; + } + QT3DSU16 theHeaderData; + memCopy(&theHeaderData, theInStream.m_Header, sizeof(g_BOMMarker)); + + char8_t nsSeparator = '$'; + + if (theHeaderData == g_BOMMarker) + qFatal("UTF-16 files not supported"); + + QXmlStreamReader sreader; + DOMParser domParser(factory, sreader, nsSeparator); + QT3DSU8 dataBuf[2048]; + QT3DSU32 amountRead = 0; + do { + amountRead = theInStream.Read(toDataRef(dataBuf, 2048)); + if (amountRead) { + QByteArray tmp = QByteArray::fromRawData((char*)dataBuf,amountRead); + sreader.addData(tmp); + } + } while (amountRead > 0); + while (!sreader.atEnd()) { + QXmlStreamReader::TokenType token = sreader.readNext(); + if (token == QXmlStreamReader::StartElement) { + domParser.m_Factory.IgnoreStrBuf(); + domParser.ParseName((TXMLCharPtr)sreader.name().toUtf8().data()); + int line = sreader.lineNumber(); + SDOMElement *newElem = + domParser.m_Factory.NextElement(domParser.m_RegName, domParser.m_RegNS, line); + if (domParser.m_FirstElement == NULL) { + domParser.m_FirstElement = newElem; + domParser.m_TopElement = newElem; + } else { + domParser.m_TopElement->AppendChild(*newElem); + domParser.m_TopElement = newElem; + } + const QXmlStreamAttributes& attributes = sreader.attributes(); + for (auto attrib : attributes) { + domParser.ParseName((TXMLCharPtr)attrib.name().toUtf8().data()); + SDOMAttribute *att = + domParser.m_Factory.NextAttribute(domParser.m_RegName, + (TXMLCharPtr)attrib.value() + .toUtf8().data(), + domParser.m_RegNS, line); + newElem->m_Attributes.push_back(*att); + } + } else if (token == QXmlStreamReader::Characters) { + QByteArray text = sreader.text().toUtf8(); + domParser.m_Factory.AppendStrBuf(text.data(), text.length()); + } else if (token == QXmlStreamReader::EndElement) { + domParser.m_TopElement->m_Value = domParser.m_Factory.FinalizeStrBuf(); + domParser.m_TopElement = domParser.m_TopElement->m_Parent; + } + + if (sreader.hasError()) { + TXMLCharPtr error = (TXMLCharPtr)sreader.errorString().toUtf8().data(); + handler->OnXmlError(error, sreader.lineNumber(), sreader.columnNumber()); + return nullptr; + } + + } + return eastl::make_pair(domParser.m_FirstPair, domParser.m_FirstElement); + } +}; + +class SimpleDomFactory : public IDOMFactory +{ + typedef eastl::basic_string TNarrowStr; + NVAllocatorCallback &m_Allocator; + Pool m_ElementPool; + Pool m_AttributePool; + Pool m_NamespaceNodePool; + eastl::vector m_BigStrings; + NVScopedRefCounted m_StringTable; + TNarrowStr m_StringBuilder; + volatile QT3DSI32 mRefCount; + +public: + SimpleDomFactory(NVAllocatorCallback &alloc, NVScopedRefCounted strt) + : m_Allocator(alloc) + , m_StringTable(strt) + , m_StringBuilder(ForwardingAllocator(alloc, "SimpleDomFactory::m_StringBuilder")) + , mRefCount(0) + { + } + + ~SimpleDomFactory() + { + QT3DS_FOREACH(idx, m_BigStrings.size()) + m_Allocator.deallocate(m_BigStrings[idx]); + m_BigStrings.clear(); + } + + NVAllocatorCallback &GetAllocator() override { return m_Allocator; } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Allocator) + + TXMLCharPtr RegisterStr(TXMLCharPtr str) + { + if (str == NULL || *str == 0) + return ""; + return m_StringTable->RegisterStr(str); + } + + virtual void Release() { delete this; } + void AppendStrBuf(TXMLCharPtr str, QT3DSU32 len) override + { + if (len && *str) { + m_StringBuilder.append(str, str + len); + } + } + + // Null terminate what is there and return the buffer. + // This pointer needs to be persistent. + TXMLCharPtr FinalizeStrBuf() override + { + if (m_StringBuilder.size() == 0) + return ""; + QT3DSU32 len = m_StringBuilder.size() + 1; + QT3DSU32 numBytes = len * sizeof(char8_t); + char8_t *newMem = + (char8_t *)m_Allocator.allocate(numBytes, "DOMFactory::ValueStr", __FILE__, __LINE__); + memCopy(newMem, m_StringBuilder.c_str(), numBytes); + m_BigStrings.push_back(newMem); + m_StringBuilder.clear(); + return newMem; + } + void IgnoreStrBuf() override { m_StringBuilder.clear(); } + + SDOMAttribute *NextAttribute(CRegisteredString name, TXMLCharPtr val, + CRegisteredString ns, int inLine) override + { + TXMLCharPtr v(RegisterValue(val)); + SDOMAttribute *att = (SDOMAttribute *)m_AttributePool.allocate(__FILE__, __LINE__); + new (att) SDOMAttribute(name, ns, v, inLine); + return att; + } + + SDOMElement *NextElement(CRegisteredString name, CRegisteredString ns, int inLine) override + { + IgnoreStrBuf(); + SDOMElement *elem = (SDOMElement *)(m_ElementPool.allocate(__FILE__, __LINE__)); + new (elem) SDOMElement(name, ns, inLine); + return elem; + } + + SNamespacePairNode *NextNSPairNode(CRegisteredString ns, CRegisteredString abbr) override + { + return m_NamespaceNodePool.construct(SNamespacePair(ns, abbr), __FILE__, __LINE__); + } + + NVScopedRefCounted GetStringTable() override { return m_StringTable; } +}; +} + +NVScopedRefCounted +IDOMReader::CreateDOMReader(NVAllocatorCallback &inAlloc, SDOMElement &inRootElement, + NVScopedRefCounted inStringTable, + NVScopedRefCounted inFactory) +{ + return QT3DS_NEW(inAlloc, SDOMReader)(inAlloc, inRootElement, inStringTable, inFactory); +} + +eastl::pair, NVScopedRefCounted> +IDOMWriter::CreateDOMWriter(NVScopedRefCounted inFactory, SDOMElement &inRootElement, + NVScopedRefCounted inStringTable) +{ + NVScopedRefCounted writer( + QT3DS_NEW(inFactory->GetAllocator(), SDOMWriter)(inFactory, inStringTable, inRootElement)); + return eastl::make_pair(writer.mPtr, writer.mPtr); +} + +TXMLCharPtr IDOMFactory::RegisterValue(TXMLCharPtr inValue) +{ + if (isTrivial(inValue)) + return ""; + IgnoreStrBuf(); + AppendStrBuf(inValue, (QT3DSU32)strlen(inValue)); + return FinalizeStrBuf(); +} + +NVScopedRefCounted +IDOMFactory::CreateDOMFactory(NVAllocatorCallback &inAlloc, + NVScopedRefCounted inStrTable) +{ + return QT3DS_NEW(inAlloc, SimpleDomFactory)(inAlloc, inStrTable); +} + +void CDOMSerializer::WriteXMLHeader(IOutStream &inStream) +{ + const char8_t *header = "\n"; + QT3DSU32 len = (QT3DSU32)strlen(header); + inStream.Write(header, len); +} + +// Lexigraphically sort the attributes. +struct SAttributeComparator +{ + bool operator()(const SDOMAttribute *lhs, const SDOMAttribute *rhs) + { + int nsCmp = strcmp(lhs->m_Namespace, rhs->m_Namespace); + if (nsCmp) + return nsCmp < 0; + + return strcmp(lhs->m_Name, rhs->m_Name) < 0; + } +}; + +typedef eastl::vector TAttVector; +typedef eastl::hash_map, + eastl::equal_to, ForwardingAllocator> + TNSMap; + +CRegisteredString GetOrCreateNamespaceAbbr(NVAllocatorCallback &inAlloc, CRegisteredString theNs, + TNSMap &inNamespace, TNSMap &inReverseNamespaces, + IStringTable &inStrTable, bool &outCreated) +{ + CRegisteredString abbr; + if (theNs.IsValid()) { + TNSMap::iterator nsIter = inNamespace.find(theNs); + if (nsIter != inNamespace.end()) { + abbr = nsIter->second; + outCreated = false; + } else { + eastl::basic_string theStr( + ForwardingAllocator(inAlloc, "nsBuilderString")); + theStr.assign("a"); + eastl::basic_string theNsStr( + ForwardingAllocator(inAlloc, "nsBuilderString")); + CRegisteredString theNS = inStrTable.RegisterStr(theStr.c_str()); + while (inReverseNamespaces.find(theNS) != inReverseNamespaces.end()) { + for (int idx = 0; + idx < 26 && inReverseNamespaces.find(theNS) == inReverseNamespaces.end(); + ++idx) { + theNsStr = theStr; + theNsStr.append(1, (char8_t)('a' + idx)); + theNS = inStrTable.RegisterStr(theNsStr.c_str()); + } + theStr.append(1, 'a'); + } + inNamespace.insert(eastl::make_pair(theNs, theNS)); + abbr = theNS; + outCreated = true; + } + } + return abbr; +} + +// Write an element with attributes sorted by name so a file diff is effective. +void WriteElement(NVAllocatorCallback &inAlloc, SDOMElement &inElement, SimpleXmlWriter &inWriter, + TAttVector &inAttSorter, TNSMap &inNamespace, TNSMap &inReverseNamespaces, + IStringTable &inStrTable, bool inTrimEmptyElems, bool inWriteXMLNS) +{ + inAttSorter.clear(); + + // We decided that we don't want attribute sorting; the code that adds attributes needs + // to be consistent. + // This element doesn't add anything to the system in this case. + if (inTrimEmptyElems && inElement.m_Attributes.empty() && inElement.m_Children.empty() + && isTrivial(inElement.m_Value)) + return; + + for (TAttributeList::iterator iter = inElement.m_Attributes.begin(), + end = inElement.m_Attributes.end(); + iter != end; ++iter) + inAttSorter.push_back(&(*iter)); + + // Find the namespace for the element + bool createdAbbr = false; + CRegisteredString abbr = GetOrCreateNamespaceAbbr(inAlloc, inElement.m_Namespace, inNamespace, + inReverseNamespaces, inStrTable, createdAbbr); + + inWriter.Begin(inElement.m_Name, abbr); + eastl::basic_string theStr( + ForwardingAllocator(inAlloc, "nsBuilderString")); + if (inWriteXMLNS) { + for (TNSMap::iterator iter = inNamespace.begin(), end = inNamespace.end(); iter != end; + ++iter) { + theStr.assign("xmlns"); + if (iter->second.IsValid()) { + theStr.append(1, ':'); + theStr.append(iter->second.c_str()); + } + inWriter.Att(theStr.c_str(), NULL, iter->first.c_str()); + } + } else if (createdAbbr) { + theStr.assign("xmlns:"); + theStr.append(abbr.c_str()); + inWriter.Att(theStr.c_str(), NULL, inElement.m_Namespace.c_str()); + } + + const char8_t *theLastAttName = 0; + const char8_t *theLastAttNamespace = 0; + for (QT3DSU32 idx = 0, end = inAttSorter.size(); idx < end; ++idx) { + SDOMAttribute *theAtt(inAttSorter[idx]); + if (theAtt->m_Name != theLastAttName || theAtt->m_Namespace != theLastAttNamespace) { + abbr = GetOrCreateNamespaceAbbr(inAlloc, theAtt->m_Namespace, inNamespace, + inReverseNamespaces, inStrTable, createdAbbr); + if (createdAbbr) { + theStr.assign("xmlns:"); + theStr.append(abbr.c_str()); + inWriter.Att(theStr.c_str(), NULL, inElement.m_Namespace.c_str()); + } + + inWriter.Att(theAtt->m_Name, abbr, theAtt->m_Value); + } else { + QT3DS_ASSERT(false); + } + theLastAttName = theAtt->m_Name; + theLastAttNamespace = theAtt->m_Namespace; + } + // Elements can either have children or values but not both at this point. + if (inElement.m_Children.empty() == false) { + for (SDOMElement::TElementChildList::iterator iter = inElement.m_Children.begin(), + end = inElement.m_Children.end(); + iter != end; ++iter) + WriteElement(inAlloc, *iter, inWriter, inAttSorter, inNamespace, inReverseNamespaces, + inStrTable, inTrimEmptyElems, false); + + inWriter.End(); + } else { + if (!isTrivial(inElement.m_Value)) + inWriter.Value(inElement.m_Value); + + inWriter.End(); + } +} + +void CDOMSerializer::Write(NVAllocatorCallback &inAlloc, SDOMElement &inElement, + IOutStream &inStream, IStringTable &inStrTable, + NVConstDataRef inNamespaces, bool inTrimEmptyElements, + QT3DSU32 inTabs, bool inWriteNamespaces) +{ + TAttVector theAttSorter(ForwardingAllocator(inAlloc, "CDOMSerializer::AttributeList")); + TNSMap theNamespaces(ForwardingAllocator(inAlloc, "CDOMSerializer::NamespaceMap")); + TNSMap theReverseNamespaces(ForwardingAllocator(inAlloc, "CDOMSerializer::NamespaceMap")); + for (QT3DSU32 idx = 0, end = inNamespaces.size(); idx < end; ++idx) { + theNamespaces.insert( + eastl::make_pair(inNamespaces[idx].m_Namespace, inNamespaces[idx].m_Abbreviation)); + theReverseNamespaces.insert( + eastl::make_pair(inNamespaces[idx].m_Abbreviation, inNamespaces[idx].m_Namespace)); + } + SimpleXmlWriter writer(inAlloc, inStream, inTabs); + WriteElement(inAlloc, inElement, writer, theAttSorter, theNamespaces, theReverseNamespaces, + inStrTable, inTrimEmptyElements, inWriteNamespaces); +} + +eastl::pair +CDOMSerializer::Read(IDOMFactory &inFactory, IInStream &inStream, CXmlErrorHandler *inErrorHandler) +{ + return DOMParser::ParseXMLFile(inFactory, inStream, inErrorHandler); +} diff --git a/src/Runtime/Source/foundation/XML.h b/src/Runtime/Source/foundation/XML.h new file mode 100644 index 00000000..360bfdd7 --- /dev/null +++ b/src/Runtime/Source/foundation/XML.h @@ -0,0 +1,680 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_FOUNDATION_XML_H +#define QT3DS_FOUNDATION_XML_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "foundation/StringConversion.h" //Conversion between string and various datatypes. +#include "foundation/Qt3DSFlags.h" +#include "EASTL/algorithm.h" +#include "foundation/IOStreams.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" + +namespace qt3ds { +namespace foundation { + + class IStringTable; + + class IDOMFactory; + + class IInStream; + class IOutStream; + struct SDOMAttribute; + struct SDOMElement; + struct SNamespacePairNode; + + typedef const char8_t *TXMLCharPtr; + + typedef eastl::basic_string TXMLStr; + + // When the factor is destroyed, all elements and attributes are destroyed. + class IDOMFactory : public NVRefCounted + { + protected: + virtual ~IDOMFactory() {} + public: + // Str does not need to be null terminated. + virtual void AppendStrBuf(TXMLCharPtr str, QT3DSU32 len) = 0; + // Null terminate what is there and return the buffer. + // This pointer needs to be persistent. + virtual TXMLCharPtr FinalizeStrBuf() = 0; + virtual void IgnoreStrBuf() = 0; + + virtual SDOMAttribute *NextAttribute(CRegisteredString name, TXMLCharPtr val, + CRegisteredString ns = CRegisteredString(), + int inLine = 0) = 0; + virtual SDOMElement *NextElement(CRegisteredString name, + CRegisteredString ns = CRegisteredString(), + int inLine = 0) = 0; + virtual SNamespacePairNode *NextNSPairNode(CRegisteredString ns, + CRegisteredString abbr) = 0; + + TXMLCharPtr RegisterValue(TXMLCharPtr inValue); + + virtual NVScopedRefCounted GetStringTable() = 0; + virtual NVAllocatorCallback &GetAllocator() = 0; + + static NVScopedRefCounted + CreateDOMFactory(NVAllocatorCallback &inAllocator, + NVScopedRefCounted inStrTable); + }; + + struct SDOMAttribute + { + CRegisteredString m_Namespace; + CRegisteredString m_Name; + const char8_t *m_Value; + SDOMAttribute *m_NextAttribute; + SDOMAttribute *m_PreviousAttribute; + int m_Line; + SDOMAttribute() + : m_Value(NULL) + , m_NextAttribute(NULL) + , m_PreviousAttribute(NULL) + , m_Line(0) + { + } + + SDOMAttribute(CRegisteredString inName, CRegisteredString inNs, const char8_t *inValue, + int line) + : m_Namespace(inNs) + , m_Name(inName) + , m_Value(inValue) + , m_NextAttribute(NULL) + , m_PreviousAttribute(NULL) + , m_Line(line) + { + } + + bool Value(const char8_t *&outValue) + { + outValue = m_Value; + return true; + } + + template + bool Value(TDataType &outValue) + { + StringConversion().StrTo(m_Value, outValue); + return true; + } + }; + + struct SNextAttOp + { + SDOMAttribute *get(SDOMAttribute &inAtt) { return inAtt.m_NextAttribute; } + const SDOMAttribute *get(const SDOMAttribute &inAtt) { return inAtt.m_NextAttribute; } + void set(SDOMAttribute &inAtt, SDOMAttribute *next) { inAtt.m_NextAttribute = next; } + }; + struct SPrevAttOp + { + SDOMAttribute *get(SDOMAttribute &inAtt) { return inAtt.m_PreviousAttribute; } + const SDOMAttribute *get(const SDOMAttribute &inAtt) { return inAtt.m_PreviousAttribute; } + void set(SDOMAttribute &inAtt, SDOMAttribute *prev) { inAtt.m_PreviousAttribute = prev; } + }; + + typedef InvasiveLinkedList TAttributeList; + + struct SNamespacePair + { + CRegisteredString m_Namespace; + CRegisteredString m_Abbreviation; + SNamespacePair(CRegisteredString ns = CRegisteredString(), + CRegisteredString abbr = CRegisteredString()) + : m_Namespace(ns) + , m_Abbreviation(abbr) + { + } + }; + + struct SNamespacePairNode : public SNamespacePair + { + SNamespacePairNode *m_NextNode; + SNamespacePairNode(const SNamespacePair &inSrc = SNamespacePair()) + : SNamespacePair(inSrc) + , m_NextNode(NULL) + { + } + }; + + // Simplified dom element. All it has is one character value and list of attributes + // and children. So you can't mix elements and character data like you can in + // full xml, but this simplifies parsing. + struct SDOMElement + { + struct SNextElemOp + { + SDOMElement *get(SDOMElement &elem) { return elem.m_NextSibling; } + const SDOMElement *get(const SDOMElement &elem) { return elem.m_NextSibling; } + void set(SDOMElement &elem, SDOMElement *next) { elem.m_NextSibling = next; } + }; + struct SPrevElemOp + { + SDOMElement *get(SDOMElement &elem) { return elem.m_PreviousSibling; } + const SDOMElement *get(const SDOMElement &elem) { return elem.m_PreviousSibling; } + void set(SDOMElement &elem, SDOMElement *prev) { elem.m_PreviousSibling = prev; } + }; + typedef InvasiveLinkedList TElementChildList; + + CRegisteredString m_Namespace; + CRegisteredString m_Name; + const char8_t *m_Value; + SDOMElement *m_Parent; + SDOMElement *m_NextSibling; + SDOMElement *m_PreviousSibling; + TAttributeList m_Attributes; + TElementChildList m_Children; + int m_Line; + + SDOMElement() + : m_Value(NULL) + , m_Parent(NULL) + , m_NextSibling(NULL) + , m_PreviousSibling(NULL) + , m_Line(0) + { + } + + SDOMElement(CRegisteredString name, CRegisteredString ns, int inLine) + : m_Namespace(ns) + , m_Name(name) + , m_Value(NULL) + , m_Parent(NULL) + , m_NextSibling(NULL) + , m_PreviousSibling(NULL) + , m_Line(inLine) + { + } + + void AppendChild(SDOMElement &inElem, SDOMElement *inPos = NULL) + { + if (inElem.m_Parent) + inElem.m_Parent->RemoveChild(inElem); + inElem.m_Parent = this; + if (inPos) { + QT3DS_ASSERT(inPos->m_Parent == this); + m_Children.insert_after(*inPos, inElem); + } else + m_Children.push_back(inElem); + } + + void PrependChild(SDOMElement &inElem, SDOMElement *inPos = NULL) + { + if (inElem.m_Parent) + inElem.m_Parent->RemoveChild(inElem); + inElem.m_Parent = this; + if (inPos) { + QT3DS_ASSERT(inPos->m_Parent == this); + m_Children.insert_before(*inPos, inElem); + } else + m_Children.push_front(inElem); + } + + void RemoveChild(SDOMElement &inElem) + { + if (inElem.m_Parent == this) { + m_Children.remove(inElem); + } else { + if (inElem.m_Parent) { + QT3DS_ASSERT(false); + } + } + } + SDOMElement *FindNext(CRegisteredString inName, Option inNamespace, + TElementChildList::iterator iter) + { + for (TElementChildList::iterator end(NULL); iter != end; ++iter) { + if (inName.IsValid() == false || inName == iter->m_Name) { + if (inNamespace.hasValue() == false || *inNamespace == iter->m_Namespace) + return &(*iter); + } + } + return NULL; + } + // Search starts just *after inStartPos if provided + SDOMElement *FindChild(CRegisteredString inName, Option inNamespace, + SDOMElement *inStartPos = NULL) + { + TElementChildList::iterator iter = m_Children.begin(); + if (inStartPos) { + QT3DS_ASSERT(inStartPos->m_Parent == this); + iter = TElementChildList::iterator(inStartPos->m_NextSibling); + } + return FindNext(inName, inNamespace, iter); + } + // Search starts just *after inStartPos if provided + SDOMElement *FindSibling(CRegisteredString inName, Option inNamespace) + { + TElementChildList::iterator iter(m_NextSibling); + return FindNext(inName, inNamespace, iter); + } + + SDOMAttribute *FindAttribute(CRegisteredString inName, + Option inNamespace) + { + for (TAttributeList::iterator iter = m_Attributes.begin(), end = m_Attributes.end(); + iter != end; ++iter) { + if (iter->m_Name == inName) { + if (inNamespace.hasValue() == false || *inNamespace == iter->m_Namespace) + return &(*iter); + } + } + return NULL; + } + + template + bool AttValue(CRegisteredString inName, Option inNamespace, + TDataType &outValue) + { + SDOMAttribute *att = FindAttribute(inName, inNamespace); + if (att) + return att->Value(outValue); + return false; + } + + QT3DSU32 GetNumChildren(CRegisteredString inName, + Option inNamespace = Empty()) const + { + QT3DSU32 count = 0; + if (inName.IsValid() == false) { + // empty loop intentional + for (TElementChildList::iterator iter = m_Children.begin(), end = m_Children.end(); + iter != end; ++iter, ++count) + ; + } else { + for (TElementChildList::iterator iter = m_Children.begin(), end = m_Children.end(); + iter != end; ++iter) { + if (iter->m_Name == inName + && (inNamespace.isEmpty() || iter->m_Namespace == *inNamespace)) + ++count; + } + } + return count; + } + + void SetAttributeValue(CRegisteredString inName, Option inNamespace, + TXMLCharPtr inValue, IDOMFactory &inFactory, int inLine) + { + SDOMAttribute *att = FindAttribute(inName, inNamespace); + if (att) { + att->m_Value = inFactory.RegisterValue(inValue); + } else { + m_Attributes.push_back(*inFactory.NextAttribute( + inName, inValue, inNamespace.unsafeGetValue(), inLine)); + } + } + + void RemoveAttribute(CRegisteredString nm, Option inNamespace) + { + SDOMAttribute *theAttribute = FindAttribute(nm, inNamespace); + if (theAttribute) + m_Attributes.remove(*theAttribute); + } + }; + + struct SReaderScope + { + SDOMElement *m_Element; + SDOMAttribute *m_Attribute; + SReaderScope(SDOMElement *inElem = NULL, SDOMAttribute *inAtt = NULL) + : m_Element(inElem) + , m_Attribute(inAtt) + { + } + }; + + class IDOMReader : public NVRefCounted + { + protected: + virtual ~IDOMReader() {} + public: + // Stack object to save the reader's state. + struct Scope + { + IDOMReader &m_Reader; + Scope(IDOMReader &reader) + : m_Reader(reader) + { + m_Reader.PushScope(); + } + Scope(NVScopedRefCounted reader) + : m_Reader(*reader) + { + m_Reader.PushScope(); + } + ~Scope() { m_Reader.PopScope(); } + }; + + // Parse buffer + MemoryBuffer m_TempBuf; + NVScopedRefCounted m_StringTable; + + IDOMReader(NVAllocatorCallback &inAlloc, NVScopedRefCounted inStringTable) + : m_TempBuf(ForwardingAllocator(inAlloc, "IDOMReader::m_TempBuf")) + , m_StringTable(inStringTable) + { + } + + NVScopedRefCounted GetStringTable() { return m_StringTable; } + + // Pushing scope saves your state so no matter where you are when + // you next pop scope, you come back to the same state. + virtual void PushScope() = 0; + virtual void PopScope() = 0; + + // Sometimes pushing and popping scope isn't enough and you need + // somewhat random access to scope. + // This scope does not remember the current attribute. + virtual SReaderScope GetScope() = 0; + virtual void SetScope(SReaderScope inScope) = 0; + // Return an attribute whose value is *not* registered with the string table. + // You can't hold onto this value for any length of time, but when you need to + // immediately convert to a different value this is the most efficient way. + virtual bool UnregisteredAtt(TXMLCharPtr name, TXMLCharPtr &outValue, + TXMLCharPtr ns = NULL) = 0; + // Return an attribute whose value *is* registered with the string table. + virtual bool Att(TXMLCharPtr name, CRegisteredString &outValue, TXMLCharPtr ns = NULL) = 0; + virtual SDOMAttribute *GetFirstAttribute() = 0; + virtual SDOMAttribute *GetNextAttribute() = 0; + virtual QT3DSU32 CountChildren(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) = 0; + virtual bool MoveToFirstChild(TXMLCharPtr childName = NULL, TXMLCharPtr ns = NULL) = 0; + virtual bool MoveToNextSibling(TXMLCharPtr siblingName = NULL, TXMLCharPtr ns = NULL) = 0; + // Leave element means go to its parent. + virtual void Leave() = 0; + virtual SDOMElement *GetElement() const = 0; + CRegisteredString GetElementName() const + { + SDOMElement *elem = GetElement(); + if (elem) + return elem->m_Name; + return CRegisteredString(); + } + + // Value is the concatentated text node values inside the element + virtual bool Value(TXMLCharPtr &outValue) = 0; + + // Get the element this reader was created with + virtual SDOMElement *GetTopElement() = 0; + + bool Att(TXMLCharPtr name, TXMLStr &outValue) + { + TXMLCharPtr temp; + if (UnregisteredAtt(name, temp)) { + outValue.assign(temp); + return true; + } + return false; + } + + template + bool Att(TXMLCharPtr name, TDataType &outValue) + { + TXMLCharPtr temp; + if (UnregisteredAtt(name, temp)) { + StringConversion().StrTo(temp, outValue); + return true; + } else { + return false; + } + } + + bool ChildValue(TXMLCharPtr name, TXMLCharPtr &value) + { + if (MoveToFirstChild(name)) { + Value(value); + Leave(); + return true; + } + return false; + } + + bool RegisteredChildValue(TXMLCharPtr name, TXMLCharPtr &value) + { + if (MoveToFirstChild(name)) { + RegisteredValue(value); + Leave(); + return true; + } + return false; + } + bool RegisteredValue(TXMLCharPtr &outValue) + { + bool retval = Value(outValue); + if (retval) + outValue = m_StringTable->RegisterStr(outValue); + return retval; + } + + template + bool Value(TDataType &outValue) + { + TXMLCharPtr value; + if (Value(value)) { + StringConversion().StrTo(value, outValue); + return true; + } + return false; + } + + // IDOMReader implementations + template + bool ValueList(NVDataRef data) + { + const char8_t *value; + if (Value(value)) { + Char8TReader reader(const_cast(value), m_TempBuf); + reader.ReadRef(data); + } + return true; + } + + // Destructive operation because we can't trust + // strtod to do the right thing. On windows, for long strings, + // it calls strlen every operation thus leading to basically N^2 + // behavior + template + NVConstDataRef ChildValueList(TXMLCharPtr listName) + { + NVConstDataRef retval; + TXMLCharPtr childValue = NULL; + if (ChildValue(listName, childValue)) { + Char8TReader reader(const_cast(childValue), m_TempBuf); + reader.ReadBuffer(retval); + } + return retval; + } + + template + void Serialize(const char8_t *elemName, TSerializer &serializer, + const char8_t *inNamespace = NULL) + { + IDOMReader::Scope __theScope(*this); + if (MoveToFirstChild(elemName, inNamespace)) { + serializer.Serialize(*this); + } + } + // Optionally hold on to the factory to keep our elements in memory as long as we are. + static NVScopedRefCounted CreateDOMReader( + NVAllocatorCallback &inAlloc, SDOMElement &inRootElement, + NVScopedRefCounted inStringTable, + NVScopedRefCounted inFactory = NVScopedRefCounted()); + }; + + // Write out data in an xml-like fasion without specifying exactly + // where that data is being written. + class IDOMWriter : public NVRefCounted + { + protected: + virtual ~IDOMWriter() {} + public: + // Control the element scope. + struct Scope + { + IDOMWriter &m_Writer; + Scope(IDOMWriter &writer, TXMLCharPtr inElemName, TXMLCharPtr inNamespace = NULL) + : m_Writer(writer) + { + m_Writer.Begin(inElemName, inNamespace); + } + ~Scope() { m_Writer.End(); } + }; + + char8_t m_NarrowBuf[256]; + + // There tend to be two types of elements. + // Containers (\n\t\n) + // and Values onetwothree + virtual void Begin(TXMLCharPtr inElemName, TXMLCharPtr inNamespace = NULL, + int inLine = 0) = 0; + // Attributes. They may be sorted just before write + virtual void Att(TXMLCharPtr name, TXMLCharPtr value, TXMLCharPtr inNamespace = NULL, + int inLine = 0) = 0; + virtual void Value(TXMLCharPtr value) = 0; + virtual void End() = 0; + virtual void RemoveCurrent() = 0; + virtual void RemoveAttribute(TXMLCharPtr inItem, TXMLCharPtr inNamespace = NULL) = 0; + // Get the number of tabs required to line up the next line + // with the opening of the previous line + virtual QT3DSU32 GetTabs() = 0; + virtual SDOMElement *GetTopElement() = 0; + virtual NVScopedRefCounted GetFactory() = 0; + // Move this item before this sibling. Function does not rearrange the + // tree in any major way and will not work if inItem and inSibling aren't + // siblings. + virtual void MoveBefore(TXMLCharPtr inItem, TXMLCharPtr inSibling, + TXMLCharPtr inNamespace = NULL) = 0; + virtual NVAllocatorCallback &GetAllocator() = 0; + + virtual void ChildValue(TXMLCharPtr name, TXMLCharPtr value, TXMLCharPtr inNamespace = NULL) + { + Begin(name, inNamespace); + Value(value); + End(); + } + + TXMLCharPtr ToStr(char8_t val) + { + m_NarrowBuf[0] = val; + m_NarrowBuf[1] = 0; + return m_NarrowBuf; + } + + template + TXMLCharPtr ToStr(TDataType val) + { + StringConversion().ToStr(val, NVDataRef(m_NarrowBuf, 256)); + return m_NarrowBuf; + } + + void Att(TXMLCharPtr name, const TXMLStr &inValue, TXMLCharPtr inNamespace = NULL) + { + return Att(name, inValue.c_str(), inNamespace); + } + + template + void Att(TXMLCharPtr name, TData value, TXMLCharPtr inNamespace = NULL) + { + Att(name, ToStr(value), inNamespace); + } + + template + void Serialize(const char8_t *elemName, TSerializer &serializer, + TXMLCharPtr inNamespace = NULL) + { + IDOMWriter::Scope __theScope(*this, elemName, inNamespace); + serializer.Serialize(*this); + } + + NVScopedRefCounted CreateDOMReader() + { + NVScopedRefCounted theFactory(GetFactory()); + return IDOMReader::CreateDOMReader(GetAllocator(), *GetTopElement(), + theFactory->GetStringTable(), theFactory); + } + + // Note that the default method of creating a writer also creates a reader; they can + // both manipulation the DOM hierarch. + static eastl::pair, NVScopedRefCounted> + CreateDOMWriter(NVScopedRefCounted inFactory, SDOMElement &inRootElement, + NVScopedRefCounted inStringTable); + + static eastl::pair, NVScopedRefCounted> + CreateDOMWriter(NVAllocatorCallback &inAlloc, const char8_t *inTopElemName, + NVScopedRefCounted inStringTable, + const char8_t *inNamespace = NULL) + { + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(inAlloc, inStringTable)); + SDOMElement *theRoot = + theFactory->NextElement(theFactory->GetStringTable()->RegisterStr(inTopElemName), + theFactory->GetStringTable()->RegisterStr(inNamespace)); + return CreateDOMWriter(theFactory, *theRoot, inStringTable); + } + }; + + class CXmlErrorHandler + { + protected: + virtual ~CXmlErrorHandler() {} + public: + virtual void OnXmlError(TXMLCharPtr errorName, int line, int column) = 0; + }; + + class CDOMSerializer + { + public: + static void WriteXMLHeader(IOutStream &inStream); + + // Write out the elements. These pairs will be used in order to abbreviate namespaces with + // nicer abbreviations. + // Any namespaces not found in those pairs will get auto-generated abbreviations + // The document will be assumed to be in the namespace that has no abbreviation. + // For fragments or snippets, it is better to avoid writing out the namespace declarations + static void + Write(NVAllocatorCallback &inAlloc, SDOMElement &inElement, IOutStream &inStream, + IStringTable &inStrTable, + NVConstDataRef inNamespaces = NVConstDataRef(), + bool inTrimEmptyElements = true, QT3DSU32 inTabs = 0, bool inWriteNamespaces = true); + + // Returns a pair of the namespace pair nodes and the dom element. The ns pair nodes allow + // us to at least keep the same abbreviations + // used if namespace are used. + static eastl::pair + Read(IDOMFactory &inFactory, IInStream &inStream, CXmlErrorHandler *inErrorHandler = NULL); + }; +} +} +#endif diff --git a/src/Runtime/Source/foundation/linux/LICENSE.TXT b/src/Runtime/Source/foundation/linux/LICENSE.TXT new file mode 100644 index 00000000..f40caef8 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/LICENSE.TXT @@ -0,0 +1,7 @@ + Copyright (c) 2001 Intel Corporation. + +Permition is granted to use, copy, distribute and prepare derivative works +of this library for any purpose and without fee, provided, that the above +copyright notice and this statement appear in all copies. +Intel makes no representations about the suitability of this library for +any purpose, and specifically disclaims all warranties. diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxAoS.h b/src/Runtime/Source/foundation/linux/Qt3DSLinuxAoS.h new file mode 100644 index 00000000..6bcb4406 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxAoS.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_LINUX_AOS_H +#define QT3DS_LINUX_AOS_H + +// no includes here! this file should be included from NVcVecMath.h only!!! + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +// only SSE compatible platforms should reach this +// likely to be split up when we add NEON support. +#include + +typedef union UnionM128 { + UnionM128() {} + UnionM128(__m128 in) { m128 = in; } + + UnionM128(__m128i in) { m128i = in; } + + operator __m128() { return m128; } + + operator const __m128() const { return m128; } + + float m128_f32[4]; + __int8_t m128_i8[16]; + __int16_t m128_i16[8]; + __int32_t m128_i32[4]; + __int64_t m128_i64[2]; + __uint16_t m128_u16[8]; + __uint32_t m128_u32[4]; + __uint64_t m128_u64[2]; + __m128 m128; + __m128i m128i; +} UnionM128; + +typedef __m128 FloatV; +typedef __m128 Vec3V; +typedef __m128 Vec4V; +typedef __m128 BoolV; +typedef __m128 QuatV; +// typedef __m128 VecU32V; +// typedef __m128 VecI32V; +// typedef __m128 VecU16V; +// typedef __m128 VecI16V; +// typedef __m128 VecU8V; +typedef UnionM128 VecU32V; +typedef UnionM128 VecI32V; +typedef UnionM128 VecU16V; +typedef UnionM128 VecI16V; +typedef UnionM128 VecU8V; + +#define FloatVArg FloatV & +#define Vec3VArg Vec3V & +#define Vec4VArg Vec4V & +#define BoolVArg BoolV & +#define VecU32VArg VecU32V & +#define VecI32VArg VecI32V & +#define VecU16VArg VecU16V & +#define VecI16VArg VecI16V & +#define VecU8VArg VecU8V & +#define QuatVArg QuatV & + +QT3DS_ALIGN_PREFIX(16) +struct Mat33V +{ + Mat33V() {} + Mat33V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2) + : col0(c0) + , col1(c1) + , col2(c2) + { + } + Vec3V QT3DS_ALIGN(16, col0); + Vec3V QT3DS_ALIGN(16, col1); + Vec3V QT3DS_ALIGN(16, col2); +} QT3DS_ALIGN_SUFFIX(16); + +QT3DS_ALIGN_PREFIX(16) +struct Mat34V +{ + Mat34V() {} + Mat34V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2, const Vec3V &c3) + : col0(c0) + , col1(c1) + , col2(c2) + , col3(c3) + { + } + Vec3V QT3DS_ALIGN(16, col0); + Vec3V QT3DS_ALIGN(16, col1); + Vec3V QT3DS_ALIGN(16, col2); + Vec3V QT3DS_ALIGN(16, col3); +} QT3DS_ALIGN_SUFFIX(16); + +QT3DS_ALIGN_PREFIX(16) +struct Mat43V +{ + Mat43V() {} + Mat43V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2) + : col0(c0) + , col1(c1) + , col2(c2) + { + } + Vec4V QT3DS_ALIGN(16, col0); + Vec4V QT3DS_ALIGN(16, col1); + Vec4V QT3DS_ALIGN(16, col2); +} QT3DS_ALIGN_SUFFIX(16); + +QT3DS_ALIGN_PREFIX(16) +struct Mat44V +{ + Mat44V() {} + Mat44V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2, const Vec4V &c3) + : col0(c0) + , col1(c1) + , col2(c2) + , col3(c3) + { + } + Vec4V QT3DS_ALIGN(16, col0); + Vec4V QT3DS_ALIGN(16, col1); + Vec4V QT3DS_ALIGN(16, col2); + Vec4V QT3DS_ALIGN(16, col3); +} QT3DS_ALIGN_SUFFIX(16); + +#endif // QT3DS_LINUX_AOS_H diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxAtomic.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxAtomic.cpp new file mode 100644 index 00000000..f0045dd9 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxAtomic.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAtomic.h" +#ifdef __QNX__ +#include +#endif +#ifdef __INTEGRITY +#include +#endif + +#define PAUSE() asm("nop") + +namespace qt3ds { +namespace foundation { +#ifdef __QNX__ + QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) + { + atomic_add((volatile unsigned *)val, 1); + return *val; + } + + QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) + { + atomic_sub((volatile unsigned *)val, 1); + return *val; + } +#elif defined (__INTEGRITY) + // TestAndSet and AtomicModify take in volatile Address* leading to overflow error if used + + QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) + { + static QMutex mutex; + QMutexLocker lock(&mutex); + QT3DSI32 ret = *dest; + *dest = (*dest == comp) ? exch : ret; + return ret; + } + + QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) + { + static QMutex mutex; + QMutexLocker lock(&mutex); + return ++(*val); + } + + QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) + { + static QMutex mutex; + QMutexLocker lock(&mutex); + return --(*val); + } +#else + void *atomicCompareExchangePointer(volatile void **dest, void *exch, void *comp) + { + return __sync_val_compare_and_swap((void **)dest, comp, exch); + } + + QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) + { + return __sync_val_compare_and_swap(dest, comp, exch); + } + + QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) { return __sync_add_and_fetch(val, 1); } + + QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) { return __sync_sub_and_fetch(val, 1); } + + QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta) { return __sync_add_and_fetch(val, delta); } + + QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2) + { + QT3DSI32 oldVal, newVal; + + do { + PAUSE(); + oldVal = *val; + + if (val2 > oldVal) + newVal = val2; + else + newVal = oldVal; + + } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); + + return *val; + } + + QT3DSI32 atomicExchange(volatile QT3DSI32 *val, QT3DSI32 val2) + { + QT3DSI32 newVal, oldVal; + + do { + PAUSE(); + oldVal = *val; + newVal = val2; + } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); + + return newVal; + } +#endif +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxFPU.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxFPU.cpp new file mode 100644 index 00000000..c3eae215 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxFPU.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/Qt3DSFPU.h" +#include + +QT3DS_COMPILE_TIME_ASSERT(8 * sizeof(qt3ds::QT3DSU32) >= sizeof(fenv_t)); + +qt3ds::foundation::FPUGuard::FPUGuard() +{ +#ifdef __CYGWIN__ +#pragma message "FPUGuard::FPUGuard() is not implemented" +#else + fegetenv(reinterpret_cast(mControlWords)); + fesetenv(FE_DFL_ENV); +#endif +} + +qt3ds::foundation::FPUGuard::~FPUGuard() +{ +#ifdef __CYGWIN__ +#pragma message "FPUGuard::~FPUGuard() is not implemented" +#else + fesetenv(reinterpret_cast(mControlWords)); +#endif +} diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxFile.h b/src/Runtime/Source/foundation/linux/Qt3DSLinuxFile.h new file mode 100644 index 00000000..1369735f --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxFile.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_LINUX_FILE_H +#define QT3DS_FOUNDATION_QT3DS_LINUX_FILE_H + +#include "foundation/Qt3DS.h" +#include + +namespace qt3ds { +namespace foundation { + QT3DS_INLINE int fopen_s(FILE **_File, const char *_Filename, const char *_Mode) + { + FILE *fp = ::fopen(_Filename, _Mode); + return fp ? *_File = fp, 0 : -1; + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxInlineAoS.h b/src/Runtime/Source/foundation/linux/Qt3DSLinuxInlineAoS.h new file mode 100644 index 00000000..0443ba90 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxInlineAoS.h @@ -0,0 +1,2666 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// Copyright (c) 2001 Intel Corporation. +// +// Permition is granted to use, copy, distribute and prepare derivative works +// of this library for any purpose and without fee, provided, that the above +// copyright notice and this statement appear in all copies. +// Intel makes no representations about the suitability of this library for +// any purpose, and specifically disclaims all warranties. +// See LEGAL.TXT for all the legal information. +// + +#ifndef QT3DS_LINUX_INLINE_AOS_H +#define QT3DS_LINUX_INLINE_AOS_H + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +// Remove this define when all platforms use simd solver. +#define QT3DS_SUPPORT_SIMD + +#define _QT3DS_FPCLASS_SNAN 0x0001 /* signaling NaN */ +#define _QT3DS_FPCLASS_QNAN 0x0002 /* quiet NaN */ +#define _QT3DS_FPCLASS_NINF 0x0004 /* negative infinity */ +#define _QT3DS_FPCLASS_PINF 0x0200 /* positive infinity */ + +QT3DS_FORCE_INLINE __m128 m128_I2F(__m128i n) +{ + return _mm_castsi128_ps(n); +} +QT3DS_FORCE_INLINE __m128i m128_F2I(__m128 n) +{ + return _mm_castps_si128(n); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAllTrue4_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return moveMask == (0xf); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue4_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return moveMask != (0x0); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAllTrue3_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return (moveMask & 0x7) == (0x7); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue3_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return (moveMask & 0x7) != (0x0); +} + +///////////////////////////////////////////////////////////////////// +////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +QT3DS_FORCE_INLINE QT3DSU32 FiniteTestEq(const Vec4V a, const Vec4V b) +{ + // This is a bit of a bodge. + //_mm_comieq_ss returns 1 if either value is nan so we need to re-cast a and b with true encoded + //as a non-nan number. + // There must be a better way of doing this in sse. + const BoolV one = FOne(); + const BoolV zero = FZero(); + const BoolV a1 = V4Sel(a, one, zero); + const BoolV b1 = V4Sel(b, one, zero); + return (_mm_comieq_ss(a1, b1) && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 1, 1, 1)), + _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(1, 1, 1, 1))) + && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(2, 2, 2, 2)), + _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(2, 2, 2, 2))) + && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 3, 3, 3)), + _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(3, 3, 3, 3)))); +} + +QT3DS_FORCE_INLINE bool isValidFloatV(const FloatV a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))) + && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))) + && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)))); +} + +QT3DS_FORCE_INLINE bool isValidVec3V(const Vec3V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero()) ? true : false); +} + +QT3DS_FORCE_INLINE bool isFiniteFloatV(const FloatV a) +{ + const QT3DSU32 badNumber = + (_QT3DS_FPCLASS_SNAN | _QT3DS_FPCLASS_QNAN | _QT3DS_FPCLASS_NINF | _QT3DS_FPCLASS_PINF); + const FloatV vBadNum = FloatV_From_F32((QT3DSF32 &)badNumber); + const BoolV vMask = BAnd(vBadNum, a); + return FiniteTestEq(vMask, BFFFF()) == 1; +} + +QT3DS_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) +{ + const QT3DSU32 badNumber = + (_QT3DS_FPCLASS_SNAN | _QT3DS_FPCLASS_QNAN | _QT3DS_FPCLASS_NINF | _QT3DS_FPCLASS_PINF); + const Vec3V vBadNum = Vec3V_From_F32((QT3DSF32 &)badNumber); + const BoolV vMask = BAnd(BAnd(vBadNum, a), BTTTF()); + return FiniteTestEq(vMask, BFFFF()) == 1; +} + +QT3DS_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) +{ + /*Vec4V a; + QT3DS_ALIGN(16, QT3DSF32 f[4]); + F32Array_Aligned_From_Vec4V(a, f); + return NVIsFinite(f[0]) + && NVIsFinite(f[1]) + && NVIsFinite(f[2]) + && NVIsFinite(f[3]);*/ + + const QT3DSU32 badNumber = + (_QT3DS_FPCLASS_SNAN | _QT3DS_FPCLASS_QNAN | _QT3DS_FPCLASS_NINF | _QT3DS_FPCLASS_PINF); + const Vec4V vBadNum = Vec4V_From_F32((QT3DSF32 &)badNumber); + const BoolV vMask = BAnd(vBadNum, a); + + return FiniteTestEq(vMask, BFFFF()) == 1; +} + +QT3DS_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FloatV_From_F32(0.0f)) + ? true + : false); +} + +QT3DS_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FloatV_From_F32(0.0f)) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FloatV_From_F32(0.0f)) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FloatV_From_F32(0.0f))); +} + +QT3DS_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FloatV_From_F32(0.0f)) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FloatV_From_F32(0.0f)) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FloatV_From_F32(0.0f)) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FloatV_From_F32(0.0f))); +} + +///////////////////////////////////////////////////////////////////// +////VECTORISED FUNCTION IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +QT3DS_FORCE_INLINE FloatV FloatV_From_F32(const QT3DSF32 f) +{ + return (_mm_load1_ps(&f)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_F32(const QT3DSF32 f) +{ + return _mm_set_ps(0.0f, f, f, f); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32(const QT3DSF32 f) +{ + return (_mm_load1_ps(&f)); +} + +QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32(const bool f) +{ + const QT3DSU32 i = -(QT3DSI32)f; + return _mm_load1_ps((float *)&i); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_Aligned(const QT3DSVec3 &f) +{ + VECMATHAOS_ASSERT(0 == ((size_t)&f & 0x0f)); + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3(const QT3DSVec3 &f) +{ + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_WUndefined(const QT3DSVec3 &f) +{ + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) +{ + return V4SetW(v, V4Zero()); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) +{ + return f; // ok if it is implemented as the same type. +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_NVVec3_WUndefined(const QT3DSVec3 &f) +{ + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Mat33V Mat33V_From_NVMat33(const QT3DSMat33 &m) +{ + return Mat33V(Vec3V_From_NVVec3(m.column0), Vec3V_From_NVVec3(m.column1), + Vec3V_From_NVVec3(m.column2)); +} + +QT3DS_FORCE_INLINE void NVMat33_From_Mat33V(const Mat33V &m, QT3DSMat33 &out) +{ + QT3DS_ASSERT((size_t(&out) & 15) == 0); + NVVec3_From_Vec3V(m.col0, out.column0); + NVVec3_From_Vec3V(m.col1, out.column1); + NVVec3_From_Vec3V(m.col2, out.column2); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array_Aligned(const QT3DSF32 *const f) +{ + VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); + return (_mm_load_ps(f)); +} + +QT3DS_FORCE_INLINE void F32Array_Aligned_From_Vec4V(Vec4V a, QT3DSF32 *f) +{ + VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); + _mm_store_ps(f, a); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array(const QT3DSF32 *const f) +{ + return (_mm_loadu_ps(f)); +} + +QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32Array(const bool *const f) +{ + const QT3DS_ALIGN(16, QT3DSU32) b[4] = { -(QT3DSI32)f[0], -(QT3DSI32)f[1], -(QT3DSI32)f[2], -(QT3DSI32)f[3] }; + return _mm_load1_ps((float *)&b); +} + +QT3DS_FORCE_INLINE QT3DSF32 NVF32_From_FloatV(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + QT3DSF32 f; + _mm_store_ss(&f, a); + return f; +} + +QT3DS_FORCE_INLINE void NVF32_From_FloatV(const FloatV a, QT3DSF32 *QT3DS_RESTRICT f) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + _mm_store_ss(f, a); +} + +QT3DS_FORCE_INLINE void NVVec3Aligned_From_Vec3V(const Vec3V a, QT3DSVec3 &f) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); + VECMATHAOS_ASSERT(0 == ((int)&f & 0x0F)); + QT3DS_ALIGN(16, QT3DSF32) f2[4]; + _mm_store_ps(f2, a); + f = QT3DSVec3(f2[0], f2[1], f2[2]); +} + +QT3DS_FORCE_INLINE void NVVec3_From_Vec3V(const Vec3V a, QT3DSVec3 &f) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); + QT3DS_ALIGN(16, QT3DSF32) f2[4]; + _mm_store_ps(f2, a); + f = QT3DSVec3(f2[0], f2[1], f2[2]); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualFloatV(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return (_mm_comieq_ss(a, b) != 0); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec3V(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return V3AllEq(a, b) != 0; +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec4V(const Vec4V a, const Vec4V b) +{ + return V4AllEq(a, b) != 0; +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualBoolV(const BoolV a, const BoolV b) +{ + return BAllTrue4_R(VecI32V_IsEq(a, b)) != 0; +} + +#define VECMATH_AOS_EPSILON (1e-3f) + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualFloatV(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + const FloatV c = FSub(a, b); + const FloatV minError = FloatV_From_F32(-VECMATH_AOS_EPSILON); + const FloatV maxError = FloatV_From_F32(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(c, minError) && _mm_comilt_ss(c, maxError)); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + const Vec3V c = V3Sub(a, b); + const Vec3V minError = Vec3V_From_F32(-VECMATH_AOS_EPSILON); + const Vec3V maxError = Vec3V_From_F32(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError)); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) +{ + const Vec4V c = V4Sub(a, b); + const Vec4V minError = Vec4V_From_F32(-VECMATH_AOS_EPSILON); + const Vec4V maxError = Vec4V_From_F32(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), maxError)); +} + +////////////////////////////////// +// FLOATV +////////////////////////////////// + +QT3DS_FORCE_INLINE FloatV FZero() +{ + return FloatV_From_F32(0.0f); +} + +QT3DS_FORCE_INLINE FloatV FOne() +{ + return FloatV_From_F32(1.0f); +} + +QT3DS_FORCE_INLINE FloatV FHalf() +{ + return FloatV_From_F32(0.5f); +} + +QT3DS_FORCE_INLINE FloatV FEps() +{ + return FloatV_From_F32(QT3DS_ENV_REAL); +} + +QT3DS_FORCE_INLINE FloatV FEps6() +{ + return FloatV_From_F32(1e-6f); +} + +QT3DS_FORCE_INLINE FloatV FMax() +{ + return FloatV_From_F32(QT3DS_MAX_REAL); +} + +QT3DS_FORCE_INLINE FloatV FNegMax() +{ + return FloatV_From_F32(-QT3DS_MAX_REAL); +} + +QT3DS_FORCE_INLINE FloatV IZero() +{ + const QT3DSU32 zero = 0; + return _mm_load1_ps((QT3DSF32 *)&zero); +} + +QT3DS_FORCE_INLINE FloatV IOne() +{ + const QT3DSU32 one = 1; + return _mm_load1_ps((QT3DSF32 *)&one); +} + +QT3DS_FORCE_INLINE FloatV ITwo() +{ + const QT3DSU32 two = 2; + return _mm_load1_ps((QT3DSF32 *)&two); +} + +QT3DS_FORCE_INLINE FloatV IThree() +{ + const QT3DSU32 three = 3; + return _mm_load1_ps((QT3DSF32 *)&three); +} + +QT3DS_FORCE_INLINE FloatV IFour() +{ + QT3DSU32 four = 4; + return _mm_load1_ps((QT3DSF32 *)&four); +} + +QT3DS_FORCE_INLINE FloatV FNeg(const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +QT3DS_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_add_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_sub_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE FloatV FRecip(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return _mm_rcp_ps(a); +} + +QT3DS_FORCE_INLINE FloatV FRecipFast(const FloatV a) +{ + return FRecip(a); +} + +QT3DS_FORCE_INLINE FloatV FRsqrt(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return _mm_rsqrt_ps(a); +} + +QT3DS_FORCE_INLINE FloatV FSqrt(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return _mm_sqrt_ps(a); +} + +QT3DS_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) +{ + return FRsqrt(a); +} + +QT3DS_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidFloatV(c)); + return FAdd(FMul(a, b), c); +} + +QT3DS_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidFloatV(c)); + return FSub(c, FMul(a, b)); +} + +QT3DS_FORCE_INLINE FloatV FAbs(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + QT3DS_ALIGN(16, const QT3DSU32) absMask[4] = { 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF }; + return _mm_and_ps(a, _mm_load_ps((QT3DSF32 *)absMask)); +} + +QT3DS_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(_VecMathTests::allElementsEqualBoolV(c, BTTTT()) + || _VecMathTests::allElementsEqualBoolV(c, BFFFF())); + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +QT3DS_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_cmpgt_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_cmpge_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_max_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_min_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(minV)); + VECMATHAOS_ASSERT(isValidFloatV(maxV)); + return FMax(FMin(a, maxV), minV); +} + +QT3DS_FORCE_INLINE QT3DSU32 FAllGrtr(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return (_mm_comigt_ss(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 FAllGrtrOrEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + + return (_mm_comige_ss(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 FAllEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + + return (_mm_comieq_ss(a, b)); +} + +QT3DS_FORCE_INLINE FloatV FRound(const FloatV a) +{ + // return _mm_round_ps(a, 0x0); + const Vec3V half = Vec3V_From_F32(0.5f); + const Vec3V aPlusHalf = V3Add(a, half); + __m128i tmp = _mm_cvttps_epi32(aPlusHalf); + return _mm_cvtepi32_ps(tmp); +} + +QT3DS_FORCE_INLINE FloatV FSin(const FloatV a) +{ + // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + FloatV Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const FloatV tmp = FMul(a, twoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V3 = FMul(V2, V1); + const FloatV V5 = FMul(V3, V2); + const FloatV V7 = FMul(V5, V2); + const FloatV V9 = FMul(V7, V2); + const FloatV V11 = FMul(V9, V2); + const FloatV V13 = FMul(V11, V2); + const FloatV V15 = FMul(V13, V2); + const FloatV V17 = FMul(V15, V2); + const FloatV V19 = FMul(V17, V2); + const FloatV V21 = FMul(V19, V2); + const FloatV V23 = FMul(V21, V2); + + const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Result = FMulAdd(S1, V3, V1); + Result = FMulAdd(S2, V5, Result); + Result = FMulAdd(S3, V7, Result); + Result = FMulAdd(S4, V9, Result); + Result = FMulAdd(S5, V11, Result); + Result = FMulAdd(S6, V13, Result); + Result = FMulAdd(S7, V15, Result); + Result = FMulAdd(S8, V17, Result); + Result = FMulAdd(S9, V19, Result); + Result = FMulAdd(S10, V21, Result); + Result = FMulAdd(S11, V23, Result); + + return Result; +} + +QT3DS_FORCE_INLINE FloatV FCos(const FloatV a) +{ + // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + FloatV Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const FloatV tmp = FMul(a, twoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V4 = FMul(V2, V2); + const FloatV V6 = FMul(V4, V2); + const FloatV V8 = FMul(V4, V4); + const FloatV V10 = FMul(V6, V4); + const FloatV V12 = FMul(V6, V6); + const FloatV V14 = FMul(V8, V6); + const FloatV V16 = FMul(V8, V8); + const FloatV V18 = FMul(V10, V8); + const FloatV V20 = FMul(V10, V10); + const FloatV V22 = FMul(V12, V10); + + const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Result = FMulAdd(C1, V2, V4One()); + Result = FMulAdd(C2, V4, Result); + Result = FMulAdd(C3, V6, Result); + Result = FMulAdd(C4, V8, Result); + Result = FMulAdd(C5, V10, Result); + Result = FMulAdd(C6, V12, Result); + Result = FMulAdd(C7, V14, Result); + Result = FMulAdd(C8, V16, Result); + Result = FMulAdd(C9, V18, Result); + Result = FMulAdd(C10, V20, Result); + Result = FMulAdd(C11, V22, Result); + + return Result; +} + +QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) +{ + const BoolV ffff = BFFFF(); + const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); + return !BAllEq(c, ffff); +} + +QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) +{ + const BoolV tttt = BTTTT(); + const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); + return BAllEq(c, tttt); +} + +QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV bounds) +{ + return FOutOfBounds(a, FNeg(bounds), bounds); +} + +QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV bounds) +{ + return FInBounds(a, FNeg(bounds), bounds); +} + +////////////////////////////////// +// VEC3V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec3V V3Splat(const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + const __m128 zero = FloatV_From_F32(0.0f); + const __m128 fff0 = _mm_move_ss(f, zero); + return _mm_shuffle_ps(fff0, fff0, _MM_SHUFFLE(0, 1, 2, 3)); +} + +QT3DS_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) +{ + VECMATHAOS_ASSERT(isValidFloatV(x)); + VECMATHAOS_ASSERT(isValidFloatV(y)); + VECMATHAOS_ASSERT(isValidFloatV(z)); + // static on zero causes compiler crash on x64 debug_opt + const __m128 zero = FloatV_From_F32(0.0f); + const __m128 xy = _mm_move_ss(x, y); + const __m128 z0 = _mm_move_ss(zero, z); + + return _mm_shuffle_ps(xy, z0, _MM_SHUFFLE(1, 0, 0, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3UnitX() +{ + const QT3DS_ALIGN(16, QT3DSF32) x[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +QT3DS_FORCE_INLINE Vec3V V3UnitY() +{ + const QT3DS_ALIGN(16, QT3DSF32) y[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +QT3DS_FORCE_INLINE Vec3V V3UnitZ() +{ + const QT3DS_ALIGN(16, QT3DSF32) z[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +QT3DS_FORCE_INLINE FloatV V3GetX(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE FloatV V3GetY(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +QT3DS_FORCE_INLINE FloatV V3GetZ(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V3Sel(BFTTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V3Sel(BTFTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V3Sel(BTTFT(), v, f); +} + +QT3DS_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) +{ + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 0, 3, 0)); + return V3SetY(r, V3GetX(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) +{ + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); + return V3SetY(r, V3GetY(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) +{ + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 2, 3, 2)); + return V3SetY(r, V3GetZ(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3Zero() +{ + return Vec3V_From_F32(0.0f); +} + +QT3DS_FORCE_INLINE Vec3V V3Eps() +{ + return Vec3V_From_F32(QT3DS_ENV_REAL); +} +QT3DS_FORCE_INLINE Vec3V V3One() +{ + return Vec3V_From_F32(1.0f); +} + +QT3DS_FORCE_INLINE Vec3V V3Neg(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +QT3DS_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_add_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_sub_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + const __m128 one = Vec3V_From_F32(1.0f); + const __m128 tttf = BTTTF(); + const __m128 b1 = V3Sel(tttf, b, one); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + const __m128 one = Vec3V_From_F32(1.0f); + const __m128 tttf = BTTTF(); + const __m128 b1 = V3Sel(tttf, b, one); + return _mm_mul_ps(a, _mm_rcp_ps(b1)); +} + +QT3DS_FORCE_INLINE Vec3V V3Recip(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = Vec3V_From_F32(0.0f); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rcp_ps(a); + return V3Sel(tttf, recipA, zero); +} + +QT3DS_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) +{ + return V3Recip(a); +} + +QT3DS_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = Vec3V_From_F32(0.0f); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rsqrt_ps(a); + return V3Sel(tttf, recipA, zero); +} + +QT3DS_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) +{ + return V3Rsqrt(a); +} + +QT3DS_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Add(V3Scale(a, b), c); +} + +QT3DS_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Sub(c, V3Scale(a, b)); +} + +QT3DS_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Add(V3Mul(a, b), c); +} + +QT3DS_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Sub(c, V3Scale(a, b)); +} + +QT3DS_FORCE_INLINE Vec3V V3Abs(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Max( + a, V3Neg(a)); // sw/physx/shared/reviewed/3/feature/sdk/include/windows/Qt3DSWindowsInlineAoS.h +} + +QT3DS_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + //__m128 dot1 = _mm_mul_ps(a, b); + ////w,z,y,x + //__m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2,1,0,3)); //z,y,x,w + //__m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1,0,3,2)); //y,x,w,z + //__m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0,3,2,1)); //x,w,z,y + // return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1,shuf1)); + + __m128 dot1 = _mm_mul_ps(a, b); + __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf2, shuf3), shuf1); +} + +QT3DS_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); +} + +QT3DS_FORCE_INLINE FloatV V3Length(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_sqrt_ps(V3Dot(a, a)); +} + +QT3DS_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Dot(a, a); +} + +QT3DS_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Scale(a, _mm_rsqrt_ps(V3Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Scale(a, _mm_rsqrt_ps(V3Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = FloatV_From_F32(0.0f); + const __m128 length = V3Length(a); + const __m128 isGreaterThanZero = FIsGrtr(length, zero); + return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), zero); +} + +QT3DS_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +QT3DS_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_cmpgt_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_cmpge_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_max_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_min_ps(a, b); +} + +// Extract the maximum value from a +QT3DS_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + + return _mm_max_ps(_mm_max_ps(shuf1, shuf2), shuf3); +} + +// Extract the maximum value from a +QT3DS_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + + return _mm_min_ps(_mm_min_ps(shuf1, shuf2), shuf3); +} + +// return (a >= 0.0f) ? 1.0f : -1.0f; +QT3DS_FORCE_INLINE Vec3V V3Sign(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 one = V3One(); + const __m128 none = V3Neg(one); + return V3Sel(V3IsGrtrOrEq(a, zero), one, none); +} + +QT3DS_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(minV)); + VECMATHAOS_ASSERT(isValidVec3V(maxV)); + return V3Max(V3Min(a, maxV), minV); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtr(const Vec3V a, const Vec3V b) +{ + return BAllTrue3_R(V4IsGrtr(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) +{ + return BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3AllEq(const Vec3V a, const Vec3V b) +{ + return BAllTrue3_R(V4IsEq(a, b)); +} + +QT3DS_FORCE_INLINE Vec3V V3Round(const Vec3V a) +{ + // return _mm_round_ps(a, 0x0); + const Vec3V half = Vec3V_From_F32(0.5f); + const Vec3V aPlusHalf = V3Add(a, half); + __m128i tmp = _mm_cvttps_epi32(aPlusHalf); + return _mm_cvtepi32_ps(tmp); +} + +QT3DS_FORCE_INLINE Vec3V V3Sin(const Vec3V a) +{ + // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + Vec3V Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec3V tmp = V3Mul(a, twoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V3 = V3Mul(V2, V1); + const Vec3V V5 = V3Mul(V3, V2); + const Vec3V V7 = V3Mul(V5, V2); + const Vec3V V9 = V3Mul(V7, V2); + const Vec3V V11 = V3Mul(V9, V2); + const Vec3V V13 = V3Mul(V11, V2); + const Vec3V V15 = V3Mul(V13, V2); + const Vec3V V17 = V3Mul(V15, V2); + const Vec3V V19 = V3Mul(V17, V2); + const Vec3V V21 = V3Mul(V19, V2); + const Vec3V V23 = V3Mul(V21, V2); + + const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Result = V3MulAdd(S1, V3, V1); + Result = V3MulAdd(S2, V5, Result); + Result = V3MulAdd(S3, V7, Result); + Result = V3MulAdd(S4, V9, Result); + Result = V3MulAdd(S5, V11, Result); + Result = V3MulAdd(S6, V13, Result); + Result = V3MulAdd(S7, V15, Result); + Result = V3MulAdd(S8, V17, Result); + Result = V3MulAdd(S9, V19, Result); + Result = V3MulAdd(S10, V21, Result); + Result = V3MulAdd(S11, V23, Result); + + return Result; +} + +QT3DS_FORCE_INLINE Vec3V V3Cos(const Vec3V a) +{ + // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + Vec3V Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec3V tmp = V3Mul(a, twoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V4 = V3Mul(V2, V2); + const Vec3V V6 = V3Mul(V4, V2); + const Vec3V V8 = V3Mul(V4, V4); + const Vec3V V10 = V3Mul(V6, V4); + const Vec3V V12 = V3Mul(V6, V6); + const Vec3V V14 = V3Mul(V8, V6); + const Vec3V V16 = V3Mul(V8, V8); + const Vec3V V18 = V3Mul(V10, V8); + const Vec3V V20 = V3Mul(V10, V10); + const Vec3V V22 = V3Mul(V12, V10); + + const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Result = V3MulAdd(C1, V2, V4One()); + Result = V3MulAdd(C2, V4, Result); + Result = V3MulAdd(C3, V6, Result); + Result = V3MulAdd(C4, V8, Result); + Result = V3MulAdd(C5, V10, Result); + Result = V3MulAdd(C6, V12, Result); + Result = V3MulAdd(C7, V14, Result); + Result = V3MulAdd(C8, V16, Result); + Result = V3MulAdd(C9, V18, Result); + Result = V3MulAdd(C10, V20, Result); + Result = V3MulAdd(C11, V22, Result); + + return Result; +} + +QT3DS_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 2, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 0)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 2, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 0, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) +{ + return _mm_shuffle_ps(v1, v0, _MM_SHUFFLE(3, 1, 2, 3)); +} + +QT3DS_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) +{ + return _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 0, 3, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) +{ + // There must be a better way to do this. + Vec3V v2 = V3Zero(); + FloatV y1 = V3GetY(v1); + FloatV x0 = V3GetX(v0); + v2 = V3SetX(v2, y1); + return V3SetY(v2, x0); +} + +QT3DS_FORCE_INLINE FloatV V3SumElems(const Vec3V a) +{ + __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + const BoolV ffff = BFFFF(); + const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); + return !BAllEq(c, ffff); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + const BoolV tttt = BTTTT(); + const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); + return BAllEq(c, tttt); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) +{ + return V3OutOfBounds(a, V3Neg(bounds), bounds); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V bounds) +{ + return V3InBounds(a, V3Neg(bounds), bounds); +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec4V V4Splat(const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatV *const floatVArray) +{ + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[0])); + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[1])); + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[2])); + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[3])); + __m128 xw = _mm_move_ss(floatVArray[1], floatVArray[0]); // y, y, y, x + __m128 yz = _mm_move_ss(floatVArray[2], floatVArray[3]); // z, z, z, w + return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); +} + +QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, + const FloatVArg w) +{ + VECMATHAOS_ASSERT(isValidFloatV(x)); + VECMATHAOS_ASSERT(isValidFloatV(y)); + VECMATHAOS_ASSERT(isValidFloatV(z)); + VECMATHAOS_ASSERT(isValidFloatV(w)); + __m128 xw = _mm_move_ss(y, x); // y, y, y, x + __m128 yz = _mm_move_ss(z, w); // z, z, z, w + return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); +} + +QT3DS_FORCE_INLINE Vec4V V4UnitW() +{ + const QT3DS_ALIGN(16, QT3DSF32) w[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + const __m128 w128 = _mm_load_ps(w); + return w128; +} + +QT3DS_FORCE_INLINE Vec4V V4UnitX() +{ + const QT3DS_ALIGN(16, QT3DSF32) x[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +QT3DS_FORCE_INLINE Vec4V V4UnitY() +{ + const QT3DS_ALIGN(16, QT3DSF32) y[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +QT3DS_FORCE_INLINE Vec4V V4UnitZ() +{ + const QT3DS_ALIGN(16, QT3DSF32) z[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +QT3DS_FORCE_INLINE FloatV V4GetW(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +QT3DS_FORCE_INLINE FloatV V4GetX(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE FloatV V4GetY(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +QT3DS_FORCE_INLINE FloatV V4GetZ(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +QT3DS_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BTTTF(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BFTTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BTFTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BTTFT(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4Zero() +{ + return Vec4V_From_F32(0.0f); +} + +QT3DS_FORCE_INLINE Vec4V V4One() +{ + return Vec4V_From_F32(1.0f); +} + +QT3DS_FORCE_INLINE Vec3V V4Eps() +{ + return Vec3V_From_F32(QT3DS_ENV_REAL); +} + +QT3DS_FORCE_INLINE Vec4V V4Neg(const Vec4V f) +{ + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +QT3DS_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) +{ + return _mm_add_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) +{ + return _mm_sub_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) +{ + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) +{ + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE Vec4V V4Recip(const Vec4V a) +{ + return _mm_rcp_ps(a); +} + +QT3DS_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) +{ + return V4Recip(a); +} + +QT3DS_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) +{ + return _mm_rsqrt_ps(a); +} + +QT3DS_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) +{ + return V4Rsqrt(a); +} + +QT3DS_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return V4Add(V4Scale(a, b), c); +} + +QT3DS_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return V4Sub(c, V4Scale(a, b)); +} + +QT3DS_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Add(V4Scale(a, b), c); +} + +QT3DS_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Sub(c, V4Scale(a, b)); +} + +QT3DS_FORCE_INLINE Vec4V V4Abs(const Vec4V a) +{ + return V4Max(a, V3Neg(a)); +} + +QT3DS_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) +{ + __m128 dot1 = _mm_mul_ps(a, b); // x,y,z,w + __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 1, 0, 3)); // w,x,y,z + __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 0, 3, 2)); // z,w,x,y + __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 3, 2, 1)); // y,z,w,x + return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1, shuf1)); +} + +QT3DS_FORCE_INLINE FloatV V4Length(const Vec4V a) +{ + return _mm_sqrt_ps(V4Dot(a, a)); +} + +QT3DS_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) +{ + return V4Dot(a, a); +} + +QT3DS_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) +{ + return V4ScaleInv(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) +{ + return V4ScaleInvFast(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a) +{ + const __m128 zero = FloatV_From_F32(0.0f); + const __m128 length = V4Length(a); + const __m128 isGreaterThanZero = FIsGrtr(length, zero); + return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), zero); +} + +QT3DS_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) +{ + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) +{ + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +QT3DS_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) +{ + return _mm_cmpgt_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpge_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V4Max(const Vec4V a, const Vec4V b) +{ + return _mm_max_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) +{ + return _mm_min_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) +{ + __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_max_ps(_mm_max_ps(a, shuf1), _mm_max_ps(shuf2, shuf3)); +} + +QT3DS_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) +{ + return V4Max(V4Min(a, maxV), minV); +} + +QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtr(const Vec4V a, const Vec4V b) +{ + return BAllTrue4_R(V4IsGrtr(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return BAllTrue4_R(V4IsGrtrOrEq(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V4AllEq(const Vec4V a, const Vec4V b) +{ + return BAllTrue4_R(V4IsEq(a, b)); +} + +QT3DS_FORCE_INLINE Vec4V V4Round(const Vec4V a) +{ + // return _mm_round_ps(a, 0x0); + const Vec3V half = Vec3V_From_F32(0.5f); + const Vec3V aPlusHalf = V3Add(a, half); + __m128i tmp = _mm_cvttps_epi32(aPlusHalf); + return _mm_cvtepi32_ps(tmp); +} + +QT3DS_FORCE_INLINE Vec4V V4Sin(const Vec4V a) +{ + // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + Vec4V Result; + + const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec4V tmp = V4Mul(a, twoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V3 = V4Mul(V2, V1); + const Vec4V V5 = V4Mul(V3, V2); + const Vec4V V7 = V4Mul(V5, V2); + const Vec4V V9 = V4Mul(V7, V2); + const Vec4V V11 = V4Mul(V9, V2); + const Vec4V V13 = V4Mul(V11, V2); + const Vec4V V15 = V4Mul(V13, V2); + const Vec4V V17 = V4Mul(V15, V2); + const Vec4V V19 = V4Mul(V17, V2); + const Vec4V V21 = V4Mul(V19, V2); + const Vec4V V23 = V4Mul(V21, V2); + + const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Result = V4MulAdd(S1, V3, V1); + Result = V4MulAdd(S2, V5, Result); + Result = V4MulAdd(S3, V7, Result); + Result = V4MulAdd(S4, V9, Result); + Result = V4MulAdd(S5, V11, Result); + Result = V4MulAdd(S6, V13, Result); + Result = V4MulAdd(S7, V15, Result); + Result = V4MulAdd(S8, V17, Result); + Result = V4MulAdd(S9, V19, Result); + Result = V4MulAdd(S10, V21, Result); + Result = V4MulAdd(S11, V23, Result); + + return Result; +} + +QT3DS_FORCE_INLINE Vec4V V4Cos(const Vec4V a) +{ + // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + Vec4V Result; + + const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec4V tmp = V4Mul(a, twoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V4 = V4Mul(V2, V2); + const Vec4V V6 = V4Mul(V4, V2); + const Vec4V V8 = V4Mul(V4, V4); + const Vec4V V10 = V4Mul(V6, V4); + const Vec4V V12 = V4Mul(V6, V6); + const Vec4V V14 = V4Mul(V8, V6); + const Vec4V V16 = V4Mul(V8, V8); + const Vec4V V18 = V4Mul(V10, V8); + const Vec4V V20 = V4Mul(V10, V10); + const Vec4V V22 = V4Mul(V12, V10); + + const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Result = V4MulAdd(C1, V2, V4One()); + Result = V4MulAdd(C2, V4, Result); + Result = V4MulAdd(C3, V6, Result); + Result = V4MulAdd(C4, V8, Result); + Result = V4MulAdd(C5, V10, Result); + Result = V4MulAdd(C6, V12, Result); + Result = V4MulAdd(C7, V14, Result); + Result = V4MulAdd(C8, V16, Result); + Result = V4MulAdd(C9, V18, Result); + Result = V4MulAdd(C10, V20, Result); + Result = V4MulAdd(C11, V22, Result); + + return Result; +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +QT3DS_FORCE_INLINE BoolV BFFFF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0, 0 }; + const __m128 ffff = _mm_load_ps((float *)&f); + return ffff; +} + +QT3DS_FORCE_INLINE BoolV BFFFT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0, 0xFFFFFFFF }; + const __m128 ffft = _mm_load_ps((float *)&f); + return ffft; +} + +QT3DS_FORCE_INLINE BoolV BFFTF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0xFFFFFFFF, 0 }; + const __m128 fftf = _mm_load_ps((float *)&f); + return fftf; +} + +QT3DS_FORCE_INLINE BoolV BFFTT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 fftt = _mm_load_ps((float *)&f); + return fftt; +} + +QT3DS_FORCE_INLINE BoolV BFTFF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0, 0 }; + const __m128 ftff = _mm_load_ps((float *)&f); + return ftff; +} + +QT3DS_FORCE_INLINE BoolV BFTFT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0, 0xFFFFFFFF }; + const __m128 ftft = _mm_load_ps((float *)&f); + return ftft; +} + +QT3DS_FORCE_INLINE BoolV BFTTF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; + const __m128 fttf = _mm_load_ps((float *)&f); + return fttf; +} + +QT3DS_FORCE_INLINE BoolV BFTTT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 fttt = _mm_load_ps((float *)&f); + return fttt; +} + +QT3DS_FORCE_INLINE BoolV BTFFF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0, 0 }; + const __m128 tfff = _mm_load_ps((float *)&f); + return tfff; +} + +QT3DS_FORCE_INLINE BoolV BTFFT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0, 0xFFFFFFFF }; + const __m128 tfft = _mm_load_ps((float *)&f); + return tfft; +} + +QT3DS_FORCE_INLINE BoolV BTFTF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0 }; + const __m128 tftf = _mm_load_ps((float *)&f); + return tftf; +} + +QT3DS_FORCE_INLINE BoolV BTFTT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 tftt = _mm_load_ps((float *)&f); + return tftt; +} + +QT3DS_FORCE_INLINE BoolV BTTFF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0 }; + const __m128 ttff = _mm_load_ps((float *)&f); + return ttff; +} + +QT3DS_FORCE_INLINE BoolV BTTFT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF }; + const __m128 ttft = _mm_load_ps((float *)&f); + return ttft; +} + +QT3DS_FORCE_INLINE BoolV BTTTF() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; + const __m128 tttf = _mm_load_ps((float *)&f); + return tttf; +} + +QT3DS_FORCE_INLINE BoolV BTTTT() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 tttt = _mm_load_ps((float *)&f); + return tttt; +} + +QT3DS_FORCE_INLINE BoolV BXMask() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0xFFFFFFFF, 0, 0, 0 }; + const __m128 tfff = _mm_load_ps((float *)&f); + return tfff; +} + +QT3DS_FORCE_INLINE BoolV BYMask() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0xFFFFFFFF, 0, 0 }; + const __m128 ftff = _mm_load_ps((float *)&f); + return ftff; +} + +QT3DS_FORCE_INLINE BoolV BZMask() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0xFFFFFFFF, 0 }; + const __m128 fftf = _mm_load_ps((float *)&f); + return fftf; +} + +QT3DS_FORCE_INLINE BoolV BWMask() +{ + const QT3DS_ALIGN(16, QT3DSU32) f[4] = { 0, 0, 0, 0xFFFFFFFF }; + const __m128 ffft = _mm_load_ps((float *)&f); + return ffft; +} + +QT3DS_FORCE_INLINE BoolV BGetX(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE BoolV BGetY(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +QT3DS_FORCE_INLINE BoolV BGetZ(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +QT3DS_FORCE_INLINE BoolV BGetW(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +QT3DS_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) +{ + return (_mm_and_ps(a, b)); +} + +QT3DS_FORCE_INLINE BoolV BNot(const BoolV a) +{ + const BoolV bAllTrue(BTTTT()); + return _mm_xor_ps(a, bAllTrue); +} + +QT3DS_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) +{ + return (_mm_andnot_ps(a, b)); +} + +QT3DS_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) +{ + return (_mm_or_ps(a, b)); +} + +QT3DS_FORCE_INLINE BoolV BAllTrue4(const BoolV a) +{ + const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) +{ + const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE BoolV BAllTrue3(const BoolV a) +{ + const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) +{ + const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAllEq(const BoolV a, const BoolV b) +{ + const BoolV bTest = m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); + return BAllTrue4_R(bTest); +} + +////////////////////////////////// +// MAT33V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec3V M33MulV3(const Mat33V &a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +QT3DS_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V &a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +QT3DS_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V &A, const Vec3V b, const Vec3V c) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + Vec3V result = V3MulAdd(A.col0, x, c); + result = V3MulAdd(A.col1, y, result); + return V3MulAdd(A.col2, z, result); +} + +QT3DS_FORCE_INLINE Mat33V M33MulM33(const Mat33V &a, const Mat33V &b) +{ + return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Add(const Mat33V &a, const Mat33V &b) +{ + return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Inverse(const Mat33V &a) +{ + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = FloatV_From_F32(0.0f); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + + return Mat33V(_mm_mul_ps(colInv0, invDet), _mm_mul_ps(colInv1, invDet), + _mm_mul_ps(colInv2, invDet)); +} + +QT3DS_FORCE_INLINE Mat33V M33Trnsps(const Mat33V &a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +QT3DS_FORCE_INLINE Mat33V M33Identity() +{ + return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); +} + +QT3DS_FORCE_INLINE Mat33V M33Sub(const Mat33V &a, const Mat33V &b) +{ + return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Neg(const Mat33V &a) +{ + return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Abs(const Mat33V &a) +{ + return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); +} + +QT3DS_FORCE_INLINE Mat33V PromoteVec3V(const Vec3V v) +{ + const BoolV bTFFF = BTFFF(); + const BoolV bFTFF = BFTFF(); + const BoolV bFFTF = BTFTF(); + + const Vec3V zero = V3Zero(); + + return Mat33V(V3Sel(bTFFF, v, zero), V3Sel(bFTFF, v, zero), V3Sel(bFFTF, v, zero)); +} + +QT3DS_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) +{ + const FloatV x = V3Mul(V3UnitX(), d); + const FloatV y = V3Mul(V3UnitY(), d); + const FloatV z = V3Mul(V3UnitZ(), d); + return Mat33V(x, y, z); +} + +////////////////////////////////// +// MAT34V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec3V M34MulV3(const Mat34V &a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); + return (V3Add(v0PlusV1Plusv2, a.col3)); +} + +QT3DS_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V &a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +QT3DS_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V &a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +QT3DS_FORCE_INLINE Mat34V M34MulM34(const Mat34V &a, const Mat34V &b) +{ + return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), + M34MulV3(a, b.col3)); +} + +QT3DS_FORCE_INLINE Mat33V M34MulM33(const Mat34V &a, const Mat33V &b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V &a, const Mat34V &b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +QT3DS_FORCE_INLINE Mat34V M34Add(const Mat34V &a, const Mat34V &b) +{ + return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), + V3Add(a.col3, b.col3)); +} + +QT3DS_FORCE_INLINE Mat34V M34InverseV(const Mat34V &a) +{ + Mat34V aInv; + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = FloatV_From_F32(0.0f); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + aInv.col0 = _mm_mul_ps(colInv0, invDet); + aInv.col1 = _mm_mul_ps(colInv1, invDet); + aInv.col2 = _mm_mul_ps(colInv2, invDet); + aInv.col3 = M34Mul33V3(aInv, V3Neg(a.col3)); + return aInv; +} + +QT3DS_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V &a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +////////////////////////////////// +// MAT44V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec4V M44MulV4(const Mat44V &a, const Vec4V b) +{ + const FloatV x = V4GetX(b); + const FloatV y = V4GetY(b); + const FloatV z = V4GetZ(b); + const FloatV w = V4GetW(b); + + const Vec4V v0 = V4Scale(a.col0, x); + const Vec4V v1 = V4Scale(a.col1, y); + const Vec4V v2 = V4Scale(a.col2, z); + const Vec4V v3 = V4Scale(a.col3, w); + const Vec4V v0PlusV1 = V4Add(v0, v1); + const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); + return (V4Add(v0PlusV1Plusv2, v3)); +} + +QT3DS_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V &a, const Vec4V b) +{ + QT3DS_ALIGN(16, FloatV) + dotProdArray[4] = { V4Dot(a.col0, b), V4Dot(a.col1, b), V4Dot(a.col2, b), V4Dot(a.col3, b) }; + return V4Merge(dotProdArray); +} + +QT3DS_FORCE_INLINE Mat44V M44MulM44(const Mat44V &a, const Mat44V &b) +{ + return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), + M44MulV4(a, b.col3)); +} + +QT3DS_FORCE_INLINE Mat44V M44Add(const Mat44V &a, const Mat44V &b) +{ + return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), + V4Add(a.col3, b.col3)); +} + +QT3DS_FORCE_INLINE Mat44V M44Trnsps(const Mat44V &a) +{ + const Vec4V v0 = _mm_unpacklo_ps(a.col0, a.col2); + const Vec4V v1 = _mm_unpackhi_ps(a.col0, a.col2); + const Vec4V v2 = _mm_unpacklo_ps(a.col1, a.col3); + const Vec4V v3 = _mm_unpackhi_ps(a.col1, a.col3); + return Mat44V(_mm_unpacklo_ps(v0, v2), _mm_unpackhi_ps(v0, v2), _mm_unpacklo_ps(v1, v3), + _mm_unpackhi_ps(v1, v3)); +} + +QT3DS_FORCE_INLINE Mat44V M44Inverse(const Mat44V &a) +{ + __m128 minor0, minor1, minor2, minor3; + __m128 row0, row1, row2, row3; + __m128 det, tmp1; + + tmp1 = FloatV_From_F32(0.0f); + row1 = FloatV_From_F32(0.0f); + row3 = FloatV_From_F32(0.0f); + + row0 = a.col0; + row1 = _mm_shuffle_ps(a.col1, a.col1, _MM_SHUFFLE(1, 0, 3, 2)); + row2 = a.col2; + row3 = _mm_shuffle_ps(a.col3, a.col3, _MM_SHUFFLE(1, 0, 3, 2)); + + tmp1 = _mm_mul_ps(row2, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_mul_ps(row1, tmp1); + minor1 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); + minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); + minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); + + tmp1 = _mm_mul_ps(row1, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); + minor3 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); + minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); + + tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + row2 = _mm_shuffle_ps(row2, row2, 0x4E); + minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); + minor2 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); + minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); + + tmp1 = _mm_mul_ps(row0, row1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); + + tmp1 = _mm_mul_ps(row0, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); + minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); + + tmp1 = _mm_mul_ps(row0, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); + + det = _mm_mul_ps(row0, minor0); + det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); + det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); + tmp1 = _mm_rcp_ss(det); +#if 0 + det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); + det = _mm_shuffle_ps(det, det, 0x00); +#else + det = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 0, 0, 0)); +#endif + + minor0 = _mm_mul_ps(det, minor0); + minor1 = _mm_mul_ps(det, minor1); + minor2 = _mm_mul_ps(det, minor2); + minor3 = _mm_mul_ps(det, minor3); + Mat44V invTrans(minor0, minor1, minor2, minor3); + return M44Trnsps(invTrans); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_XYZW(QT3DSF32 x, QT3DSF32 y, QT3DSF32 z, QT3DSF32 w) +{ + return _mm_set_ps(w, z, y, x); +} + +// AP: work in progress - use proper SSE intrinsics where possible +QT3DS_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) +{ + VecU16V result; + result.m128_u16[0] = QT3DSU16(NVClamp((a).m128_u32[0], 0, 0xFFFF)); + result.m128_u16[1] = QT3DSU16(NVClamp((a).m128_u32[1], 0, 0xFFFF)); + result.m128_u16[2] = QT3DSU16(NVClamp((a).m128_u32[2], 0, 0xFFFF)); + result.m128_u16[3] = QT3DSU16(NVClamp((a).m128_u32[3], 0, 0xFFFF)); + result.m128_u16[4] = QT3DSU16(NVClamp((b).m128_u32[0], 0, 0xFFFF)); + result.m128_u16[5] = QT3DSU16(NVClamp((b).m128_u32[1], 0, 0xFFFF)); + result.m128_u16[6] = QT3DSU16(NVClamp((b).m128_u32[2], 0, 0xFFFF)); + result.m128_u16[7] = QT3DSU16(NVClamp((b).m128_u32[3], 0, 0xFFFF)); + return result; +} + +QT3DS_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32(const QT3DSI32 i) +{ + return (_mm_load1_ps((QT3DSF32 *)&i)); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array(const QT3DSI32 *i) +{ + return _mm_loadu_ps((QT3DSF32 *)i); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array_Aligned(const QT3DSI32 *i) +{ + return _mm_load_ps((QT3DSF32 *)i); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_add_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_sub_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_cmpgt_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Zero() +{ + return V4Zero(); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, + const VecI32VArg d) +{ + return V4Merge(a, b, c, d); +} + +template +QT3DS_FORCE_INLINE VecI32V V4ISplat() +{ + VecI32V result; + result.m128_i32[0] = a; + result.m128_i32[1] = a; + result.m128_i32[2] = a; + result.m128_i32[3] = a; + return result; +} + +QT3DS_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V *address) +{ + *address = val; +} + +QT3DS_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V *address) +{ + *address = val; +} + +QT3DS_FORCE_INLINE Vec4V V4LoadAligned(Vec4V *addr) +{ + return *addr; +} + +QT3DS_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V *addr) +{ + return Vec4V_From_F32Array((float *)addr); +} + +QT3DS_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) +{ + VecU32V result32(a); + result32 = V4U32Andc(result32, b); + return Vec4V(result32); +} + +QT3DS_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) +{ + return V4IsGrtr(a, b); +} + +QT3DS_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V *addr) +{ + return *addr; +} + +QT3DS_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V *addr) +{ + return *addr; +} + +QT3DS_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) +{ + // _mm_cmpgt_epi16 doesn't work for unsigned values unfortunately + // return m128_I2F(_mm_cmpgt_epi16(m128_F2I(a), m128_F2I(b))); + VecU16V result; + result.m128_u16[0] = (a).m128_u16[0] > (b).m128_u16[0]; + result.m128_u16[1] = (a).m128_u16[1] > (b).m128_u16[1]; + result.m128_u16[2] = (a).m128_u16[2] > (b).m128_u16[2]; + result.m128_u16[3] = (a).m128_u16[3] > (b).m128_u16[3]; + result.m128_u16[4] = (a).m128_u16[4] > (b).m128_u16[4]; + result.m128_u16[5] = (a).m128_u16[5] > (b).m128_u16[5]; + result.m128_u16[6] = (a).m128_u16[6] > (b).m128_u16[6]; + result.m128_u16[7] = (a).m128_u16[7] > (b).m128_u16[7]; + return result; +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) +{ + Vec4V result = Vec4V_From_XYZW(QT3DSF32(a.m128_u32[0]), QT3DSF32(a.m128_u32[1]), QT3DSF32(a.m128_u32[2]), + QT3DSF32(a.m128_u32[3])); + return result; +} + +template +QT3DS_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) +{ + VecU32V result; + result.m128_u32[0] = result.m128_u32[1] = result.m128_u32[2] = result.m128_u32[3] = + a.m128_u32[index]; + return result; +} + +template +QT3DS_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) +{ + float *data = (float *)&a; + return Vec4V_From_F32(data[index]); +} + +template +QT3DS_FORCE_INLINE VecU16V V4U16SplatElement(VecU16V a) +{ + VecU16V result; + for (int i = 0; i < 8; i++) + result.m128_u16[i] = a.m128_u16[index]; + return result; +} + +template +QT3DS_FORCE_INLINE VecI16V V4I16SplatImmediate() +{ + VecI16V result; + result.m128_i16[0] = imm; + result.m128_i16[1] = imm; + result.m128_i16[2] = imm; + result.m128_i16[3] = imm; + result.m128_i16[4] = imm; + result.m128_i16[5] = imm; + result.m128_i16[6] = imm; + result.m128_i16[7] = imm; + return result; +} + +QT3DS_FORCE_INLINE VecU16V V4U16SubtractModulo(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_sub_epi16(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16AddModulo(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_add_epi16(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU32V V4U16GetLo16(VecU16V a) +{ + VecU32V result; + result.m128_u32[0] = a.m128_u16[0]; + result.m128_u32[1] = a.m128_u16[2]; + result.m128_u32[2] = a.m128_u16[4]; + result.m128_u32[3] = a.m128_u16[6]; + return result; +} + +QT3DS_FORCE_INLINE VecU32V V4U16GetHi16(VecU16V a) +{ + VecU32V result; + result.m128_u32[0] = a.m128_u16[1]; + result.m128_u32[1] = a.m128_u16[3]; + result.m128_u32[2] = a.m128_u16[5]; + result.m128_u32[3] = a.m128_u16[7]; + return result; +} + +QT3DS_FORCE_INLINE VecU32V VecU32V_From_XYZW(QT3DSU32 x, QT3DSU32 y, QT3DSU32 z, QT3DSU32 w) +{ + VecU32V result; + result.m128_u32[0] = x; + result.m128_u32[1] = y; + result.m128_u32[2] = z; + result.m128_u32[3] = w; + return result; +} + +QT3DS_FORCE_INLINE Vec4V V4Ceil(const Vec4V in) +{ + UnionM128 a(in); + return Vec4V_From_XYZW(NVCeil(a.m128_f32[0]), NVCeil(a.m128_f32[1]), NVCeil(a.m128_f32[2]), + NVCeil(a.m128_f32[3])); +} + +QT3DS_FORCE_INLINE Vec4V V4Floor(const Vec4V in) +{ + UnionM128 a(in); + return Vec4V_From_XYZW(NVFloor(a.m128_f32[0]), NVFloor(a.m128_f32[1]), NVFloor(a.m128_f32[2]), + NVFloor(a.m128_f32[3])); +} + +QT3DS_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V in, QT3DSU32 power) +{ + QT3DS_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); + QT3DS_FORCE_PARAMETER_REFERENCE(power); // prevent warning in release builds + QT3DSF32 ffffFFFFasFloat = QT3DSF32(0xFFFF0000); + UnionM128 a(in); + VecU32V result; + result.m128_u32[0] = QT3DSU32(NVClamp((a).m128_f32[0], 0.0f, ffffFFFFasFloat)); + result.m128_u32[1] = QT3DSU32(NVClamp((a).m128_f32[1], 0.0f, ffffFFFFasFloat)); + result.m128_u32[2] = QT3DSU32(NVClamp((a).m128_f32[2], 0.0f, ffffFFFFasFloat)); + result.m128_u32[3] = QT3DSU32(NVClamp((a).m128_f32[3], 0.0f, ffffFFFFasFloat)); + return result; +} + +#endif // QT3DS_LINUX_INLINE_AOS_H diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxIntrinsics.h b/src/Runtime/Source/foundation/linux/Qt3DSLinuxIntrinsics.h new file mode 100644 index 00000000..70974609 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxIntrinsics.h @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_LINUX_INTRINSICS_H +#define QT3DS_FOUNDATION_QT3DS_LINUX_INTRINSICS_H + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" + +#if !(defined QT3DS_LINUX || defined QT3DS_ANDROID || defined QT3DS_APPLE || defined QT3DS_QNX) +#error "This file should only be included by Linux builds!!" +#endif + +#include +#include +#include +#include + +namespace qt3ds { +namespace intrinsics { + //! \brief platform-specific absolute value + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float abs(float a) { return ::fabs(a); } + + //! \brief platform-specific select float + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float fsel(float a, float b, float c) + { + return (a >= 0.0f) ? b : c; + } + + //! \brief platform-specific sign + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sign(float a) { return (a >= 0.0f) ? 1.0f : -1.0f; } + + //! \brief platform-specific reciprocal + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recip(float a) { return 1.0f / a; } + + //! \brief platform-specific reciprocal estimate + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipFast(float a) { return 1.0f / a; } + + //! \brief platform-specific square root + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sqrt(float a) { return ::sqrtf(a); } + + //! \brief platform-specific reciprocal square root + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrt(float a) { return 1.0f / ::sqrtf(a); } + + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrtFast(float a) { return 1.0f / ::sqrtf(a); } + + //! \brief platform-specific sine + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sin(float a) { return ::sinf(a); } + + //! \brief platform-specific cosine + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float cos(float a) { return ::cosf(a); } + + //! \brief platform-specific minimum + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMin(float a, float b) { return a < b ? a : b; } + + //! \brief platform-specific maximum + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMax(float a, float b) { return a > b ? a : b; } + + //! \brief platform-specific finiteness check (not INF or NAN) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(float a) { return std::isfinite(a); } + + //! \brief platform-specific finiteness check (not INF or NAN) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(double a) { return std::isfinite(a); } + QT3DS_FORCE_INLINE void memoryBarrier() + { +#if 0 //!defined (QT3DS_ARM) + smp_mb(); +#endif + } + + /*! + Return the index of the highest set bit. Undefined for zero arg. + */ + QT3DS_INLINE QT3DSU32 highestSetBitUnsafe(QT3DSU32 v) + { + + // http://graphics.stanford.edu/~seander/bithacks.html + static const QT3DSU32 MultiplyDeBruijnBitPosition[32] = { 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31 }; + + v |= v >> 1; // first round up to one less than a power of 2 + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + return MultiplyDeBruijnBitPosition[(QT3DSU32)(v * 0x07C4ACDDU) >> 27]; + } + + /*! + Return the index of the highest set bit. Undefined for zero arg. + */ + QT3DS_INLINE QT3DSI32 lowestSetBitUnsafe(QT3DSU32 v) + { + // http://graphics.stanford.edu/~seander/bithacks.html + static const QT3DSU32 MultiplyDeBruijnBitPosition[32] = { 0, 1, 28, 2, 29, 14, 24, 3, + 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, + 26, 12, 18, 6, 11, 5, 10, 9 }; + QT3DSI32 w = v; + return MultiplyDeBruijnBitPosition[(QT3DSU32)((w & -w) * 0x077CB531U) >> 27]; + } + + /*! + Returns the index of the highest set bit. Undefined for zero arg. + */ + QT3DS_INLINE QT3DSU32 countLeadingZeros(QT3DSU32 v) + { + QT3DSI32 result = 0; +#ifdef _INTEGRITYPLATFORM + QT3DSU32 testBit = (1U << 31); +#else + QT3DSU32 testBit = (1 << 31); +#endif + while ((v & testBit) == 0 && testBit != 0) + result++, testBit >>= 1; + return result; + } + + /*! + Sets \c count bytes starting at \c dst to zero. + */ + QT3DS_FORCE_INLINE void *memZero(void *QT3DS_RESTRICT dest, QT3DSU32 count) + { + return memset(dest, 0, count); + } + + /*! + Sets \c count bytes starting at \c dst to \c c. + */ + QT3DS_FORCE_INLINE void *memSet(void *QT3DS_RESTRICT dest, QT3DSI32 c, QT3DSU32 count) + { + return memset(dest, c, count); + } + + /*! + Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. + */ + QT3DS_FORCE_INLINE void *memCopy(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) + { + return memcpy(dest, src, count); + } + + /*! + Copies \c count bytes from \c src to \c dst. Supports overlapping regions. + */ + QT3DS_FORCE_INLINE void *memMove(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) + { + return memmove(dest, src, count); + } + + /*! + Set 128B to zero starting at \c dst+offset. Must be aligned. + */ + QT3DS_FORCE_INLINE void memZero128(void *QT3DS_RESTRICT dest, QT3DSU32 offset = 0) + { + QT3DS_ASSERT(((size_t(dest) + offset) & 0x7f) == 0); + memSet((char *QT3DS_RESTRICT)dest + offset, 0, 128); + } + + /*! + Prefetch aligned 128B around \c ptr+offset. + */ + QT3DS_FORCE_INLINE void prefetch128(const void *, QT3DSU32 = 0) {} + + /*! + Prefetch \c count bytes starting at \c ptr. + */ + QT3DS_FORCE_INLINE void prefetch(const void *ptr, QT3DSU32 count = 0) + { + for (QT3DSU32 i = 0; i <= count; i += 128) + prefetch128(ptr, i); + } + + //! \brief platform-specific floor + QT3DS_FORCE_INLINE float floatFloor(float x) { return ::floorf(x); } +} // namespace intrinsics +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxMutex.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxMutex.cpp new file mode 100644 index 00000000..bbc55829 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxMutex.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAtomic.h" + +#include + +namespace qt3ds { +namespace foundation { + + namespace { + pthread_mutex_t *getMutex(MutexImpl *impl) + { + return reinterpret_cast(impl); + } + } + + MutexImpl::MutexImpl() + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(getMutex(this), &attr); + pthread_mutexattr_destroy(&attr); + } + + MutexImpl::~MutexImpl() { pthread_mutex_destroy(getMutex(this)); } + + bool MutexImpl::lock() { return !pthread_mutex_lock(getMutex(this)); } + + bool MutexImpl::trylock() { return !pthread_mutex_trylock(getMutex(this)); } + + bool MutexImpl::unlock() { return !pthread_mutex_unlock(getMutex(this)); } + + const QT3DSU32 MutexImpl::size = sizeof(pthread_mutex_t); + + class ReadWriteLockImpl + { + public: + ReadWriteLockImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + pthread_mutex_t mutex; + volatile int readerCounter; + }; + + ReadWriteLock::ReadWriteLock(NVAllocatorCallback &alloc) + { + mImpl = QT3DS_NEW(alloc, ReadWriteLockImpl)(alloc); + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mImpl->mutex, &attr); + pthread_mutexattr_destroy(&attr); + + mImpl->readerCounter = 0; + } + + ReadWriteLock::~ReadWriteLock() + { + pthread_mutex_destroy(&mImpl->mutex); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + void ReadWriteLock::lockReader() + { + pthread_mutex_lock(&mImpl->mutex); + + atomicIncrement(&mImpl->readerCounter); + + pthread_mutex_unlock(&mImpl->mutex); + } + + void ReadWriteLock::lockWriter() + { + pthread_mutex_lock(&mImpl->mutex); + + while (mImpl->readerCounter != 0) + ; + } + + void ReadWriteLock::unlockReader() { atomicDecrement(&mImpl->readerCounter); } + + void ReadWriteLock::unlockWriter() { pthread_mutex_unlock(&mImpl->mutex); } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp new file mode 100644 index 00000000..90aab79a --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxSemaphore.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSSemaphore.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSAllocatorCallback.h" + +#include +#include +#include +#include +#include + +namespace qt3ds { +namespace foundation { + + class SemaphoreImpl + { + public: + SemaphoreImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + pthread_mutex_t mutex; + pthread_cond_t cond; + QT3DSU32 count; + QT3DSU32 maxCount; + }; + + struct NVLinuxScopeLock + { + NVLinuxScopeLock(pthread_mutex_t &m) + : mMutex(m) + { + pthread_mutex_lock(&mMutex); + } + + ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } + private: + pthread_mutex_t &mMutex; + }; + + Semaphore::Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount) + { + mImpl = QT3DS_NEW(alloc, SemaphoreImpl)(alloc); + int status = pthread_mutex_init(&mImpl->mutex, 0); + QT3DS_ASSERT(!status); + status = pthread_cond_init(&mImpl->cond, 0); + QT3DS_ASSERT(!status); + mImpl->count = initialCount; + mImpl->maxCount = maxCount; + QT3DS_ASSERT(initialCount <= maxCount); + } + + Semaphore::~Semaphore() + { + pthread_cond_destroy(&mImpl->cond); + pthread_mutex_destroy(&mImpl->mutex); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + bool Semaphore::wait(QT3DSU32 milliseconds) + { + NVLinuxScopeLock lock(mImpl->mutex); + + if (mImpl->count > 0) { + mImpl->count--; + return true; + } + + if (milliseconds == 0) { + return false; + } + + if (milliseconds == QT3DSU32(-1)) { + int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); + QT3DS_ASSERT(!status); + (void)status; + } else { + timespec ts; + timeval tp; + gettimeofday(&tp, NULL); + QT3DSU32 sec = milliseconds / 1000; + QT3DSU32 usec = (milliseconds - 1000 * sec) * 1000; + + // sschirm: taking into account that us might accumulate to a second + // otherwise the pthread_cond_timedwait complains on osx. + usec = tp.tv_usec + usec; + QT3DSU32 div_sec = usec / 1000000; + QT3DSU32 rem_usec = usec - div_sec * 1000000; + + ts.tv_sec = tp.tv_sec + sec + div_sec; + ts.tv_nsec = rem_usec * 1000; + + int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); + QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); + (void)ierr; + return false; + } + + return true; + } + + void Semaphore::post() + { + NVLinuxScopeLock lock(mImpl->mutex); + mImpl->count++; + if (mImpl->count > mImpl->maxCount) + mImpl->count = mImpl->maxCount; + else { + pthread_cond_broadcast(&mImpl->cond); + } + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxString.h b/src/Runtime/Source/foundation/linux/Qt3DSLinuxString.h new file mode 100644 index 00000000..a4645f2b --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxString.h @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_LINUX_STRING_H +#define QT3DS_FOUNDATION_QT3DS_LINUX_STRING_H + +#include "foundation/Qt3DS.h" + +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable : 4995 4996) + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +QT3DS_INLINE void NVStrcpy(char *dest, size_t size, const char *src) +{ + ::strncpy(dest, src, size); +} + +QT3DS_INLINE int NVStrcat(char *dest, size_t size, const char *src) +{ + ::strcat(dest, src); + return 0; +} +QT3DS_INLINE int NVVsprintf(char *dest, size_t size, const char *src, va_list arg) +{ + int r = ::vsprintf(dest, src, arg); + + return r; +} +QT3DS_INLINE int NVStricmp(const char *str, const char *str1) +{ + return (::strcasecmp(str, str1)); +} + +namespace string { + + QT3DS_INLINE void strcpy(char *dest, size_t size, const char *src) { ::strcpy(dest, src); } + QT3DS_INLINE void strcat(char *dest, size_t size, const char *src) { ::strcat(dest, src); } + // QT3DS_INLINE int strcasecmp(const char *str, const char *str1) {return(::strcasecmp(str, + // str1));} + QT3DS_INLINE QT3DSI32 stricmp(const char *str, const char *str1) { return (::strcasecmp(str, str1)); } + QT3DS_INLINE QT3DSI32 strnicmp(const char *str, const char *str1, size_t len) + { + return (::strncasecmp(str, str1, len)); + } + + QT3DS_INLINE QT3DSI32 strncat_s(char *dstBfr, size_t dstSize, const char *srcBfr, size_t numCpy) + { + if (!dstBfr || !srcBfr || !dstSize) + return -1; + + size_t len = strlen(dstBfr); + + if (len >= dstSize) + return -1; + + size_t remain = dstSize - len - 1; + size_t transfer = remain > numCpy ? numCpy : remain; + ::memmove(dstBfr + len, srcBfr, transfer); + dstBfr[len + transfer] = '\0'; + return numCpy <= remain ? 0 : -1; + } + + QT3DS_INLINE QT3DSI32 _vsnprintf(char *dest, size_t size, const char *src, va_list arg) + { + QT3DSI32 r = ::vsnprintf(dest, size, src, arg); + + return r; + } + QT3DS_INLINE QT3DSI32 vsprintf(char *dest, size_t size, const char *src, va_list arg) + { + QT3DSI32 r = ::vsprintf(dest, src, arg); + + return r; + } + QT3DS_INLINE int vsprintf_s(char *dest, size_t size, const char *src, va_list arg) + { + int r = ::vsprintf(dest, src, arg); + + return r; + } + + QT3DS_INLINE int sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...) + { + if (_DstBuf == NULL || _Format == NULL) { + return -1; + } + + va_list arg; + va_start(arg, _Format); + int r = ::vsprintf(_DstBuf, _Format, arg); + va_end(arg); + + return r; + } + + QT3DS_INLINE QT3DSI32 sprintf(char *_DstBuf, size_t _DstSize, const char *_Format, ...) + { + va_list arg; + va_start(arg, _Format); + QT3DSI32 r = ::vsprintf(_DstBuf, _Format, arg); + va_end(arg); + + return r; + } + + QT3DS_INLINE int strncpy_s(char *strDest, size_t sizeInBytes, const char *strSource, size_t count) + { + if (strDest == NULL || strSource == NULL || sizeInBytes == 0) { + return -1; + } + + if (sizeInBytes < count) { + strDest[0] = 0; + return -1; + } + + ::strncpy(strDest, strSource, count); + return 0; + } + + QT3DS_INLINE void strcpy_s(char *dest, size_t size, const char *src) + { + ::strncpy(dest, src, size); + } + + QT3DS_INLINE int strcat_s(char *dest, size_t size, const char *src) + { + ::strcat(dest, src); + return 0; + } + + QT3DS_INLINE QT3DSI32 sscanf(const char *buffer, const char *format, ...) + { + va_list arg; + va_start(arg, format); + QT3DSI32 r = ::sscanf(buffer, format, arg); + va_end(arg); + + return r; + }; + + QT3DS_INLINE void strlwr(char *str) + { + while (*str) { + if (*str >= 'A' && *str <= 'Z') + *str += 32; + str++; + } + } + + QT3DS_INLINE void strupr(char *str) + { + while (*str) { + if (*str >= 'a' && *str <= 'z') + *str -= 32; + str++; + } + } + +} // namespace string + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +#pragma warning(pop) + +#endif diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxSync.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxSync.cpp new file mode 100644 index 00000000..52f9d7ab --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxSync.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSAllocatorCallback.h" + +#include +#include +#include +#include +#include + +namespace qt3ds { +namespace foundation { + + class SyncImpl + { + public: + SyncImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + pthread_mutex_t mutex; + pthread_cond_t cond; + volatile bool is_set; + }; + + struct NVLinuxScopeLock + { + NVLinuxScopeLock(pthread_mutex_t &m) + : mMutex(m) + { + pthread_mutex_lock(&mMutex); + } + + ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } + private: + pthread_mutex_t &mMutex; + }; + + Sync::Sync(NVAllocatorCallback &alloc) + { + mImpl = QT3DS_NEW(alloc, SyncImpl)(alloc); + int status = pthread_mutex_init(&mImpl->mutex, 0); + QT3DS_ASSERT(!status); + status = pthread_cond_init(&mImpl->cond, 0); + QT3DS_ASSERT(!status); + mImpl->is_set = false; + } + + Sync::~Sync() + { + pthread_cond_destroy(&mImpl->cond); + pthread_mutex_destroy(&mImpl->mutex); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + void Sync::reset() + { + NVLinuxScopeLock lock(mImpl->mutex); + mImpl->is_set = false; + } + + void Sync::set() + { + NVLinuxScopeLock lock(mImpl->mutex); + if (!mImpl->is_set) { + mImpl->is_set = true; + pthread_cond_broadcast(&mImpl->cond); + } + } + + bool Sync::wait(QT3DSU32 ms) + { + NVLinuxScopeLock lock(mImpl->mutex); + if (!mImpl->is_set) { + if (ms == QT3DSU32(-1)) { + int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); + QT3DS_ASSERT(!status); + (void)status; + } else { + timespec ts; + timeval tp; + gettimeofday(&tp, NULL); + QT3DSU32 sec = ms / 1000; + QT3DSU32 usec = (ms - 1000 * sec) * 1000; + + // sschirm: taking into account that us might accumulate to a second + // otherwise the pthread_cond_timedwait complains on osx. + usec = tp.tv_usec + usec; + QT3DSU32 div_sec = usec / 1000000; + QT3DSU32 rem_usec = usec - div_sec * 1000000; + + ts.tv_sec = tp.tv_sec + sec + div_sec; + ts.tv_nsec = rem_usec * 1000; + + int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); + QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); + (void)ierr; + } + } + return mImpl->is_set; + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxThread.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxThread.cpp new file mode 100644 index 00000000..fa6e069e --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxThread.cpp @@ -0,0 +1,384 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSThread.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#if !defined(QT3DS_APPLE) && !defined(ANDROID) && !defined(__CYGWIN__) && !defined(__QNX__) && !defined(__INTEGRITY) +#include // PTHREAD_STACK_MIN +#endif +#include +#include +#if !defined(__QNX__) && !defined(__INTEGRITY) +#include +#include +#if !defined(QT3DS_APPLE) +#include +#include +#endif +#endif + +#define NVSpinLockPause() asm("nop") + +namespace qt3ds { +namespace foundation { + using namespace intrinsics; + + typedef enum { _NVThreadNotStarted, _NVThreadStarted, _NVThreadStopped } NVThreadState; + + class ThreadImpl + { + public: + ThreadImpl(NVFoundationBase &foundation) + : mFoundation(foundation) + { + } + NVFoundationBase &mFoundation; + Thread::ExecuteFn fn; + void *arg; + volatile QT3DSI32 quitNow; + volatile QT3DSI32 threadStarted; + NVThreadState state; + + pthread_t thread; + pid_t tid; + }; + + void *NVThreadStart(void *arg); + + Thread::Id Thread::getId() { return Id(pthread_self()); } + + Thread::Thread(NVFoundationBase &foundation) + { + mImpl = QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); + mImpl->thread = 0; + mImpl->tid = 0; + mImpl->state = _NVThreadNotStarted; + mImpl->quitNow = 0; + mImpl->threadStarted = 0; + mImpl->fn = NULL; + mImpl->arg = NULL; + } + + Thread::Thread(NVFoundationBase &foundation, Thread::ExecuteFn fn, void *arg) + { + mImpl = (ThreadImpl *)QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); + mImpl->thread = 0; + mImpl->tid = 0; + mImpl->state = _NVThreadNotStarted; + mImpl->quitNow = 0; + mImpl->threadStarted = 0; + mImpl->fn = fn; + mImpl->arg = arg; + + start(0); + } + + Thread::~Thread() + { + if (mImpl->state == _NVThreadStarted) + kill(); + QT3DS_FREE(mImpl->mFoundation.getAllocator(), mImpl); + } + + void Thread::start(QT3DSU32 stackSize) + { + if (mImpl->state != _NVThreadNotStarted) + return; + + if (stackSize == 0) + stackSize = DEFAULT_STACK_SIZE; + +#if defined(PTHREAD_STACK_MIN) && !defined(ANDROID) + if (stackSize < PTHREAD_STACK_MIN) { + qCWarning(WARNING, "Thread::start(): stack size was set below PTHREAD_STACK_MIN"); + stackSize = PTHREAD_STACK_MIN; + } +#endif + + pthread_attr_t attr; + int status = pthread_attr_init(&attr); + QT3DS_ASSERT(!status); + + status = pthread_attr_setstacksize(&attr, stackSize); + QT3DS_ASSERT(!status); + status = pthread_create(&mImpl->thread, &attr, NVThreadStart, this); + QT3DS_ASSERT(!status); + +#ifndef __QNX__ + // wait for thread to startup and write out TID + // otherwise TID dependent calls like setAffinity will fail. + while (atomicCompareExchange(&(mImpl->threadStarted), 1, 1) == 0) + yield(); +#endif + + mImpl->state = _NVThreadStarted; + + status = pthread_attr_destroy(&attr); + QT3DS_ASSERT(!status); + } + + static void setTid(ThreadImpl &threadImpl) + { +#ifndef __QNX__ +// query TID +#ifdef QT3DS_APPLE + threadImpl.tid = syscall(SYS_gettid); +#elif defined(__INTEGRITY) + pthread_t ptid = pthread_self(); + uint64_t threadId = 0; + memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid))); + threadImpl.tid = threadId; +#else + threadImpl.tid = syscall(__NR_gettid); +#endif + + // notify/unblock parent thread + atomicCompareExchange(&(threadImpl.threadStarted), 1, 0); +#else + QT3DS_ASSERT(false); +#endif + } + + void *NVThreadStart(void *arg) + { + // run execute from base class to run gettid in the new thread's context + ((Thread *)arg)->Thread::execute(); + return 0; + } + + void Thread::execute(void) + { + // run setTid in thread's context + setTid(*mImpl); + + // then run either the passed in function or execute from the derived class. + if (mImpl->fn) + (*mImpl->fn)(mImpl->arg); + else + this->execute(); + } + + void Thread::signalQuit() { atomicIncrement(&(mImpl->quitNow)); } + + bool Thread::waitForQuit() + { + if (mImpl->state == _NVThreadNotStarted) + return false; + + pthread_join(mImpl->thread, NULL); + return true; + } + + bool Thread::quitIsSignalled() + { +#ifndef __QNX__ + return atomicCompareExchange(&(mImpl->quitNow), 0, 0) != 0; +#else + // Hope for memory locking on the arm. + return mImpl->quitNow != 0; +#endif + } + + void Thread::quit() + { + mImpl->state = _NVThreadStopped; + pthread_exit(0); + } + + void Thread::kill() + { +#ifndef ANDROID + if (mImpl->state == _NVThreadStarted) + pthread_cancel(mImpl->thread); + mImpl->state = _NVThreadStopped; +#else + qCWarning(WARNING, "Thread::kill() called, but is not implemented"); +#endif + } + + void Thread::sleep(QT3DSU32 ms) + { + timespec sleepTime; + QT3DSU32 remainder = ms % 1000; + sleepTime.tv_sec = ms - remainder; + sleepTime.tv_nsec = remainder * 1000000L; + + while (nanosleep(&sleepTime, &sleepTime) == -1) + continue; + } + + void Thread::yield() { sched_yield(); } + + QT3DSU32 Thread::setAffinityMask(QT3DSU32 mask) + { + // Same as windows impl if mask is zero + if (!mask) + return 0; + +#ifndef __QNX__ + QT3DSU64 prevMask = 0; + +// Apple doesn't support syscall with getaffinity and setaffinity +#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) + QT3DSI32 errGet = syscall(__NR_sched_getaffinity, mImpl->tid, sizeof(prevMask), &prevMask); + if (errGet < 0) + return 0; + + QT3DSI32 errSet = syscall(__NR_sched_setaffinity, mImpl->tid, sizeof(mask), &mask); + if (errSet != 0) + return 0; +#endif + + return QT3DSU32(prevMask); +#else + QT3DS_ASSERT(false); + return 0; +#endif + } + + void Thread::setName(const char *name) + { +#if (defined(ANDROID) && (__ANDROID_API__ > 8)) + pthread_setname_np(mImpl->thread, name); +#else +// not implemented because most unix APIs expect setName() +// to be called from the thread's context. Example see next comment: + +// this works only with the current thread and can rename +// the main process if used in the wrong context: +// prctl(PR_SET_NAME, reinterpret_cast(name) ,0,0,0); +#endif + } + +#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) + static ThreadPriority::Enum convertPriorityFromLinux(QT3DSU32 inPrio, int policy) + { + QT3DS_COMPILE_TIME_ASSERT(ThreadPriority::eLOW > ThreadPriority::eHIGH); + QT3DS_COMPILE_TIME_ASSERT(ThreadPriority::eHIGH == 0); + + int maxL = sched_get_priority_max(policy); + int minL = sched_get_priority_min(policy); + int rangeL = maxL - minL; + int rangeNV = ThreadPriority::eLOW - ThreadPriority::eHIGH; + + // case for default scheduler policy + if (rangeL == 0) + return ThreadPriority::eNORMAL; + + float floatPrio = (float(maxL - inPrio) * float(rangeNV)) / float(rangeL); + + return ThreadPriority::Enum(int(roundf(floatPrio))); + } + + static int convertPriorityToLinux(ThreadPriority::Enum inPrio, int policy) + { + int maxL = sched_get_priority_max(policy); + int minL = sched_get_priority_min(policy); + int rangeL = maxL - minL; + int rangeNV = ThreadPriority::eLOW - ThreadPriority::eHIGH; + + // case for default scheduler policy + if (rangeL == 0) + return 0; + + float floatPrio = (float(ThreadPriority::eLOW - inPrio) * float(rangeL)) / float(rangeNV); + + return minL + int(roundf(floatPrio)); + } +#endif + + void Thread::setPriority(ThreadPriority::Enum val) + { +#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) + int policy; + sched_param s_param; + pthread_getschedparam(mImpl->thread, &policy, &s_param); + s_param.sched_priority = convertPriorityToLinux(val, policy); + pthread_setschedparam(mImpl->thread, policy, &s_param); +#endif + } + + ThreadPriority::Enum Thread::getPriority(Id pthread) + { +#if !defined(QT3DS_APPLE) && !defined(__INTEGRITY) + int policy; + sched_param s_param; + int ret = pthread_getschedparam(pthread_t(pthread), &policy, &s_param); + if (ret == 0) + return convertPriorityFromLinux(s_param.sched_priority, policy); + else + return ThreadPriority::eNORMAL; +#else + return ThreadPriority::eNORMAL; +#endif + } + + QT3DSU32 TlsAlloc() + { +#if !defined(__INTEGRITY) + pthread_key_t key; + int status = pthread_key_create(&key, NULL); + QT3DS_ASSERT(!status); + (void)status; + return (QT3DSU32)key; +#else + QT3DS_ASSERT(false); + return 0; +#endif + } + + void TlsFree(QT3DSU32 index) + { + int status = pthread_key_delete((pthread_key_t)index); + QT3DS_ASSERT(!status); + (void)status; + } + + void *TlsGet(QT3DSU32 index) { return (void *)pthread_getspecific((pthread_key_t)index); } + + QT3DSU32 TlsSet(QT3DSU32 index, void *value) + { + int status = pthread_setspecific((pthread_key_t)index, value); + QT3DS_ASSERT(!status); + return !status; + } + + // DM: On Linux x86-32, without implementation-specific restrictions + // the default stack size for a new thread should be 2 megabytes (kernel.org). + // NOTE: take care of this value on other architecutres! + const QT3DSU32 Thread::DEFAULT_STACK_SIZE = 1 << 21; + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxTime.cpp b/src/Runtime/Source/foundation/linux/Qt3DSLinuxTime.cpp new file mode 100644 index 00000000..6b3e93e4 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxTime.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSTime.h" + +#include +#include + +#if defined QT3DS_APPLE +#include +#endif + +// Use real-time high-precision timer. +#ifndef QT3DS_APPLE +#define CLOCKID CLOCK_REALTIME +#endif + +namespace qt3ds { +namespace foundation { + + const CounterFrequencyToTensOfNanos Time::sCounterFreq = Time::getCounterFrequency(); + + static Time::Second getTimeSeconds() + { + static struct timeval _tv; + gettimeofday(&_tv, NULL); + return double(_tv.tv_sec) + double(_tv.tv_usec) * 0.000001; + } + + Time::Time() { mLastTime = getTimeSeconds(); } + + Time::Second Time::getElapsedSeconds() + { + Time::Second curTime = getTimeSeconds(); + Time::Second diff = curTime - mLastTime; + mLastTime = curTime; + return diff; + } + + Time::Second Time::peekElapsedSeconds() + { + Time::Second curTime = getTimeSeconds(); + Time::Second diff = curTime - mLastTime; + return diff; + } + + Time::Second Time::getLastTime() const { return mLastTime; } + +#ifdef QT3DS_APPLE + CounterFrequencyToTensOfNanos Time::getCounterFrequency() + { + mach_timebase_info_data_t info; + mach_timebase_info(&info); + // sschirm: some code in the PhysX samples assumes that + // CounterFrequencyToTensOfNanos::mDenominator is #ticks/second + // which is bad since it ignores the numenator. This is a temporary fix + // with the same setup as windows + // return CounterFrequencyToTensOfNanos( info.numer, info.denom*10 ); + return CounterFrequencyToTensOfNanos(sNumTensOfNanoSecondsInASecond, + info.denom * 1000000000 / info.numer); + } + + QT3DSU64 Time::getCurrentCounterValue() { return mach_absolute_time(); } + +#else + + CounterFrequencyToTensOfNanos Time::getCounterFrequency() + { + return CounterFrequencyToTensOfNanos(1, 10); + } + + QT3DSU64 Time::getCurrentCounterValue() + { + struct timespec mCurrTimeInt; + clock_gettime(CLOCKID, &mCurrTimeInt); + // Convert to nanos as this doesn't cause a large divide here + return (static_cast(mCurrTimeInt.tv_sec) * 1000000000) + + (static_cast(mCurrTimeInt.tv_nsec)); + } +#endif + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/linux/Qt3DSLinuxTrigConstants.h b/src/Runtime/Source/foundation/linux/Qt3DSLinuxTrigConstants.h new file mode 100644 index 00000000..120dec78 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/Qt3DSLinuxTrigConstants.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_LINUX_TRIG_CONSTANTS_H +#define QT3DS_LINUX_TRIG_CONSTANTS_H + +//#define QT3DS_GLOBALCONST extern const __declspec(selectany) + +#define QT3DS_GLOBALCONST extern const __attribute__((weak)) + +QT3DS_ALIGN_PREFIX(16) +struct QT3DS_VECTORF32 +{ + float f[4]; +}; + +#define QT3DS_PI 3.141592654f +#define QT3DS_2PI 6.283185307f +#define QT3DS_1DIVPI 0.318309886f +#define QT3DS_1DIV2PI 0.159154943f +#define QT3DS_PIDIV2 1.570796327f +#define QT3DS_PIDIV4 0.785398163f + +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients0 = { 1.0f, -0.166666667f, 8.333333333e-3f, + -1.984126984e-4f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients1 = { 2.755731922e-6f, -2.505210839e-8f, + 1.605904384e-10f, -7.647163732e-13f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients2 = { 2.811457254e-15f, -8.220635247e-18f, + 1.957294106e-20f, -3.868170171e-23f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients0 = { 1.0f, -0.5f, 4.166666667e-2f, + -1.388888889e-3f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients1 = { 2.480158730e-5f, -2.755731922e-7f, + 2.087675699e-9f, -1.147074560e-11f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients2 = { 4.779477332e-14f, -1.561920697e-16f, + 4.110317623e-19f, -8.896791392e-22f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients0 = { 1.0f, 0.333333333f, 0.133333333f, + 5.396825397e-2f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients1 = { 2.186948854e-2f, 8.863235530e-3f, + 3.592128167e-3f, 1.455834485e-3f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients2 = { 5.900274264e-4f, 2.391290764e-4f, + 9.691537707e-5f, 3.927832950e-5f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients0 = { -0.05806367563904f, -0.41861972469416f, + 0.22480114791621f, 2.17337241360606f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients1 = { 0.61657275907170f, 4.29696498283455f, + -1.18942822255452f, -6.53784832094831f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients2 = { -1.36926553863413f, -4.48179294237210f, + 1.41810672941833f, 5.48179257935713f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients0 = { 1.0f, 0.333333334f, 0.2f, 0.142857143f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients1 = { 1.111111111e-1f, 9.090909091e-2f, + 7.692307692e-2f, 6.666666667e-2f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients2 = { 5.882352941e-2f, 5.263157895e-2f, + 4.761904762e-2f, 4.347826087e-2f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinEstCoefficients = { 1.0f, -1.66521856991541e-1f, + 8.199913018755e-3f, -1.61475937228e-4f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosEstCoefficients = { 1.0f, -4.95348008918096e-1f, + 3.878259962881e-2f, -9.24587976263e-4f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanEstCoefficients = { 2.484f, -1.954923183e-1f, 2.467401101f, + QT3DS_1DIVPI }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanEstCoefficients = { 7.689891418951e-1f, 1.104742493348f, + 8.661844266006e-1f, QT3DS_PIDIV2 }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstCoefficients = { -1.36178272886711f, 2.37949493464538f, + -8.08228565650486e-1f, + 2.78440142746736e-1f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstConstants = { 1.00000011921f, QT3DS_PIDIV2, 0.0f, 0.0f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXPiConstants0 = { QT3DS_PI, QT3DS_2PI, QT3DS_1DIVPI, QT3DS_1DIV2PI }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXReciprocalTwoPi = { QT3DS_1DIV2PI, QT3DS_1DIV2PI, QT3DS_1DIV2PI, + QT3DS_1DIV2PI }; + +#endif diff --git a/src/Runtime/Source/foundation/linux/SocketImpl.h b/src/Runtime/Source/foundation/linux/SocketImpl.h new file mode 100644 index 00000000..4c3fcb73 --- /dev/null +++ b/src/Runtime/Source/foundation/linux/SocketImpl.h @@ -0,0 +1,424 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef FOUNDATION_LINUX_SOCKET_IMPL_H +#define FOUNDATION_LINUX_SOCKET_IMPL_H +#pragma once + +/*=========================================================================*\ +* BSD include files +\*=========================================================================*/ +/* error codes */ +#include +/* close function */ +#include +/* fnctnl function and associated constants */ +#include +/* struct sockaddr */ +#include +/* socket function */ +#include +/* struct timeval */ +#include +/* gethostbyname and gethostbyaddr functions */ +#include +/* sigpipe handling */ +#include +/* IP stuff*/ +#include +#include +/* TCP options (nagle algorithm disable) */ +#include + +namespace qt3ds { +namespace foundation { + namespace socketimpl { + // Functions take from lua socket implementation. Note that it has an MIT license. + + enum { + IO_DONE = 0, /* operation completed successfully */ + IO_TIMEOUT = -1, /* operation timed out */ + IO_CLOSED = -2, /* the connection has been closed */ + IO_UNKNOWN = -3 + }; + + /*-------------------------------------------------------------------------*\ + * I/O error strings + \*-------------------------------------------------------------------------*/ + const char *io_strerror(int err) + { + switch (err) { + case IO_DONE: + return NULL; + case IO_CLOSED: + return "closed"; + case IO_TIMEOUT: + return "timeout"; + default: + return "unknown error"; + } + } + + typedef int t_socket; + typedef t_socket *p_socket; + typedef struct sockaddr SA; + +#define SOCKET_INVALID (-1) + +#define WAITFD_R 1 +#define WAITFD_W 2 +#define WAITFD_C (WAITFD_R | WAITFD_W) + + int socket_waitfd(p_socket ps, int sw, QT3DSU32 tm) + { + int ret; + fd_set rfds, wfds, *rp, *wp; + struct timeval tv, *tp = NULL; + if (tm == 0) + return IO_TIMEOUT; /* optimize timeout == 0 case */ + if (tm < QT3DS_MAX_U32) { + // shoule consider max timeout specially by setting tp = NULL + // or you get invalid argument errno = 22 + tv.tv_sec = (int)(tm / 1000); + QT3DSU32 leftover = tm % 1000; + tv.tv_usec = (int)(leftover * 100000); + tp = &tv; + } + do { + /* must set bits within loop, because select may have modifed them */ + rp = wp = NULL; + if (sw & WAITFD_R) { + FD_ZERO(&rfds); + FD_SET(*ps, &rfds); + rp = &rfds; + } + if (sw & WAITFD_W) { + FD_ZERO(&wfds); + FD_SET(*ps, &wfds); + wp = &wfds; + } + ret = select(*ps + 1, rp, wp, NULL, tp); + } while (ret == -1 && errno == EINTR); + if (ret == -1) + return errno; + if (ret == 0) + return IO_TIMEOUT; + if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) + return IO_CLOSED; + return IO_DONE; + } + + /*-------------------------------------------------------------------------*\ + * Initializes module + \*-------------------------------------------------------------------------*/ + int socket_open(void) + { + /* instals a handler to ignore sigpipe or it will crash us */ + signal(SIGPIPE, SIG_IGN); + return 1; + } + + /*-------------------------------------------------------------------------*\ + * Close module + \*-------------------------------------------------------------------------*/ + int socket_close(void) { return 1; } + + /*-------------------------------------------------------------------------*\ + * Put socket into blocking mode + \*-------------------------------------------------------------------------*/ + void socket_setblocking(p_socket ps) + { + int flags = fcntl(*ps, F_GETFL, 0); + flags &= (~(O_NONBLOCK)); + fcntl(*ps, F_SETFL, flags); + } + + /*-------------------------------------------------------------------------*\ + * Put socket into non-blocking mode + \*-------------------------------------------------------------------------*/ + void socket_setnonblocking(p_socket ps) + { + int flags = fcntl(*ps, F_GETFL, 0); + flags |= O_NONBLOCK; + fcntl(*ps, F_SETFL, flags); + } + + /*-------------------------------------------------------------------------*\ + * Close and inutilize socket + \*-------------------------------------------------------------------------*/ + void socket_destroy(p_socket ps) + { + if (*ps != SOCKET_INVALID) { + socket_setblocking(ps); + close(*ps); + *ps = SOCKET_INVALID; + } + } + /*-------------------------------------------------------------------------*\ + * + \*-------------------------------------------------------------------------*/ + void socket_shutdown(p_socket ps, int how) + { + socket_setblocking(ps); + shutdown(*ps, how); + socket_setnonblocking(ps); + } + + /*-------------------------------------------------------------------------*\ + * Creates and sets up a socket + \*-------------------------------------------------------------------------*/ + int socket_create(p_socket ps, int domain, int type, int protocol) + { + *ps = socket(domain, type, protocol); + if (*ps != SOCKET_INVALID) + return IO_DONE; + else + return errno; + } + + /*-------------------------------------------------------------------------*\ + * + \*-------------------------------------------------------------------------*/ + int socket_listen(p_socket ps, int backlog) + { + int err = IO_DONE; + socket_setblocking(ps); + if (listen(*ps, backlog)) + err = errno; + socket_setnonblocking(ps); + return err; + } + + /*-------------------------------------------------------------------------*\ + * Binds or returns error message + \*-------------------------------------------------------------------------*/ + int socket_bind(p_socket ps, SA *addr, socklen_t len) + { + int err = IO_DONE; + socket_setblocking(ps); + if (bind(*ps, addr, len) < 0) + err = errno; + socket_setnonblocking(ps); + return err; + } + + /*-------------------------------------------------------------------------*\ + * Connects or returns error message + \*-------------------------------------------------------------------------*/ + int socket_connect(p_socket ps, SA *addr, socklen_t len, QT3DSU32 tm) + { + int err; + /* avoid calling on closed sockets */ + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + /* call connect until done or failed without being interrupted */ + do + if (connect(*ps, addr, len) == 0) + return IO_DONE; + while ((err = errno) == EINTR); + /* if connection failed immediately, return error code */ + if (err != EINPROGRESS && err != EAGAIN) + return err; + /* zero timeout case optimization */ + if (tm == 0) + return IO_TIMEOUT; + /* wait until we have the result of the connection attempt or timeout */ + err = socket_waitfd(ps, WAITFD_C, tm); + if (err == IO_CLOSED) { + if (recv(*ps, (char *)&err, 0, 0) == 0) + return IO_DONE; + else + return errno; + } else + return err; + } + + /*-------------------------------------------------------------------------*\ + * Accept with timeout + \*-------------------------------------------------------------------------*/ + int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, QT3DSU32 tm) + { + SA daddr; + socklen_t dlen = sizeof(daddr); + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + if (!addr) + addr = &daddr; + if (!len) + len = &dlen; + for (;;) { + int err; + if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) + return IO_DONE; + err = errno; + if (err == EINTR) + continue; + if (err != EAGAIN && err != ECONNABORTED) + return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) + return err; + } + /* can't reach here */ + return IO_UNKNOWN; + } + + /*-------------------------------------------------------------------------*\ + * Send with timeout + \*-------------------------------------------------------------------------*/ + int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, QT3DSU32 tm) + { + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + /* loop until we send something or we give up on error */ + for (;;) { + long put = (long)send(*ps, data, count, 0); + /* if we sent anything, we are done */ + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = errno; + /* send can't really return 0, but EPIPE means the connection was closed */ + if (put == 0 || err == EPIPE) + return IO_CLOSED; + /* we call was interrupted, just try again */ + if (err == EINTR) + continue; + /* if failed fatal reason, report error */ + if (err != EAGAIN) + return err; + /* wait until we can send something or we timeout */ + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) + return err; + } + /* can't reach here */ + return IO_UNKNOWN; + } + + /*-------------------------------------------------------------------------*\ + * Receive with timeout + \*-------------------------------------------------------------------------*/ + int socket_recv(p_socket ps, char *data, size_t count, size_t *got, QT3DSU32 tm) + { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + for (;;) { + long taken = (long)recv(*ps, data, count, 0); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + err = errno; + if (taken == 0) + return IO_CLOSED; + if (err == EINTR) + continue; + if (err != EAGAIN) + return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) + return err; + } + return IO_UNKNOWN; + } + + int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) + { + *hp = gethostbyaddr(addr, len, AF_INET); + if (*hp) + return IO_DONE; + else if (h_errno) + return h_errno; + else if (errno) + return errno; + else + return IO_UNKNOWN; + } + + int socket_gethostbyname(const char *addr, struct hostent **hp) + { + *hp = gethostbyname(addr); + if (*hp) + return IO_DONE; + else if (h_errno) + return h_errno; + else if (errno) + return errno; + else + return IO_UNKNOWN; + } + + /*-------------------------------------------------------------------------*\ + * Error translation functions + * Make sure important error messages are standard + \*-------------------------------------------------------------------------*/ + const char *socket_hoststrerror(int err) + { + if (err <= 0) + return io_strerror(err); + switch (err) { + case HOST_NOT_FOUND: + return "host not found"; + default: + return hstrerror(err); + } + } + + const char *socket_strerror(int err) + { + if (err <= 0) + return io_strerror(err); + switch (err) { + case EADDRINUSE: + return "address already in use"; + case EISCONN: + return "already connected"; + case EACCES: + return "permission denied"; + case ECONNREFUSED: + return "connection refused"; + case ECONNABORTED: + return "closed"; + case ECONNRESET: + return "closed"; + case ETIMEDOUT: + return "timeout"; + default: + return strerror(errno); + } + } + } +} +} + +#endif diff --git a/src/Runtime/Source/foundation/linux/qt_attribution.json b/src/Runtime/Source/foundation/linux/qt_attribution.json new file mode 100644 index 00000000..3c3bed6b --- /dev/null +++ b/src/Runtime/Source/foundation/linux/qt_attribution.json @@ -0,0 +1,10 @@ +{ + "Id": "qt3dslinuxinlineaos", + "Name": "Qt3DSLinuxInlineAoS", + "QDocModule": "qt3dstudio", + "QtUsage": "Used by Qt3DStudio, Runtime component.", + + "License": "Other", + "LicenseFile": "LICENSE.TXT", + "Copyright": "Copyright (c) 2001 Intel Corporation." +} diff --git a/src/Runtime/Source/foundation/macos/Qt3DSUnixAtomic.cpp b/src/Runtime/Source/foundation/macos/Qt3DSUnixAtomic.cpp new file mode 100644 index 00000000..c1ac3965 --- /dev/null +++ b/src/Runtime/Source/foundation/macos/Qt3DSUnixAtomic.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2001-2004 NovodeX AG. +** Copyright (C) 2004-2008 AGEIA Technologies, Inc. +** Copyright (C) 2008-2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAtomic.h" + +#define PAUSE() asm("nop") + +namespace qt3ds { +namespace foundation { + + void *atomicCompareExchangePointer(volatile void **dest, void *exch, void *comp) + { + return __sync_val_compare_and_swap((void **)dest, comp, exch); + } + + QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) + { + return __sync_val_compare_and_swap(dest, comp, exch); + } + + QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) { return __sync_add_and_fetch(val, 1); } + + QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) { return __sync_sub_and_fetch(val, 1); } + + QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta) { return __sync_add_and_fetch(val, delta); } + + QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2) + { + QT3DSI32 oldVal, newVal; + + do { + PAUSE(); + oldVal = *val; + + if (val2 > oldVal) + newVal = val2; + else + newVal = oldVal; + + } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); + + return *val; + } + + QT3DSI32 atomicExchange(volatile QT3DSI32 *val, QT3DSI32 val2) + { + QT3DSI32 newVal, oldVal; + + do { + PAUSE(); + oldVal = *val; + newVal = val2; + } while (atomicCompareExchange(val, newVal, oldVal) != oldVal); + + return oldVal; + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/macos/Qt3DSUnixFPU.cpp b/src/Runtime/Source/foundation/macos/Qt3DSUnixFPU.cpp new file mode 100644 index 00000000..59c9850d --- /dev/null +++ b/src/Runtime/Source/foundation/macos/Qt3DSUnixFPU.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2001-2004 NovodeX AG. +** Copyright (C) 2004-2008 AGEIA Technologies, Inc. +** Copyright (C) 2008-2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSFPU.h" +#include + +#if !(defined(__CYGWIN__) || defined(PX_ANDROID)) +QT3DS_COMPILE_TIME_ASSERT(8 * sizeof(qt3ds::QT3DSU32) >= sizeof(fenv_t)); +#endif + +qt3ds::foundation::FPUGuard::FPUGuard() +{ +#if defined(__CYGWIN__) +#pragma message "FPUGuard::FPUGuard() is not implemented" +#elif defined(PX_ANDROID) +// not supported unless ARM_HARD_FLOAT is enabled. +#else + fegetenv(reinterpret_cast(mControlWords)); + fesetenv(FE_DFL_ENV); +#endif +} + +qt3ds::foundation::FPUGuard::~FPUGuard() +{ +#if defined(__CYGWIN__) +#pragma message "FPUGuard::~FPUGuard() is not implemented" +#elif defined(PX_ANDROID) +// not supported unless ARM_HARD_FLOAT is enabled. +#else + fesetenv(reinterpret_cast(mControlWords)); +#endif +} diff --git a/src/Runtime/Source/foundation/macos/Qt3DSUnixMutex.cpp b/src/Runtime/Source/foundation/macos/Qt3DSUnixMutex.cpp new file mode 100644 index 00000000..bbc55829 --- /dev/null +++ b/src/Runtime/Source/foundation/macos/Qt3DSUnixMutex.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAtomic.h" + +#include + +namespace qt3ds { +namespace foundation { + + namespace { + pthread_mutex_t *getMutex(MutexImpl *impl) + { + return reinterpret_cast(impl); + } + } + + MutexImpl::MutexImpl() + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(getMutex(this), &attr); + pthread_mutexattr_destroy(&attr); + } + + MutexImpl::~MutexImpl() { pthread_mutex_destroy(getMutex(this)); } + + bool MutexImpl::lock() { return !pthread_mutex_lock(getMutex(this)); } + + bool MutexImpl::trylock() { return !pthread_mutex_trylock(getMutex(this)); } + + bool MutexImpl::unlock() { return !pthread_mutex_unlock(getMutex(this)); } + + const QT3DSU32 MutexImpl::size = sizeof(pthread_mutex_t); + + class ReadWriteLockImpl + { + public: + ReadWriteLockImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + pthread_mutex_t mutex; + volatile int readerCounter; + }; + + ReadWriteLock::ReadWriteLock(NVAllocatorCallback &alloc) + { + mImpl = QT3DS_NEW(alloc, ReadWriteLockImpl)(alloc); + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mImpl->mutex, &attr); + pthread_mutexattr_destroy(&attr); + + mImpl->readerCounter = 0; + } + + ReadWriteLock::~ReadWriteLock() + { + pthread_mutex_destroy(&mImpl->mutex); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + void ReadWriteLock::lockReader() + { + pthread_mutex_lock(&mImpl->mutex); + + atomicIncrement(&mImpl->readerCounter); + + pthread_mutex_unlock(&mImpl->mutex); + } + + void ReadWriteLock::lockWriter() + { + pthread_mutex_lock(&mImpl->mutex); + + while (mImpl->readerCounter != 0) + ; + } + + void ReadWriteLock::unlockReader() { atomicDecrement(&mImpl->readerCounter); } + + void ReadWriteLock::unlockWriter() { pthread_mutex_unlock(&mImpl->mutex); } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/macos/Qt3DSUnixSemaphore.cpp b/src/Runtime/Source/foundation/macos/Qt3DSUnixSemaphore.cpp new file mode 100644 index 00000000..90aab79a --- /dev/null +++ b/src/Runtime/Source/foundation/macos/Qt3DSUnixSemaphore.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSSemaphore.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSAllocatorCallback.h" + +#include +#include +#include +#include +#include + +namespace qt3ds { +namespace foundation { + + class SemaphoreImpl + { + public: + SemaphoreImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + pthread_mutex_t mutex; + pthread_cond_t cond; + QT3DSU32 count; + QT3DSU32 maxCount; + }; + + struct NVLinuxScopeLock + { + NVLinuxScopeLock(pthread_mutex_t &m) + : mMutex(m) + { + pthread_mutex_lock(&mMutex); + } + + ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } + private: + pthread_mutex_t &mMutex; + }; + + Semaphore::Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount) + { + mImpl = QT3DS_NEW(alloc, SemaphoreImpl)(alloc); + int status = pthread_mutex_init(&mImpl->mutex, 0); + QT3DS_ASSERT(!status); + status = pthread_cond_init(&mImpl->cond, 0); + QT3DS_ASSERT(!status); + mImpl->count = initialCount; + mImpl->maxCount = maxCount; + QT3DS_ASSERT(initialCount <= maxCount); + } + + Semaphore::~Semaphore() + { + pthread_cond_destroy(&mImpl->cond); + pthread_mutex_destroy(&mImpl->mutex); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + bool Semaphore::wait(QT3DSU32 milliseconds) + { + NVLinuxScopeLock lock(mImpl->mutex); + + if (mImpl->count > 0) { + mImpl->count--; + return true; + } + + if (milliseconds == 0) { + return false; + } + + if (milliseconds == QT3DSU32(-1)) { + int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); + QT3DS_ASSERT(!status); + (void)status; + } else { + timespec ts; + timeval tp; + gettimeofday(&tp, NULL); + QT3DSU32 sec = milliseconds / 1000; + QT3DSU32 usec = (milliseconds - 1000 * sec) * 1000; + + // sschirm: taking into account that us might accumulate to a second + // otherwise the pthread_cond_timedwait complains on osx. + usec = tp.tv_usec + usec; + QT3DSU32 div_sec = usec / 1000000; + QT3DSU32 rem_usec = usec - div_sec * 1000000; + + ts.tv_sec = tp.tv_sec + sec + div_sec; + ts.tv_nsec = rem_usec * 1000; + + int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); + QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); + (void)ierr; + return false; + } + + return true; + } + + void Semaphore::post() + { + NVLinuxScopeLock lock(mImpl->mutex); + mImpl->count++; + if (mImpl->count > mImpl->maxCount) + mImpl->count = mImpl->maxCount; + else { + pthread_cond_broadcast(&mImpl->cond); + } + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/macos/Qt3DSUnixSync.cpp b/src/Runtime/Source/foundation/macos/Qt3DSUnixSync.cpp new file mode 100644 index 00000000..52f9d7ab --- /dev/null +++ b/src/Runtime/Source/foundation/macos/Qt3DSUnixSync.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSAllocatorCallback.h" + +#include +#include +#include +#include +#include + +namespace qt3ds { +namespace foundation { + + class SyncImpl + { + public: + SyncImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + pthread_mutex_t mutex; + pthread_cond_t cond; + volatile bool is_set; + }; + + struct NVLinuxScopeLock + { + NVLinuxScopeLock(pthread_mutex_t &m) + : mMutex(m) + { + pthread_mutex_lock(&mMutex); + } + + ~NVLinuxScopeLock() { pthread_mutex_unlock(&mMutex); } + private: + pthread_mutex_t &mMutex; + }; + + Sync::Sync(NVAllocatorCallback &alloc) + { + mImpl = QT3DS_NEW(alloc, SyncImpl)(alloc); + int status = pthread_mutex_init(&mImpl->mutex, 0); + QT3DS_ASSERT(!status); + status = pthread_cond_init(&mImpl->cond, 0); + QT3DS_ASSERT(!status); + mImpl->is_set = false; + } + + Sync::~Sync() + { + pthread_cond_destroy(&mImpl->cond); + pthread_mutex_destroy(&mImpl->mutex); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + void Sync::reset() + { + NVLinuxScopeLock lock(mImpl->mutex); + mImpl->is_set = false; + } + + void Sync::set() + { + NVLinuxScopeLock lock(mImpl->mutex); + if (!mImpl->is_set) { + mImpl->is_set = true; + pthread_cond_broadcast(&mImpl->cond); + } + } + + bool Sync::wait(QT3DSU32 ms) + { + NVLinuxScopeLock lock(mImpl->mutex); + if (!mImpl->is_set) { + if (ms == QT3DSU32(-1)) { + int status = pthread_cond_wait(&mImpl->cond, &mImpl->mutex); + QT3DS_ASSERT(!status); + (void)status; + } else { + timespec ts; + timeval tp; + gettimeofday(&tp, NULL); + QT3DSU32 sec = ms / 1000; + QT3DSU32 usec = (ms - 1000 * sec) * 1000; + + // sschirm: taking into account that us might accumulate to a second + // otherwise the pthread_cond_timedwait complains on osx. + usec = tp.tv_usec + usec; + QT3DSU32 div_sec = usec / 1000000; + QT3DSU32 rem_usec = usec - div_sec * 1000000; + + ts.tv_sec = tp.tv_sec + sec + div_sec; + ts.tv_nsec = rem_usec * 1000; + + int ierr = pthread_cond_timedwait(&mImpl->cond, &mImpl->mutex, &ts); + QT3DS_ASSERT((ierr == 0) || (ierr == ETIMEDOUT)); + (void)ierr; + } + } + return mImpl->is_set; + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/macos/Qt3DSUnixTime.cpp b/src/Runtime/Source/foundation/macos/Qt3DSUnixTime.cpp new file mode 100644 index 00000000..58eadcb6 --- /dev/null +++ b/src/Runtime/Source/foundation/macos/Qt3DSUnixTime.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2001-2004 NovodeX AG. +** Copyright (C) 2004-2008 AGEIA Technologies, Inc. +** Copyright (C) 2008-2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSTime.h" + +#include +#include + +#if defined QT3DS_APPLE +#include +#endif + +// Use real-time high-precision timer. +#ifndef QT3DS_APPLE +#define CLOCKID CLOCK_REALTIME +#endif + +namespace qt3ds { +namespace foundation { + + const CounterFrequencyToTensOfNanos Time::sCounterFreq = Time::getCounterFrequency(); + + static Time::Second getTimeSeconds() + { + static struct timeval _tv; + gettimeofday(&_tv, NULL); + return double(_tv.tv_sec) + double(_tv.tv_usec) * 0.000001; + } + + Time::Time() { mLastTime = getTimeSeconds(); } + + Time::Second Time::getElapsedSeconds() + { + Time::Second curTime = getTimeSeconds(); + Time::Second diff = curTime - mLastTime; + mLastTime = curTime; + return diff; + } + + Time::Second Time::peekElapsedSeconds() + { + Time::Second curTime = getTimeSeconds(); + Time::Second diff = curTime - mLastTime; + return diff; + } + + Time::Second Time::getLastTime() const { return mLastTime; } + +#ifdef QT3DS_APPLE + CounterFrequencyToTensOfNanos Time::getCounterFrequency() + { + mach_timebase_info_data_t info; + mach_timebase_info(&info); + // mach_absolute_time * (info.numer/info.denom) is in units of nano seconds + return CounterFrequencyToTensOfNanos(info.numer, info.denom * 10); + } + + QT3DSU64 Time::getCurrentCounterValue() { return mach_absolute_time(); } + +#else + + CounterFrequencyToTensOfNanos Time::getCounterFrequency() + { + return CounterFrequencyToTensOfNanos(1, 10); + } + + PxU64 Time::getCurrentCounterValue() + { + struct timespec mCurrTimeInt; + clock_gettime(CLOCKID, &mCurrTimeInt); + // Convert to nanos as this doesn't cause a large divide here + return (static_cast(mCurrTimeInt.tv_sec) * 1000000000) + + (static_cast(mCurrTimeInt.tv_nsec)); + } +#endif + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/qt_attribution.json b/src/Runtime/Source/foundation/qt_attribution.json new file mode 100644 index 00000000..537d8be3 --- /dev/null +++ b/src/Runtime/Source/foundation/qt_attribution.json @@ -0,0 +1,22 @@ +{ + "Id": "convertutf", + "Name": "ConvertUTF", + "QDocModule": "qt3dstudio", + "QtUsage": "Used by Qt3DStudio, Studio and Runtime components.", + + "License": "Other", + "LicenseFile": "LICENSE_CONVERTUTF.TXT", + "Copyright": "Copyright 2001-2004 Unicode, Inc." +} +, +{ + "Id": "socket", + "Name": "Socket", + "QDocModule": "qt3dstudio", + "QtUsage": "Used by Qt3DStudio, Runtime component.", + + "License": "MIT license", + "LicenseId": "MIT", + "LicenseFile": "LICENCE_SOCKET.TXT", + "Copyright": "Copyright (C) 2004-2013 Diego Nehab." +} diff --git a/src/Runtime/Source/foundation/windows/LICENSE.TXT b/src/Runtime/Source/foundation/windows/LICENSE.TXT new file mode 100644 index 00000000..f40caef8 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/LICENSE.TXT @@ -0,0 +1,7 @@ + Copyright (c) 2001 Intel Corporation. + +Permition is granted to use, copy, distribute and prepare derivative works +of this library for any purpose and without fee, provided, that the above +copyright notice and this statement appear in all copies. +Intel makes no representations about the suitability of this library for +any purpose, and specifically disclaims all warranties. diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsAoS.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsAoS.h new file mode 100644 index 00000000..c654ec79 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsAoS.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_WINDOWS_AOS_H +#define QT3DS_WINDOWS_AOS_H + +// no includes here! this file should be included from NVcVecMath.h only!!! + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +typedef __m128 FloatV; +typedef __m128 Vec3V; +typedef __m128 Vec4V; +typedef __m128 BoolV; +typedef __m128 VecU32V; +typedef __m128 VecI32V; +typedef __m128 VecU16V; +typedef __m128 VecI16V; +typedef __m128 VecU8V; +typedef __m128 QuatV; + +#define FloatVArg FloatV & +#define Vec3VArg Vec3V & +#define Vec4VArg Vec4V & +#define BoolVArg BoolV & +#define VecU32VArg VecU32V & +#define VecI32VArg VecI32V & +#define VecU16VArg VecU16V & +#define VecI16VArg VecI16V & +#define VecU8VArg VecU8V & +#define QuatVArg QuatV & + +QT3DS_ALIGN_PREFIX(16) +struct Mat33V +{ + Mat33V() {} + Mat33V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2) + : col0(c0) + , col1(c1) + , col2(c2) + { + } + Vec3V QT3DS_ALIGN(16, col0); + Vec3V QT3DS_ALIGN(16, col1); + Vec3V QT3DS_ALIGN(16, col2); +} QT3DS_ALIGN_SUFFIX(16); + +QT3DS_ALIGN_PREFIX(16) +struct Mat34V +{ + Mat34V() {} + Mat34V(const Vec3V &c0, const Vec3V &c1, const Vec3V &c2, const Vec3V &c3) + : col0(c0) + , col1(c1) + , col2(c2) + , col3(c3) + { + } + Vec3V QT3DS_ALIGN(16, col0); + Vec3V QT3DS_ALIGN(16, col1); + Vec3V QT3DS_ALIGN(16, col2); + Vec3V QT3DS_ALIGN(16, col3); +} QT3DS_ALIGN_SUFFIX(16); + +QT3DS_ALIGN_PREFIX(16) +struct Mat43V +{ + Mat43V() {} + Mat43V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2) + : col0(c0) + , col1(c1) + , col2(c2) + { + } + Vec4V QT3DS_ALIGN(16, col0); + Vec4V QT3DS_ALIGN(16, col1); + Vec4V QT3DS_ALIGN(16, col2); +} QT3DS_ALIGN_SUFFIX(16); + +QT3DS_ALIGN_PREFIX(16) +struct Mat44V +{ + Mat44V() {} + Mat44V(const Vec4V &c0, const Vec4V &c1, const Vec4V &c2, const Vec4V &c3) + : col0(c0) + , col1(c1) + , col2(c2) + , col3(c3) + { + } + Vec4V QT3DS_ALIGN(16, col0); + Vec4V QT3DS_ALIGN(16, col1); + Vec4V QT3DS_ALIGN(16, col2); + Vec4V QT3DS_ALIGN(16, col3); +} QT3DS_ALIGN_SUFFIX(16); + +#endif // QT3DS_WINDOWS_AOS_H diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsAtomic.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsAtomic.cpp new file mode 100644 index 00000000..4f95d3dd --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsAtomic.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/windows/Qt3DSWindowsInclude.h" +#include "foundation/Qt3DSAtomic.h" + +namespace qt3ds { +namespace foundation { + + QT3DSI32 atomicExchange(volatile QT3DSI32 *val, QT3DSI32 val2) + { + return (QT3DSI32)InterlockedExchange((volatile LONG *)val, (LONG)val2); + } + + QT3DSI32 atomicCompareExchange(volatile QT3DSI32 *dest, QT3DSI32 exch, QT3DSI32 comp) + { + return (QT3DSI32)InterlockedCompareExchange((volatile LONG *)dest, exch, comp); + } + + void *atomicCompareExchangePointer(volatile void **dest, void *exch, void *comp) + { + return InterlockedCompareExchangePointer((volatile PVOID *)dest, exch, comp); + } + + QT3DSI32 atomicIncrement(volatile QT3DSI32 *val) + { + return (QT3DSI32)InterlockedIncrement((volatile LONG *)val); + } + + QT3DSI32 atomicDecrement(volatile QT3DSI32 *val) + { + return (QT3DSI32)InterlockedDecrement((volatile LONG *)val); + } + + QT3DSI32 atomicAdd(volatile QT3DSI32 *val, QT3DSI32 delta) + { + LONG newValue, oldValue; + do { + oldValue = *val; + newValue = oldValue + delta; + } while (InterlockedCompareExchange((volatile LONG *)val, newValue, oldValue) != oldValue); + + return newValue; + } + + QT3DSI32 atomicMax(volatile QT3DSI32 *val, QT3DSI32 val2) + { + // Could do this more efficiently in asm... + + LONG newValue, oldValue; + + do { + oldValue = *val; + + if (val2 > oldValue) + newValue = val2; + else + newValue = oldValue; + + } while (InterlockedCompareExchange((volatile LONG *)val, newValue, oldValue) != oldValue); + + return newValue; + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsFPU.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsFPU.cpp new file mode 100644 index 00000000..47242801 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsFPU.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "foundation/Qt3DSFPU.h" +#include "float.h" + +#ifdef QT3DS_X64 +#define _MCW_ALL _MCW_DN | _MCW_EM | _MCW_RC +#else +#define _MCW_ALL _MCW_DN | _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC +#endif + +qt3ds::foundation::FPUGuard::FPUGuard() +{ +// default plus FTZ and DAZ +#if defined(QT3DS_WINDOWS) && defined(QT3DS_VC) +#ifdef QT3DS_X64 + _controlfp_s(mControlWords, _CW_DEFAULT | _DN_FLUSH, _MCW_ALL); +#else + __control87_2(_CW_DEFAULT | _DN_FLUSH, _MCW_ALL, mControlWords, mControlWords + 1); +#endif +#endif +} + +qt3ds::foundation::FPUGuard::~FPUGuard() +{ +#if defined(QT3DS_WINDOWS) && defined(QT3DS_VC) +#ifdef QT3DS_X64 + _controlfp_s(mControlWords, *mControlWords, _MCW_ALL); +#else + __control87_2(mControlWords[0], _MCW_ALL, mControlWords, 0); + __control87_2(mControlWords[1], _MCW_ALL, 0, mControlWords + 1); +#endif +#endif +} diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsFile.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsFile.h new file mode 100644 index 00000000..6c232a54 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsFile.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_WINDOWS_FILE_H +#define QT3DS_FOUNDATION_QT3DS_WINDOWS_FILE_H + +#include "foundation/Qt3DS.h" + +#include + +namespace qt3ds { +namespace foundation { + QT3DS_INLINE errno_t fopen_s(FILE **_File, const char *_Filename, const char *_Mode) + { + return ::fopen_s(_File, _Filename, _Mode); + }; + +} // namespace foundation +} // namespace qt3ds + +#endif diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsInclude.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsInclude.h new file mode 100644 index 00000000..f01c9f1a --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsInclude.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOWSINCLUDE_H +#define WINDOWSINCLUDE_H + +#include "foundation/Qt3DS.h" + +#ifndef _WIN32 +#error "This file should only be included by Windows builds!!" +#endif + +#ifdef _WINDOWS_ // windows already included +#error "Only include windows.h through this file!!" +#endif + +// We only support >= Windows XP, and we need this for critical section and +#define _WIN32_WINNT 0x0500 + +// turn off as much as we can for windows. All we really need is the thread functions(critical +// sections/Interlocked* etc) +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOUSER +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOMETAFILE +#define NOMSG +#define NOOPENFILE +#define NOSCROLL +#define NOSERVICE +#define NOSOUND +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define WIN32_LEAN_AND_MEAN + +#include + +#ifdef QT3DS_SUPPORT_SSE +#include +#endif + +#endif diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsInlineAoS.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsInlineAoS.h new file mode 100644 index 00000000..60c57894 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsInlineAoS.h @@ -0,0 +1,2715 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// Copyright (c) 2001 Intel Corporation. +// +// Permition is granted to use, copy, distribute and prepare derivative works +// of this library for any purpose and without fee, provided, that the above +// copyright notice and this statement appear in all copies. +// Intel makes no representations about the suitability of this library for +// any purpose, and specifically disclaims all warranties. +// See LEGAL.TXT for all the legal information. +// + +#ifndef QT3DS_WINDOWS_INLINE_AOS_H +#define QT3DS_WINDOWS_INLINE_AOS_H + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +// Remove this define when all platforms use simd solver. +#define QT3DS_SUPPORT_SIMD + +QT3DS_FORCE_INLINE __m128 m128_I2F(__m128i n) +{ + return _mm_castsi128_ps(n); +} +QT3DS_FORCE_INLINE __m128i m128_F2I(__m128 n) +{ + return _mm_castps_si128(n); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAllTrue4_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return moveMask == (0xf); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue4_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return moveMask != (0x0); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAllTrue3_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return (moveMask & 0x7) == (0x7); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAnyTrue3_R(const BoolV a) +{ + const QT3DSI32 moveMask = _mm_movemask_ps(a); + return (moveMask & 0x7) != (0x0); +} + +///////////////////////////////////////////////////////////////////// +////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +QT3DS_FORCE_INLINE QT3DSU32 FiniteTestEq(const Vec4V a, const Vec4V b) +{ + // This is a bit of a bodge. + //_mm_comieq_ss returns 1 if either value is nan so we need to re-cast a and b with true encoded + //as a non-nan number. + // There must be a better way of doing this in sse. + const BoolV one = FOne(); + const BoolV zero = FZero(); + const BoolV a1 = V4Sel(a, one, zero); + const BoolV b1 = V4Sel(b, one, zero); + return (_mm_comieq_ss(a1, b1) && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 1, 1, 1)), + _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(1, 1, 1, 1))) + && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(2, 2, 2, 2)), + _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(2, 2, 2, 2))) + && _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 3, 3, 3)), + _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(3, 3, 3, 3)))); +} + +QT3DS_FORCE_INLINE bool isValidFloatV(const FloatV a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))) + && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))) + && _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)))); +} + +QT3DS_FORCE_INLINE bool isValidVec3V(const Vec3V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero()) ? true : false); +} + +QT3DS_FORCE_INLINE bool isFiniteFloatV(const FloatV a) +{ + const QT3DSU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); + const FloatV vBadNum = FloatV_From_F32((QT3DSF32 &)badNumber); + const BoolV vMask = BAnd(vBadNum, a); + return FiniteTestEq(vMask, BFFFF()) == 1; +} + +QT3DS_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) +{ + const QT3DSU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); + const Vec3V vBadNum = Vec3V_From_F32((QT3DSF32 &)badNumber); + const BoolV vMask = BAnd(BAnd(vBadNum, a), BTTTF()); + return FiniteTestEq(vMask, BFFFF()) == 1; +} + +QT3DS_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) +{ + /*Vec4V a; + QT3DS_ALIGN(16, QT3DSF32 f[4]); + F32Array_Aligned_From_Vec4V(a, f); + return NVIsFinite(f[0]) + && NVIsFinite(f[1]) + && NVIsFinite(f[2]) + && NVIsFinite(f[3]);*/ + + const QT3DSU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); + const Vec4V vBadNum = Vec4V_From_F32((QT3DSF32 &)badNumber); + const BoolV vMask = BAnd(vBadNum, a); + + return FiniteTestEq(vMask, BFFFF()) == 1; +} + +QT3DS_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) ? true : false); +} + +QT3DS_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero())); +} + +QT3DS_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero()) + || _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero())); +} + +///////////////////////////////////////////////////////////////////// +////VECTORISED FUNCTION IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +QT3DS_FORCE_INLINE FloatV FloatV_From_F32(const QT3DSF32 f) +{ + return (_mm_load1_ps(&f)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_F32(const QT3DSF32 f) +{ + return _mm_set_ps(0.0f, f, f, f); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32(const QT3DSF32 f) +{ + return (_mm_load1_ps(&f)); +} + +QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32(const bool f) +{ + const QT3DSU32 i = -(QT3DSI32)f; + return _mm_load1_ps((float *)&i); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_Aligned(const QT3DSVec3 &f) +{ + VECMATHAOS_ASSERT(0 == ((size_t)&f & 0x0f)); + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3(const QT3DSVec3 &f) +{ + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_NVVec3_WUndefined(const QT3DSVec3 &f) +{ + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) +{ + return V4SetW(v, V4Zero()); +} + +QT3DS_FORCE_INLINE Vec3V Vec3V_From_F32Array_Aligned(const QT3DSF32 *const f) +{ + VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); + return (_mm_load_ps(f)); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) +{ + return f; // ok if it is implemented as the same type. +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_NVVec3_WUndefined(const QT3DSVec3 &f) +{ + return (_mm_set_ps(0.0f, f.z, f.y, f.x)); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array_Aligned(const QT3DSF32 *const f) +{ + VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); + return (_mm_load_ps(f)); +} + +QT3DS_FORCE_INLINE void F32Array_Aligned_From_Vec4V(const Vec4V a, QT3DSF32 *f) +{ + VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); + _mm_store_ps(f, a); +} + +QT3DS_FORCE_INLINE void NVU32Array_Aligned_From_BoolV(const BoolV a, QT3DSU32 *f) +{ + VECMATHAOS_ASSERT(0 == ((QT3DSU64)f & 0x0f)); + _mm_store_ps((QT3DSF32 *)f, a); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_F32Array(const QT3DSF32 *const f) +{ + return (_mm_loadu_ps(f)); +} + +QT3DS_FORCE_INLINE BoolV BoolV_From_Bool32Array(const bool *const f) +{ + const QT3DS_ALIGN(16, QT3DSU32 b[4]) = { -(QT3DSI32)f[0], -(QT3DSI32)f[1], -(QT3DSI32)f[2], -(QT3DSI32)f[3] }; + return _mm_load1_ps((float *)&b); +} + +QT3DS_FORCE_INLINE QT3DSF32 NVF32_From_FloatV(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + QT3DSF32 f; + _mm_store_ss(&f, a); + return f; +} + +QT3DS_FORCE_INLINE void NVF32_From_FloatV(const FloatV a, QT3DSF32 *QT3DS_RESTRICT f) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + _mm_store_ss(f, a); +} + +QT3DS_FORCE_INLINE void NVVec3Aligned_From_Vec3V(const Vec3V a, QT3DSVec3 &f) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); + VECMATHAOS_ASSERT(0 == ((int)&f & 0x0F)); + QT3DS_ALIGN(16, QT3DSF32 f2[4]); + _mm_store_ps(f2, a); + f = QT3DSVec3(f2[0], f2[1], f2[2]); +} + +QT3DS_FORCE_INLINE void Store_From_BoolV(const BoolV b, QT3DSU32 *b2) +{ + _mm_store_ss((QT3DSF32 *)b2, b); +} + +QT3DS_FORCE_INLINE void NVVec3_From_Vec3V(const Vec3V a, QT3DSVec3 &f) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(0 == ((int)&a & 0x0F)); + QT3DS_ALIGN(16, QT3DSF32 f2[4]); + _mm_store_ps(f2, a); + f = QT3DSVec3(f2[0], f2[1], f2[2]); +} + +QT3DS_FORCE_INLINE Mat33V Mat33V_From_NVMat33(const QT3DSMat33 &m) +{ + return Mat33V(Vec3V_From_NVVec3(m.column0), Vec3V_From_NVVec3(m.column1), + Vec3V_From_NVVec3(m.column2)); +} + +QT3DS_FORCE_INLINE void NVMat33_From_Mat33V(const Mat33V &m, QT3DSMat33 &out) +{ + QT3DS_ASSERT((size_t(&out) & 15) == 0); + NVVec3_From_Vec3V(m.col0, out.column0); + NVVec3_From_Vec3V(m.col1, out.column1); + NVVec3_From_Vec3V(m.col2, out.column2); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualFloatV(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return (_mm_comieq_ss(a, b) != 0); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec3V(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return V3AllEq(a, b) != 0; +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualVec4V(const Vec4V a, const Vec4V b) +{ + return V4AllEq(a, b) != 0; +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsEqualBoolV(const BoolV a, const BoolV b) +{ + return BAllTrue4_R(VecI32V_IsEq(a, b)) != 0; +} + +#define VECMATH_AOS_EPSILON (1e-3f) + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualFloatV(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + const FloatV c = FSub(a, b); + static const FloatV minError = FloatV_From_F32(-VECMATH_AOS_EPSILON); + static const FloatV maxError = FloatV_From_F32(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(c, minError) && _mm_comilt_ss(c, maxError)); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + const Vec3V c = V3Sub(a, b); + static const Vec3V minError = Vec3V_From_F32(-VECMATH_AOS_EPSILON); + static const Vec3V maxError = Vec3V_From_F32(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError)); +} + +QT3DS_FORCE_INLINE bool _VecMathTests::allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) +{ + const Vec4V c = V4Sub(a, b); + static const Vec4V minError = Vec4V_From_F32(-VECMATH_AOS_EPSILON); + static const Vec4V maxError = Vec4V_From_F32(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError) + && _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), minError) + && _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), maxError)); +} + +////////////////////////////////// +// FLOATV +////////////////////////////////// + +QT3DS_FORCE_INLINE FloatV FZero() +{ + return FloatV_From_F32(0.0f); +} + +QT3DS_FORCE_INLINE FloatV FOne() +{ + return FloatV_From_F32(1.0f); +} + +QT3DS_FORCE_INLINE FloatV FHalf() +{ + return FloatV_From_F32(0.5f); +} + +QT3DS_FORCE_INLINE FloatV FEps() +{ + return FloatV_From_F32(QT3DS_ENV_REAL); +} + +QT3DS_FORCE_INLINE FloatV FEps6() +{ + return FloatV_From_F32(1e-6f); +} + +QT3DS_FORCE_INLINE FloatV FMax() +{ + return FloatV_From_F32(QT3DS_MAX_REAL); +} + +QT3DS_FORCE_INLINE FloatV FNegMax() +{ + return FloatV_From_F32(-QT3DS_MAX_REAL); +} + +QT3DS_FORCE_INLINE FloatV IZero() +{ + const QT3DSU32 zero = 0; + return _mm_load1_ps((QT3DSF32 *)&zero); +} + +QT3DS_FORCE_INLINE FloatV IOne() +{ + const QT3DSU32 one = 1; + return _mm_load1_ps((QT3DSF32 *)&one); +} + +QT3DS_FORCE_INLINE FloatV ITwo() +{ + const QT3DSU32 two = 2; + return _mm_load1_ps((QT3DSF32 *)&two); +} + +QT3DS_FORCE_INLINE FloatV IThree() +{ + const QT3DSU32 three = 3; + return _mm_load1_ps((QT3DSF32 *)&three); +} + +QT3DS_FORCE_INLINE FloatV IFour() +{ + QT3DSU32 four = 4; + return _mm_load1_ps((QT3DSF32 *)&four); +} + +QT3DS_FORCE_INLINE FloatV FNeg(const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +QT3DS_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_add_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_sub_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE FloatV FRecip(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return _mm_div_ps(FOne(), a); +} + +QT3DS_FORCE_INLINE FloatV FRecipFast(const FloatV a) +{ + return _mm_rcp_ps(a); +} + +QT3DS_FORCE_INLINE FloatV FRsqrt(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return _mm_div_ps(FOne(), _mm_sqrt_ps(a)); +} + +QT3DS_FORCE_INLINE FloatV FSqrt(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + return _mm_sqrt_ps(a); +} + +QT3DS_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) +{ + return _mm_rsqrt_ps(a); +} + +QT3DS_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidFloatV(c)); + return FAdd(FMul(a, b), c); +} + +QT3DS_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidFloatV(c)); + return FSub(c, FMul(a, b)); +} + +QT3DS_FORCE_INLINE FloatV FAbs(const FloatV a) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + QT3DS_ALIGN(16, const static QT3DSU32 absMask[4]) = { 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF, + 0x7fFFffFF }; + return _mm_and_ps(a, _mm_load_ps((QT3DSF32 *)absMask)); +} + +QT3DS_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(_VecMathTests::allElementsEqualBoolV(c, BTTTT()) + || _VecMathTests::allElementsEqualBoolV(c, BFFFF())); + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +QT3DS_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_cmpgt_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_cmpge_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_max_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_min_ps(a, b); +} + +QT3DS_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(minV)); + VECMATHAOS_ASSERT(isValidFloatV(maxV)); + return FMax(FMin(a, maxV), minV); +} + +QT3DS_FORCE_INLINE QT3DSU32 FAllGrtr(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return (_mm_comigt_ss(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 FAllGrtrOrEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + + return (_mm_comige_ss(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 FAllEq(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + + return (_mm_comieq_ss(a, b)); +} + +QT3DS_FORCE_INLINE FloatV FRound(const FloatV a) +{ + // return _mm_round_ps(a, 0x0); + const Vec3V half = Vec3V_From_F32(0.5f); + const Vec3V aPlusHalf = V3Add(a, half); + __m128i tmp = _mm_cvttps_epi32(aPlusHalf); + return _mm_cvtepi32_ps(tmp); +} + +QT3DS_FORCE_INLINE FloatV FSin(const FloatV a) +{ + // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + FloatV Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const FloatV tmp = FMul(a, twoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V3 = FMul(V2, V1); + const FloatV V5 = FMul(V3, V2); + const FloatV V7 = FMul(V5, V2); + const FloatV V9 = FMul(V7, V2); + const FloatV V11 = FMul(V9, V2); + const FloatV V13 = FMul(V11, V2); + const FloatV V15 = FMul(V13, V2); + const FloatV V17 = FMul(V15, V2); + const FloatV V19 = FMul(V17, V2); + const FloatV V21 = FMul(V19, V2); + const FloatV V23 = FMul(V21, V2); + + const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Result = FMulAdd(S1, V3, V1); + Result = FMulAdd(S2, V5, Result); + Result = FMulAdd(S3, V7, Result); + Result = FMulAdd(S4, V9, Result); + Result = FMulAdd(S5, V11, Result); + Result = FMulAdd(S6, V13, Result); + Result = FMulAdd(S7, V15, Result); + Result = FMulAdd(S8, V17, Result); + Result = FMulAdd(S9, V19, Result); + Result = FMulAdd(S10, V21, Result); + Result = FMulAdd(S11, V23, Result); + + return Result; +} + +QT3DS_FORCE_INLINE FloatV FCos(const FloatV a) +{ + // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + FloatV Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const FloatV twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const FloatV tmp = FMul(a, twoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V4 = FMul(V2, V2); + const FloatV V6 = FMul(V4, V2); + const FloatV V8 = FMul(V4, V4); + const FloatV V10 = FMul(V6, V4); + const FloatV V12 = FMul(V6, V6); + const FloatV V14 = FMul(V8, V6); + const FloatV V16 = FMul(V8, V8); + const FloatV V18 = FMul(V10, V8); + const FloatV V20 = FMul(V10, V10); + const FloatV V22 = FMul(V12, V10); + + const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Result = FMulAdd(C1, V2, V4One()); + Result = FMulAdd(C2, V4, Result); + Result = FMulAdd(C3, V6, Result); + Result = FMulAdd(C4, V8, Result); + Result = FMulAdd(C5, V10, Result); + Result = FMulAdd(C6, V12, Result); + Result = FMulAdd(C7, V14, Result); + Result = FMulAdd(C8, V16, Result); + Result = FMulAdd(C9, V18, Result); + Result = FMulAdd(C10, V20, Result); + Result = FMulAdd(C11, V22, Result); + + return Result; +} + +QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) +{ + const BoolV ffff = BFFFF(); + const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); + return !BAllEq(c, ffff); +} + +QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) +{ + const BoolV tttt = BTTTT(); + const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); + return BAllEq(c, tttt); +} + +QT3DS_FORCE_INLINE QT3DSU32 FOutOfBounds(const FloatV a, const FloatV bounds) +{ + return FOutOfBounds(a, FNeg(bounds), bounds); +} + +QT3DS_FORCE_INLINE QT3DSU32 FInBounds(const FloatV a, const FloatV bounds) +{ + return FInBounds(a, FNeg(bounds), bounds); +} + +////////////////////////////////// +// VEC3V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec3V V3Splat(const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + const __m128 zero = V3Zero(); + const __m128 fff0 = _mm_move_ss(f, zero); + return _mm_shuffle_ps(fff0, fff0, _MM_SHUFFLE(0, 1, 2, 3)); +} + +QT3DS_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) +{ + VECMATHAOS_ASSERT(isValidFloatV(x)); + VECMATHAOS_ASSERT(isValidFloatV(y)); + VECMATHAOS_ASSERT(isValidFloatV(z)); + // static on zero causes compiler crash on x64 debug_opt + const __m128 zero = V3Zero(); + const __m128 xy = _mm_move_ss(x, y); + const __m128 z0 = _mm_move_ss(zero, z); + + return _mm_shuffle_ps(xy, z0, _MM_SHUFFLE(1, 0, 0, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3UnitX() +{ + const QT3DS_ALIGN(16, QT3DSF32 x[4]) = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +QT3DS_FORCE_INLINE Vec3V V3UnitY() +{ + const QT3DS_ALIGN(16, QT3DSF32 y[4]) = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +QT3DS_FORCE_INLINE Vec3V V3UnitZ() +{ + const QT3DS_ALIGN(16, QT3DSF32 z[4]) = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +QT3DS_FORCE_INLINE FloatV V3GetX(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE FloatV V3GetY(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +QT3DS_FORCE_INLINE FloatV V3GetZ(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V3Sel(BFTTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V3Sel(BTFTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V3Sel(BTTFT(), v, f); +} + +QT3DS_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) +{ + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 0, 3, 0)); + return V3SetY(r, V3GetX(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) +{ + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); + return V3SetY(r, V3GetY(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) +{ + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 2, 3, 2)); + return V3SetY(r, V3GetZ(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3Zero() +{ + return Vec3V_From_F32(0.0f); +} + +QT3DS_FORCE_INLINE Vec3V V3One() +{ + return Vec3V_From_F32(1.0f); +} + +QT3DS_FORCE_INLINE Vec3V V3Eps() +{ + return Vec3V_From_F32(QT3DS_ENV_REAL); +} + +QT3DS_FORCE_INLINE Vec3V V3Neg(const Vec3V f) +{ + VECMATHAOS_ASSERT(isValidVec3V(f)); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +QT3DS_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_add_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_sub_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + // why are these here? + // static const __m128 one=V3One(); + // static const __m128 tttf=BTTTF(); + // const __m128 b1=V3Sel(tttf,b,one); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + const __m128 one = V3One(); + const __m128 tttf = BTTTF(); + const __m128 b1 = V3Sel(tttf, b, one); + return _mm_mul_ps(a, _mm_rcp_ps(b1)); +} + +QT3DS_FORCE_INLINE Vec3V V3Recip(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_div_ps(V3One(), a); + return V3Sel(tttf, recipA, zero); +} + +QT3DS_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rcp_ps(a); + return V3Sel(tttf, recipA, zero); +} + +QT3DS_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_div_ps(V3One(), _mm_sqrt_ps(a)); + return V3Sel(tttf, recipA, zero); +} + +QT3DS_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rsqrt_ps(a); + return V3Sel(tttf, recipA, zero); +} + +QT3DS_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Add(V3Scale(a, b), c); +} + +QT3DS_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidFloatV(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Sub(c, V3Scale(a, b)); +} + +QT3DS_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Add(V3Mul(a, b), c); +} + +QT3DS_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + VECMATHAOS_ASSERT(isValidVec3V(c)); + return V3Sub(c, V3Mul(a, b)); +} + +QT3DS_FORCE_INLINE Vec3V V3Abs(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Max(a, V3Neg(a)); +} + +QT3DS_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + __m128 dot1 = _mm_mul_ps(a, b); // w,z,y,x + //__m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2,1,0,3)); //z,y,x,w + //__m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1,0,3,2)); //y,x,w,z + //__m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0,3,2,1)); //x,w,z,y + // return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1,shuf1)); + + __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); +} + +QT3DS_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); +} + +QT3DS_FORCE_INLINE FloatV V3Length(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_sqrt_ps(V3Dot(a, a)); +} + +QT3DS_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Dot(a, a); +} + +QT3DS_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(V3Dot(a, a) != FZero()) + return V3ScaleInv(a, _mm_sqrt_ps(V3Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return V3Mul(a, _mm_rsqrt_ps(V3Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 eps = V3Eps(); + const __m128 length = V3Length(a); + const __m128 isGreaterThanZero = FIsGrtr(length, eps); + return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), zero); +} + +QT3DS_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +QT3DS_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_cmpgt_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_cmpge_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_max_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(b)); + return _mm_min_ps(a, b); +} + +// Extract the maximum value from a +QT3DS_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + + return _mm_max_ps(_mm_max_ps(shuf1, shuf2), shuf3); +} + +// Extract the maximum value from a +QT3DS_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + + return _mm_min_ps(_mm_min_ps(shuf1, shuf2), shuf3); +} + +//// if(a > 0.0f) return 1.0f; else if a == 0.f return 0.f, else return -1.f; +// QT3DS_FORCE_INLINE Vec3V V3MathSign(const Vec3V a) +//{ +// VECMATHAOS_ASSERT(isValidVec3V(a)); +// +// const __m128i ai = _mm_cvtps_epi32(a); +// const __m128i bi = _mm_cvtps_epi32(V3Neg(a)); +// const __m128 aa = _mm_cvtepi32_ps(_mm_srai_epi32(ai, 31)); +// const __m128 bb = _mm_cvtepi32_ps(_mm_srai_epi32(bi, 31)); +// return _mm_or_ps(aa, bb); +//} + +// return (a >= 0.0f) ? 1.0f : -1.0f; +QT3DS_FORCE_INLINE Vec3V V3Sign(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + const __m128 zero = V3Zero(); + const __m128 one = V3One(); + const __m128 none = V3Neg(one); + return V3Sel(V3IsGrtrOrEq(a, zero), one, none); +} + +QT3DS_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(minV)); + VECMATHAOS_ASSERT(isValidVec3V(maxV)); + return V3Max(V3Min(a, maxV), minV); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtr(const Vec3V a, const Vec3V b) +{ + return BAllTrue3_R(V4IsGrtr(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) +{ + return BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3AllEq(const Vec3V a, const Vec3V b) +{ + return BAllTrue3_R(V4IsEq(a, b)); +} + +QT3DS_FORCE_INLINE Vec3V V3Round(const Vec3V a) +{ + // return _mm_round_ps(a, 0x0); + const Vec3V half = Vec3V_From_F32(0.5f); + const Vec3V aPlusHalf = V3Add(a, half); + const __m128i tmp = _mm_cvttps_epi32(aPlusHalf); + return _mm_cvtepi32_ps(tmp); +} + +QT3DS_FORCE_INLINE Vec3V V3Sin(const Vec3V a) +{ + // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + Vec3V Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec3V tmp = V3Mul(a, twoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V3 = V3Mul(V2, V1); + const Vec3V V5 = V3Mul(V3, V2); + const Vec3V V7 = V3Mul(V5, V2); + const Vec3V V9 = V3Mul(V7, V2); + const Vec3V V11 = V3Mul(V9, V2); + const Vec3V V13 = V3Mul(V11, V2); + const Vec3V V15 = V3Mul(V13, V2); + const Vec3V V17 = V3Mul(V15, V2); + const Vec3V V19 = V3Mul(V17, V2); + const Vec3V V21 = V3Mul(V19, V2); + const Vec3V V23 = V3Mul(V21, V2); + + const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Result = V3MulAdd(S1, V3, V1); + Result = V3MulAdd(S2, V5, Result); + Result = V3MulAdd(S3, V7, Result); + Result = V3MulAdd(S4, V9, Result); + Result = V3MulAdd(S5, V11, Result); + Result = V3MulAdd(S6, V13, Result); + Result = V3MulAdd(S7, V15, Result); + Result = V3MulAdd(S8, V17, Result); + Result = V3MulAdd(S9, V19, Result); + Result = V3MulAdd(S10, V21, Result); + Result = V3MulAdd(S11, V23, Result); + + return Result; +} + +QT3DS_FORCE_INLINE Vec3V V3Cos(const Vec3V a) +{ + // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + Vec3V Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + const Vec3V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec3V tmp = V3Mul(a, twoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V4 = V3Mul(V2, V2); + const Vec3V V6 = V3Mul(V4, V2); + const Vec3V V8 = V3Mul(V4, V4); + const Vec3V V10 = V3Mul(V6, V4); + const Vec3V V12 = V3Mul(V6, V6); + const Vec3V V14 = V3Mul(V8, V6); + const Vec3V V16 = V3Mul(V8, V8); + const Vec3V V18 = V3Mul(V10, V8); + const Vec3V V20 = V3Mul(V10, V10); + const Vec3V V22 = V3Mul(V12, V10); + + const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Result = V3MulAdd(C1, V2, V4One()); + Result = V3MulAdd(C2, V4, Result); + Result = V3MulAdd(C3, V6, Result); + Result = V3MulAdd(C4, V8, Result); + Result = V3MulAdd(C5, V10, Result); + Result = V3MulAdd(C6, V12, Result); + Result = V3MulAdd(C7, V14, Result); + Result = V3MulAdd(C8, V16, Result); + Result = V3MulAdd(C9, V18, Result); + Result = V3MulAdd(C10, V20, Result); + Result = V3MulAdd(C11, V22, Result); + + return Result; +} + +QT3DS_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 2, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 0)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)) + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 2, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 0, 1)); +} + +QT3DS_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) +{ + VECMATHAOS_ASSERT(isValidVec3V(v0)); + VECMATHAOS_ASSERT(isValidVec3V(v1)); + return _mm_shuffle_ps(v1, v0, _MM_SHUFFLE(3, 1, 2, 3)); +} + +QT3DS_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) +{ + VECMATHAOS_ASSERT(isValidVec3V(v0)); + VECMATHAOS_ASSERT(isValidVec3V(v1)); + return _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 0, 3, 2)); +} + +QT3DS_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) +{ + VECMATHAOS_ASSERT(isValidVec3V(v0)); + VECMATHAOS_ASSERT(isValidVec3V(v1)); + // There must be a better way to do this. + Vec3V v2 = V3Zero(); + FloatV y1 = V3GetY(v1); + FloatV x0 = V3GetX(v0); + v2 = V3SetX(v2, y1); + return V3SetY(v2, x0); +} + +QT3DS_FORCE_INLINE FloatV V3SumElems(const Vec3V a) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + + __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(min)); + VECMATHAOS_ASSERT(isValidVec3V(max)); + const BoolV ffff = BFFFF(); + const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); + return !BAllEq(c, ffff); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + VECMATHAOS_ASSERT(isValidVec3V(a)); + VECMATHAOS_ASSERT(isValidVec3V(min)); + VECMATHAOS_ASSERT(isValidVec3V(max)); + const BoolV tttt = BTTTT(); + const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); + return BAllEq(c, tttt); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) +{ + return V3OutOfBounds(a, V3Neg(bounds), bounds); +} + +QT3DS_FORCE_INLINE QT3DSU32 V3InBounds(const Vec3V a, const Vec3V bounds) +{ + return V3InBounds(a, V3Neg(bounds), bounds); +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec4V V4Splat(const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + // return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0,0,0,0)); + return f; +} + +QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatV *const floatVArray) +{ + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[0])); + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[1])); + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[2])); + VECMATHAOS_ASSERT(isValidFloatV(floatVArray[3])); + __m128 xw = _mm_move_ss(floatVArray[1], floatVArray[0]); // y, y, y, x + __m128 yz = _mm_move_ss(floatVArray[2], floatVArray[3]); // z, z, z, w + return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); +} + +QT3DS_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, + const FloatVArg w) +{ + VECMATHAOS_ASSERT(isValidFloatV(x)); + VECMATHAOS_ASSERT(isValidFloatV(y)); + VECMATHAOS_ASSERT(isValidFloatV(z)); + VECMATHAOS_ASSERT(isValidFloatV(w)); + __m128 xw = _mm_move_ss(y, x); // y, y, y, x + __m128 yz = _mm_move_ss(z, w); // z, z, z, w + return (_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); +} + +QT3DS_FORCE_INLINE Vec4V V4UnitW() +{ + const QT3DS_ALIGN(16, QT3DSF32 w[4]) = { 0.0f, 0.0f, 0.0f, 1.0f }; + const __m128 w128 = _mm_load_ps(w); + return w128; +} + +QT3DS_FORCE_INLINE Vec4V V4UnitX() +{ + const QT3DS_ALIGN(16, QT3DSF32 x[4]) = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +QT3DS_FORCE_INLINE Vec4V V4UnitY() +{ + const QT3DS_ALIGN(16, QT3DSF32 y[4]) = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +QT3DS_FORCE_INLINE Vec4V V4UnitZ() +{ + const QT3DS_ALIGN(16, QT3DSF32 z[4]) = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +QT3DS_FORCE_INLINE FloatV V4GetW(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +QT3DS_FORCE_INLINE FloatV V4GetX(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE FloatV V4GetY(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +QT3DS_FORCE_INLINE FloatV V4GetZ(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +QT3DS_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BTTTF(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BFTTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BTFTT(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) +{ + VECMATHAOS_ASSERT(isValidVec3V(v)); + VECMATHAOS_ASSERT(isValidFloatV(f)); + return V4Sel(BTTFT(), v, f); +} + +QT3DS_FORCE_INLINE Vec4V V4Zero() +{ + return Vec4V_From_F32(0.0f); +} + +QT3DS_FORCE_INLINE Vec4V V4One() +{ + return Vec4V_From_F32(1.0f); +} + +QT3DS_FORCE_INLINE Vec4V V4Eps() +{ + return Vec4V_From_F32(QT3DS_ENV_REAL); +} + +QT3DS_FORCE_INLINE Vec4V V4Neg(const Vec4V f) +{ + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +QT3DS_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) +{ + return _mm_add_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) +{ + return _mm_sub_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) +{ + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) +{ + return _mm_div_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +QT3DS_FORCE_INLINE Vec4V V4Recip(const Vec4V a) +{ + return _mm_div_ps(V4One(), a); +} + +QT3DS_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) +{ + return _mm_rcp_ps(a); +} + +QT3DS_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) +{ + return _mm_div_ps(V4One(), _mm_sqrt_ps(a)); +} + +QT3DS_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) +{ + return _mm_rsqrt_ps(a); +} + +QT3DS_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return V4Add(V4Scale(a, b), c); +} + +QT3DS_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) +{ + VECMATHAOS_ASSERT(isValidFloatV(b)); + return V4Sub(c, V4Scale(a, b)); +} + +QT3DS_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Add(V4Mul(a, b), c); +} + +QT3DS_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Sub(c, V4Mul(a, b)); +} + +QT3DS_FORCE_INLINE Vec4V V4Abs(const Vec4V a) +{ + return V4Max(a, V4Neg(a)); +} + +QT3DS_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) +{ + __m128 dot1 = _mm_mul_ps(a, b); // x,y,z,w + __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 1, 0, 3)); // w,x,y,z + __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 0, 3, 2)); // z,w,x,y + __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 3, 2, 1)); // y,z,w,x + return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1, shuf1)); +} + +QT3DS_FORCE_INLINE FloatV V4Length(const Vec4V a) +{ + return _mm_sqrt_ps(V4Dot(a, a)); +} + +QT3DS_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) +{ + return V4Dot(a, a); +} + +QT3DS_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) +{ + VECMATHAOS_ASSERT(V4Dot(a, a) != FZero()) + return V4ScaleInv(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) +{ + return V4ScaleInvFast(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +QT3DS_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a) +{ + const __m128 zero = FZero(); + const __m128 eps = V3Eps(); + const __m128 length = V4Length(a); + const __m128 isGreaterThanZero = V4IsGrtr(length, eps); + return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), zero); +} + +QT3DS_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) +{ + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +QT3DS_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) +{ + return _mm_cmpgt_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpge_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) +{ + return _mm_cmpeq_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec3V V4Max(const Vec4V a, const Vec4V b) +{ + return _mm_max_ps(a, b); +} + +QT3DS_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) +{ + return _mm_min_ps(a, b); +} + +// Extract the maximum value from a +QT3DS_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) +{ + __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_max_ps(_mm_max_ps(a, shuf1), _mm_max_ps(shuf2, shuf3)); +} + +// Extract the maximum value from a +QT3DS_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a) +{ + __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_min_ps(_mm_min_ps(a, shuf1), _mm_min_ps(shuf2, shuf3)); +} + +QT3DS_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) +{ + return V4Max(V4Min(a, maxV), minV); +} + +QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtr(const Vec4V a, const Vec4V b) +{ + return BAllTrue4_R(V4IsGrtr(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return BAllTrue4_R(V4IsGrtrOrEq(a, b)); +} + +QT3DS_FORCE_INLINE QT3DSU32 V4AllEq(const Vec4V a, const Vec4V b) +{ + return BAllTrue4_R(V4IsEq(a, b)); +} + +QT3DS_FORCE_INLINE Vec4V V4Round(const Vec4V a) +{ + // return _mm_round_ps(a, 0x0); + const Vec3V half = Vec3V_From_F32(0.5f); + const Vec3V aPlusHalf = V3Add(a, half); + __m128i tmp = _mm_cvttps_epi32(aPlusHalf); + return _mm_cvtepi32_ps(tmp); +} + +QT3DS_FORCE_INLINE Vec4V V4Sin(const Vec4V a) +{ + // Vec4V V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + // Vec4V S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + Vec4V Result; + + const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec4V tmp = V4Mul(a, twoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V3 = V4Mul(V2, V1); + const Vec4V V5 = V4Mul(V3, V2); + const Vec4V V7 = V4Mul(V5, V2); + const Vec4V V9 = V4Mul(V7, V2); + const Vec4V V11 = V4Mul(V9, V2); + const Vec4V V13 = V4Mul(V11, V2); + const Vec4V V15 = V4Mul(V13, V2); + const Vec4V V17 = V4Mul(V15, V2); + const Vec4V V19 = V4Mul(V17, V2); + const Vec4V V21 = V4Mul(V19, V2); + const Vec4V V23 = V4Mul(V21, V2); + + const Vec4V sinCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Result = V4MulAdd(S1, V3, V1); + Result = V4MulAdd(S2, V5, Result); + Result = V4MulAdd(S3, V7, Result); + Result = V4MulAdd(S4, V9, Result); + Result = V4MulAdd(S5, V11, Result); + Result = V4MulAdd(S6, V13, Result); + Result = V4MulAdd(S7, V15, Result); + Result = V4MulAdd(S8, V17, Result); + Result = V4MulAdd(S9, V19, Result); + Result = V4MulAdd(S10, V21, Result); + Result = V4MulAdd(S11, V23, Result); + + return Result; +} + +QT3DS_FORCE_INLINE Vec4V V4Cos(const Vec4V a) +{ + // XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + // XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + Vec4V Result; + + const Vec4V twoPi = Vec4V_From_F32Array_Aligned(g_PXReciprocalTwoPi.f); + const Vec4V tmp = V4Mul(a, twoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V4 = V4Mul(V2, V2); + const Vec4V V6 = V4Mul(V4, V2); + const Vec4V V8 = V4Mul(V4, V4); + const Vec4V V10 = V4Mul(V6, V4); + const Vec4V V12 = V4Mul(V6, V6); + const Vec4V V14 = V4Mul(V8, V6); + const Vec4V V16 = V4Mul(V8, V8); + const Vec4V V18 = V4Mul(V10, V8); + const Vec4V V20 = V4Mul(V10, V10); + const Vec4V V22 = V4Mul(V12, V10); + + const Vec4V cosCoefficients0 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = Vec4V_From_F32Array_Aligned(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Result = V4MulAdd(C1, V2, V4One()); + Result = V4MulAdd(C2, V4, Result); + Result = V4MulAdd(C3, V6, Result); + Result = V4MulAdd(C4, V8, Result); + Result = V4MulAdd(C5, V10, Result); + Result = V4MulAdd(C6, V12, Result); + Result = V4MulAdd(C7, V14, Result); + Result = V4MulAdd(C8, V16, Result); + Result = V4MulAdd(C9, V18, Result); + Result = V4MulAdd(C10, V20, Result); + Result = V4MulAdd(C11, V22, Result); + + return Result; +} + +////////////////////////////////// +// BoolV +////////////////////////////////// + +QT3DS_FORCE_INLINE BoolV BFFFF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0, 0 }; + const __m128 ffff = _mm_load_ps((float *)&f); + return ffff; +} + +QT3DS_FORCE_INLINE BoolV BFFFT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0, 0xFFFFFFFF }; + const __m128 ffft = _mm_load_ps((float *)&f); + return ffft; +} + +QT3DS_FORCE_INLINE BoolV BFFTF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0xFFFFFFFF, 0 }; + const __m128 fftf = _mm_load_ps((float *)&f); + return fftf; +} + +QT3DS_FORCE_INLINE BoolV BFFTT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 fftt = _mm_load_ps((float *)&f); + return fftt; +} + +QT3DS_FORCE_INLINE BoolV BFTFF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0, 0 }; + const __m128 ftff = _mm_load_ps((float *)&f); + return ftff; +} + +QT3DS_FORCE_INLINE BoolV BFTFT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0, 0xFFFFFFFF }; + const __m128 ftft = _mm_load_ps((float *)&f); + return ftft; +} + +QT3DS_FORCE_INLINE BoolV BFTTF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; + const __m128 fttf = _mm_load_ps((float *)&f); + return fttf; +} + +QT3DS_FORCE_INLINE BoolV BFTTT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 fttt = _mm_load_ps((float *)&f); + return fttt; +} + +QT3DS_FORCE_INLINE BoolV BTFFF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0, 0 }; + const __m128 tfff = _mm_load_ps((float *)&f); + return tfff; +} + +QT3DS_FORCE_INLINE BoolV BTFFT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0, 0xFFFFFFFF }; + const __m128 tfft = _mm_load_ps((float *)&f); + return tfft; +} + +QT3DS_FORCE_INLINE BoolV BTFTF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0 }; + const __m128 tftf = _mm_load_ps((float *)&f); + return tftf; +} + +QT3DS_FORCE_INLINE BoolV BTFTT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 tftt = _mm_load_ps((float *)&f); + return tftt; +} + +QT3DS_FORCE_INLINE BoolV BTTFF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0 }; + const __m128 ttff = _mm_load_ps((float *)&f); + return ttff; +} + +QT3DS_FORCE_INLINE BoolV BTTFT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF }; + const __m128 ttft = _mm_load_ps((float *)&f); + return ttft; +} + +QT3DS_FORCE_INLINE BoolV BTTTF() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; + const __m128 tttf = _mm_load_ps((float *)&f); + return tttf; +} + +QT3DS_FORCE_INLINE BoolV BTTTT() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + const __m128 tttt = _mm_load_ps((float *)&f); + return tttt; +} + +QT3DS_FORCE_INLINE BoolV BXMask() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0xFFFFFFFF, 0, 0, 0 }; + const __m128 tfff = _mm_load_ps((float *)&f); + return tfff; +} + +QT3DS_FORCE_INLINE BoolV BYMask() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0xFFFFFFFF, 0, 0 }; + const __m128 ftff = _mm_load_ps((float *)&f); + return ftff; +} + +QT3DS_FORCE_INLINE BoolV BZMask() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0xFFFFFFFF, 0 }; + const __m128 fftf = _mm_load_ps((float *)&f); + return fftf; +} + +QT3DS_FORCE_INLINE BoolV BWMask() +{ + const QT3DS_ALIGN(16, QT3DSU32 f[4]) = { 0, 0, 0, 0xFFFFFFFF }; + const __m128 ffft = _mm_load_ps((float *)&f); + return ffft; +} + +QT3DS_FORCE_INLINE BoolV BGetX(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +QT3DS_FORCE_INLINE BoolV BGetY(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +QT3DS_FORCE_INLINE BoolV BGetZ(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +QT3DS_FORCE_INLINE BoolV BGetW(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +QT3DS_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) +{ + return (_mm_and_ps(a, b)); +} + +QT3DS_FORCE_INLINE BoolV BNot(const BoolV a) +{ + const BoolV bAllTrue(BTTTT()); + return _mm_xor_ps(a, bAllTrue); +} + +QT3DS_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) +{ + return (_mm_andnot_ps(a, b)); +} + +QT3DS_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) +{ + return (_mm_or_ps(a, b)); +} + +QT3DS_FORCE_INLINE BoolV BAllTrue4(const BoolV a) +{ + const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) +{ + const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE BoolV BAllTrue3(const BoolV a) +{ + const BoolV bTmp = _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) +{ + const BoolV bTmp = _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), + _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +QT3DS_FORCE_INLINE QT3DSU32 BAllEq(const BoolV a, const BoolV b) +{ + const BoolV bTest = m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); + return BAllTrue4_R(bTest); +} + +////////////////////////////////// +// MAT33V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec3V M33MulV3(const Mat33V &a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +QT3DS_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V &a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +QT3DS_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V &A, const Vec3V b, const Vec3V c) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + Vec3V result = V3MulAdd(A.col0, x, c); + result = V3MulAdd(A.col1, y, result); + return V3MulAdd(A.col2, z, result); +} + +QT3DS_FORCE_INLINE Mat33V M33MulM33(const Mat33V &a, const Mat33V &b) +{ + return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Add(const Mat33V &a, const Mat33V &b) +{ + return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Sub(const Mat33V &a, const Mat33V &b) +{ + return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Neg(const Mat33V &a) +{ + return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Abs(const Mat33V &a) +{ + return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M33Inverse(const Mat33V &a) +{ + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = V3Zero(); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + + return Mat33V(_mm_mul_ps(colInv0, invDet), _mm_mul_ps(colInv1, invDet), + _mm_mul_ps(colInv2, invDet)); +} + +QT3DS_FORCE_INLINE Mat33V M33Trnsps(const Mat33V &a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +QT3DS_FORCE_INLINE Mat33V M33Identity() +{ + return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); +} + +QT3DS_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) +{ + const FloatV x = V3Mul(V3UnitX(), d); + const FloatV y = V3Mul(V3UnitY(), d); + const FloatV z = V3Mul(V3UnitZ(), d); + return Mat33V(x, y, z); +} + +////////////////////////////////// +// MAT34V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec3V M34MulV3(const Mat34V &a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); + return (V3Add(v0PlusV1Plusv2, a.col3)); +} + +QT3DS_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V &a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +QT3DS_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V &a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +QT3DS_FORCE_INLINE Mat34V M34MulM34(const Mat34V &a, const Mat34V &b) +{ + return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), + M34MulV3(a, b.col3)); +} + +QT3DS_FORCE_INLINE Mat33V M34MulM33(const Mat34V &a, const Mat33V &b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +QT3DS_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V &a, const Mat34V &b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +QT3DS_FORCE_INLINE Mat34V M34Add(const Mat34V &a, const Mat34V &b) +{ + return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), + V3Add(a.col3, b.col3)); +} + +QT3DS_FORCE_INLINE Mat34V M34Inverse(const Mat34V &a) +{ + Mat34V aInv; + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = V3Zero(); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + aInv.col0 = _mm_mul_ps(colInv0, invDet); + aInv.col1 = _mm_mul_ps(colInv1, invDet); + aInv.col2 = _mm_mul_ps(colInv2, invDet); + aInv.col3 = M34Mul33V3(aInv, V3Neg(a.col3)); + return aInv; +} + +QT3DS_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V &a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +////////////////////////////////// +// MAT44V +////////////////////////////////// + +QT3DS_FORCE_INLINE Vec4V M44MulV4(const Mat44V &a, const Vec4V b) +{ + const FloatV x = V4GetX(b); + const FloatV y = V4GetY(b); + const FloatV z = V4GetZ(b); + const FloatV w = V4GetW(b); + + const Vec4V v0 = V4Scale(a.col0, x); + const Vec4V v1 = V4Scale(a.col1, y); + const Vec4V v2 = V4Scale(a.col2, z); + const Vec4V v3 = V4Scale(a.col3, w); + const Vec4V v0PlusV1 = V4Add(v0, v1); + const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); + return (V4Add(v0PlusV1Plusv2, v3)); +} + +QT3DS_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V &a, const Vec4V b) +{ + QT3DS_ALIGN(16, FloatV dotProdArray[4]) = { V4Dot(a.col0, b), V4Dot(a.col1, b), V4Dot(a.col2, b), + V4Dot(a.col3, b) }; + return V4Merge(dotProdArray); +} + +QT3DS_FORCE_INLINE Mat44V M44MulM44(const Mat44V &a, const Mat44V &b) +{ + return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), + M44MulV4(a, b.col3)); +} + +QT3DS_FORCE_INLINE Mat44V M44Add(const Mat44V &a, const Mat44V &b) +{ + return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), + V4Add(a.col3, b.col3)); +} + +QT3DS_FORCE_INLINE Mat44V M44Trnsps(const Mat44V &a) +{ + const Vec4V v0 = _mm_unpacklo_ps(a.col0, a.col2); + const Vec4V v1 = _mm_unpackhi_ps(a.col0, a.col2); + const Vec4V v2 = _mm_unpacklo_ps(a.col1, a.col3); + const Vec4V v3 = _mm_unpackhi_ps(a.col1, a.col3); + return Mat44V(_mm_unpacklo_ps(v0, v2), _mm_unpackhi_ps(v0, v2), _mm_unpacklo_ps(v1, v3), + _mm_unpackhi_ps(v1, v3)); +} + +// The original code as provided by Intel in +// "Streaming SIMD Extensions - Inverse of 4x4 Matrix" +// (ftp://download.intel.com/design/pentiumiii/sml/24504301.pdf) +QT3DS_FORCE_INLINE Mat44V M44Inverse(const Mat44V &a) +{ + __m128 minor0, minor1, minor2, minor3; + __m128 row0, row1, row2, row3; + __m128 det, tmp1; + + tmp1 = V4Zero(); + row1 = V4Zero(); + row3 = V4Zero(); + + row0 = a.col0; + row1 = _mm_shuffle_ps(a.col1, a.col1, _MM_SHUFFLE(1, 0, 3, 2)); + row2 = a.col2; + row3 = _mm_shuffle_ps(a.col3, a.col3, _MM_SHUFFLE(1, 0, 3, 2)); + + tmp1 = _mm_mul_ps(row2, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_mul_ps(row1, tmp1); + minor1 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); + minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); + minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); + + tmp1 = _mm_mul_ps(row1, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); + minor3 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); + minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); + + tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + row2 = _mm_shuffle_ps(row2, row2, 0x4E); + minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); + minor2 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); + minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); + + tmp1 = _mm_mul_ps(row0, row1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); + + tmp1 = _mm_mul_ps(row0, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); + minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); + + tmp1 = _mm_mul_ps(row0, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); + + det = _mm_mul_ps(row0, minor0); + det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); + det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); + tmp1 = _mm_rcp_ss(det); +#if 0 + det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); + det = _mm_shuffle_ps(det, det, 0x00); +#else + det = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 0, 0, 0)); +#endif + + minor0 = _mm_mul_ps(det, minor0); + minor1 = _mm_mul_ps(det, minor1); + minor2 = _mm_mul_ps(det, minor2); + minor3 = _mm_mul_ps(det, minor3); + Mat44V invTrans(minor0, minor1, minor2, minor3); + return M44Trnsps(invTrans); +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_XYZW(QT3DSF32 x, QT3DSF32 y, QT3DSF32 z, QT3DSF32 w) +{ + return _mm_set_ps(w, z, y, x); +} + +// AP: work in progress - use proper SSE intrinsics where possible +QT3DS_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) +{ + VecU16V result; + result.m128_u16[0] = QT3DSU16(NVClamp((a).m128_u32[0], 0, 0xFFFF)); + result.m128_u16[1] = QT3DSU16(NVClamp((a).m128_u32[1], 0, 0xFFFF)); + result.m128_u16[2] = QT3DSU16(NVClamp((a).m128_u32[2], 0, 0xFFFF)); + result.m128_u16[3] = QT3DSU16(NVClamp((a).m128_u32[3], 0, 0xFFFF)); + result.m128_u16[4] = QT3DSU16(NVClamp((b).m128_u32[0], 0, 0xFFFF)); + result.m128_u16[5] = QT3DSU16(NVClamp((b).m128_u32[1], 0, 0xFFFF)); + result.m128_u16[6] = QT3DSU16(NVClamp((b).m128_u32[2], 0, 0xFFFF)); + result.m128_u16[7] = QT3DSU16(NVClamp((b).m128_u32[3], 0, 0xFFFF)); + return result; +} + +QT3DS_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32(const QT3DSI32 i) +{ + return (_mm_load1_ps((QT3DSF32 *)&i)); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array(const QT3DSI32 *i) +{ + return _mm_loadu_ps((QT3DSF32 *)i); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_From_I32Array_Aligned(const QT3DSI32 *i) +{ + return _mm_load_ps((QT3DSF32 *)i); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_add_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_sub_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_cmpgt_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Zero() +{ + return V4Zero(); +} + +QT3DS_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, + const VecI32VArg d) +{ + return V4Merge(a, b, c, d); +} + +template +QT3DS_FORCE_INLINE VecI32V V4ISplat() +{ + VecI32V result; + result.m128_i32[0] = a; + result.m128_i32[1] = a; + result.m128_i32[2] = a; + result.m128_i32[3] = a; + return result; +} + +QT3DS_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V *address) +{ + *address = val; +} + +QT3DS_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V *address) +{ + *address = val; +} + +QT3DS_FORCE_INLINE Vec4V V4LoadAligned(Vec4V *addr) +{ + return *addr; +} + +QT3DS_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V *addr) +{ + return Vec4V_From_F32Array((float *)addr); +} + +QT3DS_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) +{ + VecU32V result32(a); + result32 = V4U32Andc(result32, b); + return Vec4V(result32); +} + +QT3DS_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) +{ + return V4IsGrtr(a, b); +} + +QT3DS_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V *addr) +{ + return *addr; +} + +QT3DS_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V *addr) +{ + return *addr; +} + +QT3DS_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) +{ + // _mm_cmpgt_epi16 doesn't work for unsigned values unfortunately + // return m128_I2F(_mm_cmpgt_epi16(m128_F2I(a), m128_F2I(b))); + VecU16V result; + result.m128_u16[0] = (a).m128_u16[0] > (b).m128_u16[0]; + result.m128_u16[1] = (a).m128_u16[1] > (b).m128_u16[1]; + result.m128_u16[2] = (a).m128_u16[2] > (b).m128_u16[2]; + result.m128_u16[3] = (a).m128_u16[3] > (b).m128_u16[3]; + result.m128_u16[4] = (a).m128_u16[4] > (b).m128_u16[4]; + result.m128_u16[5] = (a).m128_u16[5] > (b).m128_u16[5]; + result.m128_u16[6] = (a).m128_u16[6] > (b).m128_u16[6]; + result.m128_u16[7] = (a).m128_u16[7] > (b).m128_u16[7]; + return result; +} + +QT3DS_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) +{ + Vec4V result = Vec4V_From_XYZW(QT3DSF32(a.m128_u32[0]), QT3DSF32(a.m128_u32[1]), QT3DSF32(a.m128_u32[2]), + QT3DSF32(a.m128_u32[3])); + return result; +} + +template +QT3DS_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) +{ + VecU32V result; + result.m128_u32[0] = result.m128_u32[1] = result.m128_u32[2] = result.m128_u32[3] = + a.m128_u32[index]; + return result; +} + +template +QT3DS_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) +{ + float *data = (float *)&a; + return Vec4V_From_F32(data[index]); +} + +template +QT3DS_FORCE_INLINE VecU16V V4U16SplatElement(VecU16V a) +{ + VecU16V result = a; // AM: initializing to avoid nonsensical warning 4701 here with VC10. + for (int i = 0; i < 8; i++) + result.m128_u16[i] = a.m128_u16[index]; + return result; +} + +template +QT3DS_FORCE_INLINE VecI16V V4I16SplatImmediate() +{ + VecI16V result; + result.m128_i16[0] = imm; + result.m128_i16[1] = imm; + result.m128_i16[2] = imm; + result.m128_i16[3] = imm; + result.m128_i16[4] = imm; + result.m128_i16[5] = imm; + result.m128_i16[6] = imm; + result.m128_i16[7] = imm; + return result; +} + +QT3DS_FORCE_INLINE VecU16V V4U16SubtractModulo(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_sub_epi16(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU16V V4U16AddModulo(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_add_epi16(m128_F2I(a), m128_F2I(b))); +} + +QT3DS_FORCE_INLINE VecU32V V4U16GetLo16(VecU16V a) +{ + VecU32V result; + result.m128_u32[0] = a.m128_u16[0]; + result.m128_u32[1] = a.m128_u16[2]; + result.m128_u32[2] = a.m128_u16[4]; + result.m128_u32[3] = a.m128_u16[6]; + return result; +} + +QT3DS_FORCE_INLINE VecU32V V4U16GetHi16(VecU16V a) +{ + VecU32V result; + result.m128_u32[0] = a.m128_u16[1]; + result.m128_u32[1] = a.m128_u16[3]; + result.m128_u32[2] = a.m128_u16[5]; + result.m128_u32[3] = a.m128_u16[7]; + return result; +} + +QT3DS_FORCE_INLINE VecU32V VecU32V_From_XYZW(QT3DSU32 x, QT3DSU32 y, QT3DSU32 z, QT3DSU32 w) +{ + VecU32V result; + result.m128_u32[0] = x; + result.m128_u32[1] = y; + result.m128_u32[2] = z; + result.m128_u32[3] = w; + return result; +} + +QT3DS_FORCE_INLINE Vec4V V4Ceil(const Vec4V a) +{ + return Vec4V_From_XYZW(NVCeil(a.m128_f32[0]), NVCeil(a.m128_f32[1]), NVCeil(a.m128_f32[2]), + NVCeil(a.m128_f32[3])); +} + +QT3DS_FORCE_INLINE Vec4V V4Floor(const Vec4V a) +{ + return Vec4V_From_XYZW(NVFloor(a.m128_f32[0]), NVFloor(a.m128_f32[1]), NVFloor(a.m128_f32[2]), + NVFloor(a.m128_f32[3])); +} + +QT3DS_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V a, QT3DSU32 power) +{ + QT3DS_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); + QT3DS_FORCE_PARAMETER_REFERENCE(power); // prevent warning in release builds + QT3DSF32 ffffFFFFasFloat = QT3DSF32(0xFFFF0000); + VecU32V result; + result.m128_u32[0] = QT3DSU32(NVClamp((a).m128_f32[0], 0.0f, ffffFFFFasFloat)); + result.m128_u32[1] = QT3DSU32(NVClamp((a).m128_f32[1], 0.0f, ffffFFFFasFloat)); + result.m128_u32[2] = QT3DSU32(NVClamp((a).m128_f32[2], 0.0f, ffffFFFFasFloat)); + result.m128_u32[3] = QT3DSU32(NVClamp((a).m128_f32[3], 0.0f, ffffFFFFasFloat)); + return result; +} + +#endif // QT3DS_WINDOWS_INLINE_AOS_H diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsIntrinsics.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsIntrinsics.h new file mode 100644 index 00000000..3e0b3e8f --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsIntrinsics.h @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_WINDOWS_INTRINSICS_H +#define QT3DS_FOUNDATION_QT3DS_WINDOWS_INTRINSICS_H + +#include "foundation/Qt3DS.h" + +#if !defined QT3DS_WINDOWS && !defined QT3DS_WIN8ARM +#error "This file should only be included by Windows builds!!" +#endif + +#ifdef QT3DS_GNUC +#include +#else +#include +#endif +#include +#include +#include +#include "foundation/Qt3DSAssert.h" + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +namespace intrinsics { +#endif + + //! \brief platform-specific absolute value + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float abs(float a) { return float(::fabs(a)); } + + //! \brief platform-specific select float + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float fsel(float a, float b, float c) + { + return (a >= 0.0f) ? b : c; + } + + //! \brief platform-specific sign + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sign(float a) { return (a >= 0.0f) ? 1.0f : -1.0f; } + + //! \brief platform-specific reciprocal + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recip(float a) { return 1.0f / a; } + + //! \brief platform-specific square root + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sqrt(float a) { return ::sqrtf(a); } + + //! \brief platform-specific reciprocal square root + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrt(float a) { return 1.0f / ::sqrtf(a); } + + //! \brief platform-specific sine + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float sin(float a) { return ::sinf(a); } + + //! \brief platform-specific cosine + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float cos(float a) { return ::cosf(a); } + + //! \brief platform-specific minimum + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMin(float a, float b) { return a < b ? a : b; } + + //! \brief platform-specific maximum + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float selectMax(float a, float b) { return a > b ? a : b; } + + //! \brief platform-specific finiteness check (not INF or NAN) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(float a) + { +#if defined(__CUDACC__) + return isfinite(a)? true : false; +#elif defined(QT3DS_GNUC) + return (std::isfinite(a) && !std::isinf(a)) ? true : false; +#else + return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); +#endif + } + + //! \brief platform-specific finiteness check (not INF or NAN) + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE bool isFinite(double a) + { +#if defined(__CUDACC__) + return isfinite(a)? true : false; +#elif defined(QT3DS_GNUC) + return (std::isfinite(a) && !std::isinf(a)) ? true : false; +#else + return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); +#endif + } + /* +* Implements a memory barrier +*/ + QT3DS_FORCE_INLINE void memoryBarrier() + { + _ReadWriteBarrier(); + /* long Barrier; + __asm { + xchg Barrier, eax + }*/ + } + + /*! + Returns the index of the highest set bit. Not valid for zero arg. + */ + QT3DS_FORCE_INLINE QT3DSU32 highestSetBitUnsafe(QT3DSU32 v) + { + unsigned long retval; + _BitScanReverse(&retval, v); + return retval; + } + + /*! + Returns the index of the highest set bit. Undefined for zero arg. + */ + QT3DS_FORCE_INLINE QT3DSU32 lowestSetBitUnsafe(QT3DSU32 v) + { + unsigned long retval; + _BitScanForward(&retval, v); + return retval; + } + + /*! + Returns the number of leading zeros in v. Returns 32 for v=0. + */ + QT3DS_FORCE_INLINE QT3DSU32 countLeadingZeros(QT3DSU32 v) + { + if (v) { + unsigned long bsr = (unsigned long)-1; + _BitScanReverse(&bsr, v); + return 31 - bsr; + } else + return 32; + } + + /*! + Sets \c count bytes starting at \c dst to zero. + */ + QT3DS_FORCE_INLINE void *memZero(void *QT3DS_RESTRICT dest, QT3DSU32 count) + { + return memset(dest, 0, count); + } + + /*! + Sets \c count bytes starting at \c dst to \c c. + */ + QT3DS_FORCE_INLINE void *memSet(void *QT3DS_RESTRICT dest, QT3DSI32 c, QT3DSU32 count) + { + return memset(dest, c, count); + } + + /*! + Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. + */ + QT3DS_FORCE_INLINE void *memCopy(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) + { + return memcpy(dest, src, count); + } + + /*! + Copies \c count bytes from \c src to \c dst. Supports overlapping regions. + */ + QT3DS_FORCE_INLINE void *memMove(void *QT3DS_RESTRICT dest, const void *QT3DS_RESTRICT src, QT3DSU32 count) + { + return memmove(dest, src, count); + } + + /*! + Set 128B to zero starting at \c dst+offset. Must be aligned. + */ + QT3DS_FORCE_INLINE void memZero128(void *QT3DS_RESTRICT dest, QT3DSU32 offset = 0) + { + QT3DS_ASSERT(((size_t(dest) + offset) & 0x7f) == 0); + memSet((char *QT3DS_RESTRICT)dest + offset, 0, 128); + } + + /*! + Prefetch aligned 128B around \c ptr+offset. + */ + QT3DS_FORCE_INLINE void prefetch128(const void *ptr, QT3DSU32 offset = 0) + { +#ifdef QT3DS_WINDOWS + _mm_prefetch(((const char *)ptr + offset), _MM_HINT_T0); +#endif + } + + /*! + Prefetch \c count bytes starting at \c ptr. + */ + QT3DS_FORCE_INLINE void prefetch(const void *ptr, QT3DSU32 count = 0) + { + for (QT3DSU32 i = 0; i <= count; i += 128) + prefetch128(ptr, i); + } + + //! \brief platform-specific reciprocal + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipFast(float a) { return 1.0f / a; } + + //! \brief platform-specific fast reciprocal square root + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float recipSqrtFast(float a) { return 1.0f / ::sqrtf(a); } + + //! \brief platform-specific floor + QT3DS_CUDA_CALLABLE QT3DS_FORCE_INLINE float floatFloor(float x) { return ::floorf(x); } + +#ifndef QT3DS_DOXYGEN +} // namespace intrinsics +} // namespace qt3ds +#endif + +#endif diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsMutex.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsMutex.cpp new file mode 100644 index 00000000..c5fef09f --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsMutex.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/windows/Qt3DSWindowsInclude.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSAssert.h" + +namespace qt3ds { +namespace foundation { + + namespace { + CRITICAL_SECTION *getMutex(MutexImpl *impl) + { + return reinterpret_cast(impl); + } + } + + MutexImpl::MutexImpl() { InitializeCriticalSection(getMutex(this)); } + + MutexImpl::~MutexImpl() { DeleteCriticalSection(getMutex(this)); } + + bool MutexImpl::lock() + { + EnterCriticalSection(getMutex(this)); + return true; + } + + bool MutexImpl::trylock() { return TryEnterCriticalSection(getMutex(this)) != 0; } + + bool MutexImpl::unlock() + { + LeaveCriticalSection(getMutex(this)); + return true; + } + + const QT3DSU32 MutexImpl::size = sizeof(CRITICAL_SECTION); + + class ReadWriteLockImpl + { + public: + ReadWriteLockImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + HANDLE hReaderEvent; + HANDLE hMutex; + CRITICAL_SECTION writerMutex; + LONG counter; // count the number of readers in the lock. + LONG recursionCounter; // handle recursive writer locking + }; + + ReadWriteLock::ReadWriteLock(NVAllocatorCallback &alloc) + { + mImpl = QT3DS_NEW(alloc, ReadWriteLockImpl)(alloc); + + mImpl->hReaderEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + QT3DS_ASSERT(mImpl->hReaderEvent != NULL); + + mImpl->hMutex = CreateEvent(NULL, FALSE, TRUE, NULL); + QT3DS_ASSERT(mImpl->hMutex != NULL); + + InitializeCriticalSection(&mImpl->writerMutex); + mImpl->counter = -1; + mImpl->recursionCounter = 0; + } + + ReadWriteLock::~ReadWriteLock() + { + if (mImpl->hReaderEvent != NULL) { + CloseHandle(mImpl->hReaderEvent); + } + + if (mImpl->hMutex != NULL) { + CloseHandle(mImpl->hMutex); + } + + DeleteCriticalSection(&mImpl->writerMutex); + + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + void ReadWriteLock::lockReader() + { + if (InterlockedIncrement(&mImpl->counter) == 0) { + WaitForSingleObject(mImpl->hMutex, INFINITE); + SetEvent(mImpl->hReaderEvent); + } + + WaitForSingleObject(mImpl->hReaderEvent, INFINITE); + } + + void ReadWriteLock::lockWriter() + { + EnterCriticalSection(&mImpl->writerMutex); + + // we may already have the global mutex(really an event so we have to handle recursion + // ourselves) + if (++mImpl->recursionCounter == 1) { + WaitForSingleObject(mImpl->hMutex, INFINITE); + } + } + + void ReadWriteLock::unlockReader() + { + if (InterlockedDecrement(&mImpl->counter) < 0) { + ResetEvent(mImpl->hReaderEvent); + SetEvent(mImpl->hMutex); + } + } + + void ReadWriteLock::unlockWriter() + { + if (--mImpl->recursionCounter == 0) { + SetEvent(mImpl->hMutex); + } + + LeaveCriticalSection(&mImpl->writerMutex); + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp new file mode 100644 index 00000000..bb14c104 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsSemaphore.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/windows/Qt3DSWindowsInclude.h" +#include "foundation/Qt3DSSemaphore.h" +#include "foundation/Qt3DSAllocator.h" + +namespace qt3ds { +namespace foundation { + + class SemaphoreImpl + { + public: + SemaphoreImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + HANDLE handle; + }; + + Semaphore::Semaphore(NVAllocatorCallback &alloc, QT3DSU32 initialCount, QT3DSU32 maxCount) + { + mImpl = QT3DS_NEW(alloc, SemaphoreImpl)(alloc); + mImpl->handle = CreateSemaphore(0, initialCount, maxCount, (LPCTSTR)NULL); + } + + Semaphore::~Semaphore() + { + CloseHandle(mImpl->handle); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + bool Semaphore::wait(QT3DSU32 milliseconds) + { + if (milliseconds == -1) + milliseconds = INFINITE; + + return WaitForSingleObject(mImpl->handle, milliseconds) == WAIT_OBJECT_0 ? true : false; + } + + void Semaphore::post() { ReleaseSemaphore(mImpl->handle, 1, (LPLONG)NULL); } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsString.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsString.h new file mode 100644 index 00000000..8d5fcd31 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsString.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_FOUNDATION_QT3DS_WINDOWS_STRING_H +#define QT3DS_FOUNDATION_QT3DS_WINDOWS_STRING_H + +#include "foundation/Qt3DS.h" + +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable : 4995 4996) + +#ifndef QT3DS_DOXYGEN +namespace qt3ds { +#endif + +QT3DS_INLINE void NVStrcpy(char *dest, size_t size, const char *src) +{ + ::strcpy_s(dest, size, src); +} +QT3DS_INLINE void NVStrcat(char *dest, size_t size, const char *src) +{ + ::strcat_s(dest, size, src); +} +QT3DS_INLINE QT3DSI32 NVVsprintf(char *dest, size_t size, const char *src, va_list arg) +{ + QT3DSI32 r = ::vsprintf_s(dest, size, src, arg); + + return r; +} +QT3DS_INLINE QT3DSI32 NVStricmp(const char *str, const char *str1) +{ + return (::_stricmp(str, str1)); +} + +namespace string { + QT3DS_INLINE QT3DSI32 stricmp(const char *str, const char *str1) { return (::_stricmp(str, str1)); } + QT3DS_INLINE QT3DSI32 strnicmp(const char *str, const char *str1, size_t len) + { + return (::_strnicmp(str, str1, len)); + } + QT3DS_INLINE QT3DSI32 strncat_s(char *a, QT3DSI32 b, const char *c, size_t d) + { + return (::strncat_s(a, b, c, d)); + } + QT3DS_INLINE QT3DSI32 strncpy_s(char *strDest, size_t sizeInBytes, const char *strSource, + size_t count) + { + return (::strncpy_s(strDest, sizeInBytes, strSource, count)); + } + QT3DS_INLINE void strcpy_s(char *dest, size_t size, const char *src) + { + ::strcpy_s(dest, size, src); + } + QT3DS_INLINE void strcat_s(char *dest, size_t size, const char *src) + { + ::strcat_s(dest, size, src); + } + QT3DS_INLINE QT3DSI32 _vsnprintf(char *dest, size_t size, const char *src, va_list arg) + { + QT3DSI32 r = ::_vsnprintf(dest, size, src, arg); + + return r; + } + QT3DS_INLINE QT3DSI32 vsprintf_s(char *dest, size_t size, const char *src, va_list arg) + { + QT3DSI32 r = ::vsprintf_s(dest, size, src, arg); + + return r; + } + + QT3DS_INLINE QT3DSI32 sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...) + { + va_list arg; + va_start(arg, _Format); + QT3DSI32 r = ::vsprintf_s(_DstBuf, _DstSize, _Format, arg); + va_end(arg); + + return r; + } + QT3DS_INLINE QT3DSI32 sscanf_s(const char *buffer, const char *format, ...) + { + va_list arg; + va_start(arg, format); + QT3DSI32 r = ::sscanf_s(buffer, format, arg); + va_end(arg); + + return r; + }; + + QT3DS_INLINE void strlwr(char *str) + { + while (*str) { + if (*str >= 'A' && *str <= 'Z') + *str += 32; + str++; + } + } + + QT3DS_INLINE void strupr(char *str) + { + while (*str) { + if (*str >= 'a' && *str <= 'z') + *str -= 32; + str++; + } + } + +} // namespace string + +#ifndef QT3DS_DOXYGEN +} // namespace qt3ds +#endif + +#pragma warning(pop) + +#endif diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsSync.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsSync.cpp new file mode 100644 index 00000000..49667e94 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsSync.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/windows/Qt3DSWindowsInclude.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSAllocator.h" + +namespace qt3ds { +namespace foundation { + + class SyncImpl + { + public: + SyncImpl(NVAllocatorCallback &alloc) + : mAllocator(alloc) + { + } + NVAllocatorCallback &mAllocator; + HANDLE handle; + }; + + Sync::Sync(NVAllocatorCallback &alloc) + { + mImpl = QT3DS_NEW(alloc, SyncImpl)(alloc); + mImpl->handle = CreateEvent(0, true, false, 0); + } + + Sync::~Sync() + { + CloseHandle(mImpl->handle); + QT3DS_FREE(mImpl->mAllocator, mImpl); + } + + void Sync::reset() { ResetEvent(mImpl->handle); } + + void Sync::set() { SetEvent(mImpl->handle); } + + bool Sync::wait(QT3DSU32 milliseconds) + { + if (milliseconds == -1) + milliseconds = INFINITE; + + return WaitForSingleObject(mImpl->handle, milliseconds) == WAIT_OBJECT_0 ? true : false; + } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsThread.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsThread.cpp new file mode 100644 index 00000000..3a30de8c --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsThread.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/windows/Qt3DSWindowsInclude.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSThread.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" + +// an exception for setting the thread name in microsoft debuggers +#define QT3DS_MS_VC_EXCEPTION 0x406D1388 + +namespace qt3ds { +namespace foundation { + +// struct for naming a thread in the debugger +#pragma pack(push, 8) + + typedef struct tagTHREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + } THREADNAME_INFO; + +#pragma pack(pop) + + namespace { + + DWORD WINAPI NVThreadStart(LPVOID arg) + { + ((Thread *)arg)->execute(); + return 0; + } + } + + class ThreadImpl + { + public: + enum State { NotStarted, Started, Stopped }; + ThreadImpl(NVFoundationBase &foundation) + : mFoundation(foundation) + { + } + NVFoundationBase &mFoundation; + HANDLE thread; + LONG quitNow; // Should be 32bit aligned on SMP systems. + State state; + DWORD threadID; + + Thread::ExecuteFn fn; + void *arg; + }; + + Thread::Id Thread::getId() { return static_cast(GetCurrentThreadId()); } + + Thread::Thread(NVFoundationBase &foundation) + { + mImpl = (ThreadImpl *)QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); + mImpl->thread = NULL; + mImpl->state = ThreadImpl::NotStarted; + mImpl->quitNow = 0; + } + + Thread::Thread(NVFoundationBase &foundation, ExecuteFn fn, void *arg) + { + mImpl = (ThreadImpl *)QT3DS_NEW(foundation.getAllocator(), ThreadImpl)(foundation); + mImpl->thread = NULL; + mImpl->state = ThreadImpl::NotStarted; + mImpl->quitNow = 0; + mImpl->fn = fn; + mImpl->arg = arg; + + start(0); + } + + Thread::~Thread() + { + if (mImpl->state == ThreadImpl::Started) + kill(); + CloseHandle(mImpl->thread); + QT3DS_FREE(mImpl->mFoundation.getAllocator(), mImpl); + } + + void Thread::start(QT3DSU32 stackSize) + { + if (mImpl->state != ThreadImpl::NotStarted) + return; + mImpl->state = ThreadImpl::Started; + + mImpl->thread = + CreateThread(NULL, stackSize, NVThreadStart, (LPVOID)this, 0, &mImpl->threadID); + } + + void Thread::signalQuit() { InterlockedIncrement(&(mImpl->quitNow)); } + + bool Thread::waitForQuit() + { + if (mImpl->state == ThreadImpl::NotStarted) + return false; + + WaitForSingleObject(mImpl->thread, INFINITE); + return true; + } + + bool Thread::quitIsSignalled() + { + return InterlockedCompareExchange(&(mImpl->quitNow), 0, 0) != 0; + } + + void Thread::quit() + { + mImpl->state = ThreadImpl::Stopped; + ExitThread(0); + } + + void Thread::kill() + { + if (mImpl->state == ThreadImpl::Started) + TerminateThread(mImpl->thread, 0); + mImpl->state = ThreadImpl::Stopped; + } + + void Thread::sleep(QT3DSU32 ms) { Sleep(ms); } + + void Thread::yield() { SwitchToThread(); } + + void Thread::execute(void) { (*mImpl->fn)(mImpl->arg); } + + QT3DSU32 Thread::setAffinityMask(QT3DSU32 mask) + { + return mask ? (QT3DSU32)SetThreadAffinityMask(mImpl->thread, mask) : 0; + } + + void Thread::setName(const char *name) + { + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = mImpl->threadID; + info.dwFlags = 0; + +#ifdef QT3DS_VC + // C++ Exceptions are disabled for this project, but SEH is not (and cannot be) + // http://stackoverflow.com/questions/943087/what-exactly-will-happen-if-i-disable-c-exceptions-in-a-project + __try { + RaiseException(QT3DS_MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR *)&info); + } __except (EXCEPTION_EXECUTE_HANDLER) { + // this runs if not attached to a debugger (thus not really naming the thread) + } +#else + RaiseException(QT3DS_MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR *)&info); +#endif + } + + void Thread::setPriority(ThreadPriority::Enum prio) + { + switch (prio) { + case ThreadPriority::eHIGH: + SetThreadPriority(mImpl->thread, THREAD_PRIORITY_HIGHEST); + break; + case ThreadPriority::eABOVE_NORMAL: + SetThreadPriority(mImpl->thread, THREAD_PRIORITY_ABOVE_NORMAL); + break; + case ThreadPriority::eNORMAL: + SetThreadPriority(mImpl->thread, THREAD_PRIORITY_NORMAL); + break; + case ThreadPriority::eBELOW_NORMAL: + SetThreadPriority(mImpl->thread, THREAD_PRIORITY_BELOW_NORMAL); + break; + case ThreadPriority::eLOW: + SetThreadPriority(mImpl->thread, THREAD_PRIORITY_LOWEST); + break; + default: + break; + } + } + + ThreadPriority::Enum Thread::getPriority(Id threadId) + { + ThreadPriority::Enum retval = ThreadPriority::eLOW; + int priority = GetThreadPriority((HANDLE)threadId); + StaticAssert<(THREAD_PRIORITY_HIGHEST > THREAD_PRIORITY_ABOVE_NORMAL)>::valid_expression(); + if (priority >= THREAD_PRIORITY_HIGHEST) + retval = ThreadPriority::eHIGH; + else if (priority >= THREAD_PRIORITY_ABOVE_NORMAL) + retval = ThreadPriority::eABOVE_NORMAL; + else if (priority >= THREAD_PRIORITY_NORMAL) + retval = ThreadPriority::eNORMAL; + else if (priority >= THREAD_PRIORITY_BELOW_NORMAL) + retval = ThreadPriority::eBELOW_NORMAL; + return retval; + } + + QT3DSU32 TlsAlloc() + { + DWORD rv = ::TlsAlloc(); + QT3DS_ASSERT(rv != TLS_OUT_OF_INDEXES); + return (QT3DSU32)rv; + } + + void TlsFree(QT3DSU32 index) { ::TlsFree(index); } + + void *TlsGet(QT3DSU32 index) { return ::TlsGetValue(index); } + + QT3DSU32 TlsSet(QT3DSU32 index, void *value) { return ::TlsSetValue(index, value); } + + const QT3DSU32 Thread::DEFAULT_STACK_SIZE = 1048576; + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsTime.cpp b/src/Runtime/Source/foundation/windows/Qt3DSWindowsTime.cpp new file mode 100644 index 00000000..9215d642 --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsTime.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSTime.h" +#include "foundation/windows/Qt3DSWindowsInclude.h" + +namespace { +::qt3ds::QT3DSI64 getTimeTicks() +{ + LARGE_INTEGER a; + QueryPerformanceCounter(&a); + return a.QuadPart; +} + +double getTickDuration() +{ + LARGE_INTEGER a; + QueryPerformanceFrequency(&a); + return 1.0f / double(a.QuadPart); +} + +double sTickDuration = getTickDuration(); +} // namespace + +namespace qt3ds { +namespace foundation { + + const CounterFrequencyToTensOfNanos Time::sCounterFreq = Time::getCounterFrequency(); + + CounterFrequencyToTensOfNanos Time::getCounterFrequency() + { + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + return CounterFrequencyToTensOfNanos(Time::sNumTensOfNanoSecondsInASecond, freq.QuadPart); + } + + QT3DSU64 Time::getCurrentCounterValue() + { + LARGE_INTEGER ticks; + QueryPerformanceCounter(&ticks); + return ticks.QuadPart; + } + + Time::Time() + : mTickCount(0) + { + getElapsedSeconds(); + } + + Time::Second Time::getElapsedSeconds() + { + QT3DSI64 lastTickCount = mTickCount; + mTickCount = getTimeTicks(); + return (mTickCount - lastTickCount) * sTickDuration; + } + + Time::Second Time::peekElapsedSeconds() + { + return (getTimeTicks() - mTickCount) * sTickDuration; + } + + Time::Second Time::getLastTime() const { return mTickCount * sTickDuration; } + +} // namespace foundation +} // namespace qt3ds diff --git a/src/Runtime/Source/foundation/windows/Qt3DSWindowsTrigConstants.h b/src/Runtime/Source/foundation/windows/Qt3DSWindowsTrigConstants.h new file mode 100644 index 00000000..e3da844c --- /dev/null +++ b/src/Runtime/Source/foundation/windows/Qt3DSWindowsTrigConstants.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_WINDOWS_TRIG_CONSTANTS_H +#define QT3DS_WINDOWS_TRIG_CONSTANTS_H + +#define QT3DS_GLOBALCONST extern const __declspec(selectany) + +__declspec(align(16)) struct QT3DS_VECTORF32 +{ + float f[4]; +}; + +#define QT3DS_PI 3.141592654f +#define QT3DS_2PI 6.283185307f +#define QT3DS_1DIVPI 0.318309886f +#define QT3DS_1DIV2PI 0.159154943f +#define QT3DS_PIDIV2 1.570796327f +#define QT3DS_PIDIV4 0.785398163f + +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients0 = { 1.0f, -0.166666667f, 8.333333333e-3f, + -1.984126984e-4f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients1 = { 2.755731922e-6f, -2.505210839e-8f, + 1.605904384e-10f, -7.647163732e-13f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinCoefficients2 = { 2.811457254e-15f, -8.220635247e-18f, + 1.957294106e-20f, -3.868170171e-23f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients0 = { 1.0f, -0.5f, 4.166666667e-2f, + -1.388888889e-3f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients1 = { 2.480158730e-5f, -2.755731922e-7f, + 2.087675699e-9f, -1.147074560e-11f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosCoefficients2 = { 4.779477332e-14f, -1.561920697e-16f, + 4.110317623e-19f, -8.896791392e-22f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients0 = { 1.0f, 0.333333333f, 0.133333333f, + 5.396825397e-2f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients1 = { 2.186948854e-2f, 8.863235530e-3f, + 3.592128167e-3f, 1.455834485e-3f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanCoefficients2 = { 5.900274264e-4f, 2.391290764e-4f, + 9.691537707e-5f, 3.927832950e-5f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients0 = { -0.05806367563904f, -0.41861972469416f, + 0.22480114791621f, 2.17337241360606f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients1 = { 0.61657275907170f, 4.29696498283455f, + -1.18942822255452f, -6.53784832094831f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinCoefficients2 = { -1.36926553863413f, -4.48179294237210f, + 1.41810672941833f, 5.48179257935713f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients0 = { 1.0f, 0.333333334f, 0.2f, 0.142857143f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients1 = { 1.111111111e-1f, 9.090909091e-2f, + 7.692307692e-2f, 6.666666667e-2f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanCoefficients2 = { 5.882352941e-2f, 5.263157895e-2f, + 4.761904762e-2f, 4.347826087e-2f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXSinEstCoefficients = { 1.0f, -1.66521856991541e-1f, + 8.199913018755e-3f, -1.61475937228e-4f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXCosEstCoefficients = { 1.0f, -4.95348008918096e-1f, + 3.878259962881e-2f, -9.24587976263e-4f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXTanEstCoefficients = { 2.484f, -1.954923183e-1f, 2.467401101f, + QT3DS_1DIVPI }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXATanEstCoefficients = { 7.689891418951e-1f, 1.104742493348f, + 8.661844266006e-1f, QT3DS_PIDIV2 }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstCoefficients = { -1.36178272886711f, 2.37949493464538f, + -8.08228565650486e-1f, + 2.78440142746736e-1f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXASinEstConstants = { 1.00000011921f, QT3DS_PIDIV2, 0.0f, 0.0f }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXPiConstants0 = { QT3DS_PI, QT3DS_2PI, QT3DS_1DIVPI, QT3DS_1DIV2PI }; +QT3DS_GLOBALCONST QT3DS_VECTORF32 g_PXReciprocalTwoPi = { QT3DS_1DIV2PI, QT3DS_1DIV2PI, QT3DS_1DIV2PI, + QT3DS_1DIV2PI }; + +#endif diff --git a/src/Runtime/Source/foundation/windows/SocketImpl.h b/src/Runtime/Source/foundation/windows/SocketImpl.h new file mode 100644 index 00000000..f72203bd --- /dev/null +++ b/src/Runtime/Source/foundation/windows/SocketImpl.h @@ -0,0 +1,506 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* +LuaSocket 3.0 license +Copyright � 2004-2013 Diego Nehab + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef FOUNDATION_WINDOWS_SOCKET_IMPL_H +#define FOUNDATION_WINDOWS_SOCKET_IMPL_H +#pragma once +#include +#pragma warning(disable : 4127) +#pragma warning(disable : 4702) + +namespace qt3ds { +namespace foundation { + namespace socketimpl { + + // Functions take from lua socket implementation. Note that it has an MIT license. + + enum { + IO_DONE = 0, /* operation completed successfully */ + IO_TIMEOUT = -1, /* operation timed out */ + IO_CLOSED = -2, /* the connection has been closed */ + IO_UNKNOWN = -3 + }; + + /*-------------------------------------------------------------------------*\ + * I/O error strings + \*-------------------------------------------------------------------------*/ + const char *io_strerror(int err) + { + switch (err) { + case IO_DONE: + return NULL; + case IO_CLOSED: + return "closed"; + case IO_TIMEOUT: + return "timeout"; + default: + return "unknown error"; + } + } + + typedef int socklen_t; + typedef SOCKET t_socket; + typedef t_socket *p_socket; + typedef struct sockaddr SA; + +#define SOCKET_INVALID (INVALID_SOCKET) + + static const char *wstrerror(int err) + { + switch (err) { + case WSAEINTR: + return "Interrupted function call"; + case WSAEACCES: + return "Permission denied"; + case WSAEFAULT: + return "Bad address"; + case WSAEINVAL: + return "Invalid argument"; + case WSAEMFILE: + return "Too many open files"; + case WSAEWOULDBLOCK: + return "Resource temporarily unavailable"; + case WSAEINPROGRESS: + return "Operation now in progress"; + case WSAEALREADY: + return "Operation already in progress"; + case WSAENOTSOCK: + return "Socket operation on nonsocket"; + case WSAEDESTADDRREQ: + return "Destination address required"; + case WSAEMSGSIZE: + return "Message too long"; + case WSAEPROTOTYPE: + return "Protocol wrong type for socket"; + case WSAENOPROTOOPT: + return "Bad protocol option"; + case WSAEPROTONOSUPPORT: + return "Protocol not supported"; + case WSAESOCKTNOSUPPORT: + return "Socket type not supported"; + case WSAEOPNOTSUPP: + return "Operation not supported"; + case WSAEPFNOSUPPORT: + return "Protocol family not supported"; + case WSAEAFNOSUPPORT: + return "Address family not supported by protocol family"; + case WSAEADDRINUSE: + return "Address already in use"; + case WSAEADDRNOTAVAIL: + return "Cannot assign requested address"; + case WSAENETDOWN: + return "Network is down"; + case WSAENETUNREACH: + return "Network is unreachable"; + case WSAENETRESET: + return "Network dropped connection on reset"; + case WSAECONNABORTED: + return "Software caused connection abort"; + case WSAECONNRESET: + return "Connection reset by peer"; + case WSAENOBUFS: + return "No buffer space available"; + case WSAEISCONN: + return "Socket is already connected"; + case WSAENOTCONN: + return "Socket is not connected"; + case WSAESHUTDOWN: + return "Cannot send after socket shutdown"; + case WSAETIMEDOUT: + return "Connection timed out"; + case WSAECONNREFUSED: + return "Connection refused"; + case WSAEHOSTDOWN: + return "Host is down"; + case WSAEHOSTUNREACH: + return "No route to host"; + case WSAEPROCLIM: + return "Too many processes"; + case WSASYSNOTREADY: + return "Network subsystem is unavailable"; + case WSAVERNOTSUPPORTED: + return "Winsock.dll version out of range"; + case WSANOTINITIALISED: + return "Successful WSAStartup not yet performed"; + case WSAEDISCON: + return "Graceful shutdown in progress"; + case WSAHOST_NOT_FOUND: + return "Host not found"; + case WSATRY_AGAIN: + return "Nonauthoritative host not found"; + case WSANO_RECOVERY: + return "Nonrecoverable name lookup error"; + case WSANO_DATA: + return "Valid name, no data record of requested type"; + default: + return "Unknown error"; + } + } + + const char *socket_strerror(int err) + { + switch (err) { + case WSAEADDRINUSE: + return "address already in use"; + case WSAECONNREFUSED: + return "connection refused"; + case WSAEISCONN: + return "already connected"; + case WSAEACCES: + return "permission denied"; + case WSAECONNABORTED: + return "closed"; + case WSAECONNRESET: + return "closed"; + case WSAETIMEDOUT: + return "timeout"; + default: + return wstrerror(err); + } + } + + int socket_open(void) + { + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 0); + int err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) + return 0; + if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) + && (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { + WSACleanup(); + return 0; + } + return 1; + } + + /*-------------------------------------------------------------------------*\ + * Close module + \*-------------------------------------------------------------------------*/ + int socket_close(void) + { + WSACleanup(); + return 1; + } + +/*-------------------------------------------------------------------------*\ +* Wait for readable/writable/connected socket with timeout +\*-------------------------------------------------------------------------*/ +#define WAITFD_R 1 +#define WAITFD_W 2 +#define WAITFD_E 4 +#define WAITFD_C (WAITFD_E | WAITFD_W) + + static int socket_waitfd(p_socket ps, int sw, QT3DSU32 timeoutMilliseconds) + { + int ret; + fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; + struct timeval tv, *tp = NULL; + if (timeoutMilliseconds == 0) + return IO_TIMEOUT; /* optimize timeout == 0 case */ + if (sw & WAITFD_R) { + FD_ZERO(&rfds); + FD_SET(*ps, &rfds); + rp = &rfds; + } + if (sw & WAITFD_W) { + FD_ZERO(&wfds); + FD_SET(*ps, &wfds); + wp = &wfds; + } + if (sw & WAITFD_C) { + FD_ZERO(&efds); + FD_SET(*ps, &efds); + ep = &efds; + } + if (timeoutMilliseconds >= 0.0) { + tv.tv_sec = (int)(timeoutMilliseconds / 1000); + QT3DSU32 leftover = timeoutMilliseconds % 1000; + tv.tv_usec = (int)(leftover * 100000); + tp = &tv; + } + ret = select(0, rp, wp, ep, tp); + if (ret == -1) + return WSAGetLastError(); + if (ret == 0) + return IO_TIMEOUT; + if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) + return IO_CLOSED; + return IO_DONE; + } + + static int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, + QT3DSU32 timeoutMilliseconds) + { + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + /* loop until we send something or we give up on error */ + for (;;) { + /* try to send something */ + int put = send(*ps, data, (int)count, 0); + /* if we sent something, we are done */ + if (put > 0) { + *sent = put; + return IO_DONE; + } + /* deal with failure */ + err = WSAGetLastError(); + /* we can only proceed if there was no serious error */ + if (err != WSAEWOULDBLOCK) + return err; + /* avoid busy wait */ + if ((err = socket_waitfd(ps, WAITFD_W, timeoutMilliseconds)) != IO_DONE) + return err; + } + /* can't reach here */ + return IO_UNKNOWN; + } + /*-------------------------------------------------------------------------*\ + * Receive with timeout + \*-------------------------------------------------------------------------*/ + static int socket_recv(p_socket ps, char *data, size_t count, size_t *got, + QT3DSU32 timeoutMilliseconds) + { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + for (;;) { + int taken = recv(*ps, data, (int)count, 0); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + if (taken == 0) + return IO_CLOSED; + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) + return err; + if ((err = socket_waitfd(ps, WAITFD_R, timeoutMilliseconds)) != IO_DONE) + return err; + } + return IO_UNKNOWN; + } + + void socket_setblocking(p_socket ps) + { + u_long argp = 0; + ioctlsocket(*ps, FIONBIO, &argp); + } + + /*-------------------------------------------------------------------------*\ + * Put socket into non-blocking mode + \*-------------------------------------------------------------------------*/ + void socket_setnonblocking(p_socket ps) + { + u_long argp = 1; + ioctlsocket(*ps, FIONBIO, &argp); + } + + int socket_listen(p_socket ps, int backlog) + { + int err = IO_DONE; + socket_setblocking(ps); + if (listen(*ps, backlog) < 0) + err = WSAGetLastError(); + socket_setnonblocking(ps); + return err; + } + + /*-------------------------------------------------------------------------*\ + * Accept with timeout + \*-------------------------------------------------------------------------*/ + static int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, QT3DSU32 tm) + { + SA daddr; + socklen_t dlen = sizeof(daddr); + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + if (!addr) + addr = &daddr; + if (!len) + len = &dlen; + for (;;) { + int err; + /* try to get client socket */ + if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) + return IO_DONE; + /* find out why we failed */ + err = WSAGetLastError(); + /* if we failed because there was no connectoin, keep trying */ + if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) + return err; + /* call select to avoid busy wait */ + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) + return err; + } + /* can't reach here */ + return IO_UNKNOWN; + } + + int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) + { + *hp = gethostbyaddr(addr, len, AF_INET); + if (*hp) + return IO_DONE; + else + return WSAGetLastError(); + } + + int socket_gethostbyname(const char *addr, struct hostent **hp) + { + *hp = gethostbyname(addr); + if (*hp) + return IO_DONE; + else + return WSAGetLastError(); + } + + /*-------------------------------------------------------------------------*\ + * Error translation functions + \*-------------------------------------------------------------------------*/ + const char *socket_hoststrerror(int err) + { + if (err <= 0) + return io_strerror(err); + switch (err) { + case WSAHOST_NOT_FOUND: + return "host not found"; + default: + return wstrerror(err); + } + } + /*-------------------------------------------------------------------------*\ + * Close and inutilize socket + \*-------------------------------------------------------------------------*/ + void socket_destroy(p_socket ps) + { + if (*ps != SOCKET_INVALID) { + socket_setblocking(ps); /* close can take a long time on WIN32 */ + closesocket(*ps); + *ps = SOCKET_INVALID; + } + } + + /*-------------------------------------------------------------------------*\ + * + \*-------------------------------------------------------------------------*/ + void socket_shutdown(p_socket ps, int how) + { + socket_setblocking(ps); + shutdown(*ps, how); + } + + int socket_create(p_socket ps, int domain, int type, int protocol) + { + *ps = socket(domain, type, protocol); + if (*ps != SOCKET_INVALID) + return IO_DONE; + else + return WSAGetLastError(); + } + + /*-------------------------------------------------------------------------*\ + * Connects or returns error message + \*-------------------------------------------------------------------------*/ + int socket_connect(p_socket ps, SA *addr, socklen_t len, QT3DSU32 tm) + { + int err; + /* don't call on closed socket */ + if (*ps == SOCKET_INVALID) + return IO_CLOSED; + /* ask system to connect */ + if (connect(*ps, addr, len) == 0) + return IO_DONE; + /* make sure the system is trying to connect */ + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) + return err; + /* zero timeout case optimization */ + if (tm == 0) + return IO_TIMEOUT; + /* we wait until something happens */ + err = socket_waitfd(ps, WAITFD_C, tm); + if (err == IO_CLOSED) { + int len = sizeof(err); + /* give windows time to set the error (yes, disgusting) */ + Sleep(10); + /* find out why we failed */ + getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); + /* we KNOW there was an error. if 'why' is 0, we will return + * "unknown error", but it's not really our fault */ + return err > 0 ? err : IO_UNKNOWN; + } else + return err; + } + + /*-------------------------------------------------------------------------*\ + * Binds or returns error message + \*-------------------------------------------------------------------------*/ + int socket_bind(p_socket ps, SA *addr, socklen_t len) + { + int err = IO_DONE; + socket_setblocking(ps); + if (bind(*ps, addr, len) < 0) + err = WSAGetLastError(); + socket_setnonblocking(ps); + return err; + } + } +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/foundation/windows/qt_attribution.json b/src/Runtime/Source/foundation/windows/qt_attribution.json new file mode 100644 index 00000000..e0310cfa --- /dev/null +++ b/src/Runtime/Source/foundation/windows/qt_attribution.json @@ -0,0 +1,10 @@ +{ + "Id": "qt3dswindowsaos", + "Name": "Qt3DSWindowsAoS", + "QDocModule": "qt3dstudio", + "QtUsage": "Used by Qt3DStudio, Runtime component.", + + "License": "Other", + "LicenseFile": "LICENSE.TXT", + "Copyright": "Copyright (c) 2001 Intel Corporation." +} diff --git a/src/Runtime/Source/hdr/CUDABSDFMipmap.cpp b/src/Runtime/Source/hdr/CUDABSDFMipmap.cpp new file mode 100644 index 00000000..94f6712f --- /dev/null +++ b/src/Runtime/Source/hdr/CUDABSDFMipmap.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifdef PLATFORM_HAS_CUDA + +#include "CUDABSDFMipmap.h" +#include "cuda.h" +#include "cuda_runtime.h" +#include "cuda_gl_interop.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/Qt3DSRefCounted.h" +#include "nv_log.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace qt3ds::foundation; + +__host__ void jerror1(cudaError error); +#ifdef _DEBUG +#define CHECK_AND_HANDLE_CUDA_ERROR(func) \ + func; \ + { \ + cudaError error = cudaGetLastError(); \ + if (error != cudaSuccess) { \ + printf("%s\n", cudaGetErrorString(error)); \ + jerror1(error); \ + QT3DS_ASSERT(false); \ + } \ + } +#else +#define CHECK_AND_HANDLE_CUDA_ERROR(func) func; +#endif + +CUDABSDFMipMap::CUDABSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) + : BSDFMipMap(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd) + , m_TextureBinded(false) +{ + + // CHECK_AND_HANDLE_CUDA_ERROR( cudaFree( 0 ); ) + m_Pitches = (size_t *)QT3DS_ALLOC(m_Foundation.getAllocator(), + sizeof(size_t) * m_MaxMipMapLevel + 1, "BSDF MipMap pitches"); + md_MipMapsData = (void **)QT3DS_ALLOC(m_Foundation.getAllocator(), + sizeof(void *) * m_MaxMipMapLevel + 1, "BSDF MipMap data"); + // CHECK_AND_HANDLE_CUDA_ERROR(); + size_t imagePitch; + int width = m_Width; + int height = m_Height; + + for (int i = 0; i <= m_MaxMipMapLevel; ++i) { + imagePitch = m_SizeOfFormat * width; + // checkCudaErrors(cudaMalloc((void **)&cuda_dest_resource[mip], size_tex_data)); + CHECK_AND_HANDLE_CUDA_ERROR( + cudaMallocPitch((void **)&md_MipMapsData[i], &m_Pitches[i], imagePitch, height);) + CHECK_AND_HANDLE_CUDA_ERROR(cudaMemset(md_MipMapsData[i], -1, m_Pitches[i] * height);) + + width = width > 2 ? width >> 1 : 1; + height = height > 2 ? height >> 1 : 1; + } +} + +CUDABSDFMipMap::~CUDABSDFMipMap() +{ + // CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceReset(); ) + CHECK_AND_HANDLE_CUDA_ERROR(cudaDeviceSynchronize();) + for (int i = 0; i <= m_MaxMipMapLevel; ++i) { + CHECK_AND_HANDLE_CUDA_ERROR(cudaFree(md_MipMapsData[i]);) + } + QT3DS_FREE(m_Foundation.getAllocator(), md_MipMapsData); + QT3DS_FREE(m_Foundation.getAllocator(), m_Pitches); +} + +void CUDABSDFMipMap::BindTexture() +{ + if (!m_TextureBinded) { + m_TextureBinded = true; + + int width = m_Width; + int height = m_Height; + for (int i = 0; i <= m_MaxMipMapLevel; ++i) { + // if you wwant to change some texture filter settings use m_Texture2D object + m_Texture2D.SetTextureData(NVDataRef(), (QT3DSU8)i, width, height, + NVRenderTextureFormats::RGBA16F, + NVRenderTextureFormats::RGBA16F); + + width = width > 2 ? width >> 1 : 1; + height = height > 2 ? height >> 1 : 1; + } + // CHECK_AND_HANDLE_CUDA_ERROR( cudaGraphicsGLRegisterImage( &m_CudaMipMapResource, + // (GLuint)m_TextureHandle, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard | + // cudaGraphicsRegisterFlagsTextureGather) ) + CHECK_AND_HANDLE_CUDA_ERROR(cudaGraphicsGLRegisterImage( + &m_CudaMipMapResource, (GLuint)m_TextureHandle, GL_TEXTURE_2D, + cudaGraphicsRegisterFlagsWriteDiscard | cudaGraphicsRegisterFlagsTextureGather)) + } +} + +void CUDABSDFMipMap::TransferTexture() // after cuda generation +{ + cudaArray *texturePtr; + CHECK_AND_HANDLE_CUDA_ERROR(cudaGraphicsMapResources(1, &m_CudaMipMapResource, 0)) + int width = m_Width; + int height = m_Height; + for (int i = 0; i <= m_MaxMipMapLevel; ++i) { + CHECK_AND_HANDLE_CUDA_ERROR( + cudaGraphicsSubResourceGetMappedArray(&texturePtr, m_CudaMipMapResource, 0, i)) + CHECK_AND_HANDLE_CUDA_ERROR(cudaMemcpy2DToArray(texturePtr, 0, 0, md_MipMapsData[i], + m_Pitches[i], width * m_SizeOfFormat, + height, cudaMemcpyDeviceToDevice)); + + width = width > 2 ? width >> 1 : 1; + height = height > 2 ? height >> 1 : 1; + } + CHECK_AND_HANDLE_CUDA_ERROR(cudaGraphicsUnmapResources(1, &m_CudaMipMapResource, 0)) +} + +#endif diff --git a/src/Runtime/Source/hdr/CUDABSDFMipmap.h b/src/Runtime/Source/hdr/CUDABSDFMipmap.h new file mode 100644 index 00000000..33e0b91c --- /dev/null +++ b/src/Runtime/Source/hdr/CUDABSDFMipmap.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUDABSDfMIPMAP_H +#define CUDABSDFMIPMAP_H +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "MipmapBSDF.h" + +#include "Qt3DSRenderLoadedTexture.h" + +#include "Qt3DSTypes.h" +struct cudaGraphicsResource; +#ifdef _LINUXPLATFORM +#define __declspec(dllexport) +#define __cdecl + +#endif +using namespace qt3ds::render; + +class CUDABSDFMipMap : public BSDFMipMap +{ +public: + CUDABSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + ~CUDABSDFMipMap(); + void Build(void *inTextureData, int inTextureDataSize, + NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, + NVRenderTextureFormats::Enum inFormat); + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation); + +private: + void CreateBsdfMipMaps(qt3ds::render::SLoadedTexture &inLoadedImage, void **result, int width, + int height); //, qt3ds::foundation::IPerfTimer& inPerfTimer); + + void BindTexture(); + void TransferTexture(); + + cudaGraphicsResource *m_CudaMipMapResource; + void **md_MipMapsData; + size_t *m_Pitches; + NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; + bool m_TextureBinded; +}; + +#endif diff --git a/src/Runtime/Source/hdr/GLComputeMipMap.h b/src/Runtime/Source/hdr/GLComputeMipMap.h new file mode 100644 index 00000000..a1a7ce5f --- /dev/null +++ b/src/Runtime/Source/hdr/GLComputeMipMap.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLCOMPUTE_BSDF_MIMAP_H +#define GLCOMPUTE_BSDF_MIMAP_H + +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "MipmapBSDF.h" + +#include "Qt3DSRenderLoadedTexture.h" +#include "Qt3DSTypes.h" + +using namespace qt3ds::render; + +class qt3ds::render::NVRenderContext; +class qt3ds::render::NVRenderShaderProgram; +class qt3ds::render::NVRenderTexture2D; + +class GLComputeMipMap : public BSDFMipMap +{ +public: + GLComputeMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + ~GLComputeMipMap(); + void Build(void *inTextureData, int inTextureDataSize, + NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, + NVRenderTextureFormats::Enum inFormat); + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation); + +private: + void CreateLevel0Tex(void *inTextureData, int inTextureDataSize, + NVRenderTextureFormats::Enum inFormat); + + NVScopedRefCounted m_BSDFProgram; + NVScopedRefCounted m_UploadProgram_RGBA8; + NVScopedRefCounted m_UploadProgram_RGB8; + NVScopedRefCounted m_Level0Tex; + bool m_TextureCreated; + + void createComputeProgram(NVRenderContext *context); + NVRenderShaderProgram *getOrCreateUploadComputeProgram(NVRenderContext *context, + NVRenderTextureFormats::Enum inFormat); +}; + +#endif diff --git a/src/Runtime/Source/hdr/GLComputeMipmap.cpp b/src/Runtime/Source/hdr/GLComputeMipmap.cpp new file mode 100644 index 00000000..36b550dd --- /dev/null +++ b/src/Runtime/Source/hdr/GLComputeMipmap.cpp @@ -0,0 +1,394 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "GLComputeMipMap.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "render/Qt3DSRenderContext.h" +#include "nv_log.h" +#include + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace qt3ds::foundation; + +static const char *computeUploadShader(std::string &prog, NVRenderTextureFormats::Enum inFormat, + bool binESContext) +{ + if (binESContext) { + prog += "#version 310 es\n" + "#extension GL_ARB_compute_shader : enable\n" + "precision highp float;\n" + "precision highp int;\n" + "precision mediump image2D;\n"; + } else { + prog += "#version 430\n" + "#extension GL_ARB_compute_shader : enable\n"; + } + + if (inFormat == NVRenderTextureFormats::RGBA8) { + prog += "// Set workgroup layout;\n" + "layout (local_size_x = 16, local_size_y = 16) in;\n\n" + "layout (rgba8, binding = 1) uniform image2D inputImage;\n\n" + "layout (rgba16f, binding = 2) uniform image2D outputImage;\n\n" + "void main()\n" + "{\n" + " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " + ">= gl_NumWorkGroups.y )\n" + " return;\n" + " vec4 value = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.xy));\n" + " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), value );\n" + "}\n"; + } else { + prog += "float convertToFloat( in uint inValue )\n" + "{\n" + " uint v = inValue & uint(0xFF);\n" + " float f = float(v)/256.0;\n" + " return f;\n" + "}\n"; + + prog += "int getMod( in int inValue, in int mod )\n" + "{\n" + " int v = mod * (inValue/mod);\n" + " return inValue - v;\n" + "}\n"; + + prog += "vec4 getRGBValue( in int byteNo, vec4 inVal, vec4 inVal1 )\n" + "{\n" + " vec4 result= vec4(0.0);\n" + " if( byteNo == 0) {\n" + " result.r = inVal.r;\n" + " result.g = inVal.g;\n" + " result.b = inVal.b;\n" + " }\n" + " else if( byteNo == 1) {\n" + " result.r = inVal.g;\n" + " result.g = inVal.b;\n" + " result.b = inVal.a;\n" + " }\n" + " else if( byteNo == 2) {\n" + " result.r = inVal.b;\n" + " result.g = inVal.a;\n" + " result.b = inVal1.r;\n" + " }\n" + " else if( byteNo == 3) {\n" + " result.r = inVal.a;\n" + " result.g = inVal1.r;\n" + " result.b = inVal1.g;\n" + " }\n" + " return result;\n" + "}\n"; + + prog += "// Set workgroup layout;\n" + "layout (local_size_x = 16, local_size_y = 16) in;\n\n" + "layout (rgba8, binding = 1) uniform image2D inputImage;\n\n" + "layout (rgba16f, binding = 2) uniform image2D outputImage;\n\n" + "void main()\n" + "{\n" + " vec4 result = vec4(0.0);\n" + " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " + ">= gl_NumWorkGroups.y )\n" + " return;\n" + " int xpos = (int(gl_GlobalInvocationID.x)*3)/4;\n" + " int xmod = getMod(int(gl_GlobalInvocationID.x)*3, 4);\n" + " ivec2 readPos = ivec2(xpos, gl_GlobalInvocationID.y);\n" + " vec4 value = imageLoad(inputImage, readPos);\n" + " vec4 value1 = imageLoad(inputImage, ivec2(readPos.x + 1, readPos.y));\n" + " result = getRGBValue( xmod, value, value1);\n" + " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), result );\n" + "}\n"; + } + return prog.c_str(); +} + +static const char *computeWorkShader(std::string &prog, bool binESContext) +{ + if (binESContext) { + prog += "#version 310 es\n" + "#extension GL_ARB_compute_shader : enable\n" + "precision highp float;\n" + "precision highp int;\n" + "precision mediump image2D;\n"; + } else { + prog += "#version 430\n" + "#extension GL_ARB_compute_shader : enable\n"; + } + + prog += "int wrapMod( in int a, in int base )\n" + "{\n" + " return ( a >= 0 ) ? a % base : -(a % base) + base;\n" + "}\n"; + + prog += "void getWrappedCoords( inout int sX, inout int sY, in int width, in int height )\n" + "{\n" + " if (sY < 0) { sX -= width >> 1; sY = -sY; }\n" + " if (sY >= height) { sX += width >> 1; sY = height - sY; }\n" + " sX = wrapMod( sX, width );\n" + "}\n"; + + prog += "// Set workgroup layout;\n" + "layout (local_size_x = 16, local_size_y = 16) in;\n\n" + "layout (rgba16f, binding = 1) uniform image2D inputImage;\n\n" + "layout (rgba16f, binding = 2) uniform image2D outputImage;\n\n" + "void main()\n" + "{\n" + " int prevWidth = int(gl_NumWorkGroups.x) << 1;\n" + " int prevHeight = int(gl_NumWorkGroups.y) << 1;\n" + " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y >= " + "gl_NumWorkGroups.y )\n" + " return;\n" + " vec4 accumVal = vec4(0.0);\n" + " for ( int sy = -2; sy <= 2; ++sy )\n" + " {\n" + " for ( int sx = -2; sx <= 2; ++sx )\n" + " {\n" + " int sampleX = sx + (int(gl_GlobalInvocationID.x) << 1);\n" + " int sampleY = sy + (int(gl_GlobalInvocationID.y) << 1);\n" + " getWrappedCoords(sampleX, sampleY, prevWidth, prevHeight);\n" + " if ((sampleY * prevWidth + sampleX) < 0 )\n" + " sampleY = prevHeight + sampleY;\n" + " ivec2 pos = ivec2(sampleX, sampleY);\n" + " vec4 value = imageLoad(inputImage, pos);\n" + " float filterPdf = 1.0 / ( 1.0 + float(sx*sx + sy*sy)*2.0 );\n" + " filterPdf /= 4.71238898;\n" + " accumVal[0] += filterPdf * value.r;\n" + " accumVal[1] += filterPdf * value.g;\n" + " accumVal[2] += filterPdf * value.b;\n" + " accumVal[3] += filterPdf * value.a;\n" + " }\n" + " }\n" + " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), accumVal );\n" + "}\n"; + + return prog.c_str(); +} + +GLComputeMipMap::GLComputeMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) + : BSDFMipMap(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd) + , m_BSDFProgram(NULL) + , m_UploadProgram_RGBA8(NULL) + , m_UploadProgram_RGB8(NULL) + , m_Level0Tex(NULL) + , m_TextureCreated(false) +{ +} + +GLComputeMipMap::~GLComputeMipMap() +{ + m_UploadProgram_RGB8 = NULL; + m_UploadProgram_RGBA8 = NULL; + m_BSDFProgram = NULL; + m_Level0Tex = NULL; +} + +inline NVConstDataRef toRef(const char *data) +{ + size_t len = strlen(data) + 1; + return NVConstDataRef((const QT3DSI8 *)data, (QT3DSU32)len); +} + +static bool isGLESContext(NVRenderContext *context) +{ + NVRenderContextType ctxType = context->GetRenderContextType(); + + // Need minimum of GL3 or GLES3 + if (ctxType == NVRenderContextValues::GLES2 || ctxType == NVRenderContextValues::GLES3 + || ctxType == NVRenderContextValues::GLES31) { + return true; + } + + return false; +} + +#define WORKGROUP_SIZE 16 + +void GLComputeMipMap::createComputeProgram(NVRenderContext *context) +{ + std::string computeProg; + + if (!m_BSDFProgram) { + m_BSDFProgram = context + ->CompileComputeSource( + "Compute BSDF mipmap shader", + toRef(computeWorkShader(computeProg, isGLESContext(context)))) + .mShader; + } +} + +NVRenderShaderProgram * +GLComputeMipMap::getOrCreateUploadComputeProgram(NVRenderContext *context, + NVRenderTextureFormats::Enum inFormat) +{ + std::string computeProg; + + if (inFormat == NVRenderTextureFormats::RGB8) { + if (!m_UploadProgram_RGB8) { + m_UploadProgram_RGB8 = + context + ->CompileComputeSource( + "Compute BSDF mipmap level 0 RGB8 shader", + toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) + .mShader; + } + + return m_UploadProgram_RGB8; + } else { + if (!m_UploadProgram_RGBA8) { + m_UploadProgram_RGBA8 = + context + ->CompileComputeSource( + "Compute BSDF mipmap level 0 RGBA8 shader", + toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) + .mShader; + } + + return m_UploadProgram_RGBA8; + } +} + +void GLComputeMipMap::CreateLevel0Tex(void *inTextureData, int inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) +{ + NVRenderTextureFormats::Enum theFormat = inFormat; + int theWidth = m_Width; + + // Since we cannot use RGB format in GL compute + // we treat it as a RGBA component format + if (inFormat == NVRenderTextureFormats::RGB8) { + // This works only with 4 byte aligned data + QT3DS_ASSERT(m_Width % 4 == 0); + theFormat = NVRenderTextureFormats::RGBA8; + theWidth = (m_Width * 3) / 4; + } + + if (m_Level0Tex == NULL) { + m_Level0Tex = m_NVRenderContext->CreateTexture2D(); + m_Level0Tex->SetTextureStorage(1, theWidth, m_Height, theFormat, theFormat, + NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); + } else { + m_Level0Tex->SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, + 0, 0, theWidth, m_Height, theFormat); + } +} + +void GLComputeMipMap::Build(void *inTextureData, int inTextureDataSize, + NVRenderBackend::NVRenderBackendTextureObject, + NVRenderTextureFormats::Enum inFormat) +{ + bool needMipUpload = (inFormat != m_DestinationFormat); + // re-upload data + if (!m_TextureCreated) { + m_Texture2D.SetTextureStorage( + m_MaxMipMapLevel + 1, m_Width, m_Height, m_DestinationFormat, inFormat, (needMipUpload) + ? NVDataRef() + : NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); + m_Texture2D.addRef(); + // create a compute shader (if not aloread done) which computes the BSDF mipmaps for this + // texture + createComputeProgram(m_NVRenderContext); + + if (!m_BSDFProgram) { + QT3DS_ASSERT(false); + return; + } + + m_TextureCreated = true; + } else if (!needMipUpload) { + m_Texture2D.SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, + 0, 0, m_Width, m_Height, inFormat); + } + + if (needMipUpload) { + CreateLevel0Tex(inTextureData, inTextureDataSize, inFormat); + } + + NVScopedRefCounted theInputImage; + NVScopedRefCounted theOutputImage; + theInputImage = + m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); + theOutputImage = + m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); + + if (needMipUpload && m_Level0Tex) { + NVRenderShaderProgram *uploadProg = + getOrCreateUploadComputeProgram(m_NVRenderContext, inFormat); + if (!uploadProg) + return; + + m_NVRenderContext->SetActiveShader(uploadProg); + + NVScopedRefCounted theInputImage0; + theInputImage0 = + m_NVRenderContext->CreateImage2D(m_Level0Tex, NVRenderImageAccessType::ReadWrite); + + theInputImage0->SetTextureLevel(0); + NVRenderCachedShaderProperty theCachedinputImage0("inputImage", + *uploadProg); + theCachedinputImage0.Set(theInputImage0); + + theOutputImage->SetTextureLevel(0); + NVRenderCachedShaderProperty theCachedOutputImage("outputImage", + *uploadProg); + theCachedOutputImage.Set(theOutputImage); + + m_NVRenderContext->DispatchCompute(uploadProg, m_Width, m_Height, 1); + + // sync + NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); + m_NVRenderContext->SetMemoryBarrier(flags); + } + + int width = m_Width >> 1; + int height = m_Height >> 1; + + m_NVRenderContext->SetActiveShader(m_BSDFProgram); + + for (int i = 1; i <= m_MaxMipMapLevel; ++i) { + theOutputImage->SetTextureLevel(i); + NVRenderCachedShaderProperty theCachedOutputImage("outputImage", + *m_BSDFProgram); + theCachedOutputImage.Set(theOutputImage); + theInputImage->SetTextureLevel(i - 1); + NVRenderCachedShaderProperty theCachedinputImage("inputImage", + *m_BSDFProgram); + theCachedinputImage.Set(theInputImage); + + m_NVRenderContext->DispatchCompute(m_BSDFProgram, width, height, 1); + + width = width > 2 ? width >> 1 : 1; + height = height > 2 ? height >> 1 : 1; + + // sync + NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); + m_NVRenderContext->SetMemoryBarrier(flags); + } +} diff --git a/src/Runtime/Source/hdr/HDR.cpp b/src/Runtime/Source/hdr/HDR.cpp new file mode 100644 index 00000000..9abe2b3b --- /dev/null +++ b/src/Runtime/Source/hdr/HDR.cpp @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "HDR.h" diff --git a/src/Runtime/Source/hdr/HDR.h b/src/Runtime/Source/hdr/HDR.h new file mode 100644 index 00000000..fbc4ea41 --- /dev/null +++ b/src/Runtime/Source/hdr/HDR.h @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef HDR_H +#define HDR_H + +#include "foundation/Qt3DSVec3.h" +//#include "HDR.h" + +namespace qt3ds { +class QT3DSVec3; + +namespace HDR { + + template + class HDRConfiguration; + + template + class Histogram + { + public: + /** + * @brief build the histogram based on 2^10 binning. + * + * @param[in] inImage Pointer to image + * @param[in] inWidth Width of image + * @param[in] inHeight Height of image + * @param[out] outHistogram + * + * @return No return + */ + static void Build(QT3DSVec3 *inImage, int inWidth, int inHeight, QT3DSVec3 *outHistogram) + { + long noPixels = inWidth * inHeight; + + for (int i = 0; i < noPixels; ++i) { + outHistogram[(int)inImage[i].x].x++; + outHistogram[(int)inImage[i].y].y++; + outHistogram[(int)inImage[i].z].z++; + } + } + }; + + template + class HDR + { + + public: + HDR(HDRConfiguration *inConfiguration) { mHDRConfiguration = inConfiguration; } + + void Build(QT3DSVec3 **inImages, int inNoImages, int inWidth, int inHeight, float *inExposures, + QT3DSVec3 *outRadiance) + { + for (int x = 0; x < inWidth; ++x) { + for (int y = 0; y < inHeight; ++y) { + QT3DSVec3 divisor(0.0f); + QT3DSVec3 dividend(0.0f); + for (int i = 0; i < inNoImages; ++i) { + QT3DSVec3 pixel = inImages[i][x + y * inWidth]; + + dividend += (LUT(mHDRConfiguration->weights, pixel) * inExposures[i]) + .multiply(LUT(mHDRConfiguration->CRF, pixel)); + divisor += LUT(mHDRConfiguration->weights, pixel) * inExposures[i] + * inExposures[i]; + } + divisor.x = 1.0f / divisor.x; + divisor.y = 1.0f / divisor.y; + divisor.z = 1.0f / divisor.z; + + outRadiance[x + y * inWidth] = dividend.multiply(divisor); + } + } + } + + private: + /** + * @brief Return the value based off from array as a LUT + * + * @param[in] inLUT The LUT table of interest + * @param[in] inValue The value that you have + * @param[out] QT3DSVec3 The corresponding value of array based on input + * tuple + * + * @return No return + */ + QT3DSVec3 LUT(float *inLUT, QT3DSVec3 inValue) + { + return QT3DSVec3(inLUT[(int)inValue.x], inLUT[(int)inValue.y], inLUT[(int)inValue.z]); + } + + QT3DSVec3 LUT(QT3DSVec3 *inLUT, QT3DSVec3 inValue) + { + return QT3DSVec3(inLUT[(int)inValue.x].x, inLUT[(int)inValue.y].y, + inLUT[(int)inValue.z].z); + } + + HDRConfiguration *mHDRConfiguration; + }; + + template + class HDRConfiguration + { + public: + HDRConfiguration() + { + threshold = 0.1f; + maxIterations = 30; + GenerateRobertsonWeighting(); + } + + void SetCRF(QT3DSVec3 *inCRF) { memcpy(CRF, inCRF, sizeof(QT3DSVec3) * N); } + + /** + * @brief build the camera response function + * + * @param[in] inImages Pointer to images + * @param[in] inNoImages Number of images + * @param[in] inWidth Width of image + * @param[in] inHeight Height of image + * @param[out] outHistogram + * + * @return No return + */ + void BuildCRF(QT3DSVec3 **inImages, int inNoImages, int inWidth, int inHeight, + float *inExposures) + { + QT3DSVec3 histogram[N]; + QT3DSVec3 newCRF[N]; + + HDR hdr(this); + + memset(histogram, 0, sizeof(QT3DSVec3) * N); + + for (int i = 0; i < inNoImages; ++i) { + Histogram::Build(inImages[i], inWidth, inHeight, histogram); + } + + for (int i = 0; i < N; ++i) { + histogram[i].x = histogram[i].x > 0 ? 1 / histogram[i].x : 0; + histogram[i].y = histogram[i].y > 0 ? 1 / histogram[i].y : 0; + histogram[i].z = histogram[i].z > 0 ? 1 / histogram[i].z : 0; + } + + QT3DSVec3 *radiance = new QT3DSVec3[inWidth * inHeight * sizeof(QT3DSVec3)]; + + // iteration 0, linearize CRF + for (int i = 0; i < N; ++i) { + CRF[i] = QT3DSVec3((float)i) * 2.0f / N; + } + + for (int iteration = 0; iteration < maxIterations; ++iteration) { + hdr.Build(inImages, inNoImages, inWidth, inHeight, inExposures, radiance); + + memset(newCRF, 0, sizeof(QT3DSVec3) * N); + + for (int i = 0; i < inNoImages; ++i) { + for (int x = 0; x < inWidth; ++x) { + for (int y = 0; y < inHeight; ++y) { + long offset = x + y * inWidth; + QT3DSVec3 pixel = inImages[i][offset]; + newCRF[(int)pixel.x].x += (inExposures[i] * radiance[offset].x); + newCRF[(int)pixel.y].y += (inExposures[i] * radiance[offset].y); + newCRF[(int)pixel.z].z += (inExposures[i] * radiance[offset].z); + } + } + } + + float difference = 0; + for (int i = 0; i < N; ++i) { + newCRF[i] = newCRF[i].multiply(histogram[i]); + } + + QT3DSVec3 middle = newCRF[N / 2]; + for (int i = 0; i < N; ++i) { + newCRF[i].x = newCRF[i].x / middle.x; + newCRF[i].y = newCRF[i].y / middle.y; + newCRF[i].z = newCRF[i].z / middle.z; + difference += (CRF[i] - newCRF[i]).magnitude(); + } + for (int i = 0; i < N; ++i) { + CRF[i] = newCRF[i]; + } + if (difference < threshold) { + break; + } + } + delete[] radiance; + } + + float weights[N]; + QT3DSVec3 CRF[N]; + + private: + void GenerateRobertsonWeighting() + { + // Dynamic Range Improvement Through Multiple Exposures (5) + // gaussian random weighting + float divisor = (N - 1) * (N - 1) / 4.0; + for (int i = 0; i < N; ++i) { + float dividend = (i - (N - 1) / 2.0f); + dividend *= dividend; + weights[i] = exp(-4.0f * dividend / divisor); + } + } + + int maxIterations; + float threshold; + }; +} +} +#endif diff --git a/src/Runtime/Source/hdr/MipmapBSDF.cpp b/src/Runtime/Source/hdr/MipmapBSDF.cpp new file mode 100644 index 00000000..fd57015e --- /dev/null +++ b/src/Runtime/Source/hdr/MipmapBSDF.cpp @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "MipmapBSDF.h" +#include "GLComputeMipMap.h" + +#ifdef PLATFORM_HAS_CUDA +#include "cuda.h" +#include "cuda_runtime.h" +#include "CUDABSDFMipmap.h" +#endif + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/Qt3DSRefCounted.h" +#include "nv_log.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace qt3ds::foundation; + +BSDFMipMap::BSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture2D, NVRenderTextureFormats::Enum inDestFormat, + NVFoundationBase &inFnd) + : m_Foundation(inFnd) + , m_Texture2D(inTexture2D) + , m_Width(inWidth) + , m_Height(inHeight) + , m_DestinationFormat(inDestFormat) + , m_NVRenderContext(inNVRenderContext) +{ + // Calculate mip level + int maxDim = inWidth >= inHeight ? inWidth : inHeight; + + m_MaxMipMapLevel = static_cast(logf((float)maxDim) / logf(2.0f)); + // no concept of sizeOfFormat just does'nt make sense + m_SizeOfFormat = NVRenderTextureFormats::getSizeofFormat(m_DestinationFormat); + m_NoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_DestinationFormat); +} + +BSDFMipMap *BSDFMipMap::Create(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd) +{ + BSDFMipMap *theBSDFMipMap = NULL; +#ifdef PLATFORM_HAS_CUDA + int deviceCount; + cudaError_t e = cudaGetDeviceCount(&deviceCount); +#endif + + if (inNVRenderContext->IsComputeSupported()) { + theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), GLComputeMipMap)( + inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); + } else +#ifdef PLATFORM_HAS_CUDA + if (e == cudaSuccess && deviceCount > 0) { + theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), CUDABSDFMipMap)( + inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); + } else +#endif + if (!theBSDFMipMap) { + theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), BasicBSDFMipMap)( + inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); + } + + return theBSDFMipMap; +} + +BasicBSDFMipMap::BasicBSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) + : BSDFMipMap(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd) +{ +} + +BSDFMipMap::~BSDFMipMap() +{ +} + +void BasicBSDFMipMap::Build(void *inTextureData, int inTextureDataSize, + NVRenderBackend::NVRenderBackendTextureObject, + NVRenderTextureFormats::Enum inFormat) +{ + + m_InternalFormat = inFormat; + m_SizeOfInternalFormat = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); + m_InternalNoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_InternalFormat); + + m_Texture2D.SetTextureData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, + m_Width, m_Height, inFormat, m_DestinationFormat); + + STextureData theMipImage; + STextureData prevImage; + prevImage.data = inTextureData; + prevImage.dataSizeInBytes = inTextureDataSize; + prevImage.format = inFormat; + int curWidth = m_Width; + int curHeight = m_Height; + int size = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); + for (int idx = 1; idx <= m_MaxMipMapLevel; ++idx) { + theMipImage = + CreateBsdfMipLevel(theMipImage, prevImage, curWidth, curHeight); //, m_PerfTimer ); + curWidth = curWidth >> 1; + curHeight = curHeight >> 1; + curWidth = curWidth >= 1 ? curWidth : 1; + curHeight = curHeight >= 1 ? curHeight : 1; + inTextureDataSize = curWidth * curHeight * size; + + m_Texture2D.SetTextureData(toU8DataRef((char *)theMipImage.data, (QT3DSU32)inTextureDataSize), + (QT3DSU8)idx, (QT3DSU32)curWidth, (QT3DSU32)curHeight, theMipImage.format, + m_DestinationFormat); + + if (prevImage.data == inTextureData) + prevImage = STextureData(); + + STextureData temp = prevImage; + prevImage = theMipImage; + theMipImage = temp; + } + QT3DS_FREE(m_Foundation.getAllocator(), theMipImage.data); + QT3DS_FREE(m_Foundation.getAllocator(), prevImage.data); +} + +inline int BasicBSDFMipMap::wrapMod(int a, int base) +{ + return (a >= 0) ? a % base : (a % base) + base; +} + +inline void BasicBSDFMipMap::getWrappedCoords(int &sX, int &sY, int width, int height) +{ + if (sY < 0) { + sX -= width >> 1; + sY = -sY; + } + if (sY >= height) { + sX += width >> 1; + sY = height - sY; + } + sX = wrapMod(sX, width); +} + +STextureData BasicBSDFMipMap::CreateBsdfMipLevel(STextureData &inCurMipLevel, + STextureData &inPrevMipLevel, int width, + int height) //, IPerfTimer& inPerfTimer ) +{ + // SStackPerfTimer __timer( inPerfTimer, "Image BSDF Mip Level" ); + STextureData retval; + int newWidth = width >> 1; + int newHeight = height >> 1; + newWidth = newWidth >= 1 ? newWidth : 1; + newHeight = newHeight >= 1 ? newHeight : 1; + + if (inCurMipLevel.data) { + retval = inCurMipLevel; + retval.dataSizeInBytes = + newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); + } else { + retval.dataSizeInBytes = + newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); + retval.format = inPrevMipLevel.format; // inLoadedImage.format; + retval.data = m_Foundation.getAllocator().allocate( + retval.dataSizeInBytes, "Bsdf Scaled Image Data", __FILE__, __LINE__); + } + + for (int y = 0; y < newHeight; ++y) { + for (int x = 0; x < newWidth; ++x) { + float accumVal[4]; + accumVal[0] = 0; + accumVal[1] = 0; + accumVal[2] = 0; + accumVal[3] = 0; + for (int sy = -2; sy <= 2; ++sy) { + for (int sx = -2; sx <= 2; ++sx) { + int sampleX = sx + (x << 1); + int sampleY = sy + (y << 1); + getWrappedCoords(sampleX, sampleY, width, height); + + // Cauchy filter (this is simply because it's the easiest to evaluate, and + // requires no complex + // functions). + float filterPdf = 1.f / (1.f + float(sx * sx + sy * sy) * 2.f); + // With FP HDR formats, we're not worried about intensity loss so much as + // unnecessary energy gain, + // whereas with LDR formats, the fear with a continuous normalization factor is + // that we'd lose + // intensity and saturation as well. + filterPdf /= (NVRenderTextureFormats::getSizeofFormat(retval.format) >= 8) + ? 4.71238898f + : 4.5403446f; + // filterPdf /= 4.5403446f; // Discrete normalization factor + // filterPdf /= 4.71238898f; // Continuous normalization factor + float curPix[4]; + QT3DSI32 byteOffset = (sampleY * width + sampleX) + * NVRenderTextureFormats::getSizeofFormat(retval.format); + if (byteOffset < 0) { + sampleY = height + sampleY; + byteOffset = (sampleY * width + sampleX) + * NVRenderTextureFormats::getSizeofFormat(retval.format); + } + + NVRenderTextureFormats::decodeToFloat(inPrevMipLevel.data, byteOffset, curPix, + retval.format); + + accumVal[0] += filterPdf * curPix[0]; + accumVal[1] += filterPdf * curPix[1]; + accumVal[2] += filterPdf * curPix[2]; + accumVal[3] += filterPdf * curPix[3]; + } + } + + /* + // Re-adjustment after the fact for the RGBD hack. + if (retval.format == NVRenderTextureFormats::RGBA8 || retval.format == + NVRenderTextureFormats::SRGB8A8) + { + float divVal = (accumVal[0] > accumVal[1]) ? accumVal[0] : accumVal[1]; + divVal = (divVal > accumVal[2]) ? divVal : accumVal[2]; + if (divVal > 1.0) + { + divVal = 1.0f / divVal; + accumVal[0] *= divVal; + accumVal[1] *= divVal; + accumVal[2] *= divVal; + accumVal[3] = divVal; + } + else + accumVal[3] = 1.0f; + } + */ + QT3DSU32 newIdx = + (y * newWidth + x) * NVRenderTextureFormats::getSizeofFormat(retval.format); + + NVRenderTextureFormats::encodeToPixel(accumVal, retval.data, newIdx, retval.format); + } + } + + return retval; +} diff --git a/src/Runtime/Source/hdr/MipmapBSDF.cu b/src/Runtime/Source/hdr/MipmapBSDF.cu new file mode 100644 index 00000000..6ddac4be --- /dev/null +++ b/src/Runtime/Source/hdr/MipmapBSDF.cu @@ -0,0 +1,404 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#if defined (_PLATFORM_USE_EGL) +#include +#include +#endif + +#include "CUDABSDFMipmap.h" +#include "cuda.h" +#include "cuda_runtime.h" +#include "cuda_gl_interop.h" +#include + +using namespace nv; +using namespace nv::render; +__host__ void jerror1(cudaError error) +{ + static int i = 0; + ++i; +} +#ifdef _DEBUG +#define CHECK_AND_HANDLE_CUDA_ERROR(func) \ + func; \ + { \ + cudaError error = cudaGetLastError(); \ + if ( error != cudaSuccess ) \ + { \ + printf("%s\n", cudaGetErrorString(error)); \ + jerror1(error);\ + NV_ASSERT( false ); \ + } \ + } +#else +#define CHECK_AND_HANDLE_CUDA_ERROR(func) \ +func; +#endif + +__device__ inline int wrapMod( int a, int base ) +{ + int ret = a % base; + if (ret < 0 ) ret += base; + return ret; +} + +__device__ inline void getWrappedCoords( int &sX, int &sY, int width, int height ) +{ + if (sY < 0) { sX -= width >> 1; sY = -sY; } + if (sY >= height) { sX += width >> 1; sY = height - sY; } + sX = wrapMod( sX, width ); + sY = wrapMod( sY, height ); +} + +__device__ void decodeToFloat( void *inPtr, NVU32 byteOfs, float *outPtr, NVRenderTextureFormats::Enum inFmt, unsigned int numberOfComponent ) +{ + outPtr[0] = 0.0f; outPtr[1] = 0.0f; outPtr[2] = 0.0f; outPtr[3] = 0.0f; + NVU8 *src = reinterpret_cast(inPtr); + //float divisor; // If we want to support RGBD? + switch(inFmt) + { + case NVRenderTextureFormats::Alpha8: + outPtr[0] = ((float)src[byteOfs]) / 255.0f; + break; + + case NVRenderTextureFormats::Luminance8: + case NVRenderTextureFormats::LuminanceAlpha8: + case NVRenderTextureFormats::R8: + case NVRenderTextureFormats::RG8: + case NVRenderTextureFormats::RGB8: + case NVRenderTextureFormats::RGBA8: + case NVRenderTextureFormats::SRGB8: + case NVRenderTextureFormats::SRGB8A8: + // NOTE : RGBD Hack here for reference. Not meant for installation. + //divisor = (NVRenderTextureFormats::getSizeofFormat(inFmt) == 4) ? ((float)src[byteOfs+3]) / 255.0f : 1.0f; + for ( NVU32 i = 0; i < numberOfComponent; ++i ) + { + float val = ((float)src[byteOfs + i]) / 255.0f; + outPtr[i] = (i < 3) ? powf(val, 0.4545454545f) : val; + // Assuming RGBA8 actually means RGBD (which is stupid, I know) + //if ( NVRenderTextureFormats::getSizeofFormat(inFmt) == 4 ) { outPtr[i] /= divisor; } + } + //outPtr[3] = divisor; + break; + + case NVRenderTextureFormats::RGBA32F: + outPtr[0] = reinterpret_cast(src+byteOfs)[0]; + outPtr[1] = reinterpret_cast(src+byteOfs)[1]; + outPtr[2] = reinterpret_cast(src+byteOfs)[2]; + outPtr[3] = reinterpret_cast(src+byteOfs)[3]; + break; + case NVRenderTextureFormats::RGB32F: + outPtr[0] = reinterpret_cast(src+byteOfs)[0]; + outPtr[1] = reinterpret_cast(src+byteOfs)[1]; + outPtr[2] = reinterpret_cast(src+byteOfs)[2]; + break; + + case NVRenderTextureFormats::RGBA16F: + /* + for ( NVU32 i = 0; i < 4; ++i ) + { + // NOTE : This only works on the assumption that we don't have any denormals, Infs or NaNs. + // Every pixel in our source image should be "regular" + NVU16 h = reinterpret_cast(src + byteOfs)[i]; + NVU32 sign = (h & 0x8000) << 16; + NVU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); + NVU32 mantissa = ((h & 0x3ff) << 13); + NVU32 result = sign | exponent | mantissa; + + if (h == 0 || h == 0x8000) { result = 0; } // Special case for zero and negative zero + memcpy( reinterpret_cast(outPtr) + i, &result, 4 ); + }*/ + + for ( NVU32 i = 0; i < 2; i++ ) + { + // NOTE : This only works on the assumption that we don't have any denormals, Infs or NaNs. + // Every pixel in our source image should be "regular" + + NVU32 h1 = reinterpret_cast(src + byteOfs)[i]; + + for ( NVU8 j = 0; j < 2; j++ ) + { + NVU16 h = (h1 & (0x0000FFFF << j*16 )) >> j*16; + NVU32 sign = (h & 0x8000) << 16; + NVU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); + NVU32 mantissa = ((h & 0x3ff) << 13); + NVU32 result = sign | exponent | mantissa; + + if (h == 0 || h == 0x8000) { result = 0; } // Special case for zero and negative zero + memcpy( reinterpret_cast(outPtr) + i*2 + j, &result, 4 ); + } + } + break; + + case NVRenderTextureFormats::R11G11B10: + // place holder + NV_ASSERT( false ); + break; + + default: + outPtr[0] = 0.0f; + outPtr[1] = 0.0f; + outPtr[2] = 0.0f; + outPtr[3] = 0.0f; + break; + } +} + +void __device__ encodeToPixel( float *inPtr, void *outPtr, NVU32 byteOfs, NVRenderTextureFormats::Enum inFmt, unsigned int noOfComponent ) +{ + NVU8 *dest = reinterpret_cast(outPtr); + switch(inFmt) + { + case NVRenderTextureFormats::Alpha8: + dest[byteOfs] = NVU8( inPtr[0] * 255.0f ); + break; + + case NVRenderTextureFormats::Luminance8: + case NVRenderTextureFormats::LuminanceAlpha8: + case NVRenderTextureFormats::R8: + case NVRenderTextureFormats::RG8: + case NVRenderTextureFormats::RGB8: + case NVRenderTextureFormats::RGBA8: + case NVRenderTextureFormats::SRGB8: + case NVRenderTextureFormats::SRGB8A8: + for ( NVU32 i = 0; i < noOfComponent; ++i ) + { + inPtr[i] = (inPtr[i] > 1.0f) ? 1.0f : inPtr[i]; + if (i < 3) + dest[byteOfs+i] = NVU8( powf( inPtr[i], 2.2f ) * 255.0f); + else + dest[byteOfs+i] = NVU8( inPtr[i] * 255.0f ); + } + break; + + case NVRenderTextureFormats::RGBA32F: + reinterpret_cast(dest+byteOfs)[0] = inPtr[0]; + reinterpret_cast(dest+byteOfs)[1] = inPtr[1]; + reinterpret_cast(dest+byteOfs)[2] = inPtr[2]; + reinterpret_cast(dest+byteOfs)[3] = inPtr[3]; + break; + case NVRenderTextureFormats::RGB32F: + reinterpret_cast(dest+byteOfs)[0] = inPtr[0]; + reinterpret_cast(dest+byteOfs)[1] = inPtr[1]; + reinterpret_cast(dest+byteOfs)[2] = inPtr[2]; + break; + + case NVRenderTextureFormats::RGBA16F: + for ( NVU32 i = 0; i < 4; ++i ) + { + // NOTE : This also has the limitation of not handling infs, NaNs and denormals, but it should be + // sufficient for our purposes. + if (inPtr[i] > 65519.0f) { inPtr[i] = 65519.0f; } + if (fabs(inPtr[i]) < 6.10352E-5f) { inPtr[i] = 0.0f; } + NVU32 f = reinterpret_cast(inPtr)[i]; + NVU32 sign = (f & 0x80000000) >> 16; + NVI32 exponent = (f & 0x7f800000) >> 23; + NVU32 mantissa = (f >> 13) & 0x3ff; + exponent = exponent - 112; + if (exponent > 31) { exponent = 31; } + if (exponent < 0) { exponent = 0; } + exponent = exponent << 10; + reinterpret_cast(dest + byteOfs)[i] = NVU16(sign | exponent | mantissa); + } + break; + + case NVRenderTextureFormats::R11G11B10: + // place holder + NV_ASSERT( false ); + break; + + default: + dest[byteOfs] = 0; + dest[byteOfs+1] = 0; + dest[byteOfs+2] = 0; + dest[byteOfs+3] = 0; + break; + } +} + +void __global__ Convert3To4Component( cudaTextureObject_t tex, float *d_outBuffer, Q3DStudio::INT32 dpitch, Q3DStudio::INT32 width, Q3DStudio::INT32 height ) +{ + float *dest = d_outBuffer; + + int x = threadIdx.x + blockIdx.x * blockDim.x; + int y = threadIdx.y + blockIdx.y * blockDim.y; + if ( x >= width || y >= height ) + return; + int inX = x * 3; + int outX = x * 4; + dest[outX + y * width * 4] = tex2D(tex, inX, y); + dest[outX + y * width * 4 + 1] = tex2D(tex, inX + 1, y); + dest[outX + y * width * 4 + 2] = tex2D(tex, inX + 2, y); + dest[outX + y * width * 4 + 3] = 255 * 255; +} + +void __global__ ConvertData( void* d_InBuffer, NVRenderTextureFormats::Enum inFmt, int inSizeOfFormat, int inNoOfComponent, int inPitch, + void* d_OutBuffer, NVRenderTextureFormats::Enum outFmt, int outSizeOfFormat, int outNoOfComponent, int outPitch, int width, int height ) +{ + + int x = threadIdx.x + blockIdx.x * blockDim.x; + int y = threadIdx.y + blockIdx.y * blockDim.y; + if ( x >= width || y >= height ) + return; + float values[4]; + + decodeToFloat( d_InBuffer, (inPitch * y) + (x * inSizeOfFormat), values, inFmt, inNoOfComponent ); + encodeToPixel( values, d_OutBuffer, (outPitch * y) + (x * outSizeOfFormat), outFmt, outSizeOfFormat ); +} + +void __global__ CreateBsdfMipLevel( cudaTextureObject_t tex, void *d_curBuffer, void *d_prevBuffer, Q3DStudio::INT32 pitch, Q3DStudio::INT32 width, Q3DStudio::INT32 height, + nv::render::NVRenderTextureFormats::Enum inFormat, unsigned int sizeOfFormat ) +{ + float accumVal[4]; + //unsigned int sizeofFormat = getSizeofFormat(inFormat); + //__shared__ float dataBlock[ ]; //(32+4) * (32+4) * 12 + int x = threadIdx.x + blockIdx.x * blockDim.x; + int y = threadIdx.y + blockIdx.y * blockDim.y; + + if ( x >= (width > 2 ? width >> 1 : 1) || y >= (height > 2 ? height >> 1 : 1)) return; + + accumVal[0] = 0; accumVal[1] = 0; accumVal[2] = 0; accumVal[3] = 0; + + for ( int sy = -2; sy <= 2; ++sy ) + { + for ( int sx = -2; sx <= 2; ++sx ) + { + int sampleX = sx + (x << 1); + int sampleY = sy + (y << 1); + //getWrappedCoords(sampleX, sampleY, width, height); + // Cauchy filter (this is simply because it's the easiest to evaluate, and requires no complex + // functions). + float filterPdf = 1.f / ( 1.f + float(sx*sx + sy*sy)*2.f ); + // With FP HDR formats, we're not worried about intensity loss so much as unnecessary energy gain, + // whereas with LDR formats, the fear with a continuous normalization factor is that we'd lose + // intensity and saturation as well. + filterPdf /= sizeOfFormat >= 8 ? 4.71238898f : 4.5403446f; + //filterPdf /= 4.5403446f; // Discrete normalization factor + //filterPdf /= 4.71238898f; // Continuous normalization factor + //float curPix[4]; + sampleX = sampleX*4; + getWrappedCoords(sampleX, sampleY, width*4, height); + accumVal[0] += filterPdf * tex2D(tex, sampleX, sampleY); + accumVal[1] += filterPdf * tex2D(tex, sampleX + 1, sampleY); + accumVal[2] += filterPdf * tex2D(tex, sampleX + 2, sampleY); + accumVal[3] += filterPdf * tex2D(tex, sampleX + 3, sampleY); + } + } + + encodeToPixel(accumVal, d_curBuffer, y * pitch + x * sizeOfFormat, inFormat, sizeOfFormat); +} + +struct SMipTextureData +{ + void* data; + unsigned int dataSize; + unsigned int mipLevel; + unsigned int width; + unsigned int height; + NVRenderTextureFormats::Enum format; +}; + +__host__ void CUDABSDFMipMap::Build( void* inTextureData, int inTextureDataSize, NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, NVRenderTextureFormats::Enum inFormat ) +{ + m_TextureHandle = inTextureHandle; + m_InternalFormat = inFormat; + m_SizeOfInternalFormat = NVRenderTextureFormats::getSizeofFormat( m_InternalFormat ); + m_InternalNoOfComponent = NVRenderTextureFormats::getNumberOfComponent( m_InternalFormat ); + + m_Texture2D.SetTextureData( NVDataRef( (NVU8*)inTextureData, inTextureDataSize ) + , 0 + , m_Width + , m_Height + , inFormat + , m_DestinationFormat ); + + size_t pitch; + float* d_inTextureData; + + cudaMallocPitch(&d_inTextureData, &pitch, m_Width * m_SizeOfInternalFormat, m_Height); CHECK_AND_HANDLE_CUDA_ERROR(); + CHECK_AND_HANDLE_CUDA_ERROR( cudaMemcpy2D( d_inTextureData, pitch, inTextureData, m_Width * m_SizeOfInternalFormat, m_Width * m_SizeOfInternalFormat, m_Height, cudaMemcpyHostToDevice ) ); + { + dim3 blockDim(16, 16, 1); + dim3 gridDim(ceil(m_Width / 16.0f), ceil(m_Height / 16.0f) ,1 ); + + //std::cerr << "if= " << m_InternalFormat << " sizeOut= " << m_SizeOfInternalFormat << " numOfIntComp" << m_InternalNoOfComponent << " pitch= " << pitch << " destFormat= " << m_DestinationFormat << " sizeFormat= " << m_SizeOfFormat << " numOfComp= " << m_NoOfComponent << " Pitch0=" << m_Pitches[0] << std::endl; + //NVLogWarn("cuda", "%i %i %i %i %i %i %i %i\n",(int)m_InternalFormat ,m_SizeOfInternalFormat ,m_InternalNoOfComponent , pitch, (int)m_DestinationFormat, m_SizeOfFormat, m_NoOfComponent ,m_Pitches[0]); + ConvertData<<>>( d_inTextureData, m_InternalFormat, m_SizeOfInternalFormat, m_InternalNoOfComponent, pitch, + md_MipMapsData[0], m_DestinationFormat, m_SizeOfFormat, m_NoOfComponent, m_Pitches[0], m_Width, m_Height ); + } + cudaFree(d_inTextureData); + + int curWidth = m_Width; + int curHeight = m_Height; + + cudaTextureObject_t* tex; + tex = new cudaTextureObject_t[m_MaxMipMapLevel]; + for ( int idx = 1; idx <= m_MaxMipMapLevel; ++idx ) + { + tex[idx-1] = -1; + dim3 blockDim(16, 16, 1); + dim3 gridDim(ceil(curWidth / 32.0f), ceil(curHeight / 32.0f) ,1 ); + + cudaResourceDesc resDesc; + memset(&resDesc, 0, sizeof(resDesc)); + resDesc.res.pitch2D.desc.f = cudaChannelFormatKindFloat; + resDesc.res.pitch2D.desc.x = m_SizeOfFormat / m_NoOfComponent * 8; // bits per channel + resDesc.resType = cudaResourceTypePitch2D; + resDesc.res.pitch2D.devPtr = (char*)(md_MipMapsData[idx-1]); + resDesc.res.pitch2D.height = curHeight; + resDesc.res.pitch2D.width = curWidth * m_NoOfComponent; + resDesc.res.pitch2D.pitchInBytes = m_Pitches[idx-1];// aligned to texturePitchAlignment + + cudaTextureDesc texDesc; + memset(&texDesc, 0, sizeof(texDesc)); + texDesc.addressMode[0] = cudaAddressModeWrap; + texDesc.addressMode[1] = cudaAddressModeWrap; + texDesc.readMode = cudaReadModeElementType; + //texDesc.normalizedCoords = 1; + + + CHECK_AND_HANDLE_CUDA_ERROR( cudaCreateTextureObject( &tex[idx-1], &resDesc, &texDesc, NULL ) ); + CreateBsdfMipLevel<<>>( tex[idx-1], (reinterpret_cast(md_MipMapsData[idx])), (reinterpret_cast(md_MipMapsData[idx-1])), m_Pitches[idx], curWidth, curHeight, m_DestinationFormat, m_SizeOfFormat ); + + curWidth = curWidth > 2 ? curWidth >> 1 : 1; + curHeight = curHeight > 2 ? curHeight >> 1 : 1; + } + + CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceSynchronize(); ) + BindTexture(); + TransferTexture(); + for (int idx = 0; idx < m_MaxMipMapLevel;++idx ) + cudaDestroyTextureObject(tex[idx]); +// CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceReset(); ) + CHECK_AND_HANDLE_CUDA_ERROR( cudaDeviceSynchronize(); ) + + //NV_FREE( m_Foundation.getAllocator(), inTextureData ); + +} diff --git a/src/Runtime/Source/hdr/MipmapBSDF.h b/src/Runtime/Source/hdr/MipmapBSDF.h new file mode 100644 index 00000000..be8f1366 --- /dev/null +++ b/src/Runtime/Source/hdr/MipmapBSDF.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MIPMAPBSDF_H +#define MIPMAPBSDF_H +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/backends/gl/Qt3DSOpenGLUtil.h" + +#include "Qt3DSRenderLoadedTexture.h" + +#include "Qt3DSTypes.h" +#ifdef _LINUXPLATFORM +#define __declspec(dllexport) +#define __cdecl + +#endif +using namespace qt3ds::render; + +class BSDFMipMap : public NVRefCounted +{ +public: + BSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + virtual ~BSDFMipMap(); + + virtual void Build(void *inTextureData, int inTextureDataSize, + NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, + NVRenderTextureFormats::Enum inFormat) = 0; + static BSDFMipMap *Create(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + +protected: + volatile QT3DSI32 mRefCount; ///< reference count + NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things + + NVRenderTexture2D &m_Texture2D; + NVRenderTextureFormats::Enum m_InternalFormat; + NVRenderTextureFormats::Enum m_DestinationFormat; + int m_Width; + int m_Height; + int m_MaxMipMapLevel; + int m_SizeOfFormat; + int m_SizeOfInternalFormat; + int m_InternalNoOfComponent; + int m_NoOfComponent; + NVRenderContext *m_NVRenderContext; +}; + +class BasicBSDFMipMap : public BSDFMipMap +{ +public: + BasicBSDFMipMap(NVRenderContext *inNVRenderContext, int inWidth, int inHeight, + NVRenderTexture2D &inTexture, NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + + void Build(void *inTextureData, int inTextureDataSize, + NVRenderBackend::NVRenderBackendTextureObject inTextureHandle, + NVRenderTextureFormats::Enum inFormat); + + STextureData CreateBsdfMipLevel(STextureData &inCurMipLevel, STextureData &inPrevMipLevel, + int width, int height); //, IPerfTimer& inPerfTimer ); + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation); + + int wrapMod(int a, int base); + void getWrappedCoords(int &sX, int &sY, int width, int height); + NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; +}; + +#endif diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/NvVec.h b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/NvVec.h new file mode 100644 index 00000000..4e5b09ce --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/NvVec.h @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H +#define INCLUDED_QT3DS_MATH_CPP_VEC_H + +#include "misc.h" + +struct _NvVec3 +{ + union { + struct + { + float x, y, z; + }; + float v[3]; + }; +}; + +struct NvVec3 : public _NvVec3 +{ + NvVec3() { zero(); } + + NvVec3(float x, float y, float z) + { + v[0] = x; + v[1] = y; + v[2] = z; + } + + NvVec3(NvVec3 const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + v[2] = that.v[2]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + v[2] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + NvVec3 &operator+=(NvVec3 const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + v[2] += that.v[2]; + return *this; + } + + NvVec3 &operator-=(NvVec3 const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + v[2] -= that.v[2]; + return *this; + } + + NvVec3 &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + v[2] *= s; + return *this; + } + + NvVec3 &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + v[2] /= s; + return *this; + } +}; + +inline float dot(NvVec3 const &a, NvVec3 const &b) +{ + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a) +{ + + return NvVec3(-a.v[0], -a.v[1], -a.v[2]); +} + +inline NvVec3 operator*(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); +} + +inline NvVec3 operator*(float s, NvVec3 const &a) +{ + + return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); +} + +inline NvVec3 operator/(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); +} + +inline float magnitude(NvVec3 const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec3 normalize(NvVec3 const &v) +{ + float l = magnitude(v); + return NvVec3(v[0] / l, v[1] / l, v[2] / l); +} + +inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], + a.v[0] * b.v[1] - a.v[1] * b.v[0]); +} + +inline bool operator==(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); +} + +inline bool operator!=(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); +} + +struct NvVec2f +{ + union { + struct + { + float x, y; + float v[2]; + }; + }; + + NvVec2f() { zero(); } + + NvVec2f(float x, float y) + { + v[0] = x; + v[1] = y; + } + + NvVec2f(NvVec2f const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + NvVec2f &operator+=(NvVec2f const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + return *this; + } + + NvVec2f &operator-=(NvVec2f const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + return *this; + } + + NvVec2f &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + return *this; + } + + NvVec2f &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + return *this; + } +}; + +inline float dot(NvVec2f const &a, NvVec2f const &b) +{ + + return a[0] * b[0] + a[1] * b[1]; +} + +inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a) +{ + + return NvVec2f(-a.v[0], -a.v[1]); +} + +inline NvVec2f operator*(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] * s, a.v[1] * s); +} + +inline NvVec2f operator*(float s, NvVec2f const &a) +{ + + return NvVec2f(s * a.v[0], s * a.v[1]); +} + +inline NvVec2f operator/(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] / s, a.v[1] / s); +} + +inline float magnitude(NvVec2f const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec2f normalize(NvVec2f const &v) +{ + float l = dot(v, v); + return NvVec2f(v[0] / l, v[1] / l); +} + +inline float cross(NvVec2f const &a, NvVec2f const &b) +{ + + return a.v[0] * b.v[1] - b.v[0] * a.v[1]; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/misc.h b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/misc.h new file mode 100644 index 00000000..983410f3 --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/misc.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H +#define INCLUDED_QT3DS_MATH_CPP_MISC_H + +inline bool nvIsPowerOfTwo(unsigned int i) +{ + return (i & (i - 1)) == 0; +} + +inline float nvDegToRadf(float d) +{ + return d * 3.14159265358979323846f / 180.0f; +} + +inline float nvRadToDegf(float r) +{ + return r * 180.0f / 3.14159265358979323846f; +} + +/* + 'mod' differs from '%' in that it behaves correctly when either the + numerator or denominator is negative. +*/ + +inline int nvMod(int n, int d) +{ + int m = n % d; + return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; +} + +inline int nvAbs(int n) +{ + if (n < 0) + return -n; + return n; +} + +inline int nvSign(int n) +{ + if (n > 0) + return 1; + if (n < 0) + return -1; + return 0; +} + +/* + This returns the smallest amplitude value x such that + nvMod(b + x, m) == a +*/ + +inline int nvDifMod(int a, int b, int m) +{ + + int x1 = a - b; + int x2 = (x1 > 0) ? x1 - m : x1 + m; + return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; +} + +inline float nvWrapf(float a, float min, float max) +{ + + assert(max > min); + + float d = max - min; + float s = a - min; + float q = s / d; + float m = q - floorf(q); + return m * d + min; +} + +inline float nvClampf(float a, float min, float max) +{ + return (a < min) ? min : ((a > max) ? max : a); +} + +inline int nvClampi(int i, int min, int max) +{ + return (i < min) ? min : ((i > max) ? max : i); +} + +inline float nvGaussian(float x, float s) +{ + float c = s * sqrtf(2.0f * 3.14159265358979323846f); + return expf(-(x * x) / (2.0f * s * s)) / c; +} + +inline float nvLerpf(float a, float b, float t) +{ + return a * (1.0f - t) + b * t; +} + +inline float nvEasef(float t) +{ + + float t_2 = t * t; + float t_3 = t_2 * t; + return 3.0f * t_2 - 2.0f * t_3; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.cpp b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.cpp new file mode 100644 index 00000000..b83cb39e --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_math.h" + +static const double a = 16807.0; +static const double m = 2147483647.0; + +static double nextSeed(double seed) +{ + double t = a * seed; + return t - m * (double)((int)(t / m)); +} + +GLfloat NvRandf() +{ + static double seed = 1.0; + seed = nextSeed(seed); + return (GLfloat)(seed * (1 / m)); +} + +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) +{ + // kdGetTimeUST is never supposed to decrease (i.e. that + // means it can't wrap, either. IIRC, it will wrap in + // 593 years). So we ignore that option... + + // Used for frame-to-frame diffs, this will fit in 32b + // as long as the times are < ~4.3s apart + long long int diffTime = newTime - oldTime; + + // Need to find a better way to do this. + // However, I believe we will be uSec precise (not run + // out of mantissa bits for uSecs) as long as the diff + // is < ~16s (1e-6 * (2^24)) + return ((GLfloat)diffTime) / 1.0e9f; +} diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.h b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.h new file mode 100644 index 00000000..cf2d8b30 --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_math.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_MATH_H +#define _QT3DS_MATH_H + +#include + +GLfloat NvRandf(); + +/* These are the recommended "safer" ways to use GLfloat for time */ + +/* Returns the seconds between the two given times */ +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); + +#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) + +#endif diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.cpp b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.cpp new file mode 100644 index 00000000..e208ac31 --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.cpp @@ -0,0 +1,1030 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_matrix.h" + +int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) +{ + return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); +} + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; +} + +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; +} + +GLfloat NvVecLengthf(const GLfloat v[3]) +{ + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) +{ + GLfloat const l = NvVecLengthf(v); + r[0] = v[0] / l; + r[1] = v[1] / l; + r[2] = v[2] / l; +} + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] + b[0]; + r[1] = a[1] + b[1]; + r[2] = a[2] + b[2]; +} + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] - b[0]; + r[1] = a[1] - b[1]; + r[2] = a[2] - b[2]; +} + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + GLfloat t[3]; + + t[0] = a[1] * b[2] - a[2] * b[1]; + t[1] = a[2] * b[0] - a[0] * b[2]; + t[2] = a[0] * b[1] - a[1] * b[0]; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; +} + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); + + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; +} + +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; + r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; +} + +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; +} + +static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; + r[3][3] = 1.0f; +} + +static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; + r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; + r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; + r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; + r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; +} + +void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) + && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { + if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) + && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { + NvMultMat3x3f(r, a, b); + } else { + NvMultMat4x3f(r, a, b); + } + } else { + NvMultMat4x4f(r, a, b); + } + + NvCopyMatf(result, r); +} + +static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + /* x */ + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + /* y */ + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + /* z */ + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = 1.0f; +} + +static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] + + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] + + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] + + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] + + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] + + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] + + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] + + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] + + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] + + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] + + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] + + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] + + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) + / d; + + r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] + + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] + + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) + / d; + + r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] + + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] + + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) + / d; + + r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] + + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] + + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) + / d; + + r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] + + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] + + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) + / d; + + r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] + + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] + + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) + / d; + + r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] + + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] + + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) + / d; + + r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] + + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] + + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) + / d; + + r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] + + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] + + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) + / d; + + r[2][1] = + (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] + + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) + / d; + + r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] + + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] + + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) + / d; + + r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] + + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] + + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) + / d; + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) + / d; +} + +void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { + if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { + NvInvMat3x3f(r, m); + } else { + NvInvMat4x3f(r, m); + } + } else { + NvInvMat4x4f(r, m); + } + + NvCopyMatf(result, r); +} + +void NvBuildIdentityMatf(GLfloat r[4][4]) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = x; + r[3][1] = y; + r[3][2] = z; + r[3][3] = 1.0f; +} + +void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, + GLfloat z) +{ + GLfloat r[4][4]; /*temporary storage for result */ + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; + r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; + r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; + r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = x; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = y; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = z; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * x; + r[0][1] = m[0][1] * x; + r[0][2] = m[0][2] * x; + r[0][3] = m[0][3] * x; + + r[1][0] = m[1][0] * y; + r[1][1] = m[1][1] * y; + r[1][2] = m[1][2] * y; + r[1][3] = m[1][3] * y; + + r[2][0] = m[2][0] * z; + r[2][1] = m[2][1] * z; + r[2][2] = m[2][2] * z; + r[2][3] = m[2][3] * z; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) +{ + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = c; + r[1][2] = s; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = -s; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = 0.0f; + r[0][2] = -s; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = s; + r[2][1] = 0.0f; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = s; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = -s; + r[1][1] = c; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0] * c + m[2][0] * s; + r[1][1] = m[1][1] * c + m[2][1] * s; + r[1][2] = m[1][2] * c + m[2][2] * s; + r[1][3] = m[1][3] * c + m[2][3] * s; + + r[2][0] = m[1][0] * -s + m[2][0] * c; + r[2][1] = m[1][1] * -s + m[2][1] * c; + r[2][2] = m[1][2] * -s + m[2][2] * c; + r[2][3] = m[1][3] * -s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[2][0] * -s; + r[0][1] = m[0][1] * c + m[2][1] * -s; + r[0][2] = m[0][2] * c + m[2][2] * -s; + r[0][3] = m[0][3] * c + m[2][3] * -s; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[0][0] * s + m[2][0] * c; + r[2][1] = m[0][1] * s + m[2][1] * c; + r[2][2] = m[0][2] * s + m[2][2] * c; + r[2][3] = m[0][3] * s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[1][0] * s; + r[0][1] = m[0][1] * c + m[1][1] * s; + r[0][2] = m[0][2] * c + m[1][2] * s; + r[0][3] = m[0][3] * c + m[1][3] * s; + + r[1][0] = m[0][0] * -s + m[1][0] * c; + r[1][1] = m[0][1] * -s + m[1][1] * c; + r[1][2] = m[0][2] * -s + m[1][2] * c; + r[1][3] = m[0][3] * -s + m[1][3] * c; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) +{ + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + /* build a matrix from the quat */ + + result[0][0] = 1.0f - 2.0f * (j * j + k * k); + result[0][1] = 2.0f * (i * j + r * k); + result[0][2] = 2.0f * (i * k - r * j); + result[0][3] = 0.0f; + + result[1][0] = 2.0f * (i * j - r * k); + result[1][1] = 1.0f - 2.0f * (i * i + k * k); + result[1][2] = 2.0f * (j * k + r * i); + result[1][3] = 0.0f; + + result[2][0] = 2.0f * (i * k + r * j); + result[2][1] = 2.0f * (j * k - r * i); + result[2][2] = 1.0f - 2.0f * (i * i + j * j); + result[2][3] = 0.0f; + + result[3][0] = 0.0f; + result[3][1] = 0.0f; + result[3][2] = 0.0f; + result[3][3] = 1.0f; +} + +void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians) +{ + GLfloat r[4][4]; + + { + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat const dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + { + /* build a matrix from the quat */ + + GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); + GLfloat const a01 = 2.0f * (i * j + r * k); + GLfloat const a02 = 2.0f * (i * k - r * j); + + GLfloat const a10 = 2.0f * (i * j - r * k); + GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); + GLfloat const a12 = 2.0f * (j * k + r * i); + + GLfloat const a20 = 2.0f * (i * k + r * j); + GLfloat const a21 = 2.0f * (j * k - r * i); + GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); + + result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; + result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; + result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; + result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; + + result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; + result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; + result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; + result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; + + result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; + result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; + result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; + result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; + + result[3][0] = m[3][0]; + result[3][1] = m[3][1]; + result[3][2] = m[3][2]; + result[3][3] = m[3][3]; + } + } + + NvCopyMatf(result, r); +} + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) +{ + NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees) +{ + NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]) +{ + GLfloat ev[3]; + GLfloat z[3]; + GLfloat x_tmp[3]; + GLfloat x[3]; + GLfloat y[3]; + + NvSubVecf(ev, eye, obj); + + NvNormalizeVecf(z, ev); + + NvCrossProductf(x_tmp, up, z); + + NvNormalizeVecf(x, x_tmp); + + NvCrossProductf(y, z, x); + + r[0][0] = x[0]; + r[0][1] = y[0]; + r[0][2] = z[0]; + r[0][3] = 0.0f; + + r[1][0] = x[1]; + r[1][1] = y[1]; + r[1][2] = z[1]; + r[1][3] = 0.0f; + + r[2][0] = x[2]; + r[2][1] = y[2]; + r[2][2] = z[2]; + r[2][3] = 0.0f; + + r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; + r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; + r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; + r[3][3] = 1.0f; +} + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const m00 = znear * 2.0f / (right - left); + GLfloat const m11 = znear * 2.0f / (top - bottom); + GLfloat const m22 = -(zfar + znear) / (zfar - znear); + + GLfloat const m20 = (right + left) / (right - left); + GLfloat const m21 = (top + bottom) / (top - bottom); + + GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); + GLfloat const m23 = -1.0f; + + r[0][0] = m00; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = m11; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = m20; + r[2][1] = m21; + r[2][2] = m22; + r[2][3] = m23; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = m32; + r[3][3] = 0.0f; +} + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + GLfloat const sz = -2.0f / (zfar - znear); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + GLfloat const tz = -(zfar + znear) / (zfar - znear); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = sz; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = tz; + r[3][3] = 1.0f; +} diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.h b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.h new file mode 100644 index 00000000..2a8e186e --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_matrix.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_MATRIX_H +#define INCLUDED_MATRIX_H + +#include +#include +#include + +#define KD_FLT_EPSILON 1.19209290E-07F +#define KD_DEG_TO_RAD_F 0.0174532924F +#define KD_RAD_TO_DEG_F 57.2957802F + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); + +/* vector utilities */ + +GLfloat NvVecLengthf(const GLfloat v[3]); + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); + +/* matrix utilities */ + +void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); + +void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); + +/* matrix building utilities */ + +void NvBuildIdentityMatf(GLfloat r[4][4]); + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); + +void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]); + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +/* matrix concatenation utilities */ + +void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); +void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees); + +void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); + +void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians); + +#endif diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.cpp b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.cpp new file mode 100644 index 00000000..6dc6d1a7 --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_quat.h" +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) +{ + memcpy(r, q, 4 * sizeof(GLfloat)); +} + +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) +{ + // Assumes that the quaternion is normalized! + GLfloat x2 = q[0] * 2.0f; + GLfloat y2 = q[1] * 2.0f; + GLfloat z2 = q[2] * 2.0f; + GLfloat xSq2 = x2 * q[0]; + GLfloat ySq2 = y2 * q[1]; + GLfloat zSq2 = z2 * q[2]; + GLfloat xy2 = x2 * q[1]; + GLfloat xz2 = x2 * q[2]; + GLfloat xw2 = x2 * q[3]; + GLfloat yz2 = y2 * q[2]; + GLfloat yw2 = y2 * q[3]; + GLfloat zw2 = z2 * q[3]; + + /* Matrix is + * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | + * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | + * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | + */ + r[0][0] = 1.0f - ySq2 - zSq2; + r[0][1] = xy2 - zw2; + r[0][2] = xz2 + yw2; + + r[1][0] = xy2 + zw2; + r[1][1] = 1.0f - xSq2 - zSq2; + r[1][2] = yz2 - xw2; + + r[2][0] = xz2 - yw2; + r[2][1] = yz2 + xw2; + r[2][2] = 1.0f - xSq2 - ySq2; +} + +void NvQuatIdentity(GLfloat r[4]) +{ + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = 1.0f; +} + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = axis[0] * sina; + r[1] = axis[1] * sina; + r[2] = axis[2] * sina; + r[3] = cosa; +} + +void NvQuatX(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = sina; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatY(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = sina; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatZ(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = sina; + r[3] = cosa; +} + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatY(h, heading); + NvQuatX(p, pitch); + NvQuatZ(ro, roll); + + NvQuatMult(r, h, p); + NvQuatMult(r, ro, r); +} + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatZ(ro, roll); + NvQuatX(p, pitch); + NvQuatY(h, heading); + + NvQuatMult(r, p, h); + NvQuatMult(r, r, ro); +} + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) +{ + return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; +} + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) +{ + const GLfloat q1x = q1[0]; + const GLfloat q1y = q1[1]; + const GLfloat q1z = q1[2]; + const GLfloat q1w = q1[3]; + const GLfloat q2x = q2[0]; + const GLfloat q2y = q2[1]; + const GLfloat q2z = q2[2]; + const GLfloat q2w = q2[3]; + + r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; + r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; + r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; + r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; +} + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) +{ + GLfloat omt = 1.0f - t; + + if (NvQuatDot(q1, q2) < 0.0f) { + r[0] = -q1[0] * omt + q2[0] * t; + r[1] = -q1[1] * omt + q2[1] * t; + r[2] = -q1[2] * omt + q2[2] * t; + r[3] = -q1[3] * omt + q2[3] * t; + } else { + r[0] = q1[0] * omt + q2[0] * t; + r[1] = q1[1] * omt + q2[1] * t; + r[2] = q1[2] * omt + q2[2] * t; + r[3] = q1[3] * omt + q2[3] * t; + } + + NvQuatNormalize(r, r); +} + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) +{ + GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); + + r[0] = invLength * q[0]; + r[1] = invLength * q[1]; + r[2] = invLength * q[2]; + r[3] = invLength * q[3]; +} diff --git a/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.h b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.h new file mode 100644 index 00000000..688c30a7 --- /dev/null +++ b/src/Runtime/Source/platformspecific/android/jni/libs/nv_math/nv_quat.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QUAT_H +#define INCLUDED_QUAT_H + +#include +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); + +void NvQuatIdentity(GLfloat r[4]); + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); + +void NvQuatX(GLfloat r[4], GLfloat radians); + +void NvQuatY(GLfloat r[4], GLfloat radians); + +void NvQuatZ(GLfloat r[4], GLfloat radians); + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.abc b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.abc new file mode 100644 index 00000000..f7e3c2f6 Binary files /dev/null and b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.abc differ diff --git a/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.dds b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.dds new file mode 100644 index 00000000..5bde760b Binary files /dev/null and b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_256.dds differ diff --git a/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.abc b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.abc new file mode 100644 index 00000000..2ff78757 Binary files /dev/null and b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.abc differ diff --git a/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.dds b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.dds new file mode 100644 index 00000000..f9e76d94 Binary files /dev/null and b/src/Runtime/Source/platformspecific/linux/assets/courier+lucida_512.dds differ diff --git a/src/Runtime/Source/platformspecific/linux/assets/font.frag b/src/Runtime/Source/platformspecific/linux/assets/font.frag new file mode 100644 index 00000000..e4673cf8 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/assets/font.frag @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +uniform sampler2D fontTex; + +varying lowp vec4 col_var; +varying lowp vec2 tex_var; + +void main() +{ + gl_FragColor = texture2D(fontTex, tex_var).a * col_var; +} + diff --git a/src/Runtime/Source/platformspecific/linux/assets/font.vert b/src/Runtime/Source/platformspecific/linux/assets/font.vert new file mode 100644 index 00000000..9f307a2f --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/assets/font.vert @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// this is set from higher level. think of it as the upper model matrix +uniform mat4 pixelToClipMat; + +uniform vec4 col_uni; + +attribute vec2 pos_attr; +attribute vec2 tex_attr; +attribute vec4 col_attr; + +varying vec4 col_var; +varying vec2 tex_var; + +void main() +{ + // account for translation and rotation of the primitive into [-1,1] spatial default. + gl_Position = pixelToClipMat * vec4(pos_attr.x, pos_attr.y, 0, 1); + + col_var = col_attr * col_uni; + tex_var = tex_attr; +} diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_color.h b/src/Runtime/Source/platformspecific/linux/libs/nv_color.h new file mode 100644 index 00000000..b9347529 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_color.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_COLOR_H +#define _QT3DS_COLOR_H + +/** @file nv_color.h + Simple abstraction for RGBA colors as parameters to various libraries/functions. +*/ + +/** Base type for a single color channel (8-bit unsigned). */ +typedef unsigned char NvPCColor8; + +//#define NV_COLOR_BREAKOLD +#ifdef NV_COLOR_BREAKOLD // uses a struct to break backwards-compat and accidental uses + +typedef struct +{ + NvPCColor8 r; + NvPCColor8 g; + NvPCColor8 b; + NvPCColor8 a; +} NvPackedColor; + +static const NvPackedColor gnvpcwhite = { 255, 255, 255, 255 }; +static const NvPackedColor gnvpcblack = { 0, 0, 0, 255 }; + +#define NV_PACKED_COLOR(r, g, b, a) \ + { \ + (NvPCColor8)(r), (NvPCColor8)(g), (NvPCColor8)(b), (NvPCColor8)(a) \ + } + +#define NV_PC_PREDEF_WHITE gnvpcwhite +#define NV_PC_PREDEF_BLACK gnvpcblack + +#define NV_PC_RED(c) (c.r) +#define NV_PC_GREEN(c) (c.g) +#define NV_PC_BLUE(c) (c.b) +#define NV_PC_ALPHA(c) (c.a) + +#define NV_PC_PACK_UINT(c) (*(unsigned int *)(&(c))) + +#define NV_PC_EQUAL(x, y) ((x).r == (y).r && (x).g == (y).g && (x).b == (y).b && (x).a == (y).a) + +#else /* code that doesn't break old pass-as-uint stuff */ + +/** Main type declaration for a packed 4-color construct. */ +typedef unsigned int NvPackedColor; + +/** A macro to build a packed color, passing in RGBA as four 8-bit integer values. */ +#define NV_PACKED_COLOR(r, g, b, a) \ + ((NvPackedColor)(((((int)(a)) & 0xFF) << 24) | ((((int)(b)) & 0xFF) << 16) \ + | ((((int)(g)) & 0xFF) << 8) | ((((int)(r)) & 0xFF)))) + +/** A predefined constant for WHITE. */ +#define NV_PC_PREDEF_WHITE NV_PACKED_COLOR(0xFF, 0xFF, 0xFF, 0xFF) +/** A predefined constant for BLACK. */ +#define NV_PC_PREDEF_BLACK NV_PACKED_COLOR(0x00, 0x00, 0x00, 0xFF) + +/** A macro for 'extracting' the red value from an NvPackedColor. */ +#define NV_PC_RED(c) ((c >> 0) & 0xff) +/** A macro for 'extracting' the green value from an NvPackedColor. */ +#define NV_PC_GREEN(c) ((c >> 8) & 0xff) +/** A macro for 'extracting' the blue value from an NvPackedColor. */ +#define NV_PC_BLUE(c) ((c >> 16) & 0xff) +/** A macro for 'extracting' the alpha value from an NvPackedColor. */ +#define NV_PC_ALPHA(c) ((c >> 24) & 0xff) + +/** A macro requesting the packed color repacked into a 32-bit unsigned int. + This is a no-op for the color-as-uint approach. +*/ +#define NV_PC_PACK_UINT(c) (c) +/** A macro for testing the equality of two NvPackedColors. */ +#define NV_PC_EQUAL(x, y) (x == y) +#endif + +/** A macro for mapping a single packed color channel into its floating point [0,1] rep. */ +#define NV_PC_TO_FLOAT(c) (c / 255.0f) + +#endif /*_QT3DS_COLOR_H*/ diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_debug.h b/src/Runtime/Source/platformspecific/linux/libs/nv_debug.h new file mode 100644 index 00000000..2559dd6f --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_debug.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_DEBUG_H +#define __INCLUDED_QT3DS_DEBUG_H + +#define CT_ASSERT(tag, cond) enum { COMPILE_TIME_ASSERT__##tag = 1 / (cond) } + +#define dimof(x) (sizeof(x) / sizeof(x[0])) +#include + +#define DBG_DETAILED 0 + +#if 0 + + // the detailed prefix can be customised by setting DBG_DETAILED_PREFIX. See + // below as a reference. + // NOTE: fmt is the desired format string and must be in the prefix. + //#ifndef DBG_DETAILED_PREFIX + // #define DBG_DETAILED_PREFIX "%s, %s, line %d: " fmt, __FILE__, __FUNCTION__, __LINE__, + //#endif + //#define DEBUG_D_(fmt, args...) + //#define DEBUG_D(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, (DBG_DETAILED_PREFIX) ## args) + +#else + +#ifdef STRINGIFY +#pragma push_macro("STRINGIFY") +#undef STRINGIFY +#define STRINGIFYPUSHED_____ +#endif +#define STRINGIFY(x) #x + +// debug macro, includes file name function name and line number +#define TO(x) typeof(x) +#define DEBUG_D_(file, line, fmt, args...) \ + __android_log_print(ANDROID_LOG_DEBUG, MODULE, file ", %s, line(" STRINGIFY(line) "): " fmt, \ + __FUNCTION__, ##args) +#define DEBUG_D(fmt, args...) DEBUG_D_(__FILE__, __LINE__, fmt, ##args) + +#ifdef STRINGIFYPUSHED_____ +#undef STRINGIFYPUSHED_____ +#pragma pop_macro("STRINGIFY") +#endif + +#endif + +// basic debug macro +#define DEBUG_(fmt, args...) (__android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args)) + +// Debug macro that can be switched to spew a file name, +// function and line number using DEBUG_DETAILED +#if DBG_DETAILED == 1 +#define DEBUG(fmt, args...) DEBUG_D(fmt, ##args) +#else +#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args) +#endif + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_global.h b/src/Runtime/Source/platformspecific/linux/libs/nv_global.h new file mode 100644 index 00000000..9d23d45f --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_global.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_GLOBAL_H +#define __INCLUDED_QT3DS_GLOBAL_H + +#include "nv_types.h" + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/NvVec.h b/src/Runtime/Source/platformspecific/linux/libs/nv_math/NvVec.h new file mode 100644 index 00000000..4e5b09ce --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/NvVec.h @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H +#define INCLUDED_QT3DS_MATH_CPP_VEC_H + +#include "misc.h" + +struct _NvVec3 +{ + union { + struct + { + float x, y, z; + }; + float v[3]; + }; +}; + +struct NvVec3 : public _NvVec3 +{ + NvVec3() { zero(); } + + NvVec3(float x, float y, float z) + { + v[0] = x; + v[1] = y; + v[2] = z; + } + + NvVec3(NvVec3 const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + v[2] = that.v[2]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + v[2] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + NvVec3 &operator+=(NvVec3 const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + v[2] += that.v[2]; + return *this; + } + + NvVec3 &operator-=(NvVec3 const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + v[2] -= that.v[2]; + return *this; + } + + NvVec3 &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + v[2] *= s; + return *this; + } + + NvVec3 &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + v[2] /= s; + return *this; + } +}; + +inline float dot(NvVec3 const &a, NvVec3 const &b) +{ + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a) +{ + + return NvVec3(-a.v[0], -a.v[1], -a.v[2]); +} + +inline NvVec3 operator*(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); +} + +inline NvVec3 operator*(float s, NvVec3 const &a) +{ + + return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); +} + +inline NvVec3 operator/(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); +} + +inline float magnitude(NvVec3 const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec3 normalize(NvVec3 const &v) +{ + float l = magnitude(v); + return NvVec3(v[0] / l, v[1] / l, v[2] / l); +} + +inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], + a.v[0] * b.v[1] - a.v[1] * b.v[0]); +} + +inline bool operator==(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); +} + +inline bool operator!=(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); +} + +struct NvVec2f +{ + union { + struct + { + float x, y; + float v[2]; + }; + }; + + NvVec2f() { zero(); } + + NvVec2f(float x, float y) + { + v[0] = x; + v[1] = y; + } + + NvVec2f(NvVec2f const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + NvVec2f &operator+=(NvVec2f const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + return *this; + } + + NvVec2f &operator-=(NvVec2f const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + return *this; + } + + NvVec2f &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + return *this; + } + + NvVec2f &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + return *this; + } +}; + +inline float dot(NvVec2f const &a, NvVec2f const &b) +{ + + return a[0] * b[0] + a[1] * b[1]; +} + +inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a) +{ + + return NvVec2f(-a.v[0], -a.v[1]); +} + +inline NvVec2f operator*(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] * s, a.v[1] * s); +} + +inline NvVec2f operator*(float s, NvVec2f const &a) +{ + + return NvVec2f(s * a.v[0], s * a.v[1]); +} + +inline NvVec2f operator/(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] / s, a.v[1] / s); +} + +inline float magnitude(NvVec2f const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec2f normalize(NvVec2f const &v) +{ + float l = dot(v, v); + return NvVec2f(v[0] / l, v[1] / l); +} + +inline float cross(NvVec2f const &a, NvVec2f const &b) +{ + + return a.v[0] * b.v[1] - b.v[0] * a.v[1]; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/misc.h b/src/Runtime/Source/platformspecific/linux/libs/nv_math/misc.h new file mode 100644 index 00000000..983410f3 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/misc.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H +#define INCLUDED_QT3DS_MATH_CPP_MISC_H + +inline bool nvIsPowerOfTwo(unsigned int i) +{ + return (i & (i - 1)) == 0; +} + +inline float nvDegToRadf(float d) +{ + return d * 3.14159265358979323846f / 180.0f; +} + +inline float nvRadToDegf(float r) +{ + return r * 180.0f / 3.14159265358979323846f; +} + +/* + 'mod' differs from '%' in that it behaves correctly when either the + numerator or denominator is negative. +*/ + +inline int nvMod(int n, int d) +{ + int m = n % d; + return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; +} + +inline int nvAbs(int n) +{ + if (n < 0) + return -n; + return n; +} + +inline int nvSign(int n) +{ + if (n > 0) + return 1; + if (n < 0) + return -1; + return 0; +} + +/* + This returns the smallest amplitude value x such that + nvMod(b + x, m) == a +*/ + +inline int nvDifMod(int a, int b, int m) +{ + + int x1 = a - b; + int x2 = (x1 > 0) ? x1 - m : x1 + m; + return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; +} + +inline float nvWrapf(float a, float min, float max) +{ + + assert(max > min); + + float d = max - min; + float s = a - min; + float q = s / d; + float m = q - floorf(q); + return m * d + min; +} + +inline float nvClampf(float a, float min, float max) +{ + return (a < min) ? min : ((a > max) ? max : a); +} + +inline int nvClampi(int i, int min, int max) +{ + return (i < min) ? min : ((i > max) ? max : i); +} + +inline float nvGaussian(float x, float s) +{ + float c = s * sqrtf(2.0f * 3.14159265358979323846f); + return expf(-(x * x) / (2.0f * s * s)) / c; +} + +inline float nvLerpf(float a, float b, float t) +{ + return a * (1.0f - t) + b * t; +} + +inline float nvEasef(float t) +{ + + float t_2 = t * t; + float t_3 = t_2 * t; + return 3.0f * t_2 - 2.0f * t_3; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.cpp b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.cpp new file mode 100644 index 00000000..b83cb39e --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_math.h" + +static const double a = 16807.0; +static const double m = 2147483647.0; + +static double nextSeed(double seed) +{ + double t = a * seed; + return t - m * (double)((int)(t / m)); +} + +GLfloat NvRandf() +{ + static double seed = 1.0; + seed = nextSeed(seed); + return (GLfloat)(seed * (1 / m)); +} + +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) +{ + // kdGetTimeUST is never supposed to decrease (i.e. that + // means it can't wrap, either. IIRC, it will wrap in + // 593 years). So we ignore that option... + + // Used for frame-to-frame diffs, this will fit in 32b + // as long as the times are < ~4.3s apart + long long int diffTime = newTime - oldTime; + + // Need to find a better way to do this. + // However, I believe we will be uSec precise (not run + // out of mantissa bits for uSecs) as long as the diff + // is < ~16s (1e-6 * (2^24)) + return ((GLfloat)diffTime) / 1.0e9f; +} diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.h b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.h new file mode 100644 index 00000000..2ef7bba0 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_math.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_MATH_H +#define _QT3DS_MATH_H + +#include + +GLfloat NvRandf(); + +/* These are the recommended "safer" ways to use GLfloat for time */ + +/* Returns the seconds between the two given times */ +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); + +#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.cpp b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.cpp new file mode 100644 index 00000000..e208ac31 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.cpp @@ -0,0 +1,1030 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_matrix.h" + +int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) +{ + return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); +} + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; +} + +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; +} + +GLfloat NvVecLengthf(const GLfloat v[3]) +{ + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) +{ + GLfloat const l = NvVecLengthf(v); + r[0] = v[0] / l; + r[1] = v[1] / l; + r[2] = v[2] / l; +} + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] + b[0]; + r[1] = a[1] + b[1]; + r[2] = a[2] + b[2]; +} + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] - b[0]; + r[1] = a[1] - b[1]; + r[2] = a[2] - b[2]; +} + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + GLfloat t[3]; + + t[0] = a[1] * b[2] - a[2] * b[1]; + t[1] = a[2] * b[0] - a[0] * b[2]; + t[2] = a[0] * b[1] - a[1] * b[0]; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; +} + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); + + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; +} + +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; + r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; +} + +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; +} + +static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; + r[3][3] = 1.0f; +} + +static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; + r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; + r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; + r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; + r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; +} + +void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) + && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { + if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) + && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { + NvMultMat3x3f(r, a, b); + } else { + NvMultMat4x3f(r, a, b); + } + } else { + NvMultMat4x4f(r, a, b); + } + + NvCopyMatf(result, r); +} + +static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + /* x */ + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + /* y */ + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + /* z */ + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = 1.0f; +} + +static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] + + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] + + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] + + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] + + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] + + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] + + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] + + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] + + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] + + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] + + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] + + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] + + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) + / d; + + r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] + + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] + + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) + / d; + + r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] + + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] + + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) + / d; + + r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] + + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] + + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) + / d; + + r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] + + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] + + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) + / d; + + r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] + + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] + + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) + / d; + + r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] + + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] + + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) + / d; + + r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] + + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] + + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) + / d; + + r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] + + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] + + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) + / d; + + r[2][1] = + (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] + + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) + / d; + + r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] + + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] + + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) + / d; + + r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] + + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] + + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) + / d; + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) + / d; +} + +void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { + if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { + NvInvMat3x3f(r, m); + } else { + NvInvMat4x3f(r, m); + } + } else { + NvInvMat4x4f(r, m); + } + + NvCopyMatf(result, r); +} + +void NvBuildIdentityMatf(GLfloat r[4][4]) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = x; + r[3][1] = y; + r[3][2] = z; + r[3][3] = 1.0f; +} + +void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, + GLfloat z) +{ + GLfloat r[4][4]; /*temporary storage for result */ + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; + r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; + r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; + r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = x; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = y; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = z; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * x; + r[0][1] = m[0][1] * x; + r[0][2] = m[0][2] * x; + r[0][3] = m[0][3] * x; + + r[1][0] = m[1][0] * y; + r[1][1] = m[1][1] * y; + r[1][2] = m[1][2] * y; + r[1][3] = m[1][3] * y; + + r[2][0] = m[2][0] * z; + r[2][1] = m[2][1] * z; + r[2][2] = m[2][2] * z; + r[2][3] = m[2][3] * z; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) +{ + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = c; + r[1][2] = s; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = -s; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = 0.0f; + r[0][2] = -s; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = s; + r[2][1] = 0.0f; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = s; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = -s; + r[1][1] = c; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0] * c + m[2][0] * s; + r[1][1] = m[1][1] * c + m[2][1] * s; + r[1][2] = m[1][2] * c + m[2][2] * s; + r[1][3] = m[1][3] * c + m[2][3] * s; + + r[2][0] = m[1][0] * -s + m[2][0] * c; + r[2][1] = m[1][1] * -s + m[2][1] * c; + r[2][2] = m[1][2] * -s + m[2][2] * c; + r[2][3] = m[1][3] * -s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[2][0] * -s; + r[0][1] = m[0][1] * c + m[2][1] * -s; + r[0][2] = m[0][2] * c + m[2][2] * -s; + r[0][3] = m[0][3] * c + m[2][3] * -s; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[0][0] * s + m[2][0] * c; + r[2][1] = m[0][1] * s + m[2][1] * c; + r[2][2] = m[0][2] * s + m[2][2] * c; + r[2][3] = m[0][3] * s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[1][0] * s; + r[0][1] = m[0][1] * c + m[1][1] * s; + r[0][2] = m[0][2] * c + m[1][2] * s; + r[0][3] = m[0][3] * c + m[1][3] * s; + + r[1][0] = m[0][0] * -s + m[1][0] * c; + r[1][1] = m[0][1] * -s + m[1][1] * c; + r[1][2] = m[0][2] * -s + m[1][2] * c; + r[1][3] = m[0][3] * -s + m[1][3] * c; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) +{ + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + /* build a matrix from the quat */ + + result[0][0] = 1.0f - 2.0f * (j * j + k * k); + result[0][1] = 2.0f * (i * j + r * k); + result[0][2] = 2.0f * (i * k - r * j); + result[0][3] = 0.0f; + + result[1][0] = 2.0f * (i * j - r * k); + result[1][1] = 1.0f - 2.0f * (i * i + k * k); + result[1][2] = 2.0f * (j * k + r * i); + result[1][3] = 0.0f; + + result[2][0] = 2.0f * (i * k + r * j); + result[2][1] = 2.0f * (j * k - r * i); + result[2][2] = 1.0f - 2.0f * (i * i + j * j); + result[2][3] = 0.0f; + + result[3][0] = 0.0f; + result[3][1] = 0.0f; + result[3][2] = 0.0f; + result[3][3] = 1.0f; +} + +void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians) +{ + GLfloat r[4][4]; + + { + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat const dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + { + /* build a matrix from the quat */ + + GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); + GLfloat const a01 = 2.0f * (i * j + r * k); + GLfloat const a02 = 2.0f * (i * k - r * j); + + GLfloat const a10 = 2.0f * (i * j - r * k); + GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); + GLfloat const a12 = 2.0f * (j * k + r * i); + + GLfloat const a20 = 2.0f * (i * k + r * j); + GLfloat const a21 = 2.0f * (j * k - r * i); + GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); + + result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; + result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; + result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; + result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; + + result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; + result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; + result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; + result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; + + result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; + result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; + result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; + result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; + + result[3][0] = m[3][0]; + result[3][1] = m[3][1]; + result[3][2] = m[3][2]; + result[3][3] = m[3][3]; + } + } + + NvCopyMatf(result, r); +} + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) +{ + NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees) +{ + NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]) +{ + GLfloat ev[3]; + GLfloat z[3]; + GLfloat x_tmp[3]; + GLfloat x[3]; + GLfloat y[3]; + + NvSubVecf(ev, eye, obj); + + NvNormalizeVecf(z, ev); + + NvCrossProductf(x_tmp, up, z); + + NvNormalizeVecf(x, x_tmp); + + NvCrossProductf(y, z, x); + + r[0][0] = x[0]; + r[0][1] = y[0]; + r[0][2] = z[0]; + r[0][3] = 0.0f; + + r[1][0] = x[1]; + r[1][1] = y[1]; + r[1][2] = z[1]; + r[1][3] = 0.0f; + + r[2][0] = x[2]; + r[2][1] = y[2]; + r[2][2] = z[2]; + r[2][3] = 0.0f; + + r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; + r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; + r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; + r[3][3] = 1.0f; +} + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const m00 = znear * 2.0f / (right - left); + GLfloat const m11 = znear * 2.0f / (top - bottom); + GLfloat const m22 = -(zfar + znear) / (zfar - znear); + + GLfloat const m20 = (right + left) / (right - left); + GLfloat const m21 = (top + bottom) / (top - bottom); + + GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); + GLfloat const m23 = -1.0f; + + r[0][0] = m00; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = m11; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = m20; + r[2][1] = m21; + r[2][2] = m22; + r[2][3] = m23; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = m32; + r[3][3] = 0.0f; +} + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + GLfloat const sz = -2.0f / (zfar - znear); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + GLfloat const tz = -(zfar + znear) / (zfar - znear); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = sz; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = tz; + r[3][3] = 1.0f; +} diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.h b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.h new file mode 100644 index 00000000..5f567f06 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_matrix.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_MATRIX_H +#define INCLUDED_MATRIX_H + +#include + +#include +#include + +#define KD_FLT_EPSILON 1.19209290E-07F +#define KD_DEG_TO_RAD_F 0.0174532924F +#define KD_RAD_TO_DEG_F 57.2957802F + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); + +/* vector utilities */ + +GLfloat NvVecLengthf(const GLfloat v[3]); + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); + +/* matrix utilities */ + +void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); + +void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); + +/* matrix building utilities */ + +void NvBuildIdentityMatf(GLfloat r[4][4]); + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); + +void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]); + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +/* matrix concatenation utilities */ + +void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); +void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees); + +void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); + +void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians); + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.cpp b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.cpp new file mode 100644 index 00000000..e66420c6 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_quat.h" +#include +#ifdef _INTEGRITYPLATFORM +#include +#else +#include +#endif + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) +{ + memcpy(r, q, 4 * sizeof(GLfloat)); +} + +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) +{ + // Assumes that the quaternion is normalized! + GLfloat x2 = q[0] * 2.0f; + GLfloat y2 = q[1] * 2.0f; + GLfloat z2 = q[2] * 2.0f; + GLfloat xSq2 = x2 * q[0]; + GLfloat ySq2 = y2 * q[1]; + GLfloat zSq2 = z2 * q[2]; + GLfloat xy2 = x2 * q[1]; + GLfloat xz2 = x2 * q[2]; + GLfloat xw2 = x2 * q[3]; + GLfloat yz2 = y2 * q[2]; + GLfloat yw2 = y2 * q[3]; + GLfloat zw2 = z2 * q[3]; + + /* Matrix is + * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | + * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | + * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | + */ + r[0][0] = 1.0f - ySq2 - zSq2; + r[0][1] = xy2 - zw2; + r[0][2] = xz2 + yw2; + + r[1][0] = xy2 + zw2; + r[1][1] = 1.0f - xSq2 - zSq2; + r[1][2] = yz2 - xw2; + + r[2][0] = xz2 - yw2; + r[2][1] = yz2 + xw2; + r[2][2] = 1.0f - xSq2 - ySq2; +} + +void NvQuatIdentity(GLfloat r[4]) +{ + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = 1.0f; +} + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = axis[0] * sina; + r[1] = axis[1] * sina; + r[2] = axis[2] * sina; + r[3] = cosa; +} + +void NvQuatX(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = sina; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatY(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = sina; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatZ(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = sina; + r[3] = cosa; +} + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatY(h, heading); + NvQuatX(p, pitch); + NvQuatZ(ro, roll); + + NvQuatMult(r, h, p); + NvQuatMult(r, ro, r); +} + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatZ(ro, roll); + NvQuatX(p, pitch); + NvQuatY(h, heading); + + NvQuatMult(r, p, h); + NvQuatMult(r, r, ro); +} + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) +{ + return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; +} + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) +{ + const GLfloat q1x = q1[0]; + const GLfloat q1y = q1[1]; + const GLfloat q1z = q1[2]; + const GLfloat q1w = q1[3]; + const GLfloat q2x = q2[0]; + const GLfloat q2y = q2[1]; + const GLfloat q2z = q2[2]; + const GLfloat q2w = q2[3]; + + r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; + r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; + r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; + r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; +} + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) +{ + GLfloat omt = 1.0f - t; + + if (NvQuatDot(q1, q2) < 0.0f) { + r[0] = -q1[0] * omt + q2[0] * t; + r[1] = -q1[1] * omt + q2[1] * t; + r[2] = -q1[2] * omt + q2[2] * t; + r[3] = -q1[3] * omt + q2[3] * t; + } else { + r[0] = q1[0] * omt + q2[0] * t; + r[1] = q1[1] * omt + q2[1] * t; + r[2] = q1[2] * omt + q2[2] * t; + r[3] = q1[3] * omt + q2[3] * t; + } + + NvQuatNormalize(r, r); +} + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) +{ + GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); + + r[0] = invLength * q[0]; + r[1] = invLength * q[1]; + r[2] = invLength * q[2]; + r[3] = invLength * q[3]; +} diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.h b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.h new file mode 100644 index 00000000..2e97c717 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_math/nv_quat.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QUAT_H +#define INCLUDED_QUAT_H + +#include + +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); + +void NvQuatIdentity(GLfloat r[4]); + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); + +void NvQuatX(GLfloat r[4], GLfloat radians); + +void NvQuatY(GLfloat r[4], GLfloat radians); + +void NvQuatZ(GLfloat r[4], GLfloat radians); + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); + +#endif diff --git a/src/Runtime/Source/platformspecific/linux/libs/nv_types.h b/src/Runtime/Source/platformspecific/linux/libs/nv_types.h new file mode 100644 index 00000000..1d1b0300 --- /dev/null +++ b/src/Runtime/Source/platformspecific/linux/libs/nv_types.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_TYPES_H +#define __INCLUDED_QT3DS_TYPES_H + +typedef unsigned char NvU8; // 0 to 255 +typedef unsigned short NvU16; // 0 to 65535 +typedef unsigned int NvU32; // 0 to 4294967295 +typedef unsigned long long NvU64; // 0 to 18446744073709551615 +typedef signed char NvS8; // -128 to 127 +typedef signed short NvS16; // -32768 to 32767 +typedef signed int NvS32; // -2147483648 to 2147483647 +typedef signed long long NvS64; // 2^-63 to 2^63-1 + +// Explicitly sized floats +typedef float NvF32; // IEEE Single Precision (S1E8M23) +typedef double NvF64; // IEEE Double Precision (S1E11M52) + +// Boolean type +#define QT3DS_FALSE 0 +#define QT3DS_TRUE 1 +typedef NvU8 NvBool; + +// Result of sizeof operator +typedef unsigned long NvSize; + +// Type large enough to hold a relative file offset +typedef long NvOffset; + +// Base NULL type. +#define QT3DS_NULL 0 + +// Error related +typedef enum { + NvError_Success = 0, + NvError_NotSupported, + NvError_NotInitialized, + NvError_BadParameter, + NvError_InsufficientMemory, + NvError_NoEntries, + NvError_UnknownError, +} NvError; + +#if 1 // defined(_DEBUG) // !!!!TBD TODO +#define NvAssert(c) +#else +#define NvAssert(c) ((void)((c) ? 0 : (NvHandleAssertion(#c, __FILE__, __LINE__), 0))) +#endif + +// Other standardized typedefs +typedef NvU64 NvUST; // U64 unadjusted system time value + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.abc b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.abc new file mode 100644 index 00000000..f7e3c2f6 Binary files /dev/null and b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.abc differ diff --git a/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.dds b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.dds new file mode 100644 index 00000000..5bde760b Binary files /dev/null and b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_256.dds differ diff --git a/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.abc b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.abc new file mode 100644 index 00000000..2ff78757 Binary files /dev/null and b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.abc differ diff --git a/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.dds b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.dds new file mode 100644 index 00000000..f9e76d94 Binary files /dev/null and b/src/Runtime/Source/platformspecific/macos/assets/courier+lucida_512.dds differ diff --git a/src/Runtime/Source/platformspecific/macos/assets/font.frag b/src/Runtime/Source/platformspecific/macos/assets/font.frag new file mode 100644 index 00000000..e4673cf8 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/assets/font.frag @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +uniform sampler2D fontTex; + +varying lowp vec4 col_var; +varying lowp vec2 tex_var; + +void main() +{ + gl_FragColor = texture2D(fontTex, tex_var).a * col_var; +} + diff --git a/src/Runtime/Source/platformspecific/macos/assets/font.vert b/src/Runtime/Source/platformspecific/macos/assets/font.vert new file mode 100644 index 00000000..9f307a2f --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/assets/font.vert @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// this is set from higher level. think of it as the upper model matrix +uniform mat4 pixelToClipMat; + +uniform vec4 col_uni; + +attribute vec2 pos_attr; +attribute vec2 tex_attr; +attribute vec4 col_attr; + +varying vec4 col_var; +varying vec2 tex_var; + +void main() +{ + // account for translation and rotation of the primitive into [-1,1] spatial default. + gl_Position = pixelToClipMat * vec4(pos_attr.x, pos_attr.y, 0, 1); + + col_var = col_attr * col_uni; + tex_var = tex_attr; +} diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_color.h b/src/Runtime/Source/platformspecific/macos/libs/nv_color.h new file mode 100644 index 00000000..b9347529 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_color.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_COLOR_H +#define _QT3DS_COLOR_H + +/** @file nv_color.h + Simple abstraction for RGBA colors as parameters to various libraries/functions. +*/ + +/** Base type for a single color channel (8-bit unsigned). */ +typedef unsigned char NvPCColor8; + +//#define NV_COLOR_BREAKOLD +#ifdef NV_COLOR_BREAKOLD // uses a struct to break backwards-compat and accidental uses + +typedef struct +{ + NvPCColor8 r; + NvPCColor8 g; + NvPCColor8 b; + NvPCColor8 a; +} NvPackedColor; + +static const NvPackedColor gnvpcwhite = { 255, 255, 255, 255 }; +static const NvPackedColor gnvpcblack = { 0, 0, 0, 255 }; + +#define NV_PACKED_COLOR(r, g, b, a) \ + { \ + (NvPCColor8)(r), (NvPCColor8)(g), (NvPCColor8)(b), (NvPCColor8)(a) \ + } + +#define NV_PC_PREDEF_WHITE gnvpcwhite +#define NV_PC_PREDEF_BLACK gnvpcblack + +#define NV_PC_RED(c) (c.r) +#define NV_PC_GREEN(c) (c.g) +#define NV_PC_BLUE(c) (c.b) +#define NV_PC_ALPHA(c) (c.a) + +#define NV_PC_PACK_UINT(c) (*(unsigned int *)(&(c))) + +#define NV_PC_EQUAL(x, y) ((x).r == (y).r && (x).g == (y).g && (x).b == (y).b && (x).a == (y).a) + +#else /* code that doesn't break old pass-as-uint stuff */ + +/** Main type declaration for a packed 4-color construct. */ +typedef unsigned int NvPackedColor; + +/** A macro to build a packed color, passing in RGBA as four 8-bit integer values. */ +#define NV_PACKED_COLOR(r, g, b, a) \ + ((NvPackedColor)(((((int)(a)) & 0xFF) << 24) | ((((int)(b)) & 0xFF) << 16) \ + | ((((int)(g)) & 0xFF) << 8) | ((((int)(r)) & 0xFF)))) + +/** A predefined constant for WHITE. */ +#define NV_PC_PREDEF_WHITE NV_PACKED_COLOR(0xFF, 0xFF, 0xFF, 0xFF) +/** A predefined constant for BLACK. */ +#define NV_PC_PREDEF_BLACK NV_PACKED_COLOR(0x00, 0x00, 0x00, 0xFF) + +/** A macro for 'extracting' the red value from an NvPackedColor. */ +#define NV_PC_RED(c) ((c >> 0) & 0xff) +/** A macro for 'extracting' the green value from an NvPackedColor. */ +#define NV_PC_GREEN(c) ((c >> 8) & 0xff) +/** A macro for 'extracting' the blue value from an NvPackedColor. */ +#define NV_PC_BLUE(c) ((c >> 16) & 0xff) +/** A macro for 'extracting' the alpha value from an NvPackedColor. */ +#define NV_PC_ALPHA(c) ((c >> 24) & 0xff) + +/** A macro requesting the packed color repacked into a 32-bit unsigned int. + This is a no-op for the color-as-uint approach. +*/ +#define NV_PC_PACK_UINT(c) (c) +/** A macro for testing the equality of two NvPackedColors. */ +#define NV_PC_EQUAL(x, y) (x == y) +#endif + +/** A macro for mapping a single packed color channel into its floating point [0,1] rep. */ +#define NV_PC_TO_FLOAT(c) (c / 255.0f) + +#endif /*_QT3DS_COLOR_H*/ diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_debug.h b/src/Runtime/Source/platformspecific/macos/libs/nv_debug.h new file mode 100644 index 00000000..2559dd6f --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_debug.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_DEBUG_H +#define __INCLUDED_QT3DS_DEBUG_H + +#define CT_ASSERT(tag, cond) enum { COMPILE_TIME_ASSERT__##tag = 1 / (cond) } + +#define dimof(x) (sizeof(x) / sizeof(x[0])) +#include + +#define DBG_DETAILED 0 + +#if 0 + + // the detailed prefix can be customised by setting DBG_DETAILED_PREFIX. See + // below as a reference. + // NOTE: fmt is the desired format string and must be in the prefix. + //#ifndef DBG_DETAILED_PREFIX + // #define DBG_DETAILED_PREFIX "%s, %s, line %d: " fmt, __FILE__, __FUNCTION__, __LINE__, + //#endif + //#define DEBUG_D_(fmt, args...) + //#define DEBUG_D(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, (DBG_DETAILED_PREFIX) ## args) + +#else + +#ifdef STRINGIFY +#pragma push_macro("STRINGIFY") +#undef STRINGIFY +#define STRINGIFYPUSHED_____ +#endif +#define STRINGIFY(x) #x + +// debug macro, includes file name function name and line number +#define TO(x) typeof(x) +#define DEBUG_D_(file, line, fmt, args...) \ + __android_log_print(ANDROID_LOG_DEBUG, MODULE, file ", %s, line(" STRINGIFY(line) "): " fmt, \ + __FUNCTION__, ##args) +#define DEBUG_D(fmt, args...) DEBUG_D_(__FILE__, __LINE__, fmt, ##args) + +#ifdef STRINGIFYPUSHED_____ +#undef STRINGIFYPUSHED_____ +#pragma pop_macro("STRINGIFY") +#endif + +#endif + +// basic debug macro +#define DEBUG_(fmt, args...) (__android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args)) + +// Debug macro that can be switched to spew a file name, +// function and line number using DEBUG_DETAILED +#if DBG_DETAILED == 1 +#define DEBUG(fmt, args...) DEBUG_D(fmt, ##args) +#else +#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args) +#endif + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_global.h b/src/Runtime/Source/platformspecific/macos/libs/nv_global.h new file mode 100644 index 00000000..9d23d45f --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_global.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_GLOBAL_H +#define __INCLUDED_QT3DS_GLOBAL_H + +#include "nv_types.h" + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/NvVec.h b/src/Runtime/Source/platformspecific/macos/libs/nv_math/NvVec.h new file mode 100644 index 00000000..4e5b09ce --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/NvVec.h @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H +#define INCLUDED_QT3DS_MATH_CPP_VEC_H + +#include "misc.h" + +struct _NvVec3 +{ + union { + struct + { + float x, y, z; + }; + float v[3]; + }; +}; + +struct NvVec3 : public _NvVec3 +{ + NvVec3() { zero(); } + + NvVec3(float x, float y, float z) + { + v[0] = x; + v[1] = y; + v[2] = z; + } + + NvVec3(NvVec3 const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + v[2] = that.v[2]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + v[2] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + NvVec3 &operator+=(NvVec3 const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + v[2] += that.v[2]; + return *this; + } + + NvVec3 &operator-=(NvVec3 const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + v[2] -= that.v[2]; + return *this; + } + + NvVec3 &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + v[2] *= s; + return *this; + } + + NvVec3 &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + v[2] /= s; + return *this; + } +}; + +inline float dot(NvVec3 const &a, NvVec3 const &b) +{ + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a) +{ + + return NvVec3(-a.v[0], -a.v[1], -a.v[2]); +} + +inline NvVec3 operator*(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); +} + +inline NvVec3 operator*(float s, NvVec3 const &a) +{ + + return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); +} + +inline NvVec3 operator/(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); +} + +inline float magnitude(NvVec3 const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec3 normalize(NvVec3 const &v) +{ + float l = magnitude(v); + return NvVec3(v[0] / l, v[1] / l, v[2] / l); +} + +inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], + a.v[0] * b.v[1] - a.v[1] * b.v[0]); +} + +inline bool operator==(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); +} + +inline bool operator!=(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); +} + +struct NvVec2f +{ + union { + struct + { + float x, y; + float v[2]; + }; + }; + + NvVec2f() { zero(); } + + NvVec2f(float x, float y) + { + v[0] = x; + v[1] = y; + } + + NvVec2f(NvVec2f const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + NvVec2f &operator+=(NvVec2f const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + return *this; + } + + NvVec2f &operator-=(NvVec2f const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + return *this; + } + + NvVec2f &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + return *this; + } + + NvVec2f &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + return *this; + } +}; + +inline float dot(NvVec2f const &a, NvVec2f const &b) +{ + + return a[0] * b[0] + a[1] * b[1]; +} + +inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a) +{ + + return NvVec2f(-a.v[0], -a.v[1]); +} + +inline NvVec2f operator*(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] * s, a.v[1] * s); +} + +inline NvVec2f operator*(float s, NvVec2f const &a) +{ + + return NvVec2f(s * a.v[0], s * a.v[1]); +} + +inline NvVec2f operator/(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] / s, a.v[1] / s); +} + +inline float magnitude(NvVec2f const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec2f normalize(NvVec2f const &v) +{ + float l = dot(v, v); + return NvVec2f(v[0] / l, v[1] / l); +} + +inline float cross(NvVec2f const &a, NvVec2f const &b) +{ + + return a.v[0] * b.v[1] - b.v[0] * a.v[1]; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/misc.h b/src/Runtime/Source/platformspecific/macos/libs/nv_math/misc.h new file mode 100644 index 00000000..983410f3 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/misc.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H +#define INCLUDED_QT3DS_MATH_CPP_MISC_H + +inline bool nvIsPowerOfTwo(unsigned int i) +{ + return (i & (i - 1)) == 0; +} + +inline float nvDegToRadf(float d) +{ + return d * 3.14159265358979323846f / 180.0f; +} + +inline float nvRadToDegf(float r) +{ + return r * 180.0f / 3.14159265358979323846f; +} + +/* + 'mod' differs from '%' in that it behaves correctly when either the + numerator or denominator is negative. +*/ + +inline int nvMod(int n, int d) +{ + int m = n % d; + return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; +} + +inline int nvAbs(int n) +{ + if (n < 0) + return -n; + return n; +} + +inline int nvSign(int n) +{ + if (n > 0) + return 1; + if (n < 0) + return -1; + return 0; +} + +/* + This returns the smallest amplitude value x such that + nvMod(b + x, m) == a +*/ + +inline int nvDifMod(int a, int b, int m) +{ + + int x1 = a - b; + int x2 = (x1 > 0) ? x1 - m : x1 + m; + return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; +} + +inline float nvWrapf(float a, float min, float max) +{ + + assert(max > min); + + float d = max - min; + float s = a - min; + float q = s / d; + float m = q - floorf(q); + return m * d + min; +} + +inline float nvClampf(float a, float min, float max) +{ + return (a < min) ? min : ((a > max) ? max : a); +} + +inline int nvClampi(int i, int min, int max) +{ + return (i < min) ? min : ((i > max) ? max : i); +} + +inline float nvGaussian(float x, float s) +{ + float c = s * sqrtf(2.0f * 3.14159265358979323846f); + return expf(-(x * x) / (2.0f * s * s)) / c; +} + +inline float nvLerpf(float a, float b, float t) +{ + return a * (1.0f - t) + b * t; +} + +inline float nvEasef(float t) +{ + + float t_2 = t * t; + float t_3 = t_2 * t; + return 3.0f * t_2 - 2.0f * t_3; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.cpp b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.cpp new file mode 100644 index 00000000..b83cb39e --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_math.h" + +static const double a = 16807.0; +static const double m = 2147483647.0; + +static double nextSeed(double seed) +{ + double t = a * seed; + return t - m * (double)((int)(t / m)); +} + +GLfloat NvRandf() +{ + static double seed = 1.0; + seed = nextSeed(seed); + return (GLfloat)(seed * (1 / m)); +} + +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) +{ + // kdGetTimeUST is never supposed to decrease (i.e. that + // means it can't wrap, either. IIRC, it will wrap in + // 593 years). So we ignore that option... + + // Used for frame-to-frame diffs, this will fit in 32b + // as long as the times are < ~4.3s apart + long long int diffTime = newTime - oldTime; + + // Need to find a better way to do this. + // However, I believe we will be uSec precise (not run + // out of mantissa bits for uSecs) as long as the diff + // is < ~16s (1e-6 * (2^24)) + return ((GLfloat)diffTime) / 1.0e9f; +} diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.h b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.h new file mode 100644 index 00000000..e777e409 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_math.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_MATH_H +#define _QT3DS_MATH_H + +#include + +GLfloat NvRandf(); + +/* These are the recommended "safer" ways to use GLfloat for time */ + +/* Returns the seconds between the two given times */ +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); + +#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.cpp b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.cpp new file mode 100644 index 00000000..e208ac31 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.cpp @@ -0,0 +1,1030 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_matrix.h" + +int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) +{ + return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); +} + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; +} + +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; +} + +GLfloat NvVecLengthf(const GLfloat v[3]) +{ + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) +{ + GLfloat const l = NvVecLengthf(v); + r[0] = v[0] / l; + r[1] = v[1] / l; + r[2] = v[2] / l; +} + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] + b[0]; + r[1] = a[1] + b[1]; + r[2] = a[2] + b[2]; +} + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] - b[0]; + r[1] = a[1] - b[1]; + r[2] = a[2] - b[2]; +} + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + GLfloat t[3]; + + t[0] = a[1] * b[2] - a[2] * b[1]; + t[1] = a[2] * b[0] - a[0] * b[2]; + t[2] = a[0] * b[1] - a[1] * b[0]; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; +} + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); + + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; +} + +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; + r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; +} + +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; +} + +static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; + r[3][3] = 1.0f; +} + +static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; + r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; + r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; + r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; + r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; +} + +void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) + && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { + if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) + && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { + NvMultMat3x3f(r, a, b); + } else { + NvMultMat4x3f(r, a, b); + } + } else { + NvMultMat4x4f(r, a, b); + } + + NvCopyMatf(result, r); +} + +static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + /* x */ + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + /* y */ + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + /* z */ + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = 1.0f; +} + +static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] + + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] + + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] + + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] + + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] + + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] + + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] + + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] + + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] + + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] + + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] + + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] + + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) + / d; + + r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] + + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] + + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) + / d; + + r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] + + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] + + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) + / d; + + r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] + + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] + + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) + / d; + + r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] + + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] + + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) + / d; + + r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] + + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] + + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) + / d; + + r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] + + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] + + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) + / d; + + r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] + + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] + + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) + / d; + + r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] + + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] + + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) + / d; + + r[2][1] = + (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] + + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) + / d; + + r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] + + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] + + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) + / d; + + r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] + + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] + + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) + / d; + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) + / d; +} + +void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { + if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { + NvInvMat3x3f(r, m); + } else { + NvInvMat4x3f(r, m); + } + } else { + NvInvMat4x4f(r, m); + } + + NvCopyMatf(result, r); +} + +void NvBuildIdentityMatf(GLfloat r[4][4]) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = x; + r[3][1] = y; + r[3][2] = z; + r[3][3] = 1.0f; +} + +void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, + GLfloat z) +{ + GLfloat r[4][4]; /*temporary storage for result */ + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; + r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; + r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; + r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = x; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = y; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = z; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * x; + r[0][1] = m[0][1] * x; + r[0][2] = m[0][2] * x; + r[0][3] = m[0][3] * x; + + r[1][0] = m[1][0] * y; + r[1][1] = m[1][1] * y; + r[1][2] = m[1][2] * y; + r[1][3] = m[1][3] * y; + + r[2][0] = m[2][0] * z; + r[2][1] = m[2][1] * z; + r[2][2] = m[2][2] * z; + r[2][3] = m[2][3] * z; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) +{ + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = c; + r[1][2] = s; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = -s; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = 0.0f; + r[0][2] = -s; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = s; + r[2][1] = 0.0f; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = s; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = -s; + r[1][1] = c; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0] * c + m[2][0] * s; + r[1][1] = m[1][1] * c + m[2][1] * s; + r[1][2] = m[1][2] * c + m[2][2] * s; + r[1][3] = m[1][3] * c + m[2][3] * s; + + r[2][0] = m[1][0] * -s + m[2][0] * c; + r[2][1] = m[1][1] * -s + m[2][1] * c; + r[2][2] = m[1][2] * -s + m[2][2] * c; + r[2][3] = m[1][3] * -s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[2][0] * -s; + r[0][1] = m[0][1] * c + m[2][1] * -s; + r[0][2] = m[0][2] * c + m[2][2] * -s; + r[0][3] = m[0][3] * c + m[2][3] * -s; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[0][0] * s + m[2][0] * c; + r[2][1] = m[0][1] * s + m[2][1] * c; + r[2][2] = m[0][2] * s + m[2][2] * c; + r[2][3] = m[0][3] * s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[1][0] * s; + r[0][1] = m[0][1] * c + m[1][1] * s; + r[0][2] = m[0][2] * c + m[1][2] * s; + r[0][3] = m[0][3] * c + m[1][3] * s; + + r[1][0] = m[0][0] * -s + m[1][0] * c; + r[1][1] = m[0][1] * -s + m[1][1] * c; + r[1][2] = m[0][2] * -s + m[1][2] * c; + r[1][3] = m[0][3] * -s + m[1][3] * c; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) +{ + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + /* build a matrix from the quat */ + + result[0][0] = 1.0f - 2.0f * (j * j + k * k); + result[0][1] = 2.0f * (i * j + r * k); + result[0][2] = 2.0f * (i * k - r * j); + result[0][3] = 0.0f; + + result[1][0] = 2.0f * (i * j - r * k); + result[1][1] = 1.0f - 2.0f * (i * i + k * k); + result[1][2] = 2.0f * (j * k + r * i); + result[1][3] = 0.0f; + + result[2][0] = 2.0f * (i * k + r * j); + result[2][1] = 2.0f * (j * k - r * i); + result[2][2] = 1.0f - 2.0f * (i * i + j * j); + result[2][3] = 0.0f; + + result[3][0] = 0.0f; + result[3][1] = 0.0f; + result[3][2] = 0.0f; + result[3][3] = 1.0f; +} + +void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians) +{ + GLfloat r[4][4]; + + { + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat const dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + { + /* build a matrix from the quat */ + + GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); + GLfloat const a01 = 2.0f * (i * j + r * k); + GLfloat const a02 = 2.0f * (i * k - r * j); + + GLfloat const a10 = 2.0f * (i * j - r * k); + GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); + GLfloat const a12 = 2.0f * (j * k + r * i); + + GLfloat const a20 = 2.0f * (i * k + r * j); + GLfloat const a21 = 2.0f * (j * k - r * i); + GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); + + result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; + result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; + result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; + result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; + + result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; + result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; + result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; + result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; + + result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; + result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; + result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; + result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; + + result[3][0] = m[3][0]; + result[3][1] = m[3][1]; + result[3][2] = m[3][2]; + result[3][3] = m[3][3]; + } + } + + NvCopyMatf(result, r); +} + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) +{ + NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees) +{ + NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]) +{ + GLfloat ev[3]; + GLfloat z[3]; + GLfloat x_tmp[3]; + GLfloat x[3]; + GLfloat y[3]; + + NvSubVecf(ev, eye, obj); + + NvNormalizeVecf(z, ev); + + NvCrossProductf(x_tmp, up, z); + + NvNormalizeVecf(x, x_tmp); + + NvCrossProductf(y, z, x); + + r[0][0] = x[0]; + r[0][1] = y[0]; + r[0][2] = z[0]; + r[0][3] = 0.0f; + + r[1][0] = x[1]; + r[1][1] = y[1]; + r[1][2] = z[1]; + r[1][3] = 0.0f; + + r[2][0] = x[2]; + r[2][1] = y[2]; + r[2][2] = z[2]; + r[2][3] = 0.0f; + + r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; + r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; + r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; + r[3][3] = 1.0f; +} + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const m00 = znear * 2.0f / (right - left); + GLfloat const m11 = znear * 2.0f / (top - bottom); + GLfloat const m22 = -(zfar + znear) / (zfar - znear); + + GLfloat const m20 = (right + left) / (right - left); + GLfloat const m21 = (top + bottom) / (top - bottom); + + GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); + GLfloat const m23 = -1.0f; + + r[0][0] = m00; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = m11; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = m20; + r[2][1] = m21; + r[2][2] = m22; + r[2][3] = m23; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = m32; + r[3][3] = 0.0f; +} + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + GLfloat const sz = -2.0f / (zfar - znear); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + GLfloat const tz = -(zfar + znear) / (zfar - znear); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = sz; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = tz; + r[3][3] = 1.0f; +} diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.h b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.h new file mode 100644 index 00000000..0709f117 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_matrix.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_MATRIX_H +#define INCLUDED_MATRIX_H + +#include +#include +#include + +#define KD_FLT_EPSILON 1.19209290E-07F +#define KD_DEG_TO_RAD_F 0.0174532924F +#define KD_RAD_TO_DEG_F 57.2957802F + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); + +/* vector utilities */ + +GLfloat NvVecLengthf(const GLfloat v[3]); + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); + +/* matrix utilities */ + +void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); + +void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); + +/* matrix building utilities */ + +void NvBuildIdentityMatf(GLfloat r[4][4]); + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); + +void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]); + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +/* matrix concatenation utilities */ + +void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); +void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees); + +void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); + +void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians); + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.cpp b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.cpp new file mode 100644 index 00000000..ec497941 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_quat.h" +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) +{ + memcpy(r, q, 4 * sizeof(GLfloat)); +} + +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) +{ + // Assumes that the quaternion is normalized! + GLfloat x2 = q[0] * 2.0f; + GLfloat y2 = q[1] * 2.0f; + GLfloat z2 = q[2] * 2.0f; + GLfloat xSq2 = x2 * q[0]; + GLfloat ySq2 = y2 * q[1]; + GLfloat zSq2 = z2 * q[2]; + GLfloat xy2 = x2 * q[1]; + GLfloat xz2 = x2 * q[2]; + GLfloat xw2 = x2 * q[3]; + GLfloat yz2 = y2 * q[2]; + GLfloat yw2 = y2 * q[3]; + GLfloat zw2 = z2 * q[3]; + + /* Matrix is + * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | + * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | + * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | + */ + r[0][0] = 1.0f - ySq2 - zSq2; + r[0][1] = xy2 - zw2; + r[0][2] = xz2 + yw2; + + r[1][0] = xy2 + zw2; + r[1][1] = 1.0f - xSq2 - zSq2; + r[1][2] = yz2 - xw2; + + r[2][0] = xz2 - yw2; + r[2][1] = yz2 + xw2; + r[2][2] = 1.0f - xSq2 - ySq2; +} + +void NvQuatIdentity(GLfloat r[4]) +{ + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = 1.0f; +} + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = axis[0] * sina; + r[1] = axis[1] * sina; + r[2] = axis[2] * sina; + r[3] = cosa; +} + +void NvQuatX(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = sina; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatY(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = sina; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatZ(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = sina; + r[3] = cosa; +} + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatY(h, heading); + NvQuatX(p, pitch); + NvQuatZ(ro, roll); + + NvQuatMult(r, h, p); + NvQuatMult(r, ro, r); +} + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatZ(ro, roll); + NvQuatX(p, pitch); + NvQuatY(h, heading); + + NvQuatMult(r, p, h); + NvQuatMult(r, r, ro); +} + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) +{ + return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; +} + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) +{ + const GLfloat q1x = q1[0]; + const GLfloat q1y = q1[1]; + const GLfloat q1z = q1[2]; + const GLfloat q1w = q1[3]; + const GLfloat q2x = q2[0]; + const GLfloat q2y = q2[1]; + const GLfloat q2z = q2[2]; + const GLfloat q2w = q2[3]; + + r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; + r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; + r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; + r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; +} + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) +{ + GLfloat omt = 1.0f - t; + + if (NvQuatDot(q1, q2) < 0.0f) { + r[0] = -q1[0] * omt + q2[0] * t; + r[1] = -q1[1] * omt + q2[1] * t; + r[2] = -q1[2] * omt + q2[2] * t; + r[3] = -q1[3] * omt + q2[3] * t; + } else { + r[0] = q1[0] * omt + q2[0] * t; + r[1] = q1[1] * omt + q2[1] * t; + r[2] = q1[2] * omt + q2[2] * t; + r[3] = q1[3] * omt + q2[3] * t; + } + + NvQuatNormalize(r, r); +} + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) +{ + GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); + + r[0] = invLength * q[0]; + r[1] = invLength * q[1]; + r[2] = invLength * q[2]; + r[3] = invLength * q[3]; +} diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.h b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.h new file mode 100644 index 00000000..2afdcb71 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_math/nv_quat.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QUAT_H +#define INCLUDED_QUAT_H + +#include +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); + +void NvQuatIdentity(GLfloat r[4]); + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); + +void NvQuatX(GLfloat r[4], GLfloat radians); + +void NvQuatY(GLfloat r[4], GLfloat radians); + +void NvQuatZ(GLfloat r[4], GLfloat radians); + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); + +#endif diff --git a/src/Runtime/Source/platformspecific/macos/libs/nv_types.h b/src/Runtime/Source/platformspecific/macos/libs/nv_types.h new file mode 100644 index 00000000..1d1b0300 --- /dev/null +++ b/src/Runtime/Source/platformspecific/macos/libs/nv_types.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_TYPES_H +#define __INCLUDED_QT3DS_TYPES_H + +typedef unsigned char NvU8; // 0 to 255 +typedef unsigned short NvU16; // 0 to 65535 +typedef unsigned int NvU32; // 0 to 4294967295 +typedef unsigned long long NvU64; // 0 to 18446744073709551615 +typedef signed char NvS8; // -128 to 127 +typedef signed short NvS16; // -32768 to 32767 +typedef signed int NvS32; // -2147483648 to 2147483647 +typedef signed long long NvS64; // 2^-63 to 2^63-1 + +// Explicitly sized floats +typedef float NvF32; // IEEE Single Precision (S1E8M23) +typedef double NvF64; // IEEE Double Precision (S1E11M52) + +// Boolean type +#define QT3DS_FALSE 0 +#define QT3DS_TRUE 1 +typedef NvU8 NvBool; + +// Result of sizeof operator +typedef unsigned long NvSize; + +// Type large enough to hold a relative file offset +typedef long NvOffset; + +// Base NULL type. +#define QT3DS_NULL 0 + +// Error related +typedef enum { + NvError_Success = 0, + NvError_NotSupported, + NvError_NotInitialized, + NvError_BadParameter, + NvError_InsufficientMemory, + NvError_NoEntries, + NvError_UnknownError, +} NvError; + +#if 1 // defined(_DEBUG) // !!!!TBD TODO +#define NvAssert(c) +#else +#define NvAssert(c) ((void)((c) ? 0 : (NvHandleAssertion(#c, __FILE__, __LINE__), 0))) +#endif + +// Other standardized typedefs +typedef NvU64 NvUST; // U64 unadjusted system time value + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.abc b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.abc new file mode 100644 index 00000000..f7e3c2f6 Binary files /dev/null and b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.abc differ diff --git a/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.dds b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.dds new file mode 100644 index 00000000..5bde760b Binary files /dev/null and b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_256.dds differ diff --git a/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.abc b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.abc new file mode 100644 index 00000000..2ff78757 Binary files /dev/null and b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.abc differ diff --git a/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.dds b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.dds new file mode 100644 index 00000000..f9e76d94 Binary files /dev/null and b/src/Runtime/Source/platformspecific/windows/assets/courier+lucida_512.dds differ diff --git a/src/Runtime/Source/platformspecific/windows/assets/font.frag b/src/Runtime/Source/platformspecific/windows/assets/font.frag new file mode 100644 index 00000000..e4673cf8 --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/assets/font.frag @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +uniform sampler2D fontTex; + +varying lowp vec4 col_var; +varying lowp vec2 tex_var; + +void main() +{ + gl_FragColor = texture2D(fontTex, tex_var).a * col_var; +} + diff --git a/src/Runtime/Source/platformspecific/windows/assets/font.vert b/src/Runtime/Source/platformspecific/windows/assets/font.vert new file mode 100644 index 00000000..9f307a2f --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/assets/font.vert @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// this is set from higher level. think of it as the upper model matrix +uniform mat4 pixelToClipMat; + +uniform vec4 col_uni; + +attribute vec2 pos_attr; +attribute vec2 tex_attr; +attribute vec4 col_attr; + +varying vec4 col_var; +varying vec2 tex_var; + +void main() +{ + // account for translation and rotation of the primitive into [-1,1] spatial default. + gl_Position = pixelToClipMat * vec4(pos_attr.x, pos_attr.y, 0, 1); + + col_var = col_attr * col_uni; + tex_var = tex_attr; +} diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_color.h b/src/Runtime/Source/platformspecific/windows/libs/nv_color.h new file mode 100644 index 00000000..b9347529 --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_color.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_COLOR_H +#define _QT3DS_COLOR_H + +/** @file nv_color.h + Simple abstraction for RGBA colors as parameters to various libraries/functions. +*/ + +/** Base type for a single color channel (8-bit unsigned). */ +typedef unsigned char NvPCColor8; + +//#define NV_COLOR_BREAKOLD +#ifdef NV_COLOR_BREAKOLD // uses a struct to break backwards-compat and accidental uses + +typedef struct +{ + NvPCColor8 r; + NvPCColor8 g; + NvPCColor8 b; + NvPCColor8 a; +} NvPackedColor; + +static const NvPackedColor gnvpcwhite = { 255, 255, 255, 255 }; +static const NvPackedColor gnvpcblack = { 0, 0, 0, 255 }; + +#define NV_PACKED_COLOR(r, g, b, a) \ + { \ + (NvPCColor8)(r), (NvPCColor8)(g), (NvPCColor8)(b), (NvPCColor8)(a) \ + } + +#define NV_PC_PREDEF_WHITE gnvpcwhite +#define NV_PC_PREDEF_BLACK gnvpcblack + +#define NV_PC_RED(c) (c.r) +#define NV_PC_GREEN(c) (c.g) +#define NV_PC_BLUE(c) (c.b) +#define NV_PC_ALPHA(c) (c.a) + +#define NV_PC_PACK_UINT(c) (*(unsigned int *)(&(c))) + +#define NV_PC_EQUAL(x, y) ((x).r == (y).r && (x).g == (y).g && (x).b == (y).b && (x).a == (y).a) + +#else /* code that doesn't break old pass-as-uint stuff */ + +/** Main type declaration for a packed 4-color construct. */ +typedef unsigned int NvPackedColor; + +/** A macro to build a packed color, passing in RGBA as four 8-bit integer values. */ +#define NV_PACKED_COLOR(r, g, b, a) \ + ((NvPackedColor)(((((int)(a)) & 0xFF) << 24) | ((((int)(b)) & 0xFF) << 16) \ + | ((((int)(g)) & 0xFF) << 8) | ((((int)(r)) & 0xFF)))) + +/** A predefined constant for WHITE. */ +#define NV_PC_PREDEF_WHITE NV_PACKED_COLOR(0xFF, 0xFF, 0xFF, 0xFF) +/** A predefined constant for BLACK. */ +#define NV_PC_PREDEF_BLACK NV_PACKED_COLOR(0x00, 0x00, 0x00, 0xFF) + +/** A macro for 'extracting' the red value from an NvPackedColor. */ +#define NV_PC_RED(c) ((c >> 0) & 0xff) +/** A macro for 'extracting' the green value from an NvPackedColor. */ +#define NV_PC_GREEN(c) ((c >> 8) & 0xff) +/** A macro for 'extracting' the blue value from an NvPackedColor. */ +#define NV_PC_BLUE(c) ((c >> 16) & 0xff) +/** A macro for 'extracting' the alpha value from an NvPackedColor. */ +#define NV_PC_ALPHA(c) ((c >> 24) & 0xff) + +/** A macro requesting the packed color repacked into a 32-bit unsigned int. + This is a no-op for the color-as-uint approach. +*/ +#define NV_PC_PACK_UINT(c) (c) +/** A macro for testing the equality of two NvPackedColors. */ +#define NV_PC_EQUAL(x, y) (x == y) +#endif + +/** A macro for mapping a single packed color channel into its floating point [0,1] rep. */ +#define NV_PC_TO_FLOAT(c) (c / 255.0f) + +#endif /*_QT3DS_COLOR_H*/ diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_config/nv_config.h b/src/Runtime/Source/platformspecific/windows/libs/nv_config/nv_config.h new file mode 100644 index 00000000..fb0b88af --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_config/nv_config.h @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2008 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef _QT3DS_CONFIG_H +#define _QT3DS_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \file nv_config.h + Support for block-based text config files. + + Supports: +
    +
  • C-style comment blocks +
  • C++-style comment lines +
  • Line continuation via backslash +
  • Linux, Mac and Windows line endings +
  • Arrays of tokens, broken out by line +
  • Tokens are split by commas and whitespace +
  • Quoted string tokens containing any characters +
+ */ + +/** The in-memory representation of a loaded config file. + + This opaque data structure is passed by pointer to all of the + configuration functions and represents the loaded configuration + file. Once loaded, there is no mutable persistent state in this + object. It is passed as const to all functions +*/ +typedef struct NvConfigData NvConfigData; + +/** The representation of a sub-range of lines in a config file. + + This structure is application-readable and mutable, and is used to + represent a subset of the lines in a config file. Generally, these + ranges represent delineated blocks in the config file. Special versions + of many of the config file functions take data ranges instead of + entire config files + + @see NvConfigFindDelimitedBlock() +*/ +typedef struct NvConfigDataRange +{ + /** A reference to the "parent" config file for this range */ + NvConfigData *data; + /** The first line of the range (inclusive) */ + KDint startLine; + /** The last line of the range (inclusive) */ + KDint endLine; +} NvConfigDataRange; + +/** Creates a config data object that represents an existing config file + + @return A pointer to the allocated config data, or NULL if the file cannot + be found or does not conform to the basic config file format + @param filename The path of the config file to be loaded + @see NvConfigFree() +*/ +NvConfigData *NvConfigCreateFromFile(const KDchar *filename); + +/** Creates a config data object from an-in memory string + + Useful when the config file is loaded from a larger, packed data file, + or generated on-the-fly in the application. Note that the code does not + automatically handle NULL-terminated strings + + @return A pointer to the allocated config data, or NULL if the string + does not conform to the basic config file format + @param fileBuffer A pointer to the start of the string of config data + @param fileSize The length of the string in characters + @see NvConfigFree() +*/ +NvConfigData *NvConfigCreateFromBuffer(const KDchar *fileBuffer, KDint fileSize); + +/** Deletes an existing config file data object + + @param data A pointer to the data object to delete +*/ +void NvConfigFree(NvConfigData *data); + +/** Returns the number of token-bearing lines in the config data object. + + This does not count merged lines, comment lines, or whitespace. This + value is one greater than the maximum valid line index in the file + + @return The line count + @param data A pointer to the data object +*/ +KDint NvConfigGetLineCount(const NvConfigData *data); + +/** Returns the number of tokens in the indexed line + + @return The token count + @param data A pointer to the data object + @param line The line whose count is to be returned. This parameter must + be at least 0 and must be less than the line count of the object + @see NvConfigGetLineCount +*/ +KDint NvConfigGetTokenCount(const NvConfigData *data, KDint line); + +/** Returns a NULL-terminated string token at the given line and token index + + The parameters are unchecked. + + @return A non-mutable token pointer for the referenced token + @param data A pointer to the data object + @param line The line whose token is to be returned. This parameter must + be at least 0 and must be less than the line count of the object + @param token The token index of the token to be returned. This parameter must + be at least 0 and must be less than the token count of the line + @see NvConfigGetLineCount + @see NvConfigGetTokenCount +*/ +const KDchar *NvConfigGetToken(const NvConfigData *data, KDint line, KDint token); + +/** Returns the string token converted to an integer + + Returns the string token at the given line and token index converted to an integer. + The parameters are unchecked, and the string token is assumed to be convertible to + an integer value. + + @return The integer value of the referenced token + @param data A pointer to the data object + @param line The line whose token is to be returned. This parameter must + be at least 0 and must be less than the line count of the object + @param token The token index of the token to be returned. This parameter must + be at least 0 and must be less than the token count of the line + @see NvConfigGetLineCount + @see NvConfigGetTokenCount +*/ +KDint NvConfigGetIntToken(const NvConfigData *data, KDint line, KDint token); + +/** Returns the string token converted to a floating-point value + + Returns the string token at the given line and token index converted to a + floating-point number. The parameters are unchecked, and the string token + is assumed to be convertible to a real value. + + @return The floating-point value of the referenced token + @param data A pointer to the data object + @param line The line whose token is to be returned. This parameter must + be at least 0 and must be less than the line count of the object + @param token The token index of the token to be returned. This parameter must + be at least 0 and must be less than the token count of the line + @see NvConfigGetLineCount + @see NvConfigGetTokenCount +*/ +KDfloat32 NvConfigGetFloatToken(const NvConfigData *data, KDint line, KDint token); + +/** Returns the count of lines in the config data whose leading token + matches a given string + + The search starts at the indicated line and continues to the end of the file + + @return The count of matching lines + @param data A pointer to the data object + @param name The string to be matched (case-sensitive) + @param startLine The line at which the search should start. This parameter must + be at least 0 and must be less than the line count of the object + @see NvConfigGetLineCount +*/ +KDint NvConfigCountMatchingLines(const NvConfigData *data, const KDchar *name, KDint startLine); + +/** Returns the count of lines in the subrange of the config data + whose leading token matches a given string + + The search is run only in the given subrange of the file + + @return The count of matching lines + @param range A pointer to the subrange of the data object + @param name The string to be matched (case-sensitive) +*/ +KDint NvConfigCountMatchingLinesInRange(const NvConfigDataRange *range, const KDchar *name); + +/** Returns the index of the first line in the config data (at or after + the given start line) whose leading token matches a given string + + The search starts at the indicated line and continues to the end of the + file + + @return The index of the first matching line, or -1 if no match + @param data A pointer to the data object + @param name The string to be matched (case-sensitive) + @param startLine The line at which the search should start. This parameter must + be at least 0 and must be less than the line count of the object + @see NvConfigGetLineCount +*/ +KDint NvConfigFindMatchingLine(const NvConfigData *data, const KDchar *name, KDint startLine); + +/** Returns the index of the first line in the subrange of the config data + whose leading token matches a given string + + The search is run only in the given subrange of the file + + @return The index of the first matching line, or -1 if no match + @param range A pointer to the subrange of the data object + @param name The string to be matched (case-sensitive) +*/ +KDint NvConfigFindMatchingLineInRange(const NvConfigDataRange *range, const KDchar *name); + +/** Finds a matching token-delimited block in the file and returns it as a subrange. + + Searches for a token-delimited open/close block in the given line range. + If the nested parameter is true, then additional nested open/close blocks + are tracked and the returned block is the one that properly closes the + given open block. If the nested flag is false, then the open/close are + treated like C-comments, and the first closing token found is returned + + @return KD_TRUE if a block with both an open and a close token is found, + KD_FALSE otherwise + @param data A pointer to the data object + @param openText The string token to be matched as the start of a block. + (case-sensitive) Only the leading token of each line is tested + @param closeText The string token to be matched as the end of a block. + (case-sensitive) Only the leading token of each line is tested + @param nested If KD_TRUE, C-bracket-style nesting is used to determine + which end token is matched. If KD_FALSE, C-comment-style flat matching + is used to match the end token. + @param startLine The index of the first line to search (inclusive) + @param endLine The index of the last line to search (inclusive) + @param range Output: A pointer to the subrange of the data object. This + should be a pointer to an allocated struct +*/ +KDboolean NvConfigFindDelimitedBlock(const NvConfigData *data, const KDchar *openText, + const KDchar *closeText, KDboolean nested, KDint startLine, + KDint endLine, NvConfigDataRange *range); + +/** Returns the index of the first matching token in the given line + + Returns the index of the first token on the given line (if any) that + matches the given string. + + @return The index of the matching string token in the line, or else -1 if + the token is not found in the line + @param data A pointer to the data object + @param token The string to be matched (case-sensitive) + @param line The line to search. This parameter must + be at least 0 and must be less than the line count of the object + @see NvConfigGetLineCount +*/ +KDint NvConfigFindMatchingTokenInLine(const NvConfigData *data, const KDchar *token, KDint line); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_debug.h b/src/Runtime/Source/platformspecific/windows/libs/nv_debug.h new file mode 100644 index 00000000..2559dd6f --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_debug.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_DEBUG_H +#define __INCLUDED_QT3DS_DEBUG_H + +#define CT_ASSERT(tag, cond) enum { COMPILE_TIME_ASSERT__##tag = 1 / (cond) } + +#define dimof(x) (sizeof(x) / sizeof(x[0])) +#include + +#define DBG_DETAILED 0 + +#if 0 + + // the detailed prefix can be customised by setting DBG_DETAILED_PREFIX. See + // below as a reference. + // NOTE: fmt is the desired format string and must be in the prefix. + //#ifndef DBG_DETAILED_PREFIX + // #define DBG_DETAILED_PREFIX "%s, %s, line %d: " fmt, __FILE__, __FUNCTION__, __LINE__, + //#endif + //#define DEBUG_D_(fmt, args...) + //#define DEBUG_D(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, (DBG_DETAILED_PREFIX) ## args) + +#else + +#ifdef STRINGIFY +#pragma push_macro("STRINGIFY") +#undef STRINGIFY +#define STRINGIFYPUSHED_____ +#endif +#define STRINGIFY(x) #x + +// debug macro, includes file name function name and line number +#define TO(x) typeof(x) +#define DEBUG_D_(file, line, fmt, args...) \ + __android_log_print(ANDROID_LOG_DEBUG, MODULE, file ", %s, line(" STRINGIFY(line) "): " fmt, \ + __FUNCTION__, ##args) +#define DEBUG_D(fmt, args...) DEBUG_D_(__FILE__, __LINE__, fmt, ##args) + +#ifdef STRINGIFYPUSHED_____ +#undef STRINGIFYPUSHED_____ +#pragma pop_macro("STRINGIFY") +#endif + +#endif + +// basic debug macro +#define DEBUG_(fmt, args...) (__android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args)) + +// Debug macro that can be switched to spew a file name, +// function and line number using DEBUG_DETAILED +#if DBG_DETAILED == 1 +#define DEBUG(fmt, args...) DEBUG_D(fmt, ##args) +#else +#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, MODULE, fmt, ##args) +#endif + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_global.h b/src/Runtime/Source/platformspecific/windows/libs/nv_global.h new file mode 100644 index 00000000..9d23d45f --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_global.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_GLOBAL_H +#define __INCLUDED_QT3DS_GLOBAL_H + +#include "nv_types.h" + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/NvVec.h b/src/Runtime/Source/platformspecific/windows/libs/nv_math/NvVec.h new file mode 100644 index 00000000..4e5b09ce --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/NvVec.h @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_VEC_H +#define INCLUDED_QT3DS_MATH_CPP_VEC_H + +#include "misc.h" + +struct _NvVec3 +{ + union { + struct + { + float x, y, z; + }; + float v[3]; + }; +}; + +struct NvVec3 : public _NvVec3 +{ + NvVec3() { zero(); } + + NvVec3(float x, float y, float z) + { + v[0] = x; + v[1] = y; + v[2] = z; + } + + NvVec3(NvVec3 const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + v[2] = that.v[2]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + v[2] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 3) && (i >= 0)); + return v[i]; + } + + NvVec3 &operator+=(NvVec3 const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + v[2] += that.v[2]; + return *this; + } + + NvVec3 &operator-=(NvVec3 const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + v[2] -= that.v[2]; + return *this; + } + + NvVec3 &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + v[2] *= s; + return *this; + } + + NvVec3 &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + v[2] /= s; + return *this; + } +}; + +inline float dot(NvVec3 const &a, NvVec3 const &b) +{ + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +inline NvVec3 operator+(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] + b.v[0], a.v[1] + b.v[1], a.v[2] + b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[0] - b.v[0], a.v[1] - b.v[1], a.v[2] - b.v[2]); +} + +inline NvVec3 operator-(NvVec3 const &a) +{ + + return NvVec3(-a.v[0], -a.v[1], -a.v[2]); +} + +inline NvVec3 operator*(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] * s, a.v[1] * s, a.v[2] * s); +} + +inline NvVec3 operator*(float s, NvVec3 const &a) +{ + + return NvVec3(s * a.v[0], s * a.v[1], s * a.v[2]); +} + +inline NvVec3 operator/(NvVec3 const &a, float s) +{ + + return NvVec3(a.v[0] / s, a.v[1] / s, a.v[2] / s); +} + +inline float magnitude(NvVec3 const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec3 normalize(NvVec3 const &v) +{ + float l = magnitude(v); + return NvVec3(v[0] / l, v[1] / l, v[2] / l); +} + +inline NvVec3 cross(NvVec3 const &a, NvVec3 const &b) +{ + + return NvVec3(a.v[1] * b.v[2] - a.v[2] * b.v[1], a.v[2] * b.v[0] - a.v[0] * b.v[2], + a.v[0] * b.v[1] - a.v[1] * b.v[0]); +} + +inline bool operator==(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] == b.v[0] && a.v[1] == b.v[1] && a.v[2] == b.v[2]); +} + +inline bool operator!=(NvVec3 const &a, NvVec3 const &b) +{ + return (a.v[0] != b.v[0] || a.v[1] != b.v[1] || a.v[2] != b.v[2]); +} + +struct NvVec2f +{ + union { + struct + { + float x, y; + float v[2]; + }; + }; + + NvVec2f() { zero(); } + + NvVec2f(float x, float y) + { + v[0] = x; + v[1] = y; + } + + NvVec2f(NvVec2f const &that) + { + v[0] = that.v[0]; + v[1] = that.v[1]; + } + + inline void zero() + { + v[0] = 0.0f; + v[1] = 0.0f; + } + + inline float &operator[](int i) + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + inline float const &operator[](int i) const + { + assert((i < 2) && (i >= 0)); + return v[i]; + } + + NvVec2f &operator+=(NvVec2f const &that) + { + v[0] += that.v[0]; + v[1] += that.v[1]; + return *this; + } + + NvVec2f &operator-=(NvVec2f const &that) + { + v[0] -= that.v[0]; + v[1] -= that.v[1]; + return *this; + } + + NvVec2f &operator*=(float s) + { + v[0] *= s; + v[1] *= s; + return *this; + } + + NvVec2f &operator/=(float s) + { + v[0] /= s; + v[1] /= s; + return *this; + } +}; + +inline float dot(NvVec2f const &a, NvVec2f const &b) +{ + + return a[0] * b[0] + a[1] * b[1]; +} + +inline NvVec2f operator+(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] + b.v[0], a.v[1] + b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a, NvVec2f const &b) +{ + + return NvVec2f(a.v[0] - b.v[0], a.v[1] - b.v[1]); +} + +inline NvVec2f operator-(NvVec2f const &a) +{ + + return NvVec2f(-a.v[0], -a.v[1]); +} + +inline NvVec2f operator*(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] * s, a.v[1] * s); +} + +inline NvVec2f operator*(float s, NvVec2f const &a) +{ + + return NvVec2f(s * a.v[0], s * a.v[1]); +} + +inline NvVec2f operator/(NvVec2f const &a, float s) +{ + + return NvVec2f(a.v[0] / s, a.v[1] / s); +} + +inline float magnitude(NvVec2f const &v) +{ + return sqrtf(dot(v, v)); +} + +inline NvVec2f normalize(NvVec2f const &v) +{ + float l = dot(v, v); + return NvVec2f(v[0] / l, v[1] / l); +} + +inline float cross(NvVec2f const &a, NvVec2f const &b) +{ + + return a.v[0] * b.v[1] - b.v[0] * a.v[1]; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/misc.h b/src/Runtime/Source/platformspecific/windows/libs/nv_math/misc.h new file mode 100644 index 00000000..983410f3 --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/misc.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QT3DS_MATH_CPP_MISC_H +#define INCLUDED_QT3DS_MATH_CPP_MISC_H + +inline bool nvIsPowerOfTwo(unsigned int i) +{ + return (i & (i - 1)) == 0; +} + +inline float nvDegToRadf(float d) +{ + return d * 3.14159265358979323846f / 180.0f; +} + +inline float nvRadToDegf(float r) +{ + return r * 180.0f / 3.14159265358979323846f; +} + +/* + 'mod' differs from '%' in that it behaves correctly when either the + numerator or denominator is negative. +*/ + +inline int nvMod(int n, int d) +{ + int m = n % d; + return (((m < 0) && (d > 0)) || ((m > 0) && (d < 0))) ? (m + d) : m; +} + +inline int nvAbs(int n) +{ + if (n < 0) + return -n; + return n; +} + +inline int nvSign(int n) +{ + if (n > 0) + return 1; + if (n < 0) + return -1; + return 0; +} + +/* + This returns the smallest amplitude value x such that + nvMod(b + x, m) == a +*/ + +inline int nvDifMod(int a, int b, int m) +{ + + int x1 = a - b; + int x2 = (x1 > 0) ? x1 - m : x1 + m; + return (nvAbs(x1) < nvAbs(x2)) ? x1 : x2; +} + +inline float nvWrapf(float a, float min, float max) +{ + + assert(max > min); + + float d = max - min; + float s = a - min; + float q = s / d; + float m = q - floorf(q); + return m * d + min; +} + +inline float nvClampf(float a, float min, float max) +{ + return (a < min) ? min : ((a > max) ? max : a); +} + +inline int nvClampi(int i, int min, int max) +{ + return (i < min) ? min : ((i > max) ? max : i); +} + +inline float nvGaussian(float x, float s) +{ + float c = s * sqrtf(2.0f * 3.14159265358979323846f); + return expf(-(x * x) / (2.0f * s * s)) / c; +} + +inline float nvLerpf(float a, float b, float t) +{ + return a * (1.0f - t) + b * t; +} + +inline float nvEasef(float t) +{ + + float t_2 = t * t; + float t_3 = t_2 * t; + return 3.0f * t_2 - 2.0f * t_3; +} + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.cpp b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.cpp new file mode 100644 index 00000000..b83cb39e --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_math.h" + +static const double a = 16807.0; +static const double m = 2147483647.0; + +static double nextSeed(double seed) +{ + double t = a * seed; + return t - m * (double)((int)(t / m)); +} + +GLfloat NvRandf() +{ + static double seed = 1.0; + seed = nextSeed(seed); + return (GLfloat)(seed * (1 / m)); +} + +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime) +{ + // kdGetTimeUST is never supposed to decrease (i.e. that + // means it can't wrap, either. IIRC, it will wrap in + // 593 years). So we ignore that option... + + // Used for frame-to-frame diffs, this will fit in 32b + // as long as the times are < ~4.3s apart + long long int diffTime = newTime - oldTime; + + // Need to find a better way to do this. + // However, I believe we will be uSec precise (not run + // out of mantissa bits for uSecs) as long as the diff + // is < ~16s (1e-6 * (2^24)) + return ((GLfloat)diffTime) / 1.0e9f; +} diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.h b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.h new file mode 100644 index 00000000..ec729a79 --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_math.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _QT3DS_MATH_H +#define _QT3DS_MATH_H + +#include + +GLfloat NvRandf(); + +/* These are the recommended "safer" ways to use GLfloat for time */ + +/* Returns the seconds between the two given times */ +GLfloat NvClockDiffInSecs(long long int newTime, long long int oldTime); + +#define QT3DS_MILISECS_TO_UST(ms) ((long long int)(ms)*1000000) + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.cpp b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.cpp new file mode 100644 index 00000000..e208ac31 --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.cpp @@ -0,0 +1,1030 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_matrix.h" + +int NvDifferentMatsf(GLfloat a[4][4], const GLfloat b[4][4]) +{ + return ((&a[3][3] < &b[0][0]) || (&b[3][3] < &a[0][0])); +} + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; +} + +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]) +{ + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; +} + +GLfloat NvVecLengthf(const GLfloat v[3]) +{ + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]) +{ + GLfloat const l = NvVecLengthf(v); + r[0] = v[0] / l; + r[1] = v[1] / l; + r[2] = v[2] / l; +} + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] + b[0]; + r[1] = a[1] + b[1]; + r[2] = a[2] + b[2]; +} + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + r[0] = a[0] - b[0]; + r[1] = a[1] - b[1]; + r[2] = a[2] - b[2]; +} + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]) +{ + GLfloat t[3]; + + t[0] = a[1] * b[2] - a[2] * b[1]; + t[1] = a[2] * b[0] - a[0] * b[2]; + t[2] = a[0] * b[1] - a[1] * b[0]; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; +} + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + GLfloat inv_w = 1.0f / (m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3]); + + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * inv_w; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * inv_w; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * inv_w; +} + +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0] * a[3]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1] * a[3]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2] * a[3]; + r[3] = m[0][3] * a[0] + m[1][3] * a[1] + m[2][3] * a[2] + m[3][3] * a[3]; +} + +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]) +{ + r[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2]; + r[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2]; + r[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2]; +} + +static void NvMultMat3x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvMultMat4x3f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2]; + r[0][3] = 0.0f; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2]; + r[1][3] = 0.0f; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2]; + r[2][3] = 0.0f; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2]; + r[3][3] = 1.0f; +} + +static void NvMultMat4x4f(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + assert(NvDifferentMatsf(r, a) && NvDifferentMatsf(r, b)); + + r[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2] + a[3][0] * b[0][3]; + r[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2] + a[3][1] * b[0][3]; + r[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2] + a[3][2] * b[0][3]; + r[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + a[2][3] * b[0][2] + a[3][3] * b[0][3]; + + r[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2] + a[3][0] * b[1][3]; + r[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]; + r[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]; + r[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]; + + r[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2] + a[3][0] * b[2][3]; + r[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]; + r[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]; + r[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]; + + r[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + a[2][0] * b[3][2] + a[3][0] * b[3][3]; + r[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]; + r[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]; + r[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]; +} + +void NvMultMatf(GLfloat result[4][4], const GLfloat a[4][4], const GLfloat b[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((a[0][3] == 0.0f) && (a[1][3] == 0.0f) && (a[2][3] == 0.0f) && (a[2][3] == 1.0f) + && (b[0][3] == 0.0f) && (b[1][3] == 0.0f) && (b[2][3] == 0.0f) && (b[2][3] == 1.0f)) { + if ((a[3][0] == 0.0f) && (a[3][1] == 0.0f) && (a[3][2] == 0.0f) && (b[3][0] == 0.0f) + && (b[3][1] == 0.0f) && (b[3][2] == 0.0f)) { + NvMultMat3x3f(r, a, b); + } else { + NvMultMat4x3f(r, a, b); + } + } else { + NvMultMat4x4f(r, a, b); + } + + NvCopyMatf(result, r); +} + +static void NvInvMat3x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +static void NvInvMat4x3f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + -m[0][1] * m[1][0] * m[2][2] + + -m[0][2] * m[1][1] * m[2][0]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d; + r[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / d; + r[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d; + r[0][3] = 0.0f; + + r[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / d; + r[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d; + r[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / d; + r[1][3] = 0.0f; + + r[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d; + r[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / d; + r[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d; + r[2][3] = 0.0f; + + /* x */ + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + /* y */ + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + /* z */ + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = 1.0f; +} + +static void NvInvMat4x4f(GLfloat r[4][4], const GLfloat m[4][4]) +{ + GLfloat d = m[0][0] * m[1][1] * m[2][2] * m[3][3] + m[0][0] * m[1][2] * m[2][3] * m[3][1] + + m[0][0] * m[1][3] * m[2][1] * m[3][2] + m[0][1] * m[1][0] * m[2][3] * m[3][2] + + m[0][1] * m[1][2] * m[2][0] * m[3][3] + m[0][1] * m[1][3] * m[2][2] * m[3][0] + + m[0][2] * m[1][0] * m[2][1] * m[3][3] + m[0][2] * m[1][1] * m[2][3] * m[3][0] + + m[0][2] * m[1][3] * m[2][0] * m[3][1] + m[0][3] * m[1][0] * m[2][2] * m[3][1] + + m[0][3] * m[1][1] * m[2][0] * m[3][2] + m[0][3] * m[1][2] * m[2][1] * m[3][0] + + -m[0][0] * m[1][1] * m[2][3] * m[3][2] + -m[0][0] * m[1][2] * m[2][1] * m[3][3] + + -m[0][0] * m[1][3] * m[2][2] * m[3][1] + -m[0][1] * m[1][0] * m[2][2] * m[3][3] + + -m[0][1] * m[1][2] * m[2][3] * m[3][0] + -m[0][1] * m[1][3] * m[2][0] * m[3][2] + + -m[0][2] * m[1][0] * m[2][3] * m[3][1] + -m[0][2] * m[1][1] * m[2][0] * m[3][3] + + -m[0][2] * m[1][3] * m[2][1] * m[3][0] + -m[0][3] * m[1][0] * m[2][1] * m[3][2] + + -m[0][3] * m[1][1] * m[2][2] * m[3][0] + -m[0][3] * m[1][2] * m[2][0] * m[3][1]; + + assert(NvDifferentMatsf(r, m)); + + r[0][0] = (m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + + m[1][3] * m[2][1] * m[3][2] + -m[1][1] * m[2][3] * m[3][2] + + -m[1][2] * m[2][1] * m[3][3] + -m[1][3] * m[2][2] * m[3][1]) + / d; + + r[0][1] = (m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] + + m[0][3] * m[2][2] * m[3][1] + -m[0][1] * m[2][2] * m[3][3] + + -m[0][2] * m[2][3] * m[3][1] + -m[0][3] * m[2][1] * m[3][2]) + / d; + + r[0][2] = (m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] + + m[0][3] * m[1][1] * m[3][2] + -m[0][1] * m[1][3] * m[3][2] + + -m[0][2] * m[1][1] * m[3][3] + -m[0][3] * m[1][2] * m[3][1]) + / d; + + r[0][3] = (m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] + + m[0][3] * m[1][2] * m[2][1] + -m[0][1] * m[1][2] * m[2][3] + + -m[0][2] * m[1][3] * m[2][1] + -m[0][3] * m[1][1] * m[2][2]) + / d; + + r[1][0] = (m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] + + m[1][3] * m[2][2] * m[3][0] + -m[1][0] * m[2][2] * m[3][3] + + -m[1][2] * m[2][3] * m[3][0] + -m[1][3] * m[2][0] * m[3][2]) + / d; + + r[1][1] = (m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] + + m[0][3] * m[2][0] * m[3][2] + -m[0][0] * m[2][3] * m[3][2] + + -m[0][2] * m[2][0] * m[3][3] + -m[0][3] * m[2][2] * m[3][0]) + / d; + + r[1][2] = (m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] + + m[0][3] * m[1][2] * m[3][0] + -m[0][0] * m[1][2] * m[3][3] + + -m[0][2] * m[1][3] * m[3][0] + -m[0][3] * m[1][0] * m[3][2]) + / d; + + r[1][3] = (m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] + + m[0][3] * m[1][0] * m[2][2] + -m[0][0] * m[1][3] * m[2][2] + + -m[0][2] * m[1][0] * m[2][3] + -m[0][3] * m[1][2] * m[2][0]) + / d; + + r[2][0] = (m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] + + m[1][3] * m[2][0] * m[3][1] + -m[1][0] * m[2][3] * m[3][1] + + -m[1][1] * m[2][0] * m[3][3] + -m[1][3] * m[2][1] * m[3][0]) + / d; + + r[2][1] = + (-m[0][0] * m[2][1] * m[3][3] + -m[0][1] * m[2][3] * m[3][0] + -m[0][3] * m[2][0] * m[3][1] + + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] + m[0][3] * m[2][1] * m[3][0]) + / d; + + r[2][2] = (m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] + + m[0][3] * m[1][0] * m[3][1] + -m[0][0] * m[1][3] * m[3][1] + + -m[0][1] * m[1][0] * m[3][3] + -m[0][3] * m[1][1] * m[3][0]) + / d; + + r[2][3] = (m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] + + m[0][3] * m[1][1] * m[2][0] + -m[0][1] * m[1][3] * m[2][0] + + -m[0][3] * m[1][0] * m[2][1] + -m[0][0] * m[1][1] * m[2][3]) + / d; + + r[3][0] = (m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + + m[1][2] * m[2][1] * m[3][0] + -m[1][0] * m[2][1] * m[3][2] + + -m[1][1] * m[2][2] * m[3][0] + -m[1][2] * m[2][0] * m[3][1]) + / d; + + r[3][1] = (m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + + m[0][2] * m[2][0] * m[3][1] + -m[0][0] * m[2][2] * m[3][1] + + -m[0][1] * m[2][0] * m[3][2] + -m[0][2] * m[2][1] * m[3][0]) + / d; + + r[3][2] = (m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + + m[0][2] * m[1][1] * m[3][0] + -m[0][0] * m[1][1] * m[3][2] + + -m[0][1] * m[1][2] * m[3][0] + -m[0][2] * m[1][0] * m[3][1]) + / d; + + r[3][3] = (m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + + m[0][2] * m[1][0] * m[2][1] + -m[0][0] * m[1][2] * m[2][1] + + -m[0][1] * m[1][0] * m[2][2] + -m[0][2] * m[1][1] * m[2][0]) + / d; +} + +void NvInvMatf(GLfloat result[4][4], const GLfloat m[4][4]) +{ + /* + Use a temporary matrix for the result and copy the temporary + into the result when finished. Doing this instead of writing + the result directly guarantees that the routine will work even + if the result overlaps one or more of the arguments in + memory. + */ + + GLfloat r[4][4]; + + if ((m[0][3] == 0.0f) && (m[1][3] == 0.0f) && (m[2][3] == 0.0f) && (m[2][3] == 1.0f)) { + if ((m[3][0] == 0.0f) && (m[3][1] == 0.0f) && (m[3][2] == 0.0f)) { + NvInvMat3x3f(r, m); + } else { + NvInvMat4x3f(r, m); + } + } else { + NvInvMat4x4f(r, m); + } + + NvCopyMatf(result, r); +} + +void NvBuildIdentityMatf(GLfloat r[4][4]) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = x; + r[3][1] = y; + r[3][2] = z; + r[3][3] = 1.0f; +} + +void NvMultTranslateMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, + GLfloat z) +{ + GLfloat r[4][4]; /*temporary storage for result */ + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0]; + r[3][1] = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1]; + r[3][2] = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2]; + r[3][3] = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + r[0][0] = x; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = y; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = z; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultScaleMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z) +{ + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * x; + r[0][1] = m[0][1] * x; + r[0][2] = m[0][2] * x; + r[0][3] = m[0][3] * x; + + r[1][0] = m[1][0] * y; + r[1][1] = m[1][1] * y; + r[1][2] = m[1][2] * y; + r[1][3] = m[1][3] * y; + + r[2][0] = m[2][0] * z; + r[2][1] = m[2][1] * z; + r[2][2] = m[2][2] * z; + r[2][3] = m[2][3] * z; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians) +{ + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = 1.0f; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = c; + r[1][2] = s; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = -s; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = 0.0f; + r[0][2] = -s; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = 1.0f; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = s; + r[2][1] = 0.0f; + r[2][2] = c; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + r[0][0] = c; + r[0][1] = s; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = -s; + r[1][1] = c; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvMultRotXRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[0][3] = m[0][3]; + + r[1][0] = m[1][0] * c + m[2][0] * s; + r[1][1] = m[1][1] * c + m[2][1] * s; + r[1][2] = m[1][2] * c + m[2][2] * s; + r[1][3] = m[1][3] * c + m[2][3] * s; + + r[2][0] = m[1][0] * -s + m[2][0] * c; + r[2][1] = m[1][1] * -s + m[2][1] * c; + r[2][2] = m[1][2] * -s + m[2][2] * c; + r[2][3] = m[1][3] * -s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotYRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[2][0] * -s; + r[0][1] = m[0][1] * c + m[2][1] * -s; + r[0][2] = m[0][2] * c + m[2][2] * -s; + r[0][3] = m[0][3] * c + m[2][3] * -s; + + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[1][3] = m[1][3]; + + r[2][0] = m[0][0] * s + m[2][0] * c; + r[2][1] = m[0][1] * s + m[2][1] * c; + r[2][2] = m[0][2] * s + m[2][2] * c; + r[2][3] = m[0][3] * s + m[2][3] * c; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvMultRotZRadMatf(GLfloat result[4][4], const GLfloat m[4][4], GLfloat radians) +{ + + GLfloat const s = sinf(radians); + GLfloat const c = cosf(radians); + + GLfloat r[4][4]; + + r[0][0] = m[0][0] * c + m[1][0] * s; + r[0][1] = m[0][1] * c + m[1][1] * s; + r[0][2] = m[0][2] * c + m[1][2] * s; + r[0][3] = m[0][3] * c + m[1][3] * s; + + r[1][0] = m[0][0] * -s + m[1][0] * c; + r[1][1] = m[0][1] * -s + m[1][1] * c; + r[1][2] = m[0][2] * -s + m[1][2] * c; + r[1][3] = m[0][3] * -s + m[1][3] * c; + + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + r[2][3] = m[2][3]; + + r[3][0] = m[3][0]; + r[3][1] = m[3][1]; + r[3][2] = m[3][2]; + r[3][3] = m[3][3]; + + NvCopyMatf(result, r); +} + +void NvBuildRotRadMatf(GLfloat result[4][4], const GLfloat axis[3], GLfloat radians) +{ + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + /* build a matrix from the quat */ + + result[0][0] = 1.0f - 2.0f * (j * j + k * k); + result[0][1] = 2.0f * (i * j + r * k); + result[0][2] = 2.0f * (i * k - r * j); + result[0][3] = 0.0f; + + result[1][0] = 2.0f * (i * j - r * k); + result[1][1] = 1.0f - 2.0f * (i * i + k * k); + result[1][2] = 2.0f * (j * k + r * i); + result[1][3] = 0.0f; + + result[2][0] = 2.0f * (i * k + r * j); + result[2][1] = 2.0f * (j * k - r * i); + result[2][2] = 1.0f - 2.0f * (i * i + j * j); + result[2][3] = 0.0f; + + result[3][0] = 0.0f; + result[3][1] = 0.0f; + result[3][2] = 0.0f; + result[3][3] = 1.0f; +} + +void NvMultRotRadMatf(GLfloat result[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians) +{ + GLfloat r[4][4]; + + { + /* build a quat first */ + + GLfloat i, j, k, r; + + /* should be */ + GLfloat const dst_l = sinf(radians / 2.0f); + + /* actually is */ + GLfloat const src_l = sqrtf(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); + + if (src_l <= KD_FLT_EPSILON) { + i = 0.0f; + j = 0.0f; + k = 0.0f; + r = 1.0f; + } else { + GLfloat const s = dst_l / src_l; + i = axis[0] * s; + j = axis[1] * s; + k = axis[2] * s; + r = cosf(radians / 2.0f); + } + + { + /* build a matrix from the quat */ + + GLfloat const a00 = 1.0f - 2.0f * (j * j + k * k); + GLfloat const a01 = 2.0f * (i * j + r * k); + GLfloat const a02 = 2.0f * (i * k - r * j); + + GLfloat const a10 = 2.0f * (i * j - r * k); + GLfloat const a11 = 1.0f - 2.0f * (i * i + k * k); + GLfloat const a12 = 2.0f * (j * k + r * i); + + GLfloat const a20 = 2.0f * (i * k + r * j); + GLfloat const a21 = 2.0f * (j * k - r * i); + GLfloat const a22 = 1.0f - 2.0f * (i * i + j * j); + + result[0][0] = m[0][0] * a00 + m[1][0] * a01 + m[2][0] * a02; + result[0][1] = m[0][1] * a00 + m[1][1] * a01 + m[2][1] * a02; + result[0][2] = m[0][2] * a00 + m[1][2] * a01 + m[2][2] * a02; + result[0][3] = m[0][3] * a00 + m[1][3] * a01 + m[2][3] * a02; + + result[1][0] = m[0][0] * a10 + m[1][0] * a11 + m[2][0] * a12; + result[1][1] = m[0][1] * a10 + m[1][1] * a11 + m[2][1] * a12; + result[1][2] = m[0][2] * a10 + m[1][2] * a11 + m[2][2] * a12; + result[1][3] = m[0][3] * a10 + m[1][3] * a11 + m[2][3] * a12; + + result[2][0] = m[0][0] * a20 + m[1][0] * a21 + m[2][0] * a22; + result[2][1] = m[0][1] * a20 + m[1][1] * a21 + m[2][1] * a22; + result[2][2] = m[0][2] * a20 + m[1][2] * a21 + m[2][2] * a22; + result[2][3] = m[0][3] * a20 + m[1][3] * a21 + m[2][3] * a22; + + result[3][0] = m[3][0]; + result[3][1] = m[3][1]; + result[3][2] = m[3][2]; + result[3][3] = m[3][3]; + } + } + + NvCopyMatf(result, r); +} + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotXRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotYRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees) +{ + NvBuildRotZRadMatf(r, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotXRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotYRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees) +{ + NvMultRotZRadMatf(r, m, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees) +{ + NvBuildRotRadMatf(r, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees) +{ + NvMultRotRadMatf(r, m, axis, degrees * KD_DEG_TO_RAD_F); +} + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]) +{ + GLfloat ev[3]; + GLfloat z[3]; + GLfloat x_tmp[3]; + GLfloat x[3]; + GLfloat y[3]; + + NvSubVecf(ev, eye, obj); + + NvNormalizeVecf(z, ev); + + NvCrossProductf(x_tmp, up, z); + + NvNormalizeVecf(x, x_tmp); + + NvCrossProductf(y, z, x); + + r[0][0] = x[0]; + r[0][1] = y[0]; + r[0][2] = z[0]; + r[0][3] = 0.0f; + + r[1][0] = x[1]; + r[1][1] = y[1]; + r[1][2] = z[1]; + r[1][3] = 0.0f; + + r[2][0] = x[2]; + r[2][1] = y[2]; + r[2][2] = z[2]; + r[2][3] = 0.0f; + + r[3][0] = -x[0] * eye[0] + -x[1] * eye[1] + -x[2] * eye[2]; + r[3][1] = -y[0] * eye[0] + -y[1] * eye[1] + -y[2] * eye[2]; + r[3][2] = -z[0] * eye[0] + -z[1] * eye[1] + -z[2] * eye[2]; + r[3][3] = 1.0f; +} + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const m00 = znear * 2.0f / (right - left); + GLfloat const m11 = znear * 2.0f / (top - bottom); + GLfloat const m22 = -(zfar + znear) / (zfar - znear); + + GLfloat const m20 = (right + left) / (right - left); + GLfloat const m21 = (top + bottom) / (top - bottom); + + GLfloat const m32 = -(2.0f * zfar * znear) / (zfar - znear); + GLfloat const m23 = -1.0f; + + r[0][0] = m00; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = m11; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = m20; + r[2][1] = m21; + r[2][2] = m22; + r[2][3] = m23; + + r[3][0] = 0.0f; + r[3][1] = 0.0f; + r[3][2] = m32; + r[3][3] = 0.0f; +} + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = 1.0f; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = 0.0f; + r[3][3] = 1.0f; +} + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) +{ + GLfloat const sx = 2.0f / (right - left); + GLfloat const sy = 2.0f / (top - bottom); + GLfloat const sz = -2.0f / (zfar - znear); + + GLfloat const tx = -(right + left) / (right - left); + GLfloat const ty = -(top + bottom) / (top - bottom); + GLfloat const tz = -(zfar + znear) / (zfar - znear); + + r[0][0] = sx; + r[0][1] = 0.0f; + r[0][2] = 0.0f; + r[0][3] = 0.0f; + + r[1][0] = 0.0f; + r[1][1] = sy; + r[1][2] = 0.0f; + r[1][3] = 0.0f; + + r[2][0] = 0.0f; + r[2][1] = 0.0f; + r[2][2] = sz; + r[2][3] = 0.0f; + + r[3][0] = tx; + r[3][1] = ty; + r[3][2] = tz; + r[3][3] = 1.0f; +} diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.h b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.h new file mode 100644 index 00000000..0e04568e --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_matrix.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_MATRIX_H +#define INCLUDED_MATRIX_H + +#include +#include +#include + +#define KD_FLT_EPSILON 1.19209290E-07F +#define KD_DEG_TO_RAD_F 0.0174532924F +#define KD_RAD_TO_DEG_F 57.2957802F + +void NvCopyMatf(GLfloat r[4][4], const GLfloat m[4][4]); +void NvExtract3x3Matf(GLfloat r[3][3], const GLfloat m[4][4]); + +/* vector utilities */ + +GLfloat NvVecLengthf(const GLfloat v[3]); + +void NvNormalizeVecf(GLfloat r[3], const GLfloat v[3]); + +void NvAddVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvSubVecf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvCrossProductf(GLfloat r[3], const GLfloat a[3], const GLfloat b[3]); + +void NvTransformPointf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); +void NvTransformHomPointf(GLfloat r[4], const GLfloat m[4][4], const GLfloat a[4]); +void NvTransformVecf(GLfloat r[3], const GLfloat m[4][4], const GLfloat a[3]); + +/* matrix utilities */ + +void NvMultMatf(GLfloat r[4][4], const GLfloat a[4][4], const GLfloat b[4][4]); + +void NvInvMatf(GLfloat r[4][4], const GLfloat m[4][4]); + +/* matrix building utilities */ + +void NvBuildIdentityMatf(GLfloat r[4][4]); + +void NvBuildTranslateMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildScaleMatf(GLfloat r[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvBuildRotXDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotYDegMatf(GLfloat r[4][4], GLfloat degrees); +void NvBuildRotZDegMatf(GLfloat r[4][4], GLfloat degrees); + +void NvBuildRotDegMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat degrees); + +void NvBuildRotXRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotYRadMatf(GLfloat r[4][4], GLfloat radians); +void NvBuildRotZRadMatf(GLfloat r[4][4], GLfloat radians); + +void NvBuildRotRadMatf(GLfloat r[4][4], const GLfloat axis[3], GLfloat radians); + +void NvBuildLookatMatf(GLfloat r[4][4], const GLfloat eye[3], const GLfloat obj[3], + const GLfloat up[3]); + +void NvBuildFrustumMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +void NvBuildOrtho2Matf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); + +void NvBuildOrthoMatf(GLfloat r[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); + +/* matrix concatenation utilities */ + +void NvMultTranslateMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); +void NvMultScaleMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat x, GLfloat y, GLfloat z); + +void NvMultRotXDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotYDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); +void NvMultRotZDegMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat degrees); + +void NvMultRotDegMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat degrees); + +void NvMultRotXRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotYRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); +void NvMultRotZRadMatf(GLfloat r[4][4], const GLfloat m[4][4], GLfloat radians); + +void NvMultRotRadMatf(GLfloat r[4][4], const GLfloat m[4][4], const GLfloat axis[3], + GLfloat radians); + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.cpp b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.cpp new file mode 100644 index 00000000..9626eb8c --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nv_quat.h" +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]) +{ + memcpy(r, q, 4 * sizeof(GLfloat)); +} + +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]) +{ + // Assumes that the quaternion is normalized! + GLfloat x2 = q[0] * 2.0f; + GLfloat y2 = q[1] * 2.0f; + GLfloat z2 = q[2] * 2.0f; + GLfloat xSq2 = x2 * q[0]; + GLfloat ySq2 = y2 * q[1]; + GLfloat zSq2 = z2 * q[2]; + GLfloat xy2 = x2 * q[1]; + GLfloat xz2 = x2 * q[2]; + GLfloat xw2 = x2 * q[3]; + GLfloat yz2 = y2 * q[2]; + GLfloat yw2 = y2 * q[3]; + GLfloat zw2 = z2 * q[3]; + + /* Matrix is + * | 1 - 2y^2 - 2z^2 2xy - 2zw 2xz + 2yw | + * | 2xy + 2zw 1 - 2x^2 - 2z^2 2yz - 2xw | + * | 2xz - 2yw 2yz + 2xw 1 - 2x^2 - 2y^2 | + */ + r[0][0] = 1.0f - ySq2 - zSq2; + r[0][1] = xy2 - zw2; + r[0][2] = xz2 + yw2; + + r[1][0] = xy2 + zw2; + r[1][1] = 1.0f - xSq2 - zSq2; + r[1][2] = yz2 - xw2; + + r[2][0] = xz2 - yw2; + r[2][1] = yz2 + xw2; + r[2][2] = 1.0f - xSq2 - ySq2; +} + +void NvQuatIdentity(GLfloat r[4]) +{ + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = 1.0f; +} + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = axis[0] * sina; + r[1] = axis[1] * sina; + r[2] = axis[2] * sina; + r[3] = cosa; +} + +void NvQuatX(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = sina; + r[1] = 0.0f; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatY(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = sina; + r[2] = 0.0f; + r[3] = cosa; +} + +void NvQuatZ(GLfloat r[4], GLfloat radians) +{ + GLfloat cosa = cosf(radians * 0.5f); + GLfloat sina = sinf(radians * 0.5f); + + r[0] = 0.0f; + r[1] = 0.0f; + r[2] = sina; + r[3] = cosa; +} + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatY(h, heading); + NvQuatX(p, pitch); + NvQuatZ(ro, roll); + + NvQuatMult(r, h, p); + NvQuatMult(r, ro, r); +} + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll) +{ + GLfloat h[4], p[4], ro[4]; + + NvQuatZ(ro, roll); + NvQuatX(p, pitch); + NvQuatY(h, heading); + + NvQuatMult(r, p, h); + NvQuatMult(r, r, ro); +} + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]) +{ + return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]; +} + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]) +{ + const GLfloat q1x = q1[0]; + const GLfloat q1y = q1[1]; + const GLfloat q1z = q1[2]; + const GLfloat q1w = q1[3]; + const GLfloat q2x = q2[0]; + const GLfloat q2y = q2[1]; + const GLfloat q2z = q2[2]; + const GLfloat q2w = q2[3]; + + r[0] = q1y * q2z - q2y * q1z + q1w * q2x + q2w * q1x; + r[1] = q1z * q2x - q2z * q1x + q1w * q2y + q2w * q1y; + r[2] = q1x * q2y - q2x * q1y + q1w * q2z + q2w * q1z; + r[3] = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; +} + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t) +{ + GLfloat omt = 1.0f - t; + + if (NvQuatDot(q1, q2) < 0.0f) { + r[0] = -q1[0] * omt + q2[0] * t; + r[1] = -q1[1] * omt + q2[1] * t; + r[2] = -q1[2] * omt + q2[2] * t; + r[3] = -q1[3] * omt + q2[3] * t; + } else { + r[0] = q1[0] * omt + q2[0] * t; + r[1] = q1[1] * omt + q2[1] * t; + r[2] = q1[2] * omt + q2[2] * t; + r[3] = q1[3] * omt + q2[3] * t; + } + + NvQuatNormalize(r, r); +} + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]) +{ + GLfloat invLength = 1.0f / sqrtf(NvQuatDot(q, q)); + + r[0] = invLength * q[0]; + r[1] = invLength * q[1]; + r[2] = invLength * q[2]; + r[3] = invLength * q[3]; +} diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.h b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.h new file mode 100644 index 00000000..4c65cb9e --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_math/nv_quat.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INCLUDED_QUAT_H +#define INCLUDED_QUAT_H + +#include +#include +#include + +void NvQuatCopy(GLfloat r[4], const GLfloat q[4]); +void NvQuatConvertTo3x3Mat(GLfloat r[3][3], const GLfloat q[4]); + +void NvQuatIdentity(GLfloat r[4]); + +void NvQuatFromAngleAxis(GLfloat r[4], GLfloat radians, const GLfloat axis[3]); + +void NvQuatX(GLfloat r[4], GLfloat radians); + +void NvQuatY(GLfloat r[4], GLfloat radians); + +void NvQuatZ(GLfloat r[4], GLfloat radians); + +void NvQuatFromEuler(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +void NvQuatFromEulerReverse(GLfloat r[4], GLfloat heading, GLfloat pitch, GLfloat roll); + +GLfloat NvQuatDot(const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatMult(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4]); + +void NvQuatNLerp(GLfloat r[4], const GLfloat q1[4], const GLfloat q2[4], GLfloat t); + +void NvQuatNormalize(GLfloat r[4], const GLfloat q[4]); + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/nv_types.h b/src/Runtime/Source/platformspecific/windows/libs/nv_types.h new file mode 100644 index 00000000..1d1b0300 --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/nv_types.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2011 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __INCLUDED_QT3DS_TYPES_H +#define __INCLUDED_QT3DS_TYPES_H + +typedef unsigned char NvU8; // 0 to 255 +typedef unsigned short NvU16; // 0 to 65535 +typedef unsigned int NvU32; // 0 to 4294967295 +typedef unsigned long long NvU64; // 0 to 18446744073709551615 +typedef signed char NvS8; // -128 to 127 +typedef signed short NvS16; // -32768 to 32767 +typedef signed int NvS32; // -2147483648 to 2147483647 +typedef signed long long NvS64; // 2^-63 to 2^63-1 + +// Explicitly sized floats +typedef float NvF32; // IEEE Single Precision (S1E8M23) +typedef double NvF64; // IEEE Double Precision (S1E11M52) + +// Boolean type +#define QT3DS_FALSE 0 +#define QT3DS_TRUE 1 +typedef NvU8 NvBool; + +// Result of sizeof operator +typedef unsigned long NvSize; + +// Type large enough to hold a relative file offset +typedef long NvOffset; + +// Base NULL type. +#define QT3DS_NULL 0 + +// Error related +typedef enum { + NvError_Success = 0, + NvError_NotSupported, + NvError_NotInitialized, + NvError_BadParameter, + NvError_InsufficientMemory, + NvError_NoEntries, + NvError_UnknownError, +} NvError; + +#if 1 // defined(_DEBUG) // !!!!TBD TODO +#define NvAssert(c) +#else +#define NvAssert(c) ((void)((c) ? 0 : (NvHandleAssertion(#c, __FILE__, __LINE__), 0))) +#endif + +// Other standardized typedefs +typedef NvU64 NvUST; // U64 unadjusted system time value + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/libs/qt3ds_launcher_defs.h b/src/Runtime/Source/platformspecific/windows/libs/qt3ds_launcher_defs.h new file mode 100644 index 00000000..6577fb4a --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/libs/qt3ds_launcher_defs.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* TAGRELEASE: public */ + +#ifndef _QT3DSLAUNCHERDEFS_H +#define _QT3DSLAUNCHERDEFS_H + +/* Applications should call kdSetWindowPropertyiv with + * KD_WINDOWPROPERTY_APP_ID_QT3DS as the pname + * and one of the ID's below as the param + * Or else define their own in the range starting with + * KD_APP_ID_USER_BASE_QT3DS + * call must be made _prior_ to window realize + */ + +/* Need to define an NV internal KD property range - defining to a fixed value for now */ +/* But this window property is unused in the current KD spec */ +#define KD_WINDOWPROPERTY_APP_ID_QT3DS 0x1000 + +#define KD_APP_ID_UNKNOWN_QT3DS 0 +#define KD_APP_ID_KEYBOARD_QT3DS 1 /* QT3DS RESERVED */ +#define KD_APP_ID_CONTACTS_QT3DS 2 /* QT3DS RESERVED */ +#define KD_APP_ID_MESSAGING_QT3DS 3 /* QT3DS RESERVED */ +#define KD_APP_ID_EMAIL_QT3DS 4 /* QT3DS RESERVED */ +#define KD_APP_ID_IM_QT3DS 5 /* QT3DS RESERVED */ +#define KD_APP_ID_PHONEDIALER_QT3DS 6 /* QT3DS RESERVED */ +#define KD_APP_ID_GAME_QT3DS 7 +#define KD_APP_ID_ADDRESSBOOK_QT3DS 8 /* Assigned to NV addrbook demo */ +#define KD_APP_ID_MUSICPLAYER_QT3DS 9 /* Assigned to NV mediaplayer demo */ +#define KD_APP_ID_SMS_QT3DS 10 /* QT3DS RESERVED */ +#define KD_APP_ID_IMAGEBROWSER_QT3DS 11 /* Assigned to NV photoviewer demo */ +#define KD_APP_ID_MAP_QT3DS 12 /* QT3DS RESERVED */ +#define KD_APP_ID_HOME_QT3DS 13 /* Assigned to NV launcher_gui home screen */ +#define KD_APP_ID_CALENDAR_QT3DS 14 /* QT3DS RESERVED */ +#define KD_APP_ID_VIDEO_QT3DS 15 /* Assigned to NV videoplayer demo */ +#define KD_APP_ID_WIDGETS_QT3DS 16 /* QT3DS RESERVED */ +#define KD_APP_ID_CAMERA_QT3DS 19 /* QT3DS RESERVED */ +#define KD_APP_ID_MEDIAWALL_QT3DS 20 /* QT3DS RESERVED */ +#define KD_APP_ID_OPERA_QT3DS 21 /* QT3DS RESERVED */ +#define KD_APP_ID_YOUTUBE_QT3DS 22 /* QT3DS RESERVED */ +#define KD_APP_ID_VISION_QT3DS 23 /* QT3DS RESERVED */ +#define KD_APP_ID_USER_BASE_QT3DS 1024 /* Base of app-reserved */ + +/* starting orientation support */ +#define KD_WINDOWPROPERTY_ORIENTATION_QT3DS 0x1001 + +#define KD_WINDOWPROPERTY_STATUSBAR_QT3DS 0x1002 +#define KD_STATUSBAR_HIDEALL_QT3DS 0x0000 +#define KD_STATUSBAR_SHOWBAR_QT3DS 0x0001 +#define KD_STATUSBAR_SHOWBG_QT3DS 0x0002 /* not set as state, just for mask */ +#define KD_STATUSBAR_SHOWALL_QT3DS 0x0003 /* this is showbar+showbg in bits...*/ + +#define KD_WINDOWPROPERTY_PROCESS_ID_QT3DS 0x1003 + +/* App-level KD state - if this exists and is nonzero, then the app is */ +/* Running in the launcher */ + +#define KD_STATE_LAUNCHER_ACTIVE_QT3DS 0x11001 + +/* Part of GL_NV_log_textures extension */ +/* Not currently supported in external release */ +#define GL_LOG_TEXTURES_QT3DS 0x85FF +#define GL_LOG_TEXTURES_ZONE_QT3DS 0x85FE + +#endif diff --git a/src/Runtime/Source/platformspecific/windows/viewer/Resource.h b/src/Runtime/Source/platformspecific/windows/viewer/Resource.h new file mode 100644 index 00000000..58c9336e --- /dev/null +++ b/src/Runtime/Source/platformspecific/windows/viewer/Resource.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#define IDI_ICON1 103 +#define IDI_ICON2 105 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp new file mode 100644 index 00000000..f67cf717 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "foundation/Qt3DSVec4.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +namespace { +class ClearColor : public NVRenderExample +{ + NVRenderContext &m_Context; + +public: + ClearColor(NVRenderContext &ctx) + : m_Context(ctx) + { + } + virtual void drawFrame(double currentSeconds) + { + // Apply this value immediately but track it so that a later pop will in fact + // restore this value. + if (currentSeconds < 1) + m_Context.SetClearColor(QT3DSVec4(.8f, .0f, .0f, 1.f)); + else if (currentSeconds < 2) + m_Context.SetClearColor(QT3DSVec4(0.f, .0f, 1.f, 1.f)); + else + m_Context.SetClearColor(QT3DSVec4(0.f, 1.0f, 1.f, 1.f)); + m_Context.Clear(NVRenderClearFlags(NVRenderClearValues::Color)); + } + virtual QT3DSU32 getRuntimeInSeconds() { return 2; } + virtual void release() { NVDelete(m_Context.GetFoundation(), this); } +}; +} + +// QT3DS_RENDER_REGISTER_EXAMPLE( ClearColor ); \ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp new file mode 100644 index 00000000..d866cda0 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp @@ -0,0 +1,491 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "render/NvRenderBaseTypes.h" +#include "render_util/NVRenderAllocator.h" +#include "render_util/NVRenderErrorStream.h" +#include "render_util/NVRenderUtils.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSTime.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSMath.h" + +#include +#include +#include + +using namespace qt3ds; +using namespace qt3ds::render; + +static TExampleCreateFunc gCreateFuncs[128]; + +TExampleCreateFunc *NVRenderExampleFactory::mExampleCreators = gCreateFuncs; +QT3DSU32 NVRenderExampleFactory::mMaxCreators = 128; +QT3DSU32 NVRenderExampleFactory::mNumCreators = 0; +namespace { +NVRenderErrorStream g_errorStream; +NVRenderAllocator g_allocator(g_errorStream); +NVFoundation *g_foundation(NULL); +NVRenderContext *g_renderContext(NULL); +NVRenderExample *g_example(NULL); +QT3DSI32 g_exampleIdx(0); +Time::Second g_runTime; +Time g_timer; +} + +bool NVRenderExampleFactory::nextExample() +{ + if (g_example) + g_example->release(); + g_example = 0; + if (g_exampleIdx < (int)mNumCreators) { + g_example = mExampleCreators[g_exampleIdx](*g_renderContext); + ++g_exampleIdx; + g_runTime = g_example->getRuntimeInSeconds(); + g_timer = Time(); + return true; + } + return false; +} + +void NVRenderExampleFactory::beginExamples() +{ + g_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, g_allocator, g_errorStream); + g_renderContext = + &NVRenderContext::CreateGL(*g_foundation, NVRenderContextType(NVRenderContextValues::GL2)); + nextExample(); +} +bool NVRenderExampleFactory::update() +{ + Time::Second currentTime = g_timer.peekElapsedSeconds(); + if (currentTime > g_runTime) + nextExample(); + if (g_example) + g_example->drawFrame(currentTime); + + return g_example != NULL; +} + +void NVRenderExampleFactory::endExamples() +{ + g_exampleIdx = mNumCreators; + nextExample(); + if (g_renderContext) + g_renderContext->release(); + if (g_foundation) + g_foundation->release(); + + g_renderContext = NULL; + g_foundation = NULL; +} + +namespace qt3ds { +namespace render { + /////////////////////////////////////////////////////////////////////////////// + + // Math stuff + + int eq(float a, float b) + { + float diff = a - b; + if (diff < 0) { + diff = -diff; + } + return diff <= eps; + } + + // + // Matrix functions, since GLES 2.x doesn't provide them + // + + void NvGl2DemoMatrixIdentity(float m[16]) + { + memset(m, 0, sizeof(float) * 16); + m[4 * 0 + 0] = m[4 * 1 + 1] = m[4 * 2 + 2] = m[4 * 3 + 3] = 1.0; + } + + int NvGl2DemoMatrixEquals(float a[16], float b[16]) + { + int i; + for (i = 0; i < 16; ++i) + if (!eq(a[i], b[i])) + return 0; + + return 1; + } + + void NvGl2DemoMatrixTranspose(float m[16]) + { + int i, j; + float t; + for (i = 1; i < 4; ++i) + for (j = 0; j < i; ++j) { + t = m[4 * i + j]; + m[4 * i + j] = m[4 * j + i]; + m[4 * j + i] = t; + } + } + + void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]) + { + int r, c, i; + for (r = 0; r < 4; r++) { + float m[4] = { 0.0, 0.0, 0.0, 0.0 }; + for (c = 0; c < 4; c++) { + for (i = 0; i < 4; i++) { + m[c] += m0[4 * i + r] * m1[4 * c + i]; + } + } + for (c = 0; c < 4; c++) { + m0[4 * c + r] = m[c]; + } + } + } + + void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]) + { + int r, c, i; + for (r = 0; r < 4; r++) { + float m[3] = { 0.0, 0.0, 0.0 }; + for (c = 0; c < 3; c++) { + for (i = 0; i < 3; i++) { + m[c] += m0[4 * i + r] * m1[3 * c + i]; + } + } + for (c = 0; c < 3; c++) { + m0[4 * c + r] = m[c]; + } + } + } + + void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]) + { + int r, c, i; + for (r = 0; r < 3; r++) { + float m[3] = { 0.0, 0.0, 0.0 }; + for (c = 0; c < 3; c++) { + for (i = 0; i < 3; i++) { + m[c] += m0[3 * i + r] * m1[3 * c + i]; + } + } + for (c = 0; c < 3; c++) { + m0[3 * c + r] = m[c]; + } + } + } + + void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f) + { + float m1[16]; + float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv, twoNear; + + rightMinusLeftInv = 1.0f / (r - l); + topMinusBottomInv = 1.0f / (t - b); + farMinusNearInv = 1.0f / (f - n); + twoNear = 2.0f * n; + + m1[0] = twoNear * rightMinusLeftInv; + m1[1] = 0.0f; + m1[2] = 0.0f; + m1[3] = 0.0f; + + m1[4] = 0.0f; + m1[5] = twoNear * topMinusBottomInv; + m1[6] = 0.0f; + m1[7] = 0.0f; + + m1[8] = (r + l) * rightMinusLeftInv; + m1[9] = (t + b) * topMinusBottomInv; + m1[10] = -(f + n) * farMinusNearInv; + m1[11] = -1.0f; + + m1[12] = 0.0f; + m1[13] = 0.0f; + m1[14] = -(twoNear * f) * farMinusNearInv; + m1[15] = 0.0f; + + NvGl2DemoMatrixMultiply(m, m1); + } + + void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f) + { + float m1[16]; + float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv; + + rightMinusLeftInv = 1.0f / (r - l); + topMinusBottomInv = 1.0f / (t - b); + farMinusNearInv = 1.0f / (f - n); + + m1[0] = 2.0f * rightMinusLeftInv; + m1[1] = 0.0f; + m1[2] = 0.0f; + m1[3] = 0.0f; + + m1[4] = 0.0f; + m1[5] = 2.0f * topMinusBottomInv; + m1[6] = 0.0f; + m1[7] = 0.0f; + + m1[8] = 0.0f; + m1[9] = 0.0f; + m1[10] = -2.0f * farMinusNearInv; + m1[11] = 0.0f; + + m1[12] = -(r + l) * rightMinusLeftInv; + m1[13] = -(t + b) * topMinusBottomInv; + m1[14] = -(f + n) * farMinusNearInv; + m1[15] = 1.0f; + + NvGl2DemoMatrixMultiply(m, m1); + } + + void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z) + { + float m1[16]; + NvGl2DemoMatrixIdentity(m1); + + m1[4 * 3 + 0] = x; + m1[4 * 3 + 1] = y; + m1[4 * 3 + 2] = z; + + NvGl2DemoMatrixMultiply(m, m1); + } + + void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z) + { + float len = (float)sqrtf(x * x + y * y + z * z); + float u0 = x / len; + float u1 = y / len; + float u2 = z / len; + float rad = (float)(theta / 180 * NVPi); + float c = (float)cosf(rad); + float s = (float)sinf(rad); + m[3 * 0 + 0] = u0 * u0 + c * (1 - u0 * u0) + s * 0; + m[3 * 0 + 1] = u0 * u1 + c * (0 - u0 * u1) + s * u2; + m[3 * 0 + 2] = u0 * u2 + c * (0 - u0 * u2) - s * u1; + + m[3 * 1 + 0] = u1 * u0 + c * (0 - u1 * u0) - s * u2; + m[3 * 1 + 1] = u1 * u1 + c * (1 - u1 * u1) + s * 0; + m[3 * 1 + 2] = u1 * u2 + c * (0 - u1 * u2) + s * u0; + + m[3 * 2 + 0] = u2 * u0 + c * (0 - u2 * u0) + s * u1; + m[3 * 2 + 1] = u2 * u1 + c * (0 - u2 * u1) - s * u0; + m[3 * 2 + 2] = u2 * u2 + c * (1 - u2 * u2) + s * 0; + } + + void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z) + { + float r[9]; + NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z); + NvGl2DemoMatrixMultiply_4x4_3x3(m, r); + } + + void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z) + { + float r[9]; + NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z); + NvGl2DemoMatrixMultiply_3x3(m, r); + } + + float NvGl2DemoMatrixDeterminant(float m[16]) + { + return m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] + + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] + + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] + + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] + + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2] + + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] + + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3] + - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] + - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3] + + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; + } + + void NvGl2DemoMatrixInverse(float m[16]) + { + float a[16]; + float det; + int i; + float b[16], e[16]; + + a[4 * 0 + 0] = m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] + - m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] + + m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] + - m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] + + m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 0 + 1] = m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] + - m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] + + m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] + + m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] + - m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 0 + 2] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 1] + - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 1] + + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 2] + - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 3] + + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 3]; + a[4 * 0 + 3] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] + - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] + - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] + + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] + + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] + - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3]; + a[4 * 1 + 0] = m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] + - m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] + + m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] + + m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] + - m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 1 + 1] = m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] + + m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 1 + 2] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 2] + + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 2] + + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 3] + - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 3]; + a[4 * 1 + 3] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] + + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] + - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] + - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] + + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3]; + a[4 * 2 + 0] = m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] + + m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] + - m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] + - m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]; + a[4 * 2 + 1] = m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] + + m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] + - m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]; + a[4 * 2 + 2] = m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 0] + + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 1] + - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 1] + - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 3]; + a[4 * 2 + 3] = m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] + - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] + + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] + + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] + - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3]; + a[4 * 3 + 0] = m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] + - m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] + + m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]; + a[4 * 3 + 1] = m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] + + m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] + - m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] + + m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]; + a[4 * 3 + 2] = m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 1] + + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 2]; + a[4 * 3 + 3] = m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] + + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] + - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] + - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] + + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2]; + + det = NvGl2DemoMatrixDeterminant(m); + + for (i = 0; i < 16; ++i) + a[i] /= det; + + NvGl2DemoMatrixIdentity(e); + + NvGl2DemoMatrixCopy(b, m); + NvGl2DemoMatrixMultiply(b, a); + + NvGl2DemoMatrixCopy(m, a); + } + + void NvGl2DemoMatrixCopy(float dest[16], float src[16]) + { + memcpy(dest, src, 16 * sizeof(float)); + } + + void NvGl2DemoMatrixPrint(float a[16]) + { + int i, j; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + printf("%f%c", a[4 * i + j], j == 3 ? '\n' : ' '); + } + + void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]) + { + float res[4]; + int i, j; + + for (i = 0; i < 4; ++i) { + res[i] = 0; + for (j = 0; j < 4; ++j) + res[i] += m[i * 4 + j] * v[j]; + } + + memcpy(v, res, sizeof(res)); + } +} +} \ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h new file mode 100644 index 00000000..79bfd911 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EXAMPLE_H +#define QT3DS_RENDER_EXAMPLE_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/NvRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + class NVRenderContext; + + class NVRenderExample + { + protected: + virtual ~NVRenderExample() {} + public: + virtual void drawFrame(double currentSeconds) = 0; + virtual QT3DSU32 getRuntimeInSeconds() { return 5; } + virtual void handleKeypress(int /*keypress*/) {} + virtual void release() = 0; + }; + + typedef NVRenderExample *(*TExampleCreateFunc)(NVRenderContext &context); + + struct NVRenderExampleFactory + { + static TExampleCreateFunc *mExampleCreators; + static QT3DSU32 mMaxCreators; + static QT3DSU32 mNumCreators; + + static void addCreator(TExampleCreateFunc creator) + { + if (mNumCreators < mMaxCreators) { + mExampleCreators[mNumCreators] = creator; + ++mNumCreators; + } else + QT3DS_ASSERT(false); + } + + // Assuming that the render context is egl + // Relies on the global structures defined in demo common + // to figure out window state. + static bool nextExample(); + static void beginExamples(); + static bool update(); + static void endExamples(); + }; + + template + struct NVRenderExampleCreator + { + + static NVRenderExample *createExample(NVRenderContext &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), TExample)(context); + } + NVRenderExampleCreator() { NVRenderExampleFactory::addCreator(createExample); } + }; + +#define QT3DS_RENDER_REGISTER_EXAMPLE(dtype) static NVRenderExampleCreator dtype##Creator + +#define eps 1e-4 + + int eq(float a, float b); + + // Matrix functions + void NvGl2DemoMatrixIdentity(float m[16]); + int NvGl2DemoMatrixEquals(float a[16], float b[16]); + void NvGl2DemoMatrixTranspose(float m[16]); + void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]); + void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]); + void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]); + void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f); + void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f); + void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z); + void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z); + void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z); + void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z); + + float NvGl2DemoMatrixDeterminant(float m[16]); + void NvGl2DemoMatrixInverse(float m[16]); + void NvGl2DemoMatrixCopy(float dest[16], float src[16]); + + void NvGl2DemoMatrixPrint(float a[16]); + + void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]); +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp new file mode 100644 index 00000000..efae6f5e --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExampleTools.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render_util/NVRenderUtils.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSVec4.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +struct BoxFace +{ + QT3DSVec3 positions[4]; + QT3DSVec3 normal; +}; + +static const BoxFace g_BoxFaces[] = { + { // Z+ + QT3DSVec3(-1, -1, 1), QT3DSVec3(-1, 1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(0, 0, 1) }, + { // X+ + QT3DSVec3(1, -1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, -1, -1), QT3DSVec3(1, 0, 0) }, + { // Z- + QT3DSVec3(1, -1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, -1, -1), + QT3DSVec3(0, 0, -1) }, + { // X- + QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, -1, 1), + QT3DSVec3(-1, 0, 0) }, + { // Y+ + QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, 1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, 1, 1), QT3DSVec3(0, 1, 0) }, + { // Y- + QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, -1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(1, -1, -1), QT3DSVec3(0, -1, 0) } +}; + +static const QT3DSVec3 g_BoxUVs[] = { + QT3DSVec3(0, 1, 0), QT3DSVec3(0, 0, 0), QT3DSVec3(1, 0, 0), QT3DSVec3(1, 1, 0), +}; + +void NVRenderExampleTools::createBox(NVRenderContext &context, + NVRenderVertexBuffer *&outVertexBuffer, + NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory) +{ + const QT3DSU32 numVerts = 24; + const QT3DSU32 numIndices = 36; + QT3DSVec3 extents = QT3DSVec3(1, 1, 1); + + NVRenderVertexBufferEntry entries[] = { + NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0), + NVRenderVertexBufferEntry("attr_norm", NVRenderComponentTypes::QT3DSF32, 3, 3 * sizeof(QT3DSF32)), + NVRenderVertexBufferEntry("attr_uv", NVRenderComponentTypes::QT3DSF32, 2, 6 * sizeof(QT3DSF32)), + }; + + QT3DSU32 bufStride = 8 * sizeof(QT3DSF32); + QT3DSU32 bufSize = bufStride * numVerts; + outVertexBuffer = context.CreateVertexBuffer( + NVRenderBufferUsageType::Static, NVConstDataRef(entries, 3), 0, + releaseMemory ? 0 : bufSize); + QT3DS_ASSERT(bufStride == outVertexBuffer->GetStride()); + NVDataRef vertData; + if (releaseMemory) + vertData = NVDataRef( + (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "VertexBufferData"), + bufSize); + else + vertData = outVertexBuffer->LockBuffer(bufSize); + QT3DSU8 *positions = (QT3DSU8 *)vertData.begin(); + QT3DSU8 *normals = positions + 3 * sizeof(QT3DSF32); + QT3DSU8 *uvs = normals + 3 * sizeof(QT3DSF32); + + for (QT3DSU32 i = 0; i < 6; i++) { + const BoxFace &bf = g_BoxFaces[i]; + for (QT3DSU32 j = 0; j < 4; j++) { + QT3DSVec3 &p = *(QT3DSVec3 *)positions; + positions = ((QT3DSU8 *)positions) + bufStride; + QT3DSVec3 &n = *(QT3DSVec3 *)normals; + normals = ((QT3DSU8 *)normals) + bufStride; + QT3DSF32 *uv = (QT3DSF32 *)uvs; + uvs = ((QT3DSU8 *)uvs) + bufStride; + n = bf.normal; + p = bf.positions[j].multiply(extents); + uv[0] = g_BoxUVs[j].x; + uv[1] = g_BoxUVs[j].y; + } + } + + if (releaseMemory) { + outVertexBuffer->SetBuffer(vertData, false); + context.GetFoundation().getAllocator().deallocate(vertData.begin()); + } else + outVertexBuffer->UnlockBuffer(); + + bufSize = numIndices * sizeof(QT3DSU16); + outIndexBuffer = + context.CreateIndexBuffer(NVRenderBufferUsageType::Static, NVRenderComponentTypes::QT3DSU16, + releaseMemory ? 0 : bufSize); + NVDataRef indexData; + if (releaseMemory) + indexData = NVDataRef( + (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "IndexData"), + bufSize); + else + indexData = outIndexBuffer->LockBuffer(bufSize); + QT3DSU16 *indices = reinterpret_cast(indexData.begin()); + for (QT3DSU8 i = 0; i < 6; i++) { + const QT3DSU16 base = i * 4; + *(indices++) = base + 0; + *(indices++) = base + 1; + *(indices++) = base + 2; + *(indices++) = base + 0; + *(indices++) = base + 2; + *(indices++) = base + 3; + } + if (releaseMemory) { + outIndexBuffer->SetBuffer(indexData, false); + context.GetFoundation().getAllocator().deallocate(indexData.begin()); + } else + outIndexBuffer->UnlockBuffer(); +} + +namespace { + +inline NVConstDataRef toRef(const char *data) +{ + size_t len = strlen(data) + 1; + return NVConstDataRef((const QT3DSI8 *)data, len); +} + +static void dumpShaderOutput(NVRenderContext &ctx, + const NVRenderVertFragCompilationResult &compResult) +{ + if (!isTrivial(compResult.mFragCompilationOutput)) { + ctx.GetFoundation().error(QT3DS_WARN, "Frag output:\n%s", compResult.mFragCompilationOutput); + } + if (!isTrivial(compResult.mVertCompilationOutput)) { + ctx.GetFoundation().error(QT3DS_WARN, "Vert output:\n%s", compResult.mVertCompilationOutput); + } + if (!isTrivial(compResult.mLinkOutput)) { + ctx.GetFoundation().error(QT3DS_WARN, "Link output:\n%s", compResult.mLinkOutput); + } +} + +NVRenderVertFragShader *compileAndDump(NVRenderContext &ctx, const char *name, + const char *vertShader, const char *fragShader) +{ + NVRenderVertFragCompilationResult compResult = + ctx.CompileSource(name, toRef(vertShader), toRef(fragShader)); + dumpShaderOutput(ctx, compResult); + return compResult.mShader; +} +} + +NVRenderVertFragShader *NVRenderExampleTools::createSimpleShader(NVRenderContext &ctx) +{ + return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShader()); +} + +NVRenderVertFragShader *NVRenderExampleTools::createSimpleShaderTex(NVRenderContext &ctx) +{ + return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShaderTex()); +} \ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h new file mode 100644 index 00000000..5b402868 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EXAMPLE_TOOLS_H +#define QT3DS_RENDER_EXAMPLE_TOOLS_H +#include "Qt3DSRenderExample.h" + +namespace qt3ds { +namespace render { + + class NVRenderExampleTools + { + public: + static const char *getSimpleVertShader() + { + return "uniform mat4 mat_mvp;\n" + "attribute vec3 attr_pos; // Vertex pos\n" + "attribute vec3 attr_norm; // Vertex pos\n" + "attribute vec2 attr_uv; // UV coords\n" + "varying vec4 color_to_add;\n" + "varying vec2 uv_coords;\n" + "void main()\n" + "{\n" + "gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n" + "color_to_add.xyz = attr_norm * attr_norm;\n" + "color_to_add.a = 1.0;\n" + "uv_coords = attr_uv;\n" + "}\n"; + } + + static const char *getSimpleFragShader() + { + return "precision mediump sampler2D;\n" + "precision mediump float;\n" + "varying vec4 color_to_add;\n" + "void main()\n" + "{\n" + "gl_FragColor=color_to_add;\n" + "}\n"; + } + + static const char *getSimpleFragShaderTex() + { + return "precision mediump sampler2D;\n" + "precision mediump float;\n" + "uniform sampler2D image0;\n" + "varying vec2 uv_coords;\n" + "void main()\n" + "{\n" + "gl_FragColor=vec4(texture2D( image0, uv_coords ).xyz, 1.0 );\n" + "}\n"; + } + + static void createBox(NVRenderContext &context, NVRenderVertexBuffer *&outVertexBuffer, + NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory = true); + static NVRenderVertFragShader *createSimpleShader(NVRenderContext &context); + static NVRenderVertFragShader *createSimpleShaderTex(NVRenderContext &context); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp new file mode 100644 index 00000000..e2cb4149 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "Qt3DSRenderExampleTools.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "foundation/Qt3DSVec4.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +namespace { +struct ShaderArgs +{ + float mvp[16]; + NVRenderTexture2DPtr texture; + NVRenderVertFragShaderPtr shader; + ShaderArgs() {} +}; +class RenderToTexture : public NVRenderExample +{ + NVRenderContext &m_Context; + NVScopedRefCounted mVertexBuffer; + NVScopedRefCounted mIndexBuffer; + // Simple shader + NVScopedRefCounted mSimpleShader; + // Simple shader with texture lookup. + NVScopedRefCounted mSimpleShaderTex; + + NVScopedRefCounted mFrameBuffer; + NVScopedRefCounted mColorBuffer; + NVScopedRefCounted mDepthBuffer; + + NVRenderHandle mGroupId; + QT3DSU32 mFBWidth; + QT3DSU32 mFBHeight; + + ShaderArgs mShaderArgs; + float frus[16]; + float model[16]; + float rot[9]; + +public: + RenderToTexture(NVRenderContext &context) + : m_Context(context) + , mFBWidth(400) + , mFBHeight(400) + { + NVRenderExampleTools::createBox(m_Context, mVertexBuffer.mPtr, mIndexBuffer.mPtr); + mVertexBuffer->addRef(); + mIndexBuffer->addRef(); + mSimpleShader = NVRenderExampleTools::createSimpleShader(m_Context); + mSimpleShaderTex = NVRenderExampleTools::createSimpleShaderTex(m_Context); + // If you don't want the depth buffer information back out of the system, then you can + // do this. + // mDepthBuffer = m_Context.CreateRenderBuffer( NVRenderRenderBufferFormats::Depth16, + // mFBWidth, mFBHeight ); + + mDepthBuffer = m_Context.CreateTexture2D(); + mDepthBuffer->SetTextureData(NVDataRef(), 0, mFBWidth, mFBHeight, + NVRenderTextureFormats::Depth16); + mColorBuffer = m_Context.CreateTexture2D(); + mColorBuffer->SetTextureData(NVDataRef(), 0, mFBWidth, mFBHeight, + NVRenderTextureFormats::RGBA8); + if (mDepthBuffer.mPtr && mColorBuffer.mPtr) { + // Creating objects tends to Bind them to their active state hooks. + // So to protect the rest of the system against what they are doing (if we care), we + // need + // to push the current state + // Auto-binds the framebuffer. + mFrameBuffer = m_Context.CreateFrameBuffer(); + mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *mColorBuffer.mPtr); + mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Depth, *mDepthBuffer.mPtr); + QT3DS_ASSERT(mFrameBuffer->IsComplete()); + + m_Context.SetRenderTarget(NULL); + } + mColorBuffer->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + mColorBuffer->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + m_Context.SetVertexBuffer(mVertexBuffer); + m_Context.SetIndexBuffer(mIndexBuffer); + m_Context.SetDepthTestEnabled(true); + m_Context.SetDepthWriteEnabled(true); + m_Context.SetClearColor(QT3DSVec4(.3f)); + // Setup various matrici + NvGl2DemoMatrixIdentity(model); + NvGl2DemoMatrixIdentity(frus); + NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10); + NvGl2DemoMatrixTranslate(model, 0, 0, -4); + mShaderArgs.texture = mColorBuffer.mPtr; + } + void setupMVP(QT3DSVec3 translation) + { + float *mvp(mShaderArgs.mvp); + memCopy(mvp, frus, 16 * sizeof(float)); + NvGl2DemoMatrixMultiply(mvp, model); + NvGl2DemoMatrixTranslate(mvp, translation.x, translation.y, translation.z); + NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot); + } + void DrawIndexedArrays(QT3DSVec3 translation) + { + setupMVP(translation); + m_Context.SetActiveShader(mShaderArgs.shader); + mShaderArgs.shader->Bind(); + mShaderArgs.shader->SetPropertyValue("mat_mvp", + *reinterpret_cast(mShaderArgs.mvp)); + mShaderArgs.shader->SetPropertyValue("image0", mShaderArgs.texture); + m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0); + } + + virtual void drawFrame(double currentSeconds) + { + NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0); + NVRenderClearFlags clearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth); + // render to frame buffer + { + NVRenderContextScopedProperty __framebuffer( + m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget, + mFrameBuffer); + NVRenderContextScopedProperty __viewport( + m_Context, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, + NVRenderRect(0, 0, mFBWidth, mFBHeight)); + NVRenderContextScopedProperty __clearColor( + m_Context, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, + QT3DSVec4(.6f)); + m_Context.Clear(clearFlags); + mShaderArgs.shader = mSimpleShader; + DrawIndexedArrays(QT3DSVec3(0.f)); + } + m_Context.Clear(clearFlags); + mShaderArgs.texture = mColorBuffer; + mShaderArgs.shader = mSimpleShaderTex; + + DrawIndexedArrays(QT3DSVec3(-2.f, 0.f, 0.f)); + + mShaderArgs.texture = mDepthBuffer; + DrawIndexedArrays(QT3DSVec3(2.f, 0.f, 0.f)); + } + virtual QT3DSU32 getRuntimeInSeconds() + { + return mSimpleShader.mPtr && mSimpleShaderTex.mPtr ? 5 : 0; + } + virtual void release() { NVDelete(m_Context.GetFoundation(), this); } +}; +} + +QT3DS_RENDER_REGISTER_EXAMPLE(RenderToTexture); \ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp new file mode 100644 index 00000000..807f0821 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/NVRenderVertFragShader.h" +#include "render_util/NVRenderUtils.h" +#include "Qt3DSRenderExampleTools.h" +#include "foundation/Qt3DSMat44.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +#pragma warning(disable : 4189) +#pragma warning(disable : 4100) + +namespace { + +struct ShaderArguments +{ + QT3DSMat44 mMatrix; +}; + +class SpinningCube : public NVRenderExample +{ + NVRenderContext &m_Context; + NVScopedRefCounted mVertexBuffer; + NVScopedRefCounted mIndexBuffer; + NVScopedRefCounted mShader; + NVRenderHandle mShaderArgGroupId; + float frus[16]; + float model[16]; + float rot[9]; + +public: + SpinningCube(NVRenderContext &ctx) + : m_Context(ctx) + { + NVRenderExampleTools::createBox(ctx, mVertexBuffer.mPtr, mIndexBuffer.mPtr, false); + mVertexBuffer->addRef(); + mIndexBuffer->addRef(); + mShader = NVRenderExampleTools::createSimpleShader(ctx); + ctx.SetViewport(NVRenderRect(0, 0, 400, 400)); + // These properties will get applied just before render no matter what + // so we can just use the default settings here. + ctx.SetVertexBuffer(mVertexBuffer); + ctx.SetIndexBuffer(mIndexBuffer); + if (mShader) { + ctx.SetActiveShader(mShader); + } + ctx.SetDepthTestEnabled(true); + ctx.SetDepthWriteEnabled(true); + NvGl2DemoMatrixIdentity(model); + NvGl2DemoMatrixIdentity(frus); + NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10); + NvGl2DemoMatrixTranslate(model, 0, 0, -4); + } + virtual void drawFrame(double currentSeconds) + { + NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0); + float mvp[16]; + NvGl2DemoMatrixIdentity(mvp); + NvGl2DemoMatrixMultiply(mvp, frus); + NvGl2DemoMatrixMultiply(mvp, model); + NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot); + + NVConstDataRef instance((QT3DSU8 *)mvp, 16 * sizeof(float)); + m_Context.Clear( + NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth)); + mShader->SetPropertyValue("mat_mvp", *reinterpret_cast(mvp)); + m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0); + } + virtual QT3DSU32 getRuntimeInSeconds() { return mShader.mPtr ? 5 : 0; } + virtual void release() { NVDelete(m_Context.GetFoundation(), this); } +}; +} +QT3DS_RENDER_REGISTER_EXAMPLE(SpinningCube); \ No newline at end of file diff --git a/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp new file mode 100644 index 00000000..272c3e8c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderAtomicCounterBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + ///< struct handling a constant buffer entry + class AtomicCounterBufferEntry + { + public: + CRegisteredString m_Name; ///< parameter Name + QT3DSI32 m_Offset; ///< offset into the memory buffer + + AtomicCounterBufferEntry(CRegisteredString name, QT3DSI32 offset) + : m_Name(name) + , m_Offset(offset) + { + } + }; + + NVRenderAtomicCounterBuffer::NVRenderAtomicCounterBuffer( + NVRenderContextImpl &context, CRegisteredString bufferName, size_t size, + NVRenderBufferUsageType::Enum usageType, NVDataRef data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Storage, usageType, data) + , m_Name(bufferName) + , m_AtomicCounterBufferEntryMap( + m_Foundation.getAllocator(), + "NVRenderAtomicCounterBuffer::m_AtomicCounterBufferEntryMap") + , m_Dirty(true) + { + QT3DS_ASSERT(context.IsStorageBufferSupported()); + } + + NVRenderAtomicCounterBuffer::~NVRenderAtomicCounterBuffer() + { + for (TRenderAtomiCounterBufferEntryMap::iterator + iter = m_AtomicCounterBufferEntryMap.begin(), + end = m_AtomicCounterBufferEntryMap.end(); + iter != end; ++iter) { + NVDelete(m_Foundation.getAllocator(), iter->second); + } + + m_AtomicCounterBufferEntryMap.clear(); + + m_Context.BufferDestroyed(*this); + } + + void NVRenderAtomicCounterBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderAtomicCounterBuffer::BindToShaderProgram(QT3DSU32 index) + { + m_Backend->ProgramSetAtomicCounterBuffer(index, m_BufferHandle); + } + + void NVRenderAtomicCounterBuffer::Update() + { + // we only update the buffer if it is dirty and we actually have some data + if (m_Dirty && m_BufferData.size()) { + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, + m_BufferData.begin()); + m_Dirty = false; + } + } + + void NVRenderAtomicCounterBuffer::UpdateData(QT3DSI32 offset, NVDataRef data) + { + // we only update the buffer if we something + if (data.size()) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, + data.begin() + offset); + } + + void NVRenderAtomicCounterBuffer::AddParam(CRegisteredString name, QT3DSU32 offset) + { + if (m_AtomicCounterBufferEntryMap.find(name) == m_AtomicCounterBufferEntryMap.end()) { + AtomicCounterBufferEntry *newEntry = + QT3DS_NEW(m_Foundation.getAllocator(), AtomicCounterBufferEntry)(name, offset); + + if (newEntry) + m_AtomicCounterBufferEntryMap.insert(eastl::make_pair(name, newEntry)); + } else { + // no duplicated entries + return; + } + } + + bool NVRenderAtomicCounterBuffer::ContainsParam(CRegisteredString name) + { + if (m_AtomicCounterBufferEntryMap.find(name) != m_AtomicCounterBufferEntryMap.end()) + return true; + else + return false; + } + + NVRenderAtomicCounterBuffer * + NVRenderAtomicCounterBuffer::Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderAtomicCounterBuffer *retval = NULL; + + if (context.IsAtomicCounterBufferSupported()) { + CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); + QT3DSU32 bufSize = sizeof(NVRenderAtomicCounterBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "AtomicCounterBuffer"); + retval = new (newMem) NVRenderAtomicCounterBuffer( + context, theBufferName, size, usageType, + toDataRef(const_cast(bufferData.begin()), bufferData.size())); + } else { + QT3DS_ASSERT(false); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h new file mode 100644 index 00000000..5ff449ea --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + class AtomicCounterBufferEntry; + + typedef nvhash_map + TRenderAtomiCounterBufferEntryMap; + + ///< Constant (uniform) buffer representation + class QT3DS_AUTOTEST_EXPORT NVRenderAtomicCounterBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] bufferName Name of the buffer. Must match the name used in programs + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, + size_t size, NVRenderBufferUsageType::Enum usageType, + NVDataRef data); + + ///< destructor + virtual ~NVRenderAtomicCounterBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief bind the buffer to a shader program + * + * @param[in] index Index of the constant buffer within the program + * + * @return no return. + */ + virtual void BindToShaderProgram(QT3DSU32 index); + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief update a piece of memory directly within the storage buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 (430) layout which guarantees a specific layout behavior across + *all HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into storage buffer + * @param[in] data pointer to data + * + * @return no return + */ + void UpdateData(QT3DSI32 offset, NVDataRef data); + + /** + * @brief add a parameter to the atomic counter buffer + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] offset Offset in bytes into the buffer + * + * @return no return + */ + void AddParam(CRegisteredString name, QT3DSU32 offset); + + /** + * @brief Check if the buffer contains this param + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * + * @return no return + */ + bool ContainsParam(CRegisteredString name); + + /** + * @brief get the buffer name + * + * @return the buffer name + */ + CRegisteredString GetBufferName() const { return m_Name; } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + /** + * @brief create a NVRenderAtomicCounterBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the buffer object or NULL + */ + static NVRenderAtomicCounterBuffer *Create(NVRenderContextImpl &context, + const char *bufferName, + NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef bufferData); + + private: + CRegisteredString m_Name; ///< buffer name + TRenderAtomiCounterBufferEntryMap + m_AtomicCounterBufferEntryMap; ///< holds the entries of a atomic counter buffer + bool m_Dirty; ///< true if buffer is dirty + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp new file mode 100644 index 00000000..42641a04 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderAttribLayout.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + ///< constructor + NVRenderAttribLayout::NVRenderAttribLayout(NVRenderContextImpl &context, + NVConstDataRef attribs) + : m_Context(context) + , m_Foundation(context.GetFoundation()) + , mRefCount(0) + , m_Backend(context.GetBackend()) + { + m_AttribLayoutHandle = m_Backend->CreateAttribLayout(attribs); + QT3DS_ASSERT(m_AttribLayoutHandle); + } + + ///< destructor + NVRenderAttribLayout::~NVRenderAttribLayout() + { + if (m_AttribLayoutHandle) { + m_Backend->ReleaseAttribLayout(m_AttribLayoutHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h new file mode 100644 index 00000000..da801c8e --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_ATTRIB_LAYOUT_H +#define QT3DS_RENDER_ATTRIB_LAYOUT_H + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + // forward declarations + class NVRenderContextImpl; + class NVRenderBackend; + + ///< this class handles the vertex attribute layout setup + class NVRenderAttribLayout : public NVRefCounted + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] attribs Pointer to attribute list + * + * @return No return. + */ + NVRenderAttribLayout(NVRenderContextImpl &context, + NVConstDataRef attribs); + ///< destructor + ~NVRenderAttribLayout(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendAttribLayoutObject GetAttribLayoutHandle() const + { + return m_AttribLayoutHandle; + } + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + + NVRenderBackend::NVRenderBackendAttribLayoutObject + m_AttribLayoutHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h b/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h new file mode 100644 index 00000000..c988b2f1 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h @@ -0,0 +1,2100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TYPES_H +#define QT3DS_RENDER_QT3DS_RENDER_TYPES_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSMath.h" +#include "foundation/Qt3DSVec2.h" + +namespace qt3ds { + +namespace render { +using namespace foundation; + +#define QT3DS_RENDER_ITERATE_COMPONENT_TYPES \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU8) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI8) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU16) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI16) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU32) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI32) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU64) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI64) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF16) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF32) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF64) + +struct NVRenderComponentTypes +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) x, + QT3DS_RENDER_ITERATE_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_COMPONENT_TYPES + #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + default: + break; + } + return "Unknown"; + } + + static qt3ds::QT3DSU32 getSizeofType(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ + case x: \ + return sizeof(qt3ds::x); + QT3DS_RENDER_ITERATE_COMPONENT_TYPES + #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } +}; + +/** + Define a set of compile-time trait classes that map the enumerations + to actual compile time types and sizeof so we can deal with the enumeration + in generic ways. + */ +template +struct NVRenderComponentTraits +{ + bool force_compile_error; +}; + +/** + Define a compile time mapping from datatype to enumeration. Not that if you + use this with a type that isn't a component type you will get a compilation + error. + */ +template +struct NVRenderComponentTypeToTypeMap +{ + bool force_compile_error; +}; + +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ + template <> \ + struct NVRenderComponentTraits \ +{ \ + typedef x TComponentType; \ + QT3DSU8 mComponentSize; \ + NVRenderComponentTraits() \ + : mComponentSize(sizeof(x)) \ +{ \ +} \ +}; \ + template <> \ + struct NVRenderComponentTypeToTypeMap \ +{ \ + NVRenderComponentTypes::Enum m_ComponentType; \ + NVRenderComponentTypeToTypeMap() \ + : m_ComponentType(NVRenderComponentTypes::x) \ +{ \ +} \ +}; + +QT3DS_RENDER_ITERATE_COMPONENT_TYPES; + +#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + +// Map at compile time from component type to datatype; +template +inline NVRenderComponentTypes::Enum getComponentTypeForType() +{ + return NVRenderComponentTypeToTypeMap().m_ComponentType; +} + +struct NVRenderContextValues +{ + enum Enum { + GLES2 = 1 << 0, + GL2 = 1 << 1, + GLES3 = 1 << 2, + GL3 = 1 << 3, + GLES3PLUS = 1 << 4, + GL4 = 1 << 5, + NullContext = 1 << 6, + }; +}; + +typedef NVFlags NVRenderContextType; + +struct NVRenderClearValues +{ + enum Enum { + Color = 1 << 0, + Depth = 1 << 1, + Stencil = 1 << 3, + Coverage = 1 << 4, + }; +}; + +typedef NVFlags NVRenderClearFlags; + +struct NVRenderQueryType +{ + enum Enum { + Unknown = 0, + Samples, ///< samples query object + Timer, ///< timer query object + }; +}; + +struct NVRenderQueryResultType +{ + enum Enum { + Unknown = 0, + ResultAvailable, ///< Check if query result is available + Result, ///< Get actual result + }; +}; + +struct NVRenderSyncType +{ + enum Enum { + Unknown = 0, + GpuCommandsComplete, ///< sync to Gpu commands finished + }; +}; + +struct NVRenderSyncValues +{ + enum Enum { + Unknown = 0, ///< for future usage + }; +}; + +typedef NVFlags NVRenderSyncFlags; + +struct NVRenderCommandFlushValues +{ + enum Enum { + SyncFlushCommands = 0, ///< sync for flushing command + }; +}; + +typedef NVFlags NVRenderCommandFlushFlags; + +struct NVRenderBufferBindValues +{ + enum Enum { + Unknown = 0, + Vertex = 1 << 0, ///< Bind as vertex buffer + Index = 1 << 1, ///< Bind as index buffer + Constant = 1 << 2, ///< Bind as constant buffer + Storage = 1 << 3, ///< Bind as shader storage buffer + Atomic_Counter = 1 << 4, ///< Bind as atomic counter buffer + Draw_Indirect = 1 << 5, ///< Bind as draw indirect buffer + }; +}; + +typedef NVFlags NVRenderBufferBindFlags; + +struct NVRenderBufferUsageType +{ + enum Enum { + Unknown = 0, + Static, ///< Rarely updated + Dynamic, ///< Most likely updated every frame + }; +}; + +struct NVRenderImageAccessType +{ + enum Enum { + Unknown = 0, + Read, ///< Read only access + Write, ///< Write only access + ReadWrite, ///< Read and write access + }; +}; + +struct NVRenderBufferAccessTypeValues +{ + enum Enum { + Unknown = 0, + Read = 1 << 0, ///< Read access + Write = 1 << 1, ///< Write access + Invalid = 1 << 2, ///< No sync + InvalidRange = 1 << 3, ///< No sync + + }; +}; + +typedef NVFlags NVRenderBufferAccessFlags; + +///< defines a barrier of ordering the memory transactions to a command relative to those issued +///before the barrier +struct NVRenderBufferBarrierValues +{ + enum Enum { + Unknown = 0, + VertexAttribArray = 1 << 0, ///< Barrier for vertex attributes sourced from a buffer + ElementArray = 1 << 1, ///< Barrier for indices sourced from a buffer + UniformBuffer = 1 << 2, ///< Barrier for shader uniforms sourced from a buffer + TextureFetch = 1 << 3, ///< Barrier for texture fetches within shaders + ShaderImageAccess = 1 << 4, ///< Barrier for image access using load / store + CommandBuffer = 1 << 5, ///< Barrier for indirect drawing + PixelBuffer = 1 << 6, ///< Barrier for pixel buffer access + TextureUpdate = 1 << 7, ///< Barrier for texture writes + BufferUpdate = 1 << 8, ///< Barrier for buffer writes + Framebuffer = 1 << 9, ///< Barrier for framebuffer writes + TransformFeedback = 1 << 10, ///< Barrier for transform feedback writes + AtomicCounter = 1 << 11, ///< Barrier for atomic counter writes + ShaderStorage = 1 << 12, ///< Barrier for shader storage blocks writes + All = 0xFFFF, ///< Barrier for all of the above + }; +}; + +typedef NVFlags NVRenderBufferBarrierFlags; + +#define QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA4) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGB565) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA5551) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth16) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth24) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth32) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(StencilIndex8) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(CoverageNV) + +struct NVRenderRenderBufferFormats +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) x, + QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS +#undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS + #undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_TEXTURE_FORMATS \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32I) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32UI) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8A8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB565) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA5551) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Alpha8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance16) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(LuminanceAlpha8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R11G11B10) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB9E5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_DXT1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT3) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_PunchThrough_Alpha1_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_PunchThrough_Alpha1_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA8_ETC2_EAC) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ETC2_EAC) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNSIGNED_FLOAT) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_SIGNED_FLOAT) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_4x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x12) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_4x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x12) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth16) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth32) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24Stencil8) + +struct NVRenderTextureFormats +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) x, +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) x, +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) x, + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS +#undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT +#undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT +#undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + }; + + static bool isUncompressedTextureFormat(NVRenderTextureFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \ + case NVRenderTextureFormats::x: \ + return true; +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT + default: + break; + } + return false; + } + + static bool isCompressedTextureFormat(NVRenderTextureFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \ + case NVRenderTextureFormats::x: \ + return true; +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT + default: + break; + } + return false; + } + + static bool isDepthTextureFormat(NVRenderTextureFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \ + case NVRenderTextureFormats::x: \ + return true; + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT + default: + break; + } + return false; + } + + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + default: + break; + } + return "Unknown"; + } + + static QT3DSU32 getSizeofFormat(Enum value) + { + switch (value) { + case R8: + return 1; + case R16F: + return 2; + case R16: + return 2; + case R32I: + return 4; + case R32F: + return 4; + case RGBA8: + return 4; + case RGB8: + return 3; + case RGB565: + return 2; + case RGBA5551: + return 2; + case Alpha8: + return 1; + case Luminance8: + return 1; + case LuminanceAlpha8: + return 1; + case Depth16: + return 2; + case Depth24: + return 3; + case Depth32: + return 4; + case Depth24Stencil8: + return 4; + case RGB9E5: + return 4; + case SRGB8: + return 3; + case SRGB8A8: + return 4; + case RGBA16F: + return 8; + case RG16F: + return 4; + case RG32F: + return 8; + case RGBA32F: + return 16; + case RGB32F: + return 12; + case R11G11B10: + return 4; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static QT3DSU32 getNumberOfComponent(Enum value) + { + switch (value) { + case R8: + return 1; + case R16F: + return 1; + case R16: + return 1; + case R32I: + return 1; + case R32F: + return 1; + case RGBA8: + return 4; + case RGB8: + return 3; + case RGB565: + return 3; + case RGBA5551: + return 4; + case Alpha8: + return 1; + case Luminance8: + return 1; + case LuminanceAlpha8: + return 2; + case Depth16: + return 1; + case Depth24: + return 1; + case Depth32: + return 1; + case Depth24Stencil8: + return 2; + case RGB9E5: + return 3; + case SRGB8: + return 3; + case SRGB8A8: + return 4; + case RGBA16F: + return 4; + case RG16F: + return 2; + case RG32F: + return 2; + case RGBA32F: + return 4; + case RGB32F: + return 3; + case R11G11B10: + return 3; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static void decodeToFloat(void *inPtr, QT3DSU32 byteOfs, float *outPtr, + NVRenderTextureFormats::Enum inFmt) + { + outPtr[0] = 0.0f; + outPtr[1] = 0.0f; + outPtr[2] = 0.0f; + outPtr[3] = 0.0f; + QT3DSU8 *src = reinterpret_cast(inPtr); + // float divisor; // If we want to support RGBD? + switch (inFmt) { + case Alpha8: + outPtr[0] = ((float)src[byteOfs]) / 255.0f; + break; + + case Luminance8: + case LuminanceAlpha8: + case R8: + case RG8: + case RGB8: + case RGBA8: + case SRGB8: + case SRGB8A8: + // NOTE : RGBD Hack here for reference. Not meant for installation. + // divisor = (NVRenderTextureFormats::getSizeofFormat(inFmt) == 4) ? + // ((float)src[byteOfs+3]) / 255.0f : 1.0f; + for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) { + float val = ((float)src[byteOfs + i]) / 255.0f; + outPtr[i] = (i < 3) ? powf(val, 0.4545454545f) : val; + // Assuming RGBA8 actually means RGBD (which is stupid, I know) + // if ( NVRenderTextureFormats::getSizeofFormat(inFmt) == 4 ) { outPtr[i] /= + // divisor; } + } + // outPtr[3] = divisor; + break; + + case R32F: + outPtr[0] = reinterpret_cast(src + byteOfs)[0]; + break; + case RG32F: + outPtr[0] = reinterpret_cast(src + byteOfs)[0]; + outPtr[1] = reinterpret_cast(src + byteOfs)[1]; + break; + case RGBA32F: + outPtr[0] = reinterpret_cast(src + byteOfs)[0]; + outPtr[1] = reinterpret_cast(src + byteOfs)[1]; + outPtr[2] = reinterpret_cast(src + byteOfs)[2]; + outPtr[3] = reinterpret_cast(src + byteOfs)[3]; + break; + case RGB32F: + outPtr[0] = reinterpret_cast(src + byteOfs)[0]; + outPtr[1] = reinterpret_cast(src + byteOfs)[1]; + outPtr[2] = reinterpret_cast(src + byteOfs)[2]; + break; + + case R16F: + case RG16F: + case RGBA16F: + for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) { + // NOTE : This only works on the assumption that we don't have any denormals, + // Infs or NaNs. + // Every pixel in our source image should be "regular" + QT3DSU16 h = reinterpret_cast(src + byteOfs)[i]; + QT3DSU32 sign = (h & 0x8000) << 16; + QT3DSU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); + QT3DSU32 mantissa = ((h & 0x3ff) << 13); + QT3DSU32 result = sign | exponent | mantissa; + + if (h == 0 || h == 0x8000) { + result = 0; + } // Special case for zero and negative zero + qt3ds::intrinsics::memCopy(reinterpret_cast(outPtr) + i, &result, 4); + } + break; + + case R11G11B10: + // place holder + QT3DS_ASSERT(false); + break; + + default: + outPtr[0] = 0.0f; + outPtr[1] = 0.0f; + outPtr[2] = 0.0f; + outPtr[3] = 0.0f; + break; + } + } + + static void encodeToPixel(float *inPtr, void *outPtr, QT3DSU32 byteOfs, + NVRenderTextureFormats::Enum inFmt) + { + QT3DSU8 *dest = reinterpret_cast(outPtr); + switch (inFmt) { + case NVRenderTextureFormats::Alpha8: + dest[byteOfs] = QT3DSU8(inPtr[0] * 255.0f); + break; + + case Luminance8: + case LuminanceAlpha8: + case R8: + case RG8: + case RGB8: + case RGBA8: + case SRGB8: + case SRGB8A8: + for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) { + inPtr[i] = (inPtr[i] > 1.0f) ? 1.0f : inPtr[i]; + if (i < 3) + dest[byteOfs + i] = QT3DSU8(powf(inPtr[i], 2.2f) * 255.0f); + else + dest[byteOfs + i] = QT3DSU8(inPtr[i] * 255.0f); + } + break; + + case R32F: + reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; + break; + case RG32F: + reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; + reinterpret_cast(dest + byteOfs)[1] = inPtr[1]; + break; + case RGBA32F: + reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; + reinterpret_cast(dest + byteOfs)[1] = inPtr[1]; + reinterpret_cast(dest + byteOfs)[2] = inPtr[2]; + reinterpret_cast(dest + byteOfs)[3] = inPtr[3]; + break; + case RGB32F: + reinterpret_cast(dest + byteOfs)[0] = inPtr[0]; + reinterpret_cast(dest + byteOfs)[1] = inPtr[1]; + reinterpret_cast(dest + byteOfs)[2] = inPtr[2]; + break; + + case R16F: + case RG16F: + case RGBA16F: + for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) { + // NOTE : This also has the limitation of not handling infs, NaNs and + // denormals, but it should be + // sufficient for our purposes. + if (inPtr[i] > 65519.0f) { + inPtr[i] = 65519.0f; + } + if (fabs(inPtr[i]) < 6.10352E-5f) { + inPtr[i] = 0.0f; + } + QT3DSU32 f = reinterpret_cast(inPtr)[i]; + QT3DSU32 sign = (f & 0x80000000) >> 16; + QT3DSI32 exponent = (f & 0x7f800000) >> 23; + QT3DSU32 mantissa = (f >> 13) & 0x3ff; + exponent = exponent - 112; + if (exponent > 31) { + exponent = 31; + } + if (exponent < 0) { + exponent = 0; + } + exponent = exponent << 10; + reinterpret_cast(dest + byteOfs)[i] = + QT3DSU16(sign | exponent | mantissa); + } + break; + + case R11G11B10: + // place holder + QT3DS_ASSERT(false); + break; + + default: + dest[byteOfs] = 0; + dest[byteOfs + 1] = 0; + dest[byteOfs + 2] = 0; + dest[byteOfs + 3] = 0; + break; + } + } +}; + +struct NVRenderTextureTargetType +{ + enum Enum { + Unknown = 0, + Texture2D, + Texture2D_MS, + Texture2D_Array, + TextureCube, + TextureCubePosX, + TextureCubeNegX, + TextureCubePosY, + TextureCubeNegY, + TextureCubePosZ, + TextureCubeNegZ, + }; +}; + +struct NVRenderTextureUnit +{ + enum Enum { + TextureUnit_0 = 0, + TextureUnit_1, + TextureUnit_2, + TextureUnit_3, + TextureUnit_4, + TextureUnit_5, + TextureUnit_6, + TextureUnit_7, + TextureUnit_8, + TextureUnit_9, + TextureUnit_10, + TextureUnit_11, + TextureUnit_12, + TextureUnit_13, + TextureUnit_14, + TextureUnit_15, + TextureUnit_16, + TextureUnit_17, + TextureUnit_18, + TextureUnit_19, + TextureUnit_20, + TextureUnit_21, + TextureUnit_22, + TextureUnit_23, + TextureUnit_24, + TextureUnit_25, + TextureUnit_26, + TextureUnit_27, + TextureUnit_28, + TextureUnit_29, + TextureUnit_30, + TextureUnit_31 + }; +}; + +struct NVRenderTextureCompareMode +{ + enum Enum { Unknown = 0, NoCompare, CompareToRef }; +}; + +struct NVRenderTextureSwizzleMode +{ + enum Enum { NoSwizzle = 0, L8toR8, A8toR8, L8A8toRG8, L16toR16 }; +}; + +#define QT3DS_RENDER_ITERATE_BOOL_OP \ + QT3DS_RENDER_HANDLE_BOOL_OP(Never) \ + QT3DS_RENDER_HANDLE_BOOL_OP(Less) \ + QT3DS_RENDER_HANDLE_BOOL_OP(LessThanOrEqual) \ + QT3DS_RENDER_HANDLE_BOOL_OP(Equal) \ + QT3DS_RENDER_HANDLE_BOOL_OP(NotEqual) \ + QT3DS_RENDER_HANDLE_BOOL_OP(Greater) \ + QT3DS_RENDER_HANDLE_BOOL_OP(GreaterThanOrEqual) \ + QT3DS_RENDER_HANDLE_BOOL_OP(AlwaysTrue) + +struct NVRenderTextureCompareOp +{ + enum Enum { +#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x, + QT3DS_RENDER_ITERATE_BOOL_OP +#undef QT3DS_RENDER_HANDLE_BOOL_OP + }; +}; + +#define QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP \ + QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Nearest) \ + QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Linear) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapNearest) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapNearest) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapLinear) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapLinear) + +struct NVRenderTextureMinifyingOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x, +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) x, + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + }; + const char *toString(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderTextureMagnifyingOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x, +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + }; + const char *toString(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP \ + QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(ClampToEdge) \ + QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(MirroredRepeat) \ + QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(Repeat) + +struct NVRenderTextureCoordOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) x, + QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP + }; + const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_HINT \ + QT3DS_RENDER_HANDLE_HINT(Fastest) \ + QT3DS_RENDER_HANDLE_HINT(Nicest) \ + QT3DS_RENDER_HANDLE_HINT(Unspecified) + +struct NVRenderHint +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_HINT(x) x, + QT3DS_RENDER_ITERATE_HINT +#undef QT3DS_RENDER_HANDLE_HINT + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_HINT(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_HINT + #undef QT3DS_RENDER_HANDLE_HINT + default: + break; + } + return "Unknown"; + } +}; + +class NVRenderImplemented +{ +protected: + virtual ~NVRenderImplemented() {} +public: + // Get the handle that binds us to the implementation. + // For instance, return the GLuint that came back from + // glGenTextures. + virtual const void *GetImplementationHandle() const = 0; +}; + +struct NVRenderVertexBufferEntry +{ + const char *m_Name; + /** Datatype of the this entry points to in the buffer */ + NVRenderComponentTypes::Enum m_ComponentType; + /** Number of components of each data member. 1,2,3, or 4. Don't be stupid.*/ + QT3DSU32 m_NumComponents; + /** Offset from the beginning of the buffer of the first item */ + QT3DSU32 m_FirstItemOffset; + /** Attribute input slot used for this entry*/ + QT3DSU32 m_InputSlot; + + NVRenderVertexBufferEntry(const char *nm, NVRenderComponentTypes::Enum type, + QT3DSU32 numComponents, QT3DSU32 firstItemOffset = 0, + QT3DSU32 inputSlot = 0) + : m_Name(nm) + , m_ComponentType(type) + , m_NumComponents(numComponents) + , m_FirstItemOffset(firstItemOffset) + , m_InputSlot(inputSlot) + { + } + + NVRenderVertexBufferEntry() + : m_Name(NULL) + , m_ComponentType(NVRenderComponentTypes::Unknown) + , m_NumComponents(0) + , m_FirstItemOffset(0) + , m_InputSlot(0) + { + } + + NVRenderVertexBufferEntry(const NVRenderVertexBufferEntry &inOther) + : m_Name(inOther.m_Name) + , m_ComponentType(inOther.m_ComponentType) + , m_NumComponents(inOther.m_NumComponents) + , m_FirstItemOffset(inOther.m_FirstItemOffset) + , m_InputSlot(inOther.m_InputSlot) + { + } + + NVRenderVertexBufferEntry &operator=(const NVRenderVertexBufferEntry &inOther) + { + if (this != &inOther) { + m_Name = inOther.m_Name; + m_ComponentType = inOther.m_ComponentType; + m_NumComponents = inOther.m_NumComponents; + m_FirstItemOffset = inOther.m_FirstItemOffset; + m_InputSlot = inOther.m_InputSlot; + } + return *this; + } +}; + +class NVRenderShaderProgram; + +typedef NVConstDataRef TConstI8Ref; + +struct NVRenderVertFragCompilationResult +{ + const char *mShaderName; + + NVRenderShaderProgram *mShader; ///< contains the program + + NVRenderVertFragCompilationResult() + : mShaderName("") + , mShader(NULL) + { + } +}; + +#define QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color0) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color1) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color2) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color3) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color4) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color5) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color6) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color7) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Depth) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Stencil) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(DepthStencil) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(CoverageNV) + +struct NVRenderFrameBufferAttachments +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(x) x, + QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT + LastAttachment, + }; +}; + +struct NVRenderDrawMode +{ + enum Enum { + Unknown = 0, + Points, + LineStrip, + LineLoop, + Lines, + TriangleStrip, + TriangleFan, + Triangles, + Patches, + }; +}; + +struct NVRenderTextureCubeFaces +{ + enum Enum { + InvalidFace = 0, + CubePosX = 1, + CubeNegX, + CubePosY, + CubeNegY, + CubePosZ, + CubeNegZ, + }; +}; + +// enums match the NV path extensions +struct NVRenderPathCommands +{ + enum Enum { + Close = 0, + MoveTo = 2, + CubicCurveTo = 12, + }; +}; + +struct NVRenderPathFontTarget +{ + enum Enum { + StandardFont = 0, + SystemFont = 1, + FileFont = 2, + }; +}; + +struct NVRenderPathMissingGlyphs +{ + enum Enum { + SkipMissing = 0, + UseMissing = 1, + }; +}; + +struct NVRenderPathFontStyleValues +{ + enum Enum { + Bold = 1 << 0, + Italic = 1 << 1, + }; +}; + +typedef NVFlags NVRenderPathFontStyleFlags; + +struct NVRenderPathReturnValues +{ + enum Enum { + FontGlypsAvailable = 0, + FontTargetUnavailable = 1, + FontUnavailable = 2, + FontUnintelligible = 3, + InvalidEnum = 4, + OutOfMemory = 5, + }; +}; + +struct NVRenderPathFormatType +{ + enum Enum { + Byte = 1, + UByte, + Short, + UShort, + Int, + Uint, + Float, + Utf8, + Utf16, + Bytes2, + Bytes3, + Bytes4, + }; +}; + +struct NVRenderPathGlyphFontMetricValues +{ + enum Enum { + GlyphWidth = 1 << 0, + GlyphHeight = 1 << 1, + GlyphHorizontalBearingX = 1 << 2, + GlyphHorizontalBearingY = 1 << 3, + GlyphHorizontalBearingAdvance = 1 << 4, + GlyphVerticalBearingX = 1 << 5, + GlyphVerticalBearingY = 1 << 6, + GlyphVerticalBearingAdvance = 1 << 7, + GlyphHasKerning = 1 << 8, + + FontXMinBounds = 1 << 9, + FontYMinBounds = 1 << 10, + FontXMaxBounds = 1 << 11, + FontYMaxBounds = 1 << 12, + FontUnitsPerEm = 1 << 13, + FontAscender = 1 << 14, + FontDescender = 1 << 15, + FontHeight = 1 << 16, + FontMaxAdvanceWidth = 1 << 17, + FontMaxAdvanceHeight = 1 << 18, + FontUnderlinePosition = 1 << 19, + FontUnderlineThickness = 1 << 20, + FontHasKerning = 1 << 21, + FontNumGlyphIndices = 1 << 22, + }; +}; + +typedef NVFlags +NVRenderPathGlyphFontMetricFlags; + +struct NVRenderPathListMode +{ + enum Enum { + AccumAdjacentPairs = 1, + AdjacentPairs, + FirstToRest, + }; +}; + +struct NVRenderPathFillMode +{ + enum Enum { + Fill = 1, + CountUp, + CountDown, + Invert, + }; +}; + +struct NVRenderPathCoverMode +{ + enum Enum { + ConvexHull = 1, + BoundingBox, + BoundingBoxOfBoundingBox, + PathFillCover, + PathStrokeCover, + }; +}; + +struct NVRenderPathTransformType +{ + enum Enum { + NoTransform = 0, + TranslateX, + TranslateY, + Translate2D, + Translate3D, + Affine2D, + Affine3D, + TransposeAffine2D, + TransposeAffine3D, + }; +}; + +#define QT3DS_RENDER_ITERATE_WINDING \ + QT3DS_RENDER_HANDLE_WINDING(Clockwise) \ + QT3DS_RENDER_HANDLE_WINDING(CounterClockwise) + +struct NVRenderWinding +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_WINDING(x) x, + QT3DS_RENDER_ITERATE_WINDING +#undef QT3DS_RENDER_HANDLE_WINDING + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_WINDING(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_WINDING + #undef QT3DS_RENDER_HANDLE_WINDING + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_RENDER_STATE \ + QT3DS_RENDER_HANDLE_RENDER_STATE(Blend) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(CullFace) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(DepthTest) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(StencilTest) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(ScissorTest) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(DepthWrite) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(Multisample) + +struct NVRenderState +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) x, + QT3DS_RENDER_ITERATE_RENDER_STATE +#undef QT3DS_RENDER_HANDLE_RENDER_STATE + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_RENDER_STATE + #undef QT3DS_RENDER_HANDLE_RENDER_STATE + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_BLEND_FUNC \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(Zero) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(One) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(DstColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(DstAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantAlpha) \ + QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(SrcAlphaSaturate) + +struct NVRenderSrcBlendFunc +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x, +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) x, + QT3DS_RENDER_ITERATE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC + }; + + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_BLEND_FUNC + #undef QT3DS_RENDER_HANDLE_BLEND_FUNC + #undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderDstBlendFunc +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x, +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) + QT3DS_RENDER_ITERATE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC + }; + + static const char *toString(Enum value) + { + return NVRenderSrcBlendFunc::toString((NVRenderSrcBlendFunc::Enum)value); + } +}; + +#define QT3DS_RENDER_ITERATE_BLEND_EQUATION \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(Add) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(Subtract) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(ReverseSubtract) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(Overlay) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorBurn) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorDodge) + +struct NVRenderBlendEquation +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) x, + QT3DS_RENDER_ITERATE_BLEND_EQUATION +#undef QT3DS_RENDER_HANDLE_BLEND_EQUATION + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_BLEND_EQUATION + #undef QT3DS_RENDER_HANDLE_BLEND_EQUATION + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_FACES \ + QT3DS_RENDER_HANDLE_FACES(Front) \ + QT3DS_RENDER_HANDLE_FACES(Back) \ + QT3DS_RENDER_HANDLE_FACES(FrontAndBack) + +struct NVRenderFaces +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_FACES(x) x, + QT3DS_RENDER_ITERATE_FACES +#undef QT3DS_RENDER_HANDLE_FACES + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_FACES(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_FACES + #undef QT3DS_RENDER_HANDLE_FACES + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_READ_FACES \ + QT3DS_RENDER_HANDLE_READ_FACES(Front) \ + QT3DS_RENDER_HANDLE_READ_FACES(Back) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color0) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color1) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color2) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color3) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color4) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color5) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color6) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color7) + +struct NVReadFaces +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_READ_FACES(x) x, + QT3DS_RENDER_ITERATE_READ_FACES +#undef QT3DS_RENDER_HANDLE_READ_FACES + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_READ_FACES(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_READ_FACES + #undef QT3DS_RENDER_HANDLE_READ_FACES + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderBoolOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x, + QT3DS_RENDER_ITERATE_BOOL_OP +#undef QT3DS_RENDER_HANDLE_BOOL_OP + }; + + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_BOOL_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_BOOL_OP + #undef QT3DS_RENDER_HANDLE_BOOL_OP + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_STENCIL_OP \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Keep) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Zero) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Replace) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Increment) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(IncrementWrap) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Decrement) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(DecrementWrap) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Invert) + +struct NVRenderStencilOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) x, + QT3DS_RENDER_ITERATE_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_STENCIL_OP + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_STENCIL_OP + #undef QT3DS_RENDER_HANDLE_STENCIL_OP + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderBlendFunctionArgument +{ + NVRenderSrcBlendFunc::Enum m_SrcRGB; + NVRenderDstBlendFunc::Enum m_DstRGB; + NVRenderSrcBlendFunc::Enum m_SrcAlpha; + NVRenderDstBlendFunc::Enum m_DstAlpha; + + NVRenderBlendFunctionArgument(NVRenderSrcBlendFunc::Enum srcRGB, + NVRenderDstBlendFunc::Enum dstRGB, + NVRenderSrcBlendFunc::Enum srcAlpha, + NVRenderDstBlendFunc::Enum dstAlpha) + : m_SrcRGB(srcRGB) + , m_DstRGB(dstRGB) + , m_SrcAlpha(srcAlpha) + , m_DstAlpha(dstAlpha) + { + } + + // Default blend system premultiplies values. + NVRenderBlendFunctionArgument() + : m_SrcRGB(NVRenderSrcBlendFunc::SrcAlpha) + , m_DstRGB(NVRenderDstBlendFunc::OneMinusSrcAlpha) + , m_SrcAlpha(NVRenderSrcBlendFunc::One) + , m_DstAlpha(NVRenderDstBlendFunc::OneMinusSrcAlpha) + { + } +}; + +struct NVRenderBlendEquationArgument +{ + NVRenderBlendEquation::Enum m_RGBEquation; + NVRenderBlendEquation::Enum m_AlphaEquation; + + NVRenderBlendEquationArgument(NVRenderBlendEquation::Enum rgb, + NVRenderBlendEquation::Enum alpha) + : m_RGBEquation(rgb) + , m_AlphaEquation(alpha) + { + } + NVRenderBlendEquationArgument() + : m_RGBEquation(NVRenderBlendEquation::Add) + , m_AlphaEquation(NVRenderBlendEquation::Add) + { + } +}; + +struct NVRenderStencilOperationArgument +{ + NVRenderStencilOp::Enum m_StencilFail; // What happens when stencil test fails. + // These values assume the stencil passed + NVRenderStencilOp::Enum + m_DepthFail; // What happens when the stencil passes but depth test fail. + NVRenderStencilOp::Enum m_DepthPass; // What happens when the stencil and depth tests pass. + + NVRenderStencilOperationArgument(NVRenderStencilOp::Enum fail, + NVRenderStencilOp::Enum depthFail, + NVRenderStencilOp::Enum depthPass) + : m_StencilFail(fail) + , m_DepthFail(depthFail) + , m_DepthPass(depthPass) + { + } + NVRenderStencilOperationArgument() + : m_StencilFail(NVRenderStencilOp::Keep) + , m_DepthFail(NVRenderStencilOp::Keep) + , m_DepthPass(NVRenderStencilOp::Keep) + { + } + NVRenderStencilOperationArgument(const NVRenderStencilOperationArgument &StencilOp) + : m_StencilFail(StencilOp.m_StencilFail) + , m_DepthFail(StencilOp.m_DepthFail) + , m_DepthPass(StencilOp.m_DepthPass) + { + } + + NVRenderStencilOperationArgument &operator=(const NVRenderStencilOperationArgument &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_StencilFail = rhs.m_StencilFail; + m_DepthFail = rhs.m_DepthFail; + m_DepthPass = rhs.m_DepthPass; + + return *this; + } + + bool operator==(const NVRenderStencilOperationArgument &other) const + { + return (m_StencilFail == other.m_StencilFail && m_DepthFail == other.m_DepthFail + && m_DepthPass == other.m_DepthPass); + } +}; + +// see glStencilFuncSeparate +struct NVRenderStencilFunctionArgument +{ + NVRenderBoolOp::Enum m_Function; + QT3DSU32 m_ReferenceValue; + QT3DSU32 m_Mask; + + NVRenderStencilFunctionArgument(NVRenderBoolOp::Enum function, QT3DSU32 referenceValue, + QT3DSU32 mask) + : m_Function(function) + , m_ReferenceValue(referenceValue) + , m_Mask(mask) + { + } + NVRenderStencilFunctionArgument() + : m_Function(NVRenderBoolOp::AlwaysTrue) + , m_ReferenceValue(0) + , m_Mask((QT3DSU32)-1) + { + } + NVRenderStencilFunctionArgument(const NVRenderStencilFunctionArgument &StencilFunc) + : m_Function(StencilFunc.m_Function) + , m_ReferenceValue(StencilFunc.m_ReferenceValue) + , m_Mask(StencilFunc.m_Mask) + { + } + + NVRenderStencilFunctionArgument &operator=(const NVRenderStencilFunctionArgument &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_Function = rhs.m_Function; + m_ReferenceValue = rhs.m_ReferenceValue; + m_Mask = rhs.m_Mask; + + return *this; + } + + bool operator==(const NVRenderStencilFunctionArgument &other) const + { + return (m_Function == other.m_Function && m_ReferenceValue == other.m_ReferenceValue + && m_Mask == other.m_Mask); + } +}; + +class NVRenderFrameBuffer; +class NVRenderVertexBuffer; +class NVRenderIndexBuffer; +class NVRenderShaderProgram; +class NVRenderProgramPipeline; +class NVRenderTextureBase; +class NVRenderTexture2D; +class NVRenderTexture2DArray; +class NVRenderTextureCube; +class NVRenderImage2D; +class NVRenderDataBuffer; +class NVRenderAttribLayout; +class NVRenderInputAssembler; + +typedef NVRenderFrameBuffer *NVRenderFrameBufferPtr; +typedef NVRenderVertexBuffer *NVRenderVertexBufferPtr; +typedef NVRenderIndexBuffer *NVRenderIndexBufferPtr; +typedef NVRenderTexture2D *NVRenderTexture2DPtr; +typedef NVRenderTexture2DPtr *NVRenderTexture2DHandle; +typedef NVRenderTexture2DArray *NVRenderTexture2DArrayPtr; +typedef NVRenderTextureCube *NVRenderTextureCubePtr; +typedef NVRenderTextureCubePtr *NVRenderTextureCubeHandle; +typedef NVRenderImage2D *NVRenderImage2DPtr; +typedef NVRenderDataBuffer *NVRenderDataBufferPtr; +typedef const char *NVRenderConstCharPtr; +typedef bool QT3DSRenderBool; +typedef NVRenderShaderProgram *NVRenderShaderProgramPtr; +typedef NVDataRef NVU32List; +typedef NVDataRef NVConstCharPtrList; + +template +struct NVRenderRectT +{ + typedef TDataType TRectType; + TDataType m_X; + TDataType m_Y; + TDataType m_Width; + TDataType m_Height; + NVRenderRectT(TDataType x, TDataType y, TDataType w, TDataType h) + : m_X(x) + , m_Y(y) + , m_Width(w) + , m_Height(h) + { + } + NVRenderRectT() + : m_X(0) + , m_Y(0) + , m_Width(0) + , m_Height(0) + { + } + bool operator==(const NVRenderRectT &inOther) const + { + return m_X == inOther.m_X && m_Y == inOther.m_Y && m_Width == inOther.m_Width + && m_Height == inOther.m_Height; + } + bool operator!=(const NVRenderRectT &inOther) const + { + return !(*this == inOther); + } + TDataType GetRightExtent() const { return m_X + m_Width; } + TDataType GetBottomExtent() const { return m_Y + m_Height; } + // Ensure this rect is inside the bounds of the other rect + void EnsureInBounds(const NVRenderRectT &inOther) + { + TDataType rightExtent = qt3ds::NVMin(GetRightExtent(), inOther.GetRightExtent()); + TDataType bottomExtent = qt3ds::NVMin(GetBottomExtent(), inOther.GetBottomExtent()); + m_X = qt3ds::NVMax(m_X, inOther.m_X); + m_Y = qt3ds::NVMax(m_Y, inOther.m_Y); + m_Width = NVMax(static_cast(0), rightExtent - m_X); + m_Height = NVMax(static_cast(0), bottomExtent - m_Y); + } +}; + +// Render rects are setup to be in the coordinate space of the gl viewport, +// so x, y are left, bottom with increasing units going to the right and +// up respectively. +struct NVRenderRect : public NVRenderRectT +{ + typedef NVRenderRectT TBase; + NVRenderRect(QT3DSI32 x, QT3DSI32 y, QT3DSI32 w, QT3DSI32 h) + : TBase(x, y, w, h) + { + } + NVRenderRect() + : TBase() + { + } +}; + +struct NVRenderRectF : public NVRenderRectT +{ + typedef NVRenderRectT TBase; + NVRenderRectF(QT3DSF32 x, QT3DSF32 y, QT3DSF32 w, QT3DSF32 h) + : TBase(x, y, w, h) + { + } + NVRenderRectF() + : TBase() + { + } + NVRenderRectF(const NVRenderRect &inRect) + : TBase((QT3DSF32)inRect.m_X, (QT3DSF32)inRect.m_Y, (QT3DSF32)inRect.m_Width, + (QT3DSF32)inRect.m_Height) + { + } + NVRenderRect ToIntegerRect() const + { + return NVRenderRect((QT3DSI32)m_X, (QT3DSI32)m_Y, (QT3DSU32)(m_Width + .5f), + (QT3DSU32)(m_Height + .5f)); + } + QT3DSVec2 BottomLeft() const { return QT3DSVec2(m_X, m_Y); } + QT3DSVec2 Center() const + { + QT3DSVec2 halfDims = HalfDims(); + return QT3DSVec2(m_X + halfDims.x, m_Y + halfDims.y); + } + QT3DSVec2 HalfDims() const { return QT3DSVec2(m_Width / 2.0f, m_Height / 2.0f); } + // Normalized coordinates are in the range of -1,1 where -1 is the left, bottom edges + // and 1 is the top,right edges. + QT3DSVec2 AbsoluteToNormalizedCoordinates(QT3DSVec2 absoluteCoordinates) const + { + QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates)); + return RelativeToNormalizedCoordinates(relativeCoords); + }; + + QT3DSVec2 RelativeToNormalizedCoordinates(QT3DSVec2 rectRelativeCoords) const + { + QT3DSVec2 halfDims(HalfDims()); + QT3DSVec2 retval((rectRelativeCoords.x / halfDims.x) - 1.0f, + (rectRelativeCoords.y / halfDims.y) - 1.0f); + return retval; + } + + // Take coordinates in global space and move local space where 0,0 is the center + // of the rect but return value in pixels, not in normalized -1,1 range + QT3DSVec2 ToNormalizedRectRelative(QT3DSVec2 absoluteCoordinates) const + { + // normalize them + QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates)); + QT3DSVec2 halfDims(HalfDims()); + QT3DSVec2 normalized((relativeCoords.x / halfDims.x) - 1.0f, + (relativeCoords.y / halfDims.y) - 1.0f); + return QT3DSVec2(normalized.x * halfDims.x, normalized.y * halfDims.y); + } + + // Return coordinates in pixels but relative to this rect. + QT3DSVec2 ToRectRelative(QT3DSVec2 absoluteCoordinates) const + { + return QT3DSVec2(absoluteCoordinates.x - m_X, absoluteCoordinates.y - m_Y); + } + + QT3DSVec2 ToAbsoluteCoords(QT3DSVec2 inRelativeCoords) const + { + return QT3DSVec2(inRelativeCoords.x + m_X, inRelativeCoords.y + m_Y); + } +}; + +template +struct NVRenderGenericVec2 +{ + TDataType x; + TDataType y; + NVRenderGenericVec2(TDataType _x, TDataType _y) + : x(_x) + , y(_y) + { + } + NVRenderGenericVec2() {} + bool operator==(const NVRenderGenericVec2 &inOther) const + { + return x == inOther.x && y == inOther.y; + } +}; + +template +struct NVRenderGenericVec3 +{ + TDataType x; + TDataType y; + TDataType z; + NVRenderGenericVec3(TDataType _x, TDataType _y, TDataType _z) + : x(_x) + , y(_y) + , z(_z) + { + } + NVRenderGenericVec3() {} + bool operator==(const NVRenderGenericVec3 &inOther) const + { + return x == inOther.x && y == inOther.y && z == inOther.z; + } +}; + +template +struct NVRenderGenericVec4 +{ + TDataType x; + TDataType y; + TDataType z; + TDataType w; + NVRenderGenericVec4(TDataType _x, TDataType _y, TDataType _z, TDataType _w) + : x(_x) + , y(_y) + , z(_z) + , w(_w) + { + } + NVRenderGenericVec4() {} + bool operator==(const NVRenderGenericVec4 &inOther) const + { + return x == inOther.x && y == inOther.y && z == inOther.z && w == inOther.w; + } +}; + +#define DECLARE_GENERIC_VECTOR_TYPE(type, numElems) \ + typedef NVRenderGenericVec##numElems type##_##numElems +DECLARE_GENERIC_VECTOR_TYPE(bool, 2); +DECLARE_GENERIC_VECTOR_TYPE(bool, 3); +DECLARE_GENERIC_VECTOR_TYPE(bool, 4); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 2); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 3); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 4); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 2); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 3); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 4); + +#define ITERATE_QT3DS_SHADER_DATA_TYPES \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSRenderBool) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(bool_2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(bool_3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(bool_4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSF32) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat33) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat44) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DHandle) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DArrayPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubePtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubeHandle) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderImage2DPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderDataBufferPtr) + +struct NVRenderShaderDataTypes +{ + enum Enum { + Unknown = 0, +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) type, + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + }; +}; + +template +struct NVDataTypeToShaderDataTypeMap +{ +}; + +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ + template <> \ + struct NVDataTypeToShaderDataTypeMap \ +{ \ + static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::type; } \ +}; +ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + +template <> +struct NVDataTypeToShaderDataTypeMap> +{ + static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::QT3DSMat44; } +}; + +struct NVRenderShaderTypeValue +{ + enum Enum { + Unknown = 1 << 0, + Vertex = 1 << 1, + Fragment = 1 << 2, + TessControl = 1 << 3, + TessEvaluation = 1 << 4, + Geometry = 1 << 5 + }; +}; + +typedef NVFlags NVRenderShaderTypeFlags; + +struct NVRenderTextureTypeValue +{ + enum Enum { + Unknown = 0, + Diffuse, + Specular, + Environment, + Bump, + Normal, + Displace, + Emissive, + Emissive2, + Anisotropy, + Translucent, + LightmapIndirect, + LightmapRadiosity, + LightmapShadow + }; + + static const char *toString(NVRenderTextureTypeValue::Enum value) + { + switch (value) { + case Unknown: + return "Unknown"; + case Diffuse: + return "Diffuse"; + case Specular: + return "Specular"; + case Environment: + return "Environment"; + case Bump: + return "Bump"; + case Normal: + return "Normal"; + case Displace: + return "Displace"; + case Emissive: + return "Emissive"; + case Emissive2: + return "Emissive2"; + case Anisotropy: + return "Anisotropy"; + case Translucent: + return "Translucent"; + case LightmapIndirect: + return "LightmapIndirect"; + case LightmapRadiosity: + return "LightmapRadiosity"; + case LightmapShadow: + return "LightmapShadow"; + default: + return "Unknown"; + } + } +}; + +#define ITERATE_QT3DS_READ_PIXEL_FORMATS \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(Alpha8) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB565) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB8) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA4444) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA5551) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA8) + +struct NVRenderReadPixelFormats +{ + enum Enum { + Unknown = 0, +#define HANDLE_QT3DS_READ_PIXEL_FORMAT(format) format, + ITERATE_QT3DS_READ_PIXEL_FORMATS +#undef HANDLE_QT3DS_READ_PIXEL_FORMAT + }; +}; + +// Now for scoped property access. +template +struct NVRenderGenericScopedProperty +{ + typedef void (TBaseType::*TSetter)(TDataType inType); + typedef TDataType (TBaseType::*TGetter)() const; + + TBaseType &m_Context; + TSetter m_Setter; + TDataType m_InitialValue; + NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter) + : m_Context(ctx) + , m_Setter(setter) + , m_InitialValue(((ctx).*getter)()) + { + } + NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter, + const TDataType &inNewValue) + : m_Context(ctx) + , m_Setter(setter) + , m_InitialValue(((ctx).*getter)()) + { + ((m_Context).*m_Setter)(inNewValue); + } + ~NVRenderGenericScopedProperty() { ((m_Context).*m_Setter)(m_InitialValue); } +}; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp b/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp new file mode 100644 index 00000000..01aef473 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderComputeShader.h" + +namespace qt3ds { +namespace render { + + NVRenderComputeShader::NVRenderComputeShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, NVConstDataRef source, + bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateComputeShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderComputeShader::~NVRenderComputeShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseComputeShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderComputeShader.h b/src/Runtime/Source/render/Qt3DSRenderComputeShader.h new file mode 100644 index 00000000..1ab36bc0 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderComputeShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_COMPUTE_SHADER_H +#define QT3DS_RENDER_COMPUTE_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a compute shader + class NVRenderComputeShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderComputeShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram); + + /// @brief destructor + ~NVRenderComputeShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendComputeShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendComputeShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp new file mode 100644 index 00000000..1b3c43a9 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderConstantBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + ///< struct handling a constant buffer entry + class ConstantBufferParamEntry + { + public: + CRegisteredString m_Name; ///< parameter Name + NVRenderShaderDataTypes::Enum m_Type; ///< parameter type + QT3DSI32 m_Count; ///< one or array size + QT3DSI32 m_Offset; ///< offset into the memory buffer + + ConstantBufferParamEntry(CRegisteredString name, NVRenderShaderDataTypes::Enum type, + QT3DSI32 count, QT3DSI32 offset) + : m_Name(name) + , m_Type(type) + , m_Count(count) + , m_Offset(offset) + { + } + }; + + NVRenderConstantBuffer::NVRenderConstantBuffer(NVRenderContextImpl &context, + CRegisteredString bufferName, size_t size, + NVRenderBufferUsageType::Enum usageType, + NVDataRef data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Constant, usageType, NVDataRef()) + , m_Name(bufferName) + , m_ConstantBufferEntryMap(m_Foundation.getAllocator(), + "NVRenderConstantBuffer::m_ConstantBufferEntryMap") + , m_CurrentOffset(0) + , m_CurrentSize(0) + , m_HWBufferInitialized(false) + , m_Dirty(true) + , m_RangeStart(0) + , m_RangeEnd(0) + , m_MaxBlockSize(0) + { + QT3DS_ASSERT(context.GetConstantBufferSupport()); + + m_Backend->GetRenderBackendValue( + NVRenderBackend::NVRenderBackendQuery::MaxConstantBufferBlockSize, &m_MaxBlockSize); + + if (size && data.size() && size == data.size()) { + QT3DS_ASSERT(size < (QT3DSU32)m_MaxBlockSize); + if (allocateShadowBuffer(data.size())) { + memcpy(m_ShadowCopy.begin(), data.begin(), data.size()); + } + } + } + + NVRenderConstantBuffer::~NVRenderConstantBuffer() + { + // check if we should release memory + if (m_ShadowCopy.size()) { + m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin()); + } + + m_ShadowCopy = NVDataRef(); + + for (TRenderConstantBufferEntryMap::iterator iter = m_ConstantBufferEntryMap.begin(), + end = m_ConstantBufferEntryMap.end(); + iter != end; ++iter) { + NVDelete(m_Foundation.getAllocator(), iter->second); + } + + m_ConstantBufferEntryMap.clear(); + + m_Context.BufferDestroyed(*this); + } + + void NVRenderConstantBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderConstantBuffer::BindToShaderProgram(NVRenderShaderProgram *inShader, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + if ((QT3DSI32)binding == -1) { + binding = m_Context.GetNextConstantBufferUnit(); + m_Backend->ProgramSetConstantBlock(inShader->GetShaderProgramHandle(), blockIndex, + binding); + } + + m_Backend->ProgramSetConstantBuffer(binding, m_BufferHandle); + } + + bool NVRenderConstantBuffer::SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, + QT3DSI32 bufSize, QT3DSI32 paramCount) + { + bool bSuccess = false; + + if (!m_HWBufferInitialized) { + // allocate shadow buffer + QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate( + bufSize, "NVRenderConstantBuffer", __FILE__, __LINE__); + if (!newMem) + return false; + + // allocate temp buffers to hold constant buffer information + QT3DSI32 *theIndices = NULL, *theTypes = NULL, *theSizes = NULL, *theOffsets = NULL; + theIndices = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theIndices) + goto fail; + theTypes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theTypes) + goto fail; + theSizes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theSizes) + goto fail; + theOffsets = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theOffsets) + goto fail; + + bSuccess = true; + + // get indices for the individal constant buffer entries + m_Backend->GetConstantBufferParamIndices(pProgram->GetShaderProgramHandle(), index, + theIndices); + + // get constant buffer uniform information + m_Backend->GetConstantBufferParamInfoByIndices(pProgram->GetShaderProgramHandle(), + paramCount, (QT3DSU32 *)theIndices, + theTypes, theSizes, theOffsets); + + // get the names of the uniforms + char nameBuf[512]; + QT3DSI32 elementCount, binding; + NVRenderShaderDataTypes::Enum type; + + QT3DS_FOREACH(idx, paramCount) + { + m_Backend->GetConstantInfoByID(pProgram->GetShaderProgramHandle(), theIndices[idx], + 512, &elementCount, &type, &binding, nameBuf); + // check if we already have this entry + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + TRenderConstantBufferEntryMap::iterator entry = + m_ConstantBufferEntryMap.find(theName); + if (entry != m_ConstantBufferEntryMap.end()) { + ConstantBufferParamEntry *pParam = entry->second; + // copy content + if (m_ShadowCopy.size()) + memcpy(newMem + theOffsets[idx], + m_ShadowCopy.begin() + entry->second->m_Offset, + entry->second->m_Count * getUniformTypeSize(pParam->m_Type)); + + pParam->m_Offset = theOffsets[idx]; + QT3DS_ASSERT(type == pParam->m_Type); + QT3DS_ASSERT(elementCount == pParam->m_Count); + } else { + // create one + m_ConstantBufferEntryMap.insert(eastl::make_pair( + theName, + createParamEntry(theName, (NVRenderShaderDataTypes::Enum)theTypes[idx], + theSizes[idx], theOffsets[idx]))); + } + } + + // release previous one + if (m_ShadowCopy.size()) { + m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin()); + } + // set new one + m_ShadowCopy = NVDataRef(newMem, bufSize); + + m_HWBufferInitialized = true; + + fail: + if (theIndices) + QT3DS_FREE(m_Foundation.getAllocator(), theIndices); + if (theTypes) + QT3DS_FREE(m_Foundation.getAllocator(), theTypes); + if (theSizes) + QT3DS_FREE(m_Foundation.getAllocator(), theSizes); + if (theOffsets) + QT3DS_FREE(m_Foundation.getAllocator(), theOffsets); + + } else { + // some sanity checks + bSuccess = true; + bSuccess &= (m_ShadowCopy.size() <= (QT3DSU32)bufSize); + } + + return bSuccess; + } + + void NVRenderConstantBuffer::Update() + { + // we only update the buffer if the buffer is already on hardware + // and if it is dirty + if (m_Dirty && m_HWBufferInitialized) { + if (m_RangeEnd == 0) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_ShadowCopy.size(), + m_UsageType, m_ShadowCopy.begin()); + else + UpdateRange(); + + m_Dirty = false; + m_RangeStart = m_RangeEnd = 0; + } + } + + void NVRenderConstantBuffer::UpdateRange() + { + if ((m_RangeStart + m_RangeEnd) > m_ShadowCopy.size()) { + QT3DS_ASSERT(false); + return; + } + + m_Backend->UpdateBufferRange(m_BufferHandle, m_BindFlags, m_RangeStart, + m_RangeEnd - m_RangeStart, + m_ShadowCopy.begin() + m_RangeStart); + } + + void NVRenderConstantBuffer::AddParam(CRegisteredString name, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count) + { + if (m_ConstantBufferEntryMap.find(name) == m_ConstantBufferEntryMap.end()) { + ConstantBufferParamEntry *newEntry = + QT3DS_NEW(m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, + m_CurrentOffset); + + if (newEntry) + m_ConstantBufferEntryMap.insert(eastl::make_pair(name, newEntry)); + } else { + // no duplicated entries + return; + } + + // compute new current buffer size and offset + QT3DSI32 constantSize = getUniformTypeSize(type) * count; + m_CurrentSize += constantSize; + m_CurrentOffset += constantSize; + } + + void NVRenderConstantBuffer::UpdateParam(const char *inName, NVDataRef value) + { + // allocate space if not done yet + // NOTE this gets reallocated once we get the real constant buffer size from a program + if (!m_ShadowCopy.size()) { + // allocate shadow buffer + if (!allocateShadowBuffer(m_CurrentSize)) + return; + } + + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(inName)); + TRenderConstantBufferEntryMap::iterator entry = m_ConstantBufferEntryMap.find(theName); + if (entry != m_ConstantBufferEntryMap.end()) { + if (!memcmp(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(), + entry->second->m_Count * getUniformTypeSize(entry->second->m_Type))) { + return; + } + memcpy(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(), + entry->second->m_Count * getUniformTypeSize(entry->second->m_Type)); + m_Dirty = true; + } + } + + void NVRenderConstantBuffer::UpdateRaw(QT3DSI32 offset, NVDataRef data) + { + // allocate space if yet done + if (!m_ShadowCopy.size()) { + // allocate shadow buffer + if (!allocateShadowBuffer(data.size())) + return; + } + + QT3DS_ASSERT((offset + data.size()) < (QT3DSU32)m_MaxBlockSize); + + // we do not initialize anything when this is used + m_HWBufferInitialized = true; + + // we do not allow resize once allocated + if ((offset + data.size()) > m_ShadowCopy.size()) + return; + + // copy data + if (!memcmp(m_ShadowCopy.begin() + offset, data.begin(), data.size())) { + return; + } + memcpy(m_ShadowCopy.begin() + offset, data.begin(), data.size()); + + // update start + m_RangeStart = (m_Dirty) ? (m_RangeStart > (QT3DSU32)offset) ? offset : m_RangeStart : offset; + m_RangeEnd = (offset + data.size() > m_RangeEnd) ? offset + data.size() : m_RangeEnd; + + m_Dirty = true; + } + + ConstantBufferParamEntry *NVRenderConstantBuffer::createParamEntry( + CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count, QT3DSI32 offset) + { + ConstantBufferParamEntry *newEntry = QT3DS_NEW( + m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, offset); + + return newEntry; + } + + QT3DSI32 + NVRenderConstantBuffer::getUniformTypeSize(NVRenderShaderDataTypes::Enum type) + { + switch (type) { + case NVRenderShaderDataTypes::QT3DSF32: + return sizeof(QT3DSF32); + case NVRenderShaderDataTypes::QT3DSI32: + return sizeof(QT3DSI32); + case NVRenderShaderDataTypes::QT3DSI32_2: + return sizeof(QT3DSI32) * 2; + case NVRenderShaderDataTypes::QT3DSI32_3: + return sizeof(QT3DSI32) * 3; + case NVRenderShaderDataTypes::QT3DSI32_4: + return sizeof(QT3DSI32) * 4; + case NVRenderShaderDataTypes::QT3DSU32: + return sizeof(QT3DSU32); + case NVRenderShaderDataTypes::QT3DSU32_2: + return sizeof(QT3DSU32) * 2; + case NVRenderShaderDataTypes::QT3DSU32_3: + return sizeof(QT3DSU32) * 3; + case NVRenderShaderDataTypes::QT3DSU32_4: + return sizeof(QT3DSU32) * 4; + case NVRenderShaderDataTypes::QT3DSVec2: + return sizeof(QT3DSF32) * 2; + case NVRenderShaderDataTypes::QT3DSVec3: + return sizeof(QT3DSF32) * 3; + case NVRenderShaderDataTypes::QT3DSVec4: + return sizeof(QT3DSF32) * 4; + case NVRenderShaderDataTypes::QT3DSMat33: + return sizeof(QT3DSF32) * 9; + case NVRenderShaderDataTypes::QT3DSMat44: + return sizeof(QT3DSF32) * 16; + default: + QT3DS_ASSERT(!"Unhandled type in NVRenderConstantBuffer::getUniformTypeSize"); + break; + } + + return 0; + } + + bool NVRenderConstantBuffer::allocateShadowBuffer(QT3DSU32 size) + { + // allocate shadow buffer + QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate(size, "NVRenderConstantBuffer", + __FILE__, __LINE__); + if (!newMem) + return false; + + m_ShadowCopy = NVDataRef(newMem, size); + + m_BufferCapacity = size; + + return true; + } + + NVRenderConstantBuffer *NVRenderConstantBuffer::Create(NVRenderContextImpl &context, + const char *bufferName, + NVRenderBufferUsageType::Enum usageType, + size_t size, + NVConstDataRef bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderConstantBuffer *retval = NULL; + + if (context.GetConstantBufferSupport()) { + CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); + QT3DSU32 cbufSize = sizeof(NVRenderConstantBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "ConstantBuffer"); + retval = new (newMem) NVRenderConstantBuffer( + context, theBufferName, size, usageType, + toDataRef(const_cast(bufferData.begin()), bufferData.size())); + } else { + QT3DS_ASSERT(false); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h new file mode 100644 index 00000000..5ede23b9 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + class ConstantBufferParamEntry; + class NVRenderShaderProgram; + + typedef nvhash_map TRenderConstantBufferEntryMap; + + ///< Constant (uniform) buffer representation + class QT3DS_AUTOTEST_EXPORT NVRenderConstantBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] bufferName Name of the buffer. Must match the name used in programs + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderConstantBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, + size_t size, NVRenderBufferUsageType::Enum usageType, + NVDataRef data); + + ///< destructor + virtual ~NVRenderConstantBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief bind the buffer to a shader program + * + * @param[in] inShader Pointer to active program + * @param[in] blockIndex Index of the constant block within the program + * @param[in] binding Binding point of constant buffer + * + * @return no return. + */ + virtual void BindToShaderProgram(NVRenderShaderProgram *inShader, QT3DSU32 blockIndex, + QT3DSU32 binding); + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief setup constant buffer + * + * @param[in] pProgram Pointer to the shader program + * @param[in] index Index of the constant buffer within the program + * @param[in] bufSize Size of the constant buffer + * @param[in] paramCount Parameter entry count of the constant buffer + * + * @return return if successful + */ + bool SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, QT3DSI32 bufSize, + QT3DSI32 paramCount); + + /** + * @brief add a parameter to the constant buffer + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] type Type of the parameter like Mat44 + * @param[in] count One or size of array + * + * @return no return + */ + void AddParam(CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count); + + /** + * @brief update a parameter in the constant buffer + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] value New value + * + * @return no return + */ + void UpdateParam(const char *name, NVDataRef value); + + /** + * @brief update a piece of memory directly within the constant buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 layout which guarantees a specific layout behavior across all + *HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into constant buffer + * @param[in] data pointer to new data + * + * @return no return + */ + void UpdateRaw(QT3DSI32 offset, NVDataRef data); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + /** + * @brief create a NVRenderConstantBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the backend object handle. + */ + static NVRenderConstantBuffer *Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData); + + /** + * @brief get the buffer name + * + * @return the buffer name + */ + CRegisteredString GetBufferName() const { return m_Name; } + + private: + /** + * @brief Create a parameter entry + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] type Type of the parameter like Mat44 + * @param[in] count One or size of array + * @param[in] offset Offset of the parameter in the memory buffer + * + * @return return new Entry + */ + ConstantBufferParamEntry *createParamEntry(CRegisteredString name, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + QT3DSI32 offset); + + /** + * @brief get size of a uniform type + * + * @param[in] type type of uniform + * + * @return return uniform size + */ + QT3DSI32 + getUniformTypeSize(NVRenderShaderDataTypes::Enum type); + + /** + * @brief allocate the shadow buffer + * + * @param[in] size size of buffer + * + * @return return true on success + */ + bool allocateShadowBuffer(QT3DSU32 size); + + /** + * @brief update a certain range of the buffer to hardware + * + * @return no return. + */ + virtual void UpdateRange(); + + private: + CRegisteredString m_Name; ///< buffer name + TRenderConstantBufferEntryMap + m_ConstantBufferEntryMap; ///< holds the entries of a constant buffer + QT3DSU32 m_CurrentOffset; ///< holds the current offset + QT3DSU32 m_CurrentSize; ///< holds the current size + bool m_HWBufferInitialized; ///< true if the hardware version of the buffer is initialized + bool m_Dirty; ///< true if buffer is dirty + QT3DSU32 m_RangeStart; ///< start offset of the range to update + QT3DSU32 m_RangeEnd; ///< size of the range to update + QT3DSI32 m_MaxBlockSize; ///< maximum size for a single constant buffer + NVDataRef m_ShadowCopy; ///< host copy of the data in the GPU + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.cpp b/src/Runtime/Source/render/Qt3DSRenderContext.cpp new file mode 100644 index 00000000..aa2cb30f --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderContext.cpp @@ -0,0 +1,1107 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMat44.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Utils.h" +#include "EASTL/set.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace eastl; + +namespace qt3ds { +namespace render { + + NVRenderContextImpl::NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, + IStringTable &inStrTable) + : m_backend(inBackend) + , m_DirtyFlags(0) + , m_DefaultOffscreenRenderTarget((NVRenderBackend::NVRenderBackendRenderTargetObject)NULL) + , m_DephBits(16) + , m_StencilBits(8) + , mRefCount(0) + , m_Foundation(fnd) + , m_StringTable(inStrTable) + , m_VertToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_VertToImpMap") + , m_IndexToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_IndexToImpMap") + , m_ConstantToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ConstantToImpMap") + , m_StorageToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_StorageToImpMap") + , m_AtomicCounterToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_AtomicCounterToImpMap") + , m_DrawIndirectToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_DrawIndirectToImpMap") + , m_DepthStencilStateToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_DepthStencilStateToImpMap") + , m_RasterizerStateToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RasterizerStateToImpMap") + , m_PathFontSpecToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RasterizerStateToImpMap") + , m_Tex2DToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Tex2DToImpMap") + , m_Tex2DArrayToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_Tex2DArrayToImpMap") + , m_TexCubeToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_TexCubeToImpMap") + , m_Image2DtoImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Image2DtoImpMap") + , m_ShaderToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ShaderToImpMap") + , m_RenderBufferToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RenderBufferToImpMap") + , m_FrameBufferToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_FrameBufferToImpMap") + , m_NextTextureUnit(1) + , m_NextConstantBufferUnit(1) + , m_PropertyStack(m_Foundation.getAllocator(), "NVRenderContextImpl::m_PropertyStack") + { + + m_StringTable.addRef(); + + m_MaxTextureUnits = m_backend->GetMaxCombinedTextureUnits(); + m_MaxConstantBufferUnits = 16; // need backend query + + // get initial state + memZero(&m_HardwarePropertyContext, sizeof(m_HardwarePropertyContext)); + + // get default blending functions + m_backend->GetBlendFunc(&m_HardwarePropertyContext.m_BlendFunction); + // set default blend euqation + m_HardwarePropertyContext.m_BlendEquation.m_RGBEquation = NVRenderBlendEquation::Add; + m_HardwarePropertyContext.m_BlendEquation.m_AlphaEquation = NVRenderBlendEquation::Add; + // default state + m_HardwarePropertyContext.m_CullingEnabled = + m_backend->GetRenderState(NVRenderState::CullFace); + m_HardwarePropertyContext.m_DepthFunction = m_backend->GetDepthFunc(); + m_HardwarePropertyContext.m_BlendingEnabled = + m_backend->GetRenderState(NVRenderState::Blend); + m_HardwarePropertyContext.m_DepthWriteEnabled = m_backend->GetDepthWrite(); + m_HardwarePropertyContext.m_DepthTestEnabled = + m_backend->GetRenderState(NVRenderState::DepthTest); + m_HardwarePropertyContext.m_ScissorTestEnabled = + m_backend->GetRenderState(NVRenderState::ScissorTest); + m_backend->GetScissorRect(&m_HardwarePropertyContext.m_ScissorRect); + m_backend->GetViewportRect(&m_HardwarePropertyContext.m_Viewport); + + DoSetClearColor(m_HardwarePropertyContext.m_ClearColor); + } + + NVRenderContextImpl::~NVRenderContextImpl() + { + m_StringTable.release(); + QT3DS_ASSERT(m_VertToImpMap.size() == 0); + m_VertToImpMap.clear(); + QT3DS_ASSERT(m_IndexToImpMap.size() == 0); + m_IndexToImpMap.clear(); + QT3DS_ASSERT(m_ConstantToImpMap.size() == 0); + m_ConstantToImpMap.clear(); + QT3DS_ASSERT(m_StorageToImpMap.size() == 0); + m_StorageToImpMap.clear(); + QT3DS_ASSERT(m_DepthStencilStateToImpMap.size() == 0); + m_DepthStencilStateToImpMap.clear(); + QT3DS_ASSERT(m_RasterizerStateToImpMap.size() == 0); + m_RasterizerStateToImpMap.clear(); + QT3DS_ASSERT(m_PathFontSpecToImpMap.size() == 0); + m_PathFontSpecToImpMap.clear(); + QT3DS_ASSERT(m_Tex2DToImpMap.size() == 0); + m_Tex2DToImpMap.clear(); + QT3DS_ASSERT(m_Tex2DArrayToImpMap.size() == 0); + m_Tex2DArrayToImpMap.clear(); + QT3DS_ASSERT(m_Image2DtoImpMap.size() == 0); + m_Image2DtoImpMap.clear(); + QT3DS_ASSERT(m_ShaderToImpMap.size() == 0); + m_ShaderToImpMap.clear(); + QT3DS_ASSERT(m_RenderBufferToImpMap.size() == 0); + m_RenderBufferToImpMap.clear(); + QT3DS_ASSERT(m_FrameBufferToImpMap.size() == 0); + m_FrameBufferToImpMap.clear(); + + m_backend = NULL; + } + + void NVRenderContextImpl::getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) + { + QT3DSI32 theMaxTextureSize = 0; + m_backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxTextureSize); + + oWidth = (QT3DSU32)theMaxTextureSize; + oHeight = (QT3DSU32)theMaxTextureSize; + } + + NVRenderDepthStencilState *NVRenderContextImpl::CreateDepthStencilState( + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + NVRenderDepthStencilState *state = NVRenderDepthStencilState::Create( + *this, enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, + stencilFuncBack, depthStencilOpFront, depthStencilOpBack); + if (state) + m_DepthStencilStateToImpMap.insert( + make_pair(state->GetDepthStencilObjectHandle(), state)); + + return state; + } + + void NVRenderContextImpl::SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) + { + if (inDepthStencilState) { + m_backend->SetDepthStencilState(inDepthStencilState->GetDepthStencilObjectHandle()); + // currently we have a mixture therefore we need to update the context state + SetDepthFunction(inDepthStencilState->GetDepthFunc()); + SetDepthWriteEnabled(inDepthStencilState->GetDepthMask()); + SetDepthTestEnabled(inDepthStencilState->GetDepthEnabled()); + SetStencilTestEnabled(inDepthStencilState->GetStencilEnabled()); + } + } + + void NVRenderContextImpl::StateDestroyed(NVRenderDepthStencilState &state) + { + m_DepthStencilStateToImpMap.erase(state.GetDepthStencilObjectHandle()); + } + + NVRenderRasterizerState * + NVRenderContextImpl::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + NVRenderRasterizerState *state = + NVRenderRasterizerState::Create(*this, depthBias, depthScale, cullFace); + if (state) + m_RasterizerStateToImpMap.insert(make_pair(state->GetRasterizerObjectHandle(), state)); + + return state; + } + + void NVRenderContextImpl::SetRasterizerState(NVRenderRasterizerState *inRasterizerState) + { + if (inRasterizerState) + m_backend->SetRasterizerState(inRasterizerState->GetRasterizerObjectHandle()); + } + + void NVRenderContextImpl::StateDestroyed(NVRenderRasterizerState &state) + { + m_RasterizerStateToImpMap.erase(state.GetRasterizerObjectHandle()); + } + + NVRenderVertexBuffer * + NVRenderContextImpl::CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, + QT3DSU32 stride, NVConstDataRef bufferData) + { + NVRenderVertexBuffer *buffer = + NVRenderVertexBuffer::Create(*this, usageType, size, stride, bufferData); + if (buffer) + m_VertToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); + return buffer; + } + + NVRenderVertexBuffer *NVRenderContextImpl::GetVertexBuffer(const void *implementationHandle) + { + nvhash_map::const_iterator entry = + m_VertToImpMap.find(implementationHandle); + if (entry != m_VertToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderVertexBuffer &buffer) + { + m_VertToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderIndexBuffer * + NVRenderContextImpl::CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, + qt3ds::render::NVRenderComponentTypes::Enum componentType, + size_t size, NVConstDataRef bufferData) + { + NVRenderIndexBuffer *buffer = + NVRenderIndexBuffer::Create(*this, usageType, componentType, size, bufferData); + + if (buffer) { + m_IndexToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); + } + + return buffer; + } + + NVRenderIndexBuffer *NVRenderContextImpl::GetIndexBuffer(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_IndexToImpMap.find(implementationHandle); + if (entry != m_IndexToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderIndexBuffer &buffer) + { + m_IndexToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderConstantBuffer * + NVRenderContextImpl::CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef bufferData) + { + NVRenderConstantBuffer *buffer = + NVRenderConstantBuffer::Create(*this, bufferName, usageType, size, bufferData); + + if (buffer) { + m_ConstantToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderConstantBuffer *NVRenderContextImpl::GetConstantBuffer(CRegisteredString bufferName) + { + TContextConstantBufferMap::iterator entry = m_ConstantToImpMap.find(bufferName); + if (entry != m_ConstantToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderConstantBuffer &buffer) + { + m_ConstantToImpMap.erase(buffer.GetBufferName()); + } + + QT3DSU32 NVRenderContextImpl::GetNextConstantBufferUnit() + { + QT3DSU32 retval = m_NextConstantBufferUnit; + ++m_NextConstantBufferUnit; + // Too many texture units for a single draw call. + if (retval >= m_MaxConstantBufferUnits) { + QT3DS_ASSERT(false); + retval = retval % m_MaxConstantBufferUnits; + } + return retval; + } + + NVRenderStorageBuffer *NVRenderContextImpl::CreateStorageBuffer( + const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) + { + NVRenderStorageBuffer *buffer = + NVRenderStorageBuffer::Create(*this, bufferName, usageType, size, bufferData, pBuffer); + + if (buffer) { + m_StorageToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderStorageBuffer *NVRenderContextImpl::GetStorageBuffer(CRegisteredString bufferName) + { + TContextStorageBufferMap::iterator entry = m_StorageToImpMap.find(bufferName); + if (entry != m_StorageToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderStorageBuffer &buffer) + { + m_StorageToImpMap.erase(buffer.GetBufferName()); + } + + NVRenderAtomicCounterBuffer *NVRenderContextImpl::CreateAtomicCounterBuffer( + const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) + { + NVRenderAtomicCounterBuffer *buffer = + NVRenderAtomicCounterBuffer::Create(*this, bufferName, usageType, size, bufferData); + + if (buffer) { + m_AtomicCounterToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderAtomicCounterBuffer * + NVRenderContextImpl::GetAtomicCounterBuffer(CRegisteredString bufferName) + { + TContextAtomicCounterBufferMap::iterator entry = m_AtomicCounterToImpMap.find(bufferName); + if (entry != m_AtomicCounterToImpMap.end()) + return entry->second; + return NULL; + } + + NVRenderAtomicCounterBuffer * + NVRenderContextImpl::GetAtomicCounterBufferByParam(CRegisteredString paramName) + { + // iterate through all atomic counter buffers + for (TContextAtomicCounterBufferMap::iterator iter = m_AtomicCounterToImpMap.begin(), + end = m_AtomicCounterToImpMap.end(); + iter != end; ++iter) { + if (iter->second && iter->second->ContainsParam(paramName)) + return iter->second; + } + + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderAtomicCounterBuffer &buffer) + { + m_AtomicCounterToImpMap.erase(buffer.GetBufferName()); + } + + NVRenderDrawIndirectBuffer *NVRenderContextImpl::CreateDrawIndirectBuffer( + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) + { + NVRenderDrawIndirectBuffer *buffer = + NVRenderDrawIndirectBuffer::Create(*this, usageType, size, bufferData); + + if (buffer) { + m_DrawIndirectToImpMap.insert(make_pair(buffer->GetBuffertHandle(), buffer)); + } + + return buffer; + } + + NVRenderDrawIndirectBuffer *NVRenderContextImpl::GetDrawIndirectBuffer( + NVRenderBackend::NVRenderBackendBufferObject implementationHandle) + { + TContextDrawIndirectBufferMap::iterator entry = + m_DrawIndirectToImpMap.find(implementationHandle); + if (entry != m_DrawIndirectToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderDrawIndirectBuffer &buffer) + { + m_DrawIndirectToImpMap.erase(buffer.GetBuffertHandle()); + } + + void NVRenderContextImpl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) + { + m_backend->SetMemoryBarrier(barriers); + } + + NVRenderOcclusionQuery *NVRenderContextImpl::CreateOcclusionQuery() + { + NVRenderOcclusionQuery *theQuery = NVRenderOcclusionQuery::Create(*this); + + return theQuery; + } + + NVRenderTimerQuery *NVRenderContextImpl::CreateTimerQuery() + { + NVRenderTimerQuery *theQuery = NVRenderTimerQuery::Create(*this); + + return theQuery; + } + + NVRenderSync *NVRenderContextImpl::CreateSync() + { + NVRenderSync *theSync = NVRenderSync::Create(*this); + + return theSync; + } + + NVRenderTexture2D *NVRenderContextImpl::CreateTexture2D() + { + NVRenderTexture2D *retval = NVRenderTexture2D::Create(*this); + if (retval) + m_Tex2DToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderTexture2DArray *NVRenderContextImpl::CreateTexture2DArray() + { + NVRenderTexture2DArray *retval = NVRenderTexture2DArray::Create(*this); + if (retval) + m_Tex2DArrayToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + NVRenderTextureCube *NVRenderContextImpl::CreateTextureCube() + { + NVRenderTextureCube *retval = NVRenderTextureCube::Create(*this); + if (retval) + m_TexCubeToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + NVRenderTexture2D *NVRenderContextImpl::GetTexture2D(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_Tex2DToImpMap.find(implementationHandle); + if (entry != m_Tex2DToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2D &buffer) + { + m_Tex2DToImpMap.erase(buffer.GetImplementationHandle()); + // We would like to find and catch any situations where this texture is being used + // but that would require some real work that we don't want to do right now. + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2DArray &buffer) + { + m_Tex2DArrayToImpMap.erase(buffer.GetTextureObjectHandle()); + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTextureCube &buffer) + { + m_TexCubeToImpMap.erase(buffer.GetTextureObjectHandle()); + } + + NVRenderImage2D *NVRenderContextImpl::CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + { + NVRenderImage2D *retval = NVRenderImage2D::Create(*this, inTexture, inAccess); + if (retval) + m_Image2DtoImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + void NVRenderContextImpl::ImageDestroyed(NVRenderImage2D &image) + { + m_Image2DtoImpMap.erase(image.GetTextureObjectHandle()); + } + + // IF this texture isn't on a texture unit, put it on one. + // If it is on a texture unit, mark it as the most recently used texture. + QT3DSU32 NVRenderContextImpl::GetNextTextureUnit() + { + QT3DSU32 retval = m_NextTextureUnit; + ++m_NextTextureUnit; + // Too many texture units for a single draw call. + if (retval >= m_MaxTextureUnits) { + QT3DS_ASSERT(false); + retval = retval % m_MaxTextureUnits; + } + return retval; + } + + NVRenderRenderBuffer * + NVRenderContextImpl::CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, + QT3DSU32 width, QT3DSU32 height) + { + NVRenderRenderBuffer *retval = + NVRenderRenderBuffer::Create(*this, bufferFormat, width, height); + if (retval != NULL) + m_RenderBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderRenderBuffer *NVRenderContextImpl::GetRenderBuffer(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_RenderBufferToImpMap.find(implementationHandle); + if (entry != m_RenderBufferToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::RenderBufferDestroyed(NVRenderRenderBuffer &buffer) + { + m_RenderBufferToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderFrameBuffer *NVRenderContextImpl::CreateFrameBuffer() + { + NVRenderFrameBuffer *retval = NVRenderFrameBuffer::Create(*this); + if (retval != NULL) + m_FrameBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderFrameBuffer *NVRenderContextImpl::GetFrameBuffer(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_FrameBufferToImpMap.find(implementationHandle); + if (entry != m_FrameBufferToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::FrameBufferDestroyed(NVRenderFrameBuffer &fb) + { + m_FrameBufferToImpMap.erase(fb.GetImplementationHandle()); + if (m_HardwarePropertyContext.m_FrameBuffer == &fb) + m_HardwarePropertyContext.m_FrameBuffer = NULL; + } + + NVRenderAttribLayout * + NVRenderContextImpl::CreateAttributeLayout(NVConstDataRef attribs) + { + return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderAttribLayout)(*this, attribs); + } + + NVRenderInputAssembler *NVRenderContextImpl::CreateInputAssembler( + NVRenderAttribLayout *attribLayout, NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, + NVConstDataRef offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) + { + return QT3DS_NEW(GetFoundation().getAllocator(), + NVRenderInputAssembler)(*this, attribLayout, buffers, indexBuffer, strides, + offsets, primType, patchVertexCount); + } + + void NVRenderContextImpl::SetInputAssembler(NVRenderInputAssembler *inputAssembler) + { + if (m_HardwarePropertyContext.m_InputAssembler != inputAssembler) { + DoSetInputAssembler(inputAssembler); + } + } + + NVRenderVertFragCompilationResult NVRenderContextImpl::CompileSource( + const char *shaderName, NVConstDataRef vertShader, NVConstDataRef fragShader, + NVConstDataRef tessControlShaderSource, + NVConstDataRef tessEvaluationShaderSource, NVConstDataRef geometryShaderSource, + bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) + { + NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( + *this, shaderName, vertShader, fragShader, tessControlShaderSource, + tessEvaluationShaderSource, geometryShaderSource, separateProgram, type, binaryProgram); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; + } + + NVRenderVertFragCompilationResult NVRenderContextImpl::CompileBinary( + const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef vertShader, NVDataRef fragShader, + NVDataRef tessControlShaderSource, NVDataRef tessEvaluationShaderSource, + NVConstDataRef geometryShaderSource) + { +#ifndef _MACOSX + NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( + *this, shaderName, vertShader, fragShader, tessControlShaderSource, + tessEvaluationShaderSource, geometryShaderSource, false, type, true); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; +#else + QT3DS_ASSERT(false); + return NVRenderVertFragCompilationResult(); +#endif + } + + NVRenderVertFragCompilationResult + NVRenderContextImpl::CompileComputeSource(const char *shaderName, + NVConstDataRef computeShaderSource) + { + NVRenderVertFragCompilationResult result = + NVRenderShaderProgram::CreateCompute(*this, shaderName, computeShaderSource); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; + } + + NVRenderShaderProgram *NVRenderContextImpl::GetShaderProgram(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_ShaderToImpMap.find(implementationHandle); + if (entry != m_ShaderToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::ShaderDestroyed(NVRenderShaderProgram &shader) + { + m_ShaderToImpMap.erase(shader.GetShaderProgramHandle()); + if (m_HardwarePropertyContext.m_ActiveShader == &shader) + SetActiveShader(NULL); + } + + NVRenderProgramPipeline *NVRenderContextImpl::CreateProgramPipeline() + { + return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderProgramPipeline)(*this, + GetFoundation()); + } + + NVRenderPathSpecification *NVRenderContextImpl::CreatePathSpecification() + { + return NVRenderPathSpecification::CreatePathSpecification(*this); + } + + NVRenderPathRender *NVRenderContextImpl::CreatePathRender(size_t range) + { + return NVRenderPathRender::Create(*this, range); + } + + void NVRenderContextImpl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) + { + m_backend->SetPathProjectionMatrix(inPathProjection); + } + + void NVRenderContextImpl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) + { + m_backend->SetPathModelViewMatrix(inPathModelview); + } + + void NVRenderContextImpl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) + { + m_backend->SetPathStencilDepthOffset(inSlope, inBias); + } + void NVRenderContextImpl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) + { + m_backend->SetPathCoverDepthFunc(inFunc); + } + + NVRenderPathFontSpecification * + NVRenderContextImpl::CreatePathFontSpecification(CRegisteredString fontName) + { + // first check if it already exists + nvhash_map::const_iterator entry = + m_PathFontSpecToImpMap.find(fontName); + if (entry != m_PathFontSpecToImpMap.end()) + return entry->second; + + // if not create new one + NVRenderPathFontSpecification *pPathFontSpec = + NVRenderPathFontSpecification::CreatePathFontSpecification(*this, fontName); + + if (pPathFontSpec) + m_PathFontSpecToImpMap.insert(make_pair(fontName, pPathFontSpec)); + + return pPathFontSpec; + } + + void + NVRenderContextImpl::ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec) + { + m_PathFontSpecToImpMap.erase(inPathSpec.GetFontName()); + } + + NVRenderPathFontItem *NVRenderContextImpl::CreatePathFontItem() + { + // if not create new one + return NVRenderPathFontItem::CreatePathFontItem(*this); + } + + void NVRenderContextImpl::SetClearColor(QT3DSVec4 inClearColor) + { + if (m_HardwarePropertyContext.m_ClearColor != inClearColor) + DoSetClearColor(inClearColor); + } + + void NVRenderContextImpl::SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) + { + if (memcmp(&inFunctions, &m_HardwarePropertyContext.m_BlendFunction, + sizeof(NVRenderBlendFunctionArgument))) { + DoSetBlendFunction(inFunctions); + } + } + + void NVRenderContextImpl::SetBlendEquation(NVRenderBlendEquationArgument inEquations) + { + if (memcmp(&inEquations, &m_HardwarePropertyContext.m_BlendEquation, + sizeof(NVRenderBlendEquationArgument))) { + DoSetBlendEquation(inEquations); + } + } + + void NVRenderContextImpl::SetCullingEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_CullingEnabled) { + DoSetCullingEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) + { + if (inFunction != m_HardwarePropertyContext.m_DepthFunction) { + DoSetDepthFunction(inFunction); + } + } + + void NVRenderContextImpl::SetBlendingEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_BlendingEnabled) { + DoSetBlendingEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetColorWritesEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_ColorWritesEnabled) { + DoSetColorWritesEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetDepthWriteEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_DepthWriteEnabled) { + m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::DepthWrite); + } + } + + void NVRenderContextImpl::SetDepthTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_DepthTestEnabled) { + DoSetDepthTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetMultisampleEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_MultisampleEnabled) { + DoSetMultisampleEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetStencilTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_StencilTestEnabled) { + DoSetStencilTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetScissorTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_ScissorTestEnabled) { + DoSetScissorTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetScissorRect(NVRenderRect inRect) + { + if (memcmp(&inRect, &m_HardwarePropertyContext.m_ScissorRect, sizeof(NVRenderRect))) { + DoSetScissorRect(inRect); + } + } + + void NVRenderContextImpl::SetViewport(NVRenderRect inViewport) + { + if (memcmp(&inViewport, &m_HardwarePropertyContext.m_Viewport, sizeof(NVRenderRect))) { + DoSetViewport(inViewport); + } + } + + void NVRenderContextImpl::SetActiveShader(NVRenderShaderProgram *inShader) + { + if (inShader != m_HardwarePropertyContext.m_ActiveShader) + DoSetActiveShader(inShader); + } + + void NVRenderContextImpl::SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) + { + if (inProgramPipeline != m_HardwarePropertyContext.m_ActiveProgramPipeline) + DoSetActiveProgramPipeline(inProgramPipeline); + } + + void NVRenderContextImpl::DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) + { + QT3DS_ASSERT(inShader); + + if (inShader != m_HardwarePropertyContext.m_ActiveShader) + DoSetActiveShader(inShader); + + m_backend->DispatchCompute(inShader->GetShaderProgramHandle(), numGroupsX, numGroupsY, + numGroupsZ); + + OnPostDraw(); + } + + void NVRenderContextImpl::SetDrawBuffers(NVConstDataRef inDrawBufferSet) + { + m_backend->SetDrawBuffers( + (m_HardwarePropertyContext.m_FrameBuffer) + ? m_HardwarePropertyContext.m_FrameBuffer->GetFrameBuffertHandle() + : NULL, + inDrawBufferSet); + } + + void NVRenderContextImpl::SetReadBuffer(NVReadFaces::Enum inReadFace) + { + // currently NULL which means the read target must be set with setReadTarget + m_backend->SetReadBuffer(NULL, inReadFace); + } + + void NVRenderContextImpl::ReadPixels(NVRenderRect inRect, + NVRenderReadPixelFormats::Enum inFormat, + NVDataRef inWriteBuffer) + { + // NULL means read from current render target + m_backend->ReadPixel(NULL, inRect.m_X, inRect.m_Y, inRect.m_Width, inRect.m_Height, + inFormat, (void *)inWriteBuffer.begin()); + } + + void NVRenderContextImpl::SetRenderTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { + DoSetRenderTarget(inBuffer); + } + } + + void NVRenderContextImpl::SetReadTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { + DoSetReadTarget(inBuffer); + } + } + + void NVRenderContextImpl::ResetBlendState() + { + QT3DSI32_4 values; + + m_backend->SetRenderState(m_HardwarePropertyContext.m_BlendingEnabled, + NVRenderState::Blend); + const NVRenderBlendFunctionArgument &theBlendArg(m_HardwarePropertyContext.m_BlendFunction); + m_backend->SetBlendFunc(theBlendArg); + } + + // Pop the entire set of properties, potentially forcing the values + // to opengl. + void NVRenderContextImpl::PopPropertySet(bool inForceSetProperties) + { + if (!m_PropertyStack.empty()) { + SNVGLHardPropertyContext &theTopContext(m_PropertyStack.back()); + if (inForceSetProperties) { +#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ + DoSet##setterName(theTopContext.m_##propName); + + ITERATE_HARDWARE_CONTEXT_PROPERTIES + +#undef HANDLE_CONTEXT_HARDWARE_PROPERTY + } else { +#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ + Set##setterName(theTopContext.m_##propName); + + ITERATE_HARDWARE_CONTEXT_PROPERTIES + +#undef HANDLE_CONTEXT_HARDWARE_PROPERTY + } + m_PropertyStack.pop_back(); + } + } + + void NVRenderContextImpl::Clear(NVRenderClearFlags flags) + { + if ((flags & NVRenderClearValues::Depth) + && m_HardwarePropertyContext.m_DepthWriteEnabled == false) { + QT3DS_ASSERT(false); + SetDepthWriteEnabled(true); + } + m_backend->Clear(flags); + } + + void NVRenderContextImpl::Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) + { + NVRenderFrameBuffer *previous = m_HardwarePropertyContext.m_FrameBuffer; + if (previous != &fb) + SetRenderTarget(&fb); + + Clear(flags); + + if (previous != &fb) + SetRenderTarget(previous); + } + + void NVRenderContextImpl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) + { + m_backend->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, flags, + filter); + } + + bool + NVRenderContextImpl::BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, + NVRenderShaderProgram *shader) + { + // setup the input assembler object + return m_backend->SetInputAssembler(inputAssembler->GetInputAssemblerHandle(), + shader->GetShaderProgramHandle()); + } + + bool NVRenderContextImpl::ApplyPreDrawProperties() + { + // Get the currently bound vertex and shader + NVRenderInputAssembler *inputAssembler = this->m_HardwarePropertyContext.m_InputAssembler; + NVRenderShaderProgram *shader = this->m_HardwarePropertyContext.m_ActiveShader; + + // we could render through a program pipline + if (shader == NULL && this->m_HardwarePropertyContext.m_ActiveProgramPipeline) + shader = this->m_HardwarePropertyContext.m_ActiveProgramPipeline->GetVertexStage(); + + if (inputAssembler == NULL || shader == NULL) { + qCCritical(INVALID_OPERATION, + "Attempting to render no valid shader or input assembler setup"); + QT3DS_ASSERT(false); + return false; + } + + return BindShaderToInputAssembler(inputAssembler, shader); + } + + void NVRenderContextImpl::OnPostDraw() + { + // reset input assembler binding + m_backend->SetInputAssembler(NULL, 0); + // Texture unit 0 is used for setting up and loading textures. + // Bugs happen if we load a texture then setup the sampler. + // Then we load another texture. Because when loading we use texture unit 0, + // the render bindings for the first texture are blown away. + // Again, for this reason, texture unit 0 is reserved for loading textures. + m_NextTextureUnit = 1; + m_NextConstantBufferUnit = 0; + } + + void NVRenderContextImpl::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) + { + if (!ApplyPreDrawProperties()) + return; + + NVRenderIndexBuffer *theIndexBuffer = const_cast( + m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); + if (theIndexBuffer == NULL) + m_backend->Draw(drawMode, offset, count); + else + theIndexBuffer->Draw(drawMode, count, offset); + + OnPostDraw(); + } + + void NVRenderContextImpl::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) + { + if (!ApplyPreDrawProperties()) + return; + + NVRenderIndexBuffer *theIndexBuffer = const_cast( + m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); + if (theIndexBuffer == NULL) + m_backend->DrawIndirect(drawMode, (const void *)offset); + else + theIndexBuffer->DrawIndirect(drawMode, offset); + + OnPostDraw(); + } + + QT3DSMat44 + NVRenderContext::ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, + const NVRenderRectF &inViewport, + const NVRenderRectF &inVirtualViewport) + { + if (inVirtualViewport == inViewport) + return inProjection; + // Run conversion to floating point once. + NVRenderRectF theVirtualViewport(inVirtualViewport); + NVRenderRectF theViewport(inViewport); + if (theVirtualViewport.m_Width == 0 || theVirtualViewport.m_Height == 0 + || theViewport.m_Width == 0 || theViewport.m_Height == 0) { + QT3DS_ASSERT(false); + return inProjection; + } + QT3DSMat44 theScaleTransMat(QT3DSMat44::createIdentity()); + QT3DSF32 theHeightDiff = theViewport.m_Height - theVirtualViewport.m_Height; + QT3DSF32 theViewportOffY = theVirtualViewport.m_Y - theViewport.m_Y; + QT3DSVec2 theCameraOffsets = QT3DSVec2(theVirtualViewport.m_Width - theViewport.m_Width + + (theVirtualViewport.m_X - theViewport.m_X) * 2.0f, + theHeightDiff + (theViewportOffY - theHeightDiff) * 2.0f); + QT3DSVec2 theCameraScale = QT3DSVec2(theVirtualViewport.m_Width / theViewport.m_Width, + theVirtualViewport.m_Height / theViewport.m_Height); + + QT3DSVec3 theTranslation(theCameraOffsets.x / theViewport.m_Width, + theCameraOffsets.y / theViewport.m_Height, 0); + theScaleTransMat.column3[0] = theTranslation.x; + theScaleTransMat.column3[1] = theTranslation.y; + theScaleTransMat.column0[0] = theCameraScale.x; + theScaleTransMat.column1[1] = theCameraScale.y; + + return theScaleTransMat * inProjection; + } + + NVRenderVertFragCompilationResult NVRenderContext::CompileSource( + const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, const char *fragShader, + QT3DSU32 inFragLen, const char *tessControlShaderSource, QT3DSU32 inTCLen, + const char *tessEvaluationShaderSource, QT3DSU32 inTELen, const char *geometryShaderSource, + QT3DSU32 inGSLen, bool separableProgram) + { + return CompileSource( + shaderName, NVConstDataRef((const QT3DSI8 *)vertShader, inVertLen), + NVConstDataRef((const QT3DSI8 *)fragShader, inFragLen), + NVConstDataRef((const QT3DSI8 *)tessControlShaderSource, inTCLen), + NVConstDataRef((const QT3DSI8 *)tessEvaluationShaderSource, inTELen), + NVConstDataRef((const QT3DSI8 *)geometryShaderSource, inGSLen), separableProgram); + } + + void NVRenderContextImpl::DoSetActiveShader(NVRenderShaderProgram *inShader) + { + m_HardwarePropertyContext.m_ActiveShader = NULL; + if (inShader) + m_backend->SetActiveProgram(inShader->GetShaderProgramHandle()); + else { + m_backend->SetActiveProgram(NULL); + } + m_HardwarePropertyContext.m_ActiveShader = inShader; + } + + void NVRenderContextImpl::DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) + { + if (inProgramPipeline) { + // invalid any bound shader + DoSetActiveShader(NULL); + inProgramPipeline->Bind(); + } else + m_backend->SetActiveProgramPipeline(NULL); + + m_HardwarePropertyContext.m_ActiveProgramPipeline = inProgramPipeline; + } + + NVRenderContext &NVRenderContext::CreateNULL(NVFoundationBase &foundation, + IStringTable &inStringTable) + { + NVRenderContext *retval = NULL; + + // create backend + NVScopedRefCounted theStringTable(inStringTable); + NVScopedRefCounted theBackend = + NVRenderBackendNULL::CreateBackend(foundation); + retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, + *theStringTable); + return *retval; + } +} +} // end namespace diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.h b/src/Runtime/Source/render/Qt3DSRenderContext.h new file mode 100644 index 00000000..e5b51341 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderContext.h @@ -0,0 +1,1063 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CONTEXT_H +#define QT3DS_RENDER_CONTEXT_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "render/glg/Qt3DSGLImplObjects.h" +#include "render/backends/gl/Q3DSRenderBackendGLES2.h" +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" +#include "render/backends/gl/Qt3DSRenderBackendGL4.h" +#include "render/backends/software/Qt3DSRenderBackendNULL.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderConstantBuffer.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderDepthStencilState.h" +#include "render/Qt3DSRenderRasterizerState.h" +#include "render/Qt3DSRenderDrawable.h" +#include "render/Qt3DSRenderInputAssembler.h" +#include "render/Qt3DSRenderAttribLayout.h" +#include "render/Qt3DSRenderImageTexture.h" +#include "render/Qt3DSRenderOcclusionQuery.h" +#include "render/Qt3DSRenderTimerQuery.h" +#include "render/Qt3DSRenderSync.h" +#include "render/Qt3DSRenderTexture2DArray.h" +#include "render/Qt3DSRenderTextureCube.h" +#include "render/Qt3DSRenderStorageBuffer.h" +#include "render/Qt3DSRenderAtomicCounterBuffer.h" +#include "render/Qt3DSRenderDrawIndirectBuffer.h" +#include "render/Qt3DSRenderProgramPipeline.h" +#include "render/Qt3DSRenderPathRender.h" +#include "render/Qt3DSRenderPathSpecification.h" +#include "render/Qt3DSRenderPathFontSpecification.h" +#include "render/Qt3DSRenderPathFontText.h" + +#include + +// When SW fallback is defined we can support (some) object/layer advanced blend modes. If defined, +// the HW implementation is still preperred if available through extensions. SW fallback can't be +// used in custom shaders. +#define ADVANCED_BLEND_SW_FALLBACK +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + using namespace foundation; + + struct NVRenderShaderProgramBinaryType + { + enum Enum { + Unknown = 0, + NVBinary = 1, + }; + }; + + // context dirty flags + struct NVRenderContextDirtyValues + { + enum Enum { + InputAssembler = 1 << 0, + }; + }; + + typedef NVFlags NVRenderContextDirtyFlags; + typedef nvhash_map TContextConstantBufferMap; + typedef nvhash_map TContextStorageBufferMap; + typedef nvhash_map + TContextAtomicCounterBufferMap; + typedef nvhash_map + TContextDrawIndirectBufferMap; + typedef nvhash_map + TContextDepthStencilStateMap; + typedef nvhash_map + TContextRasterizerStateMap; + typedef nvhash_map + TContextTex2DArrayToImpMap; + typedef nvhash_map + TContextTexCubeToImpMap; + typedef nvhash_map + TContextImage2DToImpMap; + typedef nvhash_map + TContextPathFontSpecificationMap; + + class QT3DS_AUTOTEST_EXPORT NVRenderContext : public NVRefCounted, public NVRenderDrawable + { + public: + virtual NVRenderContextType GetRenderContextType() const = 0; + virtual bool AreMultisampleTexturesSupported() const = 0; + virtual bool GetConstantBufferSupport() const = 0; + virtual void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) = 0; + virtual const char *GetShadingLanguageVersion() = 0; + // Get the bit depth of the currently bound depth buffer. + virtual QT3DSU32 GetDepthBits() const = 0; + virtual QT3DSU32 GetStencilBits() const = 0; + virtual bool + GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const = 0; + virtual bool AreDXTImagesSupported() const = 0; + virtual bool IsDepthStencilSupported() const = 0; + virtual bool IsFpRenderTargetSupported() const = 0; + virtual bool IsTessellationSupported() const = 0; + virtual bool IsGeometryStageSupported() const = 0; + virtual bool IsComputeSupported() const = 0; + virtual bool IsSampleQuerySupported() const = 0; + virtual bool IsTimerQuerySupported() const = 0; + virtual bool IsCommandSyncSupported() const = 0; + virtual bool IsTextureArraySupported() const = 0; + virtual bool IsStorageBufferSupported() const = 0; + virtual bool IsAtomicCounterBufferSupported() const = 0; + virtual bool IsShaderImageLoadStoreSupported() const = 0; + virtual bool IsProgramPipelineSupported() const = 0; + virtual bool IsPathRenderingSupported() const = 0; + virtual bool IsBlendCoherencySupported() const = 0; + virtual bool IsAdvancedBlendHwSupported() const = 0; + virtual bool IsAdvancedBlendHwSupportedKHR() const = 0; + virtual bool IsStandardDerivativesSupported() const = 0; + virtual bool IsTextureLodSupported() const = 0; + + virtual void SetDefaultRenderTarget(QT3DSU64 targetID) = 0; + virtual void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) = 0; + + virtual NVRenderDepthStencilState * + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) = 0; + + virtual NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) = 0; + + virtual NVRenderVertexBuffer * + CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, QT3DSU32 stride = 0, + NVConstDataRef bufferData = NVConstDataRef()) = 0; + virtual NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) = 0; + + virtual NVRenderIndexBuffer * + CreateIndexBuffer(NVRenderBufferUsageType::Enum usageType, + NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef bufferData = NVConstDataRef()) = 0; + virtual NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) = 0; + + virtual NVRenderConstantBuffer * + CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) = 0; + virtual NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) = 0; + + virtual NVRenderStorageBuffer * + CreateStorageBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) = 0; + virtual NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) = 0; + + virtual NVRenderAtomicCounterBuffer * + CreateAtomicCounterBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) = 0; + virtual NVRenderAtomicCounterBuffer * + GetAtomicCounterBuffer(CRegisteredString bufferName) = 0; + virtual NVRenderAtomicCounterBuffer * + GetAtomicCounterBufferByParam(CRegisteredString paramName) = 0; + + virtual NVRenderDrawIndirectBuffer * + CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) = 0; + virtual NVRenderDrawIndirectBuffer *GetDrawIndirectBuffer( + NVRenderBackend::NVRenderBackendBufferObject implementationHandle) = 0; + + virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; + + virtual NVRenderOcclusionQuery *CreateOcclusionQuery() = 0; + virtual NVRenderTimerQuery *CreateTimerQuery() = 0; + virtual NVRenderSync *CreateSync() = 0; + + virtual NVRenderTexture2D *CreateTexture2D() = 0; + virtual NVRenderTexture2D *GetTexture2D(const void *implementationHandle) = 0; + virtual NVRenderBackend *GetBackend() = 0; + + virtual NVRenderTexture2DArray *CreateTexture2DArray() = 0; + + virtual NVRenderTextureCube *CreateTextureCube() = 0; + + virtual NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) = 0; + + virtual NVRenderRenderBuffer * + CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width, + QT3DSU32 height) = 0; + virtual NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) = 0; + // Create a new frame buffer and set the current render target to that frame buffer. + virtual NVRenderFrameBuffer *CreateFrameBuffer() = 0; + virtual NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) = 0; + + virtual NVRenderAttribLayout * + CreateAttributeLayout(NVConstDataRef attribs) = 0; + + virtual NVRenderInputAssembler * + CreateInputAssembler(NVRenderAttribLayout *attribLayout, + NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, + NVConstDataRef offsets, + NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles, + QT3DSU32 patchVertexCount = 1) = 0; + virtual void SetInputAssembler(NVRenderInputAssembler *inputAssembler) = 0; + + virtual NVRenderVertFragCompilationResult CompileSource( + const char *shaderName, NVConstDataRef vertShader, + NVConstDataRef fragShader, + NVConstDataRef tessControlShaderSource = NVConstDataRef(), + NVConstDataRef tessEvaluationShaderSource = NVConstDataRef(), + NVConstDataRef geometryShaderSource = NVConstDataRef(), + bool separateProgram = false, + NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, + bool binaryProgram = false) = 0; + + // You must figure out inVertLen and inFragLen yourself, this object doesn't do that. + NVRenderVertFragCompilationResult + CompileSource(const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, + const char *fragShader, QT3DSU32 inFragLen, const char * = NULL, + QT3DSU32 inTCLen = 0, const char *tessEvaluationShaderSource = NULL, + QT3DSU32 inTELen = 0, const char *geometryShaderSource = NULL, QT3DSU32 inGSLen = 0, + bool separableProgram = false); + + virtual NVRenderVertFragCompilationResult + CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef vertShader, NVDataRef fragShader, + NVDataRef tessControlShaderSource = NVDataRef(), + NVDataRef tessEvaluationShaderSource = NVDataRef(), + NVConstDataRef geometryShaderSource = NVConstDataRef()) = 0; + + virtual NVRenderVertFragCompilationResult + CompileComputeSource(const char *shaderName, NVConstDataRef computeShaderSource) = 0; + + virtual NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) = 0; + + virtual NVRenderProgramPipeline *CreateProgramPipeline() = 0; + + virtual NVRenderPathSpecification *CreatePathSpecification() = 0; + virtual NVRenderPathRender *CreatePathRender(size_t range = 1) = 0; + virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; + virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; + virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; + virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) = 0; + + virtual NVRenderPathFontSpecification * + CreatePathFontSpecification(CRegisteredString fontName) = 0; + virtual NVRenderPathFontItem *CreatePathFontItem() = 0; + + // Specific setters for the guaranteed-to-exist context properties to set them as fast as + // possible. + // Note that this bypasses the property manage so push/pop will have no effect (unless you + // set these already + // once after a push using the property manager. + virtual void SetClearColor(QT3DSVec4 inClearColor) = 0; + virtual QT3DSVec4 GetClearColor() const = 0; + + virtual void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) = 0; + virtual NVRenderBlendFunctionArgument GetBlendFunction() const = 0; + + virtual void SetBlendEquation(NVRenderBlendEquationArgument inEquations) = 0; + virtual NVRenderBlendEquationArgument GetBlendEquation() const = 0; + + virtual void SetCullingEnabled(bool inEnabled) = 0; + virtual bool IsCullingEnabled() const = 0; + + virtual void SetDepthFunction(NVRenderBoolOp::Enum inFunction) = 0; + virtual qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const = 0; + + virtual void SetBlendingEnabled(bool inEnabled) = 0; + virtual bool IsBlendingEnabled() const = 0; + + virtual void SetDepthWriteEnabled(bool inEnabled) = 0; + virtual bool IsDepthWriteEnabled() const = 0; + + virtual void SetDepthTestEnabled(bool inEnabled) = 0; + virtual bool IsDepthTestEnabled() const = 0; + + virtual void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) = 0; + virtual void SetStencilTestEnabled(bool inEnabled) = 0; + virtual bool IsStencilTestEnabled() const = 0; + + virtual void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) = 0; + + virtual void SetScissorTestEnabled(bool inEnabled) = 0; + virtual bool IsScissorTestEnabled() const = 0; + + virtual void SetScissorRect(NVRenderRect inRect) = 0; + virtual NVRenderRect GetScissorRect() const = 0; + + virtual void SetViewport(NVRenderRect inViewport) = 0; + virtual NVRenderRect GetViewport() const = 0; + + virtual void SetColorWritesEnabled(bool inEnabled) = 0; + virtual bool IsColorWritesEnabled() const = 0; + + virtual void SetMultisampleEnabled(bool inEnabled) = 0; + virtual bool IsMultisampleEnabled() const = 0; + + // Used during layer rendering because we can't set the *actual* viewport to what it should + // be due to hardware problems. + // Set during begin render. + static QT3DSMat44 + ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, + const NVRenderRectF &inViewport, + const NVRenderRectF &inVirtualViewport); + + virtual void SetRenderTarget(NVRenderFrameBuffer *inBuffer) = 0; + virtual void SetReadTarget(NVRenderFrameBuffer *inBuffer) = 0; + virtual NVRenderFrameBuffer *GetRenderTarget() const = 0; + + virtual void SetActiveShader(NVRenderShaderProgram *inShader) = 0; + virtual NVRenderShaderProgram *GetActiveShader() const = 0; + + virtual void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) = 0; + virtual NVRenderProgramPipeline *GetActiveProgramPipeline() const = 0; + + virtual void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; + + // Push the entire set of properties. + virtual void PushPropertySet() = 0; + // Pop the entire set of properties, potentially forcing the values + // to opengl. Will set the hardware state to whatever at the time of push. + virtual void PopPropertySet(bool inForceSetProperties) = 0; + + // Ensure the hardware state matches the state we expect. + virtual void ResetBlendState() = 0; + + // Draw buffers are what the system will render to.. Applies to the current render context. + //-1 means none, else the integer is assumed to be an index past the draw buffer index. + // This applies only to the currently bound framebuffer. + virtual void SetDrawBuffers(NVConstDataRef inDrawBufferSet) = 0; + virtual void SetReadBuffer(NVReadFaces::Enum inReadFace) = 0; + + virtual void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat, + NVDataRef inWriteBuffer) = 0; + + // Return the property manager for this render context + // virtual NVRenderPropertyManager& GetPropertyManager() = 0; + // Clear the current render target + virtual void Clear(NVRenderClearFlags flags) = 0; + // Clear this framebuffer without changing the active frame buffer + virtual void Clear(NVRenderFrameBuffer &framebuffer, NVRenderClearFlags flags) = 0; + // copy framebuffer content between read target and render target + virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) = 0; + + // Render, applying these immediate property values just before render. The hardware + // properties are tracked for push/pop + // but the shader properties are just set on the active shader *after* the hardware + // properties have been set. The shader properties are not tracked for push/pop. + // This call is meant to come directly before each draw call to setup the last bit of state + // before the draw operation. Note that there isn't another way to set the immedate + // property values for a given shader because it isn't clear which shader is active + // when the properties are getting set. + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override = 0; + + /** + * @brief Draw the current active vertex buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] indirect Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) = 0; + + virtual NVFoundationBase &GetFoundation() = 0; + virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; + virtual NVAllocatorCallback &GetAllocator() = 0; + + virtual QSurfaceFormat format() const = 0; + + virtual void resetStates() = 0; + + static NVRenderContext &CreateGL(NVFoundationBase &foundation, IStringTable &inStringTable, + const QSurfaceFormat &format); + + static NVRenderContext &CreateNULL(NVFoundationBase &foundation, + IStringTable &inStringTable); + }; + + // Now for scoped property access. + template + struct NVRenderContextScopedProperty + : public NVRenderGenericScopedProperty + { + typedef typename NVRenderGenericScopedProperty::TGetter TGetter; + typedef typename NVRenderGenericScopedProperty::TSetter TSetter; + NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter) + : NVRenderGenericScopedProperty(ctx, getter, setter) + { + } + NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter, + const TDataType &inNewValue) + : NVRenderGenericScopedProperty(ctx, getter, setter, + inNewValue) + { + } + }; + +/** + * A Render Context implementation class + * + */ + +#define ITERATE_HARDWARE_CONTEXT_PROPERTIES \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(RenderTarget, FrameBuffer) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveShader, ActiveShader) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveProgramPipeline, ActiveProgramPipeline) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(InputAssembler, InputAssembler) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendFunction, BlendFunction) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(CullingEnabled, CullingEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthFunction, DepthFunction) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendingEnabled, BlendingEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthWriteEnabled, DepthWriteEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthTestEnabled, DepthTestEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(StencilTestEnabled, StencilTestEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorTestEnabled, ScissorTestEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorRect, ScissorRect) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(Viewport, Viewport) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ClearColor, ClearColor) + + // forward declarations + + class NVRenderContextImpl : public NVRenderContext, public NoCopy + { + public: + // these variables represent the current hardware state of the render context. + SNVGLHardPropertyContext m_HardwarePropertyContext; + + private: + NVScopedRefCounted m_backend; ///< pointer to our render backend + NVRenderContextDirtyFlags m_DirtyFlags; ///< context dirty flags + + NVRenderBackend::NVRenderBackendRenderTargetObject + m_DefaultOffscreenRenderTarget; ///< this is a special target set from outside if we + ///never render to a window directly (GL only) + QT3DSI32 m_DephBits; ///< this is the depth bits count of the default window render target + QT3DSI32 m_StencilBits; ///< this is the stencil bits count of the default window render target + + protected: + volatile QT3DSI32 mRefCount; + NVFoundationBase &m_Foundation; + qt3ds::foundation::IStringTable &m_StringTable; + + nvhash_map m_VertToImpMap; + nvhash_map m_IndexToImpMap; + TContextConstantBufferMap m_ConstantToImpMap; + TContextStorageBufferMap m_StorageToImpMap; + TContextAtomicCounterBufferMap m_AtomicCounterToImpMap; + TContextDrawIndirectBufferMap m_DrawIndirectToImpMap; + TContextDepthStencilStateMap m_DepthStencilStateToImpMap; + TContextRasterizerStateMap m_RasterizerStateToImpMap; + TContextPathFontSpecificationMap m_PathFontSpecToImpMap; + + nvhash_map m_Tex2DToImpMap; + TContextTex2DArrayToImpMap m_Tex2DArrayToImpMap; + TContextTexCubeToImpMap m_TexCubeToImpMap; + TContextImage2DToImpMap m_Image2DtoImpMap; + nvhash_map m_ShaderToImpMap; + nvhash_map m_RenderBufferToImpMap; + nvhash_map m_FrameBufferToImpMap; + QT3DSU32 m_MaxTextureUnits; + QT3DSU32 m_NextTextureUnit; + QT3DSU32 m_MaxConstantBufferUnits; + QT3DSU32 m_NextConstantBufferUnit; + + nvvector m_PropertyStack; + + void DoSetClearColor(QT3DSVec4 inClearColor) + { + m_HardwarePropertyContext.m_ClearColor = inClearColor; + m_backend->SetClearColor(&inClearColor); + } + + void DoSetBlendFunction(NVRenderBlendFunctionArgument inFunctions) + { + QT3DSI32_4 values; + m_HardwarePropertyContext.m_BlendFunction = inFunctions; + + m_backend->SetBlendFunc(inFunctions); + } + + void DoSetBlendEquation(NVRenderBlendEquationArgument inEquations) + { + QT3DSI32_4 values; + m_HardwarePropertyContext.m_BlendEquation = inEquations; + + m_backend->SetBlendEquation(inEquations); + } + + void DoSetCullingEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_CullingEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::CullFace); + } + + void DoSetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) + { + m_HardwarePropertyContext.m_DepthFunction = inFunction; + m_backend->SetDepthFunc(inFunction); + } + + void DoSetBlendingEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_BlendingEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::Blend); + } + + void DoSetColorWritesEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_ColorWritesEnabled = inEnabled; + m_backend->SetColorWrites(inEnabled, inEnabled, inEnabled, inEnabled); + } + + void DoSetMultisampleEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_MultisampleEnabled = inEnabled; + m_backend->SetMultisample(inEnabled); + } + + void DoSetDepthWriteEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; + m_backend->SetDepthWrite(inEnabled); + } + + void DoSetDepthTestEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_DepthTestEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::DepthTest); + } + + void DoSetStencilTestEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_StencilTestEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::StencilTest); + } + + void DoSetScissorTestEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_ScissorTestEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::ScissorTest); + } + + void DoSetScissorRect(NVRenderRect inRect) + { + m_HardwarePropertyContext.m_ScissorRect = inRect; + m_backend->SetScissorRect(inRect); + } + + void DoSetViewport(NVRenderRect inViewport) + { + m_HardwarePropertyContext.m_Viewport = inViewport; + m_backend->SetViewportRect(inViewport); + } + + // Circular dependencies between shader constants and shader programs preclude + // implementation in header + void DoSetActiveShader(NVRenderShaderProgram *inShader); + void DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline); + + void DoSetInputAssembler(NVRenderInputAssembler *inAssembler) + { + m_HardwarePropertyContext.m_InputAssembler = inAssembler; + m_DirtyFlags |= NVRenderContextDirtyValues::InputAssembler; + } + + void DoSetRenderTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer) + m_backend->SetRenderTarget(inBuffer->GetFrameBuffertHandle()); + else + m_backend->SetRenderTarget(m_DefaultOffscreenRenderTarget); + + m_HardwarePropertyContext.m_FrameBuffer = inBuffer; + } + + void DoSetReadTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer) + m_backend->SetReadTarget(inBuffer->GetFrameBuffertHandle()); + else + m_backend->SetReadTarget(NVRenderBackend::NVRenderBackendRenderTargetObject(NULL)); + } + + bool BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, + NVRenderShaderProgram *shader); + bool ApplyPreDrawProperties(); + void OnPostDraw(); + + public: + NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, + IStringTable &inStrTable); + virtual ~NVRenderContextImpl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation); + + NVRenderBackend *GetBackend() override { return m_backend; } + + void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) override; + + const char *GetShadingLanguageVersion() override + { + return m_backend->GetShadingLanguageVersion(); + } + + NVRenderContextType GetRenderContextType() const override + { + return m_backend->GetRenderContextType(); + } + + QT3DSU32 GetDepthBits() const override + { + // only query this if a framebuffer is bound + if (m_HardwarePropertyContext.m_FrameBuffer) + return m_backend->GetDepthBits(); + else + return m_DephBits; + } + + QT3DSU32 GetStencilBits() const override + { + // only query this if a framebuffer is bound + if (m_HardwarePropertyContext.m_FrameBuffer) + return m_backend->GetStencilBits(); + else + return m_StencilBits; + } + + bool GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const override + { + return m_backend->GetRenderBackendCap(inCap); + } + + bool AreMultisampleTexturesSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::MsTexture); + } + + bool GetConstantBufferSupport() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ConstantBuffer); + } + + bool AreDXTImagesSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DxtImages); + } + + bool IsDepthStencilSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DepthStencilTexture); + } + + bool IsFpRenderTargetSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::FpRenderTarget); + } + + bool IsTessellationSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Tessellation); + } + + bool IsGeometryStageSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Geometry); + } + + bool IsComputeSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Compute); + } + + bool IsSampleQuerySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::SampleQuery); + } + + bool IsTimerQuerySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TimerQuery); + } + + bool IsCommandSyncSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::CommandSync); + } + bool IsTextureArraySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureArray); + } + bool IsStorageBufferSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StorageBuffer); + } + bool IsAtomicCounterBufferSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AtomicCounterBuffer); + } + bool IsShaderImageLoadStoreSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ShaderImageLoadStore); + } + bool IsProgramPipelineSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ProgramPipeline); + } + bool IsPathRenderingSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::PathRendering); + } + // Are blend modes really supported in HW? + bool IsAdvancedBlendHwSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlend); + } + bool IsAdvancedBlendHwSupportedKHR() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlendKHR); + } + bool IsBlendCoherencySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::BlendCoherency); + } + bool IsStandardDerivativesSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StandardDerivatives); + } + bool IsTextureLodSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureLod); + } + + void SetDefaultRenderTarget(QT3DSU64 targetID) override + { + m_DefaultOffscreenRenderTarget = + (NVRenderBackend::NVRenderBackendRenderTargetObject)targetID; + } + + void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) override { m_DephBits = depthBits; } + + virtual NVRenderDepthStencilState * + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) override; + void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) override; + virtual void StateDestroyed(NVRenderDepthStencilState &state); + + NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) override; + void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) override; + virtual void StateDestroyed(NVRenderRasterizerState &state); + + NVRenderVertexBuffer *CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, + size_t size, QT3DSU32 stride, + NVConstDataRef bufferData) override; + NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) override; + virtual void BufferDestroyed(NVRenderVertexBuffer &buffer); + + virtual NVRenderIndexBuffer * + CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, + qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef bufferData) override; + NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) override; + virtual void BufferDestroyed(NVRenderIndexBuffer &buffer); + + virtual NVRenderConstantBuffer * + CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) override; + NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) override; + virtual void BufferDestroyed(NVRenderConstantBuffer &buffer); + + virtual QT3DSU32 GetNextConstantBufferUnit(); + + virtual NVRenderStorageBuffer * + CreateStorageBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) override; + NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) override; + virtual void BufferDestroyed(NVRenderStorageBuffer &buffer); + + virtual NVRenderAtomicCounterBuffer * + CreateAtomicCounterBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) override; + NVRenderAtomicCounterBuffer *GetAtomicCounterBuffer(CRegisteredString bufferName) override; + virtual NVRenderAtomicCounterBuffer * + GetAtomicCounterBufferByParam(CRegisteredString paramName) override; + virtual void BufferDestroyed(NVRenderAtomicCounterBuffer &buffer); + + virtual NVRenderDrawIndirectBuffer * + CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) override; + virtual NVRenderDrawIndirectBuffer * + GetDrawIndirectBuffer(NVRenderBackend::NVRenderBackendBufferObject implementationHandle) override; + virtual void BufferDestroyed(NVRenderDrawIndirectBuffer &buffer); + + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + + NVRenderOcclusionQuery *CreateOcclusionQuery() override; + NVRenderTimerQuery *CreateTimerQuery() override; + NVRenderSync *CreateSync() override; + + NVRenderTexture2D *CreateTexture2D() override; + NVRenderTexture2D *GetTexture2D(const void *implementationHandle) override; + virtual void TextureDestroyed(NVRenderTexture2D &buffer); + + NVRenderTexture2DArray *CreateTexture2DArray() override; + virtual void TextureDestroyed(NVRenderTexture2DArray &buffer); + + NVRenderTextureCube *CreateTextureCube() override; + virtual void TextureDestroyed(NVRenderTextureCube &buffer); + + virtual QT3DSU32 GetNextTextureUnit(); + + NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) override; + virtual void ImageDestroyed(NVRenderImage2D &buffer); + + virtual NVRenderRenderBuffer * + CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width, + QT3DSU32 height) override; + NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) override; + virtual void RenderBufferDestroyed(NVRenderRenderBuffer &buffer); + + NVRenderFrameBuffer *CreateFrameBuffer() override; + NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) override; + virtual void FrameBufferDestroyed(NVRenderFrameBuffer &fb); + + virtual NVRenderAttribLayout * + CreateAttributeLayout(NVConstDataRef attribs) override; + NVRenderInputAssembler *CreateInputAssembler( + NVRenderAttribLayout *attribLayout, NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, + NVConstDataRef offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) override; + void SetInputAssembler(NVRenderInputAssembler *inputAssembler) override; + + NVRenderVertFragCompilationResult CompileSource( + const char *shaderName, NVConstDataRef vertShader, + NVConstDataRef fragShader, + NVConstDataRef tessControlShaderSource = NVConstDataRef(), + NVConstDataRef tessEvaluationShaderSource = NVConstDataRef(), + NVConstDataRef geometryShaderSource = NVConstDataRef(), + bool separateProgram = false, + NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, + bool binaryProgram = false) override; + + virtual NVRenderVertFragCompilationResult + CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef vertShader, NVDataRef fragShader, + NVDataRef tessControlShaderSource = NVDataRef(), + NVDataRef tessEvaluationShaderSource = NVDataRef(), + NVConstDataRef geometryShaderSource = NVConstDataRef()) override; + + virtual NVRenderVertFragCompilationResult + CompileComputeSource(const char *shaderName, NVConstDataRef computeShaderSource) override; + + NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) override; + virtual void ShaderDestroyed(NVRenderShaderProgram &shader); + + NVRenderProgramPipeline *CreateProgramPipeline() override; + NVRenderPathSpecification *CreatePathSpecification() override; + NVRenderPathRender *CreatePathRender(size_t range = 1) override; + void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; + void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; + void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) override; + + virtual NVRenderPathFontSpecification * + CreatePathFontSpecification(CRegisteredString fontName) override; + virtual void ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec); + NVRenderPathFontItem *CreatePathFontItem() override; + + void SetClearColor(QT3DSVec4 inClearColor) override; + QT3DSVec4 GetClearColor() const override { return m_HardwarePropertyContext.m_ClearColor; } + + void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) override; + NVRenderBlendFunctionArgument GetBlendFunction() const override + { + return m_HardwarePropertyContext.m_BlendFunction; + } + + void SetBlendEquation(NVRenderBlendEquationArgument inEquations) override; + NVRenderBlendEquationArgument GetBlendEquation() const override + { + return m_HardwarePropertyContext.m_BlendEquation; + }; + + void SetCullingEnabled(bool inEnabled) override; + bool IsCullingEnabled() const override { return m_HardwarePropertyContext.m_CullingEnabled; } + + void SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) override; + qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const override + { + return m_HardwarePropertyContext.m_DepthFunction; + } + + void SetBlendingEnabled(bool inEnabled) override; + bool IsBlendingEnabled() const override + { + return m_HardwarePropertyContext.m_BlendingEnabled; + } + + void SetDepthWriteEnabled(bool inEnabled) override; + bool IsDepthWriteEnabled() const override + { + return m_HardwarePropertyContext.m_DepthWriteEnabled; + } + void SetDepthTestEnabled(bool inEnabled) override; + bool IsDepthTestEnabled() const override + { + return m_HardwarePropertyContext.m_DepthTestEnabled; + } + + void SetStencilTestEnabled(bool inEnabled) override; + bool IsStencilTestEnabled() const override + { + return m_HardwarePropertyContext.m_StencilTestEnabled; + } + + void SetScissorTestEnabled(bool inEnabled) override; + bool IsScissorTestEnabled() const override + { + return m_HardwarePropertyContext.m_ScissorTestEnabled; + } + void SetScissorRect(NVRenderRect inRect) override; + NVRenderRect GetScissorRect() const override + { + return m_HardwarePropertyContext.m_ScissorRect; + } + + void SetViewport(NVRenderRect inViewport) override; + NVRenderRect GetViewport() const override { return m_HardwarePropertyContext.m_Viewport; } + + void SetColorWritesEnabled(bool inEnabled) override; + bool IsColorWritesEnabled() const override + { + return m_HardwarePropertyContext.m_ColorWritesEnabled; + } + + void SetMultisampleEnabled(bool inEnabled) override; + bool IsMultisampleEnabled() const override + { + return m_HardwarePropertyContext.m_MultisampleEnabled; + } + + void SetActiveShader(NVRenderShaderProgram *inShader) override; + NVRenderShaderProgram *GetActiveShader() const override + { + return m_HardwarePropertyContext.m_ActiveShader; + } + + void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) override; + NVRenderProgramPipeline *GetActiveProgramPipeline() const override + { + return m_HardwarePropertyContext.m_ActiveProgramPipeline; + } + + void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + + void SetDrawBuffers(NVConstDataRef inDrawBufferSet) override; + void SetReadBuffer(NVReadFaces::Enum inReadFace) override; + + void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat, + NVDataRef inWriteBuffer) override; + + void SetRenderTarget(NVRenderFrameBuffer *inBuffer) override; + void SetReadTarget(NVRenderFrameBuffer *inBuffer) override; + NVRenderFrameBuffer *GetRenderTarget() const override + { + return m_HardwarePropertyContext.m_FrameBuffer; + } + + void ResetBlendState() override; + + // Push the entire set of properties. + void PushPropertySet() override { m_PropertyStack.push_back(m_HardwarePropertyContext); } + + // Pop the entire set of properties, potentially forcing the values + // to opengl. + void PopPropertySet(bool inForceSetProperties) override; + + // clear current bound render target + void Clear(NVRenderClearFlags flags) override; + // clear passed in rendertarget + void Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) override; + + // copy framebuffer content between read target and render target + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override; + void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) override; + + NVFoundationBase &GetFoundation() override { return m_Foundation; } + qt3ds::foundation::IStringTable &GetStringTable() override { return m_StringTable; } + NVAllocatorCallback &GetAllocator() override { return m_Foundation.getAllocator(); } + QSurfaceFormat format() const override + { + return m_backend->format(); + } + virtual void resetStates() + { + PushPropertySet(); + PopPropertySet(true); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp new file mode 100644 index 00000000..b00b0af0 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderDataBuffer.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderDataBuffer::NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, + size_t size, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, + NVDataRef data) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_UsageType(usageType) + , m_BindFlags(bindFlags) + , m_BufferData(data) + , m_BufferCapacity(data.size()) + , m_BufferSize(size) + , m_OwnsData(false) + , m_Mapped(false) + { + m_BufferHandle = + m_Backend->CreateBuffer(size, bindFlags, usageType, (const void *)m_BufferData.begin()); + } + + NVRenderDataBuffer::~NVRenderDataBuffer() + { + if (m_BufferHandle) { + m_Backend->ReleaseBuffer(m_BufferHandle); + } + m_BufferHandle = 0; + + releaseMemory(); + } + + void NVRenderDataBuffer::releaseMemory() + { + // chekc if we should release memory + if (m_BufferData.size() && m_OwnsData) { + m_Foundation.getAllocator().deallocate(m_BufferData.begin()); + } + + m_BufferData = NVDataRef(); + m_OwnsData = false; + } + + NVDataRef NVRenderDataBuffer::MapBuffer() + { + // don't map twice + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer"); + QT3DS_ASSERT(false); + } + + QT3DSU8 *pData = (QT3DSU8 *)m_Backend->MapBuffer( + m_BufferHandle, m_BindFlags, 0, m_BufferSize, + NVRenderBufferAccessFlags(NVRenderBufferAccessTypeValues::Read + | NVRenderBufferAccessTypeValues::Write)); + + releaseMemory(); + m_BufferData = toDataRef(const_cast(pData), (QT3DSU32)m_BufferSize); + m_BufferCapacity = (QT3DSU32)m_BufferSize; + m_OwnsData = false; + + // currently we return a reference to the system memory + m_Mapped = true; + return m_BufferData; + } + + NVDataRef NVRenderDataBuffer::MapBufferRange(size_t offset, size_t size, + NVRenderBufferAccessFlags flags) + { + // don't map twice + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer"); + QT3DS_ASSERT(false); + } + // don't map out of range + if ((m_BufferSize < (offset + size)) || (size == 0)) { + qCCritical(INVALID_OPERATION, "Attempting to map out of buffer range"); + QT3DS_ASSERT(false); + } + + QT3DSU8 *pData = + (QT3DSU8 *)m_Backend->MapBuffer(m_BufferHandle, m_BindFlags, offset, size, flags); + + releaseMemory(); + m_BufferData = toDataRef(const_cast(pData), (QT3DSU32)size); + m_BufferCapacity = (QT3DSU32)size; + m_OwnsData = false; + + // currently we return a reference to the system memory + m_Mapped = true; + return m_BufferData; + } + + void NVRenderDataBuffer::UnmapBuffer() + { + if (m_Mapped) { + // update hardware + m_Backend->UnmapBuffer(m_BufferHandle, m_BindFlags); + m_Mapped = false; + releaseMemory(); + } + } + + void NVRenderDataBuffer::UpdateBuffer(NVConstDataRef data, bool ownsMemory) + { + // don't update a mapped buffer + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to update a mapped buffer"); + QT3DS_ASSERT(false); + } + + releaseMemory(); + + m_BufferData = toDataRef(const_cast(data.begin()), data.size()); + m_BufferCapacity = data.mSize; + m_OwnsData = ownsMemory; + // update hardware + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferCapacity, m_UsageType, + (const void *)m_BufferData.begin()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h new file mode 100644 index 00000000..579e2361 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DATA_BUFFER_H +#define QT3DS_RENDER_DATA_BUFFER_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + class NVRenderBackend; + + ///< Base class + class NVRenderDataBuffer : public NVRefCounted, public NVRenderImplemented + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBufferUsageType::Enum m_UsageType; ///< usage type + NVRenderBufferBindFlags m_BindFlags; ///< bind flags + NVDataRef m_BufferData; ///< buffer data pointer + QT3DSU32 m_BufferCapacity; ///< size of internal backup buffer (m_BufferData) + size_t m_BufferSize; ///< size of buffer + bool m_OwnsData; ///< true when we own m_BufferData + bool m_Mapped; ///< true when locked for reading or writing to m_BufferData + NVRenderBackend::NVRenderBackendBufferObject m_BufferHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return No return. + */ + NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, NVDataRef data); + + virtual ~NVRenderDataBuffer(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + /** + * @brief Get Buffer usage type + * + * @return Return usage tyoe + */ + virtual NVRenderBufferUsageType::Enum GetBufferUsageType() const + { + return m_UsageType; + } + + /** + * @brief Get Buffer usage type + * Should be overwritten + * + * @return Return usage tyoe + */ + virtual NVRenderBufferBindFlags GetBufferBindings() const { return m_BindFlags; } + + /** + * @brief Return buffer size in byte + * + * @return Return size + */ + virtual QT3DSU32 Size() { return (QT3DSU32)m_BufferSize; } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + virtual void Bind() = 0; + + /** + * @brief Map the buffer + * Mapped buffers cannot be used for rendering + * + * @return Return mapped pointer to data + */ + virtual NVDataRef MapBuffer(); + + /** + * @brief Map a range of a buffer + * Mapped buffers cannot be used for rendering + * + * @param[in] offset Offset in bytes into the buffer + * @param[in] size Range in bytes to map + * @param[in] flags Buffer access flags + * + * @return Return mapped pointer to data + */ + virtual NVDataRef MapBufferRange(size_t offset, size_t size, + NVRenderBufferAccessFlags flags); + + /** + * @brief Unmap the buffer + * This updates the data to the hardware + * + * @return no return + */ + virtual void UnmapBuffer(); + + /** + * @brief constructor + * + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * @param[in] ownsMemory If true data will be owned by this object and can therefore be + * released + * + * @return No return. + */ + virtual void UpdateBuffer(NVConstDataRef data, bool ownsMemory = false); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const = 0; + + // this will be obsolete + const void *GetImplementationHandle() const override = 0; + + private: + void releaseMemory(); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp new file mode 100644 index 00000000..3ea47e23 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderDepthStencilState.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderDepthStencilState::NVRenderDepthStencilState( + NVRenderContextImpl &context, NVFoundationBase &fnd, bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_DepthEnabled(enableDepth) + , m_DepthMask(depthMask) + , m_DepthFunc(depthFunc) + , m_StencilEnabled(enableStencil) + , m_StencilFuncFront(stencilFuncFront) + , m_StencilFuncBack(stencilFuncBack) + , m_DepthStencilOpFront(depthStencilOpFront) + , m_DepthStencilOpBack(depthStencilOpBack) + { + // create backend handle + m_StateHandle = m_Backend->CreateDepthStencilState( + enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, + depthStencilOpFront, depthStencilOpBack); + } + + NVRenderDepthStencilState::~NVRenderDepthStencilState() + { + if (m_StateHandle) { + m_Context.StateDestroyed(*this); + m_Backend->ReleaseDepthStencilState(m_StateHandle); + } + } + + NVRenderDepthStencilState * + NVRenderDepthStencilState::Create(NVRenderContextImpl &context, bool enableDepth, + bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderDepthStencilState)( + context, context.GetFoundation(), enableDepth, depthMask, depthFunc, enableStencil, + stencilFuncFront, stencilFuncBack, depthStencilOpFront, depthStencilOpBack); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h new file mode 100644 index 00000000..e6b31981 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DEPTH_STENCIL_STATE_H +#define QT3DS_RENDER_DEPTH_STENCIL_STATE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + + // currently this handles only stencil state + class NVRenderDepthStencilState : public NVRefCounted + { + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendDepthStencilStateObject + m_StateHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] enableDepth enable depth test + * @param[in] depthMask enable depth writes + * @param[in] depthFunc depth compare function + * @param[in] enableStencil enable stencil test + * @param[in] stencilFuncFront stencil setup front faces + * @param[in] stencilFuncBack stencil setup back faces + * @param[in] depthStencilOpFront depth/stencil operations front faces + * @param[in] depthStencilOpBack depth/stencil operations back faces + * + * @return No return. + */ + NVRenderDepthStencilState(NVRenderContextImpl &context, NVFoundationBase &fnd, + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack); + + virtual ~NVRenderDepthStencilState(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + ///< various get functions + const NVRenderStencilFunctionArgument GetStencilFunc(NVRenderFaces::Enum face) const + { + return (face == NVRenderFaces::Back) ? m_StencilFuncBack : m_StencilFuncFront; + } + const NVRenderStencilOperationArgument GetStencilOp(NVRenderFaces::Enum face) const + { + return (face == NVRenderFaces::Back) ? m_DepthStencilOpBack : m_DepthStencilOpFront; + } + NVRenderBoolOp::Enum GetDepthFunc() const { return m_DepthFunc; } + bool GetDepthEnabled() const { return m_DepthEnabled; } + bool GetStencilEnabled() const { return m_StencilEnabled; } + bool GetDepthMask() const { return m_DepthMask; } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendDepthStencilStateObject + GetDepthStencilObjectHandle() + { + return m_StateHandle; + } + + static NVRenderDepthStencilState * + Create(NVRenderContextImpl &context, bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack); + + private: + bool m_DepthEnabled; ///< depth test enabled + bool m_DepthMask; ///< depth writes enabled + NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func + bool m_StencilEnabled; ///< stencil test enabled + NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup front faces + NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup back faces + NVRenderStencilOperationArgument + m_DepthStencilOpFront; ///< depth stencil operation front faces + NVRenderStencilOperationArgument + m_DepthStencilOpBack; ///< depth stencil operation back faces + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp new file mode 100644 index 00000000..9940003f --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderDrawIndirectBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + NVRenderDrawIndirectBuffer::NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, + size_t size, + NVRenderBufferUsageType::Enum usageType, + NVDataRef data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Draw_Indirect, usageType, data) + , m_Dirty(true) + { + } + + NVRenderDrawIndirectBuffer::~NVRenderDrawIndirectBuffer() { m_Context.BufferDestroyed(*this); } + + void NVRenderDrawIndirectBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderDrawIndirectBuffer::Update() + { + // we only update the buffer if it is dirty and we actually have some data + if (m_Dirty && m_BufferData.size()) { + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, + m_BufferData.begin()); + m_Dirty = false; + } + } + + void NVRenderDrawIndirectBuffer::UpdateData(QT3DSI32 offset, NVDataRef data) + { + // we only update the buffer if we something + if (data.size()) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, + data.begin() + offset); + } + + NVRenderDrawIndirectBuffer * + NVRenderDrawIndirectBuffer::Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderDrawIndirectBuffer *retval = NULL; + + // these are the context flags which do not support this drawing mode + NVRenderContextType noDrawIndirectSupported( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2 | NVRenderContextValues::GL3 + | NVRenderContextValues::GLES3); + NVRenderContextType ctxType = context.GetRenderContextType(); + + if (!(ctxType & noDrawIndirectSupported)) { + QT3DSU32 bufSize = sizeof(NVRenderDrawIndirectBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "DrawIndirectBuffer"); + retval = new (newMem) NVRenderDrawIndirectBuffer( + context, size, usageType, + toDataRef(const_cast(bufferData.begin()), bufferData.size())); + } else { + QT3DS_ASSERT(false); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h new file mode 100644 index 00000000..81cd59d1 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + + struct DrawArraysIndirectCommand + { + QT3DSU32 count; + QT3DSU32 primCount; + QT3DSU32 first; + QT3DSU32 baseInstance; + }; + + struct DrawElementsIndirectCommand + { + QT3DSU32 count; + QT3DSU32 primCount; + QT3DSU32 firstIndex; + QT3DSU32 baseVertex; + QT3DSU32 baseInstance; + }; + + ///< Constant (uniform) buffer representation + class NVRenderDrawIndirectBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, size_t size, + NVRenderBufferUsageType::Enum usageType, NVDataRef data); + + ///< destructor + virtual ~NVRenderDrawIndirectBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief update a piece of memory directly within the storage buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 (430) layout which guarantees a specific layout behavior across + *all HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into storage buffer + * @param[in] data pointer to data + * + * @return no return + */ + void UpdateData(QT3DSI32 offset, NVDataRef data); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + /** + * @brief create a NVRenderDrawIndirectBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the buffer object or NULL + */ + static NVRenderDrawIndirectBuffer *Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef bufferData); + + private: + bool m_Dirty; ///< true if buffer is dirty + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawable.h b/src/Runtime/Source/render/Qt3DSRenderDrawable.h new file mode 100644 index 00000000..0f78aacc --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDrawable.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H +#define QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H +#include "Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + class NVRenderDrawable + { + protected: + virtual ~NVRenderDrawable() {} + + public: + /** + * Draw using this object. + * offset is in num elements, not in number of bytes + * because the various different draw functions differ in what datatype + * offset is (gl drawarrays vs gl drawindexedarras). + */ + virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp new file mode 100644 index 00000000..e2f31f1b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderFragmentShader.h" + +namespace qt3ds { +namespace render { + + NVRenderFragmentShader::NVRenderFragmentShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateFragmentShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderFragmentShader::~NVRenderFragmentShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseFragmentShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h new file mode 100644 index 00000000..f661605c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_FRAGMENT_SHADER_H +#define QT3DS_RENDER_FRAGMENT_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a fragment shader + class NVRenderFragmentShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderFragmentShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram); + + /// @brief destructor + ~NVRenderFragmentShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendFragmentShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendFragmentShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp new file mode 100644 index 00000000..0ab38428 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp @@ -0,0 +1,300 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderFrameBuffer::NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_BufferHandle(NULL) + , m_AttachmentBits(0) + { + m_BufferHandle = m_Backend->CreateRenderTarget(); + QT3DS_ASSERT(m_BufferHandle); + } + + NVRenderFrameBuffer::~NVRenderFrameBuffer() + { + m_Context.FrameBufferDestroyed(*this); + m_Backend->ReleaseRenderTarget(m_BufferHandle); + m_BufferHandle = 0; + m_AttachmentBits = 0; + + // release attachments + QT3DS_FOREACH(idx, (QT3DSU32)NVRenderFrameBufferAttachments::LastAttachment) + { + if ((NVRenderFrameBufferAttachments::Enum)idx + != NVRenderFrameBufferAttachments::DepthStencil + || m_Context.IsDepthStencilSupported()) + releaseAttachment((NVRenderFrameBufferAttachments::Enum)idx); + } + } + + inline void CheckAttachment(NVRenderContext &ctx, + NVRenderFrameBufferAttachments::Enum attachment) + { +#ifdef _DEBUG + QT3DS_ASSERT(attachment != NVRenderFrameBufferAttachments::DepthStencil + || ctx.IsDepthStencilSupported()); +#endif + (void)ctx; + (void)attachment; + } + + NVRenderTextureTargetType::Enum + NVRenderFrameBuffer::releaseAttachment(NVRenderFrameBufferAttachments::Enum idx) + { + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Unknown; + + NVRenderTextureOrRenderBuffer Attach = m_Attachments[idx]; + if (Attach.HasTexture2D()) { + target = (Attach.GetTexture2D()->IsMultisampleTexture()) + ? NVRenderTextureTargetType::Texture2D_MS + : NVRenderTextureTargetType::Texture2D; + Attach.GetTexture2D()->release(); + } else if (Attach.HasTexture2DArray()) { + target = (Attach.GetTexture2DArray()->IsMultisampleTexture()) + ? NVRenderTextureTargetType::Texture2D_MS + : NVRenderTextureTargetType::Texture2D_Array; + Attach.GetTexture2DArray()->release(); + } else if (Attach.HasTextureCube()) { + target = (Attach.GetTextureCube()->IsMultisampleTexture()) + ? NVRenderTextureTargetType::Texture2D_MS + : NVRenderTextureTargetType::TextureCube; + Attach.GetTextureCube()->release(); + } else if (Attach.HasRenderBuffer()) + Attach.GetRenderBuffer()->release(); + + CheckAttachment(m_Context, idx); + m_Attachments[idx] = NVRenderTextureOrRenderBuffer(); + + m_AttachmentBits &= ~(1 << idx); + + return target; + } + + NVRenderTextureOrRenderBuffer + NVRenderFrameBuffer::GetAttachment(NVRenderFrameBufferAttachments::Enum attachment) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return NVRenderTextureOrRenderBuffer(); + } + CheckAttachment(m_Context, attachment); + return m_Attachments[attachment]; + } + + void NVRenderFrameBuffer::Attach(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureTargetType::Enum target) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return; + } + + // early out + // if there is nothing to detach + if (!buffer.HasTexture2D() && !buffer.HasRenderBuffer() && !buffer.HasTexture2DArray() + && !(m_AttachmentBits & (1 << attachment))) + return; + + CheckAttachment(m_Context, attachment); + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + // release previous attachments + NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); + + if (buffer.HasTexture2D()) { + // On the same attachment point there could be a something attached with a different + // target MSAA <--> NoMSAA + if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target) + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTexture2D()->GetTextureObjectHandle(), target); + buffer.GetTexture2D()->addRef(); + m_AttachmentBits |= (1 << attachment); + } else if (buffer.HasTexture2DArray()) { + // On the same attachment point there could be a something attached with a different + // target MSAA <--> NoMSAA + if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target) + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTexture2D()->GetTextureObjectHandle(), target); + buffer.GetTexture2DArray()->addRef(); + m_AttachmentBits |= (1 << attachment); + } else if (buffer.HasRenderBuffer()) { + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetRenderBuffer()->GetRenderBuffertHandle()); + buffer.GetRenderBuffer()->addRef(); + m_AttachmentBits |= (1 << attachment); + } else if (theRelTarget == NVRenderTextureTargetType::Unknown) { + // detach renderbuffer + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendRenderbufferObject(NULL)); + } else { + // detach texture + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + } + m_Attachments[attachment] = buffer; + } + + void NVRenderFrameBuffer::AttachLayer(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer, + QT3DSI32 level) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return; + } + + // This function is only used for attaching a layer + // If texture exists probably something is wrong + if (!buffer.HasTexture2DArray()) { + QT3DS_ASSERT(false); + return; + } + + CheckAttachment(m_Context, attachment); + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + // release previous attachments + NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); + + // On the same attachment point there could be a something attached with a different target + // MSAA <--> NoMSAA + if (theRelTarget != NVRenderTextureTargetType::Unknown + && theRelTarget != NVRenderTextureTargetType::Texture2D_Array) + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTexture2DArray()->GetTextureObjectHandle(), level, + layer); + buffer.GetTexture2DArray()->addRef(); + m_AttachmentBits |= (1 << attachment); + + m_Attachments[attachment] = buffer; + } + + void NVRenderFrameBuffer::AttachFace(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureCubeFaces::Enum face) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return; + } + + if (face == NVRenderTextureCubeFaces::InvalidFace) { + QT3DS_ASSERT(false); + return; + } + + CheckAttachment(m_Context, attachment); + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + // release previous attachments + NVRenderTextureTargetType::Enum attachTarget = static_cast( + (int)NVRenderTextureTargetType::TextureCube + (int)face); + NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); + + // If buffer has no texture cube, this call is used to detach faces. + // If release target is not cube, there is something else attached to that + // attachment point, so we want to release that first. E.g (MSAA <--> NoMSAA) + if (theRelTarget == NVRenderTextureTargetType::TextureCube && !buffer.HasTextureCube()) { + theRelTarget = attachTarget; + attachTarget = NVRenderTextureTargetType::Unknown; + } else if (theRelTarget == NVRenderTextureTargetType::TextureCube) { + theRelTarget = NVRenderTextureTargetType::Unknown; + } + if (theRelTarget != NVRenderTextureTargetType::Unknown) { + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + } + + if (attachTarget != NVRenderTextureTargetType::Unknown) { + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTextureCube()->GetTextureObjectHandle(), + attachTarget); + buffer.GetTextureCube()->addRef(); + m_AttachmentBits |= (1 << attachment); + } + + m_Attachments[attachment] = buffer; + } + + bool NVRenderFrameBuffer::IsComplete() + { + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + return m_Backend->RenderTargetIsValid(m_BufferHandle); + } +} +} + +qt3ds::render::NVRenderFrameBuffer * +qt3ds::render::NVRenderFrameBuffer::Create(NVRenderContextImpl &context) +{ + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderFrameBuffer)(context, context.GetFoundation()); +} diff --git a/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h new file mode 100644 index 00000000..1882a27d --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTexture2D; + class NVRenderRenderBuffer; + class NVRenderTexture2DArray; + class NVRenderTextureCube; + + class NVRenderTextureOrRenderBuffer + { + NVRenderTexture2D *m_Texture2D; + NVRenderTexture2DArray *m_Texture2DArray; + NVRenderTextureCube *m_TextureCube; + NVRenderRenderBuffer *m_RenderBuffer; + + public: + NVRenderTextureOrRenderBuffer(NVRenderTexture2D &texture) + : m_Texture2D(&texture) + , m_Texture2DArray(NULL) + , m_TextureCube(NULL) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer(NVRenderRenderBuffer &render) + : m_Texture2D(NULL) + , m_Texture2DArray(NULL) + , m_TextureCube(NULL) + , m_RenderBuffer(&render) + { + } + NVRenderTextureOrRenderBuffer(NVRenderTexture2DArray &textureArray) + : m_Texture2D(NULL) + , m_Texture2DArray(&textureArray) + , m_TextureCube(NULL) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer(NVRenderTextureCube &textureCube) + : m_Texture2D(NULL) + , m_Texture2DArray(NULL) + , m_TextureCube(&textureCube) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer() + : m_Texture2D(NULL) + , m_Texture2DArray(NULL) + , m_TextureCube(NULL) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer(const NVRenderTextureOrRenderBuffer &other) + : m_Texture2D(other.m_Texture2D) + , m_Texture2DArray(other.m_Texture2DArray) + , m_TextureCube(other.m_TextureCube) + , m_RenderBuffer(other.m_RenderBuffer) + { + } + NVRenderTextureOrRenderBuffer &operator=(const NVRenderTextureOrRenderBuffer &other) + { + if (this != &other) { + m_Texture2D = const_cast(other.m_Texture2D); + m_Texture2DArray = const_cast(other.m_Texture2DArray); + m_RenderBuffer = const_cast(other.m_RenderBuffer); + m_TextureCube = const_cast(other.m_TextureCube); + } + return *this; + } + + bool HasTexture2D() const { return m_Texture2D != NULL; } + bool HasTexture2DArray() const { return m_Texture2DArray != NULL; } + bool HasTextureCube() const { return m_TextureCube != NULL; } + bool HasRenderBuffer() const { return m_RenderBuffer != NULL; } + + NVRenderTexture2D *GetTexture2D() const + { + QT3DS_ASSERT(HasTexture2D()); + return m_Texture2D; + } + NVRenderTexture2DArray *GetTexture2DArray() const + { + QT3DS_ASSERT(HasTexture2DArray()); + return m_Texture2DArray; + } + NVRenderTextureCube *GetTextureCube() const + { + QT3DS_ASSERT(HasTextureCube()); + return m_TextureCube; + } + NVRenderRenderBuffer *GetRenderBuffer() const + { + QT3DS_ASSERT(HasRenderBuffer()); + return m_RenderBuffer; + } + }; + + class NVRenderFrameBuffer : public NVRefCounted, public NVRenderImplemented + { + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + + NVRenderTextureOrRenderBuffer + m_Attachments[NVRenderFrameBufferAttachments::LastAttachment]; ///< attachments array + NVRenderBackend::NVRenderBackendRenderTargetObject + m_BufferHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd); + + /// destructor + virtual ~NVRenderFrameBuffer(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + /** + * @brief query attachment + * + * + * @return buffer format + */ + virtual NVRenderTextureOrRenderBuffer + GetAttachment(NVRenderFrameBufferAttachments::Enum attachment); + + /** + * @brief Attach a render or texture buffer to a render target + * For texture attachments we use always level 0 + * + * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) + * @param[in] buffer Contains a pointer to the attachment + * @param[in] target Attachment texture target + * + * @return no return + */ + virtual void + Attach(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D); + + /** + * @brief Attach a particular layer of the texture 2D array to a render target + * + * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) + * @param[in] buffer Pointer to the Texture Array which contains the + * layers + * @param[in] layer The index to the layer that will be attached to the + * target + * @param[in] level Mip level of the texture that will be attached + * (default 0) + * + * @return no return + */ + virtual void AttachLayer(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer, + QT3DSI32 level = 0); + + /** + * @brief Attach a particular face of the texture cubemap to a render target + * + * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) + * @param[in] buffer Pointer to the Texture Array which contains the + * layers + * @param[in] face The face of the cubemap that will be attached to the + * target + * @param[in] level Mip level of the texture that will be attached + * (default 0) + * + * @return no return + */ + virtual void AttachFace(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureCubeFaces::Enum face); + + /** + * @brief Check that this framebuffer is complete and can be rendered to. + * + * + * @return true if complete + */ + virtual bool IsComplete(); + + /** + * @brief query if framebuffer has any attachment + * + * @return true if any attachment + */ + virtual bool HasAnyAttachment() { return (m_AttachmentBits != 0); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendRenderTargetObject GetFrameBuffertHandle() + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + /** + * @brief static creator function + * + * @param[in] context Pointer to context + * + * @return a pointer to framebuffer object. + */ + static NVRenderFrameBuffer *Create(NVRenderContextImpl &context); + + private: + /** + * @brief releaes an attached object + * + * @return which target we released + */ + NVRenderTextureTargetType::Enum releaseAttachment(NVRenderFrameBufferAttachments::Enum idx); + + QT3DSU32 m_AttachmentBits; ///< holds flags for current attached buffers + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp new file mode 100644 index 00000000..50567287 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderGeometryShader.h" + +namespace qt3ds { +namespace render { + + NVRenderGeometryShader::NVRenderGeometryShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateGeometryShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderGeometryShader::~NVRenderGeometryShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseGeometryShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h new file mode 100644 index 00000000..2a643cfc --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GEOMETRY_SHADER_H +#define QT3DS_RENDER_GEOMETRY_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a vertex shader + class NVRenderGeometryShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderGeometryShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram); + + /// @brief destructor + ~NVRenderGeometryShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendGeometryShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendGeometryShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp b/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp new file mode 100644 index 00000000..e987cc31 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderImageTexture.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderImage2D::NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_Texture2D(inTexture) + , m_TextureUnit(QT3DS_MAX_U32) + , m_AccessType(inAccess) + , m_TextureLevel(0) + { + inTexture->addRef(); + } + + NVRenderImage2D::~NVRenderImage2D() + { + m_Context.ImageDestroyed(*this); + m_Texture2D->release(); + } + + void NVRenderImage2D::SetTextureLevel(QT3DSI32 inLevel) + { + if (m_Texture2D && m_Texture2D->GetNumMipmaps() >= (QT3DSU32)inLevel) { + m_TextureLevel = inLevel; + } + } + + void NVRenderImage2D::Bind(QT3DSU32 unit) + { + if (unit == -1) + m_TextureUnit = m_Context.GetNextTextureUnit(); + else + m_TextureUnit = unit; + + STextureDetails theDetails(m_Texture2D->GetTextureDetails()); + + // note it is the callers responsibility that the texture format is supported by the compute + // shader + m_Backend->BindImageTexture(m_Texture2D->GetTextureObjectHandle(), m_TextureUnit, + m_TextureLevel, false, 0, m_AccessType, theDetails.m_Format); + } + + NVRenderBackend::NVRenderBackendTextureObject NVRenderImage2D::GetTextureObjectHandle() + { + return m_Texture2D->GetTextureObjectHandle(); + } + + NVRenderImage2D *NVRenderImage2D::Create(NVRenderContextImpl &context, + NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + { + if (inTexture) + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderImage2D)(context, context.GetFoundation(), inTexture, inAccess); + else + return NULL; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderImageTexture.h b/src/Runtime/Source/render/Qt3DSRenderImageTexture.h new file mode 100644 index 00000000..8b3469b0 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderImageTexture.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H +#define QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTexture2D; + + // a wrapper class for NVRenderTexture2D + // to use with compute shaders and load / store image shaders + + class NVRenderImage2D : public NVRefCounted + { + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderTexture2D *m_Texture2D; ///< pointer to texture + QT3DSI32 m_TextureUnit; ///< texture unit this texture should use + NVRenderImageAccessType::Enum + m_AccessType; ///< texture / image access type ( read, write, read_write ) + QT3DSU32 m_TextureLevel; ///< texture level we use for this image + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] inTexture Pointer to a NVRenderTexture2D object + * @param[in] inAccess Image access type ( read, write, read_write ) + * + * @return No return. + */ + NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTexture2D *inTexture, NVRenderImageAccessType::Enum inAccess); + + virtual ~NVRenderImage2D(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Set the access rights within the shader. + * Can be read, write or read_write. + * + * @param[in] inAccess Image access type ( read, write, read_write ) + * + * @return No return. + */ + virtual void SetAccessType(NVRenderImageAccessType::Enum inAccess) + { + m_AccessType = inAccess; + } + + /** + * @brief Set the texture level we use for this image + * + * @param[in] inLevel texture level ( must be in range of max levels ) + * + * @return No return. + */ + virtual void SetTextureLevel(QT3DSI32 inLevel); + + /** + * @brief Get texture unit used + * + * + * @return texture unit bound to. + */ + virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; } + + /** + * @brief Bind a texture for shader access + * + * @param[in] unit The binding point + * + * @return No return. + */ + virtual void Bind(QT3DSU32 unit); + + /** + * @brief get the backend object handle + * here we return the handle from the wrapped texture + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle(); + + /** + * @brief static creation function + * + * @param[in] context Pointer to context + * @param[in] inTexture Pointer to a NVRenderTexture2D object + * @param[in] inAccess Image access type ( read, write, read_write ) + * + * @return No return. + */ + static NVRenderImage2D *Create(NVRenderContextImpl &context, NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp new file mode 100644 index 00000000..37f56bd2 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + NVRenderIndexBuffer::NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size, + NVRenderComponentTypes::Enum componentType, + NVRenderBufferUsageType::Enum usageType, + NVDataRef data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Index, usageType, data) + , m_ComponentType(componentType) + { + } + + NVRenderIndexBuffer::~NVRenderIndexBuffer() { m_Context.BufferDestroyed(*this); } + + QT3DSU32 NVRenderIndexBuffer::GetNumIndices() const + { + QT3DSU32 dtypeSize = NVRenderComponentTypes::getSizeofType(m_ComponentType); + return m_BufferCapacity / dtypeSize; + } + + void NVRenderIndexBuffer::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) + { + m_Backend->DrawIndexed( + drawMode, count, m_ComponentType, + (const void *)(offset * NVRenderComponentTypes::getSizeofType(m_ComponentType))); + } + + void NVRenderIndexBuffer::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) + { + m_Backend->DrawIndexedIndirect(drawMode, m_ComponentType, (const void *)offset); + } + + void NVRenderIndexBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + NVRenderIndexBuffer *NVRenderIndexBuffer::Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + NVRenderComponentTypes::Enum componentType, + size_t size, NVConstDataRef bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + if (componentType != NVRenderComponentTypes::QT3DSU32 + && componentType != NVRenderComponentTypes::QT3DSU16 + && componentType != NVRenderComponentTypes::QT3DSU8) { + qCCritical(INVALID_PARAMETER, "Invalid component type for index buffer"); + QT3DS_ASSERT(false); + return NULL; + } + + QT3DSU32 ibufSize = sizeof(NVRenderIndexBuffer); + QT3DSU8 *baseMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), ibufSize, "IndexBuffer"); + NVRenderIndexBuffer *retval = new (baseMem) NVRenderIndexBuffer( + context, size, componentType, usageType, + toDataRef(const_cast(bufferData.begin()), bufferData.size())); + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h new file mode 100644 index 00000000..6b9c4711 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_INDEX_BUFFER_H +#define QT3DS_RENDER_INDEX_BUFFER_H +#include "render/Qt3DSRenderDataBuffer.h" +#include "render/Qt3DSRenderDrawable.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + class NVRenderIndexBuffer : public NVRenderDataBuffer, public NVRenderDrawable + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] componentType Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size, + NVRenderComponentTypes::Enum componentType, + NVRenderBufferUsageType::Enum usageType, NVDataRef data); + + ///< destruvtor + ~NVRenderIndexBuffer(); + + /** + * @brief get the component type (QT3DSU8, QT3DSU16) + * + * @return the component type + */ + virtual NVRenderComponentTypes::Enum GetComponentType() const { return m_ComponentType; } + + /** + * @brief get the index count + * + * @return actual index count + */ + virtual QT3DSU32 GetNumIndices() const; + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief draw the buffer + * + * @param[in] drawMode draw mode (e.g Triangles...) + * @param[in] count vertex count + * @param[in] offset start offset in byte + * + * @return no return. + */ + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override; + + /** + * @brief draw the buffer via indirec draw buffer setup + * + * @param[in] drawMode draw mode (e.g Triangles...) + * @param[in] offset byte offset into the bound drawIndirectBuffer see + * NVRenderDrawIndirectBuffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + static NVRenderIndexBuffer *Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef bufferData); + + private: + NVRenderComponentTypes::Enum m_ComponentType; ///< component type (QT3DSU8, QT3DSU16) + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp new file mode 100644 index 00000000..e4d38b9d --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderInputAssembler.h" +#include "render/Qt3DSRenderAttribLayout.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + ///< constructor + NVRenderInputAssembler::NVRenderInputAssembler( + NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout, + NVConstDataRef buffers, const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, + NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) + : m_Context(context) + , m_Foundation(context.GetFoundation()) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_AttribLayout(attribLayout) + , m_VertexBuffers(context.GetAllocator(), "m_VertexBuffers") + , m_IndexBuffer(indexBuffer) + , m_PrimitiveType(primType) + , m_PatchVertexCount(patchVertexCount) + { + // we cannot currently attach more than 16 vertex buffers + QT3DS_ASSERT(buffers.size() < 16); + // if primitive is "Patch" we need a patch per vertex count > 0 + QT3DS_ASSERT(m_PrimitiveType != NVRenderDrawMode::Patches || m_PatchVertexCount > 1); + + QT3DSU32 entrySize = sizeof(NVRenderBackend::NVRenderBackendBufferObject) * buffers.size(); + NVRenderBackend::NVRenderBackendBufferObject *bufferHandle = + (NVRenderBackend::NVRenderBackendBufferObject *)QT3DS_ALLOC( + m_Foundation.getAllocator(), entrySize, "NVRenderInputAssembler"); + // setup vertex buffer backend handle array + QT3DS_FOREACH(idx, buffers.size()) + { + m_VertexBuffers.push_back(buffers.mData[idx]); + bufferHandle[idx] = buffers.mData[idx]->GetBuffertHandle(); + }; + + m_VertexbufferHandles = toConstDataRef(bufferHandle, buffers.size()); + + m_InputAssemblertHandle = m_Backend->CreateInputAssembler( + m_AttribLayout->GetAttribLayoutHandle(), m_VertexbufferHandles, + (m_IndexBuffer) ? m_IndexBuffer->GetBuffertHandle() : NULL, strides, offsets, + patchVertexCount); + + attribLayout->addRef(); + } + + ///< destructor + NVRenderInputAssembler::~NVRenderInputAssembler() + { + m_AttribLayout->release(); + + if (m_InputAssemblertHandle) { + m_Backend->ReleaseInputAssembler(m_InputAssemblertHandle); + } + + QT3DS_FREE(m_Foundation.getAllocator(), (void *)m_VertexbufferHandles.mData); + } + + QT3DSU32 NVRenderInputAssembler::GetIndexCount() const + { + return (m_IndexBuffer) ? m_IndexBuffer->GetNumIndices() : 0; + } + + QT3DSU32 NVRenderInputAssembler::GetVertexCount() const + { + // makes only sense if we have a single vertex buffer + QT3DS_ASSERT(m_VertexBuffers.size() == 1); + + return m_VertexBuffers[0]->GetNumVertexes(); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h new file mode 100644 index 00000000..adac4c42 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_INPUT_ASSEMBLER_H +#define QT3DS_RENDER_INPUT_ASSEMBLER_H + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + // forward declarations + class NVRenderContextImpl; + class NVRenderBackend; + class NVRenderAttribLayout; + + ///< this class handles the vertex attribute layout setup + class NVRenderInputAssembler : public NVRefCounted + { + public: + /** + * @brief constructor + * + * NOTE: The limit for buffers count is currently 16 + * + * @param[in] context Pointer to context + * @param[in] attribLayout Pointer to NVRenderAttribLayout object + * @param[in] buffers list of vertex buffers + * @param[in] indexBuffer pointer to index buffer. Can be NULL + * @param[in] strides list of strides of the buffer + * @param[in] offsets list of offsets into the buffer + * @param[in] primType primitive type used for drawing + * @param[in] patchVertexCount if primitive is "Patch" this is the vertex count for a + *single patch + * + * @return No return. + */ + NVRenderInputAssembler(NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout, + NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, + NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles, + QT3DSU32 patchVertexCount = 1); + ///< destructor + ~NVRenderInputAssembler(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendInputAssemblerObject GetInputAssemblerHandle() const + { + return m_InputAssemblertHandle; + } + + /** + * @brief get the attached index buffer + * + * @return the index buffer + */ + const NVRenderIndexBuffer *GetIndexBuffer() { return m_IndexBuffer; } + + /** + * @brief get the index count of the attached index buffer (if any) + * + * @return the index buffer count + */ + QT3DSU32 GetIndexCount() const; + + /** + * @brief get the vertex count of the buffer + * Note this makes only sense if we have a single + * interleaved buffer + * + * @return the vertex buffer count + */ + QT3DSU32 GetVertexCount() const; + + /** + * @brief get the primitive type used for drawing + * + * @return primitive type + */ + NVRenderDrawMode::Enum GetPrimitiveType() const { return m_PrimitiveType; } + + /** + * @brief set the per vertex patch count + * + * @return none + */ + void SetPatchVertexCount(QT3DSU32 count) + { + if (count != m_PatchVertexCount) { + // clamp to 1; + m_PatchVertexCount = (count == 0) ? 1 : count; + ; + m_Backend->SetPatchVertexCount(m_InputAssemblertHandle, m_PatchVertexCount); + } + } + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + + NVRenderAttribLayout *m_AttribLayout; ///< pointer to attribute layout + nvvector m_VertexBuffers; ///< vertex buffers + const NVRenderIndexBuffer *m_IndexBuffer; ///< index buffer + NVConstDataRef + m_VertexbufferHandles; ///< opaque vertex buffer backend handles + + NVRenderBackend::NVRenderBackendInputAssemblerObject + m_InputAssemblertHandle; ///< opaque backend handle + NVRenderDrawMode::Enum m_PrimitiveType; ///< primitive type used for drawing + QT3DSU32 m_PatchVertexCount; ///< vertex count if primitive type is patch + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp new file mode 100644 index 00000000..d1b62d4c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderOcclusionQuery.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + NVRenderOcclusionQuery::NVRenderOcclusionQuery(NVRenderContextImpl &context, + NVFoundationBase &fnd) + : NVRenderQueryBase(context, fnd) + { + } + + NVRenderOcclusionQuery::~NVRenderOcclusionQuery() {} + + void NVRenderOcclusionQuery::Begin() + { + m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Samples); + } + + void NVRenderOcclusionQuery::End() + { + m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Samples); + } + + void NVRenderOcclusionQuery::GetResult(QT3DSU32 *params) + { + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); + } + + bool NVRenderOcclusionQuery::GetResultAvailable() + { + QT3DSU32 param; + + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::ResultAvailable, ¶m); + + return (param == 1); + } + + NVRenderOcclusionQuery *NVRenderOcclusionQuery::Create(NVRenderContextImpl &context) + { + if (!context.IsSampleQuerySupported()) + return NULL; + + NVRenderOcclusionQuery *retval = + QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderOcclusionQuery)(context, context.GetFoundation()); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h new file mode 100644 index 00000000..04f64e97 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_OCCLUSION_QUERY_H +#define QT3DS_RENDER_OCCLUSION_QUERY_H + +#include "render/Qt3DSRenderQueryBase.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + class NVRenderOcclusionQuery : public NVRenderQueryBase + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderOcclusionQuery(NVRenderContextImpl &context, NVFoundationBase &fnd); + + ///< destructor + ~NVRenderOcclusionQuery(); + + /** + * @brief Get query type + * + * @return Return query type + */ + NVRenderQueryType::Enum GetQueryType() const override + { + return NVRenderQueryType::Samples; + } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief begin a query + * + * @return no return. + */ + void Begin() override; + + /** + * @brief end a query + * + * @return no return. + */ + void End() override; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + void GetResult(QT3DSU32 *params) override; + + /** + * @brief query if a result is available + * + * + * @return true if available. + */ + virtual bool GetResultAvailable(); + + /* + * @brief static creation function + * + * * @return a occlusion query object on success + */ + static NVRenderOcclusionQuery *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp new file mode 100644 index 00000000..3e9276aa --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderPathFontSpecification.h" +#include "render/Qt3DSRenderPathFontText.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderPathFontSpecification::NVRenderPathFontSpecification(NVRenderContextImpl &context, + NVFoundationBase &fnd, + CRegisteredString fontName) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_NumFontGlyphs(0) + , m_EmScale(2048) // 2048 is default true type scale + , m_Type(NVRenderPathFormatType::UByte) + , m_TransformType(NVRenderPathTransformType::Translate2D) + , m_FontName(fontName) + { + } + + NVRenderPathFontSpecification::~NVRenderPathFontSpecification() + { + m_Context.ReleasePathFontSpecification(*this); + } + + void NVRenderPathFontSpecification::LoadPathGlyphs(const char *fontName, + NVRenderPathFormatType::Enum type) + { + // check if we already created it + if (m_NumFontGlyphs) + return; + + m_Type = type; + + // create fonts based on the input + m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::FileFont, fontName, NVRenderPathFontStyleFlags(), 0, m_EmScale, + &m_NumFontGlyphs); + + // Fallback in case the previuos call fails + // This is a no-op if the previous call succeeds + // Note that sans is an inbuild driver font + if (!m_PathRenderHandle) { + m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::SystemFont, "Arial", NVRenderPathFontStyleFlags(), 0, + m_EmScale, &m_NumFontGlyphs); + } + + // we should have some glyphs + QT3DS_ASSERT(m_NumFontGlyphs); + } + + void + NVRenderPathFontSpecification::StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem) + { + const void *glyphIDs = inPathFontItem.GetGlyphIDs(); + const QT3DSF32 *spacing = inPathFontItem.GetSpacing(); + if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) { + QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount()); + return; + } + + m_Backend->StencilFillPathInstanced(m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), + m_Type, glyphIDs, NVRenderPathFillMode::Fill, 0xFF, + m_TransformType, spacing); + } + + void NVRenderPathFontSpecification::CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem) + { + const void *glyphIDs = inPathFontItem.GetGlyphIDs(); + const QT3DSF32 *spacing = inPathFontItem.GetSpacing(); + if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) { + QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount()); + return; + } + + m_Backend->CoverFillPathInstanced( + m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), m_Type, glyphIDs, + NVRenderPathCoverMode::BoundingBoxOfBoundingBox, m_TransformType, spacing); + } + + QT3DSU32 + NVRenderPathFontSpecification::getSizeofType(NVRenderPathFormatType::Enum type) + { + switch (type) { + case NVRenderPathFormatType::Byte: + return sizeof(QT3DSI8); + case NVRenderPathFormatType::UByte: + return sizeof(QT3DSU8); + case NVRenderPathFormatType::Bytes2: + return sizeof(QT3DSU16); + case NVRenderPathFormatType::Uint: + return sizeof(QT3DSU32); + case NVRenderPathFormatType::Utf8: + return sizeof(QT3DSU32); + default: + QT3DS_ASSERT(false); + return 1; + } + } + + NVRenderPathFontSpecification * + NVRenderPathFontSpecification::CreatePathFontSpecification(NVRenderContextImpl &context, + CRegisteredString fontName) + { + QT3DS_ASSERT(context.IsPathRenderingSupported()); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathFontSpecification)(context, context.GetFoundation(), fontName); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h new file mode 100644 index 00000000..dad3f6bb --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #pragma once +#ifndef QT3DS_RENDER_PATH_FONT_SPECIFICATION_H +#define QT3DS_RENDER_PATH_FONT_SPECIFICATION_H +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/StringTable.h" +#include "EASTL/string.h" +#include "render/backends/Qt3DSRenderBackend.h" + + namespace qt3ds +{ + namespace render { + + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderPathRender; + class NVRenderPathFontItem; + + class NVRenderPathFontSpecification : public NVRefCounted + { + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 + mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] fontName Name of font ( may include path + * ) + * + * @return No return. + */ + NVRenderPathFontSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd, + CRegisteredString fontName); + + /// @NVRenderPathSpecification destructor + ~NVRenderPathFontSpecification(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Load numGlyphs glyphs from specified font file + * + * @param[in] pathBase Base of path objects + * @param[in] fontName Name of font ( may include path + * ) + * @param[in] numGlyphs Glyph count + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes character string + * + * @return No return + */ + virtual void LoadPathGlyphs(const char *fontName, NVRenderPathFormatType::Enum type); + + /** + * @brief Render a stencil fill pass for fonts + * + * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification + * + * @return no return + */ + void StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem); + + /** + * @brief Render a cover fill pass for fonts + * + * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification + * + * @return no return + */ + void CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem); + + /** + * @brief get type for font path set + * + * @return path font type + */ + NVRenderPathFormatType::Enum GetPathFontType() { return m_Type; } + + /** + * @brief get font glyph count + * + * @return get glyph count + */ + QT3DSU32 GetFontGlyphsCount() { return m_NumFontGlyphs; } + + /** + * @brief get spacing for char set + * + * @return spacing array + */ + QT3DSF32 GetEmScale() const { return m_EmScale; } + + /** + * @brief Get font name + * + * @return name set + */ + CRegisteredString GetFontName() const { return m_FontName; } + + private: + QT3DSU32 m_NumFontGlyphs; ///< glyph count of the entire font set + QT3DSF32 m_EmScale; ///< true type scale + NVRenderPathFormatType::Enum m_Type; ///< type ( byte, int,... ) + NVRenderPathTransformType::Enum m_TransformType; ///< transform type default 2D + CRegisteredString m_FontName; ///< Name of Font + NVRenderBackend::NVRenderBackendPathObject + m_PathRenderHandle; ///< opaque backend handle + + private: + /** + * @brief Get size of type + * + * @param[in] type type ( byte, int,... ) + * + * @return true if successful + */ + QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type); + + public: + static NVRenderPathFontSpecification * + CreatePathFontSpecification(NVRenderContextImpl &context, CRegisteredString fontName); + }; + } +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp b/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp new file mode 100644 index 00000000..aeaad13c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderPathFontText.h" +#include "render/Qt3DSRenderPathFontSpecification.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderPathRender.h" + +namespace qt3ds { +namespace render { + + // see NVprSDK for explanation + // Math from page 54-56 of "Digital Image Warping" by George Wolberg, + // though credited to Paul Heckert's "Fundamentals of Texture + // Mapping and Image Warping" 1989 Master's thesis. + static QT3DSMat33 mapSquareToQuad(QT3DSVec2 inSquare[4]) + { + QT3DSMat33 ret; + + QT3DSVec2 d1(inSquare[1] - inSquare[2]); + QT3DSVec2 d2(inSquare[3] - inSquare[2]); + QT3DSVec2 d3(inSquare[0] - inSquare[1] + inSquare[2] - inSquare[3]); + + QT3DSF32 denom = d1.x * d2.y - d2.x * d1.y; + if (denom == 0.0) { + return QT3DSMat33::createIdentity(); + } + + ret[2][0] = (d3.x * d2.y - d2.x * d3.y) / denom; + ret[2][1] = (d1.x * d3.y - d3.x * d1.y) / denom; + ret[2][2] = 1.0; + ret[0][0] = inSquare[1].x - inSquare[0].x + ret[2][0] * inSquare[1].x; + ret[1][0] = inSquare[1].y - inSquare[0].y + ret[2][0] * inSquare[1].y; + ret[0][1] = inSquare[3].x - inSquare[0].x + ret[2][1] * inSquare[3].x; + ret[1][1] = inSquare[3].y - inSquare[0].y + ret[2][1] * inSquare[3].y; + ret[0][2] = inSquare[0].x; + ret[1][2] = inSquare[0].y; + + return ret; + } + + static QT3DSMat33 mapQuadToSquare(QT3DSVec2 inSquare[4]) + { + return mapSquareToQuad(inSquare).getInverse(); + } + + static QT3DSMat33 mapQuadToQuad(QT3DSVec2 fromSquare[4], QT3DSVec2 toSquare[4]) + { + return (mapSquareToQuad(toSquare) * mapQuadToSquare(fromSquare)); + } + + static QT3DSMat44 mapBoxToQuad(QT3DSVec4 inBox, QT3DSVec2 inSquare[4]) + { + QT3DSVec2 fromSquare[4] = { QT3DSVec2(inBox.x, inBox.y), QT3DSVec2(inBox.z, inBox.y), + QT3DSVec2(inBox.z, inBox.w), QT3DSVec2(inBox.x, inBox.w) }; + + QT3DSMat33 ret = mapQuadToQuad(fromSquare, inSquare); + + return QT3DSMat44(ret.column0, ret.column1, ret.column2, QT3DSVec3(0.0, 0.0, 0.0)); + } + + NVRenderPathFontItem::NVRenderPathFontItem(NVFoundationBase &fnd) + : m_Foundation(fnd) + , mRefCount(0) + , m_NumGlyphs(0) + , m_GlyphIDs(NULL) + , m_TranslateXY(NULL) + { + } + + NVRenderPathFontItem::~NVRenderPathFontItem() + { + if (m_TranslateXY) + QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY); + if (m_GlyphIDs) + QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs); + } + + void NVRenderPathFontItem::InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs, + NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, + QT3DSVec2 pixelBound, QT3DSVec2 logicalBound, QT3DSF32 emScale) + { + m_NumGlyphs = glyphCount; + + // allocate glyphs array + if (m_GlyphIDs) + QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs); + + // allocate position array + if (m_TranslateXY) + QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY); + + m_GlyphIDs = (QT3DSU32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), + glyphCount * getSizeofType(type), "NVRenderPathFontItem"); + m_TranslateXY = + (QT3DSF32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), 2 * (glyphCount + 1) * sizeof(QT3DSF32), + "NVRenderPathFontItem"); + + if (!m_GlyphIDs || !m_TranslateXY) + return; + + QT3DSU32 *pTheGlyphIDs = (QT3DSU32 *)m_GlyphIDs; + QT3DSU32 *pInGlyphs = (QT3DSU32 *)glyphIDs; + + /// copy glyphs array + for (size_t i = 0; i < glyphCount; i++) { + pTheGlyphIDs[i] = pInGlyphs[i]; + } + + // copy position array + // we copy what we got from our layout system + if (posArray != NULL) { + for (size_t i = 0, k = 0; i < glyphCount * 2; i += 2, k++) { + m_TranslateXY[i] = posArray[i] * emScale; + m_TranslateXY[i + 1] = posArray[i + 1] * emScale; + } + } + + // setup transform + QT3DSVec2 square[4] = { QT3DSVec2(0.0, 0.0), QT3DSVec2(pixelBound.x, 0.0), + QT3DSVec2(pixelBound.x, pixelBound.y), QT3DSVec2(0.0, pixelBound.y) }; + QT3DSVec4 box(0.0, 0.0, logicalBound.x * emScale, logicalBound.y * emScale); + + m_ModelMatrix = mapBoxToQuad(box, square); + } + + const QT3DSMat44 NVRenderPathFontItem::GetTransform() + { + return QT3DSMat44(QT3DSVec4(m_ModelMatrix[0][0], m_ModelMatrix[1][0], 0.0, m_ModelMatrix[2][0]), + QT3DSVec4(m_ModelMatrix[0][1], m_ModelMatrix[1][1], 0.0, m_ModelMatrix[2][1]), + QT3DSVec4(0.0, 0.0, 1.0, 0.0), + QT3DSVec4(m_ModelMatrix[0][2], m_ModelMatrix[1][2], 0.0, m_ModelMatrix[2][2])); + } + + QT3DSU32 + NVRenderPathFontItem::getSizeofType(NVRenderPathFormatType::Enum type) + { + switch (type) { + case NVRenderPathFormatType::Byte: + return sizeof(QT3DSI8); + case NVRenderPathFormatType::UByte: + return sizeof(QT3DSU8); + case NVRenderPathFormatType::Bytes2: + return sizeof(QT3DSU16); + case NVRenderPathFormatType::Uint: + return sizeof(QT3DSU32); + case NVRenderPathFormatType::Utf8: + return sizeof(QT3DSU32); + default: + QT3DS_ASSERT(false); + return 1; + } + } + + NVRenderPathFontItem *NVRenderPathFontItem::CreatePathFontItem(NVRenderContextImpl &context) + { + QT3DS_ASSERT(context.IsPathRenderingSupported()); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathFontItem)(context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontText.h b/src/Runtime/Source/render/Qt3DSRenderPathFontText.h new file mode 100644 index 00000000..a1d103ac --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontText.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #pragma once +#ifndef QT3DS_RENDER_PATH_FONT_TEXT_H +#define QT3DS_RENDER_PATH_FONT_TEXT_H +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "EASTL/string.h" +#include "render/backends/Qt3DSRenderBackend.h" + + namespace qt3ds +{ + namespace render { + + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderPathFontSpecification; + + class NVRenderPathFontItem : public NVRefCounted + { + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 + mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderPathFontItem(NVFoundationBase &fnd); + + /// @NVRenderPathFontItem destructor + ~NVRenderPathFontItem(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Setup text + * + * @param[in] glyphCount number of glyphs + * @param[in] glyphIDs array of glyhp ID's + * @param[in] type type ( byte, int,... ) + * @param[in] posArray array of glyhp positions + * @param[in] pixelBound pixel boundary + * @param[in] logicalBound logical boundary + * @param[in] emScale true type scale + * + * @return No return. + */ + void InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs, + NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, QT3DSVec2 pixelBound, + QT3DSVec2 logicalBound, QT3DSF32 emScale); + + /** + * @brief get glyph count + * + * @return get glyph count + */ + size_t GetGlyphsCount() { return m_NumGlyphs; } + + /** + * @brief get spacing for char set + * + * @return spacing array + */ + const QT3DSF32 *GetSpacing() { return m_TranslateXY; } + + /** + * @brief get name set + * + * @return name set + */ + const void *GetGlyphIDs() { return (void *)m_GlyphIDs; } + + /** + * @brief Get Y bound of font metric + * + * @return transform matrix + */ + const QT3DSMat44 GetTransform(); + + private: + /** + * @brief Get size of type + * + * @param[in] type type ( byte, int,... ) + * + * @return true if successful + */ + QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type); + + private: + size_t m_NumGlyphs; ///< glyph count + QT3DSU32 *m_GlyphIDs; ///< array glyph ID's + QT3DSF32 * + m_TranslateXY; ///< pointer to arrray for character advance information like kerning + QT3DSMat44 m_ModelMatrix; ///< Matrix which converts from font space to box space + + public: + static NVRenderPathFontItem *CreatePathFontItem(NVRenderContextImpl &context); + }; + } +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp b/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp new file mode 100644 index 00000000..42982498 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderPathRender.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderPathSpecification.h" +#include "render/Qt3DSRenderPathFontSpecification.h" + +namespace qt3ds { +namespace render { + + NVRenderPathRender::NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, + size_t range) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_StrokeWidth(0.0f) + { + m_Range = range; + m_PathRenderHandle = m_Backend->CreatePathNVObject(range); + } + + NVRenderPathRender::~NVRenderPathRender() + { + if (m_PathRenderHandle) { + m_Backend->ReleasePathNVObject(m_PathRenderHandle, m_Range); + } + } + + void NVRenderPathRender::SetPathSpecification(NVRenderPathSpecification &inCommandBuffer) + { + m_Backend->SetPathSpecification(m_PathRenderHandle, inCommandBuffer.GetPathCommands(), + inCommandBuffer.GetPathCoords()); + } + + NVBounds3 NVRenderPathRender::GetPathObjectBoundingBox() + { + return m_Backend->GetPathObjectBoundingBox(m_PathRenderHandle); + } + + NVBounds3 NVRenderPathRender::GetPathObjectFillBox() + { + return m_Backend->GetPathObjectFillBox(m_PathRenderHandle); + } + + NVBounds3 NVRenderPathRender::GetPathObjectStrokeBox() + { + return m_Backend->GetPathObjectStrokeBox(m_PathRenderHandle); + } + + void NVRenderPathRender::SetStrokeWidth(QT3DSF32 inStrokeWidth) + { + if (inStrokeWidth != m_StrokeWidth) { + m_StrokeWidth = inStrokeWidth; + m_Backend->SetStrokeWidth(m_PathRenderHandle, inStrokeWidth); + } + } + + QT3DSF32 NVRenderPathRender::GetStrokeWidth() const { return m_StrokeWidth; } + + void NVRenderPathRender::StencilStroke() { m_Backend->StencilStrokePath(m_PathRenderHandle); } + + void NVRenderPathRender::StencilFill() { m_Backend->StencilFillPath(m_PathRenderHandle); } + + NVRenderPathRender *NVRenderPathRender::Create(NVRenderContextImpl &context, size_t range) + { + if (!context.IsPathRenderingSupported()) + return NULL; + + NVRenderPathRender *retval = + QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathRender)(context, context.GetFoundation(), range); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathRender.h b/src/Runtime/Source/render/Qt3DSRenderPathRender.h new file mode 100644 index 00000000..c261ca31 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathRender.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_RENDER_H +#define QT3DS_RENDER_PATH_RENDER_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "foundation/Qt3DSBounds3.h" +#include + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderPathSpecification; + class NVRenderPathFontSpecification; + + ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....) + class NVRenderPathRender : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] range Number of internal objects + * + * @return No return. + */ + NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t range); + + /// @brief destructor + ~NVRenderPathRender(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendPathObject GetPathHandle() { return m_PathRenderHandle; } + + // The render context can create a path specification object. + void SetPathSpecification(NVRenderPathSpecification &inCommandBuffer); + + NVBounds3 GetPathObjectBoundingBox(); + NVBounds3 GetPathObjectFillBox(); + NVBounds3 GetPathObjectStrokeBox(); + + void SetStrokeWidth(QT3DSF32 inStrokeWidth); + QT3DSF32 GetStrokeWidth() const; + + void StencilStroke(); + void StencilFill(); + + /** + * @brief static create function + * + * @param[in] context Pointer to render context + * @param[in] range Number of internal objects + * + * @return the backend object handle. + */ + static NVRenderPathRender *Create(NVRenderContextImpl &context, size_t range); + + private: + NVRenderBackend::NVRenderBackendPathObject m_PathRenderHandle; ///< opaque backend handle + size_t m_Range; ///< range of internal objects + QT3DSF32 m_StrokeWidth; + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp new file mode 100644 index 00000000..f4b26f11 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderPathSpecification.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderPathSpecification::NVRenderPathSpecification(NVRenderContextImpl &context, + NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_PathCommands(fnd.getAllocator(), "m_PathCommands") + , m_PathCoords(fnd.getAllocator(), "m_PathCoords") + { + } + + NVRenderPathSpecification::~NVRenderPathSpecification() {} + + void NVRenderPathSpecification::Reset() + { + m_PathCommands.clear(); + m_PathCoords.clear(); + } + + void NVRenderPathSpecification::P(QT3DSVec2 inData) + { + m_PathCoords.push_back(inData.x); + m_PathCoords.push_back(inData.y); + } + + void NVRenderPathSpecification::MoveTo(QT3DSVec2 inPoint) + { + // we should actually query the backend for command converesion + // but will we support any other pather render system than nv path? + StaticAssert::valid_expression(); + + m_PathCommands.push_back(NVRenderPathCommands::MoveTo); + P(inPoint); + } + + void NVRenderPathSpecification::CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest) + { + // we should actually query the backend for command converesion + // but will we support any other pather render system than nv path? + StaticAssert::valid_expression(); + + m_PathCommands.push_back(NVRenderPathCommands::CubicCurveTo); + P(inC1); + P(inC2); + P(inDest); + } + + void NVRenderPathSpecification::ClosePath() + { + // we should actually query the backend for command converesion + // but will we support any other pather render system than nv path? + StaticAssert::valid_expression(); + + m_PathCommands.push_back(NVRenderPathCommands::Close); + } + + NVRenderPathSpecification * + NVRenderPathSpecification::CreatePathSpecification(NVRenderContextImpl &context) + { + QT3DS_ASSERT(context.IsPathRenderingSupported()); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathSpecification)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h new file mode 100644 index 00000000..7c6faeda --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_SPECIFICATION_H +#define QT3DS_RENDER_PATH_SPECIFICATION_H +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + class NVRenderContextImpl; + + class NVRenderPathSpecification : public NVRefCounted + { + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderPathSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd); + + /// @NVRenderPathSpecification destructor + ~NVRenderPathSpecification(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief reset commands and coordiantes + * + * @return No return. + */ + virtual void Reset(); + + /** + * @brief add new move to command + * + * @param[in] inPoint Coordinate + * + * @return No return. + */ + virtual void MoveTo(QT3DSVec2 inPoint); + + /** + * @brief add new cubic curve command + * + * @param[in] inC1 control point 1 + * @param[in] inC2 control point 2 + * @param[in] inDest final point + * + * @return No return. + */ + virtual void CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest); + + /** + * @brief add new close command + * + * + * @return No return. + */ + virtual void ClosePath(); + + /** + * @brief Get path command list + * + * + * @return path commands + */ + virtual NVConstDataRef GetPathCommands() { return m_PathCommands; } + + /** + * @brief Get path coordinates list + * + * + * @return path coordinates + */ + virtual NVConstDataRef GetPathCoords() { return m_PathCoords; } + + private: + nvvector m_PathCommands; + nvvector m_PathCoords; + + /** + * @brief add a new point to the coordinates + * + * @param[in] inPoint Coordinate + * + * @return No return. + */ + void P(QT3DSVec2 inData); + + public: + static NVRenderPathSpecification *CreatePathSpecification(NVRenderContextImpl &context); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp new file mode 100644 index 00000000..b0a9f271 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderProgramPipeline.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + NVRenderProgramPipeline::NVRenderProgramPipeline(NVRenderContextImpl &context, + NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_Program(NULL) + , m_VertexProgram(NULL) + , m_FragmentProgram(NULL) + , m_TessControlProgram(NULL) + , m_TessEvalProgram(NULL) + , m_GeometryProgram(NULL) + , m_ComputProgram(NULL) + { + m_ProgramPipelineHandle = m_Backend->CreateProgramPipeline(); + } + + NVRenderProgramPipeline::~NVRenderProgramPipeline() + { + if (m_ProgramPipelineHandle) { + m_Backend->ReleaseProgramPipeline(m_ProgramPipelineHandle); + } + + if (m_VertexProgram) + m_VertexProgram->release(); + if (m_FragmentProgram) + m_FragmentProgram->release(); + if (m_TessControlProgram) + m_TessControlProgram->release(); + if (m_TessEvalProgram) + m_TessEvalProgram->release(); + if (m_GeometryProgram) + m_GeometryProgram->release(); + } + + bool NVRenderProgramPipeline::IsValid() { return (m_ProgramPipelineHandle != NULL); } + + void NVRenderProgramPipeline::SetProgramStages(NVRenderShaderProgram *inProgram, + NVRenderShaderTypeFlags flags) + { + bool bDirty = false; + + if (flags & NVRenderShaderTypeValue::Vertex && inProgram != m_VertexProgram) { + if (m_VertexProgram) + m_VertexProgram->release(); + if (inProgram) + inProgram->addRef(); + m_VertexProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::Fragment && inProgram != m_FragmentProgram) { + if (m_FragmentProgram) + m_FragmentProgram->release(); + if (inProgram) + inProgram->addRef(); + m_FragmentProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::TessControl && inProgram != m_TessControlProgram) { + if (m_TessControlProgram) + m_TessControlProgram->release(); + if (inProgram) + inProgram->addRef(); + m_TessControlProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::TessEvaluation && inProgram != m_TessEvalProgram) { + if (m_TessEvalProgram) + m_TessEvalProgram->release(); + if (inProgram) + inProgram->addRef(); + m_TessEvalProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::Geometry && inProgram != m_GeometryProgram) { + if (m_GeometryProgram) + m_GeometryProgram->release(); + if (inProgram) + inProgram->addRef(); + m_GeometryProgram = inProgram; + bDirty = true; + } + + if (bDirty) { + m_Backend->SetProgramStages(m_ProgramPipelineHandle, flags, + (inProgram) ? inProgram->GetShaderProgramHandle() : NULL); + } + } + + void NVRenderProgramPipeline::Bind() + { + m_Backend->SetActiveProgramPipeline(m_ProgramPipelineHandle); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h new file mode 100644 index 00000000..ce47146a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PROGRAM_PIPLINE_H +#define QT3DS_RENDER_PROGRAM_PIPLINE_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderContext.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderShaderProgram; + + ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....) + class QT3DS_AUTOTEST_EXPORT NVRenderProgramPipeline : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderProgramPipeline(NVRenderContextImpl &context, NVFoundationBase &fnd); + + /// @brief destructor + ~NVRenderProgramPipeline(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Query if pipeline is valid + * + * @return True if valid. + */ + bool IsValid(); + + /** + * @brief enable / disable a program stage in the pipeline + * + * @param[in] pProgram Pointer to program. If NULL stage will be disabled + * @param[in] flags Flags to which stage this program is bound to. Can more than + * one stage + * + * @return no return. + */ + void SetProgramStages(NVRenderShaderProgram *pProgram, NVRenderShaderTypeFlags flags); + + /** + * @brief Make the program pipeline active + * + * @return True if valid. + */ + void Bind(); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendProgramPipeline GetShaderHandle() + { + return m_ProgramPipelineHandle; + } + + /** + * @brief get the vertex stage program + * + * @return the backend object handle. + */ + NVRenderShaderProgram *GetVertexStage() { return m_VertexProgram; } + + private: + NVRenderBackend::NVRenderBackendProgramPipeline + m_ProgramPipelineHandle; ///< opaque backend handle + + NVRenderShaderProgram + *m_Program; ///< for non separable programs this contains the entire program + NVRenderShaderProgram + *m_VertexProgram; ///< for separable programs this contains the vertex program + NVRenderShaderProgram + *m_FragmentProgram; ///< for separable programs this contains the fragment program + NVRenderShaderProgram *m_TessControlProgram; ///< for separable programs this contains the + ///tessellation control program + NVRenderShaderProgram *m_TessEvalProgram; ///< for separable programs this contains the + ///tessellation evaluation program + NVRenderShaderProgram + *m_GeometryProgram; ///< for separable programs this contains the geometry program + NVRenderShaderProgram + *m_ComputProgram; ///< for separable programs this contains the compute program + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp b/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp new file mode 100644 index 00000000..f13bc499 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderQueryBase.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderQueryBase::NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + { + m_QueryHandle = m_Backend->CreateQuery(); + } + + NVRenderQueryBase::~NVRenderQueryBase() + { + if (m_QueryHandle) + m_Backend->ReleaseQuery(m_QueryHandle); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderQueryBase.h b/src/Runtime/Source/render/Qt3DSRenderQueryBase.h new file mode 100644 index 00000000..7a7ead87 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderQueryBase.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QUERY_BASE_H +#define QT3DS_RENDER_QUERY_BASE_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + class NVRenderBackend; + + ///< Base class + class NVRenderQueryBase : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendQueryObject m_QueryHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd); + + virtual ~NVRenderQueryBase(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Get query type + * + * @return Return query type + */ + virtual NVRenderQueryType::Enum GetQueryType() const = 0; + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief begin a query + * + * @return no return. + */ + virtual void Begin() = 0; + + /** + * @brief end a query + * + * @return no return. + */ + virtual void End() = 0; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + virtual void GetResult(QT3DSU32 *params) = 0; + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendQueryObject GetQuerytHandle() const + { + return m_QueryHandle; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp new file mode 100644 index 00000000..e7daf7f4 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderRasterizerState.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderRasterizerState::NVRenderRasterizerState(NVRenderContextImpl &context, + NVFoundationBase &fnd, QT3DSF32 depthBias, + QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + { + // create backend handle + m_StateHandle = m_Backend->CreateRasterizerState(depthBias, depthScale, cullFace); + } + + NVRenderRasterizerState::~NVRenderRasterizerState() + { + if (m_StateHandle) { + m_Backend->ReleaseRasterizerState(m_StateHandle); + m_Context.StateDestroyed(*this); + } + } + + NVRenderRasterizerState *NVRenderRasterizerState::Create(NVRenderContextImpl &context, + QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderRasterizerState)( + context, context.GetFoundation(), depthBias, depthScale, cullFace); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h new file mode 100644 index 00000000..9b71ae42 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RASTERIZER_STATE_H +#define QT3DS_RENDER_RASTERIZER_STATE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + + // currently this handles only stencil state + class NVRenderRasterizerState : public NVRefCounted + { + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendRasterizerStateObject + m_StateHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] depthBias depth bias + * @param[in] depthScale depth multiplicator + * @param[in] cullFace which face to cull front or back + * + * @return No return. + */ + NVRenderRasterizerState(NVRenderContextImpl &context, NVFoundationBase &fnd, + QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace); + + virtual ~NVRenderRasterizerState(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendRasterizerStateObject GetRasterizerObjectHandle() + { + return m_StateHandle; + } + + static NVRenderRasterizerState *Create(NVRenderContextImpl &context, QT3DSF32 depthBias, + QT3DSF32 depthScale, NVRenderFaces::Enum cullFace); + + private: + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp new file mode 100644 index 00000000..b682bc1b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderRenderBuffer::NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderRenderBufferFormats::Enum format, + QT3DSU32 width, QT3DSU32 height) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_Width(width) + , m_Height(height) + , m_StorageFormat(format) + , m_BufferHandle(NULL) + { + SetDimensions(NVRenderRenderBufferDimensions(width, height)); + } + + NVRenderRenderBuffer::~NVRenderRenderBuffer() + { + m_Context.RenderBufferDestroyed(*this); + m_Backend->ReleaseRenderbuffer(m_BufferHandle); + m_BufferHandle = 0; + } + + void NVRenderRenderBuffer::SetDimensions(const NVRenderRenderBufferDimensions &inDimensions) + { + QT3DSU32 maxWidth, maxHeight; + m_Width = inDimensions.m_Width; + m_Height = inDimensions.m_Height; + + // get max size and clamp to max value + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (m_Width > maxWidth || m_Height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + m_Width = NVMin(m_Width, maxWidth); + m_Height = NVMin(m_Height, maxHeight); + } + + bool success = true; + + if (m_BufferHandle == NULL) + m_BufferHandle = m_Backend->CreateRenderbuffer(m_StorageFormat, m_Width, m_Height); + else + success = + m_Backend->ResizeRenderbuffer(m_BufferHandle, m_StorageFormat, m_Width, m_Height); + + if (m_BufferHandle == NULL || !success) { + // We could try smaller sizes + QT3DS_ASSERT(false); + qCCritical(INTERNAL_ERROR, "Unable to create render buffer %s, %dx%d", + NVRenderRenderBufferFormats::toString(m_StorageFormat), m_Width, + m_Height); + } + } +} +} + +qt3ds::render::NVRenderRenderBuffer * +qt3ds::render::NVRenderRenderBuffer::Create(NVRenderContextImpl &context, + NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, + QT3DSU32 height) +{ + NVRenderRenderBuffer *retval = NULL; + if (width == 0 || height == 0) { + qCCritical(INVALID_PARAMETER, "Invalid renderbuffer width or height"); + return retval; + } + + retval = QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderRenderBuffer)(context, context.GetFoundation(), format, width, height); + + return retval; +} diff --git a/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h new file mode 100644 index 00000000..41f4068a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + class NVRenderContextImpl; + + struct NVRenderRenderBufferDimensions + { + QT3DSU32 m_Width; ///< buffer width + QT3DSU32 m_Height; ///< buffer height + + NVRenderRenderBufferDimensions(QT3DSU32 w, QT3DSU32 h) + : m_Width(w) + , m_Height(h) + { + } + NVRenderRenderBufferDimensions() + : m_Width(0) + , m_Height(0) + { + } + }; + + class NVRenderRenderBuffer : public NVRefCounted, public NVRenderImplemented + { + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + QT3DSU32 m_Width; ///< buffer width + QT3DSU32 m_Height; ///< buffer height + NVRenderRenderBufferFormats::Enum m_StorageFormat; ///< buffer storage format + + NVRenderBackend::NVRenderBackendRenderbufferObject + m_BufferHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] format Renderbuffer format + * @param[in] width Renderbuffer width + * @param[in] height Renderbuffer height + * + * @return No return. + */ + NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, QT3DSU32 height); + + /// destructor + virtual ~NVRenderRenderBuffer(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + /** + * @brief query buffer format + * + * + * @return buffer format + */ + virtual NVRenderRenderBufferFormats::Enum GetStorageFormat() const + { + return m_StorageFormat; + } + + /** + * @brief query buffer dimension + * + * + * @return NVRenderRenderBufferDimensions object + */ + virtual NVRenderRenderBufferDimensions GetDimensions() const + { + return NVRenderRenderBufferDimensions(m_Width, m_Height); + } + + /** + * @brief constructor + * + * @param[in] inDimensions A dimension object + * + * @return buffer format + */ + virtual void SetDimensions(const NVRenderRenderBufferDimensions &inDimensions); + + /** + * @brief static creator function + * + * @param[in] context Pointer to context + * @param[in] format Renderbuffer format + * @param[in] width Renderbuffer width + * @param[in] height Renderbuffer height + * + * @return No return. + */ + static NVRenderRenderBuffer *Create(NVRenderContextImpl &context, + NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, + QT3DSU32 height); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendRenderbufferObject GetRenderBuffertHandle() + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderSampler.cpp b/src/Runtime/Source/render/Qt3DSRenderSampler.cpp new file mode 100644 index 00000000..b02fc615 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSampler.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSDataRef.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" + +namespace qt3ds { +namespace render { + + NVRenderTextureSampler::NVRenderTextureSampler( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, NVRenderTextureSwizzleMode::Enum swizzleMode, + QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, NVRenderTextureCompareMode::Enum compareMode, + NVRenderTextureCompareOp::Enum compareFunc, QT3DSF32 anisotropy, QT3DSF32 *borderColor) + : m_MinFilter(minFilter) + , m_MagFilter(magFilter) + , m_WrapS(wrapS) + , m_WrapT(wrapT) + , m_WrapR(wrapR) + , m_SwizzleMode(swizzleMode) + , m_MinLod(minLod) + , m_MaxLod(maxLod) + , m_LodBias(lodBias) + , m_CompareMode(compareMode) + , m_CompareOp(compareFunc) + , m_Anisotropy(anisotropy) + , m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_SamplerHandle(NULL) + { + // create backend handle + m_SamplerHandle = m_Backend->CreateSampler(); + + if (borderColor) { + m_BorderColor[0] = borderColor[0]; + m_BorderColor[1] = borderColor[1]; + m_BorderColor[2] = borderColor[2]; + m_BorderColor[3] = borderColor[3]; + } + } + + NVRenderTextureSampler::~NVRenderTextureSampler() + { + if (m_SamplerHandle) + m_Backend->ReleaseSampler(m_SamplerHandle); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderSampler.h b/src/Runtime/Source/render/Qt3DSRenderSampler.h new file mode 100644 index 00000000..77d3f008 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSampler.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H +#define QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + + class NVRenderTextureSampler + { + public: + NVRenderTextureMinifyingOp::Enum m_MinFilter; + NVRenderTextureMagnifyingOp::Enum m_MagFilter; + NVRenderTextureCoordOp::Enum m_WrapS; + NVRenderTextureCoordOp::Enum m_WrapT; + NVRenderTextureCoordOp::Enum m_WrapR; + NVRenderTextureSwizzleMode::Enum m_SwizzleMode; + QT3DSF32 m_MinLod; + QT3DSF32 m_MaxLod; + QT3DSF32 m_LodBias; + NVRenderTextureCompareMode::Enum m_CompareMode; + NVRenderTextureCompareOp::Enum m_CompareOp; + QT3DSF32 m_Anisotropy; + QT3DSF32 m_BorderColor[4]; + + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] swizzleMode Texture swizzle mode + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail bias (unused) + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] (unused) + * + * @return No return. + */ + NVRenderTextureSampler( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL); + + /** + * @brief destructor + * + */ + virtual ~NVRenderTextureSampler(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendSamplerObject GetSamplerHandle() const + { + return m_SamplerHandle; + } + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendSamplerObject m_SamplerHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderShader.h b/src/Runtime/Source/render/Qt3DSRenderShader.h new file mode 100644 index 00000000..8d0a62c4 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShader.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_H +#define QT3DS_RENDER_SHADER_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderContext.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< A shader program is an object composed of a multiple shaders (vertex, fragment, + ///geometry,....) + class NVRenderShader + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + NVConstDataRef m_Source; ///< shader source code + bool m_Binary; ///< true for binary programs + eastl::string m_ErrorMessage; ///< contains the error message if linking fails + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , m_Source(source) + , m_Binary(binaryProgram) + { + } + + /// @brief destructor + ~NVRenderShader(){} + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + virtual bool IsValid() = 0; + + /** + * @brief Get Error Message + * + * @param[out] messageLength Pointer to error string + * @param[out] messageLength Size of error meesage + * + * @return no return + */ + virtual void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage) + { + // Since we do not have any error message just generate a generic one + if (m_Binary) + m_ErrorMessage = "Binary shader compilation failed"; + + *messageLength = m_ErrorMessage.size(); + errorMessage = m_ErrorMessage.c_str(); + } + + /** + * @brief Get Error Message + * + * + * @return error message. + */ + virtual const char *GetErrorMessage() + { + if (m_Binary) + m_ErrorMessage = "Binary shader compilation failed"; + + return m_ErrorMessage.c_str(); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h b/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h new file mode 100644 index 00000000..7fb57ffe --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h @@ -0,0 +1,448 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_CONSTANT_H +#define QT3DS_RENDER_SHADER_CONSTANT_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DSMat44.h" +#include "EASTL/string.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + ///< forward declarations + class NVRenderContextImpl; + class NVRenderConstantBuffer; + + ///< A shader constant belongs to a program + class QT3DS_AUTOTEST_EXPORT NVRenderShaderConstantBase + { + public: + NVRenderBackend *m_Backend; ///< pointer to backend + CRegisteredString m_Name; ///< register constant name + QT3DSI32 m_Location; ///< constant index + QT3DSI32 m_ElementCount; ///< constant element count for arrays + NVRenderShaderDataTypes::Enum m_Type; ///< constant type + QT3DSI32 m_Binding; ///< sampler/imnage binding point + + public: + NVRenderShaderConstantBase(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding) + : m_Backend(backend) + , m_Name(name) + , m_Location(location) + , m_ElementCount(elementCount) + , m_Type(type) + , m_Binding(binding) + { + } + + NVRenderShaderDataTypes::Enum GetShaderConstantType() const { return m_Type; } + + virtual void Release() = 0; + }; + + ///< A general class for shader types + template + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + TDataType m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + memset(&m_Value, 0, sizeof(TDataType)); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for textures + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for textures + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QVector m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value.resize(elementCount); + m_Value.fill(QT3DS_MAX_U32); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for texture arrays + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for cubemap textures + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for cubemap textures + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QVector m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value.resize(elementCount); + m_Value.fill(QT3DS_MAX_U32); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for texture image buffer + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< Base for any buffer ( constant, texture, ... ) which is used by this program + class NVRenderShaderBufferBase + { + public: + NVRenderContextImpl &m_Context; ///< pointer to context + CRegisteredString m_Name; ///< buffer name + QT3DSU32 m_Location; ///< program buffer block location + QT3DSU32 m_Binding; ///< program buffer binding + QT3DSI32 m_Size; ///< buffer size + + public: + NVRenderShaderBufferBase(NVRenderContextImpl &context, CRegisteredString name, + QT3DSI32 location, QT3DSI32 binding, QT3DSI32 size) + : m_Context(context) + , m_Name(name) + , m_Location(location) + , m_Binding(binding) + , m_Size(size) + { + } + + virtual void Release() = 0; + + virtual void Validate(NVRenderShaderProgram *inShader) = 0; + virtual void BindToProgram(NVRenderShaderProgram *inShader) = 0; + virtual void Update() = 0; + }; + + class NVRenderShaderConstantBuffer : public NVRenderShaderBufferBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer + NVRenderConstantBuffer *m_pCB; ///< pointer to constant buffer + + public: + NVRenderShaderConstantBuffer(NVRenderContextImpl &context, CRegisteredString name, + QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, + NVRenderConstantBuffer *pCB, NVFoundationBase &allocator) + : NVRenderShaderBufferBase(context, name, location, binding, size) + , m_Foundation(allocator) + , m_ParamCount(count) + , m_pCB(pCB) + { + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override + { + if (m_pCB) + m_pCB->release(); + + NVDelete(GetFoundation().getAllocator(), this); + } + + void Validate(NVRenderShaderProgram *inShader) override + { + // A constant buffer might not be set at first call + // due to the fact that they are compiled from a cache file + // Now it must exists. + if (m_pCB) + return; + + NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(m_Name); + if (cb) { + cb->SetupBuffer(inShader, m_Location, m_Size, m_ParamCount); + cb->addRef(); + m_pCB = cb; + } else { + QT3DS_ASSERT(false); + } + } + + void Update() override + { + if (m_pCB) + m_pCB->Update(); + } + + void BindToProgram(NVRenderShaderProgram *inShader) override + { + if (m_pCB) + m_pCB->BindToShaderProgram(inShader, m_Location, m_Binding); + } + }; + + class NVRenderShaderStorageBuffer : public NVRenderShaderBufferBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer + NVRenderStorageBuffer *m_pSB; ///< pointer to storage buffer + + public: + NVRenderShaderStorageBuffer(NVRenderContextImpl &context, CRegisteredString name, + QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, + NVRenderStorageBuffer *pSB, NVFoundationBase &allocator) + : NVRenderShaderBufferBase(context, name, location, binding, size) + , m_Foundation(allocator) + , m_ParamCount(count) + , m_pSB(pSB) + { + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override + { + if (m_pSB) + m_pSB->release(); + + NVDelete(GetFoundation().getAllocator(), this); + } + + void Validate(NVRenderShaderProgram * /*inShader*/) override + { + // A constant buffer might not be set at first call + // due to the fact that they are compile from a cache file + // Now it must exists. + if (m_pSB) + return; + + NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(m_Name); + if (sb) { + sb->addRef(); + m_pSB = sb; + } else { + QT3DS_ASSERT(false); + } + } + + void Update() override + { + if (m_pSB) + m_pSB->Update(); + } + + void BindToProgram(NVRenderShaderProgram * /*inShader*/) override + { + if (m_pSB) + m_pSB->BindToShaderProgram(m_Location); + } + }; + + class NVRenderShaderAtomicCounterBuffer : public NVRenderShaderBufferBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer + NVRenderAtomicCounterBuffer *m_pAcB; ///< pointer to atomic counter buffer + + public: + NVRenderShaderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString name, + QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, + NVRenderAtomicCounterBuffer *pAcB, + NVFoundationBase &allocator) + : NVRenderShaderBufferBase(context, name, location, binding, size) + , m_Foundation(allocator) + , m_ParamCount(count) + , m_pAcB(pAcB) + { + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override + { + if (m_pAcB) + m_pAcB->release(); + + NVDelete(GetFoundation().getAllocator(), this); + } + + void Validate(NVRenderShaderProgram * /*inShader*/) override + { + // A constant buffer might not be set at first call + // due to the fact that they are compile from a cache file + // Now it must exists. + if (m_pAcB) + return; + + NVRenderAtomicCounterBuffer *acb = m_Context.GetAtomicCounterBuffer(m_Name); + if (acb) { + acb->addRef(); + m_pAcB = acb; + } else { + QT3DS_ASSERT(false); + } + } + + void Update() override + { + if (m_pAcB) + m_pAcB->Update(); + } + + void BindToProgram(NVRenderShaderProgram * /*inShader*/) override + { + if (m_pAcB) + m_pAcB->BindToShaderProgram(m_Location); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp new file mode 100644 index 00000000..09f1094b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp @@ -0,0 +1,1248 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "render/Qt3DSRenderVertexShader.h" +#include "render/Qt3DSRenderFragmentShader.h" +#include "render/Qt3DSRenderTessellationShader.h" +#include "render/Qt3DSRenderGeometryShader.h" +#include "render/Qt3DSRenderComputeShader.h" +#include "render/Qt3DSRenderImageTexture.h" + +namespace qt3ds { +namespace render { + + template + struct ShaderConstantApplier + { + bool force_compile_error; + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32 &inValue, + QT3DSI32 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_2 &inValue, + QT3DSI32_2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_3 &inValue, + QT3DSI32_3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_4 &inValue, + QT3DSI32_4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + const QT3DSRenderBool inValue, QT3DSRenderBool &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_2 &inValue, + bool_2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_3 &inValue, + bool_3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_4 &inValue, + bool_4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSF32 &inValue, + QT3DSF32 &oldValue) + { + if (count > 1 || !(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec2 &inValue, + QT3DSVec2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec3 &inValue, + QT3DSVec3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec4 &inValue, + QT3DSVec4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32 &inValue, + QT3DSU32 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_2 &inValue, + QT3DSU32_2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_3 &inValue, + QT3DSU32_3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_4 &inValue, + QT3DSU32_4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat33 inValue, + QT3DSMat33 &, bool inTranspose) + { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + inValue.front(), inTranspose); + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat44 inValue, + QT3DSMat44 &, bool inTranspose) + { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + inValue.front(), inTranspose); + } + + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVConstDataRef inValue, QT3DSMat44 &, bool inTranspose) + { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + reinterpret_cast(inValue.begin()), + inTranspose); + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DPtr inValue, QT3DSU32 &oldValue) + { + if (inValue) { + NVRenderTexture2D *texObj = reinterpret_cast(inValue); + texObj->Bind(); + QT3DSU32 texUnit = texObj->GetTextureUnit(); + if (texUnit != oldValue) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + oldValue = texUnit; + } + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, + QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DHandle inValue, QVector &oldValue) + { + Q_UNUSED(type) + if (inValue) { + bool update = false; + for (int i = 0; i < count; i++) { + NVRenderTexture2D *texObj = reinterpret_cast(inValue[i]); + QT3DSU32 texUnit = QT3DS_MAX_U32; + if (texObj) { + texObj->Bind(); + texUnit = texObj->GetTextureUnit(); + } + if (texUnit != oldValue[i]) { + update = true; + oldValue[i] = texUnit; + } + } + if (update) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, + NVRenderShaderDataTypes::NVRenderTexture2DPtr, + count, oldValue.data()); + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DArrayPtr inValue, QT3DSU32 &oldValue) + { + if (inValue) { + NVRenderTexture2DArray *texObj = + reinterpret_cast(inValue); + texObj->Bind(); + QT3DSU32 texUnit = texObj->GetTextureUnit(); + if (texUnit != oldValue) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + oldValue = texUnit; + } + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTextureCubePtr inValue, QT3DSU32 &oldValue) + { + if (inValue) { + NVRenderTextureCube *texObj = reinterpret_cast(inValue); + texObj->Bind(); + QT3DSU32 texUnit = texObj->GetTextureUnit(); + if (texUnit != oldValue) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + oldValue = texUnit; + } + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, + QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTextureCubeHandle inValue, QVector &oldValue) + { + Q_UNUSED(type) + if (inValue) { + bool update = false; + for (int i = 0; i < count; i++) { + NVRenderTextureCube *texObj = reinterpret_cast(inValue[i]); + QT3DSU32 texUnit = QT3DS_MAX_U32; + if (texObj) { + texObj->Bind(); + texUnit = texObj->GetTextureUnit(); + } + if (texUnit != oldValue[i]) { + update = true; + oldValue[i] = texUnit; + } + } + if (update) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, + NVRenderShaderDataTypes::NVRenderTextureCubePtr, + count, oldValue.data()); + } + } + }; + + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderImage2DPtr inValue, QT3DSU32 &oldValue, QT3DSI32 binding) + { + if (inValue) { + NVRenderImage2D *imgObj = reinterpret_cast(inValue); + imgObj->Bind(binding); + QT3DSU32 texUnit = imgObj->GetTextureUnit(); + if (texUnit != oldValue) { + // on ES we need a explicit binding value + QT3DS_ASSERT(backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS + || binding != -1); + // this is not allowed on ES 3+ for image types + if (backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + + oldValue = texUnit; + } + } + } + }; + + NVRenderShaderProgram::NVRenderShaderProgram(NVRenderContextImpl &context, + NVFoundationBase &fnd, const char *programName, + bool separableProgram) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_ProgramName(programName) + , m_ProgramHandle(NULL) + , m_Constants(context.GetFoundation().getAllocator(), "NVRenderShaderProgram::m_Constants") + , m_ShaderBuffers(context.GetFoundation().getAllocator(), + "NVRenderShaderProgram::m_ShaderBuffers") + , m_ProgramType(ProgramType::Graphics) + { + m_ProgramHandle = m_Backend->CreateShaderProgram(separableProgram); + + QT3DS_ASSERT(m_ProgramHandle); + } + + NVRenderShaderProgram::~NVRenderShaderProgram() + { + m_Context.ShaderDestroyed(*this); + + if (m_ProgramHandle) + m_Backend->ReleaseShaderProgram(m_ProgramHandle); + + for (TShaderConstantMap::iterator iter = m_Constants.begin(), end = m_Constants.end(); + iter != end; ++iter) { + iter->second->Release(); + } + + m_Constants.clear(); + + for (TShaderBufferMap::iterator iter = m_ShaderBuffers.begin(), end = m_ShaderBuffers.end(); + iter != end; ++iter) { + iter->second->Release(); + } + + m_ShaderBuffers.clear(); + + m_ProgramHandle = NULL; + } + + template + void NVRenderShaderProgram::Attach(TShaderObject *pShader) + { + m_Backend->AttachShader(m_ProgramHandle, pShader->GetShaderHandle()); + } + + template + void NVRenderShaderProgram::Detach(TShaderObject *pShader) + { + m_Backend->DetachShader(m_ProgramHandle, pShader->GetShaderHandle()); + } + + static NVRenderShaderConstantBase * + ShaderConstantFactory(NVRenderBackend *backend, CRegisteredString inName, + NVFoundationBase &alloc, QT3DSI32 uniLoc, QT3DSI32 elementCount, + NVRenderShaderDataTypes::Enum inConstantType, QT3DSI32 binding) + { + switch (inConstantType) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(nv) \ + case NVRenderShaderDataTypes::nv: \ + return QT3DS_NEW(alloc.getAllocator(), NVRenderShaderConstant)( \ + backend, inName, uniLoc, elementCount, inConstantType, binding, alloc); + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return NULL; + } + + template + static NVRenderShaderBufferBase * + ShaderBufferFactory(NVRenderContextImpl &context, CRegisteredString inName, + NVFoundationBase &alloc, QT3DSI32 cbLoc, QT3DSI32 cbBinding, QT3DSI32 cbSize, + QT3DSI32 cbCount, TBufferDataType *pBuffer) + { + return QT3DS_NEW(alloc.getAllocator(), TShaderBufferType)(context, inName, cbLoc, cbBinding, + cbSize, cbCount, pBuffer, alloc); + } + + bool NVRenderShaderProgram::Link() + { + bool success = m_Backend->LinkProgram(m_ProgramHandle, m_ErrorMessage); + + if (success) { + char nameBuf[512]; + QT3DSI32 location, elementCount, binding; + NVRenderShaderDataTypes::Enum type; + + QT3DSI32 constantCount = m_Backend->GetConstantCount(m_ProgramHandle); + + QT3DS_FOREACH(idx, constantCount) + { + location = m_Backend->GetConstantInfoByID(m_ProgramHandle, idx, 512, &elementCount, + &type, &binding, nameBuf); + + // sampler arrays have different type + if (type == NVRenderShaderDataTypes::NVRenderTexture2DPtr && elementCount > 1) { + type = NVRenderShaderDataTypes::NVRenderTexture2DHandle; + } else if (type == NVRenderShaderDataTypes::NVRenderTextureCubePtr + && elementCount > 1) { + type = NVRenderShaderDataTypes::NVRenderTextureCubeHandle; + } + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + m_Constants.insert(eastl::make_pair( + theName, + ShaderConstantFactory(m_Backend, theName, m_Context.GetFoundation(), + location, elementCount, type, binding))); + } + } + + // next query constant buffers info + QT3DSI32 length, bufferSize, paramCount; + QT3DSI32 constantBufferCount = m_Backend->GetConstantBufferCount(m_ProgramHandle); + QT3DS_FOREACH(idx, constantBufferCount) + { + location = m_Backend->GetConstantBufferInfoByID( + m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); + + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + + // find constant buffer in our DB + NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(theName); + if (cb) { + cb->SetupBuffer(this, location, bufferSize, paramCount); + cb->addRef(); + } + + m_ShaderBuffers.insert(eastl::make_pair( + theName, + ShaderBufferFactory( + m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize, + paramCount, cb))); + } + } + + // next query storage buffers + QT3DSI32 storageBufferCount = m_Backend->GetStorageBufferCount(m_ProgramHandle); + QT3DS_FOREACH(idx, storageBufferCount) + { + location = m_Backend->GetStorageBufferInfoByID( + m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); + + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + + // find constant buffer in our DB + NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(theName); + if (sb) { + sb->addRef(); + } + + m_ShaderBuffers.insert(eastl::make_pair( + theName, + ShaderBufferFactory( + m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize, + paramCount, sb))); + } + } + + // next query atomic counter buffers + QT3DSI32 atomicBufferCount = m_Backend->GetAtomicCounterBufferCount(m_ProgramHandle); + QT3DS_FOREACH(idx, atomicBufferCount) + { + location = m_Backend->GetAtomicCounterBufferInfoByID( + m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); + + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + + // find atomic counter buffer in our DB + // The buffer itself is not used in the program itself. + // Instead uniform variables are used but the interface to set the value is like + // for buffers. + // This is a bit insane but that is how it is. + // The theName variable contains the uniform name associated with an atomic + // counter buffer. + // We get the actual buffer name by searching for this uniform name + // See NVRenderTestAtomicCounterBuffer.cpp how the setup works + NVRenderAtomicCounterBuffer *acb = + m_Context.GetAtomicCounterBufferByParam(theName); + if (acb) { + acb->addRef(); + + m_ShaderBuffers.insert(eastl::make_pair( + acb->GetBufferName(), + ShaderBufferFactory( + m_Context, acb->GetBufferName(), m_Context.GetFoundation(), + location, -1, bufferSize, paramCount, acb))); + } + } + } + } + + return success; + } + + void NVRenderShaderProgram::GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage) + { + *messageLength = m_ErrorMessage.size(); + errorMessage = m_ErrorMessage.c_str(); + } + + const char *NVRenderShaderProgram::GetErrorMessage() { return m_ErrorMessage.c_str(); } + + NVRenderShaderConstantBase *NVRenderShaderProgram::GetShaderConstant(const char *constantName) + { + TShaderConstantMap::iterator theIter = + m_Constants.find(m_Context.GetStringTable().RegisterStr(constantName)); + + if (theIter != m_Constants.end()) { + NVRenderShaderConstantBase *theConstant = + static_cast(theIter->second); + return theConstant; + } + + return NULL; + } + + NVRenderShaderBufferBase *NVRenderShaderProgram::GetShaderBuffer(const char *bufferName) + { + TShaderBufferMap::iterator theIter = + m_ShaderBuffers.find(m_Context.GetStringTable().RegisterStr(bufferName)); + + if (theIter != m_ShaderBuffers.end()) { + return theIter->second; + } + + return NULL; + } + + NVRenderContextImpl &NVRenderShaderProgram::GetRenderContext() { return m_Context; } + + template + void SetConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const TDataType &inValue, const QT3DSI32 inCount) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + NVRenderShaderConstant *inConstant = + static_cast *>(inConstantBase); + ShaderConstantApplier().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, + inValue, inConstant->m_Value); + } else { + QT3DS_ASSERT(false); + } + } + + template + void SetSamplerConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const TDataType &inValue, const QT3DSI32 inCount) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + NVRenderShaderConstant *inConstant = + static_cast *>(inConstantBase); + ShaderConstantApplier().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, + inValue, inConstant->m_Value, inConstant->m_Binding); + } else { + QT3DS_ASSERT(false); + } + } + + template + void SetMatrixConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const TDataType &inValue, const QT3DSI32 inCount, + bool inTranspose) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + NVRenderShaderConstant *inConstant = + static_cast *>(inConstantBase); + ShaderConstantApplier().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, + inValue, inConstant->m_Value, inTranspose); + } else { + QT3DS_ASSERT(false); + } + } + + template + void SetMatrixConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const NVConstDataRef inValue, + const QT3DSI32 /*inCount*/, bool inTranspose) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= (QT3DSI32)inValue.size()); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + NVRenderShaderConstant *inConstant = + static_cast *>(inConstantBase); + ShaderConstantApplier().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inValue.size(), + inConstant->m_Type, inValue, inConstant->m_Value, inTranspose); + } else { + QT3DS_ASSERT(false); + } + } + + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + QT3DSI32 inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSI32_2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSI32_3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSI32_4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + QT3DSRenderBool inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const bool_2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const bool_3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const bool_4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSF32 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSVec2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSVec3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSVec4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32_2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32_3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32_4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSMat33 &inValue, const QT3DSI32 inCount, + bool inTranspose) + { + SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSMat44 &inValue, const QT3DSI32 inCount, + bool inTranspose) + { + SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const NVConstDataRef inValue, + const QT3DSI32 inCount) + { + SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, false); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2D *inValue, const QT3DSI32 inCount) + { + Q_UNUSED(inCount) + SetConstantValueOfType(this, inConstant, inValue, 1); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2D **inValue, + const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2DArray *inValue, + const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTextureCube *inValue, const QT3DSI32 inCount) + { + Q_UNUSED(inCount) + SetConstantValueOfType(this, inConstant, inValue, 1); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTextureCube **inValue, + const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderImage2D *inValue, const QT3DSI32 inCount) + { + SetSamplerConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *, NVRenderDataBuffer *, + const QT3DSI32) + { + // this is merely a dummy right now + } + + void NVRenderShaderProgram::BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex) + { + NVRenderBackend::NVRenderBackendBufferObject obj(NULL); + if (inBuffer) + obj = inBuffer->GetBuffertHandle(); + m_Backend->ProgramSetStorageBuffer(inIndex, obj); + } + + namespace { + void WriteErrorMessage(NVFoundationBase &fnd, const char *tag, const char *message) + { + Q_UNUSED(fnd) + eastl::string messageData(nonNull(message)); + eastl::vector lines; + for (eastl::string::size_type pos = messageData.find('\n'); pos != eastl::string::npos; + pos = messageData.find('\n')) { + eastl::string line = messageData.substr(0, pos); + messageData.erase(messageData.begin(), messageData.begin() + pos + 1); + if (line.size()) + qCCritical(INVALID_OPERATION, "%s: %s", tag, line.c_str()); + } + } + } + + Option NVRenderShaderProgram::createVertexShader( + NVRenderContextImpl &context, NVConstDataRef vertexShaderSource, bool binaryProgram) + { + if (vertexShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderVertexShader(context, context.GetFoundation(), vertexShaderSource, + binaryProgram)); + } + + Option NVRenderShaderProgram::createFragmentShader( + NVRenderContextImpl &context, NVConstDataRef fragmentShaderSource, bool binaryProgram) + { + if (fragmentShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderFragmentShader(context, context.GetFoundation(), fragmentShaderSource, + binaryProgram)); + } + + Option + NVRenderShaderProgram::createTessControlShader(NVRenderContextImpl &context, + NVConstDataRef tessControlShaderSource, + bool binaryProgram) + { + if (tessControlShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTessControlShader(context, context.GetFoundation(), + tessControlShaderSource, binaryProgram)); + } + + Option + NVRenderShaderProgram::createTessEvaluationShader(NVRenderContextImpl &context, + NVConstDataRef tessControlShaderSource, + bool binaryProgram) + { + if (tessControlShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTessEvaluationShader(context, context.GetFoundation(), + tessControlShaderSource, binaryProgram)); + } + + Option NVRenderShaderProgram::createGeometryShader( + NVRenderContextImpl &context, NVConstDataRef geometryShaderSource, bool binaryProgram) + { + if (geometryShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderGeometryShader(context, context.GetFoundation(), geometryShaderSource, + binaryProgram)); + } + + NVRenderVertFragCompilationResult NVRenderShaderProgram::Create( + NVRenderContextImpl &context, const char *programName, + NVConstDataRef vertShaderSource, NVConstDataRef fragShaderSource, + NVConstDataRef tessControlShaderSource, + NVConstDataRef tessEvaluationShaderSource, NVConstDataRef geometryShaderSource, + bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) + { + NVRenderVertFragCompilationResult result; + NVRenderShaderProgram *pProgram = NULL; + bool bProgramIsValid = false; + + result.mShaderName = programName; + + // our minimum requirement is a vertex and a fragment shader or geometry shader + // if we should treat it as a separate program we don't care + if (!separateProgram + && (vertShaderSource.size() == 0 + || (fragShaderSource.size() == 0 && geometryShaderSource.size() == 0))) { + qCCritical(INVALID_PARAMETER, + "Vertex or fragment (geometry) source have 0 length"); + QT3DS_ASSERT(false); + return result; + } + + if (binaryProgram && type != NVRenderShaderProgramBinaryType::NVBinary) { + qCCritical(INVALID_PARAMETER, "Unrecoginzed binary format"); + QT3DS_ASSERT(false); + return result; + } + + // first create and compile shader + Option vtxShader = + createVertexShader(context, vertShaderSource, binaryProgram); + Option fragShader = + createFragmentShader(context, fragShaderSource, binaryProgram); + Option tcShader = + createTessControlShader(context, tessControlShaderSource, binaryProgram); + Option teShader = + createTessEvaluationShader(context, tessEvaluationShaderSource, binaryProgram); + Option geShader = + createGeometryShader(context, geometryShaderSource, binaryProgram); + + bool vertexValid = (vtxShader.hasValue()) ? vtxShader.getValue()->IsValid() : true; + bool fragValid = (fragShader.hasValue()) ? fragShader.getValue()->IsValid() : true; + bool tcValid = (tcShader.hasValue()) ? tcShader.getValue()->IsValid() : true; + bool teValid = (teShader.hasValue()) ? teShader.getValue()->IsValid() : true; + bool geValid = (geShader.hasValue()) ? geShader.getValue()->IsValid() : true; + + if (vertexValid && fragValid && tcValid && teValid && geValid) { + // shaders were succesfuly created + pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)( + context, context.GetFoundation(), programName, separateProgram); + + if (pProgram) { + // attach programs + if (vtxShader.hasValue() && vtxShader.getValue()->IsValid()) + pProgram->Attach(vtxShader.getValue()); + if (fragShader.hasValue() && fragShader.getValue()->IsValid()) + pProgram->Attach(fragShader.getValue()); + if (tcShader.hasValue() && tcShader.getValue()->IsValid()) + pProgram->Attach(tcShader.getValue()); + if (teShader.hasValue() && teShader.getValue()->IsValid()) + pProgram->Attach(teShader.getValue()); + if (geShader.hasValue() && geShader.getValue()->IsValid()) + pProgram->Attach(geShader.getValue()); + + // link program + bProgramIsValid = pProgram->Link(); + } + } + + // if anything went wrong print out + if (!vertexValid || !fragValid || !tcValid || !teValid || !geValid || !bProgramIsValid) { + NVFoundationBase &foundation(context.GetFoundation()); + + if (!vertexValid) { + qCCritical(INTERNAL_ERROR, "Failed to generate vertex shader!!"); + qCCritical(INTERNAL_ERROR, "Vertex source:\n%s", + nonNull((const char *)vertShaderSource.begin())); + WriteErrorMessage(foundation, "Vertex compilation output:", + vtxShader.getValue()->GetErrorMessage()); + } + + if (!fragValid) { + qCCritical(INTERNAL_ERROR, "Failed to generate fragment shader!!"); + qCCritical(INTERNAL_ERROR, "Fragment source:\n%s", + nonNull((const char *)fragShaderSource.begin())); + WriteErrorMessage(foundation, "Fragment compilation output:", + fragShader.getValue()->GetErrorMessage()); + } + + if (!tcValid) { + qCCritical(INTERNAL_ERROR, + "Failed to generate tessellation control shader!!"); + qCCritical(INTERNAL_ERROR, "Tessellation control source:\n%s", + nonNull((const char *)tessControlShaderSource.begin())); + WriteErrorMessage(foundation, "Tessellation control compilation output:", + tcShader.getValue()->GetErrorMessage()); + } + + if (!teValid) { + qCCritical(INTERNAL_ERROR, + "Failed to generate tessellation evaluation shader!!"); + qCCritical(INTERNAL_ERROR, "Tessellation evaluation source:\n%s", + nonNull((const char *)tessEvaluationShaderSource.begin())); + WriteErrorMessage(foundation, "Tessellation evaluation compilation output:", + teShader.getValue()->GetErrorMessage()); + } + + if (!geValid) { + qCCritical(INTERNAL_ERROR, "Failed to generate geometry shader!!"); + qCCritical(INTERNAL_ERROR, "Geometry source:\n%s", + nonNull((const char *)geometryShaderSource.begin())); + WriteErrorMessage(foundation, "Geometry compilation output:", + geShader.getValue()->GetErrorMessage()); + } + + if (!bProgramIsValid && pProgram) { + qCCritical(INTERNAL_ERROR, "Failed to link program!!"); + WriteErrorMessage(foundation, "Program link output:", pProgram->GetErrorMessage()); + + // delete program + QT3DS_FREE(context.GetFoundation().getAllocator(), pProgram); + pProgram = NULL; + } + } + + // clean up + if (vtxShader.hasValue()) { + if (bProgramIsValid && vtxShader.getValue()->IsValid()) + pProgram->Detach(vtxShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), vtxShader.getValue()); + } + if (fragShader.hasValue()) { + if (bProgramIsValid && fragShader.getValue()->IsValid()) + pProgram->Detach(fragShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), fragShader.getValue()); + } + if (tcShader.hasValue()) { + if (bProgramIsValid && tcShader.getValue()->IsValid()) + pProgram->Detach(tcShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), tcShader.getValue()); + } + if (teShader.hasValue()) { + if (bProgramIsValid && teShader.getValue()->IsValid()) + pProgram->Detach(teShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), teShader.getValue()); + } + if (geShader.hasValue()) { + if (bProgramIsValid && geShader.getValue()->IsValid()) + pProgram->Detach(geShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), geShader.getValue()); + } + + // set program + result.mShader = pProgram; + + return result; + } + + NVRenderVertFragCompilationResult + NVRenderShaderProgram::CreateCompute(NVRenderContextImpl &context, const char *programName, + NVConstDataRef computeShaderSource) + { + NVRenderVertFragCompilationResult result; + NVRenderShaderProgram *pProgram = NULL; + bool bProgramIsValid = true; + + result.mShaderName = programName; + + // check source + if (computeShaderSource.size() == 0) { + qCCritical(INVALID_PARAMETER, "compute source has 0 length"); + QT3DS_ASSERT(false); + return result; + } + + NVRenderComputeShader computeShader(context, context.GetFoundation(), computeShaderSource, + false); + + if (computeShader.IsValid()) { + // shaders were succesfuly created + pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)( + context, context.GetFoundation(), programName, false); + + if (pProgram) { + // attach programs + pProgram->Attach(&computeShader); + + // link program + bProgramIsValid = pProgram->Link(); + + // set program type + pProgram->SetProgramType(ProgramType::Compute); + } + } + + // if anything went wrong print out + if (!computeShader.IsValid() || !bProgramIsValid) { + NVFoundationBase &foundation(context.GetFoundation()); + + if (!computeShader.IsValid()) { + qCCritical(INTERNAL_ERROR, "Failed to generate compute shader!!"); + qCCritical(INTERNAL_ERROR, "Vertex source:\n%s", + nonNull((const char *)computeShaderSource.begin())); + WriteErrorMessage(foundation, "Compute shader compilation output:", + computeShader.GetErrorMessage()); + } + } + + // set program + result.mShader = pProgram; + + return result; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h new file mode 100644 index 00000000..054db64b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h @@ -0,0 +1,540 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_PROGRAM_H +#define QT3DS_RENDER_SHADER_PROGRAM_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShaderConstant.h" +#include "EASTL/string.h" +#include "EASTL/utility.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + ///< forward declarations + class NVRenderContextImpl; + class NVRenderVertexShader; + class NVRenderFragmentShader; + class NVRenderTessControlShader; + class NVRenderTessEvaluationShader; + class NVRenderGeometryShader; + class NVRenderShaderConstantBase; + class NVRenderShaderBufferBase; + class NVRenderComputeShader; + + typedef nvhash_map TShaderConstantMap; + typedef nvhash_map TShaderBufferMap; + + ///< A shader program is an object composed of a multiple shaders (vertex, fragment, + ///geometry,....) + class QT3DS_AUTOTEST_EXPORT NVRenderShaderProgram : public NVRefCounted + { + public: + struct ProgramType + { + enum Enum { Graphics, Compute }; + }; + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + const char *m_ProgramName; /// Name of the program + NVRenderBackend::NVRenderBackendShaderProgramObject + m_ProgramHandle; ///< opaque backend handle + TShaderConstantMap m_Constants; ///< map of shader constants + TShaderBufferMap m_ShaderBuffers; ///< map of shader buffers + ProgramType::Enum m_ProgramType; ///< shader type + eastl::string m_ErrorMessage; ///< contains the error message if linking fails + + /** + * @brief create vertex shader + * + * @param[in] context Pointer to render context + * @param[in] vertexShaderSource Fragment shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to vertex shader object + */ + static Option + createVertexShader(NVRenderContextImpl &context, NVConstDataRef vertexShaderSource, + bool binaryProgram = false); + + /** + * @brief create fragment shader + * + * @param[in] context Pointer to render context + * @param[in] fragmentShaderSource Fragment shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to fragment shader object + */ + static Option + createFragmentShader(NVRenderContextImpl &context, + NVConstDataRef fragmentShaderSource, bool binaryProgram = false); + + /** + * @brief create tesselation control shader + * + * @param[in] context Pointer to render context + * @param[in] tessControlShaderSource Tessellation control shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to tessellation control shader + */ + static Option + createTessControlShader(NVRenderContextImpl &context, + NVConstDataRef tessControlShaderSource, + bool binaryProgram = false); + + /** + * @brief create tesselation evaluation shader + * + * @param[in] context Pointer to render context + * @param[in] tessEvaluationShaderSource Tessellation evaluation shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to tessellation evaluation shader + */ + static Option + createTessEvaluationShader(NVRenderContextImpl &context, + NVConstDataRef tessEvaluationShaderSource, + bool binaryProgram = false); + + /** + * @brief create geometry shader + * + * @param[in] context Pointer to render context + * @param[in] geometryShaderSource Geometry shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to geometry shader + */ + static Option + createGeometryShader(NVRenderContextImpl &context, + NVConstDataRef geometryShaderSource, bool binaryProgram = false); + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] programName Pointer to string of program name + * @param[in] separableProgram True if this is a separable program + * + * @return No return. + */ + NVRenderShaderProgram(NVRenderContextImpl &context, NVFoundationBase &fnd, + const char *programName, bool separableProgram); + + /// destructor + ~NVRenderShaderProgram(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief attach a shader to the program + * + * @param[in] pShader Pointer to shader object + * + * @return No return. + */ + template + void Attach(TShaderObject *pShader); + + /** + * @brief detach a shader from the program + * + * @param[in] pShader Pointer to shader object + * + * @return No return. + */ + template + void Detach(TShaderObject *pShader); + + /** + * @brief link a program + * + * + * @return true if succesfuly linked. + */ + bool Link(); + + /** + * @brief set a shader type + * + * @param[in] type shader type ( graphics or compute ) + * + * @return No return. + */ + void SetProgramType(ProgramType::Enum type) { m_ProgramType = type; } + ProgramType::Enum GetProgramType() const { return m_ProgramType; } + + /** + * @brief Get Error Message + * + * @param[out] messageLength Pointer to error string + * @param[out] messageLength Size of error meesage + * + * @return no return. + */ + void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage); + + /** + * @brief Get Error Message + * + * + * @return error message. + */ + const char *GetErrorMessage(); + + /** + * @brief Query constant class + * + * @param[in] constantName Pointer to constant name + * + * @return return a pointer to a constant class. + */ + NVRenderShaderConstantBase *GetShaderConstant(const char *constantName); + + /** + * @brief Query a shader buffer (constant, ... ) + * + * @param[in] bufferName Pointer to constant name + * + * @return return a pointer to a constant class. + */ + NVRenderShaderBufferBase *GetShaderBuffer(const char *bufferName); + + // concrete set functions + void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSI32 inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSRenderBool inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSF32 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat33 &inValue, + const QT3DSI32 inCount, bool inTranspose = false); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat44 &inValue, + const QT3DSI32 inCount, bool inTranspose = false); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, + const NVConstDataRef inValue, const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D *inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D **inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2DArray *inValue, const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube *inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube **inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderImage2D *inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderDataBuffer *inValue, + const QT3DSI32 inCount); + + /** + * @brief Template to set constant value via name + * + * @param[in] inConstantName Pointer to constant name + * @param[in] inValue Pointer to data + * @param[in] inCount Number of elements (array count) + * + * @return return a pointer to a constant class. + */ + template + void SetPropertyValue(const char *inConstantName, const TDataType &inValue, + const QT3DSI32 inCount = 1) + { + NVRenderShaderConstantBase *theConstant = GetShaderConstant(inConstantName); + + if (theConstant) { + if (theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + SetConstantValue(theConstant, inValue, inCount); + } else { + // Types don't match or property not found + QT3DS_ASSERT(false); + } + } + } + + /** + * @brief Template to set constant value shader constant object + * + * @param[in] inConstant Pointer shader constant object + * @param[in] inValue Pointer to data + * @param[in] inCount Number of elements (array count) + * + * @return return a pointer to a constant class. + */ + template + void SetPropertyValue(NVRenderShaderConstantBase *inConstant, const TDataType &inValue, + const QT3DSI32 inCount = 1) + { + if (inConstant) { + if (inConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + SetConstantValue(inConstant, inValue, inCount); + } else { + // Types don't match or property not found + QT3DS_ASSERT(false); + } + } + } + + virtual void BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendShaderProgramObject GetShaderProgramHandle() const + { + return m_ProgramHandle; + } + + /** + * @brief get the context object + * + * @return context which this shader belongs to. + */ + NVRenderContextImpl &GetRenderContext(); + + /** + * @brief Create a shader program + * + * @param[in] context Pointer to context + * @param[in] programName Name of the program + * @param[in] vertShaderSource Vertex shader source code + * @param[in] fragShaderSource Fragment shader source code + * @param[in] tessControlShaderSource tessellation control shader source code + * @param[in] tessEvaluationShaderSource tessellation evaluation shader source code + * @param[in] separateProgram True if this will we a separate + * program + * @param[in] type Binary program type + * @param[in] binaryProgram True if program is binary + * + * @return a render result + */ + static NVRenderVertFragCompilationResult Create( + NVRenderContextImpl &context, const char *programName, + NVConstDataRef vertShaderSource, NVConstDataRef fragShaderSource, + NVConstDataRef tessControlShaderSource = NVConstDataRef(), + NVConstDataRef tessEvaluationShaderSource = NVConstDataRef(), + NVConstDataRef geometryShaderSource = NVConstDataRef(), + bool separateProgram = false, + NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, + bool binaryProgram = false); + + /** + * @brief Create a compute shader program + * + * @param[in] context Pointer to context + * @param[in] programName Name of the program + * @param[in] computeShaderSource Compute shader source code + * + * @return a render result + */ + static NVRenderVertFragCompilationResult + CreateCompute(NVRenderContextImpl &context, const char *programName, + NVConstDataRef computeShaderSource); + }; + + // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe + // way. + template + struct NVRenderCachedShaderProperty + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object + + NVRenderCachedShaderProperty(const QString &inConstantName, NVRenderShaderProgram &inShader) + : NVRenderCachedShaderProperty(qPrintable(inConstantName), inShader) + { + } + + NVRenderCachedShaderProperty(const char *inConstantName, NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_Constant(NULL) + { + NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); + if (theConstant) { + if (theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + m_Constant = theConstant; + } else { + // Property types do not match, this probably indicates that the shader changed + // while the + // code creating this object did not change. + QT3DS_ASSERT(false); + } + } + } + + NVRenderCachedShaderProperty() + : m_Shader(NULL) + , m_Constant(NULL) + { + } + + void Set(const TDataType &inValue) + { + if (m_Constant) + m_Shader->SetPropertyValue(m_Constant, inValue); + } + + bool IsValid() const { return m_Constant != 0; } + }; + + template + struct NVRenderCachedShaderPropertyArray + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object + TDataType m_array[size]; + + NVRenderCachedShaderPropertyArray(const QString &inConstantName, + NVRenderShaderProgram &inShader) + : NVRenderCachedShaderPropertyArray(qPrintable(inConstantName), inShader) + { + + } + + NVRenderCachedShaderPropertyArray(const char *inConstantName, + NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_Constant(nullptr) + { + memset(m_array, 0, sizeof(m_array)); + NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); + if (theConstant) { + if (theConstant->m_ElementCount > 1 && theConstant->m_ElementCount <= size && + theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + m_Constant = theConstant; + } else { + // Property types do not match, this probably indicates that the shader changed + // while the code creating this object did not change. + QT3DS_ASSERT(false); + } + } + } + + NVRenderCachedShaderPropertyArray() + : m_Shader(nullptr) + , m_Constant(nullptr) + { + memset(m_array, 0, sizeof(m_array)); + } + + void Set(int count) + { + if (m_Constant) + m_Shader->SetPropertyValue(m_Constant, (TDataType*)m_array, qMin(size, count)); + } + + bool IsValid() const { return m_Constant != 0; } + }; + + // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe + // way. + template + struct NVRenderCachedShaderBuffer + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + TDataType m_ShaderBuffer; ///< poiner to shader buffer object + + NVRenderCachedShaderBuffer(const char *inShaderBufferName, NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_ShaderBuffer(NULL) + { + TDataType theShaderBuffer = + static_cast(inShader.GetShaderBuffer(inShaderBufferName)); + if (theShaderBuffer) { + m_ShaderBuffer = theShaderBuffer; + } + } + NVRenderCachedShaderBuffer() + : m_Shader(NULL) + , m_ShaderBuffer(NULL) + { + } + + void Set() + { + if (m_ShaderBuffer) { + m_ShaderBuffer->Validate(m_Shader); + m_ShaderBuffer->Update(); + m_ShaderBuffer->BindToProgram(m_Shader); + } + } + + bool IsValid() const { return m_ShaderBuffer != 0; } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp new file mode 100644 index 00000000..ab632189 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderStorageBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + NVRenderStorageBuffer::NVRenderStorageBuffer(NVRenderContextImpl &context, + CRegisteredString bufferName, size_t size, + NVRenderBufferUsageType::Enum usageType, + NVDataRef data, NVRenderDataBuffer *pBuffer) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Storage, usageType, data) + , m_Name(bufferName) + , m_WrappedBuffer(pBuffer) + , m_Dirty(true) + { + QT3DS_ASSERT(context.IsStorageBufferSupported()); + + if (pBuffer) + pBuffer->addRef(); + } + + NVRenderStorageBuffer::~NVRenderStorageBuffer() + { + if (m_WrappedBuffer) + m_WrappedBuffer->release(); + + m_Context.BufferDestroyed(*this); + } + + void NVRenderStorageBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + if (m_WrappedBuffer) + m_WrappedBuffer->Bind(); + else + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderStorageBuffer::BindToShaderProgram(QT3DSU32 index) + { + m_Backend->ProgramSetStorageBuffer( + index, (m_WrappedBuffer) ? m_WrappedBuffer->GetBuffertHandle() : m_BufferHandle); + } + + void NVRenderStorageBuffer::Update() + { + // we only update the buffer if it is dirty and we actually have some data + if (m_Dirty && m_BufferData.size()) { + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, + m_BufferData.begin()); + m_Dirty = false; + } + } + + void NVRenderStorageBuffer::UpdateData(QT3DSI32 offset, NVDataRef data) + { + // we only update the buffer if it is not just a wrapper + if (!m_WrappedBuffer) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, + data.begin() + offset); + } + + NVRenderStorageBuffer * + NVRenderStorageBuffer::Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderStorageBuffer *retval = NULL; + + if (context.IsStorageBufferSupported()) { + CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); + QT3DSU32 cbufSize = sizeof(NVRenderStorageBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "StorageBuffer"); + retval = new (newMem) NVRenderStorageBuffer( + context, theBufferName, size, usageType, + toDataRef(const_cast(bufferData.begin()), bufferData.size()), pBuffer); + } else { + QString errorMsg = QObject::tr("Shader storage buffers are not supported: %1") + .arg(bufferName); + qCCritical(INVALID_OPERATION) << errorMsg; + QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h new file mode 100644 index 00000000..fefe6b08 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + class NVRenderVertexBuffer; + + ///< Constant (uniform) buffer representation + class NVRenderStorageBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] bufferName Name of the buffer. Must match the name used in programs + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * @param[in] pBuffer Pointer to the buffer + * + * @return No return. + */ + NVRenderStorageBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, + size_t size, NVRenderBufferUsageType::Enum usageType, + NVDataRef data, NVRenderDataBuffer *pBuffer = NULL); + + ///< destructor + virtual ~NVRenderStorageBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief bind the buffer to a shader program + * + * @param[in] index Index of the constant buffer within the program + * + * @return no return. + */ + virtual void BindToShaderProgram(QT3DSU32 index); + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief update a piece of memory directly within the storage buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 (430) layout which guarantees a specific layout behavior across + *all HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into storage buffer + * @param[in] data pointer to data + * + * @return no return + */ + void UpdateData(QT3DSI32 offset, NVDataRef data); + + /** + * @brief get the buffer name + * + * @return the buffer name + */ + CRegisteredString GetBufferName() const { return m_Name; } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + /** + * @brief create a NVRenderStorageBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the buffer object or NULL + */ + static NVRenderStorageBuffer *Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData, + NVRenderDataBuffer *pBuffer); + + private: + CRegisteredString m_Name; ///< buffer name + NVRenderDataBuffer *m_WrappedBuffer; ///< pointer to wrapped buffer + bool m_Dirty; ///< true if buffer is dirty + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderSync.cpp b/src/Runtime/Source/render/Qt3DSRenderSync.cpp new file mode 100644 index 00000000..02d153a6 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSync.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSync.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderSync::NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_SyncHandle(NULL) + { + } + + NVRenderSync::~NVRenderSync() + { + if (m_SyncHandle) + m_Backend->ReleaseSync(m_SyncHandle); + } + + void NVRenderSync::Sync() + { + // On every sync call we need to create a new sync object + // A sync object can only be used once + + // First delete the old object + // We can safely do this because it is actually not deleted until + // it is unused + if (m_SyncHandle) + m_Backend->ReleaseSync(m_SyncHandle); + + m_SyncHandle = + m_Backend->CreateSync(NVRenderSyncType::GpuCommandsComplete, NVRenderSyncFlags()); + } + + void NVRenderSync::Wait() + { + // wait until the sync object is signaled or a timeout happens + if (m_SyncHandle) + m_Backend->WaitSync(m_SyncHandle, NVRenderCommandFlushFlags(), 0); + } + + NVRenderSync *NVRenderSync::Create(NVRenderContextImpl &context) + { + if (!context.IsCommandSyncSupported()) + return NULL; + + NVRenderSync *retval = QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderSync)(context, context.GetFoundation()); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderSync.h b/src/Runtime/Source/render/Qt3DSRenderSync.h new file mode 100644 index 00000000..9dfeb28a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSync.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SYNC_H +#define QT3DS_RENDER_SYNC_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + class NVRenderBackend; + + ///< Base class + class NVRenderSync : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendSyncObject m_SyncHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd); + + virtual ~NVRenderSync(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Get sync type + * + * @return Return query type + */ + virtual NVRenderSyncType::Enum GetSyncType() const + { + return NVRenderSyncType::GpuCommandsComplete; + } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief Create a sync object and place it in command stream. + * Note every syncobject can only be used once. + * This function creates a new sync object on ever call + * and deletes the previous one + * + * @return no return. + */ + virtual void Sync(); + + /** + * @brief Wait for a sync to be signaled + * Note this blocks until the sync is signaled + * + * @return no return. + */ + virtual void Wait(); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendSyncObject GetSyncHandle() const + { + return m_SyncHandle; + } + + /* + * @brief static creation function + * + * @return a sync object on success + */ + static NVRenderSync *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp new file mode 100644 index 00000000..7a0fd897 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderTessellationShader.h" + +namespace qt3ds { +namespace render { + + NVRenderTessControlShader::NVRenderTessControlShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef source, + bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateTessControlShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderTessControlShader::~NVRenderTessControlShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseTessControlShader(m_ShaderHandle); + } + } + + NVRenderTessEvaluationShader::NVRenderTessEvaluationShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef source, + bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = + m_Backend->CreateTessEvaluationShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderTessEvaluationShader::~NVRenderTessEvaluationShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseTessEvaluationShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h new file mode 100644 index 00000000..b69e56b1 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TESSELLATION_SHADER_H +#define QT3DS_RENDER_TESSELLATION_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a tessellation control shader + class NVRenderTessControlShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderTessControlShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram); + + /// @brief destructor + ~NVRenderTessControlShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTessControlShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendTessControlShaderObject + m_ShaderHandle; ///< opaque backend handle + }; + + ///< This class represents a tessellation evaluation shader + class NVRenderTessEvaluationShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderTessEvaluationShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram); + + /// @brief destructor + ~NVRenderTessEvaluationShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTessEvaluationShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp b/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp new file mode 100644 index 00000000..c5ea4750 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTexture2D::NVRenderTexture2D(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : NVRenderTextureBase(context, fnd, texTarget) + , m_Width(0) + , m_Height(0) + { + } + + NVRenderTexture2D::~NVRenderTexture2D() { m_Context.TextureDestroyed(*this); } + + STextureDetails NVRenderTexture2D::GetTextureDetails() const + { + return STextureDetails(m_Width, m_Height, 0, m_SampleCount, m_Format); + } + + void NVRenderTexture2D::SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, + QT3DSU32 height, NVRenderTextureFormats::Enum format, + NVRenderTextureFormats::Enum formatDest) + { + QT3DS_ASSERT(m_TextureHandle); + + // check if we should compress this texture + + if (inMipLevel == 0) { + m_Width = width; + m_Height = height; + m_Format = format; + + // We re-use textures and this might have been a MSAA texture before + // for resue we must completely destroy the texture object and create a new one + // The same is true for immutable textures + if (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS || m_Immutable) { + m_Backend->ReleaseTexture(m_TextureHandle); + m_TexTarget = NVRenderTextureTargetType::Texture2D; + m_SampleCount = 1; + m_TextureHandle = m_Backend->CreateTexture(); + } + + if (NVRenderTextureFormats::isCompressedTextureFormat(formatDest)) { + bool compress = NVRenderTextureFormats::isUncompressedTextureFormat(format); + bool appropriateSizes = ((width % 4) || (height % 4)) == false; + + // we only compress multiple of 4 textures + if (compress && !appropriateSizes) + compress = false; + + if (compress) { + // This seems like a very dubious line here. If we are compressing then the + // image + // is really 1/4 the width and height? - CN + m_Width = width / 4; + m_Height = height / 4; + m_Format = formatDest; + } + } else if (NVRenderTextureFormats::isUncompressedTextureFormat(formatDest)) { + m_Format = formatDest; + } + } + + if (m_MaxMipLevel < inMipLevel) { + m_MaxMipLevel = inMipLevel; + } + + // get max size and check value + QT3DSU32 maxWidth, maxHeight; + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (width > maxWidth || height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + } + if (NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Backend->SetTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width, + height, 0, format, newBuffer.begin()); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) { + m_Backend->SetCompressedTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, format, + width, height, 0, newBuffer.size(), + newBuffer.begin()); + } + // Set our texture parameters to a default that will look the best + if (inMipLevel > 0) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + + void NVRenderTexture2D::SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum formaInternal, + NVRenderTextureFormats::Enum format, + NVDataRef dataBuffer) + { + QT3DS_ASSERT(m_TextureHandle); + + if (!m_Context.IsShaderImageLoadStoreSupported()) { + qCCritical(INVALID_OPERATION, "The extension Shader_Image_Load_Store is not supported"); + return; + } + + m_Width = width; + m_Height = height; + m_Format = formaInternal; + if (format == NVRenderTextureFormats::Unknown) + format = formaInternal; + + // get max size and check value + QT3DSU32 maxWidth, maxHeight; + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (width > maxWidth || height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + } + + if (inLevels < 1) { + qCCritical(INVALID_PARAMETER, "inLevels is less than 1 (%d)", inLevels); + } + + m_MaxMipLevel = inLevels - 1; // we count from 0 + + // only uncompressed formats are supported and no depth + if (NVRenderTextureFormats::isUncompressedTextureFormat(formaInternal)) { + m_Backend->CreateTextureStorage2D(m_TextureHandle, m_TexTarget, inLevels, formaInternal, + width, height); + + m_Immutable = true; + m_TexTarget = NVRenderTextureTargetType::Texture2D; + + if (dataBuffer.size() > 0) + m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, 0, 0, 0, width, height, + format, dataBuffer.begin()); + + if (inLevels > 1) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + } + + void NVRenderTexture2D::SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + QT3DS_ASSERT(m_MaxMipLevel == 0); + + m_TexTarget = NVRenderTextureTargetType::Texture2D_MS; + + QT3DSU32 maxWidth, maxHeight; + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (width > maxWidth || height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + } + + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)); + + m_Backend->SetMultisampledTextureData2D(m_TextureHandle, m_TexTarget, sampleCount, format, + width, height, true); + + m_Width = width; + m_Height = height; + m_SampleCount = sampleCount; + m_Format = format; + } + + void NVRenderTexture2D::SetTextureSubData(NVDataRef newBuffer, QT3DSU8 inMipLevel, + QT3DSU32 inXOffset, QT3DSU32 inYOffset, QT3DSU32 width, + QT3DSU32 height, NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + + if (!NVRenderTextureFormats::isUncompressedTextureFormat(format)) { + qCCritical(INVALID_PARAMETER, "Cannot set sub data for depth or compressed formats"); + QT3DS_ASSERT(false); + return; + } + QT3DSU32 subRectStride = width * NVRenderTextureFormats::getSizeofFormat(format); + if (newBuffer.size() < subRectStride * height) { + qCCritical(INVALID_PARAMETER, "Invalid sub rect buffer size"); + QT3DS_ASSERT(false); + return; + } + // nop + if (width == 0 || height == 0) + return; + + if (inXOffset + width > m_Width || inYOffset + height > m_Height) { + qCCritical(INVALID_PARAMETER, "Sub rect outside existing image bounds"); + QT3DS_ASSERT(false); + return; + } + + // not handled yet + QT3DS_ASSERT(!NVRenderTextureFormats::isDepthTextureFormat(format)); + + m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, inMipLevel, inXOffset, + inYOffset, width, height, format, newBuffer.begin()); + } + + void NVRenderTexture2D::GenerateMipmaps(NVRenderHint::Enum genType) + { + applyTexParams(); + m_Backend->GenerateMipMaps(m_TextureHandle, m_TexTarget, genType); + QT3DSU32 maxDim = (m_Width >= m_Height) ? m_Width : m_Height; + m_MaxMipLevel = static_cast(logf((float)maxDim) / logf(2.0f)); + // we never create more level than m_MaxLevel + m_MaxMipLevel = qt3ds::NVMin(m_MaxMipLevel, (QT3DSU32)m_MaxLevel); + } + + void NVRenderTexture2D::Bind() + { + m_TextureUnit = m_Context.GetNextTextureUnit(); + + m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); + + applyTexParams(); + applyTexSwizzle(); + } + + NVRenderTexture2D *NVRenderTexture2D::Create(NVRenderContextImpl &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTexture2D)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2D.h b/src/Runtime/Source/render/Qt3DSRenderTexture2D.h new file mode 100644 index 00000000..29c7c1b4 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2D.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTextureBase.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + class NVRenderTexture2D : public NVRenderTextureBase, public NVRenderImplemented + { + + private: + QT3DSU32 m_Width; ///< texture width + QT3DSU32 m_Height; ///< texture height + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTexture2D( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D); + + virtual ~NVRenderTexture2D(); + + // Get the texture details for mipmap level 0 if it was set. + STextureDetails GetTextureDetails() const override; + + /** + * @brief Create GL texture object and upload data + * + * @param[in] newBuffer Texture data for level 0 + * @param[in] inMipLevel Texture level count + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] format Texture data format + * @param[in] formaInternal Texture internal format + * + * @return No return. + */ + virtual void SetTextureData( + NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format, + NVRenderTextureFormats::Enum formaInternal = NVRenderTextureFormats::Unknown); + + /** + * @brief Create memory storage for a texture object + * This create a texture storage which is immutable in size and format + * Use this for textures used within compute shaders + * + * @param[in] inLevels Texture level count + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] formaInternal Texture internal format + * @param[in] format Texture data format of dataBuffer + * @param[in] dataBuffer Texture data for level 0 + * + * @return No return. + */ + virtual void + SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum formaInternal, + NVRenderTextureFormats::Enum format = NVRenderTextureFormats::Unknown, + NVDataRef dataBuffer = NVDataRef()); + + virtual void SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format); + + bool IsMultisampleTexture() const override + { + return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS); + } + QT3DSU32 GetSampleCount() const override { return m_SampleCount; } + bool IsImmutableTexture() const override { return m_Immutable; } + + // Update a sub-rect of the image. newBuffer is expected to be a continguous subrect of the + // image. + virtual void SetTextureSubData(NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 inXOffset, + QT3DSU32 inYOffset, QT3DSU32 inSubImageWidth, + QT3DSU32 inSubImageHeight, NVRenderTextureFormats::Enum format); + // Generate a set of mipmaps from mipLevel( 0 ). Uses the graphis layer to do this if + // possible + // glGenerateMipmap + virtual void GenerateMipmaps(NVRenderHint::Enum genType = NVRenderHint::Nicest); + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + void Bind() override; + + QT3DSU32 GetNumMipmaps() override { return m_MaxMipLevel; } + + /** + * @brief Query if texture needs coordinate swizzle + * + * @return texture swizzle mode + */ + NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() override + { + // if our backend supports hardware texture swizzle then there is no need for a shader + // swizzle + return (m_Backend->GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::TexSwizzle)) + ? NVRenderTextureSwizzleMode::NoSwizzle + : m_Backend->GetTextureSwizzleMode(m_Format); + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_TextureHandle); + } + + static NVRenderTexture2D *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp new file mode 100644 index 00000000..fc0dfa45 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "render/Qt3DSRenderTexture2DArray.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTexture2DArray::NVRenderTexture2DArray(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : NVRenderTextureBase(context, fnd, texTarget) + , m_Width(0) + , m_Height(0) + , m_Slices(0) + { + } + + NVRenderTexture2DArray::~NVRenderTexture2DArray() { m_Context.TextureDestroyed(*this); } + + void NVRenderTexture2DArray::SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, + QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + + if (inMipLevel == 0) { + m_Width = width; + m_Height = height; + m_Slices = slices; + m_Format = format; + m_MaxMipLevel = inMipLevel; + } + + if (m_MaxMipLevel < inMipLevel) { + m_MaxMipLevel = inMipLevel; + } + + // get max size and check value + QT3DSI32 theMaxLayerSize, theMaxSize; + m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxSize); + m_Backend->GetRenderBackendValue( + NVRenderBackend::NVRenderBackendQuery::MaxTextureArrayLayers, &theMaxLayerSize); + if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize + || slices > (QT3DSU32)theMaxLayerSize) { + qCCritical(INVALID_OPERATION, + "Width or height or Slices is greater than max texture size (%d, %d, %d)", + theMaxSize, theMaxSize, theMaxLayerSize); + } + + // currently we do not support compressed texture arrays + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)); + + if (NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Backend->SetTextureData3D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width, + height, slices, 0, format, newBuffer.begin()); + } + + // Set our texture parameters to a default that will look the best + if (inMipLevel > 0) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + + STextureDetails NVRenderTexture2DArray::GetTextureDetails() const + { + return STextureDetails(m_Width, m_Height, m_Slices, m_SampleCount, m_Format); + } + + void NVRenderTexture2DArray::Bind() + { + m_TextureUnit = m_Context.GetNextTextureUnit(); + + m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); + + applyTexParams(); + applyTexSwizzle(); + } + + NVRenderTexture2DArray *NVRenderTexture2DArray::Create(NVRenderContextImpl &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTexture2DArray)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h new file mode 100644 index 00000000..30ed6dbb --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTextureBase.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + class QT3DS_AUTOTEST_EXPORT NVRenderTexture2DArray : public NVRenderTextureBase + { + private: + QT3DSU32 m_Width; ///< texture width + QT3DSU32 m_Height; ///< texture height + QT3DSU32 m_Slices; ///< texture slices + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTexture2DArray( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D_Array); + + virtual ~NVRenderTexture2DArray(); + + /** + * @brief constructor + * + * @param[in] newBuffer Pointer to pixel buffer + * @param[in] inMipLevel Pointer to foundation + * @param[in] width Texture target + * @param[in] height Texture target + * @param[in] slices Texture target + * @param[in] format Texture target + * + * @return No return. + */ + void SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height, + QT3DSU32 slices, NVRenderTextureFormats::Enum format); + + // Get the texture details for mipmap level 0 if it was set. + STextureDetails GetTextureDetails() const override; + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + void Bind() override; + + /** + * @brief create a texture array object + * + * + * @ return a texture array object + */ + static NVRenderTexture2DArray *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp b/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp new file mode 100644 index 00000000..d055d72c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "render/Qt3DSRenderTextureBase.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTextureBase::NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_TextureHandle(NULL) + , m_TextureUnit(QT3DS_MAX_U32) + , m_SamplerParamsDirty(true) + , m_TexStateDirty(false) + , m_SampleCount(1) + , m_Format(NVRenderTextureFormats::Unknown) + , m_TexTarget(texTarget) + , m_BaseLevel(0) + , m_MaxLevel(1000) + , m_MaxMipLevel(0) + , m_Immutable(false) + { + m_TextureHandle = m_Backend->CreateTexture(); + m_Sampler = QT3DS_NEW(m_Context.GetFoundation().getAllocator(), + NVRenderTextureSampler)(context, context.GetFoundation()); + } + + NVRenderTextureBase::~NVRenderTextureBase() + { + if (m_Sampler) + QT3DS_FREE(m_Context.GetFoundation().getAllocator(), m_Sampler); + if (m_TextureHandle) + m_Backend->ReleaseTexture(m_TextureHandle); + } + + void NVRenderTextureBase::SetBaseLevel(QT3DSI32 value) + { + if (m_BaseLevel != value) { + m_BaseLevel = value; + m_TexStateDirty = true; + } + } + + void NVRenderTextureBase::SetMaxLevel(QT3DSI32 value) + { + if (m_MaxLevel != value) { + m_MaxLevel = value; + m_TexStateDirty = true; + } + } + + void NVRenderTextureBase::SetMinFilter(NVRenderTextureMinifyingOp::Enum value) + { + if (m_Sampler->m_MinFilter != value) { + m_Sampler->m_MinFilter = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetMagFilter(NVRenderTextureMagnifyingOp::Enum value) + { + if (m_Sampler->m_MagFilter != value) { + m_Sampler->m_MagFilter = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureWrapS(NVRenderTextureCoordOp::Enum value) + { + if (m_Sampler->m_WrapS != value) { + m_Sampler->m_WrapS = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureWrapT(NVRenderTextureCoordOp::Enum value) + { + if (m_Sampler->m_WrapT != value) { + m_Sampler->m_WrapT = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureCompareMode(NVRenderTextureCompareMode::Enum value) + { + if (m_Sampler->m_CompareMode != value) { + m_Sampler->m_CompareMode = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value) + { + if (m_Sampler->m_CompareOp != value) { + m_Sampler->m_CompareOp = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::applyTexParams() + { + if (m_SamplerParamsDirty) { + m_Backend->UpdateSampler(m_Sampler->GetSamplerHandle(), m_TexTarget, + m_Sampler->m_MinFilter, m_Sampler->m_MagFilter, + m_Sampler->m_WrapS, m_Sampler->m_WrapT, m_Sampler->m_WrapR, + m_Sampler->m_MinLod, m_Sampler->m_MaxLod, m_Sampler->m_LodBias, + m_Sampler->m_CompareMode, m_Sampler->m_CompareOp); + + m_SamplerParamsDirty = false; + } + + if (m_TexStateDirty) { + m_Backend->UpdateTextureObject(m_TextureHandle, m_TexTarget, m_BaseLevel, m_MaxLevel); + m_TexStateDirty = false; + } + } + + void NVRenderTextureBase::applyTexSwizzle() + { + NVRenderTextureSwizzleMode::Enum theSwizzleMode = + m_Backend->GetTextureSwizzleMode(m_Format); + if (theSwizzleMode != m_Sampler->m_SwizzleMode) { + m_Sampler->m_SwizzleMode = theSwizzleMode; + m_Backend->UpdateTextureSwizzle(m_TextureHandle, m_TexTarget, theSwizzleMode); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureBase.h b/src/Runtime/Source/render/Qt3DSRenderTextureBase.h new file mode 100644 index 00000000..872a634e --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureBase.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + struct STextureDetails + { + QT3DSU32 m_Width; + QT3DSU32 m_Height; + QT3DSU32 m_Depth; + QT3DSU32 m_SampleCount; + NVRenderTextureFormats::Enum m_Format; + + STextureDetails(QT3DSU32 w, QT3DSU32 h, QT3DSU32 d, QT3DSU32 samples, NVRenderTextureFormats::Enum f) + : m_Width(w) + , m_Height(h) + , m_Depth(d) + , m_SampleCount(samples) + , m_Format(f) + { + } + STextureDetails() + : m_Width(0) + , m_Height(0) + , m_Depth(0) + , m_SampleCount(1) + , m_Format(NVRenderTextureFormats::Unknown) + { + } + }; + + class NVRenderTextureBase : public NVRefCounted + { + + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; ///< opaque backend handle + QT3DSU32 m_TextureUnit; ///< texture unit this texture should use + bool m_SamplerParamsDirty; ///< true if sampler state is dirty + bool m_TexStateDirty; ///< true if texture object state is dirty + QT3DSU32 m_SampleCount; ///< texture height + NVRenderTextureFormats::Enum m_Format; ///< texture format + NVRenderTextureTargetType::Enum m_TexTarget; ///< texture target + NVRenderTextureSampler *m_Sampler; ///< current texture sampler state + QT3DSI32 m_BaseLevel; ///< minimum lod specified + QT3DSI32 m_MaxLevel; ///< maximum lod specified + QT3DSU32 m_MaxMipLevel; ///< highest mip level + bool m_Immutable; ///< true if this is a immutable texture ( size and format ) + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget); + + virtual ~NVRenderTextureBase(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + virtual void SetMinFilter(NVRenderTextureMinifyingOp::Enum value); + virtual void SetMagFilter(NVRenderTextureMagnifyingOp::Enum value); + + virtual void SetBaseLevel(QT3DSI32 value); + virtual void SetMaxLevel(QT3DSI32 value); + + virtual void SetTextureWrapS(NVRenderTextureCoordOp::Enum value); + virtual void SetTextureWrapT(NVRenderTextureCoordOp::Enum value); + + virtual void SetTextureCompareMode(NVRenderTextureCompareMode::Enum value); + virtual void SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value); + + virtual void SetTextureUnit(QT3DSU32 unit) { m_TextureUnit = unit; } + virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; } + + // Get the texture details for mipmap level 0 if it was set. + virtual STextureDetails GetTextureDetails() const = 0; + + virtual bool IsMultisampleTexture() const + { + return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS); + } + virtual QT3DSU32 GetSampleCount() const { return m_SampleCount; } + virtual bool IsImmutableTexture() const { return m_Immutable; } + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + virtual void Bind() = 0; + + virtual QT3DSU32 GetNumMipmaps() { return m_MaxMipLevel; } + + /** + * @brief Query if texture needs coordinate swizzle + * + * @return texture swizzle mode + */ + virtual NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() + { + // if our backend supports hardware texture swizzle then there is no need for a shader + // swizzle + return (m_Backend->GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::TexSwizzle)) + ? NVRenderTextureSwizzleMode::NoSwizzle + : m_Backend->GetTextureSwizzleMode(m_Format); + } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle() + { + return m_TextureHandle; + } + + protected: + void applyTexParams(); + void applyTexSwizzle(); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp b/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp new file mode 100644 index 00000000..0919daf3 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2014 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "render/Qt3DSRenderTextureCube.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTextureCube::NVRenderTextureCube(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : NVRenderTextureBase(context, fnd, texTarget) + , m_Width(0) + , m_Height(0) + { + } + + NVRenderTextureCube::~NVRenderTextureCube() { m_Context.TextureDestroyed(*this); } + + void NVRenderTextureCube::SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, + NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, + QT3DSU32 height, NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + QT3DS_ASSERT(inFace != NVRenderTextureCubeFaces::InvalidFace); + + if (inMipLevel == 0) { + m_Width = width; + m_Height = height; + m_Format = format; + m_MaxMipLevel = inMipLevel; + } + + if (m_MaxMipLevel < inMipLevel) { + m_MaxMipLevel = inMipLevel; + } + + // get max size and check value + QT3DSI32 theMaxSize; + m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxSize); + if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + theMaxSize, theMaxSize); + } + + NVRenderTextureTargetType::Enum outTarget = + static_cast((int)m_TexTarget + (int)inFace); + if (NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Backend->SetTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, format, width, + height, 0, format, newBuffer.begin()); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) { + m_Backend->SetCompressedTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, + format, width, height, 0, newBuffer.size(), + newBuffer.begin()); + } + + // Set our texture parameters to a default that will look the best + if (inMipLevel > 0) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + + STextureDetails NVRenderTextureCube::GetTextureDetails() const + { + return STextureDetails(m_Width, m_Height, 6, m_SampleCount, m_Format); + } + + void NVRenderTextureCube::Bind() + { + m_TextureUnit = m_Context.GetNextTextureUnit(); + + m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); + + applyTexParams(); + applyTexSwizzle(); + } + + NVRenderTextureCube *NVRenderTextureCube::Create(NVRenderContextImpl &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTextureCube)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureCube.h b/src/Runtime/Source/render/Qt3DSRenderTextureCube.h new file mode 100644 index 00000000..7310d44d --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureCube.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2014 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTextureBase.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + class NVRenderTextureCube : public NVRenderTextureBase + { + private: + QT3DSU32 m_Width; ///< texture width (per face) + QT3DSU32 m_Height; ///< texture height (per face) + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTextureCube( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::TextureCube); + + virtual ~NVRenderTextureCube(); + + /** + * @brief constructor + * + * @param[in] newBuffer Pointer to pixel buffer + * @param[in] inMipLevel Pointer to foundation + * @param[in] width Texture target + * @param[in] height Texture target + * @param[in] slices Texture target + * @param[in] format Texture target + * + * @return No return. + */ + void SetTextureData(NVDataRef newBuffer, QT3DSU8 inMipLevel, + NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format); + + // Get the texture details for mipmap level 0 if it was set. + STextureDetails GetTextureDetails() const override; + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + void Bind() override; + + /** + * @brief create a texture array object + * + * + * @ return a texture array object + */ + static NVRenderTextureCube *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp new file mode 100644 index 00000000..4184436a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderTimerQuery.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + NVRenderTimerQuery::NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd) + : NVRenderQueryBase(context, fnd) + { + } + + NVRenderTimerQuery::~NVRenderTimerQuery() {} + + void NVRenderTimerQuery::Begin() + { + m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Timer); + } + + void NVRenderTimerQuery::End() { m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Timer); } + + void NVRenderTimerQuery::GetResult(QT3DSU32 *params) + { + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); + } + + void NVRenderTimerQuery::GetResult(QT3DSU64 *params) + { + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); + } + + void NVRenderTimerQuery::SetTimerQuery() { m_Backend->SetQueryTimer(m_QueryHandle); } + + NVRenderTimerQuery *NVRenderTimerQuery::Create(NVRenderContextImpl &context) + { + if (!context.IsTimerQuerySupported()) + return NULL; + + NVRenderTimerQuery *retval = QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTimerQuery)(context, context.GetFoundation()); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h new file mode 100644 index 00000000..f909f374 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TIMER_QUERY_H +#define QT3DS_RENDER_TIMER_QUERY_H + +#include "render/Qt3DSRenderQueryBase.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + class NVRenderTimerQuery : public NVRenderQueryBase + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd); + + ///< destructor + ~NVRenderTimerQuery(); + + /** + * @brief Get query type + * + * @return Return query type + */ + NVRenderQueryType::Enum GetQueryType() const override + { + return NVRenderQueryType::Timer; + } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief begin a query + * + * @return no return. + */ + void Begin() override; + + /** + * @brief end a query + * + * @return no return. + */ + void End() override; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + void GetResult(QT3DSU32 *params) override; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + virtual void GetResult(QT3DSU64 *params); + + /** + * @brief Places an absolute timer query into the render queue + * The result can be queried with GetResult + * + * @return no return. + */ + virtual void SetTimerQuery(); + + /* + * @brief static creation function + * + * * @return a timer query object on success + */ + static NVRenderTimerQuery *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp new file mode 100644 index 00000000..89d6204e --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderVertexBuffer::NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, + QT3DSU32 stride, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, + NVDataRef data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, bindFlags, usageType, data) + , m_Stride(stride) + { + QT3DS_ASSERT(m_Stride); + } + + NVRenderVertexBuffer::~NVRenderVertexBuffer() { m_Context.BufferDestroyed(*this); } + + void NVRenderVertexBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + NVRenderVertexBuffer *NVRenderVertexBuffer::Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + size_t size, QT3DSU32 stride, + NVConstDataRef bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + + QT3DSU32 vbufSize = sizeof(NVRenderVertexBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), vbufSize, "VertexBuffer"); + NVRenderVertexBuffer *retval = new (newMem) NVRenderVertexBuffer( + context, size, stride, NVRenderBufferBindValues::Vertex, usageType, + toDataRef(const_cast(bufferData.begin()), bufferData.size())); + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h new file mode 100644 index 00000000..914afe27 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderDrawable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + ///< Vertex buffer representation + class NVRenderVertexBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] entries Vertex buffer attribute layout entries + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return No return. + */ + NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, QT3DSU32 stride, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, NVDataRef data); + + ///< destructor + virtual ~NVRenderVertexBuffer(); + + /** + * @brief return vertex data stride + * + * @return data stride. + */ + virtual QT3DSU32 GetStride() const { return m_Stride; } + + /** + * @brief get vertex count + * + * @return vertex count + */ + virtual QT3DSU32 GetNumVertexes() const + { + QT3DS_ASSERT((m_BufferCapacity % m_Stride) == 0); + return m_BufferCapacity / m_Stride; + } + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast(m_BufferHandle); + } + + // No stride means that stride is calculated from the size of last entry found via entry + // offset + // Leaves this buffer temporarily bound. + static NVRenderVertexBuffer *Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, size_t size, + QT3DSU32 stride, NVConstDataRef bufferData); + + private: + QT3DSU32 m_Stride; ///< veretex data stride + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp b/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp new file mode 100644 index 00000000..3a53ad50 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderVertexShader.h" + +namespace qt3ds { +namespace render { + + NVRenderVertexShader::NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateVertexShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderVertexShader::~NVRenderVertexShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseVertexShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexShader.h b/src/Runtime/Source/render/Qt3DSRenderVertexShader.h new file mode 100644 index 00000000..0a96045b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_VERTEX_SHADER_H +#define QT3DS_RENDER_VERTEX_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a vertex shader + class NVRenderVertexShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef source, bool binaryProgram); + + /// @brief destructor + ~NVRenderVertexShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendVertexShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendVertexShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h b/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h new file mode 100644 index 00000000..12de5d88 --- /dev/null +++ b/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h @@ -0,0 +1,2245 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_H +#define QT3DS_RENDER_BACKEND_H + +/// @file Qt3DSRenderBackend.h +/// NVRender backend definition. + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSNoCopy.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSBounds3.h" +#include + +#include + +namespace qt3ds { +namespace render { + +#define HandleToID_cast(staticType, dynamicType, handle) \ + static_cast(reinterpret_cast(handle)) + + class NVRenderBackend : public NVRefCounted, public NoCopy + { + + public: + /// opaque buffer object handle + typedef struct _NVRenderBackendBufferObject *NVRenderBackendBufferObject; + /// opaque attribute layout object handle + typedef struct _NVRenderBackendAttribLayoutObject *NVRenderBackendAttribLayoutObject; + /// opaque input assembler object handle + typedef struct _NVRenderBackendInputAssemblerObject *NVRenderBackendInputAssemblerObject; + /// opaque texture object handle + typedef struct _NVRenderBackendTextureObject *NVRenderBackendTextureObject; + /// opaque sampler object handle + typedef struct _NVRenderBackendSamplerObject *NVRenderBackendSamplerObject; + /// opaque renderbuffer object handle + typedef struct _NVRenderBackendRenderbufferObject *NVRenderBackendRenderbufferObject; + /// opaque framebuffer object handle + typedef struct _NVRenderBackendRenderTargetObject *NVRenderBackendRenderTargetObject; + /// opaque vertex shader object handle + typedef struct _NVRenderBackendVertexShaderObject *NVRenderBackendVertexShaderObject; + /// opaque fragment shader object handle + typedef struct _NVRenderBackendFragmentShaderObject *NVRenderBackendFragmentShaderObject; + /// opaque tesselation control shader object handle + typedef struct _NVRenderBackendTessControlShaderObject + *NVRenderBackendTessControlShaderObject; + /// opaque tesselation evaluation shader object handle + typedef struct _NVRenderBackendTessEvaluationShaderObject + *NVRenderBackendTessEvaluationShaderObject; + /// opaque geometry shader object handle + typedef struct _NVRenderBackendGeometryShaderObject *NVRenderBackendGeometryShaderObject; + /// opaque compute shader object handle + typedef struct _NVRenderBackendComputeShaderObject *NVRenderBackendComputeShaderObject; + /// opaque shader program object handle + typedef struct _NVRenderBackendShaderProgramObject *NVRenderBackendShaderProgramObject; + /// opaque depth stencil state object handle + typedef struct _NVRenderBackendDepthStencilStateObject + *NVRenderBackendDepthStencilStateObject; + /// opaque rasterizer state object handle + typedef struct _NVRenderBackendRasterizerStateObject *NVRenderBackendRasterizerStateObject; + /// opaque query object handle + typedef struct _NVRenderBackendQueryObject *NVRenderBackendQueryObject; + /// opaque sync object handle + typedef struct _NVRenderBackendSyncObject *NVRenderBackendSyncObject; + /// opaque sync object handle + typedef struct _NVRenderBackendProgramPipeline *NVRenderBackendProgramPipeline; + /// opaque sync object handle + typedef struct _NVRenderBackendPathObject *NVRenderBackendPathObject; + + // backend capability caps + typedef struct + { + enum Enum { + ConstantBuffer, ///< Constant buffer support query + DepthStencilTexture, ///< depth stencil texture format suport query + DxtImages, ///< DXT image support query + FpRenderTarget, ///< render to floating point target support query + MsTexture, ///< Multisample texture support query + TexSwizzle, ///< Texture swizzle support query + FastBlits, ///< Hardware supports fast blits + Tessellation, ///< Hardware supports tessellation + Compute, ///< Hardware supports compute shader + Geometry, ///< Hardware supports geometry shader + SampleQuery, ///< Hardware supports query calls of type samples + TimerQuery, ///< Hardware supports query calls of type timer + CommandSync, ///< Hardware supports command sync object + TextureArray, ///< Hardware supports texture arrays + StorageBuffer, ///< Hardware supports shader storage buffers + AtomicCounterBuffer, ///< Hardware supports atomic counter buffers + ShaderImageLoadStore, ///< Hardware supports shader image load store operations + ProgramPipeline, ///< Driver supports separate programs + PathRendering, ///< Driver support path rendering + AdvancedBlend, ///< Driver supports advanced blend modes + BlendCoherency, ///< Hardware supports blend coherency + gpuShader5, // for high precision sampling + AdvancedBlendKHR, ///< Driver supports advanced blend modes + VertexArrayObject, + StandardDerivatives, + TextureLod + }; + } NVRenderBackendCaps; + + // backend queries + typedef struct + { + enum Enum { + MaxTextureSize, ///< Return max supported texture size + MaxTextureArrayLayers, ///< Return max supported layer count for texture arrays + MaxConstantBufferSlots, ///< Return max supported constant buffe slots for a single + ///shader stage + MaxConstantBufferBlockSize ///< Return max supported size for a single constant + ///buffer block + }; + } NVRenderBackendQuery; + + /// backend interface + + /** + * @brief get the backend type + * + * @return true backend type + */ + virtual NVRenderContextType GetRenderContextType() const = 0; + + /** + * @brief get the version of the shading language + * @return version string, must be copied by clients to be retained. + */ + virtual const char *GetShadingLanguageVersion() = 0; + + /** + * @brief get maximum supported texture image units that + * can be used to access texture maps from the vertex shader and the fragment processor + *combined. + * + * @return max texture size + */ + virtual QT3DSU32 GetMaxCombinedTextureUnits() = 0; + + /** + * @brief query Backend capabilities + * + * @param[in] inCap CAPS flag to query + * @ConstantBuffer, @DepthStencilTexture, ... + * + * @return true if supported + */ + virtual bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const = 0; + + /** + * @brief query Backend values + * + * @param[in] inQuery Query flag to get value for + * @MaxTextureSize, @MaxTextureArrayLayers, + *... + * @param[in/out] params the query result is stored here + * + * @return no return + */ + virtual void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, + QT3DSI32 *params) const = 0; + + /** + * @brief query for bit depth of the depth buffer + * + * @return depth buffer bitplanes + */ + virtual QT3DSU32 GetDepthBits() const = 0; + + /** + * @brief query for bit depth of the stencil buffer + * + * @return stencil buffer bitplanes + */ + virtual QT3DSU32 GetStencilBits() const = 0; + + /* + * @brief set a backend rende state + * + * @param[in] bEnable enable/disable state + * @param[in] value type of state + * + * @return no return + */ + virtual void SetRenderState(bool bEnable, const NVRenderState::Enum value) = 0; + + /** + * @brief get a backend rende state + * + * @param[in] value type of state + * + * @return true if state enabled otherwise false + */ + virtual bool GetRenderState(const NVRenderState::Enum value) = 0; + + /** + * @brief get current depth function + * + * @return active depth function + */ + virtual NVRenderBoolOp::Enum GetDepthFunc() = 0; + + /** + * @brief create a depth stencil state object + * + * @param[in] enableDepth enable depth test + * @param[in] depthMask enable depth writes + * @param[in] depthFunc depth compare function + * @param[in] enableStencil enable stencil test + * @param[in] stencilFuncFront stencil setup front faces + * @param[in] stencilFuncBack stencil setup back faces + * @param[in] depthStencilOpFront depth/stencil operations front faces + * @param[in] depthStencilOpBack depth/stencil operations back faces + * + * @return opaque handle to state object + */ + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) = 0; + + /** + * @brief release a depth stencil state object + * + * @param[in] depthStencilState pointer to state object + * + * @return none + */ + virtual void + ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; + + /** + * @brief create a rasterizer state object + * + * @param[in] depthBias any othe value than 0 enables depth bias + * @param[in] depthScale any othe value than 0 enables depth scale + * @param[in] cullFace select face to cull front or back + * + * @return opaque handle to state object + */ + virtual NVRenderBackendRasterizerStateObject + CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) = 0; + + /** + * @brief release a rasterizer state object + * + * @param[in] rasterizerState pointer to state object + * + * @return none + */ + virtual void + ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; + + /** + * @brief set depth stencil state + * + * @param[in] depthStencilState pointer to state object + * + * @return none + */ + virtual void + SetDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; + + /** + * @brief set rasterizer state + * + * @param[in] rasterizerState pointer to state object + * + * @return none + */ + virtual void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; + + /** + * @brief set current depth function + * + * @param[in] func type of function + * + * @return no return + */ + virtual void SetDepthFunc(const NVRenderBoolOp::Enum func) = 0; + + /** + * @brief query if depth write is enabled + * + * @return true if enabled + */ + virtual bool GetDepthWrite() = 0; + + /** + * @brief enable / disable depth writes + * + * @param[in] bEnable true for enable + * + * @return no return + */ + virtual void SetDepthWrite(bool bEnable) = 0; + + /** + * @brief enable / disable color channel writes + * + * @param[in] bRed true for enable red channel + * @param[in] bGreen true for enable green channel + * @param[in] bBlue true for enable blue channel + * @param[in] bAlpha true for enable alpha channel + * + * @return no return + */ + virtual void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + + /** + * @brief enable / disable multisample rendering + * + * @param[in] bEnable true for enable + * + * @return no return + */ + virtual void SetMultisample(bool bEnable) = 0; + + /** + * @brief query blend functions + * + * @param[out] pBlendFuncArg blending functions + * + * @return no return + */ + virtual void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) = 0; + + /** + * @brief set blend functions + * + * @param[in] pBlendFuncArg blending functions + * + * @return no return + */ + virtual void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) = 0; + + /** + * @brief set blend equation + * + * @param[in] pBlendEquArg blending equation + * + * @return no return + */ + virtual void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) = 0; + + /** + * @brief guarantee blend coherency + * + * + * @return no return + */ + virtual void SetBlendBarrier(void) = 0; + + /** + * @brief query scissor rectangle + * + * @param[out] pRect contains scissor rect + * + * @return no return + */ + virtual void GetScissorRect(NVRenderRect *pRect) = 0; + + /** + * @brief set scissor rectangle + * + * @param[out] pRect contains scissor rect + * + * @return no return + */ + virtual void SetScissorRect(const NVRenderRect &rect) = 0; + + /** + * @brief query viewport rectangle + * + * @param[out] pRect contains viewport rect + * + * @return no return + */ + virtual void GetViewportRect(NVRenderRect *pRect) = 0; + + /** + * @brief set viewport rectangle + * + * @param[out] pRect contains viewport rect + * + * @return no return + */ + virtual void SetViewportRect(const NVRenderRect &rect) = 0; + + /** + * @brief query viewport rectangle + * + * @param[in] clearColor clear color + * + * @return no return + */ + virtual void SetClearColor(const QT3DSVec4 *pClearColor) = 0; + + /** + * @brief query viewport rectangle + * + * @param[in] flags clear flags + * + * @return no return + */ + virtual void Clear(NVRenderClearFlags flags) = 0; + + /** + * @brief create a buffer object + * + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + *application. + * + * @return The created buffer object or NULL if the creation failed. + */ + virtual NVRenderBackendBufferObject CreateBuffer(size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, + const void *hostPtr = NULL) = 0; + + /** + * @brief bind a buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * + * @return no return. + */ + virtual void BindBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) = 0; + + /** + * @brief Release a single buffer object + * + * @param[in] bo Pointer to buffer object + * + * @return no return. + */ + virtual void ReleaseBuffer(NVRenderBackendBufferObject bo) = 0; + + /** + * @brief update a whole buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] size Size of the data buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return no return. + */ + virtual void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t size, NVRenderBufferUsageType::Enum usage, + const void *data) = 0; + + /** + * @brief update a range of a buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] size Size of the data buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return no return. + */ + virtual void UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) = 0; + + /** + * @brief Get a pointer to the buffer data ( GL(ES) >= 3 only ) + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] offset Byte offset into the data buffer + * @param[in] length Byte length of mapping size + * @param[in] access Access of the buffer (e.g. read, write, ...) + * + * @return pointer to mapped data or null. + */ + virtual void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) = 0; + + /** + * @brief Unmap a previously mapped buffer ( GL(ES) >= 3 only ) + * This functions transfers the content to the hardware buffer + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * + * @return true if successful + */ + virtual bool UnmapBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) = 0; + + /** + * @brief Set a memory barrier + * + * @param[in] barriers Flags for barriers + * + * @return no return. + */ + virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; + + /** + * @brief create a query object + * + * @return The created query object or NULL if the creation failed. + */ + virtual NVRenderBackendQueryObject CreateQuery() = 0; + + /** + * @brief delete query objects + * + * @param[in] qo Handle to query object + * + * @return no return + */ + virtual void ReleaseQuery(NVRenderBackendQueryObject qo) = 0; + + /** + * @brief Start query recording + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * + * @return no return + */ + virtual void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; + + /** + * @brief End query recording + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * + * @return no return + */ + virtual void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; + + /** + * @brief Get a query result + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * @param[out] params Contains result of query regarding query type + * + * @return no return + */ + virtual void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) = 0; + + /** + * @brief Get a query result + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * @param[out] params Contains result of query regarding query type 64 bit returns + * + * @return no return + */ + virtual void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) = 0; + + /** + * @brief Record the GPU time using the query object + * + * @param[in] qo Handle to query object + * + * @return no return + */ + virtual void SetQueryTimer(NVRenderBackendQueryObject qo) = 0; + + /** + * @brief create a sync object and place it in the command queue + * + * @param[in] tpye Type to sync + * @param[in] syncFlags Currently unused + * + * @return The created sync object or NULL if the creation failed. + */ + virtual NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) = 0; + + /** + * @brief delete sync object + * + * @param[in] so Handle to sync object + * + * @return no return + */ + virtual void ReleaseSync(NVRenderBackendSyncObject so) = 0; + + /** + * @brief wait for sync object to be signaled + * + * @param[in] so Handle to sync object + * @param[in] syncFlags Currently unused + * @param[in] timeout Currently ignored + * + * @return no return + */ + virtual void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) = 0; + + /** + * @brief create a render target object + * + * + * @return The created render target object or NULL if the creation failed. + */ + virtual NVRenderBackendRenderTargetObject CreateRenderTarget() = 0; + + /** + * @brief Release a single render target object + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Attach a renderbuffer object to the framebuffer + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] rbo Pointer to renderbuffer object + * + * @return no return. + */ + virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) = 0; + + /** + * @brief Attach a texture object to the render target + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] to Pointer to texture object + * @param[in] target Attachment texture target + * + * @return no return. + */ + virtual void RenderTargetAttach( + NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) = 0; + + /** + * @brief Attach a texture object to the render target + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] to Pointer to texture object + * @param[in] level Texture mip level + * @param[in] layer Texture layer or slice + * + * @return no return. + */ + virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) = 0; + + /** + * @brief Make a render target active + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void SetRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Check if a render target is ready for render + * + * @param[in] rto Pointer to render target object + * + * @return true if usable. + */ + virtual bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Make a render target active for reading + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void SetReadTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Set active buffers for drawing + * + * @param[in] rto Pointer to render target object + * @param[in] inDrawBufferSet Pointer to array of enabled render targets + * + * @return no return. + */ + virtual void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) = 0; + + /** + * @brief Set active buffer for reading + * + * @param[in] rto Pointer to render target object + * @param[in] inReadFace Buffer to read from + * + * @return no return. + */ + virtual void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) = 0; + + /** + * @brief Copy framebuffer attachments. Source is set with SetReadTarget dest with + * SetRenderTarget + * + * @param[in] srcX0 Lower left X coord of source rectangle + * @param[in] srcY0 Lower left Y coord of source rectangle + * @param[in] srcX1 Upper right X coord of source rectangle + * @param[in] srcY1 Upper right Y coord of source rectangle + * @param[in] dstX0 Lower left X coord of dest rectangle + * @param[in] dstY0 Lower left Y coord of dest rectangle + * @param[in] dstX1 Upper right X coord of dest rectangle + * @param[in] dstY1 Upper right Y coord of dest rectangle + * @param[in] inDrawBufferSet pointer to array of enabled render targets + * @param[in] filter Copy filter method (NEAREST or LINEAR) + * + * @return no return. + */ + virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) = 0; + + /** + * @brief create a render buffer object + * + * @param[in] storageFormat Format of the buffer + * @param[in] width Buffer with + * @param[in] height Buffer height + * + * @return The created render buffer object or NULL if the creation failed. + */ + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) = 0; + + /** + * @brief Release a single renderbuffer object + * + * @param[in] bo Pointer to renderbuffer object + * + * @return no return. + */ + virtual void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) = 0; + + /** + * @brief resize a render buffer object + * + * @param[in] storageFormat Format of the buffer + * @param[in] width Buffer with + * @param[in] height Buffer height + * + * @return True on success + */ + virtual bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) = 0; + + /** + * @brief create a texture object + * + * @return The created texture object or NULL if the creation failed.. + */ + virtual NVRenderBackendTextureObject CreateTexture() = 0; + + /** + * @brief set texture data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief set texture data for the face of a Cube map + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target face + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief create a storage for a 2D texture including mip levels + * Note that this makes texture immutable in size and format + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] levels Texture mip level count + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * + * @return No return + */ + virtual void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) = 0; + + /** + * @brief set texture sub data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] xOffset Texture x offset + * @param[in] yOffset Texture y offset + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] border border + * @param[in] format format of texture + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture data for a Cubemap face + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture sub data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] xOffset Texture x offset + * @param[in] yOffset Texture y offset + * @param[in] width texture width + * @param[in] height texture height + * @param[in] format format of provided pixel data + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureSubData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief establish a multisampled 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D MS + * @param[in] samples Textures sample count + * @param[in] internalFormat Format of the texture + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] bool Fixed sample locations + * + * @return No return + */ + virtual void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) = 0; + + /** + * @brief set texture data for a 3D texture or 2D texture array + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] depth texture depth or slice count + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief generate mipmap levels + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D,... + * @param[in] hint How to generate mips (Nicest) + * + * @return No return + */ + virtual void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) = 0; + + /** + * @brief bind a texture object + * + * @param[in] to Pointer to texture object + * @param[in] target Where to bind this texture (e.g. 2D, 3D, ...) + * @param[in] unit Which unit to bind this texture + * + * @return no return. + */ + virtual void BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) = 0; + + /** + * @brief bind a image/texture object + * + * @param[in] to Pointer to texture object + * @param[in] unit Which unit to bind this texture + * @param[in] level Which level to bind + * @param[in] layered Bind layered texture (cube map, array,... ) + * @param[in] level Specify layer. Only valid of layered=false. + * @param[in] access Access mode ( read, write, read-write ) + * @param[in] format Texture format must be compatible with Image format + * + * @return no return. + */ + virtual void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum accessFlags, + NVRenderTextureFormats::Enum format) = 0; + + /** + * @brief Release a single texture object + * + * @param[in] to Pointer to buffer object + * + * @return no return. + */ + virtual void ReleaseTexture(NVRenderBackendTextureObject to) = 0; + + /** + * @brief query texture swizzle mode + * This is mainly for luminance, alpha replacement with R8 formats + * + * @param[in] inFormat input texture format to check + * + * @return texture swizzle mode + */ + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const = 0; + + /** + * @ brief create a sampler + * + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail example + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] + * + * @return The created sampler object or NULL if the creation failed. + */ + virtual NVRenderBackendSamplerObject CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; + + /** + * @ brief update a sampler + * + * @param[in] so Pointer to sampler object + * @param[in] target Texture target 2D, 3D + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail bias (unused) + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] (unused) + * + * @return No return + */ + virtual void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; + + /** + * @ brief Update a textures swizzle mode + * + * @param[in] so Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] swizzleMode Texture swizzle mode + * + * @return No return + */ + virtual void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) = 0; + + /** + * @ brief Update state belonging to a texture object + * + * @param[in] so Pointer to texture object + * @param[in] target Texture target 2D, 3D, Cube + * @param[in] baseLevel Texture base level + * @param[in] maxLevel Texture max level + * + * @return No return + */ + virtual void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) = 0; + + /** + * @brief Release a single sampler object + * + * @param[in] so Pointer to sampler object + * + * @return no return. + */ + virtual void ReleaseSampler(NVRenderBackendSamplerObject so) = 0; + + /** + * @brief create a attribute layout object + * + * @param[in] attribs Array off vertex attributes. + * + * @return The created attribute layout object or NULL if the creation failed. + */ + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef attribs) = 0; + + /** + * @brief Release a attribute layoutr object + * + * @param[in] ao Pointer to attribute layout object + * + * @return no return. + */ + virtual void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) = 0; + + /** + * @brief create a input assembler object + * + * @param[in] attribLayout Pointer to NVRenderBackendAttribLayoutObject object + * @param[in] buffers list of vertex buffers + * @param[in] indexBuffer index buffer object + * @param[in] strides list of strides of the buffer + * @param[in] offsets list of offsets into the buffer + * @param[in] patchVertexCount vertext count for a patch. Only valid for patch primitives + * + * @return The created input assembler object or NULL if the creation failed. + */ + virtual NVRenderBackendInputAssemblerObject + CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, + QT3DSU32 patchVertexCount) = 0; + + /** + * @brief Release a input assembler object + * + * @param[in] iao Pointer to attribute layout object + * + * @return no return. + */ + virtual void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) = 0; + + /** + * @brief Set a input assembler object. + * This setup the render engine vertex assmebly + * + * @param[in] iao Pointer to attribute layout object + * @param[in] po Pointer program object + * + * @return false if it fails. + */ + virtual bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Set the per patch vertex count + * + * @param[in] iao Pointer to attribute layout object + * @param[in] count Count of vertices per patch + * + * @return false if it fails. + */ + virtual void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) = 0; + + /** + * @brief create a vertex shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created vertex shader object or NULL if the creation failed. + */ + virtual NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef source, + eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a vertex shader object + * + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief create a fragment shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created vertex shader object or NULL if the creation failed. + */ + virtual NVRenderBackendFragmentShaderObject + CreateFragmentShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a fragment shader object + * + * @param[in] vso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief create a tessellation control shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created tessellation control shader object or NULL if the creation failed. + */ + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a tessellation control shader object + * + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief create a tessellation evaluation shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created tessellation evaluation shader object or NULL if the creation failed. + */ + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a tessellation evaluation shader object + * + * @param[in] tcso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void + ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief create a geometry shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created geometry shader object or NULL if the creation failed. + */ + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a geometry shader object + * + * @param[in] tcso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief create a compute shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created compute shader object or NULL if the creation failed. + */ + virtual NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef source, + eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a compute shader object + * + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief attach a vertex shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief detach a vertex shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief attach a fragment shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] fso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief detach a fragment shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] fso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief attach a tessellation control shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief detach a tessellation control shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief attach a tessellation evaluation shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief detach a tessellation evaluation shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief attach a geometry shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief detach a geometry shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief attach a compute shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief detach a compute shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief create a shader program object + * + * @param[in] isSeparable Tell the backend that this program is separable + * + * @return The created shader program object or NULL if the creation failed. + */ + virtual NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) = 0; + + /** + * @brief release a shader program object + * + * @param[in] po Pointer to shader program object + * + * @return No Return. + */ + virtual void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief link a shader program object + * + * @param[in] po Pointer to shader program object + * @param[in/out] errorMessage Pointer to copy the error message + * + * @return True if program is succesful linked. + */ + virtual bool LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) = 0; + + /** + * @brief Make a program current + * + * @param[in] po Pointer to shader program object + * + * @return No return + */ + virtual void SetActiveProgram(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief create a program pipeline object + * + * + * @return The created program pipeline object or NULL if the creation failed. + */ + virtual NVRenderBackendProgramPipeline CreateProgramPipeline() = 0; + + /** + * @brief release a program pipeline object + * + * @param[in] ppo Pointer to program pipeline object + * + * @return No Return. + */ + virtual void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; + + /** + * @brief Make a program pipeline current + * + * @param[in] ppo Pointer to program pipeline object + * + * @return No return + */ + virtual void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; + + /** + * @brief Make a program stage active for this pipeline + * + * @param[in] ppo Pointer to program pipeline object + * @param[in] flags Shader stage flags to which this po is bound to + * @param[in] po Pointer to shader program object + * + * @return No return + */ + virtual void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Runs a compute program + * + * @param[in] po Pointer to shader program object + * @param[in] numGroupsX The number of work groups to be launched in the X + * dimension + * @param[in] numGroupsY The number of work groups to be launched in the Y + * dimension + * @param[in] numGroupsZ The number of work groups to be launched in the Z + * dimension + * + * @return No return + */ + virtual void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; + + /** + * @brief Query constant count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active constant count + */ + virtual QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query constant buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active constant buffer count + */ + virtual QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query constant information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant ID + * @param[in] bufSize Max char for nameBuf + * @param[out] numElem Usually one unless for arrays + * @param[out] type Constant data type (QT3DSVec4, QT3DSVec3,...) + * @param[out] binding Unit binding point for samplers and images + * @param[out] nameBuf Name of the constant + * + * @return Return current constant location or -1 if not found + */ + virtual QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) = 0; + + /** + * @brief Query constant buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count ot parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current constant buffer location or -1 if not found + */ + virtual QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) = 0; + + /** + * @brief Query constant buffer param indices + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant buffer ID + * @param[out] indices Receives the indices of the uniforms within the + * constant buffer + * + * @return no return value + */ + virtual void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) = 0; + + /** + * @brief Query constant buffer param info by indices + * + * @param[in] po Pointer to shader program object + * @param[in] count Number of indices + * @param[in] indices The indices of the uniforms within the constant + * buffer + * @param[out] type Array of param types ( float ,int, ...) + * @param[out] size Array of param size + * @param[out] offset Array of param offsets within the constant buffer + * + * @return no return value + */ + virtual void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) = 0; + + /** + * @brief Bind program constant block + * + * @param[in] po Pointer to shader program object + * @param[in] blockIndex Constant block index returned by + * GetConstantBufferInfoByID + * @param[in] binding Block binding location which should be the same as index + * in ProgramSetConstantBlock + * + * @return No return + */ + virtual void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) = 0; + + /** + * @brief Bind constant buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to constant buffer object + * + * @return No return + */ + virtual void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Query storage buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active storage buffer count + */ + virtual QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query storage buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Storage buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count of parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current storage buffer binding or -1 if not found + */ + virtual QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) = 0; + + /** + * @brief Bind a storage buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to storage buffer object + * + * @return No return + */ + virtual void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Query atomic counter buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active atomic buffer count + */ + virtual QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query atomic counter buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Storage buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count of parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current storage buffer binding or -1 if not found + */ + virtual QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) = 0; + + /** + * @brief Bind a atomic counter buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to atomic counter buffer object + * + * @return No return + */ + virtual void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Set constant value + * + * @param[in] po Pointer program object + * @param[in] id Constant ID + * @param[in] type Constant data type (QT3DSVec4, QT3DSVec3,...) + * @param[in] count Element count + * @param[in] value Pointer to constant value + * @param[in] transpose Transpose a matrix + * + * @return No return + */ + virtual void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose = false) = 0; + + /** + * @brief Draw the current active vertex buffer + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] start Start vertex + * @param[in] count Vertex count + * + * @return no return. + */ + virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) = 0; + + /** + * @brief Draw the current active vertex buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] indirect Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) = 0; + + /** + * @brief Draw the current active index buffer + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] count Index count + * @param[in] type Index type (QT3DSU16, QT3DSU8) + * @param[in] indices Pointer to index buffer. In the case of buffer objects + * this is an offset into the active index buffer + *object. + * + * @return no return. + */ + virtual void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) = 0; + + /** + * @brief Draw the current active index buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] type Index type (QT3DSU16, QT3DSU8) + * @param[in] indices Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) = 0; + + /** + * @brief Read a pixel rectangle from render target (from bottom left) + * + * @param[in] rto Pointer to render target object + * @param[in] x Windows X start coord + * @param[in] y Windows Y start coord + * @param[in] width Read width dim + * @param[in] height Read height dim + * @param[out] pixels Returned pixel data + * + * @return No return + */ + virtual void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, + QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, + void *pixels) = 0; + + /** + * @brief Create a NV path render object + * + * @param[in] range Number of internal objects + * + * @return return path object on success or NULL + */ + virtual NVRenderBackendPathObject CreatePathNVObject(size_t range) = 0; + + /** + * @brief Relase a NV path render object + * + * @param[in] po Created path object + * @param[in] range Number of internal objects + * + * @return return path object on success or NULL + */ + virtual void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) = 0; + + /** + * @brief Set the path commands and data. + * + * @param[in] inPathObject Pointer to NV path object + * @param[in] inPathCommands vector of path commands ( moveTo,... ) + * @param[in] inPathCoords vector of path coords + * + * @return No return + */ + virtual void SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef inPathCommands, + NVConstDataRef inPathCoords) = 0; + + /** + * @brief Get Bounds of the path object + * + * @param[in] inPathObject Pointer to NV path object + * + * @return return bounds + */ + virtual NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) = 0; + virtual NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) = 0; + virtual NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) = 0; + + /** + * @brief Set stroke width. Defaults to 0 if unset. + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void SetStrokeWidth(NVRenderBackendPathObject inPathObject, + QT3DSF32 inStrokeWidth) = 0; + + /** + * @brief Path transform commands + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; + virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; + + /** + * @brief Path stencil pass operations + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void StencilStrokePath(NVRenderBackendPathObject inPathObject) = 0; + virtual void StencilFillPath(NVRenderBackendPathObject inPathObject) = 0; + + /** + * @brief Does a instanced stencil fill pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] fillMode Fille mode + * @param[in] stencilMask Stencil mask + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced stencil stroke pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] stencilRef Stencil reference + * @param[in] stencilMask Stencil mask + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, + QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced cover fill pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] coverMode Cover mode + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced cover stroke pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] coverMode Cover mode + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Path stencil and depth offset + * + * @param[in] inSlope slope + * @param[in] inBias bias + * + * @return No return + */ + virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; + + /** + * @brief Path cover function + * + * @param[in] inDepthFunction depth function + * + * @return No return + */ + virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) = 0; + + /** + * @brief Load glyphs + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] numGlyphs Glyph count + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] handleMissingGlyphs skip or use + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return No return + */ + virtual void LoadPathGlyphs(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, + NVRenderPathFormatType::Enum type, const void *charCodes, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) = 0; + + /** + * @brief Load indexed font set + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] firstGlyphIndex First glyph + * @param[in] numGlyphs Glyph count + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return return load status + */ + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) = 0; + + /** + * @brief Load indexed font set + * + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * @param[out] po contains glyph count + * + * @return returnr base path object + */ + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, + QT3DSU32 *count) = 0; + + /** + * @brief Load font set + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] firstGlyph First glyph + * @param[in] numGlyphs Glyph count + * @param[in] handleMissingGlyphs skip or use + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return No return + */ + virtual void LoadPathGlyphRange(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) = 0; + + /** + * @brief Query font metrics + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] metricQueryMask Qeury bit mask + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] stride scale ( true type scale e.g. 2048 ) + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, const void *charCodes, + size_t stride, QT3DSF32 *metrics) = 0; + + /** + * @brief Query font metrics + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] metricQueryMask Qeury bit mask + * @param[in] stride scale ( true type scale e.g. 2048 ) + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) = 0; + + /** + * @brief Query path spacing + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] pathListMode How to compute spacing + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] advanceScale + * @param[in] kerningScale + * @param[in] transformType + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, + QT3DSF32 advanceScale, QT3DSF32 kerningScale, + NVRenderPathTransformType::Enum transformType, + QT3DSF32 *spacing) = 0; + + virtual QSurfaceFormat format() const = 0; + + protected: + /// struct for what the backend supports + typedef struct NVRenderBackendSupport + { + union { + struct + { + bool bDXTImagesSupported : 1; ///< compressed images supported + bool bAnistropySupported : 1; ///< anistropic filtering supported + bool bTextureSwizzleSupported : 1; ///< texture swizzle supported + bool bDepthStencilSupported : 1; ///< depth stencil textures are supported + bool bFPRenderTargetsSupported : 1; ///< floating point render targets are + ///supported + bool bConstantBufferSupported : 1; ///< Constant (uniform) buffers are supported + bool bMsTextureSupported : 1; ///< Multisample textures are esupported + bool bFastBlitsSupported : 1; ///< The hardware supports fast memor blits + bool bTessellationSupported : 1; ///< Hardware supports tessellation + bool bComputeSupported : 1; ///< Hardware supports compute shader + bool bGeometrySupported : 1; ///< Hardware supports geometry shader + bool bTimerQuerySupported : 1; ///< Hardware supports timer queries + bool bProgramInterfaceSupported : 1; ///< API supports program interface queries + bool bStorageBufferSupported : 1; ///< Shader storage buffers are supported + bool bAtomicCounterBufferSupported : 1; ///< Atomic counter buffers are + /// supported + bool bShaderImageLoadStoreSupported : 1; ///< Shader image load / store + ///operations are supported + bool bProgramPipelineSupported : 1; ///< Driver supports separate programs + bool bNVPathRenderingSupported : 1; ///< Driver NV path rendering + bool bNVAdvancedBlendSupported : 1; ///< Advanced blend modes supported + bool bNVBlendCoherenceSupported : 1; ///< Advanced blend done coherently + ///supported + bool bGPUShader5ExtensionSupported : 1; + bool bKHRAdvancedBlendSupported : 1; ///< Advanced blend modes supported + bool bKHRBlendCoherenceSupported : 1; ///< Advanced blend done coherently + bool bVertexArrayObjectSupported : 1; + bool bStandardDerivativesSupported : 1; + bool bTextureLodSupported : 1; + } bits; + + QT3DSU32 u32Values; + } caps; + } NVRenderBackendSupportBits; + + NVRenderBackendSupportBits m_backendSupport; ///< holds the backend support bits + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp new file mode 100644 index 00000000..d38c330c --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp @@ -0,0 +1,887 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Q3DSRenderBackendGLES2.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_MULTISAMPLE_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTENSION_FUNCTION(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_TIMER_EXT(x) +#define GL_CALL_TESSELATION_EXT(x) +#define GL_CALL_MULTISAMPLE_EXT(x) +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTENSION_FUNCTION(x) +#endif + +#ifndef GL_DEPTH_STENCIL_OES +#define GL_DEPTH_STENCIL_OES 0x84F9 +#endif + +namespace qt3ds { +namespace render { + +/// constructor +NVRenderBackendGLES2Impl::NVRenderBackendGLES2Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGLBase(fnd, stringTable, format) +{ + QString exts3tc = QStringLiteral("GL_EXT_texture_compression_s3tc"); + QString extsdxt = QStringLiteral("GL_EXT_texture_compression_dxt1"); + QString extsAniso = QStringLiteral("GL_EXT_texture_filter_anisotropic"); + QString extsTexSwizzle = QStringLiteral("GL_ARB_texture_swizzle"); + QString extsFPRenderTarget = QStringLiteral("GL_EXT_color_buffer_float"); + QString extsTimerQuery = QStringLiteral("GL_EXT_timer_query"); + QString extsGpuShader5 = QStringLiteral("EXT_gpu_shader5"); + QString extDepthTexture = QStringLiteral("GL_OES_packed_depth_stencil"); + QString extvao = QStringLiteral("GL_OES_vertex_array_object"); + QString extStdDd = QStringLiteral("GL_OES_standard_derivatives"); + QString extTexLod = QStringLiteral("GL_EXT_shader_texture_lod"); + + const char *languageVersion = GetShadingLanguageVersion(); + qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + eastl::string apiVendor(getVendorString()); + qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); + + eastl::string apiRenderer(getRendererString()); + qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); + + // clear support bits + m_backendSupport.caps.u32Values = 0; + + const char *extensions = getExtensionString(); + m_extensions = QString::fromLocal8Bit(extensions).split(" "); + + // get extension count + GLint numExtensions = m_extensions.size(); + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + + const QString &extensionString = m_extensions.at(i); + + // search for extension + if (!m_backendSupport.caps.bits.bDXTImagesSupported + && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { + m_backendSupport.caps.bits.bDXTImagesSupported = true; + } else if (!m_backendSupport.caps.bits.bAnistropySupported + && extsAniso.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAnistropySupported = true; + } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported + && extsFPRenderTarget.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + } else if (!m_backendSupport.caps.bits.bTimerQuerySupported + && extsTimerQuery.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported + && extsGpuShader5.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; + } else if (!m_backendSupport.caps.bits.bTextureSwizzleSupported + && extsTexSwizzle.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTextureSwizzleSupported = true; + } else if (!m_backendSupport.caps.bits.bDepthStencilSupported + && extDepthTexture.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bDepthStencilSupported = true; + } else if (!m_backendSupport.caps.bits.bVertexArrayObjectSupported + && extvao.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; + } else if (!m_backendSupport.caps.bits.bStandardDerivativesSupported + && extStdDd.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bStandardDerivativesSupported = true; + } else if (!m_backendSupport.caps.bits.bTextureLodSupported + && extTexLod.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTextureLodSupported = true; + } + } + + qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensions); + + // constant buffers support is always not true + m_backendSupport.caps.bits.bConstantBufferSupported = false; + + // query hardware + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); + + // internal state tracker + m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); + + // finally setup caps based on device + setAndInspectHardwareCaps(); + + // Initialize extensions +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#endif +} +/// destructor +NVRenderBackendGLES2Impl::~NVRenderBackendGLES2Impl() +{ + if (m_pCurrentMiscState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + if (m_qt3dsExtensions) + delete m_qt3dsExtensions; +#endif +} + +void NVRenderBackendGLES2Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(samples); + NVRENDER_BACKEND_UNUSED(internalFormat); + NVRENDER_BACKEND_UNUSED(width); + NVRENDER_BACKEND_UNUSED(height); + NVRENDER_BACKEND_UNUSED(fixedsamplelocations); +} + +void NVRenderBackendGLES2Impl::SetTextureData3D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, + QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + } + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + } + + GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, + (GLsizei)height, (GLsizei)depth, border, glformat, + gltype, hostPtr)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLES2Impl::SetTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + glInternalFormat = glformat; + } + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + if (format == NVRenderTextureFormats::Depth24Stencil8) { + glformat = GL_DEPTH_STENCIL_OES; + gltype = GL_UNSIGNED_INT_24_8; + } + glInternalFormat = glformat; + } + + Q_ASSERT(glformat == glInternalFormat); + GL_CALL_EXTRA_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, + (GLsizei)height, border, glformat, gltype, hostPtr)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLES2Impl::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) +{ + + // Satisfy the compiler + // These are not available in GLES 3 and we don't use them right now + QT3DS_ASSERT(lodBias == 0.0); + QT3DS_ASSERT(!borderColor); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(borderColor); + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + anisotropy)); + } +} + +void NVRenderBackendGLES2Impl::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) +{ + NVRENDER_BACKEND_UNUSED(to); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); +} + +void NVRenderBackendGLES2Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(swizzleMode); +#if defined(QT_OPENGL_ES) + if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { + GLint glSwizzle[4]; + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); + + // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); + + } +#endif +} + +QT3DSU32 +NVRenderBackendGLES2Impl::GetDepthBits() const +{ + QT3DSI32 depthBits; + GL_CALL_EXTRA_FUNCTION( + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); + + return depthBits; +} + +QT3DSU32 +NVRenderBackendGLES2Impl::GetStencilBits() const +{ + QT3DSI32 stencilBits; + GL_CALL_EXTRA_FUNCTION( + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilBits)); + + return stencilBits; +} + +void NVRenderBackendGLES2Impl::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum /*genType*/) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +bool NVRenderBackendGLES2Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) +{ + if (iao == nullptr) { + // unbind and return; + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(0)); + return true; + } + + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + NVDataRef shaderAttribBuffer; + if (pProgram->m_shaderInput) + shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; + + if ((attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) + || (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot)) { + return false; + } + + if (inputAssembler->m_VaoID == 0) { + // generate vao + GL_CALL_EXTENSION_FUNCTION(glGenVertexArraysOES(1, &inputAssembler->m_VaoID)); + QT3DS_ASSERT(inputAssembler->m_VaoID); + } + + if (inputAssembler->m_cachedShaderHandle != programID) { + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); + inputAssembler->m_cachedShaderHandle = programID; + + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents) { + qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + return false; + } else { + entryData.m_AttribIndex = attrib.m_AttribLocation; + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + + // disable max possible used first + // this is currently sufficient since we always re-arrange input attributes from 0 + for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); + + // setup all attribs + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); + if (entry) { + const NVRenderBackendLayoutEntryGL &entryData(*entry); + GLuint id = HandleToID_cast( + GLuint, size_t, + inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); + GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); + GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; + GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; + GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( + entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, + stride, (const void *)(entryData.m_Offset + offset))); + + } else { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); + } + } + + // setup index buffer. + if (inputAssembler->m_IndexbufferHandle) { + GL_CALL_EXTRA_FUNCTION(glBindBuffer( + GL_ELEMENT_ARRAY_BUFFER, + HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); + } else { + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + } else { + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); + } +#ifdef _DEBUG + if (inputAssembler->m_VaoID) { + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents + || entryData.m_AttribIndex != attrib.m_AttribLocation) { + qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + } +#endif // _DEBUG + + return true; +} + +void NVRenderBackendGLES2Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) +{ + NVRENDER_BACKEND_UNUSED(rto); + + m_DrawBuffersArray.clear(); + + for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { + if (inDrawBufferSet[idx] < 0) + m_DrawBuffersArray.push_back(GL_NONE); + else + m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); + } + + GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), + m_DrawBuffersArray.data())); +} + +void NVRenderBackendGLES2Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) +{ + NVRENDER_BACKEND_UNUSED(rto); + NVRENDER_BACKEND_UNUSED(inReadFace); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) +{ + NVRENDER_BACKEND_UNUSED(attachment); + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(level); + NVRENDER_BACKEND_UNUSED(layer); + Q_ASSERT(false); +} + +void NVRenderBackendGLES2Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, + QT3DSI32 srcY1, QT3DSI32 dstX0, QT3DSI32 dstY0, + QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) +{ + GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, + dstY1, + m_Conversion.fromClearFlagsToGL(flags), + m_Conversion.fromTextureMagnifyingOpToGL(filter))); +} + + +NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLES2Impl::CreateRenderTarget() +{ + GLuint fboID = 0; + GL_CALL_EXTRA_FUNCTION(glGenFramebuffers(1, &fboID)); + return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; +} + +void NVRenderBackendGLES2Impl::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + if (fboID) + GL_CALL_EXTRA_FUNCTION(glDeleteFramebuffers(1, &fboID)); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) +{ + // rto must be the current render target + GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_EXTRA_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, + rbID)); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target) +{ + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D + || m_backendSupport.caps.bits.bMsTextureSupported); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + if (attachment == NVRenderFrameBufferAttachments::DepthStencil) { + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + glTarget, texID, 0)); + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + glTarget, texID, 0)); + } else { + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, + 0)); + } +} + +void NVRenderBackendGLES2Impl::SetRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); +} + +void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); +} + +bool NVRenderBackendGLES2Impl::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) +{ + GLenum completeStatus = GL_CALL_EXTRA_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); + switch (completeStatus) { +#define HANDLE_INCOMPLETE_STATUS(x) \ + case x: \ + qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ + return false; + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) + #undef HANDLE_INCOMPLETE_STATUS + } + return true; +} + +NVRenderBackend::NVRenderBackendRenderbufferObject +NVRenderBackendGLES2Impl::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + GLuint bufID = 0; + + GL_CALL_EXTRA_FUNCTION(glGenRenderbuffers(1, &bufID)); + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + bufID = 0; + } + + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; +} + +void NVRenderBackendGLES2Impl::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + if (bufID) + GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); +} + +bool NVRenderBackendGLES2Impl::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + bool success = true; + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + QT3DS_ASSERT(bufID); + + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + success = false; + } + + return success; +} + +void *NVRenderBackendGLES2Impl::MapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t length, NVRenderBufferAccessFlags accessFlags) +{ + void *ret = nullptr; + ret = GL_CALL_EXTRA_FUNCTION( + glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, + length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); + + return ret; +} + +bool NVRenderBackendGLES2Impl::UnmapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags) +{ + GLboolean ret; + + ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); + + return (ret) ? true : false; +} + +QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) +{ + QT3DS_ASSERT(po); + GLint numUniformBuffers = 0; + if (GetRenderBackendCap(NVRenderBackendCaps::ConstantBuffer)) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, + &numUniformBuffers)); + } + return numUniformBuffers; +} + +QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferInfoByID( + NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + GLuint blockIndex = GL_INVALID_INDEX; + + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, + nameBuf)); + + if (*length > 0) { + blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); + if (blockIndex != GL_INVALID_INDEX) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); + } + } + + return blockIndex; +} + +void NVRenderBackendGLES2Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (indices) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + indices)); + } +} + +void NVRenderBackendGLES2Impl::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(count); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (count && indices) { + if (type) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, + GL_UNIFORM_TYPE, type)); + // convert to UIC types + QT3DS_FOREACH(idx, count) + { + type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); + } + } + if (size) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, + GL_UNIFORM_SIZE, size)); + } + if (offset) { + GL_CALL_EXTRA_FUNCTION( + glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); + } + } +} + +void NVRenderBackendGLES2Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); +} + +void NVRenderBackendGLES2Impl::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) +{ + QT3DS_ASSERT(bo); + + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); +} + +NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLES2Impl::CreateQuery() +{ + QT3DSU32 glQueryID = 0; + + return (NVRenderBackendQueryObject)glQueryID; +} + +void NVRenderBackendGLES2Impl::ReleaseQuery(NVRenderBackendQueryObject) +{ + +} + +void NVRenderBackendGLES2Impl::BeginQuery(NVRenderBackendQueryObject, + NVRenderQueryType::Enum) +{ + +} + +void NVRenderBackendGLES2Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) +{ + +} + +void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, + QT3DSU32 *) +{ + +} + +void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, + QT3DSU64 *) +{ + +} + +void NVRenderBackendGLES2Impl::SetQueryTimer(NVRenderBackendQueryObject) +{ + +} + +NVRenderBackend::NVRenderBackendSyncObject +NVRenderBackendGLES2Impl::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) +{ + GLsync syncID = 0; + return NVRenderBackendSyncObject(syncID); +} + +void NVRenderBackendGLES2Impl::ReleaseSync(NVRenderBackendSyncObject) +{ + +} + +void NVRenderBackendGLES2Impl::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, + QT3DSU64) +{ + +} +} +} diff --git a/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h new file mode 100644 index 00000000..4890de0e --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_BACKEND_GLES2_H +#define QT3DS_RENDER_BACKEND_GLES2_H + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +#include +#include + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendMiscStateGL; + + using namespace foundation; + + class NVRenderBackendGLES2Impl : public NVRenderBackendGLBase + { + public: + /// constructor + NVRenderBackendGLES2Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGLES2Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = nullptr) override; + + void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = nullptr) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0f, QT3DSF32 maxLod = 1000.0f, QT3DSF32 lodBias = 0.0f, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0f, QT3DSF32 *borderColor = nullptr) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override; + + void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) override; + void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) override; + + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + + NVRenderBackendRenderTargetObject CreateRenderTarget() override; + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target + = NVRenderTextureTargetType::Texture2D) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) override; + void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; + + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) override; + void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) override; + + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, + QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + protected: + NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; +#endif + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp new file mode 100644 index 00000000..564ecd5a --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +Qt3DSOpenGLExtensions::Qt3DSOpenGLExtensions() + : QAbstractOpenGLExtension(*(new Qt3DSOpenGLExtensionsPrivate)) +{ +} + +bool Qt3DSOpenGLExtensions::initializeOpenGLFunctions() +{ + if (isInitialized()) + return true; + + QT_PREPEND_NAMESPACE(QOpenGLContext) *context = + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); + if (!context) { + qWarning("A current OpenGL context is required to resolve functions"); + return false; + } + + Q_D(Qt3DSOpenGLExtensions); + + d->BlendBarrierNV = reinterpret_cast( + context->getProcAddress("glBlendBarrierNV")); + d->PathGlyphIndexArrayNV = reinterpret_cast( + context->getProcAddress("glPathGlyphIndexArrayNV")); + d->PathGlyphIndexRangeNV = reinterpret_cast( + context->getProcAddress("glPathGlyphIndexRangeNV")); + QAbstractOpenGLExtension::initializeOpenGLFunctions(); + return true; +} + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +Qt3DSOpenGLES2Extensions::Qt3DSOpenGLES2Extensions() +{ +} + +bool Qt3DSOpenGLES2Extensions::initializeOpenGLFunctions() +{ + if (isInitialized()) + return true; + + QT_PREPEND_NAMESPACE(QOpenGLContext) *context = + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); + if (!context) { + qWarning("A current OpenGL context is required to resolve functions"); + return false; + } + + Q_D(Qt3DSOpenGLExtensions); + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + d->PatchParameteriEXT = reinterpret_cast( + context->getProcAddress("glPatchParameteriEXT")); + d->QueryCounterEXT = reinterpret_cast( + context->getProcAddress("glQueryCounterEXT")); + d->GetQueryObjectui64vEXT = reinterpret_cast( + context->getProcAddress("glGetQueryObjectui64vEXT")); + d->GenPathsNV = reinterpret_cast( + context->getProcAddress("glGenPathsNV")); + d->DeletePathsNV = reinterpret_cast( + context->getProcAddress("glDeletePathsNV")); + d->PathCommandsNV = reinterpret_cast( + context->getProcAddress("glPathCommandsNV")); + d->PathGlyphsNV = reinterpret_cast( + context->getProcAddress("glPathGlyphsNV")); + d->PathGlyphRangeNV = reinterpret_cast( + context->getProcAddress("glPathGlyphRangeNV")); + d->PathParameterfNV = reinterpret_cast( + context->getProcAddress("glPathParameterfNV")); + d->PathStencilDepthOffsetNV = reinterpret_cast( + context->getProcAddress("glPathStencilDepthOffsetNV")); + d->StencilFillPathNV = reinterpret_cast( + context->getProcAddress("glStencilFillPathNV")); + d->StencilStrokePathNV = reinterpret_cast( + context->getProcAddress("glStencilStrokePathNV")); + d->StencilFillPathInstancedNV = reinterpret_cast( + context->getProcAddress("glStencilFillPathInstancedNV")); + d->StencilStrokePathInstancedNV + = reinterpret_cast( + context->getProcAddress("glStencilStrokePathInstancedNV")); + d->PathCoverDepthFuncNV = reinterpret_cast( + context->getProcAddress("glPathCoverDepthFuncNV")); + d->CoverFillPathInstancedNV = reinterpret_cast( + context->getProcAddress("glCoverFillPathInstancedNV")); + d->CoverStrokePathInstancedNV = reinterpret_cast( + context->getProcAddress("glCoverStrokePathInstancedNV")); + d->GetPathParameterfvNV = reinterpret_cast( + context->getProcAddress("glGetPathParameterfvNV")); + d->GetPathMetricsNV = reinterpret_cast( + context->getProcAddress("glGetPathMetricsNV")); + d->GetPathMetricRangeNV = reinterpret_cast( + context->getProcAddress("glGetPathMetricRangeNV")); + d->GetPathSpacingNV = reinterpret_cast( + context->getProcAddress("glGetPathSpacingNV")); + d->BindVertexArrayOES = reinterpret_cast( + context->getProcAddress("glBindVertexArrayOES")); + d->DeleteVertexArraysOES = reinterpret_cast( + context->getProcAddress("glDeleteVertexArraysOES")); + d->GenVertexArraysOES = reinterpret_cast( + context->getProcAddress("glGenVertexArraysOES")); + d->IsVertexArrayOES = reinterpret_cast( + context->getProcAddress("glIsVertexArrayOES")); +#endif + Qt3DSOpenGLExtensions::initializeOpenGLFunctions(); + return true; +} +#endif // QT_OPENGL_ES diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h new file mode 100644 index 00000000..c9ba76a6 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h @@ -0,0 +1,392 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLEXTENSIONS_H +#define QT3DSOPENGLEXTENSIONS_H + +#include + +/* Some OpenGL extensions that are not (yet) found in Qt's OpenGL extensions. + * These should be auto-generated and added to QtOpenGLExtensions module */ +class Qt3DSOpenGLExtensionsPrivate : public QAbstractOpenGLExtensionPrivate +{ +public: + void (QOPENGLF_APIENTRYP BlendBarrierNV)(); + GLenum (QOPENGLF_APIENTRYP PathGlyphIndexArrayNV)( + GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint, + GLfloat); + GLenum (QOPENGLF_APIENTRYP PathGlyphIndexRangeNV)( + GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2]); + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + void (QOPENGLF_APIENTRYP PatchParameteriEXT)(GLenum, GLint); + void (QOPENGLF_APIENTRYP QueryCounterEXT)(GLuint, GLenum); + void (QOPENGLF_APIENTRYP GetQueryObjectui64vEXT)(GLuint, GLenum, + GLuint64 *); + GLuint (QOPENGLF_APIENTRYP GenPathsNV)(GLsizei); + void (QOPENGLF_APIENTRYP DeletePathsNV)(GLuint, GLsizei); + void (QOPENGLF_APIENTRYP PathCommandsNV)(GLuint, GLsizei, const GLubyte *, + GLsizei, GLenum, const void *); + void (QOPENGLF_APIENTRYP PathGlyphsNV)(GLuint, GLenum, const void *, + GLbitfield, GLsizei, GLenum, const void *, GLenum, GLuint, GLfloat); + void (QOPENGLF_APIENTRYP PathGlyphRangeNV)(GLuint, GLenum, const void *, + GLbitfield, GLuint, GLsizei, GLenum, GLuint, GLfloat); + void (QOPENGLF_APIENTRYP PathParameterfNV)(GLuint, GLenum, GLfloat); + void (QOPENGLF_APIENTRYP PathStencilDepthOffsetNV)(GLfloat, GLfloat); + void (QOPENGLF_APIENTRYP StencilFillPathNV)(GLuint, GLenum, GLuint); + void (QOPENGLF_APIENTRYP StencilStrokePathNV)(GLuint, GLint, GLuint); + void (QOPENGLF_APIENTRYP StencilFillPathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLuint, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP StencilStrokePathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP PathCoverDepthFuncNV)(GLenum); + void (QOPENGLF_APIENTRYP CoverFillPathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP CoverStrokePathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP GetPathParameterfvNV)(GLuint, GLenum, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathMetricsNV)(GLbitfield, GLsizei, GLenum, + const void *, GLuint, GLsizei, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathMetricRangeNV)(GLbitfield, GLuint, GLsizei, + GLsizei, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathSpacingNV)(GLenum, GLsizei, GLenum, + const void *, GLuint, GLfloat, GLfloat, GLenum, GLfloat *); + void (QOPENGLF_APIENTRYP BindVertexArrayOES) (GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArraysOES) (GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArraysOES) (GLsizei n, GLuint *arrays); + GLboolean (QOPENGLF_APIENTRYP IsVertexArrayOES) (GLuint array); +#endif +}; + +class Qt3DSOpenGLExtensions : public QAbstractOpenGLExtension +{ +public: + Qt3DSOpenGLExtensions(); + + bool initializeOpenGLFunctions() override; + + void glBlendBarrierNV(); + GLenum glPathGlyphIndexArrayNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, + GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); + GLenum glPathGlyphIndexRangeNV(GLenum fontTarget, const void *fontName, + GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, + GLuint baseAndCount[2]); + +protected: + Q_DECLARE_PRIVATE(Qt3DSOpenGLExtensions) +}; + +inline void Qt3DSOpenGLExtensions::glBlendBarrierNV() +{ + Q_D(Qt3DSOpenGLExtensions); + d->BlendBarrierNV(); +} + +inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexArrayNV( + GLuint firstPathName, GLenum fontTarget, const void *fontName, + GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, + GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->PathGlyphIndexArrayNV(firstPathName, fontTarget, fontName, + fontStyle, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale); +} + +inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexRangeNV(GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, + GLfloat emScale, GLuint baseAndCount[2]) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->PathGlyphIndexRangeNV(fontTarget, fontName, fontStyle, + pathParameterTemplate, emScale, baseAndCount); +} + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +class Qt3DSOpenGLES2Extensions : public Qt3DSOpenGLExtensions +{ +public: + Qt3DSOpenGLES2Extensions(); + + // tesselation shader + void glPatchParameteriEXT(GLenum pname, GLint value); + + // timer + void glQueryCounterEXT(GLuint id, GLenum target); + void glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params); + + // nv paths + + GLuint glGenPathsNV(GLsizei range); + void glDeletePathsNV(GLuint path, GLsizei range); + void glPathCommandsNV(GLuint path, GLsizei numCommands, + const GLubyte *commands, GLsizei numCoords, GLenum coordType, + const void *coords); + void glPathGlyphsNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, + GLenum type, const void *charcodes, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale); + void glPathGlyphRangeNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, + GLsizei numGlyphs, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale); + void glPathParameterfNV(GLuint path, GLenum pname, GLfloat value); + void glPathStencilDepthOffsetNV(GLfloat factor, GLfloat units); + void glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask); + void glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask); + void glStencilFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, + GLenum transformType, const GLfloat *transformValues); + void glStencilStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLint reference, GLuint mask, + GLenum transformType, const GLfloat *transformValues); + void glPathCoverDepthFuncNV(GLenum func); + void glCoverFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum coverMode, + GLenum transformType, const GLfloat *transformValues); + void glCoverStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum coverMode, + GLenum transformType, const GLfloat *transformValues); + void glGetPathParameterfvNV(GLuint path, GLenum pname, GLfloat *value); + void glGetPathMetricsNV(GLbitfield metricQueryMask, GLsizei numPaths, + GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, + GLfloat *metrics); + void glGetPathMetricRangeNV(GLbitfield metricQueryMask, + GLuint firstPathName, GLsizei numPaths, GLsizei stride, + GLfloat *metrics); + void glGetPathSpacingNV(GLenum pathListMode, GLsizei numPaths, + GLenum pathNameType, const void *paths, GLuint pathBase, + GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, + GLfloat *returnedSpacing); + void glBindVertexArrayOES(GLuint array); + void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays); + void glGenVertexArraysOES(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArrayOES(GLuint array); + + bool initializeOpenGLFunctions() Q_DECL_FINAL; +}; + +inline void Qt3DSOpenGLES2Extensions::glPatchParameteriEXT(GLenum pname, + GLint value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PatchParameteriEXT(pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glQueryCounterEXT(GLuint id, + GLenum target) +{ + Q_D(Qt3DSOpenGLExtensions); + d->QueryCounterEXT(id, target); +} + +inline void Qt3DSOpenGLES2Extensions::glGetQueryObjectui64vEXT(GLuint id, + GLenum pname, GLuint64 *params) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetQueryObjectui64vEXT(id, pname, params); +} + +inline GLuint Qt3DSOpenGLES2Extensions::glGenPathsNV(GLsizei range) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->GenPathsNV(range); +} + +inline void Qt3DSOpenGLES2Extensions::glDeletePathsNV(GLuint path, + GLsizei range) +{ + Q_D(Qt3DSOpenGLExtensions); + d->DeletePathsNV(path, range); +} + +inline void Qt3DSOpenGLES2Extensions::glPathCommandsNV(GLuint path, + GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, + GLenum coordType, const void *coords) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathCommandsNV(path, numCommands, commands, numCoords, coordType, + coords); +} + +inline void Qt3DSOpenGLES2Extensions::glPathGlyphsNV(GLuint firstPathName, + GLenum fontTarget, const void *fontName, GLbitfield fontStyle, + GLsizei numGlyphs, GLenum type, const void *charcodes, + GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, numGlyphs, + type, charcodes, handleMissingGlyphs, pathParameterTemplate, emScale); +} + +inline void Qt3DSOpenGLES2Extensions::glPathGlyphRangeNV(GLuint firstPathName, + GLenum fontTarget, const void *fontName, GLbitfield fontStyle, + GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathGlyphRangeNV(firstPathName, fontTarget, fontName, fontStyle, + firstGlyph, numGlyphs, handleMissingGlyphs, pathParameterTemplate, + emScale); +} + +inline void Qt3DSOpenGLES2Extensions::glPathParameterfNV(GLuint path, + GLenum pname, GLfloat value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathParameterfNV(path, pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glPathStencilDepthOffsetNV(GLfloat factor, + GLfloat units) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathStencilDepthOffsetNV(factor, units); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilFillPathNV(GLuint path, + GLenum fillMode, GLuint mask) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilFillPathNV(path, fillMode, mask); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathNV(GLuint path, + GLint reference, GLuint mask) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilStrokePathNV(path, reference, mask); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilFillPathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum fillMode, GLuint mask, GLenum transformType, + const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLint reference, GLuint mask, GLenum transformType, + const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glPathCoverDepthFuncNV(GLenum func) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathCoverDepthFuncNV(func); +} + +inline void Qt3DSOpenGLES2Extensions::glCoverFillPathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum coverMode, GLenum transformType, const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->CoverFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glCoverStrokePathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum coverMode, GLenum transformType, const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->CoverStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathParameterfvNV(GLuint path, + GLenum pname, GLfloat *value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathParameterfvNV(path, pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathMetricsNV( + GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathMetricsNV(metricQueryMask, numPaths, pathNameType, paths, + pathBase, stride, metrics); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathMetricRangeNV( + GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, + GLsizei stride, GLfloat *metrics) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathMetricRangeNV(metricQueryMask, firstPathName, numPaths, stride, + metrics); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathSpacingNV(GLenum pathListMode, + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, + GLfloat *returnedSpacing) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase, + advanceScale, kerningScale, transformType, returnedSpacing); +} + +inline void Qt3DSOpenGLES2Extensions::glBindVertexArrayOES(GLuint array) +{ + Q_D(Qt3DSOpenGLExtensions); + d->BindVertexArrayOES(array); +} + +inline void Qt3DSOpenGLES2Extensions::glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) +{ + Q_D(Qt3DSOpenGLExtensions); + d->DeleteVertexArraysOES(n, arrays); +} + +inline void Qt3DSOpenGLES2Extensions::glGenVertexArraysOES(GLsizei n, GLuint *arrays) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GenVertexArraysOES(n, arrays); +} + +inline GLboolean Qt3DSOpenGLES2Extensions::glIsVertexArrayOES(GLuint array) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->IsVertexArrayOES(array); +} + +#endif // QT_OPENGL_ES + +#endif // QT3DSOPENGLEXTENSIONS_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h new file mode 100644 index 00000000..0e6dc6d4 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLPREFIX_H +#define QT3DSOPENGLPREFIX_H + +#include +#if defined(QT_OPENGL_ES) +#define GL_GLEXT_PROTOTYPES +#if defined(QT_OPENGL_ES_3_2) +#include +#else +#include +#include +#endif + +// Adding this to ensure that platform version of gl2ext.h is included +// before Qt's qopengles2ext.h which is missing symbols we need +#include +#endif + +#endif // QT3DSOPENGLPREFIX_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h new file mode 100644 index 00000000..882e2761 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h @@ -0,0 +1,408 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLTOKENS_H +#define QT3DSOPENGLTOKENS_H + +/** + * This is our general internal to GL type conversion routines + * Add defines which are not in standard GL(ext) header but in GL2(ext) + * The define are the same with different names + * Expectation is the NVIDIA defines (need for compile) + */ +#ifndef GL_NVIDIA_PLATFORM_BINARY_NV +#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B +#endif +#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT +#endif + +#if defined(__APPLE__) || defined(ANDROID) || defined(__INTEGRITY) +#ifndef GL_DEPTH_COMPONENT24 +#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES +#endif +#ifndef GL_DEPTH_COMPONENT32 +#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES +#endif + +/** +_* tessellation_shader defines + */ +#ifndef GL_TESS_EVALUATION_SHADER +#define GL_TESS_EVALUATION_SHADER GL_TESS_EVALUATION_SHADER_EXT +#endif +#ifndef GL_TESS_CONTROL_SHADER +#define GL_TESS_CONTROL_SHADER GL_TESS_CONTROL_SHADER_EXT +#endif +#ifndef GL_PATCHES +#define GL_PATCHES GL_PATCHES_EXT +#endif +#ifndef GL_PATCH_VERTICES +#define GL_PATCH_VERTICES GL_PATCH_VERTICES_EXT +#endif +#ifndef GL_TESS_CONTROL_SHADER_BIT +#define GL_TESS_CONTROL_SHADER_BIT GL_TESS_CONTROL_SHADER_BIT_EXT +#endif +#ifndef GL_TESS_EVALUATION_SHADER_BIT +#define GL_TESS_EVALUATION_SHADER_BIT GL_TESS_EVALUATION_SHADER_BIT_EXT +#endif +#ifndef GL_VERTEX_SHADER_BIT +#define GL_VERTEX_SHADER_BIT GL_VERTEX_SHADER_BIT_EXT +#endif +#ifndef GL_FRAGMENT_SHADER_BIT +#define GL_FRAGMENT_SHADER_BIT GL_FRAGMENT_SHADER_BIT_EXT +#endif +#ifndef GL_GEOMETRY_SHADER_BIT +#define GL_GEOMETRY_SHADER_BIT GL_GEOMETRY_SHADER_BIT_EXT +#endif + + +/** + * sample shading extension + */ +#ifndef GL_SAMPLE_SHADING +#define GL_SAMPLE_SHADING GL_SAMPLE_SHADING_OES +#endif +#ifndef GL_MIN_SAMPLE_SHADING_VALUE +#define GL_MIN_SAMPLE_SHADING_VALUE GL_MIN_SAMPLE_SHADING_VALUE_OES +#endif + +/** + * Timer query extension + */ +#ifndef GL_TIME_ELAPSED +#define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT +#endif +#ifndef GL_TIMESTAMP +#define GL_TIMESTAMP GL_TIMESTAMP_EXT +#endif + +/** + * compute shader + */ +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif + +/** + * texture formats ( make build happy ) + */ +#ifndef GL_R16 +#define GL_R16 0x822A +#endif + +#endif // __APPLE__ || ANDROID || __INTEGRITY + +#if defined(__APPLE__) || defined(ANDROID) + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#endif + +#ifndef GL_ALL_BARRIER_BITS +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#endif + +#ifndef GL_SHADER_STORAGE_BARRIER_BIT +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#endif + +#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + + + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_2_BYTES_NV 0x1407 +#define GL_3_BYTES_NV 0x1408 +#define GL_4_BYTES_NV 0x1409 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_CONSTANT_NV 0x8576 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D +#endif /* GL_NV_path_rendering */ + +#ifndef GL_SHADER_STORAGE_BLOCK +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#endif + +#ifndef GL_ACTIVE_RESOURCES +#define GL_ACTIVE_RESOURCES 0x92F5 +#endif + +#ifndef GL_BUFFER_BINDING +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#endif + +#ifndef GL_UNIFORM +#define GL_UNIFORM 0x92E1 +#endif + +#ifndef GL_COMPUTE_SHADER +#define GL_COMPUTE_SHADER 0x91B9 +#endif + +#endif // __APPLE__ || ANDROID + +#endif // QT3DSOPENGLTOKENS_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h new file mode 100644 index 00000000..32f7dad7 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h @@ -0,0 +1,2201 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLUTIL_H +#define QT3DSOPENGLUTIL_H + +#include "render/backends/gl/Qt3DSOpenGLPrefix.h" +#include "render/backends/gl/Qt3DSOpenGLTokens.h" +#include +#include + +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSFoundation.h" + +// The actual binding to the hardware the does some minor conversions between gles and +// the nv render enumeration types +namespace qt3ds { +namespace render { + +#ifndef GL_TEXTURE_2D_MULTISAMPLE +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#endif + +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif + +#ifndef GL_MULTISAMPLE_EXT +#define GL_MULTISAMPLE_EXT 0x809D +#endif + +#ifndef GL_COLOR_ATTACHMENT1 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#endif + +#ifndef GL_RED +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#endif + +#ifndef GL_PATCHES +#define GL_PATCHES 0x000E +#endif + +#ifndef GL_READ_ONLY +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#endif + +#ifndef GL_DRAW_INDIRECT_BUFFER +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#endif + +#ifndef GL_VERTEX_SHADER_BIT +#define GL_VERTEX_SHADER_BIT 0x00000001 +#endif + +#ifndef GL_FRAGMENT_SHADER_BIT +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#endif + +#ifndef GL_GEOMETRY_SHADER_BIT +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#endif + +#ifndef GL_TESS_CONTROL_SHADER_BIT +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#endif + +#ifndef GL_TESS_EVALUATION_SHADER_BIT +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#endif + +#ifndef GL_ETC1_RGB8_OES +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +#ifndef GL_COMPRESSED_RED_RGTC1 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#endif + +#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#endif + +#ifndef GL_COMPRESSED_RG_RGTC2 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#endif + +#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#endif + +#ifndef GL_COMPRESSED_RGB8_ETC2 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ETC2 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#endif + +#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#endif + +#ifndef GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#endif + +#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#endif + +#ifndef GL_COMPRESSED_R11_EAC +#define GL_COMPRESSED_R11_EAC 0x9270 +#endif + +#ifndef GL_COMPRESSED_SIGNED_R11_EAC +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#endif + +#ifndef GL_COMPRESSED_RG11_EAC +#define GL_COMPRESSED_RG11_EAC 0x9272 +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG11_EAC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#endif + +#define QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ZERO, Zero) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE, One) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_COLOR, SrcColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_COLOR, OneMinusSrcColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_COLOR, DstColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_COLOR, OneMinusDstColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_ALPHA, SrcAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_ALPHA, OneMinusSrcAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_ALPHA, DstAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_ALPHA, OneMinusDstAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_COLOR, ConstantColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_COLOR, OneMinusConstantColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_ALPHA, ConstantAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_ALPHA, OneMinusConstantAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(GL_SRC_ALPHA_SATURATE, SrcAlphaSaturate) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT, Front) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_BACK, Back) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT_AND_BACK, FrontAndBack) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CW, Clockwise) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CCW, CounterClockwise) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NEVER, Never) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LESS, Less) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_EQUAL, Equal) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LEQUAL, LessThanOrEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GREATER, Greater) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NOTEQUAL, NotEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GEQUAL, GreaterThanOrEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_ALWAYS, AlwaysTrue) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_HINT \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_FASTEST, Fastest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_NICEST, Nicest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_DONT_CARE, Unspecified) + +#define QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_KEEP, Keep) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_ZERO, Zero) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_REPLACE, Replace) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR, Increment) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR_WRAP, IncrementWrap) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR, Decrement) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR_WRAP, DecrementWrap) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INVERT, Invert) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_BYTE, QT3DSU8) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_BYTE, QT3DSI8) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_SHORT, QT3DSU16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_SHORT, QT3DSI16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_INT, QT3DSU32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(GL_INT, QT3DSI32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_FLOAT, QT3DSF32) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_STATIC_DRAW, Static) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_DYNAMIC_DRAW, Dynamic) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_NEAREST, Nearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_LINEAR, Linear) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_NEAREST, NearestMipmapNearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_NEAREST, LinearMipmapNearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_LINEAR, NearestMipmapLinear) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_LINEAR, LinearMipmapLinear) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_CLAMP_TO_EDGE, ClampToEdge) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_MIRRORED_REPEAT, MirroredRepeat) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_REPEAT, Repeat) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT, QT3DSF32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC2, QT3DSVec2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC3, QT3DSVec3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC4, QT3DSVec4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT, QT3DSI32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC2, QT3DSI32_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC3, QT3DSI32_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC4, QT3DSI32_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL, QT3DSRenderBool) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC2, bool_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC3, bool_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC4, bool_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT, QT3DSU32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC2, QT3DSU32_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC3, QT3DSU32_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC4, QT3DSU32_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT3, QT3DSMat33) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT4, QT3DSMat44) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D, NVRenderTexture2DPtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D_ARRAY, NVRenderTexture2DArrayPtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_CUBE, NVRenderTextureCubePtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_IMAGE_2D, NVRenderImage2DPtr) +// cube Sampler and mat22 unsupported + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT, QT3DSF32, 1) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC2, QT3DSF32, 2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC3, QT3DSF32, 3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC4, QT3DSF32, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT2, QT3DSF32, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT3, QT3DSF32, 9) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT4, QT3DSF32, 16) +#if defined(GL_DEPTH_COMPONENT32) +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT32, Depth32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) +#else +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) +#endif + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color0, 0) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color1, 1) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color2, 2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color3, 3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color4, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color5, 5) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color6, 6) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color7, 7) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_ATTACHMENT, Depth) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_STENCIL_ATTACHMENT, Stencil) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_STENCIL_ATTACHMENT, DepthStencil) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_COLOR_BUFFER_BIT, Color) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_DEPTH_BUFFER_BIT, Depth) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_STENCIL_BUFFER_BIT, Stencil) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS + + static bool IsGlEsContext(NVRenderContextType inContextType) + { + NVRenderContextType esContextTypes(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + + if ((inContextType & esContextTypes)) + return true; + + return false; + } + + struct GLConversion + { + GLConversion() + { } + + static const char *processGLError(GLenum error) + { + const char *errorString = ""; + switch (error) { +#define stringiseError(error) \ + case error: \ + errorString = #error; \ + break + stringiseError(GL_NO_ERROR); + stringiseError(GL_INVALID_ENUM); + stringiseError(GL_INVALID_VALUE); + stringiseError(GL_INVALID_OPERATION); + stringiseError(GL_INVALID_FRAMEBUFFER_OPERATION); + stringiseError(GL_OUT_OF_MEMORY); +#undef stringiseError + default: + errorString = "Unknown GL error"; + break; + } + return errorString; + } + + static NVRenderSrcBlendFunc::Enum fromGLToSrcBlendFunc(QT3DSI32 value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case srcVal: \ + return NVRenderSrcBlendFunc::enumVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ + case srcVal: \ + return NVRenderSrcBlendFunc::enumVal; + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return NVRenderSrcBlendFunc::Unknown; + } + } + + static GLenum fromSrcBlendFuncToGL(NVRenderSrcBlendFunc::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case NVRenderSrcBlendFunc::enumVal: \ + return srcVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ + case NVRenderSrcBlendFunc::enumVal: \ + return srcVal; + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return 0; + } + } + + static NVRenderDstBlendFunc::Enum fromGLToDstBlendFunc(QT3DSI32 value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case srcVal: \ + return NVRenderDstBlendFunc::enumVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return NVRenderDstBlendFunc::Unknown; + } + } + + static GLenum fromDstBlendFuncToGL(NVRenderDstBlendFunc::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case NVRenderDstBlendFunc::enumVal: \ + return srcVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return 0; + } + } + + static GLenum fromBlendEquationToGL(NVRenderBlendEquation::Enum value, + bool nvAdvancedBlendSupported, + bool khrAdvancedBlendSupported) + { + switch (value) { + case NVRenderBlendEquation::Add: + return GL_FUNC_ADD; + case NVRenderBlendEquation::Subtract: + return GL_FUNC_SUBTRACT; + case NVRenderBlendEquation::ReverseSubtract: + return GL_FUNC_REVERSE_SUBTRACT; + default: + QT3DS_ASSERT(nvAdvancedBlendSupported || khrAdvancedBlendSupported); + break; + } + + if (nvAdvancedBlendSupported) { + switch (value) { + case NVRenderBlendEquation::Overlay: + return GL_OVERLAY_NV; + case NVRenderBlendEquation::ColorBurn: + return GL_COLORBURN_NV; + case NVRenderBlendEquation::ColorDodge: + return GL_COLORDODGE_NV; + default: + break; + } + } + +#if defined(GL_KHR_blend_equation_advanced) + if (khrAdvancedBlendSupported) { + switch (value) { + case NVRenderBlendEquation::Overlay: + return GL_OVERLAY_KHR; + case NVRenderBlendEquation::ColorBurn: + return GL_COLORBURN_KHR; + case NVRenderBlendEquation::ColorDodge: + return GL_COLORDODGE_KHR; + default: + break; + } + } +#endif + + QT3DS_ASSERT(false); + return GL_FUNC_ADD; + } + + static NVRenderFaces::Enum fromGLToFaces(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ + case x: \ + return NVRenderFaces::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderFaces::Unknown; + } + + static GLenum fromFacesToGL(NVRenderFaces::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ + case NVRenderFaces::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVReadFaces::Enum fromGLToReadFaces(GLenum value) + { + switch (value) { + case GL_FRONT: + return NVReadFaces::Front; + case GL_BACK: + return NVReadFaces::Back; + case GL_COLOR_ATTACHMENT0: + return NVReadFaces::Color0; + case GL_COLOR_ATTACHMENT1: + return NVReadFaces::Color1; + case GL_COLOR_ATTACHMENT2: + return NVReadFaces::Color2; + case GL_COLOR_ATTACHMENT3: + return NVReadFaces::Color3; + case GL_COLOR_ATTACHMENT4: + return NVReadFaces::Color4; + case GL_COLOR_ATTACHMENT5: + return NVReadFaces::Color5; + case GL_COLOR_ATTACHMENT6: + return NVReadFaces::Color6; + case GL_COLOR_ATTACHMENT7: + return NVReadFaces::Color7; + + default: + break; + } + QT3DS_ASSERT(false); + return NVReadFaces::Unknown; + } + + static GLenum fromReadFacesToGL(NVReadFaces::Enum value) + { + switch (value) { + case NVReadFaces::Front: + return GL_FRONT; + case NVReadFaces::Back: + return GL_BACK; + case NVReadFaces::Color0: + return GL_COLOR_ATTACHMENT0; + case NVReadFaces::Color1: + return GL_COLOR_ATTACHMENT1; + case NVReadFaces::Color2: + return GL_COLOR_ATTACHMENT2; + case NVReadFaces::Color3: + return GL_COLOR_ATTACHMENT3; + case NVReadFaces::Color4: + return GL_COLOR_ATTACHMENT4; + case NVReadFaces::Color5: + return GL_COLOR_ATTACHMENT5; + case NVReadFaces::Color6: + return GL_COLOR_ATTACHMENT6; + case NVReadFaces::Color7: + return GL_COLOR_ATTACHMENT7; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderWinding::Enum fromGLToWinding(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ + case x: \ + return NVRenderWinding::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderWinding::Unknown; + } + + static GLenum fromWindingToGL(NVRenderWinding::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ + case NVRenderWinding::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderBoolOp::Enum fromGLToBoolOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case x: \ + return NVRenderBoolOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderBoolOp::Unknown; + } + + static GLenum fromBoolOpToGL(NVRenderBoolOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case NVRenderBoolOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderHint::Enum fromGLToHint(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ + case x: \ + return NVRenderHint::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_HINT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderHint::Unknown; + } + + static GLenum fromHintToGL(NVRenderHint::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ + case NVRenderHint::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_HINT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderStencilOp::Enum fromGLToStencilOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ + case x: \ + return NVRenderStencilOp::y; + QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP + default: + break; + } + + QT3DS_ASSERT(false); + return NVRenderStencilOp::Unknown; + } + + static GLenum fromStencilOpToGL(NVRenderStencilOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ + case NVRenderStencilOp::y: \ + return x; + QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP + default: + break; + } + + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderComponentTypes::Enum fromGLToBufferComponentTypes(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ + case x: \ + return NVRenderComponentTypes::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderComponentTypes::Unknown; + } + + static GLenum fromBufferComponentTypesToGL(NVRenderComponentTypes::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ + case NVRenderComponentTypes::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) \ + case NVRenderComponentTypes::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromIndexBufferComponentsTypesToGL(NVRenderComponentTypes::Enum value) + { + switch (value) { + case NVRenderComponentTypes::QT3DSU8: + return GL_UNSIGNED_BYTE; + case NVRenderComponentTypes::QT3DSU16: + return GL_UNSIGNED_SHORT; + case NVRenderComponentTypes::QT3DSU32: + return GL_UNSIGNED_INT; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromBindBufferFlagsToGL(NVRenderBufferBindFlags flags) + { + QT3DSU32 value = flags; + GLenum retval = GL_INVALID_ENUM; + if (value & NVRenderBufferBindValues::Vertex) + retval = GL_ARRAY_BUFFER; + else if (value & NVRenderBufferBindValues::Index) + retval = GL_ELEMENT_ARRAY_BUFFER; + else if (value & NVRenderBufferBindValues::Constant) + retval = GL_UNIFORM_BUFFER; + else if (value & NVRenderBufferBindValues::Storage) + retval = GL_SHADER_STORAGE_BUFFER; + else if (value & NVRenderBufferBindValues::Atomic_Counter) + retval = GL_ATOMIC_COUNTER_BUFFER; + else if (value & NVRenderBufferBindValues::Draw_Indirect) + retval = GL_DRAW_INDIRECT_BUFFER; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderBufferBindFlags fromGLToBindBufferFlags(GLenum value) + { + QT3DSU32 retval = 0; + + if (value == GL_ARRAY_BUFFER) + retval |= NVRenderBufferBindValues::Vertex; + else if (value == GL_ELEMENT_ARRAY_BUFFER) + retval |= NVRenderBufferBindValues::Index; + else if (value == GL_UNIFORM_BUFFER) + retval |= NVRenderBufferBindValues::Constant; + else if (value == GL_SHADER_STORAGE_BUFFER) + retval |= NVRenderBufferBindValues::Storage; + else if (value == GL_ATOMIC_COUNTER_BUFFER) + retval |= NVRenderBufferBindValues::Atomic_Counter; + else if (value == GL_DRAW_INDIRECT_BUFFER) + retval |= NVRenderBufferBindValues::Draw_Indirect; + else + QT3DS_ASSERT(false); + + return NVRenderBufferBindFlags(retval); + } + + static NVRenderBufferUsageType::Enum fromGLToBufferUsageType(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ + case x: \ + return NVRenderBufferUsageType::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderBufferUsageType::Unknown; + } + + static GLenum fromBufferUsageTypeToGL(NVRenderBufferUsageType::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ + case NVRenderBufferUsageType::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromQueryTypeToGL(NVRenderQueryType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderQueryType::Samples) + retval = GL_ANY_SAMPLES_PASSED; +#if defined(GL_TIME_ELAPSED) + else if (type == NVRenderQueryType::Timer) + retval = GL_TIME_ELAPSED; +#elif defined(GL_TIME_ELAPSED_EXT) + else if (type == NVRenderQueryType::Timer) + retval = GL_TIME_ELAPSED_EXT; +#endif + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromQueryResultTypeToGL(NVRenderQueryResultType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderQueryResultType::ResultAvailable) + retval = GL_QUERY_RESULT_AVAILABLE; + else if (type == NVRenderQueryResultType::Result) + retval = GL_QUERY_RESULT; + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromSyncTypeToGL(NVRenderSyncType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderSyncType::GpuCommandsComplete) + retval = GL_SYNC_GPU_COMMANDS_COMPLETE; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderTextureFormats::Enum + replaceDeprecatedTextureFormat(NVRenderContextType type, NVRenderTextureFormats::Enum value, + NVRenderTextureSwizzleMode::Enum &swizzleMode) + { + NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderTextureFormats::Enum newValue = value; + swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + + if (!(type & deprecatedContextFlags)) { + switch (value) { + case NVRenderTextureFormats::Luminance8: + newValue = NVRenderTextureFormats::R8; + swizzleMode = NVRenderTextureSwizzleMode::L8toR8; + break; + case NVRenderTextureFormats::LuminanceAlpha8: + newValue = NVRenderTextureFormats::RG8; + swizzleMode = NVRenderTextureSwizzleMode::L8A8toRG8; + break; + case NVRenderTextureFormats::Alpha8: + newValue = NVRenderTextureFormats::R8; + swizzleMode = NVRenderTextureSwizzleMode::A8toR8; + break; + case NVRenderTextureFormats::Luminance16: + newValue = NVRenderTextureFormats::R16; + swizzleMode = NVRenderTextureSwizzleMode::L16toR16; + break; + default: + break; + } + } + + return newValue; + } + + static void + NVRenderConvertSwizzleModeToGL(const NVRenderTextureSwizzleMode::Enum swizzleMode, + GLint glSwizzle[4]) + { + switch (swizzleMode) { + case NVRenderTextureSwizzleMode::L16toR16: + case NVRenderTextureSwizzleMode::L8toR8: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_RED; + glSwizzle[2] = GL_RED; + glSwizzle[3] = GL_ONE; + break; + case NVRenderTextureSwizzleMode::L8A8toRG8: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_RED; + glSwizzle[2] = GL_RED; + glSwizzle[3] = GL_GREEN; + break; + case NVRenderTextureSwizzleMode::A8toR8: + glSwizzle[0] = GL_ZERO; + glSwizzle[1] = GL_ZERO; + glSwizzle[2] = GL_ZERO; + glSwizzle[3] = GL_RED; + break; + case NVRenderTextureSwizzleMode::NoSwizzle: + default: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_GREEN; + glSwizzle[2] = GL_BLUE; + glSwizzle[3] = GL_ALPHA; + break; + } + } + + static bool fromUncompressedTextureFormatToGL(NVRenderContextType type, + NVRenderTextureFormats::Enum value, + GLenum &outFormat, GLenum &outDataType, + GLenum &outInternalFormat) + { + switch (value) { + case NVRenderTextureFormats::R8: + if (type == NVRenderContextValues::GLES2) { + outFormat = GL_ALPHA; + outInternalFormat = GL_ALPHA; + } else { + outFormat = GL_RED; + outInternalFormat = GL_R8; + } + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RG8: + outFormat = GL_RG; + outInternalFormat = GL_RG8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGBA8: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGB8: + outFormat = GL_RGB; + outInternalFormat = GL_RGB8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGB565: + outFormat = GL_RGB; + outInternalFormat = GL_RGB8; + outDataType = GL_UNSIGNED_SHORT_5_6_5; + return true; + case NVRenderTextureFormats::RGBA5551: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA8; + outDataType = GL_UNSIGNED_SHORT_5_5_5_1; + return true; + case NVRenderTextureFormats::Alpha8: + outFormat = GL_ALPHA; + outInternalFormat = GL_ALPHA; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::Luminance8: + outFormat = GL_LUMINANCE; + outInternalFormat = GL_LUMINANCE; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::LuminanceAlpha8: + outFormat = GL_LUMINANCE_ALPHA; + outInternalFormat = GL_LUMINANCE_ALPHA; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::Luminance16: +#if defined(QT_OPENGL_ES) + outFormat = GL_LUMINANCE16F_EXT; + outInternalFormat = GL_LUMINANCE16F_EXT; +#else + outFormat = GL_LUMINANCE; + outInternalFormat = GL_LUMINANCE; +#endif + outDataType = GL_UNSIGNED_INT; + return true; + default: + break; + } + + NVRenderContextType contextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + // check extented texture formats + if (!(type & contextFlags)) { + switch (value) { +#if !defined(QT_OPENGL_ES) + case NVRenderTextureFormats::R16: { + if (IsGlEsContext(type)) { + outFormat = GL_RED_INTEGER; + outInternalFormat = GL_R16UI; + } else { + outFormat = GL_RED; + outInternalFormat = GL_R16; + } + outDataType = GL_UNSIGNED_SHORT; + return true; + } +#endif + case NVRenderTextureFormats::R16F: + outFormat = GL_RED; + outInternalFormat = GL_R16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::R32UI: + outFormat = GL_RED_INTEGER; + outInternalFormat = GL_R32UI; + outDataType = GL_UNSIGNED_INT; + return true; + case NVRenderTextureFormats::R32F: + outFormat = GL_RED; + outInternalFormat = GL_R32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGBA16F: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::RG16F: + outFormat = GL_RG; + outInternalFormat = GL_RG16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::RG32F: + outFormat = GL_RG; + outInternalFormat = GL_RG32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGBA32F: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGB32F: + outFormat = GL_RGB; + outInternalFormat = GL_RGB32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::R11G11B10: + outFormat = GL_RGB; + outInternalFormat = GL_R11F_G11F_B10F; + outDataType = GL_UNSIGNED_INT_10F_11F_11F_REV; + return true; + case NVRenderTextureFormats::RGB9E5: + outFormat = GL_RGB; + outInternalFormat = GL_RGB9_E5; + outDataType = GL_UNSIGNED_INT_5_9_9_9_REV; + return true; + case NVRenderTextureFormats::SRGB8: + outFormat = GL_RGB; + outInternalFormat = GL_SRGB8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::SRGB8A8: + outFormat = GL_RGBA; + outInternalFormat = GL_SRGB8_ALPHA8; + outDataType = GL_UNSIGNED_BYTE; + return true; + default: + break; + } + } + + QT3DS_ASSERT(false); + return false; + } + + static GLenum fromCompressedTextureFormatToGL(NVRenderTextureFormats::Enum value) + { + switch (value) { + case NVRenderTextureFormats::RGBA_DXT1: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case NVRenderTextureFormats::RGB_DXT1: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case NVRenderTextureFormats::RGBA_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case NVRenderTextureFormats::RGBA_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case NVRenderTextureFormats::R_ATI1N_UNorm: + return GL_COMPRESSED_RED_RGTC1; + case NVRenderTextureFormats::R_ATI1N_SNorm: + return GL_COMPRESSED_SIGNED_RED_RGTC1; + case NVRenderTextureFormats::RG_ATI2N_UNorm: + return GL_COMPRESSED_RG_RGTC2; + case NVRenderTextureFormats::RG_ATI2N_SNorm: + return GL_COMPRESSED_SIGNED_RG_RGTC2; + case NVRenderTextureFormats::RGB_BP_UNSIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_SIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_UNorm: + return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + case NVRenderTextureFormats::R11_EAC_UNorm: + return GL_COMPRESSED_R11_EAC; + case NVRenderTextureFormats::R11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_R11_EAC; + case NVRenderTextureFormats::RG11_EAC_UNorm: + return GL_COMPRESSED_RG11_EAC; + case NVRenderTextureFormats::RG11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_RG11_EAC; + case NVRenderTextureFormats::RGB8_ETC2: + return GL_COMPRESSED_RGB8_ETC2; + case NVRenderTextureFormats::SRGB8_ETC2: + return GL_COMPRESSED_SRGB8_ETC2; + case NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::RGBA8_ETC2_EAC: + return GL_COMPRESSED_RGBA8_ETC2_EAC; + case NVRenderTextureFormats::SRGB8_Alpha8_ETC2_EAC: + return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + case NVRenderTextureFormats::RGB8_ETC1: + return GL_ETC1_RGB8_OES; +#ifdef GL_KHR_texture_compression_astc_hdr + case NVRenderTextureFormats::RGBA_ASTC_4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x4: + return GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x5: + return GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x5: + return GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x6: + return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x5: + return GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x6: + return GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x8: + return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x5: + return GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x6: + return GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x8: + return GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x10: + return GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x10: + return GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x12: + return GL_COMPRESSED_RGBA_ASTC_12x12_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_4x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x12: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; +#endif // GL_KHR_texture_compression_astc_hdr + default: + break; + } + + QT3DS_ASSERT(false); + return 0; + } + + static bool fromDepthTextureFormatToGL(NVRenderContextType type, + NVRenderTextureFormats::Enum value, + GLenum &outFormat, GLenum &outDataType, + GLenum &outInternalFormat) + { + NVRenderContextType theContextFlags(NVRenderContextValues::GLES2 + | NVRenderContextValues::GL2); + + bool supportDepth24 = !(type & theContextFlags); + bool supportDepth32f = !(type & theContextFlags); + bool supportDepth24Stencil8 = !(type & theContextFlags); + + switch (value) { + case NVRenderTextureFormats::Depth16: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = GL_DEPTH_COMPONENT16; + outDataType = GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth24: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = (supportDepth24) ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth24) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth32: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = + (supportDepth32f) ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth32f) ? GL_FLOAT : GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth24Stencil8: + outFormat = (supportDepth24Stencil8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; + outInternalFormat = + (supportDepth24Stencil8) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth24Stencil8) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_SHORT; + return true; + default: + break; + } + + QT3DS_ASSERT(false); + return false; + } + + static GLenum fromTextureTargetToGL(NVRenderTextureTargetType::Enum value) + { + GLenum retval = 0; + if (value == NVRenderTextureTargetType::Texture2D) + retval = GL_TEXTURE_2D; + else if (value == NVRenderTextureTargetType::Texture2D_MS) + retval = GL_TEXTURE_2D_MULTISAMPLE; + else if (value == NVRenderTextureTargetType::Texture2D_Array) + retval = GL_TEXTURE_2D_ARRAY; + else if (value == NVRenderTextureTargetType::TextureCube) + retval = GL_TEXTURE_CUBE_MAP; + else if (value == NVRenderTextureTargetType::TextureCubeNegX) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + else if (value == NVRenderTextureTargetType::TextureCubePosX) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + else if (value == NVRenderTextureTargetType::TextureCubeNegY) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + else if (value == NVRenderTextureTargetType::TextureCubePosY) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + else if (value == NVRenderTextureTargetType::TextureCubeNegZ) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + else if (value == NVRenderTextureTargetType::TextureCubePosZ) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderTextureTargetType::Enum fromGLToTextureTarget(GLenum value) + { + NVRenderTextureTargetType::Enum retval = NVRenderTextureTargetType::Unknown; + + if (value == GL_TEXTURE_2D) + retval = NVRenderTextureTargetType::Texture2D; + else if (value == GL_TEXTURE_2D_MULTISAMPLE) + retval = NVRenderTextureTargetType::Texture2D_MS; + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromTextureUnitToGL(NVRenderTextureUnit::Enum value) + { + QT3DSU32 v = value; + GLenum retval = GL_TEXTURE0; + retval = GL_TEXTURE0 + v; + + return retval; + } + + static GLenum fromGLToTextureUnit(GLenum value) + { + QT3DS_ASSERT(value > GL_TEXTURE0); + + QT3DSU32 v = value - GL_TEXTURE0; + NVRenderTextureUnit::Enum retval = + NVRenderTextureUnit::Enum(NVRenderTextureUnit::TextureUnit_0 + v); + + return retval; + } + + static GLenum fromTextureMinifyingOpToGL(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case NVRenderTextureMinifyingOp::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ + case NVRenderTextureMinifyingOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureMinifyingOp::Enum fromGLToTextureMinifyingOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case x: \ + return NVRenderTextureMinifyingOp::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ + case x: \ + return NVRenderTextureMinifyingOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureMinifyingOp::Unknown; + } + + static GLenum fromTextureMagnifyingOpToGL(NVRenderTextureMagnifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case NVRenderTextureMagnifyingOp::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureMagnifyingOp::Enum fromGLToTextureMagnifyingOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case x: \ + return NVRenderTextureMagnifyingOp::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureMagnifyingOp::Unknown; + } + + static GLenum fromTextureCoordOpToGL(NVRenderTextureCoordOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ + case NVRenderTextureCoordOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureCoordOp::Enum fromGLToTextureCoordOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ + case x: \ + return NVRenderTextureCoordOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureCoordOp::Unknown; + } + + static GLenum fromTextureCompareModeToGL(NVRenderTextureCompareMode::Enum value) + { + switch (value) { + case NVRenderTextureCompareMode::NoCompare: + return GL_NONE; + case NVRenderTextureCompareMode::CompareToRef: + return GL_COMPARE_REF_TO_TEXTURE; + default: + break; + } + + QT3DS_ASSERT(false); + return NVRenderTextureCompareMode::Unknown; + } + + static GLenum fromGLToTextureCompareMode(GLenum value) + { + switch (value) { + case GL_NONE: + return NVRenderTextureCompareMode::NoCompare; + case GL_COMPARE_REF_TO_TEXTURE: + return NVRenderTextureCompareMode::CompareToRef; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static GLenum fromTextureCompareFuncToGL(NVRenderTextureCompareOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case NVRenderTextureCompareOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromImageFormatToGL(NVRenderTextureFormats::Enum value) + { + switch (value) { + case NVRenderTextureFormats::R8: + return GL_R8; + case NVRenderTextureFormats::R32I: + return GL_R32I; + case NVRenderTextureFormats::R32UI: + return GL_R32UI; + case NVRenderTextureFormats::R32F: + return GL_R32F; + case NVRenderTextureFormats::RGBA8: + return GL_RGBA8; + case NVRenderTextureFormats::SRGB8A8: + return GL_RGBA8_SNORM; + case NVRenderTextureFormats::RG16F: + return GL_RG16F; + case NVRenderTextureFormats::RGBA16F: + return GL_RGBA16F; + case NVRenderTextureFormats::RGBA32F: + return GL_RGBA32F; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + + static GLenum fromImageAccessToGL(NVRenderImageAccessType::Enum value) + { + switch (value) { + case NVRenderImageAccessType::Read: + return GL_READ_ONLY; + case NVRenderImageAccessType::Write: + return GL_WRITE_ONLY; + case NVRenderImageAccessType::ReadWrite: + return GL_READ_WRITE; + default: + break; + } + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static GLbitfield fromBufferAccessBitToGL(NVRenderBufferAccessFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; + + if (value & NVRenderBufferAccessTypeValues::Read) + retval |= GL_MAP_READ_BIT; + if (value & NVRenderBufferAccessTypeValues::Write) + retval |= GL_MAP_WRITE_BIT; + if (value & NVRenderBufferAccessTypeValues::Invalid) + retval |= GL_MAP_INVALIDATE_BUFFER_BIT; + if (value & NVRenderBufferAccessTypeValues::InvalidRange) + retval |= GL_MAP_INVALIDATE_RANGE_BIT; + + QT3DS_ASSERT(retval); + return retval; + } + + static GLbitfield fromMemoryBarrierFlagsToGL(NVRenderBufferBarrierFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderBufferBarrierValues::AtomicCounter) + retval |= GL_ATOMIC_COUNTER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::BufferUpdate) + retval |= GL_BUFFER_UPDATE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::CommandBuffer) + retval |= GL_COMMAND_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ElementArray) + retval |= GL_ELEMENT_ARRAY_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::Framebuffer) + retval |= GL_FRAMEBUFFER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::PixelBuffer) + retval |= GL_PIXEL_BUFFER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ShaderImageAccess) + retval |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ShaderStorage) + retval |= GL_SHADER_STORAGE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TextureFetch) + retval |= GL_TEXTURE_FETCH_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TextureUpdate) + retval |= GL_TEXTURE_UPDATE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TransformFeedback) + retval |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::UniformBuffer) + retval |= GL_UNIFORM_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::VertexAttribArray) + retval |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; +#endif + QT3DS_ASSERT(retval); + return retval; + } + + static GLbitfield fromShaderTypeFlagsToGL(NVRenderShaderTypeFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; + if (value & NVRenderShaderTypeValue::Vertex) + retval |= GL_VERTEX_SHADER_BIT; + if (value & NVRenderShaderTypeValue::Fragment) + retval |= GL_FRAGMENT_SHADER_BIT; + if (value & NVRenderShaderTypeValue::TessControl) + retval |= GL_TESS_CONTROL_SHADER_BIT; + if (value & NVRenderShaderTypeValue::TessEvaluation) + retval |= GL_TESS_EVALUATION_SHADER_BIT; + if (value & NVRenderShaderTypeValue::Geometry) +#if defined(QT_OPENGL_ES_3_1) + retval |= GL_GEOMETRY_SHADER_BIT_EXT; +#else + retval |= GL_GEOMETRY_SHADER_BIT; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + + static GLenum fromPropertyDataTypesToShaderGL(NVRenderShaderDataTypes::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ + case NVRenderShaderDataTypes::nv: \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderShaderDataTypes::Enum fromShaderGLToPropertyDataTypes(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ + case gl: \ + return NVRenderShaderDataTypes::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES + case GL_SAMPLER_2D_SHADOW: + return NVRenderShaderDataTypes::NVRenderTexture2DPtr; +#if !defined(QT_OPENGL_ES) + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return NVRenderShaderDataTypes::QT3DSU32; + case GL_UNSIGNED_INT_IMAGE_2D: + return NVRenderShaderDataTypes::NVRenderImage2DPtr; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderShaderDataTypes::Unknown; + } + + static GLenum fromComponentTypeAndNumCompsToAttribGL(NVRenderComponentTypes::Enum compType, + QT3DSU32 numComps) + { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ + if (compType == NVRenderComponentTypes::ct && numComps == nc) \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES + QT3DS_ASSERT(false); + return 0; + } + + static void fromAttribGLToComponentTypeAndNumComps( + GLenum enumVal, NVRenderComponentTypes::Enum &outCompType, QT3DSU32 &outNumComps) + { + switch (enumVal) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ + case gl: \ + outCompType = NVRenderComponentTypes::ct; \ + outNumComps = nc; \ + return; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES + default: + break; + } + QT3DS_ASSERT(false); + outCompType = NVRenderComponentTypes::Unknown; + outNumComps = 0; + } + + static GLenum + fromRenderBufferFormatsToRenderBufferGL(NVRenderRenderBufferFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ + case NVRenderRenderBufferFormats::nv: \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderRenderBufferFormats::Enum + fromRenderBufferGLToRenderBufferFormats(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ + case gl: \ + return NVRenderRenderBufferFormats::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderRenderBufferFormats::Unknown; + } + + static GLenum fromFramebufferAttachmentsToGL(NVRenderFrameBufferAttachments::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ + case NVRenderFrameBufferAttachments::x: \ + return GL_COLOR_ATTACHMENT0 + idx; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ + case NVRenderFrameBufferAttachments::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderFrameBufferAttachments::Unknown; + } + + static NVRenderFrameBufferAttachments::Enum fromGLToFramebufferAttachments(GLenum value) + { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ + if (value == GL_COLOR_ATTACHMENT0 + idx) \ + return NVRenderFrameBufferAttachments::x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ + if (value == x) \ + return NVRenderFrameBufferAttachments::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT + QT3DS_ASSERT(false); + return NVRenderFrameBufferAttachments::Unknown; + } + + static GLbitfield fromClearFlagsToGL(NVRenderClearFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ + if ((value & NVRenderClearValues::nv)) \ + retval |= gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS + return retval; + } + + static NVRenderClearFlags fromGLToClearFlags(GLbitfield value) + { + QT3DSU32 retval = 0; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ + if ((value & gl)) \ + retval |= NVRenderClearValues::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS + return NVRenderClearFlags(retval); + } + + static GLenum fromDrawModeToGL(NVRenderDrawMode::Enum value, bool inTesselationSupported) + { + switch (value) { + case NVRenderDrawMode::Points: + return GL_POINTS; + case NVRenderDrawMode::Lines: + return GL_LINES; + case NVRenderDrawMode::LineStrip: + return GL_LINE_STRIP; + case NVRenderDrawMode::LineLoop: + return GL_LINE_LOOP; + case NVRenderDrawMode::TriangleStrip: + return GL_TRIANGLE_STRIP; + case NVRenderDrawMode::TriangleFan: + return GL_TRIANGLE_FAN; + case NVRenderDrawMode::Triangles: + return GL_TRIANGLES; + case NVRenderDrawMode::Patches: + return (inTesselationSupported) ? GL_PATCHES : GL_TRIANGLES; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static NVRenderDrawMode::Enum fromGLToDrawMode(GLenum value) + { + switch (value) { + case GL_POINTS: + return NVRenderDrawMode::Points; + case GL_LINES: + return NVRenderDrawMode::Lines; + case GL_LINE_STRIP: + return NVRenderDrawMode::LineStrip; + case GL_LINE_LOOP: + return NVRenderDrawMode::LineLoop; + case GL_TRIANGLE_STRIP: + return NVRenderDrawMode::TriangleStrip; + case GL_TRIANGLE_FAN: + return NVRenderDrawMode::TriangleFan; + case GL_TRIANGLES: + return NVRenderDrawMode::Triangles; + case GL_PATCHES: + return NVRenderDrawMode::Patches; + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderDrawMode::Unknown; + } + + static GLenum fromRenderStateToGL(NVRenderState::Enum value) + { + switch (value) { + case NVRenderState::Blend: + return GL_BLEND; + case NVRenderState::CullFace: + return GL_CULL_FACE; + case NVRenderState::DepthTest: + return GL_DEPTH_TEST; + case NVRenderState::Multisample: +#if defined(QT_OPENGL_ES) + return GL_MULTISAMPLE_EXT; +#else + return GL_MULTISAMPLE; +#endif + case NVRenderState::StencilTest: + return GL_STENCIL_TEST; + case NVRenderState::ScissorTest: + return GL_SCISSOR_TEST; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderState::Enum fromGLToRenderState(GLenum value) + { + switch (value) { + case GL_BLEND: + return NVRenderState::Blend; + case GL_CULL_FACE: + return NVRenderState::CullFace; + case GL_DEPTH_TEST: + return NVRenderState::DepthTest; +#if defined(QT_OPENGL_ES) + case GL_MULTISAMPLE_EXT: +#else + case GL_MULTISAMPLE: +#endif + return NVRenderState::Multisample; + case GL_STENCIL_TEST: + return NVRenderState::StencilTest; + case GL_SCISSOR_TEST: + return NVRenderState::ScissorTest; + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderState::Unknown; + } + + static bool fromReadPixelsToGlFormatAndType(NVRenderReadPixelFormats::Enum inReadPixels, + GLuint *outFormat, GLuint *outType) + { + switch (inReadPixels) { + case NVRenderReadPixelFormats::Alpha8: + *outFormat = GL_ALPHA; + *outType = GL_UNSIGNED_BYTE; + break; + case NVRenderReadPixelFormats::RGB565: + *outFormat = GL_RGB; + *outType = GL_UNSIGNED_SHORT_5_6_5; + case NVRenderReadPixelFormats::RGB8: + *outFormat = GL_RGB; + *outType = GL_UNSIGNED_BYTE; + break; + case NVRenderReadPixelFormats::RGBA4444: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case NVRenderReadPixelFormats::RGBA5551: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case NVRenderReadPixelFormats::RGBA8: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_BYTE; + break; + default: + *outFormat = 0; + *outType = 0; + QT3DS_ASSERT(false); + return false; + }; + + return true; + } + + static GLenum fromPathFillModeToGL(NVRenderPathFillMode::Enum inMode) + { + GLenum glFillMode; + + switch (inMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathFillMode::Fill: + glFillMode = GL_PATH_FILL_MODE_NV; + break; + case NVRenderPathFillMode::CountUp: + glFillMode = GL_COUNT_UP_NV; + break; + case NVRenderPathFillMode::CountDown: + glFillMode = GL_COUNT_DOWN_NV; + break; + case NVRenderPathFillMode::Invert: + glFillMode = GL_INVERT; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glFillMode; + } + + static GLenum fromPathFontTargetToGL(NVRenderPathFontTarget::Enum inFontTarget) + { + GLenum glFontTarget; + + switch (inFontTarget) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathFontTarget::StandardFont: + glFontTarget = GL_STANDARD_FONT_NAME_NV; + break; + case NVRenderPathFontTarget::SystemFont: + glFontTarget = GL_SYSTEM_FONT_NAME_NV; + break; + case NVRenderPathFontTarget::FileFont: + glFontTarget = GL_FILE_NAME_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glFontTarget; + } + + static NVRenderPathReturnValues::Enum fromGLToPathFontReturn(GLenum inReturnValue) + { + NVRenderPathReturnValues::Enum returnValue; + + switch (inReturnValue) { +#if !defined(QT_OPENGL_ES) + case GL_FONT_GLYPHS_AVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontGlypsAvailable; + break; + case GL_FONT_TARGET_UNAVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontTargetUnavailable; + break; + case GL_FONT_UNAVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontUnavailable; + break; + case GL_FONT_UNINTELLIGIBLE_NV: + returnValue = NVRenderPathReturnValues::FontUnintelligible; + break; +#endif + case GL_INVALID_ENUM: + case GL_INVALID_VALUE: + returnValue = NVRenderPathReturnValues::InvalidEnum; + break; + case GL_OUT_OF_MEMORY: + returnValue = NVRenderPathReturnValues::OutOfMemory; + break; + default: + QT3DS_ASSERT(false); + returnValue = NVRenderPathReturnValues::FontTargetUnavailable; + break; + } + + return returnValue; + } + + static GLenum fromPathMissingGlyphsToGL(NVRenderPathMissingGlyphs::Enum inHandleGlyphs) + { + GLenum glMissingGlyphs; + + switch (inHandleGlyphs) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathMissingGlyphs::SkipMissing: + glMissingGlyphs = GL_SKIP_MISSING_GLYPH_NV; + break; + case NVRenderPathMissingGlyphs::UseMissing: + glMissingGlyphs = GL_USE_MISSING_GLYPH_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glMissingGlyphs; + } + + static GLenum fromPathListModeToGL(NVRenderPathListMode::Enum inListMode) + { + GLenum glListMode; + + switch (inListMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathListMode::AccumAdjacentPairs: + glListMode = GL_ACCUM_ADJACENT_PAIRS_NV; + break; + case NVRenderPathListMode::AdjacentPairs: + glListMode = GL_ADJACENT_PAIRS_NV; + break; + case NVRenderPathListMode::FirstToRest: + glListMode = GL_FIRST_TO_REST_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glListMode; + } + + static GLenum fromPathCoverModeToGL(NVRenderPathCoverMode::Enum inMode) + { + GLenum glCoverMode; + + switch (inMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathCoverMode::ConvexHull: + glCoverMode = GL_CONVEX_HULL_NV; + break; + case NVRenderPathCoverMode::BoundingBox: + glCoverMode = GL_BOUNDING_BOX_NV; + break; + case NVRenderPathCoverMode::BoundingBoxOfBoundingBox: + glCoverMode = GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV; + break; + case NVRenderPathCoverMode::PathFillCover: + glCoverMode = GL_PATH_FILL_COVER_MODE_NV; + break; + case NVRenderPathCoverMode::PathStrokeCover: + glCoverMode = GL_PATH_STROKE_COVER_MODE_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glCoverMode; + } + + static GLenum fromPathTypeToGL(NVRenderPathFormatType::Enum value) + { + switch (value) { + case NVRenderPathFormatType::Byte: + return GL_BYTE; + case NVRenderPathFormatType::UByte: + return GL_UNSIGNED_BYTE; + case NVRenderPathFormatType::Short: + return GL_SHORT; + case NVRenderPathFormatType::UShort: + return GL_UNSIGNED_SHORT; + case NVRenderPathFormatType::Int: + return GL_INT; + case NVRenderPathFormatType::Uint: + return GL_UNSIGNED_INT; +#if !defined(QT_OPENGL_ES) + case NVRenderPathFormatType::Bytes2: + return GL_2_BYTES_NV; + case NVRenderPathFormatType::Bytes3: + return GL_3_BYTES_NV; + case NVRenderPathFormatType::Bytes4: + return GL_4_BYTES_NV; + case NVRenderPathFormatType::Utf8: + return GL_UTF8_NV; + case NVRenderPathFormatType::Utf16: + return GL_UTF16_NV; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return GL_UNSIGNED_BYTE; + } + + static GLbitfield fromPathFontStyleToGL(NVRenderPathFontStyleFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderPathFontStyleValues::Bold) + retval |= GL_BOLD_BIT_NV; + if (value & NVRenderPathFontStyleValues::Italic) + retval |= GL_ITALIC_BIT_NV; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + + static GLenum fromPathTransformToGL(NVRenderPathTransformType::Enum value) + { + switch (value) { + case NVRenderPathTransformType::NoTransform: + return GL_NONE; +#if !defined(QT_OPENGL_ES) + case NVRenderPathTransformType::TranslateX: + return GL_TRANSLATE_X_NV; + case NVRenderPathTransformType::TranslateY: + return GL_TRANSLATE_Y_NV; + case NVRenderPathTransformType::Translate2D: + return GL_TRANSLATE_2D_NV; + case NVRenderPathTransformType::Translate3D: + return GL_TRANSLATE_3D_NV; + case NVRenderPathTransformType::Affine2D: + return GL_AFFINE_2D_NV; + case NVRenderPathTransformType::Affine3D: + return GL_AFFINE_3D_NV; + case NVRenderPathTransformType::TransposeAffine2D: + return GL_TRANSPOSE_AFFINE_2D_NV; + case NVRenderPathTransformType::TransposeAffine3D: + return GL_TRANSPOSE_AFFINE_3D_NV; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return GL_UNSIGNED_BYTE; + } + + static GLbitfield fromPathMetricQueryFlagsToGL(NVRenderPathGlyphFontMetricFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderPathGlyphFontMetricValues::GlyphWidth) + retval |= GL_GLYPH_WIDTH_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHeight) + retval |= GL_GLYPH_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingX) + retval |= GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingY) + retval |= GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingAdvance) + retval |= GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingX) + retval |= GL_GLYPH_VERTICAL_BEARING_X_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingY) + retval |= GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingAdvance) + retval |= GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHasKerning) + retval |= GL_GLYPH_HAS_KERNING_BIT_NV; + + if (value & NVRenderPathGlyphFontMetricValues::FontXMinBounds) + retval |= GL_FONT_X_MIN_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontYMinBounds) + retval |= GL_FONT_Y_MIN_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontXMaxBounds) + retval |= GL_FONT_X_MAX_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontYMaxBounds) + retval |= GL_FONT_Y_MAX_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontUnitsPerEm) + retval |= GL_FONT_UNITS_PER_EM_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontAscender) + retval |= GL_FONT_ASCENDER_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontDescender) + retval |= GL_FONT_DESCENDER_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontHeight) + retval |= GL_FONT_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) + retval |= GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceHeight) + retval |= GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontUnderlinePosition) + retval |= GL_FONT_UNDERLINE_POSITION_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) + retval |= GL_FONT_UNDERLINE_THICKNESS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontHasKerning) + retval |= GL_FONT_HAS_KERNING_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontNumGlyphIndices) + retval |= GL_FONT_NUM_GLYPH_INDICES_BIT_NV; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + }; +} +} + +#endif // QT3DSOPENGLUTIL_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp new file mode 100644 index 00000000..d78c51d9 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp @@ -0,0 +1,784 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +#if defined(QT_OPENGL_ES) +#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_TIMER_EXT(x) m_timerExtension->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_tessellationShader->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_MULTISAMPLE_EXT(x) m_multiSample->x; RENDER_LOG_ERROR_PARAMS(x); +#endif + +namespace qt3ds { +namespace render { + +#ifndef GL_PATCH_VERTICES +#define GL_PATCH_VERTICES 0x8E72 +#endif + + /// constructor + NVRenderBackendGL3Impl::NVRenderBackendGL3Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGLBase(fnd, stringTable, format) + { + eastl::string exts3tc("GL_EXT_texture_compression_s3tc"); + eastl::string extsdxt("GL_EXT_texture_compression_dxt1"); + eastl::string extsAniso("GL_EXT_texture_filter_anisotropic"); + eastl::string extsTexSwizzle("GL_ARB_texture_swizzle"); + eastl::string extsAstcHDR("GL_KHR_texture_compression_astc_hdr"); + eastl::string extsAstcLDR("GL_KHR_texture_compression_astc_ldr"); + eastl::string extsFPRenderTarget("GL_EXT_color_buffer_float"); + eastl::string extsTimerQuery("GL_EXT_timer_query"); + eastl::string extsGpuShader5("EXT_gpu_shader5"); + + const char *languageVersion = GetShadingLanguageVersion(); + qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + eastl::string apiVendor(getVendorString()); + qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); + + eastl::string apiRenderer(getRendererString()); + qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); + + // clear support bits + m_backendSupport.caps.u32Values = 0; + + // get extension count + GLint numExtensions = 0; + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); + + eastl::string extensionBuffer; + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); + + m_extensions.push_back(QString::fromLocal8Bit(extensionString)); + + if (extensionBuffer.size()) + extensionBuffer.append(" "); + extensionBuffer.append(extensionString); + + // search for extension + if (!m_backendSupport.caps.bits.bDXTImagesSupported + && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { + m_backendSupport.caps.bits.bDXTImagesSupported = true; + } else if (!m_backendSupport.caps.bits.bAnistropySupported + && extsAniso.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAnistropySupported = true; + } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported + && extsFPRenderTarget.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + } else if (!m_backendSupport.caps.bits.bTimerQuerySupported + && extsTimerQuery.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported + && extsGpuShader5.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; + } + + } + + qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensionBuffer.c_str()); + + // texture swizzle is always true + m_backendSupport.caps.bits.bTextureSwizzleSupported = true; + // depthstencil renderbuffer support is always true + m_backendSupport.caps.bits.bDepthStencilSupported = true; + // constant buffers support is always true + m_backendSupport.caps.bits.bConstantBufferSupported = true; + m_backendSupport.caps.bits.bStandardDerivativesSupported = true; + m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; + m_backendSupport.caps.bits.bTextureLodSupported = true; + + if (!isESCompatible()) { + // render to float textures is always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + // multisampled texture is always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bMsTextureSupported = true; + // timer queries are always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } + + // query hardware + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); + + // internal state tracker + m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); + + // finally setup caps based on device + setAndInspectHardwareCaps(); + + // Initialize extensions +#if defined(QT_OPENGL_ES_2) + m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#else + m_timerExtension = new QOpenGLExtension_ARB_timer_query; + m_timerExtension->initializeOpenGLFunctions(); + m_tessellationShader = new QOpenGLExtension_ARB_tessellation_shader; + m_tessellationShader->initializeOpenGLFunctions(); + m_multiSample = new QOpenGLExtension_ARB_texture_multisample; + m_multiSample->initializeOpenGLFunctions(); + m_qt3dsExtensions = new Qt3DSOpenGLExtensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#endif + } + /// destructor + NVRenderBackendGL3Impl::~NVRenderBackendGL3Impl() + { + if (m_pCurrentMiscState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); +#if !defined(QT_OPENGL_ES_2) + if (m_timerExtension) + delete m_timerExtension; + if (m_tessellationShader) + delete m_tessellationShader; + if (m_multiSample) + delete m_multiSample; +#endif + if (m_qt3dsExtensions) + delete m_qt3dsExtensions; + } + + void NVRenderBackendGL3Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) + { +// Not supported by ES 3 yet +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(samples); + NVRENDER_BACKEND_UNUSED(internalFormat); + NVRENDER_BACKEND_UNUSED(width); + NVRENDER_BACKEND_UNUSED(height); + NVRENDER_BACKEND_UNUSED(fixedsamplelocations); +#else + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + GL_CALL_MULTISAMPLE_EXT(glTexImage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, + (GLsizei)width, (GLsizei)height, fixedsamplelocations)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +#endif + } + + void NVRenderBackendGL3Impl::SetTextureData3D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, + QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + (GLsizei)depth, border, glformat, gltype, hostPtr)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGL3Impl::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + + // Satisfy the compiler + // These are not available in GLES 3 and we don't use them right now + QT3DS_ASSERT(lodBias == 0.0); + QT3DS_ASSERT(!borderColor); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(borderColor); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_R, + m_Conversion.fromTextureCoordOpToGL(wrapR))); + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MIN_LOD, minLod)); + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_LOD, maxLod)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE, + m_Conversion.fromTextureCompareModeToGL(compareMode))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC, + m_Conversion.fromTextureCompareFuncToGL(compareFunc))); + + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy)); + } + } + + void NVRenderBackendGL3Impl::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) + { + NVRENDER_BACKEND_UNUSED(to); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); + } + + void NVRenderBackendGL3Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) + { + NVRENDER_BACKEND_UNUSED(to); + if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { + GLint glSwizzle[4]; + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); +#if defined(QT_OPENGL_ES) + // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); +#else + GL_CALL_EXTRA_FUNCTION(glTexParameteriv(glTarget, GL_TEXTURE_SWIZZLE_RGBA, glSwizzle)); +#endif + } + } + + QT3DSU32 + NVRenderBackendGL3Impl::GetDepthBits() const + { + QT3DSI32 depthBits; + GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv( + GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); + + return depthBits; + } + + QT3DSU32 + NVRenderBackendGL3Impl::GetStencilBits() const + { + QT3DSI32 stencilBits; + GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilBits)); + + return stencilBits; + } + + void NVRenderBackendGL3Impl::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum /*genType*/) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + bool NVRenderBackendGL3Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) + { + if (iao == NULL) { + // unbind and return; + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(0)); + return true; + } + + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + NVDataRef shaderAttribBuffer; + if (pProgram->m_shaderInput) + shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; + + if (attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) + return false; + + if (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot) { + QT3DS_ASSERT(false); + return false; + } + + if (inputAssembler->m_VaoID == 0) { + // generate vao + GL_CALL_EXTRA_FUNCTION(glGenVertexArrays(1, &inputAssembler->m_VaoID)); + QT3DS_ASSERT(inputAssembler->m_VaoID); + } + + // set patch parameter count if changed + if (m_backendSupport.caps.bits.bTessellationSupported + && m_pCurrentMiscState->m_PatchVertexCount != inputAssembler->m_PatchVertexCount) { + m_pCurrentMiscState->m_PatchVertexCount = inputAssembler->m_PatchVertexCount; +#if defined(QT_OPENGL_ES) + GL_CALL_TESSELATION_EXT(glPatchParameteriEXT(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); +#else + GL_CALL_TESSELATION_EXT(glPatchParameteri(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); +#endif + } + + if (inputAssembler->m_cachedShaderHandle != programID) { + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); + inputAssembler->m_cachedShaderHandle = programID; + + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents) { + qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + return false; + } else { + entryData.m_AttribIndex = attrib.m_AttribLocation; + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + + // disable max possible used first + // this is currently sufficient since we always re-arrange input attributes from 0 + for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); + } + + // setup all attribs + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); + if (entry) { + const NVRenderBackendLayoutEntryGL &entryData(*entry); + GLuint id = HandleToID_cast( + GLuint, size_t, + inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); + GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); + GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; + GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; + GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( + entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, + stride, (const void *)(entryData.m_Offset + offset))); + + } else { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); + } + } + + // setup index buffer. + if (inputAssembler->m_IndexbufferHandle) { + GL_CALL_EXTRA_FUNCTION(glBindBuffer( + GL_ELEMENT_ARRAY_BUFFER, + HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); + } else { + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + } else { + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); + } +#ifdef _DEBUG + if (inputAssembler->m_VaoID) { + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents + || entryData.m_AttribIndex != attrib.m_AttribLocation) { + qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + } +#endif // _DEBUG + + return true; + } + + void NVRenderBackendGL3Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) + { + NVRENDER_BACKEND_UNUSED(rto); + + m_DrawBuffersArray.clear(); + + for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { + if (inDrawBufferSet[idx] < 0) + m_DrawBuffersArray.push_back(GL_NONE); + else + m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); + } + + GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), m_DrawBuffersArray.data())); + } + + void NVRenderBackendGL3Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) + { + NVRENDER_BACKEND_UNUSED(rto); + + GL_CALL_EXTRA_FUNCTION(glReadBuffer(m_Conversion.fromReadFacesToGL(inReadFace))); + } + + void NVRenderBackendGL3Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) + { + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_EXTRA_FUNCTION(glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttach, texID, level, layer)) + } + + void NVRenderBackendGL3Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); + } + + void NVRenderBackendGL3Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) + { + GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + m_Conversion.fromClearFlagsToGL(flags), + m_Conversion.fromTextureMagnifyingOpToGL(filter))); + } + + void *NVRenderBackendGL3Impl::MapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t length, NVRenderBufferAccessFlags accessFlags) + { + void *ret = NULL; + ret = GL_CALL_EXTRA_FUNCTION(glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, + length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); + + return ret; + } + + bool NVRenderBackendGL3Impl::UnmapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags) + { + GLboolean ret; + + ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); + + return (ret) ? true : false; + } + + QT3DSI32 NVRenderBackendGL3Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLint numUniformBuffers; + GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBuffers)); + + return numUniformBuffers; + } + + QT3DSI32 + NVRenderBackendGL3Impl::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + GLuint blockIndex = GL_INVALID_INDEX; + + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, nameBuf)); + + if (*length > 0) { + blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); + if (blockIndex != GL_INVALID_INDEX) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); + } + } + + return blockIndex; + } + + void + NVRenderBackendGL3Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (indices) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices)); + } + } + + void NVRenderBackendGL3Impl::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(count); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (count && indices) { + if (type) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_TYPE, type)); + // convert to UIC types + QT3DS_FOREACH(idx, count) + { + type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); + } + } + if (size) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_SIZE, size)); + } + if (offset) { + GL_CALL_EXTRA_FUNCTION( + glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); + } + } + } + + void NVRenderBackendGL3Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); + } + + void NVRenderBackendGL3Impl::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + QT3DS_ASSERT(bo); + + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); + } + + NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGL3Impl::CreateQuery() + { + QT3DSU32 glQueryID = 0; + + GL_CALL_EXTRA_FUNCTION(glGenQueries(1, &glQueryID)); + + return (NVRenderBackendQueryObject)glQueryID; + } + + void NVRenderBackendGL3Impl::ReleaseQuery(NVRenderBackendQueryObject qo) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + GL_CALL_EXTRA_FUNCTION(glDeleteQueries(1, &queryID)); + } + + void NVRenderBackendGL3Impl::BeginQuery(NVRenderBackendQueryObject qo, + NVRenderQueryType::Enum type) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + GL_CALL_EXTRA_FUNCTION(glBeginQuery(m_Conversion.fromQueryTypeToGL(type), queryID)); + } + + void NVRenderBackendGL3Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum type) + { + GL_CALL_EXTRA_FUNCTION(glEndQuery(m_Conversion.fromQueryTypeToGL(type))); + } + + void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, + QT3DSU32 *params) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + if (params) + GL_CALL_EXTRA_FUNCTION(glGetQueryObjectuiv( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); + } + + void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, + QT3DSU64 *params) + { + if (m_backendSupport.caps.bits.bTimerQuerySupported) { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + if (params) +#if defined(QT_OPENGL_ES) + GL_CALL_TIMER_EXT(glGetQueryObjectui64vEXT( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); +#else + GL_CALL_TIMER_EXT(glGetQueryObjectui64v( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); +#endif + } + } + + void NVRenderBackendGL3Impl::SetQueryTimer(NVRenderBackendQueryObject qo) + { + if (m_backendSupport.caps.bits.bTimerQuerySupported) { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); +#if defined(QT_OPENGL_ES) + GL_CALL_TIMER_EXT(glQueryCounterEXT(queryID, GL_TIMESTAMP_EXT)); +#else + GL_CALL_TIMER_EXT(glQueryCounter(queryID, GL_TIMESTAMP)); +#endif + } + } + + NVRenderBackend::NVRenderBackendSyncObject + NVRenderBackendGL3Impl::CreateSync(NVRenderSyncType::Enum syncType, NVRenderSyncFlags) + { + GLsync syncID = 0; + + syncID = GL_CALL_EXTRA_FUNCTION(glFenceSync(m_Conversion.fromSyncTypeToGL(syncType), 0)); + + return NVRenderBackendSyncObject(syncID); + } + + void NVRenderBackendGL3Impl::ReleaseSync(NVRenderBackendSyncObject so) + { + GLsync syncID = (GLsync)so; + + GL_CALL_EXTRA_FUNCTION(glDeleteSync(syncID)); + } + + void NVRenderBackendGL3Impl::WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags, + QT3DSU64) + { + GLsync syncID = (GLsync)so; + + GL_CALL_EXTRA_FUNCTION(glWaitSync(syncID, 0, GL_TIMEOUT_IGNORED)); + } +} +} diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h new file mode 100644 index 00000000..7147b341 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL3_H +#define QT3DS_RENDER_BACKEND_GL3_H + +/// @file Qt3DSRenderBackendGL3.h +/// NVRender OpenGL 3 backend definition. + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +#include +#include + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendMiscStateGL; + + using namespace foundation; + + class NVRenderBackendGL3Impl : public NVRenderBackendGLBase + { + public: + /// constructor + NVRenderBackendGL3Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGL3Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override; + + void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) override; + void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) override; + + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; + void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; + + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + protected: + NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state +#if defined(QT_OPENGL_ES_2) + Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; +#else + QOpenGLExtension_ARB_timer_query *m_timerExtension; + QOpenGLExtension_ARB_tessellation_shader *m_tessellationShader; + QOpenGLExtension_ARB_texture_multisample *m_multiSample; + Qt3DSOpenGLExtensions *m_qt3dsExtensions; +#endif + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp new file mode 100644 index 00000000..083fc35e --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp @@ -0,0 +1,875 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGL4.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +#if defined(QT_OPENGL_ES) +#define GL_CALL_NVPATH_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_NVPATH_EXT(x) m_nvPathRendering->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_DIRECTSTATE_EXT(x) m_directStateAccess->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#endif + +#ifndef GL_GEOMETRY_SHADER_EXT +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#endif + +namespace qt3ds { +namespace render { + + /// constructor + NVRenderBackendGL4Impl::NVRenderBackendGL4Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGL3Impl(fnd, stringTable, format) + { + eastl::string extTess("GL_ARB_tessellation_shader"); + eastl::string extGeometry("GL_EXT_geometry_shader4"); + eastl::string arbCompute("GL_ARB_compute_shader"); + eastl::string arbStorageBuffer("GL_ARB_shader_storage_buffer_object"); + eastl::string arbAtomicCounterBuffer("GL_ARB_shader_atomic_counters"); + eastl::string arbProgInterface("GL_ARB_program_interface_query"); + eastl::string arbShaderImageLoadStore("GL_ARB_shader_image_load_store"); + eastl::string nvPathRendering("GL_NV_path_rendering"); + eastl::string nvBlendAdvanced("GL_NV_blend_equation_advanced"); + eastl::string khrBlendAdvanced("GL_KHR_blend_equation_advanced"); + eastl::string nvBlendAdvancedCoherent("GL_NV_blend_equation_advanced_coherent"); + eastl::string khrBlendAdvancedCoherent("GL_KHR_blend_equation_advanced_coherent"); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + // get extension count + GLint numExtensions = 0; + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); + + // search for extension + if (!m_backendSupport.caps.bits.bTessellationSupported + && extTess.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTessellationSupported = true; + } else if (!m_backendSupport.caps.bits.bComputeSupported + && arbCompute.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bComputeSupported = true; + } else if (!m_backendSupport.caps.bits.bGeometrySupported + && extGeometry.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGeometrySupported = true; + } else if (!m_backendSupport.caps.bits.bStorageBufferSupported + && arbStorageBuffer.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bStorageBufferSupported = true; + } else if (!m_backendSupport.caps.bits.bAtomicCounterBufferSupported + && arbAtomicCounterBuffer.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; + } else if (!m_backendSupport.caps.bits.bProgramInterfaceSupported + && arbProgInterface.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bProgramInterfaceSupported = true; + } else if (!m_backendSupport.caps.bits.bShaderImageLoadStoreSupported + && arbShaderImageLoadStore.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; + } else if (!m_backendSupport.caps.bits.bNVPathRenderingSupported + && nvPathRendering.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVPathRenderingSupported = true; + } else if (!m_backendSupport.caps.bits.bNVAdvancedBlendSupported + && nvBlendAdvanced.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVAdvancedBlendSupported = true; + } else if (!m_backendSupport.caps.bits.bNVBlendCoherenceSupported + && nvBlendAdvancedCoherent.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVBlendCoherenceSupported = true; + } else if (!m_backendSupport.caps.bits.bKHRAdvancedBlendSupported + && khrBlendAdvanced.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported = true; + } else if (!m_backendSupport.caps.bits.bKHRBlendCoherenceSupported + && khrBlendAdvancedCoherent.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bKHRBlendCoherenceSupported = true; + } + } + + // always true for GL4.1 and GLES 3.1 devices + m_backendSupport.caps.bits.bMsTextureSupported = true; + m_backendSupport.caps.bits.bProgramPipelineSupported = true; + + if (!isESCompatible()) { + // TODO: investigate GL 4.0 support + // we expect minimum GL 4.1 context anything beyond is handeled via extensions + // Tessellation is always supported on none ES systems which support >=GL4 + m_backendSupport.caps.bits.bTessellationSupported = true; + // geometry shader is always supported on none ES systems which support >=GL4 ( actually + // 3.2 already ) + m_backendSupport.caps.bits.bGeometrySupported = true; + } else { + // always true for GLES 3.1 devices + m_backendSupport.caps.bits.bComputeSupported = true; + m_backendSupport.caps.bits.bProgramInterfaceSupported = true; + m_backendSupport.caps.bits.bStorageBufferSupported = true; + m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; + m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; + } + +#if !defined(QT_OPENGL_ES) + // Initialize extensions + m_nvPathRendering = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_NV_path_rendering)(); + m_nvPathRendering->initializeOpenGLFunctions(); + m_directStateAccess = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_EXT_direct_state_access)(); + m_directStateAccess->initializeOpenGLFunctions(); +#endif + } + + /// destructor + NVRenderBackendGL4Impl::~NVRenderBackendGL4Impl() + { +#if !defined(QT_OPENGL_ES) + if (m_nvPathRendering) + NVDelete(m_Foundation.getAllocator(), m_nvPathRendering); + if (m_directStateAccess) + NVDelete(m_Foundation.getAllocator(), m_directStateAccess); +#endif + } + + void NVRenderBackendGL4Impl::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) + { + GL_CALL_EXTRA_FUNCTION( + glDrawArraysIndirect(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + indirect)); + } + + void NVRenderBackendGL4Impl::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) + { + GL_CALL_EXTRA_FUNCTION(glDrawElementsIndirect( + m_Conversion.fromDrawModeToGL(drawMode, + m_backendSupport.caps.bits.bTessellationSupported), + m_Conversion.fromIndexBufferComponentsTypesToGL(type), indirect)); + } + + void NVRenderBackendGL4Impl::CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + // up to now compressed is not supported + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + GL_CALL_EXTRA_FUNCTION( + glTexStorage2D(glTarget, levels, glInternalFormat, (GLsizei)width, (GLsizei)height)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGL4Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + GL_CALL_EXTRA_FUNCTION(glTexStorage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, + (GLsizei)width, (GLsizei)height, + fixedsamplelocations)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + NVRenderBackend::NVRenderBackendTessControlShaderObject + NVRenderBackendGL4Impl::CreateTessControlShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { +#if !defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_CONTROL_SHADER)); +#else + GLuint shaderID = 0; +#endif + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendTessControlShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + NVRenderBackendGL4Impl::CreateTessEvaluationShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { +#if !defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_EVALUATION_SHADER)); +#else + GLuint shaderID = 0; +#endif + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendGeometryShaderObject + NVRenderBackendGL4Impl::CreateGeometryShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { +#if defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER_EXT)); +#else + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER)); +#endif + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendGeometryShaderObject)shaderID; + } + + void NVRenderBackendGL4Impl::SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, + QT3DSU32 count) + { + QT3DS_ASSERT(iao); + QT3DS_ASSERT(count); + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + inputAssembler->m_PatchVertexCount = count; + } + + void NVRenderBackendGL4Impl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) + { + GL_CALL_EXTRA_FUNCTION(glMemoryBarrier(m_Conversion.fromMemoryBarrierFlagsToGL(barriers))); + } + + void NVRenderBackendGL4Impl::BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, + QT3DSI32 level, bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + GL_CALL_EXTRA_FUNCTION(glBindImageTexture(unit, texID, level, layered, layer, + m_Conversion.fromImageAccessToGL(access), + m_Conversion.fromImageFormatToGL(format))); + } + + QT3DSI32 NVRenderBackendGL4Impl::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) + { + GLint numStorageBuffers = 0; + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) + GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_SHADER_STORAGE_BLOCK, + GL_ACTIVE_RESOURCES, &numStorageBuffers)); +#endif + return numStorageBuffers; + } + + QT3DSI32 + NVRenderBackendGL4Impl::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) + { + GLint bufferIndex = GL_INVALID_INDEX; + + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + QT3DS_ASSERT(bufferSize); + QT3DS_ASSERT(paramCount); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_SHADER_STORAGE_BLOCK, id, nameBufSize, + length, nameBuf)); + + if (*length > 0) { +#define QUERY_COUNT 3 + GLsizei actualCount; + GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, + GL_NUM_ACTIVE_VARIABLES }; + GLint params[QUERY_COUNT]; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_SHADER_STORAGE_BLOCK, id, + QUERY_COUNT, props, QUERY_COUNT, &actualCount, + params)); + + QT3DS_ASSERT(actualCount == QUERY_COUNT); + + bufferIndex = params[0]; + *bufferSize = params[1]; + *paramCount = params[2]; + } + } +#endif + return bufferIndex; + } + + void NVRenderBackendGL4Impl::ProgramSetStorageBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + GL_CALL_EXTRA_FUNCTION( + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); +#endif + } + + QT3DSI32 NVRenderBackendGL4Impl::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) + { + GLint numAtomicCounterBuffers = 0; + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) + GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_ATOMIC_COUNTER_BUFFER, + GL_ACTIVE_RESOURCES, &numAtomicCounterBuffers)); +#endif + return numAtomicCounterBuffers; + } + + QT3DSI32 + NVRenderBackendGL4Impl::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + GLint bufferIndex = GL_INVALID_INDEX; + + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + QT3DS_ASSERT(bufferSize); + QT3DS_ASSERT(paramCount); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { + { +#define QUERY_COUNT 3 + GLsizei actualCount; + GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, + GL_NUM_ACTIVE_VARIABLES }; + GLint params[QUERY_COUNT]; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_ATOMIC_COUNTER_BUFFER, id, + QUERY_COUNT, props, QUERY_COUNT, &actualCount, + params)); + + QT3DS_ASSERT(actualCount == QUERY_COUNT); + + bufferIndex = params[0]; + *bufferSize = params[1]; + *paramCount = params[2]; + + GLenum props1[1] = { GL_ATOMIC_COUNTER_BUFFER_INDEX }; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_UNIFORM, id, 1, props1, 1, + &actualCount, params)); + + QT3DS_ASSERT(actualCount == 1); + + *nameBuf = '\0'; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_UNIFORM, params[0], nameBufSize, + length, nameBuf)); + } + } +#endif + return bufferIndex; + } + + void NVRenderBackendGL4Impl::ProgramSetAtomicCounterBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + GL_CALL_EXTRA_FUNCTION( + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); +#endif + } + + void NVRenderBackendGL4Impl::SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); + + switch (glType) { + case GL_FLOAT: + GL_CALL_EXTRA_FUNCTION(glProgramUniform1fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC2: + GL_CALL_EXTRA_FUNCTION(glProgramUniform2fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC3: + GL_CALL_EXTRA_FUNCTION(glProgramUniform3fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC4: + GL_CALL_EXTRA_FUNCTION(glProgramUniform4fv(programID, id, count, (GLfloat *)value)); + break; + case GL_INT: + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, (GLint *)value)); + break; + case GL_BOOL: + { + GLint boolValue = *(GLboolean *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, &boolValue)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + GL_CALL_EXTRA_FUNCTION(glProgramUniform2iv(programID, id, count, (GLint *)value)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + GL_CALL_EXTRA_FUNCTION(glProgramUniform3iv(programID, id, count, (GLint *)value)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + GL_CALL_EXTRA_FUNCTION(glProgramUniform4iv(programID, id, count, (GLint *)value)); + break; + case GL_FLOAT_MAT3: + GL_CALL_EXTRA_FUNCTION( + glProgramUniformMatrix3fv(programID, id, count, transpose, (GLfloat *)value)); + break; + case GL_FLOAT_MAT4: + GL_CALL_EXTRA_FUNCTION( + glProgramUniformMatrix4fv(programID, id, count, transpose, (GLfloat *)value)); + break; + case GL_IMAGE_2D: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: { + if (count <= 1) { + GLint sampler = *(GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler)); + } else { + GLint *sampler = (GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, sampler)); + } + } break; + default: + qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); + QT3DS_ASSERT(false); + break; + } + } + + NVRenderBackend::NVRenderBackendComputeShaderObject + NVRenderBackendGL4Impl::CreateComputeShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = 0; +#if defined(GL_COMPUTE_SHADER) + shaderID = m_glExtraFunctions->glCreateShader(GL_COMPUTE_SHADER); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } +#endif + return (NVRenderBackend::NVRenderBackendComputeShaderObject)shaderID; + } + + void NVRenderBackendGL4Impl::DispatchCompute(NVRenderBackendShaderProgramObject, + QT3DSU32 numGroupsX, QT3DSU32 numGroupsY, + QT3DSU32 numGroupsZ) + { + GL_CALL_EXTRA_FUNCTION(glDispatchCompute(numGroupsX, numGroupsY, numGroupsZ)); + } + + NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGL4Impl::CreateProgramPipeline() + { + GLuint pipeline; + GL_CALL_EXTRA_FUNCTION(glGenProgramPipelines(1, &pipeline)); + + return NVRenderBackend::NVRenderBackendProgramPipeline(pipeline); + } + + void NVRenderBackendGL4Impl::ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + GL_CALL_EXTRA_FUNCTION(glDeleteProgramPipelines(1, &pipeline)); + } + + void NVRenderBackendGL4Impl::SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + + GL_CALL_EXTRA_FUNCTION(glBindProgramPipeline(pipeline)); + } + + void NVRenderBackendGL4Impl::SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + GLuint programID = 0; + + if (po) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + programID = static_cast(pProgram->m_ProgramID); + } + + GL_CALL_EXTRA_FUNCTION( + glUseProgramStages(pipeline, m_Conversion.fromShaderTypeFlagsToGL(flags), programID)); + } + + void NVRenderBackendGL4Impl::SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) + { + if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported || + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported) + GL_CALL_EXTRA_FUNCTION(glBlendEquation(m_Conversion.fromBlendEquationToGL( + pBlendEquArg.m_RGBEquation, m_backendSupport.caps.bits.bNVAdvancedBlendSupported, + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported))); + } + + void NVRenderBackendGL4Impl::SetBlendBarrier(void) + { + if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported) + GL_CALL_QT3DS_EXT(glBlendBarrierNV()); + } + + NVRenderBackend::NVRenderBackendPathObject + NVRenderBackendGL4Impl::CreatePathNVObject(size_t range) + { + GLuint pathID = GL_CALL_NVPATH_EXT(glGenPathsNV((GLsizei)range)); + + return NVRenderBackend::NVRenderBackendPathObject(pathID); + } + void NVRenderBackendGL4Impl::SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef inPathCommands, + NVConstDataRef inPathCoords) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, inPathObject); + GL_CALL_NVPATH_EXT(glPathCommandsNV(pathID, inPathCommands.size(), inPathCommands.begin(), + inPathCoords.size(), GL_FLOAT, inPathCoords.begin())); + } + + NVBounds3 + NVRenderBackendGL4Impl::GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_OBJECT_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + NVBounds3 NVRenderBackendGL4Impl::GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_FILL_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + NVBounds3 NVRenderBackendGL4Impl::GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_STROKE_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + void NVRenderBackendGL4Impl::SetStrokeWidth(NVRenderBackendPathObject inPathObject, + QT3DSF32 inStrokeWidth) + { +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glPathParameterfNV(HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_STROKE_WIDTH_NV, inStrokeWidth)); +#endif + } + + void NVRenderBackendGL4Impl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) + { +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(inPathProjection); +#else + GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_PROJECTION, inPathProjection.front())); +#endif + } + + void NVRenderBackendGL4Impl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) + { +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(inPathModelview); +#else + GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_MODELVIEW, inPathModelview.front())); +#endif + } + + void NVRenderBackendGL4Impl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) + { + GL_CALL_NVPATH_EXT(glPathStencilDepthOffsetNV(inSlope, inBias)); + } + + void NVRenderBackendGL4Impl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) + { + GL_CALL_NVPATH_EXT(glPathCoverDepthFuncNV(m_Conversion.fromBoolOpToGL(inDepthFunction))); + } + + void NVRenderBackendGL4Impl::StencilStrokePath(NVRenderBackendPathObject inPathObject) + { + GL_CALL_NVPATH_EXT(glStencilStrokePathNV(HandleToID_cast(GLuint, size_t, inPathObject), 0x1, (GLuint)~0)); + } + + void NVRenderBackendGL4Impl::StencilFillPath(NVRenderBackendPathObject inPathObject) + { +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glStencilFillPathNV(HandleToID_cast(GLuint, size_t, inPathObject), + GL_COUNT_UP_NV, (GLuint)~0)); +#endif + } + + void NVRenderBackendGL4Impl::ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glDeletePathsNV(pathID, (GLsizei)range)); + } + + void NVRenderBackendGL4Impl::StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glStencilFillPathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathFillModeToGL(fillMode), stencilMask, + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::StencilStrokePathInstancedN( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glStencilStrokePathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, stencilRef, + stencilMask, m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::CoverFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glCoverFillPathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathCoverModeToGL(coverMode), + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::CoverStrokePathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glCoverStrokePathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathCoverModeToGL(coverMode), + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::LoadPathGlyphs( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + + GL_CALL_NVPATH_EXT(glPathGlyphsNV(pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), (GLsizei)numGlyphs, + m_Conversion.fromPathTypeToGL(type), charCodes, + m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), + pathTemplateID, emScale)); + } + + NVRenderPathReturnValues::Enum NVRenderBackendGL4Impl::LoadPathGlyphsIndexed( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + GLenum glRet = 0; + + glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexArrayNV( + pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyphIndex, + (GLsizei)numGlyphs, pathTemplateID, emScale)); + + return m_Conversion.fromGLToPathFontReturn(glRet); + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGL4Impl::LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale, QT3DSU32 *count) + { + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + GLenum glRet = 0; + GLuint baseAndCount[2] = { 0, 0 }; + + glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexRangeNV(m_Conversion.fromPathFontTargetToGL(fontTarget), + fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), + pathTemplateID, emScale, baseAndCount)); + + if (count) + *count = baseAndCount[1]; + + return NVRenderBackend::NVRenderBackendPathObject(baseAndCount[0]); + } + + void NVRenderBackendGL4Impl::LoadPathGlyphRange( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + + GL_CALL_NVPATH_EXT(glPathGlyphRangeNV( + pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyph, (GLsizei)numGlyphs, + m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), pathTemplateID, emScale)); + } + + void NVRenderBackendGL4Impl::GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, + const void *charCodes, size_t stride, + QT3DSF32 *metrics) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathMetricsNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), + charCodes, pathID, (GLsizei)stride, metrics)); + } + + void + NVRenderBackendGL4Impl::GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathMetricRangeNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), + pathID, (GLsizei)numPaths, (GLsizei)stride, metrics)); + } + + void NVRenderBackendGL4Impl::GetPathSpacing( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, QT3DSF32 advanceScale, + QT3DSF32 kerningScale, NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathSpacingNV(m_Conversion.fromPathListModeToGL(pathListMode), + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), + charCodes, pathID, advanceScale, kerningScale, + m_Conversion.fromPathTransformToGL(transformType), spacing)); + } +} +} diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h new file mode 100644 index 00000000..bfdc03b7 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL4_H +#define QT3DS_RENDER_BACKEND_GL4_H + +/// @file Qt3DSRenderBackendGL4.h +/// NVRender OpenGL 4 backend definition. + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + class NVRenderBackendGL4Impl : public NVRenderBackendGL3Impl + { + public: + /// constructor + NVRenderBackendGL4Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGL4Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; + void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, const void *indirect) override; + + void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, const void *value, + bool transpose) override; + + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) override; + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) override; + + virtual NVRenderBackendComputeShaderObject + CreateComputeShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + + NVRenderBackendProgramPipeline CreateProgramPipeline() override; + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) override; + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) override; + void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) override; + + void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; + void SetBlendBarrier(void) override; + + NVRenderBackendPathObject CreatePathNVObject(size_t range) override; + void SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef inPathCommands, + NVConstDataRef inPathCoords) override; + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) override; + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) override; + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) override; + void SetStrokeWidth(NVRenderBackendPathObject inPathObject, QT3DSF32 inStrokeWidth) override; + + void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; + void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; + void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) override; + void StencilStrokePath(NVRenderBackendPathObject inPathObject) override; + void StencilFillPath(NVRenderBackendPathObject inPathObject) override; + void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; + + void StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) override; + void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, + QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void LoadPathGlyphs(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, + NVRenderPathFormatType::Enum type, const void *charCodes, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, + QT3DSU32 *count) override; + void LoadPathGlyphRange(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) override; + void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, const void *charCodes, + size_t stride, QT3DSF32 *metrics) override; + void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) override; + void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, + QT3DSF32 advanceScale, QT3DSF32 kerningScale, + NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) override; + private: +#if !defined(QT_OPENGL_ES) + QOpenGLExtension_NV_path_rendering *m_nvPathRendering; + QOpenGLExtension_EXT_direct_state_access *m_directStateAccess; +#endif + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp new file mode 100644 index 00000000..940ab094 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp @@ -0,0 +1,2220 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "foundation/StringTable.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_FUNCTION(x) m_glFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +namespace qt3ds { +namespace render { + +#ifndef GL_PROGRAM_SEPARABLE +#define GL_PROGRAM_SEPARABLE 0x8258 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + +#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + + /// constructor + NVRenderBackendGLBase::NVRenderBackendGLBase(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : mRefCount(0) + , m_Foundation(fnd) + , m_StringTable(stringTable) + , m_Conversion() + , m_MaxAttribCount(0) + , m_DrawBuffersArray(m_Foundation.getAllocator(), + "NVRenderBackendGLBase::m_DrawBuffersArray") + , m_format(format) + { + m_glFunctions = new QOpenGLFunctions; + m_glFunctions->initializeOpenGLFunctions(); + m_glExtraFunctions = new QOpenGLExtraFunctions; + m_glExtraFunctions->initializeOpenGLFunctions(); + + // internal state tracker + m_pCurrentRasterizerState = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendRasterizerStateGL)(); + m_pCurrentDepthStencilState = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)(); + } + /// destructor + NVRenderBackendGLBase::~NVRenderBackendGLBase() + { + if (m_pCurrentRasterizerState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentRasterizerState); + if (m_pCurrentDepthStencilState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentDepthStencilState); + if (m_glFunctions) + delete m_glFunctions; + if (m_glExtraFunctions) + delete m_glExtraFunctions; + } + + NVRenderContextType NVRenderBackendGLBase::GetRenderContextType() const + { + if (m_format.renderableType() == QSurfaceFormat::OpenGLES) { + if (m_format.majorVersion() == 2) + return NVRenderContextValues::GLES2; + + if (m_format.majorVersion() == 3) { + if (m_format.minorVersion() >= 1) + return NVRenderContextValues::GLES3PLUS; + else + return NVRenderContextValues::GLES3; + } + } else if (m_format.majorVersion() == 2) { + return NVRenderContextValues::GL2; + } else if (m_format.majorVersion() == 3) { + return NVRenderContextValues::GL3; + } else if (m_format.majorVersion() == 4) { + return NVRenderContextValues::GL4; + } + + return NVRenderContextValues::NullContext; + } + + bool NVRenderBackendGLBase::isESCompatible() const + { + return m_format.renderableType() == QSurfaceFormat::OpenGLES; + } + + const char *NVRenderBackendGLBase::GetShadingLanguageVersion() + { + const char *retval = (const char *)GL_CALL_FUNCTION( + glGetString(GL_SHADING_LANGUAGE_VERSION)); + if (retval == NULL) + return ""; + + return retval; + } + + QT3DSU32 + NVRenderBackendGLBase::GetMaxCombinedTextureUnits() + { + QT3DSI32 maxUnits; + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxUnits)); + return maxUnits; + } + + bool NVRenderBackendGLBase::GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::Enum inCap) const + { + bool bSupported = false; + + switch (inCap) { + case NVRenderBackendCaps::FpRenderTarget: + bSupported = m_backendSupport.caps.bits.bFPRenderTargetsSupported; + break; + case NVRenderBackendCaps::DepthStencilTexture: + bSupported = m_backendSupport.caps.bits.bDepthStencilSupported; + break; + case NVRenderBackendCaps::ConstantBuffer: + bSupported = m_backendSupport.caps.bits.bConstantBufferSupported; + break; + case NVRenderBackendCaps::DxtImages: + bSupported = m_backendSupport.caps.bits.bDXTImagesSupported; + break; + case NVRenderBackendCaps::MsTexture: + bSupported = m_backendSupport.caps.bits.bMsTextureSupported; + break; + case NVRenderBackendCaps::TexSwizzle: + bSupported = m_backendSupport.caps.bits.bTextureSwizzleSupported; + break; + case NVRenderBackendCaps::FastBlits: + bSupported = m_backendSupport.caps.bits.bFastBlitsSupported; + break; + case NVRenderBackendCaps::Tessellation: + bSupported = m_backendSupport.caps.bits.bTessellationSupported; + break; + case NVRenderBackendCaps::Compute: + bSupported = m_backendSupport.caps.bits.bComputeSupported; + break; + case NVRenderBackendCaps::Geometry: + bSupported = m_backendSupport.caps.bits.bGeometrySupported; + break; + case NVRenderBackendCaps::SampleQuery: { + // On the following context sample query is not supported + NVRenderContextType noSamplesQuerySupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noSamplesQuerySupportedContextFlags); + } break; + case NVRenderBackendCaps::TimerQuery: + bSupported = m_backendSupport.caps.bits.bTimerQuerySupported; + break; + case NVRenderBackendCaps::CommandSync: { + // On the following context sync objects are not supported + NVRenderContextType noSyncObjectSupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noSyncObjectSupportedContextFlags); + } break; + case NVRenderBackendCaps::TextureArray: { + // On the following context texture arrays are not supported + NVRenderContextType noTextureArraySupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noTextureArraySupportedContextFlags); + } break; + case NVRenderBackendCaps::StorageBuffer: + bSupported = m_backendSupport.caps.bits.bStorageBufferSupported; + break; + case NVRenderBackendCaps::AtomicCounterBuffer: + bSupported = m_backendSupport.caps.bits.bAtomicCounterBufferSupported; + break; + case NVRenderBackendCaps::ShaderImageLoadStore: + bSupported = m_backendSupport.caps.bits.bShaderImageLoadStoreSupported; + break; + case NVRenderBackendCaps::ProgramPipeline: + bSupported = m_backendSupport.caps.bits.bProgramPipelineSupported; + break; + case NVRenderBackendCaps::PathRendering: + bSupported = m_backendSupport.caps.bits.bNVPathRenderingSupported; + break; + case NVRenderBackendCaps::AdvancedBlend: + bSupported = m_backendSupport.caps.bits.bNVAdvancedBlendSupported | + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; + break; + case NVRenderBackendCaps::AdvancedBlendKHR: + bSupported = m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; + break; + case NVRenderBackendCaps::BlendCoherency: + bSupported = m_backendSupport.caps.bits.bNVBlendCoherenceSupported | + m_backendSupport.caps.bits.bKHRBlendCoherenceSupported; + break; + case NVRenderBackendCaps::gpuShader5: + bSupported = m_backendSupport.caps.bits.bGPUShader5ExtensionSupported; + break; + case NVRenderBackendCaps::VertexArrayObject: + bSupported = m_backendSupport.caps.bits.bVertexArrayObjectSupported; + break; + case NVRenderBackendCaps::StandardDerivatives: + bSupported = m_backendSupport.caps.bits.bStandardDerivativesSupported; + break; + case NVRenderBackendCaps::TextureLod: + bSupported = m_backendSupport.caps.bits.bTextureLodSupported; + break; + default: + QT3DS_ASSERT(false); + bSupported = false; + break; + } + + return bSupported; + } + + void NVRenderBackendGLBase::GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, + QT3DSI32 *params) const + { + if (params) { + switch (inQuery) { + case NVRenderBackendQuery::MaxTextureSize: + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_TEXTURE_SIZE, params)); + break; + case NVRenderBackendQuery::MaxTextureArrayLayers: { + NVRenderContextType noTextureArraySupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noTextureArraySupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, params)); + } else { + *params = 0; + } + } break; + case NVRenderBackendQuery::MaxConstantBufferSlots: { + NVRenderContextType noConstantBufferSupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noConstantBufferSupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, params)); + } else { + *params = 0; + } + } break; + case NVRenderBackendQuery::MaxConstantBufferBlockSize: { + NVRenderContextType noConstantBufferSupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noConstantBufferSupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, params)); + } else { + *params = 0; + } + } break; + default: + QT3DS_ASSERT(false); + *params = 0; + break; + } + } + } + + QT3DSU32 + NVRenderBackendGLBase::GetDepthBits() const + { + QT3DSI32 depthBits; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_BITS, &depthBits)); + return depthBits; + } + + QT3DSU32 + NVRenderBackendGLBase::GetStencilBits() const + { + QT3DSI32 stencilBits; + GL_CALL_FUNCTION(glGetIntegerv(GL_STENCIL_BITS, &stencilBits)); + return stencilBits; + } + + void NVRenderBackendGLBase::SetMultisample(bool bEnable) + { + QT3DS_ASSERT(m_backendSupport.caps.bits.bMsTextureSupported || !bEnable); + // For GL ES explicit multisample enabling is not needed + // and does not exist + NVRenderContextType noMsaaEnableContextFlags(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noMsaaEnableContextFlags)) { + SetRenderState(bEnable, NVRenderState::Multisample); + } + } + + void NVRenderBackendGLBase::SetRenderState(bool bEnable, const NVRenderState::Enum value) + { + if (value == NVRenderState::DepthWrite) { + GL_CALL_FUNCTION(glDepthMask(bEnable)); + } else { + if (bEnable) { + GL_CALL_FUNCTION(glEnable(m_Conversion.fromRenderStateToGL(value))); + } else { + GL_CALL_FUNCTION(glDisable(m_Conversion.fromRenderStateToGL(value))); + } + } + } + + NVRenderBackend::NVRenderBackendDepthStencilStateObject + NVRenderBackendGLBase::CreateDepthStencilState( + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + NVRenderBackendDepthStencilStateGL *retval = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)( + enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, + depthStencilOpFront, depthStencilOpBack); + + return (NVRenderBackend::NVRenderBackendDepthStencilStateObject)retval; + } + + void NVRenderBackendGLBase::ReleaseDepthStencilState( + NVRenderBackendDepthStencilStateObject inDepthStencilState) + { + NVRenderBackendDepthStencilStateGL *inputState = + (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; + if (inputState) + NVDelete(m_Foundation.getAllocator(), inputState); + } + + NVRenderBackend::NVRenderBackendRasterizerStateObject + NVRenderBackendGLBase::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + NVRenderBackendRasterizerStateGL *retval = + QT3DS_NEW(m_Foundation.getAllocator(), + NVRenderBackendRasterizerStateGL)(depthBias, depthScale, cullFace); + + return (NVRenderBackend::NVRenderBackendRasterizerStateObject)retval; + } + + void NVRenderBackendGLBase::ReleaseRasterizerState( + NVRenderBackendRasterizerStateObject rasterizerState) + { + NVRenderBackendRasterizerStateGL *inputState = + (NVRenderBackendRasterizerStateGL *)rasterizerState; + if (inputState) + NVDelete(m_Foundation.getAllocator(), inputState); + } + + void NVRenderBackendGLBase::SetDepthStencilState( + NVRenderBackendDepthStencilStateObject inDepthStencilState) + { + NVRenderBackendDepthStencilStateGL *inputState = + (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; + if (inputState && !(*m_pCurrentDepthStencilState == *inputState)) { + // we check on a per single state base + if (inputState->m_DepthEnable != m_pCurrentDepthStencilState->m_DepthEnable) { + SetRenderState(inputState->m_DepthEnable, NVRenderState::DepthTest); + m_pCurrentDepthStencilState->m_DepthEnable = inputState->m_DepthEnable; + } + if (inputState->m_StencilEnable != m_pCurrentDepthStencilState->m_StencilEnable) { + SetRenderState(inputState->m_StencilEnable, NVRenderState::StencilTest); + m_pCurrentDepthStencilState->m_StencilEnable = inputState->m_StencilEnable; + } + + if (inputState->m_DepthMask != m_pCurrentDepthStencilState->m_DepthMask) { + GL_CALL_FUNCTION(glDepthMask(inputState->m_DepthMask)); + m_pCurrentDepthStencilState->m_DepthMask = inputState->m_DepthMask; + } + + if (inputState->m_DepthFunc != m_pCurrentDepthStencilState->m_DepthFunc) { + GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(inputState->m_DepthFunc))); + m_pCurrentDepthStencilState->m_DepthFunc = inputState->m_DepthFunc; + } + + if (!(inputState->m_DepthStencilOpFront + == m_pCurrentDepthStencilState->m_DepthStencilOpFront)) { + GL_CALL_FUNCTION(glStencilOpSeparate( + GL_FRONT, + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_StencilFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthPass))); + m_pCurrentDepthStencilState->m_DepthStencilOpFront = + inputState->m_DepthStencilOpFront; + } + + if (!(inputState->m_DepthStencilOpBack + == m_pCurrentDepthStencilState->m_DepthStencilOpBack)) { + GL_CALL_FUNCTION(glStencilOpSeparate( + GL_BACK, + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_StencilFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthPass))); + m_pCurrentDepthStencilState->m_DepthStencilOpBack = + inputState->m_DepthStencilOpBack; + } + + if (!(inputState->m_StencilFuncFront + == m_pCurrentDepthStencilState->m_StencilFuncFront)) { + GL_CALL_FUNCTION(glStencilFuncSeparate( + GL_FRONT, + m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncFront.m_Function), + inputState->m_StencilFuncFront.m_ReferenceValue, + inputState->m_StencilFuncFront.m_Mask)); + m_pCurrentDepthStencilState->m_StencilFuncFront = inputState->m_StencilFuncFront; + } + + if (!(inputState->m_StencilFuncBack + == m_pCurrentDepthStencilState->m_StencilFuncBack)) { + GL_CALL_FUNCTION(glStencilFuncSeparate( + GL_BACK, m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncBack.m_Function), + inputState->m_StencilFuncBack.m_ReferenceValue, + inputState->m_StencilFuncBack.m_Mask)); + m_pCurrentDepthStencilState->m_StencilFuncBack = inputState->m_StencilFuncBack; + } + } + } + + void + NVRenderBackendGLBase::SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) + { + NVRenderBackendRasterizerStateGL *inputState = + (NVRenderBackendRasterizerStateGL *)rasterizerState; + if (inputState && !(*m_pCurrentRasterizerState == *inputState)) { + // store current state + *m_pCurrentRasterizerState = *inputState; + + if (m_pCurrentRasterizerState->m_DepthBias != 0.0 + || m_pCurrentRasterizerState->m_DepthScale != 0.0) { + GL_CALL_FUNCTION(glEnable(GL_POLYGON_OFFSET_FILL)); + } else { + GL_CALL_FUNCTION(glDisable(GL_POLYGON_OFFSET_FILL)); + } + + GL_CALL_FUNCTION(glPolygonOffset(m_pCurrentRasterizerState->m_DepthBias, + m_pCurrentRasterizerState->m_DepthScale)); + + GL_CALL_FUNCTION( + glCullFace(m_Conversion.fromFacesToGL(m_pCurrentRasterizerState->m_CullFace))); + } + } + + bool NVRenderBackendGLBase::GetRenderState(const NVRenderState::Enum value) + { + bool enabled = GL_CALL_FUNCTION(glIsEnabled(m_Conversion.fromRenderStateToGL(value))); + return enabled; + } + + NVRenderBoolOp::Enum NVRenderBackendGLBase::GetDepthFunc() + { + QT3DSI32 value; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_FUNC, &value)); + return m_Conversion.fromGLToBoolOp(value); + } + + void NVRenderBackendGLBase::SetDepthFunc(const NVRenderBoolOp::Enum func) + { + GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(func))); + } + + bool NVRenderBackendGLBase::GetDepthWrite() + { + QT3DSI32 value; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_WRITEMASK, (GLint *)&value)); + return value ? true : false; + } + + void NVRenderBackendGLBase::SetDepthWrite(bool bEnable) { GL_CALL_FUNCTION(glDepthMask(bEnable)); } + + void NVRenderBackendGLBase::SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) + { + GL_CALL_FUNCTION(glColorMask(bRed, bGreen, bBlue, bAlpha)); + } + + void NVRenderBackendGLBase::GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) + { + QT3DS_ASSERT(pBlendFuncArg); + QT3DSI32_4 values; + + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&values.x)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&values.y)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&values.z)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&values.w)); + + pBlendFuncArg->m_SrcRGB = m_Conversion.fromGLToSrcBlendFunc(values.x); + pBlendFuncArg->m_SrcAlpha = m_Conversion.fromGLToSrcBlendFunc(values.y); + pBlendFuncArg->m_DstRGB = m_Conversion.fromGLToDstBlendFunc(values.z); + pBlendFuncArg->m_DstAlpha = m_Conversion.fromGLToDstBlendFunc(values.w); + } + + void NVRenderBackendGLBase::SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) + { + QT3DSI32_4 values; + + values.x = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcRGB); + values.y = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstRGB); + values.z = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcAlpha); + values.w = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstAlpha); + + GL_CALL_FUNCTION(glBlendFuncSeparate(values.x, values.y, values.z, values.w)); + } + + void NVRenderBackendGLBase::SetBlendEquation(const NVRenderBlendEquationArgument &) + { + // needs GL4 / GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetBlendBarrier() + { + // needs GL4 / GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetScissorRect(NVRenderRect *pRect) + { + QT3DS_ASSERT(pRect); + GL_CALL_FUNCTION(glGetIntegerv(GL_SCISSOR_BOX, (GLint *)pRect)); + } + + void NVRenderBackendGLBase::SetScissorRect(const NVRenderRect &rect) + { + GL_CALL_FUNCTION(glScissor(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height)); + } + + void NVRenderBackendGLBase::GetViewportRect(NVRenderRect *pRect) + { + QT3DS_ASSERT(pRect); + GL_CALL_FUNCTION(glGetIntegerv(GL_VIEWPORT, (GLint *)pRect)); + } + + void NVRenderBackendGLBase::SetViewportRect(const NVRenderRect &rect) + { + GL_CALL_FUNCTION(glViewport(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height);); + } + + void NVRenderBackendGLBase::SetClearColor(const QT3DSVec4 *pClearColor) + { + QT3DS_ASSERT(pClearColor); + + GL_CALL_FUNCTION(glClearColor(pClearColor->x, pClearColor->y, + pClearColor->z, pClearColor->w)); + } + + void NVRenderBackendGLBase::Clear(NVRenderClearFlags flags) + { + GL_CALL_FUNCTION(glClear(m_Conversion.fromClearFlagsToGL(flags))); + } + + NVRenderBackend::NVRenderBackendBufferObject + NVRenderBackendGLBase::CreateBuffer(size_t size, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, const void *hostPtr) + { + GLuint bufID = 0; + + GL_CALL_FUNCTION(glGenBuffers(1, &bufID)); + + if (bufID && size) { + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + if (target != GL_INVALID_ENUM) { + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferData(target, size, hostPtr, + m_Conversion.fromBufferUsageTypeToGL(usage))); + } else { + GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); + bufID = 0; + qCCritical(GL_ERROR, GLConversion::processGLError(target)); + } + } + + return (NVRenderBackend::NVRenderBackendBufferObject)bufID; + } + + void NVRenderBackendGLBase::BindBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_FUNCTION(glBindBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags), bufID)); + } + + void NVRenderBackendGLBase::ReleaseBuffer(NVRenderBackendBufferObject bo) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); + } + + void NVRenderBackendGLBase::UpdateBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t size, + NVRenderBufferUsageType::Enum usage, const void *data) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferData(target, size, data, m_Conversion.fromBufferUsageTypeToGL(usage))); + } + + void NVRenderBackendGLBase::UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferSubData(target, offset, size, data)); + } + + void *NVRenderBackendGLBase::MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, + size_t, size_t, NVRenderBufferAccessFlags) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NULL; + } + + bool NVRenderBackendGLBase::UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return true; + } + + void NVRenderBackendGLBase::SetMemoryBarrier(NVRenderBufferBarrierFlags) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLBase::CreateQuery() + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackendQueryObject(0); + } + + void NVRenderBackendGLBase::ReleaseQuery(NVRenderBackendQueryObject) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, QT3DSU32 *) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, QT3DSU64 *) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetQueryTimer(NVRenderBackendQueryObject) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderBackend::NVRenderBackendSyncObject + NVRenderBackendGLBase::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackendSyncObject(0); + } + + void NVRenderBackendGLBase::ReleaseSync(NVRenderBackendSyncObject) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, + QT3DSU64) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLBase::CreateRenderTarget() + { + GLuint fboID = 0; + + GL_CALL_FUNCTION(glGenFramebuffers(1, &fboID)); + + return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; + } + + void NVRenderBackendGLBase::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + if (fboID) { + GL_CALL_FUNCTION(glDeleteFramebuffers(1, &fboID)); + } + } + + void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) + { + // rto must be the current render target + GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, rbID)); + } + + void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target) + { + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D + || m_backendSupport.caps.bits.bMsTextureSupported); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, 0)) + } + + void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) + { + // Needs GL3 or GLES 3 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetRenderTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); + } + + bool NVRenderBackendGLBase::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) + { + // rto must be the current render target + GLenum completeStatus = GL_CALL_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); + switch (completeStatus) { +#define HANDLE_INCOMPLETE_STATUS(x) \ + case x: \ + qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ + return false; + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) +#undef HANDLE_INCOMPLETE_STATUS + } + return true; + } + + NVRenderBackend::NVRenderBackendRenderbufferObject + NVRenderBackendGLBase::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) + { + GLuint bufID = 0; + + GL_CALL_FUNCTION(glGenRenderbuffers(1, &bufID)); + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + bufID = 0; + } + + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; + } + + void NVRenderBackendGLBase::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + if (bufID) { + GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + } + } + + bool NVRenderBackendGLBase::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) + { + bool success = true; + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + QT3DS_ASSERT(bufID); + + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + success = false; + } + + return success; + } + + NVRenderBackend::NVRenderBackendTextureObject NVRenderBackendGLBase::CreateTexture() + { + GLuint texID = 0; + + GL_CALL_FUNCTION(glGenTextures(1, &texID)); + return (NVRenderBackend::NVRenderBackendTextureObject)texID; + } + + void NVRenderBackendGLBase::BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0 + unit)); + GL_CALL_FUNCTION(glBindTexture(m_Conversion.fromTextureTargetToGL(target), texID)); + } + + void NVRenderBackendGLBase::BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, + QT3DSI32, NVRenderImageAccessType::Enum, + NVRenderTextureFormats::Enum) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::ReleaseTexture(NVRenderBackendTextureObject to) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GL_CALL_FUNCTION(glDeleteTextures(1, &texID)); + } + + void NVRenderBackendGLBase::SetTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + border, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + // This will look very SetTextureData2D, but the target for glBindTexture will be different from + // the target for + // glTexImage2D. + void NVRenderBackendGLBase::SetTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GLenum glTexTarget = + m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + // for es2 internal format must be same as format + if (GetRenderContextType() == NVRenderContextValues::GLES2) + glInternalFormat = glformat; + + GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + border, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); + } + + void NVRenderBackendGLBase::CreateTextureStorage2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t) + { + // you need GL 4.2 or GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, + size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + format = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), format, + swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = 0; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + GL_CALL_FUNCTION(glTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, + (GLsizei)height, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGLBase::SetCompressedTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, + (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGLBase::SetCompressedTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GLenum glTexTarget = + m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, + (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); + } + + void NVRenderBackendGLBase::SetCompressedTextureSubData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(format); + GL_CALL_FUNCTION(glCompressedTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, + (GLsizei)height, glformat, (GLsizei)imageSize, + hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGLBase::SetTextureData3D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, + size_t, QT3DSI32, NVRenderTextureFormats::Enum, + const void *) + { + // needs GL3 or GLES3 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glValue = GLConversion::fromHintToGL(genType); + GL_CALL_FUNCTION(glHint(GL_GENERATE_MIPMAP_HINT, glValue)); + GL_CALL_FUNCTION(glGenerateMipmap(glTarget)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + NVRenderTextureSwizzleMode::Enum + NVRenderBackendGLBase::GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const + { + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), inFormat, swizzleMode); + + return swizzleMode; + } + + NVRenderBackend::NVRenderBackendSamplerObject NVRenderBackendGLBase::CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSI32 minLod, QT3DSI32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + // Satisfy the compiler + // We don"t setup the state here for GL + // but we need to pass on the variables here + // to satisfy the interface + NVRENDER_BACKEND_UNUSED(minFilter); + NVRENDER_BACKEND_UNUSED(magFilter); + NVRENDER_BACKEND_UNUSED(wrapS); + NVRENDER_BACKEND_UNUSED(wrapT); + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + NVRENDER_BACKEND_UNUSED(anisotropy); + NVRENDER_BACKEND_UNUSED(borderColor); + + // return a dummy handle + return (NVRenderBackend::NVRenderBackendSamplerObject)0x0001; + } + + void NVRenderBackendGLBase::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + // Satisfy the compiler + // These are not available in GLES 2 and we don't use them right now + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + NVRENDER_BACKEND_UNUSED(borderColor); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy)); + } + } + + void NVRenderBackendGLBase::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) + { + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(baseLevel); + NVRENDER_BACKEND_UNUSED(maxLevel); + } + + void NVRenderBackendGLBase::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) + { + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + + // Nothing to do here still might be called + QT3DS_ASSERT(swizzleMode == NVRenderTextureSwizzleMode::NoSwizzle); + + NVRENDER_BACKEND_UNUSED(swizzleMode); + } + + void NVRenderBackendGLBase::ReleaseSampler(NVRenderBackendSamplerObject so) + { + GLuint samplerID = HandleToID_cast(GLuint, size_t, so); + if (!samplerID) + return; + // otherwise nothing to do + } + + NVRenderBackend::NVRenderBackendAttribLayoutObject + NVRenderBackendGLBase::CreateAttribLayout(NVConstDataRef attribs) + { + QT3DSU32 attribLayoutSize = sizeof(NVRenderBackendAttributeLayoutGL); + QT3DSU32 entrySize = sizeof(NVRenderBackendLayoutEntryGL) * attribs.size(); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), attribLayoutSize + entrySize, + "BackendAttributeLayoutGL"); + NVDataRef entryRef = + PtrAtOffset(newMem, attribLayoutSize, entrySize); + QT3DSU32 maxInputSlot = 0; + + // copy data + QT3DS_FOREACH(idx, attribs.size()) + { + entryRef[idx].m_AttribName = m_StringTable->RegisterStr(attribs.mData[idx].m_Name); + entryRef[idx].m_Normalize = 0; + entryRef[idx].m_AttribIndex = 0; // will be set later + entryRef[idx].m_Type = m_Conversion.fromComponentTypeAndNumCompsToAttribGL( + attribs.mData[idx].m_ComponentType, attribs.mData[idx].m_NumComponents); + entryRef[idx].m_NumComponents = attribs.mData[idx].m_NumComponents; + entryRef[idx].m_InputSlot = attribs.mData[idx].m_InputSlot; + entryRef[idx].m_Offset = attribs.mData[idx].m_FirstItemOffset; + + if (maxInputSlot < entryRef[idx].m_InputSlot) + maxInputSlot = entryRef[idx].m_InputSlot; + } + + NVRenderBackendAttributeLayoutGL *retval = + new (newMem) NVRenderBackendAttributeLayoutGL(entryRef, maxInputSlot); + + return (NVRenderBackend::NVRenderBackendAttribLayoutObject)retval; + } + + void NVRenderBackendGLBase::ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) + { + NVRenderBackendAttributeLayoutGL *attribLayout = (NVRenderBackendAttributeLayoutGL *)ao; + + NVDelete(m_Foundation.getAllocator(), attribLayout); + }; + + NVRenderBackend::NVRenderBackendInputAssemblerObject + NVRenderBackendGLBase::CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, + NVConstDataRef offsets, + QT3DSU32 patchVertexCount) + { + NVRenderBackendAttributeLayoutGL *attribLayoutGL = + (NVRenderBackendAttributeLayoutGL *)attribLayout; + + NVRenderBackendInputAssemblerGL *retval = QT3DS_NEW(m_Foundation.getAllocator(), + NVRenderBackendInputAssemblerGL)( + m_Foundation, attribLayoutGL, buffers, indexBuffer, strides, offsets, patchVertexCount); + + return (NVRenderBackend::NVRenderBackendInputAssemblerObject)retval; + } + + void NVRenderBackendGLBase::ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) + { + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVDelete(m_Foundation.getAllocator(), inputAssembler); + } + + bool NVRenderBackendGLBase::compileSource(GLuint shaderID, NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + GLint shaderSourceSize = static_cast(source.size()); + const char *shaderSourceData = (const char *)source.begin(); + GLint shaderStatus = GL_TRUE; + + if (!binary) { + + GL_CALL_FUNCTION(glShaderSource(shaderID, 1, &shaderSourceData, &shaderSourceSize)); + GL_CALL_FUNCTION(glCompileShader(shaderID)); + + GLint logLen; + GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_COMPILE_STATUS, &shaderStatus)); + GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLen)); + + // Check if some log exists. We also write warnings here + // Should at least contain more than the null termination + if (logLen > 2) { + errorMessage.resize(logLen + 1); + + GLint lenWithoutNull; + GL_CALL_FUNCTION(glGetShaderInfoLog(shaderID, logLen, &lenWithoutNull, + (char *)errorMessage.c_str())); + } + } else { + GL_CALL_FUNCTION(glShaderBinary(1, &shaderID, GL_NVIDIA_PLATFORM_BINARY_NV, shaderSourceData, + shaderSourceSize)); + GLenum binaryError = m_glFunctions->glGetError(); + if (binaryError != GL_NO_ERROR) { + shaderStatus = GL_FALSE; + qCCritical(GL_ERROR, GLConversion::processGLError(binaryError)); + } + } + + return (shaderStatus == GL_TRUE); + } + + NVRenderBackend::NVRenderBackendVertexShaderObject + NVRenderBackendGLBase::CreateVertexShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_VERTEX_SHADER)); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendVertexShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendFragmentShaderObject + NVRenderBackendGLBase::CreateFragmentShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_FRAGMENT_SHADER)); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendFragmentShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendTessControlShaderObject + NVRenderBackendGLBase::CreateTessControlShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4 or GLES EXT_tessellation_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendTessControlShaderObject)0; + } + + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + NVRenderBackendGLBase::CreateTessEvaluationShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4 or GLES EXT_tessellation_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)0; + } + + NVRenderBackend::NVRenderBackendGeometryShaderObject + NVRenderBackendGLBase::CreateGeometryShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4 or GLES EXT_geometry_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendGeometryShaderObject)0; + } + + NVRenderBackend::NVRenderBackendComputeShaderObject + NVRenderBackendGLBase::CreateComputeShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4.3 or GLES3.1 support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendComputeShaderObject)0; + } + + void NVRenderBackendGLBase::ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void + NVRenderBackendGLBase::ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseTessEvaluationShader( + NVRenderBackendTessEvaluationShaderObject teso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); + } + + NVRenderBackend::NVRenderBackendShaderProgramObject + NVRenderBackendGLBase::CreateShaderProgram(bool isSeparable) + { + NVRenderBackendShaderProgramGL *theProgram = NULL; + GLuint programID = GL_CALL_FUNCTION(glCreateProgram()); + + if (programID) { + theProgram = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendShaderProgramGL)(programID); + + if (!theProgram) { + GL_CALL_FUNCTION(glDeleteProgram(programID)); + } else if (isSeparable && m_backendSupport.caps.bits.bProgramPipelineSupported) { + GL_CALL_EXTRA_FUNCTION(glProgramParameteri(programID, GL_PROGRAM_SEPARABLE, GL_TRUE)); + } + } + + return (NVRenderBackend::NVRenderBackendShaderProgramObject)theProgram; + } + + void NVRenderBackendGLBase::ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_FUNCTION(glDeleteProgram(programID)); + + if (pProgram->m_shaderInput) { + NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); + pProgram->m_shaderInput = NULL; + } + + NVDelete(m_Foundation.getAllocator(), pProgram); + } + + bool NVRenderBackendGLBase::LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_FUNCTION(glLinkProgram(programID)); + + GLint linkStatus, logLen; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_LINK_STATUS, &linkStatus)); + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLen)); + + // if succesfuly linked get the attribute information + if (linkStatus) { + // release old stuff + if (pProgram->m_shaderInput) { + NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); + pProgram->m_shaderInput = NULL; + } + + GLint numAttribs; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTES, &numAttribs)); + + if (numAttribs) { + NVRenderBackendShaderInputEntryGL *tempShaderInputEntry = + (NVRenderBackendShaderInputEntryGL *)QT3DS_ALLOC( + m_Foundation.getAllocator(), + sizeof(NVRenderBackendShaderInputEntryGL) * m_MaxAttribCount, + "BackendShaderInputEntryGL"); + + GLint maxLength; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength)); + QT3DSI8 *nameBuf = + (QT3DSI8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), maxLength, "LinkProgram"); + + // fill in data + QT3DSU32 count = 0; + QT3DS_FOREACH(idx, numAttribs) + { + GLint size = 0; + GLenum glType; + NVRenderComponentTypes::Enum compType = NVRenderComponentTypes::Unknown; + QT3DSU32 numComps = 0; + + GL_CALL_FUNCTION(glGetActiveAttrib(programID, idx, maxLength, NULL, &size, &glType, + (char *)nameBuf)); + // Skip anything named with gl_ + if (memcmp(nameBuf, "gl_", 3) == 0) + continue; + + m_Conversion.fromAttribGLToComponentTypeAndNumComps(glType, compType, numComps); + + tempShaderInputEntry[count].m_AttribName = + m_StringTable->RegisterStr((char *)nameBuf); + tempShaderInputEntry[count].m_AttribLocation = + GL_CALL_FUNCTION(glGetAttribLocation(programID, (char *)nameBuf)); + tempShaderInputEntry[count].m_Type = glType; + tempShaderInputEntry[count].m_NumComponents = numComps; + + ++count; + } + + // Now allocate space for the actuall entries + QT3DSU32 shaderInputSize = sizeof(NVRenderBackendShaderInputGL); + QT3DSU32 entrySize = sizeof(NVRenderBackendShaderInputEntryGL) * count; + QT3DSU8 *newMem = + (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), shaderInputSize + entrySize, + "BackendShaderInputEntryGL"); + NVDataRef entryRef = + PtrAtOffset(newMem, shaderInputSize, + entrySize); + // fill data + QT3DS_FOREACH(idx, count) + { + entryRef[idx].m_AttribName = tempShaderInputEntry[idx].m_AttribName; + entryRef[idx].m_AttribLocation = tempShaderInputEntry[idx].m_AttribLocation; + entryRef[idx].m_Type = tempShaderInputEntry[idx].m_Type; + entryRef[idx].m_NumComponents = tempShaderInputEntry[idx].m_NumComponents; + } + + // placement new + NVRenderBackendShaderInputGL *shaderInput = + new (newMem) NVRenderBackendShaderInputGL(entryRef); + // set the pointer + pProgram->m_shaderInput = shaderInput; + + QT3DS_FREE(m_Foundation.getAllocator(), nameBuf); + QT3DS_FREE(m_Foundation.getAllocator(), tempShaderInputEntry); + } + } + + // Check if some log exists. We also write warnings here + // Should at least contain more than the null termination + if (logLen > 2) { + errorMessage.resize(logLen + 1); + + GLint lenWithoutNull; + GL_CALL_FUNCTION(glGetProgramInfoLog(programID, logLen, &lenWithoutNull, + (char *)errorMessage.c_str())); + } + + return (linkStatus == GL_TRUE); + } + + void NVRenderBackendGLBase::SetActiveProgram(NVRenderBackendShaderProgramObject po) + { + GLuint programID = 0; + + if (po) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + programID = static_cast(pProgram->m_ProgramID); + } + + GL_CALL_FUNCTION(glUseProgram(programID)); + } + + NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGLBase::CreateProgramPipeline() + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + return NVRenderBackend::NVRenderBackendProgramPipeline(0); + } + + void NVRenderBackendGLBase::ReleaseProgramPipeline(NVRenderBackendProgramPipeline) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetActiveProgramPipeline(NVRenderBackendProgramPipeline) + { + // needs GL 4 context + //TODO: should be fixed? + // QT3DS_ASSERT(false); + } + + void NVRenderBackendGLBase::SetProgramStages(NVRenderBackendProgramPipeline, + NVRenderShaderTypeFlags, + NVRenderBackendShaderProgramObject) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSU32) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + QT3DSI32 NVRenderBackendGLBase::GetConstantCount(NVRenderBackendShaderProgramObject po) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLint numUniforms; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORMS, &numUniforms)); + + return numUniforms; + } + + QT3DSI32 NVRenderBackendGLBase::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; + } + + QT3DSI32 + NVRenderBackendGLBase::GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLenum glType; + GL_CALL_FUNCTION(glGetActiveUniform(programID, id, bufSize, NULL, numElem, &glType, nameBuf)); + *type = m_Conversion.fromShaderGLToPropertyDataTypes(glType); + + QT3DSI32 uniformLoc = GL_CALL_FUNCTION(glGetUniformLocation(programID, nameBuf)); + + // get unit binding point + *binding = -1; + if (uniformLoc != -1 && (glType == GL_IMAGE_2D || glType == GL_UNSIGNED_INT_IMAGE_2D + || glType == GL_UNSIGNED_INT_ATOMIC_COUNTER)) { + GL_CALL_FUNCTION(glGetUniformiv(programID, uniformLoc, binding)); + } + + return uniformLoc; + } + + QT3DSI32 + NVRenderBackendGLBase::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; + } + + void NVRenderBackendGLBase::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(indices); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(count); + NVRENDER_BACKEND_UNUSED(indices); + NVRENDER_BACKEND_UNUSED(type); + NVRENDER_BACKEND_UNUSED(size); + NVRENDER_BACKEND_UNUSED(offset); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(blockIndex); + NVRENDER_BACKEND_UNUSED(binding); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + QT3DSI32 NVRenderBackendGLBase::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; + } + + QT3DSI32 + NVRenderBackendGLBase::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; + } + + void NVRenderBackendGLBase::ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + } + + QT3DSI32 NVRenderBackendGLBase::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; + } + + QT3DSI32 + NVRenderBackendGLBase::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; + } + + void NVRenderBackendGLBase::ProgramSetAtomicCounterBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + } + + void NVRenderBackendGLBase::SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) + { + GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); + + switch (glType) { + case GL_FLOAT: + GL_CALL_FUNCTION(glUniform1fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC2: + GL_CALL_FUNCTION(glUniform2fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC3: + GL_CALL_FUNCTION(glUniform3fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC4: + GL_CALL_FUNCTION(glUniform4fv(id, count, (GLfloat *)value)); + break; + case GL_INT: + GL_CALL_FUNCTION(glUniform1iv(id, count, (GLint *)value)); + break; + case GL_BOOL: + { + GLint boolValue = *(GLboolean *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, &boolValue)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + GL_CALL_FUNCTION(glUniform2iv(id, count, (GLint *)value)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + GL_CALL_FUNCTION(glUniform3iv(id, count, (GLint *)value)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + GL_CALL_FUNCTION(glUniform4iv(id, count, (GLint *)value)); + break; + case GL_FLOAT_MAT3: + GL_CALL_FUNCTION(glUniformMatrix3fv(id, count, transpose, (GLfloat *)value)); + break; + case GL_FLOAT_MAT4: + GL_CALL_FUNCTION(glUniformMatrix4fv(id, count, transpose, (GLfloat *)value)); + break; + case GL_IMAGE_2D: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: { + if (count > 1) { + GLint *sampler = (GLint *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, sampler)); + } else { + GLint sampler = *(GLint *)value; + GL_CALL_FUNCTION(glUniform1i(id, sampler)); + } + } break; + default: + qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); + QT3DS_ASSERT(false); + break; + } + } + + void NVRenderBackendGLBase::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) + { + GL_CALL_FUNCTION(glDrawArrays(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + start, count)); + } + + void NVRenderBackendGLBase::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(drawMode); + NVRENDER_BACKEND_UNUSED(indirect); + } + + void NVRenderBackendGLBase::DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) + { + GL_CALL_FUNCTION(glDrawElements(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + count, m_Conversion.fromIndexBufferComponentsTypesToGL(type), + indices)); + } + + void NVRenderBackendGLBase::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(drawMode); + NVRENDER_BACKEND_UNUSED(type); + NVRENDER_BACKEND_UNUSED(indirect); + } + + void NVRenderBackendGLBase::ReadPixel(NVRenderBackendRenderTargetObject /* rto */, QT3DSI32 x, + QT3DSI32 y, QT3DSI32 width, QT3DSI32 height, + NVRenderReadPixelFormats::Enum inFormat, void *pixels) + { + GLuint glFormat; + GLuint glType; + if (m_Conversion.fromReadPixelsToGlFormatAndType(inFormat, &glFormat, &glType)) { + GL_CALL_FUNCTION(glReadPixels(x, y, width, height, glFormat, glType, pixels)); + } + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::CreatePathNVObject(size_t) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackend::NVRenderBackendPathObject(0); + } + + void NVRenderBackendGLBase::ReleasePathNVObject(NVRenderBackendPathObject, size_t) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::LoadPathGlyphs(NVRenderBackendPathObject, + NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, + NVRenderBackendPathObject, QT3DSF32) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::LoadPathGlyphRange(NVRenderBackendPathObject, + NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, + NVRenderBackendPathObject, QT3DSF32) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderPathReturnValues::Enum NVRenderBackendGLBase::LoadPathGlyphsIndexed( + NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, QT3DSF32) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderPathReturnValues::FontUnavailable; + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::Enum, const void *, NVRenderPathFontStyleFlags, + NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) + { + return NVRenderBackendPathObject(0); + } + + void NVRenderBackendGLBase::GetPathMetrics(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, + NVRenderPathFormatType::Enum, const void *, size_t, + QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, + QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetPathSpacing(NVRenderBackendPathObject, size_t, + NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, + QT3DSF32, NVRenderPathTransformType::Enum, QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, + const void *, QT3DSI32, QT3DSU32, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + ///< private calls + const char *NVRenderBackendGLBase::getVersionString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VERSION)); + if (retval == NULL) + return ""; + + return retval; + } + + const char *NVRenderBackendGLBase::getVendorString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VENDOR)); + if (retval == NULL) + return ""; + + return retval; + } + + const char *NVRenderBackendGLBase::getRendererString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER)); + if (retval == NULL) + return ""; + + return retval; + } + + const char *NVRenderBackendGLBase::getExtensionString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS)); + if (retval == NULL) + return ""; + + return retval; + } + + /** + * @brief This function inspects the various strings to setup + * HW capabilities of the device. + * We can do a lot of smart things here based on GL version + * renderer string and vendor. + * + * @return No return + */ + void NVRenderBackendGLBase::setAndInspectHardwareCaps() + { + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + // we assume all GLES versions running on mobile with shared memory + // this means framebuffer blits are slow and should be optimized or avoided + if (apiVersion.find("OpenGL ES") == eastl::string::npos) { + // no ES device + m_backendSupport.caps.bits.bFastBlitsSupported = true; + } + } + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS + void NVRenderBackendGLBase::checkGLError(const char *function, const char *file, + const unsigned int line) const + { + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR) << GLConversion::processGLError(error) << " " + << function << " " << file << " " << line; + } + } +#else + void NVRenderBackendGLBase::checkGLError() const + { +#if !defined(NDEBUG) || defined(_DEBUG) + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) + qCCritical(GL_ERROR) << GLConversion::processGLError(error); +#endif + } +#endif + +} +} diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h new file mode 100644 index 00000000..9048a9c4 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h @@ -0,0 +1,530 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL_BASE_H +#define QT3DS_RENDER_BACKEND_GL_BASE_H + +/// @file Qt3DSRenderBackendGLBase.h +/// NVRender OpenGL Core backend definition. + +#include "foundation/Qt3DSContainers.h" +#include "foundation/StringTable.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/backends/gl/Qt3DSOpenGLUtil.h" +#include + +#include +#include +#include + +#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; + +// Enable this to log opengl errors instead of an assert +//#define RENDER_BACKEND_LOG_GL_ERRORS + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendRasterizerStateGL; + class NVRenderBackendDepthStencilStateGL; + + using namespace foundation; + + typedef eastl::basic_string TContextStr; + + class NVRenderBackendGLBase : public NVRenderBackend + { + public: + /// constructor + NVRenderBackendGLBase(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGLBase(); + + public: + /// API Interface + NVRenderContextType GetRenderContextType() const override; + bool isESCompatible() const; + + const char *GetShadingLanguageVersion() override; + /// get implementation depended values + QT3DSU32 GetMaxCombinedTextureUnits() override; + bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const override; + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override; + + /// state get/set functions + void SetRenderState(bool bEnable, const NVRenderState::Enum value) override; + bool GetRenderState(const NVRenderState::Enum value) override; + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) override; + virtual void + ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; + virtual NVRenderBackendRasterizerStateObject + CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) override; + void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; + virtual void + SetDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; + void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; + NVRenderBoolOp::Enum GetDepthFunc() override; + void SetDepthFunc(const NVRenderBoolOp::Enum func) override; + bool GetDepthWrite() override; + void SetDepthWrite(bool bEnable) override; + void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) override; + void SetMultisample(bool bEnable) override; + void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) override; + void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) override; + void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; + void SetBlendBarrier(void) override; + void GetScissorRect(NVRenderRect *pRect) override; + void SetScissorRect(const NVRenderRect &rect) override; + void GetViewportRect(NVRenderRect *pRect) override; + void SetViewportRect(const NVRenderRect &rect) override; + + void SetClearColor(const QT3DSVec4 *pClearColor) override; + void Clear(NVRenderClearFlags flags) override; + + /// resource handling + NVRenderBackendBufferObject CreateBuffer(size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, + const void *hostPtr = NULL) override; + void BindBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + void ReleaseBuffer(NVRenderBackendBufferObject bo) override; + void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t size, NVRenderBufferUsageType::Enum usage, + const void *data) override; + void UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) override; + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + NVRenderBackendRenderTargetObject CreateRenderTarget() override; + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) override; + void RenderTargetAttach( + NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; + void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; + + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) override; + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) override; + + NVRenderBackendTextureObject CreateTexture() override; + void BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) override; + void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) override; + void ReleaseTexture(NVRenderBackendTextureObject to) override; + void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void SetTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) override; + void SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void SetCompressedTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) override; + void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) override; + void SetCompressedTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, + size_t width, size_t height, + NVRenderTextureFormats::Enum format, + size_t imageSize, const void *hostPtr = NULL) override; + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override = 0; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const override; + + NVRenderBackendSamplerObject CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + void ReleaseSampler(NVRenderBackendSamplerObject so) override; + + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef attribs) override; + void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) override; + + virtual NVRenderBackendInputAssemblerObject + CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, + QT3DSU32 patchVertexCount) override; + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override = 0; + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override + { + QT3DS_ASSERT(false); + } + + // shader + virtual NVRenderBackendVertexShaderObject + CreateVertexShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendFragmentShaderObject + CreateFragmentShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendComputeShaderObject + CreateComputeShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) override; + void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) override; + void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) override; + void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) override; + void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) override; + void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) override; + NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) override; + void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) override; + bool LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) override; + void SetActiveProgram(NVRenderBackendShaderProgramObject po) override; + void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + NVRenderBackendProgramPipeline CreateProgramPipeline() override; + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline po) override; + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline po) override; + void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) override; + + // uniforms + QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) override; + void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) override; + + // uniform buffers + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + // storage buffers + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + // atomic counter buffers + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + /// draw calls + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) override; + void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; + void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) override; + void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, const void *indirect) override; + + // read calls + void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, + QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, void *pixels) override; + + // NV path rendering + NVRenderBackendPathObject CreatePathNVObject(size_t range) override; + // Pathing requires gl4 backend. + void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef, + NVConstDataRef) override + { + } + + ///< Bounds of the fill and stroke + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + + /** + * Defaults to 0 if unset. + */ + void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} + void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} + void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} + void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} + void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} + void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} + void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; + + void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override; + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, + NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) override; + void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override; + void GetPathMetrics(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, NVRenderPathFormatType::Enum, + const void *, size_t, QT3DSF32 *) override; + void GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override; + void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, + NVRenderPathTransformType::Enum, QT3DSF32 *) override; + + void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, QT3DSI32, + QT3DSU32, NVRenderPathTransformType::Enum, + const QT3DSF32 *) override; + void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + + QSurfaceFormat format() const override + { + return m_format; + } + + protected: + virtual NVFoundationBase &GetFoundation() { return m_Foundation; } + virtual bool compileSource(GLuint shaderID, NVConstDataRef source, + eastl::string &errorMessage, bool binary); + virtual const char *getVersionString(); + virtual const char *getVendorString(); + virtual const char *getRendererString(); + virtual const char *getExtensionString(); + + virtual void setAndInspectHardwareCaps(); + + protected: + volatile QT3DSI32 mRefCount; ///< reference count + NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things + NVScopedRefCounted + m_StringTable; ///< pointer to a string table + GLConversion m_Conversion; ///< Class for conversion from base type to GL types + QStringList m_extensions; ///< contains the OpenGL extension string + QT3DSI32 m_MaxAttribCount; ///< Maximum attributes which can be used + nvvector m_DrawBuffersArray; ///< Contains the drawbuffer enums + QSurfaceFormat m_format; + + NVRenderBackendRasterizerStateGL + *m_pCurrentRasterizerState; ///< this holds the current rasterizer state + NVRenderBackendDepthStencilStateGL + *m_pCurrentDepthStencilState; ///< this holds the current depth stencil state + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS + void checkGLError(const char *function, const char *file, const unsigned int line) const; +#else + void checkGLError() const; +#endif + QOpenGLFunctions *m_glFunctions; + QOpenGLExtraFunctions *m_glExtraFunctions; + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h new file mode 100644 index 00000000..e14111af --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H +#define QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StringTable.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + struct NVRenderBackendLayoutEntryGL + { + CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader + QT3DSU8 m_Normalize; ///< normalize parameter + QT3DSU32 m_AttribIndex; ///< attribute index + QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT + QT3DSU32 m_NumComponents; ///< component count. max 4 + QT3DSU32 m_InputSlot; ///< Input slot where to fetch the data from + QT3DSU32 m_Offset; ///< offset in byte + }; + + ///< this class handles the vertex attribute layout setup + class NVRenderBackendAttributeLayoutGL + { + public: + ///< constructor + NVRenderBackendAttributeLayoutGL(NVDataRef entries, + QT3DSU32 maxInputSlot) + : m_LayoutAttribEntries(entries) + , m_MaxInputSlot(maxInputSlot) + { + } + ///< destructor + ~NVRenderBackendAttributeLayoutGL(){} + + NVRenderBackendLayoutEntryGL *getEntryByName(CRegisteredString entryName) const + { + QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) + { + if (m_LayoutAttribEntries[idx].m_AttribName == entryName) + return &m_LayoutAttribEntries.mData[idx]; + } + return NULL; + } + + Option getEntryByAttribIndex(QT3DSU32 attribIndex) const + { + QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) + { + if (m_LayoutAttribEntries[idx].m_AttribIndex == attribIndex) + return m_LayoutAttribEntries[idx]; + } + return Empty(); + } + + NVDataRef + m_LayoutAttribEntries; ///< vertex attribute layout entries + QT3DSU32 m_MaxInputSlot; ///< max used input slot + }; + + ///< this class handles the input assembler setup + class NVRenderBackendInputAssemblerGL + { + public: + ///< constructor + NVRenderBackendInputAssemblerGL( + NVFoundationBase &fnd, NVRenderBackendAttributeLayoutGL *attribLayout, + NVConstDataRef buffers, + const NVRenderBackend::NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, QT3DSU32 patchVertexCount) + : m_Foundation(fnd) + , m_attribLayout(attribLayout) + , m_VertexbufferHandles(buffers) + , m_IndexbufferHandle(indexBuffer) + , m_VaoID(0) + , m_cachedShaderHandle(0) + , m_PatchVertexCount(patchVertexCount) + { + QT3DSU32 *strideMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), + "BackendAttributeLayoutGL:m_strides"); + QT3DSU32 *offsetMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), + "BackendAttributeLayoutGL:m_strides"); + // copy offsets and strides + QT3DS_FOREACH(idx, strides.size()) + { + strideMem[idx] = strides.mData[idx]; + offsetMem[idx] = offsets.mData[idx]; + } + + m_strides = toDataRef(strideMem, strides.size()); + m_offsets = toDataRef(offsetMem, offsets.size()); + } + ///< destructor + ~NVRenderBackendInputAssemblerGL() + { + QT3DS_FREE(m_Foundation.getAllocator(), m_strides.mData); + QT3DS_FREE(m_Foundation.getAllocator(), m_offsets.mData); + }; + + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackendAttributeLayoutGL *m_attribLayout; ///< pointer to attribute layout + NVConstDataRef + m_VertexbufferHandles; ///< opaque vertex buffer backend handles + NVRenderBackend::NVRenderBackendBufferObject + m_IndexbufferHandle; ///< opaque index buffer backend handles + QT3DSU32 m_VaoID; ///< this is only used if GL version is greater or equal 3 + QT3DSU32 m_cachedShaderHandle; ///< this is the shader id which was last used with this object + QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive + NVDataRef m_strides; ///< buffer strides + NVDataRef m_offsets; ///< buffer offsets + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h new file mode 100644 index 00000000..3a74a8e3 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H +#define QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + ///< this class handles the shader input variables + class NVRenderBackendDepthStencilStateGL + { + public: + ///< constructor + NVRenderBackendDepthStencilStateGL(bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + : m_DepthEnable(enableDepth) + , m_DepthMask(depthMask) + , m_DepthFunc(depthFunc) + , m_StencilEnable(enableStencil) + , m_StencilFuncFront(stencilFuncFront) + , m_StencilFuncBack(stencilFuncBack) + , m_DepthStencilOpFront(depthStencilOpFront) + , m_DepthStencilOpBack(depthStencilOpBack) + { + } + + ///< constructor + NVRenderBackendDepthStencilStateGL() + : m_DepthEnable(true) + , m_DepthMask(true) + , m_DepthFunc(NVRenderBoolOp::LessThanOrEqual) + , m_StencilEnable(false) + { + } + + ///< destructor + ~NVRenderBackendDepthStencilStateGL(){} + + ///< assignement + NVRenderBackendDepthStencilStateGL &operator=(const NVRenderBackendDepthStencilStateGL &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_DepthEnable = rhs.m_DepthEnable; + m_DepthMask = rhs.m_DepthMask; + m_DepthFunc = rhs.m_DepthFunc; + m_StencilEnable = rhs.m_StencilEnable; + m_StencilFuncFront = rhs.m_StencilFuncFront; + m_StencilFuncBack = rhs.m_StencilFuncBack; + m_DepthStencilOpFront = rhs.m_DepthStencilOpFront; + m_DepthStencilOpBack = rhs.m_DepthStencilOpBack; + + return *this; + } + + bool operator==(const NVRenderBackendDepthStencilStateGL &other) const + { + return (m_DepthEnable == other.m_DepthEnable && m_DepthMask == other.m_DepthMask + && m_DepthFunc == other.m_DepthFunc && m_StencilEnable == other.m_StencilEnable + && m_StencilFuncFront == other.m_StencilFuncFront + && m_StencilFuncBack == other.m_StencilFuncBack + && m_DepthStencilOpFront == other.m_DepthStencilOpFront + && m_DepthStencilOpBack == other.m_DepthStencilOpBack); + } + + bool m_DepthEnable; ///< depth test enabled + bool m_DepthMask; ///< enable / disable depth writes + NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func + bool m_StencilEnable; ///< enable disable stencil test + NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup for front faces + NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup for back faces + NVRenderStencilOperationArgument + m_DepthStencilOpFront; ///< depth stencil operation for front faces + NVRenderStencilOperationArgument + m_DepthStencilOpBack; ///< depth stencil operation for back faces + }; + + class NVRenderBackendMiscStateGL + { + public: + ///< constructor + NVRenderBackendMiscStateGL() + : m_PatchVertexCount(1) + { + } + + QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive + }; + + class NVRenderBackendRasterizerStateGL + { + public: + ///< constructor + NVRenderBackendRasterizerStateGL(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + : m_DepthBias(depthBias) + , m_DepthScale(depthScale) + , m_CullFace(cullFace) + { + } + ///< constructor + NVRenderBackendRasterizerStateGL() + : m_DepthBias(0.0) + , m_DepthScale(0.0) + , m_CullFace(NVRenderFaces::Back) + { + } + + NVRenderBackendRasterizerStateGL &operator=(const NVRenderBackendRasterizerStateGL &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_DepthBias = rhs.m_DepthBias; + m_DepthScale = rhs.m_DepthScale; + m_CullFace = rhs.m_CullFace; + + return *this; + } + + bool operator==(const NVRenderBackendRasterizerStateGL &other) const + { + return (m_DepthBias == other.m_DepthBias && m_DepthScale == other.m_DepthScale + && m_CullFace == other.m_CullFace); + } + + QT3DSF32 m_DepthBias; ///< depth bias + QT3DSF32 m_DepthScale; ///< mulitply constant + NVRenderFaces::Enum m_CullFace; ///< cull face front or back + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h new file mode 100644 index 00000000..f7caffd8 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H +#define QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + struct NVRenderBackendShaderInputEntryGL + { + CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader + QT3DSU32 m_AttribLocation; ///< attribute index + QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT + QT3DSU32 m_NumComponents; ///< component count. max 4 + }; + + ///< this class handles the shader input variables + class NVRenderBackendShaderInputGL + { + public: + ///< constructor + NVRenderBackendShaderInputGL(NVDataRef entries) + : m_ShaderInputEntries(entries) + { + } + ///< destructor + ~NVRenderBackendShaderInputGL(){} + + NVRenderBackendShaderInputEntryGL *getEntryByName(CRegisteredString entryName) const + { + QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) + { + if (m_ShaderInputEntries[idx].m_AttribName == entryName) + return &m_ShaderInputEntries.mData[idx]; + } + return NULL; + } + + Option + getEntryByAttribLocation(QT3DSU32 attribLocation) const + { + QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) + { + if (m_ShaderInputEntries[idx].m_AttribLocation == attribLocation) + return m_ShaderInputEntries[idx]; + } + return Empty(); + } + + NVDataRef m_ShaderInputEntries; ///< shader input entries + }; + + ///< this class represents the internals of a GL program + class NVRenderBackendShaderProgramGL + { + public: + ///< constructor + NVRenderBackendShaderProgramGL(QT3DSU32 programID) + : m_ProgramID(programID) + , m_shaderInput(NULL) + { + } + + ///< destructor + ~NVRenderBackendShaderProgramGL(){} + + QT3DSU32 m_ProgramID; ///< this is the OpenGL object ID + NVRenderBackendShaderInputGL *m_shaderInput; ///< pointer to shader input object + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp new file mode 100644 index 00000000..88670ef7 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMat44.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Utils.h" +#include "EASTL/set.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace eastl; + +namespace qt3ds { +namespace render { + + NVRenderContext &NVRenderContext::CreateGL(NVFoundationBase &foundation, + IStringTable &inStringTable, + const QSurfaceFormat &format) + { + NVRenderContext *retval = NULL; + + QT3DS_ASSERT(format.majorVersion() >= 2); + + // create backend + NVScopedRefCounted theStringTable(inStringTable); + NVScopedRefCounted theBackend; + bool isES = format.renderableType() == QSurfaceFormat::OpenGLES; + if (isES && (format.majorVersion() == 2 + || (format.majorVersion() == 3 && format.minorVersion() == 0))) { + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGLES2Impl)(foundation, + *theStringTable, + format); + } else if (format.majorVersion() == 3 && format.minorVersion() >= 1 && !isES) { + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, + *theStringTable, + format); + } else if (format.majorVersion() == 4 + || (isES && format.majorVersion() == 3 && format.minorVersion() >= 1)) { +#ifdef Q_OS_MACOS + // TODO: macOS crashes with glTextStorage2DMultisample, so fall back to OpenGL3 + // for now (QT3DS-590) + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, + *theStringTable, + format); +#else + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL4Impl)(foundation, + *theStringTable, + format); +#endif + } else { + QT3DS_ASSERT(false); + qCCritical(INTERNAL_ERROR) << "Can't find a suitable OpenGL version for" << format; + } + + + retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, + *theStringTable); + + return *retval; + } +} +} diff --git a/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp new file mode 100644 index 00000000..af93e928 --- /dev/null +++ b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp @@ -0,0 +1,588 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "render/backends/software/Qt3DSRenderBackendNULL.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" + +#include + +using namespace qt3ds::render; +using namespace qt3ds::foundation; +using namespace qt3ds; + +namespace { +struct SNullBackend : public NVRenderBackend +{ + NVFoundationBase &m_Foundation; + QT3DSI32 mRefCount; + + SNullBackend(NVFoundationBase &fnd) + : m_Foundation(fnd) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + /// backend interface + + NVRenderContextType GetRenderContextType() const override + { + return NVRenderContextValues::NullContext; + } + const char *GetShadingLanguageVersion() override { return ""; } + QT3DSU32 GetMaxCombinedTextureUnits() override { return 32; } + bool GetRenderBackendCap(NVRenderBackendCaps::Enum) const override { return false; } + void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override + { + if (params) { + switch (inQuery) { + case NVRenderBackendQuery::MaxTextureSize: + *params = 4096; + break; + case NVRenderBackendQuery::MaxTextureArrayLayers: + *params = 0; + break; + default: + QT3DS_ASSERT(false); + *params = 0; + break; + } + } + } + QT3DSU32 GetDepthBits() const override { return 16; } + QT3DSU32 GetStencilBits() const override { return 0; } + void SetRenderState(bool, const NVRenderState::Enum) override {} + bool GetRenderState(const NVRenderState::Enum) override { return false; } + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool, bool, NVRenderBoolOp::Enum, bool, + NVRenderStencilFunctionArgument &, NVRenderStencilFunctionArgument &, + NVRenderStencilOperationArgument &, NVRenderStencilOperationArgument &) override + { + return NVRenderBackendDepthStencilStateObject(1); + } + void ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} + NVRenderBackendRasterizerStateObject CreateRasterizerState(QT3DSF32, QT3DSF32, + NVRenderFaces::Enum) override + { + return NVRenderBackendRasterizerStateObject(1); + } + void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject) override {} + void SetDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} + void SetRasterizerState(NVRenderBackendRasterizerStateObject) override {} + NVRenderBoolOp::Enum GetDepthFunc() override { return NVRenderBoolOp::Equal; } + void SetDepthFunc(const NVRenderBoolOp::Enum) override {} + bool GetDepthWrite() override { return false; } + + void SetDepthWrite(bool) override {} + void SetColorWrites(bool, bool, bool, bool) override {} + void SetMultisample(bool) override {} + void GetBlendFunc(NVRenderBlendFunctionArgument *) override {} + void SetBlendFunc(const NVRenderBlendFunctionArgument &) override {} + void SetBlendEquation(const NVRenderBlendEquationArgument &) override {} + void SetBlendBarrier(void) override {} + void GetScissorRect(NVRenderRect *) override {} + void SetScissorRect(const NVRenderRect &) override {} + void GetViewportRect(NVRenderRect *) override {} + void SetViewportRect(const NVRenderRect &) override {} + void SetClearColor(const QT3DSVec4 *) override {} + void Clear(NVRenderClearFlags) override {} + NVRenderBackendBufferObject CreateBuffer(size_t, NVRenderBufferBindFlags, + NVRenderBufferUsageType::Enum, const void *) override + { + return NVRenderBackendBufferObject(1); + } + void BindBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override {} + void ReleaseBuffer(NVRenderBackendBufferObject) override {} + + void UpdateBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, + NVRenderBufferUsageType::Enum, const void *) override + { + } + void UpdateBufferRange(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, + const void *) override + { + } + void *MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, + NVRenderBufferAccessFlags) override + { + return NULL; + } + bool UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override { return true; } + void SetMemoryBarrier(NVRenderBufferBarrierFlags) override {} + NVRenderBackendQueryObject CreateQuery() override { return NVRenderBackendQueryObject(1); } + void ReleaseQuery(NVRenderBackendQueryObject) override {} + void BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} + void EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} + void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, + QT3DSU32 *) override {} + void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, + QT3DSU64 *) override {} + void SetQueryTimer(NVRenderBackendQueryObject) override {} + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) override + { + return NVRenderBackendSyncObject(1); + }; + void ReleaseSync(NVRenderBackendSyncObject) override {} + void WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, QT3DSU64) override {} + NVRenderBackendRenderTargetObject CreateRenderTarget() override + { + return NVRenderBackendRenderTargetObject(1); + } + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject) override {} + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendRenderbufferObject) override + { + } + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum) override + { + } + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) override + { + } + void SetRenderTarget(NVRenderBackendRenderTargetObject) override {} + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject) override { return false; } + void SetReadTarget(NVRenderBackendRenderTargetObject) override {} + void SetDrawBuffers(NVRenderBackendRenderTargetObject, NVConstDataRef) override {} + void SetReadBuffer(NVRenderBackendRenderTargetObject, NVReadFaces::Enum) override {} + + void BlitFramebuffer(QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, + NVRenderClearFlags, NVRenderTextureMagnifyingOp::Enum) override + { + } + NVRenderBackendRenderbufferObject CreateRenderbuffer(NVRenderRenderBufferFormats::Enum, + size_t, size_t) override + { + return NVRenderBackendRenderbufferObject(1); + } + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject) override {} + + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject, + NVRenderRenderBufferFormats::Enum, size_t, size_t) override + { + return false; + } + NVRenderBackendTextureObject CreateTexture() override { return NVRenderBackendTextureObject(1); } + + void SetTextureData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + NVRenderTextureFormats::Enum, const void *) override + { + } + void SetTextureDataCubeFace(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + NVRenderTextureFormats::Enum, const void *) override + { + } + void CreateTextureStorage2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t) override + { + } + void SetTextureSubData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, QT3DSI32, QT3DSI32, size_t, size_t, + NVRenderTextureFormats::Enum, const void *) override + { + } + void SetCompressedTextureData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + size_t, const void *) override + { + } + void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, + QT3DSI32, size_t, const void *) override + { + } + void SetCompressedTextureSubData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, QT3DSI32, QT3DSI32, + size_t, size_t, NVRenderTextureFormats::Enum, size_t, + const void *) override + { + } + void SetMultisampledTextureData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, size_t, + NVRenderTextureFormats::Enum, size_t, size_t, bool) override + { + } + void SetTextureData3D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, size_t, + QT3DSI32, NVRenderTextureFormats::Enum, const void *) override + { + } + void GenerateMipMaps(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + NVRenderHint::Enum) override + { + } + void BindTexture(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, QT3DSU32) override + { + } + void BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, QT3DSI32, + NVRenderImageAccessType::Enum, NVRenderTextureFormats::Enum) override + { + } + void ReleaseTexture(NVRenderBackendTextureObject) override {} + + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum) const override + { + return NVRenderTextureSwizzleMode::NoSwizzle; + } + + virtual NVRenderBackendSamplerObject + CreateSampler(NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, + NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, + NVRenderTextureCoordOp::Enum, QT3DSI32, QT3DSI32, QT3DSF32, + NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, QT3DSF32, QT3DSF32 *) override + { + return NVRenderBackendSamplerObject(1); + } + + void UpdateSampler(NVRenderBackendSamplerObject, NVRenderTextureTargetType::Enum, + NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, + NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, + NVRenderTextureCoordOp::Enum, QT3DSF32, QT3DSF32, QT3DSF32, + NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, + QT3DSF32, QT3DSF32 *) override + { + } + + void UpdateTextureObject(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSI32, QT3DSI32) override + { + } + + void UpdateTextureSwizzle(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + NVRenderTextureSwizzleMode::Enum) override + { + } + + void ReleaseSampler(NVRenderBackendSamplerObject) override {} + + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef) override + { + return NVRenderBackendAttribLayoutObject(1); + } + + void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject) override {} + + NVRenderBackendInputAssemblerObject CreateInputAssembler( + NVRenderBackendAttribLayoutObject, NVConstDataRef, + const NVRenderBackendBufferObject, NVConstDataRef, NVConstDataRef, QT3DSU32) override + { + return NVRenderBackendInputAssemblerObject(1); + } + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject) override {} + bool SetInputAssembler(NVRenderBackendInputAssemblerObject, + NVRenderBackendShaderProgramObject) override + { + return false; + } + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override {} + NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendVertexShaderObject(1); + } + void ReleaseVertexShader(NVRenderBackendVertexShaderObject) override {} + NVRenderBackendFragmentShaderObject CreateFragmentShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendFragmentShaderObject(1); + } + void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject) override {} + NVRenderBackendTessControlShaderObject CreateTessControlShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendTessControlShaderObject(1); + } + void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject) override {} + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef, eastl::string &, bool) override + { + return NVRenderBackendTessEvaluationShaderObject(1); + } + void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject) override {} + NVRenderBackendGeometryShaderObject CreateGeometryShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendGeometryShaderObject(1); + } + void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject) override {} + NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendComputeShaderObject(1); + } + void ReleaseComputeShader(NVRenderBackendComputeShaderObject) override {} + void AttachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendFragmentShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessControlShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessEvaluationShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendGeometryShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendComputeShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendFragmentShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessControlShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessEvaluationShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendGeometryShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendComputeShaderObject) override + { + } + NVRenderBackendShaderProgramObject CreateShaderProgram(bool) override + { + return NVRenderBackendShaderProgramObject(1); + } + void ReleaseShaderProgram(NVRenderBackendShaderProgramObject) override {} + NVRenderBackendProgramPipeline CreateProgramPipeline() override + { + return NVRenderBackendProgramPipeline(1); + } + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline) override {} + + bool LinkProgram(NVRenderBackendShaderProgramObject, eastl::string &) override { return false; } + void SetActiveProgram(NVRenderBackendShaderProgramObject) override {} + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline) override {} + void SetProgramStages(NVRenderBackendProgramPipeline, NVRenderShaderTypeFlags, + NVRenderBackendShaderProgramObject) override {} + void DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSU32) override {} + QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSI32 *, + NVRenderShaderDataTypes::Enum *, QT3DSI32 *, char *) override + { + return 0; + } + + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return 0; + } + + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSI32 *) override + { + } + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject, QT3DSU32, + QT3DSU32 *, QT3DSI32 *, QT3DSI32 *, QT3DSI32 *) override {} + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32) override {} + void ProgramSetConstantBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject) override { return 0; }; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return -1; + } + void ProgramSetStorageBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return -1; + }; + void ProgramSetAtomicCounterBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + void SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32, + NVRenderShaderDataTypes::Enum, QT3DSI32, const void *, bool) override + { + } + + void Draw(NVRenderDrawMode::Enum, QT3DSU32, QT3DSU32) override {} + void DrawIndirect(NVRenderDrawMode::Enum, const void *) override {} + + void DrawIndexed(NVRenderDrawMode::Enum, QT3DSU32, NVRenderComponentTypes::Enum, + const void *) override + { + } + void DrawIndexedIndirect(NVRenderDrawMode::Enum, NVRenderComponentTypes::Enum, + const void *) override + { + } + + void ReadPixel(NVRenderBackendRenderTargetObject, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, + NVRenderReadPixelFormats::Enum, void *) override + { + } + + NVRenderBackendPathObject CreatePathNVObject(size_t) override + { + return NVRenderBackendPathObject(1); + }; + void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef, + NVConstDataRef) override + { + } + + ///< Bounds of the fill and stroke + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + + /** + * Defaults to 0 if unset. + */ + void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} + void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} + void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} + + void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} + void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} + void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} + void ReleasePathNVObject(NVRenderBackendPathObject, size_t) override {} + + void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, QT3DSF32) override + { + } + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, + QT3DSF32) override + { + return NVRenderPathReturnValues::FontUnavailable; + } + NVRenderBackendPathObject LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, + const void *, + NVRenderPathFontStyleFlags, + NVRenderBackendPathObject, QT3DSF32, + QT3DSU32 *) override + { + return NVRenderBackendPathObject(1); + } + void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override + { + } + void GetPathMetrics(NVRenderBackendPathObject, size_t, NVRenderPathGlyphFontMetricFlags, + NVRenderPathFormatType::Enum, const void *, size_t, QT3DSF32 *) override + { + } + void GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override + { + } + void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, + NVRenderPathTransformType::Enum, QT3DSF32 *) override + { + } + + void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, QT3DSI32, + QT3DSU32, NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + QSurfaceFormat format() const override + { + return QSurfaceFormat(); + } +}; +} + +NVRenderBackend &NVRenderBackendNULL::CreateBackend(NVFoundationBase &foundation) +{ + return *QT3DS_NEW(foundation.getAllocator(), SNullBackend)(foundation); +} diff --git a/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h new file mode 100644 index 00000000..397ecfb1 --- /dev/null +++ b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_NULL_H +#define QT3DS_RENDER_BACKEND_NULL_H +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderBackendNULL : public NVRenderBackend + { + public: + static NVRenderBackend &CreateBackend(NVFoundationBase &foundation); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h b/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h new file mode 100644 index 00000000..28f246fd --- /dev/null +++ b/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GL_IMPL_OBJECTS_H +#define QT3DS_RENDER_GL_IMPL_OBJECTS_H +#include "render/backends/gl/Qt3DSOpenGLUtil.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace render { + + // The set of all properties as they are currently set in hardware. + struct SNVGLHardPropertyContext + { + NVRenderFrameBuffer *m_FrameBuffer; + NVRenderShaderProgram *m_ActiveShader; + NVRenderProgramPipeline *m_ActiveProgramPipeline; + NVRenderInputAssembler *m_InputAssembler; + NVRenderBlendFunctionArgument m_BlendFunction; + NVRenderBlendEquationArgument m_BlendEquation; + bool m_CullingEnabled; + NVRenderBoolOp::Enum m_DepthFunction; + bool m_BlendingEnabled; + bool m_DepthWriteEnabled; + bool m_DepthTestEnabled; + bool m_StencilTestEnabled; + bool m_ScissorTestEnabled; + bool m_ColorWritesEnabled; + bool m_MultisampleEnabled; + NVRenderRect m_ScissorRect; + NVRenderRect m_Viewport; + QT3DSVec4 m_ClearColor; + + SNVGLHardPropertyContext() + : m_FrameBuffer(NULL) + , m_ActiveShader(NULL) + , m_ActiveProgramPipeline(NULL) + , m_InputAssembler(NULL) + , m_CullingEnabled(true) + , m_DepthFunction(NVRenderBoolOp::Less) + , m_BlendingEnabled(true) + , m_DepthWriteEnabled(true) + , m_DepthTestEnabled(true) + , m_StencilTestEnabled(false) + , m_ScissorTestEnabled(true) + , m_ColorWritesEnabled(true) + , m_MultisampleEnabled(false) + , m_ClearColor(0, 0, 0, 1) + { + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSActivationManager.cpp b/src/Runtime/Source/runtime/Qt3DSActivationManager.cpp new file mode 100644 index 00000000..3d052742 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSActivationManager.cpp @@ -0,0 +1,1027 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "RuntimePrefix.h" +#include "Qt3DSActivationManager.h" +#include "Qt3DSElementSystem.h" +#include "Qt3DSComponentManager.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSInvasiveSet.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/StringTable.h" +#include "EASTL/sort.h" +#include "Qt3DSAttributeHashes.h" +#include "Qt3DSPresentation.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSync.h" +#include "Qt3DSRenderThreadPool.h" + +using namespace qt3ds::runtime; +using namespace qt3ds::runtime::element; +using qt3ds::render::IThreadPool; +using qt3ds::foundation::Time; + +namespace { + +typedef nvvector TElementAndSortKeyList; + +struct STimeEvent +{ + enum Type { + Start = 0, + Stop, + }; + + Type m_Type; + TTimeUnit m_Time; + nvvector m_AffectedNodes; + + STimeEvent(Type inType, NVAllocatorCallback &alloc, TTimeUnit inTime) + : m_Type(inType) + , m_Time(inTime) + , m_AffectedNodes(alloc, "TimeEvent") + { + } + + void Reset() + { + m_Time = 0; + m_AffectedNodes.clear(); + } +}; + +struct STimeEventGreaterThan +{ + bool operator()(const STimeEvent *lhs, const STimeEvent *rhs) const + { + if (lhs->m_Time == rhs->m_Time) + return lhs->m_Type > rhs->m_Type; + + return lhs->m_Time > rhs->m_Time; + } +}; + +struct STimeEventLessThan +{ + bool operator()(const STimeEvent *lhs, const STimeEvent *rhs) const + { + if (lhs->m_Time == rhs->m_Time) + return lhs->m_Type < rhs->m_Type; + + return lhs->m_Time < rhs->m_Time; + } +}; + +typedef nvvector TTimeEventList; +struct STimeContext; +typedef NVDataRef> TTimeContextSet; + +// Tree navigation + +SElement *GetElementNodeFirstChild(SElement &inNode) +{ + return inNode.m_Child; +} +SElement *GetElementNodeNextSibling(SElement &inNode) +{ + return inNode.m_Sibling; +} +SElement *GetElementNodeParent(SElement &inNode) +{ + return inNode.m_Parent; +} + +struct SScanBufferEntry +{ + SElement *m_Node; + QT3DSU32 m_StartTime; + QT3DSU32 m_EndTime; + + SScanBufferEntry() + : m_Node(NULL) + , m_StartTime(0) + , m_EndTime(QT3DS_MAX_U32) + { + } + SScanBufferEntry(SElement *inNode) + : m_Node(inNode) + , m_StartTime(0) + , m_EndTime(QT3DS_MAX_U32) + { + } + SScanBufferEntry(SElement *inNode, QT3DSU32 start, QT3DSU32 end) + : m_Node(inNode) + , m_StartTime(start) + , m_EndTime(end) + { + } + + SScanBufferEntry(SElement *inNode, bool inParentActive) + : m_Node(inNode) + , m_StartTime(inParentActive ? 1 : 0) + , m_EndTime(0) + { + } + + bool IsParentActive() const { return m_StartTime ? true : false; } +}; + +typedef nvvector TScanBuffer; +typedef nvvector TElementNodePtrList; + +struct SElementIndexPairSorter +{ + bool operator()(const eastl::pair &lhs, + const eastl::pair &rhs) const + { + return lhs.second < rhs.second; + } +}; + +struct SElementPtrSort +{ + bool operator()(const SElement *lhs, const SElement *rhs) + { + return lhs->Depth() < rhs->Depth(); + } +}; + +DEFINE_INVASIVE_SINGLE_LIST(TimeContext); + +struct STimeContext +{ + NVAllocatorCallback &m_Allocator; + SComponent &m_Component; + CTimePolicy m_TimePolicy; + SComponentTimePolicyOverride *m_TimePolicyOverride; + TTimeUnit m_CurrentTime; + TElementNodePtrList m_Elements; + TTimeEventList m_TimeEventBackingStore; + TTimeEventList m_TimeEvents; + SActivationManagerNodeDirtyList m_DirtyList; + QT3DSU32 m_TimeEventBackingStoreIndex; + QT3DSI32 mRefCount; + STimeContext *m_NextSibling; + TTimeContextList m_Children; + Mutex &m_ElementAccessMutex; + bool m_AllNodesDirty; + bool m_TimeDataNeedsUpdate; + + STimeContext(NVAllocatorCallback &alloc, SComponent &inComponent, Mutex &inElementAccessMutex) + : m_Allocator(alloc) + , m_Component(inComponent) + , m_TimePolicyOverride(NULL) + , m_CurrentTime(-1) + , m_Elements(alloc, "m_Elements") + , m_TimeEventBackingStore(alloc, "TimeEventBackingStore") + , m_TimeEvents(alloc, "TimeEvents") + , m_DirtyList(alloc) + , m_TimeEventBackingStoreIndex(0) + , mRefCount(0) + , m_NextSibling(NULL) + , m_ElementAccessMutex(inElementAccessMutex) + , m_AllNodesDirty(true) + , m_TimeDataNeedsUpdate(true) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) + ~STimeContext() + { + Reset(); + for (TTimeEventList::iterator iter = m_TimeEventBackingStore.begin(), + end = m_TimeEventBackingStore.end(); + iter != end; ++iter) { + NVDelete(m_Allocator, *iter); + } + + m_TimeEventBackingStore.clear(); + RemoveOverride(); + } + + void Reset() + { + for (TTimeEventList::iterator iter = m_TimeEvents.begin(), end = m_TimeEvents.end(); + iter != end; ++iter) + (*iter)->Reset(); + + m_TimeEvents.clear(); + m_TimeEventBackingStoreIndex = 0; + m_CurrentTime = -1; + m_DirtyList.clear(); + m_AllNodesDirty = true; + m_TimeDataNeedsUpdate = true; + } + + STimeEvent &GetTimeEventForTime(TTimeUnit inTime, STimeEvent::Type inType) + { + TTimeEventList::iterator inserter = m_TimeEvents.end(); + for (TTimeEventList::iterator iter = m_TimeEvents.begin(), end = m_TimeEvents.end(); + iter != end && inserter == end; ++iter) { + if ((*iter)->m_Time == inTime) { + if ((*iter)->m_Type == inType) + return **iter; + // Start comes before stop + if ((*iter)->m_Type == STimeEvent::Stop) + inserter = iter; + } + + if ((*iter)->m_Time > inTime) + inserter = iter; + } + + if (m_TimeEventBackingStoreIndex == m_TimeEventBackingStore.size()) + m_TimeEventBackingStore.push_back( + QT3DS_NEW(m_Allocator, STimeEvent)(inType, m_Allocator, inTime)); + + STimeEvent *newEvent = m_TimeEventBackingStore[m_TimeEventBackingStoreIndex]; + ++m_TimeEventBackingStoreIndex; + + newEvent->m_Time = inTime; + newEvent->m_Type = inType; + newEvent->m_AffectedNodes.clear(); + + if (inserter == m_TimeEvents.end()) + m_TimeEvents.push_back(newEvent); + else + m_TimeEvents.insert(inserter, newEvent); + + return *newEvent; + }; + + void UpdateNodeList(nvvector &inList, bool timeActive) + { + for (QT3DSU32 elemIdx = 0, endIdx = inList.size(); elemIdx < endIdx; ++elemIdx) { + SActivationManagerNode &theNode = inList[elemIdx]->m_ActivationManagerNode; + if (timeActive != theNode.m_Flags.IsTimeActive()) { + theNode.m_Flags.SetTimeActive(timeActive); + SetElementDirty(*inList[elemIdx]); + } + } + } + + // Returns true if we have reached the end time. + bool CalculateNewTime(TTimeUnit inGlobalTime) + { + Option theNewTime; + if (m_TimePolicyOverride) { + SComponentTimePolicyOverride *theOverride = m_TimePolicyOverride; + eastl::pair theEvalResult = + theOverride->ComputeLocalTime(m_TimePolicy, inGlobalTime); + if (theEvalResult.first && theOverride->m_TimeCallback) { + Mutex::ScopedLock __locker(m_ElementAccessMutex); + theOverride->m_TimeCallback->OnTimeFinished(); + theOverride->m_TimeCallback->Release(); + theOverride->m_TimeCallback = NULL; + } + return false; + } else { + Q3DStudio::BOOL theReachedEndTime = m_TimePolicy.ComputeTime(inGlobalTime); + if (theReachedEndTime) + return true; + + return false; + } + } + + // There are four conditions this happens: + // 1. This object is getting destroyed + // 2. A new override is being set. + // 3. The compoent switched slides. + // 4. The component was deactivated. + void RemoveOverride() + { + if (m_TimePolicyOverride) { + if (m_TimePolicyOverride->m_TimeCallback) { + Mutex::ScopedLock __locker(m_ElementAccessMutex); + m_TimePolicyOverride->m_TimeCallback->Release(); + m_TimePolicyOverride->m_TimeCallback = NULL; + } + + NVDelete(m_Allocator, m_TimePolicyOverride); + m_TimePolicyOverride = NULL; + } + } + + void UpdateLocalTime(TTimeUnit inNewTime, TScanBuffer &inScanBuffer, IActivityZone &inZone) + { + if (m_TimeDataNeedsUpdate) { + BuildTimeContext(inScanBuffer, inZone); + } + + TTimeUnit newTime = inNewTime; + if (newTime != m_CurrentTime) { + SComponent &myNode = m_Component; + { + Mutex::ScopedLock __locker(m_ElementAccessMutex); + myNode.SetDirty(); + } + STimeEvent searchEvent(STimeEvent::Start, m_Allocator, m_CurrentTime); + bool forward = newTime > m_CurrentTime; + m_CurrentTime = NVMax((TTimeUnit)0, newTime); + + if (forward) { + TTimeEventList::iterator iter = eastl::lower_bound( + m_TimeEvents.begin(), m_TimeEvents.end(), &searchEvent, STimeEventLessThan()); + + for (TTimeEventList::iterator end = m_TimeEvents.end(); + iter != end && (*iter)->m_Time <= newTime; ++iter) { + // Stop only works if the time is greater. + // start works if the time is equal. + bool isActive = true; + if ((*iter)->m_Type == STimeEvent::Stop) + isActive = newTime <= (*iter)->m_Time; + + UpdateNodeList((*iter)->m_AffectedNodes, isActive); + } + } else { + searchEvent.m_Type = STimeEvent::Stop; + TTimeEventList::reverse_iterator iter = + eastl::lower_bound(m_TimeEvents.rbegin(), m_TimeEvents.rend(), &searchEvent, + STimeEventGreaterThan()); + + for (TTimeEventList::reverse_iterator end = m_TimeEvents.rend(); + iter != end && (*iter)->m_Time >= newTime; ++iter) { + bool isActive = true; + if ((*iter)->m_Type == STimeEvent::Start) + isActive = newTime >= (*iter)->m_Time; + + UpdateNodeList((*iter)->m_AffectedNodes, isActive); + } + } + } + } + + void UpdateNodeElementInformation(SElement &inNode) + { + Q3DStudio::UVariant attValue; + if (inNode.GetAttribute(Q3DStudio::ATTRIBUTE_STARTTIME, attValue)) + inNode.m_ActivationManagerNode.m_StartTime = (QT3DSU32)attValue.m_INT32; + + if (inNode.GetAttribute(Q3DStudio::ATTRIBUTE_ENDTIME, attValue)) + inNode.m_ActivationManagerNode.m_StopTime = (QT3DSU32)attValue.m_INT32; + + inNode.m_ActivationManagerNode.m_Flags.SetTimeActive(false); + // Note that we don't set the script information here. The reason is that this requires the + // script list + // and we don't have access to it. Plus it can't change when a slide changes so it is kind + // of irrelevant. + } + + bool BuildTimeContextElementNode(SElement &inNode, QT3DSU32 inGlobalMin, QT3DSU32 inGlobalMax) + { + // Note that just because a node itself does not participate in the time graph, + // this does not mean that its children do not participate in the time graph. + if (inNode.DoesParticipateInTimeGraph()) { + UpdateNodeElementInformation(inNode); + if (inNode.IsUserActive()) { + inGlobalMin = NVMax(inNode.m_ActivationManagerNode.m_StartTime, inGlobalMin); + inGlobalMax = NVMin(inNode.m_ActivationManagerNode.m_StopTime, inGlobalMax); + if (inGlobalMin < inGlobalMax) { + GetTimeEventForTime(inGlobalMin, STimeEvent::Start) + .m_AffectedNodes.push_back(&inNode); + GetTimeEventForTime(inGlobalMax, STimeEvent::Stop) + .m_AffectedNodes.push_back(&inNode); + } + } + } else { + inNode.m_ActivationManagerNode.m_Flags.SetTimeActive(true); + // Carry global min/max information down so children get setup correctly. + inNode.m_ActivationManagerNode.m_StartTime = inGlobalMin; + inNode.m_ActivationManagerNode.m_StopTime = inGlobalMax; + } + // Is it worth looking at children at all + return inNode.IsUserActive(); + } + + void BuildTimeContext(TScanBuffer &inScanBuffer, IActivityZone &inZone) + { + Mutex::ScopedLock __locker(m_ElementAccessMutex); + QT3DS_ASSERT(m_TimeDataNeedsUpdate); + m_TimeDataNeedsUpdate = false; + SComponent &myNode = m_Component; + SElement *theChild = myNode.m_Child; + if (theChild == NULL) { + return; + } + inScanBuffer.clear(); + for (SElement *theChild = myNode.m_Child; theChild; theChild = theChild->m_Sibling) { + inScanBuffer.push_back(theChild); + } + for (QT3DSU32 idx = 0, end = (QT3DSU32)inScanBuffer.size(); idx < end; ++idx) { + SScanBufferEntry theEntry(inScanBuffer[idx]); + bool careAboutChildren = BuildTimeContextElementNode( + *theEntry.m_Node, theEntry.m_StartTime, theEntry.m_EndTime); + if (careAboutChildren && theEntry.m_Node->IsComponent() == false) { + for (SElement *theChild = theEntry.m_Node->m_Child; theChild; + theChild = theChild->m_Sibling) { + inScanBuffer.push_back(SScanBufferEntry( + theChild, theEntry.m_Node->m_ActivationManagerNode.m_StartTime, + theEntry.m_Node->m_ActivationManagerNode.m_StopTime)); + } + end = (QT3DSU32)inScanBuffer.size(); + } + if (theEntry.m_Node->IsComponent()) + inZone.AddActivityItems(*theEntry.m_Node); + } + } + + void SetElementDirty(SElement &inNode) + { + SElement *theComponentParent = &inNode.GetComponentParent(); + if (inNode.IsComponent() && inNode.m_Parent) + theComponentParent = &inNode.m_Parent->GetComponentParent(); + + QT3DS_ASSERT(theComponentParent == &m_Component); + if (m_AllNodesDirty == false) { + // We check independent items every frame anyway so it isn't worth setting them dirty + // here. + if (inNode.IsIndependent() == false) { + m_DirtyList.insert(inNode); + } + + // Dirty to root time context. This ensures that if we run an activate scan starting at + // a parent + // we won't have to re-run the scan at this node because it will not be dirty. + // This also makes sure that if we mark all nodes dirty we continue the activate scan + // till we hit at least + // this node. + SElement *theParent = inNode.m_Parent; + while (theParent) { + if (theParent->IsComponent() + || theParent->m_ActivationManagerNode.m_Flags.IsChildDirty()) + theParent = NULL; + else { + SActivationManagerNode &theNode = theParent->m_ActivationManagerNode; + theNode.m_Flags.SetChildDirty(); + theParent = theParent->m_Parent; + } + } + } + } + + static void UpdateItemScriptStatus(SElement &inNode, bool activeAndHasScript, + TElementAndSortKeyList &scriptBuffer) + { + QT3DSU32 theIndex = inNode.Depth(); + eastl::pair theInsertedItem(&inNode, theIndex); + if (activeAndHasScript) { + if (inNode.m_ActivationManagerNode.m_Flags.HasScript() == false) { + scriptBuffer.push_back(theInsertedItem); + inNode.m_ActivationManagerNode.m_Flags.SetHasScript(true); + } + } else { + if (inNode.m_ActivationManagerNode.m_Flags.HasScript() == true) { + TElementAndSortKeyList::iterator theFind = + eastl::find(scriptBuffer.begin(), scriptBuffer.end(), theInsertedItem); + if (theFind != scriptBuffer.end()) + scriptBuffer.erase(theFind); + inNode.m_ActivationManagerNode.m_Flags.SetHasScript(false); + } + } + } + + static void HandleActivationChange(SElement &inNode, TElementAndSortKeyList &activateBuffer, + TElementAndSortKeyList &deactivateBuffer, + TElementAndSortKeyList &scriptBuffer, + Mutex &inElementAccessMutex, bool &scriptBufferRequiresSort, + bool inIsActive) + { + Mutex::ScopedLock __locker(inElementAccessMutex); + TElementAndSortKey theKey(&inNode, inNode.Depth()); + if (inIsActive) { + activateBuffer.push_back(TElementAndSortKey(theKey)); + } else { + deactivateBuffer.push_back(theKey); + } + + if (inNode.Flags().HasScriptCallbacks()) { + UpdateItemScriptStatus(inNode, inIsActive, scriptBuffer); + scriptBufferRequiresSort = true; + } + inNode.SetGlobalActive(inIsActive); + } + + // Runs once we notice that the item's global active status has changed. + // Note we explicitly do not update independent items because those are updated + // as the first step of each time context update itself. + // We do, however, remove them from the dirty list here. + static void RunActivateScan(SElement &inNode, TScanBuffer &inScanBuffer, + TElementAndSortKeyList &activateBuffer, + TElementAndSortKeyList &deactivateBuffer, + TElementAndSortKeyList &scriptBuffer, Mutex &inElementAccessMutex, + bool &scriptBufferRequiresSort, bool inRunFullScan) + { + inScanBuffer.clear(); + + // Block used to hide variables to avoid an error. + { + bool parentActive = true; + SElement *theParent = inNode.m_Parent; + if (theParent != NULL) + parentActive = theParent->IsGlobalActive(); + + inScanBuffer.push_back(SScanBufferEntry(&inNode, parentActive)); + } + + for (QT3DSU32 idx = 0, end = inScanBuffer.size(); idx < end; ++idx) { + SScanBufferEntry theEntry(inScanBuffer[idx]); + SElement *theScanNode = theEntry.m_Node; + QT3DS_ASSERT(theScanNode->IsIndependent() == false); + bool parentActive = theEntry.IsParentActive(); + bool wasActive = theScanNode->IsGlobalActive(); + bool isActive = theScanNode->IsGlobalActive(parentActive); + bool wasChildDirty = theScanNode->m_ActivationManagerNode.m_Flags.IsChildDirty(); + theScanNode->m_ActivationManagerNode.m_Flags.ClearChildDirty(); + bool activateChange = isActive != wasActive; + bool checkChildren = activateChange || (isActive && (wasChildDirty || inRunFullScan)); + if (activateChange) { + HandleActivationChange(*theScanNode, activateBuffer, deactivateBuffer, scriptBuffer, + inElementAccessMutex, scriptBufferRequiresSort, isActive); + } + + if (checkChildren && theScanNode->m_Child) { + for (SElement *theScanNodeChild = theScanNode->m_Child; theScanNodeChild; + theScanNodeChild = theScanNodeChild->m_Sibling) { + if (theScanNodeChild->IsIndependent() == false) + inScanBuffer.push_back(SScanBufferEntry(theScanNodeChild, isActive)); + } + end = inScanBuffer.size(); + } + } + } + + void RunDirtyScan(TScanBuffer &inScanBuffer, TElementNodePtrList &inTempDirtyList, + TElementAndSortKeyList &activateBuffer, + TElementAndSortKeyList &deactivateBuffer, + TElementAndSortKeyList &scriptBuffer, bool &scriptBufferRequiresSort) + { + if (m_AllNodesDirty == true) { + inTempDirtyList.clear(); + SComponent &myNode = m_Component; + for (SElement *theChild = myNode.m_Child; theChild; theChild = theChild->m_Sibling) { + // Independent nodes don't need to be in the dirty list. + if (theChild->IsIndependent() == false) + inTempDirtyList.push_back(theChild); + } + } else { + inTempDirtyList.assign(m_DirtyList.begin(), m_DirtyList.end()); + // Reset nodes that are dirty to *not* be dirty. + m_DirtyList.clear(); + // We have to sort the dirty list because it may have nodes out of order and the active + // algorithm requires parents before children. We use the depth member variable to + // achieve this. + eastl::sort(inTempDirtyList.begin(), inTempDirtyList.end(), SElementPtrSort()); + } + for (QT3DSU32 idx = 0, end = (QT3DSU32)inTempDirtyList.size(); idx < end; ++idx) { + SElement &dirtyNode(*inTempDirtyList[idx]); + // This is slightly inefficient in the case where a both a child and parent are in the + // dirty list. + // This case has got to be extremely rare in practice, however. + RunActivateScan(dirtyNode, inScanBuffer, activateBuffer, deactivateBuffer, scriptBuffer, + m_ElementAccessMutex, scriptBufferRequiresSort, m_AllNodesDirty); + } + // Set at end so while debugging you can see if all nodes were dirty on method entry. + m_AllNodesDirty = false; + } + + bool Update(TTimeUnit inGlobalTime, TScanBuffer &inScanBuffer, + TElementNodePtrList &inTempDirtyList, TElementAndSortKeyList &activateBuffer, + TElementAndSortKeyList &deactivateBuffer, TElementAndSortKeyList &scriptBuffer, + bool &scriptBufferRequiresSort, Q3DStudio::CComponentManager &inComponentManager, + IPerfTimer &inPerfTimer, IActivityZone &inZone) + { + QT3DSU64 start = qt3ds::foundation::Time::getCurrentCounterValue(); + SComponent &theContextNode = m_Component; + bool parentActive = true; + SElement *theParent = theContextNode.m_Parent; + if (theParent != NULL) + parentActive = theParent->IsGlobalActive(); + + bool wasActive = theContextNode.IsGlobalActive(); + bool isActive = theContextNode.IsGlobalActive(parentActive); + bool activationChange = isActive != wasActive; + inPerfTimer.Update("ActivationManager - Update Initial Vars", + qt3ds::foundation::Time::getCurrentCounterValue() - start); + if (activationChange) { + SStackPerfTimer __timer(inPerfTimer, "ActivationManager - Activation Change"); + HandleActivationChange(theContextNode, activateBuffer, deactivateBuffer, scriptBuffer, + m_ElementAccessMutex, scriptBufferRequiresSort, isActive); + m_DirtyList.clear(); + m_AllNodesDirty = true; + if (isActive) { + Mutex::ScopedLock __locker(m_ElementAccessMutex); + inComponentManager.GotoSlideIndex(&theContextNode, 1, false); + } else + RemoveOverride(); + } + if (isActive) { + SStackPerfTimer __timer(inPerfTimer, "ActivationManager - Update Local Time"); + bool atEndOfTime = CalculateNewTime(inGlobalTime); + if (atEndOfTime) { + Mutex::ScopedLock __locker(m_ElementAccessMutex); + if (theContextNode.IsPlayThrough()) + inComponentManager.PlaythroughToSlide(&theContextNode); + } + // Note the slide may have changed here and thus updated our time policy. + // Set time active flags based on time. + UpdateLocalTime(m_TimePolicy.GetTime(), inScanBuffer, inZone); + } + if (isActive || activationChange) { + if (m_AllNodesDirty || m_DirtyList.size()) { + SStackPerfTimer __timer(inPerfTimer, "ActivationManager - Dirty Scan"); + RunDirtyScan(inScanBuffer, inTempDirtyList, activateBuffer, deactivateBuffer, + scriptBuffer, scriptBufferRequiresSort); + } + } + return isActive || activationChange; + } + + void GoToTime(TTimeUnit inTime) + { + if (m_TimePolicyOverride) { + m_TimePolicyOverride->SetTime(m_TimePolicy, inTime); + } else { + m_TimePolicy.SetTime(inTime); + } + } +}; + +IMPLEMENT_INVASIVE_SINGLE_LIST(TimeContext, m_NextSibling); + +struct SActivityZone : public IActivityZone +{ + typedef nvhash_map> TComponentTimeContextMap; + NVFoundationBase &m_Foundation; + Q3DStudio::CPresentation &m_Presentation; + IStringTable &m_StringTable; + nvvector m_RootElements; + TComponentTimeContextMap m_TimeContexts; + // These could potentially not be sorted but for 7.5 and TZ3 I don't want to risk the + // bugs assocated with not producing the exact same output as the original algorithm. + TElementAndSortKeyList m_ActivatedItems; + TElementAndSortKeyList m_DeactivatedItems; + + // This will always need to be sorted because it is maintained across update calls + TElementAndSortKeyList m_ScriptItems; + + // Temporaries used while scanning nodes for various features. + TScanBuffer m_ScanBuffer; + TElementNodePtrList m_TempDirtyList; + nvvector m_TimeContextScanBuffer; + + TTimeContextList m_RootContexts; + Mutex &m_ElementAccessMutex; + Mutex m_UpdateCheckMutex; + Sync m_UpdateSync; + TTimeUnit m_GlobalTime; + IPerfTimer *m_PerfTimer; + STypeDesc m_DummyTypeDesc; + SComponent m_DummyComponent; + STimeContext m_DummyContext; + bool m_Active; + // True if m_ScriptItems needs to be resorted. + bool m_ScriptRequiresSort; + bool m_Updating; + + QT3DSI32 mRefCount; + + SActivityZone(NVFoundationBase &inFnd, Q3DStudio::CPresentation &inPres, + IStringTable &inStrTable, Mutex &inElementAccessMutex) + : m_Foundation(inFnd) + , m_Presentation(inPres) + , m_StringTable(inStrTable) + , m_RootElements(inFnd.getAllocator(), "Elements") + , m_TimeContexts(inFnd.getAllocator(), "TimeContexts") + , m_ActivatedItems(inFnd.getAllocator(), "m_ActivatedItems") + , m_DeactivatedItems(inFnd.getAllocator(), "m_DeactivatedItems") + , m_ScriptItems(inFnd.getAllocator(), "m_ScriptItems") + , m_ScanBuffer(inFnd.getAllocator(), "m_ScanBuffer") + , m_TempDirtyList(inFnd.getAllocator(), "m_TempDirtyList") + , m_TimeContextScanBuffer(inFnd.getAllocator(), "m_TimeContextScanBuffer") + , m_ElementAccessMutex(inElementAccessMutex) + , m_UpdateCheckMutex(inFnd.getAllocator()) + , m_UpdateSync(inFnd.getAllocator()) + , m_GlobalTime(0) + , m_PerfTimer(NULL) + , m_DummyComponent(m_DummyTypeDesc) + , m_DummyContext(m_Foundation.getAllocator(), m_DummyComponent, m_ElementAccessMutex) + , m_Active(true) + , m_ScriptRequiresSort(true) + , m_Updating(false) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + Q3DStudio::CPresentation &GetPresentation() override { return m_Presentation; } + + static void SortElementBuffer(nvvector> &inBuffer) + { + eastl::sort(inBuffer.begin(), inBuffer.end(), SElementIndexPairSorter()); + } + + static void AddElementNodeToBuffer(nvvector> &inBuffer, + SElement &inNode) + { + eastl::pair insertItem(&inNode, inNode.Depth()); + QT3DS_ASSERT(eastl::find(inBuffer.begin(), inBuffer.end(), insertItem) == inBuffer.end()); + inBuffer.push_back(insertItem); + } + + TActivityItemBuffer GetActivatedItems() override { return m_ActivatedItems; } + + TActivityItemBuffer GetDeactivatedItems() override { return m_DeactivatedItems; } + // All active items that are script enabled. + TActivityItemBuffer GetScriptItems() override + { + // Created in a delayed way. + if (m_ScriptRequiresSort) { + m_ScriptRequiresSort = false; + SortElementBuffer(m_ScriptItems); + } + return m_ScriptItems; + } + + void SetZoneActive(bool inActive) override { m_Active = inActive; } + bool IsZoneActive() override { return m_Active; } + + SActivationManagerNode *GetElementNodeForElement(TActivityItem item) + { + return &item.m_ActivationManagerNode; + } + + STimeContext &GetItemTimeContext(SElement &inNode) + { + SElement &theComponent = inNode.GetComponentParent(); + if (!theComponent.IsComponent()) { + QT3DS_ASSERT(false); + return m_DummyContext; + } + + eastl::pair inserter = m_TimeContexts.insert( + eastl::make_pair(&theComponent, NVScopedRefCounted())); + if (inserter.second) { + inserter.first->second = QT3DS_NEW(m_Foundation.getAllocator(), STimeContext)( + m_Foundation.getAllocator(), static_cast(theComponent), + m_ElementAccessMutex); + STimeContext &theNewContext = *inserter.first->second; + if (theComponent.m_Parent == NULL) + m_RootContexts.push_back(theNewContext); + else { + STimeContext &parentContext = GetItemTimeContext(*theComponent.m_Parent); + parentContext.m_Children.push_back(theNewContext); + } + } + return *inserter.first->second.mPtr; + } + + void AddActivityItems(TActivityItem inNode) override + { + if (inNode.m_Parent == NULL) + m_RootElements.push_back(&inNode); + + GetItemTimeContext(inNode); + } + + CTimePolicy *GetOwnedTimePolicy(TActivityItem item) override + { + return &GetItemTimeContext(item).m_TimePolicy; + } + + virtual SComponentTimePolicyOverride * + GetOrCreateItemComponentOverride(TActivityItem item, float inMultiplier, TTimeUnit inEndTime, + IComponentTimeOverrideFinishedCallback *inCallback) override + { + STimeContext &theContext = GetItemTimeContext(item); + + theContext.RemoveOverride(); + theContext.m_TimePolicyOverride = + QT3DS_NEW(m_Foundation.getAllocator(), + SComponentTimePolicyOverride)(&item, inMultiplier, inEndTime, inCallback); + theContext.m_TimePolicy.SetPaused(false); + + return theContext.m_TimePolicyOverride; + } + + // If I am independent, then I am my own time parent. + // else travel up the chain till you find an indpendent node. + SElement &GetItemTimeParentNode(SElement &inNode) + { + if (inNode.m_Parent != NULL) { + SElement &theParent = *inNode.m_Parent; + if (theParent.IsIndependent()) + return theParent; + return GetItemTimeParentNode(theParent); + } + // All roots are time independent by definition. + return inNode; + } + + TActivityItemPtr GetItemTimeParent(SElement &inNode) override + { + return &GetItemTimeParentNode(inNode); + } + + void InsertIntoAppropriateDirtyList(SElement &inNode) + { + // This may need to be faster at some point... + GetItemTimeContext(inNode).SetElementDirty(inNode); + } + + bool GetItemUserActive(TActivityItem item) override { return item.IsExplicitActive(); } + + void UpdateItemScriptStatus(TActivityItem item) override + { + if (item.IsGlobalActive()) { + STimeContext::UpdateItemScriptStatus(item, item.Flags().HasScriptCallbacks(), + m_ScriptItems); + m_ScriptRequiresSort = true; + } + } + + void UpdateItemInfo(TActivityItem item) override { GetItemTimeContext(item).Reset(); } + + // Order of events will be: + // 1. On Slide Change + // 2. Time Update + // 3. On Slide Change + // 4. Update Local Time + void OnSlideChange(TActivityItem item) override + { + STimeContext &theContext = GetItemTimeContext(item); + // Rebuilding the context sets all the elements dirty. + // This takes care of everything *but* the script item changes. + theContext.Reset(); + theContext.RemoveOverride(); + } + + bool GetItemTimeActive(TActivityItem item) override + { + SActivationManagerNode *theNode = GetElementNodeForElement(item); + if (theNode) + return theNode->m_Flags.IsTimeActive(); + return false; + } + + TTimeUnit GetItemLocalTime(TActivityItem item) override + { + SElement *theElem = &item.GetComponentParent(); + if (item.IsComponent() && item.m_Parent) + theElem = &item.m_Parent->GetComponentParent(); + + return GetItemTimeContext(*theElem).m_CurrentTime; + } + + TTimeUnit GetItemComponentTime(TActivityItem item) override + { + return GetItemTimeContext(item).m_CurrentTime; + } + + bool IsUpdating() override + { + Mutex::ScopedLock __locker(m_UpdateCheckMutex); + return m_Updating; + } + + void EndUpdate() override + { + m_UpdateSync.reset(); + while (IsUpdating()) + m_UpdateSync.wait(); + } + + void DoUpdate() + { + SStackPerfTimer __timer(m_PerfTimer, "ActivationManager - DoUpdate"); + if (m_Active) { + // We know that parent elements are added before children. + // So we know the time contexts are in an appropriate order, assuming they completely + // resolve their results before the next time context runs. + Q3DStudio::CComponentManager &theManager = + static_cast(m_Presentation.GetComponentManager()); + m_TimeContextScanBuffer.clear(); + + for (TTimeContextList::iterator iter = m_RootContexts.begin(), + end = m_RootContexts.end(); + iter != end; ++iter) + m_TimeContextScanBuffer.push_back(&(*iter)); + + for (QT3DSU32 idx = 0, end = m_TimeContextScanBuffer.size(); idx < end; ++idx) { + STimeContext &theContext = *m_TimeContextScanBuffer[idx]; + bool checkChildren = + theContext.Update(m_GlobalTime, m_ScanBuffer, m_TempDirtyList, m_ActivatedItems, + m_DeactivatedItems, m_ScriptItems, m_ScriptRequiresSort, + theManager, *m_PerfTimer, *this); + if (checkChildren) { + for (TTimeContextList::iterator timeIter = theContext.m_Children.begin(), + timeEnd = theContext.m_Children.end(); + timeIter != timeEnd; ++timeIter) { + m_TimeContextScanBuffer.push_back(&(*timeIter)); + } + end = m_TimeContextScanBuffer.size(); + } + } + } + + eastl::sort(m_ActivatedItems.begin(), m_ActivatedItems.end(), SElementIndexPairSorter()); + eastl::sort(m_DeactivatedItems.begin(), m_DeactivatedItems.end(), + SElementIndexPairSorter()); + Mutex::ScopedLock __locker(m_UpdateCheckMutex); + { + m_Updating = false; + m_UpdateSync.set(); + } + } + + static void UpdateCallback(void *data) + { + SActivityZone *theZone = reinterpret_cast(data); + theZone->DoUpdate(); + } + + void BeginUpdate(TTimeUnit inGlobalTime, IPerfTimer &inPerfTimer, + IThreadPool &inThreadPool) override + { + // It is expected that an update is not running. + m_ActivatedItems.clear(); + m_DeactivatedItems.clear(); + m_GlobalTime = inGlobalTime; + m_PerfTimer = &inPerfTimer; + m_Updating = true; + inThreadPool.AddTask(this, UpdateCallback, NULL); + } + + void GoToTime(TActivityItem inItem, TTimeUnit inTime) override + { + GetItemTimeContext(inItem).GoToTime(inTime); + } +}; + +struct SActivityZoneManager : public IActivityZoneManager +{ + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + // Zones may access the element mutex on destruction *so* it is important that + // it is destroyed *after* the zone list. + Mutex m_ElementAccessMutex; + nvvector> m_Zones; + QT3DSI32 mRefCount; + + SActivityZoneManager(NVFoundationBase &fnd, IStringTable &inStrTable) + : m_Foundation(fnd) + , m_StringTable(inStrTable) + , m_ElementAccessMutex(m_Foundation.getAllocator()) + , m_Zones(m_Foundation.getAllocator(), "m_Zones") + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + IActivityZone &CreateActivityZone(Q3DStudio::CPresentation &inPresentation) override + { + m_Zones.push_back(QT3DS_NEW(m_Foundation.getAllocator(), SActivityZone)( + m_Foundation, inPresentation, m_StringTable, m_ElementAccessMutex)); + return *m_Zones.back().mPtr; + } +}; +} + +IActivityZoneManager & +IActivityZoneManager::CreateActivityZoneManager(NVFoundationBase &inFoundation, + IStringTable &inStrTable) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SActivityZoneManager)(inFoundation, inStrTable); +} diff --git a/src/Runtime/Source/runtime/Qt3DSActivationManager.h b/src/Runtime/Source/runtime/Qt3DSActivationManager.h new file mode 100644 index 00000000..f343ac9b --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSActivationManager.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_ACTIVATION_MANAGER_H +#define QT3DS_ACTIVATION_MANAGER_H +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Utils.h" +#include "Qt3DSKernelTypes.h" +#include "Qt3DSMetadata.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSTimePolicy.h" + +namespace Q3DStudio { +struct IComponentTimeOverrideFinishedCallback; +struct SComponentTimePolicyOverride; +class CPresentation; +} + +namespace qt3ds { +namespace foundation { + class IPerfTimer; +} +} + +namespace qt3ds { +namespace render { + class IThreadPool; +} +} + +namespace qt3ds { +namespace runtime { + using namespace qt3ds::foundation; + using namespace qt3ds; + using Q3DStudio::CTimePolicy; + using Q3DStudio::SComponentTimePolicyOverride; + using Q3DStudio::IComponentTimeOverrideFinishedCallback; + using Q3DStudio::CPresentation; + using Q3DStudio::TTimeUnit; + using qt3ds::render::IThreadPool; + + class IActivationManager; + + typedef element::SElement &TActivityItem; + typedef element::SElement *TActivityItemPtr; + + typedef eastl::pair TElementAndSortKey; + + typedef NVConstDataRef TActivityItemBuffer; + + // Items can have user active and time active. Time active is controlled by this object + // but user active can be set. An item is only active if it both actives are true. + // Inactive items have completely inactive children. + class IActivityZone + { + protected: + virtual ~IActivityZone() {} + public: + virtual Q3DStudio::CPresentation &GetPresentation() = 0; + + // Items activated this cycle + virtual TActivityItemBuffer GetActivatedItems() = 0; + // Items deactivated this cycle + virtual TActivityItemBuffer GetDeactivatedItems() = 0; + // All active items that are script enabled. + virtual TActivityItemBuffer GetScriptItems() = 0; + + // Inactive zones don't update their item lists when the manager updates. + virtual void SetZoneActive(bool inActive) = 0; + virtual bool IsZoneActive() = 0; + + virtual void AddActivityItems(TActivityItem root) = 0; + + // Get the time policy that is owned by this element. + virtual CTimePolicy *GetOwnedTimePolicy(TActivityItem item) = 0; + // Get the local time for this element. This is the time the animation system should see + virtual TTimeUnit GetItemLocalTime(TActivityItem item) = 0; + // Get the local time if this isn't independent, else get the time context time for the + // component. + virtual TTimeUnit GetItemComponentTime(TActivityItem item) = 0; + + virtual SComponentTimePolicyOverride * + GetOrCreateItemComponentOverride(TActivityItem item, float inMultiplier, + TTimeUnit inEndTime, + IComponentTimeOverrideFinishedCallback *inCallback) = 0; + + // If this item is independent, return this item. + // else get time parent of my parent. + virtual TActivityItemPtr GetItemTimeParent(TActivityItem item) = 0; + + bool IsIndependent(TActivityItem item) { return GetOwnedTimePolicy(item) != NULL; } + + // Any time the item has script flag changes after its initial creation. + // Note that this flag cannot change due to slide changes, it can only change due + // to something that had a script error and thus is disabled. + virtual void UpdateItemScriptStatus(TActivityItem item) = 0; + + // If the start, end, or explicit active flags change *outside* of a slide change. + virtual void UpdateItemInfo(TActivityItem item) = 0; + virtual bool GetItemUserActive(TActivityItem item) = 0; + + // Callback when the slide changes, the time context needs to be rebuilt in this case. + virtual void OnSlideChange(TActivityItem item) = 0; + + virtual bool GetItemTimeActive(TActivityItem item) = 0; + + virtual void BeginUpdate(QT3DSI64 inGlobalTime, IPerfTimer &inPerfTimer, + IThreadPool &inThreadPool) = 0; + virtual bool IsUpdating() = 0; + virtual void EndUpdate() = 0; + + virtual void GoToTime(TActivityItem item, TTimeUnit inTime) = 0; + }; + + class IActivityZoneManager : public NVRefCounted + { + protected: + virtual ~IActivityZoneManager() {} + public: + virtual IActivityZone &CreateActivityZone(Q3DStudio::CPresentation &inPresentation) = 0; + + static IActivityZoneManager &CreateActivityZoneManager(NVFoundationBase &inFoundation, + IStringTable &inStrTable); + }; +} +} +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSAnimationSystem.cpp b/src/Runtime/Source/runtime/Qt3DSAnimationSystem.cpp new file mode 100644 index 00000000..84d1c6db --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSAnimationSystem.cpp @@ -0,0 +1,432 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "RuntimePrefix.h" +#include "Qt3DSTypes.h" +#include "Qt3DSAnimationSystem.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSInvasiveSet.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSPool.h" +#include "Qt3DSElementSystem.h" +#include "Qt3DSCubicRoots.h" +#include "Qt3DSBezierEval.h" +#include "foundation/SerializationTypes.h" +#include "foundation/IOStreams.h" +#include "EASTL/sort.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSIndexableLinkedList.h" + +using namespace qt3ds::runtime; +using namespace qt3ds::runtime::element; + +namespace { + +struct SAnimationKey +{ + QT3DSF32 m_Time; ///< Time + QT3DSF32 m_Value; ///< Value + QT3DSF32 m_C1Time; ///< Control 1 time + QT3DSF32 m_C1Value; ///< Control 1 value + QT3DSF32 m_C2Time; ///< Control 2 time + QT3DSF32 m_C2Value; ///< Control 2 value + SAnimationKey() + : m_Time(0) + , m_Value(0) + , m_C1Time(0) + , m_C1Value(0) + , m_C2Time(0) + , m_C2Value(0) + { + } + + SAnimationKey(float time, float val, float c1time, float c1value, float c2time, float c2value) + : m_Time(time) + , m_Value(val) + , m_C1Time(c1time) + , m_C1Value(c1value) + , m_C2Time(c2time) + , m_C2Value(c2value) + { + } +}; + +struct SAnimationKeyNode +{ + enum { + AnimationKeyArraySize = 4, + }; + + SAnimationKey m_Data[AnimationKeyArraySize]; + SAnimationKeyNode *m_NextNode; + SAnimationKeyNode() + : m_NextNode(NULL) + { + } +}; + +typedef IndexableLinkedList + TAnimationKeyNodeList; + +struct SAnimationTrack +{ + SElement *m_Element; + QT3DSI32 m_Id; + QT3DSU32 m_PropertyIndex; + QT3DSU32 m_KeyCount; + SAnimationKeyNode *m_Keys; + QT3DSU32 m_ActiveSetIndex; + bool m_Dynamic; + + SAnimationTrack() + : m_Element(NULL) + , m_Id(0) + , m_PropertyIndex(0) + , m_KeyCount(0) + , m_Keys(NULL) + , m_ActiveSetIndex(QT3DS_MAX_U32) + , m_Dynamic(false) + { + } + SAnimationTrack(SElement &inElement, QT3DSI32 inId, QT3DSU32 inPropertyIndex, bool inIsDynamic) + : m_Element(&inElement) + , m_Id(inId) + , m_PropertyIndex(inPropertyIndex) + , m_KeyCount(0) + , m_Keys(NULL) + , m_ActiveSetIndex(QT3DS_MAX_U32) + , m_Dynamic(inIsDynamic) + { + } +}; + +struct GetAnimationTrackActiveSetIndex +{ + QT3DSU32 operator()(const SAnimationTrack &inTrack) const { return inTrack.m_ActiveSetIndex; } +}; + +struct SetAnimationTrackActiveSetIndex +{ + void operator()(SAnimationTrack &inTrack, QT3DSU32 inIdx) { inTrack.m_ActiveSetIndex = inIdx; } +}; + +typedef InvasiveSet + TAnimationTrackActiveSet; + +struct SAnimationTrackComparator +{ + bool operator()(SAnimationTrack *lhs, SAnimationTrack *rhs) const + { + return lhs->m_Id < rhs->m_Id; + } +}; + +struct SAnimSystem : public IAnimationSystem +{ + typedef nvhash_map TAnimationTrackHash; + + NVFoundationBase &m_Foundation; + Pool m_AnimationTrackPool; + Pool m_AnimationKeyNodePool; + TAnimationTrackHash m_Tracks; + SAnimationTrack *m_LastInsertedTrack; + TAnimationTrackActiveSet m_ActiveSet; + NVDataRef m_LoadData; + QT3DSI32 m_NextTrackId; + QT3DSI32 m_RefCount; + + SAnimSystem(NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , m_AnimationTrackPool( + ForwardingAllocator(inFoundation.getAllocator(), "AnimationTrackPool")) + , m_AnimationKeyNodePool( + ForwardingAllocator(inFoundation.getAllocator(), "AnimationKeyNodePool")) + , m_Tracks(inFoundation.getAllocator(), "m_Tracks") + , m_LastInsertedTrack(NULL) + , m_ActiveSet(inFoundation.getAllocator(), "m_ActiveSet") + , m_NextTrackId(1) + , m_RefCount(0) + { + } + + static QT3DSI32 IncrementTrackId(QT3DSI32 inTrackId) + { + ++inTrackId; + if (!inTrackId) + ++inTrackId; + return inTrackId; + } + + void addRef() override { atomicIncrement(&m_RefCount); } + + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc = m_Foundation.getAllocator(); + NVDelete(alloc, this); + } + } + + QT3DSI32 CreateAnimationTrack(element::SElement &inElement, QT3DSU32 inPropertyName, + bool inDynamic) override + { + // first, make sure we can find the property. + Option theIndex = inElement.FindPropertyIndex(inPropertyName); + Option theProperty; + if (theIndex.hasValue()) + theProperty = inElement.GetPropertyByIndex(*theIndex); + + if (theProperty.hasValue() == false + || theProperty->first.m_Type != Q3DStudio::ATTRIBUTETYPE_FLOAT) { + QT3DS_ASSERT(false); + return 0; + } + + eastl::pair inserter; + // Find unused track id. + for (inserter = m_Tracks.insert(eastl::make_pair(m_NextTrackId, (SAnimationTrack *)NULL)); + inserter.second == false; m_NextTrackId = IncrementTrackId(m_NextTrackId)) { + } + + SAnimationTrack *theNewTrack = + reinterpret_cast(m_AnimationTrackPool.allocate(__FILE__, __LINE__)); + new (theNewTrack) SAnimationTrack(inElement, inserter.first->first, *theIndex, inDynamic); + inserter.first->second = theNewTrack; + m_LastInsertedTrack = theNewTrack; + ++m_NextTrackId; + return inserter.first->first; + } + + SAnimationKey *GetKeyByIndex(QT3DSU32 inIndex, SAnimationTrack &inTrack) + { + if (inIndex >= inTrack.m_KeyCount) + return 0; + + return &TAnimationKeyNodeList::GetObjAtIdx(inTrack.m_Keys, inIndex); + } + + SAnimationKey &GetOrCreateKeyByIndex(QT3DSU32 inIndex, SAnimationTrack &inTrack) + { + if (inIndex < inTrack.m_KeyCount) + return *GetKeyByIndex(inIndex, inTrack); + + return TAnimationKeyNodeList::Create(inTrack.m_Keys, inTrack.m_KeyCount, + m_AnimationKeyNodePool); + } + + void AddKey(QT3DSF32 inTime, QT3DSF32 inValue, QT3DSF32 inC1Time, QT3DSF32 inC1Value, + QT3DSF32 inC2Time, QT3DSF32 inC2Value) override + { + if (m_LastInsertedTrack == NULL) { + QT3DS_ASSERT(false); + return; + } + SAnimationKey &theNewKey = + GetOrCreateKeyByIndex(m_LastInsertedTrack->m_KeyCount, *m_LastInsertedTrack); + theNewKey = SAnimationKey(inTime, inValue, inC1Time, inC1Value, inC2Time, inC2Value); + } + + SAnimationTrack *GetAnimationTrack(QT3DSI32 inTrackId) + { + TAnimationTrackHash::iterator iter = m_Tracks.find(inTrackId); + if (iter != m_Tracks.end()) + return iter->second; + return NULL; + } + + struct SNextKeyRetVal + { + SAnimationKeyNode *m_Node; + SAnimationKey *m_Start; + SAnimationKey *m_End; + + SNextKeyRetVal(SAnimationKeyNode &inNode) + : m_Node(&inNode) + , m_Start(NULL) + , m_End(NULL) + { + } + SNextKeyRetVal(SAnimationKeyNode &inNode, SAnimationKey &inLastKey) + : m_Node(&inNode) + , m_Start(NULL) + , m_End(&inLastKey) + { + } + SNextKeyRetVal(SAnimationKeyNode &inNode, SAnimationKey &inStart, SAnimationKey &inLastKey) + : m_Node(&inNode) + , m_Start(&inStart) + , m_End(&inLastKey) + { + } + SNextKeyRetVal() + : m_Node(NULL) + , m_Start(NULL) + , m_End(NULL) + { + } + }; + + SNextKeyRetVal NextKeyIsGreaterThan(TAnimationKeyNodeList::iterator iter, QT3DSF32 inTime) + { + SAnimationKey *theStartKey = &(*iter); + QT3DSU32 nextIdx = iter.m_Idx + 1; + if (nextIdx == iter.m_Count) + return SNextKeyRetVal(*iter.m_Node, *theStartKey); + + TAnimationKeyNodeList::iterator next = iter; + ++next; + + SAnimationKey &nextKey = *next; + + if (nextKey.m_Time >= inTime) + return SNextKeyRetVal(*iter.m_Node, *theStartKey, nextKey); + return SNextKeyRetVal(*iter.m_Node); + } + + QT3DSF32 Evaluate(SAnimationTrack &inTrack, QT3DSF32 inTime) + { + if (inTrack.m_KeyCount < 2) { + if (inTrack.m_KeyCount == 1) + return GetKeyByIndex(0, inTrack)->m_Value; + return 0.0f; + } + + TAnimationKeyNodeList::iterator iter = + TAnimationKeyNodeList::begin(inTrack.m_Keys, inTrack.m_KeyCount); + + if ((*iter).m_Time >= inTime) { + return (*iter).m_Value; + } + + // We know it isn't the first key. + SNextKeyRetVal theKeyData; + for (theKeyData = NextKeyIsGreaterThan(iter, inTime); theKeyData.m_End == NULL; + ++iter, theKeyData = NextKeyIsGreaterThan(iter, inTime)) { + } + + if (theKeyData.m_Node == NULL && theKeyData.m_End == NULL) { + QT3DS_ASSERT(false); + return 0.0f; + } + + if (theKeyData.m_Start != NULL) { + SAnimationKey &start(*theKeyData.m_Start); + SAnimationKey &end(*theKeyData.m_End); + return Q3DStudio::EvaluateBezierKeyframe( + inTime, start.m_Time, start.m_Value, start.m_C1Time, start.m_C1Value, + start.m_C2Time, start.m_C2Value, end.m_Time, end.m_Value); + } + return theKeyData.m_End->m_Value; + } + + void Update() override + { + for (QT3DSU32 idx = 0, end = m_ActiveSet.size(); idx < end; ++idx) { + SAnimationTrack &theTrack = *m_ActiveSet[idx]; + SElement &theElement = *theTrack.m_Element; + QT3DSF32 theTime = static_cast(theElement.GetOuterTime()); + TPropertyDescAndValuePtr theProperty = + *theElement.GetPropertyByIndex(theTrack.m_PropertyIndex); + Q3DStudio::UVariant &theValue(*theProperty.second); + QT3DSF32 newValue = Evaluate(theTrack, theTime); + if (fabs(theValue.m_FLOAT - newValue) > SElement::SmallestDifference()) { + theValue.m_FLOAT = newValue; + theElement.SetDirty(); + } + } + } + + void SetActive(QT3DSI32 inTrackId, bool inActive) override + { + SAnimationTrack *theTrack = GetAnimationTrack(inTrackId); + if (theTrack) { + if (inActive) + m_ActiveSet.insert(*theTrack); + else + m_ActiveSet.remove(*theTrack); + } + } + //============================================================================== + /** + * Recomputes control point values for Studio animation based off of new start + * value. + * @param inNewStartValue new start value for the keyframe + * @param inKeyStart start index of the keyframes + */ + void RecomputeControlPoints(QT3DSF32 inNewStartValue, SAnimationTrack &inTrack) + { + SAnimationKey &theFirstKey = *GetKeyByIndex(0, inTrack); + SAnimationKey &theSecondKey = *GetKeyByIndex(1, inTrack); + + // Determine original control point ratios + Q3DStudio::FLOAT theOriginalInterval = + (theSecondKey.m_Value - theFirstKey.m_Value) * (1.0f / 3.0f); + Q3DStudio::FLOAT theEaseOutRatio = theOriginalInterval != 0.0f + ? (theFirstKey.m_C1Value - theFirstKey.m_Value) / theOriginalInterval + : 0.0f; + Q3DStudio::FLOAT theEaseInRatio = theOriginalInterval != 0.0f + ? (theSecondKey.m_Value - theFirstKey.m_C2Value) / theOriginalInterval + : 0.0f; + + // Apply ratios based off new start value + Q3DStudio::FLOAT theNewInterval = (theSecondKey.m_Value - inNewStartValue) * (1.0f / 3.0f); + theFirstKey.m_C1Value = inNewStartValue + (theNewInterval * theEaseOutRatio); + theFirstKey.m_C2Value = theSecondKey.m_Value - (theNewInterval * theEaseInRatio); + } + + void UpdateDynamicKey(QT3DSI32 inTrackId) override + { + SAnimationTrack *theTrack = GetAnimationTrack(inTrackId); + if (theTrack && theTrack->m_Dynamic) { + SAnimationKey *theFirstKey = GetKeyByIndex(0, *theTrack); + if (theFirstKey) { + Q3DStudio::UVariant *thePropData = + theTrack->m_Element->GetPropertyByIndex(theTrack->m_PropertyIndex)->second; + + // Recompute interpolation + if (theTrack->m_KeyCount > 1) + RecomputeControlPoints(thePropData->m_FLOAT, *theTrack); + + // Update start value + theFirstKey->m_Value = thePropData->m_FLOAT; + } + } + } +}; +} + +IAnimationSystem &IAnimationSystem::CreateAnimationSystem(NVFoundationBase &inFoundation) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SAnimSystem)(inFoundation); +} diff --git a/src/Runtime/Source/runtime/Qt3DSAnimationSystem.h b/src/Runtime/Source/runtime/Qt3DSAnimationSystem.h new file mode 100644 index 00000000..24542ad9 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSAnimationSystem.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_ANIMATION_SYSTEM_H +#define QT3DS_ANIMATION_SYSTEM_H +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSRefCounted.h" + +#pragma once +namespace qt3ds { +namespace foundation { + class IOutStream; +} +} + +namespace qt3ds { +namespace runtime { + using namespace qt3ds; + using namespace qt3ds::foundation; + + namespace element { + struct SElement; + } + class IElementAllocator; + + class IAnimationSystem : public NVRefCounted + { + public: + virtual QT3DSI32 CreateAnimationTrack(element::SElement &inElement, QT3DSU32 inPropertyName, + bool inDynamic) = 0; + virtual void AddKey(QT3DSF32 inTime, QT3DSF32 inValue, QT3DSF32 inC1Time, QT3DSF32 inC1Value, + QT3DSF32 inC2Time, QT3DSF32 inC2Value) = 0; + virtual void Update() = 0; + virtual void SetActive(QT3DSI32 inTrackId, bool inActive) = 0; + virtual void UpdateDynamicKey(QT3DSI32 inTrackId) = 0; + + static IAnimationSystem &CreateAnimationSystem(NVFoundationBase &inFoundation); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSApplication.cpp b/src/Runtime/Source/runtime/Qt3DSApplication.cpp new file mode 100644 index 00000000..249070c2 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSApplication.cpp @@ -0,0 +1,1831 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// We need a Qt header first here because Qt's metatype system insists that Bool +// can not be defined first before Qt headers are included and the includes below +// define Bool by way of Xll/XLib.h via khronos -> egl -> X11 +#include + +#include "RuntimePrefix.h" +#include "Qt3DSApplication.h" +#include "Qt3DSApplicationValues.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSMemory.h" +#include "Qt3DSRuntimeFactory.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/FileTools.h" +#include "Qt3DSIScriptBridge.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/XML.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSContainers.h" +#include "EASTL/hash_map.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSInputEventTypes.h" +#include "Qt3DSSceneManager.h" +#include "Qt3DSIScene.h" +#include "Qt3DSInputEngine.h" +#include "Qt3DSStateVisualBindingContext.h" +#include "Qt3DSMetadata.h" +#include "Qt3DSUIPParser.h" +#include "foundation/Socket.h" +#include "Qt3DSStateDebugStreams.h" +#include "Qt3DSSceneGraphDebugger.h" +#include "Qt3DSSceneGraphDebuggerValue.h" +#include "EventPollingSystem.h" +#include "Qt3DSRenderContextCore.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/SerializationTypes.h" +#include "EASTL/sort.h" +#include "Qt3DSRenderBufferLoader.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSync.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderThreadPool.h" +#include "foundation/StringConversionImpl.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSActivationManager.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSAudioPlayer.h" +#include "Qt3DSElementSystem.h" +#include +#include +#include +#include "q3dsvariantconfig_p.h" + +using namespace qt3ds; +using namespace qt3ds::runtime; +using namespace Q3DStudio; +using qt3ds::state::debugger::ISceneGraphRuntimeDebugger; +using qt3ds::state::debugger::SSGPropertyChange; + +namespace qt3ds { +namespace foundation { +template <> +struct StringConversion +{ + void StrTo(const char8_t *buffer, QT3DSVec2 &item) + { + char *endPtr = NULL; + item.x = (float)strtod(buffer, &endPtr); + if (endPtr) + item.y = (float)strtod(endPtr, NULL); + } +}; +} +} + +namespace { +struct SDebugSettings +{ + eastl::string m_Server; + int m_Port; + bool m_Listen; + SDebugSettings() + : m_Port(0) + , m_Listen(false) + { + } +}; + +struct SFrameTimer +{ + int m_FrameCount; + QT3DSU64 m_FrameTime; + SFrameTimer(QT3DSU64 fc = 0) + : m_FrameCount(fc) + , m_FrameTime(qt3ds::foundation::Time::getCurrentCounterValue()) + { + } + + QT3DSF32 GetElapsedSeconds(QT3DSU64 currentTime) const + { + QT3DSU64 diff = currentTime - m_FrameTime; + QT3DSF32 diffNanos + = static_cast(qt3ds::foundation::Time::sCounterFreq.toTensOfNanos(diff)); + return diffNanos / qt3ds::foundation::Time::sNumTensOfNanoSecondsInASecond; + } + + QT3DSF32 GetElapsedSeconds() const + { + return GetElapsedSeconds(qt3ds::foundation::Time::getCurrentCounterValue()); + } + + QPair GetFPS(int updateFC) + { + int elapsedFrames = updateFC - m_FrameCount; + QT3DSU64 currentTime = qt3ds::foundation::Time::getCurrentCounterValue(); + QT3DSF32 elapsedSeconds = GetElapsedSeconds(currentTime); + QT3DSF32 retval = elapsedFrames / elapsedSeconds; + m_FrameCount = updateFC; + m_FrameTime = currentTime; + return qMakePair(retval, elapsedFrames); + } +}; + +struct SRefCountedAssetValue : public SAssetValue +{ + NVFoundationBase &m_Foundation; + QT3DSI32 mRefCount; + SRefCountedAssetValue(NVFoundationBase &fnd) + : SAssetValue() + , m_Foundation(fnd) + , mRefCount(0) + { + } + + SRefCountedAssetValue(NVFoundationBase &fnd, const SAssetValue &asset) + : SAssetValue(asset) + , m_Foundation(fnd) + , mRefCount(0) + { + } + + SRefCountedAssetValue(NVFoundationBase &fnd, const SPresentationAsset &asset) + : SAssetValue(asset) + , m_Foundation(fnd) + , mRefCount(0) + { + } + + SRefCountedAssetValue(NVFoundationBase &fnd, const SBehaviorAsset &asset) + : SAssetValue(asset) + , m_Foundation(fnd) + , mRefCount(0) + { + } + + SRefCountedAssetValue(NVFoundationBase &fnd, const SRenderPluginAsset &asset) + : SAssetValue(asset) + , m_Foundation(fnd) + , mRefCount(0) + { + } + + SRefCountedAssetValue(NVFoundationBase &fnd, const SSCXMLAsset &asset) + : SAssetValue(asset) + , m_Foundation(fnd) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) +}; + +typedef nvhash_map> TIdAssetMap; +typedef nvhash_map THashStrMap; +typedef nvvector>> +TIdAssetList; +typedef eastl::pair THandleElementPair; +typedef NVConstDataRef THandleElementDataBuffer; +typedef nvvector THandleElementDataBufferList; +typedef nvhash_map THandleElementMap; + +struct SHandleElementPairComparator +{ + bool operator()(const THandleElementPair &lhs, const THandleElementPair &rhs) const + { + return lhs.first < rhs.first; + } +}; + +struct SApp; + +class IAppLoadContext : public NVRefCounted +{ +public: + virtual void EndLoad() = 0; + virtual bool OnGraphicsInitialized(IRuntimeFactory &inFactory) = 0; + virtual bool HasCompletedLoading() = 0; + static IAppLoadContext &CreateXMLLoadContext( + SApp &inApp, NVConstDataRef inStateReferences, + const char8_t *inScaleMode); +}; + +inline float Clamp(float val, float inMin = 0.0f, float inMax = 1.0f) +{ + if (val < inMin) + return inMin; + if (val > inMax) + return inMax; + return val; +} + +// A set of common settings that may come from the UIA or from the command line. +// command line settings always override uia settings. +struct SApplicationSettings +{ + Option m_LayerCacheEnabled; + Option m_LayerGpuProfilingEnabled; + Option m_ShaderCachePersistenceEnabled; + + SApplicationSettings() {} + + template + static Option Choose(const Option &inCommandLine, + const Option &inUIAFile) + { + if (inCommandLine.hasValue()) + return inCommandLine; + return inUIAFile; + } + + SApplicationSettings(const SApplicationSettings &inCommandLine, + const SApplicationSettings &inUIAFileSettings) + : m_LayerCacheEnabled( + Choose(inCommandLine.m_LayerCacheEnabled, inUIAFileSettings.m_LayerCacheEnabled)) + , m_LayerGpuProfilingEnabled(Choose(inCommandLine.m_LayerGpuProfilingEnabled, + inUIAFileSettings.m_LayerGpuProfilingEnabled)) + , m_ShaderCachePersistenceEnabled(Choose(inCommandLine.m_ShaderCachePersistenceEnabled, + inUIAFileSettings.m_ShaderCachePersistenceEnabled)) + { + } + + static const char8_t *LayerCacheName() { return "layer-caching"; } + static const char8_t *LayerGpuProfilerName() { return "layer-gpu-profiling"; } + static const char8_t *ShaderCacheName() { return "shader-cache-persistence"; } + + void ParseBoolEnableDisableItem(const IDOMReader &inReader, const char8_t *itemName, + Option &itemValue) + { + const char8_t *inItem; + if (const_cast(inReader).UnregisteredAtt(itemName, inItem)) { + if (AreEqualCaseless(inItem, "disabled")) + itemValue = false; + else + itemValue = true; + } + } + + void ParseBoolEnableDisableItem(const eastl::vector &inCommandLine, + const char8_t *itemName, Option &itemValue) + { + eastl::string temp; + temp.assign("-"); + temp.append(itemName); + for (QT3DSU32 idx = 0, end = inCommandLine.size(); idx < end; ++idx) { + if (inCommandLine[idx].find(temp) == 0) { + if (inCommandLine[idx].length() == temp.size()) { + qCWarning(qt3ds::INVALID_OPERATION) + << "Unable to parse parameter %s. Please pass =enable|disable as " + << "part of the parameter. " << temp.c_str(); + } else { + temp = inCommandLine[idx].substr(temp.size() + 1); + eastl::string::size_type start = temp.find_first_of("'\""); + if (start != eastl::string::npos) + temp.erase(0, start); + + eastl::string::size_type end = temp.find_first_of("'\""); + if (end != eastl::string::npos) + temp.erase(end); + if (AreEqualCaseless(temp.c_str(), "disabled")) + itemValue = false; + else + itemValue = true; + qCInfo(qt3ds::INVALID_OPERATION) + << "Item " << itemName + << (itemValue ? " enabled" : " disabled"); + } + } + } + } + + template + void ParseItems(const TReaderType &inReader) + { + ParseBoolEnableDisableItem(inReader, LayerCacheName(), m_LayerCacheEnabled); + ParseBoolEnableDisableItem(inReader, LayerGpuProfilerName(), m_LayerGpuProfilingEnabled); + ParseBoolEnableDisableItem(inReader, ShaderCacheName(), m_ShaderCachePersistenceEnabled); + } + + void Parse(IDOMReader &inReader) { ParseItems(inReader); } + + void Parse(const eastl::vector &inCommandLine) { ParseItems(inCommandLine); } + + struct SOptionSerializer + { + bool m_HasValue; + bool m_Value; + QT3DSU8 m_Padding[2]; + SOptionSerializer(const Option &inValue = Empty()) + : m_HasValue(inValue.hasValue()) + , m_Value(inValue.hasValue() ? *inValue : false) + { + m_Padding[0] = 0; + m_Padding[1] = 0; + } + + operator Option() const + { + if (m_HasValue) + return m_Value; + return Empty(); + } + }; + + void Save(IOutStream &outStream) const + { + outStream.Write(SOptionSerializer(m_LayerCacheEnabled)); + outStream.Write(SOptionSerializer(m_LayerGpuProfilingEnabled)); + outStream.Write(SOptionSerializer(m_ShaderCachePersistenceEnabled)); + } + + void Load(IInStream &inStream) + { + SOptionSerializer s; + inStream.Read(s); + m_LayerCacheEnabled = s; + inStream.Read(s); + m_LayerGpuProfilingEnabled = s; + inStream.Read(s); + m_ShaderCachePersistenceEnabled = s; + } +}; + +struct SDummyAudioPlayer : public IAudioPlayer +{ + virtual ~SDummyAudioPlayer() {} + bool PlaySoundFile(const char *inFilePath) override + { + (void *)inFilePath; + qCWarning(qt3ds::TRACE_INFO) + << "Qt3DSTegraApplication: Unimplemented method IAudioPlayer::PlaySoundFile"; + return false; + } +} g_DummyAudioPlayer; + +struct SAudioPlayerWrapper : public IAudioPlayer +{ +private: + IApplication *m_Application; + IAudioPlayer *m_RealPlayer; + +public: + SAudioPlayerWrapper() + : m_Application(0) + , m_RealPlayer(&g_DummyAudioPlayer) + { + } + virtual ~SAudioPlayerWrapper() {} + + void SetApplication(IApplication &inApplication) { m_Application = &inApplication; } + + void SetPlayer(IAudioPlayer *inPlayer) + { + if (inPlayer) + m_RealPlayer = inPlayer; + else + m_RealPlayer = &g_DummyAudioPlayer; + } + + bool PlaySoundFile(const char *inFilePath) override + { + eastl::string theFilePath(nonNull(inFilePath)); + if (m_RealPlayer != &g_DummyAudioPlayer) { + qt3ds::foundation::CFileTools::CombineBaseAndRelative( + m_Application->GetProjectDirectory().c_str(), inFilePath, theFilePath); + } + return m_RealPlayer->PlaySoundFile(theFilePath.c_str()); + } +}; + +struct SApp : public IApplication +{ + + NVScopedRefCounted m_CoreFactory; + NVScopedRefCounted m_RuntimeFactory; + + Q3DStudio::CInputEngine *m_InputEnginePtr; + CAppStr m_ApplicationDir; + CAppStr m_ProjectDir; + Option m_DebugSettings; + CAppStr m_InitialPresentationId; + CAppStr m_DLLDirectory; + TIdAssetMap m_AssetMap; + // Keep the assets ordered. This enables the uia order to mean something. + TIdAssetList m_OrderedAssets; + SPickFrame m_PickFrame; + SPickFrame m_MousePickCache; + SPickFrame m_MouseOverCache; + THashStrMap m_HashStrMap; + CTimer m_Timer; + Q3DStudio::INT64 m_ManualTime; + SFrameTimer m_FrameTimer; + Q3DStudio::INT32 m_FrameCount; + // the name of the file without extension. + eastl::string m_Filename; + Q3DSVariantConfig m_variantConfig; + + qt3ds::foundation::NVScopedReleasable m_MetaData; + nvvector> m_Behaviors; + NVScopedRefCounted m_SocketSystem; + NVScopedRefCounted m_ServerStream; + NVScopedRefCounted m_ProtocolSocket; + NVScopedRefCounted m_StateDebugger; + NVScopedRefCounted m_SceneGraphDebugger; + NVScopedRefCounted m_ActivityZoneManager; + NVScopedRefCounted m_ElementAllocator; + nvvector m_ChangeBuffer; + + // Handles are loaded sorted but only added to the handle map when needed. + nvvector m_LoadBuffer; + nvvector m_PresentationBuffer; + Mutex m_RunnableMutex; + nvvector> m_ThreadRunnables; + nvvector> m_MainThreadRunnables; + NVScopedRefCounted m_AppLoadContext; + bool m_HideFPS; + bool m_DisableState; + bool m_ProfileLogging; + bool m_LastRenderWasDirty; + QT3DSU64 m_LastFrameStartTime; + QT3DSU64 m_ThisFrameStartTime; + double m_MillisecondsSinceLastFrame; + // We get odd oscillations if we do are too quick to report that the frame wasn't dirty + // after input. + int m_DirtyCountdown; + SApplicationSettings m_UIAFileSettings; + eastl::pair, size_t> m_ElementLoadResult; + + SAudioPlayerWrapper m_AudioPlayer; + + Qt3DSAssetVisitor *m_visitor; + + bool m_createSuccessful; + + DataInputMap m_dataInputs; + + QT3DSI32 mRefCount; + SApp(Q3DStudio::IRuntimeFactoryCore &inFactory, const char8_t *inAppDir) + : m_CoreFactory(inFactory) + , m_InputEnginePtr(NULL) + , m_ApplicationDir(inFactory.GetFoundation().getAllocator()) + , m_ProjectDir(inFactory.GetFoundation().getAllocator()) + , m_InitialPresentationId(inFactory.GetFoundation().getAllocator()) + , m_DLLDirectory(inFactory.GetFoundation().getAllocator()) + , m_AssetMap(inFactory.GetFoundation().getAllocator(), "SApp::m_AssetMap") + , m_OrderedAssets(inFactory.GetFoundation().getAllocator(), "SApp::m_OrderedAssets") + , m_HashStrMap(inFactory.GetFoundation().getAllocator(), "SApp::m_HashStrMap") + , m_Timer(inFactory.GetTimeProvider()) + , m_ManualTime(0) + , m_FrameCount(0) + , m_Behaviors(inFactory.GetFoundation().getAllocator(), "SApp::m_Behaviors") + , m_ActivityZoneManager(IActivityZoneManager::CreateActivityZoneManager( + inFactory.GetFoundation(), inFactory.GetStringTable())) + , m_ElementAllocator(IElementAllocator::CreateElementAllocator(inFactory.GetFoundation(), + inFactory.GetStringTable())) + , m_ChangeBuffer(inFactory.GetFoundation().getAllocator(), "SApp::m_ChangeBuffer") + , m_LoadBuffer(inFactory.GetFoundation().getAllocator(), "SApp::m_LoadBuffer") + , m_PresentationBuffer(inFactory.GetFoundation().getAllocator(), + "SApp::m_PresentationBuffer") + , m_RunnableMutex(inFactory.GetFoundation().getAllocator()) + , m_ThreadRunnables(inFactory.GetFoundation().getAllocator(), "SApp::m_ThreadRunnables") + , m_MainThreadRunnables(inFactory.GetFoundation().getAllocator(), + "SApp::m_MainThreadRunnables") + , m_HideFPS(true) + , m_DisableState(false) + , m_ProfileLogging(false) + , m_LastRenderWasDirty(true) + , m_LastFrameStartTime(0) + , m_ThisFrameStartTime(0) + , m_MillisecondsSinceLastFrame(0) + , m_DirtyCountdown(5) + , m_createSuccessful(false) + , mRefCount(0) + , m_visitor(nullptr) + { + m_AudioPlayer.SetApplication(*this); + eastl::string tempStr(inAppDir); + CFileTools::NormalizePath(tempStr); + m_ApplicationDir.assign(tempStr.c_str()); + + Q3DStudio_memset(&m_PickFrame, 0, sizeof(SPickFrame)); + Q3DStudio_memset(&m_MousePickCache, 0, sizeof(SPickFrame)); + Q3DStudio_memset(&m_MouseOverCache, 0, sizeof(SPickFrame)); + + m_Timer.Start(); + + m_CoreFactory->SetApplicationCore(this); + m_CoreFactory->GetScriptEngineQml().SetApplicationCore(*this); + + m_CoreFactory->AddSearchPath(tempStr.c_str()); + } + + ~SApp() + { + EndLoad(); + { + Mutex::ScopedLock __locker(m_RunnableMutex); + m_ThreadRunnables.clear(); + } + // Ensure we stop the timer. + HasCompletedLoading(); + m_AppLoadContext = NULL; + + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + SAssetValue &theAsset = *m_OrderedAssets[idx].second; + if (theAsset.getType() == AssetValueTypes::Presentation) { + SPresentationAsset &thePresAsset = *theAsset.getDataPtr(); + if (thePresAsset.m_Presentation) { + Q3DStudio_delete(thePresAsset.m_Presentation, CPresentation); + thePresAsset.m_Presentation = NULL; + } + } + } + } + + void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *v) override + { + m_visitor = v; + } + + NVDataRef GetPresentations() + { + if (m_PresentationBuffer.empty()) { + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + SAssetValue &theAsset = *m_OrderedAssets[idx].second; + if (theAsset.getType() == AssetValueTypes::Presentation) { + SPresentationAsset &thePresAsset = *theAsset.getDataPtr(); + if (thePresAsset.m_Presentation) + m_PresentationBuffer.push_back(thePresAsset.m_Presentation); + } + } + } + return m_PresentationBuffer; + } + + void addRef() override { atomicIncrement(&mRefCount); } + + void release() override + { + atomicDecrement(&mRefCount); + if (mRefCount <= 0) + NVDelete(m_CoreFactory->GetFoundation().getAllocator(), this); + } + + void QueueForMainThread(IAppRunnable &inRunnable) override + { + Mutex::ScopedLock __locker(m_RunnableMutex); + m_ThreadRunnables.push_back(inRunnable); + } + + // Debugging is disabled by default. + void EnableDebugging(bool inListen, const char8_t *inServer = NULL, int inPort = 0) override + { + SDebugSettings theSettings; + theSettings.m_Server.assign(nonNull(inServer)); + if (theSettings.m_Server.size() == 0) + theSettings.m_Server = "localhost"; + theSettings.m_Port = inPort; + if (!inPort) + theSettings.m_Port = 8172; + theSettings.m_Listen = inListen; + m_DebugSettings = theSettings; + // Done at load time only. + } + + // state machine is enabled by default + void DisableStateMachine() override { m_DisableState = true; } + + virtual void EnableProfileLogging() + { + m_ProfileLogging = true; + if (m_RuntimeFactory) + m_RuntimeFactory->GetScriptEngineQml().EnableProfiling(); + } + + // Verbose logging is disabled by default. + virtual void SetVerboseLogging(bool inEnableVerboseLogging) + { + + } + + //////////////////////////////////////////////////////////////////////////// + // Update rhythm implementations + //////////////////////////////////////////////////////////////////////////// + + void SetPickFrame(const SPickFrame &inPickFrame) + { + // The model has changed, fire enter and exit mouse events + if (inPickFrame.m_Model != m_PickFrame.m_Model) { + // For determining onGroupedMouseOver/Out: + // arg1 = the original onMouseOut model and arg2 = the original onMouseOver model + UVariant theMouseOutModel; + UVariant theMouseOverModel; + theMouseOutModel.m_VoidPointer = m_PickFrame.m_Model; + theMouseOverModel.m_VoidPointer = inPickFrame.m_Model; + + // It seems like you would want to 'onMouseOut' before you 'onMouseOver' something new? + if (m_PickFrame.m_Model) { + m_PickFrame.m_Model->GetBelongedPresentation()->FireEvent( + ON_MOUSEOUT, m_PickFrame.m_Model, &theMouseOutModel, &theMouseOverModel, + ATTRIBUTETYPE_POINTER, ATTRIBUTETYPE_POINTER); + } + if (inPickFrame.m_Model) { + inPickFrame.m_Model->GetBelongedPresentation()->FireEvent( + ON_MOUSEOVER, inPickFrame.m_Model, &theMouseOutModel, &theMouseOverModel, + ATTRIBUTETYPE_POINTER, ATTRIBUTETYPE_POINTER); + m_MouseOverCache = inPickFrame; + } + } + + const TEventCommandHash *theEventArray[] = { &ON_MOUSEDOWN, &ON_MOUSEUP, + &ON_MIDDLEMOUSEDOWN, &ON_MIDDLEMOUSEUP, + &ON_RIGHTMOUSEDOWN, &ON_RIGHTMOUSEUP }; + const TEventCommandHash *theClickEventArray[] = { &ON_MOUSECLICK, &ON_MIDDLEMOUSECLICK, + &ON_RIGHTMOUSECLICK }; + + // Click events... + // NOTE: This is a fancy way to iterate programatically over all the handled mouse inputs + // handled (declared in AKPickFrame.h for now) + // we iterate to INPUTBUTTONCOUNT (see comment in AKPickFrame.h) * 2, because we handle + // mouse down and up + for (QT3DSI32 theMouseEvtIter = 0; theMouseEvtIter < MOUSEBUTTONCOUNT - 1; + theMouseEvtIter++) { + // we effectively iterate to MOUSEBUTTONCOUNT * 2 (see comment in AKPickFrame.h) to + // handle mouse down and up + QT3DSI32 theMouseDownFlag = 1 << (theMouseEvtIter * 2); + QT3DSI32 theMouseUpFlag = 1 << (theMouseEvtIter * 2 + 1); + + // on*MouseDown + // if this frame, the mouse button is down, and last frame it wasn't (new down click) + if (inPickFrame.m_Model && inPickFrame.m_InputFrame.m_MouseFlags & theMouseDownFlag + && !(m_PickFrame.m_InputFrame.m_MouseFlags & theMouseDownFlag)) { + // fire the 'on*MouseDown' event - which is at the even indices since the down + // events for each button are before the up + inPickFrame.m_Model->GetBelongedPresentation()->FireEvent( + *theEventArray[theMouseEvtIter * 2], inPickFrame.m_Model); + + // cache this as the last item we 'onMouseDown' on + m_MousePickCache = inPickFrame; + } + + // on*MouseUp + // if we mouse up on anything, send the event + if (inPickFrame.m_InputFrame.m_MouseFlags & theMouseUpFlag) { + // fire the 'on*MouseUp' event - odd indices (1,3,5 etc) + if (m_MousePickCache.m_Model) { + m_MousePickCache.m_Model->GetBelongedPresentation()->FireEvent( + *theEventArray[theMouseEvtIter * 2 + 1], m_MousePickCache.m_Model); + } + + // on*MouseClick + // if we had a up click on the same item we were mouse down on last frame ... we had + // a click + if (inPickFrame.m_Model && inPickFrame.m_Model == m_MousePickCache.m_Model) { + inPickFrame.m_Model->GetBelongedPresentation()->FireEvent( + *theClickEventArray[theMouseEvtIter], inPickFrame.m_Model); + } + + // clear the stored 'last mouse down' since we just got a mouse up + Q3DStudio_memset(&m_MousePickCache, 0, sizeof(SPickFrame)); + } + + // on*MouseDblClick + } + + if (m_MouseOverCache.m_Model) { + + if (inPickFrame.m_InputFrame.m_MouseFlags & VSCROLLWHEEL) { + UVariant theScrollValue; + theScrollValue.m_INT32 = inPickFrame.m_InputFrame.m_ScrollValue; + m_MouseOverCache.m_Model->GetBelongedPresentation()->FireEvent( + ON_VERTICALSCROLLWHEEL, m_MouseOverCache.m_Model, &theScrollValue, + NULL, ATTRIBUTETYPE_INT32); + } else if (inPickFrame.m_InputFrame.m_MouseFlags & HSCROLLWHEEL) { + UVariant theScrollValue; + theScrollValue.m_INT32 = inPickFrame.m_InputFrame.m_ScrollValue; + m_MouseOverCache.m_Model->GetBelongedPresentation()->FireEvent( + ON_HORIZONTALSCROLLWHEEL, m_MouseOverCache.m_Model, &theScrollValue, + NULL, ATTRIBUTETYPE_INT32); + } + } + + // Do this last + m_PickFrame = inPickFrame; + } + + void ClearPresentationDirtyLists() + { + NVDataRef thePresentations(GetPresentations()); + for (QT3DSU32 idx = 0, end = thePresentations.size(); idx < end; ++idx) + thePresentations[idx]->ClearDirtyList(); + } + + void UpdatePresentations() + { + SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), "UpdatePresentations"); + // Transfer the input frame to the kernel for pick processing + // the scene manager now handles the picking on each of its scenes + SetPickFrame(m_RuntimeFactory->GetSceneManager().AdvancePickFrame( + m_InputEnginePtr->GetInputFrame())); + // clear up mouse flag for horizontal and vertical scroll + m_InputEnginePtr->GetInputFrame().m_MouseFlags &= !(HSCROLLWHEEL | VSCROLLWHEEL); + + // Update all the presentations. + // Animations are advanced based on m_Timer by default, but this can be overridden via + // SetTimeMilliSecs(). + Q3DStudio::INT64 globalTime(GetTimeMilliSecs()); + + NVDataRef thePresentations(GetPresentations()); + + { + SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), + "UpdatePresentations - pre update"); + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { + SPresentationAsset &theAsset( + *m_OrderedAssets[idx].second->getDataPtr()); + CPresentation *thePresentation = theAsset.m_Presentation; + if (thePresentation && thePresentation->GetActive()) + thePresentation->PreUpdate(globalTime); + } + } + } + { + SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), + "UpdatePresentations - begin update"); + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { + SPresentationAsset &theAsset( + *m_OrderedAssets[idx].second->getDataPtr()); + CPresentation *thePresentation = theAsset.m_Presentation; + if (thePresentation && thePresentation->GetActive()) + thePresentation->BeginUpdate(); + } + } + } + { + SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), + "UpdatePresentations - end update"); + + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { + SPresentationAsset &theAsset( + *m_OrderedAssets[idx].second->getDataPtr()); + CPresentation *thePresentation = theAsset.m_Presentation; + // allow EndUpdate also for inactive presentations so that we can + // activate it + if (thePresentation) + thePresentation->EndUpdate(); + } + } + } + { + SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), + "UpdatePresentations - postupdate"); + + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { + SPresentationAsset &theAsset( + *m_OrderedAssets[idx].second->getDataPtr()); + CPresentation *thePresentation = theAsset.m_Presentation; + // allow PostUpdate also for inactive presentations so that we can + // activate it + if (thePresentation) + thePresentation->PostUpdate(globalTime); + } + } + } + + // Run the garbage collection + m_CoreFactory->GetScriptEngineQml().StepGC(); + } + + void UpdateScenes() { m_RuntimeFactory->GetSceneManager().Update(); } + + void Render() + { + SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), "Render"); + CPresentation *pres = GetPrimaryPresentation(); + if (pres) + m_LastRenderWasDirty = m_RuntimeFactory->GetSceneManager().RenderPresentation(pres); + } + + void ResetDirtyCounter() { m_DirtyCountdown = 5; } + + // Update all the presentations and render them. + void UpdateAndRender() override + { + QT3DS_ASSERT(m_AppLoadContext.mPtr == NULL); + m_ThisFrameStartTime = qt3ds::foundation::Time::getCurrentCounterValue(); + if (m_LastFrameStartTime) { + QT3DSU64 durationSinceLastFrame = m_ThisFrameStartTime - m_LastFrameStartTime; + m_MillisecondsSinceLastFrame = + qt3ds::foundation::Time::sCounterFreq.toTensOfNanos(durationSinceLastFrame) + * (1.0 / 100000.0); + } else { + m_MillisecondsSinceLastFrame = 0; + } + + if (m_ProtocolSocket) + m_ProtocolSocket->MessagePump(); + ++m_FrameCount; + + // Update any state systems + if (!m_DisableState) + m_CoreFactory->GetVisualStateContext().Initialize(); + + // First off, update any application level behaviors. + IScriptBridge &theScriptEngine = m_CoreFactory->GetScriptEngineQml(); + for (QT3DSU32 idx = 0, end = m_Behaviors.size(); idx < end; ++idx) { + eastl::pair &entry(m_Behaviors[idx]); + if (!entry.second) { + entry.second = true; + theScriptEngine.ExecuteApplicationScriptFunction(entry.first.m_Handle, + "onInitialize"); + } + } + + // TODO: Initialize presentations + + // Start any state systems + if (!m_DisableState) + m_CoreFactory->GetVisualStateContext().Start(); + + for (QT3DSU32 idx = 0, end = m_Behaviors.size(); idx < end; ++idx) { + eastl::pair &entry(m_Behaviors[idx]); + theScriptEngine.ExecuteApplicationScriptFunction(entry.first.m_Handle, "onUpdate"); + } + + if (!m_DisableState) + m_CoreFactory->GetVisualStateContext().Update(); + + UpdatePresentations(); + + if (m_ProtocolSocket) { + m_ProtocolSocket->MessagePump(); + if (m_ProtocolSocket->Connected() == false) + exit(0); + } + + UpdateScenes(); + + Render(); + + GetSceneGraphDebugger(); + + if (m_SceneGraphDebugger->IsConnected()) { + NVDataRef thePresentations(GetPresentations()); + size_t thePresentationCount = thePresentations.size(); + for (QT3DSU32 thePresentationIndex = 0; thePresentationIndex < thePresentationCount; + thePresentationIndex++) { + CPresentation *thePresentation = thePresentations[thePresentationIndex]; + Q3DStudio::TElementList &theDirtyList = + thePresentation->GetFrameData().GetDirtyList(); + for (QT3DSU32 idx = 0, end = theDirtyList.GetCount(); idx < end; ++idx) { + Q3DStudio::TElement &theElement = *theDirtyList[idx]; + // Set active + m_ChangeBuffer.push_back(SSGPropertyChange()); + QT3DSI32 active = theElement.GetActive() ? 1 : 0; + m_ChangeBuffer.back().m_Hash = CHash::HashAttribute("active"); + m_ChangeBuffer.back().m_Value = qt3ds::state::debugger::SSGValue(active); + for (long attIdx = 0, attEnd = theElement.GetAttributeCount(); attIdx < attEnd; + ++attIdx) { + Option theValue = + theElement.GetPropertyByIndex(attIdx); + m_ChangeBuffer.push_back(SSGPropertyChange()); + SSGPropertyChange &theChange(m_ChangeBuffer.back()); + theChange.m_Hash = theValue->first.GetNameHash(); + Q3DStudio::EAttributeType theAttType = theValue->first.m_Type; + switch (theAttType) { + case ATTRIBUTETYPE_HASH: + case ATTRIBUTETYPE_BOOL: + case ATTRIBUTETYPE_INT32: + theChange.m_Value = + qt3ds::state::debugger::SSGValue( + (QT3DSI32)theValue->second->m_INT32); + break; + case ATTRIBUTETYPE_FLOAT: + theChange.m_Value = + qt3ds::state::debugger::SSGValue(theValue->second->m_FLOAT); + break; + case ATTRIBUTETYPE_STRING: { + CRegisteredString data = m_CoreFactory->GetStringTable().HandleToStr( + theValue->second->m_StringHandle); + theChange.m_Value = qt3ds::state::debugger::SSGValue(data); + } break; + case ATTRIBUTETYPE_POINTER: { + void *ptrVal = theValue->second->m_VoidPointer; + QT3DSU64 coercedVal = (QT3DSU64)ptrVal; + theChange.m_Value = qt3ds::state::debugger::SSGValue(coercedVal); + } break; + case ATTRIBUTETYPE_ELEMENTREF: { + void *ptrVal = GetElementByHandle(theValue->second->m_ElementHandle); + QT3DSU64 coercedVal = (QT3DSU64)ptrVal; + theChange.m_Value = qt3ds::state::debugger::SSGValue(coercedVal); + } break; + default: + QT3DS_ASSERT(false); + break; + } + } + // If this is a component element, we have a few more properties we need to + // grab. + if (theElement.IsComponent()) { + TComponent &theComponent = static_cast(theElement); + QT3DSI32 slide = theComponent.GetCurrentSlide(); + QT3DSI32 isPaused = theComponent.GetPaused() ? 1 : 0; + QT3DSI32 time + =(QT3DSI32)thePresentation->GetActivityZone()->GetItemComponentTime( + theComponent); + m_ChangeBuffer.push_back( + SSGPropertyChange(CHash::HashAttribute("slide"), slide)); + m_ChangeBuffer.push_back( + SSGPropertyChange(CHash::HashAttribute("paused"), isPaused)); + m_ChangeBuffer.push_back( + SSGPropertyChange(CHash::HashAttribute("time"), time)); + } + if (m_ChangeBuffer.size()) { + m_SceneGraphDebugger->OnPropertyChanged(&theElement, m_ChangeBuffer); + m_ChangeBuffer.clear(); + } + } + } + m_SceneGraphDebugger->EndFrame(); + } + + m_InputEnginePtr->ClearInputFrame(); + ClearPresentationDirtyLists(); + + if (m_ProtocolSocket) + m_ProtocolSocket->MessagePump(); + + if (!m_CoreFactory->GetEventSystem().GetAndClearEventFetchedFlag()) + m_CoreFactory->GetEventSystem().PurgeEvents(); // GetNextEvents of event system has not + // been called in this round, so clear + // events to avoid events to be piled up + + QT3DSU64 updateEndTime = qt3ds::foundation::Time::getCurrentCounterValue(); + QT3DSU64 updateDuration = updateEndTime - m_ThisFrameStartTime; + double millis + = qt3ds::foundation::Time::sCounterFreq.toTensOfNanos(updateDuration) + * (1.0 / 100000); + if (floor(m_FrameTimer.GetElapsedSeconds()) > 0.0f) { + QPair fps = m_FrameTimer.GetFPS(m_FrameCount); + m_RuntimeFactory->GetQt3DSRenderContext().SetFPS(fps); + if (m_ProfileLogging || !m_HideFPS) { + qCInfo(PERF_INFO, "Render Statistics: %3.2ffps, frame count %d", + fps.first, fps.second); + } + } + + (void)millis; + + /*if ( millis > 30.0 ) + { + m_CoreFactory->GetFoundation().error( NVErrorCode::eDEBUG_INFO, __FILE__, __LINE__, + "Qt3DS Long Frame: %3.2fms", millis ); + //Useful for figuring out where the frame time comes from. + m_CoreFactory->GetPerfTimer().OutputTimerData(); + + } + else*/ + m_CoreFactory->GetPerfTimer().ResetTimerData(); + + fflush(stdout); + m_LastFrameStartTime = m_ThisFrameStartTime; + if (m_LastRenderWasDirty) + ResetDirtyCounter(); + else + m_DirtyCountdown = NVMax(0, m_DirtyCountdown - 1); + } + + // hook this up to -layer-caching. + // otherwise it might be hard to measure performance + bool IsApplicationDirty() override + { + return (m_DirtyCountdown > 0); + } + + double GetMillisecondsSinceLastFrame() override { return m_MillisecondsSinceLastFrame; } + + void MarkApplicationDirty() override { ResetDirtyCounter(); } + + Q3DStudio::IAudioPlayer &GetAudioPlayer() override { return m_AudioPlayer; } + //////////////////////////////////////////////////////////////////////////////// + // Generalized save/load + //////////////////////////////////////////////////////////////////////////////// + + bool LoadUIP(SPresentationAsset &inAsset, + NVConstDataRef inExternalReferences) + { + GetMetaData(); + eastl::string theFile; + CFileTools::CombineBaseAndRelative(GetProjectDirectory().c_str(), inAsset.m_Src.c_str(), + theFile); + // Check if the file event exists + eastl::string fullPath; + NVScopedRefCounted theStream + = m_CoreFactory->GetRenderContextCore().GetInputStreamFactory().GetStreamForFile( + theFile.c_str()); + if (theStream) { + theStream = NULL; + CPresentation *thePresentation + = Q3DStudio_new(CPresentation) CPresentation(inAsset.m_Id.c_str(), this); + inAsset.m_Presentation = thePresentation; + thePresentation->SetFilePath(theFile.c_str()); + NVScopedReleasable theUIPParser(IUIPParser::Create( + theFile.c_str(), *m_MetaData, + m_CoreFactory->GetInputStreamFactory(), + m_CoreFactory->GetStringTable())); + Q3DStudio::IScene *newScene = NULL; + ISceneGraphRuntimeDebugger &theDebugger = GetSceneGraphDebugger(); + m_PresentationBuffer.clear(); + // Map presentation id has to be called before load so that when we send the element + // id updates the system can also send the presentationid->id mapping. + theDebugger.MapPresentationId(thePresentation, inAsset.m_Id.c_str()); + if (theUIPParser->Load(*thePresentation, inExternalReferences, + GetSceneGraphDebugger())) { + // Load the scene graph portion of the scene. + newScene = m_RuntimeFactory->GetSceneManager().LoadScene( + thePresentation, theUIPParser.mPtr, + m_CoreFactory->GetScriptEngineQml(), + m_variantConfig); + } + + if (newScene == NULL) { + Q3DStudio_delete(thePresentation, CPresentation); + qCWarning(qt3ds::INVALID_OPERATION) + << "Unable to load presentation " << theFile.c_str(); + inAsset.m_Presentation = NULL; + return false; + } else { + if (inAsset.m_Id.IsValid() && m_InitialPresentationId.empty()) + m_InitialPresentationId.assign(inAsset.m_Id); + + if (inAsset.m_Id.IsValid()) + newScene->RegisterOffscreenRenderer(inAsset.m_Id); + return true; + } + } + qCWarning(qt3ds::INVALID_OPERATION) << "Unable to load presentation " << theFile.c_str(); + return false; + } + + bool LoadUIA(IDOMReader &inReader, NVFoundationBase &fnd) + { + NVConstDataRef theStateReferences; + { + IDOMReader::Scope __preparseScope(inReader); + theStateReferences = m_CoreFactory->GetVisualStateContext().PreParseDocument(inReader); + } + { + m_UIAFileSettings.Parse(inReader); + } + { + IDOMReader::Scope __assetsScope(inReader); + if (!inReader.MoveToFirstChild("assets")) { + qCCritical(INVALID_OPERATION, + "UIA input xml doesn't contain tag; load failed"); + return false; + } + + eastl::string pathString; + + const char8_t *initialItem = ""; + inReader.UnregisteredAtt("initial", initialItem); + m_InitialPresentationId.clear(); + if (!isTrivial(initialItem)) { + if (initialItem[0] == '#') + ++initialItem; + + m_InitialPresentationId.assign(initialItem); + } + eastl::vector theUIPReferences; + eastl::string tempString; + + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + IDOMReader::Scope __assetScope(inReader); + const char8_t *itemId(""); + inReader.UnregisteredAtt("id", itemId); + const char8_t *src = ""; + inReader.UnregisteredAtt("src", src); + pathString.clear(); + if (!isTrivial(src)) + CFileTools::CombineBaseAndRelative(m_ProjectDir.c_str(), src, pathString); + + const char8_t *assetName = inReader.GetElementName(); + if (AreEqual(assetName, "presentation")) { + SPresentationAsset theAsset(RegisterStr(itemId), RegisterStr(src)); + bool activeFlag; + if (inReader.Att("active", activeFlag)) + theAsset.m_Active = activeFlag; + RegisterAsset(theAsset); + } else if (AreEqual(assetName, "dataInput")) { + DataInputDef diDef; + const char8_t *name = ""; + const char8_t *type = ""; + const char8_t *evaluator = ""; + diDef.value = QVariant::Invalid; + inReader.UnregisteredAtt("name", name); + inReader.UnregisteredAtt("type", type); + inReader.Att("min", diDef.min); + inReader.Att("max", diDef.max); + inReader.UnregisteredAtt("evaluator", evaluator); + if (AreEqual(type, "Ranged Number")) + diDef.type = DataInputTypeRangedNumber; + else if (AreEqual(type, "String")) + diDef.type = DataInputTypeString; + else if (AreEqual(type, "Float")) + diDef.type = DataInputTypeFloat; + else if (AreEqual(type, "Vector3")) + diDef.type = DataInputTypeVector3; + else if (AreEqual(type, "Vector2")) + diDef.type = DataInputTypeVector2; + else if (AreEqual(type, "Boolean")) + diDef.type = DataInputTypeBoolean; + else if (AreEqual(type, "Variant")) + diDef.type = DataInputTypeVariant; + + if (AreEqual(type, "Evaluator")) { + diDef.type = DataInputTypeEvaluator; + diDef.evaluator = QString::fromUtf8(evaluator); + } + + m_dataInputs.insert(QString::fromUtf8(name), diDef); + } else if (AreEqual(assetName, "renderplugin")) { + const char8_t *pluginArgs = ""; + inReader.UnregisteredAtt("args", pluginArgs); + RegisterAsset(SRenderPluginAsset(RegisterStr(itemId), RegisterStr(src), + RegisterStr(pluginArgs))); + } else if (AreEqual(assetName, "statemachine")) { + const char8_t *dm = ""; + inReader.UnregisteredAtt("datamodel", dm); + m_CoreFactory->GetVisualStateContext().LoadStateMachine(itemId, src, + nonNull(dm)); + RegisterAsset( + SSCXMLAsset(RegisterStr(itemId), RegisterStr(src), RegisterStr(dm))); + + } else if (AreEqual(assetName, "behavior")) { + SBehaviorAsset theAsset(RegisterStr(itemId), RegisterStr(src), 0); + RegisterAsset(theAsset); + } else if (AreEqual(assetName, "presentation-qml")) { + const char8_t *args = ""; + inReader.UnregisteredAtt("args", args); + RegisterAsset(SQmlPresentationAsset(RegisterStr(itemId), RegisterStr(src), + RegisterStr(args))); + } else { + qCWarning(WARNING, "Unrecognized child %s", assetName); + } + } + } // end assets scope + const char8_t *initialScaleMode = ""; + inReader.UnregisteredAtt("scalemode", initialScaleMode); + + { + IDOMReader::Scope __machineScope(inReader); + m_CoreFactory->GetVisualStateContext().LoadVisualStateMapping(inReader); + } + m_AppLoadContext + = IAppLoadContext::CreateXMLLoadContext(*this, theStateReferences, + initialScaleMode); + return true; + } + + DataInputMap &dataInputMap() override + { + return m_dataInputs; + } + + struct SAppXMLErrorHandler : public qt3ds::foundation::CXmlErrorHandler + { + NVFoundationBase &m_Foundation; + const char8_t *m_FilePath; + SAppXMLErrorHandler(NVFoundationBase &fnd, const char8_t *filePath) + : m_Foundation(fnd) + , m_FilePath(filePath) + { + } + + void OnXmlError(TXMLCharPtr errorName, int line, int /*column*/) override + { + qCWarning(INVALID_OPERATION, m_FilePath, line, "%s", errorName); + } + }; + + void ConnectDebugger() + { + NVFoundationBase &fnd(m_CoreFactory->GetFoundation()); + Q3DStudio::IScriptBridge &theBridge = m_CoreFactory->GetScriptEngineQml(); + if (m_DebugSettings.hasValue()) { + m_SocketSystem = SocketSystem::createSocketSystem(fnd); + if (m_DebugSettings->m_Listen) { + // Wait for connection request from debug server + qCInfo(TRACE_INFO, "Listening for debug connection on port %d", + m_DebugSettings->m_Port); + NVScopedRefCounted theServer + = m_SocketSystem->createServer(m_DebugSettings->m_Port); + theServer->setTimeout(1000); + m_ServerStream = theServer->nextClient(); + } else { + // Attempt to connect to the debug server + qCInfo(TRACE_INFO, "Attempt to connect to debug server %s:%d", + m_DebugSettings->m_Server.c_str(), m_DebugSettings->m_Port); + m_ServerStream = m_SocketSystem->createStream(m_DebugSettings->m_Server.c_str(), + m_DebugSettings->m_Port, 1000); + } + if (m_ServerStream) { + m_ServerStream->setTimeout(QT3DS_MAX_U32); + // This system declares protocols, we don't listen for new ones. + m_ProtocolSocket = qt3ds::state::debugger::IMultiProtocolSocket::CreateProtocolSocket( + fnd, *m_ServerStream, m_CoreFactory->GetStringTable(), NULL); + if (!m_ProtocolSocket->Initialize()) { + m_ProtocolSocket = NULL; + m_ServerStream = NULL; + m_SocketSystem = NULL; + qCWarning(WARNING, + "Initialization failed after connection to server, debug server %s:%d", + m_DebugSettings->m_Server.c_str(), m_DebugSettings->m_Port); + + } else { + using namespace qt3ds::state::debugger; + theBridge.EnableDebugging(*m_ProtocolSocket); + NVScopedRefCounted socketStream + = m_ProtocolSocket->CreateProtocol( + CProtocolNames::getSCXMLProtocolName(), NULL); + GetStateDebugger().OnServerConnected(*socketStream); + + NVScopedRefCounted theSGStream + = m_ProtocolSocket->CreateProtocol( + ISceneGraphRuntimeDebugger::GetProtocolName(), NULL); + GetSceneGraphDebugger().OnConnection(*theSGStream); + theSGStream->SetListener(&GetSceneGraphDebugger()); + } + } else { + qCWarning(WARNING, "Failed to connect to debug server %s:%d", + m_DebugSettings->m_Server.c_str(), m_DebugSettings->m_Port); + } + } + } + + virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override + { + SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), "Application: Begin Load"); + eastl::string directory; + eastl::string filename; + eastl::string extension; + CFileTools::Split(sourcePath.toUtf8().constData(), directory, filename, extension); + eastl::string projectDirectory(directory); + + m_ProjectDir.assign(projectDirectory.c_str()); + m_CoreFactory->AddSearchPath(projectDirectory.c_str()); + + // add additional search path + QString projectDir = CFileTools::NormalizePathForQtUsage(projectDirectory.c_str()); + if (!projectDir.startsWith(QStringLiteral(":"))) { + eastl::string relativeProjectDir; + CFileTools::CombineBaseAndRelative(m_ApplicationDir.c_str(), projectDirectory.c_str(), + relativeProjectDir); + m_CoreFactory->AddSearchPath(relativeProjectDir.c_str()); + } + + NVFoundationBase &fnd(m_CoreFactory->GetFoundation()); + + if (m_CoreFactory->GetRenderContextCore().GetTextRendererCore()) { + m_CoreFactory->GetRenderContextCore().GetTextRendererCore()->AddProjectFontDirectory( + projectDirectory.c_str()); + m_CoreFactory->GetRenderContextCore().GetTextRendererCore()->BeginPreloadFonts( + m_CoreFactory->GetRenderContextCore().GetThreadPool(), + m_CoreFactory->GetRenderContextCore().GetPerfTimer()); + } + m_Filename = filename; + m_variantConfig.setVariantList(variantList); + bool retval = false; + if (extension.comparei("uip") == 0) { +#if !defined(_LINUXPLATFORM) && !defined(_INTEGRITYPLATFORM) + ConnectDebugger(); +#endif + m_InitialPresentationId.assign(filename.c_str()); + eastl::string relativePath = "./"; + relativePath.append(filename); + relativePath.append("."); + relativePath.append("uip"); + RegisterAsset(SPresentationAsset(RegisterStr(filename.c_str()), + RegisterStr(relativePath.c_str()))); + m_AppLoadContext = IAppLoadContext::CreateXMLLoadContext( + *this, NVDataRef(), ""); + + retval = true; + } else if (extension.comparei("uia") == 0) { +#if !defined(_LINUXPLATFORM) && !defined(_INTEGRITYPLATFORM) + ConnectDebugger(); +#endif + CFileSeekableIOStream inputStream(sourcePath, FileReadFlags()); + if (inputStream.IsOpen()) { + NVScopedRefCounted strTable( + IStringTable::CreateStringTable(fnd.getAllocator())); + NVScopedRefCounted domFactory( + IDOMFactory::CreateDOMFactory(fnd.getAllocator(), strTable)); + SAppXMLErrorHandler errorHandler(fnd, sourcePath.toUtf8().constData()); + eastl::pair readResult = + CDOMSerializer::Read(*domFactory, inputStream, &errorHandler); + if (!readResult.second) { + qCCritical(INVALID_PARAMETER, "%s doesn't appear to be valid xml", + sourcePath.toUtf8().constData()); + } else { + NVScopedRefCounted domReader = IDOMReader::CreateDOMReader( + fnd.getAllocator(), *readResult.second, strTable, domFactory); + if (m_visitor) + m_visitor->visit(sourcePath.toUtf8().constData()); + retval = LoadUIA(*domReader, fnd); + } + } else { + qCCritical(INVALID_PARAMETER, "Unable to open input file %s", + sourcePath.toUtf8().constData()); + } + } else { + QT3DS_ASSERT(false); + } + return retval; + } + + void EndLoad() override + { + if (m_AppLoadContext) + m_AppLoadContext->EndLoad(); + } + + void RunAllRunnables() + { + { + Mutex::ScopedLock __locker(m_RunnableMutex); + m_MainThreadRunnables = m_ThreadRunnables; + m_ThreadRunnables.clear(); + } + for (QT3DSU32 idx = 0, end = m_MainThreadRunnables.size(); idx < end; ++idx) + m_MainThreadRunnables[idx]->Run(); + m_MainThreadRunnables.clear(); + } + + bool HasCompletedLoading() override + { + RunAllRunnables(); + if (m_AppLoadContext) + return m_AppLoadContext->HasCompletedLoading(); + + return true; + } + + bool createSuccessful() override + { + return m_createSuccessful; + } + + // will force loading to end if endLoad hasn't been called yet. Will fire off loading + // of resources that need to be uploaded to opengl. Maintains reference to runtime factory + IApplication &CreateApplication(Q3DStudio::CInputEngine &inInputEngine, + Q3DStudio::IAudioPlayer *inAudioPlayer, + Q3DStudio::IRuntimeFactory &inFactory) override + { + { + SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), + "Application: Initialize Graphics"); + + { + SStackPerfTimer __timer(m_CoreFactory->GetPerfTimer(), "Application: EndLoad"); + EndLoad(); + } + m_InputEnginePtr = &inInputEngine; + m_RuntimeFactory = inFactory; + + { + SStackPerfTimer __timer(m_CoreFactory->GetPerfTimer(), + "Application: Load Context Graphics Initialized"); + if (m_AppLoadContext) + m_createSuccessful = m_AppLoadContext->OnGraphicsInitialized(inFactory); + // Guarantees the end of the multithreaded access to the various components + m_AppLoadContext = NULL; + if (!m_createSuccessful) + return *this; + } + + { + SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), + "Application: End Font Preload"); + if (m_CoreFactory->GetRenderContextCore().GetTextRendererCore()) + m_CoreFactory->GetRenderContextCore() + .GetTextRendererCore() + ->EndPreloadFonts(); + } + + RunAllRunnables(); + // Moving set application to the end ensures that the application load context is not + // accessing + // the lua state in another thread while we are calling set application. This + // apparently may cause + // the call to set application to fail miserably. + m_RuntimeFactory->SetApplication(this); + m_RuntimeFactory->GetStringTable().DisableMultithreadedAccess(); + + for (QT3DSU32 idx = 0, end = m_OrderedAssets.size(); idx < end; ++idx) { + if (m_OrderedAssets[idx].second->getType() == AssetValueTypes::Presentation) { + SPresentationAsset &theAsset( + *m_OrderedAssets[idx].second->getDataPtr()); + CPresentation *thePresentation = theAsset.m_Presentation; + if (thePresentation) { + SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), + "Application: SetActivityZone"); + thePresentation->SetActivityZone( + &m_ActivityZoneManager->CreateActivityZone(*thePresentation)); + thePresentation->SetActive(theAsset.m_Active); + } + } + } + + inInputEngine.SetApplication(this); + } + SApplicationSettings finalSettings(/*m_CommandLineSettings, */m_UIAFileSettings); + if (finalSettings.m_LayerCacheEnabled.hasValue()) { + inFactory.GetQt3DSRenderContext().GetRenderer().EnableLayerCaching( + *finalSettings.m_LayerCacheEnabled); + } + if (finalSettings.m_LayerGpuProfilingEnabled.hasValue()) { + inFactory.GetQt3DSRenderContext().GetRenderer().EnableLayerGpuProfiling( + *finalSettings.m_LayerGpuProfilingEnabled); + } + + m_CoreFactory->GetPerfTimer().OutputTimerData(); + + m_AudioPlayer.SetPlayer(inAudioPlayer); + + return *this; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // Getters/Setters + ////////////////////////////////////////////////////////////////////////////////////////////////////// + CRegisteredString RegisterStr(const char8_t *inStr) + { + return m_CoreFactory->GetStringTable().RegisterStr(inStr); + } + + // The directory that contains the executable and the root resource path + CRegisteredString GetApplicationDirectory() const override + { + return const_cast(*this).m_CoreFactory->GetStringTable().RegisterStr( + m_ApplicationDir.c_str()); + } + // Directory that contained the XIF file. + CRegisteredString GetProjectDirectory() const override + { + QT3DS_ASSERT(m_ProjectDir.size()); + return const_cast(*this).m_CoreFactory->GetStringTable().RegisterStr( + m_ProjectDir.c_str()); + } + + CRegisteredString GetDllDir() const override + { + if (m_DLLDirectory.size()) { + return const_cast(*this).m_CoreFactory->GetStringTable().RegisterStr( + m_DLLDirectory.c_str()); + } + return CRegisteredString(); + } + + void SetDllDir(const char *inDllDir) override + { + m_DLLDirectory.assign(nonNull(inDllDir)); + m_CoreFactory->SetDllDir(inDllDir); + } + + Q3DStudio::IRuntimeFactory &GetRuntimeFactory() const override { return *m_RuntimeFactory.mPtr; } + Q3DStudio::IRuntimeFactoryCore &GetRuntimeFactoryCore() override { return *m_CoreFactory; } + + Q3DStudio::CPresentation *GetPrimaryPresentation() override + { + return GetPresentationById(m_InitialPresentationId.c_str()); + } + + Q3DStudio::CPresentation *GetPresentationById(const char8_t *inId) override + { + if (!isTrivial(inId)) { + TIdAssetMap::iterator iter + = m_AssetMap.find(m_CoreFactory->GetStringTable().RegisterStr(inId)); + if (iter != m_AssetMap.end() + && iter->second->getType() == AssetValueTypes::Presentation) { + return iter->second->getData().m_Presentation; + } + } + return NULL; + } + + // Returns a list of all presentations in the application + // The primary presentation is returned at index 0 + QList GetPresentationList() override + { + QList list; + for (TIdAssetMap::iterator iter = m_AssetMap.begin(); iter != m_AssetMap.end(); ++iter) { + if (iter->second->getType() == AssetValueTypes::Presentation) { + Q3DStudio::CPresentation *presentation + = iter->second->getData().m_Presentation; + if (presentation) { + if (iter->first == m_InitialPresentationId) + list.prepend(presentation); + else + list.append(presentation); + } + } + } + return list; + } + + template + void RegisterAsset(const TAssetType &inAsset) + { + NVScopedRefCounted theValue( + QT3DS_NEW(m_CoreFactory->GetFoundation().getAllocator(), + SRefCountedAssetValue(m_CoreFactory->GetFoundation(), inAsset))); + if (inAsset.m_Id.IsValid()) + m_AssetMap.insert(eastl::make_pair(inAsset.m_Id, theValue)); + + m_OrderedAssets.push_back(eastl::make_pair(inAsset.m_Id, theValue)); + + if (m_visitor) { + m_visitor->visit(inAsset.Type(), inAsset.m_Id.c_str(), inAsset.m_Src.c_str(), + inAsset.m_Args.c_str()); + } + } + + THashValue HashString(const char *inStr) override + { + if (inStr == NULL) + inStr = ""; + THashValue retval = CHash::HashString(inStr); + eastl::pair insertResult + = m_HashStrMap.insert(eastl::make_pair(retval, CRegisteredString())); + if (insertResult.second) + insertResult.first->second = m_CoreFactory->GetStringTable().RegisterStr(inStr); + return retval; + } + + const char *ReverseHash(THashValue theValue) override + { + THashStrMap::iterator find = m_HashStrMap.find(theValue); + if (find != m_HashStrMap.end()) + return find->second.c_str(); + return ""; + } + + void SetFrameCount(Q3DStudio::INT32 inFrameCount) override { m_FrameCount = inFrameCount; } + + Q3DStudio::INT32 GetFrameCount() override { return m_FrameCount; } + + void SetTimeMilliSecs(Q3DStudio::INT64 inMilliSecs) override { m_ManualTime = inMilliSecs; } + + Q3DStudio::INT64 GetTimeMilliSecs() override + { + return m_ManualTime == 0 ? m_Timer.GetTimeMilliSecs() : m_ManualTime; + } + + void ResetTime() override + { + m_Timer.Reset(); + m_ManualTime = 0; + } + + void HideFPS(bool flag) override { m_HideFPS = flag; } + + Q3DStudio::CInputEngine &GetInputEngine() override + { + QT3DS_ASSERT(m_InputEnginePtr); + return *m_InputEnginePtr; + } + + Q3DStudio::IRuntimeMetaData &GetMetaData() override + { + if (!m_MetaData) { + m_MetaData = &IRuntimeMetaData::Create(m_CoreFactory->GetInputStreamFactory()); + if (!m_MetaData) { + qCCritical(qt3ds::INVALID_OPERATION) + << "IRuntimeMetaData::Create: Failed to create meta data"; + } + } + return *m_MetaData; + } + + qt3ds::state::debugger::IDebugger &GetStateDebugger() override + { + if (!m_StateDebugger) + m_StateDebugger = qt3ds::state::debugger::IDebugger::CreateDebugger(); + return *m_StateDebugger; + } + + qt3ds::state::debugger::ISceneGraphRuntimeDebugger &GetSceneGraphDebugger() override + { + if (!m_SceneGraphDebugger) + m_SceneGraphDebugger = qt3ds::state::debugger::ISceneGraphRuntimeDebugger::Create( + m_CoreFactory->GetFoundation(), m_CoreFactory->GetStringTable()); + return *m_SceneGraphDebugger; + } + + IActivityZoneManager &GetActivityZoneManager() override { return *m_ActivityZoneManager; } + + IElementAllocator &GetElementAllocator() override { return *m_ElementAllocator; } + + Q3DStudio::UINT32 GetHandleForElement(Q3DStudio::TElement *inElement) override + { + return inElement->GetHandle(); + } + + Q3DStudio::TElement *GetElementByHandle(Q3DStudio::UINT32 inHandle) override + { + return GetElementAllocator().FindElementByHandle(inHandle); + } +}; + +struct SXMLLoader : public IAppLoadContext +{ + SApp &m_App; + eastl::string m_ScaleMode; + eastl::vector m_References; + QT3DSI32 mRefCount; + + SXMLLoader(SApp &inApp, const char8_t *sc, NVConstDataRef refs) + : m_App(inApp) + , m_ScaleMode(nonNull(sc)) + , mRefCount(0) + { + m_References.assign(refs.begin(), refs.end()); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_App.m_CoreFactory->GetFoundation().getAllocator()) + + void EndLoad() override {} + + bool HasCompletedLoading() override { return true; } + + bool OnGraphicsInitialized(IRuntimeFactory &inFactory) override + { + eastl::vector theUIPReferences; + eastl::string tempString; + for (QT3DSU32 idx = 0, end = m_App.m_OrderedAssets.size(); idx < end; ++idx) { + SAssetValue &theAsset = *m_App.m_OrderedAssets[idx].second; + eastl::string thePathStr; + + CFileTools::CombineBaseAndRelative(m_App.GetProjectDirectory().c_str(), + theAsset.GetSource(), thePathStr); + switch (theAsset.getType()) { + case AssetValueTypes::Presentation: { + QDir::addSearchPath(QStringLiteral("qt3dstudio"), + QFileInfo(QString(thePathStr.c_str())) + .absoluteDir().absolutePath()); + SPresentationAsset &thePresentationAsset + = *theAsset.getDataPtr(); + theUIPReferences.clear(); + for (QT3DSU32 refIdx = 0, refEnd = m_References.size(); refIdx < refEnd; ++refIdx) { + tempString.assign(m_References[refIdx].m_ElementPath.c_str()); + eastl::string::size_type colonPos = tempString.find_first_of(':'); + if (colonPos != eastl::string::npos) { + tempString = tempString.substr(0, colonPos); + if (tempString.compare(thePresentationAsset.m_Id.c_str()) == 0) { + SElementAttributeReference newReference( + m_References[refIdx].m_ElementPath.c_str() + colonPos + 1, + m_References[refIdx].m_Attribute.c_str()); + theUIPReferences.push_back(newReference); + } + } + } + + if (!m_App.LoadUIP(thePresentationAsset, + toConstDataRef(theUIPReferences.data(), + (QT3DSU32)theUIPReferences.size()))) { + qCCritical(INVALID_OPERATION, "Unable to load presentation %s", + thePathStr.c_str()); + } + } break; + case AssetValueTypes::Behavior: { + SBehaviorAsset &theBehaviorAsset = *theAsset.getDataPtr(); + Q3DStudio::INT32 scriptId + = m_App.m_CoreFactory->GetScriptEngineQml().InitializeApplicationBehavior( + theBehaviorAsset.m_Src); + if (scriptId == 0) { + qCCritical(INVALID_OPERATION, "Unable to load application behavior %s", + theBehaviorAsset.m_Src.c_str()); + } else { + theBehaviorAsset.m_Handle = scriptId; + m_App.m_Behaviors.push_back(eastl::make_pair(theBehaviorAsset, false)); + } + } break; + case AssetValueTypes::RenderPlugin: { + SRenderPluginAsset &thePluginAsset = *theAsset.getDataPtr(); + + inFactory.GetSceneManager().LoadRenderPlugin( + thePluginAsset.m_Id, thePathStr.c_str(), thePluginAsset.m_Args); + } break; + + case AssetValueTypes::QmlPresentation: { + SQmlPresentationAsset &asset = *theAsset.getDataPtr(); + inFactory.GetSceneManager().LoadQmlStreamerPlugin(asset.m_Id); + } break; + // SCXML, NoAssetValue do not need processing here + default: + break; + } + } + if (m_ScaleMode.empty() == false) { + const char8_t *initialScaleMode(m_ScaleMode.c_str()); + // Force loading to finish here, just like used to happen. + if (AreEqual(initialScaleMode, "center")) { + inFactory.GetQt3DSRenderContext().SetScaleMode(qt3ds::render::ScaleModes::ExactSize); + } else if (AreEqual(initialScaleMode, "fit")) { + inFactory.GetQt3DSRenderContext().SetScaleMode(qt3ds::render::ScaleModes::ScaleToFit); + } else if (AreEqual(initialScaleMode, "fill")) { + inFactory.GetQt3DSRenderContext().SetScaleMode(qt3ds::render::ScaleModes::ScaleToFill); + } else { + qCCritical(INVALID_PARAMETER, "Unrecognized scale mode attribute value: ", + initialScaleMode); + } + } + return true; + } + + virtual void OnFirstRender() {} +}; + +IAppLoadContext &IAppLoadContext::CreateXMLLoadContext( + SApp &inApp, NVConstDataRef inStateReferences, + const char8_t *inScaleMode) +{ + return *QT3DS_NEW(inApp.m_CoreFactory->GetFoundation().getAllocator(), + SXMLLoader)(inApp, inScaleMode, inStateReferences); +} +} + +CAppStr::CAppStr(NVAllocatorCallback &alloc, const char8_t *inStr) + : TBase(inStr, ForwardingAllocator(alloc, "CAppStr")) +{ +} + +CAppStr::CAppStr(const CAppStr &inOther) + : TBase(inOther) +{ +} + +CAppStr::CAppStr() + : TBase() +{ +} + +CAppStr &CAppStr::operator=(const CAppStr &inOther) +{ + TBase::operator=(inOther); + return *this; +} + +IApplicationCore &IApplicationCore::CreateApplicationCore(Q3DStudio::IRuntimeFactoryCore &inFactory, + const char8_t *inApplicationDirectory) +{ + return *QT3DS_NEW(inFactory.GetFoundation().getAllocator(), SApp)(inFactory, + inApplicationDirectory); +} + +// Checks if the event is one that can cause picking +bool IApplicationCore::isPickingEvent(TEventCommandHash event) +{ + return (event == ON_MOUSEDOWN + || event == ON_MOUSEUP + || event == ON_MIDDLEMOUSEDOWN + || event == ON_MIDDLEMOUSEUP + || event == ON_RIGHTMOUSEDOWN + || event == ON_RIGHTMOUSEUP + || event == ON_MOUSECLICK + || event == ON_MIDDLEMOUSECLICK + || event == ON_RIGHTMOUSECLICK + || event == ON_MOUSEOVER + || event == ON_MOUSEOUT + || event == ON_GROUPEDMOUSEOVER + || event == ON_GROUPEDMOUSEOUT); +} diff --git a/src/Runtime/Source/runtime/Qt3DSApplication.h b/src/Runtime/Source/runtime/Qt3DSApplication.h new file mode 100644 index 00000000..d825fe0f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSApplication.h @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_APPLICATION_H +#define QT3DS_APPLICATION_H +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Utils.h" +#include "Qt3DSKernelTypes.h" +#include "Qt3DSMetadata.h" +#include "QtQml/qjsengine.h" + +namespace Q3DStudio { +class IRuntimeFactory; +class IRuntimeFactoryCore; +class CRuntime; +class CPresentation; +class CInputEngine; +class IAudioPlayer; +} + +namespace qt3ds { +namespace state { +namespace debugger { +class IDebugger; +class ISceneGraphRuntimeDebugger; +} +} +} + +namespace qt3ds { +class Qt3DSAssetVisitor; +namespace runtime { +using namespace qt3ds::foundation; +using namespace qt3ds; + +class IElementAllocator; +class IActivityZoneManager; + +class CAppStr : public eastl::basic_string +{ + typedef eastl::basic_string TBase; + +public: + CAppStr(NVAllocatorCallback &alloc, const char8_t *inStr = NULL); + CAppStr(const CAppStr &inOther); + CAppStr(); + CAppStr &operator=(const CAppStr &inOther); +}; + +class IApplication; + +class IAppRunnable : public NVRefCounted +{ +public: + virtual void Run() = 0; +}; + +class QT3DS_AUTOTEST_EXPORT IApplicationCore : public NVRefCounted +{ +public: + // threadsafe call. + virtual void QueueForMainThread(IAppRunnable &inRunnable) = 0; + + // The directory that contains the executable and the root resource path + virtual CRegisteredString GetApplicationDirectory() const = 0; + // Directory that contained the UIA file. + virtual CRegisteredString GetProjectDirectory() const = 0; + // Directory where we will copy shared object files to before we load them. + // This is specifically for android and the case where the place where the project exists + // is not always the place where we can load the project. + virtual CRegisteredString GetDllDir() const = 0; + virtual void SetDllDir(const char *inDllDir) = 0; + virtual Q3DStudio::THashValue HashString(const char *inStr) = 0; + virtual const char *ReverseHash(Q3DStudio::THashValue theValue) = 0; + + virtual Q3DStudio::IRuntimeMetaData &GetMetaData() = 0; + // Element handles are unique across all presentations. + virtual Q3DStudio::TElement *GetElementByHandle(Q3DStudio::UINT32 inHandle) = 0; + // Passing in NULL gets you zero as the return handle. + virtual Q3DStudio::UINT32 GetHandleForElement(Q3DStudio::TElement *inElement) = 0; + + virtual Q3DStudio::IRuntimeFactoryCore &GetRuntimeFactoryCore() = 0; + virtual void HideFPS(bool flag) = 0; + + virtual qt3ds::state::debugger::ISceneGraphRuntimeDebugger &GetSceneGraphDebugger() = 0; + virtual qt3ds::state::debugger::IDebugger &GetStateDebugger() = 0; + virtual IActivityZoneManager &GetActivityZoneManager() = 0; + virtual IElementAllocator &GetElementAllocator() = 0; + + // Debugging is disabled by default. + // This is expected be be called before load and will not immediately connect. + // until we have a valid presentation directory (which is required for the debug system + // at the other end of the connection). + // listen - either list for a connection else actively connect to a server. + // inServer - if listen is false, then the server addr to connect to. Ignored if server is + // true + // inPort - If listen is false, the port on server to connect to, else port to open up + // socket on. + virtual void EnableDebugging(bool inListen = false, const char8_t *inServer = NULL, + int inPort = 0) = 0; + + // State machine is enabled by default + // Disable state machine is meant to disable internal statemachine, but may plug in an + // external statemachine + virtual void DisableStateMachine() = 0; + + // nonblocking call to begin loading, loads uia file alone and returns. + virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; + + // blocking call to end all loading threads and such/wait till finished + virtual void EndLoad() = 0; + // Will EndLoad cause nontrivial blocking. + // Runs any queued runnables. + virtual bool HasCompletedLoading() = 0; + + virtual void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) = 0; + + // will force loading to end if endLoad hasn't been called yet. Will fire off loading + // of resources that need to be uploaded to opengl. Maintains reference to runtime factory + virtual IApplication &CreateApplication(Q3DStudio::CInputEngine &inInputEngine, + Q3DStudio::IAudioPlayer *inAudioPlayer, + Q3DStudio::IRuntimeFactory &inFactory) = 0; + + // maintains reference to runtime factory core. AppDir is where the executable is located; + // the system will expect res directory + // next to executable. + static IApplicationCore &CreateApplicationCore(Q3DStudio::IRuntimeFactoryCore &inFactory, + const char8_t *inApplicationDirectory); + static bool isPickingEvent(Q3DStudio::TEventCommandHash event); +}; + +struct DataInputControlledAttribute +{ + QByteArray elementPath; + QVector attributeName; + Q3DStudio::EAttributeType propertyType = Q3DStudio::ATTRIBUTETYPE_NONE; +}; + +enum DataInputType { + DataInputTypeInvalid = 0, + DataInputTypeRangedNumber, + DataInputTypeString, + DataInputTypeFloat, + DataInputTypeEvaluator, + DataInputTypeBoolean, + DataInputTypeVector3, + DataInputTypeVector2, + DataInputTypeVariant +}; + +struct DataInputDef +{ + QVector controlledAttributes; + DataInputType type = DataInputTypeInvalid; + float min = 0.0f; + float max = 0.0f; + QString evaluator; + QJSValue evalFunc; // keep both evaluator string and JS function + // to avoid having to evaluate string several times + QVariant value; // most recently set value + // evaluator datainputs that need to re-evaluate when this datainput changes value + QVector dependents; + +}; + +typedef QMap DataInputMap; + +class IApplication : public IApplicationCore +{ +public: + virtual Q3DStudio::IRuntimeFactory &GetRuntimeFactory() const = 0; + + virtual void SetFrameCount(Q3DStudio::INT32 inFrameCount) = 0; + virtual Q3DStudio::INT32 GetFrameCount() = 0; + + // Allow overriding the global wall time. This way animations can be + // advanced at an arbitrary rate when rendering offscreen. Set to 0 to + // disable (the default). + virtual void SetTimeMilliSecs(Q3DStudio::INT64 inMilliSecs) = 0; + + virtual Q3DStudio::INT64 GetTimeMilliSecs() = 0; + virtual void ResetTime() = 0; + + // Setup during UpdateAndRender. Returns 0 for first frame. + virtual double GetMillisecondsSinceLastFrame() = 0; + + virtual Q3DStudio::CInputEngine &GetInputEngine() = 0; + + virtual Q3DStudio::CPresentation *GetPrimaryPresentation() = 0; + + virtual Q3DStudio::CPresentation *GetPresentationById(const char8_t *inId) = 0; + + virtual QList GetPresentationList() = 0; + + // Update all the presentations and render them. Called exactly once per frame. + virtual void UpdateAndRender() = 0; + + virtual bool IsApplicationDirty() = 0; + + virtual void MarkApplicationDirty() = 0; + + virtual Q3DStudio::IAudioPlayer &GetAudioPlayer() = 0; + + virtual bool createSuccessful() = 0; + + virtual DataInputMap &dataInputMap() = 0; +}; +} +} + +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSApplicationValues.h b/src/Runtime/Source/runtime/Qt3DSApplicationValues.h new file mode 100644 index 00000000..80e8f73f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSApplicationValues.h @@ -0,0 +1,369 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#include "Qt3DSApplication.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" +#include "foundation/StringTable.h" + +namespace qt3ds { + +class Qt3DSAssetVisitor +{ +public: + virtual void visit(const char *path) = 0; + virtual void visit(const char *type, const char *id, const char *src, const char *args) = 0; +}; + +namespace runtime { + + using qt3ds::foundation::CRegisteredString; + + struct AssetValueTypes + { + enum Enum { + NoAssetValue = 0, + Presentation, + SCXML, + RenderPlugin, + Behavior, + QmlPresentation, + }; + }; + struct SAssetBase + { + CRegisteredString m_Id; + CRegisteredString m_Src; + CRegisteredString m_Args; + SAssetBase(CRegisteredString inId = CRegisteredString(), + CRegisteredString inSrc = CRegisteredString(), + CRegisteredString inArgs = CRegisteredString()) + : m_Id(inId) + , m_Src(inSrc) + , m_Args(inArgs) + { + } + bool operator==(const SAssetBase &inOther) const + { + return m_Id == inOther.m_Id && m_Src == inOther.m_Src + && m_Args == inOther.m_Args; + } + template + void Remap(TRemapper &item) + { + item.Remap(m_Id); + item.Remap(m_Src); + item.Remap(m_Args); + } + virtual const char *Type() const + { + return nullptr; + } + }; + + struct SPresentationAsset : public SAssetBase + { + Q3DStudio::CPresentation *m_Presentation; + bool m_Active; + + SPresentationAsset(CRegisteredString inId = CRegisteredString(), + CRegisteredString inRelPath = CRegisteredString(), + Q3DStudio::CPresentation *inPresentation = NULL) + : SAssetBase(inId, inRelPath, CRegisteredString()) + , m_Presentation(inPresentation) + , m_Active(true) + { + } + + bool operator==(const SPresentationAsset &inOther) const + { + return SAssetBase::operator==(inOther) && m_Presentation == inOther.m_Presentation + && m_Active == inOther.m_Active; + } + + template + void Remap(TRemapper &item) + { + m_Presentation = NULL; + SAssetBase::Remap(item); + } + const char *Type() const override + { + return "presentation"; + } + }; + + struct SSCXMLAsset : public SAssetBase + { + CRegisteredString m_Datamodel; + SSCXMLAsset(CRegisteredString inId = CRegisteredString(), + CRegisteredString inRelPath = CRegisteredString(), + CRegisteredString inDatamodel = CRegisteredString()) + : SAssetBase(inId, inRelPath, CRegisteredString()) + , m_Datamodel(inDatamodel) + { + } + bool operator==(const SSCXMLAsset &inOther) const + { + return SAssetBase::operator==(inOther) && m_Datamodel == inOther.m_Datamodel; + } + template + void Remap(TRemapper &item) + { + SAssetBase::Remap(item); + item.Remap(m_Datamodel); + } + const char *Type() const override + { + return "scxml"; + } + }; + + struct SRenderPluginAsset : public SAssetBase + { + SRenderPluginAsset(CRegisteredString inId = CRegisteredString(), + CRegisteredString inRelPath = CRegisteredString(), + CRegisteredString inArgs = CRegisteredString()) + : SAssetBase(inId, inRelPath, inArgs) + { + } + const char *Type() const override + { + return "renderplugin"; + } + }; + + struct SQmlPresentationAsset : public SAssetBase + { + SQmlPresentationAsset(CRegisteredString inId = CRegisteredString(), + CRegisteredString inRelPath = CRegisteredString(), + CRegisteredString inArgs = CRegisteredString()) + : SAssetBase(inId, inRelPath, inArgs) + { + } + const char *Type() const override + { + return "presentation-qml"; + } + }; + + struct SBehaviorAsset : public SAssetBase + { + Q3DStudio::INT32 m_Handle; + SBehaviorAsset(CRegisteredString inId = CRegisteredString(), + CRegisteredString inRelPath = CRegisteredString(), + Q3DStudio::INT32 inHandle = 0) + : SAssetBase(inId, inRelPath, CRegisteredString()) + , m_Handle(inHandle) + { + } + bool operator==(const SBehaviorAsset &inOther) const + { + return SAssetBase::operator==(inOther) && m_Handle == inOther.m_Handle; + } + template + void Remap(TRemapper &item) + { + m_Handle = -1; + SAssetBase::Remap(item); + } + const char *Type() const override + { + return "behaviour"; + } + }; +} +} + +namespace qt3ds { +namespace foundation { + template <> + struct DestructTraits + { + void destruct(qt3ds::runtime::SPresentationAsset &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::runtime::SSCXMLAsset &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::runtime::SRenderPluginAsset &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::runtime::SBehaviorAsset &) {} + }; +} +} + +namespace qt3ds { +namespace runtime { + + // Force compile error if unsupported datatype requested + template + struct SAssetValueTypeMap + { + }; + + template <> + struct SAssetValueTypeMap + { + static AssetValueTypes::Enum GetType() { return AssetValueTypes::Presentation; } + }; + template <> + struct SAssetValueTypeMap + { + static AssetValueTypes::Enum GetType() { return AssetValueTypes::SCXML; } + }; + template <> + struct SAssetValueTypeMap + { + static AssetValueTypes::Enum GetType() { return AssetValueTypes::RenderPlugin; } + }; + template <> + struct SAssetValueTypeMap + { + static AssetValueTypes::Enum GetType() { return AssetValueTypes::QmlPresentation; } + }; + template <> + struct SAssetValueTypeMap + { + static AssetValueTypes::Enum GetType() { return AssetValueTypes::Behavior; } + }; + + struct SAssetValueUnionTraits + { + typedef AssetValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(SPresentationAsset), + }; + + static TIdType getNoDataId() { return AssetValueTypes::NoAssetValue; } + + template + static TIdType getType() + { + return SAssetValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case AssetValueTypes::Presentation: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::SCXML: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::RenderPlugin: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::Behavior: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::QmlPresentation: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case AssetValueTypes::NoAssetValue: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case AssetValueTypes::Presentation: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::SCXML: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::RenderPlugin: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::Behavior: + return inVisitor(*NVUnionCast(inData)); + case AssetValueTypes::QmlPresentation: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case AssetValueTypes::NoAssetValue: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SAssetValueUnionTraits::TBufferSize> + TAssetValueUnionType; + + struct SAssetValue : public TAssetValueUnionType + { + SAssetValue() {} + + SAssetValue(const SAssetValue &inOther) + : TAssetValueUnionType(static_cast(inOther)) + { + } + + template + SAssetValue(const TDataType &inDt) + : TAssetValueUnionType(inDt) + { + } + + SAssetValue &operator=(const SAssetValue &inOther) + { + TAssetValueUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SAssetValue &inOther) const + { + return TAssetValueUnionType::operator==(inOther); + } + bool operator!=(const SAssetValue &inOther) const + { + return TAssetValueUnionType::operator!=(inOther); + } + + bool empty() const { return getType() == AssetValueTypes::NoAssetValue; } + + CRegisteredString GetSource() + { + if (empty()) + return CRegisteredString(); + return reinterpret_cast(m_Data)->m_Src; + } + }; +} +} diff --git a/src/Runtime/Source/runtime/Qt3DSAttributeHashes.cpp b/src/Runtime/Source/runtime/Qt3DSAttributeHashes.cpp new file mode 100644 index 00000000..1409901f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSAttributeHashes.cpp @@ -0,0 +1,289 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSAttributeHashes.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +// !!!!! AUTOGENERATED CODE - DO NOT MODIFY MANUALLY !!!!! + +// Run the AttributeHashes project to regenerate this file from Attributehashes.txt list + + + +/// Function providing reverse hash lookup +const char *GetAttributeString(const EAttribute inAttribute) +{ + switch (inAttribute) { + case ATTRIBUTE_NAME: return "name"; + case ATTRIBUTE_TYPE: return "type"; + case ATTRIBUTE_OPACITY: return "opacity"; + case ATTRIBUTE_STARTTIME: return "starttime"; + case ATTRIBUTE_ENDTIME: return "endtime"; + case ATTRIBUTE_SOURCEPATH: return "sourcepath"; + case ATTRIBUTE_IMPORTID: return "importid"; + case ATTRIBUTE_EYEBALL: return "eyeball"; + case ATTRIBUTE_POSITION: return "position"; + case ATTRIBUTE_POSITION_X: return "position.x"; + case ATTRIBUTE_POSITION_Y: return "position.y"; + case ATTRIBUTE_POSITION_Z: return "position.z"; + case ATTRIBUTE_ROTATION: return "rotation"; + case ATTRIBUTE_ROTATION_X: return "rotation.x"; + case ATTRIBUTE_ROTATION_Y: return "rotation.y"; + case ATTRIBUTE_ROTATION_Z: return "rotation.z"; + case ATTRIBUTE_SCALE: return "scale"; + case ATTRIBUTE_SCALE_X: return "scale.x"; + case ATTRIBUTE_SCALE_Y: return "scale.y"; + case ATTRIBUTE_SCALE_Z: return "scale.z"; + case ATTRIBUTE_PIVOT: return "pivot"; + case ATTRIBUTE_PIVOT_X: return "pivot.x"; + case ATTRIBUTE_PIVOT_Y: return "pivot.y"; + case ATTRIBUTE_PIVOT_Z: return "pivot.z"; + case ATTRIBUTE_ROTATIONORDER: return "rotationorder"; + case ATTRIBUTE_ORIENTATION: return "orientation"; + case ATTRIBUTE_SHADOWCASTER: return "shadowcaster"; + case ATTRIBUTE_TESSELLATION: return "tessellation"; + case ATTRIBUTE_EDGETESS: return "edgetess"; + case ATTRIBUTE_INNERTESS: return "innertess"; + case ATTRIBUTE_ORTHOGRAPHIC: return "orthographic"; + case ATTRIBUTE_CLIPNEAR: return "clipnear"; + case ATTRIBUTE_CLIPFAR: return "clipfar"; + case ATTRIBUTE_FOV: return "fov"; + case ATTRIBUTE_FOVHORIZONTAL: return "fovhorizontal"; + case ATTRIBUTE_SCALEMODE: return "scalemode"; + case ATTRIBUTE_SCALEANCHOR: return "scaleanchor"; + case ATTRIBUTE_BRIGHTNESS: return "brightness"; + case ATTRIBUTE_LINEARFADE: return "linearfade"; + case ATTRIBUTE_EXPFADE: return "expfade"; + case ATTRIBUTE_LIGHTTYPE: return "lighttype"; + case ATTRIBUTE_SCOPE: return "scope"; + case ATTRIBUTE_LIGHTDIFFUSE: return "lightdiffuse"; + case ATTRIBUTE_LIGHTDIFFUSE_R: return "lightdiffuse.r"; + case ATTRIBUTE_LIGHTDIFFUSE_G: return "lightdiffuse.g"; + case ATTRIBUTE_LIGHTDIFFUSE_B: return "lightdiffuse.b"; + case ATTRIBUTE_LIGHTAMBIENT_R: return "lightambient.r"; + case ATTRIBUTE_LIGHTAMBIENT: return "lightambient"; + case ATTRIBUTE_LIGHTAMBIENT_G: return "lightambient.g"; + case ATTRIBUTE_LIGHTAMBIENT_B: return "lightambient.b"; + case ATTRIBUTE_LIGHTSPECULAR: return "lightspecular"; + case ATTRIBUTE_LIGHTSPECULAR_R: return "lightspecular.r"; + case ATTRIBUTE_LIGHTSPECULAR_G: return "lightspecular.g"; + case ATTRIBUTE_LIGHTSPECULAR_B: return "lightspecular.b"; + case ATTRIBUTE_AREAWIDTH: return "areawidth"; + case ATTRIBUTE_AREAHEIGHT: return "areaheight"; + case ATTRIBUTE_CASTSHADOW: return "castshadow"; + case ATTRIBUTE_SHDWBIAS: return "shdwbias"; + case ATTRIBUTE_SHDWFACTOR: return "shdwfactor"; + case ATTRIBUTE_SHDWMAPRES: return "shdwmapres"; + case ATTRIBUTE_SHDWMAPFAR: return "shdwmapfar"; + case ATTRIBUTE_SHDWMAPFOV: return "shdwmapfov"; + case ATTRIBUTE_SHDWFILTER: return "shdwfilter"; + case ATTRIBUTE_LIGHTMAPINDIRECT: return "lightmapindirect"; + case ATTRIBUTE_LIGHTMAPRADIOSITY: return "lightmapradiosity"; + case ATTRIBUTE_LIGHTMAPSHADOW: return "lightmapshadow"; + case ATTRIBUTE_IBLPROBE: return "iblprobe"; + case ATTRIBUTE_SHADERLIGHTING: return "shaderlighting"; + case ATTRIBUTE_EMISSIVEPOWER: return "emissivepower"; + case ATTRIBUTE_EMISSIVECOLOR: return "emissivecolor"; + case ATTRIBUTE_EMISSIVECOLOR_R: return "emissivecolor.r"; + case ATTRIBUTE_EMISSIVECOLOR_G: return "emissivecolor.g"; + case ATTRIBUTE_EMISSIVECOLOR_B: return "emissivecolor.b"; + case ATTRIBUTE_DIFFUSE: return "diffuse"; + case ATTRIBUTE_DIFFUSE_R: return "diffuse.r"; + case ATTRIBUTE_DIFFUSE_G: return "diffuse.g"; + case ATTRIBUTE_DIFFUSE_B: return "diffuse.b"; + case ATTRIBUTE_SPECULARMAP: return "specularmap"; + case ATTRIBUTE_SPECULARMODEL: return "specularmodel"; + case ATTRIBUTE_SPECULARTINT: return "speculartint"; + case ATTRIBUTE_SPECULARTINT_R: return "speculartint.r"; + case ATTRIBUTE_SPECULARTINT_G: return "speculartint.g"; + case ATTRIBUTE_SPECULARTINT_B: return "speculartint.b"; + case ATTRIBUTE_IOR: return "ior"; + case ATTRIBUTE_FRESNELPOWER: return "fresnelPower"; + case ATTRIBUTE_SPECULARAMOUNT: return "specularamount"; + case ATTRIBUTE_SPECULARROUGHNESS: return "specularroughness"; + case ATTRIBUTE_ROUGHNESSMAP: return "roughnessmap"; + case ATTRIBUTE_BLENDMODE: return "blendmode"; + case ATTRIBUTE_CULLING: return "culling"; + case ATTRIBUTE_ZBUFFERWRITE: return "zbufferwrite"; + case ATTRIBUTE_DIFFUSEMAP: return "diffusemap"; + case ATTRIBUTE_DIFFUSEMAP2: return "diffusemap2"; + case ATTRIBUTE_DIFFUSEMAP3: return "diffusemap3"; + case ATTRIBUTE_SPECULARREFLECTION: return "specularreflection"; + case ATTRIBUTE_OPACITYMAP: return "opacitymap"; + case ATTRIBUTE_EMISSIVEMAP: return "emissivemap"; + case ATTRIBUTE_EMISSIVEMAP2: return "emissivemap2"; + case ATTRIBUTE_BUMPMAP: return "bumpmap"; + case ATTRIBUTE_BUMPAMOUNT: return "bumpamount"; + case ATTRIBUTE_NORMALMAP: return "normalmap"; + case ATTRIBUTE_DISPLACEMENTMAP: return "displacementmap"; + case ATTRIBUTE_DISPLACEAMOUNT: return "displaceamount"; + case ATTRIBUTE_TRANSLUCENCYMAP: return "translucencymap"; + case ATTRIBUTE_TRANSLUCENTFALLOFF: return "translucentfalloff"; + case ATTRIBUTE_DIFFUSELIGHTWRAP: return "diffuselightwrap"; + case ATTRIBUTE_REFERENCEDMATERIAL: return "referencedmaterial"; + case ATTRIBUTE_VERTEXCOLORS: return "vertexcolors"; + case ATTRIBUTE_ROTATIONUV: return "rotationuv"; + case ATTRIBUTE_POSITIONU: return "positionu"; + case ATTRIBUTE_POSITIONV: return "positionv"; + case ATTRIBUTE_SCALEU: return "scaleu"; + case ATTRIBUTE_SCALEV: return "scalev"; + case ATTRIBUTE_PIVOTU: return "pivotu"; + case ATTRIBUTE_PIVOTV: return "pivotv"; + case ATTRIBUTE_TILINGMODEHORZ: return "tilingmodehorz"; + case ATTRIBUTE_TILINGMODEVERT: return "tilingmodevert"; + case ATTRIBUTE_MAPPINGTYPE: return "mappingtype"; + case ATTRIBUTE_MAPPINGMODE: return "mappingmode"; + case ATTRIBUTE_SUBPRESENTATION: return "subpresentation"; + case ATTRIBUTE_URI: return "uri"; + case ATTRIBUTE_TRANSPARENT: return "transparent"; + case ATTRIBUTE_PROGRESSIVEAA: return "progressiveaa"; + case ATTRIBUTE_MULTISAMPLEAA: return "multisampleaa"; + case ATTRIBUTE_TEMPORALAA: return "temporalaa"; + case ATTRIBUTE_BLENDTYPE: return "blendtype"; + case ATTRIBUTE_HORZFIELDS: return "horzfields"; + case ATTRIBUTE_LEFT: return "left"; + case ATTRIBUTE_LEFTUNITS: return "leftunits"; + case ATTRIBUTE_WIDTH: return "width"; + case ATTRIBUTE_WIDTHUNITS: return "widthunits"; + case ATTRIBUTE_RIGHT: return "right"; + case ATTRIBUTE_RIGHTUNITS: return "rightunits"; + case ATTRIBUTE_VERTFIELDS: return "vertfields"; + case ATTRIBUTE_TOP: return "top"; + case ATTRIBUTE_TOPUNITS: return "topunits"; + case ATTRIBUTE_HEIGHT: return "height"; + case ATTRIBUTE_HEIGHTUNITS: return "heightunits"; + case ATTRIBUTE_BOTTOM: return "bottom"; + case ATTRIBUTE_BOTTOMUNITS: return "bottomunits"; + case ATTRIBUTE_AOSTRENGTH: return "aostrength"; + case ATTRIBUTE_AODISTANCE: return "aodistance"; + case ATTRIBUTE_AOSOFTNESS: return "aosoftness"; + case ATTRIBUTE_AOBIAS: return "aobias"; + case ATTRIBUTE_AOSAMPLERATE: return "aosamplerate"; + case ATTRIBUTE_AODITHER: return "aodither"; + case ATTRIBUTE_SHADOWSTRENGTH: return "shadowstrength"; + case ATTRIBUTE_SHADOWDIST: return "shadowdist"; + case ATTRIBUTE_SHADOWSOFTNESS: return "shadowsoftness"; + case ATTRIBUTE_SHADOWBIAS: return "shadowbias"; + case ATTRIBUTE_LIGHTPROBE: return "lightprobe"; + case ATTRIBUTE_PROBEBRIGHT: return "probebright"; + case ATTRIBUTE_FASTIBL: return "fastibl"; + case ATTRIBUTE_PROBEHORIZON: return "probehorizon"; + case ATTRIBUTE_PROBEFOV: return "probefov"; + case ATTRIBUTE_LIGHTPROBE2: return "lightprobe2"; + case ATTRIBUTE_PROBE2FADE: return "probe2fade"; + case ATTRIBUTE_PROBE2WINDOW: return "probe2window"; + case ATTRIBUTE_PROBE2POS: return "probe2pos"; + case ATTRIBUTE_DISABLEDEPTHTEST: return "disabledepthtest"; + case ATTRIBUTE_DISABLEDEPTHPREPASS: return "disabledepthprepass"; + case ATTRIBUTE_TEXTCOLOR: return "textcolor"; + case ATTRIBUTE_TEXTCOLOR_R: return "textcolor.r"; + case ATTRIBUTE_TEXTCOLOR_G: return "textcolor.g"; + case ATTRIBUTE_TEXTCOLOR_B: return "textcolor.b"; + case ATTRIBUTE_SIZE: return "size"; + case ATTRIBUTE_FONT: return "font"; + case ATTRIBUTE_DROPSHADOW: return "dropshadow"; + case ATTRIBUTE_DROPSHADOWSTRENGTH: return "dropshadowstrength"; + case ATTRIBUTE_DROPSHADOWOFFSET: return "dropshadowoffset"; + case ATTRIBUTE_DROPSHADOWOFFSETX: return "dropshadowoffsetx"; + case ATTRIBUTE_DROPSHADOWOFFSETY: return "dropshadowoffsety"; + case ATTRIBUTE_DROPSHADOWHORZALIGN: return "dropshadowhorzalign"; + case ATTRIBUTE_DROPSHADOWVERTALIGN: return "dropshadowvertalign"; + case ATTRIBUTE_BOUNDINGBOX: return "boundingbox"; + case ATTRIBUTE_BOUNDINGBOX_X: return "boundingbox.x"; + case ATTRIBUTE_BOUNDINGBOX_Y: return "boundingbox.y"; + case ATTRIBUTE_ELIDE: return "elide"; + case ATTRIBUTE_TRACKING: return "tracking"; + case ATTRIBUTE_LEADING: return "leading"; + case ATTRIBUTE_RENDERSTYLE: return "renderstyle"; + case ATTRIBUTE_TEXTSTRING: return "textstring"; + case ATTRIBUTE_BACKCOLOR_R: return "backcolor.r"; + case ATTRIBUTE_BACKCOLOR_G: return "backcolor.g"; + case ATTRIBUTE_BACKCOLOR_B: return "backcolor.b"; + case ATTRIBUTE_TEXTTYPE: return "texttype"; + case ATTRIBUTE_USEBACKCOLOR: return "usebackcolor"; + case ATTRIBUTE_WORDWRAP: return "wordwrap"; + case ATTRIBUTE_HORZSCROLL: return "horzscroll"; + case ATTRIBUTE_HORZALIGN: return "horzalign"; + case ATTRIBUTE_VERTSCROLL: return "vertscroll"; + case ATTRIBUTE_VERTALIGN: return "vertalign"; + case ATTRIBUTE_BOXHEIGHT: return "boxheight"; + case ATTRIBUTE_BOXWIDTH: return "boxwidth"; + case ATTRIBUTE_REMOTESTRINGSOURCE: return "remotestringsource"; + case ATTRIBUTE_CACHEDTEXTSTRING: return "cachedtextstring"; + case ATTRIBUTE_ENABLEACCELERATEDFONT: return "enableacceleratedfont"; + case ATTRIBUTE_BEHAVIORSCRIPTS: return "BehaviorScripts"; + case ATTRIBUTE_UICCUSTOMOBJTYPE: return "UICCustomObjType"; + case ATTRIBUTE_BGCOLORENABLE: return "bgcolorenable"; + case ATTRIBUTE_BACKGROUND: return "background"; + case ATTRIBUTE_BACKGROUNDCOLOR_R: return "backgroundcolor.r"; + case ATTRIBUTE_BACKGROUNDCOLOR_G: return "backgroundcolor.g"; + case ATTRIBUTE_BACKGROUNDCOLOR_B: return "backgroundcolor.b"; + case ATTRIBUTE_PATHTYPE: return "pathtype"; + case ATTRIBUTE_LINEARERROR: return "linearerror"; + case ATTRIBUTE_EDGETESSAMOUNT: return "edgetessamount"; + case ATTRIBUTE_INNERTESSAMOUNT: return "innertessamount"; + case ATTRIBUTE_BEGINCAP: return "begincap"; + case ATTRIBUTE_BEGINCAPOFFSET: return "begincapoffset"; + case ATTRIBUTE_BEGINCAPOPACITY: return "begincapopacity"; + case ATTRIBUTE_BEGINCAPWIDTH: return "begincapwidth"; + case ATTRIBUTE_ENDCAP: return "endcap"; + case ATTRIBUTE_ENDCAPOFFSET: return "endcapoffset"; + case ATTRIBUTE_ENDCAPOPACITY: return "endcapopacity"; + case ATTRIBUTE_ENDCAPWIDTH: return "endcapwidth"; + case ATTRIBUTE_PAINTSTYLE: return "paintstyle"; + case ATTRIBUTE_CLOSED: return "closed"; + case ATTRIBUTE_INCOMINGANGLE: return "incomingangle"; + case ATTRIBUTE_INCOMINGDISTANCE: return "incomingdistance"; + case ATTRIBUTE_OUTGOINGDISTANCE: return "outgoingdistance"; + case ATTRIBUTE_PARTICLETYPE: return "particletype"; + case ATTRIBUTE_MAXPARTICLES: return "maxparticles"; + case ATTRIBUTE_PARTICLESIZE: return "particlesize"; + case ATTRIBUTE_LIFETIME: return "lifetime"; + case ATTRIBUTE_CONTROLLEDPROPERTY: return "controlledproperty"; + case ATTRIBUTE_QT_IO: return "qt.io"; + default: { + static char s_UnknownHash[16]; + sprintf(s_UnknownHash, "(0x%08X)", inAttribute); + return s_UnknownHash; + } + } +} + +} // namespace Q3DStudio + diff --git a/src/Runtime/Source/runtime/Qt3DSAttributeHashes.h b/src/Runtime/Source/runtime/Qt3DSAttributeHashes.h new file mode 100644 index 00000000..02dda069 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSAttributeHashes.h @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +// !!!!! AUTOGENERATED CODE - DO NOT MODIFY MANUALLY !!!!! + +// Run the AttributeHashes project to regenerate this file from Attributehashes.txt list + +/// Key for the CElement attribute-value pair +enum EAttribute { + ATTRIBUTE_NAME = 0x02B79D95, // name + ATTRIBUTE_TYPE = 0x005F9806, // type + ATTRIBUTE_OPACITY = 0x0191C315, // opacity + ATTRIBUTE_STARTTIME = 0x010A57B1, // starttime + ATTRIBUTE_ENDTIME = 0x003BF5F8, // endtime + ATTRIBUTE_SOURCEPATH = 0x0009EA60, // sourcepath + ATTRIBUTE_IMPORTID = 0x008F7900, // importid + ATTRIBUTE_EYEBALL = 0x02F454F0, // eyeball + ATTRIBUTE_POSITION = 0x00E9B7D7, // position + ATTRIBUTE_POSITION_X = 0x027C230D, // position.x + ATTRIBUTE_POSITION_Y = 0x027D234C, // position.y + ATTRIBUTE_POSITION_Z = 0x027E238B, // position.z + ATTRIBUTE_ROTATION = 0x03E51862, // rotation + ATTRIBUTE_ROTATION_X = 0x0239EE18, // rotation.x + ATTRIBUTE_ROTATION_Y = 0x023AEE57, // rotation.y + ATTRIBUTE_ROTATION_Z = 0x023BEE96, // rotation.z + ATTRIBUTE_SCALE = 0x01012856, // scale + ATTRIBUTE_SCALE_X = 0x0065440C, // scale.x + ATTRIBUTE_SCALE_Y = 0x0066444B, // scale.y + ATTRIBUTE_SCALE_Z = 0x0067448A, // scale.z + ATTRIBUTE_PIVOT = 0x009E907E, // pivot + ATTRIBUTE_PIVOT_X = 0x03811834, // pivot.x + ATTRIBUTE_PIVOT_Y = 0x03821873, // pivot.y + ATTRIBUTE_PIVOT_Z = 0x038318B2, // pivot.z + ATTRIBUTE_ROTATIONORDER = 0x03CE5F70, // rotationorder + ATTRIBUTE_ORIENTATION = 0x001A90B0, // orientation + ATTRIBUTE_SHADOWCASTER = 0x0363F874, // shadowcaster + ATTRIBUTE_TESSELLATION = 0x0335861F, // tessellation + ATTRIBUTE_EDGETESS = 0x023933D2, // edgetess + ATTRIBUTE_INNERTESS = 0x01529259, // innertess + ATTRIBUTE_ORTHOGRAPHIC = 0x0244BB70, // orthographic + ATTRIBUTE_CLIPNEAR = 0x0068FF28, // clipnear + ATTRIBUTE_CLIPFAR = 0x037EF699, // clipfar + ATTRIBUTE_FOV = 0x00D60213, // fov + ATTRIBUTE_FOVHORIZONTAL = 0x01BDB34F, // fovhorizontal + ATTRIBUTE_SCALEMODE = 0x01FD2FD3, // scalemode + ATTRIBUTE_SCALEANCHOR = 0x02CFCF41, // scaleanchor + ATTRIBUTE_BRIGHTNESS = 0x0230D3AF, // brightness + ATTRIBUTE_LINEARFADE = 0x0104E9FF, // linearfade + ATTRIBUTE_EXPFADE = 0x006B9267, // expfade + ATTRIBUTE_LIGHTTYPE = 0x0033F1D0, // lighttype + ATTRIBUTE_SCOPE = 0x0258D0CC, // scope + ATTRIBUTE_LIGHTDIFFUSE = 0x01246FD4, // lightdiffuse + ATTRIBUTE_LIGHTDIFFUSE_R = 0x035AAB10, // lightdiffuse.r + ATTRIBUTE_LIGHTDIFFUSE_G = 0x034FA85B, // lightdiffuse.g + ATTRIBUTE_LIGHTDIFFUSE_B = 0x034AA720, // lightdiffuse.b + ATTRIBUTE_LIGHTAMBIENT_R = 0x0179AD1A, // lightambient.r + ATTRIBUTE_LIGHTAMBIENT = 0x00DA56DE, // lightambient + ATTRIBUTE_LIGHTAMBIENT_G = 0x016EAA65, // lightambient.g + ATTRIBUTE_LIGHTAMBIENT_B = 0x0169A92A, // lightambient.b + ATTRIBUTE_LIGHTSPECULAR = 0x03E39A07, // lightspecular + ATTRIBUTE_LIGHTSPECULAR_R = 0x0241EBC3, // lightspecular.r + ATTRIBUTE_LIGHTSPECULAR_G = 0x0236E90E, // lightspecular.g + ATTRIBUTE_LIGHTSPECULAR_B = 0x0231E7D3, // lightspecular.b + ATTRIBUTE_AREAWIDTH = 0x005A8BE7, // areawidth + ATTRIBUTE_AREAHEIGHT = 0x00334D2C, // areaheight + ATTRIBUTE_CASTSHADOW = 0x0335FD81, // castshadow + ATTRIBUTE_SHDWBIAS = 0x0125E79F, // shdwbias + ATTRIBUTE_SHDWFACTOR = 0x01B11BE9, // shdwfactor + ATTRIBUTE_SHDWMAPRES = 0x01E53834, // shdwmapres + ATTRIBUTE_SHDWMAPFAR = 0x019A30FD, // shdwmapfar + ATTRIBUTE_SHDWMAPFOV = 0x00830B07, // shdwmapfov + ATTRIBUTE_SHDWFILTER = 0x0176E1E0, // shdwfilter + ATTRIBUTE_LIGHTMAPINDIRECT = 0x004F1D6C, // lightmapindirect + ATTRIBUTE_LIGHTMAPRADIOSITY = 0x00AC7C50, // lightmapradiosity + ATTRIBUTE_LIGHTMAPSHADOW = 0x00191F3A, // lightmapshadow + ATTRIBUTE_IBLPROBE = 0x0039FD03, // iblprobe + ATTRIBUTE_SHADERLIGHTING = 0x0068A84F, // shaderlighting + ATTRIBUTE_EMISSIVEPOWER = 0x03D6F9F2, // emissivepower + ATTRIBUTE_EMISSIVECOLOR = 0x00B7AC94, // emissivecolor + ATTRIBUTE_EMISSIVECOLOR_R = 0x039B87D0, // emissivecolor.r + ATTRIBUTE_EMISSIVECOLOR_G = 0x0390851B, // emissivecolor.g + ATTRIBUTE_EMISSIVECOLOR_B = 0x038B83E0, // emissivecolor.b + ATTRIBUTE_DIFFUSE = 0x0105521E, // diffuse + ATTRIBUTE_DIFFUSE_R = 0x015B085A, // diffuse.r + ATTRIBUTE_DIFFUSE_G = 0x015005A5, // diffuse.g + ATTRIBUTE_DIFFUSE_B = 0x014B046A, // diffuse.b + ATTRIBUTE_SPECULARMAP = 0x034CD047, // specularmap + ATTRIBUTE_SPECULARMODEL = 0x039EBE5A, // specularmodel + ATTRIBUTE_SPECULARTINT = 0x03535E02, // speculartint + ATTRIBUTE_SPECULARTINT_R = 0x0399623E, // speculartint.r + ATTRIBUTE_SPECULARTINT_G = 0x038E5F89, // speculartint.g + ATTRIBUTE_SPECULARTINT_B = 0x03895E4E, // speculartint.b + ATTRIBUTE_IOR = 0x00667354, // ior + ATTRIBUTE_FRESNELPOWER = 0x022178B6, // fresnelPower + ATTRIBUTE_SPECULARAMOUNT = 0x01144425, // specularamount + ATTRIBUTE_SPECULARROUGHNESS = 0x03925653, // specularroughness + ATTRIBUTE_ROUGHNESSMAP = 0x01088174, // roughnessmap + ATTRIBUTE_BLENDMODE = 0x01923A6C, // blendmode + ATTRIBUTE_CULLING = 0x03C539F0, // culling + ATTRIBUTE_ZBUFFERWRITE = 0x03E19B3B, // zbufferwrite + ATTRIBUTE_DIFFUSEMAP = 0x00FF8126, // diffusemap + ATTRIBUTE_DIFFUSEMAP2 = 0x0038D4A8, // diffusemap2 + ATTRIBUTE_DIFFUSEMAP3 = 0x0039D4E7, // diffusemap3 + ATTRIBUTE_SPECULARREFLECTION = 0x006B4C12, // specularreflection + ATTRIBUTE_OPACITYMAP = 0x00DA796F, // opacitymap + ATTRIBUTE_EMISSIVEMAP = 0x00F6427B, // emissivemap + ATTRIBUTE_EMISSIVEMAP2 = 0x03476893, // emissivemap2 + ATTRIBUTE_BUMPMAP = 0x024EE11A, // bumpmap + ATTRIBUTE_BUMPAMOUNT = 0x01BC4192, // bumpamount + ATTRIBUTE_NORMALMAP = 0x03BD578B, // normalmap + ATTRIBUTE_DISPLACEMENTMAP = 0x01BCD1FB, // displacementmap + ATTRIBUTE_DISPLACEAMOUNT = 0x01EC1EAF, // displaceamount + ATTRIBUTE_TRANSLUCENCYMAP = 0x01D8F015, // translucencymap + ATTRIBUTE_TRANSLUCENTFALLOFF = 0x0097E985, // translucentfalloff + ATTRIBUTE_DIFFUSELIGHTWRAP = 0x038F6522, // diffuselightwrap + ATTRIBUTE_REFERENCEDMATERIAL = 0x035FDA80, // referencedmaterial + ATTRIBUTE_VERTEXCOLORS = 0x000814EC, // vertexcolors + ATTRIBUTE_ROTATIONUV = 0x012E3A61, // rotationuv + ATTRIBUTE_POSITIONU = 0x01D05AB4, // positionu + ATTRIBUTE_POSITIONV = 0x01D15AF3, // positionv + ATTRIBUTE_SCALEU = 0x001409F5, // scaleu + ATTRIBUTE_SCALEV = 0x00150A34, // scalev + ATTRIBUTE_PIVOTU = 0x03F8ABCD, // pivotu + ATTRIBUTE_PIVOTV = 0x03F9AC0C, // pivotv + ATTRIBUTE_TILINGMODEHORZ = 0x02562203, // tilingmodehorz + ATTRIBUTE_TILINGMODEVERT = 0x03F92B21, // tilingmodevert + ATTRIBUTE_MAPPINGTYPE = 0x02CA9058, // mappingtype + ATTRIBUTE_MAPPINGMODE = 0x002715CF, // mappingmode + ATTRIBUTE_SUBPRESENTATION = 0x03CA7426, // subpresentation + ATTRIBUTE_URI = 0x00296894, // uri + ATTRIBUTE_TRANSPARENT = 0x0316BA2E, // transparent + ATTRIBUTE_PROGRESSIVEAA = 0x019F1955, // progressiveaa + ATTRIBUTE_MULTISAMPLEAA = 0x013D29FD, // multisampleaa + ATTRIBUTE_TEMPORALAA = 0x00212AFE, // temporalaa + ATTRIBUTE_BLENDTYPE = 0x0035B4F5, // blendtype + ATTRIBUTE_HORZFIELDS = 0x02B8A818, // horzfields + ATTRIBUTE_LEFT = 0x0196B9B9, // left + ATTRIBUTE_LEFTUNITS = 0x02F9D2D8, // leftunits + ATTRIBUTE_WIDTH = 0x00C4D65A, // width + ATTRIBUTE_WIDTHUNITS = 0x01D7DF77, // widthunits + ATTRIBUTE_RIGHT = 0x039EAB44, // right + ATTRIBUTE_RIGHTUNITS = 0x0357EF0D, // rightunits + ATTRIBUTE_VERTFIELDS = 0x03462436, // vertfields + ATTRIBUTE_TOP = 0x002F6B0B, // top + ATTRIBUTE_TOPUNITS = 0x03D58806, // topunits + ATTRIBUTE_HEIGHT = 0x00CE9F79, // height + ATTRIBUTE_HEIGHTUNITS = 0x00C91D18, // heightunits + ATTRIBUTE_BOTTOM = 0x00F4EE75, // bottom + ATTRIBUTE_BOTTOMUNITS = 0x0174091C, // bottomunits + ATTRIBUTE_AOSTRENGTH = 0x010F7ED1, // aostrength + ATTRIBUTE_AODISTANCE = 0x01DC349D, // aodistance + ATTRIBUTE_AOSOFTNESS = 0x02CCDC71, // aosoftness + ATTRIBUTE_AOBIAS = 0x01818219, // aobias + ATTRIBUTE_AOSAMPLERATE = 0x0039B568, // aosamplerate + ATTRIBUTE_AODITHER = 0x0274316C, // aodither + ATTRIBUTE_SHADOWSTRENGTH = 0x0039ED5F, // shadowstrength + ATTRIBUTE_SHADOWDIST = 0x038213FA, // shadowdist + ATTRIBUTE_SHADOWSOFTNESS = 0x01F74AFF, // shadowsoftness + ATTRIBUTE_SHADOWBIAS = 0x02CB3EA7, // shadowbias + ATTRIBUTE_LIGHTPROBE = 0x02D47DC6, // lightprobe + ATTRIBUTE_PROBEBRIGHT = 0x029DC5B6, // probebright + ATTRIBUTE_FASTIBL = 0x02559509, // fastibl + ATTRIBUTE_PROBEHORIZON = 0x014DAAF5, // probehorizon + ATTRIBUTE_PROBEFOV = 0x03D66903, // probefov + ATTRIBUTE_LIGHTPROBE2 = 0x00430008, // lightprobe2 + ATTRIBUTE_PROBE2FADE = 0x02ED0742, // probe2fade + ATTRIBUTE_PROBE2WINDOW = 0x016B224E, // probe2window + ATTRIBUTE_PROBE2POS = 0x024B0C0E, // probe2pos + ATTRIBUTE_DISABLEDEPTHTEST = 0x000B8353, // disabledepthtest + ATTRIBUTE_DISABLEDEPTHPREPASS = 0x02AE1EA7, // disabledepthprepass + ATTRIBUTE_TEXTCOLOR = 0x02D9114A, // textcolor + ATTRIBUTE_TEXTCOLOR_R = 0x00E9F186, // textcolor.r + ATTRIBUTE_TEXTCOLOR_G = 0x00DEEED1, // textcolor.g + ATTRIBUTE_TEXTCOLOR_B = 0x00D9ED96, // textcolor.b + ATTRIBUTE_SIZE = 0x00F2C81F, // size + ATTRIBUTE_FONT = 0x03412331, // font + ATTRIBUTE_DROPSHADOW = 0x03E3F231, // dropshadow + ATTRIBUTE_DROPSHADOWSTRENGTH = 0x03F8B7D0, // dropshadowstrength + ATTRIBUTE_DROPSHADOWOFFSET = 0x024A9C5E, // dropshadowoffset + ATTRIBUTE_DROPSHADOWOFFSETX = 0x013298AA, // dropshadowoffsetx + ATTRIBUTE_DROPSHADOWOFFSETY = 0x013398E9, // dropshadowoffsety + ATTRIBUTE_DROPSHADOWHORZALIGN = 0x00D1BC39, // dropshadowhorzalign + ATTRIBUTE_DROPSHADOWVERTALIGN = 0x038D589B, // dropshadowvertalign + ATTRIBUTE_BOUNDINGBOX = 0x02F3B6D9, // boundingbox + ATTRIBUTE_BOUNDINGBOX_X = 0x0272C10F, // boundingbox.x + ATTRIBUTE_BOUNDINGBOX_Y = 0x0273C14E, // boundingbox.y + ATTRIBUTE_ELIDE = 0x022937DD, // elide + ATTRIBUTE_TRACKING = 0x02A25049, // tracking + ATTRIBUTE_LEADING = 0x016A6BDA, // leading + ATTRIBUTE_RENDERSTYLE = 0x03567B85, // renderstyle + ATTRIBUTE_TEXTSTRING = 0x01124062, // textstring + ATTRIBUTE_BACKCOLOR_R = 0x0290CCE0, // backcolor.r + ATTRIBUTE_BACKCOLOR_G = 0x0285CA2B, // backcolor.g + ATTRIBUTE_BACKCOLOR_B = 0x0280C8F0, // backcolor.b + ATTRIBUTE_TEXTTYPE = 0x0240ADD9, // texttype + ATTRIBUTE_USEBACKCOLOR = 0x0243BACB, // usebackcolor + ATTRIBUTE_WORDWRAP = 0x0134B04C, // wordwrap + ATTRIBUTE_HORZSCROLL = 0x005B3CC4, // horzscroll + ATTRIBUTE_HORZALIGN = 0x00BA002A, // horzalign + ATTRIBUTE_VERTSCROLL = 0x00E8B8E2, // vertscroll + ATTRIBUTE_VERTALIGN = 0x03759C8C, // vertalign + ATTRIBUTE_BOXHEIGHT = 0x0079AF8E, // boxheight + ATTRIBUTE_BOXWIDTH = 0x016B7105, // boxwidth + ATTRIBUTE_REMOTESTRINGSOURCE = 0x025DFEEE, // remotestringsource + ATTRIBUTE_CACHEDTEXTSTRING = 0x0095DBA0, // cachedtextstring + ATTRIBUTE_ENABLEACCELERATEDFONT = 0x0053A92D, // enableacceleratedfont + ATTRIBUTE_BEHAVIORSCRIPTS = 0x01DF916A, // BehaviorScripts + ATTRIBUTE_UICCUSTOMOBJTYPE = 0x029F1BCF, // UICCustomObjType + ATTRIBUTE_BGCOLORENABLE = 0x0021EE1F, // bgcolorenable + ATTRIBUTE_BACKGROUND = 0x006AA932, // background + ATTRIBUTE_BACKGROUNDCOLOR_R = 0x02AF0767, // backgroundcolor.r + ATTRIBUTE_BACKGROUNDCOLOR_G = 0x02A404B2, // backgroundcolor.g + ATTRIBUTE_BACKGROUNDCOLOR_B = 0x029F0377, // backgroundcolor.b + ATTRIBUTE_PATHTYPE = 0x02D2A5E1, // pathtype + ATTRIBUTE_LINEARERROR = 0x0378A51D, // linearerror + ATTRIBUTE_EDGETESSAMOUNT = 0x02577E3A, // edgetessamount + ATTRIBUTE_INNERTESSAMOUNT = 0x0027A241, // innertessamount + ATTRIBUTE_BEGINCAP = 0x03373D37, // begincap + ATTRIBUTE_BEGINCAPOFFSET = 0x01FEFE64, // begincapoffset + ATTRIBUTE_BEGINCAPOPACITY = 0x02C2761E, // begincapopacity + ATTRIBUTE_BEGINCAPWIDTH = 0x0102BDE3, // begincapwidth + ATTRIBUTE_ENDCAP = 0x00ADB3A9, // endcap + ATTRIBUTE_ENDCAPOFFSET = 0x0382A9D6, // endcapoffset + ATTRIBUTE_ENDCAPOPACITY = 0x019BA72C, // endcapopacity + ATTRIBUTE_ENDCAPWIDTH = 0x03A315F1, // endcapwidth + ATTRIBUTE_PAINTSTYLE = 0x03ADEC8D, // paintstyle + ATTRIBUTE_CLOSED = 0x01807034, // closed + ATTRIBUTE_INCOMINGANGLE = 0x03890AB3, // incomingangle + ATTRIBUTE_INCOMINGDISTANCE = 0x005EB2A5, // incomingdistance + ATTRIBUTE_OUTGOINGDISTANCE = 0x017C597F, // outgoingdistance + ATTRIBUTE_PARTICLETYPE = 0x01C01260, // particletype + ATTRIBUTE_MAXPARTICLES = 0x00BE66B7, // maxparticles + ATTRIBUTE_PARTICLESIZE = 0x02534279, // particlesize + ATTRIBUTE_LIFETIME = 0x0033D297, // lifetime + ATTRIBUTE_CONTROLLEDPROPERTY = 0x022C0A1D, // controlledproperty + ATTRIBUTE_QT_IO = 0x010EF2CF, // qt.io +}; // enum EAttribute + +#define AK_STRING_QT_IO "qt.io" + +/// Function providing reverse hash lookup +const char *GetAttributeString(const EAttribute inAttribute); + +} // namespace Q3DStudio + diff --git a/src/Runtime/Source/runtime/Qt3DSAttributeHashes.txt b/src/Runtime/Source/runtime/Qt3DSAttributeHashes.txt new file mode 100644 index 00000000..7c38c875 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSAttributeHashes.txt @@ -0,0 +1,242 @@ +name +type +opacity + +starttime +endtime + +sourcepath +importid +eyeball +position +position.x +position.y +position.z +rotation +rotation.x +rotation.y +rotation.z +scale +scale.x +scale.y +scale.z +pivot +pivot.x +pivot.y +pivot.z +rotationorder +orientation +shadowcaster +tessellation +edgetess +innertess + +orthographic +clipnear +clipfar +fov +fovhorizontal +scalemode +scaleanchor + +brightness +linearfade +expfade +lighttype +scope +lightdiffuse +lightdiffuse.r +lightdiffuse.g +lightdiffuse.b +lightambient.r +lightambient +lightambient.g +lightambient.b +lightspecular +lightspecular.r +lightspecular.g +lightspecular.b +areawidth +areaheight +castshadow +shdwbias +shdwfactor +shdwmapres +shdwmapfar +shdwmapfov +shdwfilter + +lightmapindirect +lightmapradiosity +lightmapshadow + +iblprobe + +shaderlighting +emissivepower +emissivecolor +emissivecolor.r +emissivecolor.g +emissivecolor.b +diffuse +diffuse.r +diffuse.g +diffuse.b +specularmap +specularmodel +speculartint +speculartint.r +speculartint.g +speculartint.b +ior +fresnelPower +specularamount +specularroughness +roughnessmap +blendmode +culling +zbufferwrite +diffusemap +diffusemap2 +diffusemap3 +specularreflection +opacitymap +emissivemap +emissivemap2 +bumpmap +bumpamount +normalmap +displacementmap +displaceamount +translucencymap +translucentfalloff +diffuselightwrap +referencedmaterial +vertexcolors + +rotationuv +positionu +positionv +scaleu +scalev +pivotu +pivotv +tilingmodehorz +tilingmodevert +mappingtype +mappingmode +subpresentation +uri + +transparent +progressiveaa +multisampleaa +temporalaa +blendtype +horzfields +left +leftunits +width +widthunits +right +rightunits +vertfields +top +topunits +height +heightunits +bottom +bottomunits +aostrength +aodistance +aosoftness +aobias +aosamplerate +aodither +shadowstrength +shadowdist +shadowsoftness +shadowbias +lightprobe +probebright +fastibl +probehorizon +probefov +lightprobe2 +probe2fade +probe2window +probe2pos +disabledepthtest +disabledepthprepass + +textcolor +textcolor.r +textcolor.g +textcolor.b +size +font +dropshadow +dropshadowstrength +dropshadowoffset +dropshadowoffsetx +dropshadowoffsety +dropshadowhorzalign +dropshadowvertalign +boundingbox +boundingbox.x +boundingbox.y +elide +tracking +leading +renderstyle +textstring +backcolor.r +backcolor.g +backcolor.b +texttype +usebackcolor +wordwrap +horzscroll +horzalign +vertscroll +vertalign +boxheight +boxwidth +remotestringsource +cachedtextstring +enableacceleratedfont + +BehaviorScripts +UICCustomObjType + +bgcolorenable +background +backgroundcolor.r +backgroundcolor.g +backgroundcolor.b + +pathtype +linearerror +edgetessamount +innertessamount +begincap +begincapoffset +begincapopacity +begincapwidth +endcap +endcapoffset +endcapopacity +endcapwidth +paintstyle +closed + +incomingangle +incomingdistance +outgoingdistance + +particletype +maxparticles +particlesize +lifetime + +controlledproperty diff --git a/src/Runtime/Source/runtime/Qt3DSCommandEventTypes.h b/src/Runtime/Source/runtime/Qt3DSCommandEventTypes.h new file mode 100644 index 00000000..01a12b44 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSCommandEventTypes.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSHash.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Commands +//============================================================================== + +// Command types are 31-bit hash instead of 32-bit +// The 1 bit flag is being used to differentiate between a Command and an Event +// Commands trigger execution, both commands and events can trigger logic + +// Asset +const TEventCommandHash COMMAND_SETPROPERTY = CHash::HashEventCommand("COMMAND_SETPROPERTY"); +const TEventCommandHash COMMAND_FIREEVENT = CHash::HashEventCommand("COMMAND_FIREEVENT"); +const TEventCommandHash COMMAND_SCRIPTLET = CHash::HashEventCommand("COMMAND_SCRIPTLET"); +const TEventCommandHash COMMAND_PLAYSOUND = CHash::HashEventCommand("COMMAND_PLAYSOUND"); +const TEventCommandHash COMMAND_EMITSIGNAL = CHash::HashEventCommand("COMMAND_EMITSIGNAL"); + +// Time +const TEventCommandHash COMMAND_PLAY = CHash::HashEventCommand("COMMAND_PLAY"); +const TEventCommandHash COMMAND_PAUSE = CHash::HashEventCommand("COMMAND_PAUSE"); +const TEventCommandHash COMMAND_GOTOTIME = CHash::HashEventCommand("COMMAND_GOTOTIME"); +const TEventCommandHash COMMAND_GOTOTIMELABEL = CHash::HashEventCommand("COMMAND_GOTOTIMELABEL"); + +// Slide +const TEventCommandHash COMMAND_GOTOSLIDE = CHash::HashEventCommand("COMMAND_GOTOSLIDE"); +const TEventCommandHash COMMAND_GOTOSLIDENAME = CHash::HashEventCommand("COMMAND_GOTOSLIDENAME"); +const TEventCommandHash COMMAND_GOTONEXTSLIDE = CHash::HashEventCommand("COMMAND_GOTONEXTSLIDE"); +const TEventCommandHash COMMAND_GOTOPREVIOUSSLIDE = + CHash::HashEventCommand("COMMAND_GOTOPREVIOUSSLIDE"); +const TEventCommandHash COMMAND_BACKSLIDE = CHash::HashEventCommand("COMMAND_BACKSLIDE"); + +// Behavior +const TEventCommandHash COMMAND_CUSTOMACTION = CHash::HashEventCommand("COMMAND_CUSTOMACTION"); +const TEventCommandHash COMMAND_CUSTOMCALLBACK = CHash::HashEventCommand("COMMAND_CALLBACK"); +//============================================================================== +// Events +//============================================================================== + +// Slide Events +const TEventCommandHash EVENT_ONSLIDEENTER = CHash::HashEventCommand("onSlideEnter"); +const TEventCommandHash EVENT_ONSLIDEEXIT = CHash::HashEventCommand("onSlideExit"); + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSCommandHelper.cpp b/src/Runtime/Source/runtime/Qt3DSCommandHelper.cpp new file mode 100644 index 00000000..53c7648a --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSCommandHelper.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +#include "Qt3DSCommandHelper.h" +#include "Qt3DSCommandEventTypes.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSApplication.h" +#include "Qt3DSSlideSystem.h" + +namespace Q3DStudio { + +CCommandHelper::CCommandHelper() +{ +} + +CCommandHelper::~CCommandHelper() +{ +} + +static Option FindSlide(TElement &inElement, const char *slideName) +{ + IPresentation *thePresentation = inElement.GetBelongedPresentation(); + + int theSlideHashName = thePresentation->GetApplication().HashString(slideName); + TComponent *theComponent = thePresentation->GetComponentManager().GetComponent(&inElement); + UINT8 theSlideIndex = + thePresentation->GetSlideSystem().FindSlide(*theComponent, theSlideHashName); + if (theSlideIndex >= theComponent->GetSlideCount()) { + qt3ds::foundation::CRegisteredString elemPath = thePresentation->GetElementPath(inElement); + if (elemPath.IsValid()) { + qCCritical(qt3ds::INVALID_PARAMETER) + << "CCommandHelper: FindSlide: Unable to find slide " + << slideName << " on element " << elemPath.c_str(); + } else { + qCCritical(qt3ds::INVALID_PARAMETER) + << "CCommandHelper: FindSlide: Unable to find slide " << slideName; + } + return Empty(); + } + + return theSlideIndex; +} + +bool CCommandHelper::SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlideIndex, + const SScriptEngineGotoSlideArgs &inArgs) +{ + IPresentation *thePresentation = inElement.GetBelongedPresentation(); + TElement *theTarget = GetComponentParent(&inElement); + SComponentGotoSlideData theSlideData(inSlideIndex); + theSlideData.m_Mode = inArgs.m_Mode; + theSlideData.m_Paused = inArgs.m_Paused; + theSlideData.m_Rate = inArgs.m_Rate; + theSlideData.m_Reverse = inArgs.m_Reverse; + theSlideData.m_StartTime = inArgs.m_StartTime; + // Resolve playthroughto if it has a valid value. + if (!isTrivial(inArgs.m_PlaythroughTo)) { + if (AreEqual(inArgs.m_PlaythroughTo, "next")) + theSlideData.m_PlaythroughTo = -1; + else if (AreEqual(inArgs.m_PlaythroughTo, "previous")) + theSlideData.m_PlaythroughTo = -2; + else { + // Find the slide if possible. If not, then just error leave things as they are. + + Option theSlideIndex = FindSlide(inElement, inArgs.m_PlaythroughTo); + if (theSlideIndex.hasValue()) + theSlideData.m_PlaythroughTo = *theSlideIndex; + } + } + thePresentation->GetComponentManager().SetupComponentGotoSlideCommand(theTarget, theSlideData); + UVariant theArg1; + UVariant theArg2; + qt3ds::intrinsics::memZero(&theArg1, sizeof(UVariant)); + qt3ds::intrinsics::memZero(&theArg2, sizeof(UVariant)); + thePresentation->FireCommand(COMMAND_GOTOSLIDE, theTarget, &theArg1, &theArg2); + return true; +} + +bool CCommandHelper::SetupGotoSlideCommand(TElement &inElement, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs) +{ + Option theSlideIndex = FindSlide(inElement, slideName); + if (theSlideIndex.hasValue()) + return SetupGotoSlideCommand(inElement, *theSlideIndex, inArgs); + return false; +} + +//============================================================================== +/** + * Checks if the given element is a component. If it isn't walks up the tree and looks for one. + * @param inElementManager the object that manages the elements in the presentation + * @param inElement the element to check if it's a component + * @return the component + */ +TElement *CCommandHelper::GetComponentParent(TElement *inElement) +{ + Q3DStudio_ASSERT(inElement); + return &inElement->GetComponentParent(); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSCommandHelper.h b/src/Runtime/Source/runtime/Qt3DSCommandHelper.h new file mode 100644 index 00000000..412a51a1 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSCommandHelper.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "Qt3DSIScriptBridge.h" + +namespace Q3DStudio { + +class CCommandHelper +{ +private: + CCommandHelper(); + CCommandHelper(const CCommandHelper &); + CCommandHelper &operator=(const CCommandHelper &); + virtual ~CCommandHelper(); + +public: + static bool SetupGotoSlideCommand(TElement &inElement, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs); + static bool SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlide, + const SScriptEngineGotoSlideArgs &inArgs); + +public: + static TElement *GetComponentParent(TElement *inParent); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSComponentManager.cpp b/src/Runtime/Source/runtime/Qt3DSComponentManager.cpp new file mode 100644 index 00000000..2cfb2311 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSComponentManager.cpp @@ -0,0 +1,480 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSComponentManager.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSSlideSystem.h" +#include "Qt3DSCommandEventTypes.h" +#include "Qt3DSPresentationFrameData.h" +#include "Qt3DSApplication.h" +#include "Qt3DSActivationManager.h" +#include "Qt3DSPresentation.h" + +using qt3ds::runtime::SSlideKey; +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + * @param inPresentation reference to its presentation + */ +CComponentManager::CComponentManager(IPresentation &inPresentation) + : m_Presentation(static_cast(inPresentation)) +{ +} + +//============================================================================== +/** + * Enforces the contract that slide switching requires a reset to the master + * slide (slide 0) before switching to the desired slide index. + * Also updates the TComponent's current slide number. + * @param inComponent TComponent to set slide on + * @param inSlideIndex relative index of the slide to switch to + * @param inSlideExit true if exiting the slide, false otherwise + */ +void CComponentManager::GotoSlideIndex(TElement *inComponent, + const SComponentGotoSlideData &inGotoData, + BOOL inSlideExit /*= true*/) +{ + TComponent *theComponent = GetComponent(inComponent); + + if (theComponent == NULL) { + return; + } + + if (inGotoData.m_Slide < 1 || inGotoData.m_Slide >= theComponent->GetSlideCount()) { + qCCritical(qt3ds::INVALID_PARAMETER) + << "GotoSlide: Index out of range: Index " << inGotoData.m_Slide + << " SlideCount: "<< theComponent->GetSlideCount(); + return; + } + + if (theComponent->GetActive() == false) { + m_ComponentInitialSlideMap[inComponent] = inGotoData; + return; + } + + SComponentGotoSlideData theGotoSlideData(inGotoData); + + TComponentGotoSlideDataMap::iterator iter = m_ComponentInitialSlideMap.find(inComponent); + if (iter != m_ComponentInitialSlideMap.end()) { + theGotoSlideData = iter->second; + m_ComponentInitialSlideMap.erase(iter); + } + + const UINT8 theCurrentSlideIndex = theComponent->GetCurrentSlide(); + + QString elementPath = QString::fromUtf8(inComponent->m_Path.c_str()); + + if (inSlideExit) { + SEventCommand theEvent = { inComponent, EVENT_ONSLIDEEXIT }; + theEvent.m_IsEvent = true; + m_Presentation.ProcessEvent(theEvent); + + // Signal previous slide change + m_Presentation.signalProxy()->SigSlideExited(elementPath, theCurrentSlideIndex, + GetCurrentSlideName(inComponent)); + + // m_Presentation.FireEvent(EVENT_ONSLIDEEXIT, inComponent); + // m_Presentation.FlushEventCommandQueue(); + } + + // Update dynamic keys to use current values before slide switching, with the exception of + // master slides because playback only starts from non-master slides. + if (theCurrentSlideIndex > 0) { + m_Presentation.GetSlideSystem().InitializeDynamicKeys( + SSlideKey(*theComponent, (qt3ds::QT3DSU8)theGotoSlideData.m_Slide), + m_Presentation.GetAnimationSystem()); + // deactivate actions and animation tracks on the current slide. + m_Presentation.GetSlideSystem().RollbackSlide( + SSlideKey(*inComponent, (qt3ds::QT3DSU8)theCurrentSlideIndex), + m_Presentation.GetAnimationSystem(), m_Presentation.GetLogicSystem()); + } else { + m_Presentation.GetSlideSystem().ExecuteSlide(SSlideKey(*inComponent, 0), + m_Presentation.GetAnimationSystem(), + m_Presentation.GetLogicSystem()); + } + // Execute new slide. + m_Presentation.GetSlideSystem().ExecuteSlide( + SSlideKey(*inComponent, (qt3ds::QT3DSU8)theGotoSlideData.m_Slide), + m_Presentation.GetAnimationSystem(), m_Presentation.GetLogicSystem()); + CTimePolicy &thePolicy(theComponent->GetTimePolicy()); + TTimeUnit theLoopingDuration = thePolicy.GetLoopingDuration(); + if (theGotoSlideData.m_Mode.hasValue()) { + inComponent->SetPlayThrough(false); + switch (*theGotoSlideData.m_Mode) { + case TimePolicyModes::Looping: + thePolicy.Initialize(theLoopingDuration, 0, false); + break; + case TimePolicyModes::PingPong: + thePolicy.Initialize(theLoopingDuration, 0, true); + break; + case TimePolicyModes::StopAtEnd: + thePolicy.Initialize(theLoopingDuration, 1, false); + break; + case TimePolicyModes::Ping: + thePolicy.Initialize(theLoopingDuration, 1, true); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + // Update the current index which also updates the back index + theComponent->SetCurrentSlide(static_cast(theGotoSlideData.m_Slide)); + m_PlaythroughOverrideMap.erase(inComponent); + if (theGotoSlideData.m_PlaythroughTo.hasValue()) { + m_PlaythroughOverrideMap.insert( + eastl::make_pair(inComponent, *theGotoSlideData.m_PlaythroughTo)); + theComponent->SetPlayThrough(true); + } + + // Reset time for component to 0 + + if (theGotoSlideData.m_Paused.hasValue()) + thePolicy.SetPaused(*theGotoSlideData.m_Paused); + + thePolicy.SetRate(theGotoSlideData.m_Rate); + thePolicy.SetReverse(theGotoSlideData.m_Reverse); + + if (theGotoSlideData.m_StartTime.hasValue()) + thePolicy.SetTime(*theGotoSlideData.m_StartTime); + + inComponent->SetDirty(); + m_Presentation.FireEvent(EVENT_ONSLIDEENTER, inComponent); + qt3ds::runtime::IActivityZone *theZone = m_Presentation.GetActivityZone(); + if (theZone) + theZone->OnSlideChange(*inComponent); + + // Signal current slide change + m_Presentation.signalProxy()->SigSlideEntered(elementPath, GetCurrentSlide(inComponent), + GetCurrentSlideName(inComponent)); +} + +//============================================================================== +/** + * Sets a component to a specified slide using the slide name hash. + * Performs a switch to Slide 0 (master) first, before switching to the + * required slide. + * @param inComponent reference to the TComponent + * @param inSlideHashName hash of the slide to switch to + */ +void CComponentManager::GotoSlideName(TElement *inComponent, const TStringHash inSlideHashName) +{ + TComponent *theComponent = GetComponent(inComponent); + UINT8 theSlideIndex = m_Presentation.GetSlideSystem().FindSlide(*theComponent, inSlideHashName); + + if (theSlideIndex < 1 || theSlideIndex >= theComponent->GetSlideCount()) { + const char *slideName = m_Presentation.GetApplication().ReverseHash(inSlideHashName); + if (slideName && *slideName) + qCCritical(qt3ds::INVALID_PARAMETER) << "GotoSlide: Name not found: " << slideName; + else + qCCritical(qt3ds::INVALID_PARAMETER) << "GotoSlide: Name not found: " << inSlideHashName; + + } else + GotoSlideIndex(inComponent, theSlideIndex); +} + +//============================================================================== +/** + * Return the index of the current slide of the component. + * @param inComponent reference to the TComponent + * @return the index of current slide + */ +UINT8 CComponentManager::GetCurrentSlide(TElement *inComponent) +{ + return GetComponent(inComponent)->GetCurrentSlide(); +} + +//============================================================================== +/** + * Return the number of slides on a component. + * @param inComponent reference to the TComponent + * @return the number of slides + */ +UINT8 CComponentManager::GetSlideCount(TElement *inComponent) +{ + return GetComponent(inComponent)->GetSlideCount(); +} + +//============================================================================== +/** + * Performs a switch to the slide following the current slide (current slide + 1). + * @param inComponent reference to the TComponent + * @param inIncrement slide increment offset + */ +void CComponentManager::GoToNextSlide(TElement *inComponent, const INT32 inIncrement) +{ + TComponent *theComponent = GetComponent(inComponent); + INT32 theNewIndex = Q3DStudio_clamp(inIncrement + theComponent->GetCurrentSlide(), 1L, + theComponent->GetSlideCount() - 1); + + // Trigger goto to slide only if the next slide is not the current + if (theComponent->GetActive()) { + if (theNewIndex != theComponent->GetCurrentSlide()) + GotoSlideIndex(inComponent, theNewIndex); + } else { + qCCritical(qt3ds::INVALID_PARAMETER) + << "Runtime: Attempt to goto slide on an inactive component!"; + } +} + +//============================================================================== +/** + * Performs a switch to the slide following the current slide (current slide - 1). + * @param inComponent reference to the TComponent + * @param inDecrement slide decrement offset + */ +void CComponentManager::GoToPreviousSlide(TElement *inComponent, const INT32 inDecrement) +{ + TComponent *theComponent = GetComponent(inComponent); + INT32 theNewIndex = Q3DStudio_clamp(theComponent->GetCurrentSlide() - inDecrement, 1L, + theComponent->GetSlideCount() - 1); + + // Trigger goto to slide only if the next slide is not the current + if (theNewIndex != theComponent->GetCurrentSlide()) + GotoSlideIndex(inComponent, theNewIndex); +} + +//============================================================================== +/** + * Playthrough to the next slide that is specified. + * @param inComponent reference to the TComponent + */ +void CComponentManager::PlaythroughToSlide(TElement *inComponent) +{ + TComponent *theComponent = GetComponent(inComponent); + TComponentIntMap::iterator iter = m_PlaythroughOverrideMap.find(inComponent); + INT32 thePlaythroughTo = 0; + if (iter != m_PlaythroughOverrideMap.end()) { + thePlaythroughTo = iter->second; + m_PlaythroughOverrideMap.erase(iter); + } else { + thePlaythroughTo = m_Presentation.GetSlideSystem().GetPlaythroughToSlideIndex( + SSlideKey(*theComponent, (qt3ds::QT3DSU8)theComponent->GetCurrentSlide())); + if (thePlaythroughTo == -1) { + qCCritical(qt3ds::INVALID_OPERATION) << "Missing slide to play through to"; + inComponent->SetPlayThrough( + false); // clear this flag, so that this is equivalent to a "Stop At End" + } + } + + if (thePlaythroughTo == -2) { + GoToPreviousSlide(inComponent, 1); + } else if (thePlaythroughTo == -1) { + GoToNextSlide(inComponent, 1); + } else { + GotoSlideIndex(inComponent, thePlaythroughTo); + } +} + +//============================================================================== +/** + * Performs a switch to the previous slide. + * @param inComponent reference to the TComponent + */ +void CComponentManager::GoToBackSlide(TElement *inComponent) +{ + TComponent *theComponent = GetComponent(inComponent); + GotoSlideIndex(theComponent, theComponent->GetPreviousSlide()); +} + +//============================================================================== +/** + * Set the component's local time using the supplied time. + * @param inComponent reference to the TComponent + * @param inTime supplied time + */ +void CComponentManager::GoToTime(TElement *inComponent, const TTimeUnit inTime) +{ + if (inComponent == NULL) + return; + if (inComponent->GetActive() == false) { + qCCritical(qt3ds::INVALID_OPERATION) + << "Runtime: Attempt to goto time on inactive component!"; + return; + } + m_Presentation.GetActivityZone()->GoToTime(*inComponent, inTime); + inComponent->SetDirty(); +} + +//============================================================================== +/** + * Get the component's playback state + * @param inComponent reference to the TComponent + * @return true if it's paused, false if it's playing + */ +BOOL CComponentManager::GetPause(TElement *inComponent) +{ + CTimePolicy &theTimePolicy = GetComponent(inComponent)->GetTimePolicy(); + return theTimePolicy.GetPaused(); +} + +//============================================================================== +/** + * Get the component's ping pong direction + * @param inComponent reference to the TComponent + * @return true if it's pingponging forward, false if it's pingponging backwards + */ +BOOL CComponentManager::GetPlayBackDirection(TElement *inComponent) +{ + return GetComponent(inComponent)->GetPlayBackDirection(); +} + +//============================================================================== +/** + * Update time policy of the component during each slide execution + * @param inComponent reference to the TComponent + * @param inLoopDuration loop duration of component at that slide + * @param inRepetitions number of repetitions + * @param inPingPong if true the component will move with respect to reverse time + *sequence + * @param inPlayThrough if true the component will continue to execute next slide + */ +void CComponentManager::SetTimePolicy(TElement *inComponent, const TTimeUnit inLoopDuration, + const UINT32 inRepetitions, const BOOL inPingPong, + const BOOL inPlayThrough) +{ + CTimePolicy &theTimePolicy = GetComponent(inComponent)->GetTimePolicy(); + theTimePolicy.Initialize(inLoopDuration, inRepetitions, inPingPong); + inComponent->SetPlayThrough(inPlayThrough); +} + +//============================================================================== +/** + * Set the component's playback to either play or pause + * @param inComponent reference to the TComponent + * @param inPause true = pause, false = play + */ +void CComponentManager::SetPause(TElement *inComponent, const BOOL inPause) +{ + CTimePolicy &theTimePolicy = GetComponent(inComponent)->GetTimePolicy(); + BOOL wasPaused = theTimePolicy.GetPaused(); + theTimePolicy.SetPaused(inPause); + if (wasPaused != inPause) + inComponent->SetDirty(); +} + +//============================================================================== +/** + * Promote from TElement* to TComponent. + * @param inElement TElement pointer to be recast as TComponent + * @return pointer to the component + */ +TComponent *CComponentManager::GetComponent(TElement *inElement) +{ + Q3DStudio_ASSERT(inElement->IsComponent()); + return static_cast(inElement); +} + +//============================================================================== +/** + * Gets the string name of the current slide. + * @param inComponent the component to query for it's current slide name + * @return the char buffer storing the name + */ +const CHAR *CComponentManager::GetCurrentSlideName(TElement *inComponent) +{ + TComponent *theComponent = GetComponent(inComponent); + return m_Presentation.GetSlideSystem().GetSlideName( + SSlideKey(*theComponent, (qt3ds::QT3DSU8)theComponent->GetCurrentSlide())); +} + +void CComponentManager::OnElementDeactivated(TElement *) +{ +} + +void CComponentManager::SetComponentTimeOverride(TElement *inElement, TTimeUnit inEndTime, + FLOAT inInterpolation, + IComponentTimeOverrideFinishedCallback *inCallback) +{ + if (inElement->IsComponent()) { + qCCritical(qt3ds::INVALID_OPERATION) + << "ComponentManager: SetComponentTimeOverride called on object that " + << "wasn't an element"; + if (inCallback) + inCallback->Release(); + Q3DStudio_ASSERT(false); + return; + } + // sanitize end time. + CTimePolicy &theTimePolicy = GetComponent(inElement)->GetTimePolicy(); + if (inEndTime < 0) + inEndTime = 0; + if (inEndTime > theTimePolicy.GetLoopingDuration()) + inEndTime = theTimePolicy.GetLoopingDuration(); + m_Presentation.GetActivityZone()->GetOrCreateItemComponentOverride(*inElement, inInterpolation, + inEndTime, inCallback); + + // Force the time policy object to respect its own time. If we played through till the end and + // sat there for a while + // we need the actual time will travel further and further from the time policy's local time. + // If we then play backward we + // will jump until the offset is synchronized with the actual time. + theTimePolicy.SetTime(theTimePolicy.GetTime()); + inElement->SetDirty(); +} + +void CComponentManager::SetupComponentGotoSlideCommand(TElement *inElement, + const SComponentGotoSlideData &inSlide) +{ + m_ComponentGotoSlideMap[inElement] = inSlide; +} + +bool CComponentManager::HasComponentGotoSlideCommand(TElement *inElement) +{ + return m_ComponentGotoSlideMap.find(inElement) != m_ComponentGotoSlideMap.end(); +} + +SComponentGotoSlideData CComponentManager::GetComponentGotoSlideCommand(TElement *inElement) +{ + TComponentGotoSlideDataMap::iterator iter = m_ComponentGotoSlideMap.find(inElement); + if (iter != m_ComponentGotoSlideMap.end()) + return iter->second; + return -1; +} + +void CComponentManager::ReleaseComponentGotoSlideCommand(TElement *inElement) +{ + TComponentGotoSlideDataMap::iterator iter = m_ComponentGotoSlideMap.find(inElement); + if (iter != m_ComponentGotoSlideMap.end()) + m_ComponentGotoSlideMap.erase(iter); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSComponentManager.h b/src/Runtime/Source/runtime/Qt3DSComponentManager.h new file mode 100644 index 00000000..865b8aa9 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSComponentManager.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSIComponentManager.h" +#include "EASTL/hash_map.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { +class CTimePolicy; +class CPresentation; +struct SComponentTimePolicyOverride +{ + TElement *m_Element; + FLOAT m_TimeMultiplier; + TTimeUnit m_EndTime; + IComponentTimeOverrideFinishedCallback *m_TimeCallback; + SComponentTimePolicyOverride(TElement *inElement, FLOAT inMultiplier, TTimeUnit inEndTime, + IComponentTimeOverrideFinishedCallback *inCallback) + : m_Element(inElement) + , m_TimeMultiplier(inMultiplier) + , m_EndTime(inEndTime) + , m_TimeCallback(inCallback) + { + } + // Returns the local time and a boolean indicating if we have reached the end. + // Implemented in UICTimePolicy.cpp so that I can compare the CTimePolicy::ComputeTime method + // with + // SComponentTimePolicyOverride::ComputLocalTime method + eastl::pair ComputeLocalTime(CTimePolicy &inTimePolicy, + TTimeUnit inGlobalTime); + // Implemented in UICTimePolicy.cpp + void SetTime(CTimePolicy &inTimePolicy, TTimeUnit inLocalTime); +}; + +typedef eastl::hash_map TComponentGotoSlideDataMap; +typedef eastl::hash_map TComponentIntMap; + +//============================================================================== +/** + * The Component Manager is a factory and container of all components + * within the presentation. + */ +class CComponentManager : public IComponentManager +{ + CPresentation &m_Presentation; + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CComponentManager(IPresentation &inPresentation); + +public: // Slide + void GotoSlideIndex(TElement *inComponent, const SComponentGotoSlideData &inGotoData, + BOOL inSlideExit = true) override; + void GotoSlideName(TElement *inComponent, const TStringHash inSlideHashName) override; + void GoToBackSlide(TElement *inComponent) override; + void GoToNextSlide(TElement *inComponent, const INT32 inDecrement = 1) override; + void GoToPreviousSlide(TElement *inComponent, const INT32 inDecrement = 1) override; + void PlaythroughToSlide(TElement *inComponent); + + UINT8 GetSlideCount(TElement *inComponent) override; + UINT8 GetCurrentSlide(TElement *inComponent) override; + const CHAR *GetCurrentSlideName(TElement *inComponent) override; + + void OnElementDeactivated(TElement *inElement) override; + + void SetComponentTimeOverride(TElement *inElement, TTimeUnit inEndTime, FLOAT inInterpolation, + IComponentTimeOverrideFinishedCallback *inCallback) override; + + // Allows multiple gotoslide command operating on the same element to work correctly. + // This API is meant to fix a scenario where gotoslide is called multiple times in a frame + // on the same component. This isn't avoidable in some cases without very complex scene logic. + + // later calls override earlier calls + void SetupComponentGotoSlideCommand(TElement *inElement, + const SComponentGotoSlideData &inSlide) override; + bool HasComponentGotoSlideCommand(TElement *inElement) override; + SComponentGotoSlideData GetComponentGotoSlideCommand(TElement *inElement) override; + void ReleaseComponentGotoSlideCommand(TElement *inElement) override; + +public: // Time + void GoToTime(TElement *inComponent, const TTimeUnit inTime) override; + void SetPause(TElement *inComponent, const BOOL inPause) override; + void SetTimePolicy(TElement *inComponent, const TTimeUnit inLoopDuration, + const UINT32 inRepetitions, const BOOL inPingPong, const BOOL inPlayThrough) override; + + TTimeUnit ComputeComponentLocalTime(TElement *inComponent, const TTimeUnit inGlobalTime); + BOOL GetPause(TElement *inComponent) override; + BOOL GetPlayBackDirection(TElement *inComponent) override; + +protected: // Promotion + TComponent *GetComponent(TElement *inElement) override; + +private: + // Disabled Copy Construction + CComponentManager(const CComponentManager &); + CComponentManager &operator=(const CComponentManager &); + + TComponentGotoSlideDataMap m_ComponentInitialSlideMap; + TComponentGotoSlideDataMap m_ComponentGotoSlideMap; + TComponentIntMap m_PlaythroughOverrideMap; + + //============================================================================== + // Friends + //============================================================================== + friend class CSlideBuilder; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSElementHelper.cpp b/src/Runtime/Source/runtime/Qt3DSElementHelper.cpp new file mode 100644 index 00000000..acf8849e --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSElementHelper.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +#include "Qt3DSElementHelper.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSApplication.h" +#include "Qt3DSCommandEventTypes.h" + +using namespace qt3ds; + +namespace Q3DStudio { + +const char PRESENTATION_DELIMITER = ':'; +const char NODE_DELIMITER = '.'; +const TStringHash RESERVED_THIS = CHash::HashString("this"); +const TStringHash RESERVED_PARENT = CHash::HashString("parent"); +const TStringHash RESERVED_SCENE = CHash::HashString("Scene"); + +CElementHelper::CElementHelper() +{ +} + +CElementHelper::~CElementHelper() +{ +} + +TElement *CElementHelper::GetElement(qt3ds::runtime::IApplication &inApplication, + IPresentation *inDefaultPresentation, const char *inPath, + TElement *inStartElement) +{ + if (!inPath || *inPath == 0) + return nullptr; + const char *thePath(inPath); + const char *theSubPath = nullptr; + IPresentation *thePresentation = nullptr; + size_t thePathLength = ::strlen(thePath) + 1; + char *theToken = Q3DStudio_allocate_desc(CHAR, thePathLength, "Token:TempPath"); + // Try to get the specified presentation + theSubPath = ::strchr(thePath, PRESENTATION_DELIMITER); + TElement *theElement = inStartElement; + if (theSubPath) { + UINT32 theSubPathLength = static_cast(theSubPath - thePath); + + ::strncpy(theToken, thePath, theSubPathLength); + theToken[theSubPathLength] = '\0'; + + thePath = theSubPath + 1; + + const CHAR *thePresentationName = theToken; + + thePresentation = inApplication.GetPresentationById(thePresentationName); + } + + if (!thePresentation) + thePresentation = inDefaultPresentation; + + // Return nil if the inStartElement is not in the specified presentation + if (theElement + && (!theSubPath && theElement->GetBelongedPresentation() != thePresentation)) { + thePresentation = theElement->GetBelongedPresentation(); + } + + if (!thePresentation) + return nullptr; + + TStringHash theName; + INT32 theParseCounter = 0; + + while (thePath && thePath[0] != '\0') { + ++theParseCounter; + + // Do some strtok() work here + theSubPath = ::strchr(thePath, NODE_DELIMITER); + if (theSubPath) { + UINT32 theSubPathLength = static_cast(theSubPath - thePath); + Q3DStudio_ASSERT(theSubPathLength < thePathLength); + + ::strncpy(theToken, thePath, theSubPathLength); + theToken[theSubPathLength] = '\0'; + + thePath = theSubPath + 1; + } else { + ::strcpy(theToken, thePath); + thePath = nullptr; + } + + // Hash the token and do some element searching + theName = CHash::HashString(theToken); + + if (theName == RESERVED_PARENT) { + if (theElement) + theElement = theElement->GetParent(); + } else if (theName == RESERVED_THIS) { + ; + } else { + if (theName == RESERVED_SCENE && theParseCounter == 1) { + // theElement is nullptr, so using absolute path + theElement = thePresentation->GetRoot(); + } else if (theElement) { + // Using relative path + theElement = theElement->FindChild(theName); + } + } + + if (!theElement) + thePath = nullptr; + } // while + + Q3DStudio_free(theToken, CHAR, thePathLength); + return theElement; +} +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSElementHelper.h b/src/Runtime/Source/runtime/Qt3DSElementHelper.h new file mode 100644 index 00000000..df2afddb --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSElementHelper.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +namespace qt3ds { +namespace runtime { + class IApplication; +} +} + +namespace Q3DStudio { + +class IPresentation; + +class CElementHelper +{ +private: + CElementHelper(); + CElementHelper(const CElementHelper &); + CElementHelper &operator=(const CElementHelper &); + virtual ~CElementHelper(); + +public: + static TElement *GetElement(qt3ds::runtime::IApplication &inApplication, + IPresentation *inDefaultPresentation, const char *inPath, + TElement *inStartElement = nullptr); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSElementSystem.cpp b/src/Runtime/Source/runtime/Qt3DSElementSystem.cpp new file mode 100644 index 00000000..44850859 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSElementSystem.cpp @@ -0,0 +1,855 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "RuntimePrefix.h" +#include "Qt3DSElementSystem.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "EASTL/sort.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "Qt3DSHash.h" +#include "Qt3DSActivationManager.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSPresentationFrameData.h" +#include "Qt3DSAttributeHashes.h" +#include "foundation/SerializationTypes.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSIndexableLinkedList.h" + +using namespace qt3ds::runtime::element; +using namespace qt3ds; +using namespace qt3ds::foundation; +using namespace qt3ds::intrinsics; +namespace eastl { +template <> +struct hash +{ + size_t operator()(const STypeDesc &inDesc) const { return inDesc.HashCode(); } +}; +} + +namespace { +typedef IndexableLinkedList + TElementPropertyList; +struct SPropertyDescSorter +{ + bool operator()(const TPropertyDescAndValue &lhs, const TPropertyDescAndValue &rhs) const + { + return strcmp(lhs.first.m_Name.c_str(), rhs.first.m_Name.c_str()) < 0; + } +}; +QT3DSU32 GetNumValueAllocations(const STypeDesc &inTypeDesc) +{ + return ((inTypeDesc.m_Properties.size() + SPropertyValueGroup::NumValues - 1) + / SPropertyValueGroup::NumValues); +} +struct SElementAllocator : public qt3ds::runtime::IElementAllocator +{ + typedef Pool TElementPool; + typedef Pool TComponentPool; + typedef TElementPropertyList::TPoolType TValuePool; + typedef nvhash_map THandleElementMap; + typedef nvhash_map TElementOffsetMap; + typedef nvhash_set TTypeDescSet; + typedef nvhash_map TTypeDescOffsetMap; + typedef nvhash_map TOffsetTypeDescMap; + typedef nvvector> TLoadBufferList; + + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + TElementPool m_Elements; + TComponentPool m_Components; + TValuePool m_Values; + THandleElementMap m_HandleToElements; + TElementOffsetMap m_ElementOffsets; + TTypeDescOffsetMap m_TypeDescOffsets; + TOffsetTypeDescMap m_OffsetsToTypeDescs; + TTypeDescSet m_TypeDescriptors; + nvvector m_TempPropertyDescsAndValues; + nvvector m_TempPropertyDescs; + nvvector m_IgnoredProperties; + // Upon load we allocate a set of buffers + nvvector m_LoadBuffer; + TLoadBufferList m_AllocatedBuffers; + SSAutoDeallocatorAllocator m_AutoAllocator; + nvvector m_LoadElements; + + QT3DSU32 m_NextElementHandle; + + eastl::string m_Workspace; + eastl::string m_WorkspaceExt; + + QT3DSI32 m_RefCount; + + SElementAllocator(NVFoundationBase &inFoundation, IStringTable &inStrTable) + : m_Foundation(inFoundation) + , m_StringTable(inStrTable) + , m_Elements(ForwardingAllocator(m_Foundation.getAllocator(), "m_Elements")) + , m_Components(ForwardingAllocator(m_Foundation.getAllocator(), "m_Components")) + , m_Values(ForwardingAllocator(m_Foundation.getAllocator(), "m_Values")) + , m_HandleToElements(m_Foundation.getAllocator(), "m_HandleToElements") + , m_ElementOffsets(m_Foundation.getAllocator(), "m_ElementOffsets") + , m_TypeDescOffsets(m_Foundation.getAllocator(), "m_TypeDescOffsets") + , m_OffsetsToTypeDescs(m_Foundation.getAllocator(), "m_OffsetsToTypeDescs") + , m_TypeDescriptors(m_Foundation.getAllocator(), "m_TypeDescriptors") + , m_TempPropertyDescsAndValues(m_Foundation.getAllocator(), "m_TempPropertyDescsAndValues") + , m_TempPropertyDescs(m_Foundation.getAllocator(), "m_TempPropertyDescs") + , m_IgnoredProperties(m_Foundation.getAllocator(), "m_IgnoredProperties") + , m_LoadBuffer(m_Foundation.getAllocator(), "m_LoadBuffer") + , m_AllocatedBuffers(m_Foundation.getAllocator(), "m_AllocatedBuffers") + , m_AutoAllocator(inFoundation) + , m_LoadElements(inFoundation.getAllocator(), "m_LoadElements") + , m_NextElementHandle(1) + , m_RefCount(0) + { + } + + ~SElementAllocator() {} + + void GetIgnoredProperties() + { + if (m_IgnoredProperties.empty()) + m_IgnoredProperties.push_back(m_StringTable.RegisterStr("name")); + } + + void addRef() override { atomicIncrement(&m_RefCount); } + + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Foundation.getAllocator()); + NVDelete(alloc, this); + } + } + + SElement &CreateElement(CRegisteredString inName, CRegisteredString inType, + CRegisteredString inSubType, + NVConstDataRef inPropertyDescriptions, + Q3DStudio::IPresentation *inPresentation, SElement *inParent, + bool inIsComponent) override + { + m_TempPropertyDescsAndValues.clear(); + m_TempPropertyDescs.clear(); + bool participatesInTimeGraph = false; + GetIgnoredProperties(); + for (QT3DSU32 idx = 0, end = inPropertyDescriptions.size(); idx < end; ++idx) { + QT3DSU32 nameHash = inPropertyDescriptions[idx].first.GetNameHash(); + if (nameHash == Q3DStudio::ATTRIBUTE_STARTTIME + || nameHash == Q3DStudio::ATTRIBUTE_ENDTIME) + participatesInTimeGraph = true; + if (eastl::find(m_IgnoredProperties.begin(), m_IgnoredProperties.end(), + inPropertyDescriptions[idx].first.m_Name) + == m_IgnoredProperties.end()) { + m_TempPropertyDescsAndValues.push_back(inPropertyDescriptions[idx]); + } + } + eastl::sort(m_TempPropertyDescsAndValues.begin(), m_TempPropertyDescsAndValues.end(), + SPropertyDescSorter()); + + for (QT3DSU32 idx = 0, end = m_TempPropertyDescsAndValues.size(); idx < end; ++idx) { + m_TempPropertyDescs.push_back(m_TempPropertyDescsAndValues[idx].first); + } + + STypeDesc theDesc; + theDesc.m_TypeName = inType; + theDesc.m_SubtypeName = inSubType; + theDesc.m_Properties = m_TempPropertyDescs; + theDesc.SetHashValue(); + eastl::pair inserter = m_TypeDescriptors.insert(theDesc); + + const STypeDesc &theTypeDesc = *inserter.first; + if (inserter.second) { + size_t allocSize = theDesc.m_Properties.size() * sizeof(SPropertyDesc); + if (allocSize) { + SPropertyDesc *newProps = (SPropertyDesc *)m_AutoAllocator.allocate( + allocSize, "TypeDescData", __FILE__, __LINE__, 0); + memCopy(newProps, theDesc.m_Properties.begin(), (QT3DSU32)allocSize); + // Note that this does not change the hash value. + const_cast(theTypeDesc).m_Properties = + toConstDataRef(newProps, theDesc.m_Properties.size()); + } + } + + SElement *retval = inIsComponent ? m_Components.construct(theTypeDesc, __FILE__, __LINE__) + : m_Elements.construct(theTypeDesc, __FILE__, __LINE__); + retval->m_BelongedPresentation = inPresentation; + retval->m_Name = inName; + // children + if (inParent) { + retval->m_Parent = inParent; + if (inParent->m_Child == NULL) { + inParent->m_Child = retval; + } else { + SElement *lastChild = inParent->m_Child; + while (lastChild->m_Sibling) + lastChild = lastChild->m_Sibling; + lastChild->m_Sibling = retval; + } + } + while (FindElementByHandle(m_NextElementHandle)) { + ++m_NextElementHandle; + if (!m_NextElementHandle) + ++m_NextElementHandle; + } + + // required flags + retval->m_Handle = m_NextElementHandle; + if (inIsComponent) + retval->Flags().clearOrSet(true, Q3DStudio::ELEMENTFLAG_COMPONENT); + + if (participatesInTimeGraph) + retval->Flags().clearOrSet(true, Q3DStudio::ELEMENTFLAG_TIMELINE); + + retval->Flags().clearOrSet(true, Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE); + + retval->SetDepth(); + + retval->SetDirty(); + + m_HandleToElements.insert(eastl::make_pair(retval->m_Handle, retval)); + + // property values; + QT3DSU32 propIdx = 0; + TElementPropertyList::CreateAll(retval->m_PropertyValues, theTypeDesc.m_Properties.size(), + m_Values); + for (TElementPropertyList::iterator + iter = TElementPropertyList::begin(retval->m_PropertyValues, + theTypeDesc.m_Properties.size()), + end = TElementPropertyList::end(retval->m_PropertyValues, + theTypeDesc.m_Properties.size()); + iter != end; ++iter, ++propIdx) { + (*iter) = m_TempPropertyDescsAndValues[propIdx].second; + } + + return *retval; + } + + void ReleaseElement(SElement &inElement, bool inRecurse) override + { + if (inRecurse) { + while (inElement.m_Child) + ReleaseElement(*inElement.m_Child, true); + } + // Trim out the element. + if (inElement.m_Parent) { + SElement *theParent = inElement.m_Parent; + if (theParent->m_Child == &inElement) + theParent->m_Child = inElement.m_Sibling; + else { + SElement *thePreviousChild = NULL; + // Empty loop to find the previous child + for (thePreviousChild = theParent->m_Child; + thePreviousChild->m_Sibling != &inElement && thePreviousChild; + thePreviousChild = thePreviousChild->m_Sibling) { + } + if (thePreviousChild) + thePreviousChild->m_Sibling = inElement.m_Sibling; + } + } + + m_HandleToElements.erase(inElement.m_Handle); + + QT3DSU8 *elemAddr = reinterpret_cast(&inElement); + for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx) { + NVDataRef theBuffer(m_AllocatedBuffers[idx]); + // Preloaded element, do not release back to element pools + if (elemAddr >= theBuffer.begin() && elemAddr < theBuffer.end()) + return; + } + + SPropertyValueGroup *theValueGroup = inElement.m_PropertyValues; + while (theValueGroup) { + SPropertyValueGroup *currentGroup = theValueGroup; + theValueGroup = theValueGroup->m_NextNode; + m_Values.deallocate(currentGroup); + } + + if (inElement.IsComponent()) + m_Components.deallocate(&inElement); + else + m_Elements.deallocate(&inElement); + } + + QT3DSI32 GetExtensionIndex(eastl::string &inExt) + { + QT3DSI32 retVal = 0; + + if (!inExt.compare(".x") || !inExt.compare(".r")) + retVal = 0; + else if (!inExt.compare(".y") || !inExt.compare(".g")) + retVal = 1; + if (!inExt.compare(".z") || !inExt.compare(".b")) + retVal = 2; + + return retVal; + } + + virtual Option + CreateDynamicProperty(Q3DStudio::IRuntimeMetaData &theMetaData, SElement &element, + CRegisteredString inName) override + { + SPropertyDesc *newProp = NULL; + m_TempPropertyDescsAndValues.clear(); + m_TempPropertyDescs.clear(); + + // create dynamic descriptor + if (!element.m_DynamicTypeDescription) { + STypeDesc *theDesc; + theDesc = (STypeDesc *)m_AutoAllocator.allocate(sizeof(STypeDesc), "TypeDescData", + __FILE__, __LINE__, 0); + theDesc->m_TypeName = element.m_TypeDescription->m_TypeName; + theDesc->m_SubtypeName = element.m_TypeDescription->m_SubtypeName; + theDesc->m_Properties = m_TempPropertyDescs; + theDesc->SetHashValue(); + // we need this palcement new here + ::new (theDesc) STypeDesc(); + element.m_DynamicTypeDescription = const_cast(theDesc); + } + + STypeDesc *theTypeDesc = element.m_DynamicTypeDescription; + + // remove the extension that we can find the property + QT3DSI32 extIndex = 0; + m_Workspace.assign(inName.c_str()); + eastl::string::size_type theCharPos = m_Workspace.rfind('.'); + if (theCharPos != eastl::string::npos) { + m_WorkspaceExt.assign(m_Workspace, theCharPos, m_Workspace.length()); + m_Workspace.resize(theCharPos); + extIndex = GetExtensionIndex(m_WorkspaceExt); + } + + CRegisteredString theWorkSpaceString = m_StringTable.RegisterStr(m_Workspace.c_str()); + Q3DStudio::ERuntimeDataModelDataType thePropertyType = + theMetaData.GetPropertyType(element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + + // using separate properties + bool separateProperties = theCharPos != eastl::string::npos; + + // single property + size_t allocSize = sizeof(SPropertyDesc); + if (allocSize) { + newProp = (SPropertyDesc *)m_AutoAllocator.allocate(allocSize, "SPropertyDesc", + __FILE__, __LINE__, 0); + + newProp->m_Name = inName; + + // convert to appropriate type + if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat) { + float value = theMetaData.GetPropertyValueFloat( + element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + + Q3DStudio::UVariant theValue; + theValue.m_FLOAT = value; + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), theValue)); + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat2) { + qt3ds::QT3DSVec3 value = theMetaData.GetPropertyValueVector2( + element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + + Q3DStudio::UVariant theVarValue; + theVarValue.m_FLOAT = value[extIndex]; + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), + theVarValue)); + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat3) { + qt3ds::QT3DSVec3 value = theMetaData.GetPropertyValueVector3( + element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + + if (separateProperties) { + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + + Q3DStudio::UVariant theVarValue; + theVarValue.m_FLOAT = value[extIndex]; + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), + theVarValue)); + } else { + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT3; + + Q3DStudio::UVariant theVarValue; + theVarValue.m_FLOAT3[0] = value[0]; + theVarValue.m_FLOAT3[1] = value[1]; + theVarValue.m_FLOAT3[2] = value[2]; + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT3), + theVarValue)); + } + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeLong) { + QT3DSI32 value = (QT3DSI32)theMetaData.GetPropertyValueLong( + element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_INT32; + + Q3DStudio::UVariant theVarValue; + theVarValue.m_INT32 = value; + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_INT32), + theVarValue)); + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeBool) { + bool value = theMetaData.GetPropertyValueBool( + element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_BOOL; + + Q3DStudio::UVariant theVarValue; + theVarValue.m_INT32 = value; + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_BOOL), theVarValue)); + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } else if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeString) { + Option theRuntimeStr = theMetaData.GetPropertyValueString( + element.m_TypeDescription->m_TypeName, theWorkSpaceString, + element.m_TypeDescription->m_SubtypeName); + + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_STRING; + + CStringHandle theString = m_StringTable.GetHandle(theRuntimeStr->c_str()); + Q3DStudio::UVariant theVarValue; + theVarValue.m_StringHandle = theString.handle(); + m_TempPropertyDescsAndValues.push_back(eastl::make_pair( + SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_STRING), + theVarValue)); + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } else { + newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + + theTypeDesc->m_DynamicProperties.push_back(*newProp); + } + } + + // property values; + QT3DSU32 newListSize = theTypeDesc->m_DynamicProperties.size() - 1; + TElementPropertyList::Create(element.m_DynamicPropertyValues, newListSize, m_Values); + + Q3DStudio::UVariant &propertyValue = + TElementPropertyList::GetObjAtIdx(element.m_DynamicPropertyValues, newListSize - 1); + propertyValue = m_TempPropertyDescsAndValues[0].second; + + return eastl::make_pair( + element.m_DynamicTypeDescription->m_DynamicProperties[newListSize - 1], + &TElementPropertyList::GetObjAtIdx(element.m_DynamicPropertyValues, newListSize - 1)); + } + + SElement *FindElementByHandle(QT3DSU32 inElementHandle) override + { + THandleElementMap::iterator theFind = m_HandleToElements.find(inElementHandle); + if (theFind != m_HandleToElements.end()) + return theFind->second; + return NULL; + } + + // Returns an element pointer that when added to the return value of load will be a valid + // element. + SElement *GetRemappedElementAddress(SElement *inElement) const override + { + if (inElement == NULL) + return NULL; + TElementOffsetMap::const_iterator iter = m_ElementOffsets.find(inElement); + if (iter != m_ElementOffsets.end()) + return reinterpret_cast(iter->second); + return NULL; + } + + const STypeDesc *GetRemappedTypeDescAddress(const STypeDesc *inTypeDesc) const override + { + TTypeDescOffsetMap::const_iterator iter = m_TypeDescOffsets.find((STypeDesc *)inTypeDesc); + if (iter != m_TypeDescOffsets.end()) + return reinterpret_cast(iter->second); + return NULL; + } + const STypeDesc *RemapTypeDesc(const STypeDesc *inOffset) + { + size_t memoryOffset = reinterpret_cast(inOffset); + TOffsetTypeDescMap::iterator iter = + m_OffsetsToTypeDescs.find(static_cast(memoryOffset)); + if (iter != m_OffsetsToTypeDescs.end()) + return iter->second; + return NULL; + } + + SElement *RemapElement(SElement *inElem, size_t memoryOffset) + { + if (inElem) + return reinterpret_cast(reinterpret_cast(inElem) + memoryOffset); + return NULL; + } +}; +} + +bool STypeDesc::operator==(const STypeDesc &inOther) const +{ + if (m_TypeName == inOther.m_TypeName && m_SubtypeName == inOther.m_SubtypeName + && m_Properties.size() == inOther.m_Properties.size()) { + for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { + const SPropertyDesc &lhs = m_Properties[idx]; + const SPropertyDesc &rhs = inOther.m_Properties[idx]; + if (lhs.m_Name != rhs.m_Name || lhs.m_Type != rhs.m_Type) + return false; + } + return true; + } + return false; +} + +Option STypeDesc::FindProperty(QT3DSU32 inNameHash) const +{ + for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { + const SPropertyDesc &theDesc = m_Properties[idx]; + if (Q3DStudio::CHash::HashAttribute(theDesc.m_Name) == inNameHash) + return idx; + } + return Empty(); +} + +Option STypeDesc::FindProperty(CRegisteredString inName) const +{ + for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { + const SPropertyDesc &theDesc = m_Properties[idx]; + if (theDesc.m_Name == inName) + return idx; + } + return Empty(); +} + +Option STypeDesc::FindDynamicProperty(QT3DSU32 inNameHash) const +{ + for (QT3DSU32 idx = 0, end = m_DynamicProperties.size(); idx < end; ++idx) { + const SPropertyDesc &theDesc = m_DynamicProperties[idx]; + if (Q3DStudio::CHash::HashAttribute(theDesc.m_Name) == inNameHash) + return idx; + } + return Empty(); +} + +void STypeDesc::SetHashValue() +{ + size_t typeDescHash = m_TypeName.hash() ^ m_SubtypeName.hash(); + for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { + typeDescHash = typeDescHash ^ m_Properties[idx].m_Name.hash(); + typeDescHash = typeDescHash ^ eastl::hash()(m_Properties[idx].m_Type); + } + // TODO check 64 bit compatibility + m_HashValue = (QT3DSU32)typeDescHash; +} + +QT3DSU32 SPropertyDesc::GetNameHash() const +{ + return Q3DStudio::CHash::HashAttribute(m_Name.c_str()); +} + +Q3DStudio::SAttributeKey SPropertyDesc::GetAttributeKey() const +{ + Q3DStudio::SAttributeKey retval; + memZero(&retval, sizeof(retval)); + retval.m_Type = m_Type; + retval.m_Hash = GetNameHash(); + return retval; +} + +bool SElement::IsUserActive() const +{ + return m_Flags.IsExplicitActive(); +} + +bool SElement::IsIndependent() const +{ + return IsComponent(); +} + +bool SElement::IsGlobalActive() const +{ + return GetActive(); +} +// This may require a mutex to be held. +void SElement::SetGlobalActive(bool active) +{ + SetActive(active); +} + +bool SElement::GetAttribute(QT3DSU32 inHashName, Q3DStudio::UVariant &outValue) const +{ + if (inHashName == Q3DStudio::ATTRIBUTE_NAME) { + outValue.m_StringHandle = m_BelongedPresentation->GetStringTable().GetHandle(m_Name); + return true; + } + if (inHashName == Q3DStudio::CHash::HashAttribute("path")) { + outValue.m_StringHandle = m_BelongedPresentation->GetStringTable().GetHandle(m_Path); + return true; + } + const Q3DStudio::UVariant *valPtr = FindPropertyValue(inHashName); + if (valPtr) { + outValue = *valPtr; + return true; + } + return false; +} + +void SElement::SetAttribute(const Q3DStudio::TAttributeHash inKey, + const Q3DStudio::UVariant inValue) +{ + Option existing = FindProperty(inKey); + if (existing.hasValue() == false) + return; + SetAttribute(*existing, inValue); +} + +void SElement::SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVariant inValue) +{ + Q3DStudio::EAttributeType theType = inKey.first.m_Type; + Q3DStudio::UVariant *currentValue = inKey.second; + QT3DSU32 attHash = inKey.first.GetNameHash(); + switch (theType) { + case Q3DStudio::ATTRIBUTETYPE_FLOAT: // Early return + if (fabs(currentValue->m_FLOAT - inValue.m_FLOAT) < SmallestDifference()) + return; + break; + case Q3DStudio::ATTRIBUTETYPE_FLOAT3: // Early return + if (fabs(currentValue->m_FLOAT3[0] - inValue.m_FLOAT3[0]) < SmallestDifference() + && fabs(currentValue->m_FLOAT3[1] - inValue.m_FLOAT3[1]) < SmallestDifference() + && fabs(currentValue->m_FLOAT3[2] - inValue.m_FLOAT3[2]) < SmallestDifference()) { + return; + } + break; + case Q3DStudio::ATTRIBUTETYPE_STRING: + if (currentValue->m_StringHandle == inValue.m_StringHandle) + return; + break; + default: // Early return + if (currentValue->m_INT32 == inValue.m_INT32) + return; + break; + } + *currentValue = inValue; + + if (Q3DStudio::ATTRIBUTE_EYEBALL == attHash) + SetFlag(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE, inValue.m_INT32 ? true : false); + + if (Q3DStudio::ATTRIBUTE_STARTTIME == attHash || Q3DStudio::ATTRIBUTE_ENDTIME == attHash) + GetActivityZone().UpdateItemInfo(*this); + + /* + if ( inElement->m_Flags & ELEMENTFLAG_REGISTEREDFORATTRIBUTECHANGE ) + m_AttributeChangeCallbacks.FireCallbacks( inElement, theAttribute->m_Key, + thePreviousValue, inValue ); + */ + SetDirty(); +} + +// SElement implementation +QT3DSU32 SElement::GetNameHash() const +{ + return Q3DStudio::CHash::HashString(m_Name.c_str()); +} + +// Q3DStudio::CHash::HashAttribute +Option SElement::FindPropertyIndex(QT3DSU32 inNameHash) const +{ + return m_TypeDescription->FindProperty(inNameHash); +} + +Option SElement::FindPropertyIndex(CRegisteredString inName) const +{ + return m_TypeDescription->FindProperty(inName); +} + +Option SElement::FindDynamicPropertyIndex(QT3DSU32 inNameHash) const +{ + if (m_DynamicTypeDescription) + return m_DynamicTypeDescription->FindDynamicProperty(inNameHash); + else + return Empty(); +} + +QT3DSU32 SElement::GetNumProperties() const +{ + return m_TypeDescription->m_Properties.size(); +} + +QT3DSU32 SElement::GetNumDynamicProperties() const +{ + if (m_DynamicTypeDescription) + return m_DynamicTypeDescription->m_DynamicProperties.size(); + else + return 0; +} + +Option SElement::GetPropertyByIndex(QT3DSU32 inIdx) +{ + if (inIdx < this->m_TypeDescription->m_Properties.size()) + return eastl::make_pair(m_TypeDescription->m_Properties[inIdx], + &TElementPropertyList::GetObjAtIdx(m_PropertyValues, inIdx)); + + return Empty(); +} + +Option SElement::GetDynamicPropertyByIndex(QT3DSU32 inIdx) +{ + if (inIdx < this->m_DynamicTypeDescription->m_DynamicProperties.size()) + return eastl::make_pair(m_DynamicTypeDescription->m_DynamicProperties[inIdx], + &TElementPropertyList::GetObjAtIdx(m_DynamicPropertyValues, inIdx)); + + return Empty(); +} + +Option SElement::GetPropertyByIndex(QT3DSU32 inIdx) const +{ + Option retval = + const_cast(*this).GetPropertyByIndex(inIdx); + if (retval.hasValue()) + return TPropertyDescAndConstValuePtr(*retval); + return Empty(); +} + +void SElement::SetDirty() +{ + if (!m_Flags.IsDirty()) { + m_Flags.SetDirty(true); + // The element is dirty, so place it on the frame data dirty list + m_BelongedPresentation->GetFrameData().GetDirtyList().Push(this); + m_Flags.SetDirty(true); + } +} + +void SElement::SetFlag(Q3DStudio::EElementFlag inFlag, bool inValue) +{ + bool existing = m_Flags & inFlag; + if (existing != inValue && HasActivityZone()) { + m_Flags.clearOrSet(inValue, inFlag); + if (inFlag == Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE) + GetActivityZone().UpdateItemInfo(*this); + else if (inFlag == Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS) + GetActivityZone().UpdateItemScriptStatus(*this); + SetDirty(); + } +} + +bool SElement::HasActivityZone() const +{ + return m_BelongedPresentation->GetActivityZone() != NULL; +} + +qt3ds::runtime::IActivityZone &SElement::GetActivityZone() const +{ + return *m_BelongedPresentation->GetActivityZone(); +} + +SElement &SElement::GetComponentParent() +{ + if (IsComponent()) + return *this; + + SElement *theParent = GetActivityZone().GetItemTimeParent(*this); + if (theParent) + return *theParent; + QT3DS_ASSERT(false); + return *this; +} + +const SElement &SElement::GetComponentParent() const +{ + return const_cast(this)->GetComponentParent(); +} + +SElement *SElement::FindChild(QT3DSU32 inNameHash) +{ + for (SElement *theChild = m_Child; theChild; theChild = theChild->m_Sibling) { + if (theChild->GetNameHash() == inNameHash) + return theChild; + } + return NULL; +} + +Q3DStudio::TTimeUnit SElement::GetInnerTime() const +{ + return GetActivityZone().GetItemComponentTime(const_cast(*this)); +} +// Get the time I am animating at. +Q3DStudio::TTimeUnit SElement::GetOuterTime() const +{ + return GetActivityZone().GetItemLocalTime(const_cast(*this)); +} + +bool SElement::IsDescendent(SElement &inPossibleParent) const +{ + if (m_Parent == NULL) + return false; + if (m_Parent == &inPossibleParent) + return true; + return m_Parent->IsDescendent(inPossibleParent); +} + +bool SComponent::GetPaused() const +{ + return GetTimePolicy().GetPaused(); +} + +bool SComponent::GetPlayBackDirection() const +{ + return GetTimePolicy().GetPlayBackDirection(); +} + +Q3DStudio::CTimePolicy &SComponent::GetTimePolicy() +{ + return *GetActivityZone().GetOwnedTimePolicy(*this); +} + +const Q3DStudio::CTimePolicy &SComponent::GetTimePolicy() const +{ + return const_cast(this)->GetTimePolicy(); +} + +qt3ds::runtime::IElementAllocator & +qt3ds::runtime::IElementAllocator::CreateElementAllocator(NVFoundationBase &inFoundation, + IStringTable &inStringTable) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SElementAllocator)(inFoundation, inStringTable); +} diff --git a/src/Runtime/Source/runtime/Qt3DSElementSystem.h b/src/Runtime/Source/runtime/Qt3DSElementSystem.h new file mode 100644 index 00000000..b9355c55 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSElementSystem.h @@ -0,0 +1,606 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_ELEMENT_SYSTEM_H +#define QT3DS_ELEMENT_SYSTEM_H +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "Qt3DSKernelTypes.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSInvasiveSet.h" +#include "Qt3DSMetadata.h" + +// The qt3ds runtime element system contains the element graph and the data in the element +// graph. + +namespace Q3DStudio { +// class CPresentation; +class IPresentation; +class CTimePolicy; +} + +namespace qt3ds { +namespace foundation { + class IInStream; + class IOutStream; +} +} + +namespace qt3ds { +namespace runtime { + using namespace qt3ds::foundation; + using namespace qt3ds; + class IActivityZone; + namespace element { + struct SPropertyDesc + { + CRegisteredString m_Name; + Q3DStudio::EAttributeType m_Type; + SPropertyDesc() + : m_Type(Q3DStudio::ATTRIBUTETYPE_NONE) + { + } + SPropertyDesc(CRegisteredString inStr, Q3DStudio::EAttributeType inType) + : m_Name(inStr) + , m_Type(inType) + { + } + QT3DSU32 GetNameHash() const; // CHash::HashAttribute + Q3DStudio::SAttributeKey GetAttributeKey() const; + }; + + struct STypeDesc + { + CRegisteredString m_TypeName; + CRegisteredString m_SubtypeName; + // Properties are sorted so that we can quickly create new type descriptions + // when necessary. + NVConstDataRef m_Properties; + eastl::vector m_DynamicProperties; + + private: + QT3DSU32 m_HashValue; // Cached hash value for this type descriptor + public: + STypeDesc() + : m_HashValue(0) + { + } + bool operator==(const STypeDesc &inOther) const; + // Q3DStudio::CHash::HashAttribute + Option FindProperty(QT3DSU32 inNameHash) const; + Option FindProperty(CRegisteredString inName) const; + Option FindDynamicProperty(QT3DSU32 inNameHash) const; + void SetHashValue(); + QT3DSU32 HashCode() const { return m_HashValue; } + }; + + struct SActivationManagerNodeFlagValues + { + enum Enum { + TimeActive = 1 << 1, + TempTimeActive = 1 << 4, + ParticipatesInTimeGraph = 1 << 5, + Script = 1 << 6, + ChildDirty = 1 << 7, + }; + }; + + struct SActivationManagerNodeFlags : public NVFlags + { + bool IsTimeActive() const + { + return operator&(SActivationManagerNodeFlagValues::TimeActive); + } + void SetTimeActive(bool active) + { + clearOrSet(active, SActivationManagerNodeFlagValues::TimeActive); + } + + bool IsTempTimeActive() const + { + return operator&(SActivationManagerNodeFlagValues::TempTimeActive); + } + void SetTempTimeActive(bool value) + { + clearOrSet(value, SActivationManagerNodeFlagValues::TempTimeActive); + } + + // Is this item in the activation manager's scripts list. + bool HasScript() const { return operator&(SActivationManagerNodeFlagValues::Script); } + void SetHasScript(bool value) + { + clearOrSet(value, SActivationManagerNodeFlagValues::Script); + } + + bool IsChildDirty() const + { + return operator&(SActivationManagerNodeFlagValues::ChildDirty); + } + void SetChildDirty() { clearOrSet(true, SActivationManagerNodeFlagValues::ChildDirty); } + void ClearChildDirty() + { + clearOrSet(false, SActivationManagerNodeFlagValues::ChildDirty); + } + }; + + struct SElement; + + struct SActivationManagerNode + { + // IT may seem wasteful to always have start,end time on the node. We need to do this + // however + // in order to transmit information down the timeline at times. Furthermore the + // activation manager + // is free to mangle these times as it sees fit; unlike the attribute start,end time. + QT3DSU32 m_StartTime; + QT3DSU32 m_StopTime; + // Used by the activation manager specifically. + QT3DSU32 m_DirtyIndex; + + // If m_Flags.IsIndependent(), first child is implicitly zero and instead + // this records the time context index assocated with this element node. + // Else this records the first child index. + // These could perhaps be moved to the element flags except it breaks some isolation and + // it just doesn't seem worth it. + SActivationManagerNodeFlags m_Flags; + + SActivationManagerNode() + : m_StartTime(QT3DS_MAX_U32) + , m_StopTime(QT3DS_MAX_U32) + , m_DirtyIndex(QT3DS_MAX_U32) + { + } + }; + + struct SElementFlag : public NVFlags + { + void SetDirty(bool inDirty) { clearOrSet(inDirty, Q3DStudio::ELEMENTFLAG_DIRTY); } + bool IsDirty() const { return this->operator&(Q3DStudio::ELEMENTFLAG_DIRTY); } + + bool IsComponent() const { return this->operator&(Q3DStudio::ELEMENTFLAG_COMPONENT); } + + void SetExplicitActive(bool inValue) + { + clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE); + } + bool IsExplicitActive() const + { + return this->operator&(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE); + } + + void SetActive(bool inValue) + { + clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_GLOBALACTIVE); + } + bool IsActive() const { return this->operator&(Q3DStudio::ELEMENTFLAG_GLOBALACTIVE); } + + void SetPickEnabled(bool inValue) + { + clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_PICKENABLED); + } + bool IsPickEnabled() const + { + return this->operator&(Q3DStudio::ELEMENTFLAG_PICKENABLED); + } + + void SetPlayThrough(bool inValue) + { + clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_PLAYTHROUGH); + } + bool IsPlayThrough() const + { + return this->operator&(Q3DStudio::ELEMENTFLAG_PLAYTHROUGH); + } + + void SetScriptCallbacks(bool inValue) + { + clearOrSet(inValue, Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS); + } + bool HasScriptCallbacks() const + { + return this->operator&(Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS); + } + + bool HasStartEndTime() const + { + return this->operator&(Q3DStudio::ELEMENTFLAG_TIMELINE); + } + }; + + typedef eastl::pair TPropertyDescAndValuePtr; + typedef eastl::pair + TPropertyDescAndConstValuePtr; + typedef eastl::pair TPropertyDescAndValue; + // There is probably some balance here between number of values in a group + // and number of groups. A heuristic of a large application would tell you + // the optimum number of values to groups. + struct SPropertyValueGroup + { + enum { + NumValues = 4, + }; + Q3DStudio::UVariant m_Data[4]; + SPropertyValueGroup *m_NextNode; + SPropertyValueGroup() + : m_NextNode(NULL) + { + for (QT3DSU32 idx = 0; idx < NumValues; ++idx) + m_Data[idx].m_INT32 = 0; + } + }; + + struct SElement + { + CRegisteredString m_Name; // const, do not set after creation. + CRegisteredString m_Path; + const STypeDesc *m_TypeDescription; ///< static information created on load time + // The property values are in order described in the type description. + SPropertyValueGroup *m_PropertyValues; + // dynamic section + STypeDesc *m_DynamicTypeDescription; ///< we may create this on the fly + SPropertyValueGroup *m_DynamicPropertyValues; + + protected: + SElementFlag m_Flags; // Setting these changes things. + public: + QT3DSU32 m_Handle; + QT3DSU32 m_ScriptID; ///< Superfluous, could use handle to link to script representation + QT3DSU32 m_Depth; ///< Distance from this node to the root of the graph. + SElement *m_Parent; ///< Parent element in activity graph + SElement *m_Sibling; ///< Next sibling element in activity graph + SElement *m_Child; ///< First child element in activity graph + void *m_Association; ///< Link to associated asset in scene + Q3DStudio::IPresentation *m_BelongedPresentation; + SActivationManagerNode m_ActivationManagerNode; + + SElement(const STypeDesc &inDesc) + : m_TypeDescription(&inDesc) + , m_PropertyValues(NULL) + , m_DynamicTypeDescription(NULL) + , m_DynamicPropertyValues(NULL) + , m_Handle(0) + , m_ScriptID(0) + , m_Depth(0) + , m_Parent(NULL) + , m_Sibling(NULL) + , m_Child(NULL) + , m_Association(NULL) + , m_BelongedPresentation(NULL) + { + } + QT3DSU32 GetHandle() const { return m_Handle; } + const STypeDesc &GetTypeDescription() const { return *m_TypeDescription; } + void SetTypeDescription(const STypeDesc *inDesc) { m_TypeDescription = inDesc; } + // Q3DStudio::CHash::HashString + QT3DSU32 GetNameHash() const; + const SPropertyValueGroup *GetFirstPropertyGroup() const { return m_PropertyValues; } + void SetFirstPropertyGroup(SPropertyValueGroup *inGroup) { m_PropertyValues = inGroup; } + + SPropertyValueGroup *&UnsafeGetFirstPropertyGroup() { return m_PropertyValues; } + + // In general, use these accessors for attributes, especially setting values. + // The other accessors are fast paths that do not: + // 1. Set dirty flags + // 2. Notify the activation zone of changes if setting start,end time. + // 3. Notify any other subsystems. + bool GetAttribute(QT3DSU32 inHashName, Q3DStudio::UVariant &outValue) const; + // Triggers updating various subcomponents based on attribute key. + void SetAttribute(const Q3DStudio::TAttributeHash inKey, + const Q3DStudio::UVariant inValue); + // Triggers updating various subcomponents without requiring a new property lookup. + void SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVariant inNewValue); + + // Q3DStudio::CHash::HashAttribute + Option FindPropertyIndex(QT3DSU32 inNameHash) const; + Option FindPropertyIndex(CRegisteredString inName) const; + + Option FindDynamicPropertyIndex(QT3DSU32 inNameHash) const; + + QT3DSU32 GetNumProperties() const; + QT3DSU32 GetAttributeCount() const { return GetNumProperties(); } + + QT3DSU32 GetNumDynamicProperties() const; + QT3DSU32 GetDynamicAttributeCount() const { return GetNumDynamicProperties(); } + + // Note that if you set a value then this object is dirty. + // Bypasses special checks in setAttribute. In general, use setAttribute. + Option GetPropertyByIndex(QT3DSU32 inIdx); + Option GetPropertyByIndex(QT3DSU32 inIdx) const; + + Option GetDynamicPropertyByIndex(QT3DSU32 inIdx); + + Q3DStudio::UVariant *FindPropertyValue(QT3DSU32 inNameHash) + { + Option idx = FindPropertyIndex(inNameHash); + if (idx.hasValue()) { + Option theVal = GetPropertyByIndex(idx); + if (theVal.hasValue()) + return theVal->second; + } + return NULL; + } + const Q3DStudio::UVariant *FindPropertyValue(QT3DSU32 inNameHash) const + { + Option idx = FindPropertyIndex(inNameHash); + if (idx.hasValue()) { + Option theVal = GetPropertyByIndex(idx); + if (theVal.hasValue()) + return theVal->second; + } + return NULL; + } + Q3DStudio::UVariant *FindPropertyValue(CRegisteredString inNameHash) + { + Option idx = FindPropertyIndex(inNameHash); + if (idx.hasValue()) { + Option theVal = GetPropertyByIndex(idx); + if (theVal.hasValue()) + return theVal->second; + } + return NULL; + } + + const Q3DStudio::UVariant *FindPropertyValue(CRegisteredString inNameHash) const + { + Option idx = FindPropertyIndex(inNameHash); + if (idx.hasValue()) { + Option theVal = GetPropertyByIndex(idx); + if (theVal.hasValue()) + return theVal->second; + } + return NULL; + } + + Option FindProperty(QT3DSU32 inNameHash) + { + Option idx = FindPropertyIndex(inNameHash); + if (idx.hasValue()) + return GetPropertyByIndex(*idx); + return Empty(); + } + + Option FindDynamicProperty(QT3DSU32 inNameHash) + { + Option idx = FindDynamicPropertyIndex(inNameHash); + if (idx.hasValue()) + return GetDynamicPropertyByIndex(*idx); + + return Empty(); + } + + SElement *GetParent() { return m_Parent; } + const SElement *GetParent() const { return m_Parent; } + SElement *GetSibling() { return m_Sibling; } + const SElement *GetSibling() const { return m_Sibling; } + SElement *GetChild() { return m_Child; } + const SElement *GetChild() const { return m_Child; } + CRegisteredString GetType() const { return m_TypeDescription->m_TypeName; } + bool IsComponent() const { return m_Flags.IsComponent(); } + + Q3DStudio::IPresentation *GetBelongedPresentation() { return m_BelongedPresentation; } + void SetBelongedPresentation(Q3DStudio::IPresentation &inPresentation) + { + m_BelongedPresentation = &inPresentation; + } + + // Set flags bypassing the dirty system *and* updates to the activity zone. + // do not do this unless you are sure you do not want any side effects. + SElementFlag &Flags() { return m_Flags; } + + // User flag that is set and is persistent + void SetExplicitActive(bool inValue) + { + SetFlag(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE, inValue); + } + bool IsExplicitActive() const { return m_Flags.IsExplicitActive(); } + + // Flag set by the activity manager. + void SetActive(bool inValue) { SetFlag(Q3DStudio::ELEMENTFLAG_GLOBALACTIVE, inValue); } + bool GetActive() const { return m_Flags.IsActive(); } + + void SetPickEnabled(bool inValue) + { + SetFlag(Q3DStudio::ELEMENTFLAG_PICKENABLED, inValue); + } + bool IsPickEnabled() const { return m_Flags.IsPickEnabled(); } + + void SetPlayThrough(bool inValue) + { + SetFlag(Q3DStudio::ELEMENTFLAG_PLAYTHROUGH, inValue); + } + bool IsPlayThrough() const { return m_Flags.IsPlayThrough(); } + + void SetScriptCallbacks(bool inValue) + { + SetFlag(Q3DStudio::ELEMENTFLAG_SCRIPTCALLBACKS, inValue); + } + bool HasScriptCallbacks() const { return m_Flags.HasScriptCallbacks(); } + + bool IsDirty() const { return m_Flags.IsDirty(); } + + bool GetFlag(Q3DStudio::EElementFlag inFlag) const { return m_Flags.operator&(inFlag); } + + void SetDirty(); + void SetFlag(Q3DStudio::EElementFlag inFlag, bool inValue); + void SetFlag(Q3DStudio::EElementFlag inFlag, int inValue) + { + SetFlag(inFlag, inValue ? true : false); + } + qt3ds::runtime::IActivityZone &GetActivityZone() const; + bool HasActivityZone() const; + // Floating point number differences above this trigger a setDirty call. + static float SmallestDifference() { return 0.000001f; } + SElement &GetComponentParent(); + const SElement &GetComponentParent() const; + SElement *FindChild(QT3DSU32 inNameHash); + // Get the time of my first noncomponent child or + // my time if I am not a component. + Q3DStudio::TTimeUnit GetInnerTime() const; + // Get the time I am animating at. + Q3DStudio::TTimeUnit GetOuterTime() const; + bool IsDescendent(SElement &inPossibleParent) const; + void *GetAssociation() const { return m_Association; } + void SetAssociation(void *inAssoc) { m_Association = inAssoc; } + QT3DSU32 GetUncachedDepth() const + { + if (m_Parent) + return m_Parent->GetUncachedDepth() + 1; + return 0; + } + void SetDepth() { m_Depth = GetUncachedDepth(); } + QT3DSU32 Depth() const { return m_Depth; } + + bool IsUserActive() const; + + bool IsIndependent() const; + + bool IsGlobalActive() const; + // This may require a mutex to be held. + void SetGlobalActive(bool active); + + bool IsTimeActive() const + { + if (m_Parent != NULL) + return m_ActivationManagerNode.m_Flags.IsTimeActive(); + return true; + } + + bool DoesParticipateInTimeGraph() const { return m_Flags.HasStartEndTime(); } + + bool IsGlobalActive(bool inParentActive) const + { + bool ta = IsTimeActive(); + bool ua = IsUserActive(); + + return ta && ua && inParentActive; + } + }; + + struct SGetElementNodeDirtyIndex + { + QT3DSU32 operator()(const SElement &inNode) + { + return inNode.m_ActivationManagerNode.m_DirtyIndex; + } + }; + struct SSetElementNodeDirtyIndex + { + void operator()(SElement &inNode, QT3DSU32 val) + { + inNode.m_ActivationManagerNode.m_DirtyIndex = val; + } + }; + + struct SActivationManagerNodeDirtyList + : public InvasiveSet + { + typedef InvasiveSet + TBaseType; + SActivationManagerNodeDirtyList(NVAllocatorCallback &callback) + : TBaseType(callback, "SActivationManagerNodeDirtyList") + { + } + }; + + struct SComponent : public SElement + { + Q3DStudio::SAlignedTimeUnit m_BeginTime; + Q3DStudio::SAlignedTimeUnit m_Duration; + + // Slide related + QT3DSU8 m_SlideCount; ///< Number of slides starting from base index + QT3DSU8 m_CurrentSlide; ///< Current slide number + QT3DSU8 m_PreviousSlide; ///< Previous slide number + SComponent(const STypeDesc &inDesc) + : SElement(inDesc) + , m_SlideCount(0) + , m_CurrentSlide(0) + , m_PreviousSlide(0) + { + } + + QT3DSU8 GetCurrentSlide() const { return m_CurrentSlide; } + void SetCurrentSlide(QT3DSU8 inSlide) + { + m_PreviousSlide = m_CurrentSlide; + m_CurrentSlide = inSlide; + } + QT3DSU8 GetSlideCount() const { return m_SlideCount; } + QT3DSU8 GetPreviousSlide() const { return m_PreviousSlide; } + bool GetPaused() const; + bool GetPlayBackDirection() const; + Q3DStudio::CTimePolicy &GetTimePolicy(); + const Q3DStudio::CTimePolicy &GetTimePolicy() const; + }; + } + // Global store of all elements, values. + class IElementAllocator : public NVRefCounted + { + public: + // Performs coalesing of element types so that there are the least number of type + // descriptions + // Certain properties, like name, eyeball, are never in the property description. + virtual element::SElement & + CreateElement(CRegisteredString inName, CRegisteredString inType, + CRegisteredString inSubType, + NVConstDataRef inPropertyDescriptions, + Q3DStudio::IPresentation *inPresentation, element::SElement *inParent, + bool inIsComponent) = 0; + + virtual void ReleaseElement(element::SElement &inElement, bool inRecurse) = 0; + + virtual Option + CreateDynamicProperty(Q3DStudio::IRuntimeMetaData &theMetaData, element::SElement &element, + CRegisteredString inName) = 0; + + virtual element::SElement *FindElementByHandle(QT3DSU32 inElementHandle) = 0; + // Returns an element pointer that when added to the return value of load will be a valid + // element. + virtual element::SElement * + GetRemappedElementAddress(element::SElement *inElement) const = 0; + virtual const element::STypeDesc * + GetRemappedTypeDescAddress(const element::STypeDesc *inTypeDesc) const = 0; + // If load is successful, then returns an address that can be added to elements and the root + // element. + + static IElementAllocator &CreateElementAllocator(NVFoundationBase &inFoundation, + IStringTable &inStringTable); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSEvent.h b/src/Runtime/Source/runtime/Qt3DSEvent.h new file mode 100644 index 00000000..aef317a5 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSEvent.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSKernelTypes.h" +#include "Qt3DSElementSystem.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +/// Common structure used as both Events and Commands +struct SEventCommand +{ + TElement *m_Target; ///< The target of this action + TEventCommandHash m_Type; ///< Type of action to perform + UVariant m_Arg1; ///< Argument 1 + UVariant m_Arg2; ///< Argument 2 + UINT8 m_Arg1Type; ///< EAttributeType for arg1 variant + UINT8 m_Arg2Type; ///< EAttributeType for arg2 variant + + BOOL m_IsEvent : 1; ///< This is an Event or Command + BOOL m_BubbleUp : 1; ///< Bubble up to scene parent (2.4.2: theEvent:stopPropagation) + BOOL m_BubbleDown : 1; ///< Bubble down to scene children (2.4.2: theEvent:stopPropagation) + BOOL m_Done : 1; ///< Stop further handling (2.4.3: theEvent:stopImmediatePropagation) + + UINT8 m_Unused; ///< (padding) +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSEventCallbacks.cpp b/src/Runtime/Source/runtime/Qt3DSEventCallbacks.cpp new file mode 100644 index 00000000..25d720ea --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSEventCallbacks.cpp @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSEventCallbacks.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + */ +CEventCallbacks::CEventCallbacks() + : m_EventCallbacksList(0, 0, "EventCallbacksList") + , m_CallbackList(0, 0, "CallbackList") +{ +} + +//============================================================================== +/** + * Destructor + */ +CEventCallbacks::~CEventCallbacks() +{ + UnregisterAllCallbacks(); +} + +//============================================================================== +/** + * Registers a callback to be triggered when a specific event is fired on an + * element. + * @param inElement element to monitor + * @param inEventHash event hash to monitor + * @param inCallback static callback function + * @param inContextData arbitary data pointer + */ +void CEventCallbacks::RegisterCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) +{ + TEventCallbacksList *theEventCallbackList = NULL; + + // Look for the list of callbacks for this element + FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) + { + if (inElement == (*theEntry)->m_Element) { + theEventCallbackList = &(*theEntry)->m_EventEntries; + break; + } + } + + // Create a new list of callbacks if it does not already exist + if (!theEventCallbackList) { + SElementCallbackEntry *theElementCallbackEntry = + Q3DStudio_new(SElementCallbackEntry) SElementCallbackEntry(); + theElementCallbackEntry->m_Element = inElement; + m_EventCallbacksList.Push(theElementCallbackEntry); + theEventCallbackList = &m_EventCallbacksList.Top()->m_EventEntries; + } + + TCallbackList *theElementCallbackList = NULL; + + // Look for the list of callbacks for this event + FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList)) + { + if (inEventHash == (*theEntry)->m_EventHash) { + theElementCallbackList = &(*theEntry)->m_Callbacks; + break; + } + } + + // Create a new list of callbacks if it does not already exist + if (!theElementCallbackList) { + SEventCallbackEntry *theEventCallbackEntry = + Q3DStudio_new(SEventCallbackEntry) SEventCallbackEntry(); + theEventCallbackEntry->m_EventHash = inEventHash; + theEventCallbackList->Push(theEventCallbackEntry); + theElementCallbackList = &theEventCallbackList->Top()->m_Callbacks; + } + + // Insert callback + SCallbackEntry theCallbackEntry = { inCallback, inContextData }; + theElementCallbackList->Push(theCallbackEntry); +} + +//============================================================================== +/** + * Unregisters an event callback. + * @param inElement element to monitor + * @param inEventHash event hash to monitor + * @param inCallback static callback function + * @param inContextData arbitary data pointer + * @param outLast indicates if element no longer has callbacks registered + * @return BOOL true if callback is unregistered successfully + */ +BOOL CEventCallbacks::UnregisterCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData, + BOOL &outLast) +{ + outLast = false; + + TEventCallbacksList *theEventCallbackList = NULL; + + INT32 theEventListIndex = 0; + SElementCallbackEntry *theFoundEntry = NULL; + FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) + { + if (inElement == (*theEntry)->m_Element) { + theFoundEntry = *theEntry; + theEventCallbackList = &(*theEntry)->m_EventEntries; + break; + } + ++theEventListIndex; + } + + if (!theEventCallbackList) + return false; + + TCallbackList *theElementCallbackList = NULL; + + INT32 theElementListIndex = 0; + SEventCallbackEntry *theEventCallbackEntry = NULL; + FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList)) + { + if (inEventHash == (*theEntry)->m_EventHash) { + theEventCallbackEntry = *theEntry; + theElementCallbackList = &(*theEntry)->m_Callbacks; + break; + } + ++theElementListIndex; + } + + if (!theElementCallbackList) + return false; + + INT32 theCallbackIndex = 0; + FOR_ARRAY(SCallbackEntry, theEntry, (*theElementCallbackList)) + { + if (inCallback == theEntry->m_Function && inContextData == theEntry->m_ContextData) { + theElementCallbackList->Remove(theCallbackIndex); + + if (theElementCallbackList->GetCount() == 0) { + Q3DStudio_delete(theEventCallbackEntry, SEventCallbackEntry); + theEventCallbackList->Remove(theElementListIndex); + } + + if (theEventCallbackList->GetCount() == 0) { + Q3DStudio_delete(theFoundEntry, SElementCallbackEntry); + m_EventCallbacksList.Remove(theEventListIndex); + outLast = true; + } + + return true; + } + ++theCallbackIndex; + } + + return false; +} + +//============================================================================== +/** + * Unregisters all callbacks. + */ +void CEventCallbacks::UnregisterAllCallbacks() +{ + FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) + Q3DStudio_delete(*theEntry, SElementCallbackEntry); + m_EventCallbacksList.Clear(); +} + +//============================================================================== +/** + * Fires event callbacks + * @param ioEvent the event that was fired + */ +void CEventCallbacks::FireCallbacks(SEventCommand &ioEvent) +{ + TEventCallbacksList *theEventCallbackList = NULL; + + // Look for the list of callbacks for this element + FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList) + { + if (ioEvent.m_Target == (*theEntry)->m_Element) { + theEventCallbackList = &(*theEntry)->m_EventEntries; + break; + } + } + + if (!theEventCallbackList) + return; + + // Look for the list of callbacks for this event + FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList)) + { + if (ioEvent.m_Type == (*theEntry)->m_EventHash) { + PerformCallbacks((*theEntry)->m_Callbacks, ioEvent); + break; + } + } +} + +//============================================================================== +/** + * Executing a list of callbacks + * @param inCallbackList the list of callbacks to invoke + * @param ioEvent the event to pass to the callbacks + */ +void CEventCallbacks::PerformCallbacks(TCallbackList &inCallbackList, SEventCommand &ioEvent) +{ + // As the callbacks can potentially do a register/unregister that would alter the call list, + // it is safer to get a clean copy of the call list to iterate through. + + // Clumsy way to do a m_CallbackList = inCallbackList + m_CallbackList.Clear(false); + m_CallbackList.Reserve(inCallbackList.GetCount()); + FOR_ARRAY(SCallbackEntry, theEntry, inCallbackList) + m_CallbackList.Push(*theEntry); + + // Invoking the callbacks + FOR_ARRAY(SCallbackEntry, theEntry, m_CallbackList) + theEntry->m_Function(theEntry->m_ContextData, ioEvent); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSEventCallbacks.h b/src/Runtime/Source/runtime/Qt3DSEventCallbacks.h new file mode 100644 index 00000000..5c17477d --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSEventCallbacks.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "Qt3DSEvent.h" +#include "Qt3DSMemory.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Typedefs +//============================================================================== +typedef void (*TEventCallback)(void *inContextData, SEventCommand &ioEvent); + +//============================================================================== +/** + * Manages the various events callbacks in the system. It fires the + * registered callbacks when an event was triggered. + */ +class CEventCallbacks +{ + //============================================================================== + // Structs + //============================================================================== +protected: + struct SCallbackEntry + { + TEventCallback m_Function; ///< Callback function pointer + void *m_ContextData; ///< User data + }; + typedef CArray TCallbackList; ///< Array of callbacks regisgtered + + struct SEventCallbackEntry + { + SEventCallbackEntry() + : m_EventHash(0) + { + } + ~SEventCallbackEntry() {} + + TEventCommandHash m_EventHash; ///< The event of interest + TCallbackList m_Callbacks; ///< List of callbacks listening to this event + + private: // Disabled Copy Construction + SEventCallbackEntry(const SEventCallbackEntry &); + SEventCallbackEntry &operator=(const SEventCallbackEntry &); + }; + typedef CArray TEventCallbacksList; ///< Array of events with callback + + struct SElementCallbackEntry + { + SElementCallbackEntry() + : m_Element(NULL) + { + } + ~SElementCallbackEntry() + { + FOR_ARRAY(SEventCallbackEntry *, theEntry, m_EventEntries) + Q3DStudio_delete(*theEntry, SEventCallbackEntry); + } + + TElement *m_Element; ///< Element to monitor for event + TEventCallbacksList m_EventEntries; ///< List of events listened on this element + + private: // Disabled Copy Construction + SElementCallbackEntry(const SElementCallbackEntry &); + SElementCallbackEntry &operator=(const SElementCallbackEntry &); + }; + typedef CArray + TElementCallbacksList; ///< Array of elements with callbacks + + //============================================================================== + // Fields + //============================================================================== +protected: + TElementCallbacksList m_EventCallbacksList; ///< List of event callbacks + TCallbackList m_CallbackList; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CEventCallbacks(); + ~CEventCallbacks(); + +public: // Registration + void RegisterCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData); + BOOL UnregisterCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData, BOOL &outLast); + void UnregisterAllCallbacks(); + +public: // Operation + void FireCallbacks(SEventCommand &ioEvent); + +protected: + void PerformCallbacks(TCallbackList &inCallbackList, SEventCommand &ioEvent); + +private: // Disabled Copy Construction + CEventCallbacks(const CEventCallbacks &); + CEventCallbacks &operator=(const CEventCallbacks &); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSFrameworkTypes.h b/src/Runtime/Source/runtime/Qt3DSFrameworkTypes.h new file mode 100644 index 00000000..8cb5c3b8 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSFrameworkTypes.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTypes.h" +#include "Qt3DSArray.h" +#include "Qt3DSVector3.h" +#include "Qt3DSMatrix.h" +#include "Qt3DSBoundingBox.h" +#include "Qt3DSKernelTypes.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSIComponentManager.h b/src/Runtime/Source/runtime/Qt3DSIComponentManager.h new file mode 100644 index 00000000..8185da2d --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSIComponentManager.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSTimePolicy.h" +#include "foundation/Qt3DSOption.h" + +//============================================================================== +// Includes +//============================================================================== + +namespace qt3ds { +namespace runtime { + namespace element { + struct TElement; + struct TComponent; + } +} +} +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +struct IComponentTimeOverrideFinishedCallback +{ +protected: + virtual ~IComponentTimeOverrideFinishedCallback() {} +public: + virtual void OnTimeFinished() = 0; + virtual void Release() = 0; +}; + +typedef qt3ds::foundation::Option TTimePolicyModeOption; +typedef qt3ds::foundation::Option TInt32Option; +typedef qt3ds::foundation::Option TULongOption; +typedef qt3ds::foundation::Option TBoolOption; + +struct SComponentGotoSlideData +{ + INT32 m_Slide; + TTimePolicyModeOption m_Mode; + //-2 means previous, -1 means next, 1-N means slide + TInt32Option m_PlaythroughTo; + TULongOption m_StartTime; + FLOAT m_Rate; + bool m_Reverse; + TBoolOption m_Paused; + + // No mode means use the mode in the slide data. + SComponentGotoSlideData(INT32 inSlide = 0, + TTimePolicyModeOption inMode = TTimePolicyModeOption(), + TInt32Option inPlayThrough = TInt32Option(), + TULongOption inStartTime = TULongOption(), FLOAT inRate = 1.0f, + bool inReverse = false, TBoolOption inPaused = TBoolOption()) + : m_Slide(inSlide) + , m_Mode(inMode) + , m_PlaythroughTo(inPlayThrough) + , m_StartTime(inStartTime) + , m_Rate(inRate) + , m_Reverse(inReverse) + , m_Paused(inPaused) + { + } +}; + +//============================================================================== +/** + * @interface IComponentManager + * Base interface of the container of all the components in the presentation. + * This specify the basic operations required to implement a Component manager + * object that works well with the kernel. + */ +class IComponentManager +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + virtual ~IComponentManager() {} + +public: // Promotion + virtual TComponent *GetComponent(TElement *inElement) = 0; + +public: // Slides + virtual void GotoSlideIndex(TElement *inComponent, const SComponentGotoSlideData &inGotoData, + BOOL inSlideExit = true) = 0; + virtual void GotoSlideName(TElement *inComponent, const TStringHash inSlideHashName) = 0; + virtual void GoToBackSlide(TElement *inComponent) = 0; + virtual void GoToNextSlide(TElement *inComponent, const INT32 inDecrement = 1) = 0; + virtual void GoToPreviousSlide(TElement *inComponent, const INT32 inDecrement = 1) = 0; + + virtual UINT8 GetSlideCount(TElement *inComponent) = 0; + virtual UINT8 GetCurrentSlide(TElement *inComponent) = 0; + virtual const CHAR *GetCurrentSlideName(TElement *inComponent) = 0; + + virtual void OnElementDeactivated(TElement *inElement) = 0; + + virtual void SetComponentTimeOverride(TElement *inElement, TTimeUnit inEndTime, + FLOAT inInterpolation, + IComponentTimeOverrideFinishedCallback *inCallback) = 0; + + virtual void SetupComponentGotoSlideCommand(TElement *inElement, + const SComponentGotoSlideData &inGotoSlideData) = 0; + virtual bool HasComponentGotoSlideCommand(TElement *inElement) = 0; + virtual SComponentGotoSlideData GetComponentGotoSlideCommand(TElement *inElement) = 0; + virtual void ReleaseComponentGotoSlideCommand(TElement *inElement) = 0; + +public: // Time + virtual void GoToTime(TElement *inComponent, const TTimeUnit inTime) = 0; + virtual void SetPause(TElement *inComponent, const BOOL inPause) = 0; + virtual void SetTimePolicy(TElement *inComponent, const TTimeUnit inLoopDuration, + const UINT32 inRepetitions, const BOOL inPingPong, + const BOOL inPlayThrough) = 0; + + virtual BOOL GetPause(TElement *inComponent) = 0; + virtual BOOL GetPlayBackDirection(TElement *inComponent) = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSIInputSystem.h b/src/Runtime/Source/runtime/Qt3DSIInputSystem.h new file mode 100644 index 00000000..6cd201fb --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSIInputSystem.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "Qt3DSInputEngine.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Input system interface + */ +class IInputSystem : public CInputEngine +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + virtual ~IInputSystem() {} + +public: // Processing + virtual void UpdateInput() = 0; + virtual void ProcessInput() = 0; + +protected: // Input System handler + virtual void CheckMouseEvent() = 0; + virtual void CheckKeyboardEvent() = 0; + virtual void CheckJoystickEvent() = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSIScene.h b/src/Runtime/Source/runtime/Qt3DSIScene.h new file mode 100644 index 00000000..8872b93f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSIScene.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSBounds3.h" +#include "Qt3DSBoundingBox.h" +namespace qt3ds { +namespace render { + class IImageLoadListener; +} +} + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class IPresentation; +class RuntimeMatrix; +struct SPickFrame; + +//============================================================================== +/** +* @interface IScene +* +* Runtime interface to the renderer's representation of a presentation. Scenes are +* created by the SceneManager and rendered via a lower level rendering system. +*/ +struct STextSizes +{ + INT32 m_Width; + INT32 m_Height; + STextSizes() + : m_Width(0) + , m_Height(0) + { + } + STextSizes(INT32 w, INT32 h) + : m_Width(w) + , m_Height(h) + { + } +}; + +struct SMousePosition +{ + INT32 m_X; + INT32 m_Y; + SMousePosition(INT32 x, INT32 y) + : m_X(x) + , m_Y(y) + { + } + SMousePosition() + : m_X(0) + , m_Y(0) + { + } +}; + +struct SCameraRect +{ + float m_Left; + float m_Top; + float m_Right; + float m_Bottom; + SCameraRect(float l = 0.0f, float t = 0.0f, float r = 0.0f, float b = 0.0f) + : m_Left(l) + , m_Top(t) + , m_Right(r) + , m_Bottom(b) + { + } + + bool IsValid() const { return fabs(m_Right - m_Left) > 0.0f; } +}; + +class IScene +{ + //============================================================================== + // Methods + //============================================================================== +protected: + virtual ~IScene() {} + +public: // Base Interface + virtual IPresentation &GetPresentation() = 0; + + virtual void SetUserData(void *inUserData) = 0; + virtual void *GetUserData() = 0; + + // virtual void Clone( TElementList& inElements, TElementList& inElementClones, TElement* + // inNewParent = NULL ) = 0; + virtual void CalculateGlobalTransform(TElement *inElement, RuntimeMatrix &outTransform) = 0; + virtual void SetLocalTransformMatrix(TElement *inElement, const RuntimeMatrix &inTransform) = 0; + // Get bounding box in global space + virtual CBoundingBox GetBoundingBox(TElement *inElement, bool inSelfOnly) = 0; + // Get bounding box in local space. + virtual CBoundingBox GetLocalBoundingBox(TElement *inElement, bool inSelfOnly) = 0; + + // The final argument, inHasTransparency has 3 possible values, + // 0 for no transparency, 1 for hasTransparency, -1 for unknown + virtual void SetTextureData(TElement *inElement, const unsigned char *inBuffer, + INT32 inBufferLength, INT32 inWidth, INT32 inHeight, + qt3ds::render::NVRenderTextureFormats::Enum inFormat, + INT32 inHasTransparency = -1) = 0; + + virtual bool CreateOrSetMeshData(const char *inPathStr, unsigned char *vertData, + unsigned int numVerts, unsigned int vertStride, + unsigned int *indexData, unsigned int numIndices, + qt3ds::NVBounds3 &objBounds) = 0; + + virtual STextSizes MeasureText(TElement *inElement, const char *inTextStr) = 0; + + virtual STextSizes GetPresentationDesignDimensions() = 0; + // If the rect's right - left == 0.0, this method failed. Possibly because the layer is just + // direct-rendering + // a sub-presentation. + virtual SCameraRect GetCameraBounds(TElement &inElement) = 0; + + virtual void PositionToScreen(TElement &inElement, qt3ds::QT3DSVec3 &inPos, + qt3ds::QT3DSVec3 &outScreen) = 0; + virtual void ScreenToPosition(TElement &inElement, qt3ds::QT3DSVec3 &inScreen, + qt3ds::QT3DSVec3 &outPos) = 0; + + // This is the best place for now... + virtual void GetImageInfoFromRenderEngine(TElement *inElement, INT32 &ioWidth, + INT32 &ioHeight) = 0; + + virtual qt3ds::foundation::CRegisteredString RegisterStr(const char *inStr) = 0; + + virtual Q3DStudio::INT32 + LoadImageBatch(qt3ds::foundation::CRegisteredString *inFullPaths, INT32 inNumPaths, + qt3ds::foundation::CRegisteredString inDefaultImage, + qt3ds::render::IImageLoadListener *inLoadCallback = NULL) = 0; + + virtual SMousePosition WindowToPresentation(const SMousePosition &inWindowPos) = 0; + + virtual void RegisterOffscreenRenderer(const char *inKey) = 0; + + virtual void Release() = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h b/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h new file mode 100644 index 00000000..6dd04074 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSIComponentManager.h" +#include "EASTL/vector.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSRefCounted.h" +//============================================================================== +// Namespace +//============================================================================== +namespace qt3ds { +namespace runtime { + class IApplication; + class IApplicationCore; +} +} +namespace qt3ds { +namespace state { + namespace debugger { + class IMultiProtocolSocket; + } +} +} +namespace qt3ds { +namespace render { + class IThreadPool; +} +} + +struct script_State; + +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +struct SEventCommand; +class IPresentation; + +//============================================================================== +/** + * @interface IScriptBridge + * @brief Callback and load interface for a script engine. + */ + +class IScriptTableProvider +{ +protected: + virtual ~IScriptTableProvider() {} +public: + virtual void CreateTable(script_State *inState) = 0; +}; + +struct SScriptEngineGotoSlideArgs +{ + TTimePolicyModeOption m_Mode; + //-2 means previous, -1 means next, 1-N means slide + const char *m_PlaythroughTo; + TULongOption m_StartTime; + float m_Rate; + bool m_Reverse; + TBoolOption m_Paused; + SScriptEngineGotoSlideArgs() + : m_PlaythroughTo(NULL) + , m_Rate(1.0f) + , m_Reverse(false) + { + } +}; + +class CScriptEngineCallFunctionArgRetriever +{ +public: + CScriptEngineCallFunctionArgRetriever(const char *inArguments) + : m_ArgumentString(inArguments) + { + } + virtual ~CScriptEngineCallFunctionArgRetriever() {} + // Retrieve argument + // Return value: -1 error; otherwise it indicates argument count + virtual int RetrieveArgument(script_State *inState); + virtual eastl::string GetArgDescription(); + +protected: + const char *m_ArgumentString; +}; + +class IScriptBridge : public qt3ds::foundation::NVRefCounted +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + virtual ~IScriptBridge() {} + +public: // thread + // After this call all public functions are protected by a mutex + virtual void EnableMultithreadedAccess() = 0; + // After this call all public functions are not threadsafe. + virtual void DisableMultithreadedAccess() = 0; + +public: // Settings + virtual void SetApplicationCore(qt3ds::runtime::IApplicationCore &inApplication) = 0; + virtual void SetApplication(qt3ds::runtime::IApplication &inApplication) = 0; + +public: // Scripts + // Both loads script, create an self table -> scriptIndex in a behaviors table + // LoadScript goes further by registering scriptIndex->inPresentation, and inOwner->m_ScriptID= + // scriptIndex + virtual void LoadScript(IPresentation *inPresentation, TElement *inOwner, + const CHAR *inName) = 0; + virtual Q3DStudio::INT32 InitializeApplicationBehavior(const char *inProjectRelativePath) = 0; + +public: // Script functions and Callbacks + virtual void ProcessFrameCallbacks(IPresentation *inPresentation) = 0; + // Call a member function inFnName from self table whose script index is given by inApp + virtual void ExecuteApplicationScriptFunction(Q3DStudio::INT32 inApp, const char *inFnName) = 0; + virtual void CallFunction(const char *behavior, const char *handler, + CScriptEngineCallFunctionArgRetriever &inArgRetriever) = 0; + +public: // Custom Actions + virtual void ProcessSignal(IPresentation *inPresentation, + const SEventCommand &inCommand) = 0; + virtual void ProcessCustomActions(IPresentation *inPresentation, + const SEventCommand &inCommand) = 0; + virtual void ProcessCustomCallback(IPresentation *inPresentation, + const SEventCommand &inCommand) = 0; + +public: // Elements + // Use inProvider to create a new table and associate with inElement: currently a render plugin + // element this mimics render plugin as an behavior element + virtual void SetTableForElement(TElement &inElement, IScriptTableProvider &inProvider) = 0; + virtual void SetAttribute(const char *element, const char *attName, const char *value) = 0; + virtual void FireEvent(const char *element, const char *evtName) = 0; + virtual void SetDataInputValue(const QString &name, const QVariant &value) = 0; + +public: // Components + virtual void GotoSlide(const char *component, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs) = 0; + virtual void GotoSlideRelative(const char *component, bool inNextSlide, bool inWrap, + const SScriptEngineGotoSlideArgs &inArgs) = 0; + +public: // Presentation + virtual void SetPresentationAttribute(const char *presId, const char *attName, + const char *attValue) = 0; + +public: // Multimedia + virtual bool PlaySoundFile(const char *soundPath) = 0; + +public: // Miscellaneous + virtual void EnableDebugging(qt3ds::state::debugger::IMultiProtocolSocket &socket) = 0; + virtual void EnableProfiling() = 0; + virtual void StepGC() = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSIStateful.h b/src/Runtime/Source/runtime/Qt3DSIStateful.h new file mode 100644 index 00000000..0eca293e --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSIStateful.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSArray.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +class IStatefulStackBase +{ +public: + virtual void PushState() = 0; + virtual void PopState() = 0; +}; + +template +class IStatefulStack : public IStatefulStackBase +{ +public: + IStatefulStack(T &inStateProperty) + : m_StateProperty(inStateProperty) + { + } + + virtual ~IStatefulStack(){}; + +public: + virtual void PushState() { m_States.Push(m_StateProperty); } + virtual void PopState() { m_StateProperty = m_States.Pop(); } + +protected: + T &m_StateProperty; + CArray m_States; +}; + +} // namespace Q3DStudio \ No newline at end of file diff --git a/src/Runtime/Source/runtime/Qt3DSIText.h b/src/Runtime/Source/runtime/Qt3DSIText.h new file mode 100644 index 00000000..c4694fe2 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSIText.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class CWorld; +class CRenderStateManager; + +class IText +{ +public: // Text update + virtual void Update(CWorld &inWorld, CVector3 &outBoxMin, CVector3 &outBoxMax) = 0; + virtual void Apply(CRenderStateManager &inRenderStateManager) = 0; + static IText *GetIText(INT32 inAssociation); +}; + +} // namespace Q3DStudio \ No newline at end of file diff --git a/src/Runtime/Source/runtime/Qt3DSInputDefs.h b/src/Runtime/Source/runtime/Qt3DSInputDefs.h new file mode 100644 index 00000000..447e424b --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSInputDefs.h @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Mouse button state flags + * There is some discrepancy between mouse state and mouse events. + * + * Mouse button state refers to the actual state of the button as captured + * by the input engine. The logical states are: up, pressed, down and released. + * + * Mouse events are generated by Kernel (in CKernel::SetPickFrame), and current + * support is only for pressed and released. This translates to the respective + * MOUSE_DOWN and MOUSE_UP. + * + * Therefore, a mapping would be: + * STATE_MOUSE_PRESSED -> EVENT_MOUSE_DOWN + * STATE_MOUSE_RELEASED -> EVENT_MOUSE_UP + * STATE_MOUSE_UP -> No corresponding event + * STATE_MOUSE_DOWN -> No corresponding event + * + */ +enum EMouseInputFlags { + NO_INPUT = 0, + // + LMOUSE_PRESSED = 1 << 0, + LMOUSE_RELEASED = 1 << 1, + MMOUSE_PRESSED = 1 << 2, + MMOUSE_RELEASED = 1 << 3, + RMOUSE_PRESSED = 1 << 4, + RMOUSE_RELEASED = 1 << 5, + // + LMOUSE_DOWN = 1 << 6, + LMOUSE_UP = 1 << 7, + MMOUSE_DOWN = 1 << 8, + MMOUSE_UP = 1 << 9, + RMOUSE_DOWN = 1 << 10, + RMOUSE_UP = 1 << 11, + MOUSEBUTTONCOUNT = 3, // left, middle, right - could potentially have more mouse buttons + + HSCROLLWHEEL = 1 << 12, + VSCROLLWHEEL = 1 << 13, +}; + +//============================================================================== +/** + * Key code/index to SInputFrame::m_KeyStates + */ +// enum EKeyCode +//{ +// KEY_NOKEY = 0x00, +// KEY_ESCAPE, +// KEY_1, +// KEY_2, +// KEY_3, +// KEY_4, +// KEY_5, +// KEY_6, +// KEY_7, +// KEY_8, +// KEY_9, +// KEY_0, +// KEY_MINUS, /* - on main keyboard */ +// KEY_EQUALS, +// KEY_BACK, /* backspace */ +// KEY_TAB, +// KEY_Q, +// KEY_W, +// KEY_E, +// KEY_R, +// KEY_T, +// KEY_Y, +// KEY_U, +// KEY_I, +// KEY_O, +// KEY_P, +// KEY_LBRACKET, +// KEY_RBRACKET, +// KEY_RETURN, /* Enter on main keyboard */ +// KEY_LCONTROL, +// KEY_A, +// KEY_S, +// KEY_D, +// KEY_F, +// KEY_G, +// KEY_H, +// KEY_J, +// KEY_K, +// KEY_L, +// KEY_SEMICOLON, +// KEY_APOSTROPHE, +// KEY_GRAVE, /* accent grave */ +// KEY_LSHIFT, +// KEY_BACKSLASH, +// KEY_Z, +// KEY_X, +// KEY_C, +// KEY_V, +// KEY_B, +// KEY_N, +// KEY_M, +// KEY_COMMA, +// KEY_PERIOD, /* . on main keyboard */ +// KEY_SLASH, /* / on main keyboard */ +// KEY_RSHIFT, +// KEY_MULTIPLY, /* * on numeric keypad */ +// KEY_LMENU, /* left Alt */ +// KEY_SPACE, +// KEY_CAPITAL, +// KEY_F1, +// KEY_F2, +// KEY_F3, +// KEY_F4, +// KEY_F5, +// KEY_F6, +// KEY_F7, +// KEY_F8, +// KEY_F9, +// KEY_F10, +// KEY_NUMLOCK, +// KEY_SCROLL, /* Scroll Lock */ +// KEY_NUMPAD7, +// KEY_NUMPAD8, +// KEY_NUMPAD9, +// KEY_SUBTRACT, /* - on numeric keypad */ +// KEY_NUMPAD4, +// KEY_NUMPAD5, +// KEY_NUMPAD6, +// KEY_ADD, /* + on numeric keypad */ +// KEY_NUMPAD1, +// KEY_NUMPAD2, +// KEY_NUMPAD3, +// KEY_NUMPAD0, +// KEY_DECIMAL, /* . on numeric keypad */ +// KEY_OEM_102, /* <> or \| on RT 102-key keyboard (Non-U.S.) */ +// KEY_F11, +// KEY_F12, +// KEY_F13, /* (NEC PC98) */ +// KEY_F14, /* (NEC PC98) */ +// KEY_F15, /* (NEC PC98) */ +// KEY_KANA, /* (Japanese keyboard) */ +// KEY_ABNT_C1, /* /? on Brazilian keyboard */ +// KEY_CONVERT, /* (Japanese keyboard) */ +// KEY_NOCONVERT, /* (Japanese keyboard) */ +// KEY_YEN, /* (Japanese keyboard) */ +// KEY_ABNT_C2, /* Numpad . on Brazilian keyboard */ +// KEY_NUMPADEQUALS, /* = on numeric keypad (NEC PC98) */ +// KEY_PREVTRACK, /* Previous Track +// (DIK_CIRCUMFLEX on Japanese keyboard) */ +// KEY_AT, /* (NEC PC98) */ +// KEY_COLON, /* (NEC PC98) */ +// KEY_UNDERLINE, /* (NEC PC98) */ +// KEY_KANJI, /* (Japanese keyboard) */ +// KEY_STOP, /* (NEC PC98) */ +// KEY_AX, /* (Japan AX) */ +// KEY_UNLABELED, /* (J3100) */ +// KEY_NEXTTRACK, /* Next Track */ +// KEY_NUMPADENTER, /* Enter on numeric keypad */ +// KEY_RCONTROL, +// KEY_MUTE, /* Mute */ +// KEY_CALCULATOR, /* Calculator */ +// KEY_PLAYPAUSE, /* Play / Pause */ +// KEY_MEDIASTOP, /* Media Stop */ +// KEY_VOLUMEDOWN, /* Volume - */ +// KEY_VOLUMEUP, /* Volume + */ +// KEY_WEBHOME, /* Web home */ +// KEY_NUMPADPERIOD, /* . on numeric keypad (NEC PC98) */ +// KEY_DIVIDE, /* / on numeric keypad */ +// KEY_SYSRQ, +// KEY_RMENU, /* right Alt */ +// KEY_PAUSE, /* Pause */ +// KEY_HOME, /* Home on arrow keypad */ +// KEY_UP, /* UpArrow on arrow keypad */ +// KEY_PRIOR, /* PgUp on arrow keypad */ +// KEY_LEFT, /* LeftArrow on arrow keypad */ +// KEY_RIGHT, /* RightArrow on arrow keypad */ +// KEY_END, /* End on arrow keypad */ +// KEY_DOWN, /* DownArrow on arrow keypad */ +// KEY_NEXT, /* PgDn on arrow keypad */ +// KEY_INSERT, /* Insert on arrow keypad */ +// KEY_DELETE, /* Delete on arrow keypad */ +// KEY_LWIN, /* Left Windows key */ +// KEY_RWIN, /* Right Windows key */ +// KEY_APPS, /* AppMenu key */ +// KEY_POWER, /* System Power */ +// KEY_SLEEP, /* System Sleep */ +// KEY_WAKE, /* System Wake */ +// KEY_WEBSEARCH, /* Web Search */ +// KEY_WEBFAVORITES, /* Web Favorites */ +// KEY_WEBREFRESH, /* Web Refresh */ +// KEY_WEBSTOP, /* Web Stop */ +// KEY_WEBFORWARD, /* Web Forward */ +// KEY_WEBBACK, /* Web Back */ +// KEY_MYCOMPUTER, /* My Computer */ +// KEY_MAIL, /* Mail */ +// KEY_MEDIASELECT, /* Media Select */ +// // +// KEY_TOTAL_COUNT +//}; + +typedef enum _EKeyCode { + KEY_NOKEY = 0, + KEY_ESCAPE, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_0, + KEY_SUBTRACT, + KEY_EQUALS, + KEY_BACK, + KEY_TAB, + KEY_Q, + KEY_W, + KEY_E, + KEY_R, + KEY_T, + KEY_Y, + KEY_U, + KEY_I, + KEY_O, + KEY_P, + KEY_LBRACKET, + KEY_RBRACKET, + KEY_RETURN, + KEY_LCONTROL, + KEY_A, // 30 + KEY_S, + KEY_D, + KEY_F, + KEY_G, + KEY_H, + KEY_J, + KEY_K, + KEY_L, + KEY_SEMICOLON, + KEY_APOSTROPHE, // 40 + KEY_GRAVE, + KEY_LSHIFT, + KEY_BACKSLASH, + KEY_Z, + KEY_X, + KEY_C, + KEY_V, + KEY_B, + KEY_N, + KEY_M, + KEY_COMMA, + KEY_PERIOD, + KEY_SLASH, + KEY_RSHIFT, + KEY_MULTIPLY, + KEY_LALT, + KEY_SPACE, + KEY_CAPITAL, + KEY_F1, + KEY_F2, // 60 + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_NUMLOCK, + KEY_SCROLL, // 70 + KEY_NUMPAD7, + KEY_NUMPAD8, + KEY_NUMPAD9, + KEY_NUMPADSUBTRACT, + KEY_NUMPAD4, + KEY_NUMPAD5, + KEY_NUMPAD6, + KEY_NUMPADADD, + KEY_NUMPAD1, + KEY_NUMPAD2, // 80 + KEY_NUMPAD3, + KEY_NUMPAD0, + KEY_NUMPADDECIMAL, + KEY_NOOP, + KEY_ZENKAKUHANKAKU, + KEY_102ND, + KEY_F11, + KEY_F12, + KEY_F13, + KEY_F14, // 90 + KEY_HIRAGANA, + KEY_HENKAN, + KEY_KATAKANAHIRAGANA, + KEY_MUHENKAN, + KEY_KPJPCOMMA, + KEY_NUMPADENTER, + KEY_RCONTROL, + KEY_NUMPADDIVIDE, + KEY_PRINTSCREEN, + KEY_RALT, // 100 + KEY_LINEFEED, + KEY_HOME, + KEY_UP, + KEY_PGUP, + KEY_LEFT, + KEY_RIGHT, + KEY_END, + KEY_DOWN, + KEY_PGDN, + KEY_INSERT, // 110 + KEY_DELETE, + KEY_MACRO, + KEY_MUTE, + KEY_VOLUMEDOWN, + KEY_VOLUMEUP, + KEY_POWER, + KEY_KPEQUAL, + KEY_KPPLUSMINUS, + KEY_PAUSE, + KEY_SCALE, + KEY_TOTAL_COUNT +} EKeyCode; + +//============================================================================== +/** + * Keyboard modifier flags + */ +enum EKeyboardModifierFlags { + MODIFIER_NONE = 0, + MODIFIER_SHIFT = 1 << 0, + MODIFIER_CTRL = 1 << 1, + MODIFIER_ALT = 1 << 2, + MODIFIER_KEYDOWN = 1 << 3, ///< One or more key is down +}; + +//============================================================================== +/** + * Button codes + */ +enum EButtonCodes { + BUTTON_A = 0, + BUTTON_B, + BUTTON_X, + BUTTON_Y, + BUTTON_L1, + BUTTON_R1, + BUTTON_THUMBL, + BUTTON_THUMBR, + BUTTON_SELECT, + BUTTON_START, + BUTTON_MODE, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_LEFT, + BUTTON_RIGHT, + BUTTON_CENTER, + BUTTON_ENTER, + BUTTON_TOTAL_COUNT +}; + +//============================================================================== +/** + * Axis codes + */ +enum EAxisCodes { + AXIS_X = 0, + AXIS_Y, + AXIS_Z, + AXIS_RZ, + AXIS_HAT_X, + AXIS_HAT_Y, + AXIS_LTRIGGER, + AXIS_RTRIGGER, + AXIS_TOTAL_COUNT +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSInputEngine.cpp b/src/Runtime/Source/runtime/Qt3DSInputEngine.cpp new file mode 100644 index 00000000..d3cbe423 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSInputEngine.cpp @@ -0,0 +1,849 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" +#include +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSInputEngine.h" +#include "Qt3DSSceneManager.h" +#include "Qt3DSInputEventTypes.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSApplication.h" +#include "Qt3DSRuntimeFactory.h" +#include "EventPollingSystem.h" +#include "foundation/Qt3DSAssert.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +class CInputEventProvider : public qt3ds::evt::IEventProvider +{ + int m_RefCount; + +public: + CInputEventProvider() + : m_RefCount(0) + { + } + ~CInputEventProvider() + { + while (!m_Events.empty()) { + delete m_Events.front(); + m_Events.pop_front(); + } + } + struct SEvent + { + enum EType { TYPE_NONE = 0, TYPE_KEYBOARD, TYPE_BUTTON, TYPE_COUNT }; + SEvent(EType inType) + : m_Type(inType) + { + } + EType m_Type; + + virtual SEvent *Clone() const = 0; + virtual Qt3DSEventSystemEvent *GenEventSystemEvent(qt3ds::evt::IEventFactory &inFactory) = 0; + }; + struct SKeyboardEvent : public SEvent + { + SKeyboardEvent() + : SEvent(TYPE_KEYBOARD) + , m_KeyCode(KEY_NOKEY) + , m_KeyEvent(0) + { + } + SKeyboardEvent(INT32 inKeyCode, UINT32 inKeyEvent) + : SEvent(TYPE_KEYBOARD) + , m_KeyCode(inKeyCode) + , m_KeyEvent(inKeyEvent) + { + } + SEvent *Clone() const override + { + return new SKeyboardEvent(this->m_KeyCode, this->m_KeyEvent); + } + Qt3DSEventSystemEvent *GenEventSystemEvent(qt3ds::evt::IEventFactory &inFactory) override + { + if (m_KeyEvent == ON_KEYDOWN || m_KeyEvent == ON_KEYUP || m_KeyEvent == ON_KEYREPEAT) { + Qt3DSEventSystemEvent &theEvent = inFactory.CreateEvent(3); + int theIndex = 0; + theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("category"); + theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("kb"); + ++theIndex; + theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("code"); + theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesNumber; + theEvent.m_Data[theIndex].m_Value.m_Number = m_KeyCode; + ++theIndex; + theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("action"); + theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; + if (m_KeyEvent == ON_KEYDOWN) + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("down"); + else if (m_KeyEvent == ON_KEYUP) + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("up"); + else if (m_KeyEvent == ON_KEYREPEAT) + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("repeat"); + ++theIndex; + return &theEvent; + } + QT3DS_ASSERT(false); + return 0; + } + INT32 m_KeyCode; + UINT32 m_KeyEvent; + }; + struct SButtonEvent : public SEvent + { + SButtonEvent() + : SEvent(TYPE_BUTTON) + , m_ButtonCode(BUTTON_TOTAL_COUNT) + , m_ButtonEvent(0) + { + } + SButtonEvent(INT32 inButtonCode, UINT32 inButtonEvent) + : SEvent(TYPE_BUTTON) + , m_ButtonCode(inButtonCode) + , m_ButtonEvent(inButtonEvent) + { + } + SEvent *Clone() const override + { + return new SKeyboardEvent(this->m_ButtonCode, this->m_ButtonEvent); + } + Qt3DSEventSystemEvent *GenEventSystemEvent(qt3ds::evt::IEventFactory &inFactory) override + { + if (m_ButtonEvent == ON_BUTTONDOWN || m_ButtonEvent == ON_BUTTONUP + || m_ButtonEvent == ON_BUTTONREPEAT) { + Qt3DSEventSystemEvent &theEvent = inFactory.CreateEvent(3); + int theIndex = 0; + theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("category"); + theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("button"); + ++theIndex; + theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("code"); + theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesNumber; + theEvent.m_Data[theIndex].m_Value.m_Number = m_ButtonCode; + ++theIndex; + theEvent.m_Data[theIndex].m_Name = inFactory.RegisterStr("action"); + theEvent.m_Data[theIndex].m_Value.m_Type = QT3DSEventSystemEventTypesString; + if (m_ButtonEvent == ON_BUTTONDOWN) + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("down"); + else if (m_ButtonEvent == ON_BUTTONUP) + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("up"); + else if (m_ButtonEvent == ON_BUTTONREPEAT) + theEvent.m_Data[theIndex].m_Value.m_String = inFactory.AllocateStr("repeat"); + ++theIndex; + return &theEvent; + } + QT3DS_ASSERT(false); + return 0; + } + INT32 m_ButtonCode; + UINT32 m_ButtonEvent; + }; + size_t GetNextEvents(qt3ds::evt::IEventFactory &inFactory, Qt3DSEventSystemEvent **outBuffer, + size_t inBufLenInEvent) override + { + size_t theEventCount = 0; + while (!m_Events.empty() && inBufLenInEvent--) { + SEvent *theBufferedEvent = m_Events.front(); + Qt3DSEventSystemEvent *theEventSystemEvent = + theBufferedEvent->GenEventSystemEvent(inFactory); + if (theEventSystemEvent) + outBuffer[theEventCount++] = theEventSystemEvent; + m_Events.pop_front(); + } + return theEventCount; + } + + void addRef() { ++m_RefCount; } + + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + + void Release() override { release(); } + + void AddEvent(const SEvent &inEvent) + { + SEvent *theEvent = inEvent.Clone(); + if (theEvent) + m_Events.push_back(theEvent); + else + QT3DS_ASSERT(false); + } + +private: + eastl::list m_Events; +}; + +//============================================================================== +/** + * Constructor + */ +CInputEngine::CInputEngine() + : m_BeginPickInput(false) + , m_Application(NULL) + , m_InputEventProvider(NULL) +{ + m_InputFrame.m_PickValid = false; + m_InputFrame.m_PickX = 0; + m_InputFrame.m_PickY = 0; + + // TODO: SK - To quickly restore functionality, but this is should be in tegra-specific project. + m_InputFrame.m_DeltaX = 0; + m_InputFrame.m_DeltaY = 0; +} + +//============================================================================== +/** + * Destructor + */ +CInputEngine::~CInputEngine() +{ +} + +//============================================================================== +/** + * Set the top-level interface of the Runtime object + * @param inRuntime the top-level interface of the Runtime object + */ +void CInputEngine::SetApplication(qt3ds::runtime::IApplication *inApplication) +{ + m_Application = inApplication; + // Create this here. If we die before the application does, then the system will crash unless + // the application event system is reponsibe for the keyboard provider. Since the provider + // never + // access back to this object, this is the most sensible relationship. Furthermore if we have + // never been given an application, it doesn't make sense to have a keyboard event provider. + // In reality, this entire system should be ref counted. + m_InputEventProvider = new CInputEventProvider(); + + // Add a ref for the event system because it does not add its own ref. + m_InputEventProvider->addRef(); + m_Application->GetRuntimeFactory().GetEventSystem().AddProvider(*m_InputEventProvider); + MarkApplicationDirty(); +} + +//============================================================================== +/** + * Get the input information for the current frame + * @return the SInputFrame that defines the current frame input information + */ +SInputFrame &CInputEngine::GetInputFrame() +{ + return m_InputFrame; +} + +//============================================================================== +/** + * Return the key input portion of the input frame. + */ +SKeyInputFrame &CInputEngine::GetKeyInputFrame() +{ + return m_InputFrame.m_KeyInputFrame; +} + +void CInputEngine::BeginPickInput() +{ + m_PickInput.clear(); + m_BeginPickInput = true; +} + +//============================================================================== +/** + * Set the pick information the the input frame structure + * @param inX the X value of the pick position + * @param inY the Y value of the pick position + * @param inValid whether the X and Y value are valid + */ +void CInputEngine::SetPickInput(FLOAT inX, FLOAT inY, BOOL inValid /*= true*/) +{ + m_InputFrame.m_PickValid = inValid; + m_InputFrame.m_PickX = inX; + m_InputFrame.m_PickY = inY; + m_InputFrame.m_MouseFlags = 0; + MarkApplicationDirty(); + if (m_BeginPickInput && m_PickInput.size() < 1000) + m_PickInput.push_back(eastl::make_pair(inX, inY)); +} + +void CInputEngine::EndPickInput() +{ + m_BeginPickInput = false; +} + +CInputEngine::TPickInputList CInputEngine::GetPickInput() const +{ + return qt3ds::foundation::toDataRef(m_PickInput.data(), m_PickInput.size()); +} + +//============================================================================== +/** + * Set the mouse button state flag + * @param inFlags the current mouse state + */ +void CInputEngine::SetPickFlags(INT32 inFlags) +{ + m_InputFrame.m_MouseFlags |= inFlags; +} + +//============================================================================== +/** + * Set the keyboard status + * @param inKeyCode the identifier of the key + * @param inDown identify whether the key is down + */ +void CInputEngine::SetKeyState(INT32 inKeyCode, BOOL inDown) +{ + if (!inDown) + m_InputFrame.m_KeyInputFrame.m_KeyStates.erase(inKeyCode); + else { + SKeyInputFrame::MAP_KEYCODE_COUNT::iterator theIter = + m_InputFrame.m_KeyInputFrame.m_KeyStates.find(inKeyCode); + if (theIter == m_InputFrame.m_KeyInputFrame.m_KeyStates.end()) + m_InputFrame.m_KeyInputFrame.m_KeyStates.insert( + eastl::make_pair(inKeyCode, 1)); + else if (theIter->second < 255) + ++theIter->second; + } + MarkApplicationDirty(); +} + +//============================================================================== +/** + * Set the button status + * @param inButtonCode the identifier of the button + * @param inDown identify whether the button is down + */ +void CInputEngine::SetButtonState(INT32 inButtonCode, BOOL inDown) +{ + if (!inDown) + m_InputFrame.m_ButtonStates.erase(inButtonCode); + else { + SInputFrame::MAP_BUTTONCODE_COUNT::iterator theIter = + m_InputFrame.m_ButtonStates.find(inButtonCode); + if (theIter == m_InputFrame.m_ButtonStates.end()) + m_InputFrame.m_ButtonStates.insert(eastl::make_pair(inButtonCode, 1)); + else if (theIter->second < 255) + ++theIter->second; + } + MarkApplicationDirty(); +} + +//============================================================================== +/** + * Set the scroll value + * @param inMouseFlag flag to indicate whether this is a vertical or horizontal + *scroll + * @param inValue value of scroll performed + */ +void CInputEngine::SetScrollValue(INT32 inMouseFlag, INT16 inValue) +{ + m_InputFrame.m_MouseFlags = inMouseFlag; + m_InputFrame.m_ScrollValue = inValue; + MarkApplicationDirty(); +} +//============================================================================== +/** + * Set whether the keyboard is modified + * @param inFlag true if the keyboard status is modified + */ +void CInputEngine::SetModifierFlag(INT32 inFlag) +{ + m_InputFrame.m_KeyInputFrame.m_ModifierFlags |= inFlag; +} + +// Currently unused +//============================================================================== +/** + * Converts KeyCode in index format to ASCII format. + * This will translate upper/lower-case letters too. + * @param inKeyCode the index format keycode + * @param inShift whether the shift button is pressed + * @return the ASCII format keycode + */ +// INT32 CInputEngine::ConvertKeyCode( INT32 inKeyCode, BOOL inShift ) +//{ +// static INT32 s_ASCIILowerCase[] = +// { +// 0,//KEY_NOKEY = 0x00, +// 27,//KEY_ESCAPE, +// '1',//KEY_1, +// '2',//KEY_2, +// '3',//KEY_3, +// '4',//KEY_4, +// '5',//KEY_5, +// '6',//KEY_6, +// '7',//KEY_7, +// '8',//KEY_8, +// '9',//KEY_9, +// '0',//KEY_0, +// '-',//KEY_MINUS, /* - on main keyboard */ +// '=',//KEY_EQUALS, +// 8,//KEY_BACK, /* backspace */ +// '\t',//KEY_TAB, +// 'q',//KEY_Q, +// 'w',//KEY_W, +// 'e',//KEY_E, +// 'r',//KEY_R, +// 't',//KEY_T, +// 'y',//KEY_Y, +// 'u',//KEY_U, +// 'i',//KEY_I, +// 'o',//KEY_O, +// 'p',//KEY_P, +// '[',//KEY_LBRACKET, +// ']',//KEY_RBRACKET, +// '\n',//KEY_RETURN, /* Enter on main keyboard */ +// 0,//KEY_LCONTROL, +// 'a',//KEY_A, +// 's',//KEY_S, +// 'd',//KEY_D, +// 'f',//KEY_F, +// 'g',//KEY_G, +// 'h',//KEY_H, +// 'j',//KEY_J, +// 'k',//KEY_K, +// 'l',//KEY_L, +// ';',//KEY_SEMICOLON, +// '\'',//KEY_APOSTROPHE, +// '`',//KEY_GRAVE, /* accent grave */ +// 0,//KEY_LSHIFT, +// '\\',//KEY_BACKSLASH, +// 'z',//KEY_Z, +// 'x',//KEY_X, +// 'c',//KEY_C, +// 'v',//KEY_V, +// 'b',//KEY_B, +// 'n',//KEY_N, +// 'm',//KEY_M, +// ',',//KEY_COMMA, +// '.',//KEY_PERIOD, /* . on main keyboard */ +// '/',//KEY_SLASH, /* / on main keyboard */ +// 0,//KEY_RSHIFT, +// '*',//KEY_MULTIPLY, /* * on numeric keypad */ +// 0,//KEY_LMENU, /* left Alt */ +// ' ',//KEY_SPACE, +// 0,//KEY_CAPITAL, +// 0,//KEY_F1, +// 0,//KEY_F2, +// 0,//KEY_F3, +// 0,//KEY_F4, +// 0,//KEY_F5, +// 0,//KEY_F6, +// 0,//KEY_F7, +// 0,//KEY_F8, +// 0,//KEY_F9, +// 0,//KEY_F10, +// 0,//KEY_NUMLOCK, +// 0,//KEY_SCROLL, /* Scroll Lock */ +// '7',//KEY_NUMPAD7, +// '8',//KEY_NUMPAD8, +// '9',//KEY_NUMPAD9, +// '-',//KEY_SUBTRACT, /* - on numeric keypad */ +// '4',//KEY_NUMPAD4, +// '5',//KEY_NUMPAD5, +// '6',//KEY_NUMPAD6, +// '+',//KEY_ADD, /* + on numeric keypad */ +// '1',//KEY_NUMPAD1, +// '2',//KEY_NUMPAD2, +// '3',//KEY_NUMPAD3, +// '0',//KEY_NUMPAD0, +// '.',//KEY_DECIMAL, /* . on numeric keypad */ +// 0,//KEY_OEM_102, /* <> or \| on RT 102-key keyboard (Non-U.S.) */ +// 0,//KEY_F11, +// 0,//KEY_F12, +// 0,//KEY_F13, /* (NEC PC98) */ +// 0,//KEY_F14, /* (NEC PC98) */ +// 0,//KEY_F15, /* (NEC PC98) */ +// 0,//KEY_KANA, /* (Japanese keyboard) */ +// 0,//KEY_ABNT_C1, /* /? on Brazilian keyboard */ +// 0,//KEY_CONVERT, /* (Japanese keyboard) */ +// 0,//KEY_NOCONVERT, /* (Japanese keyboard) */ +// 0,//KEY_YEN, /* (Japanese keyboard) */ +// 0,//KEY_ABNT_C2, /* Numpad . on Brazilian keyboard */ +// 0,//KEY_NUMPADEQUALS, /* = on numeric keypad (NEC PC98) */ +// 0,//KEY_PREVTRACK, /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ +// 0,//KEY_AT, /* (NEC PC98) */ +// 0,//KEY_COLON, /* (NEC PC98) */ +// 0,//KEY_UNDERLINE, /* (NEC PC98) */ +// 0,//KEY_KANJI, /* (Japanese keyboard) */ +// 0,//KEY_STOP, /* (NEC PC98) */ +// 0,//KEY_AX, /* (Japan AX) */ +// 0,//KEY_UNLABELED, /* (J3100) */ +// 0,//KEY_NEXTTRACK, /* Next Track */ +// 0,//KEY_NUMPADENTER, /* Enter on numeric keypad */ +// 0,//KEY_RCONTROL, +// 0,//KEY_MUTE, /* Mute */ +// 0,//KEY_CALCULATOR, /* Calculator */ +// 0,//KEY_PLAYPAUSE, /* Play / Pause */ +// 0,//KEY_MEDIASTOP, /* Media Stop */ +// 0,//KEY_VOLUMEDOWN, /* Volume - */ +// 0,//KEY_VOLUMEUP, /* Volume + */ +// 0,//KEY_WEBHOME, /* Web home */ +// 0,//KEY_NUMPADCOMMA, /* , on numeric keypad (NEC PC98) */ +// 0,//KEY_DIVIDE, /* / on numeric keypad */ +// 0,//KEY_SYSRQ, +// 0,//KEY_RMENU, /* right Alt */ +// 0,//KEY_PAUSE, /* Pause */ +// 0,//KEY_HOME, /* Home on arrow keypad */ +// 0,//KEY_UP, /* UpArrow on arrow keypad */ +// 0,//KEY_PRIOR, /* PgUp on arrow keypad */ +// 0,//KEY_LEFT, /* LeftArrow on arrow keypad */ +// 0,//KEY_RIGHT, /* RightArrow on arrow keypad */ +// 0,//KEY_END, /* End on arrow keypad */ +// 0,//KEY_DOWN, /* DownArrow on arrow keypad */ +// 0,//KEY_NEXT, /* PgDn on arrow keypad */ +// 0,//KEY_INSERT, /* Insert on arrow keypad */ +// 127,//KEY_DELETE, /* Delete on arrow keypad */ +// 0,//KEY_LWIN, /* Left Windows key */ +// 0,//KEY_RWIN, /* Right Windows key */ +// 0,//KEY_APPS, /* AppMenu key */ +// 0,//KEY_POWER, /* System Power */ +// 0,//KEY_SLEEP, /* System Sleep */ +// 0,//KEY_WAKE, /* System Wake */ +// 0,//KEY_WEBSEARCH, /* Web Search */ +// 0,//KEY_WEBFAVORITES, /* Web Favorites */ +// 0,//KEY_WEBREFRESH, /* Web Refresh */ +// 0,//KEY_WEBSTOP, /* Web Stop */ +// 0,//KEY_WEBFORWARD, /* Web Forward */ +// 0,//KEY_WEBBACK, /* Web Back */ +// 0,//KEY_MYCOMPUTER, /* My Computer */ +// 0,//KEY_MAIL, /* Mail */ +// 0//KEY_MEDIASELECT, /* Media Select */ +// }; +// +// static INT32 s_ASCIIUpperCase[] = +// { +// 0,//KEY_NOKEY = 0x00, +// 27,//KEY_ESCAPE, +// '!',//KEY_1, +// '@',//KEY_2, +// '#',//KEY_3, +// '$',//KEY_4, +// '%',//KEY_5, +// '^',//KEY_6, +// '&',//KEY_7, +// '*',//KEY_8, +// '(',//KEY_9, +// ')',//KEY_0, +// '_',//KEY_MINUS, /* - on main keyboard */ +// '+',//KEY_EQUALS, +// 8,//KEY_BACK, /* backspace */ +// '\t',//KEY_TAB, +// 'Q',//KEY_Q, +// 'W',//KEY_W, +// 'E',//KEY_E, +// 'R',//KEY_R, +// 'T',//KEY_T, +// 'Y',//KEY_Y, +// 'U',//KEY_U, +// 'I',//KEY_I, +// 'O',//KEY_O, +// 'P',//KEY_P, +// '{',//KEY_LBRACKET, +// '}',//KEY_RBRACKET, +// '\n',//KEY_RETURN, /* Enter on main keyboard */ +// 0,//KEY_LCONTROL, +// 'A',//KEY_A, +// 'S',//KEY_S, +// 'D',//KEY_D, +// 'F',//KEY_F, +// 'G',//KEY_G, +// 'H',//KEY_H, +// 'J',//KEY_J, +// 'K',//KEY_K, +// 'L',//KEY_L, +// ':',//KEY_SEMICOLON, +// '\"',//KEY_APOSTROPHE, +// '~',//KEY_GRAVE, /* accent grave */ +// 0,//KEY_LSHIFT, +// '|',//KEY_BACKSLASH, +// 'Z',//KEY_Z, +// 'X',//KEY_X, +// 'C',//KEY_C, +// 'V',//KEY_V, +// 'B',//KEY_B, +// 'N',//KEY_N, +// 'M',//KEY_M, +// '<',//KEY_COMMA, +// '>',//KEY_PERIOD, /* . on main keyboard */ +// '?',//KEY_SLASH, /* / on main keyboard */ +// 0,//KEY_RSHIFT, +// '*',//KEY_MULTIPLY, /* * on numeric keypad */ +// 0,//KEY_LMENU, /* left Alt */ +// ' ',//KEY_SPACE, +// 0,//KEY_CAPITAL, +// 0,//KEY_F1, +// 0,//KEY_F2, +// 0,//KEY_F3, +// 0,//KEY_F4, +// 0,//KEY_F5, +// 0,//KEY_F6, +// 0,//KEY_F7, +// 0,//KEY_F8, +// 0,//KEY_F9, +// 0,//KEY_F10, +// 0,//KEY_NUMLOCK, +// 0,//KEY_SCROLL, /* Scroll Lock */ +// '7',//KEY_NUMPAD7, +// '8',//KEY_NUMPAD8, +// '9',//KEY_NUMPAD9, +// '-',//KEY_SUBTRACT, /* - on numeric keypad */ +// '4',//KEY_NUMPAD4, +// '5',//KEY_NUMPAD5, +// '6',//KEY_NUMPAD6, +// '+',//KEY_ADD, /* + on numeric keypad */ +// '1',//KEY_NUMPAD1, +// '2',//KEY_NUMPAD2, +// '3',//KEY_NUMPAD3, +// '0',//KEY_NUMPAD0, +// '.',//KEY_DECIMAL, /* . on numeric keypad */ +// 0,//KEY_OEM_102, /* <> or \| on RT 102-key keyboard (Non-U.S.) */ +// 0,//KEY_F11, +// 0,//KEY_F12, +// 0,//KEY_F13, /* (NEC PC98) */ +// 0,//KEY_F14, /* (NEC PC98) */ +// 0,//KEY_F15, /* (NEC PC98) */ +// 0,//KEY_KANA, /* (Japanese keyboard) */ +// 0,//KEY_ABNT_C1, /* /? on Brazilian keyboard */ +// 0,//KEY_CONVERT, /* (Japanese keyboard) */ +// 0,//KEY_NOCONVERT, /* (Japanese keyboard) */ +// 0,//KEY_YEN, /* (Japanese keyboard) */ +// 0,//KEY_ABNT_C2, /* Numpad . on Brazilian keyboard */ +// 0,//KEY_NUMPADEQUALS, /* = on numeric keypad (NEC PC98) */ +// 0,//KEY_PREVTRACK, /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ +// 0,//KEY_AT, /* (NEC PC98) */ +// 0,//KEY_COLON, /* (NEC PC98) */ +// 0,//KEY_UNDERLINE, /* (NEC PC98) */ +// 0,//KEY_KANJI, /* (Japanese keyboard) */ +// 0,//KEY_STOP, /* (NEC PC98) */ +// 0,//KEY_AX, /* (Japan AX) */ +// 0,//KEY_UNLABELED, /* (J3100) */ +// 0,//KEY_NEXTTRACK, /* Next Track */ +// 0,//KEY_NUMPADENTER, /* Enter on numeric keypad */ +// 0,//KEY_RCONTROL, +// 0,//KEY_MUTE, /* Mute */ +// 0,//KEY_CALCULATOR, /* Calculator */ +// 0,//KEY_PLAYPAUSE, /* Play / Pause */ +// 0,//KEY_MEDIASTOP, /* Media Stop */ +// 0,//KEY_VOLUMEDOWN, /* Volume - */ +// 0,//KEY_VOLUMEUP, /* Volume + */ +// 0,//KEY_WEBHOME, /* Web home */ +// 0,//KEY_NUMPADCOMMA, /* , on numeric keypad (NEC PC98) */ +// 0,//KEY_DIVIDE, /* / on numeric keypad */ +// 0,//KEY_SYSRQ, +// 0,//KEY_RMENU, /* right Alt */ +// 0,//KEY_PAUSE, /* Pause */ +// 0,//KEY_HOME, /* Home on arrow keypad */ +// 0,//KEY_UP, /* UpArrow on arrow keypad */ +// 0,//KEY_PRIOR, /* PgUp on arrow keypad */ +// 0,//KEY_LEFT, /* LeftArrow on arrow keypad */ +// 0,//KEY_RIGHT, /* RightArrow on arrow keypad */ +// 0,//KEY_END, /* End on arrow keypad */ +// 0,//KEY_DOWN, /* DownArrow on arrow keypad */ +// 0,//KEY_NEXT, /* PgDn on arrow keypad */ +// 0,//KEY_INSERT, /* Insert on arrow keypad */ +// 127,//KEY_DELETE, /* Delete on arrow keypad */ +// 0,//KEY_LWIN, /* Left Windows key */ +// 0,//KEY_RWIN, /* Right Windows key */ +// 0,//KEY_APPS, /* AppMenu key */ +// 0,//KEY_POWER, /* System Power */ +// 0,//KEY_SLEEP, /* System Sleep */ +// 0,//KEY_WAKE, /* System Wake */ +// 0,//KEY_WEBSEARCH, /* Web Search */ +// 0,//KEY_WEBFAVORITES, /* Web Favorites */ +// 0,//KEY_WEBREFRESH, /* Web Refresh */ +// 0,//KEY_WEBSTOP, /* Web Stop */ +// 0,//KEY_WEBFORWARD, /* Web Forward */ +// 0,//KEY_WEBBACK, /* Web Back */ +// 0,//KEY_MYCOMPUTER, /* My Computer */ +// 0,//KEY_MAIL, /* Mail */ +// 0//KEY_MEDIASELECT, /* Media Select */ +// }; +// +// if ( inKeyCode < 0 || inKeyCode > KEY_TOTAL_COUNT ) +// return 0; +// +// if ( inShift ) +// return s_ASCIIUpperCase[inKeyCode]; +// +// return s_ASCIILowerCase[inKeyCode]; +//} + +//============================================================================== +/** + * Clear the current input frame data, typically after the event has been processed. + */ +void CInputEngine::ClearInputFrame() +{ + // TODO: SK - To quickly restore functionality, but this is should be in tegra-specific project. + m_InputFrame.m_PickValid = false; +} + +//============================================================================== +/** + * Can be more appropriately named and perhaps moved to a COutputEngine class. + * to translate event triggered from script back to a "device" event + * e.g to simulate clicking on Home button. + * + * Base class does nothing. + */ +BOOL CInputEngine::TranslateEvent(const CHAR *inEvent) +{ + Q3DStudio_UNREFERENCED_PARAMETER(inEvent); + return false; +} + +//============================================================================== +/** + * Handle firing of keyboard events when a scancode is received. + */ +void CInputEngine::HandleKeyboard(INT32 inKeyCode, INT32 inPressed, INT32 inRepeat) +{ + if (inKeyCode >= KEY_TOTAL_COUNT || inKeyCode <= KEY_NOKEY) { + qCDebug(qt3ds::TRACE_INFO) + << "Input: Key input out of range. key code: " << inKeyCode + << " pressed: " << inPressed << " repeat: " << inRepeat; + } + if (m_Application == NULL) + return; + MarkApplicationDirty(); + + SetKeyState(inKeyCode, inPressed ? true : false); + + CPresentation *theActivePresentation(m_Application->GetPrimaryPresentation()); + if (theActivePresentation) { + TElement *theScene = theActivePresentation->GetRoot(); + UVariant theKeycode; + theKeycode.m_INT32 = inKeyCode; + + TEventCommandHash theEvent; + if (inPressed) { + UINT16 theKeyCount = m_InputFrame.m_KeyInputFrame.GetKeyCount(inKeyCode); + QT3DS_ASSERT(theKeyCount >= 1); + if (theKeyCount == 1 && inRepeat == 0) + theEvent = ON_KEYDOWN; + else + theEvent = ON_KEYREPEAT; + } else { + theEvent = ON_KEYUP; + } + + theActivePresentation->FireEvent(theEvent, theScene, &theKeycode, NULL, ATTRIBUTETYPE_INT32, + ATTRIBUTETYPE_NONE); + if (m_InputEventProvider) + m_InputEventProvider->AddEvent( + CInputEventProvider::SKeyboardEvent(theKeycode.m_INT32, theEvent)); + } +} + +//============================================================================== +/** + * Handle button events. + */ +void CInputEngine::HandleButton(INT32 inButtonCode, INT32 inPressed, INT32 inRepeat) +{ + if (inButtonCode >= BUTTON_TOTAL_COUNT || inButtonCode < 0) { + qCDebug(qt3ds::TRACE_INFO) + << "Input: Key input out of range. key code: " << inButtonCode + << " pressed: " << inPressed << " repeat: " << inRepeat; + } + if (m_Application == NULL) + return; + MarkApplicationDirty(); + + SetButtonState(inButtonCode, inPressed ? true : false); + + CPresentation *theActivePresentation(m_Application->GetPrimaryPresentation()); + if (theActivePresentation) { + TElement *theScene = theActivePresentation->GetRoot(); + UVariant theButtonCode; + theButtonCode.m_INT32 = inButtonCode; + + TEventCommandHash theEvent; + if (inPressed) { + if (inRepeat == 0) + theEvent = ON_BUTTONDOWN; + else + theEvent = ON_BUTTONREPEAT; + } else { + theEvent = ON_BUTTONUP; + } + + theActivePresentation->FireEvent(theEvent, theScene, &theButtonCode, NULL, + ATTRIBUTETYPE_INT32, ATTRIBUTETYPE_NONE); + if (m_InputEventProvider) + m_InputEventProvider->AddEvent( + CInputEventProvider::SButtonEvent(theButtonCode.m_INT32, theEvent)); + } +} + +//============================================================================== +/** + * Handle joystick events. + */ +void CInputEngine::HandleAxis(INT32 inAxisCode, FLOAT inValue) +{ + if (m_Application == NULL) + return; + MarkApplicationDirty(); + if (m_InputFrame.m_AxisStates[inAxisCode] != inValue) { + m_InputFrame.m_AxisStates[inAxisCode] = inValue; + + CPresentation *theActivePresentation(m_Application->GetPrimaryPresentation()); + if (theActivePresentation) { + TElement *theScene = theActivePresentation->GetRoot(); + UVariant theAxisCode; + theAxisCode.m_INT32 = inAxisCode; + UVariant theValue; + theValue.m_FLOAT = inValue; + + theActivePresentation->FireEvent(ON_AXISMOVED, theScene, &theAxisCode, &theValue, + ATTRIBUTETYPE_INT32, ATTRIBUTETYPE_FLOAT); + } + } +} + +void CInputEngine::MarkApplicationDirty() +{ + if (m_Application) + m_Application->MarkApplicationDirty(); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSInputEngine.h b/src/Runtime/Source/runtime/Qt3DSInputEngine.h new file mode 100644 index 00000000..bf75e5a1 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSInputEngine.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSKernelTypes.h" +#include "Qt3DSPickFrame.h" +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/vector.h" +#include "foundation/Qt3DSDataRef.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace qt3ds { +namespace runtime { + class IApplication; +} +} +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class CRuntime; +union UVariant; +class CInputEventProvider; + +//============================================================================== +/** +* @class CInputEngine +* @brief The basic input engine +*/ +class CInputEngine +{ + //============================================================================== + // Fields + //============================================================================== +protected: + SInputFrame m_InputFrame; ///< The data describing the input state + eastl::vector> m_PickInput; + bool m_BeginPickInput; + qt3ds::runtime::IApplication *m_Application; ///< The Runtime object + qt3ds::foundation::NVScopedRefCounted + m_InputEventProvider; ///< The event provider for keyboard + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + typedef qt3ds::foundation::NVConstDataRef> TPickInputList; + CInputEngine(); + virtual ~CInputEngine(); + +public: // Runtime interfaces + void SetApplication(qt3ds::runtime::IApplication *inApplication); + +public: + // Access + virtual SInputFrame &GetInputFrame(); + virtual SKeyInputFrame &GetKeyInputFrame(); + + // Setters + // Multitouch is handled by using BeginPickInput, SetPickInput (several times), and EndPickInput + // pairs. + // The assumption here is that the pick input is static until changed. So to clear it you need + // a + // begin, end pair without any other pieces. + virtual void BeginPickInput(); + virtual void SetPickInput(FLOAT inX, FLOAT inY, BOOL inValid = true); + virtual void EndPickInput(); + virtual TPickInputList GetPickInput() const; + virtual void SetPickFlags(INT32 inFlags); + virtual void SetKeyState(INT32 inKeyCode, BOOL inDown); + virtual void SetButtonState(INT32 inButtonCode, BOOL inDown); + virtual void SetScrollValue(INT32 inFlags, INT16 value); + virtual void SetModifierFlag(INT32 inFlag); + + // Keyboard hook + virtual void HandleKeyboard(INT32 inKeyCode, INT32 inPressed, INT32 inRepeat = 0); + + // Other input + virtual void HandleButton(INT32 inButtonCode, INT32 inPressed, INT32 inRepeat = 0); + virtual void HandleAxis(INT32 inAxisCode, FLOAT inValue); + + // Helpers + // virtual INT32 ConvertKeyCode( INT32 inKeyCode, BOOL inShift ); + // TODO: SK - To quickly restore functionality, but this is should be in tegra-specific project. + virtual void ClearInputFrame(); + virtual BOOL TranslateEvent(const CHAR *inEvent); + + void MarkApplicationDirty(); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSInputEventTypes.h b/src/Runtime/Source/runtime/Qt3DSInputEventTypes.h new file mode 100644 index 00000000..0b3c3981 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSInputEventTypes.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSHash.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +// Mouse events +const TEventCommandHash ON_MOUSEOVER = CHash::HashEventCommand("onMouseOver"); +const TEventCommandHash ON_MOUSEOUT = CHash::HashEventCommand("onMouseOut"); +const TEventCommandHash ON_GROUPEDMOUSEOVER = CHash::HashEventCommand("onGroupedMouseOver"); +const TEventCommandHash ON_GROUPEDMOUSEOUT = CHash::HashEventCommand("onGroupedMouseOut"); + +// Crude hack to pretend mouse events are gesture events, since gesture events are all you +// can specify in studio. +// TODO: Fix properly, preferably by bringing back gesture support +const TEventCommandHash ON_MOUSEDOWN = CHash::HashEventCommand("onPressureDown"); +const TEventCommandHash ON_MOUSEUP = CHash::HashEventCommand("onPressureUp"); +const TEventCommandHash ON_MOUSECLICK = CHash::HashEventCommand("onTap"); +const TEventCommandHash ON_MOUSEDBLCLICK = CHash::HashEventCommand("onDoubleTap"); +//const TEventCommandHash ON_MOUSEDOWN = CHash::HashEventCommand("onMouseDown"); +//const TEventCommandHash ON_MOUSEUP = CHash::HashEventCommand("onMouseUp"); +//const TEventCommandHash ON_MOUSECLICK = CHash::HashEventCommand("onMouseClick"); +//const TEventCommandHash ON_MOUSEDBLCLICK = CHash::HashEventCommand("onMouseDblClick"); + +const TEventCommandHash ON_MIDDLEMOUSEDOWN = CHash::HashEventCommand("onMiddleMouseDown"); +const TEventCommandHash ON_MIDDLEMOUSEUP = CHash::HashEventCommand("onMiddleMouseUp"); +const TEventCommandHash ON_MIDDLEMOUSECLICK = CHash::HashEventCommand("onMiddleMouseClick"); +const TEventCommandHash ON_MIDDLEDBLMOUSECLICK = CHash::HashEventCommand("onMiddleMouseDblClick"); + +const TEventCommandHash ON_RIGHTMOUSEDOWN = CHash::HashEventCommand("onRightMouseDown"); +const TEventCommandHash ON_RIGHTMOUSEUP = CHash::HashEventCommand("onRightMouseUp"); +const TEventCommandHash ON_RIGHTMOUSECLICK = CHash::HashEventCommand("onRightMouseClick"); +const TEventCommandHash ON_RIGHTDBLMOUSECLICK = CHash::HashEventCommand("onRightMouseDblClick"); + +const TEventCommandHash ON_HORIZONTALSCROLLWHEEL = + CHash::HashEventCommand("onHorizontalScrollWheel"); +const TEventCommandHash ON_VERTICALSCROLLWHEEL = CHash::HashEventCommand("onVerticalScrollWheel"); + +const TEventCommandHash ON_KEYUP = + CHash::HashEventCommand("onKeyUp"); ///< Studio's keyboard event string +const TEventCommandHash ON_KEYDOWN = + CHash::HashEventCommand("onKeyDown"); ///< Studio's keyboard event string +const TEventCommandHash ON_KEYREPEAT = + CHash::HashEventCommand("onKeyRepeat"); ///< Studio's keyboard event string + +const TEventCommandHash ON_BUTTONUP = CHash::HashEventCommand("onButtonUp"); +const TEventCommandHash ON_BUTTONDOWN = CHash::HashEventCommand("onButtonDown"); +const TEventCommandHash ON_BUTTONREPEAT = CHash::HashEventCommand("onButtonRepeat"); + +const TEventCommandHash ON_AXISMOVED = CHash::HashEventCommand("onAxisMoved"); + +// Used by UIContract +const TEventCommandHash ON_LEFT = CHash::HashEventCommand("onLeft"); +const TEventCommandHash ON_RIGHT = CHash::HashEventCommand("onRight"); +const TEventCommandHash ON_UP = CHash::HashEventCommand("onUp"); +const TEventCommandHash ON_DOWN = CHash::HashEventCommand("onDown"); +const TEventCommandHash ON_BACK = CHash::HashEventCommand("onBack"); +const TEventCommandHash ON_SELECT = CHash::HashEventCommand("onSelect"); + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSInputFrame.h b/src/Runtime/Source/runtime/Qt3DSInputFrame.h new file mode 100644 index 00000000..f80f3ebc --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSInputFrame.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSPlatformSpecific.h" +#include "Qt3DSInputDefs.h" + +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Input structure defining the values for keyboard input + */ +struct SKeyInputFrame +{ + UINT16 m_ModifierFlags; ///< Keyboard modifier state flags + typedef eastl::map MAP_KEYCODE_COUNT; + MAP_KEYCODE_COUNT + m_KeyStates; ///< Keycode map representing number of frames since the keys are down + ///< 0 - up, 255 - down for more than 254 frames + + SKeyInputFrame() + : m_ModifierFlags(MODIFIER_NONE) + { + } + + UINT16 GetKeyCount(INT32 inKeyCode) + { + MAP_KEYCODE_COUNT::iterator theIter = m_KeyStates.find(inKeyCode); + return theIter != m_KeyStates.end() ? theIter->second : 0; + } +}; + +//============================================================================== +/** + * Input structure defining the values fed into input processing + */ +struct SInputFrame +{ + SKeyInputFrame m_KeyInputFrame; ///< Data for keyboard input + + typedef eastl::map MAP_BUTTONCODE_COUNT; + MAP_BUTTONCODE_COUNT m_ButtonStates; + + FLOAT m_AxisStates[AXIS_TOTAL_COUNT]; + + FLOAT m_PickX; ///< Horizontal screen location + FLOAT m_PickY; ///< Vertical screen location + + INT32 m_MouseFlags; ///< Mouse button state flags + + // SK - gesture-specific variables should NOT be in core runtime, its tegra-specific + INT32 m_GestureID; ///< a running counter/unique-id + INT32 m_GestureKind; ///< Gesture state flags + + /* different gestures will interpret as different values. could be: + * DRAG: delta position + * FLICK: velocities + * ZOOM: second finger or quantized delta */ + INT16 m_DeltaX; + INT16 m_DeltaY; + + BOOL m_PickValid; ///< X and Y are valid inputs + INT16 m_ScrollValue; //< Value of scrollwheel scrolled + + CHAR m_Padding[1]; + + SInputFrame() + : m_PickX(0) + , m_PickY(0) + , m_MouseFlags(NO_INPUT) + , m_GestureID(0) + , m_GestureKind(0) + , m_DeltaX(0) + , m_DeltaY(0) + , m_PickValid(false) + { + Q3DStudio_memset(m_AxisStates, 0, sizeof(m_AxisStates)); + } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSKernelTypes.h b/src/Runtime/Source/runtime/Qt3DSKernelTypes.h new file mode 100644 index 00000000..db290996 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSKernelTypes.h @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSArray.h" + +namespace qt3ds { +namespace runtime { + namespace element { + struct SElement; + struct SComponent; + } +} +} + +namespace Q3DStudio { +typedef qt3ds::runtime::element::SElement TElement; +typedef qt3ds::runtime::element::SComponent TComponent; +} +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class CString; + +//============================================================================== +// Typedefs +//============================================================================== +typedef CArray TElementList; ///< Dynamic list of CElements +typedef CArray TEventList; ///< Dynamic list of CStrings +typedef CArray TAssociationList; ///< Dynamic list of IDs used for the association process + +typedef UINT32 TEventCommandHash; ///< Value from CHash::Hash31 +typedef UINT32 TStringHash; ///< Value from CHash::Hash +typedef UINT32 TAttributeHash; ///< Value from CHash::Hash27 +typedef UINT32 THashValue; ///< 32 bit value indicating a hash + +//============================================================================== +// Enumerations +//============================================================================== + +/// Each attribute knows the type of its value and uses 4 bits for this enum +enum EAttributeType { + ATTRIBUTETYPE_NONE = 0, + ATTRIBUTETYPE_INT32, + ATTRIBUTETYPE_HASH, + ATTRIBUTETYPE_FLOAT, + ATTRIBUTETYPE_BOOL, + ATTRIBUTETYPE_STRING, + ATTRIBUTETYPE_POINTER, + ATTRIBUTETYPE_ELEMENTREF, + ATTRIBUTETYPE_DATADRIVEN_PARENT, + ATTRIBUTETYPE_DATADRIVEN_CHILD, + ATTRIBUTETYPE_FLOAT3, + ATTRIBUTETYPE_FLOAT2, + ATTRIBUTETYPE_DATAINPUT_TIMELINE, + ATTRIBUTETYPE_DATAINPUT_SLIDE, + ATTRIBUTETYPECOUNT +}; + +/// Elements represent various types of objects +enum EElementType { + ELEMENTTYPE_UNKNOWN = 0, + ELEMENTTYPE_NODE, + ELEMENTTYPE_CAMERA, + ELEMENTTYPE_LIGHT, + ELEMENTTYPE_TEXT, + ELEMENTTYPE_MATERIAL, + ELEMENTTYPE_TEXTURE, + ELEMENTTYPE_COMPONENT, + ELEMENTTYPE_BEHAVIOR, + ELEMENTTYPE_PATH, + ELEMENTTYPE_PATHANCHORPOINT, + ELEMENTTYPE_SUBPATH, + ELEMENTTYPECOUNT +}; + +//============================================================================== +// Enumerations +//============================================================================== + +/// Various bit flags packed into a single 16bit space. +enum EElementFlag { + // Persistent flags (set only at creation) + ELEMENTFLAG_COMPONENT = 1, ///< Element is a component + ELEMENTFLAG_TIMELINE = 1 << 1, ///< Element has start time and duration attributes + ELEMENTFLAG_CLONE = 1 << 2, ///< Element is a clone + ELEMENTFLAG_ATTRIBUTELOCK = + 1 << 3, ///< No more attributes can be added (always true during runtime) + + // Configuration flags (seldom changed) + ELEMENTFLAG_SCRIPTCALLBACKS = 1 + << 4, ///< At least one script has requested notify on onActivate, onDeactivate, onUpdate + ELEMENTFLAG_SCRIPTINITIALIZE = 1 + << 5, ///< At least one script has requested notify on onInitialize + ELEMENTFLAG_REGISTEREDFORATTRIBUTECHANGE = 1 << 6, ///< Element monitored for attribute change + ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK = 1 << 7, ///< Element registered for event callbacks + ELEMENTFLAG_PICKENABLED = 1 << 8, ///< At least one script or action has registered for mouse + ///events based on this element + + // Runtime flags + ELEMENTFLAG_GLOBALACTIVE = + 1 << 9, ///< Combination active flag based on explicit, time and parent active + ELEMENTFLAG_EXPLICITACTIVE = 1 << 10, ///< Explicit On/Off switch on each element + ELEMENTFLAG_PLAYTHROUGH = 1 << 11, ///< Playthrough slides enabled if this is a component + ELEMENTFLAG_DIRTY = 1 << 12, ///< Attributes or user visible flags have changed + + // Flags used by the activation manager + ELEMENTFLAG_AMGR_TIMEACTIVE = 1 << 13, ///< Is the element alive according to time information +}; + +// Four byte aligned time unit structure. +struct SAlignedTimeUnit +{ + UINT32 m_LowWord; + UINT32 m_HighWord; + + SAlignedTimeUnit() {} + SAlignedTimeUnit(const TTimeUnit &inUnit); + SAlignedTimeUnit(const SAlignedTimeUnit &inOther) + : m_LowWord(inOther.m_LowWord) + , m_HighWord(inOther.m_HighWord) + { + } + SAlignedTimeUnit &operator=(const SAlignedTimeUnit &inOther) + { + m_LowWord = inOther.m_LowWord; + m_HighWord = inOther.m_HighWord; + return *this; + } + operator TTimeUnit() const; + + void operator-=(const TTimeUnit &inTime); + void operator%=(const TTimeUnit &inTime); +}; + +//============================================================================== +// Defines +//============================================================================== +#define Q3DStudio_ATTRIBUTEKEYBITS 26 /* Number of bits to store attributes index */ +#define Q3DStudio_ATTRIBUTEKEYMASK 0x03ffffff /* Bit mask covering 26 bits */ + +//============================================================================== +// Structs +//============================================================================== + +/// Each element has a number of attributes associated with it - This is the key. +struct SAttributeKey +{ + TAttributeHash m_Hash : Q3DStudio_ATTRIBUTEKEYBITS; ///< hash of attribute name + TAttributeHash m_Type : 4; ///< Attribute type such as INT32, FLOAT, STRING + TAttributeHash m_Dirty : 1; ///< Dirty bit signalling that the attribute value has been modified + TAttributeHash + m_DontOptimize : 1; ///< Used by the exporter/optimizer to flag attributes as un-optimizable + + void Convert(const UINT32 &inKey) + { + m_Hash = inKey & Q3DStudio_ATTRIBUTEKEYMASK; + m_Type = (inKey & 0x3c000000) >> Q3DStudio_ATTRIBUTEKEYBITS; + m_Dirty = (inKey & 0x40000000) >> (Q3DStudio_ATTRIBUTEKEYBITS + 4); + m_DontOptimize = (inKey & 0x80000000) >> (Q3DStudio_ATTRIBUTEKEYBITS + 5); + } +}; + +/// The structure to store a memory pool for clones. +/// The actual data pool will start at the address after these 8 bytes. +struct SClone +{ + SClone *m_Next; ///< Pointer to the next block of memory + UINT32 m_Size; ///< Size of the current block of memory +}; + +//============================================================================== +// Unions +//============================================================================== + +/// Each element has a number of attributes associated with it - This is the value. +union UVariant { + INT32 m_INT32; ///< Integer representation + FLOAT m_FLOAT; ///< Float representation + THashValue m_Hash; ///< Explicit hash representation + UINT32 m_StringHandle; ///< Handle into the IStringTable member of the presentation + void *m_VoidPointer; ///< Generic data Pointer + UINT32 m_ElementHandle; ///< Element handle. Resolve using IApplication object. + FLOAT m_FLOAT3[3]; ///< Vector 3 representation +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSLogicSystem.cpp b/src/Runtime/Source/runtime/Qt3DSLogicSystem.cpp new file mode 100644 index 00000000..1aec08f1 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSLogicSystem.cpp @@ -0,0 +1,293 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "RuntimePrefix.h" +#include "Qt3DSLogicSystem.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSApplication.h" +#include "foundation/SerializationTypes.h" +#include "foundation/IOStreams.h" + +using namespace qt3ds::runtime; +using namespace qt3ds::foundation; +using namespace qt3ds; +using namespace qt3ds::runtime::element; + +namespace { +struct SLogicKey +{ + QT3DSU32 m_ElementHandle; + Q3DStudio::TEventCommandHash m_CommandHash; + SLogicKey(QT3DSU32 hdl = 0, Q3DStudio::TEventCommandHash hash = 0) + : m_ElementHandle(hdl) + , m_CommandHash(hash) + { + } + + bool operator==(const SLogicKey &other) const + { + return m_ElementHandle == other.m_ElementHandle && m_CommandHash == other.m_CommandHash; + } + size_t hash() const + { + return eastl::hash()(m_ElementHandle) ^ eastl::hash()((QT3DSU32)m_CommandHash); + } +}; + +struct SLogicData +{ + SLogicData *m_NextLogicData; + QT3DSU32 m_Owner; + QT3DSU32 m_Target; + Q3DStudio::TEventCommandHash m_Type; + Q3DStudio::UVariant m_Arg1; + Q3DStudio::UVariant m_Arg2; + QT3DSI32 m_Id; + bool m_Active; + + SLogicData() + : m_NextLogicData(NULL) + , m_Owner(0) + , m_Target(0) + , m_Type(0) + , m_Id(0) + , m_Active(false) + { + m_Arg1.m_INT32 = 0; + m_Arg2.m_INT32 = 0; + } + + SLogicData(QT3DSU32 owner, QT3DSU32 target, Q3DStudio::TEventCommandHash type, Q3DStudio::UVariant a1, + Q3DStudio::UVariant a2, bool active, QT3DSI32 inId) + : m_NextLogicData(NULL) + , m_Owner(owner) + , m_Target(target) + , m_Type(type) + , m_Arg1(a1) + , m_Arg2(a2) + , m_Id(inId) + , m_Active(active) + { + } +}; + +DEFINE_INVASIVE_SINGLE_LIST(LogicData); +IMPLEMENT_INVASIVE_SINGLE_LIST(LogicData, m_NextLogicData); +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SLogicKey &inKey) const { return inKey.hash(); } +}; +} + +namespace { + +struct SLogicSystem : public ILogicSystem +{ + typedef nvhash_map TLogicKeyHash; + typedef nvhash_map TIdLogicKeyHash; + typedef Pool TLogicDataPool; + + NVFoundationBase &m_Foundation; + + TLogicKeyHash m_LogicKeys; + TIdLogicKeyHash m_IdToLogicKeys; + TLogicDataPool m_LogicDataPool; + QT3DSI32 m_NextId; + NVDataRef m_LoadData; + + QT3DSI32 m_RefCount; + + SLogicSystem(NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , m_LogicKeys(inFoundation.getAllocator(), "m_LogicKeys") + , m_IdToLogicKeys(inFoundation.getAllocator(), "m_IdToLogicKeys") + , m_LogicDataPool(ForwardingAllocator(inFoundation.getAllocator(), "m_LogicDataPool")) + , m_NextId(1) + , m_RefCount(0) + { + } + + void addRef() override { atomicIncrement(&m_RefCount); } + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Foundation.getAllocator()); + NVDelete(alloc, this); + } + } + void IncrementNextId() + { + ++m_NextId; + if (m_NextId == 0) + ++m_NextId; + } + static QT3DSU32 GetHandle(element::SElement *elem) + { + if (elem) + return elem->GetHandle(); + return 0; + } + // returns the action id + QT3DSI32 AddAction(element::SElement &inTrigger, + Q3DStudio::TEventCommandHash inEventNameHash, + element::SElement *inTarget, element::SElement *inOwner, + Q3DStudio::TEventCommandHash inType, Q3DStudio::UVariant inArg1, + Q3DStudio::UVariant inArg2, bool inActive) override + { + SLogicKey theKey(inTrigger.GetHandle(), inEventNameHash); + eastl::pair inserter = + m_LogicKeys.insert(eastl::make_pair(theKey, TLogicDataList())); + + eastl::pair idInserter; + for (idInserter = m_IdToLogicKeys.insert(eastl::make_pair(m_NextId, theKey)); + idInserter.second == false; + idInserter = m_IdToLogicKeys.insert(eastl::make_pair(m_NextId, theKey))) { + IncrementNextId(); + } + IncrementNextId(); + + SLogicData *theData = m_LogicDataPool.construct(__FILE__, __LINE__); + *theData = SLogicData(GetHandle(inOwner), GetHandle(inTarget), inType, inArg1, inArg2, + inActive, idInserter.first->first); + inserter.first->second.push_back(*theData); + return idInserter.first->first; + } + + void OnEvent(Q3DStudio::TEventCommandHash inEventName, element::SElement &inTarget, + Q3DStudio::IPresentation &inPresentation) const override + { + SLogicKey theKey(inTarget.GetHandle(), inEventName); + TLogicKeyHash::const_iterator iter = m_LogicKeys.find(theKey); + if (iter != m_LogicKeys.end()) { + qt3ds::runtime::IApplication &theApplication = inPresentation.GetApplication(); + qt3ds::runtime::IElementAllocator &theElemAllocator = + theApplication.GetElementAllocator(); + for (TLogicDataList::const_iterator listIter = iter->second.begin(), + endIter = iter->second.end(); + listIter != endIter; ++listIter) { + if (listIter->m_Active) { + inPresentation.FireCommand( + listIter->m_Type, theElemAllocator.FindElementByHandle(listIter->m_Target), + &listIter->m_Arg1, &listIter->m_Arg2); + } + } + } + } + + void SetActive(QT3DSI32 inActionIndex, bool inActive, IElementAllocator &inElemAllocator) override + { + TIdLogicKeyHash::iterator iter = m_IdToLogicKeys.find(inActionIndex); + if (iter != m_IdToLogicKeys.end()) { + TLogicKeyHash::iterator logicIter = m_LogicKeys.find(iter->second); + if (logicIter != m_LogicKeys.end()) { + for (TLogicDataList::iterator listIter = logicIter->second.begin(), + listEnd = logicIter->second.end(); + listIter != listEnd; ++listIter) + if (listIter->m_Id == inActionIndex) { + listIter->m_Active = inActive; + if (IApplicationCore::isPickingEvent(logicIter->first.m_CommandHash)) { + SElement *theElement = inElemAllocator.FindElementByHandle( + logicIter->first.m_ElementHandle); + if (theElement && inActive) + theElement->SetFlag(Q3DStudio::ELEMENTFLAG_PICKENABLED, true); + } + } + } + } + } + + void SaveBinaryData(qt3ds::foundation::IOutStream &ioStream) override + { + qt3ds::foundation::SWriteBuffer theWriter(m_Foundation.getAllocator(), "WriteBuffer"); + theWriter.write(m_NextId); + theWriter.write((QT3DSU32)m_LogicKeys.size()); + for (TLogicKeyHash::iterator iter = m_LogicKeys.begin(), end = m_LogicKeys.end(); + iter != end; ++iter) { + if (iter->second.m_Head == NULL) + continue; + + theWriter.write(iter->first); + QT3DSU32 datumOffset = theWriter.size(); + theWriter.write((QT3DSU32)0); + QT3DSU32 datumCount = 0; + for (SLogicData *theDatum = iter->second.m_Head; theDatum; + theDatum = theDatum->m_NextLogicData, ++datumCount) { + theWriter.write(*theDatum); + } + QT3DSU32 *countPtr = reinterpret_cast(theWriter.begin() + datumOffset); + *countPtr = datumCount; + } + ioStream.Write(theWriter.begin(), theWriter.size()); + } + + void LoadBinaryData(NVDataRef inLoadData) override + { + m_LoadData = inLoadData; + SDataReader theReader(inLoadData.begin(), inLoadData.end()); + m_NextId = *theReader.Load(); + QT3DSU32 numKeys = *theReader.Load(); + for (QT3DSU32 idx = 0, end = numKeys; idx < end; ++idx) { + SLogicKey theKey = *theReader.Load(); + QT3DSU32 numActions = *theReader.Load(); + if (numActions == 0) + continue; + + TLogicKeyHash::iterator inserter = + m_LogicKeys.insert(eastl::make_pair(theKey, TLogicDataList())).first; + SLogicData *lastDatum = NULL; + for (QT3DSU32 actIdx = 0, actEnd = numActions; actIdx < actEnd; ++actIdx) { + SLogicData *nextDatum = theReader.Load(); + if (lastDatum == NULL) + inserter->second.m_Head = nextDatum; + else + lastDatum->m_NextLogicData = nextDatum; + lastDatum = nextDatum; + m_IdToLogicKeys.insert(eastl::make_pair(nextDatum->m_Id, theKey)); + } + if (lastDatum) + lastDatum->m_NextLogicData = NULL; + } + } +}; +} + +ILogicSystem &ILogicSystem::CreateLogicSystem(NVFoundationBase &inFnd) +{ + return *QT3DS_NEW(inFnd.getAllocator(), SLogicSystem)(inFnd); +} diff --git a/src/Runtime/Source/runtime/Qt3DSLogicSystem.h b/src/Runtime/Source/runtime/Qt3DSLogicSystem.h new file mode 100644 index 00000000..af13c91f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSLogicSystem.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_LOGIC_SYSTEM_H +#define QT3DS_LOGIC_SYSTEM_H +#include "Qt3DSElementSystem.h" + +namespace qt3ds { +namespace runtime { + + class ILogicSystem : public NVRefCounted + { + public: + // returns the action id + virtual QT3DSI32 AddAction(element::SElement &inTrigger, + Q3DStudio::TEventCommandHash inEventNameHash, + element::SElement *inTarget, element::SElement *inOwner, + Q3DStudio::TEventCommandHash inType, Q3DStudio::UVariant inArg1, + Q3DStudio::UVariant inArg2, bool inActive) = 0; + + virtual void OnEvent(Q3DStudio::TEventCommandHash inEventName, element::SElement &inTarget, + Q3DStudio::IPresentation &inPresentation) const = 0; + virtual void SetActive(QT3DSI32 inActionIndex, bool inActive, + IElementAllocator &inElemAllocator) = 0; + + virtual void SaveBinaryData(qt3ds::foundation::IOutStream &ioStream) = 0; + virtual void LoadBinaryData(NVDataRef inLoadData) = 0; + + static ILogicSystem &CreateLogicSystem(NVFoundationBase &inFnd); + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.cpp b/src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.cpp new file mode 100644 index 00000000..06d0eee6 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSOutputMemoryStream.h" +#include "Qt3DSHash.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * XXX + */ +COutputMemoryStream::COutputMemoryStream() +{ +} + +//============================================================================== +/** + * XXX + */ +COutputMemoryStream::~COutputMemoryStream() +{ +} + +//============================================================================== +/** + * XXX + */ +void COutputMemoryStream::Reset() +{ + m_Data.clear(); +} + +//============================================================================== +/** + * XXX + */ +COutputMemoryStream &COutputMemoryStream::operator<<(const COutputMemoryStream &inStream) +{ + size_t theSize = inStream.m_Data.size(); + for (size_t theCount = 0; theCount < theSize; ++theCount) + m_Data.push_back(inStream.m_Data[theCount]); + return *this; +} + +//============================================================================== +/** + * XXX + */ +void COutputMemoryStream::WriteStringHash(const CHAR *inItem) +{ + TStringHash theHash = CHash::HashString(inItem); + // DEBUG + //{FILE*fp=fopen("hashed.txt","a");if(fp){fprintf(fp,"%ul %s\n",theHash,inItem);fclose(fp);}} + operator<<(theHash); +} + +//============================================================================== +/** + * XXX + */ +void COutputMemoryStream::WriteEventCommandHash(const CHAR *inItem) +{ + TStringHash theHash = CHash::HashEventCommand(inItem); + // DEBUG + //{FILE*fp=fopen("hashed.txt","a");if(fp){fprintf(fp,"%ul %s\n",theHash,inItem);fclose(fp);}} + operator<<(theHash); +} + +//============================================================================== +/** + * XXX + */ +COutputMemoryStream &COutputMemoryStream::operator<<(const std::string &inString) +{ + const UINT8 *thePtr = reinterpret_cast(inString.c_str()); + for (size_t theCounter = 0; theCounter < inString.size(); ++theCounter) { + m_Data.push_back(*thePtr); + ++thePtr; + } + + return *this; +} + +//============================================================================== +/** + * XXX + */ +COutputMemoryStream &COutputMemoryStream::operator<<(const EAttributeType inType) +{ + UINT8 theType = static_cast(inType); + m_Data.push_back(theType); + + return *this; +} + +//============================================================================== +/** + * XXX + */ +UINT32 COutputMemoryStream::GetSize() const +{ + return static_cast(m_Data.size()); +} + +//============================================================================== +/** + * XXX + */ +const UINT8 *COutputMemoryStream::GetData() const +{ + return &m_Data[0]; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.h b/src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.h new file mode 100644 index 00000000..da28245f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSOutputMemoryStream.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSHash.h" +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable : 4820) // X bytes padding added after data member +#pragma warning( \ + disable : 4061) // enumerator X in switch of enum Y is not explicitly handled by a case label +#pragma warning(disable : 4062) // enumerator X in switch of enum Y is not handled +#pragma warning(disable : 4548) // xlocale warnings +#pragma warning( \ + disable : 4738) // storing 32-bit float result in memory, possible loss of performance +#endif +#include +#include +#include +#include + +#ifdef _WIN32 +#pragma warning(pop) +#endif + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Class +//============================================================================== +class COutputMemoryStream +{ + //============================================================================== + // Fields + //============================================================================== +public: + std::vector m_Data; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + COutputMemoryStream(); + virtual ~COutputMemoryStream(); + +public: // Access + void Reset(); + UINT32 GetSize() const; + const UINT8 *GetData() const; + +public: // Output + void WriteStringHash(const CHAR *inItem); + void WriteEventCommandHash(const CHAR *inItem); + +public: // Operators + COutputMemoryStream &operator<<(const COutputMemoryStream &inStream); + COutputMemoryStream &operator<<(const std::string &inString); + COutputMemoryStream &operator<<(const EAttributeType inType); + + //============================================================================== + // Template Methods + //============================================================================== +public: + template + COutputMemoryStream &operator<<(const T &inItem) + { + size_t theSize = sizeof(T); + const UINT8 *thePtr = reinterpret_cast(&inItem); + for (size_t theCounter = 0; theCounter < theSize; ++theCounter) { + m_Data.push_back(*thePtr); + ++thePtr; + } + return *this; + } + + template + void SetData(const T &inItem, UINT32 inByteOffset) + { + UINT8 *theSourcePtr = &m_Data[inByteOffset]; + size_t theSize = sizeof(T); + const UINT8 *thePtr = reinterpret_cast(&inItem); + for (size_t theCounter = 0; theCounter < theSize; ++theCounter) { + *theSourcePtr = *thePtr; + ++thePtr; + ++theSourcePtr; + } + } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSParametersSystem.cpp b/src/Runtime/Source/runtime/Qt3DSParametersSystem.cpp new file mode 100644 index 00000000..84b642cd --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSParametersSystem.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" +#include "Qt3DSParametersSystem.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSIndexableLinkedList.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/SerializationTypes.h" +#include "foundation/IOStreams.h" + +using namespace qt3ds::runtime; + +namespace { + +struct SParameterGroup +{ + enum { + NumParametersPerGroup = 4, + }; + TIdValuePair m_Data[NumParametersPerGroup]; + SParameterGroup *m_NextNode; + + SParameterGroup() + : m_NextNode(NULL) + { + } +}; + +struct SParameterGroupEntry +{ + QT3DSU32 m_ParameterCount; + SParameterGroup *m_FirstGroup; + SParameterGroupEntry() + : m_ParameterCount(0) + , m_FirstGroup(NULL) + { + } +}; + +typedef IndexableLinkedList + TParametersList; + +struct SParamSystem : public IParametersSystem +{ + typedef nvhash_map TIdGroupHash; + + NVFoundationBase &m_Foundation; + TParametersList::TPoolType m_ParametersPool; + TIdGroupHash m_Groups; + QT3DSI32 m_NextId; + NVDataRef m_LoadData; + QT3DSI32 m_RefCount; + + SParamSystem(NVFoundationBase &fnd) + : m_Foundation(fnd) + , m_ParametersPool(ForwardingAllocator(fnd.getAllocator(), "ParametersPool")) + , m_Groups(fnd.getAllocator(), "m_Groups") + , m_NextId(1) + , m_RefCount(0) + { + } + + void addRef() override { atomicIncrement(&m_RefCount); } + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc = m_Foundation.getAllocator(); + NVDelete(alloc, this); + } + } + + void IncrementId() + { + ++m_NextId; + if (!m_NextId) + ++m_NextId; + } + + QT3DSI32 CreateParameterGroup() override + { + eastl::pair inserter = + m_Groups.insert(eastl::make_pair(m_NextId, SParameterGroupEntry())); + while (inserter.second == false) { + IncrementId(); + inserter = m_Groups.insert(eastl::make_pair(m_NextId, SParameterGroupEntry())); + } + return inserter.first->first; + } + + void AddParameter(QT3DSI32 inGroup, QT3DSU32 inNameHash, Q3DStudio::UVariant inParam) override + { + TIdGroupHash::iterator iter = m_Groups.find(inGroup); + if (iter == m_Groups.end()) { + QT3DS_ASSERT(false); + return; + } + + SParameterGroupEntry &theEntry(iter->second); + TIdValuePair &thePair = TParametersList::Create( + theEntry.m_FirstGroup, theEntry.m_ParameterCount, m_ParametersPool); + thePair = eastl::make_pair(inNameHash, inParam); + } + + QT3DSU32 GetNumParameters(QT3DSI32 inGroup) const override + { + TIdGroupHash::const_iterator iter = m_Groups.find(inGroup); + if (iter == m_Groups.end()) { + QT3DS_ASSERT(false); + return 0; + } + + const SParameterGroupEntry &theEntry(iter->second); + return theEntry.m_ParameterCount; + } + TIdValuePair GetParameter(QT3DSI32 inGroup, QT3DSU32 inIndex) const override + { + Q3DStudio::UVariant dummyValue; + dummyValue.m_INT32 = 0; + TIdValuePair retval = TIdValuePair(0, dummyValue); + + TIdGroupHash::const_iterator iter = m_Groups.find(inGroup); + if (iter == m_Groups.end()) { + QT3DS_ASSERT(false); + return retval; + } + + const SParameterGroupEntry &theEntry(iter->second); + + if (inIndex < theEntry.m_ParameterCount) + return TParametersList::GetObjAtIdx(theEntry.m_FirstGroup, inIndex); + + QT3DS_ASSERT(false); + return retval; + } +}; +} + +IParametersSystem &IParametersSystem::CreateParametersSystem(NVFoundationBase &fnd) +{ + return *QT3DS_NEW(fnd.getAllocator(), SParamSystem)(fnd); +} diff --git a/src/Runtime/Source/runtime/Qt3DSParametersSystem.h b/src/Runtime/Source/runtime/Qt3DSParametersSystem.h new file mode 100644 index 00000000..50a4652d --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSParametersSystem.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_PARAMETERS_SYSTEM_H +#define QT3DS_PARAMETERS_SYSTEM_H +#pragma once +#include "Qt3DSKernelTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/utility.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace foundation { + class IOutStream; +} +} + +namespace qt3ds { +namespace runtime { + using namespace qt3ds; + using namespace qt3ds::foundation; + + typedef eastl::pair TIdValuePair; + + class IParametersSystem : public NVRefCounted + { + public: + virtual QT3DSI32 CreateParameterGroup() = 0; + virtual void AddParameter(QT3DSI32 inGroup, QT3DSU32 inNameHash, Q3DStudio::UVariant inParam) = 0; + + virtual QT3DSU32 GetNumParameters(QT3DSI32 inGroupId) const = 0; + virtual TIdValuePair GetParameter(QT3DSI32 inGroupId, QT3DSU32 inIndex) const = 0; + + static IParametersSystem &CreateParametersSystem(NVFoundationBase &inFoundation); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSPickFrame.h b/src/Runtime/Source/runtime/Qt3DSPickFrame.h new file mode 100644 index 00000000..15da72c9 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSPickFrame.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSInputFrame.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class IPresentation; + +//============================================================================== +/** + * Reporting structure describing a complete mouse pick including initial + * mouse XY screen position, which element was hit, UV point of hit, global + * intersection point and more. + */ +struct SPickFrame +{ + SInputFrame m_InputFrame; ///< Input values to process + + FLOAT m_PickOrigin[3]; ///< 3D pick ray start + FLOAT m_PickDirection[3]; ///< 3D pick ray direction + + FLOAT m_LocalHit[2]; ///< 2D pick ray intersection + FLOAT m_SquaredDistance; ///< Distance from camera to intersection + TElement *m_Model; ///< Element picked + // IPresentation* m_SubPresentation; ///< The picked element has a subpresentation + + BOOL m_ResultValid; ///< Model found - Whole structure is valid + INT8 m_Unused[3]; ///< Padding +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSPresentation.cpp b/src/Runtime/Source/runtime/Qt3DSPresentation.cpp new file mode 100644 index 00000000..358b3abb --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSPresentation.cpp @@ -0,0 +1,784 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSPresentation.h" +#include "Qt3DSCommandEventTypes.h" +#include "Qt3DSIScriptBridge.h" +#include "Qt3DSInputEventTypes.h" +#include "Qt3DSDataLogger.h" +#include "Qt3DSApplication.h" +#include "Qt3DSRuntimeFactory.h" +#include "Qt3DSCommandHelper.h" +#include "Qt3DSActivationManager.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSComponentManager.h" +#include "Qt3DSRenderBufferLoader.h" +#include "Qt3DSSlideSystem.h" +#include "Qt3DSLogicSystem.h" +#include "Qt3DSParametersSystem.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +/// Maximum number of Event/Command that can be queued in an Update cycle +const INT32 Q3DStudio_EVENTCOMMANDQUEUECAPACITY = 512; + +/// Limit to prevent infinite loop during queue processing +const INT32 Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT = Q3DStudio_EVENTCOMMANDQUEUECAPACITY * 10; + +#ifdef WIN32 +#pragma warning(push) +#pragma warning(disable : 4355) +#endif +//============================================================================== +/** + * Constructor + */ +CPresentation::CPresentation(const CHAR *inName, qt3ds::runtime::IApplication *inApplication) + : m_Name(inName) + , m_Application(inApplication) + , m_Scene(NULL) + , m_ActivityZone(NULL) + , m_RootElement(NULL) + , m_EventCommandQueue(Q3DStudio_EVENTCOMMANDQUEUECAPACITY, "EventCommandQueue") + , m_IsProcessingEventCommandQueue(false) + , m_ComponentManager(*this) + , m_Offset(0) + , m_LocalTime(0) + , m_PreviousGlobalTime(-1) + , m_Paused(false) + , m_OffsetInvalid(true) + , m_Active(true) +{ + m_Size.m_Width = 0; + m_Size.m_Height = 0; + m_Size.m_ScaleMode = SCALEMODE_UNKNOWN; + m_AnimationSystem = IAnimationSystem::CreateAnimationSystem( + inApplication->GetRuntimeFactoryCore().GetFoundation()); + m_SlideSystem = + ISlideSystem::CreateSlideSystem(inApplication->GetRuntimeFactoryCore().GetFoundation(), + inApplication->GetRuntimeFactoryCore().GetStringTable(), + inApplication->GetElementAllocator()); + m_LogicSystem = + ILogicSystem::CreateLogicSystem(inApplication->GetRuntimeFactoryCore().GetFoundation()); + m_ParametersSystem = IParametersSystem::CreateParametersSystem( + inApplication->GetRuntimeFactoryCore().GetFoundation()); +} +#ifdef _WIN32 +#pragma warning(pop) +#endif + +//============================================================================== +/** + * Destructor + */ +CPresentation::~CPresentation() +{ +} + +//============================================================================== +/** + * Registers an element for notification when events fired on it. + * @param inElement target element to monitor + * @param inEventHash event hash to register for + * @param inCallback static callback function + * @param inContextData arbitrary data pointer + */ +void CPresentation::RegisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) +{ + m_EventCallbacks.RegisterCallback(inElement, inEventHash, inCallback, inContextData); + inElement->SetFlag(ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK, true); + + if (qt3ds::runtime::IApplicationCore::isPickingEvent(inEventHash)) + inElement->SetFlag(ELEMENTFLAG_PICKENABLED, true); +} + +//============================================================================== +/** + * Unregisters a previously registered event callback. + * @param inElement target element to monitor + * @param inEventHash event hash to register for + * @param inCallback static callback function + * @param inContextData arbitrary data pointer + */ +BOOL CPresentation::UnregisterEventCallback(TElement *inElement, + const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) +{ + BOOL theLast = false; + BOOL theResult = m_EventCallbacks.UnregisterCallback(inElement, inEventHash, inCallback, + inContextData, theLast); + + // Unflag element if there are no longer any callbacks on it + if (theLast) + inElement->SetFlag(ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK, false); + + if (qt3ds::runtime::IApplicationCore::isPickingEvent(inEventHash)) + inElement->SetFlag(ELEMENTFLAG_PICKENABLED, false); + + return theResult; +} + +void CPresentation::ClearDirtyList() +{ + FOR_ARRAY(TElement *, theElement, GetFrameData().GetDirtyList()) + { + (*theElement)->Flags().SetDirty(false); + } + GetFrameData().Reset(); +} + +inline void ConvertActivityZoneBufferToElementList(qt3ds::runtime::TActivityItemBuffer inSource, + TElementList &outResult) +{ + for (qt3ds::QT3DSU32 idx = 0, end = inSource.size(); idx < end; ++idx) + outResult.Push(inSource[idx].first); +} + +void CPresentation::PreUpdate(const TTimeUnit inGlobalTime) +{ + if (m_OffsetInvalid || m_Paused) { + m_OffsetInvalid = false; + m_Offset = m_LocalTime - inGlobalTime; + } else + m_LocalTime = inGlobalTime + m_Offset; + + // Event/Command Processing Stage + ProcessEventCommandQueue(); +} + +//============================================================================== +/** + * Update the presentation to the current time. This will start triggering the + * various stages of the presentation frame rhythm + * @param inGlobalTime time at which to update each presentation + * @return true if there were events to be processed. + */ +void CPresentation::BeginUpdate() +{ + // Active Scan Stage + if (m_ActivityZone) { + m_ActivityZone->BeginUpdate( + m_LocalTime, m_Application->GetRuntimeFactory().GetPerfTimer(), + m_Application->GetRuntimeFactory().GetQt3DSRenderContext().GetThreadPool()); + } +} + +void CPresentation::EndUpdate() +{ + if (m_ActivityZone) { + m_ActivityZone->EndUpdate(); + CPresentationFrameData &theFrameData = GetFrameData(); + ConvertActivityZoneBufferToElementList(m_ActivityZone->GetActivatedItems(), + theFrameData.GetActivationList()); + ConvertActivityZoneBufferToElementList(m_ActivityZone->GetDeactivatedItems(), + theFrameData.GetDeactivationList()); + ConvertActivityZoneBufferToElementList(m_ActivityZone->GetScriptItems(), + theFrameData.GetScriptsList()); + } + + if (!m_Paused) { + // Animation Track Evaluation Stage + m_AnimationSystem->Update(); + } +} + +void CPresentation::PostUpdate(const TTimeUnit inGlobalTime) +{ + if (!m_Paused) { + // Callback Stage + if (m_Application && m_PreviousGlobalTime != inGlobalTime) + m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessFrameCallbacks(this); + } + + m_PreviousGlobalTime = inGlobalTime; +} + +//============================================================================== +/** + * Process the Event/Command queue completely + * PostEventCommand is the method that will add new Event/Command to the queue. + * + * The contract for Event/Command processing: + * 1. If an Event or Command is posted during the processing stage, it will be added + * to the end of the queue and is guaranteed to be processed in the current cycle. + * For example, if an Event (which is processed) triggers a Command to set a model to red, + * the model will turn red in the current frame. + * + * 2. If an Event or Command is posted after the processing stage, such as during the + * Callback stage, it will only be processed on the next Update cycle. + * For example, if the "turn mode to red" Command is posted in a script callback, the + * model will turn red in the next frame. + * + * 3. If an Event or Command is posted before the processing stage, for example an + * external Event posted just before the Update cycle, it will be processed in the current + *cycle. + * For example, if the "turn mode to red" Command is posted from the game engine prior to + * the Update cycle, the model will turn red in the current frame. + * + * @see PostEventCommand + * @return true if there were events that were processed. + */ +BOOL CPresentation::ProcessEventCommandQueue() +{ + PerfLogGeneralEvent2(DATALOGGER_PROCESSEVENTS); + + m_IsProcessingEventCommandQueue = true; + + BOOL theResult = !m_EventCommandQueue.IsEmpty(); + INT32 theEventProcessedCount = 0; + while (!m_EventCommandQueue.IsEmpty()) { + SEventCommand &theEventCommand = m_EventCommandQueue.Top(); + if (theEventCommand.m_IsEvent) + ProcessEvent(theEventCommand, theEventProcessedCount); + else + ProcessCommand(theEventCommand); + + // Infinite-loop check + if (theEventProcessedCount > Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT) { + // Breakout policy: Dump remaining Event/Commands + qCCritical(qt3ds::INVALID_OPERATION) + << "ProcessEventCommandQueue exceeded maximum loop count" + << "Remaining Event/Commands will be cleared. Event count: " + << theEventProcessedCount << "Limit: " << Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT; + m_EventCommandQueue.Clear(); + } else { + m_EventCommandQueue.Pop(); + } + } + + m_IsProcessingEventCommandQueue = false; + + return theResult; +} + +//============================================================================== +/** + * Pass incoming event to event consumers immediately + * @param ioEvent the incoming event + */ +void CPresentation::ProcessEvent(SEventCommand &ioEvent, INT32 &ioEventCount) +{ + if (ioEventCount < Q3DStudio_MAXEVENTCOMMANDLOOPCOUNT) { + ++ioEventCount; + PerfLogPresentationEvent1(DATALOGGER_PROCESSEVENT); + + // Callbacks can change ioEvent's bubbling flags + if (ioEvent.m_Target->GetFlag(ELEMENTFLAG_REGISTEREDFOREVENTCALLBACK)) { + m_EventCallbacks.FireCallbacks(ioEvent); + } + + // Do an early return if callback do a "stopImmediatePropagation" + if (ioEvent.m_Done) + return; + + if (ioEvent.m_Target) { + // Logic should not be able to change ioEvent's bubbling flags + // ...or can it? + m_LogicSystem->OnEvent(ioEvent.m_Type, *ioEvent.m_Target, *this); + } + + ProcessEventBubbling(ioEvent, ioEventCount); + } +} + +//============================================================================== +/** + * Handle event bubbling + * @param ioEvent the incoming event + */ +void CPresentation::ProcessEventBubbling(SEventCommand &ioEvent, INT32 &ioEventCount) +{ + PerfLogPresentationEvent1(DATALOGGER_PROCESSEVENTBUBBLING); + + // Check for onGroupedMouseOver/Out + // arg1 = the original onMouseOut model and arg2 = the original onMouseOver model + if (ioEvent.m_Type == ON_MOUSEOUT) { + // If original onMouseOver model is NULL or not a descendent, fire onGroupedMouseOut + TElement *theMouseOverModel = static_cast(ioEvent.m_Arg2.m_VoidPointer); + if (!theMouseOverModel || !ioEvent.m_Target->IsDescendent(*theMouseOverModel)) { + SEventCommand theEvent = ioEvent; + theEvent.m_Type = ON_GROUPEDMOUSEOUT; + theEvent.m_BubbleUp = 0; // no bubbling + theEvent.m_BubbleDown = 0; + FireEvent(theEvent); + } + // set the original onMouseOver model to the target to make IsDescendent queries less + // expensive + else if (theMouseOverModel) { + ioEvent.m_Arg2.m_VoidPointer = ioEvent.m_Target; + } + } else if (ioEvent.m_Type == ON_MOUSEOVER) { + // If original onMouseOut model is NULL or not a descendent, fire onGroupedMouseOver + TElement *theMouseOutModel = static_cast(ioEvent.m_Arg1.m_VoidPointer); + if (!theMouseOutModel || !ioEvent.m_Target->IsDescendent(*theMouseOutModel)) { + SEventCommand theEvent = ioEvent; + theEvent.m_Type = ON_GROUPEDMOUSEOVER; + theEvent.m_BubbleUp = 0; // no bubbling + theEvent.m_BubbleDown = 0; + FireEvent(theEvent); + } + // set the original onMouseOut model to the target to make IsDescendent queries less + // expensive + else if (theMouseOutModel) { + ioEvent.m_Arg1.m_VoidPointer = ioEvent.m_Target; + } + } + + // Do NOT bubble up onSlideEnter and onSlideExit events from current component to its parent + // scene + // since each component has its own slides. + if (ioEvent.m_BubbleUp && (ioEvent.m_Target->Flags() & ELEMENTFLAG_COMPONENT) + && (ioEvent.m_Type == EVENT_ONSLIDEENTER || ioEvent.m_Type == EVENT_ONSLIDEEXIT)) { + ioEvent.m_BubbleUp = FALSE; + } + + // Event bubbling + if (ioEvent.m_BubbleUp) { + TElement *theParent = ioEvent.m_Target->m_Parent; + if (theParent) { + ioEvent.m_Target = theParent; + ProcessEvent(ioEvent, ioEventCount); + } + } +} + +//============================================================================== +/** + * Execute command immediately + * @param inCommand incoming command structure + */ +void CPresentation::ProcessCommand(const SEventCommand &inCommand) +{ + PerfLogPresentationEvent1(DATALOGGER_PROCESSCOMMAND); + + // Attributes (Arg1 = key, Arg2 = value) + if (inCommand.m_Type == COMMAND_SETPROPERTY) { + SAttributeKey theAttributeKey; + UINT32 theHash = static_cast(inCommand.m_Arg1.m_Hash); + theAttributeKey.Convert( + theHash); // Need this conversion to prevent problems arising due to endianess + inCommand.m_Target->SetAttribute(theAttributeKey.m_Hash, inCommand.m_Arg2); + + // Events (Arg1 = hashed event name) + } else if (inCommand.m_Type == COMMAND_FIREEVENT) { + FireEvent(inCommand.m_Arg1.m_Hash, inCommand.m_Target); + + // Time (Arg1 = time) + } else if (inCommand.m_Type == COMMAND_PLAY) { + GetComponentManager().SetPause(inCommand.m_Target, false); + } else if (inCommand.m_Type == COMMAND_PAUSE) { + GetComponentManager().SetPause(inCommand.m_Target, true); + } else if (inCommand.m_Type == COMMAND_GOTOTIME) { + GetComponentManager().GoToTime(inCommand.m_Target, inCommand.m_Arg1.m_INT32); + + // Slide (Arg1 = slide index or slide name) + } else if (inCommand.m_Type == COMMAND_GOTOSLIDE) { + // Goto slide commands are handled differently. + IComponentManager &theManager(GetComponentManager()); + Q3DStudio::SComponentGotoSlideData theGotoSlideData = + theManager.GetComponentGotoSlideCommand(inCommand.m_Target); + if (theGotoSlideData.m_Slide > 0) + theManager.GotoSlideIndex(inCommand.m_Target, theGotoSlideData); + + theManager.ReleaseComponentGotoSlideCommand(inCommand.m_Target); + } else if (inCommand.m_Type == COMMAND_GOTOSLIDENAME) { + GetComponentManager().GotoSlideName(inCommand.m_Target, inCommand.m_Arg1.m_Hash); + } else if (inCommand.m_Type == COMMAND_GOTONEXTSLIDE) { + GetComponentManager().GoToNextSlide(inCommand.m_Target); + } else if (inCommand.m_Type == COMMAND_GOTOPREVIOUSSLIDE) { + GetComponentManager().GoToPreviousSlide(inCommand.m_Target); + } else if (inCommand.m_Type == COMMAND_BACKSLIDE) { + GetComponentManager().GoToBackSlide(inCommand.m_Target); + + // Behavior + } else if (inCommand.m_Type == COMMAND_CUSTOMACTION) { + m_Application->GetRuntimeFactoryCore().GetScriptEngineQml() + .ProcessCustomActions(this, inCommand); + } else if (inCommand.m_Type == COMMAND_CUSTOMCALLBACK) { + m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessCustomCallback( + this, inCommand); + } else if (inCommand.m_Type == COMMAND_PLAYSOUND) { + CRegisteredString theSoundPathReg = GetStringTable().HandleToStr(inCommand.m_Arg1.m_INT32); + if (theSoundPathReg.IsValid()) { + const char *theSoundPath = theSoundPathReg.c_str(); + if (strlen(theSoundPath) > 0) { + m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().PlaySoundFile( + theSoundPath); + } + } + } else if (inCommand.m_Type == COMMAND_EMITSIGNAL) { + m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessSignal(this, inCommand); + } else { + qCCritical(qt3ds::INVALID_OPERATION) << "Command not implemented: " << inCommand.m_Type; + } +} + +//============================================================================== +/** + * Put an Event in the queue to be processed later during the Event/Command + * processing stage in Update + * This method is used by Event-bubbling during ProcessEvent + * + * @param inEvent the incoming event + * @see PostEvent + */ +void CPresentation::FireEvent(const SEventCommand &inEvent) +{ + SEventCommand &theEventCommand = m_EventCommandQueue.NewEntry(); + + theEventCommand = inEvent; + + theEventCommand.m_IsEvent = true; +} + +//============================================================================== +/** + * Put an Event in the queue to be processed later during the Event/Command + * processing stage in Update See ProcessEventCommandQueue for more + * information on the contract for Event/Command processing. + * + * @param inEventType the incoming event type + * @param inTarget the target for the event + * @param inArg1 optional argument #1 + * @param inArg2 optional argument #2 + * @param inType1 optional type for argument #1 + * @param inType2 optional type for argument #2 + * @see ProcessEventCommandQueue + * @see PostEventCommand + */ +void CPresentation::FireEvent(const TEventCommandHash inEventType, TElement *inTarget, + const UVariant *inArg1, const UVariant *inArg2, + const EAttributeType inType1, const EAttributeType inType2) +{ + + SEventCommand theEvent = { inTarget, inEventType }; + + theEvent.m_IsEvent = true; + theEvent.m_BubbleUp = true; + + theEvent.m_Arg1Type = static_cast(inType1); + theEvent.m_Arg2Type = static_cast(inType2); + + if (inArg1) + theEvent.m_Arg1 = *inArg1; + if (inArg2) + theEvent.m_Arg2 = *inArg2; + + m_EventCommandQueue.NewEntry() = theEvent; +} + +//============================================================================== +/** + * Put a Command in the queue to be processed later during the Event/Command + * processing stage in Update. See ProcessEventCommandQueue for more information + * on the contract for Event/Command processing. + * + * For cases where the Commands need to be synchronized with the Frame-Rhythm + * An example would be calling "SetSlide" in scripts. + * + * @see ProcessEventCommandQueue + * @see PostEventCommand + * @param inEventType the incoming command type + * @param inTarget the target for the command + * @param inArg1 optional argument #1 + * @param inArg2 optional argument #2 + * @param inType1 optional type for argument #1 + * @param inType2 optional type for argument #2 + */ +void CPresentation::FireCommand(const TEventCommandHash inEventType, TElement *inTarget, + const UVariant *inArg1, const UVariant *inArg2, + const EAttributeType inType1, const EAttributeType inType2) +{ + // Pre-filter gotoslidename commands. + if (inEventType == COMMAND_GOTOSLIDENAME) { + int theSlideHashName = inArg1->m_INT32; + TComponent *theComponent = GetComponentManager().GetComponent(inTarget); + UINT8 theSlideIndex = GetSlideSystem().FindSlide(*theComponent, theSlideHashName); + // Translate into a slide index command. + CCommandHelper::SetupGotoSlideCommand(*inTarget, theSlideIndex, + SScriptEngineGotoSlideArgs()); + } else { + SEventCommand theCommand = { inTarget, inEventType }; + + theCommand.m_Arg1Type = static_cast(inType1); + theCommand.m_Arg2Type = static_cast(inType2); + + if (inArg1) + theCommand.m_Arg1 = *inArg1; + if (inArg2) + theCommand.m_Arg2 = *inArg2; + + m_EventCommandQueue.NewEntry() = theCommand; + } +} + +void CPresentation::FlushEventCommandQueue(void) +{ + if (!m_IsProcessingEventCommandQueue) + ProcessEventCommandQueue(); +} + +void CPresentation::ProcessEvent(SEventCommand &inEvent) +{ + INT32 theEventProcessedCount = 0; + ProcessEvent(inEvent, theEventProcessedCount); +} +//============================================================================== +/** + * This method is triggered after the presentation is streamed in. At this point, + * all the stores will be loaded up. + */ +void CPresentation::OnPresentationLoaded() +{ + m_FrameData.Reserve(1000 /*m_ElementManager.GetElementCount( )*/); +} + +//============================================================================== +/** + * Set the full path for this presentation. This can be used by anyone who + * knows the presentation to form relative paths. + * @param inPath the path to which to set. + */ +void CPresentation::SetFilePath(const CHAR *inPath) +{ + m_FilePath = inPath; +} + +//============================================================================== +/** + * Gets the full file path for this presentation. This can be used by anyone who + * knows the presentation to form relative correct paths. + */ +QString CPresentation::GetFilePath() +{ + return m_FilePath; +} + +//============================================================================== +/** + * Gets the pause state + * @return true if the presentation is paused, false if otherwise + */ +BOOL CPresentation::GetPause() const +{ + return m_Paused; +} + +//============================================================================== +/** + * Sets the pause state + * @param inPause set true to pause, set false if otherwise + */ +void CPresentation::SetPause(const BOOL inPause) +{ + m_Paused = inPause ? true : false; +} + +//============================================================================== +/** + * Simple manager access: Scene + */ +void CPresentation::SetScene(IScene *inScene) +{ + m_Scene = inScene; +} + +void CPresentation::SetActivityZone(qt3ds::runtime::IActivityZone *inZone) +{ + m_ActivityZone = inZone; + m_ActivityZone->SetZoneActive(m_Active); + TElement *theSceneElement = m_RootElement; + qt3ds::runtime::IActivityZone &theZone(*GetActivityZone()); + // The activity zone requires elements described to it in breadth first search order. + theZone.AddActivityItems(*theSceneElement); +} + +void CPresentation::SetActive(bool inValue) +{ + m_Active = inValue; + m_ActivityZone->SetZoneActive(m_Active); +} + +bool CPresentation::GetActive() const +{ + return m_Active; +} + +//============================================================================== +/** + * Simple manager access: Scene + */ +IScene *CPresentation::GetScene() const +{ + return m_Scene; +} + +//============================================================================== +/** +* Simple manager access: Script Bridge Qml +*/ +IScriptBridge *CPresentation::GetScriptBridgeQml() +{ + if (m_Application) + return &m_Application->GetRuntimeFactoryCore().GetScriptEngineQml(); + + return NULL; +} + +//============================================================================== +/** + * Simple manager access: Component Manager + */ +IComponentManager &CPresentation::GetComponentManager() +{ + return m_ComponentManager; +} + +//============================================================================== +/** + * Simple manager access: Slide Manager + */ +ISlideSystem &CPresentation::GetSlideSystem() +{ + return *m_SlideSystem; +} + +//============================================================================== +/** + * Simple manager access: Animation Manager + */ +qt3ds::runtime::IAnimationSystem &CPresentation::GetAnimationSystem() +{ + return *m_AnimationSystem; +} + +//============================================================================== +/** + * Simple manager access: Logic Manager + */ +ILogicSystem &CPresentation::GetLogicSystem() +{ + return *m_LogicSystem; +} + +//============================================================================== +/** + * Simple manager access: Params Manager + */ +IParametersSystem &CPresentation::GetParametersSystem() +{ + return *m_ParametersSystem; +} + +void CPresentation::SetElementPath(TElement &inElement, const char8_t *inPath) +{ + CRegisteredString str; + if (m_Application) + str = m_Application->GetRuntimeFactoryCore().GetStringTable().RegisterStr( + qt3ds::foundation::nonNull(inPath)); + + if (str.IsValid()) + m_ElementPathMap.insert(eastl::make_pair(&inElement, str)); +} + +qt3ds::foundation::CRegisteredString CPresentation::GetElementPath(TElement &inElement) +{ + TElemStringMap::iterator iter = m_ElementPathMap.find(&inElement); + if (iter != m_ElementPathMap.end()) + return iter->second; + + return qt3ds::foundation::CRegisteredString(); +} + +qt3ds::foundation::IStringTable &CPresentation::GetStringTable() +{ + return GetApplication().GetRuntimeFactoryCore().GetStringTable(); +} + +//============================================================================== +/** + * Current frame data stores traversal lists for use later + */ +CPresentationFrameData &CPresentation::GetFrameData() +{ + return m_FrameData; +} + +void CPresentation::SetLoadedBuffer(qt3ds::render::ILoadedBuffer &inBuffer) +{ + m_LoadedBuffer = inBuffer; +} + +//============================================================================== +/** + * Retrieve the name of the presentation. This is actually the file path. + * @return the name of this presentation + */ +const QByteArray CPresentation::GetName() const +{ + return m_Name.toLatin1(); +} + +//============================================================================== +/** + * Retrieve the size of the presentation in Studio + * @return the size of this presentation + */ +SPresentationSize CPresentation::GetSize() const +{ + return m_Size; +} + +//============================================================================== +/** + * Set the size of the presentation as reflected in Studio + * @param inSize size of presentation ( width, height, scale mode ) in Studio + */ +void CPresentation::SetSize(const SPresentationSize &inSize) +{ + m_Size = inSize; +} + +QPresentationSignalProxy *CPresentation::signalProxy() +{ + return &m_SignalProxy; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSPresentation.h b/src/Runtime/Source/runtime/Qt3DSPresentation.h new file mode 100644 index 00000000..0f0b1b0f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSPresentation.h @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "RuntimePrefix.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSPresentationFrameData.h" +#include "Qt3DSAnimationSystem.h" +#include "Qt3DSCircularArray.h" +#include "Qt3DSEventCallbacks.h" +#include "Qt3DSTimePolicy.h" +#include "EASTL/hash_map.h" +#include "foundation/StringTable.h" +#include "Qt3DSComponentManager.h" + +#include + +class QPresentationSignalProxy : public QObject +{ + Q_OBJECT +Q_SIGNALS: + void SigSlideEntered(const QString &elementPath, unsigned int index, const QString &name); + void SigSlideExited(const QString &elementPath, unsigned int index, const QString &name); +}; + +namespace qt3ds { +namespace runtime { + class IApplication; + class IActivityZone; +} +} + +namespace qt3ds { +namespace render { + class ILoadedBuffer; +} +} + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { +//============================================================================== +/** + * Intelligent representation of a Studio presentation. + */ +class CPresentation : public IPresentation +{ + //============================================================================== + // Fields + //============================================================================== +protected: + QString m_Name; ///< Name of ths presentation + QString m_FilePath; ///< The full path from which this presentation was loaded + qt3ds::runtime::IApplication *m_Application; ///< Runtime object + IScene *m_Scene; ///< Connection to the associated scene (render) for this presentation + qt3ds::runtime::IActivityZone *m_ActivityZone; ///< Controls element active status. + TElement *m_RootElement; + + CPresentationFrameData m_FrameData; ///< Storage of data of the current frame + CCircularArray m_EventCommandQueue; ///< The Event/Command integrated queue + bool m_IsProcessingEventCommandQueue; + CEventCallbacks m_EventCallbacks; ///< Handles event callbacks on registered elements + SPresentationSize m_Size; ///< Native width, height and mode exported from Studio + + qt3ds::foundation::NVScopedRefCounted + m_LoadedBuffer; ///< Reference to loaded data when loading from binary. + + CComponentManager m_ComponentManager; + qt3ds::foundation::NVScopedRefCounted + m_SlideSystem; ///< Container and factory of all logics + qt3ds::foundation::NVScopedRefCounted + m_LogicSystem; ///< Container and factory of all logics + qt3ds::foundation::NVScopedRefCounted + m_AnimationSystem; ///< Container and factory of all animation tracks + qt3ds::foundation::NVScopedRefCounted + m_ParametersSystem; ///< Container and factory of all custom actions + + TTimeUnit m_Offset; + TTimeUnit m_LocalTime; + TTimeUnit m_PreviousGlobalTime; + bool m_Paused; + bool m_OffsetInvalid; + bool m_Active; + + typedef eastl::hash_map TElemStringMap; + TElemStringMap m_ElementPathMap; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CPresentation(const CHAR *inName, qt3ds::runtime::IApplication *inRuntime); + virtual ~CPresentation(); + +public: // Execution + void Initialize(); + // Clear dirty elements + void ClearDirtyList() override; + // Run events + void PreUpdate(const TTimeUnit inGlobalTime) override; + // update element graph + void BeginUpdate() override; + // end update element graph + void EndUpdate() override; + // Run behaviors. + void PostUpdate(const TTimeUnit inGlobalTime) override; + +public: // Bridge Control + IScene *GetScene() const override; + IScriptBridge *GetScriptBridgeQml() override; + void SetScene(IScene *inScene) override; + + void SetActivityZone(qt3ds::runtime::IActivityZone *inZone); + qt3ds::runtime::IActivityZone *GetActivityZone() override { return m_ActivityZone; } + void SetActive(bool inValue); + bool GetActive() const; + TElement *GetRoot() override { return m_RootElement; } + void SetRoot(TElement &inRoot) override { m_RootElement = &inRoot; } + +public: // Commands and Events + void FireEvent(const SEventCommand &inEvent); + void FireEvent(const TEventCommandHash inEventType, TElement *inTarget, + const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, + const EAttributeType inType1 = ATTRIBUTETYPE_NONE, + const EAttributeType inType2 = ATTRIBUTETYPE_NONE) override; + void FireCommand(const TEventCommandHash inCommandType, TElement *inTarget, + const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, + const EAttributeType inType1 = ATTRIBUTETYPE_NONE, + const EAttributeType inType2 = ATTRIBUTETYPE_NONE) override; + void FlushEventCommandQueue(void) override; + void ProcessEvent(SEventCommand &inEvent) override; + + QPresentationSignalProxy *signalProxy(); + +public: // Event Callbacks + void RegisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) override; + BOOL UnregisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) override; + +protected: // Execution Helper Methods + void ProcessAllCallbacks(); + BOOL ProcessEventCommandQueue(); + void ProcessEvent(SEventCommand &ioEvent, INT32 &ioEventCount); + void ProcessEventBubbling(SEventCommand &ioEvent, INT32 &ioEventCount); + void ProcessCommand(const SEventCommand &inCommand); + +public: // Managers + IComponentManager &GetComponentManager() override; + ISlideSystem &GetSlideSystem() override; + IAnimationSystem &GetAnimationSystem() override; + ILogicSystem &GetLogicSystem() override; + IParametersSystem &GetParametersSystem() override; + qt3ds::foundation::IStringTable &GetStringTable() override; + qt3ds::runtime::IApplication &GetApplication() override + { + QT3DS_ASSERT(m_Application); + return *m_Application; + } + void SetLoadedBuffer(qt3ds::render::ILoadedBuffer &inBuffer); + + void SetElementPath(TElement &inElement, const char8_t *inPath) override; + qt3ds::foundation::CRegisteredString GetElementPath(TElement &inElement) override; + +public: // Helpers + CPresentationFrameData &GetFrameData() override; + TTimeUnit GetTime() { return m_LocalTime; } + +public: // Hooks and callbacks + void OnPresentationLoaded() override; + +public: // Configuration access + SPresentationSize GetSize() const override; + BOOL GetPause() const; + const QByteArray GetName() const; + + void SetSize(const SPresentationSize &inSize) override; + void SetPause(const BOOL inPause); + void SetHide(const BOOL inHide); + void SetUpdateLock(const BOOL inLockUpdate); + void SetVCAA(const BOOL inVCAA); + +public: // Full file path + void SetFilePath(const CHAR *inPath) override; + QString GetFilePath() override; + +private: // Disabled Copy Construction + CPresentation(CPresentation &); + CPresentation &operator=(const CPresentation &); +private: + QPresentationSignalProxy m_SignalProxy; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSPresentationFrameData.cpp b/src/Runtime/Source/runtime/Qt3DSPresentationFrameData.cpp new file mode 100644 index 00000000..649462aa --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSPresentationFrameData.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSPresentationFrameData.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +const FLOAT DIRTY_STORE_RATIO = 0.1f; +const FLOAT TRAVERSAL_STORE_RATIO = 0.5f; +const FLOAT ACTIVATION_STORE_RATIO = 0.3f; +const FLOAT DEACTIVATION_STORE_RATIO = 0.3f; + +//============================================================================== +/** + * Constructor + */ +CPresentationFrameData::CPresentationFrameData() + : m_DirtyList(0, 0, "Frame:DirtyList") + , m_TraversalList(0, 0, "Frame:TraversalList") + , m_ScriptsList(0, 0, "Frame:ScriptsList") + , m_ActivationList(0, 0, "Frame:ActivationList") + , m_DeactivationList(0, 0, "Frame:DeactivationList") /*,*/ +// m_SlideExitList( 0, 0, "Frame:SlideExitList" ), +// m_SlideEnterList( 0, 0, "Frame:SlideEnterList" ) +{ +} + +//============================================================================== +/** + * Reserve memory from the memory subsytem to store the various arrays. + * @param inElementCount the number of elements loaded + */ +void CPresentationFrameData::Reserve(const INT32 /*inElementCount*/) +{ +} + +//============================================================================== +/** + * Clean up the data. This is usually called at the start of the frame rhythm to + * clean up the data from previous frame + * Memory allocation should be clear by default. + * Previous list could be a lot longer than current or future list which means + * the appliation is using more memory than needed. The heuristics of both + * initialization and runtime freeing is dependent on the presentation. + */ +void CPresentationFrameData::Reset() +{ + // Keep the capacity of these lists every frame since they have consistent + // sizes from frame to frame + m_TraversalList.Clear(false); + m_ScriptsList.Clear(false); + + // These lists are more sporatic (slide changes) for now, clear them as + // above but potential memory saving could occur by calling Clear( true ) instead + m_ActivationList.Clear(false); + m_DeactivationList.Clear(false); + + // NOTE: When we clear the dirty list, we also must ensure that the elements + // themselves are un-dirtied to prepare for the next frame. This is done + // by the caller of "CPresentationFrameData::Reset" + m_DirtyList.Clear(false); + + // m_SlideExitList.Clear( false ); + // m_SlideEnterList.Clear( false ); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSPresentationFrameData.h b/src/Runtime/Source/runtime/Qt3DSPresentationFrameData.h new file mode 100644 index 00000000..332cc84a --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSPresentationFrameData.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Presentation update cycle data storage class. + * + * This is the data collected from the Presentation on each frame. Other subsystems + * or external system uses these data to perform their specific operation + */ +class CPresentationFrameData +{ + //============================================================================== + // Fields + //============================================================================== +protected: + TElementList m_DirtyList; ///< List of elements with modified attributes + TElementList m_TraversalList; ///< List of active elements + TElementList m_ScriptsList; ///< List of elements where scripts are active + TElementList + m_ActivationList; ///< List of elements whose global active flips from false to true + TElementList + m_DeactivationList; ///< List of elements whose global active flops from true to false + // TElementList m_SlideExitList; ///< List of components that exits their + // slides + // TElementList m_SlideEnterList; ///< List of components that enters their + // slides + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CPresentationFrameData(); + void Reserve(const INT32 inElementCount); + +public: // Data Management + void Reset(); + + TElementList &GetDirtyList() { return m_DirtyList; } + TElementList &GetTraversalList() { return m_TraversalList; } + TElementList &GetScriptsList() { return m_ScriptsList; } + TElementList &GetActivationList() { return m_ActivationList; } + TElementList &GetDeactivationList() { return m_DeactivationList; } + // TElementList& GetSlideExitList( ) { return m_SlideExitList; + // } + // TElementList& GetSlideEnterList( ) { return m_SlideEnterList; } + +private: // Disabled Copy Construction + CPresentationFrameData(const CPresentationFrameData &); + CPresentationFrameData &operator=(const CPresentationFrameData &); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSQmlElementHelper.cpp b/src/Runtime/Source/runtime/Qt3DSQmlElementHelper.cpp new file mode 100644 index 00000000..f5f42396 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSQmlElementHelper.cpp @@ -0,0 +1,319 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSQmlElementHelper.h" +#include "Qt3DSCommandEventTypes.h" +#include "Qt3DSHash.h" +#include "Qt3DSAttributeHashes.h" +#include "Qt3DSElementSystem.h" +#include "Qt3DSRuntimeFactory.h" +#include "qmath.h" + +using namespace Q3DStudio; +using namespace qt3ds; + +//============================================================================== +// Constants +//============================================================================== +const char PRESENTATION_DELIMITER = ':'; +const char NODE_DELIMITER = '.'; +const TStringHash RESERVED_THIS = CHash::HashString("this"); +const TStringHash RESERVED_PARENT = CHash::HashString("parent"); +const TStringHash RESERVED_SCENE = CHash::HashString("Scene"); + +//============================================================================== +/** +* Constructor +*/ +CQmlElementHelper::CQmlElementHelper() +{ +} + +//============================================================================== +/** +* Destructor +*/ +CQmlElementHelper::~CQmlElementHelper() +{ +} + +TElement *CQmlElementHelper::GetElement(qt3ds::runtime::IApplication &inApplication, + IPresentation *inDefaultPresentation, const char *inPath, + TElement *inStartElement) +{ + if (inPath == nullptr || *inPath == 0) + return nullptr; + const char *thePath(inPath); + const char *theSubPath = nullptr; + IPresentation *thePresentation = nullptr; + size_t thePathLength = ::strlen(thePath) + 1; + char *theToken = + Q3DStudio_allocate_desc(CHAR, thePathLength, "Token:TempPath"); // Temporary token storage + // Try to get the specified presentation + theSubPath = ::strchr(thePath, PRESENTATION_DELIMITER); + TElement *theElement = inStartElement; + if (theSubPath != nullptr) { + UINT32 theSubPathLength = static_cast(theSubPath - thePath); + + ::strncpy(theToken, thePath, theSubPathLength); + theToken[theSubPathLength] = '\0'; + + thePath = theSubPath + 1; + + const CHAR *thePresentationName = theToken; + + thePresentation = inApplication.GetPresentationById(thePresentationName); + } + if (thePresentation == nullptr) + thePresentation = inDefaultPresentation; + + // Return nil if the inStartElement is not in the specified presentation + if (theElement != nullptr + && (theSubPath == nullptr && theElement->GetBelongedPresentation() != thePresentation)) { + thePresentation = theElement->GetBelongedPresentation(); + } + + if (thePresentation == nullptr) + return nullptr; + + TStringHash theName; + INT32 theParseCounter = 0; + + while (thePath != nullptr && thePath[0] != '\0') { + ++theParseCounter; + + // Do some strtok() work here + theSubPath = ::strchr(thePath, NODE_DELIMITER); + if (theSubPath) { + UINT32 theSubPathLength = static_cast(theSubPath - thePath); + Q3DStudio_ASSERT(theSubPathLength < thePathLength); + + ::strncpy(theToken, thePath, theSubPathLength); + theToken[theSubPathLength] = '\0'; + + thePath = theSubPath + 1; + } else { + ::strcpy(theToken, thePath); + thePath = nullptr; + } + + // Hash the token and do some element searching + theName = CHash::HashString(theToken); + + if (theName == RESERVED_PARENT) { + if (theElement) + theElement = theElement->GetParent(); + } else if (theName == RESERVED_THIS) { + //Keep the original element if "this" wanted + } else { + if (theName == RESERVED_SCENE && theParseCounter == 1) + theElement = + thePresentation->GetRoot(); // theElement is nullptr, so using absolute path + + else if (theElement) + theElement = theElement->FindChild(theName); // Using relative path + } + + if (!theElement) + thePath = nullptr; + } // while + + Q3DStudio_free(theToken, CHAR, thePathLength); + return theElement; +} + +bool CQmlElementHelper::SetAttribute(TElement *theElement, const char *theAttName, + const void *value, bool inDelay) +{ + SAttributeKey theAttributeKey; + theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); + + // Early out for our single 'read only' attribute + if (ATTRIBUTE_URI == theAttributeKey.m_Hash) { + // we didn't push anything onto the stack + return false; + } + + // first search if it is a static property + Option thePropertyInfo = + theElement->FindProperty(theAttributeKey.m_Hash); + + if (!thePropertyInfo.hasValue()) { + // if not search in the dynamic properties + thePropertyInfo = theElement->FindDynamicProperty(theAttributeKey.m_Hash); + if (!thePropertyInfo.hasValue()) { + // create a new dynamic porperty + qt3ds::runtime::IElementAllocator &theElemAllocator( + theElement->GetBelongedPresentation()->GetApplication().GetElementAllocator()); + qt3ds::foundation::IStringTable &theStringTable( + theElement->GetBelongedPresentation()->GetStringTable()); + IRuntimeMetaData &theMetaData = + theElement->GetBelongedPresentation()->GetApplication().GetMetaData(); + thePropertyInfo = theElemAllocator.CreateDynamicProperty( + theMetaData, *theElement, theStringTable.RegisterStr(theAttName)); + } + } + + if (thePropertyInfo.hasValue()) { + UVariant theNewValue; + QString name(thePropertyInfo->first.m_Name.c_str()); + EAttributeType theAttributeType = thePropertyInfo->first.m_Type; + switch (theAttributeType) { + case ATTRIBUTETYPE_INT32: + case ATTRIBUTETYPE_HASH: + theNewValue.m_INT32 = *(INT32 *)value; + break; + + case ATTRIBUTETYPE_FLOAT: + theNewValue.m_FLOAT = *(FLOAT *)value; + if (name.startsWith(QLatin1String("rotation."))) + theNewValue.m_FLOAT = qDegreesToRadians(theNewValue.m_FLOAT); + break; + + case ATTRIBUTETYPE_BOOL: + theNewValue.m_INT32 = *(INT32 *)value; + break; + + case ATTRIBUTETYPE_STRING: + theNewValue.m_StringHandle = + theElement->GetBelongedPresentation()->GetStringTable().GetHandle( + (const char *)value); + break; + + case ATTRIBUTETYPE_POINTER: + qCCritical(INVALID_OPERATION, "setAttribute: pointer attributes not handled."); + return false; + break; + + case ATTRIBUTETYPE_ELEMENTREF: + qCCritical(INVALID_OPERATION, "setAttribute: ElementRef attributes are read only."); + return false; + break; + + case ATTRIBUTETYPE_FLOAT3: { + FLOAT *vec3 = (FLOAT *)value; + theNewValue.m_FLOAT3[0] = vec3[0]; + theNewValue.m_FLOAT3[1] = vec3[1]; + theNewValue.m_FLOAT3[2] = vec3[2]; + if (name == QLatin1String("rotation")) { + theNewValue.m_FLOAT3[0]= qDegreesToRadians(theNewValue.m_FLOAT3[0]); + theNewValue.m_FLOAT3[1]= qDegreesToRadians(theNewValue.m_FLOAT3[1]); + theNewValue.m_FLOAT3[2]= qDegreesToRadians(theNewValue.m_FLOAT3[2]); + } + } break; + + case ATTRIBUTETYPE_NONE: + case ATTRIBUTETYPE_DATADRIVEN_PARENT: + case ATTRIBUTETYPE_DATADRIVEN_CHILD: + case ATTRIBUTETYPECOUNT: + default: + qCCritical(INVALID_OPERATION, "setAttribute: Attribute has no type!"); + return false; + break; + } + + if (inDelay) { + UVariant arg1; + arg1.m_INT32 = theAttributeKey.m_Hash; + theElement->GetBelongedPresentation()->FireCommand( + COMMAND_SETPROPERTY, theElement, &arg1, &theNewValue, ATTRIBUTETYPE_HASH, + theAttributeType); + } else { + theElement->SetAttribute(*thePropertyInfo, theNewValue); + } + } else { + return false; + } + return true; +} + +bool CQmlElementHelper::GetAttribute(TElement *inElement, const char *inAttribute, void *value) +{ + SAttributeKey theAttributeKey; + theAttributeKey.m_Hash = CHash::HashAttribute(inAttribute); + + Option thePropertyInfo = + inElement->FindDynamicProperty(theAttributeKey.m_Hash); + + if (thePropertyInfo.hasValue()) { + UVariant *theValuePtr = thePropertyInfo->second; + EAttributeType theAttributeType = thePropertyInfo->first.m_Type; + switch (theAttributeType) { + case ATTRIBUTETYPE_INT32: + case ATTRIBUTETYPE_HASH: + *(INT32 *)value = theValuePtr->m_INT32; + break; + + case ATTRIBUTETYPE_FLOAT: + *(FLOAT *)value = theValuePtr->m_FLOAT; + break; + + case ATTRIBUTETYPE_BOOL: + *(INT32 *)value = (theValuePtr->m_INT32 != 0); + break; + + case ATTRIBUTETYPE_STRING: + *(char *)value = *inElement->GetBelongedPresentation() + ->GetStringTable() + .HandleToStr(theValuePtr->m_StringHandle) + .c_str(); + break; + + case ATTRIBUTETYPE_POINTER: + qCCritical(INVALID_OPERATION, "getAttribute: pointer attributes not handled."); + return false; + break; + + case ATTRIBUTETYPE_ELEMENTREF: + qCCritical(INVALID_OPERATION, "getAttribute: ElementRef attributes are read only."); + return false; + break; + + case ATTRIBUTETYPE_FLOAT3: { + FLOAT *vec3 = (FLOAT *)value; + vec3[0] = theValuePtr->m_FLOAT3[0]; + vec3[1] = theValuePtr->m_FLOAT3[1]; + vec3[2] = theValuePtr->m_FLOAT3[2]; + } break; + + case ATTRIBUTETYPE_NONE: + case ATTRIBUTETYPE_DATADRIVEN_PARENT: + case ATTRIBUTETYPE_DATADRIVEN_CHILD: + case ATTRIBUTETYPECOUNT: + default: + qCCritical(INVALID_OPERATION, "getAttribute: Attribute has no type!"); + return false; + break; + } + } else { + return false; + } + return true; +} diff --git a/src/Runtime/Source/runtime/Qt3DSQmlElementHelper.h b/src/Runtime/Source/runtime/Qt3DSQmlElementHelper.h new file mode 100644 index 00000000..ec36c8ed --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSQmlElementHelper.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_QML_ELEMENT_HELPER_H +#define QT3DS_QML_ELEMENT_HELPER_H + +#include "Qt3DSApplication.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSKernelTypes.h" + +namespace Q3DStudio { + +class CQmlElementHelper +{ +private: + CQmlElementHelper(); + virtual ~CQmlElementHelper(); + +public: + static TElement *GetElement(qt3ds::runtime::IApplication &inApplication, + IPresentation *inDefaultPresentation, const char *inPath, + TElement *inStartElement = NULL); + + static bool SetAttribute(TElement *inElement, const char *inAttribute, const void *value, + bool inDelay); + static bool GetAttribute(TElement *inElement, const char *inAttribute, void *value); +}; +} + +#endif // QT3DS_QML_ELEMENT_HELPER_H diff --git a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp new file mode 100644 index 00000000..1ba1a5a6 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp @@ -0,0 +1,1346 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSQmlEngine.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSInputEngine.h" +#include "Qt3DSSceneManager.h" +#include "Qt3DSVector3.h" +#include "Qt3DSColor.h" +#include "Qt3DSAttributeHashes.h" +#include "Qt3DSFileStream.h" +#include "Qt3DSDataLogger.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/FileTools.h" +#include "foundation/Qt3DSSystem.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSStateDebugger.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSSlideSystem.h" + +#include "EASTL/vector.h" +#include "EASTL/list.h" +#include +#include "Qt3DSCommandEventTypes.h" +#include "Qt3DSApplication.h" +#include "Qt3DSRuntimeFactory.h" +#include "Qt3DSStateDebugStreams.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "Qt3DSRenderThreadPool.h" +#include "Qt3DSRenderImageBatchLoader.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSAudioPlayer.h" +#include "Qt3DSActivationManager.h" +#include "Qt3DSParametersSystem.h" +#include "Qt3DSQmlElementHelper.h" +#include "q3dsqmlscript.h" + +#include +#include +#include +#include +#include +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +#if defined(_DEBUG) || (_PROFILE) +#define Q3DStudio_LOG_EVENT(S) // something +#else +#define Q3DStudio_LOG_EVENT(S) +#endif + +using qt3ds::runtime::IApplicationCore; +using qt3ds::runtime::IApplication; +using namespace qt3ds; + +namespace __SQmlEngineImpl_Basic_Structs__ { + struct QmlScopedLock + { + qt3ds::foundation::Mutex *m_Mutex; + + QmlScopedLock(qt3ds::foundation::Mutex *mtx) + : m_Mutex(mtx) + { + if (m_Mutex) + m_Mutex->lock(); + } + + ~QmlScopedLock() + { + if (m_Mutex) + m_Mutex->unlock(); + } + }; +} + +using namespace __SQmlEngineImpl_Basic_Structs__; +#define QML_ENGINE_MULTITHREAD_PROTECT_METHOD QmlScopedLock __locker(m_MultithreadedMutex); + +//============================================================================== +// Callback handling +/** +* Constructor +*/ +CScriptCallbacks::CScriptCallbacks() + : m_CallbackList(0, 0, "CallbackList") +{ +} + +/** +* Destructor +*/ +CScriptCallbacks::~CScriptCallbacks() +{ + FOR_ARRAY(SFrameCallbackEntry *, theEntry, m_CallbackList) + Q3DStudio_delete(*theEntry, SFrameCallbackEntry); + + m_CallbackList.Clear(); +} + +bool CScriptCallbacks::RegisterCallback(Q3DStudio::UINT32 callbackType, + const TScriptCallback inCallback, void *inUserData) +{ + // currently we only support these two types of callbacks + if (callbackType != SCRIPT_ON_INITIALIZE && callbackType != SCRIPT_ON_UPDATE) { + return false; + } + + SFrameCallbackEntry *theFrameCallbackEntry = NULL; + + try { + // note we don't care if someone registers the same function twice. + theFrameCallbackEntry = Q3DStudio_new(SFrameCallbackEntry) SFrameCallbackEntry(); + + if (!theFrameCallbackEntry) { + throw "failed to allocated SFrameCallbackEntry"; + } + + SScriptCallbackEntry *theScriptCallbackEntry = + Q3DStudio_new(SScriptCallbackEntry) SScriptCallbackEntry(); + if (!theScriptCallbackEntry) { + throw "failed to allocated SScriptCallbackEntry"; + } + + theScriptCallbackEntry->m_CallbackType = callbackType; + theScriptCallbackEntry->m_Function = inCallback; + theScriptCallbackEntry->m_UserData = inUserData; + theScriptCallbackEntry->m_Processed = false; + + theFrameCallbackEntry->m_Callbacks.Push(theScriptCallbackEntry); + + m_CallbackList.Push(theFrameCallbackEntry); + + } catch (const char *) { + if (theFrameCallbackEntry) + Q3DStudio_delete(theFrameCallbackEntry, SFrameCallbackEntry); + + return false; + } + + return true; +} + +void CScriptCallbacks::UnregisterCallback(Q3DStudio::UINT32, const TScriptCallback) +{ + // not used so far +} + +void CScriptCallbacks::ProcessCallbacks() +{ + // Call onInitialize function + FOR_ARRAY(SFrameCallbackEntry *, theFrameEntry, m_CallbackList) + { + FOR_ARRAY(SScriptCallbackEntry *, theEntry, (*theFrameEntry)->m_Callbacks) + { + if (((*theEntry)->m_CallbackType == SCRIPT_ON_INITIALIZE) && !(*theEntry)->m_Processed + && (*theEntry)->m_Function) { + (*theEntry)->m_Function((*theEntry)->m_UserData); + (*theEntry)->m_Processed = true; + } + } + } + + // Call onUpdate functions + FOR_ARRAY(SFrameCallbackEntry *, theFrameEntry, m_CallbackList) + { + FOR_ARRAY(SScriptCallbackEntry *, theEntry, (*theFrameEntry)->m_Callbacks) + { + // int type = (*theEntry)->m_CallbackType; + if ((*theEntry)->m_CallbackType == SCRIPT_ON_UPDATE && (*theEntry)->m_Function) { + (*theEntry)->m_Function((*theEntry)->m_UserData); + } + } + } +} + +//============================================================================== +//* End of helper class handling element operations +//============================================================================== + +//============================================================================== +/** +* Helper class handling command operations +*/ +class CQmlCommandHelper +{ + //============================================================================== + // Methods + //============================================================================== +private: // Constructors + CQmlCommandHelper(); + virtual ~CQmlCommandHelper(); + +public: // static Functions + static bool SetupGotoSlideCommand(TElement &inElement, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs); + static bool SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlideIndex, + const SScriptEngineGotoSlideArgs &inArgs); + +protected: // Static Hidden Helpers + // static TElement* FireCommand(TEventCommandHash inCommand); + +public: // Static Helpers + static TElement *GetComponentParent(TElement *inParent); +}; + +//============================================================================== +/** +* Constructor +*/ +CQmlCommandHelper::CQmlCommandHelper() +{ +} + +//============================================================================== +/** +* Destructor +*/ +CQmlCommandHelper::~CQmlCommandHelper() +{ +} + +static Option FindSlide(TElement &inElement, const char *slideName) +{ + IPresentation *thePresentation = inElement.GetBelongedPresentation(); + + int theSlideHashName = thePresentation->GetApplication().HashString(slideName); + TComponent *theComponent = thePresentation->GetComponentManager().GetComponent(&inElement); + UINT8 theSlideIndex = + thePresentation->GetSlideSystem().FindSlide(*theComponent, theSlideHashName); + if (theSlideIndex >= theComponent->GetSlideCount()) { + qt3ds::foundation::CRegisteredString elemPath = thePresentation->GetElementPath(inElement); + if (elemPath.IsValid()) { + qCCritical(qt3ds::INVALID_OPERATION) + << "QMLCommandHelper: goToSlide: Unable to find slide " + << slideName <<"on element " << elemPath.c_str(); + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "QMLCommandHelper: goToSlide: Unable to find slide " + << slideName; + } + return Empty(); + } + + return theSlideIndex; +} + +TElement *CQmlCommandHelper::GetComponentParent(TElement *inElement) +{ + Q3DStudio_ASSERT(inElement); + return &inElement->GetComponentParent(); +} + +bool CQmlCommandHelper::SetupGotoSlideCommand(TElement &inElement, Q3DStudio::INT32 inSlideIndex, + const SScriptEngineGotoSlideArgs &inArgs) +{ + IPresentation *thePresentation = inElement.GetBelongedPresentation(); + TElement *theTarget = GetComponentParent(&inElement); + SComponentGotoSlideData theSlideData(inSlideIndex); + theSlideData.m_Mode = inArgs.m_Mode; + theSlideData.m_Paused = inArgs.m_Paused; + theSlideData.m_Rate = inArgs.m_Rate; + theSlideData.m_Reverse = inArgs.m_Reverse; + theSlideData.m_StartTime = inArgs.m_StartTime; + // Resolve playthroughto if it has a valid value. + if (!isTrivial(inArgs.m_PlaythroughTo)) { + if (AreEqual(inArgs.m_PlaythroughTo, "next")) + theSlideData.m_PlaythroughTo = -1; + else if (AreEqual(inArgs.m_PlaythroughTo, "previous")) + theSlideData.m_PlaythroughTo = -2; + else { + // Find the slide if possible. If not, then just error leave things as they are. + + Option theSlideIndex = FindSlide(inElement, inArgs.m_PlaythroughTo); + if (theSlideIndex.hasValue()) + theSlideData.m_PlaythroughTo = *theSlideIndex; + } + } + thePresentation->GetComponentManager().SetupComponentGotoSlideCommand(theTarget, theSlideData); + UVariant theArg1; + UVariant theArg2; + qt3ds::intrinsics::memZero(&theArg1, sizeof(UVariant)); + qt3ds::intrinsics::memZero(&theArg2, sizeof(UVariant)); + thePresentation->FireCommand(COMMAND_GOTOSLIDE, theTarget, &theArg1, &theArg2); + return true; +} + +bool CQmlCommandHelper::SetupGotoSlideCommand(TElement &inElement, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs) +{ + Option theSlideIndex = FindSlide(inElement, slideName); + if (theSlideIndex.hasValue()) + return SetupGotoSlideCommand(inElement, *theSlideIndex, inArgs); + + return false; +} + +//============================================================================== +//* End of helper class handling command operations +//============================================================================== + +struct SEmitSignalData : public NVRefCounted +{ + NVAllocatorCallback &m_Alloc; + volatile QT3DSI32 mRefCount; + INT32 m_SignalNameHandler; ///< The name of the signal to emit + TElement *m_TargetElement; ///< The source element where the event is going to occur + + SEmitSignalData(NVAllocatorCallback &alloc, INT32 inSignalName, TElement *inElement) + : m_Alloc(alloc) + , mRefCount(0) + , m_SignalNameHandler(inSignalName) + , m_TargetElement(inElement) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc) +}; + +class CQmlEngineImpl : public CQmlEngine +{ + typedef NVScopedRefCounted TEmitSignalPtr; + typedef eastl::list TEmitSignalQueue; + + static const int MAX_ACTION_QUEUE_SIZE = 100; + +private: + qt3ds::NVFoundationBase &m_Foundation; + IApplication *m_Application; + IApplicationCore *m_ApplicationCore; + qt3ds::foundation::Mutex m_PreloadMutex; + qt3ds::foundation::Mutex *m_MultithreadedMutex; + + TEmitSignalQueue m_EmitSignalDataList; + + QT3DSI32 mRefCount; + + CScriptCallbacks m_ScriptCallbacks; + + QQmlEngine m_engine; + QMap m_components; + QVector m_scripts; + +public: + CQmlEngineImpl(NVFoundationBase &fnd, ITimeProvider &inTimeProvider); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + // functions from IScriptBridge + void EnableMultithreadedAccess() override; + void DisableMultithreadedAccess() override; + + void SetApplicationCore(qt3ds::runtime::IApplicationCore &inApplication) override; + void SetApplication(qt3ds::runtime::IApplication &inApplication) override; + qt3ds::runtime::IApplication *GetApplication() override; + void Initialize() override; + + void LoadScript(IPresentation *presentation, TElement *element, const CHAR *path) override; + Q3DStudio::INT32 InitializeApplicationBehavior(const char *) override + { + return -1; + } + + void ProcessFrameCallbacks(IPresentation *) override; + void ExecuteApplicationScriptFunction(Q3DStudio::INT32, const char *) override {} + void CallFunction(const char *, const char *, + CScriptEngineCallFunctionArgRetriever &) override {} + + void ProcessSignal(IPresentation *inPresentation, + const SEventCommand &inCommand) override; + void ProcessCustomActions(IPresentation *inPresentation, + const SEventCommand &inCommand) override; + void ProcessCustomCallback(IPresentation *, const SEventCommand &) override {} + + void SetTableForElement(TElement &, IScriptTableProvider &) override {} + void SetAttribute(const char *element, const char *attName, const char *value) override; + bool GetAttribute(const char *element, const char *attName, char *value) override; + void FireEvent(const char *element, const char *evtName) override; + void SetDataInputValue(const QString &name, const QVariant &value) override; + + void GotoSlide(const char *component, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs) override; + void GotoSlideRelative(const char *, bool, bool, const SScriptEngineGotoSlideArgs &) override; + + void SetPresentationAttribute(const char *, const char *, const char *) override; + + // No need to implement here, as sound playing is done in Qt3DSViewerApp + bool PlaySoundFile(const char *) override { return false; } + + void EnableDebugging(qt3ds::state::debugger::IMultiProtocolSocket &) override {} + void EnableProfiling() override {} + void StepGC() override {} + + // functions from CQMLEngine + bool PeekSignal(TElement *&outElement, char *&outName) override; + void GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex, + const SScriptEngineGotoSlideArgs &inArgs) override; + bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) override; + void GotoTime(const char *component, const Q3DStudio::FLOAT time) override; + bool RegisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback, + void *inUserData) override; + void Shutdown(qt3ds::NVFoundationBase &inFoundation) override; + +private: + void createComponent(QQmlComponent *component, TElement *element); + TElement *getTarget(const char *component); + void listAllElements(TElement *root, QList &elements); + void initializeDataInputsInPresentation(CPresentation &presentation, bool isPrimary); + // Splits down vector attributes to components as Runtime does not really + // handle vectors at this level anymore + bool getAttributeVector3(QVector &outAttVec, const QByteArray &attName, + TElement *elem); + bool getAttributeVector2(QVector &outAttVec, const QByteArray &attName, + TElement *elem); + // build and evaluate Evaluator datainput type expression + QJSValue buildJSFunc(const QString &userFunc); + // pass controller name for error reporting purposes + QVariant callJSFunc(const QString &controllerName, qt3ds::runtime::DataInputDef &diDef, + const QVariant::Type type); + // matches all numeric datatypes so we do not get datatype mismatch when JS + // decides to change result datatype (f.ex from double to int when result + // fractional part for specific input values happens to be exactly zero) + bool isMatchingDatatype(QVariant::Type resultType, QVariant::Type propertyType); + // find out which datainputs are used in the expression + QVector resolveDependentDatainputs(const QString &expression, + const QString &controllerName); +}; + +CQmlEngineImpl::CQmlEngineImpl(NVFoundationBase &fnd, ITimeProvider &) + : m_Foundation(fnd) + , m_Application(NULL) + , m_ApplicationCore(NULL) + , m_PreloadMutex(fnd.getAllocator()) + , m_MultithreadedMutex(NULL) + , m_EmitSignalDataList( + ForwardingAllocator(fnd.getAllocator(), "CQmlEngineImpl::m_EmitSignalDataList")) + , mRefCount(0) +{ + qmlRegisterType("QtStudio3D.Behavior", 1, 0, "Behavior"); + qmlRegisterType("QtStudio3D.Behavior", 1, 1, "Behavior"); +} + +void CQmlEngineImpl::Shutdown(qt3ds::NVFoundationBase &inFoundation) +{ +} + +void CQmlEngineImpl::EnableMultithreadedAccess() +{ + m_MultithreadedMutex = &m_PreloadMutex; +} + +void CQmlEngineImpl::DisableMultithreadedAccess() +{ + m_MultithreadedMutex = NULL; +} + +void CQmlEngineImpl::SetApplicationCore(qt3ds::runtime::IApplicationCore &inApplication) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + m_ApplicationCore = &inApplication; +} + +void CQmlEngineImpl::SetApplication(qt3ds::runtime::IApplication &inApplication) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + m_Application = &inApplication; +} + +qt3ds::runtime::IApplication *CQmlEngineImpl::GetApplication() +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + return m_Application; +} + +void CQmlEngineImpl::Initialize() +{ + // Gather data input controlled properties + QList presentations = m_Application->GetPresentationList(); + + for (int i = 0; i < presentations.size(); ++i) + initializeDataInputsInPresentation(*presentations[i], i == 0); +} + +void CQmlEngineImpl::SetAttribute(const char *element, const char *attName, const char *value) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + + TElement *theTarget = getTarget(element); + if (theTarget) { + bool success = CQmlElementHelper::SetAttribute(theTarget, attName, value, false); + if (!success) { + qCCritical(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::SetAttribute: " + << "failed to set attribute on element" + << element << ":" << attName << ":" << value; + } + } +} + +bool CQmlEngineImpl::GetAttribute(const char *element, const char *attName, char *value) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + + TElement *theTarget = getTarget(element); + if (theTarget) { + bool success = CQmlElementHelper::GetAttribute(theTarget, attName, value); + if (!success) { + qCCritical(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::SetAttribute: " + << "failed to set attribute on element" + << element << ":" << attName << ":" << value; + } + return success; + } + + return false; +} + +void CQmlEngineImpl::LoadScript(IPresentation *presentation, TElement *element, const CHAR *path) +{ + QString presPath = QFileInfo(presentation->GetFilePath()).absolutePath(); + + QString sourcePath(presPath + QLatin1Char('/') + path); + sourcePath.replace(QLatin1Char('\\'), QLatin1Char('/')); + + TElement *parent = element->GetParent(); + if (!parent) + return; + + if (!m_components.contains(sourcePath)) { + m_components[sourcePath] = new QQmlComponent(&m_engine, QUrl::fromLocalFile(sourcePath), + &m_engine); + } + + QQmlComponent *component = m_components[sourcePath]; + if (component->status() == QQmlComponent::Ready) { + createComponent(component, element); + } else if (component->status() == QQmlComponent::Error) { + qWarning() << "Error while loading script" + << component->url().toString() + << ":" << component->errorString(); + } else { + QObject::connect(component, &QQmlComponent::statusChanged, + [this, component, element] (QQmlComponent::Status status) { + if (status == QQmlComponent::Ready) { + createComponent(component, element); + } else { + qWarning() << "Error while loading script" + << component->url().toString() + << ":" << component->errorString(); + } + } + ); + } +} + +void CQmlEngineImpl::FireEvent(const char *element, const char *evtName) +{ + TElement *theElement = getTarget(element); + if (theElement && theElement->GetActive() == true) { + IPresentation *thePresentation = theElement->GetBelongedPresentation(); + thePresentation->FireEvent(CHash::HashEventCommand(evtName), theElement); + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::FireEvent: " + << "failed to find element: " + << element << " " << evtName; + } +} + +void CQmlEngineImpl::SetDataInputValue(const QString &name, const QVariant &value) +{ + qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); + if (diMap.contains(name)) { + qt3ds::runtime::DataInputDef &diDef = diMap[name]; + diDef.value = value; + const QVector &ctrlAtt + = diDef.controlledAttributes; + for (const qt3ds::runtime::DataInputControlledAttribute &ctrlElem : ctrlAtt) { + switch (ctrlElem.propertyType) { + case ATTRIBUTETYPE_DATAINPUT_TIMELINE: { + // Quietly ignore other than number type data inputs when adjusting timeline + if (diDef.type == qt3ds::runtime::DataInputTypeRangedNumber) { + TTimeUnit endTime = 0; + TElement *element = getTarget(ctrlElem.elementPath.constData()); + TComponent *component = static_cast(element); + endTime = component->GetTimePolicy().GetLoopingDuration(); + + // Normalize the value to dataInput range + qreal newTime = qreal(endTime) * (qreal(value.toFloat() - diDef.min) + / qreal(diDef.max - diDef.min)); + GotoTime(ctrlElem.elementPath.constData(), float(newTime / 1000.0)); + } + break; + } + case ATTRIBUTETYPE_DATAINPUT_SLIDE: { + // Quietly ignore other than string type when adjusting slide + if (diDef.type == qt3ds::runtime::DataInputTypeString) { + const QByteArray valueStr = value.toString().toUtf8(); + GotoSlide(ctrlElem.elementPath.constData(), valueStr.constData(), + SScriptEngineGotoSlideArgs()); + } + break; + } + // Silently ignore invalid incoming type if it does not + // match with the datainput type except with type Variant, for which + // the incoming value is cast to target property type without checking. + // Caveat emptor. + + // For Evaluator, typecheck the JS evaluation result to see if it + // matches with the target property. + + // Handle ranged number similarly to generic float + // if it is bound to properties other + // than timeline animation i.e. disregard range min and max + + case ATTRIBUTETYPE_FLOAT: { + float valueFloat; + if (diDef.type == qt3ds::runtime::DataInputTypeFloat + || diDef.type == qt3ds::runtime::DataInputTypeRangedNumber + || diDef.type == qt3ds::runtime::DataInputTypeVariant) { + valueFloat = value.toFloat(); + } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { + valueFloat = callJSFunc(name, diDef, QVariant::Type::Double).toFloat(); + } else { + qWarning() << __FUNCTION__ << "Property type " + << ctrlElem.propertyType + << " not matching with Datainput " << name + << " data type " + << diDef.type; + break; + } + + SetAttribute(ctrlElem.elementPath.constData(), + ctrlElem.attributeName.first().constData(), + reinterpret_cast(&valueFloat)); + break; + } + case ATTRIBUTETYPE_FLOAT3: { + QVector3D valueVec; + if (diDef.type == qt3ds::runtime::DataInputTypeVector3 + || diDef.type == qt3ds::runtime::DataInputTypeVariant) { + valueVec = value.value(); + } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { + const QVariant res = callJSFunc(name, diDef, QVariant::Type::Vector3D); + valueVec = res.value(); + } else { + qWarning() << __FUNCTION__ << "Property type " + << ctrlElem.propertyType + << " not matching with Datainput " << name + << " data type " + << diDef.type; + break; + } + // Set the values of vector attribute components separately + for (int i = 0; i < 3; i++) { + const float val = valueVec[i]; + SetAttribute(ctrlElem.elementPath.constData(), + ctrlElem.attributeName[i].constData(), + reinterpret_cast(&val)); + } + break; + } + case ATTRIBUTETYPE_FLOAT2: + { + QVector2D valueVec; + if (diDef.type == qt3ds::runtime::DataInputTypeVector2 + || diDef.type == qt3ds::runtime::DataInputTypeVariant) { + valueVec = value.value(); + } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { + const QVariant res = callJSFunc(name, diDef, QVariant::Type::Vector2D); + valueVec = res.value(); + } else { + qWarning() << __FUNCTION__ << "Property type " + << ctrlElem.propertyType + << " not matching with Datainput " << name + << " data type " + << diDef.type; + break; + } + // Set the values of vector attribute components separately + for (int i = 0; i < 2; i++) { + const float val = valueVec[i]; + SetAttribute(ctrlElem.elementPath.constData(), + ctrlElem.attributeName[i].constData(), + reinterpret_cast(&val)); + } + break; + } + case ATTRIBUTETYPE_BOOL: { + bool valueBool; + if (diDef.type == qt3ds::runtime::DataInputTypeBoolean + || diDef.type == qt3ds::runtime::DataInputTypeVariant) { + valueBool = value.toBool(); + } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { + valueBool = callJSFunc(name, diDef, QVariant::Type::Bool).toBool(); + } else { + qWarning() << __FUNCTION__ << "Property type " + << ctrlElem.propertyType + << " not matching with Datainput " << name + << " data type " + << diDef.type; + break; + } + + SetAttribute(ctrlElem.elementPath.constData(), + ctrlElem.attributeName.first().constData(), + reinterpret_cast(&valueBool)); + break; + } + case ATTRIBUTETYPE_STRING: { + QByteArray valueStr; + // Allow scalar number types also as inputs to string attribute + if (diDef.type == qt3ds::runtime::DataInputTypeString + || diDef.type == qt3ds::runtime::DataInputTypeRangedNumber + || diDef.type == qt3ds::runtime::DataInputTypeFloat + || diDef.type == qt3ds::runtime::DataInputTypeVariant) { + valueStr = value.toString().toUtf8(); + } else if (diDef.type == qt3ds::runtime::DataInputTypeEvaluator) { + valueStr = callJSFunc(name, diDef, QVariant::Type::String) + .toString().toUtf8(); + } else { + qWarning() << __FUNCTION__ << "Property type " + << ctrlElem.propertyType + << " not matching with Datainput " << name + << " data type " + << diDef.type; + break; + } + + SetAttribute(ctrlElem.elementPath.constData(), + ctrlElem.attributeName.first().constData(), + valueStr.constData()); + break; + } + default: + QT3DS_ALWAYS_ASSERT_MESSAGE("Unexpected data input type"); + break; + } + } + + // Trigger re-evaluation of Evaluator datainputs that use this datainput + // as source data. Do this by calling setDataInputValue for evaluator + // with the current set value of the Evaluator (_not_ the evaluator result) + for (auto dependent : diDef.dependents) { + // Dependent list also contains the name of this datainput if + // the value of this datainput is used as source data. In this case + // obviously do not cause infinite recursion. + if (dependent != name) + SetDataInputValue(dependent, diMap[dependent].value); + } + } +} + +void CQmlEngineImpl::GotoSlide(const char *component, const char *slideName, + const SScriptEngineGotoSlideArgs &inArgs) +{ + TElement *theTarget = getTarget(component); + if (theTarget) { + CQmlCommandHelper::SetupGotoSlideCommand(*theTarget, slideName, inArgs); + } else { + qCWarning(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::GotoSlide: Unable to find component " << component; + } +} + +void CQmlEngineImpl::GotoSlideRelative(const char *component, bool inNextSlide, bool inWrap, + const SScriptEngineGotoSlideArgs &inArgs) +{ + TElement *theTarget = getTarget(component); + if (theTarget) { + theTarget = &theTarget->GetComponentParent(); + if (theTarget && theTarget->GetActive()) { + TComponent *theComponent = static_cast(theTarget); + Q3DStudio::INT32 theSlide = theComponent->GetCurrentSlide(); + Q3DStudio::INT32 theSlideCount = theComponent->GetSlideCount(); + theSlide = inNextSlide ? theSlide + 1 : theSlide - 1; + if (theSlide < 1) { + if (inWrap) + theSlide = theSlideCount - 1; + else + theSlide = 1; + } else if (theSlide == theSlideCount) { + if (inWrap) + theSlide = 1; + else + theSlide = theSlideCount - 1; + } + if (theSlide != theComponent->GetCurrentSlide()) { + CQmlCommandHelper::SetupGotoSlideCommand(*theTarget, theSlide, inArgs); + } + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "QmlEngine::GotoSlideRelative: Component is not active: " << component; + } + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "QmlEngine::GotoSlideRelative: failed to find component: " << component; + } +} + +void CQmlEngineImpl::SetPresentationAttribute(const char *presId, const char *, const char *value) +{ + if (isTrivial(presId)) + return; + if (presId[0] == '#') + ++presId; + CPresentation *thePresentation = m_Application->GetPresentationById(presId); + if (thePresentation) { + bool active = AreEqualCaseless(nonNull(value), "True"); + thePresentation->SetActive(active); + } +} + +void CQmlEngineImpl::GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex, + const SScriptEngineGotoSlideArgs &inArgs) +{ + TElement *theTarget = getTarget(component); + if (theTarget) { + CQmlCommandHelper::SetupGotoSlideCommand(*theTarget, slideIndex, inArgs); + } else { + qCWarning(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::GotoSlide: Unable to find component " << component; + } +} + +bool CQmlEngineImpl::GetSlideInfo(const char *element, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + + TElement *theTarget = getTarget(element); + if (theTarget && theTarget->IsComponent()) { + IPresentation *thePresentation = theTarget->GetBelongedPresentation(); + TComponent *theComponent = thePresentation->GetComponentManager().GetComponent(theTarget); + currentIndex = int(theComponent->GetCurrentSlide()); + previousIndex = int(theComponent->GetPreviousSlide()); + if (currentIndex > 0) { + currentName = QString::fromLocal8Bit( + thePresentation->GetSlideSystem().GetSlideName( + qt3ds::runtime::SSlideKey(*theComponent, QT3DSU32(currentIndex)))); + } else { + currentName.clear(); + } + if (previousIndex > 0) { + previousName = QString::fromLocal8Bit( + thePresentation->GetSlideSystem().GetSlideName( + qt3ds::runtime::SSlideKey(*theComponent, QT3DSU32(previousIndex)))); + } else { + previousName.clear(); + } + return true; + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::GetSlideInfo: Supplied element is not a component " << element; + } + return false; +} + +void CQmlEngineImpl::GotoTime(const char *component, const Q3DStudio::FLOAT time) +{ + TElement *theTarget = getTarget(component); + if (theTarget && theTarget->GetActive()) { + UVariant theArg1; + UVariant theArg2; + + IPresentation *thePresentation = theTarget->GetBelongedPresentation(); + + theArg1.m_INT32 = static_cast(time * 1000); + + TElement *theParentTarget = &theTarget->GetComponentParent(); + + thePresentation->FireCommand(COMMAND_GOTOTIME, theParentTarget, &theArg1, &theArg2); + } +} + +bool CQmlEngineImpl::RegisterCallback(Q3DStudio::UINT32 callbackType, + const TScriptCallback inCallback, void *inUserData) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + return m_ScriptCallbacks.RegisterCallback(callbackType, inCallback, inUserData); +} + +void CQmlEngineImpl::ProcessFrameCallbacks(IPresentation *) +{ + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + m_ScriptCallbacks.ProcessCallbacks(); + + for (Q3DSQmlScript *script : m_scripts) + script->update(); +} + +void CQmlEngineImpl::ProcessSignal(IPresentation *inPresentation, + const SEventCommand &inCommand) +{ + using qt3ds::runtime::TIdValuePair; + QML_ENGINE_MULTITHREAD_PROTECT_METHOD; + TElement *theElement = inCommand.m_Target; // the element that is a behavior + + CPresentation *thePresentation = (CPresentation *)inPresentation; + // IParametersSystem& theParametersManager = thePresentation->GetParametersSystem(); + qt3ds::foundation::IStringTable &theStrTable(thePresentation->GetStringTable()); + + CRegisteredString theSignal = theStrTable.HandleToStr(inCommand.m_Arg1.m_INT32); + + if (!theSignal.IsValid() || m_EmitSignalDataList.size() > CQmlEngineImpl::MAX_ACTION_QUEUE_SIZE) + return; + + TEmitSignalPtr theTemp = QT3DS_NEW(m_Foundation.getAllocator(), SEmitSignalData)( + m_Foundation.getAllocator(), inCommand.m_Arg1.m_INT32, theElement); + m_EmitSignalDataList.push_back(theTemp); +} + + +//============================================================================== +/** +* Handle custom actions +* @param inCommand carrier of command and parameter information +*/ +void CQmlEngineImpl::ProcessCustomActions(IPresentation *presentation, + const SEventCommand &command) +{ + TElement *element = command.m_Target; + for (Q3DSQmlScript *script : m_scripts) { + if (script->hasBehavior(element)) { + IParametersSystem ¶metersManager + = static_cast(presentation)->GetParametersSystem(); + INT32 groupId = command.m_Arg1.m_INT32; + UINT32 numParams = parametersManager.GetNumParameters(groupId); + if (numParams == 0) { + QT3DS_ASSERT(false); + return; + } + + qt3ds::runtime::TIdValuePair tempData = parametersManager.GetParameter(groupId, 0); + if (tempData.first != CHash::HashString("string")) { + QT3DS_ASSERT(false); + return; + } + + CRegisteredString functionName = presentation->GetStringTable().HandleToStr( + tempData.second.m_StringHandle); + script->call(functionName.c_str()); + return; + } + } +} + +bool CQmlEngineImpl::PeekSignal(TElement *&outElement, char *&outName) +{ + if (m_EmitSignalDataList.empty()) + return false; + + NVScopedRefCounted theAction = m_EmitSignalDataList.front(); + m_EmitSignalDataList.pop_front(); + + outElement = theAction->m_TargetElement; + if (outElement) { + IPresentation *thePresentation = outElement->GetBelongedPresentation(); + qt3ds::foundation::IStringTable &theStrTable(thePresentation->GetStringTable()); + CRegisteredString theSignal = theStrTable.HandleToStr(theAction->m_SignalNameHandler); + outName = (char *)theSignal.c_str(); + } else { + qCWarning(qt3ds::INVALID_OPERATION) + << "CQmlEngineImpl::PeekCustomAction: Unable to find element: EmitSignal queue error"; + outName = NULL; + } + + return true; +} + +void CQmlEngineImpl::createComponent(QQmlComponent *component, TElement *element) +{ + TElement *parent = element->GetParent(); + if (!parent) + return; + + QQmlContext *context = new QQmlContext(&m_engine, &m_engine); + QObject *obj = component->beginCreate(context); + if (!obj) { + context->deleteLater(); + return; + } + Q3DSQmlBehavior *behaviorObject = qobject_cast(obj); + if (behaviorObject == nullptr) { + obj->deleteLater(); + context->deleteLater(); + return; + } + + auto script = new Q3DSQmlScript(*this, *behaviorObject, *element, *parent); + component->completeCreate(); + behaviorObject->setScript(script); + + script->setParent(component); + obj->setParent(script); + m_scripts.push_back(script); +} + +TElement *CQmlEngineImpl::getTarget(const char *component) { + TElement *target = NULL; + QStringList split = QString(component).split(":"); + if (split.size() > 1) { + target = CQmlElementHelper::GetElement( + *m_Application, + m_Application->GetPresentationById(split.at(0).toStdString().c_str()), + split.at(1).toStdString().c_str(), NULL); + } else { + target = CQmlElementHelper::GetElement( + *m_Application, + m_Application->GetPrimaryPresentation(), + split.at(0).toStdString().c_str(), NULL); + } + return target; +} + +void CQmlEngineImpl::listAllElements(TElement *root, QList &elements) +{ + elements.append(root); + TElement *nextChild = root->GetChild(); + while (nextChild) { + listAllElements(nextChild, elements); + nextChild = nextChild->GetSibling(); + } +} + +void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentation, + bool isPrimary) +{ + TElement *parent = presentation.GetRoot(); + QList elements; + listAllElements(parent, elements); + qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); + qt3ds::foundation::IStringTable &strTable(presentation.GetStringTable()); + + for (TElement *element : qAsConst(elements)) { + Option ctrlIndex = element->FindPropertyIndex(ATTRIBUTE_CONTROLLEDPROPERTY); + if (ctrlIndex.hasValue()) { + Option propertyInfo = + element->GetPropertyByIndex(*ctrlIndex); + UVariant *valuePtr = propertyInfo->second; + QString valueStr = + QString::fromUtf8(strTable.HandleToStr(valuePtr->m_StringHandle)); + if (!valueStr.isEmpty()) { + QStringList splitValues = valueStr.split(QChar(' ')); + for (int i = 1; i < splitValues.size(); i += 2) { + QString controllerName = splitValues[i - 1]; + // remove datainput name prefix "$" + controllerName.remove(0, 1); + if (diMap.contains(controllerName)) { + qt3ds::runtime::DataInputControlledAttribute ctrlElem; + if (!isPrimary) { + // Prepend presentation id to element path + ctrlElem.elementPath = presentation.GetName(); + ctrlElem.elementPath.append(QByteArrayLiteral(":")); + } + ctrlElem.attributeName.append(splitValues[i].toUtf8()); + if (ctrlElem.attributeName.first() == QByteArrayLiteral("@timeline")) { + ctrlElem.propertyType = ATTRIBUTETYPE_DATAINPUT_TIMELINE; + TElement *component = &element->GetComponentParent(); + ctrlElem.elementPath.append(component->m_Path); + } else if (ctrlElem.attributeName.first() == QByteArrayLiteral("@slide")) { + ctrlElem.propertyType = ATTRIBUTETYPE_DATAINPUT_SLIDE; + TElement *component = &element->GetComponentParent(); + ctrlElem.elementPath.append(component->m_Path); + } else if (diMap[controllerName].type + == qt3ds::runtime::DataInputTypeVector3) { + // special handling for vector datatype to handle + // expansion from to .x .y .z + QVector attVec; + bool success = getAttributeVector3( + attVec, ctrlElem.attributeName.first().constData(), + element); + if (!attVec.empty() && success) { + ctrlElem.attributeName = attVec; + ctrlElem.elementPath.append(element->m_Path); + ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT3; + } else { + qWarning() << __FUNCTION__ << "Property " + << ctrlElem.attributeName.first() + << " was not expanded to vector"; + ctrlElem.propertyType = ATTRIBUTETYPE_NONE; + } + } else if (diMap[controllerName].type + == qt3ds::runtime::DataInputTypeVector2) { + // special handling for vector datatype to handle + // expansion from to .x .y + QVector attVec; + bool success = getAttributeVector2( + attVec, ctrlElem.attributeName.first().constData(), + element); + if (!attVec.empty() && success) { + ctrlElem.attributeName = attVec; + ctrlElem.elementPath.append(element->m_Path); + ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT2; + } else { + qWarning() << __FUNCTION__ << "Property " + << ctrlElem.attributeName.first() + << " was not expanded to vector"; + ctrlElem.propertyType = ATTRIBUTETYPE_NONE; + } + } else if (diMap[controllerName].type + == qt3ds::runtime::DataInputTypeEvaluator) { + diMap[controllerName].evalFunc + = buildJSFunc(diMap[controllerName].evaluator); + auto referencedDIs = resolveDependentDatainputs( + diMap[controllerName].evaluator, controllerName); + // add this evaluator datainput to the dependent list + // for those datainputs that are used in the expression + // for this evaluator + for (auto ref : referencedDIs) + diMap[ref].dependents.append(controllerName); + + ctrlElem.elementPath.append(element->m_Path); + TStringHash attHash = CHash::HashAttribute( + ctrlElem.attributeName.first().constData()); + Option attInfo + = element->FindProperty(attHash); + if (attInfo.hasValue()) + ctrlElem.propertyType = attInfo->first.m_Type; + } else { + // all other scalar datatypes + ctrlElem.elementPath.append(element->m_Path); + TStringHash attHash = CHash::HashAttribute( + ctrlElem.attributeName.first().constData()); + Option attInfo + = element->FindProperty(attHash); + if (attInfo.hasValue()) { + ctrlElem.propertyType = attInfo->first.m_Type; + } else { + ctrlElem.propertyType = ATTRIBUTETYPE_NONE; + qWarning() << __FUNCTION__ << "Property " + << ctrlElem.attributeName.first() << " not existing!"; + } + } + qt3ds::runtime::DataInputDef &diDef = diMap[controllerName]; + diDef.controlledAttributes.append(ctrlElem); + } + } + } + } + } +} + +// Bit clumsy way of getting from "position" to "position .x .y .z" and enabling datainput +// support for vectorized types. UIP parser has already thrown away all vector +// type attributes and at this point we are operating with scalar components only. +// We check if this element has a property attName.x or attName.r to find out it +// we should expand property attName to XYZ or RGB vector +bool CQmlEngineImpl::getAttributeVector3(QVector &outAttVec, + const QByteArray &attName, + TElement *elem) +{ + auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); + + if (!elem->FindProperty(hashName).isEmpty()) { + outAttVec.append(attName + ".x"); + outAttVec.append(attName + ".y"); + outAttVec.append(attName + ".z"); + return true; + } + hashName = Q3DStudio::CHash::HashAttribute(attName + ".r"); + if (!elem->FindProperty(hashName).isEmpty()) { + outAttVec.append(attName + ".r"); + outAttVec.append(attName + ".g"); + outAttVec.append(attName + ".b"); + return true; + } + return false; +} + +bool CQmlEngineImpl::getAttributeVector2(QVector &outAttVec, + const QByteArray &attName, + TElement *elem) +{ + auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); + + if (!elem->FindProperty(hashName).isEmpty()) { + outAttVec.append(attName + ".x"); + outAttVec.append(attName + ".y"); + return true; + } + + hashName = Q3DStudio::CHash::HashAttribute(attName + ".u"); + if (!elem->FindProperty(hashName).isEmpty()) { + outAttVec.append(attName + ".u"); + outAttVec.append(attName + ".v"); + return true; + } + return false; +} + +QJSValue CQmlEngineImpl::buildJSFunc(const QString &userFunc) +{ + auto res = this->m_engine.evaluate(userFunc); + if (res.isError()) { + qWarning() << __FUNCTION__ + << "Uncaught exception during datainput evaluation. Evaluator function" << userFunc; + } + return res; +} + +QVariant CQmlEngineImpl::callJSFunc(const QString &controllerName, + qt3ds::runtime::DataInputDef &diDef, + const QVariant::Type type) +{ + qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); + QJSValueList args; + QVector sourceDIs = resolveDependentDatainputs(diDef.evaluator, controllerName); + + // get the most recent set values for datainput sources (arguments) in the expression + for (auto diVal : sourceDIs) + args << this->m_engine.toScriptValue(diMap[diVal].value); + + if (diDef.evalFunc.isCallable()) { + QJSValue res = diDef.evalFunc.call(args); + if (res.isError()) { + qWarning() << __FUNCTION__ << "Error during datainput" << controllerName + << "evaluator call:" << res.toString() << "\nEvaluator function" + << diDef.evaluator; + return QVariant::Invalid; + } + + QVariant ret = res.toVariant(); + if (ret.isValid() && isMatchingDatatype(ret.type(), type)) { + // further check if the result is valid number + if (ret.type() == QVariant::Double && qIsNaN(res.toNumber())) { + qWarning() << __FUNCTION__ << "Datainput" << controllerName << "evaluator" + << "result not a number (NaN)." + << "\nEvaluator function" << diDef.evaluator; + return QVariant::Invalid; + } else { + return ret; + } + } else { + qWarning() << __FUNCTION__ << "Datainput" << controllerName << "evaluator" + << "result not valid or matching with target attribute type. Result type" + << QVariant::typeToName(ret.type()) << " target attribute type " + << QVariant::typeToName(type) << "\nEvaluator function" << diDef.evaluator; + } + } else { + qWarning() << __FUNCTION__ << "Datainput" << controllerName << "evaluator" + << diDef.evaluator << " not valid callable"; + } + return QVariant::Invalid; +} + +bool CQmlEngineImpl::isMatchingDatatype(QVariant::Type resultType, QVariant::Type propertyType) +{ + if (resultType == propertyType) + return true; + // Allow binding from numeric datainput to string target + if ((resultType == QVariant::Double || resultType == QVariant::Int + || resultType == QVariant::LongLong) + && (propertyType == QVariant::Double || propertyType == QVariant::Int + || propertyType == QVariant::LongLong || propertyType == QVariant::String)) { + return true; + } + return false; +} + +QVector CQmlEngineImpl::resolveDependentDatainputs(const QString &expression, + const QString &controllerName) +{ + QVector ret; + qt3ds::runtime::DataInputMap &diMap = m_Application->dataInputMap(); + if (!expression.contains("function", Qt::CaseInsensitive)) { + qWarning() << __FUNCTION__ << "Function keyword not found in datainput" + << controllerName << "evaluator"; + return QVector(); + } + + int argListStart = expression.indexOf("function(") + 9; + int argListStop = expression.indexOf(')', argListStart); + QString argstr = expression.mid(argListStart , argListStop - argListStart); + QStringList args = argstr.split(','); + + for (auto di : args) { + auto diTrim = di.trimmed(); + if (diMap.contains(diTrim)) { + if (diMap[diTrim].type == qt3ds::runtime::DataInputTypeEvaluator + && diTrim != controllerName) { + qWarning() << __FUNCTION__ << "Invalid evaluator function in" << controllerName + << ". Another evaluator is used as source data."; + } else { + ret.append(diTrim); + } + } else { + qWarning() << __FUNCTION__ << "Evaluator in" << controllerName << "evaluator" + << "is using unknown datainput" << diTrim << " as input argument name"; + } + } + return ret; +} + +/** +* @brief Create QML engine +* +* @param[in] inFoundation Pointer to foundation +* @param[in] inTimeProvider Pointer to time provider +* +* @return no return +*/ +CQmlEngine *CQmlEngine::Create(qt3ds::NVFoundationBase &inFoundation, ITimeProvider &inTimeProvider) +{ + return QT3DS_NEW(inFoundation.getAllocator(), CQmlEngineImpl)(inFoundation, inTimeProvider); +} +} diff --git a/src/Runtime/Source/runtime/Qt3DSQmlEngine.h b/src/Runtime/Source/runtime/Qt3DSQmlEngine.h new file mode 100644 index 00000000..71ef1b3f --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSQmlEngine.h @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 1993-20016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_QML_ENGINE_H +#define QT3DS_QML_ENGINE_H + +#include "Qt3DSIScriptBridge.h" +#include "Qt3DSIComponentManager.h" +#include "EASTL/vector.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSMutex.h" +#include "Qt3DSTimer.h" + +//============================================================================== +// Namespace +//============================================================================== + +namespace Q3DStudio { +//============================================================================== +// Typedefs +//============================================================================== +typedef void (*TScriptCallback)(void *inUserData); + +//============================================================================== +// Defines +//============================================================================== +#define SCRIPT_ON_INITIALIZE 1 +#define SCRIPT_ON_UPDATE 2 + +//============================================================================== +// Forwards +//============================================================================== +struct SEventCommand; +class IPresentation; + +//============================================================================== +/** +* Manages the various events callbacks in the system. It fires the +* registered callbacks when an event was triggered. +*/ +class CScriptCallbacks +{ + //============================================================================== + // Structs + //============================================================================== +protected: + struct SScriptCallbackEntry + { + SScriptCallbackEntry() {} + ~SScriptCallbackEntry() {} + + TScriptCallback m_Function; ///< Callback function pointer + void *m_UserData; ///< User data + Q3DStudio::UINT32 + m_CallbackType; ///< callback type. determines when and/or how often it is called + bool m_Processed; ///< Only used if the callback is of + + private: // Disabled Copy Construction + SScriptCallbackEntry(const SScriptCallbackEntry &); + SScriptCallbackEntry &operator=(const SScriptCallbackEntry &); + }; + typedef CArray TCallbackList; ///< Array of callbacks regisgtered + + struct SFrameCallbackEntry + { + SFrameCallbackEntry() {} + ~SFrameCallbackEntry() + { + FOR_ARRAY(SScriptCallbackEntry *, theEntry, m_Callbacks) + Q3DStudio_delete(*theEntry, SScriptCallbackEntry); + } + + TCallbackList m_Callbacks; ///< List of callbacks listening to this event + + private: // Disabled Copy Construction + SFrameCallbackEntry(const SFrameCallbackEntry &); + SFrameCallbackEntry &operator=(const SFrameCallbackEntry &); + }; + + typedef CArray TFrameCallbacksList; ///< Array of frame callbacks + +public: // Construction + CScriptCallbacks(); + ~CScriptCallbacks(); + + bool RegisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback, + void *inUserData); + void UnregisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback); + + void ProcessCallbacks(); + +private: + TFrameCallbacksList m_CallbackList; + +private: // Disabled Copy Construction + CScriptCallbacks(const CScriptCallbacks &); + CScriptCallbacks &operator=(const CScriptCallbacks &); +}; + +class CQmlEngine : public IScriptBridge +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + virtual ~CQmlEngine() {} + +public: // Public functions but not functions on the script bridge + /** + * @brief Peek a custom action from the queue + * + * @param[out] outElement Target Element + * @param[out] outSignal Signal Name + * + * @return true if signal available + */ + virtual bool PeekSignal(TElement *&outElement, char *&outName) = 0; + + /** + * @brief Select a slide by index + * + * @param[in] component Component Name + * @param[in] slideIndex Slide index + * @param[in] inArgs Arguemnts for slide switch + * + * @return none + */ + virtual void GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex, + const SScriptEngineGotoSlideArgs &inArgs) = 0; + + virtual bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) = 0; + + /** + * @brief Go to specified time + * + * @param[in] component Component Name + * @param[in] time New time + * + * @return none + */ + virtual void GotoTime(const char *component, const Q3DStudio::FLOAT time) = 0; + + /** + * @brief Return values of an attribute + * + * @param[in] element Element Name + * @param[in] attName Attribute name + * @param[out] value Attribute value + * + * @return none + */ + virtual bool GetAttribute(const char *element, const char *attName, char *value) = 0; + + /** + * @brief Register a callback + * + * @param[in] callbackType callback type +* @param[in] inCallback pointer to callback +* @param[in] inUserData pointer to user data + * + * @return true on success + */ + virtual bool RegisterCallback(Q3DStudio::UINT32 callbackType, const TScriptCallback inCallback, + void *inUserData) = 0; + + /** + * @brief Shutdown QML engine + * + * @param[in] inFoundation Pointer to foundation + * + * @return no return + */ + virtual void Shutdown(qt3ds::NVFoundationBase &inFoundation) = 0; + + virtual qt3ds::runtime::IApplication *GetApplication() = 0; + + virtual void Initialize() = 0; + +public: + /** + * @brief Create QML engine + * + * @param[in] inFoundation Pointer to foundation + * @param[in] inTimeProvider Pointer to time provider + * + * @return no return + */ + static CQmlEngine *Create(qt3ds::NVFoundationBase &inFoundation, ITimeProvider &inTimeProvider); +}; + +} // namespace Q3DStudio + +#endif diff --git a/src/Runtime/Source/runtime/Qt3DSRuntimeFactory.h b/src/Runtime/Source/runtime/Qt3DSRuntimeFactory.h new file mode 100644 index 00000000..1df732a6 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSRuntimeFactory.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "Qt3DSTimer.h" +#include "foundation/Qt3DSRefCounted.h" + +namespace qt3ds { +namespace render { + class IInputStreamFactory; + class IQt3DSRenderContext; + class IQt3DSRenderContextCore; +} +} + +namespace qt3ds { +namespace runtime { + class IApplication; + class IApplicationCore; +} +} + +namespace qt3ds { +namespace state { + class IVisualStateContext; +} +} + +namespace qt3ds { +namespace evt { + class IEventSystem; +} +} + +namespace qt3ds { +class NVFoundationBase; +namespace foundation { + class IStringTable; + class IPerfTimer; +} +} + +namespace Q3DStudio { + +class IScene; +class CRenderEngine; +class ISceneManager; +class IRender; +class CInputEngine; +class IScriptBridge; +class CPresentation; +class IPresentation; +class ITimeProvider; +class ISceneBinaryLoader; + +// All of the interfaces available without opengl initialized. +class IRuntimeFactoryCore : public qt3ds::foundation::NVRefCounted +{ +public: + virtual ISceneBinaryLoader &GetSceneLoader() = 0; + virtual IScriptBridge &GetScriptEngineQml() = 0; + virtual qt3ds::render::IQt3DSRenderContextCore &GetRenderContextCore() = 0; + virtual qt3ds::render::IInputStreamFactory &GetInputStreamFactory() = 0; + virtual qt3ds::state::IVisualStateContext &GetVisualStateContext() = 0; + virtual qt3ds::evt::IEventSystem &GetEventSystem() = 0; + virtual ITimeProvider &GetTimeProvider() = 0; + virtual qt3ds::NVFoundationBase &GetFoundation() = 0; + virtual qt3ds::foundation::IPerfTimer &GetPerfTimer() = 0; + virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; + virtual void AddSearchPath(const char8_t *inFile) = 0; + virtual void SetDllDir(const char *inDir) = 0; + virtual qt3ds::runtime::IApplicationCore *GetApplicationCore() = 0; + virtual void SetApplicationCore(qt3ds::runtime::IApplicationCore *app) = 0; +}; + +class IRuntimeFactory : public IRuntimeFactoryCore +{ +protected: + virtual ~IRuntimeFactory() {} + +public: + virtual ISceneManager &GetSceneManager() = 0; + virtual qt3ds::render::IQt3DSRenderContext &GetQt3DSRenderContext() = 0; + virtual qt3ds::runtime::IApplication *GetApplication() = 0; + virtual void SetApplication(qt3ds::runtime::IApplication *app) = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSSceneManager.h b/src/Runtime/Source/runtime/Qt3DSSceneManager.h new file mode 100644 index 00000000..7b8a4aab --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSSceneManager.h @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSPickFrame.h" +#include "Qt3DSIStateful.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSIScene.h" + +namespace qt3ds { +namespace foundation { + class IInStream; + class IOutStream; + class Mutex; +} +} + +namespace qt3ds { +class Q3DSVariantConfig; +namespace render { + class IQt3DSRenderContextCore; + class ILoadedBuffer; +} +} + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class IScene; +class IPresentation; +class CRenderEngine; +class CRenderEngine; +class IUIPParser; +class CFileStream; +class IRuntimeFactory; +class IScriptBridge; +class ISceneManager; + +class ISceneBinaryLoader : public qt3ds::foundation::NVRefCounted +{ +protected: + virtual ~ISceneBinaryLoader() {} + +public: + virtual qt3ds::foundation::NVDataRef + BinaryLoadManagerData(qt3ds::foundation::IInStream &inStream, const char *inBinaryDir) = 0; + + // threadsafe + // Can be called from any thread + virtual bool GetBinaryLoadFileName(eastl::string &inPresentationFilename, + eastl::string &outResult) = 0; + + // threadsafe + // returns a handle to the loaded object. Return value of zero means error. + virtual qt3ds::QT3DSU32 LoadSceneStage1(qt3ds::foundation::CRegisteredString inPresentationDirectory, + qt3ds::render::ILoadedBuffer &inData) = 0; + + // threadsafe + // still does not require openGL context but has dependency on a few other things. + virtual void LoadSceneStage2(qt3ds::QT3DSU32 inSceneHandle, IPresentation &inPresentation, + size_t inElementMemoryOffset, IScriptBridge &inBridge) = 0; +}; +struct FacePositionPlanes +{ + enum Enum { XY = 0, YZ, XZ }; +}; + +//============================================================================== +/** +* @class ISceneManager +* @brief Container class that creates and manages all the Scenes. +*/ +class ISceneManager : public qt3ds::foundation::NVRefCounted +{ +protected: + virtual ~ISceneManager(){} + +public: // Presentations + //============================================================================== + /** + * Load a new scene based on an existing presentation. This will create a new + * CScene-based class from the factory method at "CreateScene". To supply + * your own class, simply set "CreateScene" to the desired factory method. + * After creating the new scene, a load will be triggered. + * @param inPresentation the current presentation loaded + */ + virtual IScene *LoadScene(IPresentation *inPresentation, IUIPParser *inParser, + IScriptBridge &inBridge, + const qt3ds::Q3DSVariantConfig &variantConfig) = 0; + virtual void LoadRenderPlugin(const CHAR *inAssetIDString, const CHAR *inPath, + const CHAR *inArgs) = 0; + + virtual void LoadQmlStreamerPlugin(const CHAR *inAssetIDString) = 0; + + virtual void BinarySaveManagerData(qt3ds::foundation::IOutStream &inStream, + const char *inBinaryDir) = 0; + // Loading flow data needs to return the string table memory block. This allows + // other systems to use remap their string table strings assuming they had mapped them before + // serialization. In general this is a horrible hack and abstraction leak but assuming you have + // a string + // table I guess it isn't too bad. + virtual qt3ds::foundation::NVDataRef + BinaryLoadManagerData(qt3ds::foundation::IInStream &inStream, const char *inBinaryDir) = 0; + + virtual void BinarySave(Q3DStudio::IScene &inScene) = 0; + +public: // Update Cycle + virtual BOOL Update() = 0; + virtual BOOL RenderPresentation(IPresentation *inPresentation) = 0; + virtual void OnViewResize(INT32 inViewWidth, INT32 inViewHeight) = 0; + virtual void GetViewSize(INT32 &outWidth, INT32 &outHeight) = 0; + + virtual STextSizes GetDisplayDimensions(Q3DStudio::IPresentation *inPrimaryPresentation) = 0; + +public: // Picking + virtual Q3DStudio::TElement *UserPick(float mouseX, float mouseY) = 0; + virtual SPickFrame AdvancePickFrame(const SInputFrame &inInputFrame) = 0; + // Get the relative UV coord position of an element. This matches how mouse picking works where + // we pick out + virtual qt3ds::foundation::Option + FacePosition(Q3DStudio::TElement &inElement, float mouseX, float mouseY, + qt3ds::foundation::NVDataRef inMapperElements, + FacePositionPlanes::Enum inPlane) = 0; + + virtual void Release() = 0; + + static ISceneManager &Create(IRuntimeFactory &inFactory, CRenderEngine &inRenderEngine); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp b/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp new file mode 100644 index 00000000..e7cc0983 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp @@ -0,0 +1,541 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "RuntimePrefix.h" +#include "Qt3DSSlideSystem.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSAnimationSystem.h" +#include "Qt3DSLogicSystem.h" +#include "foundation/SerializationTypes.h" +#include "foundation/IOStreams.h" +#include "Qt3DSHash.h" +#include "Qt3DSTimePolicy.h" +#include "foundation/Qt3DSIndexableLinkedList.h" + +using namespace qt3ds::runtime; +using namespace qt3ds::runtime::element; + +namespace { +struct SSlideAttribute +{ + QT3DSU32 m_Index; + Q3DStudio::UVariant m_Value; + SSlideAttribute() + : m_Index(0) + { + m_Value.m_INT32 = 0; + } + SSlideAttribute(QT3DSU32 idx, Q3DStudio::UVariant val) + : m_Index(idx) + , m_Value(val) + { + } +}; + +struct SSlideAttributeNode +{ + enum { + AttributeCount = 8, + }; + + SSlideAttribute m_Data[AttributeCount]; + SSlideAttributeNode *m_NextNode; + + SSlideAttributeNode() + : m_NextNode(NULL) + { + } +}; + +typedef IndexableLinkedList + TSlideAttributeNodeList; + +struct SSlideElement +{ + QT3DSU32 m_ElementHandle; + QT3DSU32 m_AttributeCount : 31; + QT3DSU32 m_Active : 1; + SSlideElement *m_NextElement; + SSlideAttributeNode *m_AttributeNodes; + + SSlideElement() + : m_ElementHandle(0) + , m_AttributeCount(0) + , m_Active(false) + , m_NextElement(NULL) + , m_AttributeNodes(NULL) + { + } +}; + +struct SSlideAnimActionNode +{ + enum { + AnimActionCount = 8, + }; + SSlideAnimAction m_Data[AnimActionCount]; + SSlideAnimActionNode *m_NextNode; + SSlideAnimActionNode() + : m_NextNode(NULL) + { + } +}; + +typedef IndexableLinkedList + TSlideAnimActionNodeList; + +struct SSlide +{ + SSlide *m_NextSlide; + CRegisteredString m_Name; + QT3DSU32 m_PlayMode : 3; + QT3DSU32 m_PlayThroughTo : 8; // OXFF means no playthrough + QT3DSU32 m_Paused : 1; + QT3DSU32 m_StartTime; + QT3DSU32 m_EndTime; + QT3DSU32 m_AnimActionCount; + SSlideElement *m_FirstElement; + SSlideAnimActionNode *m_FirstAnimActionNode; + + SSlide() + : m_NextSlide(NULL) + , m_PlayMode(PlayMode::StopAtEnd) + , m_PlayThroughTo(0xFF) + , m_Paused(false) + , m_StartTime(0) + , m_EndTime(0) + , m_AnimActionCount(0) + , m_FirstElement(NULL) + , m_FirstAnimActionNode(NULL) + { + } + + void Initialize(CRegisteredString inName, PlayMode::Enum inMode, QT3DSU8 inPlayThrough, + bool inPaused, QT3DSU32 inStartTime, QT3DSU32 inEndTime) + { + m_Name = inName; + m_PlayMode = inMode; + m_PlayThroughTo = inPlayThrough; + m_Paused = inPaused; + m_StartTime = inStartTime; + m_EndTime = inEndTime; + } +}; + +struct SSlideSystem : public ISlideSystem +{ + typedef nvhash_map TComponentSlideHash; + typedef Pool TAttributeNodePool; + typedef Pool TSlideAnimActionPool; + typedef Pool TSlideElementPool; + typedef Pool TSlidePool; + + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + IElementAllocator &m_ElementSystem; + TAttributeNodePool m_AttributeNodePool; + TSlideAnimActionPool m_AnimActionPool; + TSlideElementPool m_SlideElements; + TSlidePool m_SlidePool; + TComponentSlideHash m_Slides; + + SSlide *m_CurrentSlide; + SSlideElement *m_CurrentSlideElement; + + NVDataRef m_LoadData; + + QT3DSI32 m_RefCount; + + SSlideSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, IElementAllocator &inAllocator) + : m_Foundation(inFnd) + , m_StringTable(inStrTable) + , m_ElementSystem(inAllocator) + , m_AttributeNodePool(ForwardingAllocator(inFnd.getAllocator(), "m_AttributeNodePool")) + , m_AnimActionPool(ForwardingAllocator(inFnd.getAllocator(), "m_AnimActionPool")) + , m_SlidePool(ForwardingAllocator(inFnd.getAllocator(), "m_SlidePool")) + , m_SlideElements(ForwardingAllocator(inFnd.getAllocator(), "m_SlideElements")) + , m_Slides(inFnd.getAllocator(), "m_Slides") + , m_CurrentSlide(NULL) + , m_CurrentSlideElement(NULL) + , m_RefCount(0) + { + } + + void addRef() override { atomicIncrement(&m_RefCount); } + + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Foundation.getAllocator()); + NVDelete(alloc, this); + } + } + + QT3DSU32 AddSlide(element::SElement &inComponent, const char8_t *inName, + PlayMode::Enum inPlayMode, bool inPaused, QT3DSU8 inPlayThroughTo, + QT3DSU32 inMinTime, QT3DSU32 inMaxTime) override + { + eastl::pair inserter = + m_Slides.insert(eastl::make_pair(&inComponent, (SSlide *)NULL)); + SSlide *newSlide = m_SlidePool.construct(__FILE__, __LINE__); + QT3DSU32 slideIndex = 0; + if (inserter.first->second == NULL) { + inserter.first->second = newSlide; + } else { + SSlide *theSlide = NULL; + for (theSlide = inserter.first->second; theSlide->m_NextSlide != NULL; + theSlide = theSlide->m_NextSlide) { + ++slideIndex; + } + theSlide->m_NextSlide = newSlide; + } + m_CurrentSlide = newSlide; + newSlide->Initialize(m_StringTable.RegisterStr(inName), inPlayMode, inPlayThroughTo, + inPaused, inMinTime, inMaxTime); + m_CurrentSlideElement = NULL; + if (inComponent.IsComponent()) { + SComponent &theComponent = static_cast(inComponent); + theComponent.m_SlideCount++; + } + return slideIndex; + } + + void SetSlideMaxTime(QT3DSU32 inMaxTime) override + { + if (m_CurrentSlide != NULL) + m_CurrentSlide->m_EndTime = inMaxTime; + } + + void AddSlideElement(element::SElement &inElement, bool inActive) override + { + if (m_CurrentSlide != NULL) { + SSlideElement *lastSlideElement = m_CurrentSlideElement; + m_CurrentSlideElement = m_SlideElements.construct(__FILE__, __LINE__); + m_CurrentSlideElement->m_Active = inActive; + m_CurrentSlideElement->m_ElementHandle = inElement.GetHandle(); + if (lastSlideElement == NULL) { + QT3DS_ASSERT(m_CurrentSlide->m_FirstElement == NULL); + m_CurrentSlide->m_FirstElement = m_CurrentSlideElement; + } else { + lastSlideElement->m_NextElement = m_CurrentSlideElement; + } + m_CurrentSlideElement->m_Active = inActive; + } else { + QT3DS_ASSERT(false); + } + } + void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, Q3DStudio::UVariant inValue) override + { + if (m_CurrentSlideElement != NULL) { + + SElement *theElement = + m_ElementSystem.FindElementByHandle(m_CurrentSlideElement->m_ElementHandle); + Option theIdx = theElement->FindPropertyIndex(inKey.m_Hash); + if (theIdx.hasValue() == false) { + QT3DS_ASSERT(false); + return; + } + QT3DSU32 count = m_CurrentSlideElement->m_AttributeCount; + TSlideAttributeNodeList::Create(m_CurrentSlideElement->m_AttributeNodes, count, + m_AttributeNodePool) = + SSlideAttribute(*theIdx, inValue); + m_CurrentSlideElement->m_AttributeCount = count; + } + } + + SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inId, bool inActive) override + { + if (m_CurrentSlide != NULL) { + SSlideAnimAction &theAnimAction = TSlideAnimActionNodeList::Create( + m_CurrentSlide->m_FirstAnimActionNode, m_CurrentSlide->m_AnimActionCount, + m_AnimActionPool); + theAnimAction = SSlideAnimAction((QT3DSI32)inId, inActive, inAnimation); + &theAnimAction; + } + + return NULL; + } + + const SSlide *FindSlide(SSlideKey inKey) const + { + TComponentSlideHash::const_iterator iter = m_Slides.find(inKey.m_Component); + if (iter == m_Slides.end()) + return NULL; + + SSlide *theSlide = iter->second; + for (QT3DSU32 idx = inKey.m_Index; idx; --idx) { + if (theSlide) + theSlide = theSlide->m_NextSlide; + } + + return theSlide; + } + + template + static void IterateSlideAnimActions(const SSlide &inSlide, TOperator inOp) + { + for (TSlideAnimActionNodeList::const_iterator + iter = TSlideAnimActionNodeList::begin(inSlide.m_FirstAnimActionNode, + inSlide.m_AnimActionCount), + end = TSlideAnimActionNodeList::end(inSlide.m_FirstAnimActionNode, + inSlide.m_AnimActionCount); + iter != end; ++iter) { + inOp(*iter); + } + } + + template + static void IterateSlideElementAttributes(const SSlide &inSlide, TOperator inOp, + IElementAllocator &inAlloc) + { + for (SSlideElement *theElement = inSlide.m_FirstElement; theElement; + theElement = theElement->m_NextElement) { + SElement *theElem = inAlloc.FindElementByHandle(theElement->m_ElementHandle); + if (!theElem) { + QT3DS_ASSERT(false); + } else { + if (inOp.handleElementActive(*theElem, theElement->m_Active)) { + for (TSlideAttributeNodeList::const_iterator + iter = TSlideAttributeNodeList::begin(theElement->m_AttributeNodes, + theElement->m_AttributeCount), + end = TSlideAttributeNodeList::end(theElement->m_AttributeNodes, + theElement->m_AttributeCount); + iter != end; ++iter) { + inOp.handleElementAttribute(*theElem, *iter); + } + } + } + } + } + + struct SDynamicKeyOperator + { + IAnimationSystem &m_AnimationSystem; + SDynamicKeyOperator(IAnimationSystem &anim) + : m_AnimationSystem(anim) + { + } + void operator()(const SSlideAnimAction &theAction) + { + if (theAction.m_IsAnimation && theAction.m_Active) + m_AnimationSystem.UpdateDynamicKey(theAction.m_Id); + } + }; + + struct SExecuteAnimActionOperator + { + IElementAllocator &m_ElementAllocator; + IAnimationSystem &m_AnimationSystem; + ILogicSystem &m_LogicManager; + bool m_Invert; + + SExecuteAnimActionOperator(IElementAllocator &inElemAllocator, IAnimationSystem &anim, + ILogicSystem &logic, bool inInvert = false) + : m_ElementAllocator(inElemAllocator) + , m_AnimationSystem(anim) + , m_LogicManager(logic) + , m_Invert(inInvert) + { + } + + void operator()(const SSlideAnimAction &theAction) + { + bool active = theAction.m_Active; + if (m_Invert) + active = !active; + if (theAction.m_IsAnimation) + m_AnimationSystem.SetActive(theAction.m_Id, active); + else + m_LogicManager.SetActive(theAction.m_Id, active, m_ElementAllocator); + } + }; + + struct SElementOperator + { + bool m_InvertActive; + SElementOperator(bool inInvert = false) + : m_InvertActive(inInvert) + { + } + bool handleElementActive(SElement &inElement, bool inActive) + { + if (m_InvertActive && inElement.Flags().IsExplicitActive()) + inActive = !inActive; + inElement.Flags().SetExplicitActive(inActive); + + if (m_InvertActive) + return false; + + return inActive; + } + + void handleElementAttribute(SElement &inElement, const SSlideAttribute &inAttribute) + { + Option theProperty = + inElement.GetPropertyByIndex(inAttribute.m_Index); + if (theProperty.hasValue()) { + inElement.SetAttribute(*theProperty, inAttribute.m_Value); + } else { + QT3DS_ASSERT(false); + } + } + }; + + void InitializeDynamicKeys(SSlideKey inKey, IAnimationSystem &inAnimationSystem) const override + { + const SSlide *theSlide = FindSlide(inKey); + if (theSlide != NULL) { + IterateSlideAnimActions(*theSlide, SDynamicKeyOperator(inAnimationSystem)); + } + } + + void ExecuteSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, + ILogicSystem &inLogicManager) const override + { + const SSlide *theSlide = FindSlide(inKey); + + if (theSlide == NULL) { + QT3DS_ASSERT(false); + return; + } + if (inKey.m_Component->IsComponent()) { + Q3DStudio::TTimeUnit theLoopDuration = theSlide->m_EndTime - theSlide->m_StartTime; + SComponent &theComponent = static_cast(*inKey.m_Component); + Q3DStudio::CTimePolicy &thePolicy = theComponent.GetTimePolicy(); + Q3DStudio::TimePolicyModes::Enum theMode = Q3DStudio::TimePolicyModes::StopAtEnd; + switch (theSlide->m_PlayMode) { + case PlayMode::Looping: + theMode = Q3DStudio::TimePolicyModes::Looping; + break; + case PlayMode::PingPong: + theMode = Q3DStudio::TimePolicyModes::PingPong; + break; + case PlayMode::Ping: + theMode = Q3DStudio::TimePolicyModes::Ping; + break; + + case PlayMode::StopAtEnd: + case PlayMode::PlayThroughTo: + default: + theMode = Q3DStudio::TimePolicyModes::StopAtEnd; + break; + } + thePolicy.Initialize(theLoopDuration, theMode); + thePolicy.SetPaused(theSlide->m_Paused); + + theComponent.SetPlayThrough(theSlide->m_PlayMode == PlayMode::PlayThroughTo); + } + + IterateSlideElementAttributes(*theSlide, SElementOperator(false), m_ElementSystem); + IterateSlideAnimActions(*theSlide, SExecuteAnimActionOperator( + m_ElementSystem, inAnimationSystem, inLogicManager)); + } + + void RollbackSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, + ILogicSystem &inLogicManager) const override + { + const SSlide *theSlide = FindSlide(inKey); + + if (theSlide == NULL) { + QT3DS_ASSERT(false); + return; + } + + IterateSlideElementAttributes(*theSlide, SElementOperator(true), m_ElementSystem); + IterateSlideAnimActions( + *theSlide, + SExecuteAnimActionOperator(m_ElementSystem, inAnimationSystem, inLogicManager, true)); + } + + QT3DSU8 FindSlide(element::SElement &inComponent, const char8_t *inSlideName) const override + { + TComponentSlideHash::const_iterator theFindResult = m_Slides.find(&inComponent); + if (theFindResult == m_Slides.end()) { + QT3DS_ASSERT(false); + return 0xFF; + } + CRegisteredString theRegName = m_StringTable.RegisterStr(inSlideName); + QT3DSU8 idx = 0; + for (const SSlide *theSlide = theFindResult->second; theSlide; + theSlide = theSlide->m_NextSlide, ++idx) { + if (theSlide->m_Name == theRegName) + return idx; + } + return 0xFF; + } + + QT3DSU8 FindSlide(element::SElement &inComponent, QT3DSU32 inSlideHashName) const override + { + TComponentSlideHash::const_iterator theFindResult = m_Slides.find(&inComponent); + if (theFindResult == m_Slides.end()) { + QT3DS_ASSERT(false); + return 0xFF; + } + + QT3DSU8 idx = 0; + for (const SSlide *theSlide = theFindResult->second; theSlide; + theSlide = theSlide->m_NextSlide, ++idx) { + if (Q3DStudio::CHash::HashString(theSlide->m_Name) == inSlideHashName) + return idx; + } + return 0xFF; + } + + const char8_t *GetSlideName(SSlideKey inKey) const override + { + const SSlide *theSlide = FindSlide(inKey); + if (theSlide) + return theSlide->m_Name.c_str(); + QT3DS_ASSERT(false); + return ""; + } + + QT3DSU8 GetPlaythroughToSlideIndex(SSlideKey inKey) const override + { + const SSlide *theSlide = FindSlide(inKey); + if (theSlide) + return theSlide->m_PlayThroughTo; + QT3DS_ASSERT(false); + return 0xFF; + } +}; +} + +ISlideSystem &ISlideSystem::CreateSlideSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, + IElementAllocator &inElemAllocator) +{ + return *QT3DS_NEW(inFnd.getAllocator(), SSlideSystem)(inFnd, inStrTable, inElemAllocator); +} diff --git a/src/Runtime/Source/runtime/Qt3DSSlideSystem.h b/src/Runtime/Source/runtime/Qt3DSSlideSystem.h new file mode 100644 index 00000000..de2ddbbc --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSSlideSystem.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "Qt3DSElementSystem.h" + +namespace Q3DStudio { +class ILogicManager; +} + +namespace qt3ds { +namespace runtime { + class ILogicSystem; + class IAnimationSystem; + + struct SSlideKey + { + element::SElement *m_Component; + QT3DSU32 m_Index; + SSlideKey() + : m_Component(NULL) + , m_Index(0) + { + } + SSlideKey(element::SElement &inElem, QT3DSU32 inIdx) + : m_Component(&inElem) + , m_Index(inIdx) + { + } + + bool IsValid() const { return m_Component != NULL; } + + bool operator==(const SSlideKey &inOther) const + { + return m_Component == inOther.m_Component && m_Index == inOther.m_Index; + } + }; + + struct PlayMode + { + enum Enum { + Looping = 0, + StopAtEnd, + PingPong, + Ping, + PlayThroughTo, + }; + }; + + struct SSlidePlayInformation + { + PlayMode::Enum m_PlayMode; + bool m_Paused; + QT3DSU8 m_PlayThroughTo; + + SSlidePlayInformation() + : m_PlayMode(PlayMode::Looping) + , m_Paused(false) + , m_PlayThroughTo(0xFF) + { + } + }; + + struct SSlideAnimAction + { + QT3DSI32 m_Id; + bool m_Active; + bool m_IsAnimation; + SSlideAnimAction() + : m_Id(0) + , m_Active(false) + , m_IsAnimation(false) + { + } + SSlideAnimAction(QT3DSI32 inId, bool inActive, bool inAnimation) + : m_Id(inId) + , m_Active(inActive) + , m_IsAnimation(inAnimation) + { + } + }; + + // Throughout this object, a slide index of 0xFF means invalid slide index. + class ISlideSystem : public NVRefCounted + { + public: + static QT3DSU8 InvalidSlideIndex() { return 0xFF; } + // Building out a dataset. + // Returns the index + // This slide is now the active cursor. The rest of the building functions will implicitly + // refer + // to the last added slide + // Playthroughto is either an index of the new slide or -1 meaning no playthough value. + virtual QT3DSU32 AddSlide(element::SElement &inComponent, const char8_t *inName, + PlayMode::Enum inPlayMode = PlayMode::Looping, bool inPaused = false, + QT3DSU8 inPlaythroughTo = InvalidSlideIndex(), QT3DSU32 inMinTime = 0, + QT3DSU32 inMaxTime = 0) = 0; + + virtual void SetSlideMaxTime(QT3DSU32 inMaxTime) = 0; + virtual void AddSlideElement(element::SElement &inElement, bool inActive) = 0; + virtual void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, + Q3DStudio::UVariant inValue) = 0; + virtual SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inIndex, + bool inActive) = 0; + + // Using the dataset + virtual void InitializeDynamicKeys(SSlideKey inKey, + IAnimationSystem &inAnimationSystem) const = 0; + virtual void ExecuteSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, + ILogicSystem &inLogicManager) const = 0; + virtual void RollbackSlide(SSlideKey inKey, IAnimationSystem &inAnimationSystem, + ILogicSystem &inLogicManager) const = 0; + virtual QT3DSU8 FindSlide(element::SElement &inComponent, + const char8_t *inSlideName) const = 0; + virtual QT3DSU8 FindSlide(element::SElement &inComponent, QT3DSU32 inSlideHashName) const = 0; + virtual const char8_t *GetSlideName(SSlideKey inKey) const = 0; + virtual QT3DSU8 GetPlaythroughToSlideIndex(SSlideKey inKey) const = 0; + + static ISlideSystem &CreateSlideSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, + IElementAllocator &inElemAllocator); + }; +} +} diff --git a/src/Runtime/Source/runtime/Qt3DSTimePolicy.cpp b/src/Runtime/Source/runtime/Qt3DSTimePolicy.cpp new file mode 100644 index 00000000..e1efb8e0 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSTimePolicy.cpp @@ -0,0 +1,407 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTimePolicy.h" +#include "foundation/Qt3DSUnionCast.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "Qt3DSComponentManager.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +const TTimeUnit CTimePolicy::FOREVER = 0; + +SAlignedTimeUnit::SAlignedTimeUnit(const TTimeUnit &inUnit) +{ + StaticAssert::valid_expression(); + qt3ds::intrinsics::memCopy(this, &inUnit, sizeof(TTimeUnit)); +} + +SAlignedTimeUnit::operator TTimeUnit() const +{ + TTimeUnit retval; + qt3ds::intrinsics::memCopy(&retval, this, sizeof(TTimeUnit)); + return retval; +} + +void SAlignedTimeUnit::operator-=(const TTimeUnit &inTime) +{ + TTimeUnit theThis(*this); + theThis -= inTime; + *this = SAlignedTimeUnit(theThis); +} + +void SAlignedTimeUnit::operator%=(const TTimeUnit &inTime) +{ + TTimeUnit theThis(*this); + theThis %= inTime; + *this = SAlignedTimeUnit(theThis); +} + +//============================================================================== +/** + * Initialization + */ + +void CTimePolicy::Initialize(const TTimeUnit inLoopingDuration, TimePolicyModes::Enum inMode) +{ + m_LocalTime = 0; + m_LoopingDuration = (unsigned long)inLoopingDuration; + m_TimePolicyMode = inMode; + m_Offset = 0; + m_Paused = false; + m_OffsetInvalid = 1; + m_Backward = 0; + m_Rate = 1.0f; +} + +void CTimePolicy::Initialize(const TTimeUnit inLoopingDuration /*= FOREVER*/, + UINT32 inRepetitions /*= 1*/, BOOL inPingPong /*= false*/) +{ + // UINT8 m_Repetitions : 2; ///< Number of traversal ( 0 = forever, 1 = stop at end, 2 = + // ping ) + TimePolicyModes::Enum theMode = TimePolicyModes::StopAtEnd; + if (inRepetitions == 1) + theMode = TimePolicyModes::StopAtEnd; + else if (inRepetitions == 0) { + if (inPingPong) + theMode = TimePolicyModes::PingPong; + else + theMode = TimePolicyModes::Looping; + } else + theMode = TimePolicyModes::Ping; + + Initialize(inLoopingDuration, theMode); +} + +//============================================================================== +/** + * Return the last computed time. This is subjected to playmodes. + * @return local time + */ +TTimeUnit CTimePolicy::InternalGetTime() const +{ + if (m_LocalTime < m_LoopingDuration) + return m_LocalTime; + else { + if (m_LoopingDuration == 0) + return m_LocalTime; + + switch (m_TimePolicyMode) { + case TimePolicyModes::StopAtEnd: + return m_LoopingDuration; + case TimePolicyModes::Looping: + return m_LocalTime % m_LoopingDuration; + case TimePolicyModes::Ping: { + unsigned long interval = m_LocalTime / m_LoopingDuration; + unsigned long leftover = m_LocalTime % m_LoopingDuration; + if (interval == 1) + return m_LoopingDuration - leftover; + return 0; + } + case TimePolicyModes::PingPong: { + unsigned long interval = m_LocalTime / m_LoopingDuration; + unsigned long leftover = m_LocalTime % m_LoopingDuration; + if (interval % 2) + return m_LoopingDuration - leftover; + return leftover; + } + default: + QT3DS_ASSERT(false); + return 0; + break; + } + } +} + +TTimeUnit CTimePolicy::GetTime() const +{ + TTimeUnit retval = InternalGetTime(); + // Apply direction and rate. + bool isPlayingBack = m_Backward; + if (m_Rate < 0) + isPlayingBack = !isPlayingBack; + + if (isPlayingBack) + retval = m_LoopingDuration - retval; + return retval; +} + +static unsigned long clampTime(long inTime, unsigned long inDuration) +{ + if (inTime < 0) + return 0; + if (inTime > (long)inDuration) + return inDuration; + return (unsigned long)inTime; +} + +//============================================================================== +/** + * Trigger the policy to return inTime next GetTime is called. + * This is tricky math and the m_Offset field is being used both normally to + * simply change the time and here to calibrate itself next time ComputeTime + * is called. + * @param inTime time to be returned next ComputeTime + */ +void CTimePolicy::SetTime(TTimeUnit inTime) +{ + + bool isPlayingBack = m_Backward; + if (m_Rate < 0) + isPlayingBack = !isPlayingBack; + + if (isPlayingBack) + inTime = m_LoopingDuration - inTime; + + m_OffsetInvalid = 1; + + // Setup m_LocalTime such that it reflects intime. + if (m_LoopingDuration == 0) { + m_LocalTime = (unsigned long)inTime; + return; + } + + switch (m_TimePolicyMode) { + case TimePolicyModes::StopAtEnd: + m_LocalTime = clampTime((long)inTime, m_LoopingDuration); + break; + case TimePolicyModes::Looping: { + long input = (long)inTime; + while (input < 0) + input += (long)m_LoopingDuration; + m_LocalTime = ((unsigned long)input) % m_LoopingDuration; + } break; + case TimePolicyModes::Ping: { + long input = (long)inTime; + if (input < 0) + input = 0; + + long totalInterval = (long)(m_LoopingDuration * 2); + if (input > totalInterval) + m_LocalTime = (unsigned long)totalInterval; + else + m_LocalTime = (unsigned long)input; + } break; + case TimePolicyModes::PingPong: { + long totalInterval = (long)(m_LoopingDuration * 2); + long input = (long)inTime; + while (input < 0) + input += totalInterval; + m_LocalTime = (unsigned long)(input % totalInterval); + } break; + default: + QT3DS_ASSERT(false); + } +} + +//============================================================================== +/** + * Retrieves the looping duration. + * @see CTimePolicy::SetLoopingDuration( ) + * @return TTimeUnit looping duration + */ +TTimeUnit CTimePolicy::GetLoopingDuration() const +{ + return m_LoopingDuration; +} + +//============================================================================== +/** + * Set the looping duration. + * Looping duration is defined as the time it takes before stopping, pinging or + * looping. + * @param inTime looping duration + */ +void CTimePolicy::SetLoopingDuration(const TTimeUnit inTime) +{ + m_LoopingDuration = (unsigned long)inTime; +} + +//============================================================================== +/** + * Return the paused state. + * @return BOOL pause state + */ +BOOL CTimePolicy::GetPaused() const +{ + return m_Paused; +} + +BOOL CTimePolicy::GetPlayBackDirection() const +{ + bool reversePlaybackDirection = m_Backward; + if (m_Rate < 0) + reversePlaybackDirection = !reversePlaybackDirection; + + bool retval = m_LocalTime < m_LoopingDuration; + + if (reversePlaybackDirection) + retval = !retval; + return retval; +} + +//============================================================================== +/** + * Sets the paused state + * @param inPaused pause state + */ +void CTimePolicy::SetPaused(const BOOL inPaused) +{ + m_Paused = static_cast(inPaused); +} + +BOOL CTimePolicy::UpdateTime(const TTimeUnit inTime) +{ + if (fabs(m_Rate) > .001f) + m_LocalTime = + static_cast(((unsigned long)(inTime + m_Offset)) * fabs(m_Rate)); + // else we are effectively stopped and we can't update the time. + + if (m_LoopingDuration == 0) + return FALSE; + + unsigned long maxUsefulDuration = m_LoopingDuration * 2; + BOOL retval = 0; + switch (m_TimePolicyMode) { + case TimePolicyModes::StopAtEnd: + if (m_LocalTime > m_LoopingDuration) { + retval = 1; + m_LocalTime = m_LoopingDuration; + } + break; + case TimePolicyModes::Looping: + m_LocalTime = m_LocalTime % m_LoopingDuration; + break; + case TimePolicyModes::Ping: + if (m_LocalTime > maxUsefulDuration) { + retval = 1; + m_LocalTime = maxUsefulDuration; + } + break; + case TimePolicyModes::PingPong: + m_LocalTime = m_LocalTime % maxUsefulDuration; + break; + default: + QT3DS_ASSERT(false); + break; + } + return retval; +} +//============================================================================== +/** + * Compute the local time based off the current global time and the settings + * such as duration, repetitions and ping-pong. + * @param inTime global time being fed + * @return BOOL true if policy has reached it's end time + */ +BOOL CTimePolicy::ComputeTime(const TTimeUnit inTime) +{ + // Return the last computed time if paused + if (m_Paused || m_OffsetInvalid) { + // m_LocalTime = inTime + m_Offset; + if (fabs(m_Rate) > .001) + m_Offset = (TTimeUnit)(m_LocalTime / fabs(m_Rate)) - inTime; + else // rate is zero, this should not happen. + m_Offset = (TTimeUnit)(m_LocalTime)-inTime; + m_OffsetInvalid = 0; + return false; + } + return UpdateTime(inTime); +} + +eastl::pair +SComponentTimePolicyOverride::ComputeLocalTime(CTimePolicy &inTimePolicy, TTimeUnit inGlobalTime) +{ + TTimeUnit retval = 0; + BOOL finished = FALSE; + if (inTimePolicy.m_Paused || inTimePolicy.m_OffsetInvalid) { + finished = inTimePolicy.ComputeTime(inGlobalTime); + } else { + Q3DStudio_ASSERT(m_EndTime <= inTimePolicy.GetLoopingDuration()); + unsigned long newLocalTime = (unsigned long)(inGlobalTime + inTimePolicy.m_Offset); + + float diff = static_cast(newLocalTime - inTimePolicy.GetTime()); + diff *= m_TimeMultiplier; + float updatedLocalTime = static_cast(inTimePolicy.m_LocalTime) + diff; + + if (updatedLocalTime < 0.0f) + updatedLocalTime = 0.0f; + + inTimePolicy.m_LocalTime = static_cast(updatedLocalTime); + + bool runningBackwards = m_TimeMultiplier < 0; + + if (runningBackwards) { + if (inTimePolicy.m_LocalTime <= m_EndTime) { + finished = TRUE; + inTimePolicy.m_LocalTime = (unsigned long)m_EndTime; + } + } else // running forwards + { + if (inTimePolicy.m_LocalTime >= m_EndTime) { + finished = TRUE; + inTimePolicy.m_LocalTime = (unsigned long)m_EndTime; + } + } + inTimePolicy.m_Offset = inTimePolicy.m_LocalTime - inGlobalTime; + } + retval = inTimePolicy.GetTime(); + return eastl::make_pair(finished, retval); +} + +void SComponentTimePolicyOverride::SetTime(CTimePolicy &inTimePolicy, TTimeUnit inLocalTime) +{ + if (inLocalTime < 0) + inLocalTime = 0; + if (m_TimeMultiplier < 0) { + if (inLocalTime <= m_EndTime) { + inLocalTime = m_EndTime; + } + } else // running forwards + { + if (inLocalTime >= m_EndTime) { + inLocalTime = m_EndTime; + } + } + inTimePolicy.SetTime(inLocalTime); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/Qt3DSTimePolicy.h b/src/Runtime/Source/runtime/Qt3DSTimePolicy.h new file mode 100644 index 00000000..6a137196 --- /dev/null +++ b/src/Runtime/Source/runtime/Qt3DSTimePolicy.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "foundation/Qt3DSOption.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +struct TimePolicyModes +{ + enum Enum { + StopAtEnd = 0, + Looping, + PingPong, + Ping, + }; +}; + +//============================================================================== +/** + * Filter time based of parameters such as loop, duration, ping-pong etc. + * + * The time policy is an agnostic class that transforms time units based on + * internal settings and times given to it. Think of it as the minimal + * intelligence needed to support the time playback modes we use. It is simply + * a function that takes in a source time variable, adjusts it accordingly, + * and returns a filtered version. + */ + +QT3DS_ALIGN_PREFIX(4) class CTimePolicy +{ + //============================================================================== + // Fields and Constants + //============================================================================== +public: + const static TTimeUnit FOREVER; ///< Forever repetitions means loop forever, Forever duration + ///means infinite duration + friend struct SComponentTimePolicyOverride; ///< This class needs to mangle some of our internal + ///members to keep everything consistent + +protected: + // Time policy related ( 20 bytes ) + unsigned long m_LocalTime; ///< Component current local time; transformed by playmodes + unsigned long m_LoopingDuration; ///< Looping duration + SAlignedTimeUnit m_Offset; ///< Subtraction modifier + FLOAT m_Rate; ///< Time policy rate + UINT8 m_TimePadding[12]; ///< Padding to keep the size of the time policy the same. + + UINT8 + m_TimePolicyMode : 2; ///< Number of durations before halting - FOREVER means infinite reps + UINT8 m_Paused : 1; ///< Paused or playing + UINT8 m_OffsetInvalid : 1; ///< True if we need to reset our offset + UINT8 m_Backward : 1; ///< True if are in 'reverse' mode + + UINT8 m_Unused[3]; ///< (Padding 3 bytes) + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + void Initialize(const TTimeUnit inLoopingDuration = FOREVER, + TimePolicyModes::Enum inMode = TimePolicyModes::StopAtEnd); + void Initialize(const TTimeUnit inLoopingDuration, UINT32 inRepetitions, BOOL inPingPong); + +public: // Access Methods + FLOAT GetRate() const { return m_Rate; } + void SetRate(float inRate) { m_Rate = inRate; } + + bool IsReverse() const { return m_Backward; } + void SetReverse(bool inIsReverse) { m_Backward = inIsReverse ? 1 : 0; } + + TTimeUnit GetTime() const; + void SetTime(TTimeUnit inTime); + + TTimeUnit GetLoopingDuration() const; + void SetLoopingDuration(const TTimeUnit inTime); + + BOOL GetPaused() const; + void SetPaused(const BOOL inPaused); + + BOOL GetPlayBackDirection() const; + +public: // Time update + // The addendum contains extra parameters used that can be specified in a goto-slide command + // in the uia file. + BOOL ComputeTime(const TTimeUnit inTime); + +private: + TTimeUnit InternalGetTime() const; + + BOOL UpdateTime(const TTimeUnit inTime); +} QT3DS_ALIGN_SUFFIX(4); + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtime/RuntimePrefix.h b/src/Runtime/Source/runtime/RuntimePrefix.h new file mode 100644 index 00000000..bf729ebf --- /dev/null +++ b/src/Runtime/Source/runtime/RuntimePrefix.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "render/backends/gl/Qt3DSOpenGLPrefix.h" + +#ifdef _WIN32 +//============================================================================== +// DISABLED WARNINGS +// +// Note that most of these warnings are tuned off by default by the compiler +// even at warning level 4. Using option /Wall turns on all warnings and makes +// even standard Microsoft include files cry. We had to turn off these or +// turn off warnings individually for each standard include file which was +// too much work. Point is that /Wall is like Warning Level 5 and this brings +// it down to about Warning level 4.5, still way above /W4. +//#pragma warning( disable : 4189 ) // local variable is initialized but not referenced +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +#pragma warning(disable : 4511) // copy constructor could not be generated +#pragma warning(disable : 4512) // assignment operator could not be generated +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#pragma warning(disable : 4619) // #pragma warning : there is no warning number '4619' (in string.h) +#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy + // constructor is inaccessible +#pragma warning(disable : 4626) // assignment operator could not be generated because a base class + // assignment operator is inaccessible +#pragma warning( \ + disable : 4668) // not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +#pragma warning(disable : 4826) // Conversion from 'const void *' to 'void *' is sign-extended +#pragma warning(disable : 4996) // _snprintf' was declared deprecated +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning(disable : 4710) // function not inlined +#pragma warning( \ + disable : 4738) // storing 32-bit float result in memory, possible loss of performance + +#pragma warning(disable : 4640) // construction of local static object is not thread-safe +#pragma warning(disable : 4127) // conditional expression is constant + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif //_WIN32 + +//============================================================================== +// STD INCLUDES - Standard includes MUST come first +#include // Standard functions +#include // File and IO +#ifndef _INTEGRITYPLATFORM +#include // memset, memcpy +#endif +#include // strlen + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +#include + +#define UNREFERENCED_PARAMETER(theParam) theParam; +#endif + +//============================================================================== +// ROOT INCLUDES FOR FRAMEWORK +//============================================================================== +#include "Qt3DSTypes.h" +#include "Qt3DSPlatformSpecific.h" +#include "Qt3DSAssert.h" +#include "Qt3DSMacros.h" +#include "Qt3DSConfig.h" +#include "Qt3DSMemorySettings.h" +#include "Qt3DSMemory.h" +#include "Qt3DSFrameworkTypes.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTimer.h" +#include "Qt3DSIScene.h" +#include "foundation/Qt3DSRefCounted.h" //scoped releasable auto ptr. +#include "EASTL/hash_map.h" +#include "EASTL/string.h" diff --git a/src/Runtime/Source/runtime/q3dsqmlbehavior.cpp b/src/Runtime/Source/runtime/q3dsqmlbehavior.cpp new file mode 100644 index 00000000..83b706eb --- /dev/null +++ b/src/Runtime/Source/runtime/q3dsqmlbehavior.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlbehavior.h" +#include "q3dsqmlscript.h" + +namespace Q3DStudio { + +Q3DSQmlBehavior::Q3DSQmlBehavior(QObject *parent) + : QObject(parent), m_script(nullptr) +{ + +} + +void Q3DSQmlBehavior::setScript(Q3DSQmlScript *script) +{ + m_script = script; +} + +float Q3DSQmlBehavior::getDeltaTime() +{ + return m_script->getDeltaTime(); +} + +float Q3DSQmlBehavior::getAttribute(const QString &attribute) +{ + return m_script->getAttribute(attribute); +} + +void Q3DSQmlBehavior::setAttribute(const QString &attribute, const QVariant &value) +{ + m_script->setAttribute(attribute, value); +} + +void Q3DSQmlBehavior::setAttribute(const QString &handle, const QString &attribute, + const QVariant &value) +{ + m_script->setAttribute(handle, attribute, value); +} + +void Q3DSQmlBehavior::fireEvent(const QString &event) +{ + m_script->fireEvent(event); +} + +void Q3DSQmlBehavior::registerForEvent(const QString &event, const QJSValue &function) +{ + m_script->registerForEvent(event, function); +} + +void Q3DSQmlBehavior::registerForEvent(const QString &handle, const QString &event, + const QJSValue &function) +{ + m_script->registerForEvent(handle, event, function); +} + +void Q3DSQmlBehavior::unregisterForEvent(const QString &event) +{ + m_script->unregisterForEvent(event); +} + +void Q3DSQmlBehavior::unregisterForEvent(const QString &handle, const QString &event) +{ + m_script->unregisterForEvent(handle, event); +} + +QVector2D Q3DSQmlBehavior::getMousePosition() +{ + return m_script->getMousePosition(); +} + +QMatrix4x4 Q3DSQmlBehavior::calculateGlobalTransform(const QString &handle) +{ + return m_script->calculateGlobalTransform(handle); +} + +QVector3D Q3DSQmlBehavior::lookAt(const QVector3D &target) +{ + return m_script->lookAt(target); +} + +QVector3D Q3DSQmlBehavior::matrixToEuler(const QMatrix4x4 &matrix) +{ + return m_script->matrixToEuler(matrix); +} + +QString Q3DSQmlBehavior::getParent(const QString &handle) +{ + return m_script->getParent(handle); +} + +void Q3DSQmlBehavior::setDataInputValue(const QString &name, const QVariant &value) +{ + return m_script->setDataInputValue(name, value); +} + +} diff --git a/src/Runtime/Source/runtime/q3dsqmlbehavior.h b/src/Runtime/Source/runtime/q3dsqmlbehavior.h new file mode 100644 index 00000000..76f4a4a0 --- /dev/null +++ b/src/Runtime/Source/runtime/q3dsqmlbehavior.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DSQMLBEHAVIOR_H +#define Q3DSQMLBEHAVIOR_H + +#include +#include +#include +#include +#include +#include + +namespace Q3DStudio { + +class Q3DSQmlScript; + +class Q3DSQmlBehavior : public QObject +{ + Q_OBJECT +public: + Q3DSQmlBehavior(QObject *parent = nullptr); + + void setScript(Q3DSQmlScript *script); + + Q_INVOKABLE float getDeltaTime(); + Q_INVOKABLE float getAttribute(const QString &attribute); + Q_INVOKABLE void setAttribute(const QString &attribute, const QVariant &value); + Q_INVOKABLE void setAttribute(const QString &handle, const QString &attribute, + const QVariant &value); + Q_INVOKABLE void fireEvent(const QString &event); + Q_INVOKABLE void registerForEvent(const QString &event, const QJSValue &function); + Q_INVOKABLE void registerForEvent(const QString &handle, const QString &event, + const QJSValue &function); + Q_INVOKABLE void unregisterForEvent(const QString &event); + Q_INVOKABLE void unregisterForEvent(const QString &handle, const QString &event); + Q_INVOKABLE QVector2D getMousePosition(); + Q_INVOKABLE QMatrix4x4 calculateGlobalTransform(const QString &handle = QString()); + Q_INVOKABLE QVector3D lookAt(const QVector3D &target); + Q_INVOKABLE QVector3D matrixToEuler(const QMatrix4x4 &matrix); + Q_INVOKABLE QString getParent(const QString &handle = QString()); + Q_REVISION(1) Q_INVOKABLE void setDataInputValue(const QString &name, const QVariant &value); + + +Q_SIGNALS: + void initialize(); + void activate(); + void update(); + void deactivate(); + +private: + Q3DSQmlScript *m_script; +}; + +} + +#endif diff --git a/src/Runtime/Source/runtime/q3dsqmlscript.cpp b/src/Runtime/Source/runtime/q3dsqmlscript.cpp new file mode 100644 index 00000000..09f18148 --- /dev/null +++ b/src/Runtime/Source/runtime/q3dsqmlscript.cpp @@ -0,0 +1,403 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlscript.h" + +#include "Qt3DSQmlEngine.h" +#include "Qt3DSElementSystem.h" +#include "Qt3DSApplication.h" +#include "Qt3DSPresentation.h" +#include "Qt3DSInputEngine.h" +#include "Qt3DSInputFrame.h" +#include "Qt3DSQmlElementHelper.h" +#include "Qt3DSHash.h" +#include "Qt3DSEulerAngles.h" + +using namespace Q3DStudio; + +QJSValue argToQJSValue(qt3ds::foundation::IStringTable &strTable, + Q3DStudio::UINT8 type, const UVariant &value) { + switch (type) { + case ATTRIBUTETYPE_INT32: + case ATTRIBUTETYPE_HASH: + return QJSValue(value.m_INT32); + case ATTRIBUTETYPE_FLOAT: + return QJSValue(value.m_FLOAT); + case ATTRIBUTETYPE_BOOL: + return QJSValue(value.m_INT32 != 0); + case ATTRIBUTETYPE_STRING: + return QJSValue(strTable.HandleToStr(value.m_StringHandle)); + case ATTRIBUTETYPE_NONE: + return QJSValue(); + default: + qCCritical(qt3ds::INVALID_OPERATION) + << "Pushed event argument value of unknown type: "<< type; + } + return QJSValue(); +} + +void eventCallback(void *contextData, SEventCommand &event) +{ + auto data = static_cast(contextData); + qt3ds::foundation::IStringTable &strTable( + event.m_Target->GetBelongedPresentation()->GetStringTable()); + QJSValue arg1 = argToQJSValue(strTable, event.m_Arg1Type, event.m_Arg1); + QJSValue arg2 = argToQJSValue(strTable, event.m_Arg2Type, event.m_Arg2); + data->function.call({arg1, arg2}); +} + +Q3DSQmlScript::Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, + TElement &behavior, TElement &owner) + : QObject(nullptr) + , m_api(api) + , m_object(object) + , m_behavior(behavior) + , m_owner(owner) + , m_initialized(false) + , m_lastActivationState(false) + , m_deltaTime(0.0f) + , m_lastTime(0) +{ + updateProperties(); +} + +Q3DSQmlScript::~Q3DSQmlScript() +{ + for (const EventCallbackInfo &callback : m_eventCallbacks) + delete callback.data; +} + +void Q3DSQmlScript::update() +{ + updateProperties(); + + bool active = m_behavior.GetActive(); + + if (active && !m_initialized) { + m_initialized = true; + Q_EMIT m_object.initialize(); + } + + TTimeUnit time = static_cast(m_behavior.GetBelongedPresentation())->GetTime(); + m_deltaTime = (time - m_lastTime) / 1000.0f; + m_lastTime = time; + + if (m_lastActivationState != active) { + if (active) + Q_EMIT m_object.activate(); + else + Q_EMIT m_object.deactivate(); + } + m_lastActivationState = active; + if (active) + Q_EMIT m_object.update(); +} + +void Q3DSQmlScript::call(const QString &function) +{ + const QMetaObject *meta = m_object.metaObject(); + const QString normalized = function + "()"; + if (meta->indexOfMethod(normalized.toUtf8().constData()) != -1) + QMetaObject::invokeMethod(&m_object, function.toUtf8().constData()); +} + +void Q3DSQmlScript::updateProperties() +{ + using namespace qt3ds::foundation; + using namespace qt3ds::runtime::element; + + if (!m_behavior.GetActive()) + return; + + unsigned int numProperties = m_behavior.GetNumProperties(); + for (unsigned int i = 0; i < numProperties; ++i) { + Option property = m_behavior.GetPropertyByIndex(i); + if (!property.hasValue()) + break; + + TPropertyDescAndValuePtr value = property.getValue(); + const char *name = value.first.m_Name.c_str(); + + UVariant *valuePtr = value.second; + switch (value.first.m_Type) { + case ATTRIBUTETYPE_INT32: + case ATTRIBUTETYPE_HASH: + m_object.setProperty(name, valuePtr->m_INT32); + break; + case ATTRIBUTETYPE_FLOAT: + m_object.setProperty(name, valuePtr->m_FLOAT); + break; + case ATTRIBUTETYPE_BOOL: + m_object.setProperty(name, valuePtr->m_INT32 != 0); + break; + case ATTRIBUTETYPE_STRING: + m_object.setProperty( + name, + m_behavior.GetBelongedPresentation()->GetStringTable() + .HandleToStr(valuePtr->m_StringHandle) + .c_str()); + break; + default: + QT3DS_ASSERT(false); + } + } +} + +bool Q3DSQmlScript::hasBehavior(const TElement *behavior) +{ + return &m_behavior == behavior; +} + +float Q3DSQmlScript::getDeltaTime() +{ + return m_deltaTime; +} + +float Q3DSQmlScript::getAttribute(const QString &attribute) +{ + if (!m_behavior.GetActive()) + return 0; + + float floatValue = 0; + m_api.GetAttribute(m_owner.m_Path, + attribute.toUtf8().constData(), + (char *)&floatValue); + return floatValue; +} + +void Q3DSQmlScript::setAttribute(const QString &attribute, const QVariant &value) +{ + setAttribute("", attribute, value); +} + +void Q3DSQmlScript::setAttribute(const QString &handle, const QString &attribute, + const QVariant &value) +{ + if (!m_behavior.GetActive()) + return; + + TElement *element = &m_owner; + if (!handle.isEmpty()) + element = getElementByPath(handle); + if (!element) + return; + + QByteArray valueStr; + float valueFloat; + + const char *valuePtr = nullptr; + switch (static_cast(value.type())) { + case QMetaType::Bool: + case QMetaType::Int: + case QMetaType::Double: + case QMetaType::Float: + valueFloat = value.toFloat(); + valuePtr = (const char *)&valueFloat; + break; + case QMetaType::QString: + default: + valueStr = value.toString().toUtf8(); + valuePtr = valueStr.constData(); + break; + } + + m_api.SetAttribute(element->m_Path, + attribute.toUtf8().constData(), + valuePtr); +} + +void Q3DSQmlScript::fireEvent(const QString &event) +{ + if (!m_behavior.GetActive()) + return; + m_api.FireEvent(m_behavior.m_Path, event.toUtf8().constData()); +} + +void Q3DSQmlScript::registerForEvent(const QString &event, const QJSValue &function) +{ + registerForEvent("", event, function); +} + +void Q3DSQmlScript::registerForEvent(const QString &handle, const QString &event, + const QJSValue &function) +{ + if (!m_behavior.GetActive()) + return; + + TElement *element = &m_owner; + if (!handle.isEmpty()) + element = getElementByPath(handle); + if (!element) + return; + + if (!function.isCallable()) + return; + + CPresentation *presentation + = static_cast(m_behavior.GetBelongedPresentation()); + TEventCommandHash eventHash = CHash::HashEventCommand(event.toUtf8().constData()); + + for (auto &&callback : m_eventCallbacks) { + if (callback.element == element && callback.eventHash == eventHash) + return; + } + + EventData *data = new EventData(); + data->function = function; + + m_eventCallbacks.push_back({element, eventHash, data}); + + presentation->RegisterEventCallback(element, eventHash, &eventCallback, data); +} + +void Q3DSQmlScript::unregisterForEvent(const QString &event) +{ + unregisterForEvent("", event); +} + +void Q3DSQmlScript::unregisterForEvent(const QString &handle, const QString &event) +{ + if (!m_behavior.GetActive()) + return; + + TElement *element = &m_owner; + if (!handle.isEmpty()) + element = getElementByPath(handle); + if (!element) + return; + + CPresentation *presentation + = static_cast(m_behavior.GetBelongedPresentation()); + TEventCommandHash eventHash = CHash::HashEventCommand(event.toUtf8().constData()); + EventData *data = nullptr; + + for (int i = 0; i < m_eventCallbacks.size(); ++i) { + if (m_eventCallbacks[i].element == element && m_eventCallbacks[i].eventHash == eventHash) { + data = m_eventCallbacks[i].data; + m_eventCallbacks.erase(m_eventCallbacks.begin() + i); + break; + } + } + + if (data) { + presentation->UnregisterEventCallback(element, eventHash, &eventCallback, data); + delete data; + } +} + +QVector2D Q3DSQmlScript::getMousePosition() +{ + CPresentation *presentation + = static_cast(m_behavior.GetBelongedPresentation()); + qt3ds::runtime::IApplication &app = presentation->GetApplication(); + + SInputFrame input = app.GetInputEngine().GetInputFrame(); + if (app.GetPrimaryPresentation()) { + Q3DStudio::SMousePosition position = + app.GetPrimaryPresentation()->GetScene()->WindowToPresentation( + Q3DStudio::SMousePosition(static_cast(input.m_PickX), + static_cast(input.m_PickY))); + + return QVector2D(position.m_X, position.m_Y); + } + return QVector2D(0, 0); +} + +QMatrix4x4 Q3DSQmlScript::calculateGlobalTransform(const QString &handle) +{ + TElement *element = &m_owner; + if (!handle.isEmpty()) + element = getElementByPath(handle); + if (!element) + return QMatrix4x4(); + + RuntimeMatrix transform; + IScene *scene = element->GetBelongedPresentation()->GetScene(); + scene->CalculateGlobalTransform(element, transform); + transform.FlipCoordinateSystem(); + + return QMatrix4x4(&transform.m_Data[0][0]); +} + +QVector3D Q3DSQmlScript::lookAt(const QVector3D &target) +{ + RuntimeVector3 rotation; + + FLOAT theMag = ::sqrtf(target.x() * target.x() + target.z() * target.z()); + FLOAT thePitch = -::atan2f(target.y(), theMag); + FLOAT theYaw = ::atan2f(target.x(), target.z()); + + rotation.Set(thePitch, theYaw, 0.0f); + + return QVector3D(rotation.m_X, rotation.m_Y, rotation.m_Z); +} + +QVector3D Q3DSQmlScript::matrixToEuler(const QMatrix4x4 &matrix) +{ + CEulerAngleConverter converter; + const float *qMatrix = matrix.constData(); + HMatrix hHatrix; + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) + hHatrix[i][j] = qMatrix[j * 4 + i]; + } + EulerAngles eulerAngles = converter.Eul_FromHMatrix(hHatrix, EulOrdYXZs); + return QVector3D(-eulerAngles.y, -eulerAngles.x, -eulerAngles.z); +} + +QString Q3DSQmlScript::getParent(const QString &handle) +{ + TElement *element = &m_owner; + if (!handle.isEmpty()) + element = getElementByPath(handle); + if (!element) + return ""; + + TElement *parent = element->GetParent(); + if (!parent) + return ""; + return parent->m_Path.c_str(); +} + +void Q3DSQmlScript::setDataInputValue(const QString &name, const QVariant &value) +{ + m_api.SetDataInputValue(name, value); +} + +TElement *Q3DSQmlScript::getElementByPath(const QString &path) +{ + if (!m_api.GetApplication()) + return nullptr; + + TElement *element = CQmlElementHelper::GetElement( + *m_api.GetApplication(), + m_api.GetApplication()->GetPrimaryPresentation(), + path.toUtf8().constData(), &m_owner); + return element; +} diff --git a/src/Runtime/Source/runtime/q3dsqmlscript.h b/src/Runtime/Source/runtime/q3dsqmlscript.h new file mode 100644 index 00000000..1049bd86 --- /dev/null +++ b/src/Runtime/Source/runtime/q3dsqmlscript.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DSQMLSCRIPT_H +#define Q3DSQMLSCRIPT_H + +#include +#include +#include +#include +#include +#include + +#include "Qt3DSTypes.h" +#include "Qt3DSKernelTypes.h" +#include "Qt3DSEvent.h" +#include "q3dsqmlbehavior.h" + +namespace Q3DStudio { +class CQmlEngine; + +class Q3DSQmlScript : public QObject +{ + Q_OBJECT +public: + Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, TElement &element, TElement &parent); + ~Q3DSQmlScript(); + + void update(); + void call(const QString &function); + void updateProperties(); + bool hasBehavior(const TElement *behavior); + + float getDeltaTime(); + float getAttribute(const QString &attribute); + void setAttribute(const QString &attribute, const QVariant &value); + void setAttribute(const QString &handle, const QString &attribute, + const QVariant &value); + void fireEvent(const QString &event); + void registerForEvent(const QString &event, const QJSValue &function); + void registerForEvent(const QString &handle, const QString &event, + const QJSValue &function); + void unregisterForEvent(const QString &event); + void unregisterForEvent(const QString &handle, const QString &event); + QVector2D getMousePosition(); + QMatrix4x4 calculateGlobalTransform(const QString &handle); + QVector3D lookAt(const QVector3D &target); + QVector3D matrixToEuler(const QMatrix4x4 &matrix); + QString getParent(const QString &handle); + void setDataInputValue(const QString &name, const QVariant &value); + + struct EventData { + QJSValue function; + }; + +private: + TElement *getElementByPath(const QString &path); + + CQmlEngine &m_api; + Q3DSQmlBehavior &m_object; + TElement &m_behavior; + TElement &m_owner; + + bool m_initialized; + bool m_lastActivationState; + + float m_deltaTime; + TTimeUnit m_lastTime; + struct EventCallbackInfo { + TElement *element; + TEventCommandHash eventHash; + EventData *data; + }; + + QVector m_eventCallbacks; +}; +} + +#endif // Q3DSQMLSCRIPT_H diff --git a/src/Runtime/Source/runtime/q3dsvariantconfig.cpp b/src/Runtime/Source/runtime/q3dsvariantconfig.cpp new file mode 100644 index 00000000..e1fa04c6 --- /dev/null +++ b/src/Runtime/Source/runtime/q3dsvariantconfig.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "q3dsvariantconfig_p.h" + +namespace qt3ds { + +Q3DSVariantConfig::Q3DSVariantConfig() +{ + +} + +Q3DSVariantConfig::~Q3DSVariantConfig() +{ + for (auto str : qAsConst(m_internalVariantList)) + delete str; + m_internalVariantList.clear(); +} + +void Q3DSVariantConfig::setVariantList(const QStringList &variantList) +{ + // Store the QStringList to be returned from the API + m_variantList = variantList; + + for (auto str : qAsConst(m_internalVariantList)) + delete str; + m_internalVariantList.clear(); + + // Build a fixed (in mem location) list of the variant strings + for (auto tag : variantList) + m_internalVariantList.append(new QString(tag)); + + // Parse the variantGroup:variant list to map using the fixed list + m_variantFilter.clear(); + for (auto tag : qAsConst(m_internalVariantList)) { + QStringRef refTag = QStringRef(tag); + int separatorIdx = refTag.indexOf(QLatin1Char(':')); + QStringRef group = refTag.left(separatorIdx); + QStringRef variant = refTag.mid(separatorIdx + 1); + m_variantFilter[group].append(variant); + } +} + +bool Q3DSVariantConfig::isPartOfConfig(const QStringRef &variantAttributes) const +{ + // Variant filter is ignored when it's not defined + // or if the object has no variant attributes + if (m_variantFilter.isEmpty() || variantAttributes.isEmpty()) + return true; + + // Collect all variant tags per group from the element + QHash> groupToVariants; + const QVector variantTags = variantAttributes.split( + QLatin1Char(','), + QString::SkipEmptyParts); + + for (auto tag : variantTags) { + // Break each variantGroup:value to group and value strings + int groupSeparatorIdx = tag.indexOf(QLatin1Char(':')); + QStringRef group = tag.left(groupSeparatorIdx); + + // Only collect variant tags that are relevant to variant filtering + if (m_variantFilter.contains(group)) { + QStringRef variant = tag.mid(groupSeparatorIdx + 1); + groupToVariants[group].append(variant); + } + } + + // If no relevant variant tags found in element, load the element + if (groupToVariants.isEmpty()) + return true; + + // Verify that the element matches the variant filtering per group. + // To match the element must either: + // - Have no variant tag defined for the group + // - Have a matching tag for the group + bool isLoaded = true; + const auto filteredGroups = m_variantFilter.keys(); + for (auto group : filteredGroups) { + const QVector variants = groupToVariants[group]; + const QVector filteredVariants = m_variantFilter[group]; + + if (variants.size() > 0) { + // Check if ANY of the variant values of the element matches ANY + // of the included variants in the filter for this variant group + bool matchesFilter = false; + for (auto variant : variants) + matchesFilter |= filteredVariants.contains(variant); + + isLoaded &= matchesFilter; + } + } + + return isLoaded; +} + +} diff --git a/src/Runtime/Source/runtime/q3dsvariantconfig_p.h b/src/Runtime/Source/runtime/q3dsvariantconfig_p.h new file mode 100644 index 00000000..1905f44a --- /dev/null +++ b/src/Runtime/Source/runtime/q3dsvariantconfig_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef Q3DSVARIANTCONFIG_P_H +#define Q3DSVARIANTCONFIG_P_H + +#include +#include +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of a number of Qt sources files. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +namespace qt3ds { + +class Q3DSVariantConfig +{ +public: + Q3DSVariantConfig(); + ~Q3DSVariantConfig(); + + inline bool operator==(const Q3DSVariantConfig &other) const + { + return (this->m_variantList == other.m_variantList); + } + + inline bool operator!=(const Q3DSVariantConfig &other) const + { + return (this->m_variantList != other.m_variantList); + } + + inline bool isEmpty() const { return m_variantList.isEmpty(); } + + void setVariantList(const QStringList &variantList); + + bool isPartOfConfig(const QStringRef &variantAttributes) const; + + inline const QStringList &variantList() const { return m_variantList; } + +private: + QStringList m_variantList; + QList m_internalVariantList; + QHash> m_variantFilter; +}; + +}; +#endif // Q3DSVARIANTCONFIG_P_H diff --git a/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderKey.h b/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderKey.h new file mode 100644 index 00000000..555c2689 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderKey.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_OFFSCREEN_RENDER_KEY_H +#define QT3DS_OFFSCREEN_RENDER_KEY_H +#include "Qt3DSRender.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" + +namespace qt3ds { +namespace foundation { + + template <> + struct DestructTraits + { + void destruct(CRegisteredString &) {} + }; +} +} + +namespace qt3ds { +namespace render { + struct OffscreenRendererKeyTypes + { + enum Enum { + NoOffscreenRendererKey = 0, + RegisteredString, + VoidPtr, + }; + }; + + template + struct SOffscreenRendererKeyTypeMap + { + }; + template <> + struct SOffscreenRendererKeyTypeMap + { + enum { KeyType = OffscreenRendererKeyTypes::RegisteredString }; + }; + template <> + struct SOffscreenRendererKeyTypeMap + { + enum { KeyType = OffscreenRendererKeyTypes::VoidPtr }; + }; + + struct SOffscreenRendererKeyUnionTraits + { + typedef OffscreenRendererKeyTypes::Enum TIdType; + enum { + TBufferSize = sizeof(CRegisteredString), + }; + + static TIdType getNoDataId() { return OffscreenRendererKeyTypes::NoOffscreenRendererKey; } + + template + static TIdType getType() + { + return (TIdType)SOffscreenRendererKeyTypeMap::KeyType; + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case OffscreenRendererKeyTypes::RegisteredString: + return inVisitor(*NVUnionCast(inData)); + case OffscreenRendererKeyTypes::VoidPtr: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case OffscreenRendererKeyTypes::NoOffscreenRendererKey: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case OffscreenRendererKeyTypes::RegisteredString: + return inVisitor(*NVUnionCast(inData)); + case OffscreenRendererKeyTypes::VoidPtr: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case OffscreenRendererKeyTypes::NoOffscreenRendererKey: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SOffscreenRendererKeyUnionTraits::TBufferSize> + TOffscreenRendererKeyUnionType; + + struct SOffscreenRendererKey : public TOffscreenRendererKeyUnionType + { + typedef TOffscreenRendererKeyUnionType TBase; + SOffscreenRendererKey() {} + SOffscreenRendererKey(const CRegisteredString &str) + : TBase(str) + { + } + SOffscreenRendererKey(void *key) + : TBase(key) + { + } + SOffscreenRendererKey(const SOffscreenRendererKey &other) + : TBase(static_cast(other)) + { + } + SOffscreenRendererKey &operator=(const SOffscreenRendererKey &other) + { + TBase::operator=(other); + return *this; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.cpp b/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.cpp new file mode 100644 index 00000000..7d66c7a3 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.cpp @@ -0,0 +1,498 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSOffscreenRenderManager.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "Qt3DSRenderResourceManager.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSOffscreenRenderKey.h" +#include "foundation/FastAllocator.h" +#include "Qt3DSRenderRenderList.h" +#include "Qt3DSRenderResourceTexture2D.h" +#include "Qt3DSRenderResourceBufferObjects.h" +#include "Qt3DSRendererUtil.h" + +using namespace qt3ds::render; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SOffscreenRendererKey &key) const + { + switch (key.getType()) { + case OffscreenRendererKeyTypes::RegisteredString: + return hash()(key.getData()); + case OffscreenRendererKeyTypes::VoidPtr: + return hash()(reinterpret_cast(key.getData())); + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + bool operator()(const SOffscreenRendererKey &lhs, const SOffscreenRendererKey &rhs) const + { + return lhs == rhs; + } +}; +} + +namespace { + +using eastl::pair; +using eastl::make_pair; + +struct SRendererData : SOffscreenRenderResult +{ + NVAllocatorCallback &m_Allocator; + IResourceManager &m_ResourceManager; + QT3DSU32 m_FrameCount; + bool m_Rendering; + + SRendererData(NVAllocatorCallback &inAllocator, IResourceManager &inResourceManager) + : m_Allocator(inAllocator) + , m_ResourceManager(inResourceManager) + , m_FrameCount(QT3DS_MAX_U32) + , m_Rendering(false) + { + } + ~SRendererData() + { + if (m_Texture) + m_ResourceManager.Release(*m_Texture); + m_Texture = NULL; + } + void Release() { NVDelete(m_Allocator, this); } +}; + +struct SScopedRenderDataRenderMarker +{ + SRendererData &m_Data; + SScopedRenderDataRenderMarker(SRendererData &d) + : m_Data(d) + { + QT3DS_ASSERT(m_Data.m_Rendering == false); + m_Data.m_Rendering = true; + } + ~SScopedRenderDataRenderMarker() { m_Data.m_Rendering = false; } +}; + +struct SRenderDataReleaser +{ + SRendererData *mPtr; + SRenderDataReleaser(SRendererData *inItem) + : mPtr(inItem) + { + } + // Transfer ownership + SRenderDataReleaser(const SRenderDataReleaser &inOther) + : mPtr(inOther.mPtr) + { + const_cast(inOther).mPtr = NULL; + } + + ~SRenderDataReleaser() + { + if (mPtr) + mPtr->Release(); + } +}; +struct SOffscreenRenderManager; + +struct SOffscreenRunnable : public IRenderTask +{ + SOffscreenRenderManager &m_RenderManager; + SRendererData &m_Data; + SOffscreenRendererEnvironment m_DesiredEnvironment; + SOffscreenRunnable(SOffscreenRenderManager &rm, SRendererData &data, + SOffscreenRendererEnvironment env) + : m_RenderManager(rm) + , m_Data(data) + , m_DesiredEnvironment(env) + { + } + void Run() override; +}; + +struct SOffscreenRenderManager : public IOffscreenRenderManager +{ + typedef nvhash_map TRendererMap; + IQt3DSRenderContext &m_Context; + NVAllocatorCallback &m_Allocator; + NVScopedRefCounted m_StringTable; + NVScopedRefCounted m_ResourceManager; + TRendererMap m_Renderers; + SFastAllocator<> m_PerFrameAllocator; + QT3DSU32 m_FrameCount; // cheap per- + + volatile QT3DSI32 mRefCount; + + SOffscreenRenderManager(NVAllocatorCallback &inCallback, IStringTable &inStringTable, + IResourceManager &inManager, IQt3DSRenderContext &inContext) + : m_Context(inContext) + , m_Allocator(inCallback) + , m_StringTable(inStringTable) + , m_ResourceManager(inManager) + , m_Renderers(inCallback, "SOffscreenRenderManager::m_Renderers") + , m_PerFrameAllocator(inCallback, "m_PerFrameAllocator") + , m_FrameCount(0) + , mRefCount(0) + { + } + + virtual ~SOffscreenRenderManager() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Allocator) + + Option MaybeRegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, + IOffscreenRenderer &inRenderer) override + { + TRendererMap::iterator theIter = m_Renderers.find(inKey); + if (theIter != m_Renderers.end()) { + SRendererData &theData = *(theIter->second.mPtr); + if (theData.m_Renderer != &inRenderer) { + if (inKey.getType() == OffscreenRendererKeyTypes::RegisteredString) { + qCCritical(INVALID_OPERATION, "Different renderers registered under same key: %s", + inKey.getData().c_str()); + } + QT3DS_ASSERT(false); + return Empty(); + } + return false; + } + RegisterOffscreenRenderer(inKey, inRenderer); + return true; + } + + void RegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, + IOffscreenRenderer &inRenderer) override + { + pair theInsert = m_Renderers.insert( + make_pair(inKey, QT3DS_NEW(m_Allocator, SRendererData)(m_Allocator, *m_ResourceManager))); + QT3DS_ASSERT(theInsert.second); + SRendererData &theData = *(theInsert.first->second.mPtr); + theData.m_Renderer = &inRenderer; + } + + bool HasOffscreenRenderer(const SOffscreenRendererKey &inKey) override + { + return m_Renderers.find(inKey) != m_Renderers.end(); + } + + IOffscreenRenderer *GetOffscreenRenderer(const SOffscreenRendererKey &inKey) override + { + TRendererMap::iterator theRenderer = m_Renderers.find(inKey); + if (theRenderer != m_Renderers.end()) { + SRendererData &theData = *theRenderer->second.mPtr; + return theData.m_Renderer; + } + return NULL; + } + void ReleaseOffscreenRenderer(const SOffscreenRendererKey &inKey) override + { + m_Renderers.erase(inKey); + } + + void RenderItem(SRendererData &theData, SOffscreenRendererEnvironment theDesiredEnvironment) + { + NVRenderContext &theContext = m_ResourceManager->GetRenderContext(); + QT3DSVec2 thePresScaleFactor = m_Context.GetPresentationScaleFactor(); + SOffscreenRendererEnvironment theOriginalDesiredEnvironment(theDesiredEnvironment); + // Ensure that our overall render context comes back no matter what the client does. + qt3ds::render::NVRenderContextScopedProperty __clearColor( + theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, + QT3DSVec4(0, 0, 0, 0)); + qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled, false); + qt3ds::render::NVRenderContextScopedProperty __scissorRect( + theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); + qt3ds::render::NVRenderContextScopedProperty __viewportRect( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); + qt3ds::render::NVRenderContextScopedProperty __depthWrite( + theContext, &NVRenderContext::IsDepthWriteEnabled, + &NVRenderContext::SetDepthWriteEnabled, false); + qt3ds::render::NVRenderContextScopedProperty __depthFunction( + theContext, &NVRenderContext::GetDepthFunction, &NVRenderContext::SetDepthFunction, + qt3ds::render::NVRenderBoolOp::Less); + qt3ds::render::NVRenderContextScopedProperty __blendEnabled( + theContext, &NVRenderContext::IsBlendingEnabled, &NVRenderContext::SetBlendingEnabled, + false); + qt3ds::render::NVRenderContextScopedProperty + __blendFunction(theContext, &NVRenderContext::GetBlendFunction, + &NVRenderContext::SetBlendFunction, + qt3ds::render::NVRenderBlendFunctionArgument()); + qt3ds::render::NVRenderContextScopedProperty + __blendEquation(theContext, &NVRenderContext::GetBlendEquation, + &NVRenderContext::SetBlendEquation, + qt3ds::render::NVRenderBlendEquationArgument()); + qt3ds::render::NVRenderContextScopedProperty + __rendertarget(theContext, &NVRenderContext::GetRenderTarget, + &NVRenderContext::SetRenderTarget); + + QT3DSU32 theSampleCount = 1; + bool isMultisamplePass = false; + if (theDesiredEnvironment.m_MSAAMode != AAModeValues::NoAA) { + switch (theDesiredEnvironment.m_MSAAMode) { + case AAModeValues::SSAA: + theSampleCount = 1; + isMultisamplePass = true; + break; + case AAModeValues::X2: + theSampleCount = 2; + isMultisamplePass = true; + break; + case AAModeValues::X4: + theSampleCount = 4; + isMultisamplePass = true; + break; + case AAModeValues::X8: + theSampleCount = 8; + isMultisamplePass = true; + break; + default: + QT3DS_ASSERT(false); + break; + }; + + // adjust render size for SSAA + if (theDesiredEnvironment.m_MSAAMode == AAModeValues::SSAA) { + CRendererUtil::GetSSAARenderSize( + theOriginalDesiredEnvironment.m_Width, theOriginalDesiredEnvironment.m_Height, + theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height); + } + } + CResourceFrameBuffer theFrameBuffer(*m_ResourceManager); + theFrameBuffer.EnsureFrameBuffer(); + NVRenderTexture2D *renderTargetTexture(theData.m_Texture); + qt3ds::render::NVRenderTextureTargetType::Enum fboAttachmentType = + qt3ds::render::NVRenderTextureTargetType::Texture2D; + if (isMultisamplePass) { + renderTargetTexture = NULL; + if (theSampleCount > 1) + fboAttachmentType = qt3ds::render::NVRenderTextureTargetType::Texture2D_MS; + } + + CResourceTexture2D renderColorTexture(*m_ResourceManager, renderTargetTexture); + + CResourceTexture2D renderDepthStencilTexture(*m_ResourceManager); + + if (theSampleCount > 1) + m_Context.GetRenderContext().SetMultisampleEnabled(true); + + qt3ds::render::NVRenderClearFlags theClearFlags; + NVRenderTextureFormats::Enum theDepthStencilTextureFormat(NVRenderTextureFormats::Unknown); + NVRenderFrameBufferAttachments::Enum theAttachmentLocation( + NVRenderFrameBufferAttachments::Unknown); + if (theDesiredEnvironment.m_Stencil) { + theDepthStencilTextureFormat = NVRenderTextureFormats::Depth24Stencil8; + theAttachmentLocation = NVRenderFrameBufferAttachments::DepthStencil; + } else if (theDesiredEnvironment.m_Depth != OffscreenRendererDepthValues::NoDepthBuffer) { + theAttachmentLocation = NVRenderFrameBufferAttachments::Depth; + switch (theDesiredEnvironment.m_Depth) { + case OffscreenRendererDepthValues::Depth16: + theDepthStencilTextureFormat = NVRenderTextureFormats::Depth16; + break; + case OffscreenRendererDepthValues::Depth24: + theDepthStencilTextureFormat = NVRenderTextureFormats::Depth24; + break; + case OffscreenRendererDepthValues::Depth32: + theDepthStencilTextureFormat = NVRenderTextureFormats::Depth32; + break; + default: + theAttachmentLocation = NVRenderFrameBufferAttachments::Unknown; + theDepthStencilTextureFormat = NVRenderTextureFormats::Unknown; + break; + } + } + renderColorTexture.EnsureTexture(theDesiredEnvironment.m_Width, + theDesiredEnvironment.m_Height, + theDesiredEnvironment.m_Format, theSampleCount); + theFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *renderColorTexture, + fboAttachmentType); + + if (theDepthStencilTextureFormat != NVRenderTextureFormats::Unknown) { + renderDepthStencilTexture.EnsureTexture(theDesiredEnvironment.m_Width, + theDesiredEnvironment.m_Height, + theDepthStencilTextureFormat, theSampleCount); + theFrameBuffer->Attach(theAttachmentLocation, *renderDepthStencilTexture, + fboAttachmentType); + } + // IsComplete check takes a really long time so I am not going to worry about it for now. + + theContext.SetRenderTarget(theFrameBuffer); + theContext.SetViewport( + NVRenderRect(0, 0, theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height)); + theContext.SetScissorTestEnabled(false); + + theContext.SetBlendingEnabled(false); + theData.m_Renderer->Render(theDesiredEnvironment, theContext, thePresScaleFactor, + SScene::AlwaysClear, this); + + if (theSampleCount > 1) { + CResourceTexture2D theResult(*m_ResourceManager, theData.m_Texture); + + if (theDesiredEnvironment.m_MSAAMode != AAModeValues::SSAA) { + // Have to downsample the FBO. + CRendererUtil::ResolveMutisampleFBOColorOnly( + *m_ResourceManager, theResult, m_Context.GetRenderContext(), + theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height, + theDesiredEnvironment.m_Format, *theFrameBuffer); + + m_Context.GetRenderContext().SetMultisampleEnabled(false); + } else { + // Resolve the FBO to the layer texture + CRendererUtil::ResolveSSAAFBOColorOnly( + *m_ResourceManager, theResult, theOriginalDesiredEnvironment.m_Width, + theOriginalDesiredEnvironment.m_Height, m_Context.GetRenderContext(), + theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height, + theDesiredEnvironment.m_Format, *theFrameBuffer); + } + + QT3DS_ASSERT(theData.m_Texture == theResult.GetTexture()); + theResult.ForgetTexture(); + } else { + renderColorTexture.ForgetTexture(); + } + theFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer(), fboAttachmentType); + if (theAttachmentLocation != NVRenderFrameBufferAttachments::Unknown) + theFrameBuffer->Attach(theAttachmentLocation, NVRenderTextureOrRenderBuffer(), + fboAttachmentType); + } + + SOffscreenRenderResult GetRenderedItem(const SOffscreenRendererKey &inKey) override + { + TRendererMap::iterator theRenderer = m_Renderers.find(inKey); + QT3DSVec2 thePresScaleFactor = m_Context.GetPresentationScaleFactor(); + if (theRenderer != m_Renderers.end() && theRenderer->second.mPtr->m_Rendering == false) { + SRendererData &theData = *theRenderer->second.mPtr; + SScopedRenderDataRenderMarker __renderMarker(theData); + + bool renderedThisFrame = theData.m_Texture && theData.m_FrameCount == m_FrameCount; + theData.m_FrameCount = m_FrameCount; + // Two different quick-out pathways. + if (renderedThisFrame) + return theData; + + SOffscreenRendererEnvironment theDesiredEnvironment = + theData.m_Renderer->GetDesiredEnvironment(thePresScaleFactor); + // Ensure we get a valid width and height + theDesiredEnvironment.m_Width = + ITextRenderer::NextMultipleOf4(theDesiredEnvironment.m_Width); + theDesiredEnvironment.m_Height = + ITextRenderer::NextMultipleOf4(theDesiredEnvironment.m_Height); + if (theDesiredEnvironment.m_Width == 0 || theDesiredEnvironment.m_Height == 0) { + return SOffscreenRenderResult(); + } + + NVRenderRect theViewport(0, 0, theDesiredEnvironment.m_Width, + theDesiredEnvironment.m_Height); + IRenderList &theRenderList(m_Context.GetRenderList()); + NVRenderContext &theContext(m_Context.GetRenderContext()); + // This happens here because if there are any fancy render steps + SRenderListScopedProperty _scissor(theRenderList, + &IRenderList::IsScissorTestEnabled, + &IRenderList::SetScissorTestEnabled, false); + SRenderListScopedProperty _viewport( + theRenderList, &IRenderList::GetViewport, &IRenderList::SetViewport, theViewport); + // Some plugins don't use the render list so they need the actual gl context setup. + qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled, false); + qt3ds::render::NVRenderContextScopedProperty __viewportRect( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, + theViewport); + + QT3DSU32 taskId = m_Context.GetRenderList().AddRenderTask( + *QT3DS_NEW(m_Context.GetPerFrameAllocator(), + SOffscreenRunnable)(*this, theData, theDesiredEnvironment)); + + SOffscreenRenderFlags theFlags = + theData.m_Renderer->NeedsRender(theDesiredEnvironment, thePresScaleFactor, this); + theData.m_HasTransparency = theFlags.m_HasTransparency; + theData.m_HasChangedSinceLastFrame = theFlags.m_HasChangedSinceLastFrame; + if (theData.m_Texture) { + // Quick-out if the renderer doesn't need to render itself. + if (theData.m_HasChangedSinceLastFrame == false) { + m_Context.GetRenderList().DiscardRenderTask(taskId); + return theData; + } + } else + theData.m_HasChangedSinceLastFrame = true; + + // Release existing texture if it doesn't match latest environment request. + if (theData.m_Texture) { + STextureDetails theDetails = theData.m_Texture->GetTextureDetails(); + if (theDesiredEnvironment.m_Width != theDetails.m_Width + || theDesiredEnvironment.m_Height != theDetails.m_Height + || theDesiredEnvironment.m_Format != theDetails.m_Format) { + m_ResourceManager->Release(*theData.m_Texture); + theData.m_Texture = NULL; + } + } + + if (theData.m_Texture == NULL) + theData.m_Texture = m_ResourceManager->AllocateTexture2D( + theDesiredEnvironment.m_Width, theDesiredEnvironment.m_Height, + theDesiredEnvironment.m_Format); + + // Add the node to the graph and get on with it. + + return theData; + } + return SOffscreenRenderResult(); + } + + void BeginFrame() override { m_PerFrameAllocator.reset(); } + void EndFrame() override { ++m_FrameCount; } +}; + +void SOffscreenRunnable::Run() +{ + m_RenderManager.RenderItem(m_Data, m_DesiredEnvironment); +} +} + +IOffscreenRenderManager &IOffscreenRenderManager::CreateOffscreenRenderManager( + NVAllocatorCallback &inCallback, IStringTable &inStringTable, IResourceManager &inManager, + IQt3DSRenderContext &inContext) +{ + return *QT3DS_NEW(inCallback, SOffscreenRenderManager)(inCallback, inStringTable, inManager, + inContext); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.h b/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.h new file mode 100644 index 00000000..57dcf430 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSOffscreenRenderManager.h @@ -0,0 +1,256 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_OFFSCREEN_RENDER_MANAGER_H +#define QT3DS_OFFSCREEN_RENDER_MANAGER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSOption.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderLayer.h" + +namespace qt3ds { +namespace render { + class IResourceManager; + struct Qt3DSRenderPickResult; + class IGraphObjectPickQuery; + struct OffscreenRendererDepthValues + { + enum Enum { + NoDepthBuffer = 0, + Depth16, // 16 bit depth buffer + Depth24, // 24 bit depth buffer + Depth32, // 32 bit depth buffer + Depth24Stencil8 // 24 bit depth buffer 8 bit stencil buffer + }; + }; + + struct SOffscreenRendererEnvironment + { + QT3DSU32 m_Width; + QT3DSU32 m_Height; + NVRenderTextureFormats::Enum m_Format; + OffscreenRendererDepthValues::Enum m_Depth; + bool m_Stencil; + AAModeValues::Enum m_MSAAMode; + + SOffscreenRendererEnvironment() + : m_Width(0) + , m_Height(0) + , m_Format(NVRenderTextureFormats::Unknown) + , m_Depth(OffscreenRendererDepthValues::NoDepthBuffer) + , m_Stencil(false) + , m_MSAAMode(AAModeValues::NoAA) + { + } + + SOffscreenRendererEnvironment(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inFormat) + : m_Width(inWidth) + , m_Height(inHeight) + , m_Format(inFormat) + , m_Depth(OffscreenRendererDepthValues::Depth16) + , m_Stencil(false) + , m_MSAAMode(AAModeValues::NoAA) + { + } + + SOffscreenRendererEnvironment(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inFormat, + OffscreenRendererDepthValues::Enum inDepth, bool inStencil, + AAModeValues::Enum inAAMode) + : m_Width(inWidth) + , m_Height(inHeight) + , m_Format(inFormat) + , m_Depth(inDepth) + , m_Stencil(inStencil) + , m_MSAAMode(inAAMode) + { + } + + SOffscreenRendererEnvironment(const SOffscreenRendererEnvironment &inOther) + : m_Width(inOther.m_Width) + , m_Height(inOther.m_Height) + , m_Format(inOther.m_Format) + , m_Depth(inOther.m_Depth) + , m_Stencil(inOther.m_Stencil) + , m_MSAAMode(inOther.m_MSAAMode) + { + } + }; + + struct SOffscreenRenderFlags + { + bool m_HasTransparency; + bool m_HasChangedSinceLastFrame; + SOffscreenRenderFlags() + : m_HasTransparency(false) + , m_HasChangedSinceLastFrame(false) + { + } + + SOffscreenRenderFlags(bool transparency, bool hasChanged) + : m_HasTransparency(transparency) + , m_HasChangedSinceLastFrame(hasChanged) + { + } + }; + + typedef void *SRenderInstanceId; + + class IOffscreenRenderer : public NVRefCounted + { + public: + class IOffscreenRendererCallback + { + public: + virtual void onOffscreenRendererInitialized(const QString &id) = 0; + virtual void onOffscreenRendererFrame(const QString &id) = 0; + protected: + virtual ~IOffscreenRendererCallback() {} + }; + + protected: + virtual ~IOffscreenRenderer() {} + public: + virtual void addCallback(IOffscreenRendererCallback *cb) = 0; + // Arbitrary const char* returned to indicate the type of this renderer + // Can be overloaded to form the basis of an RTTI type system. + // Not currently used by the rendering system. + virtual CRegisteredString GetOffscreenRendererType() = 0; + virtual SOffscreenRendererEnvironment + GetDesiredEnvironment(QT3DSVec2 inPresentationScaleFactor) = 0; + // Returns true of this object needs to be rendered, false if this object is not dirty + virtual SOffscreenRenderFlags + NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, + QT3DSVec2 inPresentationScaleFactor, + const SRenderInstanceId instanceId) = 0; + // Returns true if the rendered result image has transparency, or false + // if it should be treated as a completely opaque image. + // It is the IOffscreenRenderer's job to clear any buffers (color, depth, stencil) that it + // needs to. It should not assume that it's buffers are clear; + // Sometimes we scale the width and height of the main presentation in order to fit a + // window. + // If we do so, the scale factor tells the subpresentation renderer how much the system has + // scaled. + virtual void Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, + SScene::RenderClearCommand inColorBufferNeedsClear, + const SRenderInstanceId instanceId) = 0; + virtual void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, + SScene::RenderClearCommand inColorBufferNeedsClear, + QT3DSVec3 inclearColor, + const SRenderInstanceId instanceId) = 0; + + // Implementors should implement one of the two interfaces below. + + // If this renderer supports picking that can return graph objects + // then return an interface here. + virtual IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId instanceId) = 0; + + // If you *don't* support the GraphObjectPickIterator interface, then you should implement + // this interface + // The system will just ask you to pick. + // If you return true, then we will assume that you swallowed the pick and will continue no + // further. + // else we will assume you did not and will continue the picking algorithm. + virtual bool Pick(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, + const SRenderInstanceId instanceId) = 0; + }; + + struct SOffscreenRenderResult + { + NVScopedRefCounted m_Renderer; + NVRenderTexture2D *m_Texture; + bool m_HasTransparency; + bool m_HasChangedSinceLastFrame; + + SOffscreenRenderResult(IOffscreenRenderer &inRenderer, NVRenderTexture2D &inTexture, + bool inTrans, bool inDirty) + : m_Renderer(&inRenderer) + , m_Texture(&inTexture) + , m_HasTransparency(inTrans) + , m_HasChangedSinceLastFrame(inDirty) + { + } + SOffscreenRenderResult() + : m_Renderer(NULL) + , m_Texture(NULL) + , m_HasTransparency(false) + , m_HasChangedSinceLastFrame(false) + { + } + }; + + struct SOffscreenRendererKey; + + /** + * The offscreen render manager attempts to satisfy requests for a given image under a given + *key. + * Renderers are throttled such that they render at most once per frame and potentially less + *than + * that if they don't require a new render. + */ + class IOffscreenRenderManager : public NVRefCounted + { + protected: + virtual ~IOffscreenRenderManager() {} + public: + // returns true if the renderer has not been registered. + // No return value means there was an error registering this id. + virtual Option MaybeRegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, + IOffscreenRenderer &inRenderer) = 0; + virtual void RegisterOffscreenRenderer(const SOffscreenRendererKey &inKey, + IOffscreenRenderer &inRenderer) = 0; + virtual bool HasOffscreenRenderer(const SOffscreenRendererKey &inKey) = 0; + virtual IOffscreenRenderer *GetOffscreenRenderer(const SOffscreenRendererKey &inKey) = 0; + virtual void ReleaseOffscreenRenderer(const SOffscreenRendererKey &inKey) = 0; + + // This doesn't trigger rendering right away. A node is added to the render graph that + // points to this item. + // Thus rendering is deffered until the graph is run but we promise to render to this + // resource. + virtual SOffscreenRenderResult GetRenderedItem(const SOffscreenRendererKey &inKey) = 0; + // Called by the UICRenderContext, clients don't need to call this. + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; + + static IOffscreenRenderManager & + CreateOffscreenRenderManager(NVAllocatorCallback &inCallback, IStringTable &inStringTable, + IResourceManager &inManager, IQt3DSRenderContext &inContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.cpp b/src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.cpp new file mode 100644 index 00000000..4028373b --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSOldNBustedRenderPlugin.h" +#include "SystemPrefix.h" +#include "Qt3DSDLLManager.h" +#include "render/Qt3DSRenderContext.h" + +#ifdef WIN32 +#pragma warning(disable : 4355) // this used in initializer list. I have never seen this result in + // a physical error +#endif + +namespace qt3ds { +namespace render { + + COldNBustedPluginRenderer::COldNBustedPluginRenderer(IQt3DSRenderContext &inRenderContext, + long inDLLHandle) + : m_RenderContext(inRenderContext) + , m_DLLHandle(inDLLHandle) + , mRefCount(0) + , m_OffscreenRendererType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) + { + if (m_DLLHandle != -1) { + Q3DStudio::CDLLManager &theManager = Q3DStudio::CDLLManager::GetDLLManager(); + + // Grab function procs + m_GetTextureSizeProc = reinterpret_cast( + theManager.GetProc("GetDesiredTextureSize", m_DLLHandle)); + Q3DStudio_ASSERT(m_GetTextureSizeProc); + + m_RenderProc = reinterpret_cast(theManager.GetProc("Render", m_DLLHandle)); + Q3DStudio_ASSERT(m_RenderProc); + } + } + + NVRenderTextureFormats::Enum convertTextureFormat(ETEXTUREFORMAT fmt) + { + NVRenderTextureFormats::Enum ret = NVRenderTextureFormats::RGBA8; + switch (fmt) { + + case ETEXTUREFORMAT_RGBA8: + break; + + case ETEXTUREFORMAT_RGB8: + ret = NVRenderTextureFormats::RGB8; + break; + + default: + break; + + } + return ret; + } + + SOffscreenRendererEnvironment + COldNBustedPluginRenderer::GetDesiredEnvironment(QT3DSVec2 inPresScale) + { + long width, height; + ETEXTUREFORMAT format; + + m_GetTextureSizeProc(&width, &height, &format); + + return SOffscreenRendererEnvironment( + (QT3DSU32)(width * inPresScale.x), (QT3DSU32)(height * inPresScale.y), + convertTextureFormat(format), OffscreenRendererDepthValues::Depth24, false, + AAModeValues::NoAA); + } + + SOffscreenRenderFlags + COldNBustedPluginRenderer::NeedsRender(const SOffscreenRendererEnvironment & /*inEnvironment*/, + QT3DSVec2 /*inPresScale*/, + const SRenderInstanceId) + { + return SOffscreenRenderFlags(true, true); + } + + // Returns true if the rendered result image has transparency, or false + // if it should be treated as a completely opaque image. + void COldNBustedPluginRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 /*inPresScale*/, + SScene::RenderClearCommand /*inClearColorBuffer*/, + const SRenderInstanceId) + { + inRenderContext.PushPropertySet(); + + m_RenderProc(inEnvironment.m_Width, inEnvironment.m_Height, 1); + + inRenderContext.PopPropertySet(true); + } +} +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.h b/src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.h new file mode 100644 index 00000000..86f20a78 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSOldNBustedRenderPlugin.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_OLD_N_BUSTED_RENDER_PLUGIN_H +#define QT3DS_OLD_N_BUSTED_RENDER_PLUGIN_H + +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSRenderContextCore.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "Qt3DSPluginDLL.h" + +namespace qt3ds { +namespace render { + + class COldNBustedPluginRenderer; + + class COldNBustedPluginRenderer : public IOffscreenRenderer + { + public: + IQt3DSRenderContext &m_RenderContext; + long m_DLLHandle; + volatile QT3DSI32 mRefCount; + SOffscreenRendererEnvironment m_LastRenderedEnvironment; + CRegisteredString m_OffscreenRendererType; + + PROC_GetDesiredTextureSize m_GetTextureSizeProc; + PROC_Render m_RenderProc; + + COldNBustedPluginRenderer(IQt3DSRenderContext &inRenderContext, long inDLLHandle); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) + + SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresScale) override; + virtual SOffscreenRenderFlags + NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, QT3DSVec2 inPresScale, + const SRenderInstanceId instanceId) override; + void Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext & /*inRenderContext*/, + QT3DSVec2 inPresScale, SScene::RenderClearCommand inClearBuffer, + const SRenderInstanceId instanceId) override; + void RenderWithClear(const SOffscreenRendererEnvironment &/*inEnvironment*/, + NVRenderContext &/*inRenderContext*/, + QT3DSVec2 /*inPresentationScaleFactor*/, + SScene::RenderClearCommand /*inColorBufferNeedsClear*/, + QT3DSVec3 /*inclearColor*/, + const SRenderInstanceId /*instanceId*/) override {} + IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId instanceId) override + { + Q_UNUSED(instanceId); + return NULL; + } + bool Pick(const QT3DSVec2 & /*inMouseCoords*/, const QT3DSVec2 & /*inViewportDimensions*/, + const SRenderInstanceId instanceId) override + { + Q_UNUSED(instanceId); + return false; + } + void addCallback(IOffscreenRendererCallback *cb) override + { + + } + // Used for RTTI purposes so we can safely static-cast an offscreen renderer to a + // CPluginRenderer + static const char *GetRendererName() { return "Plugin"; } + CRegisteredString GetOffscreenRendererType() override { return m_OffscreenRendererType; } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSOnscreenTextRenderer.cpp b/src/Runtime/Source/runtimerender/Qt3DSOnscreenTextRenderer.cpp new file mode 100644 index 00000000..4b74c511 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSOnscreenTextRenderer.cpp @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#define QT3DS_RENDER_ONSCREEN_TEXT +#ifdef QT3DS_RENDER_ONSCREEN_TEXT + +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderTextureAtlas.h" + +#include "EASTL/string.h" +#include "EASTL/hash_set.h" + +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StrConvertUTF.h" + +#include "render/Qt3DSRenderContext.h" + +#include +#include +#include +#include + +using namespace qt3ds::render; + +namespace { + +struct STextureAtlasFontEntry +{ + STextureAtlasFontEntry() + : m_x(0) + , m_y(0) + , m_width(0) + , m_height(0) + , m_xOffset(0) + , m_yOffset(0) + , m_advance(0) + , m_s(0) + , m_t(0) + , m_s1(0) + , m_t1(0) + { + } + + STextureAtlasFontEntry(float x, float y, float width, float height, float xoffset, + float yoffset, float advance, float s, float t, float s1, float t1) + : m_x(x) + , m_y(y) + , m_width(width) + , m_height(height) + , m_xOffset(xoffset) + , m_yOffset(yoffset) + , m_advance(advance) + , m_s(s) + , m_t(t) + , m_s1(s1) + , m_t1(t1) + { + } + + QT3DSF32 m_x; + QT3DSF32 m_y; + QT3DSF32 m_width; + QT3DSF32 m_height; + QT3DSF32 m_xOffset; + QT3DSF32 m_yOffset; + QT3DSF32 m_advance; + + QT3DSF32 m_s; + QT3DSF32 m_t; + QT3DSF32 m_s1; + QT3DSF32 m_t1; +}; + +typedef eastl::basic_string TStrType; +typedef nvhash_map TTextureAtlasMap; + +struct STextAtlasFont +{ + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + QT3DSU32 m_FontSize; + TTextureAtlasMap m_AtlasEntries; ///< our entries in the atlas + + STextAtlasFont(NVFoundationBase &inFoundation, QT3DSU32 fontSize) + : m_Foundation(inFoundation) + , mRefCount(0) + , m_FontSize(fontSize) + , m_AtlasEntries(inFoundation.getAllocator(), + "Qt3DSOnscreenRenderer::STextAtlasFont::m_AtlasEntrys") + { + } + + ~STextAtlasFont() { m_AtlasEntries.clear(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + static STextAtlasFont &CreateTextureAtlasFont(NVFoundationBase &inFnd, QT3DSU32 fontSize) + { + return *QT3DS_NEW(inFnd.getAllocator(), STextAtlasFont)(inFnd, fontSize); + } +}; + +// This class is only for rendering 2D screen aligned text +// it uses a predefined true type font and character set with various sizes +struct Qt3DSOnscreenTextRenderer : public ITextRenderer +{ + + static const QT3DSI32 TEXTURE_ATLAS_DIM = + 256; // if you change this you need to adjust STextTextureAtlas size as well + +private: + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_RenderContext; + volatile QT3DSI32 mRefCount; + bool m_TextureAtlasInitialized; ///< true if atlas is setup + NVScopedRefCounted m_TextTextureAtlas; + NVScopedRefCounted m_TextFont; + QRawFont *m_font; +public: + Qt3DSOnscreenTextRenderer(NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , mRefCount(0) + , m_TextureAtlasInitialized(false) + , m_font(nullptr) + { + } + + virtual ~Qt3DSOnscreenTextRenderer() + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + void AddSystemFontDirectory(const char8_t *) override {} + + virtual void AddProjectFontDirectory(CRegisteredString) + { + // We always render using the default font with on-screen renderer, + // so no need to care about font directories + } + + void AddProjectFontDirectory(const char8_t *inProjectDirectory) override + { + if (m_RenderContext) + AddProjectFontDirectory( + m_RenderContext->GetStringTable().RegisterStr(inProjectDirectory)); + } + + void loadFont() + { + // Ensure font. We can only render text of single size at the moment. + // Add a size map of fonts if it ever becomes necessary to render multiple font sizes. + if (!m_font) + m_font = new QRawFont(QStringLiteral(":res/Font/TitilliumWeb-Regular.ttf"), 20.0); + + // setup texture atlas + m_TextTextureAtlas = + ITextureAtlas::CreateTextureAtlas(m_RenderContext->GetFoundation(), *m_RenderContext, + TEXTURE_ATLAS_DIM, TEXTURE_ATLAS_DIM); + + // our list of predefined cached characters + QString cache = QStringLiteral(" !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~"); + + m_TextFont = STextAtlasFont::CreateTextureAtlasFont(m_Foundation, 20); + CreateTextureAtlasEntries(m_font, *m_TextFont, cache); + m_TextureAtlasInitialized = true; + } + + void CreateTextureAtlasEntries(QRawFont *rawFont, STextAtlasFont &font, const QString &cache) + { + if (m_TextureAtlasInitialized || !m_TextTextureAtlas || !rawFont) + return; + + STextureAtlasRect theAtlasRect; + + QVector glyphIndices = rawFont->glyphIndexesForString(cache); + QVector glyphAdvances = rawFont->advancesForGlyphIndexes(glyphIndices); + + for (int i = 0; i < glyphIndices.size(); i++) { + quint32 index = glyphIndices[i]; + QImage glyphImage; + + // blank char is not contained in a true type font + if (cache.at(i) != QChar(' ')) + glyphImage = rawFont->alphaMapForGlyph(index, QRawFont::PixelAntialiasing); + + QRectF rect = rawFont->boundingRect(index); + NVConstDataRef bufferData(static_cast(glyphImage.bits()), + glyphImage.byteCount()); + + theAtlasRect = m_TextTextureAtlas->AddAtlasEntry( + glyphImage.width(), glyphImage.height(), + glyphImage.bytesPerLine(), glyphImage.width(), bufferData); + + if (theAtlasRect.m_Width != 0) { + font.m_AtlasEntries.insert( + eastl::make_pair( + cache.at(i).unicode(), STextureAtlasFontEntry( + (QT3DSF32)theAtlasRect.m_X, (QT3DSF32)theAtlasRect.m_Y, + (QT3DSF32)theAtlasRect.m_Width, (QT3DSF32)theAtlasRect.m_Height, + (QT3DSF32)rect.x(), (QT3DSF32)(0.0 - rect.height() - rect.y()), + glyphAdvances[i].x(), + theAtlasRect.m_NormX, theAtlasRect.m_NormY, + theAtlasRect.m_NormX + theAtlasRect.m_NormWidth, + theAtlasRect.m_NormY + theAtlasRect.m_NormHeight))); + } + } + } + + void ClearProjectFontDirectories() override {} + + ITextRenderer &GetTextRenderer(NVRenderContext &inRenderContext) override + { + m_RenderContext = inRenderContext; + return *this; + } + + void PreloadFonts() override {} + void ReloadFonts() override {} + + // unused + NVConstDataRef GetProjectFontList() override + { + Q_ASSERT(false); + return NVConstDataRef(); + } + + // unused + Option GetFontNameForFont(CRegisteredString) override + { + Q_ASSERT(false); + return Empty(); + } + + // unused + Option GetFontNameForFont(const char8_t *) override + { + Q_ASSERT(false); + return Empty(); + } + + // unused + STextDimensions MeasureText(const STextRenderInfo &, QT3DSF32, const char8_t *) override + { + Q_ASSERT(false); + return STextDimensions(0, 0); + } + + // unused + STextTextureDetails RenderText(const STextRenderInfo &, NVRenderTexture2D &) override + { + QT3DS_ASSERT(false); + return STextTextureDetails(); + } + + // unused + STextTextureDetails RenderText(const STextRenderInfo &, NVRenderPathFontItem &, + NVRenderPathFontSpecification &) override + { + QT3DS_ASSERT(false); + return STextTextureDetails(); + } + + SRenderTextureAtlasDetails RenderText(const STextRenderInfo &inText) override + { + qt3ds::foundation::IStringTable &theStringTable(m_RenderContext->GetStringTable()); + + const wchar_t *wText = theStringTable.GetWideStr(inText.m_Text); + QT3DSU32 length = (QT3DSU32)wcslen(wText); + + if (length) { + STextAtlasFont *pFont = m_TextFont; + const STextureAtlasFontEntry *pEntry; + QT3DSF32 x1, y1, x2, y2; + QT3DSF32 s, t, s1, t1; + QT3DSF32 advance = 0.0; + // allocate buffer for all the vertex data we need + // we construct triangles here + // which means character count x 6 vertices x 5 floats + QT3DSF32 *vertexData = + (QT3DSF32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), + length * 6 * 5 * sizeof(QT3DSF32), + "Qt3DSOnscreenTextRenderer"); + QT3DSF32 *bufPtr = vertexData; + if (vertexData) { + for (size_t i = 0; i < length; ++i) { + pEntry = &pFont->m_AtlasEntries.find(wText[i])->second; + + if (pEntry) { + x1 = advance + pEntry->m_xOffset; + x2 = x1 + pEntry->m_width * inText.m_ScaleX; + y1 = pEntry->m_yOffset; + y2 = y1 + pEntry->m_height * inText.m_ScaleY; + + s = pEntry->m_s; + s1 = pEntry->m_s1; + t = pEntry->m_t; + t1 = pEntry->m_t1; + // store vertex data + bufPtr[0] = x1; + bufPtr[1] = y1; + bufPtr[2] = 0.0; + bufPtr[3] = s; + bufPtr[4] = t; + bufPtr[5] = x2; + bufPtr[6] = y1; + bufPtr[7] = 0.0; + bufPtr[8] = s1; + bufPtr[9] = t; + bufPtr[10] = x2; + bufPtr[11] = y2; + bufPtr[12] = 0.0; + bufPtr[13] = s1; + bufPtr[14] = t1; + + bufPtr[15] = x1; + bufPtr[16] = y1; + bufPtr[17] = 0.0; + bufPtr[18] = s; + bufPtr[19] = t; + bufPtr[20] = x2; + bufPtr[21] = y2; + bufPtr[22] = 0.0; + bufPtr[23] = s1; + bufPtr[24] = t1; + bufPtr[25] = x1; + bufPtr[26] = y2; + bufPtr[27] = 0.0; + bufPtr[28] = s; + bufPtr[29] = t1; + + advance += pEntry->m_advance * inText.m_ScaleX; + + bufPtr += 30; + } + } + + m_TextTextureAtlas->RelaseEntries(); + + return SRenderTextureAtlasDetails(length * 6, + toU8DataRef(vertexData, length * 6 * 5)); + } + } + + return SRenderTextureAtlasDetails(); + } + + STextTextureAtlasEntryDetails RenderAtlasEntry(QT3DSU32 index, + NVRenderTexture2D &inTexture) override + { + if (m_TextTextureAtlas) { + TTextureAtlasEntryAndBuffer theEntry = m_TextTextureAtlas->GetAtlasEntryByIndex(index); + if (theEntry.first.m_Width) { + inTexture.SetTextureData(theEntry.second, 0, theEntry.first.m_Width, + theEntry.first.m_Height, NVRenderTextureFormats::Alpha8); + inTexture.SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + inTexture.SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + inTexture.SetTextureWrapS(qt3ds::render::NVRenderTextureCoordOp::ClampToEdge); + inTexture.SetTextureWrapT(qt3ds::render::NVRenderTextureCoordOp::ClampToEdge); + STextureDetails theTextureDetails = inTexture.GetTextureDetails(); + return STextTextureAtlasEntryDetails(theTextureDetails.m_Width, + theTextureDetails.m_Height, theEntry.first.m_X, + theEntry.first.m_Y); + } + } + + return STextTextureAtlasEntryDetails(); + } + QT3DSI32 CreateTextureAtlas() override + { + loadFont(); + + QT3DSI32 count = 0; + if (m_TextTextureAtlas) + count = m_TextTextureAtlas->GetAtlasEntryCount(); + + return count; + } + + void BeginFrame() override {} + void EndFrame() override {} + void BeginPreloadFonts(IThreadPool &, IPerfTimer &) override {} + void EndPreloadFonts() override {} +}; +} + +ITextRendererCore &ITextRendererCore::CreateOnscreenTextRenderer(NVFoundationBase &inFnd) +{ + return *QT3DS_NEW(inFnd.getAllocator(), Qt3DSOnscreenTextRenderer)(inFnd); +} + +#endif // QT3DS_RENDER_ONSCREEN_TEXT diff --git a/src/Runtime/Source/runtimerender/Qt3DSQtTextRenderer.cpp b/src/Runtime/Source/runtimerender/Qt3DSQtTextRenderer.cpp new file mode 100644 index 00000000..17539e4a --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSQtTextRenderer.cpp @@ -0,0 +1,678 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderText.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" + +#include "foundation/Qt3DSVec2.h" +#include "foundation/FileTools.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderThreadPool.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "EASTL/set.h" +#include "EASTL/list.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace qt3ds::render; + +namespace { + +struct Qt3DSQtTextRenderer : public ITextRenderer +{ + struct FontInfo + { + QString fontFileName; + QString fontName; + QString fontFamily; + int fontId; + QFont font; + + FontInfo() : + fontId(-1) + {} + + FontInfo(const QString &fileName, const QString &name, const QString &family, int id) : + fontFileName(fileName) + , fontName(name) + , fontFamily(family) + , fontId(id) + { + font.setFamily(fontFamily); + } + + FontInfo(const FontInfo &other) : + fontFileName(other.fontFileName) + , fontName(other.fontName) + , fontFamily(other.fontFamily) + , fontId(other.fontId) + , font(other.font) + {} + + FontInfo &operator=(const FontInfo &other) + { + fontFileName = other.fontFileName; + fontName = other.fontName; + fontFamily = other.fontFamily; + fontId = other.fontId; + font = other.font; + + return *this; + } + }; + + typedef eastl::string TStrType; + typedef eastl::set TStringSet; + typedef QHash TFontInfoHash; + + NVFoundationBase &m_foundation; + NVScopedRefCounted m_stringTable; + NVScopedRefCounted m_renderContext; + NVScopedRefCounted m_perfTimer; + volatile QT3DSI32 mRefCount; + nvvector m_installedFonts; + + Sync m_PreloadSync; + + TStringSet m_systemFontDirs; + TStringSet m_projectFontDirs; + TFontInfoHash m_projectFontInfos; + TFontInfoHash m_systemFontInfos; + TStrType m_workspace; + + bool m_systemFontsInitialized; + bool m_projectFontsInitialized; + bool m_PreloadingFonts; + + QStringList m_nameFilters; + qreal m_pixelRatio; + + Qt3DSQtTextRenderer(NVFoundationBase &inFoundation, IStringTable &inStrTable) + : m_foundation(inFoundation) + , m_stringTable(inStrTable) + , mRefCount(0) + , m_installedFonts(inFoundation.getAllocator(), "Qt3DSQtTextRenderer::m_installedFonts") + , m_PreloadSync(inFoundation.getAllocator()) + , m_systemFontsInitialized(false) + , m_projectFontsInitialized(false) + , m_PreloadingFonts(false) + , m_pixelRatio(1.0) + { + const QWindowList list = QGuiApplication::topLevelWindows(); + if (list.size() > 0) + m_pixelRatio = list[0]->devicePixelRatio(); + + m_nameFilters << QStringLiteral("*.ttf"); + m_nameFilters << QStringLiteral("*.otf"); + } + virtual ~Qt3DSQtTextRenderer() + { + QFontDatabase::removeAllApplicationFonts(); + } + + QString stringToQString(const CRegisteredString &str) + { + return QString::fromUtf8(str.c_str()); + } + + QString stringToQString(const eastl::string &str) + { + return QString::fromUtf8(str.c_str()); + } + + QString stringToQString(const char8_t *str) + { + return QString::fromUtf8(str); + } + + CRegisteredString QStringToRegisteredString(const QString &str) + { + return m_stringTable->RegisterStr(str.toUtf8().constData()); + } + + void unregisterProjectFonts() + { + for (FontInfo &fi : m_projectFontInfos.values()) + QFontDatabase::removeApplicationFont(fi.fontId); + m_projectFontsInitialized = false; + m_installedFonts.clear(); + m_projectFontInfos.clear(); + } + + QString getFileStem(const QString &fileName) + { + QString retVal; + int dotPos = fileName.lastIndexOf(QChar('.')); + if (dotPos < 0) + return retVal; + int slashPos = fileName.lastIndexOf(QChar('/')); + retVal = fileName.mid(slashPos + 1); + retVal.chop(fileName.length() - dotPos); + return retVal; + } + + void registerFonts(TStringSet dirSet, TFontInfoHash *fontInfos = nullptr) + { + for (TStringSet::const_iterator theIter = dirSet.begin(), + theEnd = dirSet.end(); + theIter != theEnd; ++theIter) { + QString localDir = CFileTools::NormalizePathForQtUsage(stringToQString(*theIter)); + QDir dir(localDir); + if (!dir.exists()) { + qCCritical(INTERNAL_ERROR) << "Adding font directory:" << localDir; + continue; + } + if (fontInfos) + dir.cd(QStringLiteral("fonts")); + QStringList entryList = dir.entryList(m_nameFilters); + for (QString entry : entryList) { + entry = dir.absoluteFilePath(entry); + QFile file(entry); + if (file.open(QIODevice::ReadOnly)) { + QByteArray rawData = file.readAll(); + int fontId = QFontDatabase::addApplicationFontFromData(rawData); + if (fontId < 0) { + qCWarning(WARNING, "Failed to register font: %s", + entry.toStdString().c_str()); + } else if (fontInfos) { + QString fontName = getFileStem(entry); + QString fontFamily; + QStringList families = QFontDatabase::applicationFontFamilies(fontId); + if (families.size() > 0) + fontFamily = families.at(0); + FontInfo fi(entry, fontName, fontFamily, fontId); + // Detect font style and weight using a dummy QRawFont + QRawFont rawFont(rawData, 1.0); + if (rawFont.isValid()) { + if (rawFont.style() != QFont::StyleOblique) { + fi.font.setStyle(rawFont.style()); + fi.font.setWeight(rawFont.weight()); + } + } else { + qCWarning(WARNING, "Failed to determine font style: %s", + entry.toStdString().c_str()); + } + fontInfos->insert(fontName, fi); + } + } else { + qCWarning(WARNING, "Failed to load font: %s", + entry.toStdString().c_str()); + } + } + } + } + + void projectCleanup() + { + m_projectFontsInitialized = false; + unregisterProjectFonts(); + m_projectFontDirs.clear(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_foundation.getAllocator()) + + eastl::pair AddFontDirectory(const TStrType &inDirectory, TStringSet &inDirSet) + { + if (inDirectory.empty()) { + m_workspace.assign("./"); + } else { + m_workspace.clear(); + for (const char8_t *item = inDirectory.c_str(); item && *item; ++item) { + if (*item == '\\') + m_workspace.append(1, '/'); + else + m_workspace.append(1, static_cast(*item)); + } + if (m_workspace.back() != '/') + m_workspace.append(1, '/'); + } + + return eastl::make_pair(m_workspace, inDirSet.insert(m_workspace).second); + } + + // You can have several standard font directories and these will be persistent + void AddSystemFontDirectory(const char8_t *inDirectory) override + { + AddFontDirectory(inDirectory, m_systemFontDirs); + } + + void AddProjectFontDirectory(const char8_t *inProjectDirectory) override + { + eastl::pair theAddResult = + AddFontDirectory(inProjectDirectory, m_projectFontDirs); + if (theAddResult.second && m_projectFontsInitialized) + ReloadFonts(); + } + + void ReloadFonts() override + { + unregisterProjectFonts(); + PreloadFonts(); + } + + void PreloadFonts() override + { + if (!m_systemFontsInitialized) { + m_systemFontsInitialized = true; + registerFonts(m_systemFontDirs, &m_systemFontInfos); + } + + if (!m_projectFontsInitialized) { + m_projectFontsInitialized = true; + registerFonts(m_projectFontDirs, &m_projectFontInfos); + } + } + + void ClearProjectFontDirectories() override + { + projectCleanup(); + } + + static void PreloadThreadCallback(void *inData) + { + Qt3DSQtTextRenderer *theRenderer(reinterpret_cast(inData)); + theRenderer->PreloadFonts(); + theRenderer->m_PreloadSync.set(); + } + + void BeginPreloadFonts(IThreadPool &inThreadPool, IPerfTimer &inTimer) override + { + m_PreloadingFonts = true; + + m_PreloadSync.reset(); + m_perfTimer = inTimer; + + inThreadPool.AddTask(this, PreloadThreadCallback, NULL); + } + + void EndPreloadFonts() override + { + if (m_PreloadingFonts) { + { + SStackPerfTimer __perfTimer(*m_perfTimer, "QtText: Wait till font preloading completed"); + m_PreloadSync.wait(); + } + } + m_PreloadingFonts = false; + } + + // Get the list of project fonts. These are the only fonts that can be displayed. + NVConstDataRef GetProjectFontList() override + { + PreloadFonts(); + if (m_installedFonts.empty()) { + m_installedFonts.reserve(m_projectFontInfos.size()); + for (FontInfo &fi : m_projectFontInfos.values()) { + m_installedFonts.push_back(SRendererFontEntry( + QStringToRegisteredString(fi.fontName), + QStringToRegisteredString(fi.fontFileName))); + } + } + return m_installedFonts; + } + + Option GetFontNameForFont(CRegisteredString inFontname) override + { + // This function is there to support legacy font names. + + QString inStr = stringToQString(inFontname); + if (m_projectFontInfos.keys().contains(inStr)) + return inFontname; + + // Fall back for family name detection if not found by font name + for (FontInfo &fi : m_projectFontInfos.values()) { + if (inStr == fi.fontFamily) + return QStringToRegisteredString(fi.fontName); + } + + return Empty(); + } + + Option GetFontNameForFont(const char8_t *inFontname) override + { + return GetFontNameForFont(m_stringTable->RegisterStr(inFontname)); + } + + ITextRenderer &GetTextRenderer(NVRenderContext &inRenderContext) override + { + m_renderContext = inRenderContext; + return *this; + } + + FontInfo &fontInfoForName(const CRegisteredString &fontName) + { + PreloadFonts(); + QString qtFontName = stringToQString(fontName); + if (m_projectFontInfos.contains(qtFontName)) + return m_projectFontInfos[qtFontName]; + + if (m_systemFontInfos.contains(qtFontName)) + return m_systemFontInfos[qtFontName]; + + // Unknown font, create a system font for it + FontInfo fi("", qtFontName, qtFontName, -1); + m_systemFontInfos.insert(qtFontName, fi); + + return m_systemFontInfos[qtFontName]; + } + + void updateFontInfo(FontInfo &fi, const STextRenderInfo &inText, + QT3DSF32 inTextScaleFactor = 1.0f) + { + qreal pixelSize = inText.m_FontSize; + fi.font.setPixelSize(pixelSize * inTextScaleFactor); + fi.font.setLetterSpacing(QFont::AbsoluteSpacing, qreal(inText.m_Tracking)); + } + + QStringList splitText(const char8_t *theText) + { + // Split the text into lines + int lines = 1; + int lineLen = 0; + QStringList lineList; + const char8_t *lineStartItem = nullptr; + for (const char8_t *item = theText; item && *item; ++item) { + if (!lineLen) + lineStartItem = item; + ++lineLen; + if (*item == '\n') { + int chopAmount = 1; + if (lineLen > 1 && *(item - 1) == '\r') + ++chopAmount; + + ++lines; + lineList.append(QString::fromUtf8(lineStartItem, lineLen - chopAmount)); + lineLen = 0; + } + } + if (lineStartItem) + lineList.append(QString::fromUtf8(lineStartItem, lineLen)); + + return lineList; + } + + QRectF textBoundingBox(const STextRenderInfo &inText, + const QFontMetricsF &fm, QStringList &lineList, + QVector &lineWidths, const char8_t *inTextOverride = nullptr) + { + const char8_t *theText = inTextOverride ? inTextOverride : inText.m_Text.c_str(); + lineList = splitText(theText); + + QRectF boundingBox; + boundingBox.setHeight(lineList.size() * fm.height() + qCeil(qreal(lineList.size() - 1) * qreal(inText.m_Leading))); + + lineWidths.resize(lineList.size()); + + for (int i = 0; i < lineList.size(); ++i) { + // For italicized fonts the bounding box right is the correct method + // to measure since the left offset may extend, but for + // non-italicized fonts we need the width method to meausure + // otherwise the resultant text will be clipped. + QString line = lineList.at(i); + qreal width = fm.width(line); + qreal right = fm.boundingRect(line).right(); + // For hdpi displays, fontmetrics doesn't always calculate enough space for fonts, so + // we add the pixel ratio to all widths to avoid clipping + qreal lineWidth = qMax(width, right) + m_pixelRatio; + lineWidths[i] = lineWidth; + if (boundingBox.width() < lineWidth) + boundingBox.setWidth(lineWidth); + } + + // We don't want extra letter spacing on the last glyph, so let's remove it + boundingBox.setRight(qMax(boundingBox.left(), boundingBox.right() - qFloor(inText.m_Tracking))); + + return boundingBox; + } + + STextDimensions MeasureText(const STextRenderInfo &inText, QT3DSF32 inTextScaleFactor, + const char8_t *inTextOverride) override + { + FontInfo &fi = fontInfoForName(inText.m_Font); + updateFontInfo(fi, inText, inTextScaleFactor); + QFontMetricsF fm(fi.font); + QStringList dummyList; + QVector dummyWidth; + QRectF boundingBox = textBoundingBox(inText, fm, dummyList, dummyWidth, inTextOverride); + return STextDimensions(boundingBox.width(), boundingBox.height()); + } + + int alignToQtAlign(TextVerticalAlignment::Enum va) + { + int qtAlign(0); + switch (va) { + case TextVerticalAlignment::Top: + qtAlign = Qt::AlignTop; + break; + case TextVerticalAlignment::Bottom: + qtAlign = Qt::AlignBottom; + break; + default: + qtAlign = Qt::AlignVCenter; + } + + return qtAlign; + } + + STextTextureDetails RenderText(const STextRenderInfo &inSrcText, + NVRenderTexture2D &inTexture) override + { + FontInfo &fi = fontInfoForName(inSrcText.m_Font); + updateFontInfo(fi, inSrcText); + QFontMetricsF fm(fi.font); + int horizontalAlignmentFlag = Qt::AlignLeft; + + int shadowRgb = int(2.55f * (100 - int(inSrcText.m_DropShadowStrength))); + QStringList lineList; + QVector lineWidths; + QRectF boundingBox; + const bool dynamicTextArea = inSrcText.m_BoundingBox.isZero(); + + if (dynamicTextArea) { + boundingBox = textBoundingBox(inSrcText, fm, lineList, lineWidths); + } else { + lineList << inSrcText.m_Text.c_str(); + lineWidths << inSrcText.m_BoundingBox.x; + boundingBox = QRectF(0, 0, inSrcText.m_BoundingBox.x, inSrcText.m_BoundingBox.y); + } + + if (boundingBox.width() <= 0 || boundingBox.height() <= 0) { + return ITextRenderer::UploadData(toU8DataRef((char *)nullptr, 0), inTexture, 4, 4, + 0, 0, + NVRenderTextureFormats::RGBA8, true); + } + + int finalWidth = NextMultipleOf4(boundingBox.width()); + int finalHeight = NextMultipleOf4(boundingBox.height()); + + QImage image(finalWidth, finalHeight, QImage::Format_ARGB32); + image.fill(0); + QPainter painter(&image); + painter.setPen(Qt::white); + painter.setFont(fi.font); + + // Translate painter to remove the extra spacing of the last letter + qreal tracking = 0.0; + switch (inSrcText.m_HorizontalAlignment) { + case TextHorizontalAlignment::Center: + horizontalAlignmentFlag = Qt::AlignHCenter; + tracking += qreal(inSrcText.m_Tracking / 2.0f); + break; + case TextHorizontalAlignment::Right: + horizontalAlignmentFlag = Qt::AlignRight; + tracking += qreal(inSrcText.m_Tracking); + break; + default: + break; // Do nothing + } + + qreal shadowOffsetX = qreal(inSrcText.m_FontSize * inSrcText.m_DropShadowOffsetX) / 1000.; + qreal shadowOffsetY = qreal(inSrcText.m_FontSize * inSrcText.m_DropShadowOffsetY) / 1000.; + // To be removed in 2.x (when UIP version is next updated) + if (inSrcText.m_DropShadow && shadowOffsetX == 0. && shadowOffsetY == 0.) { + const qreal offset = qreal(inSrcText.m_DropShadowOffset) / 10.; + switch (inSrcText.m_DropShadowHorizontalAlignment) { + case TextHorizontalAlignment::Left: + shadowOffsetX = -offset; + break; + case TextHorizontalAlignment::Right: + shadowOffsetX = offset; + break; + default: + break; + } + switch (inSrcText.m_DropShadowVerticalAlignment) { + case TextVerticalAlignment::Top: + shadowOffsetY = -offset; + break; + case TextVerticalAlignment::Bottom: + shadowOffsetY = offset; + break; + default: + break; + } + } + + int wordWrapFlags = 0; + if (dynamicTextArea) { + wordWrapFlags = Qt::TextDontClip; + } else { + switch (inSrcText.m_WordWrap) { + case TextWordWrap::WrapWord: + wordWrapFlags = Qt::TextWordWrap | Qt::TextDontClip; + break; + case TextWordWrap::WrapAnywhere: + wordWrapFlags = Qt::TextWrapAnywhere | Qt::TextDontClip; + break; + case TextWordWrap::Clip: + default: + break; + } + } + + int lineHeight = dynamicTextArea ? fm.height() : finalHeight; + QT3DSF32 nextHeight = 0; + for (int i = 0; i < lineList.size(); ++i) { + const QString &line = lineList.at(i); + qreal xTranslation = tracking; + switch (inSrcText.m_HorizontalAlignment) { + case TextHorizontalAlignment::Center: + xTranslation += qreal(boundingBox.width() - lineWidths.at(i)) / 2.0; + break; + case TextHorizontalAlignment::Right: + xTranslation += qreal(boundingBox.width() - lineWidths.at(i)); + break; + default: + break; // Do nothing + } + QRectF bound(xTranslation, qreal(nextHeight), lineWidths.at(i), lineHeight); + QRectF actualBound; + if (inSrcText.m_DropShadow) { + QRectF boundShadow(xTranslation + shadowOffsetX, nextHeight + shadowOffsetY, + qreal(lineWidths.at(i)), lineHeight); + // shadow is a darker shade of the given font color + painter.setPen(QColor(shadowRgb, shadowRgb, shadowRgb)); + painter.drawText(boundShadow, + alignToQtAlign(inSrcText.m_VerticalAlignment) | wordWrapFlags + | horizontalAlignmentFlag, line, &actualBound); + painter.setPen(Qt::white); // coloring is done in the shader + } + painter.drawText(bound, + alignToQtAlign(inSrcText.m_VerticalAlignment) | wordWrapFlags + | horizontalAlignmentFlag, line, &actualBound); + + nextHeight += QT3DSF32(lineHeight) + inSrcText.m_Leading; + } + + return ITextRenderer::UploadData(toU8DataRef(image.bits(), image.byteCount()), inTexture, + image.width(), image.height(), + image.width(), image.height(), + NVRenderTextureFormats::RGBA8, true); + } + + STextTextureDetails RenderText(const STextRenderInfo &inText, + NVRenderPathFontItem &inPathFontItem, + NVRenderPathFontSpecification &inFontPathSpec) override + { + Q_UNUSED(inText); + Q_UNUSED(inPathFontItem); + Q_UNUSED(inFontPathSpec); + QT3DS_ASSERT(m_renderContext->IsPathRenderingSupported()); + + // We do not support HW accelerated fonts (yet?) + QT3DS_ASSERT(false); + + return STextTextureDetails(); + } + + void BeginFrame() override + { + // Nothing to do + } + + void EndFrame() override + { + // Nothing to do + } + + // unused for text rendering via texture atlas + STextTextureAtlasEntryDetails RenderAtlasEntry(QT3DSU32, NVRenderTexture2D &) override + { + return STextTextureAtlasEntryDetails(); + } + QT3DSI32 CreateTextureAtlas() override + { + return 0; + } + SRenderTextureAtlasDetails RenderText(const STextRenderInfo &) override + { + return SRenderTextureAtlasDetails(); + } +}; +} + +ITextRendererCore &ITextRendererCore::CreateQtTextRenderer(NVFoundationBase &inFnd, + IStringTable &inStrTable) +{ + return *QT3DS_NEW(inFnd.getAllocator(), Qt3DSQtTextRenderer)(inFnd, inStrTable); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRender.h b/src/Runtime/Source/runtimerender/Qt3DSRender.h new file mode 100644 index 00000000..44729682 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRender.h @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_H +#define QT3DS_RENDER_H + +namespace qt3ds { +class NVAllocatorCallback; +class NVFoundationBase; +namespace foundation { + class CRegisteredString; + class IStringTable; + class CStrTableOrDataRef; + struct SStrRemapMap; + struct SWriteBuffer; + struct SDataReader; + struct SPtrOffsetMap; + class IPerfTimer; +} +namespace intrinsics { +} +namespace render { + class NVRenderTexture2D; + class NVRenderTexture2DArray; + class NVRenderTextureCube; + class NVRenderImage2D; + class NVRenderFrameBuffer; + class NVRenderRenderBuffer; + class NVRenderVertexBuffer; + class NVRenderIndexBuffer; + class NVRenderDrawIndirectBuffer; + class NVRenderInputAssembler; + class NVRenderAttribLayout; + class NVRenderDepthStencilState; + class NVRenderContext; + class NVRenderConstantBuffer; + class NVRenderShaderProgram; + class NVRenderShaderConstantBase; + struct NVRenderDrawMode; + struct NVRenderWinding; + struct NVRenderSrcBlendFunc; + struct NVRenderBlendEquation; + struct NVRenderState; + struct NVRenderTextureCoordOp; + struct NVRenderTextureMagnifyingOp; + struct NVRenderDstBlendFunc; + struct NVRenderContextValues; + struct NVRenderClearValues; + struct NVRenderRect; + struct NVRenderRectF; + struct NVRenderRenderBufferFormats; + struct NVRenderTextureFormats; + struct NVRenderTextureSwizzleMode; + struct NVRenderFrameBufferAttachments; + struct NVRenderRect; + struct NVRenderTextureCubeFaces; + struct STextureDetails; + struct NVRenderShaderDataTypes; + class NVRenderTextureOrRenderBuffer; + struct NVRenderTextureMinifyingOp; + struct NVReadFaces; + struct NVRenderVertexBufferEntry; + struct NVRenderPtrPtrMap; + class NVRenderComputeShader; + class NVRenderAttribLayout; + struct NVRenderBufferAccessTypeValues; + struct NVRenderImageAccessType; + struct NVRenderBufferBindValues; + struct DrawArraysIndirectCommand; + struct NVRenderShaderTypeValue; + class NVRenderPathRender; + class NVRenderPathSpecification; + class NVRenderPathFontSpecification; + class NVRenderPathFontItem; + struct NVRenderTextureTypeValue; + class NVRenderProgramPipeline; +} +class NVPlane; +} + +namespace eastl { +} + +namespace qt3ds { + +namespace render { + using namespace qt3ds; + using namespace qt3ds::foundation; + using namespace qt3ds::intrinsics; + using qt3ds::render::NVRenderTexture2D; + using qt3ds::render::NVRenderTexture2DArray; + using qt3ds::render::NVRenderTextureCube; + using qt3ds::render::NVRenderImage2D; + using qt3ds::render::NVRenderFrameBuffer; + using qt3ds::render::NVRenderRenderBuffer; + using qt3ds::render::NVRenderVertexBuffer; + using qt3ds::render::NVRenderIndexBuffer; + using qt3ds::render::NVRenderDrawIndirectBuffer; + using qt3ds::render::NVRenderInputAssembler; + using qt3ds::render::NVRenderAttribLayout; + using qt3ds::render::NVRenderDepthStencilState; + using qt3ds::render::NVRenderContext; + using qt3ds::render::NVRenderConstantBuffer; + using qt3ds::render::NVRenderShaderProgram; + using qt3ds::render::NVRenderShaderConstantBase; + using qt3ds::render::NVRenderDrawMode; + using qt3ds::render::NVRenderWinding; + using qt3ds::foundation::CRegisteredString; + using qt3ds::foundation::IStringTable; + using qt3ds::render::NVRenderSrcBlendFunc; + using qt3ds::render::NVRenderBlendEquation; + using qt3ds::render::NVRenderState; + using qt3ds::foundation::IStringTable; + using qt3ds::foundation::CRegisteredString; + using qt3ds::render::NVRenderTextureCoordOp; + using qt3ds::render::NVRenderDstBlendFunc; + using qt3ds::render::NVRenderRect; + using qt3ds::render::NVRenderRectF; + using qt3ds::render::NVRenderRenderBufferFormats; + using qt3ds::render::NVRenderTextureFormats; + using qt3ds::render::NVRenderTextureSwizzleMode; + using qt3ds::render::NVRenderFrameBufferAttachments; + using qt3ds::render::NVRenderRect; + using qt3ds::render::NVRenderContextValues; + using qt3ds::render::NVRenderClearValues; + using qt3ds::render::STextureDetails; + using qt3ds::render::NVRenderShaderDataTypes; + using qt3ds::render::NVRenderTextureMagnifyingOp; + using qt3ds::render::NVRenderTextureOrRenderBuffer; + using qt3ds::render::NVRenderTextureMinifyingOp; + using qt3ds::render::NVReadFaces; + using qt3ds::render::NVRenderTextureCubeFaces; + using qt3ds::foundation::SStrRemapMap; + using qt3ds::foundation::SWriteBuffer; + using qt3ds::foundation::SDataReader; + using qt3ds::render::NVRenderPtrPtrMap; + using qt3ds::foundation::CStrTableOrDataRef; + using qt3ds::foundation::SPtrOffsetMap; + using qt3ds::foundation::IPerfTimer; + using qt3ds::render::NVRenderVertexBufferEntry; + using qt3ds::render::NVRenderComputeShader; + using qt3ds::render::NVRenderAttribLayout; + using qt3ds::render::NVRenderBufferAccessTypeValues; + using qt3ds::render::NVRenderImageAccessType; + using qt3ds::render::NVRenderBufferBindValues; + using qt3ds::render::DrawArraysIndirectCommand; + using qt3ds::render::NVRenderShaderTypeValue; + using qt3ds::render::NVRenderPathRender; + using qt3ds::render::NVRenderPathSpecification; + using qt3ds::render::NVRenderPathFontSpecification; + using qt3ds::render::NVRenderPathFontItem; + using qt3ds::render::NVRenderTextureTypeValue; + using qt3ds::render::NVRenderProgramPipeline; + + class IQt3DSRenderContextCore; + class IQt3DSRenderContext; + class IQt3DSRenderer; + class IBufferManager; + struct SRenderMesh; + class IRenderableObject; + class IQt3DSRenderer; + class IBufferManager; + class IResourceManager; + class IOffscreenRenderManager; + struct SNode; + struct SGraphObject; + class ITextRenderer; + class ITextRendererCore; + class IInputStreamFactory; + class IRefCountedInputStream; + class IEffectSystem; + class IEffectSystemCore; + class CRenderString; + class IShaderCache; + class IQt3DSRenderNodeFilter; + class IRenderWidget; + class IRenderWidgetContext; + struct SShaderVertexCodeGenerator; + struct SShaderFragmentCodeGenerator; + class IThreadPool; + struct SRenderMesh; + struct SLoadedTexture; + class IImageBatchLoader; + class ITextTextureCache; + class ITextTextureAtlas; + class IRenderPluginInstance; + class IRenderPluginClass; + class IRenderPluginManager; + class IRenderPluginManagerCore; + struct SRenderPlugin; + class IDynamicObjectSystemCore; + class IDynamicObjectSystem; + class IDynamicObjectClass; + struct SRenderSubset; + struct SModel; + namespace dynamic { + struct SPropertyDefinition; + } + struct SLight; + struct SCamera; + struct SCustomMaterial; + class ICustomMaterialSystem; + class ICustomMaterialSystemCore; + struct SLayer; + struct SReferencedMaterial; + struct SPGGraphObject; + class IPixelGraphicsRenderer; + class IBufferLoader; + struct SEffect; + class IRenderList; + class IRenderTask; + class CResourceTexture2D; + class IPathManagerCore; + class IPathManager; + struct SPath; + struct SPathSubPath; + class IShaderProgramGenerator; + class IShaderStageGenerator; + class IDefaultMaterialShaderGenerator; + class ICustomMaterialShaderGenerator; + struct SRenderableImage; + class Qt3DSShadowMap; + struct SLightmaps; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.cpp new file mode 100644 index 00000000..86375566 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderClippingFrustum.h" + +using namespace qt3ds::render; + +SClippingFrustum::SClippingFrustum(const QT3DSMat44 &modelviewprojection, SClipPlane nearPlane) +{ + SClipPlane *_cullingPlanes = mPlanes; + const QT3DSMat44 &modelViewProjectionMat(modelviewprojection); + const QT3DSF32 *modelviewProjection = modelViewProjectionMat.front(); + +// update planes (http://read.pudn.com/downloads128/doc/542641/Frustum.pdf) +// Google for Gribb plane extraction if that link doesn't work. +// http://www.google.com/search?q=ravensoft+plane+extraction +#define M(_x, _y) modelviewProjection[(4 * (_y)) + (_x)] + // left plane + _cullingPlanes[0].normal.x = M(3, 0) + M(0, 0); + _cullingPlanes[0].normal.y = M(3, 1) + M(0, 1); + _cullingPlanes[0].normal.z = M(3, 2) + M(0, 2); + _cullingPlanes[0].d = M(3, 3) + M(0, 3); + _cullingPlanes[0].d /= _cullingPlanes[0].normal.normalize(); + + // right plane + _cullingPlanes[1].normal.x = M(3, 0) - M(0, 0); + _cullingPlanes[1].normal.y = M(3, 1) - M(0, 1); + _cullingPlanes[1].normal.z = M(3, 2) - M(0, 2); + _cullingPlanes[1].d = M(3, 3) - M(0, 3); + _cullingPlanes[1].d /= _cullingPlanes[1].normal.normalize(); + + // far plane + _cullingPlanes[2].normal.x = M(3, 0) - M(2, 0); + _cullingPlanes[2].normal.y = M(3, 1) - M(2, 1); + _cullingPlanes[2].normal.z = M(3, 2) - M(2, 2); + _cullingPlanes[2].d = M(3, 3) - M(2, 3); + _cullingPlanes[2].d /= _cullingPlanes[2].normal.normalize(); + + // bottom plane + _cullingPlanes[3].normal.x = M(3, 0) + M(1, 0); + _cullingPlanes[3].normal.y = M(3, 1) + M(1, 1); + _cullingPlanes[3].normal.z = M(3, 2) + M(1, 2); + _cullingPlanes[3].d = M(3, 3) + M(1, 3); + _cullingPlanes[3].d /= _cullingPlanes[3].normal.normalize(); + + // top plane + _cullingPlanes[4].normal.x = M(3, 0) - M(1, 0); + _cullingPlanes[4].normal.y = M(3, 1) - M(1, 1); + _cullingPlanes[4].normal.z = M(3, 2) - M(1, 2); + _cullingPlanes[4].d = M(3, 3) - M(1, 3); + _cullingPlanes[4].d /= _cullingPlanes[4].normal.normalize(); +#undef M + _cullingPlanes[5] = nearPlane; + // http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/include/osg/Plane?rev=5328 + // setup the edges of the plane that we will clip against an axis-aligned bounding box. + for (QT3DSU32 idx = 0; idx < 6; ++idx) { + _cullingPlanes[idx].calculateBBoxEdges(); + } +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.h b/src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.h new file mode 100644 index 00000000..b788ad24 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderClippingFrustum.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CLIPPING_PLANE_H +#define QT3DS_RENDER_CLIPPING_PLANE_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSPlane.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSBounds3.h" + +namespace qt3ds { +namespace render { + + struct BoxEdgeFlagValues + { + enum Enum { + xMax = 1, + yMax = 1 << 1, + zMax = 1 << 2, + }; + }; + + typedef NVFlags TRenderBoxEdge; + + // For an intesection test, we only need two points of the bounding box. + // There will be a point nearest to the plane, and a point furthest from the plane. + // We can derive these points from the plane normal equation. + struct SPlaneBoxEdge + { + TRenderBoxEdge lowerEdge; + TRenderBoxEdge upperEdge; + }; + + struct SClipPlane + { + QT3DSVec3 normal; + QT3DSF32 d; + SPlaneBoxEdge mEdges; + + // For intersection tests, we only need to know if the numerator is greater than, equal to, + // or less than zero. + inline QT3DSF32 distance(const QT3DSVec3 &pt) const { return normal.dot(pt) + d; } + + // Only works if p0 is above the line and p1 is below the plane. + inline QT3DSVec3 intersectWithLine(const QT3DSVec3 &p0, const QT3DSVec3 &p1) const + { + QT3DSVec3 dir = p1 - p0; + QT3DSVec3 pointOnPlane = normal * (-d); +#ifdef _DEBUG + QT3DSF32 distanceOfPoint = distance(pointOnPlane); + QT3DS_ASSERT(NVAbs(distanceOfPoint) < 0.0001f); +#endif + QT3DSF32 numerator = (pointOnPlane - p0).dot(normal); + QT3DSF32 denominator = dir.dot(normal); + + QT3DS_ASSERT(NVAbs(denominator) > .0001f); + QT3DSF32 t = (numerator / denominator); + QT3DSVec3 retval = p0 + dir * t; +#ifdef _DEBUG + QT3DSF32 retvalDistance = distance(retval); + QT3DS_ASSERT(NVAbs(retvalDistance) < .0001f); +#endif + return retval; + } + + static inline QT3DSVec3 corner(const NVBounds3 &bounds, TRenderBoxEdge edge) + { + return QT3DSVec3((edge & BoxEdgeFlagValues::xMax) ? bounds.maximum[0] : bounds.minimum[0], + (edge & BoxEdgeFlagValues::yMax) ? bounds.maximum[1] : bounds.minimum[1], + (edge & BoxEdgeFlagValues::zMax) ? bounds.maximum[2] : bounds.minimum[2]); + } + + // dividing the distance numerator + + // I got this code from osg, but it is in graphics gems + // as well. + /** intersection test between plane and bounding sphere. + return 1 if the bs is completely above plane, + return 0 if the bs intersects the plane, + return -1 if the bs is completely below the plane.*/ + inline int intersect(const NVBounds3 &bounds) const + { + // if lowest point above plane than all above. + if (distance(corner(bounds, mEdges.lowerEdge)) > 0.0f) + return 1; + + // if highest point is below plane then all below. + if (distance(corner(bounds, mEdges.upperEdge)) < 0.0f) + return -1; + + // d_lower<=0.0f && d_upper>=0.0f + // therefore must be crossing plane. + return 0; + } + + inline void calculateBBoxEdges() + { + mEdges.upperEdge = TRenderBoxEdge( + static_cast((normal[0] >= 0.0f ? BoxEdgeFlagValues::xMax : 0) + | (normal[1] >= 0.0f ? BoxEdgeFlagValues::yMax : 0) + | (normal[2] >= 0.0f ? BoxEdgeFlagValues::zMax : 0))); + + mEdges.lowerEdge = TRenderBoxEdge((~((QT3DSU8)mEdges.upperEdge)) & 7); + } + }; + + struct SClippingFrustum + { + SClipPlane mPlanes[6]; + + SClippingFrustum() {} + + SClippingFrustum(const QT3DSMat44 &modelviewprojection, SClipPlane nearPlane); + + bool intersectsWith(const NVBounds3 &bounds) const + { + for (QT3DSU32 idx = 0; idx < 6; ++idx) + if (mPlanes[idx].intersect(bounds) < 0) + return false; + return true; + } + + bool intersectsWith(const QT3DSVec3 &point, QT3DSF32 radius = 0.0f) const + { + for (QT3DSU32 idx = 0; idx < 6; ++idx) + if (mPlanes[idx].distance(point) < radius) + return false; + return true; + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp new file mode 100644 index 00000000..e0eedfd3 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp @@ -0,0 +1,819 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRender.h" +#include "EABase/eabase.h" //char16_t definition +#include "Qt3DSRenderContextCore.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderNode.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderResourceManager.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSRenderEffectSystem.h" +#include "Qt3DSRenderShaderCache.h" +#include "foundation/Qt3DSFoundation.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "Qt3DSRenderCamera.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderThreadPool.h" +#include "Qt3DSRenderImageBatchLoader.h" +#include "Qt3DSRenderTextTextureCache.h" +#include "Qt3DSRenderTextTextureAtlas.h" +#include "Qt3DSRenderPlugin.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderPixelGraphicsRenderer.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "Qt3DSRenderBufferLoader.h" +#include "foundation/FastAllocator.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "Qt3DSRenderRenderList.h" +#include "Qt3DSRenderPathManager.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include "Qt3DSRenderCustomMaterialShaderGenerator.h" + +using namespace qt3ds::render; + +namespace { + +struct SRenderContextCore : public IQt3DSRenderContextCore +{ + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_StringTable; + NVScopedRefCounted m_PerfTimer; + NVScopedRefCounted m_InputStreamFactory; + NVScopedRefCounted m_ThreadPool; + NVScopedRefCounted m_DynamicObjectSystem; + NVScopedRefCounted m_MaterialSystem; + NVScopedRefCounted m_EffectSystem; + NVScopedRefCounted m_BufferLoader; + NVScopedRefCounted m_RenderPluginManagerCore; + NVScopedRefCounted m_TextRenderer; + NVScopedRefCounted m_OnscreenTexRenderer; + NVScopedRefCounted m_PathManagerCore; + + QT3DSI32 mRefCount; + SRenderContextCore(NVFoundationBase &fnd, IStringTable &strTable) + : m_Foundation(fnd) + , m_StringTable(strTable) + , m_PerfTimer(IPerfTimer::CreatePerfTimer(fnd)) + , m_InputStreamFactory(IInputStreamFactory::Create(fnd)) + , m_ThreadPool(IThreadPool::CreateThreadPool(fnd, 4)) + , mRefCount(0) + { + m_DynamicObjectSystem = IDynamicObjectSystemCore::CreateDynamicSystemCore(*this); + m_MaterialSystem = ICustomMaterialSystemCore::CreateCustomMaterialSystemCore(*this); + m_EffectSystem = IEffectSystemCore::CreateEffectSystemCore(*this); + m_RenderPluginManagerCore = + IRenderPluginManagerCore::Create(fnd, strTable, *m_InputStreamFactory); + m_BufferLoader = IBufferLoader::Create(m_Foundation, *m_InputStreamFactory, *m_ThreadPool); + m_PathManagerCore = IPathManagerCore::CreatePathManagerCore(*this); + } + + virtual ~SRenderContextCore() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + IStringTable &GetStringTable() override { return *m_StringTable; } + NVFoundationBase &GetFoundation() override { return m_Foundation; } + NVAllocatorCallback &GetAllocator() override { return m_Foundation.getAllocator(); } + IInputStreamFactory &GetInputStreamFactory() override { return *m_InputStreamFactory; } + IThreadPool &GetThreadPool() override { return *m_ThreadPool; } + IDynamicObjectSystemCore &GetDynamicObjectSystemCore() override + { + return *m_DynamicObjectSystem; + } + ICustomMaterialSystemCore &GetMaterialSystemCore() override { return *m_MaterialSystem; } + IEffectSystemCore &GetEffectSystemCore() override { return *m_EffectSystem; } + IPerfTimer &GetPerfTimer() override { return *m_PerfTimer; } + IBufferLoader &GetBufferLoader() override { return *m_BufferLoader; } + IRenderPluginManagerCore &GetRenderPluginCore() override { return *m_RenderPluginManagerCore; } + IPathManagerCore &GetPathManagerCore() override { return *m_PathManagerCore; } + IQt3DSRenderContext &CreateRenderContext(NVRenderContext &inContext, + const char8_t *inPrimitivesDirectory) override; + void SetTextRendererCore(ITextRendererCore &inRenderer) override { m_TextRenderer = inRenderer; } + ITextRendererCore *GetTextRendererCore() override { return m_TextRenderer.mPtr; } + void SetOnscreenTextRendererCore(ITextRendererCore &inRenderer) override + { + m_OnscreenTexRenderer = inRenderer; + } + ITextRendererCore *GetOnscreenTextRendererCore() override { return m_OnscreenTexRenderer.mPtr; } +}; + +inline float Clamp(float val, float inMin = 0.0f, float inMax = 1.0f) +{ + if (val < inMin) + return inMin; + if (val > inMax) + return inMax; + return val; +} + +struct SPerFrameAllocator : public NVAllocatorCallback +{ + SFastAllocator<> m_FastAllocator; + SSAutoDeallocatorAllocator m_LargeAllocator; + + SPerFrameAllocator(NVAllocatorCallback &baseAllocator) + : m_FastAllocator(baseAllocator, "PerFrameAllocation") + , m_LargeAllocator(baseAllocator) + { + } + + inline void *allocate(size_t inSize, const char *inFile, int inLine) + { + if (inSize < 8192) + return m_FastAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); + else + return m_LargeAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); + } + + inline void *allocate(size_t inSize, const char *inFile, int inLine, int, int) + { + if (inSize < 8192) + return m_FastAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); + else + return m_LargeAllocator.allocate(inSize, "PerFrameAllocation", inFile, inLine, 0); + } + + inline void deallocate(void *, size_t) {} + + void reset() + { + m_FastAllocator.reset(); + m_LargeAllocator.deallocateAllAllocations(); + } + + void *allocate(size_t inSize, const char *typeName, const char *inFile, int inLine, + int flags = 0) override + { + if (inSize < SFastAllocator<>::SlabSize) + return m_FastAllocator.allocate(inSize, typeName, inFile, inLine, flags); + else + return m_LargeAllocator.allocate(inSize, typeName, inFile, inLine, flags); + } + + void *allocate(size_t inSize, const char *typeName, const char *inFile, int inLine, + size_t alignment, size_t alignmentOffset) override + { + if (inSize < SFastAllocator<>::SlabSize) + return m_FastAllocator.allocate(inSize, typeName, inFile, inLine, alignment, + alignmentOffset); + else + return m_LargeAllocator.allocate(inSize, typeName, inFile, inLine, alignment, + alignmentOffset); + } + + void deallocate(void *) override {} +}; + +struct SRenderContext : public IQt3DSRenderContext +{ + NVScopedRefCounted m_RenderContext; + NVScopedRefCounted m_CoreContext; + NVScopedRefCounted m_StringTable; + NVScopedRefCounted m_PerfTimer; + NVScopedRefCounted m_InputStreamFactory; + NVScopedRefCounted m_BufferManager; + NVScopedRefCounted m_ResourceManager; + NVScopedRefCounted m_OffscreenRenderManager; + NVScopedRefCounted m_Renderer; + NVScopedRefCounted m_TextRenderer; + NVScopedRefCounted m_OnscreenTextRenderer; + NVScopedRefCounted m_TextTextureCache; + NVScopedRefCounted m_TextTextureAtlas; + NVScopedRefCounted m_DynamicObjectSystem; + NVScopedRefCounted m_EffectSystem; + NVScopedRefCounted m_ShaderCache; + NVScopedRefCounted m_ThreadPool; + NVScopedRefCounted m_ImageBatchLoader; + NVScopedRefCounted m_RenderPluginManager; + NVScopedRefCounted m_CustomMaterialSystem; + NVScopedRefCounted m_PixelGraphicsRenderer; + NVScopedRefCounted m_PathManager; + NVScopedRefCounted m_ShaderProgramGenerator; + NVScopedRefCounted m_DefaultMaterialShaderGenerator; + NVScopedRefCounted m_CustomMaterialShaderGenerator; + SPerFrameAllocator m_PerFrameAllocator; + NVScopedRefCounted m_RenderList; + QT3DSU32 m_FrameCount; + volatile QT3DSI32 mRefCount; + // Viewport that this render context should use + Option m_Viewport; + QSize m_WindowDimensions; + ScaleModes::Enum m_ScaleMode; + bool m_WireframeMode; + bool m_IsInSubPresentation; + Option m_SceneColor; + Option m_MatteColor; + RenderRotationValues::Enum m_Rotation; + NVScopedRefCounted m_RotationFBO; + NVScopedRefCounted m_RotationTexture; + NVScopedRefCounted m_RotationDepthBuffer; + NVRenderFrameBuffer *m_ContextRenderTarget; + NVRenderRect m_PresentationViewport; + QSize m_PresentationDimensions; + QSize m_RenderPresentationDimensions; + QSize m_PreRenderPresentationDimensions; + QT3DSVec2 m_PresentationScale; + NVRenderRect m_VirtualViewport; + QPair m_FPS; + bool m_AuthoringMode; + + SRenderContext(NVRenderContext &ctx, IQt3DSRenderContextCore &inCore, + const char8_t *inApplicationDirectory) + : m_RenderContext(ctx) + , m_CoreContext(inCore) + , m_StringTable(ctx.GetStringTable()) + , m_PerfTimer(inCore.GetPerfTimer()) + , m_InputStreamFactory(inCore.GetInputStreamFactory()) + , m_BufferManager( + IBufferManager::Create(ctx, *m_StringTable, *m_InputStreamFactory, *m_PerfTimer)) + , m_ResourceManager(IResourceManager::CreateResourceManager(ctx)) + , m_ShaderCache(IShaderCache::CreateShaderCache(ctx, *m_InputStreamFactory, *m_PerfTimer)) + , m_ThreadPool(inCore.GetThreadPool()) + , m_RenderList(IRenderList::CreateRenderList(ctx.GetFoundation())) + , m_PerFrameAllocator(ctx.GetAllocator()) + , m_FrameCount(0) + , mRefCount(0) + , m_WindowDimensions(800, 480) + , m_ScaleMode(ScaleModes::ExactSize) + , m_WireframeMode(false) + , m_IsInSubPresentation(false) + , m_Rotation(RenderRotationValues::NoRotation) + , m_ContextRenderTarget(NULL) + , m_PresentationScale(0, 0) + , m_FPS(qMakePair(0.0, 0)) + , m_AuthoringMode(false) + { + m_OffscreenRenderManager = IOffscreenRenderManager::CreateOffscreenRenderManager( + ctx.GetAllocator(), *m_StringTable, *m_ResourceManager, *this); + m_Renderer = IQt3DSRenderer::CreateRenderer(*this); + if (inApplicationDirectory && *inApplicationDirectory) + m_InputStreamFactory->AddSearchDirectory(inApplicationDirectory); + + m_ImageBatchLoader = + IImageBatchLoader::CreateBatchLoader(ctx.GetFoundation(), *m_InputStreamFactory, + *m_BufferManager, *m_ThreadPool, *m_PerfTimer); + m_RenderPluginManager = inCore.GetRenderPluginCore().GetRenderPluginManager(ctx); + m_DynamicObjectSystem = inCore.GetDynamicObjectSystemCore().CreateDynamicSystem(*this); + m_EffectSystem = inCore.GetEffectSystemCore().GetEffectSystem(*this); + m_CustomMaterialSystem = inCore.GetMaterialSystemCore().GetCustomMaterialSystem(*this); + // as does the custom material system + m_PixelGraphicsRenderer = IPixelGraphicsRenderer::CreateRenderer(*this, *m_StringTable); + ITextRendererCore *theTextCore = inCore.GetTextRendererCore(); + m_ShaderProgramGenerator = IShaderProgramGenerator::CreateProgramGenerator(*this); + m_DefaultMaterialShaderGenerator = + IDefaultMaterialShaderGenerator::CreateDefaultMaterialShaderGenerator(*this); + m_CustomMaterialShaderGenerator = + ICustomMaterialShaderGenerator::CreateCustomMaterialShaderGenerator(*this); + if (theTextCore) { + m_TextRenderer = theTextCore->GetTextRenderer(ctx); + m_TextTextureCache = ITextTextureCache::CreateTextureCache( + m_RenderContext->GetFoundation(), *m_TextRenderer, *m_RenderContext); + } + + ITextRendererCore *theOnscreenTextCore = inCore.GetOnscreenTextRendererCore(); + if (theOnscreenTextCore) { + m_OnscreenTextRenderer = theOnscreenTextCore->GetTextRenderer(ctx); + m_TextTextureAtlas = ITextTextureAtlas::CreateTextureAtlas( + m_RenderContext->GetFoundation(), *m_OnscreenTextRenderer, *m_RenderContext); + } + m_PathManager = inCore.GetPathManagerCore().OnRenderSystemInitialize(*this); + +#if defined (QT3DS_SHADER_PLATFORM_LIBRARY_DIR) + const QString platformDirectory; +#if defined(_WIN32) + platformDirectory = QStringLiteral("res/platform/win"); +#elif defined(_LINUX) + platformDirectory = QStringLiteral("res/platform/linux"); +#elif defined(_MACOSX) + platformDirectory = QStringLiteral("res/platform/macos"); +#endif + GetDynamicObjectSystem().setShaderCodeLibraryPlatformDirectory(platformDirectory); +#endif + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext->GetAllocator()); + + IStringTable &GetStringTable() override { return *m_StringTable; } + NVFoundationBase &GetFoundation() override { return m_RenderContext->GetFoundation(); } + NVAllocatorCallback &GetAllocator() override { return m_RenderContext->GetAllocator(); } + IQt3DSRenderer &GetRenderer() override { return *m_Renderer; } + IBufferManager &GetBufferManager() override { return *m_BufferManager; } + IResourceManager &GetResourceManager() override { return *m_ResourceManager; } + NVRenderContext &GetRenderContext() override { return *m_RenderContext; } + IOffscreenRenderManager &GetOffscreenRenderManager() override + { + return *m_OffscreenRenderManager; + } + IInputStreamFactory &GetInputStreamFactory() override { return *m_InputStreamFactory; } + IEffectSystem &GetEffectSystem() override { return *m_EffectSystem; } + IShaderCache &GetShaderCache() override { return *m_ShaderCache; } + IThreadPool &GetThreadPool() override { return *m_ThreadPool; } + IImageBatchLoader &GetImageBatchLoader() override { return *m_ImageBatchLoader; } + ITextTextureCache *GetTextureCache() override { return m_TextTextureCache.mPtr; } + ITextTextureAtlas *GetTextureAtlas() override { return m_TextTextureAtlas.mPtr; } + IRenderPluginManager &GetRenderPluginManager() override { return *m_RenderPluginManager; } + IDynamicObjectSystem &GetDynamicObjectSystem() override { return *m_DynamicObjectSystem; } + ICustomMaterialSystem &GetCustomMaterialSystem() override { return *m_CustomMaterialSystem; } + IPixelGraphicsRenderer &GetPixelGraphicsRenderer() override { return *m_PixelGraphicsRenderer; } + IPerfTimer &GetPerfTimer() override { return *m_PerfTimer; } + IRenderList &GetRenderList() override { return *m_RenderList; } + IPathManager &GetPathManager() override { return *m_PathManager; } + IShaderProgramGenerator &GetShaderProgramGenerator() override + { + return *m_ShaderProgramGenerator; + } + IDefaultMaterialShaderGenerator &GetDefaultMaterialShaderGenerator() override + { + return *m_DefaultMaterialShaderGenerator; + } + ICustomMaterialShaderGenerator &GetCustomMaterialShaderGenerator() override + { + return *m_CustomMaterialShaderGenerator; + } + NVAllocatorCallback &GetPerFrameAllocator() override { return m_PerFrameAllocator; } + + QT3DSU32 GetFrameCount() override { return m_FrameCount; } + void SetFPS(QPair inFPS) override { m_FPS = inFPS; } + QPair GetFPS(void) override { return m_FPS; } + + bool IsAuthoringMode() override { return m_AuthoringMode; } + void SetAuthoringMode(bool inMode) override { m_AuthoringMode = inMode; } + + bool IsInSubPresentation() override { return m_IsInSubPresentation; } + void SetInSubPresentation(bool inValue) override { m_IsInSubPresentation = inValue; } + + ITextRenderer *GetTextRenderer() override { return m_TextRenderer; } + + ITextRenderer *GetOnscreenTextRenderer() override { return m_OnscreenTextRenderer; } + + void SetSceneColor(Option inSceneColor) override { m_SceneColor = inSceneColor; } + void SetMatteColor(Option inMatteColor) override { m_MatteColor = inMatteColor; } + + void SetWindowDimensions(const QSize &inWindowDimensions) override + { + m_WindowDimensions = inWindowDimensions; + } + + QSize GetWindowDimensions() override { return m_WindowDimensions; } + + void SetScaleMode(ScaleModes::Enum inMode) override { m_ScaleMode = inMode; } + + ScaleModes::Enum GetScaleMode() override { return m_ScaleMode; } + + void SetWireframeMode(bool inEnable) override { m_WireframeMode = inEnable; } + + bool GetWireframeMode() override { return m_WireframeMode; } + + void SetViewport(Option inViewport) override { m_Viewport = inViewport; } + Option GetViewport() const override { return m_Viewport; } + + IRenderWidgetContext &GetRenderWidgetContext() override + { + return m_Renderer->GetRenderWidgetContext(); + } + + eastl::pair GetPresentationViewportAndOuterViewport() const + { + QSize thePresentationDimensions(m_PresentationDimensions); + NVRenderRect theOuterViewport(GetContextViewport()); + if (m_Rotation == RenderRotationValues::Clockwise90 + || m_Rotation == RenderRotationValues::Clockwise270) { + eastl::swap(theOuterViewport.m_Width, theOuterViewport.m_Height); + eastl::swap(theOuterViewport.m_X, theOuterViewport.m_Y); + } + // Calculate the presentation viewport perhaps with the window width and height swapped. + return eastl::make_pair( + GetPresentationViewport(theOuterViewport, m_ScaleMode, thePresentationDimensions), + theOuterViewport); + } + + NVRenderRectF GetDisplayViewport() const override + { + return GetPresentationViewportAndOuterViewport().first; + } + + void SetPresentationDimensions(const QSize &inPresentationDimensions) override + { + m_PresentationDimensions = inPresentationDimensions; + } + QSize GetCurrentPresentationDimensions() const override + { + return m_PresentationDimensions; + } + + void SetRenderRotation(RenderRotationValues::Enum inRotation) override + { + m_Rotation = inRotation; + } + + RenderRotationValues::Enum GetRenderRotation() const override { return m_Rotation; } + QT3DSVec2 GetMousePickViewport() const override + { + bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation; + if (renderOffscreen) + return QT3DSVec2((QT3DSF32)m_PresentationViewport.m_Width, + (QT3DSF32)m_PresentationViewport.m_Height); + else + return QT3DSVec2((QT3DSF32)m_WindowDimensions.width(), (QT3DSF32)m_WindowDimensions.height()); + } + NVRenderRect GetContextViewport() const override + { + NVRenderRect retval; + if (m_Viewport.hasValue()) + retval = *m_Viewport; + else + retval = NVRenderRect(0, 0, m_WindowDimensions.width(), m_WindowDimensions.height()); + + return retval; + } + + QT3DSVec2 GetMousePickMouseCoords(const QT3DSVec2 &inMouseCoords) const override + { + bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation; + if (renderOffscreen) { + QSize thePresentationDimensions(m_RenderPresentationDimensions); + NVRenderRect theViewport(GetContextViewport()); + // Calculate the presentation viewport perhaps with the presentation width and height + // swapped. + NVRenderRect thePresentationViewport = + GetPresentationViewport(theViewport, m_ScaleMode, thePresentationDimensions); + // Translate pick into presentation space without rotations or anything else. + QT3DSF32 YHeightDiff = (QT3DSF32)((QT3DSF32)m_WindowDimensions.height() + - (QT3DSF32)thePresentationViewport.m_Height); + QT3DSVec2 theLocalMouse((inMouseCoords.x - thePresentationViewport.m_X), + (inMouseCoords.y - YHeightDiff + thePresentationViewport.m_Y)); + switch (m_Rotation) { + default: + case RenderRotationValues::NoRotation: + QT3DS_ASSERT(false); + break; + case RenderRotationValues::Clockwise90: + eastl::swap(theLocalMouse.x, theLocalMouse.y); + theLocalMouse.y = thePresentationViewport.m_Width - theLocalMouse.y; + break; + case RenderRotationValues::Clockwise180: + theLocalMouse.y = thePresentationViewport.m_Height - theLocalMouse.y; + theLocalMouse.x = thePresentationViewport.m_Width - theLocalMouse.x; + break; + case RenderRotationValues::Clockwise270: + eastl::swap(theLocalMouse.x, theLocalMouse.y); + theLocalMouse.x = thePresentationViewport.m_Height - theLocalMouse.x; + break; + } + return theLocalMouse; + } + return inMouseCoords; + } + + NVRenderRect GetPresentationViewport(const NVRenderRect &inViewerViewport, + ScaleModes::Enum inScaleToFit, + const QSize &inPresDimensions) const + { + NVRenderRect retval; + QT3DSI32 theWidth = inViewerViewport.m_Width; + QT3DSI32 theHeight = inViewerViewport.m_Height; + if (inPresDimensions.width() == 0 || inPresDimensions.height() == 0) + return NVRenderRect(0, 0, 0, 0); + // Setup presentation viewport. This may or may not match the physical viewport that we + // want to setup. + // Avoiding scaling keeps things as sharp as possible. + if (inScaleToFit == ScaleModes::ExactSize) { + retval.m_Width = inPresDimensions.width(); + retval.m_Height = inPresDimensions.height(); + retval.m_X = (theWidth - (QT3DSI32)inPresDimensions.width()) / 2; + retval.m_Y = (theHeight - (QT3DSI32)inPresDimensions.height()) / 2; + } else if (inScaleToFit == ScaleModes::ScaleToFit + || inScaleToFit == ScaleModes::FitSelected) { + // Scale down in such a way to preserve aspect ratio. + float screenAspect = (float)theWidth / (float)theHeight; + float thePresentationAspect = + (float)inPresDimensions.width() / (float)inPresDimensions.height(); + if (screenAspect >= thePresentationAspect) { + // if the screen height is the limiting factor + retval.m_Y = 0; + retval.m_Height = theHeight; + retval.m_Width = (QT3DSI32)(thePresentationAspect * retval.m_Height); + retval.m_X = (theWidth - retval.m_Width) / 2; + } else { + retval.m_X = 0; + retval.m_Width = theWidth; + retval.m_Height = (QT3DSI32)(retval.m_Width / thePresentationAspect); + retval.m_Y = (theHeight - retval.m_Height) / 2; + } + } else { + // Setup the viewport for everything and let the presentations figure it out. + retval.m_X = 0; + retval.m_Y = 0; + retval.m_Width = theWidth; + retval.m_Height = theHeight; + } + retval.m_X += inViewerViewport.m_X; + retval.m_Y += inViewerViewport.m_Y; + return retval; + } + + void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, + const char *text) override + { + m_Renderer->RenderText2D(x, y, inColor, text); + } + + void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, + qt3ds::foundation::Option inColor) override + { + m_Renderer->RenderGpuProfilerStats(x, y, inColor); + } + + NVRenderRect GetPresentationViewport() const override { return m_PresentationViewport; } + struct SBeginFrameResult + { + bool m_RenderOffscreen; + QSize m_PresentationDimensions; + bool m_ScissorTestEnabled; + NVRenderRect m_ScissorRect; + NVRenderRect m_Viewport; + QSize m_FBODimensions; + SBeginFrameResult(bool ro, QSize presDims, bool scissorEnabled, + NVRenderRect scissorRect, NVRenderRect viewport, + QSize fboDims) + : m_RenderOffscreen(ro) + , m_PresentationDimensions(presDims) + , m_ScissorTestEnabled(scissorEnabled) + , m_ScissorRect(scissorRect) + , m_Viewport(viewport) + , m_FBODimensions(fboDims) + { + } + SBeginFrameResult() {} + }; + + // Calculated values passed from beginframe to setupRenderTarget. + // Trying to avoid duplicate code as much as possible. + SBeginFrameResult m_BeginFrameResult; + + void BeginFrame() override + { + m_PreRenderPresentationDimensions = m_PresentationDimensions; + QSize thePresentationDimensions(m_PreRenderPresentationDimensions); + NVRenderRect theContextViewport(GetContextViewport()); + m_PerFrameAllocator.reset(); + IRenderList &theRenderList(*m_RenderList); + theRenderList.BeginFrame(); + if (m_Viewport.hasValue()) { + theRenderList.SetScissorTestEnabled(true); + theRenderList.SetScissorRect(theContextViewport); + } else { + theRenderList.SetScissorTestEnabled(false); + } + bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation; + eastl::pair thePresViewportAndOuterViewport = + GetPresentationViewportAndOuterViewport(); + NVRenderRect theOuterViewport = thePresViewportAndOuterViewport.second; + // Calculate the presentation viewport perhaps with the window width and height swapped. + NVRenderRect thePresentationViewport = thePresViewportAndOuterViewport.first; + m_PresentationViewport = thePresentationViewport; + m_PresentationScale = QT3DSVec2( + (QT3DSF32)thePresentationViewport.m_Width / (QT3DSF32)thePresentationDimensions.width(), + (QT3DSF32)thePresentationViewport.m_Height / (QT3DSF32)thePresentationDimensions.height()); + QSize fboDimensions; + if (thePresentationViewport.m_Width > 0 && thePresentationViewport.m_Height > 0) { + if (renderOffscreen == false) { + m_PresentationDimensions = QSize(thePresentationViewport.m_Width, + thePresentationViewport.m_Height); + m_RenderList->SetViewport(thePresentationViewport); + if (thePresentationViewport.m_X || thePresentationViewport.m_Y + || thePresentationViewport.m_Width != (QT3DSI32)theOuterViewport.m_Width + || thePresentationViewport.m_Height != (QT3DSI32)theOuterViewport.m_Height) { + m_RenderList->SetScissorRect(thePresentationViewport); + m_RenderList->SetScissorTestEnabled(true); + } + } else { + QT3DSU32 imageWidth = ITextRenderer::NextMultipleOf4(thePresentationViewport.m_Width); + QT3DSU32 imageHeight = + ITextRenderer::NextMultipleOf4(thePresentationViewport.m_Height); + fboDimensions = QSize(imageWidth, imageHeight); + m_PresentationDimensions = QSize(thePresentationViewport.m_Width, + thePresentationViewport.m_Height); + NVRenderRect theSceneViewport = NVRenderRect(0, 0, imageWidth, imageHeight); + m_RenderList->SetScissorTestEnabled(false); + m_RenderList->SetViewport(theSceneViewport); + } + } + + m_BeginFrameResult = SBeginFrameResult( + renderOffscreen, m_PresentationDimensions, m_RenderList->IsScissorTestEnabled(), + m_RenderList->GetScissor(), m_RenderList->GetViewport(), fboDimensions); + + m_Renderer->BeginFrame(); + m_OffscreenRenderManager->BeginFrame(); + if (m_TextRenderer) + m_TextRenderer->BeginFrame(); + if (m_TextTextureCache) + m_TextTextureCache->BeginFrame(); + m_ImageBatchLoader->BeginFrame(); + } + + QT3DSVec2 GetPresentationScaleFactor() const override { return m_PresentationScale; } + + virtual void SetupRenderTarget() + { + NVRenderRect theContextViewport(GetContextViewport()); + if (m_Viewport.hasValue()) { + m_RenderContext->SetScissorTestEnabled(true); + m_RenderContext->SetScissorRect(theContextViewport); + } else { + m_RenderContext->SetScissorTestEnabled(false); + } + { + QT3DSVec4 theClearColor; + if (m_MatteColor.hasValue()) + theClearColor = m_MatteColor; + else + theClearColor = m_SceneColor; + m_RenderContext->SetClearColor(theClearColor); + m_RenderContext->Clear(qt3ds::render::NVRenderClearValues::Color); + } + bool renderOffscreen = m_BeginFrameResult.m_RenderOffscreen; + m_RenderContext->SetViewport(m_BeginFrameResult.m_Viewport); + m_RenderContext->SetScissorRect(m_BeginFrameResult.m_ScissorRect); + m_RenderContext->SetScissorTestEnabled(m_BeginFrameResult.m_ScissorTestEnabled); + + if (m_PresentationViewport.m_Width > 0 && m_PresentationViewport.m_Height > 0) { + if (renderOffscreen == false) { + if (m_RotationFBO != NULL) { + m_ResourceManager->Release(*m_RotationFBO); + m_ResourceManager->Release(*m_RotationTexture); + m_ResourceManager->Release(*m_RotationDepthBuffer); + m_RotationFBO = NULL; + m_RotationTexture = NULL; + m_RotationDepthBuffer = NULL; + } + if (m_SceneColor.hasValue() && m_SceneColor.getValue().w != 0.0f) { + m_RenderContext->SetClearColor(m_SceneColor); + m_RenderContext->Clear(qt3ds::render::NVRenderClearValues::Color); + } + } else { + QT3DSU32 imageWidth = m_BeginFrameResult.m_FBODimensions.width(); + QT3DSU32 imageHeight = m_BeginFrameResult.m_FBODimensions.height(); + NVRenderTextureFormats::Enum theColorBufferFormat = NVRenderTextureFormats::RGBA8; + NVRenderRenderBufferFormats::Enum theDepthBufferFormat = + NVRenderRenderBufferFormats::Depth16; + m_ContextRenderTarget = m_RenderContext->GetRenderTarget(); + if (m_RotationFBO == NULL) { + m_RotationFBO = m_ResourceManager->AllocateFrameBuffer(); + m_RotationTexture = m_ResourceManager->AllocateTexture2D( + imageWidth, imageHeight, theColorBufferFormat); + m_RotationDepthBuffer = m_ResourceManager->AllocateRenderBuffer( + imageWidth, imageHeight, theDepthBufferFormat); + m_RotationFBO->Attach(NVRenderFrameBufferAttachments::Color0, + *m_RotationTexture); + m_RotationFBO->Attach(NVRenderFrameBufferAttachments::Depth, + *m_RotationDepthBuffer); + } else { + STextureDetails theDetails = m_RotationTexture->GetTextureDetails(); + if (theDetails.m_Width != imageWidth || theDetails.m_Height != imageHeight) { + m_RotationTexture->SetTextureData(NVDataRef(), 0, imageWidth, + imageHeight, theColorBufferFormat); + m_RotationDepthBuffer->SetDimensions( + qt3ds::render::NVRenderRenderBufferDimensions(imageWidth, imageHeight)); + } + } + m_RenderContext->SetRenderTarget(m_RotationFBO); + if (m_SceneColor.hasValue()) { + m_RenderContext->SetClearColor(m_SceneColor); + m_RenderContext->Clear(qt3ds::render::NVRenderClearValues::Color); + } + } + } + } + + void RunRenderTasks() override + { + m_RenderList->RunRenderTasks(); + SetupRenderTarget(); + } + + // Note this runs before EndFrame + virtual void TeardownRenderTarget() + { + if (m_RotationFBO) { + ScaleModes::Enum theScaleToFit = m_ScaleMode; + NVRenderRect theOuterViewport(GetContextViewport()); + m_RenderContext->SetRenderTarget(m_ContextRenderTarget); + QSize thePresentationDimensions = GetCurrentPresentationDimensions(); + if (m_Rotation == RenderRotationValues::Clockwise90 + || m_Rotation == RenderRotationValues::Clockwise270) { + thePresentationDimensions = QSize(thePresentationDimensions.height(), + thePresentationDimensions.width()); + } + m_RenderPresentationDimensions = thePresentationDimensions; + // Calculate the presentation viewport perhaps with the presentation width and height + // swapped. + NVRenderRect thePresentationViewport = + GetPresentationViewport(theOuterViewport, theScaleToFit, thePresentationDimensions); + SCamera theCamera; + switch (m_Rotation) { + default: + QT3DS_ASSERT(false); + break; + case RenderRotationValues::Clockwise90: + theCamera.m_Rotation.z = 90; + break; + case RenderRotationValues::Clockwise180: + theCamera.m_Rotation.z = 180; + break; + case RenderRotationValues::Clockwise270: + theCamera.m_Rotation.z = 270; + break; + } + TORAD(theCamera.m_Rotation.z); + theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + theCamera.m_Flags.SetOrthographic(true); + m_RenderContext->SetViewport(thePresentationViewport); + QT3DSVec2 theCameraDimensions((QT3DSF32)thePresentationViewport.m_Width, + (QT3DSF32)thePresentationViewport.m_Height); + theCamera.CalculateGlobalVariables( + NVRenderRect(0, 0, (QT3DSU32)thePresentationViewport.m_Width, + (QT3DSU32)thePresentationViewport.m_Height), + theCameraDimensions); + QT3DSMat44 theVP; + theCamera.CalculateViewProjectionMatrix(theVP); + SNode theTempNode; + theTempNode.CalculateGlobalVariables(); + QT3DSMat44 theMVP; + QT3DSMat33 theNormalMat; + theTempNode.CalculateMVPAndNormalMatrix(theVP, theMVP, theNormalMat); + m_RenderContext->SetCullingEnabled(false); + m_RenderContext->SetBlendingEnabled(false); + m_RenderContext->SetDepthTestEnabled(false); + m_Renderer->RenderQuad(QT3DSVec2((QT3DSF32)m_PresentationViewport.m_Width, + (QT3DSF32)m_PresentationViewport.m_Height), + theMVP, *m_RotationTexture); + } + } + + void EndFrame() override + { + TeardownRenderTarget(); + m_ImageBatchLoader->EndFrame(); + if (m_TextTextureCache) + m_TextTextureCache->EndFrame(); + if (m_TextRenderer) + m_TextRenderer->EndFrame(); + m_OffscreenRenderManager->EndFrame(); + m_Renderer->EndFrame(); + m_CustomMaterialSystem->EndFrame(); + m_PresentationDimensions = m_PreRenderPresentationDimensions; + ++m_FrameCount; + } +}; + +IQt3DSRenderContext &SRenderContextCore::CreateRenderContext(NVRenderContext &inContext, + const char8_t *inPrimitivesDirectory) +{ + return *QT3DS_NEW(m_Foundation.getAllocator(), SRenderContext)(inContext, *this, + inPrimitivesDirectory); +} +} + +IQt3DSRenderContextCore &IQt3DSRenderContextCore::Create(NVFoundationBase &fnd, IStringTable &strt) +{ + return *QT3DS_NEW(fnd.getAllocator(), SRenderContextCore)(fnd, strt); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h new file mode 100644 index 00000000..be1498b8 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CONTEXT_CORE_H +#define QT3DS_RENDER_CONTEXT_CORE_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderPresentation.h" + +#include +#include + +namespace qt3ds { +namespace render { + struct ScaleModes + { + enum Enum { + ExactSize = 0, // Ensure the viewport is exactly same size as application + ScaleToFit = 1, // Resize viewport keeping aspect ratio + ScaleToFill = 2, // Resize viewport to entire window + FitSelected = 3, // Resize presentation to fit into viewport + }; + }; + + // Part of render context that does not require the render system. + class IQt3DSRenderContextCore : public NVRefCounted + { + public: + virtual IStringTable &GetStringTable() = 0; + virtual NVFoundationBase &GetFoundation() = 0; + virtual NVAllocatorCallback &GetAllocator() = 0; + virtual IInputStreamFactory &GetInputStreamFactory() = 0; + virtual IThreadPool &GetThreadPool() = 0; + virtual IDynamicObjectSystemCore &GetDynamicObjectSystemCore() = 0; + virtual ICustomMaterialSystemCore &GetMaterialSystemCore() = 0; + virtual IEffectSystemCore &GetEffectSystemCore() = 0; + virtual IPerfTimer &GetPerfTimer() = 0; + virtual IBufferLoader &GetBufferLoader() = 0; + virtual IRenderPluginManagerCore &GetRenderPluginCore() = 0; + virtual IPathManagerCore &GetPathManagerCore() = 0; + // Text renderers may be provided by clients at runtime. + virtual void SetTextRendererCore(ITextRendererCore &inRenderer) = 0; + virtual ITextRendererCore *GetTextRendererCore() = 0; + // this is our default 2D text onscreen renderer + virtual void SetOnscreenTextRendererCore(ITextRendererCore &inRenderer) = 0; + virtual ITextRendererCore *GetOnscreenTextRendererCore() = 0; + // The render context maintains a reference to this object. + virtual IQt3DSRenderContext &CreateRenderContext(NVRenderContext &inContext, + const char8_t *inPrimitivesDirectory) = 0; + + static IQt3DSRenderContextCore &Create(NVFoundationBase &fnd, IStringTable &strt); + }; + + class IQt3DSRenderContext : public NVRefCounted + { + protected: + virtual ~IQt3DSRenderContext() {} + public: + virtual IStringTable &GetStringTable() = 0; + virtual NVFoundationBase &GetFoundation() = 0; + virtual NVAllocatorCallback &GetAllocator() = 0; + virtual IQt3DSRenderer &GetRenderer() = 0; + virtual IRenderWidgetContext &GetRenderWidgetContext() = 0; + virtual IBufferManager &GetBufferManager() = 0; + virtual IResourceManager &GetResourceManager() = 0; + virtual NVRenderContext &GetRenderContext() = 0; + virtual IOffscreenRenderManager &GetOffscreenRenderManager() = 0; + virtual IInputStreamFactory &GetInputStreamFactory() = 0; + virtual IEffectSystem &GetEffectSystem() = 0; + virtual IShaderCache &GetShaderCache() = 0; + virtual IThreadPool &GetThreadPool() = 0; + virtual IImageBatchLoader &GetImageBatchLoader() = 0; + virtual IRenderPluginManager &GetRenderPluginManager() = 0; + virtual IDynamicObjectSystem &GetDynamicObjectSystem() = 0; + virtual ICustomMaterialSystem &GetCustomMaterialSystem() = 0; + virtual IPixelGraphicsRenderer &GetPixelGraphicsRenderer() = 0; + virtual IPerfTimer &GetPerfTimer() = 0; + virtual ITextTextureCache *GetTextureCache() = 0; + virtual ITextRenderer *GetTextRenderer() = 0; + virtual IRenderList &GetRenderList() = 0; + virtual IPathManager &GetPathManager() = 0; + virtual IShaderProgramGenerator &GetShaderProgramGenerator() = 0; + virtual IDefaultMaterialShaderGenerator &GetDefaultMaterialShaderGenerator() = 0; + virtual ICustomMaterialShaderGenerator &GetCustomMaterialShaderGenerator() = 0; + // The memory used for the per frame allocator is released as the first step in BeginFrame. + // This is useful for short lived objects and datastructures. + virtual NVAllocatorCallback &GetPerFrameAllocator() = 0; + // Get the number of times EndFrame has been called + virtual QT3DSU32 GetFrameCount() = 0; + + // Get fps + virtual QPair GetFPS() = 0; + // Set fps by higher level, etc application + virtual void SetFPS(QPair inFPS) = 0; + + // Currently there are a few things that need to work differently + // in authoring mode vs. runtime. The particle effects, for instance + // need to be framerate-independent at runtime but framerate-dependent during + // authoring time assuming virtual 16 ms frames. + // Defaults to falst. + virtual bool IsAuthoringMode() = 0; + virtual void SetAuthoringMode(bool inMode) = 0; + + // This one is setup by the runtime binding + virtual ITextRenderer *GetOnscreenTextRenderer() = 0; + virtual ITextTextureAtlas *GetTextureAtlas() = 0; + + // Sub presentations change the rendering somewhat. + virtual bool IsInSubPresentation() = 0; + virtual void SetInSubPresentation(bool inValue) = 0; + virtual void SetSceneColor(Option inSceneColor) = 0; + virtual void SetMatteColor(Option inMatteColor) = 0; + + // Render screen aligned 2D text at x,y + virtual void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, + const char *text) = 0; + // render Gpu profiler values + virtual void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, + qt3ds::foundation::Option inColor) = 0; + + // The reason you can set both window dimensions and an overall viewport is that the mouse + // needs to be inverted + // which requires the window height, and then the rest of the system really requires the + // viewport. + virtual void SetWindowDimensions(const QSize &inWindowDimensions) = 0; + virtual QSize GetWindowDimensions() = 0; + + // In addition to the window dimensions which really have to be set, you can optionally + // set the viewport which will force the entire viewer to render specifically to this + // viewport. + virtual void SetViewport(Option inViewport) = 0; + virtual Option GetViewport() const = 0; + virtual NVRenderRect GetContextViewport() const = 0; + // Only valid between calls to Begin,End. + virtual NVRenderRect GetPresentationViewport() const = 0; + + virtual void SetScaleMode(ScaleModes::Enum inMode) = 0; + virtual ScaleModes::Enum GetScaleMode() = 0; + + virtual void SetWireframeMode(bool inEnable) = 0; + virtual bool GetWireframeMode() = 0; + + // Return the viewport the system is using to render data to. This gives the the dimensions + // of the rendered system. It is dependent on but not equal to the viewport. + virtual NVRenderRectF GetDisplayViewport() const = 0; + + // Layers require the current presentation dimensions in order to render. + virtual void + SetPresentationDimensions(const QSize &inPresentationDimensions) = 0; + virtual QSize GetCurrentPresentationDimensions() const = 0; + + virtual void SetRenderRotation(RenderRotationValues::Enum inRotation) = 0; + virtual RenderRotationValues::Enum GetRenderRotation() const = 0; + + virtual QT3DSVec2 GetMousePickViewport() const = 0; + virtual QT3DSVec2 GetMousePickMouseCoords(const QT3DSVec2 &inMouseCoords) const = 0; + + // Valid during and just after prepare for render. + virtual QT3DSVec2 GetPresentationScaleFactor() const = 0; + + // Steps needed to render: + // 1. BeginFrame - sets up new target in render graph + // 2. Add everything you need to the render graph + // 3. RunRenderGraph - runs the graph, rendering things to main render target + // 4. Render any additional stuff to main render target on top of previously rendered + // information + // 5. EndFrame + + // Clients need to call this every frame in order for various subsystems to release + // temporary per-frame allocated objects. + // Also sets up the viewport according to SetViewportInfo + // and the topmost presentation dimensions. Expects there to be exactly one presentation + // dimension pushed at this point. + // This also starts a render target in the render graph. + virtual void BeginFrame() = 0; + + // This runs through the added tasks in reverse order. This is used to render dependencies + // before rendering to the main render target. + virtual void RunRenderTasks() = 0; + // Now you can render to the main render target if you want to render over the top + // of everything. + // Next call end frame. + virtual void EndFrame() = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialRenderContext.h b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialRenderContext.h new file mode 100644 index 00000000..5283660c --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialRenderContext.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_RENDER_CONTEXT_H +#define QT3DS_RENDER_CUSTOM_MATERIAL_RENDER_CONTEXT_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSMat44.h" +#include "foundation/Qt3DSMat33.h" +#include "Qt3DSRenderShaderKeys.h" + +namespace qt3ds { +namespace render { + + struct SLayerRenderData; + + struct SCustomMaterialRenderContext + { + // The lights and camera will not change per layer, + // so that information can be set once for all the shaders. + const SLayer &m_Layer; + const SLayerRenderData &m_LayerData; + NVDataRef m_Lights; + const SCamera &m_Camera; + + // Per-object information. + const SModel &m_Model; + const SRenderSubset &m_Subset; + const QT3DSMat44 &m_ModelViewProjection; + const QT3DSMat44 &m_ModelMatrix; ///< model to world transformation + const QT3DSMat33 &m_NormalMatrix; + const SCustomMaterial &m_Material; + const NVRenderTexture2D *m_DepthTexture; + const NVRenderTexture2D *m_AOTexture; + SShaderDefaultMaterialKey m_MaterialKey; + SRenderableImage *m_FirstImage; + QT3DSF32 m_Opacity; + + SCustomMaterialRenderContext( + const SLayer &layer, const SLayerRenderData &data, NVDataRef lights, + const SCamera &cam, const SModel &m, const SRenderSubset &subset, const QT3DSMat44 &mvp, + const QT3DSMat44 &world, const QT3DSMat33 &nm, const SCustomMaterial &material, + const NVRenderTexture2D *depthTex, const NVRenderTexture2D *aoTex, + SShaderDefaultMaterialKey inMaterialKey, SRenderableImage *inFirstImage = NULL, + QT3DSF32 opacity = 1.0) + : m_Layer(layer) + , m_LayerData(data) + , m_Lights(lights) + , m_Camera(cam) + , m_Model(m) + , m_Subset(subset) + , m_ModelViewProjection(mvp) + , m_ModelMatrix(world) + , m_NormalMatrix(nm) + , m_Material(material) + , m_DepthTexture(depthTex) + , m_AOTexture(aoTex) + , m_MaterialKey(inMaterialKey) + , m_FirstImage(inFirstImage) + , m_Opacity(opacity) + { + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.cpp new file mode 100644 index 00000000..fe6a6dc3 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.cpp @@ -0,0 +1,1261 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderCustomMaterialShaderGenerator.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "Qt3DSRenderableImage.h" +#include "Qt3DSRenderImage.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderLight.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderShadowMap.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderLightConstantProperties.h" + +using namespace qt3ds::render; +using qt3ds::render::NVRenderCachedShaderProperty; +using qt3ds::render::NVRenderCachedShaderBuffer; + +namespace { +struct SShaderLightProperties +{ + NVScopedRefCounted m_Shader; + RenderLightTypes::Enum m_LightType; + SLightSourceShader m_LightData; + volatile QT3DSI32 mRefCount; + + SShaderLightProperties(NVRenderShaderProgram &inShader) + : m_Shader(inShader) + , m_LightType(RenderLightTypes::Directional) + , mRefCount(0) + { + } + + void Set(const SLight *inLight) + { + QT3DSVec3 dir(0, 0, 1); + if (inLight->m_LightType == RenderLightTypes::Directional) { + dir = inLight->GetScalingCorrectDirection(); + // we lit in world sapce + dir *= -1; + m_LightData.m_position = QT3DSVec4(dir, 0.0); + } else if (inLight->m_LightType == RenderLightTypes::Area) { + dir = inLight->GetScalingCorrectDirection(); + m_LightData.m_position = QT3DSVec4(inLight->GetGlobalPos(), 1.0); + } else { + dir = inLight->GetGlobalPos(); + m_LightData.m_position = QT3DSVec4(dir, 1.0); + } + + m_LightType = inLight->m_LightType; + + m_LightData.m_direction = QT3DSVec4(dir, 0.0); + + float normalizedBrightness = inLight->m_Brightness / 100.0f; + m_LightData.m_diffuse = QT3DSVec4(inLight->m_DiffuseColor * normalizedBrightness, 1.0); + m_LightData.m_specular = QT3DSVec4(inLight->m_SpecularColor * normalizedBrightness, 1.0); + + if (inLight->m_LightType == RenderLightTypes::Area) { + m_LightData.m_width = inLight->m_AreaWidth; + m_LightData.m_height = inLight->m_AreaWidth; + + QT3DSMat33 theDirMatrix(inLight->m_GlobalTransform.getUpper3x3()); + m_LightData.m_right = + QT3DSVec4(theDirMatrix.transform(QT3DSVec3(1, 0, 0)), inLight->m_AreaWidth); + m_LightData.m_up = + QT3DSVec4(theDirMatrix.transform(QT3DSVec3(0, 1, 0)), inLight->m_AreaHeight); + } else { + m_LightData.m_width = 0.0; + m_LightData.m_height = 0.0; + m_LightData.m_right = QT3DSVec4(0.0f); + m_LightData.m_up = QT3DSVec4(0.0f); + + // These components only apply to CG lights + m_LightData.m_ambient = QT3DSVec4(inLight->m_AmbientColor, 1.0); + + m_LightData.m_constantAttenuation = 1.0; + m_LightData.m_linearAttenuation = inLight->m_LinearFade; + m_LightData.m_quadraticAttenuation = inLight->m_ExponentialFade; + m_LightData.m_spotCutoff = 180.0; + } + + if (m_LightType == RenderLightTypes::Point) { + m_LightData.m_shadowView = QT3DSMat44::createIdentity(); + } else { + m_LightData.m_shadowView = inLight->m_GlobalTransform; + } + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) + + static SShaderLightProperties CreateLightEntry(NVRenderShaderProgram &inShader) + { + return SShaderLightProperties(inShader); + } +}; + +/** + * Cached texture property lookups, used one per texture so a shader generator for N + * textures will have an array of N of these lookup objects. + */ +struct SShaderTextureProperties +{ + NVRenderCachedShaderProperty m_Sampler; + NVRenderCachedShaderProperty m_Offsets; + NVRenderCachedShaderProperty m_Rotations; + SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, + NVRenderShaderProgram &inShader) + : m_Sampler(sampName, inShader) + , m_Offsets(offName, inShader) + , m_Rotations(rotName, inShader) + { + } + SShaderTextureProperties() {} +}; + +/* We setup some shared state on the custom material shaders */ +struct SShaderGeneratorGeneratedShader +{ + typedef nvhash_map TCustomMaterialImagMap; + + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + // Specific properties we know the shader has to have. + NVRenderCachedShaderProperty m_ModelMatrix; + NVRenderCachedShaderProperty m_ViewProjMatrix; + NVRenderCachedShaderProperty m_ViewMatrix; + NVRenderCachedShaderProperty m_NormalMatrix; + NVRenderCachedShaderProperty m_CameraPos; + NVRenderCachedShaderProperty m_ProjMatrix; + NVRenderCachedShaderProperty m_ViewportMatrix; + NVRenderCachedShaderProperty m_CamProperties; + NVRenderCachedShaderProperty m_DepthTexture; + NVRenderCachedShaderProperty m_AOTexture; + NVRenderCachedShaderProperty m_LightProbe; + NVRenderCachedShaderProperty m_LightProbeProps; + NVRenderCachedShaderProperty m_LightProbeOpts; + NVRenderCachedShaderProperty m_LightProbeRot; + NVRenderCachedShaderProperty m_LightProbeOfs; + NVRenderCachedShaderProperty m_LightProbe2; + NVRenderCachedShaderProperty m_LightProbe2Props; + NVRenderCachedShaderProperty m_LightCount; + NVRenderCachedShaderProperty m_AreaLightCount; + NVRenderCachedShaderProperty m_ShadowMapCount; + NVRenderCachedShaderProperty m_ShadowCubeCount; + NVRenderCachedShaderProperty m_Opacity; + NVRenderCachedShaderBuffer m_AoShadowParams; + NVRenderCachedShaderBuffer m_LightsBuffer; + NVRenderCachedShaderBuffer m_AreaLightsBuffer; + + SLightConstantProperties *m_lightsProperties; + SLightConstantProperties *m_areaLightsProperties; + + typedef NVRenderCachedShaderPropertyArray ShadowMapPropertyArray; + typedef NVRenderCachedShaderPropertyArray ShadowCubePropertyArray; + + ShadowMapPropertyArray m_shadowMaps; + ShadowCubePropertyArray m_shadowCubes; + + // Cache the image property name lookups + TCustomMaterialImagMap m_Images; // Images external to custom material usage + volatile QT3DSI32 m_RefCount; + + SShaderGeneratorGeneratedShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) + : m_Allocator(inContext.GetAllocator()) + , m_Shader(inShader) + , m_ModelMatrix("model_matrix", inShader) + , m_ViewProjMatrix("model_view_projection", inShader) + , m_ViewMatrix("view_matrix", inShader) + , m_NormalMatrix("normal_matrix", inShader) + , m_CameraPos("camera_position", inShader) + , m_ProjMatrix("view_projection_matrix", inShader) + , m_ViewportMatrix("viewport_matrix", inShader) + , m_CamProperties("camera_properties", inShader) + , m_DepthTexture("depth_sampler", inShader) + , m_AOTexture("ao_sampler", inShader) + , m_LightProbe("light_probe", inShader) + , m_LightProbeProps("light_probe_props", inShader) + , m_LightProbeOpts("light_probe_opts", inShader) + , m_LightProbeRot("light_probe_rotation", inShader) + , m_LightProbeOfs("light_probe_offset", inShader) + , m_LightProbe2("light_probe2", inShader) + , m_LightProbe2Props("light_probe2_props", inShader) + , m_LightCount("uNumLights", inShader) + , m_AreaLightCount("uNumAreaLights", inShader) + , m_ShadowMapCount("uNumShadowMaps", inShader) + , m_ShadowCubeCount("uNumShadowCubes", inShader) + , m_Opacity("object_opacity", inShader) + , m_AoShadowParams("cbAoShadow", inShader) + , m_LightsBuffer("cbBufferLights", inShader) + , m_AreaLightsBuffer("cbBufferAreaLights", inShader) + , m_lightsProperties(nullptr) + , m_areaLightsProperties(nullptr) + , m_shadowMaps("shadowMaps[0]", inShader) + , m_shadowCubes("shadowCubes[0]", inShader) + , m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images") + , m_RefCount(0) + { + m_Shader.addRef(); + } + + ~SShaderGeneratorGeneratedShader() + { + m_Shader.release(); + delete m_lightsProperties; + delete m_areaLightsProperties; + } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Allocator); + NVDelete(alloc, this); + } + } + + SLightConstantProperties *GetLightProperties(int count) + { + if (!m_lightsProperties || m_areaLightsProperties->m_lightCountInt < count) { + if (m_lightsProperties) + delete m_lightsProperties; + m_lightsProperties = new SLightConstantProperties + ("lights", "uNumLights", *this, false, count); + } + return m_lightsProperties; + } + SLightConstantProperties *GetAreaLightProperties(int count) + { + if (!m_areaLightsProperties || m_areaLightsProperties->m_lightCountInt < count) { + if (m_areaLightsProperties) + delete m_areaLightsProperties; + m_areaLightsProperties = new SLightConstantProperties + ("areaLights", "uNumAreaLights", *this, false, count); + } + return m_areaLightsProperties; + } +}; + +struct SShaderGenerator : public ICustomMaterialShaderGenerator +{ + typedef CRenderString TStrType; + typedef nvhash_map> + TProgramToShaderMap; + typedef eastl::pair> + TCustomMaterialLightEntry; + typedef eastl::pair> TShadowMapEntry; + typedef eastl::pair> + TShadowCubeEntry; + typedef qt3ds::foundation::nvhash_map> + TStrConstanBufMap; + + IQt3DSRenderContext &m_RenderContext; + IShaderProgramGenerator &m_ProgramGenerator; + + const SCustomMaterial *m_CurrentMaterial; + SShaderDefaultMaterialKey *m_CurrentKey; + IDefaultMaterialVertexPipeline *m_CurrentPipeline; + TShaderFeatureSet m_CurrentFeatureSet; + NVDataRef m_Lights; + SRenderableImage *m_FirstImage; + bool m_HasTransparency; + + TStrType m_ImageStem; + TStrType m_ImageSampler; + TStrType m_ImageFragCoords; + TStrType m_ImageRotScale; + TStrType m_ImageOffset; + + eastl::string m_GeneratedShaderString; + + SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; + TProgramToShaderMap m_ProgramToShaderMap; + + nvvector m_LightEntries; + + TStrConstanBufMap m_ConstantBuffers; ///< store all constants buffers + + QT3DSI32 m_RefCount; + + SShaderGenerator(IQt3DSRenderContext &inRc) + : m_RenderContext(inRc) + , m_ProgramGenerator(m_RenderContext.GetShaderProgramGenerator()) + , m_CurrentMaterial(NULL) + , m_CurrentKey(NULL) + , m_CurrentPipeline(NULL) + , m_FirstImage(NULL) + , m_HasTransparency(false) + , m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap") + , m_LightEntries(inRc.GetAllocator(), "m_LightEntries") + , m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers") + , m_RefCount(0) + { + } + + void addRef() override { atomicIncrement(&m_RefCount); } + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + m_ConstantBuffers.clear(); + NVDelete(m_RenderContext.GetAllocator(), this); + } + } + + IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } + IDefaultMaterialVertexPipeline &VertexGenerator() { return *m_CurrentPipeline; } + IShaderStageGenerator &FragmentGenerator() + { + return *m_ProgramGenerator.GetStage(ShaderGeneratorStages::Fragment); + } + SShaderDefaultMaterialKey &Key() { return *m_CurrentKey; } + const SCustomMaterial &Material() { return *m_CurrentMaterial; } + TShaderFeatureSet FeatureSet() { return m_CurrentFeatureSet; } + bool HasTransparency() { return m_HasTransparency; } + + QT3DSU32 + ConvertTextureTypeValue(ImageMapTypes::Enum inType) + { + NVRenderTextureTypeValue::Enum retVal = NVRenderTextureTypeValue::Unknown; + + switch (inType) { + case ImageMapTypes::LightmapIndirect: + retVal = NVRenderTextureTypeValue::LightmapIndirect; + break; + case ImageMapTypes::LightmapRadiosity: + retVal = NVRenderTextureTypeValue::LightmapRadiosity; + break; + case ImageMapTypes::LightmapShadow: + retVal = NVRenderTextureTypeValue::LightmapShadow; + break; + case ImageMapTypes::Bump: + retVal = NVRenderTextureTypeValue::Bump; + break; + case ImageMapTypes::Diffuse: + retVal = NVRenderTextureTypeValue::Diffuse; + break; + case ImageMapTypes::Displacement: + retVal = NVRenderTextureTypeValue::Displace; + break; + default: + retVal = NVRenderTextureTypeValue::Unknown; + break; + } + + QT3DS_ASSERT(retVal != NVRenderTextureTypeValue::Unknown); + + return (QT3DSU32)retVal; + } + + SImageVariableNames GetImageVariableNames(QT3DSU32 imageIdx) override + { + // convert to NVRenderTextureTypeValue + NVRenderTextureTypeValue::Enum texType = (NVRenderTextureTypeValue::Enum)imageIdx; + m_ImageStem = NVRenderTextureTypeValue::toString(texType); + m_ImageStem.append("_"); + m_ImageSampler = m_ImageStem; + m_ImageSampler.append("sampler"); + m_ImageFragCoords = m_ImageStem; + m_ImageFragCoords.append("uv_coords"); + m_ImageRotScale = m_ImageStem; + m_ImageRotScale.append("rot_scale"); + m_ImageOffset = m_ImageStem; + m_ImageOffset.append("offset"); + + SImageVariableNames retVal; + retVal.m_ImageSampler = m_ImageSampler.c_str(); + retVal.m_ImageFragCoords = m_ImageFragCoords.c_str(); + return retVal; + } + + void SetImageShaderVariables(SShaderGeneratorGeneratedShader &inShader, + SRenderableImage &inImage) + { + // skip displacement and emissive mask maps which are handled differently + if (inImage.m_MapType == ImageMapTypes::Displacement + || inImage.m_MapType == ImageMapTypes::Emissive) + return; + + SShaderGeneratorGeneratedShader::TCustomMaterialImagMap::iterator iter = + inShader.m_Images.find(inImage.m_MapType); + if (iter == inShader.m_Images.end()) { + SImageVariableNames names = + GetImageVariableNames(ConvertTextureTypeValue(inImage.m_MapType)); + inShader.m_Images.insert(eastl::make_pair( + (QT3DSU32)inImage.m_MapType, + SShaderTextureProperties(names.m_ImageSampler, m_ImageOffset.c_str(), + m_ImageRotScale.c_str(), inShader.m_Shader))); + iter = inShader.m_Images.find(inImage.m_MapType); + } + + SShaderTextureProperties &theShaderProps = iter->second; + const QT3DSMat44 &textureTransform = inImage.m_Image.m_TextureTransform; + const QT3DSF32 *dataPtr(textureTransform.front()); + QT3DSVec3 offsets(dataPtr[12], dataPtr[13], 0.0f); + // Grab just the upper 2x2 rotation matrix from the larger matrix. + QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); + + // The image horizontal and vertical tiling modes need to be set here, before we set texture + // on the shader. + // because setting the image on the texture forces the textue to bind and immediately apply + // any tex params. + inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapS( + inImage.m_Image.m_HorizontalTilingMode); + inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapT( + inImage.m_Image.m_VerticalTilingMode); + + theShaderProps.m_Sampler.Set(inImage.m_Image.m_TextureData.m_Texture); + theShaderProps.m_Offsets.Set(offsets); + theShaderProps.m_Rotations.Set(rotations); + } + + void GenerateImageUVCoordinates(IShaderStageGenerator &, QT3DSU32, QT3DSU32, SRenderableImage &) override {} + + ///< get the light constant buffer and generate if necessary + NVRenderConstantBuffer *GetLightConstantBuffer(const char *name, QT3DSU32 inLightCount) + { + NVRenderContext &theContext(m_RenderContext.GetRenderContext()); + + // we assume constant buffer support + QT3DS_ASSERT(theContext.GetConstantBufferSupport()); + // we only create if if we have lights + if (!inLightCount || !theContext.GetConstantBufferSupport()) + return NULL; + + CRegisteredString theName = theContext.GetStringTable().RegisterStr(name); + NVRenderConstantBuffer *pCB = theContext.GetConstantBuffer(theName); + + if (!pCB) { + // create with size of all structures + int for light count + SLightSourceShader s[QT3DS_MAX_NUM_LIGHTS]; + NVDataRef cBuffer((QT3DSU8 *)&s, (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + + (4 * sizeof(QT3DSI32))); + pCB = theContext.CreateConstantBuffer( + name, qt3ds::render::NVRenderBufferUsageType::Static, + (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + (4 * sizeof(QT3DSI32)), cBuffer); + if (!pCB) { + QT3DS_ASSERT(false); + return NULL; + } + // init first set + memset(&s[0], 0x0, sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS); + QT3DSI32 cgLights[4] = {0, 0, 0, 0}; + pCB->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32) * 4)); + pCB->UpdateRaw(4 * sizeof(QT3DSI32), + NVDataRef((QT3DSU8 *)&s[0], + sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS)); + pCB->Update(); // update to hardware + + m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); + } + + return pCB; + } + + bool GenerateVertexShader(SShaderDefaultMaterialKey &, const char8_t *inShaderPathName) + { + qt3ds::render::IDynamicObjectSystem &theDynamicSystem( + m_RenderContext.GetDynamicObjectSystem()); + CRenderString theShaderBuffer; + const char8_t *vertSource = theDynamicSystem.GetShaderSource( + m_RenderContext.GetStringTable().RegisterStr(inShaderPathName), theShaderBuffer); + + QT3DS_ASSERT(vertSource); + eastl::string srcString(vertSource); + + // Check if the vertex shader portion already contains a main function + // The same string contains both the vertex and the fragment shader + // The last "#ifdef FRAGMENT_SHADER" should mark the start of the fragment shader + eastl_size_t fragmentDefStart = srcString.find("#ifdef FRAGMENT_SHADER"); + eastl_size_t nextIndex = fragmentDefStart; + while (nextIndex != eastl::string::npos) { + nextIndex = srcString.find("#ifdef FRAGMENT_SHADER", nextIndex + 1); + if (nextIndex != eastl::string::npos) + fragmentDefStart = nextIndex; + } + eastl_size_t mainStart = srcString.find("void main()"); + + if (mainStart != eastl::string::npos && (fragmentDefStart == eastl::string::npos + || mainStart < fragmentDefStart)) { + TShaderGeneratorStageFlags stages(IShaderProgramGenerator::DefaultFlags()); + ProgramGenerator().BeginProgram(stages); + IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); + vertexShader << "#define VERTEX_SHADER\n\n"; + vertexShader << srcString.data() << Endl; + return true; + } + + // vertex displacement + QT3DSU32 imageIdx = 0; + SRenderableImage *displacementImage = NULL; + QT3DSU32 displacementImageIdx = 0; + + for (SRenderableImage *img = m_FirstImage; img != NULL; + img = img->m_NextImage, ++imageIdx) { + if (img->m_MapType == ImageMapTypes::Displacement) { + displacementImage = img; + displacementImageIdx = imageIdx; + break; + } + } + + // the pipeline opens/closes up the shaders stages + VertexGenerator().BeginVertexGeneration(displacementImageIdx, displacementImage); + return false; + } + + SShaderGeneratorGeneratedShader &GetShaderForProgram(NVRenderShaderProgram &inProgram) + { + eastl::pair inserter = + m_ProgramToShaderMap.insert(eastl::make_pair( + &inProgram, NVScopedRefCounted(NULL))); + if (inserter.second) { + NVAllocatorCallback &alloc(m_RenderContext.GetRenderContext().GetAllocator()); + inserter.first->second = QT3DS_NEW(alloc, SShaderGeneratorGeneratedShader)( + inProgram, m_RenderContext.GetRenderContext()); + } + return *inserter.first->second; + } + + virtual SShaderLightProperties *SetLight(NVRenderShaderProgram &inShader, size_t lightIdx, + size_t shadeIdx, const SLight *inLight, + SShadowMapEntry *inShadow, QT3DSI32 shadowIdx, + QT3DSF32 shadowDist) + { + SShaderLightProperties *theLightEntry(NULL); + for (QT3DSU32 idx = 0, end = m_LightEntries.size(); idx < end && theLightEntry == NULL; + ++idx) { + if (m_LightEntries[idx].first == lightIdx + && m_LightEntries[idx].second->m_Shader.mPtr == &inShader + && m_LightEntries[idx].second->m_LightType == inLight->m_LightType) { + theLightEntry = m_LightEntries[idx].second; + } + } + if (theLightEntry == NULL) { + // create a new name + eastl::string lightName; + if (inLight->m_LightType == RenderLightTypes::Area) + lightName = "arealights"; + else + lightName = "lights"; + char buf[16]; + _snprintf(buf, 16, "[%d]", int(shadeIdx)); + lightName.append(buf); + + NVScopedRefCounted theNewEntry = + QT3DS_NEW(m_RenderContext.GetAllocator(), + SShaderLightProperties)(SShaderLightProperties::CreateLightEntry(inShader)); + m_LightEntries.push_back(eastl::make_pair(lightIdx, theNewEntry)); + theLightEntry = theNewEntry.mPtr; + } + theLightEntry->Set(inLight); + theLightEntry->m_LightData.m_shadowControls = + QT3DSVec4(inLight->m_ShadowBias, inLight->m_ShadowFactor, shadowDist, 0.0); + theLightEntry->m_LightData.m_shadowIdx = (inShadow) ? shadowIdx : -1; + + return theLightEntry; + } + + void SetShadowMaps(NVRenderShaderProgram &inProgram, SShadowMapEntry *inShadow, + QT3DSI32 &numShadowMaps, QT3DSI32 &numShadowCubes, bool shadowMap, + SShaderGeneratorGeneratedShader::ShadowMapPropertyArray &shadowMaps, + SShaderGeneratorGeneratedShader::ShadowCubePropertyArray &shadowCubes) + { + Q_UNUSED(inProgram) + if (inShadow) { + if (shadowMap == false && inShadow->m_DepthCube + && (numShadowCubes < QT3DS_MAX_NUM_SHADOWS)) { + shadowCubes.m_array[numShadowCubes] = inShadow->m_DepthCube.mPtr; + ++numShadowCubes; + } else if (shadowMap && inShadow->m_DepthMap + && (numShadowMaps < QT3DS_MAX_NUM_SHADOWS)) { + shadowMaps.m_array[numShadowMaps] = inShadow->m_DepthMap.mPtr; + ++numShadowMaps; + } + } + } + + void SetGlobalProperties(NVRenderShaderProgram &inProgram, const SLayer & /*inLayer*/ + , + SCamera &inCamera, QT3DSVec3, NVDataRef inLights, + NVDataRef, Qt3DSShadowMap *inShadowMaps) + { + SShaderGeneratorGeneratedShader &theShader(GetShaderForProgram(inProgram)); + m_RenderContext.GetRenderContext().SetActiveShader(&inProgram); + + SCamera &theCamera(inCamera); + + QT3DSVec2 camProps(theCamera.m_ClipNear, theCamera.m_ClipFar); + theShader.m_CamProperties.Set(camProps); + theShader.m_CameraPos.Set(theCamera.GetGlobalPos()); + + if (theShader.m_ViewMatrix.IsValid()) + theShader.m_ViewMatrix.Set(theCamera.m_GlobalTransform.getInverse()); + + if (theShader.m_ProjMatrix.IsValid()) { + QT3DSMat44 vProjMat; + inCamera.CalculateViewProjectionMatrix(vProjMat); + theShader.m_ProjMatrix.Set(vProjMat); + } + + // set lights separate for area lights + QT3DSI32 cgLights = 0, areaLights = 0; + QT3DSI32 numShadowMaps = 0, numShadowCubes = 0; + + // this call setup the constant buffer for ambient occlusion and shadow + theShader.m_AoShadowParams.Set(); + + if (m_RenderContext.GetRenderContext().GetConstantBufferSupport()) { + NVRenderConstantBuffer *pLightCb = + GetLightConstantBuffer("cbBufferLights", inLights.size()); + NVRenderConstantBuffer *pAreaLightCb = + GetLightConstantBuffer("cbBufferAreaLights", inLights.size()); + + // Split the count between CG lights and area lights + for (QT3DSU32 lightIdx = 0; lightIdx < inLights.size() && pLightCb; ++lightIdx) { + SShadowMapEntry *theShadow = NULL; + if (inShadowMaps && inLights[lightIdx]->m_CastShadow) + theShadow = inShadowMaps->GetShadowMapEntry(lightIdx); + + QT3DSI32 shdwIdx = (inLights[lightIdx]->m_LightType + != RenderLightTypes::Directional) + ? numShadowCubes + : numShadowMaps; + SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes, + inLights[lightIdx]->m_LightType == RenderLightTypes::Directional, + theShader.m_shadowMaps, theShader.m_shadowCubes); + + if (inLights[lightIdx]->m_LightType == RenderLightTypes::Area) { + SShaderLightProperties *theAreaLightEntry = + SetLight(inProgram, lightIdx, areaLights, inLights[lightIdx], theShadow, + shdwIdx, inCamera.m_ClipFar); + + if (theAreaLightEntry && pAreaLightCb) { + pAreaLightCb->UpdateRaw( + areaLights * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), + NVDataRef((QT3DSU8 *)&theAreaLightEntry->m_LightData, + sizeof(SLightSourceShader))); + } + + areaLights++; + } else { + SShaderLightProperties *theLightEntry = + SetLight(inProgram, lightIdx, cgLights, inLights[lightIdx], theShadow, + shdwIdx, inCamera.m_ClipFar); + + if (theLightEntry && pLightCb) { + pLightCb->UpdateRaw( + cgLights * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), + NVDataRef((QT3DSU8 *)&theLightEntry->m_LightData, + sizeof(SLightSourceShader))); + } + + cgLights++; + } + } + + if (pLightCb) { + pLightCb->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); + theShader.m_LightsBuffer.Set(); + } + if (pAreaLightCb) { + pAreaLightCb->UpdateRaw(0, NVDataRef((QT3DSU8 *)&areaLights, + sizeof(QT3DSI32))); + theShader.m_AreaLightsBuffer.Set(); + } + + theShader.m_LightCount.Set(cgLights); + theShader.m_AreaLightCount.Set(areaLights); + } else { + QVector lprop; + QVector alprop; + for (QT3DSU32 lightIdx = 0; lightIdx < inLights.size(); ++lightIdx) { + + SShadowMapEntry *theShadow = NULL; + if (inShadowMaps && inLights[lightIdx]->m_CastShadow) + theShadow = inShadowMaps->GetShadowMapEntry(lightIdx); + + QT3DSI32 shdwIdx = (inLights[lightIdx]->m_LightType + != RenderLightTypes::Directional) + ? numShadowCubes + : numShadowMaps; + SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes, + inLights[lightIdx]->m_LightType == RenderLightTypes::Directional, + theShader.m_shadowMaps, theShader.m_shadowCubes); + + SShaderLightProperties *p = SetLight(inProgram, lightIdx, areaLights, + inLights[lightIdx], theShadow, + shdwIdx, inCamera.m_ClipFar); + if (inLights[lightIdx]->m_LightType == RenderLightTypes::Area) + alprop.push_back(p); + else + lprop.push_back(p); + } + SLightConstantProperties *lightProperties + = theShader.GetLightProperties(lprop.size()); + SLightConstantProperties *areaLightProperties + = theShader.GetAreaLightProperties(alprop.size()); + + lightProperties->updateLights(lprop); + areaLightProperties->updateLights(alprop); + + theShader.m_LightCount.Set(lprop.size()); + theShader.m_AreaLightCount.Set(alprop.size()); + } + for (int i = numShadowMaps; i < QT3DS_MAX_NUM_SHADOWS; ++i) + theShader.m_shadowMaps.m_array[i] = NULL; + for (int i = numShadowCubes; i < QT3DS_MAX_NUM_SHADOWS; ++i) + theShader.m_shadowCubes.m_array[i] = NULL; + theShader.m_shadowMaps.Set(numShadowMaps); + theShader.m_shadowCubes.Set(numShadowCubes); + theShader.m_ShadowMapCount.Set(numShadowMaps); + theShader.m_ShadowCubeCount.Set(numShadowCubes); + } + + void SetMaterialProperties(NVRenderShaderProgram &inProgram, const SCustomMaterial &inMaterial, + const QT3DSVec2 &, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inSSaoTexture, + SImage *inLightProbe, SImage *inLightProbe2, QT3DSF32 inProbeHorizon, + QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, + QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) + { + ICustomMaterialSystem &theMaterialSystem(m_RenderContext.GetCustomMaterialSystem()); + SShaderGeneratorGeneratedShader &theShader(GetShaderForProgram(inProgram)); + + theShader.m_ViewProjMatrix.Set(inModelViewProjection); + theShader.m_NormalMatrix.Set(inNormalMatrix); + theShader.m_ModelMatrix.Set(inGlobalTransform); + + theShader.m_DepthTexture.Set(inDepthTexture); + theShader.m_AOTexture.Set(inSSaoTexture); + + theShader.m_Opacity.Set(inOpacity); + + qt3ds::render::SImage *theLightProbe = inLightProbe; + qt3ds::render::SImage *theLightProbe2 = inLightProbe2; + + if (inMaterial.m_IblProbe && inMaterial.m_IblProbe->m_TextureData.m_Texture) { + theLightProbe = inMaterial.m_IblProbe; + } + + if (theLightProbe) { + if (theLightProbe->m_TextureData.m_Texture) { + NVRenderTextureCoordOp::Enum theHorzLightProbeTilingMode = + theLightProbe->m_HorizontalTilingMode; + NVRenderTextureCoordOp::Enum theVertLightProbeTilingMode = + theLightProbe->m_VerticalTilingMode; + theLightProbe->m_TextureData.m_Texture->SetTextureWrapS( + theHorzLightProbeTilingMode); + theLightProbe->m_TextureData.m_Texture->SetTextureWrapT( + theVertLightProbeTilingMode); + + const QT3DSMat44 &textureTransform = theLightProbe->m_TextureTransform; + // We separate rotational information from offset information so that just maybe the + // shader + // will attempt to push less information to the card. + const QT3DSF32 *dataPtr(textureTransform.front()); + // The third member of the offsets contains a flag indicating if the texture was + // premultiplied or not. + // We use this to mix the texture alpha. + // light_probe_offsets.w is now no longer being used to enable/disable fast IBL, + // (it's now the only option) + // So now, it's storing the number of mip levels in the IBL image. + QT3DSVec4 offsets(dataPtr[12], dataPtr[13], + theLightProbe->m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f + : 0.0f, + (float)theLightProbe->m_TextureData.m_Texture->GetNumMipmaps()); + // Fast IBL is always on; + // inRenderContext.m_Layer.m_FastIbl ? 1.0f : 0.0f ); + // Grab just the upper 2x2 rotation matrix from the larger matrix. + QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); + + theShader.m_LightProbeRot.Set(rotations); + theShader.m_LightProbeOfs.Set(offsets); + + if ((!inMaterial.m_IblProbe) && (inProbeFOV < 180.f)) { + theShader.m_LightProbeOpts.Set( + QT3DSVec4(0.01745329251994329547f * inProbeFOV, 0.0f, 0.0f, 0.0f)); + } + + // Also make sure to add the secondary texture, but it should only be added if the + // primary + // (i.e. background) texture is also there. + if (theLightProbe2 && theLightProbe2->m_TextureData.m_Texture) { + theLightProbe2->m_TextureData.m_Texture->SetTextureWrapS( + theHorzLightProbeTilingMode); + theLightProbe2->m_TextureData.m_Texture->SetTextureWrapT( + theVertLightProbeTilingMode); + theShader.m_LightProbe2.Set(theLightProbe2->m_TextureData.m_Texture); + theShader.m_LightProbe2Props.Set( + QT3DSVec4(inProbe2Window, inProbe2Pos, inProbe2Fade, 1.0f)); + + const QT3DSMat44 &xform2 = theLightProbe2->m_TextureTransform; + const QT3DSF32 *dataPtr(xform2.front()); + + theShader.m_LightProbeProps.Set( + QT3DSVec4(dataPtr[12], dataPtr[13], inProbeHorizon, inProbeBright * 0.01f)); + } else { + theShader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + theShader.m_LightProbeProps.Set( + QT3DSVec4(0.0f, 0.0f, inProbeHorizon, inProbeBright * 0.01f)); + } + } else { + theShader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); + theShader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + } + + theShader.m_LightProbe.Set(theLightProbe->m_TextureData.m_Texture); + + } else { + theShader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); + theShader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + } + + // finally apply custom material shader properties + theMaterialSystem.ApplyShaderPropertyValues(inMaterial, inProgram); + + // additional textures + for (SRenderableImage *theImage = inFirstImage; theImage; theImage = theImage->m_NextImage) + SetImageShaderVariables(theShader, *theImage); + } + + void SetMaterialProperties(NVRenderShaderProgram &inProgram, + const SGraphObject &inMaterial, const QT3DSVec2 &inCameraVec, + const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, + const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + SLayerGlobalRenderProperties inRenderProperties) override + { + const SCustomMaterial &theCustomMaterial( + reinterpret_cast(inMaterial)); + QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::CustomMaterial); + + SetGlobalProperties(inProgram, inRenderProperties.m_Layer, inRenderProperties.m_Camera, + inRenderProperties.m_CameraDirection, inRenderProperties.m_Lights, + inRenderProperties.m_LightDirections, + inRenderProperties.m_ShadowMapManager); + + SetMaterialProperties(inProgram, theCustomMaterial, inCameraVec, inModelViewProjection, + inNormalMatrix, inGlobalTransform, inFirstImage, inOpacity, + inRenderProperties.m_DepthTexture, inRenderProperties.m_SSaoTexture, + inRenderProperties.m_LightProbe, inRenderProperties.m_LightProbe2, + inRenderProperties.m_ProbeHorizon, inRenderProperties.m_ProbeBright, + inRenderProperties.m_Probe2Window, inRenderProperties.m_Probe2Pos, + inRenderProperties.m_Probe2Fade, inRenderProperties.m_ProbeFOV); + } + + void GenerateLightmapIndirectFunc(IShaderStageGenerator &inFragmentShader, + SImage *pEmissiveLightmap) + { + inFragmentShader << "\n"; + inFragmentShader << "vec3 computeMaterialLightmapIndirect()\n{\n"; + inFragmentShader << " vec4 indirect = vec4( 0.0, 0.0, 0.0, 0.0 );\n"; + if (pEmissiveLightmap) { + SImageVariableNames names = + GetImageVariableNames(ConvertTextureTypeValue(ImageMapTypes::LightmapIndirect)); + inFragmentShader.AddUniform(names.m_ImageSampler, "sampler2D"); + inFragmentShader.AddUniform(m_ImageOffset, "vec3"); + inFragmentShader.AddUniform(m_ImageRotScale, "vec4"); + + inFragmentShader << "\n indirect = evalIndirectLightmap( " << m_ImageSampler + << ", varTexCoord1, "; + inFragmentShader << m_ImageRotScale << ", "; + inFragmentShader << m_ImageOffset << " );\n\n"; + } + + inFragmentShader << " return indirect.rgb;\n"; + inFragmentShader << "}\n\n"; + } + + void GenerateLightmapRadiosityFunc(IShaderStageGenerator &inFragmentShader, + SImage *pRadiosityLightmap) + { + inFragmentShader << "\n"; + inFragmentShader << "vec3 computeMaterialLightmapRadiosity()\n{\n"; + inFragmentShader << " vec4 radiosity = vec4( 1.0, 1.0, 1.0, 1.0 );\n"; + if (pRadiosityLightmap) { + SImageVariableNames names = + GetImageVariableNames(ConvertTextureTypeValue(ImageMapTypes::LightmapRadiosity)); + inFragmentShader.AddUniform(names.m_ImageSampler, "sampler2D"); + inFragmentShader.AddUniform(m_ImageOffset, "vec3"); + inFragmentShader.AddUniform(m_ImageRotScale, "vec4"); + + inFragmentShader << "\n radiosity = evalRadiosityLightmap( " << m_ImageSampler + << ", varTexCoord1, "; + inFragmentShader << m_ImageRotScale << ", "; + inFragmentShader << m_ImageOffset << " );\n\n"; + } + + inFragmentShader << " return radiosity.rgb;\n"; + inFragmentShader << "}\n\n"; + } + + void GenerateLightmapShadowFunc(IShaderStageGenerator &inFragmentShader, + SImage *pBakedShadowMap) + { + inFragmentShader << "\n"; + inFragmentShader << "vec4 computeMaterialLightmapShadow()\n{\n"; + inFragmentShader << " vec4 shadowMask = vec4( 1.0, 1.0, 1.0, 1.0 );\n"; + if (pBakedShadowMap) { + SImageVariableNames names = + GetImageVariableNames((QT3DSU32)NVRenderTextureTypeValue::LightmapShadow); + // Add uniforms + inFragmentShader.AddUniform(names.m_ImageSampler, "sampler2D"); + inFragmentShader.AddUniform(m_ImageOffset, "vec3"); + inFragmentShader.AddUniform(m_ImageRotScale, "vec4"); + + inFragmentShader << "\n shadowMask = evalShadowLightmap( " << m_ImageSampler + << ", texCoord0, "; + inFragmentShader << m_ImageRotScale << ", "; + inFragmentShader << m_ImageOffset << " );\n\n"; + } + + inFragmentShader << " return shadowMask;\n"; + inFragmentShader << "}\n\n"; + } + + void GenerateLightmapIndirectSetupCode(IShaderStageGenerator &inFragmentShader, + SRenderableImage *pIndirectLightmap, + SRenderableImage *pRadiosityLightmap) + { + if (!pIndirectLightmap && !pRadiosityLightmap) + return; + + eastl::string finalValue; + + inFragmentShader << "\n"; + inFragmentShader << "void initializeLayerVariablesWithLightmap(void)\n{\n"; + if (pIndirectLightmap) { + inFragmentShader + << " vec3 lightmapIndirectValue = computeMaterialLightmapIndirect( );\n"; + finalValue.append("vec4(lightmapIndirectValue, 1.0)"); + } + if (pRadiosityLightmap) { + inFragmentShader + << " vec3 lightmapRadisoityValue = computeMaterialLightmapRadiosity( );\n"; + if (finalValue.empty()) + finalValue.append("vec4(lightmapRadisoityValue, 1.0)"); + else + finalValue.append(" + vec4(lightmapRadisoityValue, 1.0)"); + } + + finalValue.append(";\n"); + + char buf[16]; + for (QT3DSU32 idx = 0; idx < Material().m_LayerCount; idx++) { + _snprintf(buf, 16, "[%d]", idx); + inFragmentShader << " layers" << buf << ".base += " << finalValue.c_str(); + inFragmentShader << " layers" << buf << ".layer += " << finalValue.c_str(); + } + + inFragmentShader << "}\n\n"; + } + + void GenerateLightmapShadowCode(IShaderStageGenerator &inFragmentShader, + SRenderableImage *pBakedShadowMap) + { + if (pBakedShadowMap) { + inFragmentShader << " tmpShadowTerm *= computeMaterialLightmapShadow( );\n\n"; + } + } + + void ApplyEmissiveMask(IShaderStageGenerator &inFragmentShader, SImage *pEmissiveMaskMap) + { + inFragmentShader << "\n"; + inFragmentShader << "vec3 computeMaterialEmissiveMask()\n{\n"; + inFragmentShader << " vec3 emissiveMask = vec3( 1.0, 1.0, 1.0 );\n"; + if (pEmissiveMaskMap) { + inFragmentShader << " texture_coordinate_info tci;\n"; + inFragmentShader << " texture_coordinate_info transformed_tci;\n"; + inFragmentShader << " tci = textureCoordinateInfo( texCoord0, tangent, binormal );\n"; + inFragmentShader << " transformed_tci = transformCoordinate( " + "rotationTranslationScale( vec3( 0.000000, 0.000000, 0.000000 ), "; + inFragmentShader << "vec3( 0.000000, 0.000000, 0.000000 ), vec3( 1.000000, 1.000000, " + "1.000000 ) ), tci );\n"; + inFragmentShader << " emissiveMask = fileTexture( " + << pEmissiveMaskMap->m_ImageShaderName.c_str() + << ", vec3( 0, 0, 0 ), vec3( 1, 1, 1 ), mono_alpha, transformed_tci, "; + inFragmentShader << "vec2( 0.000000, 1.000000 ), vec2( 0.000000, 1.000000 ), " + "wrap_repeat, wrap_repeat, gamma_default ).tint;\n"; + } + + inFragmentShader << " return emissiveMask;\n"; + inFragmentShader << "}\n\n"; + } + + void GenerateFragmentShader(SShaderDefaultMaterialKey &, const char8_t *inShaderPathName, + bool hasCustomVertexShader) + { + qt3ds::render::IDynamicObjectSystem &theDynamicSystem( + m_RenderContext.GetDynamicObjectSystem()); + CRenderString theShaderBuffer; + const char8_t *fragSource = theDynamicSystem.GetShaderSource( + m_RenderContext.GetStringTable().RegisterStr(inShaderPathName), theShaderBuffer); + + QT3DS_ASSERT(fragSource); + + // light maps + bool hasLightmaps = false; + SRenderableImage *lightmapShadowImage = NULL; + SRenderableImage *lightmapIndirectImage = NULL; + SRenderableImage *lightmapRadisoityImage = NULL; + + for (SRenderableImage *img = m_FirstImage; img != NULL; img = img->m_NextImage) { + if (img->m_MapType == ImageMapTypes::LightmapIndirect) { + lightmapIndirectImage = img; + hasLightmaps = true; + } else if (img->m_MapType == ImageMapTypes::LightmapRadiosity) { + lightmapRadisoityImage = img; + hasLightmaps = true; + } else if (img->m_MapType == ImageMapTypes::LightmapShadow) { + lightmapShadowImage = img; + } + } + + if (!hasCustomVertexShader) { + VertexGenerator().GenerateUVCoords(0); + // for lightmaps we expect a second set of uv coordinates + if (hasLightmaps) + VertexGenerator().GenerateUVCoords(1); + } + + IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); + IShaderStageGenerator &fragmentShader(FragmentGenerator()); + + eastl::string srcString(fragSource); + + if (m_RenderContext.GetRenderContext().GetRenderContextType() + == NVRenderContextValues::GLES2) { + eastl::string::size_type pos = 0; + while ((pos = srcString.find("out vec4 fragColor", pos)) != eastl::string::npos) { + srcString.insert(pos, "//"); + pos += int(strlen("//out vec4 fragColor")); + } + } + + fragmentShader << "#define FRAGMENT_SHADER\n\n"; + + // Check if the fragment shader portion already contains a main function + // The same string contains both the vertex and the fragment shader + // The last "#ifdef FRAGMENT_SHADER" should mark the start of the fragment shader + eastl_size_t fragmentDefStart = srcString.find("#ifdef FRAGMENT_SHADER"); + eastl_size_t nextIndex = fragmentDefStart; + while (nextIndex != eastl::string::npos) { + nextIndex = srcString.find("#ifdef FRAGMENT_SHADER", nextIndex + 1); + if (nextIndex != eastl::string::npos) + fragmentDefStart = nextIndex; + } + eastl_size_t mainStart = srcString.find("void main()"); + if (fragmentDefStart == eastl::string::npos) + return; + + if (mainStart != eastl::string::npos && mainStart < fragmentDefStart) + mainStart = srcString.find("void main()", mainStart + 1); + + bool hasCustomFragmentShader = mainStart != eastl::string::npos; + + if (!hasCustomFragmentShader) + fragmentShader.AddInclude("evalLightmaps.glsllib"); + + // check dielectric materials + if (!Material().IsDielectric()) + fragmentShader << "#define MATERIAL_IS_NON_DIELECTRIC 1\n\n"; + else + fragmentShader << "#define MATERIAL_IS_NON_DIELECTRIC 0\n\n"; + + fragmentShader << "#define QT3DS_ENABLE_RNM 0\n\n"; + + fragmentShader << srcString.data() << Endl; + + if (hasCustomFragmentShader) { + fragmentShader << "#define FRAGMENT_SHADER\n\n"; + if (!hasCustomVertexShader) { + vertexShader.GenerateWorldNormal(); + vertexShader.GenerateVarTangentAndBinormal(); + vertexShader.GenerateWorldPosition(); + + vertexShader.GenerateViewVector(); + } + return; + } + + if (Material().HasLighting() && lightmapIndirectImage) { + GenerateLightmapIndirectFunc(fragmentShader, &lightmapIndirectImage->m_Image); + } + if (Material().HasLighting() && lightmapRadisoityImage) { + GenerateLightmapRadiosityFunc(fragmentShader, &lightmapRadisoityImage->m_Image); + } + if (Material().HasLighting() && lightmapShadowImage) { + GenerateLightmapShadowFunc(fragmentShader, &lightmapShadowImage->m_Image); + } + + if (Material().HasLighting() && (lightmapIndirectImage || lightmapRadisoityImage)) + GenerateLightmapIndirectSetupCode(fragmentShader, lightmapIndirectImage, + lightmapRadisoityImage); + + if (Material().HasLighting()) { + ApplyEmissiveMask(fragmentShader, Material().m_EmissiveMap2); + } + + // setup main + VertexGenerator().BeginFragmentGeneration(); + + // since we do pixel lighting we always need this if lighting is enabled + // We write this here because the functions below may also write to + // the fragment shader + if (Material().HasLighting()) { + vertexShader.GenerateWorldNormal(); + vertexShader.GenerateVarTangentAndBinormal(); + vertexShader.GenerateWorldPosition(); + + if (Material().IsSpecularEnabled()) + vertexShader.GenerateViewVector(); + } + + fragmentShader << " initializeBaseFragmentVariables();" << Endl; + fragmentShader << " computeTemporaries();" << Endl; + fragmentShader << " normal = normalize( computeNormal() );" << Endl; + fragmentShader << " initializeLayerVariables();" << Endl; + fragmentShader << " float alpha = clamp( evalCutout(), 0.0, 1.0 );" << Endl; + + if (Material().IsCutOutEnabled()) { + fragmentShader << " if ( alpha <= 0.0f )" << Endl; + fragmentShader << " discard;" << Endl; + } + + // indirect / direct lightmap init + if (Material().HasLighting() && (lightmapIndirectImage || lightmapRadisoityImage)) + fragmentShader << " initializeLayerVariablesWithLightmap();" << Endl; + + // shadow map + GenerateLightmapShadowCode(fragmentShader, lightmapShadowImage); + + // main Body + fragmentShader << "#include \"customMaterialFragBodyAO.glsllib\"" << Endl; + + // for us right now transparency means we render a glass style material + if (m_HasTransparency && !Material().IsTransmissive()) + fragmentShader << " rgba = computeGlass( normal, materialIOR, alpha, rgba );" << Endl; + if (Material().IsTransmissive()) + fragmentShader << " rgba = computeOpacity( rgba );" << Endl; + + if (VertexGenerator().HasActiveWireframe()) { + fragmentShader.Append("vec3 edgeDistance = varEdgeDistance * gl_FragCoord.w;"); + fragmentShader.Append( + "\tfloat d = min(min(edgeDistance.x, edgeDistance.y), edgeDistance.z);"); + fragmentShader.Append("\tfloat mixVal = smoothstep(0.0, 1.0, d);"); // line width 1.0 + + fragmentShader.Append("\trgba = mix( vec4(0.0, 1.0, 0.0, 1.0), rgba, mixVal);"); + } + fragmentShader << " rgba.a *= object_opacity;" << Endl; + if (m_RenderContext.GetRenderContext().GetRenderContextType() + == NVRenderContextValues::GLES2) + fragmentShader << " gl_FragColor = rgba;" << Endl; + else + fragmentShader << " fragColor = rgba;" << Endl; + } + + NVRenderShaderProgram *GenerateCustomMaterialShader(const char8_t *inShaderPrefix, + const char8_t *inCustomMaterialName) + { + // build a string that allows us to print out the shader we are generating to the log. + // This is time consuming but I feel like it doesn't happen all that often and is very + // useful to users + // looking at the log file. + m_GeneratedShaderString.clear(); + m_GeneratedShaderString.assign(nonNull(inShaderPrefix)); + m_GeneratedShaderString.append(inCustomMaterialName); + SShaderDefaultMaterialKey theKey(Key()); + theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); + + bool hasCustomVertexShader = GenerateVertexShader(theKey, inCustomMaterialName); + GenerateFragmentShader(theKey, inCustomMaterialName, hasCustomVertexShader); + + VertexGenerator().EndVertexGeneration(); + VertexGenerator().EndFragmentGeneration(); + + NVRenderShaderProgram *program = ProgramGenerator().CompileGeneratedShader( + m_GeneratedShaderString.c_str(), SShaderCacheProgramFlags(), FeatureSet()); + if (program && hasCustomVertexShader) { + // Change uniforms names to match runtime 2.x uniforms + SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(*program)); + shader.m_ModelMatrix = NVRenderCachedShaderProperty("modelMatrix", + *program); + shader.m_ViewProjMatrix = NVRenderCachedShaderProperty( + "modelViewProjection", *program); + shader.m_ViewMatrix = NVRenderCachedShaderProperty("viewMatrix", *program); + shader.m_NormalMatrix = NVRenderCachedShaderProperty("modelNormalMatrix", + *program); + shader.m_ProjMatrix = NVRenderCachedShaderProperty("viewProjectionMatrix", + *program); + shader.m_ViewportMatrix = NVRenderCachedShaderProperty("viewportMatrix", + *program); + shader.m_CameraPos = NVRenderCachedShaderProperty("eyePosition", *program); + } + return program; + } + + virtual NVRenderShaderProgram * + GenerateShader(const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, + IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, + NVDataRef inLights, SRenderableImage *inFirstImage, + bool inHasTransparency, const char8_t *inShaderPrefix, + const char8_t *inCustomMaterialName) override + { + QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::CustomMaterial); + m_CurrentMaterial = reinterpret_cast(&inMaterial); + m_CurrentKey = &inShaderDescription; + m_CurrentPipeline = static_cast(&inVertexPipeline); + m_CurrentFeatureSet = inFeatureSet; + m_Lights = inLights; + m_FirstImage = inFirstImage; + m_HasTransparency = inHasTransparency; + + return GenerateCustomMaterialShader(inShaderPrefix, inCustomMaterialName); + } +}; +} + +ICustomMaterialShaderGenerator & +ICustomMaterialShaderGenerator::CreateCustomMaterialShaderGenerator(IQt3DSRenderContext &inRc) +{ + return *QT3DS_NEW(inRc.GetAllocator(), SShaderGenerator)(inRc); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.h b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.h new file mode 100644 index 00000000..44e2c064 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialShaderGenerator.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_SHADER_GENERATOR_H +#define QT3DS_RENDER_CUSTOM_MATERIAL_SHADER_GENERATOR_H +#include "Qt3DSRenderMaterialShaderGenerator.h" + +namespace qt3ds { +namespace render { + + class Qt3DSShadowMap; + + class ICustomMaterialShaderGenerator : public IMaterialShaderGenerator + { + public: + SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override = 0; + void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, + QT3DSU32 uvSet, SRenderableImage &image) override = 0; + + // inPipelineName needs to be unique else the shader cache will just return shaders from + // different pipelines. + NVRenderShaderProgram *GenerateShader( + const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, + IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, + NVDataRef inLights, SRenderableImage *inFirstImage, bool inHasTransparency, + const char8_t *inVertexPipelineName, const char8_t *inCustomMaterialName = "") override = 0; + + // Also sets the blend function on the render context. + virtual void + SetMaterialProperties(NVRenderShaderProgram &inProgram, const SGraphObject &inMaterial, + const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + SLayerGlobalRenderProperties inRenderProperties) override = 0; + + static ICustomMaterialShaderGenerator & + CreateCustomMaterialShaderGenerator(IQt3DSRenderContext &inRenderContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp new file mode 100644 index 00000000..3841dd07 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp @@ -0,0 +1,2074 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderCustomMaterialRenderContext.h" +#include "Qt3DSRenderContextCore.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderDynamicObjectSystemCommands.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderResourceManager.h" +#include "Qt3DSRenderMesh.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderLayer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "render/Qt3DSRenderComputeShader.h" +#include "foundation/PreAllocatedAllocator.h" +#include "foundation/SerializationTypes.h" +#include "foundation/Qt3DSTime.h" +#include "Qt3DSRenderDynamicObjectSystemUtil.h" +#include "Qt3DSRenderableImage.h" +#include "rendererimpl/Qt3DSVertexPipelineImpl.h" +#include "rendererimpl/Qt3DSRendererImplLayerRenderData.h" +#include "Qt3DSRenderCustomMaterialShaderGenerator.h" +#include "Qt3DSRenderModel.h" + +using namespace qt3ds::render; +using namespace qt3ds::render::dynamic; +using qt3ds::render::NVRenderContextScopedProperty; +using qt3ds::render::NVRenderCachedShaderProperty; +using qt3ds::render::NVRenderCachedShaderBuffer; + +SCustomMaterialVertexPipeline::SCustomMaterialVertexPipeline(IQt3DSRenderContext *inContext, + TessModeValues::Enum inTessMode) + : SVertexPipelineImpl( + inContext->GetAllocator(), inContext->GetCustomMaterialShaderGenerator(), + inContext->GetShaderProgramGenerator(), inContext->GetStringTable(), false) + , m_Context(inContext) + , m_TessMode(TessModeValues::NoTess) +{ + if (m_Context->GetRenderContext().IsTessellationSupported()) { + m_TessMode = inTessMode; + } + + if (m_Context->GetRenderContext().IsGeometryStageSupported() + && m_TessMode != TessModeValues::NoTess) { + m_Wireframe = inContext->GetWireframeMode(); + } +} + +void SCustomMaterialVertexPipeline::InitializeTessControlShader() +{ + if (m_TessMode == TessModeValues::NoTess + || ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl) == NULL) { + return; + } + + IShaderStageGenerator &tessCtrlShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + + SetupTessIncludes(ShaderGeneratorStages::TessControl, m_TessMode); + + tessCtrlShader.Append("void main() {\n"); + + tessCtrlShader.Append("\tctWorldPos[0] = varWorldPos[0];"); + tessCtrlShader.Append("\tctWorldPos[1] = varWorldPos[1];"); + tessCtrlShader.Append("\tctWorldPos[2] = varWorldPos[2];"); + + if (m_TessMode == TessModeValues::TessPhong || m_TessMode == TessModeValues::TessNPatch) { + tessCtrlShader.Append("\tctNorm[0] = varObjectNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = varObjectNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = varObjectNormal[2];"); + } + if (m_TessMode == TessModeValues::TessNPatch) { + tessCtrlShader.Append("\tctTangent[0] = varObjTangent[0];"); + tessCtrlShader.Append("\tctTangent[1] = varObjTangent[1];"); + tessCtrlShader.Append("\tctTangent[2] = varObjTangent[2];"); + } + + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); +} + +void SCustomMaterialVertexPipeline::InitializeTessEvaluationShader() +{ + if (m_TessMode == TessModeValues::NoTess + || ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval) == NULL) { + return; + } + + IShaderStageGenerator &tessEvalShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddUniform("normal_matrix", "mat3"); + + SetupTessIncludes(ShaderGeneratorStages::TessEval, m_TessMode); + + if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) { + tessEvalShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + tessEvalShader.AddUniform("model_matrix", "mat4"); + tessEvalShader.AddUniform("displace_tiling", "vec3"); + tessEvalShader.AddUniform("displaceAmount", "float"); + tessEvalShader.AddUniform(m_DisplacementImage->m_Image.m_ImageShaderName.c_str(), + "sampler2D"); + } + + tessEvalShader.Append("void main() {"); + + if (m_TessMode == TessModeValues::TessNPatch) { + tessEvalShader.Append("\tctNorm[0] = varObjectNormalTC[0];"); + tessEvalShader.Append("\tctNorm[1] = varObjectNormalTC[1];"); + tessEvalShader.Append("\tctNorm[2] = varObjectNormalTC[2];"); + + tessEvalShader.Append("\tctTangent[0] = varTangentTC[0];"); + tessEvalShader.Append("\tctTangent[1] = varTangentTC[1];"); + tessEvalShader.Append("\tctTangent[2] = varTangentTC[2];"); + } + + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); +} + +void SCustomMaterialVertexPipeline::FinalizeTessControlShader() +{ + IShaderStageGenerator &tessCtrlShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + // add varyings we must pass through + typedef TStrTableStrMap::const_iterator TParamIter; + for (TParamIter iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + tessCtrlShader << "\t" << iter->first.c_str() + << "TC[gl_InvocationID] = " << iter->first.c_str() + << "[gl_InvocationID];\n"; + } +} + +void SCustomMaterialVertexPipeline::FinalizeTessEvaluationShader() +{ + IShaderStageGenerator &tessEvalShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + eastl::string outExt(""); + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) + outExt = "TE"; + + // add varyings we must pass through + typedef TStrTableStrMap::const_iterator TParamIter; + if (m_TessMode == TessModeValues::TessNPatch) { + for (TParamIter iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() + << " = gl_TessCoord.z * " << iter->first.c_str() << "TC[0] + "; + tessEvalShader << "gl_TessCoord.x * " << iter->first.c_str() << "TC[1] + "; + tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[2];\n"; + } + + // transform the normal + if (m_GenerationFlags & GenerationFlagValues::WorldNormal) + tessEvalShader << "\n\tvarNormal" << outExt.c_str() + << " = normalize(normal_matrix * teNorm);\n"; + // transform the tangent + if (m_GenerationFlags & GenerationFlagValues::TangentBinormal) { + tessEvalShader << "\n\tvarTangent" << outExt.c_str() + << " = normalize(normal_matrix * teTangent);\n"; + // transform the binormal + tessEvalShader << "\n\tvarBinormal" << outExt.c_str() + << " = normalize(normal_matrix * teBinormal);\n"; + } + } else { + for (TParamIter iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() + << " = gl_TessCoord.x * " << iter->first.c_str() << "TC[0] + "; + tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[1] + "; + tessEvalShader << "gl_TessCoord.z * " << iter->first.c_str() << "TC[2];\n"; + } + + // displacement mapping makes only sense with linear tessellation + if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) { + tessEvalShader + << "\ttexture_coordinate_info tmp = textureCoordinateInfo( varTexCoord0" + << outExt.c_str() << ", varTangent" << outExt.c_str() << ", varBinormal" + << outExt.c_str() << " );" << Endl; + tessEvalShader << "\ttmp = transformCoordinate( rotationTranslationScale( vec3( " + "0.000000, 0.000000, 0.000000 ), vec3( 0.000000, 0.000000, " + "0.000000 ), displace_tiling ), tmp);" + << Endl; + + tessEvalShader << "\tpos.xyz = defaultMaterialFileDisplacementTexture( " + << m_DisplacementImage->m_Image.m_ImageShaderName.c_str() + << ", displaceAmount, " + << "tmp.position.xy"; + tessEvalShader << ", varObjectNormal" << outExt.c_str() << ", pos.xyz );" << Endl; + tessEvalShader << "\tvarWorldPos" << outExt.c_str() << "= (model_matrix * pos).xyz;" + << Endl; + } + + // transform the normal + tessEvalShader << "\n\tvarNormal" << outExt.c_str() + << " = normalize(normal_matrix * varObjectNormal" << outExt.c_str() + << ");\n"; + } + + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); +} + +// Responsible for beginning all vertex and fragment generation (void main() { etc). +void SCustomMaterialVertexPipeline::BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) +{ + m_DisplacementIdx = displacementImageIdx; + m_DisplacementImage = displacementImage; + + TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); + + if (m_TessMode != TessModeValues::NoTess) { + theStages |= ShaderGeneratorStages::TessControl; + theStages |= ShaderGeneratorStages::TessEval; + } + if (m_Wireframe) { + theStages |= ShaderGeneratorStages::Geometry; + } + + ProgramGenerator().BeginProgram(theStages); + + if (m_TessMode != TessModeValues::NoTess) { + InitializeTessControlShader(); + InitializeTessEvaluationShader(); + } + if (m_Wireframe) { + InitializeWireframeGeometryShader(); + } + + IShaderStageGenerator &vertexShader(Vertex()); + + // thinks we need + vertexShader.AddInclude("viewProperties.glsllib"); + vertexShader.AddInclude("customMaterial.glsllib"); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader << "void main()" << Endl << "{" << Endl; + + if (displacementImage) { + GenerateUVCoords(0); + if (!HasTessellation()) { + vertexShader.AddUniform("displaceAmount", "float"); + vertexShader.AddUniform("displace_tiling", "vec3"); + // we create the world position setup here + // because it will be replaced with the displaced position + SetCode(GenerationFlagValues::WorldPosition); + vertexShader.AddUniform("model_matrix", "mat4"); + + vertexShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + vertexShader.AddUniform(displacementImage->m_Image.m_ImageShaderName.c_str(), + "sampler2D"); + + vertexShader << "\ttexture_coordinate_info tmp = textureCoordinateInfo( texCoord0, " + "varTangent, varBinormal );" + << Endl; + vertexShader << "\ttmp = transformCoordinate( rotationTranslationScale( vec3( " + "0.000000, 0.000000, 0.000000 ), vec3( 0.000000, 0.000000, " + "0.000000 ), displace_tiling ), tmp);" + << Endl; + + vertexShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " + << displacementImage->m_Image.m_ImageShaderName.c_str() + << ", displaceAmount, " + << "tmp.position.xy" + << ", attr_norm, attr_pos );" << Endl; + + AddInterpolationParameter("varWorldPos", "vec3"); + vertexShader.Append("\tvec3 local_model_world_position = (model_matrix * " + "vec4(displacedPos, 1.0)).xyz;"); + AssignOutput("varWorldPos", "local_model_world_position"); + } + } + + if (HasTessellation()) { + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + } else { + vertexShader.AddUniform("model_view_projection", "mat4"); + if (displacementImage) + vertexShader.Append( + "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); + else + vertexShader.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + } + + if (HasTessellation()) { + GenerateWorldPosition(); + GenerateWorldNormal(); + GenerateObjectNormal(); + GenerateVarTangentAndBinormal(); + } +} + +void SCustomMaterialVertexPipeline::BeginFragmentGeneration() +{ + Fragment().AddUniform("object_opacity", "float"); + Fragment() << "void main()" << Endl << "{" << Endl; +} + +void SCustomMaterialVertexPipeline::AssignOutput(const char8_t *inVarName, + const char8_t *inVarValue) +{ + Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n"; +} + +void SCustomMaterialVertexPipeline::GenerateUVCoords(QT3DSU32 inUVSet) +{ + if (inUVSet == 0 && SetCode(GenerationFlagValues::UVCoords)) + return; + if (inUVSet == 1 && SetCode(GenerationFlagValues::UVCoords1)) + return; + + QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); + + if (inUVSet == 0) + AddInterpolationParameter("varTexCoord0", "vec3"); + else if (inUVSet == 1) + AddInterpolationParameter("varTexCoord1", "vec3"); + + DoGenerateUVCoords(inUVSet); +} + +void SCustomMaterialVertexPipeline::GenerateWorldNormal() +{ + if (SetCode(GenerationFlagValues::WorldNormal)) + return; + AddInterpolationParameter("varNormal", "vec3"); + DoGenerateWorldNormal(); +} + +void SCustomMaterialVertexPipeline::GenerateObjectNormal() +{ + if (SetCode(GenerationFlagValues::ObjectNormal)) + return; + DoGenerateObjectNormal(); +} + +void SCustomMaterialVertexPipeline::GenerateVarTangentAndBinormal() +{ + if (SetCode(GenerationFlagValues::TangentBinormal)) + return; + AddInterpolationParameter("varTangent", "vec3"); + AddInterpolationParameter("varBinormal", "vec3"); + AddInterpolationParameter("varObjTangent", "vec3"); + AddInterpolationParameter("varObjBinormal", "vec3"); + DoGenerateVarTangentAndBinormal(); +} + +void SCustomMaterialVertexPipeline::GenerateWorldPosition() +{ + if (SetCode(GenerationFlagValues::WorldPosition)) + return; + + ActiveStage().AddUniform("model_matrix", "mat4"); + AddInterpolationParameter("varWorldPos", "vec3"); + AddInterpolationParameter("varObjPos", "vec3"); + DoGenerateWorldPosition(); +} + +// responsible for closing all vertex and fragment generation +void SCustomMaterialVertexPipeline::EndVertexGeneration() +{ + if (HasTessellation()) { + // finalize tess control shader + FinalizeTessControlShader(); + // finalize tess evaluation shader + FinalizeTessEvaluationShader(); + + TessControl().Append("}"); + TessEval().Append("}"); + + if (m_Wireframe) { + // finalize geometry shader + FinalizeWireframeGeometryShader(); + Geometry().Append("}"); + } + } + + Vertex().Append("}"); +} + +void SCustomMaterialVertexPipeline::EndFragmentGeneration() +{ + Fragment().Append("}"); +} + +IShaderStageGenerator &SCustomMaterialVertexPipeline::ActiveStage() +{ + return Vertex(); +} + +void SCustomMaterialVertexPipeline::AddInterpolationParameter(const char8_t *inName, + const char8_t *inType) +{ + m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); + Vertex().AddOutgoing(inName, inType); + Fragment().AddIncoming(inName, inType); + + if (HasTessellation()) { + eastl::string nameBuilder(inName); + nameBuilder.append("TC"); + TessControl().AddOutgoing(nameBuilder.c_str(), inType); + + nameBuilder.assign(inName); + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) { + nameBuilder.append("TE"); + Geometry().AddOutgoing(inName, inType); + } + TessEval().AddOutgoing(nameBuilder.c_str(), inType); + } +} + +void SCustomMaterialVertexPipeline::DoGenerateUVCoords(QT3DSU32 inUVSet) +{ + QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); + + if (inUVSet == 0) { + Vertex().AddIncoming("attr_uv0", "vec2"); + Vertex() << "\tvec3 texCoord0 = vec3( attr_uv0, 0.0 );" << Endl; + AssignOutput("varTexCoord0", "texCoord0"); + } else if (inUVSet == 1) { + Vertex().AddIncoming("attr_uv1", "vec2"); + Vertex() << "\tvec3 texCoord1 = vec3( attr_uv1, 1.0 );" << Endl; + AssignOutput("varTexCoord1", "texCoord1"); + } +} + +void SCustomMaterialVertexPipeline::DoGenerateWorldNormal() +{ + IShaderStageGenerator &vertexGenerator(Vertex()); + vertexGenerator.AddIncoming("attr_norm", "vec3"); + vertexGenerator.AddUniform("normal_matrix", "mat3"); + + if (HasTessellation() == false) { + Vertex().Append("\tvarNormal = normalize( normal_matrix * attr_norm );"); + } +} + +void SCustomMaterialVertexPipeline::DoGenerateObjectNormal() +{ + AddInterpolationParameter("varObjectNormal", "vec3"); + Vertex().Append("\tvarObjectNormal = attr_norm;"); +} + +void SCustomMaterialVertexPipeline::DoGenerateWorldPosition() +{ + Vertex().Append("\tvarObjPos = attr_pos;"); + Vertex().Append("\tvec4 worldPos = (model_matrix * vec4(attr_pos, 1.0));"); + AssignOutput("varWorldPos", "worldPos.xyz"); +} + +void SCustomMaterialVertexPipeline::DoGenerateVarTangentAndBinormal() +{ + Vertex().AddIncoming("attr_textan", "vec3"); + Vertex().AddIncoming("attr_binormal", "vec3"); + + Vertex() << "\tvarTangent = normal_matrix * attr_textan;" << Endl + << "\tvarBinormal = normal_matrix * attr_binormal;" << Endl; + + Vertex() << "\tvarObjTangent = attr_textan;" << Endl << "\tvarObjBinormal = attr_binormal;" + << Endl; +} + +void SCustomMaterialVertexPipeline::DoGenerateVertexColor() +{ + Vertex().AddIncoming("attr_color", "vec3"); + Vertex().Append("\tvarColor = attr_color;"); +} + + +struct SMaterialClass +{ + NVAllocatorCallback *m_Allocator; + IDynamicObjectClass *m_Class; + bool m_HasTransparency; + bool m_HasRefraction; + bool m_HasDisplacement; + bool m_AlwaysDirty; + QT3DSU32 m_ShaderKey; + QT3DSU32 m_LayerCount; + QT3DSI32 mRefCount; + SMaterialClass(NVAllocatorCallback &alloc, IDynamicObjectClass &inCls) + : m_Allocator(&alloc) + , m_Class(&inCls) + , m_HasTransparency(false) + , m_HasRefraction(false) + , m_HasDisplacement(false) + , m_AlwaysDirty(false) + , m_ShaderKey(0) + , m_LayerCount(0) + , mRefCount(0) + { + } + + ~SMaterialClass() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator) + + void AfterWrite() + { + m_Allocator = NULL; + m_Class = NULL; + mRefCount = 0; + } + + void AfterRead(NVAllocatorCallback &alloc, IDynamicObjectClass &inCls) + { + m_Allocator = &alloc; + m_Class = &inCls; + mRefCount = 0; + } +}; + +typedef nvhash_map> TStringMaterialMap; +typedef eastl::pair TStrStrPair; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const TStrStrPair &item) const + { + return hash()(item.first) ^ hash()(item.second); + } +}; +} + +struct SShaderMapKey +{ + TStrStrPair m_Name; + eastl::vector m_Features; + TessModeValues::Enum m_TessMode; + bool m_WireframeMode; + SShaderDefaultMaterialKey m_MaterialKey; + size_t m_HashCode; + SShaderMapKey(TStrStrPair inName, TShaderFeatureSet inFeatures, TessModeValues::Enum inTessMode, + bool inWireframeMode, SShaderDefaultMaterialKey inMaterialKey) + : m_Name(inName) + , m_Features(inFeatures.begin(), inFeatures.end()) + , m_TessMode(inTessMode) + , m_WireframeMode(inWireframeMode) + , m_MaterialKey(inMaterialKey) + { + m_HashCode = eastl::hash()(m_Name) + ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size())) + ^ eastl::hash()(m_TessMode) ^ eastl::hash()(m_WireframeMode) + ^ eastl::hash()(inMaterialKey.hash()); + } + bool operator==(const SShaderMapKey &inKey) const + { + return m_Name == inKey.m_Name && m_Features == inKey.m_Features + && m_TessMode == inKey.m_TessMode && m_WireframeMode == inKey.m_WireframeMode + && m_MaterialKey == inKey.m_MaterialKey; + } +}; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SShaderMapKey &inKey) const { return inKey.m_HashCode; } +}; +} + +namespace { + +struct SCustomMaterialTextureData +{ + NVScopedRefCounted m_Shader; + qt3ds::render::NVRenderCachedShaderProperty m_Sampler; + qt3ds::render::NVRenderTexture2D *m_Texture; + bool m_needsMips; + volatile QT3DSI32 mRefCount; + + SCustomMaterialTextureData(NVRenderShaderProgram &inShader, NVRenderTexture2D *inTexture, + const char *inTexName, bool needMips) + : m_Shader(inShader) + , m_Sampler(inTexName, inShader) + , m_Texture(inTexture) + , m_needsMips(needMips) + , mRefCount(0) + { + } + + void Set(const SPropertyDefinition *inDefinition) + { + if (m_Texture && inDefinition) { + m_Texture->SetMagFilter(inDefinition->m_MagFilterOp); + m_Texture->SetMinFilter(inDefinition->m_MinFilterOp); + m_Texture->SetTextureWrapS(inDefinition->m_CoordOp); + m_Texture->SetTextureWrapT(inDefinition->m_CoordOp); + } else if (m_Texture) { + // set some defaults + m_Texture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + m_Texture->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + m_Texture->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + } + + if ((m_Texture->GetNumMipmaps() == 0) && m_needsMips) + m_Texture->GenerateMipmaps(); + + m_Sampler.Set(m_Texture); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) + + static SCustomMaterialTextureData CreateTextureEntry(NVRenderShaderProgram &inShader, + NVRenderTexture2D *inTexture, + const char *inTexName, bool needMips) + { + return SCustomMaterialTextureData(inShader, inTexture, inTexName, needMips); + } +}; + +typedef eastl::pair> + TCustomMaterialTextureEntry; + +/** + * Cached tessellation property lookups this is on a per mesh base + */ +struct SCustomMaterialsTessellationProperties +{ + NVRenderCachedShaderProperty m_EdgeTessLevel; ///< tesselation value for the edges + NVRenderCachedShaderProperty m_InsideTessLevel; ///< tesselation value for the inside + NVRenderCachedShaderProperty + m_PhongBlend; ///< blending between linear and phong component + NVRenderCachedShaderProperty + m_DistanceRange; ///< distance range for min and max tess level + NVRenderCachedShaderProperty m_DisableCulling; ///< if set to 1.0 this disables backface + ///culling optimization in the tess shader + + SCustomMaterialsTessellationProperties() {} + SCustomMaterialsTessellationProperties(NVRenderShaderProgram &inShader) + : m_EdgeTessLevel("tessLevelOuter", inShader) + , m_InsideTessLevel("tessLevelInner", inShader) + , m_PhongBlend("phongBlend", inShader) + , m_DistanceRange("distanceRange", inShader) + , m_DisableCulling("disableCulling", inShader) + { + } +}; + +/* We setup some shared state on the custom material shaders */ +struct SCustomMaterialShader +{ + NVScopedRefCounted m_Shader; + NVRenderCachedShaderProperty m_ModelMatrix; + NVRenderCachedShaderProperty m_ViewProjMatrix; + NVRenderCachedShaderProperty m_ViewMatrix; + NVRenderCachedShaderProperty m_NormalMatrix; + NVRenderCachedShaderProperty m_CameraPos; + NVRenderCachedShaderProperty m_ProjMatrix; + NVRenderCachedShaderProperty m_ViewportMatrix; + NVRenderCachedShaderProperty m_CamProperties; + NVRenderCachedShaderProperty m_DepthTexture; + NVRenderCachedShaderProperty m_AOTexture; + NVRenderCachedShaderProperty m_LightProbe; + NVRenderCachedShaderProperty m_LightProbeProps; + NVRenderCachedShaderProperty m_LightProbeOpts; + NVRenderCachedShaderProperty m_LightProbeRot; + NVRenderCachedShaderProperty m_LightProbeOfs; + NVRenderCachedShaderProperty m_LightProbe2; + NVRenderCachedShaderProperty m_LightProbe2Props; + NVRenderCachedShaderProperty m_LightCount; + NVRenderCachedShaderProperty m_AreaLightCount; + NVRenderCachedShaderBuffer m_AoShadowParams; + SCustomMaterialsTessellationProperties m_Tessellation; + SDynamicShaderProgramFlags m_ProgramFlags; + volatile QT3DSI32 mRefCount; + SCustomMaterialShader(NVRenderShaderProgram &inShader, SDynamicShaderProgramFlags inFlags) + : m_Shader(inShader) + , m_ModelMatrix("model_matrix", inShader) + , m_ViewProjMatrix("model_view_projection", inShader) + , m_ViewMatrix("view_matrix", inShader) + , m_NormalMatrix("normal_matrix", inShader) + , m_CameraPos("camera_position", inShader) + , m_ProjMatrix("view_projection_matrix", inShader) + , m_ViewportMatrix("viewport_matrix", inShader) + , m_CamProperties("camera_properties", inShader) + , m_DepthTexture("depth_sampler", inShader) + , m_AOTexture("ao_sampler", inShader) + , m_LightProbe("light_probe", inShader) + , m_LightProbeProps("light_probe_props", inShader) + , m_LightProbeOpts("light_probe_opts", inShader) + , m_LightProbeRot("light_probe_rotation", inShader) + , m_LightProbeOfs("light_probe_offset", inShader) + , m_LightProbe2("light_probe2", inShader) + , m_LightProbe2Props("light_probe2_props", inShader) + , m_LightCount("uNumLights", inShader) + , m_AreaLightCount("uNumAreaLights", inShader) + , m_AoShadowParams("cbAoShadow", inShader) + , m_Tessellation(inShader) + , m_ProgramFlags(inFlags) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) +}; + +struct SMaterialOrComputeShader +{ + SCustomMaterialShader *m_MaterialShader; + NVRenderShaderProgram *m_ComputeShader; + SMaterialOrComputeShader() + : m_MaterialShader(NULL) + , m_ComputeShader(NULL) + { + } + SMaterialOrComputeShader(SCustomMaterialShader &inMaterialShader) + : m_MaterialShader(&inMaterialShader) + , m_ComputeShader(NULL) + { + } + SMaterialOrComputeShader(NVRenderShaderProgram &inComputeShader) + : m_MaterialShader(NULL) + , m_ComputeShader(&inComputeShader) + { + QT3DS_ASSERT(inComputeShader.GetProgramType() == NVRenderShaderProgram::ProgramType::Compute); + } + bool IsValid() const { return m_MaterialShader || m_ComputeShader; } + bool IsComputeShader() const { return m_ComputeShader != NULL; } + bool IsMaterialShader() const { return m_MaterialShader != NULL; } + SCustomMaterialShader &MaterialShader() + { + QT3DS_ASSERT(IsMaterialShader()); + return *m_MaterialShader; + } + NVRenderShaderProgram &ComputeShader() + { + QT3DS_ASSERT(IsComputeShader()); + return *m_ComputeShader; + } +}; + +struct SCustomMaterialBuffer +{ + CRegisteredString m_Name; + NVScopedRefCounted m_FrameBuffer; + NVScopedRefCounted m_Texture; + SAllocateBufferFlags m_Flags; + + SCustomMaterialBuffer(CRegisteredString inName, NVRenderFrameBuffer &inFb, + NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags) + : m_Name(inName) + , m_FrameBuffer(&inFb) + , m_Texture(&inTexture) + , m_Flags(inFlags) + { + } + SCustomMaterialBuffer() {} +}; + +struct SMaterialSystem; +typedef nvhash_map> + TStringVertexBufferMap; +typedef nvhash_map> + TStringAssemblerMap; + +struct SStringMemoryBarrierFlagMap +{ + const char8_t *m_Name; + qt3ds::render::NVRenderBufferBarrierValues::Enum m_Value; + SStringMemoryBarrierFlagMap(const char8_t *nm, + qt3ds::render::NVRenderBufferBarrierValues::Enum val) + : m_Name(nm) + , m_Value(val) + { + } +}; + +SStringMemoryBarrierFlagMap g_StringMemoryFlagMap[] = { + SStringMemoryBarrierFlagMap("vertex_attribute", + qt3ds::render::NVRenderBufferBarrierValues::VertexAttribArray), + SStringMemoryBarrierFlagMap("element_array", + qt3ds::render::NVRenderBufferBarrierValues::ElementArray), + SStringMemoryBarrierFlagMap("uniform_buffer", + qt3ds::render::NVRenderBufferBarrierValues::UniformBuffer), + SStringMemoryBarrierFlagMap("texture_fetch", + qt3ds::render::NVRenderBufferBarrierValues::TextureFetch), + SStringMemoryBarrierFlagMap("shader_image_access", + qt3ds::render::NVRenderBufferBarrierValues::ShaderImageAccess), + SStringMemoryBarrierFlagMap("command_buffer", + qt3ds::render::NVRenderBufferBarrierValues::CommandBuffer), + SStringMemoryBarrierFlagMap("pixel_buffer", + qt3ds::render::NVRenderBufferBarrierValues::PixelBuffer), + SStringMemoryBarrierFlagMap("texture_update", + qt3ds::render::NVRenderBufferBarrierValues::TextureUpdate), + SStringMemoryBarrierFlagMap("buffer_update", + qt3ds::render::NVRenderBufferBarrierValues::BufferUpdate), + SStringMemoryBarrierFlagMap("frame_buffer", + qt3ds::render::NVRenderBufferBarrierValues::Framebuffer), + SStringMemoryBarrierFlagMap("transform_feedback", + qt3ds::render::NVRenderBufferBarrierValues::TransformFeedback), + SStringMemoryBarrierFlagMap("atomic_counter", + qt3ds::render::NVRenderBufferBarrierValues::AtomicCounter), + SStringMemoryBarrierFlagMap("shader_storage", + qt3ds::render::NVRenderBufferBarrierValues::ShaderStorage), +}; + +struct SStringBlendFuncMap +{ + const char8_t *m_Name; + qt3ds::render::NVRenderSrcBlendFunc::Enum m_Value; + SStringBlendFuncMap(const char8_t *nm, qt3ds::render::NVRenderSrcBlendFunc::Enum val) + : m_Name(nm) + , m_Value(val) + { + } +}; + +SStringBlendFuncMap g_BlendFuncMap[] = { +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(nm) \ + SStringBlendFuncMap(#nm, qt3ds::render::NVRenderSrcBlendFunc::nm), +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(nm) \ + SStringBlendFuncMap(#nm, qt3ds::render::NVRenderSrcBlendFunc::nm), + QT3DS_RENDER_ITERATE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC +}; + +struct SMaterialSystem : public ICustomMaterialSystem +{ + typedef nvhash_map> TShaderMap; + typedef eastl::pair TAllocatedImageEntry; + + IQt3DSRenderContextCore &m_CoreContext; + IQt3DSRenderContext *m_Context; + mutable qt3ds::render::SPreAllocatedAllocator m_Allocator; + TStringMaterialMap m_StringMaterialMap; + TShaderMap m_ShaderMap; + nvvector m_TextureEntries; + nvvector m_AllocatedBuffers; + nvvector m_AllocatedImages; + bool m_UseFastBlits; + eastl::string m_ShaderNameBuilder; + QT3DSU64 m_LastFrameTime; + QT3DSF32 m_MillisecondsSinceLastFrame; + QT3DSI32 mRefCount; + + SMaterialSystem(IQt3DSRenderContextCore &ct) + : m_CoreContext(ct) + , m_Context(NULL) + , m_Allocator(ct.GetAllocator()) + , m_StringMaterialMap(ct.GetAllocator(), "SMaterialSystem::m_StringMaterialMap") + , m_ShaderMap(ct.GetAllocator(), "SMaterialSystem::m_ShaderMap") + , m_TextureEntries(ct.GetAllocator(), "SMaterialSystem::m_TextureEntries") + , m_AllocatedBuffers(ct.GetAllocator(), "SMaterialSystem::m_AllocatedBuffers") + , m_AllocatedImages(ct.GetAllocator(), "SMaterialSystem::m_AllocatedImages") + , m_UseFastBlits(true) + , m_LastFrameTime(0) + , m_MillisecondsSinceLastFrame(0) + , mRefCount(0) + { + } + + ~SMaterialSystem() + { + while (m_AllocatedBuffers.size()) + m_AllocatedBuffers.replace_with_last(0); + + for (QT3DSU32 idx = 0; idx < m_AllocatedImages.size(); ++idx) { + SImage *pImage = m_AllocatedImages[idx].second; + QT3DS_FREE(m_CoreContext.GetAllocator(), pImage); + } + m_AllocatedImages.clear(); + } + + void ReleaseBuffer(QT3DSU32 inIdx) + { + // Don't call this on MaterialSystem destroy. + // This causes issues for scene liftime buffers + // because the resource manager is destroyed before + IResourceManager &theManager(m_Context->GetResourceManager()); + SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[inIdx]); + theEntry.m_FrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer()); + + theManager.Release(*theEntry.m_FrameBuffer); + theManager.Release(*theEntry.m_Texture); + m_AllocatedBuffers.replace_with_last(inIdx); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_CoreContext.GetAllocator()) + + bool IsMaterialRegistered(CRegisteredString inStr) override + { + return m_StringMaterialMap.find(inStr) != m_StringMaterialMap.end(); + } + + bool RegisterMaterialClass(CRegisteredString inName, + NVConstDataRef inProperties) override + { + if (IsMaterialRegistered(inName)) + return false; + m_CoreContext.GetDynamicObjectSystemCore().Register( + inName, inProperties, sizeof(SCustomMaterial), GraphObjectTypes::CustomMaterial); + IDynamicObjectClass *theClass = + m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + return false; + } + SMaterialClass *theNewClass = QT3DS_NEW(m_Allocator, SMaterialClass)(m_Allocator, *theClass); + m_StringMaterialMap.insert(eastl::make_pair(inName, theNewClass)); + return true; + } + + SMaterialClass *GetMaterialClass(CRegisteredString inStr) + { + TStringMaterialMap::iterator theIter = m_StringMaterialMap.find(inStr); + if (theIter != m_StringMaterialMap.end()) + return theIter->second; + return NULL; + } + + const SMaterialClass *GetMaterialClass(CRegisteredString inStr) const + { + return const_cast(this)->GetMaterialClass(inStr); + } + + virtual NVConstDataRef + GetCustomMaterialProperties(CRegisteredString inCustomMaterialName) const override + { + IDynamicObjectClass *theMaterialClass = + m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inCustomMaterialName); + + if (theMaterialClass) + return theMaterialClass->GetProperties(); + + return NVConstDataRef(); + } + + virtual QT3DSU32 FindBuffer(CRegisteredString inName) + { + for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx) + if (m_AllocatedBuffers[idx].m_Name == inName) + return idx; + return m_AllocatedBuffers.size(); + } + + virtual QT3DSU32 FindAllocatedImage(CRegisteredString inName) + { + for (QT3DSU32 idx = 0, end = m_AllocatedImages.size(); idx < end; ++idx) + if (m_AllocatedImages[idx].first == inName) + return idx; + return QT3DSU32(-1); + } + + virtual bool TextureNeedsMips(const SPropertyDefinition *inPropDec, + qt3ds::render::NVRenderTexture2D *inTexture) + { + if (inPropDec && inTexture) { + return bool((inPropDec->m_MinFilterOp == NVRenderTextureMinifyingOp::LinearMipmapLinear) + && (inTexture->GetNumMipmaps() == 0)); + } + + return false; + } + + virtual void SetTexture(NVRenderShaderProgram &inShader, CRegisteredString inPropName, + NVRenderTexture2D *inTexture, + const SPropertyDefinition *inPropDec = NULL, bool needMips = false) + { + SCustomMaterialTextureData *theTextureEntry(NULL); + for (QT3DSU32 idx = 0, end = m_TextureEntries.size(); idx < end && theTextureEntry == NULL; + ++idx) { + if (m_TextureEntries[idx].first == inPropName + && m_TextureEntries[idx].second->m_Shader.mPtr == &inShader + && m_TextureEntries[idx].second->m_Texture == inTexture) { + theTextureEntry = m_TextureEntries[idx].second; + break; + } + } + if (theTextureEntry == NULL) { + NVScopedRefCounted theNewEntry = + QT3DS_NEW(m_CoreContext.GetAllocator(), SCustomMaterialTextureData)( + SCustomMaterialTextureData::CreateTextureEntry(inShader, inTexture, inPropName, + needMips)); + m_TextureEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); + theTextureEntry = theNewEntry.mPtr; + } + theTextureEntry->Set(inPropDec); + } + + void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inNames) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetPropertyEnumNames(inName, inPropName, + inNames); + } + + void SetPropertyTextureSettings(CRegisteredString inName, CRegisteredString inPropName, + CRegisteredString inPropPath, + NVRenderTextureTypeValue::Enum inTexType, + NVRenderTextureCoordOp::Enum inCoordOp, + NVRenderTextureMagnifyingOp::Enum inMagFilterOp, + NVRenderTextureMinifyingOp::Enum inMinFilterOp) override + { + SMaterialClass *theClass = GetMaterialClass(inName); + if (theClass && inTexType == NVRenderTextureTypeValue::Displace) { + theClass->m_HasDisplacement = true; + } + m_CoreContext.GetDynamicObjectSystemCore().SetPropertyTextureSettings( + inName, inPropName, inPropPath, inTexType, inCoordOp, inMagFilterOp, inMinFilterOp); + } + + void SetMaterialClassShader(CRegisteredString inName, const char8_t *inShaderType, + const char8_t *inShaderVersion, const char8_t *inShaderData, + bool inHasGeomShader, bool inIsComputeShader) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetShaderData(inName, inShaderData, inShaderType, + inShaderVersion, inHasGeomShader, + inIsComputeShader); + } + + SCustomMaterial *CreateCustomMaterial(CRegisteredString inName, + NVAllocatorCallback &inSceneGraphAllocator) override + { + SCustomMaterial *theMaterial = static_cast( + m_CoreContext.GetDynamicObjectSystemCore().CreateInstance(inName, + inSceneGraphAllocator)); + SMaterialClass *theClass = GetMaterialClass(inName); + + if (theMaterial) { + QT3DSU32 key = 0, count = 0; + if (theClass) { + key = theClass->m_ShaderKey; + count = theClass->m_LayerCount; + } + theMaterial->Initialize(key, count); + } + + return theMaterial; + } + + void SetCustomMaterialTransparency(CRegisteredString inName, bool inHasTransparency) override + { + SMaterialClass *theClass = GetMaterialClass(inName); + + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + + theClass->m_HasTransparency = inHasTransparency; + } + + void SetCustomMaterialRefraction(CRegisteredString inName, bool inHasRefraction) override + { + SMaterialClass *theClass = GetMaterialClass(inName); + + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + + theClass->m_HasRefraction = inHasRefraction; + } + + void SetCustomMaterialAlwaysDirty(CRegisteredString inName, bool inIsAlwaysDirty) override + { + SMaterialClass *theClass = GetMaterialClass(inName); + + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + + theClass->m_AlwaysDirty = inIsAlwaysDirty; + } + + void SetCustomMaterialShaderKey(CRegisteredString inName, QT3DSU32 inShaderKey) override + { + SMaterialClass *theClass = GetMaterialClass(inName); + + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + + theClass->m_ShaderKey = inShaderKey; + } + + void SetCustomMaterialLayerCount(CRegisteredString inName, QT3DSU32 inLayerCount) override + { + SMaterialClass *theClass = GetMaterialClass(inName); + + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + + theClass->m_LayerCount = inLayerCount; + } + + void SetCustomMaterialCommands(CRegisteredString inName, + NVConstDataRef inCommands) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands(inName, inCommands); + } + + CRegisteredString GetShaderCacheKey(CRenderString &inShaderKeyBuffer, const char8_t *inId, + const char8_t *inProgramMacro, + const dynamic::SDynamicShaderProgramFlags &inFlags) + { + inShaderKeyBuffer.assign(inId); + if (inProgramMacro && *inProgramMacro) { + inShaderKeyBuffer.append("#"); + inShaderKeyBuffer.append(inProgramMacro); + } + if (inFlags.IsTessellationEnabled()) { + inShaderKeyBuffer.append("#"); + inShaderKeyBuffer.append(TessModeValues::toString(inFlags.m_TessMode)); + } + if (inFlags.IsGeometryShaderEnabled() && inFlags.m_WireframeMode) { + inShaderKeyBuffer.append("#"); + inShaderKeyBuffer.append(inFlags.wireframeToString(inFlags.m_WireframeMode)); + } + + return m_CoreContext.GetStringTable().RegisterStr(inShaderKeyBuffer.c_str()); + } + + NVRenderShaderProgram *GetShader(SCustomMaterialRenderContext &inRenderContext, + const SCustomMaterial &inMaterial, + const SBindShader &inCommand, TShaderFeatureSet inFeatureSet, + const dynamic::SDynamicShaderProgramFlags &inFlags) + { + ICustomMaterialShaderGenerator &theMaterialGenerator( + m_Context->GetCustomMaterialShaderGenerator()); + + // generate key + CRenderString theShaderKeyBuffer; + CRegisteredString theKey = GetShaderCacheKey(theShaderKeyBuffer, inCommand.m_ShaderPath, + inCommand.m_ShaderDefine, inFlags); + + SCustomMaterialVertexPipeline thePipeline(m_Context, + inRenderContext.m_Model.m_TessellationMode); + + NVRenderShaderProgram *theProgram = theMaterialGenerator.GenerateShader( + inMaterial, inRenderContext.m_MaterialKey, thePipeline, inFeatureSet, + inRenderContext.m_Lights, inRenderContext.m_FirstImage, + (inMaterial.m_hasTransparency || inMaterial.m_hasRefraction), + "custom material pipeline-- ", inCommand.m_ShaderPath.c_str()); + + return theProgram; + } + + SMaterialOrComputeShader BindShader(SCustomMaterialRenderContext &inRenderContext, + const SCustomMaterial &inMaterial, + const SBindShader &inCommand, + TShaderFeatureSet inFeatureSet) + { + NVRenderShaderProgram *theProgram = NULL; + + SDynamicShaderProgramFlags theFlags(inRenderContext.m_Model.m_TessellationMode, + inRenderContext.m_Subset.m_WireframeMode); + theFlags.SetTessellationEnabled(inRenderContext.m_Model.m_TessellationMode + != TessModeValues::NoTess); + theFlags.SetGeometryShaderEnabled(inRenderContext.m_Subset.m_WireframeMode); + + SShaderMapKey skey = SShaderMapKey( + TStrStrPair(inCommand.m_ShaderPath, inCommand.m_ShaderDefine), inFeatureSet, + theFlags.m_TessMode, theFlags.m_WireframeMode, inRenderContext.m_MaterialKey); + eastl::pair theInsertResult(m_ShaderMap.insert( + eastl::make_pair(skey, NVScopedRefCounted(NULL)))); + + if (theInsertResult.second) { + theProgram = GetShader(inRenderContext, inMaterial, inCommand, inFeatureSet, theFlags); + + if (theProgram) { + theInsertResult.first->second = + QT3DS_NEW(m_Allocator, SCustomMaterialShader)(*theProgram, theFlags); + } + } else if (theInsertResult.first->second) + theProgram = theInsertResult.first->second->m_Shader; + + if (theProgram) { + if (theProgram->GetProgramType() == NVRenderShaderProgram::ProgramType::Graphics) { + if (theInsertResult.first->second) { + NVRenderContext &theContext(m_Context->GetRenderContext()); + theContext.SetActiveShader(theInsertResult.first->second->m_Shader); + } + + return *theInsertResult.first->second; + } else { + NVRenderContext &theContext(m_Context->GetRenderContext()); + theContext.SetActiveShader(theProgram); + return *(static_cast(theProgram)); + } + } + return SMaterialOrComputeShader(); + } + + void DoApplyInstanceValue(SCustomMaterial & /* inMaterial */, QT3DSU8 *inDataPtr, + CRegisteredString inPropertyName, + NVRenderShaderDataTypes::Enum inPropertyType, + NVRenderShaderProgram &inShader, + const SPropertyDefinition &inDefinition) + { + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(inPropertyName); + using namespace qt3ds::render; + if (theConstant) { + if (theConstant->GetShaderConstantType() == inPropertyType) { + if (inPropertyType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + StaticAssert::valid_expression(); + CRegisteredString *theStrPtr = reinterpret_cast(inDataPtr); + IBufferManager &theBufferManager(m_Context->GetBufferManager()); + NVRenderTexture2D *theTexture = NULL; + + if (theStrPtr->IsValid()) { + SImageTextureData theTextureData = + theBufferManager.LoadRenderImage(*theStrPtr); + if (theTextureData.m_Texture) { + theTexture = theTextureData.m_Texture; + SetTexture(inShader, inPropertyName, theTexture, &inDefinition, + TextureNeedsMips(&inDefinition, theTexture)); + } + } + } else { + switch (inPropertyType) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ + case NVRenderShaderDataTypes::type: \ + inShader.SetPropertyValue(theConstant, *(reinterpret_cast(inDataPtr))); \ + break; + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + QT3DS_ASSERT(false); + break; + } + } + } else { + qCCritical(INVALID_OPERATION, + "CustomMaterial ApplyInstanceValue command datatype and " + "shader datatypes differ for property %s", + inPropertyName.c_str()); + QT3DS_ASSERT(false); + } + } + } + + void ApplyInstanceValue(SCustomMaterial &inMaterial, SMaterialClass &inClass, + NVRenderShaderProgram &inShader, const SApplyInstanceValue &inCommand) + { + // sanity check + if (inCommand.m_PropertyName.IsValid()) { + bool canGetData = + inCommand.m_ValueOffset + getSizeofShaderDataType(inCommand.m_ValueType) + <= inMaterial.m_DataSectionByteSize; + if (canGetData == false) { + QT3DS_ASSERT(false); + return; + } + QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + inCommand.m_ValueOffset; + const SPropertyDefinition *theDefinition = + inClass.m_Class->FindPropertyByName(inCommand.m_PropertyName); + if (theDefinition) + DoApplyInstanceValue(inMaterial, dataPtr, inCommand.m_PropertyName, + inCommand.m_ValueType, inShader, *theDefinition); + } else { + NVConstDataRef theDefs = inClass.m_Class->GetProperties(); + for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) { + const SPropertyDefinition &theDefinition(theDefs[idx]); + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(theDefinition.m_Name); + + // This is fine, the property wasn't found and we continue, no problem. + if (!theConstant) + continue; + QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + theDefinition.m_Offset; + DoApplyInstanceValue(inMaterial, dataPtr, theDefinition.m_Name, + theDefinition.m_DataType, inShader, theDefinition); + } + } + } + + void ApplyBlending(const SApplyBlending &inCommand) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + + theContext.SetBlendingEnabled(true); + + qt3ds::render::NVRenderBlendFunctionArgument blendFunc = + qt3ds::render::NVRenderBlendFunctionArgument( + inCommand.m_SrcBlendFunc, inCommand.m_DstBlendFunc, inCommand.m_SrcBlendFunc, + inCommand.m_DstBlendFunc); + + qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, + NVRenderBlendEquation::Add); + + theContext.SetBlendFunction(blendFunc); + theContext.SetBlendEquation(blendEqu); + } + + // we currently only bind a source texture + const NVRenderTexture2D *ApplyBufferValue(const SCustomMaterial &inMaterial, + NVRenderShaderProgram &inShader, + const SApplyBufferValue &inCommand, + const NVRenderTexture2D *inSourceTexture) + { + const NVRenderTexture2D *theTexture = NULL; + + if (inCommand.m_BufferName.IsValid()) { + QT3DSU32 bufferIdx = FindBuffer(inCommand.m_BufferName); + if (bufferIdx < m_AllocatedBuffers.size()) { + SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); + theTexture = theEntry.m_Texture; + } else { + // we must have allocated the read target before + qCCritical(INTERNAL_ERROR, + "CustomMaterial: ApplyBufferValue: Failed to setup read target"); + QT3DS_ASSERT(false); + } + } else + theTexture = inSourceTexture; + + if (inCommand.m_ParamName.IsValid()) { + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(inCommand.m_ParamName); + + if (theConstant) { + if (theConstant->GetShaderConstantType() + != NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + qCCritical(INVALID_OPERATION, + "CustomMaterial %s: Binding buffer to parameter %s that is not a texture", + inMaterial.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); + QT3DS_ASSERT(false); + } else { + SetTexture(inShader, inCommand.m_ParamName, + const_cast(theTexture)); + } + } + } + + return theTexture; + } + + void AllocateBuffer(const SAllocateBuffer &inCommand, NVRenderFrameBuffer *inTarget) + { + STextureDetails theSourceTextureDetails; + NVRenderTexture2D *theTexture = NULL; + // get color attachment we always assume at location 0 + if (inTarget) { + NVRenderTextureOrRenderBuffer theSourceTexture = + inTarget->GetAttachment(NVRenderFrameBufferAttachments::Color0); + // we need a texture + if (theSourceTexture.HasTexture2D()) { + theSourceTextureDetails = theSourceTexture.GetTexture2D()->GetTextureDetails(); + } else { + qCCritical(INVALID_OPERATION, "CustomMaterial %s: Invalid source texture", + inCommand.m_Name.c_str()); + QT3DS_ASSERT(false); + return; + } + } else { + NVRenderContext &theContext = m_Context->GetRenderContext(); + // if we allocate a buffer based on the default target use viewport to get the dimension + NVRenderRect theViewport(theContext.GetViewport()); + theSourceTextureDetails.m_Height = theViewport.m_Height; + theSourceTextureDetails.m_Width = theViewport.m_Width; + } + + QT3DSU32 theWidth = (QT3DSU32)(theSourceTextureDetails.m_Width * inCommand.m_SizeMultiplier); + QT3DSU32 theHeight = (QT3DSU32)(theSourceTextureDetails.m_Height * inCommand.m_SizeMultiplier); + NVRenderTextureFormats::Enum theFormat = inCommand.m_Format; + if (theFormat == NVRenderTextureFormats::Unknown) + theFormat = theSourceTextureDetails.m_Format; + IResourceManager &theResourceManager(m_Context->GetResourceManager()); + // size intentionally requiried every loop; + QT3DSU32 bufferIdx = FindBuffer(inCommand.m_Name); + if (bufferIdx < m_AllocatedBuffers.size()) { + SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); + STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails(); + if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight + && theDetails.m_Format == theFormat) { + theTexture = theEntry.m_Texture; + } else { + ReleaseBuffer(bufferIdx); + } + } + + if (theTexture == NULL) { + NVRenderFrameBuffer *theFB(theResourceManager.AllocateFrameBuffer()); + NVRenderTexture2D *theTexture( + theResourceManager.AllocateTexture2D(theWidth, theHeight, theFormat)); + theTexture->SetMagFilter(inCommand.m_FilterOp); + theTexture->SetMinFilter( + static_cast(inCommand.m_FilterOp)); + theTexture->SetTextureWrapS(inCommand.m_TexCoordOp); + theTexture->SetTextureWrapT(inCommand.m_TexCoordOp); + theFB->Attach(NVRenderFrameBufferAttachments::Color0, *theTexture); + m_AllocatedBuffers.push_back(SCustomMaterialBuffer( + inCommand.m_Name, *theFB, *theTexture, inCommand.m_BufferFlags)); + } + } + + NVRenderFrameBuffer *BindBuffer(const SCustomMaterial &inMaterial, const SBindBuffer &inCommand, + bool &outClearTarget, QT3DSVec2 &outDestSize) + { + NVRenderFrameBuffer *theBuffer = NULL; + NVRenderTexture2D *theTexture = NULL; + + // search for the buffer + QT3DSU32 bufferIdx = FindBuffer(inCommand.m_BufferName); + if (bufferIdx < m_AllocatedBuffers.size()) { + theBuffer = m_AllocatedBuffers[bufferIdx].m_FrameBuffer; + theTexture = m_AllocatedBuffers[bufferIdx].m_Texture; + } + + if (theBuffer == NULL) { + qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", + inMaterial.m_ClassName.c_str(), inCommand.m_BufferName.c_str()); + QT3DS_ASSERT(false); + return NULL; + } + + if (theTexture) { + STextureDetails theDetails(theTexture->GetTextureDetails()); + m_Context->GetRenderContext().SetViewport( + NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); + outDestSize = QT3DSVec2((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); + outClearTarget = inCommand.m_NeedsClear; + } + + return theBuffer; + } + + void computeScreenCoverage(SCustomMaterialRenderContext &inRenderContext, QT3DSI32 *xMin, + QT3DSI32 *yMin, QT3DSI32 *xMax, QT3DSI32 *yMax) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + TNVBounds2BoxPoints outPoints; + QT3DSVec4 projMin(QT3DS_MAX_REAL); + QT3DSVec4 projMax(-QT3DS_MAX_REAL); + + // get points + inRenderContext.m_Subset.m_Bounds.expand(outPoints); + for (QT3DSU32 idx = 0; idx < 8; ++idx) { + QT3DSVec4 homPoint(outPoints[idx], 1.0); + QT3DSVec4 projPoint = inRenderContext.m_ModelViewProjection.transform(homPoint); + projPoint /= projPoint.w; + + if (projMin.x > projPoint.x) + projMin.x = projPoint.x; + if (projMin.y > projPoint.y) + projMin.y = projPoint.y; + if (projMin.z > projPoint.z) + projMin.z = projPoint.z; + + if (projMax.x < projPoint.x) + projMax.x = projPoint.x; + if (projMax.y < projPoint.y) + projMax.y = projPoint.y; + if (projMax.z < projPoint.z) + projMax.z = projPoint.z; + } + + NVRenderRect theViewport(theContext.GetViewport()); + QT3DSI32 x1 = QT3DSI32(projMax.x * (theViewport.m_Width / 2) + + (theViewport.m_X + (theViewport.m_Width / 2))); + QT3DSI32 y1 = QT3DSI32(projMax.y * (theViewport.m_Height / 2) + + (theViewport.m_Y + (theViewport.m_Height / 2))); + + QT3DSI32 x2 = QT3DSI32(projMin.x * (theViewport.m_Width / 2) + + (theViewport.m_X + (theViewport.m_Width / 2))); + QT3DSI32 y2 = QT3DSI32(projMin.y * (theViewport.m_Height / 2) + + (theViewport.m_Y + (theViewport.m_Height / 2))); + + if (x1 > x2) { + *xMin = x2; + *xMax = x1; + } else { + *xMin = x1; + *xMax = x2; + } + if (y1 > y2) { + *yMin = y2; + *yMax = y1; + } else { + *yMin = y1; + *yMax = y2; + } + } + + void BlitFramebuffer(SCustomMaterialRenderContext &inRenderContext, + const SApplyBlitFramebuffer &inCommand, NVRenderFrameBuffer *inTarget) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + // we change the read/render targets here + NVRenderContextScopedProperty __framebuffer( + theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + // we may alter scissor + NVRenderContextScopedProperty theScissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled); + + if (inCommand.m_DestBufferName.IsValid()) { + QT3DSU32 bufferIdx = FindBuffer(inCommand.m_DestBufferName); + if (bufferIdx < m_AllocatedBuffers.size()) { + SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); + theContext.SetRenderTarget(theEntry.m_FrameBuffer); + } else { + // we must have allocated the read target before + qCCritical(INTERNAL_ERROR, + "CustomMaterial: BlitFramebuffer: Failed to setup render target"); + QT3DS_ASSERT(false); + } + } else { + // our dest is the default render target + theContext.SetRenderTarget(inTarget); + } + + if (inCommand.m_SourceBufferName.IsValid()) { + QT3DSU32 bufferIdx = FindBuffer(inCommand.m_SourceBufferName); + if (bufferIdx < m_AllocatedBuffers.size()) { + SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]); + theContext.SetReadTarget(theEntry.m_FrameBuffer); + theContext.SetReadBuffer(NVReadFaces::Color0); + } else { + // we must have allocated the read target before + qCCritical(INTERNAL_ERROR, + "CustomMaterial: BlitFramebuffer: Failed to setup read target"); + QT3DS_ASSERT(false); + } + } else { + // our source is the default read target + // depending on what we render we assume color0 or back + theContext.SetReadTarget(inTarget); + NVReadFaces::Enum value = (inTarget) ? NVReadFaces::Color0 : NVReadFaces::Back; + theContext.SetReadBuffer(value); + } + + NVRenderRect theViewport(theContext.GetViewport()); + theContext.SetScissorTestEnabled(false); + + if (!m_UseFastBlits) { + // only copy sreen amount of pixels + QT3DSI32 xMin, yMin, xMax, yMax; + computeScreenCoverage(inRenderContext, &xMin, &yMin, &xMax, &yMax); + + // same dimension + theContext.BlitFramebuffer(xMin, yMin, xMax, yMax, xMin, yMin, xMax, yMax, + NVRenderClearValues::Color, + NVRenderTextureMagnifyingOp::Nearest); + } else { + // same dimension + theContext.BlitFramebuffer( + theViewport.m_X, theViewport.m_Y, theViewport.m_X + theViewport.m_Width, + theViewport.m_Y + theViewport.m_Height, theViewport.m_X, theViewport.m_Y, + theViewport.m_X + theViewport.m_Width, theViewport.m_Y + theViewport.m_Height, + NVRenderClearValues::Color, NVRenderTextureMagnifyingOp::Nearest); + } + } + + SLayerGlobalRenderProperties + GetLayerGlobalRenderProperties(SCustomMaterialRenderContext &inRenderContext) + { + const SLayer &theLayer = inRenderContext.m_Layer; + const SLayerRenderData &theData = inRenderContext.m_LayerData; + + return SLayerGlobalRenderProperties( + theLayer, const_cast(inRenderContext.m_Camera), theData.m_CameraDirection, + inRenderContext.m_Lights, NVDataRef(), theData.m_ShadowMapManager.mPtr, + const_cast(inRenderContext.m_DepthTexture), + const_cast(inRenderContext.m_AOTexture), theLayer.m_LightProbe, + theLayer.m_LightProbe2, theLayer.m_ProbeHorizon, theLayer.m_ProbeBright, + theLayer.m_Probe2Window, theLayer.m_Probe2Pos, theLayer.m_Probe2Fade, + theLayer.m_ProbeFov); + } + + void RenderPass(SCustomMaterialRenderContext &inRenderContext, SCustomMaterialShader &inShader, + NVRenderTexture2D * /* inSourceTexture */ + , + NVRenderFrameBuffer *inFrameBuffer, bool inRenderTargetNeedsClear, + NVRenderInputAssembler &inAssembler, QT3DSU32 inCount, QT3DSU32 inOffset) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + theContext.SetRenderTarget(inFrameBuffer); + + QT3DSVec4 clearColor(0.0); + NVRenderContextScopedProperty __clearColor( + theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, + clearColor); + if (inRenderTargetNeedsClear) { + theContext.Clear(qt3ds::render::NVRenderClearValues::Color); + } + + ICustomMaterialShaderGenerator &theMaterialGenerator( + m_Context->GetCustomMaterialShaderGenerator()); + + theMaterialGenerator.SetMaterialProperties( + *inShader.m_Shader, inRenderContext.m_Material, QT3DSVec2(1.0, 1.0), + inRenderContext.m_ModelViewProjection, inRenderContext.m_NormalMatrix, + inRenderContext.m_ModelMatrix, inRenderContext.m_FirstImage, inRenderContext.m_Opacity, + GetLayerGlobalRenderProperties(inRenderContext)); + + // I think the prim type should always be fetched from the + // current mesh subset setup because there you get the actual draw mode + // for this frame + NVRenderDrawMode::Enum theDrawMode = inAssembler.GetPrimitiveType(); + + // tesselation + if (inRenderContext.m_Subset.m_PrimitiveType == NVRenderDrawMode::Patches) { + QT3DSVec2 camProps(inRenderContext.m_Camera.m_ClipNear, + inRenderContext.m_Camera.m_ClipFar); + theDrawMode = inRenderContext.m_Subset.m_PrimitiveType; + inShader.m_Tessellation.m_EdgeTessLevel.Set(inRenderContext.m_Subset.m_EdgeTessFactor); + inShader.m_Tessellation.m_InsideTessLevel.Set( + inRenderContext.m_Subset.m_InnerTessFactor); + // the blend value is hardcoded + inShader.m_Tessellation.m_PhongBlend.Set(0.75); + // this should finally be based on some user input + inShader.m_Tessellation.m_DistanceRange.Set(camProps); + // enable culling + inShader.m_Tessellation.m_DisableCulling.Set(0.0); + } + + if (inRenderContext.m_Subset.m_WireframeMode) { + NVRenderRect theViewport(theContext.GetViewport()); + QT3DSMat44 vpMatrix; + vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0); + vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0); + vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0); + vpMatrix.column3 = + QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X, + (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0); + + inShader.m_ViewportMatrix.Set(vpMatrix); + } + + theContext.SetInputAssembler(&inAssembler); + + theContext.SetCullingEnabled(true); + QT3DSU32 count = inCount; + QT3DSU32 offset = inOffset; + + theContext.Draw(theDrawMode, count, offset); + } + + void DoRenderCustomMaterial(SCustomMaterialRenderContext &inRenderContext, + const SCustomMaterial &inMaterial, SMaterialClass &inClass, + NVRenderFrameBuffer *inTarget, TShaderFeatureSet inFeatureSet) + { + NVRenderContext &theContext = m_Context->GetRenderContext(); + SCustomMaterialShader *theCurrentShader(NULL); + + NVRenderFrameBuffer *theCurrentRenderTarget(inTarget); + NVRenderRect theOriginalViewport(theContext.GetViewport()); + NVRenderTexture2D *theCurrentSourceTexture = 0; + + // for refrative materials we come from the transparent render path + // but we do not want to do blending + bool wasBlendingEnabled = theContext.IsBlendingEnabled(); + if (inMaterial.m_hasRefraction) + theContext.SetBlendingEnabled(false); + + NVRenderContextScopedProperty __framebuffer( + theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + NVRenderContextScopedProperty __viewport( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); + + QT3DSVec2 theDestSize; + bool theRenderTargetNeedsClear = false; + + NVConstDataRef theCommands(inClass.m_Class->GetRenderCommands()); + for (QT3DSU32 commandIdx = 0, commandEnd = theCommands.size(); commandIdx < commandEnd; + ++commandIdx) { + const SCommand &theCommand(*theCommands[commandIdx]); + + switch (theCommand.m_Type) { + case CommandTypes::AllocateBuffer: + AllocateBuffer(static_cast(theCommand), inTarget); + break; + case CommandTypes::BindBuffer: + theCurrentRenderTarget = + BindBuffer(inMaterial, static_cast(theCommand), + theRenderTargetNeedsClear, theDestSize); + break; + case CommandTypes::BindTarget: + // Restore the previous render target and info. + theCurrentRenderTarget = inTarget; + theContext.SetViewport(theOriginalViewport); + break; + case CommandTypes::BindShader: { + theCurrentShader = NULL; + SMaterialOrComputeShader theBindResult = + BindShader(inRenderContext, inMaterial, + static_cast(theCommand), inFeatureSet); + if (theBindResult.IsMaterialShader()) + theCurrentShader = &theBindResult.MaterialShader(); + } break; + case CommandTypes::ApplyInstanceValue: + // we apply the property update explicitly at the render pass + break; + case CommandTypes::Render: + if (theCurrentShader) { + RenderPass(inRenderContext, *theCurrentShader, theCurrentSourceTexture, + theCurrentRenderTarget, theRenderTargetNeedsClear, + *inRenderContext.m_Subset.m_InputAssembler, + inRenderContext.m_Subset.m_Count, inRenderContext.m_Subset.m_Offset); + } + // reset + theRenderTargetNeedsClear = false; + break; + case CommandTypes::ApplyBlending: + ApplyBlending(static_cast(theCommand)); + break; + case CommandTypes::ApplyBufferValue: + if (theCurrentShader) + ApplyBufferValue(inMaterial, *theCurrentShader->m_Shader, + static_cast(theCommand), + theCurrentSourceTexture); + break; + case CommandTypes::ApplyBlitFramebuffer: + BlitFramebuffer(inRenderContext, + static_cast(theCommand), inTarget); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + if (inMaterial.m_hasRefraction) + theContext.SetBlendingEnabled(wasBlendingEnabled); + + // Release any per-frame buffers + for (QT3DSU32 idx = 0; idx < m_AllocatedBuffers.size(); ++idx) { + if (m_AllocatedBuffers[idx].m_Flags.IsSceneLifetime() == false) { + ReleaseBuffer(idx); + --idx; + } + } + } + + const char *GetShaderName(const SCustomMaterial &inMaterial) override + { + SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); + if (!theClass) + return NULL; + + NVConstDataRef theCommands = theClass->m_Class->GetRenderCommands(); + TShaderAndFlags thePrepassShader; + for (QT3DSU32 idx = 0, end = theCommands.size(); + idx < end && thePrepassShader.first.mPtr == NULL; ++idx) { + const SCommand &theCommand = *theCommands[idx]; + if (theCommand.m_Type == CommandTypes::BindShader) { + const SBindShader &theBindCommand = static_cast(theCommand); + return theBindCommand.m_ShaderPath.c_str(); + } + } + + QT3DS_ASSERT(false); + return NULL; + } + + void ApplyShaderPropertyValues(const SCustomMaterial &inMaterial, + NVRenderShaderProgram &inProgram) override + { + SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); + if (!theClass) + return; + + SApplyInstanceValue applier; + ApplyInstanceValue(const_cast(inMaterial), *theClass, inProgram, + applier); + } + + virtual void PrepareTextureForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) + { + NVConstDataRef thePropDefs = inClass.m_Class->GetProperties(); + for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) { + if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + if (thePropDefs[idx].m_TexUsageType == NVRenderTextureTypeValue::Displace) { + SImage *pImage = NULL; + + // we only do this to not miss if "None" is selected + CRegisteredString theStrPtr = *reinterpret_cast( + inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset); + + if (theStrPtr.IsValid()) { + + QT3DSU32 index = FindAllocatedImage(thePropDefs[idx].m_ImagePath); + if (index == QT3DSU32(-1)) { + pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)(); + m_AllocatedImages.push_back( + eastl::make_pair(thePropDefs[idx].m_ImagePath, pImage)); + } else + pImage = m_AllocatedImages[index].second; + + if (inMaterial.m_DisplacementMap != pImage) { + inMaterial.m_DisplacementMap = pImage; + inMaterial.m_DisplacementMap->m_ImagePath = + thePropDefs[idx].m_ImagePath; + inMaterial.m_DisplacementMap->m_ImageShaderName = + thePropDefs[idx].m_Name; // this is our name in the shader + inMaterial.m_DisplacementMap->m_VerticalTilingMode = + thePropDefs[idx].m_CoordOp; + inMaterial.m_DisplacementMap->m_HorizontalTilingMode = + thePropDefs[idx].m_CoordOp; + } + } else { + inMaterial.m_DisplacementMap = NULL; + } + } else if (thePropDefs[idx].m_TexUsageType == NVRenderTextureTypeValue::Emissive2) { + SImage *pImage = NULL; + + // we only do this to not miss if "None" is selected + CRegisteredString theStrPtr = *reinterpret_cast( + inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset); + + if (theStrPtr.IsValid()) { + QT3DSU32 index = FindAllocatedImage(thePropDefs[idx].m_ImagePath); + if (index == QT3DSU32(-1)) { + pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)(); + m_AllocatedImages.push_back( + eastl::make_pair(thePropDefs[idx].m_ImagePath, pImage)); + } else + pImage = m_AllocatedImages[index].second; + + if (inMaterial.m_EmissiveMap2 != pImage) { + inMaterial.m_EmissiveMap2 = pImage; + inMaterial.m_EmissiveMap2->m_ImagePath = thePropDefs[idx].m_ImagePath; + inMaterial.m_EmissiveMap2->m_ImageShaderName = + thePropDefs[idx].m_Name; // this is our name in the shader + inMaterial.m_EmissiveMap2->m_VerticalTilingMode = + thePropDefs[idx].m_CoordOp; + inMaterial.m_EmissiveMap2->m_HorizontalTilingMode = + thePropDefs[idx].m_CoordOp; + } + } else { + inMaterial.m_EmissiveMap2 = NULL; + } + } + } + } + } + + virtual void PrepareDisplacementForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) + { + if (inMaterial.m_DisplacementMap == NULL) + return; + + // our displacement mappin in MDL has fixed naming + NVConstDataRef thePropDefs = inClass.m_Class->GetProperties(); + for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) { + if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSF32 + && AreEqual(thePropDefs[idx].m_Name.c_str(), "displaceAmount")) { + QT3DSF32 theValue = *reinterpret_cast(inMaterial.GetDataSectionBegin() + + thePropDefs[idx].m_Offset); + inMaterial.m_DisplaceAmount = theValue; + } else if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSVec3 + && AreEqual(thePropDefs[idx].m_Name.c_str(), "displace_tiling")) { + QT3DSVec3 theValue = *reinterpret_cast(inMaterial.GetDataSectionBegin() + + thePropDefs[idx].m_Offset); + if (theValue.x != inMaterial.m_DisplacementMap->m_Scale.x + || theValue.y != inMaterial.m_DisplacementMap->m_Scale.y) { + inMaterial.m_DisplacementMap->m_Scale = QT3DSVec2(theValue.x, theValue.y); + inMaterial.m_DisplacementMap->m_Flags.SetTransformDirty(true); + } + } + } + } + + void PrepareMaterialForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) + { + PrepareTextureForRender(inClass, inMaterial); + + if (inClass.m_HasDisplacement) + PrepareDisplacementForRender(inClass, inMaterial); + } + + // Returns true if the material is dirty and thus will produce a different render result + // than previously. This effects things like progressive AA. + // TODO - return more information, specifically about transparency (object is transparent, + // object is completely transparent + bool PrepareForRender(const SModel & /*inModel*/, const SRenderSubset & /*inSubset*/, + SCustomMaterial &inMaterial, bool clearMaterialDirtyFlags) override + { + SMaterialClass *theMaterialClass = GetMaterialClass(inMaterial.m_ClassName); + if (theMaterialClass == NULL) { + QT3DS_ASSERT(false); + return false; + } + + PrepareMaterialForRender(*theMaterialClass, inMaterial); + + inMaterial.m_hasTransparency = theMaterialClass->m_HasTransparency; + inMaterial.m_hasRefraction = theMaterialClass->m_HasRefraction; + inMaterial.m_hasVolumetricDF = false; + + bool wasDirty = inMaterial.IsDirty() || theMaterialClass->m_AlwaysDirty; + if (clearMaterialDirtyFlags) + inMaterial.UpdateDirtyForFrame(); + + return wasDirty; + } + + // TODO - handle UIC specific features such as vertex offsets for prog-aa and opacity. + void RenderSubset(SCustomMaterialRenderContext &inRenderContext, + TShaderFeatureSet inFeatureSet) override + { + SMaterialClass *theClass = GetMaterialClass(inRenderContext.m_Material.m_ClassName); + + // Ensure that our overall render context comes back no matter what the client does. + qt3ds::render::NVRenderContextScopedProperty + __blendFunction(m_Context->GetRenderContext(), &NVRenderContext::GetBlendFunction, + &NVRenderContext::SetBlendFunction, + qt3ds::render::NVRenderBlendFunctionArgument()); + qt3ds::render::NVRenderContextScopedProperty + __blendEquation(m_Context->GetRenderContext(), &NVRenderContext::GetBlendEquation, + &NVRenderContext::SetBlendEquation, + qt3ds::render::NVRenderBlendEquationArgument()); + + NVRenderContextScopedProperty theBlendEnabled(m_Context->GetRenderContext(), + &NVRenderContext::IsBlendingEnabled, + &NVRenderContext::SetBlendingEnabled); + + DoRenderCustomMaterial(inRenderContext, inRenderContext.m_Material, *theClass, + m_Context->GetRenderContext().GetRenderTarget(), inFeatureSet); + } + + bool RenderDepthPrepass(const QT3DSMat44 &inMVP, const SCustomMaterial &inMaterial, + const SRenderSubset &inSubset) override + { + SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); + NVConstDataRef theCommands = theClass->m_Class->GetRenderCommands(); + TShaderAndFlags thePrepassShader; + for (QT3DSU32 idx = 0, end = theCommands.size(); + idx < end && thePrepassShader.first.mPtr == NULL; ++idx) { + const SCommand &theCommand = *theCommands[idx]; + if (theCommand.m_Type == CommandTypes::BindShader) { + const SBindShader &theBindCommand = static_cast(theCommand); + thePrepassShader = m_Context->GetDynamicObjectSystem().GetDepthPrepassShader( + theBindCommand.m_ShaderPath, CRegisteredString(), TShaderFeatureSet()); + } + } + + if (thePrepassShader.first.mPtr == NULL) + return false; + + NVRenderContext &theContext = m_Context->GetRenderContext(); + NVRenderShaderProgram &theProgram = *thePrepassShader.first; + theContext.SetActiveShader(&theProgram); + theProgram.SetPropertyValue("model_view_projection", inMVP); + theContext.SetInputAssembler(inSubset.m_InputAssemblerPoints); + theContext.Draw(NVRenderDrawMode::Lines, inSubset.m_PosVertexBuffer->GetNumVertexes(), 0); + return true; + } + + void OnMaterialActivationChange(const SCustomMaterial &inMaterial, bool inActive) override + { + Q_UNUSED(inMaterial) + Q_UNUSED(inActive) + } + + void EndFrame() override + { + QT3DSU64 currentFrameTime = qt3ds::foundation::Time::getCurrentTimeInTensOfNanoSeconds(); + if (m_LastFrameTime) { + QT3DSU64 timePassed = currentFrameTime - m_LastFrameTime; + m_MillisecondsSinceLastFrame = static_cast(timePassed / 100000.0); + } + m_LastFrameTime = currentFrameTime; + } + + void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, + const char8_t * /*inProjectDir*/) const override + { + QT3DSU32 offset = ioBuffer.size(); + ioBuffer.write((QT3DSU32)m_StringMaterialMap.size()); + for (TStringMaterialMap::const_iterator iter = m_StringMaterialMap.begin(), + end = m_StringMaterialMap.end(); + iter != end; ++iter) { + size_t nameOffset = ioBuffer.size() - offset; + (void)nameOffset; + CRegisteredString materialName(iter->first); + materialName.Remap(inRemapMap); + ioBuffer.write(materialName); + const SMaterialClass *materialClass = iter->second.mPtr; + QT3DSU32 offset = ioBuffer.size(); + ioBuffer.write(*materialClass); + QT3DSU8 *materialOffset = ioBuffer.begin() + offset; + SMaterialClass *writtenClass = (SMaterialClass *)materialOffset; + writtenClass->AfterWrite(); + ioBuffer.align(4); + } + } + + void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t * /*inProjectDir*/) override + { + m_Allocator.m_PreAllocatedBlock = inData; + m_Allocator.m_OwnsMemory = false; + qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); + QT3DSU32 numMaterialClasses = theReader.LoadRef(); + for (QT3DSU32 idx = 0; idx < numMaterialClasses; ++idx) { + CRegisteredString clsName = theReader.LoadRef(); + clsName.Remap(inStrDataBlock); + IDynamicObjectClass *theDynamicCls = + m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(clsName); + SMaterialClass *theReadClass = theReader.Load(); + theReader.Align(4); + if (theDynamicCls) { + theReadClass->AfterRead(m_Allocator, *theDynamicCls); + m_StringMaterialMap.insert(eastl::make_pair(clsName, theReadClass)); + } + } + } + + ICustomMaterialSystem &GetCustomMaterialSystem(IQt3DSRenderContext &inContext) override + { + m_Context = &inContext; + + // check for fast blits + NVRenderContext &theContext = m_Context->GetRenderContext(); + m_UseFastBlits = theContext.GetRenderBackendCap( + qt3ds::render::NVRenderBackend::NVRenderBackendCaps::FastBlits); + + return *this; + } +}; +} + +ICustomMaterialSystemCore & +ICustomMaterialSystemCore::CreateCustomMaterialSystemCore(IQt3DSRenderContextCore &ctx) +{ + return *QT3DS_NEW(ctx.GetAllocator(), SMaterialSystem)(ctx); +} + diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.h b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.h new file mode 100644 index 00000000..cb2a5f7d --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderCustomMaterialSystem.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_SYSTEM_H +#define QT3DS_RENDER_CUSTOM_MATERIAL_SYSTEM_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "rendererimpl/Qt3DSVertexPipelineImpl.h" + +namespace qt3ds { +namespace render { + + namespace dynamic { + struct SCommand; // UICRenderEffectCommands.h + } + + struct SCustomMaterialRenderContext; + + class ICustomMaterialSystemCore : public NVRefCounted + { + public: + virtual bool IsMaterialRegistered(CRegisteredString inStr) = 0; + + virtual bool + RegisterMaterialClass(CRegisteredString inName, + NVConstDataRef inProperties) = 0; + + virtual NVConstDataRef + GetCustomMaterialProperties(CRegisteredString inCustomMaterialName) const = 0; + + virtual void SetCustomMaterialRefraction(CRegisteredString inName, + bool inHasRefraction) = 0; + virtual void SetCustomMaterialTransparency(CRegisteredString inName, + bool inHasTransparency) = 0; + virtual void SetCustomMaterialAlwaysDirty(CRegisteredString inName, + bool inIsAlwaysDirty) = 0; + virtual void SetCustomMaterialShaderKey(CRegisteredString inName, QT3DSU32 inShaderKey) = 0; + virtual void SetCustomMaterialLayerCount(CRegisteredString inName, QT3DSU32 inLayerCount) = 0; + // The custom material commands are the actual commands that run for a given material + // effect. The tell the system exactly + // explicitly things like bind this shader, bind this render target, apply this property, + // run this shader + // See UICRenderEffectCommands.h for the list of commands. + // These commands are copied into the effect. + virtual void SetCustomMaterialCommands(CRegisteredString inName, + NVConstDataRef inCommands) = 0; + + virtual void SetMaterialClassShader(CRegisteredString inName, const char8_t *inShaderType, + const char8_t *inShaderVersion, + const char8_t *inShaderData, bool inHasGeomShader, + bool inIsComputeShader) = 0; + + virtual SCustomMaterial * + CreateCustomMaterial(CRegisteredString inName, + NVAllocatorCallback &inSceneGraphAllocator) = 0; + + virtual void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inNames) = 0; + + virtual void SetPropertyTextureSettings(CRegisteredString inEffectName, + CRegisteredString inPropName, + CRegisteredString inPropPath, + NVRenderTextureTypeValue::Enum inTexType, + NVRenderTextureCoordOp::Enum inCoordOp, + NVRenderTextureMagnifyingOp::Enum inMagFilterOp, + NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0; + + virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, + const char8_t *inProjectDir) const = 0; + virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t *inProjectDir) = 0; + + virtual ICustomMaterialSystem &GetCustomMaterialSystem(IQt3DSRenderContext &inContext) = 0; + + static ICustomMaterialSystemCore & + CreateCustomMaterialSystemCore(IQt3DSRenderContextCore &inContext); + }; + // How to handle blend modes? + class ICustomMaterialSystem : public ICustomMaterialSystemCore + { + public: + // Returns true if the material is dirty and thus will produce a different render result + // than previously. This effects things like progressive AA. + virtual bool PrepareForRender(const SModel &inModel, const SRenderSubset &inSubset, + SCustomMaterial &inMaterial, bool inClearDirty) = 0; + + virtual bool RenderDepthPrepass(const QT3DSMat44 &inMVP, const SCustomMaterial &inMaterial, + const SRenderSubset &inSubset) = 0; + virtual void RenderSubset(SCustomMaterialRenderContext &inRenderContext, + TShaderFeatureSet inFeatureSet) = 0; + virtual void OnMaterialActivationChange(const SCustomMaterial &inMaterial, + bool inActive) = 0; + + // get shader name + virtual const char *GetShaderName(const SCustomMaterial &inMaterial) = 0; + // apply property values + virtual void ApplyShaderPropertyValues(const SCustomMaterial &inMaterial, + NVRenderShaderProgram &inProgram) = 0; + // Called by the uiccontext so this system can clear any per-frame render information. + virtual void EndFrame() = 0; + }; + + struct QT3DS_AUTOTEST_EXPORT SCustomMaterialVertexPipeline : public SVertexPipelineImpl + { + IQt3DSRenderContext *m_Context; + TessModeValues::Enum m_TessMode; + + SCustomMaterialVertexPipeline(IQt3DSRenderContext *inContext, TessModeValues::Enum inTessMode); + void InitializeTessControlShader(); + void InitializeTessEvaluationShader(); + void FinalizeTessControlShader(); + void FinalizeTessEvaluationShader(); + + // Responsible for beginning all vertex and fragment generation (void main() { etc). + virtual void BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) override; + // The fragment shader expects a floating point constant, object_opacity to be defined + // post this method. + virtual void BeginFragmentGeneration() override; + // Output variables may be mangled in some circumstances so the shader generation + // system needs an abstraction mechanism around this. + virtual void AssignOutput(const char8_t *inVarName, const char8_t *inVarValue) override; + virtual void GenerateEnvMapReflection() override {} + virtual void GenerateViewVector() override {} + virtual void GenerateUVCoords(QT3DSU32 inUVSet) override; + virtual void GenerateWorldNormal() override; + virtual void GenerateObjectNormal() override; + virtual void GenerateVarTangentAndBinormal() override; + virtual void GenerateWorldPosition() override; + // responsible for closing all vertex and fragment generation + virtual void EndVertexGeneration() override; + virtual void EndFragmentGeneration() override; + virtual IShaderStageGenerator &ActiveStage() override; + virtual void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override; + virtual void DoGenerateUVCoords(QT3DSU32 inUVSet) override; + virtual void DoGenerateWorldNormal() override; + virtual void DoGenerateObjectNormal() override; + virtual void DoGenerateWorldPosition() override; + virtual void DoGenerateVarTangentAndBinormal() override; + virtual void DoGenerateVertexColor() override; + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp new file mode 100644 index 00000000..4dceaca8 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp @@ -0,0 +1,1930 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "Qt3DSRenderableImage.h" +#include "Qt3DSRenderImage.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderLight.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderShadowMap.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderLightConstantProperties.h" + +using namespace qt3ds::render; +using qt3ds::render::NVRenderCachedShaderProperty; +using qt3ds::render::NVRenderCachedShaderBuffer; + +namespace { + +const QT3DSF32 MINATTENUATION = 0; +const QT3DSF32 MAXATTENUATION = 1000; + +QT3DSF32 ClampFloat(QT3DSF32 value, QT3DSF32 min, QT3DSF32 max) +{ + return value < min ? min : ((value > max) ? max : value); +} + +QT3DSF32 TranslateConstantAttenuation(QT3DSF32 attenuation) +{ + return attenuation * .01f; +} + +QT3DSF32 TranslateLinearAttenuation(QT3DSF32 attenuation) +{ + attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); + return attenuation * 0.0001f; +} + +QT3DSF32 TranslateQuadraticAttenuation(QT3DSF32 attenuation) +{ + attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); + return attenuation * 0.0000001f; +} + +/** + * Cached texture property lookups, used one per texture so a shader generator for N + * textures will have an array of N of these lookup objects. + */ +struct SShaderTextureProperties +{ + NVRenderCachedShaderProperty m_Sampler; + NVRenderCachedShaderProperty m_Offsets; + NVRenderCachedShaderProperty m_Rotations; + NVRenderCachedShaderProperty m_Size; + SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, + const char *sizeName, + NVRenderShaderProgram &inShader) + : m_Sampler(sampName, inShader) + , m_Offsets(offName, inShader) + , m_Rotations(rotName, inShader) + , m_Size(sizeName, inShader) + { + } + SShaderTextureProperties() {} +}; + +/** + * Cached light property lookups, used one per light so a shader generator for N + * lights will have an array of N of these lookup objects. + */ +struct SShaderLightProperties +{ + // Color of the light + QT3DSVec3 m_LightColor; + SLightSourceShader m_LightData; + + SShaderLightProperties() {} +}; + +struct SShadowMapProperties +{ + NVRenderCachedShaderProperty m_ShadowmapTexture; ///< shadow texture + NVRenderCachedShaderProperty m_ShadowCubeTexture; ///< shadow cubemap + NVRenderCachedShaderProperty + m_ShadowmapMatrix; ///< world to ligh space transform matrix + NVRenderCachedShaderProperty m_ShadowmapSettings; ///< shadow rendering settings + + SShadowMapProperties() {} + SShadowMapProperties(const char *shadowmapTextureName, const char *shadowcubeTextureName, + const char *shadowmapMatrixName, const char *shadowmapSettingsName, + NVRenderShaderProgram &inShader) + : m_ShadowmapTexture(shadowmapTextureName, inShader) + , m_ShadowCubeTexture(shadowcubeTextureName, inShader) + , m_ShadowmapMatrix(shadowmapMatrixName, inShader) + , m_ShadowmapSettings(shadowmapSettingsName, inShader) + { + } +}; + +/** + * The results of generating a shader. Caches all possible variable names into + * typesafe objects. + */ +struct SShaderGeneratorGeneratedShader +{ + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + // Specific properties we know the shader has to have. + NVRenderCachedShaderProperty m_MVP; + NVRenderCachedShaderProperty m_NormalMatrix; + NVRenderCachedShaderProperty m_GlobalTransform; + NVRenderCachedShaderProperty m_ViewProj; + NVRenderCachedShaderProperty m_ViewMatrix; + NVRenderCachedShaderProperty m_MaterialDiffuse; + NVRenderCachedShaderProperty m_MaterialProperties; + // tint, ior + NVRenderCachedShaderProperty m_MaterialSpecular; + NVRenderCachedShaderProperty m_BumpAmount; + NVRenderCachedShaderProperty m_DisplaceAmount; + NVRenderCachedShaderProperty m_TranslucentFalloff; + NVRenderCachedShaderProperty m_DiffuseLightWrap; + NVRenderCachedShaderProperty m_FresnelPower; + NVRenderCachedShaderProperty m_DiffuseColor; + NVRenderCachedShaderProperty m_CameraPosition; + NVRenderCachedShaderProperty m_CameraDirection; + QT3DSVec3 m_LightAmbientTotal; + NVRenderCachedShaderProperty m_MaterialDiffuseLightAmbientTotal; + NVRenderCachedShaderProperty m_CameraProperties; + + NVRenderCachedShaderProperty m_DepthTexture; + NVRenderCachedShaderProperty m_AOTexture; + NVRenderCachedShaderProperty m_LightProbe; + NVRenderCachedShaderProperty m_LightProbeProps; + NVRenderCachedShaderProperty m_LightProbeOpts; + NVRenderCachedShaderProperty m_LightProbeRot; + NVRenderCachedShaderProperty m_LightProbeOfs; + NVRenderCachedShaderProperty m_LightProbeSize; + NVRenderCachedShaderProperty m_LightProbe2; + NVRenderCachedShaderProperty m_LightProbe2Props; + NVRenderCachedShaderProperty m_LightProbe2Size; + + NVRenderCachedShaderBuffer m_AoShadowParams; + NVRenderCachedShaderBuffer m_LightsBuffer; + + SLightConstantProperties *m_lightConstantProperties; + + // Cache the image property name lookups + nvvector m_Images; + nvvector m_Lights; + // Cache shadow map properties + nvvector m_ShadowMaps; + + QT3DSI32 m_RefCount; + + SShaderGeneratorGeneratedShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) + : m_Allocator(inContext.GetAllocator()) + , m_Shader(inShader) + , m_MVP("model_view_projection", inShader) + , m_NormalMatrix("normal_matrix", inShader) + , m_GlobalTransform("model_matrix", inShader) + , m_ViewProj("view_projection_matrix", inShader) + , m_ViewMatrix("view_matrix", inShader) + , m_MaterialDiffuse("material_diffuse", inShader) + , m_MaterialProperties("material_properties", inShader) + , m_MaterialSpecular("material_specular", inShader) + , m_BumpAmount("bumpAmount", inShader) + , m_DisplaceAmount("displaceAmount", inShader) + , m_TranslucentFalloff("translucentFalloff", inShader) + , m_DiffuseLightWrap("diffuseLightWrap", inShader) + , m_FresnelPower("fresnelPower", inShader) + , m_DiffuseColor("diffuse_color", inShader) + , m_CameraPosition("camera_position", inShader) + , m_CameraDirection("camera_direction", inShader) + , m_MaterialDiffuseLightAmbientTotal("light_ambient_total", inShader) + , m_CameraProperties("camera_properties", inShader) + , m_DepthTexture("depth_sampler", inShader) + , m_AOTexture("ao_sampler", inShader) + , m_LightProbe("light_probe", inShader) + , m_LightProbeProps("light_probe_props", inShader) + , m_LightProbeOpts("light_probe_opts", inShader) + , m_LightProbeRot("light_probe_rotation", inShader) + , m_LightProbeOfs("light_probe_offset", inShader) + , m_LightProbeSize("light_probe_size", inShader) + , m_LightProbe2("light_probe2", inShader) + , m_LightProbe2Props("light_probe2_props", inShader) + , m_LightProbe2Size("light_probe2_size", inShader) + , m_AoShadowParams("cbAoShadow", inShader) + , m_LightsBuffer("cbBufferLights", inShader) + , m_lightConstantProperties(NULL) + , m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images") + , m_Lights(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Lights") + , m_ShadowMaps(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_ShadowMaps") + , m_RefCount(0) + { + m_Shader.addRef(); + } + ~SShaderGeneratorGeneratedShader() + { + if (m_lightConstantProperties) + delete m_lightConstantProperties; + m_Shader.release(); + } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Allocator); + NVDelete(alloc, this); + } + } +}; + + +#ifndef EA_PLATFORM_WINDOWS +#define _snprintf snprintf +#endif + +struct SShaderGenerator : public IDefaultMaterialShaderGenerator +{ + typedef CRenderString TStrType; + typedef nvhash_map> + TProgramToShaderMap; + typedef qt3ds::foundation::nvhash_map> + TStrConstanBufMap; + + IQt3DSRenderContext &m_RenderContext; + IShaderProgramGenerator &m_ProgramGenerator; + + const SDefaultMaterial *m_CurrentMaterial; + SShaderDefaultMaterialKey *m_CurrentKey; + Qt3DSShadowMap *m_ShadowMapManager; + IDefaultMaterialVertexPipeline *m_CurrentPipeline; + TShaderFeatureSet m_CurrentFeatureSet; + NVDataRef m_Lights; + SRenderableImage *m_FirstImage; + bool m_HasTransparency; + bool m_LightsAsSeparateUniforms; + + TStrType m_ImageStem; + TStrType m_ImageSampler; + TStrType m_ImageOffsets; + TStrType m_ImageRotations; + TStrType m_ImageFragCoords; + TStrType m_ImageTemp; + TStrType m_ImageSamplerSize; + + TStrType m_TexCoordTemp; + + TStrType m_LightStem; + TStrType m_LightColor; + TStrType m_LightSpecularColor; + TStrType m_LightAttenuation; + TStrType m_LightConstantAttenuation; + TStrType m_LightLinearAttenuation; + TStrType m_LightQuadraticAttenuation; + TStrType m_NormalizedDirection; + TStrType m_LightDirection; + TStrType m_LightPos; + TStrType m_LightUp; + TStrType m_LightRt; + TStrType m_RelativeDistance; + TStrType m_RelativeDirection; + + TStrType m_ShadowMapStem; + TStrType m_ShadowCubeStem; + TStrType m_ShadowMatrixStem; + TStrType m_ShadowCoordStem; + TStrType m_ShadowControlStem; + + TStrType m_TempStr; + + eastl::string m_GeneratedShaderString; + + SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; + TProgramToShaderMap m_ProgramToShaderMap; + + TStrConstanBufMap m_ConstantBuffers; ///< store all constants buffers + + QT3DSI32 m_RefCount; + + SShaderGenerator(IQt3DSRenderContext &inRc) + : m_RenderContext(inRc) + , m_ProgramGenerator(m_RenderContext.GetShaderProgramGenerator()) + , m_CurrentMaterial(NULL) + , m_CurrentKey(NULL) + , m_ShadowMapManager(NULL) + , m_CurrentPipeline(NULL) + , m_FirstImage(NULL) + , m_LightsAsSeparateUniforms(false) + , m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap") + , m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers") + , m_RefCount(0) + { + } + + void addRef() override { atomicIncrement(&m_RefCount); } + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + m_ConstantBuffers.clear(); + NVDelete(m_RenderContext.GetAllocator(), this); + } + } + IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } + IDefaultMaterialVertexPipeline &VertexGenerator() { return *m_CurrentPipeline; } + IShaderStageGenerator &FragmentGenerator() + { + return *m_ProgramGenerator.GetStage(ShaderGeneratorStages::Fragment); + } + SShaderDefaultMaterialKey &Key() { return *m_CurrentKey; } + const SDefaultMaterial &Material() { return *m_CurrentMaterial; } + TShaderFeatureSet FeatureSet() { return m_CurrentFeatureSet; } + bool HasTransparency() { return m_HasTransparency; } + + void addFunction(IShaderStageGenerator &generator, QString functionName) + { + generator.AddFunction(functionName); + } + + void SetupImageVariableNames(size_t imageIdx) + { + m_ImageStem = "image"; + char buf[16]; + _snprintf(buf, 16, "%d", int(imageIdx)); + m_ImageStem.append(buf); + m_ImageStem.append("_"); + + m_ImageSampler = m_ImageStem; + m_ImageSampler.append("sampler"); + m_ImageOffsets = m_ImageStem; + m_ImageOffsets.append("offsets"); + m_ImageRotations = m_ImageStem; + m_ImageRotations.append("rotations"); + m_ImageFragCoords = m_ImageStem; + m_ImageFragCoords.append("uv_coords"); + m_ImageSamplerSize = m_ImageStem; + m_ImageSamplerSize.append("size"); + } + + void SetupTexCoordVariableName(size_t uvSet) + { + m_TexCoordTemp = "varTexCoord"; + char buf[16]; + _snprintf(buf, 16, "%d", int(uvSet)); + m_TexCoordTemp.append(buf); + } + + SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override + { + SetupImageVariableNames(inIdx); + SImageVariableNames retval; + retval.m_ImageSampler = m_ImageSampler.c_str(); + retval.m_ImageFragCoords = m_ImageFragCoords.c_str(); + return retval; + } + + void AddLocalVariable(IShaderStageGenerator &inGenerator, const char8_t *inName, + const char8_t *inType) + { + inGenerator << "\t" << inType << " " << inName << ";" << Endl; + } + + void AddLocalVariable(IShaderStageGenerator &inGenerator, const TStrType &inName, + const char8_t *inType) + { + AddLocalVariable(inGenerator, inName.c_str(), inType); + } + + void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, QT3DSU32 uvSet, + SRenderableImage &image) override + { + IDefaultMaterialVertexPipeline &vertexShader( + static_cast(inVertexPipeline)); + IShaderStageGenerator &fragmentShader(FragmentGenerator()); + SetupImageVariableNames(idx); + SetupTexCoordVariableName(uvSet); + fragmentShader.AddUniform(m_ImageSampler, "sampler2D"); + vertexShader.AddUniform(m_ImageOffsets, "vec3"); + fragmentShader.AddUniform(m_ImageOffsets, "vec3"); + vertexShader.AddUniform(m_ImageRotations, "vec4"); + fragmentShader.AddUniform(m_ImageRotations, "vec4"); + + if (image.m_Image.m_MappingMode == ImageMappingModes::Normal) { + vertexShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " + << m_ImageRotations << ".y, " << m_ImageOffsets << ".x );" << Endl; + vertexShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " + << m_ImageRotations << ".w, " << m_ImageOffsets << ".y );" << Endl; + vertexShader.AddOutgoing(m_ImageFragCoords, "vec2"); + addFunction(vertexShader, "getTransformedUVCoords"); + vertexShader.GenerateUVCoords(uvSet); + m_ImageTemp = m_ImageFragCoords; + m_ImageTemp.append("temp"); + vertexShader << "\tvec2 " << m_ImageTemp << " = getTransformedUVCoords( vec3( " + << m_TexCoordTemp << ", 1.0), uTransform, vTransform );" << Endl; + if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) + vertexShader << "\t" << m_ImageTemp << ".y = 1.0 - " << m_ImageFragCoords << ".y;" + << Endl; + + vertexShader.AssignOutput(m_ImageFragCoords.c_str(), m_ImageTemp.c_str()); + } else { + fragmentShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " + << m_ImageRotations << ".y, " << m_ImageOffsets << ".x );" << Endl; + fragmentShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " + << m_ImageRotations << ".w, " << m_ImageOffsets << ".y );" << Endl; + vertexShader.GenerateEnvMapReflection(); + addFunction(fragmentShader, "getTransformedUVCoords"); + fragmentShader << "\tvec2 " << m_ImageFragCoords + << " = getTransformedUVCoords( environment_map_reflection, uTransform, " + "vTransform );" + << Endl; + if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) + fragmentShader << "\t" << m_ImageFragCoords << ".y = 1.0 - " << m_ImageFragCoords + << ".y;" << Endl; + } + } + + void GenerateImageUVCoordinates(QT3DSU32 idx, SRenderableImage &image, QT3DSU32 uvSet = 0) + { + GenerateImageUVCoordinates(VertexGenerator(), idx, uvSet, image); + } + + void GenerateImageUVCoordinates(QT3DSU32 idx, SRenderableImage &image, + IDefaultMaterialVertexPipeline &inShader) + { + if (image.m_Image.m_MappingMode == ImageMappingModes::Normal) { + SetupImageVariableNames(idx); + inShader.AddUniform(m_ImageSampler, "sampler2D"); + inShader.AddUniform(m_ImageOffsets, "vec3"); + inShader.AddUniform(m_ImageRotations, "vec4"); + + inShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " << m_ImageRotations + << ".y, " << m_ImageOffsets << ".x );" << Endl; + inShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " << m_ImageRotations + << ".w, " << m_ImageOffsets << ".y );" << Endl; + inShader << "\tvec2 " << m_ImageFragCoords << ";" << Endl; + addFunction(inShader, "getTransformedUVCoords"); + inShader.GenerateUVCoords(); + inShader + << "\t" << m_ImageFragCoords + << " = getTransformedUVCoords( vec3( varTexCoord0, 1.0), uTransform, vTransform );" + << Endl; + if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) + inShader << "\t" << m_ImageFragCoords << ".y = 1.0 - " << m_ImageFragCoords << ".y;" + << Endl; + } + } + + void OutputSpecularEquation(DefaultMaterialSpecularModel::Enum inSpecularModel, + IShaderStageGenerator &fragmentShader, const char *inLightDir, + const char *inLightSpecColor) + { + switch (inSpecularModel) { + case DefaultMaterialSpecularModel::KGGX: { + fragmentShader.AddInclude("defaultMaterialPhysGlossyBSDF.glsllib"); + fragmentShader.AddUniform("material_specular", "vec4"); + fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " + "specularColor * kggxGlossyDefaultMtl( " + << "world_normal, tangent, -" << inLightDir << ".xyz, view_vector, " + << inLightSpecColor + << ".rgb, vec3(material_specular.xyz), roughnessAmount, " + "roughnessAmount ).rgb;" + << Endl; + } break; + case DefaultMaterialSpecularModel::KWard: { + fragmentShader.AddInclude("defaultMaterialPhysGlossyBSDF.glsllib"); + fragmentShader.AddUniform("material_specular", "vec4"); + fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " + "specularColor * wardGlossyDefaultMtl( " + << "world_normal, tangent, -" << inLightDir << ".xyz, view_vector, " + << inLightSpecColor + << ".rgb, vec3(material_specular.xyz), roughnessAmount, " + "roughnessAmount ).rgb;" + << Endl; + } break; + default: + addFunction(fragmentShader, "specularBSDF"); + fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " + "specularColor * specularBSDF( " + << "world_normal, -" << inLightDir << ".xyz, view_vector, " + << inLightSpecColor << ".rgb, 1.0, 2.56 / (roughnessAmount + " + "0.01), vec3(1.0), scatter_reflect ).rgb;" + << Endl; + break; + } + } + + void OutputDiffuseAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos, + TStrType inLightPrefix) + { + m_NormalizedDirection = inLightPrefix + "_areaDir"; + AddLocalVariable(infragmentShader, m_NormalizedDirection, "vec3"); + infragmentShader << "\tlightAttenuation = calculateDiffuseAreaOld( " << m_LightDirection + << ".xyz, " << m_LightPos << ".xyz, " << m_LightUp << ", " << m_LightRt + << ", " << inPos << ", " << m_NormalizedDirection << " );" << Endl; + } + + void OutputSpecularAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos, + const char *inView, const char *inLightSpecColor) + { + addFunction(infragmentShader, "sampleAreaGlossyDefault"); + infragmentShader.AddUniform("material_specular", "vec4"); + infragmentShader << "global_specular_light.rgb += " << inLightSpecColor + << ".rgb * lightAttenuation * shadowFac * material_specular.rgb * " + "specularAmount * sampleAreaGlossyDefault( tanFrame, " + << inPos << ", " << m_NormalizedDirection << ", " << m_LightPos << ".xyz, " + << m_LightRt << ".w, " << m_LightUp << ".w, " << inView + << ", roughnessAmount, roughnessAmount ).rgb;" << Endl; + } + + void AddTranslucencyIrradiance(IShaderStageGenerator &infragmentShader, SRenderableImage *image, + TStrType inLightPrefix, bool areaLight) + { + if (image == NULL) + return; + + addFunction(infragmentShader, "diffuseReflectionWrapBSDF"); + if (areaLight) { + infragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " + "translucent_thickness_exp * diffuseReflectionWrapBSDF( " + "-world_normal, " + << m_NormalizedDirection << ", " << m_LightColor + << ".rgb, diffuseLightWrap ).rgb;" << Endl; + } else { + infragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " + "translucent_thickness_exp * diffuseReflectionWrapBSDF( " + "-world_normal, " + << "-" << m_NormalizedDirection << ", " << m_LightColor + << ".rgb, diffuseLightWrap ).rgb;" << Endl; + } + } + + void SetupShadowMapVariableNames(size_t lightIdx) + { + m_ShadowMapStem = "shadowmap"; + m_ShadowCubeStem = "shadowcube"; + char buf[16]; + _snprintf(buf, 16, "%d", int(lightIdx)); + m_ShadowMapStem.append(buf); + m_ShadowCubeStem.append(buf); + m_ShadowMatrixStem = m_ShadowMapStem; + m_ShadowMatrixStem.append("_matrix"); + m_ShadowCoordStem = m_ShadowMapStem; + m_ShadowCoordStem.append("_coord"); + m_ShadowControlStem = m_ShadowMapStem; + m_ShadowControlStem.append("_control"); + } + + void AddShadowMapContribution(IShaderStageGenerator &inLightShader, QT3DSU32 lightIndex, + RenderLightTypes::Enum inType) + { + SetupShadowMapVariableNames(lightIndex); + + inLightShader.AddInclude("shadowMapping.glsllib"); + if (inType == RenderLightTypes::Directional) { + inLightShader.AddUniform(m_ShadowMapStem, "sampler2D"); + } else { + inLightShader.AddUniform(m_ShadowCubeStem, "samplerCube"); + } + inLightShader.AddUniform(m_ShadowControlStem, "vec4"); + inLightShader.AddUniform(m_ShadowMatrixStem, "mat4"); + + /* + if ( inType == RenderLightTypes::Area ) + { + inLightShader << "vec2 " << m_ShadowCoordStem << ";" << Endl; + inLightShader << "\tshadow_map_occl = sampleParaboloid( " << m_ShadowMapStem << ", " + << m_ShadowControlStem << ", " + << + m_ShadowMatrixStem << ", varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z), " + << m_ShadowCoordStem + << " );" << Endl; + } + else */ + if (inType != RenderLightTypes::Directional) { + inLightShader << "\tshadow_map_occl = sampleCubemap( " << m_ShadowCubeStem << ", " + << m_ShadowControlStem << ", " << m_ShadowMatrixStem << ", " << m_LightPos + << ".xyz, varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z) );" + << Endl; + } else + inLightShader << "\tshadow_map_occl = sampleOrthographic( " << m_ShadowMapStem << ", " + << m_ShadowControlStem << ", " << m_ShadowMatrixStem + << ", varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z) );" << Endl; + } + + void AddDisplacementMappingForDepthPass(IShaderStageGenerator &inShader) override + { + inShader.AddIncoming("attr_uv0", "vec2"); + inShader.AddIncoming("attr_norm", "vec3"); + inShader.AddUniform("displacementSampler", "sampler2D"); + inShader.AddUniform("displaceAmount", "float"); + inShader.AddUniform("displacementMap_rot", "vec4"); + inShader.AddUniform("displacementMap_offset", "vec3"); + inShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + + inShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, displacementMap_rot.y, " + "displacementMap_offset.x );"); + inShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, displacementMap_rot.w, " + "displacementMap_offset.y );"); + addFunction(inShader, "getTransformedUVCoords"); + inShader.Append("\tvec2 uv_coords = attr_uv0;"); + inShader << "\tuv_coords = getTransformedUVCoords( vec3( uv_coords, 1.0), uTransform, " + "vTransform );\n"; + inShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " + "displacementSampler , displaceAmount, uv_coords , attr_norm, attr_pos );" + << Endl; + inShader.Append("\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); + } + + void AddDisplacementImageUniforms(IShaderStageGenerator &inGenerator, + QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) override + { + if (displacementImage) { + SetupImageVariableNames(displacementImageIdx); + inGenerator.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + inGenerator.AddUniform("model_matrix", "mat4"); + inGenerator.AddUniform("camera_position", "vec3"); + inGenerator.AddUniform("displaceAmount", "float"); + inGenerator.AddUniform(m_ImageSampler, "sampler2D"); + } + } + + bool MaybeAddMaterialFresnel(IShaderStageGenerator &fragmentShader, NVConstDataRef inKey, + bool inFragmentHasSpecularAmount) + { + if (m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey)) { + if (inFragmentHasSpecularAmount == false) + fragmentShader << "\tfloat specularAmount = 1.0;" << Endl; + inFragmentHasSpecularAmount = true; + fragmentShader.AddInclude("defaultMaterialFresnel.glsllib"); + fragmentShader.AddUniform("fresnelPower", "float"); + fragmentShader.AddUniform("material_specular", "vec4"); + fragmentShader << "\tfloat fresnelRatio = defaultMaterialSimpleFresnel( world_normal, " + "view_vector, material_specular.w, fresnelPower );" + << Endl; + fragmentShader << "\tspecularAmount *= fresnelRatio;" << Endl; + } + return inFragmentHasSpecularAmount; + } + void SetupLightVariableNames(size_t lightIdx, SLight &inLight) + { + if (m_LightsAsSeparateUniforms) { + char buf[16]; + _snprintf(buf, 16, "light_%d", int(lightIdx)); + m_LightStem = buf; + m_LightColor = m_LightStem; + m_LightColor.append("_diffuse"); + m_LightDirection = m_LightStem; + m_LightDirection.append("_direction"); + m_LightSpecularColor = m_LightStem; + m_LightSpecularColor.append("_specular"); + if (inLight.m_LightType == RenderLightTypes::Point) { + m_LightPos = m_LightStem; + m_LightPos.append("_position"); + m_LightAttenuation = m_LightStem; + m_LightAttenuation.append("_attenuation"); + } else if (inLight.m_LightType == RenderLightTypes::Area) { + m_LightPos = m_LightStem; + m_LightPos.append("_position"); + m_LightUp = m_LightStem; + m_LightUp.append("_up"); + m_LightRt = m_LightStem; + m_LightRt.append("_right"); + } + } else { + m_LightStem = "lights"; + char buf[16]; + _snprintf(buf, 16, "[%d].", int(lightIdx)); + m_LightStem.append(buf); + + m_LightColor = m_LightStem; + m_LightColor.append("diffuse"); + m_LightDirection = m_LightStem; + m_LightDirection.append("direction"); + m_LightSpecularColor = m_LightStem; + m_LightSpecularColor.append("specular"); + if (inLight.m_LightType == RenderLightTypes::Point) { + m_LightPos = m_LightStem; + m_LightPos.append("position"); + m_LightConstantAttenuation = m_LightStem; + m_LightConstantAttenuation.append("constantAttenuation"); + m_LightLinearAttenuation = m_LightStem; + m_LightLinearAttenuation.append("linearAttenuation"); + m_LightQuadraticAttenuation = m_LightStem; + m_LightQuadraticAttenuation.append("quadraticAttenuation"); + } else if (inLight.m_LightType == RenderLightTypes::Area) { + m_LightPos = m_LightStem; + m_LightPos.append("position"); + m_LightUp = m_LightStem; + m_LightUp.append("up"); + m_LightRt = m_LightStem; + m_LightRt.append("right"); + } + } + } + + void addDisplacementMapping(IDefaultMaterialVertexPipeline &inShader) + { + inShader.AddIncoming("attr_uv0", "vec2"); + inShader.AddIncoming("attr_norm", "vec3"); + inShader.AddUniform("displacementSampler", "sampler2D"); + inShader.AddUniform("displaceAmount", "float"); + inShader.AddUniform("displacementMap_rot", "vec4"); + inShader.AddUniform("displacementMap_offset", "vec3"); + inShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + + inShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, displacementMap_rot.y, " + "displacementMap_offset.x );"); + inShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, displacementMap_rot.w, " + "displacementMap_offset.y );"); + addFunction(inShader, "getTransformedUVCoords"); + inShader.GenerateUVCoords(); + inShader << "\tvarTexCoord0 = getTransformedUVCoords( vec3( varTexCoord0, 1.0), " + "uTransform, vTransform );\n"; + inShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " + "displacementSampler , displaceAmount, varTexCoord0 , attr_norm, attr_pos );" + << Endl; + inShader.Append("\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); + } + + void GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, + eastl::basic_string &texSwizzle, + eastl::basic_string &lookupSwizzle) + { + qt3ds::render::NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + + if (!(m_RenderContext.GetRenderContext().GetRenderContextType() & deprecatedContextFlags)) { + switch (swizzleMode) { + case NVRenderTextureSwizzleMode::L8toR8: + case NVRenderTextureSwizzleMode::L16toR16: + texSwizzle.append(".rgb"); + lookupSwizzle.append(".rrr"); + break; + case NVRenderTextureSwizzleMode::L8A8toRG8: + texSwizzle.append(".rgba"); + lookupSwizzle.append(".rrrg"); + break; + case NVRenderTextureSwizzleMode::A8toR8: + texSwizzle.append(".a"); + lookupSwizzle.append(".r"); + break; + default: + break; + } + } + } + + ///< get the light constant buffer and generate if necessary + NVRenderConstantBuffer *GetLightConstantBuffer(QT3DSU32 inLightCount) + { + NVRenderContext &theContext(m_RenderContext.GetRenderContext()); + + // we assume constant buffer support + QT3DS_ASSERT(theContext.GetConstantBufferSupport()); + + // we only create if if we have lights + if (!inLightCount || !theContext.GetConstantBufferSupport()) + return NULL; + + CRegisteredString theName = theContext.GetStringTable().RegisterStr("cbBufferLights"); + NVRenderConstantBuffer *pCB = theContext.GetConstantBuffer(theName); + + if (!pCB) { + // create + SLightSourceShader s[QT3DS_MAX_NUM_LIGHTS]; + NVDataRef cBuffer((QT3DSU8 *)&s, (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + + (4 * sizeof(QT3DSI32))); + pCB = theContext.CreateConstantBuffer( + theName, qt3ds::render::NVRenderBufferUsageType::Static, + (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + (4 * sizeof(QT3DSI32)), cBuffer); + if (!pCB) { + QT3DS_ASSERT(false); + return NULL; + } + // init first set + memset(&s[0], 0x0, sizeof(SLightSourceShader)); + QT3DSI32 cgLights = 0; + pCB->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); + pCB->UpdateRaw(4 * sizeof(QT3DSI32), + NVDataRef((QT3DSU8 *)&s[0], sizeof(SLightSourceShader))); + pCB->Update(); // update to hardware + + m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); + } + + return pCB; + } + + void SetImageShaderVariables(SShaderGeneratorGeneratedShader &inShader, + SRenderableImage &inImage, QT3DSU32 idx) + { + size_t numImageVariables = inShader.m_Images.size(); + for (size_t namesIdx = numImageVariables; namesIdx <= idx; ++namesIdx) { + SetupImageVariableNames(idx); + inShader.m_Images.push_back( + SShaderTextureProperties(m_ImageSampler.c_str(), m_ImageOffsets.c_str(), + m_ImageRotations.c_str(), m_ImageSamplerSize.c_str(), + inShader.m_Shader)); + } + SShaderTextureProperties &theShaderProps = inShader.m_Images[idx]; + const QT3DSMat44 &textureTransform = inImage.m_Image.m_TextureTransform; + // We separate rotational information from offset information so that just maybe the shader + // will attempt to push less information to the card. + const QT3DSF32 *dataPtr(textureTransform.front()); + // The third member of the offsets contains a flag indicating if the texture was + // premultiplied or not. + // We use this to mix the texture alpha. + QT3DSVec3 offsets(dataPtr[12], dataPtr[13], + inImage.m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f + : 0.0f); + // Grab just the upper 2x2 rotation matrix from the larger matrix. + QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); + + // The image horizontal and vertical tiling modes need to be set here, before we set texture + // on the shader. + // because setting the image on the texture forces the textue to bind and immediately apply + // any tex params. + NVRenderTexture2D *imageTexture = inImage.m_Image.m_TextureData.m_Texture; + inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapS( + inImage.m_Image.m_HorizontalTilingMode); + inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapT( + inImage.m_Image.m_VerticalTilingMode); + theShaderProps.m_Sampler.Set(imageTexture); + theShaderProps.m_Offsets.Set(offsets); + theShaderProps.m_Rotations.Set(rotations); + theShaderProps.m_Size.Set(QT3DSVec2(imageTexture->GetTextureDetails().m_Width, + imageTexture->GetTextureDetails().m_Height)); + } + + void GenerateShadowMapOcclusion(QT3DSU32 lightIdx, bool inShadowEnabled, + RenderLightTypes::Enum inType) + { + if (inShadowEnabled) { + VertexGenerator().GenerateWorldPosition(); + AddShadowMapContribution(FragmentGenerator(), lightIdx, inType); + /* + VertexGenerator().AddUniform( m_ShadowMatrixStem, "mat4" ); + VertexGenerator().AddOutgoing( m_ShadowCoordStem, "vec4" ); + VertexGenerator() << "\tvec4 local_" << m_ShadowCoordStem << " = " << m_ShadowMatrixStem + << " * vec4(local_model_world_position, 1.0);" << Endl; + m_TempStr.assign( "local_" ); + m_TempStr.append( m_ShadowCoordStem ); + VertexGenerator().AssignOutput( m_ShadowCoordStem.c_str(), m_TempStr.c_str() ); + */ + } else { + FragmentGenerator() << "\tshadow_map_occl = 1.0;" << Endl; + } + } + + void GenerateVertexShader() + { + // vertex displacement + QT3DSU32 imageIdx = 0; + SRenderableImage *displacementImage = NULL; + QT3DSU32 displacementImageIdx = 0; + + for (SRenderableImage *img = m_FirstImage; img != NULL; + img = img->m_NextImage, ++imageIdx) { + if (img->m_MapType == ImageMapTypes::Displacement) { + displacementImage = img; + displacementImageIdx = imageIdx; + break; + } + } + + // the pipeline opens/closes up the shaders stages + VertexGenerator().BeginVertexGeneration(displacementImageIdx, displacementImage); + } + + void GenerateFragmentShader(SShaderDefaultMaterialKey &inKey) + { + bool specularEnabled = Material().IsSpecularEnabled(); + bool vertexColorsEnabled = Material().IsVertexColorsEnabled(); + + bool hasLighting = Material().HasLighting(); + bool hasImage = m_FirstImage != NULL; + + bool hasIblProbe = m_DefaultMaterialShaderKeyProperties.m_HasIbl.GetValue(inKey); + bool hasSpecMap = false; + bool hasEnvMap = false; + bool hasEmissiveMap = false; + bool hasLightmaps = false; + // Pull the bump out as + SRenderableImage *bumpImage = NULL; + QT3DSU32 imageIdx = 0; + QT3DSU32 bumpImageIdx = 0; + SRenderableImage *specularAmountImage = NULL; + QT3DSU32 specularAmountImageIdx = 0; + SRenderableImage *roughnessImage = NULL; + QT3DSU32 roughnessImageIdx = 0; + // normal mapping + SRenderableImage *normalImage = NULL; + QT3DSU32 normalImageIdx = 0; + // translucency map + SRenderableImage *translucencyImage = NULL; + QT3DSU32 translucencyImageIdx = 0; + // lightmaps + SRenderableImage *lightmapIndirectImage = NULL; + QT3DSU32 lightmapIndirectImageIdx = 0; + SRenderableImage *lightmapRadiosityImage = NULL; + QT3DSU32 lightmapRadiosityImageIdx = 0; + SRenderableImage *lightmapShadowImage = NULL; + QT3DSU32 lightmapShadowImageIdx = 0; + const bool supportStandardDerivatives + = m_RenderContext.GetRenderContext().IsStandardDerivativesSupported(); + + for (SRenderableImage *img = m_FirstImage; img != NULL; + img = img->m_NextImage, ++imageIdx) { + hasSpecMap = img->m_MapType == ImageMapTypes::Specular; + if (img->m_MapType == ImageMapTypes::Bump) { + bumpImage = img; + bumpImageIdx = imageIdx; + } else if (img->m_MapType == ImageMapTypes::SpecularAmountMap) { + specularAmountImage = img; + specularAmountImageIdx = imageIdx; + } else if (img->m_MapType == ImageMapTypes::Roughness) { + roughnessImage = img; + roughnessImageIdx = imageIdx; + } else if (img->m_MapType == ImageMapTypes::Normal) { + normalImage = img; + normalImageIdx = imageIdx; + } else if (img->m_Image.m_MappingMode == ImageMappingModes::Environment) { + hasEnvMap = true; + } else if (img->m_MapType == ImageMapTypes::Translucency) { + translucencyImage = img; + translucencyImageIdx = imageIdx; + } else if (img->m_MapType == ImageMapTypes::Emissive) { + hasEmissiveMap = true; + } else if (img->m_MapType == ImageMapTypes::LightmapIndirect) { + lightmapIndirectImage = img; + lightmapIndirectImageIdx = imageIdx; + hasLightmaps = true; + } else if (img->m_MapType == ImageMapTypes::LightmapRadiosity) { + lightmapRadiosityImage = img; + lightmapRadiosityImageIdx = imageIdx; + hasLightmaps = true; + } else if (img->m_MapType == ImageMapTypes::LightmapShadow) { + lightmapShadowImage = img; + lightmapShadowImageIdx = imageIdx; + hasLightmaps = true; + } + } + + bool enableFresnel = m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey); + bool enableSSAO = false; + bool enableSSDO = false; + bool enableShadowMaps = false; + bool enableBumpNormal = normalImage || bumpImage; + + for (QT3DSU32 idx = 0; idx < FeatureSet().size(); ++idx) { + eastl::string name(FeatureSet()[idx].m_Name.c_str()); + if (name == "QT3DS_ENABLE_SSAO") + enableSSAO = FeatureSet()[idx].m_Enabled; + else if (name == "QT3DS_ENABLE_SSDO") + enableSSDO = FeatureSet()[idx].m_Enabled; + else if (name == "QT3DS_ENABLE_SSM") + enableShadowMaps = FeatureSet()[idx].m_Enabled; + } + + bool includeSSAOSSDOVars = enableSSAO || enableSSDO || enableShadowMaps; + + VertexGenerator().BeginFragmentGeneration(); + IShaderStageGenerator &fragmentShader(FragmentGenerator()); + IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); + + // The fragment or vertex shaders may not use the material_properties or diffuse + // uniforms in all cases but it is simpler to just add them and let the linker strip them. + fragmentShader.AddUniform("material_diffuse", "vec4"); + fragmentShader.AddUniform("diffuse_color", "vec3"); + fragmentShader.AddUniform("material_properties", "vec4"); + + // All these are needed for SSAO + if (includeSSAOSSDOVars) { + fragmentShader.AddInclude("SSAOCustomMaterial.glsllib"); + // fragmentShader.AddUniform( "ao_sampler", "sampler2D" ); + } + + if (hasIblProbe && hasLighting) { + fragmentShader.AddInclude("sampleProbe.glsllib"); + } + + if (hasLighting) { + if (!m_LightsAsSeparateUniforms) + addFunction(fragmentShader, "sampleLightVars"); + addFunction(fragmentShader, "diffuseReflectionBSDF"); + } + + if (hasLighting && hasLightmaps) { + fragmentShader.AddInclude("evalLightmaps.glsllib"); + } + + // view_vector, varWorldPos, world_normal are all used if there is a specular map + // in addition to if there is specular lighting. So they are lifted up here, always + // generated. + // we rely on the linker to strip out what isn't necessary instead of explicitly stripping + // it for code simplicity. + if (hasImage) { + fragmentShader.Append("\tvec3 uTransform;"); + fragmentShader.Append("\tvec3 vTransform;"); + } + + if (includeSSAOSSDOVars || hasSpecMap || hasLighting || hasEnvMap || enableFresnel + || hasIblProbe || enableBumpNormal) { + vertexShader.GenerateViewVector(); + vertexShader.GenerateWorldNormal(); + vertexShader.GenerateWorldPosition(); + } + if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal) + vertexShader.GenerateVarTangentAndBinormal(); + + if (vertexColorsEnabled) + vertexShader.GenerateVertexColor(); + else + fragmentShader.Append("\tvec3 vertColor = vec3(1.0);"); + + // You do bump or normal mapping but not both + if (bumpImage != NULL) { + GenerateImageUVCoordinates(bumpImageIdx, *bumpImage); + fragmentShader.AddUniform("bumpAmount", "float"); + + fragmentShader.AddUniform(m_ImageSamplerSize, "vec2"); + fragmentShader.AddInclude("defaultMaterialBumpNoLod.glsllib"); + fragmentShader << "\tworld_normal = defaultMaterialBumpNoLod( " << m_ImageSampler + << ", bumpAmount, " << m_ImageFragCoords + << ", tangent, binormal, world_normal, " + << m_ImageSamplerSize << ");" << Endl; + // Do gram schmidt + fragmentShader << "\tbinormal = normalize(cross(world_normal, tangent) );\n"; + fragmentShader << "\ttangent = normalize(cross(binormal, world_normal) );\n"; + + } else if (normalImage != NULL) { + GenerateImageUVCoordinates(normalImageIdx, *normalImage); + + fragmentShader.AddInclude("defaultMaterialFileNormalTexture.glsllib"); + fragmentShader.AddUniform("bumpAmount", "float"); + + fragmentShader << "\tworld_normal = defaultMaterialFileNormalTexture( " + << m_ImageSampler << ", bumpAmount, " << m_ImageFragCoords + << ", tangent, binormal );" << Endl; + } + + if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal) + fragmentShader << "\tmat3 tanFrame = mat3(tangent, binormal, world_normal);" << Endl; + + bool fragmentHasSpecularAmount = false; + + if (hasEmissiveMap) { + fragmentShader.Append("\tvec3 global_emission = material_diffuse.rgb;"); + } + + if (hasLighting) { + fragmentShader.AddUniform("light_ambient_total", "vec3"); + + fragmentShader.Append( + "\tvec4 global_diffuse_light = vec4(light_ambient_total.xyz, 1.0);"); + fragmentShader.Append("\tvec3 global_specular_light = vec3(0.0, 0.0, 0.0);"); + fragmentShader.Append("\tfloat shadow_map_occl = 1.0;"); + + if (specularEnabled) { + vertexShader.GenerateViewVector(); + fragmentShader.AddUniform("material_properties", "vec4"); + } + + if (lightmapIndirectImage != NULL) { + GenerateImageUVCoordinates(lightmapIndirectImageIdx, *lightmapIndirectImage, 1); + fragmentShader << "\tvec4 indirect_light = texture2D( " << m_ImageSampler << ", " + << m_ImageFragCoords << ");" << Endl; + fragmentShader << "\tglobal_diffuse_light += indirect_light;" << Endl; + if (specularEnabled) { + fragmentShader + << "\tglobal_specular_light += indirect_light.rgb * material_properties.x;" + << Endl; + } + } + + if (lightmapRadiosityImage != NULL) { + GenerateImageUVCoordinates(lightmapRadiosityImageIdx, *lightmapRadiosityImage, 1); + fragmentShader << "\tvec4 direct_light = texture2D( " << m_ImageSampler << ", " + << m_ImageFragCoords << ");" << Endl; + fragmentShader << "\tglobal_diffuse_light += direct_light;" << Endl; + if (specularEnabled) { + fragmentShader + << "\tglobal_specular_light += direct_light.rgb * material_properties.x;" + << Endl; + } + } + + if (translucencyImage != NULL) { + fragmentShader.AddUniform("translucentFalloff", "float"); + fragmentShader.AddUniform("diffuseLightWrap", "float"); + + GenerateImageUVCoordinates(translucencyImageIdx, *translucencyImage); + + fragmentShader << "\tvec4 translucent_depth_range = texture2D( " << m_ImageSampler + << ", " << m_ImageFragCoords << ");" << Endl; + fragmentShader << "\tfloat translucent_thickness = translucent_depth_range.r * " + "translucent_depth_range.r;" + << Endl; + fragmentShader << "\tfloat translucent_thickness_exp = exp( translucent_thickness " + "* translucentFalloff);" + << Endl; + } + + fragmentShader.Append("\tfloat lightAttenuation = 1.0;"); + + AddLocalVariable(fragmentShader, "aoFactor", "float"); + + if (hasLighting && enableSSAO) + fragmentShader.Append("\taoFactor = customMaterialAO();"); + else + fragmentShader.Append("\taoFactor = 1.0;"); + + AddLocalVariable(fragmentShader, "shadowFac", "float"); + + if (specularEnabled) { + fragmentShader << "\tfloat specularAmount = material_properties.x;" << Endl; + fragmentHasSpecularAmount = true; + } + // Fragment lighting means we can perhaps attenuate the specular amount by a texture + // lookup. + + fragmentShader << "\tvec3 specularColor = vec3(1.0);" << Endl; + if (specularAmountImage) { + if (!specularEnabled) + fragmentShader << "\tfloat specularAmount = 1.0;" << Endl; + GenerateImageUVCoordinates(specularAmountImageIdx, *specularAmountImage); + fragmentShader << "\tspecularColor = texture2D( " + << m_ImageSampler << ", " << m_ImageFragCoords << " ).xyz;" << Endl; + fragmentHasSpecularAmount = true; + } + + fragmentShader << "\tfloat roughnessAmount = material_properties.y;" << Endl; + if (roughnessImage) { + GenerateImageUVCoordinates(roughnessImageIdx, *roughnessImage); + fragmentShader << "\tfloat sampledRoughness = texture2D( " + << m_ImageSampler << ", " << m_ImageFragCoords << " ).x;" << Endl; + //The roughness sampled from roughness textures is Disney roughness + //which has to be squared to get the proper value + fragmentShader << "\troughnessAmount = roughnessAmount * " + << "sampledRoughness * sampledRoughness;" << Endl; + } + + fragmentHasSpecularAmount = + MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount); + + // Iterate through all lights + for (QT3DSU32 lightIdx = 0; lightIdx < m_Lights.size(); ++lightIdx) { + SLight *lightNode = m_Lights[lightIdx]; + SetupLightVariableNames(lightIdx, *lightNode); + bool isDirectional = lightNode->m_LightType == RenderLightTypes::Directional; + bool isArea = lightNode->m_LightType == RenderLightTypes::Area; + bool isShadow = enableShadowMaps && lightNode->m_CastShadow; + + fragmentShader.Append(""); + char buf[10]; + sprintf(buf, "%d", lightIdx); + + m_TempStr.assign("light"); + m_TempStr.append(buf); + + fragmentShader << "\t//Light " << buf << Endl; + fragmentShader << "\tlightAttenuation = 1.0;" << Endl; + if (isDirectional) { + + if (m_LightsAsSeparateUniforms) { + fragmentShader.AddUniform(m_LightDirection, "vec4"); + fragmentShader.AddUniform(m_LightColor, "vec4"); + } + + if (enableSSDO) { + fragmentShader << "\tshadowFac = customMaterialShadow( " << m_LightDirection + << ".xyz, varWorldPos );" << Endl; + } else { + fragmentShader << "\tshadowFac = 1.0;" << Endl; + } + + GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, + lightNode->m_LightType); + + if (specularEnabled && enableShadowMaps && isShadow) + fragmentShader << "\tlightAttenuation *= shadow_map_occl;" << Endl; + + fragmentShader << "\tglobal_diffuse_light.rgb += shadowFac * shadow_map_occl * " + "diffuseReflectionBSDF( world_normal, " + << "-" << m_LightDirection << ".xyz, view_vector, " + << m_LightColor << ".rgb, 0.0 ).rgb;" << Endl; + + if (specularEnabled) { + if (m_LightsAsSeparateUniforms) + fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); + OutputSpecularEquation(Material().m_SpecularModel, fragmentShader, + m_LightDirection.c_str(), + m_LightSpecularColor.c_str()); + } + } else if (isArea) { + if (m_LightsAsSeparateUniforms) { + fragmentShader.AddUniform(m_LightColor, "vec4"); + fragmentShader.AddUniform(m_LightPos, "vec4"); + fragmentShader.AddUniform(m_LightDirection, "vec4"); + fragmentShader.AddUniform(m_LightUp, "vec4"); + fragmentShader.AddUniform(m_LightRt, "vec4"); + } else { + addFunction(fragmentShader, "areaLightVars"); + } + addFunction(fragmentShader, "calculateDiffuseAreaOld"); + vertexShader.GenerateWorldPosition(); + GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, + lightNode->m_LightType); + + // Debug measure to make sure paraboloid sampling was projecting to the right + // location + // fragmentShader << "\tglobal_diffuse_light.rg += " << m_ShadowCoordStem << ";" + // << Endl; + m_NormalizedDirection = m_TempStr; + m_NormalizedDirection.append("_Frame"); + + AddLocalVariable(fragmentShader, m_NormalizedDirection, "mat3"); + fragmentShader << m_NormalizedDirection << " = mat3( " << m_LightRt << ".xyz, " + << m_LightUp << ".xyz, -" << m_LightDirection << ".xyz );" + << Endl; + + if (enableSSDO) { + fragmentShader << "\tshadowFac = shadow_map_occl * customMaterialShadow( " + << m_LightDirection << ".xyz, varWorldPos );" << Endl; + } else { + fragmentShader << "\tshadowFac = shadow_map_occl;" << Endl; + } + + if (specularEnabled) { + vertexShader.GenerateViewVector(); + if (m_LightsAsSeparateUniforms) + fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); + OutputSpecularAreaLighting(fragmentShader, "varWorldPos", "view_vector", + m_LightSpecularColor.c_str()); + } + + OutputDiffuseAreaLighting(fragmentShader, "varWorldPos", m_TempStr); + fragmentShader << "\tlightAttenuation *= shadowFac;" << Endl; + + AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, true); + + fragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " + "diffuseReflectionBSDF( world_normal, " + << m_NormalizedDirection << ", view_vector, " << m_LightColor + << ".rgb, 0.0 ).rgb;" << Endl; + } else { + + vertexShader.GenerateWorldPosition(); + GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, + lightNode->m_LightType); + + if (m_LightsAsSeparateUniforms) { + fragmentShader.AddUniform(m_LightColor, "vec4"); + fragmentShader.AddUniform(m_LightPos, "vec4"); + } + + m_RelativeDirection = m_TempStr; + m_RelativeDirection.append("_relativeDirection"); + + m_NormalizedDirection = m_RelativeDirection; + m_NormalizedDirection.append("_normalized"); + + m_RelativeDistance = m_TempStr; + m_RelativeDistance.append("_distance"); + + fragmentShader << "\tvec3 " << m_RelativeDirection << " = varWorldPos - " + << m_LightPos << ".xyz;" << Endl; + fragmentShader << "\tfloat " << m_RelativeDistance << " = length( " + << m_RelativeDirection << " );" << Endl; + fragmentShader << "\tvec3 " << m_NormalizedDirection << " = " + << m_RelativeDirection << " / " << m_RelativeDistance << ";" + << Endl; + + if (enableSSDO) { + fragmentShader << "\tshadowFac = shadow_map_occl * customMaterialShadow( " + << m_NormalizedDirection << ", varWorldPos );" << Endl; + } else { + fragmentShader << "\tshadowFac = shadow_map_occl;" << Endl; + } + + addFunction(fragmentShader, "calculatePointLightAttenuation"); + + if (m_LightsAsSeparateUniforms) { + fragmentShader.AddUniform(m_LightAttenuation, "vec3"); + fragmentShader + << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation(" + << "vec3( " << m_LightAttenuation << ".x, " << m_LightAttenuation + << ".y, " << m_LightAttenuation << ".z), " << m_RelativeDistance + << ");" << Endl; + } else { + fragmentShader + << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation(" + << "vec3( " << m_LightConstantAttenuation << ", " + << m_LightLinearAttenuation << ", " << m_LightQuadraticAttenuation + << "), " << m_RelativeDistance << ");" + << Endl; + } + + + + AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, false); + + fragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " + "diffuseReflectionBSDF( world_normal, " + << "-" << m_NormalizedDirection << ", view_vector, " + << m_LightColor << ".rgb, 0.0 ).rgb;" << Endl; + + if (specularEnabled) { + if (m_LightsAsSeparateUniforms) + fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); + OutputSpecularEquation(Material().m_SpecularModel, fragmentShader, + m_NormalizedDirection.c_str(), + m_LightSpecularColor.c_str()); + } + } + } + + // This may be confusing but the light colors are already modulated by the base + // material color. + // Thus material color is the base material color * material emissive. + // Except material_color.a *is* the actual opacity factor. + // Furthermore object_opacity is something that may come from the vertex pipeline or + // somewhere else. + // We leave it up to the vertex pipeline to figure it out. + fragmentShader << "\tglobal_diffuse_light = vec4(global_diffuse_light.xyz * aoFactor, " + "object_opacity);" + << Endl << "\tglobal_specular_light = vec3(global_specular_light.xyz);" + << Endl; + } else // no lighting. + { + fragmentShader << "\tvec4 global_diffuse_light = vec4(0.0, 0.0, 0.0, object_opacity);" + << Endl << "\tvec3 global_specular_light = vec3(0.0, 0.0, 0.0);" << Endl; + + // We still have specular maps and such that could potentially use the fresnel variable. + fragmentHasSpecularAmount = + MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount); + } + + if (!hasEmissiveMap) + fragmentShader + << "\tglobal_diffuse_light.rgb += diffuse_color.rgb * material_diffuse.rgb;" + << Endl; + + // since we already modulate our material diffuse color + // into the light color we will miss it entirely if no IBL + // or light is used + if (hasLightmaps && !(m_Lights.size() || hasIblProbe)) + fragmentShader << "\tglobal_diffuse_light.rgb *= diffuse_color.rgb;" << Endl; + + if (hasLighting && hasIblProbe) { + vertexShader.GenerateWorldNormal(); + + fragmentShader << "\tglobal_diffuse_light.rgb += diffuse_color.rgb * aoFactor * " + "sampleDiffuse( tanFrame ).xyz;" + << Endl; + + if (specularEnabled) { + + fragmentShader.AddUniform("material_specular", "vec4"); + + fragmentShader << "\tglobal_specular_light.xyz += specularAmount * specularColor * " + "vec3(material_specular.xyz) * sampleGlossy( tanFrame, " + "view_vector, roughnessAmount ).xyz;" + << Endl; + } + } + + if (hasImage) { + fragmentShader.Append("\tvec4 texture_color;"); + QT3DSU32 idx = 0; + for (SRenderableImage *image = m_FirstImage; image; image = image->m_NextImage, ++idx) { + // Various maps are handled on a different locations + if (image->m_MapType == ImageMapTypes::Bump + || image->m_MapType == ImageMapTypes::Normal + || image->m_MapType == ImageMapTypes::Displacement + || image->m_MapType == ImageMapTypes::SpecularAmountMap + || image->m_MapType == ImageMapTypes::Roughness + || image->m_MapType == ImageMapTypes::Translucency + || image->m_MapType == ImageMapTypes::LightmapIndirect + || image->m_MapType == ImageMapTypes::LightmapRadiosity) { + continue; + } + + eastl::basic_string texSwizzle, lookupSwizzle, texLodStr; + + GenerateImageUVCoordinates(idx, *image, 0); + + GenerateTextureSwizzle( + image->m_Image.m_TextureData.m_Texture->GetTextureSwizzleMode(), texSwizzle, + lookupSwizzle); + + if (texLodStr.empty()) { + fragmentShader << "\ttexture_color" << texSwizzle.c_str() << " = texture2D( " + << m_ImageSampler << ", " << m_ImageFragCoords << ")" + << lookupSwizzle.c_str() << ";" << Endl; + } else { + fragmentShader << "\ttexture_color" << texSwizzle.c_str() << "= textureLod( " + << m_ImageSampler << ", " << m_ImageFragCoords << ", " + << texLodStr.c_str() << " )" << lookupSwizzle.c_str() << ";" + << Endl; + } + + if (image->m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() == true) + fragmentShader << "\ttexture_color.rgb = texture_color.a > 0.0 ? " + "texture_color.rgb / texture_color.a : vec3( 0, 0, 0 );" + << Endl; + + // These mapping types honestly don't make a whole ton of sense to me. + switch (image->m_MapType) { + case ImageMapTypes::Diffuse: // assume images are premultiplied. + case ImageMapTypes::LightmapShadow: + // We use image offsets.z to switch between incoming premultiplied textures or + // not premultiplied textures. + // If Z is 1, then we assume the incoming texture is already premultiplied, else + // we just read the rgb value. + fragmentShader.Append("\tglobal_diffuse_light *= texture_color;"); + break; + case ImageMapTypes::Specular: + + fragmentShader.AddUniform("material_specular", "vec4"); + if (fragmentHasSpecularAmount) { + fragmentShader.Append("\tglobal_specular_light.xyz += specularAmount * " + "specularColor * texture_color.xyz * " + "material_specular.xyz;"); + } else { + fragmentShader.Append("\tglobal_specular_light.xyz += texture_color.xyz * " + "material_specular.xyz;"); + } + fragmentShader.Append("\tglobal_diffuse_light.a *= texture_color.a;"); + break; + case ImageMapTypes::Opacity: + fragmentShader.Append("\tglobal_diffuse_light.a *= texture_color.a;"); + break; + case ImageMapTypes::Emissive: + fragmentShader.Append( + "\tglobal_emission *= texture_color.xyz * texture_color.a;"); + break; + default: + QT3DS_ASSERT(false); // fallthrough intentional + } + } + } + + if (hasEmissiveMap) { + fragmentShader.Append("\tglobal_diffuse_light.rgb += global_emission.rgb;"); + } + + // Ensure the rgb colors are in range. + fragmentShader.Append("\tfragOutput = vec4( clamp( vertColor * global_diffuse_light.xyz + " + "global_specular_light.xyz, 0.0, 65519.0 ), global_diffuse_light.a " + ");"); + + if (VertexGenerator().HasActiveWireframe()) { + fragmentShader.Append("vec3 edgeDistance = varEdgeDistance * gl_FragCoord.w;"); + fragmentShader.Append( + "\tfloat d = min(min(edgeDistance.x, edgeDistance.y), edgeDistance.z);"); + fragmentShader.Append("\tfloat mixVal = smoothstep(0.0, 1.0, d);"); // line width 1.0 + + fragmentShader.Append( + "\tfragOutput = mix( vec4(0.0, 1.0, 0.0, 1.0), fragOutput, mixVal);"); + } + } + + NVRenderShaderProgram *GenerateMaterialShader(const char8_t *inShaderPrefix) + { + // build a string that allows us to print out the shader we are generating to the log. + // This is time consuming but I feel like it doesn't happen all that often and is very + // useful to users + // looking at the log file. + + m_GeneratedShaderString.clear(); + m_GeneratedShaderString.assign(nonNull(inShaderPrefix)); + + SShaderDefaultMaterialKey theKey(Key()); + theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); + + m_LightsAsSeparateUniforms = !m_RenderContext.GetRenderContext().GetConstantBufferSupport(); + + GenerateVertexShader(); + GenerateFragmentShader(theKey); + + VertexGenerator().EndVertexGeneration(); + VertexGenerator().EndFragmentGeneration(); + + return ProgramGenerator().CompileGeneratedShader(m_GeneratedShaderString.c_str(), + SShaderCacheProgramFlags(), FeatureSet()); + } + + virtual NVRenderShaderProgram * + GenerateShader(const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, + IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, + NVDataRef inLights, SRenderableImage *inFirstImage, + bool inHasTransparency, const char8_t *inVertexPipelineName, const char8_t *) override + { + QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::DefaultMaterial); + m_CurrentMaterial = static_cast(&inMaterial); + m_CurrentKey = &inShaderDescription; + m_CurrentPipeline = static_cast(&inVertexPipeline); + m_CurrentFeatureSet = inFeatureSet; + m_Lights = inLights; + m_FirstImage = inFirstImage; + m_HasTransparency = inHasTransparency; + + return GenerateMaterialShader(inVertexPipelineName); + } + + SShaderGeneratorGeneratedShader &GetShaderForProgram(NVRenderShaderProgram &inProgram) + { + eastl::pair inserter = + m_ProgramToShaderMap.insert(eastl::make_pair( + &inProgram, NVScopedRefCounted(NULL))); + if (inserter.second) { + NVAllocatorCallback &alloc(m_RenderContext.GetRenderContext().GetAllocator()); + inserter.first->second = QT3DS_NEW(alloc, SShaderGeneratorGeneratedShader)( + inProgram, m_RenderContext.GetRenderContext()); + } + return *inserter.first->second; + } + + void SetGlobalProperties(NVRenderShaderProgram &inProgram, const SLayer & /*inLayer*/ + , + SCamera &inCamera, QT3DSVec3 inCameraDirection, + NVDataRef inLights, NVDataRef inLightDirections, + Qt3DSShadowMap *inShadowMapManager) + { + SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(inProgram)); + m_RenderContext.GetRenderContext().SetActiveShader(&inProgram); + + m_ShadowMapManager = inShadowMapManager; + + SCamera &theCamera(inCamera); + shader.m_CameraPosition.Set(theCamera.GetGlobalPos()); + shader.m_CameraDirection.Set(inCameraDirection); + + QT3DSMat44 viewProj; + if (shader.m_ViewProj.IsValid()) { + theCamera.CalculateViewProjectionMatrix(viewProj); + shader.m_ViewProj.Set(viewProj); + } + + if (shader.m_ViewMatrix.IsValid()) { + viewProj = theCamera.m_GlobalTransform.getInverse(); + shader.m_ViewMatrix.Set(viewProj); + } + + // update the constant buffer + shader.m_AoShadowParams.Set(); + // We can't cache light properties because they can change per object. + QT3DSVec3 theLightAmbientTotal = QT3DSVec3(0, 0, 0); + size_t numShaderLights = shader.m_Lights.size(); + size_t numShadowLights = shader.m_ShadowMaps.size(); + for (QT3DSU32 lightIdx = 0, shadowMapIdx = 0, lightEnd = inLights.size(); + lightIdx < lightEnd && lightIdx < QT3DS_MAX_NUM_LIGHTS; ++lightIdx) { + SLight *theLight(inLights[lightIdx]); + if (lightIdx >= numShaderLights) { + shader.m_Lights.push_back(SShaderLightProperties()); + ++numShaderLights; + } + if (shadowMapIdx >= numShadowLights && numShadowLights < QT3DS_MAX_NUM_SHADOWS) { + if (theLight->m_Scope == NULL && theLight->m_CastShadow) { + // PKC TODO : Fix multiple shadow issues. + // Need to know when the list of lights changes order, and clear shadow maps + // when that happens. + SetupShadowMapVariableNames(lightIdx); + shader.m_ShadowMaps.push_back(SShadowMapProperties( + m_ShadowMapStem.c_str(), m_ShadowCubeStem.c_str(), + m_ShadowMatrixStem.c_str(), m_ShadowControlStem.c_str(), inProgram)); + } + } + QT3DS_ASSERT(lightIdx < numShaderLights); + SShaderLightProperties &theLightProperties(shader.m_Lights[lightIdx]); + float brightness = TranslateConstantAttenuation(theLight->m_Brightness); + + // setup light data + theLightProperties.m_LightColor = theLight->m_DiffuseColor * brightness; + theLightProperties.m_LightData.m_specular = + QT3DSVec4(theLight->m_SpecularColor * brightness, 1.0); + theLightProperties.m_LightData.m_direction = QT3DSVec4(inLightDirections[lightIdx], 1.0); + + // TODO : This does potentially mean that we can create more shadow map entries than + // we can actually use at once. + if ((theLight->m_Scope == NULL) && (theLight->m_CastShadow && inShadowMapManager)) { + SShadowMapProperties &theShadowMapProperties(shader.m_ShadowMaps[shadowMapIdx++]); + SShadowMapEntry *pEntry = inShadowMapManager->GetShadowMapEntry(lightIdx); + if (pEntry) { + // add fixed scale bias matrix + QT3DSMat44 bias(QT3DSVec4(0.5, 0.0, 0.0, 0.0), QT3DSVec4(0.0, 0.5, 0.0, 0.0), + QT3DSVec4(0.0, 0.0, 0.5, 0.0), QT3DSVec4(0.5, 0.5, 0.5, 1.0)); + + if (theLight->m_LightType != RenderLightTypes::Directional) { + theShadowMapProperties.m_ShadowCubeTexture.Set(pEntry->m_DepthCube); + theShadowMapProperties.m_ShadowmapMatrix.Set(pEntry->m_LightView); + } else { + theShadowMapProperties.m_ShadowmapTexture.Set(pEntry->m_DepthMap); + theShadowMapProperties.m_ShadowmapMatrix.Set(bias * pEntry->m_LightVP); + } + + theShadowMapProperties.m_ShadowmapSettings.Set( + QT3DSVec4(theLight->m_ShadowBias, theLight->m_ShadowFactor, + theLight->m_ShadowMapFar, 0.0f)); + } else { + // if we have a light casting shadow we should find an entry + QT3DS_ASSERT(false); + } + } + + if (theLight->m_LightType == RenderLightTypes::Point) { + theLightProperties.m_LightData.m_position = QT3DSVec4(theLight->GetGlobalPos(), 1.0); + theLightProperties.m_LightData.m_constantAttenuation = 1.0; + theLightProperties.m_LightData.m_linearAttenuation = + TranslateLinearAttenuation(theLight->m_LinearFade); + theLightProperties.m_LightData.m_quadraticAttenuation = + TranslateQuadraticAttenuation(theLight->m_ExponentialFade); + } else if (theLight->m_LightType == RenderLightTypes::Area) { + theLightProperties.m_LightData.m_position = QT3DSVec4(theLight->GetGlobalPos(), 1.0); + + QT3DSVec3 upDir = theLight->m_GlobalTransform.getUpper3x3().transform(QT3DSVec3(0, 1, 0)); + QT3DSVec3 rtDir = theLight->m_GlobalTransform.getUpper3x3().transform(QT3DSVec3(1, 0, 0)); + + theLightProperties.m_LightData.m_up = QT3DSVec4(upDir, theLight->m_AreaHeight); + theLightProperties.m_LightData.m_right = QT3DSVec4(rtDir, theLight->m_AreaWidth); + } + theLightAmbientTotal += theLight->m_AmbientColor; + } + shader.m_LightAmbientTotal = theLightAmbientTotal; + } + + // Also sets the blend function on the render context. + void SetMaterialProperties(NVRenderShaderProgram &inProgram, const SDefaultMaterial &inMaterial, + const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inSSaoTexture, + SImage *inLightProbe, SImage *inLightProbe2, QT3DSF32 inProbeHorizon, + QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, + QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) + { + + NVRenderContext &context(m_RenderContext.GetRenderContext()); + SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(inProgram)); + shader.m_MVP.Set(inModelViewProjection); + shader.m_NormalMatrix.Set(inNormalMatrix); + shader.m_GlobalTransform.Set(inGlobalTransform); + shader.m_DepthTexture.Set(inDepthTexture); + + shader.m_AOTexture.Set(inSSaoTexture); + + qt3ds::render::SImage *theLightProbe = inLightProbe; + qt3ds::render::SImage *theLightProbe2 = inLightProbe2; + + // If the material has its own IBL Override, we should use that image instead. + if ((inMaterial.m_IblProbe) && (inMaterial.m_IblProbe->m_TextureData.m_Texture)) { + theLightProbe = inMaterial.m_IblProbe; + } + + if (theLightProbe) { + if (theLightProbe->m_TextureData.m_Texture) { + NVRenderTextureCoordOp::Enum theHorzLightProbeTilingMode = + theLightProbe->m_HorizontalTilingMode; + NVRenderTextureCoordOp::Enum theVertLightProbeTilingMode = + theLightProbe->m_VerticalTilingMode; + theLightProbe->m_TextureData.m_Texture->SetTextureWrapS( + theHorzLightProbeTilingMode); + theLightProbe->m_TextureData.m_Texture->SetTextureWrapT( + theVertLightProbeTilingMode); + const QT3DSMat44 &textureTransform = theLightProbe->m_TextureTransform; + // We separate rotational information from offset information so that just maybe the + // shader + // will attempt to push less information to the card. + const QT3DSF32 *dataPtr(textureTransform.front()); + // The third member of the offsets contains a flag indicating if the texture was + // premultiplied or not. + // We use this to mix the texture alpha. + QT3DSVec4 offsets(dataPtr[12], dataPtr[13], + theLightProbe->m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f + : 0.0f, + (float)theLightProbe->m_TextureData.m_Texture->GetNumMipmaps()); + + // Grab just the upper 2x2 rotation matrix from the larger matrix. + QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); + + shader.m_LightProbeRot.Set(rotations); + shader.m_LightProbeOfs.Set(offsets); + + if ((!inMaterial.m_IblProbe) && (inProbeFOV < 180.f)) { + shader.m_LightProbeOpts.Set( + QT3DSVec4(0.01745329251994329547f * inProbeFOV, 0.0f, 0.0f, 0.0f)); + } + + // Also make sure to add the secondary texture, but it should only be added if the + // primary + // (i.e. background) texture is also there. + if (theLightProbe2 && theLightProbe2->m_TextureData.m_Texture) { + theLightProbe2->m_TextureData.m_Texture->SetTextureWrapS( + theHorzLightProbeTilingMode); + theLightProbe2->m_TextureData.m_Texture->SetTextureWrapT( + theVertLightProbeTilingMode); + shader.m_LightProbe2.Set(theLightProbe2->m_TextureData.m_Texture); + shader.m_LightProbe2Props.Set( + QT3DSVec4(inProbe2Window, inProbe2Pos, inProbe2Fade, 1.0f)); + + const QT3DSMat44 &xform2 = theLightProbe2->m_TextureTransform; + const QT3DSF32 *dataPtr(xform2.front()); + shader.m_LightProbeProps.Set( + QT3DSVec4(dataPtr[12], dataPtr[13], inProbeHorizon, inProbeBright * 0.01f)); + } else { + shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + shader.m_LightProbeProps.Set( + QT3DSVec4(0.0f, 0.0f, inProbeHorizon, inProbeBright * 0.01f)); + } + NVRenderTexture2D *textureImage = theLightProbe->m_TextureData.m_Texture; + shader.m_LightProbe.Set(textureImage); + shader.m_LightProbeSize.Set(QT3DSVec2(textureImage->GetTextureDetails().m_Width, + textureImage->GetTextureDetails().m_Height)); + } else { + shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); + shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + } + } else { + shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); + shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); + } + + QT3DSF32 emissivePower = 1.0; + + QT3DSU32 hasLighting = inMaterial.m_Lighting != DefaultMaterialLighting::NoLighting; + if (hasLighting) + emissivePower = inMaterial.m_EmissivePower / 100.0f; + + QT3DSVec4 material_diffuse = QT3DSVec4(inMaterial.m_EmissiveColor[0] * emissivePower, + inMaterial.m_EmissiveColor[1] * emissivePower, + inMaterial.m_EmissiveColor[2] * emissivePower, inOpacity); + shader.m_MaterialDiffuse.Set(material_diffuse); + shader.m_DiffuseColor.Set(inMaterial.m_DiffuseColor); + QT3DSVec4 material_specular = + QT3DSVec4(inMaterial.m_SpecularTint[0], inMaterial.m_SpecularTint[1], + inMaterial.m_SpecularTint[2], inMaterial.m_IOR); + shader.m_MaterialSpecular.Set(material_specular); + shader.m_CameraProperties.Set(inCameraVec); + shader.m_FresnelPower.Set(inMaterial.m_FresnelPower); + + if (context.GetConstantBufferSupport()) { + NVRenderConstantBuffer *pLightCb = GetLightConstantBuffer(shader.m_Lights.size()); + // if we have lights we need a light buffer + QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightCb); + + for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); idx < end && pLightCb; ++idx) { + shader.m_Lights[idx].m_LightData.m_diffuse = + QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x, + shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y, + shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0); + + // this is our final change update memory + pLightCb->UpdateRaw(idx * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), + NVDataRef((QT3DSU8 *)&shader.m_Lights[idx].m_LightData, + sizeof(SLightSourceShader))); + } + // update light buffer to hardware + if (pLightCb) { + QT3DSI32 cgLights = shader.m_Lights.size(); + pLightCb->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); + shader.m_LightsBuffer.Set(); + } + } else { + SLightConstantProperties *pLightConstants + = GetLightConstantProperties(shader); + + // if we have lights we need a light buffer + QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightConstants); + + for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); + idx < end && pLightConstants; ++idx) { + shader.m_Lights[idx].m_LightData.m_diffuse = + QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x, + shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y, + shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0); + } + // update light buffer to hardware + if (pLightConstants) + pLightConstants->updateLights(shader); + } + + shader.m_MaterialDiffuseLightAmbientTotal.Set( + QT3DSVec3(shader.m_LightAmbientTotal.x * inMaterial.m_DiffuseColor[0], + shader.m_LightAmbientTotal.y * inMaterial.m_DiffuseColor[1], + shader.m_LightAmbientTotal.z * inMaterial.m_DiffuseColor[2])); + + shader.m_MaterialProperties.Set(QT3DSVec4( + inMaterial.m_SpecularAmount, inMaterial.m_SpecularRoughness, emissivePower, 0.0f)); + shader.m_BumpAmount.Set(inMaterial.m_BumpAmount); + shader.m_DisplaceAmount.Set(inMaterial.m_DisplaceAmount); + shader.m_TranslucentFalloff.Set(inMaterial.m_TranslucentFalloff); + shader.m_DiffuseLightWrap.Set(inMaterial.m_DiffuseLightWrap); + QT3DSU32 imageIdx = 0; + for (SRenderableImage *theImage = inFirstImage; theImage; + theImage = theImage->m_NextImage, ++imageIdx) + SetImageShaderVariables(shader, *theImage, imageIdx); + + qt3ds::render::NVRenderBlendFunctionArgument blendFunc; + qt3ds::render::NVRenderBlendEquationArgument blendEqua(NVRenderBlendEquation::Add, + NVRenderBlendEquation::Add); + // The blend function goes: + // src op + // dst op + // src alpha op + // dst alpha op + // All of our shaders produce non-premultiplied values. + switch (inMaterial.m_BlendMode) { + case DefaultMaterialBlendMode::Screen: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::One, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + break; + case DefaultMaterialBlendMode::Multiply: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::DstColor, NVRenderDstBlendFunc::Zero, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + break; + case DefaultMaterialBlendMode::Overlay: + // SW fallback is not using blend equation + // note blend func is not used here anymore + if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) + blendEqua = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Overlay, NVRenderBlendEquation::Overlay); + break; + case DefaultMaterialBlendMode::ColorBurn: + // SW fallback is not using blend equation + // note blend func is not used here anymore + if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) + blendEqua = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::ColorBurn, NVRenderBlendEquation::ColorBurn); + break; + case DefaultMaterialBlendMode::ColorDodge: + // SW fallback is not using blend equation + // note blend func is not used here anymore + if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) + blendEqua = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::ColorDodge, NVRenderBlendEquation::ColorDodge); + break; + default: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); + break; + } + context.SetBlendFunction(blendFunc); + context.SetBlendEquation(blendEqua); + } + void SetMaterialProperties(NVRenderShaderProgram &inProgram, + const SGraphObject &inMaterial, const QT3DSVec2 &inCameraVec, + const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, + const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + SLayerGlobalRenderProperties inRenderProperties) override + { + const SDefaultMaterial &theMaterial(static_cast(inMaterial)); + QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::DefaultMaterial); + + SetGlobalProperties(inProgram, inRenderProperties.m_Layer, inRenderProperties.m_Camera, + inRenderProperties.m_CameraDirection, inRenderProperties.m_Lights, + inRenderProperties.m_LightDirections, + inRenderProperties.m_ShadowMapManager); + SetMaterialProperties(inProgram, theMaterial, inCameraVec, inModelViewProjection, + inNormalMatrix, inGlobalTransform, inFirstImage, inOpacity, + inRenderProperties.m_DepthTexture, inRenderProperties.m_SSaoTexture, + inRenderProperties.m_LightProbe, inRenderProperties.m_LightProbe2, + inRenderProperties.m_ProbeHorizon, inRenderProperties.m_ProbeBright, + inRenderProperties.m_Probe2Window, inRenderProperties.m_Probe2Pos, + inRenderProperties.m_Probe2Fade, inRenderProperties.m_ProbeFOV); + } + + SLightConstantProperties *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader) + { + if (!shader.m_lightConstantProperties + || int(shader.m_Lights.size()) + > shader.m_lightConstantProperties->m_constants.size()) { + if (shader.m_lightConstantProperties) + delete shader.m_lightConstantProperties; + shader.m_lightConstantProperties + = new SLightConstantProperties( + shader, m_LightsAsSeparateUniforms); + } + return shader.m_lightConstantProperties; + } +}; +} + +IDefaultMaterialShaderGenerator & +IDefaultMaterialShaderGenerator::CreateDefaultMaterialShaderGenerator(IQt3DSRenderContext &inRc) +{ + return *QT3DS_NEW(inRc.GetAllocator(), SShaderGenerator)(inRc); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.h b/src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.h new file mode 100644 index 00000000..fc845b51 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DEFAULT_MATERIAL_SHADER_GENERATOR_H +#define QT3DS_RENDER_DEFAULT_MATERIAL_SHADER_GENERATOR_H +#include "Qt3DSRenderMaterialShaderGenerator.h" +#include "Qt3DSRenderLightConstantProperties.h" + +namespace qt3ds { +namespace render { + + class Qt3DSShadowMap; + struct SShaderGeneratorGeneratedShader; + + class IDefaultMaterialVertexPipeline : public IShaderStageGenerator + { + protected: + virtual ~IDefaultMaterialVertexPipeline() {} + public: + // Responsible for beginning all vertex and fragment generation (void main() { etc). + virtual void BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) = 0; + // The fragment shader expects a floating point constant, object_opacity to be defined + // post this method. + virtual void BeginFragmentGeneration() = 0; + // Output variables may be mangled in some circumstances so the shader generation system + // needs an abstraction + // mechanism around this. + virtual void AssignOutput(const char8_t *inVarName, const char8_t *inVarValueExpr) = 0; + + /** + * @brief Generates UV coordinates in shader code + * + * @param[in] inUVSet index of UV data set + * + * @return no return + */ + virtual void GenerateUVCoords(QT3DSU32 inUVSet = 0) = 0; + + virtual void GenerateEnvMapReflection() = 0; + virtual void GenerateViewVector() = 0; + + // fragment shader expects varying vertex normal + // lighting in vertex pipeline expects world_normal + virtual void GenerateWorldNormal() = 0; // world_normal in both vert and frag shader + virtual void GenerateObjectNormal() = 0; // object_normal in both vert and frag shader + virtual void + GenerateWorldPosition() = 0; // model_world_position in both vert and frag shader + virtual void GenerateVarTangentAndBinormal() = 0; + virtual void GenerateVertexColor() = 0; + + virtual bool HasActiveWireframe() = 0; // varEdgeDistance is a valid entity + + // responsible for closing all vertex and fragment generation + virtual void EndVertexGeneration() = 0; + virtual void EndFragmentGeneration() = 0; + }; + + class IDefaultMaterialShaderGenerator : public IMaterialShaderGenerator + { + public: + virtual void AddDisplacementImageUniforms(IShaderStageGenerator &inGenerator, + QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) = 0; + SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override = 0; + void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, + QT3DSU32 uvSet, SRenderableImage &image) override = 0; + // Transforms attr_pos, attr_norm, and attr_uv0. + virtual void AddDisplacementMappingForDepthPass(IShaderStageGenerator &inShader) = 0; + + // inPipelineName needs to be unique else the shader cache will just return shaders from + // different pipelines. + NVRenderShaderProgram *GenerateShader( + const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, + IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, + NVDataRef inLights, SRenderableImage *inFirstImage, bool inHasTransparency, + const char8_t *inVertexPipelineName, const char8_t *inCustomMaterialName = "") override = 0; + + // Also sets the blend function on the render context. + virtual void + SetMaterialProperties(NVRenderShaderProgram &inProgram, const SGraphObject &inMaterial, + const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + SLayerGlobalRenderProperties inRenderProperties) override = 0; + + static IDefaultMaterialShaderGenerator & + CreateDefaultMaterialShaderGenerator(IQt3DSRenderContext &inRenderContext); + + SLightConstantProperties + *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.cpp new file mode 100644 index 00000000..00de6c3d --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.cpp @@ -0,0 +1,1531 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderContextCore.h" +#include "render/Qt3DSRenderShaderConstant.h" +#include "Qt3DSRenderDynamicObject.h" +#include "foundation/SerializationTypes.h" +#include "foundation/FileTools.h" +#include "foundation/PreAllocatedAllocator.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderString.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderDynamicObjectSystemCommands.h" +#include "Qt3DSRenderDynamicObjectSystemUtil.h" +#include "Qt3DSRenderShaderCodeGenerator.h" +#include "foundation/Qt3DSMutex.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace qt3ds::render::dynamic; + +namespace { +typedef eastl::pair TStrStrPair; +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const TStrStrPair &item) const + { + return hash()(item.first) ^ hash()(item.second); + } +}; +} + +namespace qt3ds { +namespace render { + namespace dynamic { + + QT3DSU32 SCommand::GetSizeofCommand(const SCommand &inCommand) + { + switch (inCommand.m_Type) { + case CommandTypes::AllocateBuffer: + return sizeof(SAllocateBuffer); + case CommandTypes::BindBuffer: + return sizeof(SBindBuffer); + case CommandTypes::BindTarget: + return sizeof(SBindTarget); + case CommandTypes::BindShader: + return sizeof(SBindShader); + case CommandTypes::Render: + return sizeof(SRender); + case CommandTypes::ApplyBufferValue: + return sizeof(SApplyBufferValue); + case CommandTypes::ApplyDepthValue: + return sizeof(SApplyDepthValue); + case CommandTypes::ApplyInstanceValue: + return sizeof(SApplyInstanceValue); + case CommandTypes::ApplyBlending: + return sizeof(SApplyBlending); + case CommandTypes::ApplyRenderState: + return sizeof(SApplyRenderState); + case CommandTypes::ApplyBlitFramebuffer: + return sizeof(SApplyBlitFramebuffer); + case CommandTypes::ApplyValue: + return sizeof(SApplyValue) + + static_cast(inCommand).m_Value.mSize; + case CommandTypes::DepthStencil: + return sizeof(SDepthStencil); + case CommandTypes::AllocateImage: + return sizeof(SAllocateImage); + case CommandTypes::ApplyImageValue: + return sizeof(SApplyImageValue); + case CommandTypes::AllocateDataBuffer: + return sizeof(SAllocateDataBuffer); + case CommandTypes::ApplyDataBufferValue: + return sizeof(SApplyDataBufferValue); + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + template + inline void CopyConstructCommandT(QT3DSU8 *inDataBuffer, const SCommand &inCommand, + IStringTable &inStrTable) + { + TCommandType *theCommand = (TCommandType *)inDataBuffer; + theCommand = new (theCommand) + TCommandType(static_cast(inCommand), inStrTable); + } + + void SCommand::CopyConstructCommand(QT3DSU8 *inDataBuffer, const SCommand &inCommand, + IStringTable &inStrTable) + { + switch (inCommand.m_Type) { + case CommandTypes::AllocateBuffer: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::BindBuffer: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::BindTarget: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::BindShader: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::Render: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyBufferValue: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyDepthValue: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyInstanceValue: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyBlending: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyRenderState: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyBlitFramebuffer: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyValue: { + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + SApplyValue &dest = *reinterpret_cast(inDataBuffer); + QT3DSU8 *destMem = inDataBuffer + sizeof(SApplyValue); + const SApplyValue &src = static_cast(inCommand); + memcpy(destMem, src.m_Value.mData, src.m_Value.mSize); + dest.m_Value.mData = destMem; + break; + } + case CommandTypes::DepthStencil: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::AllocateImage: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyImageValue: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::AllocateDataBuffer: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + case CommandTypes::ApplyDataBufferValue: + CopyConstructCommandT(inDataBuffer, inCommand, inStrTable); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + } +} +} + +namespace { + +template +struct SCommandRemapping +{ + template + static void RemapCommandData(TCommandType &, TRemapper &) + { + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SAllocateBuffer &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_Name); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SAllocateImage &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_Name); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SAllocateDataBuffer &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_Name); + if (cmd.m_WrapName) + remapper.Remap(cmd.m_WrapName); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SBindBuffer &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_BufferName); + } +}; +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SBindShader &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_ShaderPath); + remapper.Remap(cmd.m_ShaderDefine); + } +}; +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SApplyInstanceValue &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_PropertyName); + } +}; +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SApplyBufferValue &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_BufferName); + remapper.Remap(cmd.m_ParamName); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SApplyDepthValue &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_ParamName); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SApplyBlitFramebuffer &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_SourceBufferName); + remapper.Remap(cmd.m_DestBufferName); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SApplyValue &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_PropertyName); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SApplyDataBufferValue &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_ParamName); + } +}; + +template <> +struct SCommandRemapping +{ + template + static void RemapCommandData(SDepthStencil &cmd, TRemapper &remapper) + { + remapper.Remap(cmd.m_BufferName); + } +}; + +QT3DSU32 Align(QT3DSU32 inValue) +{ + if (inValue % 4) + return inValue + (4 - (inValue % 4)); + return inValue; +} + +QT3DSU32 Align8(QT3DSU32 inValue) +{ + if (inValue % 8) + return inValue + (8 - (inValue % 8)); + return inValue; +} + +inline const char *GetShaderDatatypeName(NVRenderShaderDataTypes::Enum inValue) +{ + switch (inValue) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ + case NVRenderShaderDataTypes::type: \ + return #type; + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return ""; +} + +inline qt3ds::QT3DSU32 getSizeofShaderDataType(NVRenderShaderDataTypes::Enum value) +{ + using namespace qt3ds; + using namespace qt3ds::render; + switch (value) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(x) \ + case NVRenderShaderDataTypes::x: \ + return sizeof(x); + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; +} + +struct SDynamicObjectShaderInfo +{ + CRegisteredString m_Type; ///< shader type (GLSL or HLSL) + CRegisteredString m_Version; ///< shader version (e.g. 330 vor GLSL) + bool m_HasGeomShader; + bool m_IsComputeShader; + + SDynamicObjectShaderInfo() + : m_HasGeomShader(false) + , m_IsComputeShader(false) + { + } + SDynamicObjectShaderInfo(CRegisteredString inType, CRegisteredString inVersion, + bool inHasGeomShader, bool inIsComputeShader) + : m_Type(inType) + , m_Version(inVersion) + , m_HasGeomShader(inHasGeomShader) + , m_IsComputeShader(inIsComputeShader) + { + } +}; + +struct SDynamicObjClassImpl : public IDynamicObjectClass +{ + NVAllocatorCallback *m_Allocator; + CRegisteredString m_Id; + NVConstDataRef m_PropertyDefinitions; + QT3DSU32 m_PropertySectionByteSize; + QT3DSU32 m_BaseObjectSize; + GraphObjectTypes::Enum m_GraphObjectType; + QT3DSU8 *m_PropertyDefaultData; + NVConstDataRef m_RenderCommands; + volatile QT3DSI32 mRefCount; + bool m_RequiresDepthTexture; + bool m_RequiresCompilation; + NVRenderTextureFormats::Enum m_OutputFormat; + + SDynamicObjClassImpl( + NVAllocatorCallback &alloc, CRegisteredString id, + NVConstDataRef definitions, QT3DSU32 propertySectionByteSize, + QT3DSU32 baseObjectSize, GraphObjectTypes::Enum objectType, QT3DSU8 *propDefaultData, + bool inRequiresDepthTexture = false, + NVRenderTextureFormats::Enum inOutputFormat = NVRenderTextureFormats::RGBA8) + : m_Allocator(&alloc) + , m_Id(id) + , m_PropertyDefinitions(definitions) + , m_PropertySectionByteSize(propertySectionByteSize) + , m_BaseObjectSize(baseObjectSize) + , m_GraphObjectType(objectType) + , m_PropertyDefaultData(propDefaultData) + , mRefCount(0) + , m_RequiresDepthTexture(inRequiresDepthTexture) + , m_RequiresCompilation(false) + , m_OutputFormat(inOutputFormat) + { + } + + ~SDynamicObjClassImpl() + { + if (m_PropertyDefinitions.size()) { + for (QT3DSU32 idx = 0, end = m_PropertyDefinitions.size(); idx < end; ++idx) { + if (m_PropertyDefinitions[idx].m_EnumValueNames.size()) + m_Allocator->deallocate( + (void *)m_PropertyDefinitions[idx].m_EnumValueNames.begin()); + } + } + ReleaseCommands(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator) + + template + static void RemapCommand(SCommand &inCommand, TRemapperType &inRemapper) + { + switch (inCommand.m_Type) { +#define QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(type) \ + case CommandTypes::type: \ + SCommandRemapping::RemapCommandData(static_cast(inCommand), \ + inRemapper); \ + break; + QT3DS_RENDER_EFFECTS_ITERATE_COMMAND_TYPES +#undef QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES + default: + QT3DS_ASSERT(false); + break; + } + } + template + void SetupThisObjectFromMemory(NVAllocatorCallback &inAlloc, TRemapper &inRemapper, + QT3DSU8 *inCommandStart, QT3DSU32 numEffectCommands) + { + m_Allocator = &inAlloc; + mRefCount = 0; + QT3DSU8 *theCommandPtrBegin = inCommandStart; + QT3DSU32 theCommandOffset = 0; + for (QT3DSU32 idx = 0; idx < numEffectCommands; ++idx) { + SCommand *theCommand = reinterpret_cast(inCommandStart + theCommandOffset); + theCommandOffset += SCommand::GetSizeofCommand(*theCommand); + } + SCommand **theCommandPtrStart = + reinterpret_cast(theCommandPtrBegin + theCommandOffset); + m_RenderCommands = NVConstDataRef(theCommandPtrStart, numEffectCommands); + // Now run through the commands, fixup strings and setup the command ptrs + theCommandOffset = 0; + for (QT3DSU32 idx = 0; idx < numEffectCommands; ++idx) { + SCommand *theCommand = + reinterpret_cast(theCommandPtrBegin + theCommandOffset); + theCommandPtrStart[idx] = theCommand; + RemapCommand(*theCommand, inRemapper); + theCommandOffset += SCommand::GetSizeofCommand(*theCommand); + } + } + + void ReleaseCommands() + { + if (m_RenderCommands.size()) { + m_Allocator->deallocate(const_cast(*m_RenderCommands.begin())); + m_RenderCommands = NVConstDataRef(); + } + } + + CRegisteredString GetId() const override { return m_Id; } + NVConstDataRef GetProperties() const override + { + return m_PropertyDefinitions; + } + QT3DSU32 GetPropertySectionByteSize() const override { return m_PropertySectionByteSize; } + const QT3DSU8 *GetDefaultValueBuffer() const override { return m_PropertyDefaultData; } + QT3DSU32 GetBaseObjectSize() const override { return m_BaseObjectSize; } + GraphObjectTypes::Enum GraphObjectType() const override { return m_GraphObjectType; } + const SPropertyDefinition *FindDefinition(CRegisteredString &str) const + { + for (QT3DSU32 idx = 0, end = m_PropertyDefinitions.size(); idx < end; ++idx) { + const SPropertyDefinition &def(m_PropertyDefinitions[idx]); + if (def.m_Name == str) + return &def; + } + return NULL; + } + const SPropertyDefinition *FindPropertyByName(CRegisteredString inName) const override + { + return FindDefinition(inName); + } + NVConstDataRef GetRenderCommands() const override + { + return m_RenderCommands; + } + bool RequiresDepthTexture() const override { return m_RequiresDepthTexture; } + void SetRequiresDepthTexture(bool inVal) override { m_RequiresDepthTexture = inVal; } + virtual bool RequiresCompilation() const override { return m_RequiresCompilation; } + virtual void SetRequiresCompilation(bool inVal) override { m_RequiresCompilation = inVal; } + NVRenderTextureFormats::Enum GetOutputTextureFormat() const override { return m_OutputFormat; } +}; + +struct SDataRemapper +{ + template + void Remap(QT3DSU8 *inData, SPropertyDefinition &item, TRemapper &remapper) + { + switch (item.m_DataType) { + default: + break; // no remapping necessary + case NVRenderShaderDataTypes::NVRenderTexture2DPtr: + CRegisteredString *realData = reinterpret_cast(inData); + remapper.Remap(*realData); + break; + } + } +}; + +struct SShaderMapKey +{ + TStrStrPair m_Name; + eastl::vector m_Features; + TessModeValues::Enum m_TessMode; + bool m_WireframeMode; + size_t m_HashCode; + SShaderMapKey(TStrStrPair inName, TShaderFeatureSet inFeatures, TessModeValues::Enum inTessMode, + bool inWireframeMode) + : m_Name(inName) + , m_Features(inFeatures.begin(), inFeatures.end()) + , m_TessMode(inTessMode) + , m_WireframeMode(inWireframeMode) + { + m_HashCode = eastl::hash()(m_Name) + ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size())) + ^ eastl::hash()(m_TessMode) ^ eastl::hash()(m_WireframeMode); + } + bool operator==(const SShaderMapKey &inKey) const + { + return m_Name == inKey.m_Name && m_Features == inKey.m_Features + && m_TessMode == inKey.m_TessMode && m_WireframeMode == inKey.m_WireframeMode; + } +}; +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SShaderMapKey &inKey) const { return inKey.m_HashCode; } +}; +} + +namespace { + +typedef nvhash_map> TStringClassMap; +typedef nvhash_map TPathDataMap; +typedef nvhash_map TShaderInfoMap; +typedef nvhash_set TPathSet; +typedef nvhash_map TShaderMap; + +struct SDynamicObjectSystemCoreImpl : public IDynamicObjectSystem +{ +}; + +struct SDynamicObjectSystemImpl : public IDynamicObjectSystem +{ + NVFoundationBase &m_Foundation; + mutable qt3ds::render::SPreAllocatedAllocator m_Allocator; + IQt3DSRenderContextCore &m_CoreContext; + IQt3DSRenderContext *m_Context; + TStringClassMap m_Classes; + TPathDataMap m_ExpandedFiles; + CRenderString m_ShaderKeyBuilder; + TShaderMap m_ShaderMap; + TShaderInfoMap m_ShaderInfoMap; + CRenderString m_IncludePath; + CRenderString m_IncludeSearch; + CRenderString m_VertShader; + CRenderString m_FragShader; + CRenderString m_GeometryShader; + QString m_shaderLibraryVersion; + QString m_shaderLibraryPlatformDirectory; + mutable Mutex m_PropertyLoadMutex; + QT3DSI32 mRefCount; + + SDynamicObjectSystemImpl(IQt3DSRenderContextCore &inCore) + : m_Foundation(inCore.GetFoundation()) + , m_Allocator(inCore.GetAllocator()) + , m_CoreContext(inCore) + , m_Context(NULL) + , m_Classes(inCore.GetAllocator(), "Classes") + , m_ExpandedFiles(inCore.GetAllocator(), "ExpandedShaderFiles") + , m_ShaderMap(inCore.GetAllocator(), "ShaderMap") + , m_ShaderInfoMap(inCore.GetAllocator(), "ShaderInfoMap") + , m_PropertyLoadMutex(inCore.GetAllocator()) + , mRefCount(0) + { + m_IncludeSearch = "#include \""; + } + + virtual ~SDynamicObjectSystemImpl() + { + for (TPathDataMap::iterator iter = m_ExpandedFiles.begin(), end = m_ExpandedFiles.end(); + iter != end; ++iter) + m_Allocator.deallocate(iter->second); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + bool IsRegistered(CRegisteredString inStr) override + { + return m_Classes.find(inStr) != m_Classes.end(); + } + + bool Register(CRegisteredString inName, + NVConstDataRef inProperties, QT3DSU32 inBaseObjectSize, + GraphObjectTypes::Enum inGraphObjectType) override + { + if (IsRegistered(inName)) { + QT3DS_ASSERT(false); + return false; + } + nvvector definitions(m_Foundation.getAllocator(), + "PropertyDefinitions"); + QT3DSU32 theCurrentOffset = 0; + for (QT3DSU32 idx = 0, end = inProperties.size(); idx < end; ++idx) { + const SPropertyDeclaration &thePropDec = inProperties[idx]; + CRegisteredString thePropName( + m_CoreContext.GetStringTable().RegisterStr(thePropDec.m_Name)); + QT3DSU32 propSize = getSizeofShaderDataType(thePropDec.m_DataType); + definitions.push_back(SPropertyDefinition(thePropName, thePropDec.m_DataType, + theCurrentOffset, propSize)); + theCurrentOffset += propSize; + theCurrentOffset = Align(theCurrentOffset); + } + QT3DSU32 dataSectionSize = theCurrentOffset; + QT3DSU32 clsSize = Align(sizeof(SDynamicObjClassImpl)); + QT3DSU32 defSize = Align(sizeof(SPropertyDefinition) * inProperties.size()); + QT3DSU32 defaultSize = dataSectionSize; + QT3DSU32 allocSize = clsSize + defSize + defaultSize; + QT3DSU8 *allocData = reinterpret_cast( + m_Allocator.allocate(allocSize, "SDynamicObjClassImpl", __FILE__, __LINE__)); + QT3DSU8 *defData = allocData + clsSize; + QT3DSU8 *defaultData = defData + defSize; + SPropertyDefinition *defPtr = reinterpret_cast(defData); + if (defSize) + memCopy(defPtr, definitions.data(), defSize); + if (defaultSize) + memZero(defaultData, defaultSize); + SDynamicObjClassImpl *theClass = new (allocData) + SDynamicObjClassImpl(m_Allocator, inName, toDataRef(defPtr, inProperties.size()), + dataSectionSize, inBaseObjectSize, inGraphObjectType, defaultData); + m_Classes.insert(eastl::make_pair(inName, theClass)); + return true; + } + + bool Unregister(CRegisteredString inName) override { + if (!IsRegistered(inName)) { + QT3DS_ASSERT(false); + return false; + } + TStringClassMap::iterator iter = m_Classes.find(inName); + if (iter != m_Classes.end()) + m_Classes.erase(iter); + return true; + } + + SDynamicObjClassImpl *FindClass(CRegisteredString inName) + { + TStringClassMap::iterator iter = m_Classes.find(inName); + if (iter != m_Classes.end()) + return iter->second.mPtr; + return NULL; + } + + eastl::pair + FindProperty(CRegisteredString inName, CRegisteredString inPropName) + { + SDynamicObjClassImpl *cls = FindClass(inName); + if (cls) { + const SPropertyDefinition *def = cls->FindDefinition(inPropName); + if (def) + return eastl::make_pair(def, cls); + } + return eastl::pair(NULL, NULL); + } + + void SetPropertyDefaultValue(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inDefaultData) override + { + eastl::pair def = + FindProperty(inName, inPropName); + if (def.first && inDefaultData.size() >= def.first->m_ByteSize) { + memCopy(def.second->m_PropertyDefaultData + def.first->m_Offset, inDefaultData.begin(), + def.first->m_ByteSize); + } else { + QT3DS_ASSERT(false); + } + } + + void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inNames) override + { + + eastl::pair def = + FindProperty(inName, inPropName); + SPropertyDefinition *theDefinitionPtr = const_cast(def.first); + if (theDefinitionPtr == NULL) { + QT3DS_ASSERT(false); + return; + } + if (theDefinitionPtr->m_EnumValueNames.size()) { + m_Foundation.getAllocator().deallocate( + (void *)theDefinitionPtr->m_EnumValueNames.begin()); + theDefinitionPtr->m_EnumValueNames = NVConstDataRef(); + } + theDefinitionPtr->m_IsEnumProperty = true; + if (inNames.size()) { + CRegisteredString *theNameValues = (CRegisteredString *)m_Allocator.allocate( + inNames.size() * sizeof(CRegisteredString), "PropertyEnumNames", __FILE__, + __LINE__); + + memCopy(theNameValues, inNames.begin(), inNames.size() * sizeof(CRegisteredString)); + theDefinitionPtr->m_EnumValueNames = + NVConstDataRef(theNameValues, inNames.size()); + } + } + + virtual NVConstDataRef + GetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName) const override + { + eastl::pair def = + const_cast(*this).FindProperty(inName, inPropName); + if (def.first) + return def.first->m_EnumValueNames; + return NVConstDataRef(); + } + + // Called during loading which is pretty heavily multithreaded. + virtual NVConstDataRef + GetProperties(CRegisteredString inName) const override + { + Mutex::ScopedLock __locker(m_PropertyLoadMutex); + SDynamicObjClassImpl *cls = const_cast(*this).FindClass(inName); + if (cls) + return cls->m_PropertyDefinitions; + return NVConstDataRef(); + } + + void SetPropertyTextureSettings(CRegisteredString inName, CRegisteredString inPropName, + CRegisteredString inPropPath, + NVRenderTextureTypeValue::Enum inTexType, + NVRenderTextureCoordOp::Enum inCoordOp, + NVRenderTextureMagnifyingOp::Enum inMagFilterOp, + NVRenderTextureMinifyingOp::Enum inMinFilterOp) override + { + eastl::pair def = + FindProperty(inName, inPropName); + SPropertyDefinition *theDefinitionPtr = const_cast(def.first); + if (theDefinitionPtr == NULL) { + QT3DS_ASSERT(false); + return; + } + theDefinitionPtr->m_ImagePath = inPropPath; + theDefinitionPtr->m_TexUsageType = inTexType; + theDefinitionPtr->m_CoordOp = inCoordOp; + theDefinitionPtr->m_MagFilterOp = inMagFilterOp; + theDefinitionPtr->m_MinFilterOp = inMinFilterOp; + } + + IDynamicObjectClass *GetDynamicObjectClass(CRegisteredString inName) override + { + return FindClass(inName); + } + + void SetRenderCommands(CRegisteredString inClassName, + NVConstDataRef inCommands) override + { + SDynamicObjClassImpl *theClass = + const_cast(*this).FindClass(inClassName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + theClass->ReleaseCommands(); + QT3DSU32 commandAllocationSize = 0; + for (QT3DSU32 idx = 0, end = inCommands.size(); idx < end; ++idx) { + QT3DSU32 commandSize = Align(SCommand::GetSizeofCommand(*inCommands[idx])); + commandAllocationSize += commandSize; + } + QT3DSU32 commandPtrSize = inCommands.size() * sizeof(SCommand *); + QT3DSU32 totalAllocationSize = Align8(commandAllocationSize) + commandPtrSize; + QT3DSU8 *theCommandDataBegin = (QT3DSU8 *)m_Allocator.allocate( + totalAllocationSize, "dynamic::SCommand", __FILE__, __LINE__); + QT3DSU8 *theCurrentCommandData(theCommandDataBegin); + SCommand **theCommandPtrBegin = + reinterpret_cast(theCommandDataBegin + Align8(commandAllocationSize)); + SCommand **theCurrentCommandPtr = theCommandPtrBegin; + memZero(theCommandDataBegin, totalAllocationSize); + + theClass->m_RequiresDepthTexture = false; + for (QT3DSU32 idx = 0, end = inCommands.size(); idx < end; ++idx) { + SCommand &theCommand(*inCommands[idx]); + QT3DSU32 theCommandSize = SCommand::GetSizeofCommand(theCommand); + SCommand::CopyConstructCommand(theCurrentCommandData, theCommand, + m_CoreContext.GetStringTable()); + if (theCommand.m_Type == CommandTypes::ApplyDepthValue) + theClass->m_RequiresDepthTexture = true; + if (theCommand.m_Type == CommandTypes::BindTarget) { + SBindTarget *bt = reinterpret_cast(&theCommand); + theClass->m_OutputFormat = bt->m_OutputFormat; + } + + *theCurrentCommandPtr = reinterpret_cast(theCurrentCommandData); + ++theCurrentCommandPtr; + theCurrentCommandData += Align(theCommandSize); + } + QT3DS_ASSERT(theCurrentCommandData - theCommandDataBegin == (int)commandAllocationSize); + QT3DS_ASSERT((QT3DSU8 *)theCurrentCommandPtr - theCommandDataBegin == (int)totalAllocationSize); + theClass->m_RenderCommands = + NVConstDataRef(theCommandPtrBegin, inCommands.size()); + } + + virtual NVConstDataRef + GetRenderCommands(CRegisteredString inClassName) const override + { + SDynamicObjClassImpl *cls = + const_cast(*this).FindClass(inClassName); + if (cls) + return cls->m_RenderCommands; + return NVConstDataRef(); + } + + SDynamicObject *CreateInstance(CRegisteredString inClassName, + NVAllocatorCallback &inSceneGraphAllocator) override + { + SDynamicObjClassImpl *theClass = FindClass(inClassName); + if (!theClass) { + QT3DS_ASSERT(false); + return NULL; + } + QT3DSU32 totalObjectSize = theClass->m_BaseObjectSize + theClass->m_PropertySectionByteSize; + SDynamicObject *retval = reinterpret_cast(inSceneGraphAllocator.allocate( + totalObjectSize, inClassName.c_str(), __FILE__, __LINE__)); + new (retval) + SDynamicObject(theClass->m_GraphObjectType, inClassName, + theClass->m_PropertySectionByteSize, theClass->m_BaseObjectSize); + memCopy(retval->GetDataSectionBegin(), theClass->m_PropertyDefaultData, + theClass->m_PropertySectionByteSize); + return retval; + } + + void SetShaderData(CRegisteredString inPath, const char8_t *inData, + const char8_t *inShaderType, const char8_t *inShaderVersion, + bool inHasGeomShader, bool inIsComputeShader) override + { + inData = inData ? inData : ""; + eastl::pair theInserter = + m_ExpandedFiles.insert(eastl::make_pair(inPath, (char8_t *)"")); + if (theInserter.second == false) { + // Delete the existing entry. + m_Allocator.deallocate(theInserter.first->second); + } + QT3DSU32 theLen = (QT3DSU32)strlen(inData) + 1; + char8_t *newData = (char8_t *)m_Allocator.allocate( + theLen, "SDynamicObjectSystem::SetShaderData", __FILE__, __LINE__); + memCopy(newData, inData, theLen); + theInserter.first->second = newData; + + // set shader type and version if available + if (inShaderType || inShaderVersion || inHasGeomShader || inIsComputeShader) { + // UdoL TODO: Add this to the load / save setction + // In addition we should merge the source code into SDynamicObjectShaderInfo as well + SDynamicObjectShaderInfo &theShaderInfo = + m_ShaderInfoMap.insert(eastl::make_pair(inPath, SDynamicObjectShaderInfo())) + .first->second; + IStringTable &theStringTable(m_CoreContext.GetStringTable()); + theShaderInfo.m_Type = theStringTable.RegisterStr(nonNull(inShaderType)); + theShaderInfo.m_Version = theStringTable.RegisterStr(nonNull(inShaderVersion)); + theShaderInfo.m_HasGeomShader = inHasGeomShader; + theShaderInfo.m_IsComputeShader = inIsComputeShader; + } + + return; + } + + CRegisteredString GetShaderCacheKey(const char8_t *inId, const char8_t *inProgramMacro, + const dynamic::SDynamicShaderProgramFlags &inFlags) + { + m_ShaderKeyBuilder.assign(inId); + if (inProgramMacro && *inProgramMacro) { + m_ShaderKeyBuilder.append("#"); + m_ShaderKeyBuilder.append(inProgramMacro); + } + if (inFlags.IsTessellationEnabled()) { + m_ShaderKeyBuilder.append("#"); + m_ShaderKeyBuilder.append(TessModeValues::toString(inFlags.m_TessMode)); + } + if (inFlags.IsGeometryShaderEnabled() && inFlags.m_WireframeMode) { + m_ShaderKeyBuilder.append("#"); + m_ShaderKeyBuilder.append(inFlags.wireframeToString(inFlags.m_WireframeMode)); + } + + return m_CoreContext.GetStringTable().RegisterStr(m_ShaderKeyBuilder.c_str()); + } + + void InsertShaderHeaderInformation(CRenderString &theReadBuffer, + const char8_t *inPathToEffect) override + { + DoInsertShaderHeaderInformation(theReadBuffer, inPathToEffect); + } + + void DoInsertShaderHeaderInformation(CRenderString &theReadBuffer, + const char8_t *inPathToEffect) + { + // Now do search and replace for the headers + for (CRenderString::size_type thePos = theReadBuffer.find(m_IncludeSearch); + thePos != CRenderString::npos; + thePos = theReadBuffer.find(m_IncludeSearch, thePos + 1)) { + CRenderString::size_type theEndQuote = + theReadBuffer.find('\"', thePos + m_IncludeSearch.size() + 1); + // Indicates an unterminated include file. + if (theEndQuote == CRenderString::npos) { + qCCritical(INVALID_OPERATION, "Unterminated include in file: %s", inPathToEffect); + theReadBuffer.clear(); + break; + } + CRenderString::size_type theActualBegin = thePos + m_IncludeSearch.size(); + CRenderString::iterator theIncludeBegin = theReadBuffer.begin() + theActualBegin; + CRenderString::iterator theIncludeEnd = theReadBuffer.begin() + theEndQuote; + m_IncludePath.clear(); + m_IncludePath.append(theIncludeBegin, theIncludeEnd); + // If we haven't included the file yet this round + CRenderString theIncludeBuffer; + const char8_t *theHeader = DoLoadShader(m_IncludePath.c_str(), theIncludeBuffer); + QT3DSU32 theLen = (QT3DSU32)strlen(theHeader); + theReadBuffer = + theReadBuffer.replace(theReadBuffer.begin() + thePos, + theReadBuffer.begin() + theEndQuote + 1, theHeader, theLen); + } + } + + const char8_t *DoLoadShader(const char8_t *inPathToEffect, CRenderString &outShaderData) + { + eastl::pair theInsert = + m_ExpandedFiles.insert(eastl::make_pair( + m_CoreContext.GetStringTable().RegisterStr(inPathToEffect), (char8_t *)"")); + + CRenderString &theReadBuffer(outShaderData); + if (theInsert.second) { + + const QString defaultDir = m_Context->GetDynamicObjectSystem() + .GetShaderCodeLibraryDirectory(); + const QString platformDir = m_Context->GetDynamicObjectSystem() + .shaderCodeLibraryPlatformDirectory(); + + QString fullPath; + NVScopedRefCounted theStream; + if (!platformDir.isEmpty()) { + QTextStream stream(&fullPath); + stream << platformDir << QLatin1Char('/') << inPathToEffect; + theStream = m_CoreContext.GetInputStreamFactory() + .GetStreamForFile(fullPath.toLatin1().data()); + } + + if (theStream.mPtr == NULL) { + fullPath.clear(); + QTextStream stream(&fullPath); + stream << defaultDir << QLatin1Char('/') << inPathToEffect; + theStream = m_CoreContext.GetInputStreamFactory() + .GetStreamForFile(fullPath.toLatin1().data()); + if (theStream.mPtr == NULL) { + fullPath.clear(); + QTextStream stream(&fullPath); + stream << defaultDir << QLatin1Char('/') << inPathToEffect; + theStream = m_CoreContext.GetInputStreamFactory() + .GetStreamForFile(fullPath.toLatin1().data()); + } + } + if (theStream.mPtr != NULL) { + QT3DSU8 readBuf[1024]; + QT3DSU32 amountRead = 0; + do { + amountRead = theStream->Read(NVDataRef(readBuf, 1024)); + if (amountRead) + theReadBuffer.append((const char8_t *)readBuf, amountRead); + } while (amountRead); + } else { + qCCritical(INVALID_OPERATION, "Failed to find include file %s", inPathToEffect); + QT3DS_ASSERT(false); + } + theInsert.first->second = (char8_t *)m_Allocator.allocate( + theReadBuffer.size() + 1, "SDynamicObjectSystem::DoLoadShader", __FILE__, __LINE__); + memCopy(theInsert.first->second, theReadBuffer.c_str(), + QT3DSU32(theReadBuffer.size()) + 1); + } else + theReadBuffer.assign(theInsert.first->second); + DoInsertShaderHeaderInformation(theReadBuffer, inPathToEffect); + return theReadBuffer.c_str(); + } + + void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, const char8_t *inProjectDir) const override + { + QT3DSU32 startOffset = ioBuffer.size(); + ioBuffer.write((QT3DSU32)m_ExpandedFiles.size()); + for (TPathDataMap::const_iterator theIter = m_ExpandedFiles.begin(); + theIter != m_ExpandedFiles.end(); ++theIter) { + CRegisteredString thePath(theIter->first); + char8_t *theData = theIter->second; + theData = theData ? theData : (char8_t *)""; + QT3DSU32 theLen = (QT3DSU32)strlen(theData); + thePath.Remap(inRemapMap); + ioBuffer.write(thePath); + ioBuffer.write(theLen + 1); + ioBuffer.write(theData, theLen + 1); + ioBuffer.align(sizeof(void *)); + } + ioBuffer.write((QT3DSU32)m_Classes.size()); + SStringSaveRemapper theRemapper(m_Allocator, inRemapMap, inProjectDir, + m_CoreContext.GetStringTable()); + for (TStringClassMap::const_iterator iter = m_Classes.begin(), end = m_Classes.end(); + iter != end; ++iter) { + const SDynamicObjClassImpl *theClass = iter->second; + ioBuffer.align(4); + QT3DSU32 objOffset = ioBuffer.size(); + QT3DSU32 classOffset = objOffset - startOffset; + (void)classOffset; + QT3DSU32 defOffset = objOffset + sizeof(SDynamicObjClassImpl); + QT3DSU32 dataOffset = + defOffset + theClass->m_PropertyDefinitions.size() * sizeof(SPropertyDefinition); + QT3DSU32 dataEnd = dataOffset + theClass->m_PropertySectionByteSize; + QT3DSU32 writeAmount = dataEnd - objOffset; + ioBuffer.write((const QT3DSU8 *)theClass, writeAmount); + ioBuffer.align(4); + QT3DSU32 cmdOffset = 0; + QT3DSU8 *writeCommandStart = NULL; + if (theClass->m_RenderCommands.size()) { + // We know commands are allocated in a block. + const SCommand &firstCommand = *theClass->m_RenderCommands[0]; + const QT3DSU8 *commandStart = reinterpret_cast(&firstCommand); + const SCommand &lastCommand( + *theClass->m_RenderCommands[theClass->m_RenderCommands.size() - 1]); + const QT3DSU8 *commandEnd = reinterpret_cast(&lastCommand) + + SCommand::GetSizeofCommand(lastCommand); + cmdOffset = ioBuffer.size(); + ioBuffer.write(commandStart, (QT3DSU32)(commandEnd - commandStart)); + // Write location of the actual storage for the command ptr array. + ioBuffer.writeZeros(theClass->m_RenderCommands.size() * sizeof(SCommand **)); + } + ioBuffer.align(4); + if (cmdOffset) + writeCommandStart = ioBuffer.begin() + cmdOffset; + + SDynamicObjClassImpl *writeClass = + (SDynamicObjClassImpl *)(ioBuffer.begin() + objOffset); + writeClass->m_Id.Remap(inRemapMap); + writeClass->SetupThisObjectFromMemory(m_Allocator, theRemapper, writeCommandStart, + theClass->m_RenderCommands.size()); + for (QT3DSU32 idx = 0, end = theClass->m_PropertyDefinitions.size(); idx < end; ++idx) { + // Moved into the loop because writing the enumerations may resize the data buffer. + SPropertyDefinition *theDefinitions = + (SPropertyDefinition *)(ioBuffer.begin() + defOffset); + theDefinitions[idx].m_Name.Remap(inRemapMap); + const SPropertyDefinition &theDefinition(theClass->m_PropertyDefinitions[idx]); + if (theDefinitions[idx].m_EnumValueNames.size()) { + QT3DSU32 enumOffset = ioBuffer.size(); + ioBuffer.write(theDefinition.m_EnumValueNames.begin(), + theDefinition.m_EnumValueNames.size() + * sizeof(CRegisteredString)); + CRegisteredString *strPtr = + (CRegisteredString *)(ioBuffer.begin() + enumOffset); + for (QT3DSU32 enumIdx = 0, enumEnd = theDefinition.m_EnumValueNames.size(); + enumIdx < enumEnd; ++enumIdx) + strPtr[enumIdx].Remap(inRemapMap); + } + if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + QT3DSU8 *theDataPtr = ioBuffer.begin() + dataOffset; + CRegisteredString *realData = + reinterpret_cast(theDataPtr + theDefinition.m_Offset); + realData->Remap(inRemapMap); + } + } + } + + // Write out meta information about the shader system + QT3DSU32 numShaderInfos = (QT3DSU32)m_ShaderInfoMap.size(); + ioBuffer.write(numShaderInfos); + for (TShaderInfoMap::const_iterator iter = m_ShaderInfoMap.begin(), + end = m_ShaderInfoMap.end(); + iter != end; ++iter) { + CRegisteredString infoName = iter->first; + infoName.Remap(inRemapMap); + ioBuffer.write(infoName); + const SDynamicObjectShaderInfo &theInfo = iter->second; + CRegisteredString infoType(theInfo.m_Type); + CRegisteredString infoVersion(theInfo.m_Version); + infoType.Remap(inRemapMap); + infoVersion.Remap(inRemapMap); + ioBuffer.write(infoType); + ioBuffer.write(infoVersion); + } + } + + void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t *inProjectDir) override + { + m_Allocator.m_PreAllocatedBlock = inData; + m_Allocator.m_OwnsMemory = false; + TStr workspaceStr(ForwardingAllocator(m_Foundation.getAllocator(), "ProjPath")); + qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); + QT3DSU32 numMappedPaths = theReader.LoadRef(); + for (QT3DSU32 idx = 0, end = numMappedPaths; idx < end; ++idx) { + CRegisteredString theStr(theReader.LoadRef()); + QT3DSU32 theCharLen = theReader.LoadRef(); + char8_t *thePathData = reinterpret_cast(theReader.m_CurrentPtr); + theReader.m_CurrentPtr += theCharLen; + theReader.Align(); + theStr.Remap(inStrDataBlock); + m_ExpandedFiles.insert(eastl::make_pair(theStr, thePathData)); + } + SStringLoadRemapper theRemapper(m_Allocator, inStrDataBlock, inProjectDir, + m_CoreContext.GetStringTable()); + QT3DSU32 numClasses = theReader.LoadRef(); + for (QT3DSU32 idx = 0, end = numClasses; idx < end; ++idx) { + theReader.Align(4); + size_t classOffset = static_cast(theReader.m_CurrentPtr - inData.mData); + (void)classOffset; + SDynamicObjClassImpl *theClass = (SDynamicObjClassImpl *)theReader.m_CurrentPtr; + theClass->m_Allocator = &m_Allocator; + theReader.m_CurrentPtr += sizeof(SDynamicObjClassImpl); + SPropertyDefinition *theDefinitions = (SPropertyDefinition *)theReader.m_CurrentPtr; + theReader.m_CurrentPtr += + theClass->m_PropertyDefinitions.size() * sizeof(SPropertyDefinition); + QT3DSU8 *theDataBuffer = theReader.m_CurrentPtr; + theReader.m_CurrentPtr += theClass->m_PropertySectionByteSize; + theClass->m_Id.Remap(inStrDataBlock); + theClass->m_PropertyDefinitions = NVConstDataRef( + theDefinitions, theClass->m_PropertyDefinitions.size()); + theClass->m_PropertyDefaultData = theDataBuffer; + theReader.Align(4); + QT3DSU8 *theCommandStart = theReader.m_CurrentPtr; + + QT3DSU32 numRenderCommands = theClass->m_RenderCommands.size(); + new (theClass) SDynamicObjClassImpl( + m_Allocator, theClass->m_Id, theClass->m_PropertyDefinitions, + theClass->m_PropertySectionByteSize, theClass->m_BaseObjectSize, + theClass->m_GraphObjectType, theClass->m_PropertyDefaultData, + theClass->m_RequiresDepthTexture, theClass->m_OutputFormat); + + theClass->SetupThisObjectFromMemory(m_Allocator, theRemapper, theCommandStart, + numRenderCommands); + + if (theClass->m_RenderCommands.size()) { + const SCommand &theLastCommand = + *theClass->m_RenderCommands[theClass->m_RenderCommands.size() - 1]; + const QT3DSU8 *theCommandEnd = reinterpret_cast(&theLastCommand) + + SCommand::GetSizeofCommand(theLastCommand); + theReader.m_CurrentPtr = const_cast(theCommandEnd); + theReader.m_CurrentPtr += theClass->m_RenderCommands.size() * sizeof(SCommand **); + } + theReader.Align(4); + + for (QT3DSU32 defIdx = 0, defEnd = theClass->m_PropertyDefinitions.size(); defIdx < defEnd; + ++defIdx) { + SPropertyDefinition &theDef(theDefinitions[defIdx]); + theDef.m_Name.Remap(inStrDataBlock); + if (theDef.m_EnumValueNames.size()) { + CRegisteredString *theNames = (CRegisteredString *)theReader.m_CurrentPtr; + theReader.m_CurrentPtr += + theDef.m_EnumValueNames.size() * sizeof(CRegisteredString); + theDef.m_EnumValueNames = + NVDataRef(theNames, theDef.m_EnumValueNames.size()); + for (QT3DSU32 enumIdx = 0, enumEnd = theDef.m_EnumValueNames.size(); + enumIdx < enumEnd; ++enumIdx) + theNames[enumIdx].Remap(inStrDataBlock); + } + if (theDef.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + CRegisteredString *realData = + reinterpret_cast(theDataBuffer + theDef.m_Offset); + realData->Remap(inStrDataBlock); + } + } + m_Classes.insert(eastl::make_pair(theClass->m_Id, theClass)); + } + QT3DSU32 theNumShaderInfos = theReader.LoadRef(); + for (QT3DSU32 idx = 0, end = theNumShaderInfos; idx < end; ++idx) { + CRegisteredString name, type, version; + name = theReader.LoadRef(); + type = theReader.LoadRef(); + version = theReader.LoadRef(); + name.Remap(inStrDataBlock); + type.Remap(inStrDataBlock); + version.Remap(inStrDataBlock); + SDynamicObjectShaderInfo &theInfo = + m_ShaderInfoMap.insert(eastl::make_pair(name, SDynamicObjectShaderInfo())) + .first->second; + theInfo.m_Type = type; + theInfo.m_Version = version; + } + } + + IDynamicObjectSystem &CreateDynamicSystem(IQt3DSRenderContext &rc) override + { + m_Context = &rc; + return *this; + } + + QStringList getParameters(const QString &str, int begin, int end) + { + const QString s = str.mid(begin, end - begin + 1); + return s.split(","); + } + + void insertSnapperDirectives(QString &str) + { + int beginIndex = 0; + // Snapper macros: + // #define SNAPPER_SAMPLER2D(propName, propNiceName, texFilter, texWrap, showUI ) \ + // uniform sampler2D propName; \ + // uniform int flag##propName; \ + // uniform vec4 propName##Info; \ + // vec4 texture2D_##propName(vec2 uv) \ + // { \ + // return GetTextureValue( propName, uv, propName##Info.z ); \ + // } + // + // #define SNAPPER_SAMPLER2DWITHDEFAULT(propName, propNiceName, texFilter, texWrap, defaultPath, showUI ) \ + // SNAPPER_SAMPLER2D( propName, propNiceName, texFilter, texWrap, showUI ) + // + // #define SNAPPER_SAMPLERCUBE(propName, propNiceName, texFilter, texWrap ) \ + // uniform samplerCube propName; \ + // uniform vec2 propName##UVRange; \ + // uniform int flag##propName; \ + // uniform vec2 propName##Size; + QString snapperSampler = QStringLiteral("SNAPPER_SAMPLER2D("); + QString snapperSamplerDefault = QStringLiteral("SNAPPER_SAMPLER2DWITHDEFAULT("); + QString snapperSamplerCube = QStringLiteral("SNAPPER_SAMPLERCUBE("); + QString endingBracket = QStringLiteral(")"); + + while ((beginIndex = str.indexOf(snapperSampler, beginIndex)) >= 0) { + int endIndex = str.indexOf(endingBracket, beginIndex); + const QStringList list = getParameters(str, beginIndex + snapperSampler.length(), + endIndex); + str.remove(beginIndex, endIndex - beginIndex + 1); + if (list.size() == 5) { + QString insertStr; + QTextStream stream(&insertStr); + stream << "uniform sampler2D " << list[0] << ";\n"; + stream << "uniform int flag" << list[0] << ";\n"; + stream << "vec4 " << list[0] << "Info;\n"; + stream << "vec4 texture2D_" << list[0] << "(vec2 uv) " + << "{ return GetTextureValue( " << list[0] << ", uv, " + << list[0] <<"Info.z ); }\n"; + str.insert(beginIndex, insertStr); + } + } + beginIndex = 0; + while ((beginIndex = str.indexOf(snapperSamplerDefault, beginIndex)) >= 0) { + int endIndex = str.indexOf(endingBracket, beginIndex); + const QStringList list = getParameters(str, beginIndex + snapperSamplerDefault.length(), + endIndex); + str.remove(beginIndex, endIndex - beginIndex + 1); + if (list.size() == 5) { + QString insertStr; + QTextStream stream(&insertStr); + stream << "uniform sampler2D " << list[0] << ";\n"; + stream << "uniform int flag" << list[0] << ";\n"; + stream << "vec4 " << list[0] << "Info;\n"; + stream << "vec4 texture2D_" << list[0] << "(vec2 uv) " + << "{ return GetTextureValue( " << list[0] << ", uv, " + << list[0] <<"Info.z ); }\n"; + str.insert(beginIndex, insertStr); + } + } + beginIndex = 0; + while ((beginIndex = str.indexOf(snapperSamplerCube, beginIndex)) >= 0) { + int endIndex = str.indexOf(endingBracket, beginIndex); + const QStringList list = getParameters(str, beginIndex + snapperSamplerCube.length(), + endIndex); + str.remove(beginIndex, endIndex - beginIndex + 1); + if (list.size() == 4) { + QString insertStr; + QTextStream stream(&insertStr); + stream << "uniform samplerCube " << list[0] << ";\n"; + stream << "uniform vec2 "<< list[0] << "UVRange;\n"; + stream << "uniform int flag" << list[0] << ";\n"; + stream << "uniform vec2 "<< list[0] << "Size;\n"; + str.insert(beginIndex, insertStr); + } + } + } + + NVRenderShaderProgram *CompileShader(CRegisteredString inId, const char8_t *inProgramSource, + const char8_t *inGeomSource, + CRegisteredString inProgramMacroName, + TShaderFeatureSet inFeatureSet, + const dynamic::SDynamicShaderProgramFlags &inFlags, + bool inForceCompilation = false) + { + m_VertShader.clear(); + m_FragShader.clear(); + m_GeometryShader.clear(); + SShaderCacheProgramFlags theFlags; + + m_VertShader.append("#define VERTEX_SHADER\n"); + m_FragShader.append("#define FRAGMENT_SHADER\n"); + + if (inProgramMacroName.IsValid()) { + m_VertShader.append("#define "); + m_VertShader.append(inProgramMacroName.c_str()); + m_VertShader.append("\n"); + + m_FragShader.append("#define "); + m_FragShader.append(inProgramMacroName.c_str()); + m_FragShader.append("\n"); + } + + if (inGeomSource && inFlags.IsGeometryShaderEnabled()) { + theFlags.SetGeometryShaderEnabled(true); + + m_GeometryShader.append("#define GEOMETRY_SHADER 1\n"); + m_GeometryShader.append(inGeomSource); + + m_VertShader.append("#define GEOMETRY_SHADER 1\n"); + } else if (inFlags.IsGeometryShaderEnabled()) { + theFlags.SetGeometryShaderEnabled(true); + m_GeometryShader.append("#define USER_GEOMETRY_SHADER 1\n"); + m_GeometryShader.append(inProgramSource); + m_VertShader.append("#define GEOMETRY_SHADER 0\n"); + m_FragShader.append("#define GEOMETRY_WIREFRAME_SHADER 0\n"); + } else { + m_VertShader.append("#define GEOMETRY_SHADER 0\n"); + m_FragShader.append("#define GEOMETRY_WIREFRAME_SHADER 0\n"); + } + + if (strstr(inProgramSource, "SNAPPER_SAMPLER")) { + QString programSource(inProgramSource); + insertSnapperDirectives(programSource); + QByteArray data = programSource.toLatin1(); + const char *source = data.constData(); + + m_VertShader.append(source); + m_FragShader.append(source); + } else { + m_VertShader.append(inProgramSource); + m_FragShader.append(inProgramSource); + } + + IShaderCache &theShaderCache = m_Context->GetShaderCache(); + + CRegisteredString theKey = m_Context->GetStringTable().RegisterStr( + GetShaderCacheKey(inId, inProgramMacroName, inFlags)); + + if (inForceCompilation) { + return theShaderCache.ForceCompileProgram(theKey, m_VertShader.c_str(), + m_FragShader.c_str(), NULL, NULL, + m_GeometryShader.c_str(), theFlags, + inFeatureSet, false); + } + return theShaderCache.CompileProgram(theKey, m_VertShader.c_str(), m_FragShader.c_str(), + NULL, NULL, m_GeometryShader.c_str(), theFlags, + inFeatureSet); + } + + // This just returns the custom material shader source without compiling + const char8_t *GetShaderSource(CRegisteredString inPath, CRenderString &inBuffer) override + { + inBuffer.clear(); + inBuffer.append("#define FRAGMENT_SHADER\n"); + + const char8_t *source = DoLoadShader(inPath, inBuffer); + return source; + } + + TShaderAndFlags GetShaderProgram(CRegisteredString inPath, + CRegisteredString inProgramMacro, + TShaderFeatureSet inFeatureSet, + const SDynamicShaderProgramFlags &inFlags, + bool inForceCompilation) override + { + eastl::pair theInserter( + SShaderMapKey(TStrStrPair(inPath, inProgramMacro), inFeatureSet, inFlags.m_TessMode, + inFlags.m_WireframeMode), + TShaderAndFlags()); + eastl::pair theInsertResult(m_ShaderMap.insert(theInserter)); + if (theInsertResult.second || inForceCompilation) { + NVRenderShaderProgram *theProgram = m_Context->GetShaderCache().GetProgram( + GetShaderCacheKey(inPath, inProgramMacro, inFlags), inFeatureSet); + SDynamicShaderProgramFlags theFlags(inFlags); + if (!theProgram || inForceCompilation) { + SDynamicObjectShaderInfo &theShaderInfo = + m_ShaderInfoMap.insert(eastl::make_pair(inPath, SDynamicObjectShaderInfo())) + .first->second; + if (theShaderInfo.m_IsComputeShader == false) { + CRenderString theShaderBuffer; + const char8_t *programSource = DoLoadShader(inPath, theShaderBuffer); + if (theShaderInfo.m_HasGeomShader) + theFlags.SetGeometryShaderEnabled(true); + theProgram = CompileShader(inPath, programSource, NULL, inProgramMacro, + inFeatureSet, theFlags, inForceCompilation); + } else { + CRenderString theShaderBuffer; + const char8_t *shaderVersionStr = "#version 430\n"; + if ((QT3DSU32)m_Context->GetRenderContext().GetRenderContextType() + == NVRenderContextValues::GLES3PLUS) + shaderVersionStr = "#version 310 es\n"; + DoLoadShader(inPath, theShaderBuffer); + theShaderBuffer.insert(0, shaderVersionStr); + const char8_t *programSource = theShaderBuffer.c_str(); + QT3DSU32 len = (QT3DSU32)strlen(nonNull(programSource)) + 1; + theProgram = + m_Context->GetRenderContext() + .CompileComputeSource(inPath.c_str(), + NVConstDataRef((QT3DSI8 *)programSource, len)) + .mShader; + } + } + theInsertResult.first->second = TShaderAndFlags(theProgram, theFlags); + } + return theInsertResult.first->second; + } + + TShaderAndFlags GetDepthPrepassShader(CRegisteredString inPath, + CRegisteredString inPMacro, + TShaderFeatureSet inFeatureSet) override + { + SDynamicObjectShaderInfo &theShaderInfo = + m_ShaderInfoMap.insert(eastl::make_pair(inPath, SDynamicObjectShaderInfo())) + .first->second; + if (theShaderInfo.m_HasGeomShader == false) + return TShaderAndFlags(); + // else, here we go... + SDynamicShaderProgramFlags theFlags; + m_ShaderKeyBuilder.assign(inPMacro.c_str()); + m_ShaderKeyBuilder.append("depthprepass"); + + CRegisteredString theProgramMacro = + m_Context->GetStringTable().RegisterStr(m_ShaderKeyBuilder.c_str()); + + eastl::pair theInserter( + SShaderMapKey(TStrStrPair(inPath, theProgramMacro), inFeatureSet, theFlags.m_TessMode, + theFlags.m_WireframeMode), + TShaderAndFlags()); + eastl::pair theInsertResult(m_ShaderMap.insert(theInserter)); + if (theInsertResult.second) { + NVRenderShaderProgram *theProgram = m_Context->GetShaderCache().GetProgram( + GetShaderCacheKey(inPath, theProgramMacro, theFlags), inFeatureSet); + SDynamicShaderProgramFlags flags(theFlags); + if (!theProgram) { + CRenderString theShaderBuffer; + const char8_t *geomSource = DoLoadShader(inPath, theShaderBuffer); + SShaderVertexCodeGenerator vertexShader( + m_Context->GetStringTable(), m_Allocator, + m_Context->GetRenderContext().GetRenderContextType()); + SShaderFragmentCodeGenerator fragmentShader( + vertexShader, m_Allocator, + m_Context->GetRenderContext().GetRenderContextType()); + + vertexShader.AddAttribute("attr_pos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); + fragmentShader.Append("}"); + const char8_t *vertexSource = vertexShader.BuildShaderSource(); + const char8_t *fragmentSource = fragmentShader.BuildShaderSource(); + + CRenderString programBuffer; + programBuffer.assign("#ifdef VERTEX_SHADER\n"); + programBuffer.append(vertexSource); + programBuffer.append("\n#endif\n"); + programBuffer.append("\n#ifdef FRAGMENT_SHADER\n"); + programBuffer.append(fragmentSource); + programBuffer.append("\n#endif"); + flags.SetGeometryShaderEnabled(true); + theProgram = CompileShader(inPath, programBuffer.c_str(), geomSource, + theProgramMacro, inFeatureSet, flags); + } + theInsertResult.first->second = TShaderAndFlags(theProgram, flags); + } + return theInsertResult.first->second; + } + + virtual void setShaderCodeLibraryPlatformDirectory(const QString &directory) override + { + m_shaderLibraryPlatformDirectory = directory; + } + + virtual QString shaderCodeLibraryPlatformDirectory() override + { + return m_shaderLibraryPlatformDirectory; + } +}; +} + +IDynamicObjectSystemCore & +IDynamicObjectSystemCore::CreateDynamicSystemCore(IQt3DSRenderContextCore &rc) +{ + return *QT3DS_NEW(rc.GetAllocator(), SDynamicObjectSystemImpl)(rc); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.h b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.h new file mode 100644 index 00000000..b149efc8 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystem.h @@ -0,0 +1,286 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_H +#define QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSVec2.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderTessModeValues.h" +#include "Qt3DSRenderGraphObjectTypes.h" +#include "EASTL/utility.h" + +#include + +namespace qt3ds { +namespace render { + struct SDynamicObject; + + namespace dynamic { + + struct SCommand; + + struct SPropertyDeclaration + { + const char8_t *m_Name; + // The datatypes map directly to the obvious types *except* + // for NVRenderTexture2DPtr. This type will be interpreted as a + // CRegisteredString (they are the same binary size) + // and will be used to lookup the texture from the buffer manager. + NVRenderShaderDataTypes::Enum m_DataType; + + SPropertyDeclaration(const char8_t *inName, NVRenderShaderDataTypes::Enum inDtype) + : m_Name(inName) + , m_DataType(inDtype) + { + } + SPropertyDeclaration() + : m_Name("") + , m_DataType(NVRenderShaderDataTypes::Unknown) + { + } + }; + + struct SPropertyDefinition + { + CRegisteredString m_Name; + + //*not* relative to the presentation directory + CRegisteredString m_ImagePath; + // The datatypes map directly to the obvious types *except* + // for NVRenderTexture2DPtr. This type will be interpreted as a + // CRegisteredString and will be used to lookup the texture + // from the buffer manager. + NVRenderShaderDataTypes::Enum m_DataType; + // All offsets are relative to the beginning of the SEffect + // and are aligned to 4 byte boundaries. + QT3DSU32 m_Offset; + // Sizeof this datatype. + QT3DSU32 m_ByteSize; + NVConstDataRef m_EnumValueNames; + + NVRenderTextureTypeValue::Enum + m_TexUsageType; ///< texture usage type like diffuse, specular, ... + // Applies to both s,t + NVRenderTextureCoordOp::Enum m_CoordOp; + // Set mag Filter + NVRenderTextureMagnifyingOp::Enum m_MagFilterOp; + // Set min Filter + NVRenderTextureMinifyingOp::Enum m_MinFilterOp; + bool m_IsEnumProperty; + SPropertyDefinition() + : m_DataType(NVRenderShaderDataTypes::Unknown) + , m_Offset(0) + , m_ByteSize(0) + , m_TexUsageType(NVRenderTextureTypeValue::Unknown) + , m_CoordOp(NVRenderTextureCoordOp::ClampToEdge) + , m_MagFilterOp(NVRenderTextureMagnifyingOp::Linear) + , m_MinFilterOp(NVRenderTextureMinifyingOp::Linear) + , m_IsEnumProperty(false) + { + } + SPropertyDefinition(CRegisteredString inName, NVRenderShaderDataTypes::Enum inType, + QT3DSU32 inOffset, QT3DSU32 inByteSize) + : m_Name(inName) + , m_DataType(inType) + , m_Offset(inOffset) + , m_ByteSize(inByteSize) + , m_TexUsageType(NVRenderTextureTypeValue::Unknown) + , m_CoordOp(NVRenderTextureCoordOp::ClampToEdge) + , m_MagFilterOp(NVRenderTextureMagnifyingOp::Linear) + , m_MinFilterOp(NVRenderTextureMinifyingOp::Linear) + , m_IsEnumProperty(false) + { + } + }; + + struct SDynamicShaderProgramFlags : public SShaderCacheProgramFlags + { + TessModeValues::Enum m_TessMode; + bool m_WireframeMode; + + SDynamicShaderProgramFlags() + : m_TessMode(TessModeValues::NoTess) + , m_WireframeMode(false) + { + } + + SDynamicShaderProgramFlags(TessModeValues::Enum inTessMode, bool inWireframeMode) + : m_TessMode(inTessMode) + , m_WireframeMode(inWireframeMode) + { + } + + static const char *wireframeToString(bool inEnable) + { + if (inEnable) + return "wireframeMode:true"; + else + return "wireframeMode:false"; + } + }; + } + + class IDynamicObjectClass + { + protected: + virtual ~IDynamicObjectClass() {} + public: + virtual CRegisteredString GetId() const = 0; + virtual NVConstDataRef GetProperties() const = 0; + virtual QT3DSU32 GetPropertySectionByteSize() const = 0; + virtual const QT3DSU8 *GetDefaultValueBuffer() const = 0; + virtual QT3DSU32 GetBaseObjectSize() const = 0; + virtual GraphObjectTypes::Enum GraphObjectType() const = 0; + virtual const dynamic::SPropertyDefinition * + FindPropertyByName(CRegisteredString inName) const = 0; + virtual NVConstDataRef GetRenderCommands() const = 0; + virtual bool RequiresDepthTexture() const = 0; + virtual void SetRequiresDepthTexture(bool inRequires) = 0; + virtual bool RequiresCompilation() const = 0; + virtual void SetRequiresCompilation(bool inRequires) = 0; + virtual NVRenderTextureFormats::Enum GetOutputTextureFormat() const = 0; + }; + + class IDynamicObjectSystemCore : public NVRefCounted + { + protected: + virtual ~IDynamicObjectSystemCore() {} + public: + virtual bool IsRegistered(CRegisteredString inStr) = 0; + + virtual bool Register(CRegisteredString inName, + NVConstDataRef inProperties, + QT3DSU32 inBaseObjectSize, GraphObjectTypes::Enum inGraphObjectType) = 0; + + virtual bool Unregister(CRegisteredString inName) = 0; + + // Set the default value. THis is unnecessary if the default is zero as that is what it is + // assumed to be. + virtual void SetPropertyDefaultValue(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inDefaultData) = 0; + + virtual void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inNames) = 0; + + virtual NVConstDataRef + GetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName) const = 0; + + virtual NVConstDataRef + GetProperties(CRegisteredString inName) const = 0; + + virtual void SetPropertyTextureSettings(CRegisteredString inName, + CRegisteredString inPropName, + CRegisteredString inPropPath, + NVRenderTextureTypeValue::Enum inTexType, + NVRenderTextureCoordOp::Enum inCoordOp, + NVRenderTextureMagnifyingOp::Enum inMagFilterOp, + NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0; + + virtual IDynamicObjectClass *GetDynamicObjectClass(CRegisteredString inName) = 0; + + // The effect commands are the actual commands that run for a given effect. The tell the + // system exactly + // explicitly things like bind this shader, bind this render target, apply this property, + // run this shader + // See UICRenderEffectCommands.h for the list of commands. + // These commands are copied into the effect. + virtual void SetRenderCommands(CRegisteredString inClassName, + NVConstDataRef inCommands) = 0; + virtual NVConstDataRef + GetRenderCommands(CRegisteredString inClassName) const = 0; + + virtual SDynamicObject *CreateInstance(CRegisteredString inClassName, + NVAllocatorCallback &inSceneGraphAllocator) = 0; + + // scan shader for #includes and insert any found" + virtual void InsertShaderHeaderInformation(CRenderString &inShader, + const char *inLogPath) = 0; + + // Set the shader data for a given path. Used when a path doesn't correspond to a file but + // the data has been + // auto-generated. The system will look for data under this path key during the BindShader + // effect command. + virtual void SetShaderData(CRegisteredString inPath, const char8_t *inData, + const char8_t *inShaderType = NULL, + const char8_t *inShaderVersion = NULL, + bool inHasGeomShader = false, + bool inIsComputeShader = false) = 0; + + // Overall save functions for saving the class information out to the binary file. + virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, + const char8_t *inProjectDir) const = 0; + virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t *inProjectDir) = 0; + + virtual IDynamicObjectSystem &CreateDynamicSystem(IQt3DSRenderContext &rc) = 0; + + static IDynamicObjectSystemCore &CreateDynamicSystemCore(IQt3DSRenderContextCore &rc); + }; + + typedef eastl::pair, + dynamic::SDynamicShaderProgramFlags> + TShaderAndFlags; + + class IDynamicObjectSystem : public IDynamicObjectSystemCore + { + protected: + virtual ~IDynamicObjectSystem() {} + + public: + virtual TShaderAndFlags + GetShaderProgram(CRegisteredString inPath, CRegisteredString inProgramMacro, + TShaderFeatureSet inFeatureSet, + const dynamic::SDynamicShaderProgramFlags &inFlags, + bool inForceCompilation = false) = 0; + + virtual const char8_t *GetShaderSource(CRegisteredString inPath, CRenderString &source) = 0; + + // Will return null in the case where a custom prepass shader isn't needed for this object + // If no geom shader, then no depth prepass shader. + virtual TShaderAndFlags GetDepthPrepassShader(CRegisteredString inPath, + CRegisteredString inProgramMacro, + TShaderFeatureSet inFeatureSet) = 0; + + virtual void setShaderCodeLibraryPlatformDirectory(const QString &directory) = 0; + virtual QString shaderCodeLibraryPlatformDirectory() = 0; + + static QString GetShaderCodeLibraryDirectory() { return QStringLiteral("res/effectlib"); } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemCommands.h b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemCommands.h new file mode 100644 index 00000000..857dfa97 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemCommands.h @@ -0,0 +1,622 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EFFECT_SYSTEM_COMMANDS_H +#define QT3DS_RENDER_EFFECT_SYSTEM_COMMANDS_H +#include "Qt3DSRender.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSFlags.h" + +namespace qt3ds { +namespace render { + namespace dynamic { + using qt3ds::render::NVRenderBufferBarrierFlags; + + struct CommandTypes + { + enum Enum { + Unknown = 0, + AllocateBuffer, + BindTarget, + BindBuffer, + BindShader, + ApplyInstanceValue, + ApplyBufferValue, + // Apply the depth buffer as an input texture. + ApplyDepthValue, + Render, // Render to current FBO + ApplyBlending, + ApplyRenderState, // apply a render state + ApplyBlitFramebuffer, + ApplyValue, + DepthStencil, + AllocateImage, + ApplyImageValue, + AllocateDataBuffer, + ApplyDataBufferValue, + }; + }; + +#define QT3DS_RENDER_EFFECTS_ITERATE_COMMAND_TYPES \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(AllocateBuffer) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(BindTarget) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(BindBuffer) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(BindShader) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyInstanceValue) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyBufferValue) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyDepthValue) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(Render) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyBlending) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyRenderState) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyBlitFramebuffer) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyValue) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(DepthStencil) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(AllocateImage) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyImageValue) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(AllocateDataBuffer) \ + QT3DS_RENDER_EFFECTS_HANDLE_COMMAND_TYPES(ApplyDataBufferValue) + + // All commands need at least two constructors. One for when they are created that should + // setup all their member variables and one for when we are copying commands from an outside + // entity into the effect system. We have to re-register strings in that case because we + // can't assume the outside entity was using the same string table we are... + struct SCommand + { + CommandTypes::Enum m_Type; + SCommand(CommandTypes::Enum inType) + : m_Type(inType) + { + } + SCommand() + : m_Type(CommandTypes::Unknown) + { + } + // Implemented in UICRenderEffectSystem.cpp + static QT3DSU32 GetSizeofCommand(const SCommand &inCommand); + static void CopyConstructCommand(QT3DSU8 *inDataBuffer, const SCommand &inCommand, + IStringTable &inStrTable); + }; + + struct AllocateBufferFlagValues + { + enum Enum { + SceneLifetime = 1, + }; + }; + + struct SAllocateBufferFlags : public NVFlags + { + SAllocateBufferFlags(QT3DSU32 inValues) + : NVFlags(inValues) + { + } + SAllocateBufferFlags() {} + void SetSceneLifetime(bool inValue) + { + clearOrSet(inValue, AllocateBufferFlagValues::SceneLifetime); + } + // If isSceneLifetime is unset the buffer is assumed to be frame lifetime and will be + // released after this render operation. + bool IsSceneLifetime() const + { + return this->operator&(AllocateBufferFlagValues::SceneLifetime); + } + }; + + struct SAllocateBuffer : public SCommand + { + CRegisteredString m_Name; + NVRenderTextureFormats::Enum m_Format; + NVRenderTextureMagnifyingOp::Enum m_FilterOp; + NVRenderTextureCoordOp::Enum m_TexCoordOp; + QT3DSF32 m_SizeMultiplier; + SAllocateBufferFlags m_BufferFlags; + SAllocateBuffer() + : SCommand(CommandTypes::AllocateBuffer) + , m_Format(NVRenderTextureFormats::RGBA8) + , m_FilterOp(NVRenderTextureMagnifyingOp::Linear) + , m_TexCoordOp(NVRenderTextureCoordOp::ClampToEdge) + , m_SizeMultiplier(1.0f) + { + } + SAllocateBuffer(CRegisteredString inName, NVRenderTextureFormats::Enum inFormat, + NVRenderTextureMagnifyingOp::Enum inFilterOp, + NVRenderTextureCoordOp::Enum inCoordOp, QT3DSF32 inMultiplier, + SAllocateBufferFlags inFlags) + : SCommand(CommandTypes::AllocateBuffer) + , m_Name(inName) + , m_Format(inFormat) + , m_FilterOp(inFilterOp) + , m_TexCoordOp(inCoordOp) + , m_SizeMultiplier(inMultiplier) + , m_BufferFlags(inFlags) + { + } + SAllocateBuffer(const SAllocateBuffer &inOther, IStringTable &inStrTable) + : SCommand(CommandTypes::AllocateBuffer) + , m_Name(inStrTable.RegisterStr(inOther.m_Name)) + , m_Format(inOther.m_Format) + , m_FilterOp(inOther.m_FilterOp) + , m_TexCoordOp(inOther.m_TexCoordOp) + , m_SizeMultiplier(inOther.m_SizeMultiplier) + , m_BufferFlags(inOther.m_BufferFlags) + { + } + }; + + struct SAllocateImage : public SAllocateBuffer + { + NVRenderImageAccessType::Enum m_Access; + + SAllocateImage() + : SAllocateBuffer() + , m_Access(NVRenderImageAccessType::ReadWrite) + { + m_Type = CommandTypes::AllocateImage; + } + SAllocateImage(CRegisteredString inName, NVRenderTextureFormats::Enum inFormat, + NVRenderTextureMagnifyingOp::Enum inFilterOp, + NVRenderTextureCoordOp::Enum inCoordOp, QT3DSF32 inMultiplier, + SAllocateBufferFlags inFlags, NVRenderImageAccessType::Enum inAccess) + : SAllocateBuffer(inName, inFormat, inFilterOp, inCoordOp, inMultiplier, inFlags) + , m_Access(inAccess) + { + m_Type = CommandTypes::AllocateImage; + } + + SAllocateImage(const SAllocateImage &inOther, IStringTable &inStrTable) + : SAllocateBuffer(inStrTable.RegisterStr(inOther.m_Name), inOther.m_Format, + inOther.m_FilterOp, inOther.m_TexCoordOp, + inOther.m_SizeMultiplier, inOther.m_BufferFlags) + , m_Access(inOther.m_Access) + { + m_Type = CommandTypes::AllocateImage; + } + }; + + struct SAllocateDataBuffer : public SCommand + { + CRegisteredString m_Name; + NVRenderBufferBindValues::Enum m_DataBufferType; + CRegisteredString m_WrapName; + NVRenderBufferBindValues::Enum m_DataBufferWrapType; + QT3DSF32 m_Size; + SAllocateBufferFlags m_BufferFlags; + + SAllocateDataBuffer() + : SCommand(CommandTypes::AllocateDataBuffer) + { + } + + SAllocateDataBuffer(CRegisteredString inName, + NVRenderBufferBindValues::Enum inBufferType, + CRegisteredString inWrapName, + NVRenderBufferBindValues::Enum inBufferWrapType, QT3DSF32 inSize, + SAllocateBufferFlags inFlags) + : SCommand(CommandTypes::AllocateDataBuffer) + , m_Name(inName) + , m_DataBufferType(inBufferType) + , m_WrapName(inWrapName) + , m_DataBufferWrapType(inBufferWrapType) + , m_Size(inSize) + , m_BufferFlags(inFlags) + { + } + + SAllocateDataBuffer(const SAllocateDataBuffer &inOther, IStringTable &inStrTable) + : SCommand(CommandTypes::AllocateDataBuffer) + , m_Name(inStrTable.RegisterStr(inOther.m_Name)) + , m_DataBufferType(inOther.m_DataBufferType) + , m_WrapName(inStrTable.RegisterStr(inOther.m_WrapName)) + , m_DataBufferWrapType(inOther.m_DataBufferWrapType) + , m_Size(inOther.m_Size) + , m_BufferFlags(inOther.m_BufferFlags) + { + } + }; + + struct SBindTarget : public SCommand + { + NVRenderTextureFormats::Enum m_OutputFormat; + + SBindTarget(NVRenderTextureFormats::Enum inFormat = NVRenderTextureFormats::RGBA8) + : SCommand(CommandTypes::BindTarget) + , m_OutputFormat(inFormat) + { + } + SBindTarget(const SBindTarget &inOther, IStringTable &) + : SCommand(CommandTypes::BindTarget) + , m_OutputFormat(inOther.m_OutputFormat) + { + } + }; + + struct SBindBuffer : public SCommand + { + CRegisteredString m_BufferName; + bool m_NeedsClear; + SBindBuffer(CRegisteredString inBufName, bool inNeedsClear) + : SCommand(CommandTypes::BindBuffer) + , m_BufferName(inBufName) + , m_NeedsClear(inNeedsClear) + { + } + SBindBuffer(const SBindBuffer &inOther, IStringTable &inTable) + : SCommand(CommandTypes::BindBuffer) + , m_BufferName(inTable.RegisterStr(inOther.m_BufferName)) + , m_NeedsClear(inOther.m_NeedsClear) + { + } + }; + + struct SBindShader : public SCommand + { + CRegisteredString m_ShaderPath; + // One GLSL file can hold multiple shaders in the case of multipass effects. + // This makes it significantly easier for authors to reason about the shader + // but it means we need to #define a preprocessor token to indicate which + // effect we intend to compile at this point. + CRegisteredString m_ShaderDefine; + SBindShader(CRegisteredString inShaderPath, + CRegisteredString inShaderDefine = CRegisteredString()) + : SCommand(CommandTypes::BindShader) + , m_ShaderPath(inShaderPath) + , m_ShaderDefine(inShaderDefine) + { + } + SBindShader() + : SCommand(CommandTypes::BindShader) + { + } + SBindShader(const SBindShader &inOther, IStringTable &inTable) + : SCommand(CommandTypes::BindShader) + , m_ShaderPath(inTable.RegisterStr(inOther.m_ShaderPath)) + , m_ShaderDefine(inTable.RegisterStr(inOther.m_ShaderDefine)) + { + } + }; + + // The value sits immediately after the 'this' object + // in memory. + // If propertyName is not valid then we attempt to apply all of the effect property values + // to the shader, ignoring ones that don't match up. + struct SApplyInstanceValue : public SCommand + { + // Name of value to apply in shader + CRegisteredString m_PropertyName; + // type of value + NVRenderShaderDataTypes::Enum m_ValueType; + // offset in the effect data section of value. + QT3DSU32 m_ValueOffset; + SApplyInstanceValue(CRegisteredString inName, NVRenderShaderDataTypes::Enum inValueType, + QT3DSU32 inValueOffset) + : SCommand(CommandTypes::ApplyInstanceValue) + , m_PropertyName(inName) + , m_ValueType(inValueType) + , m_ValueOffset(inValueOffset) + { + } + // Default will attempt to apply all effect values to the currently bound shader + SApplyInstanceValue() + : SCommand(CommandTypes::ApplyInstanceValue) + , m_ValueType(NVRenderShaderDataTypes::Unknown) + , m_ValueOffset(0) + { + } + SApplyInstanceValue(const SApplyInstanceValue &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyInstanceValue) + , m_PropertyName(inTable.RegisterStr(inOther.m_PropertyName)) + , m_ValueType(inOther.m_ValueType) + , m_ValueOffset(inOther.m_ValueOffset) + { + } + }; + + struct SApplyValue : public SCommand + { + CRegisteredString m_PropertyName; + NVRenderShaderDataTypes::Enum m_ValueType; + NVDataRef m_Value; + SApplyValue(CRegisteredString inName, NVRenderShaderDataTypes::Enum inValueType) + : SCommand(CommandTypes::ApplyValue) + , m_PropertyName(inName) + , m_ValueType(inValueType) + { + } + // Default will attempt to apply all effect values to the currently bound shader + SApplyValue() + : SCommand(CommandTypes::ApplyValue) + , m_ValueType(NVRenderShaderDataTypes::Unknown) + { + } + + SApplyValue(const SApplyValue &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyValue) + , m_PropertyName(inTable.RegisterStr(inOther.m_PropertyName)) + , m_ValueType(inOther.m_ValueType) + , m_Value(inOther.m_Value) + { + } + }; + + // bind a buffer to a given shader parameter. + struct SApplyBufferValue : public SCommand + { + // If no buffer name is given then the special buffer [source] + // is assumed. + CRegisteredString m_BufferName; + // If no param name is given, the buffer is bound to the + // input texture parameter (texture0). + CRegisteredString m_ParamName; + + SApplyBufferValue(CRegisteredString bufferName, CRegisteredString shaderParam) + : SCommand(CommandTypes::ApplyBufferValue) + , m_BufferName(bufferName) + , m_ParamName(shaderParam) + { + } + SApplyBufferValue(const SApplyBufferValue &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyBufferValue) + , m_BufferName(inTable.RegisterStr(inOther.m_BufferName)) + , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) + { + } + }; + + // bind a buffer to a given shader parameter. + struct SApplyImageValue : public SCommand + { + CRegisteredString m_ImageName; ///< name which the image was allocated + CRegisteredString m_ParamName; ///< must match the name in the shader + bool m_BindAsTexture; ///< bind image as texture + bool m_NeedSync; ///< if true we add a memory barrier before usage + + SApplyImageValue(CRegisteredString bufferName, CRegisteredString shaderParam, + bool inBindAsTexture, bool inNeedSync) + : SCommand(CommandTypes::ApplyImageValue) + , m_ImageName(bufferName) + , m_ParamName(shaderParam) + , m_BindAsTexture(inBindAsTexture) + , m_NeedSync(inNeedSync) + { + } + SApplyImageValue(const SApplyImageValue &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyImageValue) + , m_ImageName(inTable.RegisterStr(inOther.m_ImageName)) + , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) + , m_BindAsTexture(inOther.m_BindAsTexture) + , m_NeedSync(inOther.m_NeedSync) + { + } + }; + + // bind a buffer to a given shader parameter. + struct SApplyDataBufferValue : public SCommand + { + CRegisteredString m_ParamName; ///< must match the name in the shader + NVRenderBufferBindValues::Enum m_BindAs; ///< to which target we bind this buffer + + SApplyDataBufferValue(CRegisteredString inShaderParam, + NVRenderBufferBindValues::Enum inBufferType) + : SCommand(CommandTypes::ApplyDataBufferValue) + , m_ParamName(inShaderParam) + , m_BindAs(inBufferType) + { + } + SApplyDataBufferValue(const SApplyDataBufferValue &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyDataBufferValue) + , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) + , m_BindAs(inOther.m_BindAs) + { + } + }; + + struct SApplyDepthValue : public SCommand + { + // If no param name is given, the buffer is bound to the + // input texture parameter (texture0). + CRegisteredString m_ParamName; + SApplyDepthValue(CRegisteredString param) + : SCommand(CommandTypes::ApplyDepthValue) + , m_ParamName(param) + { + } + SApplyDepthValue(const SApplyDepthValue &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyDepthValue) + , m_ParamName(inTable.RegisterStr(inOther.m_ParamName)) + { + } + }; + + struct SRender : public SCommand + { + bool m_DrawIndirect; + SRender(bool inDrawIndirect) + : SCommand(CommandTypes::Render) + , m_DrawIndirect(inDrawIndirect) + { + } + + SRender(const SRender &inOther, IStringTable &) + : SCommand(CommandTypes::Render) + , m_DrawIndirect(inOther.m_DrawIndirect) + { + } + }; + + struct SApplyBlending : public SCommand + { + NVRenderSrcBlendFunc::Enum m_SrcBlendFunc; + NVRenderDstBlendFunc::Enum m_DstBlendFunc; + + SApplyBlending(NVRenderSrcBlendFunc::Enum inSrcBlendFunc, + NVRenderDstBlendFunc::Enum inDstBlendFunc) + : SCommand(CommandTypes::ApplyBlending) + , m_SrcBlendFunc(inSrcBlendFunc) + , m_DstBlendFunc(inDstBlendFunc) + { + } + + SApplyBlending(const SApplyBlending &inOther, IStringTable &) + : SCommand(CommandTypes::ApplyBlending) + , m_SrcBlendFunc(inOther.m_SrcBlendFunc) + , m_DstBlendFunc(inOther.m_DstBlendFunc) + { + } + }; + + struct SApplyRenderState : public SCommand + { + NVRenderState::Enum m_RenderState; + bool m_Enabled; + + SApplyRenderState(qt3ds::render::NVRenderState::Enum inRenderStateValue, bool inEnabled) + : SCommand(CommandTypes::ApplyRenderState) + , m_RenderState(inRenderStateValue) + , m_Enabled(inEnabled) + { + } + + SApplyRenderState(const SApplyRenderState &inOther, IStringTable &) + : SCommand(CommandTypes::ApplyRenderState) + , m_RenderState(inOther.m_RenderState) + , m_Enabled(inOther.m_Enabled) + { + } + }; + + struct SApplyBlitFramebuffer : public SCommand + { + // If no buffer name is given then the special buffer [source] + // is assumed. Which is the default render target + CRegisteredString m_SourceBufferName; + // If no buffer name is given then the special buffer [dest] + // is assumed. Which is the default render target + CRegisteredString m_DestBufferName; + + SApplyBlitFramebuffer(CRegisteredString inSourceBufferName, + CRegisteredString inDestBufferName) + : SCommand(CommandTypes::ApplyBlitFramebuffer) + , m_SourceBufferName(inSourceBufferName) + , m_DestBufferName(inDestBufferName) + { + } + + SApplyBlitFramebuffer(const SApplyBlitFramebuffer &inOther, IStringTable &inTable) + : SCommand(CommandTypes::ApplyBlitFramebuffer) + , m_SourceBufferName(inTable.RegisterStr(inOther.m_SourceBufferName)) + , m_DestBufferName(inTable.RegisterStr(inOther.m_DestBufferName)) + { + } + }; + + struct DepthStencilFlagValues + { + enum Enum { + NoFlagValue = 0, + ClearStencil = 1 << 0, + ClearDepth = 1 << 1, + }; + }; + + struct SDepthStencilFlags : public NVFlags + { + bool HasClearStencil() const { return operator&(DepthStencilFlagValues::ClearStencil); } + void SetClearStencil(bool value) + { + clearOrSet(value, DepthStencilFlagValues::ClearStencil); + } + + bool HasClearDepth() const { return operator&(DepthStencilFlagValues::ClearDepth); } + void SetClearDepth(bool value) + { + clearOrSet(value, DepthStencilFlagValues::ClearDepth); + } + }; + + struct SDepthStencil : public SCommand + { + CRegisteredString m_BufferName; + SDepthStencilFlags m_Flags; + qt3ds::render::NVRenderStencilOp::Enum m_StencilFailOperation; + qt3ds::render::NVRenderStencilOp::Enum m_DepthPassOperation; + qt3ds::render::NVRenderStencilOp::Enum m_DepthFailOperation; + qt3ds::render::NVRenderBoolOp::Enum m_StencilFunction; + QT3DSU32 m_Reference; + QT3DSU32 m_Mask; + + SDepthStencil() + : SCommand(CommandTypes::DepthStencil) + , m_StencilFailOperation(qt3ds::render::NVRenderStencilOp::Keep) + , m_DepthPassOperation(qt3ds::render::NVRenderStencilOp::Keep) + , m_DepthFailOperation(qt3ds::render::NVRenderStencilOp::Keep) + , m_StencilFunction(qt3ds::render::NVRenderBoolOp::Equal) + , m_Reference(0) + , m_Mask(QT3DS_MAX_U32) + { + } + + SDepthStencil(CRegisteredString bufName, SDepthStencilFlags flags, + qt3ds::render::NVRenderStencilOp::Enum inStencilOp, + qt3ds::render::NVRenderStencilOp::Enum inDepthPassOp, + qt3ds::render::NVRenderStencilOp::Enum inDepthFailOp, + qt3ds::render::NVRenderBoolOp::Enum inStencilFunc, QT3DSU32 value, QT3DSU32 mask) + : SCommand(CommandTypes::DepthStencil) + , m_BufferName(bufName) + , m_Flags(flags) + , m_StencilFailOperation(inStencilOp) + , m_DepthPassOperation(inDepthPassOp) + , m_DepthFailOperation(inDepthFailOp) + , m_StencilFunction(inStencilFunc) + , m_Reference(value) + , m_Mask(mask) + { + } + + SDepthStencil(const SDepthStencil &inOther, IStringTable &inTable) + : SCommand(CommandTypes::DepthStencil) + , m_BufferName(inTable.RegisterStr(inOther.m_BufferName)) + , m_Flags(inOther.m_Flags) + , m_StencilFailOperation(inOther.m_StencilFailOperation) + , m_DepthPassOperation(inOther.m_DepthPassOperation) + , m_DepthFailOperation(inOther.m_DepthFailOperation) + , m_StencilFunction(inOther.m_StencilFunction) + , m_Reference(inOther.m_Reference) + , m_Mask(inOther.m_Mask) + { + } + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemUtil.h b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemUtil.h new file mode 100644 index 00000000..5d78a4c9 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderDynamicObjectSystemUtil.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_UTIL_H +#define QT3DS_RENDER_DYNAMIC_OBJECT_SYSTEM_UTIL_H +#include "Qt3DSRender.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "Qt3DSRenderString.h" + +namespace qt3ds { +namespace render { + namespace dynamic { + + struct SStringLoadRemapper + { + CStrTableOrDataRef m_StrData; + IStringTable &m_StringTable; + CRenderString m_PathMapper; + const char8_t *m_ProjectDir; + SStringLoadRemapper(NVAllocatorCallback &alloc, CStrTableOrDataRef inData, + const char8_t *inProjectDir, IStringTable &inStrTable) + : m_StrData(inData) + , m_StringTable(inStrTable) + , m_ProjectDir(inProjectDir) + { + Q_UNUSED(alloc) + } + void Remap(CRegisteredString &inStr) { inStr.Remap(m_StrData); } + }; + + struct SStringSaveRemapper + { + const qt3ds::render::SStrRemapMap &m_Map; + CRenderString m_RelativeBuffer; + CRenderString m_ProjectDir; + CRenderString m_FinalBuffer; + IStringTable &m_StringTable; + SStringSaveRemapper(NVAllocatorCallback &alloc, const qt3ds::render::SStrRemapMap &map, + const char8_t *inProjectDir, IStringTable &inStrTable) + : m_Map(map) + , m_StringTable(inStrTable) + { + Q_UNUSED(alloc) + m_ProjectDir.assign(inProjectDir); + } + void Remap(CRegisteredString &inStr) { inStr.Remap(m_Map); } + }; + + inline QT3DSU32 Align(QT3DSU32 inValue) + { + if (inValue % 4) + return inValue + (4 - (inValue % 4)); + return inValue; + } + + inline QT3DSU32 Align8(QT3DSU32 inValue) + { + if (inValue % 8) + return inValue + (8 - (inValue % 8)); + return inValue; + } + + inline qt3ds::QT3DSU32 getSizeofShaderDataType(NVRenderShaderDataTypes::Enum value) + { + using namespace qt3ds; + using namespace qt3ds::render; + switch (value) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(x) \ + case NVRenderShaderDataTypes::x: \ + return sizeof(x); + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + inline const char *GetShaderDatatypeName(NVRenderShaderDataTypes::Enum inValue) + { + switch (inValue) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ + case NVRenderShaderDataTypes::type: \ + return #type; + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return ""; + } + } +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.cpp new file mode 100644 index 00000000..d86c100d --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.cpp @@ -0,0 +1,1847 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderEffectSystem.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderString.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderEffect.h" +#include "Qt3DSRenderResourceManager.h" +#include "Qt3DSRenderDynamicObjectSystemCommands.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderShaderConstant.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "foundation/PreAllocatedAllocator.h" +#include "foundation/SerializationTypes.h" +#include "Qt3DSRenderShaderCache.h" +#include "foundation/FileTools.h" +#include "Qt3DSOffscreenRenderKey.h" +#include "Qt3DSRenderDynamicObjectSystemUtil.h" + +using namespace qt3ds::render; +using namespace qt3ds::render::dynamic; +using qt3ds::render::NVRenderContextScopedProperty; +using qt3ds::render::NVRenderCachedShaderProperty; +using qt3ds::render::NVRenderCachedShaderBuffer; + +// None of this code will work if the size of void* changes because that would mean that +// the alignment of some of the objects isn't 4 bytes but would be 8 bytes. + +typedef eastl::pair TStrStrPair; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const TStrStrPair &item) const + { + return hash()(item.first) ^ hash()(item.second); + } +}; +} + +namespace { + +/* + ApplyBufferValue, + //Apply the depth buffer as an input texture. + ApplyDepthValue, + Render, //Render to current FBO + */ + +struct SEffectClass +{ + NVAllocatorCallback *m_Allocator; + IDynamicObjectClass *m_DynamicClass; + volatile QT3DSI32 mRefCount; + + SEffectClass(NVAllocatorCallback &inFnd, IDynamicObjectClass &dynClass) + : m_Allocator(&inFnd) + , m_DynamicClass(&dynClass) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator) + + void SetupThisObjectFromMemory(NVAllocatorCallback &inAlloc, IDynamicObjectClass &inClass) + { + m_Allocator = &inAlloc; + m_DynamicClass = &inClass; + mRefCount = 0; + } +}; + +struct SAllocatedBufferEntry +{ + CRegisteredString m_Name; + NVScopedRefCounted m_FrameBuffer; + NVScopedRefCounted m_Texture; + SAllocateBufferFlags m_Flags; + bool m_NeedsClear; + + SAllocatedBufferEntry(CRegisteredString inName, NVRenderFrameBuffer &inFb, + NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags) + : m_Name(inName) + , m_FrameBuffer(&inFb) + , m_Texture(&inTexture) + , m_Flags(inFlags) + , m_NeedsClear(true) + { + } + SAllocatedBufferEntry() {} +}; + +struct SAllocatedImageEntry +{ + CRegisteredString m_Name; + NVScopedRefCounted m_Image; + NVScopedRefCounted m_Texture; + SAllocateBufferFlags m_Flags; + + SAllocatedImageEntry(CRegisteredString inName, NVRenderImage2D &inImage, + NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags) + : m_Name(inName) + , m_Image(&inImage) + , m_Texture(&inTexture) + , m_Flags(inFlags) + { + } + SAllocatedImageEntry() {} +}; + +struct SImageEntry +{ + NVScopedRefCounted m_Shader; + NVRenderCachedShaderProperty m_Image; + volatile QT3DSI32 mRefCount; + + SImageEntry(NVRenderShaderProgram &inShader, const char *inImageName) + : m_Shader(inShader) + , m_Image(inImageName, inShader) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) + + void Set(NVRenderImage2D *inImage) { m_Image.Set(inImage); } + + static SImageEntry CreateImageEntry(NVRenderShaderProgram &inShader, const char *inStem) + { + return SImageEntry(inShader, inStem); + } +}; + +struct SAllocatedDataBufferEntry +{ + CRegisteredString m_Name; + NVScopedRefCounted m_DataBuffer; + NVRenderBufferBindValues::Enum m_BufferType; + NVDataRef m_BufferData; + SAllocateBufferFlags m_Flags; + bool m_NeedsClear; + + SAllocatedDataBufferEntry(CRegisteredString inName, + qt3ds::render::NVRenderDataBuffer &inDataBuffer, + NVRenderBufferBindValues::Enum inType, NVDataRef data, + SAllocateBufferFlags inFlags) + : m_Name(inName) + , m_DataBuffer(&inDataBuffer) + , m_BufferType(inType) + , m_BufferData(data) + , m_Flags(inFlags) + , m_NeedsClear(false) + { + } + SAllocatedDataBufferEntry() {} +}; + +struct SDataBufferEntry +{ + NVScopedRefCounted m_Shader; + NVRenderCachedShaderBuffer m_DataBuffer; + volatile QT3DSI32 mRefCount; + + SDataBufferEntry(NVRenderShaderProgram &inShader, const char *inBufferName) + : m_Shader(inShader) + , m_DataBuffer(inBufferName, inShader) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) + + void Set(qt3ds::render::NVRenderDataBuffer *inBuffer) + { + if (inBuffer) + inBuffer->Bind(); + + m_DataBuffer.Set(); + } + + static SDataBufferEntry CreateDataBufferEntry(NVRenderShaderProgram &inShader, + const char *inStem) + { + return SDataBufferEntry(inShader, inStem); + } +}; + +struct SEffectTextureData +{ + NVRenderTexture2D *m_Texture; + bool m_NeedsAlphaMultiply; + SEffectTextureData(NVRenderTexture2D *inTexture, bool inNeedsMultiply) + : m_Texture(inTexture) + , m_NeedsAlphaMultiply(inNeedsMultiply) + { + } + SEffectTextureData() + : m_Texture(NULL) + , m_NeedsAlphaMultiply(false) + { + } +}; + +struct STextureEntry +{ + NVScopedRefCounted m_Shader; + NVRenderCachedShaderProperty m_Texture; + NVRenderCachedShaderProperty m_TextureData; + NVRenderCachedShaderProperty m_TextureFlags; + volatile QT3DSI32 mRefCount; + + STextureEntry(NVRenderShaderProgram &inShader, const char *inTexName, const char *inDataName, + const char *inFlagName) + : m_Shader(inShader) + , m_Texture(inTexName, inShader) + , m_TextureData(inDataName, inShader) + , m_TextureFlags(inFlagName, inShader) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) + + void Set(NVRenderTexture2D *inTexture, bool inNeedsAlphaMultiply, + const SPropertyDefinition *inDefinition) + { + QT3DSF32 theMixValue(inNeedsAlphaMultiply ? 0.0f : 1.0f); + if (inTexture && inDefinition) { + inTexture->SetMagFilter(inDefinition->m_MagFilterOp); + inTexture->SetMinFilter( + static_cast(inDefinition->m_MagFilterOp)); + inTexture->SetTextureWrapS(inDefinition->m_CoordOp); + inTexture->SetTextureWrapT(inDefinition->m_CoordOp); + } + m_Texture.Set(inTexture); + if (inTexture) { + STextureDetails theDetails(inTexture->GetTextureDetails()); + m_TextureData.Set( + QT3DSVec4((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height, theMixValue, 0.0f)); + // I have no idea what these flags do. + m_TextureFlags.Set(1); + } else + m_TextureFlags.Set(0); + } + + static STextureEntry CreateTextureEntry(NVRenderShaderProgram &inShader, const char *inStem, + CRenderString &inBuilder, CRenderString &inBuilder2) + { + inBuilder.assign(inStem); + inBuilder.append("Info"); + inBuilder2.assign("flag"); + inBuilder2.append(inStem); + return STextureEntry(inShader, inStem, inBuilder.c_str(), inBuilder2.c_str()); + } +}; + +typedef eastl::pair> TNamedTextureEntry; +typedef eastl::pair> TNamedImageEntry; +typedef eastl::pair> TNamedDataBufferEntry; +} + +namespace qt3ds { +namespace render { + + struct SEffectContext + { + CRegisteredString m_ClassName; + IQt3DSRenderContext &m_Context; + IResourceManager *m_ResourceManager; + nvvector m_AllocatedBuffers; + nvvector m_AllocatedImages; + nvvector m_AllocatedDataBuffers; + nvvector m_TextureEntries; + nvvector m_ImageEntries; + nvvector m_DataBufferEntries; + + SEffectContext(CRegisteredString inName, IQt3DSRenderContext &ctx, IResourceManager *inManager) + : m_ClassName(inName) + , m_Context(ctx) + , m_ResourceManager(inManager) + , m_AllocatedBuffers(ctx.GetAllocator(), "SEffectContext::m_AllocatedBuffers") + , m_AllocatedImages(ctx.GetAllocator(), "SEffectContext::m_AllocatedImages") + , m_AllocatedDataBuffers(ctx.GetAllocator(), "SEffectContext::m_AllocatedDataBuffers") + , m_TextureEntries(ctx.GetAllocator(), "SEffectContext::m_TextureEntries") + , m_ImageEntries(ctx.GetAllocator(), "SEffectContext::m_ImageEntries") + , m_DataBufferEntries(ctx.GetAllocator(), "SEffectContext::m_DataBufferEntries") + { + } + + ~SEffectContext() + { + while (m_AllocatedBuffers.size()) + ReleaseBuffer(0); + + while (m_AllocatedImages.size()) + ReleaseImage(0); + + while (m_AllocatedDataBuffers.size()) + ReleaseDataBuffer(0); + } + + void ReleaseBuffer(QT3DSU32 inIdx) + { + SAllocatedBufferEntry &theEntry(m_AllocatedBuffers[inIdx]); + theEntry.m_FrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer()); + m_ResourceManager->Release(*theEntry.m_FrameBuffer); + m_ResourceManager->Release(*theEntry.m_Texture); + m_AllocatedBuffers.replace_with_last(inIdx); + } + + void ReleaseImage(QT3DSU32 inIdx) + { + SAllocatedImageEntry &theEntry(m_AllocatedImages[inIdx]); + m_ResourceManager->Release(*theEntry.m_Image); + m_ResourceManager->Release(*theEntry.m_Texture); + m_AllocatedImages.replace_with_last(inIdx); + } + + void ReleaseDataBuffer(QT3DSU32 inIdx) + { + SAllocatedDataBufferEntry &theEntry(m_AllocatedDataBuffers[inIdx]); + m_Context.GetAllocator().deallocate(theEntry.m_BufferData.begin()); + + m_AllocatedDataBuffers.replace_with_last(inIdx); + } + + QT3DSU32 FindBuffer(CRegisteredString inName) + { + for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx) + if (m_AllocatedBuffers[idx].m_Name == inName) + return idx; + return m_AllocatedBuffers.size(); + } + + QT3DSU32 FindImage(CRegisteredString inName) + { + for (QT3DSU32 idx = 0, end = m_AllocatedImages.size(); idx < end; ++idx) + if (m_AllocatedImages[idx].m_Name == inName) + return idx; + + return m_AllocatedImages.size(); + } + + QT3DSU32 FindDataBuffer(CRegisteredString inName) + { + for (QT3DSU32 idx = 0, end = m_AllocatedDataBuffers.size(); idx < end; ++idx) { + if (m_AllocatedDataBuffers[idx].m_Name == inName) + return idx; + } + + return m_AllocatedDataBuffers.size(); + } + + void SetTexture(NVRenderShaderProgram &inShader, CRegisteredString inPropName, + NVRenderTexture2D *inTexture, bool inNeedsMultiply, + CRenderString &inStringBuilder, CRenderString &inStringBuilder2, + const SPropertyDefinition *inPropDec = NULL) + { + STextureEntry *theTextureEntry(NULL); + for (QT3DSU32 idx = 0, end = m_TextureEntries.size(); idx < end && theTextureEntry == NULL; + ++idx) { + if (m_TextureEntries[idx].first == inPropName + && m_TextureEntries[idx].second->m_Shader.mPtr == &inShader) + theTextureEntry = m_TextureEntries[idx].second; + } + if (theTextureEntry == NULL) { + NVScopedRefCounted theNewEntry = QT3DS_NEW( + m_Context.GetAllocator(), STextureEntry)(STextureEntry::CreateTextureEntry( + inShader, inPropName, inStringBuilder, inStringBuilder2)); + m_TextureEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); + theTextureEntry = theNewEntry.mPtr; + } + theTextureEntry->Set(inTexture, inNeedsMultiply, inPropDec); + } + + void SetImage(NVRenderShaderProgram &inShader, CRegisteredString inPropName, + NVRenderImage2D *inImage) + { + SImageEntry *theImageEntry(NULL); + for (QT3DSU32 idx = 0, end = m_ImageEntries.size(); idx < end && theImageEntry == NULL; + ++idx) { + if (m_ImageEntries[idx].first == inPropName + && m_ImageEntries[idx].second->m_Shader.mPtr == &inShader) + theImageEntry = m_ImageEntries[idx].second; + } + if (theImageEntry == NULL) { + NVScopedRefCounted theNewEntry = + QT3DS_NEW(m_Context.GetAllocator(), + SImageEntry)(SImageEntry::CreateImageEntry(inShader, inPropName)); + m_ImageEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); + theImageEntry = theNewEntry.mPtr; + } + + theImageEntry->Set(inImage); + } + + void SetDataBuffer(NVRenderShaderProgram &inShader, CRegisteredString inPropName, + qt3ds::render::NVRenderDataBuffer *inBuffer) + { + SDataBufferEntry *theDataBufferEntry(NULL); + for (QT3DSU32 idx = 0, end = m_DataBufferEntries.size(); + idx < end && theDataBufferEntry == NULL; ++idx) { + if (m_DataBufferEntries[idx].first == inPropName + && m_DataBufferEntries[idx].second->m_Shader.mPtr == &inShader) + theDataBufferEntry = m_DataBufferEntries[idx].second; + } + if (theDataBufferEntry == NULL) { + NVScopedRefCounted theNewEntry = + QT3DS_NEW(m_Context.GetAllocator(), SDataBufferEntry)( + SDataBufferEntry::CreateDataBufferEntry(inShader, inPropName)); + m_DataBufferEntries.push_back(eastl::make_pair(inPropName, theNewEntry)); + theDataBufferEntry = theNewEntry.mPtr; + } + + theDataBufferEntry->Set(inBuffer); + } + }; +} +} + +namespace { + +using qt3ds::render::NVRenderCachedShaderProperty; +/* We setup some shared state on the effect shaders */ +struct SEffectShader +{ + NVScopedRefCounted m_Shader; + NVRenderCachedShaderProperty m_MVP; + NVRenderCachedShaderProperty m_FragColorAlphaSettings; + NVRenderCachedShaderProperty m_DestSize; + NVRenderCachedShaderProperty m_AppFrame; + NVRenderCachedShaderProperty m_FPS; + NVRenderCachedShaderProperty m_CameraClipRange; + STextureEntry m_TextureEntry; + volatile QT3DSI32 mRefCount; + SEffectShader(NVRenderShaderProgram &inShader) + : m_Shader(inShader) + , m_MVP("ModelViewProjectionMatrix", inShader) + , m_FragColorAlphaSettings("FragColorAlphaSettings", inShader) + , m_DestSize("DestSize", inShader) + , m_AppFrame("AppFrame", inShader) + , m_FPS("FPS", inShader) + , m_CameraClipRange("CameraClipRange", inShader) + , m_TextureEntry(inShader, "Texture0", "Texture0Info", "Texture0Flags") + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) +}; + +struct SEffectSystem : public IEffectSystem +{ + typedef nvhash_map TPathDataMap; + typedef nvhash_set TPathSet; + typedef nvhash_map> TEffectClassMap; + typedef nvhash_map> TShaderMap; + typedef nvvector TContextList; + + IQt3DSRenderContextCore &m_CoreContext; + IQt3DSRenderContext *m_Context; + NVScopedRefCounted m_ResourceManager; + mutable qt3ds::render::SPreAllocatedAllocator m_Allocator; + // Keep from dual-including headers. + TEffectClassMap m_EffectClasses; + nvvector m_EffectList; + TContextList m_Contexts; + CRenderString m_TextureStringBuilder; + CRenderString m_TextureStringBuilder2; + TShaderMap m_ShaderMap; + NVScopedRefCounted m_DefaultStencilState; + nvvector> m_DepthStencilStates; + volatile QT3DSI32 mRefCount; + + SEffectSystem(IQt3DSRenderContextCore &inContext) + : m_CoreContext(inContext) + , m_Context(NULL) + , m_Allocator(inContext.GetAllocator()) + , m_EffectClasses(inContext.GetAllocator(), "SEffectSystem::m_EffectClasses") + , m_EffectList(inContext.GetAllocator(), "SEffectSystem::m_EffectList") + , m_Contexts(inContext.GetAllocator(), "SEffectSystem::m_Contexts") + , m_ShaderMap(inContext.GetAllocator(), "SEffectSystem::m_ShaderMap") + , m_DepthStencilStates(inContext.GetAllocator(), "SEffectSystem::m_DepthStencilStates") + , mRefCount(0) + { + } + + ~SEffectSystem() + { + for (QT3DSU32 idx = 0, end = m_Contexts.size(); idx < end; ++idx) + NVDelete(m_Allocator, m_Contexts[idx]); + m_Contexts.clear(); + } + + SEffectContext &GetEffectContext(SEffect &inEffect) + { + if (inEffect.m_Context == NULL) { + inEffect.m_Context = + QT3DS_NEW(m_Allocator, SEffectContext)(inEffect.m_ClassName, + *m_Context, m_ResourceManager); + m_Contexts.push_back(inEffect.m_Context); + } + return *inEffect.m_Context; + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_CoreContext.GetAllocator()); + + SEffectClass *GetEffectClass(CRegisteredString inStr) + { + TEffectClassMap::iterator theIter = m_EffectClasses.find(inStr); + if (theIter != m_EffectClasses.end()) + return theIter->second; + return NULL; + } + const SEffectClass *GetEffectClass(CRegisteredString inStr) const + { + return const_cast(this)->GetEffectClass(inStr); + } + + bool IsEffectRegistered(CRegisteredString inStr) override + { + return GetEffectClass(inStr) != NULL; + } + NVConstDataRef GetRegisteredEffects() override + { + m_EffectList.clear(); + for (TEffectClassMap::iterator theIter = m_EffectClasses.begin(), + theEnd = m_EffectClasses.end(); + theIter != theEnd; ++theIter) + m_EffectList.push_back(theIter->first); + return m_EffectList; + } + + // Registers an effect that runs via a single GLSL file. + bool RegisterGLSLEffect(CRegisteredString inName, const char8_t *inPathToEffect, + NVConstDataRef inProperties) override + { + if (IsEffectRegistered(inName)) + return false; + + m_CoreContext.GetDynamicObjectSystemCore().Register(inName, inProperties, sizeof(SEffect), + GraphObjectTypes::Effect); + IDynamicObjectClass &theClass = + *m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); + + SEffectClass *theEffect = QT3DS_NEW(m_Allocator, SEffectClass)(m_Allocator, theClass); + m_EffectClasses.insert(eastl::make_pair(inName, theEffect)); + + // Setup the commands required to run this effect + StaticAssert<(sizeof(SBindShader) % 4 == 0)>::valid_expression(); + StaticAssert<(sizeof(SApplyInstanceValue) % 4 == 0)>::valid_expression(); + StaticAssert<(sizeof(SRender) % 4 == 0)>::valid_expression(); + + QT3DSU32 commandAllocationSize = sizeof(SBindTarget); + commandAllocationSize += sizeof(SBindShader); + commandAllocationSize += sizeof(SApplyInstanceValue) * inProperties.size(); + commandAllocationSize += sizeof(SRender); + + QT3DSU32 commandCount = 3 + inProperties.size(); + QT3DSU32 commandPtrAllocationSize = commandCount * sizeof(SCommand *); + QT3DSU32 allocationSize = Align8(commandAllocationSize) + commandPtrAllocationSize; + QT3DSU8 *startBuffer = + (QT3DSU8 *)m_Allocator.allocate(allocationSize, "dynamic::SCommand", __FILE__, __LINE__); + QT3DSU8 *dataBuffer = startBuffer; + // Setup the command buffer such that the ptrs to the commands and the commands themselves + // are + // all in the same block of memory. This enables quicker iteration (trivially quicker, most + // likely) + // but it also enables simpler memory management (single free). + // Furthermore, for a single glsl file the effect properties map precisely into the + // glsl file itself. + SCommand **theFirstCommandPtr = + (reinterpret_cast(dataBuffer + Align8(commandAllocationSize))); + SCommand **theCommandPtr = theFirstCommandPtr; + memZero(dataBuffer, commandAllocationSize); + + new (dataBuffer) SBindTarget(); + *theCommandPtr = (SCommand *)dataBuffer; + ++theCommandPtr; + dataBuffer += sizeof(SBindTarget); + + new (dataBuffer) SBindShader(m_CoreContext.GetStringTable().RegisterStr(inPathToEffect)); + *theCommandPtr = (SCommand *)dataBuffer; + ++theCommandPtr; + dataBuffer += sizeof(SBindShader); + + for (QT3DSU32 idx = 0, end = inProperties.size(); idx < end; ++idx) { + const SPropertyDefinition &theDefinition( + theEffect->m_DynamicClass->GetProperties()[idx]); + new (dataBuffer) SApplyInstanceValue(theDefinition.m_Name, theDefinition.m_DataType, + theDefinition.m_Offset); + *theCommandPtr = (SCommand *)dataBuffer; + ++theCommandPtr; + dataBuffer += sizeof(SApplyInstanceValue); + } + new (dataBuffer) SRender(false); + *theCommandPtr = (SCommand *)dataBuffer; + ++theCommandPtr; + dataBuffer += sizeof(SRender); + // Ensure we end up *exactly* where we expected to. + QT3DS_ASSERT(dataBuffer == startBuffer + commandAllocationSize); + QT3DS_ASSERT(theCommandPtr - theFirstCommandPtr == (int)inProperties.size() + 3); + m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands( + inName, NVConstDataRef(theFirstCommandPtr, commandCount)); + m_Allocator.deallocate(startBuffer); + return true; + } + + void SetEffectPropertyDefaultValue(CRegisteredString inName, + CRegisteredString inPropName, + NVConstDataRef inDefaultData) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetPropertyDefaultValue(inName, inPropName, + inDefaultData); + } + + void SetEffectPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName, + NVConstDataRef inNames) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetPropertyEnumNames(inName, inPropName, + inNames); + } + + bool RegisterEffect(CRegisteredString inName, + NVConstDataRef inProperties) override + { + if (IsEffectRegistered(inName)) + return false; + m_CoreContext.GetDynamicObjectSystemCore().Register(inName, inProperties, sizeof(SEffect), + GraphObjectTypes::Effect); + IDynamicObjectClass &theClass = + *m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); + SEffectClass *theEffect = QT3DS_NEW(m_Allocator, SEffectClass)(m_Allocator, theClass); + m_EffectClasses.insert(eastl::make_pair(inName, theEffect)); + return true; + } + + bool UnregisterEffect(CRegisteredString inName) override + { + if (!IsEffectRegistered(inName)) + return false; + + m_CoreContext.GetDynamicObjectSystemCore().Unregister(inName); + + TEffectClassMap::iterator iter = m_EffectClasses.find(inName); + if (iter != m_EffectClasses.end()) + m_EffectClasses.erase(iter); + + for (QT3DSU32 idx = 0, end = m_Contexts.size(); idx < end; ++idx) { + if (m_Contexts[idx]->m_ClassName == inName) + ReleaseEffectContext(m_Contexts[idx]); + } + return true; + } + + virtual NVConstDataRef + GetEffectPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName) const override + { + const SEffectClass *theClass = GetEffectClass(inName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + NVConstDataRef(); + } + const SPropertyDefinition *theDefinitionPtr = + theClass->m_DynamicClass->FindPropertyByName(inPropName); + if (theDefinitionPtr) + return theDefinitionPtr->m_EnumValueNames; + return NVConstDataRef(); + } + + virtual NVConstDataRef + GetEffectProperties(CRegisteredString inEffectName) const override + { + const SEffectClass *theClass = GetEffectClass(inEffectName); + if (theClass) + return theClass->m_DynamicClass->GetProperties(); + return NVConstDataRef(); + } + + void SetEffectPropertyTextureSettings(CRegisteredString inName, + CRegisteredString inPropName, + CRegisteredString inPropPath, + NVRenderTextureTypeValue::Enum inTexType, + NVRenderTextureCoordOp::Enum inCoordOp, + NVRenderTextureMagnifyingOp::Enum inMagFilterOp, + NVRenderTextureMinifyingOp::Enum inMinFilterOp) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetPropertyTextureSettings( + inName, inPropName, inPropPath, inTexType, inCoordOp, inMagFilterOp, inMinFilterOp); + } + + void SetEffectRequiresDepthTexture(CRegisteredString inEffectName, bool inValue) override + { + SEffectClass *theClass = GetEffectClass(inEffectName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + theClass->m_DynamicClass->SetRequiresDepthTexture(inValue); + } + + bool DoesEffectRequireDepthTexture(CRegisteredString inEffectName) const override + { + const SEffectClass *theClass = GetEffectClass(inEffectName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + return false; + } + return theClass->m_DynamicClass->RequiresDepthTexture(); + } + + void SetEffectRequiresCompilation(CRegisteredString inEffectName, bool inValue) override + { + SEffectClass *theClass = GetEffectClass(inEffectName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + return; + } + theClass->m_DynamicClass->SetRequiresCompilation(inValue); + } + + bool DoesEffectRequireCompilation(CRegisteredString inEffectName) const override + { + const SEffectClass *theClass = GetEffectClass(inEffectName); + if (theClass == NULL) { + QT3DS_ASSERT(false); + return false; + } + return theClass->m_DynamicClass->RequiresCompilation(); + } + + void SetEffectCommands(CRegisteredString inEffectName, + NVConstDataRef inCommands) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands(inEffectName, inCommands); + } + + virtual NVConstDataRef + GetEffectCommands(CRegisteredString inEffectName) const override + { + return m_CoreContext.GetDynamicObjectSystemCore().GetRenderCommands(inEffectName); + } + + SEffect *CreateEffectInstance(CRegisteredString inEffectName, + NVAllocatorCallback &inSceneGraphAllocator) override + { + SEffectClass *theClass = GetEffectClass(inEffectName); + if (theClass == NULL) + return NULL; + StaticAssert<(sizeof(SEffect) % 4 == 0)>::valid_expression(); + + SEffect *theEffect = (SEffect *)m_CoreContext.GetDynamicObjectSystemCore().CreateInstance( + inEffectName, inSceneGraphAllocator); + theEffect->Initialize(); + return theEffect; + } + + void AllocateBuffer(SEffect &inEffect, const SAllocateBuffer &inCommand, QT3DSU32 inFinalWidth, + QT3DSU32 inFinalHeight, NVRenderTextureFormats::Enum inSourceTextureFormat) + { + // Check to see if it is already allocated and if it is, is it the correct size. If both of + // these assumptions hold, then we are good. + NVRenderTexture2D *theBufferTexture = NULL; + QT3DSU32 theWidth = + ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalWidth * inCommand.m_SizeMultiplier)); + QT3DSU32 theHeight = + ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalHeight * inCommand.m_SizeMultiplier)); + NVRenderTextureFormats::Enum resultFormat = inCommand.m_Format; + if (resultFormat == NVRenderTextureFormats::Unknown) + resultFormat = inSourceTextureFormat; + + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + // size intentionally requiried every loop; + QT3DSU32 bufferIdx = theContext.FindBuffer(inCommand.m_Name); + if (bufferIdx < theContext.m_AllocatedBuffers.size()) { + SAllocatedBufferEntry &theEntry(theContext.m_AllocatedBuffers[bufferIdx]); + STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails(); + if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight + && theDetails.m_Format == resultFormat) { + theBufferTexture = theEntry.m_Texture; + } else { + theContext.ReleaseBuffer(bufferIdx); + } + } + } + if (theBufferTexture == NULL) { + SEffectContext &theContext(GetEffectContext(inEffect)); + NVRenderFrameBuffer *theFB(m_ResourceManager->AllocateFrameBuffer()); + NVRenderTexture2D *theTexture( + m_ResourceManager->AllocateTexture2D(theWidth, theHeight, resultFormat)); + theTexture->SetMagFilter(inCommand.m_FilterOp); + theTexture->SetMinFilter( + static_cast(inCommand.m_FilterOp)); + theTexture->SetTextureWrapS(inCommand.m_TexCoordOp); + theTexture->SetTextureWrapT(inCommand.m_TexCoordOp); + theFB->Attach(NVRenderFrameBufferAttachments::Color0, *theTexture); + theContext.m_AllocatedBuffers.push_back(SAllocatedBufferEntry( + inCommand.m_Name, *theFB, *theTexture, inCommand.m_BufferFlags)); + theBufferTexture = theTexture; + } + } + + void AllocateImage(SEffect &inEffect, const SAllocateImage &inCommand, QT3DSU32 inFinalWidth, + QT3DSU32 inFinalHeight) + { + NVRenderImage2D *theImage = NULL; + QT3DSU32 theWidth = + ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalWidth * inCommand.m_SizeMultiplier)); + QT3DSU32 theHeight = + ITextRenderer::NextMultipleOf4((QT3DSU32)(inFinalHeight * inCommand.m_SizeMultiplier)); + + QT3DS_ASSERT(inCommand.m_Format != NVRenderTextureFormats::Unknown); + + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + // size intentionally requiried every loop; + QT3DSU32 imageIdx = theContext.FindImage(inCommand.m_Name); + if (imageIdx < theContext.m_AllocatedImages.size()) { + SAllocatedImageEntry &theEntry(theContext.m_AllocatedImages[imageIdx]); + STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails(); + if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight + && theDetails.m_Format == inCommand.m_Format) { + theImage = theEntry.m_Image; + } else { + theContext.ReleaseImage(imageIdx); + } + } + } + + if (theImage == NULL) { + SEffectContext &theContext(GetEffectContext(inEffect)); + // allocate an immutable texture + NVRenderTexture2D *theTexture(m_ResourceManager->AllocateTexture2D( + theWidth, theHeight, inCommand.m_Format, 1, true)); + theTexture->SetMagFilter(inCommand.m_FilterOp); + theTexture->SetMinFilter( + static_cast(inCommand.m_FilterOp)); + theTexture->SetTextureWrapS(inCommand.m_TexCoordOp); + theTexture->SetTextureWrapT(inCommand.m_TexCoordOp); + NVRenderImage2D *theImage = + (m_ResourceManager->AllocateImage2D(theTexture, inCommand.m_Access)); + theContext.m_AllocatedImages.push_back(SAllocatedImageEntry( + inCommand.m_Name, *theImage, *theTexture, inCommand.m_BufferFlags)); + } + } + + void AllocateDataBuffer(SEffect &inEffect, const SAllocateDataBuffer &inCommand) + { + QT3DSU32 theBufferSize = (QT3DSU32)inCommand.m_Size; + QT3DS_ASSERT(theBufferSize); + qt3ds::render::NVRenderDataBuffer *theDataBuffer = NULL; + qt3ds::render::NVRenderDataBuffer *theDataWrapBuffer = NULL; + + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + // size intentionally requiried every loop; + QT3DSU32 bufferIdx = theContext.FindDataBuffer(inCommand.m_Name); + if (bufferIdx < theContext.m_AllocatedDataBuffers.size()) { + SAllocatedDataBufferEntry &theEntry(theContext.m_AllocatedDataBuffers[bufferIdx]); + if (theEntry.m_BufferType == inCommand.m_DataBufferType + && theEntry.m_BufferData.size() == theBufferSize) { + theDataBuffer = theEntry.m_DataBuffer; + } else { + // if type and size don't match something is wrong + QT3DS_ASSERT(false); + } + } + } + + if (theDataBuffer == NULL) { + SEffectContext &theContext(GetEffectContext(inEffect)); + NVRenderContext &theRenderContext(m_Context->GetRenderContext()); + QT3DSU8 *initialData = (QT3DSU8 *)theContext.m_Context.GetAllocator().allocate( + theBufferSize, "SEffectContext::AllocateDataBuffer", __FILE__, __LINE__); + NVDataRef data((QT3DSU8 *)initialData, theBufferSize); + memset(initialData, 0x0L, theBufferSize); + if (inCommand.m_DataBufferType == NVRenderBufferBindValues::Storage) { + theDataBuffer = theRenderContext.CreateStorageBuffer( + inCommand.m_Name, qt3ds::render::NVRenderBufferUsageType::Dynamic, theBufferSize, + data, NULL); + } else if (inCommand.m_DataBufferType == NVRenderBufferBindValues::Draw_Indirect) { + QT3DS_ASSERT(theBufferSize == sizeof(qt3ds::render::DrawArraysIndirectCommand)); + // init a draw call + QT3DSU32 *pIndirectDrawCall = (QT3DSU32 *)initialData; + // vertex count we draw points right now only + // the rest we fill in by GPU + pIndirectDrawCall[0] = 1; + theDataBuffer = theRenderContext.CreateDrawIndirectBuffer( + qt3ds::render::NVRenderBufferUsageType::Dynamic, theBufferSize, data); + } else + QT3DS_ASSERT(false); + + theContext.m_AllocatedDataBuffers.push_back(SAllocatedDataBufferEntry( + inCommand.m_Name, *theDataBuffer, inCommand.m_DataBufferType, data, + inCommand.m_BufferFlags)); + + // create wrapper buffer + if (inCommand.m_DataBufferWrapType == NVRenderBufferBindValues::Storage + && inCommand.m_WrapName && theDataBuffer) { + theDataWrapBuffer = theRenderContext.CreateStorageBuffer( + inCommand.m_WrapName, qt3ds::render::NVRenderBufferUsageType::Dynamic, + theBufferSize, data, theDataBuffer); + theContext.m_AllocatedDataBuffers.push_back(SAllocatedDataBufferEntry( + inCommand.m_WrapName, *theDataWrapBuffer, inCommand.m_DataBufferWrapType, + NVDataRef(), inCommand.m_BufferFlags)); + } + } + } + + NVRenderTexture2D *FindTexture(SEffect &inEffect, CRegisteredString inName) + { + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + QT3DSU32 bufferIdx = theContext.FindBuffer(inName); + if (bufferIdx < theContext.m_AllocatedBuffers.size()) { + return theContext.m_AllocatedBuffers[bufferIdx].m_Texture; + } + } + QT3DS_ASSERT(false); + return NULL; + } + + NVRenderFrameBuffer *BindBuffer(SEffect &inEffect, const SBindBuffer &inCommand, + QT3DSMat44 &outMVP, QT3DSVec2 &outDestSize) + { + NVRenderFrameBuffer *theBuffer = NULL; + NVRenderTexture2D *theTexture = NULL; + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + QT3DSU32 bufferIdx = theContext.FindBuffer(inCommand.m_BufferName); + if (bufferIdx < theContext.m_AllocatedBuffers.size()) { + theBuffer = theContext.m_AllocatedBuffers[bufferIdx].m_FrameBuffer; + theTexture = theContext.m_AllocatedBuffers[bufferIdx].m_Texture; + theContext.m_AllocatedBuffers[bufferIdx].m_NeedsClear = false; + } + } + if (theBuffer == NULL) { + qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", + inEffect.m_ClassName.c_str(), inCommand.m_BufferName.c_str()); + QString errorMsg = QObject::tr("Failed to compile \"%1\" effect.\nConsider" + " removing it from the presentation.") + .arg(inEffect.m_ClassName.c_str()); + QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); + outMVP = QT3DSMat44::createIdentity(); + return NULL; + } + + if (theTexture) { + SCamera::SetupOrthographicCameraForOffscreenRender(*theTexture, outMVP); + STextureDetails theDetails(theTexture->GetTextureDetails()); + m_Context->GetRenderContext().SetViewport( + NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); + outDestSize = QT3DSVec2((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); + } + + return theBuffer; + } + + SEffectShader *BindShader(CRegisteredString &inEffectId, const SBindShader &inCommand) + { + SEffectClass *theClass = GetEffectClass(inEffectId); + if (!theClass) { + QT3DS_ASSERT(false); + return NULL; + } + + bool forceCompilation = theClass->m_DynamicClass->RequiresCompilation(); + + eastl::pair> theInserter( + TStrStrPair(inCommand.m_ShaderPath, inCommand.m_ShaderDefine), + NVScopedRefCounted()); + eastl::pair theInsertResult(m_ShaderMap.insert(theInserter)); + + if (theInsertResult.second || forceCompilation) { + NVRenderShaderProgram *theProgram = + m_Context->GetDynamicObjectSystem() + .GetShaderProgram(inCommand.m_ShaderPath, inCommand.m_ShaderDefine, + TShaderFeatureSet(), SDynamicShaderProgramFlags(), + forceCompilation).first; + if (theProgram) + theInsertResult.first->second = QT3DS_NEW(m_Allocator, SEffectShader)(*theProgram); + } + if (theInsertResult.first->second) { + NVRenderContext &theContext(m_Context->GetRenderContext()); + theContext.SetActiveShader(theInsertResult.first->second->m_Shader); + } + + return theInsertResult.first->second; + } + + void DoApplyInstanceValue(SEffect &inEffect, QT3DSU8 *inDataPtr, CRegisteredString inPropertyName, + NVRenderShaderDataTypes::Enum inPropertyType, + NVRenderShaderProgram &inShader, + const SPropertyDefinition &inDefinition) + { + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(inPropertyName); + using namespace qt3ds::render; + if (theConstant) { + if (theConstant->GetShaderConstantType() == inPropertyType) { + if (inPropertyType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + StaticAssert::valid_expression(); + CRegisteredString *theStrPtr = reinterpret_cast(inDataPtr); + IBufferManager &theBufferManager(m_Context->GetBufferManager()); + IOffscreenRenderManager &theOffscreenRenderer( + m_Context->GetOffscreenRenderManager()); + bool needsAlphaMultiply = true; + NVRenderTexture2D *theTexture = NULL; + if (theStrPtr->IsValid()) { + if (theOffscreenRenderer.HasOffscreenRenderer(*theStrPtr)) { + SOffscreenRenderResult theResult = + theOffscreenRenderer.GetRenderedItem(*theStrPtr); + needsAlphaMultiply = false; + theTexture = theResult.m_Texture; + } else { + SImageTextureData theTextureData = + theBufferManager.LoadRenderImage(*theStrPtr); + needsAlphaMultiply = true; + theTexture = theTextureData.m_Texture; + } + } + GetEffectContext(inEffect).SetTexture( + inShader, inPropertyName, theTexture, needsAlphaMultiply, + m_TextureStringBuilder, m_TextureStringBuilder2, &inDefinition); + } else if (inPropertyType == NVRenderShaderDataTypes::NVRenderImage2DPtr) { + StaticAssert::valid_expression(); + NVRenderImage2D *theImage = NULL; + GetEffectContext(inEffect).SetImage(inShader, inPropertyName, theImage); + } else if (inPropertyType == NVRenderShaderDataTypes::NVRenderDataBufferPtr) { + // we don't handle this here + } else { + switch (inPropertyType) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ + case NVRenderShaderDataTypes::type: \ + inShader.SetPropertyValue(theConstant, *(reinterpret_cast(inDataPtr))); \ + break; + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + QT3DS_ASSERT(false); + break; + } + } + } else { + qCCritical(INVALID_OPERATION, + "Effect ApplyInstanceValue command datatype " + "and shader datatypes differ for property %s", + inPropertyName.c_str()); + QT3DS_ASSERT(false); + } + } + } + + void ApplyInstanceValue(SEffect &inEffect, SEffectClass &inClass, + NVRenderShaderProgram &inShader, const SApplyInstanceValue &inCommand) + { + // sanity check + if (inCommand.m_PropertyName.IsValid()) { + bool canGetData = + inCommand.m_ValueOffset + getSizeofShaderDataType(inCommand.m_ValueType) + <= inEffect.m_DataSectionByteSize; + if (canGetData == false) { + QT3DS_ASSERT(false); + return; + } + QT3DSU8 *dataPtr = inEffect.GetDataSectionBegin() + inCommand.m_ValueOffset; + const SPropertyDefinition *theDefinition = + inClass.m_DynamicClass->FindPropertyByName(inCommand.m_PropertyName); + if (theDefinition) + DoApplyInstanceValue(inEffect, dataPtr, inCommand.m_PropertyName, + inCommand.m_ValueType, inShader, *theDefinition); + } else { + NVConstDataRef theDefs = inClass.m_DynamicClass->GetProperties(); + for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) { + const SPropertyDefinition &theDefinition(theDefs[idx]); + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(theDefinition.m_Name); + + // This is fine, the property wasn't found and we continue, no problem. + if (!theConstant) + continue; + QT3DSU8 *dataPtr = inEffect.GetDataSectionBegin() + theDefinition.m_Offset; + DoApplyInstanceValue(inEffect, dataPtr, theDefinition.m_Name, + theDefinition.m_DataType, inShader, theDefinition); + } + } + } + + void ApplyValue(SEffect &inEffect, SEffectClass &inClass, NVRenderShaderProgram &inShader, + const SApplyValue &inCommand) + { + if (inCommand.m_PropertyName.IsValid()) { + QT3DSU8 *dataPtr = inCommand.m_Value.mData; + const SPropertyDefinition *theDefinition = + inClass.m_DynamicClass->FindPropertyByName(inCommand.m_PropertyName); + if (theDefinition) + DoApplyInstanceValue(inEffect, dataPtr, inCommand.m_PropertyName, + inCommand.m_ValueType, inShader, *theDefinition); + } + } + + bool ApplyBlending(const SApplyBlending &inCommand) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + + theContext.SetBlendingEnabled(true); + + qt3ds::render::NVRenderBlendFunctionArgument blendFunc = + qt3ds::render::NVRenderBlendFunctionArgument( + inCommand.m_SrcBlendFunc, inCommand.m_DstBlendFunc, inCommand.m_SrcBlendFunc, + inCommand.m_DstBlendFunc); + + qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, + NVRenderBlendEquation::Add); + + theContext.SetBlendFunction(blendFunc); + theContext.SetBlendEquation(blendEqu); + + return true; + } + + // This has the potential to change the source texture for the current render pass + SEffectTextureData ApplyBufferValue(SEffect &inEffect, NVRenderShaderProgram &inShader, + const SApplyBufferValue &inCommand, + NVRenderTexture2D &inSourceTexture, + SEffectTextureData inCurrentSourceTexture) + { + SEffectTextureData theTextureToBind; + if (inCommand.m_BufferName.IsValid()) { + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + QT3DSU32 bufferIdx = theContext.FindBuffer(inCommand.m_BufferName); + if (bufferIdx < theContext.m_AllocatedBuffers.size()) { + SAllocatedBufferEntry &theEntry(theContext.m_AllocatedBuffers[bufferIdx]); + if (theEntry.m_NeedsClear) { + NVRenderContext &theRenderContext(m_Context->GetRenderContext()); + + theRenderContext.SetRenderTarget(theEntry.m_FrameBuffer); + // Note that depth/stencil buffers need an explicit clear in their bind + // commands in order to ensure + // we clear the least amount of information possible. + + if (theEntry.m_Texture) { + NVRenderTextureFormats::Enum theTextureFormat = + theEntry.m_Texture->GetTextureDetails().m_Format; + if (theTextureFormat != NVRenderTextureFormats::Depth16 + && theTextureFormat != NVRenderTextureFormats::Depth24 + && theTextureFormat != NVRenderTextureFormats::Depth32 + && theTextureFormat != NVRenderTextureFormats::Depth24Stencil8) { + NVRenderContextScopedProperty __clearColor( + theRenderContext, &NVRenderContext::GetClearColor, + &NVRenderContext::SetClearColor, QT3DSVec4(0.0f)); + theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); + } + } + theEntry.m_NeedsClear = false; + } + theTextureToBind = SEffectTextureData(theEntry.m_Texture, false); + } + } + if (theTextureToBind.m_Texture == NULL) { + QT3DS_ASSERT(false); + qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", + inEffect.m_ClassName.c_str(), inCommand.m_BufferName.c_str()); + QT3DS_ASSERT(false); + } + } else // no name means bind the source + theTextureToBind = SEffectTextureData(&inSourceTexture, false); + + if (inCommand.m_ParamName.IsValid()) { + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(inCommand.m_ParamName); + + if (theConstant) { + if (theConstant->GetShaderConstantType() + != NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + qCCritical(INVALID_OPERATION, + "Effect %s: Binding buffer to parameter %s that is not a texture", + inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); + QT3DS_ASSERT(false); + } else { + GetEffectContext(inEffect).SetTexture( + inShader, inCommand.m_ParamName, theTextureToBind.m_Texture, + theTextureToBind.m_NeedsAlphaMultiply, m_TextureStringBuilder, + m_TextureStringBuilder2); + } + } + return inCurrentSourceTexture; + } else { + return theTextureToBind; + } + } + + void ApplyDepthValue(SEffect &inEffect, NVRenderShaderProgram &inShader, + const SApplyDepthValue &inCommand, NVRenderTexture2D *inTexture) + { + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(inCommand.m_ParamName); + + if (theConstant) { + if (theConstant->GetShaderConstantType() + != NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + qCCritical(INVALID_OPERATION, + "Effect %s: Binding buffer to parameter %s that is not a texture", + inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); + QT3DS_ASSERT(false); + } else { + GetEffectContext(inEffect).SetTexture(inShader, inCommand.m_ParamName, inTexture, + false, m_TextureStringBuilder, + m_TextureStringBuilder2); + } + } + } + + void ApplyImageValue(SEffect &inEffect, NVRenderShaderProgram &inShader, + const SApplyImageValue &inCommand) + { + SAllocatedImageEntry theImageToBind; + if (inCommand.m_ImageName.IsValid()) { + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + QT3DSU32 bufferIdx = theContext.FindImage(inCommand.m_ImageName); + if (bufferIdx < theContext.m_AllocatedImages.size()) { + theImageToBind = SAllocatedImageEntry(theContext.m_AllocatedImages[bufferIdx]); + } + } + } + + if (theImageToBind.m_Image == NULL) { + qCCritical(INVALID_OPERATION, "Effect %s: Failed to find image %s for bind", + inEffect.m_ClassName.c_str(), inCommand.m_ImageName.c_str()); + QT3DS_ASSERT(false); + } + + if (inCommand.m_ParamName.IsValid()) { + qt3ds::render::NVRenderShaderConstantBase *theConstant = + inShader.GetShaderConstant(inCommand.m_ParamName); + + if (theConstant) { + if (inCommand.m_NeedSync) { + NVRenderBufferBarrierFlags flags( + qt3ds::render::NVRenderBufferBarrierValues::TextureFetch + | qt3ds::render::NVRenderBufferBarrierValues::TextureUpdate); + inShader.GetRenderContext().SetMemoryBarrier(flags); + } + + if (theConstant->GetShaderConstantType() + == NVRenderShaderDataTypes::NVRenderImage2DPtr + && !inCommand.m_BindAsTexture) { + GetEffectContext(inEffect).SetImage(inShader, inCommand.m_ParamName, + theImageToBind.m_Image); + } else if (theConstant->GetShaderConstantType() + == NVRenderShaderDataTypes::NVRenderTexture2DPtr + && inCommand.m_BindAsTexture) { + GetEffectContext(inEffect).SetTexture( + inShader, inCommand.m_ParamName, theImageToBind.m_Texture, false, + m_TextureStringBuilder, m_TextureStringBuilder2); + } else { + qCCritical(INVALID_OPERATION, + "Effect %s: Binding buffer to parameter %s that is not a texture", + inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); + QT3DS_ASSERT(false); + } + } + } + } + + void ApplyDataBufferValue(SEffect &inEffect, NVRenderShaderProgram &inShader, + const SApplyDataBufferValue &inCommand) + { + SAllocatedDataBufferEntry theBufferToBind; + if (inCommand.m_ParamName.IsValid()) { + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + QT3DSU32 bufferIdx = theContext.FindDataBuffer(inCommand.m_ParamName); + if (bufferIdx < theContext.m_AllocatedDataBuffers.size()) { + theBufferToBind = + SAllocatedDataBufferEntry(theContext.m_AllocatedDataBuffers[bufferIdx]); + if (theBufferToBind.m_NeedsClear) { + NVDataRef pData = theBufferToBind.m_DataBuffer->MapBuffer(); + memset(pData.begin(), 0x0L, theBufferToBind.m_BufferData.size()); + theBufferToBind.m_DataBuffer->UnmapBuffer(); + theBufferToBind.m_NeedsClear = false; + } + } + } + + if (theBufferToBind.m_DataBuffer == NULL) { + qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind", + inEffect.m_ClassName.c_str(), inCommand.m_ParamName.c_str()); + QT3DS_ASSERT(false); + } + + qt3ds::render::NVRenderShaderBufferBase *theConstant = + inShader.GetShaderBuffer(inCommand.m_ParamName); + + if (theConstant) { + GetEffectContext(inEffect).SetDataBuffer(inShader, inCommand.m_ParamName, + theBufferToBind.m_DataBuffer); + } else if (theBufferToBind.m_BufferType + == qt3ds::render::NVRenderBufferBindValues::Draw_Indirect) { + // since we filled part of this buffer on the GPU we need a sync before usage + NVRenderBufferBarrierFlags flags( + qt3ds::render::NVRenderBufferBarrierValues::CommandBuffer); + inShader.GetRenderContext().SetMemoryBarrier(flags); + } + } + } + + void ApplyRenderStateValue(NVRenderFrameBuffer *inTarget, + NVRenderTexture2D *inDepthStencilTexture, + const SApplyRenderState &theCommand) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + QT3DSU32 inState = (QT3DSU32)theCommand.m_RenderState; + bool inEnable = theCommand.m_Enabled; + + switch (inState) { + case NVRenderState::StencilTest: { + if (inEnable && inTarget) { + inTarget->Attach(NVRenderFrameBufferAttachments::DepthStencil, + *inDepthStencilTexture); + } else if (inTarget) { + inTarget->Attach(NVRenderFrameBufferAttachments::DepthStencil, + NVRenderTextureOrRenderBuffer()); + } + + theContext.SetStencilTestEnabled(inEnable); + } break; + default: + QT3DS_ASSERT(false); + break; + } + } + + static bool CompareDepthStencilState(NVRenderDepthStencilState &inState, + SDepthStencil &inStencil) + { + qt3ds::render::NVRenderStencilFunctionArgument theFunction = + inState.GetStencilFunc(qt3ds::render::NVRenderFaces::Front); + qt3ds::render::NVRenderStencilOperationArgument theOperation = + inState.GetStencilOp(qt3ds::render::NVRenderFaces::Front); + + return theFunction.m_Function == inStencil.m_StencilFunction + && theFunction.m_Mask == inStencil.m_Mask + && theFunction.m_ReferenceValue == inStencil.m_Reference + && theOperation.m_StencilFail == inStencil.m_StencilFailOperation + && theOperation.m_DepthFail == inStencil.m_DepthFailOperation + && theOperation.m_DepthPass == inStencil.m_DepthPassOperation; + } + + void RenderPass(SEffectShader &inShader, const QT3DSMat44 &inMVP, + SEffectTextureData inSourceTexture, NVRenderFrameBuffer *inFrameBuffer, + QT3DSVec2 &inDestSize, const QT3DSVec2 &inCameraClipRange, + NVRenderTexture2D *inDepthStencil, Option inDepthStencilCommand, + bool drawIndirect) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + theContext.SetRenderTarget(inFrameBuffer); + if (inDepthStencil && inFrameBuffer) { + inFrameBuffer->Attach(NVRenderFrameBufferAttachments::DepthStencil, *inDepthStencil); + if (inDepthStencilCommand.hasValue()) { + SDepthStencil &theDepthStencil(*inDepthStencilCommand); + QT3DSU32 clearFlags = 0; + if (theDepthStencil.m_Flags.HasClearStencil()) + clearFlags |= NVRenderClearValues::Stencil; + if (theDepthStencil.m_Flags.HasClearDepth()) + clearFlags |= NVRenderClearValues::Depth; + + if (clearFlags) + theContext.Clear(qt3ds::render::NVRenderClearFlags(clearFlags)); + + NVRenderDepthStencilState *targetState = NULL; + for (QT3DSU32 idx = 0, end = m_DepthStencilStates.size(); + idx < end && targetState == NULL; ++idx) { + NVRenderDepthStencilState &theState = *m_DepthStencilStates[idx]; + if (CompareDepthStencilState(theState, theDepthStencil)) + targetState = &theState; + } + if (targetState == NULL) { + qt3ds::render::NVRenderStencilFunctionArgument theFunctionArg( + theDepthStencil.m_StencilFunction, theDepthStencil.m_Reference, + theDepthStencil.m_Mask); + qt3ds::render::NVRenderStencilOperationArgument theOpArg( + theDepthStencil.m_StencilFailOperation, + theDepthStencil.m_DepthFailOperation, theDepthStencil.m_DepthPassOperation); + targetState = theContext.CreateDepthStencilState( + theContext.IsDepthTestEnabled(), theContext.IsDepthWriteEnabled(), + theContext.GetDepthFunction(), true, theFunctionArg, theFunctionArg, + theOpArg, theOpArg); + m_DepthStencilStates.push_back(targetState); + } + theContext.SetDepthStencilState(targetState); + } + } + + theContext.SetActiveShader(inShader.m_Shader); + inShader.m_MVP.Set(inMVP); + if (inSourceTexture.m_Texture) { + inShader.m_TextureEntry.Set(inSourceTexture.m_Texture, + inSourceTexture.m_NeedsAlphaMultiply, NULL); + } else { + qCCritical(INTERNAL_ERROR, "Failed to setup pass due to null source texture"); + QT3DS_ASSERT(false); + } + inShader.m_FragColorAlphaSettings.Set(QT3DSVec2(1.0f, 0.0f)); + inShader.m_DestSize.Set(inDestSize); + if (inShader.m_AppFrame.IsValid()) + inShader.m_AppFrame.Set((QT3DSF32)m_Context->GetFrameCount()); + if (inShader.m_FPS.IsValid()) + inShader.m_FPS.Set((QT3DSF32)m_Context->GetFPS().first); + if (inShader.m_CameraClipRange.IsValid()) + inShader.m_CameraClipRange.Set(inCameraClipRange); + + if (!drawIndirect) + m_Context->GetRenderer().RenderQuad(); + else + m_Context->GetRenderer().RenderPointsIndirect(); + + if (inDepthStencil && inFrameBuffer) { + inFrameBuffer->Attach(NVRenderFrameBufferAttachments::DepthStencil, + NVRenderTextureOrRenderBuffer()); + theContext.SetDepthStencilState(m_DefaultStencilState); + } + } + + void DoRenderEffect(SEffect &inEffect, SEffectClass &inClass, + NVRenderTexture2D &inSourceTexture, QT3DSMat44 &inMVP, + NVRenderFrameBuffer *inTarget, bool inEnableBlendWhenRenderToTarget, + NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inDepthStencilTexture, + const QT3DSVec2 inCameraClipRange) + { + // Run through the effect commands and render the effect. + // NVRenderTexture2D* theCurrentTexture(&inSourceTexture); + NVRenderContext &theContext = m_Context->GetRenderContext(); + + // Context variables that are updated during the course of a pass. + SEffectTextureData theCurrentSourceTexture(&inSourceTexture, false); + NVRenderTexture2D *theCurrentDepthStencilTexture = NULL; + NVRenderFrameBuffer *theCurrentRenderTarget(inTarget); + SEffectShader *theCurrentShader(NULL); + NVRenderRect theOriginalViewport(theContext.GetViewport()); + bool wasScissorEnabled = theContext.IsScissorTestEnabled(); + bool wasBlendingEnabled = theContext.IsBlendingEnabled(); + // save current blending setup + qt3ds::render::NVRenderBlendFunctionArgument theBlendFunc = theContext.GetBlendFunction(); + qt3ds::render::NVRenderBlendEquationArgument theBlendEqu = theContext.GetBlendEquation(); + bool intermediateBlendingEnabled = false; + STextureDetails theDetails(inSourceTexture.GetTextureDetails()); + QT3DSU32 theFinalWidth = (QT3DSU32)(theDetails.m_Width); + QT3DSU32 theFinalHeight = (QT3DSU32)(theDetails.m_Height); + QT3DSVec2 theDestSize; + { + // Ensure no matter the command run goes we replace the rendering system to some + // semblance of the approprate + // setting. + NVRenderContextScopedProperty __framebuffer( + theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + NVRenderContextScopedProperty __viewport( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); + NVRenderContextScopedProperty __scissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled); + NVRenderContextScopedProperty __stencilTest( + theContext, &NVRenderContext::IsStencilTestEnabled, + &NVRenderContext::SetStencilTestEnabled); + NVRenderContextScopedProperty __depthFunction( + theContext, &NVRenderContext::GetDepthFunction, &NVRenderContext::SetDepthFunction); + Option theCurrentDepthStencil; + + theContext.SetScissorTestEnabled(false); + theContext.SetBlendingEnabled(false); + theContext.SetCullingEnabled(false); + theContext.SetDepthTestEnabled(false); + theContext.SetDepthWriteEnabled(false); + + QT3DSMat44 theMVP(QT3DSMat44::createIdentity()); + NVConstDataRef theCommands = + inClass.m_DynamicClass->GetRenderCommands(); + for (QT3DSU32 commandIdx = 0, commandEnd = theCommands.size(); commandIdx < commandEnd; + ++commandIdx) { + const SCommand &theCommand(*theCommands[commandIdx]); + switch (theCommand.m_Type) { + case CommandTypes::AllocateBuffer: + AllocateBuffer(inEffect, static_cast(theCommand), + theFinalWidth, theFinalHeight, theDetails.m_Format); + break; + + case CommandTypes::AllocateImage: + AllocateImage(inEffect, static_cast(theCommand), + theFinalWidth, theFinalHeight); + break; + + case CommandTypes::AllocateDataBuffer: + AllocateDataBuffer(inEffect, + static_cast(theCommand)); + break; + + case CommandTypes::BindBuffer: + theCurrentRenderTarget = + BindBuffer(inEffect, static_cast(theCommand), theMVP, + theDestSize); + break; + + case CommandTypes::BindTarget: { + m_Context->GetRenderContext().SetRenderTarget(inTarget); + theCurrentRenderTarget = inTarget; + theMVP = inMVP; + theContext.SetViewport(theOriginalViewport); + theDestSize = QT3DSVec2((QT3DSF32)theFinalWidth, (QT3DSF32)theFinalHeight); + // This isn't necessary if we are rendering to an offscreen buffer and not + // compositing + // with other objects. + if (inEnableBlendWhenRenderToTarget) { + theContext.SetBlendingEnabled(wasBlendingEnabled); + theContext.SetScissorTestEnabled(wasScissorEnabled); + // The blending setup was done before we apply the effect + theContext.SetBlendFunction(theBlendFunc); + theContext.SetBlendEquation(theBlendEqu); + } + } break; + case CommandTypes::BindShader: + theCurrentShader = BindShader(inEffect.m_ClassName, + static_cast(theCommand)); + break; + case CommandTypes::ApplyInstanceValue: + if (theCurrentShader) + ApplyInstanceValue(inEffect, inClass, *theCurrentShader->m_Shader, + static_cast(theCommand)); + break; + case CommandTypes::ApplyValue: + if (theCurrentShader) + ApplyValue(inEffect, inClass, *theCurrentShader->m_Shader, + static_cast(theCommand)); + break; + case CommandTypes::ApplyBlending: + intermediateBlendingEnabled = + ApplyBlending(static_cast(theCommand)); + break; + case CommandTypes::ApplyBufferValue: + if (theCurrentShader) + theCurrentSourceTexture = + ApplyBufferValue(inEffect, *theCurrentShader->m_Shader, + static_cast(theCommand), + inSourceTexture, theCurrentSourceTexture); + break; + case CommandTypes::ApplyDepthValue: + if (theCurrentShader) + ApplyDepthValue(inEffect, *theCurrentShader->m_Shader, + static_cast(theCommand), + inDepthTexture); + if (!inDepthTexture) { + qCCritical(INVALID_OPERATION, + "Depth value command detected but no " + "depth buffer provided for effect %s", + inEffect.m_ClassName.c_str()); + QT3DS_ASSERT(false); + } + break; + case CommandTypes::ApplyImageValue: + if (theCurrentShader) + ApplyImageValue(inEffect, *theCurrentShader->m_Shader, + static_cast(theCommand)); + break; + case CommandTypes::ApplyDataBufferValue: + if (theCurrentShader) + ApplyDataBufferValue( + inEffect, *theCurrentShader->m_Shader, + static_cast(theCommand)); + break; + case CommandTypes::DepthStencil: { + const SDepthStencil &theDepthStencil = + static_cast(theCommand); + theCurrentDepthStencilTexture = + FindTexture(inEffect, theDepthStencil.m_BufferName); + if (theCurrentDepthStencilTexture) + theCurrentDepthStencil = theDepthStencil; + } break; + case CommandTypes::Render: + if (theCurrentShader && theCurrentSourceTexture.m_Texture) { + RenderPass(*theCurrentShader, theMVP, theCurrentSourceTexture, + theCurrentRenderTarget, theDestSize, inCameraClipRange, + theCurrentDepthStencilTexture, theCurrentDepthStencil, + static_cast(theCommand).m_DrawIndirect); + } + // Reset the source texture regardless + theCurrentSourceTexture = SEffectTextureData(&inSourceTexture, false); + theCurrentDepthStencilTexture = NULL; + theCurrentDepthStencil = Option(); + // reset intermediate blending state + if (intermediateBlendingEnabled) { + theContext.SetBlendingEnabled(false); + intermediateBlendingEnabled = false; + } + break; + case CommandTypes::ApplyRenderState: + ApplyRenderStateValue(theCurrentRenderTarget, inDepthStencilTexture, + static_cast(theCommand)); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + SetEffectRequiresCompilation(inEffect.m_ClassName, false); + + // reset to default stencil state + if (inDepthStencilTexture) { + theContext.SetDepthStencilState(m_DefaultStencilState); + } + + // Release any per-frame buffers + if (inEffect.m_Context) { + SEffectContext &theContext(*inEffect.m_Context); + // Query for size on every loop intentional + for (QT3DSU32 idx = 0; idx < theContext.m_AllocatedBuffers.size(); ++idx) { + if (theContext.m_AllocatedBuffers[idx].m_Flags.IsSceneLifetime() == false) { + theContext.ReleaseBuffer(idx); + --idx; + } + } + for (QT3DSU32 idx = 0; idx < theContext.m_AllocatedImages.size(); ++idx) { + if (theContext.m_AllocatedImages[idx].m_Flags.IsSceneLifetime() == false) { + theContext.ReleaseImage(idx); + --idx; + } + } + } + } + } + + NVRenderTexture2D *RenderEffect(SEffectRenderArgument inRenderArgument) override + { + SEffectClass *theClass = GetEffectClass(inRenderArgument.m_Effect.m_ClassName); + if (!theClass) { + QT3DS_ASSERT(false); + return NULL; + } + QT3DSMat44 theMVP; + SCamera::SetupOrthographicCameraForOffscreenRender(inRenderArgument.m_ColorBuffer, theMVP); + // setup a render target + NVRenderContext &theContext(m_Context->GetRenderContext()); + IResourceManager &theManager(m_Context->GetResourceManager()); + NVRenderContextScopedProperty __framebuffer( + theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + STextureDetails theDetails(inRenderArgument.m_ColorBuffer.GetTextureDetails()); + QT3DSU32 theFinalWidth = ITextRenderer::NextMultipleOf4((QT3DSU32)(theDetails.m_Width)); + QT3DSU32 theFinalHeight = ITextRenderer::NextMultipleOf4((QT3DSU32)(theDetails.m_Height)); + NVRenderFrameBuffer *theBuffer = theManager.AllocateFrameBuffer(); + // UdoL Some Effects may need to run before HDR tonemap. This means we need to keep the + // input format + NVRenderTextureFormats::Enum theOutputFormat = NVRenderTextureFormats::RGBA8; + if (theClass->m_DynamicClass->GetOutputTextureFormat() == NVRenderTextureFormats::Unknown) + theOutputFormat = theDetails.m_Format; + NVRenderTexture2D *theTargetTexture = + theManager.AllocateTexture2D(theFinalWidth, theFinalHeight, theOutputFormat); + theBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *theTargetTexture); + theContext.SetRenderTarget(theBuffer); + NVRenderContextScopedProperty __viewport( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, + NVRenderRect(0, 0, theFinalWidth, theFinalHeight)); + + NVRenderContextScopedProperty __scissorEnable( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled, false); + + DoRenderEffect(inRenderArgument.m_Effect, *theClass, inRenderArgument.m_ColorBuffer, theMVP, + m_Context->GetRenderContext().GetRenderTarget(), false, + inRenderArgument.m_DepthTexture, inRenderArgument.m_DepthStencilBuffer, + inRenderArgument.m_CameraClipRange); + + theBuffer->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); + theManager.Release(*theBuffer); + return theTargetTexture; + } + + // Render the effect to the currently bound render target using this MVP + bool RenderEffect(SEffectRenderArgument inRenderArgument, QT3DSMat44 &inMVP, + bool inEnableBlendWhenRenderToTarget) override + { + SEffectClass *theClass = GetEffectClass(inRenderArgument.m_Effect.m_ClassName); + if (!theClass) { + QT3DS_ASSERT(false); + return false; + } + + DoRenderEffect(inRenderArgument.m_Effect, *theClass, inRenderArgument.m_ColorBuffer, inMVP, + m_Context->GetRenderContext().GetRenderTarget(), + inEnableBlendWhenRenderToTarget, inRenderArgument.m_DepthTexture, + inRenderArgument.m_DepthStencilBuffer, inRenderArgument.m_CameraClipRange); + return true; + } + + void ReleaseEffectContext(SEffectContext *inContext) override + { + if (inContext == NULL) + return; + for (QT3DSU32 idx = 0, end = m_Contexts.size(); idx < end; ++idx) { + if (m_Contexts[idx] == inContext) { + m_Contexts.replace_with_last(idx); + NVDelete(m_Allocator, inContext); + } + } + } + + void ResetEffectFrameData(SEffectContext &inContext) override + { // Query for size on every loop intentional + for (QT3DSU32 idx = 0; idx < inContext.m_AllocatedBuffers.size(); ++idx) { + SAllocatedBufferEntry &theBuffer(inContext.m_AllocatedBuffers[idx]); + if (theBuffer.m_Flags.IsSceneLifetime() == true) + theBuffer.m_NeedsClear = true; + } + for (QT3DSU32 idx = 0; idx < inContext.m_AllocatedDataBuffers.size(); ++idx) { + SAllocatedDataBufferEntry &theDataBuffer(inContext.m_AllocatedDataBuffers[idx]); + if (theDataBuffer.m_Flags.IsSceneLifetime() == true) + theDataBuffer.m_NeedsClear = true; + } + } + + void SetShaderData(CRegisteredString path, const char8_t *data, + const char8_t *inShaderType, const char8_t *inShaderVersion, + bool inHasGeomShader, bool inIsComputeShader) override + { + m_CoreContext.GetDynamicObjectSystemCore().SetShaderData( + path, data, inShaderType, inShaderVersion, inHasGeomShader, inIsComputeShader); + } + + void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, const char8_t *inProjectDir) const override + { + ioBuffer.write((QT3DSU32)m_EffectClasses.size()); + SStringSaveRemapper theRemapper(m_Allocator, inRemapMap, inProjectDir, + m_CoreContext.GetStringTable()); + for (TEffectClassMap::const_iterator theIter = m_EffectClasses.begin(), + end = m_EffectClasses.end(); + theIter != end; ++theIter) { + const SEffectClass &theClass = *theIter->second; + CRegisteredString theClassName = theClass.m_DynamicClass->GetId(); + theClassName.Remap(inRemapMap); + ioBuffer.write(theClassName); + // Effect classes do not store any additional data from the dynamic object class. + ioBuffer.write(theClass); + } + } + + void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t *inProjectDir) override + { + m_Allocator.m_PreAllocatedBlock = inData; + m_Allocator.m_OwnsMemory = false; + qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); + QT3DSU32 numEffectClasses = theReader.LoadRef(); + SStringLoadRemapper theRemapper(m_Allocator, inStrDataBlock, inProjectDir, + m_CoreContext.GetStringTable()); + for (QT3DSU32 idx = 0, end = numEffectClasses; idx < end; ++idx) { + CRegisteredString theClassName = theReader.LoadRef(); + theClassName.Remap(inStrDataBlock); + IDynamicObjectClass *theBaseClass = + m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(theClassName); + if (theBaseClass == NULL) { + QT3DS_ASSERT(false); + return; + } + SEffectClass *theClass = theReader.Load(); + theClass->SetupThisObjectFromMemory(m_Allocator, *theBaseClass); + NVScopedRefCounted theClassPtr(theClass); + m_EffectClasses.insert(eastl::make_pair(theBaseClass->GetId(), theClassPtr)); + } + } + + IEffectSystem &GetEffectSystem(IQt3DSRenderContext &context) override + { + m_Context = &context; + + NVRenderContext &theContext(m_Context->GetRenderContext()); + + m_ResourceManager = &IResourceManager::CreateResourceManager(theContext); + + // create default stencil state + qt3ds::render::NVRenderStencilFunctionArgument stencilDefaultFunc( + qt3ds::render::NVRenderBoolOp::AlwaysTrue, 0x0, 0xFF); + qt3ds::render::NVRenderStencilOperationArgument stencilDefaultOp( + qt3ds::render::NVRenderStencilOp::Keep, qt3ds::render::NVRenderStencilOp::Keep, + qt3ds::render::NVRenderStencilOp::Keep); + m_DefaultStencilState = theContext.CreateDepthStencilState( + theContext.IsDepthTestEnabled(), theContext.IsDepthWriteEnabled(), + theContext.GetDepthFunction(), theContext.IsStencilTestEnabled(), stencilDefaultFunc, + stencilDefaultFunc, stencilDefaultOp, stencilDefaultOp); + + return *this; + } + + IResourceManager &GetResourceManager() override + { + return *m_ResourceManager; + } +}; +} + +IEffectSystemCore &IEffectSystemCore::CreateEffectSystemCore(IQt3DSRenderContextCore &inContext) +{ + return *QT3DS_NEW(inContext.GetAllocator(), SEffectSystem)(inContext); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.h b/src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.h new file mode 100644 index 00000000..119564da --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderEffectSystem.h @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EFFECT_SYSTEM_H +#define QT3DS_RENDER_EFFECT_SYSTEM_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSVec2.h" +#include "Qt3DSRenderDynamicObjectSystem.h" + +namespace qt3ds { +namespace render { + struct SEffect; + struct SEffectContext; + namespace dynamic { + struct SCommand; // UICRenderEffectCommands.h + } + + struct SEffectRenderArgument + { + SEffect &m_Effect; + NVRenderTexture2D &m_ColorBuffer; + // Some effects need the camera near and far ranges. + QT3DSVec2 m_CameraClipRange; + // Some effects require the depth buffer from the rendering of thelayer + // most do not. + NVRenderTexture2D *m_DepthTexture; + // this is a depth preapass texture we need for some effects like bloom + // actually we need the stencil values + NVRenderTexture2D *m_DepthStencilBuffer; + + SEffectRenderArgument(SEffect &inEffect, NVRenderTexture2D &inColorBuffer, + const QT3DSVec2 &inCameraClipRange, + NVRenderTexture2D *inDepthTexture = NULL, + NVRenderTexture2D *inDepthBuffer = NULL) + : m_Effect(inEffect) + , m_ColorBuffer(inColorBuffer) + , m_CameraClipRange(inCameraClipRange) + , m_DepthTexture(inDepthTexture) + , m_DepthStencilBuffer(inDepthBuffer) + { + } + }; + + class IEffectSystemCore : public NVRefCounted + { + public: + virtual bool IsEffectRegistered(CRegisteredString inStr) = 0; + virtual NVConstDataRef GetRegisteredEffects() = 0; + // Register an effect class that uses exactly these commands to render. + // Effect properties cannot change after the effect is created because that would invalidate + // existing effect instances. + // Effect commands, which are stored on the effect class, can change. + virtual bool RegisterEffect(CRegisteredString inName, + NVConstDataRef inProperties) = 0; + + virtual bool UnregisterEffect(CRegisteredString inName) = 0; + + // Shorthand method that creates an effect and auto-generates the effect commands like such: + // BindShader(inPathToEffect) + // foreach( propdec in inProperties ) ApplyValue( propDecType ) + // ApplyShader() + virtual bool + RegisterGLSLEffect(CRegisteredString inName, const char8_t *inPathToEffect, + NVConstDataRef inProperties) = 0; + // Set the default value. THis is unnecessary if the default is zero as that is what it is + // assumed to be. + virtual void SetEffectPropertyDefaultValue(CRegisteredString inName, + CRegisteredString inPropName, + NVConstDataRef inDefaultData) = 0; + virtual void SetEffectPropertyEnumNames(CRegisteredString inName, + CRegisteredString inPropName, + NVConstDataRef inNames) = 0; + virtual NVConstDataRef + GetEffectPropertyEnumNames(CRegisteredString inName, + CRegisteredString inPropName) const = 0; + + virtual NVConstDataRef + GetEffectProperties(CRegisteredString inEffectName) const = 0; + + virtual void SetEffectPropertyTextureSettings( + CRegisteredString inEffectName, CRegisteredString inPropName, + CRegisteredString inPropPath, NVRenderTextureTypeValue::Enum inTexType, + NVRenderTextureCoordOp::Enum inCoordOp, NVRenderTextureMagnifyingOp::Enum inMagFilterOp, + NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0; + + // Setting the effect commands also sets this as if there isn't a specific "apply depth + // value" + // command then this effect does not require the depth texture. + // So the setter here is completely optional. + virtual void SetEffectRequiresDepthTexture(CRegisteredString inEffectName, + bool inValue) = 0; + virtual bool DoesEffectRequireDepthTexture(CRegisteredString inEffectName) const = 0; + + virtual void SetEffectRequiresCompilation(CRegisteredString inEffectName, + bool inValue) = 0; + virtual bool DoesEffectRequireCompilation(CRegisteredString inEffectName) const = 0; + + // The effect commands are the actual commands that run for a given effect. The tell the + // system exactly + // explicitly things like bind this shader, bind this render target, apply this property, + // run this shader + // See UICRenderEffectCommands.h for the list of commands. + // These commands are copied into the effect. + virtual void SetEffectCommands(CRegisteredString inEffectName, + NVConstDataRef inCommands) = 0; + virtual NVConstDataRef + GetEffectCommands(CRegisteredString inEffectName) const = 0; + + // Set the shader data for a given path. Used when a path doesn't correspond to a file but + // the data has been + // auto-generated. The system will look for data under this path key during the BindShader + // effect command. + virtual void SetShaderData(CRegisteredString inPath, const char8_t *inData, + const char8_t *inShaderType = NULL, + const char8_t *inShaderVersion = NULL, + bool inHasGeomShader = false, + bool inIsComputeShader = false) = 0; + + // An effect instance is just a property bag along with the name of the effect to run. + // This instance is what is placed into the object graph. + virtual SEffect *CreateEffectInstance(CRegisteredString inEffectName, + NVAllocatorCallback &inSceneGraphAllocator) = 0; + + virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, + const char8_t *inProjectDir) const = 0; + virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t *inProjectDir) = 0; + + virtual IEffectSystem &GetEffectSystem(IQt3DSRenderContext &context) = 0; + + virtual IResourceManager &GetResourceManager() = 0; + + static IEffectSystemCore &CreateEffectSystemCore(IQt3DSRenderContextCore &context); + }; + + /** + * An effect is essentially a function that takes a image and produces a new image. The source + *and dest images + * aren't guaranteed to be the same size, the effect may enlarge or shrink the result. + * A specialization is when you want the effect to render to the final render target instead of + *to a separate image. + * In this case the effect cannot enlarge or shrink the final target and it will render to the + *destination buffer + * using the given MVP. + */ + class IEffectSystem : public IEffectSystemCore + { + protected: + virtual ~IEffectSystem() {} + + public: + // Calling release effect context with no context results in no problems. + virtual void ReleaseEffectContext(SEffectContext *inEffect) = 0; + + // If the effect has a context you can call this to clear persistent buffers back to their + // original value. + virtual void ResetEffectFrameData(SEffectContext &inContext) = 0; + + // Render this effect. Returns false in the case the effect wasn't rendered and the render + // state + // is guaranteed to be the same as before. + // The texture returned is allocated using the resource manager, and it is up to the caller + // to deallocate it or return it to the temporary pool if items when necessary + // Pass in true if you want the result image premultiplied. Most of the functions in the + // system + // assume non-premultiplied color for images so probably this is false. + virtual NVRenderTexture2D *RenderEffect(SEffectRenderArgument inRenderArgument) = 0; + + // Render the effect to the currently bound render target using this MVP and optionally + // enabling blending when rendering to the target + virtual bool RenderEffect(SEffectRenderArgument inRenderArgument, QT3DSMat44 &inMVP, + bool inEnableBlendWhenRenderToTarget) = 0; + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.cpp new file mode 100644 index 00000000..2732f031 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.cpp @@ -0,0 +1,383 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//============================================================================== +// Includes +//============================================================================== +#include +#include +#include +#include +#include "Qt3DSRenderEulerAngles.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4365) // warnings on conversion from unsigned int to int +#endif + +//============================================================================== +// Namespace +//============================================================================== +namespace qt3ds { +namespace render { + + //============================================================================== + /** + * Constructor + */ + CEulerAngleConverter::CEulerAngleConverter() { m_OrderInfoBuffer[0] = '\0'; } + + //============================================================================== + /** + * Destructor + */ + CEulerAngleConverter::~CEulerAngleConverter() {} + + //============================================================================== + /** + * Constructs a Euler angle & holds it in a EulerAngles struct + * @param theI x rotation ( radians ) + * @param theJ y rotation ( radians ) + * @param theH z rotation ( radians ) + * @param theOrder the order this angle is in namely XYZ( static ), etc. + * use the EulOrd**** macros to generate values + * 0 to 23 is valid + * @return the euler angle + */ + EulerAngles CEulerAngleConverter::Eul_(float theI, float theJ, float theH, int theOrder) + { + EulerAngles theEulerAngle; + theEulerAngle.x = theI; + theEulerAngle.y = theJ; + theEulerAngle.z = theH; + theEulerAngle.w = (float)theOrder; + return theEulerAngle; + } + + //============================================================================== + /** + * Construct quaternion from Euler angles (in radians). + * @param theEulerAngle incoming angle( radians ) + * @return the Quaternion + */ + Quat CEulerAngleConverter::Eul_ToQuat(EulerAngles theEulerAngle) + { + Quat theQuaternion; + double a[3], ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + int i, j, k, h, n, s, f; + + EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); + if (f == EulFrmR) { + float t = theEulerAngle.x; + theEulerAngle.x = theEulerAngle.z; + theEulerAngle.z = t; + } + + if (n == EulParOdd) + theEulerAngle.y = -theEulerAngle.y; + + ti = theEulerAngle.x * 0.5; + tj = theEulerAngle.y * 0.5; + th = theEulerAngle.z * 0.5; + + ci = cos(ti); + cj = cos(tj); + ch = cos(th); + + si = sin(ti); + sj = sin(tj); + sh = sin(th); + + cc = ci * ch; + cs = ci * sh; + sc = si * ch; + ss = si * sh; + + if (s == EulRepYes) { + a[i] = cj * (cs + sc); /* Could speed up with */ + a[j] = sj * (cc + ss); /* trig identities. */ + a[k] = sj * (cs - sc); + theQuaternion.w = (float)(cj * (cc - ss)); + } else { + a[i] = cj * sc - sj * cs; + a[j] = cj * ss + sj * cc; + a[k] = cj * cs - sj * sc; + theQuaternion.w = (float)(cj * cc + sj * ss); + } + if (n == EulParOdd) + a[j] = -a[j]; + + theQuaternion.x = (float)a[X]; + theQuaternion.y = (float)a[Y]; + theQuaternion.z = (float)a[Z]; + return theQuaternion; + } + + //============================================================================== + /** + * Construct matrix from Euler angles (in radians). + * @param theEulerAngle incoming angle + * @param theMatrix outgoing matrix + */ + void CEulerAngleConverter::Eul_ToHMatrix(EulerAngles theEulerAngle, HMatrix theMatrix) + { + double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + int i, j, k, h, n, s, f; + EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); + + if (f == EulFrmR) { + float t = theEulerAngle.x; + theEulerAngle.x = theEulerAngle.z; + theEulerAngle.z = t; + } + + if (n == EulParOdd) { + theEulerAngle.x = -theEulerAngle.x; + theEulerAngle.y = -theEulerAngle.y; + theEulerAngle.z = -theEulerAngle.z; + } + + ti = theEulerAngle.x; + tj = theEulerAngle.y; + th = theEulerAngle.z; + + ci = cos(ti); + cj = cos(tj); + ch = cos(th); + + si = sin(ti); + sj = sin(tj); + sh = sin(th); + + cc = ci * ch; + cs = ci * sh; + sc = si * ch; + ss = si * sh; + + if (s == EulRepYes) { + theMatrix[i][i] = (float)cj; + theMatrix[i][j] = (float)(sj * si); + theMatrix[i][k] = (float)(sj * ci); + theMatrix[j][i] = (float)(sj * sh); + theMatrix[j][j] = (float)(-cj * ss + cc); + theMatrix[j][k] = (float)(-cj * cs - sc); + theMatrix[k][i] = (float)(-sj * ch); + theMatrix[k][j] = (float)(cj * sc + cs); + theMatrix[k][k] = (float)(cj * cc - ss); + } else { + theMatrix[i][i] = (float)(cj * ch); + theMatrix[i][j] = (float)(sj * sc - cs); + theMatrix[i][k] = (float)(sj * cc + ss); + theMatrix[j][i] = (float)(cj * sh); + theMatrix[j][j] = (float)(sj * ss + cc); + theMatrix[j][k] = (float)(sj * cs - sc); + theMatrix[k][i] = (float)(-sj); + theMatrix[k][j] = (float)(cj * si); + theMatrix[k][k] = (float)(cj * ci); + } + + theMatrix[W][X] = 0.0; + theMatrix[W][Y] = 0.0; + theMatrix[W][Z] = 0.0; + theMatrix[X][W] = 0.0; + theMatrix[Y][W] = 0.0; + theMatrix[Z][W] = 0.0; + theMatrix[W][W] = 1.0; + } + + //============================================================================== + /** + * Convert matrix to Euler angles (in radians). + * @param theMatrix incoming matrix + * @param theOrder 0-23, use EulOrd**** to generate this value + * @return a set of angles in radians!!!! + */ + EulerAngles CEulerAngleConverter::Eul_FromHMatrix(HMatrix theMatrix, int theOrder) + { + EulerAngles theEulerAngle; + int i, j, k, h, n, s, f; + + EulGetOrd(theOrder, i, j, k, h, n, s, f); + if (s == EulRepYes) { + double sy = sqrt(theMatrix[i][j] * theMatrix[i][j] + theMatrix[i][k] * theMatrix[i][k]); + if (sy > 16 * FLT_EPSILON) { + theEulerAngle.x = (float)(atan2((double)theMatrix[i][j], (double)theMatrix[i][k])); + theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); + theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], -(double)theMatrix[k][i])); + } else { + theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); + theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); + theEulerAngle.z = 0; + } + } else { + double cy = sqrt(theMatrix[i][i] * theMatrix[i][i] + theMatrix[j][i] * theMatrix[j][i]); + if (cy > 16 * FLT_EPSILON) { + theEulerAngle.x = (float)(atan2((double)theMatrix[k][j], (double)theMatrix[k][k])); + theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); + theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], (double)theMatrix[i][i])); + } else { + theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); + theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); + theEulerAngle.z = 0; + } + } + + if (n == EulParOdd) { + theEulerAngle.x = -theEulerAngle.x; + theEulerAngle.y = -theEulerAngle.y; + theEulerAngle.z = -theEulerAngle.z; + } + + if (f == EulFrmR) { + float t = theEulerAngle.x; + theEulerAngle.x = theEulerAngle.z; + theEulerAngle.z = t; + } + theEulerAngle.w = (float)theOrder; + return theEulerAngle; + } + + //============================================================================== + /** + * Convert quaternion to Euler angles (in radians). + * @param theQuaternion incoming quaternion + * @param theOrder 0-23, use EulOrd**** to generate this value + * @return the generated angles ( radians ) + */ + EulerAngles CEulerAngleConverter::Eul_FromQuat(Quat theQuaternion, int theOrder) + { + HMatrix theMatrix; + double Nq = theQuaternion.x * theQuaternion.x + theQuaternion.y * theQuaternion.y + + theQuaternion.z * theQuaternion.z + theQuaternion.w * theQuaternion.w; + double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; + double xs = theQuaternion.x * s; + double ys = theQuaternion.y * s; + double zs = theQuaternion.z * s; + double wx = theQuaternion.w * xs; + double wy = theQuaternion.w * ys; + double wz = theQuaternion.w * zs; + double xx = theQuaternion.x * xs; + double xy = theQuaternion.x * ys; + double xz = theQuaternion.x * zs; + double yy = theQuaternion.y * ys; + double yz = theQuaternion.y * zs; + double zz = theQuaternion.z * zs; + + theMatrix[X][X] = (float)(1.0 - (yy + zz)); + theMatrix[X][Y] = (float)(xy - wz); + theMatrix[X][Z] = (float)(xz + wy); + theMatrix[Y][X] = (float)(xy + wz); + theMatrix[Y][Y] = (float)(1.0 - (xx + zz)); + theMatrix[Y][Z] = (float)(yz - wx); + theMatrix[Z][X] = (float)(xz - wy); + theMatrix[Z][Y] = (float)(yz + wx); + theMatrix[Z][Z] = (float)(1.0 - (xx + yy)); + theMatrix[W][X] = 0.0; + theMatrix[W][Y] = 0.0; + theMatrix[W][Z] = 0.0; + theMatrix[X][W] = 0.0; + theMatrix[Y][W] = 0.0; + theMatrix[Z][W] = 0.0; + theMatrix[W][W] = 1.0; + + return Eul_FromHMatrix(theMatrix, theOrder); + } + + //============================================================================== + /** + * Dump the Order information + */ + const char *CEulerAngleConverter::DumpOrderInfo() + { + long theCount = 0; + long theOrder[24]; + char theOrderStr[24][16]; + + ::strcpy(theOrderStr[theCount++], "EulOrdXYZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdXYXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXYXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXZr"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXZr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXYZr"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYZr"); + + theCount = 0; + theOrder[theCount++] = EulOrdXYZs; + theOrder[theCount++] = EulOrdXYXs; + theOrder[theCount++] = EulOrdXZYs; + theOrder[theCount++] = EulOrdXZXs; + theOrder[theCount++] = EulOrdYZXs; + theOrder[theCount++] = EulOrdYZYs; + theOrder[theCount++] = EulOrdYXZs; + theOrder[theCount++] = EulOrdYXYs; + theOrder[theCount++] = EulOrdZXYs; + theOrder[theCount++] = EulOrdZXZs; + theOrder[theCount++] = EulOrdZYXs; + theOrder[theCount++] = EulOrdZYZs; + + theOrder[theCount++] = EulOrdZYXr; + theOrder[theCount++] = EulOrdXYXr; + theOrder[theCount++] = EulOrdYZXr; + theOrder[theCount++] = EulOrdXZXr; + theOrder[theCount++] = EulOrdXZYr; + theOrder[theCount++] = EulOrdYZYr; + theOrder[theCount++] = EulOrdZXYr; + theOrder[theCount++] = EulOrdYXYr; + theOrder[theCount++] = EulOrdYXZr; + theOrder[theCount++] = EulOrdZXZr; + theOrder[theCount++] = EulOrdXYZr; + theOrder[theCount++] = EulOrdZYZr; + + char theSubBuf[256]; + m_OrderInfoBuffer[0] = '\0'; + for (long theIndex = 0; theIndex < 24; ++theIndex) { + ::sprintf(theSubBuf, " %16s - %ld\n ", theOrderStr[theIndex], theOrder[theIndex]); + ::strcat(m_OrderInfoBuffer, theSubBuf); + } + + return m_OrderInfoBuffer; + } +} +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.h b/src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.h new file mode 100644 index 00000000..bf271e29 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderEulerAngles.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include + +namespace qt3ds { +namespace render { + //============================================================================== + // Description + //============================================================================== + // QuatTypes.h - Basic type declarations + // by Ken Shoemake, shoemake@graphics.cis.upenn.edu + // in "Graphics Gems IV", Academic Press, 1994 + typedef struct + { + float x, y, z, w; + } Quat; /* Quaternion */ + typedef float HMatrix[4][4]; /* Right-handed, for column vectors */ + enum QuatPart { X, Y, Z, W }; + typedef Quat EulerAngles; /* (x,y,z)=ang 1,2,3, w=order code */ + +#define EulFrmS 0 +#define EulFrmR 1 +#define EulFrm(ord) ((unsigned)(ord)&1) +#define EulRepNo 0 +#define EulRepYes 1 +#define EulRep(ord) (((unsigned)(ord) >> 1) & 1) +#define EulParEven 0 +#define EulParOdd 1 +#define EulPar(ord) (((unsigned)(ord) >> 2) & 1) +#define EulSafe "\000\001\002\000" +#define EulNext "\001\002\000\001" +#define EulAxI(ord) ((int)(EulSafe[(((unsigned)(ord) >> 3) & 3)])) +#define EulAxJ(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) == EulParOdd)])) +#define EulAxK(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) != EulParOdd)])) +#define EulAxH(ord) ((EulRep(ord) == EulRepNo) ? EulAxK(ord) : EulAxI(ord)) + +// EulGetOrd unpacks all useful information about order simultaneously. +#define EulGetOrd(ord, i, j, k, h, n, s, f) \ + { \ + unsigned o = ord; \ + f = o & 1; \ + o = o >> 1; \ + s = o & 1; \ + o = o >> 1; \ + n = o & 1; \ + o = o >> 1; \ + i = EulSafe[o & 3]; \ + j = EulNext[i + n]; \ + k = EulNext[i + 1 - n]; \ + h = s ? k : i; \ + } + +// EulOrd creates an order value between 0 and 23 from 4-tuple choices. +#define EulOrd(i, p, r, f) (((((((i) << 1) + (p)) << 1) + (r)) << 1) + (f)) + +// Static axes +// X = 0, Y = 1, Z = 2 ref QuatPart +#define EulOrdXYZs EulOrd(0, EulParEven, EulRepNo, EulFrmS) +#define EulOrdXYXs EulOrd(0, EulParEven, EulRepYes, EulFrmS) +#define EulOrdXZYs EulOrd(0, EulParOdd, EulRepNo, EulFrmS) +#define EulOrdXZXs EulOrd(0, EulParOdd, EulRepYes, EulFrmS) +#define EulOrdYZXs EulOrd(1, EulParEven, EulRepNo, EulFrmS) +#define EulOrdYZYs EulOrd(1, EulParEven, EulRepYes, EulFrmS) +#define EulOrdYXZs EulOrd(1, EulParOdd, EulRepNo, EulFrmS) +#define EulOrdYXYs EulOrd(1, EulParOdd, EulRepYes, EulFrmS) +#define EulOrdZXYs EulOrd(2, EulParEven, EulRepNo, EulFrmS) +#define EulOrdZXZs EulOrd(2, EulParEven, EulRepYes, EulFrmS) +#define EulOrdZYXs EulOrd(2, EulParOdd, EulRepNo, EulFrmS) +#define EulOrdZYZs EulOrd(2, EulParOdd, EulRepYes, EulFrmS) + +// Rotating axes +#define EulOrdZYXr EulOrd(0, EulParEven, EulRepNo, EulFrmR) +#define EulOrdXYXr EulOrd(0, EulParEven, EulRepYes, EulFrmR) +#define EulOrdYZXr EulOrd(0, EulParOdd, EulRepNo, EulFrmR) +#define EulOrdXZXr EulOrd(0, EulParOdd, EulRepYes, EulFrmR) +#define EulOrdXZYr EulOrd(1, EulParEven, EulRepNo, EulFrmR) +#define EulOrdYZYr EulOrd(1, EulParEven, EulRepYes, EulFrmR) +#define EulOrdZXYr EulOrd(1, EulParOdd, EulRepNo, EulFrmR) +#define EulOrdYXYr EulOrd(1, EulParOdd, EulRepYes, EulFrmR) +#define EulOrdYXZr EulOrd(2, EulParEven, EulRepNo, EulFrmR) +#define EulOrdZXZr EulOrd(2, EulParEven, EulRepYes, EulFrmR) +#define EulOrdXYZr EulOrd(2, EulParOdd, EulRepNo, EulFrmR) +#define EulOrdZYZr EulOrd(2, EulParOdd, EulRepYes, EulFrmR) + +#ifndef M_PI +#define M_PI 3.1415926535898 +#endif + +#define TODEG(x) x = (float)(x * 180 / M_PI); +#define TORAD(x) x = (float)(x / 180 * M_PI); + + class CEulerAngleConverter + { + private: + char m_OrderInfoBuffer[1024]; + + public: + CEulerAngleConverter(); + virtual ~CEulerAngleConverter(); + + public: + EulerAngles Eul_(float ai, float aj, float ah, int order); + Quat Eul_ToQuat(EulerAngles ea); + void Eul_ToHMatrix(EulerAngles ea, HMatrix M); + EulerAngles Eul_FromHMatrix(HMatrix M, int order); + EulerAngles Eul_FromQuat(Quat q, int order); + + // Debug Stuff + const char *DumpOrderInfo(); + }; +} +} // namespace Q3DStudio diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderGpuProfiler.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderGpuProfiler.cpp new file mode 100644 index 00000000..740d8a71 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderGpuProfiler.cpp @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2014 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderProfiler.h" + +#include "EASTL/string.h" +#include "EASTL/hash_map.h" + +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSFoundation.h" + +#include "Qt3DSRenderContextCore.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderTimerQuery.h" +#include "render/Qt3DSRenderSync.h" + +#define RECORDED_FRAME_DELAY 3 +#define RECORDED_FRAME_DELAY_MASK 0x0003 + +using namespace qt3ds::render; + +namespace { + +using eastl::make_pair; + +struct SGpuTimerInfo +{ + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + bool m_AbsoluteTime; + QT3DSU16 m_WriteID; + QT3DSU16 m_ReadID; + QT3DSU16 m_AverageTimeWriteID; + QT3DSU64 m_AverageTime[10]; + QT3DSU32 m_FrameID[RECORDED_FRAME_DELAY]; + NVScopedRefCounted m_TimerStartQueryObjects[RECORDED_FRAME_DELAY]; + NVScopedRefCounted m_TimerEndQueryObjects[RECORDED_FRAME_DELAY]; + NVScopedRefCounted m_TimerSyncObjects[RECORDED_FRAME_DELAY]; + + SGpuTimerInfo(NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , mRefCount(0) + , m_AbsoluteTime(false) + , m_WriteID(0) + , m_ReadID(0) + , m_AverageTimeWriteID(0) + { + memset(m_AverageTime, 0x0, 10 * sizeof(QT3DSU64)); + } + + ~SGpuTimerInfo() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void IncrementWriteCounter() + { + m_WriteID++; + m_WriteID %= RECORDED_FRAME_DELAY_MASK; + } + + void IncrementReadCounter() + { + m_ReadID++; + m_ReadID %= RECORDED_FRAME_DELAY_MASK; + } + + void IncrementAveragedWriteCounter() + { + m_AverageTimeWriteID++; + m_AverageTimeWriteID %= 10; + } + + void StartTimerQuery(QT3DSU32 frameID) + { + m_FrameID[m_WriteID] = frameID; + + if (m_AbsoluteTime) + m_TimerStartQueryObjects[m_WriteID]->SetTimerQuery(); + else + m_TimerStartQueryObjects[m_WriteID]->Begin(); + } + + void EndTimerQuery() + { + if (m_AbsoluteTime) + m_TimerEndQueryObjects[m_WriteID]->SetTimerQuery(); + else + m_TimerStartQueryObjects[m_WriteID]->End(); + + IncrementWriteCounter(); + } + + void AddSync() + { + m_TimerSyncObjects[m_WriteID]->Sync(); + m_TimerSyncObjects[m_WriteID]->Wait(); + } + + QT3DSF64 GetAveragedElapsedTimeInMs() + { + QT3DSF64 time = + QT3DSF64(((m_AverageTime[0] + m_AverageTime[1] + m_AverageTime[2] + m_AverageTime[3] + + m_AverageTime[4] + m_AverageTime[5] + m_AverageTime[6] + m_AverageTime[7] + + m_AverageTime[8] + m_AverageTime[9]) + / 10) + / 1e06); + + return time; + } + + QT3DSF64 GetElapsedTimeInMs(QT3DSU32 frameID) + { + QT3DSF64 time = 0; + + if (((frameID - m_FrameID[m_ReadID]) < 2) || (m_ReadID == m_WriteID)) + return time; + + if (m_AbsoluteTime) { + QT3DSU64 startTime, endTime; + + m_TimerStartQueryObjects[m_ReadID]->GetResult(&startTime); + m_TimerEndQueryObjects[m_ReadID]->GetResult(&endTime); + + m_AverageTime[m_AverageTimeWriteID] = endTime - startTime; + } else { + QT3DSU64 elapsedTime; + + m_TimerStartQueryObjects[m_ReadID]->GetResult(&elapsedTime); + + m_AverageTime[m_AverageTimeWriteID] = elapsedTime; + } + + IncrementReadCounter(); + IncrementAveragedWriteCounter(); + + return GetAveragedElapsedTimeInMs(); + } +}; + +class Qt3DSCRenderGpuProfiler : public IRenderProfiler +{ + typedef nvhash_map> TStrGpuTimerInfoMap; + +private: + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_RenderContext; + IQt3DSRenderContext &m_Context; + volatile QT3DSI32 mRefCount; + + TStrGpuTimerInfoMap m_StrToGpuTimerMap; + IRenderProfiler::TStrIDVec m_StrToIDVec; + mutable QT3DSU32 m_VertexCount; + +public: + Qt3DSCRenderGpuProfiler(NVFoundationBase &inFoundation, IQt3DSRenderContext &inContext, + NVRenderContext &inRenderContext) + : m_Foundation(inFoundation) + , m_RenderContext(inRenderContext) + , m_Context(inContext) + , mRefCount(0) + , m_StrToGpuTimerMap(inContext.GetAllocator(), "Qt3DSRenderGpuProfiler::m_StrToGpuTimerMap") + , m_StrToIDVec(inContext.GetAllocator(), "Qt3DSRenderGpuProfiler::m_StrToIDVec") + , m_VertexCount(0) + { + } + + virtual ~Qt3DSCRenderGpuProfiler() { m_StrToGpuTimerMap.clear(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void StartTimer(CRegisteredString &nameID, bool absoluteTime, bool sync) override + { + SGpuTimerInfo *theGpuTimerData = GetOrCreateGpuTimerInfo(nameID); + + if (theGpuTimerData) { + if (sync) + theGpuTimerData->AddSync(); + + theGpuTimerData->m_AbsoluteTime = absoluteTime; + theGpuTimerData->StartTimerQuery(m_Context.GetFrameCount()); + } + } + + void EndTimer(CRegisteredString &nameID) override + { + SGpuTimerInfo *theGpuTimerData = GetOrCreateGpuTimerInfo(nameID); + + if (theGpuTimerData) { + theGpuTimerData->EndTimerQuery(); + } + } + + QT3DSF64 GetElapsedTime(const CRegisteredString &nameID) const override + { + QT3DSF64 time = 0; + SGpuTimerInfo *theGpuTimerData = GetGpuTimerInfo(nameID); + + if (theGpuTimerData) { + time = theGpuTimerData->GetElapsedTimeInMs(m_Context.GetFrameCount()); + } + + return time; + } + + const TStrIDVec &GetTimerIDs() const override { return m_StrToIDVec; } + + void AddVertexCount(QT3DSU32 count) override { m_VertexCount += count; } + + QT3DSU32 GetAndResetTriangleCount() const override + { + QT3DSU32 tris = m_VertexCount / 3; + m_VertexCount = 0; + return tris; + } + +private: + SGpuTimerInfo *GetOrCreateGpuTimerInfo(CRegisteredString &nameID) + { + TStrGpuTimerInfoMap::const_iterator theIter = m_StrToGpuTimerMap.find(nameID); + if (theIter != m_StrToGpuTimerMap.end()) + return const_cast(theIter->second.mPtr); + + SGpuTimerInfo *theGpuTimerData = + QT3DS_NEW(m_Context.GetAllocator(), SGpuTimerInfo)(m_Foundation); + + if (theGpuTimerData) { + // create queries + for (QT3DSU32 i = 0; i < RECORDED_FRAME_DELAY; i++) { + theGpuTimerData->m_TimerStartQueryObjects[i] = m_RenderContext->CreateTimerQuery(); + theGpuTimerData->m_TimerEndQueryObjects[i] = m_RenderContext->CreateTimerQuery(); + theGpuTimerData->m_TimerSyncObjects[i] = m_RenderContext->CreateSync(); + theGpuTimerData->m_FrameID[i] = 0; + } + m_StrToGpuTimerMap.insert(make_pair(nameID, theGpuTimerData)); + m_StrToIDVec.push_back(nameID); + } + + return theGpuTimerData; + } + + SGpuTimerInfo *GetGpuTimerInfo(const CRegisteredString &nameID) const + { + TStrGpuTimerInfoMap::const_iterator theIter = m_StrToGpuTimerMap.find(nameID); + if (theIter != m_StrToGpuTimerMap.end()) + return const_cast(theIter->second.mPtr); + + return NULL; + } +}; +} + +IRenderProfiler &IRenderProfiler::CreateGpuProfiler(NVFoundationBase &inFnd, + IQt3DSRenderContext &inContext, + NVRenderContext &inRenderContext) +{ + return *QT3DS_NEW(inFnd.getAllocator(), Qt3DSCRenderGpuProfiler)(inFnd, inContext, inRenderContext); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectPickQuery.h b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectPickQuery.h new file mode 100644 index 00000000..e63cad3f --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectPickQuery.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GRAPH_OBJECT_PICK_QUERY_H +#define QT3DS_RENDER_GRAPH_OBJECT_PICK_QUERY_H + +#include "Qt3DSRender.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSMat44.h" +#include "Qt3DSRenderImage.h" + +namespace qt3ds { +namespace render { + + class IOffscreenRenderer; + + struct Qt3DSRenderPickSubResult + { + IOffscreenRenderer *m_SubRenderer; + QT3DSMat44 m_TextureMatrix; + NVRenderTextureCoordOp::Enum m_HorizontalTilingMode; + NVRenderTextureCoordOp::Enum m_VerticalTilingMode; + QT3DSU32 m_ViewportWidth; + QT3DSU32 m_ViewportHeight; + Qt3DSRenderPickSubResult *m_NextSibling; + + Qt3DSRenderPickSubResult() + : m_SubRenderer(NULL) + , m_NextSibling(NULL) + { + } + Qt3DSRenderPickSubResult(IOffscreenRenderer &inSubRenderer, QT3DSMat44 inTextureMatrix, + NVRenderTextureCoordOp::Enum inHorizontalTilingMode, + NVRenderTextureCoordOp::Enum inVerticalTilingMode, QT3DSU32 width, + QT3DSU32 height) + : m_SubRenderer(&inSubRenderer) + , m_TextureMatrix(inTextureMatrix) + , m_HorizontalTilingMode(inHorizontalTilingMode) + , m_VerticalTilingMode(inVerticalTilingMode) + , m_ViewportWidth(width) + , m_ViewportHeight(height) + , m_NextSibling(NULL) + { + } + }; + + struct Qt3DSRenderPickResult + { + const SGraphObject *m_HitObject; + QT3DSF32 m_CameraDistanceSq; + // The local coordinates in X,Y UV space where the hit occured + QT3DSVec2 m_LocalUVCoords; + // The local mouse coordinates will be the same on all of the sub objects. + Qt3DSRenderPickSubResult *m_FirstSubObject; + // The offscreen renderer that was used to render the scene graph this result was produced + // from. + IOffscreenRenderer *m_OffscreenRenderer; + + Qt3DSRenderPickResult(const SGraphObject &inHitObject, QT3DSF32 inCameraDistance, + const QT3DSVec2 &inLocalUVCoords) + : m_HitObject(&inHitObject) + , m_CameraDistanceSq(inCameraDistance) + , m_LocalUVCoords(inLocalUVCoords) + , m_FirstSubObject(NULL) + , m_OffscreenRenderer(NULL) + { + } + Qt3DSRenderPickResult() + : m_HitObject(NULL) + , m_CameraDistanceSq(QT3DS_MAX_F32) + , m_LocalUVCoords(0, 0) + , m_FirstSubObject(NULL) + , m_OffscreenRenderer(NULL) + { + } + }; + + class IGraphObjectPickQuery + { + protected: + virtual ~IGraphObjectPickQuery() {} + + public: + // Implementors have the option of batching the results to allow fewer virtual calls + // or returning one item each pick. + // Results are guaranteed to be returned nearest to furthest + // If the return value has size of zero then we assume nothing more can be picked and the + // pick + // is finished. + virtual Qt3DSRenderPickResult Pick(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool inPickEverything) = 0; + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.cpp new file mode 100644 index 00000000..8fc7e5aa --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.cpp @@ -0,0 +1,670 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderGraphObjectSerializer.h" +#include "Qt3DSRenderPresentation.h" +#include "Qt3DSRenderNode.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderModel.h" +#include "Qt3DSRenderText.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderImage.h" +#include "Qt3DSRenderEffect.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderEffectSystem.h" +#include "foundation/SerializationTypes.h" +#include "Qt3DSRenderString.h" +#include "foundation/FileTools.h" +#include "Qt3DSRenderPluginGraphObject.h" +#include "Qt3DSRenderReferencedMaterial.h" +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderPathSubPath.h" +#include "Qt3DSRenderPathManager.h" + +using namespace qt3ds::render; +using namespace qt3ds::render::dynamic; + +namespace { +typedef nvhash_set TPtrSet; + +void Align(MemoryBuffer<> &inBuffer) +{ + inBuffer.align(sizeof(void *)); +} +typedef nvvector> TObjectFileStatList; +typedef SPtrOffsetMap TPtrOffsetMap; + +struct SSerializerWriteContext +{ + SPtrOffsetMap &m_OffsetMap; + SWriteBuffer &m_MemoryBuffer; + const SStrRemapMap &m_StrRemapMap; + QT3DSU32 m_DataBlockStart; + IDynamicObjectSystem &m_DynamicObjectSystem; + IPathManager &m_PathManager; + TObjectFileStatList &m_FileSizeStats; + CRenderString m_PathMapper; + CRenderString m_BasePath; + CRenderString m_RelativePath; + IStringTable &m_StringTable; + SSerializerWriteContext(SPtrOffsetMap &inOffsetMap, SWriteBuffer &inWriteBuffer, + const SStrRemapMap &inStrMap, QT3DSU32 inDataBlockStart, + IDynamicObjectSystem &inDynamicObjectSystem, + IPathManager &inPathManager, TObjectFileStatList &inStats, + NVAllocatorCallback &inAllocator, const char8_t *inProjectDirectory, + IStringTable &inStringTable) + : m_OffsetMap(inOffsetMap) + , m_MemoryBuffer(inWriteBuffer) + , m_StrRemapMap(inStrMap) + , m_DataBlockStart(inDataBlockStart) + , m_DynamicObjectSystem(inDynamicObjectSystem) + , m_PathManager(inPathManager) + , m_FileSizeStats(inStats) + , m_StringTable(inStringTable) + { + Q_UNUSED(inAllocator) + m_BasePath.assign(inProjectDirectory); + } + + bool HasWrittenObject(const void *inObject) { return m_OffsetMap.contains(inObject); } + + QT3DSU32 &GetStatEntry(GraphObjectTypes::Enum inType) const + { + for (QT3DSU32 idx = 0, end = m_FileSizeStats.size(); idx < end; ++idx) + if (m_FileSizeStats[idx].first == inType) + return m_FileSizeStats[idx].second; + m_FileSizeStats.push_back(eastl::make_pair(inType, (QT3DSU32)0)); + return m_FileSizeStats.back().second; + } + + template + void AddPtrOffset(const TObjType *inObject) + { + QT3DSU32 objOffset = m_MemoryBuffer.size() - m_DataBlockStart; + m_OffsetMap.insert(eastl::make_pair(inObject, objOffset)); +// In debug we keep stats on how much each type of object +// contributes to the file size. +#ifdef _DEBUG + GetStatEntry(inObject->m_Type) += sizeof(TObjType); +#endif + } + + void Remap(CRegisteredString &inStr) { inStr.Remap(m_StrRemapMap); } + + template + void Remap(TObjType *&inPtr) + { + if (inPtr) { + TPtrOffsetMap::iterator theIter = m_OffsetMap.find(inPtr); + if (theIter != m_OffsetMap.end()) + inPtr = reinterpret_cast(theIter->second); + else { + QT3DS_ASSERT(false); + } + } + } + + void RemapMaterial(SGraphObject *&inPtr) { Remap(inPtr); } + + template + void NullPtr(TObjType *&inPtr) + { + inPtr = NULL; + } +}; + +/////////////////////////////////////////////////////////////////////// +// --** Reading the scene graph is heavily threaded when we are loading +// multiple presentations in one application --** +/////////////////////////////////////////////////////////////////////// +struct SSerializerReadContext : public SDataReader +{ + IPathManagerCore &m_PathManager; + IDynamicObjectSystemCore &m_DynamicObjectSystem; + NVDataRef m_DataBlock; + NVDataRef m_StrTableBlock; + CRenderString m_PathMapper; + const char8_t *m_ProjectDirectory; + + SSerializerReadContext(IPathManagerCore &inPathManager, IDynamicObjectSystemCore &inDynSystem, + NVDataRef inDataBlock, NVDataRef inStrTable, + NVAllocatorCallback &inAllocator, const char8_t *inProjectDirectory) + : SDataReader(inDataBlock.begin(), inDataBlock.end()) + , m_PathManager(inPathManager) + , m_DynamicObjectSystem(inDynSystem) + , m_DataBlock(inDataBlock) + , m_StrTableBlock(inStrTable) + , m_ProjectDirectory(inProjectDirectory) + { + Q_UNUSED(inAllocator) + } + void Remap(CRegisteredString &inStr) { inStr.Remap(m_StrTableBlock); } + template + void Remap(TObjType *&inPtr) + { + if (inPtr) { + TObjType *purePtr = inPtr; + size_t ptrValue = reinterpret_cast(purePtr); + if (ptrValue < m_DataBlock.size()) + inPtr = reinterpret_cast(m_DataBlock.begin() + ptrValue); + else { + QT3DS_ASSERT(false); + inPtr = NULL; + } + } + } + void RemapMaterial(SGraphObject *&inPtr) { Remap(inPtr); } + // Nulling out pointers was done on write, so we don't do it here. + template + void NullPtr(TObjType *&) + { + } +}; + +template +struct SGraphObjectSerializerImpl +{ + static TObjType *Write(const TObjType &ioObject, SSerializerWriteContext &outSavedBuffer); + static void Remap(TObjType &inObject, SSerializerWriteContext &inRemapContext); + static TObjType *Read(SSerializerReadContext &inReadContext); +}; + +struct SWriteRemapper +{ + SSerializerWriteContext &m_WriteBuffer; + SWriteRemapper(SSerializerWriteContext &buf) + : m_WriteBuffer(buf) + { + } + // This will happen later + void Remap(const CRegisteredString &) {} + void RemapPath(const CRegisteredString &) {} + + // We ignore objects that are saved out explicitly below. + void Remap(const SScene *) {} + + void Remap(const SLayer *) {} + // Nodes are ignored because we save them out *not* in depth first order, + // with models, text, lights and camera saved out contiguously for in-memory + // traversal. + void Remap(const SNode *) {} +#ifdef _INTEGRITYPLATFORM + // explicit specialization of class "::SGraphObjectSerializerImpl" + // must precede its first use struct SGraphObjectSerializerImpl + template + void Remap(const TObjType *inObj); +#else + template + void Remap(const TObjType *inObj) + { + if (inObj) + SGraphObjectSerializerImpl::Write(*inObj, m_WriteBuffer); + } +#endif + + void RemapMaterial(const SGraphObject *inObj) + { + if (inObj) { + if (inObj->m_Type == GraphObjectTypes::DefaultMaterial) + Remap(static_cast(inObj)); + else if (inObj->m_Type == GraphObjectTypes::CustomMaterial) + Remap(static_cast(inObj)); + else if (inObj->m_Type == GraphObjectTypes::ReferencedMaterial) + Remap(static_cast(inObj)); + else { + QT3DS_ASSERT(false); + } + } + } + template + void NullPtr(const TObjType *) + { + } +}; + +void PrepareFirstPass(const SNode &inNode, nvvector &ioLightCameras, + nvvector &ioRenderable) +{ + if (GraphObjectTypes::IsRenderableType(inNode.m_Type)) + ioRenderable.push_back(&inNode); + else if (GraphObjectTypes::IsLightCameraType(inNode.m_Type)) + ioLightCameras.push_back(&inNode); + + for (const SNode *theChild = inNode.m_FirstChild; theChild; theChild = theChild->m_NextSibling) + PrepareFirstPass(*theChild, ioLightCameras, ioRenderable); +} + +template +TObject *WriteGenericGraphObjectNoRemap(const TObject &ioObject, + SSerializerWriteContext &outSavedBuffer) +{ + if (outSavedBuffer.HasWrittenObject(&ioObject)) + return NULL; + + outSavedBuffer.AddPtrOffset(&ioObject); + QT3DSU32 theOffset = outSavedBuffer.m_MemoryBuffer.size(); + outSavedBuffer.m_MemoryBuffer.write(ioObject); + // Probably the buffer stays aligned but we want to work to keep it that way. + Align(outSavedBuffer.m_MemoryBuffer); + return reinterpret_cast(outSavedBuffer.m_MemoryBuffer.begin() + theOffset); +} + +template +TObject *WriteGenericGraphObject(const TObject &ioObject, SSerializerWriteContext &outSavedBuffer) +{ + TObject *theObject = WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer); + if (theObject) // The object may have already been written. + { + // Write mappers just follow pointers and ensure all the associated objects + // are written out. + SWriteRemapper theWriteRemapper(outSavedBuffer); + const_cast(ioObject).Remap(theWriteRemapper); + } + return theObject; +} + +template +TObject *ReadGenericGraphObject(SSerializerReadContext &inReadContext) +{ + TObject *retval = inReadContext.Load(); + inReadContext.Align(); + if (retval) { + retval->Remap(inReadContext); + } + return retval; +} + +template +TObjType *SGraphObjectSerializerImpl::Write(const TObjType &ioObject, + SSerializerWriteContext &outSavedBuffer) +{ + return WriteGenericGraphObject(ioObject, outSavedBuffer); +} +template +void SGraphObjectSerializerImpl::Remap(TObjType &ioObject, + SSerializerWriteContext &inRemapContext) +{ + return ioObject.Remap(inRemapContext); +} + +template +TObjType *SGraphObjectSerializerImpl::Read(SSerializerReadContext &inReadContext) +{ + return ReadGenericGraphObject(inReadContext); +} + +void RemapProperties(SDynamicObject &ioObject, SSerializerWriteContext &outSavedBuffer, + CRegisteredString inClassName) +{ + NVConstDataRef theObjectProps = + outSavedBuffer.m_DynamicObjectSystem.GetProperties(inClassName); + for (QT3DSU32 idx = 0, end = theObjectProps.size(); idx < end; ++idx) { + const SPropertyDefinition &theDef(theObjectProps[idx]); + if (theDef.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + CRegisteredString *theStr = reinterpret_cast( + ioObject.GetDataSectionBegin() + theDef.m_Offset); + outSavedBuffer.Remap(*theStr); + } + } +} + +void RemapProperties(SDynamicObject &ioObject, SSerializerReadContext &inReadContext) +{ + // CN - !!Note this call is done on multiple threads simultaneously. I added a mutex just to be + // sure even though + // this is a read-only call; I am not certain how good the arm memory locking is when it is + // completely unprotected. + NVConstDataRef theProperties = + inReadContext.m_DynamicObjectSystem.GetProperties(ioObject.m_ClassName); + for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { + const SPropertyDefinition &theDefinition(theProperties[idx]); + if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + CRegisteredString *theString = reinterpret_cast( + ioObject.GetDataSectionBegin() + theDefinition.m_Offset); + inReadContext.Remap(*theString); + } + } +} + +template <> +struct SGraphObjectSerializerImpl +{ + static SGraphObject *Write(const SEffect &ioObject, SSerializerWriteContext &outSavedBuffer) + { + size_t itemOffset = outSavedBuffer.m_MemoryBuffer.size(); + SEffect *theNewEffect = + static_cast(WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer)); + if (theNewEffect) { + theNewEffect->m_Context = NULL; + // Writing it out is easy. Reading it back in means we have to have a correctly setup + // IEffectManager so we + // can remap strings. + outSavedBuffer.m_MemoryBuffer.write(ioObject.GetDataSectionBegin(), + ioObject.m_DataSectionByteSize); + Align(outSavedBuffer.m_MemoryBuffer); + SWriteRemapper theWriteRemapper(outSavedBuffer); + // Write any connected objects. + theNewEffect = + reinterpret_cast(outSavedBuffer.m_MemoryBuffer.begin() + itemOffset); + theNewEffect->Remap(theWriteRemapper); + } + return theNewEffect; + } + + static void Remap(SEffect &ioObject, SSerializerWriteContext &outSavedBuffer) + { + CRegisteredString theClassName = ioObject.m_ClassName; + ioObject.Remap(outSavedBuffer); + RemapProperties(ioObject, outSavedBuffer, theClassName); + } + + static SEffect *Read(SSerializerReadContext &inReadContext) + { + SEffect *theEffect = ReadGenericGraphObject(inReadContext); + if (theEffect) { + inReadContext.m_CurrentPtr += theEffect->m_DataSectionByteSize; + inReadContext.Align(); + RemapProperties(*theEffect, inReadContext); + } + return theEffect; + } +}; + +template <> +struct SGraphObjectSerializerImpl +{ + static SGraphObject *Write(const SCustomMaterial &ioObject, + SSerializerWriteContext &outSavedBuffer) + { + size_t itemOffset = outSavedBuffer.m_MemoryBuffer.size(); + SCustomMaterial *theNewObject = static_cast( + WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer)); + if (theNewObject) { + // Writing it out is easy. Reading it back in means we have to have a correctly setup + // IEffectManager so we + // can remap strings. + outSavedBuffer.m_MemoryBuffer.write(ioObject.GetDataSectionBegin(), + ioObject.m_DataSectionByteSize); + Align(outSavedBuffer.m_MemoryBuffer); + theNewObject = reinterpret_cast(outSavedBuffer.m_MemoryBuffer.begin() + + itemOffset); + SWriteRemapper theWriteRemapper(outSavedBuffer); + // Write any connected objects. + theNewObject->Remap(theWriteRemapper); + } + return theNewObject; + } + + static void Remap(SCustomMaterial &ioObject, SSerializerWriteContext &outSavedBuffer) + { + CRegisteredString theClassName(ioObject.m_ClassName); + ioObject.Remap(outSavedBuffer); + RemapProperties(ioObject, outSavedBuffer, theClassName); + } + + static SCustomMaterial *Read(SSerializerReadContext &inReadContext) + { + SCustomMaterial *theMaterial = ReadGenericGraphObject(inReadContext); + if (theMaterial) { + inReadContext.m_CurrentPtr += theMaterial->m_DataSectionByteSize; + inReadContext.Align(); + RemapProperties(*theMaterial, inReadContext); + } + return theMaterial; + } +}; + +#ifdef _INTEGRITYPLATFORM + template + void SWriteRemapper::Remap(const TObjType *inObj) + { + if (inObj) + SGraphObjectSerializerImpl::Write(*inObj, m_WriteBuffer); + } +#endif + +template <> +struct SGraphObjectSerializerImpl +{ + static SGraphObject *Write(const SPathSubPath &ioObject, + SSerializerWriteContext &outSavedBuffer) + { + SPathSubPath *theObject = WriteGenericGraphObjectNoRemap(ioObject, outSavedBuffer); + if (theObject) // The object may have already been written. + { + NVConstDataRef thePoints = + outSavedBuffer.m_PathManager.GetPathSubPathBuffer(ioObject); + outSavedBuffer.m_MemoryBuffer.write((QT3DSU32)thePoints.size()); + outSavedBuffer.m_MemoryBuffer.write(thePoints.begin(), thePoints.size()); + // Write mappers just follow pointers and ensure all the associated objects + // are written out. + SWriteRemapper theWriteRemapper(outSavedBuffer); + const_cast(ioObject).Remap(theWriteRemapper); + } + return theObject; + } + + static void Remap(SPathSubPath &ioObject, SSerializerWriteContext &outSavedBuffer) + { + ioObject.Remap(outSavedBuffer); + } + + static SPathSubPath *Read(SSerializerReadContext &inReadContext) + { + SPathSubPath *theSubPath = ReadGenericGraphObject(inReadContext); + if (theSubPath) { + QT3DSU32 numPoints = *inReadContext.Load(); + SPathAnchorPoint *theAnchorPointBuffer = + reinterpret_cast(inReadContext.m_CurrentPtr); + inReadContext.m_CurrentPtr += sizeof(SPathAnchorPoint) * numPoints; + + // CN - !!Note this call is done on multiple threads simultaneously. I added a mutex to + // the path manager object + // so this exact call is always protected. This absolutely caused crashing when it was + // not protected approriately. + inReadContext.m_PathManager.SetPathSubPathData( + *theSubPath, toConstDataRef(theAnchorPointBuffer, numPoints)); + } + return theSubPath; + } +}; + +void WriteGraphObject(const SGraphObject &inObject, SSerializerWriteContext &outSavedBuffer) +{ + SGraphObject *newObject = NULL; + switch (inObject.m_Type) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case GraphObjectTypes::type: \ + newObject = SGraphObjectSerializerImpl::Write( \ + static_cast(inObject), outSavedBuffer); \ + break; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + QT3DS_ASSERT(false); + break; + } +} + +void WriteNodeList(nvvector &inList, SSerializerWriteContext &outSavedBuffer) +{ + for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) + WriteGraphObject(*inList[idx], outSavedBuffer); +} + +// Now write everything you haven't written so far, skip writing renderables or cameras or lights +void WriteNonRenderableNonCLNode(const SNode &inNode, SSerializerWriteContext &outSavedBuffer) +{ + if (GraphObjectTypes::IsLightCameraType(inNode.m_Type) == false + && GraphObjectTypes::IsRenderableType(inNode.m_Type) == false) { + WriteGraphObject(inNode, outSavedBuffer); + } + for (const SNode *theChild = inNode.m_FirstChild; theChild; theChild = theChild->m_NextSibling) + WriteNonRenderableNonCLNode(*theChild, outSavedBuffer); +} + +SGraphObject *ReadGraphObject(SSerializerReadContext &inContext) +{ + if (inContext.m_CurrentPtr + sizeof(SGraphObject) < inContext.m_EndPtr) { + SGraphObject *theObject = reinterpret_cast(inContext.m_CurrentPtr); + switch (theObject->m_Type) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case GraphObjectTypes::type: \ + SGraphObjectSerializerImpl::Read(inContext); \ + break; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + QT3DS_ASSERT(false); + theObject = NULL; + break; + } + return theObject; + } + return NULL; +} +} + +void SGraphObjectSerializer::Save(NVFoundationBase &inFoundation, + const SPresentation &inPresentation, + qt3ds::render::SWriteBuffer &outSavedData, + IDynamicObjectSystem &inDynamicObjectSystem, + IPathManager &inPathManager, SPtrOffsetMap &outSceneGraphOffsets, + IStringTable &inStringTable, + NVDataRef inExtraGraphObjects) +{ + using namespace qt3ds::foundation; + nvvector theLightCameraList(inFoundation.getAllocator(), + "SGraphObjectSerializer::theLightCameraList"); + nvvector theRenderableList(inFoundation.getAllocator(), + "SGraphObjectSerializer::theRenderableList"); + TObjectFileStatList theStatList(inFoundation.getAllocator(), + "SGraphObjectSerializer::FileSizeStats"); + // We want to save out the scene graph in the order we are going to traverse it normally. + // This is reverse depth first for the lights, cameras, and renderables and depth first for + // everything else so we go + // in two passes per layer. + // We expect the incoming data buffer to be aligned already. + QT3DS_ASSERT(outSavedData.size() % 4 == 0); + if (inPresentation.m_Scene) { + QT3DSU32 theDataSectionStart = outSavedData.size(); + outSavedData.writeZeros(4); + SSerializerWriteContext theWriteContext( + outSceneGraphOffsets, outSavedData, inStringTable.GetRemapMap(), theDataSectionStart, + inDynamicObjectSystem, inPathManager, theStatList, inFoundation.getAllocator(), + inPresentation.m_PresentationDirectory, inStringTable); + // First pass, just write out the data. + WriteGraphObject(inPresentation, theWriteContext); + WriteGraphObject(*inPresentation.m_Scene, theWriteContext); + for (const SLayer *theLayer = inPresentation.m_Scene->m_FirstChild; theLayer; + theLayer = static_cast(theLayer->m_NextSibling)) { + theLightCameraList.clear(); + theRenderableList.clear(); + PrepareFirstPass(*theLayer, theLightCameraList, theRenderableList); + eastl::reverse(theLightCameraList.begin(), theLightCameraList.end()); + eastl::reverse(theRenderableList.begin(), theRenderableList.end()); + WriteNodeList(theLightCameraList, theWriteContext); + WriteNodeList(theRenderableList, theWriteContext); + } + // Now just write everything *but* renderable objects and cameras. + for (const SLayer *theLayer = inPresentation.m_Scene->m_FirstChild; theLayer; + theLayer = static_cast(theLayer->m_NextSibling)) { + WriteNonRenderableNonCLNode(*theLayer, theWriteContext); + } + // Write out any extra objects we haven't covered yet. + for (QT3DSU32 idx = 0, end = inExtraGraphObjects.size(); idx < end; ++idx) + WriteGraphObject(*inExtraGraphObjects[idx], theWriteContext); + + QT3DSU32 theNumObjects = theWriteContext.m_OffsetMap.size(); + QT3DSU32 *theCountPtr = reinterpret_cast(outSavedData.begin() + theDataSectionStart); + *theCountPtr = theNumObjects; + + // Second pass, perform remapping on all the objects to change their pointers to offsets + for (SPtrOffsetMap::iterator theIter = outSceneGraphOffsets.begin(), + theEnd = outSceneGraphOffsets.end(); + theIter != theEnd; ++theIter) { + QT3DSU8 *theDataPtr = outSavedData.begin() + theDataSectionStart + theIter->second; + SGraphObject *theGraphObj = reinterpret_cast(theDataPtr); + switch (theGraphObj->m_Type) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case GraphObjectTypes::type: \ + SGraphObjectSerializerImpl::Remap(static_cast(*theGraphObj), \ + theWriteContext); \ + break; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + QT3DS_ASSERT(false); + break; + } + } + } +#ifdef _DEBUG + qCDebug(TRACE_INFO, "--File size stats:"); + // Tell the users how much space is used in the file based on object type: + for (QT3DSU32 idx = 0, end = theStatList.size(); idx < end; ++idx) { + const char *theObjType = GraphObjectTypes::GetObjectTypeName(theStatList[idx].first); + qCDebug(TRACE_INFO, "%s - %d bytes:", theObjType, theStatList[idx].second); + } + qCDebug(TRACE_INFO, "--End file size stats:"); +#endif +}; + +SPresentation *SGraphObjectSerializer::Load(NVDataRef inData, NVDataRef inStrDataBlock, + IDynamicObjectSystemCore &inDynamicObjectSystem, + IPathManagerCore &inPathManager, + NVAllocatorCallback &inAllocator, + const char8_t *inProjectDirectory) +{ + SSerializerReadContext theReadContext(inPathManager, inDynamicObjectSystem, inData, + inStrDataBlock, inAllocator, inProjectDirectory); + SPresentation *retval = NULL; + if (inData.size() < 4) { + QT3DS_ASSERT(false); + return NULL; + } + QT3DSU32 theNumObjects = theReadContext.LoadRef(); + for (QT3DSU32 idx = 0, end = theNumObjects; idx < end; ++idx) { + SGraphObject *theObject = ReadGraphObject(theReadContext); + if (theObject) { + if (theObject->m_Type == GraphObjectTypes::Presentation) + retval = static_cast(theObject); + } else { + QT3DS_ASSERT(false); + } + } + return retval; +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.h b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.h new file mode 100644 index 00000000..8f8420c1 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectSerializer.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GRAPH_OBJECT_SERIALZER_H +#define QT3DS_RENDER_GRAPH_OBJECT_SERIALZER_H + +#include "Qt3DSRender.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + struct SPresentation; + class IEffectSystem; + + struct SGraphObjectSerializer + { + // This will save the tree as it exists but clients may wish to save out extra objects in + // addtion + static void + Save(NVFoundationBase &inFoundation, const SPresentation &inPresentation, + SWriteBuffer &outSavedData, IDynamicObjectSystem &inDynamicObjectSystem, + IPathManager &inPathManager, SPtrOffsetMap &outSceneGraphOffsets, + IStringTable &inStringTable, + NVDataRef inExtraGraphObjects = NVDataRef()); + + // Loading requires a correctly setup effect system because the effects have arbitrary data + // and the strings embedded in that data will + // require string remapping. + static SPresentation *Load(NVDataRef inData, NVDataRef inStrDataBlock, + IDynamicObjectSystemCore &inDynamicObjectSystem, + IPathManagerCore &inPathManager, + NVAllocatorCallback &inAllocator, + const char8_t *inProjectDirectory); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectTypes.h b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectTypes.h new file mode 100644 index 00000000..620f6c5d --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderGraphObjectTypes.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GRAPH_OBJECT_TYPES_H +#define QT3DS_RENDER_GRAPH_OBJECT_TYPES_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSAssert.h" + +namespace qt3ds { +namespace render { + +// If you need a generic switch statement, then these macros will ensure +// you get all the types the first time. +#define QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Presentation) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Scene) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Node) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Layer) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Light) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Camera) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Model) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(DefaultMaterial) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Image) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Text) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Effect) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(RenderPlugin) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(CustomMaterial) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(ReferencedMaterial) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(Path) \ + QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(PathSubPath) + + struct GraphObjectTypes + { + enum Enum { + Unknown = 0, + Presentation, + Scene, + Node, + Layer, + Light, + Camera, + Model, + DefaultMaterial, + Image, + Text, + Effect, + CustomMaterial, + RenderPlugin, + ReferencedMaterial, + Path, + PathSubPath, + Lightmaps, + LastKnownGraphObjectType, + }; + + static bool IsMaterialType(Enum type) + { + switch (type) { + case ReferencedMaterial: + case CustomMaterial: + case DefaultMaterial: + return true; + default: + return false; + } + } + + static bool IsLightmapType(Enum type) + { + switch (type) { + case Lightmaps: + case DefaultMaterial: + return true; + default: + return false; + } + } + + static bool IsNodeType(Enum type) + { + switch (type) { + case Node: + case Layer: + case Light: + case Camera: + case Model: + case Text: + case Path: + return true; + + default: + break; + } + return false; + } + + static bool IsRenderableType(Enum type) + { + switch (type) { + case Model: + case Text: + case Path: + return true; + default: + break; + } + return false; + } + + static bool IsLightCameraType(Enum type) + { + switch (type) { + case Camera: + case Light: + return true; + default: + break; + } + return false; + } + static const char *GetObjectTypeName(Enum inType) + { + switch (inType) { +#define QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE(type) \ + case type: \ + return #type; + QT3DS_RENDER_ITERATE_GRAPH_OBJECT_TYPES +#undef QT3DS_RENDER_HANDL_GRAPH_OBJECT_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return ""; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.cpp new file mode 100644 index 00000000..d699179f --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.cpp @@ -0,0 +1,883 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2001 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSRender.h" +#include "foundation/Qt3DSMath.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "Qt3DSRenderImageScaler.h" +#include "foundation/Qt3DSMemoryBuffer.h" + +using namespace qt3ds::render; +//============================================================================== +// Namespace +//============================================================================== +CImageScaler::CImageScaler(NVAllocatorCallback &inAlloc) + : m_Allocator(inAlloc) +{ +} +//============================================================================== +/** + * Scales the given image by the given scale factor. + * + * This method creates a new image based on the parameters given. + * + * @param inScaleMethod type of scaling operation + * @param inOldBuffer points to the old picture + * @param inOldWidth width of the old picture + * @param inOldHeight height of the old picture + * @param inNewBuffer will point to the scaled picture + * @param inNewWidth width of the new picture + * @param inNewHeight height of the new picture + * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) + * also equivalent to the return value of the CTextureType::PixelSize method. + */ +void CImageScaler::Scale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, + unsigned long inOldWidth, unsigned long inOldHeight, + unsigned char *&outNewBuffer, unsigned long inNewWidth, + unsigned long inNewHeight, unsigned long inPlanes) +{ + switch (inScaleMethod) { + case SCALEMETHOD_CROP: + CImageScaler::Crop(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, + inNewHeight, inPlanes); + break; + + case SCALEMETHOD_BILINEAR: + CImageScaler::Bilinear(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, + inNewHeight, inPlanes); + break; + + default: + QT3DS_ASSERT(false); + break; + } +} + +//============================================================================== +/** + * Scales the given image by the given scale factor. + * + * This method creates a new image based on the parameters given. + * + * @param inScaleMethod type of scaling operation + * @param inOldBuffer points to the old picture + * @param inOldWidth width of the old picture + * @param inOldHeight height of the old picture + * @param inNewBuffer will point to the scaled picture + * @param inNewWidth width of the new picture + * @param inNewHeight height of the new picture + * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) + * also equivalent to the return value of the CTextureType::PixelSize method. + */ +void CImageScaler::FastScale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, + unsigned long inOldWidth, unsigned long inOldHeight, + unsigned char *&outNewBuffer, unsigned long inNewWidth, + unsigned long inNewHeight, unsigned long inPlanes) +{ + switch (inScaleMethod) { + case SCALEMETHOD_CROP: + CImageScaler::Crop(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, + inNewHeight, inPlanes); + break; + + case SCALEMETHOD_POINTSAMPLE: + CImageScaler::FastPointSample(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, + inNewWidth, inNewHeight, inPlanes); + break; + + default: + QT3DS_ASSERT(false); + break; + } +} + +//============================================================================== +/** + * Debug method that simply crops the picture instead of scaling. + * + * Not for use in production. This is a test method to exercise the framework. + * + * @param inOldBuffer points to the old picture + * @param inOldWidth width of the old picture + * @param inOldHeight height of the old picture + * @param inNewBuffer will point to the scaled picture + * @param inNewWidth width of the new picture + * @param inNewHeight height of the new picture + * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) + * also equivalent to the return value of the CTextureType::PixelSize method. +*/ +void CImageScaler::Crop(unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, unsigned long inPlanes) +{ + Q_UNUSED(inOldHeight); + + QT3DS_ASSERT(inNewWidth <= inOldWidth); + QT3DS_ASSERT(inNewHeight <= inOldHeight); + + long theMinWidth = NVMin(inOldWidth, inNewWidth); + + outNewBuffer = new unsigned char[inNewWidth * inNewHeight * inPlanes]; + ::memset(outNewBuffer, 0, inNewWidth * inNewHeight * inPlanes); + + for (unsigned long theRow = 0; theRow < inNewHeight; ++theRow) { + ::memcpy(outNewBuffer + theRow * inNewWidth * inPlanes, + inOldBuffer + theRow * inOldWidth * inPlanes, theMinWidth * inPlanes); + } +} + +//============================================================================== +/** + * Plain scaling. + * + * Code adopted from http://www.codeguru.com/bitmap/SmoothBitmapResizing.html + * Preliminary formatting completed but still needs work. + * + * @param inOldBuffer points to the old picture + * @param inOldWidth width of the old picture + * @param inOldHeight height of the old picture + * @param inNewBuffer will point to the scaled picture + * @param inNewWidth width of the new picture + * @param inNewHeight height of the new picture + * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) + * also equivalent to the return value of the CTextureType::PixelSize method. +*/ +void CImageScaler::Bilinear(unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, + unsigned long inPlanes) +{ + QT3DS_ASSERT(inPlanes > 0); + + outNewBuffer = new unsigned char[inNewWidth * inNewHeight * inPlanes]; + CImageScaler::Resize(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, inNewWidth, + inNewHeight, inPlanes); +} + +//============================================================================== +/** + * Fast removal of selected pixels. + * + * Really fast scanning of every n-th pixel. This algorithm works basically by + * adding a fraction to the source pointer for each pixel destination, using + * fixed point arithmetic. + * + * @param inOldBuffer points to the old picture + * @param inOldWidth width of the old picture + * @param inOldHeight height of the old picture + * @param inNewBuffer will point to the scaled picture + * @param inNewWidth width of the new picture + * @param inNewHeight height of the new picture + * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) + * also equivalent to the return value of the CTextureType::PixelSize method. +*/ +void CImageScaler::FastPointSample(unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, + unsigned long inPlanes) +{ + unsigned long theXAccum; + unsigned long theYAccum; + unsigned long theXConst; + unsigned long theYConst; + unsigned long theRow; + unsigned long theColumn; + unsigned long theAdd; + unsigned long theSrcIndex; + outNewBuffer = new unsigned char[inNewWidth * inNewHeight * inPlanes]; + + // *** Debug *** + // char dMessage[100]; + //::sprintf( dMessage, "PointSample: %ldx%ld to %ldx%ld\n",inOldInfo.m_Width, inOldInfo.m_Height, outNewInfo.m_Width, outNewInfo.m_Height ); + //::OutputDebugString( dMessage ); + + switch (inPlanes) { + case 4: { + long *theSrc; + long *theDst; + theSrc = reinterpret_cast(inOldBuffer); + theDst = reinterpret_cast(outNewBuffer); + theYAccum = 0; + theXConst = (inOldWidth << 16) / inNewWidth; + theYConst = (inOldHeight << 16) / inNewHeight; + unsigned long theAdd; + for (theRow = 0; theRow < inNewHeight; theRow++) { + theXAccum = 0; + theSrcIndex = 0; + for (theColumn = 0; theColumn < inNewWidth; theColumn++) { + + theXAccum += theXConst; + theAdd = theXAccum >> 16; + *theDst = theSrc[theSrcIndex]; + theDst++; + theSrcIndex += theAdd; + // Clear out the integer portion of the accumulator. + theXAccum = theXAccum & 0xFFFF; + } + + theYAccum += theYConst; + theAdd = (theYAccum) >> 16; + theSrc += theAdd * inOldWidth; + // Clear out the integer portion of the accumulator. + theYAccum = theYAccum & 0xFFFF; + } + } break; + + case 3: { + unsigned char *theDest; + unsigned char *theSource; + theDest = reinterpret_cast(outNewBuffer); + theSource = reinterpret_cast(inOldBuffer); + theYAccum = 0; + theXConst = (inOldWidth << 16) / inNewWidth; + theYConst = (inOldHeight << 16) / inNewHeight; + for (theRow = 0; theRow < inNewHeight; ++theRow) { + theXAccum = 0; + theSrcIndex = 0; + for (theColumn = 0; theColumn < inNewWidth; ++theColumn) { + theDest[0] = theSource[0]; + theDest[1] = theSource[1]; + theDest[2] = theSource[2]; + theDest += 3; + theSrcIndex += 3 * (theXAccum) >> 16; + theXAccum = theXAccum & 0xFFFF; + } + theYAccum += theYConst; + theAdd = (theYAccum) >> 16; + theSource += theAdd * inOldWidth * 3; + theYAccum = theYAccum & 0xFFFF; + } + } break; + + case 2: { + short *theDest; + short *theSource; + theDest = reinterpret_cast(outNewBuffer); + theSource = reinterpret_cast(inOldBuffer); + theYAccum = 0; + theXConst = (inOldWidth << 16) / inNewWidth; + theYConst = (inOldHeight << 16) / inNewHeight; + for (unsigned long theY = 0; theY < inNewHeight; ++theY) { + theXAccum = 0; + theSrcIndex = 0; + for (unsigned long theX = 0; theX < inNewWidth; ++theX) { + *theDest = *theSource; + ++theDest; + theXAccum += theXConst; + theSrcIndex += (theXAccum) >> 16; + theXAccum = theXAccum & 0xFFFF; + } + theYAccum += theYConst; + theAdd = (theYAccum) >> 16; + theSource += theAdd * inOldWidth; + theYAccum = theYAccum & 0xFFFF; + } + } break; + + case 1: { + unsigned char *theDest; + unsigned char *theSource; + theDest = reinterpret_cast(outNewBuffer); + theSource = reinterpret_cast(inOldBuffer); + theYAccum = 0; + theXConst = (inOldWidth << 16) / inNewWidth; + theYConst = (inOldHeight << 16) / inNewHeight; + for (unsigned long theY = 0; theY < inNewHeight; ++theY) { + theXAccum = 0; + theSrcIndex = 0; + for (unsigned long theX = 0; theX < inNewWidth; ++theX) { + *theDest = *theSource; + ++theDest; + theXAccum += theXConst; + theSrcIndex += (theXAccum) >> 16; + theXAccum = theXAccum & 0xFFFF; + } + theYAccum += theYConst; + theAdd = (theYAccum) >> 16; + theSource += theAdd * inOldWidth; + theYAccum = theYAccum & 0xFFFF; + } + } break; + + default: + QT3DS_ASSERT(false); + break; + } +} + +//============================================================================== +/** + * @param inWidth + * @param inHeight + * @return unsigned char* + */ +unsigned char *CImageScaler::AllocateBuffer(long inWidth, long inHeight) +{ + unsigned char *theBuffer = new unsigned char[inHeight * inWidth * 4]; + return theBuffer; +} + +//============================================================================== +/** + * @param ioBuffer the buffer to release + */ +void CImageScaler::ReleaseBuffer(unsigned char *&ioBuffer) +{ + delete[] ioBuffer; + ioBuffer = NULL; +} + +//============================================================================== +/** + * @param inOldBuffer points to the old picture + * @param inOldWidth width of the old picture + * @param inOldHeight height of the old picture + * @param inNewBuffer will point to the scaled picture + * @param inNewWidth width of the new picture + * @param inNewHeight height of the new picture + * @param inPlanes number of planes (1 for greyscale, 3 for rgb, etc) + * also equivalent to the return value of the CTextureType::PixelSize method. + */ +void CImageScaler::Resize(unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, + unsigned long inPlanes) +{ + QT3DS_ASSERT(inPlanes == 4); + + // only do the temporary allocation if necessary + if (inOldWidth < inNewWidth || inOldHeight < inNewHeight) { + CImageScaler::ExpandRowsAndColumns(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, + inNewWidth, inNewHeight, inPlanes); + return; + } else { + // The downsampling algorithms *do* assume four planes. + if (inOldWidth > inNewWidth && inOldHeight > inNewHeight) { + MemoryBuffer<> theBuffer(ForwardingAllocator(m_Allocator, "ImageScaler::TempBuffer")); + theBuffer.reserve(inNewWidth * inOldHeight * 4); + unsigned char *theTempBuffer = theBuffer.begin(); + CImageScaler::ReduceCols(inOldBuffer, inOldWidth, inOldHeight, theTempBuffer, + inNewWidth); + CImageScaler::ReduceRows(theTempBuffer, inNewWidth, inOldHeight, outNewBuffer, + inNewHeight); + } else if (inOldWidth > inNewWidth) { + CImageScaler::ReduceCols(inOldBuffer, inOldWidth, inOldHeight, outNewBuffer, + inNewWidth); + } else if (inOldHeight > inNewHeight) { + CImageScaler::ReduceRows(inOldBuffer, inNewWidth, inOldHeight, outNewBuffer, + inNewHeight); + } + } +} + +void CImageScaler::ExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, + unsigned long inHeight, unsigned char *outBuffer, + unsigned long inDstWidth, unsigned long inDstHeight, + unsigned long inPlanes) +{ + if (inDstWidth < inWidth || inDstHeight < inHeight) { + return; + } + /*if( inPlanes == 4 ) + { + FastExpandRowsAndColumns( inBuffer, inWidth, inHeight, + outBuffer, inDstWidth, inDstHeight ); + return; + }*/ + unsigned long theYPosition; + unsigned short theYRatio; + unsigned short theYInvRatio; + unsigned long theXPosition; + unsigned short theXRatio; + unsigned short theXInvRatio; + + unsigned long theRow; + unsigned long theColumn; + unsigned long theSrcIndex; + unsigned long theDstIndex; + unsigned long theSrcLineLength; + unsigned long theTemp; + unsigned long thePixel; + + theDstIndex = 0; + theSrcIndex = 0; + theSrcLineLength = inWidth * inPlanes; + theYPosition = inDstHeight; + theYRatio = 1 << 8; + theYInvRatio = 0; + theXInvRatio = 0; + // Here we go.... + // This algorithm will be quite a bit hairy, if you want + // to understand it, then look at the two expand alogorithms above + // and realize the this is just the logical combination of the two + for (theRow = 0; theRow < inDstHeight; theRow++) { + // Run through all the rows, multiplying if necessary the two ratio's together + theXPosition = inDstWidth; + if (theYPosition < inHeight) { + // We have crossed a row boundary + theYRatio = (unsigned short)((theYPosition << 8) / inHeight); + theYInvRatio = (unsigned short)((1 << 8) - theYRatio); + + for (theColumn = 0; theColumn < inDstWidth; theColumn++) { + if (theXPosition < inWidth) { + theXRatio = (unsigned short)((theXPosition << 8) / inWidth); + theXInvRatio = (unsigned short)((1 << 8) - theXRatio); + + // The combination of both the x and y ratio's + unsigned long theLeftRatio = (theXRatio * theYRatio) >> 8; + unsigned long theRightRatio = (theXInvRatio * theYRatio) >> 8; + unsigned long theLowLeftRatio = (theXRatio * theYInvRatio) >> 8; + unsigned long theLowRightRatio = (theXInvRatio * theYInvRatio) >> 8; + // We are on a row and column boundary, thus each pixel here is the + // combination of four pixels (left right, low left, low right) + for (thePixel = 0; thePixel < inPlanes; thePixel++) { + // Left side first + theTemp = (theLeftRatio * inBuffer[theSrcIndex]); + theTemp += (theRightRatio * inBuffer[theSrcIndex + inPlanes]); + theTemp += (theLowLeftRatio * inBuffer[theSrcIndex + theSrcLineLength]); + theTemp += (theLowRightRatio + * inBuffer[theSrcIndex + theSrcLineLength + inPlanes]); + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 8); + theDstIndex++; + theSrcIndex++; + } + // Reset our position calculation + theXPosition = inDstWidth - inWidth + theXPosition; + } else { + for (thePixel = 0; thePixel < inPlanes; thePixel++) { + theTemp = theYRatio * inBuffer[theSrcIndex + thePixel]; + theTemp += + theYInvRatio * inBuffer[theSrcIndex + theSrcLineLength + thePixel]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 8); + theDstIndex++; + } + // Reset our position calculation + theXPosition -= inWidth; + } + } + // Reset our position calculation + theYPosition = inDstHeight - inHeight + theYPosition; + // Make the src index point to the next line + theSrcIndex += inPlanes; + } // Ends the if to check if we are crossing a row boundary + // Else we are not crossing a row boundary + else { + for (theColumn = 0; theColumn < inDstWidth; theColumn++) { + // If we are crossing a column boundary + if (theXPosition < inWidth) { + theXRatio = (unsigned short)((theXPosition << 8) / inWidth); + theXInvRatio = (unsigned short)((1 << 8) - theXRatio); + for (thePixel = 0; thePixel < inPlanes; thePixel++) { + theTemp = theXRatio * inBuffer[theSrcIndex]; + theTemp += theXInvRatio * inBuffer[theSrcIndex + inPlanes]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 8); + theSrcIndex++; + theDstIndex++; + } + + theXPosition = inDstWidth - inWidth + theXPosition; + } + // Else we are not crossing a column boundary + else { + for (thePixel = 0; thePixel < inPlanes; thePixel++) { + outBuffer[theDstIndex] = inBuffer[theSrcIndex + thePixel]; + theDstIndex++; + } + theXPosition -= inWidth; + } + } + // reset our y position indicator + theYPosition -= inHeight; + // reset the src index to the beginning the next line + theSrcIndex += inPlanes; + // reset src index to the beginning of this line + theSrcIndex -= theSrcLineLength; + } // End of else for row boundary + } // End of for loop for iterating through all rows +} + +// Assuming the number of planes is four + +void CImageScaler::FastExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, + unsigned long inHeight, unsigned char *outBuffer, + unsigned long inDstWidth, unsigned long inDstHeight) +{ + + if (inDstWidth < inWidth || inDstHeight < inHeight) { + return; + } + unsigned long theYPosition; + unsigned short theYRatio; + unsigned short theYInvRatio; + unsigned long theXPosition; + unsigned short theXRatio; + unsigned short theXInvRatio; + // The combination of both the x and y ratio's + unsigned long theLeftRatio; + unsigned long theRightRatio; + unsigned long theLowLeftRatio; + unsigned long theLowRightRatio; + + unsigned long theRow; + unsigned long theColumn; + unsigned long theSrcIndex; + unsigned long theDstIndex; + unsigned long theSrcLineLength; + unsigned long theTemp; + + theDstIndex = 0; + theSrcIndex = 0; + theSrcLineLength = inWidth * 4; + theYPosition = inDstHeight; + theYInvRatio = 0; + theXInvRatio = 0; + // Here we go.... + // This algorithm will be quite a bit hairy, if you want + // to understand it, then look at the two expand alogorithms above + // and realize the this is just the logical combination of the two + for (theRow = 0; theRow < inDstHeight; theRow++) { + // Run through all the rows, multiplying if necessary the two ratio's together + theXPosition = inDstWidth; + if (theYPosition < inHeight) { + // We have crossed a row boundary + theYRatio = (unsigned short)((theYPosition << 8) / inHeight); + theYInvRatio = (unsigned short)((1 << 8) - theYRatio); + + for (theColumn = 0; theColumn < inDstWidth; theColumn++) { + if (theXPosition < inWidth) { + theXRatio = (unsigned short)((theXPosition << 8) / inWidth); + theXInvRatio = (unsigned short)((1 << 8) - theXRatio); + theLeftRatio = (theXRatio * theYRatio) >> 8; + theRightRatio = (theXInvRatio * theYRatio) >> 8; + theLowLeftRatio = (theXRatio * theYInvRatio) >> 8; + theLowRightRatio = (theXInvRatio * theYInvRatio) >> 8; + // We are on a row and column boundary, thus each pixel here is the + // combination of four pixels (left right, low left, low right) + + // Left side first + theTemp = (inBuffer[theSrcIndex]); + theTemp += (inBuffer[theSrcIndex + 4]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); + theDstIndex++; + theSrcIndex++; + // Left side first + theTemp = (inBuffer[theSrcIndex]); + theTemp += (inBuffer[theSrcIndex + 4]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); + theDstIndex++; + theSrcIndex++; + // Left side first + theTemp = (inBuffer[theSrcIndex]); + theTemp += (inBuffer[theSrcIndex + 4]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); + theDstIndex++; + theSrcIndex++; + // Left side first + theTemp = (inBuffer[theSrcIndex]); + theTemp += (inBuffer[theSrcIndex + 4]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength]); + theTemp += (inBuffer[theSrcIndex + theSrcLineLength + 4]); + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 2); + theDstIndex++; + theSrcIndex++; + // Reset our position calculation + theXPosition = inDstWidth - inWidth + theXPosition; + } else { + + theTemp = inBuffer[theSrcIndex]; + theTemp += inBuffer[theSrcIndex + theSrcLineLength]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theDstIndex++; + theTemp = inBuffer[theSrcIndex + 1]; + theTemp += inBuffer[theSrcIndex + theSrcLineLength + 1]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theDstIndex++; + theTemp = inBuffer[theSrcIndex + 2]; + theTemp += inBuffer[theSrcIndex + theSrcLineLength + 2]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theDstIndex++; + theTemp = inBuffer[theSrcIndex + 3]; + theTemp += inBuffer[theSrcIndex + theSrcLineLength + 3]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theDstIndex++; + // Reset our position calculation + theXPosition -= inWidth; + } + } + // Reset our position calculation + theYPosition = inDstHeight - inHeight + theYPosition; + // Make the src index point to the next line + theSrcIndex += 4; + } // Ends the if to check if we are crossing a row boundary + // Else we are not crossing a row boundary + else { + for (theColumn = 0; theColumn < inDstWidth; theColumn++) { + // If we are crossing a column boundary + if (theXPosition < inWidth) { + theXRatio = (unsigned short)((theXPosition << 8) / inWidth); + theXInvRatio = (unsigned short)((1 << 8) - theXRatio); + + theTemp = inBuffer[theSrcIndex]; + theTemp += inBuffer[theSrcIndex + 4]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theSrcIndex++; + theDstIndex++; + theTemp = inBuffer[theSrcIndex]; + theTemp += inBuffer[theSrcIndex + 4]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theSrcIndex++; + theDstIndex++; + theTemp = inBuffer[theSrcIndex]; + theTemp += inBuffer[theSrcIndex + 4]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theSrcIndex++; + theDstIndex++; + theTemp = inBuffer[theSrcIndex]; + theTemp += inBuffer[theSrcIndex + 4]; + outBuffer[theDstIndex] = (unsigned char)(theTemp >> 1); + theSrcIndex++; + theDstIndex++; + + theXPosition = inDstWidth - inWidth + theXPosition; + } + // Else we are not crossing a column boundary + else { + *((long *)(outBuffer + theDstIndex)) = *((long *)(inBuffer + theSrcIndex)); + theDstIndex += 4; + theXPosition -= inWidth; + } + } + // reset our y position indicator + theYPosition -= inHeight; + // reset the src index to the beginning the next line + theSrcIndex += 4; + // reset src index to the beginning of this line + theSrcIndex -= theSrcLineLength; + } // End of else for row boundary + } // End of for loop for iterating through all rows +} + +//============================================================================== +/** + * @param inSrcBuffer + */ +void CImageScaler::ReduceCols(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, + unsigned char *&outDstBuffer, long inDstWidth) +{ + long theDDAConst = static_cast(1024.0 * inDstWidth / inSrcWidth); + long theDDAAccum = 0L; + long thePixelCount; + + long theSrcRow; + long theSrcCol; + long theDstCol; + + long theRedAccum; + long theGreenAccum; + long theBlueAccum; + long theAlphaAccum; + + unsigned char *theDstPointer = outDstBuffer; + unsigned char *theSrcPointer = inSrcBuffer; + unsigned char *theSrcRowPointer; + unsigned char *theDstRowPointer; + + long theSrcStepSize = 4; + long theDstStepSize = 4; + + for (theSrcRow = 0; theSrcRow < inSrcHeight; ++theSrcRow) { + + theSrcRowPointer = theSrcPointer + (theSrcRow * inSrcWidth * theSrcStepSize); + theDstRowPointer = theDstPointer + (theSrcRow * inDstWidth * theDstStepSize); + + theSrcCol = 0L; + theDstCol = 0L; + theRedAccum = 0L; + theGreenAccum = 0L; + theBlueAccum = 0L; + theAlphaAccum = 0L; + thePixelCount = 0L; + theDDAAccum = 0L; + + while (theSrcCol < inSrcWidth) { + while ((theDDAAccum < 1024L) && (theSrcCol < inSrcWidth)) { + theRedAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 0]; + theGreenAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 1]; + theBlueAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 2]; + theAlphaAccum += 1024L * theSrcRowPointer[(theSrcCol * theSrcStepSize) + 3]; + + theDDAAccum += theDDAConst; + thePixelCount += 1024L; + ++theSrcCol; + } + + theDDAAccum = (theSrcCol < inSrcWidth) ? (theDDAAccum - 1024L) : (0L); + thePixelCount -= theDDAAccum; + + theRedAccum -= + theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 0]; + theGreenAccum -= + theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 1]; + theBlueAccum -= + theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 2]; + theAlphaAccum -= + theDDAAccum * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 3]; + + theDstRowPointer[(theDstCol * theDstStepSize) + 0] = + (unsigned char)(theRedAccum / thePixelCount); + theDstRowPointer[(theDstCol * theDstStepSize) + 1] = + (unsigned char)(theGreenAccum / thePixelCount); + theDstRowPointer[(theDstCol * theDstStepSize) + 2] = + (unsigned char)(theBlueAccum / thePixelCount); + theDstRowPointer[(theDstCol * theDstStepSize) + 3] = + (unsigned char)(theAlphaAccum / thePixelCount); + + thePixelCount = 1024L - theDDAAccum; + ++theDstCol; + + if (theDstCol >= inDstWidth) { + break; + } + + theRedAccum = + thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 0]; + theGreenAccum = + thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 1]; + theBlueAccum = + thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 2]; + theAlphaAccum = + thePixelCount * (long)theSrcRowPointer[((theSrcCol - 1) * theSrcStepSize) + 3]; + } + } +} + +//============================================================================== +/** + * @param inSrcBuffer + */ +void CImageScaler::ReduceRows(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, + unsigned char *&outDstBuffer, long inDstHeight) +{ + long theDDAConst = static_cast(1024.0 * inDstHeight / inSrcHeight); + long theDDAAccum = 0; + long thePixelCount; + + long theSrcRow; + long theSrcCol; + long theDstRow; + + long theRedAccum; + long theGreenAccum; + long theBlueAccum; + long theAlphaAccum; + + unsigned char *theDstPointer = outDstBuffer; + unsigned char *theSrcPointer = inSrcBuffer; + unsigned char *theSrcColPointer = NULL; + unsigned char *theDstColPointer = NULL; + + long theStepSize = 4; + long theSrcStride = 4 * inSrcWidth; + long theDstStride = 4 * inSrcWidth; + + for (theSrcCol = 0; theSrcCol < inSrcWidth; ++theSrcCol) { + theSrcColPointer = theSrcPointer + (theSrcCol * theStepSize); + theDstColPointer = theDstPointer + (theSrcCol * theStepSize); + + theSrcRow = 0L; + theDstRow = 0L; + theRedAccum = 0L; + theGreenAccum = 0L; + theBlueAccum = 0L; + theAlphaAccum = 0L; + thePixelCount = 0L; + + theDDAAccum = 0L; + + while (theSrcRow < inSrcHeight) { + while ((theDDAAccum < 1024L) && (theSrcRow < inSrcHeight)) { + theRedAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 0]; + theGreenAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 1]; + theBlueAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 2]; + theAlphaAccum += 1024L * theSrcColPointer[(theSrcRow * theSrcStride) + 3]; + + theDDAAccum += theDDAConst; + thePixelCount += 1024L; + ++theSrcRow; + } + + theDDAAccum = (theSrcRow < inSrcHeight) ? (theDDAAccum - 1024L) : (0L); + thePixelCount -= theDDAAccum; + + theRedAccum -= + theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 0]; + theGreenAccum -= + theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 1]; + theBlueAccum -= + theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 2]; + theAlphaAccum -= + theDDAAccum * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 3]; + + theDstColPointer[(theDstRow * theDstStride) + 0] = + (unsigned char)(theRedAccum / thePixelCount); + theDstColPointer[(theDstRow * theDstStride) + 1] = + (unsigned char)(theGreenAccum / thePixelCount); + theDstColPointer[(theDstRow * theDstStride) + 2] = + (unsigned char)(theBlueAccum / thePixelCount); + theDstColPointer[(theDstRow * theDstStride) + 3] = + (unsigned char)(theAlphaAccum / thePixelCount); + + thePixelCount = 1024L - theDDAAccum; + ++theDstRow; + + if (theDstRow >= inDstHeight) { + break; + } + + theRedAccum = + thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 0]; + theGreenAccum = + thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 1]; + theBlueAccum = + thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 2]; + theAlphaAccum = + thePixelCount * (long)theSrcColPointer[((theSrcRow - 1) * theSrcStride) + 3]; + } + } +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.h b/src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.h new file mode 100644 index 00000000..27b51770 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderImageScaler.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2001 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Prefix +//============================================================================== +#ifndef __IMAGESCALER_H_ +#define __IMAGESCALER_H_ +#include "Qt3DSRender.h" + +namespace qt3ds { +namespace render { + //============================================================================== + // Class + //============================================================================== + //============================================================================== + /** + * @class CImageScaler + */ + //============================================================================== + class CImageScaler + { + NVAllocatorCallback &m_Allocator; + + public: + //============================================================================== + // Methods + //============================================================================== + enum EScaleMethod { + SCALEMETHOD_CROP = -1, // Debug only, not a scaler + SCALEMETHOD_POINTSAMPLE = 0, + SCALEMETHOD_BILINEAR = 1, + }; + + //============================================================================== + // Methods + //============================================================================== + + // Access + + public: + CImageScaler(NVAllocatorCallback &inAlloc); + + void Scale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, unsigned long inChannels); + + void FastScale(EScaleMethod inScaleMethod, unsigned char *inOldBuffer, + unsigned long inOldWidth, unsigned long inOldHeight, + unsigned char *&outNewBuffer, unsigned long inNewWidth, + unsigned long inNewHeight, unsigned long inChannels); + + void Crop(unsigned char *inOldBuffer, unsigned long inOldWidth, unsigned long inOldHeight, + unsigned char *&outNewBuffer, unsigned long inNewWidth, unsigned long inNewHeight, + unsigned long inPlanes); + + void Bilinear(unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, unsigned long inPlanes); + + void FastPointSample(unsigned char *inOldBuffer, unsigned long inOldWidth, + unsigned long inOldHeight, unsigned char *&outNewBuffer, + unsigned long inNewWidth, unsigned long inNewHeight, + unsigned long inPlanes); + + unsigned char *AllocateBuffer(long inWidth, long inHeight); + void ReleaseBuffer(unsigned char *&ioBuffer); + void Resize(unsigned char *inOldBuffer, unsigned long inOldWidth, unsigned long inOldHeight, + unsigned char *&outNewBuffer, unsigned long inNewWidth, + unsigned long inNewHeight, unsigned long inPlanes); + + // variable numbers of planes, i.e. greyscale, rb, rbg, and rgba or argb + // Bilinear algorithms, good for quality + void ExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, + unsigned long inHeight, unsigned char *outBuffer, + unsigned long inDstWidth, unsigned long inDstHeight, + unsigned long inPlanes); + + // The method implemented above, but with some optimizations + // specifically, fixed the number of planes at 4 + // eliminated the new/delete allocations + void FastExpandRowsAndColumns(unsigned char *inBuffer, unsigned long inWidth, + unsigned long inHeight, unsigned char *outBuffer, + unsigned long inDstWidth, unsigned long inDstHeight); + + void ReduceCols(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, + unsigned char *&outDstBuffer, long inDstWidth); + void ReduceRows(unsigned char *inSrcBuffer, long inSrcWidth, long inSrcHeight, + unsigned char *&outDstBuffer, long inDstHeight); + }; +} +} + +#endif // !defined(__IMAGESCALER_H_) diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h b/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h new file mode 100644 index 00000000..d3698032 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_IMAGE_TEXTURE_DATA_H +#define QT3DS_RENDER_IMAGE_TEXTURE_DATA_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSFlags.h" + +namespace qt3ds { +namespace render { + + // forward declararion + class Qt3DSRenderPrefilterTexture; + + struct ImageTextureFlagValues + { + enum Enum { + HasTransparency = 1, + InvertUVCoords = 1 << 1, + PreMultiplied = 1 << 2, + }; + }; + + struct SImageTextureFlags : public NVFlags + { + bool HasTransparency() const + { + return this->operator&(ImageTextureFlagValues::HasTransparency); + } + void SetHasTransparency(bool inValue) + { + clearOrSet(inValue, ImageTextureFlagValues::HasTransparency); + } + + bool IsInvertUVCoords() const + { + return this->operator&(ImageTextureFlagValues::InvertUVCoords); + } + void SetInvertUVCoords(bool inValue) + { + clearOrSet(inValue, ImageTextureFlagValues::InvertUVCoords); + } + + bool IsPreMultiplied() const + { + return this->operator&(ImageTextureFlagValues::PreMultiplied); + } + void SetPreMultiplied(bool inValue) + { + clearOrSet(inValue, ImageTextureFlagValues::PreMultiplied); + } + }; + + struct SImageTextureData + { + NVRenderTexture2D *m_Texture; + SImageTextureFlags m_TextureFlags; + Qt3DSRenderPrefilterTexture *m_BSDFMipMap; + + SImageTextureData() + : m_Texture(NULL) + , m_BSDFMipMap(NULL) + { + } + + bool operator!=(const SImageTextureData &inOther) + { + return m_Texture != inOther.m_Texture || m_TextureFlags != inOther.m_TextureFlags + || m_BSDFMipMap != inOther.m_BSDFMipMap; + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.cpp new file mode 100644 index 00000000..1a418b1e --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderInputStreamFactory.h" + +#include "stdio.h" + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/string.h" +#include "EASTL/vector.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/FileTools.h" +#include "foundation/Qt3DSMutex.h" + +#include +#include +#include +#include +#include + +using namespace qt3ds::render; + +namespace { +struct SInputStream : public IRefCountedInputStream +{ + NVFoundationBase &m_Foundation; + QString m_Path; + QFile m_File; + volatile QT3DSI32 mRefCount; + + SInputStream(NVFoundationBase &inFoundation, const QString &inPath) + : m_Foundation(inFoundation) + , m_Path(inPath) + , m_File(inPath) + , mRefCount(0) + { + m_File.open(QIODevice::ReadOnly); + } + virtual ~SInputStream() + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + QT3DSU32 Read(NVDataRef data) override + { + return m_File.read((char *)data.begin(), data.size()); + } + + bool Write(NVConstDataRef /*data*/) override + { + QT3DS_ASSERT(false); + return false; + } + + void SetPosition(QT3DSI64 inOffset, qt3ds::foundation::SeekPosition::Enum inEnum) override + { + if (inOffset > QT3DS_MAX_I32 || inOffset < QT3DS_MIN_I32) { + qCCritical(INVALID_OPERATION, "Attempt to seek further than platform allows"); + QT3DS_ASSERT(false); + return; + } else { + CFileTools::SetStreamPosition(m_File, inOffset, inEnum); + } + } + QT3DSI64 GetPosition() const override + { + return m_File.pos(); + } + + static SInputStream *OpenFile(const QString &inPath, NVFoundationBase &inFoundation) + { + return QT3DS_NEW(inFoundation.getAllocator(), SInputStream)(inFoundation, inPath); + } +}; + +typedef eastl::basic_string TStrType; +struct SFactory : public IInputStreamFactory +{ + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + + Mutex m_Mutex; + typedef Mutex::ScopedLock TScopedLock; + + const QString QT3DSTUDIO_TAG = QStringLiteral("qt3dstudio"); + + SFactory(NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , mRefCount(0) + , m_Mutex(inFoundation.getAllocator()) + { + // Add the top-level qrc directory + if (!QDir::searchPaths(QT3DSTUDIO_TAG).contains(QLatin1String(":/"))) + QDir::addSearchPath(QT3DSTUDIO_TAG, QStringLiteral(":/")); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + QFileInfo matchCaseInsensitiveFile(const QString& file, bool inQuiet) + { + if (!inQuiet) { + // Some assets are searched for in several levels in the project structure, + // we don't want to alert user of things that can't be fixed in the presentation + // itself. + qCWarning(WARNING, PERF_INFO, "Case-insensitive matching with file: %s", + file.toLatin1().constData()); + } + const QStringList searchDirectories = QDir::searchPaths(QT3DSTUDIO_TAG); + for (const auto &directoryPath : searchDirectories) { + QFileInfo fileInfo(file); + QDirIterator it(directoryPath, {fileInfo.fileName()}, QDir::NoFilter, + QDirIterator::Subdirectories); + while (it.hasNext()) { + QString filePath = it.next(); + if (filePath.compare(QDir::cleanPath(directoryPath + '/' + file), + Qt::CaseInsensitive) == 0) { + return QFileInfo(filePath); + } + } + } + + return QFileInfo(); + } + + void AddSearchDirectory(const char8_t *inDirectory) override + { + TScopedLock __factoryLocker(m_Mutex); + QString localDir = CFileTools::NormalizePathForQtUsage(inDirectory); + QDir directory(localDir); + if (!directory.exists()) { + qCCritical(INTERNAL_ERROR, "Adding search directory: %s", inDirectory); + return; + } + + if (!QDir::searchPaths(QT3DSTUDIO_TAG).contains(localDir)) + QDir::addSearchPath(QT3DSTUDIO_TAG, localDir); + } + + + IRefCountedInputStream *GetStreamForFile(const QString &inFilename, bool inQuiet) override + { + TScopedLock __factoryLocker(m_Mutex); + QString localFile = CFileTools::NormalizePathForQtUsage(inFilename); + QFileInfo fileInfo = QFileInfo(localFile); + SInputStream *inputStream = nullptr; + // Try to match the file with the search paths + if (!fileInfo.exists()) + fileInfo.setFile(QStringLiteral("qt3dstudio:") + localFile); + + // Try to match the case-insensitive file with the given search paths + if (!fileInfo.exists()) + fileInfo = matchCaseInsensitiveFile(localFile, inQuiet); + + if (fileInfo.exists()) + inputStream = SInputStream::OpenFile(fileInfo.absoluteFilePath(), m_Foundation); + + if (!inputStream && !inQuiet) { + // Print extensive debugging information. + qCCritical(INTERNAL_ERROR, "Failed to find file: %s", localFile.toLatin1().constData()); + qCCritical(INTERNAL_ERROR, "Searched path: %s", + QDir::searchPaths(QT3DSTUDIO_TAG).join(',').toLatin1().constData()); + } + return inputStream; + } + + bool GetPathForFile(const QString &inFilename, QString &outFile, + bool inQuiet = false) override + { + NVScopedRefCounted theStream = + GetStreamForFile(inFilename, inQuiet); + if (theStream) { + SInputStream *theRealStream = static_cast(theStream.mPtr); + outFile = theRealStream->m_Path; + return true; + } + return false; + } +}; +} + +IInputStreamFactory &IInputStreamFactory::Create(NVFoundationBase &inFoundation) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SFactory)(inFoundation); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.h b/src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.h new file mode 100644 index 00000000..e82134b8 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderInputStreamFactory.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_INPUT_STREAM_FACTORY_H +#define QT3DS_RENDER_INPUT_STREAM_FACTORY_H +#include "Qt3DSRender.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/string.h" + +namespace qt3ds { +namespace render { + class IRefCountedInputStream : public qt3ds::foundation::ISeekableIOStream, public NVRefCounted + { + protected: + virtual ~IRefCountedInputStream() {} + }; + // This class is threadsafe. + class IInputStreamFactory : public NVRefCounted + { + protected: + virtual ~IInputStreamFactory() {} + public: + // These directories must have a '/' on them + virtual void AddSearchDirectory(const char8_t *inDirectory) = 0; + virtual IRefCountedInputStream *GetStreamForFile(const QString &inFilename, + bool inQuiet = false) = 0; + // Return a path for this file. Returns true if GetStreamForFile would return a valid + // stream. + // else returns false + virtual bool GetPathForFile(const QString &inFilename, QString &outFile, + bool inQuiet = false) = 0; + + // Create an input stream factory using this foundation and an platform-optional app + // directory + // on android the app directory has no effect; use use the assets bundled with the APK file. + static IInputStreamFactory &Create(NVFoundationBase &inFoundation); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderLightConstantProperties.h b/src/Runtime/Source/runtimerender/Qt3DSRenderLightConstantProperties.h new file mode 100644 index 00000000..4dcd62c5 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderLightConstantProperties.h @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_LIGHT_CONSTANT_PROPERTIES +#define QT3DS_RENDER_LIGHT_CONSTANT_PROPERTIES + +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + +static const QStringList lconstantnames = { + QStringLiteral("position"), + QStringLiteral("direction"), + QStringLiteral("up"), + QStringLiteral("right"), + QStringLiteral("diffuse"), + QStringLiteral("ambient"), + QStringLiteral("specular"), + QStringLiteral("spotExponent"), + QStringLiteral("spotCutoff"), + QStringLiteral("constantAttenuation"), + QStringLiteral("linearAttenuation"), + QStringLiteral("quadraticAttenuation"), + QStringLiteral("range"), + QStringLiteral("width"), + QStringLiteral("height"), + QStringLiteral("shadowControls"), + QStringLiteral("shadowView"), + QStringLiteral("shadowIdx"), + QStringLiteral("attenuation") +}; + +#define LCSEED QStringLiteral("%1%2") + +template +struct SLightConstantProperties +{ + struct LightConstants + { + NVRenderCachedShaderProperty m_position; + NVRenderCachedShaderProperty m_direction; + NVRenderCachedShaderProperty m_up; + NVRenderCachedShaderProperty m_right; + NVRenderCachedShaderProperty m_diffuse; + NVRenderCachedShaderProperty m_ambient; + NVRenderCachedShaderProperty m_specular; + NVRenderCachedShaderProperty m_spotExponent; + NVRenderCachedShaderProperty m_spotCutoff; + NVRenderCachedShaderProperty m_constantAttenuation; + NVRenderCachedShaderProperty m_linearAttenuation; + NVRenderCachedShaderProperty m_quadraticAttenuation; + NVRenderCachedShaderProperty m_range; + NVRenderCachedShaderProperty m_width; + NVRenderCachedShaderProperty m_height; + NVRenderCachedShaderProperty m_shadowControls; + NVRenderCachedShaderProperty m_shadowView; + NVRenderCachedShaderProperty m_shadowIdx; + NVRenderCachedShaderProperty m_attenuation; + + LightConstants(const QString &lightRef, render::NVRenderShaderProgram &shader) + : m_position(LCSEED.arg(lightRef, lconstantnames[0]), shader) + , m_direction(LCSEED.arg(lightRef).arg(lconstantnames[1]), shader) + , m_up(LCSEED.arg(lightRef, lconstantnames[2]), shader) + , m_right(LCSEED.arg(lightRef, lconstantnames[3]), shader) + , m_diffuse(LCSEED.arg(lightRef, lconstantnames[4]), shader) + , m_ambient(LCSEED.arg(lightRef, lconstantnames[5]), shader) + , m_specular(LCSEED.arg(lightRef, lconstantnames[6]), shader) + , m_spotExponent(LCSEED.arg(lightRef, lconstantnames[7]), shader) + , m_spotCutoff(LCSEED.arg(lightRef, lconstantnames[8]), shader) + , m_constantAttenuation(LCSEED.arg(lightRef, lconstantnames[9]), shader) + , m_linearAttenuation(LCSEED.arg(lightRef, lconstantnames[10]), shader) + , m_quadraticAttenuation(LCSEED.arg(lightRef, lconstantnames[11]), shader) + , m_range(LCSEED.arg(lightRef, lconstantnames[12]), shader) + , m_width(LCSEED.arg(lightRef, lconstantnames[13]), shader) + , m_height(LCSEED.arg(lightRef, lconstantnames[14]), shader) + , m_shadowControls(LCSEED.arg(lightRef, lconstantnames[15]), shader) + , m_shadowView(LCSEED.arg(lightRef, lconstantnames[16]), shader) + , m_shadowIdx(LCSEED.arg(lightRef, lconstantnames[17]), shader) + , m_attenuation(LCSEED.arg(lightRef, lconstantnames[18]), shader) + { + + } + + template + void updateLights(LightProps &props) + { + m_position.Set(props.m_position); + m_direction.Set(props.m_direction); + m_up.Set(props.m_up); + m_right.Set(props.m_right); + m_diffuse.Set(props.m_diffuse); + m_ambient.Set(props.m_ambient); + m_specular.Set(props.m_specular); + m_spotExponent.Set(props.m_spotExponent); + m_spotCutoff.Set(props.m_spotCutoff); + m_constantAttenuation.Set(props.m_constantAttenuation); + m_linearAttenuation.Set(props.m_linearAttenuation); + m_quadraticAttenuation.Set(props.m_quadraticAttenuation); + m_range.Set(props.m_range); + m_width.Set(props.m_width); + m_height.Set(props.m_height); + m_shadowControls.Set(props.m_shadowControls); + m_shadowView.Set(props.m_shadowView); + m_shadowIdx.Set(props.m_shadowIdx); + m_attenuation.Set(QT3DSVec3(props.m_constantAttenuation, + props.m_linearAttenuation, + props.m_quadraticAttenuation)); + } + }; + + SLightConstantProperties(GeneratedShader &shader, bool packed) + : m_lightCount("uNumLights", shader.m_Shader) + { + m_constants.resize(shader.m_Lights.size()); + for (unsigned int i = 0; i < shader.m_Lights.size(); ++i) { + QString lref; + if (packed) + lref = QStringLiteral("light_%1_"); + else + lref = QStringLiteral("lights[%1]."); + lref = lref.arg(i); + m_constants[i] = new LightConstants(lref, shader.m_Shader); + } + m_lightCount.Set(shader.m_Lights.size()); + m_lightCountInt = shader.m_Lights.size(); + } + + SLightConstantProperties(const QString &lseed, const QString &lcount, + GeneratedShader &shader, bool packed, int count) + : m_lightCount(lcount, shader.m_Shader) + { + m_constants.resize(count); + for (int i = 0; i < count; ++i) { + QString lref; + if (packed) + lref = lseed + QStringLiteral("_%1_"); + else + lref = lseed + QStringLiteral("[%1]."); + lref = lref.arg(i); + m_constants[i] = new LightConstants(lref, shader.m_Shader); + } + m_lightCount.Set(count); + m_lightCountInt = count; + } + + ~SLightConstantProperties() + { + qDeleteAll(m_constants); + } + + void updateLights(GeneratedShader &shader) + { + for (int i = 0; i < m_constants.size(); ++i) + m_constants[i]->updateLights(shader.m_Lights[i].m_LightData); + } + template + void updateLights(const QVector &props) + { + for (int i = 0; i < m_constants.size(); ++i) + m_constants[i]->updateLights(props[i]->m_LightData); + } + + QVector m_constants; + NVRenderCachedShaderProperty m_lightCount; + int m_lightCountInt; +}; + +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderMaterialHelpers.h b/src/Runtime/Source/runtimerender/Qt3DSRenderMaterialHelpers.h new file mode 100644 index 00000000..afb799e7 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderMaterialHelpers.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_MATERIAL_HELPERS_H +#define QT3DS_RENDER_MATERIAL_HELPERS_H +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderReferencedMaterial.h" + +namespace qt3ds { +namespace render { + + inline bool IsMaterial(SGraphObject &obj) + { + return obj.m_Type == GraphObjectTypes::CustomMaterial + || obj.m_Type == GraphObjectTypes::DefaultMaterial + || obj.m_Type == GraphObjectTypes::ReferencedMaterial; + } + + inline bool IsMaterial(SGraphObject *obj) + { + if (obj) + return IsMaterial(*obj); + return false; + } + + inline bool IsImage(SGraphObject &obj) { return obj.m_Type == GraphObjectTypes::Image; } + + inline bool IsImage(SGraphObject *obj) + { + if (obj) + return IsImage(*obj); + return false; + } + + inline SGraphObject *GetNextMaterialSibling(SGraphObject *obj) + { + if (obj == NULL) + return NULL; + if (IsMaterial(obj) == false) { + QT3DS_ASSERT(false); + return NULL; + } + if (obj->m_Type == GraphObjectTypes::CustomMaterial) + return static_cast(obj)->m_NextSibling; + else if (obj->m_Type == GraphObjectTypes::DefaultMaterial) + return static_cast(obj)->m_NextSibling; + else + return static_cast(obj)->m_NextSibling; + } + + inline void SetNextMaterialSibling(SGraphObject &obj, SGraphObject *sibling) + { + if (IsMaterial(obj) == false) { + QT3DS_ASSERT(false); + return; + } + if (obj.m_Type == GraphObjectTypes::CustomMaterial) + static_cast(&obj)->m_NextSibling = sibling; + else if (obj.m_Type == GraphObjectTypes::DefaultMaterial) + static_cast(&obj)->m_NextSibling = sibling; + else + static_cast(&obj)->m_NextSibling = sibling; + } +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderMaterialShaderGenerator.h b/src/Runtime/Source/runtimerender/Qt3DSRenderMaterialShaderGenerator.h new file mode 100644 index 00000000..e8b9880d --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderMaterialShaderGenerator.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_MATERIAL_SHADER_GENERATOR_H +#define QT3DS_RENDER_MATERIAL_SHADER_GENERATOR_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSRenderShaderKeys.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" + +namespace qt3ds { +namespace render { + +// these are our current shader limits +#define QT3DS_MAX_NUM_LIGHTS 16 +#define QT3DS_MAX_NUM_SHADOWS 8 + + // note this struct must exactly match the memory layout of the + // struct sampleLight.glsllib and sampleArea.glsllib. If you make changes here you need + // to adjust the code in sampleLight.glsllib and sampleArea.glsllib as well + struct SLightSourceShader + { + QT3DSVec4 m_position; + QT3DSVec4 m_direction; // Specifies the light direction in world coordinates. + QT3DSVec4 m_up; + QT3DSVec4 m_right; + QT3DSVec4 m_diffuse; + QT3DSVec4 m_ambient; + QT3DSVec4 m_specular; + QT3DSF32 m_spotExponent; // Specifies the intensity distribution of the light. + QT3DSF32 m_spotCutoff; // Specifies the maximum spread angle of the light. + QT3DSF32 m_constantAttenuation; // Specifies the constant light attenuation factor. + QT3DSF32 m_linearAttenuation; // Specifies the linear light attenuation factor. + QT3DSF32 m_quadraticAttenuation; // Specifies the quadratic light attenuation factor. + QT3DSF32 m_range; // Specifies the maximum distance of the light influence + QT3DSF32 m_width; // Specifies the width of the area light surface. + QT3DSF32 m_height; // Specifies the height of the area light surface; + QT3DSVec4 m_shadowControls; + QT3DSMat44 m_shadowView; + QT3DSI32 m_shadowIdx; + QT3DSF32 m_padding1[3]; + }; + + struct SLayerGlobalRenderProperties + { + const SLayer &m_Layer; + SCamera &m_Camera; + QT3DSVec3 m_CameraDirection; + NVDataRef m_Lights; + NVDataRef m_LightDirections; + Qt3DSShadowMap *m_ShadowMapManager; + NVRenderTexture2D *m_DepthTexture; + NVRenderTexture2D *m_SSaoTexture; + SImage *m_LightProbe; + SImage *m_LightProbe2; + QT3DSF32 m_ProbeHorizon; + QT3DSF32 m_ProbeBright; + QT3DSF32 m_Probe2Window; + QT3DSF32 m_Probe2Pos; + QT3DSF32 m_Probe2Fade; + QT3DSF32 m_ProbeFOV; + + SLayerGlobalRenderProperties(const SLayer &inLayer, SCamera &inCamera, + QT3DSVec3 inCameraDirection, NVDataRef inLights, + NVDataRef inLightDirections, + Qt3DSShadowMap *inShadowMapManager, + NVRenderTexture2D *inDepthTexture, + NVRenderTexture2D *inSSaoTexture, SImage *inLightProbe, + SImage *inLightProbe2, QT3DSF32 inProbeHorizon, + QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, + QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) + : m_Layer(inLayer) + , m_Camera(inCamera) + , m_CameraDirection(inCameraDirection) + , m_Lights(inLights) + , m_LightDirections(inLightDirections) + , m_ShadowMapManager(inShadowMapManager) + , m_DepthTexture(inDepthTexture) + , m_SSaoTexture(inSSaoTexture) + , m_LightProbe(inLightProbe) + , m_LightProbe2(inLightProbe2) + , m_ProbeHorizon(inProbeHorizon) + , m_ProbeBright(inProbeBright) + , m_Probe2Window(inProbe2Window) + , m_Probe2Pos(inProbe2Pos) + , m_Probe2Fade(inProbe2Fade) + , m_ProbeFOV(inProbeFOV) + { + } + }; + + class IMaterialShaderGenerator : public NVRefCounted + { + public: + struct SImageVariableNames + { + const char8_t *m_ImageSampler; + const char8_t *m_ImageFragCoords; + }; + + virtual SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) = 0; + virtual void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, + QT3DSU32 uvSet, SRenderableImage &image) = 0; + + // inPipelineName needs to be unique else the shader cache will just return shaders from + // different pipelines. + virtual NVRenderShaderProgram *GenerateShader( + const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, + IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, + NVDataRef inLights, SRenderableImage *inFirstImage, bool inHasTransparency, + const char8_t *inVertexPipelineName, const char8_t *inCustomMaterialName = "") = 0; + + // Also sets the blend function on the render context. + virtual void + SetMaterialProperties(NVRenderShaderProgram &inProgram, const SGraphObject &inMaterial, + const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, + SRenderableImage *inFirstImage, QT3DSF32 inOpacity, + SLayerGlobalRenderProperties inRenderProperties) = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderMesh.h b/src/Runtime/Source/runtimerender/Qt3DSRenderMesh.h new file mode 100644 index 00000000..d6959ec8 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderMesh.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_MESH_H +#define QT3DS_RENDER_MESH_H +#include "Qt3DSRender.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderInputAssembler.h" +#include "foundation/Qt3DSBounds3.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSNoCopy.h" + +namespace qt3ds { +namespace render { + + struct SRenderSubsetBase + { + QT3DSU32 m_Count; + QT3DSU32 m_Offset; + NVBounds3 m_Bounds; // Vertex buffer bounds + SRenderSubsetBase() {} + SRenderSubsetBase(const SRenderSubsetBase &inOther) + : m_Count(inOther.m_Count) + , m_Offset(inOther.m_Offset) + , m_Bounds(inOther.m_Bounds) + { + } + + SRenderSubsetBase &operator=(const SRenderSubsetBase &inOther) + { + m_Count = inOther.m_Count; + m_Offset = inOther.m_Offset; + m_Bounds = inOther.m_Bounds; + return *this; + } + }; + + struct SRenderJoint + { + QT3DSI32 m_JointID; + QT3DSI32 m_ParentID; + QT3DSF32 m_invBindPose[16]; + QT3DSF32 m_localToGlobalBoneSpace[16]; + }; + + struct SRenderSubset : public SRenderSubsetBase + { + NVRenderInputAssembler *m_InputAssembler; + NVRenderInputAssembler *m_InputAssemblerDepth; + NVRenderInputAssembler + *m_InputAssemblerPoints; ///< similar to depth but ignores index buffer. + NVRenderVertexBuffer *m_VertexBuffer; + NVRenderVertexBuffer + *m_PosVertexBuffer; ///< separate position buffer for fast depth path rendering + NVRenderIndexBuffer *m_IndexBuffer; + NVRenderDrawMode::Enum m_PrimitiveType; ///< primitive type used for drawing + QT3DSF32 m_EdgeTessFactor; ///< edge tessellation amount used for tessellation shaders + QT3DSF32 m_InnerTessFactor; ///< inner tessellation amount used for tessellation shaders + bool m_WireframeMode; ///< true if we should draw the object as wireframe ( currently ony if + ///tessellation is enabled ) + NVConstDataRef m_Joints; + CRegisteredString m_Name; + nvvector m_SubSubsets; + + SRenderSubset(NVAllocatorCallback &alloc) + : m_InputAssembler(NULL) + , m_InputAssemblerDepth(NULL) + , m_InputAssemblerPoints(NULL) + , m_VertexBuffer(NULL) + , m_PosVertexBuffer(NULL) + , m_IndexBuffer(NULL) + , m_PrimitiveType(NVRenderDrawMode::Triangles) + , m_EdgeTessFactor(1.0) + , m_InnerTessFactor(1.0) + , m_WireframeMode(false) + , m_SubSubsets(alloc, "SRenderSubset::m_SubSubsets") + { + } + SRenderSubset(const SRenderSubset &inOther) + : SRenderSubsetBase(inOther) + , m_InputAssembler(inOther.m_InputAssembler) + , m_InputAssemblerDepth(inOther.m_InputAssemblerDepth) + , m_InputAssemblerPoints(inOther.m_InputAssemblerPoints) + , m_VertexBuffer(inOther.m_VertexBuffer) + , m_PosVertexBuffer(inOther.m_PosVertexBuffer) + , m_IndexBuffer(inOther.m_IndexBuffer) + , m_PrimitiveType(inOther.m_PrimitiveType) + , m_EdgeTessFactor(inOther.m_EdgeTessFactor) + , m_InnerTessFactor(inOther.m_InnerTessFactor) + , m_WireframeMode(inOther.m_WireframeMode) + , m_Joints(inOther.m_Joints) + , m_Name(inOther.m_Name) + , m_SubSubsets(inOther.m_SubSubsets) + { + } + // Note that subSubsets is *not* copied. + SRenderSubset(NVAllocatorCallback &alloc, const SRenderSubset &inOther, + const SRenderSubsetBase &inBase) + : SRenderSubsetBase(inBase) + , m_InputAssembler(inOther.m_InputAssembler) + , m_InputAssemblerDepth(inOther.m_InputAssemblerDepth) + , m_InputAssemblerPoints(inOther.m_InputAssemblerPoints) + , m_VertexBuffer(inOther.m_VertexBuffer) + , m_PosVertexBuffer(inOther.m_PosVertexBuffer) + , m_IndexBuffer(inOther.m_IndexBuffer) + , m_PrimitiveType(inOther.m_PrimitiveType) + , m_EdgeTessFactor(inOther.m_EdgeTessFactor) + , m_InnerTessFactor(inOther.m_InnerTessFactor) + , m_WireframeMode(inOther.m_WireframeMode) + , m_Name(inOther.m_Name) + , m_SubSubsets(alloc, "SRenderSubset::m_SubSubsets") + { + } + + SRenderSubset &operator=(const SRenderSubset &inOther) + { + if (this != &inOther) { + SRenderSubsetBase::operator=(inOther); + m_InputAssembler = inOther.m_InputAssembler; + m_InputAssemblerDepth = inOther.m_InputAssemblerDepth; + m_VertexBuffer = inOther.m_VertexBuffer; + m_PosVertexBuffer = inOther.m_PosVertexBuffer; + m_IndexBuffer = inOther.m_IndexBuffer; + m_PrimitiveType = inOther.m_PrimitiveType; + m_EdgeTessFactor = inOther.m_EdgeTessFactor; + m_InnerTessFactor = inOther.m_InnerTessFactor; + m_WireframeMode = inOther.m_WireframeMode; + m_Joints = inOther.m_Joints; + m_Name = inOther.m_Name; + m_SubSubsets = inOther.m_SubSubsets; + } + return *this; + } + }; + + struct SRenderMesh : public NoCopy + { + nvvector m_Subsets; + nvvector m_Joints; + NVRenderDrawMode::Enum m_DrawMode; + NVRenderWinding::Enum m_Winding; // counterclockwise + QT3DSU32 m_MeshId; // Id from the file of this mesh. + + SRenderMesh(NVRenderDrawMode::Enum inDrawMode, NVRenderWinding::Enum inWinding, + QT3DSU32 inMeshId, NVAllocatorCallback &alloc) + : m_Subsets(alloc, "SRenderMesh::m_Subsets") + , m_Joints(alloc, "SRenderMesh::Joints") + , m_DrawMode(inDrawMode) + , m_Winding(inWinding) + , m_MeshId(inMeshId) + { + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.cpp new file mode 100644 index 00000000..9953dcf2 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.cpp @@ -0,0 +1,1964 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderPathManager.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSContainers.h" +#include "EASTL/string.h" +#include "Qt3DSRenderContextCore.h" +#include "foundation/Utils.h" +#include "foundation/StringConversionImpl.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderInputAssembler.h" +#include "Qt3DSRenderPath.h" +#include "EASTL/sort.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderShaderCodeGenerator.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderPathRenderContext.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include "Qt3DSRenderCustomMaterialShaderGenerator.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "rendererimpl/Qt3DSVertexPipelineImpl.h" +#include "foundation/Qt3DSMathUtils.h" +#include "render/Qt3DSRenderPathRender.h" +#include "render/Qt3DSRenderPathSpecification.h" +#include "Qt3DSRenderPathSubPath.h" +#include "Qt3DSImportPath.h" +#include "Qt3DSRenderPathMath.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "foundation/Qt3DSMutex.h" + +using namespace qt3ds::render; +using qt3ds::render::NVRenderCachedShaderProperty; +using qt3ds::render::NVRenderCachedShaderBuffer; +using qt3ds::render::NVRenderStencilFunctionArgument; +using qt3ds::render::NVRenderBoolOp; +using qt3ds::render::NVRenderStencilOperationArgument; +using qt3ds::render::NVRenderStencilOp; + +typedef qt3dsimp::SPathBuffer TImportPathBuffer; +using namespace qt3ds::render::path; + +typedef eastl::pair TStrStrPair; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const TStrStrPair &item) const + { + return eastl::hash()(item.first) + ^ eastl::hash()(item.second); + } +}; +} + +struct SPathShaderMapKey +{ + CRegisteredString m_Name; + SShaderDefaultMaterialKey m_MaterialKey; + size_t m_HashCode; + SPathShaderMapKey(CRegisteredString inName, SShaderDefaultMaterialKey inKey) + : m_Name(inName) + , m_MaterialKey(inKey) + { + m_HashCode = eastl::hash()(m_Name) ^ m_MaterialKey.hash(); + } + bool operator==(const SPathShaderMapKey &inKey) const + { + return m_Name == inKey.m_Name && m_MaterialKey == inKey.m_MaterialKey; + } +}; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SPathShaderMapKey &inKey) const { return inKey.m_HashCode; } +}; +} + +namespace { + +struct SPathSubPathBuffer +{ + NVAllocatorCallback &m_Allocator; + nvvector m_SourceData; + SPathDirtyFlags m_Flags; + SPathSubPath &m_SubPath; + bool m_Closed; + + QT3DSI32 m_RefCount; + + SPathSubPathBuffer(NVAllocatorCallback &alloc, SPathSubPath &inSubPath) + : m_Allocator(alloc) + , m_SourceData(alloc, "m_SourceData") + , m_SubPath(inSubPath) + , m_Closed(false) + , m_RefCount(0) + { + } + + void addRef() { atomicIncrement(&m_RefCount); } + void release() + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Allocator); + NVDelete(alloc, this); + } + } +}; + +struct SImportPathWrapper +{ + NVAllocatorCallback &m_Alloc; + qt3dsimp::SPathBuffer *m_Path; + QT3DSI32 m_RefCount; + + SImportPathWrapper(NVAllocatorCallback &inAlloc, qt3dsimp::SPathBuffer &inPath) + : m_Alloc(inAlloc) + , m_Path(&inPath) + , m_RefCount(0) + { + } + + ~SImportPathWrapper() { m_Path->Free(m_Alloc); } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Alloc); + NVDelete(alloc, this); + } + } +}; + +typedef NVScopedRefCounted TPathBufferPtr; + +struct SPathBuffer +{ + NVAllocatorCallback &m_Allocator; + nvvector> m_SubPaths; + TPathBufferPtr m_PathBuffer; + + NVScopedRefCounted m_PatchData; + NVScopedRefCounted m_InputAssembler; + NVScopedRefCounted m_PathRender; + + QT3DSVec2 m_BeginTaperData; + QT3DSVec2 m_EndTaperData; + QT3DSU32 m_NumVertexes; + PathTypes::Enum m_PathType; + QT3DSF32 m_Width; + QT3DSF32 m_CPUError; + NVBounds3 m_Bounds; + Option m_BeginTaper; + Option m_EndTaper; + CRegisteredString m_SourcePath; + + // Cached data for geometry paths + + SPathDirtyFlags m_Flags; + + QT3DSI32 m_RefCount; + + SPathBuffer(NVAllocatorCallback &alloc) + : m_Allocator(alloc) + , m_SubPaths(alloc, "m_SubPaths") + , m_NumVertexes(0) + , m_PathType(PathTypes::Geometry) + , m_Width(0.0f) + , m_CPUError(0.0f) + , m_Bounds(NVBounds3::empty()) + , m_RefCount(0) + { + } + + void addRef() { atomicIncrement(&m_RefCount); } + void release() + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Allocator); + NVDelete(alloc, this); + } + } + + void ClearGeometryPathData() + { + m_PatchData = NULL; + m_InputAssembler = NULL; + } + + void ClearPaintedPathData() { m_PathRender = NULL; } + + qt3dsimp::SPathBuffer GetPathData(qt3dsimp::IPathBufferBuilder &inSpec) + { + if (m_SubPaths.size()) { + inSpec.Clear(); + for (QT3DSU32 idx = 0, end = m_SubPaths.size(); idx < end; ++idx) { + const SPathSubPathBuffer &theSubPathBuffer(*m_SubPaths[idx]); + for (QT3DSU32 equationIdx = 0, equationEnd = theSubPathBuffer.m_SourceData.size(); + equationIdx < equationEnd; ++equationIdx) { + const SPathAnchorPoint &thePoint = theSubPathBuffer.m_SourceData[equationIdx]; + if (equationIdx == 0) { + inSpec.MoveTo(thePoint.m_Position); + } else { + const SPathAnchorPoint &thePrevPoint = + theSubPathBuffer.m_SourceData[equationIdx - 1]; + QT3DSVec2 c1 = IPathManager::GetControlPointFromAngleDistance( + thePrevPoint.m_Position, thePrevPoint.m_OutgoingAngle, + thePrevPoint.m_OutgoingDistance); + QT3DSVec2 c2 = IPathManager::GetControlPointFromAngleDistance( + thePoint.m_Position, thePoint.m_IncomingAngle, + thePoint.m_IncomingDistance); + QT3DSVec2 p2 = thePoint.m_Position; + inSpec.CubicCurveTo(c1, c2, p2); + } + } + if (theSubPathBuffer.m_Closed) + inSpec.Close(); + } + return inSpec.GetPathBuffer(); + } else if (m_PathBuffer.mPtr) + return *m_PathBuffer.mPtr->m_Path; + return qt3dsimp::SPathBuffer(); + } + + void SetPathType(PathTypes::Enum inPathType) + { + if (inPathType != m_PathType) { + switch (m_PathType) { + case PathTypes::Geometry: + ClearGeometryPathData(); + break; + case PathTypes::Painted: + ClearPaintedPathData(); + break; + default: + QT3DS_ALWAYS_ASSERT_MESSAGE("Unexpected path type"); + // No further processing for unexpected path type + return; + } + m_Flags.clearOrSet(true, PathDirtyFlagValues::PathType); + } + m_PathType = inPathType; + } + + static Option ToTaperInfo(PathCapping::Enum capping, QT3DSF32 capOffset, + QT3DSF32 capOpacity, QT3DSF32 capWidth) + { + if (capping == PathCapping::Noner) + return Empty(); + + return STaperInformation(capOffset, capOpacity, capWidth); + } + + void SetBeginTaperInfo(PathCapping::Enum capping, QT3DSF32 capOffset, QT3DSF32 capOpacity, + QT3DSF32 capWidth) + { + Option newBeginInfo = + ToTaperInfo(capping, capOffset, capOpacity, capWidth); + if (!OptionEquals(newBeginInfo, m_BeginTaper)) { + m_BeginTaper = newBeginInfo; + m_Flags.clearOrSet(true, PathDirtyFlagValues::BeginTaper); + } + } + + void SetEndTaperInfo(PathCapping::Enum capping, QT3DSF32 capOffset, QT3DSF32 capOpacity, + QT3DSF32 capWidth) + { + Option newEndInfo = + ToTaperInfo(capping, capOffset, capOpacity, capWidth); + if (!OptionEquals(newEndInfo, m_EndTaper)) { + m_EndTaper = newEndInfo; + m_Flags.clearOrSet(true, PathDirtyFlagValues::EndTaper); + } + } + + void SetWidth(QT3DSF32 inWidth) + { + if (inWidth != m_Width) { + m_Width = inWidth; + m_Flags.clearOrSet(true, PathDirtyFlagValues::Width); + } + } + + void SetCPUError(QT3DSF32 inError) + { + if (inError != m_CPUError) { + m_CPUError = inError; + m_Flags.clearOrSet(true, PathDirtyFlagValues::CPUError); + } + } +}; + +struct SPathGeneratedShader +{ + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_Width; + NVRenderCachedShaderProperty m_InnerTessAmount; + NVRenderCachedShaderProperty m_EdgeTessAmount; + NVRenderCachedShaderProperty m_BeginTaperData; + NVRenderCachedShaderProperty m_EndTaperData; + NVRenderCachedShaderProperty m_WireframeViewMatrix; + + QT3DSI32 m_RefCount; + + SPathGeneratedShader(NVRenderShaderProgram &sh, NVAllocatorCallback &alloc) + : m_Allocator(alloc) + , m_Shader(sh) + , m_Width("pathWidth", sh) + , m_InnerTessAmount("tessInnerLevel", sh) + , m_EdgeTessAmount("tessEdgeLevel", sh) + , m_BeginTaperData("beginTaperInfo", sh) + , m_EndTaperData("endTaperInfo", sh) + , m_WireframeViewMatrix("viewport_matrix", sh) + , m_RefCount(0) + { + m_Shader.addRef(); + } + ~SPathGeneratedShader() { m_Shader.release(); } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) { + NVAllocatorCallback &allocator(m_Allocator); + NVDelete(allocator, this); + } + } +}; + +struct SPathVertexPipeline : public SVertexPipelineImpl +{ + + SPathVertexPipeline(IShaderProgramGenerator &inProgGenerator, + IMaterialShaderGenerator &inMaterialGenerator, NVAllocatorCallback &inAlloc, + IStringTable &inStringTable, bool inWireframe) + : SVertexPipelineImpl(inAlloc, inMaterialGenerator, inProgGenerator, inStringTable, + inWireframe) + { + } + + // Trues true if the code was *not* set. + bool SetCode(GenerationFlagValues::Enum inCode) + { + if (((QT3DSU32)m_GenerationFlags & inCode) != 0) + return true; + m_GenerationFlags |= inCode; + return false; + } + + void AssignTessEvalVarying(const char8_t *inVarName, const char8_t *inVarValueExpr) + { + const char8_t *ext = ""; + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) + ext = "TE"; + TessEval() << "\t" << inVarName << ext << " = " << inVarValueExpr << ";" << Endl; + } + + void AssignOutput(const char8_t *inVarName, const char8_t *inVarValueExpr) override + { + AssignTessEvalVarying(inVarName, inVarValueExpr); + } + + void InitializeTessShaders() + { + IShaderStageGenerator &theTessControl(TessControl()); + IShaderStageGenerator &theTessEval(TessEval()); + + // first setup tessellation control shader + theTessControl.AddUniform("tessEdgeLevel", "float"); + theTessControl.AddUniform("tessInnerLevel", "float"); + + theTessControl.AddInclude("tessellationPath.glsllib"); + + theTessControl.Append("void main() {\n"); + theTessControl.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + theTessControl.Append("\ttessShader( tessEdgeLevel, tessInnerLevel );\n"); + + bool hasGeometryShader = + ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry) != NULL; + + // second setup tessellation control shader + eastl::string outExt(""); + if (hasGeometryShader) + outExt = "TE"; + + theTessEval.AddInclude("tessellationPath.glsllib"); + theTessEval.AddUniform("normal_matrix", "mat3"); + theTessEval.AddUniform("model_view_projection", "mat4"); + theTessEval.AddUniform("pathWidth", "float"); + theTessEval.AddUniform("material_diffuse", "vec4"); + AddInterpolationParameter("varTexCoord0", "vec2"); + AddInterpolationParameter("varTessOpacity", "float"); + + theTessEval.Append("void main() {\n"); + theTessEval.Append("\tSTessShaderResult shaderResult = tessShader( pathWidth );\n"); + theTessEval.Append("\tvec3 pos = shaderResult.m_Position;\n"); + AssignTessEvalVarying("varTessOpacity", "shaderResult.m_Opacity"); + AssignTessEvalVarying("varTexCoord0", "shaderResult.m_TexCoord.xy"); + if (hasGeometryShader) + theTessEval << "\tvec2 varTexCoord0 = shaderResult.m_TexCoord.xy;\n"; + + theTessEval << "\tvec3 object_normal = vec3(0.0, 0.0, 1.0);\n"; + theTessEval << "\tvec3 world_normal = normal_matrix * object_normal;\n"; + theTessEval << "\tvec3 tangent = vec3( shaderResult.m_Tangent, 0.0 );\n"; + theTessEval << "\tvec3 binormal = vec3( shaderResult.m_Binormal, 0.0 );\n"; + + // These are necessary for texture generation. + theTessEval << "\tvec3 uTransform;" << Endl; + theTessEval << "\tvec3 vTransform;" << Endl; + + if (m_DisplacementImage) { + MaterialGenerator().GenerateImageUVCoordinates(*this, m_DisplacementIdx, 0, + *m_DisplacementImage); + theTessEval.AddUniform("displaceAmount", "float"); + theTessEval.AddUniform("model_matrix", "mat4"); + theTessEval.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + IDefaultMaterialShaderGenerator::SImageVariableNames theVarNames = + MaterialGenerator().GetImageVariableNames(m_DisplacementIdx); + + theTessEval.AddUniform(theVarNames.m_ImageSampler, "sampler2D"); + IDefaultMaterialShaderGenerator::SImageVariableNames theNames = + MaterialGenerator().GetImageVariableNames(m_DisplacementIdx); + theTessEval << "\tpos = defaultMaterialFileDisplacementTexture( " + << theNames.m_ImageSampler << ", displaceAmount, " + << theNames.m_ImageFragCoords << outExt.c_str() << ", vec3( 0.0, 0.0, 1.0 )" + << ", pos.xyz );" << Endl; + } + } + void FinalizeTessControlShader() {} + + void FinalizeTessEvaluationShader() + { + eastl::string outExt(""); + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) + outExt = "TE"; + + IShaderStageGenerator &tessEvalShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + tessEvalShader.Append("\tgl_Position = model_view_projection * vec4( pos, 1.0 );\n"); + } + + void BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) override + { + SetupDisplacement(displacementImageIdx, displacementImage); + + TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); + theStages |= ShaderGeneratorStages::TessControl; + theStages |= ShaderGeneratorStages::TessEval; + if (m_Wireframe) { + theStages |= ShaderGeneratorStages::Geometry; + } + ProgramGenerator().BeginProgram(theStages); + InitializeTessShaders(); + if (m_Wireframe) { + InitializeWireframeGeometryShader(); + } + // Open up each stage. + IShaderStageGenerator &vertexShader(Vertex()); + + vertexShader.AddIncoming("attr_pos", "vec4"); + + // useless vert shader because real work is done in TES. + vertexShader << "void main()\n" + "{\n"; + vertexShader << "\tgl_Position = attr_pos;\n"; // if tessellation is enabled pass down + // object coordinates; + vertexShader << "}\n"; + } + + void BeginFragmentGeneration() override + { + Fragment().AddUniform("material_diffuse", "vec4"); + Fragment() << "void main()" << Endl << "{" << Endl; + // We do not pass object opacity through the pipeline. + Fragment() << "\tfloat object_opacity = varTessOpacity * material_diffuse.a;" << Endl; + } + void DoGenerateUVCoords(QT3DSU32) override + { + // these are always generated regardless + } + + // fragment shader expects varying vertex normal + // lighting in vertex pipeline expects world_normal + void DoGenerateWorldNormal() override { AssignTessEvalVarying("varNormal", "world_normal"); } + void DoGenerateObjectNormal() override + { + AssignTessEvalVarying("varObjectNormal", "object_normal"); + } + void DoGenerateWorldPosition() override + { + TessEval().AddUniform("model_matrix", "mat4"); + TessEval() + << "\tvec3 local_model_world_position = vec3((model_matrix * vec4(pos, 1.0)).xyz);\n"; + } + void DoGenerateVarTangentAndBinormal() override + { + TessEval().AddUniform("normal_matrix", "mat3"); + AssignOutput("varTangent", "normal_matrix * tangent"); + AssignOutput("varBinormal", "normal_matrix * binormal"); + } + + void DoGenerateVertexColor() override + { + Vertex().AddIncoming("attr_color", "vec3"); + Vertex() << "\tvarColor = attr_color;" << Endl; + } + + void EndVertexGeneration() override + { + + if (HasTessellation()) { + // finalize tess control shader + FinalizeTessControlShader(); + // finalize tess evaluation shader + FinalizeTessEvaluationShader(); + + TessControl().Append("}"); + TessEval().Append("}"); + } + if (m_Wireframe) { + // finalize geometry shader + FinalizeWireframeGeometryShader(); + Geometry().Append("}"); + } + } + + void EndFragmentGeneration() override { Fragment().Append("}"); } + + void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override + { + m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); + Fragment().AddIncoming(inName, inType); + if (HasTessellation()) { + eastl::string nameBuilder; + nameBuilder.assign(inName); + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) + nameBuilder.append("TE"); + + TessEval().AddOutgoing(nameBuilder.c_str(), inType); + } + } + + IShaderStageGenerator &ActiveStage() override { return TessEval(); } +}; + +struct SPathXYGeneratedShader +{ + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_RectDimensions; + NVRenderCachedShaderProperty m_ModelMatrix; + NVRenderCachedShaderProperty m_CameraPosition; + NVRenderCachedShaderProperty m_CameraProperties; + QT3DSI32 m_RefCount; + + SPathXYGeneratedShader(NVRenderShaderProgram &sh, NVAllocatorCallback &alloc) + : m_Allocator(alloc) + , m_Shader(sh) + , m_RectDimensions("uni_rect_dimensions", sh) + , m_ModelMatrix("model_matrix", sh) + , m_CameraPosition("camera_position", sh) + , m_CameraProperties("camera_properties", sh) + , m_RefCount(0) + { + m_Shader.addRef(); + } + virtual ~SPathXYGeneratedShader() { m_Shader.release(); } + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) { + NVAllocatorCallback &allocator(m_Allocator); + NVDelete(allocator, this); + } + } +}; + +// Helper implements the vertex pipeline for mesh subsets when bound to the default material. +// Should be completely possible to use for custom materials with a bit of refactoring. +struct SXYRectVertexPipeline : public SVertexPipelineImpl +{ + + SXYRectVertexPipeline(IShaderProgramGenerator &inProgGenerator, + IMaterialShaderGenerator &inMaterialGenerator, + NVAllocatorCallback &inAlloc, IStringTable &inStringTable) + : SVertexPipelineImpl(inAlloc, inMaterialGenerator, inProgGenerator, inStringTable, false) + { + } + + void BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) override + { + m_DisplacementIdx = displacementImageIdx; + m_DisplacementImage = displacementImage; + + TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); + ProgramGenerator().BeginProgram(theStages); + // Open up each stage. + IShaderStageGenerator &vertexShader(Vertex()); + vertexShader.AddIncoming("attr_pos", "vec2"); + vertexShader.AddUniform("uni_rect_dimensions", "vec4"); + + vertexShader << "void main()" << Endl << "{" << Endl; + vertexShader << "\tvec3 uTransform;" << Endl; + vertexShader << "\tvec3 vTransform;" << Endl; + + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader + << "\tfloat posX = mix( uni_rect_dimensions.x, uni_rect_dimensions.z, attr_pos.x );" + << Endl; + vertexShader + << "\tfloat posY = mix( uni_rect_dimensions.y, uni_rect_dimensions.w, attr_pos.y );" + << Endl; + vertexShader << "\tvec3 pos = vec3(posX, posY, 0.0 );" << Endl; + vertexShader.Append("\tgl_Position = model_view_projection * vec4(pos, 1.0);"); + } + + void OutputParaboloidDepthShaders() + { + TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); + ProgramGenerator().BeginProgram(theStages); + IShaderStageGenerator &vertexShader(Vertex()); + vertexShader.AddIncoming("attr_pos", "vec2"); + vertexShader.AddUniform("uni_rect_dimensions", "vec4"); + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader << "void main()" << Endl << "{" << Endl; + vertexShader + << "\tfloat posX = mix( uni_rect_dimensions.x, uni_rect_dimensions.z, attr_pos.x );" + << Endl; + vertexShader + << "\tfloat posY = mix( uni_rect_dimensions.y, uni_rect_dimensions.w, attr_pos.y );" + << Endl; + vertexShader << "\tvec3 pos = vec3(posX, posY, 0.0 );" << Endl; + IShaderProgramGenerator::OutputParaboloidDepthTessEval(vertexShader); + vertexShader << "}" << Endl; + + IShaderProgramGenerator::OutputParaboloidDepthFragment(Fragment()); + } + + void OutputCubeFaceDepthShaders() + { + TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); + ProgramGenerator().BeginProgram(theStages); + IShaderStageGenerator &vertexShader(Vertex()); + IShaderStageGenerator &fragmentShader(Fragment()); + vertexShader.AddIncoming("attr_pos", "vec2"); + vertexShader.AddUniform("uni_rect_dimensions", "vec4"); + vertexShader.AddUniform("model_matrix", "mat4"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.AddOutgoing("world_pos", "vec4"); + vertexShader.Append("void main() {"); + vertexShader.Append( + " float posX = mix( uni_rect_dimensions.x, uni_rect_dimensions.z, attr_pos.x );"); + vertexShader.Append( + " float posY = mix( uni_rect_dimensions.y, uni_rect_dimensions.w, attr_pos.y );"); + vertexShader.Append(" world_pos = model_matrix * vec4( posX, posY, 0.0, 1.0 );"); + vertexShader.Append(" world_pos /= world_pos.w;"); + vertexShader.Append( + " gl_Position = model_view_projection * vec4( posX, posY, 0.0, 1.0 );"); + vertexShader.Append("}"); + + fragmentShader.AddUniform("camera_position", "vec3"); + fragmentShader.AddUniform("camera_properties", "vec2"); + + BeginFragmentGeneration(); + fragmentShader.Append( + "\tfloat dist = 0.5 * length( world_pos.xyz - camera_position );"); // Why? + fragmentShader.Append( + "\tdist = (dist - camera_properties.x) / (camera_properties.y - camera_properties.x);"); + fragmentShader.Append("\tfragOutput = vec4(dist);"); + fragmentShader.Append("}"); + } + + void BeginFragmentGeneration() override + { + Fragment().AddUniform("material_diffuse", "vec4"); + Fragment() << "void main()" << Endl << "{" << Endl; + // We do not pass object opacity through the pipeline. + Fragment() << "\tfloat object_opacity = material_diffuse.a;" << Endl; + } + + void AssignOutput(const char8_t *inVarName, const char8_t *inVarValue) override + { + Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n"; + } + void DoGenerateUVCoords(QT3DSU32) override { Vertex() << "\tvarTexCoord0 = attr_pos;" << Endl; } + + // fragment shader expects varying vertex normal + // lighting in vertex pipeline expects world_normal + void DoGenerateWorldNormal() override + { + IShaderStageGenerator &vertexGenerator(Vertex()); + vertexGenerator.AddUniform("normal_matrix", "mat3"); + vertexGenerator.Append( + "\tvec3 world_normal = normalize(normal_matrix * vec3( 0.0, 0.0, 1.0) ).xyz;"); + vertexGenerator.Append("\tvarNormal = world_normal;"); + } + + void DoGenerateObjectNormal() override + { + AddInterpolationParameter("varObjectNormal", "vec3"); + Vertex().Append("\tvarObjectNormal = vec3(0.0, 0.0, 1.0 );"); + } + + void DoGenerateWorldPosition() override + { + Vertex().Append("\tvec3 local_model_world_position = (model_matrix * vec4(pos, 1.0)).xyz;"); + AssignOutput("varWorldPos", "local_model_world_position"); + } + + void DoGenerateVarTangentAndBinormal() override + { + Vertex().AddIncoming("attr_textan", "vec3"); + Vertex().AddIncoming("attr_binormal", "vec3"); + Vertex() << "\tvarTangent = normal_matrix * vec3(1.0, 0.0, 0.0);" << Endl + << "\tvarBinormal = normal_matrix * vec3(0.0, 1.0, 0.0);" << Endl; + } + + void DoGenerateVertexColor() override + { + Vertex().AddIncoming("attr_color", "vec3"); + Vertex() << "\tvarColor = attr_color;" << Endl; + } + + void EndVertexGeneration() override { Vertex().Append("}"); } + + void EndFragmentGeneration() override { Fragment().Append("}"); } + + void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override + { + m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); + Vertex().AddOutgoing(inName, inType); + Fragment().AddIncoming(inName, inType); + } + + IShaderStageGenerator &ActiveStage() override { return Vertex(); } +}; + +struct SPathManager : public IPathManager +{ + typedef nvhash_map> TPathBufferHash; + typedef nvhash_map> + TPathSubPathBufferHash; + typedef nvhash_map> TShaderMap; + typedef nvhash_map> + TPaintedShaderMap; + typedef nvhash_map TStringPathBufferMap; + + IQt3DSRenderContextCore &m_CoreContext; + IQt3DSRenderContext *m_RenderContext; + eastl::string m_IdBuilder; + TPathSubPathBufferHash m_SubPathBuffers; + TPathBufferHash m_Buffers; + nvvector m_SubdivResult; + nvvector m_KeyPointVec; + nvvector m_PatchBuffer; + TShaderMap m_PathGeometryShaders; + TPaintedShaderMap m_PathPaintedShaders; + TStringPathBufferMap m_SourcePathBufferMap; + Mutex m_PathBufferMutex; + + NVScopedRefCounted m_DepthShader; + NVScopedRefCounted m_DepthDisplacementShader; + NVScopedRefCounted m_GeometryShadowShader; + NVScopedRefCounted m_GeometryCubeShadowShader; + NVScopedRefCounted m_GeometryDisplacementShadowShader; + + NVScopedRefCounted m_PaintedDepthShader; + NVScopedRefCounted m_PaintedShadowShader; + NVScopedRefCounted m_PaintedCubeShadowShader; + NVScopedRefCounted m_PaintedRectInputAssembler; + NVScopedRefCounted m_PaintedRectVertexBuffer; + NVScopedRefCounted m_PaintedRectIndexBuffer; + + nvvector> m_DepthStencilStates; + + NVScopedRefCounted m_PathSpecification; + NVScopedRefCounted m_PathBuilder; + + QT3DSI32 m_RefCount; + + SPathManager(IQt3DSRenderContextCore &inRC) + : m_CoreContext(inRC) + , m_RenderContext(NULL) + , m_SubPathBuffers(inRC.GetAllocator(), "m_SubPathBuffers") + , m_Buffers(inRC.GetAllocator(), "m_Buffers") + , m_SubdivResult(inRC.GetAllocator(), "m_SubdivResult") + , m_KeyPointVec(inRC.GetAllocator(), "m_KeyPointVec") + , m_PatchBuffer(inRC.GetAllocator(), "m_QuadStrip") + , m_PathGeometryShaders(inRC.GetAllocator(), "m_PathGeometryShaders") + , m_PathPaintedShaders(inRC.GetAllocator(), "m_PathPaintedShaders") + , m_SourcePathBufferMap(inRC.GetAllocator(), "m_SourcePathBufferMap") + , m_PathBufferMutex(inRC.GetAllocator()) + , m_DepthStencilStates(inRC.GetAllocator(), "m_DepthStencilStates") + , m_RefCount(0) + { + } + + virtual ~SPathManager() { m_PaintedRectInputAssembler = NULL; } + + NVAllocatorCallback &GetAllocator() { return m_CoreContext.GetAllocator(); } + IStringTable &GetStringTable() { return m_CoreContext.GetStringTable(); } + NVFoundationBase &GetFoundation() { return m_CoreContext.GetFoundation(); } + + void addRef() override { atomicIncrement(&m_RefCount); } + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(GetAllocator()); + NVDelete(alloc, this); + } + } + // Called during binary load which is heavily threaded. + void SetPathSubPathData(const SPathSubPath &inPath, + NVConstDataRef inPathCubicCurves) override + { + Mutex::ScopedLock __locker(m_PathBufferMutex); + eastl::pair inserter = + m_SubPathBuffers.insert(eastl::make_pair((SPathSubPath *)&inPath, + NVScopedRefCounted(NULL))); + if (!inserter.first->second) + inserter.first->second = QT3DS_NEW(GetAllocator(), SPathSubPathBuffer)( + GetAllocator(), const_cast(inPath)); + SPathSubPathBuffer &theBuffer = *inserter.first->second.mPtr; + theBuffer.m_SourceData.assign(inPathCubicCurves.begin(), inPathCubicCurves.end()); + theBuffer.m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); + } + + SPathBuffer *GetPathBufferObject(const SPath &inPath) + { + eastl::pair inserter = m_Buffers.insert( + eastl::make_pair((SPath *)&inPath, NVScopedRefCounted(NULL))); + if (inserter.second) { + inserter.first->second = QT3DS_NEW(GetAllocator(), SPathBuffer)(GetAllocator()); + } + return inserter.first->second.mPtr; + } + + SPathSubPathBuffer *GetPathBufferObject(const SPathSubPath &inSubPath) + { + TPathSubPathBufferHash::iterator iter = m_SubPathBuffers.find((SPathSubPath *)&inSubPath); + if (iter != m_SubPathBuffers.end()) + return iter->second.mPtr; + return NULL; + } + + NVDataRef GetPathSubPathBuffer(const SPathSubPath &inPath) override + { + SPathSubPathBuffer *theBuffer = GetPathBufferObject(inPath); + if (theBuffer) + return toDataRef(theBuffer->m_SourceData.data(), (QT3DSU32)theBuffer->m_SourceData.size()); + return NVDataRef(); + } + + NVDataRef ResizePathSubPathBuffer(const SPathSubPath &inPath, + QT3DSU32 inNumAnchors) override + { + SPathSubPathBuffer *theBuffer = GetPathBufferObject(inPath); + if (theBuffer == NULL) + SetPathSubPathData(inPath, NVConstDataRef()); + theBuffer = GetPathBufferObject(inPath); + theBuffer->m_SourceData.resize(inNumAnchors); + theBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); + return toDataRef(theBuffer->m_SourceData.data(), (QT3DSU32)theBuffer->m_SourceData.size()); + } + + // This needs to be done using roots of the first derivative. + NVBounds3 GetBounds(const SPath &inPath) override + { + NVBounds3 retval(NVBounds3::empty()); + + SPathBuffer *thePathBuffer = GetPathBufferObject(inPath); + if (thePathBuffer) { + SPathDirtyFlags geomDirtyFlags( + PathDirtyFlagValues::SourceData | PathDirtyFlagValues::BeginTaper + | PathDirtyFlagValues::EndTaper | PathDirtyFlagValues::Width + | PathDirtyFlagValues::CPUError); + + if ((((QT3DSU32)thePathBuffer->m_Flags) & (QT3DSU32)geomDirtyFlags) == 0) { + return thePathBuffer->m_Bounds; + } + } + + for (SPathSubPath *theSubPath = inPath.m_FirstSubPath; theSubPath; + theSubPath = theSubPath->m_NextSubPath) { + SPathSubPathBuffer *theBuffer = GetPathBufferObject(*theSubPath); + if (!theBuffer) + continue; + + QT3DSU32 numAnchors = theBuffer->m_SourceData.size(); + for (QT3DSU32 idx = 0, end = numAnchors; idx < end; ++idx) { + const SPathAnchorPoint &thePoint(theBuffer->m_SourceData[idx]); + QT3DSVec2 position(thePoint.m_Position); + retval.include(QT3DSVec3(position.x, position.y, 0.0f)); + if (idx) { + QT3DSVec2 incoming(IPathManagerCore::GetControlPointFromAngleDistance( + thePoint.m_Position, thePoint.m_IncomingAngle, + thePoint.m_IncomingDistance)); + retval.include(QT3DSVec3(incoming.x, incoming.y, 0.0f)); + } + + if (idx < (numAnchors - 1)) { + QT3DSVec2 outgoing(IPathManagerCore::GetControlPointFromAngleDistance( + thePoint.m_Position, thePoint.m_OutgoingAngle, + thePoint.m_OutgoingDistance)); + retval.include(QT3DSVec3(outgoing.x, outgoing.y, 0.0f)); + } + } + } + + return retval; + } + + IPathManager &OnRenderSystemInitialize(IQt3DSRenderContext &context) override + { + m_RenderContext = &context; + return *this; + } + + // find a point that will join these two curves *if* they are not first derivative continuous + static Option GetAdjoiningPoint(QT3DSVec2 prevC2, QT3DSVec2 point, QT3DSVec2 C1, QT3DSF32 pathWidth) + { + QT3DSVec2 incomingDxDy = (point - prevC2); + QT3DSVec2 outgoingDxDy = (C1 - point); + incomingDxDy.normalize(); + outgoingDxDy.normalize(); + float determinant = (incomingDxDy.x * outgoingDxDy.y) - (incomingDxDy.y * outgoingDxDy.x); + if (fabs(determinant) > .001f) { + float mult = determinant > 0.0f ? 1.0f : -1.0f; + QT3DSVec2 incomingNormal(incomingDxDy.y, -incomingDxDy.x); + QT3DSVec2 outgoingNormal(outgoingDxDy.y, -outgoingDxDy.x); + + QT3DSVec2 leftEdge = point + mult * incomingNormal * pathWidth; + QT3DSVec2 rightEdge = point + mult * outgoingNormal * pathWidth; + + return (leftEdge + rightEdge) / 2.0f; + } + return Empty(); + } + + Option> FindBreakEquation(QT3DSF32 inTaperStart) + { + QT3DSF32 lengthTotal = 0; + for (QT3DSU32 idx = 0, end = m_SubdivResult.size(); idx < end; ++idx) { + if (lengthTotal + m_SubdivResult[idx].m_Length > inTaperStart) { + QT3DSF32 breakTValue = (inTaperStart - lengthTotal) / m_SubdivResult[idx].m_Length; + nvvector::iterator breakIter = m_SubdivResult.begin() + idx; + SCubicBezierCurve theCurve(breakIter->m_P1, breakIter->m_C1, breakIter->m_C2, + breakIter->m_P2); + eastl::pair subdivCurve = + theCurve.SplitCubicBezierCurve(breakTValue); + QT3DSF32 originalBreakT = + breakIter->m_TStart + (breakIter->m_TStop - breakIter->m_TStart) * breakTValue; + // Update the existing item to point to the second equation + breakIter->m_P1 = subdivCurve.second.m_Points[0]; + breakIter->m_C1 = subdivCurve.second.m_Points[1]; + breakIter->m_C2 = subdivCurve.second.m_Points[2]; + breakIter->m_P2 = subdivCurve.second.m_Points[3]; + QT3DSF32 originalLength = breakIter->m_Length; + QT3DSF32 originalStart = breakIter->m_TStart; + breakIter->m_Length *= (1.0f - breakTValue); + breakIter->m_TStart = originalBreakT; + SResultCubic newCubic(subdivCurve.first.m_Points[0], subdivCurve.first.m_Points[1], + subdivCurve.first.m_Points[2], subdivCurve.first.m_Points[3], + breakIter->m_EquationIndex, originalStart, originalBreakT, + originalLength * breakTValue); + + m_SubdivResult.insert(breakIter, newCubic); + return eastl::make_pair(idx, breakTValue); + } + lengthTotal += m_SubdivResult[idx].m_Length; + } + return Empty(); + } + + bool PrepareGeometryPathForRender(const SPath &inPath, SPathBuffer &inPathBuffer) + { + + m_SubdivResult.clear(); + m_KeyPointVec.clear(); + const SPath &thePath(inPath); + + inPathBuffer.SetBeginTaperInfo(thePath.m_BeginCapping, thePath.m_BeginCapOffset, + thePath.m_BeginCapOpacity, thePath.m_BeginCapWidth); + inPathBuffer.SetEndTaperInfo(thePath.m_EndCapping, thePath.m_EndCapOffset, + thePath.m_EndCapOpacity, thePath.m_EndCapWidth); + inPathBuffer.SetWidth(inPath.m_Width); + inPathBuffer.SetCPUError(inPath.m_LinearError); + + SPathDirtyFlags geomDirtyFlags(PathDirtyFlagValues::SourceData + | PathDirtyFlagValues::BeginTaper + | PathDirtyFlagValues::EndTaper | PathDirtyFlagValues::Width + | PathDirtyFlagValues::CPUError); + + bool retval = false; + if (!inPathBuffer.m_PatchData + || (((QT3DSU32)inPathBuffer.m_Flags) & (QT3DSU32)geomDirtyFlags) != 0) { + qt3dsimp::SPathBuffer thePathData = inPathBuffer.GetPathData(*m_PathBuilder); + + QT3DSU32 dataIdx = 0; + QT3DSVec2 prevPoint(0, 0); + QT3DSU32 equationIdx = 0; + for (QT3DSU32 commandIdx = 0, commandEnd = thePathData.m_Commands.size(); + commandIdx < commandEnd; ++commandIdx) { + switch (thePathData.m_Commands[commandIdx]) { + case qt3dsimp::PathCommand::MoveTo: + prevPoint = + QT3DSVec2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + break; + case qt3dsimp::PathCommand::CubicCurveTo: { + QT3DSVec2 c1(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + QT3DSVec2 c2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + QT3DSVec2 p2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + OuterAdaptiveSubdivideBezierCurve( + m_SubdivResult, m_KeyPointVec, SCubicBezierCurve(prevPoint, c1, c2, p2), + NVMax(inPath.m_LinearError, 1.0f), equationIdx); + ++equationIdx; + prevPoint = p2; + } break; + case qt3dsimp::PathCommand::Close: + break; + + default: + QT3DS_ASSERT(false); + break; + } + } + + QT3DSF32 theLocalWidth = inPath.m_Width / 2.0f; + + QT3DSVec2 theBeginTaperData(theLocalWidth, thePath.m_GlobalOpacity); + QT3DSVec2 theEndTaperData(theLocalWidth, thePath.m_GlobalOpacity); + + QT3DSF32 pathLength = 0.0f; + for (QT3DSU32 idx = 0, end = m_SubdivResult.size(); idx < end; ++idx) + pathLength += m_SubdivResult[idx].m_Length; + + if (thePath.m_BeginCapping == PathCapping::Taper + || thePath.m_EndCapping == PathCapping::Taper) { + QT3DSF32 maxTaperStart = pathLength / 2.0f; + if (thePath.m_BeginCapping == PathCapping::Taper) { + // Can't start more than halfway across the path. + QT3DSF32 taperStart = NVMin(thePath.m_BeginCapOffset, maxTaperStart); + QT3DSF32 endTaperWidth = thePath.m_BeginCapWidth; + QT3DSF32 endTaperOpacity = thePath.m_GlobalOpacity * thePath.m_BeginCapOpacity; + theBeginTaperData = QT3DSVec2(endTaperWidth, endTaperOpacity); + // Find where we need to break the current equations. + Option> breakEquationAndT( + FindBreakEquation(taperStart)); + if (breakEquationAndT.hasValue()) { + QT3DSU32 breakEquation = breakEquationAndT->first; + + QT3DSF32 lengthTotal = 0; + for (QT3DSU32 idx = 0, end = breakEquation; idx <= end; ++idx) { + SResultCubic &theCubic = m_SubdivResult[idx]; + theCubic.m_Mode = SResultCubic::BeginTaper; + + theCubic.m_TaperMultiplier[0] = lengthTotal / taperStart; + lengthTotal += theCubic.m_Length; + theCubic.m_TaperMultiplier[1] = lengthTotal / taperStart; + } + } + } + if (thePath.m_EndCapping == PathCapping::Taper) { + QT3DSF32 taperStart = NVMin(thePath.m_EndCapOffset, maxTaperStart); + QT3DSF32 endTaperWidth = thePath.m_EndCapWidth; + QT3DSF32 endTaperOpacity = thePath.m_GlobalOpacity * thePath.m_EndCapOpacity; + theEndTaperData = QT3DSVec2(endTaperWidth, endTaperOpacity); + // Invert taper start so that the forward search works. + Option> breakEquationAndT( + FindBreakEquation(pathLength - taperStart)); + + if (breakEquationAndT.hasValue()) { + QT3DSU32 breakEquation = breakEquationAndT->first; + ++breakEquation; + + QT3DSF32 lengthTotal = 0; + for (QT3DSU32 idx = breakEquation, end = m_SubdivResult.size(); idx < end; + ++idx) { + SResultCubic &theCubic = m_SubdivResult[idx]; + theCubic.m_Mode = SResultCubic::EndTaper; + + theCubic.m_TaperMultiplier[0] = 1.0f - (lengthTotal / taperStart); + lengthTotal += theCubic.m_Length; + theCubic.m_TaperMultiplier[1] = 1.0f - (lengthTotal / taperStart); + } + } + } + } + + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + // Create quads out of each point. + if (m_SubdivResult.empty()) + return false; + + // Generate patches. + m_PatchBuffer.clear(); + QT3DSF32 pathWidth = thePath.m_Width / 2.0f; + // texture coords + float texCoordU = 0.0; + + for (QT3DSU32 idx = 0, end = m_SubdivResult.size(); idx < end; ++idx) { + // create patches + SResultCubic thePoint(m_SubdivResult[idx]); + + m_PatchBuffer.push_back(CreateVec4(thePoint.m_P1, thePoint.m_C1)); + m_PatchBuffer.push_back(CreateVec4(thePoint.m_C2, thePoint.m_P2)); + + // Now we need to take care of cases where the control points of the adjoining + // SubPaths + // do not line up; i.e. there is a discontinuity of the 1st derivative + // The simplest way to do this is to move the edge vertex to a halfway point + // between a line bisecting the two control lines + QT3DSVec2 incomingAdjoining(thePoint.m_P1); + QT3DSVec2 outgoingAdjoining(thePoint.m_P2); + if (idx) { + SResultCubic previousCurve = m_SubdivResult[idx - 1]; + if (previousCurve.m_EquationIndex != thePoint.m_EquationIndex) { + QT3DSF32 anchorWidth = + thePoint.GetP1Width(pathWidth, theBeginTaperData.x, theEndTaperData.x); + Option adjoining = GetAdjoiningPoint( + previousCurve.m_C2, thePoint.m_P1, thePoint.m_C1, anchorWidth); + if (adjoining.hasValue()) + incomingAdjoining = *adjoining; + } + } + if (idx < (end - 1)) { + SResultCubic nextCurve = m_SubdivResult[idx + 1]; + if (nextCurve.m_EquationIndex != thePoint.m_EquationIndex) { + QT3DSF32 anchorWidth = + thePoint.GetP2Width(pathWidth, theBeginTaperData.x, theEndTaperData.x); + Option adjoining = GetAdjoiningPoint(thePoint.m_C2, thePoint.m_P2, + nextCurve.m_C1, anchorWidth); + if (adjoining.hasValue()) + outgoingAdjoining = *adjoining; + } + } + m_PatchBuffer.push_back(CreateVec4(incomingAdjoining, outgoingAdjoining)); + + QT3DSVec4 taperData(0.0f); + taperData.x = thePoint.m_TaperMultiplier.x; + taperData.y = thePoint.m_TaperMultiplier.y; + // Note we could put a *lot* more data into this thing. + taperData.z = (QT3DSF32)thePoint.m_Mode; + m_PatchBuffer.push_back(taperData); + + // texture coord generation + // note we only generate u here. v is generated in the tess shader + // u coord for P1 and C1 + QT3DSVec2 udata(texCoordU, texCoordU + (thePoint.m_Length / pathLength)); + texCoordU = udata.y; + m_PatchBuffer.push_back(QT3DSVec4(udata.x, udata.y, 0.0, 0.0)); + } + + // buffer size is 3.0*4.0*bufSize + QT3DSU32 bufSize = (QT3DSU32)m_PatchBuffer.size() * sizeof(QT3DSVec4); + QT3DSU32 stride = sizeof(QT3DSVec4); + + if ((!inPathBuffer.m_PatchData) || inPathBuffer.m_PatchData->Size() < bufSize) { + inPathBuffer.m_PatchData = theRenderContext.CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Dynamic, bufSize, stride, + toU8DataRef(m_PatchBuffer.data(), (QT3DSU32)m_PatchBuffer.size())); + inPathBuffer.m_NumVertexes = (QT3DSU32)m_PatchBuffer.size(); + inPathBuffer.m_InputAssembler = NULL; + } else { + QT3DS_ASSERT(inPathBuffer.m_PatchData->Size() >= bufSize); + inPathBuffer.m_PatchData->UpdateBuffer( + toU8DataRef(m_PatchBuffer.data(), (QT3DSU32)m_PatchBuffer.size())); + } + + if (!inPathBuffer.m_InputAssembler) { + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry( + "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 4), + }; + + NVRenderDrawMode::Enum primType = NVRenderDrawMode::Patches; + + NVRenderAttribLayout *theLayout = + theRenderContext.CreateAttributeLayout(toConstDataRef(theEntries, 1)); + // How many vertices the TCS shader has access to in order to produce its output + // array of vertices. + const QT3DSU32 inputPatchVertexCount = 5; + inPathBuffer.m_InputAssembler = theRenderContext.CreateInputAssembler( + theLayout, toConstDataRef(inPathBuffer.m_PatchData.mPtr), NULL, + toConstDataRef(stride), toConstDataRef((QT3DSU32)0), primType, + inputPatchVertexCount); + } + inPathBuffer.m_BeginTaperData = theBeginTaperData; + inPathBuffer.m_EndTaperData = theEndTaperData; + + // cache bounds + NVBounds3 bounds = GetBounds(inPath); + inPathBuffer.m_Bounds.minimum = bounds.minimum; + inPathBuffer.m_Bounds.maximum = bounds.maximum; + } + + return retval; + } + + IMaterialShaderGenerator *GetMaterialShaderGenertator(SPathRenderContext &inRenderContext) + { + bool isDefaultMaterial = + (inRenderContext.m_Material.m_Type == GraphObjectTypes::DefaultMaterial); + + IMaterialShaderGenerator *theMaterialGenerator = NULL; + if (isDefaultMaterial) + theMaterialGenerator = &m_RenderContext->GetDefaultMaterialShaderGenerator(); + else + theMaterialGenerator = &m_RenderContext->GetCustomMaterialShaderGenerator(); + + return theMaterialGenerator; + } + + CRegisteredString GetMaterialNameForKey(SPathRenderContext &inRenderContext) + { + bool isDefaultMaterial = + (inRenderContext.m_Material.m_Type == GraphObjectTypes::DefaultMaterial); + + if (!isDefaultMaterial) { + ICustomMaterialSystem &theMaterialSystem(m_RenderContext->GetCustomMaterialSystem()); + const SCustomMaterial &theCustomMaterial( + reinterpret_cast(inRenderContext.m_Material)); + + return m_RenderContext->GetStringTable().RegisterStr( + theMaterialSystem.GetShaderName(theCustomMaterial)); + } + + return m_RenderContext->GetStringTable().RegisterStr(""); + } + + bool PreparePaintedPathForRender(const SPath &inPath, SPathBuffer &inPathBuffer) + { + NVRenderContext &theContext(this->m_RenderContext->GetRenderContext()); + if (!inPathBuffer.m_PathRender + || (((QT3DSU32)inPathBuffer.m_Flags) & PathDirtyFlagValues::SourceData)) { + if (!inPathBuffer.m_PathRender) { + inPathBuffer.m_PathRender = theContext.CreatePathRender(); + } + + if (inPathBuffer.m_PathRender == NULL || m_PathSpecification == NULL) { + // QT3DS_ASSERT( false ); + return false; + } + + m_PathSpecification->Reset(); + qt3dsimp::SPathBuffer thePathData = inPathBuffer.GetPathData(*m_PathBuilder); + + QT3DSU32 dataIdx = 0; + for (QT3DSU32 commandIdx = 0, commandEnd = thePathData.m_Commands.size(); + commandIdx < commandEnd; ++commandIdx) { + + switch (thePathData.m_Commands[commandIdx]) { + case qt3dsimp::PathCommand::MoveTo: + m_PathSpecification->MoveTo( + QT3DSVec2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1])); + dataIdx += 2; + break; + case qt3dsimp::PathCommand::CubicCurveTo: { + QT3DSVec2 c1(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + QT3DSVec2 c2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + QT3DSVec2 p2(thePathData.m_Data[dataIdx], thePathData.m_Data[dataIdx + 1]); + dataIdx += 2; + m_PathSpecification->CubicCurveTo(c1, c2, p2); + } break; + case qt3dsimp::PathCommand::Close: + m_PathSpecification->ClosePath(); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + inPathBuffer.m_PathRender->SetPathSpecification(*m_PathSpecification); + + // cache bounds + NVBounds3 bounds = GetBounds(inPath); + inPathBuffer.m_Bounds.minimum = bounds.minimum; + inPathBuffer.m_Bounds.maximum = bounds.maximum; + + return true; + } + + return false; + } + + bool PrepareForRender(const SPath &inPath) override + { + SPathBuffer *thePathBuffer = GetPathBufferObject(inPath); + if (!thePathBuffer) { + return false; + } + NVRenderContext &theContext(this->m_RenderContext->GetRenderContext()); + if (!m_PathSpecification) + m_PathSpecification = theContext.CreatePathSpecification(); + if (!m_PathSpecification) + return false; + if (!m_PathBuilder) + m_PathBuilder = qt3dsimp::IPathBufferBuilder::CreateBuilder(GetFoundation()); + + thePathBuffer->SetPathType(inPath.m_PathType); + bool retval = false; + if (inPath.m_PathBuffer.IsValid() == false) { + thePathBuffer->m_PathBuffer = NULL; + // Ensure the SubPath list is identical and clear, percolating any dirty flags up to the + // path buffer. + QT3DSU32 SubPathIdx = 0; + for (const SPathSubPath *theSubPath = inPath.m_FirstSubPath; theSubPath; + theSubPath = theSubPath->m_NextSubPath, ++SubPathIdx) { + SPathSubPathBuffer *theSubPathBuffer = GetPathBufferObject(*theSubPath); + if (theSubPathBuffer == NULL) + continue; + thePathBuffer->m_Flags = + (QT3DSU32)(thePathBuffer->m_Flags | theSubPathBuffer->m_Flags); + + if (theSubPathBuffer->m_Closed != theSubPath->m_Closed) { + thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); + theSubPathBuffer->m_Closed = theSubPath->m_Closed; + } + + if (thePathBuffer->m_SubPaths.size() <= SubPathIdx + || thePathBuffer->m_SubPaths[SubPathIdx] != theSubPathBuffer) { + thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); + if (thePathBuffer->m_SubPaths.size() <= SubPathIdx) + thePathBuffer->m_SubPaths.push_back(theSubPathBuffer); + else + thePathBuffer->m_SubPaths[SubPathIdx] = theSubPathBuffer; + } + + theSubPathBuffer->m_Flags.Clear(); + } + + if (SubPathIdx != thePathBuffer->m_SubPaths.size()) { + thePathBuffer->m_SubPaths.resize(SubPathIdx); + thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); + } + } else { + thePathBuffer->m_SubPaths.clear(); + eastl::pair inserter = + m_SourcePathBufferMap.insert( + eastl::make_pair(inPath.m_PathBuffer, TPathBufferPtr())); + if (inserter.second) { + NVScopedRefCounted theStream = + m_CoreContext.GetInputStreamFactory().GetStreamForFile( + inPath.m_PathBuffer.c_str()); + if (theStream) { + qt3dsimp::SPathBuffer *theNewBuffer = + qt3dsimp::SPathBuffer::Load(*theStream, GetFoundation()); + if (theNewBuffer) + inserter.first->second = QT3DS_NEW(GetAllocator(), SImportPathWrapper)( + GetAllocator(), *theNewBuffer); + } + } + if (thePathBuffer->m_PathBuffer != inserter.first->second) { + thePathBuffer->m_PathBuffer = inserter.first->second; + thePathBuffer->m_Flags.clearOrSet(true, PathDirtyFlagValues::SourceData); + } + } + + if (inPath.m_PathType == PathTypes::Geometry) + retval = PrepareGeometryPathForRender(inPath, *thePathBuffer); + else + retval = PreparePaintedPathForRender(inPath, *thePathBuffer); + thePathBuffer->m_Flags.Clear(); + return retval; + } + + void SetMaterialProperties(NVRenderShaderProgram &inShader, SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties &inRenderProperties) + { + IMaterialShaderGenerator *theMaterialGenerator = + GetMaterialShaderGenertator(inRenderContext); + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + theRenderContext.SetActiveShader(&inShader); + + theMaterialGenerator->SetMaterialProperties( + inShader, inRenderContext.m_Material, inRenderContext.m_CameraVec, + inRenderContext.m_ModelViewProjection, inRenderContext.m_NormalMatrix, + inRenderContext.m_Path.m_GlobalTransform, inRenderContext.m_FirstImage, + inRenderContext.m_Opacity, inRenderProperties); + } + + void DoRenderGeometryPath(SPathGeneratedShader &inShader, SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties &inRenderProperties, + SPathBuffer &inPathBuffer) + { + if (inPathBuffer.m_InputAssembler == NULL) + return; + + SetMaterialProperties(inShader.m_Shader, inRenderContext, inRenderProperties); + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + + inShader.m_BeginTaperData.Set(inPathBuffer.m_BeginTaperData); + inShader.m_EndTaperData.Set(inPathBuffer.m_EndTaperData); + if (inRenderContext.m_EnableWireframe) { + // we need the viewport matrix + NVRenderRect theViewport(theRenderContext.GetViewport()); + QT3DSMat44 vpMatrix; + vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0); + vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0); + vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0); + vpMatrix.column3 = + QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X, + (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0); + + inShader.m_WireframeViewMatrix.Set(vpMatrix); + } + + QT3DSF32 tessEdgeValue = NVMin(64.0f, NVMax(1.0f, inRenderContext.m_Path.m_EdgeTessAmount)); + QT3DSF32 tessInnerValue = NVMin(64.0f, NVMax(1.0f, inRenderContext.m_Path.m_InnerTessAmount)); + inShader.m_EdgeTessAmount.Set(tessEdgeValue); + inShader.m_InnerTessAmount.Set(tessInnerValue); + inShader.m_Width.Set(inRenderContext.m_Path.m_Width / 2.0f); + theRenderContext.SetInputAssembler(inPathBuffer.m_InputAssembler); + theRenderContext.SetCullingEnabled(false); + NVRenderDrawMode::Enum primType = NVRenderDrawMode::Patches; + theRenderContext.Draw(primType, (QT3DSU32)inPathBuffer.m_NumVertexes, 0); + } + + NVRenderDepthStencilState *GetDepthStencilState() + { + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + NVRenderBoolOp::Enum theDepthFunction = theRenderContext.GetDepthFunction(); + bool isDepthEnabled = theRenderContext.IsDepthTestEnabled(); + bool isStencilEnabled = theRenderContext.IsStencilTestEnabled(); + bool isDepthWriteEnabled = theRenderContext.IsDepthWriteEnabled(); + for (QT3DSU32 idx = 0, end = m_DepthStencilStates.size(); idx < end; ++idx) { + NVRenderDepthStencilState &theState = *m_DepthStencilStates[idx]; + if (theState.GetDepthFunc() == theDepthFunction + && theState.GetDepthEnabled() == isDepthEnabled + && theState.GetDepthMask() == isDepthWriteEnabled) + return &theState; + } + NVRenderStencilFunctionArgument theArg(NVRenderBoolOp::NotEqual, 0, 0xFF); + NVRenderStencilOperationArgument theOpArg(NVRenderStencilOp::Keep, NVRenderStencilOp::Keep, + NVRenderStencilOp::Zero); + m_DepthStencilStates.push_back(theRenderContext.CreateDepthStencilState( + isDepthEnabled, isDepthWriteEnabled, theDepthFunction, isStencilEnabled, theArg, theArg, + theOpArg, theOpArg)); + return m_DepthStencilStates.back(); + } + + static void DoSetCorrectiveScale(const QT3DSMat44 &mvp, QT3DSMat44 &outScale, NVBounds3 pathBounds) + { + // Compute the projected locations for the paraboloid and regular projection + // and thereby set the appropriate scaling factor. + QT3DSVec3 points[4]; + QT3DSVec3 projReg[4], projParab[4]; + points[0] = pathBounds.minimum; + points[1] = QT3DSVec3(pathBounds.maximum.x, pathBounds.minimum.y, pathBounds.minimum.z); + points[2] = pathBounds.maximum; + points[3] = QT3DSVec3(pathBounds.minimum.x, pathBounds.maximum.y, pathBounds.maximum.z); + + // Do the two different projections. + for (int i = 0; i < 4; ++i) { + QT3DSVec4 tmp; + tmp = mvp.transform(QT3DSVec4(points[i], 1.0f)); + tmp /= tmp.w; + projReg[i] = tmp.getXYZ(); + projParab[i] = tmp.getXYZ().getNormalized(); + projParab[i] /= projParab[i].z + 1.0f; + } + + NVBounds3 boundsA, boundsB; + for (int i = 0; i < 4; ++i) { + boundsA.include(projReg[i]); + boundsB.include(projParab[i]); + } + QT3DSF32 xscale = + (boundsB.maximum.x - boundsB.minimum.x) / (boundsA.maximum.x - boundsA.minimum.x); + QT3DSF32 yscale = + (boundsB.maximum.y - boundsB.minimum.y) / (boundsA.maximum.y - boundsA.minimum.y); + QT3DSF32 zscale = (boundsB.maximum - boundsB.minimum).magnitudeSquared() + / (boundsA.maximum - boundsA.minimum).magnitudeSquared(); + // The default minimum here is just a stupid figure that looks good on our content because + // we'd + // been using it for a little while before. Just for demo. + xscale = NVMin(0.5333333f, NVMin(xscale, yscale)); + yscale = NVMin(0.5333333f, NVMin(xscale, yscale)); + outScale.scale(QT3DSVec4(xscale, yscale, zscale, 1.0f)); + } + + void DoRenderPaintedPath(SPathXYGeneratedShader &inShader, SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties &inRenderProperties, + SPathBuffer &inPathBuffer, bool isParaboloidPass = false) + { + if (!inPathBuffer.m_PathRender) + return; + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + if (!m_PaintedRectInputAssembler) { + QT3DSVec2 vertexes[] = { + QT3DSVec2(0.0, 0.0), QT3DSVec2(1.0, 0.0), QT3DSVec2(1.0, 1.0), QT3DSVec2(0.0, 1.0), + }; + + QT3DSU8 indexes[] = { + 0, 1, 2, 2, 3, 0, + }; + + QT3DSU32 stride = sizeof(QT3DSVec2); + + NVRenderVertexBufferEntry theBufferEntries[] = { NVRenderVertexBufferEntry( + "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 0) }; + + m_PaintedRectVertexBuffer = theRenderContext.CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, 4 * sizeof(QT3DSVec2), sizeof(QT3DSVec2), + toU8DataRef(vertexes, 4)); + m_PaintedRectIndexBuffer = theRenderContext.CreateIndexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, + qt3ds::render::NVRenderComponentTypes::QT3DSU8, 6, toU8DataRef(indexes, 6)); + NVRenderAttribLayout *theAttribLayout = + theRenderContext.CreateAttributeLayout(toConstDataRef(theBufferEntries, 1)); + m_PaintedRectInputAssembler = theRenderContext.CreateInputAssembler( + theAttribLayout, toConstDataRef(m_PaintedRectVertexBuffer.mPtr), + m_PaintedRectIndexBuffer.mPtr, toConstDataRef(stride), toConstDataRef((QT3DSU32)0), + qt3ds::render::NVRenderDrawMode::Triangles); + } + + // our current render target needs stencil + QT3DS_ASSERT(theRenderContext.GetStencilBits() > 0); + + theRenderContext.SetDepthStencilState(GetDepthStencilState()); + + // http://developer.download.nvidia.com/assets/gamedev/files/Mixing_Path_Rendering_and_3D.pdf + theRenderContext.SetPathStencilDepthOffset(-.05f, -1.0f); + + // Stencil out the geometry. + QT3DSMat44 pathMdlView = QT3DSMat44::createIdentity(); + // Why is this happening? Well, it's because the painted-on path rendering is always + // a flat splatted 2D object. This is bad because a paraboloid projection demands a very + // different + // non-linear space into which we must draw. Path Rendering does not allow this sort of + // spatial + // warping internally, and all we end up passing in as a simple perspective projection. + // So for the fix, I'm scaling the actual "object" size so that it fits into the correctly + // projected + // polygon inside the paraboloid depth pass. Obviously, this scaling factor is wrong, and + // not generic + // enough to cover cases like polygons covering a large spread of the FOV and so on. It's + // really + // just a filthy awful, morally deplorable HACK. But it's basically the quickest fix at + // hand. + // This is also about the only possible approach that *could* work short of rendering the + // paths in + // a render-to-texture pass and splatting that texture on a sufficiently tessellated quad. + // Unless + // there's a way to program NVPR's internal projection scheme, that is. + // Geometry-based paths will work out better, I think, because they're actually creating + // geometry. + // This is essentially a 2D painting process inside a quad where the actual rendered region + // isn't + // exactly where NVPR thinks it should be because they're not projecting points the same + // way. + if (isParaboloidPass) { + DoSetCorrectiveScale(inRenderContext.m_ModelViewProjection, pathMdlView, + inPathBuffer.m_PathRender->GetPathObjectStrokeBox()); + } + + bool isStencilEnabled = theRenderContext.IsStencilTestEnabled(); + theRenderContext.SetStencilTestEnabled(true); + theRenderContext.SetPathProjectionMatrix(inRenderContext.m_ModelViewProjection); + theRenderContext.SetPathModelViewMatrix(pathMdlView); + + if (inRenderContext.m_IsStroke) { + inPathBuffer.m_PathRender->SetStrokeWidth(inRenderContext.m_Path.m_Width); + inPathBuffer.m_PathRender->StencilStroke(); + } else + inPathBuffer.m_PathRender->StencilFill(); + + // The stencil buffer will dictate whether this object renders or not. So we need to ignore + // the depth test result. + NVRenderBoolOp::Enum theDepthFunc = theRenderContext.GetDepthFunction(); + theRenderContext.SetDepthFunction(NVRenderBoolOp::AlwaysTrue); + // Now render the path; this resets the stencil buffer. + SetMaterialProperties(inShader.m_Shader, inRenderContext, inRenderProperties); + NVBounds3 rectBounds = inPathBuffer.m_PathRender->GetPathObjectStrokeBox(); + if (isParaboloidPass) { + rectBounds.scale(1.570796326795f); + } // PKC : More of the same ugly hack. + inShader.m_RectDimensions.Set(QT3DSVec4(rectBounds.minimum.x, rectBounds.minimum.y, + rectBounds.maximum.x, rectBounds.maximum.y)); + theRenderContext.SetInputAssembler(m_PaintedRectInputAssembler); + theRenderContext.SetCullingEnabled(false); + // Render exactly two triangles + theRenderContext.Draw(NVRenderDrawMode::Triangles, 6, 0); + theRenderContext.SetStencilTestEnabled(isStencilEnabled); + theRenderContext.SetDepthFunction(theDepthFunc); + } + + void RenderDepthPrepass(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) override + { + SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); + if (!thePathBuffer) { + return; + } + + if (thePathBuffer->m_PathType == PathTypes::Geometry) { + QT3DSU32 displacementIdx = 0; + QT3DSU32 imageIdx = 0; + SRenderableImage *displacementImage = 0; + + for (SRenderableImage *theImage = inRenderContext.m_FirstImage; + theImage != NULL && displacementImage == NULL; + theImage = theImage->m_NextImage, ++imageIdx) { + if (theImage->m_MapType == ImageMapTypes::Displacement) { + displacementIdx = imageIdx; + displacementImage = theImage; + } + } + + NVScopedRefCounted &theDesiredDepthShader = + displacementImage == NULL ? m_DepthShader : m_DepthDisplacementShader; + + if (!theDesiredDepthShader) { + IDefaultMaterialShaderGenerator &theMaterialGenerator( + m_RenderContext->GetDefaultMaterialShaderGenerator()); + SPathVertexPipeline thePipeline( + m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, + m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable(), false); + thePipeline.BeginVertexGeneration(displacementIdx, displacementImage); + thePipeline.BeginFragmentGeneration(); + thePipeline.Fragment().Append("\tfragOutput = vec4(1.0, 1.0, 1.0, 1.0);"); + thePipeline.EndVertexGeneration(); + thePipeline.EndFragmentGeneration(); + const char8_t *shaderName = "path depth"; + if (displacementImage) + shaderName = "path depth displacement"; + + SShaderCacheProgramFlags theFlags; + NVRenderShaderProgram *theProgram = + thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, + inFeatureSet); + if (theProgram) { + theDesiredDepthShader = + QT3DS_NEW(m_RenderContext->GetAllocator(), + SPathGeneratedShader)(*theProgram, m_RenderContext->GetAllocator()); + } + } + if (theDesiredDepthShader) { + DoRenderGeometryPath(*theDesiredDepthShader, inRenderContext, inRenderProperties, + *thePathBuffer); + } + } else { + // painted path, go stroke route for now. + if (!m_PaintedDepthShader) { + IDefaultMaterialShaderGenerator &theMaterialGenerator( + m_RenderContext->GetDefaultMaterialShaderGenerator()); + SXYRectVertexPipeline thePipeline( + m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, + m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); + thePipeline.BeginVertexGeneration(0, NULL); + thePipeline.BeginFragmentGeneration(); + thePipeline.Fragment().Append("\tfragOutput = vec4(1.0, 1.0, 1.0, 1.0);"); + thePipeline.EndVertexGeneration(); + thePipeline.EndFragmentGeneration(); + const char8_t *shaderName = "path painted depth"; + SShaderCacheProgramFlags theFlags; + NVRenderShaderProgram *theProgram = + thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, + inFeatureSet); + if (theProgram) { + m_PaintedDepthShader = + QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( + *theProgram, m_RenderContext->GetAllocator()); + } + } + if (m_PaintedDepthShader) { + + DoRenderPaintedPath(*m_PaintedDepthShader, inRenderContext, inRenderProperties, + *thePathBuffer); + } + } + } + + void RenderShadowMapPass(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) override + { + SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); + if (!thePathBuffer) { + return; + } + + if (inRenderContext.m_Material.m_Type != GraphObjectTypes::DefaultMaterial) + return; + + if (thePathBuffer->m_PathType == PathTypes::Painted) { + // painted path, go stroke route for now. + if (!m_PaintedShadowShader) { + IDefaultMaterialShaderGenerator &theMaterialGenerator( + m_RenderContext->GetDefaultMaterialShaderGenerator()); + SXYRectVertexPipeline thePipeline( + m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, + m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); + thePipeline.OutputParaboloidDepthShaders(); + const char8_t *shaderName = "path painted paraboloid depth"; + SShaderCacheProgramFlags theFlags; + NVRenderShaderProgram *theProgram = + thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, + inFeatureSet); + if (theProgram) { + m_PaintedShadowShader = + QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( + *theProgram, m_RenderContext->GetAllocator()); + } + } + if (m_PaintedShadowShader) { + // Setup the shader paraboloid information. + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + theRenderContext.SetActiveShader(&m_PaintedShadowShader->m_Shader); + + DoRenderPaintedPath(*m_PaintedShadowShader, inRenderContext, inRenderProperties, + *thePathBuffer, true); + } + } else { + // Until we've also got a proper path render path for this, we'll call the old-fashioned + // stuff. + RenderDepthPrepass(inRenderContext, inRenderProperties, inFeatureSet); + // QT3DS_ASSERT( false ); + } + } + + void RenderCubeFaceShadowPass(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) override + { + SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); + if (!thePathBuffer) { + return; + } + + if (inRenderContext.m_Material.m_Type != GraphObjectTypes::DefaultMaterial) + return; + + if (thePathBuffer->m_PathType == PathTypes::Painted) { + if (!m_PaintedCubeShadowShader) { + IDefaultMaterialShaderGenerator &theMaterialGenerator( + m_RenderContext->GetDefaultMaterialShaderGenerator()); + SXYRectVertexPipeline thePipeline( + m_RenderContext->GetShaderProgramGenerator(), theMaterialGenerator, + m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); + thePipeline.OutputCubeFaceDepthShaders(); + const char8_t *shaderName = "path painted cube face depth"; + SShaderCacheProgramFlags theFlags; + NVRenderShaderProgram *theProgram = + thePipeline.ProgramGenerator().CompileGeneratedShader(shaderName, theFlags, + inFeatureSet); + if (theProgram) { + m_PaintedCubeShadowShader = + QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( + *theProgram, m_RenderContext->GetAllocator()); + } + } + if (m_PaintedCubeShadowShader) { + // Setup the shader information. + NVRenderContext &theRenderContext(m_RenderContext->GetRenderContext()); + theRenderContext.SetActiveShader(&m_PaintedCubeShadowShader->m_Shader); + + m_PaintedCubeShadowShader->m_CameraPosition.Set( + inRenderContext.m_Camera.GetGlobalPos()); + m_PaintedCubeShadowShader->m_CameraProperties.Set( + QT3DSVec2(1.0f, inRenderContext.m_Camera.m_ClipFar)); + m_PaintedCubeShadowShader->m_ModelMatrix.Set(inRenderContext.m_ModelMatrix); + + DoRenderPaintedPath(*m_PaintedCubeShadowShader, inRenderContext, inRenderProperties, + *thePathBuffer, false); + } + } else { + // Until we've also got a proper path render path for this, we'll call the old-fashioned + // stuff. + RenderDepthPrepass(inRenderContext, inRenderProperties, inFeatureSet); + } + } + + void RenderPath(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) override + { + SPathBuffer *thePathBuffer = GetPathBufferObject(inRenderContext.m_Path); + if (!thePathBuffer) { + return; + } + + bool isDefaultMaterial = + (inRenderContext.m_Material.m_Type == GraphObjectTypes::DefaultMaterial); + + if (thePathBuffer->m_PathType == PathTypes::Geometry) { + IMaterialShaderGenerator *theMaterialGenerator = + GetMaterialShaderGenertator(inRenderContext); + + // we need a more evolved key her for custom materials + // the same key can still need a different shader + SPathShaderMapKey sPathkey = SPathShaderMapKey(GetMaterialNameForKey(inRenderContext), + inRenderContext.m_MaterialKey); + eastl::pair inserter = m_PathGeometryShaders.insert( + eastl::make_pair(sPathkey, NVScopedRefCounted(NULL))); + if (inserter.second) { + SPathVertexPipeline thePipeline( + m_RenderContext->GetShaderProgramGenerator(), *theMaterialGenerator, + m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable(), + m_RenderContext->GetWireframeMode()); + + NVRenderShaderProgram *theProgram = NULL; + + if (isDefaultMaterial) { + theProgram = theMaterialGenerator->GenerateShader( + inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, + inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, + inRenderContext.m_Opacity < 1.0, "path geometry pipeline-- "); + } else { + ICustomMaterialSystem &theMaterialSystem( + m_RenderContext->GetCustomMaterialSystem()); + const SCustomMaterial &theCustomMaterial( + reinterpret_cast(inRenderContext.m_Material)); + + theProgram = theMaterialGenerator->GenerateShader( + inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, + inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, + inRenderContext.m_Opacity < 1.0, "path geometry pipeline-- ", + theMaterialSystem.GetShaderName(theCustomMaterial)); + } + + if (theProgram) + inserter.first->second = + QT3DS_NEW(m_RenderContext->GetAllocator(), + SPathGeneratedShader)(*theProgram, m_RenderContext->GetAllocator()); + } + if (!inserter.first->second) + return; + + DoRenderGeometryPath(*inserter.first->second.mPtr, inRenderContext, inRenderProperties, + *thePathBuffer); + } else { + IMaterialShaderGenerator *theMaterialGenerator = + GetMaterialShaderGenertator(inRenderContext); + + // we need a more evolved key her for custom materials + // the same key can still need a different shader + SPathShaderMapKey sPathkey = SPathShaderMapKey(GetMaterialNameForKey(inRenderContext), + inRenderContext.m_MaterialKey); + eastl::pair inserter = m_PathPaintedShaders.insert( + eastl::make_pair(sPathkey, NVScopedRefCounted(NULL))); + + if (inserter.second) { + SXYRectVertexPipeline thePipeline( + m_RenderContext->GetShaderProgramGenerator(), *theMaterialGenerator, + m_RenderContext->GetAllocator(), m_RenderContext->GetStringTable()); + + NVRenderShaderProgram *theProgram = NULL; + + if (isDefaultMaterial) { + theProgram = theMaterialGenerator->GenerateShader( + inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, + inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, + inRenderContext.m_Opacity < 1.0, "path painted pipeline-- "); + } else { + ICustomMaterialSystem &theMaterialSystem( + m_RenderContext->GetCustomMaterialSystem()); + const SCustomMaterial &theCustomMaterial( + reinterpret_cast(inRenderContext.m_Material)); + + theProgram = theMaterialGenerator->GenerateShader( + inRenderContext.m_Material, inRenderContext.m_MaterialKey, thePipeline, + inFeatureSet, inRenderProperties.m_Lights, inRenderContext.m_FirstImage, + inRenderContext.m_Opacity < 1.0, "path painted pipeline-- ", + theMaterialSystem.GetShaderName(theCustomMaterial)); + } + + if (theProgram) + inserter.first->second = + QT3DS_NEW(m_RenderContext->GetAllocator(), SPathXYGeneratedShader)( + *theProgram, m_RenderContext->GetAllocator()); + } + if (!inserter.first->second) + return; + + DoRenderPaintedPath(*inserter.first->second.mPtr, inRenderContext, inRenderProperties, + *thePathBuffer); + } + } +}; +} + +QT3DSVec2 IPathManagerCore::GetControlPointFromAngleDistance(QT3DSVec2 inPosition, float inIncomingAngle, + float inIncomingDistance) +{ + if (inIncomingDistance == 0.0f) + return inPosition; + float angleRad = degToRad(inIncomingAngle); + float angleSin = NVSin(angleRad); + float angleCos = NVCos(angleRad); + QT3DSVec2 relativeAngles = QT3DSVec2(angleCos * inIncomingDistance, angleSin * inIncomingDistance); + return inPosition + relativeAngles; +} + +QT3DSVec2 IPathManagerCore::GetAngleDistanceFromControlPoint(QT3DSVec2 inPosition, QT3DSVec2 inControlPoint) +{ + QT3DSVec2 relative = inControlPoint - inPosition; + float angleRad = atan2(relative.y, relative.x); + float distance = relative.magnitude(); + return QT3DSVec2(radToDeg(angleRad), distance); +} + +IPathManagerCore &IPathManagerCore::CreatePathManagerCore(IQt3DSRenderContextCore &ctx) +{ + return *QT3DS_NEW(ctx.GetAllocator(), SPathManager)(ctx); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.h new file mode 100644 index 00000000..fc7e05f1 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPathManager.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_MANAGER_H +#define QT3DS_RENDER_PATH_MANAGER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderShaderCache.h" //TShaderFeatureSet +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSBounds3.h" +//#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" //SLayerGlobalRenderProperties + +namespace qt3ds { +namespace render { + + struct SLayerGlobalRenderProperties; + + struct SPathAnchorPoint + { + QT3DSVec2 m_Position; + QT3DSF32 m_IncomingAngle; + QT3DSF32 m_OutgoingAngle; + QT3DSF32 m_IncomingDistance; + QT3DSF32 m_OutgoingDistance; + SPathAnchorPoint() {} + SPathAnchorPoint(QT3DSVec2 inPos, QT3DSF32 inAngle, QT3DSF32 outAngle, QT3DSF32 inDis, QT3DSF32 outDis) + : m_Position(inPos) + , m_IncomingAngle(inAngle) + , m_OutgoingAngle(outAngle) + , m_IncomingDistance(inDis) + , m_OutgoingDistance(outDis) + { + } + }; + + class IPathManagerCore : public NVRefCounted + { + public: + // returns the path buffer id + //!! Note this call is made from multiple threads simultaneously during binary load. + //!! - see UICRenderGraphObjectSerializer.cpp + virtual void + SetPathSubPathData(const SPathSubPath &inPathSubPath, + NVConstDataRef inPathSubPathAnchorPoints) = 0; + + virtual NVDataRef + GetPathSubPathBuffer(const SPathSubPath &inPathSubPath) = 0; + // Marks the PathSubPath anchor points as dirty. This will mean rebuilding any PathSubPath + // context required to render the PathSubPath. + virtual NVDataRef + ResizePathSubPathBuffer(const SPathSubPath &inPathSubPath, QT3DSU32 inNumAnchors) = 0; + virtual NVBounds3 GetBounds(const SPath &inPath) = 0; + + // Helper functions used in various locations + // Angles here are in degrees because that is how they are represented in the data. + static QT3DSVec2 GetControlPointFromAngleDistance(QT3DSVec2 inPosition, float inAngle, + float inDistance); + + // Returns angle in x, distance in y. + static QT3DSVec2 GetAngleDistanceFromControlPoint(QT3DSVec2 inPosition, QT3DSVec2 inControlPoint); + + virtual IPathManager &OnRenderSystemInitialize(IQt3DSRenderContext &context) = 0; + + static IPathManagerCore &CreatePathManagerCore(IQt3DSRenderContextCore &inContext); + }; + + struct SPathRenderContext; // UICRenderPathRenderContext.h + + class IPathManager : public IPathManagerCore + { + public: + // The path segments are next expected to change after this call; changes will be ignored. + virtual bool PrepareForRender(const SPath &inPath) = 0; + + virtual void RenderDepthPrepass(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) = 0; + + virtual void RenderShadowMapPass(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) = 0; + + virtual void RenderCubeFaceShadowPass(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) = 0; + + virtual void RenderPath(SPathRenderContext &inRenderContext, + SLayerGlobalRenderProperties inRenderProperties, + TShaderFeatureSet inFeatureSet) = 0; + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPathMath.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPathMath.h new file mode 100644 index 00000000..e9eb2220 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPathMath.h @@ -0,0 +1,713 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_RENDER_PATH_MATH_H +#define QT3DS_RENDER_PATH_MATH_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +namespace qt3ds { +namespace render { +namespace path { +// Solve quadratic equation in with a templated real number system. +template + +int quadratic(REAL b, REAL c, REAL rts[2]) +{ + int nquad; + REAL dis; + REAL rtdis; + + dis = b * b - 4 * c; + rts[0] = 0; + rts[1] = 0; + if (b == 0) { + if (c == 0) { + nquad = 2; + } else { + if (c < 0) { + nquad = 2; + rts[0] = sqrt(-c); + rts[1] = -rts[0]; + } else { + nquad = 0; + } + } + } else if (c == 0) { + nquad = 2; + rts[0] = -b; + } else if (dis >= 0) { + nquad = 2; + rtdis = sqrt(dis); + if (b > 0) + rts[0] = (-b - rtdis) * (1 / REAL(2)); + else + rts[0] = (-b + rtdis) * (1 / REAL(2)); + if (rts[0] == 0) + rts[1] = -b; + else + rts[1] = c / rts[0]; + } else { + nquad = 0; + } + + return (nquad); +} /* quadratic */ + +float interest_range[2] = {0, 1}; + +void cubicInflectionPoint(const QT3DSVec2 cp[4], nvvector &key_point) +{ + // Convert control points to cubic monomial polynomial coefficients + const QT3DSVec2 A = cp[3] - cp[0] + (cp[1] - cp[2]) * 3.0; + const QT3DSVec2 B = (cp[0] - cp[1] * 2.0 + cp[2]) * 3.0, C = (cp[1] - cp[0]) * 3.0; + const QT3DSVec2 D = cp[0]; + + double a = 3 * (B.x * A.y - A.x * B.y); + double b = 3 * (C.x * A.y - C.y * A.x); + double c = C.x * B.y - C.y * B.x; + + double roots[2]; + int solutions; + // Is the quadratic really a degenerate line? + if (a == 0) { + // Is the line really a degenerate point? + if (b == 0) { + solutions = 0; + } else { + solutions = 1; + roots[0] = c / b; + } + } else { + solutions = quadratic(b / a, c / a, roots); + } + for (int i = 0; i < solutions; i++) { + QT3DSF32 t = static_cast(roots[i]); + + QT3DSVec2 p = ((A * t + B) * t + C) * t + D; + if (t >= interest_range[0] && t <= interest_range[1]) + key_point.push_back(t); + // else; Outside range of interest, ignore. + } +} + +typedef enum { + CT_POINT, + CT_LINE, + CT_QUADRATIC, + CT_CUSP, + CT_LOOP, + CT_SERPENTINE +} CurveType; + +static inline bool isZero(double v) +{ +#if 0 + const double eps = 6e-008; + + if (fabs(v) < eps) + return true; + else + return false; +#else + return v == 0.0; +#endif +} + +inline QT3DSVec3 crossv1(const QT3DSVec2 &a, const QT3DSVec2 &b) +{ + return QT3DSVec3(a[1] - b[1], b[0] - a[0], a[0] * b[1] - a[1] * b[0]); +} + +inline bool sameVertex(const QT3DSVec2 &a, const QT3DSVec2 &b) +{ + return (a.x == b.x && a.y == b.y); +} + +inline bool sameVertex(const QT3DSVec3 &a, const QT3DSVec3 &b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z); +} + +// This function "normalizes" the input vector so the larger of its components +// is in the range [512,1024]. Exploit integer math on the exponent bits to +// do this without expensive DP exponentiation. +inline void scaleTo512To1024(QT3DSVec2 &d, int e) +{ + union { + QT3DSU64 u64; + double f64; + } x; + int ie = 10 - (int)e + 1023; + QT3DS_ASSERT(ie > 0); + x.u64 = ((QT3DSU64)ie) << 52; + d *= static_cast(x.f64); +} + +inline double fastfrexp(double d, int *exponent) +{ + union { + QT3DSU64 u64; + double f64; + } x; + x.f64 = d; + *exponent = (((int)(x.u64 >> 52)) & 0x7ff) - 0x3ff; + x.u64 &= (1ULL << 63) - (1ULL << 52); + x.u64 |= (0x3ffULL << 52); + return x.f64; +} + +QT3DSVec3 CreateVec3(QT3DSVec2 xy, float z) +{ + return QT3DSVec3(xy.x, xy.y, z); +} + +QT3DSVec2 GetXY(const QT3DSVec3 &data) +{ + return QT3DSVec2(data.x, data.y); +} + +CurveType cubicDoublePoint(const QT3DSVec2 points[4], nvvector &key_point) +{ +#if 0 + const QT3DSVec2 AA = points[3] - points[0] + (points[1] - points[2]) * 3.0; + const QT3DSVec3 BB = (points[0] - points[1] * 2.0 + points[2]) * 3.0; + const QT3DSVec3 CC = (points[1] - points[0]) * 3.0, DD = points[0]; +#endif + + // Assume control points of the cubic curve are A, B, C, and D. + const QT3DSVec3 A = CreateVec3(points[0], 1); + const QT3DSVec3 B = CreateVec3(points[1], 1); + const QT3DSVec3 C = CreateVec3(points[2], 1); + const QT3DSVec3 D = CreateVec3(points[3], 1); + + // Compute the discriminant of the roots of + // H(s,t) = -36*(d1^2*s^2 - d1*d2*s*t + (d2^2 - d1*d3)*t^2) + // where H is the Hessian (the square matrix of second-order + // partial derivatives of a function) of I(s,t) + // where I(s,t) determine the inflection points of the cubic + // Bezier curve C(s,t). + // + // d1, d2, and d3 functions of the determinants constructed + // from the cubic control points. + // + // Recall dot(a,cross(b,c)) is determinant of a 3x3 matrix + // with a, b, c the rows of the matrix. + const QT3DSVec3 DC = crossv1(GetXY(D), GetXY(C)); + const QT3DSVec3 AD = crossv1(GetXY(A), GetXY(D)); + const QT3DSVec3 BA = crossv1(GetXY(B), GetXY(A)); + + const double a1 = A.dot(DC); + const double a2 = B.dot(AD); + const double a3 = C.dot(BA); + const double d1 = a1 - 2 * a2 + 3 * a3; + const double d2 = -a2 + 3 * a3; + const double d3 = 3 * a3; + const double discriminant = (3 * d2 * d2 - 4 * d1 * d3); + + // The sign of the discriminant of I classifies the curbic curve + // C into one of 6 classifications: + // 1) discriminant>0 ==> serpentine + // 2) discriminant=0 ==> cusp + // 3) discriminant<0 ==> loop + + // If the discriminant or d1 are almost but not exactly zero, the + // result is really noisy unacceptable (k,l,m) interpolation. + // If it looks almost like a quadratic or linear case, treat it that way. + if (isZero(discriminant) && isZero(d1)) { + // Cusp case + + if (isZero(d2)) { + // degenerate cases (points, lines, quadratics)... + if (isZero(d3)) { + if (sameVertex(A, B) && sameVertex(A, C) && sameVertex(A, D)) + return CT_POINT; + else + return CT_LINE; + } else { + return CT_QUADRATIC; + } + } else { + return CT_CUSP; + } + } else if (discriminant < 0) { + // Loop case + + const QT3DSF32 t = static_cast(d2 + sqrt(-discriminant)); + QT3DSVec2 d = QT3DSVec2(t, static_cast(2 * d1)); + QT3DSVec2 e = QT3DSVec2(static_cast(2 * (d2 * d2 - d1 * d3)), + static_cast(d1 * t)); + + // There is the situation where r2=c/t results in division by zero, but + // in this case, the two roots represent a double root at zero so + // subsitute l for (the otherwise NaN) m in this case. + // + // This situation can occur when the 1st and 2nd (or 3rd and 4th?) + // control point of a cubic Bezier path SubPath are identical. + if (e.x == 0 && e.y == 0) + e = d; + + // d, e, or both could be very large values. To mitigate the risk of + // floating-point overflow in subsequent calculations + // scale both vectors to be in the range [768,1024] since their relative + // scale of their x & y components is irrelevant. + + // Be careful to divide by a power-of-two to disturb mantissa bits. + + double d_max_mag = NVMax(fabs(d.x), fabs(d.y)); + int exponent; + fastfrexp(d_max_mag, &exponent); + scaleTo512To1024(d, exponent); + + double e_max_mag = NVMax(fabs(e.x), fabs(e.y)); + fastfrexp(e_max_mag, &exponent); + scaleTo512To1024(e, exponent); + + const QT3DSVec2 roots = QT3DSVec2(d.x / d.y, e.x / e.y); + + double tt; +#if 0 + tt = roots[0]; + if (tt >= interest_range[0] && tt <= interest_range[1]) + // key_point.push_back(tt); + tt = roots[1]; + if (tt >= interest_range[0] && tt <= interest_range[1]) + // key_point.push_back(tt); +#endif + tt = (roots[0] + roots[1]) / 2; + if (tt >= interest_range[0] && tt <= interest_range[1]) + key_point.push_back(static_cast(tt)); + + return CT_LOOP; + } else { + QT3DS_ASSERT(discriminant >= 0); + cubicInflectionPoint(points, key_point); + if (discriminant > 0) { + // Serpentine case + return CT_SERPENTINE; + } else { + // Cusp with inflection at infinity (treat like serpentine) + return CT_CUSP; + } + } +} + +QT3DSVec4 CreateVec4(QT3DSVec2 p1, QT3DSVec2 p2) +{ + return QT3DSVec4(p1.x, p1.y, p2.x, p2.y); +} + +QT3DSVec2 lerp(QT3DSVec2 p1, QT3DSVec2 p2, QT3DSF32 distance) +{ + return p1 + (p2 - p1) * distance; +} + +QT3DSF32 lerp(QT3DSF32 p1, QT3DSF32 p2, QT3DSF32 distance) +{ + return p1 + (p2 - p1) * distance; +} + +// Using first derivative to get tangent. +// If this equation does not make immediate sense consider that it is the first derivative +// of the de Casteljau bezier expansion, not the polynomial expansion. +float TangentAt(float inT, float p1, float c1, float c2, float p2) +{ + float a = c1 - p1; + float b = c2 - c1 - a; + float c = p2 - c2 - a - (2.0f * b); + float retval = 3.0f * (a + (2.0f * b * inT) + (c * inT * inT)); + return retval; +} + +QT3DSVec2 midpoint(QT3DSVec2 p1, QT3DSVec2 p2) +{ + return lerp(p1, p2, .5f); +} + +QT3DSF32 LineLength(QT3DSVec2 inStart, QT3DSVec2 inStop) +{ + return (inStop - inStart).magnitude(); +} + +struct SCubicBezierCurve +{ + QT3DSVec2 m_Points[4]; + SCubicBezierCurve(QT3DSVec2 a1, QT3DSVec2 c1, QT3DSVec2 c2, QT3DSVec2 a2) + { + m_Points[0] = a1; + m_Points[1] = c1; + m_Points[2] = c2; + m_Points[3] = a2; + } + + // Normal is of course orthogonal to the tangent. + QT3DSVec2 NormalAt(float inT) const + { + QT3DSVec2 tangent = QT3DSVec2( + TangentAt(inT, m_Points[0].x, m_Points[1].x, m_Points[2].x, m_Points[3].x), + TangentAt(inT, m_Points[0].y, m_Points[1].y, m_Points[2].y, m_Points[3].y)); + + QT3DSVec2 result(tangent.y, -tangent.x); + result.normalize(); + return result; + } + + eastl::pair SplitCubicBezierCurve(float inT) + { + // compute point on curve based on inT + // using de Casteljau algorithm + QT3DSVec2 p12 = lerp(m_Points[0], m_Points[1], inT); + QT3DSVec2 p23 = lerp(m_Points[1], m_Points[2], inT); + QT3DSVec2 p34 = lerp(m_Points[2], m_Points[3], inT); + QT3DSVec2 p123 = lerp(p12, p23, inT); + QT3DSVec2 p234 = lerp(p23, p34, inT); + QT3DSVec2 p1234 = lerp(p123, p234, inT); + + return eastl::make_pair(SCubicBezierCurve(m_Points[0], p12, p123, p1234), + SCubicBezierCurve(p1234, p234, p34, m_Points[3])); + } +}; + +#if 0 + static QT3DSVec2 NormalToLine( QT3DSVec2 startPoint, QT3DSVec2 endPoint ) + { + QT3DSVec2 lineDxDy = endPoint - startPoint; + QT3DSVec2 result( lineDxDy.y, -lineDxDy.x ); + result.normalize(); + return result; + } +#endif + +struct SResultCubic +{ + enum Mode { + Normal = 0, + BeginTaper = 1, + EndTaper = 2, + }; + QT3DSVec2 m_P1; + QT3DSVec2 m_C1; + QT3DSVec2 m_C2; + QT3DSVec2 m_P2; + // Location in the original data where this cubic is taken from + QT3DSU32 m_EquationIndex; + QT3DSF32 m_TStart; + QT3DSF32 m_TStop; + QT3DSF32 m_Length; + QT3DSVec2 m_TaperMultiplier; // normally 1, goes to zero at very end of taper if any taper. + Mode m_Mode; + + SResultCubic(QT3DSVec2 inP1, QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inP2, + QT3DSU32 equationIndex, QT3DSF32 tStart, QT3DSF32 tStop, QT3DSF32 length) + : m_P1(inP1) + , m_C1(inC1) + , m_C2(inC2) + , m_P2(inP2) + , m_EquationIndex(equationIndex) + , m_TStart(tStart) + , m_TStop(tStop) + , m_Length(length) + , m_TaperMultiplier(1.0f, 1.0f) + , m_Mode(Normal) + { + } + // Note the vec2 items are *not* initialized in any way here. + SResultCubic() {} + QT3DSF32 GetP1Width(QT3DSF32 inPathWidth, QT3DSF32 beginTaperWidth, QT3DSF32 endTaperWidth) + { + return GetPathWidth(inPathWidth, beginTaperWidth, endTaperWidth, 0); + } + + QT3DSF32 GetP2Width(QT3DSF32 inPathWidth, QT3DSF32 beginTaperWidth, QT3DSF32 endTaperWidth) + { + return GetPathWidth(inPathWidth, beginTaperWidth, endTaperWidth, 1); + } + + QT3DSF32 GetPathWidth(QT3DSF32 inPathWidth, QT3DSF32 beginTaperWidth, QT3DSF32 endTaperWidth, + QT3DSU32 inTaperIndex) + { + QT3DSF32 retval = inPathWidth; + switch (m_Mode) { + case BeginTaper: + retval = beginTaperWidth * m_TaperMultiplier[inTaperIndex]; + break; + case EndTaper: + retval = endTaperWidth * m_TaperMultiplier[inTaperIndex]; + break; + default: + break; + } + return retval; + } +}; + +void PushLine(nvvector &ioResultVec, QT3DSVec2 inStart, QT3DSVec2 inStop, + QT3DSU32 inEquationIndex) +{ + QT3DSVec2 range = inStop - inStart; + ioResultVec.push_back(SResultCubic(inStart, inStart + range * .333f, + inStart + range * .666f, inStop, inEquationIndex, + 0.0f, 1.0f, LineLength(inStart, inStop))); +} + +struct PathDirtyFlagValues +{ + enum Enum { + SourceData = 1, + PathType = 1 << 1, + Width = 1 << 2, + BeginTaper = 1 << 3, + EndTaper = 1 << 4, + CPUError = 1 << 5, + }; +}; + +struct SPathDirtyFlags : public NVFlags +{ + typedef NVFlags TBase; + SPathDirtyFlags() {} + SPathDirtyFlags(int inFlags) + : TBase(static_cast(inFlags)) + { + } + void Clear() + { + *this = SPathDirtyFlags(); + } +}; + +struct STaperInformation +{ + QT3DSF32 m_CapOffset; + QT3DSF32 m_CapOpacity; + QT3DSF32 m_CapWidth; + + STaperInformation() + : m_CapOffset(0) + , m_CapOpacity(0) + , m_CapWidth(0) + { + } + STaperInformation(QT3DSF32 capOffset, QT3DSF32 capOpacity, QT3DSF32 capWidth) + : m_CapOffset(capOffset) + , m_CapOpacity(capOpacity) + , m_CapWidth(capWidth) + { + } + + bool operator==(const STaperInformation &inOther) const + { + return m_CapOffset == inOther.m_CapOffset && m_CapOpacity == inOther.m_CapOpacity + && m_CapWidth == inOther.m_CapWidth; + } +}; + +template +bool OptionEquals(const Option &lhs, const Option &rhs) +{ + if (lhs.hasValue() != rhs.hasValue()) + return false; + if (lhs.hasValue()) + return lhs.getValue() == rhs.getValue(); + return true; +} +void OuterAdaptiveSubdivideBezierCurve(nvvector &ioResultVec, + nvvector &keyPointVec, + SCubicBezierCurve inCurve, QT3DSF32 inLinearError, + QT3DSU32 inEquationIndex); + +void AdaptiveSubdivideBezierCurve(nvvector &ioResultVec, + SCubicBezierCurve &inCurve, QT3DSF32 inLinearError, + QT3DSU32 inEquationIndex, QT3DSF32 inTStart, QT3DSF32 inTStop); + +// Adaptively subdivide source data to produce m_PatchData. +void AdaptiveSubdivideSourceData(NVConstDataRef inSourceData, + nvvector &ioResultVec, + nvvector &keyPointVec, QT3DSF32 inLinearError) +{ + ioResultVec.clear(); + if (inSourceData.size() < 2) + return; + // Assuming no attributes in the source data. + QT3DSU32 numEquations = (inSourceData.size() - 1); + for (QT3DSU32 idx = 0, end = numEquations; idx < end; ++idx) { + const SPathAnchorPoint &beginAnchor = inSourceData[idx]; + const SPathAnchorPoint &endAnchor = inSourceData[idx + 1]; + + QT3DSVec2 anchor1(beginAnchor.m_Position); + QT3DSVec2 control1(IPathManagerCore::GetControlPointFromAngleDistance( + beginAnchor.m_Position, beginAnchor.m_OutgoingAngle, + beginAnchor.m_OutgoingDistance)); + + QT3DSVec2 control2(IPathManagerCore::GetControlPointFromAngleDistance( + endAnchor.m_Position, endAnchor.m_IncomingAngle, + endAnchor.m_IncomingDistance)); + QT3DSVec2 anchor2(endAnchor.m_Position); + + OuterAdaptiveSubdivideBezierCurve( + ioResultVec, keyPointVec, + SCubicBezierCurve(anchor1, control1, control2, anchor2), inLinearError, idx); + } +} + +// The outer subdivide function topologically analyzes the curve to ensure that +// the sign of the second derivative does not change, no inflection points. +// Once that condition is held, then we proceed with a simple adaptive subdivision algorithm +// until the curve is accurately approximated by a straight line. +void OuterAdaptiveSubdivideBezierCurve(nvvector &ioResultVec, + nvvector &keyPointVec, + SCubicBezierCurve inCurve, QT3DSF32 inLinearError, + QT3DSU32 inEquationIndex) +{ + // Step 1, find what type of curve we are dealing with and the inflection points. + keyPointVec.clear(); + CurveType theCurveType = cubicDoublePoint(inCurve.m_Points, keyPointVec); + + QT3DSF32 tStart = 0; + switch (theCurveType) { + case CT_POINT: + ioResultVec.push_back(SResultCubic(inCurve.m_Points[0], inCurve.m_Points[0], + inCurve.m_Points[0], inCurve.m_Points[0], + inEquationIndex, 0.0f, 1.0f, 0.0f)); + return; // don't allow further recursion + case CT_LINE: + PushLine(ioResultVec, inCurve.m_Points[0], inCurve.m_Points[3], inEquationIndex); + return; // don't allow further recursion + case CT_CUSP: + case CT_LOOP: + case CT_SERPENTINE: { + // Break the curve at the inflection points if there is one. If there aren't + // inflection points + // the treat as linear (degenerate case that should not happen except in limiting + // ranges of floating point accuracy) + if (!keyPointVec.empty()) { + // It is not clear that the code results in a sorted vector, + // or a vector where all values are within the range of 0-1 + if (keyPointVec.size() > 1) + eastl::sort(keyPointVec.begin(), keyPointVec.end()); + for (QT3DSU32 idx = 0, end = (QT3DSU32)keyPointVec.size(); + idx < end && keyPointVec[idx] < 1.0f; ++idx) { + // We have a list of T values I believe sorted from beginning to end, we + // will create a set of bezier curves + // Since we split the curves, tValue is relative to tSTart, not 0. + QT3DSF32 range = 1.0f - tStart; + QT3DSF32 splitPoint = keyPointVec[idx] - tStart; + QT3DSF32 tValue = splitPoint / range; + if (tValue > 0.0f) { + eastl::pair newCurves + = inCurve.SplitCubicBezierCurve(tValue); + AdaptiveSubdivideBezierCurve(ioResultVec, newCurves.first, + inLinearError, inEquationIndex, tStart, + splitPoint); + inCurve = newCurves.second; + tStart = splitPoint; + } + } + } + } + // fallthrough intentional + break; + // fallthrough intentional + case CT_QUADRATIC: + break; + } + AdaptiveSubdivideBezierCurve(ioResultVec, inCurve, inLinearError, inEquationIndex, + tStart, 1.0f); +} + +static QT3DSF32 DistanceFromPointToLine(QT3DSVec2 inLineDxDy, QT3DSVec2 lineStart, QT3DSVec2 point) +{ + QT3DSVec2 pointToLineStart = lineStart - point; + return fabs((inLineDxDy.x * pointToLineStart.y) - (inLineDxDy.y * pointToLineStart.x)); +} + +// There are two options here. The first is to just subdivide below a given error +// tolerance. +// The second is to fit a quadratic to the curve and then precisely find the length of the +// quadratic. +// Obviously we are choosing the subdivide method at this moment but I think the fitting +// method is probably more robust. +QT3DSF32 LengthOfBezierCurve(SCubicBezierCurve &inCurve) +{ + // Find distance of control points from line. Note that both control points should be + // on same side of line else we have a serpentine which should have been removed by topological + // analysis. + QT3DSVec2 lineDxDy = inCurve.m_Points[3] - inCurve.m_Points[0]; + QT3DSF32 c1Distance = DistanceFromPointToLine( + lineDxDy, inCurve.m_Points[0], inCurve.m_Points[1]); + QT3DSF32 c2Distance = DistanceFromPointToLine( + lineDxDy, inCurve.m_Points[0], inCurve.m_Points[2]); + const float lineTolerance = 100.0f; // error in world coordinates, squared. + if (c1Distance > lineTolerance || c2Distance > lineTolerance) { + eastl::pair subdivCurve + = inCurve.SplitCubicBezierCurve(.5f); + return LengthOfBezierCurve(subdivCurve.first) + + LengthOfBezierCurve(subdivCurve.second); + } else { + return LineLength(inCurve.m_Points[0], inCurve.m_Points[3]); + } +} + +// The assumption here is the the curve type is not cusp, loop, or serpentine. +// It is either linear or it is a constant curve meaning we can use very simple means to +// figure out the curvature. There is a possibility to use some math to figure out the point of +// maximum curvature, where the second derivative will have a max value. This is probably not +// necessary. +void AdaptiveSubdivideBezierCurve(nvvector &ioResultVec, + SCubicBezierCurve &inCurve, QT3DSF32 inLinearError, + QT3DSU32 inEquationIndex, QT3DSF32 inTStart, QT3DSF32 inTStop) +{ + // Find distance of control points from line. Note that both control points should be + // on same side of line else we have a serpentine which should have been removed by topological + // analysis. + QT3DSVec2 lineDxDy = inCurve.m_Points[3] - inCurve.m_Points[0]; + QT3DSF32 c1Distance = DistanceFromPointToLine(lineDxDy, inCurve.m_Points[0], + inCurve.m_Points[1]); + QT3DSF32 c2Distance = DistanceFromPointToLine(lineDxDy, inCurve.m_Points[0], + inCurve.m_Points[2]); + const float lineTolerance = inLinearError * inLinearError; // error in world coordinates + if (c1Distance > lineTolerance || c2Distance > lineTolerance) { + eastl::pair subdivCurve + = inCurve.SplitCubicBezierCurve(.5f); + QT3DSF32 halfway = lerp(inTStart, inTStop, .5f); + AdaptiveSubdivideBezierCurve(ioResultVec, subdivCurve.first, inLinearError, + inEquationIndex, inTStart, halfway); + AdaptiveSubdivideBezierCurve(ioResultVec, subdivCurve.second, inLinearError, + inEquationIndex, halfway, inTStop); + } else { + ioResultVec.push_back(SResultCubic(inCurve.m_Points[0], inCurve.m_Points[1], + inCurve.m_Points[2], inCurve.m_Points[3], + inEquationIndex, inTStart, inTStop, + LengthOfBezierCurve(inCurve))); + } +} +} +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPathRenderContext.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPathRenderContext.h new file mode 100644 index 00000000..deeea281 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPathRenderContext.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_RENDER_CONTEXT_H +#define QT3DS_RENDER_PATH_RENDER_CONTEXT_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderShaderCache.h" //TShaderFeatureSet +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSBounds3.h" +#include "Qt3DSRenderShaderKeys.h" +#include "Qt3DSRenderableImage.h" + +namespace qt3ds { +namespace render { + + struct SPathRenderContext + { + // The lights and camera will not change per layer, + // so that information can be set once for all the shaders. + NVConstDataRef m_Lights; + const SCamera &m_Camera; + + // Per-object information. + const SPath &m_Path; + const QT3DSMat44 &m_ModelViewProjection; + const QT3DSMat44 &m_ModelMatrix; ///< model to world transformation + const QT3DSMat33 &m_NormalMatrix; + + QT3DSF32 m_Opacity; + const SGraphObject &m_Material; + SShaderDefaultMaterialKey m_MaterialKey; + SRenderableImage *m_FirstImage; + QT3DSVec2 m_CameraVec; + + bool m_EnableWireframe; + bool m_HasTransparency; + bool m_IsStroke; + + SPathRenderContext(NVConstDataRef lights, const SCamera &cam, const SPath &p, + const QT3DSMat44 &mvp, const QT3DSMat44 &world, const QT3DSMat33 &nm, + QT3DSF32 inOpacity, const SGraphObject &inMaterial, + SShaderDefaultMaterialKey inMaterialKey, SRenderableImage *inFirstImage, + bool inWireframe, QT3DSVec2 inCameraVec, bool inHasTransparency, + bool inIsStroke) + + : m_Lights(lights) + , m_Camera(cam) + , m_Path(p) + , m_ModelViewProjection(mvp) + , m_ModelMatrix(world) + , m_NormalMatrix(nm) + , m_Opacity(inOpacity) + , m_Material(inMaterial) + , m_MaterialKey(inMaterialKey) + , m_FirstImage(inFirstImage) + , m_CameraVec(inCameraVec) + , m_EnableWireframe(inWireframe) + , m_HasTransparency(inHasTransparency) + , m_IsStroke(inIsStroke) + { + } + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.cpp new file mode 100644 index 00000000..43f7c0b4 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.cpp @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderPixelGraphicsRenderer.h" +#include "Qt3DSRenderPixelGraphicsTypes.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderShaderCodeGenerator.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderShaderCache.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +namespace { + +struct SPGRectShader +{ + NVScopedRefCounted m_RectShader; + NVRenderShaderConstantBase *mvp; + NVRenderShaderConstantBase *rectColor; + NVRenderShaderConstantBase *leftright; + NVRenderShaderConstantBase *bottomtop; + + SPGRectShader() + : mvp(NULL) + , rectColor(NULL) + , leftright(NULL) + , bottomtop(NULL) + { + } + void SetShader(NVRenderShaderProgram *program) + { + m_RectShader = program; + if (program) { + mvp = program->GetShaderConstant("model_view_projection"); + rectColor = program->GetShaderConstant("rect_color"); + leftright = program->GetShaderConstant("leftright[0]"); + bottomtop = program->GetShaderConstant("bottomtop[0]"); + } + } + + void Apply(QT3DSMat44 &inVP, const SPGRect &inObject) + { + if (mvp) + m_RectShader->SetConstantValue(mvp, toConstDataRef(inVP), 1); + if (rectColor) + m_RectShader->SetConstantValue(rectColor, inObject.m_FillColor, 1); + if (leftright) { + QT3DSF32 theData[] = { inObject.m_Left, inObject.m_Right }; + m_RectShader->SetConstantValue(leftright, *theData, 2); + } + if (bottomtop) { + QT3DSF32 theData[] = { inObject.m_Bottom, inObject.m_Top }; + m_RectShader->SetConstantValue(bottomtop, *theData, 2); + } + } + + operator bool() { return m_RectShader.mPtr != NULL; } +}; + +struct SPGRenderer : public IPixelGraphicsRenderer +{ + IQt3DSRenderContext &m_RenderContext; + IStringTable &m_StringTable; + NVScopedRefCounted m_QuadVertexBuffer; + NVScopedRefCounted m_QuadIndexBuffer; + NVScopedRefCounted m_QuadInputAssembler; + NVScopedRefCounted m_QuadAttribLayout; + SShaderVertexCodeGenerator m_VertexGenerator; + SShaderFragmentCodeGenerator m_FragmentGenerator; + SPGRectShader m_RectShader; + QT3DSI32 mRefCount; + + SPGRenderer(IQt3DSRenderContext &ctx, IStringTable &strt) + : m_RenderContext(ctx) + , m_StringTable(strt) + , m_VertexGenerator(m_StringTable, ctx.GetAllocator(), + m_RenderContext.GetRenderContext().GetRenderContextType()) + , m_FragmentGenerator(m_VertexGenerator, ctx.GetAllocator(), + m_RenderContext.GetRenderContext().GetRenderContextType()) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) + void GetRectShaderProgram() + { + if (!m_RectShader) { + m_VertexGenerator.Begin(); + m_FragmentGenerator.Begin(); + m_VertexGenerator.AddAttribute("attr_pos", "vec2"); + m_VertexGenerator.AddUniform("model_view_projection", "mat4"); + m_VertexGenerator.AddUniform("leftright[2]", "float"); + m_VertexGenerator.AddUniform("bottomtop[2]", "float"); + m_FragmentGenerator.AddVarying("rect_uvs", "vec2"); + m_FragmentGenerator.AddUniform("rect_color", "vec4"); + m_VertexGenerator << "void main() {" << Endl + << "\tgl_Position = model_view_projection * vec4( " + "leftright[int(attr_pos.x)], bottomtop[int(attr_pos.y)], 0.0, 1.0 " + ");" + << Endl << "\trect_uvs = attr_pos;" << Endl << "}" << Endl; + + m_FragmentGenerator << "void main() {" << Endl << "\tfragOutput = rect_color;" << Endl + << "}" << Endl; + + m_VertexGenerator.BuildShaderSource(); + m_FragmentGenerator.BuildShaderSource(); + + m_RectShader.SetShader(m_RenderContext.GetShaderCache().CompileProgram( + m_StringTable.RegisterStr("PixelRectShader"), + m_VertexGenerator.m_FinalShaderBuilder.c_str(), + m_FragmentGenerator.m_FinalShaderBuilder.c_str(), NULL // no tess control shader + , + NULL // no tess eval shader + , + NULL // no geometry shader + , + SShaderCacheProgramFlags(), ShaderCacheNoFeatures())); + } + } + void GenerateXYQuad() + { + NVRenderContext &theRenderContext(m_RenderContext.GetRenderContext()); + + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2), + }; + + QT3DSVec2 pos[] = { QT3DSVec2(0, 0), QT3DSVec2(0, 1), QT3DSVec2(1, 1), QT3DSVec2(1, 0) }; + + if (m_QuadVertexBuffer == NULL) { + size_t bufSize = sizeof(pos); + m_QuadVertexBuffer = theRenderContext.CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, bufSize, 2 * sizeof(QT3DSF32), + toU8DataRef(pos, 4)); + } + + if (m_QuadIndexBuffer == NULL) { + QT3DSU8 indexData[] = { + 0, 1, 2, 0, 2, 3, + }; + m_QuadIndexBuffer = theRenderContext.CreateIndexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, + qt3ds::render::NVRenderComponentTypes::QT3DSU8, sizeof(indexData), + toU8DataRef(indexData, sizeof(indexData))); + } + + if (m_QuadAttribLayout == NULL) { + // create our attribute layout + m_QuadAttribLayout = + theRenderContext.CreateAttributeLayout(toConstDataRef(theEntries, 1)); + } + + if (m_QuadInputAssembler == NULL) { + + // create input assembler object + QT3DSU32 strides = m_QuadVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_QuadInputAssembler = theRenderContext.CreateInputAssembler( + m_QuadAttribLayout, toConstDataRef(&m_QuadVertexBuffer.mPtr, 1), m_QuadIndexBuffer, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + } + + void RenderPixelObject(QT3DSMat44 &inProjection, const SPGRect &inObject) + { + GenerateXYQuad(); + GetRectShaderProgram(); + if (m_RectShader) { + m_RenderContext.GetRenderContext().SetActiveShader(m_RectShader.m_RectShader.mPtr); + m_RectShader.Apply(inProjection, inObject); + + m_RenderContext.GetRenderContext().SetInputAssembler(m_QuadInputAssembler.mPtr); + m_RenderContext.GetRenderContext().Draw(NVRenderDrawMode::Triangles, + m_QuadInputAssembler->GetIndexCount(), 0); + } + } + + void RenderPixelObject(QT3DSMat44 &inProjection, const SPGVertLine &inObject) + { + // lines are really just rects, but they grow in width in a sort of odd way. + // specifically, they grow the increasing coordinate on even boundaries and centered on odd + // boundaries. + SPGRect theRect; + theRect.m_Top = inObject.m_Top; + theRect.m_Bottom = inObject.m_Bottom; + theRect.m_FillColor = inObject.m_LineColor; + theRect.m_Left = inObject.m_X; + theRect.m_Right = theRect.m_Left + 1.0f; + RenderPixelObject(inProjection, theRect); + } + + void RenderPixelObject(QT3DSMat44 &inProjection, const SPGHorzLine &inObject) + { + SPGRect theRect; + theRect.m_Right = inObject.m_Right; + theRect.m_Left = inObject.m_Left; + theRect.m_FillColor = inObject.m_LineColor; + theRect.m_Bottom = inObject.m_Y; + theRect.m_Top = theRect.m_Bottom + 1.0f; + RenderPixelObject(inProjection, theRect); + } + + void Render(NVConstDataRef inObjects) override + { + NVRenderContext &theRenderContext(m_RenderContext.GetRenderContext()); + theRenderContext.PushPropertySet(); + // Setup an orthographic camera that places the center at the + // lower left of the viewport. + NVRenderRectF theViewport = theRenderContext.GetViewport(); + // With no projection at all, we are going to get a square view box + // with boundaries from -1,1 in all dimensions. This is close to what we want. + theRenderContext.SetDepthTestEnabled(false); + theRenderContext.SetDepthWriteEnabled(false); + theRenderContext.SetScissorTestEnabled(false); + theRenderContext.SetBlendingEnabled(true); + theRenderContext.SetCullingEnabled(false); + // Colors are expected to be non-premultiplied, so we premultiply alpha into them at this + // point. + theRenderContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); + theRenderContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); + + SCamera theCamera; + theCamera.m_Position.z = -5; + theCamera.m_ClipNear = 1.0f; + theCamera.m_ClipFar = 10.0f; + theCamera.m_Flags.SetOrthographic(true); + // Setup camera projection + theCamera.ComputeFrustumOrtho(theViewport, + QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); + // Translate such that 0, 0 is lower left of screen. + NVRenderRectF theIdealViewport = theViewport; + theIdealViewport.m_X -= theViewport.m_Width / 2.0f; + theIdealViewport.m_Y -= theViewport.m_Height / 2.0f; + QT3DSMat44 theProjectionMatrix = NVRenderContext::ApplyVirtualViewportToProjectionMatrix( + theCamera.m_Projection, theViewport, theIdealViewport); + theCamera.m_Projection = theProjectionMatrix; + // Explicitly call the node's calculate global variables so that the camera doesn't attempt + // to change the projection we setup. + static_cast(theCamera).CalculateGlobalVariables(); + QT3DSMat44 theVPMatrix(QT3DSMat44::createIdentity()); + theCamera.CalculateViewProjectionMatrix(theVPMatrix); + + QT3DSVec4 theTest(60, 200, 0, 1); + QT3DSVec4 theResult = theVPMatrix.transform(theTest); + + (void)theTest; + (void)theResult; + + for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { + const SPGGraphObject &theObject(*inObjects[idx]); + + switch (theObject.m_Type) { + case SGTypes::VertLine: + RenderPixelObject(theVPMatrix, static_cast(theObject)); + break; + case SGTypes::HorzLine: + RenderPixelObject(theVPMatrix, static_cast(theObject)); + break; + case SGTypes::Rect: + RenderPixelObject(theVPMatrix, static_cast(theObject)); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + theRenderContext.PopPropertySet(false); + } +}; +} + +IPixelGraphicsRenderer &IPixelGraphicsRenderer::CreateRenderer(IQt3DSRenderContext &ctx, + IStringTable &strt) +{ + return *QT3DS_NEW(ctx.GetAllocator(), SPGRenderer)(ctx, strt); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.h new file mode 100644 index 00000000..b37cb26b --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsRenderer.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PIXEL_GRAPHICS_RENDERER_H +#define QT3DS_RENDER_PIXEL_GRAPHICS_RENDERER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + // Pixel graphics are graphics described in pixels. + // Colors are expected to be non-premultiplied, we use ROP + // hardware to do the alpha multiply into the color. + class IPixelGraphicsRenderer : public NVRefCounted + { + public: + // Renders the node to the current viewport. + virtual void Render(NVConstDataRef inObjects) = 0; + + static IPixelGraphicsRenderer &CreateRenderer(IQt3DSRenderContext &ctx, IStringTable &strt); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.cpp new file mode 100644 index 00000000..fe32437f --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderPixelGraphicsTypes.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +SPGGraphObject::SPGGraphObject(SGTypes::Enum inType) + : m_Type(inType) +{ +} + +SPGRect::SPGRect() + : SPGGraphObject(SGTypes::Rect) + , m_Left(0) + , m_Top(0) + , m_Right(0) + , m_Bottom(0) + , m_FillColor(0, 0, 0, 0) +{ +} + +SPGVertLine::SPGVertLine() + : SPGGraphObject(SGTypes::VertLine) + , m_X(0) + , m_Top(0) + , m_Bottom(0) + , m_LineColor(0, 0, 0, 0) +{ +} + +SPGHorzLine::SPGHorzLine() + : SPGGraphObject(SGTypes::HorzLine) + , m_Y(0) + , m_Left(0) + , m_Right(0) + , m_LineColor(0, 0, 0, 0) +{ +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.h new file mode 100644 index 00000000..2c154c18 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPixelGraphicsTypes.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PIXEL_GRAPHICS_TYPES_H +#define QT3DS_RENDER_PIXEL_GRAPHICS_TYPES_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DSOption.h" + +namespace qt3ds { +namespace render { + + // Vector graphics with no scaling are pixel aligned with 0,0 being the bottom,left of the + // screen + // with coordinates increasing to the right and up. This is opposite most window systems but it + // preserves the normal openGL assumptions about viewports and positive Y going up in general. + struct SGTypes + { + enum Enum { + UnknownVGType = 0, + Layer, + Rect, + VertLine, + HorzLine, + }; + }; + + struct SPGGraphObject + { + SGTypes::Enum m_Type; + SPGGraphObject(SGTypes::Enum inType); + }; + + struct SPGRect : public SPGGraphObject + { + QT3DSF32 m_Left; + QT3DSF32 m_Top; + QT3DSF32 m_Right; + QT3DSF32 m_Bottom; + + QT3DSVec4 m_FillColor; + + SPGRect(); + }; + + struct SPGVertLine : public SPGGraphObject + { + QT3DSF32 m_X; + QT3DSF32 m_Top; + QT3DSF32 m_Bottom; + QT3DSVec4 m_LineColor; + void SetPosition(QT3DSF32 val) { m_X = val; } + void SetStart(QT3DSF32 val) { m_Bottom = val; } + void SetStop(QT3DSF32 val) { m_Top = val; } + + SPGVertLine(); + }; + + struct SPGHorzLine : public SPGGraphObject + { + QT3DSF32 m_Y; + QT3DSF32 m_Left; + QT3DSF32 m_Right; + QT3DSVec4 m_LineColor; + void SetPosition(QT3DSF32 val) { m_Y = val; } + void SetStart(QT3DSF32 val) { m_Left = val; } + void SetStop(QT3DSF32 val) { m_Right = val; } + + SPGHorzLine(); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.cpp new file mode 100644 index 00000000..046f1b1b --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.cpp @@ -0,0 +1,936 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderPlugin.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/SerializationTypes.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSSystem.h" +#include "foundation/FileTools.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderString.h" +#include "Qt3DSRenderPluginPropertyValue.h" +#include "Qt3DSRenderInputStreamFactory.h" + +#if defined(QT3DS_WINDOWS) +#include "windows/DynamicLibLoader.h" +#elif defined(QT3DS_ANDROID) +#include "android/DynamicLibLoader.h" +#elif defined(QT3DS_LINUX) +#include "linux/DynamicLibLoader.h" +#elif defined(QT3DS_APPLE) +#include "macos/DynamicLibLoader.h" +#elif defined(QT3DS_QNX) +#include "qnx/DynamicLibLoader.h" +#else +#error "Must define an operating system type (QT3DS_WINDOWS, QT3DS_ANDROID, QT3DS_LINUX, QT3DS_APPLE, QT3DS_QNX)" +#endif + +using namespace qt3ds::render; + +namespace { +// Legacy definitions... +// API version 1 definitions +typedef struct _RenderPluginSurfaceDescriptionV1 +{ + long m_Width; + long m_Height; + enum QT3DSRenderPluginDepthTypes m_DepthBuffer; + enum QT3DSRenderPluginTextureTypes m_ColorBuffer; + TBool m_HasStencilBuffer; +} TRenderPluginSurfaceDescriptionV1; + +typedef TNeedsRenderResult (*TNeedsRenderFunctionV1)(TRenderPluginClassPtr cls, + TRenderPluginInstancePtr instance, + TRenderPluginSurfaceDescriptionV1 surface, + TVec2 presScaleFactor); + +typedef void (*TRenderFunctionV1)(TRenderPluginClassPtr cls, TRenderPluginInstancePtr instance, + TRenderPluginSurfaceDescriptionV1 surface, + TVec2 presScaleFactor, + QT3DSRenderPluginColorClearState inClearColorBuffer); + +// End API version 1 definitions + +TRenderPluginSurfaceDescription ToCInterface(const SOffscreenRendererEnvironment &env) +{ + TRenderPluginSurfaceDescription retval; + retval.m_Width = (long)env.m_Width; + retval.m_Height = (long)env.m_Height; + retval.m_ColorBuffer = static_cast(env.m_Format); + retval.m_DepthBuffer = static_cast(env.m_Depth); + retval.m_HasStencilBuffer = env.m_Stencil ? TTRUE : TFALSE; + retval.m_MSAALevel = QT3DSRenderPluginMSAALevelNoMSAA; + // note no supersampling AA support for plugins + // we fall back to 4xMSAA + switch (env.m_MSAAMode) { + case AAModeValues::X2: + retval.m_MSAALevel = QT3DSRenderPluginMSAALevelTwo; + break; + case AAModeValues::SSAA: + case AAModeValues::X4: + retval.m_MSAALevel = QT3DSRenderPluginMSAALevelFour; + break; + case AAModeValues::X8: + retval.m_MSAALevel = QT3DSRenderPluginMSAALevelEight; + break; + default: + QT3DS_ASSERT(false); + // fallthrough intentional. + case AAModeValues::NoAA: + break; + }; + return retval; +} + +TRenderPluginSurfaceDescriptionV1 ToCInterfaceV1(const SOffscreenRendererEnvironment &env) +{ + TRenderPluginSurfaceDescriptionV1 retval; + retval.m_Width = (long)env.m_Width; + retval.m_Height = (long)env.m_Height; + retval.m_ColorBuffer = static_cast(env.m_Format); + retval.m_DepthBuffer = static_cast(env.m_Depth); + retval.m_HasStencilBuffer = env.m_Stencil ? TTRUE : TFALSE; + return retval; +} + +TVec2 ToCInterface(const QT3DSVec2 &item) +{ + TVec2 retval = { item.x, item.y }; + return retval; +} + +QT3DSRenderPluginColorClearState ToCInterface(SScene::RenderClearCommand inClearCommand) +{ + switch (inClearCommand) { + case SScene::DoNotClear: + return QT3DSRenderPluginColorClearStateDoNotClear; + case SScene::AlwaysClear: + return QT3DSRenderPluginColorClearStateAlwaysClear; + default: + QT3DS_ASSERT(false); // fallthrough intentional + case SScene::ClearIsOptional: + return QT3DSRenderPluginColorClearStateClearIsOptional; + }; +} + +class SRenderPluginPropertyData +{ + SRenderPluginPropertyValue m_Value; + bool m_Dirty; + +public: + SRenderPluginPropertyData() + : m_Dirty(false) + { + } + SRenderPluginPropertyData(const SRenderPluginPropertyData &other) + : m_Value(other.m_Value) + , m_Dirty(other.m_Dirty) + { + } + SRenderPluginPropertyData &operator=(const SRenderPluginPropertyData &other) + { + m_Value = other.m_Value; + m_Dirty = other.m_Dirty; + return *this; + } + + bool IsDirty() const + { + return m_Value.getType() != RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue + && m_Dirty; + } + void SetValue(const SRenderPluginPropertyValue &value) + { + m_Value = value; + m_Dirty = true; + } + + TRenderPluginPropertyUpdate ClearDirty(CRegisteredString inPropName) + { + m_Dirty = false; + TRenderPluginPropertyUpdate retval; + memset(&retval, 0, sizeof(TRenderPluginPropertyUpdate)); + retval.m_PropName = inPropName.c_str(); + switch (m_Value.getType()) { + case RenderPluginPropertyValueTypes::Long: { + retval.m_PropertyType = QT3DSRenderPluginPropertyTypeLong; + long temp = (long)m_Value.getData(); + retval.m_PropertyValue = *reinterpret_cast(&temp); + } break; + case RenderPluginPropertyValueTypes::Float: { + retval.m_PropertyType = QT3DSRenderPluginPropertyTypeFloat; + float temp = m_Value.getData(); + retval.m_PropertyValue = *reinterpret_cast(&temp); + } break; + case RenderPluginPropertyValueTypes::Boolean: { + retval.m_PropertyType = QT3DSRenderPluginPropertyTypeLong; + long temp = m_Value.getData() ? TTRUE : TFALSE; + retval.m_PropertyValue = *reinterpret_cast(&temp); + } break; + case RenderPluginPropertyValueTypes::String: { + retval.m_PropertyType = QT3DSRenderPluginPropertyTypeCharPtr; + const char *temp = m_Value.getData().c_str(); + retval.m_PropertyValue = reinterpret_cast(const_cast(temp)); + } break; + default: + QT3DS_ASSERT(false); + } + return retval; + } +}; + +typedef nvvector TPropertyValueList; + +struct IInternalPluginClass : public IRenderPluginClass +{ + virtual void PushUpdates(TRenderPluginInstancePtr instance, + TPropertyValueList &propertyValues) = 0; + virtual void Update(NVConstDataRef updateBuffer, + TPropertyValueList &propertyValues) = 0; + virtual QT3DSI32 GetAPIVersion() = 0; +}; + +static NVRenderTextureFormats::Enum ToTextureFormat(QT3DSRenderPluginTextureTypes inTextureType) +{ + switch (inTextureType) { + default: + case QT3DSRenderPluginTextureTypeRGBA8: + return NVRenderTextureFormats::RGBA8; + case QT3DSRenderPluginTextureTypeRGB8: + return NVRenderTextureFormats::RGB8; + case QT3DSRenderPluginTextureTypeRGB565: + return NVRenderTextureFormats::RGB565; + case QT3DSRenderPluginTextureTypeRGBA5551: + return NVRenderTextureFormats::RGBA5551; + } +} + +static OffscreenRendererDepthValues::Enum ToDepthValue(QT3DSRenderPluginDepthTypes inType) +{ + switch (inType) { + default: + case QT3DSRenderPluginDepthTypeDepth16: + return OffscreenRendererDepthValues::Depth16; + case QT3DSRenderPluginDepthTypeDepth24: + return OffscreenRendererDepthValues::Depth24; + case QT3DSRenderPluginDepthTypeDepth32: + return OffscreenRendererDepthValues::Depth32; + } +} + +static AAModeValues::Enum ToAAMode(QT3DSRenderPluginMSAALevel inMode) +{ + switch (inMode) { + case QT3DSRenderPluginMSAALevelTwo: + return AAModeValues::X2; + case QT3DSRenderPluginMSAALevelFour: + return AAModeValues::X4; + case QT3DSRenderPluginMSAALevelEight: + return AAModeValues::X8; + default: + QT3DS_ASSERT(false); // fallthrough intentional + case QT3DSRenderPluginMSAALevelNoMSAA: + return AAModeValues::NoAA; + } +} + +struct InstanceImpl : public IRenderPluginInstance +{ + NVFoundationBase &m_Foundation; + TRenderPluginInstancePtr m_Instance; + TRenderPluginClass m_Class; + NVScopedRefCounted m_Owner; + CRegisteredString m_RendererType; + // Backing store of property values + nvvector m_PropertyValues; + bool m_Dirty; + NVRenderContext *m_RenderContext; + QT3DSI32 mRefCount; + + InstanceImpl(NVFoundationBase &fnd, TRenderPluginInstancePtr instance, TRenderPluginClass cls, + IInternalPluginClass &owner, IStringTable &strTable) + : m_Foundation(fnd) + , m_Instance(instance) + , m_Class(cls) + , m_Owner(owner) + , m_RendererType( + strTable.RegisterStr(IRenderPluginInstance::IRenderPluginOffscreenRendererType())) + , m_PropertyValues(m_Foundation.getAllocator(), "InstanceImpl::m_PropertyValues") + , m_Dirty(false) + , m_RenderContext(NULL) + , mRefCount(0) + { + } + + virtual ~InstanceImpl() { m_Class.ReleaseInstance(m_Class.m_Class, m_Instance); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void addCallback(IOffscreenRendererCallback *cb) override + { + + } + void CreateScriptProxy(script_State *state) override + { + if (m_Class.CreateInstanceScriptProxy) + m_Class.CreateInstanceScriptProxy(m_Class.m_Class, m_Instance, state); + } + + // Arbitrary const char* returned to indicate the type of this renderer + // Can be overloaded to form the basis of an RTTI type system. + // Not currently used by the rendering system. + CRegisteredString GetOffscreenRendererType() override { return m_RendererType; } + + SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresentationScaleFactor) override + { + if (m_Class.QueryInstanceRenderSurface) { + QT3DSRenderPluginMSAALevel theLevel = QT3DSRenderPluginMSAALevelNoMSAA; + TRenderPluginSurfaceDescription desc = m_Class.QueryInstanceRenderSurface( + m_Class.m_Class, m_Instance, ToCInterface(inPresentationScaleFactor)); + if (m_Owner->GetAPIVersion() > 1) + theLevel = desc.m_MSAALevel; + + return SOffscreenRendererEnvironment( + (QT3DSU32)desc.m_Width, (QT3DSU32)desc.m_Height, ToTextureFormat(desc.m_ColorBuffer), + ToDepthValue(desc.m_DepthBuffer), desc.m_HasStencilBuffer ? true : false, + ToAAMode(theLevel)); + } else { + QT3DS_ASSERT(false); + } + return SOffscreenRendererEnvironment(); + } + + // Returns true of this object needs to be rendered, false if this object is not dirty + SOffscreenRenderFlags NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, + QT3DSVec2 inPresentationScaleFactor, + const SRenderInstanceId instanceId) override + { + if (m_Dirty) { + m_Dirty = false; + m_Owner->PushUpdates(m_Instance, m_PropertyValues); + } + if (m_Class.NeedsRenderFunction) { + if (m_Owner->GetAPIVersion() > 1) { + TNeedsRenderResult result = m_Class.NeedsRenderFunction( + m_Class.m_Class, m_Instance, ToCInterface(inEnvironment), + ToCInterface(inPresentationScaleFactor)); + return SOffscreenRenderFlags(result.HasTransparency ? true : false, + result.HasChangedSinceLastFrame ? true : false); + } else { + TNeedsRenderFunctionV1 theV1Function = + reinterpret_cast(m_Class.NeedsRenderFunction); + + TNeedsRenderResult result = + theV1Function(m_Class.m_Class, m_Instance, ToCInterfaceV1(inEnvironment), + ToCInterface(inPresentationScaleFactor)); + return SOffscreenRenderFlags(result.HasTransparency ? true : false, + result.HasChangedSinceLastFrame ? true : false); + } + } + return SOffscreenRenderFlags(true, true); + } + // Returns true if the rendered result image has transparency, or false + // if it should be treated as a completely opaque image. + // It is the IOffscreenRenderer's job to clear any buffers (color, depth, stencil) that it + // needs to. It should not assume that it's buffers are clear; + // Sometimes we scale the width and height of the main presentation in order to fit a window. + // If we do so, the scale factor tells the subpresentation renderer how much the system has + // scaled. + void Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, + SScene::RenderClearCommand inColorBufferNeedsClear, + const SRenderInstanceId instanceId) override + { + m_RenderContext = &inRenderContext; + if (m_Class.RenderInstance) { + inRenderContext.PushPropertySet(); + if (m_Owner->GetAPIVersion() > 1) { + m_Class.RenderInstance(m_Class.m_Class, m_Instance, ToCInterface(inEnvironment), + ToCInterface(inPresentationScaleFactor), + ToCInterface(inColorBufferNeedsClear)); + } else { + TRenderFunctionV1 theV1Function = + reinterpret_cast(m_Class.RenderInstance); + theV1Function(m_Class.m_Class, m_Instance, ToCInterfaceV1(inEnvironment), + ToCInterface(inPresentationScaleFactor), + ToCInterface(inColorBufferNeedsClear)); + } + + inRenderContext.PopPropertySet(true); + } + } + + void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, + SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, + const SRenderInstanceId id) + { + Q_ASSERT(false); + } + + // Implementors should implement one of the two interfaces below. + + // If this renderer supports picking that can return graph objects + // then return an interface here. + IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId) override { return NULL; } + + // If you *don't* support the GraphObjectPickIterator interface, then you should implement this + // interface + // The system will just ask you to pick. + // If you return true, then we will assume that you swallowed the pick and will continue no + // further. + // else we will assume you did not and will continue the picking algorithm. + bool Pick(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, + const SRenderInstanceId instanceId) override + { + if (m_Class.Pick) { + if (m_RenderContext) { + m_RenderContext->PushPropertySet(); + bool retval = m_Class.Pick(m_Class.m_Class, m_Instance, ToCInterface(inMouseCoords), + ToCInterface(inViewportDimensions)) + ? true + : false; + m_RenderContext->PopPropertySet(true); + return retval; + } + } + return false; + } + + TRenderPluginInstancePtr GetRenderPluginInstance() override { return m_Instance; } + void Update(NVConstDataRef updateBuffer) override + { + m_Dirty = true; + m_Owner->Update(updateBuffer, m_PropertyValues); + } + IRenderPluginClass &GetPluginClass() override { return *m_Owner; } +}; + +typedef eastl::pair TStringTypePair; + +struct PluginClassImpl : public IInternalPluginClass +{ + typedef nvhash_map TStringIndexMap; + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + TRenderPluginClass m_Class; + CRegisteredString m_Type; + CLoadedDynamicLibrary *m_DynamicLibrary; + nvvector m_RegisteredProperties; + TStringIndexMap m_ComponentNameToComponentIndexMap; + nvvector m_FullPropertyList; + nvvector m_UpdateBuffer; + CRenderString m_TempString; + QT3DSI32 m_APIVersion; + + QT3DSI32 mRefCount; + + PluginClassImpl(NVFoundationBase &fnd, IStringTable &strTable, TRenderPluginClass inClass, + CRegisteredString inType, CLoadedDynamicLibrary *inLibrary) + : m_Foundation(fnd) + , m_StringTable(strTable) + , m_Class(inClass) + , m_Type(inType) + , m_DynamicLibrary(inLibrary) + , m_RegisteredProperties(m_Foundation.getAllocator(), + "PluginClassImpl::m_RegisteredProperties") + , m_ComponentNameToComponentIndexMap(m_Foundation.getAllocator(), + "PluginClassImpl::m_ComponentNameToComponentIndexMap") + , m_FullPropertyList(m_Foundation.getAllocator(), "PluginClassImpl::m_FullPropertyList") + , m_UpdateBuffer(m_Foundation.getAllocator(), "PluginClassImpl::m_UpdateBuffer") + , m_APIVersion(m_Class.GetRenderPluginAPIVersion(m_Class.m_Class)) + , mRefCount(0) + { + } + ~PluginClassImpl() + { + if (m_Class.ReleaseClass) + m_Class.ReleaseClass(m_Class.m_Class); + if (m_DynamicLibrary) + NVDelete(m_Foundation.getAllocator(), m_DynamicLibrary); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + NVScopedRefCounted CreateInstance() override + { + if (m_Class.CreateInstance) { + TRenderPluginInstancePtr instance = + m_Class.CreateInstance(m_Class.m_Class, m_Type.c_str()); + if (instance) { + InstanceImpl *retval = QT3DS_NEW(m_Foundation.getAllocator(), InstanceImpl)( + m_Foundation, instance, m_Class, *this, m_StringTable); + return retval; + } + } + return NVScopedRefCounted(); + } + + QT3DSI32 GetAPIVersion() override { return m_APIVersion; } + + void AddFullPropertyType(const char *name, RenderPluginPropertyValueTypes::Enum inType) + { + QT3DSU32 itemIndex = (QT3DSU32)m_FullPropertyList.size(); + CRegisteredString regName = m_StringTable.RegisterStr(name); + bool inserted = + m_ComponentNameToComponentIndexMap.insert(eastl::make_pair(regName, itemIndex)).second; + if (inserted) { + m_FullPropertyList.push_back(eastl::make_pair(regName, inType)); + } else { + // Duplicate property declaration. + QT3DS_ASSERT(false); + } + } + + void AddFullPropertyType(const char *name, const char *extension, + RenderPluginPropertyValueTypes::Enum inType) + { + m_TempString.assign(name); + if (!isTrivial(extension)) { + m_TempString.append("."); + m_TempString.append(extension); + } + AddFullPropertyType(m_TempString.c_str(), inType); + } + + void RegisterProperty(const SRenderPluginPropertyDeclaration &dec) override + { + QT3DSU32 startOffset = (QT3DSU32)m_FullPropertyList.size(); + + switch (dec.m_Type) { + + case SRenderPluginPropertyTypes::Vector2: + AddFullPropertyType(dec.m_Name, "x", RenderPluginPropertyValueTypes::Float); + AddFullPropertyType(dec.m_Name, "y", RenderPluginPropertyValueTypes::Float); + break; + case SRenderPluginPropertyTypes::Color: + AddFullPropertyType(dec.m_Name, "r", RenderPluginPropertyValueTypes::Float); + AddFullPropertyType(dec.m_Name, "g", RenderPluginPropertyValueTypes::Float); + AddFullPropertyType(dec.m_Name, "b", RenderPluginPropertyValueTypes::Float); + break; + case SRenderPluginPropertyTypes::Vector3: + AddFullPropertyType(dec.m_Name, "x", RenderPluginPropertyValueTypes::Float); + AddFullPropertyType(dec.m_Name, "y", RenderPluginPropertyValueTypes::Float); + AddFullPropertyType(dec.m_Name, "z", RenderPluginPropertyValueTypes::Float); + break; + case SRenderPluginPropertyTypes::Boolean: + AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::Boolean); + break; + case SRenderPluginPropertyTypes::Float: + AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::Float); + break; + case SRenderPluginPropertyTypes::Long: + AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::Long); + break; + case SRenderPluginPropertyTypes::String: + AddFullPropertyType(dec.m_Name, RenderPluginPropertyValueTypes::String); + break; + default: + QT3DS_ASSERT(false); + break; + } + m_RegisteredProperties.push_back(dec); + m_RegisteredProperties.back().m_StartOffset = startOffset; + } + + NVConstDataRef GetRegisteredProperties() override + { + return m_RegisteredProperties; + } + + SRenderPluginPropertyDeclaration GetPropertyDeclaration(CRegisteredString inPropName) override + { + for (QT3DSU32 idx = 0, end = m_RegisteredProperties.size(); idx < end; ++idx) { + if (m_RegisteredProperties[idx].m_Name == inPropName) + return m_RegisteredProperties[idx]; + } + QT3DS_ASSERT(false); + return SRenderPluginPropertyDeclaration(); + } + + // From which you can get the property name breakdown + virtual eastl::pair + GetPropertyValueInfo(QT3DSU32 inIndex) override + { + if (inIndex < m_FullPropertyList.size()) + return m_FullPropertyList[inIndex]; + QT3DS_ASSERT(false); + return eastl::pair( + CRegisteredString(), RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue); + } + + void PushUpdates(TRenderPluginInstancePtr instance, TPropertyValueList &propertyValues) override + { + m_UpdateBuffer.clear(); + for (QT3DSU32 idx = 0, end = propertyValues.size(); idx < end; ++idx) { + SRenderPluginPropertyData &theData(propertyValues[idx]); + if (theData.IsDirty()) + m_UpdateBuffer.push_back(theData.ClearDirty(m_FullPropertyList[idx].first)); + } + if (m_Class.UpdateInstance) + m_Class.UpdateInstance(m_Class.m_Class, instance, m_UpdateBuffer.data(), + (long)m_UpdateBuffer.size()); + } + + void Update(NVConstDataRef updateBuffer, + TPropertyValueList &propertyValues) override + { + for (QT3DSU32 idx = 0, end = updateBuffer.size(); idx < end; ++idx) { + const SRenderPropertyValueUpdate &update = updateBuffer[idx]; + TStringIndexMap::iterator iter = + m_ComponentNameToComponentIndexMap.find(update.m_PropertyName); + if (iter == m_ComponentNameToComponentIndexMap.end()) { + QT3DS_ASSERT(false); + continue; + } + + QT3DSU32 propIndex = iter->second; + if (update.m_Value.getType() != m_FullPropertyList[propIndex].second) { + QT3DS_ASSERT(false); + continue; + } + if (propIndex >= propertyValues.size()) + propertyValues.resize(propIndex + 1); + propertyValues[propIndex].SetValue(update.m_Value); + } + } +}; + +struct PluginInstanceKey +{ + CRegisteredString m_Path; + void *m_InstanceKey; + PluginInstanceKey(CRegisteredString p, void *ik) + : m_Path(p) + , m_InstanceKey(ik) + { + } + bool operator==(const PluginInstanceKey &rhs) const + { + return m_Path == rhs.m_Path && m_InstanceKey == rhs.m_InstanceKey; + } +}; +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const PluginInstanceKey &k) const + { + return hash()(k.m_Path) + ^ hash()(reinterpret_cast(k.m_InstanceKey)); + } + bool operator()(const PluginInstanceKey &lhs, const PluginInstanceKey &rhs) const + { + return lhs.m_Path == rhs.m_Path && lhs.m_InstanceKey == rhs.m_InstanceKey; + } +}; +} + +namespace { + +struct SLoadedPluginData +{ + CRegisteredString m_PluginPath; + eastl::vector m_Properties; +}; + +typedef eastl::vector TLoadedPluginDataList; + +struct PluginManagerImpl : public IRenderPluginManager, public IRenderPluginManagerCore +{ + typedef nvhash_map> TLoadedClassMap; + typedef nvhash_map> TInstanceMap; + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + TLoadedClassMap m_LoadedClasses; + TInstanceMap m_Instances; + NVScopedRefCounted m_RenderContext; + IInputStreamFactory &m_InputStreamFactory; + QT3DSI32 mRefCount; + TStr m_DllDir; + TLoadedPluginDataList m_LoadedPluginData; + + PluginManagerImpl(NVFoundationBase &fnd, IStringTable &st, IInputStreamFactory &inFactory) + : m_Foundation(fnd) + , m_StringTable(st) + , m_LoadedClasses(fnd.getAllocator(), "PluginManagerImpl::m_LoadedClasses") + , m_Instances(fnd.getAllocator(), "PluginManagerImpl::m_Instances") + , m_InputStreamFactory(inFactory) + , mRefCount(0) + , m_DllDir(ForwardingAllocator(fnd.getAllocator(), "PluginManagerImpl::m_DllDir")) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + IRenderPluginClass *GetRenderPlugin(CRegisteredString inRelativePath) override + { + TLoadedClassMap::iterator iter = m_LoadedClasses.find(inRelativePath); + if (iter != m_LoadedClasses.end()) + return iter->second; + + return NVScopedRefCounted(); + } + + IRenderPluginClass *GetOrCreateRenderPlugin(CRegisteredString inRelativePath) override + { + TLoadedClassMap::iterator iter = m_LoadedClasses.find(inRelativePath); + if (iter != m_LoadedClasses.end()) { + return iter->second; + } + + // We insert right here to keep us from going down this path potentially for every instance. + iter = + m_LoadedClasses + .insert(eastl::make_pair(inRelativePath, NVScopedRefCounted())) + .first; + eastl::string xmlDir, fname, extension; + + CFileTools::Split(inRelativePath.c_str(), xmlDir, fname, extension); + + eastl::string sharedLibrary(xmlDir); + eastl::string subdir(qt3ds::foundation::System::getPlatformGLStr()); + eastl::string libdir; + eastl::string libpath; + + CFileTools::CombineBaseAndRelative(xmlDir.c_str(), subdir.c_str(), libdir); + CFileTools::CombineBaseAndRelative(libdir.c_str(), fname.c_str(), libpath); +#ifdef _DEBUG + libpath.append("d"); +#endif + libpath.append(qt3ds::foundation::System::g_DLLExtension); + eastl::string loadPath; + if (m_DllDir.size()) { + // Then we have to copy the dll to the dll directory before loading because the + // filesystem + // the plugin is on may not be executable. + eastl::string targetFile; + CFileTools::CombineBaseAndRelative(m_DllDir.c_str(), fname.c_str(), targetFile); +#ifdef _DEBUG + targetFile.append("d"); +#endif + targetFile.append(qt3ds::foundation::System::g_DLLExtension); + + qCInfo(TRACE_INFO, "Copying plugin shared library from %s to %s", + libpath.c_str(), targetFile.c_str()); + + // try to open the library. + NVScopedRefCounted theStream = + m_InputStreamFactory.GetStreamForFile(libpath.c_str()); + if (!theStream) { + qCCritical(INVALID_OPERATION, "Failed to load render plugin %s", + libpath.c_str()); + return NULL; + } + CFileSeekableIOStream outStream(targetFile.c_str(), FileWriteFlags()); + if (!outStream.IsOpen()) { + qCCritical(INVALID_OPERATION, "Failed to load render plugin %s", + targetFile.c_str()); + return NULL; + } + + QT3DSU8 buf[1024] = { 0 }; + for (QT3DSU32 len = theStream->Read(toDataRef(buf, 1024)); len; + len = theStream->Read(toDataRef(buf, 1024))) { + outStream.Write(toDataRef(buf, len)); + } + loadPath = targetFile; + } else { + QString path; + m_InputStreamFactory.GetPathForFile(libpath.c_str(), path); + loadPath = path.toUtf8().data(); + } + CLoadedDynamicLibrary *library = NULL; + TRenderPluginClass newPluginClass; + memSet(&newPluginClass, 0, sizeof(newPluginClass)); + + // Do not load plugin dlls during compilation steps or when we don't have a valid render + // context. + // They may try opengl access at some point and that would end in disaster during binary + // save steps. + if ((QT3DSU32)m_RenderContext->GetRenderContextType() != NVRenderContextValues::NullContext) { + library = CLoadedDynamicLibrary::Create(loadPath.c_str(), m_Foundation); + if (!library) { + // try loading it from the system instead of from this specific path. This means do + // not use any extensions or any special + // sauce. + loadPath = fname; +#ifdef _DEBUG + loadPath.append("d"); +#endif + library = CLoadedDynamicLibrary::Create(loadPath.c_str(), m_Foundation); + } + } + + if (library) { + TCreateRenderPluginClassFunction CreateClass = + reinterpret_cast( + library->FindFunction("CreateRenderPlugin")); + if (CreateClass) { + newPluginClass = CreateClass(fname.c_str()); + if (newPluginClass.m_Class) { + // Check that the required functions are there. + if (newPluginClass.CreateInstance == NULL + || newPluginClass.QueryInstanceRenderSurface == NULL + || newPluginClass.RenderInstance == NULL + || newPluginClass.ReleaseInstance == NULL + || newPluginClass.ReleaseClass == NULL) { + if (newPluginClass.ReleaseClass) + newPluginClass.ReleaseClass(newPluginClass.m_Class); + qCCritical(INVALID_OPERATION, + "Failed to load render plugin: %s, required functions " + "missing. Required functions are:" + "CreateInstance, QueryInstanceRenderSurface, " + "RenderInstance, ReleaseInstance, ReleaseClass", + inRelativePath.c_str()); + NVDelete(m_Foundation.getAllocator(), library); + memSet(&newPluginClass, 0, sizeof(newPluginClass)); + } + } + } + } + if (newPluginClass.m_Class) { + PluginClassImpl *retval = QT3DS_NEW(m_Foundation.getAllocator(), PluginClassImpl)( + m_Foundation, m_StringTable, newPluginClass, + m_StringTable.RegisterStr(fname.c_str()), library); + + iter->second = retval; + if (newPluginClass.InitializeClassGLResources) { + m_RenderContext->PushPropertySet(); + newPluginClass.InitializeClassGLResources(newPluginClass.m_Class, loadPath.c_str()); + m_RenderContext->PopPropertySet(true); + } + return iter->second; + } + return NULL; + } + + void SetDllDir(const char *inDllDir) override { m_DllDir.assign(nonNull(inDllDir)); } + + IRenderPluginInstance *GetOrCreateRenderPluginInstance(CRegisteredString inRelativePath, + void *inKey) override + { + PluginInstanceKey theKey(inRelativePath, inKey); + TInstanceMap::iterator iter = m_Instances.find(theKey); + if (iter == m_Instances.end()) { + IRenderPluginClass *theClass = GetOrCreateRenderPlugin(inRelativePath); + NVScopedRefCounted theInstance; + if (theClass) + theInstance = theClass->CreateInstance(); + + iter = m_Instances.insert(eastl::make_pair(theKey, theInstance)).first; + } + return iter->second.mPtr; + } + + void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, + const char8_t * /*inProjectDir*/) const override + { + QT3DSU32 numClasses = m_LoadedClasses.size(); + ioBuffer.write(numClasses); + for (TLoadedClassMap::const_iterator iter = m_LoadedClasses.begin(), + end = m_LoadedClasses.end(); + iter != end; ++iter) { + CRegisteredString saveStr = iter->first; + saveStr.Remap(inRemapMap); + ioBuffer.write(saveStr); + if (iter->second) { + NVConstDataRef theProperties = + const_cast((*iter->second)).GetRegisteredProperties(); + ioBuffer.write(theProperties.size()); + for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { + SRenderPluginPropertyDeclaration theDec(theProperties[idx]); + theDec.m_Name.Remap(inRemapMap); + ioBuffer.write(theDec); + } + } else + ioBuffer.write((QT3DSU32)0); + } + } + + void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t * /*inProjectDir*/) override + { + qt3ds::render::SDataReader theReader(inData.begin(), inData.end()); + QT3DSU32 numClasses = theReader.LoadRef(); + ForwardingAllocator alloc(m_Foundation.getAllocator(), "tempstrings"); + qt3ds::foundation::TStr workStr(alloc); + nvvector propertyBuffer(m_Foundation.getAllocator(), + "tempprops"); + for (QT3DSU32 classIdx = 0; classIdx < numClasses; ++classIdx) { + CRegisteredString classPath = theReader.LoadRef(); + classPath.Remap(inStrDataBlock); + QT3DSU32 numProperties = theReader.LoadRef(); + propertyBuffer.clear(); + for (QT3DSU32 propIdx = 0; propIdx < numProperties; ++propIdx) { + propertyBuffer.push_back(theReader.LoadRef()); + propertyBuffer.back().m_Name.Remap(inStrDataBlock); + } + m_LoadedPluginData.push_back(SLoadedPluginData()); + m_LoadedPluginData.back().m_PluginPath = classPath; + m_LoadedPluginData.back().m_Properties.assign(propertyBuffer.begin(), + propertyBuffer.end()); + } + } + IRenderPluginManager &GetRenderPluginManager(NVRenderContext &rc) override + { + m_RenderContext = rc; + for (QT3DSU32 idx = 0, end = m_LoadedPluginData.size(); idx < end; ++idx) { + // Now we can attempt to load the class. + IRenderPluginClass *theClass = + GetOrCreateRenderPlugin(m_LoadedPluginData[idx].m_PluginPath); + if (theClass) { + eastl::vector &propertyBuffer( + m_LoadedPluginData[idx].m_Properties); + for (QT3DSU32 propIdx = 0, propEnd = propertyBuffer.size(); propIdx < propEnd; + ++propIdx) { + theClass->RegisterProperty(propertyBuffer[propIdx]); + } + } + } + m_LoadedPluginData.clear(); + return *this; + } +}; +} + +IRenderPluginManagerCore &IRenderPluginManagerCore::Create(NVFoundationBase &inFoundation, + IStringTable &strTable, + IInputStreamFactory &inFactory) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), PluginManagerImpl)(inFoundation, strTable, + inFactory); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.h new file mode 100644 index 00000000..eb71f846 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPlugin.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PLUGIN_H +#define QT3DS_RENDER_PLUGIN_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderPluginCInterface.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "EASTL/utility.h" + +namespace qt3ds { +namespace render { + + // UICRenderPluginPropertyValue.h + struct SRenderPropertyValueUpdate; + + class IRenderPluginInstance : public IOffscreenRenderer + { + protected: + virtual ~IRenderPluginInstance() {} + public: + static const char *IRenderPluginOffscreenRendererType() { return "IRenderPluginInstance"; } + // If this render plugin has an instance ptr, get it. + virtual TRenderPluginInstancePtr GetRenderPluginInstance() = 0; + virtual void Update(NVConstDataRef updateBuffer) = 0; + virtual IRenderPluginClass &GetPluginClass() = 0; + virtual void CreateScriptProxy(script_State *state) = 0; + }; + struct RenderPluginPropertyValueTypes + { + enum Enum { + NoRenderPluginPropertyValue = 0, + Boolean, + Long, + Float, + String, + }; + }; + + struct SRenderPluginPropertyTypes + { + enum Enum { + UnknownRenderPluginPropertyType = 0, + Float, + Vector3, + Vector2, + Color, + Boolean, + Long, + String, + }; + }; + + struct SRenderPluginPropertyDeclaration + { + CRegisteredString m_Name; + SRenderPluginPropertyTypes::Enum m_Type; + // Filled in by the class, ignored if set on registered property + QT3DSU32 m_StartOffset; + SRenderPluginPropertyDeclaration() + : m_Type(SRenderPluginPropertyTypes::UnknownRenderPluginPropertyType) + { + } + SRenderPluginPropertyDeclaration(CRegisteredString n, SRenderPluginPropertyTypes::Enum t) + : m_Name(n) + , m_Type(t) + , m_StartOffset(0) + { + } + }; + + class IRenderPluginClass : public NVRefCounted + { + protected: + virtual ~IRenderPluginClass() {} + public: + virtual NVScopedRefCounted CreateInstance() = 0; + virtual void RegisterProperty(const SRenderPluginPropertyDeclaration &dec) = 0; + virtual NVConstDataRef GetRegisteredProperties() = 0; + // The declaration contains an offset + virtual SRenderPluginPropertyDeclaration + GetPropertyDeclaration(CRegisteredString inPropName) = 0; + // From which you can get the property name breakdown + virtual eastl::pair + GetPropertyValueInfo(QT3DSU32 inIndex) = 0; + }; + + class IRenderPluginManager; + + class IRenderPluginManagerCore : public NVRefCounted + { + public: + virtual void SetDllDir(const char *inDllDir) = 0; + virtual void Load(NVDataRef inData, CStrTableOrDataRef inStrDataBlock, + const char8_t *inProjectDir) = 0; + virtual IRenderPluginManager &GetRenderPluginManager(NVRenderContext &rc) = 0; + + static IRenderPluginManagerCore &Create(NVFoundationBase &inFoundation, + IStringTable &strTable, + IInputStreamFactory &inFactory); + }; + + class IRenderPluginManager : public NVRefCounted + { + public: + virtual IRenderPluginClass *GetRenderPlugin(CRegisteredString inRelativePath) = 0; + virtual IRenderPluginClass *GetOrCreateRenderPlugin(CRegisteredString inRelativePath) = 0; + // Map a render plugin instance to this key. The instance's lifetime is managed by the + // manager so a client does not + // need to manage it. + virtual IRenderPluginInstance * + GetOrCreateRenderPluginInstance(CRegisteredString inRelativePath, void *inKey) = 0; + + virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer, + const qt3ds::render::SStrRemapMap &inRemapMap, + const char8_t *inProjectDir) const = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPluginCInterface.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPluginCInterface.h new file mode 100644 index 00000000..ec7481a0 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPluginCInterface.h @@ -0,0 +1,330 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_OBJECT_RENDER_PLUGIN_H +#define QT3DS_OBJECT_RENDER_PLUGIN_H + +/* + * Below are the definitions required in order to write a render plugin for UIComposer. + * Please note that calling anything related to opengl is explicitly not allowed except + * during either the class gl resource initialization function or during render. Calling into + * openGL and especially changing GL state during any other function may produce corrupt + *rendering. + */ + +#ifdef _cplusplus +#extern "C" { +#endif + +enum QT3DSRenderPluginPropertyTypes { + QT3DSRenderPluginPropertyTypeNone = 0, + QT3DSRenderPluginPropertyTypeLong = 1, + QT3DSRenderPluginPropertyTypeFloat = 2, + QT3DSRenderPluginPropertyTypeCharPtr = 3, +}; + +enum QT3DSRenderPluginDepthTypes { + QT3DSRenderPluginDepthTypeNoDepthBuffer = 0, + QT3DSRenderPluginDepthTypeDepth16, // 16 bit depth buffer + QT3DSRenderPluginDepthTypeDepth24, // 24 bit depth buffer + QT3DSRenderPluginDepthTypeDepth32, // 32 bit depth buffer +}; + +enum QT3DSRenderPluginTextureTypes { + QT3DSRenderPluginTextureTypeNoTexture = 0, + QT3DSRenderPluginTextureTypeRGBA8, // 32 bit format + QT3DSRenderPluginTextureTypeRGB8, // 24 bit format + QT3DSRenderPluginTextureTypeRGB565, // 16 bit format + QT3DSRenderPluginTextureTypeRGBA5551, // 16 bit format +}; + +enum QT3DSRenderPluginColorClearState { + QT3DSRenderPluginColorClearStateClearIsOptional = 0, + QT3DSRenderPluginColorClearStateDoNotClear, + QT3DSRenderPluginColorClearStateAlwaysClear, +}; + +enum QT3DSRenderPluginMSAALevel { + QT3DSRenderPluginMSAALevelNoMSAA = 0, // no MSAA, one also works. + QT3DSRenderPluginMSAALevelTwo = 2, // 2 samples + QT3DSRenderPluginMSAALevelFour = 4, // 4 samples + QT3DSRenderPluginMSAALevelEight = 8, // 8 samples +}; + +typedef long TBool; +#define TTRUE 1 +#define TFALSE 0 + +#define QT3DS_CURRENT_RENDER_PLUGIN_API_VERSION 2 + +typedef void *TRenderPluginInstancePtr; +typedef void *TRenderPluginClassPtr; + +// We will pass the componentized properties to the instance ptr. +typedef struct _RenderPluginPropertyUpdate +{ + const char *m_PropName; + enum QT3DSRenderPluginPropertyTypes m_PropertyType; + + // Is either a float or a long or a const char* depending on the property type. + // for specify types of properties, example code would be: + // float value = *((float*)&update.m_PropertyValue) + // long value = *((long*)&update.m_PropertyValue) + // char* value = (char*)update.m_PropertyValue + void *m_PropertyValue; +} TRenderPluginPropertyUpdate; + +typedef struct _RenderPluginSurfaceDescription +{ + long m_Width; + long m_Height; + enum QT3DSRenderPluginDepthTypes m_DepthBuffer; + enum QT3DSRenderPluginTextureTypes m_ColorBuffer; + TBool m_HasStencilBuffer; + QT3DSRenderPluginMSAALevel m_MSAALevel; +} TRenderPluginSurfaceDescription; + +typedef struct _TVec2 +{ + float x; + float y; +} TVec2; + +typedef struct _NeedsRenderResult +{ + TBool HasChangedSinceLastFrame; + TBool HasTransparency; +} TNeedsRenderResult; + +struct script_State; + +/* + * Create a new instance object. Typename is the name of the plugin file, so for example + * gears.plugin generates 'gears' as a type name. + * + * Required API function. + * + */ +typedef TRenderPluginInstancePtr (*TCreateInstanceFunction)(TRenderPluginClassPtr cls, + const char *inTypeName); + +typedef void (*TCreateInstanceScriptProxy)(TRenderPluginClassPtr cls, + TRenderPluginInstancePtr insPtr, + struct script_State *state); + +/* + * Update the plugin instance with a list of property updates. Properties are broken down by + *component so for example + * a color property named leftColor will be broken down into 'leftColor.r', 'leftColor.g', + *'leftColor.b'. Vector + * properties are broken down into x,y,z components. The property string has a void* member + *that is the actual value + * or in a charPtr property's case it is the char*. + * Please see the comments for m_PropertyValue member of TRenderPluginPropertyUpdate struct. + * + * Optional API function. + */ +typedef void (*TUpdateInstanceFunction)(TRenderPluginClassPtr cls, + TRenderPluginInstancePtr instance, + TRenderPluginPropertyUpdate *updates, long numUpdates); + +/* + * Query used when the plugin is rendering to an image. Should return the desired + *specifications of the plugins + * render target. + * presScaleFactor - the presentation scale factor when the user has requested scale to fit to + *be used for the + * presentation. + * + * Required API function. + */ +typedef TRenderPluginSurfaceDescription (*TSurfaceQueryFunction)(TRenderPluginClassPtr cls, + TRenderPluginInstancePtr instance, + TVec2 presScaleFactor); + +/* + * Query used by the rendering system. Should return true if the plugin will render something + *different than it did + * the last time it rendered. This is used so that we can cache render results and also so that we + *can trigger the + * progressive AA algorithm in the case where nothing has changed. + * + * presScaleFactor - the presentation scale factor when the user has requested scale to fit to be + *used for the + * presentation. + * + * OpenGL state may be changed in this function. + * + * Optional API function, returns true by default. + */ +typedef TNeedsRenderResult (*TNeedsRenderFunction)(TRenderPluginClassPtr cls, + TRenderPluginInstancePtr instance, + TRenderPluginSurfaceDescription surface, + TVec2 presScaleFactor); + +/* + * Render plugin data. + * Do not assume the surface requested is the surface given; for some cases it will be but if + *the system has deemed it + * appropriate to render the plugin directly to the back buffer then the surface description + *presented could differ by + * quite a bit. + * + * presScaleFactor - is the presentation scale factor when the user has requested scale to fit + *to be used for the + * presentation. + * inClearColorBuffer - True if the plugin needs to clear the color buffer (when rendering to + *texture) else false + * (when rendering to back buffer). + * + * Function should return 'UICTRUE' the image produced by rendering contains transparency; + *either every pixel wasn't + * written to or it is desired for the plugin to blend with background objects. Else should + *return UICFALSE. + * + * Required API function. + */ +typedef void (*TRenderFunction)(TRenderPluginClassPtr cls, TRenderPluginInstancePtr instance, + TRenderPluginSurfaceDescription surface, TVec2 presScaleFactor, + QT3DSRenderPluginColorClearState inClearColorBuffer); + +/* + * Pick - handle a mouse pick into the plugin. + * Returns true if the pick was consumed, false otherwise. + * + * Option API function. + */ +typedef TBool (*TPickFunction)(TRenderPluginClassPtr cls, TRenderPluginInstancePtr instance, + TVec2 inMouse, TVec2 inViewport); + +/* + * Release a given instance of the plugin. + * + * Required API function. + */ +typedef void (*TReleaseInstanceFunction)(TRenderPluginClassPtr cls, + TRenderPluginInstancePtr instance); + +/* + * Get the plugin API version. This allows the runtime to account for API changes over time or + * refuse to load the plugin. Plugins should return QT3DS_CURRENT_RENDER_PLUGIN_API_VERSION + * + * Required API function. + */ +typedef long (*TGetAPIVersionFunction)(TRenderPluginClassPtr cls); + +/* + * Initialize the resources for the class. Implementing this allows UIComposer to move + * expensive initialization outside of the actual presentation run, thus allowing for + * a smoother experience during the presentation at the cost of longer startup times. + * + * - plugin path is the path to the .plugin xml file so that clients can find resources + * specific to their plugin relative to their .plugin file. + * + * OpenGL state may be changed in this function. + * + * Optional API function. + */ +typedef void (*TInitializeClassGLResourcesFunction)(TRenderPluginClassPtr cls, + const char *pluginPath); + +/* + * Release the class allocated with the create proc provided in the shared library. + * + * Required API function. + */ +typedef void (*TReleaseClassFunction)(TRenderPluginClassPtr cls); + +/* + * Structure returned form the create class function. Unimplemented functions should be left + *NULL. + */ +typedef struct _RenderPluginClass +{ + TRenderPluginClassPtr m_Class; + + TGetAPIVersionFunction GetRenderPluginAPIVersion; + TInitializeClassGLResourcesFunction InitializeClassGLResources; + TReleaseClassFunction ReleaseClass; + + TCreateInstanceFunction CreateInstance; + TCreateInstanceScriptProxy CreateInstanceScriptProxy; + TUpdateInstanceFunction UpdateInstance; + TSurfaceQueryFunction QueryInstanceRenderSurface; + TNeedsRenderFunction NeedsRenderFunction; + TRenderFunction RenderInstance; + TPickFunction Pick; + TReleaseInstanceFunction ReleaseInstance; + +} TRenderPluginClass; + +// We look for this function name in the shared library +#define QT3DS_RENDER_PLUGIN_CREATE_CLASS_FUNCION_NAME "CreateRenderPlugin" + +/* + * Function signature we expect mapped to "CreateRenderPlugin". Example code: + * + extern "C" { + +#ifdef _WIN32 +#define PLUGIN_EXPORT_API __declspec(dllexport) +#else +#define PLUGIN_EXPORT_API +#endif + + + +PLUGIN_EXPORT_API TRenderPluginClass CreateRenderPlugin( const char*) +{ + GearClass* classItem = (GearClass*)malloc( sizeof(GearClass) ); + TRenderPluginClass retval; + memset( &retval, 0, sizeof( TRenderPluginClass ) ); + retval.m_Class = classItem; + retval.GetRenderPluginAPIVersion = GetAPIVersion; + retval.CreateInstance = CreateInstance; + retval.CreateInstanceScriptProxy = CreateInstanceScriptProxy; + retval.UpdateInstance = UpdateInstance; + retval.QueryInstanceRenderSurface = QuerySurface; + retval.RenderInstance = Render; + retval.ReleaseInstance = ReleaseInstance; + retval.ReleaseClass = ReleaseClass; + return retval; +} + + * Required API function. + */ + +typedef TRenderPluginClass (*TCreateRenderPluginClassFunction)(const char *inTypeName); + +#ifdef _cplusplus +} +#endif + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPluginGraphObject.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPluginGraphObject.h new file mode 100644 index 00000000..c0ea66b4 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPluginGraphObject.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PLUGIN_GRAPH_OBJECT_H +#define QT3DS_RENDER_PLUGIN_GRAPH_OBJECT_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +namespace qt3ds { +namespace render { + + struct SRenderPlugin : public SGraphObject + { + CRegisteredString m_PluginPath; + NodeFlags m_Flags; + + SRenderPlugin() + : SGraphObject(GraphObjectTypes::RenderPlugin) + { + } + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_PluginPath); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderPluginPropertyValue.h b/src/Runtime/Source/runtimerender/Qt3DSRenderPluginPropertyValue.h new file mode 100644 index 00000000..a266e8d3 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderPluginPropertyValue.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PLUGIN_PROPERTY_VALUE_H +#define QT3DS_RENDER_PLUGIN_PROPERTY_VALUE_H +#include "Qt3DSRender.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" +#include "Qt3DSRenderPlugin.h" + +namespace qt3ds { +namespace foundation { + + template <> + struct DestructTraits + { + void destruct(CRegisteredString &) {} + }; +} +} + +namespace qt3ds { +namespace render { + + template + struct SRenderPluginPropertyValueTypeMap + { + }; + + template <> + struct SRenderPluginPropertyValueTypeMap + { + enum { TypeMap = RenderPluginPropertyValueTypes::Long }; + }; + template <> + struct SRenderPluginPropertyValueTypeMap + { + enum { TypeMap = RenderPluginPropertyValueTypes::Float }; + }; + template <> + struct SRenderPluginPropertyValueTypeMap + { + enum { TypeMap = RenderPluginPropertyValueTypes::String }; + }; + template <> + struct SRenderPluginPropertyValueTypeMap + { + enum { TypeMap = RenderPluginPropertyValueTypes::Boolean }; + }; + + struct SRenderPluginPropertyValueUnionTraits + { + typedef RenderPluginPropertyValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(CRegisteredString), + }; + + static TIdType getNoDataId() + { + return RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue; + } + + template + static TIdType getType() + { + return (TIdType)SRenderPluginPropertyValueTypeMap::TypeMap; + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case RenderPluginPropertyValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case RenderPluginPropertyValueTypes::Float: + return inVisitor(*NVUnionCast(inData)); + case RenderPluginPropertyValueTypes::Long: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case RenderPluginPropertyValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case RenderPluginPropertyValueTypes::Float: + return inVisitor(*NVUnionCast(inData)); + case RenderPluginPropertyValueTypes::Long: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case RenderPluginPropertyValueTypes::NoRenderPluginPropertyValue: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SRenderPluginPropertyValueUnionTraits::TBufferSize> + TRenderPluginPropertyValueUnionType; + + struct SRenderPluginPropertyValue : public TRenderPluginPropertyValueUnionType + { + typedef TRenderPluginPropertyValueUnionType TBase; + SRenderPluginPropertyValue() {} + SRenderPluginPropertyValue(const CRegisteredString &str) + : TBase(str) + { + } + SRenderPluginPropertyValue(QT3DSI32 value) + : TBase(value) + { + } + SRenderPluginPropertyValue(QT3DSF32 value) + : TBase(value) + { + } + SRenderPluginPropertyValue(const SRenderPluginPropertyValue &other) + : TBase(static_cast(other)) + { + } + SRenderPluginPropertyValue &operator=(const SRenderPluginPropertyValue &other) + { + TBase::operator=(other); + return *this; + } + }; + + struct SRenderPropertyValueUpdate + { + // Should be the componentized name, so colors get .r .g .b appended + // and vectors get .x .y etc. This interface only updates a component at a time. + CRegisteredString m_PropertyName; + SRenderPluginPropertyValue m_Value; + SRenderPropertyValueUpdate() {} + SRenderPropertyValueUpdate(CRegisteredString str, const SRenderPluginPropertyValue &v) + : m_PropertyName(str) + , m_Value(v) + { + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderProfiler.h b/src/Runtime/Source/runtimerender/Qt3DSRenderProfiler.h new file mode 100644 index 00000000..a5941c03 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderProfiler.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PROFILER_H +#define QT3DS_RENDER_PROFILER_H +#include "Qt3DSRender.h" +#include "EASTL/string.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace render { + + /** + * Opaque profiling system for rendering. + */ + class IRenderProfiler : public NVRefCounted + { + public: + typedef nvvector TStrIDVec; + + protected: + virtual ~IRenderProfiler() {} + + public: + /** + * @brief start a timer query + * + * @param[in] nameID Timer ID for tracking + * @param[in] absoluteTime If true the absolute GPU is queried + * @param[in] sync Do a sync before starting the timer + * + * @return no return + */ + virtual void StartTimer(CRegisteredString &nameID, bool absoluteTime, bool sync) = 0; + + /** + * @brief stop a timer query + * + * @param[in] nameID Timer ID for tracking + * + * @return no return + */ + virtual void EndTimer(CRegisteredString &nameID) = 0; + + /** + * @brief Get elapsed timer value. Not this is an averaged time over several frames + * + * @param[in] nameID Timer ID for tracking + * + * @return no return + */ + virtual QT3DSF64 GetElapsedTime(const CRegisteredString &nameID) const = 0; + + /** + * @brief Get ID list of tracked timers + * + * @return ID list + */ + virtual const TStrIDVec &GetTimerIDs() const = 0; + + /** + * @brief add vertex count to current counter + * + * @return + */ + virtual void AddVertexCount(QT3DSU32 count) = 0; + + /** + * @brief get current vertex count and reset + * + * @return + */ + virtual QT3DSU32 GetAndResetTriangleCount() const = 0; + + static IRenderProfiler &CreateGpuProfiler(NVFoundationBase &inFoundation, + IQt3DSRenderContext &inContext, + NVRenderContext &inRenderContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRay.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderRay.cpp new file mode 100644 index 00000000..5376b8b9 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRay.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderRay.h" +#include "foundation/Qt3DSPlane.h" + +using namespace qt3ds::render; + +// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm + +Option SRay::Intersect(const NVPlane &inPlane) const +{ + QT3DSF32 Vd = inPlane.n.dot(m_Direction); + if (fabs(Vd) < .0001f) + return Empty(); + QT3DSF32 V0 = -1.0f * (inPlane.n.dot(m_Origin) + inPlane.d); + QT3DSF32 t = V0 / Vd; + return m_Origin + (m_Direction * t); +} + +Option SRay::IntersectWithAABB(const QT3DSMat44 &inGlobalTransform, + const NVBounds3 &inBounds, + bool inForceIntersect) const +{ + // Intersect the origin with the AABB described by bounds. + + // Scan each axis separately. This code basically finds the distance + // distance from the origin to the near and far bbox planes for a given + // axis. It then divides this distance by the direction for that axis to + // get a range of t [near,far] that the ray intersects assuming the ray is + // described via origin + t*(direction). Running through all three axis means + // that you need to min/max those ranges together to find a global min/max + // that the pick could possibly be in. + + // Transform pick origin and direction into the subset's space. + QT3DSMat44 theOriginTransform = inGlobalTransform.getInverse(); + + QT3DSVec3 theTransformedOrigin = theOriginTransform.transform(m_Origin); + QT3DSF32 *outOriginTransformPtr(theOriginTransform.front()); + outOriginTransformPtr[12] = outOriginTransformPtr[13] = outOriginTransformPtr[14] = 0.0f; + QT3DSVec3 theTransformedDirection = theOriginTransform.rotate(m_Direction); + + static const QT3DSF32 KD_FLT_MAX = 3.40282346638528860e+38; + static const QT3DSF32 kEpsilon = 1e-5f; + + QT3DSF32 theMinWinner = -KD_FLT_MAX; + QT3DSF32 theMaxWinner = KD_FLT_MAX; + + for (QT3DSU32 theAxis = 0; theAxis < 3; ++theAxis) { + // Extract the ranges and direction for this axis + QT3DSF32 theMinBox = inBounds.minimum[theAxis]; + QT3DSF32 theMaxBox = inBounds.maximum[theAxis]; + QT3DSF32 theDirectionAxis = theTransformedDirection[theAxis]; + QT3DSF32 theOriginAxis = theTransformedOrigin[theAxis]; + + QT3DSF32 theMinAxis = -KD_FLT_MAX; + QT3DSF32 theMaxAxis = KD_FLT_MAX; + if (theDirectionAxis > kEpsilon) { + theMinAxis = (theMinBox - theOriginAxis) / theDirectionAxis; + theMaxAxis = (theMaxBox - theOriginAxis) / theDirectionAxis; + } else if (theDirectionAxis < -kEpsilon) { + theMinAxis = (theMaxBox - theOriginAxis) / theDirectionAxis; + theMaxAxis = (theMinBox - theOriginAxis) / theDirectionAxis; + } else if ((theOriginAxis < theMinBox || theOriginAxis > theMaxBox) + && inForceIntersect == false) { + // Pickray is roughly parallel to the plane of the slab + // so, if the origin is not in the range, we have no intersection + return Empty(); + } + + // Shrink the intersections to find the closest hit + theMinWinner = NVMax(theMinWinner, theMinAxis); + theMaxWinner = NVMin(theMaxWinner, theMaxAxis); + + if ((theMinWinner > theMaxWinner || theMaxWinner < 0) && inForceIntersect == false) + return Empty(); + } + + QT3DSVec3 scaledDir = theTransformedDirection * theMinWinner; + QT3DSVec3 newPosInLocal = theTransformedOrigin + scaledDir; + QT3DSVec3 newPosInGlobal = inGlobalTransform.transform(newPosInLocal); + QT3DSVec3 cameraToLocal = m_Origin - newPosInGlobal; + + QT3DSF32 rayLengthSquared = cameraToLocal.magnitudeSquared(); + + QT3DSF32 xRange = inBounds.maximum.x - inBounds.minimum.x; + QT3DSF32 yRange = inBounds.maximum.y - inBounds.minimum.y; + + QT3DSVec2 relXY; + relXY.x = (newPosInLocal[0] - inBounds.minimum.x) / xRange; + relXY.y = (newPosInLocal[1] - inBounds.minimum.y) / yRange; + + return SRayIntersectionResult(rayLengthSquared, relXY); +} + +Option SRay::GetRelative(const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, + SBasisPlanes::Enum inPlane) const +{ + QT3DSMat44 theOriginTransform = inGlobalTransform.getInverse(); + + QT3DSVec3 theTransformedOrigin = theOriginTransform.transform(m_Origin); + QT3DSF32 *outOriginTransformPtr(theOriginTransform.front()); + outOriginTransformPtr[12] = outOriginTransformPtr[13] = outOriginTransformPtr[14] = 0.0f; + QT3DSVec3 theTransformedDirection = theOriginTransform.rotate(m_Direction); + + // The XY plane is going to be a plane with either positive or negative Z direction that runs + // through + QT3DSVec3 theDirection(0, 0, 1); + QT3DSVec3 theRight(1, 0, 0); + QT3DSVec3 theUp(0, 1, 0); + switch (inPlane) { + case SBasisPlanes::XY: + break; + case SBasisPlanes::XZ: + theDirection = QT3DSVec3(0, 1, 0); + theUp = QT3DSVec3(0, 0, 1); + break; + case SBasisPlanes::YZ: + theDirection = QT3DSVec3(1, 0, 0); + theRight = QT3DSVec3(0, 0, 1); + break; + } + NVPlane thePlane(theDirection, theDirection.dot(theTransformedDirection) > 0.0f + ? theDirection.dot(inBounds.maximum) + : theDirection.dot(inBounds.minimum)); + + SRay relativeRay(theTransformedOrigin, theTransformedDirection); + Option localIsect = relativeRay.Intersect(thePlane); + if (localIsect.hasValue()) { + QT3DSF32 xRange = theRight.dot(inBounds.maximum) - theRight.dot(inBounds.minimum); + QT3DSF32 yRange = theUp.dot(inBounds.maximum) - theUp.dot(inBounds.minimum); + QT3DSF32 xOrigin = xRange / 2.0f + theRight.dot(inBounds.minimum); + QT3DSF32 yOrigin = yRange / 2.0f + theUp.dot(inBounds.minimum); + return QT3DSVec2((theRight.dot(*localIsect) - xOrigin) / xRange, + (theUp.dot(*localIsect) - yOrigin) / yRange); + } + return Empty(); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRay.h b/src/Runtime/Source/runtimerender/Qt3DSRenderRay.h new file mode 100644 index 00000000..705f7089 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRay.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RAY_H +#define QT3DS_RENDER_RAY_H + +#include "Qt3DSRender.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSMat44.h" +#include "foundation/Qt3DSBounds3.h" + +namespace qt3ds { +namespace render { + + struct SBasisPlanes + { + enum Enum { + XY = 0, + YZ, + XZ, + }; + }; + + struct SRayIntersectionResult + { + QT3DSF32 m_RayLengthSquared; // Length of the ray in world coordinates for the hit. + QT3DSVec2 m_RelXY; // UV coords for further mouse picking against a offscreen-rendered object. + SRayIntersectionResult() + : m_RayLengthSquared(0) + , m_RelXY(0, 0) + { + } + SRayIntersectionResult(QT3DSF32 rl, QT3DSVec2 relxy) + : m_RayLengthSquared(rl) + , m_RelXY(relxy) + { + } + }; + + struct SRay + { + QT3DSVec3 m_Origin; + QT3DSVec3 m_Direction; + SRay() + : m_Origin(0, 0, 0) + , m_Direction(0, 0, 0) + { + } + SRay(const QT3DSVec3 &inOrigin, const QT3DSVec3 &inDirection) + : m_Origin(inOrigin) + , m_Direction(inDirection) + { + } + // If we are parallel, then no intersection of course. + Option Intersect(const NVPlane &inPlane) const; + + Option IntersectWithAABB(const QT3DSMat44 &inGlobalTransform, + const NVBounds3 &inBounds, + bool inForceIntersect = false) const; + + Option GetRelative(const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, + SBasisPlanes::Enum inPlane) const; + + Option GetRelativeXY(const QT3DSMat44 &inGlobalTransform, + const NVBounds3 &inBounds) const + { + return GetRelative(inGlobalTransform, inBounds, SBasisPlanes::XY); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp new file mode 100644 index 00000000..118c855d --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderRenderList.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "render/Qt3DSRenderBaseTypes.h" + +using namespace qt3ds::render; + +namespace { + +struct SRenderList : public IRenderList +{ + typedef eastl::pair TTaskIdTaskPair; + typedef nvvector TTaskList; + + NVFoundationBase &m_Foundation; + TTaskList m_Tasks; + QT3DSU32 m_NextTaskId; + QT3DSI32 mRefCount; + bool m_ScissorEnabled; + NVRenderRect m_ScissorRect; + NVRenderRect m_Viewport; + + SRenderList(NVFoundationBase &fnd) + : m_Foundation(fnd) + , m_Tasks(fnd.getAllocator(), "m_Tasks") + , m_NextTaskId(1) + , mRefCount(0) + , m_ScissorEnabled(false) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void BeginFrame() override + { + m_NextTaskId = 1; + m_Tasks.clear(); + } + + QT3DSU32 AddRenderTask(IRenderTask &inTask) override + { + QT3DSU32 taskId = m_NextTaskId; + ++m_NextTaskId; + m_Tasks.push_back(eastl::make_pair(taskId, &inTask)); + return taskId; + } + + void DiscardRenderTask(QT3DSU32 inTaskId) override + { + TTaskList::iterator iter, end; + for (iter = m_Tasks.begin(), end = m_Tasks.end(); iter != end && iter->first != inTaskId; + ++iter) { + } + if (iter != end) + m_Tasks.erase(iter); + } + // This runs through the added tasks in reverse order. This is used to render dependencies + // before rendering to the main render target. + void RunRenderTasks() override + { + for (TTaskList::reverse_iterator iter = m_Tasks.rbegin(), end = m_Tasks.rend(); iter != end; + ++iter) + iter->second->Run(); + BeginFrame(); + } + + void SetScissorTestEnabled(bool enabled) override { m_ScissorEnabled = enabled; } + void SetScissorRect(NVRenderRect rect) override { m_ScissorRect = rect; } + void SetViewport(NVRenderRect rect) override { m_Viewport = rect; } + bool IsScissorTestEnabled() const override { return m_ScissorEnabled; } + NVRenderRect GetScissor() const override { return m_ScissorRect; } + NVRenderRect GetViewport() const override { return m_Viewport; } +}; +} + +IRenderList &IRenderList::CreateRenderList(NVFoundationBase &fnd) +{ + return *QT3DS_NEW(fnd.getAllocator(), SRenderList)(fnd); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h new file mode 100644 index 00000000..dce9a95a --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RENDER_LIST_H +#define QT3DS_RENDER_RENDER_LIST_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + class IRenderTask + { + public: + virtual ~IRenderTask() {} + virtual void Run() = 0; + }; + + /** + * The render list exists so that dependencies of the main render target can render themselves + * completely before the main render target renders. From Maxwell GPU's on, we have a tiled + * architecture. This tiling mechanism is sensitive to switching the render target, so we would + * really like to render completely to a single render target and then switch. With our layered + * render architecture, this is not very feasible unless dependencies render themselves before + * the + * main set of layers render themselves. Furthermore it benefits the overall software + * architecture + * to have a distinct split between the prepare for render step and the render step and using + * this + * render list allows us to avoid some level of repeated tree traversal at the cost of some + * minimal + * per frame allocation. The rules for using the render list are that you need to add yourself + * before + * your dependencies do; the list is iterated in reverse during RunRenderTasks. So a layer adds + * itself + * (if it is going to render offscreen) before it runs through its renderable list to prepare + * each object + * because it is during the renderable prepare traversale that subpresentations will get added + * by + * the offscreen render manager. + */ + class IRenderList : public NVRefCounted + { + public: + // Called by the render context, do not call this. + virtual void BeginFrame() = 0; + + // Next tell all sub render target rendering systems to add themselves to the render list. + // At this point + // we agree to *not* have rendered anything, no clears or anything so if you are caching + // render state and you detect nothing has changed it may not be necessary to swap egl + // buffers. + virtual QT3DSU32 AddRenderTask(IRenderTask &inTask) = 0; + virtual void DiscardRenderTask(QT3DSU32 inTaskId) = 0; + // This runs through the added tasks in reverse order. This is used to render dependencies + // before rendering to the main render target. + virtual void RunRenderTasks() = 0; + + // We used to use GL state to pass information down the callstack. + // I have replaced those calls with this state here because that information + // controls how layers size themselves (which is quite a complicated process). + virtual void SetScissorTestEnabled(bool enabled) = 0; + virtual void SetScissorRect(NVRenderRect rect) = 0; + virtual void SetViewport(NVRenderRect rect) = 0; + virtual bool IsScissorTestEnabled() const = 0; + virtual NVRenderRect GetScissor() const = 0; + virtual NVRenderRect GetViewport() const = 0; + + static IRenderList &CreateRenderList(NVFoundationBase &inFnd); + }; + + // Now for scoped property access. + template + struct SRenderListScopedProperty + : public qt3ds::render::NVRenderGenericScopedProperty + { + typedef qt3ds::render::NVRenderGenericScopedProperty TBaseType; + typedef typename TBaseType::TGetter TGetter; + typedef typename TBaseType::TSetter TSetter; + SRenderListScopedProperty(IRenderList &ctx, TGetter getter, TSetter setter) + : TBaseType(ctx, getter, setter) + { + } + SRenderListScopedProperty(IRenderList &ctx, TGetter getter, TSetter setter, + const TDataType &inNewValue) + : TBaseType(ctx, getter, setter, inNewValue) + { + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRotationHelper.h b/src/Runtime/Source/runtimerender/Qt3DSRenderRotationHelper.h new file mode 100644 index 00000000..19ba8eb7 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRotationHelper.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_ROTATION_HELPER_H +#define QT3DS_RENDER_ROTATION_HELPER_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderNode.h" +#include "EASTL/utility.h" + +namespace qt3ds { +namespace render { + /** + * Unfortunately we still use an XYZ-Euler rotation system. This means that identical + *rotations + * can be represented in various ways. We need to ensure that the value that we write in the + * inspector palette are reasonable, however, and to do this we need a least-distance function + * from two different xyz tuples. + */ + + struct SRotationHelper + { + + // Attempt to go for negative values intead of large positive ones + // Goal is to keep the fabs of the angle low. + static QT3DSF32 ToMinimalAngle(QT3DSF32 value) + { + QT3DSF32 epsilon = (QT3DSF32)M_PI + .001f; + while (fabs(value) > epsilon) { + QT3DSF32 tpi = (QT3DSF32)(2.0f * M_PI); + if (value > 0.0f) + value -= tpi; + else + value += tpi; + } + return value; + } + + /** + * Convert an angle to a canonical form. Return this canonical form. + * + * The canonical form is defined as: + * 1. XYZ all positive. + * 2. XYZ all less than 360. + * + * To do this we rely on two identities, the first is that given an angle, adding + * (or subtracting) pi from all three components does not change the angle. + * + * The second is the obvious one that adding or subtracting 2*pi from any single + * component does not change the angle. + * + * Note that this function works in radian space. + */ + static QT3DSVec3 ToCanonicalFormStaticAxis(const QT3DSVec3 &inSrcAngle, QT3DSU32 inRotOrder) + { + // step 1 - reduce all components to less than 2*pi but greater than 0 + QT3DSVec3 retval(inSrcAngle); + retval.x = ToMinimalAngle(retval.x); + retval.y = ToMinimalAngle(retval.y); + retval.z = ToMinimalAngle(retval.z); + + // step 2 - if any two components are equal to or greater than pi + // then subtract pi from all three, then run two pi reduce again. + + QT3DSU32 greaterThanPiSum = 0; + QT3DSF32 pi = (QT3DSF32)M_PI; + for (QT3DSU32 idx = 0; idx < 3; ++idx) + if (fabs(retval[idx]) >= pi) + greaterThanPiSum++; + + if (greaterThanPiSum > 1) { + // For this identity to work, the middle axis angle needs to be subtracted from + // 180 instead of added to 180 because the previous axis *reversed* it. + QT3DSU32 theMiddleAxis = 0; + + switch (inRotOrder) { + case EulOrdXYZs: + theMiddleAxis = 1; + break; + case EulOrdXZYs: + theMiddleAxis = 2; + break; + case EulOrdYXZs: + theMiddleAxis = 0; + break; + case EulOrdYZXs: + theMiddleAxis = 2; + break; + case EulOrdZYXs: + theMiddleAxis = 1; + break; + case EulOrdZXYs: + theMiddleAxis = 0; + break; + case EulOrdXYZr: + theMiddleAxis = 1; + break; + case EulOrdXZYr: + theMiddleAxis = 2; + break; + case EulOrdYXZr: + theMiddleAxis = 0; + break; + case EulOrdYZXr: + theMiddleAxis = 2; + break; + case EulOrdZYXr: + theMiddleAxis = 1; + break; + case EulOrdZXYr: + theMiddleAxis = 0; + break; + default: + QT3DS_ASSERT(false); + return inSrcAngle; + } + for (QT3DSU32 idx = 0; idx < 3; ++idx) { + if (idx == theMiddleAxis) + retval[idx] = pi - retval[idx]; + else + retval[idx] = retval[idx] > 0.0f ? retval[idx] - pi : retval[idx] + pi; + } + } + return retval; + } + + static QT3DSVec3 ToMinimalAngleDiff(const QT3DSVec3 inDiff) + { + return QT3DSVec3(ToMinimalAngle(inDiff.x), ToMinimalAngle(inDiff.y), + ToMinimalAngle(inDiff.z)); + } + + /** + * Given an old angle and a new angle, return an angle has the same rotational value + * as the new angle *but* is as close to the old angle as possible. + * Works in radian space. This function doesn't currently work for euler angles or + * with Euler angles with repeating axis. + */ + static QT3DSVec3 ToNearestAngle(const QT3DSVec3 &inOldAngle, const QT3DSVec3 &inNewAngle, + QT3DSU32 inRotOrder) + { + switch (inRotOrder) { + case EulOrdXYZs: + case EulOrdXZYs: + case EulOrdYXZs: + case EulOrdYZXs: + case EulOrdZYXs: + case EulOrdZXYs: + case EulOrdXYZr: + case EulOrdXZYr: + case EulOrdYXZr: + case EulOrdYZXr: + case EulOrdZYXr: + case EulOrdZXYr: { + QT3DSVec3 oldA = ToCanonicalFormStaticAxis(inOldAngle, inRotOrder); + QT3DSVec3 newA = ToCanonicalFormStaticAxis(inNewAngle, inRotOrder); + QT3DSVec3 diff = newA - oldA; + return inOldAngle + ToMinimalAngleDiff(diff); + } break; + default: + return inNewAngle; + } + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.cpp new file mode 100644 index 00000000..0c7c4997 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.cpp @@ -0,0 +1,768 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderShaderCache.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSRenderString.h" +#include "foundation/XML.h" +#include "foundation/IOStreams.h" +#include "foundation/StringConversionImpl.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "foundation/FileTools.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderer.h" +#include +#include "foundation/Qt3DSTime.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "EASTL/sort.h" + +#include +#include + +using namespace qt3ds::render; + +namespace { +using qt3ds::render::NVRenderContextScopedProperty; +const char *TessellationEnabledStr = "TessellationStageEnabled"; +const char *GeometryEnabledStr = "GeometryStageEnabled"; +inline void AppendFlagValue(CRenderString &inStr, const char *flag) +{ + if (inStr.length()) + inStr.append(1, ','); + inStr.append(flag); +} +inline void CacheFlagsToStr(const SShaderCacheProgramFlags &inFlags, CRenderString &inString) +{ + inString.clear(); + if (inFlags.IsTessellationEnabled()) + AppendFlagValue(inString, TessellationEnabledStr); + if (inFlags.IsGeometryShaderEnabled()) + AppendFlagValue(inString, GeometryEnabledStr); +} + +struct ShaderType +{ + enum Enum { Vertex, TessControl, TessEval, Fragment, Geometry, Compute }; +}; + +inline ShaderType::Enum StringToShaderType(CRenderString &inShaderType) +{ + ShaderType::Enum retval = ShaderType::Vertex; + + if (inShaderType.size() == 0) + return retval; + + if (!inShaderType.compare("VertexCode")) + retval = ShaderType::Vertex; + else if (!inShaderType.compare("FragmentCode")) + retval = ShaderType::Fragment; + else if (!inShaderType.compare("TessControlCode")) + retval = ShaderType::TessControl; + else if (!inShaderType.compare("TessEvalCode")) + retval = ShaderType::TessEval; + else if (!inShaderType.compare("GeometryCode")) + retval = ShaderType::Geometry; + else + QT3DS_ASSERT(false); + + return retval; +} + +inline SShaderCacheProgramFlags CacheFlagsToStr(const CRenderString &inString) +{ + SShaderCacheProgramFlags retval; + if (inString.find(TessellationEnabledStr) != CRenderString::npos) + retval.SetTessellationEnabled(true); + if (inString.find(GeometryEnabledStr) != CRenderString::npos) + retval.SetGeometryShaderEnabled(true); + return retval; +} + +typedef eastl::pair TStringToContextValuePair; + +/*GLES2 = 1 << 0, +GL2 = 1 << 1, +GLES3 = 1 << 2, +GL3 = 1 << 3, +GL4 = 1 << 4, +NullContext = 1 << 5,*/ +TStringToContextValuePair g_StringToContextTypeValue[] = { + TStringToContextValuePair("GLES2", NVRenderContextValues::GLES2), + TStringToContextValuePair("GL2", NVRenderContextValues::GL2), + TStringToContextValuePair("GLES3", NVRenderContextValues::GLES3), + TStringToContextValuePair("GLES3PLUS", NVRenderContextValues::GLES3PLUS), + TStringToContextValuePair("GL3", NVRenderContextValues::GL3), + TStringToContextValuePair("GL4", NVRenderContextValues::GL4), + TStringToContextValuePair("NullContext", NVRenderContextValues::NullContext), +}; + +size_t g_NumStringToContextValueEntries = + sizeof(g_StringToContextTypeValue) / sizeof(*g_StringToContextTypeValue); + +inline void ContextTypeToString(qt3ds::render::NVRenderContextType inType, + CRenderString &outContextType) +{ + outContextType.clear(); + for (size_t idx = 0, end = g_NumStringToContextValueEntries; idx < end; ++idx) { + if (inType & g_StringToContextTypeValue[idx].second) { + if (outContextType.size()) + outContextType.append(1, '|'); + outContextType.append(g_StringToContextTypeValue[idx].first); + } + } +} + +inline qt3ds::render::NVRenderContextType StringToContextType(const CRenderString &inContextType) +{ + qt3ds::render::NVRenderContextType retval; + char tempBuffer[128]; + memZero(tempBuffer, 128); + const eastl::string::size_type lastTempBufIdx = 127; + eastl::string::size_type pos = 0, lastpos = 0; + if (inContextType.size() == 0) + return retval; + + do { + pos = int(inContextType.find('|', lastpos)); + if (pos == eastl::string::npos) + pos = int(inContextType.size()); + { + + eastl::string::size_type sectionLen = NVMin(pos - lastpos, lastTempBufIdx); + qt3ds::intrinsics::memCopy(tempBuffer, inContextType.c_str() + lastpos, sectionLen); + tempBuffer[lastTempBufIdx] = 0; + for (size_t idx = 0, end = g_NumStringToContextValueEntries; idx < end; ++idx) { + if (strcmp(g_StringToContextTypeValue[idx].first, tempBuffer) == 0) + retval = retval | g_StringToContextTypeValue[idx].second; + } + } + // iterate past the bar + ++pos; + lastpos = pos; + } while (pos < inContextType.size() && pos != eastl::string::npos); + + return retval; +} + +struct SShaderCacheKey +{ + CRegisteredString m_Key; + eastl::vector m_Features; + size_t m_HashCode; + + SShaderCacheKey(CRegisteredString key = CRegisteredString()) + : m_Key(key) + , m_HashCode(0) + { + } + + SShaderCacheKey(const SShaderCacheKey &other) + : m_Key(other.m_Key) + , m_Features(other.m_Features) + , m_HashCode(other.m_HashCode) + { + } + + SShaderCacheKey &operator=(const SShaderCacheKey &other) + { + m_Key = other.m_Key; + m_Features = other.m_Features; + m_HashCode = other.m_HashCode; + return *this; + } + + void GenerateHashCode() + { + m_HashCode = m_Key.hash(); + m_HashCode = m_HashCode + ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size())); + } + bool operator==(const SShaderCacheKey &inOther) const + { + return m_Key == inOther.m_Key && m_Features == inOther.m_Features; + } +}; +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SShaderCacheKey &inKey) const { return inKey.m_HashCode; } +}; +} + +namespace { + +struct ShaderCache : public IShaderCache +{ + typedef nvhash_map> TShaderMap; + NVRenderContext &m_RenderContext; + IPerfTimer &m_PerfTimer; + TShaderMap m_Shaders; + CRenderString m_CacheFilePath; + CRenderString m_VertexCode; + CRenderString m_TessCtrlCode; + CRenderString m_TessEvalCode; + CRenderString m_GeometryCode; + CRenderString m_FragmentCode; + CRenderString m_InsertStr; + CRenderString m_FlagString; + CRenderString m_ContextTypeString; + SShaderCacheKey m_TempKey; + + NVScopedRefCounted m_ShaderCache; + IInputStreamFactory &m_InputStreamFactory; + bool m_ShaderCompilationEnabled; + volatile QT3DSI32 mRefCount; + + ShaderCache(NVRenderContext &ctx, IInputStreamFactory &inInputStreamFactory, + IPerfTimer &inPerfTimer) + : m_RenderContext(ctx) + , m_PerfTimer(inPerfTimer) + , m_Shaders(ctx.GetAllocator(), "ShaderCache::m_Shaders") + , m_InputStreamFactory(inInputStreamFactory) + , m_ShaderCompilationEnabled(true) + , mRefCount(0) + { + } + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) + + NVRenderShaderProgram *GetProgram(CRegisteredString inKey, + NVConstDataRef inFeatures) override + { + m_TempKey.m_Key = inKey; + m_TempKey.m_Features.assign(inFeatures.begin(), inFeatures.end()); + m_TempKey.GenerateHashCode(); + TShaderMap::iterator theIter = m_Shaders.find(m_TempKey); + if (theIter != m_Shaders.end()) + return theIter->second; + return NULL; + } + + void AddBackwardCompatibilityDefines(ShaderType::Enum shaderType) + { + if (shaderType == ShaderType::Vertex || shaderType == ShaderType::TessControl + || shaderType == ShaderType::TessEval || shaderType == ShaderType::Geometry) { + m_InsertStr += "#define attribute in\n"; + m_InsertStr += "#define varying out\n"; + } else if (shaderType == ShaderType::Fragment) { + m_InsertStr += "#define varying in\n"; + m_InsertStr += "#define texture2D texture\n"; + m_InsertStr += "#define gl_FragColor fragOutput\n"; + + if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) + m_InsertStr += "layout(blend_support_all_equations) out;\n "; + m_InsertStr += "out vec4 fragOutput;\n"; + } + } + + void AddShaderExtensionStrings(ShaderType::Enum shaderType, bool isGLES) + { + if (isGLES) { + if (m_RenderContext.IsStandardDerivativesSupported()) + m_InsertStr += "#extension GL_OES_standard_derivatives : enable\n"; + else + m_InsertStr += "#extension GL_OES_standard_derivatives : disable\n"; + } + + if (IQt3DSRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) { + if (shaderType == ShaderType::TessControl || shaderType == ShaderType::TessEval) { + m_InsertStr += "#extension GL_EXT_tessellation_shader : enable\n"; + } else if (shaderType == ShaderType::Geometry) { + m_InsertStr += "#extension GL_EXT_geometry_shader : enable\n"; + } else if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment) { + if (m_RenderContext.GetRenderBackendCap(render::NVRenderBackend::NVRenderBackendCaps::gpuShader5)) + m_InsertStr += "#extension GL_EXT_gpu_shader5 : enable\n"; + if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) + m_InsertStr += "#extension GL_KHR_blend_equation_advanced : enable\n"; + } + } else { + if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment + || shaderType == ShaderType::Geometry) { + if (m_RenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) { + m_InsertStr += "#extension GL_ARB_gpu_shader5 : enable\n"; + m_InsertStr += "#extension GL_ARB_shading_language_420pack : enable\n"; + } + if (isGLES && m_RenderContext.IsTextureLodSupported()) + m_InsertStr += "#extension GL_EXT_shader_texture_lod : enable\n"; + if (m_RenderContext.IsShaderImageLoadStoreSupported()) + m_InsertStr += "#extension GL_ARB_shader_image_load_store : enable\n"; + if (m_RenderContext.IsAtomicCounterBufferSupported()) + m_InsertStr += "#extension GL_ARB_shader_atomic_counters : enable\n"; + if (m_RenderContext.IsStorageBufferSupported()) + m_InsertStr += "#extension GL_ARB_shader_storage_buffer_object : enable\n"; + if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) + m_InsertStr += "#extension GL_KHR_blend_equation_advanced : enable\n"; + } + } + } + + void AddShaderPreprocessor(CRenderString &str, CRegisteredString inKey, + ShaderType::Enum shaderType, + NVConstDataRef inFeatures) + { + // Don't use shading language version returned by the driver as it might + // differ from the context version. Instead use the context type to specify + // the version string. + bool isGlES = IQt3DSRenderer::IsGlEsContext(m_RenderContext.GetRenderContextType()); + m_InsertStr.clear(); + int minor = m_RenderContext.format().minorVersion(); + QString versionStr; + QTextStream stream(&versionStr); + stream << "#version "; + const QT3DSU32 type = (QT3DSU32)m_RenderContext.GetRenderContextType(); + switch (type) { + case NVRenderContextValues::GLES2: + stream << "1" << minor << "0\n"; + break; + case NVRenderContextValues::GL2: + stream << "1" << minor << "0\n"; + break; + case NVRenderContextValues::GLES3PLUS: + case NVRenderContextValues::GLES3: + stream << "3" << minor << "0 es\n"; + break; + case NVRenderContextValues::GL3: + if (minor == 3) + stream << "3" << minor << "0\n"; + else + stream << "1" << 3 + minor << "0\n"; + break; + case NVRenderContextValues::GL4: + stream << "4" << minor << "0\n"; + break; + default: + QT3DS_ASSERT(false); + break; + } + + m_InsertStr.append(versionStr.toLatin1().data()); + + if (isGlES) { + if (!IQt3DSRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) { + if (shaderType == ShaderType::Fragment) { + m_InsertStr += "#define fragOutput gl_FragData[0]\n"; + } + } else { + m_InsertStr += "#define texture2D texture\n"; + } + + // add extenions strings before any other non-processor token + AddShaderExtensionStrings(shaderType, isGlES); + + // add precision qualifier depending on backend + if (IQt3DSRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) { + m_InsertStr.append("precision highp float;\n" + "precision highp int;\n"); + if( m_RenderContext.GetRenderBackendCap(render::NVRenderBackend::NVRenderBackendCaps::gpuShader5) ) { + m_InsertStr.append("precision mediump sampler2D;\n" + "precision mediump sampler2DArray;\n" + "precision mediump sampler2DShadow;\n"); + if (m_RenderContext.IsShaderImageLoadStoreSupported()) { + m_InsertStr.append("precision mediump image2D;\n"); + } + } + + AddBackwardCompatibilityDefines(shaderType); + } else { + // GLES2 + m_InsertStr.append("precision mediump float;\n" + "precision mediump int;\n" + "#define texture texture2D\n"); + if (m_RenderContext.IsTextureLodSupported()) + m_InsertStr.append("#define textureLod texture2DLodEXT\n"); + else + m_InsertStr.append("#define textureLod(s, co, lod) texture2D(s, co)\n"); + } + } else { + if (!IQt3DSRenderer::IsGl2Context(m_RenderContext.GetRenderContextType())) { + m_InsertStr += "#define texture2D texture\n"; + + AddShaderExtensionStrings(shaderType, isGlES); + + m_InsertStr += "#if __VERSION__ >= 330\n"; + + AddBackwardCompatibilityDefines(shaderType); + + m_InsertStr += "#else\n"; + if (shaderType == ShaderType::Fragment) { + m_InsertStr += "#define fragOutput gl_FragData[0]\n"; + } + m_InsertStr += "#endif\n"; + } + } + + if (inKey.IsValid()) { + m_InsertStr += "//Shader name -"; + m_InsertStr += inKey.c_str(); + m_InsertStr += "\n"; + } + + if (shaderType == ShaderType::TessControl) { + m_InsertStr += "#define TESSELLATION_CONTROL_SHADER 1\n"; + m_InsertStr += "#define TESSELLATION_EVALUATION_SHADER 0\n"; + } else if (shaderType == ShaderType::TessEval) { + m_InsertStr += "#define TESSELLATION_CONTROL_SHADER 0\n"; + m_InsertStr += "#define TESSELLATION_EVALUATION_SHADER 1\n"; + } + + str.insert(0, m_InsertStr); + if (inFeatures.size()) { + eastl::string::size_type insertPos = int(m_InsertStr.size()); + m_InsertStr.clear(); + for (QT3DSU32 idx = 0, end = inFeatures.size(); idx < end; ++idx) { + SShaderPreprocessorFeature feature(inFeatures[idx]); + m_InsertStr.append("#define "); + m_InsertStr.append(inFeatures[idx].m_Name.c_str()); + m_InsertStr.append(" "); + m_InsertStr.append(feature.m_Enabled ? "1" : "0"); + m_InsertStr.append("\n"); + } + str.insert(insertPos, m_InsertStr); + } + } + // Compile this program overwriting any existing ones. + NVRenderShaderProgram * + ForceCompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, + const char8_t *inTessCtrl, const char8_t *inTessEval, const char8_t *inGeom, + const SShaderCacheProgramFlags &inFlags, + NVConstDataRef inFeatures, + bool separableProgram, bool fromDisk = false) override + { + if (m_ShaderCompilationEnabled == false) + return NULL; + SShaderCacheKey tempKey(inKey); + tempKey.m_Features.assign(inFeatures.begin(), inFeatures.end()); + tempKey.GenerateHashCode(); + + eastl::pair theInserter = m_Shaders.insert(tempKey); + if (fromDisk) { + qCInfo(TRACE_INFO) << "Loading from persistent shader cache: '<" + << tempKey.m_Key << ">'"; + } else { + qCInfo(TRACE_INFO) << "Compiling into shader cache: '" + << tempKey.m_Key << ">'"; + } + + if (!inVert) + inVert = ""; + if (!inTessCtrl) + inTessCtrl = ""; + if (!inTessEval) + inTessEval = ""; + if (!inGeom) + inGeom = ""; + if (!inFrag) + inFrag = ""; + + SStackPerfTimer __perfTimer(m_PerfTimer, "Shader Compilation"); + m_VertexCode.assign(inVert); + m_TessCtrlCode.assign(inTessCtrl); + m_TessEvalCode.assign(inTessEval); + m_GeometryCode.assign(inGeom); + m_FragmentCode.assign(inFrag); + // Add defines and such so we can write unified shaders that work across platforms. + // vertex and fragment shaders are optional for separable shaders + if (!separableProgram || !m_VertexCode.empty()) + AddShaderPreprocessor(m_VertexCode, inKey, ShaderType::Vertex, inFeatures); + if (!separableProgram || !m_FragmentCode.empty()) + AddShaderPreprocessor(m_FragmentCode, inKey, ShaderType::Fragment, inFeatures); + // optional shaders + if (inFlags.IsTessellationEnabled()) { + QT3DS_ASSERT(m_TessCtrlCode.size() && m_TessEvalCode.size()); + AddShaderPreprocessor(m_TessCtrlCode, inKey, ShaderType::TessControl, inFeatures); + AddShaderPreprocessor(m_TessEvalCode, inKey, ShaderType::TessEval, inFeatures); + } + if (inFlags.IsGeometryShaderEnabled()) + AddShaderPreprocessor(m_GeometryCode, inKey, ShaderType::Geometry, inFeatures); + + theInserter.first->second = + m_RenderContext + .CompileSource(inKey, m_VertexCode.c_str(), QT3DSU32(m_VertexCode.size()), + m_FragmentCode.c_str(), QT3DSU32(m_FragmentCode.size()), + m_TessCtrlCode.c_str(), QT3DSU32(m_TessCtrlCode.size()), + m_TessEvalCode.c_str(), QT3DSU32(m_TessEvalCode.size()), + m_GeometryCode.c_str(), QT3DSU32(m_GeometryCode.size()), + separableProgram).mShader; + if (theInserter.first->second) { + if (m_ShaderCache) { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "Program"); + m_ShaderCache->Att("key", inKey.c_str()); + CacheFlagsToStr(inFlags, m_FlagString); + if (m_FlagString.size()) + m_ShaderCache->Att("glflags", m_FlagString.c_str()); + // write out the GL version. + { + qt3ds::render::NVRenderContextType theContextType = + m_RenderContext.GetRenderContextType(); + ContextTypeToString(theContextType, m_ContextTypeString); + m_ShaderCache->Att("gl-context-type", m_ContextTypeString.c_str()); + } + if (inFeatures.size()) { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "Features"); + for (QT3DSU32 idx = 0, end = inFeatures.size(); idx < end; ++idx) { + m_ShaderCache->Att(inFeatures[idx].m_Name, inFeatures[idx].m_Enabled); + } + } + + { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "VertexCode"); + m_ShaderCache->Value(inVert); + } + { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "FragmentCode"); + m_ShaderCache->Value(inFrag); + } + if (m_TessCtrlCode.size()) { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "TessControlCode"); + m_ShaderCache->Value(inTessCtrl); + } + if (m_TessEvalCode.size()) { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "TessEvalCode"); + m_ShaderCache->Value(inTessEval); + } + if (m_GeometryCode.size()) { + IDOMWriter::Scope __writeScope(*m_ShaderCache, "GeometryCode"); + m_ShaderCache->Value(inGeom); + } + } + } + return theInserter.first->second; + } + + virtual NVRenderShaderProgram * + CompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, + const char8_t *inTessCtrl, const char8_t *inTessEval, const char8_t *inGeom, + const SShaderCacheProgramFlags &inFlags, + NVConstDataRef inFeatures, bool separableProgram) override + { + NVRenderShaderProgram *theProgram = GetProgram(inKey, inFeatures); + if (theProgram) + return theProgram; + + NVRenderShaderProgram *retval = + ForceCompileProgram(inKey, inVert, inFrag, inTessCtrl, inTessEval, inGeom, inFlags, + inFeatures, separableProgram); + if (m_CacheFilePath.c_str() && m_ShaderCache && m_ShaderCompilationEnabled) { + CFileSeekableIOStream theStream(m_CacheFilePath.c_str(), FileWriteFlags()); + if (theStream.IsOpen()) { + NVScopedRefCounted theStringTable( + IStringTable::CreateStringTable(m_RenderContext.GetAllocator())); + CDOMSerializer::WriteXMLHeader(theStream); + CDOMSerializer::Write(m_RenderContext.GetAllocator(), + *m_ShaderCache->GetTopElement(), theStream, *theStringTable); + } + } + return retval; + } + + void BootupDOMWriter() + { + NVScopedRefCounted theStringTable( + IStringTable::CreateStringTable(m_RenderContext.GetAllocator())); + m_ShaderCache = IDOMWriter::CreateDOMWriter(m_RenderContext.GetAllocator(), + "Qt3DSShaderCache", theStringTable) + .first; + m_ShaderCache->Att("cache_version", IShaderCache::GetShaderVersion()); + } + + void SetShaderCachePersistenceEnabled(const char8_t *inDirectory) override + { + if (inDirectory == NULL) { + m_ShaderCache = NULL; + return; + } + BootupDOMWriter(); + m_CacheFilePath = QDir(inDirectory).filePath(GetShaderCacheFileName()).toStdString(); + + NVScopedRefCounted theInStream = + m_InputStreamFactory.GetStreamForFile(m_CacheFilePath.c_str()); + if (theInStream) { + SStackPerfTimer __perfTimer(m_PerfTimer, "ShaderCache - Load"); + NVScopedRefCounted theStringTable( + IStringTable::CreateStringTable(m_RenderContext.GetAllocator())); + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_RenderContext.GetAllocator(), theStringTable)); + eastl::vector theFeatures; + + SDOMElement *theElem = CDOMSerializer::Read(*theFactory, *theInStream).second; + if (theElem) { + NVScopedRefCounted theReader = IDOMReader::CreateDOMReader( + m_RenderContext.GetAllocator(), *theElem, theStringTable, theFactory); + QT3DSU32 theAttValue = 0; + theReader->Att("cache_version", theAttValue); + if (theAttValue == IShaderCache::GetShaderVersion()) { + CRenderString loadVertexData; + CRenderString loadFragmentData; + CRenderString loadTessControlData; + CRenderString loadTessEvalData; + CRenderString loadGeometryData; + CRenderString shaderTypeString; + IStringTable &theStringTable(m_RenderContext.GetStringTable()); + for (bool success = theReader->MoveToFirstChild(); success; + success = theReader->MoveToNextSibling()) { + const char8_t *theKeyStr = NULL; + theReader->UnregisteredAtt("key", theKeyStr); + + CRegisteredString theKey = theStringTable.RegisterStr(theKeyStr); + if (theKey.IsValid()) { + m_FlagString.clear(); + const char8_t *theFlagStr = ""; + SShaderCacheProgramFlags theFlags; + if (theReader->UnregisteredAtt("glflags", theFlagStr)) { + m_FlagString.assign(theFlagStr); + theFlags = CacheFlagsToStr(m_FlagString); + } + + m_ContextTypeString.clear(); + if (theReader->UnregisteredAtt("gl-context-type", theFlagStr)) + m_ContextTypeString.assign(theFlagStr); + + theFeatures.clear(); + { + IDOMReader::Scope __featureScope(*theReader); + if (theReader->MoveToFirstChild("Features")) { + for (SDOMAttribute *theAttribute = + theReader->GetFirstAttribute(); + theAttribute; + theAttribute = theAttribute->m_NextAttribute) { + bool featureValue = false; + StringConversion().StrTo(theAttribute->m_Value, + featureValue); + theFeatures.push_back(SShaderPreprocessorFeature( + theStringTable.RegisterStr( + theAttribute->m_Name.c_str()), + featureValue)); + } + } + } + + qt3ds::render::NVRenderContextType theContextType = + StringToContextType(m_ContextTypeString); + if (((QT3DSU32)theContextType != 0) + && (theContextType & m_RenderContext.GetRenderContextType()) + == theContextType) { + IDOMReader::Scope __readerScope(*theReader); + loadVertexData.clear(); + loadFragmentData.clear(); + loadTessControlData.clear(); + loadTessEvalData.clear(); + loadGeometryData.clear(); + + // Vertex *MUST* be the first + // Todo deal with pure compute shader programs + if (theReader->MoveToFirstChild("VertexCode")) { + const char8_t *theValue = NULL; + theReader->Value(theValue); + loadVertexData.assign(theValue); + while (theReader->MoveToNextSibling()) { + theReader->Value(theValue); + + shaderTypeString.assign( + theReader->GetElementName().c_str()); + ShaderType::Enum shaderType = + StringToShaderType(shaderTypeString); + + if (shaderType == ShaderType::Fragment) + loadFragmentData.assign(theValue); + else if (shaderType == ShaderType::TessControl) + loadTessControlData.assign(theValue); + else if (shaderType == ShaderType::TessEval) + loadTessEvalData.assign(theValue); + else if (shaderType == ShaderType::Geometry) + loadGeometryData.assign(theValue); + } + } + + if (loadVertexData.size() + && (loadFragmentData.size() || loadGeometryData.size())) { + + NVRenderShaderProgram *theShader = ForceCompileProgram( + theKey, loadVertexData.c_str(), loadFragmentData.c_str(), + loadTessControlData.c_str(), loadTessEvalData.c_str(), + loadGeometryData.c_str(), theFlags, + qt3ds::foundation::toDataRef(theFeatures.data(), + (QT3DSU32)theFeatures.size()), + false, true /*fromDisk*/); + // If something doesn't save or load correctly, get the runtime + // to re-generate. + if (!theShader) + m_Shaders.erase(theKey); + } + } + } + } + } + } + } + } + + bool IsShaderCachePersistenceEnabled() const override { return m_ShaderCache != NULL; } + + void SetShaderCompilationEnabled(bool inEnableShaderCompilation) override + { + m_ShaderCompilationEnabled = inEnableShaderCompilation; + } +}; +} + +size_t qt3ds::render::HashShaderFeatureSet(NVConstDataRef inFeatureSet) +{ + size_t retval(0); + for (QT3DSU32 idx = 0, end = inFeatureSet.size(); idx < end; ++idx) { + // From previous implementation, it seems we need to ignore the order of the features. + // But we need to bind the feature flag together with its name, so that the flags will + // influence + // the final hash not only by the true-value count. + retval = retval + ^ (inFeatureSet[idx].m_Name.hash() * eastl::hash()(inFeatureSet[idx].m_Enabled)); + } + return retval; +} + +bool SShaderPreprocessorFeature::operator<(const SShaderPreprocessorFeature &other) const +{ + return strcmp(m_Name.c_str(), other.m_Name.c_str()) < 0; +} + +bool SShaderPreprocessorFeature::operator==(const SShaderPreprocessorFeature &other) const +{ + return m_Name == other.m_Name && m_Enabled == other.m_Enabled; +} + +IShaderCache &IShaderCache::CreateShaderCache(NVRenderContext &inContext, + IInputStreamFactory &inInputStreamFactory, + IPerfTimer &inPerfTimer) +{ + return *QT3DS_NEW(inContext.GetAllocator(), ShaderCache)(inContext, inInputStreamFactory, + inPerfTimer); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.h b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.h new file mode 100644 index 00000000..47e76f36 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCache.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_CACHE_H +#define QT3DS_RENDER_SHADER_CACHE_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + struct ShaderCacheProgramFlagValues + { + enum Enum { + TessellationEnabled = 1 << 0, // tessellation enabled + GeometryShaderEnabled = 1 << 1, // geometry shader enabled + }; + }; + struct SShaderCacheProgramFlags : public NVFlags + { + // tessellation enabled + void SetTessellationEnabled(bool inValue) + { + clearOrSet(inValue, ShaderCacheProgramFlagValues::TessellationEnabled); + } + bool IsTessellationEnabled() const + { + return this->operator&(ShaderCacheProgramFlagValues::TessellationEnabled); + } + // geometry shader enabled + void SetGeometryShaderEnabled(bool inValue) + { + clearOrSet(inValue, ShaderCacheProgramFlagValues::GeometryShaderEnabled); + } + bool IsGeometryShaderEnabled() const + { + return this->operator&(ShaderCacheProgramFlagValues::GeometryShaderEnabled); + } + }; + // There are a number of macros used to turn on or off various features. This allows those + // features + // to be propagated into the shader cache's caching mechanism. They will be translated into + //#define name value where value is 1 or zero depending on if the feature is enabled or not. + struct SShaderPreprocessorFeature + { + CRegisteredString m_Name; + bool m_Enabled; + SShaderPreprocessorFeature() + : m_Enabled(false) + { + } + SShaderPreprocessorFeature(CRegisteredString name, bool val) + : m_Name(name) + , m_Enabled(val) + { + } + bool operator<(const SShaderPreprocessorFeature &inOther) const; + bool operator==(const SShaderPreprocessorFeature &inOther) const; + }; + + typedef NVConstDataRef TShaderFeatureSet; + + inline TShaderFeatureSet ShaderCacheNoFeatures() { return TShaderFeatureSet(); } + + // Hash is dependent on the order of the keys; so make sure their order is consistent!! + size_t HashShaderFeatureSet(NVConstDataRef inFeatureSet); + + class IShaderCache : public NVRefCounted + { + protected: + virtual ~IShaderCache() {} + public: + // If directory is nonnull, then we attempt to load any shaders from shadercache.xml in + // inDirectory + // and save any new ones out to the same file. The shaders are marked by the gl version + // used when saving. + // If we can't open shadercache.xml from inDirectory for writing (at least), then we still + // consider the + // shadercache to be disabled. + // This call immediately blocks and attempts to load all applicable shaders from the + // shadercache.xml file in + // the given directory. + virtual void SetShaderCachePersistenceEnabled(const char8_t *inDirectory) = 0; + virtual bool IsShaderCachePersistenceEnabled() const = 0; + // It is up to the caller to ensure that inFeatures contains unique keys. + // It is also up the the caller to ensure the keys are ordered in some way. + virtual NVRenderShaderProgram * + GetProgram(CRegisteredString inKey, + NVConstDataRef inFeatures) = 0; + + // Replace an existing program in the cache for the same key with this program. + // The shaders returned by *CompileProgram functions can be released by this object + // due to ForceCompileProgram or SetProjectDirectory, so clients need to either not + // hold on to them or they need to addref/release them to ensure they still have + // access to them. + // The flags just tell us under what gl state to compile the program in order to hopefully + // reduce program compilations. + // It is up to the caller to ensure that inFeatures contains unique keys. + // It is also up the the caller to ensure the keys are ordered in some way. + virtual NVRenderShaderProgram * + ForceCompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, + const char8_t *inTessCtrl, const char8_t *inTessEval, + const char8_t *inGeom, const SShaderCacheProgramFlags &inFlags, + TShaderFeatureSet inFeatures, bool separableProgram, + bool fromDisk = false) = 0; + + // It is up to the caller to ensure that inFeatures contains unique keys. + // It is also up the the caller to ensure the keys are ordered in some way. + virtual NVRenderShaderProgram * + CompileProgram(CRegisteredString inKey, const char8_t *inVert, const char8_t *inFrag, + const char8_t *inTessCtrl, const char8_t *inTessEval, const char8_t *inGeom, + const SShaderCacheProgramFlags &inFlags, TShaderFeatureSet inFeatures, + bool separableProgram = false) = 0; + + // Used to disable any shader compilation during loading. This is used when we are just + // interested in going from uia->binary + // and we expect to run on a headless server of sorts. See the UICCompiler project for its + // only current use case. + virtual void SetShaderCompilationEnabled(bool inEnableShaderCompilation) = 0; + + // Upping the shader version invalidates all previous cache files. + static QT3DSU32 GetShaderVersion() { return 4; } + static const char8_t *GetShaderCacheFileName() { return "shadercache.xml"; } + + static IShaderCache &CreateShaderCache(NVRenderContext &inContext, + IInputStreamFactory &inInputStreamFactory, + IPerfTimer &inPerfTimer); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.cpp new file mode 100644 index 00000000..1cc9e9c7 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.cpp @@ -0,0 +1,526 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderShaderCodeGenerator.h" + +using namespace qt3ds::render; + +using eastl::make_pair; + +SShaderCodeGeneratorBase::SShaderCodeGeneratorBase(IStringTable &inStringTable, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType) + : m_StringTable(inStringTable) + , m_Codes(alloc, "SShaderCodeGenerator::m_Codes") + , m_Includes(alloc, "SShaderCodeGenerator::m_Includes") + , m_Uniforms(alloc, "SShaderCodeGenerator::m_Uniforms") + , m_ConstantBuffers(alloc, "SShaderCodeGenerator::m_ConstantBuffers") + , m_ConstantBufferParams(alloc, "SShaderCodeGenerator::m_ConstantBufferParams") + , m_Attributes(alloc, "SShaderCodeGenerator::m_Uniforms") + , m_RenderContextType(ctxType) +{ +} +void SShaderCodeGeneratorBase::Begin() +{ + m_Uniforms.clear(); + GetVaryings().clear(); + m_Attributes.clear(); + m_Includes.clear(); + m_Codes.clear(); + m_FinalShaderBuilder.clear(); + m_CodeBuilder.clear(); + m_ConstantBuffers.clear(); + m_ConstantBufferParams.clear(); +} +void SShaderCodeGeneratorBase::Append(const char *data) +{ + m_CodeBuilder.append(data); + m_CodeBuilder.append("\n"); +} +// don't add the newline +void SShaderCodeGeneratorBase::AppendPartial(const char *data) +{ + m_CodeBuilder.append(data); +} +void SShaderCodeGeneratorBase::AddUniform(const char *name, const char *type) +{ + m_Uniforms.insert(make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(type))); +} +void SShaderCodeGeneratorBase::AddUniform(TStrType &name, const char *type) +{ + AddUniform(name.c_str(), type); +} + +void SShaderCodeGeneratorBase::AddConstantBuffer(const char *name, const char *layout) +{ + m_ConstantBuffers.insert( + make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(layout))); +} +void SShaderCodeGeneratorBase::AddConstantBufferParam(const char *cbName, const char *paramName, + const char *type) +{ + TParamPair theParamPair(m_StringTable.RegisterStr(paramName), m_StringTable.RegisterStr(type)); + TConstantBufferParamPair theBufferParamPair(m_StringTable.RegisterStr(cbName), theParamPair); + m_ConstantBufferParams.push_back(theBufferParamPair); +} +void SShaderCodeGeneratorBase::AddAttribute(const char *name, const char *type) +{ + m_Attributes.insert( + make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(type))); +} +void SShaderCodeGeneratorBase::AddAttribute(TStrType &name, const char *type) +{ + AddAttribute(name.c_str(), type); +} +void SShaderCodeGeneratorBase::AddVarying(const char *name, const char *type) +{ + GetVaryings().insert( + make_pair(m_StringTable.RegisterStr(name), m_StringTable.RegisterStr(type))); +} +void SShaderCodeGeneratorBase::AddVarying(TStrType &name, const char *type) +{ + AddVarying(name.c_str(), type); +} +void SShaderCodeGeneratorBase::AddLocalVariable(const char *name, const char *type, int tabCount) +{ + for (; tabCount >= 0; --tabCount) + m_CodeBuilder.append("\t"); + m_CodeBuilder.append(type); + m_CodeBuilder.append(" "); + m_CodeBuilder.append(name); + m_CodeBuilder.append(";\n"); +} + +void SShaderCodeGeneratorBase::AddInclude(const char *name) +{ + m_Includes.insert(m_StringTable.RegisterStr(name)); +} +void SShaderCodeGeneratorBase::AddInclude(TStrType &name) +{ + AddInclude(name.c_str()); +} +void SShaderCodeGeneratorBase::AddLocalVariable(TStrType &name, const char *type, int tabCount) +{ + AddLocalVariable(name.c_str(), type, tabCount); +} +bool SShaderCodeGeneratorBase::HasCode(Enum value) +{ + return m_Codes.contains(value); +} +void SShaderCodeGeneratorBase::SetCode(Enum value) +{ + m_Codes.insert((QT3DSU32)value); +} + +void SShaderCodeGeneratorBase::SetupWorldPosition() +{ + if (!HasCode(WorldPosition)) { + SetCode(WorldPosition); + AddUniform("model_matrix", "mat4"); + Append("\tvec3 varWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); + } +} + +void SShaderCodeGeneratorBase::GenerateViewVector() +{ + if (!HasCode(ViewVector)) { + SetCode(ViewVector); + SetupWorldPosition(); + AddInclude("viewProperties.glsllib"); + Append("\tvec3 view_vector = normalize(camera_position - varWorldPos);"); + } +} + +void SShaderCodeGeneratorBase::GenerateWorldNormal() +{ + if (!HasCode(WorldNormal)) { + SetCode(WorldNormal); + AddAttribute("attr_norm", "vec3"); + AddUniform("normal_matrix", "mat3"); + Append("\tvec3 world_normal = normalize(normal_matrix * objectNormal).xyz;"); + } +} + +void SShaderCodeGeneratorBase::GenerateEnvMapReflection(SShaderCodeGeneratorBase &inFragmentShader) +{ + if (!HasCode(EnvMapReflection)) { + SetCode(EnvMapReflection); + SetupWorldPosition(); + GenerateWorldNormal(); + AddInclude("viewProperties.glsllib"); + AddVarying("var_object_to_camera", "vec3"); + Append("\tvar_object_to_camera = normalize( varWorldPos - camera_position );"); + // World normal cannot be relied upon in the vertex shader because of bump maps. + inFragmentShader.Append("\tvec3 environment_map_reflection = reflect( " + "vec3(var_object_to_camera.x, var_object_to_camera.y, " + "var_object_to_camera.z), world_normal.xyz );"); + inFragmentShader.Append("\tenvironment_map_reflection *= vec3( 0.5, 0.5, 0 );"); + inFragmentShader.Append("\tenvironment_map_reflection += vec3( 0.5, 0.5, 1.0 );"); + } +} + +void SShaderCodeGeneratorBase::GenerateUVCoords() +{ + if (!HasCode(UVCoords)) { + SetCode(UVCoords); + AddAttribute("attr_uv0", "vec2"); + Append("\tvec2 uv_coords = attr_uv0;"); + } +} + +void SShaderCodeGeneratorBase::GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, + eastl::basic_string &texSwizzle, + eastl::basic_string &lookupSwizzle) +{ + qt3ds::render::NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + + if (!(m_RenderContextType & deprecatedContextFlags)) { + switch (swizzleMode) { + case NVRenderTextureSwizzleMode::L8toR8: + case NVRenderTextureSwizzleMode::L16toR16: + texSwizzle.append(".rgb"); + lookupSwizzle.append(".rrr"); + break; + case NVRenderTextureSwizzleMode::L8A8toRG8: + texSwizzle.append(".rgba"); + lookupSwizzle.append(".rrrg"); + break; + case NVRenderTextureSwizzleMode::A8toR8: + texSwizzle.append(".a"); + lookupSwizzle.append(".r"); + break; + default: + break; + } + } +} + +void SShaderCodeGeneratorBase::GenerateShadedWireframeBase() +{ + // how this all work see + // http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf + Append("// project points to screen space\n" + "\tvec3 p0 = vec3(viewport_matrix * (gl_in[0].gl_Position / gl_in[0].gl_Position.w));\n" + "\tvec3 p1 = vec3(viewport_matrix * (gl_in[1].gl_Position / gl_in[1].gl_Position.w));\n" + "\tvec3 p2 = vec3(viewport_matrix * (gl_in[2].gl_Position / gl_in[2].gl_Position.w));\n" + "// compute triangle heights\n" + "\tfloat e1 = length(p1 - p2);\n" + "\tfloat e2 = length(p2 - p0);\n" + "\tfloat e3 = length(p1 - p0);\n" + "\tfloat alpha = acos( (e2*e2 + e3*e3 - e1*e1) / (2.0*e2*e3) );\n" + "\tfloat beta = acos( (e1*e1 + e3*e3 - e2*e2) / (2.0*e1*e3) );\n" + "\tfloat ha = abs( e3 * sin( beta ) );\n" + "\tfloat hb = abs( e3 * sin( alpha ) );\n" + "\tfloat hc = abs( e2 * sin( alpha ) );\n"); +} + +void SShaderCodeGeneratorBase::AddShaderItemMap(const char *itemType, + const TStrTableStrMap &itemMap) +{ + m_FinalShaderBuilder.append("\n"); + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; + ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(";\n"); + } +} + +void SShaderCodeGeneratorBase::AddShaderConstantBufferItemMap( + const char *itemType, const TStrTableStrMap &cbMap, TConstantBufferParamArray cbParamsArray) +{ + m_FinalShaderBuilder.append("\n"); + + // iterate over all constant buffers + for (TStrTableStrMap::const_iterator iter = cbMap.begin(), end = cbMap.end(); iter != end; + ++iter) { + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(" {\n"); + // iterate over all param entries and add match + for (TConstantBufferParamArray::const_iterator iter1 = cbParamsArray.begin(), + end = cbParamsArray.end(); + iter1 != end; ++iter1) { + if (iter1->first == iter->first) { + m_FinalShaderBuilder.append(iter1->second.second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter1->second.first); + m_FinalShaderBuilder.append(";\n"); + } + } + + m_FinalShaderBuilder.append("};\n"); + } +} + +const char *SShaderCodeGeneratorBase::BuildShaderSource() +{ + for (nvhash_set::const_iterator iter = m_Includes.begin(), + end = m_Includes.end(); + iter != end; ++iter) { + m_FinalShaderBuilder.append("#include \""); + m_FinalShaderBuilder.append(iter->c_str()); + m_FinalShaderBuilder.append("\"\n"); + } + AddShaderItemMap("attribute", m_Attributes); + AddShaderItemMap("uniform", m_Uniforms); + AddShaderConstantBufferItemMap("uniform", m_ConstantBuffers, m_ConstantBufferParams); + AddShaderItemMap("varying", GetVaryings()); + m_FinalShaderBuilder.append("\n"); + m_FinalShaderBuilder.append(m_CodeBuilder); + return m_FinalShaderBuilder.c_str(); +} +SShaderCodeGeneratorBase &SShaderCodeGeneratorBase::operator<<(const char *data) +{ + m_CodeBuilder.append(data); + return *this; +} +SShaderCodeGeneratorBase &SShaderCodeGeneratorBase::operator<<(const TStrType &data) +{ + m_CodeBuilder.append(data); + return *this; +} + +SShaderCodeGeneratorBase &SShaderCodeGeneratorBase::operator<<(const SEndlType & /*data*/) +{ + m_CodeBuilder.append("\n"); + return *this; +} + +SShaderVertexCodeGenerator::SShaderVertexCodeGenerator(IStringTable &inStringTable, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType) + : SShaderCodeGeneratorBase(inStringTable, alloc, ctxType) + , m_Varyings(alloc, "SShaderVertexCodeGenerator::m_Varyings") +{ +} +TStrTableStrMap &SShaderVertexCodeGenerator::GetVaryings() +{ + return m_Varyings; +} + +SShaderTessControlCodeGenerator::SShaderTessControlCodeGenerator( + SShaderVertexCodeGenerator &vert, NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType) + : SShaderCodeGeneratorBase(vert.m_StringTable, alloc, ctxType) + , m_VertGenerator(vert) + , m_Varyings(alloc, "SShaderTessControlCodeGenerator::m_Varyings") +{ +} + +// overwritten from base +void SShaderTessControlCodeGenerator::AddShaderItemMap(const char *itemType, + const TStrTableStrMap &itemMap) +{ + eastl::string extVtx(""); + eastl::string extTC(""); + eastl::string type(itemType); + if (!type.compare("varying")) { + extVtx = "[]"; + extTC = "TC[]"; + itemType = "attribute"; + } + + m_FinalShaderBuilder.append("\n"); + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; + ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(extVtx.c_str()); + m_FinalShaderBuilder.append(";\n"); + } + + // if this is varyings write output of tess control shader + if (!extVtx.empty()) { + m_FinalShaderBuilder.append("\n"); + itemType = "varying"; + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); + iter != end; ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(extTC.c_str()); + m_FinalShaderBuilder.append(";\n"); + } + } +} +TStrTableStrMap &SShaderTessControlCodeGenerator::GetVaryings() +{ + return m_VertGenerator.m_Varyings; +} + +SShaderTessEvalCodeGenerator::SShaderTessEvalCodeGenerator(SShaderTessControlCodeGenerator &tc, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType) + : SShaderCodeGeneratorBase(tc.m_StringTable, alloc, ctxType) + , m_TessControlGenerator(tc) + , m_hasGeometryStage(false) +{ +} +// overwritten from base +void SShaderTessEvalCodeGenerator::AddShaderItemMap(const char *itemType, + const TStrTableStrMap &itemMap) +{ + eastl::string extTC(""); + eastl::string extTE(""); + eastl::string type(itemType); + if (!type.compare("varying")) { + extTC = "TC[]"; + itemType = "attribute"; + } + if (m_hasGeometryStage) { + extTE = "TE"; + } + + m_FinalShaderBuilder.append("\n"); + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; + ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(extTC.c_str()); + m_FinalShaderBuilder.append(";\n"); + } + + // if this are varyings write output of tess eval shader + if (!extTC.empty()) { + m_FinalShaderBuilder.append("\n"); + itemType = "varying"; + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); + iter != end; ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(extTE.c_str()); + m_FinalShaderBuilder.append(";\n"); + } + } +} +TStrTableStrMap &SShaderTessEvalCodeGenerator::GetVaryings() +{ + return m_TessControlGenerator.m_VertGenerator.GetVaryings(); +} +void SShaderTessEvalCodeGenerator::SetGeometryStage(bool hasGeometryStage) +{ + m_hasGeometryStage = hasGeometryStage; +} + +SShaderGeometryCodeGenerator::SShaderGeometryCodeGenerator(SShaderVertexCodeGenerator &vert, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType) + : SShaderCodeGeneratorBase(vert.m_StringTable, alloc, ctxType) + , m_VertGenerator(vert) + , m_hasTessellationStage(true) +{ +} + +// overwritten from base +void SShaderGeometryCodeGenerator::AddShaderItemMap(const char *itemType, + const TStrTableStrMap &itemMap) +{ + eastl::string inExt(""); + eastl::string type(itemType); + if (!type.compare("varying")) { + itemType = "attribute"; + if (m_hasTessellationStage) + inExt = "TE[]"; + else + inExt = "[]"; + } + + m_FinalShaderBuilder.append("\n"); + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); iter != end; + ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(inExt.c_str()); + m_FinalShaderBuilder.append(";\n"); + } + + // if this are varyings write output of geometry shader + if (!type.compare("varying")) { + m_FinalShaderBuilder.append("\n"); + itemType = "varying"; + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); + iter != end; ++iter) { + m_FinalShaderBuilder.append(itemType); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->second); + m_FinalShaderBuilder.append(" "); + m_FinalShaderBuilder.append(iter->first); + m_FinalShaderBuilder.append(";\n"); + } + } +} +TStrTableStrMap &SShaderGeometryCodeGenerator::GetVaryings() +{ + return m_VertGenerator.m_Varyings; +} +void SShaderGeometryCodeGenerator::SetTessellationStage(bool hasTessellationStage) +{ + m_hasTessellationStage = hasTessellationStage; +} + +SShaderFragmentCodeGenerator::SShaderFragmentCodeGenerator(SShaderVertexCodeGenerator &vert, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType) + : SShaderCodeGeneratorBase(vert.m_StringTable, alloc, ctxType) + , m_VertGenerator(vert) +{ +} +TStrTableStrMap &SShaderFragmentCodeGenerator::GetVaryings() +{ + return m_VertGenerator.m_Varyings; +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.h b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.h new file mode 100644 index 00000000..80cbaaae --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGenerator.h @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_CODE_GENERATOR_H +#define QT3DS_RENDER_SHADER_CODE_GENERATOR_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSContainers.h" +#include "EASTL/string.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "Qt3DSRenderString.h" + +namespace qt3ds { +namespace render { + + struct SEndlType + { + }; + extern SEndlType Endl; + + typedef std::basic_string TStrType; + typedef eastl::pair TParamPair; + typedef eastl::pair TConstantBufferParamPair; + typedef nvvector TConstantBufferParamArray; + typedef nvhash_map TStrTableStrMap; + + struct SShaderCodeGeneratorBase + { + enum Enum { + Unknown = 0, + Lighting, + ViewVector, + WorldNormal, + WorldPosition, + EnvMapReflection, + UVCoords, + }; + IStringTable &m_StringTable; + nvhash_set m_Codes; // set of enums we have included. + nvhash_set m_Includes; + TStrTableStrMap m_Uniforms; + TStrTableStrMap m_ConstantBuffers; + TConstantBufferParamArray m_ConstantBufferParams; + TStrTableStrMap m_Attributes; + CRenderString m_FinalShaderBuilder; + TStrType m_CodeBuilder; + qt3ds::render::NVRenderContextType m_RenderContextType; + + SShaderCodeGeneratorBase(IStringTable &inStringTable, NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType); + virtual TStrTableStrMap &GetVaryings() = 0; + void Begin(); + void Append(const char *data); + // don't add the newline + void AppendPartial(const char *data); + void AddConstantBuffer(const char *name, const char *layout); + void AddConstantBufferParam(const char *cbName, const char *paramName, const char *type); + void AddUniform(const char *name, const char *type); + void AddUniform(TStrType &name, const char *type); + void AddAttribute(const char *name, const char *type); + void AddAttribute(TStrType &name, const char *type); + void AddVarying(const char *name, const char *type); + void AddVarying(TStrType &name, const char *type); + void AddLocalVariable(const char *name, const char *type, int tabCount = 1); + void AddLocalVariable(TStrType &name, const char *type, int tabCount = 1); + void AddInclude(const char *name); + void AddInclude(TStrType &name); + bool HasCode(Enum value); + void SetCode(Enum value); + void SetupWorldPosition(); + void GenerateViewVector(); + void GenerateWorldNormal(); + void GenerateEnvMapReflection(SShaderCodeGeneratorBase &inFragmentShader); + void GenerateUVCoords(); + void GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, + eastl::basic_string &texSwizzle, + eastl::basic_string &lookupSwizzle); + void GenerateShadedWireframeBase(); + void AddLighting(); + const char *BuildShaderSource(); + SShaderCodeGeneratorBase &operator<<(const char *data); + SShaderCodeGeneratorBase &operator<<(const TStrType &data); + SShaderCodeGeneratorBase &operator<<(const SEndlType & /*data*/); + + protected: + virtual void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap); + void AddShaderConstantBufferItemMap(const char *itemType, const TStrTableStrMap &cbMap, + TConstantBufferParamArray cbParamsArray); + }; + + struct SShaderVertexCodeGenerator : public SShaderCodeGeneratorBase + { + TStrTableStrMap m_Varyings; + SShaderVertexCodeGenerator(IStringTable &inStringTable, NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType); + TStrTableStrMap &GetVaryings() override; + }; + + struct SShaderTessControlCodeGenerator : public SShaderCodeGeneratorBase + { + SShaderVertexCodeGenerator &m_VertGenerator; + TStrTableStrMap m_Varyings; + SShaderTessControlCodeGenerator(SShaderVertexCodeGenerator &vert, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType); + + void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap) override; + TStrTableStrMap &GetVaryings() override; + }; + + struct SShaderTessEvalCodeGenerator : public SShaderCodeGeneratorBase + { + SShaderTessControlCodeGenerator &m_TessControlGenerator; + bool m_hasGeometryStage; + + SShaderTessEvalCodeGenerator(SShaderTessControlCodeGenerator &tc, + NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType); + + void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap) override; + TStrTableStrMap &GetVaryings() override; + virtual void SetGeometryStage(bool hasGeometryStage); + }; + + struct SShaderGeometryCodeGenerator : public SShaderCodeGeneratorBase + { + SShaderVertexCodeGenerator &m_VertGenerator; + bool m_hasTessellationStage; + + SShaderGeometryCodeGenerator(SShaderVertexCodeGenerator &vert, NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType); + + void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap) override; + TStrTableStrMap &GetVaryings() override; + virtual void SetTessellationStage(bool hasTessellationStage); + }; + + struct SShaderFragmentCodeGenerator : public SShaderCodeGeneratorBase + { + SShaderVertexCodeGenerator &m_VertGenerator; + SShaderFragmentCodeGenerator(SShaderVertexCodeGenerator &vert, NVAllocatorCallback &alloc, + qt3ds::render::NVRenderContextType ctxType); + TStrTableStrMap &GetVaryings() override; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.cpp new file mode 100644 index 00000000..173ba431 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.cpp @@ -0,0 +1,632 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderDynamicObjectSystem.h" + +#include + +using namespace qt3ds::render; + +namespace { +struct SStageGeneratorBase : public IShaderStageGenerator +{ + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + TStrTableStrMap m_Incoming; + TStrTableStrMap *m_Outgoing; + nvhash_set m_Includes; + TStrTableStrMap m_Uniforms; + TStrTableStrMap m_ConstantBuffers; + TConstantBufferParamArray m_ConstantBufferParams; + CRenderString m_CodeBuilder; + CRenderString m_FinalBuilder; + ShaderGeneratorStages::Enum m_Stage; + TShaderGeneratorStageFlags m_EnabledStages; + QStringList m_addedFunctions; + + SStageGeneratorBase(NVFoundationBase &inFnd, IStringTable &strTable, + ShaderGeneratorStages::Enum inStage) + + : m_Foundation(inFnd) + , m_StringTable(strTable) + , m_Incoming(inFnd.getAllocator(), "m_Incoming") + , m_Outgoing(NULL) + , m_Includes(inFnd.getAllocator(), "m_Includes") + , m_Uniforms(inFnd.getAllocator(), "m_Uniforms") + , m_ConstantBuffers(inFnd.getAllocator(), "m_ConstantBuffers") + , m_ConstantBufferParams(inFnd.getAllocator(), "m_ConstantBufferParams") + , m_Stage(inStage) + { + } + + virtual void Begin(TShaderGeneratorStageFlags inEnabledStages) + { + m_Incoming.clear(); + m_Outgoing = NULL; + m_Includes.clear(); + m_Uniforms.clear(); + m_ConstantBuffers.clear(); + m_ConstantBufferParams.clear(); + m_CodeBuilder.clear(); + m_FinalBuilder.clear(); + m_EnabledStages = inEnabledStages; + m_addedFunctions.clear(); + // the shared buffers will be cleared elsewhere. + } + + CRegisteredString Str(const char8_t *var) { return m_StringTable.RegisterStr(var); } + + void AddIncoming(const char8_t *name, const char8_t *type) override + { + m_Incoming.insert(eastl::make_pair(Str(name), Str(type))); + } + virtual const char8_t *GetIncomingVariableName() + { + return "in"; + } + + void AddIncoming(const TStrType &name, const char8_t *type) override + { + AddIncoming(name.c_str(), type); + } + void AddOutgoing(const char8_t *name, const char8_t *type) override + { + if (m_Outgoing == NULL) { + QT3DS_ASSERT(false); + return; + } + m_Outgoing->insert(eastl::make_pair(Str(name), Str(type))); + } + void AddOutgoing(const TStrType &name, const char8_t *type) override + { + AddOutgoing(name.c_str(), type); + } + + void AddUniform(const char8_t *name, const char8_t *type) override + { + m_Uniforms.insert(eastl::make_pair(Str(name), Str(type))); + } + void AddUniform(const TStrType &name, const char8_t *type) override + { + AddUniform(name.c_str(), type); + } + + void AddConstantBuffer(const char *name, const char *layout) override + { + m_ConstantBuffers.insert(eastl::make_pair(Str(name), Str(layout))); + } + void AddConstantBufferParam(const char *cbName, const char *paramName, const char *type) override + { + TParamPair theParamPair(m_StringTable.RegisterStr(paramName), + m_StringTable.RegisterStr(type)); + TConstantBufferParamPair theBufferParamPair(m_StringTable.RegisterStr(cbName), + theParamPair); + m_ConstantBufferParams.push_back(theBufferParamPair); + } + + IShaderStageGenerator &operator<<(const char *data) override + { + m_CodeBuilder.append(nonNull(data)); + return *this; + } + IShaderStageGenerator &operator<<(const TStrType &data) override + { + m_CodeBuilder.append(data); + return *this; + } + IShaderStageGenerator &operator<<(const SEndlType & /*data*/) override + { + m_CodeBuilder.append("\n"); + return *this; + } + void Append(const char *data) override + { + m_CodeBuilder.append(nonNull(data)); + m_CodeBuilder.append("\n"); + } + void AppendPartial(const char *data) override { m_CodeBuilder.append(nonNull(data)); } + ShaderGeneratorStages::Enum Stage() const override { return m_Stage; } + + virtual void AddShaderItemMap(const char *itemType, const TStrTableStrMap &itemMap, + const char8_t *inItemSuffix = "") + { + m_FinalBuilder.append("\n"); + + for (TStrTableStrMap::const_iterator iter = itemMap.begin(), end = itemMap.end(); + iter != end; ++iter) { + m_FinalBuilder.append(itemType); + m_FinalBuilder.append(" "); + m_FinalBuilder.append(iter->second); + m_FinalBuilder.append(" "); + m_FinalBuilder.append(iter->first); + m_FinalBuilder.append(inItemSuffix); + m_FinalBuilder.append(";\n"); + } + } + + virtual void AddShaderIncomingMap() { AddShaderItemMap(GetIncomingVariableName(), m_Incoming); } + + virtual void AddShaderUniformMap() { AddShaderItemMap("uniform", m_Uniforms); } + + virtual void AddShaderOutgoingMap() + { + if (m_Outgoing) + AddShaderItemMap("varying", *m_Outgoing); + } + + virtual void AddShaderConstantBufferItemMap(const char *itemType, const TStrTableStrMap &cbMap, + TConstantBufferParamArray cbParamsArray) + { + m_FinalBuilder.append("\n"); + + // iterate over all constant buffers + for (TStrTableStrMap::const_iterator iter = cbMap.begin(), end = cbMap.end(); iter != end; + ++iter) { + m_FinalBuilder.append(iter->second); + m_FinalBuilder.append(" "); + m_FinalBuilder.append(itemType); + m_FinalBuilder.append(" "); + m_FinalBuilder.append(iter->first); + m_FinalBuilder.append(" {\n"); + // iterate over all param entries and add match + for (TConstantBufferParamArray::const_iterator iter1 = cbParamsArray.begin(), + end = cbParamsArray.end(); + iter1 != end; ++iter1) { + if (iter1->first == iter->first) { + m_FinalBuilder.append(iter1->second.second); + m_FinalBuilder.append(" "); + m_FinalBuilder.append(iter1->second.first); + m_FinalBuilder.append(";\n"); + } + } + + m_FinalBuilder.append("};\n"); + } + } + + virtual void AppendShaderCode() { m_FinalBuilder.append(m_CodeBuilder); } + + virtual void UpdateShaderCacheFlags(SShaderCacheProgramFlags &) {} + + void AddInclude(const char8_t *name) override { m_Includes.insert(Str(name)); } + + void AddInclude(const TStrType &name) override { AddInclude(name.c_str()); } + + void AddInclude(const QString &name) override + { + QByteArray arr = name.toLatin1(); + AddInclude(arr.data()); + } + + virtual const char8_t *BuildShaderSource() + { + for (nvhash_set::const_iterator iter = m_Includes.begin(), + end = m_Includes.end(); + iter != end; ++iter) { + m_FinalBuilder.append("#include \""); + m_FinalBuilder.append(iter->c_str()); + m_FinalBuilder.append("\"\n"); + } + AddShaderIncomingMap(); + AddShaderUniformMap(); + AddShaderConstantBufferItemMap("uniform", m_ConstantBuffers, m_ConstantBufferParams); + AddShaderOutgoingMap(); + m_FinalBuilder.append("\n"); + AppendShaderCode(); + return m_FinalBuilder.c_str(); + } + + void AddFunction(const QString &functionName) override + { + if (!m_addedFunctions.contains(functionName)) { + m_addedFunctions.push_back(functionName); + QString includeName; + QTextStream stream(&includeName); + stream << "func" << functionName << ".glsllib"; + AddInclude(includeName); + } + } +}; + +struct SVertexShaderGenerator : public SStageGeneratorBase +{ + SVertexShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) + : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Vertex) + { + } + + const char8_t *GetIncomingVariableName() override { return "attribute"; } + virtual void AddIncomingInterpolatedMap() {} + + virtual const char8_t *GetInterpolatedIncomingSuffix() const { return "_attr"; } + virtual const char8_t *GetInterpolatedOutgoingSuffix() const { return ""; } +}; + +struct STessControlShaderGenerator : public SStageGeneratorBase +{ + STessControlShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) + : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::TessControl) + { + } + + void AddShaderIncomingMap() override { AddShaderItemMap("attribute", m_Incoming, "[]"); } + + void AddShaderOutgoingMap() override + { + if (m_Outgoing) + AddShaderItemMap("varying", *m_Outgoing, "[]"); + } + + void UpdateShaderCacheFlags(SShaderCacheProgramFlags &inFlags) override + { + inFlags.SetTessellationEnabled(true); + } +}; + +struct STessEvalShaderGenerator : public SStageGeneratorBase +{ + STessEvalShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) + : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::TessEval) + { + } + + void AddShaderIncomingMap() override { AddShaderItemMap("attribute", m_Incoming, "[]"); } + + void UpdateShaderCacheFlags(SShaderCacheProgramFlags &inFlags) override + { + inFlags.SetTessellationEnabled(true); + } +}; + +struct SGeometryShaderGenerator : public SStageGeneratorBase +{ + SGeometryShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) + : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Geometry) + { + } + + void AddShaderIncomingMap() override { AddShaderItemMap("attribute", m_Incoming, "[]"); } + + void AddShaderOutgoingMap() override + { + if (m_Outgoing) + AddShaderItemMap("varying", *m_Outgoing); + } + void UpdateShaderCacheFlags(SShaderCacheProgramFlags &inFlags) override + { + inFlags.SetGeometryShaderEnabled(true); + } +}; + +struct SFragmentShaderGenerator : public SStageGeneratorBase +{ + SFragmentShaderGenerator(NVFoundationBase &inFnd, IStringTable &strTable) + : SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Fragment) + { + } + void AddShaderIncomingMap() override { AddShaderItemMap("varying", m_Incoming); } + void AddShaderOutgoingMap() override {} +}; + +struct SShaderGeneratedProgramOutput +{ + // never null; so safe to call strlen on. + const char8_t *m_VertexShader; + const char8_t *m_TessControlShader; + const char8_t *m_TessEvalShader; + const char8_t *m_GeometryShader; + const char8_t *m_FragmentShader; + + SShaderGeneratedProgramOutput() + : m_VertexShader("") + , m_TessControlShader("") + , m_TessEvalShader("") + , m_GeometryShader("") + , m_FragmentShader("") + { + } + + SShaderGeneratedProgramOutput(const char8_t *vs, const char8_t *tc, const char8_t *te, + const char8_t *gs, const char8_t *fs) + : m_VertexShader(vs) + , m_TessControlShader(tc) + , m_TessEvalShader(te) + , m_GeometryShader(gs) + , m_FragmentShader(fs) + { + } +}; + +struct SProgramGenerator : public IShaderProgramGenerator +{ + IQt3DSRenderContext &m_Context; + SVertexShaderGenerator m_VS; + STessControlShaderGenerator m_TC; + STessEvalShaderGenerator m_TE; + SGeometryShaderGenerator m_GS; + SFragmentShaderGenerator m_FS; + + TShaderGeneratorStageFlags m_EnabledStages; + + QT3DSI32 m_RefCount; + + SProgramGenerator(IQt3DSRenderContext &inContext) + : m_Context(inContext) + , m_VS(inContext.GetFoundation(), inContext.GetStringTable()) + , m_TC(inContext.GetFoundation(), inContext.GetStringTable()) + , m_TE(inContext.GetFoundation(), inContext.GetStringTable()) + , m_GS(inContext.GetFoundation(), inContext.GetStringTable()) + , m_FS(inContext.GetFoundation(), inContext.GetStringTable()) + , m_RefCount(0) + { + } + + void addRef() override { atomicIncrement(&m_RefCount); } + void release() override + { + atomicDecrement(&m_RefCount); + if (m_RefCount <= 0) { + NVFoundationBase &theFoundation(m_Context.GetFoundation()); + NVDelete(theFoundation.getAllocator(), this); + } + } + + void LinkStages() + { + // Link stages incoming to outgoing variables. + SStageGeneratorBase *previous = NULL; + QT3DSU32 theStageId = 1; + for (QT3DSU32 idx = 0, end = (QT3DSU32)ShaderGeneratorStages::StageCount; idx < end; + ++idx, theStageId = theStageId << 1) { + SStageGeneratorBase *thisStage = NULL; + ShaderGeneratorStages::Enum theStageEnum = + static_cast(theStageId); + if ((m_EnabledStages & theStageEnum)) { + thisStage = &InternalGetStage(theStageEnum); + if (previous) + previous->m_Outgoing = &thisStage->m_Incoming; + previous = thisStage; + } + } + } + + void BeginProgram(TShaderGeneratorStageFlags inEnabledStages) override + { + m_VS.Begin(inEnabledStages); + m_TC.Begin(inEnabledStages); + m_TE.Begin(inEnabledStages); + m_GS.Begin(inEnabledStages); + m_FS.Begin(inEnabledStages); + m_EnabledStages = inEnabledStages; + LinkStages(); + } + + TShaderGeneratorStageFlags GetEnabledStages() const override { return m_EnabledStages; } + + SStageGeneratorBase &InternalGetStage(ShaderGeneratorStages::Enum inStage) + { + switch (inStage) { + case ShaderGeneratorStages::Vertex: + return m_VS; + case ShaderGeneratorStages::TessControl: + return m_TC; + case ShaderGeneratorStages::TessEval: + return m_TE; + case ShaderGeneratorStages::Geometry: + return m_GS; + case ShaderGeneratorStages::Fragment: + return m_FS; + default: + QT3DS_ASSERT(false); + break; + } + return m_VS; + } + // get the stage or NULL if it has not been created. + IShaderStageGenerator *GetStage(ShaderGeneratorStages::Enum inStage) override + { + if (inStage > 0 || inStage < ShaderGeneratorStages::StageCount) { + if ((m_EnabledStages & inStage)) + return &InternalGetStage(inStage); + } else { + QT3DS_ASSERT(false); + } + return NULL; + } + + qt3ds::render::NVRenderShaderProgram * + CompileGeneratedShader(const char *inShaderName, const SShaderCacheProgramFlags &inFlags, + TShaderFeatureSet inFeatureSet, bool separableProgram) override + { + // No stages enabled + if (((QT3DSU32)m_EnabledStages) == 0) { + QT3DS_ASSERT(false); + return NULL; + } + + qt3ds::render::IDynamicObjectSystem &theDynamicSystem(m_Context.GetDynamicObjectSystem()); + SShaderCacheProgramFlags theCacheFlags(inFlags); + for (QT3DSU32 stageIdx = 0, stageEnd = ShaderGeneratorStages::StageCount; stageIdx < stageEnd; + ++stageIdx) { + ShaderGeneratorStages::Enum stageName = + static_cast(1 << stageIdx); + if (m_EnabledStages & stageName) { + SStageGeneratorBase &theStage(InternalGetStage(stageName)); + theStage.BuildShaderSource(); + theStage.UpdateShaderCacheFlags(theCacheFlags); + theDynamicSystem.InsertShaderHeaderInformation(theStage.m_FinalBuilder, + inShaderName); + } + } + + const char *vertexShaderSource = m_VS.m_FinalBuilder.c_str(); + const char *tcShaderSource = m_TC.m_FinalBuilder.c_str(); + const char *teShaderSource = m_TE.m_FinalBuilder.c_str(); + const char *geShaderSource = m_GS.m_FinalBuilder.c_str(); + const char *fragmentShaderSource = m_FS.m_FinalBuilder.c_str(); + + IShaderCache &theCache = m_Context.GetShaderCache(); + CRegisteredString theCacheKey = m_Context.GetStringTable().RegisterStr(inShaderName); + return theCache.CompileProgram(theCacheKey, vertexShaderSource, fragmentShaderSource, + tcShaderSource, teShaderSource, geShaderSource, + theCacheFlags, inFeatureSet, separableProgram); + } +}; +}; + +IShaderProgramGenerator & +IShaderProgramGenerator::CreateProgramGenerator(IQt3DSRenderContext &inContext) +{ + return *QT3DS_NEW(inContext.GetAllocator(), SProgramGenerator)(inContext); +} + +void IShaderProgramGenerator::OutputParaboloidDepthVertex(IShaderStageGenerator &vertexShader) +{ + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddInclude("shadowMapping.glsllib"); + vertexShader.AddUniform("model_view_projection", "mat4"); + // vertexShader.AddUniform("model_view", "mat4"); + vertexShader.AddUniform("camera_properties", "vec2"); + // vertexShader.AddOutgoing("view_pos", "vec4"); + vertexShader.AddOutgoing("world_pos", "vec4"); + + // Project the location onto screen space. + // This will be horrible if you have a single large polygon. Tessellation is your friend here! + vertexShader.Append("void main() {"); + vertexShader.Append( + " ParaboloidMapResult data = VertexParaboloidDepth( attr_pos, model_view_projection );"); + vertexShader.Append(" gl_Position = data.m_Position;"); + vertexShader.Append(" world_pos = data.m_WorldPos;"); + vertexShader.Append("}"); +} + +void IShaderProgramGenerator::OutputParaboloidDepthTessEval(IShaderStageGenerator &tessEvalShader) +{ + tessEvalShader.AddInclude("shadowMapping.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append(" ParaboloidMapResult data = VertexParaboloidDepth( vec3(pos.xyz), " + "model_view_projection );"); + tessEvalShader.Append(" gl_Position = data.m_Position;"); + tessEvalShader.Append(" world_pos = data.m_WorldPos;"); +} + +void IShaderProgramGenerator::OutputParaboloidDepthFragment(IShaderStageGenerator &fragmentShader) +{ + fragmentShader.AddInclude("shadowMappingFragment.glsllib"); + fragmentShader.AddUniform("model_view_projection", "mat4"); + fragmentShader.AddUniform("camera_properties", "vec2"); + fragmentShader.Append("void main() {"); + fragmentShader.Append(" gl_FragDepth = FragmentParaboloidDepth( world_pos, " + "model_view_projection, camera_properties );"); + fragmentShader.Append("}"); +} + +void IShaderProgramGenerator::OutputCubeFaceDepthVertex(IShaderStageGenerator &vertexShader) +{ + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddUniform("model_matrix", "mat4"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.AddOutgoing("raw_pos", "vec4"); + vertexShader.AddOutgoing("world_pos", "vec4"); + + vertexShader.Append("void main() {"); + vertexShader.Append(" world_pos = model_matrix * vec4( attr_pos, 1.0 );"); + vertexShader.Append(" world_pos /= world_pos.w;"); + vertexShader.Append(" gl_Position = model_view_projection * vec4( attr_pos, 1.0 );"); + vertexShader.Append(" raw_pos = vec4( attr_pos, 1.0 );"); + // vertexShader.Append(" gl_Position = vec4( attr_pos, 1.0 );"); + vertexShader.Append("}"); +} + +void IShaderProgramGenerator::OutputCubeFaceDepthGeometry(IShaderStageGenerator &geometryShader) +{ + geometryShader.Append("layout(triangles) in;"); + geometryShader.Append("layout(triangle_strip, max_vertices = 18) out;"); + // geometryShader.AddUniform("shadow_mvp[6]", "mat4"); + + geometryShader.AddUniform("shadow_mv0", "mat4"); + geometryShader.AddUniform("shadow_mv1", "mat4"); + geometryShader.AddUniform("shadow_mv2", "mat4"); + geometryShader.AddUniform("shadow_mv3", "mat4"); + geometryShader.AddUniform("shadow_mv4", "mat4"); + geometryShader.AddUniform("shadow_mv5", "mat4"); + geometryShader.AddUniform("projection", "mat4"); + + geometryShader.AddUniform("model_matrix", "mat4"); + geometryShader.AddOutgoing("world_pos", "vec4"); + + geometryShader.Append("void main() {"); + geometryShader.Append(" mat4 layerMVP[6];"); + geometryShader.Append(" layerMVP[0] = projection * shadow_mv0;"); + geometryShader.Append(" layerMVP[1] = projection * shadow_mv1;"); + geometryShader.Append(" layerMVP[2] = projection * shadow_mv2;"); + geometryShader.Append(" layerMVP[3] = projection * shadow_mv3;"); + geometryShader.Append(" layerMVP[4] = projection * shadow_mv4;"); + geometryShader.Append(" layerMVP[5] = projection * shadow_mv5;"); + geometryShader.Append(" for (int i = 0; i < 6; ++i)"); + geometryShader.Append(" {"); + geometryShader.Append(" gl_Layer = i;"); + geometryShader.Append(" for(int j = 0; j < 3; ++j)"); + geometryShader.Append(" {"); + geometryShader.Append(" world_pos = model_matrix * raw_pos[j];"); + geometryShader.Append(" world_pos /= world_pos.w;"); + geometryShader.Append(" gl_Position = layerMVP[j] * raw_pos[j];"); + geometryShader.Append(" world_pos.w = gl_Position.w;"); + geometryShader.Append(" EmitVertex();"); + geometryShader.Append(" }"); + geometryShader.Append(" EndPrimitive();"); + geometryShader.Append(" }"); + geometryShader.Append("}"); +} + +void IShaderProgramGenerator::OutputCubeFaceDepthFragment(IShaderStageGenerator &fragmentShader) +{ + fragmentShader.AddUniform("camera_position", "vec3"); + fragmentShader.AddUniform("camera_properties", "vec2"); + + fragmentShader.Append("void main() {"); + fragmentShader.Append( + "\tvec3 camPos = vec3( camera_position.x, camera_position.y, -camera_position.z );"); + fragmentShader.Append("\tfloat dist = length( world_pos.xyz - camPos );"); + fragmentShader.Append( + "\tdist = (dist - camera_properties.x) / (camera_properties.y - camera_properties.x);"); + // fragmentShader.Append("\tgl_FragDepth = dist;"); + fragmentShader.Append("\tfragOutput = vec4(dist, dist, dist, 1.0);"); + fragmentShader.Append("}"); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.h b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.h new file mode 100644 index 00000000..23892c5c --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderCodeGeneratorV2.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_CODE_GENERATOR_V2_H +#define QT3DS_RENDER_SHADER_CODE_GENERATOR_V2_H +#include "Qt3DSRenderShaderCodeGenerator.h" +#include "Qt3DSRenderShaderCache.h" +#include "foundation/Qt3DSFlags.h" + +#include + +namespace qt3ds { +namespace render { + // So far the generator is only useful for graphics stages, + // it doesn't seem useful for compute stages. + struct ShaderGeneratorStages + { + enum Enum { + Vertex = 1, + TessControl = 1 << 1, + TessEval = 1 << 2, + Geometry = 1 << 3, + Fragment = 1 << 4, + StageCount = 5, + }; + }; + + typedef NVFlags TShaderGeneratorStageFlags; + + class IShaderStageGenerator + { + protected: + virtual ~IShaderStageGenerator() {} + public: + virtual void AddIncoming(const char8_t *name, const char8_t *type) = 0; + virtual void AddIncoming(const TStrType &name, const char8_t *type) = 0; + + virtual void AddOutgoing(const char8_t *name, const char8_t *type) = 0; + virtual void AddOutgoing(const TStrType &name, const char8_t *type) = 0; + + virtual void AddUniform(const char8_t *name, const char8_t *type) = 0; + virtual void AddUniform(const TStrType &name, const char8_t *type) = 0; + + virtual void AddInclude(const char8_t *name) = 0; + virtual void AddInclude(const TStrType &name) = 0; + virtual void AddInclude(const QString &name) = 0; + + virtual void AddFunction(const QString &functionName) = 0; + + virtual void AddConstantBuffer(const char *name, const char *layout) = 0; + virtual void AddConstantBufferParam(const char *cbName, const char *paramName, + const char *type) = 0; + + virtual IShaderStageGenerator &operator<<(const char *data) = 0; + virtual IShaderStageGenerator &operator<<(const TStrType &data) = 0; + virtual IShaderStageGenerator &operator<<(const SEndlType & /*data*/) = 0; + virtual void Append(const char *data) = 0; + virtual void AppendPartial(const char *data) = 0; + + virtual ShaderGeneratorStages::Enum Stage() const = 0; + }; + + class IShaderProgramGenerator : public NVRefCounted + { + public: + static TShaderGeneratorStageFlags DefaultFlags() + { + return TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex + | ShaderGeneratorStages::Fragment); + } + virtual void BeginProgram(TShaderGeneratorStageFlags inEnabledStages = DefaultFlags()) = 0; + + virtual TShaderGeneratorStageFlags GetEnabledStages() const = 0; + + // get the stage or NULL if it has not been created. + virtual IShaderStageGenerator *GetStage(ShaderGeneratorStages::Enum inStage) = 0; + + // Implicit call to end program. + virtual qt3ds::render::NVRenderShaderProgram * + CompileGeneratedShader(const char *inShaderName, const SShaderCacheProgramFlags &inFlags, + TShaderFeatureSet inFeatureSet, bool separableProgram = false) = 0; + + qt3ds::render::NVRenderShaderProgram *CompileGeneratedShader(const char *inShaderName, + bool separableProgram = false) + { + return CompileGeneratedShader(inShaderName, SShaderCacheProgramFlags(), + TShaderFeatureSet(), separableProgram); + } + + static IShaderProgramGenerator &CreateProgramGenerator(IQt3DSRenderContext &inContext); + + static void OutputParaboloidDepthVertex(IShaderStageGenerator &inGenerator); + // By convention, the local space result of the TE is stored in vec4 pos local variable. + // This function expects such state. + static void OutputParaboloidDepthTessEval(IShaderStageGenerator &inGenerator); + // Utilities shared among the various different systems. + static void OutputParaboloidDepthFragment(IShaderStageGenerator &inGenerator); + + static void OutputCubeFaceDepthVertex(IShaderStageGenerator &inGenerator); + static void OutputCubeFaceDepthGeometry(IShaderStageGenerator &inGenerator); + static void OutputCubeFaceDepthFragment(IShaderStageGenerator &inGenerator); + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShaderKeys.h b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderKeys.h new file mode 100644 index 00000000..5d02e414 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShaderKeys.h @@ -0,0 +1,802 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_KEY_H +#define QT3DS_RENDER_SHADER_KEY_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSDataRef.h" +#include "EASTL/string.h" +#include "foundation/StringConversionImpl.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderTessModeValues.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + // We have an ever expanding set of properties we like to hash into one or more 32 bit + // quantities. + // Furthermore we would like this set of properties to be convertable to string + // So the shader cache file itself is somewhat human readable/diagnosable. + // To do this we create a set of objects that act as properties to the master shader key. + // These objects are tallied in order to figure out their actual offset into the shader key's + // data store. They are also run through in order to create the string shader cache key. + + struct SShaderKeyPropertyBase + { + const char *m_Name; + QT3DSU32 m_Offset; + SShaderKeyPropertyBase(const char *name = "") + : m_Name(name) + , m_Offset(0) + { + } + QT3DSU32 GetOffset() const { return m_Offset; } + void SetOffset(QT3DSU32 of) { m_Offset = of; } + + template + QT3DSU32 GetMaskTemplate() const + { + QT3DSU32 bit = m_Offset % 32; + QT3DSU32 startValue = (1 << TBitWidth) - 1; + QT3DSU32 mask = startValue << bit; + return mask; + } + + QT3DSU32 GetIdx() const { return m_Offset / 32; } + protected: + void InternalToString(eastl::string &ioStr, const char *inBuffer) const + { + ioStr.append(m_Name); + ioStr.append("="); + ioStr.append(inBuffer); + } + + static void InternalToString(eastl::string &ioStr, const char *name, bool inValue) + { + if (inValue) { + ioStr.append(name); + ioStr.append("="); + ioStr.append(inValue ? "true" : "false"); + } + } + }; + + struct SShaderKeyBoolean : public SShaderKeyPropertyBase + { + enum { + BitWidth = 1, + }; + + SShaderKeyBoolean(const char *name = "") + : SShaderKeyPropertyBase(name) + { + } + + QT3DSU32 GetMask() const { return GetMaskTemplate(); } + void SetValue(NVDataRef inDataStore, bool inValue) const + { + QT3DSU32 idx = GetIdx(); + QT3DS_ASSERT(inDataStore.size() > idx); + QT3DSU32 mask = GetMask(); + QT3DSU32 &target = inDataStore[idx]; + if (inValue == true) { + target = target | mask; + } else { + mask = ~mask; + target = target & mask; + } + } + + bool GetValue(NVConstDataRef inDataStore) const + { + QT3DSU32 idx = GetIdx(); + QT3DSU32 mask = GetMask(); + const QT3DSU32 &target = inDataStore[idx]; + return (target & mask) ? true : false; + } + + void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const + { + bool isHigh = GetValue(inKeySet); + InternalToString(ioStr, m_Name, isHigh); + } + }; + + template + struct SShaderKeyUnsigned : public SShaderKeyPropertyBase + { + enum { + BitWidth = TBitWidth, + }; + SShaderKeyUnsigned(const char *name = "") + : SShaderKeyPropertyBase(name) + { + } + QT3DSU32 GetMask() const { return GetMaskTemplate(); } + void SetValue(NVDataRef inDataStore, QT3DSU32 inValue) const + { + QT3DSU32 startValue = (1 << TBitWidth) - 1; + // Ensure inValue is within range of bit width. + inValue = inValue & startValue; + QT3DSU32 bit = m_Offset % 32; + QT3DSU32 mask = GetMask(); + QT3DSU32 idx = GetIdx(); + inValue = inValue << bit; + QT3DSU32 &target = inDataStore[idx]; + // Get rid of existing value + QT3DSU32 inverseMask = ~mask; + target = target & inverseMask; + target = target | inValue; + } + + QT3DSU32 GetValue(NVConstDataRef inDataStore) const + { + QT3DSU32 idx = GetIdx(); + QT3DSU32 bit = m_Offset % 32; + QT3DSU32 mask = GetMask(); + const QT3DSU32 &target = inDataStore[idx]; + + QT3DSU32 retval = target & mask; + retval = retval >> bit; + return retval; + } + + void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const + { + QT3DSU32 value = GetValue(inKeySet); + char buf[64]; + StringConversion().ToStr(value, toDataRef(buf, 64)); + InternalToString(ioStr, buf); + } + }; + + struct SShaderKeyTessellation : public SShaderKeyUnsigned<4> + { + enum TessellationBits { + noTessellation = 1 << 0, + linearTessellation = 1 << 1, + phongTessellation = 1 << 2, + npatchTessellation = 1 << 3 + }; + + SShaderKeyTessellation(const char *name = "") + : SShaderKeyUnsigned<4>(name) + { + } + + bool GetBitValue(TessellationBits swizzleBit, NVConstDataRef inKeySet) const + { + return (GetValue(inKeySet) & swizzleBit) ? true : false; + } + + void SetBitValue(TessellationBits swizzleBit, bool inValue, NVDataRef inKeySet) + { + QT3DSU32 theValue = GetValue(inKeySet); + QT3DSU32 mask = swizzleBit; + if (inValue) { + theValue = theValue | mask; + } else { + mask = ~mask; + theValue = theValue & mask; + } + SetValue(inKeySet, theValue); + } + + void SetTessellationMode(NVDataRef inKeySet, TessModeValues::Enum tessellationMode, + bool val) + { + switch (tessellationMode) { + case TessModeValues::NoTess: + SetBitValue(noTessellation, val, inKeySet); + break; + case TessModeValues::TessLinear: + SetBitValue(linearTessellation, val, inKeySet); + break; + case TessModeValues::TessNPatch: + SetBitValue(npatchTessellation, val, inKeySet); + break; + case TessModeValues::TessPhong: + SetBitValue(phongTessellation, val, inKeySet); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + bool IsNoTessellation(NVConstDataRef inKeySet) const + { + return GetBitValue(noTessellation, inKeySet); + } + void SetNoTessellation(NVDataRef inKeySet, bool val) + { + SetBitValue(noTessellation, val, inKeySet); + } + + bool IsLinearTessellation(NVConstDataRef inKeySet) const + { + return GetBitValue(linearTessellation, inKeySet); + } + void SetLinearTessellation(NVDataRef inKeySet, bool val) + { + SetBitValue(linearTessellation, val, inKeySet); + } + + bool IsNPatchTessellation(NVConstDataRef inKeySet) const + { + return GetBitValue(npatchTessellation, inKeySet); + } + void SetNPatchTessellation(NVDataRef inKeySet, bool val) + { + SetBitValue(npatchTessellation, val, inKeySet); + } + + bool IsPhongTessellation(NVConstDataRef inKeySet) const + { + return GetBitValue(phongTessellation, inKeySet); + } + void SetPhongTessellation(NVDataRef inKeySet, bool val) + { + SetBitValue(phongTessellation, val, inKeySet); + } + + void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const + { + ioStr.append(m_Name); + ioStr.append("={"); + InternalToString(ioStr, "noTessellation", IsNoTessellation(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "linearTessellation", IsLinearTessellation(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "npatchTessellation", IsNPatchTessellation(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "phongTessellation", IsPhongTessellation(inKeySet)); + ioStr.append("}"); + } + }; + + struct SShaderKeyTextureSwizzle : public SShaderKeyUnsigned<5> + { + enum TextureSwizzleBits { + noSwizzle = 1 << 0, + L8toR8 = 1 << 1, + A8toR8 = 1 << 2, + L8A8toRG8 = 1 << 3, + L16toR16 = 1 << 4 + }; + + SShaderKeyTextureSwizzle(const char *name = "") + : SShaderKeyUnsigned<5>(name) + { + } + + bool GetBitValue(TextureSwizzleBits swizzleBit, NVConstDataRef inKeySet) const + { + return (GetValue(inKeySet) & swizzleBit) ? true : false; + } + + void SetBitValue(TextureSwizzleBits swizzleBit, bool inValue, NVDataRef inKeySet) + { + QT3DSU32 theValue = GetValue(inKeySet); + QT3DSU32 mask = swizzleBit; + if (inValue) { + theValue = theValue | mask; + } else { + mask = ~mask; + theValue = theValue & mask; + } + SetValue(inKeySet, theValue); + } + + void SetSwizzleMode(NVDataRef inKeySet, NVRenderTextureSwizzleMode::Enum swizzleMode, + bool val) + { + switch (swizzleMode) { + case NVRenderTextureSwizzleMode::NoSwizzle: + SetBitValue(noSwizzle, val, inKeySet); + break; + case NVRenderTextureSwizzleMode::L8toR8: + SetBitValue(L8toR8, val, inKeySet); + break; + case NVRenderTextureSwizzleMode::A8toR8: + SetBitValue(A8toR8, val, inKeySet); + break; + case NVRenderTextureSwizzleMode::L8A8toRG8: + SetBitValue(L8A8toRG8, val, inKeySet); + break; + case NVRenderTextureSwizzleMode::L16toR16: + SetBitValue(L16toR16, val, inKeySet); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + + bool IsNoSwizzled(NVConstDataRef inKeySet) const + { + return GetBitValue(noSwizzle, inKeySet); + } + void SetNoSwizzled(NVDataRef inKeySet, bool val) + { + SetBitValue(noSwizzle, val, inKeySet); + } + + bool IsL8Swizzled(NVConstDataRef inKeySet) const + { + return GetBitValue(L8toR8, inKeySet); + } + void SetL8Swizzled(NVDataRef inKeySet, bool val) + { + SetBitValue(L8toR8, val, inKeySet); + } + + bool IsA8Swizzled(NVConstDataRef inKeySet) const + { + return GetBitValue(A8toR8, inKeySet); + } + void SetA8Swizzled(NVDataRef inKeySet, bool val) + { + SetBitValue(A8toR8, val, inKeySet); + } + + bool IsL8A8Swizzled(NVConstDataRef inKeySet) const + { + return GetBitValue(L8A8toRG8, inKeySet); + } + void SetL8A8Swizzled(NVDataRef inKeySet, bool val) + { + SetBitValue(L8A8toRG8, val, inKeySet); + } + + bool IsL16Swizzled(NVConstDataRef inKeySet) const + { + return GetBitValue(L16toR16, inKeySet); + } + void SetL16Swizzled(NVDataRef inKeySet, bool val) + { + SetBitValue(L16toR16, val, inKeySet); + } + + void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const + { + ioStr.append(m_Name); + ioStr.append("={"); + InternalToString(ioStr, "noswizzle", IsNoSwizzled(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "l8swizzle", IsL8Swizzled(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "a8swizzle", IsA8Swizzled(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "l8a8swizzle", IsL8A8Swizzled(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "l16swizzle", IsL16Swizzled(inKeySet)); + ioStr.append("}"); + } + }; + + struct SShaderKeyImageMap : public SShaderKeyUnsigned<5> + { + enum ImageMapBits { + Enabled = 1 << 0, + EnvMap = 1 << 1, + LightProbe = 1 << 2, + InvertUV = 1 << 3, + Premultiplied = 1 << 4, + }; + + SShaderKeyImageMap(const char *name = "") + : SShaderKeyUnsigned<5>(name) + { + } + + bool GetBitValue(ImageMapBits imageBit, NVConstDataRef inKeySet) const + { + return (GetValue(inKeySet) & imageBit) ? true : false; + } + + void SetBitValue(ImageMapBits imageBit, bool inValue, NVDataRef inKeySet) + { + QT3DSU32 theValue = GetValue(inKeySet); + QT3DSU32 mask = imageBit; + if (inValue) { + theValue = theValue | mask; + } else { + mask = ~mask; + theValue = theValue & mask; + } + SetValue(inKeySet, theValue); + } + + bool IsEnabled(NVConstDataRef inKeySet) const + { + return GetBitValue(Enabled, inKeySet); + } + void SetEnabled(NVDataRef inKeySet, bool val) + { + SetBitValue(Enabled, val, inKeySet); + } + + bool IsEnvMap(NVConstDataRef inKeySet) const + { + return GetBitValue(EnvMap, inKeySet); + } + void SetEnvMap(NVDataRef inKeySet, bool val) { SetBitValue(EnvMap, val, inKeySet); } + + bool IsLightProbe(NVConstDataRef inKeySet) const + { + return GetBitValue(LightProbe, inKeySet); + } + void SetLightProbe(NVDataRef inKeySet, bool val) + { + SetBitValue(LightProbe, val, inKeySet); + } + + bool IsInvertUVMap(NVConstDataRef inKeySet) const + { + return GetBitValue(InvertUV, inKeySet); + } + void SetInvertUVMap(NVDataRef inKeySet, bool val) + { + SetBitValue(InvertUV, val, inKeySet); + } + + bool IsPremultiplied(NVConstDataRef inKeySet) const + { + return GetBitValue(Premultiplied, inKeySet); + } + void SetPremultiplied(NVDataRef inKeySet, bool val) + { + SetBitValue(Premultiplied, val, inKeySet); + } + + void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const + { + ioStr.append(m_Name); + ioStr.append("={"); + InternalToString(ioStr, "enabled", IsEnabled(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "envMap", IsEnvMap(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "lightProbe", IsLightProbe(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "invertUV", IsInvertUVMap(inKeySet)); + ioStr.append(";"); + InternalToString(ioStr, "premultiplied", IsPremultiplied(inKeySet)); + ioStr.append("}"); + } + }; + + struct SShaderKeySpecularModel : SShaderKeyUnsigned<2> + { + SShaderKeySpecularModel(const char *name = "") + : SShaderKeyUnsigned<2>(name) + { + } + + void SetSpecularModel(NVDataRef inKeySet, + qt3ds::render::DefaultMaterialSpecularModel::Enum inModel) + { + SetValue(inKeySet, (QT3DSU32)inModel); + } + + qt3ds::render::DefaultMaterialSpecularModel::Enum + GetSpecularModel(NVConstDataRef inKeySet) const + { + return static_cast(GetValue(inKeySet)); + } + + void ToString(eastl::string &ioStr, NVConstDataRef inKeySet) const + { + ioStr.append(m_Name); + ioStr.append("="); + switch (GetSpecularModel(inKeySet)) { + case DefaultMaterialSpecularModel::KGGX: + ioStr.append("KGGX"); + break; + case DefaultMaterialSpecularModel::KWard: + ioStr.append("KWard"); + break; + case DefaultMaterialSpecularModel::Default: + ioStr.append("Default"); + break; + } + ioStr.append(";"); + } + }; + + struct SShaderDefaultMaterialKeyProperties + { + enum { + LightCount = 7, + }; + enum ImageMapNames { + DiffuseMap0 = 0, + DiffuseMap1, + DiffuseMap2, + EmissiveMap, + EmissiveMap2, + SpecularMap, + OpacityMap, + BumpMap, + SpecularAmountMap, + NormalMap, + DisplacementMap, + TranslucencyMap, + LightmapIndirect, + LightmapRadiosity, + LightmapShadow, + RoughnessMap, + ImageMapCount + }; + + SShaderKeyBoolean m_HasLighting; + SShaderKeyBoolean m_HasIbl; + SShaderKeyUnsigned<3> m_LightCount; + SShaderKeyBoolean m_LightFlags[LightCount]; + SShaderKeyBoolean m_LightAreaFlags[LightCount]; + SShaderKeyBoolean m_LightShadowFlags[LightCount]; + SShaderKeyBoolean m_SpecularEnabled; + SShaderKeyBoolean m_FresnelEnabled; + SShaderKeyBoolean m_VertexColorsEnabled; + SShaderKeySpecularModel m_SpecularModel; + SShaderKeyImageMap m_ImageMaps[ImageMapCount]; + SShaderKeyTextureSwizzle m_TextureSwizzle[ImageMapCount]; + SShaderKeyTessellation m_TessellationMode; + SShaderKeyBoolean m_HasSkinning; + SShaderKeyBoolean m_WireframeMode; + + SShaderDefaultMaterialKeyProperties() + : m_HasLighting("hasLighting") + , m_HasIbl("hasIbl") + , m_LightCount("lightCount") + , m_SpecularEnabled("specularEnabled") + , m_FresnelEnabled("fresnelEnabled") + , m_VertexColorsEnabled("vertexColorsEnabled") + , m_SpecularModel("specularModel") + , m_TessellationMode("tessellationMode") + , m_HasSkinning("hasSkinning") + , m_WireframeMode("wireframeMode") + { + m_LightFlags[0].m_Name = "light0HasPosition"; + m_LightFlags[1].m_Name = "light1HasPosition"; + m_LightFlags[2].m_Name = "light2HasPosition"; + m_LightFlags[3].m_Name = "light3HasPosition"; + m_LightFlags[4].m_Name = "light4HasPosition"; + m_LightFlags[5].m_Name = "light5HasPosition"; + m_LightFlags[6].m_Name = "light6HasPosition"; + m_LightAreaFlags[0].m_Name = "light0HasArea"; + m_LightAreaFlags[1].m_Name = "light1HasArea"; + m_LightAreaFlags[2].m_Name = "light2HasArea"; + m_LightAreaFlags[3].m_Name = "light3HasArea"; + m_LightAreaFlags[4].m_Name = "light4HasArea"; + m_LightAreaFlags[5].m_Name = "light5HasArea"; + m_LightAreaFlags[6].m_Name = "light6HasArea"; + m_LightShadowFlags[0].m_Name = "light0HasShadow"; + m_LightShadowFlags[1].m_Name = "light1HasShadow"; + m_LightShadowFlags[2].m_Name = "light2HasShadow"; + m_LightShadowFlags[3].m_Name = "light3HasShadow"; + m_LightShadowFlags[4].m_Name = "light4HasShadow"; + m_LightShadowFlags[5].m_Name = "light5HasShadow"; + m_LightShadowFlags[6].m_Name = "light6HasShadow"; + m_ImageMaps[0].m_Name = "diffuseMap0"; + m_ImageMaps[1].m_Name = "diffuseMap1"; + m_ImageMaps[2].m_Name = "diffuseMap2"; + m_ImageMaps[3].m_Name = "emissiveMap"; + m_ImageMaps[4].m_Name = "emissiveMap2"; + m_ImageMaps[5].m_Name = "specularMap"; + m_ImageMaps[6].m_Name = "opacityMap"; + m_ImageMaps[7].m_Name = "bumpMap"; + m_ImageMaps[8].m_Name = "specularAmountMap"; + m_ImageMaps[9].m_Name = "normalMap"; + m_ImageMaps[10].m_Name = "displacementMap"; + m_ImageMaps[11].m_Name = "translucencyMap"; + m_ImageMaps[12].m_Name = "lightmapIndirect"; + m_ImageMaps[13].m_Name = "lightmapRadiosity"; + m_ImageMaps[14].m_Name = "lightmapShadow"; + m_ImageMaps[15].m_Name = "roughnessMap"; + m_TextureSwizzle[0].m_Name = "diffuseMap0_swizzle"; + m_TextureSwizzle[1].m_Name = "diffuseMap1_swizzle"; + m_TextureSwizzle[2].m_Name = "diffuseMap2_swizzle"; + m_TextureSwizzle[3].m_Name = "emissiveMap_swizzle"; + m_TextureSwizzle[4].m_Name = "emissiveMap2_swizzle"; + m_TextureSwizzle[5].m_Name = "specularMap_swizzle"; + m_TextureSwizzle[6].m_Name = "opacityMap_swizzle"; + m_TextureSwizzle[7].m_Name = "bumpMap_swizzle"; + m_TextureSwizzle[8].m_Name = "specularAmountMap_swizzle"; + m_TextureSwizzle[9].m_Name = "normalMap_swizzle"; + m_TextureSwizzle[10].m_Name = "displacementMap_swizzle"; + m_TextureSwizzle[11].m_Name = "translucencyMap_swizzle"; + m_TextureSwizzle[12].m_Name = "lightmapIndirect_swizzle"; + m_TextureSwizzle[13].m_Name = "lightmapRadiosity_swizzle"; + m_TextureSwizzle[14].m_Name = "lightmapShadow_swizzle"; + m_TextureSwizzle[15].m_Name = "roughnessMap_swizzle"; + SetPropertyOffsets(); + } + + template + void VisitProperties(TVisitor &inVisitor) + { + inVisitor.Visit(m_HasLighting); + inVisitor.Visit(m_HasIbl); + inVisitor.Visit(m_LightCount); + + for (QT3DSU32 idx = 0, end = LightCount; idx < end; ++idx) { + inVisitor.Visit(m_LightFlags[idx]); + } + + for (QT3DSU32 idx = 0, end = LightCount; idx < end; ++idx) { + inVisitor.Visit(m_LightAreaFlags[idx]); + } + + for (QT3DSU32 idx = 0, end = LightCount; idx < end; ++idx) { + inVisitor.Visit(m_LightShadowFlags[idx]); + } + + inVisitor.Visit(m_SpecularEnabled); + inVisitor.Visit(m_FresnelEnabled); + inVisitor.Visit(m_VertexColorsEnabled); + inVisitor.Visit(m_SpecularModel); + + for (QT3DSU32 idx = 0, end = ImageMapCount; idx < end; ++idx) { + inVisitor.Visit(m_ImageMaps[idx]); + inVisitor.Visit(m_TextureSwizzle[idx]); + } + + inVisitor.Visit(m_TessellationMode); + inVisitor.Visit(m_HasSkinning); + inVisitor.Visit(m_WireframeMode); + } + + struct SOffsetVisitor + { + QT3DSU32 m_Offset; + SOffsetVisitor() + : m_Offset(0) + { + } + template + void Visit(TPropType &inProp) + { + // if we cross the 32 bit border we just move + // to the next dword. + // This cost a few extra bits but prevents tedious errors like + // loosing shader key bits because they got moved beyond the 32 border + QT3DSU32 bit = m_Offset % 32; + if (bit + TPropType::BitWidth > 31) { + m_Offset += 32 - bit; + } + + inProp.SetOffset(m_Offset); + m_Offset += TPropType::BitWidth; + } + }; + + void SetPropertyOffsets() + { + SOffsetVisitor visitor; + VisitProperties(visitor); + // If this assert fires, then the default material key needs more bits. + QT3DS_ASSERT(visitor.m_Offset < 224); + } + }; + + struct SShaderDefaultMaterialKey + { + enum { + DataBufferSize = 7, + }; + QT3DSU32 m_DataBuffer[DataBufferSize]; + size_t m_FeatureSetHash; + + SShaderDefaultMaterialKey(size_t inFeatureSetHash) + : m_FeatureSetHash(inFeatureSetHash) + { + for (size_t idx = 0; idx < DataBufferSize; ++idx) + m_DataBuffer[idx] = 0; + } + + SShaderDefaultMaterialKey() + : m_FeatureSetHash(0) + { + for (size_t idx = 0; idx < DataBufferSize; ++idx) + m_DataBuffer[idx] = 0; + } + + size_t hash() const + { + size_t retval = 0; + for (size_t idx = 0; idx < DataBufferSize; ++idx) + retval = retval ^ eastl::hash()(m_DataBuffer[idx]); + return retval ^ m_FeatureSetHash; + } + + bool operator==(const SShaderDefaultMaterialKey &other) const + { + bool retval = true; + for (size_t idx = 0; idx < DataBufferSize && retval; ++idx) + retval = m_DataBuffer[idx] == other.m_DataBuffer[idx]; + return retval && m_FeatureSetHash == other.m_FeatureSetHash; + } + + // Cast operators to make getting properties easier. + operator NVDataRef() { return toDataRef(m_DataBuffer, DataBufferSize); } + + operator NVConstDataRef() const + { + return toConstDataRef(m_DataBuffer, DataBufferSize); + } + + struct SStringVisitor + { + eastl::string &m_Str; + NVConstDataRef m_KeyStore; + SStringVisitor(eastl::string &s, NVConstDataRef ks) + : m_Str(s) + , m_KeyStore(ks) + { + } + template + void Visit(const TPropType &prop) + { + QT3DSU32 originalSize = m_Str.size(); + if (m_Str.size()) + m_Str.append(";"); + prop.ToString(m_Str, m_KeyStore); + // if the only thing we added was the semicolon + // then nuke the semicolon + if (originalSize && m_Str.size() == originalSize + 1) + m_Str.resize(originalSize); + } + }; + + void ToString(eastl::string &ioString, + SShaderDefaultMaterialKeyProperties &inProperties) const + { + SStringVisitor theVisitor(ioString, *this); + inProperties.VisitProperties(theVisitor); + } + }; +} +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const qt3ds::render::SShaderDefaultMaterialKey &key) const + { + return key.hash(); + } +}; +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.cpp new file mode 100644 index 00000000..983af55c --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.cpp @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderShadowMap.h" +#include "Qt3DSRenderResourceManager.h" +#include "rendererimpl/Qt3DSRendererImplLayerRenderData.h" +#include "render/Qt3DSRenderShaderConstant.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds::render; +using qt3ds::render::NVRenderContextScopedProperty; +using qt3ds::render::NVRenderCachedShaderProperty; + +Qt3DSShadowMap::Qt3DSShadowMap(IQt3DSRenderContext &inContext) + : m_Context(inContext) + , mRefCount(0) + , m_ShadowMapList(inContext.GetAllocator(), "Qt3DSShadowMap::m_ShadowMapList") +{ +} + +Qt3DSShadowMap::~Qt3DSShadowMap() +{ + m_ShadowMapList.clear(); +} + +namespace { +bool IsDepthFormat(NVRenderTextureFormats::Enum format) +{ + switch (format) { + case NVRenderTextureFormats::Depth16: + case NVRenderTextureFormats::Depth24: + case NVRenderTextureFormats::Depth32: + case NVRenderTextureFormats::Depth24Stencil8: + return true; + default: + return false; + } +} +} + +void Qt3DSShadowMap::AddShadowMapEntry(QT3DSU32 index, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format, QT3DSU32 samples, + ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter) +{ + IResourceManager &theManager(m_Context.GetResourceManager()); + SShadowMapEntry *pEntry = NULL; + + if (index < m_ShadowMapList.size()) + pEntry = &m_ShadowMapList[index]; + + if (pEntry) { + if ((NULL != pEntry->m_DepthMap) && (mode == ShadowMapModes::CUBE)) { + theManager.Release(*pEntry->m_DepthMap); + theManager.Release(*pEntry->m_DepthCopy); + theManager.Release(*pEntry->m_DepthRender); + pEntry->m_DepthCube = theManager.AllocateTextureCube(width, height, format, samples); + pEntry->m_CubeCopy = theManager.AllocateTextureCube(width, height, format, samples); + pEntry->m_DepthRender = theManager.AllocateTexture2D( + width, height, NVRenderTextureFormats::Depth24Stencil8, samples); + pEntry->m_DepthMap = NULL; + pEntry->m_DepthCopy = NULL; + } else if ((NULL != pEntry->m_DepthCube) && (mode != ShadowMapModes::CUBE)) { + theManager.Release(*pEntry->m_DepthCube); + theManager.Release(*pEntry->m_CubeCopy); + theManager.Release(*pEntry->m_DepthRender); + pEntry->m_DepthMap = theManager.AllocateTexture2D(width, height, format, samples); + pEntry->m_DepthCopy = theManager.AllocateTexture2D(width, height, format, samples); + pEntry->m_DepthCube = NULL; + pEntry->m_CubeCopy = NULL; + pEntry->m_DepthRender = theManager.AllocateTexture2D( + width, height, NVRenderTextureFormats::Depth24Stencil8, samples); + } else if (NULL != pEntry->m_DepthMap) { + STextureDetails theDetails(pEntry->m_DepthMap->GetTextureDetails()); + + // If anything differs about the map we're looking for, let's recreate it. + if (theDetails.m_Format != format || theDetails.m_Width != width + || theDetails.m_Height != height || theDetails.m_SampleCount != samples) { + // release texture + theManager.Release(*pEntry->m_DepthMap); + theManager.Release(*pEntry->m_DepthCopy); + theManager.Release(*pEntry->m_DepthRender); + pEntry->m_DepthMap = theManager.AllocateTexture2D(width, height, format, samples); + pEntry->m_DepthCopy = theManager.AllocateTexture2D(width, height, format, samples); + pEntry->m_DepthCube = NULL; + pEntry->m_CubeCopy = NULL; + pEntry->m_DepthRender = theManager.AllocateTexture2D( + width, height, NVRenderTextureFormats::Depth24Stencil8, samples); + } + } else { + STextureDetails theDetails(pEntry->m_DepthCube->GetTextureDetails()); + + // If anything differs about the map we're looking for, let's recreate it. + if (theDetails.m_Format != format || theDetails.m_Width != width + || theDetails.m_Height != height || theDetails.m_SampleCount != samples) { + // release texture + theManager.Release(*pEntry->m_DepthCube); + theManager.Release(*pEntry->m_CubeCopy); + theManager.Release(*pEntry->m_DepthRender); + pEntry->m_DepthCube = + theManager.AllocateTextureCube(width, height, format, samples); + pEntry->m_CubeCopy = theManager.AllocateTextureCube(width, height, format, samples); + pEntry->m_DepthRender = theManager.AllocateTexture2D( + width, height, NVRenderTextureFormats::Depth24Stencil8, samples); + pEntry->m_DepthMap = NULL; + pEntry->m_DepthCopy = NULL; + } + } + + pEntry->m_ShadowMapMode = mode; + pEntry->m_ShadowFilterFlags = filter; + } else if (mode == ShadowMapModes::CUBE) { + NVRenderTextureCube *theDepthTex = + theManager.AllocateTextureCube(width, height, format, samples); + NVRenderTextureCube *theDepthCopy = + theManager.AllocateTextureCube(width, height, format, samples); + NVRenderTexture2D *theDepthTemp = theManager.AllocateTexture2D( + width, height, NVRenderTextureFormats::Depth24Stencil8, samples); + + m_ShadowMapList.push_back( + SShadowMapEntry(index, mode, filter, *theDepthTex, *theDepthCopy, *theDepthTemp)); + + pEntry = &m_ShadowMapList.back(); + } else { + NVRenderTexture2D *theDepthMap = + theManager.AllocateTexture2D(width, height, format, samples); + NVRenderTexture2D *theDepthCopy = + theManager.AllocateTexture2D(width, height, format, samples); + NVRenderTexture2D *theDepthTemp = theManager.AllocateTexture2D( + width, height, NVRenderTextureFormats::Depth24Stencil8, samples); + + m_ShadowMapList.push_back( + SShadowMapEntry(index, mode, filter, *theDepthMap, *theDepthCopy, *theDepthTemp)); + + pEntry = &m_ShadowMapList.back(); + } + + if (pEntry) { + // setup some texture settings + if (pEntry->m_DepthMap) { + pEntry->m_DepthMap->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + pEntry->m_DepthMap->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + pEntry->m_DepthMap->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + pEntry->m_DepthMap->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + + pEntry->m_DepthCopy->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + pEntry->m_DepthCopy->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + pEntry->m_DepthCopy->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + pEntry->m_DepthCopy->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + + pEntry->m_DepthRender->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + pEntry->m_DepthRender->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + pEntry->m_DepthRender->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + pEntry->m_DepthRender->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + } else { + pEntry->m_DepthCube->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + pEntry->m_DepthCube->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + pEntry->m_DepthCube->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + pEntry->m_DepthCube->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + + pEntry->m_CubeCopy->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + pEntry->m_CubeCopy->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + pEntry->m_CubeCopy->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + pEntry->m_CubeCopy->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + + pEntry->m_DepthRender->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + pEntry->m_DepthRender->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + pEntry->m_DepthRender->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + pEntry->m_DepthRender->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + } + + pEntry->m_LightIndex = index; + } +} + +SShadowMapEntry *Qt3DSShadowMap::GetShadowMapEntry(QT3DSU32 index) +{ + SShadowMapEntry *pEntry = NULL; + + for (QT3DSU32 i = 0; i < m_ShadowMapList.size(); i++) { + pEntry = &m_ShadowMapList[i]; + if (pEntry->m_LightIndex == index) + return pEntry; + } + + return NULL; +} + +Qt3DSShadowMap *Qt3DSShadowMap::Create(IQt3DSRenderContext &inContext) +{ + return QT3DS_NEW(inContext.GetFoundation().getAllocator(), Qt3DSShadowMap)(inContext); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.h b/src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.h new file mode 100644 index 00000000..c5ba2eaa --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderShadowMap.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADOW_MAP_H +#define QT3DS_RENDER_SHADOW_MAP_H +#include "Qt3DSRenderContextCore.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSMat44.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderTexture2D.h" +#ifdef _INTEGRITYPLATFORM +#include "render/Qt3DSRenderTextureCube.h" +#endif + +namespace qt3ds { +namespace render { + + struct SLayerRenderData; + + struct ShadowMapModes + { + enum Enum { + SSM, ///< standard shadow mapping + VSM, ///< variance shadow mapping + CUBE, ///< cubemap omnidirectional shadows + }; + }; + + struct ShadowFilterValues + { + enum Enum { + NONE = 1 << 0, ///< hard shadows + PCF = 1 << 1, ///< Percentage close filtering + BLUR = 1 << 2, ///< Gausian Blur + }; + }; + + struct SShadowMapEntry + { + SShadowMapEntry() + : m_LightIndex(QT3DS_MAX_U32) + , m_ShadowMapMode(ShadowMapModes::SSM) + , m_ShadowFilterFlags(ShadowFilterValues::NONE) + { + } + + SShadowMapEntry(QT3DSU32 index, ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter, + NVRenderTexture2D &depthMap, NVRenderTexture2D &depthCopy, + NVRenderTexture2D &depthTemp) + : m_LightIndex(index) + , m_ShadowMapMode(mode) + , m_ShadowFilterFlags(filter) + , m_DepthMap(depthMap) + , m_DepthCopy(depthCopy) + , m_DepthCube(NULL) + , m_CubeCopy(NULL) + , m_DepthRender(depthTemp) + { + } + + SShadowMapEntry(QT3DSU32 index, ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter, + NVRenderTextureCube &depthCube, NVRenderTextureCube &cubeTmp, + NVRenderTexture2D &depthTemp) + : m_LightIndex(index) + , m_ShadowMapMode(mode) + , m_ShadowFilterFlags(filter) + , m_DepthMap(NULL) + , m_DepthCopy(NULL) + , m_DepthCube(depthCube) + , m_CubeCopy(cubeTmp) + , m_DepthRender(depthTemp) + { + } + + QT3DSU32 m_LightIndex; ///< the light index it belongs to + ShadowMapModes::Enum m_ShadowMapMode; ///< shadow map method + ShadowFilterValues::Enum m_ShadowFilterFlags; ///< shadow filter mode + + // PKC : Adding the DepthRender buffer allows us to have a depth+stencil format when filling + // the shadow maps (depth+stencil is necessary), but use a more compact format for the + // actual + // shadow map used at shade time. See if it's worth adding. + NVScopedRefCounted m_DepthMap; ///< shadow map texture + NVScopedRefCounted + m_DepthCopy; ///< shadow map buffer used during blur passes + NVScopedRefCounted m_DepthCube; ///< shadow cube map + NVScopedRefCounted + m_CubeCopy; ///< cube map buffer used during the blur passes + NVScopedRefCounted + m_DepthRender; ///< shadow depth+stencil map used during rendering + + QT3DSMat44 m_LightVP; ///< light view projection matrix + QT3DSMat44 m_LightCubeView[6]; ///< light cubemap view matrices + QT3DSMat44 m_LightView; ///< light view transform + }; + + class Qt3DSShadowMap : public NVRefCounted + { + typedef nvvector TShadowMapEntryList; + + public: + IQt3DSRenderContext &m_Context; + volatile QT3DSI32 mRefCount; + + public: + Qt3DSShadowMap(IQt3DSRenderContext &inContext); + ~Qt3DSShadowMap(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Context.GetAllocator()) + + /* + * @brief Add a shadow map entry + * This creates a new shadow map if it does not exist or changed + * + * @param[in] index shadow map entry index + * @param[in] width shadow map width + * @param[in] height shadow map height + * @param[in] format shadow map format + * @param[in] samples shadow map sample count + * @param[in] mode shadow map mode like SSM, VCM + * @param[in] filter soft shadow map mode filter like PCF + * + * @ return no return + */ + void AddShadowMapEntry(QT3DSU32 index, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format, QT3DSU32 samples, + ShadowMapModes::Enum mode, ShadowFilterValues::Enum filter); + + /* + * @brief Get a shadow map entry + * + * @param[in] index shadow map entry index + * + * @ return shadow map entry or NULL + */ + SShadowMapEntry *GetShadowMapEntry(QT3DSU32 index); + + /* + * @brief Get shadow map entry count + * + * @ return count of shadow map entries + */ + QT3DSU32 GetShadowMapEntryCount() { return m_ShadowMapList.size(); } + + static Qt3DSShadowMap *Create(IQt3DSRenderContext &inContext); + + private: + TShadowMapEntryList m_ShadowMapList; ///< List of shadow map entries + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderString.h b/src/Runtime/Source/runtimerender/Qt3DSRenderString.h new file mode 100644 index 00000000..8d831c20 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderString.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_STRING_H +#define QT3DS_RENDER_STRING_H +#include "Qt3DSRender.h" +#include + +namespace qt3ds { +namespace render { + // can't name this CString else we will conflict a + class CRenderString : public std::basic_string + { + public: + typedef std::basic_string TStrType; + + CRenderString() + : TStrType() + { + } + CRenderString(const CRenderString &inOther) + : TStrType(inOther) + { + } + CRenderString(const TStrType &inOther) + : TStrType(inOther) + { + } + CRenderString &operator=(const CRenderString &inOther) + { + TStrType::operator=(inOther); + return *this; + } + CRenderString &operator=(const char8_t *inOther) + { + TStrType::operator=(inOther); + return *this; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderSubPresentationHelper.h b/src/Runtime/Source/runtimerender/Qt3DSRenderSubPresentationHelper.h new file mode 100644 index 00000000..d77c7a7f --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderSubPresentationHelper.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SUB_PRESENTATION_HELPER_H +#define QT3DS_RENDER_SUB_PRESENTATION_HELPER_H +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderer.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + // Small helper object to setup the state needed to render a sub presentation + // correctly. Sub presentations may have transparency, and if they do then + // then need to be rendered with pre multiple alpha disabled. If they don't, + // then they need to be rendered with pre-multiply alpha enabled (and have the alpha channel + // set to 1 + struct SSubPresentationHelper + { + IQt3DSRenderContext &m_RenderContext; + QSize m_PreviousPresentationDimensions; + + bool m_WasInSubPresentation; + + SSubPresentationHelper(IQt3DSRenderContext &inContext, + const QSize &inPresDimensions) + : m_RenderContext(inContext) + , m_PreviousPresentationDimensions(inContext.GetCurrentPresentationDimensions()) + , m_WasInSubPresentation(inContext.IsInSubPresentation()) + { + m_RenderContext.SetInSubPresentation(true); + m_RenderContext.SetPresentationDimensions(inPresDimensions); + } + ~SSubPresentationHelper() + { + m_RenderContext.SetInSubPresentation(m_WasInSubPresentation); + m_RenderContext.SetPresentationDimensions(m_PreviousPresentationDimensions); + } + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.cpp new file mode 100644 index 00000000..cd83f036 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderSubpresentation.h" +#include "Qt3DSRenderRenderList.h" +#ifdef _WIN32 +#pragma warning(disable : 4355) // this used in initializer list. I have never seen this result in + // a physical error +#endif +namespace qt3ds { +namespace render { + + Qt3DSRenderPickResult CSubPresentationPickQuery::Pick(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool inPickEverything) + { + return m_Renderer.DoGraphQueryPick(inMouseCoords, inViewportDimensions, inPickEverything); + } + + CSubPresentationRenderer::CSubPresentationRenderer(IQt3DSRenderContext &inRenderContext, + SPresentation &inPresentation) + : m_RenderContext(inRenderContext) + , m_Presentation(inPresentation) + , mRefCount(0) + , m_PickQuery(*this) + , m_OffscreenRendererType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) + { + } + + SOffscreenRendererEnvironment + CSubPresentationRenderer::GetDesiredEnvironment(QT3DSVec2 /*inPresScale*/) + { + // If we aren't using a clear color, then we are expected to blend with the background + bool hasTransparency = m_Presentation.m_Scene->m_UseClearColor ? false : true; + NVRenderTextureFormats::Enum format = + hasTransparency ? NVRenderTextureFormats::RGBA8 : NVRenderTextureFormats::RGB8; + return SOffscreenRendererEnvironment((QT3DSU32)(m_Presentation.m_PresentationDimensions.x), + (QT3DSU32)(m_Presentation.m_PresentationDimensions.y), + format, OffscreenRendererDepthValues::Depth16, false, + AAModeValues::NoAA); + } + + SOffscreenRenderFlags + CSubPresentationRenderer::NeedsRender(const SOffscreenRendererEnvironment & /*inEnvironment*/, + QT3DSVec2 /*inPresScale*/, + const SRenderInstanceId instanceId) + { + bool hasTransparency = m_Presentation.m_Scene->m_UseClearColor ? false : true; + NVRenderRect theViewportSize(m_RenderContext.GetRenderList().GetViewport()); + bool wasDirty = m_Presentation.m_Scene->PrepareForRender( + QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), + m_RenderContext, instanceId); + return SOffscreenRenderFlags(hasTransparency, wasDirty); + } + + // Returns true if the rendered result image has transparency, or false + // if it should be treated as a completely opaque image. + void CSubPresentationRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2, + SScene::RenderClearCommand inClearColorBuffer, + const SRenderInstanceId instanceId) + { + SSubPresentationHelper theHelper( + m_RenderContext, + QSize((QT3DSU32)inEnvironment.m_Width, (QT3DSU32)inEnvironment.m_Height)); + NVRenderRect theViewportSize(inRenderContext.GetViewport()); + m_Presentation.m_Scene->Render( + QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), + m_RenderContext, inClearColorBuffer, instanceId); + m_LastRenderedEnvironment = inEnvironment; + } + + void CSubPresentationRenderer::RenderWithClear( + const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresScale, + SScene::RenderClearCommand inClearBuffer, QT3DSVec3 inClearColor, + const SRenderInstanceId id) + { + Q_UNUSED(inEnvironment); + Q_UNUSED(inPresScale); + NVRenderRect theViewportSize(inRenderContext.GetViewport()); + m_Presentation.m_Scene->RenderWithClear( + QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), + m_RenderContext, inClearBuffer, inClearColor, id); + } + + // You know the viewport dimensions because + Qt3DSRenderPickResult CSubPresentationRenderer::DoGraphQueryPick( + const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, bool inPickEverything) + { + Qt3DSRenderPickResult thePickResult; + + if (m_Presentation.m_Scene && m_Presentation.m_Scene->m_FirstChild) { + thePickResult = m_RenderContext.GetRenderer().Pick( + *m_Presentation.m_Scene->m_FirstChild, inViewportDimensions, + QT3DSVec2(inMouseCoords.x, inMouseCoords.y), true, inPickEverything); + } + return thePickResult; + } +} +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.h b/src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.h new file mode 100644 index 00000000..9eb51450 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderSubpresentation.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SUBPRESENTATION_H +#define QT3DS_RENDER_SUBPRESENTATION_H + +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSRenderSubPresentationHelper.h" +#include "Qt3DSRenderPresentation.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + class CSubPresentationRenderer; + + struct CSubPresentationPickQuery : public IGraphObjectPickQuery + { + CSubPresentationRenderer &m_Renderer; + + CSubPresentationPickQuery(CSubPresentationRenderer &renderer) + : m_Renderer(renderer) + { + } + Qt3DSRenderPickResult Pick(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool inPickEverything) override; + }; + + class CSubPresentationRenderer : public IOffscreenRenderer + { + public: + IQt3DSRenderContext &m_RenderContext; + SPresentation &m_Presentation; + volatile QT3DSI32 mRefCount; + SOffscreenRendererEnvironment m_LastRenderedEnvironment; + CSubPresentationPickQuery m_PickQuery; + CRegisteredString m_OffscreenRendererType; + + CSubPresentationRenderer(IQt3DSRenderContext &inRenderContext, SPresentation &inPresentation); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) + + SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresScale) override; + virtual SOffscreenRenderFlags + NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, QT3DSVec2 inPresScale, + const SRenderInstanceId instanceId) override; + void Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext & /*inRenderContext*/, + QT3DSVec2 inPresScale, SScene::RenderClearCommand inClearBuffer, + const SRenderInstanceId instanceId) override; + void RenderWithClear(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, + QT3DSVec2 inPresScale, SScene::RenderClearCommand inClearBuffer, + QT3DSVec3 inClearColor, + const SRenderInstanceId instanceId) override; + IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId) override { return &m_PickQuery; } + bool Pick(const QT3DSVec2 & /*inMouseCoords*/, const QT3DSVec2 & /*inViewportDimensions*/, + const SRenderInstanceId) override + { + return false; + } + void addCallback(IOffscreenRendererCallback *cb) override + { + + } + // Used for RTTI purposes so we can safely static-cast an offscreen renderer to a + // CSubPresentationRenderer + static const char *GetRendererName() { return "SubPresentation"; } + CRegisteredString GetOffscreenRendererType() override { return m_OffscreenRendererType; } + + Qt3DSRenderPickResult DoGraphQueryPick(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool inPickEverything); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTaggedPointer.h b/src/Runtime/Source/runtimerender/Qt3DSRenderTaggedPointer.h new file mode 100644 index 00000000..8dd8bdd0 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTaggedPointer.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TAGGED_POINTER_H +#define QT3DS_RENDER_TAGGED_POINTER_H +#include "Qt3DSRender.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + // User's will need to define specialize this struct in order + // to de-tag a pointer. + template + struct SPointerTag + { + /* Expected API for runtime RTTI + static CRegisteredString GetTag() { return g_dtype_specific_string; } + */ + }; + + // A pointer tagged with an identifier so we can have generic + // user data that is still somewhat typesafe. + struct STaggedPointer + { + void *m_UserData; + QT3DSU32 m_Tag; + STaggedPointer() + : m_UserData(NULL) + , m_Tag(0) + { + } + + STaggedPointer(void *inUserData, QT3DSU32 inTag) + : m_UserData(inUserData) + , m_Tag(inTag) + { + } + + template + STaggedPointer(TDataType *inType) + : m_UserData(reinterpret_cast(inType)) + , m_Tag(SPointerTag::GetTag()) + { + } + + template + TDataType *DynamicCast() const + { + if (m_Tag == SPointerTag::GetTag()) + return reinterpret_cast(m_UserData); + return NULL; + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTessModeValues.h b/src/Runtime/Source/runtimerender/Qt3DSRenderTessModeValues.h new file mode 100644 index 00000000..15ea03c9 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTessModeValues.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TESS_MODE_VALUES_H +#define QT3DS_RENDER_TESS_MODE_VALUES_H +#include "Qt3DSRender.h" + +namespace qt3ds { +namespace render { + + struct SDefaultMaterial; + class IBufferManager; + + struct TessModeValues + { + enum Enum { + NoTess = 0, + TessLinear = 1, + TessPhong = 2, + TessNPatch = 3, + }; + + static const char *toString(Enum value) + { + switch (value) { + case NoTess: + return "NoTess"; + break; + case TessLinear: + return "TessLinear"; + break; + case TessPhong: + return "TessPhong"; + break; + case TessNPatch: + return "TessNPatch"; + break; + default: + return "NoTess"; + break; + } + } + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.cpp new file mode 100644 index 00000000..81c1d232 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderTextTextureAtlas.h" +#include "Qt3DSTextRenderer.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderContext.h" + +using namespace qt3ds::render; + +namespace { + +struct STextTextureAtlas : public ITextTextureAtlas +{ + static const QT3DSI32 TEXTURE_ATLAS_DIM = + 256; // if you change this you need to adjust Qt3DSOnscreenTextRenderer size as well + + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + NVScopedRefCounted m_TextRenderer; + NVScopedRefCounted m_RenderContext; + + STextTextureAtlas(NVFoundationBase &inFnd, ITextRenderer &inRenderer, + NVRenderContext &inRenderContext) + : m_Foundation(inFnd) + , mRefCount(0) + , m_TextRenderer(inRenderer) + , m_RenderContext(inRenderContext) + , m_TextureAtlasInitialized(false) + , m_textureAtlas(NULL) + { + } + + virtual ~STextTextureAtlas() + { + if (m_textureAtlas) { + m_textureAtlas->release(); + } + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + TTextRenderAtlasDetailsAndTexture RenderText(const STextRenderInfo &inText) override + { + SRenderTextureAtlasDetails theDetails = m_TextRenderer->RenderText(inText); + + return TTextRenderAtlasDetailsAndTexture(theDetails, m_textureAtlas); + } + + bool IsInitialized() override { return m_TextureAtlasInitialized && m_textureAtlas; } + + TTextTextureAtlasDetailsAndTexture PrepareTextureAtlas() override + { + if (!m_TextureAtlasInitialized && !m_textureAtlas) { + // create the texture atlas entries + QT3DSI32 count = m_TextRenderer->CreateTextureAtlas(); + + m_textureAtlas = m_RenderContext->CreateTexture2D(); + if (m_textureAtlas && count) { + m_TextureAtlasInitialized = true; + m_textureAtlas->addRef(); + // if you change the size you need to adjust Qt3DSOnscreenTextRenderer too + if (m_RenderContext->GetRenderContextType() == NVRenderContextValues::GLES2) { + m_textureAtlas->SetTextureData(NVDataRef(), 0, TEXTURE_ATLAS_DIM, + TEXTURE_ATLAS_DIM, NVRenderTextureFormats::RGBA8); + } else { + m_textureAtlas->SetTextureData(NVDataRef(), 0, TEXTURE_ATLAS_DIM, + TEXTURE_ATLAS_DIM, NVRenderTextureFormats::Alpha8); + } + m_textureAtlas->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + m_textureAtlas->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + m_textureAtlas->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge); + m_textureAtlas->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge); + qt3ds::render::STextureDetails texTexDetails = m_textureAtlas->GetTextureDetails(); + return TTextTextureAtlasDetailsAndTexture( + STextTextureAtlasDetails(texTexDetails.m_Height, texTexDetails.m_Height, false, + count), + m_textureAtlas); + } + } + + return TTextTextureAtlasDetailsAndTexture(STextTextureAtlasDetails(), NULL); + } + +private: + bool m_TextureAtlasInitialized; + NVRenderTexture2D *m_textureAtlas; // this is the actual texture which has application lifetime +}; + +} // namespace + +ITextTextureAtlas &ITextTextureAtlas::CreateTextureAtlas(NVFoundationBase &inFnd, + ITextRenderer &inTextRenderer, + NVRenderContext &inRenderContext) +{ + return *QT3DS_NEW(inFnd.getAllocator(), STextTextureAtlas)(inFnd, inTextRenderer, inRenderContext); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.h b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.h new file mode 100644 index 00000000..7a3f1215 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureAtlas.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TEXT_TEXTURE_ATLAS_H +#define QT3DS_RENDER_TEXT_TEXTURE_ATLAS_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSRenderText.h" +#include "EASTL/algorithm.h" + +namespace qt3ds { +namespace render { + + class ITextRenderer; + + typedef eastl::pair> + TTextTextureAtlasDetailsAndTexture; + typedef eastl::pair> + TTextRenderAtlasDetailsAndTexture; + + class ITextTextureAtlas : public NVRefCounted + { + protected: + virtual ~ITextTextureAtlas() {} + public: + virtual TTextRenderAtlasDetailsAndTexture RenderText(const STextRenderInfo &inText) = 0; + virtual bool IsInitialized() = 0; + virtual TTextTextureAtlasDetailsAndTexture PrepareTextureAtlas() = 0; + + static ITextTextureAtlas &CreateTextureAtlas(NVFoundationBase &inFnd, + ITextRenderer &inTextRenderer, + NVRenderContext &inRenderContext); + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.cpp new file mode 100644 index 00000000..304e64b6 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.cpp @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderTextTextureCache.h" +#include "Qt3DSTextRenderer.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSPool.h" + +using namespace qt3ds::render; + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const qt3ds::render::STextRenderInfo &inInfo) const + { + size_t retval = hash()(reinterpret_cast(inInfo.m_Text.c_str())); + retval = retval ^ hash()(reinterpret_cast(inInfo.m_Font.c_str())); + retval = retval ^ hash()(inInfo.m_FontSize); + retval = retval ^ hash()(static_cast(inInfo.m_HorizontalAlignment)); + retval = retval ^ hash()(static_cast(inInfo.m_VerticalAlignment)); + retval = retval ^ hash()(inInfo.m_Leading); + retval = retval ^ hash()(inInfo.m_Tracking); + retval = retval ^ hash()(inInfo.m_DropShadow); + retval = retval ^ hash()(inInfo.m_DropShadowStrength); + retval = retval ^ hash()(inInfo.m_DropShadowOffset); // To be removed in 2.x (when UIP version is next updated) + retval = retval ^ hash()(inInfo.m_DropShadowOffsetX); + retval = retval ^ hash()(inInfo.m_DropShadowOffsetY); + retval = retval ^ hash()(inInfo.m_BoundingBox.x); + retval = retval ^ hash()(inInfo.m_BoundingBox.y); + retval = retval ^ hash()(static_cast(inInfo.m_Elide)); + retval = retval ^ hash()(static_cast(inInfo.m_DropShadowHorizontalAlignment)); // To be removed in 2.x (when UIP version is next updated) + retval = retval ^ hash()(static_cast(inInfo.m_DropShadowVerticalAlignment)); // To be removed in 2.x (when UIP version is next updated) + retval = retval ^ hash()(static_cast(inInfo.m_WordWrap)); + retval = retval ^ hash()(inInfo.m_EnableAcceleratedFont); + return retval; + } +}; +} + +namespace { +struct STextRenderInfoAndHash +{ + STextRenderInfo m_Info; + QT3DSF32 m_ScaleFactor; + size_t m_Hashcode; + STextRenderInfoAndHash(const STextRenderInfo &inInfo, QT3DSF32 inScaleFactor) + : m_Info(inInfo) + , m_ScaleFactor(inScaleFactor) + , m_Hashcode(eastl::hash()(inInfo) ^ eastl::hash()(inScaleFactor)) + { + } + bool operator==(const STextRenderInfoAndHash &inOther) const + { + return m_Info.m_Text == inOther.m_Info.m_Text && m_Info.m_Font == inOther.m_Info.m_Font + && m_Info.m_FontSize == inOther.m_Info.m_FontSize + && m_Info.m_HorizontalAlignment == inOther.m_Info.m_HorizontalAlignment + && m_Info.m_VerticalAlignment == inOther.m_Info.m_VerticalAlignment + && m_Info.m_Leading == inOther.m_Info.m_Leading + && m_Info.m_Tracking == inOther.m_Info.m_Tracking + && m_Info.m_DropShadow == inOther.m_Info.m_DropShadow + && m_Info.m_DropShadowStrength == inOther.m_Info.m_DropShadowStrength + && m_Info.m_DropShadowOffset == inOther.m_Info.m_DropShadowOffset + && m_Info.m_DropShadowHorizontalAlignment + == inOther.m_Info.m_DropShadowHorizontalAlignment + && m_Info.m_DropShadowVerticalAlignment == inOther.m_Info.m_DropShadowVerticalAlignment + && m_Info.m_BoundingBox == inOther.m_Info.m_BoundingBox + && m_Info.m_WordWrap == inOther.m_Info.m_WordWrap + && m_Info.m_EnableAcceleratedFont == inOther.m_Info.m_EnableAcceleratedFont + && m_ScaleFactor == inOther.m_ScaleFactor; + } +}; +} + +namespace eastl { +template <> +struct hash +{ + size_t operator()(const STextRenderInfoAndHash &inInfo) const { return inInfo.m_Hashcode; } +}; +}; + +namespace { + +struct STextCacheNode +{ + STextCacheNode *m_PreviousSibling; + STextCacheNode *m_NextSibling; + STextRenderInfoAndHash m_RenderInfo; + TTPathObjectAndTexture m_TextInfo; + QT3DSU32 m_FrameCount; + + STextCacheNode(const STextRenderInfoAndHash &inRenderInfo, + const TTPathObjectAndTexture &inTextInfo) + : m_PreviousSibling(NULL) + , m_NextSibling(NULL) + , m_RenderInfo(inRenderInfo) + , m_TextInfo(inTextInfo) + , m_FrameCount(0) + { + } +}; + +typedef nvhash_map TTextureInfoHash; + +DEFINE_INVASIVE_LIST(TextCacheNode); +IMPLEMENT_INVASIVE_LIST(TextCacheNode, m_PreviousSibling, m_NextSibling); + +struct STextTextureCache : public ITextTextureCache +{ + typedef Pool TPoolType; + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + NVScopedRefCounted m_TextRenderer; + TTextureInfoHash m_TextureCache; + TTextCacheNodeList m_LRUList; + TPoolType m_CacheNodePool; + QT3DSU32 m_HighWaterMark; + QT3DSU32 m_FrameCount; + QT3DSU32 m_TextureTotalBytes; + NVScopedRefCounted m_RenderContext; + bool m_CanUsePathRendering; ///< true if we use hardware accelerated font rendering + + STextTextureCache(NVFoundationBase &inFnd, ITextRenderer &inRenderer, + NVRenderContext &inRenderContext) + : m_Foundation(inFnd) + , mRefCount(0) + , m_TextRenderer(inRenderer) + , m_TextureCache(m_Foundation.getAllocator(), "STextTextureCache::m_TextureCache") + , m_CacheNodePool(ForwardingAllocator(m_Foundation.getAllocator(), + "STextTextureCache::m_CacheNodePool")) + , m_HighWaterMark(0x100000) + , m_FrameCount(0) + , m_TextureTotalBytes(0) + , m_RenderContext(inRenderContext) + { + // hardware accelerate font rendering not ready yet + m_CanUsePathRendering = (m_RenderContext->IsPathRenderingSupported() + && m_RenderContext->IsProgramPipelineSupported()); + } + + virtual ~STextTextureCache() + { + for (TTextCacheNodeList::iterator iter = m_LRUList.begin(), end = m_LRUList.end(); + iter != end; ++iter) + iter->~STextCacheNode(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + static inline QT3DSU32 GetNumBytes(NVRenderTexture2D &inTexture) + { + STextureDetails theDetails(inTexture.GetTextureDetails()); + return theDetails.m_Width * theDetails.m_Height + * NVRenderTextureFormats::getSizeofFormat(theDetails.m_Format); + } + + NVScopedRefCounted InvalidateLastItem() + { + NVScopedRefCounted nextTexture; + if (m_LRUList.empty() == false) { + STextCacheNode &theEnd = m_LRUList.back(); + if (theEnd.m_FrameCount != m_FrameCount) { + nextTexture = theEnd.m_TextInfo.second.second; + STextureDetails theDetails = nextTexture->GetTextureDetails(); + m_TextureTotalBytes -= GetNumBytes(*nextTexture.mPtr); + m_LRUList.remove(theEnd); + // copy the key because the next statement will destroy memory + m_TextureCache.erase(theEnd.m_RenderInfo); + theEnd.~STextCacheNode(); + m_CacheNodePool.deallocate(&theEnd); + } + } + return nextTexture; + } + + TTPathObjectAndTexture RenderText(const STextRenderInfo &inText, QT3DSF32 inScaleFactor) override + { + STextRenderInfoAndHash theKey(inText, inScaleFactor); + TTextureInfoHash::iterator theFind( + m_TextureCache.find(STextRenderInfoAndHash(inText, inScaleFactor))); + STextCacheNode *retval = NULL; + if (theFind != m_TextureCache.end()) { + retval = theFind->second; + m_LRUList.remove(*retval); + } else { + NVScopedRefCounted nextTexture; + if (m_TextureTotalBytes >= m_HighWaterMark && m_LRUList.empty() == false) + nextTexture = InvalidateLastItem(); + + if (nextTexture.mPtr == NULL) + nextTexture = m_RenderContext->CreateTexture2D(); + + NVScopedRefCounted nextPathFontItemObject; + NVScopedRefCounted nextPathFontObject; + // HW acceleration for fonts not supported + //if (m_CanUsePathRendering && inText.m_EnableAcceleratedFont) { + // nextPathFontItemObject = m_RenderContext->CreatePathFontItem(); + // nextPathFontObject = m_RenderContext->CreatePathFontSpecification(inText.m_Font); + //} + + STextRenderInfo theTextInfo(inText); + theTextInfo.m_FontSize *= inScaleFactor; + STextTextureDetails theDetails; + + + // HW acceleration for fonts not supported + //if (!m_CanUsePathRendering || !inText.m_EnableAcceleratedFont) + theDetails = m_TextRenderer->RenderText(theTextInfo, *nextTexture.mPtr); + //else + // theDetails = m_TextRenderer->RenderText(theTextInfo, *nextPathFontItemObject.mPtr, + // *nextPathFontObject.mPtr); + + if (fabs(inScaleFactor - 1.0f) > .001f) { + TTPathObjectAndTexture theCanonicalDetails = RenderText(inText, 1.0f); + theDetails.m_ScaleFactor.x = + (QT3DSF32)theDetails.m_TextWidth / theCanonicalDetails.second.first.m_TextWidth; + theDetails.m_ScaleFactor.y = + (QT3DSF32)theDetails.m_TextHeight / theCanonicalDetails.second.first.m_TextHeight; + } + theKey = STextRenderInfoAndHash(inText, inScaleFactor); + retval = m_CacheNodePool.construct( + theKey, TTPathObjectAndTexture( + TPathFontSpecAndPathObject(nextPathFontObject, nextPathFontItemObject), + TTextTextureDetailsAndTexture(theDetails, nextTexture)), + __FILE__, __LINE__); + TTextureInfoHash::iterator insert = + m_TextureCache.insert(eastl::make_pair(theKey, retval)).first; + if (!m_CanUsePathRendering) + m_TextureTotalBytes += GetNumBytes(*(retval->m_TextInfo.second.second.mPtr)); + } + retval->m_FrameCount = m_FrameCount; + m_LRUList.push_front(*retval); + return retval->m_TextInfo; + } + // We may have one more texture in cache than this byte count, but this will be the limiting + // factor. + QT3DSU32 GetCacheHighWaterBytes() const override { return m_HighWaterMark; } + // default cache size is 10 MB. + void SetCacheHighWaterBytes(QT3DSU32 inByteCount) override { m_HighWaterMark = inByteCount; } + + void BeginFrame() override {} + void EndFrame() override + { + // algorithm is resistant to rollover. + ++m_FrameCount; + // Release any texture that put us over the limit. + // This almost guarantees thrashing if the limit is set too low. Enable at your + // own risk at *TEST CAREFULLY* + /* + while( m_TextureTotalBytes >= m_HighWaterMark && m_LRUList.empty() == false ) + InvalidateLastItem(); + */ + } +}; +} + +ITextTextureCache &ITextTextureCache::CreateTextureCache(NVFoundationBase &inFnd, + ITextRenderer &inTextRenderer, + NVRenderContext &inRenderContext) +{ + return *QT3DS_NEW(inFnd.getAllocator(), STextTextureCache)(inFnd, inTextRenderer, inRenderContext); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.h b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.h new file mode 100644 index 00000000..45d40217 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTextureCache.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TEXT_TEXTURE_CACHE_H +#define QT3DS_RENDER_TEXT_TEXTURE_CACHE_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSRenderText.h" +#include "EASTL/algorithm.h" + +namespace qt3ds { +namespace render { + + class ITextRenderer; + + typedef eastl::pair, + NVScopedRefCounted> + TPathFontSpecAndPathObject; + typedef eastl::pair> + TTextTextureDetailsAndTexture; + typedef eastl::pair + TTPathObjectAndTexture; + + class ITextTextureCache : public NVRefCounted + { + protected: + virtual ~ITextTextureCache() {} + public: + virtual TTPathObjectAndTexture RenderText(const STextRenderInfo &inText, + QT3DSF32 inScaleFactor) = 0; + // We may have one more texture in cache than this byte count, but this will be the limiting + // factor. + virtual QT3DSU32 GetCacheHighWaterBytes() const = 0; + virtual void SetCacheHighWaterBytes(QT3DSU32 inNumBytes) = 0; + + virtual void BeginFrame() = 0; + // We need to know the frame rhythm because we can't release anything that was touched this + // frame. + virtual void EndFrame() = 0; + + static ITextTextureCache &CreateTextureCache(NVFoundationBase &inFnd, + ITextRenderer &inTextRenderer, + NVRenderContext &inRenderContext); + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextTypes.h b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTypes.h new file mode 100644 index 00000000..72ea9c15 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextTypes.h @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TEXT_TYPES_H +#define QT3DS_RENDER_TEXT_TYPES_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSVec2.h" + +namespace qt3ds { +namespace render { + + struct TextHorizontalAlignment + { + enum Enum { + Unknown = 0, + Left, + Center, + Right, + }; + }; + + struct TextVerticalAlignment + { + enum Enum { + Unknown = 0, + Top, + Middle, + Bottom, + }; + }; + + struct TextWordWrap + { + enum Enum { + Unknown = 0, + Clip, + WrapWord, + WrapAnywhere, + }; + }; + + struct TextElide + { + enum Enum { + ElideNone = 0, + ElideLeft, + ElideMiddle, + ElideRight, + }; + }; + + struct STextDimensions + { + QT3DSU32 m_TextWidth; + QT3DSU32 m_TextHeight; + STextDimensions(QT3DSU32 w, QT3DSU32 h) + : m_TextWidth(w) + , m_TextHeight(h) + { + } + STextDimensions() + : m_TextWidth(0) + , m_TextHeight(0) + { + } + }; + + struct STextTextureDetails : public STextDimensions + { + QT3DSVec2 m_ScaleFactor; + bool m_FlipY; + STextTextureDetails(QT3DSU32 w, QT3DSU32 h, bool inFlipY, QT3DSVec2 scaleF) + : STextDimensions(w, h) + , m_ScaleFactor(scaleF) + , m_FlipY(inFlipY) + { + } + STextTextureDetails() + : m_ScaleFactor(1.0f) + , m_FlipY(false) + { + } + }; + + struct STextTextureAtlasEntryDetails : public STextDimensions + { + QT3DSI32 m_X, m_Y; + STextTextureAtlasEntryDetails(QT3DSU32 w, QT3DSU32 h, QT3DSI32 x, QT3DSI32 y) + : STextDimensions(w, h) + , m_X(x) + , m_Y(y) + { + } + STextTextureAtlasEntryDetails() + : m_X(0) + , m_Y(0) + { + } + }; + + struct SRenderTextureAtlasDetails + { + QT3DSU32 m_VertexCount; + NVDataRef m_Vertices; + + SRenderTextureAtlasDetails(QT3DSU32 count, NVDataRef inVertices) + : m_VertexCount(count) + , m_Vertices(inVertices) + { + } + SRenderTextureAtlasDetails() + : m_VertexCount(0) + , m_Vertices(NVDataRef()) + { + } + }; + + struct STextTextureAtlasDetails : public STextTextureDetails + { + QT3DSU32 m_EntryCount; + STextTextureAtlasDetails(QT3DSU32 w, QT3DSU32 h, bool inFlipY, QT3DSU32 count) + : STextTextureDetails(w, h, inFlipY, QT3DSVec2(1.0f)) + , m_EntryCount(count) + { + } + STextTextureAtlasDetails() + : m_EntryCount(0) + { + } + }; + + // Adding/removing a member to this object means you need to update the texture cache code + // - UICRenderTextTextureCache.cpp + + struct STextRenderInfo + { + CRegisteredString m_Text; + CRegisteredString m_Font; + QT3DSF32 m_FontSize; + TextHorizontalAlignment::Enum m_HorizontalAlignment; + TextVerticalAlignment::Enum m_VerticalAlignment; + QT3DSF32 m_Leading; // space between lines + QT3DSF32 m_Tracking; // space between letters + bool m_DropShadow; + QT3DSF32 m_DropShadowStrength; + QT3DSF32 m_DropShadowOffset; // To be removed in 2.x (when UIP version is next updated) + QT3DSF32 m_DropShadowOffsetX; + QT3DSF32 m_DropShadowOffsetY; + TextHorizontalAlignment::Enum m_DropShadowHorizontalAlignment; // To be removed in 2.x (when UIP version is next updated) + TextVerticalAlignment::Enum m_DropShadowVerticalAlignment; // To be removed in 2.x (when UIP version is next updated) + TextWordWrap::Enum m_WordWrap; + QT3DSVec2 m_BoundingBox; + TextElide::Enum m_Elide; + + QT3DSF32 m_ScaleX; // Pixel scale in X + QT3DSF32 m_ScaleY; // Pixel scale in Y + + bool m_EnableAcceleratedFont; ///< use NV path rendering + + STextRenderInfo(); + ~STextRenderInfo(); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.cpp new file mode 100644 index 00000000..062e7d57 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.cpp @@ -0,0 +1,364 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderTextureAtlas.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderContext.h" + +using namespace qt3ds::render; + +namespace { + +// a algorithm based on http://clb.demon.fi/files/RectangleBinPack/ +struct STextureAtlasBinPackSL +{ +public: + STextureAtlasBinPackSL(NVRenderContext &inContext, QT3DSI32 width, QT3DSI32 height) + : m_BinWidth(width) + , m_BinHeight(height) + , m_SkyLine(inContext.GetAllocator(), "STextureAtlasBinPackSL::m_SkyLine") + { + // setup first entry + SSkylineNode theNode = { 0, 0, width }; + m_SkyLine.push_back(theNode); + } + + ~STextureAtlasBinPackSL() { m_SkyLine.clear(); } + + /* insert new rect + * + */ + STextureAtlasRect Insert(QT3DSI32 width, QT3DSI32 height) + { + QT3DSI32 binHeight; + QT3DSI32 binWidth; + QT3DSI32 binIndex; + + STextureAtlasRect newNode = findPosition(width, height, &binWidth, &binHeight, &binIndex); + + if (binIndex != -1) { + // adjust skyline nodes + addSkylineLevelNode(binIndex, newNode); + } + + return newNode; + } + +private: + /// Represents a single level (a horizontal line) of the skyline/horizon/envelope. + struct SSkylineNode + { + int x; ///< The starting x-coordinate (leftmost). + int y; ///< The y-coordinate of the skyline level line. + int width; /// The line width. The ending coordinate (inclusive) will be x+width-1. + }; + + /* find position + * + */ + STextureAtlasRect findPosition(QT3DSI32 width, QT3DSI32 height, QT3DSI32 *binWidth, QT3DSI32 *binHeight, + QT3DSI32 *binIndex) + { + *binWidth = m_BinWidth; + *binHeight = m_BinHeight; + *binIndex = -1; + STextureAtlasRect newRect; + + for (QT3DSU32 i = 0; i < m_SkyLine.size(); ++i) { + QT3DSI32 y = getSkylineLevel(i, width, height); + + if (y >= 0) { + if ((y + height < *binHeight) + || ((y + height == *binHeight) && m_SkyLine[i].width < *binWidth)) { + *binHeight = y + height; + *binIndex = i; + *binWidth = m_SkyLine[i].width; + newRect.m_X = m_SkyLine[i].x; + newRect.m_Y = y; + newRect.m_Width = width; + newRect.m_Height = height; + } + } + } + + return newRect; + } + + /* @brief check if rectangle can be placed into the the bin + * + * return skyline hight + */ + int getSkylineLevel(QT3DSU32 binIndex, QT3DSI32 width, QT3DSI32 height) + { + // first check width exceed + QT3DSI32 x = m_SkyLine[binIndex].x; + if (x + width > m_BinWidth) + return -1; + + QT3DSI32 leftAlign = width; + QT3DSU32 index = binIndex; + QT3DSI32 y = m_SkyLine[index].y; + + while (leftAlign > 0) { + y = (y > m_SkyLine[index].y) ? y : m_SkyLine[index].y; + // check hight + if (y + height > m_BinHeight) + return -1; + + leftAlign -= m_SkyLine[index].width; + ++index; + + if (index > m_SkyLine.size()) + return -1; + } + + return y; + } + + /* @brief add an new skyline entry + * + * return no return + */ + void addSkylineLevelNode(QT3DSI32 binIndex, const STextureAtlasRect &newRect) + { + SSkylineNode newNode; + + newNode.x = newRect.m_X; + newNode.y = newRect.m_Y + newRect.m_Height; + newNode.width = newRect.m_Width; + m_SkyLine.insert(m_SkyLine.begin() + binIndex, newNode); + + // iterate over follow up nodes and adjust + for (QT3DSU32 i = binIndex + 1; i < m_SkyLine.size(); ++i) { + if (m_SkyLine[i].x < m_SkyLine[i - 1].x + m_SkyLine[i - 1].width) { + int shrink = m_SkyLine[i - 1].x + m_SkyLine[i - 1].width - m_SkyLine[i].x; + + m_SkyLine[i].x += shrink; + m_SkyLine[i].width -= shrink; + + if (m_SkyLine[i].width <= 0) { + m_SkyLine.erase(m_SkyLine.begin() + i); + --i; + } else { + break; + } + } else { + break; + } + } + + mergeSkylineLevelNodes(); + } + + /* @brief merge skyline node + * + * return no return + */ + void mergeSkylineLevelNodes() + { + // check if we can merge nodes + for (QT3DSU32 i = 0; i < m_SkyLine.size() - 1; ++i) { + if (m_SkyLine[i].y == m_SkyLine[i + 1].y) { + m_SkyLine[i].width += m_SkyLine[i + 1].width; + m_SkyLine.erase(m_SkyLine.begin() + (i + 1)); + --i; + } + } + } + + QT3DSI32 m_BinWidth; + QT3DSI32 m_BinHeight; + + nvvector m_SkyLine; +}; + +struct STextureAtlasEntry +{ + STextureAtlasEntry() + : m_X(0) + , m_Y(0) + , m_Width(0) + , m_Height(0) + , m_pBuffer(NVDataRef()) + { + } + STextureAtlasEntry(QT3DSF32 x, QT3DSF32 y, QT3DSF32 w, QT3DSF32 h, NVDataRef buffer) + : m_X(x) + , m_Y(y) + , m_Width(w) + , m_Height(h) + , m_pBuffer(buffer) + { + } + STextureAtlasEntry(const STextureAtlasEntry &entry) + { + m_X = entry.m_X; + m_Y = entry.m_Y; + m_Width = entry.m_Width; + m_Height = entry.m_Height; + m_pBuffer = entry.m_pBuffer; + } + ~STextureAtlasEntry() {} + + QT3DSF32 m_X, m_Y; + QT3DSF32 m_Width, m_Height; + NVDataRef m_pBuffer; +}; + +struct STextureAtlas : public ITextureAtlas +{ + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + NVScopedRefCounted m_RenderContext; + + STextureAtlas(NVFoundationBase &inFnd, NVRenderContext &inRenderContext, QT3DSI32 width, + QT3DSI32 height) + : m_Foundation(inFnd) + , mRefCount(0) + , m_RenderContext(inRenderContext) + , m_Width(width) + , m_Height(height) + , m_Spacing(1) + , m_AtlasEntrys(inFnd.getAllocator(), "STextureAtlas::m_SkyLine") + { + m_pBinPack = + QT3DS_NEW(inFnd.getAllocator(), STextureAtlasBinPackSL)(inRenderContext, width, height); + } + + virtual ~STextureAtlas() + { + RelaseEntries(); + + if (m_pBinPack) + NVDelete(m_Foundation.getAllocator(), m_pBinPack); + } + + void RelaseEntries() override + { + nvvector::iterator it; + + for (it = m_AtlasEntrys.begin(); it != m_AtlasEntrys.end(); it++) { + QT3DS_FREE(m_Foundation.getAllocator(), it->m_pBuffer.begin()); + } + + m_AtlasEntrys.clear(); + } + QT3DSI32 GetWidth() const override { return m_Width; } + QT3DSI32 GetHeight() const override { return m_Height; } + + QT3DSI32 GetAtlasEntryCount() const override { return m_AtlasEntrys.size(); } + + TTextureAtlasEntryAndBuffer GetAtlasEntryByIndex(QT3DSU32 index) override + { + if (index >= m_AtlasEntrys.size()) + return eastl::make_pair(STextureAtlasRect(), NVDataRef()); + + return eastl::make_pair(STextureAtlasRect((QT3DSI32)m_AtlasEntrys[index].m_X, + (QT3DSI32)m_AtlasEntrys[index].m_Y, + (QT3DSI32)m_AtlasEntrys[index].m_Width, + (QT3DSI32)m_AtlasEntrys[index].m_Height), + m_AtlasEntrys[index].m_pBuffer); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + STextureAtlasRect AddAtlasEntry(QT3DSI32 width, QT3DSI32 height, QT3DSI32 pitch, + QT3DSI32 dataWidth, NVConstDataRef bufferData) override + { + STextureAtlasRect rect; + + // pitch is the number of bytes per line in bufferData + // dataWidth is the relevant data width in bufferData. Rest is padding that can be ignored. + if (m_pBinPack) { + QT3DSI32 paddedWith, paddedPitch, paddedHeight; + // add spacing around the character + paddedWith = width + 2 * m_Spacing; + paddedPitch = dataWidth + 2 * m_Spacing; + paddedHeight = height + 2 * m_Spacing; + // first get entry in the texture atlas + rect = m_pBinPack->Insert(paddedWith, paddedHeight); + if (rect.m_Width == 0) + return rect; + + // we align the data be to 4 byte + int alignment = (4 - (paddedPitch % 4)) % 4; + paddedPitch += alignment; + + // since we do spacing around the character we need to copy line by line + QT3DSU8 *glyphBuffer = + (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), + paddedHeight * paddedPitch * sizeof(QT3DSU8), "STextureAtlas"); + if (glyphBuffer) { + memset(glyphBuffer, 0, paddedHeight * paddedPitch); + + QT3DSU8 *pDst = glyphBuffer + paddedPitch + m_Spacing; + QT3DSU8 *pSrc = const_cast(bufferData.begin()); + for (QT3DSI32 i = 0; i < height; ++i) { + memcpy(pDst, pSrc, dataWidth); + + pDst += paddedPitch; + pSrc += pitch; + } + + // add new entry + m_AtlasEntrys.push_back(STextureAtlasEntry( + (QT3DSF32)rect.m_X, (QT3DSF32)rect.m_Y, (QT3DSF32)paddedWith, (QT3DSF32)paddedHeight, + NVDataRef(glyphBuffer, paddedHeight * paddedPitch * sizeof(QT3DSU8)))); + + // normalize texture coordinates + rect.m_NormX = (QT3DSF32)rect.m_X / (QT3DSF32)m_Width; + rect.m_NormY = (QT3DSF32)rect.m_Y / (QT3DSF32)m_Height; + rect.m_NormWidth = (QT3DSF32)paddedWith / (QT3DSF32)m_Width; + rect.m_NormHeight = (QT3DSF32)paddedHeight / (QT3DSF32)m_Height; + } + } + + return rect; + } + +private: + QT3DSI32 m_Width; ///< texture atlas width + QT3DSI32 m_Height; ///< texture atlas height + QT3DSI32 m_Spacing; ///< spacing around the entry + nvvector m_AtlasEntrys; ///< our entries in the atlas + STextureAtlasBinPackSL *m_pBinPack; ///< our bin packer which actually does most of the work +}; + +} // namespace + +ITextureAtlas &ITextureAtlas::CreateTextureAtlas(NVFoundationBase &inFnd, + NVRenderContext &inRenderContext, QT3DSI32 width, + QT3DSI32 height) +{ + return *QT3DS_NEW(inFnd.getAllocator(), STextureAtlas)(inFnd, inRenderContext, width, height); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.h b/src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.h new file mode 100644 index 00000000..46f7bdb5 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderTextureAtlas.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TEXTURE_ATLAS_H +#define QT3DS_RENDER_TEXTURE_ATLAS_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "EASTL/algorithm.h" + +namespace qt3ds { +namespace render { + + class ITextRenderer; + + struct STextureAtlasRect + { + + STextureAtlasRect() + : m_X(0) + , m_Y(0) + , m_Width(0) + , m_Height(0) + { + } + + STextureAtlasRect(QT3DSI32 x, QT3DSI32 y, QT3DSI32 w, QT3DSI32 h) + : m_X(x) + , m_Y(y) + , m_Width(w) + , m_Height(h) + { + } + + QT3DSI32 m_X; + QT3DSI32 m_Y; + QT3DSI32 m_Width; + QT3DSI32 m_Height; + + // normalized coordinates + QT3DSF32 m_NormX; + QT3DSF32 m_NormY; + QT3DSF32 m_NormWidth; + QT3DSF32 m_NormHeight; + }; + + typedef eastl::pair> TTextureAtlasEntryAndBuffer; + + /** + * Abstract class of a texture atlas representation + */ + class ITextureAtlas : public NVRefCounted + { + protected: + virtual ~ITextureAtlas() {} + + public: + virtual QT3DSI32 GetWidth() const = 0; + virtual QT3DSI32 GetHeight() const = 0; + virtual QT3DSI32 GetAtlasEntryCount() const = 0; + virtual TTextureAtlasEntryAndBuffer GetAtlasEntryByIndex(QT3DSU32 index) = 0; + + virtual STextureAtlasRect AddAtlasEntry(QT3DSI32 width, QT3DSI32 height, QT3DSI32 pitch, + QT3DSI32 dataWidth, + NVConstDataRef bufferData) = 0; + virtual void RelaseEntries() = 0; + + static ITextureAtlas &CreateTextureAtlas(NVFoundationBase &inFnd, + NVRenderContext &inRenderContext, QT3DSI32 width, + QT3DSI32 height); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.cpp new file mode 100644 index 00000000..70499c62 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.cpp @@ -0,0 +1,327 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderThreadPool.h" +#include "foundation/Qt3DSThread.h" +#include "EASTL/utility.h" +#include "EASTL/list.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" + +using namespace qt3ds::render; + +namespace { +struct STask +{ + void *m_UserData; + TTaskFunction m_Function; + TTaskFunction m_CancelFunction; + QT3DSU64 m_Id; + TaskStates::Enum m_TaskState; + STask *m_NextTask; + STask *m_PreviousTask; + + STask(void *ud, TTaskFunction func, TTaskFunction cancelFunc, QT3DSU64 inId) + : m_UserData(ud) + , m_Function(func) + , m_CancelFunction(cancelFunc) + , m_Id(inId) + , m_TaskState(TaskStates::Queued) + , m_NextTask(NULL) + , m_PreviousTask(NULL) + { + } + STask() + : m_UserData(NULL) + , m_Function(NULL) + , m_CancelFunction(NULL) + , m_Id(0) + , m_TaskState(TaskStates::UnknownTask) + , m_NextTask(NULL) + , m_PreviousTask(NULL) + { + } + void CallFunction() + { + if (m_Function) + m_Function(m_UserData); + } + void Cancel() + { + if (m_CancelFunction) + m_CancelFunction(m_UserData); + } +}; + +struct STaskHeadOp +{ + STask *get(STask &inTask) { return inTask.m_PreviousTask; } + void set(STask &inTask, STask *inItem) { inTask.m_PreviousTask = inItem; } +}; + +struct STaskTailOp +{ + STask *get(STask &inTask) { return inTask.m_NextTask; } + void set(STask &inTask, STask *inItem) { inTask.m_NextTask = inItem; } +}; + +typedef InvasiveLinkedList TTaskList; + +class IInternalTaskManager +{ +protected: + virtual ~IInternalTaskManager() {} +public: + virtual STask GetNextTask() = 0; + virtual void TaskFinished(QT3DSU64 inId) = 0; +}; + +struct SThreadPoolThread : public Thread +{ + IInternalTaskManager &m_Mgr; + SThreadPoolThread(NVFoundationBase &foundation, IInternalTaskManager &inMgr) + : Thread(foundation) + , m_Mgr(inMgr) + { + } + void execute(void) override + { + setName("Qt3DSRender Thread manager thread"); + while (!quitIsSignalled()) { + STask task = m_Mgr.GetNextTask(); + if (task.m_Function) { + task.CallFunction(); + m_Mgr.TaskFinished(task.m_Id); + } + } + quit(); + } +}; + +struct SThreadPool : public IThreadPool, public IInternalTaskManager +{ + typedef nvhash_map TIdTaskMap; + typedef Mutex::ScopedLock TLockType; + typedef Pool TTaskPool; + + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + nvvector m_Threads; + TIdTaskMap m_Tasks; + Sync m_TaskListEvent; + volatile bool m_Running; + Mutex m_TaskListMutex; + TTaskPool m_TaskPool; + TTaskList m_TaskList; + + QT3DSU64 m_NextId; + + SThreadPool(NVFoundationBase &inBase, QT3DSU32 inMaxThreads) + : m_Foundation(inBase) + , mRefCount(0) + , m_Threads(inBase.getAllocator(), "SThreadPool::m_Threads") + , m_Tasks(inBase.getAllocator(), "SThreadPool::m_Tasks") + , m_TaskListEvent(inBase.getAllocator()) + , m_Running(true) + , m_TaskListMutex(m_Foundation.getAllocator()) + , m_TaskPool(ForwardingAllocator(m_Foundation.getAllocator(), "SThreadPool::m_TaskPool")) + , m_NextId(1) + { + // Fire up our little pools of chaos. + for (QT3DSU32 idx = 0; idx < inMaxThreads; ++idx) { + m_Threads.push_back( + QT3DS_NEW(m_Foundation.getAllocator(), SThreadPoolThread)(m_Foundation, *this)); + m_Threads.back()->start(Thread::DEFAULT_STACK_SIZE); + } + } + + void MutexHeldRemoveTaskFromList(STask *theTask) + { + if (theTask) + m_TaskList.remove(*theTask); + QT3DS_ASSERT(theTask->m_NextTask == NULL); + QT3DS_ASSERT(theTask->m_PreviousTask == NULL); + } + + STask *MutexHeldNextTask() + { + STask *theTask = m_TaskList.front_ptr(); + if (theTask) { + MutexHeldRemoveTaskFromList(theTask); + } + if (theTask) { + QT3DS_ASSERT(m_TaskList.m_Head != theTask); + QT3DS_ASSERT(m_TaskList.m_Tail != theTask); + } + return theTask; + } + + virtual ~SThreadPool() + { + m_Running = false; + + m_TaskListEvent.set(); + + for (QT3DSU32 idx = 0, end = m_Threads.size(); idx < end; ++idx) + m_Threads[idx]->signalQuit(); + + for (QT3DSU32 idx = 0, end = m_Threads.size(); idx < end; ++idx) { + m_Threads[idx]->waitForQuit(); + NVDelete(m_Foundation.getAllocator(), m_Threads[idx]); + } + + m_Threads.clear(); + + TLockType __listMutexLocker(m_TaskListMutex); + + for (STask *theTask = MutexHeldNextTask(); theTask; theTask = MutexHeldNextTask()) { + theTask->Cancel(); + } + + m_Tasks.clear(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void VerifyTaskList() + { + STask *theLastTask = NULL; + for (STask *theTask = m_TaskList.m_Head; theTask; theTask = theTask->m_NextTask) { + QT3DS_ASSERT(theTask->m_PreviousTask == theLastTask); + theLastTask = theTask; + } + theLastTask = NULL; + for (STask *theTask = m_TaskList.m_Tail; theTask; theTask = theTask->m_PreviousTask) { + QT3DS_ASSERT(theTask->m_NextTask == theLastTask); + theLastTask = theTask; + } + } + + QT3DSU64 AddTask(void *inUserData, TTaskFunction inFunction, + TTaskFunction inCancelFunction) override + { + if (inFunction && m_Running) { + TLockType __listMutexLocker(m_TaskListMutex); + QT3DSU64 taskId = m_NextId; + ++m_NextId; + + STask *theTask = (STask *)m_TaskPool.allocate(__FILE__, __LINE__); + new (theTask) STask(inUserData, inFunction, inCancelFunction, taskId); + TIdTaskMap::iterator theTaskIter = + m_Tasks.insert(eastl::make_pair(taskId, theTask)).first; + + m_TaskList.push_back(*theTask); + QT3DS_ASSERT(m_TaskList.m_Tail == theTask); + +#ifdef _DEBUG + VerifyTaskList(); +#endif + m_TaskListEvent.set(); + m_TaskListEvent.reset(); + return taskId; + } + QT3DS_ASSERT(false); + return 0; + } + + TaskStates::Enum GetTaskState(QT3DSU64 inTaskId) override + { + TLockType __listMutexLocker(m_TaskListMutex); + TIdTaskMap::iterator theTaskIter = m_Tasks.find(inTaskId); + if (theTaskIter != m_Tasks.end()) + return theTaskIter->second->m_TaskState; + return TaskStates::UnknownTask; + } + + CancelReturnValues::Enum CancelTask(QT3DSU64 inTaskId) override + { + TLockType __listMutexLocker(m_TaskListMutex); + TIdTaskMap::iterator theTaskIter = m_Tasks.find(inTaskId); + if (theTaskIter == m_Tasks.end()) + return CancelReturnValues::TaskCanceled; + if (theTaskIter->second->m_TaskState == TaskStates::Running) + return CancelReturnValues::TaskRunning; + + STask *theTask = theTaskIter->second; + theTask->Cancel(); + MutexHeldRemoveTaskFromList(theTask); + m_Tasks.erase(inTaskId); + m_TaskPool.deallocate(theTask); + + return CancelReturnValues::TaskCanceled; + } + + STask GetNextTask() override + { + + if (m_Running) { + { + TLockType __listMutexLocker(m_TaskListMutex); + STask *retval = MutexHeldNextTask(); + if (retval) + return *retval; + } + // If we couldn't get a task then wait. + m_TaskListEvent.wait(1000); + } + return STask(); + } + + void TaskFinished(QT3DSU64 inId) override + { + TLockType __listMutexLocker(m_TaskListMutex); + TIdTaskMap::iterator theTaskIter = m_Tasks.find(inId); + if (theTaskIter == m_Tasks.end()) { + QT3DS_ASSERT(false); + return; + } + + STask *theTask(theTaskIter->second); + +#ifdef _DEBUG + QT3DS_ASSERT(theTask->m_NextTask == NULL); + QT3DS_ASSERT(theTask->m_PreviousTask == NULL); +#endif + m_TaskPool.deallocate(theTask); + m_Tasks.erase(inId); + return; + } +}; +} + +IThreadPool &IThreadPool::CreateThreadPool(NVFoundationBase &inFoundation, QT3DSU32 inNumThreads) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SThreadPool)(inFoundation, inNumThreads); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.h b/src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.h new file mode 100644 index 00000000..d39f226f --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderThreadPool.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_THREAD_POOL_H +#define QT3DS_RENDER_THREAD_POOL_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" + +namespace qt3ds { +namespace render { + + typedef void (*TTaskFunction)(void *inUserData); + + struct TaskStates + { + enum Enum { + UnknownTask = 0, + Queued, + Running, + }; + }; + + struct CancelReturnValues + { + enum Enum { + TaskCanceled = 0, + TaskRunning, + TaskNotFound, + }; + }; + + class IThreadPool : public NVRefCounted + { + protected: + virtual ~IThreadPool() {} + public: + // Add a task to be run at some point in the future. + // Tasks will be run roughly in order they are given. + // The returned value is a handle that can be used to query + // details about the task + // Cancel function will be called if the thread pool is destroyed or + // of the task gets canceled. + virtual QT3DSU64 AddTask(void *inUserData, TTaskFunction inFunction, + TTaskFunction inCancelFunction) = 0; + virtual TaskStates::Enum GetTaskState(QT3DSU64 inTaskId) = 0; + virtual CancelReturnValues::Enum CancelTask(QT3DSU64 inTaskId) = 0; + + static IThreadPool &CreateThreadPool(NVFoundationBase &inFoundation, + QT3DSU32 inNumThreads = 4); + }; +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.cpp new file mode 100644 index 00000000..f64efbcc --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.cpp @@ -0,0 +1,2065 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifdef QT3DS_RENDER_ENABLE_LOAD_UIP + +#include "Qt3DSRenderUIPLoader.h" +#include "Qt3DSRenderPresentation.h" +#include "Qt3DSRenderNode.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderModel.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderImage.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderUIPSharedTranslation.h" +#include +#include +#include +#ifdef EA_PLATFORM_WINDOWS +#pragma warning(disable : 4201) +#endif +#include "Qt3DSDMXML.h" +#include "Qt3DSTypes.h" +#include "Qt3DSVector3.h" +#include "Qt3DSMetadata.h" +#include "Qt3DSDMWStrOps.h" +#include "Qt3DSDMWStrOpsImpl.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSDMComposerTypeDefinitions.h" +#include "EASTL/string.h" +#include "foundation/StrConvertUTF.h" +#include "Qt3DSRenderEffectSystem.h" +#include "Qt3DSRenderString.h" +#include "foundation/FileTools.h" +#include "Qt3DSRenderDynamicObjectSystemCommands.h" +#include "EASTL/map.h" +#include "Qt3DSRenderEffect.h" +#include "Qt3DSDMMetaDataTypes.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderPlugin.h" +#include "Qt3DSRenderPluginGraphObject.h" +#include "Qt3DSRenderPluginPropertyValue.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderMaterialHelpers.h" +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderPathSubPath.h" +#include "Qt3DSRenderPathManager.h" +#include "q3dsvariantconfig_p.h" + +using qt3ds::foundation::Option; +using qt3ds::foundation::Empty; +using qt3ds::QT3DSF32; +using qt3ds::QT3DSVec3; +using qt3ds::foundation::nvvector; +using qt3ds::QT3DSU32; +using qt3ds::render::RenderLightTypes; +using qt3ds::render::DefaultMaterialLighting; +using qt3ds::render::ImageMappingModes; +using qt3ds::render::DefaultMaterialBlendMode; +using qt3ds::render::NVRenderTextureCoordOp; +using qt3ds::foundation::IStringTable; +using qt3ds::NVFoundationBase; +using namespace qt3ds; +using namespace qt3ds::foundation; +using qt3ds::render::TIdObjectMap; +using qt3ds::render::IBufferManager; +using qt3ds::render::IEffectSystem; +using qt3ds::render::SPresentation; +using qt3ds::render::SScene; +using qt3ds::render::SLayer; +using qt3ds::render::SNode; +using qt3ds::render::SLight; +using qt3ds::render::SCamera; +using qt3ds::render::SModel; +using qt3ds::render::SText; +using qt3ds::render::SDefaultMaterial; +using qt3ds::render::SImage; +using qt3ds::render::SGraphObject; +using qt3ds::render::SDynamicObject; +using qt3ds::render::SEffect; +using qt3ds::render::SCustomMaterial; +using qt3ds::render::GraphObjectTypes; +using qt3ds::render::NodeFlags; +using qt3ds::foundation::CRegisteredString; +using qt3ds::render::CRenderString; +using qt3ds::foundation::CFileTools; +using qt3ds::render::SReferencedMaterial; +using qt3ds::render::IUIPReferenceResolver; +using qt3ds::render::SPath; +using qt3ds::render::SPathSubPath; +using qt3ds::render::SLightmaps; + +namespace qt3dsdm { +template <> +struct WStrOps +{ + void StrTo(const char8_t *buffer, SFloat2 &item, nvvector &ioTempBuf) + { + QT3DSU32 len = (QT3DSU32)strlen(buffer); + ioTempBuf.resize(len + 1); + memCopy(ioTempBuf.data(), buffer, (len + 1) * sizeof(char8_t)); + MemoryBuffer unused; + qt3dsdm::IStringTable *theTable(NULL); + WCharTReader reader(ioTempBuf.begin(), unused, *theTable); + reader.ReadRef(NVDataRef(item.m_Floats, 2)); + } +}; + +template <> +struct WStrOps +{ + void StrTo(const char8_t *buffer, SFloat3 &item, nvvector &ioTempBuf) + { + QT3DSU32 len = (QT3DSU32)strlen(buffer); + ioTempBuf.resize(len + 1); + memCopy(ioTempBuf.data(), buffer, (len + 1) * sizeof(char8_t)); + MemoryBuffer unused; + qt3dsdm::IStringTable *theTable(NULL); + WCharTReader reader(ioTempBuf.begin(), unused, *theTable); + reader.ReadRef(NVDataRef(item.m_Floats, 3)); + } +}; +} + +namespace { + +typedef eastl::basic_string TStrType; +struct IPropertyParser +{ + virtual ~IPropertyParser() {} + virtual Option ParseStr(const char8_t *inName) = 0; + virtual Option ParseFloat(const char8_t *inName) = 0; + virtual Option ParseVec2(const char8_t *inName) = 0; + virtual Option ParseVec3(const char8_t *inName) = 0; + virtual Option ParseBool(const char8_t *inName) = 0; + virtual Option ParseU32(const char8_t *inName) = 0; + virtual Option ParseI32(const char8_t *inName) = 0; + virtual Option ParseGraphObject(const char8_t *inName) = 0; + virtual Option ParseNode(const char8_t *inName) = 0; +}; +struct SMetaPropertyParser : public IPropertyParser +{ + Q3DStudio::IRuntimeMetaData &m_MetaData; + TStrType m_TempStr; + qt3ds::foundation::CRegisteredString m_Type; + qt3ds::foundation::CRegisteredString m_ClassId; + + SMetaPropertyParser(const char8_t *inType, const char8_t *inClass, + Q3DStudio::IRuntimeMetaData &inMeta) + : m_MetaData(inMeta) + , m_Type(inMeta.GetStringTable()->GetRenderStringTable().RegisterStr(inType)) + , m_ClassId(inMeta.GetStringTable()->GetRenderStringTable().RegisterStr(inClass)) + { + } + + qt3ds::foundation::CRegisteredString Register(const char8_t *inName) + { + return m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr(inName); + } + + Option ParseStr(const char8_t *inName) override + { + qt3ds::foundation::CRegisteredString theName(Register(inName)); + Q3DStudio::ERuntimeDataModelDataType theType( + m_MetaData.GetPropertyType(m_Type, theName, m_ClassId)); + if (theType != Q3DStudio::ERuntimeDataModelDataTypeObjectRef + && theType != Q3DStudio::ERuntimeDataModelDataTypeLong4) { + return m_MetaData.GetPropertyValueString(m_Type, theName, m_ClassId); + } + return Empty(); + } + Option ParseFloat(const char8_t *inName) override + { + return m_MetaData.GetPropertyValueFloat(m_Type, Register(inName), m_ClassId); + } + Option ParseVec2(const char8_t *inName) override + { + Option theProperty = + m_MetaData.GetPropertyValueVector2(m_Type, Register(inName), m_ClassId); + if (theProperty.hasValue()) { + return QT3DSVec2(theProperty->x, theProperty->y); + } + return Empty(); + } + Option ParseVec3(const char8_t *inName) override + { + Option theProperty = + m_MetaData.GetPropertyValueVector3(m_Type, Register(inName), m_ClassId); + if (theProperty.hasValue()) { + return *theProperty; + } + return Empty(); + } + Option ParseBool(const char8_t *inName) override + { + return m_MetaData.GetPropertyValueBool(m_Type, Register(inName), m_ClassId); + } + + Option ParseU32(const char8_t *inName) override + { + Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); + if (retval.hasValue()) + return (QT3DSU32)retval.getValue(); + return Empty(); + } + + Option ParseI32(const char8_t *inName) override + { + Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); + if (retval.hasValue()) + return (QT3DSI32)retval.getValue(); + return Empty(); + } + + Option ParseGraphObject(const char8_t *) override { return Empty(); } + Option ParseNode(const char8_t *) override { return Empty(); } +}; + +class IDOMReferenceResolver +{ +protected: + virtual ~IDOMReferenceResolver() {} +public: + virtual SGraphObject *ResolveReference(SGraphObject &inRootObject, const char *path) = 0; +}; + +struct SDomReaderPropertyParser : public IPropertyParser +{ + qt3dsdm::IDOMReader &m_Reader; + nvvector &m_TempBuf; + IDOMReferenceResolver &m_Resolver; + SGraphObject &m_Object; + + SDomReaderPropertyParser(qt3dsdm::IDOMReader &reader, nvvector &inTempBuf, + IDOMReferenceResolver &inResolver, SGraphObject &inObject) + : m_Reader(reader) + , m_TempBuf(inTempBuf) + , m_Resolver(inResolver) + , m_Object(inObject) + { + } + Option ParseStr(const char8_t *inName) override + { + const char8_t *retval; + if (m_Reader.Att(inName, retval)) + return TStrType(retval); + return Empty(); + } + Option ParseFloat(const char8_t *inName) override + { + QT3DSF32 retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + Option ParseVec2(const char8_t *inName) override + { + qt3dsdm::SFloat2 retval; + const char8_t *tempData; + if (m_Reader.UnregisteredAtt(inName, tempData)) { + qt3dsdm::WStrOps().StrTo(tempData, retval, m_TempBuf); + return QT3DSVec2(retval.m_Floats[0], retval.m_Floats[1]); + } + return Empty(); + } + Option ParseVec3(const char8_t *inName) override + { + qt3dsdm::SFloat3 retval; + const char8_t *tempData; + if (m_Reader.UnregisteredAtt(inName, tempData)) { + qt3dsdm::WStrOps().StrTo(tempData, retval, m_TempBuf); + return QT3DSVec3(retval.m_Floats[0], retval.m_Floats[1], retval.m_Floats[2]); + } + return Empty(); + } + Option ParseBool(const char8_t *inName) override + { + bool retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + + Option ParseU32(const char8_t *inName) override + { + QT3DSU32 retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + + Option ParseI32(const char8_t *inName) override + { + QT3DSI32 retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + + Option ParseGraphObject(const char8_t *inName) override + { + const char *temp; + if (m_Reader.UnregisteredAtt(inName, temp)) { + // Now we need to figure out if this is an element reference or if it is a relative path + // from the current element. + SGraphObject *retval = m_Resolver.ResolveReference(m_Object, temp); + if (retval) + return retval; + } + return Empty(); + } + + Option ParseNode(const char8_t *inName) override + { + Option obj = ParseGraphObject(inName); + if (obj.hasValue()) { + if (GraphObjectTypes::IsNodeType((*obj)->m_Type)) + return static_cast((*obj)); + } + return Empty(); + } +}; + +template +struct SParserHelper +{ +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseStr(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseFloat(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseVec2(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseVec3(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseBool(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseU32(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseI32(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseGraphObject(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseNode(inName); + } +}; + +struct SPathAndAnchorIndex +{ + SPathSubPath *m_Segment; + QT3DSU32 m_AnchorIndex; + SPathAndAnchorIndex(SPathSubPath *inSegment, QT3DSU32 inAnchorIndex) + : m_Segment(inSegment) + , m_AnchorIndex(inAnchorIndex) + { + } + SPathAndAnchorIndex() + : m_Segment(NULL) + , m_AnchorIndex(0) + { + } +}; + +struct SRenderUIPLoader : public IDOMReferenceResolver +{ + typedef qt3dsdm::IDOMReader::Scope TScope; + typedef eastl::map TIdStringMap; + typedef eastl::hash_map TIdPathAnchorIndexMap; + qt3dsdm::IDOMReader &m_Reader; + Q3DStudio::IRuntimeMetaData &m_MetaData; + IStringTable &m_StrTable; + NVFoundationBase &m_Foundation; + NVAllocatorCallback &m_PresentationAllocator; + qt3ds::render::TIdObjectMap &m_ObjectMap; + IBufferManager &m_BufferManager; + SPresentation *m_Presentation; + nvvector m_TempBuf; + TStrType m_TempParseString; + IEffectSystem &m_EffectSystem; + const char8_t *m_PresentationDir; + CRenderString m_PathString; + qt3ds::render::IRenderPluginManager &m_RenderPluginManager; + qt3ds::render::ICustomMaterialSystem &m_CustomMaterialSystem; + qt3ds::render::IDynamicObjectSystem &m_DynamicObjectSystem; + qt3ds::render::IPathManager &m_PathManager; + TIdStringMap m_RenderPluginSourcePaths; + IUIPReferenceResolver *m_ReferenceResolver; + MemoryBuffer m_TempBuffer; + MemoryBuffer m_ValueBuffer; + TIdPathAnchorIndexMap m_AnchorIdToPathAndAnchorIndexMap; + const Q3DSVariantConfig &m_variantConfig; + + SRenderUIPLoader(qt3dsdm::IDOMReader &inReader, const char8_t *inFullPathToPresentationFile, + Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable + // Allocator for datastructures we need to parse the file. + , + NVFoundationBase &inFoundation + // Allocator used for the presentation objects themselves + , + NVAllocatorCallback &inPresentationAllocator + // Map of string ids to objects + , + TIdObjectMap &ioObjectMap, IBufferManager &inBufferManager, + IEffectSystem &inEffectSystem, const char8_t *inPresentationDir, + qt3ds::render::IRenderPluginManager &inRPM, + qt3ds::render::ICustomMaterialSystem &inCMS, + qt3ds::render::IDynamicObjectSystem &inDynamicSystem, + qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver, + const Q3DSVariantConfig &variantConfig) + : m_Reader(inReader) + , m_MetaData(inMetaData) + , m_StrTable(inStrTable) + , m_Foundation(inFoundation) + , m_PresentationAllocator(inPresentationAllocator) + , m_ObjectMap(ioObjectMap) + , m_BufferManager(inBufferManager) + , m_Presentation(QT3DS_NEW(inPresentationAllocator, SPresentation)()) + , m_TempBuf(inFoundation.getAllocator(), "SRenderUIPLoader::m_TempBuf") + , m_EffectSystem(inEffectSystem) + , m_PresentationDir(inPresentationDir) + , m_RenderPluginManager(inRPM) + , m_CustomMaterialSystem(inCMS) + , m_DynamicObjectSystem(inDynamicSystem) + , m_PathManager(inPathManager) + , m_ReferenceResolver(inResolver) + , m_variantConfig(variantConfig) + { + std::string presentationFile = inFullPathToPresentationFile; + std::string::size_type pos = presentationFile.find_last_of("\\/"); + if (pos != std::string::npos) { + std::string path = presentationFile.substr(0, pos); + m_Presentation->m_PresentationDirectory = inStrTable.RegisterStr(path.c_str()); + } + } + + SGraphObject *ResolveReference(SGraphObject &inRoot, const char *path) override + { + if (m_ReferenceResolver) { + CRegisteredString resolvedReference = + m_ReferenceResolver->ResolveReference(inRoot.m_Id, path); + if (resolvedReference.IsValid()) { + qt3ds::render::TIdObjectMap::iterator iter = m_ObjectMap.find(resolvedReference); + if (iter != m_ObjectMap.end()) + return iter->second; + } + } + return NULL; + } + + static bool IsNode(GraphObjectTypes::Enum inType) + { + return GraphObjectTypes::IsNodeType(inType); + } + template + bool ParseProperty(IPropertyParser &inParser, const char8_t *inName, TDataType &outData) + { + Option theValue(SParserHelper::Parse(inName, inParser)); + if (theValue.hasValue()) { + outData = theValue; + return true; + } + return false; + } + bool ParseOpacityProperty(IPropertyParser &inParser, const char8_t *inName, QT3DSF32 &outOpacity) + { + if (ParseProperty(inParser, inName, outOpacity)) { + outOpacity /= 100.0f; + return true; + } + return false; + } + + bool ParseRadianProperty(IPropertyParser &inParser, const char8_t *inName, QT3DSVec3 &ioRotation) + { + if (ParseProperty(inParser, inName, ioRotation)) { + TORAD(ioRotation.x); + TORAD(ioRotation.y); + TORAD(ioRotation.z); + return true; + } + return false; + } + bool ParseRadianProperty(IPropertyParser &inParser, const char8_t *inName, QT3DSF32 &ioRotation) + { + if (ParseProperty(inParser, inName, ioRotation)) { + TORAD(ioRotation); + return true; + } + return false; + } + + void ParseRotationOrder(IPropertyParser &inParser, const char8_t *inName, + QT3DSU32 &ioRotationOrder) + { + if (ParseProperty(inParser, inName, m_TempParseString)) + ioRotationOrder = qt3ds::render::MapRotationOrder(m_TempParseString.c_str()); + } + void ParseOrientation(IPropertyParser &inParser, const char8_t *inName, NodeFlags &ioFlags) + { + if (ParseProperty(inParser, inName, m_TempParseString)) { + if (m_TempParseString == "Left Handed") + ioFlags.SetLeftHanded(true); + else + ioFlags.SetLeftHanded(false); + } + } + void ParseOrthographicProperty(IPropertyParser &inParser, const char8_t *inName, + NodeFlags &ioFlags) + { + bool isOrthographic; + if (ParseProperty(inParser, inName, isOrthographic)) + ioFlags.SetOrthographic(isOrthographic); + } + template + static bool ConvertEnumFromStr(const char8_t *inStr, TEnumType &ioEnum) + { + qt3ds::render::SEnumNameMap *theMap = qt3ds::render::SEnumParseMap::GetMap(); + for (qt3ds::render::SEnumNameMap *item = theMap; item->m_Name; ++item) { + // hack to match advanced overlay types, whose name start with a '*' + const char8_t *p = inStr; + if (*p == '*') + ++p; + if (qt3dsdm::AreEqual(p, item->m_Name)) { + ioEnum = static_cast(item->m_Enum); + return true; + } + } + return false; + } + + template + void ParseEnumProperty(IPropertyParser &inParser, const char8_t *inName, TEnumType &ioEnum) + { + if (ParseProperty(inParser, inName, m_TempParseString)) { + ConvertEnumFromStr(m_TempParseString.c_str(), ioEnum); + } + } + void ParseAndResolveSourcePath(IPropertyParser &inParser, const char8_t *inName, + CRegisteredString &ioString) + { + if (ParseProperty(inParser, inName, m_TempParseString)) + ioString = m_StrTable.RegisterStr(m_TempParseString.c_str()); + } + void ParseProperty(IPropertyParser &inParser, const char8_t *inName, SImage *&ioImage) + { + if (ParseProperty(inParser, inName, m_TempParseString)) { + TIdObjectMap::iterator theIter = + m_ObjectMap.find(m_StrTable.RegisterStr(m_TempParseString.c_str() + 1)); + if (theIter != m_ObjectMap.end() + && theIter->second->m_Type == GraphObjectTypes::Image) { + ioImage = static_cast(theIter->second); + } else { + QT3DS_ASSERT(false); + } + } + } + void ParseProperty(IPropertyParser &inParser, const char8_t *inName, CRegisteredString &ioStr) + { + if (ParseProperty(inParser, inName, m_TempParseString)) + ioStr = m_StrTable.RegisterStr(m_TempParseString.c_str()); + } + + void ParseNodeFlagsProperty(IPropertyParser &inParser, const char8_t *inName, + qt3ds::render::NodeFlags &ioFlags, + qt3ds::render::NodeFlagValues::Enum prop) + { + bool temp; + if (ParseProperty(inParser, inName, temp)) + ioFlags.ClearOrSet(temp, prop); + } + + void ParseNodeFlagsInverseProperty(IPropertyParser &inParser, const char8_t *inName, + qt3ds::render::NodeFlags &ioFlags, + qt3ds::render::NodeFlagValues::Enum prop) + { + bool temp; + if (ParseProperty(inParser, inName, temp)) + ioFlags.ClearOrSet(!temp, prop); + } + +// Create a mapping from UICRenderPropertyNames to the string in the UIP file. +#define Scene_ClearColor "backgroundcolor" +#define Scene_UseClearColor "bgcolorenable" +#define Node_Rotation "rotation" +#define Node_Position "position" +#define Node_Scale "scale" +#define Node_Pivot "pivot" +#define Node_LocalOpacity "opacity" +#define Node_RotationOrder "rotationorder" +#define Node_LeftHanded "orientation" +#define Layer_Variants "variants" +#define Layer_TemporalAAEnabled "temporalaa" +#define Layer_LayerEnableDepthTest "disabledepthtest" +#define Layer_LayerEnableDepthPrePass "disabledepthprepass" +#define Layer_ClearColor "backgroundcolor" +#define Layer_Background "background" +#define Layer_BlendType "blendtype" +#define Layer_Size "size" +#define Layer_Location "location" +#define Layer_TexturePath "sourcepath" +#define Layer_HorizontalFieldValues "horzfields" +#define Layer_Left "left" +#define Layer_LeftUnits "leftunits" +#define Layer_Width "width" +#define Layer_WidthUnits "widthunits" +#define Layer_Right "right" +#define Layer_RightUnits "rightunits" +#define Layer_VerticalFieldValues "vertfields" +#define Layer_Top "top" +#define Layer_TopUnits "topunits" +#define Layer_Height "height" +#define Layer_HeightUnits "heightunits" +#define Layer_Bottom "bottom" +#define Layer_BottomUnits "bottomunits" +#define Layer_AoStrength "aostrength" +#define Layer_AoDistance "aodistance" +#define Layer_AoSoftness "aosoftness" +#define Layer_AoBias "aobias" +#define Layer_AoSamplerate "aosamplerate" +#define Layer_AoDither "aodither" +#define Layer_ShadowStrength "shadowstrength" +#define Layer_ShadowDist "shadowdist" +#define Layer_ShadowSoftness "shadowsoftness" +#define Layer_ShadowBias "shadowbias" +#define Layer_LightProbe "lightprobe" +#define Layer_ProbeBright "probebright" +#define Layer_FastIbl "fastibl" +#define Layer_ProbeHorizon "probehorizon" +#define Layer_ProbeFov "probefov" +#define Layer_LightProbe2 "lightprobe2" +#define Layer_Probe2Fade "probe2fade" +#define Layer_Probe2Window "probe2window" +#define Layer_Probe2Pos "probe2pos" +#define Camera_ClipNear "clipnear" +#define Camera_ClipFar "clipfar" +#define Camera_FOV "fov" +#define Camera_FOVHorizontal "fovhorizontal" +#define Camera_Orthographic "orthographic" +#define Camera_ScaleMode "scalemode" +#define Camera_ScaleAnchor "scaleanchor" +#define Light_LightType "lighttype" +#define Light_DiffuseColor "lightdiffuse" +#define Light_SpecularColor "lightspecular" +#define Light_AmbientColor "lightambient" +#define Light_Brightness "brightness" +#define Light_LinearFade "linearfade" +#define Light_ExponentialFade "expfade" +#define Light_AreaWidth "areawidth" +#define Light_AreaHeight "areaheight" +#define Light_CastShadow "castshadow" +#define Light_ShadowBias "shdwbias" +#define Light_ShadowFactor "shdwfactor" +#define Light_ShadowMapRes "shdwmapres" +#define Light_ShadowMapFar "shdwmapfar" +#define Light_ShadowMapFov "shdwmapfov" +#define Light_ShadowFilter "shdwfilter" +#define Model_MeshPath "sourcepath" +#define Model_ShadowCaster "shadowcaster" +#define Model_TessellationMode "tessellation" +#define Model_EdgeTess "edgetess" +#define Model_InnerTess "innertess" +#define Lightmaps_LightmapIndirect "lightmapindirect" +#define Lightmaps_LightmapRadiosity "lightmapradiosity" +#define Lightmaps_LightmapShadow "lightmapshadow" +#define Material_Lighting "shaderlighting" +#define Material_BlendMode "blendmode" +#define MaterialBase_IblProbe "iblprobe" +#define Material_DiffuseColor "diffuse" +#define Material_DiffuseMaps_0 "diffusemap" +#define Material_DiffuseMaps_1 "diffusemap2" +#define Material_DiffuseMaps_2 "diffusemap3" +#define Material_EmissivePower "emissivepower" +#define Material_EmissiveColor "emissivecolor" +#define Material_EmissiveMap "emissivemap" +#define Material_EmissiveMap2 "emissivemap2" +#define Material_SpecularReflection "specularreflection" +#define Material_SpecularMap "specularmap" +#define Material_SpecularModel "specularmodel" +#define Material_SpecularTint "speculartint" +#define Material_IOR "ior" +#define Material_FresnelPower "fresnelPower" +#define Material_SpecularAmount "specularamount" +#define Material_SpecularRoughness "specularroughness" +#define Material_RoughnessMap "roughnessmap" +#define Material_Opacity "opacity" +#define Material_OpacityMap "opacitymap" +#define Material_BumpMap "bumpmap" +#define Material_BumpAmount "bumpamount" +#define Material_NormalMap "normalmap" +#define Material_DisplacementMap "displacementmap" +#define Material_DisplaceAmount "displaceamount" +#define Material_TranslucencyMap "translucencymap" +#define Material_TranslucentFalloff "translucentfalloff" +#define Material_DiffuseLightWrap "diffuselightwrap" +#define Material_ReferencedMaterial "referencedmaterial" +#define Material_VertexColors "vertexcolors" +#define Image_ImagePath "sourcepath" +#define Image_OffscreenRendererId "subpresentation" +#define Image_Scale_X "scaleu" +#define Image_Scale_Y "scalev" +#define Image_Pivot_X "pivotu" +#define Image_Pivot_Y "pivotv" +#define Image_Rotation "rotationuv" +#define Image_Position_X "positionu" +#define Image_Position_Y "positionv" +#define Image_MappingMode "mappingmode" +#define Image_HorizontalTilingMode "tilingmodehorz" +#define Image_VerticalTilingMode "tilingmodevert" +#define Text_Text "textstring" +#define Text_Font "font" +#define Text_FontSize "size" +#define Text_HorizontalAlignment "horzalign" +#define Text_VerticalAlignment "vertalign" +#define Text_Leading "leading" +#define Text_Tracking "tracking" +#define Text_DropShadow "dropshadow" +#define Text_DropShadowStrength "dropshadowstrength" +#define Text_DropShadowOffset "dropshadowoffset" // To be removed in 2.x (when UIP version is next updated) +#define Text_DropShadowOffsetX "dropshadowoffsetx" +#define Text_DropShadowOffsetY "dropshadowoffsety" +#define Text_DropShadowHorizontalAlignment "dropshadowhorzalign" // To be removed in 2.x (when UIP version is next updated) +#define Text_DropShadowVerticalAlignment "dropshadowvertalign" // To be removed in 2.x (when UIP version is next updated) +#define Text_WordWrap "wordwrap" +#define Text_BoundingBox "boundingbox" +#define Text_Elide "elide" +#define Text_TextColor "textcolor" +#define Text_BackColor "backcolor" +#define Text_EnableAcceleratedFont "enableacceleratedfont" +#define Layer_ProgressiveAAMode "progressiveaa" +#define Layer_MultisampleAAMode "multisampleaa" +#define Light_Scope "scope" +#define Path_PathType "pathtype" +#define Path_PaintStyle "paintstyle" +#define Path_Width "width" +#define Path_Opacity "opacity" +#define Path_LinearError "linearerror" +#define Path_EdgeTessAmount "edgetessamount" +#define Path_InnerTessAmount "innertessamount" +#define Path_BeginCapping "begincap" +#define Path_BeginCapOffset "begincapoffset" +#define Path_BeginCapOpacity "begincapopacity" +#define Path_BeginCapWidth "begincapwidth" +#define Path_EndCapping "endcap" +#define Path_EndCapOffset "endcapoffset" +#define Path_EndCapOpacity "endcapopacity" +#define Path_EndCapWidth "endcapwidth" +#define Path_PathBuffer "sourcepath" +#define SubPath_Closed "closed" + +// Fill in implementations for the actual parse tables. +#define HANDLE_QT3DS_RENDER_PROPERTY(type, name, dirty) \ + ParseProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_REAL_VEC2_PROPERTY(type, name, dirty) \ + ParseProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_VEC3_PROPERTY(type, name, dirty) \ + ParseProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_COLOR_PROPERTY(type, name, dirty) \ + ParseProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(type, name, dirty) \ + ParseRadianProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_VEC3_RADIAN_PROPERTY(type, name, dirty) \ + ParseRadianProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(type, name, dirty) \ + ParseOpacityProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_ROTATION_ORDER_PROPERTY(type, name, dirty) \ + ParseRotationOrder(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY(type, name, dirty) \ + ParseOrientation(inParser, type##_##name, inItem.m_Flags); +#define HANDLE_QT3DS_RENDER_DEPTH_TEST_PROPERTY(type, name, dirty) \ + if (ParseProperty(inParser, type##_##name, inItem.m_##name)) \ + inItem.m_##name = !inItem.m_##name; +#define HANDLE_QT3DS_NODE_FLAGS_PROPERTY(type, name, dirty) \ + ParseNodeFlagsProperty(inParser, type##_##name, inItem.m_Flags, \ + qt3ds::render::NodeFlagValues::name); +#define HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(type, name, dirty) \ + ParseNodeFlagsInverseProperty(inParser, type##_##name, inItem.m_Flags, \ + qt3ds::render::NodeFlagValues::name); +#define HANDLE_QT3DS_RENDER_ENUM_PROPERTY(type, name, dirty) \ + ParseEnumProperty(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(type, name, dirty) \ + ParseAndResolveSourcePath(inParser, type##_##name, inItem.m_##name); +#define HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(type, name, index, dirty) \ + ParseProperty(inParser, type##_##name##_##index, inItem.m_##name[index]); +#define HANDLE_QT3DS_RENDER_VEC2_PROPERTY(type, name, dirty) \ + ParseProperty(inParser, type##_##name##_##X, inItem.m_##name.x); \ + ParseProperty(inParser, type##_##name##_##Y, inItem.m_##name.y); +#define HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY( \ + type, name, dirty) // noop by intention already handled by HANDLE_QT3DS_RENDER_COLOR_PROPERTY +#define HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY( \ + type, name, dirty) // noop by intention already handled by HANDLE_QT3DS_RENDER_VEC3_PROPERTY + + // Call the correct parser functions. + void ParseProperties(SScene &inItem, IPropertyParser &inParser) + { + ITERATE_QT3DS_RENDER_SCENE_PROPERTIES + } + void ParseProperties(SNode &inItem, IPropertyParser &inParser) + { + bool eyeball; + if (ParseProperty(inParser, "eyeball", eyeball)) + inItem.m_Flags.SetActive(eyeball); + ITERATE_QT3DS_RENDER_NODE_PROPERTIES + ParseProperty(inParser, "boneid", inItem.m_SkeletonId); + bool ignoreParent = false; + if (ParseProperty(inParser, "ignoresparent", ignoreParent)) + inItem.m_Flags.SetIgnoreParentTransform(ignoreParent); + } + void ParseProperties(SLayer &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ITERATE_QT3DS_RENDER_LAYER_PROPERTIES + ParseProperty(inParser, "aosamplerate", inItem.m_AoSamplerate); + } + void ParseProperties(SCamera &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ITERATE_QT3DS_RENDER_CAMERA_PROPERTIES + } + void ParseProperties(SLight &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ITERATE_QT3DS_RENDER_LIGHT_PROPERTIES + ParseProperty(inParser, "shdwmapres", inItem.m_ShadowMapRes); + } + void ParseProperties(SModel &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ITERATE_QT3DS_RENDER_MODEL_PROPERTIES + ParseProperty(inParser, "poseroot", inItem.m_SkeletonRoot); + } + + void ParseProperties(SText &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ITERATE_QT3DS_RENDER_TEXT_PROPERTIES + } + void ParseProperties(SLightmaps &inItem, IPropertyParser &inParser) + { + ITERATE_QT3DS_RENDER_LIGHTMAP_PROPERTIES + } + void ParseProperties(SDefaultMaterial &inItem, IPropertyParser &inParser) + { + ITERATE_QT3DS_RENDER_MATERIAL_PROPERTIES + ParseProperties(inItem.m_Lightmaps, inParser); + } + void ParseProperties(SReferencedMaterial &inItem, IPropertyParser &inParser) + { + ITERATE_QT3DS_RENDER_REFERENCED_MATERIAL_PROPERTIES + // Propagate lightmaps + if (inItem.m_ReferencedMaterial + && inItem.m_ReferencedMaterial->m_Type == GraphObjectTypes::DefaultMaterial) + ParseProperties( + static_cast(inItem.m_ReferencedMaterial)->m_Lightmaps, + inParser); + else if (inItem.m_ReferencedMaterial + && inItem.m_ReferencedMaterial->m_Type == GraphObjectTypes::CustomMaterial) + ParseProperties( + static_cast(inItem.m_ReferencedMaterial)->m_Lightmaps, inParser); + } + void ParseProperties(SImage &inItem, IPropertyParser &inParser) + { + ITERATE_QT3DS_RENDER_IMAGE_PROPERTIES + } + template + void SetDynamicObjectProperty(SDynamicObject &inEffect, + const qt3ds::render::dynamic::SPropertyDefinition &inPropDesc, + const TDataType &inProp) + { + memCopy(inEffect.GetDataSectionBegin() + inPropDesc.m_Offset, &inProp, sizeof(TDataType)); + } + template + void SetDynamicObjectProperty(SDynamicObject &inEffect, + const qt3ds::render::dynamic::SPropertyDefinition &inPropDesc, + Option inProp) + { + if (inProp.hasValue()) { + SetDynamicObjectProperty(inEffect, inPropDesc, *inProp); + } + } + void ParseProperties(SCustomMaterial &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ParseProperties(inItem.m_Lightmaps, inParser); + ITERATE_QT3DS_RENDER_CUSTOM_MATERIAL_PROPERTIES + } + void ParseProperties(SDynamicObject &inDynamicObject, IPropertyParser &inParser) + { + NVConstDataRef theProperties = + m_DynamicObjectSystem.GetProperties(inDynamicObject.m_ClassName); + + for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { + const qt3ds::render::dynamic::SPropertyDefinition &theDefinition(theProperties[idx]); + switch (theDefinition.m_DataType) { + case qt3ds::render::NVRenderShaderDataTypes::QT3DSRenderBool: + SetDynamicObjectProperty(inDynamicObject, theDefinition, + inParser.ParseBool(theDefinition.m_Name)); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSF32: + SetDynamicObjectProperty(inDynamicObject, theDefinition, + inParser.ParseFloat(theDefinition.m_Name)); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSI32: + if (theDefinition.m_IsEnumProperty == false) + SetDynamicObjectProperty(inDynamicObject, theDefinition, + inParser.ParseU32(theDefinition.m_Name)); + else { + Option theEnum = inParser.ParseStr(theDefinition.m_Name); + if (theEnum.hasValue()) { + NVConstDataRef theEnumNames = + theDefinition.m_EnumValueNames; + for (QT3DSU32 idx = 0, end = theEnumNames.size(); idx < end; ++idx) { + if (theEnum->compare(theEnumNames[idx].c_str()) == 0) { + SetDynamicObjectProperty(inDynamicObject, theDefinition, idx); + break; + } + } + } + } + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec3: + SetDynamicObjectProperty(inDynamicObject, theDefinition, + inParser.ParseVec3(theDefinition.m_Name)); + break; + case qt3ds::render::NVRenderShaderDataTypes::QT3DSVec2: + SetDynamicObjectProperty(inDynamicObject, theDefinition, + inParser.ParseVec2(theDefinition.m_Name)); + break; + case qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr: + case qt3ds::render::NVRenderShaderDataTypes::NVRenderImage2DPtr: { + Option theTexture = inParser.ParseStr(theDefinition.m_Name); + if (theTexture.hasValue()) { + CRegisteredString theStr; + if (theTexture->size()) + theStr = m_StrTable.RegisterStr(theTexture->c_str()); + + SetDynamicObjectProperty(inDynamicObject, theDefinition, theStr); + } + } break; + case qt3ds::render::NVRenderShaderDataTypes::NVRenderDataBufferPtr: + break; + default: + QT3DS_ASSERT(false); + break; + } + } + } + void ParseProperties(SPath &inItem, IPropertyParser &inParser) + { + ParseProperties(static_cast(inItem), inParser); + ITERATE_QT3DS_RENDER_PATH_PROPERTIES + } + void ParseProperties(SPathSubPath &inItem, IPropertyParser &inParser) + { + ITERATE_QT3DS_RENDER_PATH_SUBPATH_PROPERTIES + } + + void AddPluginPropertyUpdate(eastl::vector &ioUpdates, + qt3ds::render::IRenderPluginClass &, + const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, + Option data) + { + if (data.hasValue()) { + ioUpdates.push_back( + qt3ds::render::SRenderPropertyValueUpdate(inDeclaration.m_Name, *data)); + } + } + void AddPluginPropertyUpdate(eastl::vector &ioUpdates, + qt3ds::render::IRenderPluginClass &inClass, + const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, + Option data) + { + if (data.hasValue()) { + ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( + inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset).first, data->x)); + ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( + inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset + 1).first, data->y)); + } + } + void AddPluginPropertyUpdate(eastl::vector &ioUpdates, + qt3ds::render::IRenderPluginClass &inClass, + const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, + Option data) + { + if (data.hasValue()) { + ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( + inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset).first, data->x)); + ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( + inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset + 1).first, data->y)); + ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( + inClass.GetPropertyValueInfo(inDeclaration.m_StartOffset + 2).first, data->z)); + } + } + void AddPluginPropertyUpdate(eastl::vector &ioUpdates, + qt3ds::render::IRenderPluginClass &, + const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, + Option dataOpt) + { + if (dataOpt.hasValue()) { + long data = static_cast(*dataOpt); + ioUpdates.push_back( + qt3ds::render::SRenderPropertyValueUpdate(inDeclaration.m_Name, (QT3DSI32)data)); + } + } + void AddPluginPropertyUpdate(eastl::vector &ioUpdates, + qt3ds::render::IRenderPluginClass &, + const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, + Option dataOpt) + { + if (dataOpt.hasValue()) { + eastl::string &data = dataOpt.getValue(); + ioUpdates.push_back(qt3ds::render::SRenderPropertyValueUpdate( + inDeclaration.m_Name, m_StrTable.RegisterStr(data.c_str()))); + } + } + void AddPluginPropertyUpdate(eastl::vector &ioUpdates, + qt3ds::render::IRenderPluginClass &, + const qt3ds::render::SRenderPluginPropertyDeclaration &inDeclaration, + Option dataOpt) + { + if (dataOpt.hasValue()) { + bool &data = dataOpt.getValue(); + ioUpdates.push_back( + qt3ds::render::SRenderPropertyValueUpdate(inDeclaration.m_Name, data)); + } + } + void ParseProperties(qt3ds::render::SRenderPlugin &inRenderPlugin, IPropertyParser &inParser) + { + qt3ds::render::IRenderPluginClass *theClass = + m_RenderPluginManager.GetRenderPlugin(inRenderPlugin.m_PluginPath); + if (theClass) { + qt3ds::foundation::NVConstDataRef + theClassProps = theClass->GetRegisteredProperties(); + if (theClassProps.size()) { + qt3ds::render::IRenderPluginInstance *theInstance = + m_RenderPluginManager.GetOrCreateRenderPluginInstance( + inRenderPlugin.m_PluginPath, &inRenderPlugin); + if (theInstance) { + eastl::vector theUpdates; + for (QT3DSU32 idx = 0, end = theClassProps.size(); idx < end; ++idx) { + const qt3ds::render::SRenderPluginPropertyDeclaration &theDec( + theClassProps[idx]); + eastl::string tempStr; + switch (theDec.m_Type) { + case qt3ds::render::SRenderPluginPropertyTypes::Float: + AddPluginPropertyUpdate(theUpdates, *theClass, theDec, + inParser.ParseFloat(theDec.m_Name.c_str())); + break; + case qt3ds::render::SRenderPluginPropertyTypes::Vector2: + AddPluginPropertyUpdate(theUpdates, *theClass, theDec, + inParser.ParseVec2(theDec.m_Name.c_str())); + break; + case qt3ds::render::SRenderPluginPropertyTypes::Color: + case qt3ds::render::SRenderPluginPropertyTypes::Vector3: + AddPluginPropertyUpdate(theUpdates, *theClass, theDec, + inParser.ParseVec3(theDec.m_Name.c_str())); + break; + case qt3ds::render::SRenderPluginPropertyTypes::Long: + AddPluginPropertyUpdate(theUpdates, *theClass, theDec, + inParser.ParseI32(theDec.m_Name.c_str())); + break; + case qt3ds::render::SRenderPluginPropertyTypes::String: + AddPluginPropertyUpdate(theUpdates, *theClass, theDec, + inParser.ParseStr(theDec.m_Name.c_str())); + break; + case qt3ds::render::SRenderPluginPropertyTypes::Boolean: + AddPluginPropertyUpdate(theUpdates, *theClass, theDec, + inParser.ParseBool(theDec.m_Name.c_str())); + break; + default: + QT3DS_ASSERT(false); + } + } + theInstance->Update( + qt3ds::foundation::toConstDataRef(theUpdates.data(), theUpdates.size())); + } + } + } + } + +#undef HANDLE_QT3DS_RENDER_PROPERTY +#undef HANDLE_QT3DS_RENDER_ENUM_PROPERTY +#undef HANDLE_QT3DS_RENDER_RADIAN_PROPERTY +#undef HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY +#undef HANDLE_QT3DS_RENDER_ARRAY_PROPERTY +#undef HANDLE_QT3DS_NODE_FLAGS_PROPERTY +#undef HANDLE_QT3DS_ROTATION_ORDER_PROPERTY +#undef HANDLE_QT3DS_RENDER_OPACITY_PROPERTY +#undef HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY +#undef HANDLE_QT3DS_RENDER_DEPTH_TEST_PROPERTY +#undef HANDLE_QT3DS_RENDER_VEC2_PROPERTY + + void ParseGraphPass1(SGraphObject *inParent) + { + TScope __elemScope(m_Reader); + qt3dsdm::ComposerObjectTypes::Enum theObjType = + qt3dsdm::ComposerObjectTypes::Convert(m_Reader.GetElementName()); + SGraphObject *theNewObject(NULL); + const char8_t *theId; + const char8_t *theVariants; + m_Reader.Att("id", theId); + m_Reader.Att("variants", theVariants); + + QString theString(theVariants); + QStringRef theStringRef(&theString); + bool isPartOfConfig = m_variantConfig.isPartOfConfig(theStringRef); + if (isPartOfConfig) { + switch (theObjType) { + case qt3dsdm::ComposerObjectTypes::Scene: { + SScene *theScene = QT3DS_NEW(m_PresentationAllocator, SScene)(); + theNewObject = theScene; + m_Presentation->m_Scene = theScene; + theScene->m_Presentation = m_Presentation; + } break; + case qt3dsdm::ComposerObjectTypes::Layer: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SLayer)(); + break; + case qt3dsdm::ComposerObjectTypes::Group: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); + break; + case qt3dsdm::ComposerObjectTypes::Component: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); + break; + case qt3dsdm::ComposerObjectTypes::Camera: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SCamera)(); + break; + case qt3dsdm::ComposerObjectTypes::Light: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SLight)(); + break; + case qt3dsdm::ComposerObjectTypes::Model: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SModel)(); + break; + case qt3dsdm::ComposerObjectTypes::Material: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SDefaultMaterial)(); + break; + case qt3dsdm::ComposerObjectTypes::ReferencedMaterial: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SReferencedMaterial)(); + break; + case qt3dsdm::ComposerObjectTypes::Image: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SImage)(); + break; + case qt3dsdm::ComposerObjectTypes::Text: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SText)(); + break; + case qt3dsdm::ComposerObjectTypes::Path: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SPath)(); + break; + case qt3dsdm::ComposerObjectTypes::SubPath: { + SPathSubPath *thePath = QT3DS_NEW(m_PresentationAllocator, SPathSubPath)(); + theNewObject = thePath; + QT3DSU32 anchorCount = 0; + TScope _childScope(m_Reader); + for (bool success = m_Reader.MoveToFirstChild("PathAnchorPoint"); success; + success = m_Reader.MoveToNextSibling("PathAnchorPoint")) { + const char8_t *theId; + m_Reader.Att("id", theId); + CRegisteredString theIdStr = m_StrTable.RegisterStr(theId); + m_AnchorIdToPathAndAnchorIndexMap.insert( + eastl::make_pair(theIdStr, SPathAndAnchorIndex(thePath, anchorCount))); + ++anchorCount; + } + m_PathManager.ResizePathSubPathBuffer(*thePath, anchorCount); + } break; + case qt3dsdm::ComposerObjectTypes::Effect: { + const char8_t *effectClassId; + m_Reader.Att("class", effectClassId); + CRegisteredString theStr = m_StrTable.RegisterStr(effectClassId + 1); + if (m_EffectSystem.IsEffectRegistered(theStr)) + theNewObject = m_EffectSystem.CreateEffectInstance(theStr, m_PresentationAllocator); + } break; + case qt3dsdm::ComposerObjectTypes::RenderPlugin: { + const char8_t *classId; + m_Reader.Att("class", classId); + if (!qt3ds::foundation::isTrivial(classId)) { + ++classId; + TIdStringMap::iterator iter = + m_RenderPluginSourcePaths.find(m_StrTable.RegisterStr(classId)); + if (iter != m_RenderPluginSourcePaths.end()) { + CRegisteredString thePluginPath = m_StrTable.RegisterStr(iter->second.c_str()); + qt3ds::render::IRenderPluginClass *theClass = + m_RenderPluginManager.GetRenderPlugin(thePluginPath); + if (theClass) { + qt3ds::render::SRenderPlugin *thePlugin = + QT3DS_NEW(m_PresentationAllocator, qt3ds::render::SRenderPlugin)(); + thePlugin->m_PluginPath = thePluginPath; + thePlugin->m_Flags.SetActive(true); + theNewObject = thePlugin; + } + } + } + } break; + case qt3dsdm::ComposerObjectTypes::CustomMaterial: { + const char8_t *materialClassId; + m_Reader.Att("class", materialClassId); + CRegisteredString theStr = m_StrTable.RegisterStr(materialClassId + 1); + if (m_CustomMaterialSystem.IsMaterialRegistered(theStr)) { + theNewObject = + m_CustomMaterialSystem.CreateCustomMaterial(theStr, m_PresentationAllocator); + } + } break; + default: + // Ignoring unknown objects entirely at this point + break; + } + } + if (theNewObject) { + CRegisteredString theObjectId(m_StrTable.RegisterStr(theId)); + m_ObjectMap.insert(eastl::make_pair(theObjectId, theNewObject)); + theNewObject->m_Id = theObjectId; + // setup hierarchy + bool isParentNode; + bool isChildNode; + if (inParent) { + switch (inParent->m_Type) { + case GraphObjectTypes::Scene: + if (theNewObject->m_Type == GraphObjectTypes::Layer) { + static_cast(inParent)->AddChild( + *static_cast(theNewObject)); + } + break; + + case GraphObjectTypes::DefaultMaterial: + if (theNewObject->m_Type == GraphObjectTypes::Image) { + static_cast(theNewObject)->m_Parent = + static_cast(inParent); + eastl::string thePath = eastl::string(theNewObject->m_Id.c_str()); + if (thePath.find("probe") != eastl::string::npos) + static_cast(theNewObject)->m_MappingMode = + ImageMappingModes::LightProbe; + } + break; + + case GraphObjectTypes::CustomMaterial: + if (theNewObject->m_Type == GraphObjectTypes::Image) { + static_cast(theNewObject)->m_Parent = + static_cast(inParent); + eastl::string thePath = eastl::string(theNewObject->m_Id.c_str()); + if (thePath.find("probe") != eastl::string::npos) { + static_cast(theNewObject)->m_MappingMode = + ImageMappingModes::LightProbe; + } + } else { + QT3DS_ASSERT(false); + } + break; + case GraphObjectTypes::ReferencedMaterial: + if (theNewObject->m_Type == GraphObjectTypes::Image) { + // nothing to do yet + } else { + QT3DS_ASSERT(false); + } + break; + case GraphObjectTypes::Path: + + if (GraphObjectTypes::IsMaterialType(theNewObject->m_Type)) + static_cast(inParent)->AddMaterial(theNewObject); + + else if (theNewObject->m_Type == GraphObjectTypes::PathSubPath) + static_cast(inParent)->AddSubPath( + *static_cast(theNewObject)); + + break; + + default: + isParentNode = IsNode(inParent->m_Type); + isChildNode = IsNode(theNewObject->m_Type); + if (isParentNode && isChildNode) { + static_cast(inParent)->AddChild( + *static_cast(theNewObject)); + } else if (isParentNode) { + if (inParent->m_Type == GraphObjectTypes::Model + && IsMaterial(theNewObject)) { + static_cast(inParent)->AddMaterial(*theNewObject); + } else { + if (inParent->m_Type == GraphObjectTypes::Layer + && theNewObject->m_Type == GraphObjectTypes::Effect) { + static_cast(inParent)->AddEffect( + *static_cast(theNewObject)); + } else if (inParent->m_Type == GraphObjectTypes::Layer + && theNewObject->m_Type == GraphObjectTypes::Image) { + eastl::string thePath = eastl::string(theNewObject->m_Id.c_str()); + if (thePath.find("probe2") != eastl::string::npos) { + static_cast(inParent)->m_LightProbe2 = + static_cast(theNewObject); + } else { + static_cast(inParent)->m_LightProbe = + static_cast(theNewObject); + } + } else { + if (theNewObject->m_Type == GraphObjectTypes::RenderPlugin) { + qt3ds::render::SRenderPlugin *childObj = + static_cast(theNewObject); + if (inParent->m_Type == GraphObjectTypes::Layer) { + static_cast(inParent)->m_RenderPlugin = childObj; + } else { + QT3DS_ASSERT(false); + } + } else { + QT3DS_ASSERT(false); + } + } + } + } else { + if (inParent->m_Type == GraphObjectTypes::Image + && theNewObject->m_Type == GraphObjectTypes::RenderPlugin) { + static_cast(inParent)->m_RenderPlugin = + static_cast(theNewObject); + } else { + QT3DS_ASSERT(false); + } + } + } + } + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) + ParseGraphPass1(theNewObject); + } else { + if (isPartOfConfig) { + // Object was of unknown type -> parse children with NULL parent + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) { + ParseGraphPass1(NULL); + } + } + // If object wasn't part of variant config -> skip children. + // Continue parsing from next sibling with same parent. + } + } + + template + void ParsePass2Properties(TObjType &inObject, const char8_t *inClassId) + { + const char8_t *theTypeName = m_Reader.GetNarrowElementName(); + SMetaPropertyParser theMetaParser(theTypeName, inClassId, m_MetaData); + // Set default values + ParseProperties(inObject, theMetaParser); + + // Now setup property values from the element itself. + SDomReaderPropertyParser theReaderParser(m_Reader, m_TempBuf, *this, inObject); + ParseProperties(inObject, theReaderParser); + } + + // Parse the instance properties from the graph. + void ParseGraphPass2() + { + TScope __instanceScope(m_Reader); + const char8_t *theId; + m_Reader.Att("id", theId); + const char8_t *theClass = ""; + const char8_t *theVariants = ""; + m_Reader.Att("class", theClass); + m_Reader.Att("variants", theVariants); + + QString theString(theVariants); + QStringRef theStringRef(&theString); + bool isPartOfConfig = m_variantConfig.isPartOfConfig(theStringRef); + if (isPartOfConfig) { + TIdObjectMap::iterator theObject = m_ObjectMap.find(m_StrTable.RegisterStr(theId)); + if (theObject != m_ObjectMap.end()) { + switch (theObject->second->m_Type) { + case GraphObjectTypes::Scene: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Node: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Layer: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Camera: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Light: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Model: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::DefaultMaterial: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::ReferencedMaterial: + ParsePass2Properties(*static_cast(theObject->second), + theClass); + break; + case GraphObjectTypes::Image: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Text: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Effect: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::RenderPlugin: + ParsePass2Properties(*static_cast(theObject->second), + theClass); + break; + case GraphObjectTypes::CustomMaterial: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::Path: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + case GraphObjectTypes::PathSubPath: + ParsePass2Properties(*static_cast(theObject->second), theClass); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + } + + // If not part of variant config -> ignore children + if (isPartOfConfig) { + for (bool valid = m_Reader.MoveToFirstChild(); valid; valid = m_Reader.MoveToNextSibling()) + ParseGraphPass2(); + } + } + + static bool ParseVec2(SDomReaderPropertyParser &inParser, const char *inName, QT3DSVec2 &outValue) + { + Option result = inParser.ParseVec2(inName); + + if (result.hasValue()) + outValue = *result; + + return result.hasValue(); + } + + static bool ParseFloat(SDomReaderPropertyParser &inParser, const char *inName, QT3DSF32 &outValue) + { + Option result = inParser.ParseFloat(inName); + if (result.hasValue()) + outValue = *result; + return result.hasValue(); + } + + void ParseState(bool inSetSetValues) + { + TScope __slideScope(m_Reader); + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) { + if (strcmp(m_Reader.GetNarrowElementName(), "Add") == 0 + || (inSetSetValues && strcmp(m_Reader.GetNarrowElementName(), "Set") == 0)) { + const char8_t *theId; + m_Reader.Att("ref", theId); + CRegisteredString theIdStr(m_StrTable.RegisterStr(theId + 1)); + if (m_ObjectMap.contains(theIdStr)) { + TIdObjectMap::iterator theObject = m_ObjectMap.find(theIdStr); + if (theObject != m_ObjectMap.end()) { + SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, *theObject->second); + switch (theObject->second->m_Type) { + case GraphObjectTypes::Scene: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::Node: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::Layer: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::Camera: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::Light: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::Model: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::DefaultMaterial: + ParseProperties(*reinterpret_cast(theObject->second), + parser); + break; + case GraphObjectTypes::ReferencedMaterial: + ParseProperties(*static_cast(theObject->second), + parser); + break; + case GraphObjectTypes::Image: + ParseProperties(*reinterpret_cast(theObject->second), parser); + break; + case GraphObjectTypes::Text: + ParseProperties(*static_cast(theObject->second), parser); + break; + case GraphObjectTypes::Effect: + ParseProperties(*static_cast(theObject->second), parser); + break; + case GraphObjectTypes::RenderPlugin: + ParseProperties( + *static_cast(theObject->second), parser); + break; + case GraphObjectTypes::CustomMaterial: + ParseProperties( + *static_cast(theObject->second), + parser); + break; + case GraphObjectTypes::Path: + ParseProperties(*static_cast(theObject->second), + parser); + break; + case GraphObjectTypes::PathSubPath: + ParseProperties( + *static_cast(theObject->second), parser); + break; + default: + QT3DS_ASSERT(false); + break; + } + } else { + TIdPathAnchorIndexMap::iterator iter = + m_AnchorIdToPathAndAnchorIndexMap.find(theIdStr); + if (iter != m_AnchorIdToPathAndAnchorIndexMap.end()) { + SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, + *iter->second.m_Segment); + NVDataRef thePathBuffer = + m_PathManager.GetPathSubPathBuffer(*iter->second.m_Segment); + QT3DSU32 anchorIndex = iter->second.m_AnchorIndex; + QT3DSU32 numAnchors = thePathBuffer.size(); + if (anchorIndex < numAnchors) { + qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); + ParseVec2(parser, "position", thePoint.m_Position); + ParseFloat(parser, "incomingangle", thePoint.m_IncomingAngle); + thePoint.m_OutgoingAngle = thePoint.m_IncomingAngle + 180.0f; + ParseFloat(parser, "incomingdistance", thePoint.m_IncomingDistance); + ParseFloat(parser, "outgoingdistance", thePoint.m_OutgoingDistance); + } + } + } + } + } + } + } + + void AddPluginProperty(qt3ds::render::IRenderPluginClass &pluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Enum inPropType, + eastl::string &tempStr, const char *propName) + { + tempStr.assign(propName); + qt3ds::render::SRenderPluginPropertyDeclaration theDec( + m_StrTable.RegisterStr(tempStr.c_str()), inPropType); + pluginClass.RegisterProperty(theDec); + } + + SPresentation *Load(bool inSetValuesFromSlides) + { + { + TScope __outerScope(m_Reader); + if (m_Reader.MoveToFirstChild("ProjectSettings")) { + m_Reader.Att("presentationWidth", m_Presentation->m_PresentationDimensions.x); + m_Reader.Att("presentationHeight", m_Presentation->m_PresentationDimensions.y); + // Upsize them to a multiple of four. + m_Presentation->m_PresentationDimensions.x = + (QT3DSF32)qt3ds::render::ITextRenderer::NextMultipleOf4( + (QT3DSU32)m_Presentation->m_PresentationDimensions.x); + m_Presentation->m_PresentationDimensions.y = + (QT3DSF32)qt3ds::render::ITextRenderer::NextMultipleOf4( + (QT3DSU32)m_Presentation->m_PresentationDimensions.y); + const char8_t *thePresentationRotation = ""; + if (m_Reader.Att("presentationRotation", thePresentationRotation)) { + bool success = SRenderUIPLoader::ConvertEnumFromStr( + thePresentationRotation, m_Presentation->m_PresentationRotation); + (void)success; + QT3DS_ASSERT(success); + } + m_Reader.Att("preferKTX", m_Presentation->m_preferKTX); + } + } + { + TScope __outerScope(m_Reader); + if (m_Reader.MoveToFirstChild("Classes")) { + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) { + const char8_t *idStr = "", *name = "", *sourcepath = ""; + m_Reader.Att("id", idStr); + m_Reader.Att("name", name); + m_Reader.Att("sourcepath", sourcepath); + if (AreEqual(m_Reader.GetNarrowElementName(), "Effect")) { + CRegisteredString theId(m_StrTable.RegisterStr(idStr)); + if (m_EffectSystem.IsEffectRegistered(theId) == false) { + // File should already be loaded. + Option theEffectMetaData = + m_MetaData.GetEffectMetaDataBySourcePath(sourcepath); + if (theEffectMetaData.hasValue()) { + qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect( + theId, m_Foundation, m_EffectSystem, *theEffectMetaData, + m_StrTable); + } else { + QT3DS_ASSERT(false); + } + } + } else if (AreEqual(m_Reader.GetNarrowElementName(), "CustomMaterial")) { + CRegisteredString theId(m_StrTable.RegisterStr(idStr)); + if (m_CustomMaterialSystem.IsMaterialRegistered(theId) == false) { + // File should already be loaded. + Option theMetaData = + m_MetaData.GetMaterialMetaDataBySourcePath(sourcepath); + if (theMetaData.hasValue()) { + qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial( + theId, m_Foundation, m_CustomMaterialSystem, *theMetaData, + m_StrTable); + } else { + QT3DS_ASSERT(false); + } + } + } else if (AreEqual(m_Reader.GetNarrowElementName(), "RenderPlugin")) { + CRegisteredString theId(m_StrTable.RegisterStr(idStr)); + m_MetaData.LoadPluginXMLFile(m_Reader.GetNarrowElementName(), idStr, name, + sourcepath); + eastl::vector theProperties; + qt3ds::render::IRenderPluginClass *thePluginClass = + m_RenderPluginManager.GetOrCreateRenderPlugin( + m_StrTable.RegisterStr(sourcepath)); + if (thePluginClass) { + m_RenderPluginSourcePaths.insert( + eastl::make_pair(m_StrTable.RegisterStr(idStr), sourcepath)); + m_MetaData.GetInstanceProperties(m_Reader.GetNarrowElementName(), idStr, + theProperties, false); + eastl::string thePropertyStr; + CRegisteredString metaType = + m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr( + m_Reader.GetNarrowElementName()); + CRegisteredString metaId = + m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr( + idStr); + for (QT3DSU32 idx = 0, end = theProperties.size(); idx < end; ++idx) { + using namespace Q3DStudio; + CRegisteredString metaProp = + m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr( + theProperties[idx].c_str()); + Q3DStudio::ERuntimeDataModelDataType thePropType = + m_MetaData.GetPropertyType(metaType, metaProp, metaId); + switch (thePropType) { + case ERuntimeDataModelDataTypeFloat: + AddPluginProperty( + *thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Float, + thePropertyStr, metaProp.c_str()); + break; + case ERuntimeDataModelDataTypeFloat2: + AddPluginProperty( + *thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Vector2, + thePropertyStr, metaProp.c_str()); + break; + case ERuntimeDataModelDataTypeFloat3: + if (m_MetaData.GetAdditionalType(metaType, metaProp, metaId) + != ERuntimeAdditionalMetaDataTypeColor) + AddPluginProperty( + *thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Vector3, + thePropertyStr, metaProp.c_str()); + else + AddPluginProperty( + *thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Color, + thePropertyStr, metaProp.c_str()); + break; + case ERuntimeDataModelDataTypeLong: + AddPluginProperty(*thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Long, + thePropertyStr, metaProp.c_str()); + break; + case ERuntimeDataModelDataTypeString: + case ERuntimeDataModelDataTypeStringRef: + AddPluginProperty( + *thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::String, + thePropertyStr, metaProp.c_str()); + break; + case ERuntimeDataModelDataTypeBool: + AddPluginProperty( + *thePluginClass, + qt3ds::render::SRenderPluginPropertyTypes::Boolean, + thePropertyStr, metaProp.c_str()); + break; + default: + QT3DS_ASSERT(false); + } + } + } + } + } + } + } + { + TScope __outerScope(m_Reader); + if (m_Reader.MoveToFirstChild("BufferData")) { + { + TScope __imageScope(m_Reader); + for (bool valid = m_Reader.MoveToFirstChild("ImageBuffer"); valid; + valid = m_Reader.MoveToNextSibling()) { + const char8_t *srcPath; + m_Reader.UnregisteredAtt("sourcepath", srcPath); + CRegisteredString imgPath = m_StrTable.RegisterStr(srcPath); + bool hasTransparency = false; + m_Reader.Att("hasTransparency", hasTransparency); + m_BufferManager.SetImageHasTransparency(imgPath, hasTransparency); + } + } + } + } + { + TScope __outerScope(m_Reader); + { + if (m_Reader.MoveToFirstChild("Graph")) { + { + TScope __graphScope(m_Reader); + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) + ParseGraphPass1(NULL); + } + { + TScope __graphScope(m_Reader); + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) + ParseGraphPass2(); + } + } + } + } + TScope __outerScope(m_Reader); + if (m_Reader.MoveToFirstChild("Logic")) { + for (bool valid = m_Reader.MoveToFirstChild("State"); valid; + valid = m_Reader.MoveToNextSibling()) { + { + TScope __slideScope(m_Reader); + ParseState(true); // parse master + for (bool subSlide = m_Reader.MoveToFirstChild("State"); subSlide; + subSlide = m_Reader.MoveToNextSibling("State")) { + TScope __subSlideScope(m_Reader); + ParseState(false); // parse slide setting only *add* values + } + } + { + TScope __slideScope(m_Reader); + if (inSetValuesFromSlides && m_Reader.MoveToFirstChild("State")) + ParseState(true); // parse slide setting only *set* values + } + } + } + + return m_Presentation; + } +}; +} + +SPresentation *qt3ds::render::IUIPLoader::LoadUIPFile( + qt3dsdm::IDOMReader &inReader, const char8_t *inFullPathToPresentationFile, + Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable, + NVFoundationBase &inFoundation + // Allocator used for the presentation objects themselves + // this allows clients to pre-allocate a block of memory just for + // the scene graph + , + NVAllocatorCallback &inPresentationAllocator + // Map of string ids to objects + , + TIdObjectMap &ioObjectMap, IBufferManager &inBufferManager, IEffectSystem &inEffectSystem, + const char8_t *inPresentationDir, IRenderPluginManager &inPluginManager, + ICustomMaterialSystem &inCMS, IDynamicObjectSystem &inDynamicSystem, + qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver, + const Q3DSVariantConfig &variantConfig, bool inSetValuesFromSlides) +{ + SRenderUIPLoader theLoader(inReader, inFullPathToPresentationFile, inMetaData, inStrTable, + inFoundation, inPresentationAllocator, ioObjectMap, inBufferManager, + inEffectSystem, inPresentationDir, inPluginManager, inCMS, + inDynamicSystem, inPathManager, inResolver, variantConfig); + return theLoader.Load(inSetValuesFromSlides); +} +using namespace qt3dsdm; + +inline qt3ds::render::NVRenderTextureFormats::Enum +ConvertTypeAndFormatToTextureFormat(const char8_t *inType, const char8_t *inFormat, + NVFoundationBase &inFoundation) +{ + qt3ds::render::NVRenderTextureFormats::Enum retval = qt3ds::render::NVRenderTextureFormats::RGBA8; + if (AreEqual(inType, "ubyte")) { + if (AreEqual(inFormat, "rgb")) + retval = qt3ds::render::NVRenderTextureFormats::RGB8; + else if (AreEqual(inFormat, "rgba")) + retval = qt3ds::render::NVRenderTextureFormats::RGBA8; + else if (AreEqual(inFormat, "alpha")) + retval = qt3ds::render::NVRenderTextureFormats::Alpha8; + else if (AreEqual(inFormat, "lum")) + retval = qt3ds::render::NVRenderTextureFormats::Luminance8; + else if (AreEqual(inFormat, "lum_alpha")) + retval = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; + } else if (AreEqual(inType, "ushort")) { + if (AreEqual(inFormat, "rgb")) + retval = qt3ds::render::NVRenderTextureFormats::RGB565; + else if (AreEqual(inFormat, "rgba")) + retval = qt3ds::render::NVRenderTextureFormats::RGBA5551; + } else { + qCCritical(INVALID_PARAMETER, "Unsupported texture type %s, defaulting to RGBA8", + inType); + } + return retval; +} + +inline qt3ds::render::NVRenderTextureMagnifyingOp::Enum +ConvertFilterToMagOp(const char8_t *inFilter, NVFoundationBase &inFoundation) +{ + if (AreEqual(inFilter, "linear")) + return qt3ds::render::NVRenderTextureMagnifyingOp::Linear; + if (AreEqual(inFilter, "nearest")) + return qt3ds::render::NVRenderTextureMagnifyingOp::Nearest; + else { + qCCritical(INVALID_PARAMETER, "Unsupported filter type %s, defaulting to linear", + inFilter); + return qt3ds::render::NVRenderTextureMagnifyingOp::Linear; + } +} + +inline qt3ds::render::NVRenderTextureCoordOp::Enum +ConvertTextureCoordOp(const char8_t *inWrap, NVFoundationBase &inFoundation) +{ + if (AreEqual(inWrap, "clamp")) + return qt3ds::render::NVRenderTextureCoordOp::ClampToEdge; + if (AreEqual(inWrap, "repeat")) + return qt3ds::render::NVRenderTextureCoordOp::Repeat; + else { + qCCritical(INVALID_PARAMETER, "Unsupported wrap type %s, defaulting to clamp", + inWrap); + return qt3ds::render::NVRenderTextureCoordOp::ClampToEdge; + } +} + +template +QString ConvertUTFtoQString(const TCharStr *string); + +template <> +QString ConvertUTFtoQString(const char16_t *string) +{ + return QString::fromUtf16(string); +} + +template <> +QString ConvertUTFtoQString(const char32_t *string) +{ + return QString::fromUcs4(string); +} + +template <> +QString ConvertUTFtoQString(const wchar_t *string) +{ + return QString::fromWCharArray(string); +} + +// Re-register all strings because we can't be sure that the meta data system and the effect +// system are sharing the same string table. +void qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect( + CRegisteredString inEffectName, NVFoundationBase &inFoundation, IEffectSystem &inEffectSystem, + const qt3dsdm::SMetaDataEffect &inMetaDataEffect, IStringTable &inStrTable) +{ + using namespace qt3ds::render::dynamic; + if (inEffectSystem.IsEffectRegistered(inEffectName)) { + qCCritical(INVALID_OPERATION, "Effect %s is already registered", + inEffectName.c_str()); + QT3DS_ASSERT(false); + return; + } + nvvector thePropertyDeclarations( + inFoundation.getAllocator(), "qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect"); + nvvector theEnumNames( + inFoundation.getAllocator(), "qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect"); + CRenderString theConvertStr; + CRenderString theConvertShaderTypeStr; + CRenderString theConvertShaderVersionStr; + + for (QT3DSU32 idx = 0, end = inMetaDataEffect.m_Properties.size(); idx < end; ++idx) + thePropertyDeclarations.push_back( + SPropertyDeclaration(inMetaDataEffect.m_Properties[idx].m_Name.c_str(), + inMetaDataEffect.m_Properties[idx].m_DataType)); + inEffectSystem.RegisterEffect(inEffectName, thePropertyDeclarations); + for (QT3DSU32 idx = 0, end = inMetaDataEffect.m_Properties.size(); idx < end; ++idx) { + const SPropertyDefinition &theDefinition(inMetaDataEffect.m_Properties[idx]); + if (theDefinition.m_EnumValueNames.size()) { + theEnumNames.clear(); + for (QT3DSU32 enumIdx = 0, enumEnd = theDefinition.m_EnumValueNames.size(); + enumIdx < enumEnd; ++enumIdx) + theEnumNames.push_back( + inStrTable.RegisterStr(theDefinition.m_EnumValueNames[enumIdx])); + inEffectSystem.SetEffectPropertyEnumNames( + inEffectName, inStrTable.RegisterStr(theDefinition.m_Name), theEnumNames); + } + if (theDefinition.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) + inEffectSystem.SetEffectPropertyTextureSettings( + inEffectName, inStrTable.RegisterStr(theDefinition.m_Name), + inStrTable.RegisterStr(theDefinition.m_ImagePath), theDefinition.m_TexUsageType, + theDefinition.m_CoordOp, theDefinition.m_MagFilterOp, theDefinition.m_MinFilterOp); + } + for (QT3DSU32 idx = 0, end = inMetaDataEffect.m_Shaders.size(); idx < end; ++idx) { + const qt3dsdm::SMetaDataShader &theShader = inMetaDataEffect.m_Shaders[idx]; + theConvertStr.clear(); + theConvertStr = ConvertUTFtoQString( + theShader.m_Code.c_str()).toStdString(); + theConvertShaderTypeStr = ConvertUTFtoQString( + theShader.m_Type.c_str()).toStdString(); + theConvertShaderVersionStr = ConvertUTFtoQString( + theShader.m_Version.c_str()).toStdString(); + + inEffectSystem.SetShaderData(inStrTable.RegisterStr(theShader.m_Name.c_str()), + theConvertStr.c_str(), theConvertShaderVersionStr.c_str(), + theConvertStr.c_str(), theShader.m_HasGeomShader, + theShader.m_IsComputeShader); + } + + inEffectSystem.SetEffectCommands(inEffectName, inMetaDataEffect.m_EffectCommands); +} + +void qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial( + CRegisteredString inClassName, NVFoundationBase &inFoundation, + ICustomMaterialSystem &inMaterialSystem, + const qt3dsdm::SMetaDataCustomMaterial &inMetaDataMaterial, IStringTable &inStrTable) +{ + using namespace qt3ds::render::dynamic; + if (inMaterialSystem.IsMaterialRegistered(inClassName)) { + qCCritical(INVALID_OPERATION, "Effect %s is already registered", + inClassName.c_str()); + QT3DS_ASSERT(false); + return; + } + nvvector thePropertyDeclarations( + inFoundation.getAllocator(), + "qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial"); + nvvector theEnumNames( + inFoundation.getAllocator(), + "qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial"); + CRenderString theConvertStr; + CRenderString theConvertShaderTypeStr; + CRenderString theConvertShaderVersionStr; + for (QT3DSU32 idx = 0, end = inMetaDataMaterial.m_Properties.size(); idx < end; ++idx) + thePropertyDeclarations.push_back( + SPropertyDeclaration(inMetaDataMaterial.m_Properties[idx].m_Name.c_str(), + inMetaDataMaterial.m_Properties[idx].m_DataType)); + inMaterialSystem.RegisterMaterialClass(inClassName, thePropertyDeclarations); + for (QT3DSU32 idx = 0, end = inMetaDataMaterial.m_Properties.size(); idx < end; ++idx) { + const SPropertyDefinition &theDefinition(inMetaDataMaterial.m_Properties[idx]); + if (theDefinition.m_EnumValueNames.size()) { + theEnumNames.clear(); + for (QT3DSU32 enumIdx = 0, enumEnd = theDefinition.m_EnumValueNames.size(); + enumIdx < enumEnd; ++enumIdx) + theEnumNames.push_back( + inStrTable.RegisterStr(theDefinition.m_EnumValueNames[enumIdx])); + inMaterialSystem.SetPropertyEnumNames( + inClassName, inStrTable.RegisterStr(theDefinition.m_Name), theEnumNames); + } + if (theDefinition.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) + inMaterialSystem.SetPropertyTextureSettings( + inClassName, inStrTable.RegisterStr(theDefinition.m_Name), + inStrTable.RegisterStr(theDefinition.m_ImagePath), theDefinition.m_TexUsageType, + theDefinition.m_CoordOp, theDefinition.m_MagFilterOp, theDefinition.m_MinFilterOp); + } + if (inMetaDataMaterial.m_Shaders.size()) { + for (QT3DSU32 idx = 0, end = (QT3DSU32)inMetaDataMaterial.m_Shaders.size(); idx < end; ++idx) { + const qt3dsdm::SMetaDataShader &theShader = inMetaDataMaterial.m_Shaders[idx]; + theConvertStr = ConvertUTFtoQString( + theShader.m_Code.c_str()).toStdString(); + theConvertShaderTypeStr = ConvertUTFtoQString( + theShader.m_Type.c_str()).toStdString(); + theConvertShaderVersionStr = ConvertUTFtoQString( + theShader.m_Version.c_str()).toStdString(); + inMaterialSystem.SetMaterialClassShader( + inStrTable.RegisterStr(theShader.m_Name.c_str()), theConvertShaderTypeStr.c_str(), + theConvertShaderVersionStr.c_str(), theConvertStr.c_str(), + theShader.m_HasGeomShader, theShader.m_IsComputeShader); + } + } + + inMaterialSystem.SetCustomMaterialCommands(inClassName, + inMetaDataMaterial.m_CustomMaterialCommands); + inMaterialSystem.SetCustomMaterialTransparency(inClassName, + inMetaDataMaterial.m_HasTransparency); + inMaterialSystem.SetCustomMaterialRefraction(inClassName, inMetaDataMaterial.m_HasRefraction); + inMaterialSystem.SetCustomMaterialAlwaysDirty(inClassName, inMetaDataMaterial.m_AlwaysDirty); + inMaterialSystem.SetCustomMaterialShaderKey(inClassName, inMetaDataMaterial.m_ShaderKey); + inMaterialSystem.SetCustomMaterialLayerCount(inClassName, inMetaDataMaterial.m_LayerCount); +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.h b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.h new file mode 100644 index 00000000..2b70c687 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPLoader.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_UIP_LOADER_H +#define QT3DS_RENDER_UIP_LOADER_H + +#ifdef QT3DS_RENDER_ENABLE_LOAD_UIP + +#include "Qt3DSRender.h" +#include "foundation/StringTable.h" +#include +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderGraphObject.h" +#include + +namespace Q3DStudio { +class IRuntimeMetaData; +} + +namespace qt3dsdm { +class IDOMReader; +struct SMetaDataEffect; +struct SMetaDataCustomMaterial; +} + +namespace qt3ds { +class Q3DSVariantConfig; + +namespace render { + + class IBufferManager; + + typedef nvhash_map TIdObjectMap; + + struct IUIPReferenceResolver + { + protected: + virtual ~IUIPReferenceResolver() {} + public: + virtual CRegisteredString ResolveReference(CRegisteredString inStart, + const char *inReference) = 0; + }; + + struct SPresentation; + + class QT3DS_AUTOTEST_EXPORT IUIPLoader + { + public: + // The reader needs to point to the top of the file, we will search + // several objects that exist at the top level of the uip file. + // Returns NULL if we were incapable of loading the presentation. + static SPresentation * + LoadUIPFile(qt3dsdm::IDOMReader &inReader + // the full path, including the filename + // to the presentation file + , + const char8_t *inFullPathToPresentationFile, + Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable, + NVFoundationBase &inFoundation + // Allocator used for the presentation objects themselves + // this allows clients to pre-allocate a block of memory just for + // the scene graph + , + NVAllocatorCallback &inPresentationAllocator + // Map of string ids to objects + , + TIdObjectMap &ioObjectMap + // Buffer manager to load details about the images + , + IBufferManager &inBufferManager + // To load effects we need the effect system + // and the presentation directory + , + IEffectSystem &inEffectSystem, const char8_t *inPresentationDir, + IRenderPluginManager &inPluginManager, ICustomMaterialSystem &inMaterialSystem, + IDynamicObjectSystem &inDynamicSystem, qt3ds::render::IPathManager &inPathManager + // Resolve references to objects; this is done by the main uip loader during + // its normal mode of operation so we try to reuse that code. + , + IUIPReferenceResolver *inResolver + // Variant config defines variant groups and tags to be used to filter out + // unneeded parts of the presentation + , + const Q3DSVariantConfig &variantConfig + // Set some initial values by going to the master slide then slide 1 + // Useful for quick testing, sort of equivalent to showing the first frame + // of a given presentation + , + bool setValuesFromSlides = false); + + static void CreateEffectClassFromMetaEffect(CRegisteredString inEffectName, + NVFoundationBase &inFoundation, + IEffectSystem &inEffectSystem, + const qt3dsdm::SMetaDataEffect &inMetaDataEffect, + IStringTable &inStrTable); + + static void CreateMaterialClassFromMetaMaterial( + CRegisteredString inEffectName, NVFoundationBase &inFoundation, + ICustomMaterialSystem &inEffectSystem, + const qt3dsdm::SMetaDataCustomMaterial &inMetaDataMaterial, IStringTable &inStrTable); + }; +} +} + +#endif +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.cpp new file mode 100644 index 00000000..a0594933 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.cpp @@ -0,0 +1,464 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderUIPSharedTranslation.h" + +namespace qt3ds { +namespace render { + +#define WCHAR_T_Directional L"Directional" +#define WCHAR_T_Point L"Point" +#define WCHAR_T_Area L"Area" +#define WCHAR_T_None L"None" +#define WCHAR_T_Vertex L"Vertex" +#define WCHAR_T_Pixel L"Pixel" +#define WCHAR_T_Normal L"Normal" +#define WCHAR_T_Screen L"Screen" +#define WCHAR_T_Multiply L"Multiply" +#define WCHAR_T_Overlay L"Overlay" +#define WCHAR_T_ColorBurn L"ColorBurn" +#define WCHAR_T_ColorDodge L"ColorDodge" +#define WCHAR_T_Add L"Add" +#define WCHAR_T_Subtract L"Subtract" +#define WCHAR_T_UV_Mapping L"UV Mapping" +#define WCHAR_T_Environmental_Mapping L"Environmental Mapping" +#define WCHAR_T_Light_Probe L"Light Probe" +#define WCHAR_T_No_Tiling L"No Tiling" +#define WCHAR_T_Mirrored L"Mirrored" +#define WCHAR_T_Tiled L"Tiled" +#define WCHAR_T_Left L"Left" +#define WCHAR_T_Center L"Center" +#define WCHAR_T_Right L"Right" +#define WCHAR_T_Top L"Top" +#define WCHAR_T_Middle L"Middle" +#define WCHAR_T_Bottom L"Bottom" +#define WCHAR_T_ElideNone L"ElideNone" +#define WCHAR_T_ElideLeft L"ElideLeft" +#define WCHAR_T_ElideMiddle L"ElideMiddle" +#define WCHAR_T_ElideRight L"ElideRight" +#define WCHAR_T_2x L"2x" +#define WCHAR_T_4x L"4x" +#define WCHAR_T_8x L"8x" +#define WCHAR_T_SSAA L"SSAA" +#define WCHAR_T_NoRotation L"NoRotation" +#define WCHAR_T_Clockwise90 L"90" +#define WCHAR_T_Clockwise180 L"180" +#define WCHAR_T_Clockwise270 L"270" +#define WCHAR_T_Fit L"Fit" +#define WCHAR_T_Same_Size L"Same Size" +#define WCHAR_T_CENTER L"Center" +#define WCHAR_T_North L"N" +#define WCHAR_T_NorthEast L"NE" +#define WCHAR_T_East L"E" +#define WCHAR_T_SouthEast L"SE" +#define WCHAR_T_South L"S" +#define WCHAR_T_SouthWest L"SW" +#define WCHAR_T_West L"W" +#define WCHAR_T_NorthWest L"NW" +#define WCHAR_T_LeftWidth L"Left/Width" +#define WCHAR_T_LeftRight L"Left/Right" +#define WCHAR_T_WidthRight L"Width/Right" +#define WCHAR_T_TopHeight L"Top/Height" +#define WCHAR_T_TopBottom L"Top/Bottom" +#define WCHAR_T_HeightBottom L"Height/Bottom" +#define WCHAR_T_Percent L"percent" +#define WCHAR_T_Pixels L"pixels" +#define WCHAR_T_Fit_Horizontal L"Fit Horizontal" +#define WCHAR_T_Fit_Vertical L"Fit Vertical" +#define WCHAR_T_Default L"Default" +#define WCHAR_T_KGGX L"KGGX" +#define WCHAR_T_KWard L"KWard" +#define WCHAR_T_Transparent L"Transparent" +#define WCHAR_T_Unspecified L"Unspecified" +#define WCHAR_T_Color L"SolidColor" +#define WCHAR_T_Linear L"Linear" +#define WCHAR_T_Phong L"Phong" +#define WCHAR_T_NPatch L"NPatch" +#define WCHAR_T_Taper L"Taper" +#define WCHAR_T_Geometry L"Geometry" +#define WCHAR_T_Painted L"Painted" +#define WCHAR_T_Filled L"Filled" +#define WCHAR_T_Stroked L"Stroked" +#define WCHAR_T_FilledAndStroked L"Filled and Stroked" +#define WCHAR_T_Simple L"Simple" +#define WCHAR_T_Smoke L"Smoke" +#define WCHAR_T_Cloud L"Cloud" +#define WCHAR_T_Fluid L"Fluid" +#define WCHAR_T_User L"User" +#define WCHAR_T_Clip L"Clip" +#define WCHAR_T_WrapWord L"WrapWord" +#define WCHAR_T_WrapAnywhere L"WrapAnywhere" + +#define CHAR_T_Directional "Directional" +#define CHAR_T_Point "Point" +#define CHAR_T_Area "Area" +#define CHAR_T_None "None" +#define CHAR_T_Vertex "Vertex" +#define CHAR_T_Pixel "Pixel" +#define CHAR_T_Normal "Normal" +#define CHAR_T_Screen "Screen" +#define CHAR_T_Multiply "Multiply" +#define CHAR_T_Overlay "Overlay" +#define CHAR_T_ColorBurn "ColorBurn" +#define CHAR_T_ColorDodge "ColorDodge" +#define CHAR_T_Add "Add" +#define CHAR_T_Subtract "Subtract" +#define CHAR_T_UV_Mapping "UV Mapping" +#define CHAR_T_Environmental_Mapping "Environmental Mapping" +#define CHAR_T_Light_Probe "Light Probe" +#define CHAR_T_No_Tiling "No Tiling" +#define CHAR_T_Mirrored "Mirrored" +#define CHAR_T_Tiled "Tiled" +#define CHAR_T_Left "Left" +#define CHAR_T_Center "Center" +#define CHAR_T_Right "Right" +#define CHAR_T_Top "Top" +#define CHAR_T_Middle "Middle" +#define CHAR_T_Bottom "Bottom" +#define CHAR_T_ElideNone "ElideNone" +#define CHAR_T_ElideLeft "ElideLeft" +#define CHAR_T_ElideMiddle "ElideMiddle" +#define CHAR_T_ElideRight "ElideRight" +#define CHAR_T_2x "2x" +#define CHAR_T_4x "4x" +#define CHAR_T_8x "8x" +#define CHAR_T_SSAA "SSAA" +#define CHAR_T_NoRotation "NoRotation" +#define CHAR_T_Clockwise90 "90" +#define CHAR_T_Clockwise180 "180" +#define CHAR_T_Clockwise270 "270" +#define CHAR_T_Fit "Fit" +#define CHAR_T_Same_Size "Same Size" +#define CHAR_T_CENTER "Center" +#define CHAR_T_North "N" +#define CHAR_T_NorthEast "NE" +#define CHAR_T_East "E" +#define CHAR_T_SouthEast "SE" +#define CHAR_T_South "S" +#define CHAR_T_SouthWest "SW" +#define CHAR_T_West "W" +#define CHAR_T_NorthWest "NW" +#define CHAR_T_LeftWidth "Left/Width" +#define CHAR_T_LeftRight "Left/Right" +#define CHAR_T_WidthRight "Width/Right" +#define CHAR_T_TopHeight "Top/Height" +#define CHAR_T_TopBottom "Top/Bottom" +#define CHAR_T_HeightBottom "Height/Bottom" +#define CHAR_T_Percent "percent" +#define CHAR_T_Pixels "pixels" +#define CHAR_T_Fit_Horizontal "Fit Horizontal" +#define CHAR_T_Fit_Vertical "Fit Vertical" +#define CHAR_T_Default "Default" +#define CHAR_T_KGGX "KGGX" +#define CHAR_T_KWard "KWard" +#define CHAR_T_Transparent "Transparent" +#define CHAR_T_Unspecified "Unspecified" +#define CHAR_T_Color "SolidColor" +#define CHAR_T_Linear "Linear" +#define CHAR_T_Phong "Phong" +#define CHAR_T_NPatch "NPatch" +#define CHAR_T_Taper "Taper" +#define CHAR_T_Geometry "Geometry" +#define CHAR_T_Painted "Painted" +#define CHAR_T_Filled "Filled" +#define CHAR_T_Stroked "Stroked" +#define CHAR_T_FilledAndStroked "Filled and Stroked" +#define CHAR_T_Simple "Simple" +#define CHAR_T_Smoke "Smoke" +#define CHAR_T_Cloud "Cloud" +#define CHAR_T_Fluid "Fluid" +#define CHAR_T_User "User" +#define CHAR_T_Clip "Clip" +#define CHAR_T_WrapWord "WrapWord" +#define CHAR_T_WrapAnywhere "WrapAnywhere" + +#define DEFINE_NAME_MAP_ENTRY(enumval, name) \ + { \ + enumval, WCHAR_T_##name, CHAR_T_##name \ + } + SEnumNameMap g_LightTypesMap[] = { + DEFINE_NAME_MAP_ENTRY(RenderLightTypes::Directional, Directional), + DEFINE_NAME_MAP_ENTRY(RenderLightTypes::Point, Point), + DEFINE_NAME_MAP_ENTRY(RenderLightTypes::Area, Area), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_MaterialLightingMap[] = { + DEFINE_NAME_MAP_ENTRY(DefaultMaterialLighting::NoLighting, None), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialLighting::VertexLighting, Vertex), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialLighting::FragmentLighting, Pixel), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_BlendModeMap[] = { + DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Normal, Normal), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Screen, Screen), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Multiply, Multiply), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::Overlay, Overlay), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::ColorBurn, ColorBurn), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialBlendMode::ColorDodge, ColorDodge), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_ImageMappingModeMap[] = { + DEFINE_NAME_MAP_ENTRY(ImageMappingModes::Normal, UV_Mapping), + DEFINE_NAME_MAP_ENTRY(ImageMappingModes::Environment, Environmental_Mapping), + DEFINE_NAME_MAP_ENTRY(ImageMappingModes::LightProbe, Light_Probe), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_RenderTextureCoordOpMap[] = { + DEFINE_NAME_MAP_ENTRY(NVRenderTextureCoordOp::ClampToEdge, No_Tiling), + DEFINE_NAME_MAP_ENTRY(NVRenderTextureCoordOp::MirroredRepeat, Mirrored), + DEFINE_NAME_MAP_ENTRY(NVRenderTextureCoordOp::Repeat, Tiled), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_TextHorizontalAlignmentMap[] = { + DEFINE_NAME_MAP_ENTRY(TextHorizontalAlignment::Left, Left), + DEFINE_NAME_MAP_ENTRY(TextHorizontalAlignment::Center, Center), + DEFINE_NAME_MAP_ENTRY(TextHorizontalAlignment::Right, Right), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_TextVerticalAlignmentMap[] = { + DEFINE_NAME_MAP_ENTRY(TextVerticalAlignment::Top, Top), + DEFINE_NAME_MAP_ENTRY(TextVerticalAlignment::Middle, Middle), + DEFINE_NAME_MAP_ENTRY(TextVerticalAlignment::Bottom, Bottom), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_TextWordWrapMap[] = { + DEFINE_NAME_MAP_ENTRY(TextWordWrap::Clip, Clip), + DEFINE_NAME_MAP_ENTRY(TextWordWrap::WrapWord, WrapWord), + DEFINE_NAME_MAP_ENTRY(TextWordWrap::WrapAnywhere, WrapAnywhere), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_TextElideMap[] = { + DEFINE_NAME_MAP_ENTRY(TextElide::ElideNone, ElideNone), + DEFINE_NAME_MAP_ENTRY(TextElide::ElideLeft, ElideLeft), + DEFINE_NAME_MAP_ENTRY(TextElide::ElideMiddle, ElideMiddle), + DEFINE_NAME_MAP_ENTRY(TextElide::ElideRight, ElideRight), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_ProgressiveAAValuesMap[] = { + DEFINE_NAME_MAP_ENTRY(AAModeValues::NoAA, None), + DEFINE_NAME_MAP_ENTRY(AAModeValues::SSAA, SSAA), + DEFINE_NAME_MAP_ENTRY(AAModeValues::X2, 2x), + DEFINE_NAME_MAP_ENTRY(AAModeValues::X4, 4x), + DEFINE_NAME_MAP_ENTRY(AAModeValues::X8, 8x), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_LayerBlendTypesMap[] = { + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Normal, Normal), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Screen, Screen), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Multiply, Multiply), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Add, Add), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Subtract, Subtract), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::Overlay, Overlay), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::ColorBurn, ColorBurn), + DEFINE_NAME_MAP_ENTRY(LayerBlendTypes::ColorDodge, ColorDodge), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_RenderRotationValuesMap[] = { + DEFINE_NAME_MAP_ENTRY(RenderRotationValues::NoRotation, None), + DEFINE_NAME_MAP_ENTRY(RenderRotationValues::Clockwise90, Clockwise90), + DEFINE_NAME_MAP_ENTRY(RenderRotationValues::Clockwise180, Clockwise180), + DEFINE_NAME_MAP_ENTRY(RenderRotationValues::Clockwise270, Clockwise270), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_CameraScaleModesMap[] = { + DEFINE_NAME_MAP_ENTRY(CameraScaleModes::Fit, Fit), + DEFINE_NAME_MAP_ENTRY(CameraScaleModes::SameSize, Same_Size), + DEFINE_NAME_MAP_ENTRY(CameraScaleModes::FitHorizontal, Fit_Horizontal), + DEFINE_NAME_MAP_ENTRY(CameraScaleModes::FitVertical, Fit_Vertical), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_CameraScaleAnchorsMap[] = { + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::Center, Center), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::North, North), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::NorthEast, NorthEast), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::East, East), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::SouthEast, SouthEast), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::South, South), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::SouthWest, SouthWest), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::West, West), + DEFINE_NAME_MAP_ENTRY(CameraScaleAnchors::NorthWest, NorthWest), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_HorizontalFieldValuesMap[] = { + DEFINE_NAME_MAP_ENTRY(HorizontalFieldValues::LeftWidth, LeftWidth), + DEFINE_NAME_MAP_ENTRY(HorizontalFieldValues::LeftRight, LeftRight), + DEFINE_NAME_MAP_ENTRY(HorizontalFieldValues::WidthRight, WidthRight), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_VerticalFieldValuesMap[] = { + DEFINE_NAME_MAP_ENTRY(VerticalFieldValues::TopHeight, TopHeight), + DEFINE_NAME_MAP_ENTRY(VerticalFieldValues::TopBottom, TopBottom), + DEFINE_NAME_MAP_ENTRY(VerticalFieldValues::HeightBottom, HeightBottom), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_LayerUnitTypesMap[] = { + DEFINE_NAME_MAP_ENTRY(LayerUnitTypes::Percent, Percent), + DEFINE_NAME_MAP_ENTRY(LayerUnitTypes::Pixels, Pixels), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_LayerBackgroundMap[] = { + DEFINE_NAME_MAP_ENTRY(LayerBackground::Transparent, Transparent), + DEFINE_NAME_MAP_ENTRY(LayerBackground::Unspecified, Unspecified), + DEFINE_NAME_MAP_ENTRY(LayerBackground::Color, Color), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_SpecularTypesMap[] = { + DEFINE_NAME_MAP_ENTRY(DefaultMaterialSpecularModel::Default, Default), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialSpecularModel::KGGX, KGGX), + DEFINE_NAME_MAP_ENTRY(DefaultMaterialSpecularModel::KWard, KWard), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_TessellationValuesMap[] = { + DEFINE_NAME_MAP_ENTRY(TessModeValues::NoTess, None), + DEFINE_NAME_MAP_ENTRY(TessModeValues::TessLinear, Linear), + DEFINE_NAME_MAP_ENTRY(TessModeValues::TessPhong, Phong), + DEFINE_NAME_MAP_ENTRY(TessModeValues::TessNPatch, NPatch), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_PathCappingValuesMap[] = { + DEFINE_NAME_MAP_ENTRY(PathCapping::Noner, None), + DEFINE_NAME_MAP_ENTRY(PathCapping::Taper, Taper), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_PathTypesMap[] = { + DEFINE_NAME_MAP_ENTRY(PathTypes::Noner, None), + DEFINE_NAME_MAP_ENTRY(PathTypes::Painted, Painted), + DEFINE_NAME_MAP_ENTRY(PathTypes::Geometry, Geometry), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap g_PathPaintStylesMap[] = { + DEFINE_NAME_MAP_ENTRY(PathPaintStyles::Noner, None), + DEFINE_NAME_MAP_ENTRY(PathPaintStyles::FilledAndStroked, FilledAndStroked), + DEFINE_NAME_MAP_ENTRY(PathPaintStyles::Filled, Filled), + DEFINE_NAME_MAP_ENTRY(PathPaintStyles::Stroked, Stroked), + { (QT3DSU32)-1, NULL }, + }; + + SEnumNameMap *SEnumParseMap::GetMap() { return g_LightTypesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_MaterialLightingMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_BlendModeMap; } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_ImageMappingModeMap; } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_RenderTextureCoordOpMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_TextHorizontalAlignmentMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_TextVerticalAlignmentMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_TextWordWrapMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_TextElideMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_ProgressiveAAValuesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_LayerBlendTypesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_RenderRotationValuesMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_CameraScaleModesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_CameraScaleAnchorsMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_HorizontalFieldValuesMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_VerticalFieldValuesMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_LayerUnitTypesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_LayerBackgroundMap; } + + SEnumNameMap *SEnumParseMap::GetMap() + { + return g_SpecularTypesMap; + } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_TessellationValuesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_PathCappingValuesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_PathTypesMap; } + + SEnumNameMap *SEnumParseMap::GetMap() { return g_PathPaintStylesMap; } +} +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.h b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.h new file mode 100644 index 00000000..8ba74eae --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderUIPSharedTranslation.h @@ -0,0 +1,488 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_UIP_SHARED_TRANSLATION_H +#define QT3DS_RENDER_UIP_SHARED_TRANSLATION_H +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderImage.h" +#include "Qt3DSRenderText.h" +#include "Qt3DSDMWindowsCompatibility.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderModel.h" +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderPresentation.h" + +// map from qt3dsdm to qt3ds::render +namespace qt3ds { +namespace render { + + template + struct SEnumParseMap + { + }; + + struct SEnumNameMap + { + QT3DSU32 m_Enum; + const wchar_t *m_WideName; + const char8_t *m_Name; + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + + template <> + struct SEnumParseMap + { + static SEnumNameMap *GetMap(); + }; + +#define QT3DS_RENDER_WCHAR_T_XYZs L"XYZ" +#define QT3DS_RENDER_WCHAR_T_YZXs L"YZX" +#define QT3DS_RENDER_WCHAR_T_ZXYs L"ZXY" +#define QT3DS_RENDER_WCHAR_T_XZYs L"XZY" +#define QT3DS_RENDER_WCHAR_T_YXZs L"YXZ" +#define QT3DS_RENDER_WCHAR_T_ZYXs L"ZYX" + +#define QT3DS_RENDER_WCHAR_T_XYZr L"XYZr" +#define QT3DS_RENDER_WCHAR_T_YZXr L"YZXr" +#define QT3DS_RENDER_WCHAR_T_ZXYr L"ZXYr" +#define QT3DS_RENDER_WCHAR_T_XZYr L"XZYr" +#define QT3DS_RENDER_WCHAR_T_YXZr L"YXZr" +#define QT3DS_RENDER_WCHAR_T_ZYXr L"ZYXr" + +#define QT3DS_RENDER_CHAR_T_XYZs "XYZ" +#define QT3DS_RENDER_CHAR_T_YZXs "YZX" +#define QT3DS_RENDER_CHAR_T_ZXYs "ZXY" +#define QT3DS_RENDER_CHAR_T_XZYs "XZY" +#define QT3DS_RENDER_CHAR_T_YXZs "YXZ" +#define QT3DS_RENDER_CHAR_T_ZYXs "ZYX" + +#define QT3DS_RENDER_CHAR_T_XYZr "XYZr" +#define QT3DS_RENDER_CHAR_T_YZXr "YZXr" +#define QT3DS_RENDER_CHAR_T_ZXYr "ZXYr" +#define QT3DS_RENDER_CHAR_T_XZYr "XZYr" +#define QT3DS_RENDER_CHAR_T_YXZr "YXZr" +#define QT3DS_RENDER_CHAR_T_ZYXr "ZYXr" + + inline QT3DSU32 MapRotationOrder(const wchar_t *inOrderStr) + { +#define MAP_ROTATION_ORDER(name, postfix) \ + if (wcscmp(inOrderStr, QT3DS_RENDER_WCHAR_T_##name##postfix) == 0) { \ + return EulOrd##name##postfix; \ + } + MAP_ROTATION_ORDER(XYZ, s); + MAP_ROTATION_ORDER(YZX, s); + MAP_ROTATION_ORDER(ZXY, s); + MAP_ROTATION_ORDER(XZY, s); + MAP_ROTATION_ORDER(YXZ, s); + MAP_ROTATION_ORDER(ZYX, s); + MAP_ROTATION_ORDER(XYZ, r); + MAP_ROTATION_ORDER(YZX, r); + MAP_ROTATION_ORDER(ZXY, r); + MAP_ROTATION_ORDER(XZY, r); + MAP_ROTATION_ORDER(YXZ, r); + MAP_ROTATION_ORDER(ZYX, r); +#undef MAP_ROTATION_ORDER + return EulOrdYXZs; + } + + inline QT3DSU32 MapRotationOrder(const char8_t *inOrderStr) + { +#define MAP_ROTATION_ORDER(name, postfix) \ + if (strcmp(inOrderStr, QT3DS_RENDER_CHAR_T_##name##postfix) == 0) { \ + return EulOrd##name##postfix; \ + } + MAP_ROTATION_ORDER(XYZ, s); + MAP_ROTATION_ORDER(YZX, s); + MAP_ROTATION_ORDER(ZXY, s); + MAP_ROTATION_ORDER(XZY, s); + MAP_ROTATION_ORDER(YXZ, s); + MAP_ROTATION_ORDER(ZYX, s); + MAP_ROTATION_ORDER(XYZ, r); + MAP_ROTATION_ORDER(YZX, r); + MAP_ROTATION_ORDER(ZXY, r); + MAP_ROTATION_ORDER(XZY, r); + MAP_ROTATION_ORDER(YXZ, r); + MAP_ROTATION_ORDER(ZYX, r); +#undef MAP_ROTATION_ORDER + return EulOrdYXZs; + } + + // the goal is to unify the systems that transfer information into the UICRender library. + // There are currently three such systems; the runtime, studio, and the uip loader that loads + // uip files + // directly into the render library. + // To do this, we need to have a mapping between a generic key and a given property on every + // object + // along with some information about what portion of the object model this property affects. + + struct Qt3DSRenderDirtyFlags + { + enum Enum { + Unknown = 0, + Dirty = 1 << 0, + TransformDirty = 1 << 1, + TextDirty = 1 << 2, + }; + }; + +// Now we build out generic macros with no implementation that list all of the properties +// on each struct that we care about. We will fill in these macros with implementation later. +// Each macro will list the property name along with what dirty operation should get marked +// Global parse tables that list every property used by the system. + +#define ITERATE_QT3DS_RENDER_SCENE_PROPERTIES \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Scene, ClearColor, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Scene, UseClearColor, Dirty) + +#define ITERATE_QT3DS_RENDER_NODE_PROPERTIES \ + HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Rotation, TransformDirty) \ + HANDLE_QT3DS_RENDER_VEC3_RADIAN_PROPERTY(Node, Rotation, TransformDirty) \ + HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Position, TransformDirty) \ + HANDLE_QT3DS_RENDER_VEC3_PROPERTY(Node, Position, TransformDirty) \ + HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Scale, TransformDirty) \ + HANDLE_QT3DS_RENDER_VEC3_PROPERTY(Node, Scale, TransformDirty) \ + HANDLE_QT3DS_RENDER_TRANSFORM_VEC3_PROPERTY(Node, Pivot, TransformDirty) \ + HANDLE_QT3DS_RENDER_VEC3_PROPERTY(Node, Pivot, TransformDirty) \ + HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(Node, LocalOpacity, TransformDirty) \ + HANDLE_QT3DS_ROTATION_ORDER_PROPERTY(Node, RotationOrder, TransformDirty) \ + HANDLE_QT3DS_NODE_ORIENTATION_PROPERTY(Node, LeftHanded, TransformDirty) + +#define ITERATE_QT3DS_RENDER_LAYER_PROPERTIES \ + HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(Layer, LayerEnableDepthTest, Dirty) \ + HANDLE_QT3DS_NODE_FLAGS_INVERSE_PROPERTY(Layer, LayerEnableDepthPrePass, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, ProgressiveAAMode, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, MultisampleAAMode, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, TemporalAAEnabled, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Layer, ClearColor, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, BlendType, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, Background, Dirty) \ + HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Layer, TexturePath, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, HorizontalFieldValues, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Left, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, LeftUnits, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Width, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, WidthUnits, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Right, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, RightUnits, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, VerticalFieldValues, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Top, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, TopUnits, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Height, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, HeightUnits, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Bottom, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, BottomUnits, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoStrength, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoDistance, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoSoftness, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoBias, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, AoDither, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowStrength, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowDist, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowSoftness, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ShadowBias, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, LightProbe, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ProbeBright, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, FastIbl, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ProbeHorizon, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, ProbeFov, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, LightProbe2, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Probe2Fade, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Probe2Window, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Layer, Probe2Pos, Dirty) + +#define ITERATE_QT3DS_RENDER_CAMERA_PROPERTIES \ + HANDLE_QT3DS_RENDER_PROPERTY(Camera, ClipNear, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Camera, ClipFar, Dirty) \ + HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(Camera, FOV, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Camera, FOVHorizontal, Dirty) \ + HANDLE_QT3DS_NODE_FLAGS_PROPERTY(Camera, Orthographic, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Camera, ScaleMode, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Camera, ScaleAnchor, Dirty) + +#define ITERATE_QT3DS_RENDER_LIGHT_PROPERTIES \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Light, LightType, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, Scope, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Light, DiffuseColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Light, DiffuseColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Light, SpecularColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Light, SpecularColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Light, AmbientColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Light, AmbientColor, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, Brightness, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, LinearFade, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, ExponentialFade, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, AreaWidth, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, AreaHeight, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, CastShadow, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowBias, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowFactor, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowMapFar, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowMapFov, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Light, ShadowFilter, Dirty) + +#define ITERATE_QT3DS_RENDER_MODEL_PROPERTIES \ + HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Model, MeshPath, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Model, ShadowCaster, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Model, TessellationMode, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Model, EdgeTess, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Model, InnerTess, Dirty) + +#define ITERATE_QT3DS_RENDER_CUSTOM_MATERIAL_PROPERTIES \ + HANDLE_QT3DS_RENDER_PROPERTY(MaterialBase, IblProbe, Dirty) + +#define ITERATE_QT3DS_RENDER_LIGHTMAP_PROPERTIES \ + HANDLE_QT3DS_RENDER_PROPERTY(Lightmaps, LightmapIndirect, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Lightmaps, LightmapRadiosity, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Lightmaps, LightmapShadow, Dirty) + +#define ITERATE_QT3DS_RENDER_MATERIAL_PROPERTIES \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Material, Lighting, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Material, BlendMode, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, VertexColors, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(MaterialBase, IblProbe, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Material, DiffuseColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Material, DiffuseColor, Dirty) \ + HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(Material, DiffuseMaps, 0, Dirty) \ + HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(Material, DiffuseMaps, 1, Dirty) \ + HANDLE_QT3DS_RENDER_ARRAY_PROPERTY(Material, DiffuseMaps, 2, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, EmissivePower, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Material, EmissiveColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Material, EmissiveColor, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, EmissiveMap, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, EmissiveMap2, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularReflection, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularMap, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Material, SpecularModel, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Material, SpecularTint, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Material, SpecularTint, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, FresnelPower, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, IOR, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularAmount, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, SpecularRoughness, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, RoughnessMap, Dirty) \ + HANDLE_QT3DS_RENDER_OPACITY_PROPERTY(Material, Opacity, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, OpacityMap, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, BumpMap, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, BumpAmount, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, NormalMap, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, DisplacementMap, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, DisplaceAmount, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, TranslucencyMap, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, TranslucentFalloff, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, DiffuseLightWrap, Dirty) + +#define ITERATE_QT3DS_RENDER_REFERENCED_MATERIAL_PROPERTIES \ + HANDLE_QT3DS_RENDER_PROPERTY(Material, ReferencedMaterial, Dirty) + +#define ITERATE_QT3DS_RENDER_IMAGE_PROPERTIES \ + HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Image, ImagePath, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Image, OffscreenRendererId, Dirty) \ + HANDLE_QT3DS_RENDER_VEC2_PROPERTY(Image, Scale, TransformDirty) \ + HANDLE_QT3DS_RENDER_VEC2_PROPERTY(Image, Pivot, TransformDirty) \ + HANDLE_QT3DS_RENDER_RADIAN_PROPERTY(Image, Rotation, TransformDirty) \ + HANDLE_QT3DS_RENDER_VEC2_PROPERTY(Image, Position, TransformDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Image, MappingMode, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Image, HorizontalTilingMode, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Image, VerticalTilingMode, Dirty) + +#define ITERATE_QT3DS_RENDER_TEXT_PROPERTIES \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, Text, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, Font, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, FontSize, TextDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, HorizontalAlignment, TextDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, VerticalAlignment, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, Leading, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, Tracking, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadow, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowStrength, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowOffset, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowOffsetX, TextDirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, DropShadowOffsetY, TextDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, DropShadowHorizontalAlignment, TextDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, DropShadowVerticalAlignment, TextDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, WordWrap, TextDirty) \ + HANDLE_QT3DS_RENDER_REAL_VEC2_PROPERTY(Text, BoundingBox, TextDirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Text, Elide, TextDirty) \ + HANDLE_QT3DS_RENDER_COLOR_VEC3_PROPERTY(Text, TextColor, Dirty) \ + HANDLE_QT3DS_RENDER_COLOR_PROPERTY(Text, TextColor, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Text, EnableAcceleratedFont, Dirty) + +#define ITERATE_QT3DS_RENDER_PATH_PROPERTIES \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, PathType, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, Width, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, LinearError, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, EdgeTessAmount, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, InnerTessAmount, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, BeginCapping, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, BeginCapOffset, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, BeginCapOpacity, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, BeginCapWidth, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, EndCapping, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, EndCapOffset, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, EndCapOpacity, Dirty) \ + HANDLE_QT3DS_RENDER_PROPERTY(Path, EndCapWidth, Dirty) \ + HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Path, PaintStyle, Dirty) \ + HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Path, PathBuffer, Dirty) + +#define ITERATE_QT3DS_RENDER_PATH_SUBPATH_PROPERTIES \ + HANDLE_QT3DS_RENDER_PROPERTY(SubPath, Closed, Dirty) +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.cpp new file mode 100644 index 00000000..311b2189 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.cpp @@ -0,0 +1,319 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderWidgets.h" +#include "Qt3DSRenderNode.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds::render; + +namespace { + +struct SWidgetBBox : public IRenderWidget +{ + NVBounds3 m_Bounds; + QT3DSVec3 m_Color; + NVRenderVertexBuffer *m_BoxVertexBuffer; + NVRenderIndexBuffer *m_BoxIndexBuffer; + NVRenderInputAssembler *m_BoxInputAssembler; + NVRenderShaderProgram *m_BoxShader; + CRegisteredString m_ItemName; + SWidgetBBox(SNode &inNode, const NVBounds3 &inBounds, const QT3DSVec3 &inColor) + : IRenderWidget(inNode) + , m_Bounds(inBounds) + , m_Color(inColor) + , m_BoxVertexBuffer(NULL) + , m_BoxIndexBuffer(NULL) + , m_BoxInputAssembler(NULL) + , m_BoxShader(NULL) + { + } + + void SetupBoxShader(IRenderWidgetContext &inContext) + { + m_BoxShader = inContext.GetShader(m_ItemName); + if (!m_BoxShader) { + qt3ds::render::IShaderProgramGenerator &theGenerator(inContext.GetProgramGenerator()); + theGenerator.BeginProgram(); + qt3ds::render::IShaderStageGenerator &theVertexGenerator( + *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Vertex)); + qt3ds::render::IShaderStageGenerator &theFragmentGenerator( + *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Fragment)); + + theVertexGenerator.AddIncoming("attr_pos", "vec3"); + theVertexGenerator.AddUniform("model_view_projection", "mat4"); + theVertexGenerator.Append("void main() {"); + theVertexGenerator.Append( + "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + theVertexGenerator.Append("}"); + theFragmentGenerator.AddUniform("output_color", "vec3"); + theFragmentGenerator.Append("void main() {"); + theFragmentGenerator.Append("\tgl_FragColor.rgb = output_color;"); + theFragmentGenerator.Append("\tgl_FragColor.a = 1.0;"); + theFragmentGenerator.Append("}"); + m_BoxShader = inContext.CompileAndStoreShader(m_ItemName); + } + } + + void SetupBoundingBoxGraphicsObjects(IRenderWidgetContext &inContext, + NVDataRef thePoints) + { + qt3ds::render::NVRenderVertexBufferEntry theEntry( + "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3); + m_BoxVertexBuffer = &inContext.GetOrCreateVertexBuffer( + m_ItemName, 3 * sizeof(QT3DSF32), toU8DataRef(thePoints.begin(), thePoints.size())); + m_BoxIndexBuffer = inContext.GetIndexBuffer(m_ItemName); + if (!m_BoxIndexBuffer) { + // The way the bounds lays out the bounds for the box + // capitalization indicates whether this was a max or min value. + enum _Indexes { + xyz = 0, + Xyz, + xYz, + xyZ, + XYZ, + xYZ, + XyZ, + XYz, + }; + QT3DSU8 indexes[] = { + // The toBoxBounds function lays out points such that + // xyz, Xyz, xYz, xyZ, XYZ, xYZ, XyZ, XYz + // Min corner + xyz, Xyz, xyz, xYz, xyz, xyZ, + + // Max corner + XYZ, xYZ, XYZ, XyZ, XYZ, XYz, + + // Now connect the rest of the dots. + // the rules are that only one letter can change + // else you are connecting *across* the box somehow. + + Xyz, XYz, Xyz, XyZ, + + xYz, XYz, xYz, xYZ, + + xyZ, XyZ, xyZ, xYZ, + }; + m_BoxIndexBuffer = &inContext.GetOrCreateIndexBuffer( + m_ItemName, qt3ds::render::NVRenderComponentTypes::QT3DSU8, sizeof(indexes), + toU8DataRef(indexes, sizeof(indexes))); + } + + m_BoxInputAssembler = inContext.GetInputAssembler(m_ItemName); + if (!m_BoxInputAssembler && m_BoxIndexBuffer && m_BoxVertexBuffer) { + // create our attribute layout + NVRenderAttribLayout *theAttribLAyout = + &inContext.CreateAttributeLayout(toConstDataRef(&theEntry, 1)); + + QT3DSU32 strides = m_BoxVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_BoxInputAssembler = &inContext.GetOrCreateInputAssembler( + m_ItemName, theAttribLAyout, toConstDataRef(&m_BoxVertexBuffer, 1), + m_BoxIndexBuffer, toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + SetupBoxShader(inContext); + } + + void Render(IRenderWidgetContext &inWidgetContext, NVRenderContext &inRenderContext) override + { + m_ItemName = inRenderContext.GetStringTable().RegisterStr("SWidgetBBox"); + SWidgetRenderInformation theInfo(inWidgetContext.GetWidgetRenderInformation( + *m_Node, m_Node->m_Position, RenderWidgetModes::Local)); + TNVBounds2BoxPoints thePoints; + m_Bounds.expand(thePoints); + QT3DSMat44 theNodeRotation; + QT3DSMat44 theNodeToCamera = theInfo.m_NodeParentToCamera * m_Node->m_LocalTransform; + for (QT3DSU32 idx = 0; idx < 8; ++idx) + thePoints[idx] = theNodeToCamera.transform(thePoints[idx]); + SetupBoundingBoxGraphicsObjects(inWidgetContext, toDataRef(thePoints, 8)); + if (m_BoxShader && m_BoxInputAssembler) { + inRenderContext.SetBlendingEnabled(false); + inRenderContext.SetDepthWriteEnabled(true); + inRenderContext.SetDepthTestEnabled(true); + inRenderContext.SetCullingEnabled(false); + inRenderContext.SetActiveShader(m_BoxShader); + m_BoxShader->SetPropertyValue("model_view_projection", theInfo.m_LayerProjection); + m_BoxShader->SetPropertyValue("output_color", m_Color); + inRenderContext.SetInputAssembler(m_BoxInputAssembler); + inRenderContext.Draw(qt3ds::render::NVRenderDrawMode::Lines, + m_BoxInputAssembler->GetIndexCount(), 0); + } + } +}; + +struct SWidgetAxis : public IRenderWidget +{ + NVRenderVertexBuffer *m_AxisVertexBuffer; + NVRenderInputAssembler *m_AxisInputAssembler; + NVRenderShaderProgram *m_AxisShader; + CRegisteredString m_ItemName; + + SWidgetAxis(SNode &inNode) + : IRenderWidget(inNode) + , m_AxisVertexBuffer(NULL) + , m_AxisInputAssembler(NULL) + , m_AxisShader(NULL) + { + } + + void SetupAxisShader(IRenderWidgetContext &inContext) + { + m_AxisShader = inContext.GetShader(m_ItemName); + if (!m_AxisShader) { + qt3ds::render::IShaderProgramGenerator &theGenerator(inContext.GetProgramGenerator()); + theGenerator.BeginProgram(); + qt3ds::render::IShaderStageGenerator &theVertexGenerator( + *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Vertex)); + qt3ds::render::IShaderStageGenerator &theFragmentGenerator( + *theGenerator.GetStage(qt3ds::render::ShaderGeneratorStages::Fragment)); + theVertexGenerator.AddIncoming("attr_pos", "vec3"); + theVertexGenerator.AddIncoming("attr_color", "vec3"); + theVertexGenerator.AddOutgoing("output_color", "vec3"); + theVertexGenerator.AddUniform("model_view_projection", "mat4"); + theVertexGenerator.Append("void main() {"); + theVertexGenerator.Append( + "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + theVertexGenerator.Append("\toutput_color = attr_color;"); + theVertexGenerator.Append("}"); + theFragmentGenerator.Append("void main() {"); + theFragmentGenerator.Append("\tgl_FragColor.rgb = output_color;"); + theFragmentGenerator.Append("\tgl_FragColor.a = 1.0;"); + theFragmentGenerator.Append("}"); + m_AxisShader = inContext.CompileAndStoreShader(m_ItemName); + } + } + + void SetupAxesGraphicsObjects(IRenderWidgetContext &inContext, NVDataRef theAxes) + { + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + qt3ds::render::NVRenderVertexBufferEntry("attr_color", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3, 12), + }; + + m_AxisVertexBuffer = &inContext.GetOrCreateVertexBuffer( + m_ItemName, 6 * sizeof(QT3DSF32), toU8DataRef(theAxes.begin(), theAxes.size())); + m_AxisInputAssembler = inContext.GetInputAssembler(m_ItemName); + if (!m_AxisInputAssembler && m_AxisVertexBuffer) { + // create our attribute layout + NVRenderAttribLayout *theAttribLAyout = + &inContext.CreateAttributeLayout(toConstDataRef(theEntries, 2)); + + QT3DSU32 strides = m_AxisVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_AxisInputAssembler = &inContext.GetOrCreateInputAssembler( + m_ItemName, theAttribLAyout, toConstDataRef(&m_AxisVertexBuffer, 1), nullptr, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + } + + inline QT3DSVec3 TransformDirection(const QT3DSMat33 &inMatrix, const QT3DSVec3 &inDir) + { + QT3DSVec3 retval = inMatrix.transform(inDir); + return retval; + } + + void Render(IRenderWidgetContext &inWidgetContext, NVRenderContext &inRenderContext) override + { + m_ItemName = inRenderContext.GetStringTable().RegisterStr("SWidgetAxis"); + + SetupAxisShader(inWidgetContext); + + if (m_AxisShader) { + static const QT3DSVec3 pivotCol = QT3DSVec3(0, 0, 1); + if (m_Node->m_Parent && m_Node->m_Parent->m_Type != GraphObjectTypes::Layer) { + m_Node->m_Parent->CalculateGlobalVariables(); + } + QT3DSVec3 thePivot(m_Node->m_Pivot); + if (m_Node->m_Flags.IsLeftHanded()) + thePivot.z *= -1; + + SWidgetRenderInformation theInfo(inWidgetContext.GetWidgetRenderInformation( + *m_Node, QT3DSVec3(0, 0, 0), RenderWidgetModes::Local)); + + QT3DSMat44 theNodeRotation; + m_Node->CalculateRotationMatrix(theNodeRotation); + if (m_Node->m_Flags.IsLeftHanded()) + SNode::FlipCoordinateSystem(theNodeRotation); + + QT3DSMat33 theRotationMatrix(theNodeRotation.column0.getXYZ(), + theNodeRotation.column1.getXYZ(), + theNodeRotation.column2.getXYZ()); + + // Move the camera position into camera space. This is so that when we render we don't + // have to account + // for scaling done in the camera's MVP. + QT3DSVec3 theItemPosition = theInfo.m_Position; + + QT3DSMat33 theAxisTransform = theInfo.m_NormalMatrix * theRotationMatrix; + + // Scale the effective pivot line end point according to node scale + // so that pivot line always hits object center. + thePivot = thePivot.multiply(m_Node->m_Scale); + QT3DSVec3 pivotVec = TransformDirection( + theAxisTransform, QT3DSVec3(-thePivot.x, -thePivot.y, -thePivot.z)); + + QT3DSVec3 thePivotLine[] = { + theItemPosition, pivotCol, theItemPosition + pivotVec, pivotCol + }; + + SetupAxesGraphicsObjects(inWidgetContext, toDataRef(thePivotLine, 4)); + + if (m_AxisInputAssembler) { + inRenderContext.SetBlendingEnabled(false); + inRenderContext.SetDepthWriteEnabled(false); + inRenderContext.SetDepthTestEnabled(false); + inRenderContext.SetCullingEnabled(false); + inRenderContext.SetActiveShader(m_AxisShader); + m_AxisShader->SetPropertyValue("model_view_projection", theInfo.m_LayerProjection); + inRenderContext.SetInputAssembler(m_AxisInputAssembler); + // Draw line from pivot to object center. + inRenderContext.Draw(qt3ds::render::NVRenderDrawMode::Lines, 2, 0); + } + } + } +}; +} + +IRenderWidget &IRenderWidget::CreateBoundingBoxWidget(SNode &inNode, const NVBounds3 &inBounds, + const QT3DSVec3 &inColor, + NVAllocatorCallback &inAlloc) +{ + return *QT3DS_NEW(inAlloc, SWidgetBBox)(inNode, inBounds, inColor); +} + +IRenderWidget &IRenderWidget::CreateAxisWidget(SNode &inNode, NVAllocatorCallback &inAlloc) +{ + return *QT3DS_NEW(inAlloc, SWidgetAxis)(inNode); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.h b/src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.h new file mode 100644 index 00000000..28cb3322 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderWidgets.h @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_WIDGETS_H +#define QT3DS_RENDER_WIDGETS_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSMat44.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DSBounds3.h" +#include "foundation/Qt3DSVec3.h" +#include "EASTL/utility.h" +#include "foundation/Qt3DSDataRef.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "Qt3DSRenderText.h" + +namespace qt3ds { +namespace render { + + struct SWidgetRenderInformation + { + // Just the rotation component of the nodeparenttocamera. + QT3DSMat33 m_NormalMatrix; + // The node parent's global transform multiplied by the inverse camera global transfrom; + // basically the MV from model-view-projection + QT3DSMat44 m_NodeParentToCamera; + // Projection that accounts for layer scaling + QT3DSMat44 m_LayerProjection; + // Pure camera projection without layer scaling + QT3DSMat44 m_PureProjection; + // A look at matrix that will rotate objects facing directly up + // the Z axis such that the point to the camera. + QT3DSMat33 m_LookAtMatrix; + // Conversion from world to camera position so world points not in object + // local space can be converted to camera space without going through the node's + // inverse global transform + QT3DSMat44 m_CameraGlobalInverse; + // Offset to add to the node's world position in camera space to move to the ideal camera + // location so that scale will work. This offset should be added *after* translation into + // camera space + QT3DSVec3 m_WorldPosOffset; + // Position in camera space to center the widget around + QT3DSVec3 m_Position; + // Scale factor to scale the widget by. + QT3DSF32 m_Scale; + + // The camera used to render this object. + SCamera *m_Camera; + SWidgetRenderInformation(const QT3DSMat33 &inNormal, const QT3DSMat44 &inNodeParentToCamera, + const QT3DSMat44 &inLayerProjection, const QT3DSMat44 &inProjection, + const QT3DSMat33 &inLookAt, const QT3DSMat44 &inCameraGlobalInverse, + const QT3DSVec3 &inWorldPosOffset, const QT3DSVec3 &inPos, QT3DSF32 inScale, + SCamera &inCamera) + : m_NormalMatrix(inNormal) + , m_NodeParentToCamera(inNodeParentToCamera) + , m_LayerProjection(inLayerProjection) + , m_PureProjection(inProjection) + , m_LookAtMatrix(inLookAt) + , m_CameraGlobalInverse(inCameraGlobalInverse) + , m_WorldPosOffset(inWorldPosOffset) + , m_Position(inPos) + , m_Scale(inScale) + , m_Camera(&inCamera) + { + } + SWidgetRenderInformation() + : m_Camera(NULL) + { + } + }; + typedef eastl::pair + TShaderGeneratorPair; + + struct RenderWidgetModes + { + enum Enum { + Local, + Global, + }; + }; + // Context used to get render data for the widget. + class IRenderWidgetContext + { + protected: + virtual ~IRenderWidgetContext() {} + public: + virtual NVRenderVertexBuffer & + GetOrCreateVertexBuffer(CRegisteredString &inStr, QT3DSU32 stride, + NVConstDataRef bufferData = NVConstDataRef()) = 0; + virtual NVRenderIndexBuffer & + GetOrCreateIndexBuffer(CRegisteredString &inStr, + qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef bufferData = NVConstDataRef()) = 0; + virtual NVRenderAttribLayout & + CreateAttributeLayout(NVConstDataRef attribs) = 0; + virtual NVRenderInputAssembler & + GetOrCreateInputAssembler(CRegisteredString &inStr, NVRenderAttribLayout *attribLayout, + NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets) = 0; + + virtual NVRenderVertexBuffer *GetVertexBuffer(CRegisteredString &inStr) = 0; + virtual NVRenderIndexBuffer *GetIndexBuffer(CRegisteredString &inStr) = 0; + virtual NVRenderInputAssembler *GetInputAssembler(CRegisteredString &inStr) = 0; + + virtual NVRenderShaderProgram *GetShader(CRegisteredString inStr) = 0; + virtual IShaderProgramGenerator &GetProgramGenerator() = 0; + // calls compile on the program generator and stores result under this name. + virtual NVRenderShaderProgram *CompileAndStoreShader(CRegisteredString inStr) = 0; + virtual STextDimensions MeasureText(const STextRenderInfo &inText) = 0; + // Render text using a specific MVP + virtual void RenderText(const STextRenderInfo &inText, const QT3DSVec3 &inTextColor, + const QT3DSVec3 &inBackgroundColor, const QT3DSMat44 &inMVP) = 0; + // Given a node and a point in the node's local space (most likely its pivot point), we + // return + // a normal matrix so you can get the axis out, a transformation from node to camera + // a new position and a floating point scale factor so you can render in 1/2 perspective + // mode + // or orthographic mode if you would like to. + virtual SWidgetRenderInformation + GetWidgetRenderInformation(SNode &inNode, const QT3DSVec3 &inPos, + RenderWidgetModes::Enum inWidgetMode) = 0; + }; + + class IRenderWidget + { + protected: + virtual ~IRenderWidget() {} + SNode *m_Node; + + public: + IRenderWidget(SNode &inNode) + : m_Node(&inNode) + { + } + IRenderWidget() + : m_Node(NULL) + { + } + virtual void Render(IRenderWidgetContext &inWidgetContext, + NVRenderContext &inRenderContext) = 0; + SNode &GetNode() { return *m_Node; } + + // Pure widgets. + static IRenderWidget &CreateBoundingBoxWidget(SNode &inNode, const NVBounds3 &inBounds, + const QT3DSVec3 &inColor, + NVAllocatorCallback &inAlloc); + static IRenderWidget &CreateAxisWidget(SNode &inNode, NVAllocatorCallback &inAlloc); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderableImage.h b/src/Runtime/Source/runtimerender/Qt3DSRenderableImage.h new file mode 100644 index 00000000..5d4aa1c4 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderableImage.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDERABLE_IMAGE_H +#define QT3DS_RENDERABLE_IMAGE_H +#include "Qt3DSRender.h" + +namespace qt3ds { +namespace render { + + struct ImageMapTypes + { + enum Enum { + Unknown = 0, + Diffuse = 1, + Opacity = 2, + Specular = 3, + Emissive = 4, + Bump = 5, + SpecularAmountMap = 6, + Normal = 7, + Displacement = 8, + Translucency = 9, + LightmapIndirect = 10, + LightmapRadiosity = 11, + LightmapShadow = 12, + Roughness = 13, + }; + }; + + /** + * Some precomputed information on a given image. When generating a renderable, the shader + * generator goes through all the possible images on a material and for each valid image + * computes this renderable image and attaches it to the renderable. + */ + struct SRenderableImage + { + ImageMapTypes::Enum m_MapType; + SImage &m_Image; + SRenderableImage *m_NextImage; + SRenderableImage(ImageMapTypes::Enum inMapType, SImage &inImage) + : m_MapType(inMapType) + , m_Image(inImage) + , m_NextImage(NULL) + { + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderer.h b/src/Runtime/Source/runtimerender/Qt3DSRenderer.h new file mode 100644 index 00000000..360ebf48 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderer.h @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDERER_H +#define QT3DS_RENDERER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSFlags.h" +#include "EASTL/algorithm.h" //pair +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSVec2.h" +#include "Qt3DSRenderGraphObjectPickQuery.h" +#include "Qt3DSRenderCamera.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "Qt3DSRenderRay.h" + +namespace qt3ds { +namespace render { + + class IRenderableObject; + struct SModel; + struct SText; + struct SCamera; + struct SLight; + struct SLayer; + class IBufferManager; + typedef void *SRenderInstanceId; + + using qt3ds::foundation::NVConstDataRef; + + class IQt3DSRenderNodeFilter + { + protected: + virtual ~IQt3DSRenderNodeFilter() {} + public: + virtual bool IncludeNode(const SNode &inNode) = 0; + }; + struct SLayerPickSetup + { + QT3DSMat44 m_ProjectionPreMultiply; + QT3DSMat44 m_ViewProjection; + NVRenderRect m_ScissorRect; + SLayerPickSetup(const QT3DSMat44 &inProjPreMult, const QT3DSMat44 &inVP, + const NVRenderRect &inScissor) + : m_ProjectionPreMultiply(inProjPreMult) + , m_ViewProjection(inVP) + , m_ScissorRect(inScissor) + { + } + SLayerPickSetup() {} + }; + + struct SScaleAndPosition + { + QT3DSVec3 m_Position; + QT3DSF32 m_Scale; + SScaleAndPosition(const QT3DSVec3 &inPos, QT3DSF32 inScale) + : m_Position(inPos) + , m_Scale(inScale) + { + } + SScaleAndPosition() {} + }; + + class IQt3DSRenderer : public NVRefCounted + { + protected: + virtual ~IQt3DSRenderer() {} + + public: + virtual void EnableLayerCaching(bool inEnabled) = 0; + virtual bool IsLayerCachingEnabled() const = 0; + virtual void EnableLayerGpuProfiling(bool inEnabled) = 0; + virtual bool IsLayerGpuProfilingEnabled() const = 0; + + // Get the camera that rendered this node last render + virtual SCamera *GetCameraForNode(const SNode &inNode) const = 0; + virtual Option GetCameraBounds(const SGraphObject &inObject) = 0; + // Called when you have changed the number or order of children of a given node. + virtual void ChildrenUpdated(SNode &inParent) = 0; + virtual QT3DSF32 GetTextScale(const SText &inText) = 0; + + // The IQt3DSRenderContext calls these, clients should not. + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; + + // Setup the vertex and index buffers (but not shader state) + // and render the quad. The quad is setup so that its edges + // go from -1,1 in x,y and its UV coordinates will map naturally + // to an image. + virtual void RenderQuad() = 0; + + // Render a given texture to the scene using a given transform. + virtual void RenderQuad(const QT3DSVec2 inDimensions, const QT3DSMat44 &inMVP, + NVRenderTexture2D &inQuadTexture) = 0; + + // This point rendering works uisng indirect array drawing + // This means you need to setup a GPU buffer + // which contains the drawing information + virtual void RenderPointsIndirect() = 0; + + // Returns true if this layer or a sibling was dirty. + virtual bool PrepareLayerForRender(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + bool inRenderSiblings = true, + const SRenderInstanceId id = nullptr) = 0; + virtual void RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, bool clear, + QT3DSVec3 clearColor, bool inRenderSiblings = true, + const SRenderInstanceId id = nullptr) = 0; + + // Studio option to disable picking against sub renderers. This allows better interaction + // in studio. + // In pick siblings measn pick the layer siblings; this is the normal behavior. + // InPickEverything means ignore the node's pick flags; this allows us to only pick things + // that have handlers + // in some cases and just pick everything in other things. + virtual void PickRenderPlugins(bool inPick) = 0; + virtual Qt3DSRenderPickResult Pick(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, bool inPickSiblings = true, + bool inPickEverything = false, + const SRenderInstanceId id = nullptr) = 0; + + // Return the relative hit position, in UV space, of a mouse pick against this object. + // We need the node in order to figure out which layer rendered this object. + // We need mapper objects if this is a in a subpresentation because we have to know how + // to map the mouse coordinates into the subpresentation. So for instance if inNode is in + // a subpres then we need to know which image is displaying the subpres in order to map + // the mouse coordinates into the subpres's render space. + virtual Option FacePosition(SNode &inNode, NVBounds3 inBounds, + const QT3DSMat44 &inGlobalTransform, + const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, + NVDataRef inMapperObjects, + SBasisPlanes::Enum inIsectPlane) = 0; + + virtual QT3DSVec3 UnprojectToPosition(SNode &inNode, QT3DSVec3 &inPosition, + const QT3DSVec2 &inMouseVec) const = 0; + virtual QT3DSVec3 UnprojectWithDepth(SNode &inNode, QT3DSVec3 &inPosition, + const QT3DSVec3 &inMouseVec) const = 0; + virtual QT3DSVec3 ProjectPosition(SNode &inNode, const QT3DSVec3 &inPosition) const = 0; + + // Roughly equivalent of gluPickMatrix, allows users to setup a perspective transform that + // will draw some sub component + // of the layer. Used in combination with an expected viewport of 0,0,width,height the + // viewproj matrix returned will center + // around the center of the viewport and render just the part of the layer around this area. + // The return value is optional because if the mouse point is completely outside the layer + // obviously this method is irrelevant. + virtual Option GetLayerPickSetup(SLayer &inLayer, + const QT3DSVec2 &inMouseCoords, + const QSize &inPickDims) = 0; + + // Return the layer's viewport rect after the layer's member variables have been applied. + // Uses the last rendered viewport rect. + virtual Option GetLayerRect(SLayer &inLayer) = 0; + // Testing function to allow clients to render a layer using a custom view project instead + // of the one that would be setup + // using the layer's camera in conjunction with the layer's position,scale. + virtual void RunLayerRender(SLayer &inLayer, const QT3DSMat44 &inViewProjection) = 0; + + // This allocator is cleared every frame on BeginFrame. Objects constructed using this + // allocator + // Must not need their destructors called. Objects are allocate on 4 byte boundaries using + // this allocator + // regardless + virtual NVAllocatorCallback &GetPerFrameAllocator() = 0; + + // Render the layer's rect onscreen. Will only render one frame, you need to call this + // every frame + // for this to work and be persistent. + virtual void RenderLayerRect(SLayer &inLayer, const QT3DSVec3 &inColor) = 0; + // Render widgets are things that are draw on the layer's widget texture which is then + // rendered to the + // scene's widget texture. You must add them every frame you wish them to be rendered; the + // list of + // widgets is cleared every frame. + virtual void AddRenderWidget(IRenderWidget &inWidget) = 0; + + // Get a scale factor so you can have objects precisely 50 pixels. Note that this scale + // factor + // only applies to things drawn parallel to the camera plane; If you aren't parallel then + // there isn't + // a single scale factor that will work. + // For perspective-rendered objects, we shift the object forward or backwards along the + // vector from the camera + // to the object so that we are working in a consistent mathematical space. So if the + // camera is orthographic, + // you are done. + // If the camera is perspective, then this method will tell you want you need to scale + // things by to account for + // the FOV and also where the origin of the object needs to be to ensure the scale factor is + // relevant. + virtual SScaleAndPosition GetWorldToPixelScaleFactor(SLayer &inLayer, + const QT3DSVec3 &inWorldPoint) = 0; + // Called before a layer goes completely out of scope to release any rendering resources + // related to the layer. + virtual void ReleaseLayerRenderResources(SLayer &inLayer, const SRenderInstanceId id) = 0; + + // render a screen aligned 2D text + virtual void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, + const char *text) = 0; + // render Gpu profiler values + virtual void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, + qt3ds::foundation::Option inColor) = 0; + + // Get the mouse coordinates as they relate to a given layer + virtual Option GetLayerMouseCoords(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool forceImageIntersect = false) const = 0; + + virtual IRenderWidgetContext &GetRenderWidgetContext() = 0; + + static bool IsGlEsContext(qt3ds::render::NVRenderContextType inContextType); + static bool IsGlEs3Context(qt3ds::render::NVRenderContextType inContextType); + static bool IsGl2Context(qt3ds::render::NVRenderContextType inContextType); + static const char *GetGlslVesionString(qt3ds::render::NVRenderContextType inContextType); + + static IQt3DSRenderer &CreateRenderer(IQt3DSRenderContext &inContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRendererUtil.cpp b/src/Runtime/Source/runtimerender/Qt3DSRendererUtil.cpp new file mode 100644 index 00000000..7bc108e0 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRendererUtil.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRendererUtil.h" +#include "Qt3DSRenderResourceBufferObjects.h" +#include "Qt3DSRenderResourceTexture2D.h" + +using namespace qt3ds::render; + +void CRendererUtil::ResolveMutisampleFBOColorOnly(IResourceManager &inManager, + CResourceTexture2D &ioResult, + NVRenderContext &inRenderContext, QT3DSU32 inWidth, + QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inColorFormat, + NVRenderFrameBuffer &inSourceFBO) +{ + // create resolve FBO + CResourceFrameBuffer theResolveFB(inManager); + // Allocates the frame buffer which has the side effect of setting the current render target to + // that frame buffer. + theResolveFB.EnsureFrameBuffer(); + // set copy flags + qt3ds::render::NVRenderClearFlags copyFlags(NVRenderClearValues::Color); + + // get / create resolve targets and attach + ioResult.EnsureTexture(inWidth, inHeight, inColorFormat); + theResolveFB->Attach(NVRenderFrameBufferAttachments::Color0, *ioResult); + // CN - I don't believe we have to resolve the depth. + // The reason is we render the depth texture specially unresolved. So there is no need to + // resolve + // the depth prepass texture to anything else. + + // 1. Make resolve buffer be the render target ( already happend ) + // 2. Make the current layer FBO the current read target + // 3. Do the blit from MSAA to non MSAA + + // 2. + inRenderContext.SetReadTarget(&inSourceFBO); + inRenderContext.SetReadBuffer(NVReadFaces::Color0); + // 3. + inRenderContext.BlitFramebuffer(0, 0, inWidth, inHeight, 0, 0, inWidth, inHeight, copyFlags, + NVRenderTextureMagnifyingOp::Nearest); +} + +void CRendererUtil::ResolveSSAAFBOColorOnly(IResourceManager &inManager, + CResourceTexture2D &ioResult, QT3DSU32 outWidth, + QT3DSU32 outHeight, NVRenderContext &inRenderContext, + QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inColorFormat, + NVRenderFrameBuffer &inSourceFBO) +{ + // create resolve FBO + CResourceFrameBuffer theResolveFB(inManager); + // Allocates the frame buffer which has the side effect of setting the current render target to + // that frame buffer. + theResolveFB.EnsureFrameBuffer(); + // set copy flags + qt3ds::render::NVRenderClearFlags copyFlags(NVRenderClearValues::Color); + + // get / create resolve targets and attach + ioResult.EnsureTexture(outWidth, outHeight, inColorFormat); + theResolveFB->Attach(NVRenderFrameBufferAttachments::Color0, *ioResult); + // CN - I don't believe we have to resolve the depth. + // The reason is we render the depth texture specially unresolved. So there is no need to + // resolve + // the depth prepass texture to anything else. + + // 1. Make resolve buffer be the render target ( already happend ) + // 2. Make the current layer FBO the current read target + // 3. Do the blit from High res to low res buffer + + // 2. + inRenderContext.SetReadTarget(&inSourceFBO); + inRenderContext.SetReadBuffer(NVReadFaces::Color0); + // 3. + inRenderContext.BlitFramebuffer(0, 0, inWidth, inHeight, 0, 0, outWidth, outHeight, copyFlags, + NVRenderTextureMagnifyingOp::Linear); +} + +void CRendererUtil::GetSSAARenderSize(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 &outWidth, + QT3DSU32 &outHeight) +{ + // we currently double width and height + outWidth = inWidth * 2; + outHeight = inHeight * 2; + + // keep aspect ration? + // clamp to max + if (outWidth > MAX_SSAA_DIM) + outWidth = MAX_SSAA_DIM; + if (outHeight > MAX_SSAA_DIM) + outHeight = MAX_SSAA_DIM; +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSRendererUtil.h b/src/Runtime/Source/runtimerender/Qt3DSRendererUtil.h new file mode 100644 index 00000000..96f36426 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSRendererUtil.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDERER_UTIL_H +#define QT3DS_RENDERER_UTIL_H +#include "Qt3DSRender.h" +#include "render/Qt3DSRenderBaseTypes.h" +namespace qt3ds { +namespace render { + class CRendererUtil + { + static const QT3DSU32 MAX_SSAA_DIM = 8192; // max render traget size for SSAA mode + + public: + static void ResolveMutisampleFBOColorOnly(IResourceManager &inManager, + CResourceTexture2D &ioResult, + NVRenderContext &inRenderContext, QT3DSU32 inWidth, + QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inColorFormat, + NVRenderFrameBuffer &inSourceFBO); + + static void ResolveSSAAFBOColorOnly(IResourceManager &inManager, + CResourceTexture2D &ioResult, QT3DSU32 outWidth, + QT3DSU32 outHeight, NVRenderContext &inRenderContext, + QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inColorFormat, + NVRenderFrameBuffer &inSourceFBO); + + static void GetSSAARenderSize(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 &outWidth, + QT3DSU32 &outHeight); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/Qt3DSTextRenderer.cpp b/src/Runtime/Source/runtimerender/Qt3DSTextRenderer.cpp new file mode 100644 index 00000000..91a5eb78 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSTextRenderer.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSTextRenderer.h" +#include "render/Qt3DSRenderTexture2D.h" + +using namespace qt3ds::render; + +// http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html +QT3DSU32 ITextRenderer::NextPowerOf2(QT3DSU32 input) +{ + // Algorithm doesn't work for 0 or QT3DS_MAX_U32 + QT3DS_ASSERT(input > 0 && input < QT3DS_MAX_U32); + input--; + input = (input >> 1) | input; + input = (input >> 2) | input; + input = (input >> 4) | input; + input = (input >> 8) | input; + input = (input >> 16) | input; + input++; // input is now the next highest power of 2. + return input; +} + +QT3DSU32 ITextRenderer::NextMultipleOf4(QT3DSU32 inValue) +{ + QT3DSU32 remainder(inValue % 4); + if (remainder != 0) + inValue = inValue + (4 - remainder); + + return inValue; +} + +STextTextureDetails ITextRenderer::UploadData(NVDataRef inTextureData, + NVRenderTexture2D &inTexture, QT3DSU32 inDataWidth, + QT3DSU32 inDataHeight, QT3DSU32 inTextWidth, + QT3DSU32 inTextHeight, + NVRenderTextureFormats::Enum inFormat, + bool inFlipYAxis) +{ + if (inTextWidth == 0 || inTextHeight == 0) { + QT3DSU32 black[] = { 0, 0, 0, 0 }; + inTexture.SetTextureData(toU8DataRef(black, 4), 0, 2, 2, NVRenderTextureFormats::RGBA8); + return STextTextureDetails(2, 2, false, QT3DSVec2(1.0)); + } + QT3DS_ASSERT(NextMultipleOf4(inDataWidth) == inDataWidth); + QT3DSU32 theNecessaryHeight = NextMultipleOf4(inTextHeight); + QT3DSU32 dataStride = inDataWidth * NVRenderTextureFormats::getSizeofFormat(inFormat); + if (inTextureData.size() < dataStride * inDataHeight) { + QT3DS_ASSERT(false); + return STextTextureDetails(); + } + + STextureDetails theTextureDetails = inTexture.GetTextureDetails(); + QT3DSU32 theUploadSize = theNecessaryHeight * dataStride; + + NVDataRef theUploadData = NVDataRef(inTextureData.begin(), theUploadSize); + inTexture.SetTextureData(theUploadData, 0, inDataWidth, theNecessaryHeight, inFormat); + inTexture.SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear); + inTexture.SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear); + return STextTextureDetails(inTextWidth, inTextHeight, inFlipYAxis, QT3DSVec2(1.0f, 1.0f)); +} diff --git a/src/Runtime/Source/runtimerender/Qt3DSTextRenderer.h b/src/Runtime/Source/runtimerender/Qt3DSTextRenderer.h new file mode 100644 index 00000000..756c3a90 --- /dev/null +++ b/src/Runtime/Source/runtimerender/Qt3DSTextRenderer.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_TEXT_RENDERER_H +#define QT3DS_TEXT_RENDERER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderTextTypes.h" + +namespace qt3ds { +namespace render { + + struct SRendererFontEntry + { + CRegisteredString m_FontName; + CRegisteredString m_FontFile; + SRendererFontEntry() {} + SRendererFontEntry(CRegisteredString nm, CRegisteredString file) + : m_FontName(nm) + , m_FontFile(file) + { + } + }; + + class ITextRendererCore : public NVRefCounted + { + public: + // You can have several standard font directories and these will be persistent + virtual void AddSystemFontDirectory(const char8_t *inDirectory) = 0; + // Should be called to clear the current context. + virtual void AddProjectFontDirectory(const char8_t *inProjectDirectory) = 0; + virtual void ClearProjectFontDirectories() = 0; + // Force font loading *right now* + virtual void PreloadFonts() = 0; + // Do not access object in between begin/end preload pairs. + virtual void BeginPreloadFonts(IThreadPool &inThreadPool, IPerfTimer &inTimer) = 0; + virtual void EndPreloadFonts() = 0; + // Force a clear and reload of all of the fonts. + virtual void ReloadFonts() = 0; + // Get the list of project fonts. These are the only fonts that can be displayed. + virtual NVConstDataRef GetProjectFontList() = 0; + // The name stored in the ttf file isn't the actual name we use; we use the file stems. + // But we used to use the name. So this provides a sort of first-come-first-serve remapping + // from ttf-name to file-stem. + virtual Option GetFontNameForFont(CRegisteredString inFontname) = 0; + virtual Option GetFontNameForFont(const char8_t *inFontname) = 0; + + virtual ITextRenderer &GetTextRenderer(NVRenderContext &inContext) = 0; + + static ITextRendererCore &CreateQtTextRenderer(NVFoundationBase &inFoundation, + IStringTable &inStrTable); + + // call this to create onscreen text renderer + // it needs true type fonts + static ITextRendererCore &CreateOnscreenTextRenderer(NVFoundationBase &inFoundation); + }; + /** + * Opaque text rendering system. Must be able to render text to an opengl texture object. + */ + class ITextRenderer : public ITextRendererCore + { + protected: + virtual ~ITextRenderer() {} + + public: + // Measure text will inText if it isn't null or the text on the info if inText is null + virtual STextDimensions MeasureText(const STextRenderInfo &inText, QT3DSF32 inTextScaleFactor, + const char8_t *inTextOverride = NULL) = 0; + // The system will use the 'r' channel as an alpha mask in order to render the + // text. You can assume GetTextDimensions was called *just* prior to this. + // It is a good idea to ensure the texture is a power of two as not all rendering systems + // support nonpot textures. Our text rendering algorithms will render a sub-rect of the + // image + // assuming it is located toward the upper-left of the image and we are also capable of + // flipping + // the image. + virtual STextTextureDetails RenderText(const STextRenderInfo &inText, + NVRenderTexture2D &inTexture) = 0; + // this is for rendering text with NV path rendering + virtual STextTextureDetails + RenderText(const STextRenderInfo &inText, NVRenderPathFontItem &inPathFontItem, + NVRenderPathFontSpecification &inPathFontSpecicification) = 0; + // this is for rednering text using a texture atlas + virtual SRenderTextureAtlasDetails RenderText(const STextRenderInfo &inText) = 0; + + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; + + // these two function are for texture atlas usage only + // returns the atlas entries count + virtual QT3DSI32 CreateTextureAtlas() = 0; + virtual STextTextureAtlasEntryDetails RenderAtlasEntry(QT3DSU32 index, + NVRenderTexture2D &inTexture) = 0; + + // Helper function to upload the texture data to the texture + // Will resize texture as necessary and upload using texSubImage for + // quickest upload times + // This function expects that the dataWidth to be divisible by four and + // that the total data height is larger then inTextHeight *and* divisible by four. + // and that textWidth and textHeight are less than or equal to dataWidth,dataHeight + //,can be zero, and don't need to be divisible by four (or 2). + static STextTextureDetails + UploadData(NVDataRef inTextureData, NVRenderTexture2D &inTexture, QT3DSU32 inDataWidth, + QT3DSU32 inDataHeight, QT3DSU32 inTextWidth, QT3DSU32 inTextHeight, + NVRenderTextureFormats::Enum inFormat, bool inFlipYAxis); + + // Helper function to return the next power of two. + // Fails for values of 0 or QT3DS_MAX_U32 + static QT3DSU32 NextPowerOf2(QT3DSU32 inValue); + // If inValue is divisible by four, then return inValue + // else next largest number that is divisible by four. + static QT3DSU32 NextMultipleOf4(QT3DSU32 inValue); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/android/DynamicLibLoader.h b/src/Runtime/Source/runtimerender/android/DynamicLibLoader.h new file mode 100644 index 00000000..c968419a --- /dev/null +++ b/src/Runtime/Source/runtimerender/android/DynamicLibLoader.h @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "linux/DynamicLibLoader.h" diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.cpp new file mode 100644 index 00000000..062a36c5 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.cpp @@ -0,0 +1,486 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderPresentation.h" +#include "foundation/Qt3DSVec2.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSTextRenderer.h" + +#include + +using namespace qt3ds::render; + +namespace { + +QT3DSF32 GetAspectRatio(const NVRenderRectF &inViewport) +{ + return inViewport.m_Height != 0 ? inViewport.m_Width / inViewport.m_Height : 0.0f; +} + +QT3DSF32 GetAspectRatio(const QT3DSVec2 &inDimensions) +{ + return inDimensions.y != 0 ? inDimensions.x / inDimensions.y : 0.0f; +} + +bool IsCameraVerticalAdjust(CameraScaleModes::Enum inMode, QT3DSF32 inDesignAspect, + QT3DSF32 inActualAspect) +{ + return (inMode == CameraScaleModes::Fit && inActualAspect >= inDesignAspect) + || inMode == CameraScaleModes::FitVertical; +} + +bool IsCameraHorizontalAdjust(CameraScaleModes::Enum inMode, QT3DSF32 inDesignAspect, + QT3DSF32 inActualAspect) +{ + return (inMode == CameraScaleModes::Fit && inActualAspect < inDesignAspect) + || inMode == CameraScaleModes::FitHorizontal; +} + +bool IsFitTypeScaleMode(CameraScaleModes::Enum inMode) +{ + return inMode == CameraScaleModes::Fit || inMode == CameraScaleModes::FitHorizontal + || inMode == CameraScaleModes::FitVertical; +} + +struct SPinCameraResult +{ + NVRenderRectF m_Viewport; + NVRenderRectF m_VirtualViewport; + SPinCameraResult(NVRenderRectF v, NVRenderRectF vv) + : m_Viewport(v) + , m_VirtualViewport(vv) + { + } +}; +// Scale and transform the projection matrix to respect the camera anchor attribute +// and the scale mode. +SPinCameraResult PinCamera(const NVRenderRectF &inViewport, QT3DSVec2 inDesignDims, + QT3DSMat44 &ioPerspectiveMatrix, CameraScaleModes::Enum inScaleMode, + CameraScaleAnchors::Enum inPinLocation) +{ + NVRenderRectF viewport(inViewport); + NVRenderRectF idealViewport(inViewport.m_X, inViewport.m_Y, inDesignDims.x, inDesignDims.y); + QT3DSF32 designAspect = GetAspectRatio(inDesignDims); + QT3DSF32 actualAspect = GetAspectRatio(inViewport); + if (IsFitTypeScaleMode(inScaleMode)) { + idealViewport.m_Width = viewport.m_Width; + idealViewport.m_Height = viewport.m_Height; + } + // We move the viewport such that the left, top of the presentation sits against the left top + // edge + // We only need to translate in X *if* our actual aspect > design aspect + // And then we only need to account for whatever centering would happen. + + bool pinLeft = inPinLocation == CameraScaleAnchors::SouthWest + || inPinLocation == CameraScaleAnchors::West + || inPinLocation == CameraScaleAnchors::NorthWest; + bool pinRight = inPinLocation == CameraScaleAnchors::SouthEast + || inPinLocation == CameraScaleAnchors::East + || inPinLocation == CameraScaleAnchors::NorthEast; + bool pinTop = inPinLocation == CameraScaleAnchors::NorthWest + || inPinLocation == CameraScaleAnchors::North + || inPinLocation == CameraScaleAnchors::NorthEast; + bool pinBottom = inPinLocation == CameraScaleAnchors::SouthWest + || inPinLocation == CameraScaleAnchors::South + || inPinLocation == CameraScaleAnchors::SouthEast; + + if (inScaleMode == CameraScaleModes::SameSize) { + // In this case the perspective transform does not center the view, + // it places it in the lower-left of the viewport. + QT3DSF32 idealWidth = inDesignDims.x; + QT3DSF32 idealHeight = inDesignDims.y; + if (pinRight) + idealViewport.m_X -= ((idealWidth - inViewport.m_Width)); + else if (!pinLeft) + idealViewport.m_X -= ((idealWidth - inViewport.m_Width) / 2.0f); + + if (pinTop) + idealViewport.m_Y -= ((idealHeight - inViewport.m_Height)); + else if (!pinBottom) + idealViewport.m_Y -= ((idealHeight - inViewport.m_Height) / 2.0f); + } else { + // In this case our perspective matrix will center the view and we need to decenter + // it as necessary + // if we are wider than we are high + if (IsCameraVerticalAdjust(inScaleMode, designAspect, actualAspect)) { + if (pinLeft || pinRight) { + QT3DSF32 idealWidth = inViewport.m_Height * designAspect; + QT3DSI32 halfOffset = (QT3DSI32)((idealWidth - inViewport.m_Width) / 2.0f); + halfOffset = pinLeft ? halfOffset : -1 * halfOffset; + idealViewport.m_X += halfOffset; + } + } else { + if (pinTop || pinBottom) { + QT3DSF32 idealHeight = inViewport.m_Width / designAspect; + QT3DSI32 halfOffset = (QT3DSI32)((idealHeight - inViewport.m_Height) / 2.0f); + halfOffset = pinBottom ? halfOffset : -1 * halfOffset; + idealViewport.m_Y += halfOffset; + } + } + } + + ioPerspectiveMatrix = NVRenderContext::ApplyVirtualViewportToProjectionMatrix( + ioPerspectiveMatrix, viewport, idealViewport); + return SPinCameraResult(viewport, idealViewport); +} +} + +SCamera::SCamera() + : SNode(GraphObjectTypes::Camera) + , m_ClipNear(10) + , m_ClipFar(10000) + , m_FOV(60) + , m_FOVHorizontal(false) + , m_ScaleMode(CameraScaleModes::Fit) + , m_ScaleAnchor(CameraScaleAnchors::Center) +{ + TORAD(m_FOV); + m_Projection = QT3DSMat44::createIdentity(); + m_Position = QT3DSVec3(0, 0, -600); +} + +// Code for testing +SCameraGlobalCalculationResult SCamera::CalculateGlobalVariables(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) +{ + bool wasDirty = SNode::CalculateGlobalVariables(); + return SCameraGlobalCalculationResult(wasDirty, + CalculateProjection(inViewport, inDesignDimensions)); +} + +bool SCamera::CalculateProjection(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions) +{ + bool retval = false; + if (m_Flags.IsOrthographic()) + retval = ComputeFrustumOrtho(inViewport, inDesignDimensions); + else + retval = ComputeFrustumPerspective(inViewport, inDesignDimensions); + if (retval) { + QT3DSF32 *writePtr(m_Projection.front()); + m_FrustumScale.x = writePtr[0]; + m_FrustumScale.y = writePtr[5]; + PinCamera(inViewport, inDesignDimensions, m_Projection, m_ScaleMode, m_ScaleAnchor); + } + return retval; +} + +//============================================================================== +/** + * Compute the projection matrix for a perspective camera + * @return true if the computed projection matrix is valid + */ +bool SCamera::ComputeFrustumPerspective(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) +{ + m_Projection = QT3DSMat44::createIdentity(); + QT3DSF32 theAngleInRadians = verticalFov(inViewport) / 2.0f; + QT3DSF32 theDeltaZ = m_ClipFar - m_ClipNear; + QT3DSF32 theSine = sinf(theAngleInRadians); + QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); + QT3DSF32 theAspectRatio = designAspect; + if (IsFitTypeScaleMode(m_ScaleMode)) + theAspectRatio = GetAspectRatio(inViewport); + + if ((theDeltaZ != 0) && (theSine != 0) && (theAspectRatio != 0)) { + QT3DSF32 *writePtr(m_Projection.front()); + writePtr[10] = -(m_ClipFar + m_ClipNear) / theDeltaZ; + writePtr[11] = -1; + writePtr[14] = -2 * m_ClipNear * m_ClipFar / theDeltaZ; + writePtr[15] = 0; + + if (IsCameraVerticalAdjust(m_ScaleMode, designAspect, theAspectRatio)) { + QT3DSF32 theCotangent = cosf(theAngleInRadians) / theSine; + writePtr[0] = theCotangent / theAspectRatio; + writePtr[5] = theCotangent; + } else { + QT3DSF32 theCotangent = cosf(theAngleInRadians) / theSine; + writePtr[0] = theCotangent / designAspect; + writePtr[5] = theCotangent * (theAspectRatio / designAspect); + } + return true; + } else { + QT3DS_ASSERT(false); + return false; + } +} + +//============================================================================== +/** + * Compute the projection matrix for a orthographic camera + * @return true if the computed projection matrix is valid + */ +bool SCamera::ComputeFrustumOrtho(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions) +{ + m_Projection = QT3DSMat44::createIdentity(); + + QT3DSF32 theDeltaZ = m_ClipFar - m_ClipNear; + QT3DSF32 halfWidth = inDesignDimensions.x / 2.0f; + QT3DSF32 halfHeight = inDesignDimensions.y / 2.0f; + QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); + QT3DSF32 theAspectRatio = designAspect; + if (IsFitTypeScaleMode(m_ScaleMode)) + theAspectRatio = GetAspectRatio(inViewport); + if (theDeltaZ != 0) { + QT3DSF32 *writePtr(m_Projection.front()); + writePtr[10] = -2.0f / theDeltaZ; + writePtr[11] = 0.0f; + writePtr[14] = -(m_ClipNear + m_ClipFar) / theDeltaZ; + writePtr[15] = 1.0f; + if (IsCameraVerticalAdjust(m_ScaleMode, designAspect, theAspectRatio)) { + writePtr[0] = 1.0f / (halfHeight * theAspectRatio); + writePtr[5] = 1.0f / halfHeight; + } else { + writePtr[0] = 1.0f / halfWidth; + writePtr[5] = 1.0f / (halfWidth / theAspectRatio); + } + return true; + } else { + QT3DS_ASSERT(false); + return false; + } +} + +QT3DSF32 SCamera::GetOrthographicScaleFactor(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const +{ + if (m_ScaleMode == CameraScaleModes::SameSize) + return 1.0f; + QT3DSMat44 temp(QT3DSMat44::createIdentity()); + QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); + QT3DSF32 theAspectRatio = GetAspectRatio(inViewport); + if (m_ScaleMode == CameraScaleModes::Fit) { + if (theAspectRatio >= designAspect) { + return inViewport.m_Width < inDesignDimensions.x ? theAspectRatio / designAspect : 1.0f; + + } else { + return inViewport.m_Height < inDesignDimensions.y ? designAspect / theAspectRatio + : 1.0f; + } + } else if (m_ScaleMode == CameraScaleModes::FitVertical) { + return (QT3DSF32)inDesignDimensions.y / (QT3DSF32)inViewport.m_Height; + } else { + return (QT3DSF32)inDesignDimensions.x / (QT3DSF32)inViewport.m_Width; + } +} + +QT3DSF32 SCamera::GetTextScaleFactor(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const +{ + return NVMax(1.0f, 1.0f / GetOrthographicScaleFactor(inViewport, inDesignDimensions)); +} + +QT3DSMat33 SCamera::GetLookAtMatrix(const QT3DSVec3 &inUpDir, const QT3DSVec3 &inDirection) const +{ + QT3DSVec3 theDirection(inDirection); + + theDirection.normalize(); + + const QT3DSVec3 &theUpDir(inUpDir); + + // gram-shmidt orthogonalization + QT3DSVec3 theCrossDir(theDirection.cross(theUpDir)); + theCrossDir.normalize(); + QT3DSVec3 theFinalDir(theCrossDir.cross(theDirection)); + theFinalDir.normalize(); + QT3DSF32 multiplier = 1.0f; + if (m_Flags.IsLeftHanded()) + multiplier = -1.0f; + + QT3DSMat33 theResultMatrix(theCrossDir, theFinalDir, multiplier * theDirection); + return theResultMatrix; +} + +void SCamera::LookAt(const QT3DSVec3 &inCameraPos, const QT3DSVec3 &inUpDir, const QT3DSVec3 &inTargetPos) +{ + QT3DSVec3 theDirection = inTargetPos - inCameraPos; + if (m_Flags.IsLeftHanded()) + theDirection.z *= -1.0f; + m_Rotation = GetRotationVectorFromRotationMatrix(GetLookAtMatrix(inUpDir, theDirection)); + m_Position = inCameraPos; + MarkDirty(qt3ds::render::NodeTransformDirtyFlag::TransformIsDirty); +} + +void SCamera::CalculateViewProjectionMatrix(QT3DSMat44 &outMatrix) const +{ + QT3DSMat44 globalInverse = m_GlobalTransform.getInverse(); + outMatrix = m_Projection * globalInverse; +} + +SCuboidRect SCamera::GetCameraBounds(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const +{ + QT3DSMat44 unused(QT3DSMat44::createIdentity()); + SPinCameraResult theResult = + PinCamera(inViewport, inDesignDimensions, unused, m_ScaleMode, m_ScaleAnchor); + // find the normalized edges of the view frustum given the renormalization that happens when + // pinning the camera. + SCuboidRect normalizedCuboid(-1, 1, 1, -1); + QT3DSVec2 translation(theResult.m_Viewport.m_X - theResult.m_VirtualViewport.m_X, + theResult.m_Viewport.m_Y - theResult.m_VirtualViewport.m_Y); + if (m_ScaleMode == CameraScaleModes::SameSize) { + // the cuboid ranges are the actual divided by the ideal in this case + QT3DSF32 xRange = 2.0f * (theResult.m_Viewport.m_Width / theResult.m_VirtualViewport.m_Width); + QT3DSF32 yRange = + 2.0f * (theResult.m_Viewport.m_Height / theResult.m_VirtualViewport.m_Height); + normalizedCuboid = SCuboidRect(-1, -1 + yRange, -1 + xRange, -1); + translation.x /= (theResult.m_VirtualViewport.m_Width / 2.0f); + translation.y /= (theResult.m_VirtualViewport.m_Height / 2.0f); + normalizedCuboid.Translate(translation); + } + // fit. This means that two parameters of the normalized cuboid will be -1, 1. + else { + // In this case our perspective matrix will center the view and we need to decenter + // it as necessary + QT3DSF32 actualAspect = GetAspectRatio(inViewport); + QT3DSF32 designAspect = GetAspectRatio(inDesignDimensions); + // if we are wider than we are high + QT3DSF32 idealWidth = inViewport.m_Width; + QT3DSF32 idealHeight = inViewport.m_Height; + + if (IsCameraVerticalAdjust(m_ScaleMode, designAspect, actualAspect)) { + // then we just need to setup the left, right parameters of the cuboid because we know + // the top + // bottom are -1,1 due to how fit works. + idealWidth = (QT3DSF32)ITextRenderer::NextMultipleOf4( + (QT3DSU32)(inViewport.m_Height * designAspect + .5f)); + // halfRange should always be greater than 1.0f. + QT3DSF32 halfRange = inViewport.m_Width / idealWidth; + normalizedCuboid.m_Left = -halfRange; + normalizedCuboid.m_Right = halfRange; + translation.x = translation.x / (idealWidth / 2.0f); + } else { + idealHeight = (QT3DSF32)ITextRenderer::NextMultipleOf4( + (QT3DSU32)(inViewport.m_Width / designAspect + .5f)); + QT3DSF32 halfRange = inViewport.m_Height / idealHeight; + normalizedCuboid.m_Bottom = -halfRange; + normalizedCuboid.m_Top = halfRange; + translation.y = translation.y / (idealHeight / 2.0f); + } + normalizedCuboid.Translate(translation); + } + // Given no adjustment in the virtual rect, then this is what we would have. + + return normalizedCuboid; +} + +void SCamera::SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, + QT3DSMat44 &outVP) +{ + STextureDetails theDetails(inTexture.GetTextureDetails()); + SCamera theTempCamera; + SetupOrthographicCameraForOffscreenRender(inTexture, outVP, theTempCamera); +} + +void SCamera::SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, + QT3DSMat44 &outVP, SCamera &outCamera) +{ + STextureDetails theDetails(inTexture.GetTextureDetails()); + SCamera theTempCamera; + theTempCamera.m_Flags.SetOrthographic(true); + theTempCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + QT3DSVec2 theDimensions((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); + theTempCamera.CalculateGlobalVariables( + NVRenderRect(0, 0, theDetails.m_Width, theDetails.m_Height), theDimensions); + theTempCamera.CalculateViewProjectionMatrix(outVP); + outCamera = theTempCamera; +} + +SRay SCamera::Unproject(const QT3DSVec2 &inViewportRelativeCoords, const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const +{ + SRay theRay; + QT3DSMat44 tempVal(QT3DSMat44::createIdentity()); + SPinCameraResult result = + PinCamera(inViewport, inDesignDimensions, tempVal, m_ScaleMode, m_ScaleAnchor); + QT3DSVec2 globalCoords = inViewport.ToAbsoluteCoords(inViewportRelativeCoords); + QT3DSVec2 normalizedCoords = + result.m_VirtualViewport.AbsoluteToNormalizedCoordinates(globalCoords); + QT3DSVec3 &outOrigin(theRay.m_Origin); + QT3DSVec3 &outDir(theRay.m_Direction); + QT3DSVec2 inverseFrustumScale(1.0f / m_FrustumScale.x, 1.0f / m_FrustumScale.y); + QT3DSVec2 scaledCoords(inverseFrustumScale.x * normalizedCoords.x, + inverseFrustumScale.y * normalizedCoords.y); + + if (m_Flags.IsOrthographic()) { + outOrigin.x = scaledCoords.x; + outOrigin.y = scaledCoords.y; + outOrigin.z = 0.0f; + + outDir.x = 0.0f; + outDir.y = 0.0f; + outDir.z = -1.0f; + } else { + outOrigin.x = 0.0f; + outOrigin.y = 0.0f; + outOrigin.z = 0.0f; + + outDir.x = scaledCoords.x; + outDir.y = scaledCoords.y; + outDir.z = -1.0f; + } + + outOrigin = m_GlobalTransform.transform(outOrigin); + QT3DSMat33 theNormalMatrix; + CalculateNormalMatrix(theNormalMatrix); + + outDir = theNormalMatrix.transform(outDir); + outDir.normalize(); + /* + char printBuf[2000]; + sprintf_s( printBuf, "normCoords %f %f outDir %f %f %f\n" + , normalizedCoords.x, normalizedCoords.y, outDir.x, outDir.y, outDir.z ); + OutputDebugStringA( printBuf ); + */ + + return theRay; +} + +QT3DSVec3 SCamera::UnprojectToPosition(const QT3DSVec3 &inGlobalPos, const SRay &inRay) const +{ + QT3DSVec3 theCameraDir = GetDirection(); + QT3DSVec3 theObjGlobalPos = inGlobalPos; + QT3DSF32 theDistance = -1.0f * theObjGlobalPos.dot(theCameraDir); + NVPlane theCameraPlane(theCameraDir, theDistance); + return inRay.Intersect(theCameraPlane); +} + +QT3DSF32 SCamera::verticalFov(QT3DSF32 aspectRatio) const +{ + if (m_FOVHorizontal) + return 2.0f * qAtan(qTan(qreal(m_FOV) / 2.0) / qreal(aspectRatio)); + else + return m_FOV; +} + +QT3DSF32 SCamera::verticalFov(const NVRenderRectF &inViewport) const +{ + return verticalFov(GetAspectRatio(inViewport)); +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.h new file mode 100644 index 00000000..d6d8ce82 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCamera.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CAMERA_H +#define QT3DS_RENDER_CAMERA_H +#include "Qt3DSRenderNode.h" +#include "Qt3DSRenderRay.h" + +namespace qt3ds { +namespace render { + + struct SCameraGlobalCalculationResult + { + bool m_WasDirty; + bool m_ComputeFrustumSucceeded; + SCameraGlobalCalculationResult(bool inWasDirty, bool inComputeSucceeded = true) + : m_WasDirty(inWasDirty) + , m_ComputeFrustumSucceeded(inComputeSucceeded) + { + } + }; + + struct CameraScaleModes + { + enum Enum { + Fit = 0, + SameSize, + FitHorizontal, + FitVertical, + }; + }; + + struct CameraScaleAnchors + { + enum Enum { + Center = 0, + North, + NorthEast, + East, + SouthEast, + South, + SouthWest, + West, + NorthWest, + }; + }; + + struct SCuboidRect + { + QT3DSF32 m_Left; + QT3DSF32 m_Top; + QT3DSF32 m_Right; + QT3DSF32 m_Bottom; + SCuboidRect(QT3DSF32 l = 0.0f, QT3DSF32 t = 0.0f, QT3DSF32 r = 0.0f, QT3DSF32 b = 0.0f) + : m_Left(l) + , m_Top(t) + , m_Right(r) + , m_Bottom(b) + { + } + void Translate(QT3DSVec2 inTranslation) + { + m_Left += inTranslation.x; + m_Right += inTranslation.x; + m_Top += inTranslation.y; + m_Bottom += inTranslation.y; + } + }; + + struct SCamera : public SNode + { + + // Setting these variables should set dirty on the camera. + QT3DSF32 m_ClipNear; + QT3DSF32 m_ClipFar; + + QT3DSF32 m_FOV; // Radians + bool m_FOVHorizontal; + + QT3DSMat44 m_Projection; + CameraScaleModes::Enum m_ScaleMode; + CameraScaleAnchors::Enum m_ScaleAnchor; + // Record some values from creating the projection matrix + // to use during mouse picking. + QT3DSVec2 m_FrustumScale; + + SCamera(); + + QT3DSMat33 GetLookAtMatrix(const QT3DSVec3 &inUpDir, const QT3DSVec3 &inDirection) const; + // Set our position, rotation member variables based on the lookat target + // Marks this object as dirty. + // Need to test this when the camera's local transform is null. + // Assumes parent's local transform is the identity, meaning our local transform is + // our global transform. + void LookAt(const QT3DSVec3 &inCameraPos, const QT3DSVec3 &inUpDir, const QT3DSVec3 &inTargetPos); + + SCameraGlobalCalculationResult CalculateGlobalVariables(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions); + bool CalculateProjection(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions); + bool ComputeFrustumOrtho(const NVRenderRectF &inViewport, const QT3DSVec2 &inDesignDimensions); + // Used when rendering the widgets in studio. This scales the widget when in orthographic + // mode in order to have + // constant size on screen regardless. + // Number is always greater than one + QT3DSF32 GetOrthographicScaleFactor(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const; + bool ComputeFrustumPerspective(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions); + // Text may be scaled so that it doesn't appear pixellated when the camera itself is doing + // the scaling. + QT3DSF32 GetTextScaleFactor(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const; + + void CalculateViewProjectionMatrix(QT3DSMat44 &outMatrix) const; + + // If this is an orthographic camera, the cuboid properties are the distance from the center + // point + // to the left, top, right, and bottom edges of the view frustum in world units. + // If this is a perspective camera, the cuboid properties are the FOV angles + // (left,top,right,bottom) + // of the view frustum. + + // Return a normalized rect that describes the area the camera is rendering to. + // This takes into account the various camera properties (scale mode, scale anchor). + SCuboidRect GetCameraBounds(const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const; + + // Setup a camera VP projection for rendering offscreen. + static void SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, + QT3DSMat44 &outVP); + static void SetupOrthographicCameraForOffscreenRender(NVRenderTexture2D &inTexture, + QT3DSMat44 &outVP, SCamera &outCamera); + + // Unproject a point (x,y) in viewport relative coordinates meaning + // left, bottom is 0,0 and values are increasing right,up respectively. + SRay Unproject(const QT3DSVec2 &inLayerRelativeMouseCoords, const NVRenderRectF &inViewport, + const QT3DSVec2 &inDesignDimensions) const; + + // Unproject a given coordinate to a 3d position that lies on the same camera + // plane as inGlobalPos. + // Expects CalculateGlobalVariables has been called or doesn't need to be. + QT3DSVec3 UnprojectToPosition(const QT3DSVec3 &inGlobalPos, const SRay &inRay) const; + + QT3DSF32 verticalFov(QT3DSF32 aspectRatio) const; + QT3DSF32 verticalFov(const NVRenderRectF &inViewport) const; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCustomMaterial.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCustomMaterial.h new file mode 100644 index 00000000..593c7573 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderCustomMaterial.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CUSTOM_MATERIAL_H +#define QT3DS_RENDER_CUSTOM_MATERIAL_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderDynamicObject.h" +#include "Qt3DSRenderImage.h" +#include "Qt3DSRenderLightmaps.h" +#include "foundation/Qt3DSFlags.h" + +namespace qt3ds { +namespace render { + + // IMPORTANT: These flags matches the key produced by a MDL export file + struct SCustomMaterialShaderKeyValues + { + enum Enum { + diffuse = 1 << 0, + specular = 1 << 1, + glossy = 1 << 2, + cutout = 1 << 3, + refraction = 1 << 4, + transparent = 1 << 5, + displace = 1 << 6, + volumetric = 1 << 7, + transmissive = 1 << 8, + }; + }; + + typedef NVFlags SCustomMaterialShaderKeyFlags; + + struct SCustomMaterial : public SDynamicObject + { + private: + // These objects are only created via the dynamic object system. + SCustomMaterial(const SCustomMaterial &); + SCustomMaterial &operator=(const SCustomMaterial &); + SCustomMaterial(); + + public: + // lightmap section + SLightmaps m_Lightmaps; + // material section + bool m_hasTransparency; + bool m_hasRefraction; + bool m_hasVolumetricDF; + SImage *m_IblProbe; + SImage *m_EmissiveMap2; + SImage *m_DisplacementMap; + QT3DSF32 m_DisplaceAmount; ///< depends on the object size + + SGraphObject *m_NextSibling; + + SCustomMaterialShaderKeyFlags m_ShaderKeyValues; ///< input from MDL files + QT3DSU32 m_LayerCount; ///< input from MDL files + + void Initialize(QT3DSU32 inKey, QT3DSU32 inLayerCount) + { + m_Lightmaps.m_LightmapIndirect = NULL; + m_Lightmaps.m_LightmapRadiosity = NULL; + m_Lightmaps.m_LightmapShadow = NULL; + m_hasTransparency = false; + m_hasRefraction = false; + m_hasVolumetricDF = false; + m_NextSibling = NULL; + m_DirtyFlagWithInFrame = m_Flags.IsDirty(); + m_IblProbe = NULL; + m_EmissiveMap2 = NULL; + m_DisplacementMap = NULL; + m_DisplaceAmount = 0.0; + m_ShaderKeyValues = (SCustomMaterialShaderKeyFlags)inKey; + m_LayerCount = inLayerCount; + } + + bool IsDielectric() const + { + return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::diffuse; + } + bool IsSpecularEnabled() const + { + return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::specular; + } + bool IsCutOutEnabled() const + { + return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::cutout; + } + bool IsVolumetric() const + { + return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::volumetric; + } + bool IsTransmissive() const + { + return m_ShaderKeyValues & SCustomMaterialShaderKeyValues::transmissive; + } + bool HasLighting() const { return true; } + + template + void Remap(TRemapperType &inRemapper) + { + SDynamicObject::Remap(inRemapper); + m_Lightmaps.Remap(inRemapper); + inRemapper.Remap(m_IblProbe); + inRemapper.RemapMaterial(m_NextSibling); + inRemapper.Remap(m_EmissiveMap2); + inRemapper.Remap(m_DisplacementMap); + } + + // Dirty + bool m_DirtyFlagWithInFrame; + bool IsDirty() const { return m_Flags.IsDirty() || m_DirtyFlagWithInFrame; } + void UpdateDirtyForFrame() + { + m_DirtyFlagWithInFrame = m_Flags.IsDirty(); + m_Flags.SetDirty(false); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.cpp new file mode 100644 index 00000000..06f3649a --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderDefaultMaterial.h" + +using namespace qt3ds::render; + +SDefaultMaterial::SDefaultMaterial() + : SGraphObject(GraphObjectTypes::DefaultMaterial) + , m_IblProbe(NULL) + , m_Lighting(DefaultMaterialLighting::VertexLighting) + , m_BlendMode(DefaultMaterialBlendMode::Normal) + , m_DiffuseColor(1, 1, 1) + , m_EmissivePower(0) + , m_EmissiveMap(NULL) + , m_EmissiveMap2(NULL) + , m_EmissiveColor(1, 1, 1) + , m_SpecularReflection(NULL) + , m_SpecularMap(NULL) + , m_SpecularModel(DefaultMaterialSpecularModel::Default) + , m_SpecularTint(1, 1, 1) + , m_IOR(.2f) + , m_FresnelPower(0.0f) + , m_SpecularAmount(0) + , m_SpecularRoughness(50) + , m_RoughnessMap(NULL) + , m_Opacity(1) + , m_OpacityMap(NULL) + , m_BumpMap(NULL) + , m_BumpAmount(0.f) + , m_NormalMap(NULL) + , m_DisplacementMap(NULL) + , m_DisplaceAmount(0.f) + , m_TranslucencyMap(NULL) + , m_TranslucentFalloff(0.f) + , m_DiffuseLightWrap(0.f) + , m_VertexColors(false) + , m_NextSibling(NULL) + , m_Parent(NULL) +{ + m_Lightmaps.m_LightmapIndirect = NULL; + m_Lightmaps.m_LightmapRadiosity = NULL; + m_Lightmaps.m_LightmapShadow = NULL; + + m_DiffuseMaps[0] = NULL; + m_DiffuseMaps[2] = NULL; + m_DiffuseMaps[1] = NULL; +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.h new file mode 100644 index 00000000..09595236 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDefaultMaterial.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DEFAULT_MATERIAL_H +#define QT3DS_RENDER_DEFAULT_MATERIAL_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSVec3.h" +#include "Qt3DSRenderMaterialDirty.h" +#include "Qt3DSRenderLightmaps.h" + +namespace qt3ds { +namespace render { + struct DefaultMaterialLighting + { + enum Enum { + NoLighting = 0, + VertexLighting, + FragmentLighting + }; + }; + struct DefaultMaterialBlendMode + { + enum Enum { + Normal = 0, + Screen, + Multiply, + Overlay, + ColorBurn, + ColorDodge + }; + }; + + struct DefaultMaterialSpecularModel + { + enum Enum { + Default = 0, + KGGX, + KWard + }; + }; + + struct SImage; + + struct QT3DS_AUTOTEST_EXPORT SDefaultMaterial : SGraphObject + { + CMaterialDirty m_Dirty; + // lightmap section + SLightmaps m_Lightmaps; + // material section + SImage *m_IblProbe; + DefaultMaterialLighting::Enum m_Lighting; // defaults to vertex + DefaultMaterialBlendMode::Enum m_BlendMode; // defaults to normal + QT3DSVec3 m_DiffuseColor; // colors are 0-1 normalized + SImage *m_DiffuseMaps[3]; + QT3DSF32 m_EmissivePower; // 0-100, defaults to 0 + QT3DSVec3 m_EmissiveColor; + SImage *m_EmissiveMap; + SImage *m_EmissiveMap2; + SImage *m_SpecularReflection; + SImage *m_SpecularMap; + DefaultMaterialSpecularModel::Enum m_SpecularModel; + QT3DSVec3 m_SpecularTint; + QT3DSF32 m_IOR; + QT3DSF32 m_FresnelPower; + QT3DSF32 m_SpecularAmount; // 0-??, defaults to 0 + QT3DSF32 m_SpecularRoughness; // 0-??, defaults to 50 + SImage *m_RoughnessMap; + QT3DSF32 m_Opacity; // 0-1 + SImage *m_OpacityMap; + SImage *m_BumpMap; + QT3DSF32 m_BumpAmount; // 0-?? + SImage *m_NormalMap; + SImage *m_DisplacementMap; + QT3DSF32 m_DisplaceAmount; // 0-?? + SImage *m_TranslucencyMap; + QT3DSF32 m_TranslucentFalloff; // 0 - ?? + QT3DSF32 m_DiffuseLightWrap; // 0 - 1 + bool m_VertexColors; + // Materials are stored as a linked list on models. + SGraphObject *m_NextSibling; + SModel *m_Parent; + + SDefaultMaterial(); + + bool IsSpecularEnabled() const { return m_SpecularAmount > .01f; } + bool IsFresnelEnabled() const { return m_FresnelPower > 0.0f; } + bool IsVertexColorsEnabled() const { return m_VertexColors; } + bool HasLighting() const { return m_Lighting != DefaultMaterialLighting::NoLighting; } + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + m_Lightmaps.Remap(inRemapper); + inRemapper.Remap(m_IblProbe); + inRemapper.Remap(m_DiffuseMaps[0]); + inRemapper.Remap(m_DiffuseMaps[1]); + inRemapper.Remap(m_DiffuseMaps[2]); + inRemapper.Remap(m_EmissiveMap); + inRemapper.Remap(m_EmissiveMap2); + inRemapper.Remap(m_SpecularReflection); + inRemapper.Remap(m_SpecularMap); + inRemapper.Remap(m_RoughnessMap); + inRemapper.Remap(m_OpacityMap); + inRemapper.Remap(m_BumpMap); + inRemapper.Remap(m_NormalMap); + inRemapper.Remap(m_DisplacementMap); + inRemapper.Remap(m_TranslucencyMap); + inRemapper.RemapMaterial(m_NextSibling); + inRemapper.Remap(m_Parent); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp new file mode 100644 index 00000000..3d7c6ff5 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRender.h" +#include "Qt3DSRenderDynamicObject.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "foundation/FileTools.h" +#include "Qt3DSRenderString.h" + +#include + +using namespace qt3ds; +using namespace qt3ds::render; + +SDynamicObject::SDynamicObject(GraphObjectTypes::Enum inType, CRegisteredString inObjName, + QT3DSU32 inDSByteSize, QT3DSU32 thisObjSize) + : SGraphObject(inType) + , m_ClassName(inObjName) + , m_DataSectionByteSize(inDSByteSize) + , m_ThisObjectSize(thisObjSize) +{ +} + +template +void SDynamicObject::SetPropertyValueT(const dynamic::SPropertyDefinition &inDefinition, + const TDataType &inValue) +{ + if (sizeof(inValue) != inDefinition.m_ByteSize) { + QT3DS_ASSERT(false); + return; + } + memCopy(GetDataSectionBegin() + inDefinition.m_Offset, &inValue, sizeof(inValue)); +} + +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + bool inValue) +{ + SetPropertyValueT(inDefinition, inValue); +} + +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + QT3DSF32 inValue) +{ + SetPropertyValueT(inDefinition, inValue); +} +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + QT3DSF32 inValue, QT3DSU32 inOffset) +{ + if (sizeof(QT3DSF32) > (inDefinition.m_ByteSize - inOffset)) { + QT3DS_ASSERT(false); + return; + } + memCopy(GetDataSectionBegin() + inDefinition.m_Offset + inOffset, &inValue, sizeof(inValue)); +} +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const QT3DSVec2 &inValue) +{ + SetPropertyValueT(inDefinition, inValue); +} +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const QT3DSVec3 &inValue) +{ + SetPropertyValueT(inDefinition, inValue); +} +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const QT3DSVec4 &inValue) +{ + SetPropertyValueT(inDefinition, inValue); +} +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + QT3DSI32 inValue) +{ + SetPropertyValueT(inDefinition, inValue); +} +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + CRegisteredString inValue) +{ + QT3DS_ASSERT(inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr); + SetPropertyValueT(inDefinition, inValue); +} +template +void SDynamicObject::SetStrPropertyValueT(dynamic::SPropertyDefinition &inDefinition, + const char8_t *inValue, const char8_t *inProjectDir, + TStrType &ioWorkspace, IStringTable &inStrTable) +{ + if (inValue == NULL) + inValue = ""; + if (inDefinition.m_DataType == NVRenderShaderDataTypes::QT3DSI32) { + NVConstDataRef theEnumValues = inDefinition.m_EnumValueNames; + for (QT3DSI32 idx = 0, end = (QT3DSI32)theEnumValues.size(); idx < end; ++idx) { + if (strcmp(theEnumValues[idx].c_str(), inValue) == 0) { + SetPropertyValueT(inDefinition, idx); + break; + } + } + } else if (inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + if (inProjectDir == NULL) + inProjectDir = ""; + if (CFileTools::RequiresCombineBaseAndRelative(inValue)) { + QString absolute = QDir(inProjectDir).filePath(inValue); + ioWorkspace.assign(absolute.toLatin1().constData()); + SetPropertyValueT(inDefinition, inStrTable.RegisterStr(ioWorkspace.c_str())); + // We also adjust the image path in the definition + // I could not find a better place + inDefinition.m_ImagePath = inStrTable.RegisterStr(ioWorkspace.c_str()); + } else { + SetPropertyValueT(inDefinition, inStrTable.RegisterStr(inValue)); + } + } else if (inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderImage2DPtr) { + SetPropertyValueT(inDefinition, inStrTable.RegisterStr(inValue)); + } else if (inDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderDataBufferPtr) { + SetPropertyValueT(inDefinition, inStrTable.RegisterStr(inValue)); + } else { + QT3DS_ASSERT(false); + } +} + +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const char8_t *inValue, const char8_t *inProjectDir, + CRenderString &ioWorkspace, IStringTable &inStrTable) +{ + SetStrPropertyValueT(const_cast(inDefinition), inValue, + inProjectDir, ioWorkspace, inStrTable); +} + +void SDynamicObject::SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const char8_t *inValue, const char8_t *inProjectDir, + eastl::string &ioWorkspace, IStringTable &inStrTable) +{ + SetStrPropertyValueT(const_cast(inDefinition), inValue, + inProjectDir, ioWorkspace, inStrTable); +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.h new file mode 100644 index 00000000..a275e572 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderDynamicObject.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DYNAMIC_OBJECT_H +#define QT3DS_RENDER_DYNAMIC_OBJECT_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "Qt3DSRenderNode.h" +#include "EASTL/string.h" + +namespace qt3ds { +namespace render { + + namespace dynamic { + struct SPropertyDefinition; + } + + // Dynamic objects are objects that have variable number of properties during runtime. + struct SDynamicObject : public SGraphObject + { + CRegisteredString m_ClassName; + NodeFlags m_Flags; + QT3DSU32 m_DataSectionByteSize; + QT3DSU32 m_ThisObjectSize; + + SDynamicObject(GraphObjectTypes::Enum inType, CRegisteredString inClassName, + QT3DSU32 inDSByteSize, QT3DSU32 thisObjSize); + + QT3DSU8 *GetDataSectionBegin() + { + QT3DSU8 *thisObjectStart = reinterpret_cast(this); + QT3DSU8 *retval = thisObjectStart + m_ThisObjectSize; + QT3DS_ASSERT((reinterpret_cast(retval) % 4 == 0)); + return retval; + } + + const QT3DSU8 *GetDataSectionBegin() const + { + return const_cast(this)->GetDataSectionBegin(); + } + + QT3DSU8 *GetDataSectionEnd() { return GetDataSectionBegin() + m_DataSectionByteSize; } + + template + void SetPropertyValueT(const dynamic::SPropertyDefinition &inDefinition, + const TDataType &inType); + template + void SetStrPropertyValueT(dynamic::SPropertyDefinition &inDefinition, + const char8_t *inValue, const char8_t *inProjectDir, + TStrType &ioWorkspace, IStringTable &inStrTable); + + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, bool inValue); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, QT3DSF32 inValue); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, QT3DSF32 inValue, + QT3DSU32 inOffset); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const QT3DSVec2 &inValue); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const QT3DSVec3 &inValue); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const QT3DSVec4 &inValue); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, QT3DSI32 inValue); + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + CRegisteredString inValue); + + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const char8_t *inValue, const char8_t *inProjectDir, + CRenderString &ioWorkspace, IStringTable &inStrTable); + + void SetPropertyValue(const dynamic::SPropertyDefinition &inDefinition, + const char8_t *inValue, const char8_t *inProjectDir, + eastl::string &ioWorkspace, IStringTable &inStrTable); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_ClassName); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.cpp new file mode 100644 index 00000000..97cddd9d --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderEffect.h" +#include "Qt3DSRenderEffectSystem.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "Qt3DSRenderString.h" +#include "foundation/FileTools.h" + +using namespace qt3ds::render; + +void SEffect::Initialize() +{ + m_Layer = NULL; + m_NextEffect = NULL; + m_Context = NULL; +} + +void SEffect::SetActive(bool inActive, IEffectSystem &inManager) +{ + if (m_Flags.IsActive() != inActive) { + m_Flags.SetActive(inActive); + if (m_Context) + inManager.ResetEffectFrameData(*m_Context); + m_Flags.SetDirty(true); + } +} + +void SEffect::Reset(IEffectSystem &inSystem) +{ + if (m_Context) + inSystem.ResetEffectFrameData(*m_Context); + m_Flags.SetDirty(true); +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.h new file mode 100644 index 00000000..c11c214c --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderEffect.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EFFECT_H +#define QT3DS_RENDER_EFFECT_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "Qt3DSRenderNode.h" +#include "EASTL/string.h" +#include "Qt3DSRenderDynamicObject.h" + +namespace qt3ds { +namespace render { + struct SLayer; + struct SEffectContext; + + // Effects are post-render effect applied to the layer. There can be more than one of + // them and they have completely variable properties. + // see IEffectManager in order to create these effects. + // The data for the effect immediately follows the effect + struct SEffect : public SDynamicObject + { + private: + // These objects are only created via the dynamic object system. + SEffect(const SEffect &); + SEffect &operator=(const SEffect &); + SEffect(); + + public: + SLayer *m_Layer; + SEffect *m_NextEffect; + // Opaque pointer to context type implemented by the effect system. + // May be null in which case the effect system will generate a new context + // the first time it needs to render this effect. + SEffectContext *m_Context; + + void Initialize(); + + // If our active flag value changes, then we ask the effect manager + // to reset our context. + void SetActive(bool inActive, IEffectSystem &inSystem); + + void Reset(IEffectSystem &inSystem); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SDynamicObject::Remap(inRemapper); + inRemapper.Remap(m_Layer); + inRemapper.Remap(m_NextEffect); + inRemapper.NullPtr(m_Context); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderGraphObject.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderGraphObject.h new file mode 100644 index 00000000..58c48ed1 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderGraphObject.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GRAPH_OBJECT_H +#define QT3DS_RENDER_GRAPH_OBJECT_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderTaggedPointer.h" +#include "Qt3DSRenderGraphObjectTypes.h" + +namespace qt3ds { +namespace render { + + // Types should be setup on construction. Change the type + // at your own risk as the type is used for RTTI purposes. + struct QT3DS_AUTOTEST_EXPORT SGraphObject + { + // Id's help debugging the object and are optionally set + CRegisteredString m_Id; + // Type is used for RTTI purposes down the road. + GraphObjectTypes::Enum m_Type; + STaggedPointer m_UserData; + + SGraphObject(GraphObjectTypes::Enum inType) + : m_Type(inType) + { + } + SGraphObject(const SGraphObject &inCloningObject, NVAllocatorCallback & /*inAllocator*/) + : m_Id(inCloningObject.m_Id) + , m_Type(inCloningObject.m_Type) + { + } + + // If you change any detail of the scene graph, or even *breath* on a + // scene graph object, you need to bump this binary version so at least + // we know if we can load a file or not. + static QT3DSU32 GetSceneGraphBinaryVersion() { return 1; } + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + inRemapper.Remap(m_Id); + inRemapper.NullPtr(m_UserData.m_UserData); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp new file mode 100644 index 00000000..eaa98c77 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderImage.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSOffscreenRenderKey.h" +#include "Qt3DSRenderPlugin.h" +#include "Qt3DSRenderPluginGraphObject.h" + +using namespace qt3ds::render; + +SImage::SImage() + : SGraphObject(GraphObjectTypes::Image) + , m_RenderPlugin(NULL) + , m_LastFrameOffscreenRenderer(NULL) + , m_Parent(NULL) + , m_Scale(1, 1) + , m_Pivot(0, 0) + , m_Rotation(0) + , m_Position(0, 0) + , m_MappingMode(ImageMappingModes::Normal) + , m_HorizontalTilingMode(NVRenderTextureCoordOp::ClampToEdge) + , m_VerticalTilingMode(NVRenderTextureCoordOp::ClampToEdge) +{ + m_Flags.SetActive(true); + m_Flags.SetDirty(true); + m_Flags.SetTransformDirty(true); +} + +static void HandleOffscreenResult(SImage &theImage, SImageTextureData &newImage, + SOffscreenRenderResult &theResult, bool &replaceTexture, + bool &wasDirty) +{ + newImage.m_Texture = theResult.m_Texture; + newImage.m_TextureFlags.SetHasTransparency(theResult.m_HasTransparency); + newImage.m_TextureFlags.SetPreMultiplied(true); + wasDirty = wasDirty || theResult.m_HasChangedSinceLastFrame; + theImage.m_LastFrameOffscreenRenderer = theResult.m_Renderer; + replaceTexture = true; +} + +bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager &inRenderManager, + IRenderPluginManager &inPluginManager, bool forIbl) +{ + + bool wasDirty = m_Flags.IsDirty(); + m_Flags.SetDirty(false); + SImageTextureData newImage; + bool replaceTexture(false); + if (m_RenderPlugin && m_RenderPlugin->m_Flags.IsActive()) { + IRenderPluginInstance *theInstance = inPluginManager.GetOrCreateRenderPluginInstance( + m_RenderPlugin->m_PluginPath, m_RenderPlugin); + if (theInstance) { + inRenderManager.MaybeRegisterOffscreenRenderer(theInstance, *theInstance); + SOffscreenRenderResult theResult = inRenderManager.GetRenderedItem(theInstance); + HandleOffscreenResult(*this, newImage, theResult, replaceTexture, wasDirty); + } + } + + if (newImage.m_Texture == NULL) { + if (m_OffscreenRendererId.IsValid()) { + SOffscreenRenderResult theResult = + inRenderManager.GetRenderedItem(m_OffscreenRendererId); + HandleOffscreenResult(*this, newImage, theResult, replaceTexture, wasDirty); + } + } + + if (newImage.m_Texture == NULL) { + m_LastFrameOffscreenRenderer = NULL; + newImage = inBufferManager.LoadRenderImage(m_ImagePath, false, forIbl); + replaceTexture = newImage.m_Texture != m_TextureData.m_Texture; + } + + if (replaceTexture) { + wasDirty = true; + m_TextureData = newImage; + } + + if (m_Flags.IsTransformDirty()) { + wasDirty = true; + CalculateTextureTransform(); + } + return wasDirty; +} + +void SImage::CalculateTextureTransform() +{ + m_Flags.SetTransformDirty(false); + + m_TextureTransform = QT3DSMat44::createIdentity(); + + QT3DSMat44 translation(QT3DSMat44::createIdentity()); + QT3DSMat44 rotation(QT3DSMat44::createIdentity()); + QT3DSMat44 scale(QT3DSMat44::createIdentity()); + + translation.column3[0] = m_Position.x; + translation.column3[1] = m_Position.y; + scale.column0[0] = m_Scale.x; + scale.column1[1] = m_Scale.y; + rotation.rotate(m_Rotation, QT3DSVec3(0, 0, 1)); + + // Setup the pivot. + m_TextureTransform.column3[0] = m_Pivot.x; + m_TextureTransform.column3[1] = m_Pivot.y; + m_TextureTransform = m_TextureTransform * rotation; + m_TextureTransform = m_TextureTransform * scale; + m_TextureTransform = m_TextureTransform * translation; +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h new file mode 100644 index 00000000..47993e73 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_IMAGE_H +#define QT3DS_RENDER_IMAGE_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "Qt3DSRenderNode.h" +#include "foundation/Qt3DSVec2.h" +#include "Qt3DSRenderImageTextureData.h" +#include "EASTL/utility.h" + +namespace qt3ds { +namespace render { + class IQt3DSRenderContext; + class IOffscreenRenderManager; + class IOffscreenRenderer; + struct ImageMappingModes + { + enum Enum { + Normal = 0, // UV mapping + Environment = 1, + LightProbe = 2, + }; + }; + + struct QT3DS_AUTOTEST_EXPORT SImage : public SGraphObject + { + // Complete path to the file; + //*not* relative to the presentation directory + CRegisteredString m_ImagePath; + CRegisteredString m_ImageShaderName; ///< for custom materials we don't generate the name + + // Presentation id. + CRegisteredString m_OffscreenRendererId; // overrides source path if available + SRenderPlugin *m_RenderPlugin; // Overrides everything if available. + IOffscreenRenderer *m_LastFrameOffscreenRenderer; + SGraphObject *m_Parent; + + SImageTextureData m_TextureData; + + NodeFlags m_Flags; // only dirty, transform dirty, and active apply + + QT3DSVec2 m_Scale; + QT3DSVec2 m_Pivot; + QT3DSF32 m_Rotation; // Radians. + QT3DSVec2 m_Position; + ImageMappingModes::Enum m_MappingMode; + NVRenderTextureCoordOp::Enum m_HorizontalTilingMode; + NVRenderTextureCoordOp::Enum m_VerticalTilingMode; + + // Setting any of the above variables means this object is dirty. + // Setting any of the vec2 properties means this object's transform is dirty + + QT3DSMat44 m_TextureTransform; + + SImage(); + // Renders the sub presentation + // Or finds the image. + // and sets up the texture transform + bool ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager &inRenderManager, + IRenderPluginManager &pluginManager, bool forIbl = false); + + void CalculateTextureTransform(); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_ImagePath); + inRemapper.Remap(m_OffscreenRendererId); + // Null out objects that should be null when loading from file. + inRemapper.NullPtr(m_LastFrameOffscreenRenderer); + inRemapper.NullPtr(m_TextureData.m_Texture); + inRemapper.Remap(m_RenderPlugin); + inRemapper.Remap(m_Parent); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.cpp new file mode 100644 index 00000000..ee146624 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderEffect.h" + +using namespace qt3ds::render; + +SLayer::SLayer() + : SNode(GraphObjectTypes::Layer) + , m_Scene(NULL) + , m_FirstEffect(NULL) + , m_RenderPlugin(NULL) + , m_ProgressiveAAMode(AAModeValues::NoAA) + , m_MultisampleAAMode(AAModeValues::NoAA) + , m_Background(LayerBackground::Transparent) + , m_ClearColor(0) + , m_BlendType(LayerBlendTypes::Normal) + , m_HorizontalFieldValues(HorizontalFieldValues::LeftWidth) + , m_Left(0) + , m_LeftUnits(LayerUnitTypes::Percent) + , m_Width(100.0f) + , m_WidthUnits(LayerUnitTypes::Percent) + , m_Right(0) + , m_RightUnits(LayerUnitTypes::Percent) + , m_VerticalFieldValues(VerticalFieldValues::TopHeight) + , m_Top(0) + , m_TopUnits(LayerUnitTypes::Percent) + , m_Height(100.0f) + , m_HeightUnits(LayerUnitTypes::Percent) + , m_Bottom(0) + , m_BottomUnits(LayerUnitTypes::Percent) + , m_AoStrength(0) + , m_AoDistance(5.0f) + , m_AoSoftness(50.0f) + , m_AoBias(0) + , m_AoSamplerate(2) + , m_AoDither(false) + , m_ShadowStrength(0) + , m_ShadowDist(10) + , m_ShadowSoftness(100.0f) + , m_ShadowBias(0) + , m_LightProbe(NULL) + , m_ProbeBright(100.0f) + , m_FastIbl(false) + , m_ProbeHorizon(-1.0f) + , m_ProbeFov(180.0f) + , m_LightProbe2(NULL) + , m_Probe2Fade(1.0f) + , m_Probe2Window(1.0f) + , m_Probe2Pos(0.5f) + , m_TemporalAAEnabled(false) +{ + m_Flags.SetLayerRenderToTarget(true); + m_Flags.SetLayerEnableDepthTest(true); + m_Flags.SetLayerEnableDepthPrepass(true); +} + +void SLayer::AddEffect(SEffect &inEffect) +{ + // Effects need to be rendered in reverse order as described in the file. + inEffect.m_NextEffect = m_FirstEffect; + m_FirstEffect = &inEffect; + inEffect.m_Layer = this; +} + +SEffect *SLayer::GetLastEffect() +{ + if (m_FirstEffect) { + SEffect *theEffect = m_FirstEffect; + // Empty loop intentional + for (; theEffect->m_NextEffect; theEffect = theEffect->m_NextEffect) { + } + QT3DS_ASSERT(theEffect->m_NextEffect == NULL); + return theEffect; + } + return NULL; +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.h new file mode 100644 index 00000000..3759fe12 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLayer.h @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_LAYER_H +#define QT3DS_RENDER_LAYER_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderNode.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderer.h" + +namespace qt3ds { +namespace render { + class IQt3DSRenderContext; + struct SPresentation; + struct SScene; + struct SEffect; + + struct AAModeValues + { + enum Enum { + NoAA = 0, + SSAA = 1, + X2 = 2, + X4 = 4, + X8 = 8 + }; + }; + + struct HorizontalFieldValues + { + enum Enum { + LeftWidth = 0, + LeftRight, + WidthRight + }; + }; + + struct VerticalFieldValues + { + enum Enum { + TopHeight = 0, + TopBottom, + HeightBottom + }; + }; + + struct LayerUnitTypes + { + enum Enum { + Percent = 0, + Pixels + }; + }; + + struct LayerBackground + { + enum Enum { + Transparent = 0, + Unspecified, + Color + }; + }; + + struct LayerBlendTypes + { + enum Enum { + Normal = 0, + Screen, + Multiply, + Add, + Subtract, + Overlay, + ColorBurn, + ColorDodge + }; + }; + + // A layer is a special node. It *always* presents its global transform + // to children as the identity. It also can optionally have a width or height + // different than the overlying context. You can think of layers as the transformation + // between a 3d scene graph and a 2D texture. + struct QT3DS_AUTOTEST_EXPORT SLayer : public SNode + { + SScene *m_Scene; + + // First effect in a list of effects. + SEffect *m_FirstEffect; + + // If a layer has a valid texture path (one that resolves to either a + // an on-disk image or a offscreen renderer), then it does not render its + // own source path. Instead, it renders the offscreen renderer. Used in this manner, + // offscreen renderer's also have the option (if they support it) to render directly to the + // render target given a specific viewport (that is also scissored if necessary). + qt3ds::foundation::CRegisteredString m_TexturePath; + + SRenderPlugin *m_RenderPlugin; // Overrides texture path if available. + + AAModeValues::Enum m_ProgressiveAAMode; + AAModeValues::Enum m_MultisampleAAMode; + LayerBackground::Enum m_Background; + QT3DSVec3 m_ClearColor; + + LayerBlendTypes::Enum m_BlendType; + + HorizontalFieldValues::Enum m_HorizontalFieldValues; + QT3DSF32 m_Left; + LayerUnitTypes::Enum m_LeftUnits; + QT3DSF32 m_Width; + LayerUnitTypes::Enum m_WidthUnits; + QT3DSF32 m_Right; + LayerUnitTypes::Enum m_RightUnits; + + VerticalFieldValues::Enum m_VerticalFieldValues; + QT3DSF32 m_Top; + LayerUnitTypes::Enum m_TopUnits; + QT3DSF32 m_Height; + LayerUnitTypes::Enum m_HeightUnits; + QT3DSF32 m_Bottom; + LayerUnitTypes::Enum m_BottomUnits; + + // Ambient occlusion + QT3DSF32 m_AoStrength; + QT3DSF32 m_AoDistance; + QT3DSF32 m_AoSoftness; + QT3DSF32 m_AoBias; + QT3DSI32 m_AoSamplerate; + bool m_AoDither; + + // Direct occlusion + QT3DSF32 m_ShadowStrength; + QT3DSF32 m_ShadowDist; + QT3DSF32 m_ShadowSoftness; + QT3DSF32 m_ShadowBias; + + // IBL + SImage *m_LightProbe; + QT3DSF32 m_ProbeBright; + bool m_FastIbl; + QT3DSF32 m_ProbeHorizon; + QT3DSF32 m_ProbeFov; + SImage *m_LightProbe2; + QT3DSF32 m_Probe2Fade; + QT3DSF32 m_Probe2Window; + QT3DSF32 m_Probe2Pos; + + bool m_TemporalAAEnabled; + + SLayer(); + + void AddEffect(SEffect &inEffect); + + SEffect *GetLastEffect(); + + LayerBlendTypes::Enum GetLayerBlend() + { + return m_BlendType; + } + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SNode::Remap(inRemapper); + inRemapper.Remap(m_Scene); + inRemapper.Remap(m_FirstEffect); + inRemapper.Remap(m_TexturePath); + inRemapper.Remap(m_RenderPlugin); + inRemapper.Remap(m_LightProbe); + inRemapper.Remap(m_LightProbe2); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.cpp new file mode 100644 index 00000000..3b45e8c9 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderLight.h" + +using namespace qt3ds::render; + +SLight::SLight() + : SNode(GraphObjectTypes::Light) + , m_LightType(RenderLightTypes::Directional) + , m_Scope(NULL) + , m_DiffuseColor(1, 1, 1) + , m_SpecularColor(1, 1, 1) + , m_AmbientColor(0, 0, 0) + , m_Brightness(100) + , m_LinearFade(0) + , m_ExponentialFade(0) + , m_AreaWidth(0) + , m_AreaHeight(0) + , m_CastShadow(false) + , m_ShadowBias(0.0f) + , m_ShadowFactor(5.0f) + , m_ShadowMapRes(9) + , m_ShadowMapFar(5000.0f) + , m_ShadowMapFov(90.0f) + , m_ShadowFilter(35.0f) +{ + m_Flags.SetPointLight(0); +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.h new file mode 100644 index 00000000..549e3e26 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLight.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_LIGHT_H +#define QT3DS_RENDER_LIGHT_H +#include "Qt3DSRenderNode.h" + +namespace qt3ds { +namespace render { + + struct RenderLightTypes + { + enum Enum { + Unknown = 0, + Directional, + Point, + Area, + }; + }; + + struct SImage; + + struct QT3DS_AUTOTEST_EXPORT SLight : public SNode + { + RenderLightTypes::Enum m_LightType; // Directional + SNode *m_Scope; + QT3DSVec3 m_DiffuseColor; // colors are 0-1 normalized + QT3DSVec3 m_SpecularColor; // colors are 0-1 normalized + QT3DSVec3 m_AmbientColor; // colors are 0-1 normalized + + // The variables below are in the same range as Studio + // Only valid if node is a point light + QT3DSF32 m_Brightness; // 0-200 + QT3DSF32 m_LinearFade; // 0-200 + QT3DSF32 m_ExponentialFade; // 0-200 + + QT3DSF32 m_AreaWidth; // 0.01-inf + QT3DSF32 m_AreaHeight; // 0.01-inf + + bool m_CastShadow; // true if this light produce shadows + QT3DSF32 m_ShadowBias; // depth shift to avoid self-shadowing artifacts + QT3DSF32 m_ShadowFactor; // Darkening factor for ESMs + QT3DSU32 m_ShadowMapRes; // Resolution of shadow map + QT3DSF32 m_ShadowMapFar; // Far clip plane for the shadow map + QT3DSF32 m_ShadowMapFov; // Field of View for the shadow map + QT3DSF32 m_ShadowFilter; // Shadow map filter step size + + // Defaults to directional light + SLight(); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SNode::Remap(inRemapper); + inRemapper.Remap(m_Scope); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.cpp new file mode 100644 index 00000000..0e5e6c60 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderLightmaps.h" + +using namespace qt3ds::render; + +SLightmaps::SLightmaps() + : SGraphObject(GraphObjectTypes::Lightmaps) + , m_LightmapIndirect(NULL) + , m_LightmapRadiosity(NULL) + , m_LightmapShadow(NULL) +{ +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.h new file mode 100644 index 00000000..4480aea4 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderLightmaps.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_RENDER_LIGHTMAPS_H +#define QT3DS_RENDER_LIGHTMAPS_H + +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderMaterialDirty.h" + +namespace qt3ds { +namespace render { + + struct MaterialLightmapsUsage + { + enum Enum { + Dynamic = 0, + Baked, + DynamicAndBaked, + }; + }; + + struct QT3DS_AUTOTEST_EXPORT SLightmaps : public SGraphObject + { + CMaterialDirty m_Dirty; + + SImage *m_LightmapIndirect; + SImage *m_LightmapRadiosity; + SImage *m_LightmapShadow; + + SLightmaps(); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_LightmapIndirect); + inRemapper.Remap(m_LightmapRadiosity); + inRemapper.Remap(m_LightmapShadow); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderMaterialDirty.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderMaterialDirty.h new file mode 100644 index 00000000..c04c1b6b --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderMaterialDirty.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_MATERIAL_DIRTY_H +#define QT3DS_RENDER_MATERIAL_DIRTY_H + +namespace qt3ds { +namespace render { + class CMaterialDirty + { + private: + bool m_Dirty; + bool m_DirtyFlagWithInFrame; + + public: + CMaterialDirty() + : m_Dirty(true) + , m_DirtyFlagWithInFrame(m_Dirty) + { + } + + void SetDirty() { m_Dirty = m_DirtyFlagWithInFrame = true; } + bool IsDirty() const { return m_Dirty || m_DirtyFlagWithInFrame; } + void ClearDirty() { m_DirtyFlagWithInFrame = m_Dirty = false; } + void UpdateDirtyForFrame() + { + m_DirtyFlagWithInFrame = m_Dirty; + m_Dirty = false; + } + }; +} +} + +#endif // QT3DS_RENDER_MATERIAL_DIRTY_H diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.cpp new file mode 100644 index 00000000..a78396c5 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderModel.h" +#include "Qt3DSRenderMaterialHelpers.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderMesh.h" + +using namespace qt3ds::render; + +SModel::SModel() + : SNode(GraphObjectTypes::Model) + , m_FirstMaterial(NULL) + , m_SkeletonRoot(-1) + , m_TessellationMode(TessModeValues::NoTess) + , m_EdgeTess(1.0) + , m_InnerTess(1.0) + , m_WireframeMode(false) + , m_ShadowCaster(true) +{ +} + +void SModel::AddMaterial(SGraphObject &inMaterial) +{ + if (m_FirstMaterial == NULL) + m_FirstMaterial = &inMaterial; + else { + SGraphObject *lastMaterial; + // empty loop intentional + for (lastMaterial = m_FirstMaterial; lastMaterial && GetNextMaterialSibling(lastMaterial); + lastMaterial = GetNextMaterialSibling(lastMaterial)) { + } + SetNextMaterialSibling(*lastMaterial, &inMaterial); + } + if (inMaterial.m_Type == GraphObjectTypes::DefaultMaterial) + static_cast(inMaterial).m_Parent = this; +} + +NVBounds3 SModel::GetModelBounds(IBufferManager &inManager) const +{ + NVBounds3 retval; + retval.setEmpty(); + SRenderMesh *theMesh = inManager.LoadMesh(m_MeshPath); + if (theMesh) { + for (QT3DSU32 idx = 0, end = theMesh->m_Subsets.size(); idx < end; ++idx) + retval.include(theMesh->m_Subsets[idx].m_Bounds); + } + return retval; +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.h new file mode 100644 index 00000000..cc5c4e27 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderModel.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_MODEL_H +#define QT3DS_RENDER_MODEL_H + +#include "Qt3DSRenderNode.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderTessModeValues.h" + +namespace qt3ds { +namespace render { + + struct SDefaultMaterial; + class IBufferManager; + + struct QT3DS_AUTOTEST_EXPORT SModel : public SNode + { + // Complete path to the file; + //*not* relative to the presentation directory + CRegisteredString m_MeshPath; + SGraphObject *m_FirstMaterial; + QT3DSI32 m_SkeletonRoot; + TessModeValues::Enum m_TessellationMode; + QT3DSF32 m_EdgeTess; + QT3DSF32 m_InnerTess; + bool m_WireframeMode; + bool m_ShadowCaster; + + SModel(); + + void AddMaterial(SGraphObject &inMaterial); + + NVBounds3 GetModelBounds(IBufferManager &inManager) const; + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SNode::Remap(inRemapper); + inRemapper.RemapMaterial(m_FirstMaterial); + inRemapper.Remap(m_MeshPath); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.cpp new file mode 100644 index 00000000..bf47bb8d --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.cpp @@ -0,0 +1,499 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderModel.h" +#include "Qt3DSRenderNode.h" +#include "Qt3DSRenderText.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderPathManager.h" +#include "Qt3DSRenderPath.h" + +using namespace qt3ds::render; + +SNode::SNode(GraphObjectTypes::Enum inGraphObjectType) + : SGraphObject(inGraphObjectType) + , m_Rotation(0, 0, 0) // Radians + , m_Position(0, 0, 0) + , m_Scale(1, 1, 1) + , m_Pivot(0, 0, 0) + , m_RotationOrder(EulOrdYXZs) + , m_LocalOpacity(1.0f) + , m_GlobalOpacity(1.0f) + , m_SkeletonId(-1) + , m_Parent(NULL) + , m_NextSibling(NULL) + , m_PreviousSibling(NULL) + , m_FirstChild(NULL) + , m_DFSIndex(0) +{ + m_Flags.SetDirty(true); + m_Flags.SetTransformDirty(true); + m_Flags.SetLeftHanded(true); + m_Flags.SetActive(true); + m_Flags.SetLocallyPickable(true); +} + +SNode::SNode(const SNode &inCloningObject, NVAllocatorCallback &inAllocator) + : SGraphObject(inCloningObject, inAllocator) + , m_Rotation(inCloningObject.m_Rotation) // Radians + , m_Position(inCloningObject.m_Position) + , m_Scale(inCloningObject.m_Scale) + , m_Pivot(inCloningObject.m_Pivot) + , m_RotationOrder(inCloningObject.m_RotationOrder) + , m_LocalOpacity(inCloningObject.m_LocalOpacity) + , m_LocalTransform(inCloningObject.m_LocalTransform) + , m_GlobalTransform(inCloningObject.m_GlobalTransform) + , m_GlobalOpacity(inCloningObject.m_GlobalOpacity) + , m_SkeletonId(inCloningObject.m_SkeletonId) + , m_Parent(NULL) + , m_NextSibling(NULL) + , m_PreviousSibling(NULL) + , m_FirstChild(NULL) + , m_DFSIndex(0) +{ + m_Flags.SetDirty(true); + m_Flags.SetTransformDirty(true); + m_Flags.SetLeftHanded(true); + m_Flags.SetActive(true); + m_Flags.SetLocallyPickable(true); + + // for ( SNode* theChild = m_FirstChild; theChild != NULL; theChild = theChild->m_NextSibling ) + //{ + // SNode* theClonedChild = static_cast( CGraphObjectFactory::CloneGraphObject( + //*theChild, inAllocator ) ); + // AddChild( *theClonedChild ); + //} +} + +// Sets this object dirty and walks down the graph setting all +// children who are not dirty to be dirty. +void SNode::MarkDirty(NodeTransformDirtyFlag::Enum inTransformDirty) +{ + if (m_Flags.IsTransformDirty() == false) + m_Flags.SetTransformDirty(inTransformDirty != NodeTransformDirtyFlag::TransformNotDirty); + if (m_Flags.IsDirty() == false) { + m_Flags.SetDirty(true); + for (SNode *child = m_FirstChild; child; child = child->m_NextSibling) + child->MarkDirty(inTransformDirty); + } +} + +// Calculate global transform and opacity +// Walks up the graph ensure all parents are not dirty so they have +// valid global transforms. + +bool SNode::CalculateGlobalVariables() +{ + bool retval = m_Flags.IsDirty(); + if (retval) { + m_Flags.SetDirty(false); + if (m_Flags.IsTransformDirty()) + CalculateLocalTransform(); + m_GlobalOpacity = m_LocalOpacity; + if (m_Parent) { + // Layer transforms do not flow down but affect the final layer's rendered + // representation. + retval = m_Parent->CalculateGlobalVariables() || retval; + if (m_Parent->m_Type != GraphObjectTypes::Layer) { + m_GlobalOpacity *= m_Parent->m_GlobalOpacity; + if (m_Flags.IsIgnoreParentTransform() == false) + m_GlobalTransform = m_Parent->m_GlobalTransform * m_LocalTransform; + else + m_GlobalTransform = m_LocalTransform; + } else + m_GlobalTransform = m_LocalTransform; + + m_Flags.SetGlobalActive(m_Flags.IsActive() && m_Parent->m_Flags.IsGloballyActive()); + m_Flags.SetGloballyPickable(m_Flags.IsLocallyPickable() + || m_Parent->m_Flags.IsGloballyPickable()); + } else { + m_GlobalTransform = m_LocalTransform; + m_Flags.SetGlobalActive(m_Flags.IsActive()); + m_Flags.SetGloballyPickable(m_Flags.IsLocallyPickable()); + } + } + // We always clear dirty in a reasonable manner but if we aren't active + // there is no reason to tell the universe if we are dirty or not. + return retval && m_Flags.IsActive(); +} + +// Create some mapping of euler angles to their axis mapping. +#define ITERATE_POSSIBLE_EULER_ANGLES \ + HANDLE_EULER_ANGLE(EulOrdXYZs, X, Y, Z) \ + HANDLE_EULER_ANGLE(EulOrdXYXs, X, Y, X) \ + HANDLE_EULER_ANGLE(EulOrdXZYs, X, Z, Y) \ + HANDLE_EULER_ANGLE(EulOrdXZXs, X, Z, X) \ + HANDLE_EULER_ANGLE(EulOrdYZXs, Y, Z, X) \ + HANDLE_EULER_ANGLE(EulOrdYZYs, Y, Z, Y) \ + HANDLE_EULER_ANGLE(EulOrdYXZs, Y, X, Z) \ + HANDLE_EULER_ANGLE(EulOrdYXYs, Y, X, Y) \ + HANDLE_EULER_ANGLE(EulOrdZXYs, Z, X, Y) \ + HANDLE_EULER_ANGLE(EulOrdZXZs, Z, X, Z) \ + HANDLE_EULER_ANGLE(EulOrdZYXs, Z, Y, X) \ + HANDLE_EULER_ANGLE(EulOrdZYZs, Z, Y, Z) \ + HANDLE_EULER_ANGLE(EulOrdZYXr, Z, Y, X) \ + HANDLE_EULER_ANGLE(EulOrdXYXr, X, Y, X) \ + HANDLE_EULER_ANGLE(EulOrdYZXr, Y, Z, X) \ + HANDLE_EULER_ANGLE(EulOrdXZXr, X, Z, X) \ + HANDLE_EULER_ANGLE(EulOrdXZYr, X, Z, Y) \ + HANDLE_EULER_ANGLE(EulOrdYZYr, Y, Z, Y) \ + HANDLE_EULER_ANGLE(EulOrdZXYr, Z, X, Y) \ + HANDLE_EULER_ANGLE(EulOrdYXYr, Y, X, Y) \ + HANDLE_EULER_ANGLE(EulOrdYXZr, Y, X, Z) \ + HANDLE_EULER_ANGLE(EulOrdZXZr, Z, X, Z) \ + HANDLE_EULER_ANGLE(EulOrdXYZr, X, Y, Z) \ + HANDLE_EULER_ANGLE(EulOrdZYZr, Z, Y, Z) + +inline EulerAngles RotationAndOrderToShoemake(QT3DSVec3 inRotation, QT3DSU32 inOrder) +{ + EulerAngles retval; + retval.w = (QT3DSF32)inOrder; + int X = 0; + int Y = 1; + int Z = 2; + + switch (inOrder) { +#define HANDLE_EULER_ANGLE(order, xIdx, yIdx, zIdx) \ + case order: \ + retval.x = -inRotation[xIdx]; \ + retval.y = -inRotation[yIdx]; \ + retval.z = -inRotation[zIdx]; \ + break; + ITERATE_POSSIBLE_EULER_ANGLES +#undef HANDLE_EULER_ANGLE + default: + QT3DS_ASSERT(false); + retval.x = inRotation[X]; + retval.y = inRotation[Y]; + retval.z = inRotation[Z]; + break; + } + return retval; +} + +QT3DSVec3 SNode::GetRotationVectorFromRotationMatrix(const QT3DSMat33 &inMatrix) const +{ + QT3DSMat44 theConvertMatrix(inMatrix, QT3DSVec3(0, 0, 0)); + if (m_Flags.IsLeftHanded()) + SNode::FlipCoordinateSystem(theConvertMatrix); + qt3ds::render::CEulerAngleConverter theConverter; + qt3ds::render::HMatrix *theHMatrix = + reinterpret_cast(theConvertMatrix.front()); + qt3ds::render::EulerAngles theAngles = theConverter.Eul_FromHMatrix(*theHMatrix, m_RotationOrder); + return GetRotationVectorFromEulerAngles(theAngles); +} + +QT3DSVec3 SNode::GetRotationVectorFromEulerAngles(const EulerAngles &inAngles) +{ + QT3DSVec3 retval(0, 0, 0); + int X = 0; + int Y = 1; + int Z = 2; + switch ((int)inAngles.w) { +#define HANDLE_EULER_ANGLE(order, xIdx, yIdx, zIdx) \ + case order: \ + retval[xIdx] = -inAngles.x; \ + retval[yIdx] = -inAngles.y; \ + retval[zIdx] = -inAngles.z; \ + break; + ITERATE_POSSIBLE_EULER_ANGLES +#undef HANDLE_EULER_ANGLE + default: + QT3DS_ASSERT(false); + retval.x = inAngles.x; + retval.y = inAngles.y; + retval.z = inAngles.z; + break; + } + + return retval; +} + +void SNode::CalculateRotationMatrix(QT3DSMat44 &outMatrix) const +{ + StaticAssert::valid_expression(); + CEulerAngleConverter theConverter; + EulerAngles theAngles(RotationAndOrderToShoemake(m_Rotation, (int)m_RotationOrder)); + HMatrix *theMatrix = reinterpret_cast(&outMatrix); + theConverter.Eul_ToHMatrix(theAngles, *theMatrix); +} + +void SNode::FlipCoordinateSystem(QT3DSMat44 &inMatrix) +{ + QT3DSF32 *writePtr(inMatrix.front()); + // rotation conversion + writePtr[0 * 4 + 2] *= -1; + writePtr[1 * 4 + 2] *= -1; + writePtr[2 * 4 + 0] *= -1; + writePtr[2 * 4 + 1] *= -1; + + // translation conversion + writePtr[3 * 4 + 2] *= -1; +} + +void SNode::CalculateLocalTransform() +{ + m_Flags.SetTransformDirty(false); + bool leftHanded = m_Flags.IsLeftHanded(); + m_LocalTransform = QT3DSMat44::createIdentity(); + m_GlobalTransform = m_LocalTransform; + QT3DSF32 *writePtr = m_LocalTransform.front(); + QT3DSVec3 theScaledPivot(-m_Pivot[0] * m_Scale[0], -m_Pivot[1] * m_Scale[1], + -m_Pivot[2] * m_Scale[2]); + m_LocalTransform.column0[0] = m_Scale[0]; + m_LocalTransform.column1[1] = m_Scale[1]; + m_LocalTransform.column2[2] = m_Scale[2]; + + writePtr[12] = theScaledPivot[0]; + writePtr[13] = theScaledPivot[1]; + if (leftHanded) + writePtr[14] = theScaledPivot[2]; + else + writePtr[14] = -theScaledPivot[2]; + + QT3DSMat44 theRotationTransform; + CalculateRotationMatrix(theRotationTransform); + // may need column conversion in here somewhere. + m_LocalTransform = theRotationTransform * m_LocalTransform; + + writePtr[12] += m_Position[0]; + writePtr[13] += m_Position[1]; + if (leftHanded) + writePtr[14] = writePtr[14] + m_Position[2]; + else + writePtr[14] = writePtr[14] - m_Position[2]; + + if (leftHanded) { + FlipCoordinateSystem(m_LocalTransform); + } +} + +void SNode::SetLocalTransformFromMatrix(QT3DSMat44 &inTransform) +{ + m_Flags.SetTransformDirty(true); + + // clear pivot + m_Pivot[0] = m_Pivot[1] = m_Pivot[2] = 0.0f; + + // set translation + m_Position[0] = inTransform[3][0]; + m_Position[1] = inTransform[3][1]; + m_Position[2] = inTransform[3][2]; + // set scale + m_Scale[0] = inTransform.column0.magnitude(); + m_Scale[1] = inTransform.column1.magnitude(); + m_Scale[2] = inTransform.column2.magnitude(); + + // make sure there is no zero value + m_Scale[0] = (m_Scale[0] == 0.0) ? 1.0f : m_Scale[0]; + m_Scale[1] = (m_Scale[1] == 0.0) ? 1.0f : m_Scale[1]; + m_Scale[2] = (m_Scale[2] == 0.0) ? 1.0f : m_Scale[2]; + + // extract rotation by first dividing through scale value + float invScaleX = 1.0f / m_Scale[0]; + float invScaleY = 1.0f / m_Scale[1]; + float invScaleZ = 1.0f / m_Scale[2]; + + inTransform[0][0] *= invScaleX; + inTransform[0][1] *= invScaleX; + inTransform[0][2] *= invScaleX; + inTransform[1][0] *= invScaleY; + inTransform[1][1] *= invScaleY; + inTransform[1][2] *= invScaleY; + inTransform[2][0] *= invScaleZ; + inTransform[2][1] *= invScaleZ; + inTransform[2][2] *= invScaleZ; + + QT3DSMat33 theRotationMatrix(inTransform.column0.getXYZ(), inTransform.column1.getXYZ(), + inTransform.column2.getXYZ()); + m_Rotation = GetRotationVectorFromRotationMatrix(theRotationMatrix); +} + +void SNode::AddChild(SNode &inChild) +{ + if (inChild.m_Parent) + inChild.m_Parent->RemoveChild(inChild); + inChild.m_Parent = this; + if (m_FirstChild == nullptr) { + m_FirstChild = &inChild; + inChild.m_NextSibling = nullptr; + inChild.m_PreviousSibling = nullptr; + } else { + SNode *lastChild = GetLastChild(); + if (lastChild) { + lastChild->m_NextSibling = &inChild; + inChild.m_PreviousSibling = lastChild; + inChild.m_NextSibling = nullptr; + } else { + QT3DS_ASSERT(false); // no last child but first child isn't null? + } + } +} + +void SNode::RemoveChild(SNode &inChild) +{ + if (inChild.m_Parent != this) { + QT3DS_ASSERT(false); + return; + } + for (SNode *child = m_FirstChild; child; child = child->m_NextSibling) { + if (child == &inChild) { + if (child->m_PreviousSibling) + child->m_PreviousSibling->m_NextSibling = child->m_NextSibling; + if (child->m_NextSibling) + child->m_NextSibling->m_PreviousSibling = child->m_PreviousSibling; + child->m_Parent = NULL; + if (m_FirstChild == child) + m_FirstChild = child->m_NextSibling; + child->m_NextSibling = NULL; + child->m_PreviousSibling = NULL; + return; + } + } + QT3DS_ASSERT(false); +} + +SNode *SNode::GetLastChild() +{ + SNode *lastChild = NULL; + // empty loop intentional + for (lastChild = m_FirstChild; lastChild && lastChild->m_NextSibling; + lastChild = lastChild->m_NextSibling) { + } + return lastChild; +} + +void SNode::RemoveFromGraph() +{ + if (m_Parent) + m_Parent->RemoveChild(*this); + + m_NextSibling = NULL; + + // Orphan all of my children. + SNode *nextSibling = NULL; + for (SNode *child = m_FirstChild; child != NULL; child = nextSibling) { + child->m_PreviousSibling = NULL; + child->m_Parent = NULL; + nextSibling = child->m_NextSibling; + child->m_NextSibling = NULL; + } +} + +NVBounds3 SNode::GetBounds(IBufferManager &inManager, IPathManager &inPathManager, + bool inIncludeChildren, IQt3DSRenderNodeFilter *inChildFilter) const +{ + NVBounds3 retval; + retval.setEmpty(); + if (inIncludeChildren) + retval = GetChildBounds(inManager, inPathManager, inChildFilter); + + if (m_Type == GraphObjectTypes::Model) + retval.include(static_cast(this)->GetModelBounds(inManager)); + else if (m_Type == GraphObjectTypes::Text) + retval.include(static_cast(this)->GetTextBounds()); + else if (m_Type == GraphObjectTypes::Path) + retval.include(inPathManager.GetBounds(*static_cast(this))); + return retval; +} + +NVBounds3 SNode::GetChildBounds(IBufferManager &inManager, IPathManager &inPathManager, + IQt3DSRenderNodeFilter *inChildFilter) const +{ + NVBounds3 retval; + retval.setEmpty(); + for (SNode *child = m_FirstChild; child != NULL; child = child->m_NextSibling) { + if (inChildFilter == NULL || inChildFilter->IncludeNode(*child)) { + NVBounds3 childBounds; + if (child->m_Flags.IsTransformDirty()) + child->CalculateLocalTransform(); + childBounds = child->GetBounds(inManager, inPathManager); + if (childBounds.isEmpty() == false) { + // Transform the bounds into our local space. + childBounds.transform(child->m_LocalTransform); + retval.include(childBounds); + } + } + } + return retval; +} + +QT3DSVec3 SNode::GetGlobalPos() const +{ + return m_GlobalTransform.getPosition(); +} + +QT3DSVec3 SNode::GetDirection() const +{ + const QT3DSF32 *dataPtr(m_GlobalTransform.front()); + QT3DSVec3 retval(dataPtr[8], dataPtr[9], dataPtr[10]); + retval.normalize(); + return retval; +} + +QT3DSVec3 SNode::GetScalingCorrectDirection() const +{ + QT3DSMat33 theDirMatrix(m_GlobalTransform.getUpper3x3().getInverse().getTranspose()); + QT3DSVec3 theOriginalDir(0, 0, -1); + QT3DSVec3 retval = theDirMatrix.transform(theOriginalDir); + retval.normalize(); + return retval; +} + +QT3DSVec3 SNode::GetGlobalPivot() const +{ + QT3DSVec3 retval(m_Position); + retval.z *= -1; + + if (m_Parent && m_Parent->m_Type != GraphObjectTypes::Layer) + return m_Parent->m_GlobalTransform.transform(retval); + + return retval; +} + +void SNode::CalculateMVPAndNormalMatrix(const QT3DSMat44 &inViewProjection, QT3DSMat44 &outMVP, + QT3DSMat33 &outNormalMatrix) const +{ + outMVP = inViewProjection * m_GlobalTransform; + CalculateNormalMatrix(outNormalMatrix); +} + +void SNode::GetMatrixUpper3x3(QT3DSMat33 &outDest, const QT3DSMat44 &inSrc) +{ + outDest.column0 = QT3DSVec3(inSrc.column0[0], inSrc.column0[1], inSrc.column0[2]); + outDest.column1 = QT3DSVec3(inSrc.column1[0], inSrc.column1[1], inSrc.column1[2]); + outDest.column2 = QT3DSVec3(inSrc.column2[0], inSrc.column2[1], inSrc.column2[2]); +} + +void SNode::CalculateNormalMatrix(QT3DSMat33 &outNormalMatrix) const +{ + GetMatrixUpper3x3(outNormalMatrix, m_GlobalTransform); + outNormalMatrix = outNormalMatrix.getInverse().getTranspose(); +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.h new file mode 100644 index 00000000..87a1500c --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderNode.h @@ -0,0 +1,307 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_NODE_H +#define QT3DS_RENDER_NODE_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "foundation/Qt3DSMat44.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSBounds3.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSNoCopy.h" +#include "Qt3DSRenderEulerAngles.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + struct SModel; + struct SLight; + struct SCamera; + struct SText; + struct SNode; + class IBufferManager; + + class INodeQueue + { + protected: + virtual ~INodeQueue() {} + public: + virtual void Enqueue(SModel &inModel) = 0; + virtual void Enqueue(SLight &inLight) = 0; + virtual void Enqueue(SCamera &inCamera) = 0; + // virtual void Enqueue( SText& inText ) = 0; + }; + + struct NodeFlagValues + { + enum Enum { + Dirty = 1, + TransformDirty = 1 << 1, + Active = 1 << 2, ///< Is this exact object active + LeftHanded = 1 << 3, + Orthographic = 1 << 4, + PointLight = 1 << 5, + GlobalActive = 1 << 6, ///< set based in Active and if a parent is active. + TextDirty = 1 << 7, + LocallyPickable = 1 << 8, + GloballyPickable = 1 << 9, + LayerEnableDepthTest = 1 << 10, + LayerRenderToTarget = 1 << 11, ///< Does this layer render to the normal render target, + ///or is it offscreen-only + ForceLayerOffscreen = 1 << 12, ///< Forces a layer to always use the offscreen rendering + ///mechanism. This can be usefulf or caching purposes. + IgnoreParentTransform = 1 << 13, + LayerEnableDepthPrePass = 1 << 14, ///< True when we render a depth pass before + }; + }; + + struct NodeTransformDirtyFlag + { + enum Enum { + TransformNotDirty, + TransformIsDirty, + }; + }; + struct NodeFlags : public NVFlags + { + NodeFlags() + : NVFlags((QT3DSU32)0) + { + } + void ClearOrSet(bool value, NodeFlagValues::Enum enumVal) { clearOrSet(value, enumVal); } + void SetActive(bool value) { ClearOrSet(value, NodeFlagValues::Active); } + bool IsActive() const { return this->operator&(NodeFlagValues::Active); } + + void SetGlobalActive(bool value) { ClearOrSet(value, NodeFlagValues::GlobalActive); } + bool IsGloballyActive() const { return this->operator&(NodeFlagValues::GlobalActive); } + + void SetTransformDirty(bool value) { ClearOrSet(value, NodeFlagValues::TransformDirty); } + bool IsTransformDirty() const { return this->operator&(NodeFlagValues::TransformDirty); } + + void SetDirty(bool value) { ClearOrSet(value, NodeFlagValues::Dirty); } + bool IsDirty() const { return this->operator&(NodeFlagValues::Dirty); } + + bool IsLeftHanded() const { return this->operator&(NodeFlagValues::LeftHanded); } + void SetLeftHanded(bool value) { ClearOrSet(value, NodeFlagValues::LeftHanded); } + + bool IsOrthographic() const { return this->operator&(NodeFlagValues::Orthographic); } + void SetOrthographic(bool value) { ClearOrSet(value, NodeFlagValues::Orthographic); } + + bool IsPointLight() const { return this->operator&(NodeFlagValues::PointLight); } + void SetPointLight(bool value) { ClearOrSet(value, NodeFlagValues::PointLight); } + + bool IsTextDirty() const { return this->operator&(NodeFlagValues::TextDirty); } + void SetTextDirty(bool value) { ClearOrSet(value, NodeFlagValues::TextDirty); } + + bool IsLocallyPickable() const { return this->operator&(NodeFlagValues::LocallyPickable); } + void SetLocallyPickable(bool value) { ClearOrSet(value, NodeFlagValues::LocallyPickable); } + + bool IsGloballyPickable() const + { + return this->operator&(NodeFlagValues::GloballyPickable); + } + void SetGloballyPickable(bool value) + { + ClearOrSet(value, NodeFlagValues::GloballyPickable); + } + + bool IsLayerRenderToTarget() const + { + return this->operator&(NodeFlagValues::LayerRenderToTarget); + } + void SetLayerRenderToTarget(bool value) + { + ClearOrSet(value, NodeFlagValues::LayerRenderToTarget); + } + + bool IsLayerEnableDepthTest() const + { + return this->operator&(NodeFlagValues::LayerEnableDepthTest); + } + void SetLayerEnableDepthTest(bool value) + { + ClearOrSet(value, NodeFlagValues::LayerEnableDepthTest); + } + + bool IsForceLayerOffscreen() const + { + return this->operator&(NodeFlagValues::ForceLayerOffscreen); + } + void SetForceLayerOffscreen(bool value) + { + ClearOrSet(value, NodeFlagValues::ForceLayerOffscreen); + } + + bool IsIgnoreParentTransform() const + { + return this->operator&(NodeFlagValues::IgnoreParentTransform); + } + void SetIgnoreParentTransform(bool value) + { + ClearOrSet(value, NodeFlagValues::IgnoreParentTransform); + } + + bool IsLayerEnableDepthPrepass() const + { + return this->operator&(NodeFlagValues::LayerEnableDepthPrePass); + } + void SetLayerEnableDepthPrepass(bool value) + { + ClearOrSet(value, NodeFlagValues::LayerEnableDepthPrePass); + } + }; + + struct QT3DS_AUTOTEST_EXPORT SNode : public SGraphObject + { + // changing any one of these means you have to + // set this object dirty + QT3DSVec3 m_Rotation; // Radians + QT3DSVec3 m_Position; + QT3DSVec3 m_Scale; + QT3DSVec3 m_Pivot; + QT3DSU32 m_RotationOrder; // UICEulerOrder::EulOrd, defaults YXZs + + // This only sets dirty, not transform dirty + // Opacity of 1 means opaque, opacity of zero means transparent. + QT3DSF32 m_LocalOpacity; + + // results of clearing dirty. + NodeFlags m_Flags; + // These end up right handed + QT3DSMat44 m_LocalTransform; + QT3DSMat44 m_GlobalTransform; + QT3DSF32 m_GlobalOpacity; + QT3DSI32 m_SkeletonId; + + // node graph members. + SNode *m_Parent; + SNode *m_NextSibling; + SNode *m_PreviousSibling; + SNode *m_FirstChild; + // Property maintained solely by the render system. + // Depth-first-search index assigned and maintained by render system. + QT3DSU32 m_DFSIndex; + + SNode(GraphObjectTypes::Enum inType = GraphObjectTypes::Node); + SNode(const SNode &inCloningObject, NVAllocatorCallback &inAllocator); + ~SNode() {} + + // Sets this object dirty and walks down the graph setting all + // children who are not dirty to be dirty. + void MarkDirty(NodeTransformDirtyFlag::Enum inTransformDirty = + NodeTransformDirtyFlag::TransformNotDirty); + + void AddChild(SNode &inChild); + void RemoveChild(SNode &inChild); + SNode *GetLastChild(); + + // Remove this node from the graph. + // It is no longer the the parent's child lists + // and all of its children no longer have a parent + // finally they are no longer siblings of each other. + void RemoveFromGraph(); + + // Calculate global transform and opacity + // Walks up the graph ensure all parents are not dirty so they have + // valid global transforms. + bool CalculateGlobalVariables(); + + // Given our rotation order and handedness, calculate the final rotation matrix + // Only the upper 3x3 of this matrix is filled in. + // If this object is left handed, then you need to call FlipCoordinateSystem + // to get a result identical to the result produced in CalculateLocalTransform + void CalculateRotationMatrix(QT3DSMat44 &outMatrix) const; + + // Get a rotation vector that would produce the given 3x.3 matrix. + // Takes m_RotationOrder and m_Flags.IsLeftHandled into account. + // Returns a rotation vector in radians. + QT3DSVec3 GetRotationVectorFromRotationMatrix(const QT3DSMat33 &inMatrix) const; + + static QT3DSVec3 GetRotationVectorFromEulerAngles(const EulerAngles &inAngles); + + // Flip a matrix from left-handed to right-handed and vice versa + static void FlipCoordinateSystem(QT3DSMat44 &ioMatrix); + + // Force the calculation of the local transform + void CalculateLocalTransform(); + + /** + * @brief setup local tranform from a matrix. + * This function decomposes a SRT matrix. + * This will fail if this matrix contains non-affine transformations + * + * @param inTransform[in] input transformation + * + * @return true backend type + */ + void SetLocalTransformFromMatrix(QT3DSMat44 &inTransform); + + // Get the bounds of us and our children in our local space. + NVBounds3 GetBounds(IBufferManager &inManager, IPathManager &inPathManager, + bool inIncludeChildren = true, + IQt3DSRenderNodeFilter *inChildFilter = NULL) const; + NVBounds3 GetChildBounds(IBufferManager &inManager, IPathManager &inPathManager, + IQt3DSRenderNodeFilter *inChildFilter = NULL) const; + // Assumes CalculateGlobalVariables has already been called. + QT3DSVec3 GetGlobalPos() const; + QT3DSVec3 GetGlobalPivot() const; + // Pulls the 3rd column out of the global transform. + QT3DSVec3 GetDirection() const; + // Multiplies (0,0,-1) by the inverse transpose of the upper 3x3 of the global transform. + // This is correct w/r/t to scaling and which the above getDirection is not. + QT3DSVec3 GetScalingCorrectDirection() const; + + // outMVP and outNormalMatrix are returned ready to upload to openGL, meaning they are + // row-major. + void CalculateMVPAndNormalMatrix(const QT3DSMat44 &inViewProjection, QT3DSMat44 &outMVP, + QT3DSMat33 &outNormalMatrix) const; + + // This should be in a utility file somewhere + static void GetMatrixUpper3x3(QT3DSMat33 &inDest, const QT3DSMat44 &inSrc); + void CalculateNormalMatrix(QT3DSMat33 &outNormalMatrix) const; + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_Parent); + inRemapper.Remap(m_FirstChild); + inRemapper.Remap(m_NextSibling); + inRemapper.Remap(m_PreviousSibling); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.cpp new file mode 100644 index 00000000..bc637680 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderPathSubPath.h" + +using namespace qt3ds::render; + +void SPath::AddSubPath(SPathSubPath &inSegment) +{ + SPathSubPath *lastSegment = NULL; + inSegment.m_Path = this; + inSegment.m_NextSubPath = NULL; + if (m_FirstSubPath) { + // find last segment + for (lastSegment = m_FirstSubPath; lastSegment && lastSegment->m_NextSubPath; + lastSegment = lastSegment->m_NextSubPath) + ; + lastSegment->m_NextSubPath = &inSegment; + } else + m_FirstSubPath = &inSegment; +} + +void SPath::ClearSubPaths() +{ + SPathSubPath *nextSegment = NULL; + for (SPathSubPath *theSegment = m_FirstSubPath; theSegment; theSegment = nextSegment) { + nextSegment = theSegment->m_NextSubPath; + theSegment->m_Path = NULL; + theSegment->m_NextSubPath = NULL; + } + m_FirstSubPath = NULL; +} \ No newline at end of file diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.h new file mode 100644 index 00000000..7db3ef50 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPath.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_H +#define QT3DS_RENDER_PATH_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderNode.h" + +namespace qt3ds { +namespace render { + struct PathCapping + { + enum Enum { + Noner = 0, + Taper = 1, + }; + }; + + struct PathTypes + { + enum Enum { + Noner = 0, + Painted, + Geometry, + }; + }; + + struct PathPaintStyles + { + enum Enum { + Noner = 0, + FilledAndStroked, + Filled, + Stroked, + }; + }; + + struct SPath : public SNode + { + PathTypes::Enum m_PathType; + QT3DSF32 m_Width; + QT3DSF32 m_LinearError; + QT3DSF32 m_EdgeTessAmount; + QT3DSF32 m_InnerTessAmount; + PathCapping::Enum m_BeginCapping; + QT3DSF32 m_BeginCapOffset; + QT3DSF32 m_BeginCapOpacity; + QT3DSF32 m_BeginCapWidth; + PathCapping::Enum m_EndCapping; + QT3DSF32 m_EndCapOffset; + QT3DSF32 m_EndCapOpacity; + QT3DSF32 m_EndCapWidth; + SGraphObject *m_Material; + SGraphObject *m_SecondMaterial; + // Paths can either be immediate - children attached define path + // or they can link to a path buffer that defines the path. + SPathSubPath *m_FirstSubPath; + CRegisteredString m_PathBuffer; + PathPaintStyles::Enum m_PaintStyle; + + bool m_WireframeMode; + // Loaded onto the card just as data. + SPath() + : SNode(GraphObjectTypes::Path) + , m_PathType(PathTypes::Geometry) + , m_Width(5.0f) + , m_LinearError(100.0f) + , m_EdgeTessAmount(8.0f) + , m_InnerTessAmount(1.0f) + , m_BeginCapping(PathCapping::Noner) + , m_BeginCapOffset(10.0f) + , m_BeginCapOpacity(.2f) + , m_BeginCapWidth(0.0f) + , m_EndCapping(PathCapping::Noner) + , m_EndCapOffset(10.0f) + , m_EndCapOpacity(.2f) + , m_EndCapWidth(0.0f) + , m_Material(NULL) + , m_SecondMaterial(NULL) + , m_FirstSubPath(NULL) + , m_PaintStyle(PathPaintStyles::Stroked) + , m_WireframeMode(false) + { + } + + bool IsStroked() const + { + return m_PaintStyle == PathPaintStyles::Stroked + || m_PaintStyle == PathPaintStyles::FilledAndStroked; + } + + bool IsFilled() const + { + return m_PaintStyle == PathPaintStyles::Filled + || m_PaintStyle == PathPaintStyles::FilledAndStroked; + } + + void AddMaterial(SGraphObject *inMaterial) + { + if (m_Material == NULL) + m_Material = inMaterial; + else + m_SecondMaterial = inMaterial; + } + + void ClearMaterials() + { + m_Material = NULL; + m_SecondMaterial = NULL; + } + + void AddSubPath(SPathSubPath &inSubPath); + void ClearSubPaths(); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SNode::Remap(inRemapper); + inRemapper.Remap(m_PathBuffer); + inRemapper.RemapMaterial(m_Material); + inRemapper.RemapMaterial(m_SecondMaterial); + inRemapper.Remap(m_FirstSubPath); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPathSubPath.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPathSubPath.h new file mode 100644 index 00000000..ed1f9beb --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPathSubPath.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_SEGMENT_H +#define QT3DS_RENDER_PATH_SEGMENT_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" + +namespace qt3ds { +namespace render { + struct SPathSubPath : public SGraphObject + { + SPath *m_Path; + SPathSubPath *m_NextSubPath; + bool m_Closed; + + SPathSubPath() + : SGraphObject(GraphObjectTypes::PathSubPath) + , m_Path(NULL) + , m_NextSubPath(NULL) + , m_Closed(false) + { + } + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_Path); + inRemapper.Remap(m_NextSubPath); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.cpp new file mode 100644 index 00000000..6403959e --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderPresentation.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderContextCore.h" + +using namespace qt3ds::render; + +void SPresentation::Render(IQt3DSRenderContext &inContext) +{ + if (m_Scene) { + NVRenderRect theViewportSize(inContext.GetRenderContext().GetViewport()); + m_Scene->Render(QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height), + inContext); + } +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.h new file mode 100644 index 00000000..2403e3b8 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderPresentation.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PRESENTATION_H +#define QT3DS_RENDER_PRESENTATION_H + +#include "foundation/StringTable.h" +#include "Qt3DSRenderGraphObject.h" +#include "Qt3DSRenderScene.h" +#include "foundation/Qt3DSVec2.h" + +namespace qt3ds { +namespace render { + + struct RenderRotationValues + { + enum Enum { + NoRotation = 0, + Clockwise90, + Clockwise180, + Clockwise270, + }; + }; + + struct SPresentation : public SGraphObject + { + QT3DSVec2 m_PresentationDimensions; + RenderRotationValues::Enum m_PresentationRotation; + bool m_preferKTX; + SScene *m_Scene; + + CRegisteredString m_PresentationDirectory; + + SPresentation() + : SGraphObject(GraphObjectTypes::Presentation) + , m_PresentationDimensions(800, 400) + , m_PresentationRotation(RenderRotationValues::NoRotation) + , m_preferKTX(false) + , m_Scene(NULL) + { + } + + SPresentation(QT3DSF32 w, QT3DSF32 h, bool preferKTX, CRegisteredString presDir) + : SGraphObject(GraphObjectTypes::Presentation) + , m_PresentationDimensions(w, h) + , m_PresentationRotation(RenderRotationValues::NoRotation) + , m_preferKTX(preferKTX) + , m_Scene(NULL) + , m_PresentationDirectory(presDir) + { + } + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_Scene); + inRemapper.Remap(m_PresentationDirectory); + } + + void Render(IQt3DSRenderContext &inContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderReferencedMaterial.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderReferencedMaterial.h new file mode 100644 index 00000000..d2043f0d --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderReferencedMaterial.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_REFERENCED_MATERIAL_H +#define QT3DS_RENDER_REFERENCED_MATERIAL_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderGraphObject.h" +#include "Qt3DSRenderMaterialDirty.h" + +namespace qt3ds { +namespace render { + + struct SReferencedMaterial : SGraphObject + { + CMaterialDirty m_Dirty; + SGraphObject *m_ReferencedMaterial; + SGraphObject *m_NextSibling; + SReferencedMaterial() + : SGraphObject(GraphObjectTypes::ReferencedMaterial) + , m_ReferencedMaterial(NULL) + , m_NextSibling(NULL) + { + } + + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.RemapMaterial(m_ReferencedMaterial); + inRemapper.RemapMaterial(m_NextSibling); + } + }; +} +} + +#endif // QT3DS_RENDER_REFERENCED_MATERIAL_H diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.cpp new file mode 100644 index 00000000..8d206e69 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRender.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderContextCore.h" +#include "render/Qt3DSRenderContext.h" + +using namespace qt3ds::render; + +SScene::SScene() + : SGraphObject(GraphObjectTypes::Scene) + , m_Presentation(NULL) + , m_FirstChild(NULL) + , m_ClearColor(0, 0, 0) + , m_UseClearColor(true) + , m_Dirty(true) +{ +} + +void SScene::AddChild(SLayer &inLayer) +{ + if (m_FirstChild == NULL) + m_FirstChild = &inLayer; + else + GetLastChild()->m_NextSibling = &inLayer; + inLayer.m_Scene = this; +} + +SLayer *SScene::GetLastChild() +{ + // empty loop intentional + SLayer *child; + for (child = m_FirstChild; child && child->m_NextSibling; + child = (SLayer *)child->m_NextSibling) { + } + + return child; +} + +bool SScene::PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, + const SRenderInstanceId id) +{ + // We need to iterate through the layers in reverse order and ask them to render. + bool wasDirty = m_Dirty; + m_Dirty = false; + if (m_FirstChild) { + wasDirty |= + inContext.GetRenderer().PrepareLayerForRender(*m_FirstChild, inViewportDimensions, + true, id); + } + return wasDirty; +} + +void SScene::Render(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, + RenderClearCommand inClearColorBuffer, const SRenderInstanceId id) +{ + if ((inClearColorBuffer == SScene::ClearIsOptional && m_UseClearColor) + || inClearColorBuffer == SScene::AlwaysClear) { + QT3DSF32 clearColorAlpha + = inContext.IsInSubPresentation() && !m_UseClearColor ? 0.0f : 1.0f; + QT3DSVec4 clearColor(0.0f, 0.0f, 0.0f, clearColorAlpha); + if (m_UseClearColor) { + clearColor.x = m_ClearColor.x; + clearColor.y = m_ClearColor.y; + clearColor.z = m_ClearColor.z; + } + // Maybe clear and reset to previous clear color after we leave. + qt3ds::render::NVRenderContextScopedProperty __clearColor( + inContext.GetRenderContext(), &NVRenderContext::GetClearColor, + &NVRenderContext::SetClearColor, clearColor); + inContext.GetRenderContext().Clear(qt3ds::render::NVRenderClearValues::Color); + } + if (m_FirstChild) { + inContext.GetRenderer().RenderLayer(*m_FirstChild, inViewportDimensions, m_UseClearColor, + m_ClearColor, true, id); + } +} +void SScene::RenderWithClear(const QT3DSVec2 &inViewportDimensions, + IQt3DSRenderContext &inContext, + RenderClearCommand inClearColorBuffer, + QT3DSVec3 inClearColor, + const SRenderInstanceId id) +{ + // If this scene is not using clear color, we set the color + // to background color from parent layer. This allows + // fully transparent subpresentations (both scene and layer(s) transparent) + // to inherit color from the layer that contains them. + if (!m_UseClearColor) { + m_ClearColor = inClearColor; + m_UseClearColor = true; + } + Render(inViewportDimensions, inContext, inClearColorBuffer, id); +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.h new file mode 100644 index 00000000..57887199 --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderScene.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SCENE_H +#define QT3DS_RENDER_SCENE_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSVec3.h" +#include "Qt3DSRenderGraphObject.h" + +namespace qt3ds { +namespace render { + struct SLayer; + struct SPresentation; + typedef void *SRenderInstanceId; + + struct SScene : public SGraphObject + { + SPresentation *m_Presentation; + SLayer *m_FirstChild; + QT3DSVec3 m_ClearColor; + bool m_UseClearColor; + bool m_Dirty; + + enum RenderClearCommand { + ClearIsOptional = 0, + DoNotClear = 1, + AlwaysClear = 2, + }; + + SScene(); + + void AddChild(SLayer &inLayer); + SLayer *GetLastChild(); + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SGraphObject::Remap(inRemapper); + inRemapper.Remap(m_Presentation); + inRemapper.Remap(m_FirstChild); + } + // returns true if any of the layers were dirty or if this object was dirty + bool PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, + const SRenderInstanceId id = nullptr); + void Render(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, + RenderClearCommand command = ClearIsOptional, + const SRenderInstanceId id = nullptr); + void RenderWithClear(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext, + RenderClearCommand inClearColorBuffer, + QT3DSVec3 inclearColor, const SRenderInstanceId id = nullptr); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.cpp new file mode 100644 index 00000000..8b44e00f --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderText.h" + +using namespace qt3ds::render; + +STextRenderInfo::STextRenderInfo() + : m_FontSize(24) + , m_HorizontalAlignment(TextHorizontalAlignment::Center) + , m_VerticalAlignment(TextVerticalAlignment::Middle) + , m_Leading(0) + , m_Tracking(0) + , m_DropShadow(false) + , m_DropShadowStrength(80) + , m_DropShadowOffset(10) + , m_DropShadowOffsetX(0) + , m_DropShadowOffsetY(0) + , m_DropShadowHorizontalAlignment(TextHorizontalAlignment::Right) + , m_DropShadowVerticalAlignment(TextVerticalAlignment::Bottom) + , m_WordWrap(TextWordWrap::WrapWord) + , m_BoundingBox(QT3DSVec2(0 ,0)) + , m_Elide(TextElide::ElideNone) + , m_ScaleX(0) + , m_ScaleY(0) + , m_EnableAcceleratedFont(false) +{ +} + +STextRenderInfo::~STextRenderInfo() +{ +} + +SText::SText() + : SNode(GraphObjectTypes::Text) + , m_TextColor(1, 1, 1) + , m_TextTexture(NULL) +{ + m_Bounds.setEmpty(); +} + +NVBounds3 SText::GetTextBounds() const +{ + NVBounds3 retval; + retval.setEmpty(); + if (m_TextTexture != NULL) { + retval.include(m_Bounds); + } + return retval; +} diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.h new file mode 100644 index 00000000..56a2a9bf --- /dev/null +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderText.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TEXT_H +#define QT3DS_RENDER_TEXT_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderNode.h" +#include "Qt3DSRenderTextTypes.h" + +namespace qt3ds { +namespace render { + + struct SText : public SNode, public STextRenderInfo + { + // Change any of these properties and you can expect + // that the text will force an expensive re-layer and render. + // For these you need to set TextDirty. + + // These properties can change every frame with no additional cost. + QT3DSVec3 m_TextColor; + // Setup and utilized by the rendering system + NVRenderTexture2D *m_TextTexture; + STextTextureDetails m_TextTextureDetails; + // used for nv path rendering + NVRenderPathFontItem *m_PathFontItem; + NVRenderPathFontSpecification *m_PathFontDetails; + + NVBounds3 m_Bounds; + + SText(); + + NVBounds3 GetTextBounds() const; + + // Generic method used during serialization + // to remap string and object pointers + template + void Remap(TRemapperType &inRemapper) + { + SNode::Remap(inRemapper); + inRemapper.Remap(m_Text); + inRemapper.Remap(m_Font); + inRemapper.NullPtr(m_TextTexture); + inRemapper.NullPtr(m_PathFontItem); + inRemapper.NullPtr(m_PathFontDetails); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/linux/DynamicLibLoader.h b/src/Runtime/Source/runtimerender/linux/DynamicLibLoader.h new file mode 100644 index 00000000..cc5d077c --- /dev/null +++ b/src/Runtime/Source/runtimerender/linux/DynamicLibLoader.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_LINUX_DYNAMIC_LIB_LOADER_H +#define QT3DS_LINUX_DYNAMIC_LIB_LOADER_H +#include +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" + +namespace qt3ds { +namespace render { + using namespace qt3ds; + using namespace qt3ds::render; + + class CLoadedDynamicLibrary + { + void *m_DLLHandle; + CLoadedDynamicLibrary(void *hdl) + : m_DLLHandle(hdl) + { + } + CLoadedDynamicLibrary(const CLoadedDynamicLibrary &); + CLoadedDynamicLibrary &operator=(const CLoadedDynamicLibrary &); + + public: + ~CLoadedDynamicLibrary() + { + if (m_DLLHandle) + { +#ifndef _INTEGRITYPLATFORM + ::dlclose(m_DLLHandle); +#endif + } + m_DLLHandle = 0; + } + void *FindFunction(const char *name) + { +#ifndef _INTEGRITYPLATFORM + return ::dlsym(m_DLLHandle, name); +#else + qWarning() << "CLoadedDynamicLibrary::FindFunction returns NULL!"; + return NULL; +#endif + } + static CLoadedDynamicLibrary *Create(const char *inFullDllPath, NVFoundationBase &fnd) + { +#ifndef _INTEGRITYPLATFORM + void *hdl = ::dlopen(inFullDllPath, RTLD_NOW); + if (hdl == 0) { + const char *error = ::dlerror(); + qCCritical(INVALID_OPERATION, "Failed to load dynamic library %s: %s", + inFullDllPath, error); + return NULL; + } + return QT3DS_NEW(fnd.getAllocator(), CLoadedDynamicLibrary)(hdl); +#else + qWarning() << "CLoadedDynamicLibrary::Create returns NULL!"; + return NULL; +#endif + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/macos/DynamicLibLoader.h b/src/Runtime/Source/runtimerender/macos/DynamicLibLoader.h new file mode 100644 index 00000000..c968419a --- /dev/null +++ b/src/Runtime/Source/runtimerender/macos/DynamicLibLoader.h @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "linux/DynamicLibLoader.h" diff --git a/src/Runtime/Source/runtimerender/q3dsqmlrender.cpp b/src/Runtime/Source/runtimerender/q3dsqmlrender.cpp new file mode 100644 index 00000000..f1bdd4d9 --- /dev/null +++ b/src/Runtime/Source/runtimerender/q3dsqmlrender.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlrender.h" +#include "q3dsqmlstreamservice.h" +#include "render/Qt3DSRenderContext.h" + +#include +#include + +Q3DSQmlRender::Q3DSQmlRender(IQt3DSRenderContext &inRenderContext, const char *asset) + : m_RenderContext(inRenderContext) + , m_qmlStreamRenderer(nullptr) + , m_offscreenRenderType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) + , m_assetString(inRenderContext.GetStringTable().RegisterStr(asset)) + , m_callback(nullptr) + , mRefCount(0) +{ + +} + +Q3DSQmlRender::~Q3DSQmlRender() +{ + m_qmlStreamRenderer = + IQ3DSQmlStreamService::getQmlStreamService()->getRenderer(m_assetString.c_str()); + if (m_qmlStreamRenderer) + m_qmlStreamRenderer->uninitialize(); +} + +CRegisteredString Q3DSQmlRender::GetOffscreenRendererType() +{ + return m_offscreenRenderType; +} + +NVRenderTextureFormats::Enum convertTextureFormat(E_TEXTURE_FORMAT fmt) +{ + NVRenderTextureFormats::Enum ret; + + switch (fmt) { + case E_TEXTURE_RGBA8: + ret = NVRenderTextureFormats::RGBA8; + break; + default: + ret = NVRenderTextureFormats::Unknown; + break; + } + + return ret; +} + +SOffscreenRendererEnvironment Q3DSQmlRender::GetDesiredEnvironment(QT3DSVec2 inPresScale) +{ + QSize size(0, 0); + E_TEXTURE_FORMAT format = E_TEXTURE_UNKNOWN; + + if (!m_qmlStreamRenderer) + initializeRenderer(); + + if (m_qmlStreamRenderer) { + size = m_qmlStreamRenderer->getDesiredSize(); + format = m_qmlStreamRenderer->getDesiredFormat(); + } + return SOffscreenRendererEnvironment( + (QT3DSU32)(size.width() * inPresScale.x), (QT3DSU32)(size.height() * inPresScale.y), + convertTextureFormat(format), OffscreenRendererDepthValues::Depth24, false, + AAModeValues::NoAA); +} + +SOffscreenRenderFlags Q3DSQmlRender::NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, + QT3DSVec2 inPresentationScaleFactor, + const SRenderInstanceId instanceId) +{ + Q_UNUSED(inEnvironment); + Q_UNUSED(inPresentationScaleFactor); + Q_UNUSED(instanceId); + bool render = false; + if (!m_qmlStreamRenderer) + initializeRenderer(); + if (m_qmlStreamRenderer) + render = m_qmlStreamRenderer->isUpdateRequested(); + return SOffscreenRenderFlags(false, render); +} + +void Q3DSQmlRender::Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, + SScene::RenderClearCommand inColorBufferNeedsClear, + const SRenderInstanceId instanceId) +{ + Q_UNUSED(inEnvironment) + Q_UNUSED(inPresentationScaleFactor) + Q_UNUSED(inColorBufferNeedsClear) + Q_UNUSED(instanceId) + if (m_qmlStreamRenderer) { + inRenderContext.PushPropertySet(); + + m_qmlStreamRenderer->render(); + + inRenderContext.PopPropertySet(true); + + if (m_callback) + m_callback->onOffscreenRendererFrame(QString(m_assetString.c_str())); + } +} + +void Q3DSQmlRender::initializeRenderer() +{ + m_qmlStreamRenderer + = IQ3DSQmlStreamService::getQmlStreamService()->getRenderer(m_assetString.c_str()); + if (m_qmlStreamRenderer) { + if (!m_qmlStreamRenderer->initialize( + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(), + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->surface())) { + m_qmlStreamRenderer = nullptr; + } else if (m_callback) { + m_callback->onOffscreenRendererInitialized(QString(m_assetString.c_str())); + } + } +} diff --git a/src/Runtime/Source/runtimerender/q3dsqmlrender.h b/src/Runtime/Source/runtimerender/q3dsqmlrender.h new file mode 100644 index 00000000..12d459cf --- /dev/null +++ b/src/Runtime/Source/runtimerender/q3dsqmlrender.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_QML_RENDER_H +#define QT3DS_QML_RENDER_H + +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSRenderContextCore.h" + +class IQt3DS; + +using namespace qt3ds::render; + +class IQ3DSQmlStreamService; +class IQ3DSQmlStreamRenderer; + +class Q3DSQmlRender : public IOffscreenRenderer +{ +public: + Q3DSQmlRender(IQt3DSRenderContext &inRenderContext, const char *asset); + ~Q3DSQmlRender(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext.GetAllocator()) + + CRegisteredString GetOffscreenRendererType() override; + + SOffscreenRendererEnvironment GetDesiredEnvironment(QT3DSVec2 inPresentationScaleFactor) override; + + // Returns true of this object needs to be rendered, false if this object is not dirty + SOffscreenRenderFlags NeedsRender(const SOffscreenRendererEnvironment &inEnvironment, + QT3DSVec2 inPresentationScaleFactor, + const SRenderInstanceId instanceId) override; + + void Render(const SOffscreenRendererEnvironment &inEnvironment, + NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, + SScene::RenderClearCommand inColorBufferNeedsClear, + const SRenderInstanceId instanceId) override; + void RenderWithClear(const SOffscreenRendererEnvironment &/*inEnvironment*/, + NVRenderContext &/*inRenderContext*/, + QT3DSVec2 /*inPresentationScaleFactor*/, + SScene::RenderClearCommand /*inColorBufferNeedsClear*/, + QT3DSVec3 /*inclearColor*/, + const SRenderInstanceId /*instanceId*/) override {} + + IGraphObjectPickQuery *GetGraphObjectPickQuery(const SRenderInstanceId instanceId) override + { + Q_UNUSED(instanceId) + return nullptr; + } + bool Pick(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, + const SRenderInstanceId instanceId) override + { + Q_UNUSED(inMouseCoords) + Q_UNUSED(inViewportDimensions) + Q_UNUSED(instanceId) + return false; + } + void addCallback(IOffscreenRendererCallback *cb) override + { + m_callback = cb; + } + static const char *GetRendererName() { return "qml-render"; } +private: + + void initializeRenderer(); + + IQt3DSRenderContext &m_RenderContext; + IQ3DSQmlStreamRenderer *m_qmlStreamRenderer; + CRegisteredString m_offscreenRenderType; + CRegisteredString m_assetString; + IOffscreenRendererCallback *m_callback; + volatile QT3DSI32 mRefCount; +}; + +#endif diff --git a/src/Runtime/Source/runtimerender/qnx/DynamicLibLoader.h b/src/Runtime/Source/runtimerender/qnx/DynamicLibLoader.h new file mode 100644 index 00000000..c968419a --- /dev/null +++ b/src/Runtime/Source/runtimerender/qnx/DynamicLibLoader.h @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "linux/DynamicLibLoader.h" diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.cpp new file mode 100644 index 00000000..7d8054f7 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.cpp @@ -0,0 +1,530 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderableObjects.h" +#include "Qt3DSRendererImpl.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderCustomMaterialRenderContext.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderPathManager.h" +#include "Qt3DSRenderPathRenderContext.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" + +using qt3ds::foundation::CRegisteredString; + +namespace qt3ds { +namespace render { + struct SRenderableImage; + struct SShaderGeneratorGeneratedShader; + struct SSubsetRenderable; + using eastl::make_pair; + using eastl::reverse; + + STextScaleAndOffset::STextScaleAndOffset(NVRenderTexture2D &inTexture, + const STextTextureDetails &inTextDetails, + const STextRenderInfo &inInfo) + : m_TextOffset(0, 0) + , m_TextScale(1, 1) + + { + NVRenderTexture2D &theTexture = inTexture; + STextureDetails theDetails(theTexture.GetTextureDetails()); + QT3DSVec2 textDimensions(inTextDetails.m_TextWidth / 2.0f, inTextDetails.m_TextHeight / 2.0f); + textDimensions.x /= inTextDetails.m_ScaleFactor.x; + textDimensions.y /= inTextDetails.m_ScaleFactor.y; + QT3DSVec2 theTextScale(textDimensions.x, textDimensions.y); + QT3DSVec2 theTextOffset(0, 0); + + // Set the offsets to use after scaling the rect coordinates. + switch (inInfo.m_HorizontalAlignment) { + case TextHorizontalAlignment::Left: + theTextOffset[0] = theTextScale[0]; + break; + case TextHorizontalAlignment::Center: + break; + case TextHorizontalAlignment::Right: + theTextOffset[0] = -theTextScale[0]; + break; + default: + break; + } + + switch (inInfo.m_VerticalAlignment) { + case TextVerticalAlignment::Top: + theTextOffset[1] = -theTextScale[1]; + break; + case TextVerticalAlignment::Middle: + break; + case TextVerticalAlignment::Bottom: + theTextOffset[1] = theTextScale[1]; + break; + default: + break; + } + m_TextScale = theTextScale; + m_TextOffset = theTextOffset; + } + + void SSubsetRenderableBase::RenderShadowMapPass(const QT3DSVec2 &inCameraVec, + const SLight *inLight, const SCamera &inCamera, + SShadowMapEntry *inShadowMapEntry) + { + NVRenderContext &context(m_Generator.GetContext()); + SRenderableDepthPrepassShader *shader = NULL; + NVRenderInputAssembler *pIA = NULL; + + /* + if ( inLight->m_LightType == RenderLightTypes::Area ) + shader = m_Generator.GetParaboloidDepthShader( m_TessellationMode ); + else if ( inLight->m_LightType == RenderLightTypes::Directional ) + shader = m_Generator.GetOrthographicDepthShader( m_TessellationMode ); + else if ( inLight->m_LightType == RenderLightTypes::Point ) + shader = m_Generator.GetCubeShadowDepthShader( m_TessellationMode ); // This + will change to include a geometry shader pass. + */ + + if (inLight->m_LightType == RenderLightTypes::Directional) + shader = m_Generator.GetOrthographicDepthShader(m_TessellationMode); + else + shader = m_Generator.GetCubeShadowDepthShader(m_TessellationMode); + + if (shader == NULL || inShadowMapEntry == NULL) + return; + + // for phong and npatch tesselleation we need the normals too + if (m_TessellationMode == TessModeValues::NoTess + || m_TessellationMode == TessModeValues::TessLinear) + pIA = m_Subset.m_InputAssemblerDepth; + else + pIA = m_Subset.m_InputAssembler; + + QT3DSMat44 theModelViewProjection = inShadowMapEntry->m_LightVP * m_GlobalTransform; + // QT3DSMat44 theModelView = inLight->m_GlobalTransform.getInverse() * m_GlobalTransform; + + context.SetActiveShader(&shader->m_Shader); + shader->m_MVP.Set(theModelViewProjection); + shader->m_CameraPosition.Set(inCamera.m_Position); + shader->m_GlobalTransform.Set(m_GlobalTransform); + shader->m_CameraProperties.Set(inCameraVec); + /* + shader->m_CameraDirection.Set( inCamera.GetDirection() ); + + shader->m_ShadowMV[0].Set( inShadowMapEntry->m_LightCubeView[0] * m_GlobalTransform ); + shader->m_ShadowMV[1].Set( inShadowMapEntry->m_LightCubeView[1] * m_GlobalTransform ); + shader->m_ShadowMV[2].Set( inShadowMapEntry->m_LightCubeView[2] * m_GlobalTransform ); + shader->m_ShadowMV[3].Set( inShadowMapEntry->m_LightCubeView[3] * m_GlobalTransform ); + shader->m_ShadowMV[4].Set( inShadowMapEntry->m_LightCubeView[4] * m_GlobalTransform ); + shader->m_ShadowMV[5].Set( inShadowMapEntry->m_LightCubeView[5] * m_GlobalTransform ); + shader->m_Projection.Set( inCamera.m_Projection ); + */ + + // tesselation + if (m_TessellationMode != TessModeValues::NoTess) { + // set uniforms we need + shader->m_Tessellation.m_EdgeTessLevel.Set(m_Subset.m_EdgeTessFactor); + shader->m_Tessellation.m_InsideTessLevel.Set(m_Subset.m_InnerTessFactor); + // the blend value is hardcoded + shader->m_Tessellation.m_PhongBlend.Set(0.75); + // set distance range value + shader->m_Tessellation.m_DistanceRange.Set(inCameraVec); + // disable culling + shader->m_Tessellation.m_DisableCulling.Set(1.0); + } + + context.SetInputAssembler(pIA); + context.Draw(m_Subset.m_PrimitiveType, m_Subset.m_Count, m_Subset.m_Offset); + } + + void SSubsetRenderableBase::RenderDepthPass(const QT3DSVec2 &inCameraVec, + SRenderableImage *inDisplacementImage, + float inDisplacementAmount) + { + NVRenderContext &context(m_Generator.GetContext()); + SRenderableDepthPrepassShader *shader = NULL; + NVRenderInputAssembler *pIA = NULL; + SRenderableImage *displacementImage = inDisplacementImage; + + if (m_Subset.m_PrimitiveType != NVRenderDrawMode::Patches) + shader = m_Generator.GetDepthPrepassShader(displacementImage != NULL); + else + shader = m_Generator.GetDepthTessPrepassShader(m_TessellationMode, + displacementImage != NULL); + + if (shader == NULL) + return; + + // for phong and npatch tesselleation or displacement mapping we need the normals (and uv's) + // too + if ((m_TessellationMode == TessModeValues::NoTess + || m_TessellationMode == TessModeValues::TessLinear) + && !displacementImage) + pIA = m_Subset.m_InputAssemblerDepth; + else + pIA = m_Subset.m_InputAssembler; + + context.SetActiveShader(&shader->m_Shader); + context.SetCullingEnabled(true); + + shader->m_MVP.Set(m_ModelContext.m_ModelViewProjection); + + if (displacementImage) { + // setup image transform + const QT3DSMat44 &textureTransform = displacementImage->m_Image.m_TextureTransform; + const QT3DSF32 *dataPtr(textureTransform.front()); + QT3DSVec3 offsets(dataPtr[12], dataPtr[13], + displacementImage->m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() + ? 1.0f + : 0.0f); + QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); + displacementImage->m_Image.m_TextureData.m_Texture->SetTextureWrapS( + displacementImage->m_Image.m_HorizontalTilingMode); + displacementImage->m_Image.m_TextureData.m_Texture->SetTextureWrapT( + displacementImage->m_Image.m_VerticalTilingMode); + + shader->m_DisplaceAmount.Set(inDisplacementAmount); + shader->m_DisplacementProps.m_Offsets.Set(offsets); + shader->m_DisplacementProps.m_Rotations.Set(rotations); + shader->m_DisplacementProps.m_Sampler.Set( + displacementImage->m_Image.m_TextureData.m_Texture); + } + + // tesselation + if (m_TessellationMode != TessModeValues::NoTess) { + // set uniforms we need + shader->m_GlobalTransform.Set(m_GlobalTransform); + + if (m_Generator.GetLayerRenderData() && m_Generator.GetLayerRenderData()->m_Camera) + shader->m_CameraPosition.Set( + m_Generator.GetLayerRenderData()->m_Camera->GetGlobalPos()); + else if (m_Generator.GetLayerRenderData()->m_Camera) + shader->m_CameraPosition.Set(QT3DSVec3(0.0, 0.0, 1.0)); + + shader->m_Tessellation.m_EdgeTessLevel.Set(m_Subset.m_EdgeTessFactor); + shader->m_Tessellation.m_InsideTessLevel.Set(m_Subset.m_InnerTessFactor); + // the blend value is hardcoded + shader->m_Tessellation.m_PhongBlend.Set(0.75); + // set distance range value + shader->m_Tessellation.m_DistanceRange.Set(inCameraVec); + // enable culling + shader->m_Tessellation.m_DisableCulling.Set(0.0); + } + + context.SetInputAssembler(pIA); + context.Draw(m_Subset.m_PrimitiveType, m_Subset.m_Count, m_Subset.m_Offset); + } + + // An interface to the shader generator that is available to the renderables + + void SSubsetRenderable::Render(const QT3DSVec2 &inCameraVec, TShaderFeatureSet inFeatureSet) + { + NVRenderContext &context(m_Generator.GetContext()); + + SShaderGeneratorGeneratedShader *shader = m_Generator.GetShader(*this, inFeatureSet); + if (shader == NULL) + return; + + context.SetActiveShader(&shader->m_Shader); + + m_Generator.GetQt3DSContext().GetDefaultMaterialShaderGenerator().SetMaterialProperties( + shader->m_Shader, m_Material, inCameraVec, m_ModelContext.m_ModelViewProjection, + m_ModelContext.m_NormalMatrix, m_ModelContext.m_Model.m_GlobalTransform, m_FirstImage, + m_Opacity, m_Generator.GetLayerGlobalRenderProperties()); + + // tesselation + if (m_Subset.m_PrimitiveType == NVRenderDrawMode::Patches) { + shader->m_Tessellation.m_EdgeTessLevel.Set(m_Subset.m_EdgeTessFactor); + shader->m_Tessellation.m_InsideTessLevel.Set(m_Subset.m_InnerTessFactor); + // the blend value is hardcoded + shader->m_Tessellation.m_PhongBlend.Set(0.75); + // this should finally be based on some user input + shader->m_Tessellation.m_DistanceRange.Set(inCameraVec); + // enable culling + shader->m_Tessellation.m_DisableCulling.Set(0.0); + + if (m_Subset.m_WireframeMode) { + // we need the viewport matrix + NVRenderRect theViewport(context.GetViewport()); + QT3DSMat44 vpMatrix; + vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0); + vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0); + vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0); + vpMatrix.column3 = + QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X, + (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0); + + shader->m_ViewportMatrix.Set(vpMatrix); + } + } + + context.SetCullingEnabled(true); + context.SetInputAssembler(m_Subset.m_InputAssembler); + context.Draw(m_Subset.m_PrimitiveType, m_Subset.m_Count, m_Subset.m_Offset); + } + + void SSubsetRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec) + { + SRenderableImage *displacementImage = NULL; + for (SRenderableImage *theImage = m_FirstImage; + theImage != NULL && displacementImage == NULL; theImage = theImage->m_NextImage) { + if (theImage->m_MapType == ImageMapTypes::Displacement) + displacementImage = theImage; + } + SSubsetRenderableBase::RenderDepthPass(inCameraVec, displacementImage, + m_Material.m_DisplaceAmount); + } + + void STextRenderable::Render(const QT3DSVec2 &inCameraVec) + { + NVRenderContext &context(m_Generator.GetContext()); + + if (!m_Text.m_PathFontDetails) { + + STextRenderHelper theInfo = m_Generator.GetShader(*this, false); + if (theInfo.m_Shader == NULL) + return; + // All of our shaders produce premultiplied values. + qt3ds::render::NVRenderBlendFunctionArgument blendFunc( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); + + qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, + NVRenderBlendEquation::Add); + + context.SetBlendFunction(blendFunc); + context.SetBlendEquation(blendEqu); + QT3DSVec4 theColor(m_Text.m_TextColor, m_Text.m_GlobalOpacity); + + STextShader &shader(*theInfo.m_Shader); + shader.Render(*m_Text.m_TextTexture, *this, theColor, m_ModelViewProjection, + inCameraVec, context, theInfo.m_QuadInputAssembler, + theInfo.m_QuadInputAssembler.GetIndexCount(), m_Text.m_TextTextureDetails, + QT3DSVec3(0, 0, 0)); + } else { + QT3DS_ASSERT(context.IsPathRenderingSupported() && context.IsProgramPipelineSupported()); + + STextRenderHelper theInfo = m_Generator.GetShader(*this, true); + if (theInfo.m_Shader == NULL) + return; + + // All of our shaders produce premultiplied values. + qt3ds::render::NVRenderBlendFunctionArgument blendFunc( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); + + qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, + NVRenderBlendEquation::Add); + + context.SetBlendFunction(blendFunc); + context.SetBlendEquation(blendEqu); + QT3DSVec4 theColor(m_Text.m_TextColor, m_Text.m_GlobalOpacity); + + STextShader &shader(*theInfo.m_Shader); + + shader.RenderPath(*m_Text.m_PathFontItem, *m_Text.m_PathFontDetails, *this, theColor, + m_ViewProjection, m_GlobalTransform, inCameraVec, context, + m_Text.m_TextTextureDetails, QT3DSVec3(0, 0, 0)); + } + } + + void STextRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec) + { + NVRenderContext &context(m_Generator.GetContext()); + STextDepthShader *theDepthShader = m_Generator.GetTextDepthShader(); + if (theDepthShader == NULL) + return; + + if (!m_Text.m_PathFontDetails) { + // we may change stencil test state + qt3ds::render::NVRenderContextScopedProperty __stencilTest( + context, &NVRenderContext::IsStencilTestEnabled, + &NVRenderContext::SetStencilTestEnabled, true); + + NVRenderShaderProgram &theShader(theDepthShader->m_Shader); + context.SetCullingEnabled(false); + context.SetActiveShader(&theShader); + theDepthShader->m_MVP.Set(m_ModelViewProjection); + theDepthShader->m_Sampler.Set(m_Text.m_TextTexture); + const STextScaleAndOffset &theScaleAndOffset(*this); + theDepthShader->m_Dimensions.Set( + QT3DSVec4(theScaleAndOffset.m_TextScale.x, theScaleAndOffset.m_TextScale.y, + theScaleAndOffset.m_TextOffset.x, theScaleAndOffset.m_TextOffset.y)); + theDepthShader->m_CameraProperties.Set(inCameraVec); + + STextureDetails theTextureDetails = m_Text.m_TextTexture->GetTextureDetails(); + const STextTextureDetails &theTextTextureDetails(m_Text.m_TextTextureDetails); + QT3DSF32 theWidthScale = + (QT3DSF32)theTextTextureDetails.m_TextWidth / (QT3DSF32)theTextureDetails.m_Width; + QT3DSF32 theHeightScale = + (QT3DSF32)theTextTextureDetails.m_TextHeight / (QT3DSF32)theTextureDetails.m_Height; + theDepthShader->m_TextDimensions.Set( + QT3DSVec3(theWidthScale, theHeightScale, theTextTextureDetails.m_FlipY ? 1.0f : 0.0f)); + context.SetInputAssembler(&theDepthShader->m_QuadInputAssembler); + context.Draw(NVRenderDrawMode::Triangles, + theDepthShader->m_QuadInputAssembler.GetIndexCount(), 0); + } else { + qt3ds::render::NVRenderBoolOp::Enum theDepthFunction = context.GetDepthFunction(); + bool isDepthEnabled = context.IsDepthTestEnabled(); + bool isStencilEnabled = context.IsStencilTestEnabled(); + bool isDepthWriteEnabled = context.IsDepthWriteEnabled(); + qt3ds::render::NVRenderStencilFunctionArgument theArg(qt3ds::render::NVRenderBoolOp::NotEqual, + 0, 0xFF); + qt3ds::render::NVRenderStencilOperationArgument theOpArg( + qt3ds::render::NVRenderStencilOp::Keep, qt3ds::render::NVRenderStencilOp::Keep, + qt3ds::render::NVRenderStencilOp::Zero); + NVScopedRefCounted depthStencilState = + context.CreateDepthStencilState(isDepthEnabled, isDepthWriteEnabled, + theDepthFunction, false, theArg, theArg, theOpArg, + theOpArg); + + context.SetActiveShader(NULL); + context.SetCullingEnabled(false); + + context.SetDepthStencilState(depthStencilState); + + // setup transform + QT3DSMat44 offsetMatrix = QT3DSMat44::createIdentity(); + offsetMatrix.setPosition(QT3DSVec3( + m_TextOffset.x - (QT3DSF32)m_Text.m_TextTextureDetails.m_TextWidth / 2.0f, + m_TextOffset.y - (QT3DSF32)m_Text.m_TextTextureDetails.m_TextHeight / 2.0f, 0.0)); + + QT3DSMat44 pathMatrix = m_Text.m_PathFontItem->GetTransform(); + + context.SetPathProjectionMatrix(m_ViewProjection); + context.SetPathModelViewMatrix(m_GlobalTransform * offsetMatrix * pathMatrix); + + // first pass + m_Text.m_PathFontDetails->StencilFillPathInstanced(*m_Text.m_PathFontItem); + + // second pass + context.SetStencilTestEnabled(true); + m_Text.m_PathFontDetails->CoverFillPathInstanced(*m_Text.m_PathFontItem); + + context.SetStencilTestEnabled(isStencilEnabled); + context.SetDepthFunction(theDepthFunction); + } + } + + void SCustomMaterialRenderable::Render(const QT3DSVec2 & /*inCameraVec*/, + const SLayerRenderData &inLayerData, + const SLayer &inLayer, NVDataRef inLights, + const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture, + const NVRenderTexture2D *inSsaoTexture, + TShaderFeatureSet inFeatureSet) + { + IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); + SCustomMaterialRenderContext theRenderContext( + inLayer, inLayerData, inLights, inCamera, m_ModelContext.m_Model, m_Subset, + m_ModelContext.m_ModelViewProjection, m_GlobalTransform, m_ModelContext.m_NormalMatrix, + m_Material, inDepthTexture, inSsaoTexture, m_ShaderDescription, m_FirstImage, + m_Opacity); + + qt3dsContext.GetCustomMaterialSystem().RenderSubset(theRenderContext, inFeatureSet); + } + + void SCustomMaterialRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec, + const SLayer & /*inLayer*/, + NVConstDataRef /*inLights*/ + , + const SCamera & /*inCamera*/, + const NVRenderTexture2D * /*inDepthTexture*/) + { + + IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); + if (!qt3dsContext.GetCustomMaterialSystem().RenderDepthPrepass( + m_ModelContext.m_ModelViewProjection, m_Material, m_Subset)) { + SRenderableImage *displacementImage = NULL; + for (SRenderableImage *theImage = m_FirstImage; + theImage != NULL && displacementImage == NULL; theImage = theImage->m_NextImage) { + if (theImage->m_MapType == ImageMapTypes::Displacement) + displacementImage = theImage; + } + + SSubsetRenderableBase::RenderDepthPass(inCameraVec, displacementImage, + m_Material.m_DisplaceAmount); + } + } + + void SPathRenderable::RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer & /*inLayer*/, + NVConstDataRef inLights, + const SCamera &inCamera, + const NVRenderTexture2D * /*inDepthTexture*/) + { + IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); + SPathRenderContext theRenderContext( + inLights, inCamera, m_Path, m_ModelViewProjection, m_GlobalTransform, m_NormalMatrix, + m_Opacity, m_Material, m_ShaderDescription, m_FirstImage, qt3dsContext.GetWireframeMode(), + inCameraVec, false, m_IsStroke); + + qt3dsContext.GetPathManager().RenderDepthPrepass( + theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), TShaderFeatureSet()); + } + + void SPathRenderable::Render(const QT3DSVec2 &inCameraVec, const SLayer & /*inLayer*/, + NVConstDataRef inLights, const SCamera &inCamera, + const NVRenderTexture2D * /*inDepthTexture*/ + , + const NVRenderTexture2D * /*inSsaoTexture*/ + , + TShaderFeatureSet inFeatureSet) + { + IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); + SPathRenderContext theRenderContext( + inLights, inCamera, m_Path, m_ModelViewProjection, m_GlobalTransform, m_NormalMatrix, + m_Opacity, m_Material, m_ShaderDescription, m_FirstImage, qt3dsContext.GetWireframeMode(), + inCameraVec, m_RenderableFlags.HasTransparency(), m_IsStroke); + + qt3dsContext.GetPathManager().RenderPath( + theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), inFeatureSet); + } + + void SPathRenderable::RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, + const SCamera &inCamera, + SShadowMapEntry *inShadowMapEntry) + { + NVConstDataRef theLights; + IQt3DSRenderContext &qt3dsContext(m_Generator.GetQt3DSContext()); + + QT3DSMat44 theModelViewProjection = inShadowMapEntry->m_LightVP * m_GlobalTransform; + SPathRenderContext theRenderContext( + theLights, inCamera, m_Path, theModelViewProjection, m_GlobalTransform, m_NormalMatrix, + m_Opacity, m_Material, m_ShaderDescription, m_FirstImage, qt3dsContext.GetWireframeMode(), + inCameraVec, false, m_IsStroke); + + if (inLight->m_LightType != RenderLightTypes::Directional) { + qt3dsContext.GetPathManager().RenderCubeFaceShadowPass( + theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), + TShaderFeatureSet()); + } else + qt3dsContext.GetPathManager().RenderShadowMapPass( + theRenderContext, m_Generator.GetLayerGlobalRenderProperties(), + TShaderFeatureSet()); + } +} +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h new file mode 100644 index 00000000..d380b850 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h @@ -0,0 +1,431 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_IMPL_RENDERABLE_OBJECTS_H +#define QT3DS_RENDER_IMPL_RENDERABLE_OBJECTS_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSFlags.h" +#include "Qt3DSRenderModel.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderText.h" +#include "Qt3DSRenderMesh.h" +#include "Qt3DSRenderShaderKeys.h" +#include "Qt3DSRenderShaderCache.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "Qt3DSRenderableImage.h" + +namespace qt3ds { +namespace render { + + struct RenderPreparationResultFlagValues + { + enum Enum { + HasTransparency = 1 << 0, + CompletelyTransparent = 1 << 1, + Dirty = 1 << 2, + Pickable = 1 << 3, + DefaultMaterialMeshSubset = 1 << 4, + Text = 1 << 5, + Custom = 1 << 6, + CustomMaterialMeshSubset = 1 << 7, + HasRefraction = 1 << 8, + Path = 1 << 9, + ShadowCaster = 1 << 10 + }; + }; + + struct SRenderableObjectFlags : public NVFlags + { + void ClearOrSet(bool value, RenderPreparationResultFlagValues::Enum enumVal) + { + if (value) + this->operator|=(enumVal); + else + clear(enumVal); + } + + void SetHasTransparency(bool inHasTransparency) + { + ClearOrSet(inHasTransparency, RenderPreparationResultFlagValues::HasTransparency); + } + bool HasTransparency() const + { + return this->operator&(RenderPreparationResultFlagValues::HasTransparency); + } + bool HasRefraction() const + { + return this->operator&(RenderPreparationResultFlagValues::HasRefraction); + } + void SetCompletelyTransparent(bool inTransparent) + { + ClearOrSet(inTransparent, RenderPreparationResultFlagValues::CompletelyTransparent); + } + bool IsCompletelyTransparent() const + { + return this->operator&(RenderPreparationResultFlagValues::CompletelyTransparent); + } + void SetDirty(bool inDirty) + { + ClearOrSet(inDirty, RenderPreparationResultFlagValues::Dirty); + } + bool IsDirty() const { return this->operator&(RenderPreparationResultFlagValues::Dirty); } + void SetPickable(bool inPickable) + { + ClearOrSet(inPickable, RenderPreparationResultFlagValues::Pickable); + } + bool GetPickable() const + { + return this->operator&(RenderPreparationResultFlagValues::Pickable); + } + + // Mutually exclusive values + void SetDefaultMaterialMeshSubset(bool inMeshSubset) + { + ClearOrSet(inMeshSubset, RenderPreparationResultFlagValues::DefaultMaterialMeshSubset); + } + bool IsDefaultMaterialMeshSubset() const + { + return this->operator&(RenderPreparationResultFlagValues::DefaultMaterialMeshSubset); + } + + void SetCustomMaterialMeshSubset(bool inMeshSubset) + { + ClearOrSet(inMeshSubset, RenderPreparationResultFlagValues::CustomMaterialMeshSubset); + } + bool IsCustomMaterialMeshSubset() const + { + return this->operator&(RenderPreparationResultFlagValues::CustomMaterialMeshSubset); + } + + void SetText(bool inText) { ClearOrSet(inText, RenderPreparationResultFlagValues::Text); } + bool IsText() const { return this->operator&(RenderPreparationResultFlagValues::Text); } + + void SetCustom(bool inCustom) + { + ClearOrSet(inCustom, RenderPreparationResultFlagValues::Custom); + } + bool IsCustom() const { return this->operator&(RenderPreparationResultFlagValues::Custom); } + + void SetPath(bool inPath) { ClearOrSet(inPath, RenderPreparationResultFlagValues::Path); } + bool IsPath() const { return this->operator&(RenderPreparationResultFlagValues::Path); } + + void SetShadowCaster(bool inCaster) + { + ClearOrSet(inCaster, RenderPreparationResultFlagValues::ShadowCaster); + } + bool IsShadowCaster() const + { + return this->operator&(RenderPreparationResultFlagValues::ShadowCaster); + } + }; + + struct SNodeLightEntry + { + SLight *m_Light; + QT3DSU32 m_LightIndex; + SNodeLightEntry *m_NextNode; + SNodeLightEntry() + : m_Light(NULL) + , m_NextNode(NULL) + { + } + SNodeLightEntry(SLight *inLight, QT3DSU32 inLightIndex) + : m_Light(inLight) + , m_LightIndex(inLightIndex) + , m_NextNode(NULL) + { + } + }; + + DEFINE_INVASIVE_SINGLE_LIST(NodeLightEntry); + + IMPLEMENT_INVASIVE_SINGLE_LIST(NodeLightEntry, m_NextNode); + + struct SRenderableObject; + + typedef void (*TRenderFunction)(SRenderableObject &inObject, const QT3DSVec2 &inCameraProperties); + + struct SRenderableObject + { + // Variables used for picking + const QT3DSMat44 &m_GlobalTransform; + const NVBounds3 &m_Bounds; + SRenderableObjectFlags m_RenderableFlags; + // For rough sorting for transparency and for depth + QT3DSVec3 m_WorldCenterPoint; + QT3DSF32 m_CameraDistanceSq; + TessModeValues::Enum m_TessellationMode; + bool m_ShadowCaster; + // For custom renderable objects the render function must be defined + TRenderFunction m_RenderFunction; + TNodeLightEntryList m_ScopedLights; + SRenderableObject(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, + TessModeValues::Enum inTessMode = TessModeValues::NoTess, + bool inShadowCaster = true, TRenderFunction inFunction = nullptr) + + : m_GlobalTransform(inGlobalTransform) + , m_Bounds(inBounds) + , m_RenderableFlags(inFlags) + , m_WorldCenterPoint(inWorldCenterPt) + , m_CameraDistanceSq(0) + , m_TessellationMode(inTessMode) + , m_ShadowCaster(inShadowCaster) + , m_RenderFunction(inFunction) + { + } + bool operator<(SRenderableObject *inOther) const + { + return m_CameraDistanceSq < inOther->m_CameraDistanceSq; + } + }; + + typedef nvvector TRenderableObjectList; + + // Different subsets from the same model will get the same + // model context so we can generate the MVP and normal matrix once + // and only once per subset. + struct SModelContext + { + const SModel &m_Model; + QT3DSMat44 m_ModelViewProjection; + QT3DSMat33 m_NormalMatrix; + + SModelContext(const SModel &inModel, const QT3DSMat44 &inViewProjection) + : m_Model(inModel) + { + m_Model.CalculateMVPAndNormalMatrix(inViewProjection, m_ModelViewProjection, + m_NormalMatrix); + } + SModelContext(const SModelContext &inOther) + : m_Model(inOther.m_Model) + { + // The default copy constructor for these objects is pretty darn slow. + memCopy(&m_ModelViewProjection, &inOther.m_ModelViewProjection, + sizeof(m_ModelViewProjection)); + memCopy(&m_NormalMatrix, &inOther.m_NormalMatrix, sizeof(m_NormalMatrix)); + } + }; + + typedef nvvector TModelContextPtrList; + + class Qt3DSRendererImpl; + struct SLayerRenderData; + struct SShadowMapEntry; + + struct SSubsetRenderableBase : public SRenderableObject + { + Qt3DSRendererImpl &m_Generator; + const SModelContext &m_ModelContext; + SRenderSubset m_Subset; + QT3DSF32 m_Opacity; + + SSubsetRenderableBase(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SRenderSubset &subset, + const SModelContext &modelContext, QT3DSF32 inOpacity) + + : SRenderableObject(inFlags, inWorldCenterPt, modelContext.m_Model.m_GlobalTransform, + m_Subset.m_Bounds) + , m_Generator(gen) + , m_ModelContext(modelContext) + , m_Subset(subset) + , m_Opacity(inOpacity) + { + } + void RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, + const SCamera &inCamera, SShadowMapEntry *inShadowMapEntry); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec, SRenderableImage *inDisplacementImage, + float inDisplacementAmount); + }; + + /** + * A renderable that corresponds to a subset (a part of a model). + * These are created per subset per layer and are responsible for actually + * rendering this type of object. + */ + struct SSubsetRenderable : public SSubsetRenderableBase + { + const SDefaultMaterial &m_Material; + SRenderableImage *m_FirstImage; + SShaderDefaultMaterialKey m_ShaderDescription; + NVConstDataRef m_Bones; + + SSubsetRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SRenderSubset &subset, + const SDefaultMaterial &mat, const SModelContext &modelContext, + QT3DSF32 inOpacity, SRenderableImage *inFirstImage, + SShaderDefaultMaterialKey inShaderKey, + NVConstDataRef inBoneGlobals) + + : SSubsetRenderableBase(inFlags, inWorldCenterPt, gen, subset, modelContext, inOpacity) + , m_Material(mat) + , m_FirstImage(inFirstImage) + , m_ShaderDescription(inShaderKey) + , m_Bones(inBoneGlobals) + { + m_RenderableFlags.SetDefaultMaterialMeshSubset(true); + m_RenderableFlags.SetCustom(false); + m_RenderableFlags.SetText(false); + } + + void Render(const QT3DSVec2 &inCameraVec, TShaderFeatureSet inFeatureSet); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec); + + DefaultMaterialBlendMode::Enum getBlendingMode() + { + return m_Material.m_BlendMode; + } + }; + + struct SCustomMaterialRenderable : public SSubsetRenderableBase + { + const SCustomMaterial &m_Material; + SRenderableImage *m_FirstImage; + SShaderDefaultMaterialKey m_ShaderDescription; + + SCustomMaterialRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SRenderSubset &subset, + const SCustomMaterial &mat, const SModelContext &modelContext, + QT3DSF32 inOpacity, SRenderableImage *inFirstImage, + SShaderDefaultMaterialKey inShaderKey) + : SSubsetRenderableBase(inFlags, inWorldCenterPt, gen, subset, modelContext, inOpacity) + , m_Material(mat) + , m_FirstImage(inFirstImage) + , m_ShaderDescription(inShaderKey) + { + m_RenderableFlags.SetCustomMaterialMeshSubset(true); + } + + void Render(const QT3DSVec2 &inCameraVec, const SLayerRenderData &inLayerData, + const SLayer &inLayer, NVDataRef inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture, const NVRenderTexture2D *inSsaoTexture, + TShaderFeatureSet inFeatureSet); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, + NVConstDataRef inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture); + }; + + struct STextScaleAndOffset + { + QT3DSVec2 m_TextOffset; + QT3DSVec2 m_TextScale; + STextScaleAndOffset(const QT3DSVec2 &inTextOffset, const QT3DSVec2 &inTextScale) + : m_TextOffset(inTextOffset) + , m_TextScale(inTextScale) + { + } + STextScaleAndOffset(NVRenderTexture2D &inTexture, const STextTextureDetails &inTextDetails, + const STextRenderInfo &inInfo); + }; + + struct STextRenderable : public SRenderableObject, public STextScaleAndOffset + { + Qt3DSRendererImpl &m_Generator; + const SText &m_Text; + NVRenderTexture2D &m_Texture; + QT3DSMat44 m_ModelViewProjection; + QT3DSMat44 m_ViewProjection; + + STextRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SText &inText, const NVBounds3 &inBounds, + const QT3DSMat44 &inModelViewProjection, const QT3DSMat44 &inViewProjection, + NVRenderTexture2D &inTextTexture, const QT3DSVec2 &inTextOffset, + const QT3DSVec2 &inTextScale) + : SRenderableObject(inFlags, inWorldCenterPt, inText.m_GlobalTransform, inBounds) + , STextScaleAndOffset(inTextOffset, inTextScale) + , m_Generator(gen) + , m_Text(inText) + , m_Texture(inTextTexture) + , m_ModelViewProjection(inModelViewProjection) + , m_ViewProjection(inViewProjection) + { + m_RenderableFlags.SetDefaultMaterialMeshSubset(false); + m_RenderableFlags.SetCustom(false); + m_RenderableFlags.SetText(true); + } + + void Render(const QT3DSVec2 &inCameraVec); + void RenderDepthPass(const QT3DSVec2 &inCameraVec); + }; + + struct SPathRenderable : public SRenderableObject + { + Qt3DSRendererImpl &m_Generator; + SPath &m_Path; + NVBounds3 m_Bounds; + QT3DSMat44 m_ModelViewProjection; + QT3DSMat33 m_NormalMatrix; + const SGraphObject &m_Material; + QT3DSF32 m_Opacity; + SRenderableImage *m_FirstImage; + SShaderDefaultMaterialKey m_ShaderDescription; + bool m_IsStroke; + + SPathRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const QT3DSMat44 &inGlobalTransform, + NVBounds3 &inBounds, SPath &inPath, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 inNormalMat, const SGraphObject &inMaterial, QT3DSF32 inOpacity, + SShaderDefaultMaterialKey inShaderKey, bool inIsStroke) + + : SRenderableObject(inFlags, inWorldCenterPt, inGlobalTransform, m_Bounds) + , m_Generator(gen) + , m_Path(inPath) + , m_Bounds(inBounds) + , m_ModelViewProjection(inModelViewProjection) + , m_NormalMatrix(inNormalMat) + , m_Material(inMaterial) + , m_Opacity(inOpacity) + , m_FirstImage(NULL) + , m_ShaderDescription(inShaderKey) + , m_IsStroke(inIsStroke) + { + m_RenderableFlags.SetPath(true); + } + void Render(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, + NVConstDataRef inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture, const NVRenderTexture2D *inSsaoTexture, + TShaderFeatureSet inFeatureSet); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, + NVConstDataRef inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture); + + void RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, + const SCamera &inCamera, SShadowMapEntry *inShadowMapEntry); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp new file mode 100644 index 00000000..d6fb3b1b --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp @@ -0,0 +1,2014 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRender.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRendererImpl.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderImage.h" +#include "Qt3DSRenderBufferManager.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "EASTL/sort.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderPresentation.h" +#include "Qt3DSRenderEffect.h" +#include "Qt3DSRenderEffectSystem.h" +#include "Qt3DSRenderResourceManager.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "Qt3DSRenderTextTextureCache.h" +#include "Qt3DSRenderTextTextureAtlas.h" +#include "Qt3DSRenderMaterialHelpers.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderRenderList.h" +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include + +#ifdef _WIN32 +#pragma warning(disable : 4355) +#endif + +// Quick tests you can run to find performance problems + +//#define QT3DS_RENDER_DISABLE_HARDWARE_BLENDING 1 +//#define QT3DS_RENDER_DISABLE_LIGHTING 1 +//#define QT3DS_RENDER_DISABLE_TEXTURING 1 +//#define QT3DS_RENDER_DISABLE_TRANSPARENCY 1 +//#define QT3DS_RENDER_DISABLE_FRUSTUM_CULLING 1 + +// If you are fillrate bound then sorting opaque objects can help in some circumstances +//#define QT3DS_RENDER_DISABLE_OPAQUE_SORT 1 + +using qt3ds::foundation::CRegisteredString; + +namespace qt3ds { +namespace render { + + struct SRenderableImage; + struct SShaderGeneratorGeneratedShader; + struct SSubsetRenderable; + using eastl::make_pair; + using eastl::reverse; + using eastl::stable_sort; + + SEndlType Endl; + + static SRenderInstanceId combineLayerAndId(const SLayer *layer, const SRenderInstanceId id) + { + uint64_t x = (uint64_t)layer; + x += 31u * (uint64_t)id; + return (SRenderInstanceId)x; + } + + Qt3DSRendererImpl::Qt3DSRendererImpl(IQt3DSRenderContext &ctx) + : m_qt3dsContext(ctx) + , m_Context(ctx.GetRenderContext()) + , m_BufferManager(ctx.GetBufferManager()) + , m_OffscreenRenderManager(ctx.GetOffscreenRenderManager()) + , m_StringTable(IStringTable::CreateStringTable(ctx.GetAllocator())) + , m_LayerShaders(ctx.GetAllocator(), "Qt3DSRendererImpl::m_LayerShaders") + , m_Shaders(ctx.GetAllocator(), "Qt3DSRendererImpl::m_Shaders") + , m_ConstantBuffers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_ConstantBuffers") + , m_TextShader(ctx.GetAllocator()) + , m_TextPathShader(ctx.GetAllocator()) + , m_TextWidgetShader(ctx.GetAllocator()) + , m_TextOnscreenShader(ctx.GetAllocator()) +#ifdef ADVANCED_BLEND_SW_FALLBACK + , m_LayerBlendTexture(ctx.GetResourceManager()) + , m_BlendFB(NULL) +#endif + , m_InstanceRenderMap(ctx.GetAllocator(), "Qt3DSRendererImpl::m_InstanceRenderMap") + , m_LastFrameLayers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_LastFrameLayers") + , mRefCount(0) + , m_LastPickResults(ctx.GetAllocator(), "Qt3DSRendererImpl::m_LastPickResults") + , m_CurrentLayer(NULL) + , m_WidgetVertexBuffers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetVertexBuffers") + , m_WidgetIndexBuffers(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetIndexBuffers") + , m_WidgetShaders(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetShaders") + , m_WidgetInputAssembler(ctx.GetAllocator(), "Qt3DSRendererImpl::m_WidgetInputAssembler") + , m_BoneIdNodeMap(ctx.GetAllocator(), "Qt3DSRendererImpl::m_BoneIdNodeMap") + , m_PickRenderPlugins(true) + , m_LayerCachingEnabled(true) + , m_LayerGPuProfilingEnabled(false) + { + } + Qt3DSRendererImpl::~Qt3DSRendererImpl() + { + m_LayerShaders.clear(); + for (TShaderMap::iterator iter = m_Shaders.begin(), end = m_Shaders.end(); iter != end; + ++iter) + NVDelete(m_Context->GetAllocator(), iter->second); + + m_Shaders.clear(); + m_InstanceRenderMap.clear(); + m_ConstantBuffers.clear(); + } + + void Qt3DSRendererImpl::addRef() { atomicIncrement(&mRefCount); } + + void Qt3DSRendererImpl::release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Context->GetAllocator()); } + + void Qt3DSRendererImpl::ChildrenUpdated(SNode &inParent) + { + if (inParent.m_Type == GraphObjectTypes::Layer) { + TInstanceRenderMap::iterator theIter = + m_InstanceRenderMap.find(static_cast(&inParent)); + if (theIter != m_InstanceRenderMap.end()) { + theIter->second->m_CamerasAndLights.clear(); + theIter->second->m_RenderableNodes.clear(); + } + } else if (inParent.m_Parent) + ChildrenUpdated(*inParent.m_Parent); + } + + QT3DSF32 Qt3DSRendererImpl::GetTextScale(const SText &inText) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inText); + if (theData) + return theData->m_TextScale; + return 1.0f; + } + + static inline SLayer *GetNextLayer(SLayer &inLayer) + { + if (inLayer.m_NextSibling && inLayer.m_NextSibling->m_Type == GraphObjectTypes::Layer) + return static_cast(inLayer.m_NextSibling); + return NULL; + } + + static inline void MaybePushLayer(SLayer &inLayer, nvvector &outLayerList) + { + inLayer.CalculateGlobalVariables(); + if (inLayer.m_Flags.IsGloballyActive() && inLayer.m_Flags.IsLayerRenderToTarget()) + outLayerList.push_back(&inLayer); + } + static void BuildRenderableLayers(SLayer &inLayer, nvvector &renderableLayers, + bool inRenderSiblings) + { + MaybePushLayer(inLayer, renderableLayers); + if (inRenderSiblings) { + for (SLayer *theNextLayer = GetNextLayer(inLayer); theNextLayer; + theNextLayer = GetNextLayer(*theNextLayer)) + MaybePushLayer(*theNextLayer, renderableLayers); + } + } + + bool Qt3DSRendererImpl::PrepareLayerForRender(SLayer &inLayer, + const QT3DSVec2 &inViewportDimensions, + bool inRenderSiblings, + const SRenderInstanceId id) + { + (void)inViewportDimensions; + nvvector renderableLayers(m_qt3dsContext.GetPerFrameAllocator(), "LayerVector"); + // Found by fair roll of the dice. + renderableLayers.reserve(4); + + BuildRenderableLayers(inLayer, renderableLayers, inRenderSiblings); + + bool retval = false; + + for (nvvector::reverse_iterator iter = renderableLayers.rbegin(), + end = renderableLayers.rend(); + iter != end; ++iter) { + // Store the previous state of if we were rendering a layer. + SLayer *theLayer = *iter; + SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id); + + if (theRenderData) { + theRenderData->PrepareForRender(); + retval = retval || theRenderData->m_LayerPrepResult->m_Flags.WasDirty(); + } else { + QT3DS_ASSERT(false); + } + } + + return retval; + } + + void Qt3DSRendererImpl::RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + bool clear, QT3DSVec3 clearColor, bool inRenderSiblings, + const SRenderInstanceId id) + { + (void)inViewportDimensions; + nvvector renderableLayers(m_qt3dsContext.GetPerFrameAllocator(), "LayerVector"); + // Found by fair roll of the dice. + renderableLayers.reserve(4); + + BuildRenderableLayers(inLayer, renderableLayers, inRenderSiblings); + + NVRenderContext &theRenderContext(m_qt3dsContext.GetRenderContext()); + qt3ds::render::NVRenderFrameBuffer *theFB = theRenderContext.GetRenderTarget(); + for (nvvector::reverse_iterator iter = renderableLayers.rbegin(), + end = renderableLayers.rend(); + iter != end; ++iter) { + SLayer *theLayer = *iter; + SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id); + SLayerRenderPreparationResult &prepRes(*theRenderData->m_LayerPrepResult); + LayerBlendTypes::Enum layerBlend = prepRes.GetLayer()->GetLayerBlend(); +#ifdef ADVANCED_BLEND_SW_FALLBACK + if ((layerBlend == LayerBlendTypes::Overlay || + layerBlend == LayerBlendTypes::ColorBurn || + layerBlend == LayerBlendTypes::ColorDodge) && + !theRenderContext.IsAdvancedBlendHwSupported() && + !theRenderContext.IsAdvancedBlendHwSupportedKHR()) { + // Create and set up FBO and texture for advanced blending SW fallback + NVRenderRect viewport = theRenderContext.GetViewport(); + m_LayerBlendTexture.EnsureTexture(viewport.m_Width + viewport.m_X, + viewport.m_Height + viewport.m_Y, + NVRenderTextureFormats::RGBA8); + if (m_BlendFB == NULL) + m_BlendFB = theRenderContext.CreateFrameBuffer(); + m_BlendFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerBlendTexture); + theRenderContext.SetRenderTarget(m_BlendFB); + theRenderContext.SetScissorTestEnabled(false); + QT3DSVec4 color(0.0f, 0.0f, 0.0f, 0.0f); + if (clear) { + color.x = clearColor.x; + color.y = clearColor.y; + color.z = clearColor.z; + color.w = 1.0f; + } + QT3DSVec4 origColor = theRenderContext.GetClearColor(); + theRenderContext.SetClearColor(color); + theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); + theRenderContext.SetClearColor(origColor); + theRenderContext.SetRenderTarget(theFB); + break; + } else { + m_LayerBlendTexture.ReleaseTexture(); + } +#endif + } + for (nvvector::reverse_iterator iter = renderableLayers.rbegin(), + end = renderableLayers.rend(); + iter != end; ++iter) { + // Store the previous state of if we were rendering a layer. + SLayer *theLayer = *iter; + SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id); + + if (theRenderData) { + if (theRenderData->m_LayerPrepResult->IsLayerVisible()) + theRenderData->RunnableRenderToViewport(theFB); + } else { + QT3DS_ASSERT(false); + } + } + } + + SLayer *Qt3DSRendererImpl::GetLayerForNode(const SNode &inNode) const + { + if (inNode.m_Type == GraphObjectTypes::Layer) { + return &const_cast(static_cast(inNode)); + } + if (inNode.m_Parent) + return GetLayerForNode(*inNode.m_Parent); + return NULL; + } + + SLayerRenderData *Qt3DSRendererImpl::GetOrCreateLayerRenderDataForNode(const SNode &inNode, + const SRenderInstanceId id) + { + const SLayer *theLayer = GetLayerForNode(inNode); + if (theLayer) { + TInstanceRenderMap::const_iterator theIter + = m_InstanceRenderMap.find(combineLayerAndId(theLayer, id)); + if (theIter != m_InstanceRenderMap.end()) + return const_cast(theIter->second.mPtr); + + SLayerRenderData *theRenderData = QT3DS_NEW(m_Context->GetAllocator(), SLayerRenderData)( + const_cast(*theLayer), *this); + m_InstanceRenderMap.insert(make_pair(combineLayerAndId(theLayer, id), theRenderData)); + + // create a profiler if enabled + if (IsLayerGpuProfilingEnabled() && theRenderData) + theRenderData->CreateGpuProfiler(); + + return theRenderData; + } + return NULL; + } + + SCamera *Qt3DSRendererImpl::GetCameraForNode(const SNode &inNode) const + { + SLayerRenderData *theLayer = + const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); + if (theLayer) + return theLayer->m_Camera; + return NULL; + } + + Option Qt3DSRendererImpl::GetCameraBounds(const SGraphObject &inObject) + { + if (GraphObjectTypes::IsNodeType(inObject.m_Type)) { + const SNode &theNode = static_cast(inObject); + SLayerRenderData *theLayer = GetOrCreateLayerRenderDataForNode(theNode); + if (theLayer->GetOffscreenRenderer() == false) { + SCamera *theCamera = theLayer->m_Camera; + if (theCamera) + return theCamera->GetCameraBounds( + theLayer->m_LayerPrepResult->GetLayerToPresentationViewport(), + theLayer->m_LayerPrepResult->GetPresentationDesignDimensions()); + } + } + return Option(); + } + + void Qt3DSRendererImpl::DrawScreenRect(NVRenderRectF inRect, const QT3DSVec3 &inColor) + { + SCamera theScreenCamera; + theScreenCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + NVRenderRectF theViewport(m_Context->GetViewport()); + theScreenCamera.m_Flags.SetOrthographic(true); + theScreenCamera.CalculateGlobalVariables(theViewport, + QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); + GenerateXYQuad(); + if (!m_ScreenRectShader) { + IShaderProgramGenerator &theGenerator(GetProgramGenerator()); + theGenerator.BeginProgram(); + IShaderStageGenerator &vertexGenerator( + *theGenerator.GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *theGenerator.GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddUniform("rectangle_dims", "vec3"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append( + "\tgl_Position = model_view_projection * vec4(attr_pos * rectangle_dims, 1.0);"); + vertexGenerator.Append("}"); + fragmentGenerator.AddUniform("output_color", "vec3"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tgl_FragColor.rgb = output_color;"); + fragmentGenerator.Append("\tgl_FragColor.a = 1.0;"); + fragmentGenerator.Append("}"); + // No flags enabled + m_ScreenRectShader = theGenerator.CompileGeneratedShader( + "DrawScreenRect", SShaderCacheProgramFlags(), TShaderFeatureSet()); + } + if (m_ScreenRectShader) { + // Fudge the rect by one pixel to ensure we see all the corners. + if (inRect.m_Width > 1) + inRect.m_Width -= 1; + if (inRect.m_Height > 1) + inRect.m_Height -= 1; + inRect.m_X += 1; + inRect.m_Y += 1; + // Figure out the rect center. + SNode theNode; + + QT3DSVec2 rectGlobalCenter = inRect.Center(); + QT3DSVec2 rectCenter(theViewport.ToNormalizedRectRelative(rectGlobalCenter)); + theNode.m_Position.x = rectCenter.x; + theNode.m_Position.y = rectCenter.y; + theNode.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + theNode.CalculateGlobalVariables(); + QT3DSMat44 theViewProjection; + theScreenCamera.CalculateViewProjectionMatrix(theViewProjection); + QT3DSMat44 theMVP; + QT3DSMat33 theNormal; + theNode.CalculateMVPAndNormalMatrix(theViewProjection, theMVP, theNormal); + m_Context->SetBlendingEnabled(false); + m_Context->SetDepthWriteEnabled(false); + m_Context->SetDepthTestEnabled(false); + m_Context->SetCullingEnabled(false); + m_Context->SetActiveShader(m_ScreenRectShader); + m_ScreenRectShader->SetPropertyValue("model_view_projection", theMVP); + m_ScreenRectShader->SetPropertyValue("output_color", inColor); + m_ScreenRectShader->SetPropertyValue( + "rectangle_dims", QT3DSVec3(inRect.m_Width / 2.0f, inRect.m_Height / 2.0f, 0.0f)); + } + if (!m_RectInputAssembler) { + QT3DS_ASSERT(m_QuadVertexBuffer); + QT3DSU8 indexData[] = { 0, 1, 1, 2, 2, 3, 3, 0 }; + + m_RectIndexBuffer = m_Context->CreateIndexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, + qt3ds::render::NVRenderComponentTypes::QT3DSU8, sizeof(indexData), + toConstDataRef(indexData, sizeof(indexData))); + + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + }; + + // create our attribute layout + m_RectAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 1)); + + QT3DSU32 strides = m_QuadVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_RectInputAssembler = m_Context->CreateInputAssembler( + m_RectAttribLayout, toConstDataRef(&m_QuadVertexBuffer.mPtr, 1), m_RectIndexBuffer, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + + m_Context->SetInputAssembler(m_RectInputAssembler); + m_Context->Draw(NVRenderDrawMode::Lines, m_RectIndexBuffer->GetNumIndices(), 0); + } + + void Qt3DSRendererImpl::SetupWidgetLayer() + { + NVRenderContext &theContext = m_qt3dsContext.GetRenderContext(); + + if (!m_WidgetTexture) { + IResourceManager &theManager = m_qt3dsContext.GetResourceManager(); + m_WidgetTexture = theManager.AllocateTexture2D(m_BeginFrameViewport.m_Width, + m_BeginFrameViewport.m_Height, + NVRenderTextureFormats::RGBA8); + m_WidgetFBO = theManager.AllocateFrameBuffer(); + m_WidgetFBO->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer(*m_WidgetTexture)); + theContext.SetRenderTarget(m_WidgetFBO); + + // NVRenderRect theScissorRect( 0, 0, m_BeginFrameViewport.m_Width, + // m_BeginFrameViewport.m_Height ); + // NVRenderContextScopedProperty __scissorRect( theContext, + // &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect, theScissorRect ); + qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled, false); + m_Context->SetClearColor(QT3DSVec4(0, 0, 0, 0)); + m_Context->Clear(NVRenderClearValues::Color); + + } else + theContext.SetRenderTarget(m_WidgetFBO); + } + + void Qt3DSRendererImpl::BeginFrame() + { + for (QT3DSU32 idx = 0, end = m_LastFrameLayers.size(); idx < end; ++idx) + m_LastFrameLayers[idx]->ResetForFrame(); + m_LastFrameLayers.clear(); + m_BeginFrameViewport = m_qt3dsContext.GetRenderList().GetViewport(); + } + void Qt3DSRendererImpl::EndFrame() + { + if (m_WidgetTexture) { + using qt3ds::render::NVRenderContextScopedProperty; + // Releasing the widget FBO can set it as the active frame buffer. + NVRenderContextScopedProperty __fbo( + *m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + STextureDetails theDetails = m_WidgetTexture->GetTextureDetails(); + m_Context->SetBlendingEnabled(true); + // Colors are expected to be non-premultiplied, so we premultiply alpha into them at + // this point. + m_Context->SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); + m_Context->SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); + + m_Context->SetDepthTestEnabled(false); + m_Context->SetScissorTestEnabled(false); + m_Context->SetViewport(m_BeginFrameViewport); + SCamera theCamera; + theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + theCamera.m_Flags.SetOrthographic(true); + QT3DSVec2 theTextureDims((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height); + theCamera.CalculateGlobalVariables( + NVRenderRect(0, 0, theDetails.m_Width, theDetails.m_Height), theTextureDims); + QT3DSMat44 theViewProj; + theCamera.CalculateViewProjectionMatrix(theViewProj); + RenderQuad(theTextureDims, theViewProj, *m_WidgetTexture); + + IResourceManager &theManager(m_qt3dsContext.GetResourceManager()); + theManager.Release(*m_WidgetFBO); + theManager.Release(*m_WidgetTexture); + m_WidgetTexture = NULL; + m_WidgetFBO = NULL; + } + } + + inline bool PickResultLessThan(const Qt3DSRenderPickResult &lhs, const Qt3DSRenderPickResult &rhs) + { + return FloatLessThan(lhs.m_CameraDistanceSq, rhs.m_CameraDistanceSq); + } + + inline QT3DSF32 ClampUVCoord(QT3DSF32 inUVCoord, NVRenderTextureCoordOp::Enum inCoordOp) + { + if (inUVCoord > 1.0f || inUVCoord < 0.0f) { + switch (inCoordOp) { + default: + QT3DS_ASSERT(false); + break; + case NVRenderTextureCoordOp::ClampToEdge: + inUVCoord = NVMin(inUVCoord, 1.0f); + inUVCoord = NVMax(inUVCoord, 0.0f); + break; + case NVRenderTextureCoordOp::Repeat: { + QT3DSF32 multiplier = inUVCoord > 0.0f ? 1.0f : -1.0f; + QT3DSF32 clamp = fabs(inUVCoord); + clamp = clamp - floor(clamp); + if (multiplier < 0) + inUVCoord = 1.0f - clamp; + else + inUVCoord = clamp; + } break; + case NVRenderTextureCoordOp::MirroredRepeat: { + QT3DSF32 multiplier = inUVCoord > 0.0f ? 1.0f : -1.0f; + QT3DSF32 clamp = fabs(inUVCoord); + if (multiplier > 0.0f) + clamp -= 1.0f; + QT3DSU32 isMirrored = ((QT3DSU32)clamp) % 2 == 0; + QT3DSF32 remainder = clamp - floor(clamp); + inUVCoord = remainder; + if (isMirrored) { + if (multiplier > 0.0f) + inUVCoord = 1.0f - inUVCoord; + } else { + if (multiplier < 0.0f) + inUVCoord = 1.0f - remainder; + } + } break; + } + } + return inUVCoord; + } + + static eastl::pair + GetMouseCoordsAndViewportFromSubObject(QT3DSVec2 inLocalHitUVSpace, + Qt3DSRenderPickSubResult &inSubResult) + { + QT3DSMat44 theTextureMatrix(inSubResult.m_TextureMatrix); + QT3DSVec3 theNewUVCoords( + theTextureMatrix.transform(QT3DSVec3(inLocalHitUVSpace.x, inLocalHitUVSpace.y, 0))); + theNewUVCoords.x = ClampUVCoord(theNewUVCoords.x, inSubResult.m_HorizontalTilingMode); + theNewUVCoords.y = ClampUVCoord(theNewUVCoords.y, inSubResult.m_VerticalTilingMode); + QT3DSVec2 theViewportDimensions = + QT3DSVec2((QT3DSF32)inSubResult.m_ViewportWidth, (QT3DSF32)inSubResult.m_ViewportHeight); + QT3DSVec2 theMouseCoords(theNewUVCoords.x * theViewportDimensions.x, + (1.0f - theNewUVCoords.y) * theViewportDimensions.y); + + return eastl::make_pair(theMouseCoords, theViewportDimensions); + } + + SPickResultProcessResult Qt3DSRendererImpl::ProcessPickResultList(bool inPickEverything) + { + if (m_LastPickResults.empty()) + return SPickResultProcessResult(); + // Things are rendered in a particular order and we need to respect that ordering. + eastl::stable_sort(m_LastPickResults.begin(), m_LastPickResults.end(), PickResultLessThan); + + // We need to pick against sub objects basically somewhat recursively + // but if we don't hit any sub objects and the parent isn't pickable then + // we need to move onto the next item in the list. + // We need to keep in mind that theQuery->Pick will enter this method in a later + // stack frame so *if* we get to sub objects we need to pick against them but if the pick + // completely misses *and* the parent object locally pickable is false then we need to move + // onto the next object. + + QT3DSU32 maxPerFrameAllocationPickResultCount = + SFastAllocator<>::SlabSize / sizeof(Qt3DSRenderPickResult); + QT3DSU32 numToCopy = + NVMin(maxPerFrameAllocationPickResultCount, (QT3DSU32)m_LastPickResults.size()); + QT3DSU32 numCopyBytes = numToCopy * sizeof(Qt3DSRenderPickResult); + Qt3DSRenderPickResult *thePickResults = reinterpret_cast( + GetPerFrameAllocator().allocate(numCopyBytes, "tempPickData", __FILE__, __LINE__)); + memCopy(thePickResults, m_LastPickResults.data(), numCopyBytes); + m_LastPickResults.clear(); + bool foundValidResult = false; + SPickResultProcessResult thePickResult(thePickResults[0]); + for (size_t idx = 0; idx < numToCopy && foundValidResult == false; ++idx) { + thePickResult = thePickResults[idx]; + // Here we do a hierarchy. Picking against sub objects takes precedence. + // If picking against the sub object doesn't return a valid result *and* + // the current object isn't globally pickable then we move onto the next object returned + // by the pick query. + if (thePickResult.m_HitObject != NULL && thePickResult.m_FirstSubObject != NULL + && m_PickRenderPlugins) { + QT3DSVec2 theUVCoords(thePickResult.m_LocalUVCoords.x, + thePickResult.m_LocalUVCoords.y); + IOffscreenRenderer *theSubRenderer(thePickResult.m_FirstSubObject->m_SubRenderer); + eastl::pair mouseAndViewport = + GetMouseCoordsAndViewportFromSubObject(theUVCoords, + *thePickResult.m_FirstSubObject); + QT3DSVec2 theMouseCoords = mouseAndViewport.first; + QT3DSVec2 theViewportDimensions = mouseAndViewport.second; + IGraphObjectPickQuery *theQuery = theSubRenderer->GetGraphObjectPickQuery(this); + if (theQuery) { + Qt3DSRenderPickResult theInnerPickResult = + theQuery->Pick(theMouseCoords, theViewportDimensions, inPickEverything); + if (theInnerPickResult.m_HitObject) { + thePickResult = theInnerPickResult; + thePickResult.m_OffscreenRenderer = theSubRenderer; + foundValidResult = true; + thePickResult.m_WasPickConsumed = true; + } else if (GraphObjectTypes::IsNodeType(thePickResult.m_HitObject->m_Type)) { + const SNode *theNode = + static_cast(thePickResult.m_HitObject); + if (theNode->m_Flags.IsGloballyPickable() == true) { + foundValidResult = true; + thePickResult.m_WasPickConsumed = true; + } + } + } else { + // If the sub renderer doesn't consume the pick then we return the picked object + // itself. So no matter what, if we get to here the pick was consumed. + thePickResult.m_WasPickConsumed = true; + bool wasPickConsumed = + theSubRenderer->Pick(theMouseCoords, theViewportDimensions, this); + if (wasPickConsumed) { + thePickResult.m_HitObject = NULL; + foundValidResult = true; + } + } + } else { + foundValidResult = true; + thePickResult.m_WasPickConsumed = true; + } + } + return thePickResult; + } + + Qt3DSRenderPickResult Qt3DSRendererImpl::Pick(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, bool inPickSiblings, + bool inPickEverything, const SRenderInstanceId id) + { + m_LastPickResults.clear(); + + SLayer *theLayer = &inLayer; + // Stepping through how the original runtime did picking it picked layers in order + // stopping at the first hit. So objects on the top layer had first crack at the pick + // vector itself. + do { + if (theLayer->m_Flags.IsActive()) { + TInstanceRenderMap::iterator theIter + = m_InstanceRenderMap.find(combineLayerAndId(theLayer, id)); + if (theIter != m_InstanceRenderMap.end()) { + m_LastPickResults.clear(); + GetLayerHitObjectList(*theIter->second, inViewportDimensions, inMouseCoords, + inPickEverything, m_LastPickResults, + GetPerFrameAllocator()); + SPickResultProcessResult retval(ProcessPickResultList(inPickEverything)); + if (retval.m_WasPickConsumed) + return retval; + } else { + // QT3DS_ASSERT( false ); + } + } + + if (inPickSiblings) + theLayer = GetNextLayer(*theLayer); + else + theLayer = NULL; + } while (theLayer != NULL); + + return Qt3DSRenderPickResult(); + } + + static inline Option IntersectRayWithNode(const SNode &inNode, + SRenderableObject &inRenderableObject, + const SRay &inPickRay) + { + if (inRenderableObject.m_RenderableFlags.IsText()) { + STextRenderable &theRenderable = static_cast(inRenderableObject); + if (&theRenderable.m_Text == &inNode) + return inPickRay.GetRelativeXY(inRenderableObject.m_GlobalTransform, + inRenderableObject.m_Bounds); + } else if (inRenderableObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) { + SSubsetRenderable &theRenderable = static_cast(inRenderableObject); + if (&theRenderable.m_ModelContext.m_Model == &inNode) + return inPickRay.GetRelativeXY(inRenderableObject.m_GlobalTransform, + inRenderableObject.m_Bounds); + } else if (inRenderableObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { + SCustomMaterialRenderable &theRenderable = + static_cast(inRenderableObject); + if (&theRenderable.m_ModelContext.m_Model == &inNode) + return inPickRay.GetRelativeXY(inRenderableObject.m_GlobalTransform, + inRenderableObject.m_Bounds); + } else { + QT3DS_ASSERT(false); + } + return Empty(); + } + + static inline Qt3DSRenderPickSubResult ConstructSubResult(SImage &inImage) + { + STextureDetails theDetails = inImage.m_TextureData.m_Texture->GetTextureDetails(); + return Qt3DSRenderPickSubResult(*inImage.m_LastFrameOffscreenRenderer, + inImage.m_TextureTransform, inImage.m_HorizontalTilingMode, + inImage.m_VerticalTilingMode, theDetails.m_Width, + theDetails.m_Height); + } + + Option Qt3DSRendererImpl::FacePosition(SNode &inNode, NVBounds3 inBounds, + const QT3DSMat44 &inGlobalTransform, + const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, + NVDataRef inMapperObjects, + SBasisPlanes::Enum inPlane) + { + SLayerRenderData *theLayerData = GetOrCreateLayerRenderDataForNode(inNode); + if (theLayerData == NULL) + return Empty(); + // This function assumes the layer was rendered to the scene itself. There is another + // function + // for completely offscreen layers that don't get rendered to the scene. + bool wasRenderToTarget(theLayerData->m_Layer.m_Flags.IsLayerRenderToTarget()); + if (wasRenderToTarget == false || theLayerData->m_Camera == NULL + || theLayerData->m_LayerPrepResult.hasValue() == false + || theLayerData->m_LastFrameOffscreenRenderer.mPtr != NULL) + return Empty(); + + QT3DSVec2 theMouseCoords(inMouseCoords); + QT3DSVec2 theViewportDimensions(inViewportDimensions); + + for (QT3DSU32 idx = 0, end = inMapperObjects.size(); idx < end; ++idx) { + SGraphObject ¤tObject = *inMapperObjects[idx]; + if (currentObject.m_Type == GraphObjectTypes::Layer) { + // The layer knows its viewport so it can take the information directly. + // This is extremely counter intuitive but a good sign. + } else if (currentObject.m_Type == GraphObjectTypes::Image) { + SImage &theImage = static_cast(currentObject); + SModel *theParentModel = NULL; + if (theImage.m_Parent + && theImage.m_Parent->m_Type == GraphObjectTypes::DefaultMaterial) { + SDefaultMaterial *theMaterial = + static_cast(theImage.m_Parent); + if (theMaterial) { + theParentModel = theMaterial->m_Parent; + } + } + if (theParentModel == NULL) { + QT3DS_ASSERT(false); + return Empty(); + } + NVBounds3 theModelBounds = theParentModel->GetBounds( + GetQt3DSContext().GetBufferManager(), GetQt3DSContext().GetPathManager(), false); + + if (theModelBounds.isEmpty()) { + QT3DS_ASSERT(false); + return Empty(); + } + Option relativeHit = + FacePosition(*theParentModel, theModelBounds, theParentModel->m_GlobalTransform, + theViewportDimensions, theMouseCoords, NVDataRef(), + SBasisPlanes::XY); + if (relativeHit.isEmpty()) { + return Empty(); + } + Qt3DSRenderPickSubResult theResult = ConstructSubResult(theImage); + QT3DSVec2 hitInUVSpace = (*relativeHit) + QT3DSVec2(.5f, .5f); + eastl::pair mouseAndViewport = + GetMouseCoordsAndViewportFromSubObject(hitInUVSpace, theResult); + theMouseCoords = mouseAndViewport.first; + theViewportDimensions = mouseAndViewport.second; + } + } + + Option theHitRay = theLayerData->m_LayerPrepResult->GetPickRay( + theMouseCoords, theViewportDimensions, false); + if (theHitRay.hasValue() == false) + return Empty(); + + // Scale the mouse coords to change them into the camera's numerical space. + SRay thePickRay = *theHitRay; + Option newValue = thePickRay.GetRelative(inGlobalTransform, inBounds, inPlane); + return newValue; + } + + Qt3DSRenderPickResult + Qt3DSRendererImpl::PickOffscreenLayer(SLayer &/*inLayer*/, const QT3DSVec2 & /*inViewportDimensions*/ + , + const QT3DSVec2 & /*inMouseCoords*/ + , + bool /*inPickEverything*/) + { + return Qt3DSRenderPickResult(); + } + + QT3DSVec3 Qt3DSRendererImpl::UnprojectToPosition(SNode &inNode, QT3DSVec3 &inPosition, + const QT3DSVec2 &inMouseVec) const + { + // Translate mouse into layer's coordinates + SLayerRenderData *theData = + const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); + if (theData == NULL || theData->m_Camera == NULL) { + return QT3DSVec3(0, 0, 0); + } // QT3DS_ASSERT( false ); return QT3DSVec3(0,0,0); } + + QSize theWindow = m_qt3dsContext.GetWindowDimensions(); + QT3DSVec2 theDims((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()); + + SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); + SRay theRay = thePrepResult.GetPickRay(inMouseVec, theDims, true); + + return theData->m_Camera->UnprojectToPosition(inPosition, theRay); + } + + QT3DSVec3 Qt3DSRendererImpl::UnprojectWithDepth(SNode &inNode, QT3DSVec3 &, + const QT3DSVec3 &inMouseVec) const + { + // Translate mouse into layer's coordinates + SLayerRenderData *theData = + const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); + if (theData == NULL || theData->m_Camera == NULL) { + return QT3DSVec3(0, 0, 0); + } // QT3DS_ASSERT( false ); return QT3DSVec3(0,0,0); } + + // Flip the y into gl coordinates from window coordinates. + QT3DSVec2 theMouse(inMouseVec.x, inMouseVec.y); + NVReal theDepth = inMouseVec.z; + + SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); + QSize theWindow = m_qt3dsContext.GetWindowDimensions(); + SRay theRay = thePrepResult.GetPickRay( + theMouse, QT3DSVec2((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()), true); + QT3DSVec3 theTargetPosition = theRay.m_Origin + theRay.m_Direction * theDepth; + if (inNode.m_Parent != NULL && inNode.m_Parent->m_Type != GraphObjectTypes::Layer) + theTargetPosition = + inNode.m_Parent->m_GlobalTransform.getInverse().transform(theTargetPosition); + // Our default global space is right handed, so if you are left handed z means something + // opposite. + if (inNode.m_Flags.IsLeftHanded()) + theTargetPosition.z *= -1; + return theTargetPosition; + } + + QT3DSVec3 Qt3DSRendererImpl::ProjectPosition(SNode &inNode, const QT3DSVec3 &inPosition) const + { + // Translate mouse into layer's coordinates + SLayerRenderData *theData = + const_cast(*this).GetOrCreateLayerRenderDataForNode(inNode); + if (theData == NULL || theData->m_Camera == NULL) { + return QT3DSVec3(0, 0, 0); + } + + QT3DSMat44 viewProj; + theData->m_Camera->CalculateViewProjectionMatrix(viewProj); + QT3DSVec4 projPos = viewProj.transform(QT3DSVec4(inPosition, 1.0f)); + projPos.x /= projPos.w; + projPos.y /= projPos.w; + + NVRenderRectF theViewport = theData->m_LayerPrepResult->GetLayerToPresentationViewport(); + QT3DSVec2 theDims((QT3DSF32)theViewport.m_Width, (QT3DSF32)theViewport.m_Height); + projPos.x += 1.0; + projPos.y += 1.0; + projPos.x *= 0.5; + projPos.y *= 0.5; + QT3DSVec3 cameraToObject = theData->m_Camera->GetGlobalPos() - inPosition; + projPos.z = sqrtf(cameraToObject.dot(cameraToObject)); + QT3DSVec3 mouseVec = QT3DSVec3(projPos.x, projPos.y, projPos.z); + mouseVec.x *= theDims.x; + mouseVec.y *= theDims.y; + + mouseVec.x += theViewport.m_X; + mouseVec.y += theViewport.m_Y; + + // Flip the y into window coordinates so it matches the mouse. + QSize theWindow = m_qt3dsContext.GetWindowDimensions(); + mouseVec.y = theWindow.height() - mouseVec.y; + + return mouseVec; + } + + Option Qt3DSRendererImpl::GetLayerPickSetup(SLayer &inLayer, + const QT3DSVec2 &inMouseCoords, + const QSize &inPickDims) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); + if (theData == NULL || theData->m_Camera == NULL) { + QT3DS_ASSERT(false); + return Empty(); + } + QSize theWindow = m_qt3dsContext.GetWindowDimensions(); + QT3DSVec2 theDims((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()); + // The mouse is relative to the layer + Option theLocalMouse = GetLayerMouseCoords(*theData, inMouseCoords, theDims, false); + if (theLocalMouse.hasValue() == false) { + return Empty(); + } + + SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); + if (thePrepResult.GetCamera() == NULL) { + return Empty(); + } + // Perform gluPickMatrix and pre-multiply it into the view projection + QT3DSMat44 theTransScale(QT3DSMat44::createIdentity()); + SCamera &theCamera(*thePrepResult.GetCamera()); + + NVRenderRectF layerToPresentation = thePrepResult.GetLayerToPresentationViewport(); + // Offsetting is already taken care of in the camera's projection. + // All we need to do is to scale and translate the image. + layerToPresentation.m_X = 0; + layerToPresentation.m_Y = 0; + QT3DSVec2 theMouse(*theLocalMouse); + // The viewport will need to center at this location + QT3DSVec2 viewportDims((QT3DSF32)inPickDims.width(), (QT3DSF32)inPickDims.height()); + QT3DSVec2 bottomLeft = + QT3DSVec2(theMouse.x - viewportDims.x / 2.0f, theMouse.y - viewportDims.y / 2.0f); + // For some reason, and I haven't figured out why yet, the offsets need to be backwards for + // this to work. + // bottomLeft.x = layerToPresentation.m_Width - bottomLeft.x; + // bottomLeft.y = layerToPresentation.m_Height - bottomLeft.y; + // Virtual rect is relative to the layer. + NVRenderRectF thePickRect(bottomLeft.x, bottomLeft.y, viewportDims.x, viewportDims.y); + QT3DSMat44 projectionPremult(QT3DSMat44::createIdentity()); + projectionPremult = render::NVRenderContext::ApplyVirtualViewportToProjectionMatrix( + projectionPremult, layerToPresentation, thePickRect); + projectionPremult = projectionPremult.getInverse(); + + QT3DSMat44 globalInverse = theCamera.m_GlobalTransform.getInverse(); + QT3DSMat44 theVP = theCamera.m_Projection * globalInverse; + // For now we won't setup the scissor, so we may be off by inPickDims at most because + // GetLayerMouseCoords will return + // false if the mouse is too far off the layer. + return SLayerPickSetup(projectionPremult, theVP, + NVRenderRect(0, 0, (QT3DSU32)layerToPresentation.m_Width, + (QT3DSU32)layerToPresentation.m_Height)); + } + + Option Qt3DSRendererImpl::GetLayerRect(SLayer &inLayer) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); + if (theData == NULL || theData->m_Camera == NULL) { + QT3DS_ASSERT(false); + return Empty(); + } + SLayerRenderPreparationResult &thePrepResult(*theData->m_LayerPrepResult); + return thePrepResult.GetLayerToPresentationViewport(); + } + + // This doesn't have to be cheap. + void Qt3DSRendererImpl::RunLayerRender(SLayer &inLayer, const QT3DSMat44 &inViewProjection) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); + if (theData == NULL || theData->m_Camera == NULL) { + QT3DS_ASSERT(false); + return; + } + theData->PrepareAndRender(inViewProjection); + } + + void Qt3DSRendererImpl::AddRenderWidget(IRenderWidget &inWidget) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inWidget.GetNode()); + if (theData) + theData->AddRenderWidget(inWidget); + } + + void Qt3DSRendererImpl::RenderLayerRect(SLayer &inLayer, const QT3DSVec3 &inColor) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); + if (theData) + theData->m_BoundingRectColor = inColor; + } + + SScaleAndPosition Qt3DSRendererImpl::GetWorldToPixelScaleFactor(const SCamera &inCamera, + const QT3DSVec3 &inWorldPoint, + SLayerRenderData &inRenderData) + { + if (inCamera.m_Flags.IsOrthographic() == true) { + // There are situations where the camera can scale. + return SScaleAndPosition( + inWorldPoint, + inCamera.GetOrthographicScaleFactor( + inRenderData.m_LayerPrepResult->GetLayerToPresentationViewport(), + inRenderData.m_LayerPrepResult->GetPresentationDesignDimensions())); + } else { + QT3DSVec3 theCameraPos(0, 0, 0); + QT3DSVec3 theCameraDir(0, 0, -1); + SRay theRay(theCameraPos, inWorldPoint - theCameraPos); + NVPlane thePlane(theCameraDir, -600); + QT3DSVec3 theItemPosition(inWorldPoint); + Option theIntersection = theRay.Intersect(thePlane); + if (theIntersection.hasValue()) + theItemPosition = *theIntersection; + // The special number comes in from physically measuring how off we are on the screen. + QT3DSF32 theScaleFactor = (1.0f / inCamera.m_Projection.column1[1]); + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inCamera); + QT3DSU32 theHeight = theData->m_LayerPrepResult->GetTextureDimensions().height(); + QT3DSF32 theScaleMultiplier = 600.0f / ((QT3DSF32)theHeight / 2.0f); + theScaleFactor *= theScaleMultiplier; + + return SScaleAndPosition(theItemPosition, theScaleFactor); + } + } + + SScaleAndPosition Qt3DSRendererImpl::GetWorldToPixelScaleFactor(SLayer &inLayer, + const QT3DSVec3 &inWorldPoint) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); + if (theData == NULL || theData->m_Camera == NULL) { + QT3DS_ASSERT(false); + return SScaleAndPosition(); + } + return GetWorldToPixelScaleFactor(*theData->m_Camera, inWorldPoint, *theData); + } + + void Qt3DSRendererImpl::ReleaseLayerRenderResources(SLayer &inLayer, const SRenderInstanceId id) + { + TInstanceRenderMap::iterator theIter + = m_InstanceRenderMap.find(combineLayerAndId(&inLayer, id)); + if (theIter != m_InstanceRenderMap.end()) { + TLayerRenderList::iterator theLastFrm = eastl::find( + m_LastFrameLayers.begin(), m_LastFrameLayers.end(), theIter->second.mPtr); + if (theLastFrm != m_LastFrameLayers.end()) { + theIter->second->ResetForFrame(); + m_LastFrameLayers.erase(theLastFrm); + } + m_InstanceRenderMap.erase(theIter); + } + } + + void Qt3DSRendererImpl::RenderQuad(const QT3DSVec2 inDimensions, const QT3DSMat44 &inMVP, + NVRenderTexture2D &inQuadTexture) + { + m_Context->SetCullingEnabled(false); + SLayerSceneShader *theShader = GetSceneLayerShader(); + NVRenderContext &theContext(*m_Context); + theContext.SetActiveShader(&theShader->m_Shader); + theShader->m_MVP.Set(inMVP); + theShader->m_Dimensions.Set(inDimensions); + theShader->m_Sampler.Set(&inQuadTexture); + + GenerateXYQuad(); + theContext.SetInputAssembler(m_QuadInputAssembler); + theContext.Draw(NVRenderDrawMode::Triangles, m_QuadIndexBuffer->GetNumIndices(), 0); + } + + void Qt3DSRendererImpl::RenderQuad() + { + m_Context->SetCullingEnabled(false); + GenerateXYQuad(); + m_Context->SetInputAssembler(m_QuadInputAssembler); + m_Context->Draw(NVRenderDrawMode::Triangles, m_QuadIndexBuffer->GetNumIndices(), 0); + } + + void Qt3DSRendererImpl::RenderPointsIndirect() + { + m_Context->SetCullingEnabled(false); + GenerateXYZPoint(); + m_Context->SetInputAssembler(m_PointInputAssembler); + m_Context->DrawIndirect(NVRenderDrawMode::Points, 0); + } + + void Qt3DSRendererImpl::LayerNeedsFrameClear(SLayerRenderData &inLayer) + { + m_LastFrameLayers.push_back(&inLayer); + } + + void Qt3DSRendererImpl::BeginLayerDepthPassRender(SLayerRenderData &inLayer) + { + m_CurrentLayer = &inLayer; + } + + void Qt3DSRendererImpl::EndLayerDepthPassRender() { m_CurrentLayer = NULL; } + + void Qt3DSRendererImpl::BeginLayerRender(SLayerRenderData &inLayer) + { + m_CurrentLayer = &inLayer; + // Remove all of the shaders from the layer shader set + // so that we can only apply the camera and lighting properties to + // shaders that are in the layer. + m_LayerShaders.clear(); + } + void Qt3DSRendererImpl::EndLayerRender() { m_CurrentLayer = NULL; } + +// Allocate an object that lasts only this frame. +#define RENDER_FRAME_NEW(type) \ + new (m_PerFrameAllocator.m_FastAllocator.allocate(sizeof(type), __FILE__, __LINE__)) type + + void Qt3DSRendererImpl::PrepareImageForIbl(SImage &inImage) + { + if (inImage.m_TextureData.m_Texture && inImage.m_TextureData.m_Texture->GetNumMipmaps() < 1) + inImage.m_TextureData.m_Texture->GenerateMipmaps(); + } + + bool NodeContainsBoneRoot(SNode &childNode, QT3DSI32 rootID) + { + for (SNode *childChild = childNode.m_FirstChild; childChild != NULL; + childChild = childChild->m_NextSibling) { + if (childChild->m_SkeletonId == rootID) + return true; + } + + return false; + } + + void FillBoneIdNodeMap(SNode &childNode, nvhash_map &ioMap) + { + if (childNode.m_SkeletonId >= 0) + ioMap[childNode.m_SkeletonId] = &childNode; + for (SNode *childChild = childNode.m_FirstChild; childChild != NULL; + childChild = childChild->m_NextSibling) + FillBoneIdNodeMap(*childChild, ioMap); + } + + bool Qt3DSRendererImpl::PrepareTextureAtlasForRender() + { + ITextTextureAtlas *theTextureAtlas = m_qt3dsContext.GetTextureAtlas(); + if (theTextureAtlas == NULL) + return false; + + // this is a one time creation + if (!theTextureAtlas->IsInitialized()) { + NVRenderContext &theContext(*m_Context); + NVScopedRefCounted mVertexBuffer; + NVScopedRefCounted mInputAssembler; + NVScopedRefCounted mAttribLayout; + // temporay FB + using qt3ds::render::NVRenderContextScopedProperty; + NVRenderContextScopedProperty __fbo( + *m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + + ITextRenderer &theTextRenderer(*m_qt3dsContext.GetOnscreenTextRenderer()); + TTextTextureAtlasDetailsAndTexture theResult = theTextureAtlas->PrepareTextureAtlas(); + if (!theResult.first.m_EntryCount) { + QT3DS_ASSERT(theResult.first.m_EntryCount); + return false; + } + + // generate the index buffer we need + GenerateXYQuad(); + + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + qt3ds::render::NVRenderVertexBufferEntry( + "attr_uv", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), + }; + + // create our attribute layout + mAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); + + NVRenderFrameBuffer *theAtlasFB( + m_qt3dsContext.GetResourceManager().AllocateFrameBuffer()); + theAtlasFB->Attach(NVRenderFrameBufferAttachments::Color0, *theResult.second); + m_qt3dsContext.GetRenderContext().SetRenderTarget(theAtlasFB); + + // this texture contains our single entries + NVRenderTexture2D *theTexture = nullptr; + if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) { + theTexture = m_qt3dsContext.GetResourceManager() + .AllocateTexture2D(32, 32, NVRenderTextureFormats::RGBA8); + } else { + theTexture = m_qt3dsContext.GetResourceManager() + .AllocateTexture2D(32, 32, NVRenderTextureFormats::Alpha8); + } + m_Context->SetClearColor(QT3DSVec4(0, 0, 0, 0)); + m_Context->Clear(NVRenderClearValues::Color); + m_Context->SetDepthTestEnabled(false); + m_Context->SetScissorTestEnabled(false); + m_Context->SetCullingEnabled(false); + m_Context->SetBlendingEnabled(false); + m_Context->SetViewport( + NVRenderRect(0, 0, theResult.first.m_TextWidth, theResult.first.m_TextHeight)); + + SCamera theCamera; + theCamera.m_ClipNear = -1.0; + theCamera.m_ClipFar = 1.0; + theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + theCamera.m_Flags.SetOrthographic(true); + QT3DSVec2 theTextureDims((QT3DSF32)theResult.first.m_TextWidth, + (QT3DSF32)theResult.first.m_TextHeight); + theCamera.CalculateGlobalVariables( + NVRenderRect(0, 0, theResult.first.m_TextWidth, theResult.first.m_TextHeight), + theTextureDims); + // We want a 2D lower left projection + QT3DSF32 *writePtr(theCamera.m_Projection.front()); + writePtr[12] = -1; + writePtr[13] = -1; + + // generate render stuff + // We dynamicall update the vertex buffer + QT3DSF32 tempBuf[20]; + QT3DSF32 *bufPtr = tempBuf; + QT3DSU32 bufSize = 20 * sizeof(QT3DSF32); // 4 vertices 3 pos 2 tex + NVDataRef vertData((QT3DSU8 *)bufPtr, bufSize); + mVertexBuffer = theContext.CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Dynamic, 20 * sizeof(QT3DSF32), + 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32), vertData); + QT3DSU32 strides = mVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + mInputAssembler = theContext.CreateInputAssembler( + mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), m_QuadIndexBuffer.mPtr, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + + NVRenderShaderProgram *theShader = GetTextAtlasEntryShader(); + STextShader theTextShader(*theShader); + + if (theShader) { + theContext.SetActiveShader(theShader); + theTextShader.m_MVP.Set(theCamera.m_Projection); + + // we are going through all entries and render to the FBO + for (QT3DSU32 i = 0; i < theResult.first.m_EntryCount; i++) { + STextTextureAtlasEntryDetails theDetails = + theTextRenderer.RenderAtlasEntry(i, *theTexture); + // update vbo + // we need to mirror coordinates + QT3DSF32 x1 = (QT3DSF32)theDetails.m_X; + QT3DSF32 x2 = (QT3DSF32)theDetails.m_X + theDetails.m_TextWidth; + QT3DSF32 y1 = (QT3DSF32)theDetails.m_Y; + QT3DSF32 y2 = (QT3DSF32)theDetails.m_Y + theDetails.m_TextHeight; + + QT3DSF32 box[4][5] = { + { x1, y1, 0, 0, 1 }, + { x1, y2, 0, 0, 0 }, + { x2, y2, 0, 1, 0 }, + { x2, y1, 0, 1, 1 }, + }; + + NVDataRef vertData((QT3DSU8 *)box, bufSize); + mVertexBuffer->UpdateBuffer(vertData, false); + + theTextShader.m_Sampler.Set(theTexture); + + theContext.SetInputAssembler(mInputAssembler); + theContext.Draw(NVRenderDrawMode::Triangles, m_QuadIndexBuffer->GetNumIndices(), + 0); + } + } + + m_qt3dsContext.GetResourceManager().Release(*theTexture); + m_qt3dsContext.GetResourceManager().Release(*theAtlasFB); + + return true; + } + + return theTextureAtlas->IsInitialized(); + } + + Option Qt3DSRendererImpl::GetLayerMouseCoords(SLayerRenderData &inLayerRenderData, + const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool forceImageIntersect) const + { + if (inLayerRenderData.m_LayerPrepResult.hasValue()) + return inLayerRenderData.m_LayerPrepResult->GetLayerMouseCoords( + inMouseCoords, inViewportDimensions, forceImageIntersect); + return Empty(); + } + + void Qt3DSRendererImpl::GetLayerHitObjectList(SLayerRenderData &inLayerRenderData, + const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inPresCoords, bool inPickEverything, + TPickResultArray &outIntersectionResult, + NVAllocatorCallback &inTempAllocator) + { + // This function assumes the layer was rendered to the scene itself. There is another + // function + // for completely offscreen layers that don't get rendered to the scene. + bool wasRenderToTarget(inLayerRenderData.m_Layer.m_Flags.IsLayerRenderToTarget()); + if (wasRenderToTarget && inLayerRenderData.m_Camera != NULL) { + Option theHitRay; + if (inLayerRenderData.m_LayerPrepResult.hasValue()) + theHitRay = inLayerRenderData.m_LayerPrepResult->GetPickRay( + inPresCoords, inViewportDimensions, false); + if (inLayerRenderData.m_LastFrameOffscreenRenderer.mPtr == NULL) { + if (theHitRay.hasValue()) { + // Scale the mouse coords to change them into the camera's numerical space. + SRay thePickRay = *theHitRay; + for (QT3DSU32 idx = inLayerRenderData.m_OpaqueObjects.size(), end = 0; idx > end; + --idx) { + SRenderableObject *theRenderableObject = + inLayerRenderData.m_OpaqueObjects[idx - 1]; + if (inPickEverything + || theRenderableObject->m_RenderableFlags.GetPickable()) + IntersectRayWithSubsetRenderable(thePickRay, *theRenderableObject, + outIntersectionResult, + inTempAllocator); + } + for (QT3DSU32 idx = inLayerRenderData.m_TransparentObjects.size(), end = 0; + idx > end; --idx) { + SRenderableObject *theRenderableObject = + inLayerRenderData.m_TransparentObjects[idx - 1]; + if (inPickEverything + || theRenderableObject->m_RenderableFlags.GetPickable()) + IntersectRayWithSubsetRenderable(thePickRay, *theRenderableObject, + outIntersectionResult, + inTempAllocator); + } + } + } else { + IGraphObjectPickQuery *theQuery = + inLayerRenderData.m_LastFrameOffscreenRenderer->GetGraphObjectPickQuery(this); + if (theQuery) { + Qt3DSRenderPickResult theResult = + theQuery->Pick(inPresCoords, inViewportDimensions, inPickEverything); + if (theResult.m_HitObject) { + theResult.m_OffscreenRenderer = + inLayerRenderData.m_LastFrameOffscreenRenderer; + outIntersectionResult.push_back(theResult); + } + } else + inLayerRenderData.m_LastFrameOffscreenRenderer->Pick(inPresCoords, + inViewportDimensions, + this); + } + } + } + + static inline Qt3DSRenderPickSubResult ConstructSubResult(SRenderableImage &inImage) + { + return ConstructSubResult(inImage.m_Image); + } + + void Qt3DSRendererImpl::IntersectRayWithSubsetRenderable( + const SRay &inRay, SRenderableObject &inRenderableObject, + TPickResultArray &outIntersectionResultList, NVAllocatorCallback &inTempAllocator) + { + Option theIntersectionResultOpt(inRay.IntersectWithAABB( + inRenderableObject.m_GlobalTransform, inRenderableObject.m_Bounds)); + if (theIntersectionResultOpt.hasValue() == false) + return; + SRayIntersectionResult &theResult(*theIntersectionResultOpt); + + // Leave the coordinates relative for right now. + const SGraphObject *thePickObject = NULL; + if (inRenderableObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) + thePickObject = + &static_cast(&inRenderableObject)->m_ModelContext.m_Model; + else if (inRenderableObject.m_RenderableFlags.IsText()) + thePickObject = &static_cast(&inRenderableObject)->m_Text; + else if (inRenderableObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) + thePickObject = &static_cast(&inRenderableObject) + ->m_ModelContext.m_Model; + else if (inRenderableObject.m_RenderableFlags.IsPath()) + thePickObject = &static_cast(&inRenderableObject)->m_Path; + + if (thePickObject != NULL) { + outIntersectionResultList.push_back(Qt3DSRenderPickResult( + *thePickObject, theResult.m_RayLengthSquared, theResult.m_RelXY)); + + // For subsets, we know we can find images on them which may have been the result + // of rendering a sub-presentation. + if (inRenderableObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) { + Qt3DSRenderPickSubResult *theLastResult = NULL; + for (SRenderableImage *theImage = + static_cast(&inRenderableObject)->m_FirstImage; + theImage != NULL; theImage = theImage->m_NextImage) { + if (theImage->m_Image.m_LastFrameOffscreenRenderer != NULL + && theImage->m_Image.m_TextureData.m_Texture != NULL) { + Qt3DSRenderPickSubResult *theSubResult = + (Qt3DSRenderPickSubResult *)inTempAllocator.allocate( + sizeof(Qt3DSRenderPickSubResult), "Qt3DSRenderPickSubResult", + __FILE__, __LINE__); + + new (theSubResult) Qt3DSRenderPickSubResult(ConstructSubResult(*theImage)); + if (theLastResult == NULL) + outIntersectionResultList.back().m_FirstSubObject = theSubResult; + else + theLastResult->m_NextSibling = theSubResult; + theLastResult = theSubResult; + } + } + } + } + } + +#ifndef EA_PLATFORM_WINDOWS +#define _snprintf snprintf +#endif + + NVRenderShaderProgram *Qt3DSRendererImpl::CompileShader(CRegisteredString inName, + const char8_t *inVert, + const char8_t *inFrag) + { + GetProgramGenerator().BeginProgram(); + GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)->Append(inVert); + GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)->Append(inFrag); + return GetProgramGenerator().CompileGeneratedShader(inName); + } + + const QT3DSF32 MINATTENUATION = 0; + const QT3DSF32 MAXATTENUATION = 1000; + + QT3DSF32 ClampFloat(QT3DSF32 value, QT3DSF32 min, QT3DSF32 max) + { + return value < min ? min : ((value > max) ? max : value); + } + + QT3DSF32 TranslateConstantAttenuation(QT3DSF32 attenuation) { return attenuation * .01f; } + + QT3DSF32 TranslateLinearAttenuation(QT3DSF32 attenuation) + { + attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); + return attenuation * 0.0001f; + } + + QT3DSF32 TranslateQuadraticAttenuation(QT3DSF32 attenuation) + { + attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); + return attenuation * 0.0000001f; + } + + SShaderGeneratorGeneratedShader *Qt3DSRendererImpl::GetShader(SSubsetRenderable &inRenderable, + TShaderFeatureSet inFeatureSet) + { + if (m_CurrentLayer == NULL) { + QT3DS_ASSERT(false); + return NULL; + } + TShaderMap::iterator theFind = m_Shaders.find(inRenderable.m_ShaderDescription); + SShaderGeneratorGeneratedShader *retval = NULL; + if (theFind == m_Shaders.end()) { + // Generate the shader. + NVRenderShaderProgram *theShader(GenerateShader(inRenderable, inFeatureSet)); + if (theShader) { + SShaderGeneratorGeneratedShader *theGeneratedShader = + (SShaderGeneratorGeneratedShader *)m_Context->GetAllocator().allocate( + sizeof(SShaderGeneratorGeneratedShader), "SShaderGeneratorGeneratedShader", + __FILE__, __LINE__); + new (theGeneratedShader) SShaderGeneratorGeneratedShader( + m_StringTable->RegisterStr(m_GeneratedShaderString.c_str()), *theShader); + m_Shaders.insert(make_pair(inRenderable.m_ShaderDescription, theGeneratedShader)); + retval = theGeneratedShader; + } + // We still insert something because we don't to attempt to generate the same bad shader + // twice. + else + m_Shaders.insert(make_pair(inRenderable.m_ShaderDescription, + (SShaderGeneratorGeneratedShader *)NULL)); + } else + retval = theFind->second; + + if (retval != NULL) { + if (!m_LayerShaders.contains(*retval)) { + m_LayerShaders.insert(*retval); + } + if (m_CurrentLayer && m_CurrentLayer->m_Camera) { + SCamera &theCamera(*m_CurrentLayer->m_Camera); + if (m_CurrentLayer->m_CameraDirection.hasValue() == false) + m_CurrentLayer->m_CameraDirection = theCamera.GetScalingCorrectDirection(); + } + } + return retval; + } + static QT3DSVec3 g_fullScreenRectFace[] = { + QT3DSVec3(-1, -1, 0), QT3DSVec3(-1, 1, 0), QT3DSVec3(1, 1, 0), QT3DSVec3(1, -1, 0), + }; + + static QT3DSVec2 g_fullScreenRectUVs[] = { QT3DSVec2(0, 0), QT3DSVec2(0, 1), QT3DSVec2(1, 1), + QT3DSVec2(1, 0) }; + + void Qt3DSRendererImpl::GenerateXYQuad() + { + if (m_QuadInputAssembler) + return; + + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + qt3ds::render::NVRenderVertexBufferEntry("attr_uv", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), + }; + + QT3DSF32 tempBuf[20]; + QT3DSF32 *bufPtr = tempBuf; + QT3DSVec3 *facePtr(g_fullScreenRectFace); + QT3DSVec2 *uvPtr(g_fullScreenRectUVs); + for (int j = 0; j < 4; j++, ++facePtr, ++uvPtr, bufPtr += 5) { + bufPtr[0] = facePtr->x; + bufPtr[1] = facePtr->y; + bufPtr[2] = facePtr->z; + bufPtr[3] = uvPtr->x; + bufPtr[4] = uvPtr->y; + } + m_QuadVertexBuffer = m_Context->CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, 20 * sizeof(QT3DSF32), + 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32), toU8DataRef(tempBuf, 20)); + + QT3DSU8 indexData[] = { + 0, 1, 2, 0, 2, 3, + }; + m_QuadIndexBuffer = m_Context->CreateIndexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, qt3ds::render::NVRenderComponentTypes::QT3DSU8, + sizeof(indexData), toU8DataRef(indexData, sizeof(indexData))); + + // create our attribute layout + m_QuadAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); + + // create input assembler object + QT3DSU32 strides = m_QuadVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_QuadInputAssembler = m_Context->CreateInputAssembler( + m_QuadAttribLayout, toConstDataRef(&m_QuadVertexBuffer.mPtr, 1), m_QuadIndexBuffer, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + + void Qt3DSRendererImpl::GenerateXYZPoint() + { + if (m_PointInputAssembler) + return; + + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + qt3ds::render::NVRenderVertexBufferEntry("attr_uv", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), + }; + + QT3DSF32 tempBuf[5]; + tempBuf[0] = tempBuf[1] = tempBuf[2] = 0.0; + tempBuf[3] = tempBuf[4] = 0.0; + + m_PointVertexBuffer = m_Context->CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, 5 * sizeof(QT3DSF32), + 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32), toU8DataRef(tempBuf, 5)); + + // create our attribute layout + m_PointAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); + + // create input assembler object + QT3DSU32 strides = m_PointVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_PointInputAssembler = m_Context->CreateInputAssembler( + m_PointAttribLayout, toConstDataRef(&m_PointVertexBuffer.mPtr, 1), NULL, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + + eastl::pair Qt3DSRendererImpl::GetXYQuad() + { + if (!m_QuadInputAssembler) + GenerateXYQuad(); + + return eastl::make_pair(m_QuadVertexBuffer.mPtr, m_QuadIndexBuffer.mPtr); + } + + SLayerGlobalRenderProperties Qt3DSRendererImpl::GetLayerGlobalRenderProperties() + { + SLayerRenderData &theData = *m_CurrentLayer; + SLayer &theLayer = theData.m_Layer; + if (theData.m_CameraDirection.hasValue() == false) + theData.m_CameraDirection = theData.m_Camera->GetScalingCorrectDirection(); + + return SLayerGlobalRenderProperties( + theLayer, *theData.m_Camera, *theData.m_CameraDirection, theData.m_Lights, + theData.m_LightDirections, theData.m_ShadowMapManager.mPtr, theData.m_LayerDepthTexture, + theData.m_LayerSsaoTexture, theLayer.m_LightProbe, theLayer.m_LightProbe2, + theLayer.m_ProbeHorizon, theLayer.m_ProbeBright, theLayer.m_Probe2Window, + theLayer.m_Probe2Pos, theLayer.m_Probe2Fade, theLayer.m_ProbeFov); + } + + void Qt3DSRendererImpl::GenerateXYQuadStrip() + { + if (m_QuadStripInputAssembler) + return; + + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + qt3ds::render::NVRenderVertexBufferEntry("attr_uv", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), + }; + + // this buffer is filled dynmically + m_QuadStripVertexBuffer = + m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Dynamic, 0, + 3 * sizeof(QT3DSF32) + 2 * sizeof(QT3DSF32) // stride + , + NVDataRef()); + + // create our attribute layout + m_QuadStripAttribLayout = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 2)); + + // create input assembler object + QT3DSU32 strides = m_QuadStripVertexBuffer->GetStride(); + QT3DSU32 offsets = 0; + m_QuadStripInputAssembler = m_Context->CreateInputAssembler( + m_QuadStripAttribLayout, toConstDataRef(&m_QuadStripVertexBuffer.mPtr, 1), NULL, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1)); + } + + void Qt3DSRendererImpl::UpdateCbAoShadow(const SLayer *pLayer, const SCamera *pCamera, + CResourceTexture2D &inDepthTexture) + { + if (m_Context->GetConstantBufferSupport()) { + CRegisteredString theName = m_Context->GetStringTable().RegisterStr("cbAoShadow"); + NVRenderConstantBuffer *pCB = m_Context->GetConstantBuffer(theName); + + if (!pCB) { + // the size is determined automatically later on + pCB = m_Context->CreateConstantBuffer( + theName, qt3ds::render::NVRenderBufferUsageType::Static, 0, NVDataRef()); + if (!pCB) { + QT3DS_ASSERT(false); + return; + } + m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); + + // Add paramters. Note should match the appearance in the shader program + pCB->AddParam(m_Context->GetStringTable().RegisterStr("ao_properties"), + qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); + pCB->AddParam(m_Context->GetStringTable().RegisterStr("ao_properties2"), + qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); + pCB->AddParam(m_Context->GetStringTable().RegisterStr("shadow_properties"), + qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); + pCB->AddParam(m_Context->GetStringTable().RegisterStr("aoScreenConst"), + qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); + pCB->AddParam(m_Context->GetStringTable().RegisterStr("UvToEyeConst"), + qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4, 1); + } + + // update values + QT3DSVec4 aoProps(pLayer->m_AoStrength * 0.01f, pLayer->m_AoDistance * 0.4f, + pLayer->m_AoSoftness * 0.02f, pLayer->m_AoBias); + pCB->UpdateParam("ao_properties", NVDataRef((QT3DSU8 *)&aoProps, 1)); + QT3DSVec4 aoProps2((QT3DSF32)pLayer->m_AoSamplerate, (pLayer->m_AoDither) ? 1.0f : 0.0f, 0.0f, + 0.0f); + pCB->UpdateParam("ao_properties2", NVDataRef((QT3DSU8 *)&aoProps2, 1)); + QT3DSVec4 shadowProps(pLayer->m_ShadowStrength * 0.01f, pLayer->m_ShadowDist, + pLayer->m_ShadowSoftness * 0.01f, pLayer->m_ShadowBias); + pCB->UpdateParam("shadow_properties", NVDataRef((QT3DSU8 *)&shadowProps, 1)); + + QT3DSF32 R2 = pLayer->m_AoDistance * pLayer->m_AoDistance * 0.16f; + QT3DSF32 rw = 100, rh = 100; + + if (inDepthTexture && inDepthTexture.GetTexture()) { + rw = (QT3DSF32)inDepthTexture.GetTexture()->GetTextureDetails().m_Width; + rh = (QT3DSF32)inDepthTexture.GetTexture()->GetTextureDetails().m_Height; + } + QT3DSF32 fov = (pCamera) ? pCamera->verticalFov(rw / rh) : 1.0f; + QT3DSF32 tanHalfFovY = tanf(0.5f * fov * (rh / rw)); + QT3DSF32 invFocalLenX = tanHalfFovY * (rw / rh); + + QT3DSVec4 aoScreenConst(1.0f / R2, rh / (2.0f * tanHalfFovY), 1.0f / rw, 1.0f / rh); + pCB->UpdateParam("aoScreenConst", NVDataRef((QT3DSU8 *)&aoScreenConst, 1)); + QT3DSVec4 UvToEyeConst(2.0f * invFocalLenX, -2.0f * tanHalfFovY, -invFocalLenX, + tanHalfFovY); + pCB->UpdateParam("UvToEyeConst", NVDataRef((QT3DSU8 *)&UvToEyeConst, 1)); + + // update buffer to hardware + pCB->Update(); + } + } + + // widget context implementation + + NVRenderVertexBuffer &Qt3DSRendererImpl::GetOrCreateVertexBuffer(CRegisteredString &inStr, + QT3DSU32 stride, + NVConstDataRef bufferData) + { + NVRenderVertexBuffer *retval = GetVertexBuffer(inStr); + if (retval) { + // we update the buffer + retval->UpdateBuffer(bufferData, false); + return *retval; + } + retval = m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Dynamic, + bufferData.size(), stride, bufferData); + m_WidgetVertexBuffers.insert(eastl::make_pair(inStr, retval)); + return *retval; + } + NVRenderIndexBuffer & + Qt3DSRendererImpl::GetOrCreateIndexBuffer(CRegisteredString &inStr, + qt3ds::render::NVRenderComponentTypes::Enum componentType, + size_t size, NVConstDataRef bufferData) + { + NVRenderIndexBuffer *retval = GetIndexBuffer(inStr); + if (retval) { + // we update the buffer + retval->UpdateBuffer(bufferData, false); + return *retval; + } + + retval = m_Context->CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Dynamic, + componentType, size, bufferData); + m_WidgetIndexBuffers.insert(eastl::make_pair(inStr, retval)); + return *retval; + } + + NVRenderAttribLayout &Qt3DSRendererImpl::CreateAttributeLayout( + NVConstDataRef attribs) + { + // create our attribute layout + NVRenderAttribLayout *theAttribLAyout = m_Context->CreateAttributeLayout(attribs); + return *theAttribLAyout; + } + + NVRenderInputAssembler &Qt3DSRendererImpl::GetOrCreateInputAssembler( + CRegisteredString &inStr, NVRenderAttribLayout *attribLayout, + NVConstDataRef buffers, const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets) + { + NVRenderInputAssembler *retval = GetInputAssembler(inStr); + if (retval) + return *retval; + + retval = + m_Context->CreateInputAssembler(attribLayout, buffers, indexBuffer, strides, offsets); + m_WidgetInputAssembler.insert(eastl::make_pair(inStr, retval)); + return *retval; + } + + NVRenderVertexBuffer *Qt3DSRendererImpl::GetVertexBuffer(CRegisteredString &inStr) + { + TStrVertBufMap::iterator theIter = m_WidgetVertexBuffers.find(inStr); + if (theIter != m_WidgetVertexBuffers.end()) + return theIter->second; + return NULL; + } + + NVRenderIndexBuffer *Qt3DSRendererImpl::GetIndexBuffer(CRegisteredString &inStr) + { + TStrIndexBufMap::iterator theIter = m_WidgetIndexBuffers.find(inStr); + if (theIter != m_WidgetIndexBuffers.end()) + return theIter->second; + return NULL; + } + + NVRenderInputAssembler *Qt3DSRendererImpl::GetInputAssembler(CRegisteredString &inStr) + { + TStrIAMap::iterator theIter = m_WidgetInputAssembler.find(inStr); + if (theIter != m_WidgetInputAssembler.end()) + return theIter->second; + return NULL; + } + + NVRenderShaderProgram *Qt3DSRendererImpl::GetShader(CRegisteredString inStr) + { + TStrShaderMap::iterator theIter = m_WidgetShaders.find(inStr); + if (theIter != m_WidgetShaders.end()) + return theIter->second; + return NULL; + } + + NVRenderShaderProgram *Qt3DSRendererImpl::CompileAndStoreShader(CRegisteredString inStr) + { + NVRenderShaderProgram *newProgram = GetProgramGenerator().CompileGeneratedShader(inStr); + if (newProgram) + m_WidgetShaders.insert(eastl::make_pair(inStr, newProgram)); + return newProgram; + } + + IShaderProgramGenerator &Qt3DSRendererImpl::GetProgramGenerator() + { + return m_qt3dsContext.GetShaderProgramGenerator(); + } + + STextDimensions Qt3DSRendererImpl::MeasureText(const STextRenderInfo &inText) + { + if (m_qt3dsContext.GetTextRenderer() != NULL) + return m_qt3dsContext.GetTextRenderer()->MeasureText(inText, 0); + return STextDimensions(); + } + + void Qt3DSRendererImpl::RenderText(const STextRenderInfo &inText, const QT3DSVec3 &inTextColor, + const QT3DSVec3 &inBackgroundColor, const QT3DSMat44 &inMVP) + { + if (m_qt3dsContext.GetTextRenderer() != NULL) { + ITextRenderer &theTextRenderer(*m_qt3dsContext.GetTextRenderer()); + NVRenderTexture2D *theTexture = m_qt3dsContext.GetResourceManager().AllocateTexture2D( + 32, 32, NVRenderTextureFormats::RGBA8); + STextTextureDetails theTextTextureDetails = + theTextRenderer.RenderText(inText, *theTexture); + STextRenderHelper theTextHelper(GetTextWidgetShader()); + if (theTextHelper.m_Shader != NULL) { + m_qt3dsContext.GetRenderContext().SetBlendingEnabled(false); + STextScaleAndOffset theScaleAndOffset(*theTexture, theTextTextureDetails, inText); + theTextHelper.m_Shader->Render(*theTexture, theScaleAndOffset, + QT3DSVec4(inTextColor, 1.0f), inMVP, QT3DSVec2(0, 0), + GetContext(), theTextHelper.m_QuadInputAssembler, + theTextHelper.m_QuadInputAssembler.GetIndexCount(), + theTextTextureDetails, inBackgroundColor); + } + m_qt3dsContext.GetResourceManager().Release(*theTexture); + } + } + + void Qt3DSRendererImpl::RenderText2D(QT3DSF32 x, QT3DSF32 y, + qt3ds::foundation::Option inColor, + const char *text) + { + if (m_qt3dsContext.GetOnscreenTextRenderer() != NULL) { + GenerateXYQuadStrip(); + + if (PrepareTextureAtlasForRender()) { + TTextRenderAtlasDetailsAndTexture theRenderTextDetails; + ITextTextureAtlas *theTextureAtlas = m_qt3dsContext.GetTextureAtlas(); + QSize theWindow = m_qt3dsContext.GetWindowDimensions(); + + const wchar_t *wText = m_StringTable->GetWideStr(text); + STextRenderInfo theInfo; + theInfo.m_Text = m_StringTable->RegisterStr(wText); + theInfo.m_FontSize = 20; + // text scale 2% of screen we don't scale Y though because it becomes unreadable + theInfo.m_ScaleX = (theWindow.width() / 100.0f) * 1.5f / (theInfo.m_FontSize); + theInfo.m_ScaleY = 1.0f; + + theRenderTextDetails = theTextureAtlas->RenderText(theInfo); + + if (theRenderTextDetails.first.m_Vertices.size()) { + STextRenderHelper theTextHelper(GetOnscreenTextShader()); + if (theTextHelper.m_Shader != NULL) { + // setup 2D projection + SCamera theCamera; + theCamera.m_ClipNear = -1.0; + theCamera.m_ClipFar = 1.0; + + theCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + theCamera.m_Flags.SetOrthographic(true); + QT3DSVec2 theWindowDim((QT3DSF32)theWindow.width(), (QT3DSF32)theWindow.height()); + theCamera.CalculateGlobalVariables( + NVRenderRect(0, 0, theWindow.width(), theWindow.height()), + theWindowDim); + // We want a 2D lower left projection + QT3DSF32 *writePtr(theCamera.m_Projection.front()); + writePtr[12] = -1; + writePtr[13] = -1; + + // upload vertices + m_QuadStripVertexBuffer->UpdateBuffer(theRenderTextDetails.first.m_Vertices, + false); + + theTextHelper.m_Shader->Render2D( + *theRenderTextDetails.second, QT3DSVec4(inColor, 1.0f), + theCamera.m_Projection, GetContext(), + theTextHelper.m_QuadInputAssembler, + theRenderTextDetails.first.m_VertexCount, QT3DSVec2(x, y)); + } + // we release the memory here + QT3DS_FREE(m_Context->GetAllocator(), + theRenderTextDetails.first.m_Vertices.begin()); + } + } + } + } + + void Qt3DSRendererImpl::RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, + qt3ds::foundation::Option inColor) + { + if (!IsLayerGpuProfilingEnabled()) + return; + + char messageLine[1024]; + TInstanceRenderMap::const_iterator theIter; + + QT3DSF32 startY = y; + + for (theIter = m_InstanceRenderMap.begin(); theIter != m_InstanceRenderMap.end(); theIter++) { + QT3DSF32 startX = x; + const SLayerRenderData *theLayerRenderData = theIter->second; + const SLayer *theLayer = &theLayerRenderData->m_Layer; + + if (theLayer->m_Flags.IsActive() && theLayerRenderData->m_LayerProfilerGpu.mPtr) { + const IRenderProfiler::TStrIDVec &idList = + theLayerRenderData->m_LayerProfilerGpu->GetTimerIDs(); + if (!idList.empty()) { + startY -= 22; + startX += 20; + RenderText2D(startX, startY, inColor, theLayer->m_Id); + IRenderProfiler::TStrIDVec::const_iterator theIdIter = idList.begin(); + for (theIdIter = idList.begin(); theIdIter != idList.end(); theIdIter++) { + startY -= 22; + sprintf(messageLine, "%s: %.3f ms", theIdIter->c_str(), + theLayerRenderData->m_LayerProfilerGpu->GetElapsedTime(*theIdIter)); + RenderText2D(startX + 20, startY, inColor, messageLine); + } + } + } + } + } + + // Given a node and a point in the node's local space (most likely its pivot point), we return + // a normal matrix so you can get the axis out, a transformation from node to camera + // a new position and a floating point scale factor so you can render in 1/2 perspective mode + // or orthographic mode if you would like to. + SWidgetRenderInformation + Qt3DSRendererImpl::GetWidgetRenderInformation(SNode &inNode, const QT3DSVec3 &inPos, + RenderWidgetModes::Enum inWidgetMode) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inNode); + SCamera *theCamera = theData->m_Camera; + if (theCamera == NULL || theData->m_LayerPrepResult.hasValue() == false) { + QT3DS_ASSERT(false); + return SWidgetRenderInformation(); + } + QT3DSMat44 theGlobalTransform(QT3DSMat44::createIdentity()); + if (inNode.m_Parent != NULL && inNode.m_Parent->m_Type != GraphObjectTypes::Layer + && !inNode.m_Flags.IsIgnoreParentTransform()) + theGlobalTransform = inNode.m_Parent->m_GlobalTransform; + QT3DSMat44 theCameraInverse(theCamera->m_GlobalTransform.getInverse()); + QT3DSMat44 theNodeParentToCamera; + if (inWidgetMode == RenderWidgetModes::Local) + theNodeParentToCamera = theCameraInverse * theGlobalTransform; + else + theNodeParentToCamera = theCameraInverse; + + QT3DSMat33 theNormalMat(theNodeParentToCamera.column0.getXYZ(), + theNodeParentToCamera.column1.getXYZ(), + theNodeParentToCamera.column2.getXYZ()); + theNormalMat = theNormalMat.getInverse().getTranspose(); + theNormalMat.column0.normalize(); + theNormalMat.column1.normalize(); + theNormalMat.column2.normalize(); + + QT3DSMat44 theTranslation(QT3DSMat44::createIdentity()); + theTranslation.column3.x = inNode.m_Position.x; + theTranslation.column3.y = inNode.m_Position.y; + theTranslation.column3.z = inNode.m_Position.z; + theTranslation.column3.z *= -1.0f; + + theGlobalTransform = theGlobalTransform * theTranslation; + + QT3DSMat44 theNodeToParentPlusTranslation = theCameraInverse * theGlobalTransform; + QT3DSVec3 thePos = theNodeToParentPlusTranslation.transform(inPos); + SScaleAndPosition theScaleAndPos = GetWorldToPixelScaleFactor(*theCamera, thePos, *theData); + QT3DSMat33 theLookAtMatrix(QT3DSMat33::createIdentity()); + if (theCamera->m_Flags.IsOrthographic() == false) { + QT3DSVec3 theNodeToCamera = theScaleAndPos.m_Position; + theNodeToCamera.normalize(); + QT3DSVec3 theOriginalAxis = QT3DSVec3(0, 0, -1); + QT3DSVec3 theRotAxis = theOriginalAxis.cross(theNodeToCamera); + QT3DSF32 theAxisLen = theRotAxis.normalize(); + if (theAxisLen > .05f) { + QT3DSF32 theRotAmount = acos(theOriginalAxis.dot(theNodeToCamera)); + QT3DSQuat theQuat(theRotAmount, theRotAxis); + theLookAtMatrix = QT3DSMat33(theQuat); + } + } + QT3DSVec3 thePosInWorldSpace = theGlobalTransform.transform(inPos); + QT3DSVec3 theCameraPosInWorldSpace = theCamera->GetGlobalPos(); + QT3DSVec3 theCameraOffset = thePosInWorldSpace - theCameraPosInWorldSpace; + QT3DSVec3 theDir = theCameraOffset; + theDir.normalize(); + // Things should be 600 units from the camera, as that is how all of our math is setup. + theCameraOffset = 600.0f * theDir; + return SWidgetRenderInformation( + theNormalMat, theNodeParentToCamera, theCamera->m_Projection, theCamera->m_Projection, + theLookAtMatrix, theCameraInverse, theCameraOffset, theScaleAndPos.m_Position, + theScaleAndPos.m_Scale, *theCamera); + } + + Option Qt3DSRendererImpl::GetLayerMouseCoords(SLayer &inLayer, + const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool forceImageIntersect) const + { + SLayerRenderData *theData = + const_cast(*this).GetOrCreateLayerRenderDataForNode(inLayer); + return GetLayerMouseCoords(*theData, inMouseCoords, inViewportDimensions, + forceImageIntersect); + } + + bool IQt3DSRenderer::IsGlEsContext(qt3ds::render::NVRenderContextType inContextType) + { + qt3ds::render::NVRenderContextType esContextTypes(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + + if ((inContextType & esContextTypes)) + return true; + + return false; + } + + bool IQt3DSRenderer::IsGlEs3Context(qt3ds::render::NVRenderContextType inContextType) + { + if (inContextType == NVRenderContextValues::GLES3 + || inContextType == NVRenderContextValues::GLES3PLUS) + return true; + + return false; + } + + bool IQt3DSRenderer::IsGl2Context(qt3ds::render::NVRenderContextType inContextType) + { + if (inContextType == NVRenderContextValues::GL2) + return true; + + return false; + } + + IQt3DSRenderer &IQt3DSRenderer::CreateRenderer(IQt3DSRenderContext &inContext) + { + return *QT3DS_NEW(inContext.GetAllocator(), Qt3DSRendererImpl)(inContext); + } +} +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.h new file mode 100644 index 00000000..686e7d3b --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.h @@ -0,0 +1,552 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_GENERATOR_IMPL_H +#define QT3DS_RENDER_SHADER_GENERATOR_IMPL_H +#include "Qt3DSRender.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderableObjects.h" +#include "Qt3DSRendererImplShaders.h" +#include "Qt3DSRendererImplLayerRenderData.h" +#include "foundation/Qt3DSFlags.h" +#include "Qt3DSRenderMesh.h" +#include "Qt3DSRenderModel.h" +#include "foundation/Qt3DSBounds3.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSInvasiveSet.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSDataRef.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderRay.h" +#include "Qt3DSRenderText.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSRendererImplLayerRenderHelper.h" +#include "Qt3DSRenderWidgets.h" +#include "Qt3DSRenderShaderCodeGenerator.h" +#include "Qt3DSRenderClippingFrustum.h" +#include "foundation/Qt3DSUnionCast.h" +#include "foundation/FastAllocator.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "Qt3DSRenderShaderKeys.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderProfiler.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" + +namespace qt3ds { +namespace render { + + inline bool FloatLessThan(QT3DSF32 lhs, QT3DSF32 rhs) + { + QT3DSF32 diff = lhs - rhs; + if (fabs(diff) < .001) + return false; + return diff < 0.0f ? true : false; + } + inline bool ISRenderObjectPtrLessThan(const SRenderableObject *lhs, + const SRenderableObject *rhs) + { + return FloatLessThan(lhs->m_CameraDistanceSq, rhs->m_CameraDistanceSq); + } + inline bool ISRenderObjectPtrGreatThan(const SRenderableObject *lhs, + const SRenderableObject *rhs) + { + return FloatLessThan(rhs->m_CameraDistanceSq, lhs->m_CameraDistanceSq); + } + inline bool NonZero(float inValue) { return fabs(inValue) > .001f; } + inline bool NonZero(QT3DSU32 inValue) { return inValue != 0; } + inline bool IsZero(float inValue) { return fabs(inValue) < .001f; } + inline bool IsNotOne(float inValue) { return fabs(1.0f - inValue) > .001f; } + + inline bool IsRectEdgeInBounds(QT3DSI32 inNewRectOffset, QT3DSI32 inNewRectWidth, + QT3DSI32 inCurrentRectOffset, QT3DSI32 inCurrentRectWidth) + { + QT3DSI32 newEnd = inNewRectOffset + inNewRectWidth; + QT3DSI32 currentEnd = inCurrentRectOffset + inCurrentRectWidth; + return inNewRectOffset >= inCurrentRectOffset && newEnd <= currentEnd; + } + + struct STextRenderHelper + { + STextShader *m_Shader; + NVRenderInputAssembler &m_QuadInputAssembler; + STextRenderHelper(STextShader *inShader, NVRenderInputAssembler &inQuadInputAssembler) + : m_Shader(inShader) + , m_QuadInputAssembler(inQuadInputAssembler) + { + } + }; + + struct SPickResultProcessResult : public Qt3DSRenderPickResult + { + SPickResultProcessResult(const Qt3DSRenderPickResult &inSrc) + : Qt3DSRenderPickResult(inSrc) + , m_WasPickConsumed(false) + { + } + SPickResultProcessResult() + : m_WasPickConsumed(false) + { + } + bool m_WasPickConsumed; + }; + + struct STextShaderPtr + { + NVAllocatorCallback &m_Allocator; + bool m_HasGeneratedShader; + STextShader *m_Shader; + STextShaderPtr(NVAllocatorCallback &alloc) + : m_Allocator(alloc) + , m_HasGeneratedShader(false) + , m_Shader(NULL) + { + } + bool HasGeneratedShader() { return m_HasGeneratedShader; } + void Set(STextShader *inShader) + { + m_Shader = inShader; + m_HasGeneratedShader = true; + } + ~STextShaderPtr() + { + if (m_Shader) + NVDelete(m_Allocator, m_Shader); + } + operator STextShader *() { return m_Shader; } + }; + + class QT3DS_AUTOTEST_EXPORT Qt3DSRendererImpl : public IQt3DSRenderer, public IRenderWidgetContext + { + typedef nvhash_map TShaderMap; + typedef nvhash_map> + TStrConstanBufMap; + typedef nvhash_map, + eastl::hash> TInstanceRenderMap; + typedef nvvector TLayerRenderList; + typedef nvvector TPickResultArray; + + // Items to implement the widget context. + typedef nvhash_map> + TStrVertBufMap; + typedef nvhash_map> + TStrIndexBufMap; + typedef nvhash_map> + TStrShaderMap; + typedef nvhash_map> TStrIAMap; + + typedef nvhash_map TBoneIdNodeMap; + + IQt3DSRenderContext &m_qt3dsContext; + NVScopedRefCounted m_Context; + NVScopedRefCounted m_BufferManager; + NVScopedRefCounted m_OffscreenRenderManager; + NVScopedRefCounted m_StringTable; + InvasiveSet m_LayerShaders; + // For rendering bounding boxes. + NVScopedRefCounted m_BoxVertexBuffer; + NVScopedRefCounted m_BoxIndexBuffer; + NVScopedRefCounted m_BoxShader; + NVScopedRefCounted m_ScreenRectShader; + + NVScopedRefCounted m_AxisVertexBuffer; + NVScopedRefCounted m_AxisShader; + + // X,Y quad, broken down into 2 triangles and normalized over + //-1,1. + NVScopedRefCounted m_QuadVertexBuffer; + NVScopedRefCounted m_QuadIndexBuffer; + NVScopedRefCounted m_RectIndexBuffer; + NVScopedRefCounted m_QuadInputAssembler; + NVScopedRefCounted m_RectInputAssembler; + NVScopedRefCounted m_QuadAttribLayout; + NVScopedRefCounted m_RectAttribLayout; + + // X,Y triangle strip quads in screen coord dynamiclly setup + NVScopedRefCounted m_QuadStripVertexBuffer; + NVScopedRefCounted m_QuadStripInputAssembler; + NVScopedRefCounted m_QuadStripAttribLayout; + + // X,Y,Z point which is used for instanced based rendering of points + NVScopedRefCounted m_PointVertexBuffer; + NVScopedRefCounted m_PointInputAssembler; + NVScopedRefCounted m_PointAttribLayout; + + Option> m_SceneLayerShader; + Option> m_LayerProgAAShader; + + TShaderMap m_Shaders; + TStrConstanBufMap m_ConstantBuffers; ///< store the the shader constant buffers + // Option is true if we have attempted to generate the shader. + // This does not mean we were successul, however. + Option> + m_DefaultMaterialDepthPrepassShader; + Option> m_DepthPrepassShader; + Option> m_DepthPrepassShaderDisplaced; + Option> m_DepthTessLinearPrepassShader; + Option> + m_DepthTessLinearPrepassShaderDisplaced; + Option> m_DepthTessPhongPrepassShader; + Option> m_DepthTessNPatchPrepassShader; + Option> m_TextDepthPrepassShader; + Option> m_DefaultAoPassShader; + Option> m_FakeDepthShader; + Option> m_FakeCubemapDepthShader; + Option> m_ParaboloidDepthShader; + Option> m_ParaboloidDepthTessLinearShader; + Option> m_ParaboloidDepthTessPhongShader; + Option> m_ParaboloidDepthTessNPatchShader; + Option> m_CubemapDepthShader; + Option> m_CubemapDepthTessLinearShader; + Option> m_CubemapDepthTessPhongShader; + Option> m_CubemapDepthTessNPatchShader; + Option> m_OrthographicDepthShader; + Option> + m_OrthographicDepthTessLinearShader; + Option> + m_OrthographicDepthTessPhongShader; + Option> + m_OrthographicDepthTessNPatchShader; + Option> m_CubeShadowBlurXShader; + Option> m_CubeShadowBlurYShader; + Option> m_OrthoShadowBlurXShader; + Option> m_OrthoShadowBlurYShader; + +#ifdef ADVANCED_BLEND_SW_FALLBACK + Option> m_AdvancedModeOverlayBlendShader; + Option> m_AdvancedModeColorBurnBlendShader; + Option> m_AdvancedModeColorDodgeBlendShader; +#endif + // Text shaders may be generated on demand. + STextShaderPtr m_TextShader; + STextShaderPtr m_TextPathShader; + STextShaderPtr m_TextWidgetShader; + STextShaderPtr m_TextOnscreenShader; + + // Overlay used to render all widgets. + NVRenderRect m_BeginFrameViewport; + NVScopedRefCounted m_WidgetTexture; + NVScopedRefCounted m_WidgetFBO; + +#ifdef ADVANCED_BLEND_SW_FALLBACK + // Advanced blend mode SW fallback + CResourceTexture2D m_LayerBlendTexture; + NVScopedRefCounted m_BlendFB; +#endif + // Allocator for temporary data that is cleared after every layer. + TInstanceRenderMap m_InstanceRenderMap; + TLayerRenderList m_LastFrameLayers; + volatile QT3DSI32 mRefCount; + + // Set from the first layer. + TPickResultArray m_LastPickResults; + + // Temporary information stored only when rendering a particular layer. + SLayerRenderData *m_CurrentLayer; + QT3DSMat44 m_ViewProjection; + eastl::string m_GeneratedShaderString; + + TStrVertBufMap m_WidgetVertexBuffers; + TStrIndexBufMap m_WidgetIndexBuffers; + TStrShaderMap m_WidgetShaders; + TStrIAMap m_WidgetInputAssembler; + + TBoneIdNodeMap m_BoneIdNodeMap; + + bool m_PickRenderPlugins; + bool m_LayerCachingEnabled; + bool m_LayerGPuProfilingEnabled; + SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; + + public: + Qt3DSRendererImpl(IQt3DSRenderContext &ctx); + virtual ~Qt3DSRendererImpl(); + SShaderDefaultMaterialKeyProperties &DefaultMaterialShaderKeyProperties() + { + return m_DefaultMaterialShaderKeyProperties; + } + + // NVRefCounted + void addRef() override; + void release() override; + + void EnableLayerCaching(bool inEnabled) override { m_LayerCachingEnabled = inEnabled; } + bool IsLayerCachingEnabled() const override { return m_LayerCachingEnabled; } + + void EnableLayerGpuProfiling(bool inEnabled) override + { + m_LayerGPuProfilingEnabled = inEnabled; + } + bool IsLayerGpuProfilingEnabled() const override { return m_LayerGPuProfilingEnabled; } + + // Calls prepare layer for render + // and then do render layer. + bool PrepareLayerForRender(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + bool inRenderSiblings, const SRenderInstanceId id) override; + void RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + bool clear, QT3DSVec3 clearColor, bool inRenderSiblings, + const SRenderInstanceId id) override; + void ChildrenUpdated(SNode &inParent) override; + QT3DSF32 GetTextScale(const SText &inText) override; + + SCamera *GetCameraForNode(const SNode &inNode) const override; + Option GetCameraBounds(const SGraphObject &inObject) override; + virtual SLayer *GetLayerForNode(const SNode &inNode) const; + SLayerRenderData *GetOrCreateLayerRenderDataForNode(const SNode &inNode, + const SRenderInstanceId id = nullptr); + + IRenderWidgetContext &GetRenderWidgetContext() + { + return *this; + } + + void BeginFrame() override; + void EndFrame() override; + + void PickRenderPlugins(bool inPick) override { m_PickRenderPlugins = inPick; } + Qt3DSRenderPickResult Pick(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, bool inPickSiblings, + bool inPickEverything, + const SRenderInstanceId id) override; + + virtual Option + FacePosition(SNode &inNode, NVBounds3 inBounds, const QT3DSMat44 &inGlobalTransform, + const QT3DSVec2 &inViewportDimensions, const QT3DSVec2 &inMouseCoords, + NVDataRef inMapperObjects, SBasisPlanes::Enum inPlane) override; + + virtual Qt3DSRenderPickResult PickOffscreenLayer(SLayer &inLayer, + const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, + bool inPickEverything); + + QT3DSVec3 UnprojectToPosition(SNode &inNode, QT3DSVec3 &inPosition, + const QT3DSVec2 &inMouseVec) const override; + QT3DSVec3 UnprojectWithDepth(SNode &inNode, QT3DSVec3 &inPosition, + const QT3DSVec3 &inMouseVec) const override; + QT3DSVec3 ProjectPosition(SNode &inNode, const QT3DSVec3 &inPosition) const override; + + Option GetLayerPickSetup(SLayer &inLayer, + const QT3DSVec2 &inMouseCoords, + const QSize &inPickDims) override; + + Option GetLayerRect(SLayer &inLayer) override; + + void RunLayerRender(SLayer &inLayer, const QT3DSMat44 &inViewProjection) override; + + // Note that this allocator is completely reset on BeginFrame. + NVAllocatorCallback &GetPerFrameAllocator() override + { + return m_qt3dsContext.GetPerFrameAllocator(); + } + void RenderLayerRect(SLayer &inLayer, const QT3DSVec3 &inColor) override; + void AddRenderWidget(IRenderWidget &inWidget) override; + + SScaleAndPosition GetWorldToPixelScaleFactor(SLayer &inLayer, + const QT3DSVec3 &inWorldPoint) override; + SScaleAndPosition GetWorldToPixelScaleFactor(const SCamera &inCamera, + const QT3DSVec3 &inWorldPoint, + SLayerRenderData &inRenderData); + + void ReleaseLayerRenderResources(SLayer &inLayer, const SRenderInstanceId id) override; + + void RenderQuad(const QT3DSVec2 inDimensions, const QT3DSMat44 &inMVP, + NVRenderTexture2D &inQuadTexture) override; + void RenderQuad() override; + + void RenderPointsIndirect() override; + + // render a screen aligned 2D text + void RenderText2D(QT3DSF32 x, QT3DSF32 y, qt3ds::foundation::Option inColor, + const char *text) override; + bool PrepareTextureAtlasForRender(); + + // render Gpu profiler values + void RenderGpuProfilerStats(QT3DSF32 x, QT3DSF32 y, + qt3ds::foundation::Option inColor) override; + + // Callback during the layer render process. + void LayerNeedsFrameClear(SLayerRenderData &inLayer); + void BeginLayerDepthPassRender(SLayerRenderData &inLayer); + void EndLayerDepthPassRender(); + void BeginLayerRender(SLayerRenderData &inLayer); + void EndLayerRender(); + void PrepareImageForIbl(SImage &inImage); + + NVRenderShaderProgram *CompileShader(CRegisteredString inName, const char8_t *inVert, + const char8_t *inFrame); + + NVRenderShaderProgram *GenerateShader(SSubsetRenderable &inRenderable, + TShaderFeatureSet inFeatureSet); + SShaderGeneratorGeneratedShader *GetShader(SSubsetRenderable &inRenderable, + TShaderFeatureSet inFeatureSet); + + SDefaultAoPassShader *GetDefaultAoPassShader(TShaderFeatureSet inFeatureSet); + SDefaultAoPassShader *GetFakeDepthShader(TShaderFeatureSet inFeatureSet); + SDefaultAoPassShader *GetFakeCubeDepthShader(TShaderFeatureSet inFeatureSet); + SDefaultMaterialRenderableDepthShader *GetRenderableDepthShader(); + + SRenderableDepthPrepassShader *GetParaboloidDepthShader(TessModeValues::Enum inTessMode); + SRenderableDepthPrepassShader *GetParaboloidDepthNoTessShader(); + SRenderableDepthPrepassShader *GetParaboloidDepthTessLinearShader(); + SRenderableDepthPrepassShader *GetParaboloidDepthTessPhongShader(); + SRenderableDepthPrepassShader *GetParaboloidDepthTessNPatchShader(); + SRenderableDepthPrepassShader *GetCubeShadowDepthShader(TessModeValues::Enum inTessMode); + SRenderableDepthPrepassShader *GetCubeDepthNoTessShader(); + SRenderableDepthPrepassShader *GetCubeDepthTessLinearShader(); + SRenderableDepthPrepassShader *GetCubeDepthTessPhongShader(); + SRenderableDepthPrepassShader *GetCubeDepthTessNPatchShader(); + SRenderableDepthPrepassShader *GetOrthographicDepthShader(TessModeValues::Enum inTessMode); + SRenderableDepthPrepassShader *GetOrthographicDepthNoTessShader(); + SRenderableDepthPrepassShader *GetOrthographicDepthTessLinearShader(); + SRenderableDepthPrepassShader *GetOrthographicDepthTessPhongShader(); + SRenderableDepthPrepassShader *GetOrthographicDepthTessNPatchShader(); + + SRenderableDepthPrepassShader *GetDepthPrepassShader(bool inDisplaced); + SRenderableDepthPrepassShader *GetDepthTessPrepassShader(TessModeValues::Enum inTessMode, + bool inDisplaced); + SRenderableDepthPrepassShader *GetDepthTessLinearPrepassShader(bool inDisplaced); + SRenderableDepthPrepassShader *GetDepthTessPhongPrepassShader(); + SRenderableDepthPrepassShader *GetDepthTessNPatchPrepassShader(); + STextDepthShader *GetTextDepthShader(); + STextRenderHelper GetShader(STextRenderable &inRenderable, bool inUsePathRendering); + STextRenderHelper GetTextShader(bool inUsePathRendering); + STextRenderHelper GetTextWidgetShader(); + STextRenderHelper GetOnscreenTextShader(); + SLayerSceneShader *GetSceneLayerShader(); + NVRenderShaderProgram *GetTextAtlasEntryShader(); + void GenerateXYQuad(); + void GenerateXYQuadStrip(); + void GenerateXYZPoint(); + eastl::pair GetXYQuad(); + SLayerProgAABlendShader *GetLayerProgAABlendShader(); + SShadowmapPreblurShader *GetCubeShadowBlurXShader(); + SShadowmapPreblurShader *GetCubeShadowBlurYShader(); + SShadowmapPreblurShader *GetOrthoShadowBlurXShader(); + SShadowmapPreblurShader *GetOrthoShadowBlurYShader(); + +#ifdef ADVANCED_BLEND_SW_FALLBACK + SAdvancedModeBlendShader *GetAdvancedBlendModeShader(AdvancedBlendModes::Enum blendMode); + SAdvancedModeBlendShader *GetOverlayBlendModeShader(); + SAdvancedModeBlendShader *GetColorBurnBlendModeShader(); + SAdvancedModeBlendShader *GetColorDodgeBlendModeShader(); +#endif + SLayerRenderData *GetLayerRenderData() { return m_CurrentLayer; } + SLayerGlobalRenderProperties GetLayerGlobalRenderProperties(); + void UpdateCbAoShadow(const SLayer *pLayer, const SCamera *pCamera, + CResourceTexture2D &inDepthTexture); + + NVRenderContext &GetContext() { return *m_Context; } + + IQt3DSRenderContext &GetQt3DSContext() { return m_qt3dsContext; } + + void DrawScreenRect(NVRenderRectF inRect, const QT3DSVec3 &inColor); + // Binds an offscreen texture. Widgets are rendered last. + void SetupWidgetLayer(); + +#ifdef ADVANCED_BLEND_SW_FALLBACK + NVScopedRefCounted GetLayerBlendTexture() + { + return m_LayerBlendTexture.GetTexture(); + } + + NVScopedRefCounted GetBlendFB() + { + return m_BlendFB; + } +#endif + // widget context implementation + virtual NVRenderVertexBuffer & + GetOrCreateVertexBuffer(CRegisteredString &inStr, QT3DSU32 stride, + NVConstDataRef bufferData = NVConstDataRef()) override; + virtual NVRenderIndexBuffer & + GetOrCreateIndexBuffer(CRegisteredString &inStr, + qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef bufferData = NVConstDataRef()) override; + virtual NVRenderAttribLayout & + CreateAttributeLayout(NVConstDataRef attribs) override; + virtual NVRenderInputAssembler & + GetOrCreateInputAssembler(CRegisteredString &inStr, NVRenderAttribLayout *attribLayout, + NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets) override; + + NVRenderVertexBuffer *GetVertexBuffer(CRegisteredString &inStr) override; + NVRenderIndexBuffer *GetIndexBuffer(CRegisteredString &inStr) override; + NVRenderInputAssembler *GetInputAssembler(CRegisteredString &inStr) override; + + NVRenderShaderProgram *GetShader(CRegisteredString inStr) override; + NVRenderShaderProgram *CompileAndStoreShader(CRegisteredString inStr) override; + IShaderProgramGenerator &GetProgramGenerator() override; + + STextDimensions MeasureText(const STextRenderInfo &inText) override; + void RenderText(const STextRenderInfo &inText, const QT3DSVec3 &inTextColor, + const QT3DSVec3 &inBackgroundColor, const QT3DSMat44 &inMVP) override; + + // Given a node and a point in the node's local space (most likely its pivot point), we + // return + // a normal matrix so you can get the axis out, a transformation from node to camera + // a new position and a floating point scale factor so you can render in 1/2 perspective + // mode + // or orthographic mode if you would like to. + virtual SWidgetRenderInformation + GetWidgetRenderInformation(SNode &inNode, const QT3DSVec3 &inPos, + RenderWidgetModes::Enum inWidgetMode) override; + + Option GetLayerMouseCoords(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool forceImageIntersect = false) const override; + + protected: + Option GetLayerMouseCoords(SLayerRenderData &inLayer, const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inViewportDimensions, + bool forceImageIntersect = false) const; + SPickResultProcessResult ProcessPickResultList(bool inPickEverything); + // If the mouse y coordinates need to be flipped we expect that to happen before entry into + // this function + void GetLayerHitObjectList(SLayerRenderData &inLayer, const QT3DSVec2 &inViewportDimensions, + const QT3DSVec2 &inMouseCoords, bool inPickEverything, + TPickResultArray &outIntersectionResult, + NVAllocatorCallback &inTempAllocator); + void IntersectRayWithSubsetRenderable(const SRay &inRay, + SRenderableObject &inRenderableObject, + TPickResultArray &outIntersectionResultList, + NVAllocatorCallback &inTempAllocator); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp new file mode 100644 index 00000000..af3cb613 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp @@ -0,0 +1,2203 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRender.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRendererImpl.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderEffect.h" +#include "EASTL/sort.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderPresentation.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderResourceManager.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderEffectSystem.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "Qt3DSOffscreenRenderKey.h" +#include "Qt3DSRenderPlugin.h" +#include "Qt3DSRenderPluginGraphObject.h" +#include "Qt3DSRenderResourceBufferObjects.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "Qt3DSRenderMaterialHelpers.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderTextTextureCache.h" +#include "Qt3DSRenderTextTextureAtlas.h" +#include "Qt3DSRenderRenderList.h" +#include "Qt3DSRendererUtil.h" + +#ifdef WIN32 +#pragma warning(disable : 4355) +#endif + +#define QT3DS_CACHED_POST_EFFECT +const float QT3DS_DEGREES_TO_RADIANS = 0.0174532925199f; + +namespace qt3ds { +namespace render { + using eastl::reverse; + using eastl::stable_sort; + using qt3ds::render::NVRenderContextScopedProperty; + using qt3ds::QT3DSVec2; + + SLayerRenderData::SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer) + : SLayerRenderPreparationData(inLayer, inRenderer) + , m_LayerTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_TemporalAATexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerPrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerSsaoTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerMultisampleTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerMultisamplePrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerMultisampleWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerCachedTexture(NULL) + , m_AdvancedBlendDrawTexture(NULL) + , m_AdvancedBlendBlendTexture(NULL) + , m_AdvancedModeDrawFB(NULL) + , m_AdvancedModeBlendFB(NULL) + , m_ProgressiveAAPassIndex(0) + , m_TemporalAAPassIndex(0) + , m_NonDirtyTemporalAAPassIndex(0) + , m_TextScale(1.0f) + , mRefCount(0) + , m_DepthBufferFormat(NVRenderTextureFormats::Unknown) + { + } + + SLayerRenderData::~SLayerRenderData() + { + IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); + if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) + theResourceManager.Release(*m_LayerCachedTexture); + if (m_AdvancedModeDrawFB) { + m_AdvancedModeDrawFB->release(); + m_AdvancedModeDrawFB = NULL; + } + if (m_AdvancedModeBlendFB) { + m_AdvancedModeBlendFB->release(); + m_AdvancedModeBlendFB = NULL; + } + if (m_AdvancedBlendBlendTexture) + m_AdvancedBlendBlendTexture = NULL; + if (m_AdvancedBlendDrawTexture) + m_AdvancedBlendDrawTexture = NULL; + } + void SLayerRenderData::PrepareForRender(const QSize &inViewportDimensions) + { + SLayerRenderPreparationData::PrepareForRender(inViewportDimensions); + SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); + IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); + // at that time all values shoud be updated + m_Renderer.UpdateCbAoShadow(&m_Layer, m_Camera, m_LayerDepthTexture); + + // Generate all necessary lighting keys + + if (thePrepResult.m_Flags.WasLayerDataDirty()) { + m_ProgressiveAAPassIndex = 0; + } + + // Get rid of the layer texture if we aren't rendering to texture this frame. + if (m_LayerTexture && !thePrepResult.m_Flags.ShouldRenderToTexture()) { + if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { + theResourceManager.Release(*m_LayerCachedTexture); + m_LayerCachedTexture = NULL; + } + + m_LayerTexture.ReleaseTexture(); + m_LayerDepthTexture.ReleaseTexture(); + m_LayerWidgetTexture.ReleaseTexture(); + m_LayerSsaoTexture.ReleaseTexture(); + m_LayerMultisampleTexture.ReleaseTexture(); + m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); + m_LayerMultisampleWidgetTexture.ReleaseTexture(); + } + + if (NeedsWidgetTexture() == false) + m_LayerWidgetTexture.ReleaseTexture(); + + if (m_LayerDepthTexture && !thePrepResult.m_Flags.RequiresDepthTexture()) + m_LayerDepthTexture.ReleaseTexture(); + + if (m_LayerSsaoTexture && !thePrepResult.m_Flags.RequiresSsaoPass()) + m_LayerSsaoTexture.ReleaseTexture(); + + m_Renderer.LayerNeedsFrameClear(*this); + + // Clean up the texture cache if layer dimensions changed + if (inViewportDimensions.width() != m_previousDimensions.width() + || inViewportDimensions.height() != m_previousDimensions.height()) { + m_LayerTexture.ReleaseTexture(); + m_LayerDepthTexture.ReleaseTexture(); + m_LayerSsaoTexture.ReleaseTexture(); + m_LayerWidgetTexture.ReleaseTexture(); + m_LayerPrepassDepthTexture.ReleaseTexture(); + m_TemporalAATexture.ReleaseTexture(); + m_LayerMultisampleTexture.ReleaseTexture(); + m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); + m_LayerMultisampleWidgetTexture.ReleaseTexture(); + + m_previousDimensions.setWidth(inViewportDimensions.width()); + m_previousDimensions.setHeight(inViewportDimensions.height()); + + theResourceManager.DestroyFreeSizedResources(); + + // Effect system uses different resource manager, so clean that up too + m_Renderer.GetQt3DSContext().GetEffectSystem().GetResourceManager() + .DestroyFreeSizedResources(); + } + } + + NVRenderTextureFormats::Enum SLayerRenderData::GetDepthBufferFormat() + { + if (m_DepthBufferFormat == NVRenderTextureFormats::Unknown) { + QT3DSU32 theExistingDepthBits = m_Renderer.GetContext().GetDepthBits(); + QT3DSU32 theExistingStencilBits = m_Renderer.GetContext().GetStencilBits(); + switch (theExistingDepthBits) { + case 32: + m_DepthBufferFormat = NVRenderTextureFormats::Depth32; + break; + case 24: + // check if we have stencil bits + if (theExistingStencilBits > 0) + m_DepthBufferFormat = + NVRenderTextureFormats::Depth24Stencil8; // currently no stencil usage + // should be Depth24Stencil8 in + // this case + else + m_DepthBufferFormat = NVRenderTextureFormats::Depth24; + break; + case 16: + m_DepthBufferFormat = NVRenderTextureFormats::Depth16; + break; + default: + QT3DS_ASSERT(false); + m_DepthBufferFormat = NVRenderTextureFormats::Depth16; + break; + } + } + return m_DepthBufferFormat; + } + + NVRenderFrameBufferAttachments::Enum + SLayerRenderData::GetFramebufferDepthAttachmentFormat(NVRenderTextureFormats::Enum depthFormat) + { + NVRenderFrameBufferAttachments::Enum fmt = NVRenderFrameBufferAttachments::Depth; + + switch (depthFormat) { + case NVRenderTextureFormats::Depth16: + case NVRenderTextureFormats::Depth24: + case NVRenderTextureFormats::Depth32: + fmt = NVRenderFrameBufferAttachments::Depth; + break; + case NVRenderTextureFormats::Depth24Stencil8: + fmt = NVRenderFrameBufferAttachments::DepthStencil; + break; + default: + QT3DS_ASSERT(false); + break; + } + + return fmt; + } + + void SLayerRenderData::RenderAoPass() + { + m_Renderer.BeginLayerDepthPassRender(*this); + + NVRenderContext &theContext(m_Renderer.GetContext()); + SDefaultAoPassShader *shader = m_Renderer.GetDefaultAoPassShader(GetShaderFeatureSet()); + if (shader == NULL) + return; + + // Set initial state + theContext.SetBlendingEnabled(false); + theContext.SetDepthWriteEnabled(false); + theContext.SetDepthTestEnabled(false); + theContext.SetActiveShader(&(shader->m_Shader)); + + // Setup constants + shader->m_CameraDirection.Set(m_CameraDirection); + shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform); + + shader->m_DepthTexture.Set(m_LayerDepthTexture); + shader->m_DepthSamplerSize.Set(QT3DSVec2(m_LayerDepthTexture->GetTextureDetails().m_Width, + m_LayerDepthTexture->GetTextureDetails().m_Height)); + + // Important uniforms for AO calculations + QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); + shader->m_CameraProperties.Set(theCameraProps); + shader->m_AoShadowParams.Set(); + + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + + m_Renderer.EndLayerDepthPassRender(); + } + + void SLayerRenderData::RenderFakeDepthMapPass(NVRenderTexture2D *theDepthTex, + NVRenderTextureCube *theDepthCube) + { + m_Renderer.BeginLayerDepthPassRender(*this); + + NVRenderContext &theContext(m_Renderer.GetContext()); + SDefaultAoPassShader *shader = theDepthTex + ? m_Renderer.GetFakeDepthShader(GetShaderFeatureSet()) + : m_Renderer.GetFakeCubeDepthShader(GetShaderFeatureSet()); + if (shader == NULL) + return; + + // Set initial state + theContext.SetBlendingEnabled(false); + theContext.SetDepthWriteEnabled(false); + theContext.SetDepthTestEnabled(false); + theContext.SetActiveShader(&(shader->m_Shader)); + + // Setup constants + shader->m_CameraDirection.Set(m_CameraDirection); + shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform); + + shader->m_DepthTexture.Set(theDepthTex); + shader->m_CubeTexture.Set(theDepthCube); + shader->m_DepthSamplerSize.Set(QT3DSVec2(theDepthTex->GetTextureDetails().m_Width, + theDepthTex->GetTextureDetails().m_Height)); + + // Important uniforms for AO calculations + QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); + shader->m_CameraProperties.Set(theCameraProps); + shader->m_AoShadowParams.Set(); + + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + } + + namespace { + + void computeFrustumBounds(const SCamera &inCamera, const NVRenderRectF &inViewPort, + QT3DSVec3 &ctrBound, QT3DSVec3 camVerts[8]) + { + QT3DSVec3 camEdges[4]; + + const QT3DSF32 *dataPtr(inCamera.m_GlobalTransform.front()); + QT3DSVec3 camX(dataPtr[0], dataPtr[1], dataPtr[2]); + QT3DSVec3 camY(dataPtr[4], dataPtr[5], dataPtr[6]); + QT3DSVec3 camZ(dataPtr[8], dataPtr[9], dataPtr[10]); + + float tanFOV = tanf(inCamera.verticalFov(inViewPort) * 0.5f); + float asTanFOV = tanFOV * inViewPort.m_Width / inViewPort.m_Height; + camEdges[0] = -asTanFOV * camX + tanFOV * camY + camZ; + camEdges[1] = asTanFOV * camX + tanFOV * camY + camZ; + camEdges[2] = asTanFOV * camX - tanFOV * camY + camZ; + camEdges[3] = -asTanFOV * camX - tanFOV * camY + camZ; + + for (int i = 0; i < 4; ++i) { + camEdges[i].x = -camEdges[i].x; + camEdges[i].y = -camEdges[i].y; + } + + camVerts[0] = inCamera.m_Position + camEdges[0] * inCamera.m_ClipNear; + camVerts[1] = inCamera.m_Position + camEdges[0] * inCamera.m_ClipFar; + camVerts[2] = inCamera.m_Position + camEdges[1] * inCamera.m_ClipNear; + camVerts[3] = inCamera.m_Position + camEdges[1] * inCamera.m_ClipFar; + camVerts[4] = inCamera.m_Position + camEdges[2] * inCamera.m_ClipNear; + camVerts[5] = inCamera.m_Position + camEdges[2] * inCamera.m_ClipFar; + camVerts[6] = inCamera.m_Position + camEdges[3] * inCamera.m_ClipNear; + camVerts[7] = inCamera.m_Position + camEdges[3] * inCamera.m_ClipFar; + + ctrBound = camVerts[0]; + for (int i = 1; i < 8; ++i) { + ctrBound += camVerts[i]; + } + ctrBound *= 0.125f; + } + + void SetupCameraForShadowMap(const QT3DSVec2 &inCameraVec, NVRenderContext & /*inContext*/, + const NVRenderRectF &inViewport, const SCamera &inCamera, + const SLight *inLight, SCamera &theCamera) + { + // setup light matrix + QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes; + NVRenderRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes); + theCamera.m_ClipNear = 1.0f; + theCamera.m_ClipFar = inLight->m_ShadowMapFar; + // Setup camera projection + QT3DSVec3 inLightPos = inLight->GetGlobalPos(); + QT3DSVec3 inLightDir = inLight->GetDirection(); + + if (inLight->m_Flags.IsLeftHanded()) + inLightPos.z = -inLightPos.z; + + inLightPos -= inLightDir * inCamera.m_ClipNear; + theCamera.m_FOV = inLight->m_ShadowMapFov * QT3DS_DEGREES_TO_RADIANS; + + if (inLight->m_LightType == RenderLightTypes::Directional) { + QT3DSVec3 frustBounds[8], boundCtr; + computeFrustumBounds(inCamera, inViewport, boundCtr, frustBounds); + + QT3DSVec3 forward = inLightDir; + forward.normalize(); + QT3DSVec3 right = forward.cross(QT3DSVec3(0, 1, 0)); + right.normalize(); + QT3DSVec3 up = right.cross(forward); + up.normalize(); + + // Calculate bounding box of the scene camera frustum + float minDistanceZ = std::numeric_limits::max(); + float maxDistanceZ = -std::numeric_limits::max(); + float minDistanceY = std::numeric_limits::max(); + float maxDistanceY = -std::numeric_limits::max(); + float minDistanceX = std::numeric_limits::max(); + float maxDistanceX = -std::numeric_limits::max(); + for (int i = 0; i < 8; ++i) { + float distanceZ = frustBounds[i].dot(forward); + if (distanceZ < minDistanceZ) + minDistanceZ = distanceZ; + if (distanceZ > maxDistanceZ) + maxDistanceZ = distanceZ; + float distanceY = frustBounds[i].dot(up); + if (distanceY < minDistanceY) + minDistanceY = distanceY; + if (distanceY > maxDistanceY) + maxDistanceY = distanceY; + float distanceX = frustBounds[i].dot(right); + if (distanceX < minDistanceX) + minDistanceX = distanceX; + if (distanceX > maxDistanceX) + maxDistanceX = distanceX; + } + + // Apply bounding box parameters to shadow map camera projection matrix + // so that the whole scene is fit inside the shadow map + inLightPos = boundCtr; + theViewport.m_Height = abs(maxDistanceY - minDistanceY); + theViewport.m_Width = abs(maxDistanceX - minDistanceX); + theCamera.m_ClipNear = -abs(maxDistanceZ - minDistanceZ); + theCamera.m_ClipFar = abs(maxDistanceZ - minDistanceZ); + } + + theCamera.m_Flags.SetLeftHanded(false); + + theCamera.m_Flags.ClearOrSet(inLight->m_LightType == RenderLightTypes::Directional, + NodeFlagValues::Orthographic); + theCamera.m_Parent = NULL; + theCamera.m_Pivot = inLight->m_Pivot; + + if (inLight->m_LightType != RenderLightTypes::Point) { + theCamera.LookAt(inLightPos, QT3DSVec3(0, 1.0, 0), inLightPos + inLightDir); + } else { + theCamera.LookAt(inLightPos, QT3DSVec3(0, 1.0, 0), QT3DSVec3(0, 0, 0)); + } + + theCamera.CalculateGlobalVariables(theViewport, + QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); + } + } + + void SetupCubeShadowCameras(const SLight *inLight, SCamera inCameras[6]) + { + // setup light matrix + QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes; + NVRenderRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes); + QT3DSVec3 rotOfs[6]; + + QT3DS_ASSERT(inLight != NULL); + QT3DS_ASSERT(inLight->m_LightType != RenderLightTypes::Directional); + + QT3DSVec3 inLightPos = inLight->GetGlobalPos(); + if (inLight->m_Flags.IsLeftHanded()) + inLightPos.z = -inLightPos.z; + + rotOfs[0] = QT3DSVec3(0.f, -NVHalfPi, NVPi); + rotOfs[1] = QT3DSVec3(0.f, NVHalfPi, NVPi); + rotOfs[2] = QT3DSVec3(NVHalfPi, 0.f, 0.f); + rotOfs[3] = QT3DSVec3(-NVHalfPi, 0.f, 0.f); + rotOfs[4] = QT3DSVec3(0.f, NVPi, -NVPi); + rotOfs[5] = QT3DSVec3(0.f, 0.f, NVPi); + + for (int i = 0; i < 6; ++i) { + inCameras[i].m_Flags.SetLeftHanded(false); + + inCameras[i].m_Flags.ClearOrSet(false, NodeFlagValues::Orthographic); + inCameras[i].m_Parent = NULL; + inCameras[i].m_Pivot = inLight->m_Pivot; + inCameras[i].m_ClipNear = 1.0f; + inCameras[i].m_ClipFar = NVMax(2.0f, inLight->m_ShadowMapFar); + inCameras[i].m_FOV = inLight->m_ShadowMapFov * QT3DS_DEGREES_TO_RADIANS; + + inCameras[i].m_Position = inLightPos; + inCameras[i].m_Rotation = rotOfs[i]; + inCameras[i].CalculateGlobalVariables( + theViewport, QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); + } + + /* + if ( inLight->m_LightType == RenderLightTypes::Point ) return; + + QT3DSVec3 viewDirs[6]; + QT3DSVec3 viewUp[6]; + QT3DSMat33 theDirMatrix( inLight->m_GlobalTransform.getUpper3x3() ); + + viewDirs[0] = theDirMatrix.transform( QT3DSVec3( 1.f, 0.f, 0.f ) ); + viewDirs[2] = theDirMatrix.transform( QT3DSVec3( 0.f, -1.f, 0.f ) ); + viewDirs[4] = theDirMatrix.transform( QT3DSVec3( 0.f, 0.f, 1.f ) ); + viewDirs[0].normalize(); viewDirs[2].normalize(); viewDirs[4].normalize(); + viewDirs[1] = -viewDirs[0]; + viewDirs[3] = -viewDirs[2]; + viewDirs[5] = -viewDirs[4]; + + viewUp[0] = viewDirs[2]; + viewUp[1] = viewDirs[2]; + viewUp[2] = viewDirs[5]; + viewUp[3] = viewDirs[4]; + viewUp[4] = viewDirs[2]; + viewUp[5] = viewDirs[2]; + + for (int i = 0; i < 6; ++i) + { + inCameras[i].LookAt( inLightPos, viewUp[i], inLightPos + viewDirs[i] ); + inCameras[i].CalculateGlobalVariables( theViewport, QT3DSVec2( theViewport.m_Width, + theViewport.m_Height ) ); + } + */ + } + + inline void RenderRenderableShadowMapPass(SLayerRenderData &inData, SRenderableObject &inObject, + const QT3DSVec2 &inCameraProps, TShaderFeatureSet, + QT3DSU32 lightIndex, const SCamera &inCamera) + { + if (!inObject.m_RenderableFlags.IsShadowCaster()) + return; + + SShadowMapEntry *pEntry = inData.m_ShadowMapManager->GetShadowMapEntry(lightIndex); + + if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) + static_cast(inObject).RenderShadowMapPass( + inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); + else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { + static_cast(inObject).RenderShadowMapPass( + inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); + } else if (inObject.m_RenderableFlags.IsPath()) { + static_cast(inObject).RenderShadowMapPass( + inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); + } + } + + void SLayerRenderData::RenderShadowCubeBlurPass(CResourceFrameBuffer *theFB, + NVRenderTextureCube *target0, + NVRenderTextureCube *target1, QT3DSF32 filterSz, + QT3DSF32 clipFar) + { + NVRenderContext &theContext(m_Renderer.GetContext()); + + SShadowmapPreblurShader *shaderX = m_Renderer.GetCubeShadowBlurXShader(); + SShadowmapPreblurShader *shaderY = m_Renderer.GetCubeShadowBlurYShader(); + + if (shaderX == NULL) + return; + if (shaderY == NULL) + return; + // if ( theShader == NULL ) return; + + // Enable drawing to 6 color attachment buffers for cubemap passes + qt3ds::QT3DSI32 buffers[6] = { 0, 1, 2, 3, 4, 5 }; + qt3ds::foundation::NVConstDataRef bufferList(buffers, 6); + theContext.SetDrawBuffers(bufferList); + + // Attach framebuffer targets + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, *target1, + NVRenderTextureCubeFaces::CubePosX); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, *target1, + NVRenderTextureCubeFaces::CubeNegX); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, *target1, + NVRenderTextureCubeFaces::CubePosY); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, *target1, + NVRenderTextureCubeFaces::CubeNegY); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, *target1, + NVRenderTextureCubeFaces::CubePosZ); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, *target1, + NVRenderTextureCubeFaces::CubeNegZ); + + // Set initial state + theContext.SetBlendingEnabled(false); + theContext.SetDepthWriteEnabled(false); + theContext.SetDepthTestEnabled(false); + // theContext.SetColorWritesEnabled(true); + theContext.SetActiveShader(&(shaderX->m_Shader)); + + shaderX->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); + shaderX->m_DepthCube.Set(target0); + + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + + theContext.SetActiveShader(&(shaderY->m_Shader)); + + // Lather, Rinse, and Repeat for the Y-blur pass + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, *target0, + NVRenderTextureCubeFaces::CubePosX); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, *target0, + NVRenderTextureCubeFaces::CubeNegX); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, *target0, + NVRenderTextureCubeFaces::CubePosY); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, *target0, + NVRenderTextureCubeFaces::CubeNegY); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, *target0, + NVRenderTextureCubeFaces::CubePosZ); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, *target0, + NVRenderTextureCubeFaces::CubeNegZ); + + shaderY->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); + shaderY->m_DepthCube.Set(target1); + + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + + theContext.SetDepthWriteEnabled(true); + theContext.SetDepthTestEnabled(true); + // theContext.SetColorWritesEnabled(false); + + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer(), + NVRenderTextureCubeFaces::CubePosX); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, NVRenderTextureOrRenderBuffer(), + NVRenderTextureCubeFaces::CubeNegX); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, NVRenderTextureOrRenderBuffer(), + NVRenderTextureCubeFaces::CubePosY); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, NVRenderTextureOrRenderBuffer(), + NVRenderTextureCubeFaces::CubeNegY); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, NVRenderTextureOrRenderBuffer(), + NVRenderTextureCubeFaces::CubePosZ); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, NVRenderTextureOrRenderBuffer(), + NVRenderTextureCubeFaces::CubeNegZ); + + theContext.SetDrawBuffers(qt3ds::foundation::toConstDataRef((qt3ds::QT3DSI32)0)); + } + + void SLayerRenderData::RenderShadowMapBlurPass(CResourceFrameBuffer *theFB, + NVRenderTexture2D *target0, + NVRenderTexture2D *target1, QT3DSF32 filterSz, + QT3DSF32 clipFar) + { + NVRenderContext &theContext(m_Renderer.GetContext()); + + SShadowmapPreblurShader *shaderX = m_Renderer.GetOrthoShadowBlurXShader(); + SShadowmapPreblurShader *shaderY = m_Renderer.GetOrthoShadowBlurYShader(); + + if (shaderX == NULL) + return; + if (shaderY == NULL) + return; + + // Attach framebuffer target + (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *target1); + //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, *target1 ); + + // Set initial state + theContext.SetBlendingEnabled(false); + theContext.SetDepthWriteEnabled(false); + theContext.SetDepthTestEnabled(false); + theContext.SetColorWritesEnabled(true); + theContext.SetActiveShader(&(shaderX->m_Shader)); + + shaderX->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); + shaderX->m_DepthMap.Set(target0); + + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + + (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *target0); + //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, *target0 ); + theContext.SetActiveShader(&(shaderY->m_Shader)); + + shaderY->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); + shaderY->m_DepthMap.Set(target1); + + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + + theContext.SetDepthWriteEnabled(true); + theContext.SetDepthTestEnabled(true); + theContext.SetColorWritesEnabled(false); + + //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, + //NVRenderTextureOrRenderBuffer() ); + (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); + } + + void SLayerRenderData::RenderShadowMapPass(CResourceFrameBuffer *theFB) + { + SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), + "SLayerRenderData::RenderShadowMapPass"); + + if (m_Camera == NULL || !GetShadowMapManager()) + return; + + // Check if we have anything to render + if (m_OpaqueObjects.size() == 0 || m_Lights.size() == 0) + return; + + m_Renderer.BeginLayerDepthPassRender(*this); + + NVRenderContext &theRenderContext(m_Renderer.GetContext()); + + // we may change the viewport + NVRenderContextScopedProperty __viewport( + theRenderContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); + + // disable color writes + // theRenderContext.SetColorWritesEnabled( false ); + theRenderContext.SetColorWritesEnabled(true); + theRenderContext.SetDepthWriteEnabled(true); + theRenderContext.SetCullingEnabled(false); + theRenderContext.SetClearColor(QT3DSVec4(1.0f)); + + // we render the shadow map with a slight offset to prevent shadow acne and cull the front + // faces + NVScopedRefCounted rsdefaultstate = + theRenderContext.CreateRasterizerState(0.0, 0.0, qt3ds::render::NVRenderFaces::Back); + NVScopedRefCounted rsstate = + theRenderContext.CreateRasterizerState(1.5, 2.0, qt3ds::render::NVRenderFaces::Front); + theRenderContext.SetRasterizerState(rsstate); + + qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Depth + | qt3ds::render::NVRenderClearValues::Stencil + | qt3ds::render::NVRenderClearValues::Color); + + for (QT3DSU32 i = 0; i < m_Lights.size(); i++) { + // don't render shadows when not casting + if (m_Lights[i]->m_CastShadow == false) + continue; + SShadowMapEntry *pEntry = m_ShadowMapManager->GetShadowMapEntry(i); + if (pEntry && pEntry->m_DepthMap && pEntry->m_DepthCopy && pEntry->m_DepthRender) { + SCamera theCamera; + + QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); + SetupCameraForShadowMap(theCameraProps, m_Renderer.GetContext(), + __viewport.m_InitialValue, *m_Camera, + m_Lights[i], theCamera); + // we need this matrix for the final rendering + theCamera.CalculateViewProjectionMatrix(pEntry->m_LightVP); + pEntry->m_LightView = theCamera.m_GlobalTransform.getInverse(); + + STextureDetails theDetails(pEntry->m_DepthMap->GetTextureDetails()); + theRenderContext.SetViewport( + NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); + + (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *pEntry->m_DepthMap); + (*theFB)->Attach(NVRenderFrameBufferAttachments::DepthStencil, + *pEntry->m_DepthRender); + theRenderContext.Clear(clearFlags); + + RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i, theCamera); + RenderShadowMapBlurPass(theFB, pEntry->m_DepthMap, pEntry->m_DepthCopy, + m_Lights[i]->m_ShadowFilter, m_Lights[i]->m_ShadowMapFar); + } else if (pEntry && pEntry->m_DepthCube && pEntry->m_CubeCopy + && pEntry->m_DepthRender) { + SCamera theCameras[6]; + + SetupCubeShadowCameras(m_Lights[i], theCameras); + + // pEntry->m_LightView = m_Lights[i]->m_LightType == RenderLightTypes::Point ? + // QT3DSMat44::createIdentity() + // : m_Lights[i]->m_GlobalTransform; + pEntry->m_LightView = QT3DSMat44::createIdentity(); + + STextureDetails theDetails(pEntry->m_DepthCube->GetTextureDetails()); + theRenderContext.SetViewport( + NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); + + // int passes = m_Lights[i]->m_LightType == RenderLightTypes::Point ? 6 : 5; + int passes = 6; + for (int k = 0; k < passes; ++k) { + // theCameras[k].CalculateViewProjectionMatrix( pEntry->m_LightCubeVP[k] ); + pEntry->m_LightCubeView[k] = theCameras[k].m_GlobalTransform.getInverse(); + theCameras[k].CalculateViewProjectionMatrix(pEntry->m_LightVP); + + // Geometry shader multiplication really doesn't work unless you have a + // 6-layered 3D depth texture... + // Otherwise, you have no way to depth test while rendering... + // which more or less completely defeats the purpose of having a cubemap render + // target. + NVRenderTextureCubeFaces::Enum curFace = + (NVRenderTextureCubeFaces::Enum)(k + 1); + //(*theFB)->AttachFace( NVRenderFrameBufferAttachments::DepthStencil, + //*pEntry->m_DepthCube, curFace ); + (*theFB)->Attach(NVRenderFrameBufferAttachments::DepthStencil, + *pEntry->m_DepthRender); + (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, + *pEntry->m_DepthCube, curFace); + (*theFB)->IsComplete(); + theRenderContext.Clear(clearFlags); + + RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i, + theCameras[k]); + } + + RenderShadowCubeBlurPass(theFB, pEntry->m_DepthCube, pEntry->m_CubeCopy, + m_Lights[i]->m_ShadowFilter, m_Lights[i]->m_ShadowMapFar); + } + } + + (*theFB)->Attach(NVRenderFrameBufferAttachments::Depth, NVRenderTextureOrRenderBuffer()); + (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); + + // enable color writes + theRenderContext.SetColorWritesEnabled(true); + theRenderContext.SetCullingEnabled(true); + theRenderContext.SetClearColor(QT3DSVec4(0.0f)); + // reset rasterizer state + theRenderContext.SetRasterizerState(rsdefaultstate); + + m_Renderer.EndLayerDepthPassRender(); + } + + inline void RenderRenderableDepthPass(SLayerRenderData &inData, SRenderableObject &inObject, + const QT3DSVec2 &inCameraProps, TShaderFeatureSet, QT3DSU32, + const SCamera &inCamera) + { + if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) + static_cast(inObject).RenderDepthPass(inCameraProps); + else if (inObject.m_RenderableFlags.IsText()) + static_cast(inObject).RenderDepthPass(inCameraProps); + else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { + static_cast(inObject).RenderDepthPass( + inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, NULL); + } else if (inObject.m_RenderableFlags.IsPath()) { + static_cast(inObject).RenderDepthPass( + inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, NULL); + } else { + QT3DS_ASSERT(false); + } + } + + void SLayerRenderData::RenderDepthPass(bool inEnableTransparentDepthWrite) + { + SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), + "SLayerRenderData::RenderDepthPass"); + if (m_Camera == NULL) + return; + + // Avoid running this method if possible. + if ((inEnableTransparentDepthWrite == false + && (m_OpaqueObjects.size() == 0 + || m_Layer.m_Flags.IsLayerEnableDepthPrepass() == false)) + || m_Layer.m_Flags.IsLayerEnableDepthTest() == false) + return; + + m_Renderer.BeginLayerDepthPassRender(*this); + + NVRenderContext &theRenderContext(m_Renderer.GetContext()); + + // disable color writes + theRenderContext.SetColorWritesEnabled(false); + theRenderContext.SetDepthWriteEnabled(true); + + qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Stencil + | qt3ds::render::NVRenderClearValues::Depth); + theRenderContext.Clear(clearFlags); + + RunRenderPass(RenderRenderableDepthPass, false, true, inEnableTransparentDepthWrite, 0, + *m_Camera); + + // enable color writes + theRenderContext.SetColorWritesEnabled(true); + + m_Renderer.EndLayerDepthPassRender(); + } + + inline void RenderRenderable(SLayerRenderData &inData, SRenderableObject &inObject, + const QT3DSVec2 &inCameraProps, TShaderFeatureSet inFeatureSet, QT3DSU32, + const SCamera &inCamera) + { + if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) + static_cast(inObject).Render(inCameraProps, inFeatureSet); + else if (inObject.m_RenderableFlags.IsText()) + static_cast(inObject).Render(inCameraProps); + else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { + // PKC : Need a better place to do this. + SCustomMaterialRenderable &theObject = + static_cast(inObject); + if (!inData.m_Layer.m_LightProbe && theObject.m_Material.m_IblProbe) + inData.SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", + theObject.m_Material.m_IblProbe->m_TextureData.m_Texture + != NULL); + else if (inData.m_Layer.m_LightProbe) + inData.SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", + inData.m_Layer.m_LightProbe->m_TextureData.m_Texture + != NULL); + + static_cast(inObject).Render( + inCameraProps, inData, inData.m_Layer, inData.m_Lights, inCamera, + inData.m_LayerDepthTexture, inData.m_LayerSsaoTexture, inFeatureSet); + } else if (inObject.m_RenderableFlags.IsPath()) { + static_cast(inObject).Render( + inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, + inData.m_LayerDepthTexture, inData.m_LayerSsaoTexture, inFeatureSet); + } else { + QT3DS_ASSERT(false); + } + } + + void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, + bool inEnableBlending, bool inEnableDepthWrite, + bool inEnableTransparentDepthWrite, QT3DSU32 indexLight, + const SCamera &inCamera, CResourceFrameBuffer *theFB) + { + NVRenderContext &theRenderContext(m_Renderer.GetContext()); + theRenderContext.SetDepthFunction(qt3ds::render::NVRenderBoolOp::LessThanOrEqual); + theRenderContext.SetBlendingEnabled(false); + QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); + NVDataRef theOpaqueObjects = GetOpaqueRenderableObjects(); + bool usingDepthBuffer = + m_Layer.m_Flags.IsLayerEnableDepthTest() && theOpaqueObjects.size() > 0; + + if (usingDepthBuffer) { + theRenderContext.SetDepthTestEnabled(true); + theRenderContext.SetDepthWriteEnabled(inEnableDepthWrite); + } else { + theRenderContext.SetDepthWriteEnabled(false); + theRenderContext.SetDepthTestEnabled(false); + } + + for (QT3DSU32 idx = 0, end = theOpaqueObjects.size(); idx < end; ++idx) { + SRenderableObject &theObject(*theOpaqueObjects[idx]); + SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, m_SourceLightDirections, + theObject.m_ScopedLights); + SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); + inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), indexLight, + inCamera); + } + + // transparent objects + if (inEnableBlending || m_Layer.m_Flags.IsLayerEnableDepthTest() == false) { + theRenderContext.SetBlendingEnabled(true && inEnableBlending); + theRenderContext.SetDepthWriteEnabled(inEnableTransparentDepthWrite); + + NVDataRef theTransparentObjects = GetTransparentRenderableObjects(); + // Assume all objects have transparency if the layer's depth test enabled flag is true. + if (m_Layer.m_Flags.IsLayerEnableDepthTest() == true) { + for (QT3DSU32 idx = 0, end = theTransparentObjects.size(); idx < end; ++idx) { + SRenderableObject &theObject(*theTransparentObjects[idx]); + if (!(theObject.m_RenderableFlags.IsCompletelyTransparent())) { +#ifdef ADVANCED_BLEND_SW_FALLBACK + // SW fallback for advanced blend modes. + // Renders transparent objects to a separate FBO and blends them in shader + // with the opaque items and background. + DefaultMaterialBlendMode::Enum blendMode + = DefaultMaterialBlendMode::Enum::Normal; + if (theObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) + blendMode = static_cast(theObject).getBlendingMode(); + bool useBlendFallback = (blendMode == DefaultMaterialBlendMode::Overlay || + blendMode == DefaultMaterialBlendMode::ColorBurn || + blendMode == DefaultMaterialBlendMode::ColorDodge) && + !theRenderContext.IsAdvancedBlendHwSupported() && + !theRenderContext.IsAdvancedBlendHwSupportedKHR() && + m_LayerPrepassDepthTexture; + if (useBlendFallback) + SetupDrawFB(true); +#endif + SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, + m_SourceLightDirections, + theObject.m_ScopedLights); + SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); + + inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), + indexLight, inCamera); +#ifdef ADVANCED_BLEND_SW_FALLBACK + // SW fallback for advanced blend modes. + // Continue blending after transparent objects have been rendered to a FBO + if (useBlendFallback) { + BlendAdvancedToFB(blendMode, true, theFB); + // restore blending status + theRenderContext.SetBlendingEnabled(inEnableBlending); + // restore depth test status + theRenderContext.SetDepthTestEnabled(usingDepthBuffer); + theRenderContext.SetDepthWriteEnabled(inEnableTransparentDepthWrite); + } +#endif + } + } + } + // If the layer doesn't have depth enabled then we have to render via an alternate route + // where the transparent objects vector could have both opaque and transparent objects. + else { + for (QT3DSU32 idx = 0, end = theTransparentObjects.size(); idx < end; ++idx) { + SRenderableObject &theObject(*theTransparentObjects[idx]); + if (!(theObject.m_RenderableFlags.IsCompletelyTransparent())) { +#ifdef ADVANCED_BLEND_SW_FALLBACK + DefaultMaterialBlendMode::Enum blendMode + = DefaultMaterialBlendMode::Enum::Normal; + if (theObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) + blendMode = static_cast(theObject).getBlendingMode(); + bool useBlendFallback = (blendMode == DefaultMaterialBlendMode::Overlay || + blendMode == DefaultMaterialBlendMode::ColorBurn || + blendMode == DefaultMaterialBlendMode::ColorDodge) && + !theRenderContext.IsAdvancedBlendHwSupported() && + !theRenderContext.IsAdvancedBlendHwSupportedKHR(); + + if (theObject.m_RenderableFlags.HasTransparency()) { + theRenderContext.SetBlendingEnabled(true && inEnableBlending); + // If we have SW fallback for blend mode, render to a FBO and blend back. + // Slow as this must be done per-object (transparent and opaque items + // are mixed, not batched) + if (useBlendFallback) + SetupDrawFB(false); + } +#endif + SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, + m_SourceLightDirections, + theObject.m_ScopedLights); + SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); + inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), + indexLight, inCamera); +#ifdef ADVANCED_BLEND_SW_FALLBACK + if (useBlendFallback) { + BlendAdvancedToFB(blendMode, false, theFB); + // restore blending status + theRenderContext.SetBlendingEnabled(inEnableBlending); + + } +#endif + } + } + } + } + } + + void SLayerRenderData::Render(CResourceFrameBuffer *theFB) + { + SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), + "SLayerRenderData::Render"); + if (m_Camera == NULL) + return; + + m_Renderer.BeginLayerRender(*this); + RunRenderPass(RenderRenderable, true, !m_Layer.m_Flags.IsLayerEnableDepthPrepass(), false, + 0, *m_Camera, theFB); + m_Renderer.EndLayerRender(); + } + + void SLayerRenderData::CreateGpuProfiler() + { + if (m_Renderer.GetContext().IsTimerQuerySupported()) { + m_LayerProfilerGpu = IRenderProfiler::CreateGpuProfiler( + m_Renderer.GetContext().GetFoundation(), m_Renderer.GetQt3DSContext(), + m_Renderer.GetContext()); + } + } + + void SLayerRenderData::StartProfiling(CRegisteredString &nameID, bool sync) + { + if (m_LayerProfilerGpu.mPtr) { + m_LayerProfilerGpu->StartTimer(nameID, false, sync); + } + } + + void SLayerRenderData::EndProfiling(CRegisteredString &nameID) + { + if (m_LayerProfilerGpu.mPtr) { + m_LayerProfilerGpu->EndTimer(nameID); + } + } + + void SLayerRenderData::StartProfiling(const char *nameID, bool sync) + { + if (m_LayerProfilerGpu.mPtr) { + CRegisteredString theStr( + m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(nameID)); + m_LayerProfilerGpu->StartTimer(theStr, false, sync); + } + } + + void SLayerRenderData::EndProfiling(const char *nameID) + { + if (m_LayerProfilerGpu.mPtr) { + CRegisteredString theStr( + m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(nameID)); + m_LayerProfilerGpu->EndTimer(theStr); + } + } + + void SLayerRenderData::AddVertexCount(QT3DSU32 count) + { + if (m_LayerProfilerGpu.mPtr) { + m_LayerProfilerGpu->AddVertexCount(count); + } + } + + // Assumes the viewport is setup appropriately to render the widget. + void SLayerRenderData::RenderRenderWidgets() + { + if (m_Camera) { + NVRenderContext &theContext(m_Renderer.GetContext()); + for (QT3DSU32 idx = 0, end = m_IRenderWidgets.size(); idx < end; ++idx) { + IRenderWidget &theWidget = *m_IRenderWidgets[idx]; + theWidget.Render(m_Renderer, theContext); + } + } + } + +#ifdef ADVANCED_BLEND_SW_FALLBACK + void SLayerRenderData::BlendAdvancedEquationSwFallback(NVRenderTexture2D *drawTexture, + NVRenderTexture2D *layerTexture, + AdvancedBlendModes::Enum blendMode) + { + NVRenderContext &theContext(m_Renderer.GetContext()); + SAdvancedModeBlendShader *shader = m_Renderer.GetAdvancedBlendModeShader(blendMode); + if (shader == NULL) + return; + + theContext.SetActiveShader(&(shader->m_Shader)); + + shader->m_baseLayer.Set(layerTexture); + shader->m_blendLayer.Set(drawTexture); + // Draw a fullscreen quad + m_Renderer.RenderQuad(); + } + + void SLayerRenderData::SetupDrawFB(bool depthEnabled) + { + NVRenderContext &theRenderContext(m_Renderer.GetContext()); + // create drawing FBO and texture, if not existing + if (!m_AdvancedModeDrawFB) + m_AdvancedModeDrawFB = theRenderContext.CreateFrameBuffer(); + if (!m_AdvancedBlendDrawTexture) { + m_AdvancedBlendDrawTexture = theRenderContext.CreateTexture2D(); + NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); + m_AdvancedBlendDrawTexture->SetTextureData(NVDataRef(), 0, + theViewport.m_Width, + theViewport.m_Height, + NVRenderTextureFormats::RGBA8); + m_AdvancedModeDrawFB->Attach(NVRenderFrameBufferAttachments::Color0, + *m_AdvancedBlendDrawTexture); + // Use existing depth prepass information when rendering transparent objects to a FBO + if (depthEnabled) + m_AdvancedModeDrawFB->Attach(NVRenderFrameBufferAttachments::Depth, + *m_LayerPrepassDepthTexture); + } + theRenderContext.SetRenderTarget(m_AdvancedModeDrawFB); + // make sure that depth testing is on in order to render just the + // depth-passed objects (=transparent objects) and leave background intact + if (depthEnabled) + theRenderContext.SetDepthTestEnabled(true); + theRenderContext.SetBlendingEnabled(false); + // clear color commonly is the layer background, make sure that it is all-zero here + QT3DSVec4 originalClrColor = theRenderContext.GetClearColor(); + theRenderContext.SetClearColor(QT3DSVec4(0.0)); + theRenderContext.Clear(NVRenderClearValues::Color); + theRenderContext.SetClearColor(originalClrColor); + + } + void SLayerRenderData::BlendAdvancedToFB(DefaultMaterialBlendMode::Enum blendMode, + bool depthEnabled, CResourceFrameBuffer *theFB) + { + NVRenderContext &theRenderContext(m_Renderer.GetContext()); + NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); + AdvancedBlendModes::Enum advancedMode; + + switch (blendMode) { + case DefaultMaterialBlendMode::Overlay: + advancedMode = AdvancedBlendModes::Overlay; + break; + case DefaultMaterialBlendMode::ColorBurn: + advancedMode = AdvancedBlendModes::ColorBurn; + break; + case DefaultMaterialBlendMode::ColorDodge: + advancedMode = AdvancedBlendModes::ColorDodge; + break; + default: + Q_UNREACHABLE(); + } + // create blending FBO and texture if not existing + if (!m_AdvancedModeBlendFB) + m_AdvancedModeBlendFB = theRenderContext.CreateFrameBuffer(); + if (!m_AdvancedBlendBlendTexture) { + m_AdvancedBlendBlendTexture = theRenderContext.CreateTexture2D(); + m_AdvancedBlendBlendTexture->SetTextureData(NVDataRef(), 0, + theViewport.m_Width, + theViewport.m_Height, + NVRenderTextureFormats::RGBA8); + m_AdvancedModeBlendFB->Attach(NVRenderFrameBufferAttachments::Color0, + *m_AdvancedBlendBlendTexture); + } + theRenderContext.SetRenderTarget(m_AdvancedModeBlendFB); + + // Blend transparent objects with SW fallback shaders. + // Disable depth testing as transparent objects have already been + // depth-checked; here we want to run shader for all layer pixels + if (depthEnabled) + { + theRenderContext.SetDepthTestEnabled(false); + theRenderContext.SetDepthWriteEnabled(false); + } + BlendAdvancedEquationSwFallback(m_AdvancedBlendDrawTexture, m_LayerTexture, advancedMode); + theRenderContext.SetRenderTarget(*theFB); + // setup read target + theRenderContext.SetReadTarget(m_AdvancedModeBlendFB); + theRenderContext.SetReadBuffer(NVReadFaces::Color0); + theRenderContext.BlitFramebuffer(0, 0, theViewport.m_Width, theViewport.m_Height, + 0, 0, theViewport.m_Width, theViewport.m_Height, + NVRenderClearValues::Color, + NVRenderTextureMagnifyingOp::Nearest); + } +#endif + + void SLayerRenderData::RenderToViewport() + { + if (m_LayerPrepResult->IsLayerVisible()) { + if (GetOffscreenRenderer()) { + if (m_Layer.m_Background == LayerBackground::Color) { + m_LastFrameOffscreenRenderer->RenderWithClear( + CreateOffscreenRenderEnvironment(), m_Renderer.GetContext(), + m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), + SScene::AlwaysClear, m_Layer.m_ClearColor, &m_Layer); + } else { + m_LastFrameOffscreenRenderer->Render( + CreateOffscreenRenderEnvironment(), m_Renderer.GetContext(), + m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), + SScene::ClearIsOptional, &m_Layer); + } + } else { + RenderDepthPass(false); + Render(); + RenderRenderWidgets(); + } + } + } + // These are meant to be pixel offsets, so you need to divide them by the width/height + // of the layer respectively. + const QT3DSVec2 s_VertexOffsets[SLayerRenderPreparationData::MAX_AA_LEVELS] = { + QT3DSVec2(-0.170840f, -0.553840f), // 1x + QT3DSVec2(0.162960f, -0.319340f), // 2x + QT3DSVec2(0.360260f, -0.245840f), // 3x + QT3DSVec2(-0.561340f, -0.149540f), // 4x + QT3DSVec2(0.249460f, 0.453460f), // 5x + QT3DSVec2(-0.336340f, 0.378260f), // 6x + QT3DSVec2(0.340000f, 0.166260f), // 7x + QT3DSVec2(0.235760f, 0.527760f), // 8x + }; + + // Blend factors are in the form of (frame blend factor, accumulator blend factor) + const QT3DSVec2 s_BlendFactors[SLayerRenderPreparationData::MAX_AA_LEVELS] = { + QT3DSVec2(0.500000f, 0.500000f), // 1x + QT3DSVec2(0.333333f, 0.666667f), // 2x + QT3DSVec2(0.250000f, 0.750000f), // 3x + QT3DSVec2(0.200000f, 0.800000f), // 4x + QT3DSVec2(0.166667f, 0.833333f), // 5x + QT3DSVec2(0.142857f, 0.857143f), // 6x + QT3DSVec2(0.125000f, 0.875000f), // 7x + QT3DSVec2(0.111111f, 0.888889f), // 8x + }; + + const QT3DSVec2 s_TemporalVertexOffsets[SLayerRenderPreparationData::MAX_TEMPORAL_AA_LEVELS] = { + QT3DSVec2(.3f, .3f), QT3DSVec2(-.3f, -.3f) + }; + + static inline void OffsetProjectionMatrix(QT3DSMat44 &inProjectionMatrix, QT3DSVec2 inVertexOffsets) + { + inProjectionMatrix.column3.x = + inProjectionMatrix.column3.x + inProjectionMatrix.column3.w * inVertexOffsets.x; + inProjectionMatrix.column3.y = + inProjectionMatrix.column3.y + inProjectionMatrix.column3.w * inVertexOffsets.y; + } + + CRegisteredString depthPassStr; + + // Render this layer's data to a texture. Required if we have any effects, + // prog AA, or if forced. + void SLayerRenderData::RenderToTexture() + { + QT3DS_ASSERT(m_LayerPrepResult->m_Flags.ShouldRenderToTexture()); + SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); + NVRenderContext &theRenderContext(m_Renderer.GetContext()); + QSize theLayerTextureDimensions = thePrepResult.GetTextureDimensions(); + QSize theLayerOriginalTextureDimensions = theLayerTextureDimensions; + NVRenderTextureFormats::Enum DepthTextureFormat = NVRenderTextureFormats::Depth24Stencil8; + NVRenderTextureFormats::Enum ColorTextureFormat = NVRenderTextureFormats::RGBA8; + if (thePrepResult.m_LastEffect + && theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) { + if (m_Layer.m_Background != LayerBackground::Transparent) + ColorTextureFormat = NVRenderTextureFormats::R11G11B10; + else + ColorTextureFormat = NVRenderTextureFormats::RGBA16F; + } + NVRenderTextureFormats::Enum ColorSSAOTextureFormat = NVRenderTextureFormats::RGBA8; + + bool needsRender = false; + QT3DSU32 sampleCount = 1; + // check multsample mode and MSAA texture support + if (m_Layer.m_MultisampleAAMode != AAModeValues::NoAA + && theRenderContext.AreMultisampleTexturesSupported()) + sampleCount = (QT3DSU32)m_Layer.m_MultisampleAAMode; + + bool isMultisamplePass = false; + if (theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) + isMultisamplePass = + (sampleCount > 1) || (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA); + + qt3ds::render::NVRenderTextureTargetType::Enum thFboAttachTarget = + qt3ds::render::NVRenderTextureTargetType::Texture2D; + + // If the user has disabled all layer caching this has the side effect of disabling the + // progressive AA algorithm. + if (thePrepResult.m_Flags.WasLayerDataDirty() + || thePrepResult.m_Flags.WasDirty() + || m_Renderer.IsLayerCachingEnabled() == false + || thePrepResult.m_Flags.ShouldRenderToTexture()) { + m_ProgressiveAAPassIndex = 0; + m_NonDirtyTemporalAAPassIndex = 0; + needsRender = true; + } + + CResourceTexture2D *renderColorTexture = &m_LayerTexture; + CResourceTexture2D *renderPrepassDepthTexture = &m_LayerPrepassDepthTexture; + CResourceTexture2D *renderWidgetTexture = &m_LayerWidgetTexture; + NVRenderContextScopedProperty __multisampleEnabled( + theRenderContext, &NVRenderContext::IsMultisampleEnabled, + &NVRenderContext::SetMultisampleEnabled); + theRenderContext.SetMultisampleEnabled(false); + if (isMultisamplePass) { + renderColorTexture = &m_LayerMultisampleTexture; + renderPrepassDepthTexture = &m_LayerMultisamplePrepassDepthTexture; + renderWidgetTexture = &m_LayerMultisampleWidgetTexture; + // for SSAA we don't use MS textures + if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) + thFboAttachTarget = qt3ds::render::NVRenderTextureTargetType::Texture2D_MS; + } + QT3DSU32 maxTemporalPassIndex = m_Layer.m_TemporalAAEnabled ? 2 : 0; + + // If all the dimensions match then we do not have to re-render the layer. + if (m_LayerTexture.TextureMatches(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), ColorTextureFormat) + && (!thePrepResult.m_Flags.RequiresDepthTexture() + || m_LayerDepthTexture.TextureMatches(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), + DepthTextureFormat)) + && m_ProgressiveAAPassIndex >= thePrepResult.m_MaxAAPassIndex + && m_NonDirtyTemporalAAPassIndex >= maxTemporalPassIndex && needsRender == false) { + return; + } + + // adjust render size for SSAA + if (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA) { + QT3DSU32 ow, oh; + CRendererUtil::GetSSAARenderSize(theLayerOriginalTextureDimensions.width(), + theLayerOriginalTextureDimensions.height(), + ow, oh); + theLayerTextureDimensions = QSize(ow, oh); + } + + // If our pass index == thePreResult.m_MaxAAPassIndex then + // we shouldn't get into here. + + IResourceManager &theResourceManager = m_Renderer.GetQt3DSContext().GetResourceManager(); + bool hadLayerTexture = true; + + if (renderColorTexture->EnsureTexture(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), + ColorTextureFormat, sampleCount)) { + m_ProgressiveAAPassIndex = 0; + m_NonDirtyTemporalAAPassIndex = 0; + hadLayerTexture = false; + } + + if (thePrepResult.m_Flags.RequiresDepthTexture()) { + // The depth texture doesn't need to be multisample, the prepass depth does. + if (m_LayerDepthTexture.EnsureTexture(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), + DepthTextureFormat)) { + // Depth textures are generally not bilinear filtered. + m_LayerDepthTexture->SetMinFilter(NVRenderTextureMinifyingOp::Nearest); + m_LayerDepthTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Nearest); + m_ProgressiveAAPassIndex = 0; + m_NonDirtyTemporalAAPassIndex = 0; + } + } + + if (thePrepResult.m_Flags.RequiresSsaoPass()) { + if (m_LayerSsaoTexture.EnsureTexture(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), + ColorSSAOTextureFormat)) { + m_LayerSsaoTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + m_LayerSsaoTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + m_ProgressiveAAPassIndex = 0; + m_NonDirtyTemporalAAPassIndex = 0; + } + } + + QT3DS_ASSERT(!thePrepResult.m_Flags.RequiresDepthTexture() || m_LayerDepthTexture); + QT3DS_ASSERT(!thePrepResult.m_Flags.RequiresSsaoPass() || m_LayerSsaoTexture); + + CResourceTexture2D theLastLayerTexture(theResourceManager); + SLayerProgAABlendShader *theBlendShader = NULL; + QT3DSU32 aaFactorIndex = 0; + bool isProgressiveAABlendPass = + m_ProgressiveAAPassIndex && m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex; + bool isTemporalAABlendPass = m_Layer.m_TemporalAAEnabled && m_ProgressiveAAPassIndex == 0; + + if (isProgressiveAABlendPass || isTemporalAABlendPass) { + theBlendShader = m_Renderer.GetLayerProgAABlendShader(); + if (theBlendShader) { + m_LayerTexture.EnsureTexture(theLayerOriginalTextureDimensions.width(), + theLayerOriginalTextureDimensions.height(), + ColorTextureFormat); + QT3DSVec2 theVertexOffsets; + if (isProgressiveAABlendPass) { + theLastLayerTexture.StealTexture(m_LayerTexture); + aaFactorIndex = (m_ProgressiveAAPassIndex - 1); + theVertexOffsets = s_VertexOffsets[aaFactorIndex]; + } else { + if (m_TemporalAATexture.GetTexture()) + theLastLayerTexture.StealTexture(m_TemporalAATexture); + else { + if (hadLayerTexture) { + theLastLayerTexture.StealTexture(m_LayerTexture); + } + } + theVertexOffsets = s_TemporalVertexOffsets[m_TemporalAAPassIndex]; + ++m_TemporalAAPassIndex; + ++m_NonDirtyTemporalAAPassIndex; + m_TemporalAAPassIndex = m_TemporalAAPassIndex % MAX_TEMPORAL_AA_LEVELS; + } + if (theLastLayerTexture.GetTexture()) { + theVertexOffsets.x = + theVertexOffsets.x / (theLayerOriginalTextureDimensions.width() / 2.0f); + theVertexOffsets.y = + theVertexOffsets.y / (theLayerOriginalTextureDimensions.height() / 2.0f); + // Run through all models and update MVP. + // run through all texts and update MVP. + // run through all path and update MVP. + + // TODO - optimize this exact matrix operation. + for (QT3DSU32 idx = 0, end = m_ModelContexts.size(); idx < end; ++idx) { + QT3DSMat44 &originalProjection(m_ModelContexts[idx]->m_ModelViewProjection); + OffsetProjectionMatrix(originalProjection, theVertexOffsets); + } + for (QT3DSU32 idx = 0, end = m_OpaqueObjects.size(); idx < end; ++idx) { + if (m_OpaqueObjects[idx]->m_RenderableFlags.IsPath()) { + SPathRenderable &theRenderable = + static_cast(*m_OpaqueObjects[idx]); + OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, + theVertexOffsets); + } + } + for (QT3DSU32 idx = 0, end = m_TransparentObjects.size(); idx < end; ++idx) { + if (m_TransparentObjects[idx]->m_RenderableFlags.IsText()) { + STextRenderable &theRenderable = + static_cast(*m_TransparentObjects[idx]); + OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, + theVertexOffsets); + } else if (m_TransparentObjects[idx]->m_RenderableFlags.IsPath()) { + SPathRenderable &theRenderable = + static_cast(*m_TransparentObjects[idx]); + OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, + theVertexOffsets); + } + } + } + } + } + if (theLastLayerTexture.GetTexture() == NULL) { + isProgressiveAABlendPass = false; + isTemporalAABlendPass = false; + } + // Sometimes we will have stolen the render texture. + renderColorTexture->EnsureTexture(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), ColorTextureFormat, + sampleCount); + + if (!isTemporalAABlendPass) + m_TemporalAATexture.ReleaseTexture(); + + // Allocating a frame buffer can cause it to be bound, so we need to save state before this + // happens. + NVRenderContextScopedProperty __framebuf( + theRenderContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + // Match the bit depth of the current render target to avoid popping when we switch from aa + // to non aa layers + // We have to all this here in because once we change the FB by allocating an FB we are + // screwed. + NVRenderTextureFormats::Enum theDepthFormat(GetDepthBufferFormat()); + NVRenderFrameBufferAttachments::Enum theDepthAttachmentFormat( + GetFramebufferDepthAttachmentFormat(theDepthFormat)); + + // Definitely disable the scissor rect if it is running right now. + NVRenderContextScopedProperty __scissorEnabled( + theRenderContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled, false); + CResourceFrameBuffer theFB(theResourceManager); + // Allocates the frame buffer which has the side effect of setting the current render target + // to that frame buffer. + theFB.EnsureFrameBuffer(); + + bool hasDepthObjects = m_OpaqueObjects.size() > 0; + bool requiresDepthStencilBuffer = + hasDepthObjects || thePrepResult.m_Flags.RequiresStencilBuffer(); + NVRenderRect theNewViewport(0, 0, theLayerTextureDimensions.width(), + theLayerTextureDimensions.height()); + { + theRenderContext.SetRenderTarget(theFB); + NVRenderContextScopedProperty __viewport( + theRenderContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, + theNewViewport); + QT3DSVec4 clearColor(0.0); + if (m_Layer.m_Background == LayerBackground::Color) + clearColor = QT3DSVec4(m_Layer.m_ClearColor, 1.0); + + NVRenderContextScopedProperty __clearColor( + theRenderContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, + clearColor); + if (requiresDepthStencilBuffer) { + if (renderPrepassDepthTexture->EnsureTexture(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), + theDepthFormat, sampleCount)) { + (*renderPrepassDepthTexture)->SetMinFilter(NVRenderTextureMinifyingOp::Nearest); + (*renderPrepassDepthTexture) + ->SetMagFilter(NVRenderTextureMagnifyingOp::Nearest); + } + } + + if (thePrepResult.m_Flags.RequiresDepthTexture() && m_ProgressiveAAPassIndex == 0) { + // Setup FBO with single depth buffer target. + // Note this does not use multisample. + NVRenderFrameBufferAttachments::Enum theAttachment = + GetFramebufferDepthAttachmentFormat(DepthTextureFormat); + theFB->Attach(theAttachment, *m_LayerDepthTexture); + + // In this case transparent objects also may write their depth. + RenderDepthPass(true); + theFB->Attach(theAttachment, NVRenderTextureOrRenderBuffer()); + } + + if (thePrepResult.m_Flags.RequiresSsaoPass() && m_ProgressiveAAPassIndex == 0 + && m_Camera != nullptr) { + StartProfiling("AO pass", false); + // Setup FBO with single color buffer target + theFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerSsaoTexture); + theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); + RenderAoPass(); + theFB->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer()); + EndProfiling("AO pass"); + } + + if (thePrepResult.m_Flags.RequiresShadowMapPass() && m_ProgressiveAAPassIndex == 0) { + // shadow map path + RenderShadowMapPass(&theFB); + } + + if (sampleCount > 1) { + theRenderContext.SetMultisampleEnabled(true); + } + + qt3ds::render::NVRenderClearFlags clearFlags = qt3ds::render::NVRenderClearValues::Color; + + // render depth prepass + if ((*renderPrepassDepthTexture)) { + theFB->Attach(theDepthAttachmentFormat, **renderPrepassDepthTexture, + thFboAttachTarget); + + if (m_Layer.m_Flags.IsLayerEnableDepthPrepass()) { + StartProfiling("Depth pass", false); + RenderDepthPass(false); + EndProfiling("Depth pass"); + } else { + clearFlags |= (qt3ds::render::NVRenderClearValues::Depth); + clearFlags |= (qt3ds::render::NVRenderClearValues::Stencil); + // enable depth write for the clear below + theRenderContext.SetDepthWriteEnabled(true); + } + } + + theFB->Attach(NVRenderFrameBufferAttachments::Color0, **renderColorTexture, + thFboAttachTarget); + if (m_Layer.m_Background != LayerBackground::Unspecified) + theRenderContext.Clear(clearFlags); + + // We don't clear the depth buffer because the layer render code we are about to call + // will do this. + StartProfiling("Render pass", false); + Render(&theFB); + // Debug measure to view the depth map to ensure we're rendering it correctly. + //if (m_Layer.m_TemporalAAEnabled) { + // RenderFakeDepthMapPass(m_ShadowMapManager->GetShadowMapEntry(0)->m_DepthMap, + // m_ShadowMapManager->GetShadowMapEntry(0)->m_DepthCube); + //} + EndProfiling("Render pass"); + + // Now before going further, we downsample and resolve the multisample information. + // This allows all algorithms running after + // this point to run unchanged. + if (isMultisamplePass) { + if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) { + // Resolve the FBO to the layer texture + CRendererUtil::ResolveMutisampleFBOColorOnly( + theResourceManager, m_LayerTexture, theRenderContext, + theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), + ColorTextureFormat, *theFB); + + theRenderContext.SetMultisampleEnabled(false); + } else { + // Resolve the FBO to the layer texture + CRendererUtil::ResolveSSAAFBOColorOnly( + theResourceManager, m_LayerTexture, + theLayerOriginalTextureDimensions.width(), + theLayerOriginalTextureDimensions.height(), theRenderContext, + theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), + ColorTextureFormat, *theFB); + } + } + + // CN - when I tried to get anti-aliased widgets I lost all transparency on the widget + // layer which made it overwrite the object you were + // manipulating. When I tried to use parallel nsight on it the entire studio + // application crashed on startup. + if (NeedsWidgetTexture()) { + m_LayerWidgetTexture.EnsureTexture(theLayerTextureDimensions.width(), + theLayerTextureDimensions.height(), + NVRenderTextureFormats::RGBA8); + theRenderContext.SetRenderTarget(theFB); + theFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerWidgetTexture); + theFB->Attach(GetFramebufferDepthAttachmentFormat(DepthTextureFormat), + *m_LayerDepthTexture); + theRenderContext.SetClearColor(QT3DSVec4(0.0f)); + theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); + // We should already have the viewport and everything setup for this. + RenderRenderWidgets(); + } + + if (theLastLayerTexture.GetTexture() != NULL + && (isProgressiveAABlendPass || isTemporalAABlendPass)) { + theRenderContext.SetViewport( + NVRenderRect(0, 0, theLayerOriginalTextureDimensions.width(), + theLayerOriginalTextureDimensions.height())); + CResourceTexture2D targetTexture( + theResourceManager, theLayerOriginalTextureDimensions.width(), + theLayerOriginalTextureDimensions.height(), ColorTextureFormat); + theFB->Attach(theDepthAttachmentFormat, + NVRenderTextureOrRenderBuffer()); + theFB->Attach(NVRenderFrameBufferAttachments::Color0, *targetTexture); + QT3DSVec2 theBlendFactors; + if (isProgressiveAABlendPass) + theBlendFactors = s_BlendFactors[aaFactorIndex]; + else + theBlendFactors = QT3DSVec2(.5f, .5f); + + theRenderContext.SetDepthTestEnabled(false); + theRenderContext.SetBlendingEnabled(false); + theRenderContext.SetCullingEnabled(false); + theRenderContext.SetActiveShader(theBlendShader->m_Shader); + theBlendShader->m_AccumSampler.Set(theLastLayerTexture); + theBlendShader->m_LastFrame.Set(m_LayerTexture); + theBlendShader->m_BlendFactors.Set(theBlendFactors); + m_Renderer.RenderQuad(); + theFB->Attach(NVRenderFrameBufferAttachments::Color0, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + if (isTemporalAABlendPass) + m_TemporalAATexture.StealTexture(m_LayerTexture); + m_LayerTexture.StealTexture(targetTexture); + } + + m_LayerTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + m_LayerTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + + // Don't remember why needs widget texture is false here. + // Should have commented why progAA plus widgets is a fail. + if (m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex + && NeedsWidgetTexture() == false) + ++m_ProgressiveAAPassIndex; + +// now we render all post effects +#ifdef QT3DS_CACHED_POST_EFFECT + ApplyLayerPostEffects(); +#endif + + if (m_LayerPrepassDepthTexture) { + // Detach any depth buffers. + theFB->Attach(theDepthAttachmentFormat, qt3ds::render::NVRenderTextureOrRenderBuffer(), + thFboAttachTarget); + } + + theFB->Attach(NVRenderFrameBufferAttachments::Color0, + qt3ds::render::NVRenderTextureOrRenderBuffer(), thFboAttachTarget); + // Let natural scoping rules destroy the other stuff. + } + } + + void SLayerRenderData::ApplyLayerPostEffects() + { + if (m_Layer.m_FirstEffect == NULL) { + if (m_LayerCachedTexture) { + IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); + theResourceManager.Release(*m_LayerCachedTexture); + m_LayerCachedTexture = NULL; + } + return; + } + + IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); + IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); + // we use the non MSAA buffer for the effect + NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; + NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; + + NVRenderTexture2D *theCurrentTexture = theLayerColorTexture; + for (SEffect *theEffect = m_Layer.m_FirstEffect; theEffect; + theEffect = theEffect->m_NextEffect) { + if (theEffect->m_Flags.IsActive() && m_Camera) { + StartProfiling(theEffect->m_ClassName, false); + + NVRenderTexture2D *theRenderedEffect = theEffectSystem.RenderEffect( + SEffectRenderArgument(*theEffect, *theCurrentTexture, + QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), + theLayerDepthTexture, m_LayerPrepassDepthTexture)); + + EndProfiling(theEffect->m_ClassName); + + // If the texture came from rendering a chain of effects, then we don't need it + // after this. + if (theCurrentTexture != theLayerColorTexture) + theResourceManager.Release(*theCurrentTexture); + + theCurrentTexture = theRenderedEffect; + + if (!theRenderedEffect) { + QString errorMsg = QObject::tr("Failed to compile \"%1\" effect.\nConsider" + " removing it from the presentation.") + .arg(theEffect->m_ClassName.c_str()); + QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); + break; + } + } + } + + if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { + theResourceManager.Release(*m_LayerCachedTexture); + m_LayerCachedTexture = NULL; + } + + if (theCurrentTexture != m_LayerTexture) + m_LayerCachedTexture = theCurrentTexture; + } + + inline bool AnyCompletelyNonTransparentObjects(TRenderableObjectList &inObjects) + { + for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { + if (inObjects[idx]->m_RenderableFlags.IsCompletelyTransparent() == false) + return true; + } + return false; + } + + void SLayerRenderData::RunnableRenderToViewport(qt3ds::render::NVRenderFrameBuffer *theFB) + { + // If we have an effect, an opaque object, or any transparent objects that aren't completely + // transparent + // or an offscreen renderer or a layer widget texture + // Then we can't possible affect the resulting render target. + bool needsToRender = m_Layer.m_FirstEffect != NULL || m_OpaqueObjects.empty() == false + || AnyCompletelyNonTransparentObjects(m_TransparentObjects) || GetOffscreenRenderer() + || m_LayerWidgetTexture || m_BoundingRectColor.hasValue() + || m_Layer.m_Background == LayerBackground::Color; + + if (needsToRender == false) + return; + + NVRenderContext &theContext(m_Renderer.GetContext()); + theContext.resetStates(); + + NVRenderContextScopedProperty __fbo( + theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); + qt3ds::render::NVRenderRect theCurrentViewport = theContext.GetViewport(); + NVRenderContextScopedProperty __viewport( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); + NVRenderContextScopedProperty theScissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled); + NVRenderContextScopedProperty theScissorRect( + theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); + SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); + NVRenderRectF theScreenRect(thePrepResult.GetLayerToPresentationViewport()); + + bool blendingEnabled = m_Layer.m_Background == LayerBackground::Transparent; + if (!thePrepResult.m_Flags.ShouldRenderToTexture()) { + theContext.SetViewport( + m_LayerPrepResult->GetLayerToPresentationViewport().ToIntegerRect()); + theContext.SetScissorTestEnabled(true); + theContext.SetScissorRect( + m_LayerPrepResult->GetLayerToPresentationScissorRect().ToIntegerRect()); + if (m_Layer.m_Background == LayerBackground::Color) { + NVRenderContextScopedProperty __clearColor( + theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, + QT3DSVec4(m_Layer.m_ClearColor, 0.0f)); + theContext.Clear(NVRenderClearValues::Color); + } + RenderToViewport(); + } else { +// First, render the layer along with whatever progressive AA is appropriate. +// The render graph should have taken care of the render to texture step. +#ifdef QT3DS_CACHED_POST_EFFECT + NVRenderTexture2D *theLayerColorTexture = + (m_LayerCachedTexture) ? m_LayerCachedTexture : m_LayerTexture; +#else + // Then render all but the last effect + IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); + IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); + // we use the non MSAA buffer for the effect + NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; + NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; + + NVRenderTexture2D *theCurrentTexture = theLayerColorTexture; + for (SEffect *theEffect = m_Layer.m_FirstEffect; + theEffect && theEffect != thePrepResult.m_LastEffect; + theEffect = theEffect->m_NextEffect) { + if (theEffect->m_Flags.IsActive() && m_Camera) { + StartProfiling(theEffect->m_ClassName, false); + + NVRenderTexture2D *theRenderedEffect = theEffectSystem.RenderEffect( + SEffectRenderArgument(*theEffect, *theCurrentTexture, + QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), + theLayerDepthTexture, m_LayerPrepassDepthTexture)); + + EndProfiling(theEffect->m_ClassName); + + // If the texture came from rendering a chain of effects, then we don't need it + // after this. + if (theCurrentTexture != theLayerColorTexture) + theResourceManager.Release(*theCurrentTexture); + + theCurrentTexture = theRenderedEffect; + } + } +#endif + // Now the last effect or straight to the scene if we have no last effect + // There are two cases we need to consider here. The first is when we shouldn't + // transform + // the result and thus we need to setup an MVP that just maps to the viewport width and + // height. + // The second is when we are expected to render to the scene using some global + // transform. + QT3DSMat44 theFinalMVP(QT3DSMat44::createIdentity()); + SCamera theTempCamera; + NVRenderRect theLayerViewport( + thePrepResult.GetLayerToPresentationViewport().ToIntegerRect()); + NVRenderRect theLayerClip( + thePrepResult.GetLayerToPresentationScissorRect().ToIntegerRect()); + + { + QT3DSMat33 ignored; + QT3DSMat44 theViewProjection; + // We could cache these variables + theTempCamera.m_Flags.SetOrthographic(true); + theTempCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); + // Move the camera back far enough that we can see everything + QT3DSF32 theCameraSetback(10); + // Attempt to ensure the layer can never be clipped. + theTempCamera.m_Position.z = -theCameraSetback; + theTempCamera.m_ClipFar = 2.0f * theCameraSetback; + // Render the layer texture to the entire viewport. + SCameraGlobalCalculationResult theResult = theTempCamera.CalculateGlobalVariables( + theLayerViewport, + QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, (QT3DSF32)theLayerViewport.m_Height)); + theTempCamera.CalculateViewProjectionMatrix(theViewProjection); + SNode theTempNode; + theFinalMVP = theViewProjection; + qt3ds::render::NVRenderBlendFunctionArgument blendFunc; + qt3ds::render::NVRenderBlendEquationArgument blendEqu; + + switch (m_Layer.m_BlendType) { + case LayerBlendTypes::Screen: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::One, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); + break; + case LayerBlendTypes::Multiply: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::DstColor, NVRenderDstBlendFunc::Zero, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); + break; + case LayerBlendTypes::Add: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); + break; + case LayerBlendTypes::Subtract: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::ReverseSubtract, + NVRenderBlendEquation::ReverseSubtract); + break; + case LayerBlendTypes::Overlay: + // SW fallback doesn't use blend equation + // note blend func is not used here anymore + if (theContext.IsAdvancedBlendHwSupported() || + theContext.IsAdvancedBlendHwSupportedKHR()) + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Overlay, NVRenderBlendEquation::Overlay); + break; + case LayerBlendTypes::ColorBurn: + // SW fallback doesn't use blend equation + // note blend func is not used here anymore + if (theContext.IsAdvancedBlendHwSupported() || + theContext.IsAdvancedBlendHwSupportedKHR()) + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::ColorBurn, NVRenderBlendEquation::ColorBurn); + break; + case LayerBlendTypes::ColorDodge: + // SW fallback doesn't use blend equation + // note blend func is not used here anymore + if (theContext.IsAdvancedBlendHwSupported() || + theContext.IsAdvancedBlendHwSupportedKHR()) + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::ColorDodge, NVRenderBlendEquation::ColorDodge); + break; + default: + blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); + blendEqu = qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); + break; + } + theContext.SetBlendFunction(blendFunc); + theContext.SetBlendEquation(blendEqu); + theContext.SetBlendingEnabled(blendingEnabled); + theContext.SetDepthTestEnabled(false); + } + + { + theContext.SetScissorTestEnabled(true); + theContext.SetViewport(theLayerViewport); + theContext.SetScissorRect(theLayerClip); + + // Remember the camera we used so we can get a valid pick ray + m_SceneCamera = theTempCamera; + theContext.SetDepthTestEnabled(false); +#ifndef QT3DS_CACHED_POST_EFFECT + if (thePrepResult.m_LastEffect && m_Camera) { + StartProfiling(thePrepResult.m_LastEffect->m_ClassName, false); + // inUseLayerMPV is true then we are rendering directly to the scene and thus we + // should enable blending + // for the final render pass. Else we should leave it. + theEffectSystem.RenderEffect( + SEffectRenderArgument(*thePrepResult.m_LastEffect, *theCurrentTexture, + QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), + theLayerDepthTexture, m_LayerPrepassDepthTexture), + theFinalMVP, blendingEnabled); + EndProfiling(thePrepResult.m_LastEffect->m_ClassName); + // If the texture came from rendering a chain of effects, then we don't need it + // after this. + if (theCurrentTexture != theLayerColorTexture) + theResourceManager.Release(*theCurrentTexture); + } else +#endif + { + theContext.SetCullingEnabled(false); + theContext.SetBlendingEnabled(blendingEnabled); + theContext.SetDepthTestEnabled(false); +#ifdef ADVANCED_BLEND_SW_FALLBACK + NVScopedRefCounted screenTexture = + m_Renderer.GetLayerBlendTexture(); + NVScopedRefCounted blendFB = m_Renderer.GetBlendFB(); + + // Layer blending for advanced blending modes if SW fallback is needed + // rendering to FBO and blending with separate shader + if (screenTexture) { + // Blending is enabled only if layer background has been chosen transparent + // Layers with advanced blending modes + if (blendingEnabled && (m_Layer.m_BlendType == LayerBlendTypes::Overlay || + m_Layer.m_BlendType == LayerBlendTypes::ColorBurn || + m_Layer.m_BlendType == LayerBlendTypes::ColorDodge)) { + theContext.SetScissorTestEnabled(false); + theContext.SetBlendingEnabled(false); + + // Get part matching to layer from screen texture and + // use that for blending + qt3ds::render::NVRenderTexture2D *blendBlitTexture; + blendBlitTexture = theContext.CreateTexture2D(); + blendBlitTexture->SetTextureData(NVDataRef(), 0, + theLayerViewport.m_Width, + theLayerViewport.m_Height, + NVRenderTextureFormats::RGBA8); + qt3ds::render::NVRenderFrameBuffer *blitFB; + blitFB = theContext.CreateFrameBuffer(); + blitFB->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer(*blendBlitTexture)); + blendFB->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer(*screenTexture)); + theContext.SetRenderTarget(blitFB); + theContext.SetReadTarget(blendFB); + theContext.SetReadBuffer(NVReadFaces::Color0); + theContext.BlitFramebuffer(theLayerViewport.m_X, theLayerViewport.m_Y, + theLayerViewport.m_Width + + theLayerViewport.m_X, + theLayerViewport.m_Height + + theLayerViewport.m_Y, + 0, 0, + theLayerViewport.m_Width, + theLayerViewport.m_Height, + NVRenderClearValues::Color, + NVRenderTextureMagnifyingOp::Nearest); + + qt3ds::render::NVRenderTexture2D *blendResultTexture; + blendResultTexture = theContext.CreateTexture2D(); + blendResultTexture->SetTextureData(NVDataRef(), 0, + theLayerViewport.m_Width, + theLayerViewport.m_Height, + NVRenderTextureFormats::RGBA8); + qt3ds::render::NVRenderFrameBuffer *resultFB; + resultFB = theContext.CreateFrameBuffer(); + resultFB->Attach(NVRenderFrameBufferAttachments::Color0, + NVRenderTextureOrRenderBuffer(*blendResultTexture)); + theContext.SetRenderTarget(resultFB); + + AdvancedBlendModes::Enum advancedMode; + switch (m_Layer.m_BlendType) { + case LayerBlendTypes::Overlay: + advancedMode = AdvancedBlendModes::Overlay; + break; + case LayerBlendTypes::ColorBurn: + advancedMode = AdvancedBlendModes::ColorBurn; + break; + case LayerBlendTypes::ColorDodge: + advancedMode = AdvancedBlendModes::ColorDodge; + break; + default: + advancedMode = AdvancedBlendModes::None; + break; + } + + theContext.SetViewport(NVRenderRect(0, 0, theLayerViewport.m_Width, + theLayerViewport.m_Height)); + BlendAdvancedEquationSwFallback(theLayerColorTexture, blendBlitTexture, + advancedMode); + blitFB->release(); + // save blending result to screen texture for use with other layers + theContext.SetViewport(theLayerViewport); + theContext.SetRenderTarget(blendFB); + m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, + (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *blendResultTexture); + // render the blended result + theContext.SetRenderTarget(theFB); + theContext.SetScissorTestEnabled(true); + m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, + (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *blendResultTexture); + resultFB->release(); + } else { + // Layers with normal blending modes + // save result for future use + theContext.SetViewport(theLayerViewport); + theContext.SetScissorTestEnabled(false); + theContext.SetBlendingEnabled(true); + theContext.SetRenderTarget(blendFB); + m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, + (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *theLayerColorTexture); + theContext.SetRenderTarget(theFB); + theContext.SetScissorTestEnabled(true); + theContext.SetViewport(theCurrentViewport); + m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, + (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *theLayerColorTexture); + } + } else { + // No advanced blending SW fallback needed + m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, + (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *theLayerColorTexture); + } +#else + m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, + (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *theLayerColorTexture); +#endif + } + if (m_LayerWidgetTexture) { + theContext.SetBlendingEnabled(false); + m_Renderer.SetupWidgetLayer(); + SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); + NVRenderRectF thePresRect(thePrepResult.GetPresentationViewport()); + NVRenderRectF theLayerRect(thePrepResult.GetLayerToPresentationViewport()); + + // Ensure we remove any offsetting in the layer rect that was caused simply by + // the + // presentation rect offsetting but then use a new rect. + NVRenderRectF theWidgetLayerRect(theLayerRect.m_X - thePresRect.m_X, + theLayerRect.m_Y - thePresRect.m_Y, + theLayerRect.m_Width, theLayerRect.m_Height); + theContext.SetScissorTestEnabled(false); + theContext.SetViewport(theWidgetLayerRect.ToIntegerRect()); + m_Renderer.RenderQuad( + QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, (QT3DSF32)theLayerViewport.m_Height), + theFinalMVP, *m_LayerWidgetTexture); + } + } + } // End offscreen render code. + + if (m_BoundingRectColor.hasValue()) { + NVRenderContextScopedProperty __viewport( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); + NVRenderContextScopedProperty theScissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled); + NVRenderContextScopedProperty theScissorRect( + theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); + m_Renderer.SetupWidgetLayer(); + // Setup a simple viewport to render to the entire presentation viewport. + theContext.SetViewport( + NVRenderRect(0, 0, (QT3DSU32)thePrepResult.GetPresentationViewport().m_Width, + (QT3DSU32)thePrepResult.GetPresentationViewport().m_Height)); + + NVRenderRectF thePresRect(thePrepResult.GetPresentationViewport()); + + // Remove any offsetting from the presentation rect since the widget layer is a + // stand-alone fbo. + NVRenderRectF theWidgetScreenRect(theScreenRect.m_X - thePresRect.m_X, + theScreenRect.m_Y - thePresRect.m_Y, + theScreenRect.m_Width, theScreenRect.m_Height); + theContext.SetScissorTestEnabled(false); + m_Renderer.DrawScreenRect(theWidgetScreenRect, *m_BoundingRectColor); + } + theContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); + theContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); + } + +#define RENDER_FRAME_NEW(type) QT3DS_NEW(m_Renderer.GetPerFrameAllocator(), type) + + void SLayerRenderData::AddLayerRenderStep() + { + SStackPerfTimer __perfTimer(m_Renderer.GetQt3DSContext().GetPerfTimer(), + "SLayerRenderData::AddLayerRenderStep"); + QT3DS_ASSERT(m_Camera); + if (!m_Camera) + return; + + IRenderList &theGraph(m_Renderer.GetQt3DSContext().GetRenderList()); + + qt3ds::render::NVRenderRect theCurrentViewport = theGraph.GetViewport(); + if (!m_LayerPrepResult.hasValue()) + PrepareForRender( + QSize(theCurrentViewport.m_Width, theCurrentViewport.m_Height)); + } + + void SLayerRenderData::PrepareForRender() + { + // When we render to the scene itself (as opposed to an offscreen buffer somewhere) + // then we use the MVP of the layer somewhat. + NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); + PrepareForRender( + QSize((QT3DSU32)theViewport.m_Width, (QT3DSU32)theViewport.m_Height)); + } + + void SLayerRenderData::ResetForFrame() + { + SLayerRenderPreparationData::ResetForFrame(); + m_BoundingRectColor.setEmpty(); + } + + void SLayerRenderData::PrepareAndRender(const QT3DSMat44 &inViewProjection) + { + TRenderableObjectList theTransparentObjects(m_TransparentObjects); + TRenderableObjectList theOpaqueObjects(m_OpaqueObjects); + theTransparentObjects.clear(); + theOpaqueObjects.clear(); + m_ModelContexts.clear(); + SLayerRenderPreparationResultFlags theFlags; + PrepareRenderablesForRender(inViewProjection, Empty(), 1.0, theFlags); + RenderDepthPass(false); + Render(); + } + + struct SLayerRenderToTextureRunnable : public IRenderTask + { + SLayerRenderData &m_Data; + SLayerRenderToTextureRunnable(SLayerRenderData &d) + : m_Data(d) + { + } + + void Run() override { m_Data.RenderToTexture(); } + }; + + static inline OffscreenRendererDepthValues::Enum + GetOffscreenRendererDepthValue(NVRenderTextureFormats::Enum inBufferFormat) + { + switch (inBufferFormat) { + case NVRenderTextureFormats::Depth32: + return OffscreenRendererDepthValues::Depth32; + case NVRenderTextureFormats::Depth24: + return OffscreenRendererDepthValues::Depth24; + case NVRenderTextureFormats::Depth24Stencil8: + return OffscreenRendererDepthValues::Depth24; + default: + QT3DS_ASSERT(false); // fallthrough intentional + case NVRenderTextureFormats::Depth16: + return OffscreenRendererDepthValues::Depth16; + } + } + + SOffscreenRendererEnvironment SLayerRenderData::CreateOffscreenRenderEnvironment() + { + OffscreenRendererDepthValues::Enum theOffscreenDepth( + GetOffscreenRendererDepthValue(GetDepthBufferFormat())); + NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); + return SOffscreenRendererEnvironment(theViewport.m_Width, theViewport.m_Height, + NVRenderTextureFormats::RGBA8, theOffscreenDepth, + false, AAModeValues::NoAA); + } + + IRenderTask &SLayerRenderData::CreateRenderToTextureRunnable() + { + return *RENDER_FRAME_NEW(SLayerRenderToTextureRunnable)(*this); + } + + void SLayerRenderData::addRef() { atomicIncrement(&mRefCount); } + + void SLayerRenderData::release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Allocator); } +} +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h new file mode 100644 index 00000000..4e237b0b --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDERER_IMPL_LAYER_RENDER_DATA_H +#define QT3DS_RENDERER_IMPL_LAYER_RENDER_DATA_H +#include "Qt3DSRender.h" +#include "Qt3DSRendererImplLayerRenderPreparationData.h" +#include "Qt3DSRenderResourceBufferObjects.h" + +namespace qt3ds { +namespace render { + +struct AdvancedBlendModes +{ + enum Enum { + None = 0, + Overlay, + ColorBurn, + ColorDodge + }; +}; + struct QT3DS_AUTOTEST_EXPORT SLayerRenderData : public SLayerRenderPreparationData + { + + // Layers can be rendered offscreen for many reasons; effects, progressive aa, + // or just because a flag forces it. If they are rendered offscreen we can then + // cache the result so we don't render the layer again if it isn't dirty. + CResourceTexture2D m_LayerTexture; + CResourceTexture2D m_TemporalAATexture; + // Sometimes we need to render our depth buffer to a depth texture. + CResourceTexture2D m_LayerDepthTexture; + CResourceTexture2D m_LayerPrepassDepthTexture; + CResourceTexture2D m_LayerWidgetTexture; + CResourceTexture2D m_LayerSsaoTexture; + // if we render multisampled we need resolve buffers + CResourceTexture2D m_LayerMultisampleTexture; + CResourceTexture2D m_LayerMultisamplePrepassDepthTexture; + CResourceTexture2D m_LayerMultisampleWidgetTexture; + // the texture contains the render result inclusive post effects + NVRenderTexture2D *m_LayerCachedTexture; + + NVRenderTexture2D *m_AdvancedBlendDrawTexture; + NVRenderTexture2D *m_AdvancedBlendBlendTexture; + qt3ds::render::NVRenderFrameBuffer *m_AdvancedModeDrawFB; + qt3ds::render::NVRenderFrameBuffer *m_AdvancedModeBlendFB; + + // True if this layer was rendered offscreen. + // If this object has no value then this layer wasn't rendered at all. + SOffscreenRendererEnvironment m_LastOffscreenRenderEnvironment; + + // GPU profiler per layer + NVScopedRefCounted m_LayerProfilerGpu; + + SCamera m_SceneCamera; + QT3DSVec2 m_SceneDimensions; + + // ProgressiveAA algorithm details. + QT3DSU32 m_ProgressiveAAPassIndex; + // Increments every frame regardless to provide appropriate jittering + QT3DSU32 m_TemporalAAPassIndex; + // Ensures we don't stop on an in-between frame; we will run two frames after the dirty flag + // is clear. + QT3DSU32 m_NonDirtyTemporalAAPassIndex; + QT3DSF32 m_TextScale; + + volatile QT3DSI32 mRefCount; + Option m_BoundingRectColor; + NVRenderTextureFormats::Enum m_DepthBufferFormat; + + QSize m_previousDimensions; + + SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer); + + virtual ~SLayerRenderData(); + + void PrepareForRender(); + + // Internal Call + void PrepareForRender(const QSize &inViewportDimensions) override; + + NVRenderTextureFormats::Enum GetDepthBufferFormat(); + NVRenderFrameBufferAttachments::Enum + GetFramebufferDepthAttachmentFormat(NVRenderTextureFormats::Enum depthFormat); + + // Render this layer assuming viewport and RT are setup. Just renders exactly this item + // no effects. + void RenderDepthPass(bool inEnableTransparentDepthWrite = false); + void RenderAoPass(); + void RenderFakeDepthMapPass(NVRenderTexture2D *theDepthTex, + NVRenderTextureCube *theDepthCube); + void RenderShadowMapPass(CResourceFrameBuffer *theFB); + void RenderShadowCubeBlurPass(CResourceFrameBuffer *theFB, NVRenderTextureCube *target0, + NVRenderTextureCube *target1, QT3DSF32 filterSz, QT3DSF32 clipFar); + void RenderShadowMapBlurPass(CResourceFrameBuffer *theFB, NVRenderTexture2D *target0, + NVRenderTexture2D *target1, QT3DSF32 filterSz, QT3DSF32 clipFar); + + void Render(CResourceFrameBuffer *theFB = NULL); + void ResetForFrame() override; + + void CreateGpuProfiler(); + void StartProfiling(CRegisteredString &nameID, bool sync); + void EndProfiling(CRegisteredString &nameID); + void StartProfiling(const char *nameID, bool sync); + void EndProfiling(const char *nameID); + void AddVertexCount(QT3DSU32 count); + + void RenderToViewport(); + // Render this layer's data to a texture. Required if we have any effects, + // prog AA, or if forced. + void RenderToTexture(); + + void ApplyLayerPostEffects(); + + void RunnableRenderToViewport(qt3ds::render::NVRenderFrameBuffer *theFB); + + void AddLayerRenderStep(); + + void RenderRenderWidgets(); + +#ifdef ADVANCED_BLEND_SW_FALLBACK + void BlendAdvancedEquationSwFallback(NVRenderTexture2D *drawTexture, + NVRenderTexture2D *m_LayerTexture, + AdvancedBlendModes::Enum blendMode); +#endif + // test method to render this layer to a given view projection without running the entire + // layer setup system. This assumes the client has setup the viewport, scissor, and render + // target + // the way they want them. + void PrepareAndRender(const QT3DSMat44 &inViewProjection); + + SOffscreenRendererEnvironment CreateOffscreenRenderEnvironment() override; + IRenderTask &CreateRenderToTextureRunnable() override; + + void addRef(); + void release(); + + protected: + // Used for both the normal passes and the depth pass. + // When doing the depth pass, we disable blending completely because it does not really make + // sense + // to write blend equations into + void RunRenderPass(TRenderRenderableFunction renderFn, bool inEnableBlending, + bool inEnableDepthWrite, bool inEnableTransparentDepthWrite, + QT3DSU32 indexLight, const SCamera &inCamera, + CResourceFrameBuffer *theFB = NULL); +#ifdef ADVANCED_BLEND_SW_FALLBACK + //Functions for advanced blending mode fallback + void SetupDrawFB(bool depthEnabled); + void BlendAdvancedToFB(DefaultMaterialBlendMode::Enum blendMode, bool depthEnabled, + CResourceFrameBuffer *theFB); +#endif + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp new file mode 100644 index 00000000..8a050db0 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRendererImplLayerRenderHelper.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSTextRenderer.h" + +using namespace qt3ds::render; + +namespace { +// left/top +QT3DSF32 GetMinValue(QT3DSF32 start, QT3DSF32 width, QT3DSF32 value, LayerUnitTypes::Enum units) +{ + if (units == LayerUnitTypes::Pixels) + return start + value; + + return start + (value * width / 100.0f); +} + +// width/height +QT3DSF32 GetValueLen(QT3DSF32 width, QT3DSF32 value, LayerUnitTypes::Enum units) +{ + if (units == LayerUnitTypes::Pixels) + return value; + + return width * value / 100.0f; +} + +// right/bottom +QT3DSF32 GetMaxValue(QT3DSF32 start, QT3DSF32 width, QT3DSF32 value, LayerUnitTypes::Enum units) +{ + if (units == LayerUnitTypes::Pixels) + return start + width - value; + + return start + width - (value * width / 100.0f); +} + +QT3DSVec2 ToRectRelativeCoords(const QT3DSVec2 &inCoords, const NVRenderRectF &inRect) +{ + return QT3DSVec2(inCoords.x - inRect.m_X, inCoords.y - inRect.m_Y); +} +} + +SLayerRenderHelper::SLayerRenderHelper() + : m_Layer(NULL) + , m_Camera(NULL) + , m_Offscreen(false) +{ +} + +SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewport, + const NVRenderRectF &inPresentationScissor, + const QT3DSVec2 &inPresentationDesignDimensions, + SLayer &inLayer, bool inOffscreen, + qt3ds::render::ScaleModes::Enum inScaleMode, + qt3ds::QT3DSVec2 inScaleFactor) + : m_PresentationViewport(inPresentationViewport) + , m_PresentationScissor(inPresentationScissor) + , m_PresentationDesignDimensions(inPresentationDesignDimensions) + , m_Layer(&inLayer) + , m_Offscreen(inOffscreen) + , m_ScaleMode(inScaleMode) + , m_ScaleFactor(inScaleFactor) +{ + { + QT3DSF32 left = m_Layer->m_Left; + QT3DSF32 right = m_Layer->m_Right; + QT3DSF32 width = m_Layer->m_Width; + + if (m_ScaleMode == qt3ds::render::ScaleModes::FitSelected) { + if (m_Layer->m_LeftUnits == LayerUnitTypes::Pixels) + left *= m_ScaleFactor.x; + + if (m_Layer->m_RightUnits == LayerUnitTypes::Pixels) + right *= m_ScaleFactor.x; + + if (m_Layer->m_WidthUnits == LayerUnitTypes::Pixels) + width *= m_ScaleFactor.x; + } + + QT3DSF32 horzMin = GetMinValue(inPresentationViewport.m_X, inPresentationViewport.m_Width, + left, m_Layer->m_LeftUnits); + QT3DSF32 horzWidth = GetValueLen(inPresentationViewport.m_Width, width, m_Layer->m_WidthUnits); + QT3DSF32 horzMax = GetMaxValue(inPresentationViewport.m_X, inPresentationViewport.m_Width, + right, m_Layer->m_RightUnits); + + switch (inLayer.m_HorizontalFieldValues) { + case HorizontalFieldValues::LeftWidth: + m_Viewport.m_X = horzMin; + m_Viewport.m_Width = horzWidth; + break; + case HorizontalFieldValues::LeftRight: + m_Viewport.m_X = horzMin; + m_Viewport.m_Width = horzMax - horzMin; + break; + case HorizontalFieldValues::WidthRight: + m_Viewport.m_Width = horzWidth; + m_Viewport.m_X = horzMax - horzWidth; + break; + } + } + { + QT3DSF32 top = m_Layer->m_Top; + QT3DSF32 bottom = m_Layer->m_Bottom; + QT3DSF32 height = m_Layer->m_Height; + + if (m_ScaleMode == qt3ds::render::ScaleModes::FitSelected) { + + if (m_Layer->m_TopUnits == LayerUnitTypes::Pixels) + top *= m_ScaleFactor.y; + + if (m_Layer->m_BottomUnits == LayerUnitTypes::Pixels) + bottom *= m_ScaleFactor.y; + + if (m_Layer->m_HeightUnits == LayerUnitTypes::Pixels) + height *= m_ScaleFactor.y; + } + + QT3DSF32 vertMin = GetMinValue(inPresentationViewport.m_Y, inPresentationViewport.m_Height, + bottom, m_Layer->m_BottomUnits); + QT3DSF32 vertWidth = + GetValueLen(inPresentationViewport.m_Height, height, m_Layer->m_HeightUnits); + QT3DSF32 vertMax = GetMaxValue(inPresentationViewport.m_Y, inPresentationViewport.m_Height, + top, m_Layer->m_TopUnits); + + switch (inLayer.m_VerticalFieldValues) { + case VerticalFieldValues::HeightBottom: + m_Viewport.m_Y = vertMin; + m_Viewport.m_Height = vertWidth; + break; + case VerticalFieldValues::TopBottom: + m_Viewport.m_Y = vertMin; + m_Viewport.m_Height = vertMax - vertMin; + break; + case VerticalFieldValues::TopHeight: + m_Viewport.m_Height = vertWidth; + m_Viewport.m_Y = vertMax - vertWidth; + break; + } + } + + m_Viewport.m_Width = NVMax(1.0f, m_Viewport.m_Width); + m_Viewport.m_Height = NVMax(1.0f, m_Viewport.m_Height); + // Now force the viewport to be a multiple of four in width and height. This is because + // when rendering to a texture we have to respect this and not forcing it causes scaling issues + // that are noticeable especially in situations where customers are using text and such. + QT3DSF32 originalWidth = m_Viewport.m_Width; + QT3DSF32 originalHeight = m_Viewport.m_Height; + + m_Viewport.m_Width = (QT3DSF32)ITextRenderer::NextMultipleOf4((QT3DSU32)m_Viewport.m_Width); + m_Viewport.m_Height = (QT3DSF32)ITextRenderer::NextMultipleOf4((QT3DSU32)m_Viewport.m_Height); + + // Now fudge the offsets to account for this slight difference + m_Viewport.m_X += (originalWidth - m_Viewport.m_Width) / 2.0f; + m_Viewport.m_Y += (originalHeight - m_Viewport.m_Height) / 2.0f; + + m_Scissor = m_Viewport; + m_Scissor.EnsureInBounds(inPresentationScissor); + QT3DS_ASSERT(m_Scissor.m_Width >= 0.0f); + QT3DS_ASSERT(m_Scissor.m_Height >= 0.0f); +} + +// This is the viewport the camera will use to setup the projection. +NVRenderRectF SLayerRenderHelper::GetLayerRenderViewport() const +{ + if (m_Offscreen) + return NVRenderRectF(0, 0, m_Viewport.m_Width, (QT3DSF32)m_Viewport.m_Height); + else + return m_Viewport; +} + +QSize SLayerRenderHelper::GetTextureDimensions() const +{ + QT3DSU32 width = (QT3DSU32)m_Viewport.m_Width; + QT3DSU32 height = (QT3DSU32)m_Viewport.m_Height; + return QSize(ITextRenderer::NextMultipleOf4(width), + ITextRenderer::NextMultipleOf4(height)); +} + +SCameraGlobalCalculationResult SLayerRenderHelper::SetupCameraForRender(SCamera &inCamera) +{ + m_Camera = &inCamera; + NVRenderRectF rect = GetLayerRenderViewport(); + if (m_ScaleMode == ScaleModes::FitSelected) { + rect.m_Width = + (QT3DSF32)(ITextRenderer::NextMultipleOf4((QT3DSU32)(rect.m_Width / m_ScaleFactor.x))); + rect.m_Height = + (QT3DSF32)(ITextRenderer::NextMultipleOf4((QT3DSU32)(rect.m_Height / m_ScaleFactor.y))); + } + return m_Camera->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); +} + +Option SLayerRenderHelper::GetLayerMouseCoords(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inWindowDimensions, + bool inForceIntersect) const +{ + // First invert the y so we are dealing with numbers in a normal coordinate space. + // Second, move into our layer's coordinate space + QT3DSVec2 correctCoords(inMouseCoords.x, inWindowDimensions.y - inMouseCoords.y); + QT3DSVec2 theLocalMouse = m_Viewport.ToRectRelative(correctCoords); + + QT3DSF32 theRenderRectWidth = m_Viewport.m_Width; + QT3DSF32 theRenderRectHeight = m_Viewport.m_Height; + // Crop the mouse to the rect. Apply no further translations. + if (inForceIntersect == false + && (theLocalMouse.x < 0.0f || theLocalMouse.x >= theRenderRectWidth + || theLocalMouse.y < 0.0f || theLocalMouse.y >= theRenderRectHeight)) { + return Empty(); + } + return theLocalMouse; +} + +Option SLayerRenderHelper::GetPickRay(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inWindowDimensions, + bool inForceIntersect) const +{ + if (m_Camera == NULL) + return Empty(); + Option theCoords( + GetLayerMouseCoords(inMouseCoords, inWindowDimensions, inForceIntersect)); + if (theCoords.hasValue()) { + // The cameras projection is different if we are onscreen vs. offscreen. + // When offscreen, we need to move the mouse coordinates into a local space + // to the layer. + return m_Camera->Unproject(*theCoords, m_Viewport, m_PresentationDesignDimensions); + } + return Empty(); +} + +bool SLayerRenderHelper::IsLayerVisible() const +{ + return m_Scissor.m_Height >= 2.0f && m_Scissor.m_Width >= 2.0f; +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h new file mode 100644 index 00000000..8ee4ff73 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#include "Qt3DSRender.h" +#include "foundation/Qt3DSVec2.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderContextCore.h" + +namespace qt3ds { +namespace render { + + /** An independent, testable entity to encapsulate taking at least: + * layer, current viewport rect, current scissor rect, presentation design dimensions + * and producing a set of rectangles: + * layer viewport rect (inside viewport rect and calculated using outer viewport rect info) + * layer scissor rect (inside current scissor rect) + * layer camera rect (may be the viewport rect) + * + * In the case where we have to render offscreen for this layer then we need to handle produce + * a set of texture dimensions and the layer camera rect ends up being same size but with no + *offsets. + * + * This object should handle part of any translation from screenspace to global space. + * I am using language level access control on this object because it needs specific + * interface design that will enable future modifications. + */ + struct SLayerRenderHelper + { + private: + NVRenderRectF m_PresentationViewport; + NVRenderRectF m_PresentationScissor; + QT3DSVec2 m_PresentationDesignDimensions; + SLayer *m_Layer; + SCamera *m_Camera; + bool m_Offscreen; + + NVRenderRectF m_Viewport; + NVRenderRectF m_Scissor; + + ScaleModes::Enum m_ScaleMode; + QT3DSVec2 m_ScaleFactor; + + public: + SLayerRenderHelper(); + + SLayerRenderHelper(const NVRenderRectF &inPresentationViewport, + const NVRenderRectF &inPresentationScissor, + const QT3DSVec2 &inPresentationDesignDimensions, SLayer &inLayer, + bool inOffscreen, qt3ds::render::ScaleModes::Enum inScaleMode, + qt3ds::QT3DSVec2 inScaleFactor); + + NVRenderRectF GetPresentationViewport() const { return m_PresentationViewport; } + NVRenderRectF GetPresentationScissor() const { return m_PresentationScissor; } + QT3DSVec2 GetPresentationDesignDimensions() const { return m_PresentationDesignDimensions; } + SLayer *GetLayer() const { return m_Layer; } + SCamera *GetCamera() const { return m_Camera; } + bool IsOffscreen() const { return m_Offscreen; } + + // Does not differ whether offscreen or not, simply states how this layer maps to the + // presentation + NVRenderRectF GetLayerToPresentationViewport() const { return m_Viewport; } + // Does not differ whether offscreen or not, scissor rect of how this layer maps to + // presentation. + NVRenderRectF GetLayerToPresentationScissorRect() const { return m_Scissor; } + + QSize GetTextureDimensions() const; + + SCameraGlobalCalculationResult SetupCameraForRender(SCamera &inCamera); + + Option GetLayerMouseCoords(const QT3DSVec2 &inMouseCoords, + const QT3DSVec2 &inWindowDimensions, + bool inForceIntersect) const; + + Option GetPickRay(const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inWindowDimensions, + bool inForceIntersect) const; + + // Checks the various viewports and determines if the layer is visible or not. + bool IsLayerVisible() const; + + private: + // Viewport used when actually rendering. In the case where this is an offscreen item then + // it may be + // different than the layer to presentation viewport. + NVRenderRectF GetLayerRenderViewport() const; + }; +} +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp new file mode 100644 index 00000000..68ed9907 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp @@ -0,0 +1,1446 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRender.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRendererImpl.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderEffect.h" +#include "EASTL/sort.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderCamera.h" +#include "Qt3DSRenderScene.h" +#include "Qt3DSRenderPresentation.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderResourceManager.h" +#include "Qt3DSTextRenderer.h" +#include "Qt3DSRenderEffectSystem.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "Qt3DSOffscreenRenderKey.h" +#include "Qt3DSRenderPlugin.h" +#include "Qt3DSRenderPluginGraphObject.h" +#include "Qt3DSRenderResourceBufferObjects.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "Qt3DSRenderMaterialHelpers.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderCustomMaterialSystem.h" +#include "Qt3DSRenderTextTextureCache.h" +#include "Qt3DSRenderTextTextureAtlas.h" +#include "Qt3DSRenderRenderList.h" +#include "Qt3DSRenderPath.h" +#include "Qt3DSRenderPathManager.h" + +#ifdef _WIN32 +#pragma warning(disable : 4355) +#endif +namespace qt3ds { +namespace render { + using eastl::reverse; + using eastl::stable_sort; + using qt3ds::render::NVRenderContextScopedProperty; + using qt3ds::QT3DSVec2; + + namespace { + void MaybeQueueNodeForRender(SNode &inNode, nvvector &outRenderables, + nvvector &outCamerasAndLights, QT3DSU32 &ioDFSIndex) + { + ++ioDFSIndex; + inNode.m_DFSIndex = ioDFSIndex; + if (GraphObjectTypes::IsRenderableType(inNode.m_Type)) + outRenderables.push_back(inNode); + else if (GraphObjectTypes::IsLightCameraType(inNode.m_Type)) + outCamerasAndLights.push_back(&inNode); + + for (SNode *theChild = inNode.m_FirstChild; theChild != NULL; + theChild = theChild->m_NextSibling) + MaybeQueueNodeForRender(*theChild, outRenderables, outCamerasAndLights, ioDFSIndex); + } + + bool HasValidLightProbe(SImage *inLightProbeImage) + { + return inLightProbeImage && inLightProbeImage->m_TextureData.m_Texture; + } + } + + SDefaultMaterialPreparationResult::SDefaultMaterialPreparationResult( + SShaderDefaultMaterialKey inKey) + : m_FirstImage(NULL) + , m_Opacity(1.0f) + , m_MaterialKey(inKey) + , m_Dirty(false) + { + } + +#define MAX_AA_LEVELS 8 + + SLayerRenderPreparationData::SLayerRenderPreparationData(SLayer &inLayer, + Qt3DSRendererImpl &inRenderer) + : m_Layer(inLayer) + , m_Renderer(inRenderer) + , m_Allocator(inRenderer.GetContext().GetAllocator()) + , m_RenderableNodeLightEntryPool( + ForwardingAllocator(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_RenderableNodes")) + , m_RenderableNodes(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_RenderableNodes") + , m_LightToNodeMap(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_LightToNodeMap") + , m_CamerasAndLights(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_CamerasAndLights") + , m_Camera(NULL) + , m_Lights(inRenderer.GetContext().GetAllocator(), "SLayerRenderPreparationData::m_Lights") + , m_OpaqueObjects(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_OpaqueObjects") + , m_TransparentObjects(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_TransparentObjects") + , m_RenderedOpaqueObjects(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_RenderedOpaqueObjects") + , m_RenderedTransparentObjects(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_RenderedTransparentObjects") + , m_IRenderWidgets(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_IRenderWidgets") + , m_SourceLightDirections(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_SourceLightDirections") + , m_LightDirections(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_LightDirections") + , m_ModelContexts(inRenderer.GetContext().GetAllocator(), + "SLayerRenderPreparationData::m_ModelContexts") + , m_CGLightingFeatureName( + inRenderer.GetContext().GetStringTable().RegisterStr("QT3DS_ENABLE_CG_LIGHTING")) + , m_FeaturesDirty(true) + , m_FeatureSetHash(0) + , m_TooManyLightsError(false) + { + } + + SLayerRenderPreparationData::~SLayerRenderPreparationData() {} + + bool SLayerRenderPreparationData::NeedsWidgetTexture() const + { + return m_IRenderWidgets.size() > 0; + } + + void SLayerRenderPreparationData::SetShaderFeature(CRegisteredString theStr, bool inValue) + { + SShaderPreprocessorFeature item(theStr, inValue); + eastl::vector::iterator iter = m_Features.begin(), + end = m_Features.end(); + + // empty loop intentional. + for (; iter != end && ((iter->m_Name == theStr) == false); ++iter) + ; + + if (iter != end) { + if (iter->m_Enabled != inValue) { + iter->m_Enabled = inValue; + m_FeaturesDirty = true; + m_FeatureSetHash = 0; + } + } else { + m_Features.push_back(item); + m_FeaturesDirty = true; + m_FeatureSetHash = 0; + } + } + + void SLayerRenderPreparationData::SetShaderFeature(const char *inName, bool inValue) + { + CRegisteredString theStr(m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(inName)); + SetShaderFeature(theStr, inValue); + } + + NVConstDataRef SLayerRenderPreparationData::GetShaderFeatureSet() + { + if (m_FeaturesDirty) { + eastl::sort(m_Features.begin(), m_Features.end()); + m_FeaturesDirty = false; + } + return toConstDataRef(m_Features.data(), (QT3DSU32)m_Features.size()); + } + + size_t SLayerRenderPreparationData::GetShaderFeatureSetHash() + { + if (!m_FeatureSetHash) + m_FeatureSetHash = HashShaderFeatureSet(GetShaderFeatureSet()); + return m_FeatureSetHash; + } + + bool SLayerRenderPreparationData::GetShadowMapManager() + { + if (m_ShadowMapManager.mPtr) + return true; + + m_ShadowMapManager.mPtr = Qt3DSShadowMap::Create(m_Renderer.GetQt3DSContext()); + + return m_ShadowMapManager.mPtr != NULL; + } + + bool SLayerRenderPreparationData::GetOffscreenRenderer() + { + if (m_LastFrameOffscreenRenderer.mPtr) + return true; + + if (m_Layer.m_RenderPlugin && m_Layer.m_RenderPlugin->m_Flags.IsActive()) { + IRenderPluginInstance *theInstance = + m_Renderer.GetQt3DSContext().GetRenderPluginManager().GetOrCreateRenderPluginInstance( + m_Layer.m_RenderPlugin->m_PluginPath, m_Layer.m_RenderPlugin); + if (theInstance) { + m_Renderer.GetQt3DSContext() + .GetOffscreenRenderManager() + .MaybeRegisterOffscreenRenderer(&theInstance, *theInstance); + m_LastFrameOffscreenRenderer = theInstance; + } + } + if (m_LastFrameOffscreenRenderer.mPtr == NULL) + m_LastFrameOffscreenRenderer = + m_Renderer.GetQt3DSContext().GetOffscreenRenderManager().GetOffscreenRenderer( + m_Layer.m_TexturePath); + return m_LastFrameOffscreenRenderer.mPtr != NULL; + } + + QT3DSVec3 SLayerRenderPreparationData::GetCameraDirection() + { + if (m_CameraDirection.hasValue() == false) { + if (m_Camera) + m_CameraDirection = m_Camera->GetScalingCorrectDirection(); + else + m_CameraDirection = QT3DSVec3(0, 0, -1); + } + return *m_CameraDirection; + } + + // Per-frame cache of renderable objects post-sort. + NVDataRef SLayerRenderPreparationData::GetOpaqueRenderableObjects() + { + if (m_RenderedOpaqueObjects.empty() == false || m_Camera == NULL) + return m_RenderedOpaqueObjects; + if (m_Layer.m_Flags.IsLayerEnableDepthTest() && m_OpaqueObjects.empty() == false) { + QT3DSVec3 theCameraDirection(GetCameraDirection()); + QT3DSVec3 theCameraPosition = m_Camera->GetGlobalPos(); + m_RenderedOpaqueObjects.assign(m_OpaqueObjects.begin(), m_OpaqueObjects.end()); + // Setup the object's sorting information + for (QT3DSU32 idx = 0, end = m_RenderedOpaqueObjects.size(); idx < end; ++idx) { + SRenderableObject &theInfo = *m_RenderedOpaqueObjects[idx]; + QT3DSVec3 difference = theInfo.m_WorldCenterPoint - theCameraPosition; + theInfo.m_CameraDistanceSq = difference.dot(theCameraDirection); + } + + ForwardingAllocator alloc(m_Renderer.GetPerFrameAllocator(), "SortAllocations"); + // Render nearest to furthest objects + eastl::merge_sort(m_RenderedOpaqueObjects.begin(), m_RenderedOpaqueObjects.end(), alloc, + ISRenderObjectPtrLessThan); + } + return m_RenderedOpaqueObjects; + } + + // If layer depth test is false, this may also contain opaque objects. + NVDataRef SLayerRenderPreparationData::GetTransparentRenderableObjects() + { + if (m_RenderedTransparentObjects.empty() == false || m_Camera == NULL) + return m_RenderedTransparentObjects; + + m_RenderedTransparentObjects.assign(m_TransparentObjects.begin(), + m_TransparentObjects.end()); + + if (m_Layer.m_Flags.IsLayerEnableDepthTest() == false) + m_RenderedTransparentObjects.insert(m_RenderedTransparentObjects.end(), + m_OpaqueObjects.begin(), m_OpaqueObjects.end()); + + if (m_RenderedTransparentObjects.empty() == false) { + QT3DSVec3 theCameraDirection(GetCameraDirection()); + QT3DSVec3 theCameraPosition = m_Camera->GetGlobalPos(); + + // Setup the object's sorting information + for (QT3DSU32 idx = 0, end = m_RenderedTransparentObjects.size(); idx < end; ++idx) { + SRenderableObject &theInfo = *m_RenderedTransparentObjects[idx]; + QT3DSVec3 difference = theInfo.m_WorldCenterPoint - theCameraPosition; + theInfo.m_CameraDistanceSq = difference.dot(theCameraDirection); + } + ForwardingAllocator alloc(m_Renderer.GetPerFrameAllocator(), "SortAllocations"); + // render furthest to nearest. + eastl::merge_sort(m_RenderedTransparentObjects.begin(), + m_RenderedTransparentObjects.end(), alloc, + ISRenderObjectPtrGreatThan); + } + + return m_RenderedTransparentObjects; + } + +#define MAX_LAYER_WIDGETS 200 + + void SLayerRenderPreparationData::AddRenderWidget(IRenderWidget &inWidget) + { + // The if the layer is not active then the widget can't be displayed. + // Furthermore ResetForFrame won't be called below which leads to stale + // widgets in the m_IRenderWidgets array. These stale widgets would get rendered + // the next time the layer was active potentially causing a crash. + if (!m_Layer.m_Flags.IsActive()) + return; + + // Ensure we clear the widget layer always + m_Renderer.LayerNeedsFrameClear(*static_cast(this)); + + if (m_IRenderWidgets.size() < MAX_LAYER_WIDGETS) + m_IRenderWidgets.push_back(&inWidget); + } + +#define RENDER_FRAME_NEW(type) QT3DS_NEW(m_Renderer.GetPerFrameAllocator(), type) + +#define QT3DS_RENDER_MINIMUM_RENDER_OPACITY .01f + + SShaderDefaultMaterialKey + SLayerRenderPreparationData::GenerateLightingKey(DefaultMaterialLighting::Enum inLightingType) + { + SShaderDefaultMaterialKey theGeneratedKey(GetShaderFeatureSetHash()); + const bool lighting = inLightingType != DefaultMaterialLighting::NoLighting; + m_Renderer.DefaultMaterialShaderKeyProperties().m_HasLighting.SetValue(theGeneratedKey, + lighting); + if (lighting) { + const bool lightProbe = m_Layer.m_LightProbe + && m_Layer.m_LightProbe->m_TextureData.m_Texture; + m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(theGeneratedKey, + lightProbe); + + QT3DSU32 numLights = (QT3DSU32)m_Lights.size(); + if (numLights > SShaderDefaultMaterialKeyProperties::LightCount + && m_TooManyLightsError == false) { + m_TooManyLightsError = true; + numLights = SShaderDefaultMaterialKeyProperties::LightCount; + qCCritical(INVALID_OPERATION, "Too many lights on layer, max is 7"); + QT3DS_ASSERT(false); + } + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightCount.SetValue(theGeneratedKey, + numLights); + + for (QT3DSU32 lightIdx = 0, lightEnd = m_Lights.size(); + lightIdx < lightEnd; ++lightIdx) { + SLight *theLight(m_Lights[lightIdx]); + const bool isDirectional = theLight->m_LightType == RenderLightTypes::Directional; + const bool isArea = theLight->m_LightType == RenderLightTypes::Area; + const bool castShadowsArea = (theLight->m_LightType != RenderLightTypes::Area) + && (theLight->m_CastShadow); + + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightFlags[lightIdx] + .SetValue(theGeneratedKey, !isDirectional); + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightAreaFlags[lightIdx] + .SetValue(theGeneratedKey, isArea); + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightShadowFlags[lightIdx] + .SetValue(theGeneratedKey, castShadowsArea); + } + } + return theGeneratedKey; + } + + bool SLayerRenderPreparationData::PrepareTextForRender( + SText &inText, const QT3DSMat44 &inViewProjection, QT3DSF32 inTextScaleFactor, + SLayerRenderPreparationResultFlags &ioFlags) + { + ITextTextureCache *theTextRenderer = m_Renderer.GetQt3DSContext().GetTextureCache(); + if (theTextRenderer == NULL) + return false; + + SRenderableObjectFlags theFlags; + theFlags.SetHasTransparency(true); + theFlags.SetCompletelyTransparent(inText.m_GlobalOpacity < .01f); + theFlags.SetPickable(true); + bool retval = false; + + if (theFlags.IsCompletelyTransparent() == false) { + retval = inText.m_Flags.IsDirty() || inText.m_Flags.IsTextDirty(); + inText.m_Flags.SetTextDirty(false); + TTPathObjectAndTexture theResult = + theTextRenderer->RenderText(inText, inTextScaleFactor); + inText.m_TextTexture = theResult.second.second.mPtr; + inText.m_TextTextureDetails = theResult.second.first; + inText.m_PathFontItem = theResult.first.second; + inText.m_PathFontDetails = theResult.first.first; + STextScaleAndOffset theScaleAndOffset(*inText.m_TextTexture, + inText.m_TextTextureDetails, inText); + QT3DSVec2 theTextScale(theScaleAndOffset.m_TextScale); + QT3DSVec2 theTextOffset(theScaleAndOffset.m_TextOffset); + QT3DSVec3 minimum(theTextOffset[0] - theTextScale[0], theTextOffset[1] - theTextScale[1], + 0); + QT3DSVec3 maximum(theTextOffset[0] + theTextScale[0], theTextOffset[1] + theTextScale[1], + 0); + inText.m_Bounds = NVBounds3(minimum, maximum); + QT3DSMat44 theMVP; + QT3DSMat33 theNormalMatrix; + inText.CalculateMVPAndNormalMatrix(inViewProjection, theMVP, theNormalMatrix); + + if (inText.m_PathFontDetails) + ioFlags.SetRequiresStencilBuffer(true); + + STextRenderable *theRenderable = RENDER_FRAME_NEW(STextRenderable)( + theFlags, inText.GetGlobalPos(), m_Renderer, inText, inText.m_Bounds, theMVP, + inViewProjection, *inText.m_TextTexture, theTextOffset, theTextScale); + m_TransparentObjects.push_back(theRenderable); + } + return retval; + } + + eastl::pair + SLayerRenderPreparationData::ResolveReferenceMaterial(SGraphObject *inMaterial) + { + bool subsetDirty = false; + bool badIdea = false; + SGraphObject *theSourceMaterialObject(inMaterial); + SGraphObject *theMaterialObject(inMaterial); + while (theMaterialObject + && theMaterialObject->m_Type == GraphObjectTypes::ReferencedMaterial && !badIdea) { + SReferencedMaterial *theRefMaterial = + static_cast(theMaterialObject); + theMaterialObject = theRefMaterial->m_ReferencedMaterial; + if (theMaterialObject == theSourceMaterialObject) { + badIdea = true; + } + + if (theRefMaterial == theSourceMaterialObject) { + theRefMaterial->m_Dirty.UpdateDirtyForFrame(); + } + subsetDirty = subsetDirty | theRefMaterial->m_Dirty.IsDirty(); + } + if (badIdea) { + theMaterialObject = NULL; + } + return eastl::make_pair(subsetDirty, theMaterialObject); + } + + bool SLayerRenderPreparationData::PreparePathForRender( + SPath &inPath, const QT3DSMat44 &inViewProjection, + const Option &inClipFrustum, SLayerRenderPreparationResultFlags &ioFlags) + { + SRenderableObjectFlags theSharedFlags; + theSharedFlags.SetPickable(true); + QT3DSF32 subsetOpacity = inPath.m_GlobalOpacity; + bool retval = inPath.m_Flags.IsDirty(); + inPath.m_Flags.SetDirty(false); + QT3DSMat44 theMVP; + QT3DSMat33 theNormalMatrix; + + inPath.CalculateMVPAndNormalMatrix(inViewProjection, theMVP, theNormalMatrix); + NVBounds3 theBounds(this->m_Renderer.GetQt3DSContext().GetPathManager().GetBounds(inPath)); + + if (inPath.m_GlobalOpacity >= QT3DS_RENDER_MINIMUM_RENDER_OPACITY + && inClipFrustum.hasValue()) { + // Check bounding box against the clipping planes + NVBounds3 theGlobalBounds = theBounds; + theGlobalBounds.transform(inPath.m_GlobalTransform); + if (inClipFrustum->intersectsWith(theGlobalBounds) == false) + subsetOpacity = 0.0f; + } + + SGraphObject *theMaterials[2] = { inPath.m_Material, inPath.m_SecondMaterial }; + + if (inPath.m_PathType == PathTypes::Geometry + || inPath.m_PaintStyle != PathPaintStyles::FilledAndStroked) + theMaterials[1] = NULL; + + // We need to fill material to be the first one rendered so the stroke goes on top. + // In the timeline, however, this is reversed. + + if (theMaterials[1]) + eastl::swap(theMaterials[1], theMaterials[0]); + + for (QT3DSU32 idx = 0, end = 2; idx < end; ++idx) { + if (theMaterials[idx] == NULL) + continue; + + SRenderableObjectFlags theFlags = theSharedFlags; + + eastl::pair theMaterialAndDirty( + ResolveReferenceMaterial(theMaterials[idx])); + SGraphObject *theMaterial(theMaterialAndDirty.second); + retval = retval || theMaterialAndDirty.first; + + if (theMaterial != NULL && theMaterial->m_Type == GraphObjectTypes::DefaultMaterial) { + SDefaultMaterial *theDefaultMaterial = static_cast(theMaterial); + // Don't clear dirty flags if the material was referenced. + bool clearMaterialFlags = theMaterial == inPath.m_Material; + SDefaultMaterialPreparationResult prepResult(PrepareDefaultMaterialForRender( + *theDefaultMaterial, theFlags, subsetOpacity, clearMaterialFlags)); + + theFlags = prepResult.m_RenderableFlags; + if (inPath.m_PathType == PathTypes::Geometry) { + if ((inPath.m_BeginCapping != PathCapping::Noner + && inPath.m_BeginCapOpacity < 1.0f) + || (inPath.m_EndCapping != PathCapping::Noner + && inPath.m_EndCapOpacity < 1.0f)) + theFlags.SetHasTransparency(true); + } else { + ioFlags.SetRequiresStencilBuffer(true); + } + retval = retval || prepResult.m_Dirty; + bool isStroke = true; + if (idx == 0 && inPath.m_PathType == PathTypes::Painted) { + if (inPath.m_PaintStyle == PathPaintStyles::Filled + || inPath.m_PaintStyle == PathPaintStyles::FilledAndStroked) + isStroke = false; + } + + SPathRenderable *theRenderable = RENDER_FRAME_NEW(SPathRenderable)( + theFlags, inPath.GetGlobalPos(), m_Renderer, inPath.m_GlobalTransform, + theBounds, inPath, theMVP, theNormalMatrix, *theMaterial, prepResult.m_Opacity, + prepResult.m_MaterialKey, isStroke); + theRenderable->m_FirstImage = prepResult.m_FirstImage; + + IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); + IPathManager &thePathManager = qt3dsContext.GetPathManager(); + retval = thePathManager.PrepareForRender(inPath) || retval; + retval |= (inPath.m_WireframeMode != qt3dsContext.GetWireframeMode()); + inPath.m_WireframeMode = qt3dsContext.GetWireframeMode(); + + if (theFlags.HasTransparency()) + m_TransparentObjects.push_back(theRenderable); + else + m_OpaqueObjects.push_back(theRenderable); + } else if (theMaterial != NULL + && theMaterial->m_Type == GraphObjectTypes::CustomMaterial) { + SCustomMaterial *theCustomMaterial = static_cast(theMaterial); + // Don't clear dirty flags if the material was referenced. + // bool clearMaterialFlags = theMaterial == inPath.m_Material; + SDefaultMaterialPreparationResult prepResult( + PrepareCustomMaterialForRender(*theCustomMaterial, theFlags, subsetOpacity)); + + theFlags = prepResult.m_RenderableFlags; + if (inPath.m_PathType == PathTypes::Geometry) { + if ((inPath.m_BeginCapping != PathCapping::Noner + && inPath.m_BeginCapOpacity < 1.0f) + || (inPath.m_EndCapping != PathCapping::Noner + && inPath.m_EndCapOpacity < 1.0f)) + theFlags.SetHasTransparency(true); + } else { + ioFlags.SetRequiresStencilBuffer(true); + } + + retval = retval || prepResult.m_Dirty; + bool isStroke = true; + if (idx == 0 && inPath.m_PathType == PathTypes::Painted) { + if (inPath.m_PaintStyle == PathPaintStyles::Filled + || inPath.m_PaintStyle == PathPaintStyles::FilledAndStroked) + isStroke = false; + } + + SPathRenderable *theRenderable = RENDER_FRAME_NEW(SPathRenderable)( + theFlags, inPath.GetGlobalPos(), m_Renderer, inPath.m_GlobalTransform, + theBounds, inPath, theMVP, theNormalMatrix, *theMaterial, prepResult.m_Opacity, + prepResult.m_MaterialKey, isStroke); + theRenderable->m_FirstImage = prepResult.m_FirstImage; + + IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); + IPathManager &thePathManager = qt3dsContext.GetPathManager(); + retval = thePathManager.PrepareForRender(inPath) || retval; + retval |= (inPath.m_WireframeMode != qt3dsContext.GetWireframeMode()); + inPath.m_WireframeMode = qt3dsContext.GetWireframeMode(); + + if (theFlags.HasTransparency()) + m_TransparentObjects.push_back(theRenderable); + else + m_OpaqueObjects.push_back(theRenderable); + } + } + return retval; + } + + void SLayerRenderPreparationData::PrepareImageForRender( + SImage &inImage, ImageMapTypes::Enum inMapType, SRenderableImage *&ioFirstImage, + SRenderableImage *&ioNextImage, SRenderableObjectFlags &ioFlags, + SShaderDefaultMaterialKey &inShaderKey, QT3DSU32 inImageIndex) + { + IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); + IBufferManager &bufferManager = qt3dsContext.GetBufferManager(); + IOffscreenRenderManager &theOffscreenRenderManager( + qt3dsContext.GetOffscreenRenderManager()); + IRenderPluginManager &theRenderPluginManager(qt3dsContext.GetRenderPluginManager()); + if (inImage.ClearDirty(bufferManager, theOffscreenRenderManager, theRenderPluginManager)) + ioFlags |= RenderPreparationResultFlagValues::Dirty; + + // All objects with offscreen renderers are pickable so we can pass the pick through to the + // offscreen renderer and let it deal with the pick. + if (inImage.m_LastFrameOffscreenRenderer != NULL) { + ioFlags.SetPickable(true); + ioFlags |= RenderPreparationResultFlagValues::HasTransparency; + } + + if (inImage.m_TextureData.m_Texture) { + if (inImage.m_TextureData.m_TextureFlags.HasTransparency() + && (inMapType == ImageMapTypes::Diffuse + || inMapType == ImageMapTypes::Opacity + || inMapType == ImageMapTypes::Translucency)) { + ioFlags |= RenderPreparationResultFlagValues::HasTransparency; + } + // Textures used in general have linear characteristics. + // PKC -- The filters are properly set already. Setting them here only overrides what + // would + // otherwise be a correct setting. + // inImage.m_TextureData.m_Texture->SetMinFilter( NVRenderTextureMinifyingOp::Linear ); + // inImage.m_TextureData.m_Texture->SetMagFilter( NVRenderTextureMagnifyingOp::Linear ); + + SRenderableImage *theImage = RENDER_FRAME_NEW(SRenderableImage)(inMapType, inImage); + SShaderKeyImageMap &theKeyProp = + m_Renderer.DefaultMaterialShaderKeyProperties().m_ImageMaps[inImageIndex]; + + theKeyProp.SetEnabled(inShaderKey, true); + switch (inImage.m_MappingMode) { + default: + QT3DS_ASSERT(false); + // fallthrough intentional + case ImageMappingModes::Normal: + break; + case ImageMappingModes::Environment: + theKeyProp.SetEnvMap(inShaderKey, true); + break; + case ImageMappingModes::LightProbe: + theKeyProp.SetLightProbe(inShaderKey, true); + break; + } + + if (inImage.m_TextureData.m_TextureFlags.IsInvertUVCoords()) + theKeyProp.SetInvertUVMap(inShaderKey, true); + if (ioFirstImage == NULL) + ioFirstImage = theImage; + else + ioNextImage->m_NextImage = theImage; + + // assume offscreen renderer produces non-premultiplied image + if (inImage.m_LastFrameOffscreenRenderer == nullptr + && inImage.m_TextureData.m_TextureFlags.IsPreMultiplied()) + theKeyProp.SetPremultiplied(inShaderKey, true); + + SShaderKeyTextureSwizzle &theSwizzleKeyProp = + m_Renderer.DefaultMaterialShaderKeyProperties().m_TextureSwizzle[inImageIndex]; + theSwizzleKeyProp.SetSwizzleMode( + inShaderKey, inImage.m_TextureData.m_Texture->GetTextureSwizzleMode(), true); + + ioNextImage = theImage; + } + } + + SDefaultMaterialPreparationResult SLayerRenderPreparationData::PrepareDefaultMaterialForRender( + SDefaultMaterial &inMaterial, SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity, + bool inClearDirtyFlags) + { + SDefaultMaterial *theMaterial = &inMaterial; + SDefaultMaterialPreparationResult retval(GenerateLightingKey(theMaterial->m_Lighting)); + retval.m_RenderableFlags = inExistingFlags; + SRenderableObjectFlags &renderableFlags(retval.m_RenderableFlags); + SShaderDefaultMaterialKey &theGeneratedKey(retval.m_MaterialKey); + retval.m_Opacity = inOpacity; + QT3DSF32 &subsetOpacity(retval.m_Opacity); + + if (theMaterial->m_Dirty.IsDirty()) { + renderableFlags |= RenderPreparationResultFlagValues::Dirty; + } + subsetOpacity *= theMaterial->m_Opacity; + if (inClearDirtyFlags) + theMaterial->m_Dirty.UpdateDirtyForFrame(); + + SRenderableImage *firstImage = NULL; + + // set wireframe mode + m_Renderer.DefaultMaterialShaderKeyProperties().m_WireframeMode.SetValue( + theGeneratedKey, m_Renderer.GetQt3DSContext().GetWireframeMode()); + + if (theMaterial->m_IblProbe && CheckLightProbeDirty(*theMaterial->m_IblProbe)) { + m_Renderer.PrepareImageForIbl(*theMaterial->m_IblProbe); + } + + if (!m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.GetValue(theGeneratedKey)) { + bool lightProbeValid = HasValidLightProbe(theMaterial->m_IblProbe); + SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", lightProbeValid); + m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(theGeneratedKey, + lightProbeValid); + // SetShaderFeature( "QT3DS_ENABLE_IBL_FOV", + // m_Renderer.GetLayerRenderData()->m_Layer.m_ProbeFov < 180.0f ); + } + + if (subsetOpacity >= QT3DS_RENDER_MINIMUM_RENDER_OPACITY) { + + if (theMaterial->m_BlendMode != DefaultMaterialBlendMode::Normal + || theMaterial->m_OpacityMap) { + renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; + } + + bool specularEnabled = theMaterial->IsSpecularEnabled(); + m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularEnabled.SetValue( + theGeneratedKey, specularEnabled); + if (specularEnabled) { + m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularModel.SetSpecularModel( + theGeneratedKey, theMaterial->m_SpecularModel); + } + + m_Renderer.DefaultMaterialShaderKeyProperties().m_FresnelEnabled.SetValue( + theGeneratedKey, theMaterial->IsFresnelEnabled()); + + m_Renderer.DefaultMaterialShaderKeyProperties().m_VertexColorsEnabled.SetValue( + theGeneratedKey, theMaterial->IsVertexColorsEnabled()); + + // Run through the material's images and prepare them for render. + // this may in fact set pickable on the renderable flags if one of the images + // links to a sub presentation or any offscreen rendered object. + SRenderableImage *nextImage = NULL; +#define CHECK_IMAGE_AND_PREPARE(img, imgtype, shadercomponent) \ + if ((img)) \ + PrepareImageForRender(*(img), imgtype, firstImage, nextImage, renderableFlags, \ + theGeneratedKey, shadercomponent); + + CHECK_IMAGE_AND_PREPARE(theMaterial->m_DiffuseMaps[0], ImageMapTypes::Diffuse, + SShaderDefaultMaterialKeyProperties::DiffuseMap0); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_DiffuseMaps[1], ImageMapTypes::Diffuse, + SShaderDefaultMaterialKeyProperties::DiffuseMap1); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_DiffuseMaps[2], ImageMapTypes::Diffuse, + SShaderDefaultMaterialKeyProperties::DiffuseMap2); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_EmissiveMap, ImageMapTypes::Emissive, + SShaderDefaultMaterialKeyProperties::EmissiveMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_EmissiveMap2, ImageMapTypes::Emissive, + SShaderDefaultMaterialKeyProperties::EmissiveMap2); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_SpecularReflection, ImageMapTypes::Specular, + SShaderDefaultMaterialKeyProperties::SpecularMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_RoughnessMap, ImageMapTypes::Roughness, + SShaderDefaultMaterialKeyProperties::RoughnessMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_OpacityMap, ImageMapTypes::Opacity, + SShaderDefaultMaterialKeyProperties::OpacityMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_BumpMap, ImageMapTypes::Bump, + SShaderDefaultMaterialKeyProperties::BumpMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_SpecularMap, ImageMapTypes::SpecularAmountMap, + SShaderDefaultMaterialKeyProperties::SpecularAmountMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_NormalMap, ImageMapTypes::Normal, + SShaderDefaultMaterialKeyProperties::NormalMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_DisplacementMap, ImageMapTypes::Displacement, + SShaderDefaultMaterialKeyProperties::DisplacementMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_TranslucencyMap, ImageMapTypes::Translucency, + SShaderDefaultMaterialKeyProperties::TranslucencyMap); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_Lightmaps.m_LightmapIndirect, + ImageMapTypes::LightmapIndirect, + SShaderDefaultMaterialKeyProperties::LightmapIndirect); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_Lightmaps.m_LightmapRadiosity, + ImageMapTypes::LightmapRadiosity, + SShaderDefaultMaterialKeyProperties::LightmapRadiosity); + CHECK_IMAGE_AND_PREPARE(theMaterial->m_Lightmaps.m_LightmapShadow, + ImageMapTypes::LightmapShadow, + SShaderDefaultMaterialKeyProperties::LightmapShadow); + } +#undef CHECK_IMAGE_AND_PREPARE + + if (subsetOpacity < QT3DS_RENDER_MINIMUM_RENDER_OPACITY) { + subsetOpacity = 0.0f; + // You can still pick against completely transparent objects(or rather their bounding + // box) + // you just don't render them. + renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; + renderableFlags |= RenderPreparationResultFlagValues::CompletelyTransparent; + } + + if (IsNotOne(subsetOpacity)) + renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; + + retval.m_FirstImage = firstImage; + if (retval.m_RenderableFlags.IsDirty()) + retval.m_Dirty = true; + return retval; + } + + SDefaultMaterialPreparationResult SLayerRenderPreparationData::PrepareCustomMaterialForRender( + SCustomMaterial &inMaterial, SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity) + { + SDefaultMaterialPreparationResult retval(GenerateLightingKey( + DefaultMaterialLighting::FragmentLighting)); // always fragment lighting + retval.m_RenderableFlags = inExistingFlags; + SRenderableObjectFlags &renderableFlags(retval.m_RenderableFlags); + SShaderDefaultMaterialKey &theGeneratedKey(retval.m_MaterialKey); + retval.m_Opacity = inOpacity; + QT3DSF32 &subsetOpacity(retval.m_Opacity); + + // set wireframe mode + m_Renderer.DefaultMaterialShaderKeyProperties().m_WireframeMode.SetValue( + theGeneratedKey, m_Renderer.GetQt3DSContext().GetWireframeMode()); + + if (subsetOpacity < QT3DS_RENDER_MINIMUM_RENDER_OPACITY) { + subsetOpacity = 0.0f; + // You can still pick against completely transparent objects(or rather their bounding + // box) + // you just don't render them. + renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; + renderableFlags |= RenderPreparationResultFlagValues::CompletelyTransparent; + } + + if (IsNotOne(subsetOpacity)) + renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; + + SRenderableImage *firstImage = NULL; + SRenderableImage *nextImage = NULL; + +#define CHECK_IMAGE_AND_PREPARE(img, imgtype, shadercomponent) \ + if ((img)) \ + PrepareImageForRender(*(img), imgtype, firstImage, nextImage, renderableFlags, \ + theGeneratedKey, shadercomponent); + + CHECK_IMAGE_AND_PREPARE(inMaterial.m_DisplacementMap, ImageMapTypes::Displacement, + SShaderDefaultMaterialKeyProperties::DisplacementMap); + CHECK_IMAGE_AND_PREPARE(inMaterial.m_Lightmaps.m_LightmapIndirect, + ImageMapTypes::LightmapIndirect, + SShaderDefaultMaterialKeyProperties::LightmapIndirect); + CHECK_IMAGE_AND_PREPARE(inMaterial.m_Lightmaps.m_LightmapRadiosity, + ImageMapTypes::LightmapRadiosity, + SShaderDefaultMaterialKeyProperties::LightmapRadiosity); + CHECK_IMAGE_AND_PREPARE(inMaterial.m_Lightmaps.m_LightmapShadow, + ImageMapTypes::LightmapShadow, + SShaderDefaultMaterialKeyProperties::LightmapShadow); +#undef CHECK_IMAGE_AND_PREPARE + + retval.m_FirstImage = firstImage; + return retval; + } + + bool SLayerRenderPreparationData::PrepareModelForRender( + SModel &inModel, const QT3DSMat44 &inViewProjection, + const Option &inClipFrustum, TNodeLightEntryList &inScopedLights) + { + IQt3DSRenderContext &qt3dsContext(m_Renderer.GetQt3DSContext()); + IBufferManager &bufferManager = qt3dsContext.GetBufferManager(); + SRenderMesh *theMesh = bufferManager.LoadMesh(inModel.m_MeshPath); + if (theMesh == NULL) + return false; + + SGraphObject *theSourceMaterialObject = inModel.m_FirstMaterial; + SModelContext &theModelContext = + *RENDER_FRAME_NEW(SModelContext)(inModel, inViewProjection); + m_ModelContexts.push_back(&theModelContext); + + bool subsetDirty = false; + + SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, m_SourceLightDirections, + inScopedLights); + SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); + for (QT3DSU32 idx = 0, end = theMesh->m_Subsets.size(); idx < end && theSourceMaterialObject; + ++idx, theSourceMaterialObject = GetNextMaterialSibling(theSourceMaterialObject)) { + SRenderSubset &theOuterSubset(theMesh->m_Subsets[idx]); + { + SRenderSubset &theSubset(theOuterSubset); + SRenderableObjectFlags renderableFlags; + renderableFlags.SetPickable(false); + renderableFlags.SetShadowCaster(inModel.m_ShadowCaster); + QT3DSF32 subsetOpacity = inModel.m_GlobalOpacity; + QT3DSVec3 theModelCenter(theSubset.m_Bounds.getCenter()); + theModelCenter = inModel.m_GlobalTransform.transform(theModelCenter); + + if (subsetOpacity >= QT3DS_RENDER_MINIMUM_RENDER_OPACITY + && inClipFrustum.hasValue()) { + // Check bounding box against the clipping planes + NVBounds3 theGlobalBounds = theSubset.m_Bounds; + theGlobalBounds.transform(theModelContext.m_Model.m_GlobalTransform); + if (inClipFrustum->intersectsWith(theGlobalBounds) == false) + subsetOpacity = 0.0f; + } + + // For now everything is pickable. Eventually we want to have localPickable and + // globalPickable set on the node during + // updates and have the runtime tell us what is pickable and what is not pickable. + // Completely transparent models cannot be pickable. But models with completely + // transparent materials + // still are. This allows the artist to control pickability in a somewhat + // fine-grained style. + bool canModelBePickable = inModel.m_GlobalOpacity > .01f; + renderableFlags.SetPickable(canModelBePickable + && (theModelContext.m_Model.m_Flags.IsGloballyPickable() + || renderableFlags.GetPickable())); + SRenderableObject *theRenderableObject(NULL); + eastl::pair theMaterialObjectAndDirty = + ResolveReferenceMaterial(theSourceMaterialObject); + SGraphObject *theMaterialObject = theMaterialObjectAndDirty.second; + subsetDirty = subsetDirty || theMaterialObjectAndDirty.first; + if (theMaterialObject == NULL) + continue; + + // set tessellation + if (inModel.m_TessellationMode != TessModeValues::NoTess) { + theSubset.m_PrimitiveType = NVRenderDrawMode::Patches; + // set tessellation factor + theSubset.m_EdgeTessFactor = inModel.m_EdgeTess; + theSubset.m_InnerTessFactor = inModel.m_InnerTess; + // update the vertex ver patch count in the input assembler + // currently we only support triangle patches so count is always 3 + theSubset.m_InputAssembler->SetPatchVertexCount(3); + theSubset.m_InputAssemblerDepth->SetPatchVertexCount(3); + // check wireframe mode + theSubset.m_WireframeMode = qt3dsContext.GetWireframeMode(); + + subsetDirty = + subsetDirty | (theSubset.m_WireframeMode != inModel.m_WireframeMode); + inModel.m_WireframeMode = qt3dsContext.GetWireframeMode(); + } else { + theSubset.m_PrimitiveType = theSubset.m_InputAssembler->GetPrimitiveType(); + theSubset.m_InputAssembler->SetPatchVertexCount(1); + theSubset.m_InputAssemblerDepth->SetPatchVertexCount(1); + // currently we allow wirframe mode only if tessellation is on + theSubset.m_WireframeMode = false; + + subsetDirty = + subsetDirty | (theSubset.m_WireframeMode != inModel.m_WireframeMode); + inModel.m_WireframeMode = false; + } + // Only clear flags on the materials in this direct hierarchy. Do not clear them of + // this + // references materials in another hierarchy. + bool clearMaterialDirtyFlags = theMaterialObject == theSourceMaterialObject; + + if (theMaterialObject == NULL) + continue; + + if (theMaterialObject->m_Type == GraphObjectTypes::DefaultMaterial) { + SDefaultMaterial &theMaterial( + static_cast(*theMaterialObject)); + SDefaultMaterialPreparationResult theMaterialPrepResult( + PrepareDefaultMaterialForRender(theMaterial, renderableFlags, subsetOpacity, + clearMaterialDirtyFlags)); + SShaderDefaultMaterialKey theGeneratedKey = theMaterialPrepResult.m_MaterialKey; + subsetOpacity = theMaterialPrepResult.m_Opacity; + SRenderableImage *firstImage(theMaterialPrepResult.m_FirstImage); + subsetDirty |= theMaterialPrepResult.m_Dirty; + renderableFlags = theMaterialPrepResult.m_RenderableFlags; + + m_Renderer.DefaultMaterialShaderKeyProperties() + .m_TessellationMode.SetTessellationMode(theGeneratedKey, + inModel.m_TessellationMode, true); + + NVConstDataRef boneGlobals; + if (theSubset.m_Joints.size()) { + QT3DS_ASSERT(false); + } + + theRenderableObject = RENDER_FRAME_NEW(SSubsetRenderable)( + renderableFlags, theModelCenter, m_Renderer, theSubset, theMaterial, + theModelContext, subsetOpacity, firstImage, theGeneratedKey, boneGlobals); + subsetDirty = subsetDirty || renderableFlags.IsDirty(); + + } // if type == DefaultMaterial + else if (theMaterialObject->m_Type == GraphObjectTypes::CustomMaterial) { + SCustomMaterial &theMaterial( + static_cast(*theMaterialObject)); + + ICustomMaterialSystem &theMaterialSystem( + qt3dsContext.GetCustomMaterialSystem()); + subsetDirty |= theMaterialSystem.PrepareForRender( + theModelContext.m_Model, theSubset, theMaterial, clearMaterialDirtyFlags); + + SDefaultMaterialPreparationResult theMaterialPrepResult( + PrepareCustomMaterialForRender(theMaterial, renderableFlags, + subsetOpacity)); + SShaderDefaultMaterialKey theGeneratedKey = theMaterialPrepResult.m_MaterialKey; + subsetOpacity = theMaterialPrepResult.m_Opacity; + SRenderableImage *firstImage(theMaterialPrepResult.m_FirstImage); + renderableFlags = theMaterialPrepResult.m_RenderableFlags; + + // prepare for render tells us if the object is transparent + if (theMaterial.m_hasTransparency) + renderableFlags |= RenderPreparationResultFlagValues::HasTransparency; + // prepare for render tells us if the object is transparent + if (theMaterial.m_hasRefraction) + renderableFlags |= RenderPreparationResultFlagValues::HasRefraction; + + m_Renderer.DefaultMaterialShaderKeyProperties() + .m_TessellationMode.SetTessellationMode(theGeneratedKey, + inModel.m_TessellationMode, true); + + if (theMaterial.m_IblProbe && CheckLightProbeDirty(*theMaterial.m_IblProbe)) { + m_Renderer.PrepareImageForIbl(*theMaterial.m_IblProbe); + } + + theRenderableObject = RENDER_FRAME_NEW(SCustomMaterialRenderable)( + renderableFlags, theModelCenter, m_Renderer, theSubset, theMaterial, + theModelContext, subsetOpacity, firstImage, theGeneratedKey); + } + if (theRenderableObject) { + theRenderableObject->m_ScopedLights = inScopedLights; + // set tessellation + theRenderableObject->m_TessellationMode = inModel.m_TessellationMode; + + if (theRenderableObject->m_RenderableFlags.HasTransparency() + || theRenderableObject->m_RenderableFlags.HasRefraction()) { + m_TransparentObjects.push_back(theRenderableObject); + } else { + m_OpaqueObjects.push_back(theRenderableObject); + } + } + } + } + return subsetDirty; + } + + bool SLayerRenderPreparationData::PrepareRenderablesForRender( + const QT3DSMat44 &inViewProjection, const Option &inClipFrustum, + QT3DSF32 inTextScaleFactor, SLayerRenderPreparationResultFlags &ioFlags) + { + SStackPerfTimer __timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), + "SLayerRenderData::PrepareRenderablesForRender"); + m_ViewProjection = inViewProjection; + QT3DSF32 theTextScaleFactor = inTextScaleFactor; + bool wasDataDirty = false; + bool hasTextRenderer = m_Renderer.GetQt3DSContext().GetTextRenderer() != NULL; + for (QT3DSU32 idx = 0, end = m_RenderableNodes.size(); idx < end; ++idx) { + SRenderableNodeEntry &theNodeEntry(m_RenderableNodes[idx]); + SNode *theNode = theNodeEntry.m_Node; + wasDataDirty = wasDataDirty || theNode->m_Flags.IsDirty(); + switch (theNode->m_Type) { + case GraphObjectTypes::Model: { + SModel *theModel = static_cast(theNode); + theModel->CalculateGlobalVariables(); + if (theModel->m_Flags.IsGloballyActive()) { + bool wasModelDirty = PrepareModelForRender( + *theModel, inViewProjection, inClipFrustum, theNodeEntry.m_Lights); + wasDataDirty = wasDataDirty || wasModelDirty; + } + } break; + case GraphObjectTypes::Text: { + if (hasTextRenderer) { + SText *theText = static_cast(theNode); + theText->CalculateGlobalVariables(); + if (theText->m_Flags.IsGloballyActive()) { + bool wasTextDirty = PrepareTextForRender(*theText, inViewProjection, + theTextScaleFactor, ioFlags); + wasDataDirty = wasDataDirty || wasTextDirty; + } + } + } break; + case GraphObjectTypes::Path: { + SPath *thePath = static_cast(theNode); + thePath->CalculateGlobalVariables(); + if (thePath->m_Flags.IsGloballyActive()) { + bool wasPathDirty = + PreparePathForRender(*thePath, inViewProjection, inClipFrustum, ioFlags); + wasDataDirty = wasDataDirty || wasPathDirty; + } + } break; + default: + QT3DS_ASSERT(false); + break; + } + } + return wasDataDirty; + } + + bool SLayerRenderPreparationData::CheckLightProbeDirty(SImage &inLightProbe) + { + IQt3DSRenderContext &theContext(m_Renderer.GetQt3DSContext()); + return inLightProbe.ClearDirty(theContext.GetBufferManager(), + theContext.GetOffscreenRenderManager(), + theContext.GetRenderPluginManager(), true); + } + + struct SLightNodeMarker + { + SLight *m_Light; + QT3DSU32 m_LightIndex; + QT3DSU32 m_FirstValidIndex; + QT3DSU32 m_JustPastLastValidIndex; + bool m_AddOrRemove; + SLightNodeMarker() + : m_Light(NULL) + , m_FirstValidIndex(0) + , m_JustPastLastValidIndex(0) + , m_AddOrRemove(false) + { + } + SLightNodeMarker(SLight &inLight, QT3DSU32 inLightIndex, SNode &inNode, bool aorm) + : m_Light(&inLight) + , m_LightIndex(inLightIndex) + , m_AddOrRemove(aorm) + { + if (inNode.m_Type == GraphObjectTypes::Layer) { + m_FirstValidIndex = 0; + m_JustPastLastValidIndex = QT3DS_MAX_U32; + } else { + m_FirstValidIndex = inNode.m_DFSIndex; + SNode *lastChild = NULL; + SNode *firstChild = inNode.m_FirstChild; + // find deepest last child + while (firstChild) { + for (SNode *childNode = firstChild; childNode; + childNode = childNode->m_NextSibling) + lastChild = childNode; + + if (lastChild) + firstChild = lastChild->m_FirstChild; + else + firstChild = NULL; + } + if (lastChild) + // last valid index would be the last child index + 1 + m_JustPastLastValidIndex = lastChild->m_DFSIndex + 1; + else // no children. + m_JustPastLastValidIndex = m_FirstValidIndex + 1; + } + } + }; + + // m_Layer.m_Camera->CalculateViewProjectionMatrix(m_ViewProjection); + void + SLayerRenderPreparationData::PrepareForRender(const QSize &inViewportDimensions) + { + SStackPerfTimer __timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), + "SLayerRenderData::PrepareForRender"); + if (m_LayerPrepResult.hasValue()) + return; + + m_Features.clear(); + m_FeatureSetHash = 0; + QT3DSVec2 thePresentationDimensions((QT3DSF32)inViewportDimensions.width(), + (QT3DSF32)inViewportDimensions.height()); + IRenderList &theGraph(m_Renderer.GetQt3DSContext().GetRenderList()); + NVRenderRect theViewport(theGraph.GetViewport()); + NVRenderRect theScissor(theGraph.GetViewport()); + if (theGraph.IsScissorTestEnabled()) + theScissor = m_Renderer.GetContext().GetScissorRect(); + bool wasDirty = false; + bool wasDataDirty = false; + wasDirty = m_Layer.m_Flags.IsDirty(); + // The first pass is just to render the data. + QT3DSU32 maxNumAAPasses = m_Layer.m_ProgressiveAAMode == AAModeValues::NoAA + ? (QT3DSU32)0 + : (QT3DSU32)(m_Layer.m_ProgressiveAAMode) + 1; + maxNumAAPasses = NVMin((QT3DSU32)(MAX_AA_LEVELS + 1), maxNumAAPasses); + SEffect *theLastEffect = NULL; + // Uncomment the line below to disable all progressive AA. + // maxNumAAPasses = 0; + + SLayerRenderPreparationResult thePrepResult; + bool hasOffscreenRenderer = GetOffscreenRenderer(); + + bool SSAOEnabled = (m_Layer.m_AoStrength > 0.0f && m_Layer.m_AoDistance > 0.0f); + bool SSDOEnabled = (m_Layer.m_ShadowStrength > 0.0f && m_Layer.m_ShadowDist > 0.0f); + SetShaderFeature("QT3DS_ENABLE_SSAO", SSAOEnabled); + SetShaderFeature("QT3DS_ENABLE_SSDO", SSDOEnabled); + bool requiresDepthPrepass = (hasOffscreenRenderer == false) && (SSAOEnabled || SSDOEnabled); + SetShaderFeature("QT3DS_ENABLE_SSM", false); // by default no shadow map generation + + if (m_Layer.m_Flags.IsActive()) { + // Get the layer's width and height. + IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); + for (SEffect *theEffect = m_Layer.m_FirstEffect; theEffect; + theEffect = theEffect->m_NextEffect) { + if (theEffect->m_Flags.IsDirty()) { + wasDirty = true; + theEffect->m_Flags.SetDirty(false); + } + if (theEffect->m_Flags.IsActive()) { + theLastEffect = theEffect; + if (hasOffscreenRenderer == false + && theEffectSystem.DoesEffectRequireDepthTexture(theEffect->m_ClassName)) + requiresDepthPrepass = true; + } + } + if (m_Layer.m_Flags.IsDirty()) { + wasDirty = true; + m_Layer.CalculateGlobalVariables(); + } + + bool shouldRenderToTexture = true; + + if (hasOffscreenRenderer) { + // We don't render to texture with offscreen renderers, we just render them to the + // viewport. + shouldRenderToTexture = false; + // Progaa disabled when using offscreen rendering. + maxNumAAPasses = 0; + } + + thePrepResult = SLayerRenderPreparationResult(SLayerRenderHelper( + theViewport, theScissor, m_Layer.m_Scene->m_Presentation->m_PresentationDimensions, + m_Layer, shouldRenderToTexture, m_Renderer.GetQt3DSContext().GetScaleMode(), + m_Renderer.GetQt3DSContext().GetPresentationScaleFactor())); + thePrepResult.m_LastEffect = theLastEffect; + thePrepResult.m_MaxAAPassIndex = maxNumAAPasses; + thePrepResult.m_Flags.SetRequiresDepthTexture(requiresDepthPrepass + || NeedsWidgetTexture()); + thePrepResult.m_Flags.SetShouldRenderToTexture(shouldRenderToTexture); + if (m_Renderer.GetContext().GetRenderContextType() != NVRenderContextValues::GLES2) + thePrepResult.m_Flags.SetRequiresSsaoPass(SSAOEnabled); + + if (thePrepResult.IsLayerVisible()) { + if (shouldRenderToTexture) { + m_Renderer.GetQt3DSContext().GetRenderList().AddRenderTask( + CreateRenderToTextureRunnable()); + } + if (m_Layer.m_LightProbe && CheckLightProbeDirty(*m_Layer.m_LightProbe)) { + m_Renderer.PrepareImageForIbl(*m_Layer.m_LightProbe); + wasDataDirty = true; + } + + bool lightProbeValid = HasValidLightProbe(m_Layer.m_LightProbe); + + SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", lightProbeValid); + SetShaderFeature("QT3DS_ENABLE_IBL_FOV", m_Layer.m_ProbeFov < 180.0f); + + if (lightProbeValid && m_Layer.m_LightProbe2 + && CheckLightProbeDirty(*m_Layer.m_LightProbe2)) { + m_Renderer.PrepareImageForIbl(*m_Layer.m_LightProbe2); + wasDataDirty = true; + } + + SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE_2", + lightProbeValid && HasValidLightProbe(m_Layer.m_LightProbe2)); + + // Push nodes in reverse depth first order + if (m_RenderableNodes.empty()) { + m_CamerasAndLights.clear(); + QT3DSU32 dfsIndex = 0; + for (SNode *theChild = m_Layer.m_FirstChild; theChild; + theChild = theChild->m_NextSibling) + MaybeQueueNodeForRender(*theChild, m_RenderableNodes, m_CamerasAndLights, + dfsIndex); + reverse(m_CamerasAndLights.begin(), m_CamerasAndLights.end()); + reverse(m_RenderableNodes.begin(), m_RenderableNodes.end()); + m_LightToNodeMap.clear(); + } + m_Camera = NULL; + m_Lights.clear(); + m_OpaqueObjects.clear(); + m_TransparentObjects.clear(); + nvvector theLightNodeMarkers(m_Renderer.GetPerFrameAllocator(), + "LightNodeMarkers"); + m_SourceLightDirections.clear(); + + for (QT3DSU32 idx = 0, end = m_CamerasAndLights.size(); idx < end; ++idx) { + SNode *theNode(m_CamerasAndLights[idx]); + wasDataDirty = wasDataDirty || theNode->m_Flags.IsDirty(); + switch (theNode->m_Type) { + case GraphObjectTypes::Camera: { + SCamera *theCamera = static_cast(theNode); + SCameraGlobalCalculationResult theResult = + thePrepResult.SetupCameraForRender(*theCamera); + wasDataDirty = wasDataDirty || theResult.m_WasDirty; + if (theCamera->m_Flags.IsGloballyActive()) + m_Camera = theCamera; + if (theResult.m_ComputeFrustumSucceeded == false) { + qCCritical(INTERNAL_ERROR, "Failed to calculate camera frustum"); + } + } break; + case GraphObjectTypes::Light: { + SLight *theLight = static_cast(theNode); + bool lightResult = theLight->CalculateGlobalVariables(); + wasDataDirty = lightResult || wasDataDirty; + // Note we setup the light index such that it is completely invariant of if + // the + // light is active or scoped. + QT3DSU32 lightIndex = (QT3DSU32)m_SourceLightDirections.size(); + m_SourceLightDirections.push_back(QT3DSVec3(0.0f)); + // Note we still need a light check when building the renderable light list. + // We also cannot cache shader-light bindings based on layers any more + // because + // the number of lights for a given renderable does not depend on the layer + // as it used to but + // additional perhaps on the light's scoping rules. + if (theLight->m_Flags.IsGloballyActive()) { + if (theLight->m_Scope == NULL) { + m_Lights.push_back(theLight); + if (m_Renderer.GetContext().GetRenderContextType() + != NVRenderContextValues::GLES2 + && theLight->m_CastShadow && GetShadowMapManager()) { + // PKC -- use of "res" as an exponent of two is an annoying + // artifact of the XML interface + // I'll change this with an enum interface later on, but that's + // less important right now. + QT3DSU32 mapSize = 1 << theLight->m_ShadowMapRes; + ShadowMapModes::Enum mapMode = + (theLight->m_LightType != RenderLightTypes::Directional) + ? ShadowMapModes::CUBE + : ShadowMapModes::VSM; + m_ShadowMapManager->AddShadowMapEntry( + m_Lights.size() - 1, mapSize, mapSize, + NVRenderTextureFormats::R16F, 1, mapMode, + ShadowFilterValues::NONE); + thePrepResult.m_Flags.SetRequiresShadowMapPass(true); + SetShaderFeature("QT3DS_ENABLE_SSM", true); + } + } + TLightToNodeMap::iterator iter = + m_LightToNodeMap.insert(eastl::make_pair(theLight, (SNode *)NULL)) + .first; + SNode *oldLightScope = iter->second; + SNode *newLightScope = theLight->m_Scope; + + if (oldLightScope != newLightScope) { + iter->second = newLightScope; + if (oldLightScope) + theLightNodeMarkers.push_back(SLightNodeMarker( + *theLight, lightIndex, *oldLightScope, false)); + if (newLightScope) + theLightNodeMarkers.push_back(SLightNodeMarker( + *theLight, lightIndex, *newLightScope, true)); + } + if (newLightScope) { + m_SourceLightDirections.back() = + theLight->GetScalingCorrectDirection(); + } + } + } break; + default: + QT3DS_ASSERT(false); + break; + } + } + + if (theLightNodeMarkers.empty() == false) { + for (QT3DSU32 idx = 0, end = m_RenderableNodes.size(); idx < end; ++idx) { + SRenderableNodeEntry &theNodeEntry(m_RenderableNodes[idx]); + QT3DSU32 nodeDFSIndex = theNodeEntry.m_Node->m_DFSIndex; + for (QT3DSU32 markerIdx = 0, markerEnd = theLightNodeMarkers.size(); + markerIdx < markerEnd; ++markerIdx) { + SLightNodeMarker &theMarker = theLightNodeMarkers[markerIdx]; + if (nodeDFSIndex >= theMarker.m_FirstValidIndex + && nodeDFSIndex < theMarker.m_JustPastLastValidIndex) { + if (theMarker.m_AddOrRemove) { + SNodeLightEntry *theNewEntry = + m_RenderableNodeLightEntryPool.construct( + theMarker.m_Light, theMarker.m_LightIndex, __FILE__, + __LINE__); + theNodeEntry.m_Lights.push_back(*theNewEntry); + } else { + for (TNodeLightEntryList::iterator + lightIter = theNodeEntry.m_Lights.begin(), + lightEnd = theNodeEntry.m_Lights.end(); + lightIter != lightEnd; ++lightIter) { + if (lightIter->m_Light == theMarker.m_Light) { + SNodeLightEntry &theEntry = *lightIter; + theNodeEntry.m_Lights.remove(theEntry); + m_RenderableNodeLightEntryPool.deallocate(&theEntry); + break; + } + } + } + } + } + } + } + + QT3DSF32 theTextScaleFactor = 1.0f; + if (m_Camera) { + m_Camera->CalculateViewProjectionMatrix(m_ViewProjection); + theTextScaleFactor = m_Camera->GetTextScaleFactor( + thePrepResult.GetLayerToPresentationViewport(), + thePrepResult.GetPresentationDesignDimensions()); + SClipPlane nearPlane; + QT3DSMat33 theUpper33(m_Camera->m_GlobalTransform.getUpper3x3InverseTranspose()); + + QT3DSVec3 dir(theUpper33.transform(QT3DSVec3(0, 0, -1))); + dir.normalize(); + nearPlane.normal = dir; + QT3DSVec3 theGlobalPos = m_Camera->GetGlobalPos() + m_Camera->m_ClipNear * dir; + nearPlane.d = -(dir.dot(theGlobalPos)); + // the near plane's bbox edges are calculated in the clipping frustum's + // constructor. + m_ClippingFrustum = SClippingFrustum(m_ViewProjection, nearPlane); + } else + m_ViewProjection = QT3DSMat44::createIdentity(); + + // Setup the light directions here. + + for (QT3DSU32 lightIdx = 0, lightEnd = m_Lights.size(); lightIdx < lightEnd; + ++lightIdx) { + m_LightDirections.push_back(m_Lights[lightIdx]->GetScalingCorrectDirection()); + } + + m_ModelContexts.clear(); + if (GetOffscreenRenderer() == false) { + bool renderablesDirty = + PrepareRenderablesForRender(m_ViewProjection, m_ClippingFrustum, + theTextScaleFactor, thePrepResult.m_Flags); + wasDataDirty = wasDataDirty || renderablesDirty; + if (thePrepResult.m_Flags.RequiresStencilBuffer()) + thePrepResult.m_Flags.SetShouldRenderToTexture(true); + } else { + NVRenderRect theViewport = + thePrepResult.GetLayerToPresentationViewport().ToIntegerRect(); + bool theScissor = true; + NVRenderRect theScissorRect = + thePrepResult.GetLayerToPresentationScissorRect().ToIntegerRect(); + // This happens here because if there are any fancy render steps + IRenderList &theRenderList(m_Renderer.GetQt3DSContext().GetRenderList()); + NVRenderContext &theContext(m_Renderer.GetContext()); + SRenderListScopedProperty _listScissorEnabled( + theRenderList, &IRenderList::IsScissorTestEnabled, + &IRenderList::SetScissorTestEnabled, theScissor); + SRenderListScopedProperty _listViewport( + theRenderList, &IRenderList::GetViewport, &IRenderList::SetViewport, + theViewport); + SRenderListScopedProperty _listScissor( + theRenderList, &IRenderList::GetScissor, &IRenderList::SetScissorRect, + theScissorRect); + // Some plugins don't use the render list so they need the actual gl context + // setup. + qt3ds::render::NVRenderContextScopedProperty __scissorEnabled( + theContext, &NVRenderContext::IsScissorTestEnabled, + &NVRenderContext::SetScissorTestEnabled, true); + qt3ds::render::NVRenderContextScopedProperty __scissorRect( + theContext, &NVRenderContext::GetScissorRect, + &NVRenderContext::SetScissorRect, theScissorRect); + qt3ds::render::NVRenderContextScopedProperty __viewportRect( + theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, + theViewport); + SOffscreenRenderFlags theResult = m_LastFrameOffscreenRenderer->NeedsRender( + CreateOffscreenRenderEnvironment(), + m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), &m_Layer); + wasDataDirty = wasDataDirty || theResult.m_HasChangedSinceLastFrame; + } + } + } + wasDirty = wasDirty || wasDataDirty; + thePrepResult.m_Flags.SetWasDirty(wasDirty); + thePrepResult.m_Flags.SetLayerDataDirty(wasDataDirty); + + m_LayerPrepResult = thePrepResult; + + // Per-frame cache of renderable objects post-sort. + GetOpaqueRenderableObjects(); + // If layer depth test is false, this may also contain opaque objects. + GetTransparentRenderableObjects(); + + GetCameraDirection(); + } + + void SLayerRenderPreparationData::ResetForFrame() + { + m_TransparentObjects.clear_unsafe(); + m_OpaqueObjects.clear_unsafe(); + m_LayerPrepResult.setEmpty(); + // The check for if the camera is or is not null is used + // to figure out if this layer was rendered at all. + m_Camera = NULL; + m_LastFrameOffscreenRenderer = NULL; + m_IRenderWidgets.clear_unsafe(); + m_CameraDirection.setEmpty(); + m_LightDirections.clear_unsafe(); + m_RenderedOpaqueObjects.clear_unsafe(); + m_RenderedTransparentObjects.clear_unsafe(); + } +} +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h new file mode 100644 index 00000000..5b8d6e10 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h @@ -0,0 +1,367 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDERER_IMPL_LAYER_RENDER_PREPARATION_DATA_H +#define QT3DS_RENDERER_IMPL_LAYER_RENDER_PREPARATION_DATA_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSFlags.h" +#include "Qt3DSRendererImplLayerRenderHelper.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderableObjects.h" +#include "Qt3DSRenderClippingFrustum.h" +#include "Qt3DSRenderResourceTexture2D.h" +#include "Qt3DSOffscreenRenderManager.h" +#include "Qt3DSRenderProfiler.h" +#include "Qt3DSRenderShadowMap.h" +#include "foundation/Qt3DSPool.h" +#include "Qt3DSRenderableObjects.h" + +namespace qt3ds { +namespace render { + struct SLayerRenderData; + class Qt3DSRendererImpl; + struct SRenderableObject; + + struct LayerRenderPreparationResultFlagValues + { + enum Enum { + // Was the data in this layer dirty (meaning re-render to texture, possibly) + WasLayerDataDirty = 1, + // Was the data in this layer dirty *or* this layer *or* any effect dirty. + WasDirty = 1 << 1, + // An effect or flag or rotation on the layer dictates this object should + // render to the texture. + ShouldRenderToTexture = 1 << 2, + // Some effects require depth texturing, this should be set on the effect + // instance. + RequiresDepthTexture = 1 << 3, + + // Should create independent viewport + // If we aren't rendering to texture we still may have width/height manipulations + // that require our own viewport. + ShouldCreateIndependentViewport = 1 << 4, + + // SSAO should be done in a separate pass + // Note that having an AO pass necessitates a DepthTexture so this flag should + // never be set without the RequiresDepthTexture flag as well. + RequiresSsaoPass = 1 << 5, + + // if some light cause shadow + // we need a separate per light shadow map pass + RequiresShadowMapPass = 1 << 6, + + // Currently we use a stencil-cover algorithm to render bezier curves. + RequiresStencilBuffer = 1 << 7 + }; + }; + + struct SLayerRenderPreparationResultFlags + : public NVFlags + { + bool WasLayerDataDirty() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::WasLayerDataDirty); + } + void SetLayerDataDirty(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::WasLayerDataDirty); + } + + bool WasDirty() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::WasDirty); + } + void SetWasDirty(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::WasDirty); + } + + bool ShouldRenderToTexture() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::ShouldRenderToTexture); + } + void SetShouldRenderToTexture(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::ShouldRenderToTexture); + } + + bool RequiresDepthTexture() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::RequiresDepthTexture); + } + void SetRequiresDepthTexture(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresDepthTexture); + } + + bool ShouldCreateIndependentViewport() const + { + return this->operator&( + LayerRenderPreparationResultFlagValues::ShouldCreateIndependentViewport); + } + void SetShouldCreateIndependentViewport(bool inValue) + { + clearOrSet(inValue, + LayerRenderPreparationResultFlagValues::ShouldCreateIndependentViewport); + } + + bool RequiresSsaoPass() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::RequiresSsaoPass); + } + void SetRequiresSsaoPass(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresSsaoPass); + } + + bool RequiresShadowMapPass() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::RequiresShadowMapPass); + } + void SetRequiresShadowMapPass(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresShadowMapPass); + } + + bool RequiresStencilBuffer() const + { + return this->operator&(LayerRenderPreparationResultFlagValues::RequiresStencilBuffer); + } + void SetRequiresStencilBuffer(bool inValue) + { + clearOrSet(inValue, LayerRenderPreparationResultFlagValues::RequiresStencilBuffer); + } + }; + + struct SLayerRenderPreparationResult : public SLayerRenderHelper + { + SEffect *m_LastEffect; + SLayerRenderPreparationResultFlags m_Flags; + QT3DSU32 m_MaxAAPassIndex; + SLayerRenderPreparationResult() + : m_LastEffect(NULL) + , m_MaxAAPassIndex(0) + { + } + SLayerRenderPreparationResult(const SLayerRenderHelper &inHelper) + : SLayerRenderHelper(inHelper) + , m_LastEffect(NULL) + , m_MaxAAPassIndex(0) + { + } + }; + + struct SRenderableNodeEntry + { + SNode *m_Node; + TNodeLightEntryList m_Lights; + SRenderableNodeEntry() + : m_Node(NULL) + { + } + SRenderableNodeEntry(SNode &inNode) + : m_Node(&inNode) + { + } + }; + + struct SScopedLightsListScope + { + nvvector &m_LightsList; + nvvector &m_LightDirList; + QT3DSU32 m_ListOriginalSize; + SScopedLightsListScope(nvvector &inLights, nvvector &inDestLightDirList, + nvvector &inSrcLightDirList, + TNodeLightEntryList &inScopedLights) + : m_LightsList(inLights) + , m_LightDirList(inDestLightDirList) + , m_ListOriginalSize(m_LightsList.size()) + { + for (TNodeLightEntryList::iterator iter = inScopedLights.begin(), + end = inScopedLights.end(); + iter != end; ++iter) { + m_LightsList.push_back(iter->m_Light); + m_LightDirList.push_back(inSrcLightDirList[iter->m_LightIndex]); + } + } + ~SScopedLightsListScope() + { + m_LightsList.resize(m_ListOriginalSize); + m_LightDirList.resize(m_ListOriginalSize); + } + }; + + struct SDefaultMaterialPreparationResult + { + SRenderableImage *m_FirstImage; + QT3DSF32 m_Opacity; + SRenderableObjectFlags m_RenderableFlags; + SShaderDefaultMaterialKey m_MaterialKey; + bool m_Dirty; + + SDefaultMaterialPreparationResult(SShaderDefaultMaterialKey inMaterialKey); + }; + + // Data used strictly in the render preparation step. + struct SLayerRenderPreparationData + { + typedef void (*TRenderRenderableFunction)(SLayerRenderData &inData, + SRenderableObject &inObject, + const QT3DSVec2 &inCameraProps, + TShaderFeatureSet inShaderFeatures, + QT3DSU32 lightIndex, const SCamera &inCamera); + typedef nvhash_map TLightToNodeMap; + typedef Pool TNodeLightEntryPoolType; + + enum Enum { + MAX_AA_LEVELS = 8, + MAX_TEMPORAL_AA_LEVELS = 2, + }; + + SLayer &m_Layer; + Qt3DSRendererImpl &m_Renderer; + NVAllocatorCallback &m_Allocator; + // List of nodes we can render, not all may be active. Found by doing a depth-first + // search through m_FirstChild if length is zero. + + TNodeLightEntryPoolType m_RenderableNodeLightEntryPool; + nvvector m_RenderableNodes; + TLightToNodeMap m_LightToNodeMap; // map of lights to nodes to cache if we have looked up a + // given scoped light yet. + // Built at the same time as the renderable nodes map. + // these are processed so they are available when the shaders for the models + // are being generated. + nvvector m_CamerasAndLights; + + // Results of prepare for render. + SCamera *m_Camera; + nvvector m_Lights; // Only contains lights that are global. + TRenderableObjectList m_OpaqueObjects; + TRenderableObjectList m_TransparentObjects; + // Sorted lists of the rendered objects. There may be other transforms applied so + // it is simplest to duplicate the lists. + TRenderableObjectList m_RenderedOpaqueObjects; + TRenderableObjectList m_RenderedTransparentObjects; + QT3DSMat44 m_ViewProjection; + SClippingFrustum m_ClippingFrustum; + Option m_LayerPrepResult; + // Widgets drawn at particular times during the rendering process + nvvector m_IRenderWidgets; + Option m_CameraDirection; + // Scoped lights need a level of indirection into a light direction list. The source light + // directions list is as long as there are lights on the layer. It holds invalid + // information for + // any lights that are not both active and scoped; but the relative position for a given + // light + // in this list is completely constant and immutable; this relative position is saved on a + // structure + // and used when looking up the light direction for a given light. + nvvector m_SourceLightDirections; + nvvector m_LightDirections; + TModelContextPtrList m_ModelContexts; + NVScopedRefCounted m_LastFrameOffscreenRenderer; + + eastl::vector m_Features; + CRegisteredString m_CGLightingFeatureName; + bool m_FeaturesDirty; + size_t m_FeatureSetHash; + bool m_TooManyLightsError; + + // shadow mapps + NVScopedRefCounted m_ShadowMapManager; + + SLayerRenderPreparationData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer); + virtual ~SLayerRenderPreparationData(); + bool GetOffscreenRenderer(); + bool GetShadowMapManager(); + bool NeedsWidgetTexture() const; + + SShaderDefaultMaterialKey GenerateLightingKey(DefaultMaterialLighting::Enum inLightingType); + + void PrepareImageForRender(SImage &inImage, ImageMapTypes::Enum inMapType, + SRenderableImage *&ioFirstImage, SRenderableImage *&ioNextImage, + SRenderableObjectFlags &ioFlags, + SShaderDefaultMaterialKey &ioGeneratedShaderKey, + QT3DSU32 inImageIndex); + + SDefaultMaterialPreparationResult + PrepareDefaultMaterialForRender(SDefaultMaterial &inMaterial, + SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity, + bool inClearMaterialFlags); + + SDefaultMaterialPreparationResult + PrepareCustomMaterialForRender(SCustomMaterial &inMaterial, + SRenderableObjectFlags &inExistingFlags, QT3DSF32 inOpacity); + + bool PrepareModelForRender(SModel &inModel, const QT3DSMat44 &inViewProjection, + const Option &inClipFrustum, + TNodeLightEntryList &inScopedLights); + + bool PrepareTextForRender(SText &inText, const QT3DSMat44 &inViewProjection, + QT3DSF32 inTextScaleFactor, + SLayerRenderPreparationResultFlags &ioFlags); + bool PreparePathForRender(SPath &inPath, const QT3DSMat44 &inViewProjection, + const Option &inClipFrustum, + SLayerRenderPreparationResultFlags &ioFlags); + // Helper function used during PRepareForRender and PrepareAndRender + bool PrepareRenderablesForRender(const QT3DSMat44 &inViewProjection, + const Option &inClipFrustum, + QT3DSF32 inTextScaleFactor, + SLayerRenderPreparationResultFlags &ioFlags); + + // returns true if this object will render something different than it rendered the last + // time. + virtual void PrepareForRender(const QSize &inViewportDimensions); + bool CheckLightProbeDirty(SImage &inLightProbe); + void AddRenderWidget(IRenderWidget &inWidget); + void SetShaderFeature(const char *inName, bool inValue); + void SetShaderFeature(CRegisteredString inName, bool inValue); + NVConstDataRef GetShaderFeatureSet(); + size_t GetShaderFeatureSetHash(); + // The graph object is not const because this traversal updates dirty state on the objects. + eastl::pair ResolveReferenceMaterial(SGraphObject *inMaterial); + + QT3DSVec3 GetCameraDirection(); + // Per-frame cache of renderable objects post-sort. + NVDataRef GetOpaqueRenderableObjects(); + // If layer depth test is false, this may also contain opaque objects. + NVDataRef GetTransparentRenderableObjects(); + + virtual void ResetForFrame(); + + // The render list and gl context are setup for what the embedded item will + // need. + virtual SOffscreenRendererEnvironment CreateOffscreenRenderEnvironment() = 0; + + virtual IRenderTask &CreateRenderToTextureRunnable() = 0; + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.cpp new file mode 100644 index 00000000..50620f88 --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.cpp @@ -0,0 +1,2999 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRendererImpl.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSRenderLight.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderShaderCache.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "Qt3DSRenderShaderCodeGeneratorV2.h" +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include "Qt3DSVertexPipelineImpl.h" + +// This adds support for the depth buffers in the shader so we can do depth +// texture-based effects. +#define QT3DS_RENDER_SUPPORT_DEPTH_TEXTURE 1 + +namespace qt3ds { +namespace render { + + void STextShader::Render(NVRenderTexture2D &inTexture, + const STextScaleAndOffset &inScaleAndOffset, const QT3DSVec4 &inTextColor, + const QT3DSMat44 &inMVP, const QT3DSVec2 &inCameraVec, + NVRenderContext &inRenderContext, + NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, + const STextTextureDetails &inTextTextureDetails, + const QT3DSVec3 &inBackgroundColor) + { + inRenderContext.SetCullingEnabled(false); + inRenderContext.SetActiveShader(&m_Shader); + m_MVP.Set(inMVP); + m_Sampler.Set(&inTexture); + m_TextColor.Set(inTextColor); + m_Dimensions.Set(QT3DSVec4(inScaleAndOffset.m_TextScale.x, inScaleAndOffset.m_TextScale.y, + inScaleAndOffset.m_TextOffset.x, inScaleAndOffset.m_TextOffset.y)); + m_CameraProperties.Set(inCameraVec); + STextureDetails theTextureDetails = inTexture.GetTextureDetails(); + QT3DSF32 theWidthScale = + (QT3DSF32)inTextTextureDetails.m_TextWidth / (QT3DSF32)theTextureDetails.m_Width; + QT3DSF32 theHeightScale = + (QT3DSF32)inTextTextureDetails.m_TextHeight / (QT3DSF32)theTextureDetails.m_Height; + m_BackgroundColor.Set(inBackgroundColor); + + m_TextDimensions.Set( + QT3DSVec3(theWidthScale, theHeightScale, inTextTextureDetails.m_FlipY ? 1.0f : 0.0f)); + inRenderContext.SetInputAssembler(&inInputAssemblerBuffer); + inRenderContext.Draw(NVRenderDrawMode::Triangles, count, 0); + } + + void STextShader::RenderPath(NVRenderPathFontItem &inPathFontItem, + NVRenderPathFontSpecification &inPathFontSpec, + const STextScaleAndOffset &inScaleAndOffset, + const QT3DSVec4 &inTextColor, const QT3DSMat44 &inViewProjection, + const QT3DSMat44 &inModel, const QT3DSVec2 &, + NVRenderContext &inRenderContext, + const STextTextureDetails &inTextTextureDetails, + const QT3DSVec3 &inBackgroundColor) + { + qt3ds::render::NVRenderBoolOp::Enum theDepthFunction = inRenderContext.GetDepthFunction(); + bool isDepthEnabled = inRenderContext.IsDepthTestEnabled(); + bool isStencilEnabled = inRenderContext.IsStencilTestEnabled(); + bool isDepthWriteEnabled = inRenderContext.IsDepthWriteEnabled(); + qt3ds::render::NVRenderStencilFunctionArgument theArg(qt3ds::render::NVRenderBoolOp::NotEqual, 0, + 0xFF); + qt3ds::render::NVRenderStencilOperationArgument theOpArg(qt3ds::render::NVRenderStencilOp::Keep, + qt3ds::render::NVRenderStencilOp::Keep, + qt3ds::render::NVRenderStencilOp::Zero); + NVScopedRefCounted depthStencilState = + inRenderContext.CreateDepthStencilState(isDepthEnabled, isDepthWriteEnabled, + theDepthFunction, false, theArg, theArg, + theOpArg, theOpArg); + + inRenderContext.SetActiveShader(NULL); + inRenderContext.SetCullingEnabled(false); + + inRenderContext.SetDepthStencilState(depthStencilState); + + // setup transform + QT3DSMat44 offsetMatrix = QT3DSMat44::createIdentity(); + offsetMatrix.setPosition(QT3DSVec3( + inScaleAndOffset.m_TextOffset.x - (QT3DSF32)inTextTextureDetails.m_TextWidth / 2.0f, + inScaleAndOffset.m_TextOffset.y - (QT3DSF32)inTextTextureDetails.m_TextHeight / 2.0f, + 0.0)); + + QT3DSMat44 pathMatrix = inPathFontItem.GetTransform(); + + inRenderContext.SetPathProjectionMatrix(inViewProjection); + inRenderContext.SetPathModelViewMatrix(inModel * offsetMatrix * pathMatrix); + + // first pass + inPathFontSpec.StencilFillPathInstanced(inPathFontItem); + + // second pass + inRenderContext.SetActiveProgramPipeline(m_ProgramPipeline); + m_TextColor.Set(inTextColor); + m_BackgroundColor.Set(inBackgroundColor); + + inRenderContext.SetStencilTestEnabled(true); + inPathFontSpec.CoverFillPathInstanced(inPathFontItem); + + inRenderContext.SetStencilTestEnabled(isStencilEnabled); + inRenderContext.SetDepthFunction(theDepthFunction); + + inRenderContext.SetActiveProgramPipeline(NULL); + } + + void STextShader::Render2D(NVRenderTexture2D &inTexture, const QT3DSVec4 &inTextColor, + const QT3DSMat44 &inMVP, NVRenderContext &inRenderContext, + NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, + QT3DSVec2 inVertexOffsets) + { + // inRenderContext.SetCullingEnabled( false ); + inRenderContext.SetBlendingEnabled(true); + inRenderContext.SetDepthWriteEnabled(false); + inRenderContext.SetDepthTestEnabled(false); + + inRenderContext.SetActiveShader(&m_Shader); + + qt3ds::render::NVRenderBlendFunctionArgument blendFunc( + NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, + NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); + qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add, + NVRenderBlendEquation::Add); + + inRenderContext.SetBlendFunction(blendFunc); + inRenderContext.SetBlendEquation(blendEqu); + + m_MVP.Set(inMVP); + m_Sampler.Set(&inTexture); + m_TextColor.Set(inTextColor); + m_VertexOffsets.Set(inVertexOffsets); + + inRenderContext.SetInputAssembler(&inInputAssemblerBuffer); + inRenderContext.Draw(NVRenderDrawMode::Triangles, count, 0); + } + + using eastl::make_pair; + + static inline void AddVertexDepth(SShaderVertexCodeGenerator &vertexShader) + { + // near plane, far plane + vertexShader.AddInclude("viewProperties.glsllib"); + vertexShader.AddVarying("vertex_depth", "float"); + // the w coordinate is the unormalized distance to the object from the camera + // We want the normalized distance, with 0 representing the far plane and 1 representing + // the near plane, of the object in the vertex depth variable. + + vertexShader << "\tvertex_depth = calculateVertexDepth( camera_properties, gl_Position );" + << Endl; + } + + // Helper implements the vertex pipeline for mesh subsets when bound to the default material. + // Should be completely possible to use for custom materials with a bit of refactoring. + struct SSubsetMaterialVertexPipeline : public SVertexPipelineImpl + { + Qt3DSRendererImpl &m_Renderer; + SSubsetRenderable &m_Renderable; + TessModeValues::Enum m_TessMode; + + SSubsetMaterialVertexPipeline(Qt3DSRendererImpl &renderer, SSubsetRenderable &renderable, + bool inWireframeRequested) + : SVertexPipelineImpl(renderer.GetQt3DSContext().GetAllocator(), + renderer.GetQt3DSContext().GetDefaultMaterialShaderGenerator(), + renderer.GetQt3DSContext().GetShaderProgramGenerator(), + renderer.GetQt3DSContext().GetStringTable(), false) + , m_Renderer(renderer) + , m_Renderable(renderable) + , m_TessMode(TessModeValues::NoTess) + { + if (m_Renderer.GetContext().IsTessellationSupported()) { + m_TessMode = renderable.m_TessellationMode; + } + + if (m_Renderer.GetContext().IsGeometryStageSupported() + && m_TessMode != TessModeValues::NoTess) + m_Wireframe = inWireframeRequested; + } + + void InitializeTessControlShader() + { + if (m_TessMode == TessModeValues::NoTess + || ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl) == NULL) + return; + + IShaderStageGenerator &tessCtrlShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + + SetupTessIncludes(ShaderGeneratorStages::TessControl, m_TessMode); + + tessCtrlShader.Append("void main() {\n"); + + tessCtrlShader.Append("\tctWorldPos[0] = varWorldPos[0];"); + tessCtrlShader.Append("\tctWorldPos[1] = varWorldPos[1];"); + tessCtrlShader.Append("\tctWorldPos[2] = varWorldPos[2];"); + + if (m_TessMode == TessModeValues::TessPhong + || m_TessMode == TessModeValues::TessNPatch) { + tessCtrlShader.Append("\tctNorm[0] = varObjectNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = varObjectNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = varObjectNormal[2];"); + } + if (m_TessMode == TessModeValues::TessNPatch) { + tessCtrlShader.Append("\tctTangent[0] = varTangent[0];"); + tessCtrlShader.Append("\tctTangent[1] = varTangent[1];"); + tessCtrlShader.Append("\tctTangent[2] = varTangent[2];"); + } + + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + } + void InitializeTessEvaluationShader() + { + if (m_TessMode == TessModeValues::NoTess + || ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval) == NULL) + return; + + IShaderStageGenerator &tessEvalShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + SetupTessIncludes(ShaderGeneratorStages::TessEval, m_TessMode); + + if (m_TessMode == TessModeValues::TessLinear) + m_Renderer.GetQt3DSContext() + .GetDefaultMaterialShaderGenerator() + .AddDisplacementImageUniforms(tessEvalShader, m_DisplacementIdx, + m_DisplacementImage); + + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddUniform("normal_matrix", "mat3"); + + tessEvalShader.Append("void main() {"); + + if (m_TessMode == TessModeValues::TessNPatch) { + tessEvalShader.Append("\tctNorm[0] = varObjectNormalTC[0];"); + tessEvalShader.Append("\tctNorm[1] = varObjectNormalTC[1];"); + tessEvalShader.Append("\tctNorm[2] = varObjectNormalTC[2];"); + + tessEvalShader.Append("\tctTangent[0] = varTangentTC[0];"); + tessEvalShader.Append("\tctTangent[1] = varTangentTC[1];"); + tessEvalShader.Append("\tctTangent[2] = varTangentTC[2];"); + } + + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + } + + void FinalizeTessControlShader() + { + IShaderStageGenerator &tessCtrlShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + // add varyings we must pass through + typedef TStrTableStrMap::const_iterator TParamIter; + for (TParamIter iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + tessCtrlShader << "\t" << iter->first.c_str() + << "TC[gl_InvocationID] = " << iter->first.c_str() + << "[gl_InvocationID];\n"; + } + } + + void FinalizeTessEvaluationShader() + { + IShaderStageGenerator &tessEvalShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + eastl::string outExt(""); + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) + outExt = "TE"; + + // add varyings we must pass through + typedef TStrTableStrMap::const_iterator TParamIter; + if (m_TessMode == TessModeValues::TessNPatch) { + for (TParamIter iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() + << " = gl_TessCoord.z * " << iter->first.c_str() << "TC[0] + "; + tessEvalShader << "gl_TessCoord.x * " << iter->first.c_str() << "TC[1] + "; + tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[2];\n"; + } + + // transform the normal + if (m_GenerationFlags & GenerationFlagValues::WorldNormal) + tessEvalShader << "\n\tvarNormal" << outExt.c_str() + << " = normalize(normal_matrix * teNorm);\n"; + // transform the tangent + if (m_GenerationFlags & GenerationFlagValues::TangentBinormal) { + tessEvalShader << "\n\tvarTangent" << outExt.c_str() + << " = normalize(normal_matrix * teTangent);\n"; + // transform the binormal + tessEvalShader << "\n\tvarBinormal" << outExt.c_str() + << " = normalize(normal_matrix * teBinormal);\n"; + } + } else { + for (TParamIter iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str() + << " = gl_TessCoord.x * " << iter->first.c_str() << "TC[0] + "; + tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[1] + "; + tessEvalShader << "gl_TessCoord.z * " << iter->first.c_str() << "TC[2];\n"; + } + + // displacement mapping makes only sense with linear tessellation + if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) { + IDefaultMaterialShaderGenerator::SImageVariableNames theNames = + m_Renderer.GetQt3DSContext() + .GetDefaultMaterialShaderGenerator() + .GetImageVariableNames(m_DisplacementIdx); + tessEvalShader << "\tpos.xyz = defaultMaterialFileDisplacementTexture( " + << theNames.m_ImageSampler << ", displaceAmount, " + << theNames.m_ImageFragCoords << outExt.c_str(); + tessEvalShader << ", varObjectNormal" << outExt.c_str() << ", pos.xyz );" + << Endl; + tessEvalShader << "\tvarWorldPos" << outExt.c_str() + << "= (model_matrix * pos).xyz;" << Endl; + tessEvalShader << "\tvarViewVector" << outExt.c_str() + << "= normalize(camera_position - " + << "varWorldPos" << outExt.c_str() << ");" << Endl; + } + + // transform the normal + tessEvalShader << "\n\tvarNormal" << outExt.c_str() + << " = normalize(normal_matrix * varObjectNormal" << outExt.c_str() + << ");\n"; + } + + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); + } + + void BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) override + { + m_DisplacementIdx = displacementImageIdx; + m_DisplacementImage = displacementImage; + + TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags()); + if (m_TessMode != TessModeValues::NoTess) { + theStages |= ShaderGeneratorStages::TessControl; + theStages |= ShaderGeneratorStages::TessEval; + } + if (m_Wireframe) { + theStages |= ShaderGeneratorStages::Geometry; + } + ProgramGenerator().BeginProgram(theStages); + if (m_TessMode != TessModeValues::NoTess) { + InitializeTessControlShader(); + InitializeTessEvaluationShader(); + } + if (m_Wireframe) { + InitializeWireframeGeometryShader(); + } + // Open up each stage. + IShaderStageGenerator &vertexShader(Vertex()); + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader << "void main()" << Endl << "{" << Endl; + vertexShader << "\tvec3 uTransform;" << Endl; + vertexShader << "\tvec3 vTransform;" << Endl; + + if (displacementImage) { + GenerateUVCoords(); + MaterialGenerator().GenerateImageUVCoordinates(*this, displacementImageIdx, 0, + *displacementImage); + if (!HasTessellation()) { + vertexShader.AddUniform("displaceAmount", "float"); + // we create the world position setup here + // because it will be replaced with the displaced position + SetCode(GenerationFlagValues::WorldPosition); + vertexShader.AddUniform("model_matrix", "mat4"); + + vertexShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + IDefaultMaterialShaderGenerator::SImageVariableNames theVarNames = + MaterialGenerator().GetImageVariableNames(displacementImageIdx); + + vertexShader.AddUniform(theVarNames.m_ImageSampler, "sampler2D"); + + vertexShader + << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " + << theVarNames.m_ImageSampler << ", displaceAmount, " + << theVarNames.m_ImageFragCoords << ", attr_norm, attr_pos );" << Endl; + AddInterpolationParameter("varWorldPos", "vec3"); + vertexShader.Append("\tvec3 local_model_world_position = (model_matrix * " + "vec4(displacedPos, 1.0)).xyz;"); + AssignOutput("varWorldPos", "local_model_world_position"); + } + } + // for tessellation we pass on the position in object coordinates + // Also note that gl_Position is written in the tess eval shader + if (HasTessellation()) + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + else { + vertexShader.AddUniform("model_view_projection", "mat4"); + if (displacementImage) + vertexShader.Append( + "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); + else + vertexShader.Append( + "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + } + + if (HasTessellation()) { + GenerateWorldPosition(); + GenerateWorldNormal(); + GenerateObjectNormal(); + GenerateVarTangentAndBinormal(); + } + } + + void BeginFragmentGeneration() override + { + Fragment().AddUniform("material_diffuse", "vec4"); + Fragment() << "void main()" << Endl << "{" << Endl; + // We do not pass object opacity through the pipeline. + Fragment() << "\tfloat object_opacity = material_diffuse.a;" << Endl; + } + + void AssignOutput(const char8_t *inVarName, const char8_t *inVarValue) override + { + Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n"; + } + void DoGenerateUVCoords(QT3DSU32 inUVSet = 0) override + { + QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); + + if (inUVSet == 0) { + Vertex().AddIncoming("attr_uv0", "vec2"); + Vertex() << "\tvarTexCoord0 = attr_uv0;" << Endl; + } else if (inUVSet == 1) { + Vertex().AddIncoming("attr_uv1", "vec2"); + Vertex() << "\tvarTexCoord1 = attr_uv1;" << Endl; + } + } + + // fragment shader expects varying vertex normal + // lighting in vertex pipeline expects world_normal + void DoGenerateWorldNormal() override + { + IShaderStageGenerator &vertexGenerator(Vertex()); + vertexGenerator.AddIncoming("attr_norm", "vec3"); + vertexGenerator.AddUniform("normal_matrix", "mat3"); + if (HasTessellation() == false) { + vertexGenerator.Append( + "\tvec3 world_normal = normalize(normal_matrix * attr_norm).xyz;"); + vertexGenerator.Append("\tvarNormal = world_normal;"); + } + } + void DoGenerateObjectNormal() override + { + AddInterpolationParameter("varObjectNormal", "vec3"); + Vertex().Append("\tvarObjectNormal = attr_norm;"); + } + void DoGenerateWorldPosition() override + { + Vertex().Append( + "\tvec3 local_model_world_position = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); + AssignOutput("varWorldPos", "local_model_world_position"); + } + + void DoGenerateVarTangentAndBinormal() override + { + Vertex().AddIncoming("attr_textan", "vec3"); + Vertex().AddIncoming("attr_binormal", "vec3"); + + bool hasNPatchTessellation = m_TessMode == TessModeValues::TessNPatch; + + if (!hasNPatchTessellation) { + Vertex() << "\tvarTangent = normal_matrix * attr_textan;" << Endl + << "\tvarBinormal = normal_matrix * attr_binormal;" << Endl; + } else { + Vertex() << "\tvarTangent = attr_textan;" << Endl + << "\tvarBinormal = attr_binormal;" << Endl; + } + } + + void DoGenerateVertexColor() override + { + Vertex().AddIncoming("attr_color", "vec3"); + Vertex().Append("\tvarColor = attr_color;"); + } + + void EndVertexGeneration() override + { + + if (HasTessellation()) { + // finalize tess control shader + FinalizeTessControlShader(); + // finalize tess evaluation shader + FinalizeTessEvaluationShader(); + + TessControl().Append("}"); + TessEval().Append("}"); + } + if (m_Wireframe) { + // finalize geometry shader + FinalizeWireframeGeometryShader(); + Geometry().Append("}"); + } + Vertex().Append("}"); + } + + void EndFragmentGeneration() override { Fragment().Append("}"); } + + void AddInterpolationParameter(const char8_t *inName, const char8_t *inType) override + { + m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType))); + Vertex().AddOutgoing(inName, inType); + Fragment().AddIncoming(inName, inType); + if (HasTessellation()) { + eastl::string nameBuilder(inName); + nameBuilder.append("TC"); + TessControl().AddOutgoing(nameBuilder.c_str(), inType); + + nameBuilder.assign(inName); + if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) { + nameBuilder.append("TE"); + Geometry().AddOutgoing(inName, inType); + } + TessEval().AddOutgoing(nameBuilder.c_str(), inType); + } + } + + IShaderStageGenerator &ActiveStage() override { return Vertex(); } + }; + + NVRenderShaderProgram *Qt3DSRendererImpl::GenerateShader(SSubsetRenderable &inRenderable, + TShaderFeatureSet inFeatureSet) + { + // build a string that allows us to print out the shader we are generating to the log. + // This is time consuming but I feel like it doesn't happen all that often and is very + // useful to users + // looking at the log file. + QLatin1String logPrefix("mesh subset pipeline-- "); + + m_GeneratedShaderString.clear(); + m_GeneratedShaderString.assign(logPrefix.data()); + + SShaderDefaultMaterialKey theKey(inRenderable.m_ShaderDescription); + theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = + m_qt3dsContext.GetStringTable().RegisterStr(m_GeneratedShaderString.c_str()); + NVRenderShaderProgram *cachedProgram = theCache.GetProgram(theCacheKey, inFeatureSet); + if (cachedProgram) + return cachedProgram; + + SSubsetMaterialVertexPipeline pipeline( + *this, inRenderable, + m_DefaultMaterialShaderKeyProperties.m_WireframeMode.GetValue(theKey)); + return m_qt3dsContext.GetDefaultMaterialShaderGenerator().GenerateShader( + inRenderable.m_Material, inRenderable.m_ShaderDescription, pipeline, inFeatureSet, + m_CurrentLayer->m_Lights, inRenderable.m_FirstImage, + inRenderable.m_RenderableFlags.HasTransparency(), + logPrefix.data()); + } + + // -------------- Special cases for shadows ------------------- + + SRenderableDepthPrepassShader * + Qt3DSRendererImpl::GetParaboloidDepthShader(TessModeValues::Enum inTessMode) + { + if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() + || inTessMode == TessModeValues::NoTess) { + return GetParaboloidDepthNoTessShader(); + } else if (inTessMode == TessModeValues::TessLinear) { + return GetParaboloidDepthTessLinearShader(); + } else if (inTessMode == TessModeValues::TessPhong) { + return GetParaboloidDepthTessPhongShader(); + } else if (inTessMode == TessModeValues::TessNPatch) { + return GetParaboloidDepthTessNPatchShader(); + } + + return GetParaboloidDepthNoTessShader(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthNoTessShader() + { + Option> &theDepthShader = + m_ParaboloidDepthShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("paraboloid depth shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + IShaderProgramGenerator::OutputParaboloidDepthVertex(vertexShader); + IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthTessLinearShader() + { + Option> &theDepthShader = + m_ParaboloidDepthTessLinearShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("paraboloid depth tess linear shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + // vertexShader.AddOutgoing("world_pos", "vec4"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + // vertexShader.Append("\tworld_pos = attr_pos;"); + vertexShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationLinear.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + // tessCtrlShader.AddOutgoing( "outUVTC", "vec2" ); + // tessCtrlShader.AddOutgoing( "outNormalTC", "vec3" ); + tessCtrlShader.Append("void main() {\n"); + // tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); + // tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); + // tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationLinear.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + IShaderProgramGenerator::OutputParaboloidDepthTessEval(tessEvalShader); + tessEvalShader.Append("}"); + + IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); + } + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthTessPhongShader() + { + Option> &theDepthShader = + m_ParaboloidDepthTessPhongShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("paraboloid depth tess phong shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + // vertexShader.AddOutgoing("world_pos", "vec4"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + // vertexShader.Append("\tworld_pos = attr_pos;"); + vertexShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationPhong.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + // tessCtrlShader.AddOutgoing( "outUVTC", "vec2" ); + // tessCtrlShader.AddOutgoing( "outNormalTC", "vec3" ); + tessCtrlShader.Append("void main() {\n"); + // tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); + // tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); + // tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationPhong.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + IShaderProgramGenerator::OutputParaboloidDepthTessEval(tessEvalShader); + tessEvalShader.Append("}"); + + IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); + } + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetParaboloidDepthTessNPatchShader() + { + Option> &theDepthShader = + m_ParaboloidDepthTessNPatchShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("paraboloid depth tess NPatch shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + // vertexShader.AddOutgoing("world_pos", "vec4"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + // vertexShader.Append("\tworld_pos = attr_pos;"); + vertexShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + // tessCtrlShader.AddOutgoing( "outUVTC", "vec2" ); + // tessCtrlShader.AddOutgoing( "outNormalTC", "vec3" ); + tessCtrlShader.Append("void main() {\n"); + // tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); + // tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); + // tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationNPatch.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + IShaderProgramGenerator::OutputParaboloidDepthTessEval(tessEvalShader); + tessEvalShader.Append("}"); + + IShaderProgramGenerator::OutputParaboloidDepthFragment(fragmentShader); + } + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader * + Qt3DSRendererImpl::GetCubeShadowDepthShader(TessModeValues::Enum inTessMode) + { + if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() + || inTessMode == TessModeValues::NoTess) { + return GetCubeDepthNoTessShader(); + } else if (inTessMode == TessModeValues::TessLinear) { + return GetCubeDepthTessLinearShader(); + } else if (inTessMode == TessModeValues::TessPhong) { + return GetCubeDepthTessPhongShader(); + } else if (inTessMode == TessModeValues::TessNPatch) { + return GetCubeDepthTessNPatchShader(); + } + + return GetCubeDepthNoTessShader(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthNoTessShader() + { + Option> &theDepthShader = + m_CubemapDepthShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("cubemap face depth shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + + if (!depthShaderProgram) { + // GetProgramGenerator().BeginProgram( + // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | + // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( + // ShaderGeneratorStages::Geometry ) ); + + IShaderProgramGenerator::OutputCubeFaceDepthVertex(vertexShader); + // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); + IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); + } else if (theCache.IsShaderCachePersistenceEnabled()) { + // we load from shader cache set default shader stages + GetProgramGenerator().BeginProgram(); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthTessLinearShader() + { + Option> &theDepthShader = + m_CubemapDepthTessLinearShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("cubemap face depth linear tess shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + + if (!depthShaderProgram) { + // GetProgramGenerator().BeginProgram( + // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | + // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( + // ShaderGeneratorStages::Geometry ) ); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("}"); + + // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); + IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); + + tessCtrlShader.AddInclude("tessellationLinear.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationLinear.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddUniform("model_matrix", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tworld_pos = model_matrix * pos;"); + tessEvalShader.Append("\tworld_pos /= world_pos.w;"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + tessEvalShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthTessPhongShader() + { + Option> &theDepthShader = + m_CubemapDepthTessPhongShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("cubemap face depth phong tess shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + + if (!depthShaderProgram) { + // GetProgramGenerator().BeginProgram( + // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | + // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( + // ShaderGeneratorStages::Geometry ) ); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddIncoming("attr_norm", "vec3"); + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("}"); + + // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); + IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); + + tessCtrlShader.AddInclude("tessellationPhong.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationPhong.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddUniform("model_matrix", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tworld_pos = model_matrix * pos;"); + tessEvalShader.Append("\tworld_pos /= world_pos.w;"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + tessEvalShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetCubeDepthTessNPatchShader() + { + Option> &theDepthShader = + m_CubemapDepthTessNPatchShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("cubemap face depth npatch tess shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + + if (!depthShaderProgram) { + // GetProgramGenerator().BeginProgram( + // TShaderGeneratorStageFlags(ShaderGeneratorStages::Vertex | + // ShaderGeneratorStages::Fragment | ShaderGeneratorStages::Geometry) ); + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + // IShaderStageGenerator& geometryShader( *GetProgramGenerator().GetStage( + // ShaderGeneratorStages::Geometry ) ); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddIncoming("attr_norm", "vec3"); + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("}"); + + // IShaderProgramGenerator::OutputCubeFaceDepthGeometry( geometryShader ); + IShaderProgramGenerator::OutputCubeFaceDepthFragment(fragmentShader); + + tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); + tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append( + "\toutNormalTC[gl_InvocationID] = outNormal[gl_InvocationID];\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationNPatch.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddUniform("model_matrix", "mat4"); + tessEvalShader.AddOutgoing("world_pos", "vec4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tctNorm[0] = outNormalTC[0];"); + tessEvalShader.Append("\tctNorm[1] = outNormalTC[1];"); + tessEvalShader.Append("\tctNorm[2] = outNormalTC[2];"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tworld_pos = model_matrix * pos;"); + tessEvalShader.Append("\tworld_pos /= world_pos.w;"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + tessEvalShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader * + Qt3DSRendererImpl::GetOrthographicDepthShader(TessModeValues::Enum inTessMode) + { + if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() + || inTessMode == TessModeValues::NoTess) { + return GetOrthographicDepthNoTessShader(); + } else if (inTessMode == TessModeValues::TessLinear) { + return GetOrthographicDepthTessLinearShader(); + } else if (inTessMode == TessModeValues::TessPhong) { + return GetOrthographicDepthTessPhongShader(); + } else if (inTessMode == TessModeValues::TessNPatch) { + return GetOrthographicDepthTessNPatchShader(); + } + + return GetOrthographicDepthNoTessShader(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthNoTessShader() + { + Option> &theDepthShader = + m_OrthographicDepthShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("orthographic depth shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader.AddOutgoing("outDepth", "vec3"); + vertexShader.Append("void main() {"); + vertexShader.Append( + " gl_Position = model_view_projection * vec4( attr_pos, 1.0 );"); + vertexShader.Append(" outDepth.x = gl_Position.z / gl_Position.w;"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfloat depth = (outDepth.x + 1.0) * 0.5;"); + fragmentShader.Append("\tfragOutput = vec4(depth);"); + fragmentShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthTessLinearShader() + { + Option> &theDepthShader = + m_OrthographicDepthTessLinearShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("orthographic depth tess linear shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfloat depth = (outDepth.x + 1.0) * 0.5;"); + fragmentShader.Append("\tfragOutput = vec4(depth);"); + fragmentShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationLinear.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationLinear.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddOutgoing("outDepth", "vec3"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + tessEvalShader.Append("\toutDepth.x = gl_Position.z / gl_Position.w;"); + tessEvalShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthTessPhongShader() + { + Option> &theDepthShader = + m_OrthographicDepthTessPhongShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("orthographic depth tess phong shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddIncoming("attr_norm", "vec3"); + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfloat depth = (outDepth.x + 1.0) * 0.5;"); + fragmentShader.Append("\tfragOutput = vec4(depth);"); + fragmentShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationPhong.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationPhong.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddOutgoing("outDepth", "vec3"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + tessEvalShader.Append("\toutDepth.x = gl_Position.z / gl_Position.w;"); + tessEvalShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetOrthographicDepthTessNPatchShader() + { + Option> &theDepthShader = + m_OrthographicDepthTessNPatchShader; + + if (theDepthShader.hasValue() == false) { + TStrType name; + name.assign("orthographic depth tess npatch shader"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddIncoming("attr_norm", "vec3"); + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + fragmentShader.AddUniform("model_view_projection", "mat4"); + fragmentShader.AddUniform("camera_properties", "vec2"); + fragmentShader.AddUniform("camera_position", "vec3"); + fragmentShader.AddUniform("camera_direction", "vec3"); + fragmentShader.AddInclude("depthpass.glsllib"); + + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + // fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); + fragmentShader.Append("\tfloat depth = (outDepth.x - camera_properties.x) / " + "(camera_properties.y - camera_properties.x);"); + fragmentShader.Append("\tfragOutput = vec4(depth);"); + fragmentShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationNPatch.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.AddUniform("model_matrix", "mat4"); + tessEvalShader.AddOutgoing("outDepth", "vec3"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + tessEvalShader.Append("\toutDepth.x = gl_Position.z / gl_Position.w;"); + tessEvalShader.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthShader = NVScopedRefCounted(); + } + } + + return theDepthShader.getValue(); + } + + // --------------------------------- + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetDepthPrepassShader(bool inDisplaced) + { + Option> &theDepthPrePassShader = + (!inDisplaced) ? m_DepthPrepassShader : m_DepthPrepassShaderDisplaced; + + if (theDepthPrePassShader.hasValue() == false) { + // check if we do displacement mapping + TStrType name; + name.assign("depth prepass shader"); + if (inDisplaced) + name.append(" displacement"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + + vertexShader.Append("void main() {"); + + if (inDisplaced) { + GetQt3DSContext() + .GetDefaultMaterialShaderGenerator() + .AddDisplacementMappingForDepthPass(vertexShader); + } else { + vertexShader.Append( + "\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + } + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); + fragmentShader.Append("}"); + } else if (theCache.IsShaderCachePersistenceEnabled()) { + // we load from shader cache set default shader stages + GetProgramGenerator().BeginProgram(); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthPrePassShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthPrePassShader = NVScopedRefCounted(); + } + } + return theDepthPrePassShader.getValue(); + } + + SRenderableDepthPrepassShader * + Qt3DSRendererImpl::GetDepthTessPrepassShader(TessModeValues::Enum inTessMode, bool inDisplaced) + { + if (!m_qt3dsContext.GetRenderContext().IsTessellationSupported() + || inTessMode == TessModeValues::NoTess) { + return GetDepthPrepassShader(inDisplaced); + } else if (inTessMode == TessModeValues::TessLinear) { + return GetDepthTessLinearPrepassShader(inDisplaced); + } else if (inTessMode == TessModeValues::TessPhong) { + return GetDepthTessPhongPrepassShader(); + } else if (inTessMode == TessModeValues::TessNPatch) { + return GetDepthTessNPatchPrepassShader(); + } + + return GetDepthPrepassShader(inDisplaced); + } + + SRenderableDepthPrepassShader * + Qt3DSRendererImpl::GetDepthTessLinearPrepassShader(bool inDisplaced) + { + Option> &theDepthPrePassShader = + (!inDisplaced) ? m_DepthTessLinearPrepassShader + : m_DepthTessLinearPrepassShaderDisplaced; + + if (theDepthPrePassShader.hasValue() == false) { + // check if we do displacement mapping + TStrType name; + name.assign("depth tess linear prepass shader"); + if (inDisplaced) + name.append(" displacement"); + + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = m_qt3dsContext.GetStringTable().RegisterStr(name.c_str()); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexShader.AddIncoming("attr_pos", "vec3"); + if (inDisplaced) { + vertexShader.AddIncoming("attr_uv0", "vec2"); + vertexShader.AddIncoming("attr_norm", "vec3"); + + vertexShader.AddUniform("displacementMap_rot", "vec4"); + vertexShader.AddUniform("displacementMap_offset", "vec3"); + + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.AddOutgoing("outUV", "vec2"); + } + vertexShader.AddOutgoing("outWorldPos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader.AddUniform("model_matrix", "mat4"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + if (inDisplaced) { + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, " + "displacementMap_rot.y, displacementMap_offset.x );"); + vertexShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, " + "displacementMap_rot.w, displacementMap_offset.y );"); + vertexShader.AddInclude( + "defaultMaterialLighting.glsllib"); // getTransformedUVCoords is in the + // lighting code addition. + vertexShader << "\tvec2 uv_coords = attr_uv0;" << Endl; + vertexShader << "\toutUV = getTransformedUVCoords( vec3( uv_coords, 1.0), " + "uTransform, vTransform );\n"; + } + vertexShader.Append("\toutWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); + fragmentShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationLinear.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.AddOutgoing("outUVTC", "vec2"); + tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); + tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); + tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + + if (inDisplaced) { + tessCtrlShader.Append("\toutUVTC[gl_InvocationID] = outUV[gl_InvocationID];"); + tessCtrlShader.Append( + "\toutNormalTC[gl_InvocationID] = outNormal[gl_InvocationID];"); + } + + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationLinear.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + if (inDisplaced) { + tessEvalShader.AddUniform("displacementSampler", "sampler2D"); + tessEvalShader.AddUniform("displaceAmount", "float"); + tessEvalShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); + } + tessEvalShader.AddOutgoing("outUV", "vec2"); + tessEvalShader.AddOutgoing("outNormal", "vec3"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + + if (inDisplaced) { + tessEvalShader << "\toutUV = gl_TessCoord.x * outUVTC[0] + gl_TessCoord.y * " + "outUVTC[1] + gl_TessCoord.z * outUVTC[2];" + << Endl; + tessEvalShader + << "\toutNormal = gl_TessCoord.x * outNormalTC[0] + gl_TessCoord.y * " + "outNormalTC[1] + gl_TessCoord.z * outNormalTC[2];" + << Endl; + tessEvalShader + << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " + "displacementSampler , displaceAmount, outUV , outNormal, pos.xyz );" + << Endl; + tessEvalShader.Append( + "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); + } else + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;"); + + tessEvalShader.Append("}"); + } else if (theCache.IsShaderCachePersistenceEnabled()) { + // we load from shader cache set default shader stages + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + } + + SShaderCacheProgramFlags theFlags; + theFlags.SetTessellationEnabled(true); + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + name.c_str(), theFlags, TShaderFeatureSet()); + + if (depthShaderProgram) { + theDepthPrePassShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + theDepthPrePassShader = NVScopedRefCounted(); + } + } + return theDepthPrePassShader->mPtr; + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetDepthTessPhongPrepassShader() + { + if (m_DepthTessPhongPrepassShader.hasValue() == false) { + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = + m_qt3dsContext.GetStringTable().RegisterStr("depth tess phong prepass shader"); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddIncoming("attr_norm", "vec3"); + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.AddOutgoing("outWorldPos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader.AddUniform("model_matrix", "mat4"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("\toutWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); + fragmentShader.Append("}"); + + tessCtrlShader.AddInclude("tessellationPhong.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); + tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); + tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); + tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationPhong.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); + tessEvalShader.Append("}"); + } else if (theCache.IsShaderCachePersistenceEnabled()) { + // we load from shader cache set default shader stages + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + } + + SShaderCacheProgramFlags theFlags; + theFlags.SetTessellationEnabled(true); + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + "depth tess phong prepass shader", theFlags, TShaderFeatureSet()); + + if (depthShaderProgram) { + m_DepthTessPhongPrepassShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + m_DepthTessPhongPrepassShader = NVScopedRefCounted(); + } + } + return m_DepthTessPhongPrepassShader->mPtr; + } + + SRenderableDepthPrepassShader *Qt3DSRendererImpl::GetDepthTessNPatchPrepassShader() + { + if (m_DepthTessNPatchPrepassShader.hasValue() == false) { + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = + m_qt3dsContext.GetStringTable().RegisterStr("depth tess npatch prepass shader"); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &vertexShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &tessCtrlShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessControl)); + IShaderStageGenerator &tessEvalShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)); + IShaderStageGenerator &fragmentShader( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexShader.AddIncoming("attr_pos", "vec3"); + vertexShader.AddIncoming("attr_norm", "vec3"); + vertexShader.AddOutgoing("outNormal", "vec3"); + vertexShader.AddOutgoing("outWorldPos", "vec3"); + vertexShader.AddUniform("model_view_projection", "mat4"); + vertexShader.AddUniform("model_matrix", "mat4"); + vertexShader.Append("void main() {"); + vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);"); + vertexShader.Append("\toutWorldPos = (model_matrix * vec4(attr_pos, 1.0)).xyz;"); + vertexShader.Append("\toutNormal = attr_norm;"); + vertexShader.Append("}"); + fragmentShader.Append("void main() {"); + fragmentShader.Append("\tfragOutput = vec4(0.0, 0.0, 0.0, 0.0);"); + fragmentShader.Append("}"); + + tessCtrlShader.AddOutgoing("outNormalTC", "vec3"); + tessCtrlShader.AddInclude("tessellationNPatch.glsllib"); + tessCtrlShader.AddUniform("tessLevelInner", "float"); + tessCtrlShader.AddUniform("tessLevelOuter", "float"); + tessCtrlShader.Append("void main() {\n"); + tessCtrlShader.Append("\tctWorldPos[0] = outWorldPos[0];"); + tessCtrlShader.Append("\tctWorldPos[1] = outWorldPos[1];"); + tessCtrlShader.Append("\tctWorldPos[2] = outWorldPos[2];"); + tessCtrlShader.Append("\tctNorm[0] = outNormal[0];"); + tessCtrlShader.Append("\tctNorm[1] = outNormal[1];"); + tessCtrlShader.Append("\tctNorm[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tctTangent[0] = outNormal[0];"); // we don't care for the tangent + tessCtrlShader.Append("\tctTangent[1] = outNormal[1];"); + tessCtrlShader.Append("\tctTangent[2] = outNormal[2];"); + tessCtrlShader.Append( + "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"); + tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n"); + tessCtrlShader.Append( + "\toutNormalTC[gl_InvocationID] = outNormal[gl_InvocationID];\n"); + tessCtrlShader.Append("}"); + + tessEvalShader.AddInclude("tessellationNPatch.glsllib"); + tessEvalShader.AddUniform("model_view_projection", "mat4"); + tessEvalShader.Append("void main() {"); + tessEvalShader.Append("\tctNorm[0] = outNormalTC[0];"); + tessEvalShader.Append("\tctNorm[1] = outNormalTC[1];"); + tessEvalShader.Append("\tctNorm[2] = outNormalTC[2];"); + tessEvalShader.Append( + "\tctTangent[0] = outNormalTC[0];"); // we don't care for the tangent + tessEvalShader.Append("\tctTangent[1] = outNormalTC[1];"); + tessEvalShader.Append("\tctTangent[2] = outNormalTC[2];"); + tessEvalShader.Append("\tvec4 pos = tessShader( );\n"); + tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n"); + tessEvalShader.Append("}"); + } else if (theCache.IsShaderCachePersistenceEnabled()) { + // we load from shader cache set default shader stages + GetProgramGenerator().BeginProgram(TShaderGeneratorStageFlags( + ShaderGeneratorStages::Vertex | ShaderGeneratorStages::TessControl + | ShaderGeneratorStages::TessEval | ShaderGeneratorStages::Fragment)); + } + + SShaderCacheProgramFlags theFlags; + theFlags.SetTessellationEnabled(true); + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + "depth tess npatch prepass shader", theFlags, TShaderFeatureSet()); + + if (depthShaderProgram) { + m_DepthTessNPatchPrepassShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), + SRenderableDepthPrepassShader)(*depthShaderProgram, GetContext())); + } else { + m_DepthTessNPatchPrepassShader = + NVScopedRefCounted(); + } + } + return m_DepthTessNPatchPrepassShader->mPtr; + } + + SDefaultAoPassShader *Qt3DSRendererImpl::GetDefaultAoPassShader(TShaderFeatureSet inFeatureSet) + { + if (m_DefaultAoPassShader.hasValue() == false) { + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = + m_qt3dsContext.GetStringTable().RegisterStr("fullscreen AO pass shader"); + NVRenderShaderProgram *aoPassShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!aoPassShaderProgram) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &theVertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &theFragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + theVertexGenerator.AddIncoming("attr_pos", "vec3"); + theVertexGenerator.AddIncoming("attr_uv", "vec2"); + theVertexGenerator.AddOutgoing("uv_coords", "vec2"); + theVertexGenerator.Append("void main() {"); + theVertexGenerator.Append("\tgl_Position = vec4(attr_pos.xy, 0.5, 1.0 );"); + theVertexGenerator.Append("\tuv_coords = attr_uv;"); + theVertexGenerator.Append("}"); + + // fragmentGenerator.AddInclude( "SSAOCustomMaterial.glsllib" ); + theFragmentGenerator.AddInclude("viewProperties.glsllib"); + theFragmentGenerator.AddInclude("screenSpaceAO.glsllib"); + if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) { + theFragmentGenerator + << "\tuniform vec4 ao_properties;" << Endl + << "\tuniform vec4 ao_properties2;" << Endl + << "\tuniform vec4 shadow_properties;" << Endl + << "\tuniform vec4 aoScreenConst;" << Endl + << "\tuniform vec4 UvToEyeConst;" << Endl; + } else { + theFragmentGenerator + << "layout (std140) uniform cbAoShadow { " << Endl << "\tvec4 ao_properties;" + << Endl << "\tvec4 ao_properties2;" << Endl << "\tvec4 shadow_properties;" + << Endl << "\tvec4 aoScreenConst;" << Endl << "\tvec4 UvToEyeConst;" << Endl + << "};" << Endl; + } + theFragmentGenerator.AddUniform("camera_direction", "vec3"); + theFragmentGenerator.AddUniform("depth_sampler", "sampler2D"); + theFragmentGenerator.Append("void main() {"); + theFragmentGenerator << "\tfloat aoFactor;" << Endl; + theFragmentGenerator << "\tvec3 screenNorm;" << Endl; + + // We're taking multiple depth samples and getting the derivatives at each of them + // to get a more + // accurate view space normal vector. When we do only one, we tend to get bizarre + // values at the edges + // surrounding objects, and this also ends up giving us weird AO values. + // If we had a proper screen-space normal map, that would also do the trick. + if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) { + theFragmentGenerator.AddUniform("depth_sampler_size", "vec2"); + theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );"); + theFragmentGenerator.Append("\tfloat depth = getDepthValue( " + "texture2D(depth_sampler, vec2(iCoords)" + " / depth_sampler_size), camera_properties );"); + theFragmentGenerator.Append( + "\tdepth = depthValueToLinearDistance( depth, camera_properties );"); + theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / " + "(camera_properties.y - camera_properties.x);"); + theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( " + "texture2D(depth_sampler, vec2(iCoords+ivec2(1))" + " / depth_sampler_size), camera_properties );"); + theFragmentGenerator.Append( + "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );"); + theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( " + "texture2D(depth_sampler, vec2(iCoords-ivec2(1))" + " / depth_sampler_size), camera_properties );"); + } else { + theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );"); + theFragmentGenerator.Append("\tfloat depth = getDepthValue( " + "texelFetch(depth_sampler, iCoords, 0), " + "camera_properties );"); + theFragmentGenerator.Append( + "\tdepth = depthValueToLinearDistance( depth, camera_properties );"); + theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / " + "(camera_properties.y - camera_properties.x);"); + theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( " + "texelFetch(depth_sampler, iCoords+ivec2(1), 0), " + "camera_properties );"); + theFragmentGenerator.Append( + "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );"); + theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( " + "texelFetch(depth_sampler, iCoords-ivec2(1), 0), " + "camera_properties );"); + } + theFragmentGenerator.Append( + "\tdepth3 = depthValueToLinearDistance( depth, camera_properties );"); + theFragmentGenerator.Append("\tvec3 tanU = vec3(10, 0, dFdx(depth));"); + theFragmentGenerator.Append("\tvec3 tanV = vec3(0, 10, dFdy(depth));"); + theFragmentGenerator.Append("\tscreenNorm = normalize(cross(tanU, tanV));"); + theFragmentGenerator.Append("\ttanU = vec3(10, 0, dFdx(depth2));"); + theFragmentGenerator.Append("\ttanV = vec3(0, 10, dFdy(depth2));"); + theFragmentGenerator.Append("\tscreenNorm += normalize(cross(tanU, tanV));"); + theFragmentGenerator.Append("\ttanU = vec3(10, 0, dFdx(depth3));"); + theFragmentGenerator.Append("\ttanV = vec3(0, 10, dFdy(depth3));"); + theFragmentGenerator.Append("\tscreenNorm += normalize(cross(tanU, tanV));"); + theFragmentGenerator.Append("\tscreenNorm = -normalize(screenNorm);"); + + theFragmentGenerator.Append("\taoFactor = \ + SSambientOcclusion( depth_sampler, screenNorm, ao_properties, ao_properties2, \ + camera_properties, aoScreenConst, UvToEyeConst );"); + + theFragmentGenerator.Append( + "\tgl_FragColor = vec4(aoFactor, aoFactor, aoFactor, 1.0);"); + + theFragmentGenerator.Append("}"); + } + + aoPassShaderProgram = GetProgramGenerator().CompileGeneratedShader( + "fullscreen AO pass shader", SShaderCacheProgramFlags(), inFeatureSet); + + if (aoPassShaderProgram) { + m_DefaultAoPassShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), SDefaultAoPassShader)(*aoPassShaderProgram, + GetContext())); + } else { + m_DefaultAoPassShader = NVScopedRefCounted(); + } + } + return m_DefaultAoPassShader->mPtr; + } + + SDefaultAoPassShader *Qt3DSRendererImpl::GetFakeDepthShader(TShaderFeatureSet inFeatureSet) + { + if (m_FakeDepthShader.hasValue() == false) { + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = + m_qt3dsContext.GetStringTable().RegisterStr("depth display shader"); + NVRenderShaderProgram *depthShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!depthShaderProgram) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &theVertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &theFragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + theVertexGenerator.AddIncoming("attr_pos", "vec3"); + theVertexGenerator.AddIncoming("attr_uv", "vec2"); + theVertexGenerator.AddOutgoing("uv_coords", "vec2"); + theVertexGenerator.Append("void main() {"); + theVertexGenerator.Append("\tgl_Position = vec4(attr_pos.xy, 0.5, 1.0 );"); + theVertexGenerator.Append("\tuv_coords = attr_uv;"); + theVertexGenerator.Append("}"); + + theFragmentGenerator.AddUniform("depth_sampler", "sampler2D"); + theFragmentGenerator.Append("void main() {"); + theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );"); + theFragmentGenerator.Append( + "\tfloat depSample = texelFetch(depth_sampler, iCoords, 0).x;"); + theFragmentGenerator.Append( + "\tgl_FragColor = vec4( depSample, depSample, depSample, 1.0 );"); + theFragmentGenerator.Append("\treturn;"); + theFragmentGenerator.Append("}"); + } + + depthShaderProgram = GetProgramGenerator().CompileGeneratedShader( + "depth display shader", SShaderCacheProgramFlags(), inFeatureSet); + + if (depthShaderProgram) { + m_FakeDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), SDefaultAoPassShader)( + *depthShaderProgram, GetContext())); + } else { + m_FakeDepthShader = NVScopedRefCounted(); + } + } + return m_FakeDepthShader->mPtr; + } + + SDefaultAoPassShader *Qt3DSRendererImpl::GetFakeCubeDepthShader(TShaderFeatureSet inFeatureSet) + { + if (!m_FakeCubemapDepthShader.hasValue()) { + IShaderCache &theCache = m_qt3dsContext.GetShaderCache(); + CRegisteredString theCacheKey = + m_qt3dsContext.GetStringTable().RegisterStr("cube depth display shader"); + NVRenderShaderProgram *cubeShaderProgram = + theCache.GetProgram(theCacheKey, TShaderFeatureSet()); + if (!cubeShaderProgram) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &theVertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &theFragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + theVertexGenerator.AddIncoming("attr_pos", "vec3"); + theVertexGenerator.AddIncoming("attr_uv", "vec2"); + theVertexGenerator.AddOutgoing("sample_dir", "vec3"); + theVertexGenerator.Append("void main() {"); + theVertexGenerator.Append("\tgl_Position = vec4(attr_pos.xy, 0.5, 1.0 );"); + theVertexGenerator.Append( + "\tsample_dir = vec3(4.0 * (attr_uv.x - 0.5), -1.0, 4.0 * (attr_uv.y - 0.5));"); + theVertexGenerator.Append("}"); + theFragmentGenerator.AddUniform("depth_cube", "samplerCube"); + theFragmentGenerator.Append("void main() {"); + theFragmentGenerator.Append( + "\tfloat smpDepth = texture( depth_cube, sample_dir ).x;"); + theFragmentGenerator.Append( + "\tgl_FragColor = vec4(smpDepth, smpDepth, smpDepth, 1.0);"); + theFragmentGenerator.Append("}"); + } + + cubeShaderProgram = GetProgramGenerator().CompileGeneratedShader( + "cube depth display shader", SShaderCacheProgramFlags(), inFeatureSet); + + if (cubeShaderProgram) { + m_FakeCubemapDepthShader = NVScopedRefCounted( + QT3DS_NEW(GetContext().GetAllocator(), SDefaultAoPassShader)(*cubeShaderProgram, + GetContext())); + } else { + m_FakeCubemapDepthShader = NVScopedRefCounted(); + } + } + return m_FakeCubemapDepthShader.getValue(); + } + + STextRenderHelper Qt3DSRendererImpl::GetTextShader(bool inUsePathRendering) + { + STextShaderPtr &thePtr = (!inUsePathRendering) ? m_TextShader : m_TextPathShader; + if (thePtr.HasGeneratedShader()) + return STextRenderHelper(thePtr, *m_QuadInputAssembler); + + NVRenderShaderProgram *theShader = NULL; + NVRenderProgramPipeline *thePipeline = NULL; + + if (!inUsePathRendering) { + GetProgramGenerator().BeginProgram(); + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + // xy of text dimensions are scaling factors, zw are offset factors. + vertexGenerator.AddUniform("text_dimensions", "vec4"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator + << "\tvec3 textPos = vec3(attr_pos.x * text_dimensions.x + text_dimensions.z" + << ", attr_pos.y * text_dimensions.y + text_dimensions.w" + << ", attr_pos.z);" << Endl; + + vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(textPos, 1.0);"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + + fragmentGenerator.AddUniform("text_textcolor", "vec4"); + fragmentGenerator.AddUniform("text_textdimensions", "vec3"); + fragmentGenerator.AddUniform("text_image", "sampler2D"); + fragmentGenerator.AddUniform("text_backgroundcolor", "vec3"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec2 theCoords = uv_coords;"); + // Enable rendering from a sub-rect + + fragmentGenerator + << "\ttheCoords.x = theCoords.x * text_textdimensions.x;" << Endl + << "\ttheCoords.y = theCoords.y * text_textdimensions.y;" << Endl + // flip the y uv coord if the dimension's z variable is set + << "\tif ( text_textdimensions.z > 0.0 ) theCoords.y = 1.0 - theCoords.y;" << Endl; + fragmentGenerator.Append( + "\tvec4 c = texture2D(text_image, theCoords);"); + fragmentGenerator.Append( + "\tfragOutput = vec4(mix(text_backgroundcolor.rgb, " + "text_textcolor.rgb, c.rgb), c.a) * text_textcolor.a;"); + + vertexGenerator.Append("}"); + fragmentGenerator.Append("}"); + const char *shaderName = "text shader"; + theShader = GetProgramGenerator().CompileGeneratedShader( + shaderName, SShaderCacheProgramFlags(), TShaderFeatureSet(), false); + } else { + GetProgramGenerator().BeginProgram( + TShaderGeneratorStageFlags(ShaderGeneratorStages::Fragment)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + fragmentGenerator.AddUniform("text_textcolor", "vec4"); + fragmentGenerator.AddUniform("text_backgroundcolor", "vec3"); + + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tfragOutput = vec4(mix(text_backgroundcolor.rgb, " + "text_textcolor.rgb, text_textcolor.a), text_textcolor.a );"); + fragmentGenerator.Append("}"); + + const char *shaderName = "text path shader"; + theShader = GetProgramGenerator().CompileGeneratedShader( + shaderName, SShaderCacheProgramFlags(), TShaderFeatureSet(), true); + + // setup program pipeline + if (theShader) { + thePipeline = GetContext().CreateProgramPipeline(); + if (thePipeline) { + thePipeline->SetProgramStages( + theShader, + qt3ds::render::NVRenderShaderTypeFlags(NVRenderShaderTypeValue::Fragment)); + } + } + } + + if (theShader == NULL) { + thePtr.Set(NULL); + } else { + GenerateXYQuad(); + thePtr.Set(QT3DS_NEW(m_Context->GetAllocator(), STextShader)(*theShader, thePipeline)); + } + return STextRenderHelper(thePtr, *m_QuadInputAssembler); + } + + STextDepthShader *Qt3DSRendererImpl::GetTextDepthShader() + { + if (m_TextDepthPrepassShader.hasValue() == false) { + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + // xy of text dimensions are scaling factors, zw are offset factors. + vertexGenerator.AddUniform("text_dimensions", "vec4"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator + << "\tvec3 textPos = vec3(attr_pos.x * text_dimensions.x + text_dimensions.z" + << ", attr_pos.y * text_dimensions.y + text_dimensions.w" + << ", attr_pos.z);" << Endl; + + vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(textPos, 1.0);"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + + fragmentGenerator.AddUniform("text_textdimensions", "vec3"); + fragmentGenerator.AddUniform("text_image", "sampler2D"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec2 theCoords = uv_coords;"); + // Enable rendering from a sub-rect + + fragmentGenerator + << "\ttheCoords.x = theCoords.x * text_textdimensions.x;" << Endl + << "\ttheCoords.y = theCoords.y * text_textdimensions.y;" << Endl + // flip the y uv coord if the dimension's z variable is set + << "\tif ( text_textdimensions.z > 0.0 ) theCoords.y = 1.0 - theCoords.y;" << Endl; + fragmentGenerator.Append("\tfloat alpha_mask = texture2D( text_image, theCoords ).r;"); + fragmentGenerator.Append("\tif ( alpha_mask < .05 ) discard;"); + vertexGenerator.Append("}"); + fragmentGenerator.Append("}"); + const char *shaderName = "text depth shader"; + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + shaderName, SShaderCacheProgramFlags(), TShaderFeatureSet()); + if (theShader == NULL) { + m_TextDepthPrepassShader = NVScopedRefCounted(); + } else { + GenerateXYQuad(); + m_TextDepthPrepassShader = NVScopedRefCounted( + QT3DS_NEW(m_Context->GetAllocator(), STextDepthShader)( + m_Context->GetAllocator(), *theShader, *m_QuadInputAssembler)); + } + } + return m_TextDepthPrepassShader->mPtr; + } + + STextRenderHelper Qt3DSRendererImpl::GetTextWidgetShader() + { + if (m_TextWidgetShader.HasGeneratedShader()) + return STextRenderHelper(m_TextWidgetShader, *m_QuadInputAssembler); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + // xy of text dimensions are scaling factors, zw are offset factors. + vertexGenerator.AddUniform("text_dimensions", "vec4"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator + << "\tvec3 textPos = vec3(attr_pos.x * text_dimensions.x + text_dimensions.z" + << ", attr_pos.y * text_dimensions.y + text_dimensions.w" + << ", attr_pos.z);" << Endl; + + vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(textPos, 1.0);"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("text_textcolor", "vec4"); + fragmentGenerator.AddUniform("text_textdimensions", "vec3"); + fragmentGenerator.AddUniform("text_image", "sampler2D"); + fragmentGenerator.AddUniform("text_backgroundcolor", "vec3"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec2 theCoords = uv_coords;"); + // Enable rendering from a sub-rect + + fragmentGenerator << "\ttheCoords.x = theCoords.x * text_textdimensions.x;" << Endl + << "\ttheCoords.y = theCoords.y * text_textdimensions.y;" << Endl + // flip the y uv coord if the dimension's z variable is set + << "\tif ( text_textdimensions.z > 0.0 ) theCoords.y = 1.0 - theCoords.y;" + << Endl; + fragmentGenerator.Append( + "\tfloat alpha_mask = texture2D( text_image, theCoords ).r * text_textcolor.a;"); + fragmentGenerator.Append("\tfragOutput = vec4(mix(text_backgroundcolor.rgb, " + "text_textcolor.rgb, alpha_mask), 1.0 );"); + fragmentGenerator.Append("}"); + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "text widget shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (theShader == NULL) + m_TextWidgetShader.Set(NULL); + else { + GenerateXYQuad(); + m_TextWidgetShader.Set(QT3DS_NEW(m_Context->GetAllocator(), STextShader)(*theShader)); + } + return STextRenderHelper(m_TextWidgetShader, *m_QuadInputAssembler); + } + + STextRenderHelper Qt3DSRendererImpl::GetOnscreenTextShader() + { + if (m_TextOnscreenShader.HasGeneratedShader()) + return STextRenderHelper(m_TextOnscreenShader, *m_QuadStripInputAssembler); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddUniform("vertex_offsets", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + + vertexGenerator.Append("\tvec3 pos = attr_pos + vec3(vertex_offsets, 0.0);"); + vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(pos, 1.0);"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("text_textcolor", "vec4"); + fragmentGenerator.AddUniform("text_image", "sampler2D"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tfloat alpha = texture2D( text_image, uv_coords ).a;"); + fragmentGenerator.Append( + "\tfragOutput = vec4(text_textcolor.r, text_textcolor.g, text_textcolor.b, alpha);"); + fragmentGenerator.Append("}"); + + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "onscreen texture shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + + if (theShader == NULL) + m_TextOnscreenShader.Set(NULL); + else { + GenerateXYQuadStrip(); + m_TextOnscreenShader.Set(QT3DS_NEW(m_Context->GetAllocator(), STextShader)(*theShader)); + } + return STextRenderHelper(m_TextOnscreenShader, *m_QuadStripInputAssembler); + } + + NVRenderShaderProgram *Qt3DSRendererImpl::GetTextAtlasEntryShader() + { + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + + vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("text_image", "sampler2D"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tfloat alpha = texture2D( text_image, uv_coords ).a;"); + fragmentGenerator.Append("\tfragOutput = vec4(alpha, alpha, alpha, alpha);"); + fragmentGenerator.Append("}"); + + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "texture atlas entry shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + + return theShader; + } + + STextRenderHelper Qt3DSRendererImpl::GetShader(STextRenderable & /*inRenderable*/, + bool inUsePathRendering) + { + return GetTextShader(inUsePathRendering); + } + + SLayerSceneShader *Qt3DSRendererImpl::GetSceneLayerShader() + { + if (m_SceneLayerShader.hasValue()) + return m_SceneLayerShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + // xy of text dimensions are scaling factors, zw are offset factors. + vertexGenerator.AddUniform("layer_dimensions", "vec2"); + vertexGenerator.AddUniform("model_view_projection", "mat4"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator << "\tvec3 layerPos = vec3(attr_pos.x * layer_dimensions.x / 2.0" + << ", attr_pos.y * layer_dimensions.y / 2.0" + << ", attr_pos.z);" << Endl; + + vertexGenerator.Append("\tgl_Position = model_view_projection * vec4(layerPos, 1.0);"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("layer_image", "sampler2D"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec2 theCoords = uv_coords;\n"); + fragmentGenerator.Append("\tvec4 theLayerTexture = texture2D( layer_image, theCoords );\n"); + fragmentGenerator.Append("\tif( theLayerTexture.a == 0.0 ) discard;\n"); + fragmentGenerator.Append("\tfragOutput = theLayerTexture;\n"); + fragmentGenerator.Append("}"); + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "layer shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SLayerSceneShader)(*theShader); + m_SceneLayerShader = retval; + return m_SceneLayerShader.getValue(); + } + + SLayerProgAABlendShader *Qt3DSRendererImpl::GetLayerProgAABlendShader() + { + if (m_LayerProgAAShader.hasValue()) + return m_LayerProgAAShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + fragmentGenerator.AddUniform("accumulator", "sampler2D"); + fragmentGenerator.AddUniform("last_frame", "sampler2D"); + fragmentGenerator.AddUniform("blend_factors", "vec2"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec4 accum = texture2D( accumulator, uv_coords );"); + fragmentGenerator.Append("\tvec4 lastFrame = texture2D( last_frame, uv_coords );"); + fragmentGenerator.Append( + "\tgl_FragColor = accum*blend_factors.y + lastFrame*blend_factors.x;"); + fragmentGenerator.Append("}"); + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "layer progressiveAA blend shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SLayerProgAABlendShader)(*theShader); + m_LayerProgAAShader = retval; + return m_LayerProgAAShader.getValue(); + } + + SShadowmapPreblurShader *Qt3DSRendererImpl::GetCubeShadowBlurXShader() + { + if (m_CubeShadowBlurXShader.hasValue()) + return m_CubeShadowBlurXShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + // vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords.xy = attr_pos.xy;"); + vertexGenerator.Append("}"); + + // This with the ShadowBlurYShader design for a 2-pass 5x5 (sigma=1.0) + // Weights computed using -- http://dev.theomader.com/gaussian-kernel-calculator/ + fragmentGenerator.AddUniform("camera_properties", "vec2"); + fragmentGenerator.AddUniform("depthCube", "samplerCube"); + // fragmentGenerator.AddUniform("depthSrc", "sampler2D"); + fragmentGenerator.Append("layout(location = 0) out vec4 frag0;"); + fragmentGenerator.Append("layout(location = 1) out vec4 frag1;"); + fragmentGenerator.Append("layout(location = 2) out vec4 frag2;"); + fragmentGenerator.Append("layout(location = 3) out vec4 frag3;"); + fragmentGenerator.Append("layout(location = 4) out vec4 frag4;"); + fragmentGenerator.Append("layout(location = 5) out vec4 frag5;"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tfloat ofsScale = camera_properties.x / 2500.0;"); + fragmentGenerator.Append("\tvec3 dir0 = vec3(1.0, -uv_coords.y, -uv_coords.x);"); + fragmentGenerator.Append("\tvec3 dir1 = vec3(-1.0, -uv_coords.y, uv_coords.x);"); + fragmentGenerator.Append("\tvec3 dir2 = vec3(uv_coords.x, 1.0, uv_coords.y);"); + fragmentGenerator.Append("\tvec3 dir3 = vec3(uv_coords.x, -1.0, -uv_coords.y);"); + fragmentGenerator.Append("\tvec3 dir4 = vec3(uv_coords.x, -uv_coords.y, 1.0);"); + fragmentGenerator.Append("\tvec3 dir5 = vec3(-uv_coords.x, -uv_coords.y, -1.0);"); + fragmentGenerator.Append("\tfloat depth0;"); + fragmentGenerator.Append("\tfloat depth1;"); + fragmentGenerator.Append("\tfloat depth2;"); + fragmentGenerator.Append("\tfloat outDepth;"); + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir0).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir0 + vec3(0.0, 0.0, -ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir0 + vec3(0.0, 0.0, ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir0 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir0 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag0 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir1).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir1 + vec3(0.0, 0.0, -ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir1 + vec3(0.0, 0.0, ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir1 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir1 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag1 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir2).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir2 + vec3(-ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir2 + vec3(ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir2 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir2 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag2 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir3).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir3 + vec3(-ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir3 + vec3(ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir3 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir3 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag3 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir4).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir4 + vec3(-ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir4 + vec3(ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir4 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir4 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag4 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir5).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir5 + vec3(-ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir5 + vec3(ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir5 + vec3(-2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir5 + vec3(2.0*ofsScale, 0.0, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag5 = vec4(outDepth);"); + + fragmentGenerator.Append("}"); + + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "cubemap shadow blur X shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); + m_CubeShadowBlurXShader = retval; + return m_CubeShadowBlurXShader.getValue(); + } + + SShadowmapPreblurShader *Qt3DSRendererImpl::GetCubeShadowBlurYShader() + { + if (m_CubeShadowBlurYShader.hasValue()) + return m_CubeShadowBlurYShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + // vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords.xy = attr_pos.xy;"); + vertexGenerator.Append("}"); + + // This with the ShadowBlurXShader design for a 2-pass 5x5 (sigma=1.0) + // Weights computed using -- http://dev.theomader.com/gaussian-kernel-calculator/ + fragmentGenerator.AddUniform("camera_properties", "vec2"); + fragmentGenerator.AddUniform("depthCube", "samplerCube"); + // fragmentGenerator.AddUniform("depthSrc", "sampler2D"); + fragmentGenerator.Append("layout(location = 0) out vec4 frag0;"); + fragmentGenerator.Append("layout(location = 1) out vec4 frag1;"); + fragmentGenerator.Append("layout(location = 2) out vec4 frag2;"); + fragmentGenerator.Append("layout(location = 3) out vec4 frag3;"); + fragmentGenerator.Append("layout(location = 4) out vec4 frag4;"); + fragmentGenerator.Append("layout(location = 5) out vec4 frag5;"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tfloat ofsScale = camera_properties.x / 2500.0;"); + fragmentGenerator.Append("\tvec3 dir0 = vec3(1.0, -uv_coords.y, -uv_coords.x);"); + fragmentGenerator.Append("\tvec3 dir1 = vec3(-1.0, -uv_coords.y, uv_coords.x);"); + fragmentGenerator.Append("\tvec3 dir2 = vec3(uv_coords.x, 1.0, uv_coords.y);"); + fragmentGenerator.Append("\tvec3 dir3 = vec3(uv_coords.x, -1.0, -uv_coords.y);"); + fragmentGenerator.Append("\tvec3 dir4 = vec3(uv_coords.x, -uv_coords.y, 1.0);"); + fragmentGenerator.Append("\tvec3 dir5 = vec3(-uv_coords.x, -uv_coords.y, -1.0);"); + fragmentGenerator.Append("\tfloat depth0;"); + fragmentGenerator.Append("\tfloat depth1;"); + fragmentGenerator.Append("\tfloat depth2;"); + fragmentGenerator.Append("\tfloat outDepth;"); + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir0).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir0 + vec3(0.0, -ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir0 + vec3(0.0, ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir0 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir0 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag0 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir1).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir1 + vec3(0.0, -ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir1 + vec3(0.0, ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir1 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir1 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag1 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir2).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir2 + vec3(0.0, 0.0, -ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir2 + vec3(0.0, 0.0, ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir2 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir2 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag2 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir3).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir3 + vec3(0.0, 0.0, -ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir3 + vec3(0.0, 0.0, ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir3 + vec3(0.0, 0.0, -2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir3 + vec3(0.0, 0.0, 2.0*ofsScale)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag3 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir4).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir4 + vec3(0.0, -ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir4 + vec3(0.0, ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir4 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir4 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag4 = vec4(outDepth);"); + + fragmentGenerator.Append("\tdepth0 = texture(depthCube, dir5).x;"); + fragmentGenerator.Append( + "\tdepth1 = texture(depthCube, dir5 + vec3(0.0, -ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth1 += texture(depthCube, dir5 + vec3(0.0, ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 = texture(depthCube, dir5 + vec3(0.0, -2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\tdepth2 += texture(depthCube, dir5 + vec3(0.0, 2.0*ofsScale, 0.0)).x;"); + fragmentGenerator.Append( + "\toutDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfrag5 = vec4(outDepth);"); + + fragmentGenerator.Append("}"); + + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "cubemap shadow blur Y shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); + m_CubeShadowBlurYShader = retval; + return m_CubeShadowBlurYShader.getValue(); + } + + SShadowmapPreblurShader *Qt3DSRendererImpl::GetOrthoShadowBlurXShader() + { + if (m_OrthoShadowBlurXShader.hasValue()) + return m_OrthoShadowBlurXShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords.xy = attr_uv.xy;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("camera_properties", "vec2"); + fragmentGenerator.AddUniform("depthSrc", "sampler2D"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec2 ofsScale = vec2( camera_properties.x / 7680.0, 0.0 );"); + fragmentGenerator.Append("\tfloat depth0 = texture(depthSrc, uv_coords).x;"); + fragmentGenerator.Append("\tfloat depth1 = texture(depthSrc, uv_coords + ofsScale).x;"); + fragmentGenerator.Append("\tdepth1 += texture(depthSrc, uv_coords - ofsScale).x;"); + fragmentGenerator.Append( + "\tfloat depth2 = texture(depthSrc, uv_coords + 2.0 * ofsScale).x;"); + fragmentGenerator.Append("\tdepth2 += texture(depthSrc, uv_coords - 2.0 * ofsScale).x;"); + fragmentGenerator.Append( + "\tfloat outDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfragOutput = vec4(outDepth);"); + fragmentGenerator.Append("}"); + + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "shadow map blur X shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); + m_OrthoShadowBlurXShader = retval; + return m_OrthoShadowBlurXShader.getValue(); + } + + SShadowmapPreblurShader *Qt3DSRendererImpl::GetOrthoShadowBlurYShader() + { + if (m_OrthoShadowBlurYShader.hasValue()) + return m_OrthoShadowBlurYShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords.xy = attr_uv.xy;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("camera_properties", "vec2"); + fragmentGenerator.AddUniform("depthSrc", "sampler2D"); + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec2 ofsScale = vec2( 0.0, camera_properties.x / 7680.0 );"); + fragmentGenerator.Append("\tfloat depth0 = texture(depthSrc, uv_coords).x;"); + fragmentGenerator.Append("\tfloat depth1 = texture(depthSrc, uv_coords + ofsScale).x;"); + fragmentGenerator.Append("\tdepth1 += texture(depthSrc, uv_coords - ofsScale).x;"); + fragmentGenerator.Append( + "\tfloat depth2 = texture(depthSrc, uv_coords + 2.0 * ofsScale).x;"); + fragmentGenerator.Append("\tdepth2 += texture(depthSrc, uv_coords - 2.0 * ofsScale).x;"); + fragmentGenerator.Append( + "\tfloat outDepth = 0.38774 * depth0 + 0.24477 * depth1 + 0.06136 * depth2;"); + fragmentGenerator.Append("\tfragOutput = vec4(outDepth);"); + fragmentGenerator.Append("}"); + + NVRenderShaderProgram *theShader = GetProgramGenerator().CompileGeneratedShader( + "shadow map blur Y shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SShadowmapPreblurShader)(*theShader); + m_OrthoShadowBlurYShader = retval; + return m_OrthoShadowBlurYShader.getValue(); + } + +#ifdef ADVANCED_BLEND_SW_FALLBACK + SAdvancedModeBlendShader * + Qt3DSRendererImpl::GetAdvancedBlendModeShader(AdvancedBlendModes::Enum blendMode) + { + // Select between blend equations. + if (blendMode == AdvancedBlendModes::Overlay) { + return GetOverlayBlendModeShader(); + } else if (blendMode == AdvancedBlendModes::ColorBurn) { + return GetColorBurnBlendModeShader(); + } else if (blendMode == AdvancedBlendModes::ColorDodge) { + return GetColorDodgeBlendModeShader(); + } + return {}; + } + + SAdvancedModeBlendShader *Qt3DSRendererImpl::GetOverlayBlendModeShader() + { + if (m_AdvancedModeOverlayBlendShader.hasValue()) + return m_AdvancedModeOverlayBlendShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("base_layer", "sampler2D"); + fragmentGenerator.AddUniform("blend_layer", "sampler2D"); + + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec4 base = texture2D(base_layer, uv_coords);"); + fragmentGenerator.Append("\tif (base.a != 0.0) base.rgb /= base.a;"); + fragmentGenerator.Append("\telse base = vec4(0.0);"); + fragmentGenerator.Append("\tvec4 blend = texture2D(blend_layer, uv_coords);"); + fragmentGenerator.Append("\tif (blend.a != 0.0) blend.rgb /= blend.a;"); + fragmentGenerator.Append("\telse blend = vec4(0.0);"); + + fragmentGenerator.Append("\tvec4 res = vec4(0.0);"); + fragmentGenerator.Append("\tfloat p0 = base.a * blend.a;"); + fragmentGenerator.Append("\tfloat p1 = base.a * (1.0 - blend.a);"); + fragmentGenerator.Append("\tfloat p2 = blend.a * (1.0 - base.a);"); + fragmentGenerator.Append("\tres.a = p0 + p1 + p2;"); + + NVRenderShaderProgram *theShader; + fragmentGenerator.Append( + "\tfloat f_rs_rd = (base.r < 0.5? (2.0 * base.r * blend.r) : " + "(1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r)));"); + fragmentGenerator.Append( + "\tfloat f_gs_gd = (base.g < 0.5? (2.0 * base.g * blend.g) : " + "(1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g)));"); + fragmentGenerator.Append( + "\tfloat f_bs_bd = (base.b < 0.5? (2.0 * base.b * blend.b) : " + "(1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b)));"); + fragmentGenerator.Append("\tres.r = f_rs_rd * p0 + base.r * p1 + blend.r * p2;"); + fragmentGenerator.Append("\tres.g = f_gs_gd * p0 + base.g * p1 + blend.g * p2;"); + fragmentGenerator.Append("\tres.b = f_bs_bd * p0 + base.b * p1 + blend.b * p2;"); + fragmentGenerator.Append("\tgl_FragColor = vec4(res.rgb * res.a, res.a);"); + fragmentGenerator.Append("}"); + theShader = GetProgramGenerator().CompileGeneratedShader( + "advanced overlay shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SAdvancedModeBlendShader)(*theShader); + m_AdvancedModeOverlayBlendShader = retval; + return m_AdvancedModeOverlayBlendShader.getValue(); + } + + SAdvancedModeBlendShader *Qt3DSRendererImpl::GetColorBurnBlendModeShader() + { + if (m_AdvancedModeColorBurnBlendShader.hasValue()) + return m_AdvancedModeColorBurnBlendShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("base_layer", "sampler2D"); + fragmentGenerator.AddUniform("blend_layer", "sampler2D"); + + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec4 base = texture2D(base_layer, uv_coords);"); + fragmentGenerator.Append("\tif (base.a != 0.0) base.rgb /= base.a;"); + fragmentGenerator.Append("\telse base = vec4(0.0);"); + fragmentGenerator.Append("\tvec4 blend = texture2D(blend_layer, uv_coords);"); + fragmentGenerator.Append("\tif (blend.a != 0.0) blend.rgb /= blend.a;"); + fragmentGenerator.Append("\telse blend = vec4(0.0);"); + + fragmentGenerator.Append("\tvec4 res = vec4(0.0);"); + fragmentGenerator.Append("\tfloat p0 = base.a * blend.a;"); + fragmentGenerator.Append("\tfloat p1 = base.a * (1.0 - blend.a);"); + fragmentGenerator.Append("\tfloat p2 = blend.a * (1.0 - base.a);"); + fragmentGenerator.Append("\tres.a = p0 + p1 + p2;"); + + NVRenderShaderProgram *theShader; + fragmentGenerator.Append( + "\tfloat f_rs_rd = ((base.r == 1.0) ? 1.0 : " + "(blend.r == 0.0) ? 0.0 : 1.0 - min(1.0, ((1.0 - base.r) / blend.r)));"); + fragmentGenerator.Append( + "\tfloat f_gs_gd = ((base.g == 1.0) ? 1.0 : " + "(blend.g == 0.0) ? 0.0 : 1.0 - min(1.0, ((1.0 - base.g) / blend.g)));"); + fragmentGenerator.Append( + "\tfloat f_bs_bd = ((base.b == 1.0) ? 1.0 : " + "(blend.b == 0.0) ? 0.0 : 1.0 - min(1.0, ((1.0 - base.b) / blend.b)));"); + fragmentGenerator.Append("\tres.r = f_rs_rd * p0 + base.r * p1 + blend.r * p2;"); + fragmentGenerator.Append("\tres.g = f_gs_gd * p0 + base.g * p1 + blend.g * p2;"); + fragmentGenerator.Append("\tres.b = f_bs_bd * p0 + base.b * p1 + blend.b * p2;"); + fragmentGenerator.Append("\tgl_FragColor = vec4(res.rgb * res.a, res.a);"); + fragmentGenerator.Append("}"); + + theShader = GetProgramGenerator().CompileGeneratedShader( + "advanced colorBurn shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SAdvancedModeBlendShader)(*theShader); + m_AdvancedModeColorBurnBlendShader = retval; + return m_AdvancedModeColorBurnBlendShader.getValue(); + + } + + SAdvancedModeBlendShader *Qt3DSRendererImpl::GetColorDodgeBlendModeShader() + { + if (m_AdvancedModeColorDodgeBlendShader.hasValue()) + return m_AdvancedModeColorDodgeBlendShader.getValue(); + + GetProgramGenerator().BeginProgram(); + + IShaderStageGenerator &vertexGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &fragmentGenerator( + *GetProgramGenerator().GetStage(ShaderGeneratorStages::Fragment)); + vertexGenerator.AddIncoming("attr_pos", "vec3"); + vertexGenerator.AddIncoming("attr_uv", "vec2"); + vertexGenerator.AddOutgoing("uv_coords", "vec2"); + vertexGenerator.Append("void main() {"); + vertexGenerator.Append("\tgl_Position = vec4(attr_pos, 1.0 );"); + vertexGenerator.Append("\tuv_coords = attr_uv;"); + vertexGenerator.Append("}"); + + fragmentGenerator.AddUniform("base_layer", "sampler2D"); + fragmentGenerator.AddUniform("blend_layer", "sampler2D"); + + fragmentGenerator.Append("void main() {"); + fragmentGenerator.Append("\tvec4 base = texture2D(base_layer, uv_coords);"); + fragmentGenerator.Append("\tif (base.a != 0.0) base.rgb /= base.a;"); + fragmentGenerator.Append("\telse base = vec4(0.0);"); + fragmentGenerator.Append("\tvec4 blend = texture2D(blend_layer, uv_coords);"); + fragmentGenerator.Append("\tif (blend.a != 0.0) blend.rgb /= blend.a;"); + fragmentGenerator.Append("\telse blend = vec4(0.0);"); + + fragmentGenerator.Append("\tvec4 res = vec4(0.0);"); + fragmentGenerator.Append("\tfloat p0 = base.a * blend.a;"); + fragmentGenerator.Append("\tfloat p1 = base.a * (1.0 - blend.a);"); + fragmentGenerator.Append("\tfloat p2 = blend.a * (1.0 - base.a);"); + fragmentGenerator.Append("\tres.a = p0 + p1 + p2;"); + + NVRenderShaderProgram *theShader; + fragmentGenerator.Append( + "\tfloat f_rs_rd = ((base.r == 0.0) ? 0.0 : " + "(blend.r == 1.0) ? 1.0 : min(base.r / (1.0 - blend.r), 1.0));"); + fragmentGenerator.Append( + "\tfloat f_gs_gd = ((base.g == 0.0) ? 0.0 : " + "(blend.g == 1.0) ? 1.0 : min(base.g / (1.0 - blend.g), 1.0));"); + fragmentGenerator.Append( + "\tfloat f_bs_bd = ((base.b == 0.0) ? 0.0 : " + "(blend.b == 1.0) ? 1.0 : min(base.b / (1.0 - blend.b), 1.0));"); + fragmentGenerator.Append("\tres.r = f_rs_rd * p0 + base.r * p1 + blend.r * p2;"); + fragmentGenerator.Append("\tres.g = f_gs_gd * p0 + base.g * p1 + blend.g * p2;"); + fragmentGenerator.Append("\tres.b = f_bs_bd * p0 + base.b * p1 + blend.b * p2;"); + + fragmentGenerator.Append("\tgl_FragColor = vec4(res.rgb * res.a, res.a);"); + fragmentGenerator.Append("}"); + theShader = GetProgramGenerator().CompileGeneratedShader( + "advanced colorDodge shader", SShaderCacheProgramFlags(), TShaderFeatureSet()); + NVScopedRefCounted retval; + if (theShader) + retval = QT3DS_NEW(m_Context->GetAllocator(), SAdvancedModeBlendShader)(*theShader); + m_AdvancedModeColorDodgeBlendShader = retval; + return m_AdvancedModeColorDodgeBlendShader.getValue(); + + } +#endif +} +} diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.h new file mode 100644 index 00000000..1ac85dbf --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplShaders.h @@ -0,0 +1,452 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDERER_IMPL_SHADERS_H +#define QT3DS_RENDERER_IMPL_SHADERS_H +#include "Qt3DSRender.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "render/Qt3DSRenderProgramPipeline.h" + +namespace qt3ds { +namespace render { + using qt3ds::render::NVRenderCachedShaderProperty; + using qt3ds::render::NVRenderCachedShaderBuffer; + + /** + * Cached tessellation property lookups this is on a per mesh base + */ + struct SShaderTessellationProperties + { + NVRenderCachedShaderProperty m_EdgeTessLevel; ///< tesselation value for the edges + NVRenderCachedShaderProperty m_InsideTessLevel; ///< tesselation value for the inside + NVRenderCachedShaderProperty + m_PhongBlend; ///< blending between linear and phong component + NVRenderCachedShaderProperty + m_DistanceRange; ///< distance range for min and max tess level + NVRenderCachedShaderProperty m_DisableCulling; ///< if set to 1.0 this disables + ///backface culling optimization in + ///the tess shader + + SShaderTessellationProperties() {} + SShaderTessellationProperties(NVRenderShaderProgram &inShader) + : m_EdgeTessLevel("tessLevelOuter", inShader) + , m_InsideTessLevel("tessLevelInner", inShader) + , m_PhongBlend("phongBlend", inShader) + , m_DistanceRange("distanceRange", inShader) + , m_DisableCulling("disableCulling", inShader) + { + } + }; + + /** + * The results of generating a shader. Caches all possible variable names into + * typesafe objects. + */ + struct SShaderGeneratorGeneratedShader + { + QT3DSU32 m_LayerSetIndex; + CRegisteredString m_QueryString; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_ViewportMatrix; + SShaderTessellationProperties m_Tessellation; + + SShaderGeneratorGeneratedShader(CRegisteredString inQueryString, + NVRenderShaderProgram &inShader) + : m_LayerSetIndex(QT3DS_MAX_U32) + , m_QueryString(inQueryString) + , m_Shader(inShader) + , m_ViewportMatrix("viewport_matrix", inShader) + , m_Tessellation(inShader) + { + m_Shader.addRef(); + } + ~SShaderGeneratorGeneratedShader() { m_Shader.release(); } + static QT3DSU32 GetLayerIndex(const SShaderGeneratorGeneratedShader &inShader) + { + return inShader.m_LayerSetIndex; + } + static void SetLayerIndex(SShaderGeneratorGeneratedShader &inShader, QT3DSU32 idx) + { + inShader.m_LayerSetIndex = idx; + } + }; + + struct SDefaultMaterialRenderableDepthShader + { + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_MVP; + + QT3DSI32 m_RefCount; + SDefaultMaterialRenderableDepthShader(NVRenderShaderProgram &inShader, + NVRenderContext &inContext) + : m_Allocator(inContext.GetAllocator()) + , m_Shader(inShader) + , m_MVP("model_view_projection", inShader) + , m_RefCount(0) + { + m_Shader.addRef(); + } + + ~SDefaultMaterialRenderableDepthShader() { m_Shader.release(); } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + NVDelete(m_Allocator, this); + } + }; + + /** + * Cached texture property lookups, used one per texture so a shader generator for N + * textures will have an array of N of these lookup objects. + */ + struct SShaderTextureProperties + { + NVRenderCachedShaderProperty m_Sampler; + NVRenderCachedShaderProperty m_Offsets; + NVRenderCachedShaderProperty m_Rotations; + SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, + NVRenderShaderProgram &inShader) + : m_Sampler(sampName, inShader) + , m_Offsets(offName, inShader) + , m_Rotations(rotName, inShader) + { + } + SShaderTextureProperties() {} + }; + + struct SRenderableDepthPrepassShader + { + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_MVP; + NVRenderCachedShaderProperty m_GlobalTransform; + NVRenderCachedShaderProperty m_Projection; + NVRenderCachedShaderProperty m_CameraPosition; + NVRenderCachedShaderProperty m_DisplaceAmount; + SShaderTextureProperties m_DisplacementProps; + NVRenderCachedShaderProperty m_CameraProperties; + NVRenderCachedShaderProperty m_CameraDirection; + // NVRenderCachedShaderProperty m_ShadowMV[6]; + + QT3DSI32 m_RefCount; + // Cache the tessellation property name lookups + SShaderTessellationProperties m_Tessellation; + + SRenderableDepthPrepassShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) + : m_Allocator(inContext.GetAllocator()) + , m_Shader(inShader) + , m_MVP("model_view_projection", inShader) + , m_GlobalTransform("model_matrix", inShader) + , m_Projection("projection", inShader) + , m_CameraPosition("camera_position", inShader) + , m_DisplaceAmount("displaceAmount", inShader) + , m_DisplacementProps("displacementSampler", "displacementMap_offset", + "displacementMap_rot", inShader) + , m_CameraProperties("camera_properties", inShader) + , m_CameraDirection("camera_direction", inShader) + , m_RefCount(0) + , m_Tessellation(inShader) + { + /* + m_ShadowMV[0].m_Shader = &inShader; + m_ShadowMV[0].m_Constant = inShader.GetShaderConstant( "shadow_mv0" ); + m_ShadowMV[1].m_Shader = &inShader; + m_ShadowMV[1].m_Constant = inShader.GetShaderConstant( "shadow_mv1" ); + m_ShadowMV[2].m_Shader = &inShader; + m_ShadowMV[2].m_Constant = inShader.GetShaderConstant( "shadow_mv2" ); + m_ShadowMV[3].m_Shader = &inShader; + m_ShadowMV[3].m_Constant = inShader.GetShaderConstant( "shadow_mv3" ); + m_ShadowMV[4].m_Shader = &inShader; + m_ShadowMV[4].m_Constant = inShader.GetShaderConstant( "shadow_mv4" ); + m_ShadowMV[5].m_Shader = &inShader; + m_ShadowMV[5].m_Constant = inShader.GetShaderConstant( "shadow_mv5" ); + */ + m_Shader.addRef(); + } + + ~SRenderableDepthPrepassShader() { m_Shader.release(); } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + NVDelete(m_Allocator, this); + } + }; + + struct SDefaultAoPassShader + { + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_ViewMatrix; + NVRenderCachedShaderProperty m_CameraProperties; + NVRenderCachedShaderProperty m_CameraDirection; + NVRenderCachedShaderProperty m_DepthTexture; + NVRenderCachedShaderProperty m_CubeTexture; + NVRenderCachedShaderProperty m_DepthSamplerSize; + + NVRenderCachedShaderBuffer m_AoShadowParams; + QT3DSI32 m_RefCount; + + SDefaultAoPassShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) + : m_Allocator(inContext.GetAllocator()) + , m_Shader(inShader) + , m_ViewMatrix("view_matrix", inShader) + , m_CameraProperties("camera_properties", inShader) + , m_CameraDirection("camera_direction", inShader) + , m_DepthTexture("depth_sampler", inShader) + , m_CubeTexture("depth_cube", inShader) + , m_DepthSamplerSize("depth_sampler_size", inShader) + , m_AoShadowParams("cbAoShadow", inShader) + , m_RefCount(0) + { + m_Shader.addRef(); + } + ~SDefaultAoPassShader() { m_Shader.release(); } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + NVDelete(m_Allocator, this); + } + }; + + struct STextShader + { + NVRenderShaderProgram &m_Shader; + + NVScopedRefCounted m_ProgramPipeline; + + NVRenderCachedShaderProperty m_MVP; + // Dimensions and offsetting of the image. + NVRenderCachedShaderProperty m_Dimensions; + // The fourth member of text color is the opacity + NVRenderCachedShaderProperty m_TextColor; + NVRenderCachedShaderProperty m_BackgroundColor; + NVRenderCachedShaderProperty m_Sampler; + // Dimensions and offsetting of the texture + NVRenderCachedShaderProperty m_TextDimensions; + NVRenderCachedShaderProperty m_CameraProperties; + // Used only for onscreen text + NVRenderCachedShaderProperty m_VertexOffsets; + + STextShader(NVRenderShaderProgram &shader, NVRenderProgramPipeline *pipeline = NULL) + : m_Shader(shader) + , m_ProgramPipeline(pipeline) + , m_MVP("model_view_projection", shader) + , m_Dimensions("text_dimensions", shader) + , m_TextColor("text_textcolor", shader) + , m_BackgroundColor("text_backgroundcolor", shader) + , m_Sampler("text_image", shader) + , m_TextDimensions("text_textdimensions", shader) + , m_CameraProperties("camera_properties", shader) + , m_VertexOffsets("vertex_offsets", shader) + { + if (!pipeline) + m_Shader.addRef(); + } + ~STextShader() + { + if (!m_ProgramPipeline.mPtr) + m_Shader.release(); + } + void Render(NVRenderTexture2D &inTexture, const STextScaleAndOffset &inScaleAndOffset, + const QT3DSVec4 &inTextColor, const QT3DSMat44 &inMVP, const QT3DSVec2 &inCameraVec, + NVRenderContext &inRenderContext, + NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, + const STextTextureDetails &inTextTextureDetails, + const QT3DSVec3 &inBackgroundColor); + + void RenderPath(NVRenderPathFontItem &inPathFontItem, + NVRenderPathFontSpecification &inPathFontSpec, + const STextScaleAndOffset &inScaleAndOffset, const QT3DSVec4 &inTextColor, + const QT3DSMat44 &inViewProjection, const QT3DSMat44 &inModel, + const QT3DSVec2 &inCameraVec, NVRenderContext &inRenderContext, + const STextTextureDetails &inTextTextureDetails, + const QT3DSVec3 &inBackgroundColor); + + void Render2D(NVRenderTexture2D &inTexture, const QT3DSVec4 &inTextColor, const QT3DSMat44 &inMVP, + NVRenderContext &inRenderContext, + NVRenderInputAssembler &inInputAssemblerBuffer, QT3DSU32 count, + QT3DSVec2 inVertexOffsets); + }; + + struct STextDepthShader + { + NVAllocatorCallback &m_Allocator; + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_MVP; + // Dimensions and offsetting of the image. + NVRenderCachedShaderProperty m_Dimensions; + NVRenderCachedShaderProperty m_TextDimensions; + NVRenderCachedShaderProperty m_CameraProperties; + NVRenderCachedShaderProperty m_Sampler; + NVRenderInputAssembler &m_QuadInputAssembler; + QT3DSI32 m_RefCount; + + STextDepthShader(NVAllocatorCallback &alloc, NVRenderShaderProgram &prog, + NVRenderInputAssembler &assembler) + : m_Allocator(alloc) + , m_Shader(prog) + , m_MVP("model_view_projection", prog) + , m_Dimensions("text_dimensions", prog) + , m_TextDimensions("text_textdimensions", prog) + , m_CameraProperties("camera_properties", prog) + , m_Sampler("text_image", prog) + , m_QuadInputAssembler(assembler) + , m_RefCount(0) + { + m_Shader.addRef(); + } + ~STextDepthShader() { m_Shader.release(); } + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + NVDelete(m_Allocator, this); + } + }; + + struct SLayerProgAABlendShader + { + NVScopedRefCounted m_Shader; + NVRenderCachedShaderProperty m_AccumSampler; + NVRenderCachedShaderProperty m_LastFrame; + NVRenderCachedShaderProperty m_BlendFactors; + volatile QT3DSI32 mRefCount; + SLayerProgAABlendShader(NVRenderShaderProgram &inShader) + : m_Shader(inShader) + , m_AccumSampler("accumulator", inShader) + , m_LastFrame("last_frame", inShader) + , m_BlendFactors("blend_factors", inShader) + , mRefCount(0) + { + } + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator()) + }; + + struct SLayerSceneShader + { + NVRenderShaderProgram &m_Shader; + + NVRenderCachedShaderProperty m_MVP; + // Dimensions and offsetting of the image. + NVRenderCachedShaderProperty m_Dimensions; + // The fourth member of text color is the opacity + NVRenderCachedShaderProperty m_Sampler; + + volatile QT3DSI32 mRefCount; + + SLayerSceneShader(NVRenderShaderProgram &inShader) + : m_Shader(inShader) + , m_MVP("model_view_projection", inShader) + , m_Dimensions("layer_dimensions", inShader) + , m_Sampler("layer_image", inShader) + , mRefCount(0) + { + m_Shader.addRef(); + } + ~SLayerSceneShader() { m_Shader.release(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader.GetRenderContext().GetAllocator()) + }; + + struct SShadowmapPreblurShader + { + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_CameraProperties; + NVRenderCachedShaderProperty m_DepthCube; + NVRenderCachedShaderProperty m_DepthMap; + + volatile QT3DSI32 mRefCount; + + SShadowmapPreblurShader(NVRenderShaderProgram &inShader) + : m_Shader(inShader) + , m_CameraProperties("camera_properties", inShader) + , m_DepthCube("depthCube", inShader) + , m_DepthMap("depthSrc", inShader) + , mRefCount(0) + { + m_Shader.addRef(); + } + ~SShadowmapPreblurShader() { m_Shader.release(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader.GetRenderContext().GetAllocator()) + }; + +#ifdef ADVANCED_BLEND_SW_FALLBACK + struct SAdvancedModeBlendShader + { + NVRenderShaderProgram &m_Shader; + NVRenderCachedShaderProperty m_baseLayer; + NVRenderCachedShaderProperty m_blendLayer; + + volatile QT3DSI32 mRefCount; + + SAdvancedModeBlendShader(NVRenderShaderProgram &inShader) + : m_Shader(inShader) + , m_baseLayer("base_layer", inShader) + , m_blendLayer("blend_layer", inShader) + , mRefCount(0) + { + m_Shader.addRef(); + } + ~SAdvancedModeBlendShader() { m_Shader.release(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader.GetRenderContext().GetAllocator()) + + }; +#endif + + struct SGGSGet + { + QT3DSU32 operator()(const SShaderGeneratorGeneratedShader &inShader) + { + return inShader.m_LayerSetIndex; + } + }; + struct SGGSSet + { + void operator()(SShaderGeneratorGeneratedShader &inShader, QT3DSU32 idx) + { + inShader.m_LayerSetIndex = idx; + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSVertexPipelineImpl.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSVertexPipelineImpl.h new file mode 100644 index 00000000..e2de7e0f --- /dev/null +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSVertexPipelineImpl.h @@ -0,0 +1,435 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_VERTEX_PIPELINE_IMPL_H +#define QT3DS_VERTEX_PIPELINE_IMPL_H +#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" + +namespace qt3ds { +namespace render { + // Baseclass for the vertex pipelines to be sure we have consistent implementations. + struct SVertexPipelineImpl : public IDefaultMaterialVertexPipeline + { + struct GenerationFlagValues + { + enum Enum { + UVCoords = 1, + EnvMapReflection = 1 << 1, + ViewVector = 1 << 2, + WorldNormal = 1 << 3, + ObjectNormal = 1 << 4, + WorldPosition = 1 << 5, + TangentBinormal = 1 << 6, + UVCoords1 = 1 << 7, + VertexColor = 1 << 8, + }; + }; + + typedef TStrTableStrMap::const_iterator TParamIter; + typedef NVFlags TGenerationFlags; + + IMaterialShaderGenerator &m_MaterialGenerator; + IShaderProgramGenerator &m_ProgramGenerator; + IStringTable &m_StringTable; + CRenderString m_TempString; + + TGenerationFlags m_GenerationFlags; + bool m_Wireframe; + TStrTableStrMap m_InterpolationParameters; + QT3DSU32 m_DisplacementIdx; + SRenderableImage *m_DisplacementImage; + QStringList m_addedFunctions; + + SVertexPipelineImpl(NVAllocatorCallback &inAllocator, IMaterialShaderGenerator &inMaterial, + IShaderProgramGenerator &inProgram, IStringTable &inStringTable, + bool inWireframe // only works if tessellation is true + ) + + : m_MaterialGenerator(inMaterial) + , m_ProgramGenerator(inProgram) + , m_StringTable(inStringTable) + , m_Wireframe(inWireframe) + , m_InterpolationParameters(inAllocator, "m_InterpolationParameters") + , m_DisplacementIdx(0) + , m_DisplacementImage(NULL) + { + } + + // Trues true if the code was *not* set. + bool SetCode(GenerationFlagValues::Enum inCode) + { + if (((QT3DSU32)m_GenerationFlags & inCode) != 0) + return true; + m_GenerationFlags |= inCode; + return false; + } + bool HasCode(GenerationFlagValues::Enum inCode) + { + return ((QT3DSU32)(m_GenerationFlags & inCode)) != 0; + } + IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } + IShaderStageGenerator &Vertex() + { + return *ProgramGenerator().GetStage(ShaderGeneratorStages::Vertex); + } + IShaderStageGenerator &TessControl() + { + return *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl); + } + IShaderStageGenerator &TessEval() + { + return *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval); + } + IShaderStageGenerator &Geometry() + { + return *ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry); + } + IShaderStageGenerator &Fragment() + { + return *ProgramGenerator().GetStage(ShaderGeneratorStages::Fragment); + } + IMaterialShaderGenerator &MaterialGenerator() { return m_MaterialGenerator; } + + void SetupDisplacement(QT3DSU32 displacementImageIdx, SRenderableImage *displacementImage) + { + m_DisplacementIdx = displacementImageIdx; + m_DisplacementImage = displacementImage; + } + + CRegisteredString Str(const char8_t *inItem) { return m_StringTable.RegisterStr(inItem); } + + bool HasTessellation() const + { + return m_ProgramGenerator.GetEnabledStages() & ShaderGeneratorStages::TessEval; + } + bool HasGeometryStage() const + { + return m_ProgramGenerator.GetEnabledStages() & ShaderGeneratorStages::Geometry; + } + bool HasDisplacment() const { return m_DisplacementImage != NULL; } + + void InitializeWireframeGeometryShader() + { + if (m_Wireframe && ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry) + && ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)) { + IShaderStageGenerator &geometryShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry)); + // currently geometry shader is only used for drawing wireframe + if (m_Wireframe) { + geometryShader.AddUniform("viewport_matrix", "mat4"); + geometryShader.AddOutgoing("varEdgeDistance", "vec3"); + geometryShader.Append("layout (triangles) in;"); + geometryShader.Append("layout (triangle_strip, max_vertices = 3) out;"); + geometryShader.Append("void main() {"); + + // how this all work see + // http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf + + geometryShader.Append( + "// project points to screen space\n" + "\tvec3 p0 = vec3(viewport_matrix * (gl_in[0].gl_Position / " + "gl_in[0].gl_Position.w));\n" + "\tvec3 p1 = vec3(viewport_matrix * (gl_in[1].gl_Position / " + "gl_in[1].gl_Position.w));\n" + "\tvec3 p2 = vec3(viewport_matrix * (gl_in[2].gl_Position / " + "gl_in[2].gl_Position.w));\n" + "// compute triangle heights\n" + "\tfloat e1 = length(p1 - p2);\n" + "\tfloat e2 = length(p2 - p0);\n" + "\tfloat e3 = length(p1 - p0);\n" + "\tfloat alpha = acos( (e2*e2 + e3*e3 - e1*e1) / (2.0*e2*e3) );\n" + "\tfloat beta = acos( (e1*e1 + e3*e3 - e2*e2) / (2.0*e1*e3) );\n" + "\tfloat ha = abs( e3 * sin( beta ) );\n" + "\tfloat hb = abs( e3 * sin( alpha ) );\n" + "\tfloat hc = abs( e2 * sin( alpha ) );\n"); + } + } + } + + void FinalizeWireframeGeometryShader() + { + IShaderStageGenerator &geometryShader( + *ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry)); + + if (m_Wireframe == true && ProgramGenerator().GetStage(ShaderGeneratorStages::Geometry) + && ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval)) { + const char8_t *theExtension("TE["); + // we always assume triangles + for (int i = 0; i < 3; i++) { + char buf[10]; + sprintf(buf, "%d", i); + for (TStrTableStrMap::const_iterator iter = m_InterpolationParameters.begin(), + end = m_InterpolationParameters.end(); + iter != end; ++iter) { + geometryShader << "\t" << iter->first.c_str() << " = " + << iter->first.c_str() << theExtension << buf << "];\n"; + } + + geometryShader << "\tgl_Position = gl_in[" << buf << "].gl_Position;\n"; + // the triangle distance is interpolated through the shader stage + if (i == 0) + geometryShader << "\n\tvarEdgeDistance = vec3(ha*" + << "gl_in[" << buf << "].gl_Position.w, 0.0, 0.0);\n"; + else if (i == 1) + geometryShader << "\n\tvarEdgeDistance = vec3(0.0, hb*" + << "gl_in[" << buf << "].gl_Position.w, 0.0);\n"; + else if (i == 2) + geometryShader << "\n\tvarEdgeDistance = vec3(0.0, 0.0, hc*" + << "gl_in[" << buf << "].gl_Position.w);\n"; + + // submit vertex + geometryShader << "\tEmitVertex();\n"; + } + // end primitive + geometryShader << "\tEndPrimitive();\n"; + } + } + + virtual void SetupTessIncludes(ShaderGeneratorStages::Enum inStage, + TessModeValues::Enum inTessMode) + { + IShaderStageGenerator &tessShader(*ProgramGenerator().GetStage(inStage)); + + // depending on the selected tessellation mode chose program + switch (inTessMode) { + case TessModeValues::TessPhong: + tessShader.AddInclude("tessellationPhong.glsllib"); + break; + case TessModeValues::TessNPatch: + tessShader.AddInclude("tessellationNPatch.glsllib"); + break; + default: + QT3DS_ASSERT(false); // fallthrough intentional + case TessModeValues::TessLinear: + tessShader.AddInclude("tessellationLinear.glsllib"); + break; + } + } + + void GenerateUVCoords(QT3DSU32 inUVSet = 0) override + { + if (inUVSet == 0 && SetCode(GenerationFlagValues::UVCoords)) + return; + if (inUVSet == 1 && SetCode(GenerationFlagValues::UVCoords1)) + return; + + QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1); + + if (inUVSet == 0) + AddInterpolationParameter("varTexCoord0", "vec2"); + else if (inUVSet == 1) + AddInterpolationParameter("varTexCoord1", "vec2"); + + DoGenerateUVCoords(inUVSet); + } + void GenerateEnvMapReflection() override + { + if (SetCode(GenerationFlagValues::EnvMapReflection)) + return; + + GenerateWorldPosition(); + GenerateWorldNormal(); + IShaderStageGenerator &activeGenerator(ActiveStage()); + activeGenerator.AddInclude("viewProperties.glsllib"); + AddInterpolationParameter("var_object_to_camera", "vec3"); + activeGenerator.Append("\tvar_object_to_camera = normalize( local_model_world_position " + "- camera_position );"); + // World normal cannot be relied upon in the vertex shader because of bump maps. + Fragment().Append("\tvec3 environment_map_reflection = reflect( " + "normalize(var_object_to_camera), world_normal.xyz );"); + Fragment().Append("\tenvironment_map_reflection *= vec3( 0.5, 0.5, 0 );"); + Fragment().Append("\tenvironment_map_reflection += vec3( 0.5, 0.5, 1.0 );"); + } + void GenerateViewVector() override + { + if (SetCode(GenerationFlagValues::ViewVector)) + return; + GenerateWorldPosition(); + IShaderStageGenerator &activeGenerator(ActiveStage()); + activeGenerator.AddInclude("viewProperties.glsllib"); + AddInterpolationParameter("varViewVector", "vec3"); + activeGenerator.Append("\tvec3 local_view_vector = normalize(camera_position - " + "local_model_world_position);"); + AssignOutput("varViewVector", "local_view_vector"); + Fragment() << "\tvec3 view_vector = normalize(varViewVector);" << Endl; + } + + // fragment shader expects varying vertex normal + // lighting in vertex pipeline expects world_normal + void GenerateWorldNormal() override + { + if (SetCode(GenerationFlagValues::WorldNormal)) + return; + AddInterpolationParameter("varNormal", "vec3"); + DoGenerateWorldNormal(); + Fragment().Append("\tvec3 world_normal = normalize( varNormal );"); + } + void GenerateObjectNormal() override + { + if (SetCode(GenerationFlagValues::ObjectNormal)) + return; + DoGenerateObjectNormal(); + Fragment().Append("\tvec3 object_normal = normalize(varObjectNormal);"); + } + void GenerateWorldPosition() override + { + if (SetCode(GenerationFlagValues::WorldPosition)) + return; + + ActiveStage().AddUniform("model_matrix", "mat4"); + AddInterpolationParameter("varWorldPos", "vec3"); + DoGenerateWorldPosition(); + + AssignOutput("varWorldPos", "local_model_world_position"); + } + void GenerateVarTangentAndBinormal() override + { + if (SetCode(GenerationFlagValues::TangentBinormal)) + return; + AddInterpolationParameter("varTangent", "vec3"); + AddInterpolationParameter("varBinormal", "vec3"); + DoGenerateVarTangentAndBinormal(); + Fragment() << "\tvec3 tangent = normalize(varTangent);" << Endl + << "\tvec3 binormal = normalize(varBinormal);" << Endl; + } + void GenerateVertexColor() override + { + if (SetCode(GenerationFlagValues::VertexColor)) + return; + AddInterpolationParameter("varColor", "vec3"); + DoGenerateVertexColor(); + Fragment().Append("\tvec3 vertColor = varColor;"); + } + + bool HasActiveWireframe() override { return m_Wireframe; } + + // IShaderStageGenerator interface + void AddIncoming(const char8_t *name, const char8_t *type) override + { + ActiveStage().AddIncoming(name, type); + } + void AddIncoming(const TStrType &name, const char8_t *type) override + { + AddIncoming(name.c_str(), type); + } + + void AddOutgoing(const char8_t *name, const char8_t *type) override + { + AddInterpolationParameter(name, type); + } + void AddOutgoing(const TStrType &name, const char8_t *type) override + { + AddOutgoing(name.c_str(), type); + } + + void AddUniform(const char8_t *name, const char8_t *type) override + { + ActiveStage().AddUniform(name, type); + } + void AddUniform(const TStrType &name, const char8_t *type) override + { + AddUniform(name.c_str(), type); + } + + void AddInclude(const char8_t *name) override { ActiveStage().AddInclude(name); } + void AddInclude(const TStrType &name) override { AddInclude(name.c_str()); } + void AddInclude(const QString &name) override + { + QByteArray arr = name.toLatin1(); + AddInclude(arr.data()); + } + + void AddFunction(const QString &functionName) override + { + if (!m_addedFunctions.contains(functionName)) { + m_addedFunctions.push_back(functionName); + QString includeName; + QTextStream stream(&includeName); + stream << "func" << functionName << ".glsllib"; + AddInclude(includeName); + } + } + + void AddConstantBuffer(const char *name, const char *layout) override + { + ActiveStage().AddConstantBuffer(name, layout); + } + void AddConstantBufferParam(const char *cbName, const char *paramName, + const char *type) override + { + ActiveStage().AddConstantBufferParam(cbName, paramName, type); + } + + IShaderStageGenerator &operator<<(const char *data) override + { + ActiveStage() << data; + return *this; + } + IShaderStageGenerator &operator<<(const TStrType &data) override + { + ActiveStage() << data; + return *this; + } + IShaderStageGenerator &operator<<(const SEndlType &data) override + { + ActiveStage() << data; + return *this; + } + void Append(const char *data) override { ActiveStage().Append(data); } + void AppendPartial(const char *data) override { ActiveStage().Append(data); } + + ShaderGeneratorStages::Enum Stage() const override + { + return const_cast(this)->ActiveStage().Stage(); + } + + void BeginVertexGeneration(QT3DSU32 displacementImageIdx, + SRenderableImage *displacementImage) override = 0; + void AssignOutput(const char8_t *inVarName, const char8_t *inVarValueExpr) override = 0; + void EndVertexGeneration() override = 0; + + void BeginFragmentGeneration() override = 0; + void EndFragmentGeneration() override = 0; + + virtual IShaderStageGenerator &ActiveStage() = 0; + virtual void AddInterpolationParameter(const char8_t *inParamName, + const char8_t *inParamType) = 0; + + virtual void DoGenerateUVCoords(QT3DSU32 inUVSet) = 0; + virtual void DoGenerateWorldNormal() = 0; + virtual void DoGenerateObjectNormal() = 0; + virtual void DoGenerateWorldPosition() = 0; + virtual void DoGenerateVarTangentAndBinormal() = 0; + virtual void DoGenerateVertexColor() = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.cpp new file mode 100644 index 00000000..963186ff --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.cpp @@ -0,0 +1,326 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderBufferLoader.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSSync.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSRenderThreadPool.h" + +using namespace qt3ds::render; + +namespace { +struct SBufferLoader; +struct SBufferLoadResult : public ILoadedBuffer +{ + NVFoundationBase &m_Foundation; + CRegisteredString m_Path; + IBufferLoaderCallback *m_UserData; + NVDataRef m_Data; + QT3DSI32 mRefCount; + + SBufferLoadResult(NVFoundationBase &fnd, CRegisteredString p, IBufferLoaderCallback *ud, + NVDataRef data) + : m_Foundation(fnd) + , m_Path(p) + , m_UserData(ud) + , m_Data(data) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + CRegisteredString Path() override { return m_Path; } + // Data is released when the buffer itself is released. + NVDataRef Data() override { return m_Data; } + IBufferLoaderCallback *UserData() override { return m_UserData; } + + static SBufferLoadResult *Allocate(QT3DSU32 inBufferSize, NVFoundationBase &fnd, + CRegisteredString p, + NVScopedRefCounted ud) + { + size_t allocSize = sizeof(SBufferLoadResult) + inBufferSize; + QT3DSU8 *allocMem = + (QT3DSU8 *)fnd.getAllocator().allocate(allocSize, "ILoadedBuffer", __FILE__, __LINE__); + if (allocMem == NULL) + return NULL; + QT3DSU8 *bufferStart = allocMem + sizeof(SBufferLoadResult); + NVDataRef dataBuffer = toDataRef(bufferStart, inBufferSize); + return new (allocMem) SBufferLoadResult(fnd, p, ud, dataBuffer); + } +}; +struct SLoadedBufferImpl +{ + SBufferLoader &m_Loader; + QT3DSU64 m_JobId; + QT3DSU64 m_LoadId; + CRegisteredString m_Path; + NVScopedRefCounted m_UserData; + bool m_Quiet; + volatile bool m_Cancel; + NVScopedRefCounted m_Result; + SLoadedBufferImpl *m_NextBuffer; + SLoadedBufferImpl *m_PreviousBuffer; + + SLoadedBufferImpl(SBufferLoader &l, CRegisteredString inPath, + NVScopedRefCounted ud, bool inQuiet, QT3DSU64 loadId) + : m_Loader(l) + , m_JobId(0) + , m_LoadId(loadId) + , m_Path(inPath) + , m_UserData(ud) + , m_Quiet(inQuiet) + , m_Cancel(false) + , m_NextBuffer(NULL) + , m_PreviousBuffer(NULL) + { + } +}; + +DEFINE_INVASIVE_LIST(LoadedBufferImpl); +IMPLEMENT_INVASIVE_LIST(LoadedBufferImpl, m_PreviousBuffer, m_NextBuffer); + +struct SBufferLoader : public IBufferLoader +{ + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_Factory; + NVScopedRefCounted m_ThreadPool; + + Mutex m_BuffersToLoadMutex; + TLoadedBufferImplList m_BuffersToLoad; + + Mutex m_BuffersLoadingMutex; + TLoadedBufferImplList m_BuffersLoading; + + Mutex m_LoadedBuffersMutex; + TLoadedBufferImplList m_LoadedBuffers; + + Sync m_BufferLoadedEvent; + + QT3DSU64 m_NextBufferId; + + QT3DSI32 mRefCount; + + SBufferLoader(NVFoundationBase &fnd, IInputStreamFactory &fac, IThreadPool &tp) + : m_Foundation(fnd) + , m_Factory(fac) + , m_ThreadPool(tp) + , m_BuffersToLoadMutex(fnd.getAllocator()) + , m_BuffersLoadingMutex(fnd.getAllocator()) + , m_LoadedBuffersMutex(fnd.getAllocator()) + , m_BufferLoadedEvent(fnd.getAllocator()) + , m_NextBufferId(1) + , mRefCount(0) + { + m_BufferLoadedEvent.reset(); + } + + virtual ~SBufferLoader() + { + { + Mutex::ScopedLock __locker(m_BuffersToLoadMutex); + for (TLoadedBufferImplList::iterator iter = m_BuffersToLoad.begin(), + end = m_BuffersToLoad.end(); + iter != end; ++iter) { + m_ThreadPool->CancelTask(iter->m_JobId); + } + } + + // Pull any remaining buffers out of the thread system. + while (WillLoadedBuffersBeAvailable()) { + NextLoadedBuffer(); + } + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + static void InitializeActiveLoadingBuffer(SLoadedBufferImpl &theBuffer) + { + Mutex::ScopedLock theLocker(theBuffer.m_Loader.m_BuffersToLoadMutex); + Mutex::ScopedLock theSecondLocker(theBuffer.m_Loader.m_BuffersLoadingMutex); + theBuffer.m_Loader.m_BuffersToLoad.remove(theBuffer); + theBuffer.m_Loader.m_BuffersLoading.push_back(theBuffer); + } + + static void SetBufferAsLoaded(SLoadedBufferImpl &theBuffer) + { + Mutex::ScopedLock theSecondLocker(theBuffer.m_Loader.m_BuffersLoadingMutex); + Mutex::ScopedLock theLocker(theBuffer.m_Loader.m_LoadedBuffersMutex); + theBuffer.m_Loader.m_BuffersLoading.remove(theBuffer); + theBuffer.m_Loader.m_LoadedBuffers.push_back(theBuffer); + theBuffer.m_Loader.m_BufferLoadedEvent.set(); + theBuffer.m_Loader.m_BufferLoadedEvent.reset(); + } + + static void LoadNextBuffer(void *loader) + { + SLoadedBufferImpl &theBuffer = *reinterpret_cast(loader); + + InitializeActiveLoadingBuffer(theBuffer); + NVScopedRefCounted theStream = + theBuffer.m_Loader.m_Factory->GetStreamForFile(theBuffer.m_Path.c_str(), + theBuffer.m_Quiet); + if (theStream && theBuffer.m_Cancel == false) { + theStream->SetPosition(0, SeekPosition::End); + QT3DSI64 theFileLen = theStream->GetPosition(); + if (theFileLen > 0 && theFileLen < (QT3DSU32)QT3DS_MAX_U32) { + QT3DSU32 required = (QT3DSU32)theFileLen; + theBuffer.m_Result = + SBufferLoadResult::Allocate(required, theBuffer.m_Loader.m_Foundation, + theBuffer.m_Path, theBuffer.m_UserData); + QT3DSU32 amountRead = 0; + QT3DSU32 total = amountRead; + if (theBuffer.m_Result && theBuffer.m_Cancel == false) { + NVDataRef theDataBuffer(theBuffer.m_Result->m_Data); + theStream->SetPosition(0, SeekPosition::Begin); + amountRead = theStream->Read(theDataBuffer); + total += amountRead; + // Ensure we keep trying, not all file systems allow huge reads. + while (total < required && amountRead > 0 && theBuffer.m_Cancel == false) { + NVDataRef newBuffer(theDataBuffer.mData + total, required - total); + amountRead = theStream->Read(newBuffer); + total += amountRead; + } + } + if (theBuffer.m_Cancel || total != required) { + theBuffer.m_Result->m_Data = NVDataRef(); + } + } + } + + // only callback if the file was successfully loaded. + if (theBuffer.m_UserData) { + if (theBuffer.m_Cancel == false && theBuffer.m_Result.mPtr + && theBuffer.m_Result->m_Data.size()) { + theBuffer.m_UserData->OnBufferLoaded(*theBuffer.m_Result.mPtr); + } else { + if (theBuffer.m_Cancel) + theBuffer.m_UserData->OnBufferLoadCancelled(theBuffer.m_Path); + else + theBuffer.m_UserData->OnBufferLoadFailed(theBuffer.m_Path); + } + } + + SetBufferAsLoaded(theBuffer); + } + static void CancelNextBuffer(void *loader) + { + SLoadedBufferImpl &theBuffer = *reinterpret_cast(loader); + theBuffer.m_Cancel = true; + InitializeActiveLoadingBuffer(theBuffer); + + if (theBuffer.m_UserData) + theBuffer.m_UserData->OnBufferLoadCancelled(theBuffer.m_Path); + + SetBufferAsLoaded(theBuffer); + } + + // nonblocking. Quiet failure is passed to the input stream factory. + QT3DSU64 QueueForLoading(CRegisteredString inPath, + IBufferLoaderCallback *inUserData = NULL, + bool inQuietFailure = false) override + { + SLoadedBufferImpl &theBuffer = *QT3DS_NEW(m_Foundation.getAllocator(), SLoadedBufferImpl)( + *this, inPath, inUserData, inQuietFailure, m_NextBufferId); + ++m_NextBufferId; + { + Mutex::ScopedLock theLocker(m_BuffersToLoadMutex); + m_BuffersToLoad.push_back(theBuffer); + } + theBuffer.m_JobId = m_ThreadPool->AddTask(&theBuffer, LoadNextBuffer, CancelNextBuffer); + return theBuffer.m_LoadId; + } + + void CancelBufferLoad(QT3DSU64 inBufferId) override + { + { + Mutex::ScopedLock theLocker(m_BuffersToLoadMutex); + SLoadedBufferImpl *theLoadedBuffer = NULL; + for (TLoadedBufferImplList::iterator iter = m_BuffersToLoad.begin(), + end = m_BuffersToLoad.end(); + iter != end && theLoadedBuffer == NULL; ++iter) { + if (iter->m_LoadId == inBufferId) { + theLoadedBuffer = &(*iter); + // both cancellation attempts are necessary. The user will still get + // a load result, it will just have no data. + theLoadedBuffer->m_Cancel = true; + m_ThreadPool->CancelTask(theLoadedBuffer->m_JobId); + } + } + } + } + + // If we were will to wait, will we ever get another buffer + bool WillLoadedBuffersBeAvailable() override + { + Mutex::ScopedLock theLocker(m_BuffersToLoadMutex); + Mutex::ScopedLock theSecondLocker(m_BuffersLoadingMutex); + return AreLoadedBuffersAvailable() || m_BuffersToLoad.empty() == false + || m_BuffersLoading.empty() == false; + } + // Will nextLoadedBuffer block or not? + bool AreLoadedBuffersAvailable() override + { + Mutex::ScopedLock theLocker(m_LoadedBuffersMutex); + return m_LoadedBuffers.empty() == false; + } + + // blocking, be careful with this. No order guarantees here. + NVScopedRefCounted NextLoadedBuffer() override + { + while (!AreLoadedBuffersAvailable()) { + m_BufferLoadedEvent.wait(); + } + SLoadedBufferImpl *theBuffer; + { + Mutex::ScopedLock theLocker(m_LoadedBuffersMutex); + theBuffer = m_LoadedBuffers.back_ptr(); + m_LoadedBuffers.remove(*theBuffer); + } + NVScopedRefCounted retval(theBuffer->m_Result); + if (retval.mPtr == NULL) { + retval = SBufferLoadResult::Allocate(0, m_Foundation, theBuffer->m_Path, + theBuffer->m_UserData); + } + NVDelete(m_Foundation.getAllocator(), theBuffer); + return retval; + } +}; +} + +IBufferLoader &IBufferLoader::Create(NVFoundationBase &fnd, IInputStreamFactory &inFactory, + IThreadPool &inThreadPool) +{ + return *QT3DS_NEW(fnd.getAllocator(), SBufferLoader)(fnd, inFactory, inThreadPool); +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.h new file mode 100644 index 00000000..8d75e259 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferLoader.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BUFFER_LOADED_H +#define QT3DS_RENDER_BUFFER_LOADED_H + +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + class IBufferLoaderCallback; + + class ILoadedBuffer : public NVRefCounted + { + public: + virtual CRegisteredString Path() = 0; + // Data is released when the buffer itself is released. + virtual NVDataRef Data() = 0; + virtual IBufferLoaderCallback *UserData() = 0; + }; + + class IBufferLoaderCallback : public NVRefCounted + { + public: + virtual void OnBufferLoaded(ILoadedBuffer &inBuffer) = 0; + virtual void OnBufferLoadFailed(CRegisteredString inPath) = 0; + virtual void OnBufferLoadCancelled(CRegisteredString inPath) = 0; + }; + + // Job of this object is to load buffers all the way to memory as fast as possible. + class IBufferLoader : public NVRefCounted + { + public: + // nonblocking. Quiet failure is passed to the input stream factory. + // Returns handle to loading buffer + virtual QT3DSU64 QueueForLoading(CRegisteredString inPath, + IBufferLoaderCallback *inUserData = NULL, + bool inQuietFailure = false) = 0; + // Cancel a buffer that has not made it to the loaded buffers list. + virtual void CancelBufferLoad(QT3DSU64 inBufferId) = 0; + // If we were will to wait, will we ever get another buffer + virtual bool WillLoadedBuffersBeAvailable() = 0; + // Will nextLoadedBuffer block or not? + virtual bool AreLoadedBuffersAvailable() = 0; + + // blocking, be careful with this. No guarantees about timely return here. + virtual NVScopedRefCounted NextLoadedBuffer() = 0; + + static IBufferLoader &Create(NVFoundationBase &fnd, IInputStreamFactory &inFactory, + IThreadPool &inThreadPool); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp new file mode 100644 index 00000000..37ca281f --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp @@ -0,0 +1,920 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifdef _WIN32 +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +#endif +#include "Qt3DSRender.h" +#include "Qt3DSRenderBufferManager.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSAllocator.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/hash_map.h" +#include "foundation/FileTools.h" +#include "Qt3DSImportMesh.h" +#include "Qt3DSRenderMesh.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSRenderImageScaler.h" +#include "Qt3DSTextRenderer.h" +#include "foundation/Qt3DSPerfTimer.h" +#include "foundation/Qt3DSMutex.h" +#include "Qt3DSRenderPrefilterTexture.h" +#include + +using namespace qt3ds::render; + +namespace { + +using eastl::hash; +using eastl::pair; +using eastl::make_pair; +typedef eastl::basic_string TStr; +struct StrHasher +{ + size_t operator()(const TStr &str) const + { + return hash()((const char8_t *)str.c_str()); + } +}; + +struct StrEq +{ + bool operator()(const TStr &lhs, const TStr &rhs) const { return lhs == rhs; } +}; + +struct SImageEntry : public SImageTextureData +{ + bool m_Loaded; + SImageEntry() + : m_Loaded(false) + { + } + ~SImageEntry() + { + if (m_BSDFMipMap) + m_BSDFMipMap->release(); + } +}; + +struct SPrimitiveEntry +{ + // Name of the primitive as it will be in the UIP file + CRegisteredString m_PrimitiveName; + // Name of the primitive file on the filesystem + CRegisteredString m_FileName; +}; + +struct SBufferManager : public IBufferManager +{ + typedef eastl::hash_set, + eastl::equal_to, ForwardingAllocator> + TStringSet; + typedef nvhash_map TImageMap; + typedef nvhash_map TMeshMap; + typedef nvhash_map TAliasImageMap; + + NVScopedRefCounted m_Context; + NVScopedRefCounted m_StrTable; + NVScopedRefCounted m_InputStreamFactory; + IPerfTimer &m_PerfTimer; + volatile QT3DSI32 mRefCount; + TStr m_PathBuilder; + TImageMap m_ImageMap; + Mutex m_LoadedImageSetMutex; + TStringSet m_LoadedImageSet; + TAliasImageMap m_AliasImageMap; + TMeshMap m_MeshMap; + SPrimitiveEntry m_PrimitiveNames[5]; + nvvector m_EntryBuffer; + bool m_GPUSupportsDXT; + static const char8_t *GetPrimitivesDirectory() { return "res//primitives"; } + + SBufferManager(NVRenderContext &ctx, IStringTable &strTable, + IInputStreamFactory &inInputStreamFactory, IPerfTimer &inTimer) + : m_Context(ctx) + , m_StrTable(strTable) + , m_InputStreamFactory(inInputStreamFactory) + , m_PerfTimer(inTimer) + , mRefCount(0) + , m_PathBuilder(ForwardingAllocator(ctx.GetAllocator(), "SBufferManager::m_PathBuilder")) + , m_ImageMap(ctx.GetAllocator(), "SBufferManager::m_ImageMap") + , m_LoadedImageSetMutex(ctx.GetAllocator()) + , m_LoadedImageSet( + ForwardingAllocator(ctx.GetAllocator(), "SBufferManager::m_LoadedImageSet")) + , m_AliasImageMap(ctx.GetAllocator(), "SBufferManager::m_AliasImageMap") + , m_MeshMap(ctx.GetAllocator(), "SBufferManager::m_MeshMap") + , m_EntryBuffer(ctx.GetAllocator(), "SBufferManager::m_EntryBuffer") + , m_GPUSupportsDXT(ctx.AreDXTImagesSupported()) + { + } + virtual ~SBufferManager() { Clear(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Context->GetAllocator()) + + CRegisteredString CombineBaseAndRelative(const char8_t *inBase, + const char8_t *inRelative) override + { + CFileTools::CombineBaseAndRelative(inBase, inRelative, m_PathBuilder); + return m_StrTable->RegisterStr(m_PathBuilder.c_str()); + } + + void SetImageHasTransparency(CRegisteredString inImagePath, bool inHasTransparency) override + { + pair theImage = + m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); + theImage.first->second.m_TextureFlags.SetHasTransparency(inHasTransparency); + } + + bool GetImageHasTransparency(CRegisteredString inSourcePath) const override + { + TImageMap::const_iterator theIter = m_ImageMap.find(inSourcePath); + if (theIter != m_ImageMap.end()) + return theIter->second.m_TextureFlags.HasTransparency(); + return false; + } + + void SetImageTransparencyToFalseIfNotSet(CRegisteredString inSourcePath) override + { + pair theImage = + m_ImageMap.insert(make_pair(inSourcePath, SImageEntry())); + // If we did actually insert something + if (theImage.second) + theImage.first->second.m_TextureFlags.SetHasTransparency(false); + } + + void SetInvertImageUVCoords(CRegisteredString inImagePath, bool inShouldInvertCoords) override + { + pair theImage = + m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); + theImage.first->second.m_TextureFlags.SetInvertUVCoords(inShouldInvertCoords); + } + + bool IsImageLoaded(CRegisteredString inSourcePath) override + { + Mutex::ScopedLock __locker(m_LoadedImageSetMutex); + return m_LoadedImageSet.find(inSourcePath) != m_LoadedImageSet.end(); + } + + bool AliasImagePath(CRegisteredString inSourcePath, CRegisteredString inAliasPath, + bool inIgnoreIfLoaded) override + { + if (inSourcePath.IsValid() == false || inAliasPath.IsValid() == false) + return false; + // If the image is loaded then we ignore this call in some cases. + if (inIgnoreIfLoaded && IsImageLoaded(inSourcePath)) + return false; + m_AliasImageMap.insert(eastl::make_pair(inSourcePath, inAliasPath)); + return true; + } + + void UnaliasImagePath(CRegisteredString inSourcePath) override + { + m_AliasImageMap.erase(inSourcePath); + } + + CRegisteredString GetImagePath(CRegisteredString inSourcePath) override + { + TAliasImageMap::iterator theAliasIter = m_AliasImageMap.find(inSourcePath); + if (theAliasIter != m_AliasImageMap.end()) + return theAliasIter->second; + return inSourcePath; + } + + static inline int wrapMod(int a, int base) + { + int ret = a % base; + if (ret < 0) + ret += base; + return ret; + } + + static inline void getWrappedCoords(int &sX, int &sY, int width, int height) + { + if (sY < 0) { + sX -= width >> 1; + sY = -sY; + } + if (sY >= height) { + sX += width >> 1; + sY = height - sY; + } + sX = wrapMod(sX, width); + sY = wrapMod(sY, height); + } + + SImageTextureData LoadRenderImage(CRegisteredString inImagePath, + SLoadedTexture &inLoadedImage, + bool inForceScanForTransparency, bool inBsdfMipmaps) override + { + SStackPerfTimer __perfTimer(m_PerfTimer, "Image Upload"); + { + Mutex::ScopedLock __mapLocker(m_LoadedImageSetMutex); + m_LoadedImageSet.insert(inImagePath); + } + pair theImage = + m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); + bool wasInserted = theImage.second; + theImage.first->second.m_Loaded = true; + // inLoadedImage.EnsureMultiplerOfFour( m_Context->GetFoundation(), inImagePath.c_str() ); + + NVRenderTexture2D *theTexture = m_Context->CreateTexture2D(); + if (inLoadedImage.data) { + qt3ds::render::NVRenderTextureFormats::Enum destFormat = inLoadedImage.format; + if (inBsdfMipmaps) { + if (m_Context->GetRenderContextType() == render::NVRenderContextValues::GLES2) + destFormat = qt3ds::render::NVRenderTextureFormats::RGBA8; + else + destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F; + } + else { + theTexture->SetTextureData( + NVDataRef((QT3DSU8 *)inLoadedImage.data, inLoadedImage.dataSizeInBytes), 0, + inLoadedImage.width, inLoadedImage.height, inLoadedImage.format, destFormat); + } + + if (inBsdfMipmaps + && NVRenderTextureFormats::isUncompressedTextureFormat(inLoadedImage.format)) { + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + Qt3DSRenderPrefilterTexture *theBSDFMipMap = theImage.first->second.m_BSDFMipMap; + if (theBSDFMipMap == NULL) { + theBSDFMipMap = Qt3DSRenderPrefilterTexture::Create( + m_Context, inLoadedImage.width, inLoadedImage.height, *theTexture, + destFormat, m_Context->GetFoundation()); + theImage.first->second.m_BSDFMipMap = theBSDFMipMap; + } + + if (theBSDFMipMap) { + theBSDFMipMap->Build(inLoadedImage.data, inLoadedImage.dataSizeInBytes, + inLoadedImage.format); + } + } + } else if (inLoadedImage.dds) { + theImage.first->second.m_Texture = theTexture; + bool supportsDXT = m_GPUSupportsDXT; + bool isDXT = NVRenderTextureFormats::isCompressedTextureFormat(inLoadedImage.format); + bool requiresDecompression = (supportsDXT == false && isDXT) || false; + // test code for DXT decompression + // if ( isDXT ) requiresDecompression = true; + if (requiresDecompression) { + qCWarning(WARNING, PERF_INFO, + "Image %s is DXT format which is unsupported by " + "the graphics subsystem, decompressing in CPU", + inImagePath.c_str()); + } + STextureData theDecompressedImage; + for (int idx = 0; idx < inLoadedImage.dds->numMipmaps; ++idx) { + if (inLoadedImage.dds->mipwidth[idx] && inLoadedImage.dds->mipheight[idx]) { + if (requiresDecompression == false) { + theTexture->SetTextureData( + toU8DataRef((char *)inLoadedImage.dds->data[idx], + (QT3DSU32)inLoadedImage.dds->size[idx]), + (QT3DSU8)idx, (QT3DSU32)inLoadedImage.dds->mipwidth[idx], + (QT3DSU32)inLoadedImage.dds->mipheight[idx], inLoadedImage.format); + } else { + theDecompressedImage = + inLoadedImage.DecompressDXTImage(idx, &theDecompressedImage); + + if (theDecompressedImage.data) { + theTexture->SetTextureData( + toU8DataRef((char *)theDecompressedImage.data, + (QT3DSU32)theDecompressedImage.dataSizeInBytes), + (QT3DSU8)idx, (QT3DSU32)inLoadedImage.dds->mipwidth[idx], + (QT3DSU32)inLoadedImage.dds->mipheight[idx], + theDecompressedImage.format); + } + } + } + } + if (theDecompressedImage.data) + inLoadedImage.ReleaseDecompressedTexture(theDecompressedImage); + } + if (wasInserted == true || inForceScanForTransparency) + theImage.first->second.m_TextureFlags.SetHasTransparency( + inLoadedImage.ScanForTransparency()); + theImage.first->second.m_Texture = theTexture; + return theImage.first->second; + } + + SImageTextureData LoadRenderImage(CRegisteredString inImagePath, + bool inForceScanForTransparency, bool inBsdfMipmaps) override + { + inImagePath = GetImagePath(inImagePath); + + if (!inImagePath.IsValid()) + return SImageEntry(); + + TImageMap::iterator theIter = m_ImageMap.find(inImagePath); + if (theIter == m_ImageMap.end() && inImagePath.IsValid()) { + NVScopedReleasable theLoadedImage; + { + SStackPerfTimer __perfTimer(m_PerfTimer, "Image Decompression"); + theLoadedImage = SLoadedTexture::Load( + inImagePath.c_str(), m_Context->GetFoundation(), *m_InputStreamFactory, + true, m_Context->GetRenderContextType()); + // Hackish solution to custom materials not finding their textures if they are used + // in sub-presentations. Note: Runtime 1 is going to be removed in Qt 3D Studio 2.x, + // so this should be ok. + if (!theLoadedImage) { + if (QDir(inImagePath.c_str()).isRelative()) { + QString searchPath = inImagePath.c_str(); + if (searchPath.startsWith(QLatin1String("./"))) + searchPath.prepend(QLatin1String(".")); + int loops = 0; + while (!theLoadedImage && ++loops <= 3) { + theLoadedImage = SLoadedTexture::Load( + searchPath.toUtf8(), m_Context->GetFoundation(), + *m_InputStreamFactory, true, + m_Context->GetRenderContextType()); + searchPath.prepend(QLatin1String("../")); + } + } else { + // Some textures, for example environment maps for custom materials, + // have absolute path at this point. It points to the wrong place with + // the new project structure, so we need to split it up and construct + // the new absolute path here. + QString wholePath = inImagePath.c_str(); + QStringList splitPath = wholePath.split(QLatin1String("../")); + if (splitPath.size() > 1) { + QString searchPath = splitPath.at(0) + splitPath.at(1); + int loops = 0; + while (!theLoadedImage && ++loops <= 3) { + theLoadedImage = SLoadedTexture::Load( + searchPath.toUtf8(), m_Context->GetFoundation(), + *m_InputStreamFactory, true, + m_Context->GetRenderContextType()); + searchPath = splitPath.at(0); + for (int i = 0; i < loops; i++) + searchPath.append(QLatin1String("../")); + searchPath.append(splitPath.at(1)); + } + } + } + } + } + + if (theLoadedImage) { + return LoadRenderImage(inImagePath, *theLoadedImage, inForceScanForTransparency, + inBsdfMipmaps); + } else { + // We want to make sure that bad path fails once and doesn't fail over and over + // again + // which could slow down the system quite a bit. + pair theImage = + m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); + theImage.first->second.m_Loaded = true; + qCWarning(WARNING, "Failed to load image: %s", inImagePath.c_str()); + theIter = theImage.first; + } + } + return theIter->second; + } + + qt3dsimp::SMultiLoadResult LoadPrimitive(const char8_t *inRelativePath) + { + CRegisteredString theName(m_StrTable->RegisterStr(inRelativePath)); + if (m_PrimitiveNames[0].m_PrimitiveName.IsValid() == false) { + IStringTable &strTable(m_Context->GetStringTable()); + m_PrimitiveNames[0].m_PrimitiveName = strTable.RegisterStr("#Rectangle"); + m_PrimitiveNames[0].m_FileName = strTable.RegisterStr("Rectangle.mesh"); + m_PrimitiveNames[1].m_PrimitiveName = strTable.RegisterStr("#Sphere"); + m_PrimitiveNames[1].m_FileName = strTable.RegisterStr("Sphere.mesh"); + m_PrimitiveNames[2].m_PrimitiveName = strTable.RegisterStr("#Cube"); + m_PrimitiveNames[2].m_FileName = strTable.RegisterStr("Cube.mesh"); + m_PrimitiveNames[3].m_PrimitiveName = strTable.RegisterStr("#Cone"); + m_PrimitiveNames[3].m_FileName = strTable.RegisterStr("Cone.mesh"); + m_PrimitiveNames[4].m_PrimitiveName = strTable.RegisterStr("#Cylinder"); + m_PrimitiveNames[4].m_FileName = strTable.RegisterStr("Cylinder.mesh"); + } + for (size_t idx = 0; idx < 5; ++idx) { + if (m_PrimitiveNames[idx].m_PrimitiveName == theName) { + CFileTools::CombineBaseAndRelative(GetPrimitivesDirectory(), + m_PrimitiveNames[idx].m_FileName, m_PathBuilder); + QT3DSU32 id = 1; + NVScopedRefCounted theInStream( + m_InputStreamFactory->GetStreamForFile(m_PathBuilder.c_str())); + if (theInStream) + return qt3dsimp::Mesh::LoadMulti(m_Context->GetAllocator(), *theInStream, id); + else { + qCCritical(INTERNAL_ERROR, "Unable to find mesh primitive %s", + m_PathBuilder.c_str()); + return qt3dsimp::SMultiLoadResult(); + } + } + } + return qt3dsimp::SMultiLoadResult(); + } + + virtual NVConstDataRef CreatePackedPositionDataArray(qt3dsimp::SMultiLoadResult *inResult) + { + // we assume a position consists of 3 floats + QT3DSU32 vertexCount = inResult->m_Mesh->m_VertexBuffer.m_Data.size() + / inResult->m_Mesh->m_VertexBuffer.m_Stride; + QT3DSU32 dataSize = vertexCount * 3 * sizeof(QT3DSF32); + QT3DSF32 *posData = (QT3DSF32 *)QT3DS_ALLOC(m_Context->GetAllocator(), dataSize, + "SRenderMesh::CreatePackedPositionDataArray"); + QT3DSU8 *baseOffset = reinterpret_cast(inResult->m_Mesh); + // copy position data + if (posData) { + QT3DSF32 *srcData = (QT3DSF32 *)inResult->m_Mesh->m_VertexBuffer.m_Data.begin(baseOffset); + QT3DSU32 srcStride = inResult->m_Mesh->m_VertexBuffer.m_Stride / sizeof(QT3DSF32); + QT3DSF32 *dstData = posData; + QT3DSU32 dstStride = 3; + + for (QT3DSU32 i = 0; i < vertexCount; ++i) { + dstData[0] = srcData[0]; + dstData[1] = srcData[1]; + dstData[2] = srcData[2]; + + dstData += dstStride; + srcData += srcStride; + } + + return toConstDataRef((const qt3ds::QT3DSU8 *)posData, dataSize); + } + + return NVConstDataRef(); + } + + SRenderMesh *LoadMesh(CRegisteredString inMeshPath) override + { + if (inMeshPath.IsValid() == false) + return NULL; + pair theMesh = + m_MeshMap.insert(make_pair(inMeshPath, (SRenderMesh *)NULL)); + if (theMesh.second == true) { + // check to see if this is primitive + + qt3dsimp::SMultiLoadResult theResult = LoadPrimitive(inMeshPath); + + // Attempt a load from the filesystem if this mesh isn't a primitive. + if (theResult.m_Mesh == NULL) { + m_PathBuilder = inMeshPath; + TStr::size_type pound = m_PathBuilder.rfind('#'); + QT3DSU32 id = 0; + if (pound != TStr::npos) { + id = atoi(m_PathBuilder.c_str() + pound + 1); + m_PathBuilder.erase(m_PathBuilder.begin() + pound, m_PathBuilder.end()); + } + NVScopedRefCounted theStream( + m_InputStreamFactory->GetStreamForFile(m_PathBuilder.c_str())); + if (theStream) { + theResult = qt3dsimp::Mesh::LoadMulti(m_Context->GetAllocator(), *theStream, id); + } + if (theResult.m_Mesh == NULL) + qCWarning(WARNING, "Failed to load mesh: %s", m_PathBuilder.c_str()); + } + + if (theResult.m_Mesh) { + SRenderMesh *theNewMesh = QT3DS_NEW(m_Context->GetAllocator(), SRenderMesh)( + qt3ds::render::NVRenderDrawMode::Triangles, + qt3ds::render::NVRenderWinding::CounterClockwise, theResult.m_Id, + m_Context->GetAllocator()); + QT3DSU8 *baseAddress = reinterpret_cast(theResult.m_Mesh); + theMesh.first->second = theNewMesh; + NVConstDataRef theVBufData( + theResult.m_Mesh->m_VertexBuffer.m_Data.begin(baseAddress), + theResult.m_Mesh->m_VertexBuffer.m_Data.size()); + + NVRenderVertexBuffer *theVertexBuffer = m_Context->CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, + theResult.m_Mesh->m_VertexBuffer.m_Data.m_Size, + theResult.m_Mesh->m_VertexBuffer.m_Stride, theVBufData); + + // create a tight packed position data VBO + // this should improve our depth pre pass rendering + NVRenderVertexBuffer *thePosVertexBuffer = NULL; + NVConstDataRef posData = CreatePackedPositionDataArray(&theResult); + if (posData.size()) { + thePosVertexBuffer = + m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, + posData.size(), 3 * sizeof(QT3DSF32), posData); + } + + NVRenderIndexBuffer *theIndexBuffer = NULL; + if (theResult.m_Mesh->m_IndexBuffer.m_Data.size()) { + using qt3ds::render::NVRenderComponentTypes; + QT3DSU32 theIndexBufferSize = theResult.m_Mesh->m_IndexBuffer.m_Data.size(); + NVRenderComponentTypes::Enum bufComponentType = + theResult.m_Mesh->m_IndexBuffer.m_ComponentType; + QT3DSU32 sizeofType = + qt3ds::render::NVRenderComponentTypes::getSizeofType(bufComponentType); + + if (sizeofType == 2 || sizeofType == 4) { + // Ensure type is unsigned; else things will fail in rendering pipeline. + if (bufComponentType == NVRenderComponentTypes::QT3DSI16) + bufComponentType = NVRenderComponentTypes::QT3DSU16; + if (bufComponentType == NVRenderComponentTypes::QT3DSI32) + bufComponentType = NVRenderComponentTypes::QT3DSU32; + + NVConstDataRef theIBufData( + theResult.m_Mesh->m_IndexBuffer.m_Data.begin(baseAddress), + theResult.m_Mesh->m_IndexBuffer.m_Data.size()); + theIndexBuffer = m_Context->CreateIndexBuffer( + qt3ds::render::NVRenderBufferUsageType::Static, bufComponentType, + theIndexBufferSize, theIBufData); + } else { + QT3DS_ASSERT(false); + } + } + nvvector &theEntryBuffer(m_EntryBuffer); + theEntryBuffer.resize(theResult.m_Mesh->m_VertexBuffer.m_Entries.size()); + for (QT3DSU32 entryIdx = 0, + entryEnd = theResult.m_Mesh->m_VertexBuffer.m_Entries.size(); + entryIdx < entryEnd; ++entryIdx) { + theEntryBuffer[entryIdx] = + theResult.m_Mesh->m_VertexBuffer.m_Entries.index(baseAddress, entryIdx) + .ToVertexBufferEntry(baseAddress); + } + // create our attribute layout + NVRenderAttribLayout *theAttribLayout = + m_Context->CreateAttributeLayout(theEntryBuffer); + // create our attribute layout for depth pass + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry( + "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + }; + NVRenderAttribLayout *theAttribLayoutDepth = + m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 1)); + + // create input assembler object + QT3DSU32 strides = theResult.m_Mesh->m_VertexBuffer.m_Stride; + QT3DSU32 offsets = 0; + NVRenderInputAssembler *theInputAssembler = m_Context->CreateInputAssembler( + theAttribLayout, toConstDataRef(&theVertexBuffer, 1), theIndexBuffer, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), + theResult.m_Mesh->m_DrawMode); + + // create depth input assembler object + QT3DSU32 posStrides = (thePosVertexBuffer) ? 3 * sizeof(QT3DSF32) : strides; + NVRenderInputAssembler *theInputAssemblerDepth = m_Context->CreateInputAssembler( + theAttribLayoutDepth, + toConstDataRef((thePosVertexBuffer) ? &thePosVertexBuffer : &theVertexBuffer, + 1), + theIndexBuffer, toConstDataRef(&posStrides, 1), toConstDataRef(&offsets, 1), + theResult.m_Mesh->m_DrawMode); + + NVRenderInputAssembler *theInputAssemblerPoints = m_Context->CreateInputAssembler( + theAttribLayoutDepth, + toConstDataRef((thePosVertexBuffer) ? &thePosVertexBuffer : &theVertexBuffer, + 1), + NULL, toConstDataRef(&posStrides, 1), toConstDataRef(&offsets, 1), + NVRenderDrawMode::Points); + + if (!theInputAssembler || !theInputAssemblerDepth || !theInputAssemblerPoints) { + QT3DS_ASSERT(false); + return NULL; + } + theNewMesh->m_Joints.resize(theResult.m_Mesh->m_Joints.size()); + for (QT3DSU32 jointIdx = 0, jointEnd = theResult.m_Mesh->m_Joints.size(); + jointIdx < jointEnd; ++jointIdx) { + const qt3dsimp::Joint &theImportJoint( + theResult.m_Mesh->m_Joints.index(baseAddress, jointIdx)); + SRenderJoint &theNewJoint(theNewMesh->m_Joints[jointIdx]); + theNewJoint.m_JointID = theImportJoint.m_JointID; + theNewJoint.m_ParentID = theImportJoint.m_ParentID; + memCopy(theNewJoint.m_invBindPose, theImportJoint.m_invBindPose, + 16 * sizeof(QT3DSF32)); + memCopy(theNewJoint.m_localToGlobalBoneSpace, + theImportJoint.m_localToGlobalBoneSpace, 16 * sizeof(QT3DSF32)); + } + + for (QT3DSU32 subsetIdx = 0, subsetEnd = theResult.m_Mesh->m_Subsets.size(); + subsetIdx < subsetEnd; ++subsetIdx) { + SRenderSubset theSubset(m_Context->GetAllocator()); + const qt3dsimp::MeshSubset &source( + theResult.m_Mesh->m_Subsets.index(baseAddress, subsetIdx)); + theSubset.m_Bounds = source.m_Bounds; + theSubset.m_Count = source.m_Count; + theSubset.m_Offset = source.m_Offset; + theSubset.m_Joints = theNewMesh->m_Joints; + theSubset.m_Name = m_StrTable->RegisterStr(source.m_Name.begin(baseAddress)); + theVertexBuffer->addRef(); + theSubset.m_VertexBuffer = theVertexBuffer; + if (thePosVertexBuffer) { + thePosVertexBuffer->addRef(); + theSubset.m_PosVertexBuffer = thePosVertexBuffer; + } + if (theIndexBuffer) { + theIndexBuffer->addRef(); + theSubset.m_IndexBuffer = theIndexBuffer; + } + theSubset.m_InputAssembler = theInputAssembler; + theSubset.m_InputAssemblerDepth = theInputAssemblerDepth; + theSubset.m_InputAssemblerPoints = theInputAssemblerPoints; + theSubset.m_PrimitiveType = theResult.m_Mesh->m_DrawMode; + theInputAssembler->addRef(); + theInputAssemblerDepth->addRef(); + theSubset.m_InputAssemblerPoints->addRef(); + theNewMesh->m_Subsets.push_back(theSubset); + } +// If we want to, we can an in a quite stupid way break up modes into sub-subsets. +// These are assumed to use the same material as the outer subset but have fewer tris +// and should have a more exact bounding box. This sort of thing helps with using the frustum +// culling +// system but it is really done incorrectly. It should be done via some sort of oct-tree mechanism +// and it +// so that the sub-subsets spatially sorted and it should only be done upon save-to-binary with the +// results +// saved out to disk. As you can see, doing it properly requires some real engineering effort so it +// is somewhat +// unlikely it will ever happen. Or it could be done on import if someone really wants to change +// the mesh buffer +// format. Either way it isn't going to happen here and it isn't going to happen this way but this +// is a working +// example of using the technique. +#ifdef QT3DS_RENDER_GENERATE_SUB_SUBSETS + Option thePosAttrOpt = + theVertexBuffer->GetEntryByName("attr_pos"); + bool hasPosAttr = thePosAttrOpt.hasValue() + && thePosAttrOpt->m_ComponentType == qt3ds::render::NVRenderComponentTypes::QT3DSF32 + && thePosAttrOpt->m_NumComponents == 3; + + for (size_t subsetIdx = 0, subsetEnd = theNewMesh->m_Subsets.size(); + subsetIdx < subsetEnd; ++subsetIdx) { + SRenderSubset &theOuterSubset = theNewMesh->m_Subsets[subsetIdx]; + if (theOuterSubset.m_Count && theIndexBuffer + && theIndexBuffer->GetComponentType() + == qt3ds::render::NVRenderComponentTypes::QT3DSU16 + && theNewMesh->m_DrawMode == NVRenderDrawMode::Triangles && hasPosAttr) { + // Num tris in a sub subset. + QT3DSU32 theSubsetSize = 3334 * 3; // divisible by three. + size_t theNumSubSubsets = + ((theOuterSubset.m_Count - 1) / theSubsetSize) + 1; + QT3DSU32 thePosAttrOffset = thePosAttrOpt->m_FirstItemOffset; + const QT3DSU8 *theVertData = theResult.m_Mesh->m_VertexBuffer.m_Data.begin(); + const QT3DSU8 *theIdxData = theResult.m_Mesh->m_IndexBuffer.m_Data.begin(); + QT3DSU32 theVertStride = theResult.m_Mesh->m_VertexBuffer.m_Stride; + QT3DSU32 theOffset = theOuterSubset.m_Offset; + QT3DSU32 theCount = theOuterSubset.m_Count; + for (size_t subSubsetIdx = 0, subSubsetEnd = theNumSubSubsets; + subSubsetIdx < subSubsetEnd; ++subSubsetIdx) { + SRenderSubsetBase theBase; + theBase.m_Offset = theOffset; + theBase.m_Count = NVMin(theSubsetSize, theCount); + theBase.m_Bounds.setEmpty(); + theCount -= theBase.m_Count; + theOffset += theBase.m_Count; + // Create new bounds. + // Offset is in item size, not bytes. + const QT3DSU16 *theSubsetIdxData = + reinterpret_cast(theIdxData + theBase.m_Offset * 2); + for (size_t theIdxIdx = 0, theIdxEnd = theBase.m_Count; + theIdxIdx < theIdxEnd; ++theIdxIdx) { + QT3DSU32 theVertOffset = theSubsetIdxData[theIdxIdx] * theVertStride; + theVertOffset += thePosAttrOffset; + QT3DSVec3 thePos = *( + reinterpret_cast(theVertData + theVertOffset)); + theBase.m_Bounds.include(thePos); + } + theOuterSubset.m_SubSubsets.push_back(theBase); + } + } else { + SRenderSubsetBase theBase; + theBase.m_Bounds = theOuterSubset.m_Bounds; + theBase.m_Count = theOuterSubset.m_Count; + theBase.m_Offset = theOuterSubset.m_Offset; + theOuterSubset.m_SubSubsets.push_back(theBase); + } + } +#endif + if (posData.size()) + m_Context->GetAllocator().deallocate((void *)posData.begin()); + + m_Context->GetAllocator().deallocate(theResult.m_Mesh); + } + } + return theMesh.first->second; + } + + SRenderMesh *CreateMesh(Qt3DSBCharPtr inSourcePath, QT3DSU8 *inVertData, QT3DSU32 inNumVerts, + QT3DSU32 inVertStride, QT3DSU32 *inIndexData, QT3DSU32 inIndexCount, + qt3ds::NVBounds3 inBounds) override + { + CRegisteredString sourcePath = m_StrTable->RegisterStr(inSourcePath); + + // eastl::pair thePair(sourcePath, (SRenderMesh*)NULL); + pair theMesh; + // Make sure there isn't already a buffer entry for this mesh. + if (m_MeshMap.contains(sourcePath)) { + theMesh = make_pair(m_MeshMap.find(sourcePath), true); + } else { + theMesh = m_MeshMap.insert(make_pair(sourcePath, (SRenderMesh *)NULL)); + } + + if (theMesh.second == true) { + SRenderMesh *theNewMesh = QT3DS_NEW(m_Context->GetAllocator(), SRenderMesh)( + qt3ds::render::NVRenderDrawMode::Triangles, + qt3ds::render::NVRenderWinding::CounterClockwise, 0, m_Context->GetAllocator()); + + // If we failed to create the RenderMesh, return a failure. + if (!theNewMesh) { + QT3DS_ASSERT(false); + return NULL; + } + + // Get rid of any old mesh that was sitting here and fill it with a new one. + // NOTE : This is assuming that the source of our mesh data doesn't do its own memory + // management and always returns new buffer pointers every time. + // Don't know for sure if that's what we'll get from our intended sources, but that's + // easily + // adjustable by looking for matching pointers in the Subsets. + if (theNewMesh && theMesh.first->second != NULL) { + delete theMesh.first->second; + theMesh.first->second = NULL; + } + + theMesh.first->second = theNewMesh; + QT3DSU32 vertDataSize = inNumVerts * inVertStride; + NVConstDataRef theVBufData(inVertData, vertDataSize); + // NVConstDataRef theVBufData( theResult.m_Mesh->m_VertexBuffer.m_Data.begin( + // baseAddress ) + // , theResult.m_Mesh->m_VertexBuffer.m_Data.size() ); + + NVRenderVertexBuffer *theVertexBuffer = + m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, + vertDataSize, inVertStride, theVBufData); + NVRenderIndexBuffer *theIndexBuffer = NULL; + if (inIndexData != NULL && inIndexCount > 3) { + NVConstDataRef theIBufData((QT3DSU8 *)inIndexData, inIndexCount * sizeof(QT3DSU32)); + theIndexBuffer = + m_Context->CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, + qt3ds::render::NVRenderComponentTypes::QT3DSU32, + inIndexCount * sizeof(QT3DSU32), theIBufData); + } + + // WARNING + // Making an assumption here about the contents of the stream + // PKC TODO : We may have to consider some other format. + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry("attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), + qt3ds::render::NVRenderVertexBufferEntry( + "attr_uv", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), + qt3ds::render::NVRenderVertexBufferEntry( + "attr_norm", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3, 18), + }; + + // create our attribute layout + NVRenderAttribLayout *theAttribLayout = + m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 3)); + /* + // create our attribute layout for depth pass + qt3ds::render::NVRenderVertexBufferEntry theEntriesDepth[] = { + qt3ds::render::NVRenderVertexBufferEntry( "attr_pos", + qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3 ), + }; + NVRenderAttribLayout* theAttribLayoutDepth = m_Context->CreateAttributeLayout( + toConstDataRef( theEntriesDepth, 1 ) ); + */ + // create input assembler object + QT3DSU32 strides = inVertStride; + QT3DSU32 offsets = 0; + NVRenderInputAssembler *theInputAssembler = m_Context->CreateInputAssembler( + theAttribLayout, toConstDataRef(&theVertexBuffer, 1), theIndexBuffer, + toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), + qt3ds::render::NVRenderDrawMode::Triangles); + + if (!theInputAssembler) { + QT3DS_ASSERT(false); + return NULL; + } + + // Pull out just the mesh object name from the total path + eastl::string fullName(inSourcePath); + eastl::string subName(inSourcePath); + if (fullName.rfind("#") != eastl::string::npos) { + subName = fullName.substr(fullName.rfind("#"), eastl::string::npos); + } + + theNewMesh->m_Joints.clear(); + SRenderSubset theSubset(m_Context->GetAllocator()); + theSubset.m_Bounds = inBounds; + theSubset.m_Count = inIndexCount; + theSubset.m_Offset = 0; + theSubset.m_Joints = theNewMesh->m_Joints; + theSubset.m_Name = m_StrTable->RegisterStr(subName.c_str()); + theVertexBuffer->addRef(); + theSubset.m_VertexBuffer = theVertexBuffer; + theSubset.m_PosVertexBuffer = NULL; + if (theIndexBuffer) + theIndexBuffer->addRef(); + theSubset.m_IndexBuffer = theIndexBuffer; + theSubset.m_InputAssembler = theInputAssembler; + theSubset.m_InputAssemblerDepth = theInputAssembler; + theSubset.m_InputAssemblerPoints = theInputAssembler; + theSubset.m_PrimitiveType = qt3ds::render::NVRenderDrawMode::Triangles; + theSubset.m_InputAssembler->addRef(); + theSubset.m_InputAssemblerDepth->addRef(); + theSubset.m_InputAssemblerPoints->addRef(); + theNewMesh->m_Subsets.push_back(theSubset); + } + + return theMesh.first->second; + } + + void ReleaseMesh(SRenderMesh &inMesh) + { + for (QT3DSU32 subsetIdx = 0, subsetEnd = inMesh.m_Subsets.size(); subsetIdx < subsetEnd; + ++subsetIdx) { + inMesh.m_Subsets[subsetIdx].m_VertexBuffer->release(); + if (inMesh.m_Subsets[subsetIdx].m_PosVertexBuffer) // can be NULL + inMesh.m_Subsets[subsetIdx].m_PosVertexBuffer->release(); + if (inMesh.m_Subsets[subsetIdx].m_IndexBuffer) // can be NULL + inMesh.m_Subsets[subsetIdx].m_IndexBuffer->release(); + inMesh.m_Subsets[subsetIdx].m_InputAssembler->release(); + inMesh.m_Subsets[subsetIdx].m_InputAssemblerDepth->release(); + if (inMesh.m_Subsets[subsetIdx].m_InputAssemblerPoints) + inMesh.m_Subsets[subsetIdx].m_InputAssemblerPoints->release(); + } + NVDelete(m_Context->GetAllocator(), &inMesh); + } + void ReleaseTexture(SImageEntry &inEntry) + { + if (inEntry.m_Texture) + inEntry.m_Texture->release(); + } + void Clear() override + { + for (TMeshMap::iterator iter = m_MeshMap.begin(), end = m_MeshMap.end(); iter != end; + ++iter) { + SRenderMesh *theMesh = iter->second; + if (theMesh) + ReleaseMesh(*theMesh); + } + m_MeshMap.clear(); + for (TImageMap::iterator iter = m_ImageMap.begin(), end = m_ImageMap.end(); iter != end; + ++iter) { + SImageEntry &theEntry = iter->second; + ReleaseTexture(theEntry); + } + m_ImageMap.clear(); + m_AliasImageMap.clear(); + { + Mutex::ScopedLock __locker(m_LoadedImageSetMutex); + m_LoadedImageSet.clear(); + } + } + void InvalidateBuffer(CRegisteredString inSourcePath) override + { + { + TMeshMap::iterator iter = m_MeshMap.find(inSourcePath); + if (iter != m_MeshMap.end()) { + if (iter->second) + ReleaseMesh(*iter->second); + m_MeshMap.erase(iter); + return; + } + } + { + TImageMap::iterator iter = m_ImageMap.find(inSourcePath); + if (iter != m_ImageMap.end()) { + SImageEntry &theEntry = iter->second; + ReleaseTexture(theEntry); + m_ImageMap.erase(inSourcePath); + { + Mutex::ScopedLock __locker(m_LoadedImageSetMutex); + m_LoadedImageSet.erase(inSourcePath); + } + } + } + } + IStringTable &GetStringTable() override { return *m_StrTable; } +}; +} + +IBufferManager &IBufferManager::Create(NVRenderContext &inRenderContext, IStringTable &inStrTable, + IInputStreamFactory &inFactory, IPerfTimer &inPerfTimer) +{ + return *QT3DS_NEW(inRenderContext.GetAllocator(), SBufferManager)(inRenderContext, inStrTable, + inFactory, inPerfTimer); +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h new file mode 100644 index 00000000..cd9e3d33 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BUFFER_MANAGER_H +#define QT3DS_RENDER_BUFFER_MANAGER_H +#include "Qt3DSRender.h" +#include "EASTL/utility.h" //pair +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderImageTextureData.h" +#include "foundation/Qt3DSBounds3.h" + +namespace qt3ds { +namespace render { + + class IBufferManager : public NVRefCounted + { + protected: + virtual ~IBufferManager() {} + + public: + // Path manipulation used to get the final path form a base path plus relative extension + virtual CRegisteredString CombineBaseAndRelative(const char8_t *inBase, + const char8_t *inRelative) = 0; + virtual void SetImageHasTransparency(CRegisteredString inSourcePath, + bool inHasTransparency) = 0; + virtual bool GetImageHasTransparency(CRegisteredString inSourcePath) const = 0; + virtual void SetImageTransparencyToFalseIfNotSet(CRegisteredString inSourcePath) = 0; + virtual void SetInvertImageUVCoords(CRegisteredString inSourcePath, + bool inShouldInvertCoords) = 0; + + // Returns true if this image has been loaded into memory + // This call is threadsafe. Nothing else on this object is guaranteed to be. + virtual bool IsImageLoaded(CRegisteredString inSourcePath) = 0; + + // Alias one image path with another image path. Optionally this object will ignore the + // call if + // the source path is already loaded. Aliasing is currently used to allow a default image + // to be shown + // in place of an image that is loading offline. + // Returns true if the image was aliased, false otherwise. + virtual bool AliasImagePath(CRegisteredString inSourcePath, CRegisteredString inAliasPath, + bool inIgnoreIfLoaded) = 0; + virtual void UnaliasImagePath(CRegisteredString inSourcePath) = 0; + + // Returns the given source path unless the source path is aliased; in which case returns + // the aliased path. + virtual CRegisteredString GetImagePath(CRegisteredString inSourcePath) = 0; + // Returns a texture and a boolean indicating if this texture has transparency in it or not. + // Can't name this LoadImage because that gets mangled by windows to LoadImageA (uggh) + // In some cases we need to only scan particular images for transparency. + virtual SImageTextureData LoadRenderImage(CRegisteredString inImagePath, + SLoadedTexture &inTexture, + bool inForceScanForTransparency = false, + bool inBsdfMipmaps = false) = 0; + virtual SImageTextureData LoadRenderImage(CRegisteredString inSourcePath, + bool inForceScanForTransparency = false, + bool inBsdfMipmaps = false) = 0; + virtual SRenderMesh *LoadMesh(CRegisteredString inSourcePath) = 0; + + virtual SRenderMesh *CreateMesh(const char *inSourcePath, QT3DSU8 *inVertData, + QT3DSU32 inNumVerts, QT3DSU32 inVertStride, QT3DSU32 *inIndexData, + QT3DSU32 inIndexCount, qt3ds::NVBounds3 inBounds) = 0; + + // Remove *all* buffers from the buffer manager; + virtual void Clear() = 0; + virtual void InvalidateBuffer(CRegisteredString inSourcePath) = 0; + virtual IStringTable &GetStringTable() = 0; + + static IBufferManager &Create(NVRenderContext &inRenderContext, IStringTable &inStrTable, + IInputStreamFactory &inInputStreamFactory, + IPerfTimer &inTimer); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp new file mode 100644 index 00000000..8f1cb14f --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp @@ -0,0 +1,536 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderImageBatchLoader.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StringTable.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderThreadPool.h" +#include "Qt3DSRenderImageScaler.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSPerfTimer.h" + +using namespace qt3ds::render; + +namespace { + +struct SImageLoaderBatch; +typedef Mutex::ScopedLock TScopedLock; + +struct SLoadingImage +{ + SImageLoaderBatch *m_Batch; + CRegisteredString m_SourcePath; + QT3DSU64 m_TaskId; + SLoadingImage *m_Tail; + + // Called from main thread + SLoadingImage(CRegisteredString inSourcePath) + : m_Batch(NULL) + , m_SourcePath(inSourcePath) + , m_TaskId(0) + , m_Tail(NULL) + { + } + SLoadingImage() + : m_Batch(NULL) + , m_TaskId(0) + , m_Tail(NULL) + { + } + // Called from main thread + void Setup(SImageLoaderBatch &inBatch); + + // Called from loader thread + static void LoadImage(void *inImg); + + // Potentially called from loader thread + static void TaskCancelled(void *inImg); +}; + +struct SLoadingImageTailOp +{ + SLoadingImage *get(SLoadingImage &inImg) { return inImg.m_Tail; } + void set(SLoadingImage &inImg, SLoadingImage *inItem) { inImg.m_Tail = inItem; } +}; + +typedef InvasiveSingleLinkedList TLoadingImageList; + +struct SBatchLoader; + +struct SImageLoaderBatch +{ + // All variables setup in main thread and constant from then on except + // loaded image count. + SBatchLoader &m_Loader; + NVScopedRefCounted m_LoadListener; + Sync m_LoadEvent; + Mutex m_LoadMutex; + TLoadingImageList m_Images; + + TImageBatchId m_BatchId; + // Incremented in main thread + QT3DSU32 m_LoadedOrCanceledImageCount; + QT3DSU32 m_FinalizedImageCount; + QT3DSU32 m_NumImages; + NVRenderContextType m_contextType; + bool m_preferKTX; + + // Called from main thread + static SImageLoaderBatch *CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBatchId, + NVConstDataRef inSourcePaths, + CRegisteredString inImageTillLoaded, + IImageLoadListener *inListener, + NVRenderContextType contextType, + bool preferKTX); + + // Called from main thread + SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, + const TLoadingImageList &inImageList, TImageBatchId inBatchId, + QT3DSU32 inImageCount, NVRenderContextType contextType, + bool preferKTX); + + // Called from main thread + ~SImageLoaderBatch(); + + // Called from main thread + bool IsLoadingFinished() + { + Mutex::ScopedLock __locker(m_LoadMutex); + return m_LoadedOrCanceledImageCount >= m_NumImages; + } + + bool IsFinalizedFinished() + { + Mutex::ScopedLock __locker(m_LoadMutex); + return m_FinalizedImageCount >= m_NumImages; + } + + void IncrementLoadedImageCount() + { + Mutex::ScopedLock __locker(m_LoadMutex); + ++m_LoadedOrCanceledImageCount; + } + void IncrementFinalizedImageCount() + { + Mutex::ScopedLock __locker(m_LoadMutex); + ++m_FinalizedImageCount; + } + // Called from main thread + void Cancel(); + void Cancel(CRegisteredString inSourcePath); +}; + +struct SBatchLoadedImage +{ + CRegisteredString m_SourcePath; + SLoadedTexture *m_Texture; + SImageLoaderBatch *m_Batch; + SBatchLoadedImage() + : m_Texture(NULL) + , m_Batch(NULL) + { + } + + // Called from loading thread + SBatchLoadedImage(CRegisteredString inSourcePath, SLoadedTexture *inTexture, + SImageLoaderBatch &inBatch) + : m_SourcePath(inSourcePath) + , m_Texture(inTexture) + , m_Batch(&inBatch) + { + } + + // Called from main thread + bool Finalize(IBufferManager &inMgr); +}; + +struct SBatchLoader : public IImageBatchLoader +{ + typedef nvhash_map TImageLoaderBatchMap; + typedef nvhash_map TSourcePathToBatchMap; + typedef Pool TLoadingImagePool; + typedef Pool TBatchPool; + + // Accessed from loader thread + NVFoundationBase &m_Foundation; + volatile QT3DSI32 mRefCount; + // Accessed from loader thread + IInputStreamFactory &m_InputStreamFactory; + //!!Not threadsafe! accessed only from main thread + IBufferManager &m_BufferManager; + // Accessed from main thread + IThreadPool &m_ThreadPool; + // Accessed from both threads + IPerfTimer &m_PerfTimer; + // main thread + TImageBatchId m_NextBatchId; + // main thread + TImageLoaderBatchMap m_Batches; + // main thread + Mutex m_LoaderMutex; + + // Both loader and main threads + nvvector m_LoadedImages; + // main thread + nvvector m_FinishedBatches; + // main thread + TSourcePathToBatchMap m_SourcePathToBatches; + // main thread + nvvector m_LoaderBuilderWorkspace; + TLoadingImagePool m_LoadingImagePool; + TBatchPool m_BatchPool; + + SBatchLoader(NVFoundationBase &inFoundation, IInputStreamFactory &inFactory, + IBufferManager &inBufferManager, IThreadPool &inThreadPool, IPerfTimer &inTimer) + : m_Foundation(inFoundation) + , mRefCount(0) + , m_InputStreamFactory(inFactory) + , m_BufferManager(inBufferManager) + , m_ThreadPool(inThreadPool) + , m_PerfTimer(inTimer) + , m_NextBatchId(1) + , m_Batches(inFoundation.getAllocator(), "SBatchLoader::m_Batches") + , m_LoaderMutex(inFoundation.getAllocator()) + , m_LoadedImages(inFoundation.getAllocator(), "SBatchLoader::m_LoadedImages") + , m_FinishedBatches(inFoundation.getAllocator(), "SBatchLoader::m_FinishedBatches") + , m_SourcePathToBatches(inFoundation.getAllocator(), "SBatchLoader::m_SourcePathToBatches") + , m_LoaderBuilderWorkspace(inFoundation.getAllocator(), + "SBatchLoader::m_LoaderBuilderWorkspace") + , m_LoadingImagePool( + ForwardingAllocator(inFoundation.getAllocator(), "SBatchLoader::m_LoadingImagePool")) + , m_BatchPool(ForwardingAllocator(inFoundation.getAllocator(), "SBatchLoader::m_BatchPool")) + { + } + + virtual ~SBatchLoader() + { + nvvector theCancelledBatches(m_Foundation.getAllocator(), "~SBatchLoader"); + for (TImageLoaderBatchMap::iterator theIter = m_Batches.begin(), theEnd = m_Batches.end(); + theIter != theEnd; ++theIter) { + theIter->second->Cancel(); + theCancelledBatches.push_back(theIter->second->m_BatchId); + } + for (QT3DSU32 idx = 0, end = theCancelledBatches.size(); idx < end; ++idx) + BlockUntilLoaded(theCancelledBatches[idx]); + + QT3DS_ASSERT(m_Batches.size() == 0); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + // Returns an ID to the load request. Request a block of images to be loaded. + // Also takes an image that the buffer system will return when requested for the given source + // paths + // until said path is loaded. + // An optional listener can be passed in to get callbacks about the batch. + TImageBatchId LoadImageBatch(NVConstDataRef inSourcePaths, + CRegisteredString inImageTillLoaded, + IImageLoadListener *inListener, + NVRenderContextType contextType, + bool preferKTX) override + { + if (inSourcePaths.size() == 0) + return 0; + + TScopedLock __loaderLock(m_LoaderMutex); + + TImageBatchId theBatchId = 0; + + // Empty loop intentional to find an unused batch id. + for (theBatchId = m_NextBatchId; m_Batches.find(theBatchId) != m_Batches.end(); + ++m_NextBatchId, theBatchId = m_NextBatchId) { + } + + SImageLoaderBatch *theBatch(SImageLoaderBatch::CreateLoaderBatch( + *this, theBatchId, inSourcePaths, inImageTillLoaded, inListener, contextType, preferKTX)); + if (theBatch) { + m_Batches.insert(eastl::make_pair(theBatchId, theBatch)); + return theBatchId; + } + return 0; + } + + void CancelImageBatchLoading(TImageBatchId inBatchId) override + { + SImageLoaderBatch *theBatch(GetBatch(inBatchId)); + if (theBatch) + theBatch->Cancel(); + } + + // Blocks if the image is currently in-flight + void CancelImageLoading(CRegisteredString inSourcePath) override + { + TScopedLock __loaderLock(m_LoaderMutex); + TSourcePathToBatchMap::iterator theIter = m_SourcePathToBatches.find(inSourcePath); + if (theIter != m_SourcePathToBatches.end()) { + TImageBatchId theBatchId = theIter->second; + TImageLoaderBatchMap::iterator theBatchIter = m_Batches.find(theBatchId); + if (theBatchIter != m_Batches.end()) + theBatchIter->second->Cancel(inSourcePath); + } + } + + SImageLoaderBatch *GetBatch(TImageBatchId inId) + { + TScopedLock __loaderLock(m_LoaderMutex); + TImageLoaderBatchMap::iterator theIter = m_Batches.find(inId); + if (theIter != m_Batches.end()) + return theIter->second; + return NULL; + } + + void BlockUntilLoaded(TImageBatchId inId) override + { + for (SImageLoaderBatch *theBatch = GetBatch(inId); theBatch; theBatch = GetBatch(inId)) { + // Only need to block if images aren't loaded. Don't need to block if they aren't + // finalized. + if (!theBatch->IsLoadingFinished()) { + theBatch->m_LoadEvent.wait(200); + theBatch->m_LoadEvent.reset(); + } + BeginFrame(); + } + } + void ImageLoaded(SLoadingImage &inImage, SLoadedTexture *inTexture) + { + TScopedLock __loaderLock(m_LoaderMutex); + m_LoadedImages.push_back( + SBatchLoadedImage(inImage.m_SourcePath, inTexture, *inImage.m_Batch)); + inImage.m_Batch->IncrementLoadedImageCount(); + inImage.m_Batch->m_LoadEvent.set(); + } + // These are called by the render context, users don't need to call this. + void BeginFrame() override + { + TScopedLock __loaderLock(m_LoaderMutex); + // Pass 1 - send out all image loaded signals + for (QT3DSU32 idx = 0, end = m_LoadedImages.size(); idx < end; ++idx) { + + m_SourcePathToBatches.erase(m_LoadedImages[idx].m_SourcePath); + m_LoadedImages[idx].Finalize(m_BufferManager); + m_LoadedImages[idx].m_Batch->IncrementFinalizedImageCount(); + if (m_LoadedImages[idx].m_Batch->IsFinalizedFinished()) + m_FinishedBatches.push_back(m_LoadedImages[idx].m_Batch->m_BatchId); + } + m_LoadedImages.clear(); + // pass 2 - clean up any existing batches. + for (QT3DSU32 idx = 0, end = m_FinishedBatches.size(); idx < end; ++idx) { + TImageLoaderBatchMap::iterator theIter = m_Batches.find(m_FinishedBatches[idx]); + if (theIter != m_Batches.end()) { + SImageLoaderBatch *theBatch = theIter->second; + if (theBatch->m_LoadListener) + theBatch->m_LoadListener->OnImageBatchComplete(theBatch->m_BatchId); + m_Batches.erase(m_FinishedBatches[idx]); + theBatch->~SImageLoaderBatch(); + m_BatchPool.deallocate(theBatch); + } + } + m_FinishedBatches.clear(); + } + + void EndFrame() override {} +}; + +void SLoadingImage::Setup(SImageLoaderBatch &inBatch) +{ + m_Batch = &inBatch; + m_TaskId = inBatch.m_Loader.m_ThreadPool.AddTask(this, LoadImage, TaskCancelled); +} + +void SLoadingImage::LoadImage(void *inImg) +{ + SLoadingImage *theThis = reinterpret_cast(inImg); + SStackPerfTimer theTimer(theThis->m_Batch->m_Loader.m_PerfTimer, "Image Decompression"); + if (theThis->m_Batch->m_Loader.m_BufferManager.IsImageLoaded(theThis->m_SourcePath) == false) { + SLoadedTexture *theTexture = SLoadedTexture::Load( + theThis->m_SourcePath.c_str(), theThis->m_Batch->m_Loader.m_Foundation, + theThis->m_Batch->m_Loader.m_InputStreamFactory, true, + theThis->m_Batch->m_contextType, + theThis->m_Batch->m_preferKTX); + // if ( theTexture ) + // theTexture->EnsureMultiplerOfFour( theThis->m_Batch->m_Loader.m_Foundation, + //theThis->m_SourcePath.c_str() ); + + theThis->m_Batch->m_Loader.ImageLoaded(*theThis, theTexture); + } else { + theThis->m_Batch->m_Loader.ImageLoaded(*theThis, NULL); + } +} + +void SLoadingImage::TaskCancelled(void *inImg) +{ + SLoadingImage *theThis = reinterpret_cast(inImg); + theThis->m_Batch->m_Loader.ImageLoaded(*theThis, NULL); +} + +bool SBatchLoadedImage::Finalize(IBufferManager &inMgr) +{ + if (m_Texture) { + // PKC : We'll look at the path location to see if the image is in the standard + // location for IBL light probes or a standard hdr format and decide to generate BSDF + // miplevels (if the image doesn't have + // mipmaps of its own that is). + eastl::string thepath(m_SourcePath); + bool isIBL = (thepath.find(".hdr") != eastl::string::npos) + || (thepath.find("\\IBL\\") != eastl::string::npos) + || (thepath.find("/IBL/") != eastl::string::npos); + inMgr.LoadRenderImage(m_SourcePath, *m_Texture, false, isIBL); + inMgr.UnaliasImagePath(m_SourcePath); + } + if (m_Batch->m_LoadListener) + m_Batch->m_LoadListener->OnImageLoadComplete( + m_SourcePath, m_Texture ? ImageLoadResult::Succeeded : ImageLoadResult::Failed); + + if (m_Texture) { + m_Texture->release(); + return true; + } + + return false; +} + +SImageLoaderBatch * +SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBatchId, + NVConstDataRef inSourcePaths, + CRegisteredString inImageTillLoaded, + IImageLoadListener *inListener, + NVRenderContextType contextType, + bool preferKTX) +{ + TLoadingImageList theImages; + QT3DSU32 theLoadingImageCount = 0; + for (QT3DSU32 idx = 0, end = inSourcePaths.size(); idx < end; ++idx) { + CRegisteredString theSourcePath(inSourcePaths[idx]); + + if (theSourcePath.IsValid() == false) + continue; + + if (inLoader.m_BufferManager.IsImageLoaded(theSourcePath)) + continue; + + eastl::pair theInserter = + inLoader.m_SourcePathToBatches.insert(eastl::make_pair(inSourcePaths[idx], inBatchId)); + + // If the loader has already seen this image. + if (theInserter.second == false) + continue; + + if (inImageTillLoaded.IsValid()) { + // Alias the image so any further requests for this source path will result in + // the default images (image till loaded). + bool aliasSuccess = + inLoader.m_BufferManager.AliasImagePath(theSourcePath, inImageTillLoaded, true); + (void)aliasSuccess; + QT3DS_ASSERT(aliasSuccess); + } + + theImages.push_front( + *inLoader.m_LoadingImagePool.construct(theSourcePath, __FILE__, __LINE__)); + ++theLoadingImageCount; + } + if (theImages.empty() == false) { + SImageLoaderBatch *theBatch = + (SImageLoaderBatch *)inLoader.m_BatchPool.allocate(__FILE__, __LINE__); + new (theBatch) + SImageLoaderBatch(inLoader, inListener, theImages, inBatchId, theLoadingImageCount, + contextType, preferKTX); + return theBatch; + } + return NULL; +} + +SImageLoaderBatch::SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, + const TLoadingImageList &inImageList, TImageBatchId inBatchId, + QT3DSU32 inImageCount, NVRenderContextType contextType, + bool preferKTX) + : m_Loader(inLoader) + , m_LoadListener(inLoadListener) + , m_LoadEvent(inLoader.m_Foundation.getAllocator()) + , m_LoadMutex(inLoader.m_Foundation.getAllocator()) + , m_Images(inImageList) + , m_BatchId(inBatchId) + , m_LoadedOrCanceledImageCount(0) + , m_FinalizedImageCount(0) + , m_NumImages(inImageCount) + , m_contextType(contextType) + , m_preferKTX(preferKTX) +{ + for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; + ++iter) { + iter->Setup(*this); + } +} + +SImageLoaderBatch::~SImageLoaderBatch() +{ + for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; + ++iter) { + TLoadingImageList::iterator temp(iter); + ++iter; + m_Loader.m_LoadingImagePool.deallocate(temp.m_Obj); + } +} + +void SImageLoaderBatch::Cancel() +{ + for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; + ++iter) + m_Loader.m_ThreadPool.CancelTask(iter->m_TaskId); +} + +void SImageLoaderBatch::Cancel(CRegisteredString inSourcePath) +{ + for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; + ++iter) { + if (iter->m_SourcePath == inSourcePath) { + m_Loader.m_ThreadPool.CancelTask(iter->m_TaskId); + break; + } + } +} +} + +IImageBatchLoader &IImageBatchLoader::CreateBatchLoader(NVFoundationBase &inFoundation, + IInputStreamFactory &inFactory, + IBufferManager &inBufferManager, + IThreadPool &inThreadPool, + IPerfTimer &inTimer) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), + SBatchLoader)(inFoundation, inFactory, inBufferManager, inThreadPool, inTimer); +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h new file mode 100644 index 00000000..d45123f1 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_THREADED_IMAGE_LOADER_H +#define QT3DS_RENDER_THREADED_IMAGE_LOADER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSDataRef.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + struct ImageLoadResult + { + enum Enum { + Succeeded, + Failed, + }; + }; + + class IImageLoadListener : public NVRefCounted + { + protected: + virtual ~IImageLoadListener() {} + + public: + virtual void OnImageLoadComplete(CRegisteredString inPath, + ImageLoadResult::Enum inResult) = 0; + virtual void OnImageBatchComplete(QT3DSU64 inBatch) = 0; + }; + + typedef QT3DSU32 TImageBatchId; + + class IImageBatchLoader : public NVRefCounted + { + protected: + virtual ~IImageBatchLoader() {} + + public: + // Returns an ID to the load request. Request a block of images to be loaded. + // Also takes an image that the buffer system will return when requested for the given + // source paths + // until said path is loaded. + // An optional listener can be passed in to get callbacks about the batch. + virtual TImageBatchId LoadImageBatch(NVConstDataRef inSourcePaths, + CRegisteredString inImageTillLoaded, + IImageLoadListener *inListener, + NVRenderContextType type, + bool preferKTX) = 0; + // Blocks if any of the images in the batch are in flight + virtual void CancelImageBatchLoading(TImageBatchId inBatchId) = 0; + // Blocks if the image is currently in-flight + virtual void CancelImageLoading(CRegisteredString inSourcePath) = 0; + // Block until every image in the batch is loaded. + virtual void BlockUntilLoaded(TImageBatchId inId) = 0; + + // These are called by the render context, users don't need to call this. + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; + + static IImageBatchLoader &CreateBatchLoader(NVFoundationBase &inFoundation, + IInputStreamFactory &inFactory, + IBufferManager &inBufferManager, + IThreadPool &inThreadPool, IPerfTimer &inTimer); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp new file mode 100644 index 00000000..3365a2ce --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp @@ -0,0 +1,704 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderLoadedTexture.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSDMWindowsCompatibility.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderImageScaler.h" +#include "Qt3DSTextRenderer.h" +#include + +using namespace qt3ds::render; + +SLoadedTexture *SLoadedTexture::LoadQImage(const QString &inPath, QT3DSI32 flipVertical, + NVFoundationBase &fnd, + NVRenderContextType renderContextType) +{ + Q_UNUSED(flipVertical) + Q_UNUSED(renderContextType) + SLoadedTexture *retval(NULL); + NVAllocatorCallback &alloc(fnd.getAllocator()); + QImage image(inPath); + image = image.mirrored(); + image = image.rgbSwapped(); + retval = QT3DS_NEW(alloc, SLoadedTexture)(alloc); + retval->width = image.width(); + retval->height = image.height(); + retval->components = image.pixelFormat().channelCount(); + retval->image = image; + retval->data = (void*)retval->image.bits(); + retval->dataSizeInBytes = image.byteCount(); + retval->setFormatFromComponents(); + return retval; +} + + +namespace { + +/** + !!Large section of code ripped from FreeImage!! + +*/ +// ---------------------------------------------------------- +// Structures used by DXT textures +// ---------------------------------------------------------- +typedef QT3DSU8 BYTE; +typedef QT3DSU16 WORD; + +typedef struct tagColor8888 +{ + BYTE b; + BYTE g; + BYTE r; + BYTE a; +} Color8888; + +typedef struct tagColor565 +{ + WORD b : 5; + WORD g : 6; + WORD r : 5; +} Color565; + +typedef struct tagDXTColBlock +{ + Color565 colors[2]; + BYTE row[4]; +} DXTColBlock; + +typedef struct tagDXTAlphaBlockExplicit +{ + WORD row[4]; +} DXTAlphaBlockExplicit; + +typedef struct tagDXTAlphaBlock3BitLinear +{ + BYTE alpha[2]; + BYTE data[6]; +} DXTAlphaBlock3BitLinear; + +typedef struct tagDXT1Block +{ + DXTColBlock color; +} DXT1Block; + +typedef struct tagDXT3Block +{ // also used by dxt2 + DXTAlphaBlockExplicit alpha; + DXTColBlock color; +} DXT3Block; + +typedef struct tagDXT5Block +{ // also used by dxt4 + DXTAlphaBlock3BitLinear alpha; + DXTColBlock color; +} DXT5Block; + +static void GetBlockColors(const DXTColBlock &block, Color8888 colors[4], bool isDXT1) +{ + int i; + for (i = 0; i < 2; i++) { + colors[i].a = 0xff; + colors[i].r = (BYTE)(block.colors[i].r * 0xff / 0x1f); + colors[i].g = (BYTE)(block.colors[i].g * 0xff / 0x3f); + colors[i].b = (BYTE)(block.colors[i].b * 0xff / 0x1f); + } + + WORD *wCol = (WORD *)block.colors; + if (wCol[0] > wCol[1] || !isDXT1) { + // 4 color block + for (i = 0; i < 2; i++) { + colors[i + 2].a = 0xff; + colors[i + 2].r = + (BYTE)((WORD(colors[0].r) * (2 - i) + WORD(colors[1].r) * (1 + i)) / 3); + colors[i + 2].g = + (BYTE)((WORD(colors[0].g) * (2 - i) + WORD(colors[1].g) * (1 + i)) / 3); + colors[i + 2].b = + (BYTE)((WORD(colors[0].b) * (2 - i) + WORD(colors[1].b) * (1 + i)) / 3); + } + } else { + // 3 color block, number 4 is transparent + colors[2].a = 0xff; + colors[2].r = (BYTE)((WORD(colors[0].r) + WORD(colors[1].r)) / 2); + colors[2].g = (BYTE)((WORD(colors[0].g) + WORD(colors[1].g)) / 2); + colors[2].b = (BYTE)((WORD(colors[0].b) + WORD(colors[1].b)) / 2); + + colors[3].a = 0x00; + colors[3].g = 0x00; + colors[3].b = 0x00; + colors[3].r = 0x00; + } +} + +struct DXT_INFO_1 +{ + typedef DXT1Block Block; + enum { isDXT1 = 1, bytesPerBlock = 8 }; +}; + +struct DXT_INFO_3 +{ + typedef DXT3Block Block; + enum { isDXT1 = 1, bytesPerBlock = 16 }; +}; + +struct DXT_INFO_5 +{ + typedef DXT5Block Block; + enum { isDXT1 = 1, bytesPerBlock = 16 }; +}; + +template +class DXT_BLOCKDECODER_BASE +{ +protected: + Color8888 m_colors[4]; + const typename INFO::Block *m_pBlock; + unsigned m_colorRow; + +public: + void Setup(const BYTE *pBlock) + { + m_pBlock = (const typename INFO::Block *)pBlock; + GetBlockColors(m_pBlock->color, m_colors, INFO::isDXT1); + } + + void SetY(int y) { m_colorRow = m_pBlock->color.row[y]; } + + void GetColor(int x, int y, Color8888 &color) + { + Q_UNUSED(y) + unsigned bits = (m_colorRow >> (x * 2)) & 3; + color = m_colors[bits]; + std::swap(color.r, color.b); + } +}; + +class DXT_BLOCKDECODER_1 : public DXT_BLOCKDECODER_BASE +{ +public: + typedef DXT_INFO_1 INFO; +}; + +class DXT_BLOCKDECODER_3 : public DXT_BLOCKDECODER_BASE +{ +public: + typedef DXT_BLOCKDECODER_BASE base; + typedef DXT_INFO_3 INFO; + +protected: + unsigned m_alphaRow; + +public: + void SetY(int y) + { + base::SetY(y); + m_alphaRow = m_pBlock->alpha.row[y]; + } + + void GetColor(int x, int y, Color8888 &color) + { + base::GetColor(x, y, color); + const unsigned bits = (m_alphaRow >> (x * 4)) & 0xF; + color.a = (BYTE)((bits * 0xFF) / 0xF); + } +}; + +class DXT_BLOCKDECODER_5 : public DXT_BLOCKDECODER_BASE +{ +public: + typedef DXT_BLOCKDECODER_BASE base; + typedef DXT_INFO_5 INFO; + +protected: + unsigned m_alphas[8]; + unsigned m_alphaBits; + int m_offset; + +public: + void Setup(const BYTE *pBlock) + { + base::Setup(pBlock); + + const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha; + m_alphas[0] = block.alpha[0]; + m_alphas[1] = block.alpha[1]; + if (m_alphas[0] > m_alphas[1]) { + // 8 alpha block + for (int i = 0; i < 6; i++) { + m_alphas[i + 2] = ((6 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 3) / 7; + } + } else { + // 6 alpha block + for (int i = 0; i < 4; i++) { + m_alphas[i + 2] = ((4 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 2) / 5; + } + m_alphas[6] = 0; + m_alphas[7] = 0xFF; + } + } + + void SetY(int y) + { + base::SetY(y); + int i = y / 2; + const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha; + m_alphaBits = unsigned(block.data[0 + i * 3]) | (unsigned(block.data[1 + i * 3]) << 8) + | (unsigned(block.data[2 + i * 3]) << 16); + m_offset = (y & 1) * 12; + } + + void GetColor(int x, int y, Color8888 &color) + { + base::GetColor(x, y, color); + unsigned bits = (m_alphaBits >> (x * 3 + m_offset)) & 7; + color.a = (BYTE)m_alphas[bits]; + std::swap(color.r, color.b); + } +}; + +template +void DecodeDXTBlock(BYTE *dstData, const BYTE *srcBlock, long dstPitch, int bw, int bh) +{ + DECODER decoder; + decoder.Setup(srcBlock); + for (int y = 0; y < bh; y++) { + // Note that this assumes the pointer is pointing to the *last* valid start + // row. + BYTE *dst = dstData - y * dstPitch; + decoder.SetY(y); + for (int x = 0; x < bw; x++) { + decoder.GetColor(x, y, (Color8888 &)*dst); + dst += 4; + } + } +} + +struct STextureDataWriter +{ + QT3DSU32 m_Width; + QT3DSU32 m_Height; + QT3DSU32 m_Stride; + QT3DSU32 m_NumComponents; + STextureData &m_TextureData; + STextureDataWriter(QT3DSU32 w, QT3DSU32 h, bool hasA, STextureData &inTd, NVAllocatorCallback &alloc) + : m_Width(w) + , m_Height(h) + , m_Stride(hasA ? m_Width * 4 : m_Width * 3) + , m_NumComponents(hasA ? 4 : 3) + , m_TextureData(inTd) + { + QT3DSU32 dataSize = m_Stride * m_Height; + if (dataSize > m_TextureData.dataSizeInBytes) { + alloc.deallocate(m_TextureData.data); + m_TextureData.data = + alloc.allocate(dataSize, "SLoadedTexture::DecompressDXTImage", __FILE__, __LINE__); + m_TextureData.dataSizeInBytes = dataSize; + } + memZero(m_TextureData.data, m_TextureData.dataSizeInBytes); + m_TextureData.format = hasA ? NVRenderTextureFormats::RGBA8 : NVRenderTextureFormats::RGB8; + } + + void WritePixel(QT3DSU32 X, QT3DSU32 Y, QT3DSU8 *pixelData) + { + if (X < m_Width && Y < m_Height) { + char *textureData = reinterpret_cast(m_TextureData.data); + QT3DSU32 offset = Y * m_Stride + X * m_NumComponents; + + for (QT3DSU32 idx = 0; idx < m_NumComponents; ++idx) + QT3DS_ASSERT(textureData[offset + idx] == 0); + + memCopy(textureData + offset, pixelData, m_NumComponents); + } + } + + // Incoming pixels are assumed to be RGBA or RGBX, 32 bit in any case + void WriteBlock(QT3DSU32 X, QT3DSU32 Y, QT3DSU32 width, QT3DSU32 height, QT3DSU8 *pixelData) + { + QT3DSU32 offset = 0; + for (QT3DSU32 yidx = 0; yidx < height; ++yidx) { + for (QT3DSU32 xidx = 0; xidx < width; ++xidx, offset += 4) { + WritePixel(X + xidx, Y + (height - yidx - 1), pixelData + offset); + } + } + } + bool Finished() { return false; } +}; + +struct STextureAlphaScanner +{ + bool &m_Alpha; + + STextureAlphaScanner(bool &inAlpha) + : m_Alpha(inAlpha) + { + } + + void WriteBlock(QT3DSU32 X, QT3DSU32 Y, QT3DSU32 width, QT3DSU32 height, QT3DSU8 *pixelData) + { + Q_UNUSED(X) + Q_UNUSED(Y) + QT3DSU32 offset = 0; + for (QT3DSU32 yidx = 0; yidx < height; ++yidx) { + for (QT3DSU32 xidx = 0; xidx < width; ++xidx, offset += 4) { + if (pixelData[offset + 3] < 255) + m_Alpha = true; + } + } + } + + // If we detect alpha we can stop right there. + bool Finished() { return m_Alpha; } +}; +// Scan the dds image's mipmap 0 level for alpha. +template +static void DecompressDDS(void *inSrc, QT3DSU32 inDataSize, QT3DSU32 inWidth, QT3DSU32 inHeight, + TWriterType ioWriter) +{ + typedef typename DECODER::INFO INFO; + typedef typename INFO::Block Block; + (void)inDataSize; + + const QT3DSU8 *pbSrc = (const QT3DSU8 *)inSrc; + // Each DX block is composed of 16 pixels. Free image decodes those + // pixels into a 4x4 block of data. + QT3DSU8 pbDstData[4 * 4 * 4]; + // The decoder decodes backwards + // So we need to point to the last line. + QT3DSU8 *pbDst = pbDstData + 48; + + int width = (int)inWidth; + int height = (int)inHeight; + int lineStride = 16; + for (int y = 0; y < height && ioWriter.Finished() == false; y += 4) { + int yPixels = NVMin(height - y, 4); + for (int x = 0; x < width && ioWriter.Finished() == false; x += 4) { + int xPixels = NVMin(width - x, 4); + DecodeDXTBlock(pbDst, pbSrc, lineStride, xPixels, yPixels); + pbSrc += INFO::bytesPerBlock; + ioWriter.WriteBlock(x, y, xPixels, yPixels, pbDstData); + } + } +} + +bool ScanDDSForAlpha(Qt3DSDDSImage *dds) +{ + bool hasAlpha = false; + switch (dds->format) { + case qt3ds::render::NVRenderTextureFormats::RGBA_DXT1: + DecompressDDS(dds->data[0], dds->size[0], dds->mipwidth[0], + dds->mipheight[0], STextureAlphaScanner(hasAlpha)); + break; + case qt3ds::render::NVRenderTextureFormats::RGBA_DXT3: + DecompressDDS(dds->data[0], dds->size[0], dds->mipwidth[0], + dds->mipheight[0], STextureAlphaScanner(hasAlpha)); + break; + case qt3ds::render::NVRenderTextureFormats::RGBA_DXT5: + DecompressDDS(dds->data[0], dds->size[0], dds->mipwidth[0], + dds->mipheight[0], STextureAlphaScanner(hasAlpha)); + break; + default: + QT3DS_ASSERT(false); + break; + } + return hasAlpha; +} + +bool ScanImageForAlpha(const void *inData, QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 inPixelSizeInBytes, + QT3DSU8 inAlphaSizeInBits) +{ + const QT3DSU8 *rowPtr = reinterpret_cast(inData); + bool hasAlpha = false; + if (inAlphaSizeInBits == 0) + return hasAlpha; + if (inPixelSizeInBytes != 2 && inPixelSizeInBytes != 4) { + QT3DS_ASSERT(false); + return false; + } + if (inAlphaSizeInBits > 8) { + QT3DS_ASSERT(false); + return false; + } + + QT3DSU32 alphaRightShift = inPixelSizeInBytes * 8 - inAlphaSizeInBits; + QT3DSU32 maxAlphaValue = (1 << inAlphaSizeInBits) - 1; + + for (QT3DSU32 rowIdx = 0; rowIdx < inHeight && hasAlpha == false; ++rowIdx) { + for (QT3DSU32 idx = 0; idx < inWidth && hasAlpha == false; + ++idx, rowPtr += inPixelSizeInBytes) { + QT3DSU32 pixelValue = 0; + if (inPixelSizeInBytes == 2) + pixelValue = *(reinterpret_cast(rowPtr)); + else + pixelValue = *(reinterpret_cast(rowPtr)); + pixelValue = pixelValue >> alphaRightShift; + if (pixelValue < maxAlphaValue) + hasAlpha = true; + } + } + return hasAlpha; +} +} + +SLoadedTexture::~SLoadedTexture() +{ + if (dds) { + if (dds->dataBlock) + QT3DS_FREE(m_Allocator, dds->dataBlock); + + QT3DS_FREE(m_Allocator, dds); + } else if (data && image.byteCount() <= 0) { + m_Allocator.deallocate(data); + } + if (m_Palette) + m_Allocator.deallocate(m_Palette); + if (m_TransparencyTable) + m_Allocator.deallocate(m_TransparencyTable); +} + +void SLoadedTexture::release() +{ + NVAllocatorCallback *theAllocator(&m_Allocator); + this->~SLoadedTexture(); + theAllocator->deallocate(this); +} + +bool SLoadedTexture::ScanForTransparency() +{ + switch (format) { + case NVRenderTextureFormats::SRGB8A8: + case NVRenderTextureFormats::RGBA8: + if (!data) { // dds + return true; + } else { + return ScanImageForAlpha(data, width, height, 4, 8); + } + break; + // Scan the image. + case NVRenderTextureFormats::SRGB8: + case NVRenderTextureFormats::RGB8: + return false; + break; + case NVRenderTextureFormats::RGB565: + return false; + break; + case NVRenderTextureFormats::RGBA5551: + if (!data) { // dds + return true; + } else { + return ScanImageForAlpha(data, width, height, 2, 1); + } + break; + case NVRenderTextureFormats::Alpha8: + return true; + break; + case NVRenderTextureFormats::Luminance8: + return false; + break; + case NVRenderTextureFormats::LuminanceAlpha8: + if (!data) { // dds + return true; + } else { + return ScanImageForAlpha(data, width, height, 2, 8); + } + break; + case NVRenderTextureFormats::RGB_DXT1: + return false; + break; + case NVRenderTextureFormats::RGBA_DXT3: + case NVRenderTextureFormats::RGBA_DXT1: + case NVRenderTextureFormats::RGBA_DXT5: + if (dds) { + return ScanDDSForAlpha(dds); + } else { + QT3DS_ASSERT(false); + return false; + } + break; + case NVRenderTextureFormats::RGB9E5: + return false; + break; + case NVRenderTextureFormats::RG32F: + case NVRenderTextureFormats::RGB32F: + case NVRenderTextureFormats::RGBA16F: + case NVRenderTextureFormats::RGBA32F: + // PKC TODO : For now, since IBL will be the main consumer, we'll just pretend there's no + // alpha. + // Need to do a proper scan down the line, but doing it for floats is a little different + // from + // integer scans. + return false; + break; + default: + break; + } + QT3DS_ASSERT(false); + return false; +} + +void SLoadedTexture::EnsureMultiplerOfFour(NVFoundationBase &inFoundation, const char *inPath) +{ + if (width % 4 || height % 4) { + qCWarning(PERF_WARNING, + "Image %s has non multiple of four width or height; perf hit for scaling", inPath); + if (data) { + QT3DSU32 newWidth = ITextRenderer::NextMultipleOf4(width); + QT3DSU32 newHeight = ITextRenderer::NextMultipleOf4(height); + QT3DSU32 newDataSize = newWidth * newHeight * components; + NVAllocatorCallback &theAllocator(inFoundation.getAllocator()); + QT3DSU8 *newData = (QT3DSU8 *)(theAllocator.allocate(newDataSize, "Scaled Image Data", + __FILE__, __LINE__)); + CImageScaler theScaler(theAllocator); + if (components == 4) { + theScaler.FastExpandRowsAndColumns((unsigned char *)data, width, height, newData, + newWidth, newHeight); + } else + theScaler.ExpandRowsAndColumns((unsigned char *)data, width, height, newData, + newWidth, newHeight, components); + + theAllocator.deallocate(data); + data = newData; + width = newWidth; + height = newHeight; + dataSizeInBytes = newDataSize; + } + } +} + +STextureData SLoadedTexture::DecompressDXTImage(int inMipMapIdx, STextureData *inOptLastImage) +{ + STextureData retval; + if (inOptLastImage) + retval = *inOptLastImage; + + if (dds == NULL || inMipMapIdx >= dds->numMipmaps) { + QT3DS_ASSERT(false); + ReleaseDecompressedTexture(retval); + return STextureData(); + } + char *srcData = (char *)dds->data[inMipMapIdx]; + int srcDataSize = dds->size[inMipMapIdx]; + QT3DSU32 imgWidth = (QT3DSU32)dds->mipwidth[inMipMapIdx]; + QT3DSU32 imgHeight = (QT3DSU32)dds->mipheight[inMipMapIdx]; + + switch (format) { + case NVRenderTextureFormats::RGB_DXT1: + DecompressDDS( + srcData, srcDataSize, imgWidth, imgHeight, + STextureDataWriter(imgWidth, imgHeight, false, retval, m_Allocator)); + break; + case NVRenderTextureFormats::RGBA_DXT1: + DecompressDDS( + srcData, srcDataSize, imgWidth, imgHeight, + STextureDataWriter(imgWidth, imgHeight, true, retval, m_Allocator)); + break; + case NVRenderTextureFormats::RGBA_DXT3: + DecompressDDS( + srcData, srcDataSize, imgWidth, imgHeight, + STextureDataWriter(imgWidth, imgHeight, true, retval, m_Allocator)); + break; + case NVRenderTextureFormats::RGBA_DXT5: + DecompressDDS( + srcData, srcDataSize, imgWidth, imgHeight, + STextureDataWriter(imgWidth, imgHeight, true, retval, m_Allocator)); + break; + default: + QT3DS_ASSERT(false); + break; + } + return retval; +} + +void SLoadedTexture::ReleaseDecompressedTexture(STextureData inImage) +{ + if (inImage.data) + m_Allocator.deallocate(inImage.data); +} + +#ifndef EA_PLATFORM_WINDOWS +#define stricmp strcasecmp +#endif + +SLoadedTexture *SLoadedTexture::Load(const QString &inPath, NVFoundationBase &inFoundation, + IInputStreamFactory &inFactory, bool inFlipY, + NVRenderContextType renderContextType, bool preferKTX) +{ + if (inPath.isEmpty()) + return nullptr; + + // Check KTX path first + QString path = inPath; + QString ktxSource = inPath; + if (preferKTX) { + ktxSource = ktxSource.left(ktxSource.lastIndexOf(QLatin1Char('.'))); + ktxSource.append(QLatin1String(".ktx")); + } + + SLoadedTexture *theLoadedImage = nullptr; + // We will get invalid error logs of files not found if we don't force quiet mode + // If the file is actually missing, it will be logged later (loaded image is null) + NVScopedRefCounted theStream( + inFactory.GetStreamForFile(preferKTX ? ktxSource : inPath, true)); + if (!theStream.mPtr) { + if (!preferKTX) + theStream = inFactory.GetStreamForFile(inPath, true); + else + return nullptr; + } else { + path = ktxSource; + } + QString fileName; + inFactory.GetPathForFile(path, fileName, true); + if (theStream.mPtr && path.size() > 3) { + if (path.endsWith(QLatin1String("png"), Qt::CaseInsensitive) + || path.endsWith(QLatin1String("jpg"), Qt::CaseInsensitive) + || path.endsWith(QLatin1String("peg"), Qt::CaseInsensitive)) { + theLoadedImage = LoadQImage(fileName, inFlipY, inFoundation, renderContextType); + } else if (path.endsWith(QLatin1String("dds"), Qt::CaseInsensitive)) { + theLoadedImage = LoadDDS(*theStream, inFlipY, inFoundation, renderContextType); + } else if (path.endsWith(QLatin1String("gif"), Qt::CaseInsensitive)) { + theLoadedImage = LoadGIF(*theStream, !inFlipY, inFoundation, renderContextType); + } else if (path.endsWith(QLatin1String("bmp"), Qt::CaseInsensitive)) { + theLoadedImage = LoadBMP(*theStream, !inFlipY, inFoundation, renderContextType); + } else if (path.endsWith(QLatin1String("hdr"), Qt::CaseInsensitive)) { + theLoadedImage = LoadHDR(*theStream, inFoundation, renderContextType); + } else if (path.endsWith(QLatin1String("ktx"), Qt::CaseInsensitive)) { + theLoadedImage = LoadKTX(*theStream, inFlipY, inFoundation, renderContextType); + } else { + qCWarning(INTERNAL_ERROR, "Unrecognized image extension: %s", qPrintable(inPath)); + } + } + + return theLoadedImage; +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h new file mode 100644 index 00000000..f0194000 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_LOADED_TEXTURE_H +#define QT3DS_RENDER_LOADED_TEXTURE_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "Qt3DSRenderLoadedTextureDDS.h" +#include "foundation/Qt3DSRefCounted.h" +#include + +namespace qt3ds { +namespace foundation { + class ISeekableIOStream; + class IInStream; +} +} + +namespace qt3ds { +namespace render { + + class IInputStreamFactory; + + struct STextureData + { + void *data; + QT3DSU32 dataSizeInBytes; + qt3ds::render::NVRenderTextureFormats::Enum format; + STextureData() + : data(NULL) + , dataSizeInBytes(0) + , format(qt3ds::render::NVRenderTextureFormats::Unknown) + { + } + }; + struct ExtendedTextureFormats + { + enum Enum { + NoExtendedFormat = 0, + Palettized, + CustomRGB, + }; + }; + // Utility class used for loading image data from disk. + // Supports jpg, png, and dds. + struct SLoadedTexture : public NVReleasable + { + private: + ~SLoadedTexture(); + + public: + NVAllocatorCallback &m_Allocator; + QT3DSI32 width; + QT3DSI32 height; + QT3DSI32 components; + void *data; + QImage image; + QT3DSU32 dataSizeInBytes; + qt3ds::render::NVRenderTextureFormats::Enum format; + Qt3DSDDSImage *dds; + ExtendedTextureFormats::Enum m_ExtendedFormat; + // Used for palettized images. + void *m_Palette; + QT3DSI32 m_CustomMasks[3]; + int m_BitCount; + char8_t m_BackgroundColor[3]; + uint8_t *m_TransparencyTable; + int32_t m_TransparentPaletteIndex; + + SLoadedTexture(NVAllocatorCallback &inAllocator) + : m_Allocator(inAllocator) + , width(0) + , height(0) + , components(0) + , data(NULL) + , image(0) + , dataSizeInBytes(0) + , format(qt3ds::render::NVRenderTextureFormats::RGBA8) + , dds(NULL) + , m_ExtendedFormat(ExtendedTextureFormats::NoExtendedFormat) + , m_Palette(NULL) + , m_BitCount(0) + , m_TransparencyTable(NULL) + , m_TransparentPaletteIndex(-1) + { + m_CustomMasks[0] = 0; + m_CustomMasks[1] = 0; + m_CustomMasks[2] = 0; + m_BackgroundColor[0] = 0; + m_BackgroundColor[1] = 0; + m_BackgroundColor[2] = 0; + } + void setFormatFromComponents() + { + switch (components) { + case 1: // undefined, but in this context probably luminance + format = qt3ds::render::NVRenderTextureFormats::Luminance8; + break; + case 2: + format = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; + break; + case 3: + format = qt3ds::render::NVRenderTextureFormats::RGB8; + break; + + default: + // fallthrough intentional + case 4: + format = qt3ds::render::NVRenderTextureFormats::RGBA8; + break; + } + } + + void EnsureMultiplerOfFour(NVFoundationBase &inFoundation, const char *inPath); + // Returns true if this image has a pixel less than 255. + bool ScanForTransparency(); + + // Be sure to call this or risk leaking an enormous amount of memory + void release() override; + + // Not all video cards support dxt compression. Giving the last image allows + // this object to potentially reuse the memory + STextureData DecompressDXTImage(int inMipMapIdx, STextureData *inOptLastImage = NULL); + void ReleaseDecompressedTexture(STextureData inImage); + + static SLoadedTexture *Load(const QString &inPath, NVFoundationBase &inAllocator, + IInputStreamFactory &inFactory, bool inFlipY = true, + NVRenderContextType renderContextType + = NVRenderContextValues::NullContext, bool preferKTX = false); + static SLoadedTexture *LoadDDS(IInStream &inStream, QT3DSI32 flipVertical, + NVFoundationBase &fnd, + NVRenderContextType renderContextType); + static SLoadedTexture *LoadKTX(IInStream &inStream, QT3DSI32 flipVertical, + NVFoundationBase &fnd, + NVRenderContextType renderContextType); + static SLoadedTexture *LoadBMP(ISeekableIOStream &inStream, bool inFlipY, + NVFoundationBase &inFnd, + NVRenderContextType renderContextType); + static SLoadedTexture *LoadGIF(ISeekableIOStream &inStream, bool inFlipY, + NVFoundationBase &inFnd, + NVRenderContextType renderContextType); + static SLoadedTexture *LoadHDR(ISeekableIOStream &inStream, NVFoundationBase &inFnd, + NVRenderContextType renderContextType); + + static SLoadedTexture *LoadQImage(const QString &inPath, QT3DSI32 flipVertical, + NVFoundationBase &fnd, + NVRenderContextType renderContextType); + + private: + // Implemented in the bmp loader. + void FreeImagePostProcess(bool inFlipY); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureBMP.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureBMP.cpp new file mode 100644 index 00000000..29e75a89 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureBMP.cpp @@ -0,0 +1,1262 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// ========================================================== +// BMP Loader and Writer +// +// Design and implementation by +// - Floris van den Berg (flvdberg@wxs.nl) +// - Markus Loibl (markus.loibl@epost.de) +// - Martin Weber (martweb@gmx.net) +// - Herve Drolon (drolon@infonie.fr) +// - Michal Novotny (michal@etc.cz) +// +// This file is part of FreeImage 3 +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// ========================================================== + +#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" + +// ---------------------------------------------------------- +// Constants + headers +// ---------------------------------------------------------- + +static const BYTE RLE_COMMAND = 0; +static const BYTE RLE_ENDOFLINE = 0; +static const BYTE RLE_ENDOFBITMAP = 1; +static const BYTE RLE_DELTA = 2; + +static const BYTE BI_RGB = 0; +static const BYTE BI_RLE8 = 1; +static const BYTE BI_RLE4 = 2; +static const BYTE BI_BITFIELDS = 3; + +// ---------------------------------------------------------- + +#ifdef _WIN32 +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif + +typedef struct tagBITMAPCOREHEADER +{ + DWORD bcSize; + WORD bcWidth; + WORD bcHeight; + WORD bcPlanes; + WORD bcBitCnt; +} BITMAPCOREHEADER, *PBITMAPCOREHEADER; + +typedef struct tagBITMAPINFOOS2_1X_HEADER +{ + DWORD biSize; + WORD biWidth; + WORD biHeight; + WORD biPlanes; + WORD biBitCount; +} BITMAPINFOOS2_1X_HEADER, *PBITMAPINFOOS2_1X_HEADER; + +typedef struct tagBITMAPFILEHEADER +{ + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; +} BITMAPFILEHEADER, *PBITMAPFILEHEADER; + + +#ifdef _WIN32 +#pragma pack(pop) +#else +#pragma pack() +#endif + +// ========================================================== +// Plugin Interface +// ========================================================== + +static int s_format_id; + +// ========================================================== +// Internal functions +// ========================================================== + +#ifdef FREEIMAGE_BIGENDIAN +static void SwapInfoHeader(BITMAPINFOHEADER *header) +{ + SwapLong(&header->biSize); + SwapLong((DWORD *)&header->biWidth); + SwapLong((DWORD *)&header->biHeight); + SwapShort(&header->biPlanes); + SwapShort(&header->biBitCount); + SwapLong(&header->biCompression); + SwapLong(&header->biSizeImage); + SwapLong((DWORD *)&header->biXPelsPerMeter); + SwapLong((DWORD *)&header->biYPelsPerMeter); + SwapLong(&header->biClrUsed); + SwapLong(&header->biClrImportant); +} + +static void SwapCoreHeader(BITMAPCOREHEADER *header) +{ + SwapLong(&header->bcSize); + SwapShort(&header->bcWidth); + SwapShort(&header->bcHeight); + SwapShort(&header->bcPlanes); + SwapShort(&header->bcBitCnt); +} + +static void SwapOS21XHeader(BITMAPINFOOS2_1X_HEADER *header) +{ + SwapLong(&header->biSize); + SwapShort(&header->biWidth); + SwapShort(&header->biHeight); + SwapShort(&header->biPlanes); + SwapShort(&header->biBitCount); +} + +static void SwapFileHeader(BITMAPFILEHEADER *header) +{ + SwapShort(&header->bfType); + SwapLong(&header->bfSize); + SwapShort(&header->bfReserved1); + SwapShort(&header->bfReserved2); + SwapLong(&header->bfOffBits); +} +#endif + +// -------------------------------------------------------------------------- + +/** +Load uncompressed image pixels for 1-, 4-, 8-, 16-, 24- and 32-bit dib +@param io FreeImage IO +@param handle FreeImage IO handle +@param dib Image to be loaded +@param height Image height +@param pitch Image pitch +@param bit_count Image bit-depth (1-, 4-, 8-, 16-, 24- or 32-bit) +*/ +static void LoadPixelData(FreeImageIO *io, fi_handle handle, FIBITMAP *dib, int height, int pitch, + int bit_count) +{ + (void)bit_count; + // Load pixel data + // NB: height can be < 0 for BMP data + if (height > 0) { + io->read_proc((void *)FreeImage_GetBits(dib), height * pitch, 1, handle); + } else { + int positiveHeight = abs(height); + for (int c = 0; c < positiveHeight; ++c) { + io->read_proc((void *)FreeImage_GetScanLine(dib, positiveHeight - c - 1), pitch, 1, + handle); + } + } + +// swap as needed +#ifdef FREEIMAGE_BIGENDIAN + if (bit_count == 16) { + for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) { + WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y); + for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++) { + SwapShort(pixel); + pixel++; + } + } + } +#endif + +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB + if (bit_count == 24 || bit_count == 32) { + for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) { + BYTE *pixel = FreeImage_GetScanLine(dib, y); + for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++) { + INPLACESWAP(pixel[0], pixel[2]); + pixel += (bit_count >> 3); + } + } + } +#endif +} + +/** +Load image pixels for 4-bit RLE compressed dib +@param io FreeImage IO +@param handle FreeImage IO handle +@param width Image width +@param height Image height +@param dib Image to be loaded +@return Returns TRUE if successful, returns FALSE otherwise +*/ +static BOOL LoadPixelDataRLE4(FreeImageIO *io, fi_handle handle, int width, int height, + FIBITMAP *dib) +{ + int status_byte = 0; + BYTE second_byte = 0; + int bits = 0; + + BYTE *pixels = NULL; // temporary 8-bit buffer + + try { + height = abs(height); + + pixels = (BYTE *)malloc(width * height * sizeof(BYTE)); + if (!pixels) + throw(1); + memset(pixels, 0, width * height * sizeof(BYTE)); + + BYTE *q = pixels; + BYTE *end = pixels + height * width; + + for (int scanline = 0; scanline < height;) { + if (q < pixels || q >= end) { + break; + } + if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + if (status_byte != 0) { + status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q)); + // Encoded mode + if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + for (int i = 0; i < status_byte; i++) { + *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); + } + bits += status_byte; + } else { + // Escape mode + if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + switch (status_byte) { + case RLE_ENDOFLINE: { + // End of line + bits = 0; + scanline++; + q = pixels + scanline * width; + } break; + + case RLE_ENDOFBITMAP: + // End of bitmap + q = end; + break; + + case RLE_DELTA: { + // read the delta values + + BYTE delta_x = 0; + BYTE delta_y = 0; + + if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + + // apply them + + bits += delta_x; + scanline += delta_y; + q = pixels + scanline * width + bits; + } break; + + default: { + // Absolute mode + status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q)); + for (int i = 0; i < status_byte; i++) { + if ((i & 0x01) == 0) { + if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + } + *q++ = + (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); + } + bits += status_byte; + // Read pad byte + if (((status_byte & 0x03) == 1) || ((status_byte & 0x03) == 2)) { + BYTE padding = 0; + if (io->read_proc(&padding, sizeof(BYTE), 1, handle) != 1) { + throw(1); + } + } + } break; + } + } + } + + { + // Convert to 4-bit + for (int y = 0; y < height; y++) { + const BYTE *src = (BYTE *)pixels + y * width; + BYTE *dst = FreeImage_GetScanLine(dib, y); + + BOOL hinibble = TRUE; + + for (int cols = 0; cols < width; cols++) { + if (hinibble) { + dst[cols >> 1] = (src[cols] << 4); + } else { + dst[cols >> 1] |= src[cols]; + } + + hinibble = !hinibble; + } + } + } + + free(pixels); + + return TRUE; + + } catch (int) { + if (pixels) + free(pixels); + return FALSE; + } +} + +/** +Load image pixels for 8-bit RLE compressed dib +@param io FreeImage IO +@param handle FreeImage IO handle +@param width Image width +@param height Image height +@param dib Image to be loaded +@return Returns TRUE if successful, returns FALSE otherwise +*/ +static BOOL LoadPixelDataRLE8(FreeImageIO *io, fi_handle handle, int width, int height, + FIBITMAP *dib) +{ + BYTE status_byte = 0; + BYTE second_byte = 0; + int scanline = 0; + int bits = 0; + + for (;;) { + if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + + switch (status_byte) { + case RLE_COMMAND: + if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + + switch (status_byte) { + case RLE_ENDOFLINE: + bits = 0; + scanline++; + break; + + case RLE_ENDOFBITMAP: + return TRUE; + + case RLE_DELTA: { + // read the delta values + + BYTE delta_x = 0; + BYTE delta_y = 0; + + if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + + // apply them + + bits += delta_x; + scanline += delta_y; + + break; + } + + default: { + if (scanline >= abs(height)) { + return TRUE; + } + + int count = MIN((int)status_byte, width - bits); + + BYTE *sline = FreeImage_GetScanLine(dib, scanline); + + if (io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) { + return FALSE; + } + + // align run length to even number of bytes + + if ((status_byte & 1) == 1) { + if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + } + + bits += status_byte; + + break; + } + } + + break; + + default: { + if (scanline >= abs(height)) { + return TRUE; + } + + int count = MIN((int)status_byte, width - bits); + + BYTE *sline = FreeImage_GetScanLine(dib, scanline); + + if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + + for (int i = 0; i < count; i++) { + *(sline + bits) = second_byte; + + bits++; + } + + break; + } + } + } +} + +// -------------------------------------------------------------------------- + +static FIBITMAP *LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, + unsigned bitmap_bits_offset) +{ + FIBITMAP *dib = NULL; + (void)flags; + try { + // load the info header + + BITMAPINFOHEADER bih; + + io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapInfoHeader(&bih); +#endif + + // keep some general information about the bitmap + + int used_colors = bih.biClrUsed; + int width = bih.biWidth; + int height = bih.biHeight; // WARNING: height can be < 0 => check each call using 'height' + // as a parameter + int alloc_height = abs(height); + int bit_count = bih.biBitCount; + int compression = bih.biCompression; + int pitch = CalculatePitch(CalculateLine(width, bit_count)); + + switch (bit_count) { + case 1: + case 4: + case 8: { + if ((used_colors <= 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) + used_colors = CalculateUsedPaletteEntries(bit_count); + + // allocate enough memory to hold the bitmap (header, palette, pixels) and read the + // palette + + dib = FreeImage_Allocate(width, alloc_height, bit_count, io); + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information + FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); + FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); + + // load the palette + + io->read_proc(FreeImage_GetPalette(dib), used_colors * sizeof(RGBQUAD), 1, handle); +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB + RGBQUAD *pal = FreeImage_GetPalette(dib); + for (int i = 0; i < used_colors; i++) { + INPLACESWAP(pal[i].rgbRed, pal[i].rgbBlue); + } +#endif + + // seek to the actual pixel data. + // this is needed because sometimes the palette is larger than the entries it contains + // predicts + + if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + + (used_colors * sizeof(RGBQUAD)))) + io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); + + // read the pixel data + + switch (compression) { + case BI_RGB: + LoadPixelData(io, handle, dib, height, pitch, bit_count); + return dib; + + case BI_RLE4: + if (LoadPixelDataRLE4(io, handle, width, height, dib)) { + return dib; + } else { + throw "Error encountered while decoding RLE4 BMP data"; + } + break; + + case BI_RLE8: + if (LoadPixelDataRLE8(io, handle, width, height, dib)) { + return dib; + } else { + throw "Error encountered while decoding RLE8 BMP data"; + } + break; + + default: + throw "compression type not supported"; + } + } break; // 1-, 4-, 8-bit + + case 16: { + if (bih.biCompression == BI_BITFIELDS) { + DWORD bitfields[3]; + + io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle); + + dib = FreeImage_Allocate(width, alloc_height, bit_count, bitfields[0], bitfields[1], + bitfields[2], io); + } else { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI16_555_RED_MASK, + FI16_555_GREEN_MASK, FI16_555_BLUE_MASK, io); + } + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information + FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); + FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); + + // load pixel data and swap as needed if OS is Big Endian + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + return dib; + } break; // 16-bit + + case 24: + case 32: { + if (bih.biCompression == BI_BITFIELDS) { + DWORD bitfields[3]; + + io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle); + + dib = FreeImage_Allocate(width, alloc_height, bit_count, bitfields[0], bitfields[1], + bitfields[2], io); + } else { + if (bit_count == 32) { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); + } else { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); + } + } + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information + FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); + FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); + + // Skip over the optional palette + // A 24 or 32 bit DIB may contain a palette for faster color reduction + + if (used_colors > 0) { + io->seek_proc(handle, used_colors * sizeof(RGBQUAD), SEEK_CUR); + } else if ((bih.biCompression != BI_BITFIELDS) + && (bitmap_bits_offset + > sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))) { + io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); + } + + // read in the bitmap bits + // load pixel data and swap as needed if OS is Big Endian + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + // check if the bitmap contains transparency, if so enable it in the header + + return dib; + } break; // 24-, 32-bit + } + } catch (const char *message) { + if (dib) { + FreeImage_Unload(dib); + } + if (message) { + FreeImage_OutputMessageProc(s_format_id, message, io); + } + } + + return NULL; +} + +// -------------------------------------------------------------------------- + +static FIBITMAP *LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, + unsigned bitmap_bits_offset) +{ + FIBITMAP *dib = NULL; + (void)flags; + try { + // load the info header + + BITMAPINFOHEADER bih; + + io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapInfoHeader(&bih); +#endif + + // keep some general information about the bitmap + + int used_colors = bih.biClrUsed; + int width = bih.biWidth; + int height = bih.biHeight; // WARNING: height can be < 0 => check each read_proc using + // 'height' as a parameter + int alloc_height = abs(height); + int bit_count = bih.biBitCount; + int compression = bih.biCompression; + int pitch = CalculatePitch(CalculateLine(width, bit_count)); + + switch (bit_count) { + case 1: + case 4: + case 8: { + if ((used_colors <= 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) + used_colors = CalculateUsedPaletteEntries(bit_count); + + // allocate enough memory to hold the bitmap (header, palette, pixels) and read the + // palette + + dib = FreeImage_Allocate(width, alloc_height, bit_count, io); + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information + FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); + FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); + + // load the palette + + io->seek_proc(handle, sizeof(BITMAPFILEHEADER) + bih.biSize, SEEK_SET); + + RGBQUAD *pal = FreeImage_GetPalette(dib); + + for (int count = 0; count < used_colors; count++) { + FILE_BGR bgr; + + io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle); + + pal[count].rgbRed = bgr.r; + pal[count].rgbGreen = bgr.g; + pal[count].rgbBlue = bgr.b; + } + + // seek to the actual pixel data. + // this is needed because sometimes the palette is larger than the entries it contains + // predicts + + if (bitmap_bits_offset + > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) + io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); + + // read the pixel data + + switch (compression) { + case BI_RGB: + // load pixel data + LoadPixelData(io, handle, dib, height, pitch, bit_count); + return dib; + + case BI_RLE4: + if (LoadPixelDataRLE4(io, handle, width, height, dib)) { + return dib; + } else { + throw "Error encountered while decoding RLE4 BMP data"; + } + break; + + case BI_RLE8: + if (LoadPixelDataRLE8(io, handle, width, height, dib)) { + return dib; + } else { + throw "Error encountered while decoding RLE8 BMP data"; + } + break; + + default: + throw "compression type not supported"; + } + } + + case 16: { + if (bih.biCompression == 3) { + DWORD bitfields[3]; + + io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle); + + dib = FreeImage_Allocate(width, alloc_height, bit_count, bitfields[0], bitfields[1], + bitfields[2], io); + } else { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI16_555_RED_MASK, + FI16_555_GREEN_MASK, FI16_555_BLUE_MASK, io); + } + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information + FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); + FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); + + if (bitmap_bits_offset + > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) { + io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); + } + + // load pixel data and swap as needed if OS is Big Endian + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + return dib; + } + + case 24: + case 32: { + if (bit_count == 32) { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); + } else { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); + } + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information + FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter); + FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter); + + // Skip over the optional palette + // A 24 or 32 bit DIB may contain a palette for faster color reduction + + if (bitmap_bits_offset + > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) + io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); + + // read in the bitmap bits + // load pixel data and swap as needed if OS is Big Endian + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + return dib; + } + } + } catch (const char *message) { + if (dib) + FreeImage_Unload(dib); + + FreeImage_OutputMessageProc(s_format_id, message, io); + } + + return NULL; +} + +// -------------------------------------------------------------------------- + +static FIBITMAP *LoadOS21XBMP(FreeImageIO *io, fi_handle handle, int flags, + unsigned bitmap_bits_offset) +{ + FIBITMAP *dib = NULL; + (void)flags; + try { + BITMAPINFOOS2_1X_HEADER bios2_1x; + + io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapOS21XHeader(&bios2_1x); +#endif + // keep some general information about the bitmap + + int used_colors = 0; + int width = bios2_1x.biWidth; + int height = bios2_1x.biHeight; // WARNING: height can be < 0 => check each read_proc using + // 'height' as a parameter + int alloc_height = abs(height); + int bit_count = bios2_1x.biBitCount; + int pitch = CalculatePitch(CalculateLine(width, bit_count)); + + switch (bit_count) { + case 1: + case 4: + case 8: { + used_colors = CalculateUsedPaletteEntries(bit_count); + + // allocate enough memory to hold the bitmap (header, palette, pixels) and read the + // palette + + dib = FreeImage_Allocate(width, alloc_height, bit_count, io); + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information to default values (72 dpi in english units) + FreeImage_SetDotsPerMeterX(dib, 2835); + FreeImage_SetDotsPerMeterY(dib, 2835); + + // load the palette + + RGBQUAD *pal = FreeImage_GetPalette(dib); + + for (int count = 0; count < used_colors; count++) { + FILE_BGR bgr; + + io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle); + + pal[count].rgbRed = bgr.r; + pal[count].rgbGreen = bgr.g; + pal[count].rgbBlue = bgr.b; + } + + // Skip over the optional palette + // A 24 or 32 bit DIB may contain a palette for faster color reduction + + io->seek_proc(handle, bitmap_bits_offset, SEEK_SET); + + // read the pixel data + + // load pixel data + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + return dib; + } + + case 16: { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI16_555_RED_MASK, + FI16_555_GREEN_MASK, FI16_555_BLUE_MASK, io); + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information to default values (72 dpi in english units) + FreeImage_SetDotsPerMeterX(dib, 2835); + FreeImage_SetDotsPerMeterY(dib, 2835); + + // load pixel data and swap as needed if OS is Big Endian + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + return dib; + } + + case 24: + case 32: { + if (bit_count == 32) { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); + } else { + dib = FreeImage_Allocate(width, alloc_height, bit_count, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, io); + } + + if (dib == NULL) + throw "DIB allocation failed"; + + // set resolution information to default values (72 dpi in english units) + FreeImage_SetDotsPerMeterX(dib, 2835); + FreeImage_SetDotsPerMeterY(dib, 2835); + + // Skip over the optional palette + // A 24 or 32 bit DIB may contain a palette for faster color reduction + + // load pixel data and swap as needed if OS is Big Endian + LoadPixelData(io, handle, dib, height, pitch, bit_count); + + // check if the bitmap contains transparency, if so enable it in the header + + return dib; + } + } + } catch (const char *message) { + if (dib) + FreeImage_Unload(dib); + + FreeImage_OutputMessageProc(s_format_id, message, io); + } + + return NULL; +} + +// ========================================================== +// Plugin Implementation +// ========================================================== + +// ---------------------------------------------------------- + +static FIBITMAP *DoLoadBMP(FreeImageIO *io, fi_handle handle, int flags) +{ + if (handle != NULL) { + BITMAPFILEHEADER bitmapfileheader; + DWORD type = 0; + BYTE magic[2]; + + // we use this offset value to make seemingly absolute seeks relative in the file + + long offset_in_file = io->tell_proc(handle); + + // read the magic + + io->read_proc(&magic, sizeof(magic), 1, handle); + + // compare the magic with the number we know + + // somebody put a comment here explaining the purpose of this loop + while (memcmp(&magic, "BA", 2) == 0) { + io->read_proc(&bitmapfileheader.bfSize, sizeof(DWORD), 1, handle); + io->read_proc(&bitmapfileheader.bfReserved1, sizeof(WORD), 1, handle); + io->read_proc(&bitmapfileheader.bfReserved2, sizeof(WORD), 1, handle); + io->read_proc(&bitmapfileheader.bfOffBits, sizeof(DWORD), 1, handle); + io->read_proc(&magic, sizeof(magic), 1, handle); + } + + // read the fileheader + + io->seek_proc(handle, (0 - (int)sizeof(magic)), SEEK_CUR); + io->read_proc(&bitmapfileheader, (int)sizeof(BITMAPFILEHEADER), 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapFileHeader(&bitmapfileheader); +#endif + + // read the first byte of the infoheader + + io->read_proc(&type, sizeof(DWORD), 1, handle); + io->seek_proc(handle, 0 - (int)sizeof(DWORD), SEEK_CUR); +#ifdef FREEIMAGE_BIGENDIAN + SwapLong(&type); +#endif + + // call the appropriate load function for the found bitmap type + + if (type == 40) + return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits); + + if (type == 12) + return LoadOS21XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits); + + if (type <= 64) + return LoadOS22XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits); + + char buf[256]; + sprintf(buf, "unknown bmp subtype with id %d", type); + FreeImage_OutputMessageProc(s_format_id, buf, io); + } + + return NULL; +} + +template +struct SPaletteIndexer +{ + static inline uint32_t IndexOf(const uint8_t *inData, uint32_t inPos) + { + uint32_t divisor = 8 / TBitWidth; + uint32_t byte = inPos / divisor; + uint32_t modulus = inPos % divisor; + uint32_t shift = TBitWidth * modulus; + uint32_t mask = (1 << TBitWidth) - 1; + mask = mask << shift; + uint32_t byteData = inData[byte]; + return (byteData & mask) >> shift; + } +}; + +template <> +struct SPaletteIndexer<1> +{ + static inline uint32_t IndexOf(const uint8_t *inData, uint32_t inPos) + { + uint32_t byte = (inPos / 8); + uint32_t bit = 1 << (7 - (inPos % 8)); + uint32_t byteData = inData[byte]; + return (byteData & bit) ? 1 : 0; + } +}; + +template <> +struct SPaletteIndexer<8> +{ + static inline uint32_t IndexOf(const uint8_t *inData, uint32_t inPos) + { + uint32_t byte = inPos; + uint32_t bit = 0xFF; + uint32_t byteData = inData[byte]; + return byteData & bit; + } +}; + +static inline void assignQuad(uint8_t *dest, const RGBQUAD &quad) +{ + dest[0] = quad.rgbRed; + dest[1] = quad.rgbGreen; + dest[2] = quad.rgbBlue; +} + +template +inline void LoadPalettized(bool inFlipY, const RGBQUAD *palette, void *data, uint8_t *newData, + int width, int height, int components, int transparentIndex) +{ + const uint8_t *oldData = (const uint8_t *)data; + int pitch = CalculatePitch(CalculateLine(width, bitCount)); + for (uint32_t h = 0; h < (uint32_t)height; ++h) { + uint32_t relHeight = h; + if (inFlipY) + relHeight = ((uint32_t)height) - h - 1; + for (uint32_t w = 0; w < (uint32_t)width; ++w) { + const uint8_t *dataLine = oldData + pitch * h; + uint32_t pos = width * relHeight + w; + uint32_t paletteIndex = SPaletteIndexer::IndexOf(dataLine, w); + const RGBQUAD &theQuad = palette[paletteIndex]; + uint8_t *writePtr = newData + (pos * components); + assignQuad(writePtr, theQuad); + if (paletteIndex == (uint32_t)transparentIndex && components == 4) { + writePtr[3] = 0; + } + } + } +} + +inline int firstHighBit(int data) +{ + if (data == 0) + return 0; + int idx = 0; + while ((data % 2) == 0) { + data = data >> 1; + ++idx; + } + return idx; +} + +struct SMaskData +{ + uint32_t mask; + uint32_t shift; + uint32_t max; + + SMaskData(int inMask) + { + mask = inMask; + shift = firstHighBit(mask); + max = mask >> shift; + } + + inline uint8_t MapColor(uint32_t color) const + { + uint32_t intermediateValue = (color & mask) >> shift; + return (uint8_t)((intermediateValue * 255) / max); + } +}; + +template +struct ColorAccess +{ +}; + +template <> +struct ColorAccess<16> +{ + static uint32_t GetPixelWidth() { return 2; } + static uint32_t GetColor(const char8_t *src) + { + return (uint32_t) * reinterpret_cast(src); + } +}; + +template <> +struct ColorAccess<24> +{ + static uint32_t GetPixelWidth() { return 3; } + static uint32_t GetColor(const char8_t *src) + { + return (uint32_t)(*reinterpret_cast(src) & 0xFFFFFF); + } +}; + +template <> +struct ColorAccess<32> +{ + static uint32_t GetPixelWidth() { return 4; } + static uint32_t GetColor(const char8_t *src) + { + return *reinterpret_cast(src); + } +}; + +template +inline void LoadMasked(bool inFlipY, QT3DSI32 *inMasks, void *data, uint8_t *newData, int width, + int height) +{ + const char8_t *oldData = (const char8_t *)data; + SMaskData rMask(inMasks[0]); + SMaskData gMask(inMasks[1]); + SMaskData bMask(inMasks[2]); + for (int h = 0; h < height; ++h) { + int relHeight = h; + if (inFlipY) + relHeight = height - h - 1; + for (int w = 0; w < width; ++w) { + int pos = width * relHeight + w; + const char8_t *readPtr = oldData + (pos * ColorAccess::GetPixelWidth()); + uint8_t *writePtr = newData + (pos * 3); + uint32_t colorVal = ColorAccess::GetColor(readPtr); + writePtr[0] = rMask.MapColor(colorVal); + writePtr[1] = gMask.MapColor(colorVal); + writePtr[2] = bMask.MapColor(colorVal); + } + } +} + +void SLoadedTexture::FreeImagePostProcess(bool inFlipY) +{ + // We always convert 32 bit RGBA + if (m_ExtendedFormat != ExtendedTextureFormats::NoExtendedFormat) { + + QT3DSU32 stride = 3 * width; + format = NVRenderTextureFormats::RGB8; + components = 3; + if (m_ExtendedFormat == ExtendedTextureFormats::Palettized && m_TransparentPaletteIndex > -1 + && m_TransparentPaletteIndex < 256) { + stride = 4 * width; + components = 4; + format = NVRenderTextureFormats::RGBA8; + } + QT3DSU32 byteSize = height * stride; + uint8_t *newData = + (uint8_t *)m_Allocator.allocate(byteSize, "texture data", __FILE__, __LINE__); + if (format == NVRenderTextureFormats::RGBA8) + memSet(newData, 255, byteSize); + switch (m_ExtendedFormat) { + case ExtendedTextureFormats::Palettized: { + RGBQUAD *palette = (RGBQUAD *)m_Palette; + switch (m_BitCount) { + case 1: + LoadPalettized<1>(inFlipY, palette, data, newData, width, height, components, + m_TransparentPaletteIndex); + break; + case 2: + LoadPalettized<2>(inFlipY, palette, data, newData, width, height, components, + m_TransparentPaletteIndex); + break; + case 4: + LoadPalettized<4>(inFlipY, palette, data, newData, width, height, components, + m_TransparentPaletteIndex); + break; + case 8: + LoadPalettized<8>(inFlipY, palette, data, newData, width, height, components, + m_TransparentPaletteIndex); + break; + default: + QT3DS_ASSERT(false); + memSet(newData, 0, byteSize); + break; + } + } break; + case ExtendedTextureFormats::CustomRGB: { + switch (m_BitCount) { + case 16: + LoadMasked<16>(inFlipY, m_CustomMasks, data, newData, width, height); + break; + case 24: + LoadMasked<24>(inFlipY, m_CustomMasks, data, newData, width, height); + break; + case 32: + LoadMasked<32>(inFlipY, m_CustomMasks, data, newData, width, height); + break; + default: + QT3DS_ASSERT(false); + memSet(newData, 0, byteSize); + break; + } + } break; + default: + QT3DS_ASSERT(false); + memSet(newData, 0, byteSize); + break; + } + m_Allocator.deallocate(data); + if (m_Palette) + m_Allocator.deallocate(m_Palette); + data = newData; + m_Palette = NULL; + m_BitCount = 0; + this->dataSizeInBytes = byteSize; + m_ExtendedFormat = ExtendedTextureFormats::NoExtendedFormat; + } +} + +SLoadedTexture *SLoadedTexture::LoadBMP(ISeekableIOStream &inStream, bool inFlipY, + NVFoundationBase &inFnd, + qt3ds::render::NVRenderContextType renderContextType) +{ + Q_UNUSED(renderContextType) + FreeImageIO theIO(inFnd.getAllocator(), inFnd); + SLoadedTexture *retval = DoLoadBMP(&theIO, &inStream, 0); + if (retval) + retval->FreeImagePostProcess(inFlipY); + return retval; +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.cpp new file mode 100644 index 00000000..19d41d11 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.cpp @@ -0,0 +1,695 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderLoadedTextureDDS.h" +#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" + +using namespace qt3ds::render; + +namespace qt3ds { +namespace render { + + static int s_exception_string; + + //================================================================================ + // DXT data-layout structure definitions. + typedef struct + { + QT3DSU16 col0; // 16-bit 565 interpolant endpoints + QT3DSU16 col1; + QT3DSU8 row[4]; // 4x4 * 2bpp color-index == 4 bytes. + } DXTColBlock; + + typedef struct + { + QT3DSU16 row[4]; // 4x4 * 4bpp alpha == 8 bytes. (pure 4-bit alpha values) + } DXT3AlphaBlock; + + typedef struct + { + QT3DSU8 alpha0; // 8-bit alpha interpolant endpoints + QT3DSU8 alpha1; + QT3DSU8 row[6]; // 4x4 * 3bpp alpha-index == 48bits == 6 bytes. + } DXT5AlphaBlock; + + typedef struct + { + QT3DSU8 red; + QT3DSU8 green; + QT3DSU8 blue; + QT3DSU8 alpha; + } Color8888; + +//================================================================================ +// Various DDS file defines + +#define DDSD_CAPS 0x00000001l +#define DDSD_HEIGHT 0x00000002l +#define DDSD_WIDTH 0x00000004l +#define DDSD_PIXELFORMAT 0x00001000l +#define DDS_ALPHAPIXELS 0x00000001l +#define DDS_FOURCC 0x00000004l +#define DDS_PITCH 0x00000008l +#define DDS_COMPLEX 0x00000008l +#define DDS_RGB 0x00000040l +#define DDS_TEXTURE 0x00001000l +#define DDS_MIPMAPCOUNT 0x00020000l +#define DDS_LINEARSIZE 0x00080000l +#define DDS_VOLUME 0x00200000l +#define DDS_MIPMAP 0x00400000l +#define DDS_DEPTH 0x00800000l + +#define DDS_CUBEMAP 0x00000200L +#define DDS_CUBEMAP_POSITIVEX 0x00000400L +#define DDS_CUBEMAP_NEGATIVEX 0x00000800L +#define DDS_CUBEMAP_POSITIVEY 0x00001000L +#define DDS_CUBEMAP_NEGATIVEY 0x00002000L +#define DDS_CUBEMAP_POSITIVEZ 0x00004000L +#define DDS_CUBEMAP_NEGATIVEZ 0x00008000L + +#define FOURCC_DXT1 0x31545844 //(MAKEFOURCC('D','X','T','1')) +#define FOURCC_DXT3 0x33545844 //(MAKEFOURCC('D','X','T','3')) +#define FOURCC_DXT5 0x35545844 //(MAKEFOURCC('D','X','T','5')) + +#define DDS_MAGIC_FLIPPED 0x0F7166ED + + //================================================================================ + // DDS file format structures. + typedef struct _DDS_PIXELFORMAT + { + QT3DSU32 dwSize; + QT3DSU32 dwFlags; + QT3DSU32 dwFourCC; + QT3DSU32 dwRGBBitCount; + QT3DSU32 dwRBitMask; + QT3DSU32 dwGBitMask; + QT3DSU32 dwBBitMask; + QT3DSU32 dwABitMask; + } DDS_PIXELFORMAT; + + typedef struct _DDS_HEADER + { + QT3DSU32 dwSize; + QT3DSU32 dwFlags; + QT3DSU32 dwHeight; + QT3DSU32 dwWidth; + QT3DSU32 dwPitchOrLinearSize; + QT3DSU32 dwDepth; + QT3DSU32 dwMipMapCount; + QT3DSU32 dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + QT3DSU32 dwCaps1; + QT3DSU32 dwCaps2; + QT3DSU32 dwReserved2[3]; + } DDS_HEADER; + + //================================================================================ + // helper functions + //================================================================================ + + // helper macros. + static inline void NvSwapChar(QT3DSU8 &a, QT3DSU8 &b) + { + QT3DSU8 tmp; + tmp = a; + a = b; + b = tmp; + } + + static inline void NvSwapShort(QT3DSU16 &a, QT3DSU16 &b) + { + QT3DSU16 tmp; + tmp = a; + a = b; + b = tmp; + } + + //================================================================================ + //================================================================================ + static void flip_blocks_dxtc1(DXTColBlock *line, QT3DSI32 numBlocks) + { + DXTColBlock *curblock = line; + QT3DSI32 i; + + for (i = 0; i < numBlocks; i++) { + NvSwapChar(curblock->row[0], curblock->row[3]); + NvSwapChar(curblock->row[1], curblock->row[2]); + curblock++; + } + } + + //================================================================================ + //================================================================================ + static void flip_blocks_dxtc3(DXTColBlock *line, QT3DSI32 numBlocks) + { + DXTColBlock *curblock = line; + DXT3AlphaBlock *alphablock; + QT3DSI32 i; + + for (i = 0; i < numBlocks; i++) { + alphablock = (DXT3AlphaBlock *)curblock; + + NvSwapShort(alphablock->row[0], alphablock->row[3]); + NvSwapShort(alphablock->row[1], alphablock->row[2]); + curblock++; + + NvSwapChar(curblock->row[0], curblock->row[3]); + NvSwapChar(curblock->row[1], curblock->row[2]); + curblock++; + } + } + + static void flip_dxt5_alpha(DXT5AlphaBlock *block) + { + QT3DSI8 gBits[4][4]; + + const QT3DSU32 mask = 0x00000007; // bits = 00 00 01 11 + QT3DSU32 bits = 0; + memcpy(&bits, &block->row[0], sizeof(QT3DSI8) * 3); + + gBits[0][0] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[0][1] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[0][2] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[0][3] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[1][0] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[1][1] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[1][2] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[1][3] = (QT3DSI8)(bits & mask); + + bits = 0; + memcpy(&bits, &block->row[3], sizeof(QT3DSI8) * 3); + + gBits[2][0] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[2][1] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[2][2] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[2][3] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[3][0] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[3][1] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[3][2] = (QT3DSI8)(bits & mask); + bits >>= 3; + gBits[3][3] = (QT3DSI8)(bits & mask); + + bits = (gBits[3][0] << 0) | (gBits[3][1] << 3) | (gBits[3][2] << 6) | (gBits[3][3] << 9) + | (gBits[2][0] << 12) | (gBits[2][1] << 15) | (gBits[2][2] << 18) | (gBits[2][3] << 21); + memcpy(&block->row[0], &bits, 3); + + bits = (gBits[1][0] << 0) | (gBits[1][1] << 3) | (gBits[1][2] << 6) | (gBits[1][3] << 9) + | (gBits[0][0] << 12) | (gBits[0][1] << 15) | (gBits[0][2] << 18) | (gBits[0][3] << 21); + memcpy(&block->row[3], &bits, 3); + } + + static void flip_blocks_dxtc5(DXTColBlock *line, QT3DSI32 numBlocks) + { + DXTColBlock *curblock = line; + DXT5AlphaBlock *alphablock; + QT3DSI32 i; + + for (i = 0; i < numBlocks; i++) { + alphablock = (DXT5AlphaBlock *)curblock; + + flip_dxt5_alpha(alphablock); + curblock++; + + NvSwapChar(curblock->row[0], curblock->row[3]); + NvSwapChar(curblock->row[1], curblock->row[2]); + curblock++; + } + } + + static void flip_data_vertical(FreeImageIO *io, QT3DSI8 *image, QT3DSI32 width, QT3DSI32 height, + Qt3DSDDSImage *info) + { + if (info->compressed) { + QT3DSI32 linesize, j; + DXTColBlock *top; + DXTColBlock *bottom; + QT3DSI8 *tmp; + void (*flipblocks)(DXTColBlock *, QT3DSI32) = NULL; + QT3DSI32 xblocks = width / 4; + QT3DSI32 yblocks = height / 4; + QT3DSI32 blocksize; + + switch (info->format) { + case qt3ds::render::NVRenderTextureFormats::RGBA_DXT1: + blocksize = 8; + flipblocks = &flip_blocks_dxtc1; + break; + case qt3ds::render::NVRenderTextureFormats::RGBA_DXT3: + blocksize = 16; + flipblocks = &flip_blocks_dxtc3; + break; + case qt3ds::render::NVRenderTextureFormats::RGBA_DXT5: + blocksize = 16; + flipblocks = &flip_blocks_dxtc5; + break; + default: + return; + } + + linesize = xblocks * blocksize; + tmp = (QT3DSI8 *)QT3DS_ALLOC(io->m_Allocator, linesize, "flip_data_vertical compressed"); + + for (j = 0; j < (yblocks >> 1); j++) { + top = (DXTColBlock *)(void *)(image + j * linesize); + bottom = (DXTColBlock *)(void *)(image + (((yblocks - j) - 1) * linesize)); + + (*flipblocks)(top, xblocks); + (*flipblocks)(bottom, xblocks); + + memcpy(tmp, bottom, linesize); + memcpy(bottom, top, linesize); + memcpy(top, tmp, linesize); + } + + // Catch the middle row of blocks if there is one + // The loop above will skip the middle row + if (yblocks & 0x01) { + DXTColBlock *middle = (DXTColBlock *)(void *)(image + (yblocks >> 1) * linesize); + (*flipblocks)(middle, xblocks); + } + + QT3DS_FREE(io->m_Allocator, tmp); + } else { + QT3DSI32 linesize = width * info->bytesPerPixel; + QT3DSI32 j; + QT3DSI8 *top; + QT3DSI8 *bottom; + QT3DSI8 *tmp; + + // much simpler - just compute the line length and swap each row + tmp = (QT3DSI8 *)QT3DS_ALLOC(io->m_Allocator, linesize, "flip_data_vertical"); + ; + + for (j = 0; j < (height >> 1); j++) { + top = (QT3DSI8 *)(image + j * linesize); + bottom = (QT3DSI8 *)(image + (((height - j) - 1) * linesize)); + + memcpy(tmp, bottom, linesize); + memcpy(bottom, top, linesize); + memcpy(top, tmp, linesize); + } + + QT3DS_FREE(io->m_Allocator, tmp); + } + } + + static QT3DSI32 size_image(QT3DSI32 width, QT3DSI32 height, const Qt3DSDDSImage *image) + { + if (image->compressed) { + return ((width + 3) / 4) * ((height + 3) / 4) + * (image->format == qt3ds::render::NVRenderTextureFormats::RGBA_DXT1 ? 8 : 16); + } else { + return width * height * image->bytesPerPixel; + } + } + + static QT3DSI32 total_image_data_size(Qt3DSDDSImage *image) + { + QT3DSI32 i, j, index = 0, size = 0, w, h; + QT3DSI32 cubeCount = image->cubemap ? 6 : 1; + + for (j = 0; j < cubeCount; j++) { + w = image->width; + h = image->height; + + for (i = 0; i < image->numMipmaps; i++) // account for base plus each mip + { + image->size[index] = size_image(w, h, image); + image->mipwidth[index] = w; + image->mipheight[index] = h; + size += image->size[index]; + if (w != 1) { + w >>= 1; + } + if (h != 1) { + h >>= 1; + } + + index++; + } + } + + return (size); + } + + void *Qt3DSDDSAllocDataBlock(FreeImageIO *io, Qt3DSDDSImage *image) + { + if (image) { + QT3DSI32 i; + QT3DSI32 size = total_image_data_size(image); + image->dataBlock = + QT3DS_ALLOC(io->m_Allocator, size, + "Qt3DSDDSAllocDataBlock"); // no need to calloc, as we fill every bit... + if (image->dataBlock == NULL) { + return NULL; + } + + image->data[0] = image->dataBlock; + + QT3DSI32 planes = image->numMipmaps * (image->cubemap ? 6 : 1); + + for (i = 1; i < planes; i++) // account for base plus each mip + { + image->data[i] = + (void *)(((size_t)(image->data[i - 1])) + (size_t)image->size[i - 1]); + } + + return (image->dataBlock); // in case caller wants to sanity check... + } + return (NULL); + } + + static FIBITMAP *DoLoadDDS(FreeImageIO *io, IInStream &inStream, QT3DSI32 flipVertical) + { + FIBITMAP *dib = NULL; + DDS_HEADER ddsh; + QT3DSI8 filecode[4]; + Qt3DSDDSImage *image = NULL; + bool needsBGRASwap = false; + ; + bool isAllreadyFlipped = false; + + try { + // check file code + inStream.Read(filecode, 4); + if (memcmp(filecode, "DDS ", 4)) { + throw "Invalid DDS file"; + } + + image = (Qt3DSDDSImage *)QT3DS_ALLOC(io->m_Allocator, sizeof(Qt3DSDDSImage), "DoLoadDDS"); + if (image == NULL) { + throw "Qt3DSDDSImage allocation failed"; + } + memset(image, 0, sizeof(Qt3DSDDSImage)); + + // read in DDS header + inStream.Read(&ddsh, 1); + + // check if image is a cubempap + if (ddsh.dwCaps2 & DDS_CUBEMAP) { + const QT3DSI32 allFaces = DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_POSITIVEY + | DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEX | DDS_CUBEMAP_NEGATIVEY + | DDS_CUBEMAP_NEGATIVEZ; + + if ((ddsh.dwCaps2 & allFaces) != allFaces) { + throw "Not all cubemap faces defined - not supported"; + } + + image->cubemap = 1; + } else { + image->cubemap = 0; + } + + // check if image is a volume texture + if ((ddsh.dwCaps2 & DDS_VOLUME) && (ddsh.dwDepth > 0)) { + throw "Volume textures not supported"; + } + + // allocated the memory for the structure we return + dib = QT3DS_NEW(io->m_Allocator, SLoadedTexture)(io->m_Allocator); + if (dib == NULL) { + throw "DIB allocation failed"; + } + + // figure out what the image format is + if (ddsh.ddspf.dwFlags & DDS_FOURCC) { + switch (ddsh.ddspf.dwFourCC) { + case FOURCC_DXT1: + image->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT1; + image->components = 3; + image->compressed = 1; + image->alpha = 0; // Ugh - for backwards compatibility + dib->format = qt3ds::render::NVRenderTextureFormats::RGB_DXT1; + break; + case FOURCC_DXT3: + image->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT3; + image->components = 4; + image->compressed = 1; + image->alpha = 1; + dib->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT3; + break; + case FOURCC_DXT5: + image->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT5; + image->components = 4; + image->compressed = 1; + image->alpha = 1; + dib->format = qt3ds::render::NVRenderTextureFormats::RGBA_DXT5; + break; + default: + throw "Unsupported FOURCC code"; + } + } else { + // Check for a supported pixel format + if ((ddsh.ddspf.dwRGBBitCount == 32) && (ddsh.ddspf.dwRBitMask == 0x000000FF) + && (ddsh.ddspf.dwGBitMask == 0x0000FF00) + && (ddsh.ddspf.dwBBitMask == 0x00FF0000) + && (ddsh.ddspf.dwABitMask == 0xFF000000)) { + // We support D3D's A8B8G8R8, which is actually RGBA in linear + // memory, equivalent to GL's RGBA + image->format = qt3ds::render::NVRenderTextureFormats::RGBA8; + image->components = 4; + image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; + image->bytesPerPixel = 4; + image->alpha = 1; + image->compressed = 0; + dib->format = qt3ds::render::NVRenderTextureFormats::RGBA8; + } else if ((ddsh.ddspf.dwRGBBitCount == 32) && (ddsh.ddspf.dwRBitMask == 0x00FF0000) + && (ddsh.ddspf.dwGBitMask == 0x0000FF00) + && (ddsh.ddspf.dwBBitMask == 0x000000FF) + && (ddsh.ddspf.dwABitMask == 0xFF000000)) { + // We support D3D's A8R8G8B8, which is actually BGRA in linear + // memory, need to be + image->format = qt3ds::render::NVRenderTextureFormats::RGBA8; + image->components = 4; + image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; + image->bytesPerPixel = 4; + image->alpha = 1; + image->compressed = 0; + needsBGRASwap = true; + dib->format = qt3ds::render::NVRenderTextureFormats::RGBA8; + } else if ((ddsh.ddspf.dwRGBBitCount == 16) && (ddsh.ddspf.dwRBitMask == 0x0000F800) + && (ddsh.ddspf.dwGBitMask == 0x000007E0) + && (ddsh.ddspf.dwBBitMask == 0x0000001F) + && (ddsh.ddspf.dwABitMask == 0x00000000)) { + // We support D3D's R5G6B5, which is actually RGB in linear + // memory. It is equivalent to GL's GL_UNSIGNED_SHORT_5_6_5 + image->format = qt3ds::render::NVRenderTextureFormats::RGB8; + image->components = 3; + image->alpha = 0; + image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU16; + image->bytesPerPixel = 2; + image->compressed = 0; + dib->format = qt3ds::render::NVRenderTextureFormats::RGB8; + } else if ((ddsh.ddspf.dwRGBBitCount == 8) && (ddsh.ddspf.dwRBitMask == 0x00000000) + && (ddsh.ddspf.dwGBitMask == 0x00000000) + && (ddsh.ddspf.dwBBitMask == 0x00000000) + && (ddsh.ddspf.dwABitMask == 0x000000FF)) { + // We support D3D's A8 + image->format = qt3ds::render::NVRenderTextureFormats::Alpha8; + image->components = 1; + image->alpha = 1; + image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; + image->bytesPerPixel = 1; + image->compressed = 0; + dib->format = qt3ds::render::NVRenderTextureFormats::Alpha8; + } else if ((ddsh.ddspf.dwRGBBitCount == 8) && (ddsh.ddspf.dwRBitMask == 0x000000FF) + && (ddsh.ddspf.dwGBitMask == 0x00000000) + && (ddsh.ddspf.dwBBitMask == 0x00000000) + && (ddsh.ddspf.dwABitMask == 0x00000000)) { + // We support D3D's L8 (flagged as 8 bits of red only) + image->format = qt3ds::render::NVRenderTextureFormats::Luminance8; + image->components = 1; + image->alpha = 0; + image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; + image->bytesPerPixel = 1; + image->compressed = 0; + dib->format = qt3ds::render::NVRenderTextureFormats::Luminance8; + } else if ((ddsh.ddspf.dwRGBBitCount == 16) && (ddsh.ddspf.dwRBitMask == 0x000000FF) + && (ddsh.ddspf.dwGBitMask == 0x00000000) + && (ddsh.ddspf.dwBBitMask == 0x00000000) + && (ddsh.ddspf.dwABitMask == 0x0000FF00)) { + // We support D3D's A8L8 (flagged as 8 bits of red and 8 bits of alpha) + image->format = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; + image->components = 2; + image->alpha = 1; + image->componentFormat = qt3ds::render::NVRenderComponentTypes::QT3DSU8; + image->bytesPerPixel = 2; + image->compressed = 0; + dib->format = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8; + } else { + throw "not a DXTC or supported RGB(A) format image"; + } + } + + // detect flagging to indicate this texture was stored in a y-inverted fashion + if (!(ddsh.dwFlags & DDS_LINEARSIZE)) { + if (ddsh.dwPitchOrLinearSize == DDS_MAGIC_FLIPPED) { + isAllreadyFlipped = true; + } + } + + flipVertical = (isAllreadyFlipped != (flipVertical ? true : false)) ? 1 : 0; + + // store primary surface width/height/numMipmaps + image->width = ddsh.dwWidth; + image->height = ddsh.dwHeight; + image->numMipmaps = ddsh.dwFlags & DDS_MIPMAPCOUNT ? ddsh.dwMipMapCount : 1; + + if (image->numMipmaps > QT3DS_DDS_MAX_MIPMAPS) { + throw "Too many mipmaps: max 16"; + } + + // allocate the meta datablock for all mip storage. + Qt3DSDDSAllocDataBlock(io, image); + if (image->dataBlock == NULL) { + throw "Failed to allocate memory for image data storage"; + } + + dib->width = image->width; + dib->height = image->height; + dib->dds = image; + + QT3DSI32 faces = image->cubemap ? 6 : 1; + + QT3DSI32 index = 0; + for (QT3DSI32 j = 0; j < faces; j++) { + // load all surfaces for the image + QT3DSI32 width = image->width; + QT3DSI32 height = image->height; + + for (QT3DSI32 i = 0; i < image->numMipmaps; i++) { + // Get the size, read in the data. + inStream.Read( + NVDataRef((QT3DSU8 *)image->data[index], (QT3DSU32)image->size[index])); + + // Flip in Y for OpenGL if needed + if (flipVertical) + flip_data_vertical(io, (QT3DSI8 *)image->data[index], width, height, image); + + // shrink to next power of 2 + width >>= 1; + height >>= 1; + + if (!width) + width = 1; + + if (!height) + height = 1; + + // make sure DXT isn't <4 on a side... + if (image->compressed) { + if (width < 4) + width = 4; + if (height < 4) + height = 4; + } + + index++; + } + } + + if (needsBGRASwap) { + QT3DSI32 index = 0; + QT3DSI32 k; + + for (k = 0; k < faces; k++) { + QT3DSI32 width = image->width; + QT3DSI32 height = image->height; + + for (QT3DSI32 i = 0; i < image->numMipmaps; i++) { + QT3DSI8 *data = (QT3DSI8 *)(image->data[index]); + QT3DSI32 pixels = width * height; + QT3DSI32 j; + + for (j = 0; j < pixels; j++) { + QT3DSI8 temp = data[0]; + data[0] = data[2]; + data[2] = temp; + + data += 4; + } + + // shrink to next power of 2 + width >>= 1; + height >>= 1; + + if (!width) + width = 1; + + if (!height) + height = 1; + + index++; + } + } + } + } catch (const char *message) { + if (image) { + if (image->dataBlock) + QT3DS_FREE(io->m_Allocator, image->dataBlock); + + QT3DS_FREE(io->m_Allocator, image); + } + if (dib) { + FreeImage_Unload(dib); + } + if (message) { + FreeImage_OutputMessageProc(s_exception_string, message, io); + } + } + + return dib; + } + + SLoadedTexture *SLoadedTexture::LoadDDS(IInStream &inStream, QT3DSI32 flipVertical, + NVFoundationBase &inFnd, + qt3ds::render::NVRenderContextType renderContextType) + { + Q_UNUSED(renderContextType) + FreeImageIO theIO(inFnd.getAllocator(), inFnd); + SLoadedTexture *retval = DoLoadDDS(&theIO, inStream, flipVertical); + + return retval; + } +} +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.h new file mode 100644 index 00000000..8490b474 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureDDS.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#ifndef QT3DS_RENDER_LOAD_DDS_H +#define QT3DS_RENDER_LOAD_DDS_H + +namespace qt3ds { +namespace render { + +/** The maximum number of mipmap levels (per texture or per cubemap face) */ +#define QT3DS_DDS_MAX_MIPMAPS (16) + +/** The number of cubemap faces that must exist in a cubemap-bearing DDS file */ +#define QT3DS_DDS_NUM_CUBEMAP_FACES (6) + + /** The master DDS structure for loading and saving + + This is the master DDS structure. It shouldn't be allocated by hand, + always use NVHHDDSAlloc/NVHHDDSAllocData/NVHHDDSFree to manage them properly. + */ + + struct Qt3DSDDSImage + { + /** Width of the overall texture in texels */ + int width; + /** Height of the overall texture in texels */ + int height; + /** Number of color/alpha components per texel 1-4 */ + int components; + /** The GL type of each color component (noncompressed textures only) */ + int componentFormat; + /** The number of bytes per pixel (noncompressed textures only) */ + int bytesPerPixel; + /** Nonzero if the format is DXT-compressed */ + int compressed; + /** The number of levels in the mipmap pyramid (including the base level) */ + int numMipmaps; + /** If nonzero, then the file contains 6 cubemap faces */ + int cubemap; + /** The format of the loaded texture data */ + int format; + /** The GL internal format of the loaded texture data(compressed textures only) */ + int internalFormat; + /** Nonzero if the texture data includes alpha */ + int alpha; + /** Base of the allocated block of all texel data */ + void *dataBlock; + /** Pointers to the mipmap levels for the texture or each cubemap face */ + void *data[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; + /** Array of sizes of the mipmap levels for the texture or each cubemap face */ + int size[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; + /** Array of widths of the mipmap levels for the texture or each cubemap face */ + int mipwidth[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; + /** Array of heights of the mipmap levels for the texture or each cubemap face */ + int mipheight[QT3DS_DDS_MAX_MIPMAPS * QT3DS_DDS_NUM_CUBEMAP_FACES]; + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h new file mode 100644 index 00000000..13f317bd --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_LOADED_TEXTURE_FREEIMAGE_COMPAT_H +#define QT3DS_RENDER_LOADED_TEXTURE_FREEIMAGE_COMPAT_H +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "EASTL/algorithm.h" +#include +#ifndef _MACOSX +#ifndef _INTEGRITYPLATFORM +#include +#endif +#endif + +// We use a compatibility layer so we can easily convert freeimage code to load our texture formats +// where necessary. + +namespace qt3ds { +namespace render { + using namespace qt3ds::foundation; + + typedef int32_t BOOL; + typedef uint8_t BYTE; + typedef uint16_t WORD; + typedef uint32_t DWORD; + typedef int32_t LONG; + +#define FREEIMAGE_COLORORDER_BGR 0 +#define FREEIMAGE_COLORORDER_RGB 1 + +#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR + + typedef ISeekableIOStream *fi_handle; + + struct FreeImageIO + { + NVAllocatorCallback &m_Allocator; + NVFoundationBase &m_Foundation; + int (*read_proc)(void *data, int size, int itemSize, fi_handle handle); + void (*seek_proc)(fi_handle handle, int offset, int pos); + int (*tell_proc)(fi_handle handle); + static inline int reader(void *data, int size, int itemSize, fi_handle handle) + { + NVDataRef theData(toDataRef((QT3DSU8 *)data, (QT3DSU32)size * itemSize)); + QT3DSU32 amount = handle->Read(theData); + return (int)amount; + } + static inline void seeker(fi_handle handle, int offset, int pos) + { + SeekPosition::Enum seekPos(SeekPosition::Begin); + /* +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 0*/ + switch (pos) { + case 0: + seekPos = SeekPosition::Begin; + break; + case 1: + seekPos = SeekPosition::Current; + break; + case 2: + seekPos = SeekPosition::End; + break; + default: + QT3DS_ASSERT(false); + break; + } + handle->SetPosition(offset, seekPos); + } + static inline int teller(fi_handle handle) { return (int)handle->GetPosition(); } + FreeImageIO(NVAllocatorCallback &alloc, NVFoundationBase &fnd) + : m_Allocator(alloc) + , m_Foundation(fnd) + , read_proc(reader) + , seek_proc(seeker) + , tell_proc(teller) + { + } + }; + + typedef SLoadedTexture FIBITMAP; + inline BYTE *FreeImage_GetBits(FIBITMAP *bmp) { return (BYTE *)bmp->data; } + + inline int FreeImage_GetHeight(FIBITMAP *bmp) { return bmp->height; } + inline int FreeImage_GetWidth(FIBITMAP *bmp) { return bmp->width; } + +#define INPLACESWAP(x, y) eastl::swap(x, y) +#define MIN(x, y) NVMin(x, y) +#define MAX(x, y) NVMax(x, y) + +#define TRUE 1 +#define FALSE 0 + + typedef struct tagBITMAPINFOHEADER + { + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; + } BITMAPINFOHEADER, *PBITMAPINFOHEADER; + + typedef struct tagRGBQUAD + { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; +#else + BYTE rgbRed; + BYTE rgbGreen; + BYTE rgbBlue; +#endif // FREEIMAGE_COLORORDER + BYTE rgbReserved; + } RGBQUAD; + + typedef struct tagRGBTRIPLE + { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; +#else + BYTE rgbtRed; + BYTE rgbtGreen; + BYTE rgbtBlue; +#endif // FREEIMAGE_COLORORDER + } RGBTRIPLE; + + typedef struct tagBITMAPINFO + { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; + } BITMAPINFO, *PBITMAPINFO; + + typedef struct tagFILE_RGBA + { + unsigned char r, g, b, a; + } FILE_RGBA; + + typedef struct tagFILE_BGRA + { + unsigned char b, g, r, a; + } FILE_BGRA; + + typedef struct tagFILE_RGB + { + unsigned char r, g, b; + } FILE_RGB; + + typedef struct tagFILE_BGR + { + unsigned char b, g, r; + } FILE_BGR; + +// Indexes for byte arrays, masks and shifts for treating pixels as words --- +// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- + +#ifndef FREEIMAGE_BIGENDIAN +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Little Endian (x86 / MS Windows, Linux) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x00FF0000 +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x000000FF +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 16 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 0 +#define FI_RGBA_ALPHA_SHIFT 24 +#else +// Little Endian (x86 / MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x000000FF +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x00FF0000 +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 0 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 16 +#define FI_RGBA_ALPHA_SHIFT 24 +#endif // FREEIMAGE_COLORORDER +#else +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Big Endian (PPC / none) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x0000FF00 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0xFF000000 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 8 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 24 +#define FI_RGBA_ALPHA_SHIFT 0 +#else +// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0xFF000000 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0x0000FF00 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 24 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 8 +#define FI_RGBA_ALPHA_SHIFT 0 +#endif // FREEIMAGE_COLORORDER +#endif // FREEIMAGE_BIGENDIAN + +#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK | FI_RGBA_GREEN_MASK | FI_RGBA_BLUE_MASK) + +// The 16bit macros only include masks and shifts, since each color element is not byte aligned + +#define FI16_555_RED_MASK 0x7C00 +#define FI16_555_GREEN_MASK 0x03E0 +#define FI16_555_BLUE_MASK 0x001F +#define FI16_555_RED_SHIFT 10 +#define FI16_555_GREEN_SHIFT 5 +#define FI16_555_BLUE_SHIFT 0 +#define FI16_565_RED_MASK 0xF800 +#define FI16_565_GREEN_MASK 0x07E0 +#define FI16_565_BLUE_MASK 0x001F +#define FI16_565_RED_SHIFT 11 +#define FI16_565_GREEN_SHIFT 5 +#define FI16_565_BLUE_SHIFT 0 + + inline unsigned char HINIBBLE(unsigned char byte) { return byte & 0xF0; } + + inline unsigned char LOWNIBBLE(unsigned char byte) { return byte & 0x0F; } + + inline int CalculateUsedBits(int bits) + { + int bit_count = 0; + unsigned bit = 1; + + for (unsigned i = 0; i < 32; i++) { + if ((bits & bit) == bit) { + bit_count++; + } + + bit <<= 1; + } + + return bit_count; + } + + inline int CalculateLine(int width, int bitdepth) { return ((width * bitdepth) + 7) / 8; } + + inline int CalculatePitch(int line) { return (line + 3) & ~3; } + + inline int CalculateUsedPaletteEntries(int bit_count) + { + if ((bit_count >= 1) && (bit_count <= 8)) + return 1 << bit_count; + + return 0; + } + + inline unsigned char *CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) + { + return (bits + (pitch * scanline)); + } + + inline void ReplaceExtension(char *result, const char *filename, const char *extension) + { + for (size_t i = strlen(filename) - 1; i > 0; --i) { + if (filename[i] == '.') { + memcpy(result, filename, i); + result[i] = '.'; + memcpy(result + i + 1, extension, strlen(extension) + 1); + return; + } + } + + memcpy(result, filename, strlen(filename)); + result[strlen(filename)] = '.'; + memcpy(result + strlen(filename) + 1, extension, strlen(extension) + 1); + } + + inline BYTE *FreeImage_GetScanLine(FIBITMAP *bmp, int height) + { + return CalculateScanLine( + (BYTE *)bmp->data, CalculatePitch(CalculateLine(bmp->width, bmp->m_BitCount)), height); + } + +#define DLL_CALLCONV + +// ignored for now. +#define FreeImage_SetDotsPerMeterX(img, dots) +#define FreeImage_SetDotsPerMeterY(img, dots) + + inline SLoadedTexture *FreeImage_Allocate(int width, int height, int bit_count, FreeImageIO *io) + { + SLoadedTexture *theTexture = QT3DS_NEW(io->m_Allocator, SLoadedTexture)(io->m_Allocator); + int pitch = CalculatePitch(CalculateLine(width, bit_count)); + QT3DSU32 dataSize = (QT3DSU32)(height * pitch); + theTexture->dataSizeInBytes = dataSize; + theTexture->data = io->m_Allocator.allocate(dataSize, "image data", __FILE__, __LINE__); + memZero(theTexture->data, dataSize); + theTexture->width = width; + theTexture->height = height; + theTexture->m_BitCount = bit_count; + // If free image asks us for a palette, we change our format at that time. + theTexture->m_ExtendedFormat = ExtendedTextureFormats::CustomRGB; + return theTexture; + } + + inline SLoadedTexture *FreeImage_Allocate(int width, int height, int bit_count, int rmask, + int gmask, int bmask, FreeImageIO *io) + { + SLoadedTexture *retval = FreeImage_Allocate(width, height, bit_count, io); + retval->m_CustomMasks[0] = rmask; + retval->m_CustomMasks[1] = gmask; + retval->m_CustomMasks[2] = bmask; + return retval; + } + + inline RGBQUAD *FreeImage_GetPalette(SLoadedTexture *texture) + { + if (texture->m_Palette == NULL) { + texture->m_ExtendedFormat = ExtendedTextureFormats::Palettized; + QT3DSU32 memory = 256 * sizeof(RGBQUAD); + if (memory) { + texture->m_Palette = + texture->m_Allocator.allocate(memory, "texture palette", __FILE__, __LINE__); + memZero(texture->m_Palette, memory); + } + } + return (RGBQUAD *)texture->m_Palette; + } + + inline void FreeImage_Unload(SLoadedTexture *texture) { texture->release(); } + inline void FreeImage_OutputMessageProc(int, const char *message, FreeImageIO *io) + { + Q_UNUSED(io); + qCCritical(INVALID_OPERATION, "Error loading image: %s", message); + } + + inline void FreeImage_SetBackgroundColor(SLoadedTexture *texture, RGBQUAD *inColor) + { + if (inColor) { + texture->m_BackgroundColor[0] = inColor->rgbRed; + texture->m_BackgroundColor[1] = inColor->rgbGreen; + texture->m_BackgroundColor[2] = inColor->rgbBlue; + } else + memSet(texture->m_BackgroundColor, 0, 3); + } + + inline void FreeImage_SetTransparencyTable(SLoadedTexture *texture, BYTE *table, int size) + { + if (texture->m_TransparencyTable) + texture->m_Allocator.deallocate(texture->m_TransparencyTable); + texture->m_TransparencyTable = NULL; + if (table && size) { + texture->m_TransparencyTable = (uint8_t *)texture->m_Allocator.allocate( + size, "texture transparency table", __FILE__, __LINE__); + memCopy(texture->m_TransparencyTable, table, size); + } + } +} +} + +using namespace qt3ds::render; + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp new file mode 100644 index 00000000..ece4d3a3 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp @@ -0,0 +1,851 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// ========================================================== +// GIF Loader and Writer +// +// Design and implementation by +// - Ryan Rubley +// - Raphael Gaquer +// +// This file is part of FreeImage 3 +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// ========================================================== +#ifdef _MSC_VER +#pragma warning(disable : 4786) // identifier was truncated to 'number' characters +#endif + +#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" +#include "EASTL/vector.h" +#include "EASTL/string.h" +// ========================================================== +// Metadata declarations +// ========================================================== + +#define GIF_DISPOSAL_UNSPECIFIED 0 +#define GIF_DISPOSAL_LEAVE 1 +#define GIF_DISPOSAL_BACKGROUND 2 +#define GIF_DISPOSAL_PREVIOUS 3 + +// ========================================================== +// Constant/Typedef declarations +// ========================================================== + +struct GIFinfo +{ + BOOL read; + // only really used when reading + size_t global_color_table_offset; + int global_color_table_size; + BYTE background_color; + eastl::vector application_extension_offsets; + eastl::vector comment_extension_offsets; + eastl::vector graphic_control_extension_offsets; + eastl::vector image_descriptor_offsets; + + GIFinfo() + : read(0) + , global_color_table_offset(0) + , global_color_table_size(0) + , background_color(0) + { + } +}; + +struct PageInfo +{ + PageInfo(int d, int l, int t, int w, int h) + { + disposal_method = d; + left = (WORD)l; + top = (WORD)t; + width = (WORD)w; + height = (WORD)h; + } + int disposal_method; + WORD left, top, width, height; +}; + +// GIF defines a max of 12 bits per code +#define MAX_LZW_CODE 4096 + +class StringTable +{ +public: + StringTable(); + ~StringTable(); + void Initialize(int minCodeSize); + BYTE *FillInputBuffer(int len); + void CompressStart(int bpp, int width); + int CompressEnd(BYTE *buf); // 0-4 bytes + bool Compress(BYTE *buf, int *len); + bool Decompress(BYTE *buf, int *len); + void Done(void); + +protected: + bool m_done; + + int m_minCodeSize, m_clearCode, m_endCode, m_nextCode; + + int m_bpp, m_slack; // Compressor information + + int m_prefix; // Compressor state variable + int m_codeSize, m_codeMask; // Compressor/Decompressor state variables + int m_oldCode; // Decompressor state variable + int m_partial, m_partialSize; // Compressor/Decompressor bit buffer + + int firstPixelPassed; // A specific flag that indicates if the first pixel + // of the whole image had already been read + + eastl::string m_strings[MAX_LZW_CODE]; // This is what is really the "string table" data for the + // Decompressor + int *m_strmap; + + // input buffer + BYTE *m_buffer; + int m_bufferSize, m_bufferRealSize, m_bufferPos, m_bufferShift; + + void ClearCompressorTable(void); + void ClearDecompressorTable(void); +}; + +#define GIF_PACKED_LSD_HAVEGCT 0x80 +#define GIF_PACKED_LSD_COLORRES 0x70 +#define GIF_PACKED_LSD_GCTSORTED 0x08 +#define GIF_PACKED_LSD_GCTSIZE 0x07 +#define GIF_PACKED_ID_HAVELCT 0x80 +#define GIF_PACKED_ID_INTERLACED 0x40 +#define GIF_PACKED_ID_LCTSORTED 0x20 +#define GIF_PACKED_ID_RESERVED 0x18 +#define GIF_PACKED_ID_LCTSIZE 0x07 +#define GIF_PACKED_GCE_RESERVED 0xE0 +#define GIF_PACKED_GCE_DISPOSAL 0x1C +#define GIF_PACKED_GCE_WAITINPUT 0x02 +#define GIF_PACKED_GCE_HAVETRANS 0x01 + +#define GIF_BLOCK_IMAGE_DESCRIPTOR 0x2C +#define GIF_BLOCK_EXTENSION 0x21 +#define GIF_BLOCK_TRAILER 0x3B + +#define GIF_EXT_PLAINTEXT 0x01 +#define GIF_EXT_GRAPHIC_CONTROL 0xF9 +#define GIF_EXT_COMMENT 0xFE +#define GIF_EXT_APPLICATION 0xFF + +#define GIF_INTERLACE_PASSES 4 +static int g_GifInterlaceOffset[GIF_INTERLACE_PASSES] = { 0, 4, 2, 1 }; +static int g_GifInterlaceIncrement[GIF_INTERLACE_PASSES] = { 8, 8, 4, 2 }; + +StringTable::StringTable() +{ + m_buffer = NULL; + firstPixelPassed = 0; // Still no pixel read + // Maximum number of entries in the map is MAX_LZW_CODE * 256 + // (aka 2**12 * 2**8 => a 20 bits key) + // This Map could be optmized to only handle MAX_LZW_CODE * 2**(m_bpp) + m_strmap = (int *)new int[1 << 20]; +} + +StringTable::~StringTable() +{ + if (m_buffer != NULL) { + delete[] m_buffer; + } + if (m_strmap != NULL) { + delete[] m_strmap; + m_strmap = NULL; + } +} + +void StringTable::Initialize(int minCodeSize) +{ + m_done = false; + + m_bpp = 8; + m_minCodeSize = minCodeSize; + m_clearCode = 1 << m_minCodeSize; + if (m_clearCode > MAX_LZW_CODE) { + m_clearCode = MAX_LZW_CODE; + } + m_endCode = m_clearCode + 1; + + m_partial = 0; + m_partialSize = 0; + + m_bufferSize = 0; + ClearCompressorTable(); + ClearDecompressorTable(); +} + +BYTE *StringTable::FillInputBuffer(int len) +{ + if (m_buffer == NULL) { + m_buffer = new BYTE[len]; + m_bufferRealSize = len; + } else if (len > m_bufferRealSize) { + delete[] m_buffer; + m_buffer = new BYTE[len]; + m_bufferRealSize = len; + } + m_bufferSize = len; + m_bufferPos = 0; + m_bufferShift = 8 - m_bpp; + return m_buffer; +} + +void StringTable::CompressStart(int bpp, int width) +{ + m_bpp = bpp; + m_slack = (8 - ((width * bpp) % 8)) % 8; + + m_partial |= m_clearCode << m_partialSize; + m_partialSize += m_codeSize; + ClearCompressorTable(); +} + +int StringTable::CompressEnd(BYTE *buf) +{ + int len = 0; + + // output code for remaining prefix + m_partial |= m_prefix << m_partialSize; + m_partialSize += m_codeSize; + while (m_partialSize >= 8) { + *buf++ = (BYTE)m_partial; + m_partial >>= 8; + m_partialSize -= 8; + len++; + } + + // add the end of information code and flush the entire buffer out + m_partial |= m_endCode << m_partialSize; + m_partialSize += m_codeSize; + while (m_partialSize > 0) { + *buf++ = (BYTE)m_partial; + m_partial >>= 8; + m_partialSize -= 8; + len++; + } + + // most this can be is 4 bytes. 7 bits in m_partial to start + 12 for the + // last code + 12 for the end code = 31 bits total. + return len; +} + +bool StringTable::Compress(BYTE *buf, int *len) +{ + if (m_bufferSize == 0 || m_done) { + return false; + } + + int mask = (1 << m_bpp) - 1; + BYTE *bufpos = buf; + while (m_bufferPos < m_bufferSize) { + // get the current pixel value + char ch = (char)((m_buffer[m_bufferPos] >> m_bufferShift) & mask); + + // The next prefix is : + // | + int nextprefix = (((m_prefix) << 8) & 0xFFF00) + (ch & 0x000FF); + if (firstPixelPassed) { + + if (m_strmap[nextprefix] > 0) { + m_prefix = m_strmap[nextprefix]; + } else { + m_partial |= m_prefix << m_partialSize; + m_partialSize += m_codeSize; + // grab full bytes for the output buffer + while (m_partialSize >= 8 && bufpos - buf < *len) { + *bufpos++ = (BYTE)m_partial; + m_partial >>= 8; + m_partialSize -= 8; + } + + // add the code to the "table map" + m_strmap[nextprefix] = m_nextCode; + + // increment the next highest valid code, increase the code size + if (m_nextCode == (1 << m_codeSize)) { + m_codeSize++; + } + m_nextCode++; + + // if we're out of codes, restart the string table + if (m_nextCode == MAX_LZW_CODE) { + m_partial |= m_clearCode << m_partialSize; + m_partialSize += m_codeSize; + ClearCompressorTable(); + } + + // Only keep the 8 lowest bits (prevent problems with "negative chars") + m_prefix = ch & 0x000FF; + } + + // increment to the next pixel + if (m_bufferShift > 0 + && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack)) { + m_bufferShift -= m_bpp; + } else { + m_bufferPos++; + m_bufferShift = 8 - m_bpp; + } + + // jump out here if the output buffer is full + if (bufpos - buf == *len) { + return true; + } + + } else { + // Specific behavior for the first pixel of the whole image + + firstPixelPassed = 1; + // Only keep the 8 lowest bits (prevent problems with "negative chars") + m_prefix = ch & 0x000FF; + + // increment to the next pixel + if (m_bufferShift > 0 + && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack)) { + m_bufferShift -= m_bpp; + } else { + m_bufferPos++; + m_bufferShift = 8 - m_bpp; + } + + // jump out here if the output buffer is full + if (bufpos - buf == *len) { + return true; + } + } + } + + m_bufferSize = 0; + *len = (int)(bufpos - buf); + + return true; +} + +bool StringTable::Decompress(BYTE *buf, int *len) +{ + if (m_bufferSize == 0 || m_done) { + return false; + } + + BYTE *bufpos = buf; + for (; m_bufferPos < m_bufferSize; m_bufferPos++) { + m_partial |= (int)m_buffer[m_bufferPos] << m_partialSize; + m_partialSize += 8; + while (m_partialSize >= m_codeSize) { + int code = m_partial & m_codeMask; + m_partial >>= m_codeSize; + m_partialSize -= m_codeSize; + + if (code > m_nextCode || (m_nextCode == MAX_LZW_CODE && code != m_clearCode) + || code == m_endCode) { + m_done = true; + *len = (int)(bufpos - buf); + return true; + } + if (code == m_clearCode) { + ClearDecompressorTable(); + continue; + } + + // add new string to string table, if not the first pass since a clear code + if (m_oldCode != MAX_LZW_CODE) { + m_strings[m_nextCode] = + m_strings[m_oldCode] + m_strings[code == m_nextCode ? m_oldCode : code][0]; + } + + if ((int)m_strings[code].size() > *len - (bufpos - buf)) { + // out of space, stuff the code back in for next time + m_partial <<= m_codeSize; + m_partialSize += m_codeSize; + m_partial |= code; + m_bufferPos++; + *len = (int)(bufpos - buf); + return true; + } + + // output the string into the buffer + memcpy(bufpos, m_strings[code].data(), m_strings[code].size()); + bufpos += m_strings[code].size(); + + // increment the next highest valid code, add a bit to the mask if we need to increase + // the code size + if (m_oldCode != MAX_LZW_CODE && m_nextCode < MAX_LZW_CODE) { + if (++m_nextCode < MAX_LZW_CODE) { + if ((m_nextCode & m_codeMask) == 0) { + m_codeSize++; + m_codeMask |= m_nextCode; + } + } + } + + m_oldCode = code; + } + } + + m_bufferSize = 0; + *len = (int)(bufpos - buf); + + return true; +} + +void StringTable::Done(void) +{ + m_done = true; +} + +void StringTable::ClearCompressorTable(void) +{ + if (m_strmap) { + memset(m_strmap, 0xFF, sizeof(unsigned int) * (1 << 20)); + } + m_nextCode = m_endCode + 1; + + m_prefix = 0; + m_codeSize = m_minCodeSize + 1; +} + +void StringTable::ClearDecompressorTable(void) +{ + for (int i = 0; i < m_clearCode; i++) { + m_strings[i].resize(1); + m_strings[i][0] = (char)i; + } + m_nextCode = m_endCode + 1; + + m_codeSize = m_minCodeSize + 1; + m_codeMask = (1 << m_codeSize) - 1; + m_oldCode = MAX_LZW_CODE; +} + +// ========================================================== +// Plugin Interface +// ========================================================== + +static int s_format_id; + +// ========================================================== +// Plugin Implementation +// ========================================================== + +static BOOL DLL_CALLCONV Validate(FreeImageIO *io, fi_handle handle) +{ + char buf[6]; + if (io->read_proc(buf, 6, 1, handle) < 1) { + return FALSE; + } + + BOOL bResult = FALSE; + if (!strncmp(buf, "GIF", 3)) { + if (buf[3] >= '0' && buf[3] <= '9' && buf[4] >= '0' && buf[4] <= '9' && buf[5] >= 'a' + && buf[5] <= 'z') { + bResult = TRUE; + } + } + + io->seek_proc(handle, -6, SEEK_CUR); + + return bResult; +} + +// ---------------------------------------------------------- + +static void *DLL_CALLCONV Open(FreeImageIO *io, fi_handle handle) +{ + GIFinfo *info = new GIFinfo; + if (info == NULL) { + return NULL; + } + BOOL read = TRUE; + + // 25/02/2008 MDA: Not safe to memset GIFinfo structure with VS 2008 (safe iterators), + // perform initialization in constructor instead. + // memset(info, 0, sizeof(GIFinfo)); + + info->read = read; + try { + // Header + if (!Validate(io, handle)) { + throw "Not a GIF file"; + } + io->seek_proc(handle, 6, SEEK_CUR); + + // Logical Screen Descriptor + io->seek_proc(handle, 4, SEEK_CUR); + BYTE packed; + if (io->read_proc(&packed, 1, 1, handle) < 1) { + throw "EOF reading Logical Screen Descriptor"; + } + if (io->read_proc(&info->background_color, 1, 1, handle) < 1) { + throw "EOF reading Logical Screen Descriptor"; + } + io->seek_proc(handle, 1, SEEK_CUR); + + // Global Color Table + if (packed & GIF_PACKED_LSD_HAVEGCT) { + info->global_color_table_offset = io->tell_proc(handle); + info->global_color_table_size = 2 << (packed & GIF_PACKED_LSD_GCTSIZE); + io->seek_proc(handle, 3 * info->global_color_table_size, SEEK_CUR); + } + + // Scan through all the rest of the blocks, saving offsets + size_t gce_offset = 0; + BYTE block = 0; + while (block != GIF_BLOCK_TRAILER) { + if (io->read_proc(&block, 1, 1, handle) < 1) { + throw "EOF reading blocks"; + } + if (block == GIF_BLOCK_IMAGE_DESCRIPTOR) { + info->image_descriptor_offsets.push_back(io->tell_proc(handle)); + // GCE may be 0, meaning no GCE preceded this ID + info->graphic_control_extension_offsets.push_back(gce_offset); + gce_offset = 0; + + io->seek_proc(handle, 8, SEEK_CUR); + if (io->read_proc(&packed, 1, 1, handle) < 1) { + throw "EOF reading Image Descriptor"; + } + + // Local Color Table + if (packed & GIF_PACKED_ID_HAVELCT) { + io->seek_proc(handle, 3 * (2 << (packed & GIF_PACKED_ID_LCTSIZE)), SEEK_CUR); + } + + // LZW Minimum Code Size + io->seek_proc(handle, 1, SEEK_CUR); + } else if (block == GIF_BLOCK_EXTENSION) { + BYTE ext; + if (io->read_proc(&ext, 1, 1, handle) < 1) { + throw "EOF reading extension"; + } + + if (ext == GIF_EXT_GRAPHIC_CONTROL) { + // overwrite previous offset if more than one GCE found before an ID + gce_offset = io->tell_proc(handle); + } else if (ext == GIF_EXT_COMMENT) { + info->comment_extension_offsets.push_back(io->tell_proc(handle)); + } else if (ext == GIF_EXT_APPLICATION) { + info->application_extension_offsets.push_back(io->tell_proc(handle)); + } + } else if (block == GIF_BLOCK_TRAILER) { + continue; + } else { + throw "Invalid GIF block found"; + } + + // Data Sub-blocks + BYTE len; + if (io->read_proc(&len, 1, 1, handle) < 1) { + throw "EOF reading sub-block"; + } + while (len != 0) { + io->seek_proc(handle, len, SEEK_CUR); + if (io->read_proc(&len, 1, 1, handle) < 1) { + throw "EOF reading sub-block"; + } + } + } + } catch (const char *msg) { + FreeImage_OutputMessageProc(s_format_id, msg, io); + delete info; + return NULL; + } + + return info; +} + +static FIBITMAP *DLL_CALLCONV DoLoadGIF(FreeImageIO *io, fi_handle handle, int flags, void *data) +{ + if (data == NULL) { + return NULL; + } + (void)flags; + GIFinfo *info = (GIFinfo *)data; + + int page = 0; + FIBITMAP *dib = NULL; + try { + bool have_transparent = false, no_local_palette = false, interlaced = false; + int disposal_method = GIF_DISPOSAL_LEAVE, transparent_color = 0; + WORD left, top, width, height; + BYTE packed, b; + WORD w; + + // Image Descriptor + io->seek_proc(handle, (long)info->image_descriptor_offsets[page], SEEK_SET); + io->read_proc(&left, 2, 1, handle); + io->read_proc(&top, 2, 1, handle); + io->read_proc(&width, 2, 1, handle); + io->read_proc(&height, 2, 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapShort(&left); + SwapShort(&top); + SwapShort(&width); + SwapShort(&height); +#endif + io->read_proc(&packed, 1, 1, handle); + interlaced = (packed & GIF_PACKED_ID_INTERLACED) ? true : false; + no_local_palette = (packed & GIF_PACKED_ID_HAVELCT) ? false : true; + + int bpp = 8; + if (!no_local_palette) { + int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE); + if (size <= 2) + bpp = 1; + else if (size <= 16) + bpp = 4; + } else if (info->global_color_table_offset != 0) { + if (info->global_color_table_size <= 2) + bpp = 1; + else if (info->global_color_table_size <= 16) + bpp = 4; + } + dib = FreeImage_Allocate(width, height, bpp, io); + if (dib == NULL) { + throw "DIB allocated failed"; + } + + // Palette + RGBQUAD *pal = FreeImage_GetPalette(dib); + if (!no_local_palette) { + int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE); + + int i = 0; + while (i < size) { + io->read_proc(&pal[i].rgbRed, 1, 1, handle); + io->read_proc(&pal[i].rgbGreen, 1, 1, handle); + io->read_proc(&pal[i].rgbBlue, 1, 1, handle); + i++; + } + } else if (info->global_color_table_offset != 0) { + long pos = io->tell_proc(handle); + io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET); + + int i = 0; + while (i < info->global_color_table_size) { + io->read_proc(&pal[i].rgbRed, 1, 1, handle); + io->read_proc(&pal[i].rgbGreen, 1, 1, handle); + io->read_proc(&pal[i].rgbBlue, 1, 1, handle); + i++; + } + + io->seek_proc(handle, pos, SEEK_SET); + } else { + // its legal to have no palette, but we're going to generate *something* + for (int i = 0; i < 256; i++) { + pal[i].rgbRed = (BYTE)i; + pal[i].rgbGreen = (BYTE)i; + pal[i].rgbBlue = (BYTE)i; + } + } + + // LZW Minimum Code Size + io->read_proc(&b, 1, 1, handle); + StringTable *stringtable = new StringTable; + stringtable->Initialize(b); + + // Image Data Sub-blocks + int x = 0, xpos = 0, y = 0, shift = 8 - bpp, mask = (1 << bpp) - 1, interlacepass = 0; + BYTE *scanline = FreeImage_GetScanLine(dib, height - 1); + BYTE buf[4096]; + io->read_proc(&b, 1, 1, handle); + while (b) { + io->read_proc(stringtable->FillInputBuffer(b), b, 1, handle); + int size = sizeof(buf); + while (stringtable->Decompress(buf, &size)) { + for (int i = 0; i < size; i++) { + scanline[xpos] |= (buf[i] & mask) << shift; + if (shift > 0) { + shift -= bpp; + } else { + xpos++; + shift = 8 - bpp; + } + if (++x >= width) { + if (interlaced) { + y += g_GifInterlaceIncrement[interlacepass]; + if (y >= height && ++interlacepass < GIF_INTERLACE_PASSES) { + y = g_GifInterlaceOffset[interlacepass]; + } + } else { + y++; + } + if (y >= height) { + stringtable->Done(); + break; + } + x = xpos = 0; + shift = 8 - bpp; + scanline = FreeImage_GetScanLine(dib, height - y - 1); + } + } + size = sizeof(buf); + } + io->read_proc(&b, 1, 1, handle); + } + + if (page == 0) { + QT3DSU32 idx; + + // Logical Screen Descriptor + io->seek_proc(handle, 6, SEEK_SET); + WORD logicalwidth, logicalheight; + io->read_proc(&logicalwidth, 2, 1, handle); + io->read_proc(&logicalheight, 2, 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapShort(&logicalwidth); + SwapShort(&logicalheight); +#endif + + // Global Color Table + if (info->global_color_table_offset != 0) { + RGBQUAD globalpalette[256]; + io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET); + int i = 0; + while (i < info->global_color_table_size) { + io->read_proc(&globalpalette[i].rgbRed, 1, 1, handle); + io->read_proc(&globalpalette[i].rgbGreen, 1, 1, handle); + io->read_proc(&globalpalette[i].rgbBlue, 1, 1, handle); + globalpalette[i].rgbReserved = 0; + i++; + } + // background color + if (info->background_color < info->global_color_table_size) { + FreeImage_SetBackgroundColor(dib, &globalpalette[info->background_color]); + } + } + + // Application Extension + LONG loop = 1; // If no AE with a loop count is found, the default must be 1 + for (idx = 0; idx < info->application_extension_offsets.size(); idx++) { + io->seek_proc(handle, (long)info->application_extension_offsets[idx], SEEK_SET); + io->read_proc(&b, 1, 1, handle); + if (b == 11) { // All AEs start with an 11 byte sub-block to determine what type of + // AE it is + char buf[11]; + io->read_proc(buf, 11, 1, handle); + if (!memcmp(buf, "NETSCAPE2.0", 11) + || !memcmp(buf, "ANIMEXTS1.0", + 11)) { // Not everybody recognizes ANIMEXTS1.0 but it is valid + io->read_proc(&b, 1, 1, handle); + if (b == 3) { // we're supposed to have a 3 byte sub-block now + io->read_proc(&b, 1, 1, + handle); // this should be 0x01 but isn't really important + io->read_proc(&w, 2, 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapShort(&w); +#endif + loop = w; + if (loop > 0) + loop++; + break; + } + } + } + } + } + + // Graphic Control Extension + if (info->graphic_control_extension_offsets[page] != 0) { + io->seek_proc(handle, (long)(info->graphic_control_extension_offsets[page] + 1), + SEEK_SET); + io->read_proc(&packed, 1, 1, handle); + io->read_proc(&w, 2, 1, handle); +#ifdef FREEIMAGE_BIGENDIAN + SwapShort(&w); +#endif + io->read_proc(&b, 1, 1, handle); + have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false; + disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2; + + transparent_color = b; + if (have_transparent) { + int size = 1 << bpp; + if (transparent_color <= size) { + BYTE table[256]; + memset(table, 0xFF, size); + table[transparent_color] = 0; + FreeImage_SetTransparencyTable(dib, table, size); + dib->m_TransparentPaletteIndex = b; + } + } + } + b = (BYTE)disposal_method; + + delete stringtable; + + } catch (const char *msg) { + if (dib != NULL) { + FreeImage_Unload(dib); + } + FreeImage_OutputMessageProc(s_format_id, msg, io); + return NULL; + } + + return dib; +} + +static void DLL_CALLCONV Close(void *data) +{ + if (data == NULL) { + return; + } + GIFinfo *info = (GIFinfo *)data; + delete info; +} + +SLoadedTexture *SLoadedTexture::LoadGIF(ISeekableIOStream &inStream, bool inFlipY, + NVFoundationBase &inFnd, + qt3ds::render::NVRenderContextType renderContextType) +{ + Q_UNUSED(renderContextType) + FreeImageIO theIO(inFnd.getAllocator(), inFnd); + void *gifData = Open(&theIO, &inStream); + if (gifData) { + SLoadedTexture *retval = DoLoadGIF(&theIO, &inStream, 0, gifData); + Close(gifData); + if (retval) + retval->FreeImagePostProcess(inFlipY); + return retval; + } + return NULL; +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureHDR.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureHDR.cpp new file mode 100644 index 00000000..defff295 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureHDR.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2014 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// ========================================================== +// Radiance RGBE .HDR Loader +// Decodes Radiance RGBE HDR image into FP16 texture buffer. +// +// Implementation by +// Parashar Krishnamachari (parashark@nvidia.com) +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// ========================================================== + +#include "Qt3DSRenderLoadedTextureFreeImageCompat.h" +#include "render/Qt3DSRenderBaseTypes.h" + +typedef unsigned char RGBE[4]; +#define R 0 +#define G 1 +#define B 2 +#define E 3 + +#define MINELEN 8 // minimum scanline length for encoding +#define MAXELEN 0x7fff // maximum scanline length for encoding + +static int s_format_id; + +static float convertComponent(int exponent, int val) +{ + float v = val / (256.0f); + float d = powf(2.0f, (float)exponent - 128.0f); + return v * d; +} + +static void decrunchScanlineOld(FreeImageIO *io, fi_handle handle, RGBE *scanline, int width) +{ + int i; + int rshift = 0; + + while (width > 0) { + io->read_proc(scanline, 4, 1, handle); + + // The older version of RLE encodes the length in the exponent. + // and marks a run with 1, 1, 1 in RGB. This is differentiated from + // a raw value of 1, 1, 1, by having a exponent of 0; + if (scanline[0][R] == 1 && scanline[0][G] == 1 && scanline[0][B] == 1) { + for (i = (scanline[0][E] << rshift); i > 0; --i) { + memcpy(&scanline[0][0], &scanline[-1][0], 4); + ++scanline; + --width; + } + rshift += 8; + } else { + ++scanline; + --width; + rshift = 0; + } + } +} + +static void decrunchScanline(FreeImageIO *io, fi_handle handle, RGBE *scanline, int width) +{ + if ((width < MINELEN) || (width > MAXELEN)) { + decrunchScanlineOld(io, handle, scanline, width); + return; + } + + char c; + io->read_proc(&c, 1, 1, handle); + if (c != 2) { + io->seek_proc(handle, -1, SEEK_CUR); + decrunchScanlineOld(io, handle, scanline, width); + return; + } + + io->read_proc(&(scanline[0][G]), 1, 1, handle); + io->read_proc(&(scanline[0][B]), 1, 1, handle); + io->read_proc(&c, 1, 1, handle); + + if (scanline[0][G] != 2 || scanline[0][B] & 128) { + scanline[0][R] = 2; + scanline[0][E] = c; + decrunchScanlineOld(io, handle, scanline + 1, width - 1); + } + + // RLE-encoded version does a separate buffer for each channel per scanline + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < width;) { + unsigned char code, val; + io->read_proc(&code, 1, 1, handle); + if (code + > 128) // RLE-encoded run... read 1 value and copy it forward for some n count. + { + code &= 127; + io->read_proc(&val, 1, 1, handle); + while (code--) + scanline[j++][i] = val; + } else // Not a run, so we read it as raw data + { + // Note -- we store each pixel in memory 4 bytes apart, so we can't just + // do one long read. + while (code--) + io->read_proc(&(scanline[j++][i]), 1, 1, handle); + } + } + } +} + +static void decodeScanlineToTexture(RGBE *scanline, int width, void *outBuf, QT3DSU32 offset, + NVRenderTextureFormats::Enum inFormat) +{ + float rgbaF32[4]; + + for (int i = 0; i < width; ++i) { + rgbaF32[R] = convertComponent(scanline[i][E], scanline[i][R]); + rgbaF32[G] = convertComponent(scanline[i][E], scanline[i][G]); + rgbaF32[B] = convertComponent(scanline[i][E], scanline[i][B]); + rgbaF32[3] = 1.0f; + + QT3DSU8 *target = reinterpret_cast(outBuf); + target += offset; + NVRenderTextureFormats::encodeToPixel( + rgbaF32, target, i * NVRenderTextureFormats::getSizeofFormat(inFormat), inFormat); + } +} + +static FIBITMAP *DoLoadHDR(FreeImageIO *io, fi_handle handle, + NVRenderTextureFormats::Enum inFormat = NVRenderTextureFormats::RGB32F) +{ + FIBITMAP *dib = NULL; + try { + if (handle != NULL) { + char str[200]; + int i; + + // Make sure it's a Radiance RGBE file + io->read_proc(str, 10, 1, handle); + if (memcmp(str, "#?RADIANCE", 10)) { + throw "Invalid HDR file"; + } + + io->seek_proc(handle, 1, SEEK_CUR); + + // Get the command string (it's not really important for us; We're always assuming + // 32bit_rle_rgbe is the format + // we're just reading it to skip ahead the correct number of bytes). + i = 0; + char c = 0, prevC; + do { + prevC = c; + io->read_proc(&c, 1, 1, handle); + str[i++] = c; + } while (!(c == 0xa && prevC == 0xa)); + + // Get the resolution string (it will be NULL-terminated for us) + char res[200]; + i = 0; + do { + io->read_proc(&c, 1, 1, handle); + res[i++] = c; + } while (c != 0xa); + res[i] = 0; + + int width, height; + if (!sscanf(res, "-Y %d +X %d", &height, &width)) { + throw "Error encountered while loading HDR stream : could not determine image " + "resolution!"; + } + int bytesPerPixel = NVRenderTextureFormats::getSizeofFormat(inFormat); + dib = FreeImage_Allocate(width, height, bytesPerPixel * 8, io); + if (dib == NULL) { + throw "DIB allocation failed"; + } + + dib->format = inFormat; + dib->components = NVRenderTextureFormats::getNumberOfComponent(inFormat); + + // Allocate a scanline worth of RGBE data + RGBE *scanline = new RGBE[width]; + if (!scanline) { + throw "Error encountered while loading HDR stream : could not buffer scanlines!"; + } + + // Go through all the scanlines + for (int y = 0; y < height; ++y) { + QT3DSU32 byteOfs = (height - 1 - y) * width * bytesPerPixel; + decrunchScanline(io, handle, scanline, width); + decodeScanlineToTexture(scanline, width, dib->data, byteOfs, inFormat); + } + } + return dib; + } catch (const char *message) { + if (dib) { + FreeImage_Unload(dib); + } + if (message) { + FreeImage_OutputMessageProc(s_format_id, message, io); + } + } + + return NULL; +} + +SLoadedTexture *SLoadedTexture::LoadHDR(ISeekableIOStream &inStream, NVFoundationBase &inFnd, + qt3ds::render::NVRenderContextType renderContextType) +{ + FreeImageIO theIO(inFnd.getAllocator(), inFnd); + SLoadedTexture *retval = nullptr; + if (renderContextType == qt3ds::render::NVRenderContextValues::GLES2) + retval = DoLoadHDR(&theIO, &inStream, NVRenderTextureFormats::RGBA8); + else + retval = DoLoadHDR(&theIO, &inStream, NVRenderTextureFormats::RGBA16F); + + + // Let's just assume we don't support this just yet. + // if ( retval ) + // retval->FreeImagePostProcess( inFlipY ); + return retval; +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp new file mode 100644 index 00000000..b1d4b050 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "Qt3DSRenderLoadedTextureKTX.h" +#include "Qt3DSRenderLoadedTextureDDS.h" + +#include +#include + +using namespace qt3ds::render; +using namespace qt3ds::foundation; + +namespace qt3ds { +namespace render { + +static inline int blockSizeForTextureFormat(int format) +{ + switch (format) { + case QOpenGLTexture::RGB8_ETC1: + case QOpenGLTexture::RGB8_ETC2: + case QOpenGLTexture::SRGB8_ETC2: + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::R11_EAC_UNorm: + case QOpenGLTexture::R11_EAC_SNorm: + case QOpenGLTexture::RGB_DXT1: + return 8; + + default: + return 16; + } +} + +static inline int runtimeFormat(quint32 internalFormat) +{ + switch (internalFormat) { + case QOpenGLTexture::RGB8_ETC1: + return NVRenderTextureFormats::RGB8_ETC1; + case QOpenGLTexture::RGB8_ETC2: + return NVRenderTextureFormats::RGB8_ETC2; + case QOpenGLTexture::SRGB8_ETC2: + return NVRenderTextureFormats::SRGB8_ETC2; + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + return NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2; + case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: + return NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2; + case QOpenGLTexture::R11_EAC_UNorm: + return NVRenderTextureFormats::R11_EAC_UNorm; + case QOpenGLTexture::R11_EAC_SNorm: + return NVRenderTextureFormats::R11_EAC_SNorm; + case QOpenGLTexture::RGB_DXT1: + return NVRenderTextureFormats::RGB_DXT1; + case QOpenGLTexture::RGBA_DXT1: + return NVRenderTextureFormats::RGBA_DXT3; + case QOpenGLTexture::RGBA_DXT3: + return NVRenderTextureFormats::RGBA_DXT3; + case QOpenGLTexture::RGBA_DXT5: + return NVRenderTextureFormats::RGBA_DXT5; + default: + break; + } + return NVRenderTextureFormats::Unknown; +} + +static inline int imageSize(QT3DSI32 width, QT3DSI32 height, const Qt3DSDDSImage *image) +{ + return ((width + 3) / 4) * ((height + 3) / 4) + * blockSizeForTextureFormat(image->internalFormat); +} + +static inline quint32 totalImageDataSize(Qt3DSDDSImage *image) +{ + int i, j; + int index = 0; + quint32 size = 0; + int w, h; + int cubeCount = image->cubemap ? 6 : 1; + + for (j = 0; j < cubeCount; j++) { + w = image->width; + h = image->height; + + for (i = 0; i < image->numMipmaps; i++) // account for base plus each mip + { + size += 4; // image size is saved in the file + image->size[index] = imageSize(w, h, image); + image->mipwidth[index] = w; + image->mipheight[index] = h; + size += quint32(image->size[index]); + if (w != 1) + w >>= 1; + if (h != 1) + h >>= 1; + + index++; + } + } + + return (size); +} + +static inline quint32 alignedOffset(quint32 offset, quint32 byteAlign) +{ + return (offset + byteAlign - 1) & ~(byteAlign - 1); +} + +inline SLoadedTexture *loadKtx(NVAllocatorCallback &allocator, IInStream &inStream, + QT3DSI32 flipVertical) +{ + static const int KTX_IDENTIFIER_LENGTH = 12; + static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { + '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' + }; + static const quint32 platformEndianIdentifier = 0x04030201; + static const quint32 inversePlatformEndianIdentifier = 0x01020304; + + struct KTXHeader { + quint8 identifier[KTX_IDENTIFIER_LENGTH]; + quint32 endianness; + quint32 glType; + quint32 glTypeSize; + quint32 glFormat; + quint32 glInternalFormat; + quint32 glBaseInternalFormat; + quint32 pixelWidth; + quint32 pixelHeight; + quint32 pixelDepth; + quint32 numberOfArrayElements; + quint32 numberOfFaces; + quint32 numberOfMipmapLevels; + quint32 bytesOfKeyValueData; + }; + + KTXHeader header; + if (inStream.Read(header) != sizeof(header) + || qstrncmp(reinterpret_cast(header.identifier), + ktxIdentifier, KTX_IDENTIFIER_LENGTH) != 0 + || (header.endianness != platformEndianIdentifier + && header.endianness != inversePlatformEndianIdentifier)) { + return nullptr; + } + + const bool isInverseEndian = (header.endianness == inversePlatformEndianIdentifier); + auto decode = [isInverseEndian](quint32 val) { + return isInverseEndian ? qbswap(val) : val; + }; + + const bool isCompressed = decode(header.glType) == 0 && decode(header.glFormat) == 0 + && decode(header.glTypeSize) == 1; + if (!isCompressed) { + qWarning("Uncompressed ktx texture data is not supported"); + return nullptr; + } + + if (decode(header.numberOfArrayElements) != 0) { + qWarning("Array ktx textures not supported"); + return nullptr; + } + + if (decode(header.pixelDepth) != 0) { + qWarning("Only 2D and cube ktx textures are supported"); + return nullptr; + } + + const int bytesToSkip = int(decode(header.bytesOfKeyValueData)); + QVector skipData; + skipData.resize(bytesToSkip); + if (inStream.Read(NVDataRef(skipData.data(), bytesToSkip)) != bytesToSkip) { + qWarning("Unexpected end of ktx data"); + return nullptr; + } + + // now for each mipmap level we have (arrays and 3d textures not supported here) + // uint32 imageSize + // for each array element + // for each face + // for each z slice + // compressed data + // padding so that each face data starts at an offset that is a multiple of 4 + // padding so that each imageSize starts at an offset that is a multiple of 4 + + Qt3DSDDSImage *image = (Qt3DSDDSImage *)QT3DS_ALLOC(allocator, sizeof(Qt3DSDDSImage), "DoLoadDDS"); + + const quint32 level0Width = decode(header.pixelWidth); + const quint32 level0Height = decode(header.pixelHeight); + quint32 faceCount = decode(header.numberOfFaces); + const quint32 mipMapLevels = decode(header.numberOfMipmapLevels); + const quint32 format = decode(header.glInternalFormat); + image->numMipmaps = int(mipMapLevels); + image->cubemap = faceCount == 6 ? 6 : 0; + image->internalFormat = int(format); + image->format = runtimeFormat(format); + image->width = int(level0Width); + image->height = int(level0Height); + image->compressed = 1; + quint32 totalSize = totalImageDataSize(image); + image->dataBlock = QT3DS_ALLOC(allocator, totalSize, "Qt3DSDDSAllocDataBlock"); + if (inStream.Read(NVDataRef(reinterpret_cast(image->dataBlock), totalSize)) + != totalSize) { + QT3DS_FREE(allocator, image); + return nullptr; + } + + SLoadedTexture *result = QT3DS_NEW(allocator, SLoadedTexture)(allocator); + result->dds = image; + result->width = int(level0Width); + result->height = int(level0Height); + result->format = static_cast(image->format); + + // TODO: Proper support for cubemaps should be implemented at some point. + if (faceCount > 1) { + qWarning("Multiple faces (cubemaps) not currently supported in ktx"); + faceCount = 1; + } + + uint8_t *p = reinterpret_cast(image->dataBlock); + uint8_t *basep = p; + + for (quint32 mip = 0; mip < mipMapLevels; ++mip) { + if (p + 4 - basep > totalSize) + break; + const quint32 imageSize = *reinterpret_cast(p); + p += 4; + for (quint32 face = 0; face < faceCount; ++face) { + const quint32 nextOffset = quint32(p + imageSize - basep); + if (nextOffset > totalSize) + break; + image->data[mip] = reinterpret_cast(p); + p = basep + alignedOffset(nextOffset, 4); + } + } + + return result; +} + +SLoadedTexture *SLoadedTexture::LoadKTX(IInStream &inStream, QT3DSI32 flipVertical, + NVFoundationBase &inFnd, + qt3ds::render::NVRenderContextType renderContextType) +{ + Q_UNUSED(renderContextType) + SLoadedTexture *retval = loadKtx(inFnd.getAllocator(), inStream, flipVertical); + + return retval; +} + +} +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.h new file mode 100644 index 00000000..3a2d7628 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.h @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_LOAD_KTX_H +#define QT3DS_RENDER_LOAD_KTX_H + +namespace qt3ds { +namespace render { + +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.cpp new file mode 100644 index 00000000..023964f5 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.cpp @@ -0,0 +1,599 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSRenderPrefilterTexture.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +#include + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace qt3ds::foundation; + +Qt3DSRenderPrefilterTexture::Qt3DSRenderPrefilterTexture(NVRenderContext *inNVRenderContext, + QT3DSI32 inWidth, QT3DSI32 inHeight, + NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, + NVFoundationBase &inFnd) + : m_Foundation(inFnd) + , mRefCount(0) + , m_Texture2D(inTexture2D) + , m_DestinationFormat(inDestFormat) + , m_Width(inWidth) + , m_Height(inHeight) + , m_NVRenderContext(inNVRenderContext) +{ + // Calculate mip level + int maxDim = inWidth >= inHeight ? inWidth : inHeight; + + m_MaxMipMapLevel = static_cast(logf((float)maxDim) / logf(2.0f)); + // no concept of sizeOfFormat just does'nt make sense + m_SizeOfFormat = NVRenderTextureFormats::getSizeofFormat(m_DestinationFormat); + m_NoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_DestinationFormat); +} + +Qt3DSRenderPrefilterTexture * +Qt3DSRenderPrefilterTexture::Create(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, QT3DSI32 inHeight, + NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd) +{ + Qt3DSRenderPrefilterTexture *theBSDFMipMap = NULL; + + if (inNVRenderContext->IsComputeSupported()) { + theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), Qt3DSRenderPrefilterTextureCompute)( + inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); + } + + if (!theBSDFMipMap) { + theBSDFMipMap = QT3DS_NEW(inFnd.getAllocator(), Qt3DSRenderPrefilterTextureCPU)( + inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, inFnd); + } + + if (theBSDFMipMap) + theBSDFMipMap->addRef(); + + return theBSDFMipMap; +} + +Qt3DSRenderPrefilterTexture::~Qt3DSRenderPrefilterTexture() +{ +} + +//------------------------------------------------------------------------------------ +// CPU based filtering +//------------------------------------------------------------------------------------ + +Qt3DSRenderPrefilterTextureCPU::Qt3DSRenderPrefilterTextureCPU( + NVRenderContext *inNVRenderContext, int inWidth, int inHeight, NVRenderTexture2D &inTexture2D, + NVRenderTextureFormats::Enum inDestFormat, NVFoundationBase &inFnd) + : Qt3DSRenderPrefilterTexture(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, + inFnd) +{ +} + +inline int Qt3DSRenderPrefilterTextureCPU::wrapMod(int a, int base) +{ + return (a >= 0) ? a % base : (a % base) + base; +} + +inline void Qt3DSRenderPrefilterTextureCPU::getWrappedCoords(int &sX, int &sY, int width, int height) +{ + if (sY < 0) { + sX -= width >> 1; + sY = -sY; + } + if (sY >= height) { + sX += width >> 1; + sY = height - sY; + } + sX = wrapMod(sX, width); +} + +STextureData +Qt3DSRenderPrefilterTextureCPU::CreateBsdfMipLevel(STextureData &inCurMipLevel, + STextureData &inPrevMipLevel, int width, + int height) //, IPerfTimer& inPerfTimer ) +{ + STextureData retval; + int newWidth = width >> 1; + int newHeight = height >> 1; + newWidth = newWidth >= 1 ? newWidth : 1; + newHeight = newHeight >= 1 ? newHeight : 1; + + if (inCurMipLevel.data) { + retval = inCurMipLevel; + retval.dataSizeInBytes = + newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); + } else { + retval.dataSizeInBytes = + newWidth * newHeight * NVRenderTextureFormats::getSizeofFormat(inPrevMipLevel.format); + retval.format = inPrevMipLevel.format; // inLoadedImage.format; + retval.data = m_Foundation.getAllocator().allocate( + retval.dataSizeInBytes, "Bsdf Scaled Image Data", __FILE__, __LINE__); + } + + for (int y = 0; y < newHeight; ++y) { + for (int x = 0; x < newWidth; ++x) { + float accumVal[4]; + accumVal[0] = 0; + accumVal[1] = 0; + accumVal[2] = 0; + accumVal[3] = 0; + for (int sy = -2; sy <= 2; ++sy) { + for (int sx = -2; sx <= 2; ++sx) { + int sampleX = sx + (x << 1); + int sampleY = sy + (y << 1); + getWrappedCoords(sampleX, sampleY, width, height); + + // Cauchy filter (this is simply because it's the easiest to evaluate, and + // requires no complex + // functions). + float filterPdf = 1.f / (1.f + float(sx * sx + sy * sy) * 2.f); + // With FP HDR formats, we're not worried about intensity loss so much as + // unnecessary energy gain, + // whereas with LDR formats, the fear with a continuous normalization factor is + // that we'd lose + // intensity and saturation as well. + filterPdf /= (NVRenderTextureFormats::getSizeofFormat(retval.format) >= 8) + ? 4.71238898f + : 4.5403446f; + // filterPdf /= 4.5403446f; // Discrete normalization factor + // filterPdf /= 4.71238898f; // Continuous normalization factor + float curPix[4]; + QT3DSI32 byteOffset = (sampleY * width + sampleX) + * NVRenderTextureFormats::getSizeofFormat(retval.format); + if (byteOffset < 0) { + sampleY = height + sampleY; + byteOffset = (sampleY * width + sampleX) + * NVRenderTextureFormats::getSizeofFormat(retval.format); + } + + NVRenderTextureFormats::decodeToFloat(inPrevMipLevel.data, byteOffset, curPix, + retval.format); + + accumVal[0] += filterPdf * curPix[0]; + accumVal[1] += filterPdf * curPix[1]; + accumVal[2] += filterPdf * curPix[2]; + accumVal[3] += filterPdf * curPix[3]; + } + } + + QT3DSU32 newIdx = + (y * newWidth + x) * NVRenderTextureFormats::getSizeofFormat(retval.format); + + NVRenderTextureFormats::encodeToPixel(accumVal, retval.data, newIdx, retval.format); + } + } + + return retval; +} + +void Qt3DSRenderPrefilterTextureCPU::Build(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) +{ + + m_InternalFormat = inFormat; + m_SizeOfInternalFormat = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); + m_InternalNoOfComponent = NVRenderTextureFormats::getNumberOfComponent(m_InternalFormat); + + m_Texture2D.SetTextureData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, + m_Width, m_Height, inFormat, m_DestinationFormat); + + STextureData theMipImage; + STextureData prevImage; + prevImage.data = inTextureData; + prevImage.dataSizeInBytes = inTextureDataSize; + prevImage.format = inFormat; + int curWidth = m_Width; + int curHeight = m_Height; + int size = NVRenderTextureFormats::getSizeofFormat(m_InternalFormat); + for (int idx = 1; idx <= m_MaxMipMapLevel; ++idx) { + theMipImage = + CreateBsdfMipLevel(theMipImage, prevImage, curWidth, curHeight); //, m_PerfTimer ); + curWidth = curWidth >> 1; + curHeight = curHeight >> 1; + curWidth = curWidth >= 1 ? curWidth : 1; + curHeight = curHeight >= 1 ? curHeight : 1; + inTextureDataSize = curWidth * curHeight * size; + + m_Texture2D.SetTextureData(toU8DataRef((char *)theMipImage.data, (QT3DSU32)inTextureDataSize), + (QT3DSU8)idx, (QT3DSU32)curWidth, (QT3DSU32)curHeight, theMipImage.format, + m_DestinationFormat); + + if (prevImage.data == inTextureData) + prevImage = STextureData(); + + STextureData temp = prevImage; + prevImage = theMipImage; + theMipImage = temp; + } + QT3DS_FREE(m_Foundation.getAllocator(), theMipImage.data); + QT3DS_FREE(m_Foundation.getAllocator(), prevImage.data); +} + +//------------------------------------------------------------------------------------ +// GL compute based filtering +//------------------------------------------------------------------------------------ + +static const char *computeUploadShader(std::string &prog, NVRenderTextureFormats::Enum inFormat, + bool binESContext) +{ + if (binESContext) { + prog += "#version 310 es\n" + "#extension GL_ARB_compute_shader : enable\n" + "precision highp float;\n" + "precision highp int;\n" + "precision mediump image2D;\n"; + } else { + prog += "#version 430\n" + "#extension GL_ARB_compute_shader : enable\n"; + } + + if (inFormat == NVRenderTextureFormats::RGBA8) { + prog += "// Set workgroup layout;\n" + "layout (local_size_x = 16, local_size_y = 16) in;\n\n" + "layout (rgba8, binding = 1) readonly uniform image2D inputImage;\n\n" + "layout (rgba16f, binding = 2) writeonly uniform image2D outputImage;\n\n" + "void main()\n" + "{\n" + " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " + ">= gl_NumWorkGroups.y )\n" + " return;\n" + " vec4 value = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.xy));\n" + " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), value );\n" + "}\n"; + } else { + prog += "float convertToFloat( in uint inValue )\n" + "{\n" + " uint v = inValue & uint(0xFF);\n" + " float f = float(v)/256.0;\n" + " return f;\n" + "}\n"; + + prog += "int getMod( in int inValue, in int mod )\n" + "{\n" + " int v = mod * (inValue/mod);\n" + " return inValue - v;\n" + "}\n"; + + prog += "vec4 getRGBValue( in int byteNo, vec4 inVal, vec4 inVal1 )\n" + "{\n" + " vec4 result= vec4(0.0);\n" + " if( byteNo == 0) {\n" + " result.r = inVal.r;\n" + " result.g = inVal.g;\n" + " result.b = inVal.b;\n" + " }\n" + " else if( byteNo == 1) {\n" + " result.r = inVal.g;\n" + " result.g = inVal.b;\n" + " result.b = inVal.a;\n" + " }\n" + " else if( byteNo == 2) {\n" + " result.r = inVal.b;\n" + " result.g = inVal.a;\n" + " result.b = inVal1.r;\n" + " }\n" + " else if( byteNo == 3) {\n" + " result.r = inVal.a;\n" + " result.g = inVal1.r;\n" + " result.b = inVal1.g;\n" + " }\n" + " return result;\n" + "}\n"; + + prog += "// Set workgroup layout;\n" + "layout (local_size_x = 16, local_size_y = 16) in;\n\n" + "layout (rgba8, binding = 1) readonly uniform image2D inputImage;\n\n" + "layout (rgba16f, binding = 2) writeonly uniform image2D outputImage;\n\n" + "void main()\n" + "{\n" + " vec4 result = vec4(0.0);\n" + " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y " + ">= gl_NumWorkGroups.y )\n" + " return;\n" + " int xpos = (int(gl_GlobalInvocationID.x)*3)/4;\n" + " int xmod = getMod(int(gl_GlobalInvocationID.x)*3, 4);\n" + " ivec2 readPos = ivec2(xpos, gl_GlobalInvocationID.y);\n" + " vec4 value = imageLoad(inputImage, readPos);\n" + " vec4 value1 = imageLoad(inputImage, ivec2(readPos.x + 1, readPos.y));\n" + " result = getRGBValue( xmod, value, value1);\n" + " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), result );\n" + "}\n"; + } + return prog.c_str(); +} + +static const char *computeWorkShader(std::string &prog, bool binESContext) +{ + if (binESContext) { + prog += "#version 310 es\n" + "#extension GL_ARB_compute_shader : enable\n" + "precision highp float;\n" + "precision highp int;\n" + "precision mediump image2D;\n"; + } else { + prog += "#version 430\n" + "#extension GL_ARB_compute_shader : enable\n"; + } + + prog += "int wrapMod( in int a, in int base )\n" + "{\n" + " return ( a >= 0 ) ? a % base : -(a % base) + base;\n" + "}\n"; + + prog += "void getWrappedCoords( inout int sX, inout int sY, in int width, in int height )\n" + "{\n" + " if (sY < 0) { sX -= width >> 1; sY = -sY; }\n" + " if (sY >= height) { sX += width >> 1; sY = height - sY; }\n" + " sX = wrapMod( sX, width );\n" + "}\n"; + + prog += "// Set workgroup layout;\n" + "layout (local_size_x = 16, local_size_y = 16) in;\n\n" + "layout (rgba16f, binding = 1) readonly uniform image2D inputImage;\n\n" + "layout (rgba16f, binding = 2) writeonly uniform image2D outputImage;\n\n" + "void main()\n" + "{\n" + " int prevWidth = int(gl_NumWorkGroups.x) << 1;\n" + " int prevHeight = int(gl_NumWorkGroups.y) << 1;\n" + " if ( gl_GlobalInvocationID.x >= gl_NumWorkGroups.x || gl_GlobalInvocationID.y >= " + "gl_NumWorkGroups.y )\n" + " return;\n" + " vec4 accumVal = vec4(0.0);\n" + " for ( int sy = -2; sy <= 2; ++sy )\n" + " {\n" + " for ( int sx = -2; sx <= 2; ++sx )\n" + " {\n" + " int sampleX = sx + (int(gl_GlobalInvocationID.x) << 1);\n" + " int sampleY = sy + (int(gl_GlobalInvocationID.y) << 1);\n" + " getWrappedCoords(sampleX, sampleY, prevWidth, prevHeight);\n" + " if ((sampleY * prevWidth + sampleX) < 0 )\n" + " sampleY = prevHeight + sampleY;\n" + " ivec2 pos = ivec2(sampleX, sampleY);\n" + " vec4 value = imageLoad(inputImage, pos);\n" + " float filterPdf = 1.0 / ( 1.0 + float(sx*sx + sy*sy)*2.0 );\n" + " filterPdf /= 4.71238898;\n" + " accumVal[0] += filterPdf * value.r;\n" + " accumVal[1] += filterPdf * value.g;\n" + " accumVal[2] += filterPdf * value.b;\n" + " accumVal[3] += filterPdf * value.a;\n" + " }\n" + " }\n" + " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), accumVal );\n" + "}\n"; + + return prog.c_str(); +} + +inline NVConstDataRef toRef(const char *data) +{ + size_t len = strlen(data) + 1; + return NVConstDataRef((const QT3DSI8 *)data, (QT3DSU32)len); +} + +static bool isGLESContext(NVRenderContext *context) +{ + NVRenderContextType ctxType = context->GetRenderContextType(); + + // Need minimum of GL3 or GLES3 + if (ctxType == NVRenderContextValues::GLES2 || ctxType == NVRenderContextValues::GLES3 + || ctxType == NVRenderContextValues::GLES3PLUS) { + return true; + } + + return false; +} + +#define WORKGROUP_SIZE 16 + +Qt3DSRenderPrefilterTextureCompute::Qt3DSRenderPrefilterTextureCompute( + NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, QT3DSI32 inHeight, + NVRenderTexture2D &inTexture2D, NVRenderTextureFormats::Enum inDestFormat, + NVFoundationBase &inFnd) + : Qt3DSRenderPrefilterTexture(inNVRenderContext, inWidth, inHeight, inTexture2D, inDestFormat, + inFnd) + , m_BSDFProgram(NULL) + , m_UploadProgram_RGBA8(NULL) + , m_UploadProgram_RGB8(NULL) + , m_Level0Tex(NULL) + , m_TextureCreated(false) +{ +} + +Qt3DSRenderPrefilterTextureCompute::~Qt3DSRenderPrefilterTextureCompute() +{ + m_UploadProgram_RGB8 = NULL; + m_UploadProgram_RGBA8 = NULL; + m_BSDFProgram = NULL; + m_Level0Tex = NULL; +} + +void Qt3DSRenderPrefilterTextureCompute::createComputeProgram(NVRenderContext *context) +{ + std::string computeProg; + + if (!m_BSDFProgram) { + m_BSDFProgram = context + ->CompileComputeSource( + "Compute BSDF mipmap shader", + toRef(computeWorkShader(computeProg, isGLESContext(context)))) + .mShader; + } +} + +NVRenderShaderProgram *Qt3DSRenderPrefilterTextureCompute::getOrCreateUploadComputeProgram( + NVRenderContext *context, NVRenderTextureFormats::Enum inFormat) +{ + std::string computeProg; + + if (inFormat == NVRenderTextureFormats::RGB8) { + if (!m_UploadProgram_RGB8) { + m_UploadProgram_RGB8 = + context + ->CompileComputeSource( + "Compute BSDF mipmap level 0 RGB8 shader", + toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) + .mShader; + } + + return m_UploadProgram_RGB8; + } else { + if (!m_UploadProgram_RGBA8) { + m_UploadProgram_RGBA8 = + context + ->CompileComputeSource( + "Compute BSDF mipmap level 0 RGBA8 shader", + toRef(computeUploadShader(computeProg, inFormat, isGLESContext(context)))) + .mShader; + } + + return m_UploadProgram_RGBA8; + } +} + +void Qt3DSRenderPrefilterTextureCompute::CreateLevel0Tex(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) +{ + NVRenderTextureFormats::Enum theFormat = inFormat; + QT3DSI32 theWidth = m_Width; + + // Since we cannot use RGB format in GL compute + // we treat it as a RGBA component format + if (inFormat == NVRenderTextureFormats::RGB8) { + // This works only with 4 byte aligned data + QT3DS_ASSERT(m_Width % 4 == 0); + theFormat = NVRenderTextureFormats::RGBA8; + theWidth = (m_Width * 3) / 4; + } + + if (m_Level0Tex == NULL) { + m_Level0Tex = m_NVRenderContext->CreateTexture2D(); + m_Level0Tex->SetTextureStorage(1, theWidth, m_Height, theFormat, theFormat, + NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); + } else { + m_Level0Tex->SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, + 0, 0, theWidth, m_Height, theFormat); + } +} + +void Qt3DSRenderPrefilterTextureCompute::Build(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) +{ + bool needMipUpload = (inFormat != m_DestinationFormat); + // re-upload data + if (!m_TextureCreated) { + m_Texture2D.SetTextureStorage( + m_MaxMipMapLevel + 1, m_Width, m_Height, m_DestinationFormat, inFormat, (needMipUpload) + ? NVDataRef() + : NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize)); + m_Texture2D.addRef(); + // create a compute shader (if not aloread done) which computes the BSDF mipmaps for this + // texture + createComputeProgram(m_NVRenderContext); + + if (!m_BSDFProgram) { + QT3DS_ASSERT(false); + return; + } + + m_TextureCreated = true; + } else if (!needMipUpload) { + m_Texture2D.SetTextureSubData(NVDataRef((QT3DSU8 *)inTextureData, inTextureDataSize), 0, + 0, 0, m_Width, m_Height, inFormat); + } + + if (needMipUpload) { + CreateLevel0Tex(inTextureData, inTextureDataSize, inFormat); + } + + NVScopedRefCounted theInputImage; + NVScopedRefCounted theOutputImage; + theInputImage = + m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); + theOutputImage = + m_NVRenderContext->CreateImage2D(&m_Texture2D, NVRenderImageAccessType::ReadWrite); + + if (needMipUpload && m_Level0Tex) { + NVRenderShaderProgram *uploadProg = + getOrCreateUploadComputeProgram(m_NVRenderContext, inFormat); + if (!uploadProg) + return; + + m_NVRenderContext->SetActiveShader(uploadProg); + + NVScopedRefCounted theInputImage0; + theInputImage0 = + m_NVRenderContext->CreateImage2D(m_Level0Tex, NVRenderImageAccessType::ReadWrite); + + theInputImage0->SetTextureLevel(0); + NVRenderCachedShaderProperty theCachedinputImage0("inputImage", + *uploadProg); + theCachedinputImage0.Set(theInputImage0); + + theOutputImage->SetTextureLevel(0); + NVRenderCachedShaderProperty theCachedOutputImage("outputImage", + *uploadProg); + theCachedOutputImage.Set(theOutputImage); + + m_NVRenderContext->DispatchCompute(uploadProg, m_Width, m_Height, 1); + + // sync + NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); + m_NVRenderContext->SetMemoryBarrier(flags); + } + + int width = m_Width >> 1; + int height = m_Height >> 1; + + m_NVRenderContext->SetActiveShader(m_BSDFProgram); + + for (int i = 1; i <= m_MaxMipMapLevel; ++i) { + theOutputImage->SetTextureLevel(i); + NVRenderCachedShaderProperty theCachedOutputImage("outputImage", + *m_BSDFProgram); + theCachedOutputImage.Set(theOutputImage); + theInputImage->SetTextureLevel(i - 1); + NVRenderCachedShaderProperty theCachedinputImage("inputImage", + *m_BSDFProgram); + theCachedinputImage.Set(theInputImage); + + m_NVRenderContext->DispatchCompute(m_BSDFProgram, width, height, 1); + + width = width > 2 ? width >> 1 : 1; + height = height > 2 ? height >> 1 : 1; + + // sync + NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess); + m_NVRenderContext->SetMemoryBarrier(flags); + } +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.h new file mode 100644 index 00000000..e633eb14 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderPrefilterTexture.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PREFILTER_TEXTURE_H +#define QT3DS_RENDER_PREFILTER_TEXTURE_H +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "Qt3DSRender.h" + +#include "Qt3DSTypes.h" +#include "Qt3DSRenderLoadedTexture.h" + +namespace qt3ds { +namespace render { + + class Qt3DSRenderPrefilterTexture : public NVRefCounted + { + public: + Qt3DSRenderPrefilterTexture(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, QT3DSI32 inHeight, + NVRenderTexture2D &inTexture, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + virtual ~Qt3DSRenderPrefilterTexture(); + + virtual void Build(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) = 0; + + static Qt3DSRenderPrefilterTexture *Create(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, + QT3DSI32 inHeight, NVRenderTexture2D &inTexture, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + + protected: + NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things + volatile QT3DSI32 mRefCount; ///< reference count + + NVRenderTexture2D &m_Texture2D; + NVRenderTextureFormats::Enum m_InternalFormat; + NVRenderTextureFormats::Enum m_DestinationFormat; + + QT3DSI32 m_Width; + QT3DSI32 m_Height; + QT3DSI32 m_MaxMipMapLevel; + QT3DSI32 m_SizeOfFormat; + QT3DSI32 m_SizeOfInternalFormat; + QT3DSI32 m_InternalNoOfComponent; + QT3DSI32 m_NoOfComponent; + NVRenderContext *m_NVRenderContext; + }; + + class Qt3DSRenderPrefilterTextureCPU : public Qt3DSRenderPrefilterTexture + { + public: + Qt3DSRenderPrefilterTextureCPU(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, + QT3DSI32 inHeight, NVRenderTexture2D &inTexture, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + + void Build(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) override; + + STextureData CreateBsdfMipLevel(STextureData &inCurMipLevel, STextureData &inPrevMipLevel, + QT3DSI32 width, QT3DSI32 height); + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + int wrapMod(int a, int base); + void getWrappedCoords(int &sX, int &sY, int width, int height); + }; + + class Qt3DSRenderPrefilterTextureCompute : public Qt3DSRenderPrefilterTexture + { + public: + Qt3DSRenderPrefilterTextureCompute(NVRenderContext *inNVRenderContext, QT3DSI32 inWidth, + QT3DSI32 inHeight, NVRenderTexture2D &inTexture, + NVRenderTextureFormats::Enum inDestFormat, + qt3ds::NVFoundationBase &inFnd); + ~Qt3DSRenderPrefilterTextureCompute(); + + void Build(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat) override; + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + private: + void CreateLevel0Tex(void *inTextureData, QT3DSI32 inTextureDataSize, + NVRenderTextureFormats::Enum inFormat); + + NVScopedRefCounted m_BSDFProgram; + NVScopedRefCounted m_UploadProgram_RGBA8; + NVScopedRefCounted m_UploadProgram_RGB8; + NVScopedRefCounted m_Level0Tex; + bool m_TextureCreated; + + void createComputeProgram(NVRenderContext *context); + NVRenderShaderProgram * + getOrCreateUploadComputeProgram(NVRenderContext *context, + NVRenderTextureFormats::Enum inFormat); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.cpp new file mode 100644 index 00000000..25fbb414 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderResourceBufferObjects.h" + +using namespace qt3ds::render; + +/* + IResourceManager& m_ResourceManager; + NVRenderFrameBuffer* m_FrameBuffer; + */ + +CResourceFrameBuffer::CResourceFrameBuffer(IResourceManager &mgr) + : m_ResourceManager(mgr) + , m_FrameBuffer(NULL) +{ +} + +CResourceFrameBuffer::~CResourceFrameBuffer() +{ + ReleaseFrameBuffer(); +} + +bool CResourceFrameBuffer::EnsureFrameBuffer() +{ + if (!m_FrameBuffer) { + m_FrameBuffer = m_ResourceManager.AllocateFrameBuffer(); + return true; + } + return false; +} + +void CResourceFrameBuffer::ReleaseFrameBuffer() +{ + if (m_FrameBuffer) { + m_ResourceManager.Release(*m_FrameBuffer); + } +} + +CResourceRenderBuffer::CResourceRenderBuffer(IResourceManager &mgr) + : m_ResourceManager(mgr) + , m_RenderBuffer(NULL) +{ +} + +CResourceRenderBuffer::~CResourceRenderBuffer() +{ + ReleaseRenderBuffer(); +} + +bool CResourceRenderBuffer::EnsureRenderBuffer(QT3DSU32 width, QT3DSU32 height, + NVRenderRenderBufferFormats::Enum storageFormat) +{ + if (m_RenderBuffer == NULL || m_Dimensions.m_Width != width || m_Dimensions.m_Height != height + || m_StorageFormat != storageFormat) { + if (m_RenderBuffer == NULL || m_StorageFormat != storageFormat) { + ReleaseRenderBuffer(); + m_RenderBuffer = m_ResourceManager.AllocateRenderBuffer(width, height, storageFormat); + } else + m_RenderBuffer->SetDimensions( + qt3ds::render::NVRenderRenderBufferDimensions(width, height)); + m_Dimensions = m_RenderBuffer->GetDimensions(); + m_StorageFormat = m_RenderBuffer->GetStorageFormat(); + return true; + } + return false; +} + +void CResourceRenderBuffer::ReleaseRenderBuffer() +{ + if (m_RenderBuffer) { + m_ResourceManager.Release(*m_RenderBuffer); + m_RenderBuffer = NULL; + } +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.h new file mode 100644 index 00000000..fb54c4dc --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceBufferObjects.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RESOURCE_BUFFER_OBJECTS_H +#define QT3DS_RENDER_RESOURCE_BUFFER_OBJECTS_H +#include "Qt3DSRender.h" +#include "render/Qt3DSRenderContext.h" +#include "Qt3DSRenderResourceManager.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" + +namespace qt3ds { +namespace render { + class CResourceFrameBuffer + { + protected: + IResourceManager &m_ResourceManager; + NVRenderFrameBuffer *m_FrameBuffer; + + public: + CResourceFrameBuffer(IResourceManager &mgr); + ~CResourceFrameBuffer(); + bool EnsureFrameBuffer(); + void ReleaseFrameBuffer(); + + IResourceManager &GetResourceManager() { return m_ResourceManager; } + operator NVRenderFrameBuffer *() { return m_FrameBuffer; } + NVRenderFrameBuffer *operator->() + { + QT3DS_ASSERT(m_FrameBuffer); + return m_FrameBuffer; + } + NVRenderFrameBuffer &operator*() + { + QT3DS_ASSERT(m_FrameBuffer); + return *m_FrameBuffer; + } + }; + + class CResourceRenderBuffer + { + protected: + IResourceManager &m_ResourceManager; + NVRenderRenderBuffer *m_RenderBuffer; + qt3ds::render::NVRenderRenderBufferFormats::Enum m_StorageFormat; + qt3ds::render::NVRenderRenderBufferDimensions m_Dimensions; + + public: + CResourceRenderBuffer(IResourceManager &mgr); + ~CResourceRenderBuffer(); + bool EnsureRenderBuffer(QT3DSU32 width, QT3DSU32 height, + NVRenderRenderBufferFormats::Enum storageFormat); + void ReleaseRenderBuffer(); + + operator NVRenderRenderBuffer *() { return m_RenderBuffer; } + NVRenderRenderBuffer *operator->() + { + QT3DS_ASSERT(m_RenderBuffer); + return m_RenderBuffer; + } + NVRenderRenderBuffer &operator*() + { + QT3DS_ASSERT(m_RenderBuffer); + return *m_RenderBuffer; + } + }; +} +} +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.cpp new file mode 100644 index 00000000..35936885 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.cpp @@ -0,0 +1,436 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderResourceManager.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderTexture2DArray.h" +#include "render/Qt3DSRenderTextureCube.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" + +using namespace qt3ds::render; + +namespace { + +struct SResourceManager : public IResourceManager +{ + NVScopedRefCounted m_RenderContext; + // Complete list of all allocated objects + nvvector> m_AllocatedObjects; + + nvvector m_FreeFrameBuffers; + nvvector m_FreeRenderBuffers; + nvvector m_FreeTextures; + nvvector m_FreeTexArrays; + nvvector m_FreeTexCubes; + nvvector m_FreeImages; + + volatile QT3DSI32 mRefCount; + + SResourceManager(NVRenderContext &ctx) + : m_RenderContext(ctx) + , m_AllocatedObjects(ctx.GetAllocator(), "SResourceManager::m_FrameBuffers") + , m_FreeFrameBuffers(ctx.GetAllocator(), "SResourceManager::m_FreeFrameBuffers") + , m_FreeRenderBuffers(ctx.GetAllocator(), "SResourceManager::m_FreeRenderBuffers") + , m_FreeTextures(ctx.GetAllocator(), "SResourceManager::m_FreeTextures") + , m_FreeTexArrays(ctx.GetAllocator(), "SResourceManager::m_FreeTexArrays") + , m_FreeTexCubes(ctx.GetAllocator(), "SResourceManager::m_FreeTexCubes") + , m_FreeImages(ctx.GetAllocator(), "SResourceManager::m_FreeImages") + , mRefCount(0) + { + } + virtual ~SResourceManager() {} + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_RenderContext->GetAllocator()) + + NVRenderFrameBuffer *AllocateFrameBuffer() override + { + if (m_FreeFrameBuffers.empty() == true) { + NVRenderFrameBuffer *newBuffer = m_RenderContext->CreateFrameBuffer(); + m_AllocatedObjects.push_back(newBuffer); + m_FreeFrameBuffers.push_back(newBuffer); + } + NVRenderFrameBuffer *retval = m_FreeFrameBuffers.back(); + m_FreeFrameBuffers.pop_back(); + return retval; + } + void Release(NVRenderFrameBuffer &inBuffer) override + { + if (inBuffer.HasAnyAttachment()) { + // Ensure the framebuffer has no attachments. + inBuffer.Attach(NVRenderFrameBufferAttachments::Color0, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color1, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color2, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color3, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color4, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color5, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color6, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Color7, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Depth, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + inBuffer.Attach(NVRenderFrameBufferAttachments::Stencil, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + if (m_RenderContext->IsDepthStencilSupported()) + inBuffer.Attach(NVRenderFrameBufferAttachments::DepthStencil, + qt3ds::render::NVRenderTextureOrRenderBuffer()); + } +#ifdef _DEBUG + nvvector::iterator theFind = + eastl::find(m_FreeFrameBuffers.begin(), m_FreeFrameBuffers.end(), &inBuffer); + QT3DS_ASSERT(theFind == m_FreeFrameBuffers.end()); +#endif + m_FreeFrameBuffers.push_back(&inBuffer); + } + + virtual NVRenderRenderBuffer * + AllocateRenderBuffer(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderRenderBufferFormats::Enum inBufferFormat) override + { + // Look for one of this specific size and format. + QT3DSU32 existingMatchIdx = m_FreeRenderBuffers.size(); + for (QT3DSU32 idx = 0, end = existingMatchIdx; idx < end; ++idx) { + NVRenderRenderBuffer *theBuffer = m_FreeRenderBuffers[idx]; + qt3ds::render::NVRenderRenderBufferDimensions theDims = theBuffer->GetDimensions(); + NVRenderRenderBufferFormats::Enum theFormat = theBuffer->GetStorageFormat(); + if (theDims.m_Width == inWidth && theDims.m_Height == inHeight + && theFormat == inBufferFormat) { + // Replace idx with last for efficient erasure (that reorders the vector). + m_FreeRenderBuffers.replace_with_last(idx); + return theBuffer; + } else if (theFormat == inBufferFormat) + existingMatchIdx = idx; + } + // If a specific exact match couldn't be found, just use the buffer with + // the same format and resize it. + if (existingMatchIdx < m_FreeRenderBuffers.size()) { + NVRenderRenderBuffer *theBuffer = m_FreeRenderBuffers[existingMatchIdx]; + m_FreeRenderBuffers.replace_with_last(existingMatchIdx); + theBuffer->SetDimensions(qt3ds::render::NVRenderRenderBufferDimensions(inWidth, inHeight)); + return theBuffer; + } + + NVRenderRenderBuffer *theBuffer = + m_RenderContext->CreateRenderBuffer(inBufferFormat, inWidth, inHeight); + m_AllocatedObjects.push_back(theBuffer); + return theBuffer; + } + void Release(NVRenderRenderBuffer &inBuffer) override + { +#ifdef _DEBUG + nvvector::iterator theFind = + eastl::find(m_FreeRenderBuffers.begin(), m_FreeRenderBuffers.end(), &inBuffer); + QT3DS_ASSERT(theFind == m_FreeRenderBuffers.end()); +#endif + m_FreeRenderBuffers.push_back(&inBuffer); + } + NVRenderTexture2D *SetupAllocatedTexture(NVRenderTexture2D &inTexture) + { + inTexture.SetMinFilter(NVRenderTextureMinifyingOp::Linear); + inTexture.SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return &inTexture; + } + NVRenderTexture2D *AllocateTexture2D(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inTextureFormat, + QT3DSU32 inSampleCount, bool immutable) override + { + bool inMultisample = + inSampleCount > 1 && m_RenderContext->AreMultisampleTexturesSupported(); + for (QT3DSU32 idx = 0, end = m_FreeTextures.size(); idx < end; ++idx) { + NVRenderTexture2D *theTexture = m_FreeTextures[idx]; + STextureDetails theDetails = theTexture->GetTextureDetails(); + if (theDetails.m_Width == inWidth && theDetails.m_Height == inHeight + && inTextureFormat == theDetails.m_Format + && theTexture->GetSampleCount() == inSampleCount) { + m_FreeTextures.replace_with_last(idx); + return SetupAllocatedTexture(*theTexture); + } + } + // else resize an existing texture. This is very expensive + // note that MSAA textures are not resizable ( in GLES ) + /* + if ( !m_FreeTextures.empty() && !inMultisample ) + { + NVRenderTexture2D* theTexture = m_FreeTextures.back(); + m_FreeTextures.pop_back(); + + // note we could re-use a former MSAA texture + // this causes a entiere destroy of the previous texture object + theTexture->SetTextureData( NVDataRef(), 0, inWidth, inHeight, inTextureFormat + ); + + return SetupAllocatedTexture( *theTexture ); + }*/ + // else create a new texture. + NVRenderTexture2D *theTexture = m_RenderContext->CreateTexture2D(); + + if (inMultisample) + theTexture->SetTextureDataMultisample(inSampleCount, inWidth, inHeight, + inTextureFormat); + else if (immutable) + theTexture->SetTextureStorage(1, inWidth, inHeight, inTextureFormat); + else + theTexture->SetTextureData(NVDataRef(), 0, inWidth, inHeight, inTextureFormat); + + m_AllocatedObjects.push_back(theTexture); + return SetupAllocatedTexture(*theTexture); + } + void Release(NVRenderTexture2D &inBuffer) override + { +#ifdef _DEBUG + nvvector::iterator theFind = + eastl::find(m_FreeTextures.begin(), m_FreeTextures.end(), &inBuffer); + QT3DS_ASSERT(theFind == m_FreeTextures.end()); +#endif + m_FreeTextures.push_back(&inBuffer); + } + + NVRenderTexture2DArray *AllocateTexture2DArray(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 inSlices, + NVRenderTextureFormats::Enum inTextureFormat, + QT3DSU32 inSampleCount) override + { + bool inMultisample = + inSampleCount > 1 && m_RenderContext->AreMultisampleTexturesSupported(); + for (QT3DSU32 idx = 0, end = m_FreeTexArrays.size(); idx < end; ++idx) { + NVRenderTexture2DArray *theTexture = m_FreeTexArrays[idx]; + STextureDetails theDetails = theTexture->GetTextureDetails(); + if (theDetails.m_Width == inWidth && theDetails.m_Height == inHeight + && theDetails.m_Depth == inSlices && inTextureFormat == theDetails.m_Format + && theTexture->GetSampleCount() == inSampleCount) { + m_FreeTexArrays.replace_with_last(idx); + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return theTexture; + } + } + + // else resize an existing texture. This should be fairly quick at the driver level. + // note that MSAA textures are not resizable ( in GLES ) + if (!m_FreeTexArrays.empty() && !inMultisample) { + NVRenderTexture2DArray *theTexture = m_FreeTexArrays.back(); + m_FreeTexArrays.pop_back(); + + // note we could re-use a former MSAA texture + // this causes a entiere destroy of the previous texture object + theTexture->SetTextureData(NVDataRef(), 0, inWidth, inHeight, inSlices, + inTextureFormat); + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return theTexture; + } + + // else create a new texture. + NVRenderTexture2DArray *theTexture = NULL; + + if (!inMultisample) { + theTexture = m_RenderContext->CreateTexture2DArray(); + theTexture->SetTextureData(NVDataRef(), 0, inWidth, inHeight, inSlices, + inTextureFormat); + } else { + // Not supported yet + return NULL; + } + + m_AllocatedObjects.push_back(theTexture); + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return theTexture; + } + + void Release(NVRenderTexture2DArray &inBuffer) override + { +#ifdef _DEBUG + nvvector::iterator theFind = + eastl::find(m_FreeTexArrays.begin(), m_FreeTexArrays.end(), &inBuffer); + QT3DS_ASSERT(theFind == m_FreeTexArrays.end()); +#endif + m_FreeTexArrays.push_back(&inBuffer); + } + + NVRenderTextureCube *AllocateTextureCube(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inTextureFormat, + QT3DSU32 inSampleCount) override + { + bool inMultisample = + inSampleCount > 1 && m_RenderContext->AreMultisampleTexturesSupported(); + for (QT3DSU32 idx = 0, end = m_FreeTexCubes.size(); idx < end; ++idx) { + NVRenderTextureCube *theTexture = m_FreeTexCubes[idx]; + STextureDetails theDetails = theTexture->GetTextureDetails(); + if (theDetails.m_Width == inWidth && theDetails.m_Height == inHeight + && inTextureFormat == theDetails.m_Format + && theTexture->GetSampleCount() == inSampleCount) { + m_FreeTexCubes.replace_with_last(idx); + + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return theTexture; + } + } + + // else resize an existing texture. This should be fairly quick at the driver level. + // note that MSAA textures are not resizable ( in GLES ) + if (!m_FreeTexCubes.empty() && !inMultisample) { + NVRenderTextureCube *theTexture = m_FreeTexCubes.back(); + m_FreeTexCubes.pop_back(); + + // note we could re-use a former MSAA texture + // this causes a entire destroy of the previous texture object + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosX, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegX, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosY, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegY, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosZ, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegZ, + inWidth, inHeight, inTextureFormat); + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return theTexture; + } + + // else create a new texture. + NVRenderTextureCube *theTexture = NULL; + + if (!inMultisample) { + theTexture = m_RenderContext->CreateTextureCube(); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosX, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegX, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosY, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegY, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubePosZ, + inWidth, inHeight, inTextureFormat); + theTexture->SetTextureData(NVDataRef(), 0, NVRenderTextureCubeFaces::CubeNegZ, + inWidth, inHeight, inTextureFormat); + } else { + // Not supported yet + return NULL; + } + + m_AllocatedObjects.push_back(theTexture); + theTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + return theTexture; + } + + void Release(NVRenderTextureCube &inBuffer) override + { +#ifdef _DEBUG + nvvector::iterator theFind = + eastl::find(m_FreeTexCubes.begin(), m_FreeTexCubes.end(), &inBuffer); + QT3DS_ASSERT(theFind == m_FreeTexCubes.end()); +#endif + m_FreeTexCubes.push_back(&inBuffer); + } + + NVRenderImage2D *AllocateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) override + { + if (m_FreeImages.empty() == true) { + NVRenderImage2D *newImage = m_RenderContext->CreateImage2D(inTexture, inAccess); + if (newImage) { + m_AllocatedObjects.push_back(newImage); + m_FreeImages.push_back(newImage); + } + } + + NVRenderImage2D *retval = m_FreeImages.back(); + m_FreeImages.pop_back(); + + return retval; + } + + void Release(NVRenderImage2D &inBuffer) override + { +#ifdef _DEBUG + nvvector::iterator theFind = + eastl::find(m_FreeImages.begin(), m_FreeImages.end(), &inBuffer); + QT3DS_ASSERT(theFind == m_FreeImages.end()); +#endif + m_FreeImages.push_back(&inBuffer); + } + + NVRenderContext &GetRenderContext() override { return *m_RenderContext; } + + void RemoveObjectAllocation(NVRefCounted *obj) { + for (QT3DSU32 idx = 0, end = m_AllocatedObjects.size(); idx < end; ++idx) { + if (obj == m_AllocatedObjects[idx]) { + m_AllocatedObjects.replace_with_last(idx); + break; + } + } + } + + void DestroyFreeSizedResources() + { + for (int idx = m_FreeRenderBuffers.size() - 1; idx >= 0; --idx) { + NVRenderRenderBuffer *obj = m_FreeRenderBuffers[idx]; + m_FreeRenderBuffers.replace_with_last(idx); + RemoveObjectAllocation(obj); + } + for (int idx = m_FreeTextures.size() - 1; idx >= 0; --idx) { + NVRenderTexture2D *obj = m_FreeTextures[idx]; + m_FreeTextures.replace_with_last(idx); + RemoveObjectAllocation(obj); + } + for (int idx = m_FreeTexArrays.size() - 1; idx >= 0; --idx) { + NVRenderTexture2DArray *obj = m_FreeTexArrays[idx]; + m_FreeTexArrays.replace_with_last(idx); + RemoveObjectAllocation(obj); + } + for (int idx = m_FreeTexCubes.size() - 1; idx >= 0; --idx) { + NVRenderTextureCube *obj = m_FreeTexCubes[idx]; + m_FreeTexCubes.replace_with_last(idx); + RemoveObjectAllocation(obj); + } + } +}; +} + +IResourceManager &IResourceManager::CreateResourceManager(NVRenderContext &inContext) +{ + return *QT3DS_NEW(inContext.GetAllocator(), SResourceManager)(inContext); +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.h new file mode 100644 index 00000000..675d644c --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceManager.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RESOURCE_MANAGER_H +#define QT3DS_RENDER_RESOURCE_MANAGER_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + /** + * Implements simple pooling of render resources + */ + class IResourceManager : public NVRefCounted + { + protected: + virtual ~IResourceManager() {} + + public: + virtual NVRenderFrameBuffer *AllocateFrameBuffer() = 0; + virtual void Release(NVRenderFrameBuffer &inBuffer) = 0; + virtual NVRenderRenderBuffer * + AllocateRenderBuffer(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderRenderBufferFormats::Enum inBufferFormat) = 0; + virtual void Release(NVRenderRenderBuffer &inBuffer) = 0; + virtual NVRenderTexture2D *AllocateTexture2D(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inTextureFormat, + QT3DSU32 inSampleCount = 1, + bool immutable = false) = 0; + virtual void Release(NVRenderTexture2D &inBuffer) = 0; + virtual NVRenderTexture2DArray * + AllocateTexture2DArray(QT3DSU32 inWidth, QT3DSU32 inHeight, QT3DSU32 inSlices, + NVRenderTextureFormats::Enum inTextureFormat, + QT3DSU32 inSampleCount = 1) = 0; + virtual void Release(NVRenderTexture2DArray &inBuffer) = 0; + virtual NVRenderTextureCube * + AllocateTextureCube(QT3DSU32 inWidth, QT3DSU32 inHeight, + NVRenderTextureFormats::Enum inTextureFormat, + QT3DSU32 inSampleCount = 1) = 0; + virtual void Release(NVRenderTextureCube &inBuffer) = 0; + virtual NVRenderImage2D *AllocateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) = 0; + virtual void Release(NVRenderImage2D &inBuffer) = 0; + + virtual NVRenderContext &GetRenderContext() = 0; + virtual void DestroyFreeSizedResources() = 0; + + static IResourceManager &CreateResourceManager(NVRenderContext &inContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.cpp new file mode 100644 index 00000000..e877cbc9 --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderResourceTexture2D.h" + +using namespace qt3ds::render; + +CResourceTexture2D::CResourceTexture2D(IResourceManager &mgr, NVRenderTexture2D *inTexture) + : m_ResourceManager(mgr) + , m_Texture(inTexture) +{ + if (inTexture) + m_TextureDetails = inTexture->GetTextureDetails(); +} + +CResourceTexture2D::CResourceTexture2D(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) + : m_ResourceManager(mgr) + , m_Texture(NULL) +{ + EnsureTexture(width, height, inFormat, inSamples); +} + +CResourceTexture2D::~CResourceTexture2D() +{ + ReleaseTexture(); +} + +// Returns true if the texture was allocated, false if nothing changed (no allocation). +bool CResourceTexture2D::TextureMatches(QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) +{ + return m_Texture && m_TextureDetails.m_Width == width && m_TextureDetails.m_Height == height + && m_TextureDetails.m_Format == inFormat && m_TextureDetails.m_SampleCount == inSamples; +} + +bool CResourceTexture2D::EnsureTexture(QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) +{ + if (TextureMatches(width, height, inFormat, inSamples)) + return false; + + if (m_Texture && inSamples > 1) { + // we cannot resize MSAA textures though release first + ReleaseTexture(); + } + + if (!m_Texture) + m_Texture = m_ResourceManager.AllocateTexture2D(width, height, inFormat, inSamples); + else { + // multisampled textures are immuteable + QT3DS_ASSERT(inSamples == 1); + m_Texture->SetTextureData(NVDataRef(), 0, width, height, inFormat); + } + + m_TextureDetails = m_Texture->GetTextureDetails(); + return true; +} + +void CResourceTexture2D::ReleaseTexture() +{ + if (m_Texture) { + m_ResourceManager.Release(*m_Texture); + ForgetTexture(); + } +} + +void CResourceTexture2D::ForgetTexture() +{ + m_Texture = NULL; +} + +void CResourceTexture2D::StealTexture(CResourceTexture2D &inOther) +{ + ReleaseTexture(); + m_Texture = inOther.m_Texture; + m_TextureDetails = inOther.m_TextureDetails; + inOther.m_Texture = NULL; +} + +CResourceTexture2DArray::CResourceTexture2DArray(IResourceManager &mgr) + : m_ResourceManager(mgr) + , m_Texture(NULL) +{ +} + +CResourceTexture2DArray::CResourceTexture2DArray(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, + QT3DSU32 slices, + NVRenderTextureFormats::Enum inFormat, + QT3DSU32 inSamples) + : m_ResourceManager(mgr) + , m_Texture(NULL) +{ + EnsureTexture(width, height, slices, inFormat, inSamples); +} + +CResourceTexture2DArray::~CResourceTexture2DArray() +{ + ReleaseTexture(); +} + +bool CResourceTexture2DArray::TextureMatches(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) +{ + return m_Texture && m_TextureDetails.m_Depth == slices && m_TextureDetails.m_Width == width + && m_TextureDetails.m_Height == height && m_TextureDetails.m_Format == inFormat + && m_TextureDetails.m_SampleCount == inSamples; +} + +bool CResourceTexture2DArray::EnsureTexture(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples) +{ + if (TextureMatches(width, height, slices, inFormat, inSamples)) + return false; + + if (m_Texture && inSamples > 1) { + // we cannot resize MSAA textures though release first + ReleaseTexture(); + } + + if (!m_Texture) + m_Texture = + m_ResourceManager.AllocateTexture2DArray(width, height, slices, inFormat, inSamples); + else { + // multisampled textures are immuteable + QT3DS_ASSERT(inSamples == 1); + m_Texture->SetTextureData(NVDataRef(), 0, width, height, slices, inFormat); + } + + m_TextureDetails = m_Texture->GetTextureDetails(); + return true; +} + +void CResourceTexture2DArray::ReleaseTexture() +{ + if (m_Texture) { + m_ResourceManager.Release(*m_Texture); + m_Texture = NULL; + } +} + +void CResourceTexture2DArray::StealTexture(CResourceTexture2DArray &inOther) +{ + ReleaseTexture(); + m_Texture = inOther.m_Texture; + m_TextureDetails = inOther.m_TextureDetails; + inOther.m_Texture = NULL; +} diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.h new file mode 100644 index 00000000..eb54713a --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderResourceTexture2D.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RESOURCE_TEXTURE_2D_H +#define QT3DS_RENDER_RESOURCE_TEXTURE_2D_H +#include "Qt3DSRender.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderTexture2DArray.h" +#include "Qt3DSRenderResourceManager.h" + +namespace qt3ds { +namespace render { + class CResourceTexture2D + { + protected: + IResourceManager &m_ResourceManager; + NVRenderTexture2D *m_Texture; + STextureDetails m_TextureDetails; + + public: + CResourceTexture2D(IResourceManager &mgr, NVRenderTexture2D *inTexture = NULL); + // create and allocate the texture right away. + CResourceTexture2D(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); + ~CResourceTexture2D(); + // Returns true if the texture matches the specs, false if the texture needs to be + // reallocated + bool TextureMatches(QT3DSU32 width, QT3DSU32 height, NVRenderTextureFormats::Enum inFormat, + QT3DSU32 inSamples = 1); + + // Returns true if the texture was allocated, false if nothing changed (no allocation). + // Note this is the exact opposite of TextureMatches. + bool EnsureTexture(QT3DSU32 width, QT3DSU32 height, NVRenderTextureFormats::Enum inFormat, + QT3DSU32 inSamples = 1); + + // Force release the texture. + void ReleaseTexture(); + NVRenderTexture2D &operator*() + { + QT3DS_ASSERT(m_Texture); + return *m_Texture; + } + NVRenderTexture2D *operator->() + { + QT3DS_ASSERT(m_Texture); + return m_Texture; + } + operator NVRenderTexture2D *() { return m_Texture; } + NVRenderTexture2D *GetTexture() { return m_Texture; } + void ForgetTexture(); + // Enforces single ownership rules. + void StealTexture(CResourceTexture2D &inOther); + }; + + class CResourceTexture2DArray + { + protected: + IResourceManager &m_ResourceManager; + qt3ds::render::NVRenderTexture2DArray *m_Texture; + STextureDetails m_TextureDetails; + + public: + CResourceTexture2DArray(IResourceManager &mgr); + // create and allocate the texture right away. + CResourceTexture2DArray(IResourceManager &mgr, QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); + ~CResourceTexture2DArray(); + // Returns true if the texture matches the specs, false if the texture needs to be + // reallocated + bool TextureMatches(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); + + // Returns true if the texture was allocated, false if nothing changed (no allocation). + // Note this is the exact opposite of TextureMatches. + bool EnsureTexture(QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum inFormat, QT3DSU32 inSamples = 1); + + // Force release the texture. + void ReleaseTexture(); + qt3ds::render::NVRenderTexture2DArray &operator*() + { + QT3DS_ASSERT(m_Texture); + return *m_Texture; + } + qt3ds::render::NVRenderTexture2DArray *operator->() + { + QT3DS_ASSERT(m_Texture); + return m_Texture; + } + operator qt3ds::render::NVRenderTexture2DArray *() { return m_Texture; } + qt3ds::render::NVRenderTexture2DArray *GetTexture() { return m_Texture; } + // Enforces single ownership rules. + void StealTexture(CResourceTexture2DArray &inOther); + }; +} +} + +#endif diff --git a/src/Runtime/Source/runtimerender/windows/DynamicLibLoader.h b/src/Runtime/Source/runtimerender/windows/DynamicLibLoader.h new file mode 100644 index 00000000..09b028bc --- /dev/null +++ b/src/Runtime/Source/runtimerender/windows/DynamicLibLoader.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_WINDOWS_DYNAMIC_LIB_LOADER_H +#define QT3DS_WINDOWS_DYNAMIC_LIB_LOADER_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" + +#include + +namespace qt3ds { +namespace render { + using namespace qt3ds; + // using namespace qt3ds::render; + + class CLoadedDynamicLibrary + { + QLibrary* m_DLLHandle; + CLoadedDynamicLibrary(QLibrary* hdl) + : m_DLLHandle(hdl) + { + } + CLoadedDynamicLibrary(const CLoadedDynamicLibrary &); + CLoadedDynamicLibrary &operator=(const CLoadedDynamicLibrary &); + + public: + ~CLoadedDynamicLibrary() + { + if (m_DLLHandle) { + m_DLLHandle->unload(); + delete m_DLLHandle; + } + m_DLLHandle = 0; + } + void *FindFunction(const char *name) { return (void*)m_DLLHandle->resolve(name); } + static CLoadedDynamicLibrary *Create(const char *inFullDllPath, NVFoundationBase &fnd) + { + QLibrary* hdl = new QLibrary(inFullDllPath); + if (!hdl->load()) { + qCCritical(INVALID_OPERATION, "Failed to load dynamic library %s: %s", + inFullDllPath, qPrintable(hdl->errorString())); + + delete hdl; + return nullptr; + } + return QT3DS_NEW(fnd.getAllocator(), CLoadedDynamicLibrary)(hdl); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/state/Qt3DSStateApplication.h b/src/Runtime/Source/state/Qt3DSStateApplication.h new file mode 100644 index 00000000..ca8f44d5 --- /dev/null +++ b/src/Runtime/Source/state/Qt3DSStateApplication.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "foundation/Qt3DSRefCounted.h" +#include "Qt3DSTypes.h" + +namespace qt3ds { +namespace state { + + class INDDStateApplication : public qt3ds::foundation::NVRefCounted + { + public: + virtual ~INDDStateApplication() {} + + virtual double GetMillisecondsSinceLastFrame() = 0; + virtual Q3DStudio::INT32 GetFrameCount() = 0; + }; +} +} diff --git a/src/Runtime/Source/state/Qt3DSStateConfig.h b/src/Runtime/Source/state/Qt3DSStateConfig.h new file mode 100644 index 00000000..0252d1f7 --- /dev/null +++ b/src/Runtime/Source/state/Qt3DSStateConfig.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#ifdef _WIN32 +#if defined QT3DS_STATE_EXPORTS +#define QT3DS_STATE_API __declspec(dllexport) +#elif defined QT3DS_STATE_NO_EXPORTS +#define QT3DS_STATE_API +#else +#define QT3DS_STATE_API __declspec(dllimport) +#endif +#else +#define QT3DS_STATE_API +#endif diff --git a/src/Runtime/Source/state/Qt3DSStateEngine.h b/src/Runtime/Source/state/Qt3DSStateEngine.h new file mode 100644 index 00000000..464fd3a5 --- /dev/null +++ b/src/Runtime/Source/state/Qt3DSStateEngine.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "foundation/Qt3DSRefCounted.h" + +#include "Qt3DSStateConfig.h" + +namespace qt3ds { + +class NVFoundation; + +namespace foundation { + class IStringTable; +} +} + +namespace Q3DStudio { +class ITimeProvider; +} + +namespace qt3ds { +namespace state { + + class IInputStreamFactory; + + class INDDStateEngine + { + public: + enum EStateEvent { + STATE_EVENT_UNKNOWN = 0, + STATE_EVENT_STATE_ENTER, + STATE_EVENT_STATE_EXIT, + STATE_EVENT_TRANSITION, + }; + class IStateEventHandler + { + public: + virtual ~IStateEventHandler() {} + virtual void OnEvent() = 0; + }; + class IStateEventHandlerConnection : public qt3ds::foundation::NVRefCounted + { + protected: + virtual ~IStateEventHandlerConnection() {} + public: + }; + + typedef qt3ds::foundation::NVScopedRefCounted + TStateEventHandlerConnectionPtr; + + public: + virtual ~INDDStateEngine() {} + + virtual bool Load(const char *inApplicationPath) = 0; + virtual bool Step() = 0; + virtual TStateEventHandlerConnectionPtr + RegisterEventHandler(EStateEvent inEvent, const char *inEventId, + IStateEventHandler &inHandler) = 0; + virtual void FireEvent(const char *inEventName, unsigned long long inDelay, + const char *inCancelId, bool inIsExternal = true) = 0; + virtual void FireEvent(const char *inEventName, bool inIsExternal = true) = 0; + virtual void CancelEvent(const char *inCancelId) = 0; + + QT3DS_STATE_API static INDDStateEngine * + Create(qt3ds::foundation::NVScopedRefCounted inFoundation, + qt3ds::foundation::NVScopedRefCounted inStringTable, + qt3ds::foundation::NVScopedRefCounted + inInputStreamFactory, + Q3DStudio::ITimeProvider &inTimeProvider); + + QT3DS_STATE_API static INDDStateEngine *Create(); + }; +} +} diff --git a/src/Runtime/Source/state/Qt3DSStateInputStreamFactory.cpp b/src/Runtime/Source/state/Qt3DSStateInputStreamFactory.cpp new file mode 100644 index 00000000..2fd3dffa --- /dev/null +++ b/src/Runtime/Source/state/Qt3DSStateInputStreamFactory.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateInputStreamFactory.h" + +#include "stdio.h" + +#include "foundation/Qt3DSLogging.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/string.h" +#include "EASTL/vector.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/FileTools.h" +#include "foundation/Qt3DSMutex.h" +#include + +using namespace qt3ds::state; +using qt3ds::foundation::CFileTools; + +namespace { + +using qt3ds::foundation::atomicIncrement; +using qt3ds::foundation::atomicDecrement; +using qt3ds::QT3DSI32; + +struct SInputStream : public IRefCountedInputStream +{ + qt3ds::NVFoundationBase &m_Foundation; + eastl::string m_Path; + QFile m_File; + volatile qt3ds::QT3DSI32 mRefCount; + + SInputStream(qt3ds::NVFoundationBase &inFoundation, const eastl::string &inPath) + : m_Foundation(inFoundation) + , m_Path(inPath) + , m_File(inPath.c_str()) + , mRefCount(0) + { + m_File.open(QIODevice::ReadOnly); + } + virtual ~SInputStream() + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + qt3ds::QT3DSU32 Read(qt3ds::foundation::NVDataRef data) override + { + return m_File.read((char *)data.begin(), data.size()); + } + + bool Write(qt3ds::foundation::NVConstDataRef /*data*/) override + { + QT3DS_ASSERT(false); + return false; + } + + void SetPosition(qt3ds::QT3DSI64 inOffset, qt3ds::foundation::SeekPosition::Enum inEnum) override + { + if (inOffset > QT3DS_MAX_I32 || inOffset < QT3DS_MIN_I32) { + qCCritical(qt3ds::INVALID_OPERATION, "Attempt to seek further than platform allows"); + QT3DS_ASSERT(false); + return; + } else { + CFileTools::SetStreamPosition(m_File, inOffset, inEnum); + } + } + qt3ds::QT3DSI64 GetPosition() const override + { + return m_File.pos(); + } + + static SInputStream *OpenFile(const char8_t *inPath, qt3ds::NVFoundationBase &inFoundation) + { + eastl::string finalPath = CFileTools::GetFileOrAssetPath(inPath); + QFile tmp(finalPath.c_str()); + if (tmp.exists()) + return QT3DS_NEW(inFoundation.getAllocator(), SInputStream)(inFoundation, finalPath); + return NULL; + } +}; + +typedef eastl::basic_string TStrType; +struct SFactory : public IInputStreamFactory +{ + qt3ds::NVFoundationBase &m_Foundation; + volatile qt3ds::QT3DSI32 mRefCount; + TStrType m_SearchString; + qt3ds::foundation::nvvector m_SearchPaths; + TStrType m_TempAddSearch; + + qt3ds::foundation::Mutex m_Mutex; + typedef qt3ds::foundation::Mutex::ScopedLock TScopedLock; + + SFactory(qt3ds::NVFoundationBase &inFoundation) + : m_Foundation(inFoundation) + , mRefCount(0) + , m_SearchString(qt3ds::foundation::ForwardingAllocator(inFoundation.getAllocator(), + "SFactory::m_SearchString")) + , m_SearchPaths(inFoundation.getAllocator(), "SFactory::m_SearchPaths") + , m_TempAddSearch(qt3ds::foundation::ForwardingAllocator(inFoundation.getAllocator(), + "SFactory::m_TempAddSearch")) + , m_Mutex(inFoundation.getAllocator()) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void AddSearchDirectory(const char8_t *inDirectory) override + { + TScopedLock __factoryLocker(m_Mutex); + if (inDirectory && *inDirectory) { + bool foundPath = false; + m_TempAddSearch.assign(inDirectory); + qt3ds::foundation::CFileTools::NormalizePath(m_TempAddSearch); + for (qt3ds::QT3DSU32 idx = 0, end = m_SearchPaths.size(); idx < end && foundPath == false; + ++idx) { + foundPath = m_SearchPaths[idx].compare(m_TempAddSearch.c_str()) == 0; + } + if (!foundPath) { + qCInfo(qt3ds::TRACE_INFO, "Adding search path: %s", inDirectory); + m_SearchPaths.push_back(m_TempAddSearch); + } + } + } + void AttemptCFileOpen() + { + qCInfo(qt3ds::TRACE_INFO, "attempting C file api for %s", m_SearchString.c_str()); + FILE *theTest = fopen(m_SearchString.c_str(), "rb"); + if (theTest) { + qCInfo(qt3ds::TRACE_INFO, "C file api succeeded for %s", m_SearchString.c_str()); + fclose(theTest); + } else { + qCInfo(qt3ds::TRACE_INFO, "C file api failed for %s", m_SearchString.c_str()); + } + } + + // Remove the ./ from the relative path as this allows APK lookup to succeed + static void CheckRelative(TStrType &ioStr) + { + if (ioStr.find("./") == 0) + ioStr.erase(ioStr.begin(), ioStr.begin() + 2); + } + + IRefCountedInputStream *GetStreamForFile(const char8_t *inFilename, bool inQuiet) override + { + TScopedLock __factoryLocker(m_Mutex); + SInputStream *theFile = NULL; + for (qt3ds::QT3DSU32 idx = 0, end = m_SearchPaths.size() + 1; theFile == NULL && idx < end; + ++idx) { + if (idx) { + qt3ds::foundation::CFileTools::CombineBaseAndRelative(m_SearchPaths[idx - 1].c_str(), + inFilename, m_SearchString); + } else { + m_SearchString.assign(inFilename); + } + qt3ds::foundation::CFileTools::ToPlatformPath(m_SearchString); + CheckRelative(m_SearchString); + theFile = SInputStream::OpenFile(m_SearchString.c_str(), m_Foundation); + } + if (theFile) { + qCInfo(qt3ds::TRACE_INFO, "file %s resolved to: %s", inFilename, m_SearchString.c_str()); + } else { + if (inQuiet == false) { + // Print extensive debugging information. + qCWarning(qt3ds::WARNING, "Failed to find file: %s", inFilename); + qCWarning(qt3ds::WARNING, "Searched paths: %s", inFilename); + m_SearchString.assign(inFilename); + qt3ds::foundation::CFileTools::ToPlatformPath(m_SearchString); + qCWarning(qt3ds::WARNING, "%s", m_SearchString.c_str()); + for (qt3ds::QT3DSU32 idx = 0, end = m_SearchPaths.size(); idx < end; ++idx) { + qt3ds::foundation::CFileTools::CombineBaseAndRelative(m_SearchPaths[idx].c_str(), + inFilename, m_SearchString); + qt3ds::foundation::CFileTools::ToPlatformPath(m_SearchString); + CheckRelative(m_SearchString); + if (m_SearchString.compare(inFilename) != 0) + qCWarning(qt3ds::WARNING, "%s", m_SearchString.c_str()); + } + } + } + return theFile; + } + + bool GetPathForFile(const char8_t *inFilename, eastl::string &outFile, + bool inQuiet = false) override + { + qt3ds::foundation::NVScopedRefCounted theStream = + GetStreamForFile(inFilename, inQuiet); + if (theStream) { + SInputStream *theRealStream = static_cast(theStream.mPtr); + outFile = theRealStream->m_Path; + return true; + } + return false; + } +}; +} + +IInputStreamFactory &IInputStreamFactory::Create(qt3ds::NVFoundationBase &inFoundation) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SFactory)(inFoundation); +} diff --git a/src/Runtime/Source/state/Qt3DSStateInputStreamFactory.h b/src/Runtime/Source/state/Qt3DSStateInputStreamFactory.h new file mode 100644 index 00000000..a4e387ab --- /dev/null +++ b/src/Runtime/Source/state/Qt3DSStateInputStreamFactory.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSRefCounted.h" +#include "EASTL/string.h" + +#include "Qt3DSStateConfig.h" + +namespace qt3ds { +namespace state { + + class IRefCountedInputStream : public qt3ds::foundation::ISeekableIOStream, + public qt3ds::foundation::NVRefCounted + { + protected: + virtual ~IRefCountedInputStream() {} + }; + + // This class is threadsafe. + class IInputStreamFactory : public qt3ds::foundation::NVRefCounted + { + protected: + virtual ~IInputStreamFactory() {} + public: + // These directories must have a '/' on them + virtual void AddSearchDirectory(const char8_t *inDirectory) = 0; + virtual IRefCountedInputStream *GetStreamForFile(const char8_t *inFilename, + bool inQuiet = false) = 0; + // Return a path for this file. Returns true if GetStreamForFile would return a valid + // stream. + // else returns false + virtual bool GetPathForFile(const char8_t *inFilename, eastl::string &outFile, + bool inQuiet = false) = 0; + + // Create an input stream factory using this foundation and an platform-optional app + // directory + // on android the app directory has no effect; use use the assets bundled with the APK file. + QT3DS_STATE_API static IInputStreamFactory &Create(qt3ds::NVFoundationBase &inFoundation); + }; +} +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSState.h b/src/Runtime/Source/stateapplication/Qt3DSState.h new file mode 100644 index 00000000..b5686c25 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSState.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_STATE_H +#define QT3DS_STATE_H + +namespace qt3ds { +class NVAllocatorCallback; +class NVFoundationBase; +namespace foundation { + class CRegisteredString; + class IStringTable; + class IOutStream; + class IInStream; + class IDOMFactory; + struct SDOMAttribute; + struct SDOMElement; + struct SNamespacePairNode; + class SocketStream; +} + +namespace intrinsics { +} +} + +namespace qt3ds { +namespace state { + + using namespace qt3ds; + using namespace qt3ds::foundation; + using namespace qt3ds::intrinsics; + using qt3ds::foundation::CRegisteredString; + using qt3ds::foundation::IStringTable; + class IStateContext; + class IStateInterpreter; + class IStateLogger; + class IExecutionContext; + class IScriptContext; + struct SSCXML; + struct SState; + struct STransition; + struct SParallel; + struct SFinal; + struct SHistory; + struct SOnEntry; + struct SOnExit; + struct SSend; + struct SRaise; + struct SIf; + struct SElseIf; + struct SElse; + struct SLog; + struct SAssign; + struct SScript; + struct SDataModel; + struct SData; + struct SStateNode; + struct SCancel; + + namespace editor { + class IEditor; + class IEditorObject; + } + + namespace debugger { + class IDebugOutStream; + struct STransitionId; + class IStateMachineListener; + class IStateMachineDebugInterface; + class IDebugger; + struct SDebugPropertyDeclaration; + class IDebuggedInterpreter; + class IDebuggerMasterListener; + class IDebuggedInterpreter; + struct SMicrostep; + class IScriptStateListener; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateApplication.cpp b/src/Runtime/Source/stateapplication/Qt3DSStateApplication.cpp new file mode 100644 index 00000000..cd89d52f --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateApplication.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateApplication.h" +#include "foundation/FileTools.h" +#include "EASTL/vector.h" +#include "foundation/IOStreams.h" +#include "foundation/XML.h" + +#include + +typedef eastl::string TAppStr; + +using namespace qt3ds::foundation; +using namespace qt3ds::state; +using namespace eastl; + +eastl::string IApplication::GetLaunchFile(const char *inFullUIPPath) +{ + eastl::string directory; + eastl::string filestem; + eastl::string extension; + + CFileTools::Split(inFullUIPPath, directory, filestem, extension); + eastl::string uiaPath; + + eastl::vector dirFiles; + CFileTools::GetDirectoryEntries(directory, dirFiles); + + for (qt3ds::QT3DSU32 idx = 0, end = dirFiles.size(); idx < end && uiaPath.empty(); ++idx) { + eastl::string fileExt; + CFileTools::GetExtension(dirFiles[idx].c_str(), fileExt); + if (fileExt.comparei("uia") == 0) + CFileTools::CombineBaseAndRelative(directory.c_str(), dirFiles[idx].c_str(), uiaPath); + } + return uiaPath.empty() == false ? uiaPath : eastl::string(inFullUIPPath); +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateApplication.h b/src/Runtime/Source/stateapplication/Qt3DSStateApplication.h new file mode 100644 index 00000000..3ebe0d4f --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateApplication.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_APPLICATION_H +#define QT3DS_STATE_APPLICATION_H +#include "EASTL/string.h" +#include + +namespace qt3ds { +namespace state { + // Shared code for dealing with .uia files. + class IApplication + { + public: + static eastl::string GetLaunchFile(const char *inFullUIPPath); + }; +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateContext.cpp b/src/Runtime/Source/stateapplication/Qt3DSStateContext.cpp new file mode 100644 index 00000000..60814ed5 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateContext.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateContext.h" +#include "Qt3DSStateXMLIO.h" +#include "foundation/XML.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" + +using namespace qt3ds::state; + +namespace { + +struct SStateContext : public IStateContext +{ + NVFoundationBase &m_Foundation; + TIDStateMap m_IDStateMap; + TSendList m_SendList; + SSCXML *m_Root; + + // the factory needs to be here in order that we can easily just assign variables + // left and right and make things work. + NVScopedRefCounted m_DOMFactory; + TPtrExtensionMap m_ExtensionInfo; + SNamespacePairNode *m_NamespacePairs; + QT3DSI32 mRefCount; + + SStateContext(NVFoundationBase &alloc) + : m_Foundation(alloc) + , m_IDStateMap(alloc.getAllocator(), "SStateContext::m_IDStateMap") + , m_SendList(alloc.getAllocator(), "SStateContext::m_SendList") + , m_Root(NULL) + , m_DOMFactory(NULL) + , m_ExtensionInfo(alloc.getAllocator(), "SStateContext::m_ExtensionInfo") + , m_NamespacePairs(NULL) + , mRefCount(0) + { + } + virtual ~SStateContext() {} + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + void SetDOMFactory(IDOMFactory *inFactory) override; + + void SetRoot(SSCXML &inRoot) override + { + QT3DS_ASSERT(m_Root == NULL); + if (!m_Root) + m_Root = &inRoot; + } + SSCXML *GetRoot() override { return m_Root; } + void AddSendToList(SSend &inSend) override { m_SendList.push_back(&inSend); } + NVConstDataRef GetSendList() override + { + return toConstDataRef(m_SendList.data(), (QT3DSU32)m_SendList.size()); + } + IDOMFactory *GetDOMFactory() override { return m_DOMFactory; } + NVConstDataRef> GetSubContexts() override + { + return NVConstDataRef>(); + } + + // UICStateInterpreter.cpp; + bool InsertId(const CRegisteredString &inId, const SIdValue &inValue) override; + void EraseId(const CRegisteredString &inId) override; + bool ContainsId(const CRegisteredString &inStr) override; + SStateNode *FindStateNode(const CRegisteredString &inStr) override; + SSend *FindSend(const CRegisteredString &inStr) override; + + SItemExtensionInfo *GetExtensionInfo(void *inItem) override; + SItemExtensionInfo &GetOrCreateExtensionInfo(void *inItem) override; + + void SetFirstNSNode(SNamespacePairNode &inNode) override { m_NamespacePairs = &inNode; } + SNamespacePairNode *GetFirstNSNode() override { return m_NamespacePairs; } + + void Save(IOutStream &inOutStream, editor::IEditor *inEditor) override; +}; + +void SStateContext::SetDOMFactory(IDOMFactory *inFactory) +{ + m_DOMFactory = inFactory; +} + +bool SStateContext::InsertId(const CRegisteredString &inId, const SIdValue &inValue) +{ + return m_IDStateMap.insert(eastl::make_pair(inId, inValue)).second; +} + +void SStateContext::EraseId(const CRegisteredString &inId) +{ + m_IDStateMap.erase(inId); +} + +bool SStateContext::ContainsId(const CRegisteredString &inStr) +{ + return m_IDStateMap.find(inStr) != m_IDStateMap.end(); +} + +SStateNode *SStateContext::FindStateNode(const CRegisteredString &inStr) +{ + TIDStateMap::iterator iter = m_IDStateMap.find(inStr); + + if (iter != m_IDStateMap.end()) { + IdValueTypes::Enum typeEnum = iter->second.getType(); + if (typeEnum == IdValueTypes::StateNode) + return iter->second.getData(); + } + return NULL; +} + +SSend *SStateContext::FindSend(const CRegisteredString &inStr) +{ + TIDStateMap::iterator iter = m_IDStateMap.find(inStr); + if (iter != m_IDStateMap.end() && iter->second.getType() == IdValueTypes::Send) + return iter->second.getData(); + return NULL; +} + +SItemExtensionInfo *SStateContext::GetExtensionInfo(void *inItem) +{ + TPtrExtensionMap::iterator iter = m_ExtensionInfo.find(inItem); + if (iter != m_ExtensionInfo.end()) + return &iter->second; + return NULL; +} + +SItemExtensionInfo &SStateContext::GetOrCreateExtensionInfo(void *inItem) +{ + return m_ExtensionInfo.insert(eastl::make_pair(inItem, SItemExtensionInfo(inItem))) + .first->second; +} + +void SStateContext::Save(IOutStream &inOutStream, editor::IEditor *inEditor) +{ + CXMLIO::SaveSCXMLFile(*this, m_Foundation, *m_DOMFactory->GetStringTable(), inOutStream, + inEditor); +} +} + +IStateContext *IStateContext::Load(NVAllocatorCallback &inGraphAllocator, + NVFoundationBase &inFoundation, IInStream &inStream, + const char8_t *inFilename, IStringTable *inStrTable, + editor::IEditor *inEditor) +{ + + NVScopedRefCounted theStringTable = inStrTable; + if (!theStringTable) + theStringTable = IStringTable::CreateStringTable(inFoundation.getAllocator()); + NVScopedRefCounted theFactory = + IDOMFactory::CreateDOMFactory(inFoundation.getAllocator(), theStringTable); + eastl::pair readResult = + CDOMSerializer::Read(*theFactory, inStream); + SDOMElement *elem = readResult.second; + if (elem == NULL) + return NULL; + + NVScopedRefCounted theReader = IDOMReader::CreateDOMReader( + inFoundation.getAllocator(), *elem, theStringTable, *theFactory); + IStateContext *retval = QT3DS_NEW(inFoundation.getAllocator(), SStateContext)(inFoundation); + retval->SetDOMFactory(theFactory.mPtr); + CXMLIO::LoadSCXMLFile(inGraphAllocator, inFoundation, *theReader, *theStringTable, inFilename, + *retval, inEditor); + if (readResult.first) + retval->SetFirstNSNode(*readResult.first); + return retval; +} + +IStateContext *IStateContext::Create(NVFoundationBase &inFoundation) +{ + NVScopedRefCounted theStringTable = + IStringTable::CreateStringTable(inFoundation.getAllocator()); + NVScopedRefCounted theFactory = + IDOMFactory::CreateDOMFactory(inFoundation.getAllocator(), theStringTable); + + SStateContext *retval = QT3DS_NEW(inFoundation.getAllocator(), SStateContext)(inFoundation); + retval->SetDOMFactory(theFactory); + return retval; +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateContext.h b/src/Runtime/Source/stateapplication/Qt3DSStateContext.h new file mode 100644 index 00000000..31098938 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateContext.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_CONTEXT_H +#define QT3DS_STATE_CONTEXT_H +#include "Qt3DSState.h" +#include "Qt3DSStateTypes.h" + +namespace qt3ds { +namespace state { + + // Thanks to the crazy world we live in, we have to store xml extension information + // on the state context. + struct SItemExtensionInfo + { + void *m_ItemPtr; + TDOMElementNodeList m_ExtensionNodes; + TDOMAttributeNodeList m_ExtensionAttributes; + SItemExtensionInfo(void *inItemPtr) + : m_ItemPtr(inItemPtr) + { + } + }; + typedef nvhash_map TPtrExtensionMap; + // Parsing produces a list of send objects that need to be added into the script + // context if they have their idlocation attribute set. + typedef nvvector TSendList; + + class IStateContext : public NVRefCounted + { + public: + // Can only be done once. + virtual void SetRoot(SSCXML &inRoot) = 0; + virtual SSCXML *GetRoot() = 0; + virtual void AddSendToList(SSend &inSend) = 0; + virtual NVConstDataRef GetSendList() = 0; + virtual void SetDOMFactory(IDOMFactory *inFactory) = 0; + virtual IDOMFactory *GetDOMFactory() = 0; + virtual NVConstDataRef> GetSubContexts() = 0; + virtual bool ContainsId(const CRegisteredString &inId) = 0; + virtual bool InsertId(const CRegisteredString &inId, const SIdValue &inValue) = 0; + virtual void EraseId(const CRegisteredString &inId) = 0; + virtual SStateNode *FindStateNode(const CRegisteredString &inStr) = 0; + virtual SSend *FindSend(const CRegisteredString &inStr) = 0; + + virtual SItemExtensionInfo *GetExtensionInfo(void *inItem) = 0; + virtual SItemExtensionInfo &GetOrCreateExtensionInfo(void *inItem) = 0; + + virtual void SetFirstNSNode(SNamespacePairNode &inNode) = 0; + virtual SNamespacePairNode *GetFirstNSNode() = 0; + + virtual void Save(IOutStream &inOutStream, editor::IEditor *inEditor = NULL) = 0; + + // The graph allocator is expected to release anything allocated via it; the general + // allocator doesn't need to do this. + // Filename is stored on the context for debugging purposes, editor is used if during + // loading so we can load extra + // information that is associated with but not stored on the state graph. + // String table will be created if not passed in, editor is optional. + static IStateContext *Load(NVAllocatorCallback &inGraphAllocator, + NVFoundationBase &inFoundation, IInStream &inStream, + const char8_t *inFilename, IStringTable *inStrTable = NULL, + editor::IEditor *inEditor = NULL); + + static IStateContext *Create(NVFoundationBase &inGeneralAlloc); + }; +} +} +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.cpp b/src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.cpp new file mode 100644 index 00000000..4516c2f9 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.cpp @@ -0,0 +1,332 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateExecutionContext.h" +#include "Qt3DSStateExecutionTypes.h" +#include "Qt3DSStateInterpreter.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/StringConversionImpl.h" +#include "Qt3DSStateScriptContext.h" +#include "foundation/Utils.h" +#include "EASTL/string.h" + +using namespace qt3ds::state; + +namespace { +struct SExecContext : public IExecutionContext +{ + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_StringTable; + // Referencing this here would create circular references + IStateInterpreter *m_Interpreter; + IStateLogger *m_DebugLogger; + NVScopedRefCounted m_Logger; + NVScopedRefCounted m_ScriptContext; + bool m_Error; + QT3DSI32 mRefCount; + eastl::string m_DelayStr; + + SExecContext(NVFoundationBase &inFnd, IStringTable &inStrTable, IStateLogger &inLogger, + IScriptContext &inContext) + : m_Foundation(inFnd) + , m_StringTable(inStrTable) + , m_Interpreter(NULL) + , m_DebugLogger(NULL) + , m_Logger(inLogger) + , m_ScriptContext(inContext) + , m_Error(false) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void SetInterpreter(IStateInterpreter &inInterpreter) override + { + m_Interpreter = &inInterpreter; + } + + void SetMachineDebugLogger(IStateLogger &inDebugLogger) override + { + m_DebugLogger = &inDebugLogger; + } + + void SignalError() + { + const char8_t *errorInfo = m_ScriptContext->GetErrorInfo(); + if (errorInfo && *errorInfo) { + m_Interpreter->QueueEvent("error.execution", false); + } + m_Error = true; + } + void ExecuteContent(SExecutableContent &content) + { + switch (content.m_Type) { + case ExecutableContentTypes::Send: { + SSend &theSend = *content.CastTo(); + CRegisteredString theEvent; + if (!isTrivial(theSend.m_EventExpr)) { + SScriptExecutionResult theStr = + m_ScriptContext->ExecuteExpressionToString(theSend.m_EventExpr); + if (theStr.Valid()) + theEvent = m_StringTable->RegisterStr(theStr.Result()); + } else + theEvent = theSend.m_Event; + + QT3DSU64 theDelay(0); + m_DelayStr.clear(); + if (!isTrivial(theSend.m_DelayExpr)) { + SScriptExecutionResult theStr = + m_ScriptContext->ExecuteExpressionToString(theSend.m_DelayExpr); + if (theStr.Valid()) + m_DelayStr.assign(nonNull(theStr.Result())); + } else + m_DelayStr.assign(nonNull(theSend.m_Delay)); + if (m_DelayStr.size()) + theDelay = ParseTimeStrToMilliseconds(m_DelayStr.c_str()); + + if (theEvent.IsValid()) { + TEventPtr theEventPtr; + if (theSend.m_Children.empty() == false) { + IScriptEvent *theNewEvent = m_ScriptContext->CreateScriptEvent(theEvent); + theEventPtr = theNewEvent; + for (TExecutableContentList::iterator iter = theSend.m_Children.begin(), + end = theSend.m_Children.end(); + iter != end && m_Error == false; ++iter) { + if (iter->m_Type == ExecutableContentTypes::Param) { + SParam &theParam = static_cast(*iter); + if (theParam.m_Location.IsValid() == false) { + bool success = + theNewEvent->SetParam(theParam.m_Name, theParam.m_Expr); + if (!success) + SignalError(); + } else { + QT3DS_ASSERT(false); + } + } else if (iter->m_Type == ExecutableContentTypes::Content) { + SContent &theContent = static_cast(*iter); + if (!isTrivial(theContent.m_Expr)) { + bool success = theNewEvent->SetDataExpr(theContent.m_Expr); + if (!success) + SignalError(); + } else if (!isTrivial(theContent.m_ContentValue)) { + bool success = theNewEvent->SetDataStr(theContent.m_ContentValue); + if (!success) + SignalError(); + } + } else { + QT3DS_ASSERT(false); + } + } + } + if (m_Error == false) { + bool isExternal = true; + if (AreEqual("#_internal", theSend.m_Target)) + isExternal = false; + if (theEventPtr) + m_Interpreter->QueueEvent(theEventPtr, theDelay, theSend.m_Id, isExternal); + else + m_Interpreter->QueueEvent(theEvent, theDelay, theSend.m_Id, isExternal); + } + } + } break; + case ExecutableContentTypes::Cancel: { + SCancel &theCancel = *content.CastTo(); + if (theCancel.m_Send) { + m_Interpreter->CancelEvent(theCancel.m_Send->m_Id); + } else if (!isTrivial(theCancel.m_IdExpression)) { + SScriptExecutionResult theStr = + m_ScriptContext->ExecuteExpressionToString(theCancel.m_IdExpression); + if (theStr.Valid()) { + const char8_t *theStrVal(theStr.Result()); + if (!isTrivial(theStrVal)) + m_Interpreter->CancelEvent(m_StringTable->RegisterStr(theStrVal)); + } + } + } break; + case ExecutableContentTypes::Raise: { + SRaise &theRaise = *content.CastTo(); + m_Interpreter->QueueEvent(theRaise.m_Event, false); + } break; + case ExecutableContentTypes::Log: { + SLog *theLog = content.CastTo(); + SScriptExecutionResult str = + m_ScriptContext->ExecuteExpressionToString(theLog->m_Expression); + if (str.Valid()) { + m_Logger->Log(theLog->m_Label, str.Result()); + if (m_DebugLogger) + m_DebugLogger->Log(theLog->m_Label, str.Result()); + } else + SignalError(); + } break; + case ExecutableContentTypes::If: { + SIf &theIf = *content.CastTo(); + Option theCondResult = m_ScriptContext->ExecuteCondition(theIf.m_Cond); + if (theCondResult.hasValue()) { + bool currentConditionResult = *theCondResult; + for (TExecutableContentList::iterator ifIter = theIf.m_Children.begin(), + ifEnd = theIf.m_Children.end(); + ifIter != ifEnd && m_Error == false; ++ifIter) { + if (currentConditionResult) { + switch (ifIter->m_Type) { + case ExecutableContentTypes::Else: + case ExecutableContentTypes::ElseIf: + return; + default: + ExecuteContent(*ifIter); + break; + } + } else { + switch (ifIter->m_Type) { + case ExecutableContentTypes::ElseIf: { + SElseIf &theElseIf = *ifIter->CastTo(); + theCondResult = m_ScriptContext->ExecuteCondition(theElseIf.m_Cond); + if (theCondResult.hasValue()) + currentConditionResult = *theCondResult; + else { + SignalError(); + return; + } + } break; + case ExecutableContentTypes::Else: + currentConditionResult = true; + break; + // Ignore all content that isn't if or else if we shouldn't be currently + // executing it. + default: + break; + } + } + } + } else + SignalError(); + } break; + case ExecutableContentTypes::Foreach: { + SForeach &theItem = *content.CastTo(); + Option success; + for (success = m_ScriptContext->BeginForeach(theItem.m_Array, theItem.m_Item, + theItem.m_Index); + success.hasValue() && *success && m_Error == false; + success = m_ScriptContext->NextForeach(theItem.m_Item, theItem.m_Index)) { + ExecuteContent(theItem.m_Children); + } + if (m_Error) { + + } else if (success.hasValue() == false) + SignalError(); + } break; + // We shouldn't get top level else or else if statements, they can only be inside an if + // statement. + case ExecutableContentTypes::Else: + case ExecutableContentTypes::ElseIf: + QT3DS_ASSERT(false); + break; + + case ExecutableContentTypes::Assign: { + SAssign &theAssign = *content.CastTo(); + bool success = m_ScriptContext->Assign(theAssign.m_Location, theAssign.m_Expression); + if (!success) + SignalError(); + } break; + case ExecutableContentTypes::Script: { + SScript &theScript = *content.CastTo(); + if (!isTrivial(theScript.m_Data)) + m_ScriptContext->ExecuteScript(theScript.m_Data); + } break; + default: + qCCritical(INTERNAL_ERROR, "Unimplemented executable content %s", + ExecutableContentTypes::ToString(content.m_Type)); + } + } + + void ExecuteContent(TExecutableContentList &inContent) + { + for (TExecutableContentList::iterator iter = inContent.begin(), end = inContent.end(); + iter != end && m_Error == false; ++iter) { + ExecuteContent(*iter); + } + } + + void Execute(STransition &inTransaction) override + { + m_Error = false; + ExecuteContent(inTransaction.m_ExecutableContent); + } + + // These functions take the node as well as the list so a context can cache a fast + // execution path if necessary. + void Execute(SStateNode & /*inNode*/, TOnEntryList &inList) override + { + for (TOnEntryList::iterator iter = inList.begin(), end = inList.end(); iter != end; + ++iter) { + m_Error = false; + ExecuteContent(iter->m_ExecutableContent); + } + } + + void Execute(SStateNode & /*inNode*/, TOnExitList &inList) override + { + for (TOnExitList::iterator iter = inList.begin(), end = inList.end(); iter != end; ++iter) { + m_Error = false; + ExecuteContent(iter->m_ExecutableContent); + } + } +}; +} + +QT3DSU64 IExecutionContext::ParseTimeStrToMilliseconds(const char8_t *timeStr) +{ + if (isTrivial(timeStr)) + return 0; + + char *endPtr; + double theData = strtod(timeStr, &endPtr); + if (!isTrivial(endPtr)) { + if (AreEqual(endPtr, "s")) { + theData *= 1000; + } else if (AreEqual(endPtr, "ms")) { + // empty intentional + } else + theData = 0; + } else + theData = 0; + if (theData < 0) + theData = 0.0; + return static_cast(theData); +} + +IExecutionContext &IExecutionContext::Create(NVFoundationBase &inFoundation, + IStringTable &inStringTable, IStateLogger &inLogger, + IScriptContext &inScriptContext) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SExecContext)(inFoundation, inStringTable, inLogger, + inScriptContext); +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.h b/src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.h new file mode 100644 index 00000000..31ff0e22 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateExecutionContext.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EXECUTION_CONTEXT_H +#define QT3DS_STATE_EXECUTION_CONTEXT_H +#pragma once +#include "Qt3DSState.h" +#include "Qt3DSStateTypes.h" +#include "foundation/Qt3DSRefCounted.h" + +namespace qt3ds { +namespace state { + + class IStateLogger : public NVRefCounted + { + protected: + virtual ~IStateLogger() {} + public: + virtual void Log(const char8_t *inLabel, const char8_t *inExpression) = 0; + }; + // Implementation of the execution context of the scxml state specification. + // Implementations if,send,raise,foreach,etc working closely with the scripting + // system. + class IExecutionContext : public NVRefCounted + { + protected: + virtual ~IExecutionContext() {} + public: + virtual void SetInterpreter(IStateInterpreter &inInterpreter) = 0; + virtual void SetMachineDebugLogger(IStateLogger &inDebugLogger) = 0; + virtual void Execute(STransition &inTransaction) = 0; + // These functions take the node as well as the list so a context can cache a fast + // execution path if necessary. + virtual void Execute(SStateNode &inNode, TOnEntryList &inList) = 0; + virtual void Execute(SStateNode &inNode, TOnExitList &inList) = 0; + + // Returns the time string in milliseconds. + static QT3DSU64 ParseTimeStrToMilliseconds(const char8_t *timeStr); + + static IExecutionContext &Create(NVFoundationBase &inFoundation, + IStringTable &inStringTable, IStateLogger &inLogger, + IScriptContext &inScriptContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateExecutionTypes.h b/src/Runtime/Source/stateapplication/Qt3DSStateExecutionTypes.h new file mode 100644 index 00000000..6dc7674f --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateExecutionTypes.h @@ -0,0 +1,392 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EXECUTION_TYPES_H +#define QT3DS_STATE_EXECUTION_TYPES_H +#pragma once +#include "Qt3DSStateTypes.h" + +namespace qt3ds { +namespace state { + + struct ExecutableContentTypes + { + enum Enum { + NoType = 0, + Raise, + If, + ElseIf, + Else, + Foreach, + Log, + Assign, + Script, + Send, + Cancel, + Param, + Content, + }; + static const char8_t *ToString(Enum inVal) + { + switch (inVal) { + case Raise: + return "Raise"; + case If: + return "If"; + case ElseIf: + return "ElseIf"; + case Else: + return "Else"; + case Foreach: + return "Foreach"; + case Log: + return "Log"; + case Assign: + return "Assign"; + case Script: + return "Script"; + case Send: + return "Send"; + case Cancel: + return "Cancel"; + case Param: + return "Param"; + case Content: + return "Content"; + default: + return "Unknown execution type"; + } + } + }; + + struct SRaise; + struct SIf; + struct SElseIf; + struct SElse; + struct SForeach; + struct SLog; + struct SAssign; + struct SScript; + struct SSend; + struct SCancel; + struct SParam; + struct SContent; + + template + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::NoType; + } + }; + + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Raise; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() { return ExecutableContentTypes::If; } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::ElseIf; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Else; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Foreach; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() { return ExecutableContentTypes::Log; } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Assign; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Script; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Send; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Cancel; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Param; + } + }; + template <> + struct SExecutableContentTypeMap + { + static ExecutableContentTypes::Enum GetContentType() + { + return ExecutableContentTypes::Content; + } + }; + + // Defined by the execution context to speed up evaluation of executable data. + struct SExecutionData; + + struct SExecutableContent + { + const ExecutableContentTypes::Enum m_Type; + SStateNode *m_StateNodeParent; + SExecutableContent *m_Parent; + SExecutableContent *m_NextSibling; + SExecutableContent *m_PreviousSibling; + TExecutableContentList m_Children; + + SExecutableContent(ExecutableContentTypes::Enum inType) + : m_Type(inType) + , m_StateNodeParent(NULL) + , m_Parent(NULL) + , m_NextSibling(NULL) + , m_PreviousSibling(NULL) + { + } + + template + TDataType *CastTo() + { + if (m_Type == SExecutableContentTypeMap::GetContentType()) + return static_cast(this); + return NULL; + } + + template + const TDataType *CastTo() const + { + if (m_Type == SExecutableContentTypeMap::GetContentType()) + return static_cast(this); + return NULL; + } + }; + + IMPLEMENT_INVASIVE_LIST(ExecutableContent, m_PreviousSibling, m_NextSibling); + + struct SRaise : public SExecutableContent + { + CRegisteredString m_Event; + SRaise() + : SExecutableContent(ExecutableContentTypes::Raise) + { + } + }; + + struct SIf : public SExecutableContent + { + const char8_t *m_Cond; + SIf() + : SExecutableContent(ExecutableContentTypes::If) + , m_Cond(NULL) + { + } + }; + + struct SElseIf : public SExecutableContent + { + const char8_t *m_Cond; + SElseIf() + : SExecutableContent(ExecutableContentTypes::ElseIf) + , m_Cond(NULL) + { + } + }; + + struct SElse : public SExecutableContent + { + SElse() + : SExecutableContent(ExecutableContentTypes::Else) + { + } + }; + + struct SForeach : public SExecutableContent + { + CRegisteredString m_Array; + CRegisteredString m_Item; + CRegisteredString m_Index; + SForeach() + : SExecutableContent(ExecutableContentTypes::Foreach) + { + } + }; + + struct SLog : public SExecutableContent + { + CRegisteredString m_Label; + const char8_t *m_Expression; + SLog() + : SExecutableContent(ExecutableContentTypes::Log) + , m_Expression(NULL) + { + } + }; + + struct SAssign : public SExecutableContent + { + const char8_t *m_Location; + const char8_t *m_Expression; + SAssign() + : SExecutableContent(ExecutableContentTypes::Assign) + , m_Location(NULL) + , m_Expression(NULL) + { + } + }; + + struct SScript : public SExecutableContent + { + const char8_t *m_URL; + const char8_t *m_Data; + SScript() + : SExecutableContent(ExecutableContentTypes::Script) + , m_URL(NULL) + , m_Data(NULL) + { + } + }; + + struct SSend : public SExecutableContent + { + CRegisteredString m_Event; + const char8_t *m_EventExpr; + const char8_t *m_Target; + const char8_t *m_TargetExpr; + const char8_t *m_Type; + const char8_t *m_TypeExpr; + CRegisteredString m_Id; + const char8_t *m_IdLocation; + const char8_t *m_Delay; + const char8_t *m_DelayExpr; + const char8_t *m_NameList; + + SSend() + : SExecutableContent(ExecutableContentTypes::Send) + , m_EventExpr(NULL) + , m_Target(NULL) + , m_TargetExpr(NULL) + , m_Type(NULL) + , m_TypeExpr(NULL) + , m_IdLocation(NULL) + , m_Delay(NULL) + , m_DelayExpr(NULL) + , m_NameList(NULL) + { + } + }; + struct SCancel : public SExecutableContent + { + // If we have an id. + SSend *m_Send; + const char8_t *m_IdExpression; + + SCancel() + : SExecutableContent(ExecutableContentTypes::Cancel) + , m_Send(NULL) + , m_IdExpression(NULL) + { + } + }; + + struct SParam : public SExecutableContent + { + CRegisteredString m_Name; + const char8_t *m_Expr; + CRegisteredString m_Location; + SParam() + : SExecutableContent(ExecutableContentTypes::Param) + , m_Expr(NULL) + { + } + }; + + struct SContent : public SExecutableContent + { + const char8_t *m_Expr; + const char8_t *m_ContentValue; + SContent() + : SExecutableContent(ExecutableContentTypes::Content) + , m_Expr(NULL) + , m_ContentValue(NULL) + { + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateIdValue.h b/src/Runtime/Source/stateapplication/Qt3DSStateIdValue.h new file mode 100644 index 00000000..ed5beb13 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateIdValue.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_STATE_ID_TYPE_VALUE_H +#define QT3DS_STATE_ID_TYPE_VALUE_H +#include "Qt3DSState.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" + +// Discriminated union to unify different things that may be identified by an id +namespace qt3ds { +namespace state { + + struct IdValueTypes + { + enum Enum { + NoIdValue = 0, + StateNode, + Send, + }; + }; + + template + struct SIdValueTypeMap + { + static IdValueTypes::Enum GetType() { return IdValueTypes::NoIdValue; } + }; + + template <> + struct SIdValueTypeMap + { + static IdValueTypes::Enum GetType() { return IdValueTypes::StateNode; } + }; + template <> + struct SIdValueTypeMap + { + static IdValueTypes::Enum GetType() { return IdValueTypes::Send; } + }; + + struct SIdValueUnionTraits + { + typedef IdValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(void *), + }; + + static TIdType getNoDataId() { return IdValueTypes::NoIdValue; } + + template + static TIdType getType() + { + return SIdValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case IdValueTypes::StateNode: + return inVisitor(*NVUnionCast(inData)); + case IdValueTypes::Send: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case IdValueTypes::NoIdValue: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case IdValueTypes::StateNode: + return inVisitor(*NVUnionCast(inData)); + case IdValueTypes::Send: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case IdValueTypes::NoIdValue: + return inVisitor(); + } + } + }; +} +} + +// need some specializations in the original nv foundation namespace +namespace qt3ds { +namespace foundation { + + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SStateNode *) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SSend *) {} + }; +} +} + +namespace qt3ds { +namespace state { + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SIdValueUnionTraits::TBufferSize> + TIdUnionType; + + struct SIdValue : public TIdUnionType + { + SIdValue() {} + + SIdValue(const SIdValue &inOther) + : TIdUnionType(static_cast(inOther)) + { + } + + SIdValue(SStateNode *inDt) + : TIdUnionType(inDt) + { + } + SIdValue(SSend *inDt) + : TIdUnionType(inDt) + { + } + + SIdValue &operator=(const SIdValue &inOther) + { + TIdUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SIdValue &inOther) const { return TIdUnionType::operator==(inOther); } + bool operator!=(const SIdValue &inOther) const { return TIdUnionType::operator!=(inOther); } + + bool empty() const { return getType() == IdValueTypes::NoIdValue; } + }; +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.cpp b/src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.cpp new file mode 100644 index 00000000..9fc72406 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.cpp @@ -0,0 +1,2057 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateTypes.h" +#include "Qt3DSStateInterpreter.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSIntrinsics.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Utils.h" +#include "foundation/Qt3DSPool.h" +#include "foundation/Qt3DSTime.h" +#include "EASTL/string.h" +#include "EASTL/set.h" +#include "EASTL/sort.h" +#include "EASTL/list.h" +#include "Qt3DSStateExecutionContext.h" +#include "Qt3DSStateExecutionTypes.h" +#include "Qt3DSStateScriptContext.h" +#include "Qt3DSStateSharedImpl.h" +#include "foundation/XML.h" +#include "Qt3DSStateIdValue.h" +#include "Qt3DSStateDebugger.h" +#include "Qt3DSStateXMLIO.h" +#include "Qt3DSStateDebuggerValues.h" +#include "Qt3DSStateContext.h" +#include "foundation/FastAllocator.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::debugger; + +#ifdef _DEBUG +#define QT3DS_LOG_ENTER_EXIT 1 +#define QT3DS_LOG_ACTIVE_EVENT 1 +#endif + +namespace qt3ds { +namespace state { + struct SInterpreterData + { + }; +} +} + +namespace { +struct SSimpleEvent : public IEvent +{ + NVAllocatorCallback &m_Alloc; + volatile QT3DSI32 mRefCount; + CRegisteredString m_Name; + + SSimpleEvent(NVAllocatorCallback &alloc, CRegisteredString nm) + : m_Alloc(alloc) + , mRefCount(0) + , m_Name(nm) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc) + + CRegisteredString GetName() const override { return m_Name; } +}; + +struct SStateNodeInterpreterData : public SInterpreterData +{ + + QT3DSI32 m_DocumentOrder; + bool m_Entered; + SStateNode *m_TransitionSubgraphRoot; + + SStateNodeInterpreterData(QT3DSI32 inDocOrder) + : m_DocumentOrder(inDocOrder) + , m_Entered(false) + , m_TransitionSubgraphRoot(NULL) + { + } +}; + +template , + typename TEqOp = eastl::equal_to> +struct SOrderedSet +{ + typedef eastl::hash_set TSetType; + typedef nvvector TListType; + + TSetType m_Set; + TListType m_List; + typedef typename TListType::iterator iterator; + + SOrderedSet(NVAllocatorCallback &alloc, const char *inTypeName) + : m_Set(ForwardingAllocator(alloc, inTypeName)) + , m_List(alloc, inTypeName) + { + } + + bool insert(const TDataType &inDtype) + { + if (m_Set.insert(inDtype).second) { + m_List.push_back(inDtype); + return true; + } + return false; + } + + void clear() + { + m_Set.clear(); + m_List.clear(); + } + + iterator begin() { return m_List.begin(); } + iterator end() { return m_List.end(); } + QT3DSU32 size() const { return m_List.size(); } + bool contains(const TDataType &inType) const { return m_Set.find(inType) != m_Set.end(); } + TDataType operator[](int inIndex) + { + if (inIndex < (int)size()) + return m_List[inIndex]; + return TDataType(); + } + void erase(const TDataType &inType) + { + typename TSetType::iterator iter = m_Set.find(inType); + if (iter != m_Set.end()) { + m_Set.erase(iter); + typename TListType::iterator iter = eastl::find(m_List.begin(), m_List.end(), inType); + if (iter != m_List.end()) + m_List.erase(iter); + else { + QT3DS_ASSERT(false); + } + } + } +}; + +struct SStateNodeNode +{ + SStateNode *m_Node; + SStateNodeNode *m_NextSibling; + SStateNodeNode() + : m_Node(NULL) + , m_NextSibling(NULL) + { + } + SStateNodeNode(SStateNode *inNode) + : m_Node(inNode) + , m_NextSibling(NULL) + { + } +}; + +DEFINE_INVASIVE_SINGLE_LIST(StateNodeNode); +IMPLEMENT_INVASIVE_SINGLE_LIST(StateNodeNode, m_NextSibling); + +struct SFutureEvent +{ + TEventPtr m_Event; + QT3DSU64 m_FireTime; + CRegisteredString m_CancelId; + bool m_IsExternal; + SFutureEvent(TEventPtr evt, QT3DSU64 ft, CRegisteredString id, bool inExternal) + : m_Event(evt) + , m_FireTime(ft) + , m_CancelId(id) + , m_IsExternal(inExternal) + { + } + SFutureEvent() + : m_FireTime((QT3DSU64)-1) + , m_IsExternal(false) + { + } + // We want the events sorted in *reverse* time order. + bool operator<(const SFutureEvent &inOther) const { return m_FireTime < inOther.m_FireTime; } +}; + +struct StateSystem; + +typedef SOrderedSet TStateNodeSet; +typedef SOrderedSet TTransitionSet; +typedef nvvector TTransitionList; + +struct SDebugInterface : public IStateMachineDebugInterface, public IStateLogger +{ + StateSystem &m_StateSystem; + // No listener means no events and no active breakpoints of course + NVScopedRefCounted m_Listener; + TDebugStr m_LogStr; + TDebugStr m_TempStr; + TDebugStrList m_EnterList; + TDebugStrList m_ExitList; + TTransitionIdList m_TransitionList; + + SDebugInterface(StateSystem &ss) + : m_StateSystem(ss) + , m_Listener(NULL) + { + } + // ignored as this object is part of the state system. + void addRef() override; + void release() override; + bool valid() { return m_Listener.mPtr != NULL; } + + void SetStateMachineListener(IStateMachineListener *inListener) override + { + if (m_Listener.mPtr != inListener) { + m_Listener = inListener; + if (m_Listener) + OnConnect(); + } + } + + // IStateLogger interface + void Log(const char8_t *inLabel, const char8_t *inExpression) override + { + if (m_Listener) { + m_LogStr.assign(nonNull(inLabel)); + m_LogStr.append(" - "); + m_LogStr.append(nonNull(inExpression)); + m_Listener->Log(m_LogStr); + } + } + + IScriptContext &GetScriptContext() override; + + // Functions implemented after StateSystem in order to take advantage of the StateSystem struct + // members directly. + void OnConnect(); + + void EventQueued(const char8_t *inEventName, bool inInternal) + { + m_Listener->EventQueued(inEventName, inInternal); + } + // Functions should not be called in there is not a valid listener + void BeginStep(); + void BeginMicrostep(); + void SetCurrentEvent(const char8_t *inEventName, bool inInternal); + void SetTransitionSet(const TTransitionList &inTransitions); + void SetExitSet(const TStateNodeSet &inSet); + void SetEnterSet(const TStateNodeSet &inSet); + // Log statements run through the debugger as well. + void EndMicrostep(); + void EndStep(); + void OnExternalBreak() override; +}; + +#define DEBUGGER_CALL(function) \ + if (m_DebugInterface.valid()) \ + m_DebugInterface.function(); +#define DEBUGGER_CALL1(function, arg) \ + if (m_DebugInterface.valid()) \ + m_DebugInterface.function(arg); +#define DEBUGGER_CALL2(function, arg, arg2) \ + if (m_DebugInterface.valid()) \ + m_DebugInterface.function(arg, arg2); + +#ifdef _WIN32 +#pragma warning(disable : 4355) +#endif +struct SStateSignalSender : public IStateSignalConnection +{ + NVAllocatorCallback &m_Alloc; + StateSystem *m_System; + IStateInterpreterEventHandler &m_Handler; + volatile QT3DSI32 mRefCount; + SStateSignalSender(NVAllocatorCallback &inAlloc, StateSystem &inSystem, + IStateInterpreterEventHandler &inHandler) + : m_Alloc(inAlloc) + , m_System(&inSystem) + , m_Handler(inHandler) + , mRefCount(0) + { + } + virtual ~SStateSignalSender(); + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc) +}; + +// Note that we explicity don't addref the signal sender internally. This is by design. +typedef nvvector TSignalSenderList; + +struct StateSystem : public IStateInterpreter +{ + typedef eastl::basic_string TStrType; + typedef Pool TInterperterDataPool; + typedef eastl::list TEventQueue; + typedef nvhash_map THistoryMap; + typedef Pool TStateNodeNodePool; + typedef nvvector TFutureEventList; + typedef nvhash_set TTransitionHashSet; + typedef Pool TTransitionPool; + + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_Context; + volatile QT3DSI32 mRefCount; + // Holds the leaves of the current state. + NVScopedRefCounted m_StringTable; + NVScopedRefCounted m_ScriptContext; + NVScopedRefCounted m_ExecutionContext; + nvvector m_ParentComparisonLHS; + nvvector m_ParentComparisonRHS; + nvvector m_AncestorsList; + nvvector m_IDRefList; + + THistoryMap m_HistoryMap; + + SOrderedSet m_Configuration; + nvvector m_StatesToInvoke; + nvvector m_TransitionTargetList; + TTransitionList m_EnabledTransitions; + + TEventQueue m_InternalQueue; + TEventQueue m_ExternalQueue; + + SOrderedSet m_TransitionSet; + + TStateNodeSet m_StatesToEnter; + TStateNodeSet m_StatesForDefaultEntry; + TStateNodeSet m_StatesToExit; + + TInterperterDataPool m_InterpreterDataPool; + TStateNodeNodePool m_StateNodeNodePool; + + TStrType m_Workspace; + + TFutureEventList m_FutureEvents; + + bool m_Initialized; + bool m_Running; + + SDebugInterface m_DebugInterface; + TSignalSenderList m_SignalSenders; + + TTransitionHashSet m_InvalidTransitions; + + TTransitionPool m_TransitionPool; + nvvector m_TemporaryTransitions; + nvhash_map m_StateInitialTransitionMap; + SFastAllocator<> m_TemporaryAllocator; + TStrType m_IdSplitter; + nvvector m_TempNodeList; + + StateSystem(NVFoundationBase &inFnd, IStringTable &inStrTable, IScriptContext &inScriptContext, + IExecutionContext &inExecutionContext) + : m_Foundation(inFnd) + , mRefCount(0) + , m_StringTable(inStrTable) + , m_ScriptContext(inScriptContext) + , m_ExecutionContext(inExecutionContext) + , m_ParentComparisonLHS(inFnd.getAllocator(), "StateSystem::m_ParentComparisonLHS") + , m_ParentComparisonRHS(inFnd.getAllocator(), "StateSystem::m_ParentComparisonRHS") + , m_AncestorsList(inFnd.getAllocator(), "StateSystem::m_AncestorsList") + , m_IDRefList(inFnd.getAllocator(), "StateSystem::m_IDRefList") + , m_HistoryMap(inFnd.getAllocator(), "StateSystem::m_HistoryMap") + , m_Configuration(inFnd.getAllocator(), "StateSystem::m_Configuration") + , m_StatesToInvoke(inFnd.getAllocator(), "StateSystem::m_InvokeList") + , m_TransitionTargetList(inFnd.getAllocator(), "StateSystem::m_TransitionTargetList") + , m_EnabledTransitions(inFnd.getAllocator(), "StateSystem::m_TransitionList") + , m_InternalQueue(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_InternalQueue")) + , m_ExternalQueue(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_ExternalQueue")) + , m_TransitionSet(inFnd.getAllocator(), "StateSystem::m_TransitionSet") + , m_StatesToEnter(inFnd.getAllocator(), "StateSystem::m_StatesToEnter") + , m_StatesForDefaultEntry(inFnd.getAllocator(), "StateSystem::m_StatesForDefaultEntry") + , m_StatesToExit(inFnd.getAllocator(), "StateSystem::m_StatesToExit") + , m_InterpreterDataPool( + ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_InterpretDataPool")) + , m_StateNodeNodePool( + ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_StateNodeNodePool")) + , m_Workspace(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_Workspace")) + , m_FutureEvents(inFnd.getAllocator(), "StateSystem::m_FutureEvents") + , m_Initialized(false) + , m_Running(false) + , m_DebugInterface(*this) + , m_SignalSenders(inFnd.getAllocator(), "StateSystem::m_SignalSenders") + , m_InvalidTransitions(inFnd.getAllocator(), "StateSystem::m_InvalidTransitions") + , m_TransitionPool( + ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_TransitionPool")) + , m_TemporaryTransitions(inFnd.getAllocator(), "StateSystem::m_TemporaryTransitions") + , m_StateInitialTransitionMap(inFnd.getAllocator(), + "StateSystem::m_StateInitialTempTransitionMap") + , m_TemporaryAllocator(inFnd.getAllocator(), "StateSystem::m_TemporaryAllocator") + , m_IdSplitter(ForwardingAllocator(inFnd.getAllocator(), "StateSystem::m_IdSplitter")) + , m_TempNodeList(inFnd.getAllocator(), "StateSystem::m_TempNodeList") + { + inExecutionContext.SetInterpreter(*this); + inExecutionContext.SetMachineDebugLogger(m_DebugInterface); + inScriptContext.SetInterpreter(*this); + } + + ~StateSystem() + { + // Ensure the signallers will not attempt to communicate to this object. + for (TSignalSenderList::iterator iter = m_SignalSenders.begin(), + end = m_SignalSenders.end(); + iter != end; ++iter) + (*iter)->m_System = NULL; + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void InitializeDataStructures() + { + m_Configuration.clear(); + m_StatesToInvoke.clear(); + m_EnabledTransitions.clear(); + m_Running = true; + } + + STransition &CreateTemporaryTransition() + { + STransition *newTrans = m_TransitionPool.construct(__FILE__, __LINE__); + m_TemporaryTransitions.push_back(newTrans); + return *newTrans; + } + + void ReleaseInitialAndTemporaryTransitions() + { + for (QT3DSU32 idx = 0, end = m_TemporaryTransitions.size(); idx < end; ++idx) + m_TransitionPool.deallocate(m_TemporaryTransitions[idx]); + m_TemporaryTransitions.clear(); + m_StateInitialTransitionMap.clear(); + m_TemporaryAllocator.reset(); + } + + void FreeHistoryData(SHistory &inHistory) + { + THistoryMap::iterator historyData = m_HistoryMap.find(&inHistory); + if (historyData != m_HistoryMap.end()) { + for (TStateNodeNodeList::iterator iter = historyData->second.begin(), + end = historyData->second.end(); + iter != end; ++iter) + m_StateNodeNodePool.deallocate(&(*iter)); + // Force clear the list. + historyData->second.m_Head = NULL; + } + } + + TStateNodeNodeList *GetHistoryData(SHistory &inHistory) + { + THistoryMap::iterator historyData = m_HistoryMap.find(&inHistory); + if (historyData != m_HistoryMap.end()) + return &historyData->second; + return NULL; + } + + TStateNodeNodeList &GetOrCreateHistoryData(SHistory &inHistory) + { + THistoryMap::iterator historyData = m_HistoryMap.find(&inHistory); + if (historyData != m_HistoryMap.end()) + return historyData->second; + return m_HistoryMap.insert(eastl::make_pair(&inHistory, TStateNodeNodeList())) + .first->second; + } + + // Setup of the state system, you can add a set of roots to the state graph. + NVConstDataRef GetConfiguration() override { return m_Configuration.m_List; } + + void GetPathToRoot(SStateNode &state, nvvector &inParents, bool inProper) + { + inParents.clear(); + SStateNode *stateIter = &state; + if (inProper) + stateIter = state.m_Parent; + for (; stateIter; stateIter = stateIter->m_Parent) + inParents.push_back(stateIter); + } + + // Given these two states, get the nearest parent they share in common. + // Return valid is the index taken from the end of the m_ParentComparison* lists. + // the index is valid in both of them. + QT3DSI32 GetSharedParentState(SStateNode &lhs, SStateNode &rhs, bool inProper) + { + GetPathToRoot(lhs, m_ParentComparisonLHS, inProper); + GetPathToRoot(rhs, m_ParentComparisonRHS, inProper); + if (m_ParentComparisonLHS.empty() || m_ParentComparisonRHS.empty()) { + QT3DS_ASSERT(false); + return -1; + } + QT3DS_ASSERT(m_ParentComparisonLHS.back() == m_ParentComparisonRHS.back()); + QT3DSI32 retval = 0; + for (nvvector::reverse_iterator lhsComp = m_ParentComparisonLHS.rbegin(), + rhsComp = m_ParentComparisonRHS.rbegin(), + lhsEnd = m_ParentComparisonLHS.rend(), + rhsEnd = m_ParentComparisonRHS.rend(); + lhsComp != lhsEnd && rhsComp != rhsEnd && *lhsComp == *rhsComp; + ++lhsComp, ++rhsComp, ++retval) { + } + // Walk the path to the root backwards and note where it differs. + return retval - 1; + } + + void CreateStateNodeInterpreterData(SStateNode &inNode, QT3DSI32 &inIdx) + { + inNode.m_InterpreterData = m_InterpreterDataPool.construct(inIdx, __FILE__, __LINE__); + ++inIdx; + if (inNode.m_Type == StateNodeTypes::SCXML) { + SSCXML *item = inNode.CastTo(); + if (item->m_Initial) + CreateStateNodeInterpreterData(*item->m_Initial, inIdx); + } else if (inNode.m_Type == StateNodeTypes::State) { + SState *item = inNode.CastTo(); + if (item->m_Initial) + CreateStateNodeInterpreterData(*item->m_Initial, inIdx); + } + if (StateNodeTypes::CanHaveChildren(inNode.m_Type)) { + SStateParallelBase &theBase = static_cast(inNode); + for (TStateNodeList::iterator iter = theBase.m_Children.begin(), + end = theBase.m_Children.end(); + iter != end; ++iter) + CreateStateNodeInterpreterData(*iter, inIdx); + } + } + + // Creates the interpreter data for the entire graph. + void CreateStateNodeInterpreterData() + { + if (m_Context->GetRoot() == NULL) { + QT3DS_ASSERT(false); + return; + } + QT3DSI32 nodeIdx = 1; + CreateStateNodeInterpreterData(*m_Context->GetRoot(), nodeIdx); + } + + SStateNodeInterpreterData &GetOrCreateInterpreterData(SStateNode &inNode) + { + if (!inNode.m_InterpreterData) + CreateStateNodeInterpreterData(); + + return *static_cast(inNode.m_InterpreterData); + } + struct SStateNodeSorter + { + StateSystem &m_System; + SStateNodeSorter(StateSystem &inS) + : m_System(inS) + { + } + bool operator()(SStateNode *lhs, SStateNode *rhs) const + { + return m_System.GetOrCreateInterpreterData(*lhs).m_DocumentOrder + < m_System.GetOrCreateInterpreterData(*rhs).m_DocumentOrder; + } + }; + + void SortByDocumentOrder(nvvector &inList) + { + eastl::sort(inList.begin(), inList.end(), SStateNodeSorter(*this)); + } + + void SortConfiguration() { SortByDocumentOrder(m_Configuration.m_List); } + + void RunDataModel(SDataModel &inDM) + { + QT3DS_ASSERT(inDM.m_Source == NULL); + QT3DS_ASSERT(inDM.m_Expression == NULL); + for (TDataList::iterator iter = inDM.m_Data.begin(), end = inDM.m_Data.end(); iter != end; + ++iter) { + if (iter->m_Source == NULL) + m_ScriptContext->Assign(iter->m_Id.c_str(), iter->m_Expression); + else { + QT3DS_ASSERT(false); + } + } + } + + void RecursiveInitializeDataModel(SStateNode &inState) + { + SDataModel *theDataModel = inState.GetDataModel(); + if (theDataModel) + RunDataModel(*theDataModel); + + TStateNodeList *children = inState.GetChildren(); + if (children) { + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) + RecursiveInitializeDataModel(*iter); + } + } + + // Called during initialization for early binding of the datamodel + void RecursiveInitializeDataModel() + { + QT3DS_ASSERT(m_Context->GetRoot()); + QT3DS_ASSERT(m_Context->GetRoot()->m_Flags.IsLateBinding() == false); + RecursiveInitializeDataModel(*m_Context->GetRoot()); + } + + void MarkTransitionAsInvalid(STransition &inTransition, SStateNode &inParent, int inIndex) + { + if (inIndex >= 0) { + qCCritical(INVALID_OPERATION, "Detected invalid transition %s:%d", + inParent.m_Id.c_str(), inIndex); + } else { + const char *transitionType = "initial"; + if (inIndex == -1) + transitionType = "history"; + qCCritical(INVALID_OPERATION, "Detected invalid %s transition on node %s:%d", + transitionType, inParent.m_Id.c_str(), inIndex); + } + m_InvalidTransitions.insert(&inTransition); + } + + bool IsTransitionValid(STransition &inTransition) + { + return m_InvalidTransitions.find(&inTransition) == m_InvalidTransitions.end(); + } + + bool IsTransitionValid(STransition *inTransition) + { + if (inTransition) + return IsTransitionValid(*inTransition); + + // NULL transitions are of course, invalid. + return false; + } + + bool ValidateTransitionTargetList(STransition &inTransition, SStateNode &inParent, int inIndex) + { + for (QT3DSU32 idx = 0, end = inTransition.m_Target.size(); idx < end; ++idx) { + for (QT3DSU32 outerIdx = idx + 1; outerIdx < end; ++outerIdx) { + // We handle this case dynamically during transition activation + if (IsDescendant(*inTransition.m_Target[idx], *inTransition.m_Target[outerIdx]) + || IsDescendant(*inTransition.m_Target[outerIdx], *inTransition.m_Target[idx])) + continue; + + // If they aren't directly related they must be related indirectly via a parallel. + SStateNode *theLCA = + FindLCA(*inTransition.m_Target[idx], *inTransition.m_Target[outerIdx]); + if (theLCA && theLCA->m_Type != StateNodeTypes::Parallel) { + MarkTransitionAsInvalid(inTransition, inParent, inIndex); + return false; + } + } + } + return true; + } + + void ValidateInitialOrHistoryTransition(STransition *inTransition, SStateNode &inParent, + bool inIsInitial = false) + { + if (inTransition == NULL) + return; + int transIndex = inIsInitial ? -2 : -1; + if (inTransition->m_Target.size() == 0) { + MarkTransitionAsInvalid(*inTransition, inParent, transIndex); + } else { + ValidateTransitionTargetList(*inTransition, inParent, transIndex); + } + } + + void ValidateGeneralTransition(STransition &inTransition, SStateNode &inParent, int inIndex) + { + // Three distinct ways a transition could be invalid. + // 1. targetless, eventless and conditionless + if (inTransition.m_Target.size() == 0 && inTransition.m_Event.IsValid() == false + && isTrivial(inTransition.m_Condition)) + MarkTransitionAsInvalid(inTransition, inParent, inIndex); + else { + // Else eventless ,targetless, and points back to source state + if (inTransition.m_Target.size() == 1) { + if (inTransition.m_Target[0] == inTransition.m_Parent + && inTransition.m_Event.IsValid() == false + && isTrivial(inTransition.m_Condition)) { + MarkTransitionAsInvalid(inTransition, inParent, inIndex); + } + } else { + ValidateTransitionTargetList(inTransition, inParent, inIndex); + } + } + } + + void RecursiveValidateTransitions(SStateNode &inNode, SStateNode *inParent, int inIndex) + { + switch (inNode.m_Type) { + case StateNodeTypes::SCXML: + ValidateInitialOrHistoryTransition(inNode.GetInitialTransition(), inNode); + break; + case StateNodeTypes::State: + ValidateInitialOrHistoryTransition(inNode.GetInitialTransition(), inNode); + break; + case StateNodeTypes::Parallel: + ValidateInitialOrHistoryTransition(inNode.GetInitialTransition(), inNode); + break; + case StateNodeTypes::History: + ValidateInitialOrHistoryTransition(static_cast(inNode).m_Transition, inNode, + false); + break; + case StateNodeTypes::Transition: + if (inParent) + ValidateGeneralTransition(static_cast(inNode), *inParent, inIndex); + break; + default: // don't care + break; + } + RecursiveValidateTransitions(inNode, inNode.GetChildren()); + } + + void RecursiveValidateTransitions(SStateNode &inParent, TStateNodeList *inNodes) + { + if (inNodes) { + int idx = 0; + for (TStateNodeList::iterator iter = inNodes->begin(), end = inNodes->end(); + iter != end; ++iter, ++idx) + RecursiveValidateTransitions(*iter, &inParent, idx); + } + } + + // The state machine is pretty robust but there are is one category of input that can + // put the machine in a bad state. Transitions with either multiple targets or no target + // or a single target that points back to its owner may be bad depending on different criteria. + // For multiple targets, we invalidate a transition that puts us into a bad state. + // For no targets, in invalidate a transition that would cause the interpreter to loop + // infinitely + // For a single target, we invalidate a transition if it points back to its source but it has no + // condition + // or event. We don't attempt any more sophisticated analysis at this point although one could + // conceive of + // an analysis that could find loops depending on how long you wanted it to run. + void RecursiveValidateTransitions() + { + QT3DS_ASSERT(m_Context->GetRoot()); + RecursiveValidateTransitions(*m_Context->GetRoot(), NULL, 0); + } + + NVConstDataRef GetRefList(NVConstDataRef inIds) { return inIds; } + + // unsorted, may contain duplicates. + NVDataRef GetRefList(NVConstDataRef inIds) + { + m_IDRefList.clear(); + for (QT3DSU32 idx = 0, end = inIds.size(); idx < end; ++idx) { + SStateNode *theNode = m_Context->FindStateNode(inIds[idx]); + if (theNode != NULL) { + m_IDRefList.push_back(theNode); + } + } + return m_IDRefList; + } + + NVConstDataRef GetTargetStates(STransition *inTransition) + { + if (inTransition) + return inTransition->m_Target; + return NVDataRef(); + } + + static bool IsCompoundState(const SStateNode *inNode) + { + if (inNode == NULL) + return false; + return inNode->IsCompound(); + } + + static bool IsDescendant(SStateNode &inParent, SStateNode &inChild) + { + if (&inChild == &inParent) + return false; + + for (SStateNode *theNode = &inChild; theNode; theNode = theNode->m_Parent) + if (theNode == &inParent) + return true; + return false; + } + + static bool AllAreDescendants(SStateNode &inParent, NVConstDataRef inList) + { + for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) + if (IsDescendant(inParent, *inList[idx]) == false) + return false; + return true; + } + struct SRefListPlusOne + { + NVConstDataRef m_List; + SStateNode *m_Extra; + + SRefListPlusOne(NVConstDataRef l, SStateNode *e) + : m_List(l) + , m_Extra(e) + { + } + + QT3DSU32 size() { return m_List.size() + (m_Extra ? 1 : 0); } + + SStateNode *operator[](int idx) + { + if (idx < (int)m_List.size()) + return m_List[idx]; + if (idx == (int)m_List.size()) + return m_Extra; + QT3DS_ASSERT(false); + return NULL; + } + }; + + SStateNode *FindLCA(SStateNode &lhs, SStateNode &rhs) + { + QT3DSU32 sharedIdx = GetSharedParentState(lhs, rhs, false); + return *(m_ParentComparisonLHS.rbegin() + sharedIdx); + } + + SStateNode *FindLCCA(NVConstDataRef inList, SStateNode *inExtra = NULL) + { + SRefListPlusOne theList(inList, inExtra); + if (theList.size() == 0) + return NULL; + if (theList.size() == 1) { + for (SStateNode *item = theList[0]; item; item = item->m_Parent) { + if (item->IsCompound()) + return item; + } + } + SStateNode *lhs = theList[0]; + for (QT3DSU32 idx = 1, end = theList.size(); idx < end; ++idx) { + SStateNode *rhs = theList[idx]; + QT3DSU32 sharedIdx = GetSharedParentState(*lhs, *rhs, false); + lhs = *(m_ParentComparisonLHS.rbegin() + sharedIdx); + } + for (SStateNode *item = lhs; item; item = item->m_Parent) { + if (item->IsCompound()) + return item; + } + QT3DS_ASSERT(false); + return m_Context->GetRoot(); + } + NVDataRef GetProperAncestors(SStateNode &inChild, SStateNode *inStop) + { + m_AncestorsList.clear(); + for (SStateNode *parent = inChild.m_Parent; parent && parent != inStop; + parent = parent->m_Parent) + m_AncestorsList.push_back(parent); + return m_AncestorsList; + } + + bool AddStateToEnterToSet(SStateNode &inNode) + { + if (m_Configuration.contains(&inNode) == false) { + m_StatesToEnter.insert(&inNode); + return true; + } + return false; + } + + void AddStatesToEnter(SHistory &inState) + { + TStateNodeNodeList *history = GetHistoryData(inState); + if (history) { + for (TStateNodeNodeList::iterator iter = history->begin(), end = history->end(); + iter != end; ++iter) { + AddStatesToEnter(*iter->m_Node); + NVDataRef ancestors = + GetProperAncestors(*iter->m_Node, inState.m_Parent); + for (QT3DSU32 ancIdx = 0, ancEnd = ancestors.size(); ancIdx < ancEnd; ++ancIdx) + AddStateToEnterToSet(*ancestors[ancIdx]); + } + } else { + if (IsTransitionValid(inState.m_Transition)) { + NVConstDataRef theList = GetRefList(inState.m_Transition->m_Target); + for (QT3DSU32 idx = 0, end = theList.size(); idx < end; ++idx) { + AddStatesToEnter(*theList[idx]); + NVDataRef ancestors = + GetProperAncestors(*theList[idx], inState.m_Parent); + for (QT3DSU32 ancIdx = 0, ancEnd = ancestors.size(); ancIdx < ancEnd; ++ancIdx) + AddStateToEnterToSet(*ancestors[ancIdx]); + } + } else { + qCCritical(INVALID_OPERATION, + "History node %s with no history, no transition, or invalid transition visited", + inState.m_Id.c_str()); + SStateNode *theParent = inState.m_Parent; + if (theParent != NULL) { + if (theParent->m_Type != StateNodeTypes::Parallel) { + NVConstDataRef theDefaultInitial( + GetDefaultInitialState(*theParent)); + + QT3DS_ASSERT(theDefaultInitial.size() != 0); + for (QT3DSU32 idx = 0, end = theDefaultInitial.size(); idx < end; ++idx) + AddStatesToEnter(*theDefaultInitial[idx]); + + EnterAncestors(theDefaultInitial, theParent); + } else { + SParallel *pstate = theParent->CastTo(); + for (TStateNodeList::iterator iter = pstate->m_Children.begin(), + end = pstate->m_Children.end(); + iter != end; ++iter) { + if (StateNodeTypes::IsStateType(iter->m_Type)) + AddStatesToEnter(*iter); + } + } + } else { + QT3DS_ASSERT(false); // invalid configuration + } + } + } + } + NVConstDataRef GetDefaultInitialState(SStateNode &inState) + { + TStateNodeList *theChildren = inState.GetChildren(); + NVConstDataRef retval; + if (theChildren) { + for (TStateNodeList::iterator iter = theChildren->begin(), end = theChildren->end(); + iter != end && retval.size() == 0; ++iter) { + if (iter->m_Type == StateNodeTypes::State + || iter->m_Type == StateNodeTypes::Parallel + || iter->m_Type == StateNodeTypes::Final) { + SStateNode **newData = + reinterpret_cast(m_TemporaryAllocator.allocate( + sizeof(SStateNode *), "TempNode", __FILE__, __LINE__)); + newData[0] = &(*iter); + retval = toDataRef(newData, 1); + } + } + } + return retval; + } + + STransition *GetStateInitialTransition(SStateNode &inNode) + { + // Initialexpr, if it exists, takes precedence over the initial transition. + // they should not both exist but coding defensively, we have to take this into account. + eastl::pair::iterator, bool> inserter = + m_StateInitialTransitionMap.insert(eastl::make_pair(&inNode, (STransition *)NULL)); + if (inserter.second) { + const char8_t *initialExpr = inNode.GetInitialExpression(); + if (!isTrivial(initialExpr)) { + STransition *newTransition = &CreateTemporaryTransition(); + newTransition->m_Parent = &inNode; + inserter.first->second = newTransition; + SScriptExecutionResult exprResultData = + m_ScriptContext->ExecuteExpressionToString(initialExpr); + if (exprResultData.Valid()) { + const char8_t *exprResult(exprResultData.Result()); + // split this string into parts and extract ids. + m_IdSplitter.assign(nonNull(exprResult)); + const char8_t *whitespaceData = " \n\t\r"; + size_t charPos = m_IdSplitter.find_first_not_of(whitespaceData); + if (charPos == eastl::string::npos) { + m_IdSplitter.clear(); + m_Workspace.clear(); + } + if (charPos != 0) + m_IdSplitter.erase(m_IdSplitter.begin(), m_IdSplitter.begin() + charPos); + // Loop runs under assumption that idSplitter is empty or position 0 holds start + // of next id + while (m_IdSplitter.size()) { + // Trim to first character + eastl::string::size_type spacePos = + m_IdSplitter.find_first_of(whitespaceData); + + if (spacePos != eastl::string::npos) { + charPos = m_IdSplitter.find_first_not_of(whitespaceData, spacePos); + m_Workspace = m_IdSplitter.c_str(); + m_Workspace.resize(spacePos); + if (charPos != eastl::string::npos) + m_IdSplitter.erase(m_IdSplitter.begin(), + m_IdSplitter.begin() + charPos); + else + m_IdSplitter.clear(); + } else { + m_Workspace = m_IdSplitter; + m_IdSplitter.clear(); + } + + if (m_Workspace.empty() == false) { + CRegisteredString stateId = + m_StringTable->RegisterStr(m_Workspace.c_str()); + qt3ds::state::SStateNode *transitionNode = + m_Context->FindStateNode(stateId); + if (!transitionNode) { + m_TempNodeList.clear(); + m_IdSplitter.clear(); + qCCritical(INVALID_OPERATION, + "initialexpr=\"%s\" evaluated to \"%s\", but " + "this does not match the states in this " + "document. Using the default initial state " + "instead.", + nonNull(initialExpr), nonNull(exprResult)); + + eastl::string errorBuf; + IScriptEvent *newEvent = m_ScriptContext->CreateScriptEvent( + m_StringTable->RegisterStr("error.execution.initialexpr")); + newEvent->SetParamStr(m_StringTable->RegisterStr("expr"), + nonNull(initialExpr)); + errorBuf.assign(nonNull(exprResult)); + errorBuf.append(" does not match the states in this document."); + newEvent->SetParamStr(m_StringTable->RegisterStr("error"), + errorBuf.c_str()); + QueueEvent(*newEvent, false); + } else + m_TempNodeList.push_back(transitionNode); + } + } + if (m_TempNodeList.empty() == false) { + QT3DSU32 allocSize = sizeof(SStateNode *) * m_TempNodeList.size(); + SStateNode **nodeData = + reinterpret_cast(m_TemporaryAllocator.allocate( + allocSize, "TempNodes", __FILE__, __LINE__)); + memCopy(nodeData, m_TempNodeList.data(), allocSize); + newTransition->m_Target = toDataRef(nodeData, m_TempNodeList.size()); + m_TempNodeList.clear(); + } + if (newTransition->m_Target.size() != 0) { + bool isTransValid = ValidateTransitionTargetList(*newTransition, inNode, 0); + if (!isTransValid) { + m_InvalidTransitions.erase(newTransition); + // Reset the transition so that we get just the default initial state + // below + newTransition->m_Target = NVConstDataRef(); + // Create appropriate messages and events. + qCCritical(INVALID_OPERATION, + "initialexpr=\"%s\" evaluated to \"%s\", but this " + "results in an invalid transition. Using the " + "default initial state instead.", + nonNull(initialExpr), nonNull(exprResult)); + eastl::string errorBuf; + IScriptEvent *newEvent = m_ScriptContext->CreateScriptEvent( + m_StringTable->RegisterStr("error.execution.initialexpr")); + newEvent->SetParamStr(m_StringTable->RegisterStr("expr"), + nonNull(initialExpr)); + errorBuf.assign(nonNull(exprResult)); + errorBuf.append(" results in invalid transition."); + newEvent->SetParamStr(m_StringTable->RegisterStr("error"), + errorBuf.c_str()); + QueueEvent(*newEvent, false); + } + } + } // if script executed successfully + else { + const char8_t *runtimeError = exprResultData.Error(); + IScriptEvent *newEvent = m_ScriptContext->CreateScriptEvent( + m_StringTable->RegisterStr("error.execution.initialexpr")); + newEvent->SetParamStr(m_StringTable->RegisterStr("expr"), nonNull(initialExpr)); + newEvent->SetParamStr(m_StringTable->RegisterStr("error"), + nonNull(runtimeError)); + QueueEvent(*newEvent, false); + } + if (newTransition->m_Target.size() == 0) { + newTransition->m_Target = GetDefaultInitialState(inNode); + } + } + if (inserter.first->second == NULL) { + // Assume already validated + inserter.first->second = inNode.GetInitialTransition(); + } + } + return inserter.first->second; + } + + void AddStatesToEnter(SStateNode &inState) + { + if (inState.m_Type == StateNodeTypes::History) + AddStatesToEnter(*inState.CastTo()); + else { + AddStateToEnterToSet(inState); + if (inState.IsCompound()) { + m_StatesForDefaultEntry.insert(&inState); + NVConstDataRef targets; + STransition *initialTrans = GetStateInitialTransition(inState); + if (IsTransitionValid(initialTrans)) + targets = GetTargetStates(initialTrans); + + if (targets.size() == 0) + targets = GetDefaultInitialState(inState); + + QT3DS_ASSERT(targets.size() != 0); + for (QT3DSU32 idx = 0, end = targets.size(); idx < end; ++idx) + AddStatesToEnter(*targets[idx]); + + EnterAncestors(targets, &inState); + } else if (inState.m_Type == StateNodeTypes::Parallel) { + SParallel *pstate = inState.CastTo(); + for (TStateNodeList::iterator iter = pstate->m_Children.begin(), + end = pstate->m_Children.end(); + iter != end; ++iter) { + if (StateNodeTypes::IsStateType(iter->m_Type)) + AddStatesToEnter(*iter); + } + } + } + } + bool AllChildrenInFinalStates(SStateNode &inNode) + { + TStateNodeList *children = inNode.GetChildren(); + if (children) { + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) + if (!IsInFinalState(*iter)) + return false; + return true; + } + return true; + } + + void EraseState(nvvector &inList, SStateNode *inItem) + { + nvvector::iterator iter = eastl::find(inList.begin(), inList.end(), inItem); + if (iter != inList.end()) + inList.erase(iter); + } + + void ExitStates(NVDataRef inTransitions) + { + m_StatesToExit.clear(); + for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { + STransition &transition(*inTransitions[idx]); + if (transition.GetSource() == NULL) { + QT3DS_ASSERT(false); + continue; + } + NVConstDataRef theList = GetRefList(transition.m_Target); + SStateNode *ancestor = GetTransitionSubgraphRoot(transition, theList); + if (theList.size() && transition.GetSource()) { + for (QT3DSU32 idx = 0, end = m_Configuration.size(); idx < end; ++idx) + if (IsDescendant(*ancestor, *m_Configuration[idx])) + m_StatesToExit.insert(m_Configuration[idx]); + } + } + + /* + for s in m_StatesToExit: + statesToInvoke.delete(s) + */ + + SortByDocumentOrder(m_StatesToExit.m_List); + DEBUGGER_CALL1(SetExitSet, m_StatesToExit); + // Run through the list in reverse order. + for (nvvector::reverse_iterator iter = m_StatesToExit.m_List.rbegin(), + end = m_StatesToExit.m_List.rend(); + iter != end; ++iter) { +#ifdef QT3DS_LOG_ENTER_EXIT + qCInfo(TRACE_INFO, "Exiting state: %s", (*iter)->m_Id.c_str()); +#endif + TStateNodeList *children = (*iter)->GetChildren(); + if (children) { + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) { + if (iter->m_Type == StateNodeTypes::History) { + SHistory &theHistory = *iter->CastTo(); + FreeHistoryData(theHistory); + TStateNodeNodeList &theHistoryData = GetOrCreateHistoryData(theHistory); + + if (theHistory.m_Parent == NULL) { + QT3DS_ASSERT(false); + continue; + } + + // If deep, then record the leaves + if (theHistory.m_Flags.IsDeep()) { + for (TStateNodeSet::iterator configIter = m_Configuration.begin(), + configEnd = m_Configuration.end(); + configIter != configEnd; ++configIter) { + if ((*configIter)->IsAtomic() + && IsDescendant(*theHistory.m_Parent, **configIter)) + theHistoryData.push_back(*m_StateNodeNodePool.construct( + *configIter, __FILE__, __LINE__)); + } + } + // Else record what may be branches. + else { + for (TStateNodeSet::iterator configIter = m_Configuration.begin(), + configEnd = m_Configuration.end(); + configIter != configEnd; ++configIter) { + if ((*configIter)->m_Parent == theHistory.m_Parent) + theHistoryData.push_back(*m_StateNodeNodePool.construct( + *configIter, __FILE__, __LINE__)); + } + } + } + } + } + } + + for (nvvector::reverse_iterator iter = m_StatesToExit.m_List.rbegin(), + end = m_StatesToExit.m_List.rend(); + iter != end; ++iter) { + SStateNode *theState = *iter; + TOnExitList *theExitList = theState->GetOnExitList(); + if (theExitList) + m_ExecutionContext->Execute(*theState, *theExitList); + for (QT3DSU32 idx = 0, end = m_SignalSenders.size(); idx < end; ++idx) + m_SignalSenders[idx]->m_Handler.OnInterpreterEvent(InterpreterEventTypes::StateExit, + theState->m_Id); + EraseState(m_StatesToInvoke, theState); + m_Configuration.erase(theState); + } + } + + void EnterAncestor(SStateNode &inNode) + { + m_StatesToEnter.insert(&inNode); + if (inNode.m_Type == StateNodeTypes::Parallel) { + SParallel *anc = inNode.CastTo(); + for (TStateNodeList::iterator childIter = anc->m_Children.begin(), + endChild = anc->m_Children.end(); + childIter != endChild; ++childIter) { + if (!StateNodeTypes::IsStateType(childIter->m_Type)) + continue; + bool hasDescendent = false; + for (TStateNodeSet::iterator existingIter = m_StatesToEnter.begin(), + existingEnd = m_StatesToEnter.end(); + existingIter != existingEnd && hasDescendent == false; ++existingIter) { + hasDescendent = IsDescendant(*childIter, *(*existingIter)); + } + if (hasDescendent == false) + AddStatesToEnter(*childIter); + } + } + } + + void EnterAncestors(NVConstDataRef inList, SStateNode *ancestor) + { + for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) { + NVDataRef theAncestors = GetProperAncestors(*inList[idx], ancestor); + for (QT3DSU32 ancIdx = 0, ancEnd = theAncestors.size(); ancIdx < ancEnd; ++ancIdx) { + EnterAncestor(*theAncestors[ancIdx]); + // Break earlier if we have gone back and included the ancestor. + if (theAncestors[ancIdx] == ancestor) + break; + } + } + } + + void EnterStates(NVDataRef inTransitions) + { + m_StatesToEnter.clear(); + m_StatesForDefaultEntry.clear(); + + for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { + STransition &transition = *inTransitions[idx]; + NVConstDataRef theList = GetRefList(transition.m_Target); + if (transition.GetSource() == NULL) { + QT3DS_ASSERT(false); + continue; + } + + // Multi-target transitions present their own set of problems. One is that a perfectly + // valid + // multi-target transition may + if (theList.size() > 1) { + m_TransitionTargetList.clear(); + // We have to ensure that if two targets are directly related, we take the most + // derived one. + for (QT3DSU32 targetIdx = 0, targetEnd = theList.size(); targetIdx < targetEnd; + ++targetIdx) { + SStateNode *nextTarget = theList[targetIdx]; + for (QT3DSU32 takenTargetListIdx = 0, + takenTargetListEnd = m_TransitionTargetList.size(); + takenTargetListIdx < takenTargetListEnd && nextTarget; + ++takenTargetListIdx) { + SStateNode *previousTarget = m_TransitionTargetList[takenTargetListIdx]; + // If the previous target is more descendant than the original target + if (IsDescendant(*nextTarget, *previousTarget)) { + // Then we don't need to consider next target at all and we can + // continue. + nextTarget = NULL; + } else if (IsDescendant(*previousTarget, *nextTarget)) { + // If next target derives from previous target, then we remove previous + // target from + // the list. + m_TransitionTargetList.erase(m_TransitionTargetList.begin() + + takenTargetListIdx); + --takenTargetListIdx; + takenTargetListEnd = m_TransitionTargetList.size(); + } + // Else we don't care, we will add next target to the list. + } + if (nextTarget != NULL) + m_TransitionTargetList.push_back(nextTarget); + } + theList = m_TransitionTargetList; + } + + for (QT3DSU32 idx = 0, end = theList.size(); idx < end; ++idx) + AddStatesToEnter(*theList[idx]); + } + + for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { + STransition &transition = *inTransitions[idx]; + NVConstDataRef theList = GetRefList(transition.m_Target); + + if (transition.GetSource() == NULL) { + QT3DS_ASSERT(false); + continue; + } + + SStateNode *ancestor = GetTransitionSubgraphRoot(transition, theList); + EnterAncestors(theList, ancestor); + } + EnterStatesSecondHalf(); + } + + void EnterStatesSecondHalf() + { + nvvector &theEnterList(m_StatesToEnter.m_List); + SortByDocumentOrder(theEnterList); + + DEBUGGER_CALL1(SetEnterSet, m_StatesToEnter); + for (QT3DSU32 idx = 0, end = theEnterList.size(); idx < end; ++idx) { + SStateNode *theEnterState(theEnterList[idx]); +#ifdef QT3DS_LOG_ENTER_EXIT + qCInfo(TRACE_INFO, "Entering state: %s", theEnterState->m_Id.c_str()); +#endif + m_Configuration.insert(theEnterState); + m_StatesToInvoke.push_back(theEnterState); + SStateNodeInterpreterData &theData = GetOrCreateInterpreterData(*theEnterState); + if (theData.m_Entered == false) { + theData.m_Entered = true; + if (m_Context->GetRoot()->m_Flags.IsLateBinding()) { + SDataModel *theDataModel = theEnterState->GetDataModel(); + if (theDataModel) + RunDataModel(*theDataModel); + } + } + + TOnEntryList *theList = theEnterState->GetOnEntryList(); + if (theList) + m_ExecutionContext->Execute(*theEnterState, *theList); + for (QT3DSU32 idx = 0, end = m_SignalSenders.size(); idx < end; ++idx) + m_SignalSenders[idx]->m_Handler.OnInterpreterEvent( + InterpreterEventTypes::StateEnter, theEnterState->m_Id); + + if (m_StatesForDefaultEntry.contains(theEnterState)) { + SState *theState = theEnterState->CastTo(); + if (theState && IsTransitionValid(theState->m_Initial)) + m_ExecutionContext->Execute(*theState->m_Initial); + } + if (theEnterState->m_Type == StateNodeTypes::Final) { + SStateNode *parent = theEnterState->m_Parent; + SStateNode *grandparent = parent->m_Parent; + if (parent && grandparent) { + m_Workspace.assign("done.state."); + m_Workspace.append(parent->m_Id); + + // TODO - donedata + QueueEvent(m_Workspace.c_str(), false); + + if (grandparent && grandparent->m_Type == StateNodeTypes::Parallel + && AllChildrenInFinalStates(*grandparent)) { + m_Workspace.assign("done.state."); + m_Workspace.append(grandparent->m_Id); + QueueEvent(m_Workspace.c_str(), false); + } + } + } + } + + if (IsInFinalState(m_Context->GetRoot())) + m_Running = false; + SortConfiguration(); + } + + bool InConfiguration(SStateNode &inState) + { + return eastl::find(m_Configuration.begin(), m_Configuration.end(), &inState) + != m_Configuration.end(); + } + + bool IsInFinalState(SStateNode &inState) + { + if (inState.m_Type == StateNodeTypes::State && inState.IsCompound()) { + SState *theState = inState.CastTo(); + for (TStateNodeList::iterator childIter = theState->m_Children.begin(), + endIter = theState->m_Children.end(); + childIter != endIter; ++childIter) { + if (IsInFinalState(*childIter)) + return true; + } + } else if (inState.m_Type == StateNodeTypes::SCXML) { + SSCXML *theState = inState.CastTo(); + for (TStateNodeList::iterator childIter = theState->m_Children.begin(), + endIter = theState->m_Children.end(); + childIter != endIter; ++childIter) { + if (childIter->m_Type == StateNodeTypes::Final && InConfiguration(*childIter)) + return true; + } + } else if (inState.m_Type == StateNodeTypes::Parallel) { + SParallel *parallel = inState.CastTo(); + for (TStateNodeList::iterator childIter = parallel->m_Children.begin(), + endIter = parallel->m_Children.end(); + childIter != endIter; ++childIter) { + if (!IsInFinalState(*childIter)) + return false; + } + return true; + } else if (inState.m_Type == StateNodeTypes::Final && InConfiguration(inState)) + return true; + + return false; + } + + bool IsInFinalState(SStateNode *inState) + { + if (inState) + return IsInFinalState(*inState); + return false; + } + + SStateNode *GetTransitionSubgraphRoot(STransition &inTransition, + NVConstDataRef inTargetList) + { + SStateNodeInterpreterData &data = GetOrCreateInterpreterData(inTransition); + if (data.m_TransitionSubgraphRoot != NULL) + return data.m_TransitionSubgraphRoot; + if (inTransition.GetSource() == NULL) { + QT3DS_ASSERT(false); + return NULL; + } + SStateNode &source = *inTransition.GetSource(); + if (inTransition.m_Target.size() == 0) + data.m_TransitionSubgraphRoot = &source; + else { + if (inTransition.m_Flags.IsInternal() && source.IsCompound() + && AllAreDescendants(source, inTargetList)) + data.m_TransitionSubgraphRoot = &source; + else + data.m_TransitionSubgraphRoot = FindLCCA(inTargetList, &source); + } + + return data.m_TransitionSubgraphRoot; + } + SStateNode *GetTransitionSubgraphRoot(STransition &inTransition) + { + SStateNodeInterpreterData &data = GetOrCreateInterpreterData(inTransition); + if (data.m_TransitionSubgraphRoot != NULL) + return data.m_TransitionSubgraphRoot; + + return GetTransitionSubgraphRoot(inTransition, GetRefList(inTransition.m_Target)); + } + enum PreemptRule { AddNew, KeepExisting, ReplaceExisting }; + + PreemptRule IsPreempted(STransition &existing, STransition &nextTransition) + { + // Targetless transitions can get preempted and can preempt + SStateNode *existingRoot = GetTransitionSubgraphRoot(existing); + SStateNode *nextRoot = GetTransitionSubgraphRoot(nextTransition); + /* + http://www.w3.org/TR/scxml/#SelectingTransitions + + A transition T is optimally enabled by event E in atomic state S if + a) T is enabled by E in S and + b) no transition that precedes T in document order in T's source state is enabled by E in S + and + c) no transition is enabled by E in S in any descendant of T's source state. + */ + + // static bool IsDescendant( SStateNode& inParent, SStateNode& inChild ) + + if (IsDescendant(*nextRoot, *existingRoot)) + return KeepExisting; + if (IsDescendant(*existingRoot, *nextRoot)) + return ReplaceExisting; + + // Else these transactions are completely unrelated + return AddNew; + } + + void FilterPreempted(TTransitionSet &inTransitionSet, TTransitionList &outTransitions) + { + outTransitions.clear(); + for (TTransitionSet::iterator iter = inTransitionSet.begin(), end = inTransitionSet.end(); + iter != end; ++iter) { + PreemptRule preempted = AddNew; + QT3DSU32 idx, endIdx; + for (idx = 0, endIdx = outTransitions.size(); idx < endIdx && preempted == AddNew; + ++idx) + preempted = IsPreempted(*outTransitions[idx], **iter); + + switch (preempted) { + case KeepExisting: // Ignore the result. + break; + case ReplaceExisting: + // The iteration statement is evaluated before the exit test. + outTransitions[idx - 1] = *iter; + break; + case AddNew: + outTransitions.push_back(*iter); + break; + } + } + } + + bool SelectEventlessTransitions(SStateNode &inNode, TTransitionSet &inSet) + { + TStateNodeList *theChildren = inNode.GetChildren(); + if (theChildren == NULL) { + return false; + } + for (TStateNodeList::iterator iter = theChildren->begin(), end = theChildren->end(); + iter != end; ++iter) { + if (iter->m_Type == StateNodeTypes::Transition) { + STransition &trans = *iter->CastTo(); + if (IsTransitionValid(&trans)) { + if (trans.m_Event.IsValid() == false) { + if (!isTrivial(trans.m_Condition)) { + Option condEval = + m_ScriptContext->ExecuteCondition(trans.m_Condition); + if (condEval.hasValue()) { + if (*condEval) { + inSet.insert(&trans); + return true; + } + } else { + QueueEvent("error.execution", false); + return false; + } + } + // Extension for running scxml documents with transitions with nothing but + // content + else { + inSet.insert(&trans); + return true; + } + } + } + } + } + if (inNode.m_Parent) + SelectEventlessTransitions(*inNode.m_Parent, inSet); + return false; + } + + // Precondition - m_Configuration is in document order. + // Postcondition - m_EnabledTransitions contains only the transitions selected + void SelectEventlessTransitions() + { + m_TransitionSet.clear(); + static QT3DSU32 callCount = 0; + ++callCount; + for (QT3DSU32 idx = 0, end = m_Configuration.size(); idx < end; ++idx) { + if (idx) { + QT3DS_ASSERT(GetOrCreateInterpreterData(*m_Configuration[idx]).m_DocumentOrder + > GetOrCreateInterpreterData(*m_Configuration[idx - 1]).m_DocumentOrder); + } + if (m_Configuration[idx]->IsAtomic() == false) + continue; + SelectEventlessTransitions(*m_Configuration[idx], m_TransitionSet); + } + m_EnabledTransitions.clear(); + FilterPreempted(m_TransitionSet, m_EnabledTransitions); + } + void SelectTransition(SStateNode &inNode, IEvent &inEvent, TTransitionSet &outTransitions) + { + TStateNodeList *theChildren = inNode.GetChildren(); + if (theChildren) { + for (TStateNodeList::iterator iter = theChildren->begin(), end = theChildren->end(); + iter != end; ++iter) { + if (iter->m_Type == StateNodeTypes::Transition) { + STransition &theTransition = *iter->CastTo(); + if (IsTransitionValid(theTransition)) { + if (theTransition.m_Event.IsValid()) { + if (qt3ds::state::impl::NameMatches(theTransition.m_Event.c_str(), + inEvent.GetName().c_str())) { + if (!isTrivial(theTransition.m_Condition)) { + Option condResult = m_ScriptContext->ExecuteCondition( + theTransition.m_Condition); + if (condResult.hasValue()) { + if (*condResult) { + outTransitions.insert(&theTransition); + return; + } + } else { + QueueEvent("error.execution", false); + return; + } + } else { + outTransitions.insert(&theTransition); + return; + } + } + } + } + } + } + } + if (inNode.m_Parent) + SelectTransition(*inNode.m_Parent, inEvent, outTransitions); + } + + // Precondition is that m_Configuration is in document order. + void SelectTransitions(IEvent &inEvent) + { + m_TransitionSet.clear(); + for (QT3DSU32 idx = 0, end = m_Configuration.size(); idx < end; ++idx) { + // Ensure that m_Configuration is in document order. + if (idx) { + QT3DS_ASSERT(GetOrCreateInterpreterData(*m_Configuration[idx]).m_DocumentOrder + > GetOrCreateInterpreterData(*m_Configuration[idx - 1]).m_DocumentOrder); + } + + if (!m_Configuration[idx]->IsAtomic()) + continue; + SelectTransition(*m_Configuration[idx], inEvent, m_TransitionSet); + } + + FilterPreempted(m_TransitionSet, m_EnabledTransitions); + } + + bool Initialize(IStateContext &inContext, bool inValidateTransitions) override + { + m_Initialized = false; + InitializeDataStructures(); + m_Context = inContext; + QT3DS_ASSERT(m_Context->GetRoot()); + if (m_Context->GetRoot() == NULL) { + QT3DS_ASSERT(false); + m_Running = false; + return false; + } + + // Disable transitions that can put us into a bad state + if (inValidateTransitions) + RecursiveValidateTransitions(); + m_Initialized = true; + return true; + } + NVConstDataRef Start() override + { + if (!m_Initialized) { + QT3DS_ASSERT(false); + return NVConstDataRef(); + } + m_Running = true; + SSCXML &rootState = *m_Context->GetRoot(); + if (!rootState.m_Flags.IsLateBinding()) + RecursiveInitializeDataModel(); + eastl::string theSendLocExpr; + NVConstDataRef theSendData = m_Context->GetSendList(); + for (QT3DSU32 idx = 0, end = theSendData.size(); idx < end; ++idx) { + SSend &theSend(*theSendData[idx]); + if (!isTrivial(theSend.m_IdLocation)) { + QT3DS_ASSERT(theSend.m_Id.IsValid()); + m_ScriptContext->AssignStr(theSend.m_IdLocation, theSend.m_Id.c_str()); + } + } + + STransition *initialTrans = this->GetStateInitialTransition(rootState); + if (IsTransitionValid(initialTrans)) { + m_Configuration.insert(&rootState); + m_ExecutionContext->Execute(*initialTrans); + AddStatesToEnter(rootState); + EnterAncestors(initialTrans->m_Target, &rootState); + QT3DS_ASSERT(m_EnabledTransitions.empty()); + m_EnabledTransitions.clear(); + m_EnabledTransitions.push_back(initialTrans); + DEBUGGER_CALL1(SetTransitionSet, m_EnabledTransitions); + m_EnabledTransitions.clear(); + EnterStatesSecondHalf(); + ReleaseInitialAndTemporaryTransitions(); + DEBUGGER_CALL(EndMicrostep); + DEBUGGER_CALL(EndStep); + } else { + m_Running = false; + qFatal("Invalid state machine: root initial configuration is invalid"); + } + return m_Configuration.m_List; + } + + void Microstep(TTransitionList &inTransitions) + { + DEBUGGER_CALL1(SetTransitionSet, inTransitions); + ExitStates(inTransitions); + for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) { + m_ExecutionContext->Execute(*inTransitions[idx]); + for (QT3DSU32 sigIdx = 0, sigEnd = m_SignalSenders.size(); sigIdx < sigEnd; ++sigIdx) + m_SignalSenders[sigIdx]->m_Handler.OnInterpreterEvent( + InterpreterEventTypes::Transition, inTransitions[idx]->m_Id); + } + + EnterStates(inTransitions); + // Allow them to be selected again at some point. + inTransitions.clear(); + ReleaseInitialAndTemporaryTransitions(); + DEBUGGER_CALL(EndMicrostep); + } + + void CheckForDelayedEvents() + { + QT3DSU64 currentTime = Time::getCurrentTimeInTensOfNanoSeconds(); + TFutureEventList::iterator removeIter = m_FutureEvents.begin(); + TFutureEventList::iterator endIter = m_FutureEvents.end(); + // Future events list is sorted so all we have to do is iterate forward until + // fire time is greater than current time. + + for (; removeIter != endIter && removeIter->m_FireTime < currentTime; ++removeIter) { + } + // remove iter points either to the end or to the first event who's time has come. + for (TFutureEventList::iterator evtIter = m_FutureEvents.begin(); evtIter != removeIter; + ++evtIter) { + qCInfo(TRACE_INFO, "Sending delayed event: %s", evtIter->m_Event->GetName().c_str()); + QT3DS_ASSERT(evtIter->m_FireTime <= currentTime); + QueueEvent(evtIter->m_Event, evtIter->m_IsExternal); + } + if (removeIter != m_FutureEvents.begin()) { + m_FutureEvents.erase(m_FutureEvents.begin(), removeIter); + } + } + + bool CheckForStable() + { + CheckForDelayedEvents(); + if (m_EnabledTransitions.empty()) { + m_ScriptContext->ClearCurrentEvent(); + DEBUGGER_CALL(BeginMicrostep); + SelectEventlessTransitions(); + } + + return m_EnabledTransitions.empty() && m_InternalQueue.empty() && m_ExternalQueue.empty(); + } + + // Execute these events, return what state you are in. + // We process all internal and all external events before returning, so you are free to + // free or just deal with all userdata after this. + NVConstDataRef Execute() override + { + if (m_Running == false) + return m_Configuration.m_List; + + DEBUGGER_CALL(BeginStep); + DEBUGGER_CALL(BeginMicrostep); + + m_EnabledTransitions.clear(); + + QT3DSU32 iterationCount = 0; + QT3DSU32 MAX_ITERATION_COUNT = 1000; + + // Here we handle eventless transitions and transitions + // triggered by internal events until machine is stable + while (iterationCount < MAX_ITERATION_COUNT && m_Running && !CheckForStable()) { + ++iterationCount; + if (m_EnabledTransitions.empty() == false) { + Microstep(m_EnabledTransitions); + DEBUGGER_CALL(BeginMicrostep); + } else if (m_InternalQueue.empty() == false) { + NVScopedRefCounted theEvent = m_InternalQueue.front(); + m_ScriptContext->SetCurrentEvent(theEvent); + m_InternalQueue.pop_front(); + DEBUGGER_CALL2(SetCurrentEvent, theEvent->GetName().c_str(), true); +#ifdef QT3DS_LOG_ACTIVE_EVENT + qCInfo(TRACE_INFO, "Current event: %s", theEvent->GetName().c_str()); +#endif + SelectTransitions(*theEvent); + } else if (m_ExternalQueue.empty() == false) { + NVScopedRefCounted theEvent = m_ExternalQueue.front(); + m_ScriptContext->SetCurrentEvent(theEvent); + m_ExternalQueue.pop_front(); + + DEBUGGER_CALL2(SetCurrentEvent, theEvent->GetName().c_str(), false); + +#ifdef QT3DS_LOG_ACTIVE_EVENT + qCInfo(TRACE_INFO, "Current event: %s", theEvent->GetName().c_str()); +#endif + + /* + if isCancelEvent(externalEvent) + running = false + continue + */ + + // TODO datamodel + // datamodel["_event"] = theEvent; + + // TODO invoke + /* + for state in configuration: + for inv in state.invoke: + if inv.invokeid == externalEvent.invokeid: + applyFinalize(inv, externalEvent) + if inv.autoforward: + send(inv.id, externalEvent) + */ + SelectTransitions(*theEvent); + } + } + if (m_Running == false) { + for (nvvector::reverse_iterator iter = m_Configuration.m_List.rbegin(), + end = m_Configuration.m_List.rend(); + iter != end; ++iter) { + TOnExitList *theExitList = (*iter)->GetOnExitList(); + if (theExitList) + m_ExecutionContext->Execute(**iter, *theExitList); + /* + for inv in s.invoke: + cancelInvoke(inv) + */ + + // Set final done data. + /* + if isFinalState(s) and isScxmlState(s.parent): + returnDoneEvent(s.donedata) + */ + } + } + DEBUGGER_CALL(EndStep); + return m_Configuration.m_List; + } + + bool EventsPending() const override + { + return m_InternalQueue.empty() == false || m_ExternalQueue.empty() == false + || m_FutureEvents.empty() == false; + } + + bool IsRunning() const override { return m_Running; } + + void QueueEvent(const char8_t *inEventName, QT3DSU64 inDelay, CRegisteredString inCancelId, + bool inIsExternal) override + { + TEventPtr theEvent = QT3DS_NEW(m_Foundation.getAllocator(), SSimpleEvent)( + m_Foundation.getAllocator(), m_StringTable->RegisterStr(inEventName)); + QueueEvent(theEvent, inDelay, inCancelId, inIsExternal); + } + + void QueueEvent(TEventPtr inEvent, QT3DSU64 inDelay, CRegisteredString inCancelId, + bool inIsExternal) override + { + if (inDelay == 0) { + QueueEvent(inEvent, inIsExternal); + } else { + static QT3DSU64 sTensOfNanoSecondsInAMillisecond = + Time::sNumTensOfNanoSecondsInASecond / 1000; + QT3DSU64 fireTime = Time::getCurrentTimeInTensOfNanoSeconds() + + inDelay * sTensOfNanoSecondsInAMillisecond; + SFutureEvent theNewEvent(inEvent, fireTime, inCancelId, inIsExternal); + TFutureEventList::iterator iter = + eastl::upper_bound(m_FutureEvents.begin(), m_FutureEvents.end(), theNewEvent); + m_FutureEvents.insert(iter, theNewEvent); + } + } + + void QueueEvent(TEventPtr inEvent, bool inIsExternal) override + { + if (inIsExternal) + m_ExternalQueue.push_back(inEvent); + else + m_InternalQueue.push_back(inEvent); + DEBUGGER_CALL2(EventQueued, inEvent->GetName().c_str(), inIsExternal); + } + + void QueueEvent(const char8_t *inEventName, bool inIsExternal) override + { + TEventPtr theEvent = QT3DS_NEW(m_Foundation.getAllocator(), SSimpleEvent)( + m_Foundation.getAllocator(), m_StringTable->RegisterStr(inEventName)); + QueueEvent(theEvent, inIsExternal); + } + + void CancelEvent(CRegisteredString inCancelId) override + { + if (inCancelId.IsValid() == false) + return; + qCInfo(TRACE_INFO, "Cancel of id %s requested", inCancelId.c_str()); + for (QT3DSU32 idx = 0; idx < m_FutureEvents.size(); ++idx) { + if (m_FutureEvents[idx].m_CancelId == inCancelId) { + TFutureEventList::iterator iter = m_FutureEvents.begin() + idx; + qCInfo(TRACE_INFO, "Cancelling event: %s, %s", + iter->m_Event->GetName().c_str(), iter->m_CancelId.c_str()); + m_FutureEvents.erase(iter); + --idx; + } + } + } + + TSignalConnectionPtr RegisterEventHandler(IStateInterpreterEventHandler &inHandler) override + { + SStateSignalSender *sender = QT3DS_NEW(m_Foundation.getAllocator(), SStateSignalSender)( + m_Foundation.getAllocator(), *this, inHandler); + m_SignalSenders.push_back(sender); + return sender; + } + + IScriptContext &GetScriptContext() override { return *m_ScriptContext; } + + IStateContext *GetStateContext() override { return m_Context; } + + debugger::IStateMachineDebugInterface &GetDebugInterface() override { return m_DebugInterface; } + + NVFoundationBase &GetFoundation() override { return m_Foundation; } +}; + +//////////////////////////////////////////////////////////////////////////////////// +// SDebugInterface implementation +//////////////////////////////////////////////////////////////////////////////////// + +void SDebugInterface::addRef() +{ + m_StateSystem.addRef(); +} + +void SDebugInterface::release() +{ + m_StateSystem.release(); +} + +struct SDebugStrOutStream : public IOutStream +{ + TDebugStr m_Str; + bool Write(NVConstDataRef data) override + { + m_Str.append((char8_t *)data.begin(), (char8_t *)data.end()); + return true; + } +}; + +NVConstDataRef ListToRef(const nvvector &inList, TDebugStrList &outData) +{ + outData.resize(inList.size()); + for (QT3DSU32 idx = 0, end = inList.size(); idx < end; ++idx) + outData[idx].assign(nonNull(inList[idx]->m_Id.c_str())); + return toConstDataRef(outData.data(), outData.size()); +} + +IScriptContext &SDebugInterface::GetScriptContext() +{ + return *m_StateSystem.m_ScriptContext.mPtr; +} + +// Functions implemented after StateSystem in order to take advantage of the StateSystem struct +// members directly. +void SDebugInterface::OnConnect() +{ + TDebugStr theFilename; + SDebugStrOutStream theOutStream; + if (m_StateSystem.m_Context->GetRoot()) + theFilename.assign(nonNull(m_StateSystem.m_Context->GetRoot()->m_Filename)); + CXMLIO::SaveSCXMLFile(*m_StateSystem.m_Context, m_StateSystem.m_Foundation, + *m_StateSystem.m_StringTable, theOutStream); + m_Listener->OnConnect(theFilename, theOutStream.m_Str, + ListToRef(m_StateSystem.m_Configuration.m_List, m_EnterList)); +} + +// Functions should not be called in there is not a valid listener +void SDebugInterface::BeginStep() +{ + m_Listener->BeginStep(); +} + +void SDebugInterface::BeginMicrostep() +{ + m_Listener->BeginMicroStep(); +} + +void SDebugInterface::SetCurrentEvent(const char8_t *inEventName, bool inInternal) +{ + m_TempStr.assign(nonNull(inEventName)); + m_Listener->SetEvent(m_TempStr, inInternal); +} + +STransitionId TransitionToId(const STransition &inTransition) +{ + SStateNode *parent(inTransition.m_Parent); + STransitionId retval; + if (parent == NULL) { + QT3DS_ASSERT(false); + return retval; + } + + retval.m_StateId.assign(nonNull(parent->m_Id.c_str())); + if (&inTransition == parent->GetInitialTransition()) + retval.m_TransitionIndex = -1; + else if (parent->m_Type == StateNodeTypes::History) { + SHistory &theHistory = static_cast(*parent); + if (&inTransition == theHistory.m_Transition) + retval.m_TransitionIndex = -1; + } + + if (retval.m_TransitionIndex == -2) { + TStateNodeList *childList = parent->GetChildren(); + if (childList) { + QT3DSI32 index = 0; + for (TStateNodeList::iterator iter = childList->begin(), end = childList->end(); + iter != end && retval.m_TransitionIndex == -2; ++iter, ++index) { + SStateNode &theNode(*iter); + if (theNode.m_Type == StateNodeTypes::Transition && &inTransition == (&theNode)) + retval.m_TransitionIndex = index; + } + } + } + + return retval; +} + +void SDebugInterface::SetTransitionSet(const TTransitionList &inTransitions) +{ + m_TransitionList.resize(inTransitions.size()); + for (QT3DSU32 idx = 0, end = inTransitions.size(); idx < end; ++idx) + m_TransitionList[idx] = TransitionToId(*inTransitions[idx]); + m_Listener->SetTransitionSet(toDataRef(m_TransitionList.data(), m_TransitionList.size())); +} + +void SDebugInterface::SetExitSet(const TStateNodeSet &inSet) +{ + NVConstDataRef theSet(ListToRef(inSet.m_List, this->m_ExitList)); + m_Listener->SetExitSet(theSet); +} +void SDebugInterface::SetEnterSet(const TStateNodeSet &inSet) +{ + NVConstDataRef theSet(ListToRef(inSet.m_List, this->m_EnterList)); + m_Listener->SetEnterSet(theSet); +} +// Log statements run through the debugger as well. +void SDebugInterface::EndMicrostep() +{ + m_Listener->EndMicroStep(); +} +void SDebugInterface::EndStep() +{ + m_Listener->EndStep(); +} + +void SDebugInterface::OnExternalBreak() +{ + if (m_Listener) + m_Listener->OnExternalBreak(); +} + +SStateSignalSender::~SStateSignalSender() +{ + if (m_System) { + m_System->m_SignalSenders.erase( + eastl::find(m_System->m_SignalSenders.begin(), m_System->m_SignalSenders.end(), this)); + } +} +} + +IStateInterpreter &IStateInterpreter::Create(NVFoundationBase &inFnd, IStringTable &inStrTable, + IScriptContext &inScriptContext, + IExecutionContext &inExecutionContext) +{ + return *QT3DS_NEW(inFnd.getAllocator(), StateSystem)(inFnd, inStrTable, inScriptContext, + inExecutionContext); +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.h b/src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.h new file mode 100644 index 00000000..d615d21f --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateInterpreter.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_INTERPRETER_H +#define QT3DS_STATE_INTERPRETER_H +#pragma once +#include "Qt3DSState.h" +#include "Qt3DSStateTypes.h" +#include "Qt3DSStateSignalConnection.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace state { + struct InterpreterEventTypes + { + enum Enum { + UnknownInterpreterEvent = 0, + StateEnter, + StateExit, + Transition, + }; + }; + + struct IStateInterpreterEventHandler + { + protected: + virtual ~IStateInterpreterEventHandler() {} + + public: + virtual void OnInterpreterEvent(InterpreterEventTypes::Enum inEvent, + CRegisteredString inEventId) = 0; + }; + + class IStateInterpreter : public NVRefCounted + { + protected: + virtual ~IStateInterpreter() {} + public: + // Setup of the state system, you can add a set of roots to the state graph. + virtual NVConstDataRef GetConfiguration() = 0; + // State context is referenced by this object. + // We can optionally validate the transitions to ensure that no transition can put us into + // an invalid state + // and so that simple loops don't exist. It is highly recommended to use this; it is done + // once via startup and + // shouldn't add appreciably to the initialization time but it makes the transition system a + // lot more robust. + virtual bool Initialize(IStateContext &inContext, bool inValidateTransitions = true) = 0; + // Bring the state machine to the internal state. + // Returns the list of states for the initial configuration + virtual NVConstDataRef Start() = 0; + + // Execute transitions, internal events and external events until nothing is left to + // be done. + virtual NVConstDataRef Execute() = 0; + + virtual bool IsRunning() const = 0; + virtual bool EventsPending() const = 0; + + // Queue an event with an optional delay (0 means no delay). + // If the event has a delay then it can optionally be cancelled. + virtual void QueueEvent(const char8_t *inEventName, QT3DSU64 inDelay, + CRegisteredString inCancelId, bool inIsExternal = true) = 0; + virtual void QueueEvent(TEventPtr inEvent, QT3DSU64 inDelay, CRegisteredString inCancelId, + bool inIsExternal = true) = 0; + virtual void QueueEvent(TEventPtr inEvent, bool inIsExternal = true) = 0; + virtual void QueueEvent(const char8_t *inEventName, bool inIsExternal = true) = 0; + + // Cancel an event with a particular id. Only cancels delayed events that have not fired + // yet. + virtual void CancelEvent(CRegisteredString inCancelId) = 0; + + // When the connection gets destroyed, the hander will get no more events. + virtual TSignalConnectionPtr + RegisterEventHandler(IStateInterpreterEventHandler &inHandler) = 0; + + virtual debugger::IStateMachineDebugInterface &GetDebugInterface() = 0; + + virtual NVFoundationBase &GetFoundation() = 0; + + virtual IScriptContext &GetScriptContext() = 0; + + virtual IStateContext *GetStateContext() = 0; + + // The only code that needs to happen in the state system is the code that executes a + // condition. + static IStateInterpreter &Create(NVFoundationBase &inFnd, IStringTable &inStrTable, + IScriptContext &inScriptContext, + IExecutionContext &inExecutionContext); + }; +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateScriptContext.h b/src/Runtime/Source/stateapplication/Qt3DSStateScriptContext.h new file mode 100644 index 00000000..110770a1 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateScriptContext.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_SCRIPT_CONTEXT_H +#define QT3DS_STATE_SCRIPT_CONTEXT_H +#pragma once +#include "Qt3DSState.h" +#include "Qt3DSStateTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace state { + + class IScriptEvent : public IEvent + { + public: + // returns true on success, false if error.execution should be signaled. + virtual bool SetParam(CRegisteredString inName, const char8_t *inExpression) = 0; + // Sets the expression as a string + virtual bool SetParamStr(CRegisteredString inName, const char8_t *inStr) = 0; + virtual bool SetDataExpr(const char8_t *inExpression) = 0; + virtual bool SetDataStr(const char8_t *inStr) = 0; + }; + + struct SScriptExecutionResult + { + const char8_t *m_Result; + const char8_t *m_Error; + SScriptExecutionResult(const char8_t *inData, const char8_t *inError) + : m_Result(inData) + , m_Error(inError) + { + } + SScriptExecutionResult() + : m_Result("") + , m_Error("") + { + } + bool Valid() const { return m_Error == NULL || *m_Error == 0; } + const char8_t *Result() const + { + QT3DS_ASSERT(Valid()); + return m_Result; + } + const char8_t *Error() const + { + QT3DS_ASSERT(!Valid()); + return m_Error; + } + }; + + class IScriptContext : public NVRefCounted + { + protected: + virtual ~IScriptContext() {} + public: + // Should functions returning options return othing + virtual Option ExecuteCondition(const char8_t *inCond) = 0; + // Used for logging. + // Error and result are good until next call into the script context. + virtual SScriptExecutionResult ExecuteExpressionToString(const char8_t *inExpr) = 0; + + // If return value is false, error is signaled with GetErrorInfo. + virtual bool Assign(const char8_t *inVariable, const char8_t *inExpr) = 0; + // Assign a string to this variable location. + virtual void AssignStr(const char8_t *inVariable, const char8_t *inStr) = 0; + + // If return value is false, error is signaled via GetErrorInfo. + // The actual pointer and content used for inscript is expected to not change during + // execution of the system. + // it is legal for contexts to cache information based off the script pointer value. + virtual bool ExecuteScript(const char8_t *inScript) = 0; + // Always return 1 result + virtual int ExecuteStr(const char8_t *inScript, bool withRet) = 0; + + // Return true on success, false on failure, and Empty on error. + virtual Option BeginForeach(const char8_t *inArray, const char8_t *inItem, + const char8_t *inIdxVar = "") = 0; + virtual Option NextForeach(const char8_t *inItem, const char8_t *inIdxVar = "") = 0; + virtual void CancelForeach() = 0; + + virtual void SetCurrentEvent(TEventPtr inEvent) = 0; + virtual void ClearCurrentEvent() = 0; + // Create an event we can attach extra data do. + virtual IScriptEvent *CreateScriptEvent(CRegisteredString inName) = 0; + + virtual const char8_t *GetErrorInfo() = 0; + + virtual void SetInterpreter(IStateInterpreter &inInterpreter) = 0; + + virtual CRegisteredString GetContextType() { return CRegisteredString(); } + + // Dumps a differential state from the last time someone asked. This is a debug interface; + // not meant to be used + // by multiple listeners concurrently. + virtual void DumpState(debugger::IScriptStateListener &inListener) = 0; + }; +} +} +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateSharedImpl.h b/src/Runtime/Source/stateapplication/Qt3DSStateSharedImpl.h new file mode 100644 index 00000000..0b82cc3c --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateSharedImpl.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_SHARED_IMPL_H +#define QT3DS_STATE_SHARED_IMPL_H +#include "Qt3DSState.h" +#include "foundation/Utils.h" + +namespace qt3ds { +namespace state { + namespace impl { + + inline bool NameMatchesInternal(const char8_t *inTransEvent, QT3DSU32 transLen, + const char8_t *inEventName, QT3DSU32 eventLen) + { + QT3DSU32 idx, end; + // Empty loop intentional to find first nonmatching character + for (idx = 0, end = NVMin(transLen, eventLen); + idx < end && inTransEvent[idx] == inEventName[idx]; ++idx) { + } + // Note that in this case we point to the first nonmatching character which may be off + // the end of either + // eventStr or transStr + bool match = false; + if (idx == transLen) { + if (idx == eventLen) + match = true; + else if (inEventName[idx] == '.') + match = true; + else if (inTransEvent[idx - 1] == '.') + match = true; + } else if (idx == eventLen) { + if ((transLen - idx) == 1) + match = inTransEvent[idx] == '*' || inTransEvent[idx] == '.'; + + else if ((transLen - idx) == 2) + match = inTransEvent[idx] == '.' && inTransEvent[idx + 1] == '*'; + } else { + if (inTransEvent[idx] == '*') + match = true; + } + return match; + } + + inline const char8_t *FindNextNonSpace(const char8_t *inPtr) + { + for (; *inPtr == ' '; ++inPtr) { + } + return inPtr; + } + + inline const char8_t *FindNextSpaceOrNull(const char8_t *inPtr) + { + for (; *inPtr && *inPtr != ' '; ++inPtr) { + } + return inPtr; + } + + inline bool NameMatches(const char8_t *inTransEvent, const char8_t *inEventName) + { + inTransEvent = nonNull(inTransEvent); + inEventName = nonNull(inEventName); + + QT3DSU32 transLen = StrLen(inTransEvent); + + QT3DSU32 eventLen = StrLen(inEventName); + if (transLen == 0) { + QT3DS_ASSERT(false); + return false; + } + if (eventLen == 0) { + QT3DS_ASSERT(false); + return false; + } + + for (inTransEvent = FindNextNonSpace(inTransEvent); inTransEvent && *inTransEvent; + inTransEvent = FindNextNonSpace(inTransEvent)) { + const char8_t *end = FindNextSpaceOrNull(inTransEvent); + QT3DSU32 len = (QT3DSU32)(end - inTransEvent); + + if (len && NameMatchesInternal(inTransEvent, len, inEventName, eventLen)) + return true; + inTransEvent = end; + } + + return false; + } + } +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateSignalConnection.h b/src/Runtime/Source/stateapplication/Qt3DSStateSignalConnection.h new file mode 100644 index 00000000..5bfa59ad --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateSignalConnection.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_SIGNAL_CONNECTION_H +#define QT3DS_STATE_SIGNAL_CONNECTION_H +#pragma once +#include "Qt3DSState.h" +#include "foundation/Qt3DSRefCounted.h" +namespace qt3ds { +namespace state { + + class IStateSignalConnection : public NVRefCounted + { + protected: + virtual ~IStateSignalConnection() {} + public: + }; + + typedef NVScopedRefCounted TSignalConnectionPtr; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateTypes.h b/src/Runtime/Source/stateapplication/Qt3DSStateTypes.h new file mode 100644 index 00000000..41e759fb --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateTypes.h @@ -0,0 +1,720 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_STATE_TYPES_H +#define QT3DS_STATE_TYPES_H +#include "Qt3DSState.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/StringTable.h" +#include "foundation/TaggedPointer.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "Qt3DSStateIdValue.h" + +namespace qt3ds { +namespace state { + + // Link list definitions. + DEFINE_INVASIVE_LIST(StateNode); + DEFINE_INVASIVE_SINGLE_LIST(OnEntry); + DEFINE_INVASIVE_SINGLE_LIST(OnExit); + DEFINE_INVASIVE_SINGLE_LIST(DataModel); + DEFINE_INVASIVE_LIST(Invoke); + + // Externally defined objects - These objects are defined by the implementation of the + // interpreter and the execution context. They are not used and cannot be manipulated by + // core state types. + + // Standard content defined in another file so as to not clutter up the core state definitions. + struct SExecutableContent; + DEFINE_INVASIVE_LIST(ExecutableContent); + struct SScript; + struct SDataModel; + + // Defined by the execution context; These objects can be defined by the implementation of the + // scripting + // system. + struct STransitionCondition; + + // Defined by the interpreter. Really just a placeholder so the interpreter can cache + // item-specific data on an object. + struct SInterpreterData; + + // We *have* to keep some subset of the data in document order because the algorithms + // defined in the specification rely on this. + struct StateNodeTypes + { + enum Enum { + UnknownType, + State, + Parallel, + Transition, + Final, + SCXML, + History, + }; + static bool CanHaveChildren(StateNodeTypes::Enum val) + { + return val == State || val == Parallel || val == SCXML; + } + static bool CanHaveTransitions(StateNodeTypes::Enum val) + { + return val == State || val == Parallel; + } + static bool IsStateType(StateNodeTypes::Enum val) + { + return CanHaveChildren(val) || val == Final; + } + static bool IsTransitionType(StateNodeTypes::Enum val) { return val == Transition; } + static bool CanHaveInitializeNode(StateNodeTypes::Enum val) { return val == State; } + static bool IsAtomicType(StateNodeTypes::Enum val) { return val == State || val == Final; } + }; + + struct SState; + struct SParallel; + struct STransition; + struct SFinal; + struct SSCXML; + struct SHistory; + + template + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::UnknownType; } + }; + + template <> + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::State; } + }; + template <> + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::Parallel; } + }; + template <> + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::Transition; } + }; + template <> + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::Final; } + }; + template <> + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::SCXML; } + }; + template <> + struct SStateNodeTypeMap + { + static StateNodeTypes::Enum GetStateNodeType() { return StateNodeTypes::History; } + }; + // Some editor info has to be contained on the state node. Description I am fine with eliding + // but + // most of the other information needs to sit on the nodes themselves. + struct StateNodeFlagValues + { + enum Enum { + HasNothing = 0, + HasPosition = 1, + HasDimension = 1 << 1, + HasColor = 1 << 2, + HasEndPosition = 1 << 3, + }; + }; + + struct SStateNodeFlags : NVFlags + { + bool HasPosition() const { return this->operator&(StateNodeFlagValues::HasPosition); } + void SetHasPosition(bool val) { clearOrSet(val, StateNodeFlagValues::HasPosition); } + bool HasDimension() const { return this->operator&(StateNodeFlagValues::HasDimension); } + void SetHasDimension(bool val) { clearOrSet(val, StateNodeFlagValues::HasDimension); } + bool HasColor() const { return this->operator&(StateNodeFlagValues::HasColor); } + void SetHasColor(bool val) { clearOrSet(val, StateNodeFlagValues::HasColor); } + bool HasEndPosition() const { return this->operator&(StateNodeFlagValues::HasEndPosition); } + void SetHasEndPosition(bool val) { clearOrSet(val, StateNodeFlagValues::HasEndPosition); } + }; + + struct SStateNode + { + const StateNodeTypes::Enum m_Type; + CRegisteredString m_Id; + SStateNode *m_Parent; + SStateNode *m_NextSibling; + SStateNode *m_PreviousSibling; + SInterpreterData *m_InterpreterData; + SStateNodeFlags m_StateNodeFlags; + QT3DSVec2 m_Position; + QT3DSVec2 m_Dimension; + QT3DSVec3 m_Color; + + SStateNode(StateNodeTypes::Enum inType) + : m_Type(inType) + , m_Parent(NULL) + , m_NextSibling(NULL) + , m_PreviousSibling(NULL) + , m_InterpreterData(NULL) + { + } + + template + TDataType *CastTo() + { + if (m_Type == SStateNodeTypeMap::GetStateNodeType()) + return static_cast(this); + QT3DS_ASSERT(false); + return NULL; + } + + template + const TDataType *CastTo() const + { + if (m_Type == SStateNodeTypeMap::GetStateNodeType()) + return static_cast(this); + QT3DS_ASSERT(false); + return NULL; + } + // Helper functions that take care of the drama around getting the various + // shared properties + bool IsCompound() const; + bool IsAtomic() const; + void AppendChild(SStateNode &inChild); + TOnEntryList *GetOnEntryList(); + TOnExitList *GetOnExitList(); + STransition *GetInitialTransition(); + const char8_t *GetInitialExpression(); + TStateNodeList *GetChildren(); + SDataModel *GetDataModel(); + Option GetPosition() const + { + if (m_StateNodeFlags.HasPosition()) + return m_Position; + return Empty(); + } + void SetPosition(const Option &pos) + { + if (pos.hasValue()) { + m_Position = *pos; + } + m_StateNodeFlags.SetHasPosition(pos.hasValue()); + } + Option GetDimension() const + { + if (m_StateNodeFlags.HasDimension()) + return m_Dimension; + return Empty(); + } + void SetDimension(const Option &pos) + { + if (pos.hasValue()) { + m_Dimension = *pos; + } + m_StateNodeFlags.SetHasDimension(pos.hasValue()); + } + Option GetColor() const + { + if (m_StateNodeFlags.HasColor()) + return m_Color; + return Empty(); + } + void SetColor(const Option &pos) + { + if (pos.hasValue()) { + m_Color = *pos; + } + m_StateNodeFlags.SetHasColor(pos.hasValue()); + } + }; + + struct SEntryExitBase : public SStateNode + { + TOnEntryList m_OnEntry; + TOnExitList m_OnExit; + SEntryExitBase(StateNodeTypes::Enum inType) + : SStateNode(inType) + { + } + }; + + // State and parallel objects can have states as children. Nothing aside from + // SCXML can have this. + struct SStateParallelBase : public SEntryExitBase + { + TStateNodeList m_Children; + SDataModel *m_DataModel; + TInvokeList m_InvokeList; + + SStateParallelBase(StateNodeTypes::Enum inType) + : SEntryExitBase(inType) + , m_DataModel(NULL) + { + } + + void RemoveChild(SStateNode &inChild) + { + QT3DS_ASSERT(inChild.m_Parent == this); + m_Children.remove(inChild); + inChild.m_Parent = NULL; + } + + void AppendChild(SStateNode &inChild, SStateNode *inLoc = NULL) + { + if (inChild.m_Parent != NULL) + static_cast(inChild.m_Parent)->RemoveChild(inChild); + if (inLoc) + m_Children.insert_after(*inLoc, inChild); + else + m_Children.push_back(inChild); + inChild.m_Parent = this; + } + + void PrependChild(SStateNode &inChild, SStateNode *inLoc = NULL) + { + if (inChild.m_Parent != NULL) + static_cast(inChild.m_Parent)->RemoveChild(inChild); + if (inLoc) + m_Children.insert_before(*inLoc, inChild); + else + m_Children.push_front(inChild); + inChild.m_Parent = this; + } + + bool IsAtomic() const + { + for (TStateNodeList::const_iterator iter = m_Children.begin(), end = m_Children.end(); + iter != end; ++iter) { + if (iter->m_Type != StateNodeTypes::Transition) + return false; + } + return true; + } + bool IsCompound() const { return !IsAtomic(); } + }; + + struct SCXMLFlagValues + { + enum Enum { + Late = 1, + }; + }; + + struct SSCXMLFlags : public NVFlags + { + SSCXMLFlags() {} + + void SetLateBinding(bool inValue) { clearOrSet(inValue, SCXMLFlagValues::Late); } + bool IsLateBinding() const { return this->operator&(SCXMLFlagValues::Late); } + }; + + // Begin standard object definitions + + struct SSCXML : public SStateNode + { + STransition *m_Initial; + CRegisteredString m_Name; + TStateNodeList m_Children; + SScript *m_Script; + SSCXMLFlags m_Flags; + SDataModel *m_DataModel; + QT3DSI32 m_Version; + const char8_t *m_Filename; + const char8_t *m_InitialExpr; + + static QT3DSI32 GetCurrentVersion() { return 1; } + SSCXML() + : SStateNode(StateNodeTypes::SCXML) + , m_Initial(NULL) + , m_Script(NULL) + , m_DataModel(NULL) + , m_Version(GetCurrentVersion()) + , m_InitialExpr(NULL) + { + } + + void RemoveChild(SStateNode &inChild) + { + QT3DS_ASSERT(inChild.m_Parent == this); + m_Children.remove(inChild); + inChild.m_Parent = NULL; + } + + void AppendChild(SStateNode &inChild, SStateNode *inLoc = NULL) + { + if (inChild.m_Parent != NULL) + static_cast(inChild.m_Parent)->RemoveChild(inChild); + if (inLoc) + m_Children.insert_after(*inLoc, inChild); + else + m_Children.push_back(inChild); + inChild.m_Parent = this; + } + }; + + struct SState : public SStateParallelBase + { + // transition, state, parallel, and final are all handed by SStateNode + STransition *m_Initial; + const char8_t *m_InitialExpr; + + SState() + : SStateParallelBase(StateNodeTypes::State) + , m_Initial(NULL) + , m_InitialExpr(NULL) + { + } + }; + + struct SParallel : public SStateParallelBase + { + SParallel() + : SStateParallelBase(StateNodeTypes::Parallel) + { + } + }; + + struct TransitionFlagValues + { + enum Enum { + Internal = 1, + }; + }; + + struct STransitionFlags : public NVFlags + { + STransitionFlags() {} + + void SetInternal(bool inValue) { clearOrSet(inValue, TransitionFlagValues::Internal); } + bool IsInternal() const { return this->operator&(TransitionFlagValues::Internal); } + }; + + struct STransition : public SStateNode + { + CRegisteredString m_Event; + const char8_t *m_Condition; + NVConstDataRef m_Target; + STransitionFlags m_Flags; + TExecutableContentList m_ExecutableContent; + NVConstDataRef m_Path; + // If we have multiple end targets, on order to lay them out we need a branch point + // along with the number of control points in each target. The first index points to the + // branch point in the path vector, then next index tells the number of control points + // for the first end point, etc. + NVConstDataRef m_PathIndexes; + QT3DSVec2 m_EndPosition; + // m_Source of the transition is its parent + + STransition() + : SStateNode(StateNodeTypes::Transition) + , m_Condition(NULL) + , m_EndPosition(0, 0) + { + } + + SStateNode *GetSource() { return m_Parent; } + + Option GetEndPosition() const + { + if (m_StateNodeFlags.HasEndPosition()) + return m_EndPosition; + return Empty(); + } + void SetEndPosition(const Option &pos) + { + if (pos.hasValue()) { + m_EndPosition = *pos; + } + m_StateNodeFlags.SetHasEndPosition(pos.hasValue()); + } + }; + + // TODO: DoneData + struct SFinal : public SEntryExitBase + { + SFinal() + : SEntryExitBase(StateNodeTypes::Final) + { + } + }; + + struct HistoryFlagValues + { + enum Enum { + Deep = 1, + }; + }; + + struct SHistoryFlags : public NVFlags + { + SHistoryFlags() {} + + void SetDeep(bool inValue) { clearOrSet(inValue, HistoryFlagValues::Deep); } + bool IsDeep() const { return this->operator&(HistoryFlagValues::Deep); } + }; + + struct SHistory : public SStateNode + { + SHistoryFlags m_Flags; + qt3ds::foundation::STaggedPointer m_UserData; + STransition *m_Transition; + + SHistory() + : SStateNode(StateNodeTypes::History) + , m_Transition(NULL) + { + } + }; + + struct SOnEntry + { + SOnEntry *m_NextSibling; + TExecutableContentList m_ExecutableContent; + qt3ds::foundation::STaggedPointer m_UserData; + SOnEntry() + : m_NextSibling(NULL) + { + } + }; + + struct SOnExit + { + SOnExit *m_NextSibling; + TExecutableContentList m_ExecutableContent; + qt3ds::foundation::STaggedPointer m_UserData; + SOnExit() + : m_NextSibling(NULL) + { + } + }; + + struct SInvoke + { + SInvoke *m_NextSibling; + SInvoke *m_PreviousSibling; + // Will have either SCXML content or dom content but not both. + SSCXML *m_SCXMLContent; + SDOMElement *m_DOMContent; + SInvoke() + : m_NextSibling(NULL) + , m_PreviousSibling(NULL) + , m_SCXMLContent(NULL) + , m_DOMContent(NULL) + { + } + }; + + // Events, because they created both inside and outside + // the state system by various parties. + class IEvent : public NVRefCounted + { + protected: + virtual ~IEvent() {} + public: + virtual CRegisteredString GetName() const = 0; + // Optional type string for rtti. No string means this is an opaque event + // that cannot be safely cast to any specific event type. + virtual CRegisteredString GetEventType() const { return CRegisteredString(); } + }; + + typedef NVScopedRefCounted TEventPtr; + + struct SIdValue; + + typedef nvhash_map TIDStateMap; + + struct SDOMElementNode + { + SDOMElementNode *m_NextNode; + SDOMElement *m_Element; + SDOMElementNode(SDOMElement *elem = NULL) + : m_NextNode(NULL) + , m_Element(elem) + { + } + }; + + struct SDOMAttributeNode + { + SDOMAttributeNode *m_NextNode; + SDOMAttribute *m_Attribute; + SDOMAttributeNode(SDOMAttribute *inAtt = NULL) + : m_NextNode(NULL) + , m_Attribute(inAtt) + { + } + }; + DEFINE_INVASIVE_SINGLE_LIST(DOMElementNode); + DEFINE_INVASIVE_SINGLE_LIST(DOMAttributeNode); + + inline bool SStateNode::IsCompound() const + { + if (m_Type == StateNodeTypes::SCXML) + return true; + if (m_Type == StateNodeTypes::State) + return !IsAtomic(); + return false; + } + + inline bool SStateNode::IsAtomic() const + { + if (m_Type == StateNodeTypes::SCXML) + return false; + + if (m_Type == StateNodeTypes::State) { + const SState *theState = CastTo(); + for (TStateNodeList::iterator iter = theState->m_Children.begin(), + end = theState->m_Children.end(); + iter != end; ++iter) { + if (iter->m_Type != StateNodeTypes::Transition + && iter->m_Type != StateNodeTypes::History) + return false; + } + return true; + } else if (m_Type == StateNodeTypes::Final) + return true; + return false; + } + + inline void SStateNode::AppendChild(SStateNode &inChild) + { + if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) { + static_cast(this)->AppendChild(inChild); + } else if (m_Type == StateNodeTypes::SCXML) { + static_cast(this)->AppendChild(inChild); + } else { + QT3DS_ASSERT(false); + } + } + + inline TOnEntryList *SStateNode::GetOnEntryList() + { + if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) + return &static_cast(this)->m_OnEntry; + if (m_Type == StateNodeTypes::Final) + return &CastTo()->m_OnEntry; + return NULL; + } + + inline TOnExitList *SStateNode::GetOnExitList() + { + if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) + return &static_cast(this)->m_OnExit; + if (m_Type == StateNodeTypes::Final) + return &CastTo()->m_OnExit; + return NULL; + } + + inline STransition *SStateNode::GetInitialTransition() + { + if (m_Type == StateNodeTypes::State) + return static_cast(this)->m_Initial; + if (m_Type == StateNodeTypes::SCXML) + return static_cast(this)->m_Initial; + return NULL; + } + + inline const char8_t *SStateNode::GetInitialExpression() + { + if (m_Type == StateNodeTypes::State) + return nonNull(static_cast(this)->m_InitialExpr); + if (m_Type == StateNodeTypes::SCXML) + return nonNull(static_cast(this)->m_InitialExpr); + return ""; + } + + inline TStateNodeList *SStateNode::GetChildren() + { + if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) + return &static_cast(this)->m_Children; + if (m_Type == StateNodeTypes::SCXML) + return &static_cast(this)->m_Children; + return NULL; + } + + inline SDataModel *SStateNode::GetDataModel() + { + if (m_Type == StateNodeTypes::State || m_Type == StateNodeTypes::Parallel) + return static_cast(this)->m_DataModel; + if (m_Type == StateNodeTypes::SCXML) + return static_cast(this)->m_DataModel; + return NULL; + } + + IMPLEMENT_INVASIVE_LIST(Invoke, m_PreviousSibling, m_NextSibling); + IMPLEMENT_INVASIVE_LIST(StateNode, m_PreviousSibling, m_NextSibling); + IMPLEMENT_INVASIVE_SINGLE_LIST(OnEntry, m_NextSibling); + IMPLEMENT_INVASIVE_SINGLE_LIST(OnExit, m_NextSibling); + IMPLEMENT_INVASIVE_SINGLE_LIST(DOMElementNode, m_NextNode); + IMPLEMENT_INVASIVE_SINGLE_LIST(DOMAttributeNode, m_NextNode); + + DEFINE_INVASIVE_SINGLE_LIST(Data); + + struct SDataModel + { + CRegisteredString m_Id; + const char8_t *m_Source; + const char8_t *m_Expression; + TDataList m_Data; + + SDataModel() + : m_Source(NULL) + , m_Expression(NULL) + { + } + }; + + struct SData + { + CRegisteredString m_Id; + const char8_t *m_Source; + const char8_t *m_Expression; + SData *m_NextSibling; + SData() + : m_Source(NULL) + , m_Expression(NULL) + , m_NextSibling(NULL) + { + } + }; + + IMPLEMENT_INVASIVE_SINGLE_LIST(Data, m_NextSibling); +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.cpp b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.cpp new file mode 100644 index 00000000..62413bae --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.cpp @@ -0,0 +1,626 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateVisualBindingContext.h" + +#include "Qt3DSStateVisualBindingContextValues.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "EASTL/string.h" +#include "EASTL/hash_map.h" +#include "Qt3DSStateInterpreter.h" +#include "Qt3DSStateContext.h" +#include "foundation/XML.h" +#include "foundation/FileTools.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "foundation/SerializationTypes.h" +#include "foundation/StringConversionImpl.h" + +using namespace qt3ds::state; + +namespace { + +struct SStateEventKey +{ + InterpreterEventTypes::Enum m_Event; + CRegisteredString m_Id; + SStateEventKey(InterpreterEventTypes::Enum inEvt, CRegisteredString inId) + : m_Event(inEvt) + , m_Id(inId) + { + } + bool operator==(const SStateEventKey &inOther) const + { + return m_Event == inOther.m_Event && m_Id == inOther.m_Id; + } +}; +} +namespace eastl { +template <> +struct hash +{ + size_t operator()(const SStateEventKey &inKey) const + { + return hash()((int)inKey.m_Event) + ^ hash()(inKey.m_Id); + } +}; +} + +namespace { +struct SVisualStateCommandNode +{ + SVisualStateCommand m_Command; + SVisualStateCommandNode *m_NextSibling; + SVisualStateCommandNode(const SVisualStateCommand &inCommand = SVisualStateCommand()) + : m_Command(inCommand) + , m_NextSibling(NULL) + { + } +}; + +DEFINE_INVASIVE_SINGLE_LIST(VisualStateCommandNode); +IMPLEMENT_INVASIVE_SINGLE_LIST(VisualStateCommandNode, m_NextSibling); + +typedef TVisualStateCommandNodeList TCommandList; + +// Apparently eastl::hash_multimap isn't order preserving for items. +typedef eastl::hash_map, + eastl::equal_to, ForwardingAllocator> + TStateEventCommandMap; + +struct SStateMachineSystem : public IStateInterpreterEventHandler, public NVRefCounted +{ + NVAllocatorCallback &m_Allocator; + CRegisteredString m_Path; + CRegisteredString m_Id; + CRegisteredString m_DatamodelFunction; + + NVScopedRefCounted m_StringTable; + NVScopedRefCounted m_Interpreter; + TStateEventCommandMap m_CommandMap; + QT3DSI32 mRefCount; + bool m_Error; + bool m_Running; + + TSignalConnectionPtr m_InterpreterEventConnection; + NVScopedRefCounted m_CommandHandler; + NVScopedRefCounted m_InterpreterFactory; + + SStateMachineSystem(const char8_t *inPath, const char8_t *inId, const char8_t *inFunction, + IStringTable &inStrTable, NVAllocatorCallback &inAlloc) + : m_Allocator(inAlloc) + , m_Path(inStrTable.RegisterStr(inPath)) + , m_Id(inStrTable.RegisterStr(inId)) + , m_DatamodelFunction(inStrTable.RegisterStr(inFunction)) + , m_StringTable(inStrTable) + , m_CommandMap(ForwardingAllocator(inAlloc, "SStateMachineSystem::m_CommandMap")) + , mRefCount(0) + , m_Error(false) + , m_Running(false) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) + + void Initialize() + { + } + + void Start() + { + if (m_Error || m_Running || !m_Interpreter) + return; + m_Running = true; + m_Interpreter->Start(); + // Event handler must be replaced after interpreter started + m_InterpreterEventConnection = m_Interpreter->RegisterEventHandler(*this); + // Run throw the initial configuration and fire any enter events. This takes care of + // initial states. + NVConstDataRef initialConfig = m_Interpreter->GetConfiguration(); + for (QT3DSU32 nodeIdx = 0, nodeEnd = initialConfig.size(); nodeIdx < nodeEnd; ++nodeIdx) { + SStateNode *theNode(initialConfig[nodeIdx]); + OnInterpreterEvent(InterpreterEventTypes::StateEnter, theNode->m_Id); + } + } + + void Update() + { + if (m_Interpreter) { + m_Interpreter->Execute(); + } + } + + void OnInterpreterEvent(InterpreterEventTypes::Enum inEvent, + CRegisteredString inEventId) override + { + if (m_CommandHandler) { + CRegisteredString theId = m_StringTable->RegisterStr(inEventId.c_str()); + SStateEventKey theKey(inEvent, theId); + TStateEventCommandMap::iterator theItem = m_CommandMap.find(theKey); + if (theItem != m_CommandMap.end()) { + for (TCommandList::iterator iter = theItem->second.begin(), + end = theItem->second.end(); + iter != end; ++iter) + m_CommandHandler->Handle(iter->m_Command, m_Interpreter->GetScriptContext()); + } + } + } +}; + +typedef eastl::vector> TStateMachineList; + +struct SVisualStateContext : public IVisualStateContext +{ + NVFoundationBase &m_Foundation; + SSAutoDeallocatorAllocator m_DataAllocator; + QT3DSI32 mRefCount; + TStateMachineList m_StateMachines; + NVScopedRefCounted m_CommandHandler; + NVScopedRefCounted m_InterpreterFactory; + NVScopedRefCounted m_StringTable; + nvvector m_PreparseResults; + + SVisualStateContext(NVFoundationBase &fnd, IStringTable &inStrTable) + : m_Foundation(fnd) + , m_DataAllocator(fnd) + , mRefCount(0) + , m_StringTable(inStrTable) + , m_PreparseResults(fnd.getAllocator(), "SVisualStateContext::m_PreparseResults") + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void LoadStateMachine(const char8_t *id, const char8_t *inRelativePath, + const char8_t *inDatamodelFunction) override + { + SStateMachineSystem *theSystem = QT3DS_NEW(m_Foundation.getAllocator(), SStateMachineSystem)( + inRelativePath, id, inDatamodelFunction, *m_StringTable, m_Foundation.getAllocator()); + theSystem->m_CommandHandler = m_CommandHandler; + theSystem->m_InterpreterFactory = m_InterpreterFactory; + m_StateMachines.push_back(theSystem); + } + + CRegisteredString ParseStrAtt(IDOMReader &inReader, const char8_t *attName) + { + const char8_t *temp = ""; + if (inReader.UnregisteredAtt(attName, temp)) { + return m_StringTable->RegisterStr(temp); + } + return CRegisteredString(); + } + + void PreparseExecutableContent(IDOMReader &inReader) + { + for (bool setatt = inReader.MoveToFirstChild(); setatt; + setatt = inReader.MoveToNextSibling()) { + IDOMReader::Scope __commandScope(inReader); + const char8_t *elemName = inReader.GetElementName(); + + SElementReference theReference; + if (AreEqual(elemName, "goto-slide")) { + theReference = SElementReference(ParseStrAtt(inReader, "element")); + } else if (AreEqual(elemName, "call")) { + theReference = SElementReference(ParseStrAtt(inReader, "element")); + } else if (AreEqual(elemName, "set-attribute")) { + theReference = SElementReference(ParseStrAtt(inReader, "element"), + ParseStrAtt(inReader, "attribute")); + } else if (AreEqual(elemName, "fire-event")) { + theReference = SElementReference(ParseStrAtt(inReader, "element")); + } else if (AreEqual(elemName, "set-presentation")) { + } else { + qCCritical(INVALID_PARAMETER, "Unrecognized child in an enter/exit node: %s", elemName); + } + if (theReference.m_ElementPath.IsValid()) { + m_PreparseResults.push_back(theReference); + } + } + } + + NVConstDataRef PreParseDocument(IDOMReader &inReader) override + { + m_PreparseResults.clear(); + for (bool success = inReader.MoveToFirstChild("statemachine"); success; + success = inReader.MoveToNextSibling("statemachine")) { + IDOMReader::Scope __readerScope(inReader); + if (inReader.MoveToFirstChild("visual-states")) { + IDOMReader::Scope __bindingsScope(inReader); + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + IDOMReader::Scope __stateScope(inReader); + if (AreEqual(inReader.GetElementName().c_str(), "transition")) { + PreparseExecutableContent(inReader); + } else { + for (bool enterExitSuccess = inReader.MoveToFirstChild(); enterExitSuccess; + enterExitSuccess = inReader.MoveToNextSibling()) { + IDOMReader::Scope __enterExitScope(inReader); + PreparseExecutableContent(inReader); + } + } + } + } + } + return m_PreparseResults; + } + + void ParseGotoSlideData(IDOMReader &inReader, SGotoSlideData &inData) + { + const char *tempData; + if (inReader.UnregisteredAtt("direction", tempData) && AreEqual(tempData, "reverse")) + inData.m_Reverse = true; + + if (inReader.UnregisteredAtt("mode", tempData)) { + if (AreEqual(tempData, "stopatend")) { + inData.m_Mode = SlidePlaybackModes::StopAtEnd; + inData.m_PlaythroughTo = CRegisteredString(); + } else if (AreEqual(tempData, "looping")) + inData.m_Mode = SlidePlaybackModes::Looping; + else if (AreEqual(tempData, "pingpong")) + inData.m_Mode = SlidePlaybackModes::PingPong; + else if (AreEqual(tempData, "ping")) + inData.m_Mode = SlidePlaybackModes::Ping; + else if (AreEqual(tempData, "playthrough")) { + if (!inReader.UnregisteredAtt("playthroughto", tempData) || isTrivial(tempData)) { + qCCritical(INVALID_OPERATION, "Goto slide command has playthough " + "mode but no playthroughto attribute; mode will be ignored"); + } else { + inData.m_PlaythroughTo = m_StringTable->RegisterStr(tempData); + } + + if (inData.m_PlaythroughTo.hasValue()) + inData.m_Mode = SlidePlaybackModes::StopAtEnd; + } + } + + if (inReader.UnregisteredAtt("state", tempData)) + inData.m_Paused = AreEqual(tempData, "pause"); + + if (inReader.UnregisteredAtt("rate", tempData)) { + QT3DSF32 temp = 1.0f; + if (StringConversion().StrTo(tempData, temp)) + inData.m_Rate = temp; + } + + if (inReader.UnregisteredAtt("time", tempData)) { + QT3DSF32 temp = 0.0f; + if (StringConversion().StrTo(tempData, temp)) + inData.m_StartTime = static_cast(NVMax(0.0f, temp) * 1000.0f + .5f); + } + } + + void ParseExecutableContent(IDOMReader &inReader, CRegisteredString &inStateId, + InterpreterEventTypes::Enum inEvent, + TStateEventCommandMap &inCommandMap) + { + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + IDOMReader::Scope __itemScope(inReader); + const char8_t *elemName = inReader.GetElementName(); + SVisualStateCommand theCommand; + if (AreEqual(elemName, "goto-slide")) { + const char8_t *rel; + if (inReader.UnregisteredAtt("rel", rel)) { + const char8_t *wrap; + inReader.UnregisteredAtt("wrap", wrap); + SGotoSlideRelative::Enum direction = SGotoSlideRelative::Error; + if (AreEqual(rel, "next")) + direction = SGotoSlideRelative::Next; + else if (AreEqual(rel, "previous")) + direction = SGotoSlideRelative::Previous; + else { + qCCritical(INVALID_OPERATION, "Goto slide relative has invalid " + "attribute (neither 'next' nor 'previous')"); + } + bool doWrap = AreEqual(wrap, "true") ? true : false; + + SGotoSlideRelative theCommandData(ParseStrAtt(inReader, "element"), direction, + doWrap); + ParseGotoSlideData(inReader, theCommandData.m_GotoSlideData); + theCommand = SVisualStateCommand(theCommandData); + } else { + SGotoSlide theCommandData(ParseStrAtt(inReader, "element"), + ParseStrAtt(inReader, "slide")); + ParseGotoSlideData(inReader, theCommandData.m_GotoSlideData); + theCommand = SVisualStateCommand(theCommandData); + } + } else if (AreEqual(elemName, "call")) { + theCommand = SVisualStateCommand(SCallFunction(ParseStrAtt(inReader, "element"), + ParseStrAtt(inReader, "handler"), + ParseStrAtt(inReader, "arguments"))); + } else if (AreEqual(elemName, "set-attribute")) { + theCommand = SVisualStateCommand(SSetAttribute(ParseStrAtt(inReader, "element"), + ParseStrAtt(inReader, "attribute"), + ParseStrAtt(inReader, "value"))); + } else if (AreEqual(elemName, "fire-event")) { + theCommand = SVisualStateCommand( + SFireEvent(ParseStrAtt(inReader, "element"), ParseStrAtt(inReader, "event"))); + } else if (AreEqual(elemName, "set-presentation")) { + theCommand = SVisualStateCommand(SPresentationAttribute( + ParseStrAtt(inReader, "ref"), ParseStrAtt(inReader, "attribute"), + ParseStrAtt(inReader, "value"))); + } else if (AreEqual(elemName, "play-sound")) { + theCommand = SVisualStateCommand(SPlaySound(ParseStrAtt(inReader, "file"))); + } else { + qCCritical(INVALID_PARAMETER, "Unrecognized child in an enter/exit node: %s", elemName); + } + if (theCommand.getType() != VisualStateCommandTypes::NoVisualStateCommand) { + TCommandList &theList = inCommandMap + .insert(eastl::make_pair( + SStateEventKey(inEvent, inStateId), TCommandList())) + .first->second; + theList.push_back(*QT3DS_NEW(m_DataAllocator, SVisualStateCommandNode)(theCommand)); + } + } + } + + SStateMachineSystem *FindStateMachine(const char8_t *inId) + { + if (isTrivial(inId)) + return NULL; + if (inId[0] == '#') + ++inId; + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) + if (AreEqual(m_StateMachines[idx].mPtr->m_Id.c_str(), inId)) + return m_StateMachines[idx].mPtr; + return NULL; + } + + // We have to be careful of string table values coming from the state machine and from the + // reader + // because we don't necessarily share the same string table. + void LoadVisualStateMapping(IDOMReader &inReader) override + { + for (bool success = inReader.MoveToFirstChild("statemachine"); success; + success = inReader.MoveToNextSibling("statemachine")) { + IDOMReader::Scope __readerScope(inReader); + const char8_t *machineId = ""; + if (inReader.UnregisteredAtt("ref", machineId)) { + SStateMachineSystem *theSystem = FindStateMachine(machineId + 1); + if (theSystem == NULL) { + qCCritical(INVALID_OPERATION, "Unknown state machine id: %s", + nonNull(machineId)); + continue; + } + + if (inReader.MoveToFirstChild("visual-states")) { + IDOMReader::Scope __bindingsScope(inReader); + for (bool bindingsSuccess = inReader.MoveToFirstChild(); bindingsSuccess; + bindingsSuccess = inReader.MoveToNextSibling()) { + IDOMReader::Scope __stateScope(inReader); + const char8_t *rawStateId = ""; + inReader.UnregisteredAtt("ref", rawStateId); + if (isTrivial(rawStateId)) + continue; + + if (rawStateId[0] == '#') + ++rawStateId; + CRegisteredString elemName = m_StringTable->RegisterStr(rawStateId); + + if (AreEqual(inReader.GetElementName().c_str(), "transition")) { + ParseExecutableContent(inReader, elemName, + InterpreterEventTypes::Transition, + theSystem->m_CommandMap); + } else { + for (bool stateSuccess = inReader.MoveToFirstChild(); stateSuccess; + stateSuccess = inReader.MoveToNextSibling()) { + IDOMReader::Scope __enterExitScope(inReader); + const char8_t *stateChildName = inReader.GetElementName(); + if (AreEqual(stateChildName, "enter")) { + ParseExecutableContent(inReader, elemName, + InterpreterEventTypes::StateEnter, + theSystem->m_CommandMap); + } else if (AreEqual(stateChildName, "exit")) { + ParseExecutableContent(inReader, elemName, + InterpreterEventTypes::StateExit, + theSystem->m_CommandMap); + } else { + qCCritical(INVALID_PARAMETER, + "Unrecognized child in a visual state bindings state: %s", + stateChildName); + } + } + } + } + } + } else { + qCCritical(INVALID_OPERATION, "visual-state element has no machine attribute"); + } + } + } + + void SetCommandHandler(IVisualStateCommandHandler *inHandler) override + { + m_CommandHandler = inHandler; + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) + m_StateMachines[idx]->m_CommandHandler = inHandler; + } + + void SetInterpreterFactory(IVisualStateInterpreterFactory *inHandler) override + { + m_InterpreterFactory = inHandler; + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) + m_StateMachines[idx]->m_InterpreterFactory = inHandler; + } + + void Initialize() override + { + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) + m_StateMachines[idx]->Initialize(); + } + + void Start() override + { + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) + m_StateMachines[idx]->Start(); + } + + void Update() override + { + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) + m_StateMachines[idx]->Update(); + } + + QT3DSU32 CountItems(TCommandList &list) + { + QT3DSU32 retval = 0; + for (TCommandList::iterator iter = list.begin(), end = list.end(); iter != end; ++iter) + ++retval; + return retval; + } + + struct SSaveVisitor + { + const SStrRemapMap &m_RemapMap; + SSaveVisitor(const SStrRemapMap &map) + : m_RemapMap(map) + { + } + template + SVisualStateCommand operator()(const TItemType &item) + { + TItemType newItem(item); + newItem.Remap(*this); + return newItem; + } + void Remap(CRegisteredString &inStr) { inStr.Remap(m_RemapMap); } + SVisualStateCommand operator()() { return SVisualStateCommand(); } + }; + + void BinarySave(IOutStream &stream) override + { + qt3ds::foundation::SWriteBuffer theWriteBuffer(m_Foundation.getAllocator(), + "BinarySave::writebuffer"); + // Allocate space for overall size of the data section + theWriteBuffer.writeZeros(4); + theWriteBuffer.write((QT3DSU32)m_StateMachines.size()); + const SStrRemapMap &theRemapMap(m_StringTable->GetRemapMap()); + for (QT3DSU32 idx = 0, end = m_StateMachines.size(); idx < end; ++idx) { + SStateMachineSystem &theSystem = *m_StateMachines[idx]; + CRegisteredString path(theSystem.m_Path); + CRegisteredString id(theSystem.m_Id); + CRegisteredString fn(theSystem.m_DatamodelFunction); + path.Remap(theRemapMap); + id.Remap(theRemapMap); + fn.Remap(theRemapMap); + theWriteBuffer.write(path); + theWriteBuffer.write(id); + theWriteBuffer.write(fn); + theWriteBuffer.write((QT3DSU32)theSystem.m_CommandMap.size()); + for (TStateEventCommandMap::iterator iter = theSystem.m_CommandMap.begin(), + mapEnd = theSystem.m_CommandMap.end(); + iter != mapEnd; ++iter) { + theWriteBuffer.write((QT3DSU32)iter->first.m_Event); + CRegisteredString stateId(iter->first.m_Id); + stateId.Remap(theRemapMap); + theWriteBuffer.write(stateId); + + theWriteBuffer.write(CountItems(iter->second)); + for (TCommandList::iterator cmdIter = iter->second.begin(), + cmdEnd = iter->second.end(); + cmdIter != cmdEnd; ++cmdIter) { + SVisualStateCommand remapped = + cmdIter->m_Command.visit(SSaveVisitor(theRemapMap)); + SVisualStateCommandNode theNode(remapped); + theWriteBuffer.write(theNode); + } + } + } + QT3DSU32 totalSize = theWriteBuffer.size(); + QT3DSU32 *data = (QT3DSU32 *)theWriteBuffer.begin(); + data[0] = totalSize - 4; + stream.Write((QT3DSU8 *)data, totalSize); + } + + struct SLoadVisitor + { + NVDataRef m_RemapMap; + SLoadVisitor(const NVDataRef map) + : m_RemapMap(map) + { + } + template + void operator()(TItemType &item) + { + item.Remap(*this); + } + + void Remap(CRegisteredString &inStr) { inStr.Remap(m_RemapMap); } + void operator()() {} + }; + + void BinaryLoad(IInStream &stream, NVDataRef inStringTableData) override + { + QT3DSU32 length; + stream.Read(length); + QT3DSU8 *data = (QT3DSU8 *)m_DataAllocator.allocate(length, "Binaryload", __FILE__, __LINE__); + stream.Read(data, length); + + SDataReader theReader(data, data + length); + QT3DSU32 numMachines = theReader.LoadRef(); + m_StateMachines.clear(); + m_StateMachines.reserve(numMachines); + for (QT3DSU32 idx = 0, end = numMachines; idx < end; ++idx) { + CRegisteredString path = theReader.LoadRef(); + CRegisteredString id = theReader.LoadRef(); + CRegisteredString fn = theReader.LoadRef(); + path.Remap(inStringTableData); + id.Remap(inStringTableData); + fn.Remap(inStringTableData); + LoadStateMachine(id, path, fn); + SStateMachineSystem &theSystem(*m_StateMachines.back()); + QT3DSU32 mapSize = theReader.LoadRef(); + for (QT3DSU32 mapIdx = 0; mapIdx < mapSize; ++mapIdx) { + InterpreterEventTypes::Enum evt = + static_cast(theReader.LoadRef()); + CRegisteredString stateId = theReader.LoadRef(); + stateId.Remap(inStringTableData); + QT3DSU32 numCommands = theReader.LoadRef(); + TCommandList &theList = + theSystem.m_CommandMap + .insert(eastl::make_pair(SStateEventKey(evt, stateId), TCommandList())) + .first->second; + for (QT3DSU32 cmdIdx = 0, cmdEnd = numCommands; cmdIdx < cmdEnd; ++cmdIdx) { + SVisualStateCommandNode *nextNode = theReader.Load(); + nextNode->m_Command.visit(SLoadVisitor(inStringTableData)); + theList.push_back(*nextNode); + } + } + } + } +}; +} + +IVisualStateContext &IVisualStateContext::Create(NVFoundationBase &inFoundation, + IStringTable &inStrTable) +{ + return *QT3DS_NEW(inFoundation.getAllocator(), SVisualStateContext)(inFoundation, inStrTable); +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.h b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.h new file mode 100644 index 00000000..192181e4 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContext.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_STATE_VISUAL_BINDING_CONTEXT_H +#define QT3DS_STATE_VISUAL_BINDING_CONTEXT_H +#include "Qt3DSState.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/StringTable.h" +#include "Qt3DSStateVisualBindingContextCommands.h" + +namespace qt3ds { +namespace foundation { + class IDOMReader; + class CStrTableOrDataRef; +} +} + +namespace qt3ds { +namespace state { + + struct SVisualStateCommand; + struct SSetAttribute; + + // Entity responsible for implementing the various visual state commands. + class IVisualStateCommandHandler : public NVRefCounted + { + protected: + virtual ~IVisualStateCommandHandler() {} + public: + virtual void Handle(const SVisualStateCommand &inCommand, + IScriptContext &inScriptContext) = 0; + }; + + class IVisualStateInterpreterFactory : public NVRefCounted + { + protected: + virtual ~IVisualStateInterpreterFactory() {} + }; + + // It is important that the visual state context list the elements it expects to find in a uip + // file + // so that during parse of the uip file, we can generate an error if some element isn't found. + struct SElementReference + { + CRegisteredString m_ElementPath; + CRegisteredString m_Attribute; + SElementReference(CRegisteredString elemPath = CRegisteredString(), + CRegisteredString att = CRegisteredString()) + : m_ElementPath(elemPath) + , m_Attribute(att) + { + } + }; + + class IVisualStateContext : public NVRefCounted + { + protected: + virtual ~IVisualStateContext() {} + public: + // All machines are loaded execute is called on the first update call. + // made after LoadVisualStateMapping + virtual void LoadStateMachine(const char8_t *id, const char8_t *inRelativePath, + const char8_t *inDatamodelFunction) = 0; + virtual void LoadVisualStateMapping(IDOMReader &inReader) = 0; + // We have to pre-parse the xml so we can reference everything in the various presentations + // We run this pass, then during uip file parsing we output errors if things don't match up. + virtual NVConstDataRef PreParseDocument(IDOMReader &inReader) = 0; + virtual void SetCommandHandler(IVisualStateCommandHandler *inHandler) = 0; + virtual void SetInterpreterFactory(IVisualStateInterpreterFactory *inHandler) = 0; + + // Initialize the state machines. Machines are initialized in order of LoadStateMachine + // calls. + virtual void Initialize() = 0; + virtual void Start() = 0; + + // Initialize the state machines. Machines are updated in order of LoadStateMachine calls. + virtual void Update() = 0; + + // Save out to a format that allows very rapid loading. + virtual void BinarySave(IOutStream &stream) = 0; + virtual void BinaryLoad(IInStream &stream, NVDataRef inStringTableData) = 0; + + static IVisualStateContext &Create(NVFoundationBase &inFoundation, + IStringTable &inStrTable); + }; +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextCommands.h b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextCommands.h new file mode 100644 index 00000000..4d08f695 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextCommands.h @@ -0,0 +1,348 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_STATE_VISUAL_BINDING_CONTEXT_COMMANDS_H +#define QT3DS_STATE_VISUAL_BINDING_CONTEXT_COMMANDS_H +#include "Qt3DSState.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace state { + + struct VisualStateCommandTypes + { + enum Enum { + NoVisualStateCommand = 0, + GotoSlide, + CallFunction, + SetAttribute, + GotoSlideRelative, + FireEvent, + PresentationAttribute, + PlaySound, + }; + }; + + struct SlidePlaybackModes + { + enum Enum { + StopAtEnd = 0, + Looping, + PingPong, + Ping, + PlaythroughTo, + }; + }; + + struct SGotoSlideData + { + Option m_Mode; + Option m_PlaythroughTo; + Option m_StartTime; + QT3DSF32 m_Rate; + bool m_Reverse; + Option m_Paused; + SGotoSlideData() + : m_Rate(1.0f) + , m_Reverse(false) + { + } + }; + + // All the element references in this file need to be absolute, meaning they + // must begin with a presentationid:. The is because the state machine exists at the + // application level where all presentations are pretty much equal and must be referenced + // by id. + + // Go to a particular slide. + + /* + a. If the slide attribute references a slide name not present on the time context an error must + be logged each time the executable would have been run, and the executable ignored. + b. If the time context is already on the slide referenced, no change is made to the time + context. + The slide does not restart. */ + struct SGotoSlide + { + CRegisteredString m_Component; + CRegisteredString m_Slide; + SGotoSlideData m_GotoSlideData; + SGotoSlide(CRegisteredString cmd = CRegisteredString(), + CRegisteredString slide = CRegisteredString()) + : m_Component(cmd) + , m_Slide(slide) + { + } + bool operator==(const SGotoSlide &inOther) const + { + return m_Component == inOther.m_Component && m_Slide == inOther.m_Slide; + } + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_Component); + inRemapper.Remap(m_Slide); + } + }; + + /* + 1. A executable must have a element="..." attribute that references a behavior + element in one of the presentation assets for the application. + a. If the element attribute is missing, or references an element that cannot be found, + an error must be logged each time the executable would have been run, and the executable + ignored. + b. If the element attribute references an element that is not a behavior then an error + must be logged each time the executable would have been run, and the executable ignored. + 2. A executable must have a handler="..." attribute that references a function value + in the table associated with the behavior element. + a. If the handler attribute is missing, or references a value that is not a function + value, an error must be logged each time the executable would have been run, and the executable + ignored. + 3. A executable may have an args="..." attribute that specifies an expression to + evaluate. + a. If the result of evaluating this expression is a single value, it is passed as the + first argument to the behavior's function. + b. If the result of evaluating this expression is a table, it is treated as a list that + is unpack'd, the numeric properties sent as arguments in order. + c. If the result of evaluating this expression is an error, an error message must be + logged and the executable ignored. + The function is not invoked with no parameters. + */ + struct SCallFunction + { + CRegisteredString m_Behavior; + CRegisteredString m_Handler; + CRegisteredString m_Arguments; + SCallFunction(CRegisteredString behavior = CRegisteredString(), + CRegisteredString hdler = CRegisteredString(), + CRegisteredString args = CRegisteredString()) + : m_Behavior(behavior) + , m_Handler(hdler) + , m_Arguments(args) + { + } + bool operator==(const SCallFunction &inOther) const + { + return m_Behavior == inOther.m_Behavior && m_Handler == inOther.m_Handler + && m_Arguments == inOther.m_Arguments; + } + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_Behavior); + inRemapper.Remap(m_Handler); + inRemapper.Remap(m_Arguments); + } + }; + + /* + 1. A executable must have an element="..." attribute that references an + element in one of the presentation assets for the application. + a. If the element attribute is missing, or references an element that cannot be found, + an error must be logged each time the executable would have been run, and the executable + ignored. + 2. A executable must have an attribute="..." attribute that references an + attribute on the referenced element. + a. If the attribute attribute is missing, or references an attribute not present on the + element, an error must be logged each time the executable would have been run, and the + executable ignored. + 3. A executable must have an value="..." attribute that describes the value + to set. + a. The contents of this attribute are evaluated as an expression and the result used + to set the attribute. + i. If the result of evaluating this expression does not match the type of the + attribute on the element then an error must be logged and the executable ignored. + 4. If a single visual state has both and executables, and the + slide change affects the same attribute as the set-attribute executable, then the set-attribute + executable must take effect (be applied after the slide change occurs). + In the future we may wish to have the order of this interaction controllable by the + ordering of the executables. + */ + struct SSetAttribute + { + CRegisteredString m_Element; + CRegisteredString m_Attribute; + CRegisteredString m_Value; + SSetAttribute(CRegisteredString elem = CRegisteredString(), + CRegisteredString att = CRegisteredString(), + CRegisteredString val = CRegisteredString()) + : m_Element(elem) + , m_Attribute(att) + , m_Value(val) + { + } + bool operator==(const SSetAttribute &inOther) const + { + return m_Element == inOther.m_Element && m_Attribute == inOther.m_Attribute + && m_Value == inOther.m_Value; + } + + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_Element); + inRemapper.Remap(m_Attribute); + inRemapper.Remap(m_Value); + } + }; + + /* + 4. A rel="..." attribute must have either the value next or prev. + a. If the rel attribute has a different value an error must be logged each time the + executable would have been run, and the executable ignored. + b. A value of next causes the time context to go to the next slide. + i. If the time context is at the last slide, and there is no wrap attribute, or + the wrap attribute does not have a value of true, then no change occurs to the time context. + The slide does not restart. + ii. If the time context is at the last slide and there exists a wrap attribute + with a value of true then the time context is taken to the first slide. + c. A value of prev causes the time context to go to the previous slide. + i. If the time context is at the first slide, and there is no wrap attribute, or + the wrap attribute does not have a value of true, then no change occurs to the time context. + The slide does not restart. + ii. If the time context is at the last first and there exists a wrap attribute + with a value of true then the time context is taken to the last slide. + */ + struct SGotoSlideRelative + { + CRegisteredString m_Component; + enum Enum { + Next = 0, + Previous, + Error, + }; + Enum m_Direction; + bool m_Wrap; + SGotoSlideData m_GotoSlideData; + SGotoSlideRelative(CRegisteredString comp = CRegisteredString(), Enum dir = Next, + bool wrap = false) + : m_Component(comp) + , m_Direction(dir) + , m_Wrap(wrap) + { + } + bool operator==(const SGotoSlideRelative &inOther) const + { + return m_Component == inOther.m_Component && m_Direction == inOther.m_Direction + && m_Wrap == inOther.m_Wrap; + } + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_Component); + } + }; + + /* + 1. A executable must have an element="..." attribute that references an element + in one of the presentation assets for the application. + a. If the element attribute is missing, or references an element that cannot be found, + an error must be logged each time the executable would have been run, and the executable + ignored. + 2. A executable must have an event="..." attribute that describes the event + name to fire. + a. If the event attribute is missing an error must be logged each time the executable + would have been run, and the executable ignored. + */ + struct SFireEvent + { + CRegisteredString m_Element; + CRegisteredString m_Event; + SFireEvent(CRegisteredString elem, CRegisteredString evt) + : m_Element(elem) + , m_Event(evt) + { + } + SFireEvent() {} + bool operator==(const SFireEvent &inOther) const + { + return m_Element == inOther.m_Element && m_Event == inOther.m_Event; + } + + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_Element); + inRemapper.Remap(m_Event); + } + }; + + struct SPresentationAttribute + { + CRegisteredString m_Presentation; + CRegisteredString m_Attribute; + CRegisteredString m_Value; + SPresentationAttribute(CRegisteredString pres, CRegisteredString att, CRegisteredString val) + : m_Presentation(pres) + , m_Attribute(att) + , m_Value(val) + { + } + SPresentationAttribute() {} + bool operator==(const SPresentationAttribute &inOther) const + { + return m_Presentation == inOther.m_Presentation && m_Attribute == inOther.m_Attribute + && m_Value == inOther.m_Value; + } + + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_Presentation); + inRemapper.Remap(m_Attribute); + inRemapper.Remap(m_Value); + } + }; + + struct SPlaySound + { + CRegisteredString m_SoundFilePath; + SPlaySound(CRegisteredString inSoundFilePath) + : m_SoundFilePath(inSoundFilePath) + { + } + SPlaySound() {} + bool operator==(const SPlaySound &inOther) const + { + return m_SoundFilePath == inOther.m_SoundFilePath; + } + + template + void Remap(TRemapper &inRemapper) + { + inRemapper.Remap(m_SoundFilePath); + } + }; + + // defined in UICStateVisualBindingContextValues.h + struct SVisualStateCommand; +} +} +#endif diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextValues.h b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextValues.h new file mode 100644 index 00000000..7bad9b33 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateVisualBindingContextValues.h @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_STATE_VISUAL_BINDING_CONTEXT_VALUES_H +#define QT3DS_STATE_VISUAL_BINDING_CONTEXT_VALUES_H +#include "Qt3DSStateVisualBindingContext.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" +#include "Qt3DSStateVisualBindingContextCommands.h" + +namespace qt3ds { +namespace state { + + template + struct SVisualStateCommandTypeMap + { + }; + + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::GotoSlide; + } + }; + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::CallFunction; + } + }; + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::SetAttribute; + } + }; + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::GotoSlideRelative; + } + }; + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::FireEvent; + } + }; + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::PresentationAttribute; + } + }; + template <> + struct SVisualStateCommandTypeMap + { + static VisualStateCommandTypes::Enum GetType() + { + return VisualStateCommandTypes::PlaySound; + } + }; + + struct SVisualStateCommandUnionTraits + { + typedef VisualStateCommandTypes::Enum TIdType; + enum { + TBufferSize = sizeof(SGotoSlideRelative), + }; + + static TIdType getNoDataId() { return VisualStateCommandTypes::NoVisualStateCommand; } + + template + static TIdType getType() + { + return SVisualStateCommandTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case VisualStateCommandTypes::GotoSlide: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::CallFunction: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::SetAttribute: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::GotoSlideRelative: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::FireEvent: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::PresentationAttribute: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::PlaySound: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case VisualStateCommandTypes::NoVisualStateCommand: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case VisualStateCommandTypes::GotoSlide: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::CallFunction: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::SetAttribute: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::GotoSlideRelative: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::FireEvent: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::PresentationAttribute: + return inVisitor(*NVUnionCast(inData)); + case VisualStateCommandTypes::PlaySound: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case VisualStateCommandTypes::NoVisualStateCommand: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SVisualStateCommandUnionTraits::TBufferSize> + TVisualStateCommandUnionType; + + struct SVisualStateCommand : public TVisualStateCommandUnionType + { + SVisualStateCommand() {} + + SVisualStateCommand(const SVisualStateCommand &inOther) + : TVisualStateCommandUnionType( + static_cast(inOther)) + { + } + + template + SVisualStateCommand(const TDataType &inDt) + : TVisualStateCommandUnionType(inDt) + { + } + + SVisualStateCommand &operator=(const SVisualStateCommand &inOther) + { + TVisualStateCommandUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SVisualStateCommand &inOther) const + { + return TVisualStateCommandUnionType::operator==(inOther); + } + bool operator!=(const SVisualStateCommand &inOther) const + { + return TVisualStateCommandUnionType::operator!=(inOther); + } + + bool empty() const { return getType() == VisualStateCommandTypes::NoVisualStateCommand; } + }; +} +} +#ifndef _INTEGRITYPLATFORM +namespace qt3ds { +namespace foundation { + + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SGotoSlide &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SCallFunction &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SSetAttribute &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SGotoSlideRelative &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SFireEvent &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SPresentationAttribute &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::SPlaySound &) {} + }; +} +} +#endif +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.cpp b/src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.cpp new file mode 100644 index 00000000..44f3242f --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.cpp @@ -0,0 +1,1948 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateXMLIO.h" +#include "foundation/XML.h" +#include "Qt3DSStateTypes.h" +#include "Qt3DSStateContext.h" +#include "foundation/Utils.h" +#include "foundation/StringConversionImpl.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "EASTL/hash_map.h" +#include "Qt3DSStateExecutionTypes.h" +#include "Qt3DSStateEditor.h" +#include "Qt3DSStateEditorValue.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::editor; + +namespace { +#define ITERATE_XML_ELEMENT_NAMES \ + HANDLE_XML_ELEMENT_NAME(scxml) \ + HANDLE_XML_ELEMENT_NAME(state) \ + HANDLE_XML_ELEMENT_NAME(parallel) \ + HANDLE_XML_ELEMENT_NAME(transition) \ + HANDLE_XML_ELEMENT_NAME(initial) \ + HANDLE_XML_ELEMENT_NAME(final) \ + HANDLE_XML_ELEMENT_NAME(onentry) \ + HANDLE_XML_ELEMENT_NAME(onexit) \ + HANDLE_XML_ELEMENT_NAME(history) \ + HANDLE_XML_ELEMENT_NAME(raise) \ + HANDLE_XML_ELEMENT_NAME(if) \ + HANDLE_XML_ELEMENT_NAME(elseif) \ + HANDLE_XML_ELEMENT_NAME(else) \ + HANDLE_XML_ELEMENT_NAME(foreach) \ + HANDLE_XML_ELEMENT_NAME(log) \ + HANDLE_XML_ELEMENT_NAME(param) \ + HANDLE_XML_ELEMENT_NAME(assign) \ + HANDLE_XML_ELEMENT_NAME(script) \ + HANDLE_XML_ELEMENT_NAME(send) \ + HANDLE_XML_ELEMENT_NAME(cancel) \ + HANDLE_XML_ELEMENT_NAME(invoke) \ + HANDLE_XML_ELEMENT_NAME(finalize) \ + HANDLE_XML_ELEMENT_NAME(cond) \ + HANDLE_XML_ELEMENT_NAME(event) \ + HANDLE_XML_ELEMENT_NAME(datamodel) \ + HANDLE_XML_ELEMENT_NAME(data) \ + HANDLE_XML_ELEMENT_NAME(content) \ + HANDLE_XML_ELEMENT_NAME(external_transition) + +struct SXMLName +{ + enum Enum { +#define HANDLE_XML_ELEMENT_NAME(nm) e##nm, + ITERATE_XML_ELEMENT_NAMES +#undef HANDLE_XML_ELEMENT_NAME + LastName, + }; + static const char *GetNameForElemName(Enum inName) + { + switch (inName) { +#define HANDLE_XML_ELEMENT_NAME(nm) \ + case e##nm: \ + return #nm; + ITERATE_XML_ELEMENT_NAMES +#undef HANDLE_XML_ELEMENT_NAME + default: + break; + } + QT3DS_ASSERT(false); + return "unknown element"; + } +}; + +const char8_t *GetSCXMLNamespace() +{ + return "http://www.w3.org/2005/07/scxml"; +} +const char8_t *GetStudioStateNamespace() +{ + return "http://qt.io/qt3dstudio/uicstate"; +} + +typedef eastl::pair *> TIdListPtrPair; +typedef eastl::pair TIdSendPair; + +TEditorStr DoGenerateUniqueId(const char *inRoot, IStateContext &ioContext, + IStringTable &ioStringTable) +{ + if (isTrivial(inRoot)) + inRoot = "id"; + TEditorStr stem(inRoot); + TEditorStr idStr(stem); + // Make the stem a valid possible id according xml specifications + if (idStr.size()) { + // Replace all spaces with undre + // Check that the first item isn't a space or a number. We can't do a real check here + // because we don't have unicode tables of letters and such. + // replace spaces with underscores. + for (TEditorStr::size_type thePos = idStr.find(' '); thePos != TEditorStr::npos; + thePos = idStr.find(' ', thePos + 1)) + idStr.replace(thePos, 1, "_"); + if (idStr[0] >= '0' && idStr[0] <= '9') + idStr.insert(idStr.begin(), 1, ':'); + } + + QT3DSU32 idx = 0; + + while (ioContext.ContainsId(ioStringTable.RegisterStr(idStr.c_str()))) { + ++idx; + char temp[64]; + sprintf(temp, "%d", idx); + idStr.assign(stem); + idStr.append("_"); + idStr.append(temp); + } + + return idStr; +} + +struct SParseContext +{ + typedef nvvector> TExternalTransitionList; + + NVAllocatorCallback &m_GraphAllocator; + NVFoundationBase &m_Foundation; + IDOMReader &m_Reader; + IStateContext &m_Context; + IStringTable &m_StrTable; + IEditor *m_Editor; + CRegisteredString m_Names[SXMLName::LastName]; + MemoryBuffer m_ParseBuffer; + nvvector m_TempBuffer; + // To be filled in on the second parse pass + nvvector m_References; + nvvector m_SendReferences; + CXMLIO::TIdRemapMap m_RemapMap; + nvvector m_GenerateIdList; + TExternalTransitionList m_ExternalTransitions; + CRegisteredString m_SCXMLNamespace; + CRegisteredString m_StudioNamespace; + QT3DSI32 m_Version; + + SParseContext(NVAllocatorCallback &inGraphAlloc, NVFoundationBase &inFnd, IDOMReader &inReader, + IStateContext &inCtx, IStringTable &inStrTable, IEditor *inEditor) + : m_GraphAllocator(inGraphAlloc) + , m_Foundation(inFnd) + , m_Reader(inReader) + , m_Context(inCtx) + , m_StrTable(inStrTable) + , m_Editor(inEditor) + , m_ParseBuffer(ForwardingAllocator(inFnd.getAllocator(), "ParseBuffer")) + , m_TempBuffer(inFnd.getAllocator(), "TempBuffer") + , m_References(inFnd.getAllocator(), "m_References") + , m_SendReferences(inFnd.getAllocator(), "m_StrReferences") + , m_GenerateIdList(inFnd.getAllocator(), "m_GenerateIdList") + , m_ExternalTransitions(inFnd.getAllocator(), "m_ExternalTransitions") + , m_Version(SSCXML::GetCurrentVersion()) + { +#define HANDLE_XML_ELEMENT_NAME(nm) m_Names[SXMLName::e##nm] = inStrTable.RegisterStr(#nm); + ITERATE_XML_ELEMENT_NAMES +#undef HANDLE_XML_ELEMENT_NAME + m_SCXMLNamespace = inStrTable.RegisterStr(GetSCXMLNamespace()); + m_StudioNamespace = inStrTable.RegisterStr(GetStudioStateNamespace()); + } + + inline bool eq(CRegisteredString lhs, SXMLName::Enum rhs) { return lhs == m_Names[rhs]; } + const char8_t *ToGraphStr(const char8_t *temp) + { + temp = nonNull(temp); + QT3DSU32 len = StrLen(temp) + 1; + char8_t *retval = + (char8_t *)m_GraphAllocator.allocate(len, "graph string", __FILE__, __LINE__); + memCopy(retval, temp, len); + // Force null termination regardless. + retval[len] = 0; + return retval; + } + const char8_t *ParseStrAtt(const char8_t *attName) + { + const char8_t *temp; + if (m_Reader.UnregisteredAtt(attName, temp) && temp && *temp) + return ToGraphStr(temp); + return NULL; + } + void ParseStrAtt(const char8_t *attName, const char8_t *&outVal) + { + outVal = ParseStrAtt(attName); + } + void ParseStrAtt(const char8_t *attName, CRegisteredString &outVal) + { + m_Reader.Att(attName, outVal); + } + + SItemExtensionInfo &GetExtensionInfo(void *inItem) + { + return m_Context.GetOrCreateExtensionInfo(inItem); + } + + // Extension attributes are indicated by their namespace. If they have a namespace + // and they aren't scxml namespace and they aren't studio namespace, they are extension. + void ParseExtensionAttributes(void *inItem) + { + for (SDOMAttribute *theAttribute = m_Reader.GetFirstAttribute(); theAttribute; + theAttribute = theAttribute->m_NextAttribute) { + if (theAttribute->m_Namespace != m_StudioNamespace + && theAttribute->m_Namespace != m_SCXMLNamespace + && theAttribute->m_Namespace.IsValid()) { + GetExtensionInfo(inItem).m_ExtensionAttributes.push_back( + *QT3DS_NEW(m_GraphAllocator, SDOMAttributeNode)(theAttribute)); + } + } + } + bool ParseExtensionElement(void *inItem) + { + SDOMElement &theElement(*m_Reader.GetElement()); + + if (theElement.m_Namespace != m_StudioNamespace + && theElement.m_Namespace != m_SCXMLNamespace && theElement.m_Namespace.IsValid()) { + GetExtensionInfo(inItem).m_ExtensionNodes.push_back( + *QT3DS_NEW(m_GraphAllocator, SDOMElementNode)(&theElement)); + return true; + } + return false; + } + + void ParseExtensionElements(void *inItem) + { + IDOMReader::Scope _childElemScope(m_Reader); + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + ParseExtensionElement(inItem); + } + } + + NVConstDataRef ParseFloats(const char8_t *inData) + { + size_t len = StrLen(inData) + 1; + if (len == 1) + return NVConstDataRef(); + m_TempBuffer.resize((QT3DSU32)len); + memCopy(m_TempBuffer.data(), inData, (QT3DSU32)len); + m_ParseBuffer.clear(); + Char8TReader theReader(m_TempBuffer.data(), m_ParseBuffer); + NVConstDataRef retval; + theReader.ReadBuffer(retval); + return retval; + } + bool ParseVec2Att(const char8_t *attName, QT3DSVec2 &outVal) + { + const char8_t *tempVal; + if (m_Reader.UnregisteredAtt(attName, tempVal, GetStudioStateNamespace())) { + NVConstDataRef floats = ParseFloats(tempVal); + if (floats.mSize >= 2) { + memCopy(&outVal.x, floats.mData, sizeof(outVal)); + return true; + } + } + return false; + } + + bool ParseVec3Att(const char8_t *attName, QT3DSVec3 &outVal) + { + const char8_t *tempVal; + if (m_Reader.UnregisteredAtt(attName, tempVal, GetStudioStateNamespace())) { + NVConstDataRef floats = ParseFloats(tempVal); + if (floats.mSize >= 3) { + memCopy(&outVal.x, floats.mData, sizeof(outVal)); + return true; + } + } + return false; + } + + CRegisteredString RemapStr(CRegisteredString inStr) + { + CXMLIO::TIdRemapMap::iterator iter = m_RemapMap.find(inStr.c_str()); + if (iter != m_RemapMap.end()) + inStr = m_StrTable.RegisterStr(iter->second.c_str()); + return inStr; + } + + SStateNode *FindStateNode(CRegisteredString inString) + { + return m_Context.FindStateNode(RemapStr(inString)); + } + + SSend *ParseSendIdSecondPass(const char8_t *inStr) + { + if (isTrivial(inStr)) + return NULL; + return m_Context.FindSend(RemapStr(m_StrTable.RegisterStr(inStr))); + } + + NVConstDataRef ParseIDRefSecondPass(const char8_t *inStr) + { + typedef eastl::basic_string TStrType; + TStrType workspace(ForwardingAllocator(m_Foundation.getAllocator(), "ParseIDRef")); + TStrType str(ForwardingAllocator(m_Foundation.getAllocator(), "ParseIDRef")); + nvvector tempVal(m_Foundation.getAllocator(), "ParseIDRef"); + + workspace.assign(inStr); + for (TStrType::size_type startPos = workspace.find_first_not_of(' '), + endPos = workspace.find_first_of(' ', startPos); + startPos != TStrType::npos; startPos = workspace.find_first_not_of(' ', endPos), + endPos = workspace.find_first_of(' ', startPos)) { + if (endPos == TStrType::npos) + endPos = workspace.size(); + str = workspace.substr(startPos, endPos - startPos); + CRegisteredString theStr(m_StrTable.RegisterStr(str.c_str())); + SStateNode *theNode = FindStateNode(theStr); + if (theNode) + tempVal.push_back(theNode); + } + if (tempVal.size() == 0) + return NVConstDataRef(); + + SStateNode **dataPtr = (SStateNode **)m_GraphAllocator.allocate( + tempVal.size() * sizeof(SStateNode *), "IDRef", __FILE__, __LINE__); + memCopy(dataPtr, tempVal.data(), tempVal.size() * sizeof(SStateNode *)); + return toDataRef(dataPtr, tempVal.size()); + } + + void ParseIDRef(const char8_t *inStr, NVConstDataRef &ioNodes) + { + if (inStr == NULL || *inStr == 0) { + ioNodes = NVConstDataRef(); + return; + } + m_References.push_back(eastl::make_pair(inStr, &ioNodes)); + } + + static void AppendChild(SStateNode &inParent, TStateNodeList &outChildren, SStateNode &inChild) + { + inChild.m_Parent = &inParent; + outChildren.push_back(inChild); + } + + static void AppendChild(SStateNode *inNodeParent, SExecutableContent *inParent, + TExecutableContentList &outChildren, SExecutableContent &inChild) + { + if (inNodeParent) { + QT3DS_ASSERT(inParent == NULL); + } else { + QT3DS_ASSERT(inParent); + } + inChild.m_StateNodeParent = inNodeParent; + inChild.m_Parent = inParent; + outChildren.push_back(inChild); + } + + template + void ParseEditorAttributes(TStateType &inNode) + { + ParseExtensionAttributes(&inNode); + if (m_Editor) { + const char8_t *name; + if (m_Reader.UnregisteredAtt("id", name, GetStudioStateNamespace())) + m_Editor->GetOrCreate(inNode)->SetPropertyValue("id", eastl::string(nonNull(name))); + + QT3DSVec2 temp; + if (ParseVec2Att("position", temp)) + m_Editor->GetOrCreate(inNode)->SetPropertyValue("position", temp); + + if (ParseVec2Att("dimension", temp)) + m_Editor->GetOrCreate(inNode)->SetPropertyValue("dimension", temp); + + QT3DSVec3 tempv3; + if (ParseVec3Att("color", tempv3)) + m_Editor->GetOrCreate(inNode)->SetPropertyValue("dimension", tempv3); + } + } + + void ParseStateNodeEditorAttributes(SStateNode &inNode) + { + ParseExtensionAttributes(&inNode); + CRegisteredString Id; + if (inNode.m_Id.IsValid() == false) + m_Reader.Att("id", inNode.m_Id); + + QT3DSVec2 temp; + if (ParseVec2Att("position", temp)) + inNode.SetPosition(temp); + + if (ParseVec2Att("dimension", temp)) + inNode.SetDimension(temp); + + QT3DSVec3 tempv3; + if (ParseVec3Att("color", tempv3)) + inNode.SetColor(tempv3); + + if (m_Editor) { + const char8_t *desc; + if (m_Reader.UnregisteredAtt("description", desc, GetStudioStateNamespace())) + m_Editor->ToEditor(inNode)->SetPropertyValue("description", + eastl::string(nonNull(desc))); + } + } + + // Parse the node id. IF it exists, then schedule the id for remapping. + template + void ParseNodeId(TDataType &inNode) + { + m_Reader.Att("id", inNode.m_Id); + if (inNode.m_Id.IsValid() == false || m_Context.ContainsId(inNode.m_Id)) { + m_GenerateIdList.push_back(&inNode); + } else { + bool success = m_Context.InsertId(inNode.m_Id, &inNode); + (void)success; + QT3DS_ASSERT(success); + } + } + + SParam &ParseParam() + { + IDOMReader::Scope _itemScope(m_Reader); + SParam *retval = QT3DS_NEW(m_GraphAllocator, SParam)(); + ParseStrAtt("name", retval->m_Name); + ParseStrAtt("expr", retval->m_Expr); + ParseStrAtt("location", retval->m_Location); + ParseExtensionAttributes(retval); + ParseExtensionElements(retval); + return *retval; + } + + SContent &ParseContent() + { + IDOMReader::Scope _itemScope(m_Reader); + SContent *retval = QT3DS_NEW(m_GraphAllocator, SContent)(); + ParseStrAtt("expr", retval->m_Expr); + if (isTrivial(retval->m_Expr)) { + if (m_Reader.CountChildren() == 0) { + const char8_t *val = NULL; + m_Reader.Value(val); + if (!isTrivial(val)) + retval->m_ContentValue = this->ToGraphStr(val); + } + // We don't implement any extensions, so this is most certainly going into the + // extensions bin for this content. + else { + } + } + ParseExtensionAttributes(retval); + ParseExtensionElements(retval); + return *retval; + } + + SExecutableContent &ParseSend() + { + IDOMReader::Scope _itemScope(m_Reader); + SSend *retval = QT3DS_NEW(m_GraphAllocator, SSend)(); + ParseStrAtt("event", retval->m_Event); + ParseStrAtt("eventexpr", retval->m_EventExpr); + ParseStrAtt("target", retval->m_Target); + ParseStrAtt("targetexpr", retval->m_TargetExpr); + ParseStrAtt("type", retval->m_Type); + ParseStrAtt("typeExpr", retval->m_TypeExpr); + ParseNodeId(*retval); + ParseStrAtt("idlocation", retval->m_IdLocation); + ParseStrAtt("delay", retval->m_Delay); + ParseStrAtt("delayexpr", retval->m_DelayExpr); + ParseStrAtt("namelist", retval->m_NameList); + ParseExtensionAttributes(retval); + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (eq(elemName, SXMLName::eparam)) + AppendChild(NULL, retval, retval->m_Children, ParseParam()); + else if (eq(elemName, SXMLName::econtent)) + retval->m_Children.push_back(ParseContent()); + else { + if (!ParseExtensionElement(retval)) { + qCCritical(INTERNAL_ERROR, "Failed to parse send child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + } + m_Context.AddSendToList(*retval); + return *retval; + } + SExecutableContent &ParseIf() + { + IDOMReader::Scope _itemScope(m_Reader); + SIf *retval = QT3DS_NEW(m_GraphAllocator, SIf)(); + ParseStrAtt("cond", retval->m_Cond); + ParseExtensionAttributes(retval); + ParseExecutableContent(NULL, retval, retval->m_Children, retval); + return *retval; + } + + SExecutableContent &ParseElseIf() + { + IDOMReader::Scope _itemScope(m_Reader); + SElseIf *retval = QT3DS_NEW(m_GraphAllocator, SElseIf)(); + ParseStrAtt("cond", retval->m_Cond); + ParseExtensionAttributes(retval); + ParseExecutableContent(NULL, retval, retval->m_Children, retval); + return *retval; + } + + SExecutableContent &ParseElse() + { + IDOMReader::Scope _itemScope(m_Reader); + SElse *retval = QT3DS_NEW(m_GraphAllocator, SElse)(); + ParseExtensionAttributes(retval); + ParseExecutableContent(NULL, retval, retval->m_Children, retval); + return *retval; + } + SExecutableContent &ParseForEach() + { + IDOMReader::Scope _itemScope(m_Reader); + SForeach *retval = QT3DS_NEW(m_GraphAllocator, SForeach)(); + ParseStrAtt("array", retval->m_Array); + ParseStrAtt("item", retval->m_Item); + ParseStrAtt("index", retval->m_Index); + ParseExtensionAttributes(retval); + ParseExecutableContent(NULL, retval, retval->m_Children, retval); + return *retval; + } + + SExecutableContent &ParseRaise() + { + IDOMReader::Scope _itemScope(m_Reader); + SRaise *retval = QT3DS_NEW(m_GraphAllocator, SRaise)(); + ParseStrAtt("event", retval->m_Event); + ParseExtensionAttributes(retval); + ParseExtensionElements(retval); + return *retval; + } + + SExecutableContent &ParseLog() + { + IDOMReader::Scope _itemScope(m_Reader); + SLog *retval = QT3DS_NEW(m_GraphAllocator, SLog)(); + ParseStrAtt("label", retval->m_Label); + ParseStrAtt("expr", retval->m_Expression); + ParseExtensionAttributes(retval); + ParseExtensionElements(retval); + return *retval; + } + + SData &ParseData() + { + IDOMReader::Scope _itemScope(m_Reader); + SData *retval = QT3DS_NEW(m_GraphAllocator, SData)(); + ParseStrAtt("id", retval->m_Id); + ParseStrAtt("src", retval->m_Source); + ParseStrAtt("expr", retval->m_Expression); + ParseEditorAttributes(*retval); + ParseExtensionElements(retval); + const char8_t *value; + m_Reader.Value(value); + // Not handling arbitrary content under data right now. + if (isTrivial(retval->m_Expression) && !isTrivial(value)) { + retval->m_Expression = ToGraphStr(value); + } + return *retval; + } + + SDataModel *ParseDataModel() + { + IDOMReader::Scope _itemScope(m_Reader); + SDataModel *retval = QT3DS_NEW(m_GraphAllocator, SDataModel)(); + ParseStrAtt("id", retval->m_Id); + ParseStrAtt("src", retval->m_Source); + ParseStrAtt("expr", retval->m_Expression); + ParseEditorAttributes(*retval); + for (bool success = m_Reader.MoveToFirstChild("data"); success; + success = m_Reader.MoveToNextSibling("data")) + retval->m_Data.push_back(ParseData()); + + ParseExtensionElements(retval); + + return retval; + } + + SExecutableContent &ParseAssign() + { + IDOMReader::Scope _itemScope(m_Reader); + SAssign *retval = QT3DS_NEW(m_GraphAllocator, SAssign)(); + ParseStrAtt("location", retval->m_Location); + ParseStrAtt("expr", retval->m_Expression); + ParseExtensionAttributes(retval); + ParseExtensionElements(retval); + // Not dealing with children. + return *retval; + } + + SExecutableContent &ParseScript() + { + IDOMReader::Scope _itemScope(m_Reader); + SScript *retval = QT3DS_NEW(m_GraphAllocator, SScript)(); + ParseStrAtt("src", retval->m_URL); + ParseExtensionAttributes(retval); + if (m_Reader.Value(retval->m_Data)) + retval->m_Data = ToGraphStr(retval->m_Data); + ParseExtensionElements(retval); + return *retval; + } + + SExecutableContent &ParseCancel() + { + IDOMReader::Scope _itemScope(m_Reader); + SCancel *retval = QT3DS_NEW(m_GraphAllocator, SCancel)(); + const char8_t *sendId; + if (m_Reader.UnregisteredAtt("sendid", sendId)) + m_SendReferences.push_back(eastl::make_pair(sendId, &retval->m_Send)); + ParseStrAtt("sendidexpr", retval->m_IdExpression); + ParseExtensionAttributes(retval); + ParseExtensionElements(retval); + return *retval; + } + struct SExecutableContentParseBinding + { + SXMLName::Enum m_Name; + typedef SExecutableContent &(SParseContext::*TParseFunc)(); + TParseFunc m_ParseFunc; + }; + + static NVDataRef GetParseBindings() + { + static SExecutableContentParseBinding s_ExecContentParseBindings[10] = { + { SXMLName::esend, &SParseContext::ParseSend }, + { SXMLName::eif, &SParseContext::ParseIf }, + { SXMLName::eelseif, &SParseContext::ParseElseIf }, + { SXMLName::eelse, &SParseContext::ParseElse }, + { SXMLName::eforeach, &SParseContext::ParseForEach }, + { SXMLName::eraise, &SParseContext::ParseRaise }, + { SXMLName::elog, &SParseContext::ParseLog }, + { SXMLName::eassign, &SParseContext::ParseAssign }, + { SXMLName::escript, &SParseContext::ParseScript }, + { SXMLName::ecancel, &SParseContext::ParseCancel }, + }; + + return toDataRef(s_ExecContentParseBindings, 10); + } + + bool ParseExecutableContentItem(SStateNode *inNodeParent, SExecutableContent *inParent, + TExecutableContentList &outContent) + { + CRegisteredString elemName = m_Reader.GetElementName(); + NVDataRef theBindingList(GetParseBindings()); + for (QT3DSU32 idx = 0, end = theBindingList.size(); idx < end; ++idx) { + SExecutableContentParseBinding theBinding(theBindingList[idx]); + if (eq(elemName, theBinding.m_Name)) { + AppendChild(inNodeParent, inParent, outContent, (this->*theBinding.m_ParseFunc)()); + return true; + } + } + return false; + } + + void ParseExecutableContent(SStateNode *inStateNodeParent, SExecutableContent *inParent, + TExecutableContentList &outContent, void *inExtensionPtr) + { + IDOMReader::Scope _itemScope(m_Reader); + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (!ParseExecutableContentItem(inStateNodeParent, inParent, outContent)) { + if (!ParseExtensionElement(inExtensionPtr)) { + qCCritical(INTERNAL_ERROR, "Failed to parse extension child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + } + } + + SOnEntry &ParseOnEntry(SStateNode &inParent) + { + IDOMReader::Scope _itemScope(m_Reader); + SOnEntry *retval = QT3DS_NEW(m_GraphAllocator, SOnEntry)(); + ParseExecutableContent(&inParent, NULL, retval->m_ExecutableContent, retval); + return *retval; + } + + SOnExit &ParseOnExit(SStateNode &inParent) + { + IDOMReader::Scope _itemScope(m_Reader); + SOnExit *retval = QT3DS_NEW(m_GraphAllocator, SOnExit)(); + ParseExecutableContent(&inParent, NULL, retval->m_ExecutableContent, retval); + return *retval; + } + + SHistory &ParseHistory() + { + IDOMReader::Scope _itemScope(m_Reader); + SHistory *retval = QT3DS_NEW(m_GraphAllocator, SHistory)(); + ParseNodeId(*retval); + const char8_t *temp; + if (m_Reader.UnregisteredAtt("type", temp) && AreEqual(temp, "deep")) + retval->m_Flags.SetDeep(true); + ParseStateNodeEditorAttributes(*retval); + if (m_Reader.MoveToFirstChild("transition")) { + retval->m_Transition = &ParseTransition(); + retval->m_Transition->m_Parent = retval; + } + ParseExtensionElements(retval); + return *retval; + } + + STransition &ParseTransition() + { + IDOMReader::Scope _itemScope(m_Reader); + STransition *retval = QT3DS_NEW(m_GraphAllocator, STransition)(); + m_Reader.Att("event", retval->m_Event); + ParseNodeId(*retval); + const char8_t *temp; + if (m_Reader.UnregisteredAtt("target", temp)) { + ParseIDRef(temp, retval->m_Target); + } + if (m_Reader.UnregisteredAtt("type", temp) && AreEqual(temp, "internal")) + retval->m_Flags.SetInternal(true); + ParseStateNodeEditorAttributes(*retval); + + retval->m_Condition = ParseStrAtt("cond"); + // Position and such is only valid for transitions after UIC version 0. + if (m_Version > 0) { + QT3DSVec2 endPos; + if (ParseVec2Att("end_position", endPos)) + retval->SetEndPosition(endPos); + + if (m_Reader.UnregisteredAtt("path", temp)) { + NVConstDataRef pathData = ParseFloats(temp); + QT3DS_ASSERT((pathData.size() % 2) == 0); + size_t newDataSize = pathData.size() * sizeof(QT3DSF32); + QT3DSVec2 *newData = (QT3DSVec2 *)m_GraphAllocator.allocate( + newDataSize, "STransition::m_Path", __FILE__, __LINE__); + memCopy(newData, pathData.begin(), (QT3DSU32)newDataSize); + retval->m_Path = toDataRef(newData, (QT3DSU32)(newDataSize / sizeof(QT3DSVec2))); + } + } else { + retval->SetPosition(Empty()); + } + + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (!ParseExecutableContentItem(retval, NULL, retval->m_ExecutableContent)) { + if (!ParseExtensionElement(retval)) { + qCCritical(INTERNAL_ERROR, "Failed to parse transition child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + } + return *retval; + } + + SFinal &ParseFinal() + { + IDOMReader::Scope _itemScope(m_Reader); + SFinal *retval = QT3DS_NEW(m_GraphAllocator, SFinal)(); + + ParseNodeId(*retval); + ParseStateNodeEditorAttributes(*retval); + + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (eq(elemName, SXMLName::eonentry)) + retval->m_OnEntry.push_back(ParseOnEntry(*retval)); + else if (eq(elemName, SXMLName::eonexit)) + retval->m_OnExit.push_back(ParseOnExit(*retval)); + else if (!ParseExtensionElement(retval)) { + qCCritical(INTERNAL_ERROR, "Failed to parse final child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + return *retval; + } + + bool ParseStateParallelChildren(SStateNode &inParent, CRegisteredString &inElemName, + TStateNodeList &outChildren, TOnEntryList &inOnEntry, + TOnExitList &inOnExit, SDataModel *&dmPtr) + { + if (eq(inElemName, SXMLName::estate)) + AppendChild(inParent, outChildren, ParseState()); + else if (eq(inElemName, SXMLName::etransition)) + AppendChild(inParent, outChildren, ParseTransition()); + else if (eq(inElemName, SXMLName::eparallel)) + AppendChild(inParent, outChildren, ParseParallel()); + else if (eq(inElemName, SXMLName::eonentry)) + inOnEntry.push_back(ParseOnEntry(inParent)); + else if (eq(inElemName, SXMLName::eonexit)) + inOnExit.push_back(ParseOnExit(inParent)); + else if (eq(inElemName, SXMLName::ehistory)) + AppendChild(inParent, outChildren, ParseHistory()); + else if (eq(inElemName, SXMLName::efinal)) + AppendChild(inParent, outChildren, ParseFinal()); + else if (eq(inElemName, SXMLName::edatamodel)) + dmPtr = ParseDataModel(); + else { + return false; + } + return true; + } + + SStateNode &ParseParallel() + { + IDOMReader::Scope _itemScope(m_Reader); + SParallel *retval = QT3DS_NEW(m_GraphAllocator, SParallel)(); + ParseNodeId(*retval); + ParseStateNodeEditorAttributes(*retval); + + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (!ParseStateParallelChildren(*retval, elemName, retval->m_Children, + retval->m_OnEntry, retval->m_OnExit, + retval->m_DataModel)) { + if (!ParseExtensionElement(retval)) { + qCCritical(INTERNAL_ERROR, "Failed to parse parallel child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + } + return *retval; + } + + void SetStateInitialTransition(STransition *&ioInitial, TStateNodeList &inChildren, + SStateNode &inSource) + { + if (ioInitial) { + ioInitial->m_Parent = &inSource; + return; + } + SStateNode *firstStateChild = NULL; + for (TStateNodeList::iterator iter = inChildren.begin(); + iter != inChildren.end() && firstStateChild == NULL; ++iter) { + if (iter->m_Type == StateNodeTypes::State || iter->m_Type == StateNodeTypes::Parallel + || iter->m_Type == StateNodeTypes::Final) { + firstStateChild = &(*iter); + } + } + + if (firstStateChild) { + STransition *theTransition = QT3DS_NEW(m_GraphAllocator, STransition)(); + size_t byteSize = sizeof(SStateNode *); + SStateNode **theData = (SStateNode **)m_GraphAllocator.allocate( + byteSize, "InitialTransition", __FILE__, __LINE__); + *theData = firstStateChild; + theTransition->m_Target = toDataRef(theData, 1); + theTransition->m_Parent = &inSource; + ioInitial = theTransition; + } + } + + STransition *ParseInitial() + { + if (m_Reader.MoveToFirstChild("transition")) + return &ParseTransition(); + else { + QT3DS_ASSERT(false); + } + return NULL; + } + + SStateNode &ParseState() + { + IDOMReader::Scope _stateScope(m_Reader); + SState *theNewState = QT3DS_NEW(m_GraphAllocator, SState)(); + ParseNodeId(*theNewState); + const char8_t *initialAtt; + if (m_Reader.UnregisteredAtt("initialexpr", initialAtt, GetStudioStateNamespace())) { + theNewState->m_InitialExpr = ToGraphStr(initialAtt); + const char8_t *errorTest; + if (m_Reader.UnregisteredAtt("initial", errorTest)) { + qCCritical(INVALID_OPERATION, "Attribute initial=\"%s\" conflicts with " + "attribute initialexpr=\"%s\" on ; using initialexpr.", + nonNull(errorTest), nonNull(initialAtt), + nonNull(theNewState->m_Id.c_str())); + } + } else if (m_Reader.UnregisteredAtt("initial", initialAtt) && !isTrivial(initialAtt)) { + STransition *theTransition = QT3DS_NEW(m_GraphAllocator, STransition)(); + ParseIDRef(initialAtt, theTransition->m_Target); + theTransition->m_Parent = theNewState; + theNewState->m_Initial = theTransition; + } + + ParseStateNodeEditorAttributes(*theNewState); + + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (!ParseStateParallelChildren(*theNewState, elemName, theNewState->m_Children, + theNewState->m_OnEntry, theNewState->m_OnExit, + theNewState->m_DataModel)) { + // InitialExpr takes precedence over initial transition + if (eq(elemName, SXMLName::einitial) && isTrivial(theNewState->m_InitialExpr)) { + if (!theNewState->m_Initial) + theNewState->m_Initial = ParseInitial(); + } else { + if (!ParseExtensionElement(theNewState)) { + qCCritical(INTERNAL_ERROR, "Failed to parse state child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + } + } + if (isTrivial(theNewState->m_InitialExpr)) + SetStateInitialTransition(theNewState->m_Initial, theNewState->m_Children, + *theNewState); + return *theNewState; + } + + static const char8_t *GetDefaultIdName(SStateNode &theNode) + { + const char8_t *theTemp = "id"; + switch (theNode.m_Type) { + case StateNodeTypes::State: + theTemp = "state"; + break; + case StateNodeTypes::Parallel: + theTemp = "parallel"; + break; + case StateNodeTypes::Final: + theTemp = "final"; + break; + case StateNodeTypes::History: + theTemp = "history"; + break; + case StateNodeTypes::Transition: + theTemp = "transition"; + break; + default: + break; + } + return theTemp; + } + + static const char8_t *GetDefaultIdName(SSend &) { return "send"; } + + template + void GenerateIdValue(TDataType &theNode) + { + if (theNode.m_Id.IsValid() == true) { + bool preexisting = m_Context.ContainsId(theNode.m_Id); + if (preexisting) { + CRegisteredString oldId = theNode.m_Id; + theNode.m_Id = CRegisteredString(); + CXMLIO::GenerateUniqueId(theNode, oldId.c_str(), m_Context, m_StrTable); + bool success = m_RemapMap.insert(eastl::make_pair(oldId, theNode.m_Id)).second; + (void)success; + QT3DS_ASSERT(success); + } + } else { + CXMLIO::GenerateUniqueId(theNode, GetDefaultIdName(theNode), m_Context, m_StrTable); + } + } + + void FinishParsing() + { + for (QT3DSU32 idx = 0, end = m_GenerateIdList.size(); idx < end; ++idx) { + SIdValue &theNode(m_GenerateIdList[idx]); + switch (theNode.getType()) { + case IdValueTypes::StateNode: + GenerateIdValue(*(theNode.getData())); + break; + case IdValueTypes::Send: + GenerateIdValue(*(theNode.getData())); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + for (QT3DSU32 idx = 0, end = m_References.size(); idx < end; ++idx) + *(m_References[idx].second) = ParseIDRefSecondPass(m_References[idx].first); + + for (QT3DSU32 idx = 0, end = m_SendReferences.size(); idx < end; ++idx) + *(m_SendReferences[idx].second) = ParseSendIdSecondPass(m_SendReferences[idx].first); + + if (m_Editor) { + for (QT3DSU32 idx = 0, end = m_ExternalTransitions.size(); idx < end; ++idx) { + SStateNode *theNode = FindStateNode(m_ExternalTransitions[idx].first); + if (theNode) { + TObjPtr transObj = m_Editor->GetOrCreate(*m_ExternalTransitions[idx].second); + TObjPtr stateObj = m_Editor->ToEditor(*theNode); + stateObj->Append("children", transObj); + } + } + } + } + SSCXML &ParseSCXML() + { + IDOMReader::Scope _stateScope(m_Reader); + SSCXML *retval = QT3DS_NEW(m_GraphAllocator, SSCXML)(); + + if (m_Reader.Att("id", retval->m_Id)) + m_Context.InsertId(retval->m_Id, retval); + const char8_t *initial; + if (m_Reader.UnregisteredAtt("initialexpr", initial, GetStudioStateNamespace())) { + retval->m_InitialExpr = ToGraphStr(initial); + } else if (m_Reader.UnregisteredAtt("initial", initial)) { + STransition *theTransition = QT3DS_NEW(m_GraphAllocator, STransition)(); + ParseIDRef(initial, theTransition->m_Target); + theTransition->m_Parent = retval; + retval->m_Initial = theTransition; + } + ParseStrAtt("name", retval->m_Name); + const char8_t *uicVersion; + if (!m_Reader.UnregisteredAtt("version", uicVersion, GetStudioStateNamespace())) + retval->m_Version = 0; + else { + StringConversion().StrTo(uicVersion, retval->m_Version); + } + m_Version = retval->m_Version; + const char8_t *desc; + if (m_Editor && m_Reader.UnregisteredAtt("description", desc)) + m_Editor->GetOrCreate(*retval)->SetPropertyValue("description", desc); + + const char8_t *temp; + if (m_Reader.UnregisteredAtt("binding", temp) && AreEqual(temp, "late")) + retval->m_Flags.SetLateBinding(true); + + ParseExtensionAttributes(retval); + + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (eq(elemName, SXMLName::estate)) + AppendChild(*retval, retval->m_Children, ParseState()); + else if (eq(elemName, SXMLName::eparallel)) + AppendChild(*retval, retval->m_Children, ParseParallel()); + else if (eq(elemName, SXMLName::etransition)) + AppendChild(*retval, retval->m_Children, ParseTransition()); + else if (eq(elemName, SXMLName::efinal)) + AppendChild(*retval, retval->m_Children, ParseFinal()); + else if (eq(elemName, SXMLName::einitial)) + retval->m_Initial = ParseInitial(); + else if (eq(elemName, SXMLName::edatamodel)) + retval->m_DataModel = ParseDataModel(); + else { + if (!ParseExtensionElement(retval)) { + qCCritical(INTERNAL_ERROR, "Failed to parse scxml child %s", elemName.c_str()); + QT3DS_ASSERT(false); + } + } + } + if (isTrivial(retval->m_InitialExpr)) { + SetStateInitialTransition(retval->m_Initial, retval->m_Children, *retval); + } + FinishParsing(); + return *retval; + } + eastl::vector ParseFragment() + { + eastl::vector retval; + + for (bool success = m_Reader.MoveToFirstChild(); success; + success = m_Reader.MoveToNextSibling()) { + IDOMReader::Scope _loopScope(m_Reader); + CRegisteredString elemName = m_Reader.GetElementName(); + if (eq(elemName, SXMLName::estate)) + retval.push_back(&ParseState()); + else if (eq(elemName, SXMLName::eparallel)) + retval.push_back(&ParseParallel()); + else if (eq(elemName, SXMLName::efinal)) + retval.push_back(&ParseFinal()); + else if (eq(elemName, SXMLName::ehistory)) + retval.push_back(&ParseHistory()); + else if (eq(elemName, SXMLName::eexternal_transition)) { + CRegisteredString src; + m_Reader.Att("source", src); + if (src.IsValid()) + m_ExternalTransitions.push_back(eastl::make_pair(src, &ParseTransition())); + } else { + qCCritical(INTERNAL_ERROR, "Failed to parse scxml child %s", elemName.c_str() ); + QT3DS_ASSERT(false); + } + } + + FinishParsing(); + return retval; + } +}; + +struct SWriteContext +{ + IDOMWriter &m_Writer; + IStateContext &m_Context; + IStringTable &m_StringTable; + const char8_t *m_CurrentNamespace; + const char8_t *m_Names[SXMLName::LastName]; + eastl::string m_IdStr; + eastl::string m_RefListWorkspace; + IEditor *m_Editor; + MemoryBuffer m_Buffer; + Option m_MousePos; + nvvector m_WrittenNodes; + nvvector m_ExternalTransitions; + + SWriteContext(IDOMWriter &inWriter, IStateContext &inContext, IStringTable &inStrTable, + IEditor *inEditor, NVAllocatorCallback &inAlloc) + : m_Writer(inWriter) + , m_Context(inContext) + , m_StringTable(inStrTable) + , m_CurrentNamespace(GetSCXMLNamespace()) + , m_Editor(inEditor) + , m_Buffer(ForwardingAllocator(inAlloc, "WriteBuffer")) + , m_WrittenNodes(inAlloc, "m_WrittenNodes") + , m_ExternalTransitions(inAlloc, "m_ExternalTransitions") + { +#define HANDLE_XML_ELEMENT_NAME(nm) m_Names[SXMLName::e##nm] = #nm; + ITERATE_XML_ELEMENT_NAMES +#undef HANDLE_XML_ELEMENT_NAME + } + + void GenerateId(SStateNode &inNode, const char8_t *stem) + { + if (inNode.m_Id.IsValid() == false) + CXMLIO::GenerateUniqueId(inNode, stem, m_Context, m_StringTable); + } + + void WriteExtensionElement(SDOMElement &elem) + { + IDOMWriter::Scope _elemScope(m_Writer, elem.m_Name.c_str(), elem.m_Namespace.c_str()); + for (TAttributeList::iterator iter = elem.m_Attributes.begin(), + end = elem.m_Attributes.end(); + iter != end; ++iter) { + SDOMAttribute &theAttribute(*iter); + m_Writer.Att(theAttribute.m_Name, theAttribute.m_Value, + theAttribute.m_Namespace.c_str()); + } + for (SDOMElement::TElementChildList::iterator iter = elem.m_Children.begin(), + end = elem.m_Children.end(); + iter != end; ++iter) { + WriteExtensionElement(elem); + } + if (!isTrivial(elem.m_Value)) { + m_Writer.Value(elem.m_Value); + } + } + + void WriteExtensionData(void *inItem) + { + SItemExtensionInfo *infoPtr = m_Context.GetExtensionInfo(inItem); + if (infoPtr) { + SItemExtensionInfo &theInfo(*infoPtr); + for (TDOMAttributeNodeList::iterator iter = theInfo.m_ExtensionAttributes.begin(), + end = theInfo.m_ExtensionAttributes.end(); + iter != end; ++iter) { + SDOMAttribute &theAttribute(*iter->m_Attribute); + m_Writer.Att(theAttribute.m_Name.c_str(), theAttribute.m_Value, + theAttribute.m_Namespace.c_str()); + } + for (TDOMElementNodeList::iterator iter = theInfo.m_ExtensionNodes.begin(), + end = theInfo.m_ExtensionNodes.end(); + iter != end; ++iter) { + WriteExtensionElement(*iter->m_Element); + } + } + } + + void Att(const char8_t *inName, const char8_t *inData) + { + if (!isTrivial(inData)) + m_Writer.Att(inName, inData, m_CurrentNamespace); + } + + void Att(const char8_t *inName, CRegisteredString inData) + { + if (inData.IsValid()) + m_Writer.Att(inName, inData.c_str(), m_CurrentNamespace); + } + + void Att(const char8_t *inName, NVConstDataRef inData) + { + m_RefListWorkspace.clear(); + for (QT3DSU32 idx = 0, end = inData.size(); idx < end; ++idx) { + if (m_RefListWorkspace.size()) + m_RefListWorkspace.append(" "); + m_RefListWorkspace.append(inData[idx].c_str()); + } + if (m_RefListWorkspace.size()) + Att(inName, m_RefListWorkspace.c_str()); + } + void Att(const char8_t *inName, NVConstDataRef inData) + { + m_RefListWorkspace.clear(); + for (QT3DSU32 idx = 0, end = inData.size(); idx < end; ++idx) { + if (m_RefListWorkspace.size()) + m_RefListWorkspace.append(" "); + if (inData[idx]) + m_RefListWorkspace.append(inData[idx]->m_Id.c_str()); + } + if (m_RefListWorkspace.size()) + Att(inName, m_RefListWorkspace.c_str()); + } + void Att(const char8_t *inName, const QT3DSVec2 &inData) + { + m_Buffer.clear(); + Char8TWriter writer(m_Buffer); + writer.Write(NVConstDataRef(&inData.x, 2)); + m_Buffer.writeZeros(1); + m_Writer.Att(inName, (const char8_t *)m_Buffer.begin(), GetStudioStateNamespace()); + } + + void Att(const char8_t *inName, const QT3DSVec3 &inData) + { + m_Buffer.clear(); + Char8TWriter writer(m_Buffer); + writer.Write(NVConstDataRef(&inData.x, 3)); + m_Buffer.writeZeros(1); + m_Writer.Att(inName, (const char8_t *)m_Buffer.begin(), GetStudioStateNamespace()); + } + + void WriteEditorAttributes(void *inType, bool idId, bool inAdjustPos = false) + { + if (m_Editor) { + TObjPtr editorObj = m_Editor->GetEditor(inType); + if (editorObj != NULL) { + if (idId) { + eastl::string name = editorObj->GetId(); + if (name.empty() == false) + m_Writer.Att("id", name.c_str(), GetStudioStateNamespace()); + } + eastl::string description = editorObj->GetDescription(); + if (description.empty() == false) + m_Writer.Att("description", description.c_str(), GetStudioStateNamespace()); + + Option tempData = editorObj->GetPropertyValue("position"); + if (tempData.hasValue()) { + QT3DSVec2 thePos(tempData->getData()); + if (inAdjustPos && m_MousePos.hasValue()) { + // Get the global pos, not the local position. + for (TObjPtr parentPtr = editorObj->Parent(); parentPtr; + parentPtr = parentPtr->Parent()) { + Option parentPos = parentPtr->GetPropertyValue("position"); + if (parentPos.hasValue()) + thePos += parentPos->getData(); + } + // Store pos in global coords adjusted. + thePos -= *m_MousePos; + } + Att("position", thePos); + } + + tempData = editorObj->GetPropertyValue("dimension"); + if (tempData.hasValue()) + Att("dimension", tempData->getData()); + + tempData = editorObj->GetPropertyValue("color"); + if (tempData.hasValue()) + Att("color", tempData->getData()); + } + } + } + + void WriteSend(SSend &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "send", m_CurrentNamespace); + Att("event", inContent.m_Event); + Att("eventexpr", inContent.m_EventExpr); + Att("target", inContent.m_Target); + Att("targetexpr", inContent.m_TargetExpr); + Att("type", inContent.m_Type); + Att("typeExpr", inContent.m_TypeExpr); + Att("id", inContent.m_Id); + Att("idlocation", inContent.m_IdLocation); + Att("delay", inContent.m_Delay); + Att("delayexpr", inContent.m_DelayExpr); + Att("namelist", inContent.m_NameList); + WriteExecutableContentList(inContent.m_Children); + WriteEditorAttributes(&inContent, false); + WriteExtensionData(&inContent); + } + + void WriteParam(SParam &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "param", m_CurrentNamespace); + Att("name", inContent.m_Name); + + if (!isTrivial(inContent.m_Expr)) + Att("expr", inContent.m_Expr); + else if (!isTrivial(inContent.m_Location)) + Att("location", inContent.m_Location); + + WriteEditorAttributes(&inContent, false); + WriteExtensionData(&inContent); + } + + void WriteContent(SContent &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "content", m_CurrentNamespace); + if (!isTrivial(inContent.m_Expr)) + Att("expr", inContent.m_Expr); + else if (!isTrivial(inContent.m_ContentValue)) + m_Writer.Value(inContent.m_ContentValue); + + WriteEditorAttributes(&inContent, false); + WriteExtensionData(&inContent); + } + + void WriteRaise(SRaise &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "raise", m_CurrentNamespace); + Att("event", inContent.m_Event); + WriteEditorAttributes(&inContent, false); + WriteExtensionData(&inContent); + } + + void WriteAssign(SAssign &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "assign", m_CurrentNamespace); + Att("location", inContent.m_Location); + Att("expr", inContent.m_Expression); + WriteEditorAttributes(&inContent, false); + WriteExtensionData(&inContent); + } + + void WriteIf(SIf &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "if", m_CurrentNamespace); + Att("cond", inContent.m_Cond); + WriteEditorAttributes(&inContent, false); + WriteExecutableContentList(inContent.m_Children); + WriteExtensionData(&inContent); + } + + void WriteElseIf(SElseIf &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "elseif", m_CurrentNamespace); + WriteEditorAttributes(&inContent, false); + Att("cond", inContent.m_Cond); + WriteExtensionData(&inContent); + } + + void WriteElse(SElse &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "else", m_CurrentNamespace); + WriteEditorAttributes(&inContent, false); + WriteExtensionData(&inContent); + } + + void WriteLog(SLog &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "log", m_CurrentNamespace); + WriteEditorAttributes(&inContent, false); + Att("label", inContent.m_Label); + Att("expr", inContent.m_Expression); + WriteExtensionData(&inContent); + } + + void WriteScript(SScript &inContent) + { + IDOMWriter::Scope _itemScope(m_Writer, "script", m_CurrentNamespace); + WriteEditorAttributes(&inContent, false); + if (isTrivial(inContent.m_Data) && !isTrivial(inContent.m_URL)) + Att("src", inContent.m_URL); + else + m_Writer.Value(inContent.m_Data); + WriteExtensionData(&inContent); + } + + void WriteCancel(SCancel &inContent) + { + // Do not serialize invalid cancel items. + if (isTrivial(inContent.m_IdExpression) && inContent.m_Send == NULL) + return; + + IDOMWriter::Scope _itemScope(m_Writer, "cancel", m_CurrentNamespace); + if (!inContent.m_Send && inContent.m_IdExpression) + Att("sendidexpr", inContent.m_IdExpression); + else + Att("sendid", inContent.m_Send->m_Id); + + WriteEditorAttributes(&inContent, true); + WriteExtensionData(&inContent); + } + + void WriteExecutableContent(SExecutableContent &inContent) + { + switch (inContent.m_Type) { + case ExecutableContentTypes::Send: + WriteSend(static_cast(inContent)); + break; + case ExecutableContentTypes::Raise: + WriteRaise(static_cast(inContent)); + break; + case ExecutableContentTypes::Assign: + WriteAssign(static_cast(inContent)); + break; + case ExecutableContentTypes::If: + WriteIf(static_cast(inContent)); + break; + case ExecutableContentTypes::ElseIf: + WriteElseIf(static_cast(inContent)); + break; + case ExecutableContentTypes::Else: + WriteElse(static_cast(inContent)); + break; + case ExecutableContentTypes::Log: + WriteLog(static_cast(inContent)); + break; + case ExecutableContentTypes::Script: + WriteScript(static_cast(inContent)); + break; + case ExecutableContentTypes::Cancel: + WriteCancel(static_cast(inContent)); + break; + case ExecutableContentTypes::Param: + WriteParam(static_cast(inContent)); + break; + case ExecutableContentTypes::Content: + WriteContent(static_cast(inContent)); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + void WriteExecutableContentList(TExecutableContentList &inList) + { + for (TExecutableContentList::iterator contentIter = inList.begin(), + contentEnd = inList.end(); + contentIter != contentEnd; ++contentIter) + WriteExecutableContent(*contentIter); + } + + void WriteOnEntry(SOnEntry &inItem) + { + IDOMWriter::Scope _itemScope(m_Writer, "onentry", m_CurrentNamespace); + WriteEditorAttributes(&inItem, true); + WriteExecutableContentList(inItem.m_ExecutableContent); + WriteExtensionData(&inItem); + } + + void WriteOnEntryList(TOnEntryList &inList) + { + for (TOnEntryList::iterator iter = inList.begin(), end = inList.end(); iter != end; ++iter) + WriteOnEntry(*iter); + } + + void WriteOnExit(SOnExit &inItem) + { + IDOMWriter::Scope _itemScope(m_Writer, "onexit", m_CurrentNamespace); + WriteEditorAttributes(&inItem, true); + WriteExecutableContentList(inItem.m_ExecutableContent); + WriteExtensionData(&inItem); + } + + void WriteOnExitList(TOnExitList &inList) + { + for (TOnExitList::iterator iter = inList.begin(), end = inList.end(); iter != end; ++iter) + WriteOnExit(*iter); + } + + void WriteDataModel(SDataModel &inDataModel) + { + IDOMWriter::Scope _transitionScope(m_Writer, "datamodel", m_CurrentNamespace); + WriteEditorAttributes(&inDataModel, true); + for (TDataList::iterator iter = inDataModel.m_Data.begin(), end = inDataModel.m_Data.end(); + iter != end; ++iter) { + IDOMWriter::Scope _transitionScope(m_Writer, "data", m_CurrentNamespace); + Att("id", iter->m_Id); + Att("expr", iter->m_Expression); + WriteEditorAttributes(&(*iter), true); + WriteExtensionData(&(*iter)); + } + WriteExtensionData(&inDataModel); + } + + static inline SStateNode *FirstValidChild(SState &inNode) + { + for (TStateNodeList::iterator iter = inNode.m_Children.begin(), + end = inNode.m_Children.end(); + iter != end; ++iter) { + switch (iter->m_Type) { + case StateNodeTypes::State: + case StateNodeTypes::Parallel: + case StateNodeTypes::Final: + return iter.m_Obj; + default: + break; + } + } + return NULL; + } + + void WriteState(SState &inNode, bool inAdjustPos) + { + m_WrittenNodes.push_back(&inNode); + IDOMWriter::Scope _transitionScope(m_Writer, "state", m_CurrentNamespace); + GenerateId(inNode, "state"); + Att("id", inNode.m_Id); + WriteEditorAttributes(&inNode, false, inAdjustPos); + if (!isTrivial(inNode.m_InitialExpr)) { + m_Writer.Att("initialexpr", inNode.m_InitialExpr, GetStudioStateNamespace()); + } else if (inNode.m_Initial) { + // First check to see if this could be an attribute + if (inNode.m_Initial->m_ExecutableContent.empty()) { + // Now check if it has one child and if it has only one child and that child is the + // first valid possible child + // then we don't write out the attribute + bool canElideInitial = inNode.m_Initial->m_Target.size() == 0 + || (inNode.m_Initial->m_Target.size() == 1 + && inNode.m_Initial->m_Target[0] == FirstValidChild(inNode)); + if (!canElideInitial) + Att("initial", inNode.m_Initial->m_Target); + } else { + IDOMWriter::Scope _transitionScope(m_Writer, "initial", m_CurrentNamespace); + WriteTransition(*inNode.m_Initial, false); + } + } + WriteOnEntryList(inNode.m_OnEntry); + WriteOnExitList(inNode.m_OnExit); + WriteStateNodeList(inNode.m_Children); + if (inNode.m_DataModel) + WriteDataModel(*inNode.m_DataModel); + WriteExtensionData(&inNode); + } + + void WriteParallel(SParallel &inNode, bool inAdjustPos) + { + m_WrittenNodes.push_back(&inNode); + IDOMWriter::Scope _transitionScope(m_Writer, "parallel", m_CurrentNamespace); + GenerateId(inNode, "parallel"); + Att("id", inNode.m_Id); + WriteEditorAttributes(&inNode, false, inAdjustPos); + WriteOnEntryList(inNode.m_OnEntry); + WriteOnExitList(inNode.m_OnExit); + WriteStateNodeList(inNode.m_Children); + if (inNode.m_DataModel) + WriteDataModel(*inNode.m_DataModel); + WriteExtensionData(&inNode); + } + + void WriteHistory(SHistory &inNode, bool inAdjustPos) + { + m_WrittenNodes.push_back(&inNode); + IDOMWriter::Scope _transitionScope(m_Writer, "history", m_CurrentNamespace); + GenerateId(inNode, "history"); + Att("id", inNode.m_Id); + if (inNode.m_Flags.IsDeep()) + Att("type", "deep"); + WriteEditorAttributes(&inNode, false, inAdjustPos); + if (inNode.m_Transition) + WriteTransition(*inNode.m_Transition, false); + WriteExtensionData(&inNode); + } + void WriteTransitionData(STransition &inNode) + { + Att("event", inNode.m_Event); + Att("cond", inNode.m_Condition); + Att("target", inNode.m_Target); + if (inNode.m_Flags.IsInternal()) + Att("type", "internal"); + WriteEditorAttributes(&inNode, true, false); + if (inNode.m_StateNodeFlags.HasEndPosition()) { + Att("end_position", inNode.m_EndPosition); + } + if (inNode.m_Path.mSize) { + m_Buffer.clear(); + Char8TWriter writer(m_Buffer); + writer.Write( + NVConstDataRef((const QT3DSF32 *)inNode.m_Path.mData, 2 * inNode.m_Path.mSize), + QT3DS_MAX_U32); + m_Buffer.writeZeros(1); + m_Writer.Att("path", (const char8_t *)m_Buffer.begin(), GetStudioStateNamespace()); + } + WriteExecutableContentList(inNode.m_ExecutableContent); + WriteExtensionData(&inNode); + } + void WriteTransition(STransition &inNode, bool /*inAdjustPos*/) + { + IDOMWriter::Scope _transitionScope(m_Writer, "transition", m_CurrentNamespace); + WriteTransitionData(inNode); + } + void WriteExternalTransition(STransition &inNode) + { + if (inNode.m_Parent != NULL) { + IDOMWriter::Scope _transitionScope(m_Writer, "external_transition", + GetStudioStateNamespace()); + m_Writer.Att("source", inNode.m_Parent->m_Id.c_str(), GetStudioStateNamespace()); + WriteTransitionData(inNode); + } else { + QT3DS_ASSERT(false); + } + } + + void WriteFinal(SFinal &inNode, bool inAdjustPos) + { + m_WrittenNodes.push_back(&inNode); + IDOMWriter::Scope _transitionScope(m_Writer, "final", m_CurrentNamespace); + GenerateId(inNode, "history"); + Att("id", inNode.m_Id); + WriteEditorAttributes(&inNode, false, inAdjustPos); + WriteOnEntryList(inNode.m_OnEntry); + WriteOnExitList(inNode.m_OnExit); + WriteExtensionData(&inNode); + } + + void Write(SStateNode &inNode, bool inAdjustPos) + { + switch (inNode.m_Type) { + case StateNodeTypes::State: + WriteState(static_cast(inNode), inAdjustPos); + break; + case StateNodeTypes::Parallel: + WriteParallel(static_cast(inNode), inAdjustPos); + break; + case StateNodeTypes::History: + WriteHistory(static_cast(inNode), inAdjustPos); + break; + case StateNodeTypes::Transition: + WriteTransition(static_cast(inNode), inAdjustPos); + break; + case StateNodeTypes::Final: + WriteFinal(static_cast(inNode), inAdjustPos); + break; + default: + QT3DS_ASSERT(false); + break; + } + } + void WriteStateNodeList(TStateNodeList &inNodeList) + { + for (TStateNodeList::iterator iter = inNodeList.begin(), end = inNodeList.end(); + iter != end; ++iter) { + Write((*iter), false); + } + } + + void Write() + { + SSCXML &item = *m_Context.GetRoot(); + GenerateId(item, "scxml"); + Att("name", item.m_Name); + if (item.m_Flags.IsLateBinding()) + Att("binding", "late"); + Att("version", "1"); + m_Writer.Att("version", SSCXML::GetCurrentVersion(), GetStudioStateNamespace()); + + if (!isTrivial(item.m_InitialExpr)) { + m_Writer.Att("initialexpr", item.m_InitialExpr, GetStudioStateNamespace()); + } else if (item.m_Initial) + Att("initial", item.m_Initial->m_Target); + + WriteStateNodeList(item.m_Children); + if (item.m_DataModel) + WriteDataModel(*item.m_DataModel); + WriteExtensionData(&item); + } + + void CheckTransitionForWrittenNodesList(STransition *transition) + { + if (transition == NULL) + return; + for (QT3DSU32 targetIdx = 0, targetEnd = transition->m_Target.size(); targetIdx < targetEnd; + ++targetIdx) { + if (eastl::find(m_WrittenNodes.begin(), m_WrittenNodes.end(), + transition->m_Target[targetIdx]) + != m_WrittenNodes.end()) { + m_ExternalTransitions.push_back(transition); + return; + } + } + } + + // Not sure the right answer here. I know you can't just blindly work with initials and such + // because you can't create new transitions for them. + void CheckForExternalTransitions(SStateNode &inNode, const eastl::vector &inRoots) + { + switch (inNode.m_Type) { + case StateNodeTypes::SCXML: { + SSCXML &theNode(static_cast(inNode)); + // CheckTransitionForWrittenNodesList( theNode.m_Initial ); + CheckForExternalTransitions(theNode.m_Children, inRoots); + } break; + case StateNodeTypes::State: { + SState &theNode(static_cast(inNode)); + // CheckTransitionForWrittenNodesList( theNode.m_Initial ); + CheckForExternalTransitions(theNode.m_Children, inRoots); + } break; + case StateNodeTypes::Parallel: { + SParallel &theNode(static_cast(inNode)); + CheckForExternalTransitions(theNode.m_Children, inRoots); + } break; + case StateNodeTypes::Final: + break; + case StateNodeTypes::History: { + // CheckTransitionForWrittenNodesList( theNode.m_Transition ); + } break; + case StateNodeTypes::Transition: { + STransition &theNode(static_cast(inNode)); + CheckTransitionForWrittenNodesList(&theNode); + } break; + default: + QT3DS_ASSERT(false); + break; + } + } + + void CheckForExternalTransitions(TStateNodeList &ioList, + const eastl::vector &inRoots) + { + for (TStateNodeList::iterator iter = ioList.begin(), end = ioList.end(); iter != end; + ++iter) { + if (eastl::find(inRoots.begin(), inRoots.end(), &(*iter)) == inRoots.end()) + CheckForExternalTransitions(*iter, inRoots); + } + } + + void WriteFragment(eastl::vector &inRoots, const QT3DSVec2 &inMousePos) + { + m_MousePos = inMousePos; + for (QT3DSU32 idx = 0, end = inRoots.size(); idx < end; ++idx) { + Write(*inRoots[idx], true); + } + if (m_Context.GetRoot()) + CheckForExternalTransitions(*m_Context.GetRoot(), inRoots); + m_CurrentNamespace = GetStudioStateNamespace(); + for (QT3DSU32 idx = 0, end = m_ExternalTransitions.size(); idx < end; ++idx) { + WriteExternalTransition(*m_ExternalTransitions[idx]); + } + } +}; + +// True if child is a descedent of parent. False otherwise. +inline bool IsDescendent(SStateNode &parent, SStateNode &child) +{ + if (&parent == &child) + return false; + if (&parent == child.m_Parent) + return true; + + if (child.m_Parent) + return IsDescendent(parent, *child.m_Parent); + + return false; +} + +template +void GenerateUniqueIdT(TDataType &inNode, const char8_t *inStem, IStateContext &ioContext, + IStringTable &ioStringTable) +{ + QT3DS_ASSERT(inNode.m_Id.IsValid() == false); + inNode.m_Id = + ioStringTable.RegisterStr(DoGenerateUniqueId(inStem, ioContext, ioStringTable).c_str()); + bool insertResult = ioContext.InsertId(inNode.m_Id, &inNode); + QT3DS_ASSERT(insertResult); + (void)insertResult; +} +} + +namespace qt3ds { +namespace state { + + void CXMLIO::GenerateUniqueId(SStateNode &inNode, const char8_t *inStem, + IStateContext &ioContext, IStringTable &ioStringTable) + { + GenerateUniqueIdT(inNode, inStem, ioContext, ioStringTable); + } + + void CXMLIO::GenerateUniqueId(SSend &inNode, const char8_t *inStem, IStateContext &ioContext, + IStringTable &ioStringTable) + { + GenerateUniqueIdT(inNode, inStem, ioContext, ioStringTable); + } + + bool CXMLIO::LoadSCXMLFile(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, + IDOMReader &inReader, IStringTable &inStringTable, + const char8_t *inFilename, IStateContext &outContext, + editor::IEditor *inEditor) + { + // the topmost scxml node is a state, so go from there. + if (AreEqual(inReader.GetElementName().c_str(), "scxml")) { + SParseContext theParseContext(inGraphAllocator, inFnd, inReader, outContext, + inStringTable, inEditor); + outContext.SetRoot(theParseContext.ParseSCXML()); + if (outContext.GetRoot()) { + inFilename = nonNull(inFilename); + outContext.GetRoot()->m_Filename = theParseContext.ToGraphStr(inFilename); + } + return true; + } else { + return false; + } + } + + eastl::pair, CXMLIO::TIdRemapMap> + CXMLIO::LoadSCXMLFragment(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, + IDOMReader &inReader, IStringTable &inStringTable, + IStateContext &ioContext, editor::IEditor &inEditor) + { + if (AreEqual(inReader.GetElementName().c_str(), "scxml_fragment")) { + SParseContext theParseContext(inGraphAllocator, inFnd, inReader, ioContext, + inStringTable, &inEditor); + eastl::vector retval = theParseContext.ParseFragment(); + return eastl::make_pair(retval, theParseContext.m_RemapMap); + } + return eastl::make_pair(eastl::vector(), CXMLIO::TIdRemapMap()); + } + + void CXMLIO::SaveSCXMLFile(IStateContext &inContext, NVFoundationBase &inFnd, + IStringTable &inStringTable, IOutStream &outStream, + editor::IEditor *inEditor) + { + NVScopedRefCounted theFactory = + IDOMFactory::CreateDOMFactory(inFnd.getAllocator(), inStringTable); + NVScopedRefCounted theWriter = + IDOMWriter::CreateDOMWriter(inFnd.getAllocator(), "scxml", inStringTable, + GetSCXMLNamespace()) + .first; + SWriteContext theWriteContext(*theWriter, inContext, inStringTable, inEditor, + inFnd.getAllocator()); + theWriteContext.Write(); + + // Now we actually serialize the data. + eastl::vector thePairs; + thePairs.push_back( + SNamespacePair(inStringTable.RegisterStr(GetSCXMLNamespace()), CRegisteredString())); + thePairs.push_back(SNamespacePair(inStringTable.RegisterStr(GetStudioStateNamespace()), + inStringTable.RegisterStr("Qt3DS"))); + + for (SNamespacePairNode *theNode = inContext.GetFirstNSNode(); theNode; + theNode = theNode->m_NextNode) { + if (AreEqual(theNode->m_Namespace.c_str(), GetSCXMLNamespace()) == false + && AreEqual(theNode->m_Namespace.c_str(), GetStudioStateNamespace()) == false + && theNode->m_Abbreviation.IsValid()) + thePairs.push_back(*theNode); + } + + CDOMSerializer::WriteXMLHeader(outStream); + CDOMSerializer::Write(inFnd.getAllocator(), *theWriter->GetTopElement(), outStream, + inStringTable, toDataRef(thePairs.data(), thePairs.size()), false); + } + + void CXMLIO::FindRoots(NVConstDataRef inObjects, + eastl::vector &outRoots) + { + // Stupid but effective algorithm. + for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { + // Transitions never make it into the root, nor does the top scxml object + if (inObjects[idx]->m_Type == StateNodeTypes::Transition + || inObjects[idx]->m_Type == StateNodeTypes::SCXML) + continue; + SStateNode *newNode(inObjects[idx]); + // Note that re-querying size is important. + bool skip = false; + for (QT3DSU32 existingIdx = 0; existingIdx < outRoots.size() && skip == false; + ++existingIdx) { + SStateNode *existingNode(outRoots[existingIdx]); + if (newNode == existingNode || IsDescendent(*existingNode, *newNode)) + skip = true; + + // If the existing item is a descendent of new node, + // then get the existing item out of the list. + if (IsDescendent(*newNode, *existingNode)) { + // Get the existing item out of the list. + outRoots.erase(outRoots.begin() + existingIdx); + --existingIdx; + } + } + if (!skip) + outRoots.push_back(newNode); + } + } + + eastl::vector CXMLIO::SaveSCXMLFragment( + IStateContext &inContext, NVFoundationBase &inFnd, IStringTable &inStringTable, + IDOMWriter &ioWriter, NVDataRef inObjects, editor::IEditor &inEditor, + const QT3DSVec2 &inMousePos, eastl::vector &outNamespaces) + { + eastl::vector theRoots; + FindRoots(inObjects, theRoots); + NVScopedRefCounted theWriter(ioWriter); + SWriteContext theWriteContext(*theWriter, inContext, inStringTable, &inEditor, + inFnd.getAllocator()); + theWriteContext.WriteFragment(theRoots, inMousePos); + + outNamespaces.push_back( + SNamespacePair(inStringTable.RegisterStr(GetSCXMLNamespace()), CRegisteredString())); + outNamespaces.push_back(SNamespacePair(inStringTable.RegisterStr(GetStudioStateNamespace()), + inStringTable.RegisterStr("Qt3DS"))); + return theRoots; + } + + void CXMLIO::ToEditableXml(IStateContext &inContext, NVFoundationBase &inFnd, + IStringTable &inStringTable, IDOMWriter &ioWriter, + SExecutableContent &inContent, editor::IEditor &inEditor) + { + SWriteContext theWriteContext(ioWriter, inContext, inStringTable, &inEditor, + inFnd.getAllocator()); + theWriteContext.WriteExecutableContent(inContent); + } + + SExecutableContent * + CXMLIO::FromEditableXML(IDOMReader &inReader, NVFoundationBase &inFnd, IStateContext &inContext, + IStringTable &inStringTable, NVAllocatorCallback &inGraphAllocator, + editor::IEditor &inEditor, SStateNode *inStateNodeParent, + SExecutableContent *inExecContentParent) + { + SParseContext theParseContext(inGraphAllocator, inFnd, inReader, inContext, inStringTable, + &inEditor); + TExecutableContentList theContentList; + theParseContext.ParseExecutableContentItem(inStateNodeParent, inExecContentParent, + theContentList); + return &(*theContentList.begin()); + } + + eastl::vector CXMLIO::GetSupportedExecutableContentNames() + { + eastl::vector retval; + NVConstDataRef theBindingList = + SParseContext::GetParseBindings(); + for (QT3DSU32 idx = 0, end = theBindingList.size(); idx < end; ++idx) + retval.push_back( + eastl::string(SXMLName::GetNameForElemName(theBindingList[idx].m_Name))); + return retval; + } +} +} diff --git a/src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.h b/src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.h new file mode 100644 index 00000000..3a639845 --- /dev/null +++ b/src/Runtime/Source/stateapplication/Qt3DSStateXMLIO.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_XML_IO_H +#define QT3DS_STATE_XML_IO_H +#pragma once +#include "Qt3DSState.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/StringTable.h" +#include "foundation/XML.h" +#include "EASTL/map.h" +#include "EASTL/string.h" + +namespace qt3ds { +namespace foundation { + class IDOMReader; + class IDOMWriter; +} +} + +namespace qt3ds { +namespace state { + + struct SExecutableContent; + class CXMLIO + { + public: + typedef eastl::map TIdRemapMap; + + static void GenerateUniqueId(SStateNode &inNode, const char8_t *inStem, + IStateContext &ioContext, IStringTable &ioStringTable); + static void GenerateUniqueId(SSend &inNode, const char8_t *inStem, IStateContext &ioContext, + IStringTable &ioStringTable); + // Load an SCXML file and return the root states + // All states, transitions, and memory used in the graph is allocated using the graph + // allocator. + // This makes freeing the memory much easier because you can just free it by releasing the + // graph + // allocator and you don't have to go object by object. + // Filename is just used as another tag or name on the scxml object. + static bool LoadSCXMLFile(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, + IDOMReader &inReader, IStringTable &inStringTable, + const char8_t *inFilename, IStateContext &outContext, + editor::IEditor *inEditor = NULL); + + // Loading fragments remaps their ids to avoid conflics. Returns the top nodes from the + // scxml graph. + static eastl::pair, TIdRemapMap> + LoadSCXMLFragment(NVAllocatorCallback &inGraphAllocator, NVFoundationBase &inFnd, + IDOMReader &inReader, IStringTable &inStringTable, + IStateContext &ioContext, editor::IEditor &inEditor); + + // We write all the way to file instead of a DOM writer because we have to add xml + // namespaces and those can only + // be added during the actual serialization process. + static void SaveSCXMLFile(IStateContext &inContext, NVFoundationBase &inFnd, + IStringTable &inStringTable, IOutStream &outStream, + editor::IEditor *inEditor = NULL); + + static void FindRoots(NVConstDataRef inObjects, + eastl::vector &outRoots); + + // Returns the roots of the copied list + static eastl::vector + SaveSCXMLFragment(IStateContext &inContext, NVFoundationBase &inFnd, + IStringTable &inStringTable, IDOMWriter &ioWriter, + NVDataRef inObjects, editor::IEditor &inEditor, + const QT3DSVec2 &inMousePos, eastl::vector &outNamespaces); + + static void ToEditableXml(IStateContext &inContext, NVFoundationBase &inFnd, + IStringTable &inStringTable, IDOMWriter &ioWriter, + SExecutableContent &inContent, editor::IEditor &inEditor); + + static SExecutableContent * + FromEditableXML(IDOMReader &inReader, NVFoundationBase &inFnd, IStateContext &inContext, + IStringTable &inStringTable, NVAllocatorCallback &inGraphAllocator, + editor::IEditor &inEditor, SStateNode *inStateNodeParent, + SExecutableContent *inExecContentParent); + + static eastl::vector GetSupportedExecutableContentNames(); + }; +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebugger.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebugger.h new file mode 100644 index 00000000..38a0b74f --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebugger.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_SCENE_GRAPH_DEBUGGER_H +#define QT3DS_SCENE_GRAPH_DEBUGGER_H +#pragma once +#include "Qt3DSStateDebugger.h" +#include "Qt3DSUIADatamodel.h" + +namespace qt3ds { +namespace state { + namespace debugger { + + struct SSGValue; + + struct SSGPropertyChange; + + struct SGElemIdMap + { + void *m_Elem; + const char *m_Id; + }; + + // Persistant item that sticks around and appends some information to the binary file. + // The runtime debugger must exist for the entire time the runtime is running, not just + // during connection because the mapping from element->id only exists at file loading time. + class ISceneGraphRuntimeDebugger : public NVRefCounted, public IDebugStreamListener + { + public: + static const char *GetProtocolName() { return "Scene Graph Debugger"; } + // Nothing is returned if the object isn't connected. The returned value may not be + // valid + // after next GetOrCreateCall, so don't hold on to it. + virtual void MapPresentationId(void *presentation, const char *id) = 0; + virtual void MapElementIds(void *presentation, NVConstDataRef inIds) = 0; + virtual void OnPropertyChanged(void *elem, + NVConstDataRef changes) = 0; + virtual void OnConnection(IDebugOutStream &outStream) = 0; + virtual void BinarySave(IOutStream &stream) = 0; + // Load the main datastructures, although we know the ids are wrong + virtual void BinaryLoad(IInStream &stream, NVDataRef inStringTableData) = 0; + // Remap the presentation element points using id to map old presentation ptr to new + // presentation ptr. + virtual void BinaryLoadPresentation(void *presentation, const char *id, + size_t inElemOffset) = 0; + virtual void EndFrame() = 0; + virtual bool IsConnected() = 0; + + static ISceneGraphRuntimeDebugger &Create(NVFoundationBase &fnd, + IStringTable &strTable); + }; + + class ISceneGraphArchitectDebuggerListener + { + public: + virtual void OnItemsDirty(NVConstDataRef inDirtySet) = 0; + }; + + // The architect debugger only exists when debugging. + class ISceneGraphArchitectDebugger : public NVRefCounted, public IDebugStreamListener + { + public: + virtual void SetListener(ISceneGraphArchitectDebuggerListener *listener) = 0; + // Note that we wrap the att or arg list and the initial values to provide extra + // information. + virtual Q3DStudio::TAttOrArgList GetElementAttributes(app::SAppElement &elem) = 0; + + // These may be empty, so don't expect them. Also they are all string, no registered + // strings + // regardless of the type. + virtual eastl::vector + GetElementAttributeValues(app::SAppElement &elem) = 0; + virtual app::IDatamodel &GetDatamodel() = 0; + + virtual void AttachToStream(IDebugOutStream &inStream) = 0; + + virtual void RefreshData(bool inNeedReloadData) = 0; + + static ISceneGraphArchitectDebugger &Create(qt3ds::app::IDatamodel &inDatamodel); + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerProtocol.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerProtocol.h new file mode 100644 index 00000000..4fea4322 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerProtocol.h @@ -0,0 +1,375 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_SCENE_GRAPH_DEBUGGER_PROTOCOL_H +#define QT3DS_SCENE_GRAPH_DEBUGGER_PROTOCOL_H +#include "Qt3DSSceneGraphDebugger.h" +#include "Qt3DSSceneGraphDebuggerValue.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "foundation/SerializationTypes.h" + +namespace qt3ds { +namespace state { + namespace debugger { + + // These are the datatypes we will communicate information with + static QT3DSU32 GetSceneGraphProtocolVersion() { return 1; } + + struct SValueUpdate + { + QT3DSI32 m_Hash; + SSGValue m_Value; + SValueUpdate(QT3DSI32 h, const SSGValue &v) + : m_Hash(h) + , m_Value(v) + { + } + SValueUpdate() + : m_Hash(0) + { + } + template + void IterateProperties(Listener &inListener) + { + inListener.Handle(m_Hash); + inListener.Handle(m_Value); + }; + }; + + struct SElemUpdate + { + QT3DSU64 m_Elem; + NVDataRef m_Updates; + template + void IterateProperties(Listener &inListener) + { + inListener.Handle(m_Elem); + inListener.HandleRef(m_Updates); + }; + }; + + struct SElemMap + { + QT3DSU64 m_Elem; + CRegisteredString m_Id; + SElemMap() + : m_Elem(0) + { + } + SElemMap(QT3DSU64 ptr, CRegisteredString name) + : m_Elem(ptr) + , m_Id(name) + { + } + + template + void IterateProperties(Listener &inListener) + { + inListener.Handle(m_Elem); + inListener.Handle(m_Id); + } + }; + + struct SIdUpdate + { + QT3DSU64 m_Presentation; + CRegisteredString m_PresentationId; + NVDataRef m_IdUpdates; + + template + void IterateProperties(Listener &inListener) + { + inListener.Handle(m_Presentation); + inListener.Handle(m_PresentationId); + inListener.HandleRef(m_IdUpdates); + } + }; + + struct SSGProtocolMessageTypes + { + enum Enum { + UnknownMessage = 0, + Initialization, + IdUpdate, + ElemUpdate, + Frame, + }; + }; + + // Implemented on runtime side. + struct SSGProtocolWriter + { + IOutStream &m_Stream; + MemoryBuffer<> m_WriteBuffer; + QT3DSU32 m_HighWaterMark; + + SSGProtocolWriter(IOutStream &s, NVAllocatorCallback &alloc, QT3DSU32 highWaterMark = 4096) + : m_Stream(s) + , m_WriteBuffer(ForwardingAllocator(alloc, "WriteBuffer")) + , m_HighWaterMark(highWaterMark) + { + } + + void Handle(QT3DSU64 data) { m_WriteBuffer.write(data); } + + void Handle(QT3DSI32 data) { m_WriteBuffer.write(data); } + + void Handle(CRegisteredString str) + { + QT3DSU32 len = static_cast(strlen(str.c_str()) + 1); + m_WriteBuffer.write(len); + m_WriteBuffer.write(str.c_str(), len); + } + void Handle(SSGValue &value) + { + QT3DSU32 valType = static_cast(value.getType()); + m_WriteBuffer.write(valType); + switch (value.getType()) { + case SGPropertyValueTypes::Float: + m_WriteBuffer.write(value.getData()); + break; + case SGPropertyValueTypes::I32: + m_WriteBuffer.write(value.getData()); + break; + case SGPropertyValueTypes::String: + Handle(value.getData()); + break; + case SGPropertyValueTypes::Elem: + Handle(value.getData()); + break; + case SGPropertyValueTypes::NoSGValue: + break; + default: + QT3DS_ASSERT(false); + } + } + + template + void HandleRef(NVDataRef &ref) + { + m_WriteBuffer.write(ref.size()); + for (QT3DSU32 idx = 0, end = ref.size(); idx < end; ++idx) + Handle(ref[idx]); + } + + template + void Handle(TDataType &dtype) + { + dtype.IterateProperties(*this); + } + + void Flush() + { + if (m_WriteBuffer.size()) { + NVConstDataRef writeData(m_WriteBuffer); + m_Stream.Write(writeData); + m_WriteBuffer.clear(); + } + } + + void CheckBuffer() + { + if (m_WriteBuffer.size() > m_HighWaterMark) + Flush(); + } + + void Write(SIdUpdate &inIdUpdate) + { + m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::IdUpdate); + inIdUpdate.IterateProperties(*this); + Flush(); + } + + void Write(SElemUpdate &inIdUpdate) + { + m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::ElemUpdate); + inIdUpdate.IterateProperties(*this); + CheckBuffer(); + } + + void WriteInitialization() + { + m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::Initialization); + m_WriteBuffer.write(GetSceneGraphProtocolVersion()); + Flush(); + } + void WriteFrame() + { + m_WriteBuffer.write((QT3DSU32)SSGProtocolMessageTypes::Frame); + Flush(); + } + }; + + struct SSGProtocolReader + { + NVConstDataRef m_Message; + SDataReader m_Reader; + IStringTable &m_StringTable; + eastl::vector m_DataBuffer; + eastl::string m_TempString; + QT3DSU32 m_Allocated; + bool m_RestartRead; + SSGProtocolReader(NVConstDataRef msg, IStringTable &strTable) + : m_Message(msg) + , m_Reader(const_cast(msg.begin()), const_cast(msg.end())) + , m_StringTable(strTable) + , m_Allocated(0) + , m_RestartRead(false) + { + } + + SSGProtocolMessageTypes::Enum MessageType() + { + QT3DSU32 data = m_Reader.LoadRef(); + return static_cast(data); + } + + template + Option> AllocateData(size_t size) + { + if (m_RestartRead) + return Empty(); + if (size == 0) + return NVDataRef(); + + QT3DSU32 current = m_Allocated; + QT3DSU32 newAlloc = (QT3DSU32)(size * sizeof(TDataType)); + // 8 byte align + if (newAlloc % 8) + newAlloc += 8 - (newAlloc % 8); + + QT3DSU32 required = current + newAlloc; + + if (required > m_DataBuffer.size()) { + m_RestartRead = true; + m_DataBuffer.resize(required * 2); + return Empty(); + } + TDataType *offset = reinterpret_cast(&m_DataBuffer[current]); + m_Allocated += newAlloc; + return toDataRef(offset, (QT3DSU32)size); + } + + void Handle(QT3DSU64 &data) { data = m_Reader.LoadRef(); } + + void Handle(QT3DSI32 &data) { data = m_Reader.LoadRef(); } + + void Handle(CRegisteredString &str) + { + QT3DSU32 len = m_Reader.LoadRef(); + m_TempString.clear(); + if (len) + m_TempString.assign((const char *)m_Reader.m_CurrentPtr, (size_t)(len - 1)); + m_Reader.m_CurrentPtr += len; + if (m_Reader.m_CurrentPtr > m_Reader.m_EndPtr) + m_Reader.m_CurrentPtr = m_Reader.m_EndPtr; + + str = m_StringTable.RegisterStr(m_TempString.c_str()); + } + + void Handle(SSGValue &value) + { + QT3DSU32 valType = m_Reader.LoadRef(); + switch (valType) { + case SGPropertyValueTypes::Float: + value = SSGValue(m_Reader.LoadRef()); + break; + case SGPropertyValueTypes::I32: + value = SSGValue(m_Reader.LoadRef()); + break; + case SGPropertyValueTypes::String: { + CRegisteredString temp; + Handle(temp); + value = SSGValue(temp); + } break; + case SGPropertyValueTypes::Elem: + value = m_Reader.LoadRef(); + break; + case SGPropertyValueTypes::NoSGValue: + break; + default: + QT3DS_ASSERT(false); + } + } + + template + void HandleRef(NVDataRef &ref) + { + QT3DSU32 numItems = m_Reader.LoadRef(); + Option> refOpt = AllocateData(numItems); + if (refOpt.hasValue()) { + ref = *refOpt; + for (QT3DSU32 idx = 0, end = ref.size(); idx < end && m_RestartRead == false; + ++idx) + Handle(ref[idx]); + } + } + + template + void Handle(TDataType &dtype) + { + dtype.IterateProperties(*this); + } + + template + void DoRead(TDataType &ioValue) + { + QT3DSU8 *startPtr = m_Reader.m_CurrentPtr; + QT3DSU32 restartCount = 0; + do { + m_RestartRead = false; + m_Allocated = 0; + m_Reader.m_CurrentPtr = startPtr; + ioValue.IterateProperties(*this); + ++restartCount; + } while (m_RestartRead); + } + + SIdUpdate ReadIdUpdate() + { + SIdUpdate retval; + DoRead(retval); + return retval; + }; + + SElemUpdate ReadElemUpdate() + { + SElemUpdate retval; + DoRead(retval); + return retval; + }; + + QT3DSU32 ReadInitialization() { return m_Reader.LoadRef(); } + + bool Finished() { return m_Reader.m_CurrentPtr >= m_Reader.m_EndPtr; } + }; + } +} +} +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerValue.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerValue.h new file mode 100644 index 00000000..3b6a4172 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphDebuggerValue.h @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_SCENE_GRAPH_DEBUGGER_VALUE_H +#define QT3DS_SCENE_GRAPH_DEBUGGER_VALUE_H +#include "Qt3DSSceneGraphDebugger.h" +#include "Qt3DSUIADatamodel.h" +#include "Qt3DSUIADatamodelValue.h" +#include "Qt3DSStateEditorValue.h" + +namespace qt3ds { +namespace state { + namespace debugger { + struct SGPropertyValueTypes + { + enum Enum { + NoSGValue = 0, + Float, + I32, + String, + Elem, + }; + }; + + template + struct SGValueTypeMap + { + }; + + template <> + struct SGValueTypeMap + { + static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::Float; } + }; + + template <> + struct SGValueTypeMap + { + static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::I32; } + }; + + template <> + struct SGValueTypeMap + { + static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::String; } + }; + + template <> + struct SGValueTypeMap + { + static SGPropertyValueTypes::Enum GetType() { return SGPropertyValueTypes::Elem; } + }; + + struct SSGValueUnionTraits + { + typedef SGPropertyValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(QT3DSU64), + }; + + static TIdType getNoDataId() { return SGPropertyValueTypes::NoSGValue; } + + template + static TIdType getType() + { + return SGValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case SGPropertyValueTypes::Float: + return inVisitor(*NVUnionCast(inData)); + case SGPropertyValueTypes::I32: + return inVisitor(*NVUnionCast(inData)); + case SGPropertyValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case SGPropertyValueTypes::Elem: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case SGPropertyValueTypes::NoSGValue: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case SGPropertyValueTypes::Float: + return inVisitor(*NVUnionCast(inData)); + case SGPropertyValueTypes::I32: + return inVisitor(*NVUnionCast(inData)); + case SGPropertyValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case SGPropertyValueTypes::Elem: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case SGPropertyValueTypes::NoSGValue: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SSGValueUnionTraits::TBufferSize> + TSGValueUnionType; + + struct SSGValue : public TSGValueUnionType + { + SSGValue() {} + SSGValue(const SSGValue &other) + : TSGValueUnionType(static_cast(other)) + { + } + SSGValue(float val) + : TSGValueUnionType(val) + { + } + SSGValue(QT3DSI32 val) + : TSGValueUnionType(val) + { + } + SSGValue(CRegisteredString val) + : TSGValueUnionType(val) + { + } + SSGValue(QT3DSU64 val) + : TSGValueUnionType(val) + { + } + + SSGValue &operator=(const SSGValue &other) + { + TSGValueUnionType::operator=(static_cast(other)); + return *this; + } + }; + + struct SSGPropertyChange + { + QT3DSI32 m_Hash; + SSGValue m_Value; + SSGPropertyChange(QT3DSI32 h, const SSGValue &v) + : m_Hash(h) + , m_Value(v) + { + } + SSGPropertyChange() + : m_Hash(0) + { + } + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphRuntimeDebugger.cpp b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphRuntimeDebugger.cpp new file mode 100644 index 00000000..403fb580 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSSceneGraphRuntimeDebugger.cpp @@ -0,0 +1,345 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSSceneGraphDebugger.h" +#include "Qt3DSSceneGraphDebuggerValue.h" +#include "Qt3DSSceneGraphDebuggerProtocol.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "EASTL/sort.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::debugger; + +namespace { + +typedef eastl::pair TElemStringHandlePair; + +struct SRegisteredIDComparator +{ + bool operator()(const TElemStringHandlePair &lhs, const TElemStringHandlePair &rhs) const + { + return lhs.first < rhs.first; + } +}; + +struct SPresentationIdMap +{ + void *m_Presentation; + CRegisteredString m_PresentationId; + nvvector m_RegisteredIdBackingStore; + NVDataRef m_RegisteredIds; + SPresentationIdMap(NVAllocatorCallback &alloc) + : m_RegisteredIdBackingStore(alloc, "registered ids") + { + } +}; + +struct RuntimeDebuggerImpl : public ISceneGraphRuntimeDebugger +{ + NVFoundationBase &m_Foundation; + IStringTable &m_StringTable; + NVScopedRefCounted m_OutStream; + nvvector m_ElemMapBuffer; + nvvector m_PresentationIdMap; + nvvector m_ValueUpdates; + // Filter mechanism so we don't send the same thing twice. + nvhash_map> m_LastUpdates; + SSGProtocolWriter *m_Writer; + SSAutoDeallocatorAllocator m_DataAllocator; + nvhash_map m_ElemToNameMap; + QT3DSI32 mRefCount; + + RuntimeDebuggerImpl(NVFoundationBase &fnd, IStringTable &strt) + : m_Foundation(fnd) + , m_StringTable(strt) + , m_ElemMapBuffer(fnd.getAllocator(), "elem map buffer") + , m_PresentationIdMap(fnd.getAllocator(), "Presentations") + , m_ValueUpdates(fnd.getAllocator(), "Value updates") + , m_LastUpdates(fnd.getAllocator(), "Last updates") + , m_Writer(NULL) + , m_DataAllocator(fnd) + , m_ElemToNameMap(fnd.getAllocator(), "ElemToNameMap") + , mRefCount(0) + { + } + + ~RuntimeDebuggerImpl() + { + Disconnect(); + for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) + delete m_PresentationIdMap[idx]; + // the auto-deallocator takes care of the load data. + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + void Disconnect() + { + if (m_Writer) + delete m_Writer; + m_Writer = NULL; + } + + bool CheckConnection() + { + if (m_OutStream) { + bool connected = m_OutStream->Connected(); + if (!connected) + Disconnect(); + + return connected; + } + return false; + } + + void MapPresentationId(void *presentation, const char *id) override + { + CRegisteredString newId = m_StringTable.RegisterStr(nonNull(id)); + for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) { + if (m_PresentationIdMap[idx]->m_Presentation == presentation) { + m_PresentationIdMap[idx]->m_PresentationId = newId; + return; + } + } + + SPresentationIdMap *map = new SPresentationIdMap(m_Foundation.getAllocator()); + map->m_Presentation = presentation; + map->m_PresentationId = newId; + m_PresentationIdMap.push_back(map); + } + + void SendElemIdMap(SPresentationIdMap &map) + { + if (m_ElemMapBuffer.size() && CheckConnection()) { + SIdUpdate theUpdate; + theUpdate.m_Presentation = (QT3DSU64)map.m_Presentation; + theUpdate.m_PresentationId = map.m_PresentationId; + theUpdate.m_IdUpdates = m_ElemMapBuffer; + m_Writer->Write(theUpdate); + } + m_ElemMapBuffer.clear(); + } + + void MapElementIds(void *presentation, NVConstDataRef inIds) override + { + SPresentationIdMap *map = NULL; + for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end && map == NULL; ++idx) + if (m_PresentationIdMap[idx]->m_Presentation == presentation) + map = m_PresentationIdMap[idx]; + if (map == NULL) { + QT3DS_ASSERT(false); + return; + } + m_ElemMapBuffer.clear(); + m_ElemToNameMap.clear(); + for (QT3DSU32 idx = 0, end = inIds.size(); idx < end; ++idx) { + const SGElemIdMap &item(inIds[idx]); + SElemMap newMap; + newMap.m_Elem = (QT3DSU64)item.m_Elem; + CStringHandle idHandle = m_StringTable.GetHandle(nonNull(item.m_Id)); + newMap.m_Id = m_StringTable.HandleToStr(idHandle); + m_ElemMapBuffer.push_back(newMap); + m_ElemToNameMap[item.m_Elem] = idHandle; + } + SendElemIdMap(*map); + + // store them for later. + map->m_RegisteredIdBackingStore.reserve(m_ElemToNameMap.size()); + for (nvhash_map::iterator iter = m_ElemToNameMap.begin(), + end = m_ElemToNameMap.end(); + iter != end; ++iter) { + map->m_RegisteredIdBackingStore.push_back( + eastl::make_pair((QT3DSU64)iter->first, iter->second)); + } + + eastl::sort(map->m_RegisteredIdBackingStore.begin(), map->m_RegisteredIdBackingStore.end(), + SRegisteredIDComparator()); + + map->m_RegisteredIds = NVDataRef( + map->m_RegisteredIdBackingStore.data(), (QT3DSU32)map->m_RegisteredIdBackingStore.size()); + } + + static bool Equals(const SValueUpdate &lhs, const SValueUpdate &rhs) + { + return lhs.m_Hash == rhs.m_Hash && lhs.m_Value == rhs.m_Value; + } + + void OnPropertyChanged(void *elem, NVConstDataRef changes) override + { + if (CheckConnection() == false) + return; + eastl::vector &updates = m_LastUpdates[elem]; + updates.resize(changes.size()); + for (QT3DSU32 changeIdx = 0, changeEnd = changes.size(); changeIdx < changeEnd; ++changeIdx) { + SValueUpdate theUpdate; + theUpdate.m_Hash = changes[changeIdx].m_Hash; + theUpdate.m_Value = changes[changeIdx].m_Value; + if (Equals(theUpdate, updates[changeIdx]) == false) { + updates[changeIdx] = theUpdate; + m_ValueUpdates.push_back(theUpdate); + } + } + if (m_ValueUpdates.size()) { + SElemUpdate theUpdate; + theUpdate.m_Elem = (QT3DSU64)elem; + theUpdate.m_Updates = m_ValueUpdates; + m_Writer->Write(theUpdate); + m_ValueUpdates.clear(); + } + } + + void SendPresentation(SPresentationIdMap &pres) + { + if (m_OutStream) { + m_ElemMapBuffer.clear(); + for (TElemStringHandlePair *iter = pres.m_RegisteredIds.begin(), + *end = pres.m_RegisteredIds.end(); + iter != end; ++iter) { + SElemMap newMap; + newMap.m_Elem = (QT3DSU64)iter->first; + newMap.m_Id = m_StringTable.HandleToStr(iter->second); + m_ElemMapBuffer.push_back(newMap); + } + SendElemIdMap(pres); + } + } + + void OnConnection(IDebugOutStream &outStream) override + { + Disconnect(); + m_OutStream = outStream; + m_Writer = new SSGProtocolWriter(outStream, m_Foundation.getAllocator()); + m_Writer->WriteInitialization(); + for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) { + SPresentationIdMap *map = m_PresentationIdMap[idx]; + SendPresentation(*map); + } + } + + bool IsConnected() override { return CheckConnection(); } + + void BinarySave(IOutStream &ioStream) override + { + qt3ds::foundation::SWriteBuffer theWriteBuffer(m_Foundation.getAllocator(), + "BinarySave::writebuffer"); + + theWriteBuffer.writeZeros(4); // Overall binary size + theWriteBuffer.write((QT3DSU32)m_PresentationIdMap.size()); + for (QT3DSU32 idx = 0, end = m_PresentationIdMap.size(); idx < end; ++idx) { + // There is no use to writing out the presentation pointer address. + /* + void* + m_Presentation; + CRegisteredString m_PresentationId; + nvhash_map m_RegisteredIds; + */ + + SPresentationIdMap *map = m_PresentationIdMap[idx]; + CRegisteredString presId(map->m_PresentationId); + presId.Remap(m_StringTable.GetRemapMap()); + theWriteBuffer.write(presId); + theWriteBuffer.write((QT3DSU32)map->m_RegisteredIds.size()); + theWriteBuffer.write(map->m_RegisteredIds.begin(), map->m_RegisteredIds.size()); + } + + QT3DSU32 totalSize = theWriteBuffer.size(); + QT3DSU32 *data = (QT3DSU32 *)theWriteBuffer.begin(); + data[0] = totalSize - 4; + ioStream.Write((QT3DSU8 *)data, totalSize); + } + + void BinaryLoad(IInStream &ioStream, NVDataRef strTableData) override + { + QT3DSU32 length; + ioStream.Read(length); + QT3DSU8 *data = (QT3DSU8 *)m_DataAllocator.allocate(length, "Binaryload", __FILE__, __LINE__); + ioStream.Read(data, length); + SDataReader theReader(data, data + length); + QT3DSU32 numPresentations = theReader.LoadRef(); + QT3DS_ASSERT(m_PresentationIdMap.size() == 0); + m_PresentationIdMap.resize(numPresentations); + for (QT3DSU32 idx = 0, end = numPresentations; idx < end; ++idx) { + m_PresentationIdMap[idx] = new SPresentationIdMap(m_Foundation.getAllocator()); + SPresentationIdMap *map = m_PresentationIdMap[idx]; + map->m_PresentationId = theReader.LoadRef(); + map->m_PresentationId.Remap(strTableData); + QT3DSU32 numElems = theReader.LoadRef(); + map->m_RegisteredIds = + toDataRef((TElemStringHandlePair *)theReader.m_CurrentPtr, numElems); + theReader.m_CurrentPtr += numElems * sizeof(TElemStringHandlePair); + } + } + + void BinaryLoadPresentation(void *presPtr, const char *id, size_t elemOffset) override + { + CRegisteredString presId(m_StringTable.RegisterStr(id)); + SPresentationIdMap *foundPres = NULL; + for (QT3DSU32 idx = 0, end = (QT3DSU32)m_PresentationIdMap.size(); idx < end && foundPres == NULL; + ++idx) { + if (m_PresentationIdMap[idx]->m_PresentationId == presId) + foundPres = m_PresentationIdMap[idx]; + } + if (foundPres == NULL) { + QT3DS_ASSERT(false); + return; + } + + foundPres->m_Presentation = presPtr; + nvvector> newElemIds(m_Foundation.getAllocator(), + "Temp load map"); + newElemIds.reserve(foundPres->m_RegisteredIds.size()); + for (TElemStringHandlePair *iter = foundPres->m_RegisteredIds.begin(), + *end = foundPres->m_RegisteredIds.end(); + iter != end; ++iter) { + size_t oldId = (size_t)iter->first; + size_t newId = elemOffset + oldId; + iter->first = (QT3DSU64)newId; + } + SendPresentation(*foundPres); + } + + void EndFrame() override + { + if (CheckConnection()) + m_Writer->WriteFrame(); + } + + void OnMessageReceived(const SDebugStreamMessage &) override { QT3DS_ASSERT(false); } +}; +} + +ISceneGraphRuntimeDebugger &ISceneGraphRuntimeDebugger::Create(NVFoundationBase &fnd, + IStringTable &strTable) +{ + return *QT3DS_NEW(fnd.getAllocator(), RuntimeDebuggerImpl)(fnd, strTable); +} diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDataTest.cpp b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDataTest.cpp new file mode 100644 index 00000000..ced1397b --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDataTest.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateTest.h" +#include "foundation/IOStreams.h" +#include "EASTL/string.h" +#include "foundation/Utils.h" +#include "foundation/FileTools.h" +#include "foundation/XML.h" +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/TrackingAllocator.h" +#include "foundation/StringTable.h" +#include "Qt3DSStateContext.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "Qt3DSStateExecutionContext.h" +#include "Qt3DSStateInterpreter.h" + +using namespace qt3ds::state::test; +using namespace qt3ds::state; + +namespace { + +struct XMLHandler : public qt3ds::foundation::CXmlErrorHandler +{ + IDataLogger &m_Logger; + const char8_t *m_File; + eastl::string m_ErrorString; + XMLHandler(IDataLogger &logger, const char8_t *fname) + : m_Logger(logger) + , m_File(fname) + { + } + + void OnXmlError(qt3ds::foundation::TXMLCharPtr errorName, int line, int /*column*/) override + { + m_ErrorString.assign("Failed to parse test file: "); + m_ErrorString.append(m_File); + m_Logger.Log(LogType::Error, m_File, line, errorName); + } +}; + +Option RunTest(const char8_t *inFullPath, const char8_t *inRoot, + IDataLogger &inLogger) +{ + return STestResults(1, 1); +} +} + +Option IDataTest::RunFile(const char8_t *fname, const char8_t *inRootDir, + IDataLogger &inLogger) +{ + return RunTest(fname, inRootDir, inLogger); +} diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.cpp b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.cpp new file mode 100644 index 00000000..707ea73e --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.cpp @@ -0,0 +1,534 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateDebugStreams.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSMutex.h" +#include "foundation/Qt3DSSync.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "EASTL/string.h" + +using namespace qt3ds; +using namespace qt3ds::state; +using namespace qt3ds::state::debugger; + +namespace { + +struct MultiProtocolMessageTypes +{ + enum Enum { + UnknownMessageType = 0, + NewProtocol = 1, + ProtocolMessage = 1 << 2, + }; +}; + +struct SMultiProtocolMessageFlags : public NVFlags +{ + bool IsNewProtocol() { return this->operator&(MultiProtocolMessageTypes::NewProtocol); } + void SetNewProtocol(bool inValue) + { + this->clearOrSet(inValue, MultiProtocolMessageTypes::NewProtocol); + } + + bool IsProtocolMessage() { return this->operator&(MultiProtocolMessageTypes::ProtocolMessage); } + void SetProtocolMessage(bool inValue) + { + this->clearOrSet(inValue, MultiProtocolMessageTypes::ProtocolMessage); + } +}; + +struct SMultiProtocolInitializer +{ + static QT3DSU16 GetCurrentMultiProtocolVersion() { return 1; } + + QT3DSU64 m_TimeNumerator; + QT3DSU64 m_TimeDenominator; + QT3DSU32 m_ProtocolVersion; + + SMultiProtocolInitializer() + : m_TimeNumerator(Time::sCounterFreq.mNumerator) + , m_TimeDenominator(Time::sCounterFreq.mDenominator) + , m_ProtocolVersion(GetCurrentMultiProtocolVersion()) + { + } +}; + +struct SMultiProtocolMessageHeader +{ + + SMultiProtocolMessageFlags m_Flags; + QT3DSU32 m_Size; + QT3DSU32 m_ProtocolId; + QT3DSU64 m_Timestamp; + SMultiProtocolMessageHeader(MultiProtocolMessageTypes::Enum inMessageType, QT3DSU32 size, + QT3DSU32 protocolId, QT3DSU64 timestamp) + : m_Size(size) + , m_ProtocolId(protocolId) + , m_Timestamp(timestamp) + { + m_Flags.clearOrSet(true, inMessageType); + } + SMultiProtocolMessageHeader() {} +}; + +struct IProtocolMessageHandler +{ +protected: + virtual ~IProtocolMessageHandler() {} +public: + virtual void OnMessageReceived(SDebugStreamMessage msgData) = 0; +}; + +struct IProtocolHandler +{ +protected: + virtual ~IProtocolHandler() {} +public: + virtual void OnNewProtocol(CRegisteredString inProtocolName) = 0; +}; + +struct SSharedStreamImpl : public NVRefCounted +{ + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_Stream; + IOutStream &m_WriteStream; + SMultiProtocolInitializer m_Initializer; + eastl::hash_map m_ProtocolIdMap; + eastl::hash_map m_MessageHandlers; + MemoryBuffer<> m_ReadBuffer; + IStringTable &m_StringTable; + IProtocolHandler *m_ProtocolHandler; + QT3DSU32 m_NextProtocolId; + QT3DSI32 mRefCount; + + SSharedStreamImpl(NVFoundationBase &fnd, SocketStream &stream, IOutStream &writeStream, + IStringTable &strTable, IProtocolHandler &pHandler) + : m_Foundation(fnd) + , m_Stream(stream) + , m_WriteStream(writeStream) + , m_ReadBuffer(ForwardingAllocator(fnd.getAllocator(), "ReadBuffer")) + , m_StringTable(strTable) + , m_ProtocolHandler(&pHandler) + , m_NextProtocolId(1) + , mRefCount(0) + { + NVConstDataRef msgData = toU8DataRef(m_Initializer); + bool streamValid = m_Stream->Write(msgData); + if (streamValid == false) + m_Stream = NULL; + } + ~SSharedStreamImpl() {} + + bool Initialize() + { + if (m_Stream) { + NVDataRef msgData = toU8DataRef(m_Initializer); + QT3DSU32 numBytes = m_Stream->Read(msgData); + if (numBytes != sizeof(SMultiProtocolInitializer) + || m_Initializer.m_ProtocolVersion + > SMultiProtocolInitializer::GetCurrentMultiProtocolVersion()) { + m_Stream = NULL; + return false; + } + return true; + } + return false; + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + QT3DSU32 GetIdForProtocol(CRegisteredString protocol) + { + if (protocol.IsValid() == false) + return 0; + eastl::pair::iterator, bool> inserter = + m_ProtocolIdMap.insert(eastl::make_pair(protocol, m_NextProtocolId)); + if (inserter.second) { + QT3DSU32 newId = m_NextProtocolId; + ++m_NextProtocolId; + if (m_Stream) { + QT3DSU32 msgLen = (QT3DSU32)strlen(protocol) + 1; + NVConstDataRef writeBuf(reinterpret_cast(protocol.c_str()), + msgLen); + WriteMessage(MultiProtocolMessageTypes::NewProtocol, writeBuf, newId); + } + } + return inserter.first->second; + } + + CRegisteredString GetProtocolForId(QT3DSU32 id) + { + for (eastl::hash_map::iterator iter = m_ProtocolIdMap.begin(), + end = m_ProtocolIdMap.end(); + iter != end; ++iter) { + if (iter->second == id) + return iter->first; + } + return CRegisteredString(); + } + + void AddMessageHandler(CRegisteredString protocol, IProtocolMessageHandler &hdl) + { + m_MessageHandlers.insert(eastl::make_pair(GetIdForProtocol(protocol), &hdl)); + } + + void RemoveMessageHandler(CRegisteredString protocol) + { + m_MessageHandlers.erase(GetIdForProtocol(protocol)); + } + + IProtocolMessageHandler *GetMessageHandler(CRegisteredString protocol) + { + return GetMessageHandler(GetIdForProtocol(protocol)); + } + + IProtocolMessageHandler *GetMessageHandler(QT3DSU32 protocolId) + { + eastl::hash_map::iterator iter = + m_MessageHandlers.find(protocolId); + if (iter != m_MessageHandlers.end()) + return iter->second; + return NULL; + } + + void ProtocolHandlerLeaving() { m_ProtocolHandler = NULL; } + + void DispatchMessage(SMultiProtocolMessageHeader inHeader, NVConstDataRef msg) + { + if (inHeader.m_Flags.IsNewProtocol()) { + char *pId = reinterpret_cast(const_cast(msg.begin())); + // Ensure null terminated, which should be done anyway but we don't know it will be. + pId[inHeader.m_Size] = 0; + CRegisteredString protocolName = m_StringTable.RegisterStr(pId); + eastl::pair::iterator, bool> inserter = + m_ProtocolIdMap.insert(eastl::make_pair(protocolName, inHeader.m_ProtocolId)); + if (inserter.second == false) { + // remap id to higher id to reduce the chance of conflicts. + QT3DSU32 potentialNewId = NVMax(inserter.first->second, inHeader.m_ProtocolId); + if (potentialNewId != inserter.first->second) { + m_NextProtocolId = NVMax(m_NextProtocolId, potentialNewId + 1); + CRegisteredString existing = GetProtocolForId(potentialNewId); + if (existing.IsValid()) { + m_ProtocolIdMap.erase(protocolName); + GetIdForProtocol(protocolName); + return; + } else { + inserter.first->second = potentialNewId; + } + } + } else { + if (m_ProtocolHandler != NULL) { + m_ProtocolHandler->OnNewProtocol(protocolName); + } + } + } else { + IProtocolMessageHandler *handler = GetMessageHandler(inHeader.m_ProtocolId); + if (handler != NULL) + handler->OnMessageReceived(SDebugStreamMessage(inHeader.m_Timestamp, msg)); + } + } + + NVDataRef ReadChunk(NVDataRef target) + { + QT3DSU32 totalRead = 0; + do { + NVDataRef nextBuf(target.begin() + totalRead, target.size() - totalRead); + QT3DSU32 readResult = m_Stream->Read(nextBuf); + totalRead += readResult; + if (totalRead < target.size()) { + totalRead = totalRead; + } + } while (connected() && totalRead < target.size()); + + return toDataRef(m_ReadBuffer.begin(), totalRead); + } + + NVDataRef ReadChunk(QT3DSU32 size) + { + m_ReadBuffer.reserve(size); + return ReadChunk(toDataRef(m_ReadBuffer.begin(), size)); + } + + virtual SDebugStreamMessage WaitForNextMessage(CRegisteredString protocol) + { + QT3DSU32 msgId = GetIdForProtocol(protocol); + + while (m_Stream) { + SMultiProtocolMessageHeader header; + NVDataRef buf = toU8DataRef(header); + buf = ReadChunk(buf); + if (buf.size() < sizeof(header)) { + m_Stream = NULL; + QT3DS_ASSERT(false); + } else { + NVDataRef readResult = ReadChunk(header.m_Size); + if (readResult.mSize != header.m_Size) { + m_Stream = NULL; + QT3DS_ASSERT(false); + } else { + if (header.m_ProtocolId == msgId) { + SDebugStreamMessage message; + message.m_Timestamp = header.m_Timestamp; + message.m_Data = readResult; + return message; + } else + DispatchMessage(header, readResult); + } + } + } + + return SDebugStreamMessage(); + } + + virtual void MessagePump() + { + if (m_Stream == NULL) + return; + bool lastMessage = true; + do { + SMultiProtocolMessageHeader header; + NVDataRef buf = toU8DataRef(header); + QT3DSU32 amountRead = m_Stream->nonBlockingRead(buf); + if (amountRead == 0) { + if (m_Stream->connected() == false) + m_Stream = NULL; + lastMessage = false; + } else { + // read the rest of the header. + QT3DSU32 leftover = buf.size() - amountRead; + if (leftover) { + NVDataRef nextPiece(buf.begin() + amountRead, leftover); + nextPiece = ReadChunk(nextPiece); + amountRead += nextPiece.size(); + } + + if (amountRead < sizeof(SMultiProtocolMessageHeader)) { + m_Stream = NULL; + QT3DS_ASSERT(false); + + } else { + NVDataRef msgData = ReadChunk(header.m_Size); + if (msgData.size() == header.m_Size) { + DispatchMessage(header, msgData); + } else { + m_Stream = NULL; + QT3DS_ASSERT(false); + } + } + } + + } while (lastMessage && m_Stream); + } + + SMultiProtocolMessageHeader CreateHeader(MultiProtocolMessageTypes::Enum type, QT3DSU32 size, + QT3DSU32 protocolId) + { + SMultiProtocolMessageHeader retval; + retval.m_Flags.clearOrSet(true, type); + retval.m_ProtocolId = protocolId; + retval.m_Size = size; + retval.m_Timestamp = Time::getCurrentCounterValue(); + return retval; + } + + bool WriteMessage(MultiProtocolMessageTypes::Enum type, NVConstDataRef data, + QT3DSU32 protocolId) + { + if (connected()) { + SMultiProtocolMessageHeader header(CreateHeader(type, data.size(), protocolId)); + NVConstDataRef writeBuf = toU8DataRef(header); + bool success = m_WriteStream.Write(writeBuf); + if (success) { + success = m_WriteStream.Write(data); + } + if (!success) + m_Stream = NULL; + return success; + } + return false; + } + + virtual bool Write(CRegisteredString protocol, NVConstDataRef data) + { + return WriteMessage(MultiProtocolMessageTypes::ProtocolMessage, data, + GetIdForProtocol(protocol)); + } + + bool connected() { return m_Stream != NULL && m_Stream->connected(); } +}; + +struct SMultiProtocolSocketStreamImpl : public IMultiProtocolSocketStream, + public IProtocolMessageHandler +{ + NVFoundationBase &m_Foundation; + CRegisteredString m_Protocol; + IDebugStreamListener *m_Listener; + NVScopedRefCounted m_SharedStream; + bool m_StreamValid; + QT3DSI32 mRefCount; + + SMultiProtocolSocketStreamImpl(NVFoundationBase &fnd, CRegisteredString protocol, + IDebugStreamListener *listener, SSharedStreamImpl &stream) + : m_Foundation(fnd) + , m_Protocol(protocol) + , m_Listener(listener) + , m_SharedStream(stream) + , m_StreamValid(true) + , mRefCount(0) + { + m_SharedStream->AddMessageHandler(m_Protocol, *this); + } + + ~SMultiProtocolSocketStreamImpl() { m_SharedStream->RemoveMessageHandler(m_Protocol); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + IDebugStreamListener *GetListener() override { return m_Listener; } + CRegisteredString GetProtocolName() override { return m_Protocol; } + + void SetListener(IDebugStreamListener *listener) override { m_Listener = listener; } + + bool Write(NVConstDataRef data) override + { + if (m_StreamValid) + m_StreamValid = m_SharedStream->Write(m_Protocol, data); + + return m_StreamValid; + } + + SDebugStreamMessage WaitForNextMessage() override + { + if (m_StreamValid) + return m_SharedStream->WaitForNextMessage(m_Protocol); + return SDebugStreamMessage(); + } + + void OnMessageReceived(SDebugStreamMessage data) override + { + if (m_Listener) + m_Listener->OnMessageReceived(data); + } + + bool Connected() override { return m_SharedStream->connected(); } +}; + +struct SMultiProtocolSocketImpl : public IMultiProtocolSocket, public IProtocolHandler +{ + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_SharedStream; + NVScopedRefCounted m_ProtocolListener; + QT3DSI32 mRefCount; + SMultiProtocolSocketImpl(NVFoundationBase &fnd, SocketStream &inStream, IStringTable &strTable, + IMultiProtocolSocketListener *protocolListener) + : m_Foundation(fnd) + , m_ProtocolListener(protocolListener) + , mRefCount(0) + { + // At some point I may switch the writer to a buffered stream, at least on the client side. + m_SharedStream = QT3DS_NEW(m_Foundation.getAllocator(), SSharedStreamImpl)( + m_Foundation, inStream, inStream, strTable, *this); + } + + ~SMultiProtocolSocketImpl() { m_SharedStream->ProtocolHandlerLeaving(); } + + bool Initialize() override { return m_SharedStream->Initialize(); } + + bool Connected() override { return m_SharedStream->connected(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + + virtual NVScopedRefCounted + CreateProtocol(const char *name, IDebugStreamListener *inListener) override + { + NVScopedRefCounted retval = GetProtocol(name); + if (retval) { + QT3DS_ASSERT(false); + return retval; + } + CRegisteredString protocolName = m_SharedStream->m_StringTable.RegisterStr(name); + if (protocolName.IsValid() == false) { + QT3DS_ASSERT(false); + return retval; + } + SMultiProtocolSocketStreamImpl *newStream = + QT3DS_NEW(m_Foundation.getAllocator(), SMultiProtocolSocketStreamImpl)( + m_Foundation, protocolName, inListener, *m_SharedStream); + return newStream; + } + + NVScopedRefCounted GetProtocol(const char *name) override + { + CRegisteredString protocolName = m_SharedStream->m_StringTable.RegisterStr(name); + IProtocolMessageHandler *handler = m_SharedStream->GetMessageHandler(protocolName); + if (handler) { + SMultiProtocolSocketStreamImpl *theImpl = + static_cast(handler); + return theImpl; + } + return NVScopedRefCounted(); + } + + void OnNewProtocol(CRegisteredString inProtocolName) override + { + if (m_ProtocolListener) { + // We can expect the user to call create protocol at this point. + IDebugStreamListener *handler = m_ProtocolListener->OnNewProtocol(inProtocolName); + if (handler) { + SMultiProtocolSocketStreamImpl *newStream = + QT3DS_NEW(m_Foundation.getAllocator(), SMultiProtocolSocketStreamImpl)( + m_Foundation, inProtocolName, handler, *m_SharedStream); + m_ProtocolListener->OnNewProtocolStream(inProtocolName, *newStream); + } + } + } + + CounterFrequencyToTensOfNanos SourceConversion() override + { + return CounterFrequencyToTensOfNanos(m_SharedStream->m_Initializer.m_TimeNumerator, + m_SharedStream->m_Initializer.m_TimeDenominator); + } + + void MessagePump() override { m_SharedStream->MessagePump(); } +}; +} + +NVScopedRefCounted +IMultiProtocolSocket::CreateProtocolSocket(NVFoundationBase &fnd, SocketStream &inStream, + IStringTable &strTable, + IMultiProtocolSocketListener *protocolListener) +{ + return QT3DS_NEW(fnd.getAllocator(), SMultiProtocolSocketImpl)(fnd, inStream, strTable, + protocolListener); +} + diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.h new file mode 100644 index 00000000..5bbc0b26 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugStreams.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_DEBUG_STREAMS_H +#define QT3DS_STATE_DEBUG_STREAMS_H +#pragma once +#include "Qt3DSState.h" +#include "foundation/Socket.h" +#include "foundation/Qt3DSTime.h" +#include "Qt3DSStateDebugger.h" + +struct script_State; + +namespace qt3ds { +namespace state { + namespace debugger { + + class IMultiProtocolSocketStream : public IDebugOutStream + { + public: + virtual CRegisteredString GetProtocolName() = 0; + }; + + class IMultiProtocolSocketListener : public NVRefCounted + { + public: + // If a listener is returned from on new protocol, the system creates a stream + // with the returned listener + virtual IDebugStreamListener *OnNewProtocol(CRegisteredString inProtocolName) = 0; + // Created with the listener returned from OnNewProtocol. + virtual void OnNewProtocolStream(CRegisteredString inProtocolName, + IMultiProtocolSocketStream &inStream) = 0; + }; + + // Create a system of multiplexing multipler unrelated protocols + // through a single network socket. + class IMultiProtocolSocket : public NVRefCounted + { + public: + virtual bool Initialize() = 0; + virtual NVScopedRefCounted + CreateProtocol(const char *name, IDebugStreamListener *inListener) = 0; + virtual NVScopedRefCounted + GetProtocol(const char *name) = 0; + virtual bool Connected() = 0; + + // Upon connection the multi protocol system does a handshake where both sides send + // their nanosecond + // conversions across. Note that the times sent on the multi protocol packets are in a + // system-specific 64 bit quantity that + // needs conversion to actual nanoseconds to be useful (identical to + // QueryHighPerformanceFrequency, QueryHighPerformanceCounter + virtual CounterFrequencyToTensOfNanos SourceConversion() = 0; + + // Manually do a nonblocking check on the network socket for any new information and + // call the various stream listeners + // with information packets if found. + virtual void MessagePump() = 0; + + static NVScopedRefCounted + CreateProtocolSocket(NVFoundationBase &fnd, SocketStream &inStream, + IStringTable &strTable, + IMultiProtocolSocketListener *protocolListener); + }; + + class CProtocolNames + { + public: + static const char *getMobdebugProtocolName() { return "mobdebug"; } + static const char *getSCXMLProtocolName() { return "scxml"; } + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggedInterpreter.cpp b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggedInterpreter.cpp new file mode 100644 index 00000000..a64e8589 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggedInterpreter.cpp @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateDebugger.h" +#include "Qt3DSStateDebuggerProtocol.h" +#include "EASTL/map.h" +#include "EASTL/set.h" +#include "foundation/Qt3DSAtomic.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::debugger; + +namespace { + +// Horrible name, I know. +struct SDebuggedInterpreter : public IDebuggedInterpreter +{ + typedef eastl::set TDebugStrSet; + typedef eastl::vector TBreakpointList; + typedef eastl::map TDataModelTable; + typedef eastl::hash_map TTableMap; + typedef eastl::vector TTableEntryList; + // Null is the datamodel table. + + NVAllocatorCallback &m_Allocator; + NVScopedRefCounted m_Stream; + QT3DSI32 mRefCount; + TEditorPtr m_Editor; + TDebugStr m_Filename; + SMessageSerializer m_Serializer; + QT3DSI32 m_StreamId; + TBreakpointList m_Breakpoints; + TDebugStrList m_StrList; + TDebugStrSet m_Configuration; + bool m_BreakOnMicrostep; + bool m_IsBroken; + Option m_BrokenBreakpoint; + IDebuggerMasterListener &m_Listener; + TTableMap m_DatamodelValues; + mutable TTableEntryList m_TempEntries; + bool m_MicrostepHasData; + SMicrostepData m_MicrostepData; + TDebugStr m_MicrostepEvent; + TDebugStrList m_ConfigurationList; + TDebugStrList m_PreviousConfiguration; + + SDebuggedInterpreter(NVAllocatorCallback &inAlloc, IDebugOutStream &inStream, + TEditorPtr inEditor, const TDebugStr &inFname, QT3DSI32 inStreamId, + NVConstDataRef inConfiguration, + IDebuggerMasterListener &inListener) + : m_Allocator(inAlloc) + , m_Stream(inStream) + , mRefCount(0) + , m_Editor(inEditor) + , m_Filename(inFname) + , m_StreamId(inStreamId) + , m_BreakOnMicrostep(false) + , m_IsBroken(false) + , m_Listener(inListener) + , m_MicrostepHasData(false) + { + m_ConfigurationList.assign(inConfiguration.begin(), inConfiguration.end()); + m_Configuration.insert(inConfiguration.begin(), inConfiguration.end()); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) + + // Get the editor that represents the state graph for this debugged interpreter. + TEditorPtr GetEditor() override { return m_Editor; } + TDebugStr GetFilename() const override { return m_Filename; } + + template + void SendMessage(const TMessageType &inMessage) + { + m_Serializer.Serialize(m_StreamId, inMessage, 0); + m_Stream->Write(m_Serializer.ToRawMessage()); + } + + // Used when connecting to a live session. + void SetBreakpoint(const SBreakpoint &inBreakpoint) override + { + TBreakpointList::iterator iter = + eastl::find(m_Breakpoints.begin(), m_Breakpoints.end(), inBreakpoint); + if (iter == m_Breakpoints.end()) { + SendMessage(SSetBreakpoint(inBreakpoint)); + m_Breakpoints.push_back(inBreakpoint); + } + } + + void ClearBreakpoint(const SBreakpoint &inBreakpoint) override + { + TBreakpointList::iterator iter = + eastl::find(m_Breakpoints.begin(), m_Breakpoints.end(), inBreakpoint); + if (iter != m_Breakpoints.end()) { + SendMessage(SClearBreakpoint(inBreakpoint)); + m_Breakpoints.erase(iter); + } + } + + NVConstDataRef GetBreakpoints() override + { + return toDataRef(m_Breakpoints.data(), m_Breakpoints.size()); + } + + void ClearAllBreakpoints() override + { + SendMessage(SClearAllBreakpoints()); + m_Breakpoints.clear(); + } + + // break at the *end* of the microstep so you can see the data of the microstep. + void SetBreakOnMicrostep(bool inBreak) override + { + if (m_BreakOnMicrostep != inBreak) { + m_BreakOnMicrostep = inBreak; + SendMessage(SBreakOnMicrostep(inBreak)); + } + } + bool IsBreakOnMicrostep() const override { return m_BreakOnMicrostep; } + + NVConstDataRef TableToList(const TDataModelTable &inTable) const + { + m_TempEntries.resize(inTable.size()); + QT3DSU32 idx = 0; + for (TDataModelTable::const_iterator iter = inTable.begin(), end = inTable.end(); + iter != end; ++iter, ++idx) + m_TempEntries[idx] = STableEntry(iter->first, iter->second); + return toConstDataRef(m_TempEntries.data(), m_TempEntries.size()); + } + + NVConstDataRef GetTableValues(SDatamodelTable *inTable) const override + { + TTableMap::const_iterator iter = m_DatamodelValues.find(inTable); + if (iter != m_DatamodelValues.end()) + return TableToList(iter->second); + return NVConstDataRef(); + } + + NVConstDataRef GetPreviousConfiguration() const override + { + return toConstDataRef(m_PreviousConfiguration.data(), m_PreviousConfiguration.size()); + } + NVConstDataRef GetConfiguration() const override + { + return toConstDataRef(m_ConfigurationList.data(), m_ConfigurationList.size()); + } + const TDebugStr &GetMicrostepEvent() const override { return m_MicrostepEvent; } + NVConstDataRef GetMicrostepTransitions() const override + { + return toConstDataRef(m_MicrostepData.m_Transitions.data(), + m_MicrostepData.m_Transitions.size()); + } + NVConstDataRef GetMicrostepEnterStates() const override + { + return toConstDataRef(m_MicrostepData.m_EnterStates.data(), + m_MicrostepData.m_EnterStates.size()); + } + NVConstDataRef GetMicrostepExitStates() const override + { + return toConstDataRef(m_MicrostepData.m_ExitStates.data(), + m_MicrostepData.m_ExitStates.size()); + } + void Continue() override + { + SendMessage(SContinue()); + m_IsBroken = false; + m_BrokenBreakpoint = Option(); + } + + void Disconnect() override + { + ClearAllBreakpoints(); + SetBreakOnMicrostep(false); + if (m_IsBroken == true) + Continue(); + + SendMessage(SDisconnect()); + } + + void BreakpointHit(const SBreakpoint &inBreakpoint) override + { + m_BrokenBreakpoint = inBreakpoint; + m_IsBroken = true; + m_Listener.OnInterpreterBroken(*this, inBreakpoint); + } + + void OnEventQueued(const SEventQueued &inMsg) override + { + m_Listener.OnEventQueued(inMsg.m_Event, inMsg.m_Internal); + } + + void OnBeginStep(const SBeginStep &) override { m_Listener.OnBeginStep(*this); } + + void OnBeginMicrostep(const SBeginMicrostep &) override + { + m_MicrostepEvent.clear(); + m_MicrostepData.m_Transitions.clear(); + m_MicrostepData.m_EnterStates.clear(); + m_MicrostepData.m_ExitStates.clear(); + m_MicrostepHasData = false; + m_Listener.OnBeginMicrostep(*this); + } + + void OnMicrostepEvent(const SMicrostepEvent &inMsg) override + { + m_MicrostepEvent = inMsg.m_Event; + } + + void OnMicrostepData(const SMicrostepData &inMsg) override + { + m_MicrostepData = inMsg; + m_MicrostepHasData = true; + } + void OnEndMicrostep(const SEndMicrostep & /*inMsg*/) override + { + if (m_MicrostepHasData == false && m_MicrostepEvent.empty() == false) { + m_Listener.OnEventProcessed(m_MicrostepEvent, false); + } else { + m_PreviousConfiguration = m_ConfigurationList; + + for (TDebugStrList::const_iterator iter = m_MicrostepData.m_ExitStates.begin(), + end = m_MicrostepData.m_ExitStates.end(); + iter != end; ++iter) + m_Configuration.erase(*iter); + + m_Configuration.insert(m_MicrostepData.m_EnterStates.begin(), + m_MicrostepData.m_EnterStates.end()); + + m_ConfigurationList.clear(); + m_ConfigurationList.insert(m_ConfigurationList.end(), m_Configuration.begin(), + m_Configuration.end()); + if (m_BreakOnMicrostep) { + m_IsBroken = true; + m_Listener.OnInterpreterBroken(*this, Option()); + } else + m_Listener.OnMicrostep(*this); + } + } + + void OnModifyTable(const SModifyTableValues &inValues) override + { + TTableMap::iterator iter = + m_DatamodelValues.insert(eastl::make_pair(inValues.m_TablePtr, TDataModelTable())) + .first; + for (QT3DSU32 idx = 0, end = inValues.m_Modifications.size(); idx < end; ++idx) { + const STableModification &theMod(inValues.m_Modifications[idx]); + switch (theMod.m_Type) { + case TableModificationType::RemoveKey: + iter->second.erase(theMod.m_Entry.m_Key); + break; + case TableModificationType::SetKey: + (iter->second)[theMod.m_Entry.m_Key] = theMod.m_Entry.m_Value; + break; + default: + QT3DS_ASSERT(false); + break; + } + } + m_Listener.OnDatamodelChange( + *this, inValues.m_TablePtr, + toConstDataRef(inValues.m_Modifications.data(), inValues.m_Modifications.size())); + } + + bool IsBroken() const override { return m_IsBroken; } +}; +} + +IDebuggedInterpreter &IDebuggedInterpreter::Create(NVAllocatorCallback &inAlloc, + IDebugOutStream &inStream, TEditorPtr inEditor, + const TDebugStr &inFilename, QT3DSI32 inStreamId, + NVConstDataRef inConfiguration, + IDebuggerMasterListener &inListener) +{ + return *QT3DS_NEW(inAlloc, SDebuggedInterpreter)(inAlloc, inStream, inEditor, inFilename, + inStreamId, inConfiguration, inListener); +} diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.cpp b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.cpp new file mode 100644 index 00000000..5917db60 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.cpp @@ -0,0 +1,312 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateDebugger.h" +#include "Qt3DSStateDebuggerValues.h" +#include "Qt3DSStateDebuggerProtocol.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/IOStreams.h" + +using namespace qt3ds::state::debugger; +using namespace qt3ds::state; + +namespace { + +static MallocAllocator g_MallocAlloc; + +struct SDebugger : public IDebugger +{ + typedef eastl::vector> TDebugList; + typedef eastl::hash_map TMachineIdMap; + typedef eastl::hash_map, + NVScopedRefCounted>> + TIdMachineMap; + QT3DSI32 mRefCount; + QT3DSI32 m_NextStateMachineId; + TDebugList m_StateMachineList; + TMachineIdMap m_StateMachines; + TIdMachineMap m_IdToStateMachines; + QT3DSU64 m_StartTime; + NVScopedRefCounted m_OutStream; + SMessageParser m_Parser; + SMessageSerializer m_MessageSerializer; + TDebugStr m_MessageStr; + + SDebugger() + : mRefCount(0) + , m_NextStateMachineId(1) + , m_StartTime(Time::getCurrentCounterValue()) + { + } + + virtual ~SDebugger() { DisconnectFromServer(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_MallocAlloc) + + void ConnectStateMachine(IStateMachineDebugInterface &inMachine) + { + TMachineIdMap::iterator theIter = m_StateMachines.find(&inMachine); + if (theIter != m_StateMachines.end()) + return; + QT3DSI32 theId(m_NextStateMachineId); + ++m_NextStateMachineId; + IStateMachineListener *theListener = + &IStateMachineListener::Create(g_MallocAlloc, theId, *m_OutStream.mPtr, m_StartTime, + *this, inMachine.GetScriptContext()); + inMachine.SetStateMachineListener(theListener); + m_StateMachines.insert(eastl::make_pair(&inMachine, theId)); + m_IdToStateMachines.insert( + eastl::make_pair(theId, eastl::make_pair(&inMachine, theListener))); + } + + void OnServerConnected(IDebugOutStream &inStream) override + { + m_OutStream = inStream; + inStream.SetListener(this); + m_MessageSerializer.Serialize(0, SInitialization(), m_StartTime); + m_OutStream->Write(m_MessageSerializer.ToRawMessage()); + for (QT3DSU32 idx = 0, end = m_StateMachineList.size(); idx < end; ++idx) + ConnectStateMachine(*m_StateMachineList[idx]); + } + + void Connect(IStateMachineDebugInterface &inMachine) override + { + TDebugList::iterator theFind = + eastl::find(m_StateMachineList.begin(), m_StateMachineList.end(), &inMachine); + if (theFind == m_StateMachineList.end()) { + m_StateMachineList.push_back(&inMachine); + if (m_OutStream) + ConnectStateMachine(inMachine); + } + } + + void DisconnectStateMachine(IStateMachineDebugInterface &inMachine) + { + TMachineIdMap::iterator theIter = m_StateMachines.find(&inMachine); + if (theIter == m_StateMachines.end()) + return; + + QT3DSI32 theId = theIter->second; + m_MessageSerializer.Serialize(theId, SDisconnect(), + Time::getCurrentCounterValue() - m_StartTime); + m_OutStream->Write(m_MessageSerializer.ToRawMessage()); + inMachine.SetStateMachineListener(NULL); + m_StateMachines.erase(&inMachine); + m_IdToStateMachines.erase(theId); + } + void Disconnect(IStateMachineDebugInterface &inMachine) override + { + TDebugList::iterator theFind = + eastl::find(m_StateMachineList.begin(), m_StateMachineList.end(), &inMachine); + if (theFind != m_StateMachineList.end()) { + DisconnectStateMachine(inMachine); + m_StateMachineList.erase(theFind); + } + } + + void DisconnectFromServer() override + { + if (m_OutStream) { + m_MessageSerializer.Serialize(-1, SDisconnect(), + Time::getCurrentCounterValue() - m_StartTime); + m_OutStream->Write(m_MessageSerializer.ToRawMessage()); + } + m_StateMachines.clear(); + m_IdToStateMachines.clear(); + m_StateMachineList.clear(); + m_OutStream = NULL; + } + + void OnMessageReceived(const SDebugStreamMessage &msg) override + { + if (msg.m_Data.size()) + m_Parser.Parse(msg.m_Data, *this); + } + +// Set of ignored messages +#define IGNORE_DEBUG_MESSAGE_TYPE(tname) \ + void OnMessage(QT3DSI32, QT3DSU64, const S##tname &) { QT3DS_ASSERT(false); } + + // this are outgoing messages; we shouldn't be receiving them. + IGNORE_DEBUG_MESSAGE_TYPE(Initialization) + IGNORE_DEBUG_MESSAGE_TYPE(Connect) + IGNORE_DEBUG_MESSAGE_TYPE(BreakpointHit) + IGNORE_DEBUG_MESSAGE_TYPE(DebugLog) + IGNORE_DEBUG_MESSAGE_TYPE(EventQueued) + IGNORE_DEBUG_MESSAGE_TYPE(BeginStep) + IGNORE_DEBUG_MESSAGE_TYPE(BeginMicrostep) + IGNORE_DEBUG_MESSAGE_TYPE(MicrostepEvent) + IGNORE_DEBUG_MESSAGE_TYPE(MicrostepData) + IGNORE_DEBUG_MESSAGE_TYPE(EndMicrostep) + IGNORE_DEBUG_MESSAGE_TYPE(ModifyTableValues) + + IStateMachineDebugInterface *GetStateMachine(QT3DSI32 inStreamId) + { + TIdMachineMap::iterator theIter = m_IdToStateMachines.find(inStreamId); + if (theIter == m_IdToStateMachines.end()) + return NULL; + return theIter->second.first.mPtr; + } + + IStateMachineListener *GetStateMachineListener(QT3DSI32 inStreamId) + { + TIdMachineMap::iterator theIter = m_IdToStateMachines.find(inStreamId); + if (theIter == m_IdToStateMachines.end()) + return NULL; + return theIter->second.second.mPtr; + } + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SSetBreakpoint &inBp) + { + IStateMachineListener *iface = GetStateMachineListener(sid); + if (iface) + iface->SetBreakpoint(inBp.m_Breakpoint); + } + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SClearBreakpoint &inBp) + { + IStateMachineListener *iface = GetStateMachineListener(sid); + if (iface) + iface->ClearBreakpoint(inBp.m_Breakpoint); + } + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SClearAllBreakpoints &) + { + IStateMachineListener *iface = GetStateMachineListener(sid); + if (iface) + iface->ClearAllBreakpoints(); + } + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SBreakOnMicrostep &inCmd) + { + IStateMachineListener *iface = GetStateMachineListener(sid); + if (iface) + iface->SetBreakOnMicrostep(inCmd.m_Value); + } + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SContinue &) + { + IStateMachineListener *iface = GetStateMachineListener(sid); + if (iface) + iface->Continue(); + } + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SDisconnect &) + { + if (sid != 0 && sid != (QT3DSI32)QT3DS_MAX_U32) { + IStateMachineDebugInterface *iface = GetStateMachine(sid); + if (iface) + Disconnect(*iface); + } else { + if (sid == (QT3DSI32)QT3DS_MAX_U32) + DisconnectFromServer(); + } + } + + void error(const char8_t *, const char8_t *) {} +}; + +static inline NVConstDataRef ToRef(const TDebugStr &str) +{ + return NVConstDataRef((const QT3DSU8 *)str.begin(), str.size()); +} + +bool TestBasicParseRobustness() +{ + typedef STestMessageHandler THandlerType; + typedef SMessageParser TParserType; + // Just ensure things don't crash. + SInitialization testType; + THandlerType theHandler(2, 5, testType); + TDebugStr theStr; + TParserType theParser; + theParser.Parse(ToRef(theStr), theHandler); + + theStr = "Initialization"; + theParser.Parse(ToRef(theStr), theHandler); + + theStr = "Initialization "; + theParser.Parse(ToRef(theStr), theHandler); + return true; +} + +template +bool TestSerialization(const TDataType &testType, SMessageSerializer &ioSerializer, + QT3DSU64 inTimestamp) +{ + typedef STestMessageHandler THandlerType; + typedef SMessageParser TParserType; + + ioSerializer.Serialize(5, testType, inTimestamp); + THandlerType theHandler(5, inTimestamp, testType); + TParserType theParser; + theParser.Parse(ioSerializer.ToRawMessage(), theHandler); + return theHandler.m_Result; +} +} + +IDebugger &IDebugger::CreateDebugger() +{ + return *QT3DS_NEW(g_MallocAlloc, SDebugger)(); +} + +bool CDebuggerTests::TestStreamProtocol() +{ + // for each message type, fill on some values, serialize to string and back and see what happens + TDebugStrList theList; + theList.push_back("one"); + theList.push_back("two"); + TTransitionIdList theTransList; + theTransList.push_back(STransitionId("one", 2)); + theTransList.push_back(STransitionId("two", -1)); + SBreakpoint bp1(SStateEnterBreakpoint("one")); + SBreakpoint bp2(SStateExitBreakpoint("two")); + SBreakpoint bp3(STransitionId("three", 4)); + SMessageSerializer theSerializer; + bool retval = TestBasicParseRobustness(); + // breaking out the large && statement to make testing easier. + retval = retval && TestSerialization(SInitialization(), theSerializer, 5); + retval = retval && TestSerialization(SConnect("abe.scxml", "hey you", theList), + theSerializer, 6); + retval = retval + && TestSerialization(SDebugLog(TDebugStr("Hey joe, where you goin'")), theSerializer, 7); + retval = retval && TestSerialization(SBeginMicrostep(), theSerializer, 8); + retval = retval && TestSerialization(SMicrostepEvent("evt1", true), theSerializer, 9); + retval = retval + && TestSerialization(SMicrostepData(theTransList, theList, theList), theSerializer, 9); + retval = retval && TestSerialization(SEndMicrostep(), theSerializer, 10); + retval = retval && TestSerialization(SEventQueued("evt1", false), theSerializer, 11); + retval = retval && TestSerialization(SEventQueued("evt1", false), theSerializer, 12); + retval = retval && TestSerialization(SSetBreakpoint(bp1), theSerializer, 13); + retval = retval && TestSerialization(SSetBreakpoint(bp2), theSerializer, 14); + retval = retval && TestSerialization(SSetBreakpoint(bp3), theSerializer, 15); + retval = retval && TestSerialization(SClearBreakpoint(bp1), theSerializer, 16); + retval = retval && TestSerialization(SClearAllBreakpoints(), theSerializer, 17); + return retval; +} diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.h new file mode 100644 index 00000000..00814e42 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebugger.h @@ -0,0 +1,386 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_DEBUGGER_H +#define QT3DS_STATE_DEBUGGER_H +#pragma once +#include "Qt3DSState.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/StringTable.h" +#include "foundation/IOStreams.h" +#include "Qt3DSStateEditor.h" + +namespace qt3ds { +namespace state { + namespace debugger { + using namespace editor; + + typedef TEditorStr TDebugStr; + struct SDebugValue; + struct SBreakpoint; + struct SNil; + struct SDatamodelTable; + struct SDatamodelUserData; + struct SDatamodelFunction; + struct SDatamodelCFunction; + struct SDatamodelThread; + + typedef eastl::vector TBreakpointList; + + struct BreakpointTypes + { + enum Enum { + UnknownBreakpointType = 0, + StateEnter, + StateExit, + Transition, + }; + }; + + struct SDebugStreamMessage + { + // Timestamp needs to be converted using the SourceConversion on the protocol socket. + QT3DSU64 m_Timestamp; + NVConstDataRef m_Data; + SDebugStreamMessage() + : m_Timestamp(0) + { + } + SDebugStreamMessage(QT3DSU64 ts, NVConstDataRef msg) + : m_Timestamp(ts) + , m_Data(msg) + { + } + }; + + // Note the stream listeners are not ref counted. + // it is your job to ensure it lasts as long as debug stream. + class IDebugStreamListener + { + protected: + virtual ~IDebugStreamListener() {} + public: + // Async message interface. Clients must provide this. Only called on main thread + virtual void OnMessageReceived(const SDebugStreamMessage &inMessage) = 0; + }; + + class IDebugOutStream : public NVRefCounted, public IOutStream + { + protected: + virtual ~IDebugOutStream() {} + public: + virtual void SetListener(IDebugStreamListener *listener) = 0; + virtual IDebugStreamListener *GetListener() = 0; + // return true if the stream is still connected to an output, false if + // something caused the connection to fail or close. + virtual SDebugStreamMessage WaitForNextMessage() = 0; + virtual bool Connected() = 0; + }; + + struct STransitionId + { + TDebugStr m_StateId; + // Index in file order of the transition. + //-1 means initial or history::transition, depending on if the state is + // a normal state or history state. + QT3DSI32 m_TransitionIndex; + STransitionId(const TDebugStr &inId = TDebugStr(), QT3DSI32 inIdx = -2) + : m_StateId(inId) + , m_TransitionIndex(inIdx) + { + } + bool operator==(const STransitionId &inOther) const + { + return m_StateId == inOther.m_StateId + && m_TransitionIndex == inOther.m_TransitionIndex; + } + }; + + typedef eastl::vector TTransitionIdList; + + /////////////////////////////////////////////////////////////////////// + // Client (runtime) side types + /////////////////////////////////////////////////////////////////////// + + struct DatamodelValueTypes + { + enum Enum { + UnknownType = 0, + Nil, + Boolean, + Number, + String, + Table, + UserData, + Function, + CFunction, + Thread, + }; + }; + + struct SDatamodelValue; + + struct SDatamodelTable; + struct SDatamodelUserData; + struct SDatamodelFunction; + struct SDatamodelCFunction; + struct SDatamodelThread; + struct STableEntry; + + class IScriptStateListener + { + protected: + virtual ~IScriptStateListener() {} + public: + virtual void SetKey(void *inTable, const TDebugStr &inStr, + const SDatamodelValue &inValue) = 0; + virtual void RemoveKey(void *inTable, const TDebugStr &inStr) = 0; + }; + + class IDebugger; + // Information coming from the state machine + class IStateMachineListener : public NVRefCounted + { + protected: + virtual ~IStateMachineListener() {} + public: + // Events coming from the interpreter and sent over the interface. + virtual void OnConnect(const TDebugStr &SCXMLFilename, const TDebugStr &SCXMLFileData, + NVConstDataRef inConfiguration) = 0; + + virtual void Log(const TDebugStr &inStr) = 0; + virtual void EventQueued(const TDebugStr &inEventName, bool inInternal) = 0; + virtual void BeginStep() = 0; + virtual void BeginMicroStep() = 0; + virtual void SetEvent(const TDebugStr &inEventName, bool inInternal) = 0; + virtual void SetTransitionSet(NVConstDataRef inTransitions) = 0; + virtual void SetExitSet(NVConstDataRef inSet) = 0; + virtual void SetEnterSet(NVConstDataRef inSet) = 0; + // Log statements run through the debugger as well. + virtual void EndMicroStep() = 0; + virtual void EndStep() = 0; + + // So far the breakpoints have all been things that are internal to the + // state machine. + virtual void SetBreakOnMicrostep(bool inEnableStep) = 0; + virtual void SetBreakpoint(const SBreakpoint &inBreakpoint) = 0; + virtual void ClearBreakpoint(const SBreakpoint &inBreakpoint) = 0; + virtual void ClearAllBreakpoints() = 0; + + // Called internally. + virtual void Continue() = 0; + virtual void OnExternalBreak() = 0; + + static IStateMachineListener &Create(NVAllocatorCallback &inAlloc, QT3DSU32 inStreamId, + IDebugOutStream &inOutStr, QT3DSU64 inStartTime, + IDebugger &inDebugger, + IScriptContext &inScriptContext); + }; + + // Information coming from the network stream will call these iterfaces + class IStateMachineDebugInterface : public NVRefCounted + { + protected: + virtual ~IStateMachineDebugInterface() {} + public: + virtual void SetStateMachineListener(IStateMachineListener *inListener) = 0; + virtual void OnExternalBreak() = 0; + virtual IScriptContext &GetScriptContext() = 0; + }; + + // The debugger element is the object that sits in the debug process interpreter and sends + // information. + // There should be only one of these per network connection. + class IDebugger : public IDebugStreamListener, public NVRefCounted + { + protected: + virtual ~IDebugger() {} + public: + virtual void OnServerConnected(IDebugOutStream &inStream) = 0; + virtual void Connect(IStateMachineDebugInterface &inMachine) = 0; + virtual void Disconnect(IStateMachineDebugInterface &inMachine) = 0; + // Release any references to any state machines and to the output stream + virtual void DisconnectFromServer() = 0; + + static IDebugger &CreateDebugger(); + }; + + /////////////////////////////////////////////////////////////////////// + // Server (Architect) side types + /////////////////////////////////////////////////////////////////////// + + struct DebugValueTypes + { + enum Enum { NoDebugValue = 0, String, StringList, TransitionIdList }; + }; + + typedef eastl::vector TDebugStrList; + + struct STableModification; + + class IDebuggedInterpreter; + + class IDebuggerMasterListener : public NVRefCounted + { + protected: + virtual ~IDebuggerMasterListener() {} + public: + virtual void OnInterpreterConnected(IDebuggedInterpreter &inInterpreter) = 0; + // If no breakpoint then the interpreter was broken on microstep. + virtual void OnEventQueued(const TDebugStr &inEvent, bool inInternal) = 0; + virtual void OnInterpreterBroken(IDebuggedInterpreter &inInterpreter, + const Option &inBreakpoint) = 0; + // Event processed but no microstep was taken. + virtual void OnEventProcessed(const TDebugStr &inEvent, bool inInternal) = 0; + virtual void OnBeginStep(IDebuggedInterpreter &inInterpreter) = 0; + virtual void OnBeginMicrostep(IDebuggedInterpreter &inInterpreter) = 0; + // Event processed and microstep was taken. + virtual void OnMicrostep(IDebuggedInterpreter &inInterpreter) = 0; + // if inmodifications is empty the table needs to be replaced. + virtual void OnDatamodelChange(IDebuggedInterpreter &inInterpreter, + SDatamodelTable *inTable, + NVConstDataRef inModifications) = 0; + virtual void OnInterpreterDisconnected(IDebuggedInterpreter &inInterpreter) = 0; + virtual void OnLog(IDebuggedInterpreter *inInterpreter, const TDebugStr &inMessage) = 0; + }; + + struct STableEntry; + + typedef eastl::vector TTableEntryList; + + // defined in UICStateDebuggerProtocol.h" + struct SBeginStep; + struct SBeginMicrostep; + struct SMicrostepEvent; + struct SMicrostepData; + struct SEndMicrostep; + struct SEventQueued; + struct SModifyTableValues; + struct SDatamodelTable; + + // Represents the data stream coming from a single interpreter + class IDebuggedInterpreter : public NVRefCounted + { + protected: + virtual ~IDebuggedInterpreter() {} + public: + /* Playback interface, leaving until basic functionality is working. + virtual QT3DSU32 GetStepCount() = 0; + virtual void SetCurrentStep( QT3DSU32 inStep ) = 0; + virtual QT3DSU32 GetMicrostepCount() = 0; + virtual QT3DSU32 SetCurrentMicroStep( QT3DSU32 inStep ) = 0; + */ + + // Get the editor that represents the state graph for this debugged interpreter. + virtual TEditorPtr GetEditor() = 0; + virtual TDebugStr GetFilename() const = 0; + + // Used when connecting to a live session. + virtual void SetBreakpoint(const SBreakpoint &inBreakpoint) = 0; + virtual void ClearBreakpoint(const SBreakpoint &inBreakpoint) = 0; + virtual NVConstDataRef GetBreakpoints() = 0; + virtual void ClearAllBreakpoints() = 0; + // break at the *end* of the microstep so you can see the data of the microstep. + virtual void SetBreakOnMicrostep(bool inBreak) = 0; + virtual bool IsBreakOnMicrostep() const = 0; + + // Return values not valid after *next* call. + // Null means the root. + virtual NVConstDataRef + GetTableValues(SDatamodelTable *inTable = NULL) const = 0; + + virtual NVConstDataRef GetPreviousConfiguration() const = 0; + virtual NVConstDataRef GetConfiguration() const = 0; + virtual const TDebugStr &GetMicrostepEvent() const = 0; + virtual NVConstDataRef GetMicrostepTransitions() const = 0; + virtual NVConstDataRef GetMicrostepEnterStates() const = 0; + virtual NVConstDataRef GetMicrostepExitStates() const = 0; + + virtual bool IsBroken() const = 0; + virtual void Continue() = 0; + // Get the set of changed properties since the last time you asked. Obviously this is + // assuming there + // is only one 'you' asking. + virtual void Disconnect() = 0; + + // Semi-advanced debugger functionality that we don't need for version 1. + + // virtual void SetPropertyValue( const char8_t* inName, const SDebugValue& inValue ) = + // 0; + // Set a property value on the running state machine. + // virtual void SetPropertyValue( TObjPtr inEditorObj, const char8_t* inName, const + // SValueOpt& inValue ) = 0; + + // Eval code in the current state machine context. Works when connected live, wouldn't + // work if you + // were not connected live. + // virtual TDebugStr EvalCode( const TDebugStr& inStr ) = 0; + + // Information coming from the stream, clients should not call these functions + virtual void BreakpointHit(const SBreakpoint &inBreakpoint) = 0; + virtual void OnEventQueued(const SEventQueued &inMsg) = 0; + virtual void OnBeginStep(const SBeginStep &inMsg) = 0; + virtual void OnBeginMicrostep(const SBeginMicrostep &inMsg) = 0; + virtual void OnMicrostepEvent(const SMicrostepEvent &inMsg) = 0; + virtual void OnMicrostepData(const SMicrostepData &inMsg) = 0; + virtual void OnEndMicrostep(const SEndMicrostep &inMsg) = 0; + virtual void OnModifyTable(const SModifyTableValues &inValues) = 0; + + static IDebuggedInterpreter &Create(NVAllocatorCallback &inAlloc, + IDebugOutStream &inStream, TEditorPtr inEditor, + const TDebugStr &inFilename, QT3DSI32 inStreamId, + NVConstDataRef inConfiguration, + IDebuggerMasterListener &inListener); + }; + + // Debugger sites in the master process (Architect process) and controls one or more + // debuggers + // for one or more state machines running in the debug process. + class IDebuggerMaster : public IDebugStreamListener, public NVRefCounted + { + protected: + virtual ~IDebuggerMaster() {} + public: + virtual void Disconnect() = 0; + + static IDebuggerMaster &CreateMaster(IDebugOutStream &outStream, + IDebuggerMasterListener &inListener); + }; + + class CDebuggerTests + { + public: + static bool TestStreamProtocol(); + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerListener.cpp b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerListener.cpp new file mode 100644 index 00000000..2045f84f --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerListener.cpp @@ -0,0 +1,322 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateDebugger.h" +#include "Qt3DSStateDebuggerValues.h" +#include "Qt3DSStateDebuggerProtocol.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSAtomic.h" +#include "Qt3DSStateScriptContext.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::debugger; + +namespace { + +// Component sits in the state machine and receives messages from the state machine +// itself. +struct SListener : public IStateMachineListener, public IScriptStateListener +{ + typedef eastl::hash_map TTableModificationMap; + NVAllocatorCallback &m_Allocator; + QT3DSI32 mRefCount; + QT3DSU32 m_StreamId; + NVScopedRefCounted m_OutStream; + SMessageSerializer m_Serializer; + TDebugStrList m_DebugStrList; + TDebugStrList m_DebugStrAltList; + TTransitionIdList m_TransitionIdList; + QT3DSU64 m_StartTime; + bool m_BreakOnMicrostep; + bool m_Blocking; + IDebugger &m_Debugger; + TDebugStr m_BreakStr; + NVScopedRefCounted m_ScriptContext; + TTableModificationMap m_TableModifications; + TBreakpointList m_Breakpoints; + SMicrostepData m_MicrostepData; + bool m_MicrostepBeginSent; + bool m_StepSent; + + SListener(NVAllocatorCallback &alloc, QT3DSU32 inStreamId, IDebugOutStream &inOutStr, + QT3DSU64 inStartTime, IDebugger &inDebugger, IScriptContext &inScriptContext) + : m_Allocator(alloc) + , mRefCount(0) + , m_StreamId(inStreamId) + , m_OutStream(inOutStr) + , m_StartTime(inStartTime) + , m_BreakOnMicrostep(false) + , m_Blocking(false) + , m_Debugger(inDebugger) + , m_ScriptContext(inScriptContext) + , m_MicrostepBeginSent(false) + , m_StepSent(false) + { + } + + virtual ~SListener() { m_Blocking = false; } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Allocator) + + template + static const eastl::vector &RefToList(NVConstDataRef inRef, + eastl::vector &outList) + { + outList.assign(inRef.begin(), inRef.end()); + return outList; + } + + template + void Serialize(const TDataType &dtype, QT3DSU64 inTime) + { + m_Serializer.Serialize(m_StreamId, dtype, inTime); + m_OutStream->Write(m_Serializer.ToRawMessage()); + } + + template + void Serialize(const TDataType &dtype) + { + Serialize(dtype, CurrentTime()); + } + + void OnConnect(const TDebugStr &SCXMLFilename, const TDebugStr &SCXMLFileData, + NVConstDataRef inConfiguration) override + { + Serialize( + SConnect(SCXMLFilename, SCXMLFileData, RefToList(inConfiguration, m_DebugStrList))); + DumpScriptState(); + } + + QT3DSU64 CurrentTime() { return Time::getCurrentCounterValue() - m_StartTime; } + + void DumpScriptState() + { + // Run through the global state and output any keys that have changed. + m_TableModifications.clear(); + m_ScriptContext->DumpState(*this); + for (TTableModificationMap::iterator iter = m_TableModifications.begin(), + end = m_TableModifications.end(); + iter != end; ++iter) { + Serialize(iter->second); + } + m_TableModifications.clear(); + } + virtual void OnBreakpointHit(const SBreakpoint &inBreakpointId) + { + DumpScriptState(); + Serialize(SBreakpointHit(inBreakpointId)); + Break(); + } + + void Log(const TDebugStr &inStr) override { Serialize(SDebugLog(inStr)); } + + void SetBreakpoint(const SBreakpoint &inBreakpoint) override + { + m_Breakpoints.push_back(inBreakpoint); + } + + void ClearBreakpoint(const SBreakpoint &inBreakpoint) override + { + TBreakpointList::iterator removeIter = + eastl::remove(m_Breakpoints.begin(), m_Breakpoints.end(), inBreakpoint); + if (removeIter != m_Breakpoints.end()) + m_Breakpoints.erase(removeIter, m_Breakpoints.end()); + } + void ClearAllBreakpoints() override { m_Breakpoints.clear(); } + void EventQueued(const TDebugStr &inEventName, bool inInternal) override + { + Serialize(SEventQueued(inEventName, inInternal)); + } + void SendMicrostepBegin() + { + if (m_MicrostepBeginSent == false) { + if (m_StepSent == false) { + m_StepSent = true; + Serialize(SBeginStep()); + } + + m_MicrostepBeginSent = true; + Serialize(SBeginMicrostep()); + } + } + + void BeginStep() override { m_StepSent = false; } + + void BeginMicroStep() override + { + m_MicrostepBeginSent = false; + m_MicrostepData.m_Transitions.clear(); + m_MicrostepData.m_EnterStates.clear(); + m_MicrostepData.m_ExitStates.clear(); + } + + void SetEvent(const TDebugStr &inEvent, bool inInternal) override + { + if (!inEvent.empty()) { + SendMicrostepBegin(); + Serialize(SMicrostepEvent(inEvent, inInternal)); + } + } + void SetTransitionSet(NVConstDataRef inTransitions) override + { + SendMicrostepBegin(); + RefToList(inTransitions, m_MicrostepData.m_Transitions); + } + void SetExitSet(NVConstDataRef inSet) override + { + SendMicrostepBegin(); + RefToList(inSet, m_MicrostepData.m_ExitStates); + } + void SetEnterSet(NVConstDataRef inSet) override + { + SendMicrostepBegin(); + RefToList(inSet, m_MicrostepData.m_EnterStates); + } + + static inline bool FindInList(const TDebugStr &inStr, const TDebugStrList &inStrList) + { + if (eastl::find(inStrList.begin(), inStrList.end(), inStr) != inStrList.end()) + return true; + return false; + } + + static inline bool FindInList(const STransitionId &inStr, const TTransitionIdList &inStrList) + { + if (eastl::find(inStrList.begin(), inStrList.end(), inStr) != inStrList.end()) + return true; + return false; + } + + const SBreakpoint *FindHitBreakpoint() + { + // Now check for breakpoints. + for (QT3DSU32 breakIdx = 0, breakEnd = m_Breakpoints.size(); breakIdx < breakEnd; ++breakIdx) { + const SBreakpoint &theBreakpoint = m_Breakpoints[breakIdx]; + switch (theBreakpoint.getType()) { + case BreakpointTypes::StateEnter: + if (FindInList(theBreakpoint.getData().m_ObjectId, + m_MicrostepData.m_EnterStates)) + return &theBreakpoint; + case BreakpointTypes::StateExit: + if (FindInList(theBreakpoint.getData().m_ObjectId, + m_MicrostepData.m_ExitStates)) + return &theBreakpoint; + case BreakpointTypes::Transition: + if (FindInList(theBreakpoint.getData(), + m_MicrostepData.m_Transitions)) + return &theBreakpoint; + default: + QT3DS_ASSERT(false); + break; + } + } + + return NULL; + } + + // Log statements run through the debugger as well. + void EndMicroStep() override + { + DumpScriptState(); + if (m_MicrostepBeginSent) { + if (m_MicrostepData.m_Transitions.empty() == false) + Serialize(m_MicrostepData); + + Serialize(SEndMicrostep()); + const SBreakpoint *theHitBreakpoint = FindHitBreakpoint(); + if (theHitBreakpoint) + OnBreakpointHit(*theHitBreakpoint); + else if (m_BreakOnMicrostep) + Break(); + } + } + + void EndStep() override { m_StepSent = false; } + + void SetBreakOnMicrostep(bool inEnableStep) override { m_BreakOnMicrostep = inEnableStep; } + + virtual void Break() + { + if (!m_Blocking) { + // We may get disconnected *while* we are breaking. + // We need to ensure we don't get nuked while we are breaking. + NVScopedRefCounted tempVar(this); + m_Blocking = true; + while (m_Blocking) { + SDebugStreamMessage msg = m_OutStream->WaitForNextMessage(); + // Some out streams will have a reference to the debugger and some will not. + // If they do, then we do not have to hand our string to the debugger, we can assume + // the underlying implementation will have done that. If not, then we need to + // pass the message to the debugger. + if (m_Blocking && msg.m_Data.size()) + m_Debugger.OnMessageReceived(msg); + + if (!m_OutStream->Connected()) { + m_Blocking = false; + m_Debugger.DisconnectFromServer(); + } + } + } + } + + void Continue() override { m_Blocking = false; } + + void OnExternalBreak() override { DumpScriptState(); } + + // IScriptStateListener + void SetKey(void *inTable, const TDebugStr &inStr, const SDatamodelValue &inValue) override + { + SDatamodelTable *theTable((SDatamodelTable *)inTable); + SModifyTableValues &theModification = + m_TableModifications.insert(eastl::make_pair(theTable, SModifyTableValues(theTable))) + .first->second; + theModification.m_Modifications.push_back( + STableModification(STableEntry(inStr, inValue), TableModificationType::SetKey)); + } + + void RemoveKey(void *inTable, const TDebugStr &inStr) override + { + SDatamodelTable *theTable((SDatamodelTable *)inTable); + SModifyTableValues &theModification = + m_TableModifications.insert(eastl::make_pair(theTable, SModifyTableValues(theTable))) + .first->second; + theModification.m_Modifications.push_back( + STableModification(STableEntry(inStr), TableModificationType::RemoveKey)); + } +}; +} + +IStateMachineListener &IStateMachineListener::Create(NVAllocatorCallback &inAlloc, QT3DSU32 inStreamId, + IDebugOutStream &inOutStr, QT3DSU64 inStartTime, + IDebugger &inDebugger, + IScriptContext &inScriptContext) +{ + return *QT3DS_NEW(inAlloc, SListener)(inAlloc, inStreamId, inOutStr, inStartTime, inDebugger, + inScriptContext); +} diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerProtocol.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerProtocol.h new file mode 100644 index 00000000..03230a61 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerProtocol.h @@ -0,0 +1,925 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_DEBUGGER_PROTOCOL_H +#define QT3DS_STATE_DEBUGGER_PROTOCOL_H +#include "Qt3DSStateDebugger.h" +#include "Qt3DSStateDebuggerValues.h" +#include "foundation/StringConversion.h" +#include "foundation/StringConversionImpl.h" +#include "foundation/Qt3DSTime.h" + +// Stream protocol, regardless of binary vs. text. +namespace qt3ds { +namespace state { + namespace debugger { + + struct SInitialization + { + QT3DSI32 m_Version; + QT3DSI32 m_Padding; + CounterFrequencyToTensOfNanos m_TimerFrequency; + static QT3DSI32 GetCurrentVersion() { return 1; } + SInitialization() + : m_Version(GetCurrentVersion()) + , m_Padding(0) + , m_TimerFrequency(Time::sCounterFreq) + { + } + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visit(m_Version); + inVisitor.visit(m_TimerFrequency.mNumerator); + inVisitor.visit(m_TimerFrequency.mDenominator); + } + bool operator==(const SInitialization &inOther) const + { + return m_Version == inOther.m_Version + && m_TimerFrequency.mNumerator == inOther.m_TimerFrequency.mNumerator + && m_TimerFrequency.mDenominator == inOther.m_TimerFrequency.mDenominator; + } + }; + + // Listener interface. For on connect, we send the current timestamp for that state + // machine. + struct SConnect + { + TDebugStr m_Filename; + TDebugStr m_SCXMLData; // scxml file contents + TDebugStrList m_Configuration; + SConnect() {} + SConnect(const TDebugStr &fn, const TDebugStr &xmlData, const TDebugStrList &config) + : m_Filename(fn) + , m_SCXMLData(xmlData) + , m_Configuration(config) + { + } + + template + void Visit(TVisitor &inVisitor) + { + inVisitor.randomText(m_Filename); + inVisitor.randomText(m_SCXMLData); + inVisitor.visitIdList(m_Configuration); + } + bool operator==(const SConnect &inOther) const + { + return m_Filename == inOther.m_Filename && m_SCXMLData == inOther.m_SCXMLData + && m_Configuration == inOther.m_Configuration; + } + }; + + struct SBreakpointHit + { + SBreakpoint m_Breakpoint; + SBreakpointHit() {} + SBreakpointHit(const SBreakpoint &bp) + : m_Breakpoint(bp) + { + } + + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visit(m_Breakpoint); + } + bool operator==(const SBreakpointHit &inOther) const + { + return m_Breakpoint == inOther.m_Breakpoint; + } + }; + + struct SDebugLog + { + TDebugStr m_Message; + SDebugLog() {} + SDebugLog(const TDebugStr &msg) + : m_Message(msg) + { + } + template + void Visit(TVisitor &inVisitor) + { + inVisitor.randomText(m_Message); + } + bool operator==(const SDebugLog &inOther) const + { + return m_Message == inOther.m_Message; + } + }; + + struct SModifyTableValues + { + SDatamodelTable *m_TablePtr; + TTableModificationList m_Modifications; + + SModifyTableValues(SDatamodelTable *inTable = NULL, + const TTableModificationList &inList = TTableModificationList()) + : m_TablePtr(inTable) + , m_Modifications(inList) + { + } + + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visit(m_TablePtr); + inVisitor.visit(m_Modifications); + } + + bool operator==(const SModifyTableValues &inOther) const + { + return m_TablePtr == inOther.m_TablePtr + && m_Modifications == inOther.m_Modifications; + } + }; + + struct SBeginStep + { + SBeginStep() {} + template + void Visit(TVisitor &) + { + } + + bool operator==(const SBeginStep &) const { return true; } + }; + + struct SBeginMicrostep + { + SBeginMicrostep() {} + template + void Visit(TVisitor &) + { + } + + bool operator==(const SBeginMicrostep &) const { return true; } + }; + + struct SMicrostepEvent + { + TDebugStr m_Event; + bool m_Internal; + + SMicrostepEvent(const TDebugStr &inEvent = TDebugStr(), bool inIsInternal = false) + : m_Event(inEvent) + , m_Internal(inIsInternal) + { + } + + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visitId(m_Event); + inVisitor.visit(m_Internal); + } + + bool operator==(const SMicrostepEvent &inOther) const + { + return m_Event == inOther.m_Event && m_Internal == inOther.m_Internal; + } + }; + + struct SMicrostepData + { + TTransitionIdList m_Transitions; + TDebugStrList m_ExitStates; + TDebugStrList m_EnterStates; + + SMicrostepData() {} + SMicrostepData(const TTransitionIdList &inTransitions, + const TDebugStrList &inExitStates, const TDebugStrList &inEnterStates) + : m_Transitions(inTransitions) + , m_ExitStates(inExitStates) + , m_EnterStates(inEnterStates) + { + } + + template + void Visit(TVisitor &inVisitor) + { + // Eventless transitions cause us to need to always write the string length. + inVisitor.visit(m_Transitions); + inVisitor.visitIdList(m_ExitStates); + inVisitor.visitIdList(m_EnterStates); + } + bool operator==(const SMicrostepData &inOther) const + { + return m_Transitions == inOther.m_Transitions + && m_ExitStates == inOther.m_ExitStates + && m_EnterStates == inOther.m_EnterStates; + } + }; + + struct SEndMicrostep + { + SEndMicrostep() {} + template + void Visit(TVisitor & /*inVisitor*/) + { + } + + bool operator==(const SEndMicrostep &) const { return true; } + }; + + struct SEventQueued + { + TDebugStr m_Event; + bool m_Internal; + SEventQueued() + : m_Internal(false) + { + } + SEventQueued(const TDebugStr &evt, bool intern) + : m_Event(evt) + , m_Internal(intern) + { + } + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visitEventName(m_Event); + inVisitor.visit(m_Internal); + } + bool operator==(const SEventQueued &inOther) const + { + return m_Event == inOther.m_Event && m_Internal == inOther.m_Internal; + } + }; + + // Debug interface + + struct SSetBreakpoint + { + SBreakpoint m_Breakpoint; + SSetBreakpoint() {} + SSetBreakpoint(const SBreakpoint &bp) + : m_Breakpoint(bp) + { + } + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visit(m_Breakpoint); + } + bool operator==(const SSetBreakpoint &inOther) const + { + return m_Breakpoint == inOther.m_Breakpoint; + } + }; + + struct SClearBreakpoint + { + SBreakpoint m_Breakpoint; + SClearBreakpoint() {} + SClearBreakpoint(const SBreakpoint &bp) + : m_Breakpoint(bp) + { + } + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visit(m_Breakpoint); + } + bool operator==(const SClearBreakpoint &inOther) const + { + return m_Breakpoint == inOther.m_Breakpoint; + } + }; + + struct SClearAllBreakpoints + { + SClearAllBreakpoints() {} + template + void Visit(TVisitor & /*inVisitor*/) + { + } + bool operator==(const SClearAllBreakpoints & /*inOther*/) const { return true; } + }; + + struct SBreakOnMicrostep + { + bool m_Value; + SBreakOnMicrostep(bool val = false) + : m_Value(val) + { + } + template + void Visit(TVisitor &inVisitor) + { + inVisitor.visit(m_Value); + } + bool operator==(const SBreakOnMicrostep &inOther) const + { + return m_Value == inOther.m_Value; + } + }; + + struct SContinue + { + SContinue() {} + template + void Visit(TVisitor & /*inVisitor*/) + { + } + bool operator==(const SContinue & /*inOther*/) const { return true; } + }; + + struct SDisconnect + { + SDisconnect() {} + template + void Visit(TVisitor & /*inVisitor*/) + { + } + bool operator==(const SDisconnect & /*inOther*/) const { return true; } + }; + + // Visitors to handle the breakpoint subtypes. + // The empty top visitor will force a compile error if there is a breakpoint type we don't + // recognize. + template + struct SBreakpointSerializationVisitor + { + }; + + template <> + struct SBreakpointSerializationVisitor + { + enum { Type = BreakpointTypes::StateEnter }; + template + static void Visit(TVisitor &inVisitor, SStateEnterBreakpoint &inBp) + { + inVisitor.visitId(inBp.m_ObjectId); + } + }; + + template <> + struct SBreakpointSerializationVisitor + { + enum { Type = BreakpointTypes::StateExit }; + template + static void Visit(TVisitor &inVisitor, SStateExitBreakpoint &inBp) + { + inVisitor.visitId(inBp.m_ObjectId); + } + }; + + template <> + struct SBreakpointSerializationVisitor + { + enum { Type = BreakpointTypes::Transition }; + template + static void Visit(TVisitor &inVisitor, STransitionId &inBp) + { + inVisitor.visitId(inBp.m_StateId); + inVisitor.visit(inBp.m_TransitionIndex); + } + }; + +#define ITERATE_BREAKPOINT_TYPES \ + HANDLE_BREAKPOINT_TYPE(StateEnter, SStateEnterBreakpoint) \ + HANDLE_BREAKPOINT_TYPE(StateExit, SStateExitBreakpoint) \ + HANDLE_BREAKPOINT_TYPE(Transition, STransitionId) + +#define ITERATE_DEBUG_MESSAGE_TYPES \ + HANDLE_DEBUG_MESSAGE_TYPE(Initialization) \ + HANDLE_DEBUG_MESSAGE_TYPE(Connect) \ + HANDLE_DEBUG_MESSAGE_TYPE(BreakpointHit) \ + HANDLE_DEBUG_MESSAGE_TYPE(DebugLog) \ + HANDLE_DEBUG_MESSAGE_TYPE(ModifyTableValues) \ + HANDLE_DEBUG_MESSAGE_TYPE(BeginStep) \ + HANDLE_DEBUG_MESSAGE_TYPE(BeginMicrostep) \ + HANDLE_DEBUG_MESSAGE_TYPE(MicrostepEvent) \ + HANDLE_DEBUG_MESSAGE_TYPE(MicrostepData) \ + HANDLE_DEBUG_MESSAGE_TYPE(EndMicrostep) \ + HANDLE_DEBUG_MESSAGE_TYPE(EventQueued) \ + HANDLE_DEBUG_MESSAGE_TYPE(SetBreakpoint) \ + HANDLE_DEBUG_MESSAGE_TYPE(ClearBreakpoint) \ + HANDLE_DEBUG_MESSAGE_TYPE(ClearAllBreakpoints) \ + HANDLE_DEBUG_MESSAGE_TYPE(Disconnect) \ + HANDLE_DEBUG_MESSAGE_TYPE(BreakOnMicrostep) \ + HANDLE_DEBUG_MESSAGE_TYPE(Continue) + + template + struct STypeToName + { + }; + +#define HANDLE_BREAKPOINT_TYPE(enumType, structType) \ + template <> \ + struct STypeToName \ + { \ + static const char8_t *GetName() { return #enumType; } \ + }; +#define HANDLE_DEBUG_MESSAGE_TYPE(msgType) \ + template <> \ + struct STypeToName \ + { \ + static const char8_t *GetName() { return #msgType; } \ + }; + + ITERATE_BREAKPOINT_TYPES + ITERATE_DEBUG_MESSAGE_TYPES + +#undef HANDLE_BREAKPOINT_TYPE +#undef HANDLE_DEBUG_MESSAGE_TYPE + + template + struct SMessageParser + { + TDebugStr m_MessageHeaderStr; + TDebugStr m_TimestampStr; + TDebugStr m_ParseStr; + TDebugStr m_BreakpointTypeStr; + TDebugStr m_TempStr[4]; + TMessageHandler *m_CurrentHandler; + bool m_Valid; + static void Trim(TDebugStr &inStr) + { + if (inStr.empty()) + return; + eastl::string::size_type nonSpace = inStr.find_first_not_of(' '); + eastl::string::size_type lastNonSpace = inStr.find_last_not_of(' '); + if (nonSpace == TDebugStr::npos || lastNonSpace == TDebugStr::npos) { + inStr.clear(); + return; + } + + eastl::string::size_type msgLen = lastNonSpace - nonSpace; + inStr.erase(inStr.begin(), inStr.begin() + nonSpace); + inStr.resize(msgLen + 1); + } + + void TrimForward(eastl::string::size_type startPos) + { + eastl::string::size_type nextPos = m_ParseStr.find_first_not_of(' ', startPos); + if (nextPos != TDebugStr::npos) + m_ParseStr.erase(m_ParseStr.begin(), m_ParseStr.begin() + nextPos); + else + m_ParseStr.clear(); + } + + void TrimForward() + { + eastl::string::size_type nextSpace = m_ParseStr.find_first_of(' '); + TrimForward(nextSpace); + } + + void visitId(TDebugStr &inStr) + { + eastl::string::size_type nextSpace = m_ParseStr.find_first_of(' '); + if (nextSpace == TDebugStr::npos) + nextSpace = m_ParseStr.size(); + inStr.assign(m_ParseStr.begin(), m_ParseStr.begin() + nextSpace); + TrimForward(nextSpace); + } + void visit(TDebugStr &inStr) { randomText(inStr); } + void visit(QT3DSI32 &inData) + { + StringConversion().StrTo(m_ParseStr.c_str(), inData); + TrimForward(); + } + void visit(QT3DSU32 &inData) + { + StringConversion().StrTo(m_ParseStr.c_str(), inData); + TrimForward(); + } + + void visit(QT3DSU64 &inData) + { + StringConversion().StrTo(m_ParseStr.c_str(), inData); + TrimForward(); + } + + void visit(float &inData) + { + StringConversion().StrTo(m_ParseStr.c_str(), inData); + TrimForward(); + } + + void visit(bool &inData) + { + if (CompareNChars(m_ParseStr.c_str(), "True", 4) == 0) + inData = true; + else + inData = false; + + TrimForward(); + } + + template + void visitOpaquePtr(TPtrType *&inPtr) + { + QT3DSU64 temp; + visit(temp); + inPtr = reinterpret_cast(static_cast(temp)); + } + + void visit(SDatamodelTable *&inData) { visitOpaquePtr(inData); } + void visit(SDatamodelUserData *&inData) { visitOpaquePtr(inData); } + void visit(SDatamodelFunction *&inData) { visitOpaquePtr(inData); } + void visit(SDatamodelCFunction *&inData) { visitOpaquePtr(inData); } + void visit(SDatamodelThread *&inData) { visitOpaquePtr(inData); } + void visit(SNil &) {} + + void visit(SDatamodelValue &inValue) + { + visitId(m_TempStr[0]); +#define HANDLE_DATAMODEL_VALUE_TYPE(name, dtype) \ + if (AreEqual(m_TempStr[0].c_str(), #name)) { \ + dtype theData; \ + visit(theData); \ + inValue = theData; \ + } else + ITERATE_DATAMODEL_VALUE_TYPES +#undef HANDLE_DATAMODEL_VALUE_TYPE + { + QT3DS_ASSERT(false); + } + } + + void visit(TTableModificationList &inModifications) + { + QT3DSU32 numMods = 0; + visit(numMods); + inModifications.resize(numMods); + for (QT3DSU32 idx = 0, end = inModifications.size(); idx < end; ++idx) { + STableModification &theModification(inModifications[idx]); + visitId(m_TempStr[0]); + if (AreEqual(m_TempStr[0].c_str(), "SetKey")) + theModification.m_Type = TableModificationType::SetKey; + else if (AreEqual(m_TempStr[0].c_str(), "RemoveKey")) + theModification.m_Type = TableModificationType::RemoveKey; + else { + QT3DS_ASSERT(false); + continue; + } + visit(theModification.m_Entry.m_Key); + if (theModification.m_Type == TableModificationType::SetKey) + visit(theModification.m_Entry.m_Value); + } + } + + void visit(TTableEntryList &inEntryList) + { + QT3DSU32 numMods = 0; + visit(numMods); + inEntryList.resize(numMods); + for (QT3DSU32 idx = 0, end = inEntryList.size(); idx < end; ++idx) { + STableEntry &theEntry(inEntryList[idx]); + visit(theEntry.m_Key); + visit(theEntry.m_Value); + } + } + + void randomText(TDebugStr &outStr) + { + QT3DSU32 strLen = 0; + visit(strLen); + outStr.assign(m_ParseStr.begin(), m_ParseStr.begin() + strLen); + TrimForward(strLen); + } + + void visitIdList(TDebugStrList &inList) + { + QT3DSU32 numItems = 0; + visit(numItems); + inList.resize(numItems); + for (QT3DSU32 idx = 0, end = numItems; idx < end; ++idx) + visitId(inList[idx]); + } + + void visit(TTransitionIdList &inList) + { + QT3DSU32 numItems = 0; + visit(numItems); + inList.resize(numItems); + for (QT3DSU32 idx = 0, end = numItems; idx < end; ++idx) + inList[idx] = BreakpointTransition(); + } + + void visitEventName(TDebugStr &outStr) { visitId(outStr); } + + SStateEnterBreakpoint BreakpointStateEnter() + { + SStateEnterBreakpoint retval; + SBreakpointSerializationVisitor::Visit(*this, retval); + return retval; + } + + SStateExitBreakpoint BreakpointStateExit() + { + SStateExitBreakpoint retval; + SBreakpointSerializationVisitor::Visit(*this, retval); + return retval; + } + + STransitionId BreakpointTransition() + { + STransitionId retval; + SBreakpointSerializationVisitor::Visit(*this, retval); + return retval; + } + + void visit(SBreakpoint &breakpoint) + { + visitId(m_BreakpointTypeStr); +#define HANDLE_BREAKPOINT_TYPE(enumType, bpType) \ + if (AreEqual(STypeToName::GetName(), m_BreakpointTypeStr.c_str())) { \ + breakpoint = Breakpoint##enumType(); \ + } else + ITERATE_BREAKPOINT_TYPES +#undef HANDLE_BREAKPOINT_TYPE + // else is defined in the iterate breakpoints. + { + m_Valid = false; + m_CurrentHandler->error("Unrecognized breakpoint type: ", + m_BreakpointTypeStr.c_str()); + } + } + + template + void DoParseT(TDebugStr &inStr, QT3DSU64 inTimestamp, QT3DSI32 streamId, + TMessageHandler &inHandler) + { + TDataType theType; + m_ParseStr = inStr; + m_Valid = true; + m_CurrentHandler = &inHandler; + theType.Visit(*this); + if (m_Valid) + inHandler.OnMessage(streamId, inTimestamp, theType); + } + + // destructive parsing. + void Parse(NVConstDataRef data, TMessageHandler &inHandler) + { + m_ParseStr.assign((const char *)data.begin(), (const char *)data.end()); + Trim(m_ParseStr); + size_t spacePos = m_ParseStr.find_first_of(' '); + if (spacePos == TDebugStr::npos) { + m_ParseStr.assign((const char *)data.begin(), (const char *)data.end()); + inHandler.error("Failed to parse message: ", m_ParseStr.c_str()); + return; + } + qt3ds::QT3DSI32 streamId = 0; + visitId(m_MessageHeaderStr); + visit(streamId); + qt3ds::QT3DSU64 timestamp = 0; + visit(timestamp); +#define HANDLE_DEBUG_MESSAGE_TYPE(name) \ + if (AreEqual(STypeToName::GetName(), m_MessageHeaderStr.c_str())) { \ + DoParseT(m_ParseStr, timestamp, streamId, inHandler); \ + } else + ITERATE_DEBUG_MESSAGE_TYPES +#undef HANDLE_DEBUG_MESSAGE_TYPE + { + inHandler.error("Failed to parse message type: ", m_MessageHeaderStr.c_str()); + } + } + }; + + struct SMessageSerializer + { + TDebugStr m_Message; + void appendSpace() { m_Message.append(1, ' '); } + + void visitId(const TDebugStr &inStr) + { + m_Message.append(inStr); + appendSpace(); + } + template + void rawTypeToStr(const TDataType &inType) + { + char8_t buf[256] = { 0 }; + StringConversion().ToStr(inType, toDataRef(buf, 256)); + m_Message.append(buf); + appendSpace(); + } + void visit(QT3DSI32 inData) { rawTypeToStr(inData); } + void visit(QT3DSU32 inData) { rawTypeToStr(inData); } + + void visit(QT3DSU64 inData) { rawTypeToStr(inData); } + + void visit(bool inData) { rawTypeToStr(inData); } + + void visit(const TDebugStr &inStr) { randomText(inStr); } + + void visit(const SNil &) {} + + void visit(const TTransitionIdList &inData) + { + QT3DSU32 len = (QT3DSU32)inData.size(); + visit(len); + for (QT3DSU32 idx = 0; idx < len; ++idx) + Breakpoint(inData[idx]); + } + + void randomText(const TDebugStr &outStr) + { + QT3DSU32 len = (QT3DSU32)outStr.size(); + visit(len); + if (len) + m_Message.append(outStr); + appendSpace(); + } + + void visitIdList(const TDebugStrList &inList) + { + QT3DSU32 numItems = (QT3DSU32)inList.size(); + visit(numItems); + for (QT3DSU32 idx = 0; idx < numItems; ++idx) + visitId(inList[idx]); + } + + void visitEventName(const TDebugStr &outStr) { visitId(outStr); } + void visit(float inValue) { rawTypeToStr(inValue); } + template + void visitOpaquePtr(const TPtrType *inPtr) + { + size_t ptrValue = reinterpret_cast(inPtr); + QT3DSU64 fullValue = static_cast(ptrValue); + visit(fullValue); + } + + void visit(SDatamodelTable *inData) { visitOpaquePtr(inData); } + void visit(SDatamodelUserData *inData) { visitOpaquePtr(inData); } + void visit(SDatamodelFunction *inData) { visitOpaquePtr(inData); } + void visit(SDatamodelCFunction *inData) { visitOpaquePtr(inData); } + void visit(SDatamodelThread *inData) { visitOpaquePtr(inData); } + + void visit(const SDatamodelValue &inValue) + { + switch (inValue.getType()) { +#define HANDLE_DATAMODEL_VALUE_TYPE(name, dtype) \ + case DatamodelValueTypes::name: { \ + m_Message.append(#name); \ + appendSpace(); \ + visit(inValue.getData()); \ + break; \ + } + ITERATE_DATAMODEL_VALUE_TYPES +#undef HANDLE_DATAMODEL_VALUE_TYPE + default: + QT3DS_ASSERT(false); + break; + } + } + + void visit(const TTableModificationList &inModifications) + { + QT3DSU32 numItems = (QT3DSU32)inModifications.size(); + visit(numItems); + for (QT3DSU32 idx = 0, end = inModifications.size(); idx < end; ++idx) { + const STableModification &theMod(inModifications[idx]); + switch (theMod.m_Type) { + case TableModificationType::SetKey: { + m_Message.append("SetKey"); + appendSpace(); + visit(theMod.m_Entry.m_Key); + visit(theMod.m_Entry.m_Value); + break; + } + case TableModificationType::RemoveKey: { + m_Message.append("RemoveKey"); + appendSpace(); + visit(theMod.m_Entry.m_Key); + break; + } + default: + QT3DS_ASSERT(false); + m_Message.append("badvalue"); + appendSpace(); + continue; + } + } + } + void visit(TTableEntryList &inEntries) + { + QT3DSU32 numItems = (QT3DSU32)inEntries.size(); + visit(numItems); + for (QT3DSU32 idx = 0, end = inEntries.size(); idx < end; ++idx) { + const STableEntry &theEntry(inEntries[idx]); + visit(theEntry.m_Key); + visit(theEntry.m_Value); + } + } + + template + void Breakpoint(const TBreakpointType &inBp) + { + SBreakpointSerializationVisitor::Visit( + *this, const_cast(inBp)); + } + + void visit(const SBreakpoint &inBp) + { + switch (inBp.getType()) { +#define HANDLE_BREAKPOINT_TYPE(enumName, typeName) \ + case BreakpointTypes::enumName: \ + m_Message.append(STypeToName::GetName()); \ + appendSpace(); \ + Breakpoint(inBp.getData()); \ + break; + ITERATE_BREAKPOINT_TYPES +#undef HANDLE_BREAKPOINT_TYPE + default: + QT3DS_ASSERT(false); + break; + } + } + + template + void Serialize(QT3DSI32 inStreamId, const TMsgType &inMsg, QT3DSU64 inTimestamp) + { + m_Message.clear(); + m_Message.append(STypeToName::GetName()); + appendSpace(); + visit(inStreamId); + visit(inTimestamp); + const_cast(inMsg).Visit(*this); + } + + NVConstDataRef ToRawMessage() + { + if (m_Message.size() == 0) + return NVConstDataRef(); + return NVConstDataRef(reinterpret_cast(m_Message.c_str()), + (QT3DSU32)m_Message.size()); + } + }; + + template + struct SMsgComparer + { + static bool Compare(const TLhs &, const TRhs &) { return false; } + }; +#define HANDLE_DEBUG_MESSAGE_TYPE(typeName) \ + template <> \ + struct SMsgComparer \ + { \ + static bool Compare(const S##typeName &lhs, const S##typeName &rhs) { return lhs == rhs; } \ + }; + ITERATE_DEBUG_MESSAGE_TYPES; +#undef HANDLE_DEBUG_MESSAGE_TYPE + + template + struct STestMessageHandler + { + bool m_Result; + QT3DSU64 m_Timestamp; + QT3DSU32 m_StreamId; + const TMessageType &m_ExpectedResult; + + STestMessageHandler(QT3DSU32 sid, QT3DSU64 ts, const TMessageType &res) + : m_Result(false) + , m_Timestamp(ts) + , m_StreamId(sid) + , m_ExpectedResult(res) + { + } + + template + void OnMessage(QT3DSU32 sid, QT3DSU64 ts, const TCrapType &msgType) + { + if (ts == m_Timestamp && m_StreamId == sid) + m_Result = + SMsgComparer::Compare(msgType, m_ExpectedResult); + } + + void error(const char8_t *, const char8_t *) {} + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerValues.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerValues.h new file mode 100644 index 00000000..340f46cb --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateDebuggerValues.h @@ -0,0 +1,540 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_DEBUGGER_VALUES_H +#define QT3DS_STATE_DEBUGGER_VALUES_H +#pragma once +#include "Qt3DSStateDebugger.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" + +namespace qt3ds { +namespace state { + namespace debugger { + using namespace qt3ds::state::editor; + + // Force compile error if unsupported datatype requested + template + struct SDebugValueTypeMap + { + }; + + template <> + struct SDebugValueTypeMap + { + static DebugValueTypes::Enum GetType() { return DebugValueTypes::String; } + }; + template <> + struct SDebugValueTypeMap + { + static DebugValueTypes::Enum GetType() { return DebugValueTypes::StringList; } + }; + template <> + struct SDebugValueTypeMap + { + static DebugValueTypes::Enum GetType() { return DebugValueTypes::TransitionIdList; } + }; + + struct SDebugValueUnionTraits + { + typedef DebugValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(TDebugStrList), + }; + + static TIdType getNoDataId() { return DebugValueTypes::NoDebugValue; } + + template + static TIdType getType() + { + return SDebugValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case DebugValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case DebugValueTypes::StringList: + return inVisitor(*NVUnionCast(inData)); + case DebugValueTypes::TransitionIdList: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case DebugValueTypes::NoDebugValue: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case DebugValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case DebugValueTypes::StringList: + return inVisitor(*NVUnionCast(inData)); + case DebugValueTypes::TransitionIdList: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case DebugValueTypes::NoDebugValue: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SDebugValueUnionTraits::TBufferSize> + TDebugValueUnionType; + + struct SDebugValue : public TDebugValueUnionType + { + SDebugValue() {} + + SDebugValue(const SDebugValue &inOther) + : TDebugValueUnionType(static_cast(inOther)) + { + } + + SDebugValue(const char8_t *inOther) + : TDebugValueUnionType(TDebugStr(inOther)) + { + } + + template + SDebugValue(const TDataType &inDt) + : TDebugValueUnionType(inDt) + { + } + + SDebugValue &operator=(const SDebugValue &inOther) + { + TDebugValueUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SDebugValue &inOther) const + { + return TDebugValueUnionType::operator==(inOther); + } + bool operator!=(const SDebugValue &inOther) const + { + return TDebugValueUnionType::operator!=(inOther); + } + + bool empty() const { return getType() == DebugValueTypes::NoDebugValue; } + }; + + struct SDebugValueOpt : public Option + { + SDebugValueOpt(const SDebugValueOpt &inOther) + : Option(inOther) + { + } + SDebugValueOpt(const Empty &) + : Option() + { + } + SDebugValueOpt() {} + template + SDebugValueOpt(const TDataType &inOther) + : Option(SDebugValue(inOther)) + { + } + SDebugValueOpt &operator=(const SDebugValueOpt &inOther) + { + Option::operator=(inOther); + return *this; + } + }; + + // Breakpoint subtypes + + struct SStateEnterBreakpoint + { + TDebugStr m_ObjectId; + SStateEnterBreakpoint(const TDebugStr &inObj = TDebugStr()) + : m_ObjectId(inObj) + { + } + bool operator==(const SStateEnterBreakpoint &inOther) const + { + return m_ObjectId == inOther.m_ObjectId; + } + }; + + struct SStateExitBreakpoint + { + TDebugStr m_ObjectId; + SStateExitBreakpoint(const TDebugStr &inObj = TDebugStr()) + : m_ObjectId(inObj) + { + } + bool operator==(const SStateExitBreakpoint &inOther) const + { + return m_ObjectId == inOther.m_ObjectId; + } + }; + + template + struct SBreakpointTypeMap + { + static BreakpointTypes::Enum GetType() + { + return BreakpointTypes::UnknownBreakpointType; + } + }; + + template <> + struct SBreakpointTypeMap + { + static BreakpointTypes::Enum GetType() { return BreakpointTypes::StateEnter; } + }; + template <> + struct SBreakpointTypeMap + { + static BreakpointTypes::Enum GetType() { return BreakpointTypes::StateExit; } + }; + template <> + struct SBreakpointTypeMap + { + static BreakpointTypes::Enum GetType() { return BreakpointTypes::Transition; } + }; + + struct SBreakpointUnionTraits + { + typedef BreakpointTypes::Enum TIdType; + enum { + TBufferSize = sizeof(STransitionId), + }; + + static TIdType getNoDataId() { return BreakpointTypes::UnknownBreakpointType; } + + template + static TIdType getType() + { + return SBreakpointTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case BreakpointTypes::StateEnter: + return inVisitor(*NVUnionCast(inData)); + case BreakpointTypes::StateExit: + return inVisitor(*NVUnionCast(inData)); + case BreakpointTypes::Transition: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case BreakpointTypes::UnknownBreakpointType: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case BreakpointTypes::StateEnter: + return inVisitor(*NVUnionCast(inData)); + case BreakpointTypes::StateExit: + return inVisitor(*NVUnionCast(inData)); + case BreakpointTypes::Transition: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case BreakpointTypes::UnknownBreakpointType: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SBreakpointUnionTraits::TBufferSize> + TBreakpointUnionType; + + struct SBreakpoint : public TBreakpointUnionType + { + SBreakpoint() {} + + SBreakpoint(const SBreakpoint &inOther) + : TBreakpointUnionType(static_cast(inOther)) + { + } + + SBreakpoint(const char8_t *inOther) + : TBreakpointUnionType(TEditorStr(inOther)) + { + } + + template + SBreakpoint(const TDataType &inDt) + : TBreakpointUnionType(inDt) + { + } + + SBreakpoint &operator=(const SBreakpoint &inOther) + { + TBreakpointUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SBreakpoint &inOther) const + { + return TBreakpointUnionType::operator==(inOther); + } + bool operator!=(const SBreakpoint &inOther) const + { + return TBreakpointUnionType::operator!=(inOther); + } + + bool empty() const { return getType() == SBreakpointUnionTraits::getNoDataId(); } + }; + + struct SNil + { + bool operator==(const SNil &) const { return true; } + }; + +#define ITERATE_DATAMODEL_VALUE_TYPES \ + HANDLE_DATAMODEL_VALUE_TYPE(Number, float) \ + HANDLE_DATAMODEL_VALUE_TYPE(String, TDebugStr) \ + HANDLE_DATAMODEL_VALUE_TYPE(Nil, SNil) \ + HANDLE_DATAMODEL_VALUE_TYPE(Boolean, bool) \ + HANDLE_DATAMODEL_VALUE_TYPE(Table, SDatamodelTable *) \ + HANDLE_DATAMODEL_VALUE_TYPE(UserData, SDatamodelUserData *) \ + HANDLE_DATAMODEL_VALUE_TYPE(Function, SDatamodelFunction *) \ + HANDLE_DATAMODEL_VALUE_TYPE(CFunction, SDatamodelCFunction *) \ + HANDLE_DATAMODEL_VALUE_TYPE(Thread, SDatamodelThread *) + + template + struct SDatamodelValueTypeMap + { + }; + +#define HANDLE_DATAMODEL_VALUE_TYPE(name, type) \ + template <> \ + struct SDatamodelValueTypeMap \ + { \ + static DatamodelValueTypes::Enum GetType() { return DatamodelValueTypes::name; } \ + }; + ITERATE_DATAMODEL_VALUE_TYPES +#undef HANDLE_DATAMODEL_VALUE_TYPE + + struct SDatamodelValueUnionTraits + { + typedef DatamodelValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(TDebugStr), + }; + + static TIdType getNoDataId() { return DatamodelValueTypes::UnknownType; } + + template + static TIdType getType() + { + return SDatamodelValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { +#define HANDLE_DATAMODEL_VALUE_TYPE(name, type) \ + case DatamodelValueTypes::name: \ + return inVisitor(*NVUnionCast(inData)); + ITERATE_DATAMODEL_VALUE_TYPES +#undef HANDLE_DATAMODEL_VALUE_TYPE + default: + QT3DS_ASSERT(false); + case DatamodelValueTypes::UnknownType: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { +#define HANDLE_DATAMODEL_VALUE_TYPE(name, type) \ + case DatamodelValueTypes::name: \ + return inVisitor(*NVUnionCast(inData)); + ITERATE_DATAMODEL_VALUE_TYPES +#undef HANDLE_DATAMODEL_VALUE_TYPE + default: + QT3DS_ASSERT(false); + case DatamodelValueTypes::UnknownType: + return inVisitor(); + } + } + }; + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SDatamodelValueUnionTraits::TBufferSize> + TDatamodelValueUnionType; + + struct SDatamodelValue : public TDatamodelValueUnionType + { + SDatamodelValue() {} + + SDatamodelValue(const SDatamodelValue &inOther) + : TDatamodelValueUnionType(static_cast(inOther)) + { + } + + SDatamodelValue(const char8_t *inOther) + : TDatamodelValueUnionType(TDebugStr(inOther)) + { + } + + template + SDatamodelValue(const TDataType &inDt) + : TDatamodelValueUnionType(inDt) + { + } + + SDatamodelValue &operator=(const SDatamodelValue &inOther) + { + TDatamodelValueUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SDatamodelValue &inOther) const + { + return TDatamodelValueUnionType::operator==(inOther); + } + bool operator!=(const SDatamodelValue &inOther) const + { + return TDatamodelValueUnionType::operator!=(inOther); + } + + bool empty() const { return getType() == SDatamodelValueUnionTraits::getNoDataId(); } + }; + + struct STableEntry + { + TDebugStr m_Key; + SDatamodelValue m_Value; + STableEntry(const TDebugStr &inKey = TDebugStr(), + const SDatamodelValue &inValue = SDatamodelValue()) + : m_Key(inKey) + , m_Value(inValue) + { + } + + bool operator==(const STableEntry &inOther) const + { + return m_Key == inOther.m_Key && m_Value == inOther.m_Value; + } + }; + + struct TableModificationType + { + enum Enum { + UnknownModification = 0, + SetKey = 1, + RemoveKey = 2, + }; + }; + + struct STableModification + { + STableEntry m_Entry; + TableModificationType::Enum m_Type; + STableModification( + const STableEntry &inEntry = STableEntry(), + TableModificationType::Enum inEnum = TableModificationType::UnknownModification) + : m_Entry(inEntry) + , m_Type(inEnum) + { + } + bool operator==(const STableModification &inMod) const + { + return inMod.m_Entry == m_Entry && inMod.m_Type == m_Type; + } + }; + + typedef eastl::vector TTableModificationList; + } +} +} + +#ifndef _INTEGRITYPLATFORM +namespace qt3ds { +namespace foundation { + template <> + struct DestructTraits + { + void destruct(qt3ds::state::debugger::SNil &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::debugger::SDatamodelTable *) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::debugger::SDatamodelUserData *) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::debugger::SDatamodelFunction *) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::debugger::SDatamodelCFunction *) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::state::debugger::SDatamodelThread *) {} + }; +} +} +#endif + +#endif diff --git a/src/Runtime/Source/stateapplication/debugger/Qt3DSStateTest.h b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateTest.h new file mode 100644 index 00000000..6edbe366 --- /dev/null +++ b/src/Runtime/Source/stateapplication/debugger/Qt3DSStateTest.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_TEST_H +#define QT3DS_STATE_TEST_H +#include "Qt3DSState.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" + +namespace qt3ds { +namespace state { + namespace test { + + struct LogType + { + enum Enum { + Error = 0, + Info = 1, + }; + }; + + struct STestResults + { + QT3DSU32 m_TotalTests; + QT3DSU32 m_PassingTests; + STestResults(QT3DSU32 totalTests = 0, QT3DSU32 testPassed = 0) + : m_TotalTests(totalTests) + , m_PassingTests(testPassed) + { + } + STestResults &operator+=(const STestResults &inOther) + { + m_TotalTests += inOther.m_TotalTests; + m_PassingTests += inOther.m_PassingTests; + return *this; + } + + bool Failed() const { return m_TotalTests != m_PassingTests; } + bool Passed() const { return !Failed(); } + }; + + class IDataLogger + { + protected: + virtual ~IDataLogger() {} + public: + virtual void Log(LogType::Enum inLogType, const char8_t *file, int line, + const char8_t *message) = 0; + }; + + // Run a data test returning a true/false result for pass/fail. + class IDataTest + { + public: + static Option RunFile(const char8_t *fname, const char8_t *inRootDir, + IDataLogger &inLogger); + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSSceneGraphArchitectDebugger.cpp b/src/Runtime/Source/stateapplication/editor/Qt3DSSceneGraphArchitectDebugger.cpp new file mode 100644 index 00000000..e15f587d --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSSceneGraphArchitectDebugger.cpp @@ -0,0 +1,574 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSSceneGraphDebugger.h" +#include "Qt3DSSceneGraphDebuggerValue.h" +#include "Qt3DSSceneGraphDebuggerProtocol.h" +#include "Qt3DSUIADatamodel.h" +#include "Qt3DSStateEditorValue.h" +#include "Qt3DSUIADatamodelValue.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSKernelTypes.h" +#include "Qt3DSHash.h" //we need to duplicate the hash attribute calls +#include "EASTL/set.h" + +using namespace qt3ds; +using namespace qt3ds::state; +using namespace qt3ds::app; +using namespace qt3ds::state::debugger; + +namespace { + +struct SAppElemVectorSet +{ + nvvector m_Elements; + eastl::hash_set, eastl::equal_to, + ForwardingAllocator> + m_Set; + SAppElemVectorSet(NVAllocatorCallback &alloc) + : m_Elements(alloc, "AppElemVectorSet") + , m_Set(ForwardingAllocator(alloc, "AppElemVectorSet")) + { + } + + void insert(SAppElement *elem) + { + if (m_Set.insert(elem).second) + m_Elements.push_back(elem); + } + + void clear() + { + m_Elements.clear(); + m_Set.clear(); + } + NVConstDataRef ToDataRef() { return m_Elements; } +}; + +struct SValueIndex +{ + QT3DSU32 m_ValueIndex; + QT3DSU32 m_Component; + SValueIndex(QT3DSU32 vi, QT3DSU32 component) + : m_ValueIndex(vi) + , m_Component(component) + { + } +}; + +struct SAppElementEntry +{ + Q3DStudio::TAttOrArgList m_AttList; + eastl::hash_map m_HashToIndexMap; + eastl::vector m_RuntimeValues; +}; + +struct SPresentationEntry +{ + CRegisteredString m_Id; + eastl::hash_map m_ElementMap; +}; + +Option ValueToFloat(const SSGValue &val) +{ + if (val.getType() == SGPropertyValueTypes::Float) + return val.getData(); + return Empty(); +} + +Option ValueToInteger(const SSGValue &val) +{ + if (val.getType() == SGPropertyValueTypes::I32) + return val.getData(); + return Empty(); +} + +Option ValueToString(const SSGValue &val) +{ + if (val.getType() == SGPropertyValueTypes::String) + return val.getData(); + return Empty(); +} + +template +struct SValueSetter +{ +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue &incoming, float &outgoing, QT3DSU32 /*component*/) + { + Option val = ValueToFloat(incoming); + if (val.hasValue()) + outgoing = *val; + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue &incoming, QT3DSVec2 &outgoing, QT3DSU32 component) + { + Option val = ValueToFloat(incoming); + if (val.hasValue()) { + switch (component) { + case 0: + outgoing.x = *val; + break; + case 1: + outgoing.y = *val; + break; + default: + QT3DS_ASSERT(false); + break; + } + } + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue &incoming, QT3DSVec3 &outgoing, QT3DSU32 component) + { + Option val = ValueToFloat(incoming); + if (val.hasValue()) { + switch (component) { + case 0: + outgoing.x = *val; + break; + case 1: + outgoing.y = *val; + break; + case 2: + outgoing.z = *val; + break; + default: + QT3DS_ASSERT(false); + break; + } + } + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue &incoming, QT3DSI32 &outgoing, QT3DSU32 /*component*/) + { + Option val = ValueToInteger(incoming); + if (val.hasValue()) + outgoing = *val; + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue &incoming, eastl::string &outgoing, QT3DSU32 /*component*/) + { + Option val = ValueToString(incoming); + if (val.hasValue()) + outgoing = eastl::string(val->c_str()); + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue &incoming, bool &outgoing, QT3DSU32 /*component*/) + { + Option val = ValueToInteger(incoming); + if (val.hasValue()) + outgoing = (*val) != 0 ? true : false; + } +}; + +// Element ref. Not sure what to do about this right now +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue & /*incoming*/, SGuid & /*outgoing*/, QT3DSU32 /*component*/) + { + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue & /*incoming*/, CRegisteredString & /*outgoing*/, + QT3DSU32 /*component*/) + { + QT3DS_ASSERT(false); + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue & /*incoming*/, SObjectRef & /*outgoing*/, + QT3DSU32 /*component*/) + { + } +}; + +template <> +struct SValueSetter +{ + static void SetValue(const SSGValue & /*incoming*/, CStringOrInt & /*outgoing*/, + QT3DSU32 /*component*/) + { + } +}; + +struct SValueSetterVisitor +{ + const SSGValue &m_Incoming; + QT3DSU32 m_Component; + SValueSetterVisitor &operator=(const SValueSetterVisitor &); + SValueSetterVisitor(const SSGValue &i, QT3DSU32 c) + : m_Incoming(i) + , m_Component(c) + { + } + template + void operator()(TDataType &dt) + { + SValueSetter::SetValue(m_Incoming, dt, m_Component); + } + // object refs can generate this response. + void operator()() {} +}; + +void SetComponentValue(const SSGValue &incoming, app::SDatamodelValue &outgoing, QT3DSU32 component) +{ + SValueSetterVisitor visitor(incoming, component); + outgoing.visit(visitor); +} + +struct SArchitectDebuggerImpl : public ISceneGraphArchitectDebugger +{ + NVFoundationBase &m_Foundation; + NVScopedRefCounted m_Datamodel; + NVScopedRefCounted m_Stream; + ISceneGraphArchitectDebuggerListener *m_Listener; + nvhash_map m_ElemAppElemMap; + nvhash_map m_RuntimeValues; + SAppElemVectorSet m_DirtySet; + eastl::vector m_Presentations; + bool m_Valid; + QT3DSI32 mRefCount; + + SArchitectDebuggerImpl(IDatamodel &dm) + : m_Foundation(dm.GetFoundation()) + , m_Datamodel(dm) + , m_Stream(NULL) + , m_Listener(NULL) + , m_ElemAppElemMap(dm.GetFoundation().getAllocator(), "ElemAppMap") + , m_RuntimeValues(dm.GetFoundation().getAllocator(), "RuntimeValues") + , m_DirtySet(dm.GetFoundation().getAllocator()) + , m_Valid(true) + , mRefCount(0) + { + } + + void addRef() { atomicIncrement(&mRefCount); } + void release() + { + // ensure the datamodel sticks around until after we are destroyed + NVScopedRefCounted dm(m_Datamodel); + atomicDecrement(&mRefCount); + if (mRefCount <= 0) { + NVDelete(m_Foundation.getAllocator(), this); + } + } + + virtual IDatamodel &GetDatamodel() { return *m_Datamodel; } + + static QT3DSI32 GetHashValue(const char *name, const char *component, eastl::string &ioWorkspace) + { + ioWorkspace.assign(nonNull(name)); + ioWorkspace.append("."); + ioWorkspace.append(component); + return Q3DStudio::CHash::HashAttribute(ioWorkspace.c_str()); + } + + void AppendAttribute(const char *name, const char *formalName, ERuntimeDataModelDataType dtype, + SAppElementEntry &theEntry) + { + SAttOrArg newValue; + newValue.m_Name = name; + newValue.m_FormalName = formalName; + newValue.m_DataType = dtype; + theEntry.m_AttList.push_back(newValue); + theEntry.m_RuntimeValues.push_back(qt3ds::app::SDatamodelValue()); + } + + void LoadAppElement(SAppElement &elem, SPresentationEntry &entry) + { + entry.m_ElementMap.insert(eastl::make_pair( + m_Datamodel->GetStringTable().RegisterStr(m_Datamodel->GetElementId(elem).c_str()), + &elem)); + SAppElementEntry &theEntry = m_RuntimeValues[&elem]; + theEntry.m_AttList = m_Datamodel->GetElementAttributes(elem); + theEntry.m_RuntimeValues = m_Datamodel->GetElementAttributeInitialValues(elem); + AppendAttribute("active", "Active", ERuntimeDataModelDataTypeBool, theEntry); + + if (m_Datamodel->IsComponent(elem)) { + AppendAttribute("slide", "(Slide)", ERuntimeDataModelDataTypeLong, theEntry); + AppendAttribute("time", "(Time)", ERuntimeDataModelDataTypeLong, theEntry); + AppendAttribute("paused", "(Mode)", ERuntimeDataModelDataTypeBool, theEntry); + } + eastl::string hashTemp; + for (QT3DSU32 idx = 0, end = (QT3DSU32)theEntry.m_AttList.size(); idx < end; ++idx) { + // Build out the component hash names. + const Q3DStudio::SAttOrArg &theProp(theEntry.m_AttList[idx]); + switch (theProp.m_DataType) { + // one component, one hash, just hash the name + default: + theEntry.m_HashToIndexMap.insert( + eastl::make_pair((QT3DSI32)Q3DStudio::CHash::HashAttribute(theProp.m_Name.c_str()), + SValueIndex(idx, 0))); + break; + case ERuntimeDataModelDataTypeFloat2: { + theEntry.m_HashToIndexMap.insert(eastl::make_pair( + GetHashValue(theProp.m_Name.c_str(), "x", hashTemp), SValueIndex(idx, 0))); + theEntry.m_HashToIndexMap.insert(eastl::make_pair( + GetHashValue(theProp.m_Name.c_str(), "y", hashTemp), SValueIndex(idx, 1))); + } break; + case ERuntimeDataModelDataTypeFloat3: { + const char *compNames[3] = { "x", "y", "z" }; + if (theProp.m_MetaType == ERuntimeAdditionalMetaDataTypeColor) { + compNames[0] = "r"; + compNames[1] = "g"; + compNames[2] = "b"; + } + + theEntry.m_HashToIndexMap.insert( + eastl::make_pair(GetHashValue(theProp.m_Name.c_str(), compNames[0], hashTemp), + SValueIndex(idx, 0))); + theEntry.m_HashToIndexMap.insert( + eastl::make_pair(GetHashValue(theProp.m_Name.c_str(), compNames[1], hashTemp), + SValueIndex(idx, 1))); + theEntry.m_HashToIndexMap.insert( + eastl::make_pair(GetHashValue(theProp.m_Name.c_str(), compNames[2], hashTemp), + SValueIndex(idx, 2))); + } break; + } + // Set a value + if (theEntry.m_RuntimeValues[idx].getType() == ERuntimeDataModelDataTypeNone) { + switch (theProp.m_DataType) { + case ERuntimeDataModelDataTypeFloat: + theEntry.m_RuntimeValues[idx] = 0.0f; + break; + case ERuntimeDataModelDataTypeFloat2: + theEntry.m_RuntimeValues[idx] = QT3DSVec2(0, 0); + break; + case ERuntimeDataModelDataTypeFloat3: + theEntry.m_RuntimeValues[idx] = QT3DSVec3(0, 0, 0); + break; + case ERuntimeDataModelDataTypeLong: + theEntry.m_RuntimeValues[idx] = (QT3DSI32)0; + break; + case ERuntimeDataModelDataTypeString: + theEntry.m_RuntimeValues[idx] = eastl::string(); + break; + case ERuntimeDataModelDataTypeBool: + theEntry.m_RuntimeValues[idx] = false; + break; + case ERuntimeDataModelDataTypeStringRef: + theEntry.m_RuntimeValues[idx] = eastl::string(); + break; + // object references are stored as string values. + case ERuntimeDataModelDataTypeObjectRef: + theEntry.m_RuntimeValues[idx] = eastl::string(); + break; + case ERuntimeDataModelDataTypeStringOrInt: + theEntry.m_RuntimeValues[idx] = eastl::string(); + break; + } + } + } + eastl::vector children = m_Datamodel->GetElementChildren(elem); + for (size_t childIdx = 0, childEnd = children.size(); childIdx < childEnd; ++childIdx) { + LoadAppElement(*children[childIdx], entry); + } + } + + void LoadDatamodel() + { + eastl::vector presentations = m_Datamodel->GetPresentations(); + m_Presentations.clear(); + m_RuntimeValues.clear(); + m_ElemAppElemMap.clear(); + m_Presentations.resize(presentations.size()); + for (size_t idx = 0, end = presentations.size(); idx < end; ++idx) { + app::SPresentation &incoming(presentations[idx]); + SPresentationEntry &pres = m_Presentations[idx]; + pres.m_Id = m_Datamodel->GetStringTable().RegisterStr(incoming.m_Id.c_str()); + if (incoming.m_Scene) + LoadAppElement(*incoming.m_Scene, pres); + } + } + + SAppElementEntry *GetRuntimeValues(app::SAppElement &elem) + { + nvhash_map::iterator iter = m_RuntimeValues.find(&elem); + if (iter != m_RuntimeValues.end()) + return &iter->second; + return NULL; + } + + SPresentationEntry *FindPresentation(CRegisteredString &str) + { + for (size_t idx = 0, end = m_Presentations.size(); idx < end; ++idx) + if (m_Presentations[idx].m_Id == str) + return &m_Presentations[idx]; + return NULL; + } + + /*External interface for clients*/ + + void SetListener(ISceneGraphArchitectDebuggerListener *listener) { m_Listener = listener; } + + Q3DStudio::TAttOrArgList GetElementAttributes(app::SAppElement &elem) + { + SAppElementEntry *entry = GetRuntimeValues(elem); + if (entry) + return entry->m_AttList; + return Q3DStudio::TAttOrArgList(); + } + + eastl::vector GetElementAttributeValues(app::SAppElement &elem) + { + SAppElementEntry *entry = GetRuntimeValues(elem); + if (entry) + return entry->m_RuntimeValues; + return eastl::vector(); + } + + void OnMessageReceived(const SDebugStreamMessage &inMessage) + { + if (!m_Valid) + return; + SSGProtocolReader theReader(inMessage.m_Data, m_Datamodel->GetStringTable()); + while (theReader.Finished() == false && m_Valid) { + SSGProtocolMessageTypes::Enum theMessageType = theReader.MessageType(); + switch (theMessageType) { + case SSGProtocolMessageTypes::Initialization: { + QT3DSU32 version = theReader.ReadInitialization(); + if (version > GetSceneGraphProtocolVersion()) { + QT3DS_ASSERT(false); + m_Foundation.error(QT3DS_INVALID_OPERATION, + "Invalid scene graph debugger protocol version"); + m_Valid = false; + } + } break; + case SSGProtocolMessageTypes::IdUpdate: { + SIdUpdate theUpdate = theReader.ReadIdUpdate(); + SPresentationEntry *theEntry = FindPresentation(theUpdate.m_PresentationId); + if (theEntry) { + for (size_t idx = 0, end = theUpdate.m_IdUpdates.size(); idx < end; ++idx) { + const SElemMap &elemMap(theUpdate.m_IdUpdates[idx]); + eastl::hash_map::iterator iter = + theEntry->m_ElementMap.find(elemMap.m_Id); + if (iter != theEntry->m_ElementMap.end()) + m_ElemAppElemMap[elemMap.m_Elem] = iter->second; + else { + QT3DS_ASSERT(false); + m_Foundation.error(QT3DS_WARN, "Failed to map element"); + } + } + } + } break; + case SSGProtocolMessageTypes::ElemUpdate: { + SElemUpdate theUpdate = theReader.ReadElemUpdate(); + nvhash_map::iterator ptrToElem = + m_ElemAppElemMap.find(theUpdate.m_Elem); + if (ptrToElem != m_ElemAppElemMap.end()) { + nvhash_map::iterator elemToEntry = + m_RuntimeValues.find(ptrToElem->second); + if (elemToEntry != m_RuntimeValues.end()) { + SAppElementEntry &theEntry(elemToEntry->second); + m_DirtySet.insert(elemToEntry->first); + for (size_t idx = 0, end = theUpdate.m_Updates.size(); idx < end; ++idx) { + const SValueUpdate &theValue(theUpdate.m_Updates[idx]); + eastl::hash_map::iterator hashIndex = + theEntry.m_HashToIndexMap.find(theValue.m_Hash); + if (hashIndex != theEntry.m_HashToIndexMap.end()) { + const SValueIndex theIdx = hashIndex->second; + SetComponentValue(theValue.m_Value, + theEntry.m_RuntimeValues[theIdx.m_ValueIndex], + theIdx.m_Component); + } + } + } else { + QT3DS_ASSERT(false); + m_Foundation.error(QT3DS_WARN, "Failed to map element"); + } + } else { + QT3DS_ASSERT(false); + m_Foundation.error(QT3DS_WARN, "Failed to map element"); + } + } break; + case SSGProtocolMessageTypes::Frame: { + NVConstDataRef dirtyItems = m_DirtySet.ToDataRef(); + if (dirtyItems.size() && m_Listener) { + m_Listener->OnItemsDirty(dirtyItems); + m_DirtySet.clear(); + } + } break; + } + } // end while + } + + void AttachToStream(IDebugOutStream &inStream) { m_Stream = &inStream; } + + void RefreshData(bool inNeedReloadData) + { + if (inNeedReloadData) + m_Datamodel->RefreshFile(); + LoadDatamodel(); + } +}; +} + +ISceneGraphArchitectDebugger & +ISceneGraphArchitectDebugger::Create(qt3ds::app::IDatamodel &inDatamodel) +{ + SArchitectDebuggerImpl &retval = + *QT3DS_NEW(inDatamodel.GetFoundation().getAllocator(), SArchitectDebuggerImpl)(inDatamodel); + retval.LoadDatamodel(); + return retval; +} diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateDebuggerMaster.cpp b/src/Runtime/Source/stateapplication/editor/Qt3DSStateDebuggerMaster.cpp new file mode 100644 index 00000000..83fe016f --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateDebuggerMaster.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateDebugger.h" +#include "Qt3DSStateDebuggerProtocol.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSAtomic.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::debugger; + +namespace { +MallocAllocator g_MallocAlloc; + +struct SDebugStrInStream : public IInStream +{ + size_t m_Pos; + const TDebugStr &m_Str; + SDebugStrInStream(const TDebugStr &inStr) + : m_Pos(0) + , m_Str(inStr) + { + } + virtual QT3DSU32 Read(NVDataRef data) + { + size_t available = NVMin((size_t)data.size(), m_Str.size() - m_Pos); + if (available) { + memCopy(data.begin(), m_Str.data() + m_Pos, (QT3DSU32)available); + m_Pos += available; + } + return (QT3DSU32)available; + } +}; + +struct SDebuggerMaster : public IDebuggerMaster +{ + typedef eastl::hash_map> TIdInterpreterMap; + + QT3DSI32 mRefCount; + NVScopedRefCounted m_OutStream; + TIdInterpreterMap m_Interpreters; + IDebuggerMasterListener &m_Listener; + SMessageSerializer m_Serializer; + SMessageParser m_Parser; + TDebugStr m_LogStr; + TDebugStr m_MessageStr; + bool m_Invalid; + + SDebuggerMaster(IDebugOutStream &inStream, IDebuggerMasterListener &listener) + : mRefCount(0) + , m_OutStream(inStream) + , m_Listener(listener) + , m_Invalid(false) + { + } + + virtual ~SDebuggerMaster() + { + // Disconnect(); + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_MallocAlloc); + + template + void SendMessage(QT3DSI32 inStreamId, const TMessageType &inMessage) + { + m_Serializer.Serialize(inStreamId, inMessage, 0); + m_OutStream->Write(m_Serializer.ToRawMessage()); + } + + virtual void OnMessageReceived(const SDebugStreamMessage &inMessage) + { + if (m_Invalid) + return; + m_Parser.Parse(inMessage.m_Data, *this); + } + + void ReleaseAllInterpreters() + { + for (TIdInterpreterMap::iterator iter = m_Interpreters.begin(), end = m_Interpreters.end(); + iter != end; ++iter) { + iter->second->Disconnect(); + m_Listener.OnInterpreterDisconnected(*iter->second.mPtr); + } + m_Interpreters.clear(); + } + + virtual void Disconnect() + { + SendMessage(-1, SDisconnect()); + ReleaseAllInterpreters(); + } + + IDebuggedInterpreter *FindInterpreter(QT3DSI32 inStreamId) + { + TIdInterpreterMap::iterator iter = m_Interpreters.find(inStreamId); + if (iter != m_Interpreters.end()) + return iter->second.mPtr; + return NULL; + } + +// Set of ignored messages +#define IGNORE_DEBUG_MESSAGE_TYPE(tname) \ + void OnMessage(QT3DSU32, QT3DSU64, const S##tname &) { QT3DS_ASSERT(false); } + + // this are outgoing messages; we shouldn't be receiving them. + IGNORE_DEBUG_MESSAGE_TYPE(SetBreakpoint) + IGNORE_DEBUG_MESSAGE_TYPE(ClearBreakpoint) + IGNORE_DEBUG_MESSAGE_TYPE(BreakOnMicrostep) + IGNORE_DEBUG_MESSAGE_TYPE(ClearAllBreakpoints) + IGNORE_DEBUG_MESSAGE_TYPE(Continue) + + void OnMessage(QT3DSU32 sid, QT3DSU64, const SConnect &inMessage) + { + SDebugStrInStream theStream(inMessage.m_SCXMLData); + TEditorPtr theEditor(IEditor::CreateEditor(inMessage.m_Filename.c_str(), theStream)); + if (theEditor) { + IDebuggedInterpreter &theInterpreter = IDebuggedInterpreter::Create( + g_MallocAlloc, *m_OutStream.mPtr, theEditor, inMessage.m_Filename, sid, + toConstDataRef(inMessage.m_Configuration.data(), + (QT3DSU32)inMessage.m_Configuration.size()), + m_Listener); + m_Interpreters.insert(eastl::make_pair(sid, &theInterpreter)); + m_Listener.OnInterpreterConnected(theInterpreter); + } else { + m_LogStr.assign("Connection failed: "); + m_LogStr.append(inMessage.m_Filename); + // log the failure somehow. + m_Listener.OnLog(NULL, m_LogStr); + } + } + + void OnMessage(QT3DSU32 sid, QT3DSU64, const SBreakpointHit &inMessage) + { + IDebuggedInterpreter *interp = FindInterpreter(sid); + if (interp) + interp->BreakpointHit(inMessage.m_Breakpoint); + } + + void OnMessage(QT3DSU32, QT3DSU64, const SInitialization &inMessage) + { + if (inMessage.m_Version != SInitialization::GetCurrentVersion()) { + QT3DS_ASSERT(false); + m_Invalid = true; + } + } + + void OnMessage(QT3DSU32 sid, QT3DSU64, const SDebugLog &inMessage) + { + IDebuggedInterpreter *interp = FindInterpreter(sid); + m_Listener.OnLog(interp, inMessage.m_Message); + } + +#define FORWARD_INTERPRETER_EVENT(evnType, interpFun) \ + void OnMessage(QT3DSI32 sid, QT3DSU64, const evnType &inMsg) \ + { \ + IDebuggedInterpreter *interp = FindInterpreter(sid); \ + if (interp) \ + interp->interpFun(inMsg); \ + } + + FORWARD_INTERPRETER_EVENT(SEventQueued, OnEventQueued); + FORWARD_INTERPRETER_EVENT(SBeginStep, OnBeginStep); + FORWARD_INTERPRETER_EVENT(SBeginMicrostep, OnBeginMicrostep); + FORWARD_INTERPRETER_EVENT(SMicrostepEvent, OnMicrostepEvent); + FORWARD_INTERPRETER_EVENT(SMicrostepData, OnMicrostepData); + FORWARD_INTERPRETER_EVENT(SEndMicrostep, OnEndMicrostep); + FORWARD_INTERPRETER_EVENT(SModifyTableValues, OnModifyTable); + + void OnMessage(QT3DSI32 sid, QT3DSU64, const SDisconnect &) + { + if (sid > 0) { + IDebuggedInterpreter *interp = FindInterpreter(sid); + if (interp) { + m_Listener.OnInterpreterDisconnected(*interp); + m_Interpreters.erase(sid); + } + } else { + ReleaseAllInterpreters(); + } + } + + void error(const char8_t *inPrefix, const char8_t *inSuffix) + { + m_LogStr.assign(nonNull(inPrefix)); + m_LogStr.append(nonNull(inSuffix)); + m_Listener.OnLog(NULL, m_LogStr); + } +}; +} + +IDebuggerMaster &IDebuggerMaster::CreateMaster(IDebugOutStream &outStream, + IDebuggerMasterListener &inListener) +{ + return *QT3DS_NEW(g_MallocAlloc, SDebuggerMaster)(outStream, inListener); +} \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.cpp b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.cpp new file mode 100644 index 00000000..6891fab0 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.cpp @@ -0,0 +1,1880 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSState.h" +#include "Qt3DSStateEditorEditorsImpl.h" +#include "Qt3DSStateExecutionContext.h" +#include "EASTL/sort.h" + +using namespace qt3ds::state; +using namespace qt3ds::state::editor; + +namespace qt3ds { +namespace state { + namespace editor { + +#pragma warning(disable : 4355) + + SEditorImpl::SEditorImpl(TFoundationPtr inFoundation, + NVScopedRefCounted inStringTable) + : m_EditorFoundation(inFoundation) + , m_StringTable(inStringTable) + , m_AutoAllocator(m_EditorFoundation->getFoundation()) + , m_StateContext(IStateContext::Create(m_EditorFoundation->getFoundation())) + , m_Editors(m_EditorFoundation->getAllocator(), "SEditorImpl::m_Editors") + , mRefCount(0) + , m_TransactionManager( + QT3DS_NEW(inFoundation->getAllocator(), STransactionManagerImpl)(inFoundation)) + , m_Accessors(m_EditorFoundation->getAllocator(), "SEditorImpl::m_Accessors") + , m_CopyPasteListener(NULL) + { + } + + void SEditorImpl::addRef() { atomicIncrement(&mRefCount); } + + void SEditorImpl::release() + { + QT3DSI32 count = atomicDecrement(&mRefCount); + if (count <= 0) { + TFoundationPtr theFoundation(m_EditorFoundation); + NVDelete(theFoundation->getAllocator(), this); + } + } + + TObjPtr SEditorImpl::InsertEditor(void *inData, IEditorObject *inEditor) + { + if (inEditor) { + bool insertResult = m_Editors.insert(eastl::make_pair(inData, inEditor)).second; + QT3DS_ASSERT(insertResult); + (void)insertResult; + } + return inEditor; + } + + template + TObjPtr SEditorImpl::ToEditor(TStateType &inItem) + { + TStateEditorMap::iterator iter = m_Editors.find(&inItem); + if (iter != m_Editors.end()) + return iter->second; + + TObjPtr retval = SStateEditorMap::CreateEditor(inItem, *this, m_Accessors); + if (retval) + InsertEditor(&inItem, retval.mPtr); + return retval; + } + + template + TObjPtr SEditorImpl::ToEditor(TStateType *inItem) + { + if (inItem == NULL) + return TObjPtr(); + + return ToEditor(*inItem); + } + + TObjPtr SEditorImpl::ToEditor(SStateNode &inItem) + { + switch (inItem.m_Type) { + case StateNodeTypes::State: + return ToEditor(static_cast(inItem)); + case StateNodeTypes::Parallel: + return ToEditor(static_cast(inItem)); + case StateNodeTypes::Transition: + return ToEditor(static_cast(inItem)); + case StateNodeTypes::Final: + return ToEditor(static_cast(inItem)); + case StateNodeTypes::SCXML: + return ToEditor(static_cast(inItem)); + case StateNodeTypes::History: + return ToEditor(static_cast(inItem)); + default: + QT3DS_ASSERT(false); + return TObjPtr(); + } + } + + TObjPtr SEditorImpl::ExecutableContentToEditor(SExecutableContent &inItem) + { + TStateEditorMap::iterator iter = m_Editors.find(&inItem); + if (iter != m_Editors.end()) + return iter->second; + + switch (inItem.m_Type) { + case ExecutableContentTypes::Send: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::Raise: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::Log: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::Assign: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::If: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::ElseIf: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::Else: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::Script: + return ToEditor(static_cast(inItem)); + case ExecutableContentTypes::Cancel: + return ToEditor(static_cast(inItem)); + default: + QT3DS_ASSERT(false); + return TObjPtr(); + } + } + + template + TStateType *SEditorImpl::FromEditor(TObjPtr inPtr) + { + if (inPtr.mPtr == NULL) + return NULL; + const char8_t *typeName = inPtr->TypeName(); + typedef typename SStateEditorMap::TEditorType TProspectiveType; + if (AreEqual(typeName, TProspectiveType::GetTypeStr())) { + return reinterpret_cast( + &static_cast(inPtr.mPtr)->m_Data); + } + return NULL; + } + + SStateNode *SEditorImpl::StateNodeFromEditor(TObjPtr inPtr) + { + if (inPtr.mPtr == NULL) + return NULL; + const char8_t *typeName = inPtr->TypeName(); + if (AreEqual(typeName, SSCXMLEditor::GetTypeStr())) + return FromEditor(inPtr); + if (AreEqual(typeName, SStateEditor::GetTypeStr())) + return FromEditor(inPtr); + if (AreEqual(typeName, STransitionEditor::GetTypeStr())) + return FromEditor(inPtr); + if (AreEqual(typeName, SParallelEditor::GetTypeStr())) + return FromEditor(inPtr); + if (AreEqual(typeName, SFinalEditor::GetTypeStr())) + return FromEditor(inPtr); + if (AreEqual(typeName, SHistoryEditor::GetTypeStr())) + return FromEditor(inPtr); + return NULL; + } + + SExecutableContent *SEditorImpl::ExecutableContentFromEditor(TObjPtr inPtr) + { + if (inPtr.mPtr == NULL) + return NULL; + const char8_t *typeName = inPtr->TypeName(); + if (AreEqual(typeName, SSendEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SRaiseEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SLogEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SAssignEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SIfEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SElseIfEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SElseEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SScriptEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + if (AreEqual(typeName, SCancelEditor::GetTypeStr())) { + return FromEditor(inPtr); + } + + return NULL; + } + + void SEditorImpl::GenerateUniqueId(SStateNode &inNode, const char8_t *inStem) + { + QT3DS_ASSERT(inNode.m_Id.IsValid() == false); + CXMLIO::GenerateUniqueId(inNode, inStem, *m_StateContext, *m_StringTable); + } + + void SEditorImpl::GenerateUniqueId(SSend &inNode, const char8_t *inStem) + { + CXMLIO::GenerateUniqueId(inNode, inStem, *m_StateContext, *m_StringTable); + } + + TObjPtr SEditorImpl::GetRoot() { return ToEditor(m_StateContext->GetRoot()); } + + template + eastl::pair SEditorImpl::CreateEditorAndObject() + { + typedef typename SStateEditorMap::TEditorType TEditorType; + TObjPtr newEditor = SStateEditorMap::CreateEditor(*this, m_Accessors); + TStateType *theState = &static_cast(newEditor.mPtr)->m_Data; + eastl::pair retval = eastl::make_pair(theState, newEditor); + InsertEditor(retval.first, retval.second.mPtr); + return retval; + } + + TObjPtr SEditorImpl::DoCreate(const char8_t *inTypeName, const char8_t *inId) + { + if (AreEqual(inTypeName, SSCXMLEditor::GetTypeStr())) { + QT3DS_ASSERT(m_StateContext->GetRoot() == NULL); + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, inId == NULL ? "scxml" : inId); + m_StateContext->SetRoot(*theNewEditor.first); + return theNewEditor.second; + } else if (AreEqual(inTypeName, SStateEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, inId == NULL ? "state" : inId); + return theNewEditor.second; + } else if (AreEqual(inTypeName, SParallelEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, inId == NULL ? "parallel" : inId); + return theNewEditor.second; + } else if (AreEqual(inTypeName, SFinalEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, inId == NULL ? "final" : inId); + return theNewEditor.second; + } else if (AreEqual(inTypeName, SHistoryEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, inId == NULL ? "history" : inId); + return theNewEditor.second; + } else if (AreEqual(inTypeName, STransitionEditor::GetTypeStr())) { + eastl::pair theNewEditor = + CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, inId == NULL ? "transition" : inId); + return theNewEditor.second; + } else if (AreEqual(inTypeName, SDataModelEditor::GetTypeStr())) { + eastl::pair theNewEditor = + CreateEditorAndObject(); + return theNewEditor.second; + } else if (AreEqual(inTypeName, SDataEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + return theNewEditor.second; + } + + QT3DS_ASSERT(false); + return TObjPtr(); + } + + TObjPtr SEditorImpl::Create(const char8_t *inTypeName, const char8_t *inId) + { + TObjPtr retval = DoCreate(inTypeName, inId); + m_TransactionManager->OnObjectCreated(retval); + return retval; + } + + TObjPtr SEditorImpl::GetOrCreate(SSCXML &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(SState &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(STransition &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(SParallel &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(SFinal &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(SHistory &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(SDataModel &inData) { return ToEditor(inData); } + TObjPtr SEditorImpl::GetOrCreate(SData &inData) { return ToEditor(inData); } + + TObjPtr SEditorImpl::GetObjectById(const char8_t *inId) + { + if (isTrivial(inId)) + return TObjPtr(); + SStateNode *theNode = m_StateContext->FindStateNode(RegisterStr(inId)); + if (theNode) + return ToEditor(*theNode); + return TObjPtr(); + } + + TObjPtr SEditorImpl::GetEditor(void *inGraphData) + { + TStateEditorMap::iterator iter = m_Editors.find(inGraphData); + if (iter != m_Editors.end()) + return iter->second; + return TObjPtr(); + } + + TSignalConnectionPtr SEditorImpl::AddChangeListener(IEditorChangeListener &inListener) + { + return m_TransactionManager->AddChangeListener(inListener); + } + + TTransactionPtr SEditorImpl::BeginTransaction(const TEditorStr &inName) + { + return m_TransactionManager->BeginTransaction(inName); + } + + TTransactionPtr SEditorImpl::GetOpenTransaction() + { + return m_TransactionManager->GetOpenTransaction(); + } + + void SEditorImpl::RollbackTransaction() { m_TransactionManager->RollbackTransaction(); } + + void SEditorImpl::EndTransaction() { m_TransactionManager->EndTransaction(); } + + TEditorStr SEditorImpl::Copy(TObjList inObjects, const QT3DSVec2 &inMousePos) + { + eastl::vector theNodeList; + for (size_t idx = 0, end = inObjects.size(); idx < end; ++idx) { + SStateNode *theNode = StateNodeFromEditor(inObjects[idx]); + if (theNode && theNode->m_Type != StateNodeTypes::Transition + && theNode->m_Type != StateNodeTypes::SCXML) { + theNodeList.push_back(theNode); + } + } + eastl::vector theNamespaces; + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable)); + NVScopedRefCounted theWriter( + IDOMWriter::CreateDOMWriter(m_EditorFoundation->getAllocator(), "scxml_fragment", + m_StringTable) + .first); + + eastl::vector rootNodes = CXMLIO::SaveSCXMLFragment( + *m_StateContext, *m_EditorFoundation->m_Foundation, *m_StringTable, *theWriter, + toDataRef(theNodeList.data(), theNodeList.size()), *this, inMousePos, + theNamespaces); + + if (m_CopyPasteListener) + m_CopyPasteListener->OnCopy(this, rootNodes, *theWriter, theNamespaces); + + SEditorImplStrIOStream theStream; + CDOMSerializer::WriteXMLHeader(theStream); + CDOMSerializer::Write(m_EditorFoundation->getAllocator(), *theWriter->GetTopElement(), + theStream, *m_StringTable, + toDataRef(theNamespaces.data(), theNamespaces.size()), false); + return theStream.m_Str; + } + + bool SEditorImpl::CanPaste(TObjPtr inTarget) + { + SStateNode *theNode = StateNodeFromEditor(inTarget); + if (theNode) { + return theNode->m_Type != StateNodeTypes::Transition + && theNode->m_Type != StateNodeTypes::History + && theNode->m_Type != StateNodeTypes::Final; + } + + return false; + } + + void SEditorImpl::AddNewPasteObjectToTransaction(SStateNode &inNode) + { + TObjPtr editorPtr = ToEditor(inNode); + if (editorPtr) { + m_TransactionManager->m_Transaction->m_Changes.push_back(new SChange(*editorPtr)); + m_TransactionManager->OnObjectCreated(editorPtr); + Option children = editorPtr->GetPropertyValue("children"); + if (children.hasValue()) { + TObjList childList = children->getData(); + for (size_t idx = 0, end = childList.size(); idx < end; ++idx) { + SStateNode *childNode = StateNodeFromEditor(childList[idx]); + if (childNode) + AddNewPasteObjectToTransaction(*childNode); + } + } + } + } + + void RecurseAndCheckForValidHistoryAfterPaste(TObjPtr inNode, SEditorImpl &inEditor) + { + if (AreEqual(inNode->TypeName(), "history")) { + inEditor.CheckAndSetValidHistoryDefault(inNode); + } else { + Option childrenOpt = inNode->GetPropertyValue("children"); + if (childrenOpt.hasValue() == false) { + return; + } + TObjList children = childrenOpt->getData(); + for (size_t childIdx = 0, childEnd = children.size(); childIdx < childEnd; + ++childIdx) { + RecurseAndCheckForValidHistoryAfterPaste(children[childIdx], inEditor); + } + } + } + + void SEditorImpl::Paste(const TEditorStr &inCopiedObjects, TObjPtr inTarget, + const QT3DSVec2 &inMousePos) + { + Option childrenOpt = inTarget->GetPropertyValue("children"); + if (childrenOpt.hasValue() == false) { + QT3DS_ASSERT(false); + return; + } + + TObjList children = childrenOpt->getData(); + + SEditorImplStrInStream inStream(inCopiedObjects); + NVScopedRefCounted theFactory = + IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable); + eastl::pair readResult = + CDOMSerializer::Read(*theFactory, inStream); + SDOMElement *elem = readResult.second; + if (elem == NULL) { + QT3DS_ASSERT(false); + return; + } + NVScopedRefCounted theReader = IDOMReader::CreateDOMReader( + m_EditorFoundation->getAllocator(), *elem, m_StringTable, *theFactory); + eastl::pair, CXMLIO::TIdRemapMap> theRootsPair; + { + IDOMReader::Scope __readerScope(*theReader); + theRootsPair = + CXMLIO::LoadSCXMLFragment(m_AutoAllocator, *m_EditorFoundation->m_Foundation, + *theReader, *m_StringTable, *m_StateContext, *this); + } + eastl::vector &theObjects(theRootsPair.first); + if (m_CopyPasteListener) + m_CopyPasteListener->OnPaste(this, *theReader, theRootsPair.second); + // Merge any namespaces into the context's namespace list. + if (m_StateContext->GetDOMFactory()) { + for (SNamespacePairNode *fragNode = readResult.first; fragNode; + fragNode = fragNode->m_NextNode) { + bool found = false; + for (SNamespacePairNode *ctxNode = m_StateContext->GetFirstNSNode(); + ctxNode && !found; ctxNode = ctxNode->m_NextNode) { + if (ctxNode->m_Namespace == fragNode->m_Namespace) + found = true; + } + if (!found) { + SNamespacePairNode *newNode = + m_StateContext->GetDOMFactory()->NextNSPairNode( + fragNode->m_Namespace, fragNode->m_Abbreviation); + newNode->m_NextNode = m_StateContext->GetFirstNSNode(); + m_StateContext->SetFirstNSNode(*newNode); + } + } + } + QT3DSVec2 globalPos(0, 0); + if (inTarget) { + for (TObjPtr posObj = inTarget; posObj; posObj = posObj->Parent()) { + Option theData = posObj->GetPropertyValue("position"); + if (theData.hasValue()) + globalPos += theData->getData(); + } + } + QT3DSVec2 theMousePos = inMousePos - globalPos; + for (size_t idx = 0, end = theObjects.size(); idx < end; ++idx) { + SStateNode *currentObject = theObjects[idx]; + QT3DSVec2 objPos(0, 0); + if (currentObject->m_StateNodeFlags.HasPosition()) + objPos = currentObject->m_Position; + currentObject->SetPosition(objPos + theMousePos); + if (m_TransactionManager->m_Transaction) + AddNewPasteObjectToTransaction(*currentObject); + TObjPtr editorPtr = ToEditor(*currentObject); + if (editorPtr.mPtr) + children.push_back(editorPtr); + } + // This sets up the valid parents. Without that, checking if a history node is valid + // is meaningless. + inTarget->SetPropertyValue("children", children); + for (size_t idx = 0, end = children.size(); idx < end; ++idx) { + RecurseAndCheckForValidHistoryAfterPaste(children[idx], *this); + } + } + + bool SEditorImpl::IsDerivedFrom(SStateNode &child, SStateNode &parent) + { + if (&child == &parent) + return true; + if (child.m_Parent) + return IsDerivedFrom(*child.m_Parent, parent); + return false; + } + + // This method should always return a value because the scxml root item + // is the parent of everyone else. + SStateNode &SEditorImpl::GetLeastCommonAncestor(SStateNode &lhs, SStateNode &rhs) + { + // If lhs is derived from rhs, return rhs + if (IsDerivedFrom(lhs, rhs)) + return rhs; + // vice versa + else if (IsDerivedFrom(rhs, lhs)) + return lhs; + + // Else wander up the tree till we find a common ancestor. + QT3DS_ASSERT(lhs.m_Parent != NULL); + if (lhs.m_Parent != NULL) + return GetLeastCommonAncestor(*lhs.m_Parent, rhs); + + return lhs; + } + + TObjPtr SEditorImpl::GetLeastCommonAncestor(NVConstDataRef inObjects) + { + SStateNode *lastAncestor = NULL; + if (inObjects.size() == 0) + return TObjPtr(); + + for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { + if (lastAncestor == NULL) { + lastAncestor = StateNodeFromEditor(inObjects[idx]); + } else { + SStateNode *nextNode = StateNodeFromEditor(inObjects[idx]); + if (nextNode != NULL) { + lastAncestor = &GetLeastCommonAncestor(*lastAncestor, *nextNode); + } + } + } + + if (lastAncestor) + return ToEditor(*lastAncestor); + else + return TObjPtr(); + } + + void GetCancelableSendIds(TExecutableContentList &inList, TObjList &outList, + SEditorImpl &inEditor); + + void RecursiveGetCancelableSendIds(SExecutableContent &inNode, TObjList &outList, + SEditorImpl &inEditor) + { + if (inNode.m_Type == ExecutableContentTypes::Send) { + SSend &theSend = static_cast(inNode); + if (IExecutionContext::ParseTimeStrToMilliseconds(theSend.m_Delay) + || !isTrivial(theSend.m_DelayExpr)) { + outList.push_back(inEditor.ExecutableContentToEditor(theSend)); + } + } + GetCancelableSendIds(inNode.m_Children, outList, inEditor); + } + + void GetCancelableSendIds(TExecutableContentList &inList, TObjList &outList, + SEditorImpl &inEditor) + { + for (TExecutableContentList::iterator iter = inList.begin(), end = inList.end(); + iter != end; ++iter) + RecursiveGetCancelableSendIds(*iter, outList, inEditor); + } + + void RecursiveGetCancelableSendIds(SStateNode &inNode, TObjList &outList, + SEditorImpl &inEditor) + { + if (inNode.m_Type == StateNodeTypes::Transition) { + STransition &transition = static_cast(inNode); + GetCancelableSendIds(transition.m_ExecutableContent, outList, inEditor); + } else { + TOnEntryList *entryList = inNode.GetOnEntryList(); + TOnExitList *exitList = inNode.GetOnExitList(); + if (entryList) { + for (TOnEntryList::iterator iter = entryList->begin(), end = entryList->end(); + iter != end; ++iter) + GetCancelableSendIds(iter->m_ExecutableContent, outList, inEditor); + } + if (exitList) { + for (TOnExitList::iterator iter = exitList->begin(), end = exitList->end(); + iter != end; ++iter) + GetCancelableSendIds(iter->m_ExecutableContent, outList, inEditor); + } + } + TStateNodeList *childList = inNode.GetChildren(); + if (childList) { + for (TStateNodeList::iterator childIter = childList->begin(), + childEnd = childList->end(); + childIter != childEnd; ++childIter) + RecursiveGetCancelableSendIds(*childIter, outList, inEditor); + } + } + + // TODO - think about a fast and easy way to cache things (and keep the cache correct). + TObjList SEditorImpl::GetCancelableSendIds() + { + TObjList retval; + if (m_StateContext->GetRoot()) + RecursiveGetCancelableSendIds(*m_StateContext->GetRoot(), retval, *this); + return retval; + } + + static const char8_t *whitespace = "\n\r\t "; + + void StripIfLastChar(TEditorStr &str, char data) + { + if (str.size() && str.back() == data) + str.resize(str.size() - 1); + } + + void AddUnique(TEditorStrList &list, const TEditorStr &str) + { + if (eastl::find(list.begin(), list.end(), str) == list.end()) + list.push_back(str); + } + + void RecursiveScanExecutableContentForEvents(TExecutableContentList &contentList, + TEditorStrList &ioStrList) + { + for (TExecutableContentList::iterator iter = contentList.begin(), + end = contentList.end(); + iter != end; ++iter) { + if (iter->m_Type == ExecutableContentTypes::Send) { + SSend &theSend = static_cast(*iter); + if (!isTrivial(theSend.m_Event)) { + AddUnique(ioStrList, theSend.m_Event.c_str()); + } + } else if (iter->m_Type == ExecutableContentTypes::Raise) { + SRaise &theRaise = static_cast(*iter); + if (!isTrivial(theRaise.m_Event)) { + AddUnique(ioStrList, theRaise.m_Event.c_str()); + } + } + RecursiveScanExecutableContentForEvents(iter->m_Children, ioStrList); + } + } + + template + void ScanItemListForEvents(TListType *itemList, TEditorStrList &ioEvents) + { + if (itemList) { + typedef typename TListType::iterator iterator; + for (iterator iter = itemList->begin(), end = itemList->end(); iter != end; + ++iter) { + RecursiveScanExecutableContentForEvents(iter->m_ExecutableContent, ioEvents); + } + } + } + + void RecursiveGetStateMachineEvents(SStateNode &inNode, TEditorStrList &ioList) + { + if (inNode.m_Type == StateNodeTypes::Transition) { + STransition &theTransition = static_cast(inNode); + TEditorStr transStr(theTransition.m_Event); + for (size_t pos = transStr.find_first_not_of(whitespace); pos != TEditorStr::npos; + pos = transStr.find_first_not_of(whitespace, pos)) { + size_t end = transStr.find_first_of(whitespace, pos); + if (end == TEditorStr::npos) + end = transStr.size(); + TEditorStr subStr = transStr.substr(pos, end - pos); + pos = end; + StripIfLastChar(subStr, '*'); + StripIfLastChar(subStr, '.'); + AddUnique(ioList, subStr); + } + RecursiveScanExecutableContentForEvents(theTransition.m_ExecutableContent, ioList); + } else { + ScanItemListForEvents(inNode.GetOnEntryList(), ioList); + ScanItemListForEvents(inNode.GetOnExitList(), ioList); + } + TStateNodeList *children = inNode.GetChildren(); + if (children) { + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) + RecursiveGetStateMachineEvents(*iter, ioList); + } + } + + TEditorStrList SEditorImpl::GetStateMachineEvents() + { + TEditorStrList retval; + if (m_StateContext->GetRoot()) + RecursiveGetStateMachineEvents(*m_StateContext->GetRoot(), retval); + eastl::sort(retval.begin(), retval.end()); + return retval; + } + + eastl::pair + SEditorImpl::CreateExecutableContent(const char8_t *inTypeName) + { + SExecutableContent *newExecutable = NULL; + TObjPtr newObj; + if (AreEqual(inTypeName, SSendEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, "send"); + newExecutable = theNewEditor.first; + newObj = theNewEditor.second; + } else if (AreEqual(inTypeName, SScriptEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + newExecutable = theNewEditor.first; + newObj = theNewEditor.second; + } else if (AreEqual(inTypeName, SCancelEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + newExecutable = theNewEditor.first; + newObj = theNewEditor.second; + } else { + QT3DS_ASSERT(false); + } + return eastl::make_pair(newExecutable, newObj); + } + + struct SExecListAddChange : public IChange + { + TExecutableContentList &parentList; + SExecutableContent *prevSibling; + SExecutableContent &item; + TObjPtr editorObj; + QT3DSI32 mRefCount; + bool m_AddOnDo; + SExecListAddChange(TExecutableContentList &plist, SExecutableContent *prev, + SExecutableContent &_item, TObjPtr objPtr, bool addOnDo) + : parentList(plist) + , prevSibling(prev) + , item(_item) + , editorObj(objPtr) + , mRefCount(0) + , m_AddOnDo(addOnDo) + { + } + + void Add() + { + if (prevSibling) + parentList.insert_after(*prevSibling, item); + else + parentList.push_front(item); + } + void Remove() { parentList.remove(item); } + + virtual void Do() + { + if (m_AddOnDo) + Add(); + else + Remove(); + } + + virtual void Undo() + { + if (m_AddOnDo) + Remove(); + else + Add(); + } + + virtual TObjPtr GetEditor() { return editorObj; } + + virtual void addRef() { ++mRefCount; } + + virtual void release() + { + --mRefCount; + if (mRefCount <= 0) + delete this; + } + }; + + void SEditorImpl::ReplaceExecutableContent(SExecutableContent &oldContent, + SExecutableContent &newContent) + { + SStateNode *stateNodeParent = oldContent.m_StateNodeParent; + SExecutableContent *execContentParent = oldContent.m_Parent; + SExecutableContentParentInfo parentInfo(oldContent, *this); + SExecutableContent *prevSibling = oldContent.m_PreviousSibling; + + // Can't use remove object from graph here because it is too aggressive. + NVScopedRefCounted oldChange = new SExecListAddChange( + *parentInfo.parentList, prevSibling, oldContent, parentInfo.editorObj, false); + oldChange->Do(); + newContent.m_StateNodeParent = stateNodeParent; + newContent.m_Parent = execContentParent; + NVScopedRefCounted newChange = new SExecListAddChange( + *parentInfo.parentList, prevSibling, newContent, parentInfo.editorObj, true); + newChange->Do(); + if (GetOpenTransactionImpl()) { + GetOpenTransactionImpl()->m_Changes.push_back(oldChange.mPtr); + GetOpenTransactionImpl()->m_Changes.push_back(newChange.mPtr); + } + } + + TObjPtr SEditorImpl::ChangeExecutableContentType(TObjPtr inContent, const char8_t *newType) + { + SExecutableContent *theContent = ExecutableContentFromEditor(inContent); + if (!theContent) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + SExecutableContentParentInfo parentInfo(*theContent, *this); + // find the index of the item in the parent list. + if (parentInfo.parentList == NULL) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + + eastl::pair theNewContent = + CreateExecutableContent(newType); + if (!theNewContent.first) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + ReplaceExecutableContent(*theContent, *theNewContent.first); + return theNewContent.second; + } + + TEditorStr SEditorImpl::ToXML(TObjPtr inContent) + { + SExecutableContent *theContent = ExecutableContentFromEditor(inContent); + if (!theContent) { + QT3DS_ASSERT(false); + return TEditorStr(); + } + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable)); + NVScopedRefCounted theWriter( + IDOMWriter::CreateDOMWriter(m_EditorFoundation->getAllocator(), "innerXML", + m_StringTable, 0) + .first); + CXMLIO::ToEditableXml(*m_StateContext, m_EditorFoundation->getFoundation(), + *m_StringTable, *theWriter, *theContent, *this); + SDOMElement *theTopElem = theWriter->GetTopElement(); + SDOMElement *xmlElem = &theTopElem->m_Children.front(); + SEditorImplStrIOStream theStream; + if (xmlElem) { + + eastl::vector theNamespaces; + for (SNamespacePairNode *theNode = m_StateContext->GetFirstNSNode(); theNode; + theNode = theNode->m_NextNode) + theNamespaces.push_back(*theNode); + if (theNamespaces.empty()) { + theNamespaces.push_back(SNamespacePair( + m_StringTable->RegisterStr("http://www.w3.org/2005/07/scxml"))); + theNamespaces.push_back( + SNamespacePair(m_StringTable->RegisterStr("http://qt.io/qt3dstudio/uicstate"), + m_StringTable->RegisterStr("Qt3DS"))); + } + CDOMSerializer::Write( + m_EditorFoundation->getAllocator(), *xmlElem, theStream, *m_StringTable, + toDataRef(theNamespaces.data(), theNamespaces.size()), false, 0, false); + } + return theStream.m_Str; + } + + struct SStrXMLErrorHandler : public CXmlErrorHandler + { + TEditorStr m_Error; + virtual void OnXmlError(TXMLCharPtr errorName, int line, int /*column*/) + { + char buf[256]; + sprintf(buf, "Error on line %d: ", line); + m_Error.assign(buf); + m_Error.append(nonNull(errorName)); + } + }; + + eastl::pair SEditorImpl::FromXML(TObjPtr inContent, + const TEditorStr &ioEditedXML) + { + TEditorStr wrappedXML(" theNamespaces; + for (SNamespacePairNode *theNode = m_StateContext->GetFirstNSNode(); theNode; + theNode = theNode->m_NextNode) + theNamespaces.push_back(*theNode); + if (theNamespaces.empty()) { + theNamespaces.push_back( + SNamespacePair(m_StringTable->RegisterStr("http://www.w3.org/2005/07/scxml"))); + theNamespaces.push_back( + SNamespacePair(m_StringTable->RegisterStr("http://qt.io/qt3dstudio/uicstate"), + m_StringTable->RegisterStr("Qt3DS"))); + } + for (size_t idx = 0, end = theNamespaces.size(); idx < end; ++idx) { + SNamespacePair &theNode(theNamespaces[idx]); + wrappedXML.append(" xmlns"); + if (theNode.m_Abbreviation.IsValid()) { + wrappedXML.append(":"); + wrappedXML.append(theNode.m_Abbreviation.c_str()); + } + wrappedXML.append("=\""); + wrappedXML.append(theNode.m_Namespace.c_str()); + wrappedXML.append("\""); + } + wrappedXML.append(">"); + wrappedXML.append(ioEditedXML); + wrappedXML.append(""); + SEditorImplStrInStream theStream(wrappedXML); + + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_EditorFoundation->getAllocator(), m_StringTable)); + SStrXMLErrorHandler errorHandler; + SDOMElement *theElem = + CDOMSerializer::Read(*theFactory, theStream, &errorHandler).second; + TObjPtr retval; + if (theElem) { + NVScopedRefCounted theReader(IDOMReader::CreateDOMReader( + m_EditorFoundation->getAllocator(), theElem->m_Children.front(), m_StringTable, + theFactory)); + SExecutableContent *oldContent = ExecutableContentFromEditor(inContent); + SExecutableContent *theContent = + CXMLIO::FromEditableXML(*theReader, m_EditorFoundation->getFoundation(), + *m_StateContext, *m_StringTable, m_AutoAllocator, *this, + oldContent->m_StateNodeParent, oldContent->m_Parent); + if (theContent) { + ReplaceExecutableContent(*oldContent, *theContent); + retval = ExecutableContentToEditor(*theContent); + } else { + errorHandler.m_Error.assign("The \""); + errorHandler.m_Error.append(theReader->GetElementName().c_str()); + errorHandler.m_Error.append("\" action is not recognized. It must be one of:"); + eastl::vector contentNames = + CXMLIO::GetSupportedExecutableContentNames(); + for (size_t idx = 0, end = contentNames.size(); idx < end; ++idx) { + if (idx != 0) + errorHandler.m_Error.append(","); + + errorHandler.m_Error.append(" \""); + errorHandler.m_Error.append(contentNames[idx].c_str()); + errorHandler.m_Error.append("\""); + } + errorHandler.m_Error.append("."); + } + } + + return eastl::make_pair(errorHandler.m_Error, retval); + } + + void SEditorImpl::ReleaseEditor(void *inData) + { + TStateEditorMap::iterator iter = m_Editors.find(inData); + if (iter != m_Editors.end()) + m_Editors.erase(iter); + } + + bool SEditorImpl::Save(const char8_t *inFileName) + { + CFileSeekableIOStream theFile(inFileName, FileWriteFlags()); + if (theFile.IsOpen() == false) { + QT3DS_ASSERT(false); + return false; + } + + Save(theFile); + return true; + } + + void SEditorImpl::Save(IOutStream &inStream) { m_StateContext->Save(inStream, this); } + + bool SEditorImpl::Load(IInStream &inStream, const char8_t *inFilename) + { + bool theRetval = false; + m_StateContext = IStateContext::Load(m_AutoAllocator, *m_EditorFoundation->m_Foundation, + inStream, inFilename, m_StringTable.mPtr, this); + if (m_StateContext.mPtr == 0) + m_StateContext = IStateContext::Create(*m_EditorFoundation->m_Foundation); + else + theRetval = true; + return theRetval; + } + + STransaction *SEditorImpl::GetOpenTransactionImpl() + { + return m_TransactionManager->m_Transaction.mPtr; + } + + void SEditorImpl::SetIdProperty(SStateNode &inNode, const SValue &inData, + CRegisteredString & /*inTarget*/) + { + IStateContext &theContext = *m_StateContext; + theContext.EraseId(inNode.m_Id); + TEditorStr potentialId = inData.getData(); + if (potentialId.size() == 0) { + switch (inNode.m_Type) { + case StateNodeTypes::State: + potentialId = "state"; + break; + case StateNodeTypes::Parallel: + potentialId = "parallel"; + break; + case StateNodeTypes::Transition: + potentialId = "transition"; + break; + case StateNodeTypes::Final: + potentialId = "final"; + break; + case StateNodeTypes::History: + potentialId = "history"; + break; + case StateNodeTypes::SCXML: + potentialId = "scxml"; + break; + default: + QT3DS_ASSERT(false); + potentialId = "id"; + break; + } + } + CRegisteredString oldId = inNode.m_Id; + inNode.m_Id = CRegisteredString(); + GenerateUniqueId(inNode, potentialId.c_str()); + // This is a bad hack to get around: + // 1. user changes id calling this function + if (m_CopyPasteListener) { + m_CopyPasteListener->OnIDChange(this, inNode, oldId); + } + } + + void SEditorImpl::SetIdProperty(SSend &inNode, const SValue &inData, + CRegisteredString & /*inTarget*/) + { + IStateContext &theContext = *m_StateContext; + theContext.EraseId(inNode.m_Id); + TEditorStr potentialId = inData.getData(); + if (potentialId.size() == 0) + potentialId = "send"; + + inNode.m_Id = CRegisteredString(); + GenerateUniqueId(inNode, potentialId.c_str()); + } + + void SEditorImpl::Set(const Option &inData, NVConstDataRef &inTarget) + { + if (inTarget.mData != NULL) { + m_AutoAllocator.deallocate((void *)inTarget.mData); + inTarget.mData = NULL; + inTarget.mSize = 0; + } + if (inData.hasValue()) { + TObjList inList(inData->getData()); + eastl::vector validObjects; + for (size_t idx = 0, end = inList.size(); idx < end; ++idx) { + TObjPtr theObj = inList[idx]; + SStateNode *theNode = StateNodeFromEditor(theObj); + if (theNode) { + validObjects.push_back(theNode); + } else { + QT3DS_ASSERT(false); + } + } + + if (validObjects.empty() == false) { + NVConstDataRef &outList(inTarget); + size_t byteCount = validObjects.size() * sizeof(SStateNode *); + outList.mData = (SStateNode * const *)m_AutoAllocator.allocate( + byteCount, "graph ref list data", __FILE__, __LINE__); + memCopy((void *)outList.mData, validObjects.data(), byteCount); + outList.mSize = validObjects.size(); + } + } + } + + SValue SEditorImpl::Get(NVConstDataRef &inTarget) + { + TObjList retval; + NVConstDataRef inRefList(inTarget); + for (QT3DSU32 idx = 0, end = inRefList.size(); idx < end; ++idx) { + TObjPtr obj = ToEditor(inRefList[idx]); + if (obj) + retval.push_back(obj); + else { + // This shouldn't ever happen, but it might when loading + // an invalid file. + QT3DS_ASSERT(false); + } + } + return retval; + } + + void SEditorImpl::Set(const Option &inData, STransition *&inTarget) + { + inTarget = NULL; + if (inData.hasValue()) { + TObjPtr theData(inData->getData()); + inTarget = FromEditor(theData); + } + } + + Option SEditorImpl::Get(STransition *&inTarget) + { + return SValue(ToEditor(inTarget)); + } + + void SEditorImpl::SetInitial(const TObjList &inList, STransition *&outTransitionPtr) + { + if (outTransitionPtr) { + Set(SValue(inList), outTransitionPtr->m_Target); + if (outTransitionPtr->m_Target.mSize == 0 + && outTransitionPtr->m_ExecutableContent.empty()) + outTransitionPtr = NULL; + } else { + NVConstDataRef theTemp; + Set(SValue(inList), theTemp); + if (theTemp.mSize) { + outTransitionPtr = QT3DS_NEW(m_AutoAllocator, STransition)(); + outTransitionPtr->m_Target = theTemp; + } + } + } + + SValue SEditorImpl::GetInitial(STransition *inInitialTrans) + { + if (inInitialTrans) + return Get(inInitialTrans->m_Target); + + return TObjList(); + } + static inline STransition **GetInitialTransitionPtr(SStateNode &inParent) + { + StateNodeTypes::Enum typeEnum(inParent.m_Type); + STransition **theParentTransPtr = NULL; + if (typeEnum == StateNodeTypes::SCXML) + theParentTransPtr = &static_cast(inParent).m_Initial; + else if (typeEnum == StateNodeTypes::State) + theParentTransPtr = &static_cast(inParent).m_Initial; + return theParentTransPtr; + } + + static inline bool IsFirstChild(SStateNode &inChild, SStateNode &inParent) + { + TStateNodeList *childList = inParent.GetChildren(); + SStateNode *firstViableChild = NULL; + if (childList) { + for (TStateNodeList::iterator iter = childList->begin(), end = childList->end(); + iter != end && firstViableChild == NULL; ++iter) { + StateNodeTypes::Enum typeEnum = iter->m_Type; + if (typeEnum == StateNodeTypes::State || typeEnum == StateNodeTypes::Parallel + || typeEnum == StateNodeTypes::Final) { + firstViableChild = &(*iter); + } + } + } + return firstViableChild == &inChild; + } + + struct SInitialTargetChange : public IChange + { + TObjPtr m_EditorObj; + SStateNode &m_Parent; + STransition *m_InitialTransition; + STransition *m_FinalTransition; + QT3DSI32 m_RefCount; + // Implicitly setting c to be the initial target. + SInitialTargetChange(TObjPtr editorObj, SStateNode &p, SStateNode &c, + SEditorImpl &editor) + : m_EditorObj(editorObj) + , m_Parent(p) + , m_InitialTransition(NULL) + , m_FinalTransition(NULL) + , m_RefCount(0) + { + STransition **theTransitionPtr = GetInitialTransitionPtr(m_Parent); + QT3DS_ASSERT(theTransitionPtr); + if (theTransitionPtr) { + m_InitialTransition = *theTransitionPtr; + theTransitionPtr[0] = NULL; + bool firstChild = IsFirstChild(c, p); + if (!firstChild) { + TObjPtr editorObj = editor.Create("transition", ""); + TObjList targets; + targets.push_back(editor.ToEditor(c)); + editorObj->SetPropertyValue("target", targets); + SStateNode *stateNode = editor.StateNodeFromEditor(editorObj); + m_FinalTransition = static_cast(stateNode); + m_FinalTransition->m_Parent = &p; + *theTransitionPtr = m_FinalTransition; + } + } + } + virtual void addRef() { ++m_RefCount; } + virtual void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + virtual TObjPtr GetEditor() { return m_EditorObj; } + + template + void Apply(STransition *trans, TNodeType &node) + { + node.m_Initial = trans; + } + + virtual void Do() + { + if (m_Parent.m_Type == StateNodeTypes::SCXML) + Apply(m_FinalTransition, static_cast(m_Parent)); + else if (m_Parent.m_Type == StateNodeTypes::State) + Apply(m_FinalTransition, static_cast(m_Parent)); + } + + virtual void Undo() + { + if (m_Parent.m_Type == StateNodeTypes::SCXML) + Apply(m_InitialTransition, static_cast(m_Parent)); + else if (m_Parent.m_Type == StateNodeTypes::State) + Apply(m_InitialTransition, static_cast(m_Parent)); + } + }; + + void SEditorImpl::SetInitialTarget(const Option &inData, SStateNode &inNode) + { + if (inNode.m_Type == StateNodeTypes::Transition + /**|| inNode.m_Type == StateNodeTypes::History **/) { + QT3DS_ASSERT(false); + } + SStateNode *theParent = inNode.m_Parent; + if (theParent) { + STransition **theParentTransPtr = GetInitialTransitionPtr(*theParent); + + if (theParentTransPtr) { + bool newValue = false; + if (inData.hasValue()) + newValue = inData->getData(); + + NVScopedRefCounted theChange = + new SInitialTargetChange(ToEditor(*theParent), *theParent, inNode, *this); + theChange->Do(); + STransaction *theTransaction = GetOpenTransactionImpl(); + if (theTransaction) { + theTransaction->m_Changes.push_back(theChange.mPtr); + TStateNodeList *children = theParent->GetChildren(); + for (TStateNodeList::iterator iter = children->begin(), + end = children->end(); + iter != end; ++iter) { + theTransaction->m_Changes.push_back(new SChange(*ToEditor(*iter))); + } + } + } + } + } + + SValue SEditorImpl::IsInitialTarget(SStateNode &inNode) + { + if (inNode.m_Type == StateNodeTypes::Transition + /** || inNode.m_Type == StateNodeTypes::History **/) + return SValue(false); + + SStateNode *theParent(inNode.m_Parent); + if (theParent) { + if (!isTrivial(theParent->GetInitialExpression())) + return false; + + STransition *theTransition = theParent->GetInitialTransition(); + if (theTransition) { + for (QT3DSU32 idx = 0, end = theTransition->m_Target.size(); idx < end; ++idx) + if (&inNode == theTransition->m_Target[idx]) + return SValue(true); + } else { + if (GetInitialTransitionPtr(*theParent)) + return SValue(IsFirstChild(inNode, *theParent)); + } + } + return SValue(false); + } + + TEditorStr SEditorImpl::GetDefaultInitialValue(SStateNode &inNode) + { + TStateNodeList *children = inNode.GetChildren(); + if (children == NULL) + return TEditorStr(); + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) { + if (iter->m_Type != StateNodeTypes::History + && iter->m_Type != StateNodeTypes::Transition) + return TEditorStr(iter->m_Id.c_str()); + } + + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) { + if (iter->m_Type != StateNodeTypes::Transition) + return TEditorStr(iter->m_Id.c_str()); + } + + return TEditorStr(); + } + + void SEditorImpl::GetLegalInitialValues(SStateNode &inNode, + eastl::vector &outValues) + { + TStateNodeList *children = inNode.GetChildren(); + if (children == NULL) + return; + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) { + if (/** iter->m_Type != StateNodeTypes::History && **/ iter->m_Type + != StateNodeTypes::Transition) + outValues.push_back(iter->m_Id); + } + } + + struct SInitialComboChange : public IChange + { + SStateNode &m_Node; + TObjPtr m_EditorObj; + const TEditorStr m_PreEditorComboValue; + const TEditorStr m_PostEditorComboValue; + const char8_t *m_PreInitialExpression; + const char8_t *m_PostInitialExpression; + STransition *m_PreComboTransition; + STransition *m_PostComboTransition; + QT3DSI32 m_RefCount; + SInitialComboChange(SStateNode &node, TObjPtr editObj, const char8_t *preExpr, + const char8_t *postExpr, STransition *preCombo, + STransition *postCombo, const TEditorStr &preEditorComboValue, + const TEditorStr &postEditorComboValue) + : m_Node(node) + , m_EditorObj(editObj) + , m_RefCount(0) + , m_PreInitialExpression(preExpr) + , m_PostInitialExpression(postExpr) + , m_PreComboTransition(preCombo) + , m_PostComboTransition(postCombo) + , m_PreEditorComboValue(preEditorComboValue) + , m_PostEditorComboValue(postEditorComboValue) + { + } + + virtual void addRef() { ++m_RefCount; } + virtual void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + virtual TObjPtr GetEditor() { return m_EditorObj; } + + template + void Apply(const char8_t *expr, STransition *trans, const TEditorStr &comboValue, + TNodeType &node, TEditorType &editor) + { + node.m_Initial = trans; + node.m_InitialExpr = expr; + editor.ApplyInitial(comboValue); + // editor.m_InitialComboValue = comboValue; + } + + virtual void Do() + { + if (m_Node.m_Type == StateNodeTypes::SCXML) + Apply(m_PostInitialExpression, m_PostComboTransition, m_PostEditorComboValue, + static_cast(m_Node), static_cast(*m_EditorObj)); + else if (m_Node.m_Type == StateNodeTypes::State) + Apply(m_PostInitialExpression, m_PostComboTransition, m_PostEditorComboValue, + static_cast(m_Node), static_cast(*m_EditorObj)); + } + + virtual void Undo() + { + if (m_Node.m_Type == StateNodeTypes::SCXML) + Apply(m_PreInitialExpression, m_PreComboTransition, m_PreEditorComboValue, + static_cast(m_Node), static_cast(*m_EditorObj)); + else if (m_Node.m_Type == StateNodeTypes::State) + Apply(m_PreInitialExpression, m_PreComboTransition, m_PreEditorComboValue, + static_cast(m_Node), static_cast(*m_EditorObj)); + } + }; + + void SEditorImpl::SetInitialAttribute(const Option &inData, SStateNode &inNode) + { + TObjPtr theEditor = ToEditor(inNode); + STransition **targetPtr = NULL; + const char8_t **exprPtr = NULL; + TEditorStr comboValue; + if (inNode.m_Type == StateNodeTypes::State) { + targetPtr = &static_cast(inNode).m_Initial; + exprPtr = &static_cast(inNode).m_InitialExpr; + comboValue = static_cast(*theEditor).m_InitialComboValue; + } else if (inNode.m_Type == StateNodeTypes::SCXML) { + targetPtr = &static_cast(inNode).m_Initial; + exprPtr = &static_cast(inNode).m_InitialExpr; + comboValue = static_cast(*theEditor).m_InitialComboValue; + } + + if (targetPtr == NULL) { + QT3DS_ASSERT(false); + return; + } + + STransition *initialTrans = *targetPtr; + const char8_t *initialExpr = *exprPtr; + TEditorStr initialComboValue = comboValue; + + if (inData.isEmpty()) { + *targetPtr = NULL; + comboValue = "(script expression)"; + } else { + TEditorStr stateId = inData->getData(); + SStateNode *theNode = + this->m_StateContext->FindStateNode(RegisterStr(stateId.c_str())); + if (theNode) { + *targetPtr = QT3DS_NEW(this->m_AutoAllocator, STransition)(); + SStateNode **newNode = + reinterpret_cast(this->m_AutoAllocator.allocate( + sizeof(SStateNode *), "TargetList", __FILE__, __LINE__)); + targetPtr[0]->m_Target = toDataRef(newNode, 1); + *const_cast(targetPtr[0]->m_Target.begin()) = theNode; + targetPtr[0]->m_Target.mSize = 1; + comboValue = stateId; + } else { + *targetPtr = NULL; + comboValue = ""; + } + *exprPtr = ""; + } + STransition *postTrans = *targetPtr; + const char8_t *postExpr = *exprPtr; + TEditorStr postComboValue = comboValue; + STransaction *theTransaction = GetOpenTransactionImpl(); + if (theTransaction) { + SInitialComboChange *theChange = new SInitialComboChange( + inNode, ToEditor(inNode), initialExpr, postExpr, initialTrans, postTrans, + initialComboValue, postComboValue); + theChange->Do(); + theTransaction->m_Changes.push_back(theChange); + TStateNodeList *children = inNode.GetChildren(); + if (children) { + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) { + theTransaction->m_Changes.push_back(new SChange(*ToEditor(*iter))); + } + } + } + } + + void SEditorImpl::Set(const Option &inData, SDataModel *&inTarget) + { + if (inData.hasValue()) { + TObjPtr thePtr = inData->getData(); + if (thePtr) + inTarget = FromEditor(thePtr); + else + inTarget = NULL; + } else + inTarget = NULL; + } + + SValue SEditorImpl::Get(SDataModel *inTarget) { return ToEditor(inTarget); } + + void SEditorImpl::Set(const Option &inData, TDataList &inTarget) + { + while (inTarget.empty() == false) + inTarget.remove(inTarget.front()); + if (inData.hasValue()) { + TObjList newData = inData->getData(); + for (TObjList::iterator iter = newData.begin(), end = newData.end(); iter != end; + ++iter) { + SData *entry = FromEditor(*iter); + if (entry) + inTarget.push_back(*entry); + } + } + } + + SValue SEditorImpl::Get(TDataList &inTarget) + { + TObjList retval; + for (TDataList::iterator iter = inTarget.begin(), end = inTarget.end(); iter != end; + ++iter) { + TObjPtr item = ToEditor(*iter); + if (item) + retval.push_back(item); + } + return retval; + } + + void SEditorImpl::Set(const Option &inData, NVConstDataRef &inTarget) + { + if (inTarget.size()) { + m_AutoAllocator.deallocate((void *)inTarget.mData); + inTarget.mData = NULL; + inTarget.mSize = 0; + } + if (inData.hasValue()) { + TVec2List newData(inData->getData()); + if (newData.size()) { + size_t newDataSize = newData.size() * sizeof(QT3DSVec2); + QT3DSVec2 *newTargetData = (QT3DSVec2 *)m_AutoAllocator.allocate( + newDataSize, "Transition::m_Path", __FILE__, __LINE__); + memCopy(newTargetData, newData.data(), newDataSize); + inTarget = toDataRef(newTargetData, newData.size()); + } + } + } + + SValue SEditorImpl::Get(const NVConstDataRef &inTarget) + { + TVec2List retval; + if (inTarget.mSize) + retval.insert(retval.end(), inTarget.begin(), inTarget.end()); + return retval; + } + + void SEditorImpl::Set(const Option &inData, SSend *&inTarget) + { + inTarget = NULL; + if (inData.hasValue() && inData->getType() == ValueTypes::ObjPtr) { + TObjPtr object = inData->getData(); + SSend *newPtr = FromEditor(object); + inTarget = newPtr; + } + } + + SValue SEditorImpl::Get(SSend *inTarget) + { + if (!inTarget) + return SValue(TObjPtr()); + return ToEditor(inTarget); + } + + TObjPtr SEditorImpl::CreateExecutableContent(SStateNode &inParent, + const char8_t *inTypeName) + { + SExecutableContent *newExecutable = NULL; + TObjPtr newObj; + if (AreEqual(inTypeName, SSendEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + GenerateUniqueId(*theNewEditor.first, "send"); + newExecutable = theNewEditor.first; + newObj = theNewEditor.second; + } else if (AreEqual(inTypeName, SScriptEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + newExecutable = theNewEditor.first; + newObj = theNewEditor.second; + } else if (AreEqual(inTypeName, SCancelEditor::GetTypeStr())) { + eastl::pair theNewEditor = CreateEditorAndObject(); + newExecutable = theNewEditor.first; + newObj = theNewEditor.second; + } else { + QT3DS_ASSERT(false); + return TObjPtr(); + } + if (newExecutable) + newExecutable->m_StateNodeParent = &inParent; + return newObj; + } + + SValue SEditorImpl::GetSendId(const char8_t *expression) + { + if (isTrivial(expression)) + return SValue((QT3DSU32)0); + return static_cast(IExecutionContext::ParseTimeStrToMilliseconds(expression)); + } + + void SEditorImpl::SetSendId(const Option &inData, const char8_t *&outExpression) + { + if (!isTrivial(outExpression)) + m_AutoAllocator.deallocate(const_cast(outExpression)); + + outExpression = ""; + + if (inData.hasValue() && inData->getType() == ValueTypes::U32) { + QT3DSU32 expr = inData->getData(); + char buffer[64]; + sprintf(buffer, "%u", expr); + int len = strlen(buffer); + if (len < 61) { + buffer[len] = 'm'; + buffer[len + 1] = 's'; + buffer[len + 2] = 0; + } + outExpression = ToGraphStr(buffer); + } + } + + IStateContext &SEditorImpl::GetStateContext() { return *m_StateContext; } + + void SEditorImpl::SetTransactionManager(STransactionManagerImpl &manager) + { + m_TransactionManager = &manager; + } + + bool IsLegalHistoryTarget(StateNodeTypes::Enum inType) + { + return inType == StateNodeTypes::State || inType == StateNodeTypes::Final + || inType == StateNodeTypes::Parallel; + } + + void RecurseGetChildrenForHistoryTarget(SState &inNode, + eastl::vector &retval) + { + for (TStateNodeList::iterator iter = inNode.m_Children.begin(), + end = inNode.m_Children.end(); + iter != end; ++iter) { + if (IsLegalHistoryTarget(iter->m_Type)) { + retval.push_back(iter->m_Id); + if (iter->m_Type == StateNodeTypes::State) + RecurseGetChildrenForHistoryTarget(static_cast(*iter), retval); + } + } + } + + eastl::vector SEditorImpl::GetLegalHistoryDefaultValues(SHistory &inData) + { + eastl::vector retval; + if (inData.m_Parent && inData.m_Parent->m_Type == StateNodeTypes::State) { + SState &theState = static_cast(*inData.m_Parent); + for (TStateNodeList::iterator iter = theState.m_Children.begin(), + end = theState.m_Children.end(); + iter != end; ++iter) { + if (IsLegalHistoryTarget(iter->m_Type)) { + retval.push_back(iter->m_Id); + if (inData.m_Flags.IsDeep()) { + if (iter->m_Type == StateNodeTypes::State) + RecurseGetChildrenForHistoryTarget(static_cast(*iter), + retval); + } + } + } + } + return retval; + } + + void RecurseGetLegalParents(eastl::vector &outResult, + SStateNode &inTarget, SStateNode &inCurrent) + { + // Basic checks + if (inCurrent.m_Type == StateNodeTypes::History + || inCurrent.m_Type == StateNodeTypes::Final || &inCurrent == &inTarget) + return; + + // Parallel's cannot have finals, but their children could + bool isIllegalChild = (inTarget.m_Type == StateNodeTypes::Final + && inCurrent.m_Type == StateNodeTypes::Parallel) + || inCurrent.m_Type == StateNodeTypes::SCXML; + + if (isIllegalChild == false) { + outResult.push_back(inCurrent.m_Id); + } + TStateNodeList *children = inCurrent.GetChildren(); + if (children) { + for (TStateNodeList::iterator iter = children->begin(), end = children->end(); + iter != end; ++iter) { + RecurseGetLegalParents(outResult, inTarget, *iter); + } + } + } + + static bool lexi(CRegisteredString lhs, CRegisteredString rhs) + { + return strcmp(lhs.c_str(), rhs.c_str()) < 0; + } + + eastl::vector SEditorImpl::GetLegalParentIds(SStateNode &inNode) + { + // Do a depth first search and just do not include this node or any history or final + // nodes. + eastl::vector retval; + RecurseGetLegalParents(retval, inNode, *m_StateContext->GetRoot()); + eastl::sort(retval.begin(), retval.end(), lexi); + return retval; + } + + struct SParentChange : public IChange + { + TObjPtr m_ChildObj; + TStateNodeList *m_OldList; + TStateNodeList &m_NewList; + SStateNode *m_OldParent; + SStateNode &m_NewParent; + SStateNode &m_Child; + QT3DSI32 m_RefCount; + SParentChange(TObjPtr childObj, TStateNodeList *oldL, TStateNodeList &newL, + SStateNode *oldp, SStateNode &newp, SStateNode &c) + : m_ChildObj(childObj) + , m_OldList(oldL) + , m_NewList(newL) + , m_OldParent(oldp) + , m_NewParent(newp) + , m_Child(c) + , m_RefCount(0) + { + } + + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + + virtual void Do() + { + if (m_OldList) + m_OldList->remove(m_Child); + m_NewList.push_back(m_Child); + m_Child.m_Parent = &m_NewParent; + } + virtual void Undo() + { + m_NewList.remove(m_Child); + if (m_OldList) + m_OldList->push_back(m_Child); + m_Child.m_Parent = m_OldParent; + } + + virtual TObjPtr GetEditor() { return m_ChildObj; } + }; + + void SEditorImpl::SetParent(SStateNode &inNode, const Option &inValue) + { + STransaction *theTransaction = m_TransactionManager->GetOpenTransactionImpl(); + SStateNode *oldParent = inNode.m_Parent; + TEditorStr newParentId; + if (inValue.hasValue()) + newParentId = inValue->getData(); + + SStateNode *newParent = + m_StateContext->FindStateNode(m_StringTable->RegisterStr(newParentId.c_str())); + if (newParent == NULL) + newParent = m_StateContext->GetRoot(); + TStateNodeList *newList = newParent->GetChildren(); + if (newList == NULL) { + QT3DS_ASSERT(false); + return; + } + SParentChange *theChange = + new SParentChange(ToEditor(inNode), oldParent ? oldParent->GetChildren() : NULL, + *newList, oldParent, *newParent, inNode); + theChange->Do(); + if (theTransaction) { + theTransaction->m_Changes.push_back(theChange); + if (oldParent) + theTransaction->m_Changes.push_back(new SChange(*ToEditor(*oldParent))); + theTransaction->m_Changes.push_back(new SChange(*ToEditor(*newParent))); + } + CheckAndSetValidHistoryDefault(ToEditor(inNode)); + // Fix the initial state of the old parent if it exists + if (oldParent) { + if (isTrivial(oldParent->GetInitialExpression()) + && oldParent->GetInitialTransition()) { + STransition *theTransition = oldParent->GetInitialTransition(); + if (theTransition != NULL && theTransition->m_Target.size()) { + bool foundItem = false; + for (QT3DSU32 idx = 0, end = theTransition->m_Target.size(); + idx < end && foundItem == false; ++idx) { + if (theTransition->m_Target[idx] == &inNode) + foundItem = true; + } + if (foundItem) { + SetInitialAttribute(SValue(TEditorStr()), *oldParent); + } + } + } + // fix all history nodes + TStateNodeList *parentChildren = oldParent->GetChildren(); + if (parentChildren) { + for (TStateNodeList::iterator iter = parentChildren->begin(), + end = parentChildren->end(); + iter != end; ++iter) { + if (iter->m_Type == StateNodeTypes::History) { + CheckAndSetValidHistoryDefault(ToEditor(*iter)); + } + } + } + } + // Set the new object inside the new parent. + ToEditor(inNode)->SetPropertyValue("position", QT3DSVec2(0, 0)); + } + + void SEditorImpl::CheckAndSetValidHistoryDefault(TObjPtr inHistoryNode) + { + if (inHistoryNode && AreEqual(inHistoryNode->TypeName(), "history")) { + eastl::vector validChildren = + inHistoryNode->GetLegalValues("default"); + TObjList existing = inHistoryNode->GetPropertyValue("default")->getData(); + if (existing.size()) { + // Ensure all of the existing nodes are in the valid children list. + bool allValid = true; + for (size_t existingIdx = 0, existingEnd = existing.size(); + existingIdx < existingEnd && allValid; ++existingIdx) { + CRegisteredString idStr = + m_StringTable->RegisterStr(existing[existingIdx]->GetId().c_str()); + if (eastl::find(validChildren.begin(), validChildren.end(), idStr) + == validChildren.end()) + allValid = false; + } + if (allValid) + return; + } + SetValidHistoryDefault(inHistoryNode); + } + } + + void SEditorImpl::SetValidHistoryDefault(TObjPtr inHistoryNode) + { + if (inHistoryNode && AreEqual(inHistoryNode->TypeName(), "history")) { + eastl::vector legalValues = + inHistoryNode->GetLegalValues("default"); + if (legalValues.size()) { + TObjPtr firstLegal = GetObjectById(legalValues[0]); + TObjList propValue; + propValue.push_back(firstLegal); + inHistoryNode->SetPropertyValue("default", propValue); + } + } + } + + MallocAllocator SBaseEditorFoundation::g_BaseAlloc; + + bool SPropertyDecNameFinder::operator()(const SPropertyDeclaration &dec) const + { + return AreEqual(m_NameStr, dec.m_Name.c_str()); + } + + void IEditorObject::Append(const char8_t *inPropName, TObjPtr inObj) + { + Option theProp = GetPropertyValue(inPropName); + if (theProp.hasValue() && theProp->getType() == ValueTypes::ObjPtrList + && inObj != NULL) { + TObjList theData = theProp->getData(); + theData.push_back(inObj); + SetPropertyValue(inPropName, theData); + } + } + + void IEditorObject::Remove(const char8_t *inPropName, TObjPtr inObj) + { + Option theProp = GetPropertyValue(inPropName); + if (theProp.hasValue() && theProp->getType() == ValueTypes::ObjPtrList + && inObj != NULL) { + TObjList theData = theProp->getData(); + TObjList::iterator theFind = eastl::find(theData.begin(), theData.end(), inObj); + if (theFind != theData.end()) + theData.erase(theFind); + SetPropertyValue(inPropName, theData); + } + } + + IEditor &IEditor::CreateEditor() + { + TFoundationPtr theFoundation = SBaseEditorFoundation::Create(); + return *QT3DS_NEW(theFoundation->getAllocator(), SEditorImpl)( + theFoundation, IStringTable::CreateStringTable(theFoundation->getAllocator())); + } + + IEditor *IEditor::CreateEditor(const char8_t *inFname) + { + CFileSeekableIOStream theFile(inFname, FileReadFlags()); + if (theFile.IsOpen() == false) + return NULL; + + return CreateEditor(inFname, theFile); + } + + IEditor *IEditor::CreateEditor(const char8_t *inFname, IInStream &inStream) + { + IEditor &theEditor(CreateEditor()); + if (static_cast(theEditor).Load(inStream, inFname)) + return &theEditor; + + theEditor.release(); + return NULL; + } + } +} +} diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.h new file mode 100644 index 00000000..31c83afe --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditor.h @@ -0,0 +1,315 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_H +#define QT3DS_STATE_EDITOR_H +#pragma once +#include "Qt3DSState.h" +#include "Qt3DSStateSignalConnection.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/TaggedPointer.h" +#include "EASTL/vector.h" +#include "EASTL/string.h" +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "Qt3DSStateInterpreter.h" + +namespace qt3ds { +namespace state { + namespace editor { + + class IEditorObject; + typedef NVScopedRefCounted TObjPtr; + typedef eastl::vector TObjList; + + class IEditorChangeListener + { + protected: + virtual ~IEditorChangeListener() {} + public: + // The same object may be represented multiple times in this list. + virtual void OnDataChange(const TObjList &inChangedObjects, + const TObjList &inRemovedObjects) = 0; + }; + + struct EditorPropertyTypes + { + enum Enum { + NoProperty = 0, + Event, // string + Id, // string + Object, // IEditorObject + ObjectList, // IEditorObject list + // A string, but one from a set of strings. + StringSet, // string + String, // string, single line + BigString, // string than may be multiple lines long + Position, // vec2 + Dimension, // vec2 + PositionList, // vector + Script, // string + Color, + Boolean, + U32, + }; + }; + + struct SPropertyDeclaration + { + CRegisteredString m_Name; + EditorPropertyTypes::Enum m_Type; + // for enumerations, the list of enumerations + SPropertyDeclaration() {} + SPropertyDeclaration(CRegisteredString inName, EditorPropertyTypes::Enum inType) + : m_Name(inName) + , m_Type(inType) + { + } + }; + + typedef eastl::vector TPropertyDeclarationList; + + struct SPropertyDecNameFinder + { + const char8_t *m_NameStr; + SPropertyDecNameFinder(const char8_t *nmStr) + : m_NameStr(nmStr) + { + } + // Implemented in UICStateEditor.cpp to include "foundation/Utils.h" + bool operator()(const SPropertyDeclaration &dec) const; + }; + + typedef eastl::vector TVec2List; + typedef eastl::string TEditorStr; + typedef eastl::vector TEditorStrList; + + // Our generic discriminated union type for all property values. + struct SValue; + struct SValueOpt; + + class IEditor; + + class IEditorObject : public NVRefCounted + { + protected: + virtual ~IEditorObject() {} + const char8_t *m_TypeName; + + public: + IEditorObject(const char8_t *tn) + : m_TypeName(tn) + { + } + const char8_t *TypeName() const { return m_TypeName; } + // implemented in UICStateEditor.cpp using getpropertyvalue. + virtual TEditorStr GetId() = 0; + virtual TEditorStr GetDescription() = 0; + virtual void SetId(const TEditorStr &inId) = 0; + virtual void SetDescription(const TEditorStr &inName) = 0; + // Things only have one canonical parent. + virtual TObjPtr Parent() = 0; + + virtual void GetProperties(eastl::vector &outProperties) = 0; + virtual Option FindProperty(const char8_t *propName) = 0; + // The legal values for a property tend to be something that have to be calculated + // dynamically. + virtual eastl::vector GetLegalValues(const char8_t *propName) = 0; + + virtual Option GetPropertyValue(const char8_t *inPropName) = 0; + virtual void SetPropertyValue(const char8_t *inPropName, const SValueOpt &inValue) = 0; + virtual bool endEdit() { return false; } // should SetPropertyValue end property edit + + // Utility function implemented in UICStateEditor.cpp + virtual void Append(const char8_t *inPropName, TObjPtr inObj); + virtual void Remove(const char8_t *inPropName, TObjPtr inObj); + + // Remove this from any parents. Remove any transitions pointing to this. + // Only works for state-node derived types. + // Executable content, onEntry onExit and such will not work with this. + // Also removes this item id from the id map. This is what is used to delete objects. + // Do not reattach yourself; callers should release all references to this object after + // calling + // this. + virtual void RemoveObjectFromGraph() = 0; + + // Internal calls, don't call externally + virtual void RemoveIdFromContext() = 0; + virtual void AddIdToContext() = 0; + + // Most things do not have any executable content. + virtual NVConstDataRef GetExecutableContentTypes() + { + return NVConstDataRef(); + } + + // Be aware that there are more types of executable content than indicated in the store; + // a lot more. + // So just ignore the types the story ignores. + virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum /*inType*/) + { + return TObjList(); + } + + // inName can be an executable content: + //'script', 'send', 'cancel' + virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum /*inType*/, + const char8_t * /*inName*/) + { + return TObjPtr(); + } + + virtual IEditor &GetEditor() = 0; + }; + + class ITransaction : public NVRefCounted + { + protected: + virtual ~ITransaction() {} + TEditorStr m_Name; + + public: + ITransaction(const TEditorStr inName = TEditorStr()) + : m_Name(inName) + { + } + TEditorStr GetName() const { return m_Name; } + // Send the signals collected during the creation of this transaction + virtual void SendDoSignals() = 0; + virtual TObjList GetEditedObjects() = 0; + virtual void Do() = 0; + virtual void Undo() = 0; + virtual bool Empty() = 0; + }; + + typedef NVScopedRefCounted TTransactionPtr; + + class ITransactionManager : public NVRefCounted + { + protected: + virtual ~ITransactionManager() {} + public: + virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener) = 0; + // Undo/redo is supported via a transparent transaction system. + // calls are reentrant but last call will close the transaction object. + // Any changes to any editor objects will go through this transaction when they happen. + virtual TTransactionPtr BeginTransaction(const TEditorStr &inName = TEditorStr()) = 0; + virtual TTransactionPtr GetOpenTransaction() = 0; + virtual void RollbackTransaction() = 0; + virtual void EndTransaction() = 0; + }; + + // Editor interface to a UICState dataset + class IEditor : public ITransactionManager + { + protected: + virtual ~IEditor() {} + public: + // Traditional editor interface. + virtual TObjPtr GetRoot() = 0; + // You can force the id to be a particular ID in some cases, this is useful for testing. + // ID is ignored for objects that don't have an id. + virtual TObjPtr Create(const char8_t *inTypeName, const char8_t *inId = 0) = 0; + virtual TObjPtr GetOrCreate(SSCXML &inData) = 0; + virtual TObjPtr GetOrCreate(SState &inData) = 0; + virtual TObjPtr GetOrCreate(STransition &inData) = 0; + virtual TObjPtr GetOrCreate(SParallel &inData) = 0; + virtual TObjPtr GetOrCreate(SHistory &inData) = 0; + virtual TObjPtr GetOrCreate(SFinal &inData) = 0; + virtual TObjPtr GetOrCreate(SDataModel &inData) = 0; + virtual TObjPtr GetOrCreate(SData &inData) = 0; + virtual TObjPtr ToEditor(SStateNode &inItem) = 0; + + // Get a particular object by id. Useful in testing scenarios. + virtual TObjPtr GetObjectById(const char8_t *inId) = 0; + + // Get an editor, if it already has been created, for this piece of graph data. + // Note that if it has not been created, this function couldn't possibly create it + // due to lack of type information. + virtual TObjPtr GetEditor(void *inGraphData) = 0; + + // Copy save a subgraph to a string. Converts all top level positions to be relative to + // mouse pos. + virtual TEditorStr Copy(TObjList inObjects, const QT3DSVec2 &inMousePos) = 0; + virtual bool CanPaste(TObjPtr inTarget) = 0; + // Paste in, adding relative pos to all top level positions. + virtual void Paste(const TEditorStr &inCopiedObjects, TObjPtr inTarget, + const QT3DSVec2 &inRelativePos) = 0; + + virtual TObjPtr GetLeastCommonAncestor(NVConstDataRef inObjects) = 0; + + // Returns the list of send ids that have a delay on them. + virtual TObjList GetCancelableSendIds() = 0; + + // Return the set of events in use in the state machine. + virtual TEditorStrList GetStateMachineEvents() = 0; + + // Change content from one type to another. + virtual TObjPtr ChangeExecutableContentType(TObjPtr inContent, + const char8_t *newType) = 0; + + virtual TEditorStr ToXML(TObjPtr inContent) = 0; + // Returns the error from parsing the xml or if everything went correctly replaces + // inContent + // with the result of parsing the xml and returns the new content. + virtual eastl::pair FromXML(TObjPtr inContent, + const TEditorStr &ioEditedXML) = 0; + + virtual bool Save(const char8_t *inFname) = 0; + virtual void Save(IOutStream &inStream) = 0; + + // This must be called on history creation once it has been added to the proper parent. + virtual void SetValidHistoryDefault(TObjPtr inHistoryNode) = 0; + + static IEditor &CreateEditor(); + + static IEditor *CreateEditor(const char8_t *inFname); + static IEditor *CreateEditor(const char8_t *inFname, IInStream &inStream); + }; + + typedef NVScopedRefCounted TEditorPtr; + + struct SEditorImplTransactionScope + { + ITransactionManager &m_Editor; + TTransactionPtr m_Transaction; + SEditorImplTransactionScope(ITransactionManager &inEditor) + : m_Editor(inEditor) + , m_Transaction(inEditor.BeginTransaction()) + { + } + ~SEditorImplTransactionScope() { m_Editor.EndTransaction(); } + + TTransactionPtr operator->() { return m_Transaction; } + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorEditorsImpl.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorEditorsImpl.h new file mode 100644 index 00000000..fc9411d2 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorEditorsImpl.h @@ -0,0 +1,1772 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_EDITORS_IMPL_H +#define QT3DS_STATE_EDITOR_EDITORS_IMPL_H +#include "Qt3DSState.h" +#include "Qt3DSStateEditor.h" +#include "Qt3DSStateEditorValue.h" +#include "Qt3DSStateEditorTransactionImpl.h" +#include "Qt3DSStateTypes.h" +#include "Qt3DSStateEditorFoundation.h" +#include "Qt3DSStateEditorProperties.h" +#include "foundation/Utils.h" +#include "foundation/XML.h" +#include "Qt3DSStateXMLIO.h" +#include "foundation/IOStreams.h" +#include "Qt3DSStateExecutionTypes.h" +#include "Qt3DSStateContext.h" +#include "Qt3DSStateEditorImpl.h" + +namespace qt3ds { +namespace state { + namespace editor { + + struct EditorTypes + { + enum Enum { + UnknownEditor = 0, + SCXML, + State, + Parallel, + Transition, + History, + Final, + ExecutableContent, + OnEntry, + OnExit, + Send, + Raise, + If, + Else, + ElseIf, + Log, + Assign, + Script, + DataModel, + Data, + Cancel, + }; + }; + + struct SEditorImplObject : public IEditorObject + { + TFoundationPtr m_Foundation; + SEditorImpl &m_Editor; + volatile QT3DSI32 mRefCount; + eastl::string m_Id; + eastl::string m_Description; + Option m_Color; + TPropertyAccessorList m_PropertyAccessors; + + static void CreateAccessors(SEditorImpl &inData, TPropertyAccessorList &outAccessors, + bool includeId, bool includeColor) + { + if (includeId) + outAccessors.push_back(CreateEditorAccessor(inData, &SEditorImplObject::m_Id, + "id", EditorPropertyTypes::String)); + + outAccessors.push_back( + CreateEditorAccessor(inData, &SEditorImplObject::m_Description, "description", + EditorPropertyTypes::String)); + if (includeColor) + outAccessors.push_back(CreateEditorAccessor( + inData, &SEditorImplObject::m_Color, "color", EditorPropertyTypes::Color)); + } + + SEditorImplObject(const char8_t *tn, SEditorImpl &inData, + const TPropertyAccessorList &inAccessors) + : IEditorObject(tn) + , m_Foundation(inData.m_EditorFoundation) + , m_Editor(inData) + , mRefCount(0) + , m_PropertyAccessors(inAccessors) + { + } + + IPropertyAccessor *FindPropertyAccessor(const char8_t *inName) + { + CRegisteredString nameStr = m_Editor.m_StringTable->RegisterStr(inName); + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) + if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) + return m_PropertyAccessors[idx].mPtr; + return NULL; + } + + virtual void GetProperties(eastl::vector &outProperties) + { + outProperties.clear(); + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } + + virtual Option FindProperty(const char8_t *propName) + { + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { + if (AreEqual(m_PropertyAccessors[idx]->m_Declaration.m_Name.c_str(), propName)) + return m_PropertyAccessors[idx]->m_Declaration; + } + return Empty(); + } + + virtual eastl::vector GetLegalValues(const char8_t *propName) + { + IPropertyAccessor *accessor = FindPropertyAccessor(propName); + if (accessor) + return accessor->GetLegalValues(*this); + return eastl::vector(); + } + + virtual Option GetPropertyValue(const char8_t *inPropName) + { + IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); + if (accessor) { + return accessor->Get(*this); + } + return Empty(); + } + virtual void SetPropertyValue(const char8_t *inPropName, const SValueOpt &inValue) + { + IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); + if (accessor) { + if (accessor->HandlesTransaction() == false) { + STransaction *theTransaction = m_Editor.GetOpenTransactionImpl(); + if (theTransaction) { + Option existing = accessor->Get(*this); + theTransaction->m_Changes.push_back( + new SChange(existing, inValue, *accessor, *this)); + } + } + accessor->Set(*this, inValue); + } else { + QT3DS_ASSERT(false); + } + } + + virtual TEditorStr GetId() + { + Option propValue = GetPropertyValue("id"); + if (propValue.hasValue()) + return propValue->getData(); + return TEditorStr(); + } + virtual TEditorStr GetDescription() { return m_Description; } + // We have to go through the SPV interface to take transactions into account. + + virtual void SetId(const TEditorStr &inName) { SetPropertyValue("id", SValue(inName)); } + virtual void SetDescription(const TEditorStr &inName) + { + SetPropertyValue("description", SValue(inName)); + } + + virtual TObjPtr Parent() { return TObjPtr(); } + virtual void RemoveObjectFromGraph() { QT3DS_ASSERT(false); } + + virtual IEditor &GetEditor() { return m_Editor; } + }; + +#define QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE \ + void addRef() { atomicIncrement(&mRefCount); } \ + void release() \ + { \ + TFoundationPtr fnd(m_Foundation); \ + /*Ensure the editor sticks around till *after* we are gone. */ \ + /*This is because our objects will keep several bits of the editor around */ \ + QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Foundation->getAllocator()); \ + } + + struct SSCXMLEditor : public SEditorImplObject + { + typedef SSCXML TStateType; + enum { EditorType = EditorTypes::SCXML }; + + SSCXML &m_Data; + eastl::string m_InitialComboValue; + bool m_endEdit; + + static const char8_t *GetTypeStr() { return "scxml"; } + + static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + typedef SDataProp TInitialProp; + typedef SFlagBooleanProperty TBindingProp; + TPropertyAccessorList &retval(inList); + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + typedef SDataProp TNameProp; + typedef SInitialComboProp TInitialComboProp; + typedef SDataProp TCharProp; + IPropertyAccessor *newAccessor = + QT3DS_NEW(alloc, TNameProp)(inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("name"), + EditorPropertyTypes::String), + &SSCXML::m_Name); + retval.push_back(newAccessor); + retval.push_back(CreateEditorAccessor(inEditorData, + &SEditorImplObject::m_Description, + "description", EditorPropertyTypes::String)); + newAccessor = QT3DS_NEW(alloc, TBindingProp)( + inEditorData.m_EditorFoundation, *inEditorData.m_StringTable, "binding", + "early", "late", &SSCXMLFlags::IsLateBinding, &SSCXMLFlags::SetLateBinding); + retval.push_back(newAccessor); + + TInitialComboProp *theInitialCombo = QT3DS_NEW(alloc, TInitialComboProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("initial"), + EditorPropertyTypes::StringSet)); + retval.push_back(theInitialCombo); + + TCharProp *theInitialExprProp = QT3DS_NEW(alloc, TCharProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("initialexpr"), + EditorPropertyTypes::BigString), + &SSCXML::m_InitialExpr); + retval.push_back(theInitialExprProp); + + retval.push_back(CreateDataAccessor( + inEditorData, &SSCXML::m_DataModel, "datamodel", EditorPropertyTypes::Object)); + newAccessor = QT3DS_NEW(alloc, SChildrenProperty)( + inEditorData.m_EditorFoundation, *inEditorData.m_StringTable); + retval.push_back(newAccessor); + // Replace the name property with one that writes to our data + return retval; + } + + SSCXMLEditor(SSCXML &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SEditorImplObject(GetTypeStr(), inEditorData, + CreateAccessors(inEditorData, inList)) + , m_Data(inData) + , m_endEdit(false) + { + } + + void ApplyInitial(const TEditorStr &comboValue) + { + m_endEdit = false; + + if (m_InitialComboValue == "(script expression)" + || comboValue == "(script expression)") + m_endEdit = true; + + m_InitialComboValue = comboValue; + } + + virtual bool endEdit() + { + bool bTemp = m_endEdit; + m_endEdit = false; + return bTemp; + } + + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual void RemoveObjectFromGraph() { QT3DS_ASSERT(false); } + + virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } + + virtual void AddIdToContext() + { + if (m_Data.m_Id.IsValid()) + m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); + } + + virtual void GetProperties(eastl::vector &outProperties) + { + outProperties.clear(); + eastl::vector temp; + m_Editor.GetLegalInitialValues(m_Data, temp); + bool hasInitialState = temp.size() > 1; + bool hasInitialExpr = false; + CRegisteredString nameStr = m_Editor.RegisterStr("initial"); + CRegisteredString initialExprStr = m_Editor.RegisterStr("initialexpr"); + + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { + if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { + if (hasInitialState) + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } else if (m_PropertyAccessors[idx]->m_Declaration.m_Name == initialExprStr) { + if (hasInitialExpr) + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } else { + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } + + if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { + TEditorStr initialValue = + m_PropertyAccessors[idx]->Get(*this)->getData(); + if (initialValue == "(script expression)") + hasInitialExpr = true; + } + } + } + }; + + struct SPositionalEditor : public SEditorImplObject + { + SPositionalEditor(const char8_t *inTypeName, SEditorImpl &inData, + const TPropertyAccessorList &inAccessors) + : SEditorImplObject(inTypeName, inData, inAccessors) + { + } + }; + + template + struct TListInsertDeleteChange : public IChange + { + TObjPtr m_EditorObject; + QT3DSI32 mRefCount; + TListType *m_ParentList; + TListItem *m_TargetContent; + QT3DSI32 m_ContentIdx; + bool m_AddOnDo; + // The item must be in the list for this to work. + TListInsertDeleteChange(TObjPtr inEditor, TListType *plist, TListItem *tc, bool addOnDo) + : m_EditorObject(inEditor) + , mRefCount(0) + , m_ParentList(plist) + , m_TargetContent(tc) + , m_ContentIdx(-1) + , m_AddOnDo(addOnDo) + { + for (typename TListType::iterator iter = m_ParentList->begin(), + end = m_ParentList->end(); + iter != end; ++iter) { + if (&(*iter) == m_TargetContent) + break; + // setup content idx to point to the item just our target item. + ++m_ContentIdx; + } + } + virtual void addRef() { atomicIncrement(&mRefCount); } + virtual void release() + { + atomicDecrement(&mRefCount); + if (mRefCount <= 0) { + delete this; + } + } + void add() + { + if (m_ContentIdx > -1) { + QT3DSI32 idx = m_ContentIdx - 1; + typename TListType::iterator iter = m_ParentList->begin(); + + for (typename TListType::iterator end = m_ParentList->end(); + iter != end && idx > -1; ++iter, --idx) { + }; + + if (iter != m_ParentList->end()) + m_ParentList->insert_after(*iter, *m_TargetContent); + else + m_ParentList->push_back(*m_TargetContent); + } else + m_ParentList->push_front(*m_TargetContent); + } + void remove() { m_ParentList->remove(*m_TargetContent); } + + virtual void Do() + { + if (m_AddOnDo) + add(); + else + remove(); + } + virtual void Undo() + { + if (m_AddOnDo) + remove(); + else + add(); + } + virtual TObjPtr GetEditor() { return m_EditorObject; } + }; + + struct SExecutableContentChange + : public TListInsertDeleteChange + { + typedef TListInsertDeleteChange TBase; + SExecutableContentChange(TObjPtr inEditor, TExecutableContentList *plist, + SExecutableContent *tc, bool addOnDo) + : TBase(inEditor, plist, tc, addOnDo) + { + } + }; + + struct SStateEditor : public SPositionalEditor + { + typedef SState TStateType; + enum { EditorType = EditorTypes::State }; + SState &m_Data; + eastl::string m_InitialComboValue; + bool m_endEdit; + static const char8_t *GetTypeStr() { return "state"; } + + template + static void CreateStateNodeChildren(SEditorImpl &inEditorData, + TPropertyAccessorList &retval) + { + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + IPropertyAccessor *newAccessor = QT3DS_NEW(alloc, SChildrenProperty)( + inEditorData.m_EditorFoundation, *inEditorData.m_StringTable); + retval.push_back(newAccessor); + } + + template + static void CreatePositionColorAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &retval) + { + typedef SOptionAccessorProp TVec2Access; + typedef SOptionAccessorProp TVec3Access; + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + retval.push_back(QT3DS_NEW(alloc, TVec2Access)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("position"), + EditorPropertyTypes::Position), + &SStateNode::GetPosition, &SStateNode::SetPosition)); + retval.push_back(QT3DS_NEW(alloc, TVec2Access)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("dimension"), + EditorPropertyTypes::Position), + &SStateNode::GetDimension, &SStateNode::SetDimension)); + + retval.push_back(QT3DS_NEW(alloc, TVec3Access)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("color"), + EditorPropertyTypes::Color), + &SStateNode::GetColor, &SStateNode::SetColor)); + } + + static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + typedef SDataProp TInitialProp; + typedef SDataIdProp TIdPropType; + typedef SInitialTargetProp TInitialTargetProp; + typedef SInitialComboProp TInitialComboProp; + typedef SDataProp TCharProp; + + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + + TPropertyAccessorList &retval(inList); + retval.push_back(QT3DS_NEW(alloc, TIdPropType)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), + &SState::m_Id)); + + typedef SParentProp TParentPropType; + retval.push_back(QT3DS_NEW(alloc, TParentPropType)(inEditorData.m_EditorFoundation, + *inEditorData.m_StringTable)); + SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); + + TInitialComboProp *theInitialCombo = QT3DS_NEW(alloc, TInitialComboProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("initial"), + EditorPropertyTypes::StringSet)); + retval.push_back(theInitialCombo); + + TCharProp *theInitialExprProp = QT3DS_NEW(alloc, TCharProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("initialexpr"), + EditorPropertyTypes::BigString), + &SState::m_InitialExpr); + retval.push_back(theInitialExprProp); + retval.push_back(CreateDataAccessor( + inEditorData, &SState::m_DataModel, "datamodel", EditorPropertyTypes::Object)); + CreateStateNodeChildren(inEditorData, retval); + CreatePositionColorAccessors(inEditorData, retval); + retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), + EditorPropertyTypes::Boolean))); + // Replace the name property with one that writes to our data + return retval; + } + SStateEditor(SState &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SPositionalEditor(GetTypeStr(), inEditorData, + CreateAccessors(inEditorData, inList)) + , m_Data(inData) + , m_endEdit(false) + { + } + + virtual void GetProperties(eastl::vector &outProperties) + { + outProperties.clear(); + eastl::vector temp; + m_Editor.GetLegalInitialValues(m_Data, temp); + bool hasInitialState = temp.size() > 1; + bool hasInitialExpr = false; + CRegisteredString nameStr = m_Editor.RegisterStr("initial"); + CRegisteredString initialExprStr = m_Editor.RegisterStr("initialexpr"); + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { + if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { + if (hasInitialState) + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } else if (m_PropertyAccessors[idx]->m_Declaration.m_Name == initialExprStr) { + if (hasInitialExpr) + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } else + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + + if (hasInitialState + && m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) { + TEditorStr initialValue = + m_PropertyAccessors[idx]->Get(*this)->getData(); + if (initialValue == "(script expression)") + hasInitialExpr = true; + } + } + } + + void ApplyInitial(const TEditorStr &comboValue) + { + m_endEdit = false; + + if (m_InitialComboValue == "(script expression)" + || comboValue == "(script expression)") + m_endEdit = true; + + m_InitialComboValue = comboValue; + } + + virtual bool endEdit() + { + bool bTemp = m_endEdit; + m_endEdit = false; + return bTemp; + } + + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } + virtual void AddIdToContext() + { + if (m_Data.m_Id.IsValid()) + m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + struct SObjListContains + { + const TObjList &m_Targets; + SObjListContains(const TObjList &t) + : m_Targets(t) + { + } + bool operator()(const TObjPtr &inObj) const + { + return eastl::find(m_Targets.begin(), m_Targets.end(), inObj.mPtr) + != m_Targets.end(); + } + }; + + static void CheckAndRemoveStateFromTransitionProperty(TObjList &removedItems, + IEditorObject &inEditorObj, + const char8_t *propName) + { + Option propVal = inEditorObj.GetPropertyValue(propName); + if (propVal.hasValue()) { + if (propVal->getType() == ValueTypes::ObjPtr) { + TObjPtr transProp = propVal->getData(); + if (transProp) { + TObjList propValValues = + transProp->GetPropertyValue("target")->getData(); + TObjList::iterator lastIter = + eastl::remove_if(propValValues.begin(), propValValues.end(), + SObjListContains(removedItems)); + if (lastIter != propValValues.end()) { + propValValues.erase(lastIter, propValValues.end()); + if (propValValues.empty()) + inEditorObj.SetPropertyValue(propName, TObjPtr()); + else + transProp->SetPropertyValue("target", propValValues); + } + } + } else if (propVal->getType() == ValueTypes::String) { + TEditorStr theIdStr = propVal->getData(); + for (size_t idx = 0, end = removedItems.size(); idx < end; ++idx) { + if (removedItems[idx]->GetId() == theIdStr) { + inEditorObj.SetPropertyValue(propName, TEditorStr()); + break; + } + } + } + } + } + + static void RemoveTransitionsPointingTo(TObjList &removedItems, + IEditorObject &inEditorObj) + { + if (AreEqual(inEditorObj.TypeName(), "transition")) { + TObjList targets = inEditorObj.GetPropertyValue("target")->getData(); + TObjList::iterator lastIter = eastl::remove_if(targets.begin(), targets.end(), + SObjListContains(removedItems)); + if (lastIter != targets.end()) { + targets.erase(lastIter, targets.end()); + inEditorObj.SetPropertyValue("target", targets); + if (targets.size() == 0) + inEditorObj.RemoveObjectFromGraph(); + } + } else { + // state and parallel + CheckAndRemoveStateFromTransitionProperty(removedItems, inEditorObj, "initial"); + // history + CheckAndRemoveStateFromTransitionProperty(removedItems, inEditorObj, + "transition"); + } + Option childListOpt = inEditorObj.GetPropertyValue("children"); + if (childListOpt.hasValue()) { + TObjList childList = childListOpt->getData(); + for (size_t idx = 0, end = childList.size(); idx < end; ++idx) + RemoveTransitionsPointingTo(removedItems, *childList[idx]); + } + } + static void RemoveObjectFromGraph(IEditorObject &inEditorObj, + TObjList &outRemovedObjects) + { + TObjPtr parentPtr = inEditorObj.Parent(); + outRemovedObjects.push_back(&inEditorObj); + if (parentPtr) + parentPtr->Remove("children", &inEditorObj); + + Option nodeChildrenOpt = inEditorObj.GetPropertyValue("children"); + if (nodeChildrenOpt.hasValue()) { + TObjList nodeChildren(nodeChildrenOpt->getData()); + for (size_t idx = 0, end = nodeChildren.size(); idx < end; ++idx) + RemoveObjectFromGraph(*nodeChildren[idx], outRemovedObjects); + } + } + + virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } + + // Simple and slow as hell. + static void RemoveObjectFromGraph(SEditorImplObject &inEditorObj) + { + TObjList removedItems; + TObjPtr oldParent = inEditorObj.Parent(); + RemoveObjectFromGraph(inEditorObj, removedItems); + RemoveTransitionsPointingTo(removedItems, *inEditorObj.m_Editor.GetRoot()); + for (size_t idx = 0, end = removedItems.size(); idx < end; ++idx) { + inEditorObj.m_Editor.m_TransactionManager->OnObjectDeleted(removedItems[idx]); + inEditorObj.RemoveIdFromContext(); + } + if (oldParent) { + TObjList children = + oldParent->GetPropertyValue("children")->getData(); + for (size_t childIdx = 0, childEnd = children.size(); childIdx < childEnd; + ++childIdx) { + inEditorObj.m_Editor.CheckAndSetValidHistoryDefault(children[childIdx]); + } + } + } + + virtual void RemoveObjectFromGraph() { RemoveObjectFromGraph(*this); } + + virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } + + virtual NVConstDataRef GetExecutableContentTypes() + { + static InterpreterEventTypes::Enum retval[] = { InterpreterEventTypes::StateEnter, + InterpreterEventTypes::StateExit }; + return toConstDataRef(retval, 2); + } + + template + static TObjList ListDataToEditor(TListType &inList, SEditorImplObject &ioObj) + { + TObjList retval; + typename TListType::iterator iter = inList.begin(); + // Take the first one. + if (iter != inList.end()) { + for (TExecutableContentList::iterator + contentIter = iter->m_ExecutableContent.begin(), + contentEnd = iter->m_ExecutableContent.end(); + contentIter != contentEnd; ++contentIter) { + TObjPtr editorData = ioObj.m_Editor.ExecutableContentToEditor(*contentIter); + retval.push_back(editorData); + } + } + return retval; + } + + static TObjList ListDataToEditor(InterpreterEventTypes::Enum inType, + SEntryExitBase &inItem, SEditorImplObject &ioObj) + { + switch (inType) { + case InterpreterEventTypes::StateEnter: + return ListDataToEditor(inItem.m_OnEntry, ioObj); + case InterpreterEventTypes::StateExit: + return ListDataToEditor(inItem.m_OnExit, ioObj); + default: + break; + } + QT3DS_ASSERT(false); + return TObjList(); + } + + virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) + { + return SStateEditor::ListDataToEditor(inType, m_Data, *this); + } + + template + static TObjPtr DoCreateAppendExecutableContent(SEditorImplObject &inObj, + TListType &inList, const char8_t *inName, + SStateNode &inNode) + { + NVScopedRefCounted theNewListItemChange; + if (inList.empty()) { + TListItemType *newType = + QT3DS_NEW(inObj.m_Editor.m_AutoAllocator, TListItemType)(); + inList.push_back(*newType); + theNewListItemChange = new TListInsertDeleteChange( + inObj, &inList, newType, true); + } + TListItemType &theFront = *inList.begin(); + TObjPtr retval = inObj.m_Editor.CreateExecutableContent(inNode, inName); + SExecutableContent *theContent = inObj.m_Editor.ExecutableContentFromEditor(retval); + theFront.m_ExecutableContent.push_back(*theContent); + if (inObj.m_Editor.GetOpenTransactionImpl()) { + if (theNewListItemChange) + inObj.m_Editor.GetOpenTransactionImpl()->m_Changes.push_back( + theNewListItemChange); + + NVScopedRefCounted newChange = + new SExecutableContentChange(inObj, &theFront.m_ExecutableContent, + theContent, true); + inObj.m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(newChange.mPtr); + } + return retval; + } + + static TObjPtr DoCreateAppendExecutableContent(InterpreterEventTypes::Enum inType, + const char8_t *inName, + SEditorImplObject &inObj, + SEntryExitBase &inItem) + { + switch (inType) { + case InterpreterEventTypes::StateEnter: + return DoCreateAppendExecutableContent(inObj, inItem.m_OnEntry, + inName, inItem); + case InterpreterEventTypes::StateExit: + return DoCreateAppendExecutableContent(inObj, inItem.m_OnExit, inName, + inItem); + default: + break; + } + + QT3DS_ASSERT(false); + return TObjPtr(); + } + + virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, + const char8_t *inName) + { + return SStateEditor::DoCreateAppendExecutableContent(inType, inName, *this, m_Data); + } + }; + + struct SParallelEditor : public SPositionalEditor + { + typedef SParallel TStateType; + enum { EditorType = EditorTypes::Parallel }; + SParallel &m_Data; + static const char8_t *GetTypeStr() { return "parallel"; } + + static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + + typedef SInitialTargetProp TInitialTargetProp; + TPropertyAccessorList &retval(inList); + typedef SDataIdProp TIdPropType; + typedef SParentProp TParallelParentProp; + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + retval.push_back(QT3DS_NEW(alloc, TIdPropType)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), + &SParallel::m_Id)); + + retval.push_back(QT3DS_NEW(alloc, TParallelParentProp)(inEditorData.m_EditorFoundation, + *inEditorData.m_StringTable)); + + SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); + retval.push_back(CreateDataAccessor( + inEditorData, &SState::m_DataModel, "datamodel", EditorPropertyTypes::Object)); + SStateEditor::CreateStateNodeChildren(inEditorData, retval); + SStateEditor::CreatePositionColorAccessors(inEditorData, retval); + // Replace the name property with one that writes to our data + retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), + EditorPropertyTypes::Boolean))); + return retval; + } + + SParallelEditor(SParallel &inData, SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + : SPositionalEditor(GetTypeStr(), inEditorData, + CreateAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } + + virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } + + virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } + virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } + + virtual void AddIdToContext() + { + if (m_Data.m_Id.IsValid()) + m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); + } + + virtual NVConstDataRef GetExecutableContentTypes() + { + static InterpreterEventTypes::Enum retval[] = { InterpreterEventTypes::StateEnter, + InterpreterEventTypes::StateExit }; + return toConstDataRef(retval, 2); + } + + virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) + { + return SStateEditor::ListDataToEditor(inType, m_Data, *this); + } + + virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, + const char8_t *inName) + { + return SStateEditor::DoCreateAppendExecutableContent(inType, inName, *this, m_Data); + } + }; + + struct SFinalEditor : public SPositionalEditor + { + typedef SFinal TStateType; + enum { EditorType = EditorTypes::Final }; + + SFinal &m_Data; + static const char8_t *GetTypeStr() { return "final"; } + + static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + typedef SDataIdProp TIdPropType; + typedef SInitialTargetProp TInitialTargetProp; + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + typedef SParentProp TFinalParentProp; + retval.push_back(QT3DS_NEW(alloc, TIdPropType)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), + &SFinal::m_Id)); + retval.push_back(QT3DS_NEW(alloc, TFinalParentProp)(inEditorData.m_EditorFoundation, + *inEditorData.m_StringTable)); + SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); + SStateEditor::CreatePositionColorAccessors(inEditorData, retval); + retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), + EditorPropertyTypes::Boolean))); + // Replace the name property with one that writes to our data + return retval; + } + + SFinalEditor(SFinal &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SPositionalEditor(GetTypeStr(), inEditorData, + CreateAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } + + virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } + + virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } + virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } + + virtual void AddIdToContext() + { + if (m_Data.m_Id.IsValid()) + m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); + } + + virtual NVConstDataRef GetExecutableContentTypes() + { + static InterpreterEventTypes::Enum retval[] = { InterpreterEventTypes::StateEnter, + InterpreterEventTypes::StateExit }; + return toConstDataRef(retval, 2); + } + + virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) + { + return SStateEditor::ListDataToEditor(inType, m_Data, *this); + } + + virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, + const char8_t *inName) + { + return SStateEditor::DoCreateAppendExecutableContent(inType, inName, *this, m_Data); + } + }; + + struct SHistoryEditor : public SPositionalEditor + { + typedef SHistory TStateType; + enum { EditorType = EditorTypes::History }; + SHistory &m_Data; + static const char8_t *GetTypeStr() { return "history"; } + + static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + typedef SDataProp TTransitionProp; + + typedef SFlagBooleanProperty THistoryFlagsProp; + typedef SDataIdProp TIdPropType; + typedef SHistoryTransitionProp THistoryTransitionProp; + typedef SParentProp THistoryParentProp; + typedef SInitialTargetProp TInitialTargetProp; + + TPropertyAccessorList &retval(inList); + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + retval.push_back(QT3DS_NEW(alloc, TIdPropType)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("id"), EditorPropertyTypes::Id), + &SHistory::m_Id)); + retval.push_back(QT3DS_NEW(alloc, THistoryParentProp)(inEditorData.m_EditorFoundation, + *inEditorData.m_StringTable)); + SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); + SStateEditor::CreatePositionColorAccessors(inEditorData, retval); + retval.push_back(QT3DS_NEW( + alloc, THistoryFlagsProp(inEditorData.m_EditorFoundation, + *inEditorData.m_StringTable, "type", "shallow", "deep", + &SHistoryFlags::IsDeep, &SHistoryFlags::SetDeep))); + + retval.push_back(QT3DS_NEW(alloc, TTransitionProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("transition"), + EditorPropertyTypes::ObjectList), + &SHistory::m_Transition)); + + retval.push_back(QT3DS_NEW(alloc, THistoryTransitionProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("default"), + EditorPropertyTypes::ObjectList))); + + retval.push_back(QT3DS_NEW(alloc, TInitialTargetProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("is initial target"), + EditorPropertyTypes::Boolean))); + + return retval; + } + + SHistoryEditor(SHistory &inData, SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + : SPositionalEditor(GetTypeStr(), inEditorData, + CreateAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } + + virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } + + virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } + virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } + + virtual void AddIdToContext() + { + if (m_Data.m_Id.IsValid()) + m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); + } + }; + + struct STransitionEditor : public SEditorImplObject + { + typedef STransition TStateType; + STransition &m_Data; + enum { EditorType = EditorTypes::Transition }; + static const char8_t *GetTypeStr() { return "transition"; } + TVec2List m_PathList; + + static TPropertyAccessorList CreateAccessors(SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + typedef SDataProp TTransCharProp; + typedef SDataProp + TTransRegStrProp; + typedef SDataProp> + TTransTargetProp; + typedef SDataProp> + TTransPathProp; + typedef SFlagBooleanProperty + TTransitionFlagsProp; + typedef SDataIdProp TIdPropType; + typedef SOptionAccessorProp TVec2Access; + typedef SOptionAccessorProp TVec3Access; + typedef SDataIdProp TIdPropType; + + TPropertyAccessorList &retval(inList); + NVAllocatorCallback &alloc(inEditorData.m_EditorFoundation->getAllocator()); + + retval.push_back( + QT3DS_NEW(alloc, TIdPropType)(inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("id"), + EditorPropertyTypes::String), + &STransition::m_Id)); + + retval.push_back(QT3DS_NEW(alloc, TTransRegStrProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("event"), + EditorPropertyTypes::String), + &STransition::m_Event)); + + SEditorImplObject::CreateAccessors(inEditorData, retval, false, false); + IPropertyAccessor *accessor = QT3DS_NEW(alloc, TTransCharProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("cond"), + EditorPropertyTypes::BigString), + &STransition::m_Condition); + + retval.push_back(accessor); + accessor = QT3DS_NEW(alloc, TTransTargetProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("target"), + EditorPropertyTypes::ObjectList), + &STransition::m_Target); + retval.push_back(accessor); + retval.push_back(QT3DS_NEW(alloc, TTransitionFlagsProp)( + inEditorData.m_EditorFoundation, *inEditorData.m_StringTable, "type", + "external", "internal", &STransitionFlags::IsInternal, + &STransitionFlags::SetInternal)); + + accessor = QT3DS_NEW(alloc, TTransPathProp)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("path"), + EditorPropertyTypes::PositionList), + &STransition::m_Path); + retval.push_back(accessor); + retval.push_back(QT3DS_NEW(alloc, TVec2Access)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("position"), + EditorPropertyTypes::PositionList), + &STransition::GetPosition, &STransition::SetPosition)); + + retval.push_back(QT3DS_NEW(alloc, TVec2Access)( + inEditorData.m_EditorFoundation, + SPropertyDeclaration(inEditorData.RegisterStr("end position"), + EditorPropertyTypes::PositionList), + &STransition::GetEndPosition, &STransition::SetEndPosition)); + + return retval; + } + + STransitionEditor(STransition &inData, SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + : SEditorImplObject(GetTypeStr(), inEditorData, + CreateAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual void RemoveObjectFromGraph() { SStateEditor::RemoveObjectFromGraph(*this); } + + virtual TEditorStr GetId() { return m_Data.m_Id.c_str(); } + virtual void RemoveIdFromContext() { m_Editor.GetStateContext().EraseId(m_Data.m_Id); } + + virtual void AddIdToContext() + { + if (m_Data.m_Id.IsValid()) + m_Editor.GetStateContext().InsertId(m_Data.m_Id, &m_Data); + } + + virtual TObjPtr Parent() { return m_Editor.ToEditor(m_Data.m_Parent); } + + virtual NVConstDataRef GetExecutableContentTypes() + { + static InterpreterEventTypes::Enum data[] = { InterpreterEventTypes::Transition }; + return toConstDataRef(data, 1); + } + + virtual TObjList GetExecutableContent(InterpreterEventTypes::Enum inType) + { + TObjList retval; + if (inType == InterpreterEventTypes::Transition) { + for (TExecutableContentList::iterator iter = m_Data.m_ExecutableContent.begin(), + end = m_Data.m_ExecutableContent.end(); + iter != end; ++iter) { + retval.push_back(m_Editor.ExecutableContentToEditor(*iter)); + } + } + return retval; + } + virtual TObjPtr CreateAndAppendExecutableContent(InterpreterEventTypes::Enum inType, + const char8_t *inName) + { + TObjPtr retval; + if (inType == InterpreterEventTypes::Transition) { + retval = m_Editor.CreateExecutableContent(m_Data, inName); + SExecutableContent *theContent = m_Editor.ExecutableContentFromEditor(retval); + m_Data.m_ExecutableContent.push_back(*theContent); + if (m_Editor.GetOpenTransactionImpl()) { + NVScopedRefCounted newChange = + new SExecutableContentChange(*this, &m_Data.m_ExecutableContent, + theContent, true); + m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(newChange.mPtr); + } + } + return retval; + } + }; + + struct SExecutableContentParentInfo + { + SExecutableContent &content; + SEditorImpl &m_Editor; + TExecutableContentList *parentList; + TObjPtr editorObj; + TOnEntryList *entryList; + SOnEntry *entryItem; + TOnExitList *exitList; + SOnExit *exitItem; + SExecutableContentParentInfo(SExecutableContent &c, SEditorImpl &e) + : content(c) + , m_Editor(e) + , parentList(NULL) + , entryList(NULL) + , entryItem(NULL) + , exitList(NULL) + , exitItem(NULL) + { + if (GetContent().m_StateNodeParent) { + editorObj = m_Editor.ToEditor(*GetContent().m_StateNodeParent); + if (GetContent().m_StateNodeParent->m_Type == StateNodeTypes::Transition) + parentList = &static_cast(GetContent().m_StateNodeParent) + ->m_ExecutableContent; + else { + SExecutableContent *targetContent = &GetContent(); + entryList = GetContent().m_StateNodeParent->GetOnEntryList(); + exitList = GetContent().m_StateNodeParent->GetOnExitList(); + if (entryList) { + for (TOnEntryList::iterator iter = entryList->begin(), + end = entryList->end(); + iter != end && parentList == NULL; ++iter) { + for (TExecutableContentList::iterator + contentIter = iter->m_ExecutableContent.begin(), + contentEnd = iter->m_ExecutableContent.end(); + contentIter != contentEnd && parentList == NULL; + ++contentIter) { + if (&(*contentIter) == targetContent) { + parentList = &iter->m_ExecutableContent; + exitList = NULL; + entryItem = &(*iter); + } + } + } + } + if (parentList == NULL && exitList != NULL) { + for (TOnExitList::iterator iter = exitList->begin(), + end = exitList->end(); + iter != end && parentList == NULL; ++iter) { + for (TExecutableContentList::iterator + contentIter = iter->m_ExecutableContent.begin(), + contentEnd = iter->m_ExecutableContent.end(); + contentIter != contentEnd && parentList == NULL; + ++contentIter) { + if (&(*contentIter) == targetContent) { + parentList = &iter->m_ExecutableContent; + entryList = NULL; + exitItem = &(*iter); + } + } + } + } + } + } else { + editorObj = m_Editor.ToEditor(GetContent().m_Parent); + parentList = &GetContent().m_Parent->m_Children; + } + } + SExecutableContent &GetContent() { return content; } + }; + + struct SExecutableContentEditor : public SEditorImplObject + { + SExecutableContentEditor(const char8_t *inTypeStr, SEditorImpl &inEditorData, + const TPropertyAccessorList &inList) + : SEditorImplObject(inTypeStr, inEditorData, inList) + { + } + + virtual SExecutableContent &GetContent() = 0; + + virtual void RemoveObjectFromGraph() + { + SExecutableContentParentInfo parentInfo(GetContent(), m_Editor); + TExecutableContentList *parentList = parentInfo.parentList; + TObjPtr editorObj = parentInfo.editorObj; + TOnEntryList *entryList = parentInfo.entryList; + SOnEntry *entryItem = parentInfo.entryItem; + TOnExitList *exitList = parentInfo.exitList; + SOnExit *exitItem = parentInfo.exitItem; + + if (parentList) { + NVScopedRefCounted change = + new SExecutableContentChange(editorObj, parentList, &GetContent(), false); + change->Do(); + if (m_Editor.GetOpenTransactionImpl()) + m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(change.mPtr); + // Perhaps remove the item itself + if (parentList->empty()) { + NVScopedRefCounted newChange; + if (entryItem) + newChange = new TListInsertDeleteChange( + editorObj, entryList, entryItem, false); + else if (exitItem) + newChange = new TListInsertDeleteChange( + editorObj, exitList, exitItem, false); + + if (newChange) { + newChange->Do(); + if (m_Editor.GetOpenTransactionImpl()) + m_Editor.GetOpenTransactionImpl()->m_Changes.push_back(newChange); + } + } + } + } + }; + + struct SSendEditor : public SExecutableContentEditor + { + typedef SSend TStateType; + enum { EditorType = EditorTypes::Send }; + SSend &m_Data; + static const char8_t *GetTypeStr() { return "send"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + typedef SDataIdProp TIdPropType; + + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor(inData, &SSend::m_Event, "event", + EditorPropertyTypes::String)); + NVFoundationBase &fnd = inData.m_EditorFoundation->getFoundation(); + + retval.push_back(QT3DS_NEW(fnd.getAllocator(), TIdPropType)( + inData.m_EditorFoundation, + SPropertyDeclaration(inData.RegisterStr("id"), EditorPropertyTypes::Id), + &SSend::m_Id)); + + retval.push_back(QT3DS_NEW(fnd.getAllocator(), SDelayProp)( + inData.m_EditorFoundation, + SPropertyDeclaration(inData.RegisterStr("delay"), EditorPropertyTypes::U32))); + return retval; + } + SSendEditor(SSend &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SRaiseEditor : public SExecutableContentEditor + { + typedef SRaise TStateType; + enum { EditorType = EditorTypes::Raise }; + SRaise &m_Data; + static const char8_t *GetTypeStr() { return "raise"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor(inData, &SRaise::m_Event, "event", + EditorPropertyTypes::String)); + return retval; + } + SRaiseEditor(SRaise &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SLogEditor : public SExecutableContentEditor + { + typedef SLog TStateType; + enum { EditorType = EditorTypes::Log }; + SLog &m_Data; + static const char8_t *GetTypeStr() { return "log"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor(inData, &SLog::m_Label, "label", + EditorPropertyTypes::String)); + retval.push_back(CreateDataAccessor(inData, &SLog::m_Expression, "expr", + EditorPropertyTypes::String)); + return retval; + } + SLogEditor(SLog &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SAssignEditor : public SExecutableContentEditor + { + typedef SAssign TStateType; + enum { EditorType = EditorTypes::Assign }; + SAssign &m_Data; + static const char8_t *GetTypeStr() { return "assign"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor( + inData, &SAssign::m_Location, "location", EditorPropertyTypes::String)); + retval.push_back(CreateDataAccessor( + inData, &SAssign::m_Expression, "expr", EditorPropertyTypes::String)); + return retval; + } + SAssignEditor(SAssign &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SIfEditor : public SExecutableContentEditor + { + typedef SIf TStateType; + enum { EditorType = EditorTypes::If }; + SIf &m_Data; + static const char8_t *GetTypeStr() { return "if"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor(inData, &SIf::m_Cond, "cond", + EditorPropertyTypes::String)); + return retval; + } + + SIfEditor(SIf &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SElseIfEditor : public SExecutableContentEditor + { + typedef SElseIf TStateType; + enum { EditorType = EditorTypes::ElseIf }; + SElseIf &m_Data; + static const char8_t *GetTypeStr() { return "elseif"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor(inData, &SElseIf::m_Cond, "cond", + EditorPropertyTypes::String)); + return retval; + } + + SElseIfEditor(SElseIf &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SElseEditor : public SExecutableContentEditor + { + typedef SElse TStateType; + enum { EditorType = EditorTypes::Else }; + SElse &m_Data; + static const char8_t *GetTypeStr() { return "else"; } + + SElseEditor(SElse &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, inList) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SScriptEditor : public SExecutableContentEditor + { + typedef SScript TStateType; + enum { EditorType = EditorTypes::Script }; + SScript &m_Data; + static const char8_t *GetTypeStr() { return "script"; } + + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor( + inData, &SScript::m_Data, "content", EditorPropertyTypes::BigString)); + return retval; + } + + SScriptEditor(SScript &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SCancelEditor : public SExecutableContentEditor + { + typedef SData TStateType; + enum { EditorType = EditorTypes::Cancel }; + SCancel &m_Data; + static const char8_t *GetTypeStr() { return "cancel"; } + + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList retval; + retval.push_back(CreateDataAccessor( + inData, &SCancel::m_Send, "sendid", EditorPropertyTypes::Object)); + retval.push_back(CreateDataAccessor( + inData, &SCancel::m_IdExpression, "sendidexpr", EditorPropertyTypes::String)); + return retval; + } + + SCancelEditor(SCancel &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SExecutableContentEditor(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual SExecutableContent &GetContent() { return m_Data; } + virtual void *GetWrappedObject() { return &m_Data; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SDataModelEditor : public SEditorImplObject + { + typedef SDataModel TStateType; + enum { EditorType = EditorTypes::DataModel }; + SDataModel &m_Data; + static const char8_t *GetTypeStr() { return "datamodel"; } + + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList &retval(inList); + retval.push_back(CreateDataAccessor( + inData, &SDataModel::m_Data, "data", EditorPropertyTypes::ObjectList)); + return retval; + } + + SDataModelEditor(SDataModel &inData, SEditorImpl &inEditorData, + TPropertyAccessorList &inList) + : SEditorImplObject(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SDataEditor : public SEditorImplObject + { + typedef SData TStateType; + enum { EditorType = EditorTypes::Data }; + SData &m_Data; + static const char8_t *GetTypeStr() { return "data"; } + static TPropertyAccessorList GetPropertyAccessors(SEditorImpl &inData, + TPropertyAccessorList &inList) + { + if (inList.size()) + return inList; + TPropertyAccessorList retval; + retval.push_back(CreateDataAccessor(inData, &SData::m_Id, "id", + EditorPropertyTypes::String)); + retval.push_back(CreateDataAccessor( + inData, &SData::m_Expression, "expr", EditorPropertyTypes::String)); + return retval; + } + + SDataEditor(SData &inData, SEditorImpl &inEditorData, TPropertyAccessorList &inList) + : SEditorImplObject(GetTypeStr(), inEditorData, + GetPropertyAccessors(inEditorData, inList)) + , m_Data(inData) + { + } + + QT3DS_STATE_EDITOR_OBJECT_IMPLEMENT_ADDREF_RELEASE; + + virtual void *GetWrappedObject() { return &m_Data; } + + virtual CRegisteredString GetId() const { return m_Data.m_Id; } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + }; + + struct SNullEditor + { + int m_Data; + static const char8_t *GetTypeStr() { return ""; } + }; + + template + struct SStateEditorMap + { + typedef SNullEditor TEditorType; + template + static TObjPtr CreateEditor(TIgnored &, SEditorImpl &, TAccessorMap &) + { + return TObjPtr(); + } + }; + + template + struct SEditorImplStateMap + { + typedef int TStateType; + }; + + static inline TPropertyAccessorList &GetAccessorList(TAccessorMap &inMap, int inAccessor) + { + return inMap.insert(eastl::make_pair(inAccessor, TPropertyAccessorList())) + .first->second; + } + + template <> + struct SStateEditorMap + { + typedef STransition stateType; + typedef STransitionEditor TEditorType; + typedef STransitionEditor editorType; + static TObjPtr CreateEditor(stateType &inData, SEditorImpl &inEditorData, + TAccessorMap &inAccessors) + { + return QT3DS_NEW(inEditorData.m_EditorFoundation->getAllocator(), TEditorType)( + inData, inEditorData, + GetAccessorList(inAccessors, (int)editorType::EditorType)); + } + static TObjPtr CreateEditor(SEditorImpl &inEditorData, TAccessorMap &inAccessors) + { + STransition *newTransition = QT3DS_NEW(inEditorData.m_AutoAllocator, stateType)(); + newTransition->m_Flags.SetInternal(true); + return CreateEditor(*newTransition, inEditorData, inAccessors); + } + }; + template <> + struct SEditorImplStateMap + { + typedef STransition TStateType; + }; + +#define DEFINE_STATE_EDITOR_TYPE_MAP(stateType, editorType) \ + template <> \ + struct SStateEditorMap \ + { \ + typedef editorType TEditorType; \ + static TObjPtr CreateEditor(stateType &inData, SEditorImpl &inEditorData, \ + TAccessorMap &inAccessors) \ + { \ + return QT3DS_NEW(inEditorData.m_EditorFoundation->getAllocator(), TEditorType)( \ + inData, inEditorData, GetAccessorList(inAccessors, (int)editorType::EditorType)); \ + } \ + static TObjPtr CreateEditor(SEditorImpl &inEditorData, TAccessorMap &inAccessors) \ + { \ + return CreateEditor(*QT3DS_NEW(inEditorData.m_AutoAllocator, stateType)(), inEditorData, \ + inAccessors); \ + } \ + }; \ + template <> \ + struct SEditorImplStateMap \ + { \ + typedef stateType TStateType; \ + }; + + DEFINE_STATE_EDITOR_TYPE_MAP(SSCXML, SSCXMLEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SState, SStateEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SParallel, SParallelEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SHistory, SHistoryEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SFinal, SFinalEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SSend, SSendEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SRaise, SRaiseEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SLog, SLogEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SAssign, SAssignEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SIf, SIfEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SElseIf, SElseIfEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SElse, SElseEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SScript, SScriptEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SDataModel, SDataModelEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SData, SDataEditor); + DEFINE_STATE_EDITOR_TYPE_MAP(SCancel, SCancelEditor); + +#undef DEFINE_STATE_EDITOR_TYPE_MAP + } +} +} +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorFoundation.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorFoundation.h new file mode 100644 index 00000000..edb55ee3 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorFoundation.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_FOUNDATION_H +#define QT3DS_STATE_EDITOR_FOUNDATION_H +#pragma once + +#include "Qt3DSState.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "foundation/TrackingAllocator.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/IOStreams.h" + +namespace qt3ds { +namespace state { + namespace editor { + + struct SBaseEditorFoundation + { + static MallocAllocator g_BaseAlloc; + QT3DSI32 mRefCount; + CAllocator m_BaseAllocator; + NVScopedRefCounted m_Foundation; + SBaseEditorFoundation() + : mRefCount(0) + , m_BaseAllocator() + , m_Foundation(NVCreateFoundation(QT3DS_FOUNDATION_VERSION, m_BaseAllocator)) + { + } + + ~SBaseEditorFoundation() {} + + NVFoundationBase &getFoundation() { return *m_Foundation; } + NVAllocatorCallback &getAllocator() { return m_Foundation->getAllocator(); } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(g_BaseAlloc); + + static SBaseEditorFoundation &Create() + { + SBaseEditorFoundation *fndPtr = + (SBaseEditorFoundation *)malloc(sizeof(SBaseEditorFoundation)); + new (fndPtr) SBaseEditorFoundation(); + return *fndPtr; + } + }; + + typedef NVScopedRefCounted TFoundationPtr; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorImpl.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorImpl.h new file mode 100644 index 00000000..c1a691ee --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorImpl.h @@ -0,0 +1,406 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_IMPL_H +#define QT3DS_STATE_EDITOR_IMPL_H +#include "Qt3DSStateEditor.h" +#include "Qt3DSStateEditorValue.h" +#include "Qt3DSStateTypes.h" +#include "Qt3DSStateEditorFoundation.h" +#include "foundation/Utils.h" +#include "foundation/XML.h" +#include "Qt3DSStateXMLIO.h" +#include "foundation/IOStreams.h" +#include "Qt3DSStateExecutionTypes.h" +#include "Qt3DSStateContext.h" + +namespace qt3ds { +namespace state { + namespace editor { + + struct SEditorImpl; + + typedef nvhash_map TStateEditorMap; + + class IPropertyAccessor : public NVRefCounted + { + protected: + virtual ~IPropertyAccessor() {} + public: + SPropertyDeclaration m_Declaration; + IPropertyAccessor(const SPropertyDeclaration &inDec) + : m_Declaration(inDec) + { + } + virtual eastl::vector GetLegalValues(IEditorObject & /*inObj*/) + { + return eastl::vector(); + } + + virtual Option Get(IEditorObject &inObj) = 0; + virtual void Set(IEditorObject &inObj, const Option &inValue) = 0; + // Return true if this access handles the transaction code itself. + // Currently only used for the is initial target property. + virtual bool HandlesTransaction() { return false; } + }; + + typedef NVScopedRefCounted TPropertyAccessorPtr; + typedef eastl::vector TPropertyAccessorList; + typedef nvhash_map TAccessorMap; + +#define QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(foundationPtr, refcountVar) \ + void addRef() { atomicIncrement(&(refcountVar)); } \ + void release() \ + { \ + TFoundationPtr temp(foundationPtr); \ + QT3DSI32 value = atomicDecrement(&(refcountVar)); \ + if (value <= 0) \ + NVDelete(foundationPtr->getAllocator(), this); \ + } + + struct SEditorImplStrIOStream : public IOutStream + { + TEditorStr m_Str; + bool Write(NVConstDataRef data) + { + if (data.size()) + m_Str.append((const char8_t *)data.begin(), (const char8_t *)data.end()); + return true; + } + }; + + struct SEditorImplStrInStream : public IInStream + { + const char8_t *m_Pos; + const char8_t *m_End; + SEditorImplStrInStream(const TEditorStr &inStr) + : m_Pos(inStr.data()) + , m_End(inStr.data() + inStr.size()) + { + } + + virtual QT3DSU32 Read(NVDataRef data) + { + QT3DSU32 amountLeft = (QT3DSU32)(m_End - m_Pos); + QT3DSU32 amountToRead = NVMin(amountLeft, data.size()); + memCopy(data.mData, m_Pos, amountToRead); + m_Pos += amountToRead; + return amountToRead; + } + }; + + struct STransaction; + + typedef eastl::vector TChangeListenerList; + struct STransactionManagerImpl; + + class IEditorCopyPasteListener + { + protected: + virtual ~IEditorCopyPasteListener() {} + + public: + virtual void OnCopy(TEditorPtr inEditor, eastl::vector &ioCopiedRoots, + IDOMWriter &ioWriter, + eastl::vector &ioNamespaces) = 0; + virtual void OnPaste(TEditorPtr inEditor, IDOMReader &ioReader, + CXMLIO::TIdRemapMap &inStateIdRemapMap) = 0; + virtual void OnIDChange(TEditorPtr inEditor, SStateNode &inNode, + const char8_t *inOldId) = 0; + }; + + // Forward declaration of the editor interface that the properties and the editor objects + // can all use. Implementation in UICStateEditor.cpp + struct SEditorImpl : public IEditor + { + // Note that *we* keep references to our editors + // but our editor objects *cannot* keep a reference to us. + // This means that our editor objects need to be able to function (not crash) if we + // ourselves go out of scope. + TFoundationPtr m_EditorFoundation; + NVScopedRefCounted m_StringTable; + SSAutoDeallocatorAllocator m_AutoAllocator; + NVScopedRefCounted m_StateContext; + TStateEditorMap m_Editors; + volatile QT3DSI32 mRefCount; + NVScopedRefCounted m_TransactionManager; + TAccessorMap m_Accessors; + IEditorCopyPasteListener *m_CopyPasteListener; + + SEditorImpl(TFoundationPtr inFoundation, + NVScopedRefCounted inStringTable); + void addRef(); + void release(); + + TObjPtr InsertEditor(void *inData, IEditorObject *inEditor); + + template + TObjPtr ToEditor(TStateType &inItem); + + template + TObjPtr ToEditor(TStateType *inItem); + TObjPtr ToEditor(SStateNode &inItem); + TObjPtr ExecutableContentToEditor(SExecutableContent &inItem); + + template + TStateType *FromEditor(TObjPtr inPtr); + + SStateNode *StateNodeFromEditor(TObjPtr inPtr); + + SExecutableContent *ExecutableContentFromEditor(TObjPtr inPtr); + void GenerateUniqueId(SStateNode &inNode, const char8_t *inStem); + void GenerateUniqueId(SSend &inNode, const char8_t *inStem); + + virtual TObjPtr GetRoot(); + + template + eastl::pair CreateEditorAndObject(); + + TObjPtr DoCreate(const char8_t *inTypeName, const char8_t *inId); + + virtual TObjPtr Create(const char8_t *inTypeName, const char8_t *inId); + + virtual TObjPtr GetOrCreate(SSCXML &inData); + virtual TObjPtr GetOrCreate(SState &inData); + virtual TObjPtr GetOrCreate(STransition &inData); + virtual TObjPtr GetOrCreate(SParallel &inData); + virtual TObjPtr GetOrCreate(SFinal &inData); + virtual TObjPtr GetOrCreate(SHistory &inData); + virtual TObjPtr GetOrCreate(SDataModel &inData); + virtual TObjPtr GetOrCreate(SData &inData); + + virtual TObjPtr GetObjectById(const char8_t *inId); + + virtual TObjPtr GetEditor(void *inGraphData); + + virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener); + + void RemoveChangeListener(IEditorChangeListener &inListener); + + virtual TTransactionPtr BeginTransaction(const TEditorStr &inName); + + virtual TTransactionPtr GetOpenTransaction(); + + STransaction *GetOpenTransactionImpl(); + + virtual void RollbackTransaction(); + + virtual void EndTransaction(); + + virtual TEditorStr Copy(TObjList inObjects, const QT3DSVec2 &inMousePos); + + virtual bool CanPaste(TObjPtr inTarget); + + void AddNewPasteObjectToTransaction(SStateNode &inNode); + + virtual void Paste(const TEditorStr &inCopiedObjects, TObjPtr inTarget, + const QT3DSVec2 &inMousePos); + + static bool IsDerivedFrom(SStateNode &child, SStateNode &parent); + + // This method should always return a value because the scxml root item + // is the parent of everyone else. + static SStateNode &GetLeastCommonAncestor(SStateNode &lhs, SStateNode &rhs); + + TObjPtr GetLeastCommonAncestor(NVConstDataRef inObjects); + + TObjList GetCancelableSendIds(); + + TObjPtr ChangeExecutableContentType(TObjPtr inContent, const char8_t *newType); + + TEditorStr ToXML(TObjPtr inContent); + + eastl::pair FromXML(TObjPtr inContent, + const TEditorStr &ioEditedXML); + + // Return the set of events in use in the state machine. + TEditorStrList GetStateMachineEvents(); + + void ReleaseEditor(void *inData); + + virtual bool Save(const char8_t *inFileName); + virtual void Save(IOutStream &inStream); + + bool Load(IInStream &inStream, const char8_t *inFilename); + + ///////////////////////////////////////////////////////////////////// + // Property access helpers + ///////////////////////////////////////////////////////////////////// + void SetIdProperty(SStateNode &inNode, const SValue &inData, + CRegisteredString &inTarget); + void SetIdProperty(SSend &inNode, const SValue &inData, CRegisteredString &inTarget); + + void Set(const SValue &inData, CRegisteredString &inTarget) + { + TEditorStr theStr(inData.getData()); + inTarget = m_StringTable->RegisterStr(theStr.c_str()); + } + + void Set(const SValue &inData, const char8_t *&inTarget) + { + TEditorStr theStr(inData.getData()); + const char8_t *theData(theStr.c_str()); + + if (inTarget && *inTarget != 0) + m_AutoAllocator.deallocate(const_cast(inTarget)); + + size_t len = StrLen(theData); + if (len == 0) + inTarget = NULL; + + ++len; // account for null terminate + + char8_t *newTarget = (char8_t *)m_AutoAllocator.allocate(len + 1, "graph string", + __FILE__, __LINE__); + memCopy(newTarget, theData, len); + inTarget = newTarget; + } + SValue Get(CRegisteredString &inTarget) { return inTarget.c_str(); } + SValue Get(const char8_t *inItem) { return nonNull(inItem); } + + void Set(const Option &inData, NVConstDataRef &inTarget); + SValue Get(NVConstDataRef &inTarget); + + void Set(const Option &inData, STransition *&inTarget); + Option Get(STransition *&inTarget); + + void SetInitial(const TObjList &inList, STransition *&outInitialTransition); + SValue GetInitial(STransition *inInitialTransition); + + void SetInitialTarget(const Option &inData, SStateNode &inNode); + SValue IsInitialTarget(SStateNode &inNode); + + void Set(const Option &inData, SDataModel *&inTarget); + SValue Get(SDataModel *inTarget); + + void Set(const Option &inData, TDataList &inTarget); + SValue Get(TDataList &inTarget); + + void Set(const Option &inData, NVConstDataRef &inTarget); + SValue Get(const NVConstDataRef &inTarget); + + void Set(const Option &inData, SSend *&inTarget); + SValue Get(SSend *inTarget); + + void Set(const Option &inData, TEditorStr &inTarget) + { + inTarget.clear(); + if (inData.hasValue()) + inTarget = inData->getData(); + } + + SValue Get(const TEditorStr &inTarget) { return inTarget; } + + void Set(const Option &inData, Option &inTarget) + { + if (inData.hasValue()) { + inTarget = inData->getData(); + } else { + inTarget = Empty(); + } + } + Option Get(const Option &inTarget) + { + Option retval; + if (inTarget.hasValue()) + retval = SValue(inTarget.getValue()); + return retval; + } + + void Set(const Option &inData, TVec2List &inTarget) + { + if (inData.hasValue()) { + inTarget = inData->getData(); + } else { + inTarget.clear(); + } + } + SValue Get(const TVec2List &inTarget) { return inTarget; } + + void Set(const Option &inData, Option &inTarget) + { + if (inData.hasValue()) { + inTarget = inData->getData(); + } else { + inTarget = Empty(); + } + } + const Option Get(const Option &inTarget) + { + Option retval; + if (inTarget.hasValue()) + retval = SValue(inTarget.getValue()); + return retval; + } + + const char8_t *ToGraphStr(const char8_t *inStr) + { + if (isTrivial(inStr)) + return ""; + QT3DSU32 len = StrLen(inStr) + 1; + char8_t *retval = + (char8_t *)m_AutoAllocator.allocate(len, "GraphStr", __FILE__, __LINE__); + memCopy(retval, inStr, len); + return retval; + } + + SValue GetSendId(const char8_t *expression); + void SetSendId(const Option &inData, const char8_t *&outExpression); + + TObjPtr CreateExecutableContent(SStateNode &inParent, const char8_t *inTypeName); + eastl::pair + CreateExecutableContent(const char8_t *inTypeName); + + CRegisteredString RegisterStr(const char8_t *str) + { + return m_StringTable->RegisterStr(str); + } + IStateContext &GetStateContext(); + + TEditorStr GetDefaultInitialValue(SStateNode &inNode); + void GetLegalInitialValues(SStateNode &inNode, + eastl::vector &outValues); + void SetInitialAttribute(const Option &inData, SStateNode &inNode); + + void SetTransactionManager(STransactionManagerImpl &trans); + + void ReplaceExecutableContent(SExecutableContent &oldContent, + SExecutableContent &newContent); + + eastl::vector GetLegalHistoryDefaultValues(SHistory &inData); + + eastl::vector GetLegalParentIds(SStateNode &inNode); + void SetParent(SStateNode &inNode, const Option &inValue); + void CheckAndSetValidHistoryDefault(TObjPtr inHistoryNode); + void SetValidHistoryDefault(TObjPtr inHistoryNode); + }; + } +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorProperties.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorProperties.h new file mode 100644 index 00000000..5f06fbdb --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorProperties.h @@ -0,0 +1,599 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_PROPERTIES_H +#define QT3DS_STATE_EDITOR_PROPERTIES_H +#pragma once + +#include "Qt3DSStateEditorFoundation.h" +#include "Qt3DSStateEditorImpl.h" + +namespace qt3ds { +namespace state { + namespace editor { + + template + struct SPropertyAccessorBase : public IPropertyAccessor + { + TFoundationPtr m_Allocator; + volatile QT3DSI32 mRefCount; + + SPropertyAccessorBase(TFoundationPtr alloc, const SPropertyDeclaration &inDec) + : IPropertyAccessor(inDec) + , m_Allocator(alloc) + , mRefCount(0) + { + } + + virtual Option Get(IEditorObject &inObj) + { + return DoGet(static_cast(inObj)); + } + virtual void Set(IEditorObject &inObj, const Option &inValue) + { + DoSet(static_cast(inObj), inValue); + } + + virtual Option DoGet(TEditorType &inObj) = 0; + virtual void DoSet(TEditorType &inObj, const Option &inValue) = 0; + }; + + template + struct SInitialProperty : SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + static SPropertyDeclaration CreatePropertyDeclaration(IStringTable &inStrTable) + { + SPropertyDeclaration theDeclaration; + theDeclaration.m_Name = inStrTable.RegisterStr("initial"); + theDeclaration.m_Type = EditorPropertyTypes::Object; + return theDeclaration; + } + SInitialProperty(TFoundationPtr inAlloc, IStringTable &inStrTable) + : TBaseType(inAlloc, CreatePropertyDeclaration(inStrTable)) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + return SValue(inObj.Get(inObj.m_Data.m_Initial)); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.m_Initial = + inObj.template FromEditor(inValue->getData()); + } + }; + + template + struct SFlagBooleanProperty : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + typedef bool (TFlagsType::*TGetPropPtr)() const; + typedef void (TFlagsType::*TSetPropPtr)(bool); + + TGetPropPtr m_GetProp; + TSetPropPtr m_SetProp; + eastl::vector m_LegalValues; + virtual eastl::vector GetLegalValues(IEditorObject & /*inObj*/) + { + return m_LegalValues; + } + + static SPropertyDeclaration CreatePropertyDeclaration(IStringTable &inStrTable, + const char8_t *propName) + { + SPropertyDeclaration theDeclaration; + theDeclaration.m_Name = inStrTable.RegisterStr(propName); + theDeclaration.m_Type = EditorPropertyTypes::StringSet; + return theDeclaration; + } + SFlagBooleanProperty(TFoundationPtr inFnd, IStringTable &inStrTable, + const char8_t *inPropName, const char8_t *falseName, + const char8_t *trueName, TGetPropPtr inGetProp, + TSetPropPtr inSetProp) + : TBaseType(inFnd, CreatePropertyDeclaration(inStrTable, inPropName)) + , m_GetProp(inGetProp) + , m_SetProp(inSetProp) + { + m_LegalValues.push_back(inStrTable.RegisterStr(falseName)); + m_LegalValues.push_back(inStrTable.RegisterStr(trueName)); + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + bool boolVal = (inObj.m_Data.m_Flags.*m_GetProp)(); + TEditorStr retval = boolVal ? TEditorStr(m_LegalValues[1].c_str()) + : TEditorStr(m_LegalValues[0].c_str()); + return SValue(retval); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValueOpt) + { + if (inValueOpt.hasValue()) { + TEditorStr data = inValueOpt->getData(); + + if (AreEqual(data.c_str(), m_LegalValues[1].c_str())) + (inObj.m_Data.m_Flags.*m_SetProp)(true); + + else if (AreEqual(data.c_str(), m_LegalValues[0].c_str())) + (inObj.m_Data.m_Flags.*m_SetProp)(false); + + else { + QT3DS_ASSERT(false); + } + } + } + }; + + template + struct SChildrenProperty : SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + static SPropertyDeclaration CreatePropertyDeclaration(IStringTable &inStrTable) + { + SPropertyDeclaration theDeclaration; + theDeclaration.m_Name = inStrTable.RegisterStr("children"); + theDeclaration.m_Type = EditorPropertyTypes::ObjectList; + return theDeclaration; + } + + SChildrenProperty(TFoundationPtr inAlloc, IStringTable &inStrTable) + : TBaseType(inAlloc, CreatePropertyDeclaration(inStrTable)) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + TObjList retval; + for (TStateNodeList::iterator iter = inObj.m_Data.m_Children.begin(), + end = inObj.m_Data.m_Children.end(); + iter != end; ++iter) + retval.push_back(inObj.m_Editor.ToEditor(*iter)); + return SValue(retval); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + if (inValue.hasValue()) { + const TObjList &data = inValue->getData(); + TStateNodeList &theChildren(inObj.m_Data.m_Children); + // De-set all children. + while (theChildren.empty() == false) + inObj.m_Data.RemoveChild(theChildren.front()); + + for (TObjList::const_iterator iter = data.begin(), end = data.end(); + iter != end; ++iter) { + SStateNode *theNode = inObj.m_Editor.StateNodeFromEditor(*iter); + if (theNode) + inObj.m_Data.AppendChild(*theNode); + else { + QT3DS_ASSERT(false); + } + } + } + } + }; + + // Property that is represented by a data item's member. + template + struct SDataProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + typedef TDataType TStateType::*TPropertyPtr; + TPropertyPtr m_Ptr; + eastl::vector m_LegalValues; + + SDataProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, TPropertyPtr inPtr) + : TBaseType(inAlloc, inDec) + , m_Ptr(inPtr) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual eastl::vector GetLegalValues(IEditorObject & /*inObj*/) + { + return m_LegalValues; + } + + virtual Option DoGet(TEditorType &inObj) + { + return inObj.m_Editor.Get(inObj.m_Data.*(this->m_Ptr)); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.m_Editor.Set(inValue, inObj.m_Data.*(this->m_Ptr)); + } + }; + + template + struct SInitialTargetProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + + SInitialTargetProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) + : TBaseType(inAlloc, inDec) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + return inObj.m_Editor.IsInitialTarget(inObj.m_Data); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.m_Editor.SetInitialTarget(inValue, inObj.m_Data); + } + + virtual bool HandlesTransaction() { return true; } + }; + + template + struct SInitialComboProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + + SInitialComboProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) + : TBaseType(inAlloc, inDec) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual eastl::vector GetLegalValues(IEditorObject &inEditor) + { + eastl::vector retval; + TEditorType &theEditor = static_cast(inEditor); + retval.push_back(theEditor.m_Editor.RegisterStr("(script expression)")); + theEditor.m_Editor.GetLegalInitialValues(theEditor.m_Data, retval); + return retval; + } + + virtual Option DoGet(TEditorType &inObj) + { + TEditorType &theEditor = inObj; + if (theEditor.m_InitialComboValue.size() == 0) { + if (!isTrivial(inObj.m_Data.GetInitialExpression())) + theEditor.m_InitialComboValue = "(script expression)"; + else if (inObj.m_Data.GetInitialTransition() + && inObj.m_Data.GetInitialTransition()->m_Target.size()) + theEditor.m_InitialComboValue.assign( + inObj.m_Data.GetInitialTransition()->m_Target[0]->m_Id.c_str()); + else + theEditor.m_InitialComboValue = + theEditor.m_Editor.GetDefaultInitialValue(theEditor.m_Data); + } + return theEditor.m_InitialComboValue; + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + if (inValue->getData() != "(script expression)") { + inObj.m_Editor.SetInitialAttribute(inValue, inObj.m_Data); + } else { + inObj.m_Editor.SetInitialAttribute(Option(), inObj.m_Data); + } + } + virtual bool HandlesTransaction() { return true; } + }; + + template + struct SOptionAccessorProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + typedef Option TOptType; + typedef TOptType (TStateType::*TGetPtr)() const; + typedef void (TStateType::*TSetPtr)(const TOptType &inOpt); + TGetPtr m_Getter; + TSetPtr m_Setter; + + SOptionAccessorProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, + TGetPtr inPtr, TSetPtr inSetPtr) + : TBaseType(inAlloc, inDec) + , m_Getter(inPtr) + , m_Setter(inSetPtr) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + TOptType theOpt = (inObj.m_Data.*m_Getter)(); + if (theOpt.hasValue()) + return SValue(*theOpt); + return Empty(); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + TOptType theNewValue; + if (inValue.hasValue()) + theNewValue = TOptType(inValue->getData()); + (inObj.m_Data.*m_Setter)(theNewValue); + } + }; + + template + struct SDataIdProp : SDataProp + { + typedef SDataProp TBaseType; + typedef CRegisteredString TStateType::*TPropertyPtr; + + SDataIdProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, + TPropertyPtr inPtr) + : TBaseType(inAlloc, inDec, inPtr) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + // This may mangle the id in order to find a unique id. + inObj.m_Editor.SetIdProperty(inObj.m_Data, inValue, inObj.m_Data.*(this->m_Ptr)); + } + }; + + template + IPropertyAccessor *CreateDataAccessor(SEditorImpl &inData, TDataType TStateType::*inDataPtr, + const char8_t *inName, + EditorPropertyTypes::Enum inPropType) + { + typedef SDataProp TPropType; + return QT3DS_NEW(inData.m_EditorFoundation->getAllocator(), TPropType)( + inData.m_EditorFoundation, + SPropertyDeclaration(inData.RegisterStr(inName), inPropType), inDataPtr); + } + + template + struct SEditorImplProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + typedef TDataType TEditorType::*TPropertyPtr; + TPropertyPtr m_Ptr; + + SEditorImplProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, + TPropertyPtr inPtr) + : TBaseType(inAlloc, inDec) + , m_Ptr(inPtr) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + return inObj.m_Editor.Get(inObj.*(this->m_Ptr)); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.m_Editor.Set(inValue, inObj.*(this->m_Ptr)); + } + }; + + template + IPropertyAccessor * + CreateEditorAccessor(SEditorImpl &inData, TDataType TEditorObject::*inDataPtr, + const char8_t *inName, EditorPropertyTypes::Enum inPropType) + { + typedef SEditorImplProp TPropType; + return QT3DS_NEW(inData.m_EditorFoundation->getAllocator(), TPropType)( + inData.m_EditorFoundation, + SPropertyDeclaration(inData.RegisterStr(inName), inPropType), inDataPtr); + } + + // General property for initial and history transition properties + template + struct SSCXMLInitialPtr : public SPropertyAccessorBase + { + typedef STransition *TStateType::*TPropertyType; + typedef SPropertyAccessorBase TBaseType; + TPropertyType m_PropPtr; + + SSCXMLInitialPtr(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, + TPropertyType inPropPtr) + : TBaseType(inAlloc, inDec) + , m_PropPtr(inPropPtr) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + return inObj.GetInitial(inObj.m_Data.*m_PropPtr); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.SetInitial(inValue->getData(), inObj.m_Data.*m_PropPtr); + } + }; + + template + struct SSCXMLInitialContent : public SPropertyAccessorBase + { + typedef STransition *TStateType::*TPropertyType; + typedef SPropertyAccessorBase TBaseType; + TPropertyType m_PropPtr; + + SSCXMLInitialContent(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, + TPropertyType inPropPtr) + : TBaseType(inAlloc, inDec) + , m_PropPtr(inPropPtr) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + return inObj.GetInitialContent(inObj.m_Data.*m_PropPtr); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + if (inValue.hasValue()) { + inObj.SetInitialContent(inValue->getData(), inObj.m_Data.*m_PropPtr); + } else { + inObj.SetInitialContent(TObjList(), inObj.m_Data.*m_PropPtr); + } + } + }; + + template + struct SDelayProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + + SDelayProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) + : TBaseType(inAlloc, inDec) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + if (!isTrivial(inObj.m_Data.m_DelayExpr)) + return Empty(); + + return inObj.m_Editor.GetSendId(inObj.m_Data.m_Delay); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.m_Data.m_DelayExpr = ""; + inObj.m_Editor.SetSendId(inValue, inObj.m_Data.m_Delay); + } + }; + + template + struct SHistoryTransitionProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + + SHistoryTransitionProp(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec) + : TBaseType(inAlloc, inDec) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual eastl::vector GetLegalValues(IEditorObject &inEditor) + { + TEditorType &theEditor = static_cast(inEditor); + return theEditor.m_Editor.GetLegalHistoryDefaultValues(theEditor.m_Data); + } + + virtual Option DoGet(TEditorType &inObj) + { + if (inObj.m_Data.m_Transition) + return inObj.m_Editor.Get(inObj.m_Data.m_Transition->m_Target); + + return SValue(TObjList()); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + TObjList newObjects; + + if (inValue.hasValue()) + newObjects = inValue->getData(); + + if (newObjects.size()) { + if (!inObj.m_Data.m_Transition) { + inObj.m_Data.m_Transition = + (STransition *)inObj.m_Editor.m_AutoAllocator.allocate( + sizeof(STransition), "transition", __FILE__, __LINE__); + new (inObj.m_Data.m_Transition) STransition(); + inObj.m_Data.m_Transition->m_Parent = &inObj.m_Data; + } + inObj.m_Editor.Set(inValue, inObj.m_Data.m_Transition->m_Target); + } else + inObj.m_Data.m_Transition = NULL; + } + }; + + template + struct SParentProp : public SPropertyAccessorBase + { + typedef SPropertyAccessorBase TBaseType; + + SParentProp(TFoundationPtr inAlloc, IStringTable &inStrTable) + : TBaseType(inAlloc, SPropertyDeclaration(inStrTable.RegisterStr("parent"), + EditorPropertyTypes::StringSet)) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + static const char *SCXMLParentName() { return "(none)"; } + + virtual Option DoGet(TEditorType &inObj) + { + TObjPtr current = inObj.Parent(); + if (current && AreEqual(current->TypeName(), "scxml") == false) + return SValue(current->GetId()); + return Option(SValue(eastl::string(SCXMLParentName()))); + } + + virtual eastl::vector GetLegalValues(IEditorObject &inEditor) + { + TEditorType &theEditor = static_cast(inEditor); + eastl::vector retval = + theEditor.m_Editor.GetLegalParentIds(theEditor.m_Data); + CRegisteredString parentName(theEditor.m_Editor.RegisterStr(SCXMLParentName())); + retval.insert(retval.begin(), parentName); + return retval; + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + inObj.m_Editor.SetParent(inObj.m_Data, inValue); + } + + virtual bool HandlesTransaction() { return true; } + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.cpp b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.cpp new file mode 100644 index 00000000..1bc0faf7 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateEditorTransactionImpl.h" + +namespace qt3ds { +namespace state { + namespace editor { + + // Some things have to be implemented below so that we can take advantage of the full + // SEditorImpl definition. + + STransaction::STransaction(TFoundationPtr alloc, STransactionManagerImpl &inEditor, + const TEditorStr &inName) + : ITransaction(inName) + , m_Alloc(alloc) + , mRefCount(0) + , m_Editor(inEditor) + { + } + + STransaction::~STransaction() {} + + void STransaction::addRef() { atomicIncrement(&mRefCount); } + + void STransaction::release() + { + atomicDecrement(&mRefCount); + if (mRefCount <= 0) { + TFoundationPtr fnd(m_Alloc); + NVDelete(fnd->getAllocator(), this); + } + } + + void STransaction::ChangesToEditors() + { + m_EditorsList.clear(); + m_EditorsList.resize(m_Changes.size()); + eastl::transform(m_Changes.begin(), m_Changes.end(), m_EditorsList.begin(), + SChangeToEditor()); + } + + void STransaction::SendDoSignals() + { + ChangesToEditors(); + CreateRemovedEditorsList(true); + for (TChangeListenerList::iterator listenerIter = m_Editor->m_ChangeListeners.begin(), + listenerEnd = m_Editor->m_ChangeListeners.end(); + listenerIter != listenerEnd; ++listenerIter) + (*listenerIter)->OnDataChange(m_EditorsList, m_RemovedEditorsList); + } + + void STransaction::Do() + { + for (TChangeList::iterator iter = m_Changes.begin(), end = m_Changes.end(); iter != end; + ++iter) + (*iter)->Do(); + + for (TRemovePairList::iterator iter = m_RemovedPairs.begin(), + end = m_RemovedPairs.end(); + iter != end; ++iter) { + if (iter->first) + iter->second->RemoveIdFromContext(); + else + iter->second->AddIdToContext(); + } + + SendDoSignals(); + } + + void STransaction::SilentUndo() + { + for (TChangeList::reverse_iterator iter = m_Changes.rbegin(), end = m_Changes.rend(); + iter != end; ++iter) + (*iter)->Undo(); + + for (TRemovePairList::iterator iter = m_RemovedPairs.begin(), + end = m_RemovedPairs.end(); + iter != end; ++iter) { + if (iter->first) + iter->second->AddIdToContext(); + else + iter->second->RemoveIdFromContext(); + } + } + + void STransaction::Undo() + { + SilentUndo(); + m_EditorsList.clear(); + m_EditorsList.resize(m_Changes.size()); + eastl::transform(m_Changes.rbegin(), m_Changes.rend(), m_EditorsList.begin(), + SChangeToEditor()); + CreateRemovedEditorsList(false); + for (TChangeListenerList::iterator listenerIter = m_Editor->m_ChangeListeners.begin(), + listenerEnd = m_Editor->m_ChangeListeners.end(); + listenerIter != listenerEnd; ++listenerIter) + (*listenerIter)->OnDataChange(m_EditorsList, m_RemovedEditorsList); + } + + struct STransactionImplConnection : public IStateSignalConnection + { + TFoundationPtr &m_Alloc; + QT3DSI32 mRefCount; + STransactionManagerImpl &m_Editor; + IEditorChangeListener &m_ChangeListener; + STransactionImplConnection(TFoundationPtr &alloc, STransactionManagerImpl &e, + IEditorChangeListener &listener) + : m_Alloc(alloc) + , mRefCount(0) + , m_Editor(e) + , m_ChangeListener(listener) + { + } + // Implemented below editor to use editor's interfaces + virtual ~STransactionImplConnection() + { + m_Editor.RemoveChangeListener(m_ChangeListener); + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Alloc, mRefCount); + }; + + void STransactionManagerImpl::addRef() { atomicIncrement(&mRefCount); } + void STransactionManagerImpl::release() + { + atomicDecrement(&mRefCount); + if (mRefCount <= 0) { + TFoundationPtr fnd(m_EditorFoundation); + NVDelete(fnd->getAllocator(), this); + } + } + + TSignalConnectionPtr + STransactionManagerImpl::AddChangeListener(IEditorChangeListener &inListener) + { + m_ChangeListeners.push_back(&inListener); + // If we have any listeners, then we can't be destroyed as their connections will still + // need + // to talk to us to release its stuff. + if (m_ChangeListeners.size() == 1) + addRef(); + return QT3DS_NEW(m_EditorFoundation->getAllocator(), + STransactionImplConnection)(m_EditorFoundation, *this, inListener); + } + + void STransactionManagerImpl::RemoveChangeListener(IEditorChangeListener &inListener) + { + TChangeListenerList::iterator iter = + eastl::find(m_ChangeListeners.begin(), m_ChangeListeners.end(), &inListener); + if (iter != m_ChangeListeners.end()) + m_ChangeListeners.erase(iter); + if (m_ChangeListeners.size() == 0) + release(); + } + TTransactionPtr STransactionManagerImpl::BeginTransaction(const TEditorStr &inName) + { + if (!m_Transaction) { + QT3DS_ASSERT(m_OpenCount == 0); + m_Transaction = QT3DS_NEW(m_EditorFoundation->getAllocator(), + STransaction)(m_EditorFoundation, *this, inName); + } + ++m_OpenCount; + return m_Transaction.mPtr; + } + + TTransactionPtr STransactionManagerImpl::GetOpenTransaction() { return m_Transaction.mPtr; } + STransaction *STransactionManagerImpl::GetOpenTransactionImpl() + { + return m_Transaction.mPtr; + } + + void STransactionManagerImpl::RollbackTransaction() + { + --m_OpenCount; + if (m_OpenCount <= 0) { + if (m_Transaction) { + m_Transaction->Undo(); + m_Transaction = NULL; + } + } + QT3DS_ASSERT(m_OpenCount == 0); + m_OpenCount = 0; + } + + void STransactionManagerImpl::EndTransaction() + { + TTransactionPtr retval = m_Transaction.mPtr; + --m_OpenCount; + if (m_OpenCount <= 0) + m_Transaction = NULL; + QT3DS_ASSERT(m_OpenCount >= 0); + m_OpenCount = 0; + } + + void STransactionManagerImpl::OnObjectDeleted(TObjPtr inObj) + { + if (m_Transaction) + m_Transaction->m_RemovedPairs.push_back(eastl::make_pair(true, inObj)); + + if (m_ObjListener) + m_ObjListener->OnObjectDeleted(inObj); + } + void STransactionManagerImpl::OnObjectCreated(TObjPtr inObj) + { + if (m_Transaction) + m_Transaction->m_RemovedPairs.push_back(eastl::make_pair(false, inObj)); + + if (m_ObjListener) + m_ObjListener->OnObjectCreated(inObj); + } + } +} +} \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.h new file mode 100644 index 00000000..9996c351 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransactionImpl.h @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_TRANSACTION_IMPL_H +#define QT3DS_STATE_EDITOR_TRANSACTION_IMPL_H +#include "Qt3DSStateEditor.h" +#include "Qt3DSStateEditorFoundation.h" +#include "Qt3DSStateEditorProperties.h" + +namespace qt3ds { +namespace state { + namespace editor { + + class IChange : public NVRefCounted + { + protected: + virtual ~IChange() {} + public: + virtual void Do() = 0; + virtual void Undo() = 0; + virtual TObjPtr GetEditor() = 0; + }; + + typedef eastl::vector> TChangeList; + + struct SChange : public IChange + { + Option m_OldVal; + Option m_NewVal; + TPropertyAccessorPtr m_Accessor; + TObjPtr m_Editor; + QT3DSI32 mRefCount; + + SChange(const Option &inOldVal, const Option &inNewVal, + IPropertyAccessor &inAccessor, IEditorObject &inEditor) + : m_OldVal(inOldVal) + , m_NewVal(inNewVal) + , m_Accessor(inAccessor) + , m_Editor(inEditor) + , mRefCount(0) + { + } + // Sometimes we need to create a change just to signal a new object. + // In this case there isn't an accessor and there aren't old values and + // new values. + SChange(IEditorObject &inEditor) + : m_Editor(inEditor) + , mRefCount(0) + { + } + SChange() + : mRefCount(0) + { + } + void Do() + { + if (m_Accessor) + m_Accessor->Set(*m_Editor, m_NewVal); + } + + void Undo() + { + if (m_Accessor) + m_Accessor->Set(*m_Editor, m_OldVal); + } + void addRef() { atomicIncrement(&mRefCount); } + void release() + { + atomicDecrement(&mRefCount); + if (mRefCount <= 0) + delete this; + } + + TObjPtr GetEditor() { return m_Editor; } + }; + + // true if removed on do, false if removed on false; + typedef eastl::pair TRemovePair; + typedef eastl::vector TRemovePairList; + + struct STransactionManagerImpl; + + struct STransaction : public ITransaction + { + TFoundationPtr m_Alloc; + TChangeList m_Changes; + volatile QT3DSI32 mRefCount; + // We have to keep a refcount to the editor ourselves. + NVScopedRefCounted m_Editor; + TObjList m_EditorsList; + TObjList m_RemovedEditorsList; + TRemovePairList m_RemovedPairs; + + STransaction(TFoundationPtr alloc, STransactionManagerImpl &inEditor, + const TEditorStr &inName); + virtual ~STransaction(); + virtual void addRef(); + virtual void release(); + + void CreateRemovedEditorsList(bool inDo) + { + m_RemovedEditorsList.clear(); + for (TRemovePairList::iterator iter = m_RemovedPairs.begin(), + end = m_RemovedPairs.end(); + iter != end; ++iter) + if (iter->first == inDo) + m_RemovedEditorsList.push_back(iter->second); + } + + struct SChangeToEditor + { + TObjPtr operator()(IChange *inChange) const { return inChange->GetEditor(); } + }; + virtual void SendDoSignals(); + virtual void Do(); + virtual void SilentUndo(); + virtual void Undo(); + virtual bool Empty() { return m_Changes.empty() && m_RemovedPairs.empty(); } + virtual TObjList GetEditedObjects() + { + ChangesToEditors(); + return m_EditorsList; + } + void ChangesToEditors(); + }; + + class ITransManagerImplListener + { + protected: + virtual ~ITransManagerImplListener() {} + public: + virtual void OnObjectDeleted(TObjPtr inObj) = 0; + virtual void OnObjectCreated(TObjPtr inObj) = 0; + }; + + struct STransactionManagerImpl : public ITransactionManager + { + TFoundationPtr m_EditorFoundation; + volatile QT3DSI32 mRefCount; + TChangeListenerList m_ChangeListeners; + NVScopedRefCounted m_Transaction; + QT3DSI32 m_OpenCount; + ITransManagerImplListener *m_ObjListener; + + STransactionManagerImpl(TFoundationPtr fnd) + : m_EditorFoundation(fnd) + , mRefCount(0) + , m_OpenCount(0) + , m_ObjListener(NULL) + { + } + virtual void addRef(); + virtual void release(); + virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener); + virtual TTransactionPtr BeginTransaction(const TEditorStr &inName = TEditorStr()); + virtual TTransactionPtr GetOpenTransaction(); + STransaction *GetOpenTransactionImpl(); + virtual void RollbackTransaction(); + virtual void EndTransaction(); + + void OnObjectDeleted(TObjPtr inObj); + void OnObjectCreated(TObjPtr inObj); + + void RemoveChangeListener(IEditorChangeListener &inListener); + }; + } +} +} +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.cpp b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.cpp new file mode 100644 index 00000000..7fb4ab9f --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.cpp @@ -0,0 +1,813 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSStateEditorTransitionPath.h" + +namespace { + +using namespace qt3ds::state::editor; +using namespace qt3ds::state; + +bool inBounds(QT3DSF32 item, QT3DSF32 lower, QT3DSF32 upper) +{ + if (item >= lower && item <= upper) + return true; + return false; +} + +DirectionTypes::Enum EdgeTypeToDirectionType(EdgeTypes::Enum inEdgeType) +{ + switch (inEdgeType) { + case EdgeTypes::Bottom: + case EdgeTypes::Top: + return DirectionTypes::Vertical; + default: + return DirectionTypes::Horizontal; + } +} + +static inline SEndPoint DoGetActualEndPoint(const SEndPoint &inPoint, const SRect &inMyRect, + const QT3DSVec2 &inOtherCenter) +{ + SEndPoint theEndPoint = inPoint; + if (inPoint.m_EdgeType == EdgeTypes::UnsetEdgeType) + theEndPoint = CEditorTransitionPath::CalculateDefaultEndPoint(inMyRect, inOtherCenter); + return theEndPoint; +} + +static inline eastl::pair +GetEndpointPoint(const SEndPoint &inPoint, const SRect &inMyRect, const QT3DSVec2 &inOtherCenter) +{ + SEndPoint theEndPoint = DoGetActualEndPoint(inPoint, inMyRect, inOtherCenter); + SLine theRectLine; + switch (theEndPoint.m_EdgeType) { + case EdgeTypes::Top: + theRectLine = inMyRect.topEdge(); + break; + case EdgeTypes::Bottom: + theRectLine = inMyRect.bottomEdge(); + break; + case EdgeTypes::Left: + theRectLine = inMyRect.leftEdge(); + break; + default: + QT3DS_ASSERT(false); + // fallthrough intentional + case EdgeTypes::Right: + theRectLine = inMyRect.rightEdge(); + break; + } + + return eastl::make_pair(theRectLine.toPoint(theEndPoint.m_Interp), theEndPoint.m_EdgeType); +} + +inline bool RectDiffers(const Option &inLhs, const SRect &inRhs) +{ + if (inLhs.isEmpty()) + return true; + SRect lhs = *inLhs; + return CEditorTransitionPath::AreAlmostEqual(lhs.m_TopLeft, inRhs.m_TopLeft) == false + || CEditorTransitionPath::AreAlmostEqual(lhs.m_WidthHeight, inRhs.m_WidthHeight) == false; +} +} + +namespace qt3ds { +namespace state { + namespace editor { + + bool SRect::contains(const QT3DSVec2 &inPoint) const + { + if (inPoint.x >= left() && inPoint.x <= right() && inPoint.y >= top() + && inPoint.y <= bottom()) + return true; + return false; + } + + void CEditorTransitionPath::SetPathType(TransitionPathTypes::Enum inType) + { + m_TransitionPathType = inType; + if (m_TransitionPathType == TransitionPathTypes::BeginToBegin + || m_TransitionPathType == TransitionPathTypes::Targetless) + m_ControlPoints.clear(); + MarkDirty(); + } + + bool CEditorTransitionPath::UpdateBeginEndRects(const SRect &inStartRect, + const SRect &inEndRect) + { + bool dataChanged = false; + + if (m_BeginRect.hasValue() && m_EndRect.hasValue()) { + QT3DSVec2 beginDiff = inStartRect.center() - m_BeginRect->center(); + QT3DSVec2 endDiff = inEndRect.center() - m_EndRect->center(); + + if (AreAlmostEqual(beginDiff, QT3DSVec2(0, 0)) == false + && AreAlmostEqual(beginDiff, endDiff, 1)) { + dataChanged = m_ControlPoints.empty() == false; + // Move all the control points. + for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) { + SControlPoint &thePoint(m_ControlPoints[idx]); + QT3DSF32 diffComponent = + SControlPoint::GetComponent(beginDiff, thePoint.m_Direction); + thePoint.m_Position += diffComponent; + } + } + } + bool rectDiffers = + RectDiffers(m_BeginRect, inStartRect) || RectDiffers(m_EndRect, inEndRect); + m_BeginRect = inStartRect; + m_EndRect = inEndRect; + if (rectDiffers) + MarkDirty(); + m_TransitionPathType = TransitionPathTypes::BeginToEnd; + return dataChanged; + } + + bool CEditorTransitionPath::UpdateBeginEndRects(const SRect &inStartRect, + TransitionPathTypes::Enum inPathType) + { + bool dataChanged = m_ControlPoints.empty() == false; + QT3DS_ASSERT(inPathType == TransitionPathTypes::BeginToBegin + || inPathType == TransitionPathTypes::Targetless); + bool rectDiffers = m_EndRect.hasValue() || RectDiffers(m_BeginRect, inStartRect); + m_BeginRect = inStartRect; + m_EndRect = Empty(); + if (rectDiffers || dataChanged) + MarkDirty(); + m_TransitionPathType = inPathType; + return dataChanged; + } + + eastl::pair CEditorTransitionPath::GetBeginPointAndEdge() const + { + eastl::pair theStartPoint(QT3DSVec2(0, 0), + EdgeTypes::UnsetEdgeType); + if (m_BeginRect.hasValue()) { + QT3DSVec2 center(m_BeginRect->center()); + center.x += 1; + if (m_EndRect.hasValue()) + center = m_EndRect->center(); + theStartPoint = GetEndpointPoint(m_Begin, *m_BeginRect, center); + } + return theStartPoint; + } + + eastl::pair CEditorTransitionPath::GetBeginEndPoints() const + { + eastl::pair theStartPoint(GetBeginPointAndEdge()); + eastl::pair theEndPoint(QT3DSVec2(0, 0), + EdgeTypes::UnsetEdgeType); + if (m_EndRect.hasValue()) + theEndPoint = GetEndpointPoint(m_End, *m_EndRect, m_BeginRect->center()); + + return eastl::make_pair(theStartPoint.first, theEndPoint.first); + } + + SEndPoint CEditorTransitionPath::CalculateEndPoint(const SRect &inRect, + const QT3DSVec2 &inPoint, + QT3DSF32 inEdgeBoundary) + { + if (inRect.width() == 0 || inRect.height() == 0) { + QT3DS_ASSERT(false); + return SEndPoint(); + } + + SLine centerToPoint = SLine(inRect.center(), inPoint); + SLine leftOrRight; + SLine topOrBottom; + Option isect; + EdgeTypes::Enum theEdge = EdgeTypes::UnsetEdgeType; + // If line runs right, test against right edge + QT3DSF32 distance = 0; + SLine theRectLine; + if (centerToPoint.dx() > 0) { + theRectLine = inRect.rightEdge(); + isect = theRectLine.intersect(centerToPoint); + // If we are out of range for the right edge + if (isect.hasValue() && inBounds(*isect, 0.0f, 1.0f)) { + distance = theRectLine.dy(); + theEdge = EdgeTypes::Right; + } + } else { + theRectLine = inRect.leftEdge(); + isect = theRectLine.intersect(centerToPoint); + if (isect.hasValue() && inBounds(*isect, 0.0f, 1.0f)) { + distance = theRectLine.dy(); + theEdge = EdgeTypes::Left; + } + } + // If we haven't resolved the edge type + if (theEdge == EdgeTypes::UnsetEdgeType) { + if (centerToPoint.dy() < 0) { + theRectLine = inRect.topEdge(); + isect = theRectLine.intersect(centerToPoint); + theEdge = EdgeTypes::Top; + distance = theRectLine.dx(); + } else { + theRectLine = inRect.bottomEdge(); + isect = theRectLine.intersect(centerToPoint); + theEdge = EdgeTypes::Bottom; + distance = theRectLine.dx(); + } + } + // Now drop a perpendicular from the point to the rect line. + SLine normalLine(inPoint, inPoint + QT3DSVec2(theRectLine.dy(), -theRectLine.dx())); + isect = theRectLine.intersect(normalLine); + if (isect.isEmpty()) { + theEdge = EdgeTypes::Right; + isect = .5f; + } + SEndPoint retval(theEdge, *isect); + QT3DSF32 normalizedBoundary = + NVMax(0.0f, inEdgeBoundary / static_cast(fabs(distance))); + + QT3DSF32 edgeLowerBound = NVMax(0.0f, normalizedBoundary); + QT3DSF32 edgeUpperBound = NVMin(1.0f, 1.0f - normalizedBoundary); + retval.m_Interp = NVMax(edgeLowerBound, retval.m_Interp); + retval.m_Interp = NVMin(edgeUpperBound, retval.m_Interp); + return retval; + } + + // Default end points always are in the middle of the rect edge + SEndPoint CEditorTransitionPath::CalculateDefaultEndPoint(const SRect &inRect, + const QT3DSVec2 &inPoint) + { + SEndPoint ep = CalculateEndPoint(inRect, inPoint, 0.0f); + return SEndPoint(ep.m_EdgeType, .5f); + } + + void CEditorTransitionPath::SetEndPoint(const QT3DSVec2 &inWorldPoint) + { + QT3DS_ASSERT(m_EndRect.hasValue()); + m_End = CalculateEndPoint(*m_EndRect, inWorldPoint, m_StateEdgeBuffer); + MarkDirty(); + } + + void CEditorTransitionPath::SetBeginPoint(const QT3DSVec2 &inWorldPoint) + { + QT3DS_ASSERT(m_BeginRect.hasValue()); + m_Begin = CalculateEndPoint(*m_BeginRect, inWorldPoint, m_StateEdgeBuffer); + MarkDirty(); + } + + SEndPoint CEditorTransitionPath::GetActualBeginPoint() const + { + return DoGetActualEndPoint(m_Begin, *m_BeginRect, m_EndRect->center()); + } + + SEndPoint CEditorTransitionPath::GetActualEndPoint() const + { + return DoGetActualEndPoint(m_End, *m_EndRect, m_BeginRect->center()); + } + + void CEditorTransitionPath::SetControlPoint(QT3DSI32 idx, const QT3DSVec2 &inPosition, + bool inMoveAdjacentEndPoint) + { + if (idx < 0 || idx >= (QT3DSI32)m_ControlPoints.size()) { + QT3DS_ASSERT(false); + return; + } + m_ControlPoints[idx].Set(inPosition); + if (inMoveAdjacentEndPoint) { + // Move the end points adjacent to the handle. + QT3DSI32 possiblePoint = MapControlPointToPossibleControlPoint(idx); + size_t numPossible = m_PossibleControlPoints.size(); + if (possiblePoint == 0) + SetBeginPoint(inPosition); + if (possiblePoint == ((QT3DSI32)numPossible - 1)) + SetEndPoint(inPosition); + } + + MarkDirty(); + } + + void CEditorTransitionPath::SetControlPoints(const TPointList &inList) + { + QT3DS_ASSERT(inList.size() == m_Path.size()); + for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) { + SControlPoint &theControlPoint(m_ControlPoints[idx]); + if (theControlPoint.m_PathIndex >= 0 + && theControlPoint.m_PathIndex < (QT3DSI32)inList.size()) + theControlPoint.Set(inList[theControlPoint.m_PathIndex]); + else { + QT3DS_ASSERT(false); + } + } + } + + TPointList CEditorTransitionPath::GetPath() const + { + MaybeRegeneratePath(); + return m_Path; + } + + TControlPointList CEditorTransitionPath::GetPossibleControlPoints() const + { + MaybeRegeneratePath(); + return m_PossibleControlPoints; + } + + SControlPoint CEditorTransitionPath::GetPossibleControlPoint(QT3DSI32 inIdx) const + { + MaybeRegeneratePath(); + if (inIdx >= 0 && inIdx < (QT3DSI32)m_PossibleControlPoints.size()) + return m_PossibleControlPoints[inIdx]; + QT3DS_ASSERT(false); + return SControlPoint(); + } + + // This may create a new control point thus invalidating the path and possible control + // points. + QT3DSI32 + CEditorTransitionPath::MapPossibleControlPointToControlPoint(QT3DSI32 inPossiblePointIndex) + { + if (inPossiblePointIndex < 0 + || inPossiblePointIndex >= (QT3DSI32)m_PossibleControlPoints.size()) { + QT3DS_ASSERT(false); + return -1; + } + const SControlPoint &thePossiblePoint(m_PossibleControlPoints[inPossiblePointIndex]); + TControlPointList::iterator iter = eastl::lower_bound( + m_ControlPoints.begin(), m_ControlPoints.end(), thePossiblePoint); + QT3DSI32 retval = (QT3DSI32)m_ControlPoints.size(); + if (iter != m_ControlPoints.end()) { + retval = (QT3DSI32)(iter - m_ControlPoints.begin()); + if (iter->m_PathIndex == thePossiblePoint.m_PathIndex) + return retval; + } + + m_ControlPoints.insert(iter, thePossiblePoint); + return retval; + } + + QT3DSI32 CEditorTransitionPath::MapControlPointToPossibleControlPoint(QT3DSI32 inPointIndex) + { + if (inPointIndex < 0 || inPointIndex >= (QT3DSI32)m_ControlPoints.size()) { + QT3DS_ASSERT(false); + return -1; + } + const SControlPoint &theControlPoint(m_ControlPoints[inPointIndex]); + TControlPointList::iterator iter = eastl::lower_bound( + m_PossibleControlPoints.begin(), m_PossibleControlPoints.end(), theControlPoint); + if (iter != m_PossibleControlPoints.end()) { + QT3DSI32 retval = (QT3DSI32)(iter - m_PossibleControlPoints.begin()); + if (iter->m_PathIndex == theControlPoint.m_PathIndex) + return retval; + } + QT3DS_ASSERT(false); + return -1; + } + + bool CEditorTransitionPath::DoesControlPointExist(QT3DSI32 inPossiblePointIndex) const + { + if (inPossiblePointIndex < 0 + || inPossiblePointIndex >= (QT3DSI32)m_PossibleControlPoints.size()) { + QT3DS_ASSERT(false); + return false; + } + const SControlPoint &thePossiblePoint(m_PossibleControlPoints[inPossiblePointIndex]); + TControlPointList::const_iterator iter = eastl::lower_bound( + m_ControlPoints.begin(), m_ControlPoints.end(), thePossiblePoint); + if (iter != m_ControlPoints.end() && iter->m_PathIndex == thePossiblePoint.m_PathIndex) + return true; + return false; + } + + // Run through the control point list and if you find another control point on the line, + // return it's index. Else + // bail. + // If you are finding the remove algorithm is too specific or hard to use increase the 2.0f + // numbers below. + inline Option NextParallelControlPointOnLine(const SControlPoint &inItem, + const SControlPoint &inEndPoint, + const TControlPointList &inList, + size_t inStartIdx) + { + for (size_t idx = inStartIdx, end = inList.size(); idx < end; ++idx) { + const SControlPoint &theTestPoint(inList[idx]); + if (theTestPoint.m_Direction == inItem.m_Direction) { + if (CEditorTransitionPath::AreAlmostEqual(inItem.m_Position, + theTestPoint.m_Position, 2.0f)) + return idx + 1; + else + return Empty(); + } + } + + // Check if beginning and end lie in the same path, or within just a couple pixels. + if (inItem.m_Direction == inEndPoint.m_Direction + && CEditorTransitionPath::AreAlmostEqual(inItem.m_Position, inEndPoint.m_Position, + 2.0f)) + return inList.size(); + + return Empty(); + } + + // We try to find control point that point the same direction and lie on the same line with + // only control points with + // orthogonal directions in between. If we find points that fullfill this criteria, we know + // we can remove all intermediate + // points because the transition path will end up making a straight line. + bool CEditorTransitionPath::RemoveRedundantControlPoints() + { + if (m_ControlPoints.empty()) + return false; + + eastl::pair theStartPoint = GetBeginPointAndEdge(); + eastl::pair theEndPoint; + if (m_EndRect.hasValue()) + theEndPoint = GetEndpointPoint(m_End, *m_EndRect, m_BeginRect->center()); + else + theEndPoint = theStartPoint; + // Find runs of control points in the same line. Remove the points in the middle of the + // line. + SControlPoint theLastControlPoint(EdgeTypeToDirectionType(theStartPoint.second)); + theLastControlPoint.Set(theStartPoint.first); + SControlPoint theEndControlPoint(EdgeTypeToDirectionType(theEndPoint.second)); + theEndControlPoint.Set(theEndPoint.first); + size_t numControlPoints(m_ControlPoints.size()); + for (size_t idx = 0, end = numControlPoints; idx < end; ++idx) { + Option removeEnd = NextParallelControlPointOnLine( + theLastControlPoint, theEndControlPoint, m_ControlPoints, idx); + if (removeEnd.isEmpty() == false) { + size_t lastItem = *removeEnd; + m_ControlPoints.erase(m_ControlPoints.begin() + idx, + m_ControlPoints.begin() + lastItem); + --idx; + end = m_ControlPoints.size(); + } else + theLastControlPoint = m_ControlPoints[idx]; + } + if (m_ControlPoints.size() != numControlPoints) { + MarkDirty(); + return true; + } + return false; + } + + void CEditorTransitionPath::RestoreAutoTransition() + { + m_ControlPoints.clear(); + m_Begin = SEndPoint(); + m_End = SEndPoint(); + MarkDirty(); + } + + bool CEditorTransitionPath::IsManualMode() const + { + return m_Begin.m_EdgeType != EdgeTypes::UnsetEdgeType + || m_End.m_EdgeType != EdgeTypes::UnsetEdgeType || m_ControlPoints.empty() == false; + } + + SPointQueryResult CEditorTransitionPath::Pick(QT3DSVec2 inPoint, QT3DSVec2 inControlBoxDims, + QT3DSVec2 inEndBoxDims) + { + MaybeRegeneratePath(); + + if (inEndBoxDims.x && inEndBoxDims.y) { + SRect endBox(QT3DSVec2(-1.0f * inEndBoxDims.x / 2, -1.0f * inEndBoxDims.y / 2), + inEndBoxDims); + SRect testRect(endBox); + testRect.translate(m_Path.front()); + if (testRect.contains(inPoint)) + return SPointQueryResult(PointQueryResultType::Begin); + testRect = SRect(endBox); + testRect.translate(m_Path.back()); + if (testRect.contains(inPoint)) + return SPointQueryResult(PointQueryResultType::End); + } + if (inControlBoxDims.x && inControlBoxDims.y) { + SRect theControlBox( + QT3DSVec2(-1.0f * inControlBoxDims.x / 2.0f, -1.0f * inControlBoxDims.y / 2.0f), + inControlBoxDims); + for (size_t idx = 0, end = m_PossibleControlPoints.size(); idx < end; ++idx) { + const SControlPoint &thePoint(m_PossibleControlPoints[idx]); + QT3DSVec2 startPoint = m_Path[thePoint.m_PathIndex]; + QT3DSVec2 endPoint = m_Path[thePoint.m_PathIndex + 1]; + // We stretch the rect to contain the entire line, not just where we display the + // point. + QT3DSVec2 lineDims = endPoint - startPoint; + QT3DSF32 lineRectHeight = SControlPoint::GetComponent(theControlBox.m_WidthHeight, + thePoint.m_Direction); + QT3DSF32 lineRectLength = + fabs(SControlPoint::GetOrthogonalComponent(lineDims, thePoint.m_Direction)); + QT3DSVec2 rectDims = SControlPoint::FromComponentToVector( + lineRectHeight, lineRectLength, thePoint.m_Direction); + QT3DSVec2 rectTopLeft = + QT3DSVec2(NVMin(startPoint.x, endPoint.x), NVMin(startPoint.y, endPoint.y)); + QT3DSF32 rectComponent = + SControlPoint::GetComponent(rectTopLeft, thePoint.m_Direction); + rectComponent -= lineRectHeight / 2.0f; // Center the box about the line. + rectTopLeft = SControlPoint::SetComponent(rectTopLeft, rectComponent, + thePoint.m_Direction); + SRect testRect(rectTopLeft, rectDims); + if (testRect.contains(inPoint)) + return SPointQueryResult(PointQueryResultType::Control, (QT3DSI32)idx); + } + } + return PointQueryResultType::NoPoint; + } + + SPointQueryResult + CEditorTransitionPath::PickClosestControlPoint(QT3DSVec2 inPoint, + DirectionTypes::Enum inDirectionType) + { + MaybeRegeneratePath(); + QT3DSI32 closestIdx = -1; + QT3DSF32 minDistance = QT3DS_MAX_F32; + + for (size_t idx = 0, end = m_PossibleControlPoints.size(); idx < end; ++idx) { + const SControlPoint &thePoint(m_PossibleControlPoints[idx]); + QT3DSVec2 startPoint = m_Path[thePoint.m_PathIndex]; + QT3DSVec2 endPoint = m_Path[thePoint.m_PathIndex + 1]; + SLine theLine(startPoint, endPoint); + QT3DSF32 distance = theLine.distance(inPoint); + + if (distance < minDistance && thePoint.m_Direction == inDirectionType) { + closestIdx = idx; + minDistance = distance; + } + } + if (closestIdx == -1) + return SPointQueryResult(); + return SPointQueryResult(PointQueryResultType::Control, closestIdx); + } + + // The output functions are both setup under these assumptions: + // 1. The current point does *not* have representation in the possible control points list. + // 2. The last point *does* have representation in the possible control points list. + // 3. The algorithm should output all path elements up and to but not including the + // current point. + // So, given straight line do not output any possible points. + // Given zig-zag, output two points. + SControlPoint + CEditorTransitionPath::OutputParallelPoints(const SControlPoint &inLastPoint, + const SControlPoint &inCurrentPoint, + QT3DSF32 runWidth) const + { + const SControlPoint &theRunPoint(inCurrentPoint); + const SControlPoint theLastControlPoint(inLastPoint); + DirectionTypes::Enum runDirection(inLastPoint.m_Direction); + if (AreAlmostEqual(theRunPoint.m_Position, theLastControlPoint.m_Position, 1.0)) { + // Straigh line. Perhaps remove this point? + theRunPoint.m_PathIndex = theLastControlPoint.m_PathIndex; + return theRunPoint; + } else { + // First, output a possible control point inline with inLastPoint + SControlPoint possiblePoint(inLastPoint); + possiblePoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); + m_PossibleControlPoints.push_back(possiblePoint); + // Output zig-zag, we zig zag from last control point to theRunPoint. We need to + // push two points and two control points. + QT3DSVec2 startPos(m_Path.back()); + QT3DSF32 startComponent = SControlPoint::GetComponent(startPos, runDirection); + QT3DSF32 orthoStartComponent = + SControlPoint::GetOrthogonalComponent(startPos, runDirection); + QT3DSF32 endComponent = theRunPoint.m_Position; + QT3DSF32 orthoEndComponent = orthoStartComponent + runWidth; + QT3DSVec2 endPos = SControlPoint::FromComponentToVector( + endComponent, orthoEndComponent, runDirection); + QT3DSF32 zigZagOrthoPos = orthoStartComponent + runWidth / 2; + QT3DSI32 crossbarIndex = (QT3DSI32)m_Path.size(); + QT3DSVec2 crossbarStart = SControlPoint::FromComponentToVector( + startComponent, zigZagOrthoPos, runDirection); + m_Path.push_back(crossbarStart); + m_PossibleControlPoints.push_back( + SControlPoint(SControlPoint::OppositeDirection(theRunPoint.m_Direction), + orthoStartComponent, crossbarIndex)); + QT3DSVec2 crossbarEnd = SControlPoint::FromComponentToVector( + endComponent, zigZagOrthoPos, theRunPoint.m_Direction); + m_Path.push_back(crossbarEnd); + theRunPoint.m_PathIndex = crossbarIndex + 1; + // Do not, however, output the run point. This will happen in the next step. + return inCurrentPoint; + } + } + + // Given right angle, output 1 point. + SControlPoint + CEditorTransitionPath::OutputOrthogonalPoints(const SControlPoint &inLastPoint, + const SControlPoint &inCurrentPoint) const + { + SLine lastLine = inLastPoint.ToLine(); + SLine currentLine = inCurrentPoint.ToLine(); + Option isect = lastLine.intersect(currentLine); + QT3DS_ASSERT(isect.hasValue()); + inLastPoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); + m_PossibleControlPoints.push_back(inLastPoint); + if (isect.hasValue()) { + QT3DSVec2 theIsectPoint = lastLine.toPoint(*isect); + m_Path.push_back(theIsectPoint); + } + inCurrentPoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); + return inCurrentPoint; + } + + void CEditorTransitionPath::MaybeRegeneratePath() const + { + if (IsDirty() == false) + return; + + if (m_TransitionPathType == TransitionPathTypes::BeginToEnd) { + // Ensure intermediate information is cleared. + const_cast(this)->MarkDirty(); + // We don't have the begin and end states. + if (m_BeginRect.isEmpty() || m_EndRect.isEmpty()) { + QT3DS_ASSERT(false); + return; + } + // Find the start and end points. + eastl::pair theStartPoint = + GetEndpointPoint(m_Begin, *m_BeginRect, m_EndRect->center()); + eastl::pair theEndPoint = + GetEndpointPoint(m_End, *m_EndRect, m_BeginRect->center()); + m_Path.push_back(theStartPoint.first); + SControlPoint theLastControlPoint(EdgeTypeToDirectionType(theStartPoint.second)); + theLastControlPoint.Set(theStartPoint.first); + theLastControlPoint.m_PathIndex = 0; + SControlPoint theEndControlPoint(EdgeTypeToDirectionType(theEndPoint.second)); + theEndControlPoint.Set(theEndPoint.first); + for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) { + const SControlPoint &thePoint(m_ControlPoints[idx]); + if (thePoint.m_Direction == theLastControlPoint.m_Direction) { + // zig zag. Requires us to find the first point that *isn't a zig zag in + // order to + // calculate where the zig zag should be. We could have a section composed + // of only + // parallel directions and we can't lay then out until we find how much + // distance we have + // to space each on out. + // Image you get to this point and you find you have a set of control points + // with vertical direction. + // Their positions will tell us how far left each one should sit. But we + // don't have enough information + // to lay them out without knowing how much vertical space this section + // should fill. So we would have to + // search forward until we can figure this out. + QT3DSVec2 runStart = m_Path.back(); + // Search forward until either we run out of points or until we find a point + // who's direction + // does not match the current direction. We call a contiguous set of + // control points who all + // have the same direction a 'run'. + size_t runEnd; + size_t zigzagCount = 1; + DirectionTypes::Enum runDirection = theLastControlPoint.m_Direction; + // Search forward till we find a point that is different. + for (runEnd = idx + 1; runEnd < end + && m_ControlPoints[runEnd].m_Direction == thePoint.m_Direction; + ++runEnd) { + // Skip items that are in line. They shouldn't be counted towards our + // zigzag count. + if (AreAlmostEqual(m_ControlPoints[runEnd].m_Position, + m_ControlPoints[runEnd - 1].m_Position) + == false) + ++zigzagCount; + } + // Two possible cases. Either we find a control point that has a different + // direction in which case we then figure out + // how much space we need overall *or* we ran out of control points in which + // case we use the end point. + QT3DSVec2 runEndPoint(0, 0); + if (runEnd == end) { + // check if the end point direction is the same. This could be the + // final zig zag. Else it will be a righthand turn + if (EdgeTypeToDirectionType(theEndPoint.second) == runDirection + && AreAlmostEqual(theEndControlPoint.m_Position, + thePoint.m_Position) + == false) + ++zigzagCount; + + runEndPoint = theEndPoint.first; + } else { + SLine thePointLine(thePoint.ToLine()); + Option isect = + thePointLine.intersect(m_ControlPoints[runEnd].ToLine()); + if (isect.hasValue()) + runEndPoint = thePointLine.toPoint(*isect); + else { + QT3DS_ASSERT(false); + } + } + QT3DSF32 runOrthoStart = + SControlPoint::GetOrthogonalComponent(runStart, runDirection); + QT3DSF32 runOrthoEnd = + SControlPoint::GetOrthogonalComponent(runEndPoint, runDirection); + QT3DSF32 runRange = runOrthoEnd - runOrthoStart; + QT3DSF32 runWidth = runRange / (QT3DSF32)zigzagCount; + // Now we iterate through the run itself and output path elements. + for (; idx < runEnd; ++idx) { + theLastControlPoint = OutputParallelPoints( + theLastControlPoint, m_ControlPoints[idx], runWidth); + } + // Subtract one to account for the loop upate that happens next + --idx; + } else // right angle + { + theLastControlPoint = + OutputOrthogonalPoints(theLastControlPoint, m_ControlPoints[idx]); + } + } + // Finished iterating through the control points. Now we have the sticky situation + // of the very last point + // and how it joins with the end point. + QT3DSVec2 lastPoint(m_Path.back()); + if (theEndControlPoint.m_Direction == theLastControlPoint.m_Direction) { + QT3DSF32 lastPointOrthoComponent = SControlPoint::GetOrthogonalComponent( + lastPoint, theLastControlPoint.m_Direction); + QT3DSF32 endOrthoComponent = SControlPoint::GetOrthogonalComponent( + theEndPoint.first, theLastControlPoint.m_Direction); + QT3DSF32 runWidth = endOrthoComponent - lastPointOrthoComponent; + OutputParallelPoints(theLastControlPoint, theEndControlPoint, runWidth); + } else { + theLastControlPoint = + OutputOrthogonalPoints(theLastControlPoint, theEndControlPoint); + } + // Now output the last possible point which matches the end control point's + // direction and such. + theEndControlPoint.m_PathIndex = (QT3DSI32)(m_Path.size() - 1); +#ifdef _DEBUG + // The directly previous possible point in the list should not match this point. In + // fact, it really should be orthogonal. + if (m_PossibleControlPoints.size()) { + QT3DS_ASSERT(m_PossibleControlPoints.back().m_Direction + != theEndControlPoint.m_Direction + || AreAlmostEqual(m_PossibleControlPoints.back().m_Position, + theEndControlPoint.m_Position) + == false); + } +#endif + m_PossibleControlPoints.push_back(theEndControlPoint); + // Finally push back the last item. + m_Path.push_back(theEndPoint.first); + } else if (m_TransitionPathType == TransitionPathTypes::BeginToBegin + || m_TransitionPathType == TransitionPathTypes::Targetless) { + QT3DSVec2 beginCenter(m_BeginRect->center()); + beginCenter.x += 1; + eastl::pair theStartPoint = + GetEndpointPoint(m_Begin, *m_BeginRect, beginCenter); + QT3DSVec2 lineDir; + m_Path.push_back(theStartPoint.first); + if (m_TransitionPathType == TransitionPathTypes::BeginToBegin) { + switch (theStartPoint.second) { + case EdgeTypes::Top: + lineDir = QT3DSVec2(0, -1); + break; + case EdgeTypes::Bottom: + lineDir = QT3DSVec2(0, 1); + break; + case EdgeTypes::Left: + lineDir = QT3DSVec2(-1, 0); + break; + case EdgeTypes::Right: + lineDir = QT3DSVec2(1, 0); + break; + default: + QT3DS_ASSERT(false); + break; + } + QT3DSF32 squareDiagLen = 30; + QT3DSF32 halfDiag = squareDiagLen / 2.0f; + QT3DSVec2 theOppPoint = theStartPoint.first + lineDir * squareDiagLen; + QT3DSVec2 middle = (theStartPoint.first + theOppPoint) / 2.0f; + QT3DSVec2 orthoLineDir = QT3DSVec2(lineDir.y, lineDir.x); + QT3DSVec2 loopTop = middle + orthoLineDir * halfDiag; + QT3DSVec2 loopBottom = middle - orthoLineDir * halfDiag; + m_Path.push_back(loopTop); + m_Path.push_back(theOppPoint); + m_Path.push_back(loopBottom); + m_Path.push_back(theStartPoint.first); + } + } else { + QT3DS_ASSERT(false); + } + } + } +} +} \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.h new file mode 100644 index 00000000..bacf60f2 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorTransitionPath.h @@ -0,0 +1,467 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_TRANSITION_PATH_H +#define QT3DS_STATE_EDITOR_TRANSITION_PATH_H +#pragma once +#include "Qt3DSState.h" +#include "foundation/Qt3DSVec2.h" +#include "EASTL/vector.h" +#include "foundation/Qt3DSOption.h" + +namespace qt3ds { +namespace state { + namespace editor { + + struct EdgeTypes + { + enum Enum { + UnsetEdgeType = 0, + Left, + Right, + Top, + Bottom, + }; + }; + + struct SEndPoint + { + // Which edge are we on + EdgeTypes::Enum m_EdgeType; + // How far from the start of the edge are we. + QT3DSF32 m_Interp; + SEndPoint(EdgeTypes::Enum inType = EdgeTypes::UnsetEdgeType, QT3DSF32 interp = .5f) + : m_EdgeType(inType) + , m_Interp(interp) + { + } + }; + + struct DirectionTypes + { + enum Enum { + UnknownDirection = 0, + Horizontal, + Vertical, + }; + }; + + struct SLine + { + QT3DSVec2 m_Begin; + QT3DSVec2 m_End; + + SLine(const QT3DSVec2 &beg = QT3DSVec2(0, 0), const QT3DSVec2 &end = QT3DSVec2(0, 0)) + : m_Begin(beg) + , m_End(end) + { + } + + QT3DSF32 dx() const { return m_End.x - m_Begin.x; } + QT3DSF32 dy() const { return m_End.y - m_Begin.y; } + QT3DSVec2 begin() const { return m_Begin; } + QT3DSVec2 end() const { return m_End; } + QT3DSVec2 toPoint(QT3DSF32 interp) { return m_Begin + QT3DSVec2(dx() * interp, dy() * interp); } + Option slope() const + { + QT3DSF32 run = dx(); + if (fabs(run) > .0001f) + return dy() / dx(); + return Empty(); + } + // If this function returns a value, it returns an interpolation value such that if you + // call toPoint on the return value it gives you the intersection point. + // http://tog.acm.org/resources/GraphicsGems/gemsiii/insectc.c + // Simplifications taken from Qt's line intersect + Option intersect(const SLine &other) const + { + // ipmlementation is based on Graphics Gems III's "Faster Line Segment Intersection" + QT3DSVec2 a = m_End - m_Begin; + QT3DSVec2 b = other.m_End - other.m_Begin; + QT3DSVec2 c = m_Begin - other.m_Begin; + + QT3DSF32 denominator = a.y * b.x - a.x * b.y; + + if (denominator == 0 || fabs(denominator) < .0001f) + return Empty(); + + QT3DSF32 reciprocal = 1.0f / denominator; + return (b.y * c.x - b.x * c.y) * reciprocal; + } + + // Caculates the top half of the distance to line equation with the fabs or sqrt. + QT3DSF32 distanceNumerator(const QT3DSVec2 &inPoint) const + { + QT3DSF32 x2 = inPoint.x; + QT3DSF32 y2 = inPoint.y; + + QT3DSF32 x1 = m_End.x; + QT3DSF32 y1 = m_End.y; + + QT3DSF32 x0 = m_Begin.x; + QT3DSF32 y0 = m_Begin.y; + return ((x2 - x1) * (y1 - y0)) - ((x1 - x0) * (y2 - y1)); + } + + QT3DSF32 distance(const QT3DSVec2 &inPoint) const + { + QT3DSF32 theDx = dx(); + QT3DSF32 theDy = dy(); + return fabs(distanceNumerator(inPoint)) / sqrtf(theDx * theDx + theDy * theDy); + } + }; + + // Rect in same coordinate space as QT. + struct SRect + { + QT3DSVec2 m_TopLeft; + QT3DSVec2 m_WidthHeight; + SRect(const QT3DSVec2 &tl = QT3DSVec2(0, 0), const QT3DSVec2 &wh = QT3DSVec2(0, 0)) + : m_TopLeft(tl) + , m_WidthHeight(wh) + { + } + QT3DSF32 left() const { return m_TopLeft.x; } + QT3DSF32 top() const { return m_TopLeft.y; } + QT3DSF32 right() const { return m_TopLeft.x + width(); } + QT3DSF32 bottom() const { return m_TopLeft.y + height(); } + QT3DSF32 width() const { return m_WidthHeight.x; } + QT3DSF32 height() const { return m_WidthHeight.y; } + QT3DSVec2 topLeft() const { return m_TopLeft; } + QT3DSVec2 bottomLeft() const { return QT3DSVec2(left(), bottom()); } + QT3DSVec2 bottomRight() const { return QT3DSVec2(right(), bottom()); } + QT3DSVec2 topRight() const { return QT3DSVec2(right(), top()); } + QT3DSVec2 center() const + { + return QT3DSVec2(left() + width() / 2.0f, top() + height() / 2.0f); + } + SLine leftEdge() const { return SLine(topLeft(), bottomLeft()); } + SLine rightEdge() const { return SLine(topRight(), bottomRight()); } + SLine topEdge() const { return SLine(topLeft(), topRight()); } + SLine bottomEdge() const { return SLine(bottomLeft(), bottomRight()); } + void translate(QT3DSF32 x, QT3DSF32 y) + { + m_TopLeft.x += x; + m_TopLeft.y += y; + } + void translate(const QT3DSVec2 &vec) + { + m_TopLeft.x += vec.x; + m_TopLeft.y += vec.y; + } + bool contains(const QT3DSVec2 &inPoint) const; + }; + + struct SControlPoint + { + DirectionTypes::Enum m_Direction; + // World space position + QT3DSF32 m_Position; + // This is a calculated value. Values set will be ignored in favor of recaculating by + // re-deriving + // the transition path. + mutable QT3DSI32 m_PathIndex; + SControlPoint(DirectionTypes::Enum inDir = DirectionTypes::UnknownDirection, + QT3DSF32 pos = 0.0f, QT3DSI32 idx = -1) + : m_Direction(inDir) + , m_Position(pos) + , m_PathIndex(idx) + { + } + bool operator<(const SControlPoint &inOther) const + { + return m_PathIndex < inOther.m_PathIndex; + } + static QT3DSF32 GetComponent(const QT3DSVec2 &inPoint, DirectionTypes::Enum inDir) + { + switch (inDir) { + case DirectionTypes::Horizontal: + return inPoint.y; + break; + case DirectionTypes::Vertical: + return inPoint.x; + break; + default: + QT3DS_ASSERT(false); + break; + } + return 0; + } + static DirectionTypes::Enum OppositeDirection(DirectionTypes::Enum inDir) + { + switch (inDir) { + case DirectionTypes::Horizontal: + return DirectionTypes::Vertical; + default: + return DirectionTypes::Horizontal; + } + } + static QT3DSF32 GetOrthogonalComponent(const QT3DSVec2 &inPoint, DirectionTypes::Enum inDir) + { + switch (inDir) { + case DirectionTypes::Horizontal: + return inPoint.x; + default: + return inPoint.y; + } + } + static QT3DSVec2 FromComponentToVector(QT3DSF32 inComponent, QT3DSF32 orthoComponent, + DirectionTypes::Enum inDir) + { + switch (inDir) { + case DirectionTypes::Horizontal: + return QT3DSVec2(orthoComponent, inComponent); + default: + return QT3DSVec2(inComponent, orthoComponent); + } + } + static QT3DSVec2 SetComponent(const QT3DSVec2 &inPoint, QT3DSF32 inValue, + DirectionTypes::Enum inDir) + { + switch (inDir) { + case DirectionTypes::Horizontal: + return QT3DSVec2(inPoint.x, inValue); + default: + return QT3DSVec2(inValue, inPoint.y); + } + } + void Set(const QT3DSVec2 &inPoint) { m_Position = GetComponent(inPoint, m_Direction); } + SLine ToLine() const + { + switch (m_Direction) { + case DirectionTypes::Horizontal: + return SLine(QT3DSVec2(0, m_Position), QT3DSVec2(1, m_Position)); + default: + return SLine(QT3DSVec2(m_Position, 0), QT3DSVec2(m_Position, 1)); + } + } + }; + + typedef eastl::vector TControlPointList; + typedef eastl::vector TPointList; + + struct PointQueryResultType + { + enum Enum { + NoPoint = 0, + Begin, + End, + Control, + }; + }; + + struct SPointQueryResult + { + PointQueryResultType::Enum m_QueryType; + QT3DSI32 m_Index; + SPointQueryResult( + PointQueryResultType::Enum inResultType = PointQueryResultType::NoPoint, + QT3DSI32 inIndex = -1) + : m_QueryType(inResultType) + , m_Index(inIndex) + { + } + }; + + struct TransitionPathTypes + { + enum Enum { + UnknownPathType = 0, + BeginToEnd = 1, + BeginToBegin = 2, + Targetless = 3, + }; + }; + + class CEditorTransitionPath + { + QT3DSF32 m_StateEdgeBuffer; + Option m_BeginRect; + Option m_EndRect; + SEndPoint m_Begin; + SEndPoint m_End; + // Control points that the user has edited. + TControlPointList m_ControlPoints; + TransitionPathTypes::Enum m_TransitionPathType; + + // ephemeral data, can be derived from start,end points (along with start/end state) and + // the + // user control points. + mutable TPointList m_Path; + // The full set of possible control points can be derived from the path. + mutable TControlPointList m_PossibleControlPoints; + + public: + CEditorTransitionPath(QT3DSF32 inStateEdgeBuffer = 10.0f) + : m_StateEdgeBuffer(inStateEdgeBuffer) + , m_TransitionPathType(TransitionPathTypes::BeginToEnd) + { + } + Option GetBeginRect() const { return m_BeginRect; } + void SetBeginRect(const Option &inRect) + { + m_BeginRect = inRect; + MarkDirty(); + } + + Option GetEndRect() const { return m_EndRect; } + void SetEndRect(const Option &inRect) + { + m_EndRect = inRect; + MarkDirty(); + } + + TransitionPathTypes::Enum GetPathType() const { return m_TransitionPathType; } + // May delete all the control points. + void SetPathType(TransitionPathTypes::Enum inType); + // This may move control points if instart rect and inendrect have shifted by similar + // amounts + // Returns true if persistent data changed, false otherwise. + bool UpdateBeginEndRects(const SRect &inStartRect, const SRect &inEndRect); + bool UpdateBeginEndRects(const SRect &inStartRect, + TransitionPathTypes::Enum inPathType); + eastl::pair GetBeginEndPoints() const; + + SEndPoint GetEndPoint() const { return m_End; } + void SetEndPoint(const SEndPoint &pt) + { + m_End = pt; + MarkDirty(); + } + void SetEndPoint(const QT3DSVec2 &inWorldPoint); + + SEndPoint GetBeginPoint() const { return m_Begin; } + void SetBeginPoint(const SEndPoint &pt) + { + m_Begin = pt; + MarkDirty(); + } + void SetBeginPoint(const QT3DSVec2 &inWorldPoint); + // Return where the end point will be. Will not return an invalid in point + // or an end point where information is not set. + SEndPoint GetActualBeginPoint() const; + SEndPoint GetActualEndPoint() const; + + TControlPointList GetControlPoints() const { return m_ControlPoints; } + SControlPoint GetControlPoint(QT3DSI32 inIndex) const + { + if (inIndex < (QT3DSI32)m_ControlPoints.size()) + return m_ControlPoints[inIndex]; + return SControlPoint(); + } + void SetControlPoints(const TControlPointList &list) + { + m_ControlPoints = list; + MarkDirty(); + } + void SetControlPoint(QT3DSI32 inControlPointIndex, const QT3DSVec2 &inPosition, + bool inMoveAdjacentEndPoint); + + // Set the control points by updating the individual items in the path list. + // This works if you do not add/remove points from the list. + // + // list = GetPath + // move points, don't add,delete + // setControlPoints(list) + void SetControlPoints(const TPointList &inList); + TPointList GetPath() const; + TControlPointList GetPossibleControlPoints() const; + SControlPoint GetPossibleControlPoint(QT3DSI32 inIdx) const; + + // This may create a new control point thus invalidating the path and possible control + // points. + QT3DSI32 MapPossibleControlPointToControlPoint(QT3DSI32 inPossiblePointIndex); + QT3DSI32 MapControlPointToPossibleControlPoint(QT3DSI32 inPointIndex); + // Returns true if MapPossibleControlPointToControlPoint will *not* create a new point + // false otherwise. + bool DoesControlPointExist(QT3DSI32 inPossiblePointIndex) const; + + // Returns true if any points were removed. + bool RemoveRedundantControlPoints(); + + void RestoreAutoTransition(); + + bool IsManualMode() const; + + // Query against the dataset to see what got picked. Includes the endoints. + // The rects should be centered about the original and just describe the picking + // rect to hit against. Empty rects will not get hit. + // Note that the result is the index into the possible point list where the hit + // happened. + // If you intend to manipulate the point, you need to call + // MapPossibleControlPointToControlPoint, + // Which may add a control point which you then can manipulate. + SPointQueryResult Pick(QT3DSVec2 inPoint, QT3DSVec2 inControlBoxDims, + QT3DSVec2 inEndBoxDims = QT3DSVec2(0, 0)); + SPointQueryResult PickClosestControlPoint(QT3DSVec2 inPoint, + DirectionTypes::Enum inDirectionType); + + void MarkDirty() + { + m_Path.clear(); + m_PossibleControlPoints.clear(); + for (size_t idx = 0, end = m_ControlPoints.size(); idx < end; ++idx) + m_ControlPoints[idx].m_PathIndex = -1; + } + + bool IsDirty() const { return m_Path.empty(); } + + static SEndPoint CalculateEndPoint(const SRect &inRect, const QT3DSVec2 &inPoint, + QT3DSF32 inEdgeBoundary); + static SEndPoint CalculateDefaultEndPoint(const SRect &inRect, const QT3DSVec2 &inPoint); + static bool AreAlmostEqual(QT3DSF32 lhs, QT3DSF32 rhs, QT3DSF32 error = .001f) + { + if (fabs(lhs - rhs) < error) + return true; + return false; + } + + static bool AreAlmostEqual(const QT3DSVec2 &lhs, const QT3DSVec2 &rhs, QT3DSF32 error = .001f) + { + return AreAlmostEqual(lhs.x, rhs.x, error) && AreAlmostEqual(lhs.y, rhs.y, error); + } + + // Regenerates the path if this object is dirty. + void MaybeRegeneratePath() const; + + eastl::pair GetBeginPointAndEdge() const; + + protected: + // Output the path between points that have the same direction. + SControlPoint OutputParallelPoints(const SControlPoint &inLastPoint, + const SControlPoint &inCurrentPoint, + QT3DSF32 inRunWidth) const; + SControlPoint OutputOrthogonalPoints(const SControlPoint &inLastPoint, + const SControlPoint &inCurrentPoint) const; + }; + } +} +} + +#endif \ No newline at end of file diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorValue.h b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorValue.h new file mode 100644 index 00000000..d47e6c99 --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSStateEditorValue.h @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QT3DS_STATE_EDITOR_VALUE_H +#define QT3DS_STATE_EDITOR_VALUE_H +#pragma once +#include "Qt3DSState.h" +#include "Qt3DSStateEditor.h" +#include "foundation/Qt3DSDiscriminatedUnion.h" +#include "foundation/Qt3DSVec3.h" + +namespace qt3ds { +namespace state { + namespace editor { + + struct ValueTypes + { + enum Enum { + NoEditorValue = 0, + String, + ObjPtr, + ObjPtrList, + Vec2, + Vec2List, + Vec3, + Boolean, + U32, + }; + }; + + template + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::NoEditorValue; } + }; + + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::String; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::ObjPtr; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::ObjPtrList; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::Vec2; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::Vec2List; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::Vec3; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::Boolean; } + }; + template <> + struct SValueTypeMap + { + static ValueTypes::Enum GetType() { return ValueTypes::U32; } + }; + + struct SValueUnionTraits + { + typedef ValueTypes::Enum TIdType; + enum { + TBufferSize = sizeof(TVec2List), + }; + + static TIdType getNoDataId() { return ValueTypes::NoEditorValue; } + + template + static TIdType getType() + { + return SValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case ValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::ObjPtr: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::ObjPtrList: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Vec2: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Vec2List: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Vec3: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Boolean: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::U32: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case ValueTypes::NoEditorValue: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case ValueTypes::String: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::ObjPtr: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::ObjPtrList: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Vec2: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Vec2List: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Vec3: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::Boolean: + return inVisitor(*NVUnionCast(inData)); + case ValueTypes::U32: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case ValueTypes::NoEditorValue: + return inVisitor(); + } + } + }; + } +} +} + +#ifndef _INTEGRITYPLATFORM +// need some specializations in the original nv foundation namespace +namespace qt3ds { +namespace foundation { + + template <> + struct DestructTraits + { + void destruct(QT3DSVec2 &) {} + }; + template <> + struct DestructTraits + { + void destruct(QT3DSVec3 &) {} + }; +} +} +#endif + +namespace qt3ds { +namespace state { + namespace editor { + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SValueUnionTraits::TBufferSize> + TEditorUnionType; + + struct SValue : public TEditorUnionType + { + SValue() {} + + SValue(const SValue &inOther) + : TEditorUnionType(static_cast(inOther)) + { + } + + SValue(const char8_t *inOther) + : TEditorUnionType(TEditorStr(inOther)) + { + } + + template + SValue(const TDataType &inDt) + : TEditorUnionType(inDt) + { + } + + SValue &operator=(const SValue &inOther) + { + TEditorUnionType::operator=(inOther); + return *this; + } + + bool operator==(const SValue &inOther) const + { + return TEditorUnionType::operator==(inOther); + } + bool operator!=(const SValue &inOther) const + { + return TEditorUnionType::operator!=(inOther); + } + + bool empty() const { return getType() == ValueTypes::NoEditorValue; } + }; + + struct SValueOpt : public Option + { + SValueOpt(const SValueOpt &inOther) + : Option(inOther) + { + } + SValueOpt(const Empty &) + : Option() + { + } + SValueOpt() {} + template + SValueOpt(const TDataType &inOther) + : Option(SValue(inOther)) + { + } + SValueOpt &operator=(const SValueOpt &inOther) + { + Option::operator=(inOther); + return *this; + } + }; + } +} +} + +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.cpp b/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.cpp new file mode 100644 index 00000000..f21fb27b --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.cpp @@ -0,0 +1,2527 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSUIADatamodel.h" +#include "foundation/IOStreams.h" +#include "foundation/XML.h" +#include "foundation/FileTools.h" +#include "Qt3DSStateEditorFoundation.h" +#include "Qt3DSStateApplication.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "EASTL/map.h" +#include "EASTL/sort.h" +#include "Qt3DSStateEditorTransactionImpl.h" +#include "Qt3DSUIADatamodelValue.h" +#include "foundation/StringConversion.h" +#include "foundation/StringConversionImpl.h" +#include "Qt3DSDMStringTable.h" + +using namespace qt3ds::app; +using qt3ds::render::IInputStreamFactory; + +namespace qt3ds { +namespace app { + + struct ElementSubTypes + { + enum Enum { + NoSubType = 0, + Component = 1, + Behavior = 2, + }; + }; + + struct SAppElement + { + TEditorStr m_Path; + TEditorStr m_Type; + TEditorStr m_Name; + TEditorStr m_Id; + Q3DStudio::TAttOrArgList m_Attributes; + Q3DStudio::TVisualEventList m_VisualEvents; + eastl::vector> m_Children; + eastl::vector m_InitialValues; + + private: + QT3DSI32 m_RefCount; + + public: + SAppElement() + : m_RefCount(0) + { + } + + virtual ~SAppElement() {} + + void addRef() { ++m_RefCount; } + + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + + virtual ElementSubTypes::Enum GetSubType() { return ElementSubTypes::NoSubType; } + }; +} +} + +namespace { + +typedef eastl::basic_string TStrType; +struct IPropertyParser +{ + virtual ~IPropertyParser() {} + virtual Option ParseStr(const char8_t *inName) = 0; + virtual Option ParseFloat(const char8_t *inName) = 0; + virtual Option ParseVec2(const char8_t *inName) = 0; + virtual Option ParseVec3(const char8_t *inName) = 0; + virtual Option ParseBool(const char8_t *inName) = 0; + virtual Option ParseU32(const char8_t *inName) = 0; + virtual Option ParseI32(const char8_t *inName) = 0; +}; + +struct SMetaPropertyParser : public IPropertyParser +{ + Q3DStudio::IRuntimeMetaData &m_MetaData; + IStringTable &m_StringTable; + TStrType m_TempStr; + qt3ds::foundation::CRegisteredString m_Type; + qt3ds::foundation::CRegisteredString m_ClassId; + + SMetaPropertyParser(const char8_t *inType, const char8_t *inClass, + Q3DStudio::IRuntimeMetaData &inMeta, IStringTable &stringTable) + : m_MetaData(inMeta) + , m_StringTable(stringTable) + , m_Type(stringTable.RegisterStr(inType)) + , m_ClassId(stringTable.RegisterStr(inClass)) + { + } + + qt3ds::foundation::CRegisteredString Register(const char8_t *inName) + { + return m_StringTable.RegisterStr(inName); + } + + virtual Option ParseStr(const char8_t *inName) + { + qt3ds::foundation::CRegisteredString theName(Register(inName)); + Q3DStudio::ERuntimeDataModelDataType theType( + m_MetaData.GetPropertyType(m_Type, theName, m_ClassId)); + if (theType != Q3DStudio::ERuntimeDataModelDataTypeObjectRef + && theType != Q3DStudio::ERuntimeDataModelDataTypeLong4) { + return m_MetaData.GetPropertyValueString(m_Type, theName, m_ClassId); + } + return Empty(); + } + virtual Option ParseFloat(const char8_t *inName) + { + return m_MetaData.GetPropertyValueFloat(m_Type, Register(inName), m_ClassId); + } + virtual Option ParseVec2(const char8_t *inName) + { + Option theProperty = + m_MetaData.GetPropertyValueVector2(m_Type, Register(inName), m_ClassId); + if (theProperty.hasValue()) { + return QT3DSVec2(theProperty->x, theProperty->y); + } + return Empty(); + } + virtual Option ParseVec3(const char8_t *inName) + { + Option theProperty = + m_MetaData.GetPropertyValueVector3(m_Type, Register(inName), m_ClassId); + if (theProperty.hasValue()) { + return *theProperty; + } + return Empty(); + } + virtual Option ParseBool(const char8_t *inName) + { + return m_MetaData.GetPropertyValueBool(m_Type, Register(inName), m_ClassId); + } + + virtual Option ParseU32(const char8_t *inName) + { + Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); + if (retval.hasValue()) + return (QT3DSU32)retval.getValue(); + return Empty(); + } + + virtual Option ParseI32(const char8_t *inName) + { + Option retval = m_MetaData.GetPropertyValueLong(m_Type, Register(inName), m_ClassId); + if (retval.hasValue()) + return (QT3DSI32)retval.getValue(); + return Empty(); + } +}; + +struct SDomReaderPropertyParser : public IPropertyParser +{ + IDOMReader &m_Reader; + nvvector &m_TempBuf; + MemoryBuffer &m_ReadBuffer; + + SDomReaderPropertyParser(IDOMReader &reader, nvvector &inTempBuf, + MemoryBuffer &readBuf) + : m_Reader(reader) + , m_TempBuf(inTempBuf) + , m_ReadBuffer(readBuf) + { + } + virtual Option ParseStr(const char8_t *inName) + { + const char8_t *retval; + if (m_Reader.UnregisteredAtt(inName, retval)) + return TStrType(retval); + return Empty(); + } + virtual Option ParseFloat(const char8_t *inName) + { + QT3DSF32 retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + virtual Option ParseVec2(const char8_t *inName) + { + QT3DSVec2 retval; + const char8_t *tempVal; + + if (m_Reader.UnregisteredAtt(inName, tempVal)) { + eastl::string tempBuffer(tempVal); + Char8TReader theReader(const_cast(tempBuffer.c_str()), m_ReadBuffer); + NVDataRef theDataRef(toDataRef(&retval.x, 2)); + theReader.ReadRef(theDataRef); + return retval; + } + return Empty(); + } + virtual Option ParseVec3(const char8_t *inName) + { + QT3DSVec3 retval; + const char8_t *tempVal; + if (m_Reader.UnregisteredAtt(inName, tempVal)) { + eastl::string tempBuffer(tempVal); + Char8TReader theReader(const_cast(tempBuffer.c_str()), m_ReadBuffer); + NVDataRef theDataRef(toDataRef(&retval.x, 3)); + theReader.ReadRef(theDataRef); + return retval; + } + return Empty(); + } + virtual Option ParseBool(const char8_t *inName) + { + bool retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + + virtual Option ParseU32(const char8_t *inName) + { + QT3DSU32 retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } + + virtual Option ParseI32(const char8_t *inName) + { + QT3DSI32 retval; + if (m_Reader.Att(inName, retval)) + return retval; + return Empty(); + } +}; + +template +struct SParserHelper +{ +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseStr(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseFloat(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseVec2(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseVec3(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseBool(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseU32(inName); + } +}; +template <> +struct SParserHelper +{ + static Option Parse(const char8_t *inName, IPropertyParser &inParser) + { + return inParser.ParseI32(inName); + } +}; + +struct SSlideInfo +{ + TEditorStr m_Name; +}; + +struct SAppComponent : public SAppElement +{ + TEditorStrList m_Slides; + virtual ElementSubTypes::Enum GetSubType() { return ElementSubTypes::Component; } +}; + +struct SAppBehavior : public SAppElement +{ + Q3DStudio::THandlerList m_Handlers; + virtual ElementSubTypes::Enum GetSubType() { return ElementSubTypes::Behavior; } +}; + +struct SVSEditorObject; + +struct SVSEditor +{ + TFoundationPtr m_Foundation; + NVScopedRefCounted m_TransactionManager; + NVScopedRefCounted m_StringTable; + SVSEditor(TFoundationPtr fnd, IStringTable &inStringTable) + : m_Foundation(fnd) + , m_TransactionManager(QT3DS_NEW(m_Foundation->getAllocator(), STransactionManagerImpl)(fnd)) + , m_StringTable(inStringTable) + { + } + + virtual void RemoveObjectFromGraph(SVSEditorObject &inObj) = 0; + STransaction *GetOpenTransactionImpl() + { + return m_TransactionManager->GetOpenTransactionImpl(); + } +}; + +struct SVSEditorObject : public IEditorObject +{ + TFoundationPtr m_Foundation; + SVSEditor &m_Editor; + TObjPtr m_ParentObject; + TPropertyAccessorList m_PropertyAccessors; + QT3DSI32 mRefCount; + SVSEditorObject(SVSEditor &editor, TObjPtr parent, const char8_t *typeName, + const TPropertyAccessorList &ioList) + : IEditorObject(typeName) + , m_Foundation(editor.m_Foundation) + , m_Editor(editor) + , m_ParentObject(parent) + , m_PropertyAccessors(ioList) + , mRefCount(0) + { + } + + virtual TEditorStr GetId() { return TEditorStr(); } + virtual TEditorStr GetDescription() { return TEditorStr(); } + virtual void SetId(const TEditorStr &) { QT3DS_ASSERT(false); } + virtual void SetDescription(const TEditorStr &) { QT3DS_ASSERT(false); } + + virtual TObjPtr Parent() { return m_ParentObject; } + + IPropertyAccessor *FindPropertyAccessor(const char8_t *inName) + { + CRegisteredString nameStr = m_Editor.m_StringTable->RegisterStr(inName); + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) + if (m_PropertyAccessors[idx]->m_Declaration.m_Name == nameStr) + return m_PropertyAccessors[idx].mPtr; + return NULL; + } + + virtual void GetProperties(eastl::vector &outProperties) + { + outProperties.clear(); + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) + outProperties.push_back(m_PropertyAccessors[idx]->m_Declaration); + } + + virtual Option FindProperty(const char8_t *propName) + { + for (size_t idx = 0, end = m_PropertyAccessors.size(); idx < end; ++idx) { + if (AreEqual(m_PropertyAccessors[idx]->m_Declaration.m_Name.c_str(), propName)) + return m_PropertyAccessors[idx]->m_Declaration; + } + return Empty(); + } + + virtual eastl::vector GetLegalValues(const char8_t *) + { + return eastl::vector(); + } + + virtual Option GetPropertyValue(const char8_t *inPropName) + { + IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); + if (accessor) { + return accessor->Get(*this); + } + return Empty(); + } + virtual void SetPropertyValue(const char8_t *inPropName, const SValueOpt &inValue) + { + IPropertyAccessor *accessor = FindPropertyAccessor(inPropName); + if (accessor) { + STransaction *theTransaction = m_Editor.GetOpenTransactionImpl(); + if (theTransaction) { + Option existing = accessor->Get(*this); + theTransaction->m_Changes.push_back( + new SChange(existing, inValue, *accessor, *this)); + } + accessor->Set(*this, inValue); + } else { + QT3DS_ASSERT(false); + } + } + + virtual void RemoveObjectFromGraph() { m_Editor.RemoveObjectFromGraph(*this); } + virtual void RemoveIdFromContext() {} + virtual void AddIdToContext() {} + virtual IEditor &GetEditor() { return m_ParentObject->GetEditor(); } +}; + +template +struct SGenericPropertyStringAccessor : public SPropertyAccessorBase +{ + typedef TEditorStr TDataType; + typedef TDataType TEditorType::*TPropertyPtr; + typedef SPropertyAccessorBase TBaseType; + + TPropertyPtr m_Property; + + SGenericPropertyStringAccessor(TFoundationPtr inAlloc, const SPropertyDeclaration &inDec, + TPropertyPtr inPtr) + : TBaseType(inAlloc, inDec) + , m_Property(inPtr) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + TDataType &dtype = inObj.*(this->m_Property); + return SValue(dtype); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + TDataType &dtype = inObj.*(this->m_Property); + dtype.clear(); + if (inValue.hasValue() && inValue->getType() == ValueTypes::String) + dtype = inValue->getData(); + } +}; + +template +struct SGenericPropertyStringFunctionAccessor : public SPropertyAccessorBase +{ + typedef TEditorStr TDataType; + typedef TDataType (TEditorType::*TGetter)() const; + typedef void (TEditorType::*TSetter)(const TDataType &); + typedef SPropertyAccessorBase TBaseType; + + TGetter m_Getter; + TSetter m_Setter; + + SGenericPropertyStringFunctionAccessor(TFoundationPtr inAlloc, + const SPropertyDeclaration &inDec, TGetter inGetter, + TSetter inSetter) + : TBaseType(inAlloc, inDec) + , m_Getter(inGetter) + , m_Setter(inSetter) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Allocator, this->mRefCount); + + virtual Option DoGet(TEditorType &inObj) + { + TDataType dtype = (inObj.*m_Getter)(); + return SValue(dtype); + } + + virtual void DoSet(TEditorType &inObj, const Option &inValue) + { + TDataType dtype; + dtype.clear(); + if (inValue.hasValue() && inValue->getType() == ValueTypes::String) + dtype = inValue->getData(); + + (inObj.*m_Setter)(dtype); + } +}; + +struct SGotoSlideEditor : public SVSEditorObject +{ + TEditorStr m_Component; + TEditorStr m_Slide; + TEditorStr m_Rel; + TEditorStr m_Wrap; + TEditorStr m_Direction; + TEditorStr m_State; + TEditorStr m_Mode; + TEditorStr m_PlayThroughTo; + TEditorStr m_Rate; + TEditorStr m_Time; + static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) + { + if (ioList.size()) + return; + + typedef SGenericPropertyStringAccessor TStrProp; + typedef SGenericPropertyStringFunctionAccessor TStrFunProp; + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_Component)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrFunProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("slide"), + EditorPropertyTypes::String), + &SGotoSlideEditor::GetSlide, &SGotoSlideEditor::SetSlide)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrFunProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("rel"), + EditorPropertyTypes::String), + &SGotoSlideEditor::GetRel, &SGotoSlideEditor::SetRel)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("wrap"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_Wrap)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, + SPropertyDeclaration(editor.m_StringTable->RegisterStr("direction"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_Direction)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("state"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_State)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("mode"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_Mode)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, + SPropertyDeclaration(editor.m_StringTable->RegisterStr("playthroughto"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_PlayThroughTo)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("rate"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_Rate)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("time"), + EditorPropertyTypes::String), + &SGotoSlideEditor::m_Time)); + } + + SGotoSlideEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) + : SVSEditorObject(editor, parent, ElementName(), ioList) + { + } + + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); + + static const char8_t *ElementName() { return "goto-slide"; } + + void SetSlide(const TEditorStr &inSlide) + { + if (inSlide.empty() == false) { + if (m_Editor.GetOpenTransactionImpl()) + SetPropertyValue("rel", SValueOpt()); + else + m_Rel.clear(); + } + m_Slide = inSlide; + } + + TEditorStr GetSlide() const { return m_Slide; } + + void SetRel(const TEditorStr &inRel) + { + if (inRel.empty() == false) { + if (m_Editor.GetOpenTransactionImpl()) + SetPropertyValue("slide", SValueOpt()); + else + m_Slide.clear(); + } + m_Rel = inRel; + } + + TEditorStr GetRel() const { return m_Rel; } +}; + +struct SRunHandlerEditor : public SVSEditorObject +{ + TEditorStr m_Behavior; + TEditorStr m_Handler; + TEditorStr m_ArgumentStr; + static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) + { + if (ioList.size()) + return; + + typedef SGenericPropertyStringAccessor TStrProp; + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), + EditorPropertyTypes::String), + &SRunHandlerEditor::m_Behavior)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("handler"), + EditorPropertyTypes::String), + &SRunHandlerEditor::m_Handler)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, + SPropertyDeclaration(editor.m_StringTable->RegisterStr("arguments"), + EditorPropertyTypes::String), + &SRunHandlerEditor::m_ArgumentStr)); + } + SRunHandlerEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) + : SVSEditorObject(editor, parent, ElementName(), ioList) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); + static const char8_t *ElementName() { return "call"; } +}; + +struct SSetAttributeEditor : public SVSEditorObject +{ + TEditorStr m_Element; + TEditorStr m_Attribute; + TEditorStr m_Value; + + static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) + { + if (ioList.size()) + return; + + typedef SGenericPropertyStringAccessor TStrProp; + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), + EditorPropertyTypes::String), + &SSetAttributeEditor::m_Element)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, + SPropertyDeclaration(editor.m_StringTable->RegisterStr("attribute"), + EditorPropertyTypes::String), + &SSetAttributeEditor::m_Attribute)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("value"), + EditorPropertyTypes::String), + &SSetAttributeEditor::m_Value)); + } + SSetAttributeEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) + : SVSEditorObject(editor, parent, ElementName(), ioList) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); + static const char8_t *ElementName() { return "set-attribute"; } +}; + +struct SFireEventEditor : public SVSEditorObject +{ + TEditorStr m_Element; + TEditorStr m_Event; + + static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) + { + if (ioList.size()) + return; + + typedef SGenericPropertyStringAccessor TStrProp; + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("element"), + EditorPropertyTypes::String), + &SFireEventEditor::m_Element)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("event"), + EditorPropertyTypes::String), + &SFireEventEditor::m_Event)); + } + SFireEventEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) + : SVSEditorObject(editor, parent, ElementName(), ioList) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); + static const char8_t *ElementName() { return "fire-event"; } +}; + +struct SSetPresentationEditor : public SVSEditorObject +{ + TEditorStr m_Ref; + TEditorStr m_Attribute; + TEditorStr m_Value; + + static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) + { + if (ioList.size()) + return; + + typedef SGenericPropertyStringAccessor TStrProp; + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("ref"), + EditorPropertyTypes::String), + &SSetPresentationEditor::m_Ref)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, + SPropertyDeclaration(editor.m_StringTable->RegisterStr("attribute"), + EditorPropertyTypes::String), + &SSetPresentationEditor::m_Attribute)); + + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("value"), + EditorPropertyTypes::String), + &SSetPresentationEditor::m_Value)); + } + SSetPresentationEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) + : SVSEditorObject(editor, parent, ElementName(), ioList) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); + static const char8_t *ElementName() { return "set-presentation"; } +}; + +struct SPlaySoundEditor : public SVSEditorObject +{ + TEditorStr m_FilePath; + + static void CreateProperties(TPropertyAccessorList &ioList, SVSEditor &editor) + { + if (ioList.size()) + return; + + typedef SGenericPropertyStringAccessor TStrProp; + ioList.push_back(QT3DS_NEW(editor.m_Foundation->getAllocator(), TStrProp)( + editor.m_Foundation, SPropertyDeclaration(editor.m_StringTable->RegisterStr("file"), + EditorPropertyTypes::String), + &SPlaySoundEditor::m_FilePath)); + } + SPlaySoundEditor(SVSEditor &editor, TObjPtr parent, const TPropertyAccessorList &ioList) + : SVSEditorObject(editor, parent, ElementName(), ioList) + { + } + QT3DS_STATE_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(this->m_Foundation, this->mRefCount); + static const char8_t *ElementName() { return "play-sound"; } +}; + +struct SVSEntry +{ + QT3DSI32 mRefCount; + InterpreterEventTypes::Enum m_EventType; + TObjList m_Editors; + + SVSEntry(InterpreterEventTypes::Enum evtType = InterpreterEventTypes::UnknownInterpreterEvent) + : mRefCount(0) + , m_EventType(evtType) + { + } + void addRef() { ++mRefCount; } + void release() + { + --mRefCount; + if (mRefCount <= 0) + delete this; + } +}; + +struct SVSEntryListChange : public IChange +{ + TObjPtr m_Object; + NVScopedRefCounted m_Entry; + QT3DSI32 m_Index; + bool m_AddOnDo; + TObjPtr m_EditorObj; + QT3DSI32 m_RefCount; + + SVSEntryListChange(TObjPtr inObj, TObjPtr inPositionObj, SVSEntry &entry, bool addOnDo, + TObjPtr inEditorObj) + : m_Object(inObj) + , m_Entry(entry) + , m_AddOnDo(addOnDo) + , m_EditorObj(inEditorObj) + , m_RefCount(0) + { + TObjList::iterator iter = + eastl::find(entry.m_Editors.begin(), entry.m_Editors.end(), inPositionObj); + m_Index = iter - entry.m_Editors.begin(); + } + void addRef() { ++m_RefCount; } + void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + void add() { m_Entry->m_Editors.insert(m_Entry->m_Editors.begin() + m_Index, m_Object); } + void remove() + { + TObjList::iterator iter = + eastl::find(m_Entry->m_Editors.begin(), m_Entry->m_Editors.end(), m_Object); + if (iter != m_Entry->m_Editors.end()) + m_Entry->m_Editors.erase(iter); + else { + QT3DS_ASSERT(false); + } + } + + virtual void Do() + { + if (m_AddOnDo) + add(); + else + remove(); + } + virtual void Undo() + { + if (m_AddOnDo) + remove(); + else + add(); + } + virtual TObjPtr GetEditor() { return m_EditorObj; } +}; + +typedef eastl::pair, NVScopedRefCounted> TEntryExitPair; +typedef eastl::map TIdEntryExitMap; +typedef eastl::map TIdStateMapMap; + +struct SIdEntryExitDeleteChange : public IChange +{ + TIdEntryExitMap &m_Map; + TEditorStr m_Id; + TEntryExitPair m_Data; + QT3DSI32 m_RefCount; + TObjPtr m_EditorObject; + bool m_RemoveOnDo; + SIdEntryExitDeleteChange(TIdEntryExitMap &inMap, const TEditorStr &inId, TObjPtr inObj, + bool removeOnDo = true) + : m_Map(inMap) + , m_Id(inId) + , m_RefCount(0) + , m_EditorObject(inObj) + , m_RemoveOnDo(removeOnDo) + { + m_Data = m_Map[m_Id]; + } + virtual void addRef() { ++m_RefCount; } + virtual void release() + { + --m_RefCount; + if (m_RefCount <= 0) + delete this; + } + void remove() + { + TIdEntryExitMap::iterator iter = m_Map.find(m_Id); + if (iter != m_Map.end()) + m_Map.erase(iter); + else { + QT3DS_ASSERT(false); + } + } + void insert() { m_Map[m_Id] = m_Data; } + virtual void Do() + { + if (m_RemoveOnDo) + remove(); + else + insert(); + } + virtual void Undo() + { + if (m_RemoveOnDo) + insert(); + else + remove(); + } + virtual TObjPtr GetEditor() { return m_EditorObject; } +}; + +struct SEditorEntry +{ + TEditorPtr m_Editor; + TEditorStr m_Id; + TEditorStr m_FilePath; +}; + +template +SDatamodelValue ParseInitialProperty(const char8_t *inName, IPropertyParser &metaParser, + IPropertyParser &runtimeParser) +{ + Option val = SParserHelper::Parse(inName, runtimeParser); + if (val.isEmpty()) + val = SParserHelper::Parse(inName, metaParser); + if (val.hasValue()) + return SDatamodelValue(*val); + return SDatamodelValue(); +} + +template +SDatamodelValue ParseSlideProperty(const char8_t *inName, IPropertyParser &runtimeParser) +{ + Option val = SParserHelper::Parse(inName, runtimeParser); + if (val.hasValue()) + return *val; + return SDatamodelValue(); +} + +struct DatamodelImpl : public IDatamodel, + public ITransManagerImplListener, + public SVSEditor, + public IEditorCopyPasteListener +{ + TEditorStr m_FilePath; + QT3DSI32 mRefCount; + NVScopedRefCounted m_InputStreamFactory; + eastl::pair, NVScopedRefCounted> m_UIADocument; + nvvector m_UIANamespaces; + bool m_Dirty; + nvvector> m_Elements; + NVScopedRefCounted m_FinderElement; + nvvector m_Editors; + TIdStateMapMap m_IdToStateMaps; + eastl::vector m_Presentations; + nvvector m_ParseBuf; + Q3DStudio::TAttOrArgList m_SlideProperties; + eastl::string m_LoadingErrorString; + IStateMachineEditorManager &m_StateMachineEditorManager; + + DatamodelImpl(TFoundationPtr inFoundation, const TEditorStr &inPath, const TEditorStr &inAppDir, + IStateMachineEditorManager &inStateMachineEditorManager, + IStringTable &inStringTable) + : SVSEditor(inFoundation, inStringTable) + , m_FilePath(inPath) + , mRefCount(0) + , m_InputStreamFactory(IInputStreamFactory::Create(m_Foundation->getFoundation())) + , m_UIANamespaces(m_Foundation->getAllocator(), "m_UIANamespaces") + , m_Dirty(false) + , m_Elements(m_Foundation->getAllocator(), "m_Elements") + , m_Editors(m_Foundation->getAllocator(), "m_Editors") + , m_ParseBuf(inFoundation->getAllocator(), "tempbuf") + , m_StateMachineEditorManager(inStateMachineEditorManager) + { + TEditorStr ext; + CFileTools::GetExtension(m_FilePath.c_str(), ext); + if (ext.comparei("uia") != 0) { + m_FilePath = IApplication::GetLaunchFile(inPath.c_str()); + } + // Check extension, if it isn't what we expect then just set it to uia + ext.clear(); + CFileTools::GetExtension(m_FilePath.c_str(), ext); + if (ext.comparei("uia") != 0) + CFileTools::SetExtension(m_FilePath, "uia"); + + m_InputStreamFactory->AddSearchDirectory(inAppDir.c_str()); + + m_TransactionManager->m_ObjListener = this; + } + + ~DatamodelImpl() {} + + void addRef() { atomicIncrement(&mRefCount); } + + void release() + { + TFoundationPtr tempFoundation(m_Foundation); + atomicDecrement(&mRefCount); + if (mRefCount <= 0) { + NVDelete(m_Foundation->getAllocator(), this); + } + } + typedef eastl::map TIdHandlerMap; + typedef eastl::map TIdVisualEventMap; + typedef eastl::map> TIdElemMap; + + SAppElement &ParseElement(IDOMReader &inReader, Q3DStudio::IRuntimeMetaData &inMetaData, + eastl::vector> &ioChildList, + TIdElemMap &ioElemMap) + { + IDOMReader::Scope __elemScope(inReader); + const char8_t *className = inReader.GetElementName(); + const char8_t *classRef; + inReader.UnregisteredAtt("class", classRef); + const char8_t *id; + inReader.UnregisteredAtt("id", id); + Q3DStudio::SElementInfo elemInfo = inMetaData.LoadElement(className, classRef, id); + NVScopedRefCounted newElem; + if (elemInfo.m_ClassName.compare("Behavior") == 0) { + SAppBehavior *behavior = new SAppBehavior(); + behavior->m_Handlers = inMetaData.GetCustomHandlers(id); + newElem = behavior; + } else if (elemInfo.m_IsComponent) { + SAppComponent *component = new SAppComponent(); + newElem = component; + } else { + newElem = new SAppElement(); + } + newElem->m_Attributes = elemInfo.m_Attributes; + newElem->m_VisualEvents = inMetaData.GetVisualEvents(id); + newElem->m_Type = elemInfo.m_ClassName; + newElem->m_Id = id; + const char8_t *elemName; + if (inReader.UnregisteredAtt("name", elemName)) + newElem->m_Name.assign(elemName); + else { + Q3DStudio::TRuntimeMetaDataStrType str = inMetaData.GetPropertyValueString( + inMetaData.Register(className), inMetaData.Register("name"), + inMetaData.Register(id)); + newElem->m_Name = str; + } + + ioChildList.push_back(newElem); + m_Elements.push_back(newElem); + ioElemMap.insert(eastl::make_pair(TEditorStr(id), newElem)); + { + SMetaPropertyParser theMetaParser(newElem->m_Type.c_str(), classRef, inMetaData, + inMetaData.GetStringTable()->GetRenderStringTable()); + SDomReaderPropertyParser theDOMParser(inReader, m_ParseBuf, inReader.m_TempBuf); + for (size_t idx = 0, end = newElem->m_Attributes.size(); idx < end; ++idx) { + const SAttOrArg &theAtt(newElem->m_Attributes[idx]); + SDatamodelValue newValue; + switch (theAtt.m_DataType) { + case ERuntimeDataModelDataTypeFloat: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, + theDOMParser); + break; + case ERuntimeDataModelDataTypeFloat2: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, + theDOMParser); + break; + case ERuntimeDataModelDataTypeFloat3: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, + theDOMParser); + break; + case ERuntimeDataModelDataTypeLong: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, + theDOMParser); + break; + case ERuntimeDataModelDataTypeString: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), + theMetaParser, theDOMParser); + break; + case ERuntimeDataModelDataTypeBool: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), theMetaParser, + theDOMParser); + break; + case ERuntimeDataModelDataTypeStringRef: + newValue = ParseInitialProperty(theAtt.m_Name.c_str(), + theMetaParser, theDOMParser); + break; + case ERuntimeDataModelDataTypeObjectRef: + newValue = + ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); + break; + default: + break; + } + newElem->m_InitialValues.push_back(newValue); + } + } + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) + ParseElement(inReader, inMetaData, newElem->m_Children, ioElemMap); + + return *newElem; + } + + // Get the item names if not overridden + // Pull the names off so we can construct the item path. + void LoadSlide(IDOMReader &inReader, TIdElemMap &inMap) + { + IDOMReader::Scope __topScope(inReader); + for (bool commandSuccess = inReader.MoveToFirstChild(); commandSuccess; + commandSuccess = inReader.MoveToNextSibling()) { + IDOMReader::Scope __commandScope(inReader); + const char8_t *elemName = inReader.GetElementName(); + if (AreEqual(elemName, "Set") || AreEqual(elemName, "Add")) { + const char8_t *name; + TIdElemMap::iterator iter = inMap.end(); + const char8_t *itemRef; + inReader.UnregisteredAtt("ref", itemRef); + if (!isTrivial(itemRef)) { + if (itemRef[0] == '#') + ++itemRef; + iter = inMap.find(TEditorStr(itemRef)); + } + + if (inReader.UnregisteredAtt("name", name)) { + if (iter != inMap.end()) { + iter->second->m_Name.assign(name); + } else { + QT3DS_ASSERT(false); + } + } + if (iter != inMap.end() && AreEqual(elemName, "Add")) { + nvvector theTempBuf(this->m_Foundation->getAllocator(), "tempbuf"); + SDomReaderPropertyParser theDOMParser(inReader, m_ParseBuf, inReader.m_TempBuf); + SAppElement *newElem = iter->second.mPtr; + for (size_t idx = 0, end = newElem->m_Attributes.size(); idx < end; ++idx) { + const SAttOrArg &theAtt(newElem->m_Attributes[idx]); + SDatamodelValue newValue; + switch (theAtt.m_DataType) { + case ERuntimeDataModelDataTypeFloat: + newValue = + ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); + break; + case ERuntimeDataModelDataTypeFloat2: + newValue = + ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); + break; + case ERuntimeDataModelDataTypeFloat3: + newValue = + ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); + break; + case ERuntimeDataModelDataTypeLong: + newValue = + ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); + break; + case ERuntimeDataModelDataTypeString: + newValue = ParseSlideProperty(theAtt.m_Name.c_str(), + theDOMParser); + break; + case ERuntimeDataModelDataTypeBool: + newValue = + ParseSlideProperty(theAtt.m_Name.c_str(), theDOMParser); + break; + case ERuntimeDataModelDataTypeStringRef: + newValue = ParseSlideProperty(theAtt.m_Name.c_str(), + theDOMParser); + break; + case ERuntimeDataModelDataTypeObjectRef: + newValue = ParseSlideProperty(theAtt.m_Name.c_str(), + theDOMParser); + break; + default: + break; + } + if (newValue.getType() != ERuntimeDataModelDataTypeNone) + newElem->m_InitialValues[idx] = newValue; + } + } + } + } + } + + void ResolveElemPath(SAppElement &inElem, const eastl::string &parentId) + { + inElem.m_Path = parentId; + if (inElem.m_Path.back() != ':') + inElem.m_Path.append(1, '.'); + inElem.m_Path.append(inElem.m_Name); + for (size_t idx = 0, end = inElem.m_Children.size(); idx < end; ++idx) + ResolveElemPath(*inElem.m_Children[idx], inElem.m_Path); + } + + void LoadUIPFile(const char *inRelativePath, const char *inUIPId, + Q3DStudio::IRuntimeMetaData &inMetaData) + { + eastl::string appDir(m_FilePath); + CFileTools::GetDirectory(appDir); + eastl::string uipPath; + CFileTools::CombineBaseAndRelative(appDir.c_str(), inRelativePath, uipPath); + CFileSeekableIOStream uipStream(uipPath.c_str(), FileReadFlags()); + if (!uipStream.IsOpen()) { + QT3DS_ASSERT(false); + return; + } + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_Foundation->getAllocator(), m_StringTable)); + SDOMElement *domElem = CDOMSerializer::Read(*theFactory, uipStream).second; + if (!domElem) { + QT3DS_ASSERT(false); + return; + } + + NVScopedRefCounted theReader(IDOMReader::CreateDOMReader( + m_Foundation->getAllocator(), *domElem, m_StringTable, theFactory)); + if (!theReader->MoveToFirstChild("Project")) { + QT3DS_ASSERT(false); + return; + } + + Q3DStudio::IRuntimeMetaData &theMetaData(inMetaData); + theMetaData.ClearPerProjectData(); + + TEditorStr rootPath(inUIPId); + rootPath.append(1, ':'); + eastl::vector> topElements; + TIdElemMap idElemMap; + m_Presentations.push_back(SPresentation()); + SPresentation ¤tPresentation(m_Presentations.back()); + currentPresentation.m_Id.assign(inUIPId); + currentPresentation.m_SrcPath.assign(inRelativePath); + { + IDOMReader::Scope __projectScope(*theReader); + if (theReader->MoveToFirstChild("ProjectSettings")) { + const char8_t *temp; + theReader->UnregisteredAtt("author", temp); + currentPresentation.m_Author.assign(nonNull(temp)); + theReader->UnregisteredAtt("company", temp); + currentPresentation.m_Company.assign(nonNull(temp)); + theReader->Att("presentationWidth", currentPresentation.m_Width); + theReader->Att("presentationHeight", currentPresentation.m_Height); + } + // Presentation width and height as specified in the file. + } + // Classes/handlers + { + IDOMReader::Scope __projectScope(*theReader); + if (theReader->MoveToFirstChild("Classes")) { + // Load each class system into the meta data and then pull back the handlers + for (bool success = theReader->MoveToFirstChild(); success; + success = theReader->MoveToNextSibling()) { + const char8_t *id, *srcPath, *name; + theReader->UnregisteredAtt("id", id); + theReader->UnregisteredAtt("sourcepath", srcPath); + theReader->UnregisteredAtt("name", name); + eastl::string classItemPath; + CFileTools::CombineBaseAndRelative(appDir.c_str(), srcPath, classItemPath); + + if (AreEqual(theReader->GetElementName().c_str(), "Behavior")) { + bool theScriptFile = + theMetaData.LoadScriptFile("Behavior", id, name, classItemPath.c_str()); + QT3DS_ASSERT(theScriptFile); + (void)theScriptFile; + } else if (AreEqual(theReader->GetElementName().c_str(), "Effect")) { + bool theEffectFile = theMetaData.LoadEffectXMLFile("Effect", id, name, + classItemPath.c_str()); + QT3DS_ASSERT(theEffectFile); + (void)theEffectFile; + } else if (AreEqual(theReader->GetElementName().c_str(), "RenderPlugin")) { + theMetaData.LoadPluginXMLFile("RenderPlugin", id, name, + classItemPath.c_str()); + } else if (AreEqual(theReader->GetElementName().c_str(), "CustomMaterial")) { + theMetaData.LoadMaterialXMLFile("CustomMaterial", id, name, + classItemPath.c_str()); + } else { + QT3DS_ASSERT(false); + } + } + } + } + + // Graph + { + IDOMReader::Scope __projectScope(*theReader); + if (theReader->MoveToFirstChild("Graph")) { + for (bool success = theReader->MoveToFirstChild(); success; + success = theReader->MoveToNextSibling()) { + currentPresentation.m_Scene = + &ParseElement(*theReader, theMetaData, topElements, idElemMap); + } + } + } + // States/Slides + { + // This is where the name *may* be set, + IDOMReader::Scope __projectScope(*theReader); + if (theReader->MoveToFirstChild("Logic")) { + // Slides are just slightly hierarchical, master and then nonmaster children. + for (bool success = theReader->MoveToFirstChild(); success; + success = theReader->MoveToNextSibling()) { + IDOMReader::Scope __masterScope(*theReader); + LoadSlide(*theReader, idElemMap); + const char8_t *component; + theReader->UnregisteredAtt("component", component); + NVScopedRefCounted theComponent; + if (!isTrivial(component)) { + if (component[0] == '#') + ++component; + TIdElemMap::iterator iter = idElemMap.find(TEditorStr(component)); + if (iter != idElemMap.end()) { + if (iter->second->GetSubType() == ElementSubTypes::Component) + theComponent = static_cast(iter->second.mPtr); + else { + QT3DS_ASSERT(false); + } + } else { + QT3DS_ASSERT(false); + } + } + + for (bool childSuccess = theReader->MoveToFirstChild("State"); childSuccess; + childSuccess = theReader->MoveToNextSibling("State")) { + IDOMReader::Scope __slideScope(*theReader); + const char8_t *slideName; + if (theReader->UnregisteredAtt("name", slideName)) + theComponent->m_Slides.push_back(TEditorStr(slideName)); + LoadSlide(*theReader, idElemMap); + } + } + } + } + // Now resolve all the names to create full paths. + for (size_t idx = 0, end = topElements.size(); idx < end; ++idx) { + ResolveElemPath(*topElements[idx], rootPath); + } + } + + struct SElemLessThan + { + bool operator()(NVScopedRefCounted lhs, + NVScopedRefCounted rhs) const + { + return lhs->m_Path < rhs->m_Path; + } + }; + + static const char *GetNamespace() { return "http://qt.io/qt3dstudio/uia"; } + static const char *GetOldNamespace() { return "http://qt.io/qt3dstudio/uicomposer"; } + + void LoadUIADatabase() + { + CFileSeekableIOStream theStream(m_FilePath.c_str(), FileReadFlags()); + if (theStream.IsOpen()) { + LoadUIADatabaseFromStream(theStream); + } + } + + struct SXmlErrorHandler : public CXmlErrorHandler + { + SXmlErrorHandler(const eastl::string &inFilePath, eastl::string &inErrorString) + : m_FilePath(inFilePath) + , m_ErrorString(inErrorString) + { + } + virtual ~SXmlErrorHandler() {} + virtual void OnXmlError(TXMLCharPtr errorName, int line, int column) + { + if (m_ErrorString.empty()) + m_ErrorString.sprintf("%s(%d, %d): %s", m_FilePath.c_str(), line, column, + errorName); + } + eastl::string m_FilePath; + eastl::string &m_ErrorString; + }; + + void LoadUIADatabaseFromStream(IInStream &inStream) + { + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_Foundation->getAllocator(), m_StringTable)); + m_UIADocument.first = NULL; + m_UIADocument.second = NULL; + m_UIANamespaces.clear(); + m_Elements.clear(); + m_IdToStateMaps.clear(); + m_Editors.clear(); + m_Presentations.clear(); + m_SlideProperties.clear(); + m_LoadingErrorString.clear(); + eastl::string appDir(m_FilePath); + CFileTools::GetDirectory(appDir); + + SXmlErrorHandler theXmlErrorWriter(m_FilePath, m_LoadingErrorString); + eastl::pair parseResult = + CDOMSerializer::Read(*theFactory, inStream, &theXmlErrorWriter); + if (parseResult.second != NULL) { + qt3ds::foundation::CRegisteredString theRegisteredOldNamespace = + m_StringTable->RegisterStr(GetOldNamespace()); + qt3ds::foundation::CRegisteredString theRegisteredNamespace = + m_StringTable->RegisterStr(GetNamespace()); + + ReplaceDOMNamespace(*parseResult.second, theRegisteredOldNamespace, + theRegisteredNamespace); + + m_UIADocument = + IDOMWriter::CreateDOMWriter(theFactory, *parseResult.second, m_StringTable); + for (SNamespacePairNode *nodePtr = parseResult.first; nodePtr; + nodePtr = nodePtr->m_NextNode) { + if (nodePtr->m_Namespace == theRegisteredOldNamespace) + nodePtr->m_Namespace = theRegisteredNamespace; + m_UIANamespaces.push_back(*nodePtr); + } + } + + if (m_UIADocument.first.mPtr == NULL) { + m_UIADocument = IDOMWriter::CreateDOMWriter(m_Foundation->getAllocator(), "application", + m_StringTable, GetNamespace()); + m_Dirty = true; + } + if (m_UIANamespaces.empty()) + m_UIANamespaces.push_back( + SNamespacePair(m_StringTable->RegisterStr(GetNamespace()))); + + { + NVScopedReleasable theMetaData( + Q3DStudio::IRuntimeMetaData::Create(*m_InputStreamFactory)); + + if (theMetaData) { + m_SlideProperties = theMetaData->GetSlideAttributes(); + + eastl::vector> machinePathsAndIds; + IDOMReader::Scope __appScope(m_UIADocument.second); + + if (m_UIADocument.second->MoveToFirstChild("assets")) { + IDOMReader::Scope __assetsScope(m_UIADocument.second); + for (bool success = m_UIADocument.second->MoveToFirstChild(); success; + success = m_UIADocument.second->MoveToNextSibling()) { + IDOMReader::Scope __assetScope(m_UIADocument.second); + const char8_t *elemName = m_UIADocument.second->GetElementName(); + if (AreEqual(elemName, "presentation")) { + const char8_t *id, *relativePath; + m_UIADocument.second->UnregisteredAtt("id", id); + m_UIADocument.second->UnregisteredAtt("src", relativePath); + LoadUIPFile(relativePath, id, *theMetaData); + } else if (AreEqual(elemName, "statemachine")) { + const char8_t *id, *relativePath; + m_UIADocument.second->UnregisteredAtt("id", id); + m_UIADocument.second->UnregisteredAtt("src", relativePath); + TEditorStr fullPath; + CFileTools::CombineBaseAndRelative(appDir.c_str(), relativePath, + fullPath); + CreateSCXMLEditor(fullPath, nonNull(id)); + } + } + } + + // Now sort our list of elements by path after we have loaded all uip files. + eastl::sort(m_Elements.begin(), m_Elements.end(), SElemLessThan()); + } else { + QT3DS_ASSERT(false); + } + } + { + IDOMReader::Scope __appScope(m_UIADocument.second); + for (bool success = m_UIADocument.second->MoveToFirstChild("statemachine"); success; + success = m_UIADocument.second->MoveToNextSibling("statemachine")) { + IDOMReader::Scope __machineScope(m_UIADocument.second); + const char8_t *idref; + m_UIADocument.second->UnregisteredAtt("ref", idref); + if (!isTrivial(idref)) { + if (idref[0] == '#') + ++idref; + for (size_t idx = 0, end = m_Editors.size(); idx < end; ++idx) { + if (m_Editors[idx].m_Id.compare(idref) == 0) + ParseStateMachine(m_Editors[idx].m_Id, m_Editors[idx].m_Editor); + } + } + } + } + } + + virtual bool IsDirty() const { return m_Dirty; } + // General queries of the dataset defined by the uia file and all uip files and scxml files it + // includes. + + SAppElement *FindElementByPath(const TEditorStr &inPath) + { + if (!m_FinderElement) + m_FinderElement = new SAppElement(); + + m_FinderElement->m_Path = inPath; + + nvvector>::iterator iter = eastl::lower_bound( + m_Elements.begin(), m_Elements.end(), m_FinderElement, SElemLessThan()); + if (iter != m_Elements.end() && (*iter)->m_Path == m_FinderElement->m_Path) { + return iter->mPtr; + } + return NVScopedRefCounted(); + } + + virtual TEditorStrList GetComponents() + { + TEditorStrList retval; + for (size_t idx = 0, end = m_Elements.size(); idx < end; ++idx) { + if (m_Elements[idx]->GetSubType() == ElementSubTypes::Component) + retval.push_back(m_Elements[idx]->m_Path); + } + return retval; + } + + virtual TEditorStrList GetComponentSlides(const TEditorStr &inComponent) + { + SAppElement *elem = FindElementByPath(inComponent); + if (elem != NULL && elem->GetSubType() == ElementSubTypes::Component) + return static_cast(elem)->m_Slides; + return TEditorStrList(); + } + + virtual TEditorStrList GetBehaviors() + { + TEditorStrList retval; + for (size_t idx = 0, end = m_Elements.size(); idx < end; ++idx) { + if (m_Elements[idx]->GetSubType() == ElementSubTypes::Behavior) + retval.push_back(m_Elements[idx]->m_Path); + } + return retval; + } + + virtual Q3DStudio::THandlerList GetHandlers(const TEditorStr &inBehavior) + { + SAppElement *elem = FindElementByPath(inBehavior); + if (elem != NULL && elem->GetSubType() == ElementSubTypes::Behavior) + return static_cast(elem)->m_Handlers; + return Q3DStudio::THandlerList(); + } + + virtual Q3DStudio::TVisualEventList GetVisualEvents(const TEditorStr &inElement) + { + SAppElement *elem = FindElementByPath(inElement); + if (elem) + return elem->m_VisualEvents; + return Q3DStudio::TVisualEventList(); + } + + virtual TEditorStrList GetElements() + { + TEditorStrList retval; + for (size_t idx = 0, end = m_Elements.size(); idx < end; ++idx) + retval.push_back(m_Elements[idx]->m_Path); + return retval; + } + + virtual Q3DStudio::TAttOrArgList GetElementAttributes(const TEditorStr &inElement) + { + SAppElement *elem = FindElementByPath(inElement); + if (elem) + return elem->m_Attributes; + return Q3DStudio::TAttOrArgList(); + } + + TEditorPtr CreateSCXMLEditor(const TEditorStr &inPath, const TEditorStr &inId) + { + TEditorPtr newEditor = m_StateMachineEditorManager.GetOrCreateEditor(inPath, 0); + if (newEditor) { + SEditorEntry theEntry; + theEntry.m_Editor = newEditor.mPtr; + theEntry.m_FilePath = inPath; + theEntry.m_Id = inId; + m_Editors.push_back(theEntry); + } + return newEditor.mPtr; + } + + virtual TEditorPtr GetOrCreateEditor(const TEditorStr &inFullPath, bool *outLoadStatus) + { + (void)outLoadStatus; + TEditorStr normalizedPath(inFullPath); + CFileTools::NormalizePath(normalizedPath); + for (size_t idx = 0, end = m_Editors.size(); idx < end; ++idx) { + if (m_Editors[idx].m_FilePath == normalizedPath) + return m_Editors[idx].m_Editor; + } + + // Is file full path under our application directory; + TEditorStr appDir(m_FilePath); + CFileTools::GetDirectory(appDir); + TEditorStr editorDir(inFullPath); + CFileTools::GetDirectory(editorDir); + + // For scxml files outside our app dir, let the user create an editor manually. + // We will have nothing to do with it. + if (editorDir.find(appDir) == eastl::string::npos) + return TEditorPtr(); + + // Get an ID for the editor + IDOMReader::Scope __appScope(*m_UIADocument.second); + if (!m_UIADocument.second->MoveToFirstChild("assets")) { + m_UIADocument.first->Begin("assets", GetNamespace()); + } + + { + IDOMReader::Scope __assetsScope(*m_UIADocument.second); + for (bool success = m_UIADocument.second->MoveToFirstChild("statemachine"); success; + success = m_UIADocument.second->MoveToNextSibling("statemachine")) { + const char8_t *srcPath; + const char8_t *id; + m_UIADocument.second->UnregisteredAtt("src", srcPath); + m_UIADocument.second->UnregisteredAtt("id", id); + TEditorStr docPath; + CFileTools::CombineBaseAndRelative(appDir.c_str(), srcPath, docPath); + CFileTools::NormalizePath(docPath); + if (docPath == normalizedPath) { + return CreateSCXMLEditor(normalizedPath, nonNull(id)); + } + } + } + + eastl::string dirname, fname, extension; + CFileTools::Split(normalizedPath.c_str(), dirname, fname, extension); + m_UIADocument.first->Begin("statemachine", GetNamespace()); + m_UIADocument.first->Att("id", fname.c_str(), GetNamespace()); + eastl::string relativePath; + CFileTools::GetRelativeFromBase(appDir, normalizedPath, relativePath); + m_UIADocument.first->Att("src", relativePath.c_str()); + m_Dirty = true; + return CreateSCXMLEditor(normalizedPath, nonNull(fname.c_str())); + } + + static bool CouldHaveVisualStateExecutableContent(TObjPtr inObject) + { + return inObject->GetExecutableContentTypes().size() > 0; + } + template + TEditorType &CreateEditor(TObjPtr inParent) + { + TPropertyAccessorList accessors; + TEditorType::CreateProperties(accessors, *this); + return *QT3DS_NEW(m_Foundation->getAllocator(), TEditorType)(*this, inParent, accessors); + } + + SVSEntry *GetEntryForPair(TEntryExitPair &inPair, InterpreterEventTypes::Enum inType) + { + SVSEntry *theEntry; + if (inType == InterpreterEventTypes::StateEnter + || inType == InterpreterEventTypes::Transition) { + if (inPair.first == NULL) + inPair.first = new SVSEntry(inType); + theEntry = inPair.first.mPtr; + } else { + if (inPair.second == NULL) + inPair.second = new SVSEntry(inType); + theEntry = inPair.second.mPtr; + } + return theEntry; + } + + void ParseExecutableContent(IDOMReader &inReader, const TEditorStr &inId, + TIdEntryExitMap &ioMap, InterpreterEventTypes::Enum inType, + TObjPtr parentPtr) + { + IDOMReader::Scope __contentScope(inReader); + { + IDOMReader::Scope __testScope(inReader); + // See if there is any executable content to begin with. + if (inReader.MoveToFirstChild() == false) + return; + } + + TEntryExitPair &thePair = + ioMap.insert(eastl::make_pair(inId, TEntryExitPair())).first->second; + SVSEntry *theEntry = GetEntryForPair(thePair, inType); + QT3DS_ASSERT(theEntry->m_EventType == inType); + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + IDOMReader::Scope __elemScope(inReader); + const char8_t *elemName(inReader.GetElementName()); + if (AreEqual(elemName, SGotoSlideEditor::ElementName())) { + const char8_t *component, *slide, *rel, *wrap, *direction, *state, *mode, + *playthroughto, *rate, *time; + inReader.UnregisteredAtt("element", component); + if (inReader.UnregisteredAtt("slide", slide) == false) + inReader.UnregisteredAtt("rel", rel); + else + rel = ""; + inReader.UnregisteredAtt("wrap", wrap); + inReader.UnregisteredAtt("direction", direction); + inReader.UnregisteredAtt("state", state); + inReader.UnregisteredAtt("mode", mode); + inReader.UnregisteredAtt("playthroughto", playthroughto); + inReader.UnregisteredAtt("rate", rate); + inReader.UnregisteredAtt("time", time); + SGotoSlideEditor &theEditor = CreateEditor(parentPtr); + theEditor.m_Component.assign(nonNull(component)); + theEditor.m_Slide.assign(nonNull(slide)); + theEditor.m_Rel.assign(nonNull(rel)); + theEditor.m_Wrap.assign(nonNull(wrap)); + theEditor.m_Direction.assign(nonNull(direction)); + theEditor.m_State.assign(nonNull(state)); + theEditor.m_Mode.assign(nonNull(mode)); + theEditor.m_PlayThroughTo.assign(nonNull(playthroughto)); + theEditor.m_Rate.assign(nonNull(rate)); + theEditor.m_Time.assign(nonNull(time)); + theEntry->m_Editors.push_back(theEditor); + } else if (AreEqual(elemName, SSetAttributeEditor::ElementName())) { + const char8_t *element, *att, *val; + inReader.UnregisteredAtt("element", element); + inReader.UnregisteredAtt("attribute", att); + inReader.UnregisteredAtt("value", val); + SSetAttributeEditor &theEditor = CreateEditor(parentPtr); + theEditor.m_Element.assign(nonNull(element)); + theEditor.m_Attribute.assign(nonNull(att)); + theEditor.m_Value.assign(nonNull(val)); + theEntry->m_Editors.push_back(theEditor); + } else if (AreEqual(elemName, SFireEventEditor::ElementName())) { + const char8_t *element, *evt; + inReader.UnregisteredAtt("element", element); + inReader.UnregisteredAtt("event", evt); + SFireEventEditor &theEditor = CreateEditor(parentPtr); + theEditor.m_Element.assign(nonNull(element)); + theEditor.m_Event.assign(nonNull(evt)); + theEntry->m_Editors.push_back(theEditor); + } else if (AreEqual(elemName, SRunHandlerEditor::ElementName())) { + const char8_t *element, *handler, *args; + inReader.UnregisteredAtt("element", element); + inReader.UnregisteredAtt("handler", handler); + inReader.UnregisteredAtt("arguments", args); + SRunHandlerEditor &theEditor = CreateEditor(parentPtr); + theEditor.m_Behavior.assign(nonNull(element)); + theEditor.m_Handler.assign(nonNull(handler)); + theEditor.m_ArgumentStr.assign(nonNull(args)); + theEntry->m_Editors.push_back(theEditor); + } else if (AreEqual(elemName, SSetPresentationEditor::ElementName())) { + const char8_t *ref, *attribute, *value; + inReader.UnregisteredAtt("ref", ref); + inReader.UnregisteredAtt("attribute", attribute); + inReader.UnregisteredAtt("value", value); + SSetPresentationEditor &theEditor = CreateEditor(parentPtr); + theEditor.m_Ref.assign(nonNull(ref)); + theEditor.m_Attribute.assign(nonNull(attribute)); + theEditor.m_Value.assign(nonNull(value)); + theEntry->m_Editors.push_back(theEditor); + } else if (AreEqual(elemName, SPlaySoundEditor::ElementName())) { + const char8_t *file; + inReader.UnregisteredAtt("file", file); + SPlaySoundEditor &theEditor = CreateEditor(parentPtr); + theEditor.m_FilePath.assign(nonNull(file)); + theEntry->m_Editors.push_back(theEditor); + } + } + } + + void ParseVisualStateEntry(IDOMReader &inReader, TEditorPtr inEditor, TIdEntryExitMap &retval, + const char8_t *stateId) + { + TObjPtr parentPtr = inEditor->GetObjectById(stateId); + if (parentPtr) { + if (AreEqual(inReader.GetElementName().c_str(), "state")) { + for (bool entryExitSucces = inReader.MoveToFirstChild(); entryExitSucces; + entryExitSucces = inReader.MoveToNextSibling()) { + const char8_t *signalName(inReader.GetElementName()); + if (AreEqual(signalName, "enter")) { + ParseExecutableContent(inReader, stateId, retval, + InterpreterEventTypes::StateEnter, parentPtr); + } else if (AreEqual(signalName, "exit")) { + ParseExecutableContent(inReader, stateId, retval, + InterpreterEventTypes::StateExit, parentPtr); + } else { + QT3DS_ASSERT(false); + } + } + } else if (AreEqual(inReader.GetElementName().c_str(), "transition")) { + ParseExecutableContent(inReader, stateId, retval, InterpreterEventTypes::Transition, + parentPtr); + } else { + QT3DS_ASSERT(false); + } + } + } + + TIdEntryExitMap &ParseStateMachine(const TEditorStr &inId, TEditorPtr inEditor) + { + TIdEntryExitMap &retval = + m_IdToStateMaps.insert(eastl::make_pair(inId, TIdEntryExitMap())).first->second; + if (m_UIADocument.second->MoveToFirstChild("visual-states")) { + for (bool stateSuccess = m_UIADocument.second->MoveToFirstChild(); stateSuccess; + stateSuccess = m_UIADocument.second->MoveToNextSibling()) { + IDOMReader::Scope __stateScope(*m_UIADocument.second); + const char8_t *stateId; + m_UIADocument.second->UnregisteredAtt("ref", stateId); + if (!isTrivial(stateId)) { + if (stateId[0] == '#') + ++stateId; + + ParseVisualStateEntry(*m_UIADocument.second, inEditor, retval, stateId); + } + } + } + return retval; // found a statemachine with the right id. + } + + TIdEntryExitMap &GetOrCreateStateMap(const TEditorStr &inId, TEditorPtr inEditor) + { + TIdEntryExitMap &retval = + m_IdToStateMaps.insert(eastl::make_pair(inId, TIdEntryExitMap())).first->second; + + if (retval.empty()) { + IDOMReader::Scope __appScope(*m_UIADocument.second); + for (bool success = m_UIADocument.second->MoveToFirstChild("statemachine"); + success && retval.empty(); + success = m_UIADocument.second->MoveToNextSibling("statemachine")) { + IDOMReader::Scope __machineScope(*m_UIADocument.second); + const char8_t *idref; + m_UIADocument.second->UnregisteredAtt("ref", idref); + if (!isTrivial(idref)) { + if (idref[0] == '#') + ++idref; + if (inId.compare(idref) == 0) { + return ParseStateMachine(inId, inEditor); + } + } + } // for (statemachines) + } + + return retval; + } + + TIdEntryExitMap *GetStateMapForObject(TObjPtr inObject) + { + if (!CouldHaveVisualStateExecutableContent(inObject)) + return NULL; + + TEditorPtr theEditor = inObject->GetEditor(); + // Find the id for the editor + TIdEntryExitMap *stateMap(NULL); + + for (size_t idx = 0, end = m_Editors.size(); idx < end && stateMap == NULL; ++idx) { + if (m_Editors[idx].m_Editor == theEditor) + return &GetOrCreateStateMap(m_Editors[idx].m_Id, m_Editors[idx].m_Editor); + } + return NULL; + } + + // The editor obj has a remove from graph function that really is delete + virtual TObjList GetVisualStateExecutableContent(TObjPtr inObject, + InterpreterEventTypes::Enum inEventType) + { + TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); + if (stateMap == NULL) + return TObjList(); + + TEditorStr objId(inObject->GetId()); + TIdEntryExitMap::iterator iter = stateMap->find(objId); + for (TIdEntryExitMap::iterator temp = stateMap->begin(), end = stateMap->end(); temp != end; + ++temp) { + objId = temp->first; + objId.clear(); + } + if (iter != stateMap->end()) { + TEntryExitPair thePair = iter->second; + if (thePair.first && thePair.first->m_EventType == inEventType) + return thePair.first->m_Editors; + else if (thePair.second && thePair.second->m_EventType == inEventType) + return thePair.second->m_Editors; + } + + return TObjList(); + } + + // Type name is the element name, so set-attribute, goto-slide, or fire-event + virtual TObjPtr AppendVisualStateExecutableContent(TObjPtr inObject, + InterpreterEventTypes::Enum inEventType, + const char8_t *inElementName) + { + TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); + if (stateMap == NULL) + return TObjPtr(); + + NVConstDataRef supportedTypes = + inObject->GetExecutableContentTypes(); + bool foundEventType = false; + for (size_t idx = 0, end = supportedTypes.size(); idx < end && foundEventType == false; + ++idx) + if (inEventType == supportedTypes[idx]) + foundEventType = true; + + if (foundEventType == false) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + + TEntryExitPair &thePair = + stateMap->insert(eastl::make_pair(inObject->GetId(), TEntryExitPair())).first->second; + SVSEntry *entry = GetEntryForPair(thePair, inEventType); + if (!entry) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + + if (AreEqual(inElementName, SGotoSlideEditor::ElementName())) { + entry->m_Editors.push_back(CreateEditor(inObject)); + } else if (AreEqual(inElementName, SRunHandlerEditor::ElementName())) { + entry->m_Editors.push_back(CreateEditor(inObject)); + } else if (AreEqual(inElementName, SSetAttributeEditor::ElementName())) { + entry->m_Editors.push_back(CreateEditor(inObject)); + } else if (AreEqual(inElementName, SFireEventEditor::ElementName())) { + entry->m_Editors.push_back(CreateEditor(inObject)); + } else if (AreEqual(inElementName, SSetPresentationEditor::ElementName())) { + entry->m_Editors.push_back(CreateEditor(inObject)); + } else if (AreEqual(inElementName, SPlaySoundEditor::ElementName())) { + entry->m_Editors.push_back(CreateEditor(inObject)); + } else { + QT3DS_ASSERT(false); + return TObjPtr(); + } + TObjPtr retval = entry->m_Editors.back(); + STransaction *theTrans = GetOpenTransactionImpl(); + if (theTrans) { + SVSEntryListChange *theChange = + new SVSEntryListChange(TObjPtr(), retval, *entry, true, inObject); + theTrans->m_Changes.push_back(theChange); + } + return retval; + } + + virtual TObjPtr ChangeVisualStateExecutableContentName(TObjPtr inContent, + const char8_t *inElementName) + { + TObjPtr theParent = inContent->Parent(); + if (!CouldHaveVisualStateExecutableContent(theParent)) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + TIdEntryExitMap *stateMap = GetStateMapForObject(theParent); + if (stateMap == NULL) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + + TIdEntryExitMap::iterator iter = stateMap->find(theParent->GetId()); + if (iter == stateMap->end()) { + QT3DS_ASSERT(false); + return TObjPtr(); + } + TEntryExitPair thePair = iter->second; + NVScopedRefCounted theEntryFound; + if (!theEntryFound) { + NVScopedRefCounted theEntry = thePair.first; + TObjPtr theObj = inContent; + if (theEntry) { + TObjList::iterator iter = + eastl::find(theEntry->m_Editors.begin(), theEntry->m_Editors.end(), theObj); + if (iter != theEntry->m_Editors.end()) { + theEntryFound = theEntry; + } + } + } + if (!theEntryFound) { + NVScopedRefCounted theEntry = thePair.second; + TObjPtr theObj = inContent; + if (theEntry) { + TObjList::iterator iter = + eastl::find(theEntry->m_Editors.begin(), theEntry->m_Editors.end(), theObj); + if (iter != theEntry->m_Editors.end()) { + theEntryFound = theEntry; + } + } + } + if (!theEntryFound) + return TObjPtr(); + + TObjPtr theRetval; + if (AreEqual(inElementName, SGotoSlideEditor::ElementName())) { + theRetval = CreateEditor(theParent); + } else if (AreEqual(inElementName, SRunHandlerEditor::ElementName())) { + theRetval = CreateEditor(theParent); + } else if (AreEqual(inElementName, SSetAttributeEditor::ElementName())) { + theRetval = CreateEditor(theParent); + } else if (AreEqual(inElementName, SFireEventEditor::ElementName())) { + theRetval = CreateEditor(theParent); + } else if (AreEqual(inElementName, SSetPresentationEditor::ElementName())) { + theRetval = CreateEditor(theParent); + } else if (AreEqual(inElementName, SPlaySoundEditor::ElementName())) { + theRetval = CreateEditor(theParent); + } else { + QT3DS_ASSERT(false); + return TObjPtr(); + } + + NVScopedRefCounted theOldChange = + new SVSEntryListChange(inContent, inContent, *theEntryFound, false, theParent); + NVScopedRefCounted theNewChange = + new SVSEntryListChange(theRetval, inContent, *theEntryFound, true, theParent); + theOldChange->Do(); + theNewChange->Do(); + if (GetOpenTransactionImpl()) { + GetOpenTransactionImpl()->m_Changes.push_back(theOldChange.mPtr); + GetOpenTransactionImpl()->m_Changes.push_back(theNewChange.mPtr); + } + + return theRetval; + } + + // Called when the source uia changes. + virtual void RefreshFile() { LoadUIADatabase(); } + + virtual void RefreshFromStream(qt3ds::foundation::IInStream &inStream) + { + LoadUIADatabaseFromStream(inStream); + } + + // Returns the path that was passed in on create. + virtual TEditorStr GetFilePath() { return m_FilePath; } + + void CopyDOM(IDOMReader &inReader, IDOMWriter &inWriter) + { + IDOMReader::Scope __itemScope(inReader); + const SDOMElement &theElement(*inReader.GetElement()); + IDOMWriter::Scope __writeScope(inWriter, theElement.m_Name, theElement.m_Namespace); + if (theElement.m_Attributes.empty() && theElement.m_Children.empty()) { + if (!isTrivial(theElement.m_Value)) + inWriter.Value(theElement.m_Value); + } else { + for (TAttributeList::iterator iter = theElement.m_Attributes.begin(), + end = theElement.m_Attributes.end(); + iter != end; ++iter) { + inWriter.Att(iter->m_Name, iter->m_Value, iter->m_Namespace); + } + + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + IDOMReader::Scope __loopScope(inReader); + CopyDOM(inReader, inWriter); + } + } + } + void ReplaceDOMNamespace(SDOMElement &inDom, + qt3ds::foundation::CRegisteredString &inNamespaceToReplace, + qt3ds::foundation::CRegisteredString &inNewNamespace) + { + if (!inNamespaceToReplace.IsValid() || !inNewNamespace.IsValid()) + return; + if (inDom.m_Namespace == inNamespaceToReplace) + inDom.m_Namespace = inNewNamespace; + // Set attributes namespace + for (qt3ds::foundation::TAttributeList::iterator theIter = inDom.m_Attributes.begin(), + theEnd = inDom.m_Attributes.end(); + theIter != theEnd; ++theIter) { + if (theIter->m_Namespace == inNamespaceToReplace) + theIter->m_Namespace = inNewNamespace; + } + // Recursive + for (qt3ds::foundation::SDOMElement::TElementChildList::iterator + theIter = inDom.m_Children.begin(), + theEnd = inDom.m_Children.end(); + theIter != theEnd; ++theIter) { + ReplaceDOMNamespace(*theIter, inNamespaceToReplace, inNewNamespace); + } + } + struct SEditorIDFinder + { + TEditorStr m_Id; + SEditorIDFinder(const TEditorStr &id) + : m_Id(id) + { + } + bool operator()(const SEditorEntry &entry) const { return m_Id == entry.m_Id; } + }; + + void WriteExecutableContent(IDOMWriter &inWriter, NVScopedRefCounted inEntry) + { + if (inEntry == NULL) + return; + const char *elemName = ""; + switch (inEntry->m_EventType) { + case InterpreterEventTypes::Transition: + break; + case InterpreterEventTypes::StateEnter: + elemName = "enter"; + break; + case InterpreterEventTypes::StateExit: + elemName = "exit"; + break; + default: + QT3DS_ASSERT(false); + break; + } + if (!isTrivial(elemName)) + inWriter.Begin(elemName, GetNamespace()); + + eastl::vector properties; + for (size_t idx = 0, end = inEntry->m_Editors.size(); idx < end; ++idx) { + TObjPtr editor(inEntry->m_Editors[idx]); + IDOMWriter::Scope __contentScope(inWriter, editor->TypeName(), GetNamespace()); + editor->GetProperties(properties); + bool theNoProperty = true; + for (size_t idx = 0, end = properties.size(); idx < end; ++idx) { + TEditorStr theProp = + editor->GetPropertyValue(properties[idx].m_Name)->getData(); + if (theProp.empty() == false) { + inWriter.Att(properties[idx].m_Name.c_str(), theProp.c_str(), + GetNamespace()); + theNoProperty = false; + } + } + if (theNoProperty && properties.size() > 0) + inWriter.Att(properties[0].m_Name.c_str(), "", GetNamespace()); + } + + if (!isTrivial(elemName)) + inWriter.End(); + } + + void WriteStateEntry(TIdEntryExitMap::const_iterator stateIter, IDOMWriter &writer, + const char *typeName, const char *id) + { + const char8_t *stateName = "state"; + if (AreEqual(typeName, "transition")) + stateName = "transition"; + eastl::string tempAtt; + IDOMWriter::Scope __stateScope(writer, stateName, GetNamespace()); + tempAtt.assign("#"); + tempAtt.append(id); + writer.Att("ref", tempAtt.c_str()); + WriteExecutableContent(writer, stateIter->second.first); + WriteExecutableContent(writer, stateIter->second.second); + } + + // Returns false if unable to save, ask users to check the file out. + bool SaveInner(qt3ds::foundation::IOutStream &inStream) + { + IDOMReader::Scope __saveScope(m_UIADocument.second); + NVScopedRefCounted theFactory( + IDOMFactory::CreateDOMFactory(m_Foundation->getAllocator(), m_StringTable)); + NVScopedRefCounted outgoingDoc = + IDOMWriter::CreateDOMWriter(m_Foundation->getAllocator(), "application", m_StringTable, + GetNamespace()) + .first; + { + m_UIADocument.second->MoveToFirstChild("application"); + for (SDOMAttribute *theAtt = m_UIADocument.second->GetFirstAttribute(); theAtt; + theAtt = m_UIADocument.second->GetNextAttribute()) { + outgoingDoc->Att(theAtt->m_Name, theAtt->m_Value, theAtt->m_Namespace); + } + } + + { + IDOMReader::Scope __appScope(m_UIADocument.second); + if (m_UIADocument.second->MoveToFirstChild("assets")) { + CopyDOM(*m_UIADocument.second, *outgoingDoc); + } + } + { + eastl::string tempAtt; + for (TIdStateMapMap::const_iterator iter = m_IdToStateMaps.begin(), + end = m_IdToStateMaps.end(); + iter != end; ++iter) { + nvvector::iterator editorEntry = eastl::find_if( + m_Editors.begin(), m_Editors.end(), SEditorIDFinder(iter->first)); + if (editorEntry == m_Editors.end()) { + QT3DS_ASSERT(false); + return false; + } + IDOMWriter::Scope __machineScope(*outgoingDoc, "statemachine", GetNamespace()); + tempAtt.assign("#"); + tempAtt.append(iter->first); + outgoingDoc->Att("ref", tempAtt.c_str()); + IDOMWriter::Scope __vsScope(*outgoingDoc, "visual-states", GetNamespace()); + const TIdEntryExitMap &itemMap = iter->second; + for (TIdEntryExitMap::const_iterator stateIter = itemMap.begin(), + stateEnd = itemMap.end(); + stateIter != stateEnd; ++stateIter) { + TObjPtr editorObj = + editorEntry->m_Editor->GetObjectById(stateIter->first.c_str()); + if (!editorObj) { + QT3DS_ASSERT(false); + continue; + } + WriteStateEntry(stateIter, *outgoingDoc, editorObj->TypeName(), + stateIter->first.c_str()); + } + } + } + + SDOMElement *topElem = outgoingDoc->GetTopElement(); + CDOMSerializer::WriteXMLHeader(inStream); + CDOMSerializer::Write(m_Foundation->getAllocator(), *topElem, inStream, *m_StringTable, + m_UIANamespaces); + m_Dirty = false; + return true; + } + + virtual bool Save() + { + CFileSeekableIOStream theStream(m_FilePath.c_str(), FileWriteFlags()); + if (!theStream.IsOpen()) + return false; + return SaveInner(theStream); + } + + virtual bool Save(qt3ds::foundation::IOutStream &inStream) { return SaveInner(inStream); } + + virtual eastl::vector GetPresentations() { return m_Presentations; } + virtual eastl::string GetElementType(SAppElement &elem) { return elem.m_Type; } + + virtual eastl::string GetElementId(SAppElement &elem) { return elem.m_Id; } + virtual bool IsComponent(SAppElement &elem) + { + return elem.GetSubType() == ElementSubTypes::Component; + } + virtual Q3DStudio::TAttOrArgList GetElementAttributes(SAppElement &elem) + { + return elem.m_Attributes; + } + virtual Q3DStudio::TAttOrArgList GetSlideAttributes() { return m_SlideProperties; } + virtual eastl::vector GetElementAttributeInitialValues(SAppElement &elem) + { + return elem.m_InitialValues; + } + virtual eastl::vector GetElementChildren(SAppElement &elem) + { + eastl::vector retval; + retval.resize(elem.m_Children.size()); + for (size_t idx = 0, end = elem.m_Children.size(); idx < end; ++idx) + retval[idx] = elem.m_Children[idx].mPtr; + return retval; + } + virtual eastl::string GetLastLoadingErrorString() { return m_LoadingErrorString; } + // The file may either exist or not. You can pass in a uip file as well as a uia file. + + virtual NVFoundationBase &GetFoundation() { return m_Foundation->getFoundation(); } + + virtual IStringTable &GetStringTable() { return *m_StringTable; } + + // ITransactionManager + // Undo/redo is supported via a transparent transaction system. + // calls are reentrant but last call will close the transaction object. + // Any changes to any editor objects will go through this transaction when they happen. + virtual TSignalConnectionPtr AddChangeListener(IEditorChangeListener &inListener) + { + return m_TransactionManager->AddChangeListener(inListener); + } + virtual TTransactionPtr BeginTransaction(const TEditorStr &inName) + { + return m_TransactionManager->BeginTransaction(inName); + } + + virtual TTransactionPtr GetOpenTransaction() + { + return m_TransactionManager->GetOpenTransaction(); + } + + virtual void RollbackTransaction() { m_TransactionManager->RollbackTransaction(); } + virtual void EndTransaction() { m_TransactionManager->EndTransaction(); } + + virtual void OnObjectCreated(TObjPtr) {} + + virtual void OnObjectDeleted(TObjPtr inObject) + { + // don't care. + if (!CouldHaveVisualStateExecutableContent(inObject)) + return; + + TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); + if (stateMap == NULL) + return; + + TIdEntryExitMap::iterator iter = stateMap->find(inObject->GetId()); + if (iter == stateMap->end()) + return; + NVScopedRefCounted theChange = + new SIdEntryExitDeleteChange(*stateMap, inObject->GetId(), inObject); + theChange->Do(); + if (GetOpenTransactionImpl()) + GetOpenTransactionImpl()->m_Changes.push_back(theChange.mPtr); + } + bool RemoveObjectFromEntry(NVScopedRefCounted inEntry, SVSEditorObject &inObj) + { + if (inEntry) { + TObjList::iterator iter = + eastl::find(inEntry->m_Editors.begin(), inEntry->m_Editors.end(), TObjPtr(inObj)); + if (iter != inEntry->m_Editors.end()) { + NVScopedRefCounted theChange = new SVSEntryListChange( + TObjPtr(inObj), TObjPtr(inObj), *inEntry, false, inObj.m_ParentObject); + theChange->Do(); + if (GetOpenTransactionImpl()) + GetOpenTransactionImpl()->m_Changes.push_back(theChange.mPtr); + return true; + } + } + return false; + } + + virtual void RemoveObjectFromGraph(SVSEditorObject &inObj) + { + TObjPtr parentPtr = inObj.m_ParentObject; + if (!CouldHaveVisualStateExecutableContent(parentPtr)) { + QT3DS_ASSERT(false); + return; + } + TIdEntryExitMap *stateMap = GetStateMapForObject(parentPtr); + if (stateMap == NULL) { + QT3DS_ASSERT(false); + return; + } + + TIdEntryExitMap::iterator iter = stateMap->find(parentPtr->GetId()); + if (iter == stateMap->end()) { + QT3DS_ASSERT(false); + return; + } + TEntryExitPair thePair = iter->second; + if (!RemoveObjectFromEntry(thePair.first, inObj)) { + RemoveObjectFromEntry(thePair.second, inObj); + } + } + + struct SEditorFinder + { + TEditorPtr m_Editor; + SEditorFinder(TEditorPtr editor) + : m_Editor(editor) + { + } + bool operator()(const SEditorEntry &entry) const { return entry.m_Editor == m_Editor; } + }; + + void CopyStateNode(SStateNode &inNode, TIdEntryExitMap &idMap, IDOMWriter &writer) + { + TIdEntryExitMap::iterator iter = idMap.find(inNode.m_Id.c_str()); + if (iter != idMap.end()) { + const char *typeName = "state"; + if (inNode.m_Type == StateNodeTypes::Transition) + typeName = "transition"; + WriteStateEntry(iter, writer, typeName, inNode.m_Id.c_str()); + } + TStateNodeList *childList = inNode.GetChildren(); + if (childList) { + for (TStateNodeList::iterator iter = childList->begin(), end = childList->end(); + iter != end; ++iter) { + CopyStateNode(*iter, idMap, writer); + } + } + } + + virtual void OnCopy(TEditorPtr inEditor, eastl::vector &ioCopiedRoots, + IDOMWriter &ioWriter, eastl::vector &ioNamespaces) + { + ioNamespaces.push_back(SNamespacePair(m_StringTable->RegisterStr(GetNamespace()), + m_StringTable->RegisterStr("uia"))); + eastl::vector::iterator entry = + eastl::find_if(m_Editors.begin(), m_Editors.end(), SEditorFinder(inEditor)); + if (entry == m_Editors.end()) + return; + TIdStateMapMap::iterator mapEntry = m_IdToStateMaps.find(entry->m_Id); + if (mapEntry == m_IdToStateMaps.end()) + return; + IDOMWriter::Scope __modelScope(ioWriter, "datamodel_fragment", GetNamespace()); + for (size_t idx = 0, end = ioCopiedRoots.size(); idx < end; ++idx) { + CopyStateNode(*ioCopiedRoots[idx], mapEntry->second, ioWriter); + } + } + + virtual void OnPaste(TEditorPtr inEditor, IDOMReader &ioReader, + CXMLIO::TIdRemapMap &inStateIdRemapMap) + { + eastl::vector::iterator entry = + eastl::find_if(m_Editors.begin(), m_Editors.end(), SEditorFinder(inEditor)); + if (entry == m_Editors.end()) + return; + + IDOMReader::Scope __fragmentScope(ioReader); + if (ioReader.MoveToFirstChild("datamodel_fragment")) { + TIdEntryExitMap &stateMap = + m_IdToStateMaps.insert(eastl::make_pair(entry->m_Id, TIdEntryExitMap())) + .first->second; + for (bool success = ioReader.MoveToFirstChild(); success; + success = ioReader.MoveToNextSibling()) { + IDOMReader::Scope __childScope(ioReader); + const char8_t *idRef; + ioReader.UnregisteredAtt("ref", idRef); + if (isTrivial(idRef)) + continue; + if (idRef[0] == '#') + ++idRef; + + CXMLIO::TIdRemapMap::iterator finder = inStateIdRemapMap.find(idRef); + if (finder != inStateIdRemapMap.end()) + idRef = finder->second.c_str(); + + TEditorStr idStr(idRef); + TObjPtr parentObj = inEditor->GetObjectById(idRef); + if (parentObj) { + ParseVisualStateEntry(ioReader, inEditor, stateMap, idRef); + if (stateMap.find(idStr) != stateMap.end() + && m_TransactionManager->GetOpenTransactionImpl()) { + m_TransactionManager->GetOpenTransactionImpl()->m_Changes.push_back( + new SIdEntryExitDeleteChange(stateMap, idStr, parentObj, false)); + } + } + } + } + } + + virtual void OnIDChange(TEditorPtr inEditor, SStateNode &inNode, const char8_t *inOldId) + { + eastl::vector::iterator entry = + eastl::find_if(m_Editors.begin(), m_Editors.end(), SEditorFinder(inEditor)); + if (entry == m_Editors.end()) + return; + + TIdEntryExitMap &stateMap = + m_IdToStateMaps.insert(eastl::make_pair(entry->m_Id, TIdEntryExitMap())).first->second; + TEditorStr oldIdStr(inOldId); + TEditorStr newIdStr(inNode.m_Id.c_str()); + TIdEntryExitMap::iterator iter = stateMap.find(oldIdStr); + if (iter != stateMap.end()) { + TEntryExitPair thePair(iter->second); + stateMap.erase(iter); + stateMap.insert(eastl::make_pair(newIdStr, thePair)); + } + } + virtual bool OnDeleteState(TObjPtr inObject) + { + // don't care. + if (!CouldHaveVisualStateExecutableContent(inObject)) + return false; + + TIdEntryExitMap *stateMap = GetStateMapForObject(inObject); + if (stateMap == NULL) + return false; + + TIdEntryExitMap::iterator iter = stateMap->find(inObject->GetId()); + if (iter == stateMap->end()) + return false; + NVScopedRefCounted theChange = + new SIdEntryExitDeleteChange(*stateMap, inObject->GetId(), inObject); + theChange->Do(); + if (GetOpenTransactionImpl()) + GetOpenTransactionImpl()->m_Changes.push_back(theChange.mPtr); + return true; + } + virtual bool OnReloadStateMachine(TEditorPtr inStateMachineEditor) + { + bool theRetval = false; + TEditorPtr theEditor = inStateMachineEditor; + + for (size_t idx = 0, end = m_Editors.size(); idx < end; ++idx) { + if (m_Editors[idx].m_Editor == theEditor) { + TIdStateMapMap::iterator theFind = m_IdToStateMaps.find(m_Editors[idx].m_Id); + if (theFind != m_IdToStateMaps.end()) { + TIdEntryExitMap &theStateMap = theFind->second; + for (TIdEntryExitMap::iterator theIter = theStateMap.begin(), + theEnd = theStateMap.end(); + theIter != theEnd;) { + TEditorStr theStateId = theIter->first; + TObjPtr theState = inStateMachineEditor->GetObjectById(theStateId.c_str()); + if (theState) { + { + NVScopedRefCounted theEntry = theIter->second.first; + if (theEntry) { + for (TObjList::iterator theIter = theEntry->m_Editors.begin(), + theEnd = theEntry->m_Editors.end(); + theIter != theEnd; ++theIter) { + SVSEditorObject *theExecutableContent = + static_cast(theIter->mPtr); + if (theExecutableContent) { + theExecutableContent->m_ParentObject = theState; + } + } + } + } + { + NVScopedRefCounted theEntry = theIter->second.second; + if (theEntry) { + for (TObjList::iterator theIter = theEntry->m_Editors.begin(), + theEnd = theEntry->m_Editors.end(); + theIter != theEnd; ++theIter) { + SVSEditorObject *theExecutableContent = + static_cast(theIter->mPtr); + if (theExecutableContent) { + theExecutableContent->m_ParentObject = theState; + } + } + } + } + ++theIter; + } else { + theStateMap.erase(theIter++); + theRetval = true; + } + } + } + break; + } + } + return theRetval; + } + virtual void RegisterChangeListener(IStateMachineChangeListener &) {} + virtual void UnregisterChangeListener(IStateMachineChangeListener &) {} +}; +} + +IDatamodel &IDatamodel::Create(qt3ds::state::editor::TFoundationPtr inFoundation, + const TEditorStr &inPath, const TEditorStr &inAppDir, + IStateMachineEditorManager &inStateMachineEditorManager, + IInStream *inStream) +{ + return IDatamodel::Create(inFoundation, inPath, inAppDir, inStateMachineEditorManager, + IStringTable::CreateStringTable(inFoundation->getAllocator()), + inStream); +} + +IDatamodel &IDatamodel::Create(qt3ds::state::editor::TFoundationPtr inFoundation, + const TEditorStr &inPath, const TEditorStr &inAppDir, + IStateMachineEditorManager &inStateMachineEditorManager, + IStringTable &inStringTable, IInStream *inStream) +{ + DatamodelImpl &theDatamodel = *QT3DS_NEW(inFoundation->getAllocator(), DatamodelImpl)( + inFoundation, inPath, inAppDir, inStateMachineEditorManager, inStringTable); + if (inStream) + theDatamodel.LoadUIADatabaseFromStream(*inStream); + else + theDatamodel.LoadUIADatabase(); + return theDatamodel; +} diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.h b/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.h new file mode 100644 index 00000000..e064529a --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodel.h @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef UIA_DATAMODEL_H +#define UIA_DATAMODEL_H +#include "Qt3DSState.h" +#include "Qt3DSStateEditor.h" +#include "Qt3DSMetadata.h" +#include "Qt3DSStateInterpreter.h" +#include "Qt3DSStateEditorFoundation.h" + +namespace qt3ds { +namespace app { + using namespace qt3ds::state; + using namespace qt3ds::state::editor; + + typedef eastl::pair + TDataType; + + struct SDatamodelValue; + + struct SAppElement; + + struct SPresentation + { + eastl::string m_Id; + eastl::string m_SrcPath; + eastl::string m_Author; + eastl::string m_Company; + QT3DSU32 m_Width; + QT3DSU32 m_Height; + SAppElement *m_Scene; + SPresentation() + : m_Width(800) + , m_Height(480) + , m_Scene(NULL) + { + } + }; + + class IStateMachineChangeListener + { + public: + virtual ~IStateMachineChangeListener() {} + virtual bool OnDeleteState(TObjPtr inObject) = 0; + virtual bool OnReloadStateMachine(TEditorPtr inStateMachineEditor) = 0; + }; + + class IStateMachineEditorManager + { + public: + virtual ~IStateMachineEditorManager() {} + virtual TEditorPtr GetOrCreateEditor(const TEditorStr &inFullPath, bool *outLoadStatus) = 0; + virtual void RegisterChangeListener(IStateMachineChangeListener &inListener) = 0; + virtual void UnregisterChangeListener(IStateMachineChangeListener &inListener) = 0; + }; + + class IDatamodel : public ITransactionManager, + public IStateMachineEditorManager, + public IStateMachineChangeListener + { + protected: + virtual ~IDatamodel() {} + public: + // Returns true if we had to create the file. Users should always keep track of the + // transaction stack also + // this does not include that. + virtual bool IsDirty() const = 0; + // General queries of the dataset defined by the uia file and all uip files and scxml files + // it includes. + + virtual TEditorStrList GetComponents() = 0; + virtual TEditorStrList GetComponentSlides(const TEditorStr &inComponent) = 0; + + virtual TEditorStrList GetBehaviors() = 0; + + virtual Q3DStudio::THandlerList GetHandlers(const TEditorStr &inBehavior) = 0; + + virtual Q3DStudio::TVisualEventList GetVisualEvents(const TEditorStr &inElement) = 0; + + virtual TEditorStrList GetElements() = 0; + + virtual Q3DStudio::TAttOrArgList GetElementAttributes(const TEditorStr &inElement) = 0; + + // Necessary to share transaction info and trigger deletes of related information but not + // going to get + // done right now. + // virtual TEditorPtr GetOrCreateEditor( const TEditorStr& inFullPath ) = 0; + + // The editor obj has a remove from graph function that really is delete + virtual TObjList + GetVisualStateExecutableContent(TObjPtr inObject, + InterpreterEventTypes::Enum inEventType) = 0; + // Type name is the element name, so set-attribute, goto-slide, or fire-event + virtual TObjPtr AppendVisualStateExecutableContent(TObjPtr inObject, + InterpreterEventTypes::Enum inEventType, + const char8_t *inElementName) = 0; + virtual TObjPtr ChangeVisualStateExecutableContentName(TObjPtr inContent, + const char8_t *inElementName) = 0; + + // Called when the source uia changes. + virtual void RefreshFile() = 0; + virtual void RefreshFromStream(qt3ds::foundation::IInStream &inStream) = 0; + // Returns the path that was passed in on create. + virtual TEditorStr GetFilePath() = 0; + + // Returns false if unable to save, ask users to check the file out. + virtual bool Save() = 0; + virtual bool Save(qt3ds::foundation::IOutStream &inStream) = 0; + + // The section below allows someone to build an initial scene graph. + // Note that components have additional properties + // Get a list of presentations found while parsing uia file. + virtual eastl::vector GetPresentations() = 0; + virtual eastl::string GetElementType(SAppElement &elem) = 0; + virtual eastl::string GetElementId(SAppElement &elem) = 0; + virtual bool IsComponent(SAppElement &elem) = 0; + virtual Q3DStudio::TAttOrArgList GetElementAttributes(SAppElement &elem) = 0; + // These are found either on the slide or on the component depending on if you are working + // in uip space or runtime space. + virtual Q3DStudio::TAttOrArgList GetSlideAttributes() = 0; + virtual eastl::vector + GetElementAttributeInitialValues(SAppElement &elem) = 0; + virtual eastl::vector GetElementChildren(SAppElement &elem) = 0; + + virtual eastl::string GetLastLoadingErrorString() = 0; + + virtual NVFoundationBase &GetFoundation() = 0; + virtual IStringTable &GetStringTable() = 0; + + // inPath may either exist or not. You can pass in a uip file as well as a uia file. + // application dir is so we can find the meta data. + // inStream provides a way to load from memory, it will be used if it's not NULL. + static IDatamodel &Create(qt3ds::state::editor::TFoundationPtr inFoundation, + const TEditorStr &inPath, const TEditorStr &inApplicationDir, + IStateMachineEditorManager &inStateMachineEditorManager, + IInStream *inStream = 0); + static IDatamodel &Create(qt3ds::state::editor::TFoundationPtr inFoundation, + const TEditorStr &inPath, const TEditorStr &inApplicationDir, + IStateMachineEditorManager &inStateMachineEditorManager, + IStringTable &inStringTable, IInStream *inStream = 0); + }; + + typedef NVScopedRefCounted TDatamodelPtr; +} +} +#endif diff --git a/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodelValue.h b/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodelValue.h new file mode 100644 index 00000000..7698809c --- /dev/null +++ b/src/Runtime/Source/stateapplication/editor/Qt3DSUIADatamodelValue.h @@ -0,0 +1,291 @@ +/**************************************************************************** +** +** Copyright (C) 2013 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef UIA_DATAMODEL_VALUE_H +#define UIA_DATAMODEL_VALUE_H +#include "foundation/Qt3DSDiscriminatedUnion.h" +#include "Qt3DSUIADatamodel.h" + +namespace qt3ds { +namespace app { + + using namespace Q3DStudio; + + template + struct SDatamodelValueTypeMap + { + }; + +#define QT3DS_UIA_DATAMODEL_TYPE_MAP(type, enumname) \ + template <> \ + struct SDatamodelValueTypeMap \ + { \ + static Q3DStudio::ERuntimeDataModelDataType GetType() { return Q3DStudio::enumname; } \ + }; + + struct SGuid + { + long m_Data[4]; + }; + + struct SObjectRef + { + CRegisteredString m_Presentation; + CRegisteredString m_Id; + }; + + class CStringOrInt + { + bool m_IsString; + CRegisteredString m_String; + int m_IntValue; + + public: + CStringOrInt(CRegisteredString val = CRegisteredString()) + : m_IsString(true) + , m_String(val) + , m_IntValue(0) + { + } + CStringOrInt(int val) + : m_IsString(false) + , m_IntValue(val) + { + } + CStringOrInt(const CStringOrInt &other) + : m_IsString(other.m_IsString) + , m_String(other.m_String) + , m_IntValue(other.m_IntValue) + { + } + CStringOrInt &operator=(const CStringOrInt &other) + { + m_IsString = other.m_IsString; + m_String = other.m_String; + m_IntValue = other.m_IntValue; + return *this; + } + bool IsString() const { return m_IsString; } + CRegisteredString StringValue() const + { + QT3DS_ASSERT(m_IsString); + return m_String; + } + int IntValue() const + { + QT3DS_ASSERT(m_IsString == false); + return m_IntValue; + } + }; + + QT3DS_UIA_DATAMODEL_TYPE_MAP(float, ERuntimeDataModelDataTypeFloat); + QT3DS_UIA_DATAMODEL_TYPE_MAP(QT3DSVec2, ERuntimeDataModelDataTypeFloat2); + QT3DS_UIA_DATAMODEL_TYPE_MAP(QT3DSVec3, ERuntimeDataModelDataTypeFloat3); + QT3DS_UIA_DATAMODEL_TYPE_MAP(QT3DSI32, ERuntimeDataModelDataTypeLong); + QT3DS_UIA_DATAMODEL_TYPE_MAP(eastl::string, ERuntimeDataModelDataTypeString); + QT3DS_UIA_DATAMODEL_TYPE_MAP(bool, ERuntimeDataModelDataTypeBool); + QT3DS_UIA_DATAMODEL_TYPE_MAP(SGuid, ERuntimeDataModelDataTypeLong4); + QT3DS_UIA_DATAMODEL_TYPE_MAP(CRegisteredString, ERuntimeDataModelDataTypeStringRef); + QT3DS_UIA_DATAMODEL_TYPE_MAP(SObjectRef, ERuntimeDataModelDataTypeObjectRef); + QT3DS_UIA_DATAMODEL_TYPE_MAP(CStringOrInt, ERuntimeDataModelDataTypeStringOrInt); + + struct SDatamodelValueUnionTraits + { + typedef ERuntimeDataModelDataType TIdType; + enum { + TBufferSize = sizeof(eastl::string), + }; + + static TIdType getNoDataId() { return ERuntimeDataModelDataTypeNone; } + + template + static TIdType getType() + { + return SDatamodelValueTypeMap().GetType(); + } + + template + static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case ERuntimeDataModelDataTypeFloat: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeFloat2: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeFloat3: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeLong: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeString: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeBool: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeLong4: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeStringRef: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeObjectRef: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeStringOrInt: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case ERuntimeDataModelDataTypeNone: + return inVisitor(); + } + } + + template + static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor) + { + switch (inType) { + case ERuntimeDataModelDataTypeFloat: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeFloat2: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeFloat3: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeLong: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeString: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeBool: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeLong4: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeStringRef: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeObjectRef: + return inVisitor(*NVUnionCast(inData)); + case ERuntimeDataModelDataTypeStringOrInt: + return inVisitor(*NVUnionCast(inData)); + default: + QT3DS_ASSERT(false); + case ERuntimeDataModelDataTypeNone: + return inVisitor(); + } + } + }; +} +} + +// need some specializations in the original nv foundation namespace +namespace qt3ds { +namespace foundation { + + template <> + struct DestructTraits + { + void destruct(qt3ds::app::SGuid &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::app::SObjectRef &) {} + }; + template <> + struct DestructTraits + { + void destruct(qt3ds::app::CStringOrInt &) {} + }; + template <> + struct DestructTraits + { + void destruct(CRegisteredString &) {} + }; +} +} + +namespace qt3ds { +namespace app { + + typedef qt3ds::foundation:: + DiscriminatedUnion, + SDatamodelValueUnionTraits::TBufferSize> + TDatamodelUnionType; + + struct SDatamodelValue : public TDatamodelUnionType + { + SDatamodelValue() {} + SDatamodelValue(const SDatamodelValue &other) + : TDatamodelUnionType(static_cast(other)) + { + } + SDatamodelValue(float other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(QT3DSVec2 other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(QT3DSVec3 other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(QT3DSI32 other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(const eastl::string &other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(bool other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(SGuid other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(CRegisteredString other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(SObjectRef other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue(CStringOrInt other) + : TDatamodelUnionType(other) + { + } + SDatamodelValue &operator=(const SDatamodelValue &other) + { + TDatamodelUnionType::operator=(other); + return *this; + } + }; +} +} +#endif diff --git a/src/Runtime/Source/system/Qt3DSArray.h b/src/Runtime/Source/system/Qt3DSArray.h new file mode 100644 index 00000000..805b8b0a --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSArray.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSMemorySettings.h" +#include "Qt3DSMemory.h" +#include "Qt3DSPlatformSpecific.h" + +#ifdef WIN32 +#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy + // constructor is inaccessible +#pragma warning(disable : 4626) // assignment operator could not be generated because a base class + // assignment operator is inaccessible +#endif + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +#define NVARRAY_NOTFOUND -1 + +//============================================================================== +/** + * Ordered Collection also knows as a vector. + * + * Use Reserve or the constructor parameter if you know how many slots + * will be needed to prevent frequent reallocations during growth. + * + * The array grows by DEFAULT_GROWFACTOR aka 20% whenever it overflows. By + * setting the factor to 0 it will still clamp to 1 and instead grow the + * array by one slot at a time. This is not ideal but given a pooled memory + * manager you will not thrash memory too much since you will grow inside + * each pool chunk and only reallocate when switching pools. + * + * Naming of CArray instances are used to enable memory tracking of arrays + * that have gone berzerk or less frequently used instances that could be + * released after usage. + * + * The FOR_ARRAY macro is the preferred way to process all array slots. + */ +template +class CArray +{ +//============================================================================== +// Constants +//============================================================================== +#define DEFAULT_GROWFACTOR 1.2f + + //============================================================================== + // Types + //============================================================================== +public: + typedef T TType; ///< Easy access to template type + + //============================================================================== + // Fields + //============================================================================== +protected: + CHAR m_Name[32]; ///< Allows easy ID using memory reporting + T *m_Data; ///< Allocated memory containing array data + INT32 m_Capacity; ///< Max number of slots possible + INT32 m_Count; ///< Current number of slots in array + FLOAT m_GrowFactor; ///< Factor by which array grows when out of space + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + inline CArray(const INT32 inCapacity = 0, const FLOAT inGrowFactor = DEFAULT_GROWFACTOR, + const CHAR *inName = NULL); + inline CArray(const CArray &); + inline ~CArray(); + +public: // Management + inline void SetName(const CHAR *inName = NULL); + inline INT32 GetCount() const; + inline INT32 GetCapacity() const; + inline void Clear(const BOOL inRelease = true); + inline void Reserve(const INT32 inCapacity, const BOOL inExpand = false); + +public: // Stack access + void Push(const T &inValue); + inline const T &Pop(); + inline const T &Top() const; + +public: // Random access + inline INT32 GetIndex(const T &inValue) const; + inline T &operator[](const INT32 inIndex) const; + inline void Remove(const INT32 inIndex); + +public: // FOR_ARRAY iteration + inline T *Begin() const; + inline T *End() const; + +private: // Disabled Copy Construction + inline CArray &operator=(const CArray &); +}; + +} // namespace Q3DStudio + +//============================================================================== +// Template code +//============================================================================== +#include "Qt3DSArray.inl" diff --git a/src/Runtime/Source/system/Qt3DSArray.inl b/src/Runtime/Source/system/Qt3DSArray.inl new file mode 100644 index 00000000..a9667fd2 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSArray.inl @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2007 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + * + * @param inCapacity preallocated number of slots to avoid growth reallocation + * @param inGrowFactor factor by which the array grows when out of space + * @param inName 32 byte unique identifier for memory tracking + */ +template inline +CArray::CArray( const INT32 inCapacity, const FLOAT inGrowFactor, const CHAR* inName ) : + m_Data( NULL ), + m_Capacity( 0 ), + m_Count( 0 ), + m_GrowFactor( inGrowFactor ) +{ + // Disallow negative growth + if ( m_GrowFactor < 1.0f ) + m_GrowFactor = DEFAULT_GROWFACTOR; + + SetName( inName ); + Reserve( inCapacity ); +} + +//============================================================================== +/** + * Berger's Copy Constructor. + */ +template inline +CArray::CArray( const CArray& inOther ) : + m_Data( NULL ), + m_Capacity( 0 ), + m_Count( 0 ), + m_GrowFactor( inOther.m_GrowFactor ) +{ + // Disallow negative growth + if ( m_GrowFactor < 1.0f ) + m_GrowFactor = DEFAULT_GROWFACTOR; + + SetName( inOther.m_Name ); + Reserve( inOther.m_Capacity ); + FOR_ARRAY( T, theTemp, inOther ) + { + Push( *theTemp ); + } +} + +//============================================================================== +/** + * Destructor + */ +template inline +CArray::~CArray( ) +{ + Clear( true ); +} + +//============================================================================== +/** + * Name an array instance to easily identify it during memory reporting. + * @param inName 32 byte unique identifier + */ +template inline +void CArray::SetName( const CHAR* inName /*= NULL*/ ) +{ + Q3DStudio_sprintf( m_Name, sizeof( m_Name ), "%s", inName ? inName : "CArray" ); +} + +//============================================================================== +/** + * Count is the number of elements in the array. + * @return current count of the array + */ +template inline +INT32 CArray::GetCount( ) const +{ + return m_Count; +} + +//============================================================================== +/** + * Get the capacity of the array + * Capacity reflects the max count before reallocation happens. + * @return capacity of the array + */ +template inline +INT32 CArray::GetCapacity( ) const +{ + return m_Capacity; +} + +//============================================================================== +/** + * Clear the array by reducing the number of elements to zero. + * + * Using the release flag keeps the memory load low but could be + * suboptimal in situations where you are always using roughly the same + * number of elements. In that scenario, the array would have to build up + * and reallocate up to the same number of elements every time causing + * stress on the system. Clearing but keeping the buffer by setting + * release to false is optimal in that case. + * + * @param inRelease true to release memory, false keeps old buffer + */ +template inline +void CArray::Clear( const BOOL inRelease ) +{ + m_Count = 0; + + if ( inRelease ) + { + Q3DStudio_free( m_Data, T, m_Capacity ); + m_Capacity = 0; + m_Data = NULL; + } + else + Q3DStudio_memset( m_Data, 0 , sizeof( T ) * m_Capacity ); +} + +//============================================================================== +/** + * Allocate enough memory to store T. + * + * If current memory is not sufficient, new block of memory is allocated and + * data in current memory is copied to the new block of memory. Data pointer will + * point to the new block of memory and current memory is released. + * + * @param inCapacity indicate the amount of memory required. + * @param inExpand true to not only allocate but also extend array + */ +template inline +void CArray::Reserve( const INT32 inCapacity, const BOOL inExpand ) +{ + if ( inCapacity > m_Capacity ) + { + T* theData = Q3DStudio_allocate_desc( T, inCapacity, m_Name ); + Q3DStudio_memset( theData, 0 , sizeof( T ) * inCapacity ); + if ( m_Data != NULL ) + { + Q3DStudio_memcpy( theData, m_Data, sizeof( T ) * m_Count ); + Q3DStudio_free( m_Data, T, m_Capacity ); + } + m_Data = theData; + m_Capacity = inCapacity; + } + + if ( inExpand ) + m_Count = inCapacity; +} + +//============================================================================== +/** + * Insert T to the end of the array + * @param inValue value of datatype T + */ +template inline +void CArray::Push( const T& inValue ) +{ + if ( m_Count == m_Capacity ) + Reserve( static_cast( m_GrowFactor * m_Capacity ) + 1 ); + + m_Data[m_Count++] = inValue; +} + +//============================================================================== +/** + * Remove and retrieve T which is at the end of the array + * @return value of datatype T + */ +template inline +const T& CArray::Pop( ) +{ + return m_Data[--m_Count]; +} + +//============================================================================== +/** + * Get T which is at the end of the array + * @return reference of value of datatype T + */ +template inline +const T& CArray::Top( ) const +{ + return m_Data[m_Count - 1]; +} + +//============================================================================== +/** + * Get index of first element that matches inValue + * @return index of element matching T or INDEX_NOTFOUND + */ +template inline +INT32 CArray::GetIndex( const T& inValue ) const +{ + for ( INT32 theIndex = 0; theIndex < m_Count; ++theIndex ) + if ( inValue == m_Data[theIndex] ) + return theIndex; + return NVARRAY_NOTFOUND; +} + +//============================================================================== +/** + * Get the element at a particular index position of the array. + * @note Range checking is only done is debug builds. + * @param inIndex the index of the array + * @return reference of value of datatype T + */ +template inline +T& CArray::operator[]( const INT32 inIndex ) const +{ + Q3DStudio_ASSERT( inIndex >= 0 && inIndex < m_Capacity ); + return m_Data[inIndex]; +} + +//============================================================================== +/** + * Remove T that resides at a particular index position of the array. + * Other T data with higher index value is shifted to occupy the empty slot + * created in the removal process. + * @param inIndex the index of the array + */ +template inline +void CArray::Remove( const INT32 inIndex ) +{ + Q3DStudio_memmove( m_Data + inIndex, m_Data + inIndex + 1, sizeof( T ) * ( m_Count - inIndex - 1 ) ); + --m_Count; +} + +//============================================================================== +/** + * Get T at the first index of the array. + * Mainly used for FOR_ARRAY macro implementation + * @return pointer to first value in array + */ +template inline +T* CArray::Begin( ) const +{ + return m_Data; +} + +//============================================================================== +/** + * Get T at the last index of the array. + * Mainly used for FOR_ARRAY macro implementation + * @return pointer to one beyond last value in array + */ +template inline +T* CArray::End( ) const +{ + return m_Data + m_Count; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSAssert.cpp b/src/Runtime/Source/system/Qt3DSAssert.cpp new file mode 100644 index 00000000..63d38768 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSAssert.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSAssert.h" +#include "foundation/Qt3DSLogging.h" +//============================================================================== +// Platform Specific Includes +//============================================================================== +#if defined(_PCPLATFORM) +#pragma warning(push, 3) +#include +#include +#pragma warning(pop) +#endif // #if defined (_PCPLATFORM) + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Global Variables +//============================================================================== +CAssert::TFunction CAssert::s_AssertFunction = CAssert::Default; ///< Default assert function + +//============================================================================== +/** + * Default method for asserts + */ +void CAssert::Default(const CHAR *inAssert, const CHAR *inFile, INT32 inLine, + const CHAR *inFunction) +{ + // Use logger to report the string first + qCCritical (qt3ds::INTERNAL_ERROR) << "Assertion failed: " << inFile << " " << inLine + << " " << inAssert << " " << inFunction; + +#if defined(_DEBUG) && defined(_PCPLATFORM) && defined(QT3DS_VC) + if (_CrtDbgReport(_CRT_ASSERT, inFile, inLine, inFunction, "Assertion Failed") == 1) + ::DebugBreak(); +#endif // _DEBUG & _PCPLATFORM +} + +//============================================================================== +/** + * Method for setting the assert function + */ +void CAssert::SetFunction(TFunction inAssert) +{ + s_AssertFunction = inAssert; +} + +//============================================================================== +/** + * Method for getting the assert function + */ +CAssert::TFunction CAssert::GetFunction() +{ + return s_AssertFunction; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSAssert.h b/src/Runtime/Source/system/Qt3DSAssert.h new file mode 100644 index 00000000..a64ca7f6 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSAssert.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include "Qt3DSTypes.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Static gateway for all asserts. + * + * By setting your own assert function you can redirect all Runtime asserts. + * By default it uses the internal Default method that uses CLog for output + * and displays a dialog on Windows PCs. + */ +class CAssert +{ + //============================================================================== + // Typedefs + //============================================================================== +public: + typedef void (*TFunction)(const Q3DStudio::CHAR *inAssert, const Q3DStudio::CHAR *inFile, + Q3DStudio::INT32 inLine, const Q3DStudio::CHAR *inFunction); + + //============================================================================== + // Fields + //============================================================================== +protected: + static TFunction s_AssertFunction; ///< Function pointer to active assert function + + //============================================================================== + // Methods + //============================================================================== +private: // Hidden Constructor + CAssert(); + +public: // Static Usage + static void Default(const Q3DStudio::CHAR *inAssert, const Q3DStudio::CHAR *inFile, + Q3DStudio::INT32 inLine, const Q3DStudio::CHAR *inFunction); + +public: // Static Configuration + static void SetFunction(TFunction inAssert); + static TFunction GetFunction(); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSAudioPlayer.h b/src/Runtime/Source/system/Qt3DSAudioPlayer.h new file mode 100644 index 00000000..3b6f3ef8 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSAudioPlayer.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +namespace Q3DStudio { + +class IAudioPlayer +{ +public: + virtual ~IAudioPlayer() {} + virtual bool PlaySoundFile(const char *inFilePath) = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSBasicPluginDLL.h b/src/Runtime/Source/system/Qt3DSBasicPluginDLL.h new file mode 100644 index 00000000..63a2d1f6 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSBasicPluginDLL.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//============================================================================== +// Includes +//============================================================================== +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================== +// Enums +//============================================================================== +typedef enum _EDLLSTATUS { EDLLSTATUS_FAIL = 0, EDLLSTATUS_OK } EDLLSTATUS; + +// GetPluginType should return this +typedef enum _EDLLTYPE { + EDLLTYPE_UNKNOWN = 0, + EDLLTYPE_RENDERABLE_PLUGIN, + EDLLTYPE_CUSTOM_OBJECT, +} EDLLTYPE; + +//============================================================================== +// Function declarations +//============================================================================== + +//============================================================================== +/** + * Return the plugin type. + * @return plugin type + */ +typedef long (*PROC_GetPluginType)(); +Q_DECL_EXPORT long GetPluginType(); + +#ifdef __cplusplus +} +#endif diff --git a/src/Runtime/Source/system/Qt3DSBezierEval.h b/src/Runtime/Source/system/Qt3DSBezierEval.h new file mode 100644 index 00000000..c4d733a3 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSBezierEval.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +namespace Q3DStudio { + +//============================================================================== +/** + * Generic Bezier parametric curve evaluation at a given parametric value. + * @param inP0 control point P0 + * @param inP1 control point P1 + * @param inP2 control point P2 + * @param inP3 control point P3 + * @param inS the variable + * @return the evaluated value on the bezier curve + */ +inline FLOAT EvaluateBezierCurve(FLOAT inP0, FLOAT inP1, FLOAT inP2, FLOAT inP3, const FLOAT inS) +{ + // Using: + // Q(s) = Sum i=0 to 3 ( Pi * Bi,3(s)) + // where: + // Pi is a control point and + // Bi,3 is a basis function such that: + // + // B0,3(s) = (1 - s)^3 + // B1,3(s) = (3 * s) * (1 - s)^2 + // B2,3(s) = (3 * s^2) * (1 - s) + // B3,3(s) = s^3 + + /* FLOAT theSSquared = inS * inS; // + t^2 + FLOAT theSCubed = theSSquared * inS; // + t^3 + + FLOAT theSDifference = 1 - inS; // (1 - + t) + FLOAT theSDifferenceSquared = theSDifference * theSDifference; // (1 - + t)^2 + FLOAT theSDifferenceCubed = theSDifferenceSquared * theSDifference; // (1 - t)^3 + + FLOAT theFirstTerm = theSDifferenceCubed; // (1 - + t)^3 + FLOAT theSecondTerm = ( 3 * inS ) * theSDifferenceSquared; // (3 * t) * (1 + - t)^2 + FLOAT theThirdTerm = ( 3 * theSSquared ) * theSDifference; // (3 * t^2) * + (1 - t) + FLOAT theFourthTerm = theSCubed; // + t^3 + + // Q(t) = ( p0 * (1 - t)^3 ) + ( p1 * (3 * t) * (1 - t)^2 ) + ( p2 * (3 * t^2) * (1 - t) + ) + ( p3 * t^3 ) + return ( inP0 * theFirstTerm ) + ( inP1 * theSecondTerm ) + ( inP2 * theThirdTerm ) + ( + inP3 * theFourthTerm );*/ + + FLOAT theFactor = inS * inS; + inP1 *= 3 * inS; + inP2 *= 3 * theFactor; + theFactor *= inS; + inP3 *= theFactor; + + theFactor = 1 - inS; + inP2 *= theFactor; + theFactor *= 1 - inS; + inP1 *= theFactor; + theFactor *= 1 - inS; + inP0 *= theFactor; + + return inP0 + inP1 + inP2 + inP3; +} + +//============================================================================== +/** + * Inverse Bezier parametric curve evaluation to get parametric value for a given output. + * This is equal to finding the root(s) of the Bezier cubic equation. + * @param inP0 control point P0 + * @param inP1 control point P1 + * @param inP2 control point P2 + * @param inP3 control point P3 + * @param inX the variable + * @return the evaluated value + */ +inline FLOAT EvaluateInverseBezierCurve(const FLOAT inP0, const FLOAT inP1, const FLOAT inP2, + const FLOAT inP3, const FLOAT inX) +{ + FLOAT theResult = 0; + + // Using: + // Q(s) = Sum i=0 to 3 ( Pi * Bi,3(s)) + // where: + // Pi is a control point and + // Bi,3 is a basis function such that: + // + // B0,3(s) = (1 - s)^3 + // B1,3(s) = (3 * s) * (1 - s)^2 + // B2,3(s) = (3 * s^2) * (1 - s) + // B3,3(s) = s^3 + + // The Bezier cubic equation: + // inX = inP0*(1-s)^3 + inP1*(3*s)*(1-s)^2 + inP2*(3*s^2)*(1-s) + inP3*s^3 + // = s^3*( -inP0 + 3*inP1 - 3*inP2 +inP3 ) + s^2*( 3*inP0 - 6*inP1 + 3*inP2 ) + s*( -3*inP0 + // + 3*inP1 ) + inP0 + // For cubic eqn of the form: c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 = 0 + FLOAT theConstants[4]; + theConstants[0] = static_cast(inP0 - inX); + theConstants[1] = static_cast(-3 * inP0 + 3 * inP1); + theConstants[2] = static_cast(3 * inP0 - 6 * inP1 + 3 * inP2); + theConstants[3] = static_cast(-inP0 + 3 * inP1 - 3 * inP2 + inP3); + + FLOAT theSolution[3] = { 0 }; + + if (theConstants[3] == 0) { + if (theConstants[2] == 0) { + if (theConstants[1] == 0) + theResult = 0; + else + theResult = -theConstants[0] / theConstants[1]; // linear + } else { + // quadratic + INT32 theNumRoots = CCubicRoots::SolveQuadric(theConstants, theSolution); + theResult = static_cast(theSolution[theNumRoots / 2]); + } + } else { + INT32 theNumRoots = CCubicRoots::SolveCubic(theConstants, theSolution); + theResult = static_cast(theSolution[theNumRoots / 3]); + } + + return theResult; +} + +inline FLOAT EvaluateBezierKeyframe(FLOAT inTime, FLOAT inTime1, FLOAT inValue1, FLOAT inC1Time, + FLOAT inC1Value, FLOAT inC2Time, FLOAT inC2Value, FLOAT inTime2, + FLOAT inValue2) +{ + + // The special case of C1Time=0 and C2Time=0 is used to indicate Studio-native animation. + // Studio uses a simplified version of the bezier animation where the time control points + // are equally spaced between the starting and ending times. This avoids calling the expensive + // InverseBezierCurve function to find the right 's' given 't'. + FLOAT theParameter; + if (inC1Time == 0 && inC2Time == 0) { + // Special case signaling that it's ok to treat time as "s" + // This is done by assuming that Key1Val,Key1C1,Key1C2,Key2Val (aka P0,P1,P2,P3) + // are evenly distributed over time. + theParameter = (inTime - inTime1) / (inTime2 - inTime1); + } else { + // Compute the "s" parameter on the Bezier given the time + theParameter = EvaluateInverseBezierCurve(inTime1, inC1Time, inC2Time, inTime2, inTime); + if (theParameter <= 0.0f) + return inValue1; + if (theParameter >= 1.0f) + return inValue2; + } + + return EvaluateBezierCurve(inValue1, inC1Value, inC2Value, inValue2, theParameter); +} +} diff --git a/src/Runtime/Source/system/Qt3DSBoundingBox.cpp b/src/Runtime/Source/system/Qt3DSBoundingBox.cpp new file mode 100644 index 00000000..2a9331d1 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSBoundingBox.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSBoundingBox.h" +#include "Qt3DSMatrix.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor - creates an empty BoundingBox + */ +CBoundingBox::CBoundingBox() + : m_Min(1.0f, 1.0f, 1.0f) + , m_Max(-1.0f, -1.0f, -1.0f) +{ +} + +//============================================================================== +/** + * Make BoundingBox invalid + */ +void CBoundingBox::SetEmpty() +{ + m_Min.Set(1.0f, 1.0f, 1.0f); + m_Max.Set(-1.0f, -1.0f, -1.0f); +} + +//============================================================================== +/** + * Is the BoundingBox empty? + * @return true if bounding box is empty, false otherwise + */ +BOOL CBoundingBox::IsEmpty() const +{ + return (m_Min.m_X > m_Max.m_X); +} + +//============================================================================== +/** + * Add a point to the BoundingBox + * @param inPoint a 3D point + */ +void CBoundingBox::Add(const RuntimeVector3 &inPoint) +{ + if (IsEmpty()) { + m_Min = inPoint; + m_Max = inPoint; + } else { + m_Min.Minimize(inPoint); + m_Max.Maximize(inPoint); + } +} + +//============================================================================== +/** + * Add another BoundingBox to this BoundingBox + * @param inBox a 3D BoundingBox + */ +void CBoundingBox::Add(const CBoundingBox &inBox) +{ + if (!inBox.IsEmpty()) { + Add(inBox.GetMin()); + Add(inBox.GetMax()); + } +} + +//============================================================================== +/** + * Get the bounding box's smallest position + * @return the smallest position of the bounding box + */ +const RuntimeVector3 &CBoundingBox::GetMin() const +{ + return m_Min; +} + +//============================================================================== +/** + * Get the bounding box's largest position + * @return the largest position of the bounding box + */ +const RuntimeVector3 &CBoundingBox::GetMax() const +{ + return m_Max; +} + +//============================================================================== +/** + * Apply a transform to the BoundingBox + * @param inMatrix a 4x4 trasnform matrix + */ +void CBoundingBox::Transform(const RuntimeMatrix &inMatrix) +{ + // Apply transform to the 8 corners of the BoundingBox and renormalize to majox axes + CBoundingBox theTransformedBox; + RuntimeVector3 theCorners[8]; + + theCorners[0].Set(m_Min.m_X, m_Min.m_Y, m_Min.m_Z); + theCorners[1].Set(m_Min.m_X, m_Min.m_Y, m_Max.m_Z); + theCorners[2].Set(m_Min.m_X, m_Max.m_Y, m_Min.m_Z); + theCorners[3].Set(m_Min.m_X, m_Max.m_Y, m_Max.m_Z); + theCorners[4].Set(m_Max.m_X, m_Min.m_Y, m_Min.m_Z); + theCorners[5].Set(m_Max.m_X, m_Min.m_Y, m_Max.m_Z); + theCorners[6].Set(m_Max.m_X, m_Max.m_Y, m_Min.m_Z); + theCorners[7].Set(m_Max.m_X, m_Max.m_Y, m_Max.m_Z); + + for (INT32 theIndex = 0; theIndex < 8; ++theIndex) { + theCorners[theIndex].Transform(inMatrix); + theTransformedBox.Add(theCorners[theIndex]); + } + *this = theTransformedBox; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSBoundingBox.h b/src/Runtime/Source/system/Qt3DSBoundingBox.h new file mode 100644 index 00000000..988a9ba8 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSBoundingBox.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSVector3.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class RuntimeMatrix; + +//============================================================================== +/** + * Axis aligned 3D bounding box construction and manipulation. + * + * Initial construction creates an inverted box signifying an Empty box instead + * of an infinitely small box at 0,0,0. Keep this in mind when asking for + * Min or max on a box that has had no points added to it. + * + * Transforming a box simply transforms all eight corners to span a new + * axis aligned bounding box. Successive transformations can thus create a + * non-optimal box, much larger than needed. + */ +class CBoundingBox +{ + //============================================================================== + // Fields + //============================================================================== +public: + RuntimeVector3 m_Min; ///< box minimum corner point + RuntimeVector3 m_Max; ///< box maximum corner point + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CBoundingBox(); + +public: // Functions + BOOL IsEmpty() const; + void SetEmpty(); + void Add(const RuntimeVector3 &inPoint); + void Add(const CBoundingBox &inBox); + const RuntimeVector3 &GetMin() const; + const RuntimeVector3 &GetMax() const; + void Transform(const RuntimeMatrix &inMatrix); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSCircularArray.h b/src/Runtime/Source/system/Qt3DSCircularArray.h new file mode 100644 index 00000000..be921673 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSCircularArray.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Circular array. Not growable for now. + * The "streamlined" interface acts like a resource pool where construction of + * item T is minimized. + */ +template +class CCircularArray +{ + //============================================================================== + // Types + //============================================================================== +public: + typedef T TType; ///< Easy access to template type + + //============================================================================== + // Fields + //============================================================================== +protected: + CHAR m_Name[32]; ///< Allows easy ID if it grows too much + T *m_Data; ///< Allocated memory containing array data + INT32 m_Capacity; ///< Max number of elements possible + INT32 m_Count; ///< Current number of elements in array + + INT32 m_Begin; ///< circular list indices + INT32 m_End; ///< circular list indices + + // For 32-bit alignment + BOOL m_Full; ///< flag to indicate circular list is full + BOOL m_Paddings[3]; ///< Padding + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + inline CCircularArray(const INT32 inCapacity = 0, const CHAR *inName = NULL); + inline ~CCircularArray(); + +public: // Management + inline INT32 GetCount() const; + inline INT32 GetCapacity() const; + inline void Clear(const BOOL inRelease = false); + inline void Reserve(const INT32 inCapacity); + +public: // Stack access + inline T &NewEntry(); + inline void Pop(); + inline T &Top(); + +public: // Status + BOOL IsEmpty() const; + BOOL IsFull() const; + +protected: // Internal methods + void Increment(INT32 &outIndex); + void Decrement(INT32 &outIndex); + void UpdateFullStatus(); +}; + +} // namespace Q3DStudio + +//============================================================================== +// Template code +//============================================================================== +#include "Qt3DSCircularArray.inl" diff --git a/src/Runtime/Source/system/Qt3DSCircularArray.inl b/src/Runtime/Source/system/Qt3DSCircularArray.inl new file mode 100644 index 00000000..0d7f081f --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSCircularArray.inl @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2007 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + */ +template inline +CCircularArray::CCircularArray( const INT32 inCapacity, const CHAR* inName ) : + m_Data( NULL ), + m_Capacity( 0 ), + m_Count( 0 ), + m_Begin( 0 ), + m_End( 0 ), + m_Full( false ) +{ + Q3DStudio_sprintf( m_Name, sizeof( m_Name ), "%s", inName ? inName : "CircularArray" ); + Reserve( inCapacity ); +} + +//============================================================================== +/** + * Destructor + */ +template inline +CCircularArray::~CCircularArray( ) +{ + Clear( true ); +} + +//============================================================================== +/** + * Get the number of items in the array + * @return the number of items in the array + */ +template inline +INT32 CCircularArray::GetCount( ) const +{ + return m_Count; +} + +//============================================================================== +/** + * Get the capacity of the array + * @return the capacity of the array + */ +template inline +INT32 CCircularArray::GetCapacity( ) const +{ + return m_Capacity; +} + +//============================================================================== +/** + * Remove all items from the array + * @param inRelease if true, release the allocated memory, if false, reset + * parameters back to zero. + */ +template inline +void CCircularArray::Clear( const BOOL inRelease ) +{ + m_Count = 0; + m_Begin = 0; + m_End = 0; + m_Full = false; + + if ( inRelease ) + { + Q3DStudio_free( m_Data, T, m_Capacity ); + m_Capacity = 0; + m_Data = NULL; + } +} + +//============================================================================== +/** + * Change capacity of the array + * Assume no expansion for circular array + * @param inCapacity the new capacity to set + */ +template inline +void CCircularArray::Reserve( const INT32 inCapacity ) +{ + Q3DStudio_ASSERT( !m_Data ); + T* theData = Q3DStudio_allocate_desc( T, inCapacity, m_Name ); + m_Data = theData; + m_Capacity = inCapacity; +} + +//============================================================================== +/** + * Create a new uninitialized item at the end of the array. + * The returned reference is used to initialize the item. + * @return a reference to the item + */ +template inline +T& CCircularArray::NewEntry( ) +{ + Q3DStudio_ASSERT( !IsFull( ) ); + T& theResult = m_Data[m_End]; + Increment( m_End ); + UpdateFullStatus( ); + ++m_Count; + return theResult; +} + +//============================================================================== +/** + * Remove the top entry from the array + */ +template inline +void CCircularArray::Pop( ) +{ + Q3DStudio_ASSERT( !IsEmpty( ) ); + Increment( m_Begin ); + m_Full = false; + --m_Count; +} + +//============================================================================== +/** + * Get the top item from the + * @return a reference to the item + */ +template inline +T& CCircularArray::Top( ) +{ + Q3DStudio_ASSERT( !IsEmpty( ) ); + return m_Data[m_Begin]; +} + +//============================================================================== +/** + * Check if the array is empty + * @return true if empty, false otherwise. + */ +template inline +BOOL CCircularArray::IsEmpty( ) const +{ + return ( m_Begin == m_End ) && !m_Full; +} + +//============================================================================== +/** + * Check if the array is full + * @return true if full, false otherwise. + */ +template inline +BOOL CCircularArray::IsFull( ) const +{ + return m_Full; +} + +//============================================================================== +/** + * Increment index of the array + * @param outIndex the index to increment + */ +template inline +void CCircularArray::Increment( INT32& outIndex ) +{ + ++outIndex; + // circular list wrap-around + if ( outIndex >= m_Capacity ) + outIndex = 0; +} + +//============================================================================== +/** + * Decrement index of the array + * @param outIndex the index to decrement + */ +template inline +void CCircularArray::Decrement( INT32& outIndex ) +{ + --outIndex; + // circular list wrap-around + if ( outIndex < 0 ) + outIndex = m_Capacity - 1; +} + +//============================================================================== +/** + * Update the status of the m_Full flag. + * This is an internal method for use ONLY AFTER a item has been added to the array. + */ +template inline +void CCircularArray::UpdateFullStatus( ) +{ + m_Full = ( m_End == m_Begin ); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSColor.cpp b/src/Runtime/Source/system/Qt3DSColor.cpp new file mode 100644 index 00000000..a44d488b --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSColor.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSColor.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + * @param inColor 32 bit represenation of the color + */ +CColor::CColor(const Q3DStudio::UINT32 inColor) + : m_Color(inColor) +{ +} + +//============================================================================== +/** + * Constructor + * @param inRed 8 bit represenation of the red component + * @param inGreen 8 bit representation of the green component + * @param inBlue 8 bit representation of the blue component + * @param inAlpha 8 bit representation of the transparency component + */ +CColor::CColor(const UINT8 inRed, const UINT8 inGreen, const UINT8 inBlue, const UINT8 inAlpha) + : m_Red(inRed) + , m_Green(inGreen) + , m_Blue(inBlue) + , m_Alpha(inAlpha) +{ +} + +//============================================================================== +/** + * Set the color to a blend between the two given colors. + * @param inColor1 Color representing factor 0 + * @param inColor2 Color representing factor 1.0 + * @param inFactor Blend factor where 0.5 is an even mix of the two colors + */ +void CColor::Interpolate(const CColor &inColor1, const CColor &inColor2, const FLOAT inFactor) +{ + // m_Red = static_cast( rand() % 256 );//( 1.0f - inFactor ) * inColor1.m_Red + + //inFactor * inColor2.m_Red ); + // m_Green = static_cast( rand() % 256 );//( 1.0f - inFactor ) * inColor1.m_Green + + //inFactor * inColor2.m_Green ); + // m_Blue = static_cast( rand() % 256 );//( 1.0f - inFactor ) * inColor1.m_Blue + + //inFactor * inColor2.m_Blue ); + // m_Alpha = 255;//static_cast( ( 1.0f - inFactor ) * inColor1.m_Alpha + inFactor * + //inColor2.m_Alpha ); + + m_Red = static_cast((1.0f - inFactor) * inColor1.m_Red + inFactor * inColor2.m_Red); + m_Green = + static_cast((1.0f - inFactor) * inColor1.m_Green + inFactor * inColor2.m_Green); + m_Blue = static_cast((1.0f - inFactor) * inColor1.m_Blue + inFactor * inColor2.m_Blue); + m_Alpha = + static_cast((1.0f - inFactor) * inColor1.m_Alpha + inFactor * inColor2.m_Alpha); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSColor.h b/src/Runtime/Source/system/Qt3DSColor.h new file mode 100644 index 00000000..b917f46b --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSColor.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Express a color and transparency using 32 bits. + */ +class CColor +{ + //============================================================================== + // Fields + //============================================================================== +public: + union { + UINT32 m_Color; ///< 32bit representation of the color + struct + { + UINT8 m_Red; ///< Red component 0-255 + UINT8 m_Green; ///< Green component 0-255 + UINT8 m_Blue; ///< Blue component 0-255 + UINT8 m_Alpha; ///< Transparency component 0-255 + }; + }; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CColor(const UINT32 inColor); + CColor(const UINT8 inRed = 255, const UINT8 inGreen = 255, const UINT8 inBlue = 255, + const UINT8 inAlpha = 255); + +public: // Setters + void SetColor(const UINT32 inColor) { m_Color = inColor; } + void SetRed(const UINT8 inRed) { m_Red = inRed; } + void SetGreen(const UINT8 inGreen) { m_Green = inGreen; } + void SetBlue(const UINT8 inBlue) { m_Blue = inBlue; } + void SetAlpha(const UINT8 inAlpha) { m_Alpha = inAlpha; } + +public: // Getters + UINT32 GetColor() const { return m_Color; } + UINT8 GetRed() const { return m_Red; } + UINT8 GetGreen() const { return m_Green; } + UINT8 GetBlue() const { return m_Blue; } + UINT8 GetAlpha() const { return m_Alpha; } + +public: // Utilities + void Interpolate(const CColor &inColor1, const CColor &inColor2, const FLOAT inFactor); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSConfig.h b/src/Runtime/Source/system/Qt3DSConfig.h new file mode 100644 index 00000000..49c644da --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSConfig.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// This file should only contain macros that configure the build environment +// and build options. +//============================================================================== +#include "Qt3DSMemorySettings.h" + +/// Number of chars to evaluate when generating a hash from a string. +/// Verify that hash strings are unique after changing this value. +#ifndef HASH_LIMIT +#define HASH_LIMIT 100 +#endif // HASH_LIMIT + +/// Define this macro use use sync primitives(mutex/critical sections) when accessing +/// shared data structures +#ifndef Q3DStudio_USE_SYNC_PRIMITIVES +#define Q3DStudio_USE_SYNC_PRIMITIVES 1 +#endif // Q3DStudio_USE_SYNC_PRIMITIVES diff --git a/src/Runtime/Source/system/Qt3DSCubicRoots.cpp b/src/Runtime/Source/system/Qt3DSCubicRoots.cpp new file mode 100644 index 00000000..ebcc54b8 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSCubicRoots.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSCubicRoots.h" +#include "Qt3DSDataLogger.h" +#include "Qt3DSCubicRootsImpl.h" diff --git a/src/Runtime/Source/system/Qt3DSCubicRoots.h b/src/Runtime/Source/system/Qt3DSCubicRoots.h new file mode 100644 index 00000000..b5ac0530 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSCubicRoots.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Wrapper class to functions that solve cubic equations. + * + * The function suite is taken from Graphics Gems: + * Roots3And4.c + * + * Utility functions to find cubic and quartic roots, + * coefficients are passed like this: + * + * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0 + * + * The functions return the number of non-complex roots and + * put the values into the s array. + * + * Author: Jochen Schwarze (schwarze@isa.de) + * + * Jan 26, 1990 Version for Graphics Gems + * Oct 11, 1990 Fixed sign problem for negative q's in SolveQuartic + * (reported by Mark Podlipec), + * Old-style function definitions, + * IsZero() as a macro + * Nov 23, 1990 Some systems do not declare acos() and cbrt() in + * , though the functions exist in the library. + * If large coefficients are used, EQN_EPS should be + * reduced considerably (e.g. to 1E-30), results will be + * correct but multiple roots might be reported more + * than once. + */ +class CCubicRoots +{ + //============================================================================== + // Methods + //============================================================================== +public: + static INT32 SolveQuadric(FLOAT inConstants[3], FLOAT outSolutions[2]); + static INT32 SolveCubic(FLOAT inConstants[4], FLOAT outSolutions[3]); + // static int SolveQuartic( FLOAT c[5], FLOAT s[4] ); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSCubicRootsImpl.h b/src/Runtime/Source/system/Qt3DSCubicRootsImpl.h new file mode 100644 index 00000000..8cca59f9 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSCubicRootsImpl.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants used by the functions +//============================================================================== +const FLOAT M_PHI = 3.14159265358979323846f; + +/* epsilon surrounding for near zero values */ +const FLOAT EQN_EPS = 1e-9f; + +#define ISZERO(x) ((x) > -EQN_EPS && (x) < EQN_EPS) + +// cube-root +#ifndef CUBEROOT +#define CUBEROOT(x) \ + ((x) > 0.0 ? static_cast(pow((x), 1.0f / 3.0f)) \ + : ((x) < 0.0 ? -static_cast(pow(-(x), 1.0f / 3.0f)) : 0.0f)) +#endif + +//============================================================================== +/** + * Find the root/s to a quadratic equation. + * + * The equation is of the form: c[2]*x^2 + c[1]*x + c[0] = 0 + * Note that this will fail if c[2] is zero, or this is a linear equation. + * + * @param inConstants The array of constants to the equation; see form above + * @param outSolutions The array of solutions to the equation + * @return the number of solutions for the equation + */ +INT32 CCubicRoots::SolveQuadric(FLOAT inConstants[3], FLOAT outSolutions[2]) +{ +#ifdef _PERF_LOG + PerfLogMathEvent1 thePerfLog(DATALOGGER_CUBICROOT); +#endif + FLOAT theP, theQ, theD; + INT32 theResult = 0; + + /* normal form: x^2 + px + theQ = 0 */ + + theP = inConstants[1] / (2 * inConstants[2]); + theQ = inConstants[0] / inConstants[2]; + + theD = theP * theP - theQ; + + if (ISZERO(theD)) { + outSolutions[0] = -theP; + theResult = 1; + } else if (theD < 0.0f) { + theResult = 0; + } else if (theD > 0.0f) { + FLOAT theSquareRootD = sqrtf(theD); + + outSolutions[0] = theSquareRootD - theP; + outSolutions[1] = -theSquareRootD - theP; + theResult = 2; + } + + return theResult; +} + +//============================================================================== +/** + * Find the root/s to a cubic equation. + * + * The equation is of the form: c[3]*x^3 + c[2]*x^2 + c[1]*x + c[0] = 0 + * Note that this will fail if c[3] is zero, or this is a quadratic equation. + * + * @param inConstants The array of constants to the equation; see form above + * @param outSolutions The array of solutions to the equation + * @return the number of solutions for the equation + */ +INT32 CCubicRoots::SolveCubic(FLOAT inConstants[4], FLOAT outSolutions[3]) +{ +#ifdef _PERF_LOG + PerfLogMathEvent1 thePerfLog(DATALOGGER_CUBICROOT); +#endif + + INT32 theResult; + FLOAT theSubstitute; + FLOAT theVariableA, theVariableB, theVariableC; + FLOAT theASquared, theVariableP, theVariableQ; + FLOAT thePCubed, theVariableD; + + /* normal form: x^3 + Ax^2 + Bx + C = 0 */ + + theVariableA = inConstants[2] / inConstants[3]; + theVariableB = inConstants[1] / inConstants[3]; + theVariableC = inConstants[0] / inConstants[3]; + + /* substitute x = y - A/3 to eliminate quadric term: + x^3 +px + q = 0 */ + + theASquared = theVariableA * theVariableA; + theVariableP = 1.0f / 3.0f * (-1.0f / 3.0f * theASquared + theVariableB); + theVariableQ = 1.0f / 2.0f * (2.0f / 27.0f * theVariableA * theASquared + - 1.0f / 3.0f * theVariableA * theVariableB + theVariableC); + + /* use Cardano's formula */ + + thePCubed = theVariableP * theVariableP * theVariableP; + theVariableD = theVariableQ * theVariableQ + thePCubed; + + if (ISZERO(theVariableD)) { + if (ISZERO(theVariableQ)) /* one triple solution */ + { + outSolutions[0] = 0; + theResult = 1; + } else /* one single and one double solution */ + { + FLOAT theVariableU = CUBEROOT(-theVariableQ); + outSolutions[0] = 2.0f * theVariableU; + outSolutions[1] = -theVariableU; + theResult = 2; + } + } else if (theVariableD < 0.0f) /* Casus irreducibilis: three real solutions */ + { + FLOAT thePhi = 1.0f / 3.0f * static_cast(acos(-theVariableQ / sqrtf(-thePCubed))); + FLOAT theVariableT = 2.0f * sqrtf(-theVariableP); + + outSolutions[0] = theVariableT * static_cast(cos(thePhi)); + outSolutions[1] = -theVariableT * static_cast(cos(thePhi + M_PHI / 3.0f)); + outSolutions[2] = -theVariableT * static_cast(cos(thePhi - M_PHI / 3.0f)); + theResult = 3; + } else /* one real solution */ + { + FLOAT theSquareRootD = sqrtf(theVariableD); + FLOAT theVariableU = CUBEROOT(theSquareRootD - theVariableQ); + FLOAT theVariableV = -CUBEROOT(theSquareRootD + theVariableQ); + + outSolutions[0] = theVariableU + theVariableV; + theResult = 1; + } + + /* resubstitute */ + theSubstitute = 1.0f / 3.0f * theVariableA; + + for (INT32 theIndex = 0; theIndex < theResult; ++theIndex) + outSolutions[theIndex] -= theSubstitute; + + return theResult; +} + +}; // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSDLLManager.cpp b/src/Runtime/Source/system/Qt3DSDLLManager.cpp new file mode 100644 index 00000000..c6f6d80d --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDLLManager.cpp @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//============================================================================== +// Includes +//============================================================================== +#include "SystemPrefix.h" +#include "Qt3DSDLLManager.h" +#include "Qt3DSBasicPluginDLL.h" +#include +#ifdef _LINUXPLATFORM +#include +#endif + +using namespace Q3DStudio; + +//============================================================================== +/** + * Comparator for DLL instances. + * Compares by plugin type and handle + */ +namespace Q3DStudio { +bool operator==(const _SDLLInfo &inInfo1, const _SDLLInfo &inInfo2) +{ + return (inInfo1.m_Type == inInfo2.m_Type) && (inInfo1.m_Handle == inInfo2.m_Handle); +} +} + +//============================================================================== +/** + * Singleton getter + */ +CDLLManager &CDLLManager::GetDLLManager() +{ + static CDLLManager theDLLManager = CDLLManager(); + return theDLLManager; +} + +//============================================================================== +/** + * CTOR + */ +CDLLManager::CDLLManager() +{ +} + +//============================================================================== +/** + * DTOR + */ +CDLLManager::~CDLLManager() +{ +} + +//============================================================================== +/** + * Cleanup + */ +void CDLLManager::Cleanup() +{ + m_LoadedLibraries.Clear(true); +} + +//============================================================================== +/** + * Loads a DLL/shared library given a path to the library plugin and the plugin + * type to expect. + */ +long CDLLManager::LoadLibrary(const char *inLibraryPath, long inPluginType) +{ + long theEmptyIndex = NVARRAY_NOTFOUND; +#ifdef _PCPLATFORM + DLLHANDLE theHandle = ::LoadLibraryA(inLibraryPath); +#endif + +#ifdef _LINUXPLATFORM + DLLHANDLE theHandle = ::dlopen(inLibraryPath, RTLD_NOW); + + if (!theHandle) { + const char *error = ::dlerror(); + qWarning() << "Failed to load shared library, error:" << QStringLiteral("%1, full path: %2").arg(error).arg(inLibraryPath); + } + +#endif + +#ifdef _INTEGRITYPLATFORM + DLLHANDLE theHandle = 0; + qWarning() << "CDLLManager::LoadLibrary handle is zero!"; +#endif + + Q3DStudio_ASSERT(theHandle); + + if (theHandle != NULL) { + SDLLInfo theInfo; + PROC_GetPluginType theProc = + reinterpret_cast(GetProc("GetPluginType", theHandle)); + Q3DStudio_ASSERT(theProc); + + if (theProc) { + theInfo.m_Type = theProc(); + + if (theInfo.m_Type == inPluginType) { + theEmptyIndex = m_LoadedLibraries.GetIndex(theInfo); + theInfo.m_Handle = theHandle; + + if (theEmptyIndex == NVARRAY_NOTFOUND) { + m_LoadedLibraries.Push(theInfo); + theEmptyIndex = m_LoadedLibraries.GetCount() - 1; + } else + m_LoadedLibraries[theEmptyIndex] = theInfo; + } + } + + if (theEmptyIndex == NVARRAY_NOTFOUND) { +#ifdef _PCPLATFORM + ::FreeLibrary(theHandle); +#endif + +#ifdef _LINUXPLATFORM + ::dlclose(theHandle); +#endif + } + } + + return theEmptyIndex; +} + +//============================================================================== +/** + * Unloads a DLL given a handle + */ +void CDLLManager::UnloadLibrary(const long inHandle) +{ + if (inHandle >= 0 && inHandle < m_LoadedLibraries.GetCount()) { +#ifdef _PCPLATFORM + ::FreeLibrary(m_LoadedLibraries[inHandle].m_Handle); +#endif + +#ifdef _LINUXPLATFORM + ::dlclose(m_LoadedLibraries[inHandle].m_Handle); +#endif + + m_LoadedLibraries[inHandle] = SDLLInfo(); + } +} + +//============================================================================== +/** + * Retrieves a DLL proc given the proc name + */ +void *CDLLManager::GetProc(const char *inProcName, long inHandle) +{ + if (inHandle >= 0 && inHandle < m_LoadedLibraries.GetCount()) + return GetProc(inProcName, m_LoadedLibraries[inHandle].m_Handle); + + return NULL; +} + +//============================================================================== +/** + * Retrieves a DLL proc fiven the proc name + */ +void *CDLLManager::GetProc(const char *inProcName, const DLLHANDLE inHandle) +{ +#ifdef _PCPLATFORM +#ifdef QT3DS_VC + return ::GetProcAddress(inHandle, inProcName); +#else + return (void *)(::GetProcAddress(inHandle, inProcName)); +#endif +#endif + +#ifdef _LINUXPLATFORM + return ::dlsym(inHandle, inProcName); +#endif + +#ifdef _INTEGRITYPLATFORM + qWarning() << "CDLLManager::GetProc returns NULL!"; + return NULL; +#endif +} + +//============================================================================== +/** + * Retrieves the plugin type for the DLL + */ +template +EEnumType CDLLManager::GetPluginType(long inHandle) +{ + if (inHandle >= 0 && inHandle < m_LoadedLibraries.GetCount()) + return static_cast(m_LoadedLibraries[inHandle].m_Type); + + return 0; +} diff --git a/src/Runtime/Source/system/Qt3DSDLLManager.h b/src/Runtime/Source/system/Qt3DSDLLManager.h new file mode 100644 index 00000000..d670af2e --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDLLManager.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//============================================================================== +// Includes +//============================================================================== +#pragma once + +#ifdef _PCPLATFORM +#pragma warning(push, 3) +#include +#pragma warning(pop) +#endif + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +#ifdef _PCPLATFORM +typedef HMODULE DLLHANDLE; +#endif + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +typedef void *DLLHANDLE; +#endif + +typedef struct _SDLLInfo +{ + long m_Type; ///< Plugin type + DLLHANDLE m_Handle; ///< DLL handle + + _SDLLInfo() + : m_Type(0) + , m_Handle(NULL) + + { + } + +} SDLLInfo; + +//============================================================================== +/** + * Loads DLLs and queries for DLL functions + */ +class CDLLManager +{ +public: + static CDLLManager &GetDLLManager(); + +protected: + CDLLManager(); + virtual ~CDLLManager(); + +public: + long LoadLibrary(const char *inLibraryPath, long inPluginType); + void UnloadLibrary(const long inHandle); + void *GetProc(const char *inProcName, long inHandle); + template + EEnumType GetPluginType(long inHandle); + void Cleanup(); + +protected: + void *GetProc(const char *inProcName, const DLLHANDLE inHandle); + +protected: + CArray m_LoadedLibraries; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSDataLogger.cpp b/src/Runtime/Source/system/Qt3DSDataLogger.cpp new file mode 100644 index 00000000..2f45f012 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDataLogger.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSDataLogger.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +CDataLogger::SExternalFunctors CDataLogger::m_Functors; +CDataLogger::EDataLoggerLevel CDataLogger::m_LogLevel = CDataLogger::LOG_LEVEL_INVALID; +BOOL CDataLogger::m_Enabled = false; + +// Developers - change out the = NULL to = class::LogEntry to log specific stuff. +template <> +TPerfLogGeneralEvent1::TLogEntryInternal TPerfLogGeneralEvent1::m_InternalLogFunc = NULL; +template <> +TPerfLogGeneralEvent2::TLogEntryInternal TPerfLogGeneralEvent2::m_InternalLogFunc = NULL; + +template <> +TPerfLogRenderEvent1::TLogEntryInternal TPerfLogRenderEvent1::m_InternalLogFunc = NULL; +template <> +TPerfLogSceneEvent1::TLogEntryInternal TPerfLogSceneEvent1::m_InternalLogFunc = NULL; + +template <> +TPerfLogMathEvent1::TLogEntryInternal TPerfLogMathEvent1::m_InternalLogFunc = NULL; +template <> +TPerfLogPresentationEvent1::TLogEntryInternal TPerfLogPresentationEvent1::m_InternalLogFunc = NULL; +template <> +TPerfLogRenderEvent2::TLogEntryInternal TPerfLogRenderEvent2::m_InternalLogFunc = NULL; + +//============================================================================== +/** + * Set the application supplied functors to use for getting time and handling + * the writing out of data + */ +void CDataLogger::SetFunctors(SExternalFunctors inFunctors) +{ + m_Functors = inFunctors; +} + +//============================================================================== +/** +* Call into the specified functors to make stuff happen +*/ +void CDataLogger::LogEntry(UINT32 inEntryEnum, BOOL inStartFlag) +{ + if (m_Enabled && m_Functors.m_GetTimeFunc && m_Functors.m_WriteFunc && m_Functors.m_UserData) { + // Initialize to the correct values + SPerfLogEntry theEntry(inEntryEnum, inStartFlag, + m_Functors.m_GetTimeFunc(m_Functors.m_UserData)); + m_Functors.m_WriteFunc(m_Functors.m_UserData, theEntry); + } +} + +//============================================================================== +/** +* Enable logging +*/ +void CDataLogger::Enable() +{ + SetLogLevel(m_LogLevel); + m_Enabled = true; +} + +//============================================================================== +/** +* Disable logging +*/ +void CDataLogger::Disable() +{ + m_Enabled = false; +} + +//============================================================================== +/** + * XXX + */ +void CDataLogger::SetLogLevel(EDataLoggerLevel inLogLevel) +{ + switch (inLogLevel) { + // No logging + case LOG_LEVEL_NONE: + TPerfLogGeneralEvent1::Disable(); + TPerfLogGeneralEvent2::Disable(); + + TPerfLogRenderEvent1::Disable(); + TPerfLogSceneEvent1::Disable(); + + TPerfLogMathEvent1::Disable(); + TPerfLogPresentationEvent1::Disable(); + TPerfLogRenderEvent2::Disable(); + break; + + case LOG_LEVEL_3: + TPerfLogMathEvent1::Enable(); + TPerfLogPresentationEvent1::Enable(); + TPerfLogRenderEvent2::Enable(); + + case LOG_LEVEL_2: + TPerfLogRenderEvent1::Enable(); + TPerfLogSceneEvent1::Enable(); + + case LOG_LEVEL_1: + TPerfLogGeneralEvent1::Enable(); + TPerfLogGeneralEvent2::Enable(); + break; + + case LOG_LEVEL_INVALID: + default: + m_LogLevel = LOG_LEVEL_INVALID; + return; + break; + } + m_LogLevel = inLogLevel; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSDataLogger.h b/src/Runtime/Source/system/Qt3DSDataLogger.h new file mode 100644 index 00000000..b834edab --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDataLogger.h @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _DATA_LOGGER_H_ +#define _DATA_LOGGER_H_ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTypes.h" +#include "Qt3DSDataLoggerEnums.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +typedef TTimeUnit TDataLoggerTimeUnit; + +//============================================================================== +/** +* The structure that holds all the info we collect +*/ +struct SPerfLogEntry +{ + UINT32 m_EntryEnum : 31; + UINT32 m_StartBool : 1; + + TDataLoggerTimeUnit m_Time; + + SPerfLogEntry(UINT32 inEntryEnum, BOOL inStartFlag, TDataLoggerTimeUnit inTime) + : m_EntryEnum(inEntryEnum) + , m_StartBool(inStartFlag ? 1U : 0U) + , m_Time(inTime) + { + // Make sure our enums never use the high bit + Q3DStudio_ASSERT(false == (inEntryEnum & (1 << 31))); + } +}; + +//============================================================================== +/** +* The stack based helper class that wraps the actually logging of start and end messages +* for use with start/end time logging. +*/ +template +class CPerfLogPairedEventWrapper +{ +public: + typedef void (*TLogEntryInternal)(UINT32 inEntryEnum, BOOL inStartFlag); + +private: + UINT32 m_EntryEnum; + static TLogEntryInternal m_InternalLogFunc; + +private: + static void LogEntry(UINT32 inEntryEnum, BOOL inStartFlag); + +public: + CPerfLogPairedEventWrapper(UINT32 inEntryEnum); + ~CPerfLogPairedEventWrapper(); + + static void Enable(); + static void Disable(); +}; + +//============================================================================== +/** +*/ +class CPerfLogPairedEventWrapperDummy +{ +public: + CPerfLogPairedEventWrapperDummy(UINT32 /*inEntryEnum*/) {} + ~CPerfLogPairedEventWrapperDummy() {} +}; + +// Dummy structs, so we get one 'type' of class per log event +// so we can turn things on and off +struct SPerfLogGeneralEvent1 +{ +}; +struct SPerfLogGeneralEvent2 +{ +}; + +struct SPerfLogRenderEvent1 +{ +}; +struct SPerfLogSceneEvent1 +{ +}; + +struct SPerfLogMathEvent1 +{ +}; +struct SPerfLogPresentationEvent1 +{ +}; +struct SPerfLogRenderEvent2 +{ +}; + +// level 0 +// no profiling at all... + +// level 1 +typedef CPerfLogPairedEventWrapper + TPerfLogGeneralEvent1; // Frame, update presentations, update scene, render scene +typedef CPerfLogPairedEventWrapper + TPerfLogGeneralEvent2; // Event processing and manager updates, +// call frame and slide callbacks, +// opaque, transparent, layer render, finalize drawlist and pick +// level 2 +typedef CPerfLogPairedEventWrapper + TPerfLogRenderEvent1; // More detailed rendering +typedef CPerfLogPairedEventWrapper + TPerfLogSceneEvent1; // More detailed scene update + +// level 3 +typedef CPerfLogPairedEventWrapper TPerfLogMathEvent1; // vector and matrix math +typedef CPerfLogPairedEventWrapper + TPerfLogPresentationEvent1; // More detailed scene update +typedef CPerfLogPairedEventWrapper TPerfLogRenderEvent2; // + +// Defines +#ifdef _PERF_LOG +#define PerfLogGeneralEvent1(inEventID) TPerfLogGeneralEvent1 thePerfLog(inEventID); +#define PerfLogGeneralEvent2(inEventID) TPerfLogGeneralEvent2 thePerfLog(inEventID); + +#define PerfLogRenderEvent1(inEventID) TPerfLogRenderEvent1 thePerfLog(inEventID); +#define PerfLogSceneEvent1(inEventID) TPerfLogSceneEvent1 thePerfLog(inEventID); + +#define PerfLogMathEvent1(inEventID) TPerfLogMathEvent1 thePerfLog(inEventID); +#define PerfLogPresentationEvent1(inEventID) TPerfLogPresentationEvent1 thePerfLog(inEventID); +#define PerfLogRenderEvent2(inEventID) TPerfLogRenderEvent2 thePerfLog(inEventID); +#else +#define PerfLogGeneralEvent1(inEventID) +#define PerfLogGeneralEvent2(inEventID) + +#define PerfLogRenderEvent1(inEventID) +#define PerfLogSceneEvent1(inEventID) + +#define PerfLogMathEvent1(inEventID) +#define PerfLogPresentationEvent1(inEventID) +#define PerfLogRenderEvent2(inEventID) +#endif + +//============================================================================== +/** +*/ +class CDataLogger +{ +private: + // App level function to write this out to a stream/file... set externally + typedef void (*TDataLoggerWriteFunc)(void *inUserData, SPerfLogEntry inEntry); + typedef TDataLoggerTimeUnit (*TGetTimeFunc)(void *inUserData); + +public: + struct SExternalFunctors + { + void *m_UserData; + TDataLoggerWriteFunc m_WriteFunc; + TGetTimeFunc m_GetTimeFunc; + + SExternalFunctors() + : m_UserData(NULL) + , m_WriteFunc(NULL) + , m_GetTimeFunc(NULL) + { + } + }; + + enum EDataLoggerLevel { + LOG_LEVEL_NONE, + LOG_LEVEL_1, + LOG_LEVEL_2, + LOG_LEVEL_3, + LOG_LEVEL_INVALID, // use this if you want to selectively enable or disable loggers + }; + +private: + static SExternalFunctors m_Functors; + static EDataLoggerLevel m_LogLevel; + static BOOL m_Enabled; + +public: + static void SetFunctors(SExternalFunctors inFunctors); + static void LogEntry(UINT32 inEntryEnum, BOOL inStartFlag); + static void Enable(); + static void Disable(); + + static void SetLogLevel(EDataLoggerLevel inLogLevel); +}; + +} // namespace Q3DStudio + +#include "Qt3DSDataLogger.hpp" + +#endif // _DATA_LOGGER_H_ diff --git a/src/Runtime/Source/system/Qt3DSDataLogger.hpp b/src/Runtime/Source/system/Qt3DSDataLogger.hpp new file mode 100644 index 00000000..0900c4a4 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDataLogger.hpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSDataLogger.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** +* Constructor +*/ +template +CPerfLogPairedEventWrapper::CPerfLogPairedEventWrapper(UINT32 inEntryEnum) + : m_EntryEnum(inEntryEnum) +{ + if (m_InternalLogFunc) + m_InternalLogFunc(m_EntryEnum, true); +} + +//============================================================================== +/** +* Destructor +*/ +template +CPerfLogPairedEventWrapper::~CPerfLogPairedEventWrapper() +{ + if (m_InternalLogFunc) + m_InternalLogFunc(m_EntryEnum, false); +} + +//============================================================================== +/** +* Logger functions +*/ +template +void CPerfLogPairedEventWrapper::LogEntry(UINT32 inEntryEnum, BOOL inStartFlag) +{ + CDataLogger::LogEntry(inEntryEnum, inStartFlag); +} + +//============================================================================== +/** + * Enable logging + */ +template +void CPerfLogPairedEventWrapper::Enable() +{ + m_InternalLogFunc = LogEntry; +} + +//============================================================================== +/** +* Disable logging +*/ +template +void CPerfLogPairedEventWrapper::Disable() +{ + m_InternalLogFunc = NULL; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSDataLoggerEnums.h b/src/Runtime/Source/system/Qt3DSDataLoggerEnums.h new file mode 100644 index 00000000..27320e19 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDataLoggerEnums.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _DATA_LOGGER_ENUMS_H_ +#define _DATA_LOGGER_ENUMS_H_ + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +// TODO ah - for now, these are all specific to paired events. Later we will +// extend this to support single events which may or may not have timestamps +// for example, every matrix multiple would log a single event with no time +enum EDataLoggerEvents { + // + DATALOGGER_FRAME, /// Time spent in a application frame ( UpdatePresentations, UpdateScenes, and + /// Render ) + + // DATALOGGER_FRAME + // CRuntime + DATALOGGER_UPDATEPRESENTATIONS, /// Time spent updating all presentations + DATALOGGER_UPDATESCENES, /// Time spent updating all scenes + DATALOGGER_RENDERSCENES, /// Time spent rendering all scenes + + // DATALOGGER_UPDATEPRESENTATIONS + // CPresentation::Update + DATALOGGER_PROCESSEVENTS, /// Time spent in ProcessEventCommandQueue + DATALOGGER_ELEMENTMANAGERUPDATE, /// Time spent in CElementManager::Update doing activate and + /// deactivate scans + DATALOGGER_ANIMATIONMANAGERUPDATE, /// Time spent in CAnimationManager::Update + + // More detailed presentation update + DATALOGGER_PROCESSCOMMAND, /// xxx + DATALOGGER_PROCESSEVENT, /// xxx + DATALOGGER_PROCESSEVENTBUBBLING, /// xxx + + // DATALOGGER_UPDATESCENES + // CScene::Update + DATALOGGER_PROCESSDIRTYLIST, /// Time spent in CScene::ProcessDirtyList + DATALOGGER_CALCULATETRANSFORM, /// Time spent in CScene::CalculateGlobalTransform + DATALOGGER_SCENEUPDATE, /// Time spent in CScene::Update recursion + + // More detailed scene update + DATALOGGER_SCANNODEATTRIBUTES, /// Time + DATALOGGER_PUSHNODE, /// Time + + // DATALOGGER_RENDERSCENES + // CRenderEngine + DATALOGGER_RENDERLAYER, /// Time spent rendering the contents of a layer + DATALOGGER_RENDEROPAQUE, /// Time spent rendering all opaque items + DATALOGGER_RENDERTRANSPARENT, /// Time spent rendering all transparent items + DATALOGGER_FINALIZEDRAWLIST, /// Time spent finalizing the draw list + DATALOGGER_PICK, /// Time spent in pick code + + // More detailed rendering + DATALOGGER_RENDER_SORTDISTANCE, /// asdf + DATALOGGER_RENDER_SETOPACITY, /// asdf + DATALOGGER_RENDER_DRAWMODEL, /// asdf + DATALOGGER_RENDER_DRAWTEXT, /// asdf + DATALOGGER_RENDER_CLEARBUFFER, /// asdf + DATALOGGER_RENDER_ZWRITEENABLE, /// asdf + DATALOGGER_RENDER_CHECKRESIZE, /// asdf + DATALOGGER_RENDER_SETATTRIBUTES, /// asdf + DATALOGGER_RENDER_TEXTUPDATE, /// asdf + DATALOGGER_RENDER_CAMERAUPDATE, /// asdf + + // super specific low level gl calls + DATALOGGER_TEXTURESTATE_APPLY, /// asdf + DATALOGGER_GEOMETRY_DRAW, /// asdf + DATALOGGER_MATERIAL_APPLY, /// asdf + DATALOGGER_SETSHADER, /// asdf + + // vector math + DATALOGGER_VECTOR, /// asdf + DATALOGGER_MATRIX, /// asdf + DATALOGGER_CUBICROOT, /// asdf + + // + DATALOGGER_COUNTERTEST, /// Time spent in counter test code + DATALOGGER_COUNTERTESTX, /// Time spent in counter test code + + DATALOGGEREVENTCOUNT /// Event count +}; + +// CPerfLogPairedEventWrapperx thePerfLog( xxx ); + +} // namespace Q3DStudio + +#endif // _DATA_LOGGER_ENUMS_H_ diff --git a/src/Runtime/Source/system/Qt3DSDataLoggerViewer.h b/src/Runtime/Source/system/Qt3DSDataLoggerViewer.h new file mode 100644 index 00000000..0eaf9f6a --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSDataLoggerViewer.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef AKDATALOGGERVIEWER_H_INCLUDED +#define AKDATALOGGERVIEWER_H_INCLUDED + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTypes.h" +#include "Qt3DSDataLogger.h" +#include "Qt3DSDataLoggerEnums.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { +// Helps interpret and analyse data logger entries +class CDataLoggerViewer +{ +public: + typedef CArray TPerfLogEntryList; + +public: + CDataLoggerViewer(TPerfLogEntryList *inPerfLogEntryList); + CDataLoggerViewer(const char *inFilename); + virtual ~CDataLoggerViewer(); + +public: + float GetAverageTimeInMsForEntry(enum EDataLoggerEvents inEventType); + void ResetPerfLogEntry(enum EDataLoggerEvents inEventType); + void ResetAllEntries(); + +public: + static bool ProcessKeyEvent(char inKey, TPerfLogEntryList *inList); + +protected: + TPerfLogEntryList *m_PerfLogEntryList; + bool m_Dispose; +}; + +} // namespace NVUI + +#endif // AKDATALOGGERVIEWER_H_INCLUDED diff --git a/src/Runtime/Source/system/Qt3DSEGLTimer.h b/src/Runtime/Source/system/Qt3DSEGLTimer.h new file mode 100644 index 00000000..4c9f4ce2 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSEGLTimer.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSTimer.h" +#include "Qt3DSTypes.h" + +// You have to include egl before including this file. + +typedef EGLuint64NV(EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void); +typedef EGLuint64NV(EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void); +extern EGLuint64NV eglSystemTimeFrequency; +extern PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC eglGetSystemTimeFrequencyNVProc; +extern PFNEGLGETSYSTEMTIMENVPROC eglGetSystemTimeNVProc; + +namespace Q3DStudio { + +struct SEGLTimeProvider : public Q3DStudio::ITimeProvider +{ +public: + Q3DStudio::INT64 m_TimeFrequency; + SEGLTimeProvider() + : m_TimeFrequency(0) + { + } + virtual Q3DStudio::INT64 GetCurrentTimeMicroSeconds() + { + // This can be called before EGL is initialized. + if (eglGetSystemTimeFrequencyNVProc == NULL || eglGetSystemTimeNVProc == NULL) + return 0; + + if (!m_TimeFrequency) { + // Time frequency converts to seconds. + m_TimeFrequency = eglGetSystemTimeFrequencyNVProc(); + // We need it to conver to microseconds + m_TimeFrequency = m_TimeFrequency / 1000000ULL; + } + Q3DStudio::INT64 currentTime = eglGetSystemTimeNVProc(); + currentTime = currentTime / m_TimeFrequency; + return currentTime; + } +}; +} \ No newline at end of file diff --git a/src/Runtime/Source/system/Qt3DSEndian.h b/src/Runtime/Source/system/Qt3DSEndian.h new file mode 100644 index 00000000..f8913a72 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSEndian.h @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2010 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Constants +//============================================================================== + +#define QT3DS_LITTLE_ENDIAN false +#define QT3DS_BIG_ENDIAN true diff --git a/src/Runtime/Source/system/Qt3DSEulerAngles.cpp b/src/Runtime/Source/system/Qt3DSEulerAngles.cpp new file mode 100644 index 00000000..7c4364fc --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSEulerAngles.cpp @@ -0,0 +1,390 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include +#include +#include +#include +#include "Qt3DSEulerAngles.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4365) // warnings on conversion from unsigned int to int +#endif + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + */ +CEulerAngleConverter::CEulerAngleConverter() +{ + m_OrderInfoBuffer[0] = '\0'; +} + +//============================================================================== +/** + * Destructor + */ +CEulerAngleConverter::~CEulerAngleConverter() +{ +} + +//============================================================================== +/** + * Constructs a Euler angle & holds it in a EulerAngles struct + * @param theI x rotation ( radians ) + * @param theJ y rotation ( radians ) + * @param theH z rotation ( radians ) + * @param theOrder the order this angle is in namely XYZ( static ), etc. + * use the EulOrd**** macros to generate values + * 0 to 23 is valid + * @return the euler angle + */ +EulerAngles CEulerAngleConverter::Eul_(float theI, float theJ, float theH, int theOrder) +{ + EulerAngles theEulerAngle; + theEulerAngle.x = theI; + theEulerAngle.y = theJ; + theEulerAngle.z = theH; + theEulerAngle.w = (float)theOrder; + return theEulerAngle; +} + +//============================================================================== +/** + * Construct quaternion from Euler angles (in radians). + * @param theEulerAngle incoming angle( radians ) + * @return the Quaternion + */ +Quat CEulerAngleConverter::Eul_ToQuat(EulerAngles theEulerAngle) +{ + Quat theQuaternion; + double a[3], ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + int i, j, k, h, n, s, f; + + EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); + if (f == EulFrmR) { + float t = theEulerAngle.x; + theEulerAngle.x = theEulerAngle.z; + theEulerAngle.z = t; + } + + if (n == EulParOdd) + theEulerAngle.y = -theEulerAngle.y; + + ti = theEulerAngle.x * 0.5; + tj = theEulerAngle.y * 0.5; + th = theEulerAngle.z * 0.5; + + ci = cos(ti); + cj = cos(tj); + ch = cos(th); + + si = sin(ti); + sj = sin(tj); + sh = sin(th); + + cc = ci * ch; + cs = ci * sh; + sc = si * ch; + ss = si * sh; + + if (s == EulRepYes) { + a[i] = cj * (cs + sc); /* Could speed up with */ + a[j] = sj * (cc + ss); /* trig identities. */ + a[k] = sj * (cs - sc); + theQuaternion.w = (float)(cj * (cc - ss)); + } else { + a[i] = cj * sc - sj * cs; + a[j] = cj * ss + sj * cc; + a[k] = cj * cs - sj * sc; + theQuaternion.w = (float)(cj * cc + sj * ss); + } + if (n == EulParOdd) + a[j] = -a[j]; + + theQuaternion.x = (float)a[X]; + theQuaternion.y = (float)a[Y]; + theQuaternion.z = (float)a[Z]; + return theQuaternion; +} + +//============================================================================== +/** + * Construct matrix from Euler angles (in radians). + * @param theEulerAngle incoming angle + * @param theMatrix outgoing matrix + */ +void CEulerAngleConverter::Eul_ToHMatrix(EulerAngles theEulerAngle, HMatrix theMatrix) +{ + double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + int i, j, k, h, n, s, f; + EulGetOrd((unsigned int)theEulerAngle.w, i, j, k, h, n, s, f); + + if (f == EulFrmR) { + float t = theEulerAngle.x; + theEulerAngle.x = theEulerAngle.z; + theEulerAngle.z = t; + } + + if (n == EulParOdd) { + theEulerAngle.x = -theEulerAngle.x; + theEulerAngle.y = -theEulerAngle.y; + theEulerAngle.z = -theEulerAngle.z; + } + + ti = theEulerAngle.x; + tj = theEulerAngle.y; + th = theEulerAngle.z; + + ci = cos(ti); + cj = cos(tj); + ch = cos(th); + + si = sin(ti); + sj = sin(tj); + sh = sin(th); + + cc = ci * ch; + cs = ci * sh; + sc = si * ch; + ss = si * sh; + + if (s == EulRepYes) { + theMatrix[i][i] = (float)cj; + theMatrix[i][j] = (float)(sj * si); + theMatrix[i][k] = (float)(sj * ci); + theMatrix[j][i] = (float)(sj * sh); + theMatrix[j][j] = (float)(-cj * ss + cc); + theMatrix[j][k] = (float)(-cj * cs - sc); + theMatrix[k][i] = (float)(-sj * ch); + theMatrix[k][j] = (float)(cj * sc + cs); + theMatrix[k][k] = (float)(cj * cc - ss); + } else { + theMatrix[i][i] = (float)(cj * ch); + theMatrix[i][j] = (float)(sj * sc - cs); + theMatrix[i][k] = (float)(sj * cc + ss); + theMatrix[j][i] = (float)(cj * sh); + theMatrix[j][j] = (float)(sj * ss + cc); + theMatrix[j][k] = (float)(sj * cs - sc); + theMatrix[k][i] = (float)(-sj); + theMatrix[k][j] = (float)(cj * si); + theMatrix[k][k] = (float)(cj * ci); + } + + theMatrix[W][X] = 0.0; + theMatrix[W][Y] = 0.0; + theMatrix[W][Z] = 0.0; + theMatrix[X][W] = 0.0; + theMatrix[Y][W] = 0.0; + theMatrix[Z][W] = 0.0; + theMatrix[W][W] = 1.0; +} + +//============================================================================== +/** + * Convert matrix to Euler angles (in radians). + * @param theMatrix incoming matrix + * @param theOrder 0-23, use EulOrd**** to generate this value + * @return a set of angles in radians!!!! + */ +EulerAngles CEulerAngleConverter::Eul_FromHMatrix(HMatrix theMatrix, int theOrder) +{ + EulerAngles theEulerAngle; + int i, j, k, h, n, s, f; + + EulGetOrd(theOrder, i, j, k, h, n, s, f); + if (s == EulRepYes) { + double sy = sqrt(theMatrix[i][j] * theMatrix[i][j] + theMatrix[i][k] * theMatrix[i][k]); + if (sy > 16 * FLT_EPSILON) { + theEulerAngle.x = (float)(atan2((double)theMatrix[i][j], (double)theMatrix[i][k])); + theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); + theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], -(double)theMatrix[k][i])); + } else { + theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); + theEulerAngle.y = (float)(atan2((double)sy, (double)theMatrix[i][i])); + theEulerAngle.z = 0; + } + } else { + double cy = sqrt(theMatrix[i][i] * theMatrix[i][i] + theMatrix[j][i] * theMatrix[j][i]); + if (cy > 16 * FLT_EPSILON) { + theEulerAngle.x = (float)(atan2((double)theMatrix[k][j], (double)theMatrix[k][k])); + theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); + theEulerAngle.z = (float)(atan2((double)theMatrix[j][i], (double)theMatrix[i][i])); + } else { + theEulerAngle.x = (float)(atan2(-(double)theMatrix[j][k], (double)theMatrix[j][j])); + theEulerAngle.y = (float)(atan2(-(double)theMatrix[k][i], (double)cy)); + theEulerAngle.z = 0; + } + } + + if (n == EulParOdd) { + theEulerAngle.x = -theEulerAngle.x; + theEulerAngle.y = -theEulerAngle.y; + theEulerAngle.z = -theEulerAngle.z; + } + + if (f == EulFrmR) { + float t = theEulerAngle.x; + theEulerAngle.x = theEulerAngle.z; + theEulerAngle.z = t; + } + theEulerAngle.w = (float)theOrder; + return theEulerAngle; +} + +//============================================================================== +/** + * Convert quaternion to Euler angles (in radians). + * @param theQuaternion incoming quaternion + * @param theOrder 0-23, use EulOrd**** to generate this value + * @return the generated angles ( radians ) + */ +EulerAngles CEulerAngleConverter::Eul_FromQuat(Quat theQuaternion, int theOrder) +{ + HMatrix theMatrix; + double Nq = theQuaternion.x * theQuaternion.x + theQuaternion.y * theQuaternion.y + + theQuaternion.z * theQuaternion.z + theQuaternion.w * theQuaternion.w; + double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; + double xs = theQuaternion.x * s; + double ys = theQuaternion.y * s; + double zs = theQuaternion.z * s; + double wx = theQuaternion.w * xs; + double wy = theQuaternion.w * ys; + double wz = theQuaternion.w * zs; + double xx = theQuaternion.x * xs; + double xy = theQuaternion.x * ys; + double xz = theQuaternion.x * zs; + double yy = theQuaternion.y * ys; + double yz = theQuaternion.y * zs; + double zz = theQuaternion.z * zs; + + theMatrix[X][X] = (float)(1.0 - (yy + zz)); + theMatrix[X][Y] = (float)(xy - wz); + theMatrix[X][Z] = (float)(xz + wy); + theMatrix[Y][X] = (float)(xy + wz); + theMatrix[Y][Y] = (float)(1.0 - (xx + zz)); + theMatrix[Y][Z] = (float)(yz - wx); + theMatrix[Z][X] = (float)(xz - wy); + theMatrix[Z][Y] = (float)(yz + wx); + theMatrix[Z][Z] = (float)(1.0 - (xx + yy)); + theMatrix[W][X] = 0.0; + theMatrix[W][Y] = 0.0; + theMatrix[W][Z] = 0.0; + theMatrix[X][W] = 0.0; + theMatrix[Y][W] = 0.0; + theMatrix[Z][W] = 0.0; + theMatrix[W][W] = 1.0; + + return Eul_FromHMatrix(theMatrix, theOrder); +} + +//============================================================================== +/** + * Dump the Order information + */ +const char *CEulerAngleConverter::DumpOrderInfo() +{ + long theCount = 0; + long theOrder[24]; + char theOrderStr[24][16]; + + ::strcpy(theOrderStr[theCount++], "EulOrdXYZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdXYXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXYs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYXs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYZs"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXYXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZXr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXZYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYZYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXYr"); + ::strcpy(theOrderStr[theCount++], "EulOrdYXZr"); + ::strcpy(theOrderStr[theCount++], "EulOrdZXZr"); + ::strcpy(theOrderStr[theCount++], "EulOrdXYZr"); + ::strcpy(theOrderStr[theCount++], "EulOrdZYZr"); + + theCount = 0; + theOrder[theCount++] = EulOrdXYZs; + theOrder[theCount++] = EulOrdXYXs; + theOrder[theCount++] = EulOrdXZYs; + theOrder[theCount++] = EulOrdXZXs; + theOrder[theCount++] = EulOrdYZXs; + theOrder[theCount++] = EulOrdYZYs; + theOrder[theCount++] = EulOrdYXZs; + theOrder[theCount++] = EulOrdYXYs; + theOrder[theCount++] = EulOrdZXYs; + theOrder[theCount++] = EulOrdZXZs; + theOrder[theCount++] = EulOrdZYXs; + theOrder[theCount++] = EulOrdZYZs; + + theOrder[theCount++] = EulOrdZYXr; + theOrder[theCount++] = EulOrdXYXr; + theOrder[theCount++] = EulOrdYZXr; + theOrder[theCount++] = EulOrdXZXr; + theOrder[theCount++] = EulOrdXZYr; + theOrder[theCount++] = EulOrdYZYr; + theOrder[theCount++] = EulOrdZXYr; + theOrder[theCount++] = EulOrdYXYr; + theOrder[theCount++] = EulOrdYXZr; + theOrder[theCount++] = EulOrdZXZr; + theOrder[theCount++] = EulOrdXYZr; + theOrder[theCount++] = EulOrdZYZr; + + char theSubBuf[256]; + m_OrderInfoBuffer[0] = '\0'; + for (long theIndex = 0; theIndex < 24; ++theIndex) { + ::sprintf(theSubBuf, " %16s - %ld\n ", theOrderStr[theIndex], theOrder[theIndex]); + ::strcat(m_OrderInfoBuffer, theSubBuf); + } + + return m_OrderInfoBuffer; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSEulerAngles.h b/src/Runtime/Source/system/Qt3DSEulerAngles.h new file mode 100644 index 00000000..d0f53c56 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSEulerAngles.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include + +namespace Q3DStudio { +//============================================================================== +// Description +//============================================================================== +// QuatTypes.h - Basic type declarations +// by Ken Shoemake, shoemake@graphics.cis.upenn.edu +// in "Graphics Gems IV", Academic Press, 1994 +typedef struct +{ + float x, y, z, w; +} Quat; /* Quaternion */ +typedef float HMatrix[4][4]; /* Right-handed, for column vectors */ +enum QuatPart { X, Y, Z, W }; +typedef Quat EulerAngles; /* (x,y,z)=ang 1,2,3, w=order code */ + +#define EulFrmS 0 +#define EulFrmR 1 +#define EulFrm(ord) ((unsigned)(ord)&1) +#define EulRepNo 0 +#define EulRepYes 1 +#define EulRep(ord) (((unsigned)(ord) >> 1) & 1) +#define EulParEven 0 +#define EulParOdd 1 +#define EulPar(ord) (((unsigned)(ord) >> 2) & 1) +#define EulSafe "\000\001\002\000" +#define EulNext "\001\002\000\001" +#define EulAxI(ord) ((int)(EulSafe[(((unsigned)(ord) >> 3) & 3)])) +#define EulAxJ(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) == EulParOdd)])) +#define EulAxK(ord) ((int)(EulNext[EulAxI(ord) + (EulPar(ord) != EulParOdd)])) +#define EulAxH(ord) ((EulRep(ord) == EulRepNo) ? EulAxK(ord) : EulAxI(ord)) + +// EulGetOrd unpacks all useful information about order simultaneously. +#define EulGetOrd(ord, i, j, k, h, n, s, f) \ + { \ + unsigned o = ord; \ + f = o & 1; \ + o = o >> 1; \ + s = o & 1; \ + o = o >> 1; \ + n = o & 1; \ + o = o >> 1; \ + i = EulSafe[o & 3]; \ + j = EulNext[i + n]; \ + k = EulNext[i + 1 - n]; \ + h = s ? k : i; \ + } + +// EulOrd creates an order value between 0 and 23 from 4-tuple choices. +#define EulOrd(i, p, r, f) (((((((i) << 1) + (p)) << 1) + (r)) << 1) + (f)) + +// Static axes +// X = 0, Y = 1, Z = 2 ref QuatPart +#define EulOrdXYZs EulOrd(0, EulParEven, EulRepNo, EulFrmS) +#define EulOrdXYXs EulOrd(0, EulParEven, EulRepYes, EulFrmS) +#define EulOrdXZYs EulOrd(0, EulParOdd, EulRepNo, EulFrmS) +#define EulOrdXZXs EulOrd(0, EulParOdd, EulRepYes, EulFrmS) +#define EulOrdYZXs EulOrd(1, EulParEven, EulRepNo, EulFrmS) +#define EulOrdYZYs EulOrd(1, EulParEven, EulRepYes, EulFrmS) +#define EulOrdYXZs EulOrd(1, EulParOdd, EulRepNo, EulFrmS) +#define EulOrdYXYs EulOrd(1, EulParOdd, EulRepYes, EulFrmS) +#define EulOrdZXYs EulOrd(2, EulParEven, EulRepNo, EulFrmS) +#define EulOrdZXZs EulOrd(2, EulParEven, EulRepYes, EulFrmS) +#define EulOrdZYXs EulOrd(2, EulParOdd, EulRepNo, EulFrmS) +#define EulOrdZYZs EulOrd(2, EulParOdd, EulRepYes, EulFrmS) + +// Rotating axes +#define EulOrdZYXr EulOrd(0, EulParEven, EulRepNo, EulFrmR) +#define EulOrdXYXr EulOrd(0, EulParEven, EulRepYes, EulFrmR) +#define EulOrdYZXr EulOrd(0, EulParOdd, EulRepNo, EulFrmR) +#define EulOrdXZXr EulOrd(0, EulParOdd, EulRepYes, EulFrmR) +#define EulOrdXZYr EulOrd(1, EulParEven, EulRepNo, EulFrmR) +#define EulOrdYZYr EulOrd(1, EulParEven, EulRepYes, EulFrmR) +#define EulOrdZXYr EulOrd(1, EulParOdd, EulRepNo, EulFrmR) +#define EulOrdYXYr EulOrd(1, EulParOdd, EulRepYes, EulFrmR) +#define EulOrdYXZr EulOrd(2, EulParEven, EulRepNo, EulFrmR) +#define EulOrdZXZr EulOrd(2, EulParEven, EulRepYes, EulFrmR) +#define EulOrdXYZr EulOrd(2, EulParOdd, EulRepNo, EulFrmR) +#define EulOrdZYZr EulOrd(2, EulParOdd, EulRepYes, EulFrmR) + +#ifndef M_PI +#define M_PI 3.1415926535898 +#endif + +#define TODEG(x) x = (float)(x * 180 / M_PI); +#define TORAD(x) x = (float)(x / 180 * M_PI); + +class CEulerAngleConverter +{ +private: + char m_OrderInfoBuffer[1024]; + +public: + CEulerAngleConverter(); + virtual ~CEulerAngleConverter(); + +public: + EulerAngles Eul_(float ai, float aj, float ah, int order); + Quat Eul_ToQuat(EulerAngles ea); + void Eul_ToHMatrix(EulerAngles ea, HMatrix M); + EulerAngles Eul_FromHMatrix(HMatrix M, int order); + EulerAngles Eul_FromQuat(Quat q, int order); + + // Debug Stuff + const char *DumpOrderInfo(); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSFNDTimer.h b/src/Runtime/Source/system/Qt3DSFNDTimer.h new file mode 100644 index 00000000..8241e2ed --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFNDTimer.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSTimer.h" +#include "Qt3DSTypes.h" +#include "foundation/Qt3DSTime.h" + +namespace Q3DStudio { +class Qt3DSFNDTimer : public ITimeProvider +{ + Q3DStudio::INT64 GetCurrentTimeMicroSeconds() override + { + return qt3ds::foundation::Time::getCurrentTimeInTensOfNanoSeconds() / 100; + } +}; +} diff --git a/src/Runtime/Source/system/Qt3DSFile.cpp b/src/Runtime/Source/system/Qt3DSFile.cpp new file mode 100644 index 00000000..a26b7351 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFile.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSFile.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// OS level memory routines +//============================================================================== +#if defined(_XENONPLATFORM) || defined(_PCPLATFORM) || defined(_PS3PLATFORM) \ + || defined(_TEGRAPLATFORM) || defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +CFile::TOpen CFile::s_Open = &fopen; +CFile::TClose CFile::s_Close = &fclose; +CFile::TRead CFile::s_Read = &fread; +CFile::TWrite CFile::s_Write = &fwrite; +CFile::TTell CFile::s_Tell = &ftell; +CFile::TSeek CFile::s_Seek = &fseek; +#else +#error "A platform must be defined" +#endif + +//============================================================================== +/** + * Overrides basic memory allocation/deallocation routines + * @param inOpen fopen replacement method + * @param inClose fclose replacement method + * @param inRead fread replacement method + * @param inWrite fwrite replacement method + */ +void CFile::SetFileFunctions(const TOpen inOpen, const TClose inClose, const TRead inRead, + const TWrite inWrite, const TTell inTell, const TSeek inSeek) +{ + s_Open = inOpen; + s_Close = inClose; + s_Read = inRead; + s_Write = inWrite; + s_Tell = inTell; + s_Seek = inSeek; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSFile.h b/src/Runtime/Source/system/Qt3DSFile.h new file mode 100644 index 00000000..e970cd2d --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFile.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTypes.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Single overridable exit point for all low level file calls. + */ +class CFile +{ + //============================================================================== + // Typedefs + //============================================================================== +public: + typedef enum _E_SEEK { + E_SEEK_SET = SEEK_SET, + E_SEEK_CUR = SEEK_CUR, + E_SEEK_END = SEEK_END + } E_SEEK; + + typedef TFile *(*TOpen)(const char *inFileName, const char *inMode); + typedef int (*TClose)(TFile *inFile); + typedef TFileSize (*TRead)(void *inBuffer, TFileSize inSize, TFileSize inCount, TFile *inFile); + typedef TFileSize (*TWrite)(const void *inBuffer, TFileSize inSize, TFileSize inCount, + TFile *inFile); + typedef long (*TTell)(TFile *inFile); + typedef int (*TSeek)(TFile *inFile, long inOffset, int inOrigin); + + //============================================================================== + // Fields + //============================================================================== +protected: + static TOpen s_Open; ///< function pointer to fopen operation + static TClose s_Close; ///< function pointer to fclose operation + static TRead s_Read; ///< function pointer to fread operation + static TWrite s_Write; ///< function pointer to fwrite operation + static TTell s_Tell; ///< function pointer to ftell operation + static TSeek s_Seek; ///< function pointer to fseek operation + + //============================================================================== + // Methods + //============================================================================== +public: // Memory override + static void SetFileFunctions(const TOpen inOpen, const TClose inClose, const TRead inRead, + const TWrite inWrite, const TTell inTell, const TSeek inSeek); + +public: // Function access + static TOpen Open() { return s_Open; } + static TClose Close() { return s_Close; } + static TRead Read() { return s_Read; } + static TWrite Write() { return s_Write; } + static TTell Tell() { return s_Tell; } + static TSeek Seek() { return s_Seek; } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSFileStream.cpp b/src/Runtime/Source/system/Qt3DSFileStream.cpp new file mode 100644 index 00000000..202e4ae7 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFileStream.cpp @@ -0,0 +1,237 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "SystemPrefix.h" +#include "Qt3DSFile.h" +#include "Qt3DSFileStream.h" +#include "foundation/Qt3DSLogging.h" + +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + * @param inFilename the file to open + * @param inMode the file mode to use + */ +CFileStream::CFileStream(const CHAR *inFilePath, const CHAR *inMode, BOOL inKeepTrying) + : m_FileStream(NULL) + , m_Endian(QT3DS_LITTLE_ENDIAN) + , m_KeepTrying(inKeepTrying) +{ + m_TempBuffer.Reserve(sizeof(MATRIX16)); // Preallocated some space + if (inFilePath) + Open(inFilePath, inMode); +} + +//============================================================================== +/** + * Destructor + */ +CFileStream::~CFileStream() +{ + Close(); +} + +//============================================================================== +/** + * Open file. + * @param inFilename the file to open + * @param inMode the file mode ( read/write ) to use + */ +void CFileStream::Open(const CHAR *inFilePath, const CHAR *inMode) +{ + Close(); + m_FileStream = CFile::Open()(inFilePath, inMode); + while (m_KeepTrying && !m_FileStream) { + QThread::msleep(10); + m_FileStream = CFile::Open()(inFilePath, inMode); + } + + if (m_FileStream) + m_FilePath = inFilePath; +} + +//============================================================================== +/** + * Close file. + */ +void CFileStream::Close() +{ + if (m_FileStream) { + CFile::Close()(m_FileStream); + m_FileStream = NULL; + } +} + +//============================================================================== +/** + * Check if there is an opened file. + * @return TRUE if opened, FALSE otherwise. + */ +BOOL CFileStream::IsOpen() const +{ + return m_FileStream != NULL; +} + +//============================================================================== +/** + * Access the source path of a file stream. + * @return an empty string if the stream is not open + */ +const CHAR *CFileStream::GetFilePath() const +{ + return m_FilePath.toLatin1().constData(); +} + +//============================================================================== +/** + * Read from stream into memory. + * @param outMemory the destination of the read + * @param inByteCount the amount to read + * @return the number of bytes actually read + */ +INT32 CFileStream::ReadRawCopy(void *inDestination, const UINT32 inByteCount) +{ + INT32 lastRead = 0; + INT32 totalRead = 0; + do { + if (totalRead) { + qCWarning(qt3ds::INVALID_OPERATION) + << "Failed to read expected amount, retrying, expected " + << inByteCount << " bytes, got "<< totalRead <<" bytes"; + } + lastRead = static_cast(CFile::Read()(((char *)inDestination) + totalRead, 1, + inByteCount - totalRead, m_FileStream)); + totalRead += lastRead; + } while (lastRead && totalRead < (INT32)inByteCount); + + if (totalRead != (INT32)inByteCount) { + qCWarning(qt3ds::INVALID_OPERATION) + << "Failed to read expected amount, retrying, expected " + << inByteCount << " bytes, got "<< totalRead <<" bytes"; + + // Zero out remaining destination buffer. + // This can, in some cases, avoid a crash and allow the system to survive a partial + // read. + INT32 amountLeft = inByteCount - totalRead; + memset(((char *)inDestination) + totalRead, 0, amountLeft); + } + return totalRead; +} + +//============================================================================== +/** + * Reads data into internal buffer and return the data pointer for it. + * @param outMemory pointer to internal data buffer + * @param inByteCount the amount to read + * @return the number of bytes actually read + */ +INT32 CFileStream::ReadRaw(const void *&inPtr, const UINT32 inByteCount) +{ + m_TempBuffer.Reserve(static_cast(inByteCount)); + INT32 theReadSize = ReadRawCopy(m_TempBuffer.Begin(), inByteCount); + if (theReadSize != (INT32)inByteCount) { + qCWarning(qt3ds::INVALID_OPERATION) + << "Failed to read expected amount, retrying, expected "<< inByteCount + << " bytes, got "<< theReadSize <<" bytes"; + } + inPtr = m_TempBuffer.Begin(); + return theReadSize; +} + +//============================================================================== +/** + * Write from memory to stream. + * @param inMemory the buffer to write from + * @param inByteCount the amount to write + * @return the number of bytes actually written + */ +INT32 CFileStream::WriteRaw(const void *inSource, const UINT32 inByteCount) +{ + return static_cast(CFile::Write()(inSource, 1, inByteCount, m_FileStream)); +} + +//============================================================================== +/** + * Offsets the file position by the specified number of bytes + */ +void CFileStream::Offset(const INT32 inByteCount) +{ + CFile::Seek()(m_FileStream, inByteCount, CFile::E_SEEK_CUR); +} + +//============================================================================== +/** + * Returns the current position of the file stream + */ +IStream::TStreamPosition CFileStream::Current() +{ + return static_cast(CFile::Tell()(m_FileStream)); +} + +//============================================================================== +/** + * Sets the stream to the specified position within the file + */ +void CFileStream::Set(const TStreamPosition &inPosition) +{ + CFile::Seek()(m_FileStream, inPosition, CFile::E_SEEK_SET); +} + +//============================================================================== +/** + * Set the endianess of the file. + * @warning endian support not implemented + */ +void CFileStream::SetEndian(const BOOL inEndian) +{ + m_Endian = inEndian; +} + +//============================================================================== +/** + * Get the endianess of the file. + * @warning endian support not implemented + */ +BOOL CFileStream::GetEndian() +{ + return m_Endian; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSFileStream.h b/src/Runtime/Source/system/Qt3DSFileStream.h new file mode 100644 index 00000000..49e272f4 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFileStream.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSIFileStream.h" +#include "Qt3DSArray.h" +#include "Qt3DSEndian.h" + +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * File stream base class. + */ +class CFileStream : public IFileStream +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CFileStream(const CHAR *inFilePath = NULL, const CHAR *inMode = "rb", + BOOL inKeepTrying = false); + virtual ~CFileStream(); + +public: // Serializing + INT32 ReadRawCopy(void *inDestination, const UINT32 inByteCount) override; + INT32 ReadRaw(const void *&inPtr, const UINT32 inByteCount) override; + INT32 WriteRaw(const void *inSource, const UINT32 inByteCount) override; + + // Seeking + void Offset(const INT32 inOffset) override; + TStreamPosition Current() override; + void Set(const TStreamPosition &inPosition) override; + +public: // File Operation + void Open(const CHAR *inFilePath, const CHAR *inMode) override; + void Close() override; + BOOL IsOpen() const override; + const CHAR *GetFilePath() const override; + +public: // Endianess + void SetEndian(const BOOL inEndian); + BOOL GetEndian(); + + //============================================================================== + // Fields + //============================================================================== +protected: + TFile *m_FileStream; + QString m_FilePath; + CArray m_TempBuffer; + BOOL m_Endian; + BOOL m_KeepTrying; + CHAR m_Unused[2]; ///< (padding) +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSFixedArray.h b/src/Runtime/Source/system/Qt3DSFixedArray.h new file mode 100644 index 00000000..9f971d81 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFixedArray.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Fixed size Ordered Collection that doesn't support growing. + */ +template +class CFixedArray +{ + //============================================================================== + // Typedefs + //============================================================================== +public: + typedef T TType; ///< Easy access to template type + + //============================================================================== + // Fields + //============================================================================== +protected: + T m_Data[Size]; ///< Allocated memory containing array data + INT32 m_Capacity; ///< Max number of elements possible + INT32 m_Count; ///< Current number of elements in array + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + inline CFixedArray(); + inline ~CFixedArray(); + +public: // Management + inline void Clear(); + inline INT32 GetCount() const; + inline INT32 GetCapacity() const; + +public: // Stack access + inline void Push(const T &inValue); + inline const T &Pop(); + +public: // Array access + inline T &operator[](const INT32 inIndex); + inline void Remove(const INT32 inIndex); +}; + +} // namespace Q3DStudio + +//============================================================================== +// Template code +//============================================================================== +#include "Qt3DSFixedArray.inl" diff --git a/src/Runtime/Source/system/Qt3DSFixedArray.inl b/src/Runtime/Source/system/Qt3DSFixedArray.inl new file mode 100644 index 00000000..55242243 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFixedArray.inl @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 1999-2007 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + */ +template +inline CFixedArray::CFixedArray() + : m_Capacity(Size) + , m_Count(0) +{ +} + +//============================================================================== +/** + * Destructor + */ +template +inline CFixedArray::~CFixedArray() +{ +} + +//============================================================================== +/** + * Remove all elements in the array + */ +template +inline void CFixedArray::Clear() +{ + m_Count = 0; +} + +//============================================================================== +/** + * Get current count of T in the array + * @return current count of the array + */ +template +inline INT32 CFixedArray::GetCount() const +{ + return m_Count; +} + +//============================================================================== +/** + * Get the capacity of the array + * Capacity reflects the allocated memory size + * @return capacity of the array + */ +template +inline INT32 CFixedArray::GetCapacity() const +{ + return m_Capacity; +} + +//============================================================================== +/** + * Insert T to the end of the array + * @param inValue value of datatype T + */ +template +inline void CFixedArray::Push(const T &inValue) +{ + if (m_Count == m_Capacity) { + qWarning("Trying to push to many objects onto a CFixedArray", "Capacity=%d", m_Capacity); + return; + } + + m_Data[m_Count] = inValue; + ++m_Count; +} + +//============================================================================== +/** + * Remove and retrieve T which is at the end of the array + * @return value of datatype T + */ +template +inline const T &CFixedArray::Pop() +{ + if (m_Count == 0) + return {}; + + --m_Count; + return m_Data[m_Count]; +} + +//============================================================================== +/** + * Get T at a particular index position of the array. + * Need to ensure only valid index is allowed + * Clear( ) will set the m_counter = 0 + * @param inIndex the index of the array + * @return reference of value of datatype T + */ +template +inline T &CFixedArray::operator[](const INT32 inIndex) +{ + Q3DStudio_ASSERT(inIndex < m_Capacity); + + return m_Data[inIndex]; +} + +//============================================================================== +/** + * Removes a specific entry from the array. + * Moves all entries below it up, expensive. + * @param inIndex the index of the entry + */ +template +inline void CFixedArray::Remove(const INT32 inIndex) +{ + Q3DStudio_memmove(m_Data + inIndex, m_Data + inIndex + 1, sizeof(T) * (m_Count - inIndex - 1)); + --m_Count; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSFunctionWrappers.cpp b/src/Runtime/Source/system/Qt3DSFunctionWrappers.cpp new file mode 100644 index 00000000..e96c3ce1 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFunctionWrappers.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2010 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "SystemPrefix.h" +#include "Qt3DSFunctionWrappers.h" + +using namespace Q3DStudio; + +//============================================================================== +/** +* CTOR +*/ +IFunctionWrapper::IFunctionWrapper() + : m_Cost(0) +{ +} + +//============================================================================== +/** +* Retrieve the cost associated with this function. +* Should be zero or greater +*/ +INT32 IFunctionWrapper::GetCost() +{ + return m_Cost; +} + +//============================================================================== +/** +* Sets the cost associated with this function. +*/ +void IFunctionWrapper::SetCost(const INT32 inCost) +{ + m_Cost = inCost; +} \ No newline at end of file diff --git a/src/Runtime/Source/system/Qt3DSFunctionWrappers.h b/src/Runtime/Source/system/Qt3DSFunctionWrappers.h new file mode 100644 index 00000000..8fff62de --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSFunctionWrappers.h @@ -0,0 +1,416 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2010 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== + +namespace Q3DStudio { + +//============================================================================== +/** +* Interface for a function wrapper with an associated cost. +*/ +class IFunctionWrapper +{ +public: + IFunctionWrapper(); + virtual ~IFunctionWrapper(){} + +public: + virtual void Execute() = 0; + INT32 GetCost(); + void SetCost(const INT32 inCost); + +protected: + INT32 m_Cost; +}; + +//============================================================================== +/** +* 2 arguments function wrapper +*/ +template +class CFunctionWrapper2Args : public IFunctionWrapper +{ +public: + typedef void (*TFunction)(TArg1 inArg1, TArg2 inArg2); + +public: + CFunctionWrapper2Args(TFunction, TArg1 inArg1, TArg2 inArg2); + +public: + virtual void Execute(); + +protected: + TFunction m_Function; + TArg1 m_Arg1; + TArg2 m_Arg2; +}; + +// Unused +/* +template +class CFunctionWrapper3Args : public IFunctionWrapper +{ + public: + typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3 ); + + public: + CFunctionWrapper3Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 +inArg3 ); + + public: + virtual void Execute( ); + + protected: + TFunction m_Function; + TArg1 m_Arg1; + TArg2 m_Arg2; + TArg3 m_Arg3; +}; + +template +class CFunctionWrapper4Args : public IFunctionWrapper +{ + public: + typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4 +); + + public: + CFunctionWrapper4Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 +inArg3, TArg4 inArg4 ); + + public: + virtual void Execute( ); + + protected: + TFunction m_Function; + TArg1 m_Arg1; + TArg2 m_Arg2; + TArg3 m_Arg3; + TArg4 m_Arg4; +}; + +template +class CFunctionWrapper8Args : public IFunctionWrapper +{ + public: + typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4, +TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8 ); + + public: + CFunctionWrapper8Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 +inArg3, TArg4 inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8 ); + + public: + virtual void Execute( ); + + protected: + TFunction m_Function; + TArg1 m_Arg1; + TArg2 m_Arg2; + TArg3 m_Arg3; + TArg4 m_Arg4; + TArg5 m_Arg5; + TArg6 m_Arg6; + TArg7 m_Arg7; + TArg8 m_Arg8; +}; + +template +class CFunctionWrapper9Args : public IFunctionWrapper +{ + public: + typedef void ( *TFunction )( TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4, +TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8, TArg9 inArg9 ); + + public: + CFunctionWrapper9Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 +inArg3, TArg4 inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8, TArg9 inArg9 ); + + public: + virtual void Execute( ); + + protected: + TFunction m_Function; + TArg1 m_Arg1; + TArg2 m_Arg2; + TArg3 m_Arg3; + TArg4 m_Arg4; + TArg5 m_Arg5; + TArg6 m_Arg6; + TArg7 m_Arg7; + TArg8 m_Arg8; + TArg9 m_Arg9; +}; +*/ + +//============================================================================== +/** +* 1 argument member function wrapper +*/ +template +class CMemberFunctionWrapper1Args : public IFunctionWrapper +{ +public: + typedef TReturn (TObject::*TFunction)(TArg1 inArg1); + +public: + CMemberFunctionWrapper1Args(TObject *inObject, TFunction inFunction, TArg1 inArg1); + +public: + virtual void Execute(); + +protected: + TFunction m_Function; + TObject *m_Object; + TArg1 m_Arg1; +}; + +//============================================================================== +/** +* 2 argument member function wrapper +*/ +template +class CMemberFunctionWrapper2Args : public IFunctionWrapper +{ +public: + typedef TReturn (TObject::*TFunction)(TArg1 inArg1, TArg2 inArg2); + +public: + CMemberFunctionWrapper2Args(TObject *inObject, TFunction inFunction, TArg1 inArg1, + TArg2 inArg2); + +public: + virtual void Execute(); + +protected: + TFunction m_Function; + TObject *m_Object; + TArg1 m_Arg1; + TArg2 m_Arg2; +}; + +//============================================================================== +/** +* 6 argument member function wrapper +*/ +template +class CMemberFunctionWrapper6Args : public IFunctionWrapper +{ +public: + typedef TReturn (TObject::*TFunction)(TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4, + TArg5 inArg5, TArg6 inArg6); + +public: + CMemberFunctionWrapper6Args(TObject *inObject, TFunction inFunction, TArg1 inArg1, TArg2 inArg2, + TArg3 inArg3, TArg4 inArg4, TArg5 inArg5, TArg6 inArg6); + +public: + virtual void Execute(); + +protected: + TFunction m_Function; + TObject *m_Object; + TArg1 m_Arg1; + TArg2 m_Arg2; + TArg3 m_Arg3; + TArg4 m_Arg4; + TArg5 m_Arg5; + TArg6 m_Arg6; +}; + +// Implementation +template +CFunctionWrapper2Args::CFunctionWrapper2Args(TFunction inFunction, TArg1 inArg1, + TArg2 inArg2) + : m_Function(inFunction) + , m_Arg1(inArg1) + , m_Arg2(inArg2) +{ +} + +template +void CFunctionWrapper2Args::Execute() +{ + m_Function(m_Arg1, m_Arg2); +} + +// Unused +/* +template +CFunctionWrapper3Args::CFunctionWrapper3Args( TFunction inFunction, TArg1 +inArg1, TArg2 inArg2, TArg3 inArg3 ) +: m_Function( inFunction ), + m_Arg1( inArg1 ), + m_Arg2( inArg2 ), + m_Arg3( inArg3 ) +{ +} + +template +void CFunctionWrapper3Args::Execute( ) +{ + m_Function( m_Arg1, m_Arg2, m_Arg3 ); +} + +template +CFunctionWrapper4Args::CFunctionWrapper4Args( TFunction inFunction, +TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 inArg4 ) +: m_Function( inFunction ), + m_Arg1( inArg1 ), + m_Arg2( inArg2 ), + m_Arg3( inArg3 ), + m_Arg4( inArg4 ) +{ +} + +template +void CFunctionWrapper4Args::Execute( ) +{ + m_Function( m_Arg1, m_Arg2, m_Arg3, m_Arg4 ); +} + +template +CFunctionWrapper8Args::CFunctionWrapper8Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 +inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8 ) +: m_Function( inFunction ), + m_Arg1( inArg1 ), + m_Arg2( inArg2 ), + m_Arg3( inArg3 ), + m_Arg4( inArg4 ), + m_Arg5( inArg5 ), + m_Arg6( inArg6 ), + m_Arg7( inArg7 ), + m_Arg8( inArg8 ) + +{ +} + +template +void CFunctionWrapper8Args::Execute( ) +{ + m_Function( m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6, m_Arg7, m_Arg8 ); +} + +template +CFunctionWrapper9Args::CFunctionWrapper9Args( TFunction inFunction, TArg1 inArg1, TArg2 inArg2, TArg3 inArg3, TArg4 +inArg4, TArg5 inArg5, TArg6 inArg6, TArg7 inArg7, TArg8 inArg8, TArg9 inArg9 ) +: m_Function( inFunction ), + m_Arg1( inArg1 ), + m_Arg2( inArg2 ), + m_Arg3( inArg3 ), + m_Arg4( inArg4 ), + m_Arg5( inArg5 ), + m_Arg6( inArg6 ), + m_Arg7( inArg7 ), + m_Arg8( inArg8 ), + m_Arg9( inArg9 ) +{ +} + +template +void CFunctionWrapper9Args::Execute( +) +{ + m_Function( m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6, m_Arg7, m_Arg8, m_Arg9 ); +} +*/ + +template +CMemberFunctionWrapper1Args::CMemberFunctionWrapper1Args( + TObject *inObject, TFunction inFunction, TArg1 inArg1) + : m_Function(inFunction) + , m_Object(inObject) + , m_Arg1(inArg1) +{ +} + +template +void CMemberFunctionWrapper1Args::Execute() +{ + (m_Object->*m_Function)(m_Arg1); +} + +template +CMemberFunctionWrapper2Args::CMemberFunctionWrapper2Args( + TObject *inObject, TFunction inFunction, TArg1 inArg1, TArg2 inArg2) + : m_Function(inFunction) + , m_Object(inObject) + , m_Arg1(inArg1) + , m_Arg2(inArg2) +{ +} + +template +void CMemberFunctionWrapper2Args::Execute() +{ + (m_Object->*m_Function)(m_Arg1, m_Arg2); +} + +template +CMemberFunctionWrapper6Args::CMemberFunctionWrapper6Args(TObject *inObject, + TFunction inFunction, TArg1 inArg1, + TArg2 inArg2, TArg3 inArg3, + TArg4 inArg4, TArg5 inArg5, + TArg6 inArg6) + : m_Function(inFunction) + , m_Object(inObject) + , m_Arg1(inArg1) + , m_Arg2(inArg2) + , m_Arg3(inArg3) + , m_Arg4(inArg4) + , m_Arg5(inArg5) + , m_Arg6(inArg6) +{ +} + +template +void CMemberFunctionWrapper6Args::Execute() +{ + (m_Object->*m_Function)(m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6); +} +} diff --git a/src/Runtime/Source/system/Qt3DSHash.h b/src/Runtime/Source/system/Qt3DSHash.h new file mode 100644 index 00000000..8baa2dba --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSHash.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSConfig.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Utility class transforming a string into a hash value. + */ +class CHash +{ + //============================================================================== + // Methods + //============================================================================== +public: // Static utility + //============================================================================== + /** + * We use the hashing algorithm called "sdbm". + * + * This algorithm was created from sdbm (a public-domain reimplementation + * of ndbm) database library. It was found to do well in scrambling bits, + * causing better distribution of the keys and fewer splits. it also happens + * to be a good general hashing function with good distribution. the actual + * function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below + * is the faster version used in gawk. [there is even a faster, duff-device + * version] the magic constant 65599 was picked out of thin air while + * experimenting with different constants, and turns out to be a prime. this + * is one of the algorithms used in berkeley db (see sleepycat) and elsewhere. + * + * @param inString the string to hash + * @return the hash value + */ + static TStringHash HashString(const CHAR *inString) + { + TStringHash theHash = 0; + INT32 theChar = *inString; + INT32 theCount = 0; + while (theChar && (theCount < HASH_LIMIT)) { + theChar = *inString++; + theHash = theChar + (theHash << 6) + (theHash << 16) - theHash; + ++theCount; + } + + return theHash; + } + + //============================================================================== + /** + * 31-bit hash with MSB set to 0 + * + * @param inString the string to hash + * @return the 31-bit hash value + */ + static TEventCommandHash HashEventCommand(const CHAR *inString) + { + return HashString(inString) & 0x7fffffff; + } + + //============================================================================== + /** + * 26-bit hash with MSBs all set to 0 + * + * @param inString the string to hash + * @return the 26-bit hash value + */ + static TAttributeHash HashAttribute(const CHAR *inString) + { + return HashString(inString) & 0x03ffffff; + } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSIFileStream.h b/src/Runtime/Source/system/Qt3DSIFileStream.h new file mode 100644 index 00000000..0b432601 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSIFileStream.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSIStream.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * File stream interface + */ +class IFileStream : public IStream +{ +public: + virtual void Open(const CHAR *inFilePath, const CHAR *inMode) = 0; + virtual void Close() = 0; + virtual BOOL IsOpen() const = 0; + virtual const CHAR *GetFilePath() const = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSIStream.h b/src/Runtime/Source/system/Qt3DSIStream.h new file mode 100644 index 00000000..a4c11955 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSIStream.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Pure virtual interface providing the stream for class serialization. + */ +class IStream +{ + //============================================================================== + // Typedef + //============================================================================== +public: + typedef INT32 TStreamPosition; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + virtual ~IStream(){} + +public: // Serializing + virtual INT32 ReadRawCopy(void *inDestination, const UINT32 inByteCount) = 0; + virtual INT32 ReadRaw(const void *&inPtr, const UINT32 inByteCount) = 0; + virtual INT32 WriteRaw(const void *inSource, const UINT32 inByteCount) = 0; + + // Seeking + virtual void Offset(const INT32 inOffset) = 0; + virtual TStreamPosition Current() = 0; + virtual void Set(const TStreamPosition &inPosition) = 0; + +public: // Template Readers that make a copy + template + INT32 ReadCopy(T &outValue); + template + INT32 ReadArrayCopy(T *outValue, const UINT32 inCount); + +public: // Template Readers that access value directly + template + INT32 Read(const T *&inPtr); + template + INT32 ReadArray(const T *&inPtr, UINT32 inCount); + +public: // Template Writers + template + INT32 Write(const T &inValue); + template + INT32 WriteArray(const T *inValue, const UINT32 inCount); +}; + +/** Notes concerning usage of Read or ReadCopy (and ReadArray and ReadArrayCopy)**/ +/** +If the value being read fits into 4 bytes (i.e float, int/long), either Read/ReadCopy can be used. +However, if the read value is going to be accessed frequently (in loops etc), ReadCopy is +recommended so a copy is available instead of dereferencing. + +ReadCopy should be used if the data read is an array or is significantly larger than 4 bytes (like +vectors or matrixes). + +For cases where the value is to be stored in a persistant data structures, ReadCopy should be used. + +One important thing about Read/ReadArray, is that the pointer returned is only valid before the next +Read/ReadyArray is called. +There is no guarantee that the pointer data will remain unchanged during subsequent calls to +Read/ReadArray. +**/ + +//============================================================================== +/** + * Read and assign a value by copying. + */ +template +INT32 IStream::ReadCopy(T &outValue) +{ + return ReadRawCopy(&outValue, sizeof(T)); +} + +//============================================================================== +/** + * Read and copy data to a preallocated array. + */ +template +INT32 IStream::ReadArrayCopy(T *outValue, const UINT32 inCount) +{ + return ReadRawCopy(outValue, sizeof(T) * inCount); +} + +//============================================================================== +/** + * Obtain a pointer directly to the data. + */ +template +INT32 IStream::Read(const T *&inPtr) +{ + return ReadRaw(reinterpret_cast(inPtr), sizeof(T)); +} + +//============================================================================== +/** + * Obtain a pointer directly to the array data. + */ +template +INT32 IStream::ReadArray(const T *&inPtr, const UINT32 inCount) +{ + return ReadRaw(reinterpret_cast(inPtr), sizeof(T) * inCount); +} + +//============================================================================== +/** + * Write a value. + */ +template +INT32 IStream::Write(const T &inValue) +{ + return WriteRaw(&inValue, sizeof(T)); +} + +//============================================================================== +/** + * Write an array of values. + */ +template +INT32 IStream::WriteArray(const T *inValue, const UINT32 inCount) +{ + return WriteRaw(inValue, sizeof(T) * inCount); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSITimer.h b/src/Runtime/Source/system/Qt3DSITimer.h new file mode 100644 index 00000000..e73fbb95 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSITimer.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * @interface ITimer + * The base functionality of the timer used by the Kernel + * + * Implement this interface per-platform to obtain the required functionality + */ +class ITimer +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + virtual ~ITimer() {} + +public: // Operation + virtual void Start() = 0; + virtual void Stop() = 0; + virtual void Reset() = 0; + virtual TTimeUnit GetTimeMilliSecs() = 0; + virtual TMicroSeconds GetTimeMicroSecs() = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMacros.h b/src/Runtime/Source/system/Qt3DSMacros.h new file mode 100644 index 00000000..fbc40b4d --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMacros.h @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSAssert.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Easy iterations over arrays. + * @param array_type element type + * @param array_element element variable name getting each entry + * @param array_container element array we are traversing + */ +#define FOR_ARRAY(array_type, array_element, array_container) \ + for (array_type *array_element = (array_container).Begin(); \ + array_element != (array_container).End(); ++array_element) + +#define FOR_ARRAY_REVERSE(array_type, array_element, array_container) \ + for (array_type *array_element = (array_container).End() - 1; \ + array_element != (array_container).Begin() - 1; --array_element) + +//============================================================================== +/** + * Return the smallest of two numbers/objects. + * @param inA one value to compare + * @param inB another value to compare + * @return a reference, not a copy, to the smallest of the two values + */ +template +inline const T Q3DStudio_abs(const T &inVal) +{ + return inVal >= 0 ? inVal : -inVal; +} + +//============================================================================== +/** + * Return the smallest of two numbers/objects. + * @param inA one value to compare + * @param inB another value to compare + * @return a reference, not a copy, to the smallest of the two values + */ +template +inline const T &Q3DStudio_min(const T &inA, const T &inB) +{ + return inA < inB ? inA : inB; +} + +//============================================================================== +/** + * Return the largest of two numbers/objects. + * @param inA one value to compare + * @param inB another value to compare + * @return a reference, not a copy, to the largest of the two values + */ +template +inline const T &Q3DStudio_max(const T &inA, const T &inB) +{ + return inA > inB ? inA : inB; +} + +//============================================================================== +/** + * Return the smallest of three values. + * @param inA one value to compare + * @param inB another value to compare + * @param inC a third value to compare + * @return a reference, not a copy, to the smallest of the three values + */ +template +inline const T &Q3DStudio_min3(const T &inA, const T &inB, const T &inC) +{ + return inA < inB ? Q3DStudio_min(inA, inC) : Q3DStudio_min(inB, inC); +} + +//============================================================================== +/** + * Return the largest of three values. + * @param inA one value to compare + * @param inB another value to compare + * @param inC a third value to compare + * @return a reference, not a copy, to the largest of the three values + */ +template +inline const T &Q3DStudio_max3(const T &inA, const T &inB, const T &inC) +{ + return inA > inB ? Q3DStudio_max(inA, inC) : Q3DStudio_max(inB, inC); +} + +//============================================================================== +/** + * Make sure a value is in-bounds between two other values. + * @param inVal the value to clamp + * @param inMin the lowest inclusive value + * @param inMax the highest inclusive value + * @return a reference to inVal if the value is in bounds, + inMin if lower than the minimum value, or + inMax if higher than maximum value. + */ +template +inline const T &Q3DStudio_clamp(const T &inVal, const T &inMin, const T &inMax) +{ + if (inVal <= inMin) + return inMin; + else if (inVal >= inMax) + return inMax; + + return inVal; +} + +//============================================================================== +/** + * Return the identified lower and higher values. + * @param inA one value to compare + * @param inB another value to compare + * @param outMin is assigned to the lower of the two compared values + * @param outMax is assigned to the higher of the two compared values + */ +template +inline void Q3DStudio_minmax(const T &inA, const T &inB, T &outMin, T &outMax) +{ + if (inA < inB) { + outMin = inA; + outMax = inB; + } else { + outMin = inB; + outMax = inA; + } +} + +//============================================================================== +/** + * Identify needed parameters that are not currently referenced. + */ +#define Q3DStudio_UNREFERENCED_PARAMETER(P) \ + { \ + (void)P; \ + } + +//============================================================================== +/** + * Assert + */ +#if defined(_DEBUG) || defined(_PROFILE) +#define Q3DStudio_ASSERT(inExpression) \ + { \ + if (!(inExpression)) \ + Q3DStudio::CAssert::GetFunction()(#inExpression, __FILE__, __LINE__, __FUNCTION__); \ + } +#else +#define Q3DStudio_ASSERT(inExpression) ((void)0) +#endif // _DEBUG or _PROFILE + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMatrix.cpp b/src/Runtime/Source/system/Qt3DSMatrix.cpp new file mode 100644 index 00000000..b5310d0e --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMatrix.cpp @@ -0,0 +1,897 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMatrix.h" +#include "Qt3DSVector3.h" +#include "Qt3DSEulerAngles.h" +#include "Qt3DSDataLogger.h" +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +FLOAT g_IdentityInit[4][4] = { { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f } }; + +const RuntimeMatrix RuntimeMatrix::IDENTITY = RuntimeMatrix(g_IdentityInit); +extern const FLOAT RUNTIME_EPSILON; + +//============================================================================== +/** + * Empty constructor. + * Initializes this matrix to the identity matrix. + */ +RuntimeMatrix::RuntimeMatrix(const BOOL inInitializeIdentity /*= true*/) +{ + if (inInitializeIdentity) + Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); +} + +//============================================================================== +/** + * Copy constructor. + * @param inMatrix the source matrix to copy + */ +RuntimeMatrix::RuntimeMatrix(const RuntimeMatrix &inMatrix) +{ + Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); +} + +//============================================================================== +/** + * Assignment constructor. + * Initializes the matrix from an array. + * @param inComponents an array of 16 values + */ +RuntimeMatrix::RuntimeMatrix(const FLOAT inComponents[4][4]) +{ + if (inComponents) + Q3DStudio_memcpy(&m_Data, inComponents, sizeof(m_Data)); +} + +//============================================================================== +/** + * Sets this matrix to a NULL matrix with all values at zero. + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Zero() +{ + Q3DStudio_memset(&m_Data, 0, sizeof(m_Data)); + return *this; +} + +//============================================================================== +/** + * Sets the matrix to the identity matrix. + * @return reference to this matrix + */ +RuntimeMatrix &RuntimeMatrix::Identity() +{ + Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); + return *this; +} + +//============================================================================== +/** + * Copies the elements from another matrix. + * @param inMatrix the source matrix + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Set(const RuntimeMatrix &inMatrix) +{ + Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); + return *this; +} + +//============================================================================== +/** + * Copies the given components to this matrix. + * @param inComponents an array of 16 components + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Set(const FLOAT inComponents[4][4]) +{ + if (inComponents) + Q3DStudio_memcpy(&m_Data, inComponents, sizeof(m_Data)); + return *this; +} + +//============================================================================== +/** + * Heavily optimized assignment method. This has the same result as creating + * four full 4x4 matrices and multiplying them together. + * @todo Look into optimized code. + * @param inTranslation translation coordinates + * @param inRotation Euler angle rotations + * @param inScale scaling dimensions + * @param inPivot pivot offset vector + * @param inRotationOrder rotation order + * @param inCoordinateSystem the coordindate system + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Set(const RuntimeVector3 &inTranslation, const RuntimeVector3 &inRotation, + const RuntimeVector3 &inScale, const RuntimeVector3 &inPivot, const UINT8 inRotationOrder, + const UINT8 inCoordinateSystem) +{ + // *this = m_ScaleMatrix * m_PivotMatrix * m_RotMatrix * m_TransMatrix; // Distributed + //original - plain speak + + RuntimeVector3 theScaledPivot; + theScaledPivot.m_X = -inPivot.m_X * inScale.m_X; + theScaledPivot.m_Y = -inPivot.m_Y * inScale.m_Y; + theScaledPivot.m_Z = -inPivot.m_Z * inScale.m_Z; + + // This would take care of rotation in the right order + RuntimeMatrix theRotation; + theRotation.SetRotate(inRotation, inRotationOrder, inCoordinateSystem); + + Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); + m_Data[0][0] = inScale.m_X; + m_Data[1][1] = inScale.m_Y; + m_Data[2][2] = inScale.m_Z; + + m_Data[3][0] = theScaledPivot.m_X; + m_Data[3][1] = theScaledPivot.m_Y; + + if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) + m_Data[3][2] = theScaledPivot.m_Z; + else + m_Data[3][2] = -theScaledPivot.m_Z; + + MultiplyAffine(theRotation); // This could be optimized to only 9 multiplications instead of 16 + // if you do them by hand + + m_Data[3][0] += inTranslation.m_X; + m_Data[3][1] += inTranslation.m_Y; + + if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) + m_Data[3][2] += inTranslation.m_Z; + else + m_Data[3][2] += -inTranslation.m_Z; + + if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) + return FlipCoordinateSystem(); + + return *this; +} + +//============================================================================== +/** + * Sets the translation portion of the matrix without affecting the rest. + * + * If you want a pure translation matrix you must make sure to start with + * the identity matrix. + * @param inTranslate a translation vector + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::SetTranslate(const RuntimeVector3 &inTranslate) +{ + m_Data[3][0] = inTranslate.m_X; + m_Data[3][1] = inTranslate.m_Y; + m_Data[3][2] = inTranslate.m_Z; + return *this; +} + +//============================================================================== +/** + * Sets the rotation portion of the matrix without affecting the rest. + * + * FYI: The rotate and scale portions overlap. If you want a pure scale matrix + * you must make sure to start with the identity matrix. + * @param inRotation a quaternion describing the rotation + * @return reference to this modified matrix + */ +// CMatrix& CMatrix::SetRotate( const CQuaternion& inRotation ) +//{ +// inRotation.ToMatrix( *this ); +// return *this; +//} + +//============================================================================== +/** + * Sets the rotation portion of the matrix without affecting the rest. + * + * FYI: The rotate and scale portions overlap. If you want a pure rotation matrix + * you must make sure to start with the identity matrix. + * @param inRotation Euler angle rotation + * @param inRotationOrder rotation order + * @param inCoordinateSystem the coordindate system + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::SetRotate(const RuntimeVector3 &inRotation, const UINT8 inRotationOrder, + const UINT8 inCoordinateSystem) +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + Q3DStudio_UNREFERENCED_PARAMETER(inCoordinateSystem); + + EulerAngles theEulerAngles; + switch (inRotationOrder) { + case ROTATIONORDER_XYZ: + theEulerAngles.x = inRotation.m_X; + theEulerAngles.y = inRotation.m_Y; + theEulerAngles.z = inRotation.m_Z; + theEulerAngles.w = EulOrdXYZs; + break; + case ROTATIONORDER_XYZR: + theEulerAngles.x = inRotation.m_X; + theEulerAngles.y = inRotation.m_Y; + theEulerAngles.z = inRotation.m_Z; + theEulerAngles.w = EulOrdXYZr; + break; + case ROTATIONORDER_YZX: + theEulerAngles.x = inRotation.m_Y; + theEulerAngles.y = inRotation.m_Z; + theEulerAngles.z = inRotation.m_X; + theEulerAngles.w = EulOrdYZXs; + break; + case ROTATIONORDER_YZXR: + theEulerAngles.x = inRotation.m_Y; + theEulerAngles.y = inRotation.m_Z; + theEulerAngles.z = inRotation.m_X; + theEulerAngles.w = EulOrdYZXr; + break; + case ROTATIONORDER_ZXY: + theEulerAngles.x = inRotation.m_Z; + theEulerAngles.y = inRotation.m_X; + theEulerAngles.z = inRotation.m_Y; + theEulerAngles.w = EulOrdZXYs; + break; + case ROTATIONORDER_ZXYR: + theEulerAngles.x = inRotation.m_Z; + theEulerAngles.y = inRotation.m_X; + theEulerAngles.z = inRotation.m_Y; + theEulerAngles.w = EulOrdZXYr; + break; + case ROTATIONORDER_XZY: + theEulerAngles.x = inRotation.m_X; + theEulerAngles.y = inRotation.m_Z; + theEulerAngles.z = inRotation.m_Y; + theEulerAngles.w = EulOrdXZYs; + break; + case ROTATIONORDER_XZYR: + theEulerAngles.x = inRotation.m_X; + theEulerAngles.y = inRotation.m_Z; + theEulerAngles.z = inRotation.m_Y; + theEulerAngles.w = EulOrdXZYr; + break; + case ROTATIONORDER_YXZ: + theEulerAngles.x = inRotation.m_Y; + theEulerAngles.y = inRotation.m_X; + theEulerAngles.z = inRotation.m_Z; + theEulerAngles.w = EulOrdYXZs; + break; + case ROTATIONORDER_YXZR: + theEulerAngles.x = inRotation.m_Y; + theEulerAngles.y = inRotation.m_X; + theEulerAngles.z = inRotation.m_Z; + theEulerAngles.w = EulOrdYXZr; + break; + case ROTATIONORDER_ZYX: + theEulerAngles.x = inRotation.m_Z; + theEulerAngles.y = inRotation.m_Y; + theEulerAngles.z = inRotation.m_X; + theEulerAngles.w = EulOrdZYXs; + break; + case ROTATIONORDER_ZYXR: + theEulerAngles.x = inRotation.m_Z; + theEulerAngles.y = inRotation.m_Y; + theEulerAngles.z = inRotation.m_X; + theEulerAngles.w = EulOrdZYXr; + break; + default: // defaults to Studio's rotation type + theEulerAngles.x = inRotation.m_Y; + theEulerAngles.y = inRotation.m_X; + theEulerAngles.z = inRotation.m_Z; + theEulerAngles.w = EulOrdYXZs; + break; + } + + theEulerAngles.x *= -1; + theEulerAngles.y *= -1; + theEulerAngles.z *= -1; + + CEulerAngleConverter theConverter; + theConverter.Eul_ToHMatrix(theEulerAngles, m_Data); + + return *this; +} + +//============================================================================== +/** + * Sets the scale portion of the matrix without affecting the rest. + * + * FYI: The rotate and scale portions overlap. If you want a pure scale matrix + * you must make sure to start with the identity matrix. + * @param inScale scale vector + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::SetScale(const RuntimeVector3 &inScale) +{ + m_Data[0][0] = inScale.m_X; + m_Data[1][1] = inScale.m_Y; + m_Data[2][2] = inScale.m_Z; + return *this; +} + +//============================================================================== +/** + * Check this matrix against the identity matrix. + * @return true if this matrix is equivalent to the identity matrix + */ +BOOL RuntimeMatrix::IsIdentity() const +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + return *this == IDENTITY; +} + +//============================================================================== +/** + * Checks to see if this matrix is affine. + * An affine matrix has the last row being [ 0 0 0 1 ] + * @return true if the matrix is affine + */ +BOOL RuntimeMatrix::IsAffine() const +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + return m_Data[0][3] == 0 && m_Data[1][3] == 0 && m_Data[2][3] == 0 && m_Data[3][3] == 1.0f; +} + +//============================================================================== +/** + * Appends the matrix to include a translation. Equivalent to post-multiplying + * this matrix with a transformation matrix derived from the given vector. + * @param inTranslation transformation vector applied + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Translate(const RuntimeVector3 &inTranslation) +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + m_Data[3][0] += inTranslation.m_X; + m_Data[3][1] += inTranslation.m_Y; + m_Data[3][2] += inTranslation.m_Z; + return *this; +} + +//============================================================================== +/** + * Appends the matrix to include a rotation. Equivalent to post-multiplying + * this matrix with a rotation matrix derived from the given quaternion. + * @param inRotation the rotation quaternion applied + * @return reference to this modified matrix + */ +// CMatrix& CMatrix::Rotate( const CQuaternion& inRotation ) +//{ +// CMatrix theRotation; +// return MultiplyAffine( inRotation.ToMatrix( theRotation ) ); +//} + +//============================================================================== +/** + * Appends the matrix to include scaling. Equivalent to post-multiplying + * this matrix with a scale matrix derived from the given vector. + * @param inScale the scale vector applied + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Scale(const RuntimeVector3 &inScale) +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + m_Data[0][0] *= inScale.m_X; + m_Data[0][1] *= inScale.m_X; + m_Data[0][2] *= inScale.m_X; + + m_Data[1][0] *= inScale.m_Y; + m_Data[1][1] *= inScale.m_Y; + m_Data[1][2] *= inScale.m_Y; + + m_Data[2][0] *= inScale.m_Z; + m_Data[2][1] *= inScale.m_Z; + m_Data[2][2] *= inScale.m_Z; + return *this; +} + +//============================================================================== +/** + * Flips the matrix elements around the identity diagonal. + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::Transpose() +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + FLOAT theSwap = m_Data[1][0]; + m_Data[1][0] = m_Data[0][1]; + m_Data[0][1] = theSwap; + + theSwap = m_Data[2][0]; + m_Data[2][0] = m_Data[0][2]; + m_Data[0][2] = theSwap; + + theSwap = m_Data[3][0]; + m_Data[3][0] = m_Data[0][3]; + m_Data[0][3] = theSwap; + + theSwap = m_Data[2][1]; + m_Data[2][1] = m_Data[1][2]; + m_Data[1][2] = theSwap; + + theSwap = m_Data[3][1]; + m_Data[3][1] = m_Data[1][3]; + m_Data[1][3] = theSwap; + + theSwap = m_Data[3][2]; + m_Data[3][2] = m_Data[2][3]; + m_Data[2][3] = theSwap; + + return *this; +} + +//============================================================================== +/** + * Compute the inverse of a 3D affine matrix; i.e. a matrix with a + * dimensionality of 4 where the bottom row has the entries (0, 0, 0, 1). + * + * This procedure treats the 4 by 4 matrix as a block matrix and + * calculates the inverse of one submatrix for a significant performance + * improvement over a general procedure that can invert any non-singular matrix: +@code + | | -1 | -1 -1 | + | A C | | A -C A | + -1 | | | | + M = | | = | | + | 0 1 | | 0 1 | + | | | | +@endcode + * where M is a 4 by 4 matrix, + * A is the 3 by 3 upper left submatrix of M, + * C is the 3 by 1 upper right submatrix of M. + * + * @return the determinant of matrix + */ +FLOAT RuntimeMatrix::Invert() +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + const FLOAT PRECISIONLIMIT = 1.0e-07f; + FLOAT thePositiveDet = 0.0f; + FLOAT theNegativeDet = 0.0f; + FLOAT theTempDet; + + // Calculate the determinant of submatrix A and determine if the + // the matrix is singular as limited by the float precision. + theTempDet = m_Data[0][0] * m_Data[1][1] * m_Data[2][2]; + if (theTempDet >= 0.0f) + thePositiveDet += theTempDet; + else + theNegativeDet += theTempDet; + + theTempDet = m_Data[0][1] * m_Data[1][2] * m_Data[2][0]; + if (theTempDet >= 0.0f) + thePositiveDet += theTempDet; + else + theNegativeDet += theTempDet; + + theTempDet = m_Data[0][2] * m_Data[1][0] * m_Data[2][1]; + if (theTempDet >= 0.0f) + thePositiveDet += theTempDet; + else + theNegativeDet += theTempDet; + + theTempDet = -m_Data[0][2] * m_Data[1][1] * m_Data[2][0]; + if (theTempDet >= 0.0f) + thePositiveDet += theTempDet; + else + theNegativeDet += theTempDet; + + theTempDet = -m_Data[0][1] * m_Data[1][0] * m_Data[2][2]; + if (theTempDet >= 0.0f) + thePositiveDet += theTempDet; + else + theNegativeDet += theTempDet; + + theTempDet = -m_Data[0][0] * m_Data[1][2] * m_Data[2][1]; + if (theTempDet >= 0.0f) + thePositiveDet += theTempDet; + else + theNegativeDet += theTempDet; + + // Is the submatrix A nonsingular? (i.e. there is an inverse?) + FLOAT theDeterminant = thePositiveDet + theNegativeDet; + if (theDeterminant != 0 + || ::fabs(theDeterminant / (thePositiveDet - theNegativeDet)) >= PRECISIONLIMIT) { + RuntimeMatrix theInverse; + FLOAT theInvDeterminant = 1.0f / theDeterminant; + + // Calculate inverse(A) = adj(A) / det(A) + theInverse.m_Data[0][0] = + (m_Data[1][1] * m_Data[2][2] - m_Data[1][2] * m_Data[2][1]) * theInvDeterminant; + theInverse.m_Data[1][0] = + -(m_Data[1][0] * m_Data[2][2] - m_Data[1][2] * m_Data[2][0]) * theInvDeterminant; + theInverse.m_Data[2][0] = + (m_Data[1][0] * m_Data[2][1] - m_Data[1][1] * m_Data[2][0]) * theInvDeterminant; + theInverse.m_Data[0][1] = + -(m_Data[0][1] * m_Data[2][2] - m_Data[0][2] * m_Data[2][1]) * theInvDeterminant; + theInverse.m_Data[1][1] = + (m_Data[0][0] * m_Data[2][2] - m_Data[0][2] * m_Data[2][0]) * theInvDeterminant; + theInverse.m_Data[2][1] = + -(m_Data[0][0] * m_Data[2][1] - m_Data[0][1] * m_Data[2][0]) * theInvDeterminant; + theInverse.m_Data[0][2] = + (m_Data[0][1] * m_Data[1][2] - m_Data[0][2] * m_Data[1][1]) * theInvDeterminant; + theInverse.m_Data[1][2] = + -(m_Data[0][0] * m_Data[1][2] - m_Data[0][2] * m_Data[1][0]) * theInvDeterminant; + theInverse.m_Data[2][2] = + (m_Data[0][0] * m_Data[1][1] - m_Data[0][1] * m_Data[1][0]) * theInvDeterminant; + + // Calculate -C * inverse(A) + theInverse.m_Data[3][0] = + -(m_Data[3][0] * theInverse.m_Data[0][0] + m_Data[3][1] * theInverse.m_Data[1][0] + + m_Data[3][2] * theInverse.m_Data[2][0]); + theInverse.m_Data[3][1] = + -(m_Data[3][0] * theInverse.m_Data[0][1] + m_Data[3][1] * theInverse.m_Data[1][1] + + m_Data[3][2] * theInverse.m_Data[2][1]); + theInverse.m_Data[3][2] = + -(m_Data[3][0] * theInverse.m_Data[0][2] + m_Data[3][1] * theInverse.m_Data[1][2] + + m_Data[3][2] * theInverse.m_Data[2][2]); + + // assign ourselves to the inverse + *this = theInverse; + } + + return theDeterminant; +} + +//============================================================================== +/** + * Fast multiplication of two affine 4x4 matrices. No affine pre-check. + * @todo MF - Convert to SSE Assembly Code + * @param inMatrix the source matrix + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::MultiplyAffine(const RuntimeMatrix &inMatrix) +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + FLOAT theMult[4][4]; + + theMult[0][0] = m_Data[0][0] * inMatrix.m_Data[0][0] + m_Data[0][1] * inMatrix.m_Data[1][0] + + m_Data[0][2] * inMatrix.m_Data[2][0]; + theMult[0][1] = m_Data[0][0] * inMatrix.m_Data[0][1] + m_Data[0][1] * inMatrix.m_Data[1][1] + + m_Data[0][2] * inMatrix.m_Data[2][1]; + theMult[0][2] = m_Data[0][0] * inMatrix.m_Data[0][2] + m_Data[0][1] * inMatrix.m_Data[1][2] + + m_Data[0][2] * inMatrix.m_Data[2][2]; + theMult[0][3] = 0; + + theMult[1][0] = m_Data[1][0] * inMatrix.m_Data[0][0] + m_Data[1][1] * inMatrix.m_Data[1][0] + + m_Data[1][2] * inMatrix.m_Data[2][0]; + theMult[1][1] = m_Data[1][0] * inMatrix.m_Data[0][1] + m_Data[1][1] * inMatrix.m_Data[1][1] + + m_Data[1][2] * inMatrix.m_Data[2][1]; + theMult[1][2] = m_Data[1][0] * inMatrix.m_Data[0][2] + m_Data[1][1] * inMatrix.m_Data[1][2] + + m_Data[1][2] * inMatrix.m_Data[2][2]; + theMult[1][3] = 0; + + theMult[2][0] = m_Data[2][0] * inMatrix.m_Data[0][0] + m_Data[2][1] * inMatrix.m_Data[1][0] + + m_Data[2][2] * inMatrix.m_Data[2][0]; + theMult[2][1] = m_Data[2][0] * inMatrix.m_Data[0][1] + m_Data[2][1] * inMatrix.m_Data[1][1] + + m_Data[2][2] * inMatrix.m_Data[2][1]; + theMult[2][2] = m_Data[2][0] * inMatrix.m_Data[0][2] + m_Data[2][1] * inMatrix.m_Data[1][2] + + m_Data[2][2] * inMatrix.m_Data[2][2]; + theMult[2][3] = 0; + + theMult[3][0] = m_Data[3][0] * inMatrix.m_Data[0][0] + m_Data[3][1] * inMatrix.m_Data[1][0] + + m_Data[3][2] * inMatrix.m_Data[2][0] + inMatrix.m_Data[3][0]; + theMult[3][1] = m_Data[3][0] * inMatrix.m_Data[0][1] + m_Data[3][1] * inMatrix.m_Data[1][1] + + m_Data[3][2] * inMatrix.m_Data[2][1] + inMatrix.m_Data[3][1]; + theMult[3][2] = m_Data[3][0] * inMatrix.m_Data[0][2] + m_Data[3][1] * inMatrix.m_Data[1][2] + + m_Data[3][2] * inMatrix.m_Data[2][2] + inMatrix.m_Data[3][2]; + theMult[3][3] = 1.0f; + + return Set(theMult); +} + +//============================================================================== +/** + * Standard matrix multiplication + * @todo MF - Convert to SSE Assembly Code + * @param inMatrix matrix to multiply with + */ +RuntimeMatrix &RuntimeMatrix::Multiply(const RuntimeMatrix &inMatrix) +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + FLOAT theMult[4][4]; + + theMult[0][0] = m_Data[0][0] * inMatrix.m_Data[0][0] + m_Data[1][0] * inMatrix.m_Data[0][1] + + m_Data[2][0] * inMatrix.m_Data[0][2] + m_Data[3][0] * inMatrix.m_Data[0][3]; + theMult[0][1] = m_Data[0][1] * inMatrix.m_Data[0][0] + m_Data[1][1] * inMatrix.m_Data[0][1] + + m_Data[2][1] * inMatrix.m_Data[0][2] + m_Data[3][1] * inMatrix.m_Data[0][3]; + theMult[0][2] = m_Data[0][2] * inMatrix.m_Data[0][0] + m_Data[1][2] * inMatrix.m_Data[0][1] + + m_Data[2][2] * inMatrix.m_Data[0][2] + m_Data[3][2] * inMatrix.m_Data[0][3]; + theMult[0][3] = m_Data[0][3] * inMatrix.m_Data[0][0] + m_Data[1][3] * inMatrix.m_Data[0][1] + + m_Data[2][3] * inMatrix.m_Data[0][2] + m_Data[3][3] * inMatrix.m_Data[0][3]; + theMult[1][0] = m_Data[0][0] * inMatrix.m_Data[1][0] + m_Data[1][0] * inMatrix.m_Data[1][1] + + m_Data[2][0] * inMatrix.m_Data[1][2] + m_Data[3][0] * inMatrix.m_Data[1][3]; + theMult[1][1] = m_Data[0][1] * inMatrix.m_Data[1][0] + m_Data[1][1] * inMatrix.m_Data[1][1] + + m_Data[2][1] * inMatrix.m_Data[1][2] + m_Data[3][1] * inMatrix.m_Data[1][3]; + theMult[1][2] = m_Data[0][2] * inMatrix.m_Data[1][0] + m_Data[1][2] * inMatrix.m_Data[1][1] + + m_Data[2][2] * inMatrix.m_Data[1][2] + m_Data[3][2] * inMatrix.m_Data[1][3]; + theMult[1][3] = m_Data[0][3] * inMatrix.m_Data[1][0] + m_Data[1][3] * inMatrix.m_Data[1][1] + + m_Data[2][3] * inMatrix.m_Data[1][2] + m_Data[3][3] * inMatrix.m_Data[1][3]; + theMult[2][0] = m_Data[0][0] * inMatrix.m_Data[2][0] + m_Data[1][0] * inMatrix.m_Data[2][1] + + m_Data[2][0] * inMatrix.m_Data[2][2] + m_Data[3][0] * inMatrix.m_Data[2][3]; + theMult[2][1] = m_Data[0][1] * inMatrix.m_Data[2][0] + m_Data[1][1] * inMatrix.m_Data[2][1] + + m_Data[2][1] * inMatrix.m_Data[2][2] + m_Data[3][1] * inMatrix.m_Data[2][3]; + theMult[2][2] = m_Data[0][2] * inMatrix.m_Data[2][0] + m_Data[1][2] * inMatrix.m_Data[2][1] + + m_Data[2][2] * inMatrix.m_Data[2][2] + m_Data[3][2] * inMatrix.m_Data[2][3]; + theMult[2][3] = m_Data[0][3] * inMatrix.m_Data[2][0] + m_Data[1][3] * inMatrix.m_Data[2][1] + + m_Data[2][3] * inMatrix.m_Data[2][2] + m_Data[3][3] * inMatrix.m_Data[2][3]; + + theMult[3][0] = m_Data[0][0] * inMatrix.m_Data[3][0] + m_Data[1][0] * inMatrix.m_Data[3][1] + + m_Data[2][0] * inMatrix.m_Data[3][2] + m_Data[3][0] * inMatrix.m_Data[3][3]; + theMult[3][1] = m_Data[0][1] * inMatrix.m_Data[3][0] + m_Data[1][1] * inMatrix.m_Data[3][1] + + m_Data[2][1] * inMatrix.m_Data[3][2] + m_Data[3][1] * inMatrix.m_Data[3][3]; + theMult[3][2] = m_Data[0][2] * inMatrix.m_Data[3][0] + m_Data[1][2] * inMatrix.m_Data[3][1] + + m_Data[2][2] * inMatrix.m_Data[3][2] + m_Data[3][2] * inMatrix.m_Data[3][3]; + theMult[3][3] = m_Data[0][3] * inMatrix.m_Data[3][0] + m_Data[1][3] * inMatrix.m_Data[3][1] + + m_Data[2][3] * inMatrix.m_Data[3][2] + m_Data[3][3] * inMatrix.m_Data[3][3]; + + return Set(theMult); +} + +//============================================================================== +/** + * Toggle between left-hand and right-hand coordinate system + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::FlipCoordinateSystem() +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + // rotation conversion + m_Data[0][2] *= -1; + m_Data[1][2] *= -1; + m_Data[2][0] *= -1; + m_Data[2][1] *= -1; + + // translation conversion + m_Data[3][2] *= -1; + + return *this; +} + +//============================================================================== +/** + * Rotate this matrix to align with the rotation of the specified matrix. + * + * @param inMatrix the maxtrix we are cloning. + * @param inMirrorFlag flag indicating that we should flip the z and face the opposite + *direction. + * @return This matrix after the rotation. + */ +RuntimeMatrix &RuntimeMatrix::CloneRotation(const RuntimeMatrix &inMatrix, BOOL inMirrorFlag /*= false*/) +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + // Create the axes + RuntimeVector3 theZ(inMatrix.Get(2, 0), inMatrix.Get(2, 1), inMatrix.Get(2, 2)); + if (inMirrorFlag) + theZ *= -1; + RuntimeVector3 theY(inMatrix.Get(1, 0), inMatrix.Get(1, 1), inMatrix.Get(1, 2)); + RuntimeVector3 theX(theY); + theX.CrossProduct(theZ); + + // Normalize + theX.Normalize(); + theY.Normalize(); + theZ.Normalize(); + + // Copy it into the matrix + m_Data[0][0] = theX.m_X; + m_Data[0][1] = theX.m_Y; + m_Data[0][2] = theX.m_Z; + + m_Data[1][0] = theY.m_X; + m_Data[1][1] = theY.m_Y; + m_Data[1][2] = theY.m_Z; + + m_Data[2][0] = theZ.m_X; + m_Data[2][1] = theZ.m_Y; + m_Data[2][2] = theZ.m_Z; + + return *this; +} + +//============================================================================== +/** + * Compute the square distance between the position vectors of two transforms. + * @param inMatrix the other transform, signifying a global object position for example + * @return the square of the "distance" between the two transforms + */ +FLOAT RuntimeMatrix::SquareDistance(const RuntimeMatrix &inMatrix) const +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + FLOAT theResult = 0; + FLOAT theFactor; + + theFactor = m_Data[3][0] - inMatrix.m_Data[3][0]; + theFactor *= theFactor; + theResult += theFactor; + + theFactor = m_Data[3][1] - inMatrix.m_Data[3][1]; + theFactor *= theFactor; + theResult += theFactor; + + theFactor = m_Data[3][2] - inMatrix.m_Data[3][2]; + theFactor *= theFactor; + theResult += theFactor; + + return theResult; +} + +//============================================================================== +/** + * Simple assignment operator. + * @param inMatrix new matrix being assigned + * @return reference to this modified matrix + */ +RuntimeMatrix &RuntimeMatrix::operator=(const RuntimeMatrix &inMatrix) +{ + Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); + return *this; +} + +//============================================================================== +/** + * Compares this matrix's elements with another matrix's and returns true + * if the matrices are equivalent. + * @param inMatrix the matrix we are comparing against + * @return true if all elements are within EPSILON of each other. + */ +BOOL RuntimeMatrix::operator==(const RuntimeMatrix &inMatrix) const +{ + PerfLogMathEvent1(DATALOGGER_MATRIX); + + for (INT32 iRow = 0; iRow < 4; ++iRow) { + for (INT32 iCol = 0; iCol < 4; ++iCol) { + if (::fabs(m_Data[iRow][iCol] - inMatrix.m_Data[iRow][iCol]) > RUNTIME_EPSILON) + return false; + } + } + return true; +} + +//============================================================================== +/** + * Compares this matrix's elements with another matrix's and returns true + * if the matrices are not equivalent. + * @param inMatrix the matrix we are comparing against + * @return true if one or more elements are more than EPSILON from each other + */ +BOOL RuntimeMatrix::operator!=(const RuntimeMatrix &inMatrix) const +{ + // Reuse same code path.. + return !(*this == inMatrix); +} + +//============================================================================== +/** + * Standardized conversion to string. + * @param outString string becoming a representation for the matrix + */ +// void CMatrix::ToString( AK_STRING& outString ) const +//{ +// INT8 theBuffer[ 256 ]; +// +// Q3DStudio_sprintf +// ( +// theBuffer, 255, +// "%.2f %.2f %.2f %.2f " +// "%.2f %.2f %.2f %.2f " +// "%.2f %.2f %.2f %.2f " +// "%.2f %.2f %.2f %.2f", +// +// m_Data.m[ 0 ][ 0 ], +// m_Data.m[ 0 ][ 1 ], +// m_Data.m[ 0 ][ 2 ], +// m_Data.m[ 0 ][ 3 ], +// +// m_Data.m[ 1 ][ 0 ], +// m_Data.m[ 1 ][ 1 ], +// m_Data.m[ 1 ][ 2 ], +// m_Data.m[ 1 ][ 3 ], +// +// m_Data.m[ 2 ][ 0 ], +// m_Data.m[ 2 ][ 1 ], +// m_Data.m[ 2 ][ 2 ], +// m_Data.m[ 2 ][ 3 ], +// +// m_Data.m[ 3 ][ 0 ], +// m_Data.m[ 3 ][ 1 ], +// m_Data.m[ 3 ][ 2 ], +// m_Data.m[ 3 ][ 3 ] +// ); +// +// outString = theBuffer; +//} +// +////============================================================================== +///** +// * Standardized conversion from string. +// * @param inString string being a representation for the matrix +// */ +// void CMatrix::FromString( const AK_STRING& inString ) +//{ +// std::sscanf +// ( +// inString.c_str( ), +// +// "%f %f %f %f " +// "%f %f %f %f " +// "%f %f %f %f " +// "%f %f %f %f", +// +// &m_Data.m[ 0 ][ 0 ], +// &m_Data.m[ 0 ][ 1 ], +// &m_Data.m[ 0 ][ 2 ], +// &m_Data.m[ 0 ][ 3 ], +// +// &m_Data.m[ 1 ][ 0 ], +// &m_Data.m[ 1 ][ 1 ], +// &m_Data.m[ 1 ][ 2 ], +// &m_Data.m[ 1 ][ 3 ], +// +// &m_Data.m[ 2 ][ 0 ], +// &m_Data.m[ 2 ][ 1 ], +// &m_Data.m[ 2 ][ 2 ], +// &m_Data.m[ 2 ][ 3 ], +// +// &m_Data.m[ 3 ][ 0 ], +// &m_Data.m[ 3 ][ 1 ], +// &m_Data.m[ 3 ][ 2 ], +// &m_Data.m[ 3 ][ 3 ] +// ); +//} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMatrix.h b/src/Runtime/Source/system/Qt3DSMatrix.h new file mode 100644 index 00000000..4ef74420 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMatrix.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class RuntimeVector3; + +//============================================================================== +/** + * A row major matrix for 3D transformation. + * + * Matrix[row][column] +@code + | 0 1 2 3 | or | 00 01 02 03 | or | Xx Xy Xz w | + | 4 5 6 7 | | 10 11 12 13 | | Yx Yy Yz w | + | 8 9 A B | | 20 21 22 23 | | Zx Zy Zz w | + | C D E F | | 30 31 32 33 | | Tx Ty Tz w | +@endcode + * Rotations are concatenated in the the following order: YXZ + * All rotations are clockwise when viewed down the positive axis + * towards the origin. + */ +class RuntimeMatrix +{ + //============================================================================== + // Enumerations + //============================================================================== +public: + enum ERotationOrder { + ROTATIONORDER_XYZ = 0, + ROTATIONORDER_YZX, + ROTATIONORDER_ZXY, + ROTATIONORDER_XZY, + ROTATIONORDER_YXZ, + ROTATIONORDER_ZYX, + + ROTATIONORDER_XYZR, + ROTATIONORDER_YZXR, + ROTATIONORDER_ZXYR, + ROTATIONORDER_XZYR, + ROTATIONORDER_YXZR, + ROTATIONORDER_ZYXR + }; + + enum EOrientation { ORIENTATION_LEFT_HANDED = 0, ORIENTATION_RIGHT_HANDED }; + + //============================================================================== + // Constants + //============================================================================== +public: + static const RuntimeMatrix IDENTITY; ///< Enabling fast initialization from static identity matrix + + //============================================================================== + // Fields + //============================================================================== +public: + FLOAT m_Data[4][4]; ///< 16 elements in a 4 x 4 + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + RuntimeMatrix(const BOOL inInitializeIdentity = true); + RuntimeMatrix(const RuntimeMatrix &inMatrix); + RuntimeMatrix(const FLOAT inComponents[4][4]); + +public: // Initialization + RuntimeMatrix &Zero(); + RuntimeMatrix &Identity(); + + RuntimeMatrix &Set(const RuntimeMatrix &inMatrix); + RuntimeMatrix &Set(const FLOAT inComponents[4][4]); + RuntimeMatrix &Set(const RuntimeVector3 &inTranslation, const RuntimeVector3 &inRotation, const RuntimeVector3 &inScale, + const RuntimeVector3 &inPivot, const UINT8 inRotationOrder, + const UINT8 inCoordinateSystem); + + RuntimeMatrix &SetTranslate(const RuntimeVector3 &inTranslate); + RuntimeMatrix &SetRotate(const RuntimeVector3 &inRotation, const UINT8 inRotationOrder = ROTATIONORDER_XYZ, + const UINT8 inCoordinateSystem = ORIENTATION_LEFT_HANDED); + RuntimeMatrix &SetScale(const RuntimeVector3 &inScale); + +public: // Functions + BOOL IsIdentity() const; + BOOL IsAffine() const; + RuntimeMatrix &Translate(const RuntimeVector3 &inTranslate); + RuntimeMatrix &Scale(const RuntimeVector3 &inScale); + RuntimeMatrix &Transpose(); + FLOAT Invert(); + RuntimeMatrix &MultiplyAffine(const RuntimeMatrix &inMatrix); + RuntimeMatrix &Multiply(const RuntimeMatrix &inMatrix); + RuntimeMatrix &FlipCoordinateSystem(); + RuntimeMatrix &CloneRotation(const RuntimeMatrix &inMatrix, BOOL inMirrorFlag = false); + FLOAT SquareDistance(const RuntimeMatrix &inMatrix) const; + +public: // Operators + RuntimeMatrix &operator=(const RuntimeMatrix &inMatrix); + BOOL operator==(const RuntimeMatrix &inMatrix) const; + BOOL operator!=(const RuntimeMatrix &inMatrix) const; + +public: // Script based accessors + inline FLOAT Get(const INT32 inRow, const INT32 inColumn) const + { + return m_Data[inRow][inColumn]; + } + inline void Set(const INT32 inRow, const INT32 inColumn, const FLOAT inValue) + { + m_Data[inRow][inColumn] = inValue; + } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemory.cpp b/src/Runtime/Source/system/Qt3DSMemory.cpp new file mode 100644 index 00000000..17fa5c86 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemory.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemory.h" + +//============================================================================== +// OS level memory routines +//============================================================================== +Q3DStudio::CMemory::TMalloc Q3DStudio::CMemory::s_Malloc = NULL; +Q3DStudio::CMemory::TRealloc Q3DStudio::CMemory::s_Realloc = NULL; +Q3DStudio::CMemory::TFree Q3DStudio::CMemory::s_Free = NULL; + +//============================================================================== +/** + * Overrides basic memory allocation/deallocation routines + * @param inMalloc memory allocation routine + * @param inFree memory deallocation routine + * @param inRealloc memory reallocation routine + */ +void Q3DStudio::CMemory::SetMemoryFunctions(const TMalloc inMalloc, const TFree inFree, + const TRealloc inRealloc) +{ + s_Malloc = inMalloc; + s_Realloc = inRealloc; + s_Free = inFree; +} + +static Q3DStudio::CMemoryManager *s_globalManager = nullptr; +static Q3DStudio::CMemoryHeap *s_globalHeap = nullptr; + +//============================================================================== +/** + * Boot up the pooled memory manager and return it. + * @note The manager has to be initialized before use: + * GetMemoryManager( ).Initialize( "GlobalManager", g_ChunkSize, g_ChunkCount ); + * @return Q3DStudio::CMemoryManager reference to the global object + */ +Q3DStudio::CMemoryManager &GetMemoryManager() +{ + if (!s_globalManager) + s_globalManager = new Q3DStudio::CMemoryManager; + return *s_globalManager; +} + +//============================================================================== +/** + * Return a reference to the global heap object. + * @return Q3DStudio::CMemoryHeap reference to the global object + */ +Q3DStudio::CMemoryHeap &GetMemoryHeap() +{ + if (!s_globalHeap) + s_globalHeap = new Q3DStudio::CMemoryHeap; + return *s_globalHeap; +} + +//============================================================================== +// Q3DStudio_new operator prototypes (5 args) +//============================================================================== +void *operator new(size_t inReportedSize, size_t inOfficialSize, const char *inType, + const char *inFile, int inLine) +{ + Q3DStudio_UNREFERENCED_PARAMETER(inReportedSize); + Q3DStudio_ASSERT(inReportedSize == inOfficialSize); + + return Q3DStudio_HANDLER_NEW.Allocate(static_cast(inOfficialSize), + inType, inFile, inLine); +} + +//============================================================================== +/** + * Override 'operator delete' in order to track memory usage. + * + * So what's the use of the overloaded delete with special arguments? There is + * actually one case in which it will be called--when an exception is thrown + * during object construction. As you might recall, there is a contract implicit + * in the language that if an exception happens during the construction of an object, + * the memory for this object will be automatically deallocated. It so happens + * that during object's construction the compiler is still aware of which version + * of operator new was called to allocate memory. It is therefore able to generate + * a call to the corresponding version of delete, in case an exception is thrown. + * After the successful completion of construction, this information is no longer + * available and the compiler has no means to guess which version of global delete + * is appropriate for a given object. + */ +void operator delete(void *inReportedAddress, size_t inOfficialSize, const char *, const char *, + int) +{ + Q3DStudio_HANDLER_NEW.Free(inReportedAddress, + static_cast(inOfficialSize)); +} + +//============================================================================== +// Q3DStudio_virtual_new operators (4 args) +//============================================================================== +void *operator new(size_t inReportedSize, const char *inType, const char *inFile, int inLine) +{ + return Q3DStudio::CMemoryFilter::Allocate(static_cast(inReportedSize), inType, + inFile, inLine, false); +} + +void operator delete(void *inReportedAddress, const char *, const char *, int) +{ + Q3DStudio::CMemoryFilter::Free(inReportedAddress); +} diff --git a/src/Runtime/Source/system/Qt3DSMemory.h b/src/Runtime/Source/system/Qt3DSMemory.h new file mode 100644 index 00000000..cc04bf73 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemory.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#ifndef _INTEGRITYPLATFORM +#include +#endif +#include "Qt3DSMemoryHeap.h" +#include "Qt3DSMemoryManager.h" +#include "Qt3DSMemoryFilter.h" +#include "Qt3DSMemoryStatistics.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Single overridable exit point for all low level memory calls. + */ +class CMemory +{ + //============================================================================== + // Typedefs + //============================================================================== +public: + typedef void *(*TMalloc)(size_t inSize); + typedef void (*TFree)(void *inPtr); + typedef void *(*TRealloc)(void *inPtr, size_t inSize); + + //============================================================================== + // Fields + //============================================================================== +protected: + static TMalloc s_Malloc; ///< function pointer to malloc operation + static TFree s_Free; ///< function pointer to free operation + static TRealloc s_Realloc; ///< function pointer to realloc operation + + //============================================================================== + // Methods + //============================================================================== +public: // Memory override + static void SetMemoryFunctions(const TMalloc inMalloc, const TFree inFree, + const TRealloc inRealloc); + +public: // Function access + static TMalloc Malloc() { return s_Malloc; } + static TFree Free() { return s_Free; } + static TRealloc Realloc() { return s_Realloc; } +}; + +} // namespace Q3DStudio + +//============================================================================== +// Globals +//============================================================================== +Q3DStudio::CMemoryManager &GetMemoryManager(); +Q3DStudio::CMemoryHeap &GetMemoryHeap(); + +//============================================================================== +// Handlers +//============================================================================== +#ifndef Q3DStudio_HANDLER_NEW +#define Q3DStudio_HANDLER_NEW GetMemoryManager() +#endif // Q3DStudio_HANDLER_NEW + +#ifndef Q3DStudio_HANDLER_ALLOC +#define Q3DStudio_HANDLER_ALLOC GetMemoryManager() +#endif // Q3DStudio_HANDLER_ALLOC + +#ifndef Q3DStudio_HANDLER_FILTER +#define Q3DStudio_HANDLER_FILTER GetMemoryManager() +#endif // Q3DStudio_HANDLER_FILTER + +//============================================================================== +// Q3DStudio new defines +//============================================================================== +#undef new +#undef delete + +#ifndef Q3DStudio_new +#define Q3DStudio_new(type) new (sizeof(type), "class " #type, __FILE__, __LINE__) +#endif // Q3DStudio_new + +#ifndef Q3DStudio_delete +#define Q3DStudio_delete(ptr, type) \ + if (ptr) { \ + reinterpret_cast(ptr)->~type(); \ + Q3DStudio_HANDLER_NEW.Free(ptr, sizeof(type)); \ + } +#endif // Q3DStudio_delete + +#ifndef Q3DStudio_virtual_new +#define Q3DStudio_virtual_new(type) new ("class " #type, __FILE__, __LINE__) +#endif // Q3DStudio_virtual_new + +#ifndef Q3DStudio_virtual_delete +#define Q3DStudio_virtual_delete(ptr, type) \ + if (ptr) { \ + static_cast(ptr)->~type(); \ + Q3DStudio::CMemoryFilter::Free(ptr); \ + } +#endif // Q3DStudio_virtual_delete + +//============================================================================== +// Q3DStudio alloc defines +//============================================================================== +#ifndef Q3DStudio_allocate +#define Q3DStudio_allocate(type, count) \ + reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Allocate( \ + static_cast(sizeof(type) * (count)), #type "[]", __FILE__, __LINE__)) +#endif // Q3DStudio_allocate + +#ifndef Q3DStudio_allocate_desc +#define Q3DStudio_allocate_desc(type, count, desc) \ + reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Allocate( \ + static_cast(sizeof(type) * (count)), desc, __FILE__, __LINE__)) +#endif // Q3DStudio_allocate_desc + +#ifndef Q3DStudio_reallocate +#define Q3DStudio_reallocate(ptr, type, oldcount, newcount) \ + reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Reallocate( \ + ptr, static_cast(sizeof(type) * (oldcount)), \ + static_cast(sizeof(type) * (newcount)), #type "[]", __FILE__, __LINE__)) +#endif // Q3DStudio_reallocate + +#ifndef Q3DStudio_reallocate_desc +#define Q3DStudio_reallocate_desc(ptr, type, oldcount, newcount, desc) \ + reinterpret_cast(Q3DStudio_HANDLER_ALLOC.Reallocate( \ + ptr, static_cast(sizeof(type) * (oldcount)), \ + static_cast(sizeof(type) * (newcount)), desc, __FILE__, __LINE__)) +#endif // Q3DStudio_reallocate_desc + +#ifndef Q3DStudio_free +#define Q3DStudio_free(ptr, type, count) \ + Q3DStudio_HANDLER_ALLOC.Free(ptr, static_cast(sizeof(type) * (count))) +#endif // Q3DStudio_free + +//============================================================================== +// Q3DStudio_new - operator prototypes (5 args) +//============================================================================== +void *operator new(size_t inReportedSize, size_t inOfficialSize, const char *inType, + const char *inFile, int inLine); +void operator delete(void *inReportedAddress, size_t inOfficialSize, const char *, const char *, + int); + +//============================================================================== +// Q3DStudio_virtual_new and new - operator prototypes (4 args) +//============================================================================== +void *operator new(size_t inReportedSize, const char *inType, const char *inFile, int inLine); +void operator delete(void *inReportedAddress, const char *, const char *, int); diff --git a/src/Runtime/Source/system/Qt3DSMemoryFilter.cpp b/src/Runtime/Source/system/Qt3DSMemoryFilter.cpp new file mode 100644 index 00000000..f6d6591c --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryFilter.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryFilter.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Allocate a chunk of memory and add a header to track it. + * @param inSize size of requested memory block, in bytes + * @param inType allocation description + * @param inFile file name + * @param inFunction method name + * @param inLine line number + * @param inClear true to clear allocated memory to zero + * @return void* a pointer to a memory block large enough to hold inSize bytes + */ +void *CMemoryFilter::Allocate(const INT32 inSize, const CHAR *inType, const CHAR *inFile, + const INT32 inLine, const BOOL inClear) +{ + const INT32 theTotalSize = inSize + Q3DStudio_MEMORY_ALIGNMENT; + + INT32 *theMemory = reinterpret_cast( + Q3DStudio_HANDLER_FILTER.Allocate(theTotalSize, inType, inFile, inLine)); + + theMemory[0] = FILTER_DOGTAG; + theMemory[1] = theTotalSize; + + if (inClear) + Q3DStudio_memset(reinterpret_cast(theMemory) + Q3DStudio_MEMORY_ALIGNMENT, 0, + inSize); + + return reinterpret_cast(theMemory) + Q3DStudio_MEMORY_ALIGNMENT; +} + +//============================================================================== +/** + * Free a block of memory that was allocated and tagged here. + * @param inPointer pointer given in a previous filter allocation + */ +void CMemoryFilter::Free(void *inPointer) +{ + if (!inPointer) + return; + + INT32 *theMemory = + reinterpret_cast(reinterpret_cast(inPointer) - Q3DStudio_MEMORY_ALIGNMENT); + + // Sanity check: Did we allocate this memory in the first place? + // If this throws we may be calling Q3DStudio_virtual_delete on memory that was getten from + // Q3DStudio_new + Q3DStudio_ASSERT(FILTER_DOGTAG == theMemory[0]); + Q3DStudio_HANDLER_FILTER.Free(theMemory, theMemory[1]); +} + +//============================================================================== +/** + * Re-allocate an existing chunk of memory and track it. + * @param inPointer pointer given in a previous allocation + * @param inNewSize size of requested memory block, in bytes + * @param inNewType new allocation description + * @param inFile file name + * @param inFunction method name + * @param inLine line number + * @return void* a pointer to a memory block large enough to hold inSize bytes + */ +void *CMemoryFilter::Reallocate(void *inPointer, const INT32 inNewSize, const CHAR *inNewType, + const CHAR *inFile, const INT32 inLine) +{ + INT32 *theNewMemory = NULL; + const INT32 theTotalSize = inNewSize + Q3DStudio_MEMORY_ALIGNMENT; + + // Dogtag is not valid if the old pointer is NULL + if (inPointer) { + INT32 *theOldMemory = reinterpret_cast(reinterpret_cast(inPointer) + - Q3DStudio_MEMORY_ALIGNMENT); + Q3DStudio_ASSERT(FILTER_DOGTAG == theOldMemory[0]); + theNewMemory = reinterpret_cast(Q3DStudio_HANDLER_FILTER.Reallocate( + theOldMemory, theOldMemory[1], theTotalSize, inNewType, inFile, inLine)); + } else { + theNewMemory = reinterpret_cast( + Q3DStudio_HANDLER_FILTER.Reallocate(NULL, 0, theTotalSize, inNewType, inFile, inLine)); + } + + theNewMemory[0] = FILTER_DOGTAG; + theNewMemory[1] = theTotalSize; + return reinterpret_cast(theNewMemory) + Q3DStudio_MEMORY_ALIGNMENT; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryFilter.h b/src/Runtime/Source/system/Qt3DSMemoryFilter.h new file mode 100644 index 00000000..df9367da --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryFilter.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Aggregation interface for legacy calls that don't remember allocation size. + * + * CMemoryManager and its pools require that the size must be sent along with + * any call, including the Free call. Normal memory calls do not require this + * information and this filter class is used to intercept these calls and + * add a header to each call before forwarded to the manager. This thin class + * allows old school calls such as malloc and free to still use the advantages + * of a pooled memory system without impacting the cleanliness and memory + * footprint of the modern system. + */ +class CMemoryFilter +{ + //============================================================================== + // Constants + //============================================================================== +protected: + const static INT32 FILTER_DOGTAG = 0x1337f1d0; + + //============================================================================== + // Methods + //============================================================================== +public: // Allocation Deallocation + static void *Allocate(const INT32 inSize, const CHAR *inType, const CHAR *inFile, + const INT32 inLine, const BOOL inClear); + static void Free(void *inPointer); + static void *Reallocate(void *inPointer, const INT32 inNewSize, const CHAR *inNewType, + const CHAR *inFile, const INT32 inLine); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp b/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp new file mode 100644 index 00000000..4ab36178 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemory.h" +#include "Qt3DSMemoryHeap.h" +#include "Qt3DSMemoryStatistics.h" +#include "Qt3DSIStream.h" +#include "foundation/Qt3DSLogging.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Static Initialzation +//============================================================================== +CMemoryProbe CMemoryHeap::s_Probe; + +#if Q3DStudio_MEMORY_HEAPTRACKING +CMemoryHeap::TMemoryReport CMemoryHeap::s_MemoryReport; +#endif // Q3DStudio_MEMORY_HEAPTRACKING + +//============================================================================== +/** + * Allocate a chunk of memory and potentially track it. + * @param inSize size of requested memory block, in bytes + * @param inDescription allocation description such as class name or pool name + * @param inFile file name + * @param inFunction method name + * @param inLine line number + * @return void* a pointer to a memory block large enough to hold inSize bytes + */ +void *CMemoryHeap::Allocate(const INT32 inSize, const CHAR *inDescription, const CHAR *inFile, + const INT32 inLine) +{ + // Always track stats and trigger snapshot if this is a new record + s_Probe.Allocate(inSize); + + // Check if we are exceeding the max memory limit + if (Q3DStudio_MEMORY_LIMIT > 0 + && s_Probe.GetBytes(Q3DStudio::MEMSCOPE_GLOBAL, Q3DStudio::MEMVALUE_CURRENT) + > Q3DStudio_MEMORY_LIMIT) { + qCCritical (qt3ds::OUT_OF_MEMORY) + << "Q3DStudio_MEMORY_UNIT exceeded " << Q3DStudio_MEMORY_LIMIT; + Q3DStudio_ASSERT(false); + } + +#if Q3DStudio_MEMORY_HEAPTRACKING + void *theAllocatedPtr = CMemory::Malloc()(static_cast(inSize)); + if (s_MemoryReport.GetCount() < s_MemoryReport.GetCapacity()) { + SReportEntry theEntry = { theAllocatedPtr, inSize, inDescription, inFile, inLine }; + s_MemoryReport.Push(theEntry); + } else { + static BOOL s_FullWarning = false; + if (!s_FullWarning) { + qCWarning (qt3ds::TRACE_INFO) << "HeapTracker full. " + << "Please increase Q3DStudio_MEMORY_HEAPTRACKINGSIZE(" + << Q3DStudio_MEMORY_HEAPTRACKINGSIZE << ") " + << "to track all allocation and tune your pools to avoid " + << "hitting the heap."; + s_FullWarning = true; + } + } + return theAllocatedPtr; +#else + Q3DStudio_UNREFERENCED_PARAMETER(inLine); + Q3DStudio_UNREFERENCED_PARAMETER(inFile); + Q3DStudio_UNREFERENCED_PARAMETER(inDescription); + + return CMemory::Malloc()(static_cast(inSize)); +#endif // Q3DStudio_MEMORY_HEAPTRACKING +} + +//============================================================================== +/** + * Free a block of memory allocated using CMemoryHeap::Allocate + * @param inPointer pointer given in a previous allocation + * @param inSize size of given memory block, in bytes + */ +void CMemoryHeap::Free(void *inPointer, INT32 inSize) +{ + // No-Op on NULL + if (!inPointer) + return; + +#if Q3DStudio_MEMORY_HEAPTRACKING + RemoveReport(inPointer); +#endif // Q3DStudio_MEMORY_HEAPTRACKING + + s_Probe.Free(inSize); + return CMemory::Free()(inPointer); +} + +//============================================================================== +/** + * Re-allocate an existing chunk of memory and potentially track it. + * @param inPointer pointer given in a previous allocation + * @param inOldSize size of current memory block, in bytes + * @param inNewSize size of requested memory block, in bytes + * @param inNewDescription allocation description such as class name or pool name + * @param inFile file name + * @param inFunction method name + * @param inLine line number + * @return void* a pointer to a memory block large enough to hold inSize bytes + */ +void *CMemoryHeap::Reallocate(void *inPointer, const INT32 inOldSize, const INT32 inNewSize, + const CHAR *inNewDescription, const CHAR *inFile, const INT32 inLine) +{ + // Make sure this isn't a new malloc + if (!inPointer) + return Allocate(inNewSize, inNewDescription, inFile, inLine); + + // Always track stats and record new high if it's a record + s_Probe.Allocate(inNewSize); + s_Probe.Free(inOldSize); + + // Check if we are exceeding the max memory limit + Q3DStudio_ASSERT(Q3DStudio_MEMORY_LIMIT == 0 + ? true + : s_Probe.GetBytes(Q3DStudio::MEMSCOPE_GLOBAL, Q3DStudio::MEMVALUE_CURRENT) + < Q3DStudio_MEMORY_LIMIT); + +#if Q3DStudio_MEMORY_HEAPTRACKING + RemoveReport(inPointer); + + void *theReallocatedPtr = CMemory::Realloc()(inPointer, static_cast(inNewSize)); + + SReportEntry theEntry = { theReallocatedPtr, inNewSize, inNewDescription, inFile, inLine }; + s_MemoryReport.Push(theEntry); + + return theReallocatedPtr; +#else + return CMemory::Realloc()(inPointer, static_cast(inNewSize)); +#endif // Q3DStudio_MEMORY_HEAPTRACKING +} + +//============================================================================== +/** + * Retrieves memory info about a particular allocation + * @param inPointer allocated memory + * @return SMemoryHeapReportEntry* memory report + */ +CMemoryHeap::SReportEntry *CMemoryHeap::FindReport(void *inPointer) +{ + Q3DStudio_UNREFERENCED_PARAMETER(inPointer); + +#if Q3DStudio_MEMORY_HEAPTRACKING + INT32 theEnd = s_MemoryReport.GetCount(); + for (INT32 theIndex = 0; theIndex < theEnd; ++theIndex) + if (s_MemoryReport[theIndex].m_AllocatedPointer == inPointer) + return &s_MemoryReport[theIndex]; + + Q3DStudio_ASSERT(false); +#endif // Q3DStudio_MEMORY_HEAPTRACKING + + return NULL; +} + +//============================================================================== +/** + * Removes memory info due to a deallocation. + * @param inPointer allocated memory + */ +void CMemoryHeap::RemoveReport(void *inPointer) +{ + Q3DStudio_UNREFERENCED_PARAMETER(inPointer); + +#if Q3DStudio_MEMORY_HEAPTRACKING + INT32 theEnd = s_MemoryReport.GetCount(); + for (INT32 theIndex = 0; theIndex < theEnd; ++theIndex) { + if (s_MemoryReport[theIndex].m_AllocatedPointer == inPointer) { + s_MemoryReport.Remove(theIndex); + return; + } + } +#endif // Q3DStudio_MEMORY_HEAPTRACKING +} + +//============================================================================== +/** + * The memory probe records basic heap activity + * @return reference to probe + */ +CMemoryProbe &CMemoryHeap::GetProbe() +{ + return s_Probe; +} + +//============================================================================== +/** + * The report records all heap activity + * @return pointer to report if tracking is on, or NULL + */ +CMemoryHeap::TMemoryReport *CMemoryHeap::GetReport() +{ +#if Q3DStudio_MEMORY_HEAPTRACKING + return &s_MemoryReport; +#else + return NULL; +#endif // Q3DStudio_MEMORY_HEAPTRACKING +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryHeap.h b/src/Runtime/Source/system/Qt3DSMemoryHeap.h new file mode 100644 index 00000000..ba7c1306 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryHeap.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryProbe.h" +#include "Qt3DSFixedArray.h" +#include "Qt3DSMemorySettings.h" + +//============================================================================== +/** + * Low level entry points to the heap. + * + * Do not call these directly. Use Q3DStudio_new or Q3DStudio_allocate instead since + * those use the pools. + * @see CMemoryHeap + */ +#define Q3DStudio_heap_allocate(size, desc) \ + Q3DStudio::CMemoryHeap::Allocate(size, desc, __FILE__, __LINE__) +#define Q3DStudio_heap_reallocate(ptr, oldsize, newsize, newdesc) \ + Q3DStudio::CMemoryHeap::Reallocate(ptr, oldsize, newsize, newdesc, __FILE__, _LINE__) +#define Q3DStudio_heap_free(ptr, size) Q3DStudio::CMemoryHeap::Free(ptr, size) + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class IStream; + +//============================================================================== +/** + * Last memory interface before calls to memory callbacks or OS malloc. + * + * First of all, don't call this class directy. Use the macros + * Q3DStudio_heap_allocate and Q3DStudio_heap_free instead since they fill out file, + * line and function parameters for the tracking system. + * + * This is the single exit point for all heap memory allocations. Change this + * code to redirect memory to your own subsystems or add more tracking code to + * measure memory usage. Note however that most memory requests during runtime + * will never reach this point since memory pools will handle those requests. + * Large memory requests and emergency scenarios will still end up here. + * + * @note This class contains the only three real memory calls in Runtime. + */ +class CMemoryHeap +{ + //============================================================================== + // Structs + //============================================================================== +public: + /// Simple memory log entry + struct SReportEntry + { + const void *m_AllocatedPointer; ///< allocated pointer + INT32 m_Size; ///< size in bytes + const CHAR *m_Description; ///< simple description + const CHAR *m_File; ///< filename + INT32 m_Line; ///< line number + }; + + //============================================================================== + // Typedefs + //============================================================================== +public: + typedef CFixedArray TMemoryReport; + + //============================================================================== + // Fields + //============================================================================== +protected: + static CMemoryProbe s_Probe; ///< Light overall allocation statistics +#if Q3DStudio_MEMORY_HEAPTRACKING + static TMemoryReport s_MemoryReport; ///< Storage for memory logs +#endif // Q3DStudio_MEMORY_HEAPTRACKING + + //============================================================================== + // Methods + //============================================================================== +public: // Allocation/Deallocation + static void *Allocate(const INT32 inSize, const CHAR *inDescription, const CHAR *inFile, + const INT32 inLine); + static void Free(void *inPointer, INT32 inSize); + static void *Reallocate(void *inPointer, const INT32 inOldSize, const INT32 inNewSize, + const CHAR *inNewDescription, const CHAR *inFile, const INT32 inLine); + +public: // Statistics + static CMemoryProbe &GetProbe(); + static TMemoryReport *GetReport(); + +protected: // Low level memory overview + static SReportEntry *FindReport(void *inPointer); + static void RemoveReport(void *inPointer); + +public: // Report request + static void Report(IStream *inStream = NULL); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryManager.cpp b/src/Runtime/Source/system/Qt3DSMemoryManager.cpp new file mode 100644 index 00000000..a1ace59e --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryManager.cpp @@ -0,0 +1,453 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemory.h" +#include "Qt3DSMemoryManager.h" +#include "Qt3DSMemoryHeap.h" +#include "Qt3DSMemoryProbe.h" +#include "Qt3DSMemoryTracker.h" +#include "Qt3DSMemoryStatistics.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Create a new empty memory pool manager. + * + * The manager must be initialized before use or it will forward all requests + * to the heap. + */ +CMemoryManager::CMemoryManager() +{ + // Set default allocations functions if they are not already set + if (NULL == CMemory::Malloc()) + CMemory::SetMemoryFunctions(&malloc, &free, &realloc); + + CMemoryStatistics::AddManager(this); + +#if Q3DStudio_MEMORY_POOLTRACKING + Q3DStudio_memset(m_Histogram, 0, sizeof(m_Histogram)); + CMemoryStatistics::Overhead() += sizeof(m_Histogram); +#endif // Q3DStudio_MEMORY_POOLTRACKING +} + +//============================================================================== +/** + * Create a new initialized memory pool manager. + * + * @param inName short description of manager used in tracker + * @param inChunkSize array of values describing the chunk size of each pool + * @param inChunkCount array of values describing the number of chunks in each pool + */ +CMemoryManager::CMemoryManager(const CHAR *inName, + const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], + const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]) +{ + // Set default allocations functions if they are not already set + if (NULL == CMemory::Malloc()) + CMemory::SetMemoryFunctions(&malloc, &free, &realloc); + + CMemoryStatistics::AddManager(this); + Initialize(inName, inChunkSize, inChunkCount); + +#if Q3DStudio_MEMORY_POOLTRACKING + Q3DStudio_memset(m_Histogram, 0, sizeof(m_Histogram)); + CMemoryStatistics::Overhead() -= sizeof(m_Histogram); +#endif // Q3DStudio_MEMORY_POOLTRACKING +} + +//============================================================================== +/** + * Release the memory manager and all owned pools. + * + * Nobody better point to memory in these pool because the it will be + * invalid after this. + */ +CMemoryManager::~CMemoryManager() +{ + CMemoryStatistics::RemoveManager(this); + Release(); +} + +//============================================================================== +/** + * Configure the pool manager into separate pools of different chunk sizes. + * + * The chunk size array has to be increasing values such as: + * inChunkSize = { 8, 16, 32, 64, 96, 128, 256, 512, 1024 } + * but count doesn't: + * inChunkCount = { 500, 200, 1000, 200, 200, 100, 250, 50, 20 } + * + * The global memory manager settings are initialized in AKMemory.h + * + * @param inName short description of manager used in tracker + * @param inChunkSize array of Q3DStudio_MEMORY_POOLCOUNT values describing the chunk size + *of each pool + * @param inChunkCount array of Q3DStudio_MEMORY_POOLCOUNT values describing the number of + *chunks in each pool + */ +void CMemoryManager::Initialize(const CHAR *inName, + const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], + const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]) +{ + // Don't initialize more than once + Q3DStudio_ASSERT(m_Pool[0].GetChunkCount() == 0); + Q3DStudio_sprintf(m_Name, sizeof(m_Name), "%s", inName); + + for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) { + // Make sure pool are aligned to Q3DStudio_MEMORY_ALIGNMENT or smaller than + // Q3DStudio_MEMORY_ALIGNMENT + Q3DStudio_ASSERT(inChunkSize[thePoolIndex] < Q3DStudio_MEMORY_ALIGNMENT + || (inChunkSize[thePoolIndex] % Q3DStudio_MEMORY_ALIGNMENT) == 0); + m_Pool[thePoolIndex].Initialize(inName, inChunkSize[thePoolIndex], + inChunkCount[thePoolIndex]); + } +} + +//============================================================================== +/** + * Release all the memory allocated in Initialize - essentially "uninitialize". + */ +void CMemoryManager::Release() +{ + for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) + m_Pool[thePoolIndex].Release(); +} + +//============================================================================== +// ALLOCATION AND DEALLOCATION +//============================================================================== + +//============================================================================== +/** + * Fetch a new chunk of memory from the smallest pool possible + * @param inSize size of requested memory block, in bytes + * @param inType allocation description such as class name or pool name + * @param inFile file name + * @param inFunction method name + * @param inLine line number + * @return void* a pointer to a memory block large enough to hold inSize bytes + */ +void *CMemoryManager::Allocate(INT32 inSize, const CHAR *inType, const CHAR *inFile, + const INT32 inLine) +{ + Q3DStudio_ASSERT(inSize >= 0); + +#if Q3DStudio_MEMORY_POOLTRACKING + m_Histogram[Q3DStudio_min(inSize, 511)].Add(1); +#endif // Q3DStudio_MEMORY_POOLTRACKING + +#if Q3DStudio_MEMORY_LINETRACKING + inSize += sizeof(CMemoryTracker::SMemoryInfo); // make room for SMemoryInfo +#endif // Q3DStudio_MEMORY_LINETRACKING + + // Find the smallest pool that fits + void *thePointer = NULL; + INT32 thePoolIndex = 0; + while (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) { + // Does this pool fit? + if (inSize <= m_Pool[thePoolIndex].GetChunkSize()) { + thePointer = m_Pool[thePoolIndex].Allocate(); + break; + } + ++thePoolIndex; + } + + // // Record the amount of wasted bytes in this chunk + if (thePointer) { + // Basic tracking + m_ManagerData.m_Aligned.Allocate(inSize); +#if Q3DStudio_MEMORY_POOLTRACKING + m_PoolData[thePoolIndex].m_Aligned.Allocate(inSize); +#endif // Q3DStudio_MEMORY_POOLTRACKING + } + // If not, we go to the heap for now. + else { + // REFACTOR: Use the next pool size up instead? + thePointer = CMemoryHeap::Allocate(inSize, inType, inFile, inLine); + m_ManagerData.m_Overflow.Allocate(inSize); + +#if Q3DStudio_MEMORY_POOLTRACKING + if (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) + m_PoolData[thePoolIndex].m_Overflow.Allocate( + inSize); // Heap allocation due to full memory pool +#endif // Q3DStudio_MEMORY_POOLTRACKING + } + +#if Q3DStudio_MEMORY_LINETRACKING + CMemoryTracker::SMemoryInfo *theMemoryInfo = + reinterpret_cast(thePointer); + + theMemoryInfo->m_DogTag = CMemoryTracker::TRACKER_DOGTAG; + theMemoryInfo->m_Line = static_cast(inLine); + theMemoryInfo->m_Size = static_cast(inSize - sizeof(CMemoryTracker::SMemoryInfo)); + theMemoryInfo->m_File = inFile; + theMemoryInfo->m_Type = inType; + + m_LineTracker.Remember(theMemoryInfo); + thePointer = reinterpret_cast(thePointer) + 1; +#endif // Q3DStudio_MEMORY_LINETRACKING + + return thePointer; +} + +//============================================================================== +/** + * Release a chunk of memory. + * @param inPointer pointer to memory to be reused + * @param inSize size of the memory we are releasing, in bytes + */ +void CMemoryManager::Free(void *inPointer, INT32 inSize) +{ + if (!inPointer) + return; + + Q3DStudio_ASSERT(inSize >= 0); + +#if Q3DStudio_MEMORY_POOLTRACKING + m_Histogram[Q3DStudio_min(inSize, 511)].Delete(1); +#endif // Q3DStudio_MEMORY_POOLTRACKING + +#if Q3DStudio_MEMORY_LINETRACKING + inPointer = reinterpret_cast(inPointer) - 1; + m_LineTracker.Forget(reinterpret_cast(inPointer)); + inSize += sizeof(CMemoryTracker::SMemoryInfo); +#endif // Q3DStudio_MEMORY_LINETRACKING + + // Did we get a valid pool? + INT32 thePoolIndex = FetchPoolIndex(inPointer); + if (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) { + m_Pool[thePoolIndex].Free(inPointer); + m_ManagerData.m_Aligned.Free(inSize); +#if Q3DStudio_MEMORY_POOLTRACKING + m_PoolData[thePoolIndex].m_Aligned.Free(inSize); +#endif // Q3DStudio_MEMORY_POOLTRACKING + } else { + CMemoryHeap::Free(inPointer, inSize); + m_ManagerData.m_Overflow.Free(inSize); + +#if Q3DStudio_MEMORY_POOLTRACKING + if (inSize <= m_Pool[Q3DStudio_MEMORY_POOLCOUNT - 1].GetChunkSize()) + for (thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) + if (inSize <= m_Pool[thePoolIndex].GetChunkSize()) { + m_PoolData[thePoolIndex].m_Overflow.Free(inSize); + // This is driving me crazy -CN. + // Q3DStudio_ASSERT( m_PoolData[thePoolIndex].m_Overflow.GetCalls( + // MEMSCOPE_GLOBAL, MEMVALUE_CURRENT ) >= 0 ); + break; + } +#endif // Q3DStudio_MEMORY_POOLTRACKING + } +} + +//============================================================================== +/** + * Grow the existing memory allocated + * + * @param inOldPointer pointer given in a previous allocation + * @param inOldSize size of current memory block, in bytes + * @param inNewSize size of requested memory block, in bytes + * @param inNewType allocation description such as class name or pool name + * @param inFile file name + * @param inFunction method name + * @param inLine line number + * @return void* a pointer to a memory block large enough to hold inSize bytes + */ +void *CMemoryManager::Reallocate(void *inOldPointer, const INT32 inOldSize, const INT32 inNewSize, + const CHAR *inNewType, const CHAR *inFile, const INT32 inLine) +{ + Q3DStudio_ASSERT(inOldSize >= 0 && inNewSize >= 0); + + // It's legal to pass NULL as old pointer to realloc + if (!inOldPointer) + return Allocate(inNewSize, inNewType, inFile, inLine); + + if (inNewSize == 0) { + Free(inOldPointer, inOldSize); + return NULL; + } + + // Get a new bigger chunk and transfer old data to it + void *thePointer = Allocate(inNewSize, inNewType, inFile, inLine); + Q3DStudio_memcpy(thePointer, inOldPointer, Q3DStudio_min(inOldSize, inNewSize)); + + // Release old data + Free(inOldPointer, inOldSize); + return thePointer; +} + +//============================================================================== +// IMPLEMENTATION +//============================================================================== + +//============================================================================== +/** + * Find the pool that owns the given pointer. + * @param inPointer pointer to memory to be found + * @return INT32 index of pool or Q3DStudio_MEMORY_POOLCOUNT if the chunk can't be found + */ +INT32 CMemoryManager::FetchPoolIndex(const void *inPointer) +{ + // Find pool that owns the pointer + INT32 thePoolIndex = 0; + while (thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT) { + if (m_Pool[thePoolIndex].OwnsChunk(inPointer)) + return thePoolIndex; + ++thePoolIndex; + } + + return Q3DStudio_MEMORY_POOLCOUNT; +} + +//============================================================================== +// STATISTICS +//============================================================================== + +//============================================================================== +/** + * Return the text identifier of the manager + * @return the name, max 32 bytes long + */ +const CHAR *CMemoryManager::GetName() +{ + return m_Name; +} + +//============================================================================== +/** + * Reset all probe statistics + */ +void CMemoryManager::Reset() +{ + m_ManagerData.m_Aligned.Reset(); + m_ManagerData.m_Overflow.Reset(); + +#if Q3DStudio_MEMORY_POOLTRACKING + for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) { + m_Pool[thePoolIndex].GetProbe().Reset(); + m_PoolData[thePoolIndex].m_Aligned.Reset(); + m_PoolData[thePoolIndex].m_Overflow.Reset(); + } +#endif // Q3DStudio_MEMORY_POOLTRACKING +} + +//============================================================================== +/** + * Retrieve a particular memory pool + * @param inPoolIndex index of the pool + * @return SPoolData& is a reference to the indicated pool data + */ +CMemoryPool &CMemoryManager::GetPool(const INT32 inPoolIndex) +{ + Q3DStudio_ASSERT(inPoolIndex < Q3DStudio_MEMORY_POOLCOUNT && inPoolIndex >= 0); + return m_Pool[inPoolIndex]; +} + +//============================================================================== +/** + * Retrieve a particular memory pool + * @param inPoolIndex index of the pool + * @return SPoolData& is a reference to the indicated pool data + */ +CMemoryManager::SPoolData *CMemoryManager::GetPoolData(const INT32 inPoolIndex) +{ + Q3DStudio_UNREFERENCED_PARAMETER(inPoolIndex); + Q3DStudio_ASSERT(inPoolIndex < Q3DStudio_MEMORY_POOLCOUNT && inPoolIndex >= 0); + +#if Q3DStudio_MEMORY_POOLTRACKING + return m_PoolData + inPoolIndex; +#else + return NULL; +#endif // Q3DStudio_MEMORY_POOLTRACKING +} + +//============================================================================== +/** + * Retrieve the number of bytes that were allocated on the heap + * @return CMemoryProbe as the heap statistics + */ +CMemoryManager::SPoolData &CMemoryManager::GetManagerData() +{ + return m_ManagerData; +} + +//============================================================================== +/** + * Sum the high level statistics of all the pools. + * @return CMemoryProbe as the statistics, calculated on the spot + */ +CMemoryProbe CMemoryManager::GetProbe() +{ + CMemoryProbe theProbe; +#if Q3DStudio_MEMORY_POOLTRACKING + for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) + theProbe.Combine(m_Pool[thePoolIndex].GetProbe()); +#endif // Q3DStudio_MEMORY_POOLTRACKING + return theProbe; +} + +//============================================================================== +/** + * Fetch the tracker if enabled by setting Q3DStudio_MEMORY_LINETRACKING + * @return CMemoryTracker pointer or NULL + */ +CMemoryTracker *CMemoryManager::GetLineTracker() +{ +#if Q3DStudio_MEMORY_LINETRACKING + return &m_LineTracker; +#else + return NULL; +#endif // Q3DStudio_MEMORY_LINETRACKING +} + +//============================================================================== +/** + * Fetch the histogram if enabled by setting Q3DStudio_MEMORY_HISTOGRAM. + * The histogram counts all requested allocations of the specific size. + * @return UINT16 array of 512 values, or NULL + */ +const CMemoryProbe::SValue *CMemoryManager::GetHistogram() +{ +#if Q3DStudio_MEMORY_POOLTRACKING + return m_Histogram; +#else + return NULL; +#endif // Q3DStudio_MEMORY_POOLTRACKING +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryManager.h b/src/Runtime/Source/system/Qt3DSMemoryManager.h new file mode 100644 index 00000000..fa54fce7 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryManager.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryPool.h" +#include "Qt3DSMemoryProbe.h" +#include "Qt3DSMemoryTracker.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class CMemoryTracker; + +//============================================================================== +/** + * Allocation switch-board forwarding requests to pools. + * + * This is a memory pool hub acting as a complete heap replacement. The number + * of pools is hardcoded in Q3DStudio_MEMORY_POOLCOUNT but can be changed with a + * recompile. The main manager is created in AKMemory and is preconfigured to + * be generous with memory. Tune these values to match your title since + * unused chunks are wasteful. + * + * @note A pool manager survives fine even when not initialized. In this state + * it simply forwards each request to the CMemoryHeap. This setup is intentional + * to enable the default manager to survive long enough to allow future runtime + * initialization based on complexity of the level or presentation being loaded. + */ +class CMemoryManager +{ + //============================================================================== + // Structs + //============================================================================== +public: + /// External pool usage information + struct SPoolData + { + CMemoryProbe + m_Aligned; ///< Exact sum of memory use (28byte struct in 32byte pool is still 28 here) + CMemoryProbe m_Overflow; ///< Failed memory allocation because the pool was full + }; + + //============================================================================== + // Fields + //============================================================================== +protected: + CHAR m_Name[32]; ///< Manager identifier for statistics + CMemoryPool m_Pool[Q3DStudio_MEMORY_POOLCOUNT]; ///< Actual pool memory objects + SPoolData m_ManagerData; ///< Track allocations forwarded to heap because they were too large + +#if Q3DStudio_MEMORY_POOLTRACKING + SPoolData + m_PoolData[Q3DStudio_MEMORY_POOLCOUNT]; ///< Trace pools of different sizes with their usage + CMemoryProbe::SValue + m_Histogram[512]; ///< Allocation histogram if active using Q3DStudio_MEMORY_HEAPTRACKING +#endif // Q3DStudio_MEMORY_POOLTRACKING + +#if Q3DStudio_MEMORY_LINETRACKING + CMemoryTracker + m_LineTracker; ///< Line allocation tracker if active using Q3DStudio_MEMORY_LINETRACKING +#endif // Q3DStudio_MEMORY_LINETRACKING + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CMemoryManager(); + CMemoryManager(const CHAR *inName, const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], + const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]); + ~CMemoryManager(); + +public: // Initialization + void Initialize(const CHAR *inName, const INT32 inChunkSize[Q3DStudio_MEMORY_POOLCOUNT], + const INT32 inChunkCount[Q3DStudio_MEMORY_POOLCOUNT]); + void Release(); + +public: // Allocation and Deallocation + void *Allocate(INT32 inSize, const CHAR *inType, const CHAR *inFile, const INT32 inLine); + void Free(void *inOldPointer, INT32 inSize); + void *Reallocate(void *inOldPointer, const INT32 inOldSize, const INT32 inNewSize, + const CHAR *inNewType, const CHAR *inFile, const INT32 inLine); + +protected: // Implementation + INT32 FetchPoolIndex(const void *inPointer); + +public: // Statistics + void Reset(); + const CHAR *GetName(); + CMemoryPool &GetPool(const INT32 inPoolIndex); + SPoolData *GetPoolData(const INT32 inPoolIndex); + SPoolData &GetManagerData(); + CMemoryProbe GetProbe(); + CMemoryTracker *GetLineTracker(); + const CMemoryProbe::SValue *GetHistogram(); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryPool.cpp b/src/Runtime/Source/system/Qt3DSMemoryPool.cpp new file mode 100644 index 00000000..44545d45 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryPool.cpp @@ -0,0 +1,298 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryPool.h" +#include "Qt3DSMemoryHeap.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Create a new memory pool. + * + */ +CMemoryPool::CMemoryPool() + : m_ChunkSize(0) + , m_ChunkCount(0) + , m_Ceiling(NULL) + , m_Memory(NULL) + , m_Top(NULL) + , m_Hole(NULL) +{ + m_Description[0] = '\0'; +} + +//============================================================================== +/** + * Release the memory pool. + * + * Nobody better point to this pool because it's illegal after this. + * We could blast the memory in debug mode to trigger bugs early but most + * compilers already do this. + */ +CMemoryPool::~CMemoryPool() +{ + Release(); +} + +//============================================================================== +/** + * Configure the memory pool. + * + * The pool will allocate inChunkSize * inChunkCount bytes of memory from + * the heap using Q3DStudio_new, aligned on 4 byte boundaries. + * + * @param inName short description of pool - used in tracker + * @param inChunkSize size in bytes of each memory block, aka chunk + * @param inChunkCount number of chunks the pool holds + */ +void CMemoryPool::Initialize(const CHAR *inName, const INT32 inChunkSize, const INT32 inChunkCount) +{ + Q3DStudio_ASSERT(!m_Memory); + + // Round up chunk size to the next even pointer size + // It needs to be at least pointer size to store the hole linked list + INT32 theRoundedChunkSize = + static_cast(((inChunkSize + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *)); + + // Create pool description + Q3DStudio_sprintf(m_Description, sizeof(m_Description), "POOL: %s(%dx%d)", inName, + theRoundedChunkSize, inChunkCount); + + // Reserve memory pool + m_ChunkSize = theRoundedChunkSize; + m_ChunkCount = inChunkCount; + m_Memory = reinterpret_cast( + Q3DStudio_heap_allocate(m_ChunkSize * m_ChunkCount, m_Description)); + m_Top = m_Memory; + m_Ceiling = m_Memory + m_ChunkSize * m_ChunkCount; +} + +//============================================================================== +/** + * Release all the memory allocated in Initialize - essentially "uninitialize". + */ +void CMemoryPool::Release() +{ + Q3DStudio_heap_free(m_Memory, m_ChunkSize * m_ChunkCount); + + m_ChunkSize = 0, m_ChunkCount = 0; + m_Ceiling = NULL; + m_Memory = NULL; + m_Top = NULL; + m_Hole = NULL; +} + +//============================================================================== +// ALLOCATION AND DEALLOCATION +//============================================================================== + +//============================================================================== +/** + * Fetch a new chunk of memory. + * + * If there is a pool hole we use that, otherwise feed of the head. + * Every alloction is tracked in m_Statistics. + * @return a pointer to inChunkSize bytes of usable memory + */ +void *CMemoryPool::Allocate() +{ + if (m_Hole) + return PopHole(); + else + return UseTop(); +} + +//============================================================================== +/** + * Release a chunk of memory and track changes in statistics + * @param inChunk a pointer to memory to be reused + */ +void CMemoryPool::Free(void *inChunk) +{ + Q3DStudio_ASSERT(OwnsChunk(inChunk)); + PushHole(inChunk); +} + +//============================================================================== +/** + * Verify that a pointer is owned by a specific pool + * @param inChunk a pointer to be checked + * @return BOOL true if the chunk is owned by this pool + */ +BOOL CMemoryPool::OwnsChunk(const void *inChunk) const +{ +#ifdef _DEBUG + // Scan all holes to prevent double releasing memory + if (!(inChunk >= m_Ceiling || inChunk < m_Memory)) { + // No freeing anything above the top? + Q3DStudio_ASSERT(inChunk < m_Top); + + // Not freeing any holes? + void *theHoleChunk = m_Hole; + while (theHoleChunk) { + Q3DStudio_ASSERT(inChunk != theHoleChunk); + theHoleChunk = reinterpret_cast(*reinterpret_cast(theHoleChunk)); + } + } +#endif // DEBUG + + return !(inChunk >= m_Ceiling || inChunk < m_Memory); +} + +//============================================================================== +/** + * Quick check to see if there are chunks available + * @return BOOL true if the pool has available chunks + */ +BOOL CMemoryPool::IsFull() const +{ + return m_Hole == NULL && GetFreeTops() == 0; +} + +//============================================================================== +/** + * Get the total number of free chunks in this pool. + * @return INT32 is the nunber of free chunks + */ +INT32 CMemoryPool::GetFreeChunks() const +{ + return GetFreeTops() + GetFreeHoles(); +} + +//============================================================================== +/** + * Get the number of holes in this pool. + * @return INT32 is the nunber of holes + */ +INT32 CMemoryPool::GetFreeHoles() const +{ + INT32 theHoleCounter = 0; + void *theHoleChunk = m_Hole; + + // Walk the hole list until there are no more holes + while (theHoleChunk) { + theHoleChunk = reinterpret_cast(*reinterpret_cast(theHoleChunk)); + ++theHoleCounter; + } + + return theHoleCounter; +} + +//============================================================================== +/** + * Get the number of chunks left at the top. + * @return INT32 is the nunber of continous chunks at the top + */ +INT32 CMemoryPool::GetFreeTops() const +{ + return static_cast((m_Ceiling - m_Top)) / m_ChunkSize; +} + +//============================================================================== +// IMPLEMENTATION +//============================================================================== + +//============================================================================== +/** + * Return a chunch from the top. + * + * The top is only used if no pool holes are available. + * @return a pointer to the chunk at the top + */ +void *CMemoryPool::UseTop() +{ + // Out of memory? + // This is not assert since it may happen during normal runtime. + if (m_Top >= m_Ceiling) + return NULL; + + void *theChunk = m_Top; + m_Top += m_ChunkSize; + +#if Q3DStudio_MEMORY_POOLTRACKING + m_Probe.Allocate(m_ChunkSize); +#endif // Q3DStudio_MEMORY_POOLTRACKING + return theChunk; +} + +//============================================================================== +/** + * Add a new hole to the pool list. + * + * The holes are used in a stack-like fashion so the chunk we push in most + * recently is the first one to be returned next New call. + * The holes are linked by using the first four bytes to point to the next + * chunk. We are hijacking them to create a linked list of free chunks. + * @param inChunk is the just deleted chunk + */ +void CMemoryPool::PushHole(void *inChunk) +{ +#if Q3DStudio_MEMORY_POOLTRACKING + m_Probe.Free(m_ChunkSize); +#endif // Q3DStudio_MEMORY_POOLTRACKING + + // Set the pushed chunk to be the new top hole after we + // link the content of the new chunk to the last top. + *reinterpret_cast(inChunk) = reinterpret_cast(m_Hole); + m_Hole = inChunk; +} + +//============================================================================== +/** + * Get the topmost hole as our chunk. + * + * Return the latest hole and relink the list of holes to the top. + * @return void* is the most recently deleted chunk + */ +void *CMemoryPool::PopHole() +{ + Q3DStudio_ASSERT(m_Hole); + + // Return the old hole as our new chunk after we + // set the hole to the second hole in the list. + void *theChunk = m_Hole; + m_Hole = reinterpret_cast(*reinterpret_cast(m_Hole)); + +#if Q3DStudio_MEMORY_POOLTRACKING + m_Probe.Allocate(m_ChunkSize); +#endif // Q3DStudio_MEMORY_POOLTRACKING + return theChunk; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryPool.h b/src/Runtime/Source/system/Qt3DSMemoryPool.h new file mode 100644 index 00000000..01b2e418 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryPool.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryProbe.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Managed memory allocation using fixed-size chunks. + * + * The pool class implements a generic algorithm that favors reusing recently + * used memory chunks instead of returning memory continously. Yet, a fresh + * pool will always return chunks positioned side by side. + * + * If a chunk is freed it will be the first to be returned next time a fresh + * chunk is new'ed. This makes the cache lines happier. Deleted chunks are + * maintained by linking to each other instead of being stored in a separate + * memory consuming array. + */ +class CMemoryPool +{ + //============================================================================== + // Fields + //============================================================================== +protected: + INT32 m_ChunkSize; ///< size in bytes of each chunk + INT32 m_ChunkCount; ///< number of chunks in pool + + INT8 *m_Ceiling; ///< ceiling memory pointer + INT8 *m_Memory; ///< base memory pointer, INT8 for easy pointer arithemtic + INT8 *m_Top; ///< edge of free continous memory + void *m_Hole; ///< first dis-continous memory chunk if any + + CMemoryProbe m_Probe; ///< call and byte data on pool usage + CHAR m_Description[32]; ///< short description of this pool + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CMemoryPool(); + ~CMemoryPool(); + +public: // Initialization + void Initialize(const CHAR *inName, const INT32 inChunkSize, const INT32 inChunkCount); + void Release(); + +public: // Allocation and Deallocation + void *Allocate(); + void Free(void *inChunk); + BOOL IsFull() const; + BOOL OwnsChunk(const void *inChunk) const; + +protected: // Implementation + void *UseTop(); + void PushHole(void *inChunk); + void *PopHole(); + +public: // Statistics and reports + INT32 GetFreeHoles() const; + INT32 GetFreeTops() const; + INT32 GetFreeChunks() const; + INT32 GetChunkSize() const { return m_ChunkSize; } + INT32 GetChunkCount() const { return m_ChunkCount; } + CMemoryProbe &GetProbe() { return m_Probe; } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryProbe.cpp b/src/Runtime/Source/system/Qt3DSMemoryProbe.cpp new file mode 100644 index 00000000..4e977ee1 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryProbe.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryProbe.h" +#include "Qt3DSMemoryStatistics.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor - records its size with the statistics class + */ +CMemoryProbe::CMemoryProbe() +{ + CMemoryStatistics::Overhead() += sizeof(CMemoryProbe); +} + +//============================================================================== +/** + * Destructor + */ +CMemoryProbe::~CMemoryProbe() +{ + CMemoryStatistics::Overhead() -= sizeof(CMemoryProbe); +} + +//============================================================================== +/** + * Track the number related to incrementing memory. + * @param inByteAmount amount of bytes being allocated + */ +void CMemoryProbe::Allocate(const INT32 inByteAmount) +{ + if (inByteAmount > 0) { + m_Calls[MEMSCOPE_RESET].Add(1); + m_Bytes[MEMSCOPE_RESET].Add(inByteAmount); + + m_Calls[MEMSCOPE_GLOBAL].Add(1); + m_Bytes[MEMSCOPE_GLOBAL].Add(inByteAmount); + } +} + +//============================================================================== +/** + * Track the number related to incrementing memory. + * @param inByteAmount amount of bytes being deallocted + */ +void CMemoryProbe::Free(const INT32 inByteAmount) +{ + Q3DStudio_ASSERT(inByteAmount >= 0); + if (inByteAmount > 0) { + m_Calls[MEMSCOPE_RESET].Delete(1); + m_Bytes[MEMSCOPE_RESET].Delete(inByteAmount); + + m_Calls[MEMSCOPE_GLOBAL].Delete(1); + m_Bytes[MEMSCOPE_GLOBAL].Delete(inByteAmount); + } +} + +//============================================================================== +/** + * Reset all local statistics. Global values are not reset. + */ +void CMemoryProbe::Reset() +{ + m_Calls[MEMSCOPE_RESET].Reset(); + m_Bytes[MEMSCOPE_RESET].Reset(); +} + +//============================================================================== +/** + * Helper method for adding statistics used by manager to add pool usage. + * @param inProbe is the stats being added + */ +void CMemoryProbe::Combine(const CMemoryProbe &inProbe) +{ + m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS] += + inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS]; + m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES] += + inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES]; + m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK] += + inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK]; + m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT] += + inProbe.m_Calls[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT]; + + m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS] += + inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_ADDS]; + m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES] += + inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_DELETES]; + m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK] += + inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_PEAK]; + m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT] += + inProbe.m_Bytes[MEMSCOPE_GLOBAL].m_Value[MEMVALUE_CURRENT]; + + m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS] += + inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS]; + m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES] += + inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES]; + m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK] += + inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK]; + m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT] += + inProbe.m_Calls[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT]; + + m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS] += + inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_ADDS]; + m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES] += + inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_DELETES]; + m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK] += + inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_PEAK]; + m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT] += + inProbe.m_Bytes[MEMSCOPE_RESET].m_Value[MEMVALUE_CURRENT]; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryProbe.h b/src/Runtime/Source/system/Qt3DSMemoryProbe.h new file mode 100644 index 00000000..5f0844e8 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryProbe.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +#include "Qt3DSMacros.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Memory Tracking Enums +//============================================================================== + +/// Track a value - remembering peak and add/del count +enum EMemoryValue { + MEMVALUE_ADDS = 0, ///< For example: allocation call count or bytes allocated + MEMVALUE_DELETES, ///< For example: free call count or bytes deallocated + MEMVALUE_PEAK, ///< Peak of the current value since the last reset + MEMVALUE_CURRENT, ///< Current count + MEMVALUECOUNT +}; + +/// Differentiate between full session (global) or since last reset (local) +enum EMemoryScope { + MEMSCOPE_RESET = 0, ///< Since last reset + MEMSCOPE_GLOBAL, ///< Since process start + MEMSCOPECOUNT +}; + +//============================================================================== +/** + * Memory allocation counter tracking bytes or calls. + * + * A probe instance can be placed to track either number of allocations + * or the bytes of each allocation. CMemoryManager and CMemoryHeap both + * record statistics using this class. 64 bytes. + */ +class CMemoryProbe +{ + //============================================================================== + // Structs + //============================================================================== +public: + //============================================================================== + /** + * Intelligent number that tracks current, peak, incr. and decr. + * + * This value remembers how the amount added, the amount deleted, the highest + * value, while keeping a current value. These are used by CMemoryProbe when + * tracking memory allocations. + */ + struct SValue + { + // Fields + INT32 m_Value[MEMVALUECOUNT]; ///< Four aspects (add,del,current,peak) we are tracking + + // Methods + SValue() { Reset(); } + void Reset() + { + m_Value[MEMVALUE_ADDS] = 0; + m_Value[MEMVALUE_DELETES] = 0; + m_Value[MEMVALUE_PEAK] = 0; + m_Value[MEMVALUE_CURRENT] = 0; + } + + void Delete(INT32 inAmount) + { + Q3DStudio_ASSERT(inAmount >= 0); + m_Value[MEMVALUE_DELETES] += inAmount; + m_Value[MEMVALUE_CURRENT] -= inAmount; + } + + void Add(INT32 inAmount) + { + Q3DStudio_ASSERT(inAmount >= 0); + m_Value[MEMVALUE_ADDS] += inAmount; + m_Value[MEMVALUE_CURRENT] += inAmount; + m_Value[MEMVALUE_PEAK] = + Q3DStudio_max(m_Value[MEMVALUE_PEAK], m_Value[MEMVALUE_CURRENT]); + } + }; + + //============================================================================== + // Fields + //============================================================================== +protected: + SValue m_Calls[MEMSCOPECOUNT]; ///< Memory call count + SValue m_Bytes[MEMSCOPECOUNT]; ///< Memory allocation amount + + //============================================================================== + // Methods + //============================================================================== +public: // Constructor + CMemoryProbe(); + ~CMemoryProbe(); + +public: // Operations + void Reset(); + void Allocate(const INT32 inByteAmount); + void Free(const INT32 inByteAmount); + void Combine(const CMemoryProbe &inProbe); + +public: // Accessors + INT32 GetCalls(const EMemoryScope inScope, const EMemoryValue inValue) const + { + return m_Calls[inScope].m_Value[inValue]; + } + INT32 GetBytes(const EMemoryScope inScope, const EMemoryValue inValue) const + { + return m_Bytes[inScope].m_Value[inValue]; + } +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemorySettings.h b/src/Runtime/Source/system/Qt3DSMemorySettings.h new file mode 100644 index 00000000..54002424 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemorySettings.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTypes.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * GlobalMemoryManager constants + * NOTE THAT THESE NUMBERS BELOW SHOULD BE ADJUSTED TO FIT YOUR APPLICATION. + * + * See the Memory Management section in the documentation for guidelines + * on memory diagnostics that enable you to optimize these values: + */ + +//============================================================================== +// Memory Pool Configuration +//============================================================================== + +#ifndef Q3DStudio_MEMORY_POOLCOUNT +#define Q3DStudio_MEMORY_POOLCOUNT 12 +#endif // Q3DStudio_MEMORY_POOLCOUNT + +/// A memory pool has a chunk size that defines he size in bytes of each slot +/// and a chunk count defining how many slots there are of that size. +/// The pools below thus has 128 slots of 4 bytes, 256 slots of 8 bytes etc: +const INT32 g_ChunkSize[Q3DStudio_MEMORY_POOLCOUNT] = { 4, 8, 16, 32, 48, 64, + 96, 128, 160, 256, 384, 640 }; +const INT32 g_ChunkCount[Q3DStudio_MEMORY_POOLCOUNT] = { 128, 256, 256, 1536, 128, 128, + 256, 64, 32, 32, 32, 32 }; + +//============================================================================== +// Memory Settings +//============================================================================== + +/// Define the upper memory limit used by Runtime. +/// 0 = unlimited +#ifndef Q3DStudio_MEMORY_LIMIT +#define Q3DStudio_MEMORY_LIMIT 0 +#endif // Q3DStudio_MEMORY_LIMIT + +// Pool sizes and diagnostics are aligned to the required boundary. +#ifndef Q3DStudio_MEMORY_ALIGNMENT +#define Q3DStudio_MEMORY_ALIGNMENT 8 +#endif // Q3DStudio_MEMORY_ALIGNMENT + +//============================================================================== +// Memory Diagnostics +//============================================================================== + +/// Note that the simple report is always on. (F1 in Quarterback) + +/// CMemoryHeap usage report. (F2 in Quarterback) +/// Tracks large allocations such as pool buffers, managers and overflows. +/// Not much overhead since most allocations should be intercepted by pools. +#ifndef Q3DStudio_MEMORY_HEAPTRACKING +#define Q3DStudio_MEMORY_HEAPTRACKING 0 +#endif // Q3DStudio_MEMORY_HEAPTRACKING + +/// Max number of 20 byte SReportEntry heap entries +/// Increase this number if you get a log warning but you should really tune +/// your memory pools to avoid hitting the heap. +#ifndef Q3DStudio_MEMORY_HEAPTRACKINGSIZE +#define Q3DStudio_MEMORY_HEAPTRACKINGSIZE 4000 +#endif // Q3DStudio_MEMORY_HEAPTRACKINGSIZE + +/// Invasive allocation tracker. (F3 in Quarterback) +/// Track detailed memory usage per allocation through CMemoryManager by tracking +/// every Runtime allocation, line by line using __FILE__ and __LINE__. +/// Note that this adds a 16byte SMemoryInfo to each allocation and thus +/// changes pool usage. +/// === Do not tune pools with line tracking enabled! === +#ifndef Q3DStudio_MEMORY_LINETRACKING +#define Q3DStudio_MEMORY_LINETRACKING 0 +#endif // Q3DStudio_MEMORY_LINETRACKING + +// Hashbin size of entries pointing to SMemoryInfo allocation headers +#ifndef Q3DStudio_MEMORY_LINETRACKINGSIZE +#define Q3DStudio_MEMORY_LINETRACKINGSIZE (128 * 1024) +#endif // Q3DStudio_MEMORY_LINETRACKINGSIZE + +/// CMemoryManager pooled memory usage report. (F5-F8 in Quarterback) +/// Track most used allocation sizes to tune pool sizes and count. +/// Enabled by default since it allows tracking precise presentation +/// memory usage without much of an overhead. +/// It also includes a histogram when showing Reset data (F5,F6) +#ifndef Q3DStudio_MEMORY_POOLTRACKING +#ifdef _DEBUG +#define Q3DStudio_MEMORY_POOLTRACKING 1 +#else +#define Q3DStudio_MEMORY_POOLTRACKING 0 +#endif +#endif // Q3DStudio_MEMORY_POOLTRACKING + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryStatistics.cpp b/src/Runtime/Source/system/Qt3DSMemoryStatistics.cpp new file mode 100644 index 00000000..2f5eba0e --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryStatistics.cpp @@ -0,0 +1,647 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSIStream.h" +#include "Qt3DSMemoryStatistics.h" +#include "Qt3DSMemoryTracker.h" +#include "Qt3DSMemoryHeap.h" +#include "foundation/Qt3DSLogging.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Static Fields +//============================================================================== +INT32 CMemoryStatistics::s_Overhead = 0; +CMemoryManager *CMemoryStatistics::s_PoolManagers[MANAGERCOUNT] = { NULL }; + +//============================================================================== +// REGISTRATION +//============================================================================== + +//============================================================================== +/** + * Add the manager from the static list done automatically on manager construction. + * @param inManager the manager we are beginning to track + */ +void CMemoryStatistics::AddManager(CMemoryManager *inManager) +{ + INT32 theIndex = 0; + while (s_PoolManagers[theIndex] && theIndex < MANAGERCOUNT - 1) + ++theIndex; + + if (!s_PoolManagers[theIndex]) { + s_PoolManagers[theIndex] = inManager; + } else { + qCWarning(qt3ds::TRACE_INFO) + << "Could not add memory manager tracker. Limit: " << MANAGERCOUNT; + } +} + +//============================================================================== +/** + * Remove the manager from the static list done automatically on manager deletion. + * @param inManager the manager we are ceasing to track + */ +void CMemoryStatistics::RemoveManager(CMemoryManager *inManager) +{ + INT32 theIndex = 0; + while (inManager != s_PoolManagers[theIndex] && theIndex < MANAGERCOUNT - 1) + ++theIndex; + + if (inManager == s_PoolManagers[theIndex]) + s_PoolManagers[theIndex] = NULL; +} + +//============================================================================== +/** + * Read/write access to the static tracking field that keeps tab on how + * much memory we are spending _tracking_ memory. + * @return reference to the field tracking the overhead in bytes + */ +INT32 &CMemoryStatistics::Overhead() +{ + return s_Overhead; +} + +//============================================================================== +// OPERATION +//============================================================================== + +//============================================================================== +/** + * Reset all memory probes + */ +void CMemoryStatistics::Reset() +{ + qCInfo(qt3ds::TRACE_INFO) << "Resetting Memory Statistics"; + CMemoryHeap::GetProbe().Reset(); + + for (INT32 theIndex = 0; theIndex < MANAGERCOUNT; ++theIndex) + if (s_PoolManagers[theIndex]) + s_PoolManagers[theIndex]->Reset(); +} + +//============================================================================== +// ACCESS +//============================================================================== + +//============================================================================== +/** + * Quick access to memory usage of the first memory manager. + * @param inPeak is true if you want the peak, false if you want the current state + * @return the current explict usage in bytes + */ +INT32 CMemoryStatistics::GetRequestedBytes(BOOL inPeak /*=false*/) +{ + Q3DStudio_ASSERT(s_PoolManagers[0]); + + EMemoryValue theValue = inPeak ? MEMVALUE_PEAK : MEMVALUE_CURRENT; + CMemoryManager::SPoolData &theUsageData = s_PoolManagers[0]->GetManagerData(); + + return theUsageData.m_Aligned.GetBytes(MEMSCOPE_RESET, theValue) + + theUsageData.m_Overflow.GetBytes(MEMSCOPE_RESET, theValue); +} + +//============================================================================== +/** + * Quick access to heap usage. + * @param inPeak is true if you want the peak, false if you want the current state + * @return the current heap usage in bytes + */ +INT32 CMemoryStatistics::GetHeapBytes(BOOL inPeak /*=false*/) +{ + return Q3DStudio::CMemoryHeap::GetProbe().GetBytes(MEMSCOPE_RESET, + inPeak ? MEMVALUE_PEAK : MEMVALUE_CURRENT); +} + +//============================================================================== +/** + * Fill out a SFactSheet with memory statistics. + * @param outFacts is filled out with factoids showing the system state + * @param inPeak is true if you want the peak, false if you want the current state + * @param inGlobal is true if you want values since process start, false since last reset + */ +void CMemoryStatistics::GetFacts(SFactSheet &outFacts, BOOL inPeak /*= true*/, + BOOL inGlobal /*= true*/) +{ + INT32 thePresentationBytes = 0; + Q3DStudio_UNREFERENCED_PARAMETER(thePresentationBytes); + Q3DStudio_memset(&outFacts, 0, sizeof(SFactSheet)); + + // Translate flags to enumerations + EMemoryScope theScope = inGlobal ? MEMSCOPE_GLOBAL : MEMSCOPE_RESET; + EMemoryValue theValue = inPeak ? MEMVALUE_PEAK : MEMVALUE_CURRENT; + + // Capture heap state + outFacts.m_HeapState.m_Bytes = CMemoryHeap::GetProbe().GetBytes(theScope, theValue); + outFacts.m_HeapState.m_Calls = CMemoryHeap::GetProbe().GetCalls(theScope, theValue); + +#if Q3DStudio_MEMORY_POOLTRACKING + INT32 theTotalChunks = 0; + INT32 theTotalBytes = 0; + + // Scan all registered pool managers + Q3DStudio_sprintf(outFacts.m_ManagerState.m_Name, 32, "All Managers"); + for (INT32 theManagerIndex = 0; theManagerIndex < MANAGERCOUNT; ++theManagerIndex) { + CMemoryManager *theManager = s_PoolManagers[theManagerIndex]; + SFactoid &theManagerFact = outFacts.m_Manager[theManagerIndex]; + INT32 theManagerChunks = 0; + INT32 theManagerBytes = 0; + + // Ignore empty managers + if (!theManager) + break; + + // Scan each pool in the manager + Q3DStudio_sprintf(theManagerFact.m_Name, 32, " %s", theManager->GetName()); + for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; ++thePoolIndex) { + CMemoryPool &thePool = theManager->GetPool(thePoolIndex); + CMemoryManager::SPoolData *thePoolData = theManager->GetPoolData(thePoolIndex); + Q3DStudio_ASSERT(thePoolData); + + SFactoid &thePoolFact = outFacts.m_Pool[theManagerIndex][thePoolIndex]; + INT32 theUsed = thePool.GetProbe().GetCalls(theScope, theValue); + INT32 theAlign = thePoolData->m_Aligned.GetBytes(theScope, theValue); + + // Ignore empty pools + if (thePool.GetChunkCount() == 0) + break; + + // Extract all the factoids + Q3DStudio_sprintf(thePoolFact.m_Name, 32, " %d: %4db x %4d", thePoolIndex, + thePool.GetChunkSize(), thePool.GetChunkCount()); + thePoolFact.m_Bytes = thePool.GetChunkSize() * thePool.GetChunkCount(); + thePoolFact.m_Calls = thePool.GetProbe().GetCalls(theScope, theValue); + thePoolFact.m_Used = 100 * theUsed / thePool.GetChunkCount(); + + thePoolFact.m_Align = 100; + if (theUsed > 0) + thePoolFact.m_Align = 100 * theAlign / (theUsed * thePool.GetChunkSize()); + thePoolFact.m_Miss = thePoolData->m_Overflow.GetCalls(theScope, theValue); + + thePresentationBytes += theAlign + thePoolData->m_Overflow.GetBytes(theScope, theValue); + + theManagerFact.m_Bytes += thePoolFact.m_Bytes; + theManagerFact.m_Calls += thePoolFact.m_Calls; + theManagerFact.m_Used += theUsed; + theManagerFact.m_Align += theAlign; + theManagerFact.m_Miss += thePoolFact.m_Miss; + + outFacts.m_ManagerState.m_Bytes += thePoolFact.m_Bytes; + outFacts.m_ManagerState.m_Calls += thePoolFact.m_Calls; + outFacts.m_ManagerState.m_Used += theUsed; + outFacts.m_ManagerState.m_Align += theAlign; + outFacts.m_ManagerState.m_Miss += thePoolFact.m_Miss; + + theManagerChunks += thePool.GetChunkCount(); + theManagerBytes += theUsed * thePool.GetChunkSize(); + } + + thePresentationBytes += + theManager->GetManagerData().m_Overflow.GetBytes(theScope, theValue); + + // Both the manager sub-total and grand-total need to track bytes separately + // since the percentages can't just be added or averaged. Those totals + // are instead weighted and this is the tracking math that does it. + theTotalChunks += theManagerChunks; + theTotalBytes += theManagerBytes; + + theManagerFact.m_Used = 0; + if (theManagerChunks > 0) + theManagerFact.m_Used = 100 * theManagerFact.m_Used / theManagerChunks; + + theManagerFact.m_Align = 100; + if (theManagerBytes > 0) + theManagerFact.m_Align = 100 * theManagerFact.m_Align / theManagerBytes; + + CullHistogram(theManager->GetHistogram(), theValue, outFacts.m_Histogram[theManagerIndex]); + } + + // Again this is the grand-total separate percentage computation that has + // to be done in the end when all sums have been added. + outFacts.m_ManagerState.m_Used = 0; + if (theTotalChunks > 0) + outFacts.m_ManagerState.m_Used = 100 * outFacts.m_ManagerState.m_Used / theTotalChunks; + + outFacts.m_ManagerState.m_Align = 100; + if (theTotalBytes > 0) + outFacts.m_ManagerState.m_Align = 100 * outFacts.m_ManagerState.m_Align / theTotalBytes; + +#endif // Q3DStudio_MEMORY_POOLTRACKING + + // return thePresentationBytes; +} + +//============================================================================== +/** + * Find the HISTOGRAMLIMIT highest performers in the histogram. + * @param inHistogram array of CMemoryManager::HISTOGRAMCOUNT values + * each showing the number of allocation of that bytesize + * @param outResults collects the highest points of the histogram + */ +void CMemoryStatistics::CullHistogram(const CMemoryProbe::SValue *inHistogram, + const EMemoryValue inValue, + SHistogramScore outResults[HISTOGRAMCOUNT]) +{ + // Always clear even if there is no data + Q3DStudio_memset(outResults, 0, sizeof(SHistogramScore)); + + // Return quickly when no data + if (!inHistogram) + return; + + // Scan full histogram + INT32 theLowestIndex = 0; + for (UINT16 theSize = 0; theSize < 512; ++theSize) { + // Is this count higher than the lowest recorded count? + if (inHistogram[theSize].m_Value[inValue] > outResults[theLowestIndex].m_Count) { + outResults[theLowestIndex].m_Count = inHistogram[theSize].m_Value[inValue]; + outResults[theLowestIndex].m_Size = theSize; + + // Find new low in high score + theLowestIndex = 0; + for (UINT16 theResult = 1; theResult < HISTOGRAMCOUNT; ++theResult) + if (outResults[theResult].m_Count < outResults[theLowestIndex].m_Count) + theLowestIndex = theResult; + } + } + + // Sort histogram - brute force for now so don't call this all the time + ::qsort(outResults, 10, sizeof(SHistogramScore), CompareHistogram); +} + +//============================================================================== +/** + * Helper comparison function for CullHistogram + */ +int CMemoryStatistics::CompareHistogram(const void *arg1, const void *arg2) +{ + return reinterpret_cast(arg2)->m_Count + - reinterpret_cast(arg1)->m_Count; +} + +//============================================================================== +/** + * Helper comparison function for CMemoryStatistics::HeapReport + */ +int CMemoryStatistics::CompareHeap(const void *inEntry1, const void *inEntry2) +{ + return reinterpret_cast(inEntry1)->m_Size + - reinterpret_cast(inEntry2)->m_Size; +} + +//============================================================================== +// REPORTING +//============================================================================== + +//============================================================================== +/** + * Simple memory usage report covering both bytes allocated and call count. + * @param inStream the stream we are sending the report or NULL to use logger + */ +void CMemoryStatistics::SimpleReport(IStream *inStream /*=NULL*/) +{ + CHAR theReportBuffer[REPORTSIZE]; + CMemoryProbe theProbe; + + // Basic info is always available + Report(inStream, "\n --- RUNTIME SIMPLE MEMORY REPORT ---\n"); + + // Only the first manager is reported for now + Q3DStudio_ASSERT(s_PoolManagers[0]); + theProbe = s_PoolManagers[0]->GetManagerData().m_Aligned; + theProbe.Combine(s_PoolManagers[0]->GetManagerData().m_Overflow); + Report(inStream, "PRESENTATION: Current Peak Alloc Free\n"); + Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), + "Global:%12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT), + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_PEAK) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_PEAK), + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_ADDS) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_ADDS), + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_DELETES) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_DELETES)); + Report(inStream, theReportBuffer); + Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), + "Reset: %12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_CURRENT) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_CURRENT), + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_PEAK) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_PEAK), + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_ADDS) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_ADDS), + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_DELETES) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_DELETES)); + Report(inStream, theReportBuffer); + + // Overflow is memory not serviced by memory pools - removed to make the simple report... + // simpler + /* theProbe = s_PoolManagers[0]->GetManagerData( ).m_Overflow; + Report( inStream, "OVERFLOW:\n" ); + Q3DStudio_sprintf( theReportBuffer, sizeof( theReportBuffer ), + "Global:%12ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)\n", + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT ), + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_PEAK )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_PEAK ), + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_ADDS )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_ADDS ), + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_DELETES )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_DELETES ) ); + Report( inStream, theReportBuffer ); + Q3DStudio_sprintf( theReportBuffer, sizeof( theReportBuffer ), "Reset: + %12ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)%8ldk(%4ld)\n", + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_CURRENT ), + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_PEAK )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_PEAK ), + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_ADDS )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_ADDS ), + theProbe.GetBytes( MEMSCOPE_GLOBAL, MEMVALUE_DELETES )/1024, + theProbe.GetCalls( MEMSCOPE_GLOBAL, MEMVALUE_DELETES ) ); + Report( inStream, theReportBuffer );*/ + + // All managers share the same heap + theProbe = CMemoryHeap::GetProbe(); + Report(inStream, "HEAP:\n"); + Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), + "Global:%12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_CURRENT), + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_PEAK) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_PEAK), + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_ADDS) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_ADDS), + theProbe.GetBytes(MEMSCOPE_GLOBAL, MEMVALUE_DELETES) / 1024, + theProbe.GetCalls(MEMSCOPE_GLOBAL, MEMVALUE_DELETES)); + Report(inStream, theReportBuffer); + Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), + "Reset: %12dk(%4d)%8dk(%4d)%8dk(%4d)%8dk(%4d)\n", + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_CURRENT) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_CURRENT), + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_PEAK) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_PEAK), + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_ADDS) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_ADDS), + theProbe.GetBytes(MEMSCOPE_RESET, MEMVALUE_DELETES) / 1024, + theProbe.GetCalls(MEMSCOPE_RESET, MEMVALUE_DELETES)); + Report(inStream, theReportBuffer); + + Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), "Tracking overhead: %dk\n", +#if Q3DStudio_MEMORY_HEAPTRACKING + (s_Overhead + sizeof(CMemoryHeap::TMemoryReport)) / 1024); +#else + s_Overhead / 1024); +#endif // Q3DStudio_MEMORY_HEAPTRACKING + + Report(inStream, theReportBuffer); +} + +//============================================================================== +/** + * Output the memory report log. + * + * The is always watched by a CMemoryProbe that records all activity. Most + * individual allocations will not be recorded though since they are handled + * by memory pools. + * + * A probe records three axis of information (value, scope and call/bytes). + * + * # Value (current,peak,add,del) tracks the current value along with its + * peak value, and also separately tracks adds(allocations) and deletes(frees) + * such that current = add - del. + * # Scope (local,global) tracks values since last reset or dawn of heap. + * # Call/Bytes tracks separately bytes and calls so you can distinguish between + * many small allocations and a few large. + * + * @param inStream the stream we are sending the report or NULL to use logger + */ +void CMemoryStatistics::HeapReport(IStream *inStream /*=NULL*/) +{ + Report(inStream, "\n --- RUNTIME HEAP MEMORY REPORT ---\n"); + +#if Q3DStudio_MEMORY_HEAPTRACKING + // Detailed info needs Q3DStudio_MEMORY_HEAPTRACKING defined + INT32 theCount = CMemoryHeap::GetReport()->GetCount(); + ::qsort(&CMemoryHeap::GetReport()[0], static_cast(theCount), + sizeof(CMemoryHeap::SReportEntry), CompareHeap); + + CHAR theReportBuffer[REPORTSIZE]; + for (INT32 theIndex = 0; theIndex < theCount; ++theIndex) { + CMemoryHeap::SReportEntry &theEntry = CMemoryHeap::GetReport()->operator[](theIndex); + Q3DStudio_sprintf(theReportBuffer, sizeof(theReportBuffer), + "%3d. %8d bytes - \"%s\" - %s (%d)\n", theIndex, theEntry.m_Size, + theEntry.m_Description, theEntry.m_File, theEntry.m_Line); + Report(inStream, theReportBuffer); + } +#else + Report(inStream, " Unavailable: Q3DStudio_MEMORY_HEAPTRACKING not defined in this build\n"); +#endif +} + +/* Example output of CMemoryStatistics::Report + +=POOL= HEAP CALLS USED ALIGN MISSES +--------------------------------------------------------------- +All Managers 722k 38 72% 19% + + Global 482k + 0: 16b x 1024 16k 2182 3% 13% + 1: 32b x 2048 64k 4123 96% 9% 38 + 2: 48b x 512 24k 212 72% 21% + 3: 64b x 512 32k 454 11% 3% + . + 8: 512b x 128 64k 68 64% 22% +*/ + +//============================================================================== +/** + * Return a text buffer describing the state of the memory system. + */ +void CMemoryStatistics::PoolReport(BOOL inPeak /*= true*/, BOOL inGlobal /*= true*/, + IStream *inStream /*=NULL*/) +{ + CHAR theLine[256] = { 0 }; + SFactSheet theFacts; + + GetFacts(theFacts, inPeak, inGlobal); + + Report(inStream, "\n --- RUNTIME POOL MEMORY REPORT ---\n"); + Q3DStudio_sprintf(theLine, 256, + "Mode: %s %s\nTotal Heap: %7dk(%d)\nPresentation: %7dk\n", + inGlobal ? "GLOBAL" : "RESET", inPeak ? "PEAK" : "CURRENT", + theFacts.m_HeapState.m_Bytes / 1024, theFacts.m_HeapState.m_Calls, + GetRequestedBytes(inPeak) / 1024); + Report(inStream, theLine); + +#if Q3DStudio_MEMORY_POOLTRACKING + Report(inStream, "=POOLS= HEAP HITS USED ALIGN MISS" + "\n"); + Report(inStream, "-----------------------------------------------------------------" + "\n"); + Q3DStudio_sprintf(theLine, 256, "All Managers %7dk %8d %5d%% %5d%% %6d" + "\n\n", + theFacts.m_ManagerState.m_Bytes / 1024, theFacts.m_ManagerState.m_Calls, + theFacts.m_ManagerState.m_Used, theFacts.m_ManagerState.m_Align, + theFacts.m_ManagerState.m_Miss); + Report(inStream, theLine); + + for (INT32 theManagerIndex = 0; theManagerIndex < MANAGERCOUNT; ++theManagerIndex) { + SFactoid &theManagerFact = theFacts.m_Manager[theManagerIndex]; + if (theManagerFact.m_Bytes > 0) { + Q3DStudio_sprintf(theLine, 256, "%-20s %7dk %8d %5d%% %5d%% %6d\n", + theManagerFact.m_Name, theManagerFact.m_Bytes / 1024, + theManagerFact.m_Calls, theManagerFact.m_Used, theManagerFact.m_Align, + theManagerFact.m_Miss); + Report(inStream, theLine); + + for (INT32 thePoolIndex = 0; thePoolIndex < Q3DStudio_MEMORY_POOLCOUNT; + ++thePoolIndex) { + SFactoid &thePoolFact = theFacts.m_Pool[theManagerIndex][thePoolIndex]; + if (theManagerFact.m_Bytes > 0) { + Q3DStudio_sprintf(theLine, 256, "%-20s %7dk %8d %5d%% %5d%% %6d\n", + thePoolFact.m_Name, thePoolFact.m_Bytes / 1024, + thePoolFact.m_Calls, thePoolFact.m_Used, thePoolFact.m_Align, + thePoolFact.m_Miss); + Report(inStream, theLine); + } + } + + // Histogram only valid for Current-Reset + if (inGlobal) { + Report(inStream, " Histogram: Only available in RESET mode\n"); + } else { + Q3DStudio_sprintf( + theLine, 256, + " Histogram: 1:%3db(%3d) 2:%3db(%3d) 3:%3db(%3d) 4:%3db(%3d) 5:%3db(%3d)\n", + theFacts.m_Histogram[theManagerIndex][0].m_Size, + theFacts.m_Histogram[theManagerIndex][0].m_Count, + theFacts.m_Histogram[theManagerIndex][1].m_Size, + theFacts.m_Histogram[theManagerIndex][1].m_Count, + theFacts.m_Histogram[theManagerIndex][2].m_Size, + theFacts.m_Histogram[theManagerIndex][2].m_Count, + theFacts.m_Histogram[theManagerIndex][3].m_Size, + theFacts.m_Histogram[theManagerIndex][3].m_Count, + theFacts.m_Histogram[theManagerIndex][4].m_Size, + theFacts.m_Histogram[theManagerIndex][4].m_Count); + Report(inStream, theLine); + Q3DStudio_sprintf( + theLine, 256, + " 6:%3db(%3d) 7:%3db(%3d) 8:%3db(%3d) 9:%3db(%3d) 10:%3db(%3d)\n", + theFacts.m_Histogram[theManagerIndex][5].m_Size, + theFacts.m_Histogram[theManagerIndex][5].m_Count, + theFacts.m_Histogram[theManagerIndex][6].m_Size, + theFacts.m_Histogram[theManagerIndex][6].m_Count, + theFacts.m_Histogram[theManagerIndex][7].m_Size, + theFacts.m_Histogram[theManagerIndex][7].m_Count, + theFacts.m_Histogram[theManagerIndex][8].m_Size, + theFacts.m_Histogram[theManagerIndex][8].m_Count, + theFacts.m_Histogram[theManagerIndex][9].m_Size, + theFacts.m_Histogram[theManagerIndex][9].m_Count); + Report(inStream, theLine); + } + } + } +#else + Report(inStream, " Unavailable: Q3DStudio_MEMORY_POOLTRACKING not defined in this build\n"); +#endif +} + +//============================================================================== +/** + * Dump the low-level memory list stored in each manager's hash bin. + * + * @note Q3DStudio_MEMORY_LINETRACKING has to be set to 1 in AKMemorySettings.h or + * the compiler for this method to save out any data. + * + * @param inStream the stream we are sending the report or NULL to use logger + */ +void CMemoryStatistics::LineReport(IStream *inStream /*=NULL*/) +{ + Report(inStream, "\n--- RUNTIME LINE MEMORY REPORT ---\n"); +#if Q3DStudio_MEMORY_LINETRACKING + Report(inStream, "ADDR, SIZE, TYPE, LINE, FILE, \n"); + + INT32 theTotalBytes = 0; + for (INT32 theManagerIndex = 0; theManagerIndex < MANAGERCOUNT; ++theManagerIndex) + if (s_PoolManagers[theManagerIndex] && s_PoolManagers[theManagerIndex]->GetLineTracker()) + theTotalBytes += s_PoolManagers[theManagerIndex]->GetLineTracker()->Report(inStream); + + CHAR theTotal[64]; + theTotal[0] = '\0'; + + Q3DStudio_sprintf(theTotal, sizeof(theTotal), "TOTAL: , %8d\n", theTotalBytes); + Report(inStream, theTotal); +#else + Report(inStream, " Unavailable: Q3DStudio_MEMORY_LINETRACKING not defined in this build\n"); +#endif // Q3DStudio_MEMORY_LINETRACKING +} + +//============================================================================== +/** + * Output to log or stream if available. + * @param inMessage string to be reported + * @param inStream stream to be used or output to log if NULL + */ +void CMemoryStatistics::Report(IStream *inStream, const CHAR *inMessage) +{ + if (inStream) + inStream->WriteRaw(inMessage, (INT32)::strlen(inMessage)); + else + qCInfo(qt3ds::TRACE_INFO) << inMessage; +} + +//============================================================================== +/** + * Output full memory report to log or stream if available. + * @param inStream stream to be used or output to log if NULL + */ +void CMemoryStatistics::FullReport(IStream *inStream /*=NULL*/) +{ + SimpleReport(inStream); + HeapReport(inStream); + LineReport(inStream); + PoolReport(false, false, inStream); + PoolReport(true, false, inStream); + PoolReport(false, true, inStream); + PoolReport(true, true, inStream); +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryStatistics.h b/src/Runtime/Source/system/Qt3DSMemoryStatistics.h new file mode 100644 index 00000000..81e30434 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryStatistics.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryManager.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Static facade to memory statistics and allocation tracking data. + * + * Use this class to examine the memory state of the system at any point. + * Heap, managers and pools are are connected to this point by registering + * themselves on creation. Initiate the extraction of the collected data + * using this interface. + */ +class CMemoryStatistics +{ + //============================================================================== + // Constants + //============================================================================== +public: + const static INT32 REPORTSIZE = 256; ///< Max size of single report string + const static INT32 MANAGERCOUNT = 5; ///< Fixed number of managers tracked + const static INT32 HISTOGRAMCOUNT = 10; ///< Fixed number of managers tracked + + //============================================================================== + // Structs + //============================================================================== +public: + /// One row of statistics on allocation + struct SFactoid + { + CHAR m_Name[32]; ///< Ascii identifier - manager name or pool description + INT32 m_Bytes; ///< Bytes used - full pool size for example - zero if factoid unused + INT32 m_Calls; ///< Function calls, i.e number of allocations + INT32 m_Used; ///< Discrete chunk usage in percent - 10 used of 200 gives a value 5 + INT32 m_Align; ///< Packed efficiency in percent - all 24byte structs in 32byte pool give a + ///value 75 + INT32 m_Miss; ///< Allocation misses - due to full pools for example + }; + + /// Tuple describing one data point in a histogram + struct SHistogramScore + { + INT32 m_Size; ///< Allocation request in bytes + INT32 m_Count; ///< Number of allocation requests + }; + + /// Set of factoids describing a system memory state + struct SFactSheet + { + SFactoid m_HeapState; ///< Heap facts + SFactoid m_ManagerState; ///< Combined manager facts + SFactoid m_Manager[MANAGERCOUNT]; ///< Individual manager facts + SHistogramScore m_Histogram[MANAGERCOUNT][HISTOGRAMCOUNT]; ///< Top allocation requests + ///sorted by bytes, global and + ///never reset + SFactoid m_Pool[MANAGERCOUNT][Q3DStudio_MEMORY_POOLCOUNT]; ///< Individual pool facts + }; + + //============================================================================== + // Fields + //============================================================================== +protected: + static INT32 s_Overhead; ///< Memory tracking structures report in here + static CMemoryManager + *s_PoolManagers[MANAGERCOUNT]; ///< Pointers to all created memory pool managers + + //============================================================================== + // Methods + //============================================================================== +public: // Registration + static void AddManager(CMemoryManager *inManager); + static void RemoveManager(CMemoryManager *inManager); + static INT32 &Overhead(); + +public: // Access + static void Reset(); + static void GetFacts(SFactSheet &outFacts, const BOOL inPeak = false, + const BOOL inGlobal = false); + static INT32 GetRequestedBytes(const BOOL inPeak = false); + static INT32 GetHeapBytes(const BOOL inPeak = false); + +public: // Reporting + static void SimpleReport(IStream *inStream = NULL); + static void HeapReport(IStream *inStream = NULL); + static void PoolReport(const BOOL inPeak = false, const BOOL inGlobal = false, + IStream *inStream = NULL); + static void LineReport(IStream *inStream = NULL); + + static void FullReport(IStream *inStream = NULL); + static void Report(IStream *inStream, const CHAR *inString); + +protected: // Utility + static void CullHistogram(const CMemoryProbe::SValue *inHistogram, const EMemoryValue inValue, + SHistogramScore outResults[HISTOGRAMCOUNT]); + static int CompareHeap(const void *arg1, const void *arg2); + static int CompareHistogram(const void *arg1, const void *arg2); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryTracker.cpp b/src/Runtime/Source/system/Qt3DSMemoryTracker.cpp new file mode 100644 index 00000000..8aef9519 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryTracker.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSMemoryTracker.h" +#include "foundation/Qt3DSLogging.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Construct and reset the tracker. + */ +CMemoryTracker::CMemoryTracker() + : m_TrackingOverhead(0) +{ + Q3DStudio_memset(&m_TrackingHashBin, 0, sizeof(m_TrackingHashBin)); + CMemoryStatistics::Overhead() += sizeof(m_TrackingHashBin); +} + +//============================================================================== +/** + * Destructor + */ +CMemoryTracker::~CMemoryTracker() +{ + CMemoryStatistics::Overhead() -= sizeof(m_TrackingHashBin); +} + +//============================================================================== +/** + * Add information about allocation + * @param inPtr contains info about a new allocation + */ +void CMemoryTracker::Remember(SMemoryInfo *inPointer) +{ + if (inPointer) { + // Update global tracking + m_TrackingOverhead += sizeof(SMemoryInfo); + + // Locate a suitable hashbin + size_t theHashBin = + (reinterpret_cast(inPointer) >> 2) % Q3DStudio_MEMORY_LINETRACKINGSIZE; + size_t theStartHashBin = theHashBin; + + while (m_TrackingHashBin[theHashBin]) { + ++theHashBin; + if (theHashBin >= Q3DStudio_MEMORY_LINETRACKINGSIZE) + theHashBin = 0; + + if (theHashBin == theStartHashBin) { + // We've run out of room in the hashbin. + // Abort and increase the bin size. + qCCritical(qt3ds::OUT_OF_MEMORY) + << "Memory Tracker Error: Ran out of room in tracker hashbin " + << Q3DStudio_MEMORY_LINETRACKINGSIZE; + // exit( -1 ); + } + } + + // Set WatchGuard and store the pointer in the hash bin + inPointer->m_DogTag = TRACKER_DOGTAG; + m_TrackingHashBin[theHashBin] = inPointer; + } +} + +//============================================================================== +/** + * Remove information on an allocation + * @param inPtr contains info about the allocation we are releasing + */ +void CMemoryTracker::Forget(SMemoryInfo *inPointer) +{ + if (inPointer) { + // Update global tracking + m_TrackingOverhead -= sizeof(SMemoryInfo); + + // Locate the pointer in the hash bin + size_t theHashBin = Q3DStudio_max(0, (reinterpret_cast(inPointer) >> 2) + % Q3DStudio_MEMORY_LINETRACKINGSIZE); + size_t theStartHashBin = theHashBin; + + while (m_TrackingHashBin[theHashBin] != inPointer) { + ++theHashBin; + if (theHashBin >= Q3DStudio_MEMORY_LINETRACKINGSIZE) + theHashBin = 0; + + if (theHashBin == theStartHashBin) { + // We were unable to locate the pointer in the hash bin. + // This is really bad, but not catastrophic + qCWarning(qt3ds::OUT_OF_MEMORY) + << "Memory Tracker Warning. Can't find pointer in tracker hashbin"; + return; + } + } + + // Verify watch guard. Something is trashing memory if this call fails. + Q3DStudio_ASSERT(m_TrackingHashBin[theHashBin]->m_DogTag == TRACKER_DOGTAG); + + // Clear the pointer from the hash bin + m_TrackingHashBin[theHashBin] = NULL; + } +} + +//============================================================================== +/** + * Dump the memory list stored in the hash bin. + * @param inFileName the report filename or NULL to dump to the logger + */ +INT32 CMemoryTracker::Report(IStream *inStream /*=NULL*/) +{ + INT32 theTotalBytes = 0; + CHAR theLine[256]; + + for (INT32 theBinIndex = 0; theBinIndex < Q3DStudio_MEMORY_LINETRACKINGSIZE; ++theBinIndex) { + if (m_TrackingHashBin[theBinIndex]) { + CMemoryTracker::SMemoryInfo *theInfo = m_TrackingHashBin[theBinIndex]; + + Q3DStudio_sprintf(theLine, sizeof(theLine), "0x%p, %8d, %s, %s(%hd)\n", theInfo, + theInfo->m_Size, theInfo->m_Type, theInfo->m_File, theInfo->m_Line); + + CMemoryStatistics::Report(inStream, theLine); + theTotalBytes += theInfo->m_Size; + } + } + + return theTotalBytes; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSMemoryTracker.h b/src/Runtime/Source/system/Qt3DSMemoryTracker.h new file mode 100644 index 00000000..ee6ce699 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSMemoryTracker.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Low level memory statistics tracking each individual allocation. + * + * This class is instantiated in each CMemoryManager if tracking is enabled + * by setting ENABLE_MEMORY_LINETRACKING to 1 in AKConfig.h for the build + * configuration you want. + * + * Tracking is much more invasive than simple statistics since it records each + * individual allocation and deallocation. The overhead can be seen mostly in + * the memory load since we store a tracking hashbin of all memory allocation + * and a 16 byte SMemoryInfo structure is prepended to each allocation no matter + * how small. This mode should be used when debugging memory to track down + * individual allocations. It's turned off by default and should stay off + * most of the time. + * + * The tracking information is usually dumped to a comma delimited .csv file + * for easy viewing as a spreadsheet of data. This action is initiated by + * pressing CTRL-F1 in Quarterback on the PC but can be added to any viewer + * by calling CMemoryStatistics::TrackingDump. + */ +class CMemoryTracker +{ + //============================================================================== + // Constants + //============================================================================== +public: + const static UINT16 TRACKER_DOGTAG = 0xbead; ///< Watch guard value in SMemoryTrackInfo + + //============================================================================== + // Structs + //============================================================================== +public: + /// 16 bytes of details on each allocation when tracking is enabled + struct SMemoryInfo + { + UINT16 m_DogTag; ///< 0xbead - asserting this to track overwrites + INT16 m_Line; ///< line from which the allocation occurred + INT32 m_Size; ///< allocation size in bytes + const CHAR *m_File; ///< file from which the allocation occurred + const CHAR *m_Type; ///< type of allocation, usually class name + }; + + //============================================================================== + // Fields + //============================================================================== +protected: + INT32 m_TrackingOverhead; ///< memory used to track allocations in bytes + SMemoryInfo *m_TrackingHashBin[Q3DStudio_MEMORY_LINETRACKINGSIZE]; ///< hash table of all + ///tracked allocations + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CMemoryTracker(); + ~CMemoryTracker(); + +public: // Tracking + void Remember(SMemoryInfo *inData); + void Forget(SMemoryInfo *inData); + +public: // Reporting + INT32 Report(IStream *inStream = NULL); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSPlatformSpecific.h b/src/Runtime/Source/system/Qt3DSPlatformSpecific.h new file mode 100644 index 00000000..3fc34016 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSPlatformSpecific.h @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#if defined(_PCPLATFORM) + +#define Q3DStudio_memcpy(inDest, inSource, inCount) \ + memcpy(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memmove(inDest, inSource, inCount) \ + memmove(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memset(inDest, inChar, inCount) \ + memset(inDest, inChar, static_cast(inCount)) +#define Q3DStudio_memcmp(inDest, inSource, inCount) \ + memcmp(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_sprintf _snprintf +#define Q3DStudio_stricmp(inStr1, inStr2) _stricmp(inStr1, inStr2) +#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) _strnicmp(inStr1, inStr2, inCount) +#define Q3DStudio_tolower tolower +#define Q3DStudio_restrict /*__restrict*/ +#define Q3DStudio_dcbt(inOffset, inAddress) +#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy_s(inDest, inSize, inSource) +#define Q3DStudio_strcat(inDest, inSize, inSource) strcat_s(inDest, inSize, inSource) +#define Q3DStudio_fopen fopen_s +#define Q3DStudio_sleepmillisec(inMillisec) Sleep(inMillisec) +#define Q3DStudio_getpid GetCurrentProcessId + +#elif defined(_TEGRAPLATFORM) + +#define Q3DStudio_memcpy(inDest, inSource, inCount) \ + memcpy(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memmove(inDest, inSource, inCount) \ + memmove(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memset(inDest, inChar, inCount) \ + memset(inDest, inChar, static_cast(inCount)) +#define Q3DStudio_memcmp(inDest, inSource, inCount) \ + memcmp(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_sprintf _snprintf +#define Q3DStudio_stricmp(inStr1, inStr2) _stricmp(inStr1, inStr2) +#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) _strnicmp(inStr1, inStr2, inCount) +#define Q3DStudio_tolower tolower +#define Q3DStudio_restrict /*__restrict*/ +#define Q3DStudio_dcbt(inOffset, inAddress) +#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy_s(inDest, inSize, inSource) +#define Q3DStudio_strcat(inDest, inSize, inSource) strcat_s(inDest, inSize, inSource) +#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) fopen_s(inFilePtr, inFilename, inMode) +#define Q3DStudio_sleepmillisec(inMillisec) Sleep(inMillisec) +#define Q3DStudio_getpid GetCurrentProcessId + +#elif defined(_XENONPLATFORM) + +#include +#define Q3DStudio_memcpy(inDest, inSource, inCount) \ + memcpy(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memmove(inDest, inSource, inCount) \ + memmove(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memset(inDest, inChar, inCount) \ + memset(inDest, inChar, static_cast(inCount)) +#define Q3DStudio_memcmp(inDest, inSource, inCount) \ + memcmp(inDest, inSource, static_cast(inCount)) +//#define Q3DStudio_memcpy( inDest, inSource, inCount ) XMemCpy( inDest, inSource, +//static_cast( inCount ) ) +//#define Q3DStudio_memset( inDest, inChar, inCount ) XMemSet( inDest, inChar, +//static_cast( inCount ) ) +#define Q3DStudio_sprintf _snprintf +#define Q3DStudio_tolower tolower +#define Q3DStudio_restrict /*__restrict*/ +#define Q3DStudio_dcbt(inOffset, inAddress) __dcbt(inOffset, inAddress) +#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy_s(inDest, inSize, inSource) +#define Q3DStudio_strcat(inDest, inSize, inSource) strcat_s(inDest, inSize, inSource) +#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) fopen_s(inFilePtr, inFilename, inMode) +#define Q3DStudio_sleepmillisec(inMillisec) Sleep(inMillisec) +#define Q3DStudio_getpid GetCurrentProcessId +#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) _strnicmp(inStr1, inStr2, inCount) +#define Q3DStudio_stricmp(inStr1, inStr2) _stricmp(inStr1, inStr2) + +#elif defined(_PS3PLATFORM) + +#define Q3DStudio_memcpy(inDest, inSource, inCount) \ + memcpy(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memmove(inDest, inSource, inCount) \ + memmove(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memset(inDest, inChar, inCount) \ + memset(inDest, inChar, static_cast(inCount)) +#define Q3DStudio_memcmp(inDest, inSource, inCount) \ + memcmp(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_sprintf snprintf +#define Q3DStudio_tolower std::tolower +#define Q3DStudio_restrict +#define Q3DStudio_dcbt(inOffset, inAddress) +#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy(inDest, inSource) +#define Q3DStudio_strcat(inDest, inSize, inSource) strcat(inDest, inSource) +#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) *(inFilePtr) = fopen(inFilename, inMode) +#define Q3DStudio_sleepmillisec(inMillisec) \ + { \ + struct timespec theSleepTime = { inMillisec / 1000, (inMillisec % 1000) * 1000000 }; \ + ::nanosleep(&theSleepTime, NULL); \ + } +#define Q3DStudio_getpid getpid +#define Q3DStudio_stricmp(inStr1, inStr2) strcasecmp(inStr1, inStr2) +#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) strncasecmp(inStr1, inStr2, inCount) + +#elif defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +#include +#define Q3DStudio_memcpy(inDest, inSource, inCount) \ + memcpy(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memmove(inDest, inSource, inCount) \ + memmove(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_memset(inDest, inChar, inCount) \ + memset(inDest, inChar, static_cast(inCount)) +#define Q3DStudio_memcmp(inDest, inSource, inCount) \ + memcmp(inDest, inSource, static_cast(inCount)) +#define Q3DStudio_sprintf snprintf +#define Q3DStudio_stricmp(inStr1, inStr2) strcasecmp(inStr1, inStr2) +#define Q3DStudio_strnicmp(inStr1, inStr2, inCount) strncasecmp(inStr1, inStr2, inCount) +#define Q3DStudio_tolower tolower +#define Q3DStudio_restrict /*__restrict*/ +#define Q3DStudio_dcbt(inOffset, inAddress) +#define Q3DStudio_strcpy(inDest, inSize, inSource) strcpy(inDest, inSource) +#define Q3DStudio_strcat(inDest, inSize, inSource) strcat(inDest, inSource) +#define Q3DStudio_fopen(inFilePtr, inFilename, inMode) *(inFilePtr) = fopen(inFilename, inMode) +#define Q3DStudio_sleepmillisec(inMillisec) \ + { \ + struct timespec theSleepTime = { inMillisec / 1000, (inMillisec % 1000) * 1000000 }; \ + ::nanosleep(&theSleepTime, NULL); \ + } +#define Q3DStudio_getpid getpid + +#else +#error "A platform must be defined" +#endif + +//============================================================================== +/** @def Q3DStudio_dcbt( inOffset, inAddress ) + * @brief Data Cache Block Touch - Loads the block of memory containing + * the specified address into the data cache. + * + * A program uses the dcbt instruction to request a cache block fetch before + * it is actually needed by the program. This prevents stalls in the pipeline. + */ + +//============================================================================== +/** @def Q3DStudio_restrict + * @brief Cross platform macro for pointer aliasing. + * + * Performance Implications of Pointer Aliasing + * + * Doug Cook + * Silicon Graphics, Inc. + * August, 1997 + * + * Pointer aliasing can have a severe impact on program performance. + * Understanding its implications is critical to writing high-performance code. + * This document provides a brief introduction to the problem, and suggests + * several approaches to solving it through source-code restructuring, compiler + * options, and C or C++ language extensions. + * + * *Aliasing* + * + * Here's a brief overview of aliasing. Consider the following function: + * + * void process_data(float *in, float *out, float gain, int nsamps) + * { + * int i; + * for (i = 0; i < nsamps; i++) { + * out[i] = in[i] * gain; + * } + * } + * + * In C or C++, it is legal for the parameters in and out to point to + * overlapping regions in memory. When this happens, in and out are said to be + * aliases. When the compiler optimizes the function, it does not in general + * know whether in and out are aliases. It must therefore assume that any + * store through out can affect the memory pointed to by in, which severely + * limits its ability to reorder or parallelize the code (For some simple + * cases, the compiler could analyze the entire program to determine that two + * pointers cannot be aliases. But in general, it is impossible for the + * compiler to determine whether or not two pointers are aliases, so to be + * safe, it must assume that they are). + */ diff --git a/src/Runtime/Source/system/Qt3DSTimer.cpp b/src/Runtime/Source/system/Qt3DSTimer.cpp new file mode 100644 index 00000000..d9e82eb9 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSTimer.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSTimer.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + */ +CTimer::CTimer(ITimeProvider &inProvider) + : m_TimeProvider(inProvider) + , m_IsRunning(false) +{ + Start(); +} + +//============================================================================== +/** + * Start the timer + */ +void CTimer::Start() +{ + if (!m_IsRunning) + m_StartTime = m_TimeProvider.GetCurrentTimeMicroSeconds(); + m_IsRunning = true; +} + +//============================================================================== +/** + * Stop the timer + */ +void CTimer::Stop() +{ + if (m_IsRunning) + m_StartTime = m_TimeProvider.GetCurrentTimeMicroSeconds() - m_StartTime; + + m_IsRunning = false; +} + +//============================================================================== +/** + * Reset the timer + */ +void CTimer::Reset() +{ + if (m_IsRunning) + m_StartTime = m_TimeProvider.GetCurrentTimeMicroSeconds(); + else + m_StartTime = 0; +} + +//============================================================================== +/** + * Gets the current time in milliseconds. + * @return the current time since timer was started(in miliseconds), + * or time when it was stopped + */ +TTimeUnit CTimer::GetTimeMilliSecs() +{ + return GetTimeMicroSecs() / 1000; +} + +//============================================================================= +/** + * Get the number of usecs elapsed since start was called. + * If the timer is running then this will return the time from when start was + * called. If the timer is stopped then this will return the amount of time + * between the start and last stop. + * @return returns the elasped micro second. + */ +TMicroSeconds CTimer::GetTimeMicroSecs() +{ + if (m_IsRunning) + return m_TimeProvider.GetCurrentTimeMicroSeconds() - m_StartTime; + else + return m_StartTime; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSTimer.h b/src/Runtime/Source/system/Qt3DSTimer.h new file mode 100644 index 00000000..278bd4b4 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSTimer.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSITimer.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== + +//============================================================================== +/** + * Time provider interface abstracting time from the usage of time. + */ +class ITimeProvider +{ +protected: + virtual ~ITimeProvider() {} +public: + virtual INT64 GetCurrentTimeMicroSeconds() = 0; +}; + +// Pause in a way that is completely transparent to the underlying system. +class CPausingTimeProvider : public ITimeProvider +{ + ITimeProvider &m_Provider; + INT64 m_PauseOffset; + INT64 m_Offset; + bool m_Paused; + +public: + CPausingTimeProvider(ITimeProvider &inProvider) + : m_Provider(inProvider) + , m_PauseOffset(0) + , m_Offset(0) + , m_Paused(false) + { + } + + INT64 GetCurrentTimeMicroSeconds() override + { + INT64 currentTime = 0; + if (m_Paused) + currentTime = m_PauseOffset; + else + currentTime = m_Provider.GetCurrentTimeMicroSeconds(); + + return currentTime - m_Offset; + } + + void Pause() + { + if (!m_Paused) { + m_Paused = true; + m_PauseOffset = m_Provider.GetCurrentTimeMicroSeconds(); + } + } + + void UnPause() + { + if (m_Paused) { + m_Paused = false; + INT64 timePaused = m_Provider.GetCurrentTimeMicroSeconds() - m_PauseOffset; + m_Offset += timePaused; + } + } + + bool IsPaused() { return m_Paused; } + + void Reset() { m_PauseOffset = m_Offset = 0; } +}; + +//============================================================================== +/** + * @class CTimer + * @brief A very simple platform optimized utility class to return lapsed time + * + * Gets current time based on the time lapsed from the point where timer is started. + */ + +class CTimer : public ITimer +{ + + //============================================================================== + // Fields + //============================================================================== +protected: + ITimeProvider &m_TimeProvider; + INT64 m_StartTime; + BOOL m_IsRunning; // Whether this timer is running or stopped + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CTimer(ITimeProvider &inProvider); + +public: // Operation + void Start() override; + void Stop() override; + void Reset() override; + TTimeUnit GetTimeMilliSecs() override; + TMicroSeconds GetTimeMicroSecs() override; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSTypes.cpp b/src/Runtime/Source/system/Qt3DSTypes.cpp new file mode 100644 index 00000000..25d41c8b --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSTypes.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Return 2^inBitCount - 1. + * @param inBitCount number of bits available + * @param inUnsigned true if all bits are available + * @return the higest number the bits can represent + */ +INT32 Q3DStudio_maxbits(const INT32 inBitCount, const BOOL inUnsigned) +{ + Q3DStudio_ASSERT(inBitCount < 32); + if (inUnsigned) + return (1 << inBitCount) - 1; + else + return (1 << (inBitCount - 1)) - 1; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSTypes.h b/src/Runtime/Source/system/Qt3DSTypes.h new file mode 100644 index 00000000..6330919c --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSTypes.h @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Typedefs +//============================================================================== +typedef bool BOOL; ///< true or false, usually 8 bits +typedef signed char INT8; ///< A signed 8-bit integer, not a character +typedef unsigned char UINT8; ///< An unsigned 8-bit integer 0-255, not a character +typedef signed short INT16; ///< A signed 16-bit integer +typedef unsigned short UINT16; ///< An unsigned 16-bit integer +typedef int INT32; ///< A signed 32-bit integer +typedef unsigned int UINT32; ///< An unsigned 32-bit integer +typedef float FLOAT; ///< A 32-bit floating point number +typedef char CHAR; ///< String character, not a number + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +//============================================================================== +// Max constants and computation +//============================================================================== +INT32 Q3DStudio_maxbits(const INT32 inBitCount, const BOOL inUnsigned); + +#define AKMAX_INT8 static_cast(0x7F) +#define AKMAX_UINT8 static_cast(0xFF) +#define AKMAX_INT16 static_cast(0x7FFF) +#define AKMAX_UINT16 static_cast(0xFFFF) +#define AKMAX_INT32 0x7FFFFFFFL +#define AKMAX_UINT32 0xFFFFFFFFUL + +//============================================================================== +// Platform specific vectors and matrices +//============================================================================== +#if defined(_PCPLATFORM) + +typedef FILE TFile; +typedef size_t TFileSize; + +#define Q3DStudio_INT64_C(x) x +#define Q3DStudio_UINT64_C(x) x + +typedef __int64 INT64; +typedef unsigned __int64 UINT64; + +struct VECTOR4 +{ + union { + FLOAT v[4]; + UINT32 u[4]; + }; + + FLOAT &x() { return v[0]; } + FLOAT &y() { return v[1]; } + FLOAT &z() { return v[2]; } + FLOAT &w() { return v[3]; } +}; + +struct MATRIX16 +{ + union { + VECTOR4 v[4]; + FLOAT m[4][4]; + FLOAT f[16]; + }; + + FLOAT &_11() { return f[0]; } + FLOAT &_12() { return f[1]; } + FLOAT &_13() { return f[2]; } + FLOAT &_14() { return f[3]; } + FLOAT &_21() { return f[4]; } + FLOAT &_22() { return f[5]; } + FLOAT &_23() { return f[6]; } + FLOAT &_24() { return f[7]; } + FLOAT &_31() { return f[8]; } + FLOAT &_32() { return f[9]; } + FLOAT &_33() { return f[10]; } + FLOAT &_34() { return f[11]; } + FLOAT &_41() { return f[12]; } + FLOAT &_42() { return f[13]; } + FLOAT &_43() { return f[14]; } + FLOAT &_44() { return f[15]; } +}; + +#elif defined(_TEGRAPLATFORM) + +// TODO: sk - We used both WinCE and OpenKode file system utilities. Using non-OpenKode restores +// functionality in a hacky way +// but ultimately sticking to just 1 system would definitely be cleaner. +typedef FILE TFile; +typedef size_t TFileSize; +// typedef KDFile TFile; +// typedef KDsize TFileSize; + +#define Q3DStudio_INT64_C(x) x +#define Q3DStudio_UINT64_C(x) x + +typedef __int64 INT64; +typedef unsigned __int64 UINT64; + +struct VECTOR4 +{ + union { + FLOAT v[4]; + UINT32 u[4]; + }; + FLOAT &x() { return v[0]; } + FLOAT &y() { return v[1]; } + FLOAT &z() { return v[2]; } + FLOAT &w() { return v[3]; } +}; + +struct MATRIX16 +{ + union { + VECTOR4 v[4]; + FLOAT m[4][4]; + FLOAT f[16]; + }; + + FLOAT &_11() { return f[0]; } + FLOAT &_12() { return f[1]; } + FLOAT &_13() { return f[2]; } + FLOAT &_14() { return f[3]; } + FLOAT &_21() { return f[4]; } + FLOAT &_22() { return f[5]; } + FLOAT &_23() { return f[6]; } + FLOAT &_24() { return f[7]; } + FLOAT &_31() { return f[8]; } + FLOAT &_32() { return f[9]; } + FLOAT &_33() { return f[10]; } + FLOAT &_34() { return f[11]; } + FLOAT &_41() { return f[12]; } + FLOAT &_42() { return f[13]; } + FLOAT &_43() { return f[14]; } + FLOAT &_44() { return f[15]; } +}; + +#elif defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + +typedef FILE TFile; +typedef size_t TFileSize; + +#define Q3DStudio_INT64_C(x) x +#define Q3DStudio_UINT64_C(x) x + +typedef int64_t INT64; +typedef uint64_t UINT64; + +struct VECTOR4 +{ + union { + FLOAT v[4]; + UINT32 u[4]; + }; + + FLOAT &x() { return v[0]; } + FLOAT &y() { return v[1]; } + FLOAT &z() { return v[2]; } + FLOAT &w() { return v[3]; } +}; + +struct MATRIX16 +{ + union { + VECTOR4 v[4]; + FLOAT m[4][4]; + FLOAT f[16]; + }; + + FLOAT &_11() { return f[0]; } + FLOAT &_12() { return f[1]; } + FLOAT &_13() { return f[2]; } + FLOAT &_14() { return f[3]; } + FLOAT &_21() { return f[4]; } + FLOAT &_22() { return f[5]; } + FLOAT &_23() { return f[6]; } + FLOAT &_24() { return f[7]; } + FLOAT &_31() { return f[8]; } + FLOAT &_32() { return f[9]; } + FLOAT &_33() { return f[10]; } + FLOAT &_34() { return f[11]; } + FLOAT &_41() { return f[12]; } + FLOAT &_42() { return f[13]; } + FLOAT &_43() { return f[14]; } + FLOAT &_44() { return f[15]; } +}; + +#else + +#error "A platform must be defined" + +#endif + +typedef INT64 TMicroSeconds; ///< Time in microseconds +typedef INT64 TTimeUnit; ///< Time in milliseconds + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSVector3.cpp b/src/Runtime/Source/system/Qt3DSVector3.cpp new file mode 100644 index 00000000..2d790f95 --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSVector3.cpp @@ -0,0 +1,466 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "SystemPrefix.h" + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSVector3.h" +#include "Qt3DSMatrix.h" +#include "Qt3DSDataLogger.h" +#include + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +extern const float RUNTIME_EPSILON = 0.0001f; +const float RUNTIME_SQUARE_EPSILON = 0.000001f; + +//============================================================================== +/** + * Simple constructor - creates a NULL vector. + */ +RuntimeVector3::RuntimeVector3() + : m_X(0.0f) + , m_Y(0.0f) + , m_Z(0.0f) +{ +} + +//============================================================================== +/** + * Construction from three array value. + * @param inVector the source array + */ +RuntimeVector3::RuntimeVector3(const float inVector[3]) + : m_X(inVector[0]) + , m_Y(inVector[1]) + , m_Z(inVector[2]) +{ +} + +//============================================================================== +/** + * Construction from three coordinates. + * @param inX the m_X coordinate + * @param inY the m_Y coordinate + * @param inZ the m_Z coordinate + */ +RuntimeVector3::RuntimeVector3(const float inX, const float inY, const float inZ) + : m_X(inX) + , m_Y(inY) + , m_Z(inZ) +{ +} + +//============================================================================== +/** + * Copy constructor + * @param inVector the source vector + */ +RuntimeVector3::RuntimeVector3(const RuntimeVector3 &inVector) + : m_X(inVector.m_X) + , m_Y(inVector.m_Y) + , m_Z(inVector.m_Z) +{ +} + +//============================================================================== +/** + * Assignment of coordinates. + * @param inX the m_X coordinate + * @param inY the m_Y coordinate + * @param inZ the m_Z coordinate + * @return a reference to this modified vector + */ +RuntimeVector3 &RuntimeVector3::Set(const float inX, const float inY, const float inZ) +{ + m_X = inX; + m_Y = inY; + m_Z = inZ; + return *this; +} + +//============================================================================== +/** + * Assignment of coordinates using another vector. + * @param inVector the vector to be copied. + * @return a reference to this modified vector + */ +RuntimeVector3 &RuntimeVector3::Set(const RuntimeVector3 &inVector) +{ + m_X = inVector.m_X; + m_Y = inVector.m_Y; + m_Z = inVector.m_Z; + return *this; +} + +//============================================================================== +/** + * Compare this vector with another. Exact match is not needed but instead + * an error of EPSILON is allowed. + * @param inVector the vector we are compared with + * @return true if the vectors are close to identical + * @see EPSILON + */ +bool RuntimeVector3::operator==(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + + return (::fabsf(m_X - inVector.m_X) < RUNTIME_EPSILON) && (::fabsf(m_Y - inVector.m_Y) < RUNTIME_EPSILON) + && (::fabsf(m_Z - inVector.m_Z) < RUNTIME_EPSILON); +} + +//============================================================================== +/** + * Compare this vector with another. Exact match is not needed but instead + * an error of EPSILON is allowed. + * @param inVector the vector we are compared with + * @return true if the vectors are not even close to identical + * @see EPSILON + */ +bool RuntimeVector3::operator!=(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + + return (::fabsf(m_X - inVector.m_X) > RUNTIME_EPSILON) || (::fabsf(m_Y - inVector.m_Y) > RUNTIME_EPSILON) + || (::fabsf(m_Z - inVector.m_Z) > RUNTIME_EPSILON); +} + +//============================================================================== +/** + * Add this vector with another but do not modify this vector. + * @param inVector the second vector being added + * @return a new vector + */ +RuntimeVector3 RuntimeVector3::operator+(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + + return RuntimeVector3(m_X + inVector.m_X, m_Y + inVector.m_Y, m_Z + inVector.m_Z); +} + +//============================================================================== +/** + * Add two vectors but do not modify this vector. + * @param inVector vector being subtracted + * @return a new vector + */ +RuntimeVector3 RuntimeVector3::operator-(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return RuntimeVector3(m_X - inVector.m_X, m_Y - inVector.m_Y, m_Z - inVector.m_Z); +} + +//============================================================================== +/** + * Get a scaled copy of this vector. + * @param inFactor the factor that scales each coordinate + * @return a new scaled vector + */ +RuntimeVector3 RuntimeVector3::operator*(float inFactor) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return RuntimeVector3(m_X * inFactor, m_Y * inFactor, m_Z * inFactor); +} + +//============================================================================== +/** + * Invert the vector. + * @return the inverted copy of this vector + */ +RuntimeVector3 RuntimeVector3::operator-() const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return RuntimeVector3(-m_X, -m_Y, -m_Z); +} + +//============================================================================== +/** + * Simple assignment. + * @param inVector the new vector + * @return a reference to this modified vector + */ +RuntimeVector3 &RuntimeVector3::operator=(const RuntimeVector3 &inVector) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + if (&inVector != this) { + m_X = inVector.m_X; + m_Y = inVector.m_Y; + m_Z = inVector.m_Z; + } + return *this; +} + +//============================================================================== +/** + * Increment this vector. + * @param inVector has the coordinates by which this vector will be incremented + * @return a reference to this modified vector + */ +RuntimeVector3 &RuntimeVector3::operator+=(const RuntimeVector3 &inVector) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + m_X += inVector.m_X; + m_Y += inVector.m_Y; + m_Z += inVector.m_Z; + return *this; +} + +//============================================================================== +/** + * Decrement this vector. + * @param inVector has the coordinates by which this vector will be decremented + * @return a reference to this modified vector + */ +RuntimeVector3 &RuntimeVector3::operator-=(const RuntimeVector3 &inVector) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + m_X -= inVector.m_X; + m_Y -= inVector.m_Y; + m_Z -= inVector.m_Z; + return *this; +} + +//============================================================================== +/** + * Scale this vector by a factor. + * @param inFactor the scale factor + * @return a reference to this modified vector + */ +RuntimeVector3 &RuntimeVector3::operator*=(float inFactor) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + m_X *= inFactor; + m_Y *= inFactor; + m_Z *= inFactor; + return *this; +} + +//============================================================================== +/** + * Calculates the squared distance between this vector and another. + * This is often used in sorting situations where the real distance isn't needed. + * @param inVector vector to which the distance is being calculated + * @return the squared distance between vectors + */ +float RuntimeVector3::DistanceSquared(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return (m_X - inVector.m_X) * (m_X - inVector.m_X) + (m_Y - inVector.m_Y) * (m_Y - inVector.m_Y) + + (m_Z - inVector.m_Z) * (m_Z - inVector.m_Z); +} + +//============================================================================== +/** + * Calculates the distance between this vector and another. + * @param inVector vector to which the distance is being calculated + * @return the distance between vectors + */ +float RuntimeVector3::Distance(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return ::sqrtf((m_X - inVector.m_X) * (m_X - inVector.m_X) + + (m_Y - inVector.m_Y) * (m_Y - inVector.m_Y) + + (m_Z - inVector.m_Z) * (m_Z - inVector.m_Z)); +} + +//============================================================================== +/** + * Calculates the squared length (squared magnitude) of the current vector. + * @return the squared length of this vector + */ +float RuntimeVector3::LengthSquared() const +{ + return m_X * m_X + m_Y * m_Y + m_Z * m_Z; +} + +//============================================================================== +/** + * Calculates the length (magnitude) of the current vector. + * @return the length of this vector + */ +float RuntimeVector3::Length() const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return ::sqrtf(m_X * m_X + m_Y * m_Y + m_Z * m_Z); +} + +//============================================================================== +/** + * Calculates the dot product of this vector and another. + * @param inVector vector measuring with + * @return the dot product + * @see operator* + */ +float RuntimeVector3::DotProduct(const RuntimeVector3 &inVector) const +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + return m_X * inVector.m_X + m_Y * inVector.m_Y + m_Z * inVector.m_Z; +} + +//============================================================================== +/** + * Calculates the cross product of this vector and another and modifies this vector + * @param inVector other vector + * @return this cross product vector + * @see operator% + * @see operator%= + */ +RuntimeVector3 &RuntimeVector3::CrossProduct(const RuntimeVector3 &inVector) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + float theX = m_Y * inVector.m_Z - m_Z * inVector.m_Y; + float theY = m_Z * inVector.m_X - m_X * inVector.m_Z; + float theZ = m_X * inVector.m_Y - m_Y * inVector.m_X; + + m_X = theX; + m_Y = theY; + m_Z = theZ; + + return *this; +} + +//============================================================================== +/** + * Normalizes the current vector making it a unit vector. + * The normalized vector is defined to be: V_norm = V / Magnitude(V). + * @return this normalized vector +*/ +RuntimeVector3 &RuntimeVector3::Normalize() +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + float theLengthSquared = LengthSquared(); + if ((theLengthSquared > RUNTIME_SQUARE_EPSILON) && ::fabsf(theLengthSquared - 1.0f) > RUNTIME_SQUARE_EPSILON) { + float theInvLength = 1.0f / ::sqrtf(theLengthSquared); + m_X *= theInvLength; + m_Y *= theInvLength; + m_Z *= theInvLength; + } + return *this; +} + +//============================================================================== +/** + * Modifies the current vector to contain elements that are the minimum between + * this vector and another. + * @param inVector vector that whose elements are tested against the + * current vector to build the minimum. + * @return this minimized vector +*/ +RuntimeVector3 &RuntimeVector3::Minimize(const RuntimeVector3 &inVector) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + m_X = Q3DStudio_min(m_X, inVector.m_X); + m_Y = Q3DStudio_min(m_Y, inVector.m_Y); + m_Z = Q3DStudio_min(m_Z, inVector.m_Z); + return *this; +} + +//============================================================================== +/** + * Modifies the current vector to contain elements that are the maximum between + * this vector and another. + * @param inVector vector that whose elements are tested against the + * current vector to build the maximum. + * @return this maximized vector +*/ +RuntimeVector3 &RuntimeVector3::Maximize(const RuntimeVector3 &inVector) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + m_X = Q3DStudio_max(m_X, inVector.m_X); + m_Y = Q3DStudio_max(m_Y, inVector.m_Y); + m_Z = Q3DStudio_max(m_Z, inVector.m_Z); + return *this; +} + +//============================================================================== +/** + * Modifies the current vector by performing a linear interpolation + * between the current vector and the given vector. + * + * If inFactor is 0.0 then this vector remains unchanged. If inFactor is + * 1.0 then this vector becomes inDestVector. If inFactor is between 0.0-1.0 + * then this vector becomes a vector between this old vector and inDestVector + * proportionally interpolated based in inFactor. If inFactor is less than 0 + * or more than 1 then this vector is extrapolated. + * + * @param inDestVector Second vector for the interpolation + * @param inFactor Weight for the interpolation + * @return this interpolated vector + */ +RuntimeVector3 &RuntimeVector3::InterpolateLinear(const RuntimeVector3 &inDestVector, float inFactor) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + m_X += inFactor * (inDestVector.m_X - m_X); + m_Y += inFactor * (inDestVector.m_Y - m_Y); + m_Z += inFactor * (inDestVector.m_Z - m_Z); + return *this; +} + +//============================================================================== +/** + * Transforms this vector by the given matrix. + * + * The matrix is row column of the form Matrix[row][column]: +@code + | m0 m1 m2 w | + | m4 m5 m6 w | + | m8 m9 m10 w | + | tX tY tZ w | +@endcode + * @param inMatrix transform matrix + * @return this transformed vector + */ +RuntimeVector3 &RuntimeVector3::Transform(const RuntimeMatrix &inMatrix) +{ + PerfLogMathEvent1(DATALOGGER_VECTOR); + float theX = m_X; + float theY = m_Y; + float theZ = m_Z; + + m_X = theX * inMatrix.Get(0, 0) + theY * inMatrix.Get(1, 0) + theZ * inMatrix.Get(2, 0); + m_Y = theX * inMatrix.Get(0, 1) + theY * inMatrix.Get(1, 1) + theZ * inMatrix.Get(2, 1); + m_Z = theX * inMatrix.Get(0, 2) + theY * inMatrix.Get(1, 2) + theZ * inMatrix.Get(2, 2); + + m_X += inMatrix.Get(3, 0); + m_Y += inMatrix.Get(3, 1); + m_Z += inMatrix.Get(3, 2); + + return *this; +} + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/Qt3DSVector3.h b/src/Runtime/Source/system/Qt3DSVector3.h new file mode 100644 index 00000000..08df028b --- /dev/null +++ b/src/Runtime/Source/system/Qt3DSVector3.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#ifdef WIN32 +#pragma warning(disable : 4201) +#endif + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class RuntimeMatrix; + +//============================================================================== +/** + * 3D vector with automatic notification on change. + * + * This implementation of a 3D vector along with all the sibling and helper + * classes in the geometry section, try to strike a balance between clean code, + * ease-of-use and speed. Fields are public and most methods are designed to + * give the impression of a very intelligent and capable structure. Heavier + * code such as intersections is encouraged to be added externally instead + * of here. + * + * The vector is a member of the geometry classes next to CMatrix and CRotation + * @see CMatrix + * @see CRotation + */ +class RuntimeVector3 +{ + //============================================================================== + // Fields + //============================================================================== +public: + union { + float m[3]; + struct + { + float m_X; + float m_Y; + float m_Z; + }; + }; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + RuntimeVector3(); + RuntimeVector3(const float inVector[3]); + RuntimeVector3(const float inX, const float inY, const float inZ); + RuntimeVector3(const RuntimeVector3 &inVector); + +public: // Initialization + RuntimeVector3 &Set(const float inX, const float inY, const float inZ); + RuntimeVector3 &Set(const RuntimeVector3 &inVector); + +public: // Functions + float DistanceSquared(const RuntimeVector3 &inVector) const; + float Distance(const RuntimeVector3 &inVector) const; + float LengthSquared() const; + float Length() const; + float DotProduct(const RuntimeVector3 &inVector) const; + RuntimeVector3 &CrossProduct(const RuntimeVector3 &inVector); + RuntimeVector3 &Normalize(); + RuntimeVector3 &Minimize(const RuntimeVector3 &inVector); + RuntimeVector3 &Maximize(const RuntimeVector3 &inVector); + RuntimeVector3 &InterpolateLinear(const RuntimeVector3 &inDestVector, float inFactor); + RuntimeVector3 &Transform(const RuntimeMatrix &inMatrix); + +public: // Operators + bool operator==(const RuntimeVector3 &inVector) const; + bool operator!=(const RuntimeVector3 &inVector) const; + RuntimeVector3 operator+(const RuntimeVector3 &inVector) const; + RuntimeVector3 operator-(const RuntimeVector3 &inVector) const; + RuntimeVector3 operator*(float inFactor) const; + RuntimeVector3 &operator=(const RuntimeVector3 &inVector); + RuntimeVector3 &operator+=(const RuntimeVector3 &inVector); + RuntimeVector3 &operator-=(const RuntimeVector3 &inVector); + RuntimeVector3 &operator*=(float inFactor); + RuntimeVector3 operator-() const; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/system/SystemPrefix.h b/src/Runtime/Source/system/SystemPrefix.h new file mode 100644 index 00000000..aa1ba185 --- /dev/null +++ b/src/Runtime/Source/system/SystemPrefix.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#ifdef _WIN32 +//============================================================================== +// DEFINES +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +//============================================================================== +// DISABLED WARNINGS +// +// Note that most of these warnings are tuned off by default by the compiler +// even at warning level 4. Using option /Wall turns on all warnings and makes +// even standard Microsoft include files cry. We had to turn off these or +// turn off warnings individually for each standard include file which was +// too much work. Point is that /Wall is like Warning Level 5 and this brings +// it down to about Warning level 4.5, still way above /W4. +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +#pragma warning(disable : 4511) // copy constructor could not be generated +#pragma warning(disable : 4512) // assignment operator could not be generated +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#pragma warning(disable : 4619) // #pragma warning : there is no warning number '4619' (in string.h) +#pragma warning(disable : 4625) // copy constructor could not be generated because a base class copy + // constructor is inaccessible +#pragma warning(disable : 4626) // assignment operator could not be generated because a base class + // assignment operator is inaccessible +#pragma warning(disable : 4826) // Conversion from 'const void *' to 'void *' is sign-extended +#pragma warning(disable : 4996) // _snprintf' was declared deprecated +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning(disable : 4710) // function not inlined +#pragma warning(disable : 4355) // 'this' : used in base member initializer list + +#pragma warning(disable : 4640) // construction of local static object is not thread-safe +#pragma warning(disable : 4127) // conditional expression is constant +#pragma warning( \ + disable : 4738) // storing 32-bit float result in memory, possible loss of performance +#endif //_WIN32 + +//============================================================================== +// STD INCLUDES - Standard includes MUST come first +#include // Standard functions +#include // File and IO +#ifndef _INTEGRITYPLATFORM +#include // memset, memcpy +#endif +#include // strlen +#include // Bezier math - pow, acos, cos, sqrt +#include // _tolower + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +#include +#endif + +//============================================================================== +// OUR INCLUDES +#include "Qt3DSTypes.h" +#include "Qt3DSPlatformSpecific.h" +#include "Qt3DSAssert.h" +#include "Qt3DSMacros.h" +#include "Qt3DSConfig.h" +#include "Qt3DSMemorySettings.h" +#include "Qt3DSMemory.h" +#include "Qt3DSArray.h" diff --git a/src/Runtime/Source/uipparser/Qt3DSIPresentation.h b/src/Runtime/Source/uipparser/Qt3DSIPresentation.h new file mode 100644 index 00000000..00f3d15a --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSIPresentation.h @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSEventCallbacks.h" + +namespace qt3ds { +namespace runtime { + class IApplication; + class IActivityZone; + class IAnimationSystem; + class ISlideSystem; + class ILogicSystem; + class IParametersSystem; +} +} + +namespace qt3ds { +namespace foundation { + class IStringTable; +} +} + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class IComponentManager; +class IEventManager; +class IScene; +class IScriptBridge; +class CPresentationFrameData; +class CTimePolicy; +using qt3ds::runtime::ISlideSystem; +using qt3ds::runtime::IAnimationSystem; +using qt3ds::runtime::ILogicSystem; +using qt3ds::runtime::IParametersSystem; + +//============================================================================== +// Enumeration +//============================================================================== +/// Method used to translate from presentation size to window size +enum EScaleMode { + SCALEMODE_FREE, ///< Free scaling mode + SCALEMODE_EXACT, ///< Fixed presentation size + SCALEMODE_ASPECT, ///< Maintain aspect ratio + SCALEMODE_UNKNOWN, ///< ERROR! - Uninitialized scale mode +}; + +//============================================================================== +// Structs +//============================================================================== +struct SPresentationSize +{ + SPresentationSize() + : m_Width(0) + , m_Height(0) + , m_ScaleMode(0) + { + } + UINT16 m_Width; ///< Native width of the presentation + UINT16 m_Height; ///< Native height of the presentation + UINT8 m_ScaleMode; ///< Presentation to window scale method + UINT8 m_Padding[3]; +}; + +//============================================================================== +/** + * @interface IPresentation + * Base interface of the presentation. + */ +class IPresentation +{ + //============================================================================== + // Methods + //============================================================================== +public: // Construction + IPresentation() {} + virtual ~IPresentation() {} + +public: // Execution + virtual void ClearDirtyList() = 0; + virtual void PreUpdate(const TTimeUnit inGlobalTime) = 0; + virtual void BeginUpdate() = 0; + virtual void EndUpdate() = 0; + virtual void PostUpdate(const TTimeUnit inGlobalTime) = 0; + +public: // Bridge Control + virtual void SetScene(IScene *inScene) = 0; + virtual IScene *GetScene() const = 0; + virtual IScriptBridge *GetScriptBridgeQml() = 0; + +public: // Commands and Events + virtual void FireEvent(const TEventCommandHash inEventType, TElement *inTarget, + const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, + const EAttributeType inType1 = ATTRIBUTETYPE_NONE, + const EAttributeType inType2 = ATTRIBUTETYPE_NONE) = 0; + virtual void FireCommand(const TEventCommandHash inEventType, TElement *inTarget, + const UVariant *inArg1 = NULL, const UVariant *inArg2 = NULL, + const EAttributeType inType1 = ATTRIBUTETYPE_NONE, + const EAttributeType inType2 = ATTRIBUTETYPE_NONE) = 0; + virtual void FlushEventCommandQueue(void) = 0; + virtual void ProcessEvent(SEventCommand &) = 0; + +public: // Manager Access + virtual IComponentManager &GetComponentManager() = 0; + virtual ISlideSystem &GetSlideSystem() = 0; + virtual IAnimationSystem &GetAnimationSystem() = 0; + virtual ILogicSystem &GetLogicSystem() = 0; + virtual IParametersSystem &GetParametersSystem() = 0; + + virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; + virtual qt3ds::runtime::IApplication &GetApplication() = 0; + virtual qt3ds::runtime::IActivityZone *GetActivityZone() = 0; + +public: // Hooks and callbacks + virtual void OnPresentationLoaded() = 0; + +public: // Full file path + virtual void SetFilePath(const CHAR *inPath) = 0; + virtual QString GetFilePath() = 0; + virtual TElement *GetRoot() = 0; + virtual void SetRoot(TElement &inRoot) = 0; + +public: // Configuration access + virtual SPresentationSize GetSize() const = 0; + virtual void SetSize(const SPresentationSize &inSize) = 0; + virtual void SetElementPath(TElement &inElement, const char8_t *inPath) = 0; + virtual qt3ds::foundation::CRegisteredString GetElementPath(TElement &inElement) = 0; + +public: // Event Callbacks + virtual void RegisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) = 0; + virtual BOOL UnregisterEventCallback(TElement *inElement, const TEventCommandHash inEventHash, + const TEventCallback inCallback, void *inContextData) = 0; + +public: // FrameData access + virtual CPresentationFrameData &GetFrameData() = 0; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParser.h b/src/Runtime/Source/uipparser/Qt3DSUIPParser.h new file mode 100644 index 00000000..1c31d457 --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParser.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "foundation/StringTable.h" +#include + +namespace qt3ds { +namespace state { + struct SSetAttribute; + namespace debugger { + class ISceneGraphRuntimeDebugger; + } +} +} + +namespace qt3ds { +namespace render { + class IInputStreamFactory; +} +} + +//============================================================================== +// Forwards +//============================================================================== +namespace qt3dsdm { +class IDOMReader; +class IStringTable; +} + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { +using namespace qt3ds::foundation; +//============================================================================== +// Forwards +//============================================================================== +class IRuntimeMetaData; +class IPresentation; + +struct UIPElementTypes +{ + enum Enum { + Unknown = 0, + Scene = 1, + Node, + Layer, + Component, + Group, + Behavior, + Model, + Light, + Camera, + Image, + Material, + Text, + Effect, + RenderPlugin, + CustomMaterial, + ReferencedMaterial, + Path, + PathAnchorPoint, + PathSubPath, + }; +}; + +struct SElementAndType +{ + UIPElementTypes::Enum m_Type; + TElement *m_Element; + SElementAndType(UIPElementTypes::Enum inType, TElement *elem) + : m_Type(inType) + , m_Element(elem) + { + } +}; + +// Ensure these elements exist and if the attribute isn't empty ensure the attribute is referenced. +struct SElementAttributeReference +{ + eastl::string m_Path; + eastl::string m_Attribute; + SElementAttributeReference(const eastl::string &p, const eastl::string &a) + : m_Path(p) + , m_Attribute(a) + { + } +}; +//============================================================================== +/** + * @class CUIPParser + * @brief Class for parsing UIP file + */ + +class IUIPParser : public NVReleasable +{ +protected: + virtual ~IUIPParser() {} +public: // Parse UIP file + virtual BOOL Load(IPresentation &inPresentation, + NVConstDataRef inStateReferences, + qt3ds::state::debugger::ISceneGraphRuntimeDebugger &inDebugger) = 0; + virtual qt3dsdm::IDOMReader &GetDOMReader() = 0; + virtual IRuntimeMetaData &GetMetaData() = 0; + // Mapping back from file id to element id, needed to hook elements up to their respective + // parsed + // counterparts. + virtual SElementAndType GetElementForID(const char *inStringId) = 0; + virtual eastl::string ResolveReference(const char *inStringId, const char *inReferance) = 0; + // The rendering system needs to know every sourcepath found during parse of the UIP file + // so that it can do things like register images as opaque/transparent as well as preload + // mesh files (and possibly font files). + virtual NVConstDataRef GetSourcePaths() const = 0; + + // Creation function + static IUIPParser &Create(const QString &inFileName, IRuntimeMetaData &inMetaData, + qt3ds::render::IInputStreamFactory &inStreamFactory, + qt3ds::foundation::IStringTable &inStrTable); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.cpp b/src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.cpp new file mode 100644 index 00000000..ab6d751d --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.cpp @@ -0,0 +1,738 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" +#ifdef EA_PLATFORM_WINDOWS +#pragma warning(disable : 4396) // specializer warning nonsense +#endif + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSUIPParserActionHelper.h" +#include "Qt3DSUIPParserObjectRefHelper.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSCommandEventTypes.h" + +#include "Qt3DSDMPrefix.h" +#include "Qt3DSDMXML.h" +#include "Qt3DSDMWStrOpsImpl.h" +#include "Qt3DSMetadata.h" +#include "Qt3DSEulerAngles.h" +#include "Qt3DSLogicSystem.h" +#include "Qt3DSParametersSystem.h" + +using namespace qt3dsdm; + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * Constructor + */ +CUIPParserActionHelper::CUIPParserActionHelper(CUIPParserImpl *inUIPParser, + CUIPParserObjectRefHelper *inObjRefHelper, + IRuntimeMetaData &inMetaData) + : m_UIPParser(inUIPParser) + , m_ObjRefHelper(inObjRefHelper) + , m_MetaData(inMetaData) +{ +} + +//============================================================================== +/** + * Destructor + */ +CUIPParserActionHelper::~CUIPParserActionHelper() +{ +} + +void CUIPParserActionHelper::CacheAction(qt3dsdm::IDOMReader &inReader, + const char8_t *inActionOwnerId) +{ + if (IsTrivial(inActionOwnerId)) + return; + + IDOMReader::Scope __childScope(inReader); + + const char *theRef; + if (inReader.Att("ref", theRef)) { + // Ignore "ref" because we are only interested in new actions + return; + } + + // Parse the action + SActionInfo theAction; + inReader.Att("id", theAction.m_Id); + theAction.m_Owner = inActionOwnerId; + + const char *tempStr; + if (inReader.Att("triggerObject", tempStr)) + theAction.m_TriggerObject = m_UIPParser->ParseObjectRefId(tempStr, inActionOwnerId); + inReader.Att("event", theAction.m_Event); + if (inReader.Att("targetObject", tempStr)) + theAction.m_TargetObject = m_UIPParser->ParseObjectRefId(tempStr, inActionOwnerId); + if (inReader.Att("handler", tempStr)) { + theAction.m_Handler = tempStr; + CacheHandlerArguments(inReader, theAction); + } + + // Only proceeds if we can find the elements + if (theAction.m_TargetObject.empty() || theAction.m_TriggerObject.empty() + || theAction.m_Owner.empty()) { + qCWarning(qt3ds::INVALID_OPERATION) << "Action invalid, id: " << theAction.m_Id.c_str(); + return; + } + + m_ActionMap[theAction.m_Id] = theAction; + + // Build up logic tables to be processed by BuildAction later + // There are 2 tables involved: + // 1. The Listener-To-Events tables - multimap of each listener to all events it is listening to + // 2. The Listener-Event-To-Actions table - multimap of each listener-event pair to all actions + // it triggers + // note: The struct for Action is a pair of EventAction node and its owner + AddListenerEventPair(theAction.m_TriggerObject, theAction.m_Event); + + SListenerEventNamePair theListenerEventPair(theAction.m_TriggerObject, theAction.m_Event); + TEventActionOwnerPair theLogicOwnerPair(theAction.m_Id, theAction.m_Owner); + m_ListenerEventActionsMap.insert(eastl::make_pair(theListenerEventPair, theLogicOwnerPair)); +} + +void CUIPParserActionHelper::AddListenerEventPair(eastl::string inListener, + const eastl::string &inEventName) +{ + // Check for dupes + TListenerEventsNameMap::iterator theStartItr = m_ListenerEventsNameMap.lower_bound(inListener); + TListenerEventsNameMap::iterator theEndItr = m_ListenerEventsNameMap.upper_bound(inListener); + for (; theStartItr != theEndItr; ++theStartItr) { + if (theStartItr->second == inEventName) + return; + } + + m_ListenerEventsNameMap.insert(eastl::make_pair(inListener, inEventName)); +} + +void CUIPParserActionHelper::CacheHandlerArguments(qt3dsdm::IDOMReader &inReader, + SActionInfo &inAction) +{ + IDOMReader::Scope __handlerArgScope(inReader); + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + SHandlerArgumentInfo theArg; + inReader.Att("name", theArg.m_Name); + inReader.Att("value", theArg.m_Value); + inAction.m_HandlerArgs.push_back(theArg); + } + if (inAction.m_Handler == "Set Property") { + SHandlerArgumentInfo theHandlerArg1 = inAction.m_HandlerArgs[0]; + SElementData *targetData = m_UIPParser->GetElementData(inAction.m_TargetObject.c_str()); + if (targetData && !theHandlerArg1.m_Value.empty()) { + m_UIPParser->m_ParseElementManager.MarkAttributeAsReferenced( + *targetData, theHandlerArg1.m_Value.c_str()); + } + } +} + +SElement *CUIPParserActionHelper::GetElement(const eastl::string &inElementName) +{ + return m_UIPParser->GetElement(inElementName.c_str()); +} + +void CUIPParserActionHelper::GetActionSectionCount( + CUIPParserImpl::SActionSectionCount &outActionCount) +{ + // There are 2 tables involved: + // 1. The Listener-To-Events tables - multimap of each listener to all events it is listening to + // 2. The Listener-Event-To-Actions table - multimap of each listener-event pair to all actions + // it triggers + // note: The struct for Action is a pair of EventAction node and its owner + + // Get the count to reserve + // Iterate through each listener + for (TListenerEventsNameMap::iterator theListenerItr = m_ListenerEventsNameMap.begin(); + theListenerItr != m_ListenerEventsNameMap.end();) { + ++outActionCount.m_TriggerElementCount; + + INT32 theEventCount = + static_cast(m_ListenerEventsNameMap.count(theListenerItr->first)); + for (INT32 theEventCounter = 0; theEventCounter < theEventCount; + ++theEventCounter, ++theListenerItr) { + ++outActionCount.m_TriggerEventCount; + + // iterate through each listener-event pair + SListenerEventNamePair thePair(theListenerItr->first, theListenerItr->second); + TListenerEventActionsMap::iterator theActionsItr = + m_ListenerEventActionsMap.lower_bound(thePair); + INT32 theActionCount = static_cast(m_ListenerEventActionsMap.count(thePair)); + for (INT32 theActionCounter = 0; theActionCounter < theActionCount; + ++theActionCounter) { + eastl::string theActionId = theActionsItr->second.first; + outActionCount.m_ActionCount += + GetActionCount(theActionId, outActionCount.m_StringAttrCount, + outActionCount.m_CustomParamCount); + ++theActionsItr; + } + } + } +} + +void CUIPParserActionHelper::BuildActions(IPresentation &inPresentation) +{ + // Now we start building + // Iterate through each listener + for (TListenerEventsNameMap::iterator theListenerItr = m_ListenerEventsNameMap.begin(); + theListenerItr != m_ListenerEventsNameMap.end();) { + TElement *theElement = GetElement(theListenerItr->first); + + INT32 theEventCount = + static_cast(m_ListenerEventsNameMap.count(theListenerItr->first)); + for (INT32 theEventCounter = 0; theEventCounter < theEventCount; + ++theEventCounter, ++theListenerItr) { + UINT32 theEventName = + CHash::HashEventCommand(theListenerItr->second.c_str()); // UINT32: HashedName + + // iterate through each listener-event pair + SListenerEventNamePair thePair(theListenerItr->first, theListenerItr->second); + TListenerEventActionsMap::iterator theActionsItr = + m_ListenerEventActionsMap.lower_bound(thePair); + INT32 theActionCount = static_cast(m_ListenerEventActionsMap.count(thePair)); + for (INT32 theActionCounter = 0; theActionCounter < theActionCount; + ++theActionCounter) { + eastl::string theActionId = theActionsItr->second.first; + if (theElement) + BuildAction(*theElement, theEventName, inPresentation, theActionId); + ++theActionsItr; + } + } + } +} + +union UTypeConverter { + SAttributeKey m_Key; + INT32 m_IntData; +}; + +struct SActionAdder +{ + ILogicSystem &m_LogicSystem; + TElement &m_EventElement; + UINT32 m_EventName; + TElement *m_Owner; + TElement *m_Target; + + SActionAdder(ILogicSystem &inLogicSystem, TElement &inEventElement, UINT32 inEventName, + TElement *inOwner, TElement *inTarget) + : m_LogicSystem(inLogicSystem) + , m_EventElement(inEventElement) + , m_EventName(inEventName) + , m_Owner(inOwner) + , m_Target(inTarget) + { + } + + INT32 AddAction(TEventCommandHash inCommand, UINT32 inArg1 = 0, UINT32 inArg2 = 0) + { + UVariant arg1Var; + UVariant arg2Var; + arg1Var.m_INT32 = (INT32)inArg1; + arg2Var.m_INT32 = (INT32)inArg2; + return m_LogicSystem.AddAction(m_EventElement, m_EventName, m_Target, m_Owner, inCommand, + arg1Var, arg2Var, true); + } +}; + +void CUIPParserActionHelper::BuildAction(TElement &inElement, UINT32 inEventName, + IPresentation &inPresentation, + const eastl::string &inActionId) +{ + ILogicSystem &theLogicBuilder = inPresentation.GetLogicSystem(); + IParametersSystem &theParamSystem = inPresentation.GetParametersSystem(); + TActionMap::iterator theIter = m_ActionMap.find(inActionId); + if (theIter == m_ActionMap.end()) { + Q3DStudio_ASSERT(false); + qCWarning(qt3ds::INVALID_OPERATION) << "Can't find action, id: " << inActionId.c_str(); + return; + } + + SActionInfo theAction = theIter->second; + INT32 theAddActionIndex = -1; // the index of newly added action. If there are more than 1 + // actions, the index points to the firstly added action. + SActionAdder theAdder(theLogicBuilder, inElement, inEventName, GetElement(theAction.m_Owner), + GetElement(theAction.m_TargetObject)); + + // The list of applicable handler is loaded from metadata xml file (if it is non-custom handler) + bool theIsCustomHandler = IsCustomHandler(theAction); + + if (theIsCustomHandler) { + // Argument 1 - param table start index + INT32 paramGroup = theParamSystem.CreateParameterGroup(); + + // First param is the handler name we want to invoke for the custom action. + ExportCustomActionParameters(inPresentation, theParamSystem, paramGroup, + theAction.m_Handler.c_str(), ERuntimeDataModelDataTypeString, + ERuntimeAdditionalMetaDataTypeNone); + + int theHandlerArgumentCount = theAction.m_HandlerArgs.size(); + ERuntimeDataModelDataType theType; + ERuntimeAdditionalMetaDataType theAdditionalType; + // Actual handler parameters to pass in. + for (int theIndex = 0; theIndex < theHandlerArgumentCount; ++theIndex) { + GetHandlerArgumentType(theAction, theIndex, theType, theAdditionalType); + ExportCustomActionParameters(inPresentation, theParamSystem, paramGroup, + theAction.m_HandlerArgs[theIndex].m_Value.c_str(), theType, + theAdditionalType); + } + theAddActionIndex = theAdder.AddAction(COMMAND_CUSTOMACTION, (UINT32)paramGroup); + } else if (theAction.m_Handler == "Set Property") // Plain set action + { + // ArgumentOne - HashPropertyName + // ArgumentTwo - Value + SHandlerArgumentInfo theHandlerArg1 = theAction.m_HandlerArgs[0]; + SHandlerArgumentInfo theHandlerArg2 = theAction.m_HandlerArgs[1]; + + eastl::string thePropertyName = theHandlerArg1.m_Value; + SElementData *theTargetObject = + m_UIPParser->GetElementData(theAction.m_TargetObject.c_str()); + if (theTargetObject) { + SElementPropertyInfo *theProperty = m_UIPParser->m_ParseElementManager.FindProperty( + *theTargetObject, thePropertyName.c_str()); + if (theProperty) { + TPropertyDescAndValueList theProperties; + ERuntimeDataModelDataType theType = theProperty->m_DataType; + ERuntimeAdditionalMetaDataType theAdditionalType = theProperty->m_AdditionalType; + + m_UIPParser->GetAttributeList(inPresentation, theProperties, theType, + theAdditionalType, thePropertyName.c_str(), + theHandlerArg2.m_Value.c_str(), + theProperty->m_PropertyNames); + + UINT32 theActionCount = theProperties.size(); + Q3DStudio_ASSERT(theActionCount > 0); + for (UINT32 theActionIndex = 0; theActionIndex < theActionCount; ++theActionIndex) { + INT32 actionId = theAdder.AddAction( + COMMAND_SETPROPERTY, theProperties[theActionIndex].first.GetNameHash(), + theProperties[theActionIndex].second.m_INT32); + if (theActionIndex == 0) + theAddActionIndex = actionId; + } + } + } + } else if (theAction.m_Handler == "Fire Event") // Fire the selected event on the element + { + theAddActionIndex = theAdder.AddAction( + COMMAND_FIREEVENT, CHash::HashEventCommand(theAction.m_HandlerArgs[0].m_Value.c_str())); + } else if (theAction.m_Handler == "Go to Slide") // Switch slides + { + theAddActionIndex = theAdder.AddAction( + COMMAND_GOTOSLIDENAME, CHash::HashString(theAction.m_HandlerArgs[0].m_Value.c_str())); + } else if (theAction.m_Handler == "Next Slide") // Switch slides + { + theAddActionIndex = theAdder.AddAction(COMMAND_GOTONEXTSLIDE); + } else if (theAction.m_Handler == "Previous Slide") // Switch slides + { + theAddActionIndex = theAdder.AddAction(COMMAND_GOTOPREVIOUSSLIDE); + } else if (theAction.m_Handler == "Preceding Slide") // Switch slides + { + theAddActionIndex = theAdder.AddAction(COMMAND_BACKSLIDE); + } else if (theAction.m_Handler == "Play") // Play + { + theAddActionIndex = theAdder.AddAction(COMMAND_PLAY); + } else if (theAction.m_Handler == "Pause") // Pause + { + theAddActionIndex = theAdder.AddAction(COMMAND_PAUSE); + } else if (theAction.m_Handler == "Go to Time") // Goto Time + { + float theTime = 0; + const char *theValue = theAction.m_HandlerArgs[0].m_Value.c_str(); + if (!IsTrivial(theValue)) + WStrOps().StrTo(theValue, theTime); + + theAddActionIndex = + theAdder.AddAction(COMMAND_GOTOTIME, static_cast(theTime * 1000.0f)); + + bool thePause = false; + theValue = theAction.m_HandlerArgs[1].m_Value.c_str(); + if (!IsTrivial(theValue)) + WStrOps().StrTo(theValue, thePause); + theAdder.AddAction(thePause ? COMMAND_PAUSE : COMMAND_PLAY); + } else if (theAction.m_Handler == "Emit Signal") // Emit a signal + { + qt3ds::foundation::CStringHandle theStringHandle; + if (!theAction.m_HandlerArgs[0].m_Value.empty()) { + const char *theValue = theAction.m_HandlerArgs[0].m_Value.c_str(); + theStringHandle = inPresentation.GetStringTable().GetHandle(theValue); + } + theAddActionIndex = theAdder.AddAction(COMMAND_EMITSIGNAL, theStringHandle.handle()); + } else { + Q3DStudio_ASSERT(false); // what sort of crazy action is this? + } + + if (theAddActionIndex > -1) + m_ActionIdentifierMap[theAction.m_Id] = theAddActionIndex; +} + +INT32 CUIPParserActionHelper::GetActionCount(const eastl::string &inActionId) +{ + INT32 theStringAttrCount = 0; + INT32 theCustomParamCount = 0; + return GetActionCount(inActionId, theStringAttrCount, theCustomParamCount); +} + +INT32 CUIPParserActionHelper::GetActionCount(const eastl::string &inActionId, + INT32 &outStringAttrCount, INT32 &outCustomParamCount) +{ + INT32 theActionCount = 0; + + TActionMap::iterator theIter = m_ActionMap.find(inActionId); + if (theIter == m_ActionMap.end()) { + Q3DStudio_ASSERT(false); + qCWarning(qt3ds::INVALID_OPERATION) << "Can't find action, id: " << inActionId.c_str(); + return theActionCount; + } + + SActionInfo theAction = theIter->second; + + // The list of applicable handler is loaded from metadata xml file (if it is non-custom handler) + bool theIsCustomHandler = IsCustomHandler(theAction); + + if (theIsCustomHandler) { + theActionCount = 1; + + // First param is the handler name we want to invoke for the custom action. + ++outStringAttrCount; + ++outCustomParamCount; + + int theHandlerArgumentCount = theAction.m_HandlerArgs.size(); + ERuntimeDataModelDataType theType; + ERuntimeAdditionalMetaDataType theAdditionalType; + // Actual handler parameters to pass in. + for (int theIndex = 0; theIndex < theHandlerArgumentCount; ++theIndex) { + GetHandlerArgumentType(theAction, theIndex, theType, theAdditionalType); + GetCustomActionParametersCount(theType, theAdditionalType, outStringAttrCount, + outCustomParamCount); + } + } + + else if (theAction.m_Handler == "Set Property") // Plain set action + { + SHandlerArgumentInfo theHandlerArg1 = theAction.m_HandlerArgs[0]; + + eastl::string thePropertyName = theHandlerArg1.m_Value; + SElementData *theData = m_UIPParser->GetElementData(theAction.m_TargetObject.c_str()); + if (theData) { + SElementPropertyInfo *thePropertyInfo = + m_UIPParser->m_ParseElementManager.GetOrCreateProperty(*theData, + thePropertyName.c_str()); + if (thePropertyInfo) { + theActionCount = thePropertyInfo->m_Arity; + if (m_UIPParser->IsStringType(thePropertyInfo->m_DataType)) + ++outStringAttrCount; + } + } + } + + else if (theAction.m_Handler == "Fire Event" // Fire the selected event on the element + || theAction.m_Handler == "Go to Slide" // Switch slides + || theAction.m_Handler == "Next Slide" // Switch slides + || theAction.m_Handler == "Previous Slide" // Switch slides + || theAction.m_Handler == "Preceding Slide" // Switch slides + || theAction.m_Handler == "Play" // Play + || theAction.m_Handler == "Pause" // Pause + ) { + theActionCount = 1; + } + + else if (theAction.m_Handler == "Go to Time") // Goto Time + { + theActionCount = 2; + } else if (theAction.m_Handler == "Play Sound") // Play Sound + { + theActionCount = 1; + ++outStringAttrCount; + } else if (theAction.m_Handler == "Emit Signal") // Emit Signal + { + theActionCount = 1; + ++outStringAttrCount; + } else { + Q3DStudio_ASSERT(false); // what sort of crazy action is this? + } + + return theActionCount; +} + +INT32 CUIPParserActionHelper::GetActionIndex(const eastl::string &inActionId) +{ + TActionIdentifierMap::iterator theFind = m_ActionIdentifierMap.find(inActionId); + if (theFind != m_ActionIdentifierMap.end()) + return theFind->second; + Q3DStudio_ASSERT(false); + return -1; +} + +bool CUIPParserActionHelper::IsCustomHandler(const SActionInfo &inAction) +{ + const char *theClass = m_ObjRefHelper->GetClass(inAction.m_TargetObject); + if (!IsTrivial(theClass)) + return m_MetaData.IsCustomHandler(theClass, inAction.m_Handler.c_str()); + return false; +} + +void CUIPParserActionHelper::GetHandlerArgumentType( + const SActionInfo &inAction, int inArgumentIndex, ERuntimeDataModelDataType &outType, + ERuntimeAdditionalMetaDataType &outAdditionalType) +{ + const char *theClass = m_ObjRefHelper->GetClass(inAction.m_TargetObject); + return m_MetaData.GetHandlerArgumentType(theClass, inAction.m_Handler.c_str(), + inAction.m_HandlerArgs[inArgumentIndex].m_Name.c_str(), + outType, outAdditionalType); +} + +void CUIPParserActionHelper::GetCustomActionParametersCount( + ERuntimeDataModelDataType inDataType, ERuntimeAdditionalMetaDataType inAdditionalType, + INT32 &outStringAttrCount, INT32 &outCustomParamCount) +{ + // This function should match ExportCustomActionParameters + switch (inDataType) { + case ERuntimeDataModelDataTypeFloat: + case ERuntimeDataModelDataTypeLong: + case ERuntimeDataModelDataTypeBool: { + outCustomParamCount += 1; + break; + } + case ERuntimeDataModelDataTypeFloat2: { + outCustomParamCount += 2; + break; + } + case ERuntimeDataModelDataTypeFloat3: { + if (inAdditionalType == ERuntimeAdditionalMetaDataTypeColor) { + // Append rgba + outCustomParamCount += 4; + } else { + // Append xyz + outCustomParamCount += 3; + } + break; + } + // default to string + default: { + outCustomParamCount += 1; + outStringAttrCount += 1; + } + } +} + +namespace { + + using qt3ds::foundation::IStringTable; + + struct SCustomParameterParseInfoFloat + { + typedef float TParseType; + static const char8_t *Name() { return "float"; } + static TParseType Default() { return 0; } + static Q3DStudio::UVariant ToVariant(const TParseType &inParseType) + { + Q3DStudio::UVariant retval; + retval.m_FLOAT = inParseType; + return retval; + } + }; + + struct SCustomParameterParseInfoLong + { + typedef QT3DSI32 TParseType; + static const char8_t *Name() { return "long"; } + static TParseType Default() { return 0; } + static Q3DStudio::UVariant ToVariant(const TParseType &inParseType) + { + Q3DStudio::UVariant retval; + retval.m_FLOAT = static_cast(inParseType); + return retval; + } + }; + + struct SCustomParameterParseInfoBool + { + typedef bool TParseType; + static const char8_t *Name() { return "bool"; } + static TParseType Default() { return false; } + static Q3DStudio::UVariant ToVariant(const TParseType &inParseType) + { + Q3DStudio::UVariant retval; + retval.m_FLOAT = static_cast(inParseType); + return retval; + } + }; + + struct SCustomParameterParseInfoFloat2 + { + typedef SFloat2 TParseType; + static const char8_t *Name() { return "float2"; } + static TParseType Default() { return SFloat2(0, 0); } + static QT3DSU32 NumParameters() { return 2; } + static Q3DStudio::UVariant ToVariant(QT3DSU32 inIdx, const TParseType &inParseType) + { + Q3DStudio::UVariant retval; + retval.m_FLOAT = static_cast(inParseType[inIdx]); + return retval; + } + }; + + struct SCustomParameterParseInfoFloat3 + { + typedef SFloat3 TParseType; + static const char8_t *Name() { return "float3"; } + static const char8_t **Extensions() + { + static const char8_t *retval[] = { ".x", ".y", ".z", NULL }; + return retval; + } + static TParseType Default() { return SFloat3(0, 0, 0); } + static QT3DSU32 NumParameters() { return 3; } + static Q3DStudio::UVariant ToVariant(QT3DSU32 inIdx, const TParseType &inParseType) + { + Q3DStudio::UVariant retval; + retval.m_FLOAT = static_cast(inParseType[inIdx]); + return retval; + } + }; + + struct SCustomParameterParseInfoColor + { + typedef SFloat3 TParseType; + static const char8_t *Name() { return "color4"; } + static TParseType Default() { return SFloat3(0, 0, 0); } + static QT3DSU32 NumParameters() { return 4; } + static Q3DStudio::UVariant ToVariant(QT3DSU32 inIdx, const TParseType &inParseType) + { + if (inIdx < 3) { + Q3DStudio::UVariant retval; + retval.m_FLOAT = static_cast(inParseType[inIdx]) * 255.0f; + return retval; + } else { + Q3DStudio::UVariant retval; + retval.m_FLOAT = 255.0f; + return retval; + } + } + }; + + template + struct ParseParameter + { + void operator()(WCharTReader &inReader, const char *inValue, IParametersSystem &inSystem, + QT3DSI32 inGroupId) + { + typename TParseInfo::TParseType theValue = TParseInfo::Default(); + if (!IsTrivial(inValue)) + inReader.Read(theValue); + Q3DStudio::UVariant theVarValue = TParseInfo::ToVariant(theValue); + inSystem.AddParameter(inGroupId, CHash::HashString(TParseInfo::Name()), theVarValue); + } + }; + + template + struct ParseAggregateParameter + { + void operator()(WCharTReader &inReader, const char *inValue, IParametersSystem &inSystem, + QT3DSI32 inGroupId) + { + typename TParseInfo::TParseType theValue = TParseInfo::Default(); + if (!IsTrivial(inValue)) + inReader.ReadRef(NVDataRef(&theValue[0], TParseInfo::NumParameters())); + + for (QT3DSU32 idx = 0, end = TParseInfo::NumParameters(); idx < end; ++idx) { + Q3DStudio::UVariant theVarValue = TParseInfo::ToVariant(idx, theValue); + inSystem.AddParameter(inGroupId, CHash::HashString(TParseInfo::Name()), + theVarValue); + } + } + }; +} + +void CUIPParserActionHelper::ExportCustomActionParameters( + IPresentation &inPresentation, IParametersSystem &inParamSystem, QT3DSI32 inParamGroupId, + const char *inValue, ERuntimeDataModelDataType inDataType, + ERuntimeAdditionalMetaDataType inAdditionalType) +{ + // Create a destructible value + m_UIPParser->m_ValueBuffer.clear(); + m_UIPParser->m_ValueBuffer.write(inValue, (QT3DSU32)strlen(inValue) + 1); + // Clear the destination buffer + m_UIPParser->m_TempBuffer.clear(); + WCharTReader theReader((char8_t *)m_UIPParser->m_ValueBuffer.begin(), m_UIPParser->m_TempBuffer, + *m_UIPParser->GetDOMReader().GetStringTable()); + + // The function should match CUIPParserActionHelper::GetCustomActionParametersCount + switch (inDataType) { + case ERuntimeDataModelDataTypeFloat: { + ParseParameter()(theReader, inValue, inParamSystem, + inParamGroupId); + break; + } + case ERuntimeDataModelDataTypeLong: { + ParseParameter()(theReader, inValue, inParamSystem, + inParamGroupId); + break; + } + case ERuntimeDataModelDataTypeBool: { + ParseParameter()(theReader, inValue, inParamSystem, + inParamGroupId); + break; + } + case ERuntimeDataModelDataTypeFloat2: { + ParseAggregateParameter()(theReader, inValue, + inParamSystem, inParamGroupId); + break; + } + case ERuntimeDataModelDataTypeFloat3: { + if (inAdditionalType == ERuntimeAdditionalMetaDataTypeColor) { + ParseAggregateParameter()( + theReader, inValue, inParamSystem, inParamGroupId); + } else { + ParseAggregateParameter()( + theReader, inValue, inParamSystem, inParamGroupId); + } + break; + } + // default to string + default: { + UVariant theValue; + theValue.m_StringHandle = inPresentation.GetStringTable().GetHandle(inValue); + inParamSystem.AddParameter(inParamGroupId, CHash::HashString("string"), theValue); + break; + } + } +} +} diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.h b/src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.h new file mode 100644 index 00000000..3d9d44ce --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParserActionHelper.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSUIPParserImpl.h" + +namespace qt3ds { +namespace runtime { + class IParametersSystem; +} +} +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { +using qt3ds::runtime::IParametersSystem; +//============================================================================== +// Forwards +//============================================================================== + +//============================================================================== +/** + * @class CUIPParserActionHelper + * @brief Class for parsing UIP file - Action + */ +class CUIPParserActionHelper +{ + //============================================================================== + // Fields + //============================================================================== +protected: + CUIPParserImpl *m_UIPParser; + CUIPParserObjectRefHelper *m_ObjRefHelper; + IRuntimeMetaData &m_MetaData; ///< Reference to Metadata + + typedef eastl::map TActionIdentifierMap; ///< Mapping of the string that + ///uniquely identify the action + ///to the index created + TActionIdentifierMap m_ActionIdentifierMap; + + struct SHandlerArgumentInfo + { + eastl::string m_Name; + eastl::string m_Value; + + SHandlerArgumentInfo() {} + }; + typedef eastl::vector THandlerArguments; ///< List of handler arguments + struct SActionInfo + { + eastl::string m_Id; + + // Where the action is added to + eastl::string m_Owner; // Absolute path of owner object + + // Trigger object + eastl::string m_TriggerObject; // Absolute path of trigger object + eastl::string m_Event; + + // Target object + eastl::string m_TargetObject; // Absolute path of target object + eastl::string m_Handler; + THandlerArguments m_HandlerArgs; + + SActionInfo() {} + }; + typedef eastl::map TActionMap; ///< Map of action id and action info + + TActionMap m_ActionMap; + + // There are 2 tables involved: + // 1. The Listener-To-Events tables - multimap of each listener to all events it is listening to + // 2. The Listener-Event-To-Actions table - multimap of each listener-event pair to all actions + // it triggers + // note: The struct for Action is a pair of EventAction node and its owner + struct SListenerEventNamePair + { + eastl::string m_Listener; + eastl::string m_Event; + + SListenerEventNamePair(eastl::string inListener, const eastl::string &inEvent) + : m_Listener(inListener) + , m_Event(inEvent) + { + } + + bool operator<(const SListenerEventNamePair &inListenerEventPair) const + { + if (m_Listener == inListenerEventPair.m_Listener) + return m_Event < inListenerEventPair.m_Event; + return m_Listener < inListenerEventPair.m_Listener; + } + }; + + typedef eastl::pair + TEventActionOwnerPair; ///< One listener(source) can listen to multiple events + typedef eastl::multimap + TListenerEventsNameMap; ///< One listener(source)-event pair can trigger multiple actions + typedef eastl::multimap TListenerEventActionsMap; + + TListenerEventsNameMap m_ListenerEventsNameMap; + TListenerEventActionsMap m_ListenerEventActionsMap; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CUIPParserActionHelper(CUIPParserImpl *inUIPParser, CUIPParserObjectRefHelper *inObjRefHelper, + IRuntimeMetaData &inMetaData); + virtual ~CUIPParserActionHelper(); + +public: + void CacheAction(qt3dsdm::IDOMReader &inReader, const char8_t *inOwnerId); + void BuildActions(IPresentation &inPresentation); + void GetActionSectionCount(CUIPParserImpl::SActionSectionCount &outActionCount); + INT32 GetActionCount(const eastl::string &inActionId); + INT32 GetActionIndex(const eastl::string &inActionId); + +protected: // Action helper + void AddListenerEventPair(eastl::string inListener, const eastl::string &inEventName); + void CacheHandlerArguments(qt3dsdm::IDOMReader &inReader, SActionInfo &inAction); + void BuildAction(TElement &inElement, UINT32 inEventName, IPresentation &inPresentation, + const eastl::string &inActionId); + INT32 GetActionCount(const eastl::string &inActionId, INT32 &outStringAttrCount, + INT32 &outCustomParamCount); + bool IsCustomHandler(const SActionInfo &inAction); + void GetHandlerArgumentType(const SActionInfo &inAction, int inArgumentIndex, + ERuntimeDataModelDataType &outType, + ERuntimeAdditionalMetaDataType &outAdditionalType); + void GetCustomActionParametersCount(ERuntimeDataModelDataType inDataType, + ERuntimeAdditionalMetaDataType inAdditionalType, + INT32 &outStringAttrCount, INT32 &outCustomParamCount); + void ExportCustomActionParameters(IPresentation &inPresentation, + IParametersSystem &inParamSystem, QT3DSI32 inParamGroup, + const char *inDataValue, ERuntimeDataModelDataType inDataType, + ERuntimeAdditionalMetaDataType inAdditionalType); + + inline SElement *GetElement(const eastl::string &inElementName); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.cpp b/src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.cpp new file mode 100644 index 00000000..a9c581aa --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.cpp @@ -0,0 +1,2587 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" +#ifdef EA_PLATFORM_WINDOWS +#pragma warning(disable : 4396) // specializer warning nonsense +#endif + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSIPresentation.h" +#include "Qt3DSIScriptBridge.h" +#include "Qt3DSAttributeHashes.h" +#include "Qt3DSCommandEventTypes.h" +#include "Qt3DSDMPrefix.h" +#include "Qt3DSDMComposerTypeDefinitions.h" +#include "Qt3DSDMWStrOpsImpl.h" +#include "Qt3DSUIPParserActionHelper.h" +#include "Qt3DSUIPParserObjectRefHelper.h" +#include "Qt3DSApplication.h" +#include "Qt3DSRuntimeFactory.h" +#include "Qt3DSSceneGraphDebugger.h" +#include "foundation/Qt3DSFoundation.h" +#include "Qt3DSElementSystem.h" +#include "Qt3DSAnimationSystem.h" +#include "Qt3DSSlideSystem.h" + +using namespace qt3dsdm; + +#ifndef M_PI +#define M_PI 3.1415926535898 +#endif + +#define TODEG(x) x = (float)(x * 180 / M_PI); +#define TORAD(x) x = (float)(x / 180 * M_PI); + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +TStrType SParseElementManager::RegisterStr(const char8_t *inStr) +{ + return m_MetaData.GetStringTable()->GetRenderStringTable().RegisterStr(inStr); +} +SElementData &SParseElementManager::GetOrCreateElementData(const char8_t *inIdOrRef, + const char8_t *inElemType, + const char8_t *inElemClassId) +{ + if (inIdOrRef == NULL) + inIdOrRef = ""; + if (inIdOrRef[0] == '#') + ++inIdOrRef; + if (inElemClassId == NULL) + inElemClassId = ""; + if (inElemClassId[0] == '#') + ++inElemClassId; + if (inElemType == NULL) + inElemType = ""; + TStrType theStr = RegisterStr(inIdOrRef); + eastl::pair theInserter = + m_ElementMap.insert(eastl::make_pair(theStr, SElementData(theStr))); + SElementData &retval(theInserter.first->second); + if (theInserter.second) { + retval.m_Class = RegisterStr(inElemClassId); + retval.m_Type = RegisterStr(inElemType); + } + return retval; +} +SElementData *SParseElementManager::FindElementData(const char8_t *inIdOrRef) +{ + if (inIdOrRef == NULL) + inIdOrRef = ""; + if (inIdOrRef[0] == '#') + ++inIdOrRef; + TStrType theStr = RegisterStr(inIdOrRef); + TIdElementMap::iterator theIter = m_ElementMap.find(theStr); + if (theIter != m_ElementMap.end()) + return &theIter->second; + return NULL; +} +static void SetPropertyValueHash(eastl::string &inWorkspace, const char8_t *inExtension, + qt3ds::QT3DSU32 *&ioHashes, eastl::string::size_type originalSize, + CRegisteredString *&ioPropNames, + qt3ds::foundation::IStringTable &ioStringTable) +{ + if (inExtension && *inExtension) + inWorkspace.append(inExtension); + *ioHashes = Q3DStudio::CHash::HashAttribute(inWorkspace.c_str()); + *ioPropNames = ioStringTable.RegisterStr(inWorkspace.c_str()); + ++ioHashes; + ++ioPropNames; + inWorkspace.resize(originalSize); +} +static eastl::pair +SetupPropertyWorkspace(const char8_t *inPropName, eastl::string &ioWorkspace) +{ + qt3ds::QT3DSU32 outSubIndex = 0; + ioWorkspace.assign(inPropName ? inPropName : ""); + eastl::string::size_type thePeriodPos = ioWorkspace.find('.'); + if (thePeriodPos != eastl::string::npos) { + if (thePeriodPos < ioWorkspace.size() - 1) { + switch (ioWorkspace[thePeriodPos + 1]) { + default: + QT3DS_ASSERT(false); + case 'r': + case 'x': + break; + case 'g': + case 'y': + outSubIndex = 1; + break; + case 'b': + case 'z': + outSubIndex = 2; + break; + case 'a': + case 'w': + outSubIndex = 3; + break; + } + } + ioWorkspace.resize(thePeriodPos); + } + return eastl::make_pair(ioWorkspace.size(), outSubIndex); +} +SElementPropertyInfo *SParseElementManager::GetOrCreateProperty(SElementData &inData, + const char8_t *inPropertyName) +{ + SElementData &theData(inData); + SElementPropertyInfo *retvalPtr = FindProperty(inData, inPropertyName); + if (retvalPtr) + return retvalPtr; + + eastl::string::size_type thePeriodPos = + SetupPropertyWorkspace(inPropertyName, m_Workspace).first; + TStrType theStr = RegisterStr(m_Workspace.c_str()); + + if (m_MetaData.IsPropertyExist(inData.m_Type, theStr, inData.m_Class) == false) + return NULL; + + eastl::pair theInserter = + theData.m_PropertyMap.insert(eastl::make_pair(theStr, SElementPropertyInfo(theStr))); + SElementPropertyInfo &retval(theInserter.first->second); + if (theInserter.second) { + qt3ds::intrinsics::memZero(retval.m_PropertyHashes, sizeof(retval.m_PropertyHashes)); + qt3ds::QT3DSU32 *thePropHashes(retval.m_PropertyHashes); + CRegisteredString *thePropNames(retval.m_PropertyNames); + retval.m_DataType = m_MetaData.GetPropertyType(theData.m_Type, theStr, theData.m_Class); + retval.m_AdditionalType = + m_MetaData.GetAdditionalType(theData.m_Type, theStr, theData.m_Class); + if (retval.m_DataType != ERuntimeDataModelDataTypeNone) { + switch (retval.m_DataType) { + default: + retval.m_Arity = 1; + break; + case ERuntimeDataModelDataTypeFloat2: + retval.m_Arity = 2; + break; + case ERuntimeDataModelDataTypeFloat3: + retval.m_Arity = 3; + break; + } + if (retval.m_Arity > 1) { + if (retval.m_Arity == 2) { + SetPropertyValueHash(m_Workspace, ".x", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + SetPropertyValueHash(m_Workspace, ".y", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + } else { + if (m_MetaData.GetAdditionalType(theData.m_Type, theStr, theData.m_Class) + == ERuntimeAdditionalMetaDataTypeColor) { + SetPropertyValueHash(m_Workspace, ".r", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + SetPropertyValueHash(m_Workspace, ".g", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + SetPropertyValueHash(m_Workspace, ".b", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + } else { + SetPropertyValueHash(m_Workspace, ".x", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + SetPropertyValueHash(m_Workspace, ".y", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + SetPropertyValueHash(m_Workspace, ".z", thePropHashes, thePeriodPos, + thePropNames, m_StringTable); + } + } + } else { + retval.m_PropertyHashes[0] = Q3DStudio::CHash::HashAttribute(theStr.c_str()); + retval.m_PropertyNames[0] = m_StringTable.RegisterStr(m_Workspace.c_str()); + } + } + } + return &retval; +} + +SElementPropertyInfo *SParseElementManager::GetOrCreateProperty(const char8_t *inIdOrRef, + const char8_t *inElemType, + const char8_t *inElemClassId, + const char8_t *inPropertyName) +{ + return GetOrCreateProperty(GetOrCreateElementData(inIdOrRef, inElemType, inElemClassId), + inPropertyName); +} + +eastl::pair +SParseElementManager::FindPropertyWithSubIndex(SElementData &inElement, + const char8_t *inPropertyName) +{ + qt3ds::QT3DSU32 subIndex = SetupPropertyWorkspace(inPropertyName, m_Workspace).second; + TStrType theStr = RegisterStr(m_Workspace.c_str()); + TAttrMap::iterator theIter = inElement.m_PropertyMap.find(theStr); + SElementPropertyInfo *retval = NULL; + if (theIter != inElement.m_PropertyMap.end()) + retval = &theIter->second; + return eastl::make_pair(retval, subIndex); +} + +SElementPropertyInfo *SParseElementManager::FindProperty(SElementData &inElement, + const char8_t *inPropertyName) +{ + return FindPropertyWithSubIndex(inElement, inPropertyName).first; +} +SElementPropertyInfo *SParseElementManager::FindProperty(const char8_t *inIdOrRef, + const char8_t *inPropertyName) +{ + SElementData *theData(FindElementData(inIdOrRef)); + if (theData) + return FindProperty(*theData, inPropertyName); + return NULL; +} + +void SParseElementManager::MarkAttributeAsReferenced(SElementData &inElement, + const char8_t *inPropertyName) +{ + SElementPropertyInfo *theProp = GetOrCreateProperty(inElement, inPropertyName); + if (theProp) + theProp->m_ElementFlag = true; +} + +void SParseElementManager::MarkAttributeAsReferenced(const char8_t *inElement, + const char8_t *inPropertyName) +{ + SElementData *theData = FindElementData(inElement); + if (theData) + MarkAttributeAsReferenced(*theData, inPropertyName); +} + +void SParseElementManager::MarkAllAttributesAsReferenced(SElementData &inElement, + bool searchParent) +{ + m_PropertyList.clear(); + m_MetaData.GetInstanceProperties(inElement.m_Type, inElement.m_Class, m_PropertyList, + searchParent); + for (QT3DSU32 idx = 0, end = m_PropertyList.size(); idx < end; ++idx) + MarkAttributeAsReferenced(inElement, m_PropertyList[idx].c_str()); +} + +TStrType SParseSlideManager::RegisterId(const char8_t *inStr) +{ + if (!inStr) + inStr = ""; + if (*inStr == '#') + ++inStr; + return RegisterStr(inStr); +} + +SParseSlideManager::~SParseSlideManager() +{ + for (QT3DSU32 idx = 0, end = m_Animations.size(); idx < end; ++idx) + delete m_Animations[idx]; + m_Animations.clear(); +} + +SParseSlide &SParseSlideManager::GetOrCreateSlide(const char8_t *inSlideId, qt3ds::QT3DSI32 inSlideIndex) +{ + TStrType theSlideId(RegisterId(inSlideId)); + return m_SlideMap.insert(eastl::make_pair(theSlideId, SParseSlide(theSlideId, inSlideIndex))) + .first->second; +} + +SParseSlide *SParseSlideManager::FindSlide(const char8_t *inSlideId) +{ + TStrType theSlideId(RegisterId(inSlideId)); + TSlideIdToParseSlideMap::iterator theIter = m_SlideMap.find(theSlideId); + if (theIter != m_SlideMap.end()) + return &theIter->second; + return NULL; +} + +void SParseSlideManager::SetAnimationData(SParseSlide &inSlide, const char8_t *inInstanceId, + const char8_t *inPropertyName, + const char8_t *inKeyframeData, + SParseSlideAnimationTypes::Enum inType, bool inIsDynamic, + bool inIsActive) +{ + TStrType thePropertyName(RegisterStr(inPropertyName)); + SElementData *theElemData = m_ElementManager.FindElementData(inInstanceId); + if (theElemData == NULL) { + QT3DS_ASSERT(false); + return; + } + eastl::pair theProperty = + m_ElementManager.FindPropertyWithSubIndex(*theElemData, thePropertyName); + if (theProperty.first == NULL) { + QT3DS_ASSERT(false); + return; + } + qt3ds::QT3DSU32 thePropertyHash = theProperty.first->m_PropertyHashes[theProperty.second]; + // Parse the keyframe data into floating point numbers. + if (inKeyframeData == NULL) + inKeyframeData = ""; + m_KeyframeParseBuffer.clear(); + m_KeyframeParseBuffer.assign(inKeyframeData); + m_KeyframeParseFloatBuffer.clear(); + char8_t *theBufData = const_cast(m_KeyframeParseBuffer.c_str()); + + char8_t *theStartPtr = qt3dsdm::FindNextNonWhitespace(theBufData); + while (theStartPtr && *theStartPtr) { + char8_t *nextPtr = qt3dsdm::FindNextWhitespace(theStartPtr); + if (nextPtr && *nextPtr) + *nextPtr = 0; + else + nextPtr = NULL; + QT3DSF32 temp; + WStrOps().StrTo(theStartPtr, temp); + m_KeyframeParseFloatBuffer.push_back(temp); + theStartPtr = nextPtr; + if (theStartPtr) + theStartPtr = FindNextNonWhitespace(theStartPtr + 1); + } + // Don't create animations with no keyframes. + if (m_KeyframeParseFloatBuffer.empty()) { + return; + } + + SParseSlideAnimationEntry *theEntry = + new SParseSlideAnimationEntry(inSlide.m_SlideId, theElemData->m_Id, thePropertyName, + thePropertyHash, inType, NULL, 0, inIsDynamic); + theEntry->m_KeyframeData = m_KeyframeParseFloatBuffer; + m_Animations.push_back(theEntry); + switch (inType) { + case SParseSlideAnimationTypes::Linear: + m_AnimationKeyframeCount += m_KeyframeParseFloatBuffer.size() / 2; + break; + case SParseSlideAnimationTypes::Bezier: + m_AnimationKeyframeCount += m_KeyframeParseFloatBuffer.size() / 6; + break; + default: + QT3DS_ASSERT(false); + break; + case SParseSlideAnimationTypes::EaseInOut: + m_AnimationKeyframeCount += m_KeyframeParseFloatBuffer.size() / 4; + break; + } + + ReferenceAnimation(inSlide, *theEntry, inIsActive); +} + +void SParseSlideManager::ReferenceAnimation(SParseSlide &inSlide, + const SParseSlideAnimationEntry &inSource, + bool inIsActive) +{ + TAnimationList &theList = + inSlide.m_Animations.insert(eastl::make_pair(inSource.m_InstanceId, TAnimationList())) + .first->second; + theList.push_back(SParseAnimationRef(inSlide.m_SlideId, inSource.m_InstanceId, + inSource.m_PropertyName, &inSource, inIsActive)); + m_SlideAnimationCount++; +} + +TAnimationList *SParseSlideManager::GetAnimationsForInstance(SParseSlide &inSlide, + const char8_t *inInstanceId) +{ + SElementData *theElemData = m_ElementManager.FindElementData(inInstanceId); + if (theElemData) { + TInstanceIdAnimationMap::iterator theAnimations = + inSlide.m_Animations.find(theElemData->m_Id); + if (theAnimations != inSlide.m_Animations.end()) + return &theAnimations->second; + } + return NULL; +} + +SParseSlideActionEntry &SParseSlideManager::GetOrCreateAction(SParseSlide &inSlide, + const char8_t *inActionId, + qt3ds::QT3DSI32 inActionCount, + bool inActive) +{ + TStrType theActionId(RegisterId(inActionId)); + SParseSlideActionEntry theAction(inSlide.m_SlideId, theActionId, inActionCount, inActive); + memZero(theAction.m_Actions, sizeof(theAction.m_Actions)); + TActionList::iterator theIter = + eastl::find(inSlide.m_ActionList.begin(), inSlide.m_ActionList.end(), theAction); + if (theIter != inSlide.m_ActionList.end()) + return *theIter; + inSlide.m_ActionList.push_back(theAction); + m_ActionCount += inActionCount; + return inSlide.m_ActionList.back(); +} + +SParseSlideActionEntry *SParseSlideManager::FindAction(SParseSlide &inSlide, + const char8_t *inActionId) +{ + TStrType theActionId(RegisterId(inActionId)); + SParseSlideActionEntry theAction(inSlide.m_SlideId, theActionId, 0, false); + TActionList::iterator theIter = + eastl::find(inSlide.m_ActionList.begin(), inSlide.m_ActionList.end(), theAction); + if (theIter != inSlide.m_ActionList.end()) + return &(*theIter); + return NULL; +} + +//============================================================================== +/** + * Constructor + * @param inFileName name of UIP file + */ +CUIPParserImpl::CUIPParserImpl(const QString &inFileName, IRuntimeMetaData &inMetaData, + IInputStreamFactory &inFactory, + qt3ds::foundation::IStringTable &inStringTable) + : m_MetaData(inMetaData) + , m_InputStreamFactory(inFactory) + , m_ParseElementManager(inMetaData, inStringTable) + , m_ParseSlideManager(inMetaData, m_ParseElementManager) +{ + // Setup DOMSerializer and DOMReader to read the file + std::shared_ptr theStrTable(inMetaData.GetStringTable()); + shared_ptr theFactory(qt3dsdm::IDOMFactory::CreateDOMFactory(theStrTable)); + TInputStreamPtr theInStream(inFactory.GetStreamForFile(inFileName)); + qt3dsdm::SDOMElement *topElement = NULL; + if (theInStream) + topElement = CDOMSerializer::Read(*theFactory, *theInStream); + if (!topElement) { + qCCritical(qt3ds::INVALID_OPERATION) + << "Could not open UIP file: " << inFileName.toLatin1().constData(); + } else { + eastl::pair, std::shared_ptr> theWriteReader = + IDOMWriter::CreateDOMWriter(theFactory, *topElement, theStrTable); + m_DOMWriter = theWriteReader.first; + m_DOMReader = theWriteReader.second; + if (!AreEqual(m_DOMReader->GetNarrowElementName(), "UIP")) { + qCCritical(qt3ds::INVALID_OPERATION) + << "Invalid UIP file: " << inFileName.toLatin1().constData(); + } + } + + // Create Helper class + m_ObjectRefHelper = new CUIPParserObjectRefHelper(m_MetaData); + m_ActionHelper = new CUIPParserActionHelper(this, m_ObjectRefHelper, m_MetaData); +} + +//============================================================================== +/** + * Destructor + */ +CUIPParserImpl::~CUIPParserImpl() +{ + // Delete Helper class + delete m_ObjectRefHelper; + m_ObjectRefHelper = NULL; + + delete m_ActionHelper; + m_ActionHelper = NULL; +} + +//============================================================================== +/** + * Load a presentation from a UIP file. + * @param inPresentation presentation written to + * @return a flag indicating whether or not we successfully loaded the file + */ +BOOL CUIPParserImpl::Load(IPresentation &inPresentation, + NVConstDataRef inStateReferences, + qt3ds::state::debugger::ISceneGraphRuntimeDebugger &debugger) +{ + m_CurrentPresentation = &inPresentation; + if (!m_DOMReader) { + qCCritical(qt3ds::INVALID_PARAMETER) << "CUIPParserImpl::Load, No DOM reader"; + return FALSE; + } + + BOOL theLoadResult = m_DOMReader->MoveToFirstChild("Project"); + + // Load project settings + if (theLoadResult) + theLoadResult &= LoadProjectSettings(inPresentation, *m_DOMReader); + + // First, we need to load the classes, because the class information will be stored in metadata + if (theLoadResult) + theLoadResult &= LoadClasses(inPresentation, *m_DOMReader); + + // Next is to cache the scene graph because we need the id-name information to resolve object + // reference + m_ObjectRefHelper->CacheGraph(*m_DOMReader, *m_DOMWriter); + + // Next is to cache the required attributes. This will be used to build Element + // We also need to cache the actions because we need to know the ActionCount to reserve the + // memory + { + IDOMReader::Scope __graphScope(*m_DOMReader); + m_DOMReader->MoveToFirstChild("Graph"); + CacheGraphRequiredAttributes(*m_DOMReader); + } + + { + IDOMReader::Scope __logicScope(*m_DOMReader); + m_DOMReader->MoveToFirstChild("Logic"); + { + + IDOMReader::Scope __stateScope(*m_DOMReader); + for (BOOL theSuccess = m_DOMReader->MoveToFirstChild("State"); theSuccess; + theSuccess = m_DOMReader->MoveToNextSibling("State")) { + IDOMReader::Scope __subSlideScope(*m_DOMReader); + if (theLoadResult) + theLoadResult &= CacheLogicRequiredAttributes(*m_DOMReader); + } + } + } + + // go through all the references and make sure the elements exist and if they do ensure the + // attributes are marked as referenced. + for (QT3DSU32 idx = 0, end = inStateReferences.size(); idx < end; ++idx) { + const SElementAttributeReference &reference = inStateReferences[idx]; + // All references are absolute, so the start node doesn't really matter. + CRegisteredString result = m_ObjectRefHelper->ParseObjectRefId(reference.m_Path, "Scene"); + if (result.IsValid() == false) { + qCCritical(INVALID_OPERATION, "Failed to resolve reference: %s", + reference.m_Path.c_str()); + } else { + m_ParseElementManager.MarkAttributeAsReferenced(result.c_str(), + reference.m_Attribute.c_str()); + } + } + + if (theLoadResult) + CacheClassRequiredAttributes(*m_DOMReader); + + ComputeAndReserveMemory(inPresentation, *m_DOMReader); + + // Now we are ready to load the scene graph + if (theLoadResult) + theLoadResult &= LoadGraph(inPresentation, *m_DOMReader); + if (theLoadResult) + theLoadResult &= LoadLogic(inPresentation, *m_DOMReader); + + if (theLoadResult) { + // Register all element ids with the debugger + eastl::vector elemMapBuffer; + for (TIdElementMap::iterator iter = m_ParseElementManager.m_ElementMap.begin(), + end = m_ParseElementManager.m_ElementMap.end(); + iter != end; ++iter) { + const SElementData &theData = iter->second; + if (theData.m_Element) { + qt3ds::state::debugger::SGElemIdMap mapEntry; + mapEntry.m_Elem = theData.m_Element; + mapEntry.m_Id = iter->first.c_str(); + elemMapBuffer.push_back(mapEntry); + } + } + debugger.MapElementIds(&inPresentation, + toDataRef(elemMapBuffer.data(), (QT3DSU32)elemMapBuffer.size())); + } + + return theLoadResult; +} + +IDOMReader &CUIPParserImpl::GetDOMReader() +{ + return *m_DOMReader.get(); +} + +//============================================================================== +/** + * Load Project Settings + * @param inPresentation presentation written to + * @return a flag indicating whether or not we successfully loaded the file + */ +BOOL CUIPParserImpl::LoadProjectSettings(IPresentation &inPresentation, IDOMReader &inReader) +{ + IDOMReader::Scope __projectSettingsScope(inReader); + + if (inReader.MoveToFirstChild("ProjectSettings")) { + SPresentationSize thePresentationSize; + qt3ds::QT3DSI32 theWidth, theHeight; + + if (inReader.Att("presentationWidth", theWidth)) + thePresentationSize.m_Width = static_cast(theWidth); + if (inReader.Att("presentationHeight", theHeight)) + thePresentationSize.m_Height = static_cast(theHeight); + thePresentationSize.m_ScaleMode = SCALEMODE_EXACT; // ScaleMode is always EXACT + + inPresentation.SetSize(thePresentationSize); + + return true; + } else + return false; +} + +BOOL CUIPParserImpl::LoadClasses(IPresentation & /*inPresentation*/, IDOMReader &inReader) +{ + IDOMReader::Scope __classesScope(inReader); + + if (inReader.MoveToFirstChild("Classes")) { + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + const char *theSourcePath; + const char *theId; + const char *theName; + // Read the sourcepath and id + if (inReader.Att("sourcepath", theSourcePath) && inReader.Att("id", theId)) { + // Read the name + if (!inReader.Att("name", theName)) + theName = theId; + + bool theLoadFlag = false; + QString theFullPath(theSourcePath); + + if (theFullPath.endsWith(".qml")) { + theLoadFlag = m_MetaData.LoadScriptFile(inReader.GetNarrowElementName(), theId, + theName, theFullPath.toUtf8().data()); + if (theLoadFlag) + m_IdScriptMap[theId] = theSourcePath; + } else if (theFullPath.endsWith(".effect")) { + theLoadFlag = m_MetaData.LoadEffectXMLFile(inReader.GetNarrowElementName(), + theId, theName, + theFullPath.toUtf8().data()); + } else if (theFullPath.endsWith(".material") || theFullPath.endsWith(".shader")) { + theLoadFlag = m_MetaData.LoadMaterialXMLFile( + inReader.GetNarrowElementName(), theId, theName, + theFullPath.toUtf8().data()); + } else if (theFullPath.endsWith(".plugin")) { + theLoadFlag = m_MetaData.LoadPluginXMLFile(inReader.GetNarrowElementName(), + theId, theName, + theFullPath.toUtf8().data()); + } + + if (!theLoadFlag) { + // What file is this?!? + qCCritical(qt3ds::INVALID_OPERATION) + << "Could not load sourcepath file: " + << theFullPath.toLatin1().constData(); + } + } + } + } + + // Always return true. Failing to load classes should not block the rest of the system. + return true; +} + +BOOL CUIPParserImpl::LoadGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __childScope(inReader); + + m_NumGraphElements = 0; + m_NumGraphComponents = 0; + m_NumGraphAttributes = 0; + + bool theLoadResult = inReader.MoveToFirstChild("Graph"); + if (theLoadResult) { + theLoadResult &= LoadSceneGraph(inPresentation, inReader); + if (theLoadResult) + PatchSceneElementRef(); + } + + return theLoadResult; +} + +inline RuntimeVector3 Convert(const QT3DSVec3 &input) +{ + return RuntimeVector3(input.x, input.y, input.z); +} +using qt3ds::runtime::element::SPropertyDesc; +using qt3ds::runtime::element::TPropertyDescAndValue; + +void CUIPParserImpl::GetMetaAttribute(IPresentation &inPresentation, + TPropertyDescAndValueList &outDescList, TStrType inType, + TStrType inName, TStrType inClassId, + CRegisteredString *inAttStrNames) +{ + ERuntimeDataModelDataType thePropertyType = + m_MetaData.GetPropertyType(inType, inName, inClassId); + + // TODO: Handle all other types + switch (thePropertyType) { + case ERuntimeDataModelDataTypeFloat: + AddFloatAttribute(outDescList, inAttStrNames[0], + m_MetaData.GetPropertyValueFloat(inType, inName, inClassId)); + break; + case ERuntimeDataModelDataTypeFloat2: { + RuntimeVector3 theVector3 = + Convert(m_MetaData.GetPropertyValueVector2(inType, inName, inClassId)); + SFloat2 theValue(theVector3.m_X, theVector3.m_Y); + AddFloat2Attribute(outDescList, inAttStrNames, theValue); + break; + } + case ERuntimeDataModelDataTypeFloat3: { + RuntimeVector3 theVector3 = + Convert(m_MetaData.GetPropertyValueVector3(inType, inName, inClassId)); + SFloat3 theValue(theVector3.m_X, theVector3.m_Y, theVector3.m_Z); + ERuntimeAdditionalMetaDataType theAdditionalType = + m_MetaData.GetAdditionalType(inType, inName, inClassId); + AddFloat3Attribute(outDescList, theAdditionalType, inAttStrNames, theValue); + break; + } + case ERuntimeDataModelDataTypeLong: + AddLongAttribute(outDescList, inAttStrNames[0], + m_MetaData.GetPropertyValueLong(inType, inName, inClassId)); + break; + case ERuntimeDataModelDataTypeString: { + Option theRuntimeStr = + m_MetaData.GetPropertyValueString(inType, inName, inClassId); + if (theRuntimeStr.hasValue()) + AddStringAttribute(inPresentation, outDescList, inAttStrNames[0], + theRuntimeStr->c_str()); + else + AddStringAttribute(inPresentation, outDescList, inAttStrNames[0], ""); + } break; + case ERuntimeDataModelDataTypeBool: + AddBoolAttribute(outDescList, inAttStrNames[0], + m_MetaData.GetPropertyValueBool(inType, inName, inClassId)); + break; + case ERuntimeDataModelDataTypeLong4: + AddElementRefAttribute(outDescList, inAttStrNames[0], NULL); + break; + case ERuntimeDataModelDataTypeObjectRef: { + // Object ref is converted to string path + eastl::string theRuntimeStr = + m_MetaData.GetPropertyValueObjectRef(inType, inName, inClassId); + eastl::string theObjectRef = m_ObjectRefHelper->BuildReferenceString(theRuntimeStr); + AddStringAttribute(inPresentation, outDescList, inAttStrNames[0], theObjectRef.c_str()); + break; + } + default: + QT3DS_ASSERT(false); + } +} + +void CUIPParserImpl::AddFloatAttribute(TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, float &inValue) +{ + UVariant theValue; + theValue.m_FLOAT = inValue; + outDescList.push_back( + eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_FLOAT), theValue)); +} + +void CUIPParserImpl::AddLongAttribute(TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, qt3ds::QT3DSI32 &inValue) +{ + UVariant theValue; + theValue.m_INT32 = inValue; + outDescList.push_back( + eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_INT32), theValue)); +} + +void CUIPParserImpl::AddBoolAttribute(TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, bool &inValue) +{ + UVariant theValue; + theValue.m_INT32 = inValue; + outDescList.push_back( + eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_BOOL), theValue)); +} + +void CUIPParserImpl::AddFloat2Attribute(TPropertyDescAndValueList &outDescList, + CRegisteredString *inAttStrNames, SFloat2 &inValue) +{ + for (long theIndex = 0; theIndex < 2; ++theIndex) { + UVariant theValue; + theValue.m_FLOAT = inValue[theIndex]; + outDescList.push_back(eastl::make_pair( + SPropertyDesc(inAttStrNames[theIndex], ATTRIBUTETYPE_FLOAT), theValue)); + } +} + +void CUIPParserImpl::AddFloat3Attribute(TPropertyDescAndValueList &outDescList, + ERuntimeAdditionalMetaDataType inAdditionalType, + CRegisteredString *inAttStrNames, SFloat3 &inValue) +{ + for (long theIndex = 0; theIndex < 3; ++theIndex) { + float theValue = inValue[theIndex]; + if (inAdditionalType == ERuntimeAdditionalMetaDataTypeRotation) + TORAD(theValue); + UVariant theVarValue; + theVarValue.m_FLOAT = theValue; + outDescList.push_back(eastl::make_pair( + SPropertyDesc(inAttStrNames[theIndex], ATTRIBUTETYPE_FLOAT), theVarValue)); + } +} + +void CUIPParserImpl::AddStringAttribute(IPresentation &inPresentation, + TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, const char *inValue) +{ + qt3ds::foundation::CStringHandle theString = inPresentation.GetStringTable().GetHandle(inValue); + UVariant theValue; + theValue.m_StringHandle = theString.handle(); + outDescList.push_back( + eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_STRING), theValue)); + if (CHash::HashAttribute(inAttStrName.c_str()) == Q3DStudio::ATTRIBUTE_SOURCEPATH && inValue + && *inValue) + AddSourcePath(inValue); +} + +void CUIPParserImpl::AddElementRefAttribute(TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, SElement *inElement) +{ + UVariant theValue; + if (inElement) { + theValue.m_ElementHandle = inElement->GetHandle(); + QT3DS_ASSERT(theValue.m_ElementHandle); + } else + theValue.m_ElementHandle = 0; + outDescList.push_back( + eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_ELEMENTREF), theValue)); +} + +void CUIPParserImpl::GetAttributeList(IPresentation &inPresentation, + TPropertyDescAndValueList &outDescList, TStrType inType, + TStrType inName, TStrType inClassId, const char *inValue, + CRegisteredString *inPropNameStrs) +{ + ERuntimeDataModelDataType theDataType = m_MetaData.GetPropertyType(inType, inName, inClassId); + ERuntimeAdditionalMetaDataType theAdditionalType = + m_MetaData.GetAdditionalType(inType, inName, inClassId); + + GetAttributeList(inPresentation, outDescList, theDataType, theAdditionalType, inName, inValue, + inPropNameStrs); +} + +void CUIPParserImpl::GetAttributeList(IPresentation &inPresentation, + TPropertyDescAndValueList &outDescList, + ERuntimeDataModelDataType inDataType, + ERuntimeAdditionalMetaDataType inAdditionalType, const char *, + const char *inValue, CRegisteredString *inPropNameStrs) +{ + // Create a destructible value + m_ValueBuffer.clear(); + m_TempBuffer.clear(); + m_ValueBuffer.write(inValue, (QT3DSU32)strlen(inValue) + 1); + WCharTReader theReader((char8_t *)m_ValueBuffer.begin(), m_TempBuffer, + *m_DOMReader->GetStringTable()); + + // TODO: Handle all other types + // Note that the default value should be consistent with the SetDefault method of + // TDataModelValue + switch (inDataType) { + case ERuntimeDataModelDataTypeLong: { + qt3ds::QT3DSI32 theValue = 0; + if (!IsTrivial(inValue)) + theReader.Read(theValue); + AddLongAttribute(outDescList, inPropNameStrs[0], theValue); + break; + } + case ERuntimeDataModelDataTypeFloat: { + float theValue = 0; + if (!IsTrivial(inValue)) + theReader.Read(theValue); + AddFloatAttribute(outDescList, inPropNameStrs[0], theValue); + break; + } + case ERuntimeDataModelDataTypeFloat2: { + SFloat2 theValue(0); + if (!IsTrivial(inValue)) + theReader.ReadRef(NVDataRef(&theValue[0], 2)); + AddFloat2Attribute(outDescList, inPropNameStrs, theValue); + break; + } + case ERuntimeDataModelDataTypeFloat3: { + SFloat3 theValue(0); + if (!IsTrivial(inValue)) + theReader.ReadRef(NVDataRef(&theValue[0], 3)); + AddFloat3Attribute(outDescList, inAdditionalType, inPropNameStrs, theValue); + break; + } + case ERuntimeDataModelDataTypeBool: { + bool theValue = false; + if (!IsTrivial(inValue)) + theReader.Read(theValue); + AddBoolAttribute(outDescList, inPropNameStrs[0], theValue); + break; + } + case ERuntimeDataModelDataTypeStringRef: + case ERuntimeDataModelDataTypeString: { + const char *theDataPtr = ""; + if (!IsTrivial(inValue)) + theReader.Read(theDataPtr); + AddStringAttribute(inPresentation, outDescList, inPropNameStrs[0], theDataPtr); + break; + } + case ERuntimeDataModelDataTypeLong4: { + const char *theDataPtr = NULL; + if (!IsTrivial(inValue)) + theReader.Read(theDataPtr); + SElement *theElementData = GetElement(theDataPtr); + AddElementRefAttribute(outDescList, inPropNameStrs[0], theElementData); + break; + } + case ERuntimeDataModelDataTypeObjectRef: { + // Object ref is converted to string path + const char *theDataPtr = NULL; + if (!IsTrivial(inValue)) + theReader.Read(theDataPtr); + if (theDataPtr) { + eastl::string theObjectRef = m_ObjectRefHelper->BuildReferenceString(theDataPtr); + AddStringAttribute(inPresentation, outDescList, inPropNameStrs[0], + theObjectRef.c_str()); + } + break; + } + default: + QT3DS_ASSERT(false); + } +} + +//============================================================================== +/** + * Looks up the EElementType from the asset type. + */ +EElementType GetElementType(const char *inType) +{ + if (AreEqual(inType, "Scene") || AreEqual(inType, "Layer") || AreEqual(inType, "Group") + || AreEqual(inType, "Model") || AreEqual(inType, "Path")) + return ELEMENTTYPE_NODE; + + else if (AreEqual(inType, "Camera")) + return ELEMENTTYPE_CAMERA; + + else if (AreEqual(inType, "Light")) + return ELEMENTTYPE_LIGHT; + + else if (AreEqual(inType, "Component")) + return ELEMENTTYPE_COMPONENT; + + else if (AreEqual(inType, "Material")) + return ELEMENTTYPE_MATERIAL; + + else if (AreEqual(inType, "Image")) + return ELEMENTTYPE_TEXTURE; + + else if (AreEqual(inType, "Behavior")) + return ELEMENTTYPE_BEHAVIOR; + + else if (AreEqual(inType, "Text")) + return ELEMENTTYPE_TEXT; + + else if (AreEqual(inType, "PathAnchorPoint")) + return ELEMENTTYPE_PATHANCHORPOINT; + + else if (AreEqual(inType, "SubPath")) + return ELEMENTTYPE_SUBPATH; + + else + return ELEMENTTYPE_UNKNOWN; +} + +//============================================================================== +/** + * Build out the graph. + * @param inPresentation presentation written to + * @return a flag indicating whether or not we successfully loaded the file + */ +BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &inReader, + qt3ds::runtime::element::SElement *inNewStyleParent) +{ + IDOMReader::Scope __childScope(inReader); + IScriptBridge *theScriptBridgeQml = inPresentation.GetScriptBridgeQml(); + + eastl::string theFileString; + qt3ds::runtime::IApplication &theApp(inPresentation.GetApplication()); + qt3ds::runtime::IElementAllocator &theElemAllocator(theApp.GetElementAllocator()); + TPropertyDescAndValueList theProperties; + using qt3ds::runtime::element::SPropertyDesc; + qt3ds::foundation::IStringTable &theStringTable(inPresentation.GetStringTable()); + // build out the graph. + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + theProperties.clear(); + const char *theId; + inReader.Att("id", theId); + const char *theClass; + inReader.Att("class", theClass); + const char *theType(inReader.GetNarrowElementName()); + eastl::string theName(m_ObjectRefHelper->GetName(theId).c_str()); + // Get default end time from metadata + UINT32 theLoopTime = 0; + bool isComponent = false; + bool isBehavior = false; + + // Create SElement + if (AreEqual(theType, "Scene") || AreEqual(theType, "Component")) { + // TDataModelValue theValue; + theLoopTime = m_MetaData.GetPropertyValueLong(m_MetaData.Register(theType), + m_MetaData.Register("endtime")); + Q3DStudio_ASSERT(theLoopTime != 0); // Something is wrong here + isComponent = true; + } else { + if (AreEqual(theType, "Behavior") && !IsTrivial(theClass)) { + // Find the sourcepath and load the script + ++theClass; // remove the '#' + TIdSourcePathMap::iterator theSourcePathIter = m_IdScriptMap.find(theClass); + if (theSourcePathIter != m_IdScriptMap.end()) { + theFileString.assign(theSourcePathIter->second); + +// For non-windows platforms, we need to reverse the slashes +#ifndef EA_PLATFORM_WINDOWS + for (eastl::string::size_type thePos = theFileString.find('\\'); + thePos != eastl::string::npos; + thePos = theFileString.find('\\', thePos + 1)) { + theFileString.replace(thePos, 1, 1, '/'); + } +#endif + isBehavior = true; + UVariant theValue; + theValue.m_StringHandle = + inPresentation.GetStringTable().GetHandle(theFileString.c_str()); + theProperties.push_back(eastl::make_pair( + SPropertyDesc(theStringTable.RegisterStr("behaviorscripts"), + ATTRIBUTETYPE_STRING), + theValue)); + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "Could not load Behavior script: " << theClass; + } + } + } + + SElementData &theElementData = + m_ParseElementManager.GetOrCreateElementData(theId, theType, theClass); + + const char8_t *theSourcePath; + if (inReader.UnregisteredAtt("sourcepath", theSourcePath)) + AddSourcePath(theSourcePath); + + TAttrMap &theList = theElementData.m_PropertyMap; + + const char *theAttribute; + for (TAttrMap::iterator theIter = theList.begin(), theMapEnd = theList.end(); + theIter != theMapEnd; ++theIter) { + if (theIter->second.m_ElementFlag) { + // Parse the property value from uip, this will overwrite the default value + const TStrType &thePropertyName(theIter->first); + CRegisteredString *thePropertyNames = theIter->second.m_PropertyNames; + size_t theListSize = theProperties.size(); + if (inReader.Att(thePropertyName.c_str(), theAttribute)) { + ERuntimeDataModelDataType theDataType = m_MetaData.GetPropertyType( + theElementData.m_Type, thePropertyName, theElementData.m_Class); + if (theDataType == ERuntimeDataModelDataTypeLong4) { + AddElementRefToPatch(theProperties, theElementData, thePropertyName.c_str(), + theAttribute); + } else + GetAttributeList(inPresentation, theProperties, theElementData.m_Type, + thePropertyName, theElementData.m_Class, theAttribute, + thePropertyNames); + } else { + GetMetaAttribute(inPresentation, theProperties, theElementData.m_Type, + thePropertyName, theElementData.m_Class, thePropertyNames); + } + size_t theNumAtts = theProperties.size() - theListSize; + QT3DS_ASSERT(theNumAtts == (size_t)theIter->second.m_Arity); + (void)theNumAtts; + } + } + qt3ds::runtime::element::SElement &theNewElem = theElemAllocator.CreateElement( + theStringTable.RegisterStr(theName.c_str()), theStringTable.RegisterStr(theType), + theStringTable.RegisterStr(theElementData.m_Class.c_str()), + toConstDataRef(theProperties.data(), (QT3DSU32)theProperties.size()), &inPresentation, + inNewStyleParent, isComponent); + theElementData.m_Element = &theNewElem; + + if (inPresentation.GetRoot() == NULL) + inPresentation.SetRoot(theNewElem); + + eastl::string thePath; + // build out the full path to the element for debugging + for (CUIPParserObjectRefHelper::SGraphNode *theNode = + this->m_ObjectRefHelper->GetNode(theId); + theNode; theNode = theNode->m_Parent) { + if (thePath.length()) + thePath.insert(0, "."); + thePath.insert(0, theNode->m_Name); + } + if (thePath.size()) + theNewElem.m_Path = m_ParseElementManager.m_StringTable.RegisterStr(thePath.c_str()); + + if (isBehavior) { + if (theFileString.find(".qml") != eastl::string::npos) { + theScriptBridgeQml->LoadScript(&inPresentation, &theNewElem, + theFileString.c_str()); + } + } + LoadSceneGraph(inPresentation, inReader, &theNewElem); + } + + return true; +} + +//============================================================================== +/** + * This method will parse through the graph sections to cache those attributes that + * should never be optimized + */ +void CUIPParserImpl::CacheGraphRequiredAttributes(qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __childScope(inReader); + + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + const char *theId; + inReader.Att("id", theId); + const char *theType(inReader.GetNarrowElementName()); + const char *theClass = ""; + inReader.Att("class", theClass); + SElementData &theData = + m_ParseElementManager.GetOrCreateElementData(theId, theType, theClass); + // name and sourcepath are never optimized out. + m_ParseElementManager.MarkAttributeAsReferenced(theData, "name"); + // not everything needs to be in the time graph. + if (AreEqual(theType, "Scene") == false && AreEqual(theType, "Material") == false + && AreEqual(theType, "CustomMaterial") == false && AreEqual(theType, "Image") == false + && AreEqual(theType, "RenderPlugin") == false) { + SElementPropertyInfo *theProp = + m_ParseElementManager.GetOrCreateProperty(theData, "starttime"); + theProp->m_SlideFlag = true; + theProp->m_SlideForceFlag = true; + theProp->m_ElementFlag = true; + theProp = m_ParseElementManager.GetOrCreateProperty(theData, "endtime"); + theProp->m_SlideFlag = true; + theProp->m_SlideForceFlag = true; + theProp->m_ElementFlag = true; + } + + // Probably not the most optimal thing to expose this attribute for all elements that + // support it, since it is not really needed except during initialization + m_ParseElementManager.MarkAttributeAsReferenced(theData, "controlledproperty"); + + // Behaviors need all attributes possible on the object on them all the time. + if (AreEqual(theType, "Behavior") || AreEqual(theType, "RenderPlugin")) { + m_ParseElementManager.MarkAllAttributesAsReferenced(theData); + } + + // Recursive + CacheGraphRequiredAttributes(inReader); + } +} + +//============================================================================== +/** + * This method will parse through the logic sections to cache those attributes that + * will be changed and thus needs to be at the SElement + */ +BOOL CUIPParserImpl::CacheLogicRequiredAttributes(qt3dsdm::IDOMReader &inReader, + qt3ds::QT3DSI32 inSlideIndex, + SParseSlide *inParentSlide) +{ + IDOMReader::Scope __stateScope(inReader); + eastl::string theSlideId = GetSlideId(inReader); + SParseSlide &theSlide = m_ParseSlideManager.GetOrCreateSlide(theSlideId.c_str(), inSlideIndex); + eastl::hash_set theCommandInstances; + QT3DSU32 slideAnimActions = 0; + + { + IDOMReader::Scope __commandLoopScope(inReader); + for (BOOL theSuccess = inReader.MoveToFirstChild(); theSuccess; + theSuccess = inReader.MoveToNextSibling()) { + IDOMReader::Scope __commandScope(inReader); + if (AreEqual(inReader.GetNarrowElementName(), "Add") + || AreEqual(inReader.GetNarrowElementName(), "Set")) { + bool isSet = AreEqual(inReader.GetNarrowElementName(), "Set"); + + const char *theRef; + if (inReader.Att("ref", theRef)) { + theRef++; // remove the '#' + + // Set/Add command applied to an element *not* in the scene graph. + SElementData *theData = m_ParseElementManager.FindElementData(theRef); + if (theData == NULL) { + QT3DS_ASSERT(false); + continue; + } + // If this element has controlledproperty, need to mark all as referenced + // in order for datainput initialisation to find attributes that + // are controlled + // TODO: we could parse out the exact controlled property names and + // set only those as referenced. In this case we might have to expand vec3 + // type attributes to component parts + const char *ctrldProp; + inReader.Att("controlledproperty", ctrldProp); + if (ctrldProp) + m_ParseElementManager.MarkAllAttributesAsReferenced(*theData, true); + + theCommandInstances.insert(theData->m_Id); + if (isSet) { + for (eastl::pair theAtt = + inReader.GetNarrowFirstAttribute(); + !IsTrivial(theAtt.first); theAtt = inReader.GetNarrowNextAttribute()) { + if (AreEqual(theAtt.first, "ref") || AreEqual(theAtt.first, "shy")) + continue; + + SElementPropertyInfo *theProperty = + m_ParseElementManager.GetOrCreateProperty(*theData, theAtt.first); + // This property exists on both the elements and the slides. + if (theProperty) { + theProperty->m_ElementFlag = true; + theProperty->m_SlideFlag = true; + } + } + // Run through parent animations and forward them *if* this set command does + // not have this property present. + if (inParentSlide) { + TAnimationList *theAnimations = + m_ParseSlideManager.GetAnimationsForInstance(*inParentSlide, + theData->m_Id); + if (theAnimations != NULL) { + for (QT3DSU32 animIdx = 0, animEnd = theAnimations->size(); + animIdx < animEnd; ++animIdx) { + SParseAnimationRef &theEntry((*theAnimations)[animIdx]); + const char8_t *propValue = ""; + SElementPropertyInfo *thePropInfo = + m_ParseElementManager.FindProperty( + *theData, theEntry.m_PropertyName.c_str()); + if (!thePropInfo) { + QT3DS_ASSERT(false); + continue; + } + // If the attribute doesn't exist in the command, then we + // forward the animation to here + if (inReader.Att(thePropInfo->m_PropertyName, propValue) + == false) { + ++slideAnimActions; + m_ParseSlideManager.ReferenceAnimation( + theSlide, *theEntry.m_Animation, true); + } + } + } + } + } + + // find all the animations, regardless of add or set. + { + IDOMReader::Scope __animationScope(inReader); + for (BOOL theAnimScopeSuccess = inReader.MoveToFirstChild("AnimationTrack"); + theAnimScopeSuccess; + theAnimScopeSuccess = inReader.MoveToNextSibling("AnimationTrack")) { + const char *theProperty; + const char8_t *theValue = ""; + inReader.Value(theValue); + if (theValue != NULL && *theValue + && inReader.UnregisteredAtt("property", theProperty)) { + m_ParseElementManager.MarkAttributeAsReferenced(*theData, + theProperty); + // PreParse the animation at this point. This allows us to easily + // count animations. + bool isDynamic = false; + inReader.Att("dynamic", isDynamic); + SParseSlideAnimationTypes::Enum theParseType = + SParseSlideAnimationTypes::EaseInOut; + const char8_t *animType; + if (inReader.Att("type", animType)) { + if (AreEqual(animType, "EaseInOut")) { + } else if (AreEqual(animType, "Bezier")) + theParseType = SParseSlideAnimationTypes::Bezier; + else if (AreEqual(animType, "Linear")) + theParseType = SParseSlideAnimationTypes::Linear; + else { + QT3DS_ASSERT(false); + } + } + ++slideAnimActions; + m_ParseSlideManager.SetAnimationData( + theSlide, theData->m_Id, theProperty, theValue, theParseType, + isDynamic, inSlideIndex != 0); + } + } + } + + // find all the actions + { + IDOMReader::Scope __actionScope(inReader); + for (BOOL theActionScopeSuccess = inReader.MoveToFirstChild("Action"); + theActionScopeSuccess; + theActionScopeSuccess = inReader.MoveToNextSibling("Action")) { + const char8_t *theActionId; + // Don't cache reference actions + if (inReader.Att("id", theActionId)) { + m_ActionHelper->CacheAction(inReader, theData->m_Id); + bool active = true; + inReader.Att("eyeball", active); + ++slideAnimActions; + m_ParseSlideManager.GetOrCreateAction( + theSlide, theActionId, + m_ActionHelper->GetActionCount(theActionId), active); + } + } + } + } + } + } + } + // Now forward all animations from the parent slide that are for instances that we haven't + // covered at all on this slide. + if (inParentSlide) { + for (TInstanceIdAnimationMap::iterator theIter = inParentSlide->m_Animations.begin(), + theEnd = inParentSlide->m_Animations.end(); + theIter != theEnd; ++theIter) { + if (theCommandInstances.find(theIter->first) == theCommandInstances.end()) { + TAnimationList &theList(theIter->second); + for (QT3DSU32 animIdx = 0, animEnd = theList.size(); animIdx < animEnd; ++animIdx) { + SParseAnimationRef &theEntry(theList[animIdx]); + m_ParseSlideManager.ReferenceAnimation(theSlide, *theEntry.m_Animation, true); + ++slideAnimActions; + } + } + } + // Forward action creation onto this slide. + for (TActionList::iterator theIter = inParentSlide->m_ActionList.begin(), + theEnd = inParentSlide->m_ActionList.end(); + theIter != theEnd; ++theIter) { + SParseSlideActionEntry &theAction(*theIter); + m_ParseSlideManager.GetOrCreateAction(theSlide, theAction.m_ActionId, + theAction.m_ActionCount, theAction.m_Active); + ++slideAnimActions; + } + } + + eastl::vector theChildSlideIds; + + for (BOOL theSuccess = inReader.MoveToFirstChild("State"); theSuccess; + theSuccess = inReader.MoveToNextSibling("State")) { + IDOMReader::Scope __subSlideScope(inReader); + ++inSlideIndex; + theChildSlideIds.push_back(GetSlideId(inReader)); + CacheLogicRequiredAttributes(inReader, inSlideIndex, &theSlide); + } + + // Pull all child animations up into this slide, but set them to deactivated. + for (QT3DSU32 childSlideIdx = 0, childSlideEnd = theChildSlideIds.size(); + childSlideIdx < childSlideEnd; ++childSlideIdx) { + SParseSlide *theChildSlide = + m_ParseSlideManager.FindSlide(theChildSlideIds[childSlideIdx].c_str()); + if (theChildSlide) { + // Add animations that did not original in this slide to this slide. + for (TInstanceIdAnimationMap::iterator theIter = theChildSlide->m_Animations.begin(), + theEnd = theChildSlide->m_Animations.end(); + theIter != theEnd; ++theIter) { + TAnimationList &theList(theIter->second); + for (QT3DSU32 animIdx = 0, animEnd = theList.size(); animIdx < animEnd; ++animIdx) { + SParseAnimationRef &theEntry(theList[animIdx]); + if (theEntry.m_Animation + && theEntry.m_Animation->m_SlideId != theSlide.m_SlideId) { + m_ParseSlideManager.ReferenceAnimation(theSlide, *theEntry.m_Animation, + false); + ++slideAnimActions; + } + } + } + for (TActionList::iterator theIter = theChildSlide->m_ActionList.begin(), + theEnd = theChildSlide->m_ActionList.end(); + theIter != theEnd; ++theIter) { + SParseSlideActionEntry &theEntry(*theIter); + // This deactivates actions that may be active on another slide. + m_ParseSlideManager.GetOrCreateAction(theSlide, theEntry.m_ActionId, + theEntry.m_ActionCount, false); + ++slideAnimActions; + } + } + } + // qt3ds::NVFoundationBase& fnd( + // m_CurrentPresentation->GetApplication().GetRuntimeFactory().GetFoundation() ); + // fnd.error( QT3DS_TRACE, "Loading slide %s, %d anim actions", theSlideId.c_str(), + // slideAnimActions ); + + return TRUE; +} + +void CUIPParserImpl::CacheClassRequiredAttributes(qt3dsdm::IDOMReader &inReader) +{ + { + // First, we parse Graph section to cache custom attributes specified by the class + IDOMReader::Scope __graphScope(inReader); + inReader.MoveToFirstChild("Graph"); + CacheClassSceneAttributes(inReader); + } + if (!m_IdClassMap.empty()) { + // Next, we parse Logic section to update the references + IDOMReader::Scope __logicScope(inReader); + inReader.MoveToFirstChild("Logic"); + CacheClassStateAttributes(inReader); + } +} + +void CUIPParserImpl::CacheClassSceneAttributes(IDOMReader &inReader) +{ + IDOMReader::Scope __childScope(inReader); + // build out the graph. + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + const char *theId; + const char *theClass; + if (inReader.Att("class", theClass) && inReader.Att("id", theId)) { + // Add to id-class map + m_IdClassMap[theId] = theClass; + } + CacheClassSceneAttributes(inReader); + } +} + +void CUIPParserImpl::CacheClassStateAttributes(IDOMReader &inReader) +{ + IDOMReader::Scope __childScope(inReader); + + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "State")) + CacheClassStateAttributes(inReader); + else if (AreEqual(inReader.GetNarrowElementName(), "Add") + || AreEqual(inReader.GetNarrowElementName(), "Set")) { + const char *theRef; + if (inReader.Att("ref", theRef)) { + theRef++; // remove the '#' + + // Find the class, if any + TIdClassMap::iterator theIter = m_IdClassMap.find(theRef); + if (theIter != m_IdClassMap.end()) { + // Get References of the class + eastl::vector theReferences; + m_MetaData.GetReferences("", theReferences, theIter->second.c_str()); + if (!theReferences.empty()) { + // Cache the references + m_ObjectRefHelper->MarkAllReferencedAttributes( + theRef, theReferences, inReader, m_ParseElementManager); + } + } + } + } + } +} + +//============================================================================== +/** + * For ElementRef type, there could be times where the SElement isn't created yet, thus + * this method cache those Long4 type and add an empty attribute into the SElement + */ +void CUIPParserImpl::AddElementRefToPatch(TPropertyDescAndValueList &outDescList, + SElementData &inElement, const char *inName, + const char *inValue) +{ + SElementRefCache theElementRefData; + theElementRefData.m_Element = &inElement; + theElementRefData.m_Name = inName; + theElementRefData.m_Value = inValue; + m_ElementRefCache.push_back(theElementRefData); + + UVariant theValue; + theValue.m_ElementHandle = 0; + outDescList.push_back( + eastl::make_pair(SPropertyDesc(m_ParseElementManager.m_StringTable.RegisterStr(inName), + ATTRIBUTETYPE_ELEMENTREF), + theValue)); +} + +//============================================================================== +/** + * For those Long4 type that was not loaded correctly, go through all of them and + * fix up the ElementRef + */ +void CUIPParserImpl::PatchSceneElementRef() +{ + for (eastl::vector::iterator theIter = m_ElementRefCache.begin(); + theIter != m_ElementRefCache.end(); ++theIter) { + SElementRefCache &theCache = *theIter; + + SElementData *theElementData = GetElementData(theCache.m_Value.c_str()); + + SElement *theElement = theCache.m_Element->m_Element; + UVariant *theValue = theElement->FindPropertyValue( + m_ParseElementManager.RegisterStr(theCache.m_Value.c_str())); + if (theValue) { + theValue->m_ElementHandle = 0; + if (theElementData->m_Element) { + theValue->m_ElementHandle = theElementData->m_Element->GetHandle(); + QT3DS_ASSERT(theValue->m_ElementHandle); + } + } + } +} + +BOOL CUIPParserImpl::LoadLogic(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __logicScope(inReader); + + m_NumSlides = 0; + m_NumSlideElements = 0; + m_NumSlideAttributes = 0; + m_NumAnimationTracks = 0; + m_NumAnimationKeys = 0; + m_NumSlideAnimations = 0; + m_NumSlideActions = 0; + + bool theStatus = true; + + // Build all of the animation objects that we have tallied up. + for (QT3DSU32 animIdx = 0, animEnd = m_ParseSlideManager.m_Animations.size(); animIdx < animEnd; + ++animIdx) { + SParseSlideAnimationEntry &theEntry = *m_ParseSlideManager.m_Animations[animIdx]; + SElementData *theData = m_ParseElementManager.FindElementData(theEntry.m_InstanceId); + // Generate valid animation indexes while we are at it. + LoadAnimationTrack(inPresentation, *theData, theEntry); + } + + if (inReader.MoveToFirstChild("Logic")) { + + // Action + m_ActionHelper->BuildActions(inPresentation); + + for (BOOL theSuccess = inReader.MoveToFirstChild("State"); theSuccess; + theSuccess = inReader.MoveToNextSibling("State")) { + theStatus &= LoadStateGraph(inPresentation, inReader); + } + } + + return theStatus; +} + +//============================================================================== +/** + * Load the State (Slides) + * @param inPresentation presentation written to + * @return a flag indicating whether or not we successfully loaded the file + */ +BOOL CUIPParserImpl::LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __slideScope(inReader); + + BOOL theStatus = true; + + SElement *theComponent = NULL; + const char8_t *theAttribute; + if (inReader.UnregisteredAtt("component", theAttribute)) + theComponent = GetElement(theAttribute); + if (theComponent) { + INT32 theSlideIndex = 0; + LoadState(inPresentation, theComponent, theSlideIndex, inReader); + + for (BOOL theResult = inReader.MoveToFirstChild("State"); theResult; + theResult = inReader.MoveToNextSibling("State")) { + if (theStatus) + theStatus &= LoadState(inPresentation, theComponent, ++theSlideIndex, inReader); + } + } else { + if (theAttribute) { + qCCritical(qt3ds::INVALID_OPERATION) + << "Slide load failure!! Failed to find component: " << theAttribute; + } else { + qCCritical(qt3ds::INVALID_OPERATION) + << "Slide load failure!! Failed to find component."; + } + } + + return theStatus; +} + +//============================================================================== +/** + * Load the State (Slides) + * @param inPresentation presentation written to + * @return a flag indicating whether or not we successfully loaded the file + */ +BOOL CUIPParserImpl::LoadState(IPresentation &inPresentation, SElement *inComponent, + INT32 inSlideIndex, qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __stateScope(inReader); + + BOOL theResult = true; + ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); + + eastl::string theSlideName = GetSlideName(inReader); + + qt3ds::runtime::SSlidePlayInformation thePlayMode = GetPlayMode(inReader); + thePlayMode.m_PlayThroughTo = (QT3DSU8)GetPlayThroughTo(inSlideIndex, inReader); + // Setup with the default value from the metadata + INT32 theMinTime = m_MetaData.GetPropertyValueLong(m_MetaData.Register("Asset"), + m_MetaData.Register("starttime")); + INT32 theMaxTime = m_MetaData.GetPropertyValueLong(m_MetaData.Register("Asset"), + m_MetaData.Register("endtime")); + + theBuilder.AddSlide(*inComponent, theSlideName.c_str(), thePlayMode.m_PlayMode, + thePlayMode.m_Paused, thePlayMode.m_PlayThroughTo, theMinTime, theMaxTime); + m_NumSlides++; + + m_SlideElements.clear(); + m_SlideElements.insert(inComponent); + + BOOL theActiveFlag = (inSlideIndex != 0); + theBuilder.AddSlideElement(*inComponent, theActiveFlag); + ProcessStateRef(inPresentation, inComponent, inSlideIndex == 0, inReader); + + m_NumSlideElements++; + + theMaxTime = 0; + theResult &= + LoadSlideElements(inPresentation, inReader, inSlideIndex == 0, inComponent, &theMaxTime); + if (theMaxTime != 0) + theBuilder.SetSlideMaxTime((QT3DSU32)theMaxTime); + + return theResult; +} + +//============================================================================== +/** + * Process the state information to add all the animations and actions that might be setup + */ +BOOL CUIPParserImpl::ProcessStateRef(IPresentation &inPresentation, SElement *inComponent, + bool inMaster, qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __stateScope(inReader); + eastl::string theSlideId = GetSlideId(inReader); + for (BOOL theResult = inReader.MoveToFirstChild("Set"); theResult; + theResult = inReader.MoveToNextSibling("Set")) { + const char8_t *theElementRef; + if (inReader.UnregisteredAtt("ref", theElementRef) + && GetElement(theElementRef) == inComponent) + ProcessSlideAnimAction(inPresentation, theSlideId, inMaster, inReader); + } + return TRUE; +} + +void CUIPParserImpl::ComputeAndReserveMemory(IPresentation & /*inPresentation*/, + qt3dsdm::IDOMReader &inReader) +{ + SGraphSectionCount theGraphSectionCount; + SLogicSectionCount theLogicSectionCount; + SActionSectionCount theActionSectionCount; + + { + IDOMReader::Scope __graphScope(inReader); + if (inReader.MoveToFirstChild("Graph")) + DoGraphSectionCount(inReader, theGraphSectionCount); + } + DoLogicSectionCount(inReader, theLogicSectionCount); + m_ActionHelper->GetActionSectionCount(theActionSectionCount); +} + +void CUIPParserImpl::DoGraphSectionCount(qt3dsdm::IDOMReader &inReader, + SGraphSectionCount &outGraphCounter) +{ + IDOMReader::Scope __graphScope(inReader); + + for (bool theResult = inReader.MoveToFirstChild(); theResult; + theResult = inReader.MoveToNextSibling()) { + const char *theTypeStr(inReader.GetNarrowElementName()); + if (AreEqual(theTypeStr, "Scene") || AreEqual(theTypeStr, "Component")) + outGraphCounter.m_ComponentCount++; + else + outGraphCounter.m_ElementCount++; + + const char *theIdStr; + inReader.Att("id", theIdStr); + const char *theClassStr; + inReader.Att("class", theClassStr); + + // For Behavior, we are adding a string attribute ATTRIBUTE_BEHAVIORSCRIPTS + if (AreEqual(theTypeStr, "Behavior") && !IsTrivial(theClassStr)) { + ++theClassStr; // remove the '#' + TIdSourcePathMap::iterator theSourcePathIter = m_IdScriptMap.find(theClassStr); + if (theSourcePathIter != m_IdScriptMap.end()) { + outGraphCounter.m_AttributeCount++; + outGraphCounter.m_StringAttrCount++; + } + } + SElementData *theData = m_ParseElementManager.FindElementData(theIdStr); + + if (theData) { + TAttrMap &thePropertyMap = theData->m_PropertyMap; + + // TODO: Maybe we should make m_IdAttributesMap only stores those valid attributes and + // also those attributes that already converted to Runtime type (e.g. position to + // position.x .y .z ) + // then we can really stop calling all the IsValidAttribute all over the place + // and we can simple just use the size of the vector here. + for (TAttrMap::iterator theIter = thePropertyMap.begin(), theEnd = thePropertyMap.end(); + theIter != theEnd; ++theIter) { + if (theIter->second.m_ElementFlag == false) + continue; + TStrType thePropertyName(theIter->first); + outGraphCounter.m_AttributeCount += theIter->second.m_Arity; + if (IsStringType(theIter->second.m_DataType)) + outGraphCounter.m_StringAttrCount += 1; + } + } + + DoGraphSectionCount(inReader, outGraphCounter); + } +} + +void CUIPParserImpl::DoLogicSectionCount(qt3dsdm::IDOMReader &inReader, + SLogicSectionCount &outLogicCounter) +{ + IDOMReader::Scope __logicCountScope(inReader); + + if (inReader.MoveToFirstChild("Logic")) { + for (bool theResult = inReader.MoveToFirstChild("State"); theResult; + theResult = inReader.MoveToNextSibling("State")) { + DoStateSectionCount(inReader, 0, outLogicCounter); + } + } +} + +void CUIPParserImpl::DoStateSectionCount(qt3dsdm::IDOMReader &inReader, Q3DStudio::INT32 inStateIndex, + SLogicSectionCount &outLogicCounter) +{ + IDOMReader::Scope __slideCountScope(inReader); + + outLogicCounter.m_SlideCount++; + + INT32 theChildSlideCount = inReader.CountChildren("State"); + outLogicCounter.m_SlideElementCount++; // this slide is also an element + Q3DStudio::INT32 theChildStateIndex(inStateIndex + 1); + + for (bool theResult = inReader.MoveToFirstChild(); theResult; + theResult = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "State")) { + DoStateSectionCount(inReader, theChildStateIndex, outLogicCounter); + ++theChildStateIndex; + } else if (AreEqual(inReader.GetNarrowElementName(), "Add") + || AreEqual(inReader.GetNarrowElementName(), "Set")) { + // SlideMultipler is used as follows: + // For every element, animation or action, the slide is used to turn on/off them + // Hence, if it is inside master, it will have an entry in the master and all the child + // slides in the SlideManager ( hence, theChildSlideCount + 1 ) + // if it is local, it will have an entry in the master and it's slide, ( thus 2 ) + // the assumption made here is that State in uip is definitely 2 level, hence if it has + // no child slides, it is definitely master + INT32 theSlideMultiplier; + if (theChildSlideCount == 0) + theSlideMultiplier = 2; + else + theSlideMultiplier = theChildSlideCount + 1; + DoRefSectionCount(inReader, theSlideMultiplier, inStateIndex, outLogicCounter); + } + } +} + +//============================================================================== +/** + * @ param inNumSlideMultiplier To know how this is used, see comments on the place + *where SlideMultipler is calculated + */ +void CUIPParserImpl::DoRefSectionCount(qt3dsdm::IDOMReader &inReader, INT32 inNumSlideMultiplier, + INT32, SLogicSectionCount &outLogicCounter) +{ + IDOMReader::Scope __refCountScope(inReader); + const char8_t *theElementRef; + inReader.UnregisteredAtt("ref", theElementRef); + SElementData *theData(m_ParseElementManager.FindElementData(theElementRef)); + if (theData == NULL) { + QT3DS_ASSERT(false); + return; + } + + if (AreEqual(inReader.GetNarrowElementName(), "Add")) + outLogicCounter.m_SlideElementCount += inNumSlideMultiplier; + + // There are cases where some attributes only appear in the local slide element, but not at the + // master slide. e.g. endTime. + // For these attributes, we must make sure that it is added to the slide element attribute of + // the master, so that everything will work correctly. + // This is done via the slide force flag on the element property object. + for (TAttrMap::iterator theIter = theData->m_PropertyMap.begin(), + theEnd = theData->m_PropertyMap.end(); + theIter != theEnd; ++theIter) { + const char8_t *theAttValue = ""; + bool hasAtt = inReader.UnregisteredAtt(theIter->first.c_str(), theAttValue); + if (theIter->second.m_SlideFlag == true + && (theIter->second.m_SlideForceFlag == true || hasAtt == true)) { + outLogicCounter.m_SlideAttributeCount += theIter->second.m_Arity * inNumSlideMultiplier; + } + // Strings we may still load regardless + if (hasAtt && IsStringType(theIter->second.m_DataType)) + outLogicCounter.m_StringAttrCount += 1; + } + // Always add padding for now till I can figure out exactly why padding is needed + // and find a minimal way to handle it. + outLogicCounter.m_PaddingCount += inNumSlideMultiplier; +} + +qt3ds::runtime::SSlidePlayInformation CUIPParserImpl::GetPlayMode(qt3dsdm::IDOMReader &inReader) +{ + using qt3ds::runtime::PlayMode; + + qt3ds::runtime::SSlidePlayInformation thePlayInformation; + // Setup with the default value from the metadata + eastl::string thePlayMode = m_MetaData.GetPropertyValueString(m_MetaData.Register("Slide"), + m_MetaData.Register("playmode")); + PlayMode::Enum theMode = PlayMode::StopAtEnd; + + if (thePlayMode == "Looping") { + theMode = PlayMode::Looping; + } else if (thePlayMode == "PingPong") { + theMode = PlayMode::PingPong; + } else if (thePlayMode == "Ping") { + theMode = PlayMode::Ping; + } else if (thePlayMode == "Play Through To...") { + theMode = PlayMode::PlayThroughTo; + } + thePlayInformation.m_PlayMode = theMode; + + eastl::string theInitialPlayState = m_MetaData.GetPropertyValueString( + m_MetaData.Register("Slide"), m_MetaData.Register("initialplaystate")); + if (theInitialPlayState == "Pause") + thePlayInformation.m_Paused = true; + + const char *theAttribute; + if (inReader.Att("playmode", theAttribute)) { + if (AreEqual(theAttribute, "Play Through To...")) { + thePlayInformation.m_PlayMode = PlayMode::PlayThroughTo; + } else if (AreEqual(theAttribute, "Stop at end")) { + thePlayInformation.m_PlayMode = PlayMode::StopAtEnd; + } else if (AreEqual(theAttribute, "Looping")) { + thePlayInformation.m_PlayMode = PlayMode::Looping; + } else if (AreEqual(theAttribute, "PingPong")) { + thePlayInformation.m_PlayMode = PlayMode::PingPong; + } else if (AreEqual(theAttribute, "Ping")) { + thePlayInformation.m_PlayMode = PlayMode::Ping; + } + } + + if (inReader.Att("initialplaystate", theAttribute)) { + if (AreEqual(theAttribute, "Play")) + thePlayInformation.m_Paused = false; + else + thePlayInformation.m_Paused = true; + } + + return thePlayInformation; +} + +INT32 CUIPParserImpl::GetPlayThroughTo(INT32 inCurrentSlideIndex, qt3dsdm::IDOMReader &inReader) +{ + // Just hardcode it to Next since we know from the metadata the default is Next. + // If we want to query from MetaData, need to write accessor to get back SStringOrInt + INT32 thePlayThroughTo = inCurrentSlideIndex + 1; + + const char *theAttribute; + if (inReader.Att("playthroughto", theAttribute) && *theAttribute) { + if (AreEqual(theAttribute, "Previous")) + thePlayThroughTo = inCurrentSlideIndex - 1; + else if (AreEqual(theAttribute, "Next")) + thePlayThroughTo = inCurrentSlideIndex + 1; + else if (theAttribute[0] == '#') { + theAttribute++; + SParseSlide *theSlide = m_ParseSlideManager.FindSlide(theAttribute); + if (theSlide) + thePlayThroughTo = theSlide->m_SlideIndex; + else + Q_ASSERT(!"Slide Not Found"); + } + } + + return thePlayThroughTo; +} + +eastl::string CUIPParserImpl::GetSlideName(qt3dsdm::IDOMReader &inReader) +{ + eastl::string theSlideName; + if (!inReader.Att("name", theSlideName)) + inReader.Att("id", theSlideName); + return theSlideName; +} + +eastl::string CUIPParserImpl::GetSlideId(qt3dsdm::IDOMReader &inReader) +{ + eastl::string theSlideId; + if (!inReader.Att("id", theSlideId)) + inReader.Att("component", theSlideId); + return theSlideId; +} + +// In the event we added something to the slide, we return the element data. +SElementData *CUIPParserImpl::AddSlideElement(IPresentation &inPresentation, bool inMaster, + qt3dsdm::IDOMReader &inReader, INT32 *outMaxTime) +{ + ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); + + SElementData *theElementData = NULL; + const char8_t *theElementRef = ""; + if (inReader.UnregisteredAtt("ref", theElementRef)) + theElementData = m_ParseElementManager.FindElementData(theElementRef); + + SElement *theElement = theElementData ? theElementData->m_Element : NULL; + if (theElement) { + if (m_SlideElements.find(theElement) == m_SlideElements.end()) { + const char *theEyeball; + bool theActiveFlag = !( + inMaster || (inReader.Att("eyeball", theEyeball) && AreEqual(theEyeball, "False"))); + + m_SlideElements.insert(theElement); + theBuilder.AddSlideElement(*theElement, theActiveFlag); + m_NumSlideElements++; + if (outMaxTime) { + INT32 theElementMaxTime = 0; + SElement *theParent = theElement->GetParent(); + if (theParent && theParent->IsComponent() && theElement) { + // Ignore material durations (in practice this is always a material container) + qt3dsdm::ComposerObjectTypes::Enum composerType( + qt3dsdm::ComposerObjectTypes::Convert(theElementData->m_Type.c_str())); + if (composerType != qt3dsdm::ComposerObjectTypes::Material + && inReader.Att("endtime", theElementMaxTime) == false) { + theElementMaxTime = m_MetaData.GetPropertyValueLong( + theElementData->m_Type, m_MetaData.Register("endtime"), + theElementData->m_Class); + } + *outMaxTime = NVMax(*outMaxTime, theElementMaxTime); + } + } + } else + theElementData = NULL; + } + + return theElementData; +} + +BOOL CUIPParserImpl::LoadSlideElements(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, + bool inMaster, SElement *inComponent, INT32 *outMaxTime) +{ + BOOL theSuccess = true; + + { + IDOMReader::Scope __childScope(inReader); + eastl::string theSlideId = GetSlideId(inReader); + eastl::string theActionIdStr; + // Setup the add/set commands for this slide. + { + IDOMReader::Scope __slideScope(inReader); + // Load all the animations for this slide right now: + + SParseSlide *theSlide = m_ParseSlideManager.FindSlide(theSlideId.c_str()); + // All animations and actions added to the master slide are deactivated. + QT3DSU32 animActions = 0; + if (theSlide) { + bool canActivateFlag = !inMaster; + ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); + for (TInstanceIdAnimationMap::iterator + theInstAnimIter = theSlide->m_Animations.begin(), + theInstAnimEnd = theSlide->m_Animations.end(); + theInstAnimIter != theInstAnimEnd; ++theInstAnimIter) { + const TAnimationList &theAnimList(theInstAnimIter->second); + for (QT3DSU32 theAnimIdx = 0, theAnimEnd = theAnimList.size(); + theAnimIdx < theAnimEnd; ++theAnimIdx) { + theBuilder.AddSlideAnimAction( + true, theAnimList[theAnimIdx].m_Animation->m_AnimationIndex, + theAnimList[theAnimIdx].m_Active && canActivateFlag); + ++animActions; + } + } + // Build the actions for this slide. + for (TActionList::iterator theActionIter = theSlide->m_ActionList.begin(), + theActionEnd = theSlide->m_ActionList.end(); + theActionIter != theActionEnd; ++theActionIter) { + SParseSlideActionEntry &theActionEntry(*theActionIter); + theActionIdStr.assign(theActionEntry.m_ActionId.c_str()); + qt3ds::QT3DSI32 theActionIndex = m_ActionHelper->GetActionIndex(theActionIdStr); + for (qt3ds::QT3DSI32 idx = 0; idx < theActionEntry.m_ActionCount; ++idx) { + qt3ds::runtime::SSlideAnimAction *theSlideData = + theBuilder.AddSlideAnimAction(false, theActionIndex + idx, + theActionEntry.m_Active + && canActivateFlag); + theActionEntry.m_Actions[idx] = theSlideData; + ++animActions; + } + } + + // qt3ds::NVFoundationBase& fnd( + // inPresentation.GetApplication().GetRuntimeFactory().GetFoundation() ); + // fnd.error( QT3DS_TRACE, "Loading slide %s, %d anim actions", theSlideId.c_str(), + // animActions ); + } + for (BOOL theResult = inReader.MoveToFirstChild(); theResult; + theResult = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "Add") + || AreEqual(inReader.GetNarrowElementName(), "Set")) { + SElementData *theAddedElement = + AddSlideElement(inPresentation, inMaster, inReader, outMaxTime); + if (theAddedElement && theAddedElement->m_Element) { + LoadSlideElementAttrs(inPresentation, inMaster, *theAddedElement, inReader, + inComponent); + // This can define actions or set the active + ProcessSlideAnimAction(inPresentation, theSlideId, inMaster, inReader); + } + } + } + } + // Pull add commands from child slides into master slide with active=false + // else things won't get reset when we switch slides. + { + // All child state adds go into this object with active set to false + IDOMReader::Scope __masterScope(inReader); + for (BOOL theResult = inReader.MoveToFirstChild("State"); theResult; + theResult = inReader.MoveToNextSibling("State")) { + IDOMReader::Scope __childScope(inReader); + for (BOOL theResult = inReader.MoveToFirstChild("Add"); theResult; + theResult = inReader.MoveToNextSibling("Add")) { + // Add the slide element, setting the active flag to false. + AddSlideElement(inPresentation, inMaster, inReader, outMaxTime); + } + } + } + // Pull add commands from master slide for objects in this slide. + // We do this after we process the add/set commands for this slide so that objects already + // added + // get ignored. If we do pull an object forward then we have to set all of the force-set + // properties as well + // as account for a possible end-time difference. + { + IDOMReader::Scope __childScope(inReader); + inReader.Leave(); + if (AreEqual(inReader.GetNarrowElementName(), "State")) { + TPropertyDescAndValueList theProperties; + for (BOOL theResult = inReader.MoveToFirstChild("Add"); theResult; + theResult = inReader.MoveToNextSibling("Add")) { + theProperties.clear(); + SElementData *theData = + AddSlideElement(inPresentation, inMaster, inReader, NULL); + if (theData) { + // Add all forced attributes to this slide. + for (TAttrMap::iterator theIter = theData->m_PropertyMap.begin(), + theEnd = theData->m_PropertyMap.end(); + theIter != theEnd; ++theIter) { + if (theIter->second.m_SlideForceFlag) { + GetMetaAttribute(inPresentation, theProperties, theData->m_Type, + theIter->first, theData->m_Class, + theIter->second.m_PropertyNames); + } + } + ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); + for (TPropertyDescAndValueList::iterator theIter = theProperties.begin(); + theIter != theProperties.end(); ++theIter) { + theBuilder.AddSlideAttribute(theIter->first.GetAttributeKey(), + theIter->second); + m_NumSlideAttributes++; + } + + // Ensure the actual end time is accounted for. + if (outMaxTime && theData->m_Element) { + SElement *theParent = theData->m_Element->GetParent(); + if (theParent && theParent->IsComponent()) { + // Ignore material durations + // (in practice this is always a material container) + qt3dsdm::ComposerObjectTypes::Enum composerType( + qt3dsdm::ComposerObjectTypes::Convert(theData->m_Type.c_str())); + if (composerType != qt3dsdm::ComposerObjectTypes::Material) { + long theoutMaxTime = (long)*outMaxTime; + long theMaxTime = m_MetaData.GetPropertyValueLong( + theData->m_Type, m_MetaData.Register("endtime"), + theData->m_Class); + *outMaxTime = NVMax(theoutMaxTime, theMaxTime); + } + } + } + } + } + } + } + } + return theSuccess; +} + +BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool, + SElementData &inElementData, qt3dsdm::IDOMReader &inReader, + SElement *inComponent) +{ + ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); + + TPropertyDescAndValueList theAttributeList; + + const char8_t *theRef = ""; + inReader.Att("ref", theRef); + if (theRef && *theRef && theRef[0] == '#') + ++theRef; + bool isSet = AreEqual(inReader.GetNarrowElementName(), "Set"); + const char8_t *sourcepath; + if (inReader.UnregisteredAtt("sourcepath", sourcepath)) + AddSourcePath(sourcepath); + + // We don't force set attributes when a given component has a set command within one of its + // child states. This happens in the case of actions (but nothing else). + bool shouldForce = inElementData.m_Element != inComponent; + for (TAttrMap::iterator theIter = inElementData.m_PropertyMap.begin(), + theEnd = inElementData.m_PropertyMap.end(); + theIter != theEnd; ++theIter) { + const char8_t *theAttValue = ""; + bool hasAtt = inReader.UnregisteredAtt(theIter->first, theAttValue); + QT3DSU32 previousListSize = theAttributeList.size(); + if (hasAtt == false) { + // StartTime and EndTime in Master Slide are useless, so set it to the value in the + // metadata. + // if we look at the uip file, if the element doesn't have endTime, it means is 10000ms, + // and not really the value in the master slide + // this make it special from other attributes + if (theIter->second.m_SlideForceFlag && shouldForce) + GetMetaAttribute(inPresentation, theAttributeList, inElementData.m_Type, + theIter->first, inElementData.m_Class, + theIter->second.m_PropertyNames); + } else { + // Only use the attribute list from set blocks to set values into the slide, not from + // add attributes + // This isn't completely correct + GetAttributeList(inPresentation, theAttributeList, inElementData.m_Type, theIter->first, + inElementData.m_Class, theAttValue, theIter->second.m_PropertyNames); + } + if (isSet == false && theIter->second.m_SlideForceFlag == false) { + if (inElementData.m_Element != NULL && theIter->second.m_ElementFlag) { + for (QT3DSU32 idx = previousListSize, end = theAttributeList.size(); idx < end; + ++idx) { + UVariant *theValue = inElementData.m_Element->FindPropertyValue( + theAttributeList[idx].first.m_Name); + if (theValue) { + *theValue = theAttributeList[idx].second; + } + } + } + theAttributeList.resize(previousListSize); + } + } + for (TPropertyDescAndValueList::iterator theIter = theAttributeList.begin(); + theIter != theAttributeList.end(); ++theIter) { + theBuilder.AddSlideAttribute(theIter->first.GetAttributeKey(), theIter->second); + m_NumSlideAttributes++; + } + + return TRUE; +} + +void CUIPParserImpl::LoadAnimationTrack(IPresentation &inPresentation, SElementData &inElementData, + SParseSlideAnimationEntry &inAnimation) +{ + SElementPropertyInfo *theInfo = + m_ParseElementManager.FindProperty(inElementData, inAnimation.m_PropertyName); + if (theInfo == NULL) + return; + UINT32 theHashedKey = inAnimation.m_PropertyHash; + bool theIsDynamic = inAnimation.m_IsDynamic; + INT32 theIndex = inPresentation.GetAnimationSystem().CreateAnimationTrack( + *inElementData.m_Element, theHashedKey, theIsDynamic); + inAnimation.m_AnimationIndex = theIndex; + m_NumAnimationTracks++; + bool isRotation = theInfo->m_AdditionalType == ERuntimeAdditionalMetaDataTypeRotation; + LoadAnimationKeys(inPresentation, inAnimation, isRotation); +} + +void CUIPParserImpl::LoadAnimationKeys(IPresentation &inPresentation, + const SParseSlideAnimationEntry &inAnimation, + bool inIsRotation) +{ + + NVConstDataRef theFloatValues(inAnimation.m_KeyframeData.data(), + (qt3ds::QT3DSU32)inAnimation.m_KeyframeData.size()); + switch (inAnimation.m_AnimationType) { + case SParseSlideAnimationTypes::Linear: + LoadLinearKeys(inPresentation, theFloatValues, inIsRotation); + break; + case SParseSlideAnimationTypes::Bezier: + LoadBezierKeys(inPresentation, theFloatValues, inIsRotation); + break; + default: + QT3DS_ASSERT(false); + case SParseSlideAnimationTypes::EaseInOut: + LoadEaseInOutKeys(inPresentation, theFloatValues, inIsRotation); + break; + } +} + +BOOL CUIPParserImpl::LoadBezierKeys(IPresentation &inPresentation, NVConstDataRef &inValues, + bool inIsRotation) +{ + QT3DS_ASSERT(inValues.size() % 6 == 0); + if (inValues.size() % 6 != 0) + return FALSE; + + IAnimationSystem &theBuilder = inPresentation.GetAnimationSystem(); + + float theTime; + float theValue; + float theC1Time; + float theC1Value; + float theC2Time; + float theC2Value; + + const float *theIter = inValues.begin(); + + long theNumKeys = inValues.size() / 6; + QT3DS_ASSERT(theNumKeys > 0); + for (long theIndex = 0; theIndex < theNumKeys; ++theIndex) { + theTime = *theIter * 1000.0f; + ++theIter; + theValue = *theIter; + ++theIter; + ++theIter; // just increment the iterator, C2Time is set below + ++theIter; // just increment the iterator, C2Value is set below + theC1Time = *theIter * 1000.0f; + ++theIter; + theC1Value = *theIter; + ++theIter; + + if (theIndex == theNumKeys - 1) { + // Last keyframe + theC2Time = 0.0f; + theC2Value = 0.0f; + } else { + theC2Time = *(theIter + 2) * 1000.0f; // access the next inTangentTime + theC2Value = *(theIter + 3); // access the next inTangentValue + } + + if (inIsRotation) { + TORAD(theValue); + TORAD(theC1Value); + TORAD(theC2Value); + } + + theBuilder.AddKey(theTime, theValue, theC1Time, theC1Value, theC2Time, theC2Value); + m_NumAnimationKeys++; + } + return TRUE; +} + +BOOL CUIPParserImpl::LoadLinearKeys(IPresentation &inPresentation, NVConstDataRef &inValues, + bool inIsRotation) +{ + QT3DS_ASSERT(inValues.size() % 2 == 0); + if (inValues.size() % 2 != 0) + return FALSE; + + const float *theIter = inValues.begin(); + + long theNumKeys = inValues.size() / 2; + float *theEaseInOutValues = new float[theNumKeys * 4]; + float *theEaseInOutPtr = theEaseInOutValues; + for (long theKeyIndex = 0; theKeyIndex < theNumKeys; ++theKeyIndex) { + *theEaseInOutPtr++ = *theIter++; + *theEaseInOutPtr++ = *theIter++; + *theEaseInOutPtr++ = 0.0f; + *theEaseInOutPtr++ = 0.0f; + } + + NVConstDataRef theFloatValues = + NVConstDataRef(theEaseInOutValues, theNumKeys * 4); + BOOL theStatus = LoadEaseInOutKeys(inPresentation, theFloatValues, inIsRotation); + + delete[] theEaseInOutValues; + + return theStatus; +} + +CUIPParserImpl::SEaseInEaseOutKeyframe CUIPParserImpl::ParseEaseInOutKey(const float *&inFloatIter) +{ + CUIPParserImpl::SEaseInEaseOutKeyframe theKeyframe; + theKeyframe.m_Time = *inFloatIter; + ++inFloatIter; + theKeyframe.m_Value = *inFloatIter; + ++inFloatIter; + theKeyframe.m_EaseIn = *inFloatIter; + ++inFloatIter; + theKeyframe.m_EaseOut = *inFloatIter; + ++inFloatIter; + return theKeyframe; +} + +BOOL CUIPParserImpl::LoadEaseInOutKeys(IPresentation &inPresentation, + NVConstDataRef &inValues, bool inIsRotation) +{ + QT3DS_ASSERT(inValues.size() % 4 == 0); + if (inValues.size() % 4 != 0) + return FALSE; + + long theNumKeys = inValues.size() / 4; + + float *theBezierValues = new float[theNumKeys * 6]; + float *theBezierPtr = theBezierValues; + + SEaseInEaseOutKeyframe thePreviousKeyframe; + thePreviousKeyframe.m_Value = 0.0f; + SEaseInEaseOutKeyframe theCurrentKeyframe; + theCurrentKeyframe.m_Value = 0.0f; + SEaseInEaseOutKeyframe theNextKeyframe; + theNextKeyframe.m_Value = 0.0f; + + const float *theIter = inValues.begin(); + + if (theNumKeys > 0) { + theCurrentKeyframe = ParseEaseInOutKey(theIter); + float *theNextValuePtr = NULL; + float theNextValue; + + if (theNumKeys > 1) { + theNextKeyframe = ParseEaseInOutKey(theIter); + theNextValue = theNextKeyframe.m_Value; + theNextValuePtr = &theNextValue; + } + CreateBezierKeyframeFromEaseInEaseOutKeyframe(NULL, theCurrentKeyframe, theNextValuePtr, + theBezierPtr); + } + + for (long theKeyIndex = 1; theKeyIndex < theNumKeys; ++theKeyIndex) { + thePreviousKeyframe = theCurrentKeyframe; + theCurrentKeyframe = theNextKeyframe; + + float theLastValue = thePreviousKeyframe.m_Value; + float *theNextValuePtr = NULL; + float theNextValue; + if (theKeyIndex + 1 < theNumKeys) { + theNextKeyframe = ParseEaseInOutKey(theIter); + theNextValue = theNextKeyframe.m_Value; + theNextValuePtr = &theNextValue; + } + CreateBezierKeyframeFromEaseInEaseOutKeyframe(&theLastValue, theCurrentKeyframe, + theNextValuePtr, theBezierPtr); + } + + NVConstDataRef theFloatValues = NVConstDataRef(theBezierValues, theNumKeys * 6); + BOOL theStatus = LoadBezierKeys(inPresentation, theFloatValues, inIsRotation); + + delete[] theBezierValues; + return theStatus; +} + +inline float AnimationClamp(float inLowerBound, float inUpperBound, float inValue) +{ + if (inValue < inLowerBound) + return inLowerBound; + if (inValue > inUpperBound) + return inUpperBound; + return inValue; +} + +void CUIPParserImpl::CreateBezierKeyframeFromEaseInEaseOutKeyframe( + float *inPreviousValue, SEaseInEaseOutKeyframe &inCurrent, float *inNextValue, + float *&outBezierValues) +{ + float theValue = inCurrent.m_Value; + float theSeconds = inCurrent.m_Time; + float inSeconds = 0.f; + float inValue = 0.f; + float outSeconds = 0.f; + float outValue = 0.f; + const double oneThird = 1.0 / 3.0; + if (inPreviousValue) { + float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseIn / 100.f); + double theAmount = 1.0f - thePercent * oneThird; + inValue = *inPreviousValue + (float)(((inCurrent.m_Value - *inPreviousValue) * theAmount)); + } + if (inNextValue) { + float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseOut / 100.f); + double theAmount = thePercent * oneThird; + outValue = (float)(inCurrent.m_Value + ((*inNextValue - inCurrent.m_Value) * theAmount)); + } + + *outBezierValues++ = theSeconds; + *outBezierValues++ = theValue; + *outBezierValues++ = inSeconds; + *outBezierValues++ = inValue; + *outBezierValues++ = outSeconds; + *outBezierValues++ = outValue; +} + +BOOL CUIPParserImpl::ProcessSlideAnimAction(IPresentation &inPresentation, eastl::string &inSlideId, + bool inMaster, qt3dsdm::IDOMReader &inReader) +{ + IDOMReader::Scope __animationScope(inReader); + + BOOL theStatus = true; + + for (BOOL theResult = inReader.MoveToFirstChild("Action"); theResult; + theResult = inReader.MoveToNextSibling("Action")) { + // Get the active flag + const char *theEyeball; + bool theActiveFlag = + !(inMaster || (inReader.Att("eyeball", theEyeball) && AreEqual(theEyeball, "False"))); + theStatus &= AddSlideAction(inPresentation, inSlideId, theActiveFlag, inReader); + } + + return theStatus; +} + +BOOL CUIPParserImpl::AddSlideAction(IPresentation &, eastl::string &inSlideId, bool inActive, + qt3dsdm::IDOMReader &inReader) +{ + SParseSlide *theSlide = m_ParseSlideManager.FindSlide(inSlideId.c_str()); + if (theSlide == NULL) { + QT3DS_ASSERT(false); + return false; + } + + // Get the Action id + const char *theRef; + if (inReader.Att("ref", theRef)) { + theRef++; // remove the '#' + SParseSlideActionEntry *theEntry = m_ParseSlideManager.FindAction(*theSlide, theRef); + if (theEntry == NULL) { + QT3DS_ASSERT(false); + return false; + } + for (qt3ds::QT3DSI32 actIdx = 0; actIdx < theEntry->m_ActionCount; ++actIdx) { + if (theEntry->m_Actions[actIdx]) + theEntry->m_Actions[actIdx]->m_Active = inActive ? 1 : 0; + } + } else { + const char8_t *theActionId; + inReader.Att("id", theActionId); + SParseSlideActionEntry *theEntry = m_ParseSlideManager.FindAction(*theSlide, theActionId); + QT3DS_ASSERT(theEntry); + // Check to ensure this action was created. + (void)theEntry; + } + + return TRUE; +} + +bool CUIPParserImpl::IsStringType(ERuntimeDataModelDataType inDataType) +{ + if (inDataType == ERuntimeDataModelDataTypeStringRef + || inDataType == ERuntimeDataModelDataTypeString + || inDataType == ERuntimeDataModelDataTypeObjectRef) + return true; + return false; +} + +SElementData *CUIPParserImpl::GetElementData(TStrType inElementName) +{ + return m_ParseElementManager.FindElementData(inElementName); +} + +//============================================================================== +/** + * Helper function to to get the SElement object from the element name + */ +SElementData *CUIPParserImpl::GetElementData(const char8_t *inElementName) +{ + const char8_t *theElementName(inElementName); + if (!IsTrivial(inElementName) && inElementName[0] == '#') + ++theElementName; + return GetElementData(m_MetaData.Register(theElementName)); +} + +SElement *CUIPParserImpl::GetElement(const char8_t *inElementName) +{ + SElementData *theData(GetElementData(inElementName)); + if (theData) + return theData->m_Element; + return NULL; +} + +SElementData *CUIPParserImpl::ParseObjectRef(const eastl::string &inObjectPath, + const char8_t *inOwnerId) +{ + TStrType theId(ParseObjectRefId(inObjectPath, inOwnerId)); + return GetElementData(theId); +} + +TStrType CUIPParserImpl::ParseObjectRefId(const eastl::string &inObjectPath, + const char8_t *inOwnerId) +{ + return m_ObjectRefHelper->ParseObjectRefId(inObjectPath, inOwnerId); +} + +SElementAndType CUIPParserImpl::GetElementForID(const char *inElementName) +{ + SElementData *theData = m_ParseElementManager.FindElementData(inElementName); + if (theData == NULL) + return SElementAndType(UIPElementTypes::Unknown, NULL); + + qt3dsdm::ComposerObjectTypes::Enum theComposerType( + qt3dsdm::ComposerObjectTypes::Convert(theData->m_Type.c_str())); + UIPElementTypes::Enum theUIPType(UIPElementTypes::Unknown); + switch (theComposerType) { + case qt3dsdm::ComposerObjectTypes::Scene: + theUIPType = UIPElementTypes::Scene; + break; + case qt3dsdm::ComposerObjectTypes::Layer: + theUIPType = UIPElementTypes::Layer; + break; + case qt3dsdm::ComposerObjectTypes::Group: + theUIPType = UIPElementTypes::Group; + break; + case qt3dsdm::ComposerObjectTypes::Component: + theUIPType = UIPElementTypes::Component; + break; + case qt3dsdm::ComposerObjectTypes::Camera: + theUIPType = UIPElementTypes::Camera; + break; + case qt3dsdm::ComposerObjectTypes::Light: + theUIPType = UIPElementTypes::Light; + break; + case qt3dsdm::ComposerObjectTypes::Model: + theUIPType = UIPElementTypes::Model; + break; + case qt3dsdm::ComposerObjectTypes::Material: + theUIPType = UIPElementTypes::Material; + break; + case qt3dsdm::ComposerObjectTypes::Image: + theUIPType = UIPElementTypes::Image; + break; + case qt3dsdm::ComposerObjectTypes::Behavior: + theUIPType = UIPElementTypes::Behavior; + break; + case qt3dsdm::ComposerObjectTypes::Text: + theUIPType = UIPElementTypes::Text; + break; + case qt3dsdm::ComposerObjectTypes::Effect: + theUIPType = UIPElementTypes::Effect; + break; + case qt3dsdm::ComposerObjectTypes::CustomMaterial: + theUIPType = UIPElementTypes::CustomMaterial; + break; + case qt3dsdm::ComposerObjectTypes::ReferencedMaterial: + theUIPType = UIPElementTypes::ReferencedMaterial; + break; + case qt3dsdm::ComposerObjectTypes::RenderPlugin: + theUIPType = UIPElementTypes::RenderPlugin; + break; + case qt3dsdm::ComposerObjectTypes::Path: + theUIPType = UIPElementTypes::Path; + break; + case qt3dsdm::ComposerObjectTypes::PathAnchorPoint: + theUIPType = UIPElementTypes::PathAnchorPoint; + break; + case qt3dsdm::ComposerObjectTypes::SubPath: + theUIPType = UIPElementTypes::PathSubPath; + break; + default: + QT3DS_ASSERT(false); + break; + } + return SElementAndType(theUIPType, theData->m_Element); +} + +eastl::string CUIPParserImpl::ResolveReference(const char *inStringId, const char *inReference) +{ + SElementData *theData = ParseObjectRef(inReference, inStringId); + if (theData) { + return theData->m_Id.c_str(); + } + return eastl::string(); +} + +IRuntimeMetaData &CUIPParserImpl::GetMetaData() +{ + return m_MetaData; +} + +IUIPParser &IUIPParser::Create(const QString &inFileName, IRuntimeMetaData &inMetaData, + IInputStreamFactory &inFactory, + qt3ds::foundation::IStringTable &inStrTable) +{ + CUIPParserImpl &retval = *new CUIPParserImpl(inFileName, inMetaData, inFactory, inStrTable); + return retval; +} +} diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.h b/src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.h new file mode 100644 index 00000000..1a7ac778 --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParserImpl.h @@ -0,0 +1,664 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +/* +This is the main file responsible for conversion from the uip format into the runtime's data format. +The runtime works in a sort of global space so any object, be it an animation, action or element, +once +activated stays activated. Furthermore it is important that the runtime declare and set the fewest +number +of properties possible to still get the right answer. In order to achieve this the runtime relies +on the +rendering system to have the initial state of the entire scene graph, including state that is only +"Add" +commands declared in slides. + +Given that you understand master slide/ slide distinction, an accurate description would be to do +this: +1. Move all parse objects (actions, animations, elements) to be master objects and deactivate them. +2. Running through the list of nonmaster slides, activate the objects on those slides that would be +activated. +3. Now remove properties that are both unreferenced and applied 1 or fewer times. + + +The parsing system does this in reverse order so the passes look like: +1. Load meta data information (scripts, effects) to have a complete meta data model. +1. Build element graph. This is used during attribute lookup +2. Figure out which attributes will be on the elements in the graph by resolving behavior +references, action references and + Animations, and Set command attribute applications. + + During this pass we also build the set of actions and animations which will appear on each +slide. This involves both promoting + actions/animations that appear on the master slide to child slides and pulling +animations/actions declared on all child slides + onto the master slide. + +3. Count the objects that we will need. The runtime currently requires fixed object counts that +can't be exceeded + thus we have to effectively preallocate all runtime objects. + +4. Run through the file again and build the actual runtime datastructures. Actions and animations +are built from + an intermediate memory representation but the set commands and element activations are built +via running through + the file. + + +Care needs to be taken so the runtime can survive poorly formed or just meaningless uip files. +Studio is only *one* +system for producing UIP files, clients are free to use code generates (like ruby scripts and such) +to build their final +uip files so we need to be careful that we are as robust as possible and can tolerate gracefully +some level of incorrect +uip file data. +*/ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSUIPParser.h" +#include "Qt3DSTypes.h" +#include "Qt3DSMetadata.h" +#include "Qt3DSRenderInputStreamFactory.h" +#include "Qt3DSSlideSystem.h" +#include "Qt3DSDMDataTypes.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include +#include +#include +#include "Qt3DSElementSystem.h" +#include "Qt3DSSlideSystem.h" + +namespace qt3ds { +namespace render { + class IRefCountedInputStream; +} +} + +namespace qt3dsdm { +class IDOMReader; +class IDOMWriter; +} +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Forwards +//============================================================================== +class IPresentation; +class SElementBuilder; +class CContractBuilder; +class CAnimationBuilder; +class CLogicBuilder; +class CSlideBuilder; +class IRuntimeMetaData; +class CUIPParserActionHelper; +class CUIPParserObjectRefHelper; + +typedef eastl::vector TPropertyDescAndValueList; + +using qt3ds::render::IInputStreamFactory; +using qt3ds::render::IRefCountedInputStream; +typedef NVScopedRefCounted TInputStreamPtr; +typedef qt3ds::foundation::CRegisteredString TStrType; +using qt3ds::runtime::element::SElement; + +struct SElementPropertyInfo +{ + enum Enum { + MaxArity = 4, + }; + TStrType m_PropertyName; + ERuntimeDataModelDataType m_DataType; + ERuntimeAdditionalMetaDataType m_AdditionalType; + // Number of sub components of the property, 1-4 + qt3ds::QT3DSU32 m_Arity; + qt3ds::QT3DSU32 m_PropertyHashes[MaxArity]; + CRegisteredString m_PropertyNames[MaxArity]; + bool m_ElementFlag; // True if this property exists on the element. Some properties do not. + bool m_SlideFlag; // True if this property exists on the slides at all. + // starttime,endtime are forced to be on the slides whether they are in the UIP or not. + bool m_SlideForceFlag; // True if this property is *forced* on the slides whether it needs to be + // there or not + + SElementPropertyInfo(TStrType inPropName) + : m_PropertyName(inPropName) + , m_DataType(ERuntimeDataModelDataTypeNone) + , m_Arity(0) + , m_ElementFlag(false) + , m_SlideFlag(false) + , m_SlideForceFlag(false) + { + memZero(m_PropertyHashes, sizeof(m_PropertyHashes)); + } + bool operator<(const SElementPropertyInfo &inOther) const + { + return m_PropertyName < inOther.m_PropertyName; + } +}; + +typedef eastl::hash_map TAttrMap; + +struct SElementData +{ + SElement *m_Element; + TStrType m_Id; + TStrType m_Type; + TStrType m_Class; + TAttrMap m_PropertyMap; + + SElementData(TStrType inId) + : m_Element(NULL) + , m_Id(inId) + { + } + void SetElement(SElement *inElement, TStrType inType, TStrType inClass) + { + m_Element = inElement; + m_Type = inType; + m_Class = inClass; + } +}; + +typedef eastl::hash_map TIdElementMap; + +struct SParseElementManager +{ + IRuntimeMetaData &m_MetaData; + TIdElementMap m_ElementMap; + // Temporary variables for various algorithms + eastl::string m_Workspace; + eastl::vector m_PropertyList; + qt3ds::foundation::IStringTable &m_StringTable; + + SParseElementManager(IRuntimeMetaData &inMetaData, qt3ds::foundation::IStringTable &inStrTable) + : m_MetaData(inMetaData) + , m_StringTable(inStrTable) + { + } + TStrType RegisterStr(const char8_t *inStr); + SElementData &GetOrCreateElementData(const char8_t *inElemIdOrRef, const char8_t *inElemType, + const char8_t *inElemClassId); + SElementData *FindElementData(const char8_t *inIdOrRef); + // We don't allow creation of properties that don't exist in the meta data in the first place. + SElementPropertyInfo *GetOrCreateProperty(SElementData &inData, const char8_t *inPropertyName); + SElementPropertyInfo *GetOrCreateProperty(const char8_t *inIdOrRef, const char8_t *inElemType, + const char8_t *inElemClassId, + const char8_t *inPropertyName); + SElementPropertyInfo *FindProperty(SElementData &inElement, const char8_t *inPropertyName); + SElementPropertyInfo *FindProperty(const char8_t *inIdOrRef, const char8_t *inPropertyName); + eastl::pair + FindPropertyWithSubIndex(SElementData &inElement, const char8_t *inPropertyName); + // Attribute marking stage; mark which attributes will be kept on elements at all. + void MarkAttributeAsReferenced(SElementData &inElement, const char8_t *inPropertyName); + void MarkAttributeAsReferenced(const char8_t *inElement, const char8_t *inPropertyName); + void MarkAllAttributesAsReferenced(SElementData &inElement, bool searchParent = false); +}; + +struct SParseSlideActionEntry +{ + TStrType m_SlideId; + TStrType m_ActionId; + qt3ds::QT3DSI32 m_ActionCount; + bool m_Active; + qt3ds::runtime::SSlideAnimAction *m_Actions[SElementPropertyInfo::MaxArity]; + + SParseSlideActionEntry(TStrType inSlideId, TStrType inActionId, qt3ds::QT3DSI32 inActionCount, + bool inActive) + : m_SlideId(inSlideId) + , m_ActionId(inActionId) + , m_ActionCount(inActionCount) + , m_Active(inActive) + { + memZero(m_Actions, sizeof(m_Actions)); + } + SParseSlideActionEntry() + : m_ActionCount(0) + , m_Active(false) + { + } + // Partial equals, used for finding object in vector. + bool operator==(const SParseSlideActionEntry &inOther) const + { + return m_SlideId == inOther.m_SlideId && m_ActionId == inOther.m_ActionId; + } +}; + +typedef eastl::vector TActionList; + +struct SParseSlideAnimationTypes +{ + enum Enum { + NoAnimation = 0, + Linear, + EaseInOut, + Bezier, + }; +}; + +struct SParseSlideAnimationEntry +{ + TStrType m_SlideId; + TStrType m_InstanceId; + TStrType m_PropertyName; + qt3ds::QT3DSU32 m_PropertyHash; + qt3ds::QT3DSI32 m_AnimationIndex; + eastl::vector m_KeyframeData; + SParseSlideAnimationTypes::Enum m_AnimationType; + bool m_IsDynamic; + + SParseSlideAnimationEntry() + : m_AnimationIndex(-1) + , m_KeyframeData("") + , m_AnimationType(SParseSlideAnimationTypes::NoAnimation) + , m_IsDynamic(false) + { + } + SParseSlideAnimationEntry(TStrType inSlideId, TStrType inInstanceId, TStrType inPropertyName, + qt3ds::QT3DSU32 inPropHash, SParseSlideAnimationTypes::Enum inAnimType, + const float *inKeyframeData, qt3ds::QT3DSU32 inNumFloats, bool inIsDynamic) + : m_SlideId(inSlideId) + , m_InstanceId(inInstanceId) + , m_PropertyName(inPropertyName) + , m_PropertyHash(inPropHash) + , m_AnimationType(inAnimType) + , m_IsDynamic(inIsDynamic) + { + m_KeyframeData.insert(m_KeyframeData.begin(), inKeyframeData, inKeyframeData + inNumFloats); + } +}; + +struct SParseAnimationRef +{ + TStrType m_SlideId; + TStrType m_InstanceId; + TStrType m_PropertyName; + bool m_Active; + const SParseSlideAnimationEntry *m_Animation; + + SParseAnimationRef(TStrType inSlideId, TStrType inInstanceId, TStrType inPropName, + const SParseSlideAnimationEntry *inAnimation, bool inActive) + : m_SlideId(inSlideId) + , m_InstanceId(inInstanceId) + , m_PropertyName(inPropName) + , m_Active(inActive) + , m_Animation(inAnimation) + { + } + SParseAnimationRef() + : m_Active(false) + , m_Animation(NULL) + { + } + // Partial equals, used for finding object in vector. + bool operator==(const SParseAnimationRef &inOther) const + { + return m_SlideId == inOther.m_SlideId && m_InstanceId == inOther.m_InstanceId + && m_PropertyName == inOther.m_PropertyName; + } +}; + +typedef eastl::vector TAnimationList; + +typedef eastl::hash_map TInstanceIdAnimationMap; + +struct SParseSlide +{ + TStrType m_SlideId; + qt3ds::QT3DSI32 m_SlideIndex; + TActionList m_ActionList; + TInstanceIdAnimationMap m_Animations; + + SParseSlide(TStrType inId, qt3ds::QT3DSI32 inSlideIndex) + : m_SlideId(inId) + , m_SlideIndex(inSlideIndex) + { + } + SParseSlide() {} +}; + +typedef eastl::hash_map TSlideIdToParseSlideMap; + +struct SParseSlideManager +{ + IRuntimeMetaData &m_MetaData; + SParseElementManager &m_ElementManager; + TSlideIdToParseSlideMap m_SlideMap; + eastl::vector m_Animations; + qt3ds::QT3DSI32 m_SlideAnimationCount; + qt3ds::QT3DSI32 m_AnimationKeyframeCount; + qt3ds::QT3DSI32 m_ActionCount; + eastl::vector m_KeyframeParseFloatBuffer; + eastl::string m_KeyframeParseBuffer; + + SParseSlideManager(IRuntimeMetaData &inMD, SParseElementManager &inElemMgr) + : m_MetaData(inMD) + , m_ElementManager(inElemMgr) + , m_SlideAnimationCount(0) + , m_AnimationKeyframeCount(0) + , m_ActionCount(0) + { + } + ~SParseSlideManager(); + TStrType RegisterId(const char8_t *inStr); + TStrType RegisterStr(const char8_t *inStr) { return m_ElementManager.RegisterStr(inStr); } + SParseSlide &GetOrCreateSlide(const char8_t *inSlideId, qt3ds::QT3DSI32 inSlideIndex); + SParseSlide *FindSlide(const char8_t *inSlideId); + // Create an animation and reference that animation + void SetAnimationData(SParseSlide &inSlide, const char8_t *inInstanceId, + const char8_t *inPropertyName, const char8_t *inKeyframeData, + SParseSlideAnimationTypes::Enum inType, bool inIsDynamic, + bool inIsActive); + // Reference an animation. + void ReferenceAnimation(SParseSlide &inSlide, const SParseSlideAnimationEntry &inSource, + bool inIsActive); + TAnimationList *GetAnimationsForInstance(SParseSlide &inSlide, const char8_t *inInstanceId); + SParseSlideActionEntry &GetOrCreateAction(SParseSlide &inSlide, const char8_t *inActionId, + qt3ds::QT3DSI32 inActionCount, bool inEyeball); + SParseSlideActionEntry *FindAction(SParseSlide &inSlide, const char8_t *inActionId); +}; + +//============================================================================== +/** + * @class CUIPParserImpl + * @brief Class for parsing UIP file + */ +class CUIPParserImpl : public IUIPParser +{ + + typedef eastl::basic_string TNarrowStr; + + //============================================================================== + // Fields + //============================================================================== +protected: + std::shared_ptr m_DOMReader; + std::shared_ptr m_DOMWriter; + IRuntimeMetaData &m_MetaData; ///< Reference to Metadata + IInputStreamFactory &m_InputStreamFactory; + SParseElementManager m_ParseElementManager; ///< Map of id, SElement* + SParseSlideManager m_ParseSlideManager; + + CUIPParserActionHelper *m_ActionHelper; ///< Action Helper + CUIPParserObjectRefHelper *m_ObjectRefHelper; ///< Object Reference Helper + + typedef eastl::set TAddedSlideElements; + TAddedSlideElements m_SlideElements; ///< Caching of slide elements added, so that we don't need + ///to pass this around + + typedef eastl::map TIdSourcePathMap; + TIdSourcePathMap m_IdScriptMap; ///< Map of the class id and script sourcepath + + typedef eastl::map TIdClassMap; + TIdClassMap m_IdClassMap; ///< Map of id and class reference + + typedef eastl::set TStringSet; + typedef eastl::vector TStringVector; + + TStringSet m_SourcePathSet; + TStringVector m_SourcePathList; + + struct SElementRefCache + { + SElementData *m_Element; + eastl::string m_Name; + eastl::string m_Value; + }; + eastl::vector m_ElementRefCache; ///< Cache those element refs in the scene + ///graph that needs to be patch later + + struct SEaseInEaseOutKeyframe + { + float m_Time; + float m_Value; + float m_EaseIn; + float m_EaseOut; + }; + + struct SGraphSectionCount + { + INT32 m_ElementCount; + INT32 m_ComponentCount; + INT32 m_AttributeCount; + INT32 m_StringAttrCount; + + SGraphSectionCount() + : m_ElementCount(0) + , m_ComponentCount(0) + , m_AttributeCount(0) + , m_StringAttrCount(0) + { + } + }; + + struct SLogicSectionCount + { + INT32 m_SlideCount; + INT32 m_SlideElementCount; + INT32 m_SlideAttributeCount; + INT32 m_StringAttrCount; + INT32 m_PaddingCount; + + SLogicSectionCount() + : m_SlideCount(0) + , m_SlideElementCount(0) + , m_SlideAttributeCount(0) + , m_StringAttrCount(0) + , m_PaddingCount(0) + { + } + }; + + struct SActionSectionCount + { + INT32 m_TriggerElementCount; + INT32 m_TriggerEventCount; + INT32 m_ActionCount; + INT32 m_StringAttrCount; + INT32 m_CustomParamCount; + + SActionSectionCount() + : m_TriggerElementCount(0) + , m_TriggerEventCount(0) + , m_ActionCount(0) + , m_StringAttrCount(0) + , m_CustomParamCount(0) + { + } + }; + + long m_NumGraphElements; /// eclee testing only, must remove + long m_NumGraphComponents; /// eclee testing only, must remove + long m_NumGraphAttributes; /// eclee testing only, must remove + long m_NumSlides; /// eclee testing only, must remove + long m_NumSlideElements; /// eclee testing only, must remove + long m_NumSlideAttributes; /// eclee testing only, must remove + long m_NumAnimationTracks; /// eclee testing only, must remove + long m_NumAnimationKeys; /// eclee testing only, must remove + long m_NumSlideAnimations; /// eclee testing only, must remove + long m_NumSlideActions; /// klarinda testing only, must remove + + // temporarily this is here + qt3ds::foundation::MemoryBuffer m_TempBuffer; + qt3ds::foundation::MemoryBuffer m_ValueBuffer; + + IPresentation *m_CurrentPresentation; + + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CUIPParserImpl(const QString &inFileName, IRuntimeMetaData &inMetaData, + IInputStreamFactory &inFactory, qt3ds::foundation::IStringTable &inStringTable); + virtual ~CUIPParserImpl(); + +public: // Parse UIP file + BOOL Load(IPresentation &inPresentation, + NVConstDataRef inStateReferences, + qt3ds::state::debugger::ISceneGraphRuntimeDebugger &debugger) override; + qt3dsdm::IDOMReader &GetDOMReader() override; + IRuntimeMetaData &GetMetaData() override; + SElementAndType GetElementForID(const char *inStringId) override; + eastl::string ResolveReference(const char *inStringId, const char *inReferance) override; + NVConstDataRef GetSourcePaths() const override + { + return NVConstDataRef(m_SourcePathList.data(), m_SourcePathList.size()); + } + +protected: // Operation + BOOL LoadProjectSettings(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); + BOOL LoadClasses(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); + BOOL LoadGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); + BOOL LoadSceneGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, + qt3ds::runtime::element::SElement *inNewStyleParent = NULL); + BOOL LoadLogic(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); + BOOL LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); + +protected: // Memory Counter + void ComputeAndReserveMemory(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); + void DoGraphSectionCount(qt3dsdm::IDOMReader &inReader, SGraphSectionCount &outGraphCounter); + void DoLogicSectionCount(qt3dsdm::IDOMReader &inReader, SLogicSectionCount &outLogicCounter); + void DoStateSectionCount(qt3dsdm::IDOMReader &inReader, INT32 inSlideIndex, + SLogicSectionCount &outLogicCounter); + void DoRefSectionCount(qt3dsdm::IDOMReader &inReader, INT32 inNumSlideMultiplier, + INT32 inSlideIndex, SLogicSectionCount &outLogicCounter); + +protected: // Scene graph heler + void CacheGraphRequiredAttributes(qt3dsdm::IDOMReader &inReader); + BOOL CacheLogicRequiredAttributes(qt3dsdm::IDOMReader &inReader, qt3ds::QT3DSI32 inSlideIndex = 0, + SParseSlide *inParentSlide = NULL); + void CacheClassRequiredAttributes(qt3dsdm::IDOMReader &inReader); + void CacheClassSceneAttributes(qt3dsdm::IDOMReader &inReader); + void CacheClassStateAttributes(qt3dsdm::IDOMReader &inReader); + void AddElementRefToPatch(TPropertyDescAndValueList &outDescList, SElementData &inElement, + const char *inName, const char *inValue); + void PatchSceneElementRef(); + +protected: // Slide helper + BOOL LoadState(IPresentation &inPresentation, SElement *inComponent, INT32 inSlideIndex, + qt3dsdm::IDOMReader &inReader); + qt3ds::runtime::SSlidePlayInformation GetPlayMode(qt3dsdm::IDOMReader &inReader); + INT32 GetPlayThroughTo(INT32 inCurrentSlideIndex, qt3dsdm::IDOMReader &inReader); + eastl::string GetSlideName(qt3dsdm::IDOMReader &inReader); + eastl::string GetSlideId(qt3dsdm::IDOMReader &inReader); + BOOL LoadSlideElements(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, + bool inMaster, SElement *inComponent, INT32 *outMaxTime = NULL); + SElementData *AddSlideElement(IPresentation &inPresentation, bool inMaster, + qt3dsdm::IDOMReader &inReader, INT32 *outMaxTime = NULL); + BOOL LoadSlideElementAttrs(IPresentation &inPresentation, bool inMaster, + SElementData &inElementData, qt3dsdm::IDOMReader &inReader, + SElement *inComponent); + BOOL ProcessStateRef(IPresentation &inPresentation, SElement *inComponent, bool inMaster, + qt3dsdm::IDOMReader &inReader); + +protected: // Animation helper + void LoadAnimationTrack(IPresentation &inPresentation, SElementData &inElementData, + SParseSlideAnimationEntry &inAnimation); + void LoadAnimationKeys(IPresentation &inPresentation, + const SParseSlideAnimationEntry &inAnimation, bool inIsRotation); + BOOL LoadBezierKeys(IPresentation &inPresentation, NVConstDataRef &inValues, + bool inIsRotation); + BOOL LoadLinearKeys(IPresentation &inPresentation, NVConstDataRef &inValues, + bool inIsRotation); + BOOL LoadEaseInOutKeys(IPresentation &inPresentation, NVConstDataRef &inValues, + bool inIsRotation); + SEaseInEaseOutKeyframe ParseEaseInOutKey(const float *&inFloatIter); + BOOL ProcessSlideAnimAction(IPresentation &inPresentation, eastl::string &inSlideId, + bool inMaster, qt3dsdm::IDOMReader &inReader); + BOOL AddSlideAction(IPresentation &inPresentation, eastl::string &inSlideId, bool inActive, + qt3dsdm::IDOMReader &inReader); + void CreateBezierKeyframeFromEaseInEaseOutKeyframe(float *inPreviousValue, + SEaseInEaseOutKeyframe &inCurrent, + float *inNextValue, float *&outBezierValues); + +protected: // Helper methods + bool IsStringType(ERuntimeDataModelDataType inDataType); + void GetAttributeList(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, + TStrType inType, TStrType inName, TStrType inClassId, const char *inValue, + CRegisteredString *inPropNameStrs); + void GetAttributeList(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, + ERuntimeDataModelDataType inDataType, + ERuntimeAdditionalMetaDataType inAdditionalType, const char *inName, + const char *inValue, CRegisteredString *inPropNameStrs); + + SElementData *GetElementData(TStrType inElementName); + SElementData *GetElementData(const char8_t *inElementName); + SElement *GetElement(const char8_t *inElementName); + // Returns the data type and a boolean indicating if this attribute is actually used on a + // particular slide. + eastl::pair + GetAttributeType(const char8_t *inElementName, const char8_t *inPropertyName, + const SElementData &inElementData); + SElementData *ParseObjectRef(const eastl::string &inObjectPath, const char8_t *inOwnerId); + TStrType ParseObjectRefId(const eastl::string &inObjectPath, const char8_t *inOwnerId); + + void GetMetaAttribute(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, + TStrType inType, TStrType inName, TStrType inClassId, + CRegisteredString *inAttStrNames); + +protected: + void AddFloatAttribute(TPropertyDescAndValueList &outDescList, CRegisteredString inAttStrName, + float &inValue); + void AddLongAttribute(TPropertyDescAndValueList &outDescList, CRegisteredString inAttStrName, + qt3ds::QT3DSI32 &inValue); + void AddBoolAttribute(TPropertyDescAndValueList &outDescList, CRegisteredString inAttStrName, + bool &inValue); + void AddFloat2Attribute(TPropertyDescAndValueList &outDescList, + CRegisteredString *inAttStrNames, qt3dsdm::SFloat2 &inValue); + void AddFloat3Attribute(TPropertyDescAndValueList &outDescList, + ERuntimeAdditionalMetaDataType inAdditionalType, + CRegisteredString *inAttStrNames, qt3dsdm::SFloat3 &inValue); + void AddStringAttribute(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, const char *inValue); + void AddElementRefAttribute(TPropertyDescAndValueList &outDescList, + CRegisteredString inAttStrName, SElement *inElement); + + void AddSourcePath(const char *inValue) + { + if (m_SourcePathSet.find(inValue) == m_SourcePathSet.end()) { + m_SourcePathSet.insert(inValue); + m_SourcePathList.push_back(eastl::string(inValue)); + } + } + +public: // + void release() override { delete this; } + + //============================================================================== + // Friends + //============================================================================== + friend class CUIPParserActionHelper; +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.cpp b/src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.cpp new file mode 100644 index 00000000..19af2a9d --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.cpp @@ -0,0 +1,1005 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "RuntimePrefix.h" +#ifdef EA_PLATFORM_WINDOWS +#pragma warning(disable : 4100) // std::variant +#pragma warning(disable : 4396) // specializer warning nonsense +#endif + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSUIPParserObjectRefHelper.h" + +#include "Qt3DSDMPrefix.h" +#include "Qt3DSDMXML.h" +#include "Qt3DSMetadata.h" +using namespace qt3dsdm; + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +// Constants +//============================================================================== +static const char PATH_DELIMITER = '.'; // can only be single char! +static const char PATH_LINE_END = '\n'; + +//============================================================================== +/** + * Constructor + */ +CUIPParserObjectRefHelper::CUIPParserObjectRefHelper(IRuntimeMetaData &inMetaData) + : m_MetaData(inMetaData) + , m_MaterialStr(m_MetaData.Register("Material")) +{ + BuildImageNamePropertyList(); + + if (m_LayerImageIdToNameMap.empty()) { + { + TLightProbeAndNamePair theNamePair = + eastl::make_pair("Layer_lightprobe", "lightprobe"); + m_LayerImageIdToNameMap.insert(theNamePair); + } + { + TLightProbeAndNamePair theNamePair = + eastl::make_pair("Layer_lightprobe2", "lightprobe2"); + m_LayerImageIdToNameMap.insert(theNamePair); + } + } +} + +//============================================================================== +/** + * Destructor + */ +CUIPParserObjectRefHelper::~CUIPParserObjectRefHelper() +{ + // Delete SGraphNode + for (TGraphNodeMap::iterator theIter = m_GraphNodeMap.begin(); theIter != m_GraphNodeMap.end(); + ++theIter) + delete theIter->second; + m_GraphNodeMap.clear(); + m_RootNode = NULL; +} + +namespace { + void StoreTopLevelAliasAttributes( + IDOMReader &inReader, + eastl::vector> &copiedAttributes) + { + for (eastl::pair att = inReader.GetNarrowFirstAttribute(); + !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { + if (!AreEqual(att.first, "scale") && !AreEqual(att.first, "position") + && !AreEqual(att.first, "rotation") && !AreEqual(att.first, "pivot") + && !AreEqual(att.first, "endtime") && !AreEqual(att.first, "eyeball") + && !AreEqual(att.first, "ref") && !AreEqual(att.first, "id") + && !AreEqual(att.first, "name") && !AreEqual(att.first, "orientation") + && !AreEqual(att.first, "rotationorder")) // note that sourcepath does come through. + { + copiedAttributes.push_back(eastl::make_pair(att.first, att.second)); + } + } + } +} + +void CUIPParserObjectRefHelper::CacheGraph(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter) +{ + { + // First, we parse Graph section to build the scene graph + IDOMReader::Scope __graphScope(inReader); + inReader.MoveToFirstChild("Graph"); + CacheSceneGraph(inReader); + } + void *logicScopeItem = NULL; + { + // Next, we parse Logic section to update the node name and image information + IDOMReader::Scope __logicScope(inReader); + inReader.MoveToFirstChild("Logic"); + logicScopeItem = inReader.GetScope(); + CacheStateGraph(inReader); + } + if (m_SceneGraphAliasList.empty() == false) { + IDOMReader::Scope __aliasScope(inReader); + // Now we expand aliases + eastl::hash_map oldToNewIdMap; + std::shared_ptr theFactory = inWriter.GetFactory(); + std::shared_ptr theStrTable = inReader.GetStringTable(); + qt3dsdm::SDOMElement *theSlidesRoot = theFactory->NextElement("AliasSlides"); + eastl::pair, std::shared_ptr> + slideWriterReaderPair = + qt3dsdm::IDOMWriter::CreateDOMWriter(theFactory, *theSlidesRoot, theStrTable); + std::shared_ptr slideWriter = slideWriterReaderPair.first; + + { + IDOMReader::Scope __loopScope(inReader); + for (QT3DSU32 idx = 0, end = m_SceneGraphAliasList.size(); idx < end; ++idx) { + inReader.SetScope(m_SceneGraphAliasList[idx]); + const char8_t *reference; + SGraphNode *referencedNode = NULL; + const char8_t *theIdStr; + inReader.Att("id", theIdStr); + SGraphNode *aliasNode = NULL; + TGraphNodeMap::iterator iter = m_GraphNodeMap.find(m_MetaData.Register(theIdStr)); + if (iter != m_GraphNodeMap.end()) + aliasNode = iter->second; + + if (inReader.UnregisteredAtt("referencednode", reference)) { + TStrType theSourceElemId = ParseObjectRefId(reference, theIdStr); + iter = m_GraphNodeMap.find(theSourceElemId); + if (iter != m_GraphNodeMap.end()) + referencedNode = iter->second; + } + if (referencedNode == NULL || aliasNode == NULL) { + QT3DS_ASSERT(false); + continue; + } + inReader.SetScope(referencedNode->m_ReaderContext); + oldToNewIdMap.clear(); + std::shared_ptr theFactory = inWriter.GetFactory(); + std::shared_ptr theStrTable = inReader.GetStringTable(); + qt3dsdm::SDOMElement *theRoot = theFactory->NextElement(inReader.GetElementName()); + std::shared_ptr copyWriter = + qt3dsdm::IDOMWriter::CreateDOMWriter(theFactory, *theRoot, theStrTable).first; + + // Step one is just to copy the scene graph generating ids. + SGraphNode *theParent = aliasNode->m_Parent; + aliasNode->m_Class = referencedNode->m_Class; + aliasNode->m_Type = referencedNode->m_Type; + // Copy the alias id + copyWriter->Att("id", theIdStr); + eastl::vector> copiedAttributes; + StoreTopLevelAliasAttributes(inReader, copiedAttributes); + for (QT3DSU32 idx = 0, end = copiedAttributes.size(); idx < end; ++idx) { + copyWriter->Att(copiedAttributes[idx].first.c_str(), + copiedAttributes[idx].second.c_str()); + } + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "Alias")) + continue; + qt3dsdm::IDOMReader::Scope __loopScoper(inReader); + qt3dsdm::IDOMWriter::Scope writerScope(*copyWriter, + inReader.GetNarrowElementName()); + CopySceneGraph(inReader, *copyWriter, *slideWriter, oldToNewIdMap, + aliasNode->m_Name.c_str(), theIdStr, *aliasNode); + } + if (referencedNode->m_MasterSlide) { + inReader.SetScope(referencedNode->m_MasterSlide); + CopyStates(inReader, *slideWriter, oldToNewIdMap, aliasNode->m_Name.c_str(), + theIdStr); + } + // Set the scope to point at the alias node. + inReader.SetScope(aliasNode->m_ReaderContext); + inWriter.ReplaceCurrent(*theRoot); + // Now find the owning component. + SGraphNode *theComponent = theParent; + while (theComponent && theComponent->m_MasterSlide == NULL) + theComponent = theComponent->m_Parent; + + if (theComponent && theComponent->m_MasterSlide) { + inReader.SetScope(theComponent->m_MasterSlide); + // Copy any state commands that have entries in the old to new map. + CopyStateCommands(inReader, inWriter, oldToNewIdMap, aliasNode->m_Name.c_str(), + referencedNode->m_Id, theIdStr); + } else { + QT3DS_ASSERT(false); + } + } + } // End of loop scope. + + { + // Next, we parse Logic section to update the node name and image information + { + IDOMReader::Scope __logicScope(inReader); + inReader.SetScope(theSlidesRoot); + // Cache the new items and their names and such. + CacheStateGraph(inReader); + } + + inReader.MoveToFirstChild("Logic"); + inWriter.AppendChildren(*theSlidesRoot); + } + + /* +#if defined _DEBUG && defined _WIN32 + { + qt3dsdm::SDOMElement* theElem = inWriter.GetTopElement(); + { + qt3ds::foundation::CFileSeekableIOStream theWriter( "c:\\temp.xml", +FileWriteFlags() ); + qt3dsdm::CDOMSerializer::Write( *theElem, theWriter ); + } + } +#endif + */ + } + +} + +void CUIPParserObjectRefHelper::CacheSceneGraph(IDOMReader &inReader, SGraphNode *inParent) +{ + IDOMReader::Scope __childScope(inReader); + + // build out the graph. + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "Alias")) { + CacheSceneGraphNode(inReader, inParent); + m_SceneGraphAliasList.push_back(inReader.GetScope()); + } else { + SGraphNode &theNode(CacheSceneGraphNode(inReader, inParent)); + CacheSceneGraph(inReader, &theNode); + } + } +} + +CUIPParserObjectRefHelper::SGraphNode & +CUIPParserObjectRefHelper::CacheSceneGraphNode(qt3dsdm::IDOMReader &inReader, SGraphNode *inParent) +{ + SGraphNode *theNode = new SGraphNode(); + const char8_t *theIdStr; + inReader.Att("id", theIdStr); + theNode->m_Id = m_MetaData.Register(theIdStr); + theNode->m_Type = m_MetaData.Register(inReader.GetNarrowElementName()); + const char8_t *theClassStr; + inReader.Att("class", theClassStr); + theNode->m_Class = m_MetaData.Register(theClassStr); + const char *theNameStr; + theNode->m_ReaderContext = inReader.GetScope(); + + if (inParent && inParent->m_Type == m_MetaData.Register("Layer") + && theNode->m_Type == m_MetaData.Register("Image")) { + TLightProbeIdToNameMap::iterator theFind = m_LayerImageIdToNameMap.find(theIdStr); + if (theFind != m_LayerImageIdToNameMap.end()) + theNode->m_Name = m_MetaData.Register(theFind->second.c_str()); + } else if (!inReader.Att("name", theNameStr)) { + Option theNameStrOpt = m_MetaData.GetPropertyValueString( + theNode->m_Type, m_MetaData.Register("name"), theNode->m_Class); + if (theNameStrOpt.hasValue()) + theNode->m_Name = m_MetaData.Register(theNameStrOpt->c_str()); + } else + theNode->m_Name = m_MetaData.Register(theNameStr); + + if (inParent) { + theNode->m_Parent = inParent; + inParent->m_Children.push_back(theNode); + } else { + m_RootNode = theNode; + } + + m_GraphNodeMap[theNode->m_Id] = theNode; + return *theNode; +} + +void CUIPParserObjectRefHelper::CacheStateGraph(IDOMReader &inReader) +{ + IDOMReader::Scope __childScope(inReader); + const char8_t *component; + if (inReader.UnregisteredAtt("component", component)) { + TGraphNodeMap::iterator iter = m_GraphNodeMap.find(m_MetaData.Register(component + 1)); + if (iter != m_GraphNodeMap.end()) { + iter->second->m_MasterSlide = inReader.GetScope(); + } + } + + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "State")) + CacheStateGraph(inReader); + else if (AreEqual(inReader.GetNarrowElementName(), "Add") + || AreEqual(inReader.GetNarrowElementName(), "Set")) { + const char *theRef; + const char *theName; + if (inReader.Att("ref", theRef)) { + theRef++; // remove the '#' + SGraphNode *theNode = GetNode(theRef); + if (theNode) { + // Overwrite the name. This assumes that "name" property is always linked. + if (inReader.Att("name", theName)) { + theNode->m_Name = m_MetaData.Register(theName); + } + + // Special case for material. Image properties refer to instances. + // For example: Scene.Layer.Rectangle.Material.diffusemap.rotationuv -> + // diffusemap refers to Image instance + // So if we find image instance, overwrite the name of the image with the + // property name. + // This assumes that user can't rename image property + if (theNode->m_Type == m_MaterialStr && !theNode->m_Children.empty()) { + for (TImageNamePropertyList::iterator theProp = + m_ImageNamePropertyList.begin(); + theProp != m_ImageNamePropertyList.end(); ++theProp) { + const char *theImageInstance; + if (inReader.Att(theProp->c_str(), theImageInstance)) { + ++theImageInstance; // remove the '#' + SGraphNode *theImageNode = GetNode(theImageInstance); + QT3DS_ASSERT(theImageNode && theImageNode->m_Parent == theNode); + if (theImageNode) + theImageNode->m_Name = *theProp; + } + } + } + + } + } + } + } +} + +void CUIPParserObjectRefHelper::CopySceneGraph(qt3dsdm::IDOMReader &inReader, + qt3dsdm::IDOMWriter &inWriter, + qt3dsdm::IDOMWriter &inSlideWriter, + TStrToStrMap &inMap, const char *inAliasName, + const char *inAliasId, SGraphNode &inParent) +{ + qt3dsdm::IDOMReader::Scope __graphScope(inReader); + // Assume the element itself is already copied. + // Run through attributes and duplicate them, but for any id attributes generate a new id. + const char8_t *tempItem; + if (!inReader.Att("id", tempItem)) { + QT3DS_ASSERT(false); + return; + } + SGraphNode *theParent = &inParent; + eastl::string idGenerator(inAliasName); + idGenerator.append("-"); + idGenerator.append(tempItem); + while (m_GraphNodeMap.find(m_MetaData.Register(idGenerator.c_str())) != m_GraphNodeMap.end()) + idGenerator.append("_"); + inWriter.Att("id", idGenerator.c_str()); + TStrType srcId = m_MetaData.Register(tempItem); + TStrType newId = m_MetaData.Register(idGenerator.c_str()); + inMap[srcId] = newId; + SGraphNode *srcNode = m_GraphNodeMap.find(srcId)->second; + SGraphNode *newNode = new SGraphNode(); + newNode->m_Class = srcNode->m_Class; + newNode->m_Id = newId; + newNode->m_Name = srcNode->m_Name; + newNode->m_Type = srcNode->m_Type; + newNode->m_Parent = &inParent; + theParent = newNode; + m_GraphNodeMap[newId] = newNode; + inParent.m_Children.push_back(newNode); + + { + qt3dsdm::IDOMReader::Scope __childrenScope(inReader); + + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "Alias")) + continue; + qt3dsdm::IDOMWriter::Scope __newNode(inWriter, inReader.GetNarrowElementName()); + CopySceneGraph(inReader, inWriter, inSlideWriter, inMap, inAliasName, inAliasId, + *theParent); + } + } + TGraphNodeMap::iterator iter = m_GraphNodeMap.find(m_MetaData.Register(tempItem)); + if (iter == m_GraphNodeMap.end()) { + QT3DS_ASSERT(false); + return; + } + SGraphNode *targetNode = iter->second; + + for (eastl::pair att = inReader.GetNarrowFirstAttribute(); + !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { + if (AreEqual(att.first, "id")) + continue; + Q3DStudio::ERuntimeDataModelDataType theDataType = m_MetaData.GetPropertyType( + targetNode->m_Type, m_MetaData.Register(att.first), targetNode->m_Class); + // Ensure we use new ids for this datatype. This ensures that we go + if (theDataType == ERuntimeDataModelDataTypeLong4) { + TStrToStrMap::iterator aliasIdName = inMap.find(m_MetaData.Register(att.second)); + if (aliasIdName != inMap.end()) + inWriter.Att(att.first, aliasIdName->second.c_str()); + else { + QT3DS_ASSERT(false); + } + } else + inWriter.Att(att.first, att.second); + } + if (targetNode->m_MasterSlide) { + inReader.SetScope(targetNode->m_MasterSlide); + CopyStates(inReader, inSlideWriter, inMap, inAliasName, inAliasId); + } +} + +void CUIPParserObjectRefHelper::CopyStates(qt3dsdm::IDOMReader &inReader, + qt3dsdm::IDOMWriter &inSlideWriter, TStrToStrMap &inMap, + const char *inAliasName, const char *inAliasId) +{ + qt3dsdm::IDOMReader::Scope __stateScope(inReader); + qt3dsdm::IDOMWriter::Scope stateScope(inSlideWriter, "State"); + CopyAttributes(inReader, inSlideWriter, inMap, inAliasName, inAliasId); + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + if (AreEqual(inReader.GetNarrowElementName(), "State")) + CopyStates(inReader, inSlideWriter, inMap, inAliasName, inAliasId); + else { + CopyHierarchy(inReader, inSlideWriter, inMap, inAliasName, inAliasId); + } + } +} + +eastl::pair CUIPParserObjectRefHelper::ProcessAliasAttribute( + const char8_t *inObjId, eastl::pair inAttribute, + eastl::string &ioStrBuilder, TStrToStrMap &inMap) +{ + inObjId = nonNull(inObjId); + if (inObjId[0] == '#') + ++inObjId; + SGraphNode *theNode = GetNode(nonNull(inObjId)); + if (theNode == NULL) + return inAttribute; + const char8_t *propName = inAttribute.first; + const char8_t *propValue = inAttribute.second; + ERuntimeAdditionalMetaDataType thePropertyType = m_MetaData.GetAdditionalType( + theNode->m_Type, m_MetaData.Register(propName), theNode->m_Class); + if (thePropertyType == ERuntimeAdditionalMetaDataTypeImage + || thePropertyType == ERuntimeAdditionalMetaDataTypeObjectRef) { + propValue = nonNull(propValue); + if (propValue[0] == '#') + ++propValue; + TStrToStrMap::iterator iter = inMap.find(m_MetaData.Register(propValue)); + if (iter != inMap.end()) { + ioStrBuilder.assign("#"); + ioStrBuilder.append(iter->second); + propValue = ioStrBuilder.c_str(); + } else + propValue = inAttribute.second; + } + return eastl::make_pair(propName, propValue); +} + +void CUIPParserObjectRefHelper::CopyAttributes(qt3dsdm::IDOMReader &inReader, + qt3dsdm::IDOMWriter &inSlideWriter, + TStrToStrMap &inMap, const char *inAliasName, + const char *inAliasId) +{ + eastl::string builder; + const char8_t *elemId = ""; + for (eastl::pair att = inReader.GetNarrowFirstAttribute(); + !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { + if (AreEqual(att.first, "component")) { + TStrToStrMap::iterator iter = inMap.find(m_MetaData.Register(att.second + 1)); + builder.assign("#"); + if (iter != inMap.end()) { + builder.append(iter->second); + } else { + builder.append(inAliasId); + } + inSlideWriter.Att(att.first, builder.c_str()); + } else if (AreEqual(att.first, "id")) { + builder.assign(inAliasName); + builder.append("-"); + builder.append(att.second); + // cannot be + while (m_SlideIdSet.find(m_MetaData.Register(builder.c_str())) != m_SlideIdSet.end()) + builder.append("_"); + inSlideWriter.Att(att.first, builder.c_str()); + m_SlideIdSet.insert(m_MetaData.Register(builder.c_str())); + inMap[m_MetaData.Register(att.second)] = m_MetaData.Register(builder.c_str()); + } else if (AreEqual(att.first, "ref")) { + const char8_t *refItem = att.second; + if (!isTrivial(refItem)) { + ++refItem; + elemId = refItem; + TStrToStrMap::iterator iter = inMap.find(m_MetaData.Register(refItem)); + if (iter != inMap.end()) { + builder.assign("#"); + builder.append(iter->second.c_str()); + inSlideWriter.Att("ref", builder.c_str()); + } else { + QT3DS_ASSERT(false); + } + } + } else { + att = ProcessAliasAttribute(elemId, att, builder, inMap); + inSlideWriter.Att(att.first, att.second); + } + } +} + +void CUIPParserObjectRefHelper::CopyHierarchy(qt3dsdm::IDOMReader &inReader, + qt3dsdm::IDOMWriter &inSlideWriter, TStrToStrMap &inMap, + const char *inAliasName, const char *inAliasId) +{ + qt3dsdm::IDOMReader::Scope __commandScope(inReader); + qt3dsdm::IDOMWriter::Scope __writerScope(inSlideWriter, inReader.GetNarrowElementName()); + CopyAttributes(inReader, inSlideWriter, inMap, inAliasName, inAliasId); + const char8_t *childData; + if (inReader.Value(childData)) { + inSlideWriter.Value(childData); + } + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) + CopyHierarchy(inReader, inSlideWriter, inMap, inAliasName, inAliasId); +} + +void CUIPParserObjectRefHelper::CopyStateCommands(qt3dsdm::IDOMReader &inReader, + qt3dsdm::IDOMWriter &inWriter, + TStrToStrMap &oldToNewIdMap, + const char *inAliasName, const char *inOldId, + const char *inNewId) +{ + qt3dsdm::IDOMReader::Scope __commandScope(inReader); + qt3dsdm::SDOMElement *theSlidesRoot = NULL; + eastl::pair, std::shared_ptr> + slideWriterReaderPair; + std::shared_ptr commandWriter; + { + qt3dsdm::IDOMReader::Scope __loopScope(inReader); + eastl::vector> copiedAttributes; + void *destCommand = NULL; + eastl::string strBuilder; + for (bool success = inReader.MoveToFirstChild(); success; + success = inReader.MoveToNextSibling()) { + qt3dsdm::IDOMReader::Scope childScope(inReader); + if (AreEqual(inReader.GetNarrowElementName(), "State")) + CopyStateCommands(inReader, inWriter, oldToNewIdMap, inAliasName, inOldId, inNewId); + else { + const char8_t *refItem = ""; + if (inReader.Att("ref", refItem) && !isTrivial(refItem)) { + ++refItem; + TStrToStrMap::iterator iter = oldToNewIdMap.find(m_MetaData.Register(refItem)); + if (iter != oldToNewIdMap.end()) { + if (theSlidesRoot == NULL) { + std::shared_ptr theFactory = + inWriter.GetFactory(); + std::shared_ptr theStrTable = + inReader.GetStringTable(); + theSlidesRoot = theFactory->NextElement("AliasSlides"); + slideWriterReaderPair = qt3dsdm::IDOMWriter::CreateDOMWriter( + theFactory, *theSlidesRoot, theStrTable); + commandWriter = slideWriterReaderPair.first; + } + qt3dsdm::IDOMWriter::Scope elemScope(*commandWriter, + inReader.GetNarrowElementName()); + for (eastl::pair att = + inReader.GetNarrowFirstAttribute(); + !isTrivial(att.first); att = inReader.GetNarrowNextAttribute()) { + if (AreEqual(att.first, "ref")) { + strBuilder.assign("#"); + strBuilder.append(iter->second); + commandWriter->Att("ref", strBuilder.c_str()); + } else { + + att = + ProcessAliasAttribute(refItem, att, strBuilder, oldToNewIdMap); + commandWriter->Att(att.first, att.second); + } + } + for (bool commandChild = inReader.MoveToFirstChild(); commandChild; + commandChild = inReader.MoveToNextSibling()) { + qt3dsdm::IDOMReader::Scope commandChildScope(inReader); + CopyHierarchy(inReader, *commandWriter, oldToNewIdMap, inAliasName, ""); + } + } else if (AreEqual(refItem, inOldId)) { + StoreTopLevelAliasAttributes(inReader, copiedAttributes); + } else if (AreEqual(refItem, inNewId)) + destCommand = inReader.GetScope(); + } + } + } + if (copiedAttributes.size() && destCommand) { + inReader.SetScope(destCommand); + for (QT3DSU32 idx = 0, end = copiedAttributes.size(); idx < end; ++idx) { + eastl::pair &theItem(copiedAttributes[idx]); + inWriter.Att(theItem.first.c_str(), theItem.second.c_str()); + } + } + } + if (commandWriter) + inWriter.AppendChildren(*commandWriter->GetTopElement()); +} + +CUIPParserObjectRefHelper::SGraphNode *CUIPParserObjectRefHelper::GetNode(const char *inId) +{ + if (IsTrivial(inId)) + return NULL; + if (inId[0] == '#') + ++inId; + TGraphNodeMap::iterator theIter = m_GraphNodeMap.find(m_MetaData.Register(inId)); + if (theIter != m_GraphNodeMap.end()) + return theIter->second; + return NULL; +} + +CUIPParserObjectRefHelper::SGraphNode *CUIPParserObjectRefHelper::GetNode(eastl::string inId) +{ + return GetNode(inId.c_str()); +} + +CUIPParserObjectRefHelper::TStrType CUIPParserObjectRefHelper::GetName(const eastl::string &inId) +{ + SGraphNode *theNode = GetNode(inId.c_str()); + if (theNode) + return theNode->m_Name; + QT3DS_ASSERT(false); + return m_MetaData.Register(inId.c_str()); +} + +CUIPParserObjectRefHelper::TStrType CUIPParserObjectRefHelper::GetType(const eastl::string &inId) +{ + SGraphNode *theNode = GetNode(inId.c_str()); + if (theNode) + return theNode->m_Type; + QT3DS_ASSERT(false); + return m_MetaData.Register(inId.c_str()); +} + +CUIPParserObjectRefHelper::TStrType CUIPParserObjectRefHelper::GetClass(const eastl::string &inId) +{ + SGraphNode *theNode = GetNode(inId.c_str()); + if (theNode) + return theNode->m_Class; + QT3DS_ASSERT(false); + return m_MetaData.Register(inId.c_str()); +} + +CUIPParserObjectRefHelper::TStrType +CUIPParserObjectRefHelper::ParseObjectRefId(const eastl::string &inObjectPath, + const char8_t *inOwnerId) +{ + if (inObjectPath.empty()) { + QT3DS_ASSERT(false); + return TStrType(); + } else if (inObjectPath[0] == '#') { + // Absolute path + return m_MetaData.Register(inObjectPath.substr(1).c_str()); + } else { + // Relative path + SGraphNode *theNode = GetNode(inOwnerId); + + // Split the string based on PATH_DELIMITER + eastl::string theStr = inObjectPath; + eastl::string theCurrentPart; + eastl::string::size_type thePos; + while (theNode) { + thePos = theStr.find(PATH_DELIMITER); + theCurrentPart = theStr.substr(0, thePos); + + if (theCurrentPart == "parent") { + theNode = theNode->m_Parent; + } else if (theCurrentPart == "this") { + // Do nothing because theNode points to itself + } else if (theCurrentPart == "Scene") { + theNode = m_RootNode; + } else { + SGraphNode *theFoundChild = NULL; + for (QT3DSU32 childIdx = 0; + childIdx < theNode->m_Children.size() && theFoundChild == NULL; ++childIdx) { + if (AreEqual(theNode->m_Children[childIdx]->m_Name, theCurrentPart.c_str())) + theFoundChild = theNode->m_Children[childIdx]; + } + theNode = theFoundChild; + } + + if (thePos == eastl::string::npos) + break; + + // Move on to the next token + theStr = theStr.substr(thePos + 1); + } + + if (theNode) + return theNode->m_Id; + + return TStrType(); + } +} + +eastl::string CUIPParserObjectRefHelper::BuildReferenceString(eastl::string inObjectPath) +{ + if (inObjectPath.empty()) { + // QT3DS_ASSERT( false ); + return ""; + } else if (inObjectPath[0] == '#') { + // Absolute path + return BuildAbsoluteReferenceString(inObjectPath.substr(1)); + } else { + // Relative path + return inObjectPath; + } +} + +eastl::string CUIPParserObjectRefHelper::BuildAbsoluteReferenceString(eastl::string inId) +{ + return BuildAbsoluteReferenceString(GetNode(inId)); +} + +eastl::string CUIPParserObjectRefHelper::BuildAbsoluteReferenceString(SGraphNode *inNode) +{ + if (inNode == NULL) + return ""; + + eastl::string theNameStart; + eastl::string theNameEnd(inNode->m_Name); + + SGraphNode *theParent = inNode->m_Parent; + if (theParent) { + theNameStart.assign(BuildAbsoluteReferenceString(theParent)); + theNameStart.append("."); + } + theNameStart += theNameEnd; + return theNameStart; +} + +void CUIPParserObjectRefHelper::MarkAllReferencedAttributes( + eastl::string inId, const eastl::vector &inReferences, + qt3dsdm::IDOMReader &inReader, SParseElementManager &outIdAttributesMap) +{ + IDOMReader::Scope __scope(inReader); + eastl::string theReferencesTokenizer; + eastl::string theCurrentReference; + eastl::string theReferenceTokenizer; + eastl::string theCurrentString; + eastl::string::size_type startPos = 0; + eastl::string::size_type endPos = 0; + eastl::string::size_type theReferencesTokenizerPos = 0; + eastl::string::size_type theReferenceTokenizerPos = 0; + SGraphNode *theBaseInstance = GetNode(inId); + SGraphNode *theCurrentInstance = theBaseInstance; + eastl::vector theInstanceList; + + for (QT3DSU32 theRefIdx = 0, theRefEnd = inReferences.size(); theRefIdx < theRefEnd; ++theRefIdx) { + // Split the string based on PATH_LINE_END + theReferencesTokenizer = inReferences[theRefIdx]; + theReferencesTokenizerPos = 0; + while (theReferencesTokenizerPos != eastl::string::npos + && !theReferencesTokenizer.empty()) { + theCurrentInstance = theBaseInstance; + theReferencesTokenizerPos = theReferencesTokenizer.find(PATH_LINE_END); + theCurrentReference = theReferencesTokenizer.substr(0, theReferencesTokenizerPos); + + // Move to the next token + theReferencesTokenizer = theReferencesTokenizer.substr(theReferencesTokenizerPos + 1); + + // trim whitespace from the beginning and the end of the string + startPos = theCurrentReference.find_first_not_of("\n\r\t "); + endPos = theCurrentReference.find_last_not_of("\n\r\t "); + if (startPos != eastl::string::npos) + theCurrentReference = theCurrentReference.substr(startPos, endPos - startPos + 1); + + // Split the string based on PATH_DELIMITER + theReferenceTokenizer = theCurrentReference; + theReferenceTokenizerPos = 0; + theInstanceList.clear(); + while (theReferenceTokenizerPos != eastl::string::npos + && !theReferenceTokenizer.empty()) { + theReferenceTokenizerPos = theReferenceTokenizer.find(PATH_DELIMITER); + theCurrentString = theReferenceTokenizer.substr(0, theReferenceTokenizerPos); + + // Move to the next token + theReferenceTokenizer = theReferenceTokenizer.substr(theReferenceTokenizerPos + 1); + + if (theReferenceTokenizerPos != eastl::string::npos) { + theCurrentInstance = GetReferenceNode(theCurrentInstance, theCurrentString, + theInstanceList, inReader); + } else { + if (theInstanceList.size() == 0 && theCurrentInstance) + theInstanceList.push_back(theCurrentInstance); + if (!MarkAttributeAsReferenced(theBaseInstance, theInstanceList, + theCurrentString, inReader, + outIdAttributesMap)) { + qCCritical(qt3ds::INVALID_OPERATION) + << "Unable to parse reference: " + << theBaseInstance->m_Id.c_str() << " : " + << theCurrentReference.c_str(); + } + } + } + } + } +} + +//============================================================================== +/** + * Helper method to find the VAsset via the name which is the child of inAsset. + */ +CUIPParserObjectRefHelper::SGraphNode * +CUIPParserObjectRefHelper::GetReferenceNode(SGraphNode *inInstance, eastl::string &inAssetName, + eastl::vector &outInstanceList, + qt3dsdm::IDOMReader &inReader) +{ + if (!inInstance) + return NULL; + + SGraphNode *theReturnInstance = NULL; + + if (inAssetName == "Scene") { + theReturnInstance = m_RootNode; + } else if (inAssetName == "parent") { + theReturnInstance = inInstance->m_Parent; + } else if (inAssetName == "children") { + outInstanceList.insert(outInstanceList.end(), inInstance->m_Children.begin(), + inInstance->m_Children.end()); + } else if (inAssetName == "descendants") { + for (SGraphNode::TGraphNodeList::iterator theChildren = inInstance->m_Children.begin(); + theChildren != inInstance->m_Children.end(); ++theChildren) { + outInstanceList.push_back(*theChildren); + GetReferenceNode(*theChildren, inAssetName, outInstanceList, inReader); + } + } else if (inAssetName[0] == '[' && inAssetName[inAssetName.length() - 1] == ']') { + // For example: [targetElement].position + // targetElement should be an Object picker specifying which element to preserve. + eastl::string theAssetName = inAssetName.substr(1, inAssetName.length() - 2); + + // Check if the target element property exists and get the property value + eastl::string theValue; + if (!inReader.Att(theAssetName.c_str(), theValue)) { + // Try to find the parent context and get the element name from there. + if (AreEqual(inReader.GetElementName(), L"Set")) { + IDOMReader::Scope __setScope(inReader); + const char8_t *refValue = ""; + inReader.Att("ref", refValue); + inReader.Leave(); + inReader.Leave(); + for (bool success = inReader.MoveToFirstChild("Add"); success; + success = inReader.MoveToNextSibling("Add")) { + const char8_t *newRef; + inReader.Att("ref", newRef); + if (AreEqual(newRef, refValue)) { + inReader.Att(theAssetName.c_str(), theValue); + break; + } + } + } + if (theValue.empty()) { + Option theRef = m_MetaData.GetPropertyValueObjectRef( + inInstance->m_Type, m_MetaData.Register(theAssetName.c_str()), + inInstance->m_Class); + if (theRef.hasValue()) + theValue = *theRef; + } + } + if (!IsTrivial(theValue.c_str())) { + // Get the target element id + eastl::string theTargetElement = + ParseObjectRefId(theValue, inInstance->m_Id.c_str()).c_str(); + if (theTargetElement != "") { + // Get the corresponding instance + theReturnInstance = GetNode(theTargetElement); + } + } + } else { + // Get the child with the specified name. + // Note that name is not unique and so this will only return the first child that matches + // the name + for (SGraphNode::TGraphNodeList::iterator theChildren = inInstance->m_Children.begin(); + theChildren != inInstance->m_Children.end(); ++theChildren) { + if (AreEqual((*theChildren)->m_Name.c_str(), inAssetName.c_str())) { + theReturnInstance = *theChildren; + break; + } + } + } + return theReturnInstance; +} + +bool CUIPParserObjectRefHelper::MarkAttributeAsReferenced( + SGraphNode *inBaseInstance, eastl::vector &inInstanceList, + eastl::string &inAttributeName, qt3dsdm::IDOMReader &inReader, + SParseElementManager &outIdAttributesMap) +{ + bool theRet(false); + eastl::vector::iterator theIter = inInstanceList.begin(); + eastl::vector::iterator theEnd = inInstanceList.end(); + for (; theIter != theEnd; ++theIter) { + SGraphNode *theCurrentInstance = *theIter; + + if (inAttributeName == "all") { + eastl::vector theProperties; + m_MetaData.GetInstanceProperties(theCurrentInstance->m_Type.c_str(), + theCurrentInstance->m_Class.c_str(), theProperties, + true); + + if (theProperties.size() > 0) { + SElementData *theData = + outIdAttributesMap.FindElementData(theCurrentInstance->m_Id.c_str()); + if (theData) { + for (QT3DSU32 theIndex = 0; theIndex < theProperties.size(); ++theIndex) + outIdAttributesMap.MarkAttributeAsReferenced( + *theData, theProperties[theIndex].c_str()); + } + theRet = true; + } + } else { + eastl::string theAttributeName = inAttributeName; + if (inAttributeName[0] == '[' && inAttributeName[inAttributeName.length() - 1] == ']') { + // For example: parent.[targetProp] + // targetProp should be a string specifying which property to preserve + theAttributeName = theAttributeName.substr(1, theAttributeName.length() - 2); + + // Get the targetProp property value from the uip file + const char *theValue; + if (inReader.Att(theAttributeName.c_str(), theValue)) { + theAttributeName = theValue; + } else { + // Query metadata value of base instance + theAttributeName = m_MetaData.GetPropertyValueString( + inBaseInstance->m_Type, m_MetaData.Register(theAttributeName.c_str()), + inBaseInstance->m_Class); + } + } + + // Check if the property exists + if (m_MetaData.IsPropertyExist(theCurrentInstance->m_Type, + m_MetaData.Register(theAttributeName.c_str()), + theCurrentInstance->m_Class)) { + MarkPreserveFlag(theCurrentInstance, theAttributeName, outIdAttributesMap); + theRet = true; + } else { + // check whether the attribute name has ".", strip those after that and try again + eastl::string::size_type theIndex = theAttributeName.rfind('.'); + if (theIndex != eastl::string::npos) { + theAttributeName = theAttributeName.substr(0, theIndex); + if (m_MetaData.IsPropertyExist(theCurrentInstance->m_Type, + m_MetaData.Register(theAttributeName.c_str()), + theCurrentInstance->m_Class)) { + MarkPreserveFlag(theCurrentInstance, theAttributeName, outIdAttributesMap); + theRet = true; + } + } + } + } + } + + return theRet; +} + +void CUIPParserObjectRefHelper::MarkPreserveFlag(SGraphNode *inInstance, eastl::string inProperty, + SParseElementManager &outIdAttributesMap) +{ + outIdAttributesMap.MarkAttributeAsReferenced(inInstance->m_Id.c_str(), inProperty.c_str()); +} + +void CUIPParserObjectRefHelper::BuildImageNamePropertyList() +{ + // Special case for material + // Material's Image properties (such as diffuse map, etc) point to Image instances + eastl::vector theProperties; + m_MetaData.GetInstanceProperties("Material", NULL, theProperties, true); + + size_t thePropertyCount = theProperties.size(); + for (QT3DSU32 thePropertyIndex = 0; thePropertyIndex < thePropertyCount; ++thePropertyIndex) { + eastl::string theProperty = theProperties[thePropertyIndex]; + ERuntimeAdditionalMetaDataType theAdditionalMetaDataType = + m_MetaData.GetAdditionalType(m_MaterialStr, m_MetaData.Register(theProperty.c_str())); + + if (theAdditionalMetaDataType == ERuntimeAdditionalMetaDataTypeImage) { + m_ImageNamePropertyList.insert(m_MetaData.Register(theProperty.c_str())); + } + } +} +} diff --git a/src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.h b/src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.h new file mode 100644 index 00000000..fcd16985 --- /dev/null +++ b/src/Runtime/Source/uipparser/Qt3DSUIPParserObjectRefHelper.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSUIPParser.h" +#include "Qt3DSUIPParserImpl.h" + +//============================================================================== +// Namespace +//============================================================================== +namespace Q3DStudio { + +//============================================================================== +/** + * @class CUIPParserObjectRefHelper + * @brief Class for parsing UIP file - Object Reference Helper + */ +class CUIPParserObjectRefHelper +{ + typedef qt3ds::foundation::CRegisteredString TStrType; + +public: + typedef eastl::hash_map TStrToStrMap; + + /// Tree structure to cache scene graph information. This is used to resolve relative object + /// reference + struct SGraphNode + { + typedef eastl::vector TGraphNodeList; + + TStrType m_Id; // node id + TStrType m_Name; // name of the node. the name can be default from metadata, specified in + // graph section, or specified in logic section. + TStrType m_Type; // for example: Layer, Camera, Model + TStrType + m_Class; // class id. usually used by Behavior or objects that have custom properties. + void *m_ReaderContext; // Context to warp back to this node. + void *m_MasterSlide; + SGraphNode *m_Parent; + TGraphNodeList m_Children; + SGraphNode() + : m_ReaderContext(NULL) + , m_MasterSlide(NULL) + , m_Parent(NULL) + { + } + }; + //============================================================================== + // Fields + //============================================================================== +private: + typedef eastl::hash_set TImageNamePropertyList; + IRuntimeMetaData &m_MetaData; ///< Reference to Metadata + typedef eastl::hash_map TGraphNodeMap; + SGraphNode *m_RootNode; + TGraphNodeMap m_GraphNodeMap; + TImageNamePropertyList m_SlideIdSet; + + // List of Image property names, for example diffusemap, normalmap, etc + // This is to handle material and images. Material's Image properties point to instances. + TImageNamePropertyList m_ImageNamePropertyList; + TStrType m_MaterialStr; + eastl::vector m_SceneGraphAliasList; + + typedef eastl::pair TLightProbeAndNamePair; + typedef eastl::map TLightProbeIdToNameMap; + TLightProbeIdToNameMap m_LayerImageIdToNameMap; + //============================================================================== + // Methods + //============================================================================== +public: // Construction + CUIPParserObjectRefHelper(IRuntimeMetaData &inMetaData); + virtual ~CUIPParserObjectRefHelper(); + + void CacheGraph(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter); + SGraphNode *GetNode(const char *inId); + SGraphNode *GetNode(eastl::string inId); + TStrType GetName(const eastl::string &inId); // return the node name given the node id + TStrType GetType(const eastl::string &inId); // return the node type given the node id + TStrType GetClass(const eastl::string &inId); // return the node class given the node id + + TStrType ParseObjectRefId(const eastl::string &inObjectPath, const char8_t *inOwnerId); + eastl::string BuildReferenceString(eastl::string inObjectPath); + void MarkAllReferencedAttributes(eastl::string inId, + const eastl::vector &inReferences, + qt3dsdm::IDOMReader &inReader, + SParseElementManager &outIdAttributesMap); + +private: + void CacheSceneGraph(qt3dsdm::IDOMReader &inReader, SGraphNode *inParent = NULL); + SGraphNode &CacheSceneGraphNode(qt3dsdm::IDOMReader &inReader, SGraphNode *inParent = NULL); + void CacheStateGraph(qt3dsdm::IDOMReader &inReader); + + void CopySceneGraph(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter, + qt3dsdm::IDOMWriter &inSlideWriter, TStrToStrMap &inMap, + const char *inAliasName, const char *inAliasId, SGraphNode &inParent); + void CopyStates(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inSlideWriter, + TStrToStrMap &inMap, const char *inAliasName, const char *inAliasId); + void CopyAttributes(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inSlideWriter, + TStrToStrMap &inMap, const char *inAliasName, const char *inAliasId); + void CopyHierarchy(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inSlideWriter, + TStrToStrMap &inMap, const char *inAliasName, const char *inAliasId); + void CopyStateCommands(qt3dsdm::IDOMReader &inReader, qt3dsdm::IDOMWriter &inWriter, + TStrToStrMap &oldToNewIdMap, const char *inAliasName, + const char *inOldId, const char *inNewId); + // Helper method for Preseve Attributes + SGraphNode *GetReferenceNode(SGraphNode *inInstance, eastl::string &inAssetName, + eastl::vector &outInstanceList, + qt3dsdm::IDOMReader &inReader); + bool MarkAttributeAsReferenced(SGraphNode *inBaseInstance, + eastl::vector &inInstanceList, + eastl::string &inAttributeName, qt3dsdm::IDOMReader &inReader, + SParseElementManager &outIdAttributesMap); + void MarkPreserveFlag(SGraphNode *inInstance, eastl::string inProperty, + SParseElementManager &outIdAttributesMap); + eastl::pair + ProcessAliasAttribute(const char8_t *inObjId, + eastl::pair inAttribute, + eastl::string &ioStrBuilder, TStrToStrMap &inMap); + + eastl::string BuildAbsoluteReferenceString(eastl::string inId); + eastl::string BuildAbsoluteReferenceString(SGraphNode *inNode); + + // Special case for material and images. Material's Image properties point to instances. + void BuildImageNamePropertyList(); +}; + +} // namespace Q3DStudio diff --git a/src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.cpp b/src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.cpp new file mode 100644 index 00000000..b9fb9763 --- /dev/null +++ b/src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 - 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSAudioPlayerImpl.h" +#include "foundation/Qt3DSLogging.h" +#include + +#ifdef PLATFORM_HAS_QT_MULTIMEDIA_LIB +#include +#endif // PLATFORM_HAS_QT_MULTIMEDIA_LIB + +namespace Q3DSViewer { + +Qt3DSAudioPlayerImpl::Qt3DSAudioPlayerImpl() +{ +} + +Qt3DSAudioPlayerImpl::~Qt3DSAudioPlayerImpl() +{ +} + +bool Qt3DSAudioPlayerImpl::PlaySoundFile(const char *inFilePath) +{ +#ifdef PLATFORM_HAS_QT_MULTIMEDIA_LIB + QSound::play(QString(inFilePath)); + return true; +#else + Q_UNUSED(inFilePath) + qCWarning(qt3ds::WARNING, "Qt3DSAudioPlayerImpl::PlaySoundFile: no QT multimedia lib on this platform"); + return false; +#endif // PLATFORM_HAS_QT_MULTIMEDIA_LIB +} +} diff --git a/src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.h b/src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.h new file mode 100644 index 00000000..bba5bd6a --- /dev/null +++ b/src/Runtime/Source/viewer/Qt3DSAudioPlayerImpl.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2013 - 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_VIEWER_LIB_QT3DS_AUDIO_PLAYER_IMPL_H +#define QT3DS_VIEWER_LIB_QT3DS_AUDIO_PLAYER_IMPL_H + +#include "Qt3DSAudioPlayer.h" +#include "qt3dsruntimeglobal.h" + +namespace Q3DSViewer { + +class QT3DS_RUNTIME_API Qt3DSAudioPlayerImpl : public Q3DStudio::IAudioPlayer +{ +public: + Qt3DSAudioPlayerImpl(); + virtual ~Qt3DSAudioPlayerImpl(); + bool PlaySoundFile(const char *inFilePath) override; +}; +} + +#endif // !QT3DS_VIEWER_LIB_QT3DS_AUDIO_PLAYER_IMPL_H diff --git a/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp b/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp new file mode 100644 index 00000000..d393f2af --- /dev/null +++ b/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp @@ -0,0 +1,766 @@ +/**************************************************************************** +** +** Copyright (C) 2013 - 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "EnginePrefix.h" +#include "Qt3DSTegraApplication.h" +#include "Qt3DSViewerApp.h" +#include "Qt3DSTegraInputEngine.h" +#include "Qt3DSInputFrame.h" // keyboard mapping +#include "foundation/Qt3DSTime.h" +#include "Qt3DSFNDTimer.h" +#include "Qt3DSAudioPlayer.h" + +#include +#include +#include + +#ifdef _MACOSX +#include +#endif + +namespace qt3ds { +void Qt3DSAssert(const char *exp, const char *file, int line, bool *ignore) +{ + Q_UNUSED(ignore) + qCritical() << "Assertion thrown: " << file << " " << line << " " << exp; +} +} + +#ifndef EASTL_DEBUG_BREAK +void EASTL_DEBUG_BREAK() +{ + qFatal("EASTL_DEBUG_BREAK: Assertion blown"); +} + +#endif + +#ifdef _WIN32 +#include +#include +#include "Qt3DSInputFrame.h" + +void HandleController(Q3DStudio::CTegraApplication &inApplication) +{ + static const class XInputLibrary + { + private: + typedef DWORD(__stdcall *GetStateFunction)(DWORD, XINPUT_STATE *); + + public: + XInputLibrary() + : m_module(NULL) + , GetState(NULL) + { + m_module = LoadLibraryA("XINPUT9_1_0.DLL"); + if (m_module != NULL) { + GetState = reinterpret_cast(GetProcAddress(m_module, + "XInputGetState")); + } + } + + ~XInputLibrary() + { + if (m_module != NULL) + FreeLibrary(m_module); + } + + GetStateFunction GetState; + + private: + HMODULE m_module; + } library; + + static const DWORD MAX_USERS = 4; + static const Q3DStudio::FLOAT STICK_RANGE = 32767; + static const Q3DStudio::FLOAT TRIGGER_RANGE = 255; + + static const struct ButtonEntry + { + WORD XBoxButton; + Q3DStudio::INT32 button; + } buttonMap[] = { + { XINPUT_GAMEPAD_START, Q3DStudio::BUTTON_START }, + { XINPUT_GAMEPAD_BACK, Q3DStudio::BUTTON_SELECT }, + { XINPUT_GAMEPAD_LEFT_THUMB, Q3DStudio::BUTTON_THUMBL }, + { XINPUT_GAMEPAD_RIGHT_THUMB, Q3DStudio::BUTTON_THUMBR }, + { XINPUT_GAMEPAD_LEFT_SHOULDER, Q3DStudio::BUTTON_L1 }, + { XINPUT_GAMEPAD_RIGHT_SHOULDER, Q3DStudio::BUTTON_R1 }, + { XINPUT_GAMEPAD_A, Q3DStudio::BUTTON_A }, + { XINPUT_GAMEPAD_B, Q3DStudio::BUTTON_B }, + { XINPUT_GAMEPAD_X, Q3DStudio::BUTTON_X }, + { XINPUT_GAMEPAD_Y, Q3DStudio::BUTTON_Y } }; + + static DWORD userLastPacketNumber[MAX_USERS] = { 0 }; + static WORD userLastButtons[MAX_USERS] = { 0 }; + + Q3DStudio::CInputEngine *input = inApplication.GetInputEngine(); + if (input != NULL && library.GetState) { + // for each controller + for (DWORD userIndex = 0; userIndex < MAX_USERS; ++userIndex) { + DWORD &lastPacketNumber = userLastPacketNumber[userIndex]; + WORD &lastButtons = userLastButtons[userIndex]; + + // get the state + XINPUT_STATE state = { 0 }; + if (library.GetState(userIndex, &state) == ERROR_SUCCESS + && state.dwPacketNumber != lastPacketNumber) { + using namespace Q3DStudio; + const XINPUT_GAMEPAD &gamepad = state.Gamepad; + const WORD &buttons = gamepad.wButtons; + + // handle button changes + DWORD buttonChanges = buttons ^ lastButtons; + for (size_t buttonMapIndex = 0; + buttonMapIndex < sizeof(buttonMap) / sizeof(buttonMap[0]); ++buttonMapIndex) { + const ButtonEntry &buttonEntry = buttonMap[buttonMapIndex]; + if (buttonEntry.XBoxButton & buttonChanges) { + input->HandleButton(buttonEntry.button, + buttons & buttonEntry.XBoxButton); + } + } + + // handle gamepad + if (buttons & XINPUT_GAMEPAD_DPAD_LEFT) + input->HandleAxis(AXIS_HAT_X, -1); + else if (buttons & XINPUT_GAMEPAD_DPAD_RIGHT) + input->HandleAxis(AXIS_HAT_X, 1); + else + input->HandleAxis(AXIS_HAT_X, 0); + if (buttons & XINPUT_GAMEPAD_DPAD_UP) + input->HandleAxis(AXIS_HAT_Y, -1); + else if (buttons & XINPUT_GAMEPAD_DPAD_DOWN) + input->HandleAxis(AXIS_HAT_Y, 1); + else + input->HandleAxis(AXIS_HAT_Y, 0); + + // handle sticks and triggers + input->HandleAxis(AXIS_X, gamepad.sThumbLX / STICK_RANGE); + input->HandleAxis(AXIS_Y, gamepad.sThumbLY / -STICK_RANGE); + input->HandleAxis(AXIS_Z, gamepad.sThumbRX / STICK_RANGE); + input->HandleAxis(AXIS_RZ, gamepad.sThumbRY / -STICK_RANGE); + input->HandleAxis(AXIS_LTRIGGER, gamepad.bLeftTrigger / TRIGGER_RANGE); + input->HandleAxis(AXIS_RTRIGGER, gamepad.bRightTrigger / TRIGGER_RANGE); + + // save the state + lastButtons = buttons; + lastPacketNumber = state.dwPacketNumber; + } + } + } +} +#endif + +using namespace Q3DStudio; + +struct WindowRect +{ + int x; + int y; + int width; + int height; +}; + +void PerfLogSetStringData(const char *) +{ +} // Dummy defination when TCP perf logging isnt used + +Q3DStudio::Qt3DSFNDTimer g_GlobalTimeProvider; + +qint64 GetTimeUST() +{ + // this needs to be nano seconds + Q3DStudio::ITimeProvider &theTimer = g_GlobalTimeProvider; + return theTimer.GetCurrentTimeMicroSeconds() * 1000; +} + +void initResource() { + // init runtime static resources + Q_INIT_RESOURCE(res); +} + +namespace Q3DSViewer { + +struct SWindowSystemImpl : public Q3DStudio::IWindowSystem +{ + QSize m_size; + int m_OffscreenID; + int m_DepthBitCount; + + QSize GetWindowDimensions() override { return m_size; } + void SetWindowDimensions(const QSize &inSize) override + { + m_size = inSize; + } + // For platforms that support it, we get the egl info for render plugins + // Feel free to return NULL. + SEGLInfo *GetEGLInfo() override { return NULL; } + // on some systems we allow our default render target to be a offscreen buffer + // otherwise return 0; + int GetDefaultRenderTargetID() override { return m_OffscreenID; } + // returns the depth buffer bit count for the render window + int GetDepthBitCount() override { return m_DepthBitCount; } +}; + +class Q3DSViewerAppImpl +{ +public: + Q3DSViewerAppImpl(Q3DStudio::IAudioPlayer *inAudioPlayer) + : m_tegraApp(0) + , m_appInitSuccessful(false) + , m_AudioPlayer(inAudioPlayer) + { +#ifndef EMBEDDED_LINUX + initResource(); +#endif + } + Q3DStudio::CTegraApplication *m_tegraApp; ///< pointer to internal "tegra appliction" + bool m_appInitSuccessful; ///< true if m_tegraApp is initialized successful + + std::vector m_mouseButtons; + Q3DStudio::IWindowSystem *m_WindowSystem; + + IAudioPlayer *m_AudioPlayer; + QVector m_pendingEvents; + + QString m_error; + + void queueMouseEvent(int button, int pressed, int x, int y) + { + QMouseEvent *e = new QMouseEvent(pressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease, + QPointF(x, y), (Qt::MouseButton)button, + (Qt::MouseButtons)button, 0); + e->setTimestamp(static_cast(GetTimeUST())); + m_pendingEvents.append(e); + } +}; + +///< @brief contructor +Q3DSViewerApp::Q3DSViewerApp(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer) + : m_Impl(*new Q3DSViewerAppImpl(inAudioPlayer)) +{ + Q_UNUSED(glContext) + m_Impl.m_WindowSystem = new SWindowSystemImpl(); +} + +///< @brief destructor +Q3DSViewerApp::~Q3DSViewerApp() +{ + qDeleteAll(m_Impl.m_pendingEvents); + + delete m_Impl.m_AudioPlayer; + + if (m_Impl.m_tegraApp) { + disconnect(m_Impl.m_tegraApp->getNDDView()->signalProxy(), 0); + + m_Impl.m_tegraApp->Cleanup(); + Q3DStudio_virtual_delete(m_Impl.m_tegraApp, CTegraApplication); + + if (GetMemoryManager().GetLineTracker()) + GetMemoryManager().GetLineTracker()->Report(); + + GetMemoryManager().Release(); + } + delete static_cast(m_Impl.m_WindowSystem); +} + +void Q3DSViewerApp::setOffscreenId(int offscreenID) +{ + static_cast(m_Impl.m_WindowSystem)->m_OffscreenID + = offscreenID; + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) + m_Impl.m_tegraApp->GetTegraRenderEngine()->ensureRenderTarget(); +} + +bool Q3DSViewerApp::InitializeApp(int winWidth, int winHeight, const QSurfaceFormat &format, + int offscreenID, const QString &source, + const QStringList &variantList, + qt3ds::Qt3DSAssetVisitor *assetVisitor) +{ + bool hasValidPresentationFile = !source.isEmpty(); + + QFileInfo info(source); + if (!info.exists()) { + m_Impl.m_error + = QObject::tr("Failed to initialize viewer, presentation doesn't exist"); + qCritical() << m_Impl.m_error; + return false; + } + + m_Impl.m_WindowSystem->SetWindowDimensions(QSize(winWidth, winHeight)); + + // create our internal application + if (hasValidPresentationFile && !m_Impl.m_tegraApp) { + static_cast(m_Impl.m_WindowSystem)->m_OffscreenID = offscreenID; + static_cast(m_Impl.m_WindowSystem)->m_DepthBitCount + = format.depthBufferSize(); + + // create memory manager + // GetMemoryManager( ).Initialize( "GlobalManager", g_ChunkSize, g_ChunkCount ); + // create internal app + m_Impl.m_tegraApp = Q3DStudio_virtual_new(CTegraApplication) + CTegraApplication(g_GlobalTimeProvider, *m_Impl.m_WindowSystem, + m_Impl.m_AudioPlayer); + + if (assetVisitor) + m_Impl.m_tegraApp->getNDDView()->setAssetVisitor(assetVisitor); + + m_Impl.m_appInitSuccessful = m_Impl.m_tegraApp->BeginLoad(source, variantList); + + // Simulate killing the application during loading. Useful for finding serious issues with + // loading. + /*for ( unsigned idx = 0; idx < 100; ++idx ) + { + Sleep( 10*idx ); + m_Impl.m_tegraApp->Cleanup(); + Q3DStudio_virtual_delete( m_Impl.m_tegraApp, CTegraApplication ); + + m_Impl.m_tegraApp = + Q3DStudio_virtual_new(CTegraApplication)CTegraApplication(g_GlobalTimeProvider, + *m_Impl.m_WindowSystem); + m_Impl.m_appInitSuccessful = m_Impl.m_tegraApp->BeginLoad( viewerArgs ) ? true : + false; + }*/ + + if (m_Impl.m_appInitSuccessful == false) { + m_Impl.m_error = QObject::tr("Viewer launch failure! Failed to load: '%1'").arg(source); + m_Impl.m_error.append("\n"); + qCritical() << m_Impl.m_error; + return false; + } + + bool success = m_Impl.m_tegraApp->InitializeGraphics(format); + if (!success) { + m_Impl.m_error = QObject::tr("Viewer launch failure! Failed to load: '%1'").arg(source); + m_Impl.m_error.append("\n"); + qCritical() << m_Impl.m_error; + return false; + } + + // Connect signals + connect(m_Impl.m_tegraApp->getNDDView()->signalProxy(), + &QINDDViewSignalProxy::SigSlideEntered, this, &Q3DSViewerApp::SigSlideEntered); + connect(m_Impl.m_tegraApp->getNDDView()->signalProxy(), + &QINDDViewSignalProxy::SigSlideExited, this, &Q3DSViewerApp::SigSlideExited); + + Resize(winWidth, winHeight); + + Q_EMIT SigPresentationReady(); + } + return true; +} + +bool Q3DSViewerApp::IsInitialised(void) +{ + return m_Impl.m_tegraApp != NULL && m_Impl.m_appInitSuccessful == true; +} + +int Q3DSViewerApp::GetWindowHeight() +{ + return m_Impl.m_WindowSystem->GetWindowDimensions().width(); +} + +int Q3DSViewerApp::GetWindowWidth() +{ + return m_Impl.m_WindowSystem->GetWindowDimensions().height(); +} + +void Q3DSViewerApp::setupSearchPath(std::vector &cmdLineArgs) +{ + // setup some additional search path + // index 0 contains the module directory +#ifdef _MACOSX + char buf[2056]; + uint32_t bufsize = 2056; + _NSGetExecutablePath(buf, &bufsize); + std::string theModuleDirectory = buf; +#else + std::string theModuleDirectory = cmdLineArgs[0]; +#endif + std::string::size_type pos = theModuleDirectory.rfind('\\'); + if (pos == std::string::npos) + pos = theModuleDirectory.rfind('/'); + + // Include the slash + theModuleDirectory = theModuleDirectory.substr(0, pos + 1); + + // TODO: Search path needs to be set up properly + //NvFAppendSearchPath(theModuleDirectory.c_str()); +} + +void Q3DSViewerApp::Render() +{ + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { + if (m_Impl.m_appInitSuccessful) { + for (QEvent *e : m_Impl.m_pendingEvents) { + m_Impl.m_tegraApp->HandleMessage(e); + delete e; + } + m_Impl.m_pendingEvents.clear(); +#ifdef WIN32 + HandleController(*m_Impl.m_tegraApp); +#endif + + m_Impl.m_tegraApp->Render(); + } + } +} + +void Q3DSViewerApp::SaveState() +{ + if (!m_Impl.m_tegraApp) + return; + + if (m_Impl.m_tegraApp->GetTegraRenderEngine()) { + ITegraRenderStateManager &manager = + m_Impl.m_tegraApp->GetTegraRenderEngine()->GetTegraRenderStateManager(); + + manager.SaveAllState(); + } +} + +void Q3DSViewerApp::RestoreState() +{ + if (!m_Impl.m_tegraApp) + return; + + if (m_Impl.m_tegraApp->GetTegraRenderEngine()) { + ITegraRenderStateManager &manager = + m_Impl.m_tegraApp->GetTegraRenderEngine()->GetTegraRenderStateManager(); + + manager.RestoreAllState(); + } +} + +bool Q3DSViewerApp::WasLastFrameDirty() +{ + if (m_Impl.m_tegraApp) + return m_Impl.m_tegraApp->WasLastFrameDirty(); + return false; +} + +QString Q3DSViewerApp::error() +{ + QString error = m_Impl.m_error; + m_Impl.m_error.clear(); + return error; +} + +void Q3DSViewerApp::Resize(int width, int height) +{ + QSize oldSize = m_Impl.m_WindowSystem->GetWindowDimensions(); + QSize newSize(width, height); + m_Impl.m_WindowSystem->SetWindowDimensions(newSize); + + if (m_Impl.m_appInitSuccessful && m_Impl.m_tegraApp + && m_Impl.m_tegraApp->GetTegraRenderEngine()) { + QResizeEvent event = QResizeEvent(newSize, oldSize); + m_Impl.m_tegraApp->HandleMessage(&event); + } +} + +void Q3DSViewerApp::HandleKeyInput(Q3DStudio::EKeyCode inKeyCode, bool isPressed) +{ + if (!m_Impl.m_tegraApp || inKeyCode == Q3DStudio::KEY_NOKEY) + return; + + CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); + if (input) + input->HandleKeyboard(inKeyCode, isPressed); +} + +void Q3DSViewerApp::HandleMouseMove(int x, int y, bool isPressed) +{ + if (!m_Impl.m_tegraApp) + return; + + CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); + if (input) { + input->BeginPickInput(); + input->EndPickInput(); + input->SetPickInput(static_cast(x), static_cast(y), + isPressed); + } + +} + +void Q3DSViewerApp::HandleMousePress(int x, int y, int mouseButton, bool isPressed) +{ + if (!m_Impl.m_tegraApp) + return; + + bool hasButton + = std::find(m_Impl.m_mouseButtons.begin(), m_Impl.m_mouseButtons.end(), mouseButton) + != m_Impl.m_mouseButtons.end(); + + if ((mouseButton == 1 || mouseButton == 2)) { + // We keep track of the mouse presses because there are situations where the application + // will not give us a mouse + // up for each mouse down. This ameleorates the effects of those slightly misbehaving + // applications. + if (isPressed == hasButton) { + bool localIsPressed = !isPressed; + // Slightly recursive call in order to handle situations where we aren't getting + // the mouse up with the corresponding mouse down or vice versa. + HandleMousePress(x, y, mouseButton, localIsPressed); + HandleMousePress(x, y, mouseButton, isPressed); + } else { + if (isPressed) { + m_Impl.m_mouseButtons.push_back(mouseButton); + qCInfo(qt3ds::TRACE_INFO) + << "ViewerApp: Mouse down of frame " + << m_Impl.m_tegraApp->GetFrameCount(); + } else { + m_Impl.m_mouseButtons.erase(std::remove(m_Impl.m_mouseButtons.begin(), + m_Impl.m_mouseButtons.end(), mouseButton), + m_Impl.m_mouseButtons.end()); + } + + CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); + + if (input) { + input->BeginPickInput(); + input->SetPickInput(static_cast(x), + static_cast(y), isPressed); + input->EndPickInput(); + + m_Impl.queueMouseEvent(mouseButton, isPressed ? 1 : 0, x, y); + } + } + } +} + +void Q3DSViewerApp::HandleMouseWheel(int x, int y, int orientation, int numSteps) +{ + if (!m_Impl.m_tegraApp) + return; + + CInputEngine *input = m_Impl.m_tegraApp->GetInputEngine(); + if (input) { + input->SetPickInput(static_cast(x), static_cast(y), 0); + input->SetScrollValue(orientation == 0 ? VSCROLLWHEEL : HSCROLLWHEEL, numSteps); + } +} + +void Q3DSViewerApp::GoToSlideByName(const char *elementPath, const char *slideName) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->GoToSlideByName(elementPath, slideName); +} + +void Q3DSViewerApp::GoToSlideByIndex(const char *elementPath, const int slideIndex) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->GoToSlideByIndex(elementPath, slideIndex); +} + +void Q3DSViewerApp::GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->GoToSlideRelative(elementPath, next, wrap); +} + +bool Q3DSViewerApp::GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) +{ + if (!m_Impl.m_tegraApp) + return false; + + return m_Impl.m_tegraApp->GetSlideInfo(elementPath, currentIndex, previousIndex, + currentName, previousName); +} + +void Q3DSViewerApp::SetPresentationActive(const char *presId, const bool active) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->SetPresentationAttribute(presId, nullptr, active ? "True" : "False"); +} + +void Q3DSViewerApp::GoToTime(const char *elementPath, const float time) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->GoToTime(elementPath, time); +} + +void Q3DSViewerApp::PlaySoundFile(const char *soundPath) +{ + if (!m_Impl.m_AudioPlayer || !soundPath) + return; + + m_Impl.m_AudioPlayer->PlaySoundFile(soundPath); +} + +void Q3DSViewerApp::SetAttribute(const char *elementPath, const char *attributeName, + const char *value) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->SetAttribute(elementPath, attributeName, value); +} + +bool Q3DSViewerApp::GetAttribute(const char *elementPath, const char *attributeName, void *value) +{ + if (!m_Impl.m_tegraApp) + return false; + + return m_Impl.m_tegraApp->GetAttribute(elementPath, attributeName, value); +} + +void Q3DSViewerApp::FireEvent(const char *elementPath, const char *evtName) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->FireEvent(elementPath, evtName); +} + +bool Q3DSViewerApp::PeekCustomAction(std::string &outElementPath, std::string &outActionName) +{ + if (!m_Impl.m_tegraApp) + return false; + + char *theElementPath = NULL; + char *theActioName = NULL; + bool retVal = m_Impl.m_tegraApp->PeekCustomAction(theElementPath, theActioName); + + if (theElementPath) + outElementPath = theElementPath; + if (theActioName) + outActionName = theActioName; + + return retVal; +} + +bool Q3DSViewerApp::RegisterScriptCallback(ViewerCallbackType::Enum inCallbackType, + const qml_Function inCallback, void *inUserData) +{ + if (!m_Impl.m_tegraApp) + return false; + + // convert to int + int callbackType = 0; + if (inCallbackType == Q3DSViewer::ViewerCallbackType::CALLBACK_ON_INIT) + callbackType = 1; + else if (inCallbackType == Q3DSViewer::ViewerCallbackType::CALLBACK_ON_UPDATE) + callbackType = 2; + else + return false; + + bool retVal = m_Impl.m_tegraApp->RegisterScriptCallback(callbackType, inCallback, inUserData); + + return retVal; +} + +void Q3DSViewerApp::SetScaleMode(ViewerScaleModes::Enum inScale) +{ + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { + m_Impl.m_tegraApp->GetTegraRenderEngine()->SetScaleMode( + static_cast(inScale)); + } +} + +ViewerScaleModes::Enum Q3DSViewerApp::GetScaleMode() +{ + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { + return static_cast( + m_Impl.m_tegraApp->GetTegraRenderEngine()->GetScaleMode()); + } + + return ViewerScaleModes::ExactSize; +} + +void Q3DSViewerApp::setMatteColor(const QColor &color) +{ + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { + m_Impl.m_tegraApp->GetTegraRenderEngine()->SetMatteColor( + qt3ds::QT3DSVec4(color.redF(), color.greenF(), + color.blueF(), color.alphaF())); + } +} + +void Q3DSViewerApp::setShowOnScreenStats(bool inShow) +{ + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) + m_Impl.m_tegraApp->getNDDView()->showOnScreenStats(inShow); +} + +void Q3DSViewerApp::SetShadeMode(ViewerShadeModes::Enum inShadeMode) +{ + if (m_Impl.m_tegraApp && m_Impl.m_tegraApp->GetTegraRenderEngine()) { + StaticAssert::valid_expression(); + StaticAssert::valid_expression(); + StaticAssert::valid_expression(); + + m_Impl.m_tegraApp->GetTegraRenderEngine()->SetShadeMode( + static_cast(inShadeMode)); + } +} + +void Q3DSViewerApp::SetGlobalAnimationTime(qint64 inMilliSecs) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->SetGlobalAnimationTime(inMilliSecs); +} + +void Q3DSViewerApp::SetDataInputValue(const QString &name, const QVariant &value) +{ + if (!m_Impl.m_tegraApp) + return; + + m_Impl.m_tegraApp->SetDataInputValue(name, value); +} + +Q3DSViewerApp &Q3DSViewerApp::Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer) +{ + return *Q3DStudio_virtual_new(Q3DSViewerApp) Q3DSViewerApp(glContext, inAudioPlayer); +} + +void Q3DSViewerApp::Release() +{ + Q3DStudio_virtual_delete(this, Q3DSViewerApp); +} + +} // end namespace diff --git a/src/Runtime/Source/viewer/Qt3DSViewerApp.h b/src/Runtime/Source/viewer/Qt3DSViewerApp.h new file mode 100644 index 00000000..0d56c3a1 --- /dev/null +++ b/src/Runtime/Source/viewer/Qt3DSViewerApp.h @@ -0,0 +1,390 @@ +/**************************************************************************** +** +** Copyright (C) 2013 - 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_VIEWER_H +#define QT3DS_VIEWER_H + +#include "qt3dsruntimeglobal.h" + +#include +#include +#include + +#include "Qt3DSInputDefs.h" + +#include + +namespace Q3DStudio { +class CTegraApplication; +class IWindowSystem; +class IAudioPlayer; +} + +namespace qt3ds { +class Qt3DSAssetVisitor +{ +public: + virtual void visit(const char *path) = 0; + virtual void visit(const char *type, const char *id, const char *src, const char *args) = 0; +}; +} + +namespace Q3DSViewer { + +typedef void (*qml_Function)(void *inUserData); + +// not must match the NDDRuntime see +// UICQmlEngine.h +struct ViewerCallbackType +{ + enum Enum { + CALLBACK_ON_INIT = 1, + CALLBACK_ON_UPDATE = 2, + }; +}; + +struct ViewerContextType +{ + enum Enum { GL_ES2 = 0, GL_ES3, GL_ES31, GL_ES32, GL_2, GL_3_3, GL_4 }; +}; + +struct ViewerScaleModes +{ + enum Enum { + ExactSize = 0, // Ensure the viewport is exactly same size as application + ScaleToFit = 1, // Resize viewport keeping aspect ratio + ScaleToFill = 2, // Resize viewport to entire window + }; +}; + +struct ViewerShadeModes +{ + enum Enum { + Shaded = 0, // Geometry is shaded only + ShadedWireframe = 1, // Wireframe is drawn on top shaded geometry + Wireframe = 2, // Wireframe only + }; +}; + +class Q3DSViewerAppImpl; +class QT3DS_RUNTIME_API Q3DSViewerApp : public QObject +{ + Q_OBJECT +private: + Q3DSViewerApp(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer); + ~Q3DSViewerApp(); + +public: + /** + * @brief Initialize viewer app + * + * @param[in] winWidth window width + * @param[in] winHeight window height + * @param[in] format OpenGL API version + * @param[in] offscreenID ID of an OpenGL FBO we should render to by default + * @param[in] source string to presentation source + * + * @return true on success + */ + bool InitializeApp(int winWidth, int winHeight, const QSurfaceFormat& format, + int offscreenID, const QString &source, + const QStringList &variantList, + qt3ds::Qt3DSAssetVisitor *assetVisitor = nullptr); + + bool IsInitialised(void); + void setOffscreenId(int offscreenID); + + + /* + * @brief handle window resize + * + * @param[in] width new width + * @param[in] height new size + * + * @return no return + */ + void Resize(int width, int height); + + /* + * @brief does the actual scene rendering + * + * @return no return + */ + void Render(); + + /* + * @brief handle keyboard input + * + * @param[in] keyEvent event + * @param[in] isPressed true if key pressed + * + * @return no return + */ + void HandleKeyInput(Q3DStudio::EKeyCode inKeyCode, bool isPressed); + + /* + * @brief handle mouse move input + * + * @param[in] x mouse pos x + * @param[in] y mouse pos y + * @param[in] mouseButton mouse button id + * @param[in] isPressed true if key pressed + * + * @return no return + */ + void HandleMouseMove(int x, int y, bool isPressed); + + /* + * @brief handle mouse press events + * + * @param[in] x mouse pos x + * @param[in] y mouse pos y + * @param[in] mouseButton mouse button id + * @param[in] isPressed true if key pressed + * + * @return no return + */ + void HandleMousePress(int x, int y, int mouseButton, bool isPressed); + + /* + * @brief handle mouse wheel events + * + * @param[in] x mouse pos x + * @param[in] y mouse pos y + * @param[in] orientation 0 vertical, 1 horizontal + * @param[in] numSteps how much the wheel has turned + * + * @return no return + */ + void HandleMouseWheel(int x, int y, int orientation, int numSteps); + + /* + * @brief Scale scene to adjsut to window size regarding width and height + * + * @param[in] inScale true if scale false if unscale + * + * @return no return + */ + void SetScaleMode(ViewerScaleModes::Enum inScaleMode); + + ViewerScaleModes::Enum GetScaleMode(); + + void setMatteColor(const QColor &color); + void setShowOnScreenStats(bool s); + + /* + * @brief Set the shading mode + * + * @param[in] inShadeMode the selected shade mode + * + * @return no return + */ + void SetShadeMode(ViewerShadeModes::Enum inShadeMode); + + /* + * @brief Save current render state + * + * @return no return + */ + void SaveState(); + /* + * @brief Restore current render state + * + * @return no return + */ + void RestoreState(); + + /// event call back slots + + /* + * @brief Go to a slide by name + * + * @param[in] elementPath where to find the element + * @param[in] slideName slide name + * + * @return no return + */ + void GoToSlideByName(const char *elementPath, const char *slideName); + + /* + * @brief Go to a slide by index + * + * @param[in] elementPath where to find the element + * @param[in] slideIndex slide index + * + * @return no return + */ + void GoToSlideByIndex(const char *elementPath, const int slideIndex); + + /* + * @brief Go to relative slide + * + * @param[in] elementPath where to find the element + * @param[in] next next or previous + * @param[in] wrap wrap to beginning if end is reached + * + * @return no return + */ + void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap); + + bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName); + + /* + * @brief Set presentation active or inactive + * + * @param[in] presId presentation id (name without .uip) + * @param[in] active set active or inactive + * + * @return no return + */ + void SetPresentationActive(const char *presId, const bool active); + + /* + * @brief Go to a certain time + * + * @param[in] elementPath where to find the element + * @param[in] time time to move + * + * @return no return + */ + void GoToTime(const char *elementPath, const float time); + + /* + * @brief Play a sound + * + * @param[in] soundPath sound file to play + * + * @return no return + */ + void PlaySoundFile(const char *soundPath); + + /* + * @brief Set attribute values + * + * @param[in] elementPath where to find the element + * @param[in] attributeName attribute name + * @param[in] value new value of the attribute + * + * @return no return + */ + void SetAttribute(const char *elementPath, const char *attributeName, const char *value); + + /* + * @brief Get attribute values + * + * @param[in] elementPath where to find the element + * @param[in] attributeName attribute name + * @param[out] value current attribute values + * + * @return true if successful + */ + bool GetAttribute(const char *elementPath, const char *attributeName, void *value); + + /* + * @brief Fire an event + * + * @param[in] elementPath where to find the element to fire the event on + * @param[in] evtName the string that identifies and defines the event + * + * @return no return + */ + void FireEvent(const char *elementPath, const char *evtName); + + /* + * @brief Peek a custom action from the queue + * Note the action is remvoved from the queue + * + * @param[out] outElementPath element path + * @param[out] actionName action name + * + * @return true if action available + */ + bool PeekCustomAction(std::string &outElementPath, std::string &actionName); + + /** + * @brief Register a callback + * + * @param[in] callbackType callback type + * @param[in] inCallback pointer to callback + * @param[in] inCallback pointer to user data + * + * @return true on success + */ + bool RegisterScriptCallback(ViewerCallbackType::Enum callbackType, + const qml_Function inCallback, void *inUserData); + + bool WasLastFrameDirty(); + + int GetWindowHeight(); + int GetWindowWidth(); + + void SetGlobalAnimationTime(qint64 inMilliSecs); + + void SetDataInputValue(const QString &name, const QVariant &value); + + QString error(); + +private: + /* + * @brief parse command line arguments this fills in our + * global command line variables + * + * @param[in] cmdLineArgs string to command line parameter + * + * @return no return + */ + void handleCmdLineArguments(std::vector &cmdLineArgs); + /* + * @brief setup search path. + * This functions setup additonal search path for resoruces + * + * @param[in] cmdLineArgs string to command line parameter + * + * @return no return + */ + void setupSearchPath(std::vector &cmdLineArgs); + +private: + Q3DSViewerAppImpl &m_Impl; + +public: + static Q3DSViewerApp &Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer = 0); + void Release(); + +Q_SIGNALS: + void SigSlideEntered(const QString &elementPath, unsigned int index, const QString &name); + void SigSlideExited(const QString &elementPath, unsigned int index, const QString &name); + void SigPresentationReady(); +}; + +} // end namespace + +#endif // QT3DS_VIEWER_H diff --git a/src/Runtime/Source/viewer/Qt3DSViewerTimer.h b/src/Runtime/Source/viewer/Qt3DSViewerTimer.h new file mode 100644 index 00000000..de679ce9 --- /dev/null +++ b/src/Runtime/Source/viewer/Qt3DSViewerTimer.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2013 - 2016 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_ELAPSED_TIMER_H +#define QT3DS_ELAPSED_TIMER_H +#include + +namespace Q3DSViewer { + +///< @brief this class implementes a elapsed timer using QElapsedTimer +class Qt3DSElapsedTimer +{ +public: + QElapsedTimer m_elapsedTimer; + QElapsedTimer::ClockType m_clockType; + + Qt3DSElapsedTimer() + { + m_clockType = QElapsedTimer::clockType(); + reset(); + } + + void reset() { m_elapsedTimer.start(); } + + qint64 getNanoSeconds() + { + qint64 time = m_elapsedTimer.nsecsElapsed(); + reset(); + return time; + } +}; + +///< @brief this class implementes a timer using QElapsedTimer +class Qt3DSTimer +{ +public: + QElapsedTimer m_timer; + + Qt3DSTimer() { start(); } + + void start() { m_timer.start(); } + + qint64 getNanoSeconds() { return static_cast(m_timer.elapsed() * 1000 * 1000); } +}; + +///< @brief this class implementes a circular buffer +template +struct NumericCircularBuffer +{ + unsigned long m_TotalNumElements; ///< holds the current number of elements + unsigned long m_NumElements; ///< restricts the size to TBufferSize and wrappes around + unsigned long m_NextIndex; ///< next index + TDataType m_RunningTotal; ///< summed value of all entries + TDataType m_Elements[TBufferSize]; ///< element buffer + + NumericCircularBuffer() { clear(); } + void clear() + { + m_TotalNumElements = 0; + m_NumElements = 0; + m_NextIndex = 0; + m_RunningTotal = 0; + memset(m_Elements, 0, sizeof(TDataType) * TBufferSize); + } + + void push_back(const TDataType &data) + { + if (m_NumElements < TBufferSize) + ++m_NumElements; + else + m_RunningTotal -= m_Elements[m_NextIndex]; + m_RunningTotal += data; + ++m_TotalNumElements; + m_Elements[m_NextIndex] = data; + m_NextIndex = (m_NextIndex + 1) % TBufferSize; + } + unsigned long size() const { return m_NumElements; } + TDataType average() const + { + TDataType mySize = ((TDataType)size()); + if (mySize) + return m_RunningTotal / mySize; + return 0; + } + + unsigned long getTotalItems() const { return m_TotalNumElements; } + + static unsigned long getBufferSize() { return TBufferSize; } +}; + +} // end namspace + +#endif // QT3DS_ELAPSED_TIMER_H diff --git a/src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.cpp b/src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.cpp new file mode 100644 index 00000000..b8e290f8 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + +#include +#include +#include +#include +#include +#include + +#define ADDRINFO struct addrinfo +#define INVALID_SOCKET -1 +#define closesocket close +#define SD_BOTH SHUT_RDWR +#define SOCKET_ERROR -1 + +#endif + +#include "SimpleTCPClientSocket.h" + +//============================================================================== +/** + * CTOR + * Accepts a buffer size for internal storage and a flag to indicate if + * Recv should return fixed sized packets or not. + */ +SimpleTCPClientSocket::SimpleTCPClientSocket(long inBufferSize, bool inWaitForFull) + : m_ClientSocket(NULL) + , m_Data(NULL) + , m_BytesRead(0) + , m_BufferSize(inBufferSize) + , m_WaitForFull(inWaitForFull) +{ + m_Data = new char[m_BufferSize]; +} + +//============================================================================== +/** + * DTOR + */ +SimpleTCPClientSocket::~SimpleTCPClientSocket() +{ + if (m_ClientSocket) + Disconnect(); + + delete[] m_Data; +} + +//============================================================================== +/** + * Initializes TCP communications. + * Needs to be called once per app. + */ +bool SimpleTCPClientSocket::Initialize() +{ +#ifdef _PCPLATFORM + WSADATA theWsaData; + + if (WSAStartup(WINSOCK_VERSION, &theWsaData)) { + // WSAStartup failed + return false; + } +#endif + return true; +} + +//============================================================================== +/** + * Deinitializes TCP communications. + * Needs to be called once per app. + */ +void SimpleTCPClientSocket::DeInitialize() +{ +#ifdef _PCPLATFORM + WSACleanup(); +#endif +} + +//============================================================================== +/** + * Attempts to connect at the specified address and port. + */ +bool SimpleTCPClientSocket::Connect(const char *inServerAddress, const char *inServerPort) +{ + bool theReturn = false; + ADDRINFO theHints; + ADDRINFO *theAddrInfo = NULL; + ADDRINFO *theAddrInfoPtr = NULL; + + memset(&theHints, 0, sizeof(theHints)); + theHints.ai_family = PF_INET; + theHints.ai_socktype = SOCK_STREAM; + + if (getaddrinfo(inServerAddress, inServerPort, &theHints, &theAddrInfo) == 0) { + for (theAddrInfoPtr = theAddrInfo; theAddrInfoPtr != NULL; + theAddrInfoPtr = theAddrInfoPtr->ai_next) { + if ((theAddrInfoPtr->ai_family == PF_INET) + || (theAddrInfoPtr->ai_family == PF_INET6)) // only want PF_INET or PF_INET6 + { + m_ClientSocket = socket(theAddrInfoPtr->ai_family, theAddrInfoPtr->ai_socktype, + theAddrInfoPtr->ai_protocol); + + if (m_ClientSocket != INVALID_SOCKET) { + if (theAddrInfoPtr->ai_socktype == SOCK_STREAM) { + if (connect(m_ClientSocket, theAddrInfoPtr->ai_addr, + theAddrInfoPtr->ai_addrlen) + == 0) { +// Set this up to be a non-blocking socket +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + int theFlags = fcntl(m_ClientSocket, F_GETFL, 0); + fcntl(m_ClientSocket, F_SETFL, theFlags | O_NONBLOCK); +#endif + +#ifdef _PCPLATFORM + u_long theBlockMode = 1; + ioctlsocket(m_ClientSocket, FIONBIO, &theBlockMode); +#endif + + theReturn = true; + break; + } + + // Connect failed + closesocket(m_ClientSocket); + } + } + } + } + } + + freeaddrinfo(theAddrInfo); + return theReturn; +} + +//============================================================================== +/** + * Disconnect and closes the TCP connection. + */ +void SimpleTCPClientSocket::Disconnect() +{ + shutdown(m_ClientSocket, SD_BOTH); + closesocket(m_ClientSocket); + m_BytesRead = 0; + m_ClientSocket = 0; +} + +//============================================================================== +/** + * Receives a data packet from the socket. + * If m_WaitForFull is true, Recv will always return 0 until it reads m_BufferSize + * bytes. + * Else, it will return the number of bytes read (if any) per call. + */ +long SimpleTCPClientSocket::Recv() +{ + long theReturnValue = 0; + + if (m_WaitForFull) { + theReturnValue = recv(m_ClientSocket, m_Data + m_BytesRead, m_BufferSize - m_BytesRead, 0); + + if (theReturnValue > 0) + m_BytesRead += theReturnValue; + + if (m_BytesRead < m_BufferSize) + theReturnValue = 0; + else { + m_BytesRead = 0; + theReturnValue = m_BufferSize; + } + } else { + theReturnValue = recv(m_ClientSocket, m_Data, m_BufferSize, 0); + if (theReturnValue == SOCKET_ERROR) + theReturnValue = 0; + } + + return theReturnValue; +} + +//============================================================================== +/** + * Sends a data packet to the socket. + * If m_WaitForFull is true, Send will always return 0 until it receives m_BufferSize + * bytes. + * Else, it will return the number of bytes sent (if any) per call. + */ +long SimpleTCPClientSocket::Send() +{ + long theReturnValue = 0; + + if (m_WaitForFull) { + theReturnValue = send(m_ClientSocket, m_Data + m_BytesSent, m_BufferSize - m_BytesSent, 0); + + if (theReturnValue > 0) + m_BytesSent += theReturnValue; + + if (m_BytesSent < m_BufferSize) + theReturnValue = 0; + else { + m_BytesSent = 0; + theReturnValue = m_BufferSize; + } + } else { + theReturnValue = send(m_ClientSocket, m_Data, m_BufferSize, 0); + if (theReturnValue == SOCKET_ERROR) + theReturnValue = 0; + } + + return theReturnValue; +} diff --git a/src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.h b/src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.h new file mode 100644 index 00000000..c320f7fd --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/SimpleTCPClientSocket.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#pragma once + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +#define SOCKET int +#endif + +#ifdef _PCPLATFORM +#include +#include +#endif + +//============================================================================== +// Creates a TCP socket to an address and port. +// Can return either fixed sized packets or variable sized ones. +//============================================================================== +class SimpleTCPClientSocket +{ +public: + SimpleTCPClientSocket(long inBufferSize, bool inWaitForFull); + ~SimpleTCPClientSocket(); + +public: + static bool Initialize(); + static void DeInitialize(); + + // Client side + bool Connect(const char *inServerAddress, const char *inServerPort); + void Disconnect(); + + // General + long Recv(); + long Send(); + + // operator char*( ){ return m_Data; } + void *GetData() { return m_Data; } + +protected: + SOCKET m_ClientSocket; + char *m_Data; + long m_BytesRead; + long m_BytesSent; + const long m_BufferSize; + bool m_WaitForFull; +}; diff --git a/src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.cpp b/src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.cpp new file mode 100644 index 00000000..44202739 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + +#include +#include +#include +#include +#include +#include + +#define ADDRINFO struct addrinfo +#define INVALID_SOCKET -1 +#define closesocket close +#define SD_BOTH SHUT_RDWR +#define SOCKET_ERROR -1 + +#endif + +#include "SimpleTCPServerSocket.h" + +//============================================================================== +/** + * CTOR + * Accepts a buffer size for internal storage and a flag to indicate if + * Recv should return fixed sized packets or not. + */ +SimpleTCPServerSocket::SimpleTCPServerSocket(long inBufferSize, bool inWaitForFull) + : m_ServerSocket(NULL) + , m_ClientSocket(NULL) + , m_Data(NULL) + , m_BytesRead(0) + , m_BytesSent(0) + , m_BufferSize(inBufferSize) + , m_WaitForFull(inWaitForFull) + , m_Initialized(false) +{ + m_Data = new char[m_BufferSize]; +} + +//============================================================================== +/** + * DTOR + */ +SimpleTCPServerSocket::~SimpleTCPServerSocket() +{ + if (m_ClientSocket) + Disconnect(); + + delete[] m_Data; +} + +//============================================================================== +/** + * Initializes TCP communications. + * Needs to be called once per app. + */ +bool SimpleTCPServerSocket::Initialize() +{ +#ifdef _PCPLATFORM + WSADATA theWsaData; + + if (WSAStartup(WINSOCK_VERSION, &theWsaData)) { + // WSAStartup failed + return false; + } +#endif + return true; +} + +//============================================================================== +/** + * Deinitializes TCP communications. + * Needs to be called once per app. + */ +void SimpleTCPServerSocket::DeInitialize() +{ +#ifdef _PCPLATFORM + WSACleanup(); +#endif +} + +//============================================================================== +/** + * Creates server socket, bind it and listen for incoming connection from a client. + */ +bool SimpleTCPServerSocket::Accept(const char *inServerAddress /*=NULL*/, + unsigned short inServerPort /*=0*/) +{ + bool theReturn = false; + struct sockaddr_in sockaddrServer; + struct sockaddr_in sockaddrClient; + + if (!m_Initialized) { + /* Create the TCP socket */ + if ((m_ServerSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET) { + /* Construct the server sockaddr_in structure */ + memset(&sockaddrServer, 0, sizeof(sockaddrServer)); /* Clear struct */ + sockaddrServer.sin_family = AF_INET; /* Internet/IP */ + sockaddrServer.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */ + sockaddrServer.sin_port = htons(inServerPort); /* server port */ + + /* Bind the server socket */ + if (bind(m_ServerSocket, (struct sockaddr *)&sockaddrServer, sizeof(sockaddrServer)) + == 0) + m_Initialized = true; + } + } + + /* Listen on the server socket */ + if (listen(m_ServerSocket, 1) == 0) { + socklen_t theClientLen = sizeof(sockaddrClient); + /* Wait for client connection */ + if ((m_ClientSocket = + accept(m_ServerSocket, (struct sockaddr *)&sockaddrClient, &theClientLen)) + == 0) { + SetNonBlocking(m_ClientSocket); + theReturn = true; + } + } + + return theReturn; +} + +//============================================================================== +/** + * Sets socket to non blocking state + */ +bool SimpleTCPServerSocket::SetNonBlocking(SOCKET inSocket) +{ +// Set this up to be a non-blocking socket +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + int theFlags = fcntl(inSocket, F_GETFL, 0); + return fcntl(m_ClientSocket, F_SETFL, theFlags | O_NONBLOCK) == 0; +#endif + +#ifdef _PCPLATFORM + u_long theBlockMode = 1; + return ioctlsocket(inSocket, FIONBIO, &theBlockMode) == 0; +#endif +} + +//============================================================================== +/** + * Disconnect and closes the TCP connection. + */ +void SimpleTCPServerSocket::Disconnect(bool inShutdown /*= false*/) +{ + shutdown(m_ClientSocket, SD_BOTH); + closesocket(m_ClientSocket); + m_BytesRead = 0; + m_BytesSent = 0; + m_ClientSocket = 0; + + if (inShutdown) { + shutdown(m_ServerSocket, SD_BOTH); + closesocket(m_ServerSocket); + m_ServerSocket = 0; + } +} + +//============================================================================== +/** + * Receives a data packet from the socket. + * If m_WaitForFull is true, Recv will always return 0 until it reads m_BufferSize + * bytes. + * Else, it will return the number of bytes read (if any) per call. + */ +long SimpleTCPServerSocket::Recv() +{ + long theReturnValue = 0; + + if (m_WaitForFull) { + theReturnValue = recv(m_ClientSocket, m_Data + m_BytesRead, m_BufferSize - m_BytesRead, 0); + + if (theReturnValue > 0) + m_BytesRead += theReturnValue; + + if (m_BytesRead < m_BufferSize) + theReturnValue = 0; + else { + m_BytesRead = 0; + theReturnValue = m_BufferSize; + } + } else { + theReturnValue = recv(m_ClientSocket, m_Data, m_BufferSize, 0); + if (theReturnValue == SOCKET_ERROR) + theReturnValue = 0; + } + + return theReturnValue; +} + +//============================================================================== +/** + * Sends a data packet to the socket. + * If m_WaitForFull is true, Send will always return 0 until it receives m_BufferSize + * bytes. + * Else, it will return the number of bytes sent (if any) per call. + */ +long SimpleTCPServerSocket::Send() +{ + long theReturnValue = 0; + + if (m_WaitForFull) { + theReturnValue = send(m_ClientSocket, m_Data + m_BytesSent, m_BufferSize - m_BytesSent, 0); + + if (theReturnValue > 0) + m_BytesSent += theReturnValue; + + if (m_BytesSent < m_BufferSize) + theReturnValue = 0; + else { + m_BytesSent = 0; + theReturnValue = m_BufferSize; + } + } else { + theReturnValue = send(m_ClientSocket, m_Data, m_BufferSize, 0); + if (theReturnValue == SOCKET_ERROR) + theReturnValue = 0; + } + + return theReturnValue; +} diff --git a/src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.h b/src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.h new file mode 100644 index 00000000..565dd736 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/SimpleTCPServerSocket.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#pragma once + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +#define SOCKET int +#endif + +#ifdef _PCPLATFORM +#include +#include +#endif + +//============================================================================== +// Creates a TCP socket to an address and port. +// Can return either fixed sized packets or variable sized ones. +//============================================================================== +class SimpleTCPServerSocket +{ +public: + SimpleTCPServerSocket(long inBufferSize, bool inWaitForFull); + ~SimpleTCPServerSocket(); + +public: + static bool Initialize(); + static void DeInitialize(); + + // Client side + // bool Connect( const char* inServerAddress, const char* inServerPort ); + void Disconnect(bool inShutdown = false); + + bool Accept(const char *inServerAddress = 0, unsigned short inServerPort = 0); + + // General + long Recv(); + long Send(); + + // operator void*( ){ return m_Data; } + void *GetData() { return m_Data; } + +protected: + bool SetNonBlocking(SOCKET inSocket); + +protected: + SOCKET m_ServerSocket; + SOCKET m_ClientSocket; + char *m_Data; + long m_BytesRead; + long m_BytesSent; + const long m_BufferSize; + bool m_WaitForFull; + bool m_Initialized; +}; diff --git a/src/Runtime/Source/viewer/perflog/TCPPerfLogClient.cpp b/src/Runtime/Source/viewer/perflog/TCPPerfLogClient.cpp new file mode 100644 index 00000000..a8be5b27 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/TCPPerfLogClient.cpp @@ -0,0 +1,476 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "TCPPerfLogClient.h" +#include "Qt3DSMacros.h" +#include "Qt3DSPlatformSpecific.h" +#include +#include + +//============================================================================== +// Statics +//============================================================================== +static TCPPerfLogClient *s_PerfLogClient = NULL; +static SPerfLogDataExtra s_LogDataExtra = { 0 }; +static const KDust s_OneSec = 1000000000; + +//============================================================================== +/** + * Extern function to create and initialize the TCPPerfLogClient. + */ +int InitializePerfLogClient(const char *inServerAddress, const char *inPort, KDust inLogFreqMsec, + const char *inLocalLogFilename) +{ + int theReturn = 1; + + if (!s_PerfLogClient) { + s_PerfLogClient = + new TCPPerfLogClient(inServerAddress, inPort, inLogFreqMsec, inLocalLogFilename); + theReturn = s_PerfLogClient->IsConnected() || s_PerfLogClient->IsLocal(); + } + + return theReturn; +} + +void PerfLogMarkBegin(KDust inCurrentTimeMsec) +{ + if (s_PerfLogClient) + s_PerfLogClient->MarkLogBegin(inCurrentTimeMsec); +} + +void PerfLogMarkEnd(KDust inCurrentTimeMsec) +{ + if (s_PerfLogClient) + s_PerfLogClient->MarkLogEnd(inCurrentTimeMsec); +} + +void InitializeNVPerfMon(EGLDisplay inDisplay) +{ + if (s_PerfLogClient) + s_PerfLogClient->InitializeNVPerfMon(inDisplay); +} + +void CleanupPerfLogClient(EGLDisplay inDisplay) +{ + if (s_PerfLogClient) + s_PerfLogClient->CleanupPerfLogClient(inDisplay); + + delete s_PerfLogClient; +} + +void PerfLogGetShortDisplay(char *outMessageBuffer) +{ + if (s_PerfLogClient) + s_PerfLogClient->GetShortDisplay(outMessageBuffer); +} + +//============================================================================== +/** + * Extern function to send a log given a timestamp and the currently measured + * FPS + */ +void PerfLogSend(unsigned long inTimeStamp, float inFPS) +{ + if (s_PerfLogClient) + s_PerfLogClient->SendLog(inTimeStamp, inFPS); +} + +//============================================================================== +/** + * Extern function to set string data into the log packet. + */ +void PerfLogSetStringData(const char *inStringData) +{ + if (s_PerfLogClient) + s_PerfLogClient->SetStringData(inStringData); +} + +//============================================================================== +/** + * CTOR + * Attempts to make a connection to a specified server address and port. + */ +TCPPerfLogClient::TCPPerfLogClient(const char *inServerAddress, const char *inServerPort, + KDust inLogFreqUSec, const char *inLocalLogFilename) + : m_Socket(sizeof(SPerfLogData), true) + , m_ProcMeminfo(NULL) + , m_ProcStatinfo(NULL) + , m_NvRmHandle(NULL) + , m_Connected(false) + , m_SendLog(false) + , m_LocalLogFile(NULL) + , m_RequiredPasses(1) + , m_CurrentPass(0) + , m_FrameCount(0) + , m_LogFreq(inLogFreqUSec) + , m_LastLogTime(0) + , m_LastExtraLogTime(0) + , m_NVPerfMonitor(NULL) + , m_NVGPUIdleCounter(NULL) +{ + //::memset( &m_Data, 0, sizeof( m_Data) ); + m_Connected = m_Socket.Connect(inServerAddress, inServerPort); + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + // Open the meminfo procfs + m_ProcMeminfo = ::fopen("/proc/meminfo", "r"); + ::setvbuf(m_ProcMeminfo, NULL, _IONBF, 0); + + // Open the stat procfs + m_ProcStatinfo = ::fopen("/proc/stat", "r"); + ::setvbuf(m_ProcStatinfo, NULL, _IONBF, 0); +#endif + +#ifdef _TEGRA_LINUX + // Get a handle into vrm + NvRmOpen(m_NvRmHandle, 0); + + // Activate DFS so that we can retrieve the EMC utilization + if (NvRmDfsSetState(m_NvRmHandle, NvRmDfsRunState_ClosedLoop) != 0) + kdLogMessage("\nUnable to activate DFS"); +#endif + + if (inLocalLogFilename) + m_LocalLogFile = ::fopen(inLocalLogFilename, "w"); +} + +//============================================================================== +/** + * DTOR + * Closes opened handles. + */ +TCPPerfLogClient::~TCPPerfLogClient() +{ +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + fclose(m_ProcMeminfo); + fclose(m_ProcStatinfo); +#endif + +#ifdef _TEGRA_LINUX + NvRmClose(m_NvRmHandle); +#endif + m_Socket.Disconnect(); + + if (m_LocalLogFile) + ::fclose(m_LocalLogFile); +} + +//============================================================================== +/** + * Marks the beginning of perf logging. + */ +void TCPPerfLogClient::MarkLogBegin(KDust inCurrentTime) +{ + if (m_LogFreq > 0) { + if ((inCurrentTime - m_LastLogTime) > m_LogFreq) { + m_SendLog = true; // Signal to initiate logging (might required a few frames before log + // data is fully captured) + + // Starts the NV perf monitor for this frame + if (m_NVPerfMonitor) + m_NVPerfMonFuncs.eglPerfMonitorBeginExperimentNV(); + } + + if (m_SendLog) { + if (m_NVPerfMonitor) + m_NVPerfMonFuncs.eglPerfMonitorBeginPassNV(m_CurrentPass % m_RequiredPasses); + } + + if ((inCurrentTime - m_LastExtraLogTime) > s_OneSec) { + SPerfLogData *theData = static_cast(m_Socket.GetData()); + s_LogDataExtra.m_MinFPS = s_LogDataExtra.m_MaxFPS = theData->m_FPS; + s_LogDataExtra.m_MinCPULoad = s_LogDataExtra.m_MaxCPULoad = theData->m_CPULoad; + s_LogDataExtra.m_MinGPULoad = s_LogDataExtra.m_MaxGPULoad = theData->m_GPULoad; + m_LastExtraLogTime = inCurrentTime; + } + } +} + +//============================================================================== +/** + * Marks the end of perf logging. + */ +void TCPPerfLogClient::MarkLogEnd(KDust inCurrentTime) +{ + ++m_FrameCount; + + if (m_SendLog) { + if (m_NVPerfMonitor) { + // Signal the end of NV perf logging for this frame + m_NVPerfMonFuncs.eglPerfMonitorEndPassNV(); + ++m_CurrentPass; + } + + if ((m_CurrentPass % m_RequiredPasses == 0)) { + if (m_NVPerfMonitor) + m_NVPerfMonFuncs.eglPerfMonitorEndExperimentNV(); + + KDust theElaspedTime = inCurrentTime - m_LastLogTime; + SendLog(static_cast(inCurrentTime / 1000000), + static_cast(m_FrameCount / (theElaspedTime / 1000000000.0))); + m_LastLogTime = inCurrentTime; + m_FrameCount = 0; + m_SendLog = false; + } + } +} + +//============================================================================== +/** + * Sets timestamp and FPS into log and calls GatherStatistics. + * Sends log data into the socket. + */ +bool TCPPerfLogClient::SendLog(unsigned long inTimestamp, float inFPS) +{ + SPerfLogData *theData = static_cast(m_Socket.GetData()); + theData->m_Timestamp = inTimestamp; + theData->m_FPS = inFPS; + GatherStatistics(theData); + + s_LogDataExtra.m_MinFPS = Q3DStudio::Q3DStudio_min(inFPS, s_LogDataExtra.m_MinFPS); + s_LogDataExtra.m_MaxFPS = Q3DStudio::Q3DStudio_max(inFPS, s_LogDataExtra.m_MaxFPS); + + s_LogDataExtra.m_MinCPULoad = + Q3DStudio::Q3DStudio_min(theData->m_CPULoad, s_LogDataExtra.m_MinCPULoad); + s_LogDataExtra.m_MaxCPULoad = + Q3DStudio::Q3DStudio_max(theData->m_CPULoad, s_LogDataExtra.m_MaxCPULoad); + + s_LogDataExtra.m_MinGPULoad = + Q3DStudio::Q3DStudio_min(theData->m_GPULoad, s_LogDataExtra.m_MinGPULoad); + s_LogDataExtra.m_MaxGPULoad = + Q3DStudio::Q3DStudio_max(theData->m_GPULoad, s_LogDataExtra.m_MaxGPULoad); + + bool theResult = false; + + if (m_LocalLogFile) + theResult |= ::fputs(FormatPerfLogData(theData), m_LocalLogFile) > 0; + + if (IsConnected()) + theResult |= m_Socket.Send() > 0; + + return theResult; +} + +//============================================================================== +/** + * Sets string data into the next log packet to be sent. + */ +void TCPPerfLogClient::SetStringData(const char *inStringData) +{ + SPerfLogData *theData = static_cast(m_Socket.GetData()); + ::strcpy(theData->m_StringData, inStringData); +} + +//============================================================================== +/** + * Obtain memory usage using meminfo procfs. + */ +void TCPPerfLogClient::GetCPUMemoryUsage(unsigned long &outUsage) +{ + unsigned long theTotalMem = 0; + unsigned long theFreeMem = 0; + +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + rewind(m_ProcMeminfo); + fflush(m_ProcMeminfo); + + fscanf(m_ProcMeminfo, "MemTotal: %lu kB\nMemFree: %lu kB", &theTotalMem, &theFreeMem); +#endif + + outUsage = theTotalMem - theFreeMem; +} + +//============================================================================== +/** + * Obtain GPU memory usage from nvrm. + */ +void TCPPerfLogClient::GetGPUCarveoutUsage(unsigned long &outUsage) +{ + long theUsedCarveout = 0; + +#ifdef _TEGRA_LINUX + NvRmMemGetStat(NvRmMemStat_UsedCarveout, theUsedCarveout); +#endif + + outUsage = theUsedCarveout; +} + +//============================================================================== +/** + * Obtain CPU utilization from nvrm DFS. + */ +void TCPPerfLogClient::GetCPULoad(float &outPercentage) +{ +#ifdef _LINUXPLATFORM + // Get CPU load from /proc/stat + static SCPUInfo thePreviousInfo; + SCPUInfo theCurrentInfo; + + rewind(m_ProcStatinfo); + fflush(m_ProcStatinfo); + + // Read first line in /proc/stat which is a summary for all CPU cores on the system + fscanf(m_ProcStatinfo, "cpu %lu %lu %lu %lu %lu %lu %lu %lu", &theCurrentInfo.m_User, + &theCurrentInfo.m_Nice, &theCurrentInfo.m_System, &theCurrentInfo.m_Idle, + &theCurrentInfo.m_Wait, &theCurrentInfo.m_X, &theCurrentInfo.m_Y, &theCurrentInfo.m_Z); + + // Idle frames calculation + unsigned long theIdleFrames = theCurrentInfo.m_Idle - thePreviousInfo.m_Idle; + if (theIdleFrames < 0) + theIdleFrames = 0; // Appears to be a bug in 2.4.x kernels?? + + // Get the total number of timeslices + unsigned long theTotalFrames = (theCurrentInfo.m_User - thePreviousInfo.m_User) + + (theCurrentInfo.m_Nice - thePreviousInfo.m_Nice) + + (theCurrentInfo.m_System - thePreviousInfo.m_System) + theIdleFrames + + (theCurrentInfo.m_Wait - thePreviousInfo.m_Wait) + + (theCurrentInfo.m_X - thePreviousInfo.m_X) + (theCurrentInfo.m_Y - thePreviousInfo.m_Y) + + (theCurrentInfo.m_Z - thePreviousInfo.m_Z); + + if (theTotalFrames < 1) + theTotalFrames = 1; + + outPercentage = 1.0f - (theIdleFrames * 1.0f / theTotalFrames); + + thePreviousInfo = theCurrentInfo; // /proc/stat is an aggregation, so track this for the next + // time GetCPULoad is called + +#else + outPercentage = -.01f; +#endif +} + +//============================================================================== +/** + * Retrieve the GPU load performance counter + */ +void TCPPerfLogClient::GetGPULoad(long &outPercentage) +{ + EGLuint64NV theCycles = 0; + EGLuint64NV theGPUIdle = 0; + + if (m_NVPerfMonitor + && (m_NVPerfMonFuncs.eglGetPerfMarkerCounterNV(EGL_DEFAULT_PERFMARKER_NV, + m_NVGPUIdleCounter, &theGPUIdle, &theCycles) + == EGL_TRUE)) + outPercentage = static_cast(100 - theGPUIdle); + else + outPercentage = 0; +} + +//============================================================================== +/** + * Retrieve the external memory controller load. + * DFS must be running first. + */ +void TCPPerfLogClient::GetEMCLoad(float &outPercentage) +{ +// Get CPU clock utilization from DFS +#ifdef _TEGRA_LINUX + NvRmDfsClockUsage theUsage; + ::memset(&theUsage, 0, sizeof(theUsage)); + if (NvRmDfsGetClockUtilization(m_NvRmHandle, NvRmDfsClockId_Emc, theUsage) == 0) + outPercentage = theUsage.AverageKHz * 1.0f / theUsage.CurrentKHz; + else +#endif + outPercentage = -0.01f; +} + +//============================================================================== +/** + * Helper function to gather various statistics. + */ +void TCPPerfLogClient::GatherStatistics(SPerfLogData *inLogData) +{ + // Grab and set statistics here + GetGPUCarveoutUsage(inLogData->m_GPUMemoryUsage); + GetCPUMemoryUsage(inLogData->m_CPUMemoryUsage); + GetCPULoad(inLogData->m_CPULoad); + GetGPULoad(inLogData->m_GPULoad); + GetEMCLoad(inLogData->m_EMCLoad); +} + +//============================================================================== +/** + * Initialize NV perf monitor counters + * Currently only one counter requested (GPU Idle) + */ +void TCPPerfLogClient::InitializeNVPerfMon(EGLDisplay inDisplay) +{ +#ifdef _TEGRA_LINUX + EGLPerfCounterNV theCounters[50]; + EGLint theReturnedCounterSize = 0; + + m_NVPerfMonitor = m_NVPerfMonFuncs.eglCreatePerfMonitorNV( + inDisplay, EGL_PERFMONITOR_HARDWARE_COUNTERS_BIT_NV); + m_NVPerfMonFuncs.eglMakeCurrentPerfMonitorNV(m_NVPerfMonitor); + + m_NVPerfMonFuncs.eglGetPerfCountersNV(m_NVPerfMonitor, theCounters, 100, + &theReturnedCounterSize); + for (long theIndex = 0; theIndex < theReturnedCounterSize; ++theIndex) { + const char *theCounterName = m_NVPerfMonFuncs.eglQueryPerfCounterStringNV( + m_NVPerfMonitor, theCounters[theIndex], EGL_COUNTER_NAME_NV); + + // Look for a counter with the name 'gpu idle' + if (Q3DStudio_stricmp(theCounterName, "GPU Idle") == 0) { + m_NVPerfMonFuncs.eglPerfMonitorAddCountersNV(1, &theCounters[theIndex]); + m_NVGPUIdleCounter = theCounters[theIndex]; + break; + } + } + + m_NVPerfMonFuncs.eglValidatePerfMonitorNV(&m_RequiredPasses); +#else + UNREFERENCED_PARAMETER(inDisplay); +#endif +} + +//============================================================================== +/** + * Deinitializes the NV perf monitor + */ +void TCPPerfLogClient::CleanupPerfLogClient(EGLDisplay inDisplay) +{ + if (m_NVPerfMonitor) + m_NVPerfMonFuncs.eglDestroyPerfMonitorNV(inDisplay, m_NVPerfMonitor); +} + +//============================================================================== +/** + * Retrieve a formatted output string containing performance statistics + */ +void TCPPerfLogClient::GetShortDisplay(char *inMessageBuffer) +{ + SPerfLogData *theData = static_cast(m_Socket.GetData()); + FormatPerfLogDataExtra(theData, &s_LogDataExtra, inMessageBuffer); +} diff --git a/src/Runtime/Source/viewer/perflog/TCPPerfLogClient.h b/src/Runtime/Source/viewer/perflog/TCPPerfLogClient.h new file mode 100644 index 00000000..8a39dab6 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/TCPPerfLogClient.h @@ -0,0 +1,376 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +//============================================================================== +// Includes +//============================================================================== +#include +#include +#include "SimpleTCPClientSocket.h" +#include "TCPPerfLogCommon.h" +#include "TCPPerfLogClientStub.h" + +#ifdef _PCPLATFORM +#include +#endif + +//============================================================================== +// Header definations copied from nvrm headers +//============================================================================== +extern "C" { + +/** + * NvRm heap statistics. See NvRmMemGetStat() for further details. + */ +enum NvRmMemStat { + /** + * Total number of bytes reserved for the carveout heap. + */ + NvRmMemStat_TotalCarveout = 1, + /** + * Number of bytes used in the carveout heap. + */ + NvRmMemStat_UsedCarveout, + /** + * Size of the largest free block in the carveout heap. + * Size can be less than the difference of total and + * used memory. + */ + NvRmMemStat_LargestFreeCarveoutBlock, + /** + * Total number of bytes in the GART heap. + */ + NvRmMemStat_TotalGart, + /** + * Number of bytes reserved from the GART heap. + */ + NvRmMemStat_UsedGart, + /** + * Size of the largest free block in GART heap. Size can be + * less than the difference of total and used memory. + */ + NvRmMemStat_LargestFreeGartBlock, +}; + +/** + * Defines SOC-wide clocks controlled by Dynamic Frequency Scaling (DFS) + * that can be targeted by Starvation and Busy hints + */ +enum NvRmDfsClockId { + /// Specifies CPU clock + NvRmDfsClockId_Cpu = 1, + + /// Specifies AVP clock + NvRmDfsClockId_Avp, + + /// Specifies System bus clock + NvRmDfsClockId_System, + + /// Specifies AHB bus clock + NvRmDfsClockId_Ahb, + + /// Specifies APB bus clock + NvRmDfsClockId_Apb, + + /// Specifies video pipe clock + NvRmDfsClockId_Vpipe, + + /// Specifies external memory controller clock + NvRmDfsClockId_Emc, +}; + +typedef unsigned long NvRmFreqKHz; + +/** + * Holds information on DFS clock domain utilization + */ +struct NvRmDfsClockUsage +{ + /// Minimum clock domain frequency + NvRmFreqKHz MinKHz; + + /// Maximum clock domain frequency + NvRmFreqKHz MaxKHz; + + /// Low corner frequency - current low boundary for DFS control algorithm. + /// Can be dynamically adjusted via APIs: NvRmDfsSetLowCorner() for all DFS + /// domains, NvRmDfsSetCpuEnvelope() for CPU, and NvRmDfsSetEmcEnvelope() + /// for EMC. When all DFS domains hit low corner, DFS stops waking up CPU + /// from low power state. + NvRmFreqKHz LowCornerKHz; + + /// High corner frequency - current high boundary for DFS control algorithm. + /// Can be dynamically adjusted via APIs: NvRmDfsSetCpuEnvelope() for Cpu, + /// NvRmDfsSetEmcEnvelope() for Emc, and NvRmDfsSetAvHighCorner() for other + // DFS domains. + NvRmFreqKHz HighCornerKHz; + + /// Current clock domain frequency + NvRmFreqKHz CurrentKHz; + + /// Average frequency of domain *activity* (not average frequency). For + /// domains that do not have activity monitors reported as unspecified. + NvRmFreqKHz AverageKHz; +}; + +/** + * Defines DFS manager run states + */ +enum NvRmDfsRunState { + /// DFS is in invalid, not initialized state + NvRmDfsRunState_Invalid = 0, + + /// DFS is disabled / not supported (terminal state) + NvRmDfsRunState_Disabled = 1, + + /// DFS is stopped - no automatic clock control. Starvation and Busy hints + /// are recorded but have no affect. + NvRmDfsRunState_Stopped, + + /// DFS is running in closed loop - full automatic control of SoC-wide + /// clocks based on clock activity measuremnets. Starvation and Busy hints + /// are functional as well. + NvRmDfsRunState_ClosedLoop, + + /// DFS is running in closed loop with profiling (can not be set on non + /// profiling build). + NvRmDfsRunState_ProfiledLoop, +}; + +typedef void *NvRmDeviceHandle; + +NvRmDfsRunState NvRmDfsGetState(NvRmDeviceHandle inRmDeviceHandle); +long NvRmDfsSetState(NvRmDeviceHandle inRmDeviceHandle, NvRmDfsRunState inDfsRunState); + +/** + * Gets information on DFS controlled clock utilization. If DFS is stopped + * or disabled the average frequency is always equal to current frequency. + * + * @param hRmDeviceHandle The RM device handle. + * @param ClockId The DFS ID of the clock targeted by this request. + * @param pClockInfo Output storage pointer for clock utilization information. + * + * @return NvSuccess if clock usage information is returned successfully. + */ +// NvError +// NvRmDfsGetClockUtilization( +// [in] NvRmDeviceHandle hRmDeviceHandle, +// [in] NvRmDfsClockId ClockId, +// [out] NvRmDfsClockUsage pClockUsage); +long NvRmDfsGetClockUtilization(NvRmDeviceHandle inRmDeviceHandle, NvRmDfsClockId inClockId, + NvRmDfsClockUsage &inClockUsage); + +/** + * Get a memory statistics value. + * + * Querying values may have an effect on system performance and may include + * processing, like heap traversal. + * + * @param Stat NvRmMemStat value that chooses the value to return. + * @param Result Result, if the call was successful. Otherwise value + * is not touched. + * @returns NvSuccess on success, NvError_BadParameter if Stat is + * not a valid value, NvError_NotSupported if the Stat is + * not available for some reason, or + * NvError_InsufficientMemory. + */ +// NvError +// NvRmMemGetStat([in] NvRmMemStat Stat, [out] NvS32 Result); +long NvRmMemGetStat(NvRmMemStat inStat, long &outResult); + +/** + * Opens the Resource Manager for a given device. + * + * Can be called multiple times for a given device. Subsequent + * calls will not necessarily return the same handle. Each call to + * NvRmOpen() must be paired with a corresponding call to NvRmClose(). + * + * Assert encountered in debug mode if DeviceId value is invalid. + * + * This call is not intended to perform any significant hardware + * initialization of the device; rather its primary purpose is to + * initialize RM's internal data structures that are involved in + * managing the device. + * + * @param pHandle the RM handle is stored here. + * @param DeviceId implementation-dependent value specifying the device + * to be opened. Currently must be set to zero. + * + * @retval NvSuccess Indicates that RM was successfully opened. + * @retval NvError_InsufficientMemory Indicates that RM was unable to allocate + * memory for its internal data structures. + */ +// NvError NvRmOpen( [out] NvRmDeviceHandle pHandle, [in] NvU32 DeviceId ); +long NvRmOpen(NvRmDeviceHandle &inHandle, unsigned long outDeviceId); + +/** + * Closes the Resource Manager for a given device. + * + * Each call to NvRmOpen() must be paired with a corresponding call + * to NvRmClose(). + * + * @param hDevice The RM handle. If hDevice is NULL, this API has no effect. + */ +// void NvRmClose( [in] NvRmDeviceHandle hDevice ); +void NvRmClose(void *inDevice); + +} // extern "C" + +// Represents information obtained from /proc/stat +typedef struct _SCPUInfo +{ + unsigned long m_User; // timeslices in userspace + unsigned long m_Nice; // timeslices for niced processed + unsigned long m_System; // timeslices in kernelspace + unsigned long m_Idle; // timeslices in idle + unsigned long m_Wait; // timeslices in wait + unsigned long m_X; // other timeslices + unsigned long m_Y; // other timeslices + unsigned long m_Z; // other timeslices + + _SCPUInfo() + : m_User(0) + , m_Nice(0) + , m_System(0) + , m_Idle(0) + , m_Wait(0) + , m_X(0) + , m_Y(0) + , m_Z(0) + { + } + +} SCPUInfo; + +//============================================================================== +// Utility function to grab EGL function pointers for NV perf monitor. +//============================================================================== +typedef struct _SNVPerfMonitorFuncs +{ + PFNEGLCREATEPERFMONITORNVPROC eglCreatePerfMonitorNV; + PFNEGLGETCURRENTPERFMONITORNVPROC eglGetCurrentPerfMonitorNV; + PFNEGLDESTROYPERFMONITORNVPROC eglDestroyPerfMonitorNV; + PFNEGLGETPERFCOUNTERSNVPROC eglGetPerfCountersNV; + PFNEGLQUERYPERFCOUNTERSTRINGNVPROC eglQueryPerfCounterStringNV; + PFNEGLPERFMONITORADDCOUNTERSNVPROC eglPerfMonitorAddCountersNV; + PFNEGLMAKECURRENTPERFMONITORNVPROC eglMakeCurrentPerfMonitorNV; + PFNEGLGETPERFMARKERCOUNTERNVPROC eglGetPerfMarkerCounterNV; + PFNEGLPERFMONITORBEGINEXPERIMENTNVPROC eglPerfMonitorBeginExperimentNV; + PFNEGLPERFMONITORENDEXPERIMENTNVPROC eglPerfMonitorEndExperimentNV; + PFNEGLPERFMONITORBEGINPASSNVPROC eglPerfMonitorBeginPassNV; + PFNEGLPERFMONITORENDPASSNVPROC eglPerfMonitorEndPassNV; + PFNEGLVALIDATEPERFMONITORNVPROC eglValidatePerfMonitorNV; + + _SNVPerfMonitorFuncs() + { + eglCreatePerfMonitorNV = + (PFNEGLCREATEPERFMONITORNVPROC)eglGetProcAddress("eglCreatePerfMonitorNV"); + eglDestroyPerfMonitorNV = + (PFNEGLDESTROYPERFMONITORNVPROC)eglGetProcAddress("eglDestroyPerfMonitorNV"); + eglGetCurrentPerfMonitorNV = + (PFNEGLGETCURRENTPERFMONITORNVPROC)eglGetProcAddress("eglGetCurrentPerfMonitorNV"); + eglGetPerfCountersNV = + (PFNEGLGETPERFCOUNTERSNVPROC)eglGetProcAddress("eglGetPerfCountersNV"); + eglQueryPerfCounterStringNV = + (PFNEGLQUERYPERFCOUNTERSTRINGNVPROC)eglGetProcAddress("eglQueryPerfCounterStringNV"); + eglPerfMonitorAddCountersNV = + (PFNEGLPERFMONITORADDCOUNTERSNVPROC)eglGetProcAddress("eglPerfMonitorAddCountersNV"); + eglMakeCurrentPerfMonitorNV = + (PFNEGLMAKECURRENTPERFMONITORNVPROC)eglGetProcAddress("eglMakeCurrentPerfMonitorNV"); + eglGetPerfMarkerCounterNV = + (PFNEGLGETPERFMARKERCOUNTERNVPROC)eglGetProcAddress("eglGetPerfMarkerCounterNV"); + eglPerfMonitorBeginExperimentNV = (PFNEGLPERFMONITORBEGINEXPERIMENTNVPROC)eglGetProcAddress( + "eglPerfMonitorBeginExperimentNV"); + eglPerfMonitorEndExperimentNV = (PFNEGLPERFMONITORENDEXPERIMENTNVPROC)eglGetProcAddress( + "eglPerfMonitorEndExperimentNV"); + eglPerfMonitorBeginPassNV = + (PFNEGLPERFMONITORBEGINPASSNVPROC)eglGetProcAddress("eglPerfMonitorBeginPassNV"); + eglPerfMonitorEndPassNV = + (PFNEGLPERFMONITORENDPASSNVPROC)eglGetProcAddress("eglPerfMonitorEndPassNV"); + eglValidatePerfMonitorNV = + (PFNEGLVALIDATEPERFMONITORNVPROC)eglGetProcAddress("eglValidatePerfMonitorNV"); + } + +} SNVPerfMonitorFuncs; + +//============================================================================== +// Handles gathering of performance statistics and sending them. +// Attempts to make a connection to a server that it will send data to. +//============================================================================== +class TCPPerfLogClient +{ +public: + TCPPerfLogClient(const char *inServerAddress, const char *inServerPort, KDust inLogFreqUSec, + const char *inLocalLogFilename); + ~TCPPerfLogClient(); + +public: + void MarkLogBegin(KDust inCurrentTime); + void MarkLogEnd(KDust inCurrentTime); + + bool SendLog(unsigned long inTimeStamp, float inFPS); + void SetStringData(const char *inStringData); + bool IsConnected() { return m_Connected; } + bool IsLocal() { return m_LocalLogFile != NULL; } + void InitializeNVPerfMon(EGLDisplay inDisplay); + void CleanupPerfLogClient(EGLDisplay inDisplay); + void GetShortDisplay(char *inMessageBuffer); + +protected: + void GatherStatistics(SPerfLogData *inLogData); + void GetCPUMemoryUsage(unsigned long &outUsage); + void GetGPUCarveoutUsage(unsigned long &outUsage); + void GetCPULoad(float &outPercentage); + void GetGPULoad(long &outPercentage); + void GetEMCLoad(float &outPercentage); + void GetGPUWaits(long &outPercentage); + +protected: + SimpleTCPClientSocket m_Socket; + FILE *m_ProcMeminfo; + FILE *m_ProcStatinfo; + void *m_NvRmHandle; + bool m_Connected; + bool m_SendLog; + FILE *m_LocalLogFile; + + EGLint m_RequiredPasses; + EGLint m_CurrentPass; + + long m_FrameCount; + KDust m_LogFreq; + KDust m_LastLogTime; + KDust m_LastExtraLogTime; + + const SNVPerfMonitorFuncs m_NVPerfMonFuncs; + EGLPerfMonitorNV m_NVPerfMonitor; + EGLPerfCounterNV m_NVGPUIdleCounter; +}; diff --git a/src/Runtime/Source/viewer/perflog/TCPPerfLogClientStub.h b/src/Runtime/Source/viewer/perflog/TCPPerfLogClientStub.h new file mode 100644 index 00000000..2b6c0975 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/TCPPerfLogClientStub.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +//============================================================================== +// Includes +//============================================================================== + +//============================================================================== +// Extern interfaces +//============================================================================== + +#ifdef __cplusplus +extern "C" { +#endif + +int InitializePerfLogClient(const char *inServerAddress, const char *inPort, KDust inLogFreqMsec, + const char *inLocalLogFilename); +void InitializeNVPerfMon(EGLDisplay inDisplay); +void CleanupPerfLogClient(EGLDisplay inDisplay); + +void PerfLogMarkBegin(KDust inCurrentTimeMsec); +void PerfLogMarkEnd(KDust inCurrentTimeMsec); +void PerfLogSend(unsigned long inTimeStamp, float inFPS); +void PerfLogSetStringData(const char *inStringData); +void PerfLogGetShortDisplay(char *outMessageBuffer); + +#ifdef __cplusplus +} +#endif diff --git a/src/Runtime/Source/viewer/perflog/TCPPerfLogCommon.h b/src/Runtime/Source/viewer/perflog/TCPPerfLogCommon.h new file mode 100644 index 00000000..23bc58f2 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/TCPPerfLogCommon.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include + +//============================================================================== +// Structs +//============================================================================== +typedef struct _SPerfLogData +{ + unsigned long m_Timestamp; + float m_FPS; + unsigned long m_GPUMemoryUsage; + unsigned long m_CPUMemoryUsage; + float m_CPULoad; + long m_GPULoad; + float m_EMCLoad; + char m_StringData[128]; +} SPerfLogData; + +typedef struct _SPerfLogDataExtra +{ + float m_MinFPS; + float m_MaxFPS; + float m_MinCPULoad; + float m_MaxCPULoad; + long m_MinGPULoad; + long m_MaxGPULoad; +} SPerfLogDataExtra; + +//============================================================================== +/** + * Formats SPerfLogData into a user readable form. + */ +const char *FormatPerfLogData(const SPerfLogData *inData) +{ + static char theMessageBuffer[256]; + theMessageBuffer[0] = 0; + + static unsigned long thePrevTimestamp = 0; + static unsigned long theTimestampDiff = 0; + if (thePrevTimestamp != 0) + theTimestampDiff = inData->m_Timestamp - thePrevTimestamp; + + ::sprintf(theMessageBuffer, "Timestamp: %lu\tTimediff: %lu\tFPS: %.2f\tUsecase: " + "%s\tGPUMemoryUsage: %lu\tCPUMemoryUsage: %lu\tCPULoad: " + "%.2f\tGPULoad: %ld\tEMCLoad: %.2f\n", + inData->m_Timestamp, theTimestampDiff, inData->m_FPS, inData->m_StringData, + inData->m_GPUMemoryUsage, inData->m_CPUMemoryUsage, inData->m_CPULoad * 100, + inData->m_GPULoad, inData->m_EMCLoad * 100); + + thePrevTimestamp = inData->m_Timestamp; + + return theMessageBuffer; +} + +//============================================================================== +/** + * Formats SPerfLogDataExtra into a user readable form. + */ +void FormatPerfLogDataExtra(const SPerfLogData *inData, const SPerfLogDataExtra *inExtraData, + char *inMessageBuffer) +{ + ::sprintf(inMessageBuffer, "FPS: %.0f/%.0f/%.0f CPU: %.0f/%.0f/%.0f GPU: %ld/%ld/%ld EMC: %.0f", + inData->m_FPS, inExtraData->m_MaxFPS, inExtraData->m_MinFPS, inData->m_CPULoad * 100, + inExtraData->m_MaxCPULoad * 100, inExtraData->m_MinCPULoad * 100, inData->m_GPULoad, + inExtraData->m_MaxGPULoad, inExtraData->m_MinGPULoad, inData->m_EMCLoad * 100); +} diff --git a/src/Runtime/Source/viewer/perflog/TCPPerfLogServer.cpp b/src/Runtime/Source/viewer/perflog/TCPPerfLogServer.cpp new file mode 100644 index 00000000..b62663b2 --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/TCPPerfLogServer.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +#include +#include +#endif + +#ifdef _PCPLATFORM +#include +#endif + +#include +#include "TCPPerfLogServer.h" + +//============================================================================== +/** + * CTOR + * Sets up listening server at specificed address and port. + * Opens log file to be ready for writing. + */ +TCPPerfLogServer::TCPPerfLogServer(const char *inServerAddress, unsigned short inServerPort, + const char *inLogFilename) + : m_LogFileHandle(0) + , m_Socket(sizeof(SPerfLogData), true) +{ + m_LogFileHandle = ::fopen(inLogFilename, "w"); + m_Socket.Accept(inServerAddress, inServerPort); +} + +//============================================================================== +/** + * DTOR + * Closes log file and disconnects server. + */ +TCPPerfLogServer::~TCPPerfLogServer() +{ + ::fclose(m_LogFileHandle); + m_Socket.Disconnect(true); +} + +//============================================================================== +/** + * Checks for any received packets and write them into the log file + */ +const char *TCPPerfLogServer::Update() +{ + if (m_Socket.Recv() > 0) { + const char *theOutputMessage = Output(); + ::fputs(theOutputMessage, m_LogFileHandle); + return theOutputMessage; + } + + return NULL; +} + +//============================================================================== +/** + * Formats receieved data into a text string. + */ +const char *TCPPerfLogServer::Output() +{ + SPerfLogData *thePerfLogData = static_cast(m_Socket.GetData()); + + return FormatPerfLogData(thePerfLogData); +} + +//============================================================================== +/** + * Keyboard hittest for Linux + */ +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) +int kbhit(void) +{ + return 0; +} +#else +#define kbhit _kbhit +#endif + +//============================================================================== +/** + * Main + */ +int main(int argc, const char *argv[]) +{ + const char *theServerIP = "10.0.0.1"; + const char *theLogFile = "perf.log"; + if (argc > 1) + theServerIP = argv[1]; + + if (argc > 2) + theLogFile = argv[2]; + + SimpleTCPServerSocket::Initialize(); + + { + ::printf("\nLog file: %s", theLogFile); + ::printf("\nServer listening at: %s", theServerIP); + + ::printf("\nWaiting for client..."); + ::fflush(stdout); + TCPPerfLogServer theServer(theServerIP, 9997, theLogFile); + ::printf("\nClient connected..."); + ::fflush(stdout); + + while (true) { + const char *theReceivedMessage = theServer.Update(); + if (theReceivedMessage) + printf("\n%s", theReceivedMessage); + + if (kbhit()) { +#if defined(_LINUXPLATFORM) || defined(_INTEGRITYPLATFORM) + char theKey = getchar(); +#endif +#ifdef _PCPLATFORM + char theKey = (char)_getch(); +#endif + if (theKey == 'q') + break; + } + } + } + + SimpleTCPServerSocket::DeInitialize(); + return 0; +} diff --git a/src/Runtime/Source/viewer/perflog/TCPPerfLogServer.h b/src/Runtime/Source/viewer/perflog/TCPPerfLogServer.h new file mode 100644 index 00000000..bfa6abcc --- /dev/null +++ b/src/Runtime/Source/viewer/perflog/TCPPerfLogServer.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once +//============================================================================== +// Includes +//============================================================================== +#include "SimpleTCPServerSocket.h" +#include "TCPPerfLogCommon.h" +#include + +//============================================================================== +// Creates a polling server that listens for incoming log packets. +// Creates a write received log data into a file. +//============================================================================== +class TCPPerfLogServer +{ +public: + TCPPerfLogServer(const char *inServerAddress, unsigned short inServerPort, + const char *inLogFilename); + ~TCPPerfLogServer(); + + const char *Update(); + +protected: + const char *Output(); + +protected: + FILE *m_LogFileHandle; + SimpleTCPServerSocket m_Socket; +}; diff --git a/src/Runtime/Source/viewer/qt3dsruntimeglobal.h b/src/Runtime/Source/viewer/qt3dsruntimeglobal.h new file mode 100644 index 00000000..6732c85d --- /dev/null +++ b/src/Runtime/Source/viewer/qt3dsruntimeglobal.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSRUNTIMEGLOBAL_H +#define QT3DSRUNTIMEGLOBAL_H + +#include + +#ifndef _INTEGRITYPLATFORM +#if defined QT3DS_RUNTIME_EXPORTS +#define QT3DS_RUNTIME_API Q_DECL_EXPORT +#else +#define QT3DS_RUNTIME_API Q_DECL_IMPORT +#endif +#else +#define QT3DS_RUNTIME_API +#endif + +#endif // QT3DSRUNTIMEGLOBAL_H diff --git a/src/Runtime/commoninclude.pri b/src/Runtime/commoninclude.pri index 1f355c97..bf7d92d2 100644 --- a/src/Runtime/commoninclude.pri +++ b/src/Runtime/commoninclude.pri @@ -13,25 +13,23 @@ DEFINES += COMPILED_FROM_DSP \ INCLUDEPATH += \ $$PWD/Source \ - $$PWD/Source/DataModel/Include \ - $$PWD/Source/Runtime/Include \ - $$PWD/Source/System/Include \ - $$PWD/Source/Engine/Include \ - $$PWD/Source/Qt3DSFoundation/Include \ - $$PWD/Source/Qt3DSRender/Include \ - $$PWD/Source/Qt3DSRender/Source \ - $$PWD/Source/Qt3DSRender/Source/gl2 \ - $$PWD/Source/Qt3DSRender/Source/gl3 \ - $$PWD/Source/Qt3DSRender/Source/glg \ - $$PWD/Source/UIPParser/Include \ - $$PWD/Source/Qt3DSState/Include \ - $$PWD/Source/Qt3DSStateApplication/Include \ - $$PWD/Source/Qt3DSStateApplication/Editor \ - $$PWD/Source/Qt3DSStateApplication/Debugger \ - $$PWD/Source/Qt3DSEvent/Include \ - $$PWD/Source/Qt3DSEvent/InternalInclude \ - $$PWD/Source/Viewer \ - $$PWD/Source/Viewer/PerfLog \ + $$PWD/Source/datamodel \ + $$PWD/Source/runtime \ + $$PWD/Source/system \ + $$PWD/Source/engine \ + $$PWD/Source/foundation \ + $$PWD/Source/render \ + $$PWD/Source/render/gl2 \ + $$PWD/Source/render/gl3 \ + $$PWD/Source/render/glg \ + $$PWD/Source/uipparser \ + $$PWD/Source/state \ + $$PWD/Source/stateapplication \ + $$PWD/Source/stateapplication/editor \ + $$PWD/Source/stateapplication/debugger \ + $$PWD/Source/event \ + $$PWD/Source/viewer \ + $$PWD/Source/viewer/perflog \ $$PWD/../Authoring/QT3DSIMP/Qt3DSImportLib \ $$PWD/../Authoring/QT3DSDM \ $$PWD/../Authoring/QT3DSDM/Systems \ @@ -41,9 +39,9 @@ INCLUDEPATH += \ $$PWD/../3rdparty/color \ $$PWD/../3rdparty/RuntimePlatformSpecific/$$PlatformSpecificDir/PlatformLibs \ $$PWD/../QtExtras/qmlstreamer \ - $$PWD/Source/Qt3DSRuntimeRender/Include \ - $$PWD/Source/Qt3DSRuntimeRender/GraphObjects \ - $$PWD/Source/Qt3DSRuntimeRender/ResourceManager + $$PWD/Source/runtimerender \ + $$PWD/Source/runtimerender/graphobjects \ + $$PWD/Source/runtimerender/resourcemanager # TODO: Investigate whether these can be moved to commonplatform win32-msvc { @@ -54,7 +52,7 @@ win32-msvc { win32 { INCLUDEPATH += \ - $$PWD/Source/PlatformSpecific/Windows/Qt3DSLibs \ + $$PWD/Source/platformspecific/windows/libs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Windows/Qt3DSLibs } @@ -62,30 +60,28 @@ linux|qnx { QMAKE_CXXFLAGS += -fpermissive QMAKE_CFLAGS += -fpermissive INCLUDEPATH += \ - $$PWD/Source/Qt3DSFoundation/Include/foundation/linux \ - $$PWD/Source/Qt3DSFoundation/Source/foundation/linux \ - $$PWD/Source/PlatformSpecific/Linux/Qt3DSLibs \ + $$PWD/Source/foundation/linux \ + $$PWD/Source/platformspecific/linux/libs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Linux/Qt3DSLibs } integrity { INCLUDEPATH += \ - $$PWD/Source/Qt3DSFoundation/Include/foundation/linux \ - $$PWD/Source/Qt3DSFoundation/Source/foundation/linux \ - $$PWD/Source/PlatformSpecific/Linux/Qt3DSLibs \ + $$PWD/Source/foundation/linux \ + $$PWD/Source/platformspecific/linux/libs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Linux/Qt3DSLibs } macos { INCLUDEPATH += \ $$PWD/../3rdparty/RuntimePlatformSpecific/Macos/Qt3DSLibs \ - $$PWD/Source/PlatformSpecific/Macos/Qt3DSLibs + $$PWD/Source/platformspecific/macos/libs } android { INCLUDEPATH += \ - $$PWD/Source/PlatformSpecific/Android/jni/Qt3DSLibs/nv_thread \ + $$PWD/Source/platformspecific/android/jni/libs/nv_thread \ $$PWD/../3rdparty/RuntimePlatformSpecific/Android/jni/Qt3DSLibs \ $$PWD/../3rdparty/RuntimePlatformSpecific/Android/jni } diff --git a/src/commonplatform.pri b/src/commonplatform.pri index 92fb248f..cec9d152 100644 --- a/src/commonplatform.pri +++ b/src/commonplatform.pri @@ -18,17 +18,17 @@ DEFINES += \ _UNICODE \ NO_BOOST -win32: PlatformSpecificDir = Windows -macos: PlatformSpecificDir = Macos -linux|integrity|qnx: PlatformSpecificDir = Linux -android: PlatformSpecificDir = Android/jni +win32: PlatformSpecificDir = windows +macos: PlatformSpecificDir = macos +linux|integrity|qnx: PlatformSpecificDir = linux +android: PlatformSpecificDir = android/jni integrity: { DEFINES += _LINUX DEFINES += _INTEGRITYPLATFORM } -INCLUDEPATH += $$PWD/Runtime/Source/PlatformSpecific/$$PlatformSpecificDir +INCLUDEPATH += $$PWD/Runtime/Source/platformspecific/$$PlatformSpecificDir THIRDPARTY_DIR = $$(QT3DSTUDIO_3RDPARTY_DIR) isEmpty(THIRDPARTY_DIR) { -- cgit v1.2.3